@quonfig/cli 0.0.1
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/LICENSE +21 -0
- package/README.md +707 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +9 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +8 -0
- package/dist/api/get-environments.d.ts +10 -0
- package/dist/api/get-environments.js +11 -0
- package/dist/codegen/code-generators/base-generator.d.ts +11 -0
- package/dist/codegen/code-generators/base-generator.js +8 -0
- package/dist/codegen/code-generators/base-typescript-generator.d.ts +17 -0
- package/dist/codegen/code-generators/base-typescript-generator.js +35 -0
- package/dist/codegen/code-generators/node-typescript-generator.d.ts +8 -0
- package/dist/codegen/code-generators/node-typescript-generator.js +96 -0
- package/dist/codegen/code-generators/react-typescript-generator.d.ts +11 -0
- package/dist/codegen/code-generators/react-typescript-generator.js +116 -0
- package/dist/codegen/config-downloader.d.ts +7 -0
- package/dist/codegen/config-downloader.js +26 -0
- package/dist/codegen/json-schema-to-zod.d.ts +3 -0
- package/dist/codegen/json-schema-to-zod.js +170 -0
- package/dist/codegen/language-mappers/json-to-zod-mapper.d.ts +4 -0
- package/dist/codegen/language-mappers/json-to-zod-mapper.js +55 -0
- package/dist/codegen/language-mappers/zod-base-mapper.d.ts +35 -0
- package/dist/codegen/language-mappers/zod-base-mapper.js +111 -0
- package/dist/codegen/language-mappers/zod-to-string-mapper.d.ts +25 -0
- package/dist/codegen/language-mappers/zod-to-string-mapper.js +87 -0
- package/dist/codegen/language-mappers/zod-to-typescript-mapper.d.ts +35 -0
- package/dist/codegen/language-mappers/zod-to-typescript-mapper.js +133 -0
- package/dist/codegen/language-mappers/zod-to-typescript-return-value-mapper.d.ts +36 -0
- package/dist/codegen/language-mappers/zod-to-typescript-return-value-mapper.js +150 -0
- package/dist/codegen/mustache-extractor.d.ts +6 -0
- package/dist/codegen/mustache-extractor.js +83 -0
- package/dist/codegen/schema-evaluator.d.ts +37 -0
- package/dist/codegen/schema-evaluator.js +283 -0
- package/dist/codegen/schema-extractor.d.ts +24 -0
- package/dist/codegen/schema-extractor.js +265 -0
- package/dist/codegen/types.d.ts +44 -0
- package/dist/codegen/types.js +5 -0
- package/dist/codegen/zod-introspection.d.ts +85 -0
- package/dist/codegen/zod-introspection.js +205 -0
- package/dist/commands/create.d.ts +19 -0
- package/dist/commands/create.js +175 -0
- package/dist/commands/download.d.ts +13 -0
- package/dist/commands/download.js +63 -0
- package/dist/commands/generate-new-hex-key.d.ts +7 -0
- package/dist/commands/generate-new-hex-key.js +10 -0
- package/dist/commands/generate.d.ts +16 -0
- package/dist/commands/generate.js +220 -0
- package/dist/commands/get.d.ts +13 -0
- package/dist/commands/get.js +141 -0
- package/dist/commands/info.d.ts +21 -0
- package/dist/commands/info.js +464 -0
- package/dist/commands/interactive.d.ts +5 -0
- package/dist/commands/interactive.js +8 -0
- package/dist/commands/list.d.ts +13 -0
- package/dist/commands/list.js +61 -0
- package/dist/commands/login.d.ts +10 -0
- package/dist/commands/login.js +124 -0
- package/dist/commands/logout.d.ts +7 -0
- package/dist/commands/logout.js +12 -0
- package/dist/commands/mcp.d.ts +13 -0
- package/dist/commands/mcp.js +145 -0
- package/dist/commands/override.d.ts +17 -0
- package/dist/commands/override.js +170 -0
- package/dist/commands/profile.d.ts +7 -0
- package/dist/commands/profile.js +47 -0
- package/dist/commands/schema.d.ts +21 -0
- package/dist/commands/schema.js +168 -0
- package/dist/commands/serve.d.ts +13 -0
- package/dist/commands/serve.js +99 -0
- package/dist/commands/set-default.d.ts +20 -0
- package/dist/commands/set-default.js +273 -0
- package/dist/commands/verify.d.ts +12 -0
- package/dist/commands/verify.js +48 -0
- package/dist/commands/whoami.d.ts +7 -0
- package/dist/commands/whoami.js +52 -0
- package/dist/commands/workspace.d.ts +7 -0
- package/dist/commands/workspace.js +38 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/help.d.ts +4 -0
- package/dist/help.js +10 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +112 -0
- package/dist/interactive-prompt.d.ts +2 -0
- package/dist/interactive-prompt.js +162 -0
- package/dist/quonfig.d.ts +15 -0
- package/dist/quonfig.js +75 -0
- package/dist/result.d.ts +35 -0
- package/dist/result.js +9 -0
- package/dist/services/mcp.d.ts +15 -0
- package/dist/services/mcp.js +59 -0
- package/dist/ui/get-confirmation.d.ts +10 -0
- package/dist/ui/get-confirmation.js +4 -0
- package/dist/ui/get-environment.d.ts +11 -0
- package/dist/ui/get-environment.js +42 -0
- package/dist/ui/get-key.d.ts +27 -0
- package/dist/ui/get-key.js +15 -0
- package/dist/ui/get-string.d.ts +5 -0
- package/dist/ui/get-string.js +8 -0
- package/dist/ui/get-value.d.ts +18 -0
- package/dist/ui/get-value.js +46 -0
- package/dist/util/autocomplete.d.ts +6 -0
- package/dist/util/autocomplete.js +25 -0
- package/dist/util/coerce.d.ts +7 -0
- package/dist/util/coerce.js +62 -0
- package/dist/util/color.d.ts +3 -0
- package/dist/util/color.js +4 -0
- package/dist/util/config-value-dto.d.ts +16 -0
- package/dist/util/config-value-dto.js +82 -0
- package/dist/util/context.d.ts +18 -0
- package/dist/util/context.js +10 -0
- package/dist/util/domain-urls.d.ts +3 -0
- package/dist/util/domain-urls.js +18 -0
- package/dist/util/encryption.d.ts +20 -0
- package/dist/util/encryption.js +153 -0
- package/dist/util/file-manager.d.ts +12 -0
- package/dist/util/file-manager.js +16 -0
- package/dist/util/get-client.d.ts +7 -0
- package/dist/util/get-client.js +127 -0
- package/dist/util/is-interactive.d.ts +5 -0
- package/dist/util/is-interactive.js +7 -0
- package/dist/util/json-maybe.d.ts +3 -0
- package/dist/util/json-maybe.js +14 -0
- package/dist/util/name-arg.d.ts +4 -0
- package/dist/util/name-arg.js +3 -0
- package/dist/util/oauth-client.d.ts +30 -0
- package/dist/util/oauth-client.js +99 -0
- package/dist/util/secret-flags.d.ts +13 -0
- package/dist/util/secret-flags.js +13 -0
- package/dist/util/token-storage.d.ts +25 -0
- package/dist/util/token-storage.js +90 -0
- package/dist/validations/value.d.ts +4 -0
- package/dist/validations/value.js +11 -0
- package/dist/verify/standalone.d.ts +14 -0
- package/dist/verify/standalone.js +133 -0
- package/dist/verify/validate.d.ts +43 -0
- package/dist/verify/validate.js +756 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.js +2 -0
- package/oclif.manifest.json +1429 -0
- package/package.json +104 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { $ZodFunctionArgs, $ZodFunctionOut, $ZodType, util, $ZodRecordKey } from 'zod/v4/core';
|
|
3
|
+
export declare function isString(schema: $ZodType): schema is z.ZodString;
|
|
4
|
+
export declare function isNumber(schema: $ZodType): schema is z.ZodNumber;
|
|
5
|
+
export declare function isBoolean(schema: $ZodType): schema is z.ZodBoolean;
|
|
6
|
+
export declare function isNull(schema: $ZodType): schema is z.ZodNull;
|
|
7
|
+
export declare function isLiteral(schema: $ZodType): schema is z.ZodLiteral<string | number | boolean | null>;
|
|
8
|
+
export declare function isUndefined(schema: $ZodType): schema is z.ZodUndefined;
|
|
9
|
+
export declare function isUnknown(schema: $ZodType): schema is z.ZodUnknown;
|
|
10
|
+
export declare function isNever(schema: $ZodType): schema is z.ZodNever;
|
|
11
|
+
export declare function isAny(schema: $ZodType): schema is z.ZodAny;
|
|
12
|
+
export declare function isArray(schema: $ZodType): schema is z.ZodArray<z.ZodTypeAny>;
|
|
13
|
+
export declare function isObject(schema: $ZodType): schema is z.ZodObject<z.ZodRawShape>;
|
|
14
|
+
export declare function isTuple(schema: $ZodType): schema is z.ZodTuple;
|
|
15
|
+
export declare function isRecord(schema: $ZodType): schema is z.ZodRecord;
|
|
16
|
+
export declare function isEnum(schema: $ZodType): schema is z.ZodEnum<util.EnumLike>;
|
|
17
|
+
export declare function isUnion(schema: $ZodType): schema is z.ZodUnion<[z.ZodTypeAny, ...z.ZodTypeAny[]]>;
|
|
18
|
+
export declare function isOptional(schema: $ZodType): schema is z.ZodOptional<z.ZodTypeAny>;
|
|
19
|
+
export declare function isNullable(schema: $ZodType): schema is z.ZodNullable<z.ZodTypeAny>;
|
|
20
|
+
export declare function isDefault(schema: $ZodType): schema is z.ZodDefault<z.ZodTypeAny>;
|
|
21
|
+
export declare function isFunction(schema: $ZodType): schema is z.ZodFunction<$ZodFunctionArgs, $ZodFunctionOut>;
|
|
22
|
+
/**
|
|
23
|
+
* Gets the element type from an array schema
|
|
24
|
+
*/
|
|
25
|
+
export declare function getArrayElement(schema: z.ZodArray<z.ZodTypeAny>): z.ZodTypeAny;
|
|
26
|
+
/**
|
|
27
|
+
* Gets the shape from an object schema
|
|
28
|
+
*/
|
|
29
|
+
export declare function getObjectShape(schema: z.ZodObject<z.ZodRawShape>): z.ZodRawShape;
|
|
30
|
+
/**
|
|
31
|
+
* Gets the items from a tuple schema
|
|
32
|
+
*/
|
|
33
|
+
export declare function getTupleItems(schema: z.ZodTuple): readonly $ZodType[];
|
|
34
|
+
/**
|
|
35
|
+
* Gets the key and value types from a record schema
|
|
36
|
+
*/
|
|
37
|
+
export declare function getRecordTypes(schema: z.ZodRecord): {
|
|
38
|
+
keyType: $ZodRecordKey;
|
|
39
|
+
valueType: $ZodType;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Gets the enum values from an enum schema
|
|
43
|
+
*/
|
|
44
|
+
export declare function getEnumValues(schema: z.ZodEnum<util.EnumLike>): util.EnumValue[];
|
|
45
|
+
export declare function getLiteralValue(schema: z.ZodLiteral<string | number | boolean | null>): string | number | boolean | null;
|
|
46
|
+
/**
|
|
47
|
+
* Gets the options from a union schema
|
|
48
|
+
*/
|
|
49
|
+
export declare function getUnionOptions(schema: z.ZodUnion<[z.ZodTypeAny, ...z.ZodTypeAny[]]>): z.ZodTypeAny[];
|
|
50
|
+
/**
|
|
51
|
+
* Unwraps an optional schema to get its inner type
|
|
52
|
+
*/
|
|
53
|
+
export declare function unwrapOptional(schema: z.ZodOptional<z.ZodTypeAny>): z.ZodTypeAny;
|
|
54
|
+
/**
|
|
55
|
+
* Unwraps a nullable schema to get its inner type
|
|
56
|
+
*/
|
|
57
|
+
export declare function unwrapNullable(schema: z.ZodNullable<z.ZodTypeAny>): z.ZodTypeAny;
|
|
58
|
+
/**
|
|
59
|
+
* Unwraps a default schema to get its inner type and default value
|
|
60
|
+
*/
|
|
61
|
+
export declare function unwrapDefault(schema: z.ZodDefault<z.ZodTypeAny>): {
|
|
62
|
+
defaultValue: unknown;
|
|
63
|
+
innerType: z.ZodTypeAny;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Gets function arguments and return type from a function schema
|
|
67
|
+
*/
|
|
68
|
+
export declare function getFunctionSignature(schema: z.ZodFunction<$ZodFunctionArgs, $ZodFunctionOut>): {
|
|
69
|
+
args: $ZodFunctionArgs;
|
|
70
|
+
returns: $ZodFunctionOut;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* Checks if a number schema has integer constraint
|
|
74
|
+
*/
|
|
75
|
+
export declare function isNumberInteger(schema: z.ZodNumber): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Gets metadata from a schema if it has been set with .meta()
|
|
78
|
+
*/
|
|
79
|
+
export declare function getMeta(schema: $ZodType): Record<string, unknown> | undefined;
|
|
80
|
+
/**
|
|
81
|
+
* Gets a comment string from metadata.
|
|
82
|
+
* If meta only contains a description key, returns the description string.
|
|
83
|
+
* Otherwise, returns a JSON representation of the entire meta object.
|
|
84
|
+
*/
|
|
85
|
+
export declare function getMetaDescription(schema: $ZodType): string | undefined;
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Type Guards
|
|
4
|
+
// ============================================================================
|
|
5
|
+
export function isString(schema) {
|
|
6
|
+
return schema instanceof z.ZodString;
|
|
7
|
+
}
|
|
8
|
+
export function isNumber(schema) {
|
|
9
|
+
return schema instanceof z.ZodNumber;
|
|
10
|
+
}
|
|
11
|
+
export function isBoolean(schema) {
|
|
12
|
+
return schema instanceof z.ZodBoolean;
|
|
13
|
+
}
|
|
14
|
+
export function isNull(schema) {
|
|
15
|
+
return schema instanceof z.ZodNull;
|
|
16
|
+
}
|
|
17
|
+
export function isLiteral(schema) {
|
|
18
|
+
return schema instanceof z.ZodLiteral;
|
|
19
|
+
}
|
|
20
|
+
export function isUndefined(schema) {
|
|
21
|
+
return schema instanceof z.ZodUndefined;
|
|
22
|
+
}
|
|
23
|
+
export function isUnknown(schema) {
|
|
24
|
+
return schema instanceof z.ZodUnknown;
|
|
25
|
+
}
|
|
26
|
+
export function isNever(schema) {
|
|
27
|
+
return schema instanceof z.ZodNever;
|
|
28
|
+
}
|
|
29
|
+
export function isAny(schema) {
|
|
30
|
+
return schema instanceof z.ZodAny;
|
|
31
|
+
}
|
|
32
|
+
export function isArray(schema) {
|
|
33
|
+
return schema instanceof z.ZodArray;
|
|
34
|
+
}
|
|
35
|
+
export function isObject(schema) {
|
|
36
|
+
return schema instanceof z.ZodObject;
|
|
37
|
+
}
|
|
38
|
+
export function isTuple(schema) {
|
|
39
|
+
return schema instanceof z.ZodTuple;
|
|
40
|
+
}
|
|
41
|
+
export function isRecord(schema) {
|
|
42
|
+
return schema instanceof z.ZodRecord;
|
|
43
|
+
}
|
|
44
|
+
export function isEnum(schema) {
|
|
45
|
+
return schema instanceof z.ZodEnum;
|
|
46
|
+
}
|
|
47
|
+
export function isUnion(schema) {
|
|
48
|
+
return schema instanceof z.ZodUnion;
|
|
49
|
+
}
|
|
50
|
+
export function isOptional(schema) {
|
|
51
|
+
return schema instanceof z.ZodOptional;
|
|
52
|
+
}
|
|
53
|
+
export function isNullable(schema) {
|
|
54
|
+
return schema instanceof z.ZodNullable;
|
|
55
|
+
}
|
|
56
|
+
export function isDefault(schema) {
|
|
57
|
+
return schema instanceof z.ZodDefault;
|
|
58
|
+
}
|
|
59
|
+
export function isFunction(schema) {
|
|
60
|
+
return schema instanceof z.ZodFunction;
|
|
61
|
+
}
|
|
62
|
+
function isCheckNumberFormat(checkDef) {
|
|
63
|
+
return checkDef?.check === 'number_format';
|
|
64
|
+
}
|
|
65
|
+
// ============================================================================
|
|
66
|
+
// Property Extractors
|
|
67
|
+
// ============================================================================
|
|
68
|
+
/**
|
|
69
|
+
* Gets the element type from an array schema
|
|
70
|
+
*/
|
|
71
|
+
export function getArrayElement(schema) {
|
|
72
|
+
return schema.def.element;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Gets the shape from an object schema
|
|
76
|
+
*/
|
|
77
|
+
export function getObjectShape(schema) {
|
|
78
|
+
return schema.def.shape;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Gets the items from a tuple schema
|
|
82
|
+
*/
|
|
83
|
+
export function getTupleItems(schema) {
|
|
84
|
+
return schema.def.items;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Gets the key and value types from a record schema
|
|
88
|
+
*/
|
|
89
|
+
export function getRecordTypes(schema) {
|
|
90
|
+
return {
|
|
91
|
+
keyType: schema.def.keyType,
|
|
92
|
+
valueType: schema.def.valueType,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Gets the enum values from an enum schema
|
|
97
|
+
*/
|
|
98
|
+
export function getEnumValues(schema) {
|
|
99
|
+
// In v4, enum entries is an object like { "a": "a", "b": "b", "c": "c" }
|
|
100
|
+
const entries = schema.def.entries;
|
|
101
|
+
if (entries && typeof entries === 'object') {
|
|
102
|
+
return Object.values(entries);
|
|
103
|
+
}
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
export function getLiteralValue(schema) {
|
|
107
|
+
return schema.def.values[0];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Gets the options from a union schema
|
|
111
|
+
*/
|
|
112
|
+
export function getUnionOptions(schema) {
|
|
113
|
+
return schema.def.options || [];
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Unwraps an optional schema to get its inner type
|
|
117
|
+
*/
|
|
118
|
+
export function unwrapOptional(schema) {
|
|
119
|
+
return schema.def.innerType;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Unwraps a nullable schema to get its inner type
|
|
123
|
+
*/
|
|
124
|
+
export function unwrapNullable(schema) {
|
|
125
|
+
return schema.def.innerType;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Unwraps a default schema to get its inner type and default value
|
|
129
|
+
*/
|
|
130
|
+
export function unwrapDefault(schema) {
|
|
131
|
+
return {
|
|
132
|
+
defaultValue: schema.def.defaultValue,
|
|
133
|
+
innerType: schema.def.innerType,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Gets function arguments and return type from a function schema
|
|
138
|
+
*/
|
|
139
|
+
export function getFunctionSignature(schema) {
|
|
140
|
+
// In v4, function uses input/output properties
|
|
141
|
+
return {
|
|
142
|
+
args: schema.def.input,
|
|
143
|
+
returns: schema.def.output,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Checks if a number schema has integer constraint
|
|
148
|
+
*/
|
|
149
|
+
export function isNumberInteger(schema) {
|
|
150
|
+
const checks = schema.def.checks || [];
|
|
151
|
+
// Look for number_format check with integer formats
|
|
152
|
+
return checks.some((check) => {
|
|
153
|
+
const checkDef = check._zod?.def;
|
|
154
|
+
if (isCheckNumberFormat(checkDef)) {
|
|
155
|
+
const format = checkDef.format;
|
|
156
|
+
return format === 'int32' || format === 'uint32' || format === 'safeint';
|
|
157
|
+
}
|
|
158
|
+
return false;
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Gets metadata from a schema if it has been set with .meta()
|
|
163
|
+
*/
|
|
164
|
+
export function getMeta(schema) {
|
|
165
|
+
if (!schema) {
|
|
166
|
+
return undefined;
|
|
167
|
+
}
|
|
168
|
+
// Call .meta() without arguments to retrieve metadata
|
|
169
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
170
|
+
if (typeof schema.meta === 'function') {
|
|
171
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
172
|
+
return schema.meta();
|
|
173
|
+
}
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Gets a comment string from metadata.
|
|
178
|
+
* If meta only contains a description key, returns the description string.
|
|
179
|
+
* Otherwise, returns a JSON representation of the entire meta object.
|
|
180
|
+
*/
|
|
181
|
+
export function getMetaDescription(schema) {
|
|
182
|
+
const meta = getMeta(schema);
|
|
183
|
+
if (!meta || Object.keys(meta).length === 0) {
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
// If meta only has a description key, return just the description
|
|
187
|
+
const keys = Object.keys(meta);
|
|
188
|
+
if (keys.length === 1 && keys[0] === 'description' && typeof meta.description === 'string') {
|
|
189
|
+
return meta.description;
|
|
190
|
+
}
|
|
191
|
+
if (typeof meta.description === 'string') {
|
|
192
|
+
return meta.description;
|
|
193
|
+
}
|
|
194
|
+
if (typeof meta.title === 'string') {
|
|
195
|
+
return meta.title;
|
|
196
|
+
}
|
|
197
|
+
// Otherwise, return JSON representation of the entire meta object
|
|
198
|
+
try {
|
|
199
|
+
return JSON.stringify(meta, null, 2);
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
// If JSON serialization fails, return undefined
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { APICommand } from '../index.js';
|
|
2
|
+
import { JsonObj } from '../result.js';
|
|
3
|
+
export default class Create extends APICommand {
|
|
4
|
+
static args: {
|
|
5
|
+
name: import("@oclif/core/lib/interfaces/parser.js").Arg<string, Record<string, unknown>>;
|
|
6
|
+
};
|
|
7
|
+
static description: string;
|
|
8
|
+
static examples: string[];
|
|
9
|
+
static flags: {
|
|
10
|
+
secret: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
11
|
+
'secret-key-name': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
12
|
+
confidential: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
|
|
13
|
+
'env-var': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
14
|
+
type: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
15
|
+
value: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
16
|
+
};
|
|
17
|
+
run(): Promise<JsonObj | void>;
|
|
18
|
+
private createBooleanFlag;
|
|
19
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { ProvidedSource } from '@quonfig/node';
|
|
3
|
+
import { APICommand } from '../index.js';
|
|
4
|
+
import getValue from '../ui/get-value.js';
|
|
5
|
+
import { TYPE_MAPPING, coerceBool, coerceIntoType } from '../util/coerce.js';
|
|
6
|
+
import { checkmark } from '../util/color.js';
|
|
7
|
+
import { mapConfigValueToDto, mapValueTypeToString } from '../util/config-value-dto.js';
|
|
8
|
+
import { makeConfidentialValue } from '../util/encryption.js';
|
|
9
|
+
import secretFlags, { parsedSecretFlags } from '../util/secret-flags.js';
|
|
10
|
+
export default class Create extends APICommand {
|
|
11
|
+
static args = {
|
|
12
|
+
name: Args.string({ description: 'name for your new item (e.g. my.new.flag)', required: true }),
|
|
13
|
+
};
|
|
14
|
+
static description = 'Create a new item in Quonfig';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> <%= command.id %> my.new.flag --type boolean-flag',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> my.new.flag --type boolean-flag --value=true',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> my.new.string --type string --value="hello world"',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> my.new.string --type string --value="hello world" --secret',
|
|
20
|
+
'<%= config.bin %> <%= command.id %> my.new.string --type string --env-var=MY_ENV_VAR_NAME',
|
|
21
|
+
'<%= config.bin %> <%= command.id %> my.new.string --type json --value="{\\"key\\": \\"value\\"}"',
|
|
22
|
+
];
|
|
23
|
+
static flags = {
|
|
24
|
+
confidential: Flags.boolean({ default: false, description: 'mark the value as confidential' }),
|
|
25
|
+
'env-var': Flags.string({ description: 'environment variable to get value from' }),
|
|
26
|
+
type: Flags.string({
|
|
27
|
+
options: ['boolean-flag', 'boolean', 'string', 'double', 'int', 'string-list', 'json'],
|
|
28
|
+
required: true,
|
|
29
|
+
}),
|
|
30
|
+
value: Flags.string({ description: 'default value for your new item', required: false }),
|
|
31
|
+
...secretFlags('encrypt the value of this item'),
|
|
32
|
+
};
|
|
33
|
+
async run() {
|
|
34
|
+
const { args, flags } = await this.parse(Create);
|
|
35
|
+
if (flags.type === 'boolean-flag') {
|
|
36
|
+
return this.createBooleanFlag(args, flags.value);
|
|
37
|
+
}
|
|
38
|
+
const key = args.name;
|
|
39
|
+
const secret = parsedSecretFlags(flags);
|
|
40
|
+
if (flags['env-var'] && flags.value) {
|
|
41
|
+
return this.err('cannot specify both --env-var and --value');
|
|
42
|
+
}
|
|
43
|
+
if (flags['env-var'] && secret.selected) {
|
|
44
|
+
return this.err('cannot specify both --env-var and --secret');
|
|
45
|
+
}
|
|
46
|
+
if (flags.confidential && secret.selected) {
|
|
47
|
+
console.warn("Note: --confidential is implied when using --secret, so you don't need to specify both.");
|
|
48
|
+
}
|
|
49
|
+
if (secret.selected && flags.type !== 'string') {
|
|
50
|
+
return this.err('--secret flag only works with string type');
|
|
51
|
+
}
|
|
52
|
+
let configValue = {};
|
|
53
|
+
let valueType = TYPE_MAPPING[flags.type];
|
|
54
|
+
if (flags['env-var']) {
|
|
55
|
+
configValue = {
|
|
56
|
+
provided: {
|
|
57
|
+
lookup: flags['env-var'],
|
|
58
|
+
source: ProvidedSource.EnvVar,
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const valueInput = await getValue({
|
|
64
|
+
desiredValue: flags.value,
|
|
65
|
+
flags,
|
|
66
|
+
message: 'Default value',
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
68
|
+
quonfig: undefined,
|
|
69
|
+
});
|
|
70
|
+
if (valueInput.ok) {
|
|
71
|
+
const rawValue = valueInput.value;
|
|
72
|
+
const parsedConfigValue = coerceIntoType(flags.type, rawValue);
|
|
73
|
+
if (!parsedConfigValue) {
|
|
74
|
+
return this.err(`Failed to coerce value into type: ${flags.type}`, { key, phase: 'coercion' });
|
|
75
|
+
}
|
|
76
|
+
configValue = parsedConfigValue[0];
|
|
77
|
+
valueType = parsedConfigValue[1];
|
|
78
|
+
if (secret.selected) {
|
|
79
|
+
const confidentialValueResult = await makeConfidentialValue(this, rawValue, secret, '');
|
|
80
|
+
if (!confidentialValueResult.ok) {
|
|
81
|
+
this.resultMessage(confidentialValueResult);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
configValue = confidentialValueResult.value;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (flags.confidential) {
|
|
92
|
+
configValue.confidential = true;
|
|
93
|
+
}
|
|
94
|
+
// Build oRPC input for configs/create
|
|
95
|
+
const createInput = {
|
|
96
|
+
workspaceId: this.workspaceId,
|
|
97
|
+
config: {
|
|
98
|
+
key: args.name,
|
|
99
|
+
valueType: mapValueTypeToString(valueType),
|
|
100
|
+
sendToClientSdk: false,
|
|
101
|
+
default: {
|
|
102
|
+
rules: [
|
|
103
|
+
{
|
|
104
|
+
criteria: [],
|
|
105
|
+
value: mapConfigValueToDto(configValue, valueType),
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
};
|
|
111
|
+
this.verboseLog('RPC configs/create', createInput);
|
|
112
|
+
const request = await this.apiClient.post('/api/v1/configs/create', createInput);
|
|
113
|
+
if (!request.ok) {
|
|
114
|
+
const errMsg = request.status === 409
|
|
115
|
+
? `Failed to create config: ${key} already exists`
|
|
116
|
+
: `Failed to create config: ${request.status} | ${JSON.stringify(request.error)}`;
|
|
117
|
+
return this.err(errMsg, { key, phase: 'creation', serverError: request.error });
|
|
118
|
+
}
|
|
119
|
+
const response = request.json;
|
|
120
|
+
const confidentialMaybe = flags.confidential ? '(confidential) ' : '';
|
|
121
|
+
return this.ok(`${checkmark} Created ${confidentialMaybe}config: ${key}`, { key, ...response });
|
|
122
|
+
}
|
|
123
|
+
async createBooleanFlag(args, rawDefault) {
|
|
124
|
+
const key = args.name;
|
|
125
|
+
const defaultValue = coerceBool(rawDefault ?? 'false');
|
|
126
|
+
// Build oRPC input for flags/create
|
|
127
|
+
const createInput = {
|
|
128
|
+
workspaceId: this.workspaceId,
|
|
129
|
+
flag: {
|
|
130
|
+
key,
|
|
131
|
+
valueType: 'bool',
|
|
132
|
+
sendToClientSdk: true,
|
|
133
|
+
variants: [
|
|
134
|
+
{
|
|
135
|
+
value: {
|
|
136
|
+
type: 'bool',
|
|
137
|
+
value: true,
|
|
138
|
+
},
|
|
139
|
+
name: 'True',
|
|
140
|
+
description: 'Enabled',
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
value: {
|
|
144
|
+
type: 'bool',
|
|
145
|
+
value: false,
|
|
146
|
+
},
|
|
147
|
+
name: 'False',
|
|
148
|
+
description: 'Disabled',
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
default: {
|
|
152
|
+
rules: [
|
|
153
|
+
{
|
|
154
|
+
criteria: [],
|
|
155
|
+
value: {
|
|
156
|
+
type: 'bool',
|
|
157
|
+
value: defaultValue,
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
};
|
|
164
|
+
this.verboseLog('RPC flags/create', createInput);
|
|
165
|
+
const request = await this.apiClient.post('/api/v1/flags/create', createInput);
|
|
166
|
+
if (!request.ok) {
|
|
167
|
+
const errMsg = request.status === 409
|
|
168
|
+
? `Failed to create boolean flag: ${key} already exists`
|
|
169
|
+
: `Failed to create boolean flag: ${request.status} | ${JSON.stringify(request.error)}`;
|
|
170
|
+
return this.err(errMsg, { key, phase: 'creation', serverError: request.error });
|
|
171
|
+
}
|
|
172
|
+
const response = request.json;
|
|
173
|
+
return this.ok(`${checkmark} Created boolean flag: ${key}`, { key, ...response });
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { JsonObj } from '../result.js';
|
|
2
|
+
import { APICommand } from '../index.js';
|
|
3
|
+
export default class Download extends APICommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
environment: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
'sdk-key': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
|
+
};
|
|
10
|
+
init(): Promise<void>;
|
|
11
|
+
run(): Promise<JsonObj | void>;
|
|
12
|
+
private writeFile;
|
|
13
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Flags } from '@oclif/core';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
import { APICommand } from '../index.js';
|
|
5
|
+
import { getProjectEnvFromSdkKey } from '@quonfig/node';
|
|
6
|
+
import getEnvironment from '../ui/get-environment.js';
|
|
7
|
+
import { checkmark } from '../util/color.js';
|
|
8
|
+
import getClient from '../util/get-client.js';
|
|
9
|
+
export default class Download extends APICommand {
|
|
10
|
+
static description = `Download a Datafile for a given environment
|
|
11
|
+
|
|
12
|
+
You can serve a datafile using the \`serve\` command.`;
|
|
13
|
+
static examples = [
|
|
14
|
+
'<%= config.bin %> <%= command.id %> --environment=test',
|
|
15
|
+
'<%= config.bin %> <%= command.id %> --environment=test --sdk-key=YOUR_SDK_KEY',
|
|
16
|
+
];
|
|
17
|
+
static flags = {
|
|
18
|
+
environment: Flags.string({ description: 'environment to download' }),
|
|
19
|
+
'sdk-key': Flags.string({
|
|
20
|
+
description: 'SDK key for authentication (uses legacy download endpoint)',
|
|
21
|
+
required: false,
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
async init() {
|
|
25
|
+
await super.init();
|
|
26
|
+
const { flags } = await this.parse(Download);
|
|
27
|
+
// If SDK key is provided, reinitialize the client with it
|
|
28
|
+
if (flags['sdk-key']) {
|
|
29
|
+
this.rawApiClient = await getClient(this, flags['sdk-key'], flags.profile);
|
|
30
|
+
this.currentEnvironment = getProjectEnvFromSdkKey(flags['sdk-key']);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
async run() {
|
|
34
|
+
const { flags } = await this.parse(Download);
|
|
35
|
+
const environment = await getEnvironment({
|
|
36
|
+
command: this,
|
|
37
|
+
flags,
|
|
38
|
+
message: 'Which environment would you like to download?',
|
|
39
|
+
providedEnvironment: flags.environment,
|
|
40
|
+
});
|
|
41
|
+
if (!environment) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.verboseLog({ environment, usingSdkKey: Boolean(flags['sdk-key']) });
|
|
45
|
+
// Use legacy endpoint if SDK key is provided, otherwise use new OAuth endpoint
|
|
46
|
+
const downloadUrl = flags['sdk-key']
|
|
47
|
+
? `/api/v2/configs/download?envId=${environment.id}`
|
|
48
|
+
: `/all-config-types/v1/download?envId=${environment.id}`;
|
|
49
|
+
const download = await this.apiClient.get(downloadUrl);
|
|
50
|
+
if (download.ok) {
|
|
51
|
+
return this.writeFile(download, environment);
|
|
52
|
+
}
|
|
53
|
+
this.verboseLog({ result: download });
|
|
54
|
+
return this.err(`Failed to download file. Status=${download.status}`, download.error);
|
|
55
|
+
}
|
|
56
|
+
writeFile(result, environment) {
|
|
57
|
+
const fileName = `quonfig.${environment.name}.${environment.id}.config.json`;
|
|
58
|
+
const filePath = path.join(process.cwd(), fileName);
|
|
59
|
+
fs.writeFileSync(filePath, JSON.stringify(result.json, null, 2));
|
|
60
|
+
this.log(`${checkmark} Successfully downloaded ${fileName}`);
|
|
61
|
+
return { filePath, succes: true };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { encryption } from '@quonfig/node';
|
|
2
|
+
import { BaseCommand } from '../index.js';
|
|
3
|
+
export default class GenerateNewHexKey extends BaseCommand {
|
|
4
|
+
static description = 'Generate a new hex key suitable for secrets';
|
|
5
|
+
static examples = ['<%= config.bin %> <%= command.id %>'];
|
|
6
|
+
async run() {
|
|
7
|
+
const key = encryption.generateNewHexKey();
|
|
8
|
+
return this.ok(key, { key });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { JsonObj } from '../result.js';
|
|
2
|
+
import { APICommand } from '../index.js';
|
|
3
|
+
export default class Generate extends APICommand {
|
|
4
|
+
static description: string;
|
|
5
|
+
static examples: string[];
|
|
6
|
+
static flags: {
|
|
7
|
+
'output-directory': import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
8
|
+
targets: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
|
|
9
|
+
};
|
|
10
|
+
static summary: string;
|
|
11
|
+
run(): Promise<JsonObj | void>;
|
|
12
|
+
private generateParsedConfig;
|
|
13
|
+
private readLocalConfig;
|
|
14
|
+
private resolveGenerator;
|
|
15
|
+
private resolveLanguage;
|
|
16
|
+
}
|