@constructive-io/graphql-codegen 4.12.2 → 4.13.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.
Files changed (33) hide show
  1. package/core/codegen/cli/command-map-generator.d.ts +1 -0
  2. package/core/codegen/cli/command-map-generator.js +4 -0
  3. package/core/codegen/cli/config-command-generator.d.ts +11 -0
  4. package/core/codegen/cli/config-command-generator.js +458 -0
  5. package/core/codegen/cli/helpers-generator.d.ts +15 -0
  6. package/core/codegen/cli/helpers-generator.js +119 -0
  7. package/core/codegen/cli/index.d.ts +4 -0
  8. package/core/codegen/cli/index.js +21 -3
  9. package/core/codegen/orm/index.js +3 -2
  10. package/core/codegen/orm/input-types-generator.d.ts +3 -1
  11. package/core/codegen/orm/input-types-generator.js +14 -6
  12. package/core/codegen/orm/model-generator.d.ts +6 -2
  13. package/core/codegen/orm/model-generator.js +59 -37
  14. package/core/codegen/templates/query-builder.ts +2 -2
  15. package/core/codegen/templates/select-types.ts +2 -2
  16. package/esm/core/codegen/cli/command-map-generator.d.ts +1 -0
  17. package/esm/core/codegen/cli/command-map-generator.js +4 -0
  18. package/esm/core/codegen/cli/config-command-generator.d.ts +11 -0
  19. package/esm/core/codegen/cli/config-command-generator.js +422 -0
  20. package/esm/core/codegen/cli/helpers-generator.d.ts +15 -0
  21. package/esm/core/codegen/cli/helpers-generator.js +83 -0
  22. package/esm/core/codegen/cli/index.d.ts +4 -0
  23. package/esm/core/codegen/cli/index.js +18 -2
  24. package/esm/core/codegen/orm/index.js +3 -2
  25. package/esm/core/codegen/orm/input-types-generator.d.ts +3 -1
  26. package/esm/core/codegen/orm/input-types-generator.js +14 -6
  27. package/esm/core/codegen/orm/model-generator.d.ts +6 -2
  28. package/esm/core/codegen/orm/model-generator.js +59 -37
  29. package/esm/types/config.d.ts +9 -0
  30. package/esm/types/config.js +1 -0
  31. package/package.json +4 -4
  32. package/types/config.d.ts +9 -0
  33. package/types/config.js +1 -0
@@ -6,6 +6,7 @@ export interface MultiTargetCommandMapInput {
6
6
  builtinNames: {
7
7
  auth: string;
8
8
  context: string;
9
+ config: string;
9
10
  };
10
11
  targets: Array<{
11
12
  name: string;
@@ -223,6 +223,9 @@ function generateMultiTargetCommandMap(input) {
223
223
  const authImportName = `${builtinNames.auth}Cmd`;
224
224
  commandEntries.push({ kebab: builtinNames.auth, importName: authImportName });
225
225
  statements.push(createImportDeclaration(`./commands/${builtinNames.auth}`, authImportName));
226
+ const configImportName = `${builtinNames.config}Cmd`;
227
+ commandEntries.push({ kebab: builtinNames.config, importName: configImportName });
228
+ statements.push(createImportDeclaration(`./commands/${builtinNames.config}`, configImportName));
226
229
  for (const target of targets) {
227
230
  for (const table of target.tables) {
228
231
  const { singularName } = (0, utils_1.getTableNames)(table);
@@ -259,6 +262,7 @@ function generateMultiTargetCommandMap(input) {
259
262
  'Commands:',
260
263
  ` ${builtinNames.context.padEnd(20)} Manage API contexts`,
261
264
  ` ${builtinNames.auth.padEnd(20)} Manage authentication`,
265
+ ` ${builtinNames.config.padEnd(20)} Manage config key-value store`,
262
266
  ];
263
267
  for (const target of targets) {
264
268
  usageLines.push('');
@@ -0,0 +1,11 @@
1
+ import type { GeneratedFile } from './executor-generator';
2
+ /**
3
+ * Generate the config command file (get/set/list/delete for per-context vars).
4
+ *
5
+ * Usage:
6
+ * <tool> config get <key>
7
+ * <tool> config set <key> <value>
8
+ * <tool> config list
9
+ * <tool> config delete <key>
10
+ */
11
+ export declare function generateConfigCommand(toolName: string, commandName: string): GeneratedFile;
@@ -0,0 +1,458 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateConfigCommand = generateConfigCommand;
37
+ const t = __importStar(require("@babel/types"));
38
+ const babel_ast_1 = require("../babel-ast");
39
+ const utils_1 = require("../utils");
40
+ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
41
+ const specifiers = namedImports.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
42
+ const decl = t.importDeclaration(specifiers, t.stringLiteral(moduleSpecifier));
43
+ decl.importKind = typeOnly ? 'type' : 'value';
44
+ return decl;
45
+ }
46
+ function buildSwitchCase(testValue, handlerName, args) {
47
+ return t.switchCase(t.stringLiteral(testValue), [
48
+ t.returnStatement(t.callExpression(t.identifier(handlerName), args)),
49
+ ]);
50
+ }
51
+ function buildDefaultSwitchCase(usageVarName) {
52
+ return t.switchCase(null, [
53
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.identifier(usageVarName)])),
54
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
55
+ ]);
56
+ }
57
+ /**
58
+ * Generate the config command file (get/set/list/delete for per-context vars).
59
+ *
60
+ * Usage:
61
+ * <tool> config get <key>
62
+ * <tool> config set <key> <value>
63
+ * <tool> config list
64
+ * <tool> config delete <key>
65
+ */
66
+ function generateConfigCommand(toolName, commandName) {
67
+ const statements = [];
68
+ statements.push(createImportDeclaration('inquirerer', [
69
+ 'CLIOptions',
70
+ 'Inquirerer',
71
+ 'extractFirst',
72
+ ]));
73
+ statements.push(createImportDeclaration('../executor', ['getStore']));
74
+ const usageStr = `
75
+ ${toolName} ${commandName} <command>
76
+
77
+ Commands:
78
+ get <key> Get a config value
79
+ set <key> <value> Set a config value
80
+ list List all config values
81
+ delete <key> Delete a config value
82
+
83
+ --help, -h Show this help message
84
+ `;
85
+ statements.push(t.variableDeclaration('const', [
86
+ t.variableDeclarator(t.identifier('usage'), t.stringLiteral(usageStr)),
87
+ ]));
88
+ // Main export: default async (argv, prompter, _options) => { ... }
89
+ const argvParam = t.identifier('argv');
90
+ argvParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Partial'), t.tsTypeParameterInstantiation([
91
+ t.tsTypeReference(t.identifier('Record'), t.tsTypeParameterInstantiation([
92
+ t.tsStringKeyword(),
93
+ t.tsUnknownKeyword(),
94
+ ])),
95
+ ])));
96
+ const prompterParam = t.identifier('prompter');
97
+ prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
98
+ const optionsParam = t.identifier('_options');
99
+ optionsParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('CLIOptions')));
100
+ const mainBody = [
101
+ // Help check
102
+ t.ifStatement(t.logicalExpression('||', t.memberExpression(t.identifier('argv'), t.identifier('help')), t.memberExpression(t.identifier('argv'), t.identifier('h'))), t.blockStatement([
103
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.identifier('usage')])),
104
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(0)])),
105
+ ])),
106
+ // const store = getStore();
107
+ t.variableDeclaration('const', [
108
+ t.variableDeclarator(t.identifier('store'), t.callExpression(t.identifier('getStore'), [])),
109
+ ]),
110
+ // const { first: subcommand, newArgv } = extractFirst(argv);
111
+ t.variableDeclaration('const', [
112
+ t.variableDeclarator(t.objectPattern([
113
+ t.objectProperty(t.identifier('first'), t.identifier('subcommand')),
114
+ t.objectProperty(t.identifier('newArgv'), t.identifier('newArgv'), false, true),
115
+ ]), t.callExpression(t.identifier('extractFirst'), [
116
+ t.identifier('argv'),
117
+ ])),
118
+ ]),
119
+ // If no subcommand, prompt
120
+ t.ifStatement(t.unaryExpression('!', t.identifier('subcommand')), t.blockStatement([
121
+ t.variableDeclaration('const', [
122
+ t.variableDeclarator(t.identifier('answer'), t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('prompter'), t.identifier('prompt')), [
123
+ t.identifier('argv'),
124
+ t.arrayExpression([
125
+ t.objectExpression([
126
+ t.objectProperty(t.identifier('type'), t.stringLiteral('autocomplete')),
127
+ t.objectProperty(t.identifier('name'), t.stringLiteral('subcommand')),
128
+ t.objectProperty(t.identifier('message'), t.stringLiteral('What do you want to do?')),
129
+ t.objectProperty(t.identifier('options'), t.arrayExpression([
130
+ t.stringLiteral('get'),
131
+ t.stringLiteral('set'),
132
+ t.stringLiteral('list'),
133
+ t.stringLiteral('delete'),
134
+ ])),
135
+ ]),
136
+ ]),
137
+ ]))),
138
+ ]),
139
+ t.returnStatement(t.callExpression(t.identifier('handleSubcommand'), [
140
+ t.memberExpression(t.identifier('answer'), t.identifier('subcommand')),
141
+ t.identifier('newArgv'),
142
+ t.identifier('prompter'),
143
+ t.identifier('store'),
144
+ ])),
145
+ ])),
146
+ t.returnStatement(t.callExpression(t.identifier('handleSubcommand'), [
147
+ t.identifier('subcommand'),
148
+ t.identifier('newArgv'),
149
+ t.identifier('prompter'),
150
+ t.identifier('store'),
151
+ ])),
152
+ ];
153
+ const mainExport = t.exportDefaultDeclaration(t.arrowFunctionExpression([argvParam, prompterParam, optionsParam], t.blockStatement(mainBody), true));
154
+ statements.push(mainExport);
155
+ // handleSubcommand function
156
+ const subcmdParam = t.identifier('subcommand');
157
+ subcmdParam.typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword());
158
+ const argvParam2 = t.identifier('argv');
159
+ argvParam2.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Partial'), t.tsTypeParameterInstantiation([
160
+ t.tsTypeReference(t.identifier('Record'), t.tsTypeParameterInstantiation([
161
+ t.tsStringKeyword(),
162
+ t.tsUnknownKeyword(),
163
+ ])),
164
+ ])));
165
+ const prompterParam2 = t.identifier('prompter');
166
+ prompterParam2.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
167
+ const storeParam = t.identifier('store');
168
+ storeParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ReturnType'), t.tsTypeParameterInstantiation([
169
+ t.tsTypeQuery(t.identifier('getStore')),
170
+ ])));
171
+ const handleSubcommandFunc = t.functionDeclaration(t.identifier('handleSubcommand'), [subcmdParam, argvParam2, prompterParam2, storeParam], t.blockStatement([
172
+ t.switchStatement(t.identifier('subcommand'), [
173
+ buildSwitchCase('get', 'handleGet', [
174
+ t.identifier('argv'),
175
+ t.identifier('prompter'),
176
+ t.identifier('store'),
177
+ ]),
178
+ buildSwitchCase('set', 'handleSet', [
179
+ t.identifier('argv'),
180
+ t.identifier('prompter'),
181
+ t.identifier('store'),
182
+ ]),
183
+ buildSwitchCase('list', 'handleList', [t.identifier('store')]),
184
+ buildSwitchCase('delete', 'handleDelete', [
185
+ t.identifier('argv'),
186
+ t.identifier('prompter'),
187
+ t.identifier('store'),
188
+ ]),
189
+ buildDefaultSwitchCase('usage'),
190
+ ]),
191
+ ]), false, true);
192
+ statements.push(handleSubcommandFunc);
193
+ // handleGet
194
+ statements.push(buildGetHandler());
195
+ // handleSet
196
+ statements.push(buildSetHandler());
197
+ // handleList
198
+ statements.push(buildListHandler());
199
+ // handleDelete
200
+ statements.push(buildDeleteHandler());
201
+ const header = (0, utils_1.getGeneratedFileHeader)('Config key-value store commands');
202
+ const code = (0, babel_ast_1.generateCode)(statements);
203
+ return {
204
+ fileName: `commands/${commandName}.ts`,
205
+ content: header + '\n' + code,
206
+ };
207
+ }
208
+ function buildGetHandler() {
209
+ const argvParam = t.identifier('argv');
210
+ argvParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Partial'), t.tsTypeParameterInstantiation([
211
+ t.tsTypeReference(t.identifier('Record'), t.tsTypeParameterInstantiation([
212
+ t.tsStringKeyword(),
213
+ t.tsUnknownKeyword(),
214
+ ])),
215
+ ])));
216
+ const prompterParam = t.identifier('prompter');
217
+ prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
218
+ const storeParam = t.identifier('store');
219
+ storeParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ReturnType'), t.tsTypeParameterInstantiation([
220
+ t.tsTypeQuery(t.identifier('getStore')),
221
+ ])));
222
+ const body = [
223
+ // const { first: key } = extractFirst(argv);
224
+ t.variableDeclaration('const', [
225
+ t.variableDeclarator(t.objectPattern([
226
+ t.objectProperty(t.identifier('first'), t.identifier('key')),
227
+ ]), t.callExpression(t.identifier('extractFirst'), [
228
+ t.identifier('argv'),
229
+ ])),
230
+ ]),
231
+ // Prompt if no key
232
+ t.ifStatement(t.unaryExpression('!', t.identifier('key')), t.blockStatement([
233
+ t.variableDeclaration('const', [
234
+ t.variableDeclarator(t.identifier('answers'), t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('prompter'), t.identifier('prompt')), [
235
+ t.identifier('argv'),
236
+ t.arrayExpression([
237
+ t.objectExpression([
238
+ t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
239
+ t.objectProperty(t.identifier('name'), t.stringLiteral('key')),
240
+ t.objectProperty(t.identifier('message'), t.stringLiteral('Config key')),
241
+ t.objectProperty(t.identifier('required'), t.booleanLiteral(true)),
242
+ ]),
243
+ ]),
244
+ ]))),
245
+ ]),
246
+ t.variableDeclaration('const', [
247
+ t.variableDeclarator(t.identifier('value'), t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('getVar')), [t.memberExpression(t.identifier('answers'), t.identifier('key'))])),
248
+ ]),
249
+ t.ifStatement(t.binaryExpression('===', t.identifier('value'), t.identifier('undefined')), t.blockStatement([
250
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [
251
+ t.templateLiteral([
252
+ t.templateElement({ raw: 'Key "', cooked: 'Key "' }),
253
+ t.templateElement({ raw: '" not found.', cooked: '" not found.' }, true),
254
+ ], [t.memberExpression(t.identifier('answers'), t.identifier('key'))]),
255
+ ])),
256
+ ]), t.blockStatement([
257
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.identifier('value')])),
258
+ ])),
259
+ t.returnStatement(),
260
+ ])),
261
+ // const value = store.getVar(key);
262
+ t.variableDeclaration('const', [
263
+ t.variableDeclarator(t.identifier('value'), t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('getVar')), [t.identifier('key')])),
264
+ ]),
265
+ t.ifStatement(t.binaryExpression('===', t.identifier('value'), t.identifier('undefined')), t.blockStatement([
266
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [
267
+ t.templateLiteral([
268
+ t.templateElement({ raw: 'Key "', cooked: 'Key "' }),
269
+ t.templateElement({ raw: '" not found.', cooked: '" not found.' }, true),
270
+ ], [t.identifier('key')]),
271
+ ])),
272
+ ]), t.blockStatement([
273
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.identifier('value')])),
274
+ ])),
275
+ ];
276
+ return t.functionDeclaration(t.identifier('handleGet'), [argvParam, prompterParam, storeParam], t.blockStatement(body), false, true);
277
+ }
278
+ function buildSetHandler() {
279
+ const argvParam = t.identifier('argv');
280
+ argvParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Partial'), t.tsTypeParameterInstantiation([
281
+ t.tsTypeReference(t.identifier('Record'), t.tsTypeParameterInstantiation([
282
+ t.tsStringKeyword(),
283
+ t.tsUnknownKeyword(),
284
+ ])),
285
+ ])));
286
+ const prompterParam = t.identifier('prompter');
287
+ prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
288
+ const storeParam = t.identifier('store');
289
+ storeParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ReturnType'), t.tsTypeParameterInstantiation([
290
+ t.tsTypeQuery(t.identifier('getStore')),
291
+ ])));
292
+ const body = [
293
+ // const { first: key, newArgv: restArgv } = extractFirst(argv);
294
+ t.variableDeclaration('const', [
295
+ t.variableDeclarator(t.objectPattern([
296
+ t.objectProperty(t.identifier('first'), t.identifier('key')),
297
+ t.objectProperty(t.identifier('newArgv'), t.identifier('restArgv')),
298
+ ]), t.callExpression(t.identifier('extractFirst'), [
299
+ t.identifier('argv'),
300
+ ])),
301
+ ]),
302
+ // const { first: value } = extractFirst(restArgv);
303
+ t.variableDeclaration('const', [
304
+ t.variableDeclarator(t.objectPattern([
305
+ t.objectProperty(t.identifier('first'), t.identifier('value')),
306
+ ]), t.callExpression(t.identifier('extractFirst'), [
307
+ t.identifier('restArgv'),
308
+ ])),
309
+ ]),
310
+ // Prompt if missing key or value
311
+ t.ifStatement(t.logicalExpression('||', t.unaryExpression('!', t.identifier('key')), t.unaryExpression('!', t.identifier('value'))), t.blockStatement([
312
+ t.variableDeclaration('const', [
313
+ t.variableDeclarator(t.identifier('answers'), t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('prompter'), t.identifier('prompt')), [
314
+ t.objectExpression([
315
+ t.objectProperty(t.identifier('key'), t.identifier('key'), false, true),
316
+ t.objectProperty(t.identifier('value'), t.identifier('value'), false, true),
317
+ ]),
318
+ t.arrayExpression([
319
+ t.objectExpression([
320
+ t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
321
+ t.objectProperty(t.identifier('name'), t.stringLiteral('key')),
322
+ t.objectProperty(t.identifier('message'), t.stringLiteral('Config key')),
323
+ t.objectProperty(t.identifier('required'), t.booleanLiteral(true)),
324
+ ]),
325
+ t.objectExpression([
326
+ t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
327
+ t.objectProperty(t.identifier('name'), t.stringLiteral('value')),
328
+ t.objectProperty(t.identifier('message'), t.stringLiteral('Config value')),
329
+ t.objectProperty(t.identifier('required'), t.booleanLiteral(true)),
330
+ ]),
331
+ ]),
332
+ ]))),
333
+ ]),
334
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('setVar')), [
335
+ t.memberExpression(t.identifier('answers'), t.identifier('key')),
336
+ t.callExpression(t.memberExpression(t.identifier('String'), t.identifier('call')), [
337
+ t.identifier('undefined'),
338
+ t.memberExpression(t.identifier('answers'), t.identifier('value')),
339
+ ]),
340
+ ])),
341
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [
342
+ t.templateLiteral([
343
+ t.templateElement({ raw: 'Set ', cooked: 'Set ' }),
344
+ t.templateElement({ raw: ' = ', cooked: ' = ' }),
345
+ t.templateElement({ raw: '', cooked: '' }, true),
346
+ ], [
347
+ t.memberExpression(t.identifier('answers'), t.identifier('key')),
348
+ t.memberExpression(t.identifier('answers'), t.identifier('value')),
349
+ ]),
350
+ ])),
351
+ t.returnStatement(),
352
+ ])),
353
+ // store.setVar(key, String(value));
354
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('setVar')), [
355
+ t.identifier('key'),
356
+ t.callExpression(t.identifier('String'), [t.identifier('value')]),
357
+ ])),
358
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [
359
+ t.templateLiteral([
360
+ t.templateElement({ raw: 'Set ', cooked: 'Set ' }),
361
+ t.templateElement({ raw: ' = ', cooked: ' = ' }),
362
+ t.templateElement({ raw: '', cooked: '' }, true),
363
+ ], [t.identifier('key'), t.identifier('value')]),
364
+ ])),
365
+ ];
366
+ return t.functionDeclaration(t.identifier('handleSet'), [argvParam, prompterParam, storeParam], t.blockStatement(body), false, true);
367
+ }
368
+ function buildListHandler() {
369
+ const storeParam = t.identifier('store');
370
+ storeParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ReturnType'), t.tsTypeParameterInstantiation([
371
+ t.tsTypeQuery(t.identifier('getStore')),
372
+ ])));
373
+ const body = [
374
+ // const vars = store.listVars();
375
+ t.variableDeclaration('const', [
376
+ t.variableDeclarator(t.identifier('vars'), t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('listVars')), [])),
377
+ ]),
378
+ // const entries = Object.entries(vars);
379
+ t.variableDeclaration('const', [
380
+ t.variableDeclarator(t.identifier('entries'), t.callExpression(t.memberExpression(t.identifier('Object'), t.identifier('entries')), [t.identifier('vars')])),
381
+ ]),
382
+ t.ifStatement(t.binaryExpression('===', t.memberExpression(t.identifier('entries'), t.identifier('length')), t.numericLiteral(0)), t.blockStatement([
383
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.stringLiteral('No config values set.')])),
384
+ t.returnStatement(),
385
+ ])),
386
+ // for (const [key, value] of entries) { console.log(`${key} = ${value}`); }
387
+ t.forOfStatement(t.variableDeclaration('const', [
388
+ t.variableDeclarator(t.arrayPattern([t.identifier('key'), t.identifier('value')])),
389
+ ]), t.identifier('entries'), t.blockStatement([
390
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [
391
+ t.templateLiteral([
392
+ t.templateElement({ raw: '', cooked: '' }),
393
+ t.templateElement({ raw: ' = ', cooked: ' = ' }),
394
+ t.templateElement({ raw: '', cooked: '' }, true),
395
+ ], [t.identifier('key'), t.identifier('value')]),
396
+ ])),
397
+ ])),
398
+ ];
399
+ return t.functionDeclaration(t.identifier('handleList'), [storeParam], t.blockStatement(body));
400
+ }
401
+ function buildDeleteHandler() {
402
+ const argvParam = t.identifier('argv');
403
+ argvParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Partial'), t.tsTypeParameterInstantiation([
404
+ t.tsTypeReference(t.identifier('Record'), t.tsTypeParameterInstantiation([
405
+ t.tsStringKeyword(),
406
+ t.tsUnknownKeyword(),
407
+ ])),
408
+ ])));
409
+ const prompterParam = t.identifier('prompter');
410
+ prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
411
+ const storeParam = t.identifier('store');
412
+ storeParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ReturnType'), t.tsTypeParameterInstantiation([
413
+ t.tsTypeQuery(t.identifier('getStore')),
414
+ ])));
415
+ const body = [
416
+ // const { first: key } = extractFirst(argv);
417
+ t.variableDeclaration('const', [
418
+ t.variableDeclarator(t.objectPattern([
419
+ t.objectProperty(t.identifier('first'), t.identifier('key')),
420
+ ]), t.callExpression(t.identifier('extractFirst'), [
421
+ t.identifier('argv'),
422
+ ])),
423
+ ]),
424
+ // Prompt if no key
425
+ t.ifStatement(t.unaryExpression('!', t.identifier('key')), t.blockStatement([
426
+ t.variableDeclaration('const', [
427
+ t.variableDeclarator(t.identifier('answers'), t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('prompter'), t.identifier('prompt')), [
428
+ t.identifier('argv'),
429
+ t.arrayExpression([
430
+ t.objectExpression([
431
+ t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
432
+ t.objectProperty(t.identifier('name'), t.stringLiteral('key')),
433
+ t.objectProperty(t.identifier('message'), t.stringLiteral('Config key to delete')),
434
+ t.objectProperty(t.identifier('required'), t.booleanLiteral(true)),
435
+ ]),
436
+ ]),
437
+ ]))),
438
+ ]),
439
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('deleteVar')), [t.memberExpression(t.identifier('answers'), t.identifier('key'))])),
440
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [
441
+ t.templateLiteral([
442
+ t.templateElement({ raw: 'Deleted key: ', cooked: 'Deleted key: ' }),
443
+ t.templateElement({ raw: '', cooked: '' }, true),
444
+ ], [t.memberExpression(t.identifier('answers'), t.identifier('key'))]),
445
+ ])),
446
+ t.returnStatement(),
447
+ ])),
448
+ // store.deleteVar(key);
449
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('deleteVar')), [t.identifier('key')])),
450
+ t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [
451
+ t.templateLiteral([
452
+ t.templateElement({ raw: 'Deleted key: ', cooked: 'Deleted key: ' }),
453
+ t.templateElement({ raw: '', cooked: '' }, true),
454
+ ], [t.identifier('key')]),
455
+ ])),
456
+ ];
457
+ return t.functionDeclaration(t.identifier('handleDelete'), [argvParam, prompterParam, storeParam], t.blockStatement(body), false, true);
458
+ }
@@ -0,0 +1,15 @@
1
+ import type { GeneratedFile } from './executor-generator';
2
+ export interface HelpersGeneratorInput {
3
+ name: string;
4
+ ormImportPath: string;
5
+ }
6
+ /**
7
+ * Generate helpers.ts with typed per-target client factories.
8
+ *
9
+ * Each target gets a `createXxxClient(contextName?)` function that uses
10
+ * `store.getClientConfig(targetName, contextName)` under the hood with
11
+ * 3-tier resolution: appstash store -> env vars -> throw.
12
+ *
13
+ * Also re-exports the store for direct config/var access.
14
+ */
15
+ export declare function generateHelpersFile(toolName: string, targets: HelpersGeneratorInput[]): GeneratedFile;
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.generateHelpersFile = generateHelpersFile;
37
+ const t = __importStar(require("@babel/types"));
38
+ const babel_ast_1 = require("../babel-ast");
39
+ const utils_1 = require("../utils");
40
+ function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
41
+ const specifiers = namedImports.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
42
+ const decl = t.importDeclaration(specifiers, t.stringLiteral(moduleSpecifier));
43
+ decl.importKind = typeOnly ? 'type' : 'value';
44
+ return decl;
45
+ }
46
+ /**
47
+ * Generate helpers.ts with typed per-target client factories.
48
+ *
49
+ * Each target gets a `createXxxClient(contextName?)` function that uses
50
+ * `store.getClientConfig(targetName, contextName)` under the hood with
51
+ * 3-tier resolution: appstash store -> env vars -> throw.
52
+ *
53
+ * Also re-exports the store for direct config/var access.
54
+ */
55
+ function generateHelpersFile(toolName, targets) {
56
+ const statements = [];
57
+ // import { createConfigStore } from 'appstash';
58
+ statements.push(createImportDeclaration('appstash', ['createConfigStore']));
59
+ // import type { ClientConfig } from 'appstash';
60
+ statements.push(createImportDeclaration('appstash', ['ClientConfig'], true));
61
+ // Import createClient from each target's ORM
62
+ for (const target of targets) {
63
+ const aliasName = `create${target.name[0].toUpperCase()}${target.name.slice(1)}OrmClient`;
64
+ const specifier = t.importSpecifier(t.identifier(aliasName), t.identifier('createClient'));
65
+ statements.push(t.importDeclaration([specifier], t.stringLiteral(target.ormImportPath)));
66
+ }
67
+ // const store = createConfigStore('toolName');
68
+ statements.push(t.variableDeclaration('const', [
69
+ t.variableDeclarator(t.identifier('store'), t.callExpression(t.identifier('createConfigStore'), [
70
+ t.stringLiteral(toolName),
71
+ ])),
72
+ ]));
73
+ // export const getStore = () => store;
74
+ const getStoreExport = t.variableDeclaration('const', [
75
+ t.variableDeclarator(t.identifier('getStore'), t.arrowFunctionExpression([], t.identifier('store'))),
76
+ ]);
77
+ statements.push(t.exportNamedDeclaration(getStoreExport));
78
+ // export function getClientConfig(targetName: string, contextName?: string): ClientConfig
79
+ const targetNameParam = t.identifier('targetName');
80
+ targetNameParam.typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword());
81
+ const contextNameParam = t.identifier('contextName');
82
+ contextNameParam.optional = true;
83
+ contextNameParam.typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword());
84
+ const getClientConfigBody = t.blockStatement([
85
+ t.returnStatement(t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('getClientConfig')), [t.identifier('targetName'), t.identifier('contextName')])),
86
+ ]);
87
+ const getClientConfigFunc = t.functionDeclaration(t.identifier('getClientConfig'), [targetNameParam, contextNameParam], getClientConfigBody);
88
+ // Add return type annotation
89
+ const returnTypeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('ClientConfig')));
90
+ getClientConfigFunc.returnType = returnTypeAnnotation;
91
+ statements.push(t.exportNamedDeclaration(getClientConfigFunc));
92
+ // Generate typed factory for each target
93
+ for (const target of targets) {
94
+ const factoryName = `create${target.name[0].toUpperCase()}${target.name.slice(1)}Client`;
95
+ const ormAliasName = `create${target.name[0].toUpperCase()}${target.name.slice(1)}OrmClient`;
96
+ const ctxParam = t.identifier('contextName');
97
+ ctxParam.optional = true;
98
+ ctxParam.typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword());
99
+ const factoryBody = t.blockStatement([
100
+ t.variableDeclaration('const', [
101
+ t.variableDeclarator(t.identifier('config'), t.callExpression(t.memberExpression(t.identifier('store'), t.identifier('getClientConfig')), [t.stringLiteral(target.name), t.identifier('contextName')])),
102
+ ]),
103
+ t.returnStatement(t.callExpression(t.identifier(ormAliasName), [
104
+ t.objectExpression([
105
+ t.objectProperty(t.identifier('endpoint'), t.memberExpression(t.identifier('config'), t.identifier('endpoint'))),
106
+ t.objectProperty(t.identifier('headers'), t.memberExpression(t.identifier('config'), t.identifier('headers'))),
107
+ ]),
108
+ ])),
109
+ ]);
110
+ const factoryFunc = t.functionDeclaration(t.identifier(factoryName), [ctxParam], factoryBody);
111
+ statements.push(t.exportNamedDeclaration(factoryFunc));
112
+ }
113
+ const header = (0, utils_1.getGeneratedFileHeader)('SDK helpers — typed per-target client factories with 3-tier credential resolution');
114
+ const code = (0, babel_ast_1.generateCode)(statements);
115
+ return {
116
+ fileName: 'helpers.ts',
117
+ content: header + '\n' + code,
118
+ };
119
+ }
@@ -47,12 +47,16 @@ export interface GenerateMultiTargetCliOptions {
47
47
  export declare function resolveBuiltinNames(targetNames: string[], userOverrides?: BuiltinNames): {
48
48
  auth: string;
49
49
  context: string;
50
+ config: string;
50
51
  };
51
52
  export declare function generateMultiTargetCli(options: GenerateMultiTargetCliOptions): GenerateCliResult;
52
53
  export { generateExecutorFile, generateMultiTargetExecutorFile } from './executor-generator';
53
54
  export { generateTableCommand } from './table-command-generator';
54
55
  export { generateCustomCommand } from './custom-command-generator';
55
56
  export { generateCommandMap, generateMultiTargetCommandMap } from './command-map-generator';
57
+ export { generateConfigCommand } from './config-command-generator';
58
+ export { generateHelpersFile } from './helpers-generator';
59
+ export type { HelpersGeneratorInput } from './helpers-generator';
56
60
  export { generateContextCommand, generateAuthCommand, generateMultiTargetContextCommand, generateAuthCommandWithName, } from './infra-generator';
57
61
  export { generateReadme, generateAgentsDocs, getCliMcpTools, generateSkills, generateMultiTargetReadme, generateMultiTargetAgentsDocs, getMultiTargetCliMcpTools, generateMultiTargetSkills, } from './docs-generator';
58
62
  export type { MultiTargetDocsInput } from './docs-generator';