@wirecat/cli-base 0.21.0 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -1
- package/dist/commands/document.d.ts +72 -0
- package/dist/commands/document.d.ts.map +1 -0
- package/dist/commands/document.js +71 -0
- package/dist/commands/document.js.map +1 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +23 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/deadline.js +3 -3
- package/dist/deadline.js.map +1 -1
- package/dist/dev/bin.js +0 -0
- package/dist/dev/lint.d.ts +31 -0
- package/dist/dev/lint.d.ts.map +1 -0
- package/dist/dev/lint.js +148 -0
- package/dist/dev/lint.js.map +1 -0
- package/dist/dev/main.d.ts.map +1 -1
- package/dist/dev/main.js +132 -2
- package/dist/dev/main.js.map +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +5 -1
- package/dist/errors.js.map +1 -1
- package/dist/output-buffer.js +2 -2
- package/dist/output-buffer.js.map +1 -1
- package/dist/standards/errors.d.ts +40 -0
- package/dist/standards/errors.d.ts.map +1 -0
- package/dist/standards/errors.js +33 -0
- package/dist/standards/errors.js.map +1 -0
- package/dist/standards/index.d.ts +8 -0
- package/dist/standards/index.d.ts.map +1 -0
- package/dist/standards/index.js +8 -0
- package/dist/standards/index.js.map +1 -0
- package/dist/standards/lint.d.ts +29 -0
- package/dist/standards/lint.d.ts.map +1 -0
- package/dist/standards/lint.js +50 -0
- package/dist/standards/lint.js.map +1 -0
- package/dist/standards/log.d.ts +21 -0
- package/dist/standards/log.d.ts.map +1 -0
- package/dist/standards/log.js +18 -0
- package/dist/standards/log.js.map +1 -0
- package/dist/standards/output.d.ts +126 -0
- package/dist/standards/output.d.ts.map +1 -0
- package/dist/standards/output.js +54 -0
- package/dist/standards/output.js.map +1 -0
- package/dist/standards/registry.d.ts +18 -0
- package/dist/standards/registry.d.ts.map +1 -0
- package/dist/standards/registry.js +41 -0
- package/dist/standards/registry.js.map +1 -0
- package/dist/standards/steps.d.ts +28 -0
- package/dist/standards/steps.d.ts.map +1 -0
- package/dist/standards/steps.js +56 -0
- package/dist/standards/steps.js.map +1 -0
- package/dist/standards/vocabulary.d.ts +40 -0
- package/dist/standards/vocabulary.d.ts.map +1 -0
- package/dist/standards/vocabulary.js +242 -0
- package/dist/standards/vocabulary.js.map +1 -0
- package/package.json +27 -19
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
/** At most three next steps per answer, the most useful first. */
|
|
3
|
+
export declare const MAX_NEXT_STEPS = 3;
|
|
4
|
+
export declare const isoTime: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.IsoTimestampAction<string, "an ISO 8601 time with a zone">]>;
|
|
5
|
+
export declare const nextStepSchema: v.StrictObjectSchema<{
|
|
6
|
+
readonly step: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
7
|
+
/** The command path as one string, `messages list` — what the MCP router tools take as `command`. */
|
|
8
|
+
readonly command: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
9
|
+
readonly args: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
|
|
10
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
11
|
+
}, undefined>;
|
|
12
|
+
export declare const missingSchema: v.StrictObjectSchema<{
|
|
13
|
+
readonly field: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
14
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
15
|
+
readonly step: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
16
|
+
}, undefined>;
|
|
17
|
+
export declare const pageSchema: v.StrictObjectSchema<{
|
|
18
|
+
readonly limit: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
19
|
+
readonly hasMore: v.BooleanSchema<undefined>;
|
|
20
|
+
readonly cursor: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>;
|
|
21
|
+
}, undefined>;
|
|
22
|
+
export declare const metaSchema: v.StrictObjectSchema<{
|
|
23
|
+
readonly runId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
24
|
+
readonly durationMs: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
25
|
+
readonly accounts: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>, undefined>;
|
|
26
|
+
readonly skipped: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
27
|
+
readonly account: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
28
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
29
|
+
}, undefined>, undefined>, undefined>;
|
|
30
|
+
readonly truncated: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
31
|
+
}, undefined>;
|
|
32
|
+
export declare const listEnvelopeSchema: <T extends v.GenericSchema>(item: T) => v.StrictObjectSchema<{
|
|
33
|
+
readonly items: v.ArraySchema<T, undefined>;
|
|
34
|
+
readonly page: v.StrictObjectSchema<{
|
|
35
|
+
readonly limit: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 1, undefined>]>;
|
|
36
|
+
readonly hasMore: v.BooleanSchema<undefined>;
|
|
37
|
+
readonly cursor: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>;
|
|
38
|
+
}, undefined>;
|
|
39
|
+
readonly next: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StrictObjectSchema<{
|
|
40
|
+
readonly step: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
41
|
+
/** The command path as one string, `messages list` — what the MCP router tools take as `command`. */
|
|
42
|
+
readonly command: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
43
|
+
readonly args: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
|
|
44
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
45
|
+
}, undefined>, undefined>, v.MaxLengthAction<{
|
|
46
|
+
step: string;
|
|
47
|
+
command: string;
|
|
48
|
+
args: {
|
|
49
|
+
[x: string]: unknown;
|
|
50
|
+
};
|
|
51
|
+
why: string;
|
|
52
|
+
}[], 3, undefined>]>, undefined>;
|
|
53
|
+
readonly missing: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
54
|
+
readonly field: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
55
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
56
|
+
readonly step: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
57
|
+
}, undefined>, undefined>, undefined>;
|
|
58
|
+
readonly meta: v.StrictObjectSchema<{
|
|
59
|
+
readonly runId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
60
|
+
readonly durationMs: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
61
|
+
readonly accounts: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>, undefined>;
|
|
62
|
+
readonly skipped: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
63
|
+
readonly account: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
64
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
65
|
+
}, undefined>, undefined>, undefined>;
|
|
66
|
+
readonly truncated: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
67
|
+
}, undefined>;
|
|
68
|
+
}, undefined>;
|
|
69
|
+
export declare const itemEnvelopeSchema: <T extends v.GenericSchema>(item: T) => v.StrictObjectSchema<{
|
|
70
|
+
readonly item: T;
|
|
71
|
+
readonly next: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StrictObjectSchema<{
|
|
72
|
+
readonly step: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
73
|
+
/** The command path as one string, `messages list` — what the MCP router tools take as `command`. */
|
|
74
|
+
readonly command: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
75
|
+
readonly args: v.RecordSchema<v.StringSchema<undefined>, v.UnknownSchema, undefined>;
|
|
76
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
77
|
+
}, undefined>, undefined>, v.MaxLengthAction<{
|
|
78
|
+
step: string;
|
|
79
|
+
command: string;
|
|
80
|
+
args: {
|
|
81
|
+
[x: string]: unknown;
|
|
82
|
+
};
|
|
83
|
+
why: string;
|
|
84
|
+
}[], 3, undefined>]>, undefined>;
|
|
85
|
+
readonly missing: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
86
|
+
readonly field: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
87
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
88
|
+
readonly step: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
89
|
+
}, undefined>, undefined>, undefined>;
|
|
90
|
+
readonly meta: v.StrictObjectSchema<{
|
|
91
|
+
readonly runId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
92
|
+
readonly durationMs: v.SchemaWithPipe<readonly [v.NumberSchema<undefined>, v.IntegerAction<number, undefined>, v.MinValueAction<number, 0, undefined>]>;
|
|
93
|
+
readonly accounts: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>, undefined>;
|
|
94
|
+
readonly skipped: v.OptionalSchema<v.ArraySchema<v.StrictObjectSchema<{
|
|
95
|
+
readonly account: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
96
|
+
readonly why: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
97
|
+
}, undefined>, undefined>, undefined>;
|
|
98
|
+
readonly truncated: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
99
|
+
}, undefined>;
|
|
100
|
+
}, undefined>;
|
|
101
|
+
export type NextStep = v.InferOutput<typeof nextStepSchema>;
|
|
102
|
+
export type Missing = v.InferOutput<typeof missingSchema>;
|
|
103
|
+
export type Page = v.InferOutput<typeof pageSchema>;
|
|
104
|
+
export type Meta = v.InferOutput<typeof metaSchema>;
|
|
105
|
+
export interface ListEnvelope<T> {
|
|
106
|
+
items: T[];
|
|
107
|
+
page: Page;
|
|
108
|
+
next?: NextStep[];
|
|
109
|
+
missing?: Missing[];
|
|
110
|
+
meta: Meta;
|
|
111
|
+
}
|
|
112
|
+
export interface ItemEnvelope<T> {
|
|
113
|
+
item: T;
|
|
114
|
+
next?: NextStep[];
|
|
115
|
+
missing?: Missing[];
|
|
116
|
+
meta: Meta;
|
|
117
|
+
}
|
|
118
|
+
declare const fieldRuleSchema: v.StrictObjectSchema<{
|
|
119
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
120
|
+
readonly rule: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
121
|
+
}, undefined>;
|
|
122
|
+
export type FieldRule = v.InferOutput<typeof fieldRuleSchema>;
|
|
123
|
+
export declare const defineFieldRules: (input: unknown) => FieldRule[];
|
|
124
|
+
export declare const FIELD_RULES: FieldRule[];
|
|
125
|
+
export {};
|
|
126
|
+
//# sourceMappingURL=output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/standards/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAG5B,kEAAkE;AAClE,eAAO,MAAM,cAAc,IAAI,CAAA;AAE/B,eAAO,MAAM,OAAO,sHAAqE,CAAA;AAEzF,eAAO,MAAM,cAAc;;IAEzB,qGAAqG;;;;aAIrG,CAAA;AAEF,eAAO,MAAM,aAAa;;;;aAIxB,CAAA;AAEF,eAAO,MAAM,UAAU;;;;aAIrB,CAAA;AAEF,eAAO,MAAM,UAAU;;;;;;;;;aAMrB,CAAA;AAIF,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,QAAQ,CAAC;;;;;;;;;QA5BnE,qGAAqG;;;;;;;;;;;;;;;;;;;;;;;;;;;aAmCnG,CAAA;AAEJ,eAAO,MAAM,kBAAkB,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,QAAQ,CAAC;;;;QArCnE,qGAAqG;;;;;;;;;;;;;;;;;;;;;;;;;;;aA2CnG,CAAA;AAEJ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,cAAc,CAAC,CAAA;AAC3D,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,aAAa,CAAC,CAAA;AACzD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,MAAM,IAAI,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AACnD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,KAAK,EAAE,CAAC,EAAE,CAAA;IACV,IAAI,EAAE,IAAI,CAAA;IACV,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;CACX;AACD,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,IAAI,EAAE,CAAC,CAAA;IACP,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAA;IACjB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAA;IACnB,IAAI,EAAE,IAAI,CAAA;CACX;AAED,QAAA,MAAM,eAAe;;;aAA2C,CAAA;AAChE,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,eAAe,CAAC,CAAA;AAE7D,eAAO,MAAM,gBAAgB,UAAW,OAAO,KAAG,SAAS,EAGxD,CAAA;AAEH,eAAO,MAAM,WAAW,EAAE,SAAS,EAOjC,CAAA"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import { dottedId, duplicates, parseRegistry, text, word } from "./registry.js";
|
|
3
|
+
/** At most three next steps per answer, the most useful first. */
|
|
4
|
+
export const MAX_NEXT_STEPS = 3;
|
|
5
|
+
export const isoTime = v.pipe(v.string(), v.isoTimestamp("an ISO 8601 time with a zone"));
|
|
6
|
+
export const nextStepSchema = v.strictObject({
|
|
7
|
+
step: dottedId,
|
|
8
|
+
/** The command path as one string, `messages list` — what the MCP router tools take as `command`. */
|
|
9
|
+
command: text,
|
|
10
|
+
args: v.record(v.string(), v.unknown()),
|
|
11
|
+
why: text,
|
|
12
|
+
});
|
|
13
|
+
export const missingSchema = v.strictObject({
|
|
14
|
+
field: text,
|
|
15
|
+
why: text,
|
|
16
|
+
step: dottedId,
|
|
17
|
+
});
|
|
18
|
+
export const pageSchema = v.strictObject({
|
|
19
|
+
limit: v.pipe(v.number(), v.integer(), v.minValue(1)),
|
|
20
|
+
hasMore: v.boolean(),
|
|
21
|
+
cursor: v.optional(text),
|
|
22
|
+
});
|
|
23
|
+
export const metaSchema = v.strictObject({
|
|
24
|
+
runId: text,
|
|
25
|
+
durationMs: v.pipe(v.number(), v.integer(), v.minValue(0)),
|
|
26
|
+
accounts: v.optional(v.array(text)),
|
|
27
|
+
skipped: v.optional(v.array(v.strictObject({ account: text, why: text }))),
|
|
28
|
+
truncated: v.optional(v.boolean()),
|
|
29
|
+
});
|
|
30
|
+
const nextSteps = v.optional(v.pipe(v.array(nextStepSchema), v.maxLength(MAX_NEXT_STEPS)));
|
|
31
|
+
export const listEnvelopeSchema = (item) => v.strictObject({
|
|
32
|
+
items: v.array(item),
|
|
33
|
+
page: pageSchema,
|
|
34
|
+
next: nextSteps,
|
|
35
|
+
missing: v.optional(v.array(missingSchema)),
|
|
36
|
+
meta: metaSchema,
|
|
37
|
+
});
|
|
38
|
+
export const itemEnvelopeSchema = (item) => v.strictObject({
|
|
39
|
+
item,
|
|
40
|
+
next: nextSteps,
|
|
41
|
+
missing: v.optional(v.array(missingSchema)),
|
|
42
|
+
meta: metaSchema,
|
|
43
|
+
});
|
|
44
|
+
const fieldRuleSchema = v.strictObject({ id: word, rule: text });
|
|
45
|
+
export const defineFieldRules = (input) => parseRegistry("output field rules", v.array(fieldRuleSchema), input, (rules) => duplicates(rules.map((rule) => rule.id)).map((id) => `"${id}" is listed twice`));
|
|
46
|
+
export const FIELD_RULES = defineFieldRules([
|
|
47
|
+
{ id: "envelope", rule: "every JSON answer is one object: a list `{items, page, …}`, one thing `{item, …}`" },
|
|
48
|
+
{ id: "time", rule: "a time is an ISO 8601 string with a zone, never epoch milliseconds" },
|
|
49
|
+
{ id: "duration", rule: "a length of time is a number of milliseconds in a field ending in `Ms`" },
|
|
50
|
+
{ id: "ref", rule: "a stored thing is named by `ref`; a message's `ref` value is its locator" },
|
|
51
|
+
{ id: "camel-case", rule: "keys are camelCase words, no abbreviations a reader has to decode" },
|
|
52
|
+
{ id: "one-meaning", rule: "a key has one meaning and one type in every answer of every CLI" },
|
|
53
|
+
]);
|
|
54
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/standards/output.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
export declare const word: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
3
|
+
export declare const text: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
4
|
+
export declare const dottedId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
5
|
+
export declare class RegistryError extends Error {
|
|
6
|
+
readonly registry: string;
|
|
7
|
+
readonly problems: readonly string[];
|
|
8
|
+
constructor(registry: string, problems: readonly string[]);
|
|
9
|
+
}
|
|
10
|
+
export declare const issuesOf: (issues: readonly v.BaseIssue<unknown>[]) => string[];
|
|
11
|
+
/** Parses a registry, then runs its own checks over the parsed entries; throws one error naming every problem. */
|
|
12
|
+
export declare const parseRegistry: <S extends v.GenericSchema>(registry: string, schema: S, input: unknown, check?: (parsed: v.InferOutput<S>) => string[]) => v.InferOutput<S>;
|
|
13
|
+
export declare const duplicates: (values: readonly string[]) => string[];
|
|
14
|
+
export declare const jsonSchemaOf: (schema: v.GenericSchema, definitions?: Record<string, v.GenericSchema>) => import("@valibot/to-json-schema").JsonSchema;
|
|
15
|
+
export declare const placeholders: (template: string) => string[];
|
|
16
|
+
/** Fills `{name}` from `values`; a placeholder with no value throws, so a half-filled sentence never ships. */
|
|
17
|
+
export declare const fill: (template: string, values: Readonly<Record<string, string | number>>) => string;
|
|
18
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/standards/registry.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,eAAO,MAAM,IAAI,uHAAuG,CAAA;AACxH,eAAO,MAAM,IAAI,oGAAyD,CAAA;AAC1E,eAAO,MAAM,QAAQ,+HAGpB,CAAA;AAED,qBAAa,aAAc,SAAQ,KAAK;IAEpC,QAAQ,CAAC,QAAQ,EAAE,MAAM;IACzB,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE;IAFtC,YACW,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,SAAS,MAAM,EAAE,EAIrC;CACF;AAED,eAAO,MAAM,QAAQ,WAAY,SAAS,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,KAAG,MAAM,EAIrE,CAAA;AAEJ,kHAAkH;AAClH,eAAO,MAAM,aAAa,GAAI,CAAC,SAAS,CAAC,CAAC,aAAa,YAC3C,MAAM,UACR,CAAC,SACF,OAAO,UACP,CAAC,MAAM,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,KAC5C,CAAC,CAAC,WAAW,CAAC,CAAC,CAMjB,CAAA;AAED,eAAO,MAAM,UAAU,WAAY,SAAS,MAAM,EAAE,KAAG,MAAM,EAC0B,CAAA;AAEvF,eAAO,MAAM,YAAY,WAAY,CAAC,CAAC,aAAa,gBAAgB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,aAAa,CAAC,iDACP,CAAA;AAI5F,eAAO,MAAM,YAAY,aAAc,MAAM,KAAG,MAAM,EACc,CAAA;AAEpE,+GAA+G;AAC/G,eAAO,MAAM,IAAI,aAAc,MAAM,UAAU,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,KAAG,MAKvF,CAAA"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { toJsonSchema } from "@valibot/to-json-schema";
|
|
2
|
+
import * as v from "valibot";
|
|
3
|
+
export const word = v.pipe(v.string(), v.regex(/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/, "a lower-case word, words joined by -"));
|
|
4
|
+
export const text = v.pipe(v.string(), v.regex(/\S/, "must not be empty"));
|
|
5
|
+
export const dottedId = v.pipe(v.string(), v.regex(/^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)+$/, "dotted lower-case words, such as `page.next`"));
|
|
6
|
+
export class RegistryError extends Error {
|
|
7
|
+
registry;
|
|
8
|
+
problems;
|
|
9
|
+
constructor(registry, problems) {
|
|
10
|
+
super(`${registry} registry: ${problems.join("; ")}`);
|
|
11
|
+
this.registry = registry;
|
|
12
|
+
this.problems = problems;
|
|
13
|
+
this.name = "RegistryError";
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export const issuesOf = (issues) => issues.map((issue) => {
|
|
17
|
+
const path = v.getDotPath(issue);
|
|
18
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
19
|
+
});
|
|
20
|
+
/** Parses a registry, then runs its own checks over the parsed entries; throws one error naming every problem. */
|
|
21
|
+
export const parseRegistry = (registry, schema, input, check = () => []) => {
|
|
22
|
+
const parsed = v.safeParse(schema, input);
|
|
23
|
+
if (!parsed.success)
|
|
24
|
+
throw new RegistryError(registry, issuesOf(parsed.issues));
|
|
25
|
+
const problems = check(parsed.output);
|
|
26
|
+
if (problems.length > 0)
|
|
27
|
+
throw new RegistryError(registry, problems);
|
|
28
|
+
return parsed.output;
|
|
29
|
+
};
|
|
30
|
+
export const duplicates = (values) => [...new Set(values.filter((value, index) => values.indexOf(value) !== index))].sort();
|
|
31
|
+
export const jsonSchemaOf = (schema, definitions) => toJsonSchema(schema, { target: "draft-2020-12", ...(definitions ? { definitions } : {}) });
|
|
32
|
+
const PLACEHOLDER = /\{([a-zA-Z][a-zA-Z0-9]*)\}/g;
|
|
33
|
+
export const placeholders = (template) => [...template.matchAll(PLACEHOLDER)].map((match) => match[1] ?? "");
|
|
34
|
+
/** Fills `{name}` from `values`; a placeholder with no value throws, so a half-filled sentence never ships. */
|
|
35
|
+
export const fill = (template, values) => template.replace(PLACEHOLDER, (_, name) => {
|
|
36
|
+
const value = values[name];
|
|
37
|
+
if (value === undefined)
|
|
38
|
+
throw new Error(`no value for {${name}} in "${template}"`);
|
|
39
|
+
return String(value);
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/standards/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AACtD,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,+BAA+B,EAAE,sCAAsC,CAAC,CAAC,CAAA;AACxH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC,CAAA;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,IAAI,CAC5B,CAAC,CAAC,MAAM,EAAE,EACV,CAAC,CAAC,KAAK,CAAC,uCAAuC,EAAE,8CAA8C,CAAC,CACjG,CAAA;AAED,MAAM,OAAO,aAAc,SAAQ,KAAK;IAE3B,QAAQ;IACR,QAAQ;IAFnB,YACW,QAAgB,EAChB,QAA2B;QAEpC,KAAK,CAAC,GAAG,QAAQ,cAAc,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;wBAH5C,QAAQ;wBACR,QAAQ;QAGjB,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;IAC7B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,MAAuC,EAAY,EAAE,CAC5E,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;IACnB,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAA;IAChC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAA;AAC3D,CAAC,CAAC,CAAA;AAEJ,kHAAkH;AAClH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,QAAgB,EAChB,MAAS,EACT,KAAc,EACd,KAAK,GAA2C,GAAG,EAAE,CAAC,EAAE,EACtC,EAAE;IACpB,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IACzC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,IAAI,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IAC/E,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACrC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,IAAI,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IACpE,OAAO,MAAM,CAAC,MAAM,CAAA;AACtB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,MAAyB,EAAY,EAAE,CAChE,CAAC,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;AAEvF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAuB,EAAE,WAA6C,EAAE,EAAE,CACrG,YAAY,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;AAE5F,MAAM,WAAW,GAAG,6BAA6B,CAAA;AAEjD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,QAAgB,EAAY,EAAE,CACzD,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;AAEpE,+GAA+G;AAC/G,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,QAAgB,EAAE,MAAiD,EAAU,EAAE,CAClG,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,IAAY,EAAE,EAAE;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;IAC1B,IAAI,KAAK,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,SAAS,QAAQ,GAAG,CAAC,CAAA;IACnF,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;AACtB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import type { NextStep } from "./output.js";
|
|
3
|
+
/** A step's command: a path such as `messages sync`, or `*` for the command that gave the answer (`page.next`). */
|
|
4
|
+
export declare const SAME_COMMAND = "*";
|
|
5
|
+
declare const stepSchema: v.StrictObjectSchema<{
|
|
6
|
+
readonly id: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "dotted lower-case words, such as `page.next`">]>;
|
|
7
|
+
readonly command: v.UnionSchema<[v.LiteralSchema<"*", undefined>, v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a command path such as `messages sync`">]>], undefined>;
|
|
8
|
+
readonly args: v.ArraySchema<v.StrictObjectSchema<{
|
|
9
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "an argument or option name in camelCase">]>;
|
|
10
|
+
readonly required: v.BooleanSchema<undefined>;
|
|
11
|
+
}, undefined>, undefined>;
|
|
12
|
+
readonly why: v.SchemaWithPipe<readonly [v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, v.MaxLengthAction<string, 120, undefined>]>;
|
|
13
|
+
}, undefined>;
|
|
14
|
+
export type StepDefinition = v.InferOutput<typeof stepSchema>;
|
|
15
|
+
export declare const defineSteps: (input: unknown) => StepDefinition[];
|
|
16
|
+
export interface StepInput {
|
|
17
|
+
args: Readonly<Record<string, unknown>>;
|
|
18
|
+
/** Values for the `{placeholders}` of `why` that are not arguments. */
|
|
19
|
+
values?: Readonly<Record<string, string | number>>;
|
|
20
|
+
/** Required when the step's command is `*`. */
|
|
21
|
+
command?: string;
|
|
22
|
+
}
|
|
23
|
+
/** One `next` entry from its definition: checks the arguments and fills `why`. */
|
|
24
|
+
export declare const stepOf: (definition: StepDefinition, input: StepInput) => NextStep;
|
|
25
|
+
/** The steps every CLI has; each package adds its own with `defineSteps`. */
|
|
26
|
+
export declare const STEPS: StepDefinition[];
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=steps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.d.ts","sourceRoot":"","sources":["../../src/standards/steps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAG3C,mHAAmH;AACnH,eAAO,MAAM,YAAY,MAAM,CAAA;AAE/B,QAAA,MAAM,UAAU;;;;;;;;aAad,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,CAAA;AAE7D,eAAO,MAAM,WAAW,UAAW,OAAO,KAAG,cAAc,EAMvD,CAAA;AAEJ,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;IACvC,uEAAuE;IACvE,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,CAAA;IAClD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,kFAAkF;AAClF,eAAO,MAAM,MAAM,eAAgB,cAAc,SAAS,SAAS,KAAG,QAsBrE,CAAA;AAED,6EAA6E;AAC7E,eAAO,MAAM,KAAK,EAAE,cAAc,EAWhC,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import { dottedId, duplicates, fill, parseRegistry, text } from "./registry.js";
|
|
3
|
+
/** A step's command: a path such as `messages sync`, or `*` for the command that gave the answer (`page.next`). */
|
|
4
|
+
export const SAME_COMMAND = "*";
|
|
5
|
+
const stepSchema = v.strictObject({
|
|
6
|
+
id: dottedId,
|
|
7
|
+
command: v.union([
|
|
8
|
+
v.literal(SAME_COMMAND),
|
|
9
|
+
v.pipe(v.string(), v.regex(/^[a-z][a-z0-9-]*( [a-z][a-z0-9-]*)*$/, "a command path such as `messages sync`")),
|
|
10
|
+
]),
|
|
11
|
+
args: v.array(v.strictObject({
|
|
12
|
+
name: v.pipe(v.string(), v.regex(/^[a-z][a-zA-Z0-9]*$/, "an argument or option name in camelCase")),
|
|
13
|
+
required: v.boolean(),
|
|
14
|
+
})),
|
|
15
|
+
why: v.pipe(text, v.maxLength(120)),
|
|
16
|
+
});
|
|
17
|
+
export const defineSteps = (input) => parseRegistry("steps", v.array(stepSchema), input, (steps) => [
|
|
18
|
+
...duplicates(steps.map((step) => step.id)).map((id) => `"${id}" is listed twice`),
|
|
19
|
+
...steps.flatMap((step) => duplicates(step.args.map((arg) => arg.name)).map((name) => `${step.id}: argument "${name}" is listed twice`)),
|
|
20
|
+
]);
|
|
21
|
+
/** One `next` entry from its definition: checks the arguments and fills `why`. */
|
|
22
|
+
export const stepOf = (definition, input) => {
|
|
23
|
+
const command = definition.command === SAME_COMMAND ? input.command : definition.command;
|
|
24
|
+
if (!command)
|
|
25
|
+
throw new Error(`${definition.id}: the step runs the same command, so pass the command`);
|
|
26
|
+
const known = new Set(definition.args.map((arg) => arg.name));
|
|
27
|
+
// A step that reruns the answer's command carries that command's own arguments too.
|
|
28
|
+
if (definition.command !== SAME_COMMAND)
|
|
29
|
+
for (const name of Object.keys(input.args))
|
|
30
|
+
if (!known.has(name))
|
|
31
|
+
throw new Error(`${definition.id}: no argument "${name}"`);
|
|
32
|
+
for (const arg of definition.args)
|
|
33
|
+
if (arg.required && input.args[arg.name] === undefined)
|
|
34
|
+
throw new Error(`${definition.id}: argument "${arg.name}" is required`);
|
|
35
|
+
const scalars = Object.fromEntries(Object.entries(input.args).filter((entry) => ["string", "number"].includes(typeof entry[1])));
|
|
36
|
+
return {
|
|
37
|
+
step: definition.id,
|
|
38
|
+
command,
|
|
39
|
+
args: { ...input.args },
|
|
40
|
+
why: fill(definition.why, { ...scalars, ...input.values }),
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
/** The steps every CLI has; each package adds its own with `defineSteps`. */
|
|
44
|
+
export const STEPS = defineSteps([
|
|
45
|
+
{
|
|
46
|
+
id: "page.next",
|
|
47
|
+
command: SAME_COMMAND,
|
|
48
|
+
args: [
|
|
49
|
+
{ name: "cursor", required: false },
|
|
50
|
+
{ name: "page", required: false },
|
|
51
|
+
{ name: "limit", required: false },
|
|
52
|
+
],
|
|
53
|
+
why: "{shown} shown, more exist",
|
|
54
|
+
},
|
|
55
|
+
]);
|
|
56
|
+
//# sourceMappingURL=steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"steps.js","sourceRoot":"","sources":["../../src/standards/steps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAE/E,mHAAmH;AACnH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;AAE/B,MAAM,UAAU,GAAG,CAAC,CAAC,YAAY,CAAC;IAChC,EAAE,EAAE,QAAQ;IACZ,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC;QACf,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;QACvB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,sCAAsC,EAAE,wCAAwC,CAAC,CAAC;KAC9G,CAAC;IACF,IAAI,EAAE,CAAC,CAAC,KAAK,CACX,CAAC,CAAC,YAAY,CAAC;QACb,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,qBAAqB,EAAE,yCAAyC,CAAC,CAAC;QACnG,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE;KACtB,CAAC,CACH;IACD,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CACpC,CAAC,CAAA;AAIF,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,KAAc,EAAoB,EAAE,CAC9D,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC;IAC5D,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,mBAAmB,CAAC;IAClF,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CACxB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,EAAE,eAAe,IAAI,mBAAmB,CAAC,CAC7G;CACF,CAAC,CAAA;AAUJ,kFAAkF;AAClF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,UAA0B,EAAE,KAAgB,EAAY,EAAE;IAC/E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAA;IACxF,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,CAAC,EAAE,uDAAuD,CAAC,CAAA;IACtG,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAA;IAC7D,oFAAoF;IACpF,IAAI,UAAU,CAAC,OAAO,KAAK,YAAY;QACrC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;YACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,CAAC,EAAE,kBAAkB,IAAI,GAAG,CAAC,CAAA;IACpF,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI;QAC/B,IAAI,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,SAAS;YACpD,MAAM,IAAI,KAAK,CAAC,GAAG,UAAU,CAAC,EAAE,eAAe,GAAG,CAAC,IAAI,eAAe,CAAC,CAAA;IAC3E,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAChC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAsC,EAAE,CAC9E,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAC/C,CACF,CAAA;IACD,OAAO;QACL,IAAI,EAAE,UAAU,CAAC,EAAE;QACnB,OAAO;QACP,IAAI,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE;QACvB,GAAG,EAAE,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;KAC3D,CAAA;AACH,CAAC,CAAA;AAED,6EAA6E;AAC7E,MAAM,CAAC,MAAM,KAAK,GAAqB,WAAW,CAAC;IACjD;QACE,EAAE,EAAE,WAAW;QACf,OAAO,EAAE,YAAY;QACrB,IAAI,EAAE;YACJ,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE;YACnC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE;YACjC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE;SACnC;QACD,GAAG,EAAE,2BAA2B;KACjC;CACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
export declare const FLAG_TYPES: readonly ["switch", "count", "number", "string", "id", "time", "duration", "choice", "list", "path", "cursor"];
|
|
3
|
+
export declare const vocabularySchema: v.StrictObjectSchema<{
|
|
4
|
+
readonly verbs: v.ArraySchema<v.StrictObjectSchema<{
|
|
5
|
+
readonly word: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
6
|
+
readonly meaning: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
7
|
+
readonly replaces: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>, undefined>, undefined>;
|
|
8
|
+
}, undefined>, undefined>;
|
|
9
|
+
readonly nouns: v.ArraySchema<v.StrictObjectSchema<{
|
|
10
|
+
readonly word: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
11
|
+
readonly meaning: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
12
|
+
readonly kind: v.PicklistSchema<["collection", "singular"], undefined>;
|
|
13
|
+
readonly replaces: v.OptionalSchema<v.ArraySchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>, undefined>, undefined>;
|
|
14
|
+
}, undefined>, undefined>;
|
|
15
|
+
readonly views: v.ArraySchema<v.StrictObjectSchema<{
|
|
16
|
+
readonly word: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
17
|
+
readonly meaning: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
18
|
+
}, undefined>, undefined>;
|
|
19
|
+
readonly roots: v.ArraySchema<v.StrictObjectSchema<{
|
|
20
|
+
readonly word: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a lower-case word, words joined by -">]>;
|
|
21
|
+
readonly meaning: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
22
|
+
}, undefined>, undefined>;
|
|
23
|
+
readonly flags: v.ArraySchema<v.StrictObjectSchema<{
|
|
24
|
+
readonly name: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a long flag: --lower-case-words">]>;
|
|
25
|
+
readonly value: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "a value name such as <n>">]>, undefined>;
|
|
26
|
+
readonly type: v.PicklistSchema<readonly ["switch", "count", "number", "string", "id", "time", "duration", "choice", "list", "path", "cursor"], undefined>;
|
|
27
|
+
readonly meaning: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>;
|
|
28
|
+
readonly unit: v.OptionalSchema<v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, "must not be empty">]>, undefined>;
|
|
29
|
+
}, undefined>, undefined>;
|
|
30
|
+
}, undefined>;
|
|
31
|
+
export type Vocabulary = v.InferOutput<typeof vocabularySchema>;
|
|
32
|
+
export type VocabularyVerb = Vocabulary["verbs"][number];
|
|
33
|
+
export type VocabularyNoun = Vocabulary["nouns"][number];
|
|
34
|
+
export type VocabularyFlag = Vocabulary["flags"][number];
|
|
35
|
+
export type FlagType = (typeof FLAG_TYPES)[number];
|
|
36
|
+
/** One word, one meaning within its kind: a second entry for the same verb, noun, view, root or flag is refused. */
|
|
37
|
+
export declare const defineVocabulary: (input: unknown) => Vocabulary;
|
|
38
|
+
/** The words every CLI on cli-base is judged against. Seeded from STANDARD's command-name rules and the glossary. */
|
|
39
|
+
export declare const VOCABULARY: Vocabulary;
|
|
40
|
+
//# sourceMappingURL=vocabulary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vocabulary.d.ts","sourceRoot":"","sources":["../../src/standards/vocabulary.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAG5B,eAAO,MAAM,UAAU,YACrB,QAAQ,EACR,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,EACN,MAAM,EACN,QAAQ,CACA,CAAA;AAoBV,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;aAM3B,CAAA;AAEF,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAA;AAC/D,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AACxD,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AACxD,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAA;AACxD,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAElD,oHAAoH;AACpH,eAAO,MAAM,gBAAgB,UAAW,OAAO,KAAG,UAoB9C,CAAA;AA6KJ,qHAAqH;AACrH,eAAO,MAAM,UAAU,EAAE,UAavB,CAAA"}
|