mirror of
https://github.com/Start9Labs/start-sdk.git
synced 2026-03-30 12:21:57 +00:00
chore: Update the types
This commit is contained in:
@@ -35,7 +35,12 @@ const username = Value.string({
|
|||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
export class Value<A extends ValueSpec> extends IBuilder<A> {
|
export class Value<A extends ValueSpec> extends IBuilder<A> {
|
||||||
static boolean(a: { name: string; description?: string | null; warning?: string | null; default?: boolean | null }) {
|
static boolean(a: {
|
||||||
|
name: string;
|
||||||
|
description?: string | null;
|
||||||
|
warning?: string | null;
|
||||||
|
default?: boolean | null;
|
||||||
|
}) {
|
||||||
return new Value({
|
return new Value({
|
||||||
description: null,
|
description: null,
|
||||||
warning: null,
|
warning: null,
|
||||||
@@ -160,7 +165,9 @@ export class Value<A extends ValueSpec> extends IBuilder<A> {
|
|||||||
spec,
|
spec,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
static union<V extends Variants<{ [key: string]: { name: string; spec: InputSpec } }>>(
|
static union<
|
||||||
|
V extends Variants<{ [key: string]: { name: string; spec: InputSpec } }>
|
||||||
|
>(
|
||||||
a: {
|
a: {
|
||||||
name: string;
|
name: string;
|
||||||
description?: string | null;
|
description?: string | null;
|
||||||
|
|||||||
@@ -8,9 +8,14 @@ export async function specToBuilderFile(
|
|||||||
inputData: Promise<InputSpecRaw> | InputSpecRaw,
|
inputData: Promise<InputSpecRaw> | InputSpecRaw,
|
||||||
options: Parameters<typeof specToBuilder>[1]
|
options: Parameters<typeof specToBuilder>[1]
|
||||||
) {
|
) {
|
||||||
await fs.writeFile(file, await specToBuilder(inputData, options), (err) => console.error(err));
|
await fs.writeFile(file, await specToBuilder(inputData, options), (err) =>
|
||||||
|
console.error(err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
export async function specToBuilder(inputData: Promise<InputSpecRaw> | InputSpecRaw, { startSdk = "start-sdk" } = {}) {
|
export async function specToBuilder(
|
||||||
|
inputData: Promise<InputSpecRaw> | InputSpecRaw,
|
||||||
|
{ startSdk = "start-sdk" } = {}
|
||||||
|
) {
|
||||||
const outputLines: string[] = [];
|
const outputLines: string[] = [];
|
||||||
outputLines.push(`
|
outputLines.push(`
|
||||||
import {Config, Value, List, Variants} from '${startSdk}/config/builder';
|
import {Config, Value, List, Variants} from '${startSdk}/config/builder';
|
||||||
@@ -19,8 +24,13 @@ export async function specToBuilder(inputData: Promise<InputSpecRaw> | InputSpec
|
|||||||
|
|
||||||
const namedConsts = new Set(["Config", "Value", "List"]);
|
const namedConsts = new Set(["Config", "Value", "List"]);
|
||||||
const configName = newConst("InputSpec", convertInputSpec(data));
|
const configName = newConst("InputSpec", convertInputSpec(data));
|
||||||
const configMatcherName = newConst("matchInputSpec", `${configName}.validator()`);
|
const configMatcherName = newConst(
|
||||||
outputLines.push(`export type InputSpec = typeof ${configMatcherName}._TYPE;`);
|
"matchInputSpec",
|
||||||
|
`${configName}.validator()`
|
||||||
|
);
|
||||||
|
outputLines.push(
|
||||||
|
`export type InputSpec = typeof ${configMatcherName}._TYPE;`
|
||||||
|
);
|
||||||
|
|
||||||
return outputLines.join("\n");
|
return outputLines.join("\n");
|
||||||
|
|
||||||
@@ -61,7 +71,10 @@ export async function specToBuilder(inputData: Promise<InputSpecRaw> | InputSpec
|
|||||||
}
|
}
|
||||||
case "union": {
|
case "union": {
|
||||||
const { variants, type, ...rest } = value;
|
const { variants, type, ...rest } = value;
|
||||||
const variantVariable = newConst(value.name + "_variants", convertVariants(variants));
|
const variantVariable = newConst(
|
||||||
|
value.name + "_variants",
|
||||||
|
convertVariants(variants)
|
||||||
|
);
|
||||||
|
|
||||||
return `Value.union(${JSON.stringify(rest)}, ${variantVariable})`;
|
return `Value.union(${JSON.stringify(rest)}, ${variantVariable})`;
|
||||||
}
|
}
|
||||||
@@ -116,7 +129,10 @@ export async function specToBuilder(inputData: Promise<InputSpecRaw> | InputSpec
|
|||||||
})})`;
|
})})`;
|
||||||
}
|
}
|
||||||
case "object": {
|
case "object": {
|
||||||
const specName = newConst(value.name + "_spec", convertInputSpec(spec.spec));
|
const specName = newConst(
|
||||||
|
value.name + "_spec",
|
||||||
|
convertInputSpec(spec.spec)
|
||||||
|
);
|
||||||
return `List.obj({
|
return `List.obj({
|
||||||
name: ${JSON.stringify(value.name || null)},
|
name: ${JSON.stringify(value.name || null)},
|
||||||
range: ${JSON.stringify(value.range || null)},
|
range: ${JSON.stringify(value.range || null)},
|
||||||
|
|||||||
@@ -3,5 +3,4 @@ export * as trigger from "./trigger";
|
|||||||
|
|
||||||
export { TriggerInput } from "./trigger/TriggerInput";
|
export { TriggerInput } from "./trigger/TriggerInput";
|
||||||
export { HealthReceipt } from "./HealthReceipt";
|
export { HealthReceipt } from "./HealthReceipt";
|
||||||
export { readyCheck } from "./readyCheck";
|
export { ReadyProof } from "../mainFn/ReadyProof";
|
||||||
export { ReadyProof } from "./ReadyProof";
|
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
import { InterfaceReceipt } from "../mainFn/interfaceReceipt";
|
|
||||||
import { Daemon, Effects } from "../types";
|
|
||||||
import { CheckResult } from "./checkFns/CheckResult";
|
|
||||||
import { ReadyReceipt } from "./ReadyProof";
|
|
||||||
import { HealthReceipt } from "./HealthReceipt";
|
|
||||||
import { Trigger } from "./trigger";
|
|
||||||
import { TriggerInput } from "./trigger/TriggerInput";
|
|
||||||
import { defaultTrigger } from "./trigger/defaultTrigger";
|
|
||||||
|
|
||||||
function readReciptOf<A extends { daemon: Daemon }>(a: A) {
|
|
||||||
return a as A & ReadyReceipt;
|
|
||||||
}
|
|
||||||
export function readyCheck(o: {
|
|
||||||
effects: Effects;
|
|
||||||
started(onTerm: () => void): null;
|
|
||||||
interfaceReceipt: InterfaceReceipt;
|
|
||||||
healthReceipts: Iterable<HealthReceipt>;
|
|
||||||
daemonReceipt: Daemon;
|
|
||||||
name: string;
|
|
||||||
trigger?: Trigger;
|
|
||||||
fn(): Promise<CheckResult> | CheckResult;
|
|
||||||
onFirstSuccess?: () => () => Promise<unknown> | unknown;
|
|
||||||
}) {
|
|
||||||
new Promise(async () => {
|
|
||||||
const trigger = (o.trigger ?? defaultTrigger)();
|
|
||||||
let currentValue: TriggerInput = {
|
|
||||||
lastResult: null,
|
|
||||||
hadSuccess: false,
|
|
||||||
};
|
|
||||||
for (
|
|
||||||
let res = await trigger.next(currentValue);
|
|
||||||
!res.done;
|
|
||||||
res = await trigger.next(currentValue)
|
|
||||||
) {
|
|
||||||
try {
|
|
||||||
const { status, message } = await o.fn();
|
|
||||||
if (!currentValue.hadSuccess) {
|
|
||||||
await o.started(o?.onFirstSuccess ?? (() => o.daemonReceipt.term()));
|
|
||||||
}
|
|
||||||
await o.effects.setHealth({
|
|
||||||
name: o.name,
|
|
||||||
status,
|
|
||||||
message,
|
|
||||||
});
|
|
||||||
currentValue.hadSuccess = true;
|
|
||||||
currentValue.lastResult = "success";
|
|
||||||
} catch (_) {
|
|
||||||
currentValue.lastResult = "failure";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return readReciptOf({
|
|
||||||
daemon: o.daemonReceipt,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
79
lib/mainFn/Daemons.ts
Normal file
79
lib/mainFn/Daemons.ts
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import { HealthReceipt, ReadyProof } from "../health";
|
||||||
|
import { CheckResult } from "../health/checkFns";
|
||||||
|
import { Trigger } from "../health/trigger";
|
||||||
|
import { Effects, ValidIfNoStupidEscape } from "../types";
|
||||||
|
import { InterfaceReceipt } from "./interfaceReceipt";
|
||||||
|
import { RunningMainRet } from "./RunningMainRet";
|
||||||
|
type Daemon<
|
||||||
|
Ids extends string | never,
|
||||||
|
Command extends string,
|
||||||
|
Id extends string
|
||||||
|
> = {
|
||||||
|
id: Id;
|
||||||
|
command: ValidIfNoStupidEscape<Command> | [string, ...string[]];
|
||||||
|
|
||||||
|
ready: {
|
||||||
|
display: null | {
|
||||||
|
name: "Websocket Live";
|
||||||
|
message: "The websocket is live";
|
||||||
|
};
|
||||||
|
fn: () => Promise<CheckResult> | CheckResult;
|
||||||
|
trigger?: Trigger;
|
||||||
|
};
|
||||||
|
requires?: Exclude<Ids, Id>[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const todo = <A>(): A => {
|
||||||
|
throw new Error("TODO");
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Used during the main of a function, it allows us to describe and ensure a set of daemons are running.
|
||||||
|
* With the dependency, we are using this like an init system, where we can ensure that a daemon is running
|
||||||
|
* The return type of this is used in the runningMain
|
||||||
|
```ts
|
||||||
|
Daemons.with({
|
||||||
|
effects,
|
||||||
|
started,
|
||||||
|
interfacesReceipt,
|
||||||
|
})
|
||||||
|
.addDaemon({
|
||||||
|
id: "nostr",
|
||||||
|
command: "./nostr-rs-relay --db /data",
|
||||||
|
ready: {
|
||||||
|
display: {
|
||||||
|
name: "Websocket Live",
|
||||||
|
message: "The websocket is live",
|
||||||
|
},
|
||||||
|
fn: () => checkPortListening(effects, 8080),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
```
|
||||||
|
*/
|
||||||
|
export class Daemons<Ids extends string | never> {
|
||||||
|
private constructor(
|
||||||
|
readonly effects: Effects,
|
||||||
|
readonly started: (onTerm: () => void) => null,
|
||||||
|
readonly daemons?: Daemon<Ids, "command", never>[]
|
||||||
|
) {}
|
||||||
|
|
||||||
|
static with(config: {
|
||||||
|
effects: Effects;
|
||||||
|
started: (onTerm: () => void) => null;
|
||||||
|
interfaceReceipt: InterfaceReceipt;
|
||||||
|
healthReceipts: HealthReceipt[];
|
||||||
|
}) {
|
||||||
|
return new Daemons<never>(config.effects, config.started);
|
||||||
|
}
|
||||||
|
addDaemon<Id extends string, Command extends string>(
|
||||||
|
newDaemon: Daemon<Ids, Command, Id>
|
||||||
|
) {
|
||||||
|
const daemons = [...(this?.daemons ?? [])];
|
||||||
|
daemons.push(newDaemon as any);
|
||||||
|
return new Daemons<Ids | Id>(this.effects, this.started, daemons);
|
||||||
|
}
|
||||||
|
|
||||||
|
build() {
|
||||||
|
return todo<RunningMainRet>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Daemon } from "../types";
|
import { Daemon } from "../types";
|
||||||
import { ReadyProof } from "../health/ReadyProof";
|
import { ReadyProof } from "./ReadyProof";
|
||||||
|
|
||||||
export type RunningMainRet = {
|
export type RunningMainRet = {
|
||||||
[ReadyProof]: never;
|
[ReadyProof]: never;
|
||||||
|
|||||||
@@ -9,6 +9,18 @@ export { Origin } from "./Origin";
|
|||||||
export { TorBinding } from "./TorBinding";
|
export { TorBinding } from "./TorBinding";
|
||||||
export { TorHostname } from "./TorHostname";
|
export { TorHostname } from "./TorHostname";
|
||||||
|
|
||||||
|
export { Daemons } from "./Daemons";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to ensure that the main function is running with the valid proofs.
|
||||||
|
* We first do the folowing order of things
|
||||||
|
* 1. We get the interfaces
|
||||||
|
* 2. We setup all the commands to setup the system
|
||||||
|
* 3. We create the health checks
|
||||||
|
* 4. We setup the daemons init system
|
||||||
|
* @param fn
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export const runningMain: (
|
export const runningMain: (
|
||||||
fn: (o: {
|
fn: (o: {
|
||||||
effects: Effects;
|
effects: Effects;
|
||||||
|
|||||||
@@ -113,14 +113,16 @@ describe("values", () => {
|
|||||||
testOutput<typeof validator._TYPE, Array<"a" | "b">>()(null);
|
testOutput<typeof validator._TYPE, Array<"a" | "b">>()(null);
|
||||||
});
|
});
|
||||||
test("object", () => {
|
test("object", () => {
|
||||||
const value = Value.object({
|
const value = Value.object(
|
||||||
name: "Testing",
|
{
|
||||||
spec: Config.of({
|
name: "Testing",
|
||||||
|
},
|
||||||
|
Config.of({
|
||||||
a: Value.boolean({
|
a: Value.boolean({
|
||||||
name: "test",
|
name: "test",
|
||||||
}),
|
}),
|
||||||
}),
|
})
|
||||||
});
|
);
|
||||||
const validator = value.validator();
|
const validator = value.validator();
|
||||||
validator.unsafeCast({ a: true });
|
validator.unsafeCast({ a: true });
|
||||||
testOutput<typeof validator._TYPE, { a: boolean }>()(null);
|
testOutput<typeof validator._TYPE, { a: boolean }>()(null);
|
||||||
|
|||||||
25
lib/types.ts
25
lib/types.ts
@@ -79,7 +79,7 @@ export namespace ExpectedExports {
|
|||||||
export type TimeMs = number;
|
export type TimeMs = number;
|
||||||
export type VersionString = string;
|
export type VersionString = string;
|
||||||
|
|
||||||
type ValidIfNoStupidEscape<A> = A extends
|
export type ValidIfNoStupidEscape<A> = A extends
|
||||||
| `${string}'"'"'${string}`
|
| `${string}'"'"'${string}`
|
||||||
| `${string}\\"${string}`
|
| `${string}\\"${string}`
|
||||||
? never
|
? never
|
||||||
@@ -236,23 +236,20 @@ export type Effects = {
|
|||||||
callback?: (config: unknown, previousConfig: unknown) => void;
|
callback?: (config: unknown, previousConfig: unknown) => void;
|
||||||
}): Promise<unknown>;
|
}): Promise<unknown>;
|
||||||
|
|
||||||
/** Get the address for another service for local internet*/
|
getLocalHostname(): Promise<string>;
|
||||||
getServiceLocalAddress(options: {
|
getIPHostname(): Promise<string>;
|
||||||
packageId: string;
|
|
||||||
interfaceName: string;
|
|
||||||
}): Promise<string>;
|
|
||||||
/** Get the address for another service for tor interfaces */
|
/** Get the address for another service for tor interfaces */
|
||||||
getServiceTorAddress(options: {
|
getServiceTorHostname(
|
||||||
packageId: string;
|
interfaceId: string,
|
||||||
interfaceName: string;
|
packageId?: string
|
||||||
}): Promise<string>;
|
): Promise<string>;
|
||||||
/**
|
/**
|
||||||
* Get the port address for another service
|
* Get the port address for another service
|
||||||
*/
|
*/
|
||||||
getServicePortForward(options: {
|
getServicePortForward(
|
||||||
packageId: string;
|
internalPort: number,
|
||||||
internalPort: number;
|
packageId?: string
|
||||||
}): Promise<string>;
|
): Promise<number>;
|
||||||
|
|
||||||
/** When we want to create a link in the front end interfaces, and example is
|
/** When we want to create a link in the front end interfaces, and example is
|
||||||
* exposing a url to view a web service
|
* exposing a url to view a web service
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "start-sdk",
|
"name": "start-sdk",
|
||||||
"version": "0.4.0-lib0.charlie10",
|
"version": "0.4.0-lib0.charlie11",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "start-sdk",
|
"name": "start-sdk",
|
||||||
"version": "0.4.0-lib0.charlie10",
|
"version": "0.4.0-lib0.charlie11",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@iarna/toml": "^2.2.5",
|
"@iarna/toml": "^2.2.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "start-sdk",
|
"name": "start-sdk",
|
||||||
"version": "0.4.0-lib0.charlie10",
|
"version": "0.4.0-lib0.charlie11",
|
||||||
"description": "For making the patterns that are wanted in making services for the startOS.",
|
"description": "For making the patterns that are wanted in making services for the startOS.",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
|
|||||||
@@ -8,10 +8,15 @@ export async function writeConvertedFile(
|
|||||||
inputData: Promise<any> | any,
|
inputData: Promise<any> | any,
|
||||||
options: Parameters<typeof makeFileContent>[1]
|
options: Parameters<typeof makeFileContent>[1]
|
||||||
) {
|
) {
|
||||||
await fs.writeFile(file, await makeFileContent(inputData, options), (err) => console.error(err));
|
await fs.writeFile(file, await makeFileContent(inputData, options), (err) =>
|
||||||
|
console.error(err)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function makeFileContent(inputData: Promise<any> | any, { startSdk = "start-sdk" } = {}) {
|
export default async function makeFileContent(
|
||||||
|
inputData: Promise<any> | any,
|
||||||
|
{ startSdk = "start-sdk" } = {}
|
||||||
|
) {
|
||||||
const outputLines: string[] = [];
|
const outputLines: string[] = [];
|
||||||
outputLines.push(`
|
outputLines.push(`
|
||||||
import {Config, Value, List, Variants} from '${startSdk}/config/builder';
|
import {Config, Value, List, Variants} from '${startSdk}/config/builder';
|
||||||
@@ -20,8 +25,13 @@ export default async function makeFileContent(inputData: Promise<any> | any, { s
|
|||||||
|
|
||||||
const namedConsts = new Set(["Config", "Value", "List"]);
|
const namedConsts = new Set(["Config", "Value", "List"]);
|
||||||
const configName = newConst("InputSpec", convertInputSpec(data));
|
const configName = newConst("InputSpec", convertInputSpec(data));
|
||||||
const configMatcherName = newConst("matchInputSpec", `${configName}.validator()`);
|
const configMatcherName = newConst(
|
||||||
outputLines.push(`export type InputSpec = typeof ${configMatcherName}._TYPE;`);
|
"matchInputSpec",
|
||||||
|
`${configName}.validator()`
|
||||||
|
);
|
||||||
|
outputLines.push(
|
||||||
|
`export type InputSpec = typeof ${configMatcherName}._TYPE;`
|
||||||
|
);
|
||||||
|
|
||||||
return outputLines.join("\n");
|
return outputLines.join("\n");
|
||||||
|
|
||||||
@@ -101,7 +111,10 @@ export default async function makeFileContent(inputData: Promise<any> | any, { s
|
|||||||
)})`;
|
)})`;
|
||||||
}
|
}
|
||||||
case "enum": {
|
case "enum": {
|
||||||
const allValueNames = new Set([...(value?.["values"] || []), ...Object.keys(value?.["value-names"] || {})]);
|
const allValueNames = new Set([
|
||||||
|
...(value?.["values"] || []),
|
||||||
|
...Object.keys(value?.["value-names"] || {}),
|
||||||
|
]);
|
||||||
const values = Object.fromEntries(
|
const values = Object.fromEntries(
|
||||||
Array.from(allValueNames)
|
Array.from(allValueNames)
|
||||||
.filter(string.test)
|
.filter(string.test)
|
||||||
@@ -121,12 +134,14 @@ export default async function makeFileContent(inputData: Promise<any> | any, { s
|
|||||||
)} as const)`;
|
)} as const)`;
|
||||||
}
|
}
|
||||||
case "object": {
|
case "object": {
|
||||||
const specName = newConst(value.name + "_spec", convertInputSpec(value.spec));
|
const specName = newConst(
|
||||||
|
value.name + "_spec",
|
||||||
|
convertInputSpec(value.spec)
|
||||||
|
);
|
||||||
return `Value.object({
|
return `Value.object({
|
||||||
name: ${JSON.stringify(value.name || null)},
|
name: ${JSON.stringify(value.name || null)},
|
||||||
description: ${JSON.stringify(value.description || null)},
|
description: ${JSON.stringify(value.description || null)},
|
||||||
warning: ${JSON.stringify(value.warning || null)},
|
warning: ${JSON.stringify(value.warning || null)},
|
||||||
default: ${JSON.stringify(value.default || null)},
|
|
||||||
}, ${specName})`;
|
}, ${specName})`;
|
||||||
}
|
}
|
||||||
case "union": {
|
case "union": {
|
||||||
@@ -157,7 +172,9 @@ export default async function makeFileContent(inputData: Promise<any> | any, { s
|
|||||||
function convertList(value: any) {
|
function convertList(value: any) {
|
||||||
switch (value.subtype) {
|
switch (value.subtype) {
|
||||||
case "string": {
|
case "string": {
|
||||||
return `List.${value?.spec?.textarea === true ? "textarea" : "string"}(${JSON.stringify(
|
return `List.${
|
||||||
|
value?.spec?.textarea === true ? "textarea" : "string"
|
||||||
|
}(${JSON.stringify(
|
||||||
{
|
{
|
||||||
name: value.name || null,
|
name: value.name || null,
|
||||||
range: value.range || null,
|
range: value.range || null,
|
||||||
@@ -216,7 +233,10 @@ export default async function makeFileContent(inputData: Promise<any> | any, { s
|
|||||||
)})`;
|
)})`;
|
||||||
}
|
}
|
||||||
case "object": {
|
case "object": {
|
||||||
const specName = newConst(value.name + "_spec", convertInputSpec(value.spec.spec));
|
const specName = newConst(
|
||||||
|
value.name + "_spec",
|
||||||
|
convertInputSpec(value.spec.spec)
|
||||||
|
);
|
||||||
return `List.obj({
|
return `List.obj({
|
||||||
name: ${JSON.stringify(value.name || null)},
|
name: ${JSON.stringify(value.name || null)},
|
||||||
range: ${JSON.stringify(value.range || null)},
|
range: ${JSON.stringify(value.range || null)},
|
||||||
@@ -232,14 +252,19 @@ export default async function makeFileContent(inputData: Promise<any> | any, { s
|
|||||||
case "union": {
|
case "union": {
|
||||||
const variants = newConst(
|
const variants = newConst(
|
||||||
value.name + "_variants",
|
value.name + "_variants",
|
||||||
convertVariants(value.spec.variants, value.spec["variant-names"] || {})
|
convertVariants(
|
||||||
|
value.spec.variants,
|
||||||
|
value.spec["variant-names"] || {}
|
||||||
|
)
|
||||||
);
|
);
|
||||||
const unionValueName = newConst(
|
const unionValueName = newConst(
|
||||||
value.name + "_union",
|
value.name + "_union",
|
||||||
`
|
`
|
||||||
Value.union({
|
Value.union({
|
||||||
name: ${JSON.stringify(value?.spec?.tag?.name || null)},
|
name: ${JSON.stringify(value?.spec?.tag?.name || null)},
|
||||||
description: ${JSON.stringify(value?.spec?.tag?.description || null)},
|
description: ${JSON.stringify(
|
||||||
|
value?.spec?.tag?.description || null
|
||||||
|
)},
|
||||||
warning: ${JSON.stringify(value?.spec?.tag?.warning || null)},
|
warning: ${JSON.stringify(value?.spec?.tag?.warning || null)},
|
||||||
required: ${JSON.stringify(!(value?.spec?.tag?.nullable || false))},
|
required: ${JSON.stringify(!(value?.spec?.tag?.nullable || false))},
|
||||||
default: ${JSON.stringify(value?.spec?.default || null)},
|
default: ${JSON.stringify(value?.spec?.default || null)},
|
||||||
@@ -270,11 +295,16 @@ export default async function makeFileContent(inputData: Promise<any> | any, { s
|
|||||||
throw new Error(`Unknown subtype "${value.subtype}"`);
|
throw new Error(`Unknown subtype "${value.subtype}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function convertVariants(variants: Record<string, unknown>, variantNames: Record<string, string>): string {
|
function convertVariants(
|
||||||
|
variants: Record<string, unknown>,
|
||||||
|
variantNames: Record<string, string>
|
||||||
|
): string {
|
||||||
let answer = "Variants.of({";
|
let answer = "Variants.of({";
|
||||||
for (const [key, value] of Object.entries(variants)) {
|
for (const [key, value] of Object.entries(variants)) {
|
||||||
const variantSpec = newConst(key, convertInputSpec(value));
|
const variantSpec = newConst(key, convertInputSpec(value));
|
||||||
answer += `"${key}": {name: "${variantNames[key] || key}", spec: ${variantSpec}},`;
|
answer += `"${key}": {name: "${
|
||||||
|
variantNames[key] || key
|
||||||
|
}", spec: ${variantSpec}},`;
|
||||||
}
|
}
|
||||||
return `${answer}})`;
|
return `${answer}})`;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user