@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.
Files changed (142) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +707 -0
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +9 -0
  5. package/bin/run.cmd +3 -0
  6. package/bin/run.js +8 -0
  7. package/dist/api/get-environments.d.ts +10 -0
  8. package/dist/api/get-environments.js +11 -0
  9. package/dist/codegen/code-generators/base-generator.d.ts +11 -0
  10. package/dist/codegen/code-generators/base-generator.js +8 -0
  11. package/dist/codegen/code-generators/base-typescript-generator.d.ts +17 -0
  12. package/dist/codegen/code-generators/base-typescript-generator.js +35 -0
  13. package/dist/codegen/code-generators/node-typescript-generator.d.ts +8 -0
  14. package/dist/codegen/code-generators/node-typescript-generator.js +96 -0
  15. package/dist/codegen/code-generators/react-typescript-generator.d.ts +11 -0
  16. package/dist/codegen/code-generators/react-typescript-generator.js +116 -0
  17. package/dist/codegen/config-downloader.d.ts +7 -0
  18. package/dist/codegen/config-downloader.js +26 -0
  19. package/dist/codegen/json-schema-to-zod.d.ts +3 -0
  20. package/dist/codegen/json-schema-to-zod.js +170 -0
  21. package/dist/codegen/language-mappers/json-to-zod-mapper.d.ts +4 -0
  22. package/dist/codegen/language-mappers/json-to-zod-mapper.js +55 -0
  23. package/dist/codegen/language-mappers/zod-base-mapper.d.ts +35 -0
  24. package/dist/codegen/language-mappers/zod-base-mapper.js +111 -0
  25. package/dist/codegen/language-mappers/zod-to-string-mapper.d.ts +25 -0
  26. package/dist/codegen/language-mappers/zod-to-string-mapper.js +87 -0
  27. package/dist/codegen/language-mappers/zod-to-typescript-mapper.d.ts +35 -0
  28. package/dist/codegen/language-mappers/zod-to-typescript-mapper.js +133 -0
  29. package/dist/codegen/language-mappers/zod-to-typescript-return-value-mapper.d.ts +36 -0
  30. package/dist/codegen/language-mappers/zod-to-typescript-return-value-mapper.js +150 -0
  31. package/dist/codegen/mustache-extractor.d.ts +6 -0
  32. package/dist/codegen/mustache-extractor.js +83 -0
  33. package/dist/codegen/schema-evaluator.d.ts +37 -0
  34. package/dist/codegen/schema-evaluator.js +283 -0
  35. package/dist/codegen/schema-extractor.d.ts +24 -0
  36. package/dist/codegen/schema-extractor.js +265 -0
  37. package/dist/codegen/types.d.ts +44 -0
  38. package/dist/codegen/types.js +5 -0
  39. package/dist/codegen/zod-introspection.d.ts +85 -0
  40. package/dist/codegen/zod-introspection.js +205 -0
  41. package/dist/commands/create.d.ts +19 -0
  42. package/dist/commands/create.js +175 -0
  43. package/dist/commands/download.d.ts +13 -0
  44. package/dist/commands/download.js +63 -0
  45. package/dist/commands/generate-new-hex-key.d.ts +7 -0
  46. package/dist/commands/generate-new-hex-key.js +10 -0
  47. package/dist/commands/generate.d.ts +16 -0
  48. package/dist/commands/generate.js +220 -0
  49. package/dist/commands/get.d.ts +13 -0
  50. package/dist/commands/get.js +141 -0
  51. package/dist/commands/info.d.ts +21 -0
  52. package/dist/commands/info.js +464 -0
  53. package/dist/commands/interactive.d.ts +5 -0
  54. package/dist/commands/interactive.js +8 -0
  55. package/dist/commands/list.d.ts +13 -0
  56. package/dist/commands/list.js +61 -0
  57. package/dist/commands/login.d.ts +10 -0
  58. package/dist/commands/login.js +124 -0
  59. package/dist/commands/logout.d.ts +7 -0
  60. package/dist/commands/logout.js +12 -0
  61. package/dist/commands/mcp.d.ts +13 -0
  62. package/dist/commands/mcp.js +145 -0
  63. package/dist/commands/override.d.ts +17 -0
  64. package/dist/commands/override.js +170 -0
  65. package/dist/commands/profile.d.ts +7 -0
  66. package/dist/commands/profile.js +47 -0
  67. package/dist/commands/schema.d.ts +21 -0
  68. package/dist/commands/schema.js +168 -0
  69. package/dist/commands/serve.d.ts +13 -0
  70. package/dist/commands/serve.js +99 -0
  71. package/dist/commands/set-default.d.ts +20 -0
  72. package/dist/commands/set-default.js +273 -0
  73. package/dist/commands/verify.d.ts +12 -0
  74. package/dist/commands/verify.js +48 -0
  75. package/dist/commands/whoami.d.ts +7 -0
  76. package/dist/commands/whoami.js +52 -0
  77. package/dist/commands/workspace.d.ts +7 -0
  78. package/dist/commands/workspace.js +38 -0
  79. package/dist/constants.d.ts +2 -0
  80. package/dist/constants.js +2 -0
  81. package/dist/help.d.ts +4 -0
  82. package/dist/help.js +10 -0
  83. package/dist/index.d.ts +40 -0
  84. package/dist/index.js +112 -0
  85. package/dist/interactive-prompt.d.ts +2 -0
  86. package/dist/interactive-prompt.js +162 -0
  87. package/dist/quonfig.d.ts +15 -0
  88. package/dist/quonfig.js +75 -0
  89. package/dist/result.d.ts +35 -0
  90. package/dist/result.js +9 -0
  91. package/dist/services/mcp.d.ts +15 -0
  92. package/dist/services/mcp.js +59 -0
  93. package/dist/ui/get-confirmation.d.ts +10 -0
  94. package/dist/ui/get-confirmation.js +4 -0
  95. package/dist/ui/get-environment.d.ts +11 -0
  96. package/dist/ui/get-environment.js +42 -0
  97. package/dist/ui/get-key.d.ts +27 -0
  98. package/dist/ui/get-key.js +15 -0
  99. package/dist/ui/get-string.d.ts +5 -0
  100. package/dist/ui/get-string.js +8 -0
  101. package/dist/ui/get-value.d.ts +18 -0
  102. package/dist/ui/get-value.js +46 -0
  103. package/dist/util/autocomplete.d.ts +6 -0
  104. package/dist/util/autocomplete.js +25 -0
  105. package/dist/util/coerce.d.ts +7 -0
  106. package/dist/util/coerce.js +62 -0
  107. package/dist/util/color.d.ts +3 -0
  108. package/dist/util/color.js +4 -0
  109. package/dist/util/config-value-dto.d.ts +16 -0
  110. package/dist/util/config-value-dto.js +82 -0
  111. package/dist/util/context.d.ts +18 -0
  112. package/dist/util/context.js +10 -0
  113. package/dist/util/domain-urls.d.ts +3 -0
  114. package/dist/util/domain-urls.js +18 -0
  115. package/dist/util/encryption.d.ts +20 -0
  116. package/dist/util/encryption.js +153 -0
  117. package/dist/util/file-manager.d.ts +12 -0
  118. package/dist/util/file-manager.js +16 -0
  119. package/dist/util/get-client.d.ts +7 -0
  120. package/dist/util/get-client.js +127 -0
  121. package/dist/util/is-interactive.d.ts +5 -0
  122. package/dist/util/is-interactive.js +7 -0
  123. package/dist/util/json-maybe.d.ts +3 -0
  124. package/dist/util/json-maybe.js +14 -0
  125. package/dist/util/name-arg.d.ts +4 -0
  126. package/dist/util/name-arg.js +3 -0
  127. package/dist/util/oauth-client.d.ts +30 -0
  128. package/dist/util/oauth-client.js +99 -0
  129. package/dist/util/secret-flags.d.ts +13 -0
  130. package/dist/util/secret-flags.js +13 -0
  131. package/dist/util/token-storage.d.ts +25 -0
  132. package/dist/util/token-storage.js +90 -0
  133. package/dist/validations/value.d.ts +4 -0
  134. package/dist/validations/value.js +11 -0
  135. package/dist/verify/standalone.d.ts +14 -0
  136. package/dist/verify/standalone.js +133 -0
  137. package/dist/verify/validate.d.ts +43 -0
  138. package/dist/verify/validate.js +756 -0
  139. package/dist/version.d.ts +2 -0
  140. package/dist/version.js +2 -0
  141. package/oclif.manifest.json +1429 -0
  142. package/package.json +104 -0
package/bin/run.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
package/bin/run.js ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+
3
+ async function main() {
4
+ const {execute} = await import('@oclif/core')
5
+ await execute({dir: import.meta.url})
6
+ }
7
+
8
+ await main()
@@ -0,0 +1,10 @@
1
+ import type { APICommand } from '../index.js';
2
+ export interface Environment {
3
+ active?: boolean;
4
+ deletedAt?: number | null;
5
+ id: string;
6
+ name: string;
7
+ protected?: boolean;
8
+ type?: string;
9
+ }
10
+ export declare const getEnvironments: (command: APICommand) => Promise<Environment[]>;
@@ -0,0 +1,11 @@
1
+ export const getEnvironments = async (command) => {
2
+ const request = await command.apiClient.post('/api/v1/environments/list', { workspaceId: command.workspaceId });
3
+ if (!request.ok) {
4
+ const errorMsg = request.error?.error || `Failed to fetch environments: ${request.status}`;
5
+ return command.err(errorMsg, { serverError: request.error });
6
+ }
7
+ // oRPC returns the array directly (not wrapped in { environments: [] })
8
+ const environments = (Array.isArray(request.json) ? request.json : request.json.environments);
9
+ // Filter out deleted environments and sort by name
10
+ return environments.filter((env) => !env.deletedAt).sort((a, b) => a.name.localeCompare(b.name));
11
+ };
@@ -0,0 +1,11 @@
1
+ import { type ConfigFile } from '../types.js';
2
+ export interface BaseGeneratorArgs {
3
+ configFile: ConfigFile;
4
+ log: (category: string | unknown, message?: unknown) => void;
5
+ }
6
+ export declare abstract class BaseGenerator {
7
+ protected configFile: ConfigFile;
8
+ protected log: (category: string | unknown, message?: unknown) => void;
9
+ constructor({ configFile, log }: BaseGeneratorArgs);
10
+ abstract generate(): string;
11
+ }
@@ -0,0 +1,8 @@
1
+ export class BaseGenerator {
2
+ configFile;
3
+ log;
4
+ constructor({ configFile, log }) {
5
+ this.configFile = configFile;
6
+ this.log = log;
7
+ }
8
+ }
@@ -0,0 +1,17 @@
1
+ import { z } from 'zod';
2
+ import { BaseGenerator, BaseGeneratorArgs } from './base-generator.js';
3
+ export declare abstract class BaseTypescriptGenerator extends BaseGenerator {
4
+ protected MUSTACHE_IMPORT: string;
5
+ private schemaExtractor;
6
+ constructor({ configFile, log }: BaseGeneratorArgs);
7
+ protected configurations(): {
8
+ configType: "CONFIG" | "FEATURE_FLAG" | "SCHEMA";
9
+ hasFunction: boolean;
10
+ key: string;
11
+ schema: z.ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>;
12
+ sendToClientSdk: boolean;
13
+ }[];
14
+ protected durationTypeMap(): z.ZodTypeAny;
15
+ abstract declarationGenerate(): string;
16
+ abstract generate(): string;
17
+ }
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import { ZodToTypescriptMapper } from '../language-mappers/zod-to-typescript-mapper.js';
3
+ import { SchemaExtractor } from '../schema-extractor.js';
4
+ import { BaseGenerator } from './base-generator.js';
5
+ export class BaseTypescriptGenerator extends BaseGenerator {
6
+ MUSTACHE_IMPORT = "import Mustache from 'mustache'";
7
+ schemaExtractor;
8
+ constructor({ configFile, log }) {
9
+ super({ configFile, log });
10
+ this.schemaExtractor = new SchemaExtractor(log);
11
+ }
12
+ configurations() {
13
+ return this.configFile.configs
14
+ .filter((config) => config.configType === 'FEATURE_FLAG' || config.configType === 'CONFIG')
15
+ .filter((config) => config.rows.length > 0)
16
+ .sort((a, b) => a.key.localeCompare(b.key))
17
+ .map((config) => {
18
+ const schema = this.schemaExtractor.execute({
19
+ config,
20
+ configFile: this.configFile,
21
+ durationTypeMap: this.durationTypeMap,
22
+ });
23
+ return {
24
+ configType: config.configType,
25
+ hasFunction: schema && new ZodToTypescriptMapper().resolveType(schema).includes('=>'),
26
+ key: config.key,
27
+ schema,
28
+ sendToClientSdk: config.sendToClientSdk ?? false,
29
+ };
30
+ });
31
+ }
32
+ durationTypeMap() {
33
+ return z.number();
34
+ }
35
+ }
@@ -0,0 +1,8 @@
1
+ import { BaseTypescriptGenerator } from './base-typescript-generator.js';
2
+ export declare class NodeTypeScriptGenerator extends BaseTypescriptGenerator {
3
+ declarationGenerate(): string;
4
+ generate(): string;
5
+ private additionalDependencies;
6
+ private generateAccessorMethods;
7
+ private generateSchemaTypes;
8
+ }
@@ -0,0 +1,96 @@
1
+ import { stripIndent } from 'common-tags';
2
+ import camelCase from 'lodash.camelcase';
3
+ import { ZodToTypescriptMapper } from '../language-mappers/zod-to-typescript-mapper.js';
4
+ import { ZodToTypescriptReturnValueMapper } from '../language-mappers/zod-to-typescript-return-value-mapper.js';
5
+ import { BaseTypescriptGenerator } from './base-typescript-generator.js';
6
+ export class NodeTypeScriptGenerator extends BaseTypescriptGenerator {
7
+ declarationGenerate() {
8
+ return (stripIndent `
9
+ /* eslint-disable */
10
+ // AUTOGENERATED by quonfig-cli's 'gen' command
11
+ // prettier-ignore
12
+ import "@quonfig/node";
13
+
14
+ // prettier-ignore
15
+ declare module "@quonfig/node" {
16
+ export interface NodeServerConfigurationRaw {
17
+ ${this.generateSchemaTypes('raw').join('\n ') || '// No types generated'}
18
+ }
19
+
20
+ export interface NodeServerConfigurationAccessor {
21
+ ${this.generateSchemaTypes().join('\n ') || '// No types generated'}
22
+ }
23
+ }
24
+ ` + '\n' // For adding newline to avoid prettier issues
25
+ );
26
+ }
27
+ generate() {
28
+ return (stripIndent `
29
+ /* eslint-disable */
30
+ // AUTOGENERATED by quonfig-cli's 'gen' command
31
+ // prettier-ignore
32
+ import { Quonfig, Contexts, TypedNodeServerConfigurationRaw, TypedNodeServerConfigurationAccessor } from '@quonfig/node'
33
+ // prettier-ignore
34
+ ${this.additionalDependencies().join('\n// prettier-ignore\n') || '// No additional dependencies required'}
35
+
36
+ // prettier-ignore
37
+ type ContextObj = Record<string, Record<string, unknown>>
38
+
39
+ // prettier-ignore
40
+ export class QuonfigTypesafeNode {
41
+ constructor(public quonfig: Quonfig) { }
42
+
43
+ get<K extends keyof TypedNodeServerConfigurationRaw>(key: K, contexts?: Contexts | ContextObj): TypedNodeServerConfigurationRaw[K] {
44
+ return this.quonfig.get(key, contexts) as TypedNodeServerConfigurationRaw[K]
45
+ }
46
+
47
+ ${this.generateAccessorMethods().join('\n\n ') || '// No methods generated'}
48
+ }
49
+ ` + '\n' // For adding newline to avoid prettier issues
50
+ );
51
+ }
52
+ additionalDependencies() {
53
+ const dependencies = [];
54
+ const hasFunctions = this.configurations().some((c) => c.hasFunction);
55
+ if (hasFunctions) {
56
+ dependencies.push(this.MUSTACHE_IMPORT);
57
+ }
58
+ return dependencies;
59
+ }
60
+ generateAccessorMethods() {
61
+ const uniqueMethods = {};
62
+ const schemaTypes = this.configurations().map((config) => {
63
+ let methodName = camelCase(config.key);
64
+ // If the method name starts with a digit, prefix it with an underscore to ensure method name is valid
65
+ if (/^\d/.test(methodName)) {
66
+ methodName = `_${methodName}`;
67
+ }
68
+ if (uniqueMethods[methodName]) {
69
+ throw new Error(`Method '${methodName}' is already registered. Quonfig key ${config.key} conflicts with '${uniqueMethods[methodName]}'!`);
70
+ }
71
+ uniqueMethods[methodName] = config.key;
72
+ if (config.hasFunction) {
73
+ const returnValue = new ZodToTypescriptReturnValueMapper().resolveType(config.schema);
74
+ return stripIndent `
75
+ ${methodName}(contexts?: Contexts | ContextObj): TypedNodeServerConfigurationAccessor['${config.key}'] {
76
+ const raw = this.get('${config.key}', contexts)
77
+ return ${returnValue}
78
+ }
79
+ `;
80
+ }
81
+ return stripIndent `
82
+ ${methodName}(contexts?: Contexts | ContextObj): TypedNodeServerConfigurationAccessor['${config.key}'] {
83
+ return this.get('${config.key}', contexts)
84
+ }
85
+ `;
86
+ });
87
+ return schemaTypes;
88
+ }
89
+ generateSchemaTypes(target = 'accessor') {
90
+ const schemaTypes = this.configurations().flatMap((config) => {
91
+ const mapper = new ZodToTypescriptMapper({ fieldName: config.key, target });
92
+ return mapper.renderField(config.schema);
93
+ });
94
+ return schemaTypes;
95
+ }
96
+ }
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ import { BaseTypescriptGenerator } from './base-typescript-generator.js';
3
+ export declare class ReactTypeScriptGenerator extends BaseTypescriptGenerator {
4
+ declarationGenerate(): string;
5
+ protected durationTypeMap(): z.ZodTypeAny;
6
+ generate(): string;
7
+ private additionalDependencies;
8
+ private filteredConfigurations;
9
+ private generateAccessorMethods;
10
+ private generateSchemaTypes;
11
+ }
@@ -0,0 +1,116 @@
1
+ import { stripIndent } from 'common-tags';
2
+ import camelCase from 'lodash.camelcase';
3
+ import { z } from 'zod';
4
+ import { ZodToTypescriptMapper } from '../language-mappers/zod-to-typescript-mapper.js';
5
+ import { ZodToTypescriptReturnValueMapper } from '../language-mappers/zod-to-typescript-return-value-mapper.js';
6
+ import { BaseTypescriptGenerator } from './base-typescript-generator.js';
7
+ export class ReactTypeScriptGenerator extends BaseTypescriptGenerator {
8
+ declarationGenerate() {
9
+ return (stripIndent `
10
+ /* eslint-disable */
11
+ // AUTOGENERATED by quonfig-cli's 'gen' command
12
+ // prettier-ignore
13
+ import "@quonfig/javascript";
14
+ // prettier-ignore
15
+ import "@quonfig/react";
16
+
17
+ // prettier-ignore
18
+ declare module "@quonfig/javascript" {
19
+ export interface FrontEndConfigurationRaw {
20
+ ${this.generateSchemaTypes('raw').join('\n ') || '// No types generated'}
21
+ }
22
+
23
+ // Force TypedFrontEndConfigurationRaw to always use our merged interface
24
+ export type TypedFrontEndConfigurationRaw = FrontEndConfigurationRaw;
25
+ }
26
+
27
+ // prettier-ignore
28
+ declare module "@quonfig/react" {
29
+ export interface FrontEndConfigurationAccessor {
30
+ ${this.generateSchemaTypes().join('\n ') || '// No types generated'}
31
+ }
32
+
33
+ // Force TypedFrontEndConfigurationRaw to always use our merged interface
34
+ export type TypedFrontEndConfigurationAccessor = FrontEndConfigurationAccessor;
35
+ }
36
+ ` + '\n' // For adding newline to avoid prettier issues
37
+ );
38
+ }
39
+ durationTypeMap() {
40
+ return z.object({ ms: z.number(), seconds: z.number() });
41
+ }
42
+ generate() {
43
+ return (stripIndent `
44
+ /* eslint-disable */
45
+ // AUTOGENERATED by quonfig-cli's 'gen' command
46
+ // prettier-ignore
47
+ import { Quonfig, TypedFrontEndConfigurationRaw } from "@quonfig/javascript"
48
+ // prettier-ignore
49
+ import { createQuonfigHook, TypedFrontEndConfigurationAccessor } from "@quonfig/react"
50
+ // prettier-ignore
51
+ ${this.additionalDependencies().join('\n// prettier-ignore\n') || '// No additional dependencies required'}
52
+
53
+ // prettier-ignore
54
+ export class QuonfigTypesafeReact {
55
+ constructor(public quonfig: Quonfig) { }
56
+
57
+ get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {
58
+ return this.quonfig.get(key) as TypedFrontEndConfigurationRaw[K]
59
+ }
60
+
61
+ ${this.generateAccessorMethods().join('\n\n ') || '// No methods generated'}
62
+ }
63
+
64
+ // prettier-ignore
65
+ export const useQuonfig = createQuonfigHook(QuonfigTypesafeReact)
66
+ ` + '\n' // For adding newline to avoid prettier issues
67
+ );
68
+ }
69
+ additionalDependencies() {
70
+ const dependencies = [];
71
+ const hasFunctions = this.filteredConfigurations().some((c) => c.hasFunction);
72
+ if (hasFunctions) {
73
+ dependencies.push(this.MUSTACHE_IMPORT);
74
+ }
75
+ return dependencies;
76
+ }
77
+ filteredConfigurations() {
78
+ return this.configurations().filter((config) => config.configType === 'FEATURE_FLAG' || config.sendToClientSdk === true);
79
+ }
80
+ generateAccessorMethods() {
81
+ const uniqueMethods = {};
82
+ const schemaTypes = this.filteredConfigurations().map((config) => {
83
+ let methodName = camelCase(config.key);
84
+ // If the method name starts with a digit, prefix it with an underscore to ensure method name is valid
85
+ if (/^\d/.test(methodName)) {
86
+ methodName = `_${methodName}`;
87
+ }
88
+ if (uniqueMethods[methodName]) {
89
+ throw new Error(`Method '${methodName}' is already registered. Quonfig key ${config.key} conflicts with '${uniqueMethods[methodName]}'!`);
90
+ }
91
+ uniqueMethods[methodName] = config.key;
92
+ if (config.hasFunction) {
93
+ const returnValue = new ZodToTypescriptReturnValueMapper().resolveType(config.schema);
94
+ return stripIndent `
95
+ ${methodName}(): TypedFrontEndConfigurationAccessor['${config.key}'] {
96
+ const raw = this.get('${config.key}')
97
+ return ${returnValue}
98
+ }
99
+ `;
100
+ }
101
+ return stripIndent `
102
+ get ${methodName}(): TypedFrontEndConfigurationAccessor['${config.key}'] {
103
+ return this.get('${config.key}')
104
+ }
105
+ `;
106
+ });
107
+ return schemaTypes;
108
+ }
109
+ generateSchemaTypes(target = 'accessor') {
110
+ const schemaTypes = this.filteredConfigurations().map((config) => {
111
+ const mapper = new ZodToTypescriptMapper({ fieldName: config.key, target });
112
+ return mapper.renderField(config.schema);
113
+ });
114
+ return schemaTypes;
115
+ }
116
+ }
@@ -0,0 +1,7 @@
1
+ import type { ConfigFile } from './types.js';
2
+ import { APICommand } from '../index.js';
3
+ export declare class ConfigDownloader {
4
+ private command;
5
+ constructor(command: APICommand);
6
+ downloadConfig(): Promise<ConfigFile>;
7
+ }
@@ -0,0 +1,26 @@
1
+ export class ConfigDownloader {
2
+ command;
3
+ constructor(command) {
4
+ this.command = command;
5
+ }
6
+ async downloadConfig() {
7
+ try {
8
+ const response = (await this.command.apiClient.get('/all-config-types/v1/download-all-envs'));
9
+ if (!response.ok) {
10
+ throw new Error(`Failed to download config: ${response.status}`);
11
+ }
12
+ // Parse the response data - configs are nested in response.data.json
13
+ const configData = response.json;
14
+ // Print out each config key
15
+ this.command.verboseLog('\nFound configurations:', configData.configs?.length || 0);
16
+ if (!configData.configs) {
17
+ throw new Error('Invalid response format');
18
+ }
19
+ return configData;
20
+ }
21
+ catch (error) {
22
+ console.error('Error downloading config:', error);
23
+ throw error;
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,3 @@
1
+ import { z } from 'zod';
2
+ export declare function isLegacySchemaWrapper(schema: unknown): boolean;
3
+ export declare function jsonSchemaToZod(schema: unknown): z.ZodTypeAny;
@@ -0,0 +1,170 @@
1
+ import { z } from 'zod';
2
+ function isObject(value) {
3
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
4
+ }
5
+ function toMeta(schema) {
6
+ const meta = {};
7
+ if (typeof schema.title === 'string') {
8
+ meta.title = schema.title;
9
+ }
10
+ if (typeof schema.description === 'string') {
11
+ meta.description = schema.description;
12
+ }
13
+ return Object.keys(meta).length > 0 ? meta : undefined;
14
+ }
15
+ function applyMeta(schema, meta) {
16
+ return meta ? schema.meta(meta) : schema;
17
+ }
18
+ function literalFromEnum(values) {
19
+ if (values.length === 0) {
20
+ return z.never();
21
+ }
22
+ if (values.every((value) => typeof value === 'string')) {
23
+ return z.enum(values);
24
+ }
25
+ if (values.length === 1) {
26
+ return z.literal(values[0]);
27
+ }
28
+ const literals = values.map((value) => z.literal(value));
29
+ return z.union(literals);
30
+ }
31
+ function schemaFromTypeArray(schema, types) {
32
+ const nonNullTypes = types.filter((item) => item !== 'null');
33
+ const includesNull = nonNullTypes.length !== types.length;
34
+ if (nonNullTypes.length === 0 && includesNull) {
35
+ return z.null();
36
+ }
37
+ if (nonNullTypes.length === 1) {
38
+ const resolved = schemaToZod({ ...schema, type: nonNullTypes[0] });
39
+ return includesNull ? resolved.nullable() : resolved;
40
+ }
41
+ const resolved = z.union(nonNullTypes.map((type) => schemaToZod({ ...schema, type })));
42
+ return includesNull ? resolved.nullable() : resolved;
43
+ }
44
+ function schemaFromObject(schema) {
45
+ const properties = isObject(schema.properties) ? schema.properties : {};
46
+ const required = new Set(Array.isArray(schema.required) ? schema.required.filter((item) => typeof item === 'string') : []);
47
+ const shape = {};
48
+ for (const [key, value] of Object.entries(properties)) {
49
+ const propertySchema = schemaToZod(value);
50
+ shape[key] = required.has(key) ? propertySchema : propertySchema.optional();
51
+ }
52
+ const base = z.object(shape);
53
+ if (schema.additionalProperties === false) {
54
+ return base.strict();
55
+ }
56
+ if (isObject(schema.additionalProperties) && Object.keys(properties).length === 0) {
57
+ return z.record(z.string(), schemaToZod(schema.additionalProperties));
58
+ }
59
+ return base;
60
+ }
61
+ function schemaToZod(schema) {
62
+ if (!isObject(schema)) {
63
+ return z.any();
64
+ }
65
+ const meta = toMeta(schema);
66
+ let result;
67
+ if (Array.isArray(schema.enum)) {
68
+ result = literalFromEnum(schema.enum);
69
+ }
70
+ else if (schema.const !== undefined) {
71
+ result = z.literal(schema.const);
72
+ }
73
+ else if (Array.isArray(schema.type)) {
74
+ result = schemaFromTypeArray(schema, schema.type);
75
+ }
76
+ else {
77
+ switch (schema.type) {
78
+ case 'string': {
79
+ result = z.string();
80
+ break;
81
+ }
82
+ case 'number': {
83
+ result = z.number();
84
+ break;
85
+ }
86
+ case 'integer': {
87
+ result = z.number().int();
88
+ break;
89
+ }
90
+ case 'boolean': {
91
+ result = z.boolean();
92
+ break;
93
+ }
94
+ case 'null': {
95
+ result = z.null();
96
+ break;
97
+ }
98
+ case 'array': {
99
+ if (Array.isArray(schema.prefixItems)) {
100
+ const items = schema.prefixItems.map((item) => schemaToZod(item));
101
+ result = z.tuple(items);
102
+ }
103
+ else if (schema.items !== undefined) {
104
+ result = z.array(schemaToZod(schema.items));
105
+ }
106
+ else {
107
+ result = z.array(z.any());
108
+ }
109
+ break;
110
+ }
111
+ case 'object':
112
+ case undefined: {
113
+ if (schema.properties || schema.additionalProperties !== undefined || schema.required) {
114
+ result = schemaFromObject(schema);
115
+ }
116
+ else {
117
+ result = z.object({});
118
+ }
119
+ break;
120
+ }
121
+ default: {
122
+ if (Array.isArray(schema.oneOf)) {
123
+ const options = schema.oneOf.map((item) => schemaToZod(item));
124
+ result = options.length === 1 ? options[0] : z.union(options);
125
+ break;
126
+ }
127
+ if (Array.isArray(schema.anyOf)) {
128
+ const options = schema.anyOf.map((item) => schemaToZod(item));
129
+ result = options.length === 1 ? options[0] : z.union(options);
130
+ break;
131
+ }
132
+ if (Array.isArray(schema.allOf) && schema.allOf.length === 1) {
133
+ result = schemaToZod(schema.allOf[0]);
134
+ break;
135
+ }
136
+ if (schema.not === false) {
137
+ result = z.never();
138
+ break;
139
+ }
140
+ result = z.any();
141
+ }
142
+ }
143
+ }
144
+ if (schema.default !== undefined) {
145
+ result = result.default(schema.default);
146
+ }
147
+ result = applyMeta(result, meta);
148
+ return result;
149
+ }
150
+ export function isLegacySchemaWrapper(schema) {
151
+ if (!isObject(schema)) {
152
+ return false;
153
+ }
154
+ const defaultSection = schema.default;
155
+ if (!isObject(defaultSection) || !Array.isArray(defaultSection.rules)) {
156
+ return false;
157
+ }
158
+ const firstRule = defaultSection.rules[0];
159
+ if (!isObject(firstRule)) {
160
+ return false;
161
+ }
162
+ const value = firstRule.value;
163
+ if (!isObject(value) || !isObject(value.schema)) {
164
+ return false;
165
+ }
166
+ return typeof value.schema.schema === 'string';
167
+ }
168
+ export function jsonSchemaToZod(schema) {
169
+ return schemaToZod(schema);
170
+ }
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod';
2
+ export declare class JsonToZodMapper {
3
+ resolve(data: unknown): z.ZodTypeAny;
4
+ }
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ export class JsonToZodMapper {
3
+ resolve(data) {
4
+ if (Array.isArray(data)) {
5
+ if (data.length > 0) {
6
+ // Check if all elements in the array have the same type
7
+ const firstItem = data[0];
8
+ const isHomogeneous = data.every((item) => {
9
+ const itemsMatch = typeof item === typeof firstItem;
10
+ // Special handling for objects and arrays
11
+ if (typeof firstItem === 'object') {
12
+ if (Array.isArray(item)) {
13
+ return Array.isArray(firstItem);
14
+ }
15
+ return !Array.isArray(firstItem);
16
+ }
17
+ return itemsMatch;
18
+ });
19
+ // For homogeneous arrays, use the first element's type
20
+ if (isHomogeneous) {
21
+ return z.array(this.resolve(data[0]));
22
+ }
23
+ // Explicitly do not handle mixed-type arrays
24
+ // They could be tuples or heterogeneous arrays
25
+ // Instead, we return an array of unknowns
26
+ }
27
+ return z.array(z.unknown());
28
+ }
29
+ if (typeof data === 'object' && data !== null) {
30
+ const shape = {};
31
+ const dataRecord = data;
32
+ for (const key in dataRecord) {
33
+ if (Object.hasOwn(dataRecord, key)) {
34
+ shape[key] = this.resolve(dataRecord[key]);
35
+ }
36
+ }
37
+ return z.object(shape);
38
+ }
39
+ if (typeof data === 'string') {
40
+ return z.string();
41
+ }
42
+ if (typeof data === 'number') {
43
+ return z.number();
44
+ }
45
+ if (typeof data === 'boolean') {
46
+ return z.boolean();
47
+ }
48
+ if (data === null) {
49
+ return z.null();
50
+ }
51
+ console.warn(`Unknown json type:`, data);
52
+ // If the type is not recognized, default to 'any'
53
+ return z.any();
54
+ }
55
+ }
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ import { $ZodFunctionArgs, $ZodFunctionOut, $ZodType, util } from 'zod/v4/core';
3
+ export declare abstract class ZodBaseMapper {
4
+ resolveType(type: $ZodType): string;
5
+ /**
6
+ * Hook for handling meta descriptions on schemas.
7
+ * By default, this just returns the resolved type without any modification.
8
+ * Subclasses can override this to add comments or other metadata handling.
9
+ *
10
+ * @param description The description from .meta({ description: "..." })
11
+ * @param resolveType A function that resolves the inner type
12
+ * @returns The type string, potentially with description metadata
13
+ */
14
+ protected withMeta(description: string, resolveType: () => string): string;
15
+ private resolveTypeInternal;
16
+ protected abstract any(): string;
17
+ protected abstract array(wrappedType: string): string;
18
+ protected abstract boolean(): string;
19
+ protected abstract enum(values: util.EnumValue[]): string;
20
+ protected abstract function(args: string, returns: string): string;
21
+ protected abstract functionArguments(value?: $ZodFunctionArgs): string;
22
+ protected abstract functionReturns(value: $ZodFunctionOut): string;
23
+ protected abstract null(): string;
24
+ protected abstract literal(value: string | number | boolean | null): string;
25
+ protected abstract number(isInteger: boolean): string;
26
+ protected abstract object(properties: [string, z.ZodTypeAny][]): string;
27
+ protected abstract optional(wrappedType: string): string;
28
+ protected abstract never(): string;
29
+ protected abstract record(keyType: string, valueType: string): string;
30
+ protected abstract string(): string;
31
+ protected abstract tuple(wrappedTypes: string[]): string;
32
+ protected abstract undefined(): string;
33
+ protected abstract union(wrappedTypes: string[]): string;
34
+ protected abstract unknown(): string;
35
+ }