mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-26 02:11:56 +00:00
feat: New utils of createOrUpdateVault
This commit is contained in:
@@ -208,15 +208,13 @@ export type UniqueBy =
|
||||
| {
|
||||
all: readonly UniqueBy[] | UniqueBy[]
|
||||
}
|
||||
export type DefaultString =
|
||||
| string
|
||||
| {
|
||||
charset: string
|
||||
len: number
|
||||
}
|
||||
|
||||
export type DefaultString = string | RandomString
|
||||
export type RandomString = {
|
||||
charset: string
|
||||
len: number
|
||||
}
|
||||
// sometimes the type checker needs just a little bit of help
|
||||
export function isValueSpecListOf<S extends ListValueSpecType>(
|
||||
function isValueSpecListOf<S extends ListValueSpecType>(
|
||||
t: ValueSpec,
|
||||
s: S,
|
||||
): t is ValueSpecListOf<S> & { spec: ListValueSpecOf<S> } {
|
||||
|
||||
@@ -59,3 +59,5 @@ export const smtpConfig = Value.filteredUnion(async ({ effects, utils }) => {
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
export const password =
|
||||
|
||||
112
lib/util/getDefaultString.ts
Normal file
112
lib/util/getDefaultString.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import { DefaultString } from "../config/configTypes"
|
||||
|
||||
export function getDefaultString(defaultSpec: DefaultString): string {
|
||||
if (typeof defaultSpec === "string") {
|
||||
return defaultSpec
|
||||
} else {
|
||||
let s = ""
|
||||
for (let i = 0; i < defaultSpec.len; i++) {
|
||||
s = s + getRandomCharInSet(defaultSpec.charset)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
// a,g,h,A-Z,,,,-
|
||||
export function getRandomCharInSet(charset: string): string {
|
||||
const set = stringToCharSet(charset)
|
||||
let charIdx = Math.floor(Math.random() * set.len)
|
||||
for (let range of set.ranges) {
|
||||
if (range.len > charIdx) {
|
||||
return String.fromCharCode(range.start.charCodeAt(0) + charIdx)
|
||||
}
|
||||
charIdx -= range.len
|
||||
}
|
||||
throw new Error("unreachable")
|
||||
}
|
||||
|
||||
function stringToCharSet(charset: string): CharSet {
|
||||
let set: CharSet = { ranges: [], len: 0 }
|
||||
let start: string | null = null
|
||||
let end: string | null = null
|
||||
let in_range = false
|
||||
for (let char of charset) {
|
||||
switch (char) {
|
||||
case ",":
|
||||
if (start !== null && end !== null) {
|
||||
if (start!.charCodeAt(0) > end!.charCodeAt(0)) {
|
||||
throw new Error("start > end of charset")
|
||||
}
|
||||
const len = end.charCodeAt(0) - start.charCodeAt(0) + 1
|
||||
set.ranges.push({
|
||||
start,
|
||||
end,
|
||||
len,
|
||||
})
|
||||
set.len += len
|
||||
start = null
|
||||
end = null
|
||||
in_range = false
|
||||
} else if (start !== null && !in_range) {
|
||||
set.len += 1
|
||||
set.ranges.push({ start, end: start, len: 1 })
|
||||
start = null
|
||||
} else if (start !== null && in_range) {
|
||||
end = ","
|
||||
} else if (start === null && end === null && !in_range) {
|
||||
start = ","
|
||||
} else {
|
||||
throw new Error('unexpected ","')
|
||||
}
|
||||
break
|
||||
case "-":
|
||||
if (start === null) {
|
||||
start = "-"
|
||||
} else if (!in_range) {
|
||||
in_range = true
|
||||
} else if (in_range && end === null) {
|
||||
end = "-"
|
||||
} else {
|
||||
throw new Error('unexpected "-"')
|
||||
}
|
||||
break
|
||||
default:
|
||||
if (start === null) {
|
||||
start = char
|
||||
} else if (in_range && end === null) {
|
||||
end = char
|
||||
} else {
|
||||
throw new Error(`unexpected "${char}"`)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start !== null && end !== null) {
|
||||
if (start!.charCodeAt(0) > end!.charCodeAt(0)) {
|
||||
throw new Error("start > end of charset")
|
||||
}
|
||||
const len = end.charCodeAt(0) - start.charCodeAt(0) + 1
|
||||
set.ranges.push({
|
||||
start,
|
||||
end,
|
||||
len,
|
||||
})
|
||||
set.len += len
|
||||
} else if (start !== null) {
|
||||
set.len += 1
|
||||
set.ranges.push({
|
||||
start,
|
||||
end: start,
|
||||
len: 1,
|
||||
})
|
||||
}
|
||||
return set
|
||||
}
|
||||
type CharSet = {
|
||||
ranges: {
|
||||
start: string
|
||||
end: string
|
||||
len: number
|
||||
}[]
|
||||
len: number
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Parser } from "ts-matches"
|
||||
import { Parser, string } from "ts-matches"
|
||||
import * as T from "../types"
|
||||
import FileHelper from "./fileHelper"
|
||||
import nullIfEmpty from "./nullIfEmpty"
|
||||
@@ -21,6 +21,8 @@ import { LocalBinding } from "../mainFn/LocalBinding"
|
||||
import { LocalPort } from "../mainFn/LocalPort"
|
||||
import { NetworkBuilder } from "../mainFn/NetworkBuilder"
|
||||
import { TorHostname } from "../mainFn/TorHostname"
|
||||
import { DefaultString } from "../config/configTypes"
|
||||
import { getDefaultString } from "./getDefaultString"
|
||||
|
||||
// prettier-ignore
|
||||
export type FlattenIntersection<T> =
|
||||
@@ -42,6 +44,11 @@ export type WrapperDataOptionals<WrapperData, Path extends string> = {
|
||||
}
|
||||
|
||||
export type Utils<WD, WrapperOverWrite = { const: never }> = {
|
||||
createOrUpdateVault: (opts: {
|
||||
key: string
|
||||
value: string | null | undefined
|
||||
generator: DefaultString
|
||||
}) => Promise<void>
|
||||
readFile: <A>(fileHelper: FileHelper<A>) => ReturnType<FileHelper<A>["read"]>
|
||||
writeFile: <A>(
|
||||
fileHelper: FileHelper<A>,
|
||||
@@ -84,6 +91,24 @@ export type Utils<WD, WrapperOverWrite = { const: never }> = {
|
||||
export const utils = <WrapperData = never, WrapperOverWrite = { const: never }>(
|
||||
effects: T.Effects,
|
||||
): Utils<WrapperData, WrapperOverWrite> => ({
|
||||
createOrUpdateVault: async ({
|
||||
key,
|
||||
value,
|
||||
generator,
|
||||
}: {
|
||||
key: string
|
||||
value: string | null | undefined
|
||||
generator: DefaultString
|
||||
}) => {
|
||||
if (value) {
|
||||
await effects.vaultSet({ key, value })
|
||||
return
|
||||
}
|
||||
if (await effects.vaultList().then((x) => x.includes(key))) {
|
||||
return
|
||||
}
|
||||
await effects.vaultSet({ key, value: getDefaultString(generator) })
|
||||
},
|
||||
getSystemSmtp: () =>
|
||||
new GetSystemSmtp(effects) as GetSystemSmtp & WrapperOverWrite,
|
||||
readFile: <A>(fileHelper: FileHelper<A>) => fileHelper.read(effects),
|
||||
|
||||
Reference in New Issue
Block a user