mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 12:21:57 +00:00
feat: New utils of createOrUpdateVault
This commit is contained in:
@@ -208,15 +208,13 @@ export type UniqueBy =
|
|||||||
| {
|
| {
|
||||||
all: readonly UniqueBy[] | UniqueBy[]
|
all: readonly UniqueBy[] | UniqueBy[]
|
||||||
}
|
}
|
||||||
export type DefaultString =
|
export type DefaultString = string | RandomString
|
||||||
| string
|
export type RandomString = {
|
||||||
| {
|
charset: string
|
||||||
charset: string
|
len: number
|
||||||
len: number
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// sometimes the type checker needs just a little bit of help
|
// sometimes the type checker needs just a little bit of help
|
||||||
export function isValueSpecListOf<S extends ListValueSpecType>(
|
function isValueSpecListOf<S extends ListValueSpecType>(
|
||||||
t: ValueSpec,
|
t: ValueSpec,
|
||||||
s: S,
|
s: S,
|
||||||
): t is ValueSpecListOf<S> & { spec: ListValueSpecOf<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 * as T from "../types"
|
||||||
import FileHelper from "./fileHelper"
|
import FileHelper from "./fileHelper"
|
||||||
import nullIfEmpty from "./nullIfEmpty"
|
import nullIfEmpty from "./nullIfEmpty"
|
||||||
@@ -21,6 +21,8 @@ import { LocalBinding } from "../mainFn/LocalBinding"
|
|||||||
import { LocalPort } from "../mainFn/LocalPort"
|
import { LocalPort } from "../mainFn/LocalPort"
|
||||||
import { NetworkBuilder } from "../mainFn/NetworkBuilder"
|
import { NetworkBuilder } from "../mainFn/NetworkBuilder"
|
||||||
import { TorHostname } from "../mainFn/TorHostname"
|
import { TorHostname } from "../mainFn/TorHostname"
|
||||||
|
import { DefaultString } from "../config/configTypes"
|
||||||
|
import { getDefaultString } from "./getDefaultString"
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
export type FlattenIntersection<T> =
|
export type FlattenIntersection<T> =
|
||||||
@@ -42,6 +44,11 @@ export type WrapperDataOptionals<WrapperData, Path extends string> = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type Utils<WD, WrapperOverWrite = { const: never }> = {
|
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"]>
|
readFile: <A>(fileHelper: FileHelper<A>) => ReturnType<FileHelper<A>["read"]>
|
||||||
writeFile: <A>(
|
writeFile: <A>(
|
||||||
fileHelper: FileHelper<A>,
|
fileHelper: FileHelper<A>,
|
||||||
@@ -84,6 +91,24 @@ export type Utils<WD, WrapperOverWrite = { const: never }> = {
|
|||||||
export const utils = <WrapperData = never, WrapperOverWrite = { const: never }>(
|
export const utils = <WrapperData = never, WrapperOverWrite = { const: never }>(
|
||||||
effects: T.Effects,
|
effects: T.Effects,
|
||||||
): Utils<WrapperData, WrapperOverWrite> => ({
|
): 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: () =>
|
getSystemSmtp: () =>
|
||||||
new GetSystemSmtp(effects) as GetSystemSmtp & WrapperOverWrite,
|
new GetSystemSmtp(effects) as GetSystemSmtp & WrapperOverWrite,
|
||||||
readFile: <A>(fileHelper: FileHelper<A>) => fileHelper.read(effects),
|
readFile: <A>(fileHelper: FileHelper<A>) => fileHelper.read(effects),
|
||||||
|
|||||||
Reference in New Issue
Block a user