@constructive-io/graphql-codegen 4.0.1 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/handler.d.ts +13 -0
- package/cli/handler.js +74 -0
- package/cli/index.js +11 -60
- package/cli/shared.d.ts +1 -1
- package/cli/shared.js +2 -5
- package/core/codegen/barrel.d.ts +1 -0
- package/core/codegen/barrel.js +5 -2
- package/core/codegen/cli/arg-mapper.d.ts +4 -0
- package/core/codegen/cli/arg-mapper.js +117 -0
- package/core/codegen/cli/command-map-generator.d.ts +16 -0
- package/core/codegen/cli/command-map-generator.js +338 -0
- package/core/codegen/cli/custom-command-generator.d.ts +8 -0
- package/core/codegen/cli/custom-command-generator.js +155 -0
- package/core/codegen/cli/docs-generator.d.ts +26 -0
- package/core/codegen/cli/docs-generator.js +1399 -0
- package/core/codegen/cli/executor-generator.d.ts +11 -0
- package/core/codegen/cli/executor-generator.js +217 -0
- package/core/codegen/cli/index.d.ts +53 -0
- package/core/codegen/cli/index.js +153 -0
- package/core/codegen/cli/infra-generator.d.ts +9 -0
- package/core/codegen/cli/infra-generator.js +1195 -0
- package/core/codegen/cli/table-command-generator.d.ts +7 -0
- package/core/codegen/cli/table-command-generator.js +323 -0
- package/core/codegen/docs-utils.d.ts +30 -0
- package/core/codegen/docs-utils.js +122 -0
- package/core/codegen/hooks-docs-generator.d.ts +6 -0
- package/core/codegen/hooks-docs-generator.js +468 -0
- package/core/codegen/orm/docs-generator.d.ts +6 -0
- package/core/codegen/orm/docs-generator.js +416 -0
- package/core/codegen/target-docs-generator.d.ts +20 -0
- package/core/codegen/target-docs-generator.js +110 -0
- package/core/database/index.d.ts +0 -12
- package/core/database/index.js +2 -19
- package/core/generate.d.ts +34 -2
- package/core/generate.js +453 -12
- package/core/index.d.ts +0 -2
- package/core/index.js +0 -2
- package/core/introspect/source/database.js +2 -2
- package/core/introspect/source/pgpm-module.js +2 -2
- package/core/output/index.d.ts +1 -1
- package/core/output/index.js +1 -2
- package/core/output/writer.d.ts +0 -10
- package/core/output/writer.js +0 -31
- package/esm/cli/handler.d.ts +13 -0
- package/esm/cli/handler.js +71 -0
- package/esm/cli/index.js +11 -60
- package/esm/cli/shared.d.ts +1 -1
- package/esm/cli/shared.js +2 -5
- package/esm/core/codegen/barrel.d.ts +1 -0
- package/esm/core/codegen/barrel.js +5 -2
- package/esm/core/codegen/cli/arg-mapper.d.ts +4 -0
- package/esm/core/codegen/cli/arg-mapper.js +80 -0
- package/esm/core/codegen/cli/command-map-generator.d.ts +16 -0
- package/esm/core/codegen/cli/command-map-generator.js +301 -0
- package/esm/core/codegen/cli/custom-command-generator.d.ts +8 -0
- package/esm/core/codegen/cli/custom-command-generator.js +119 -0
- package/esm/core/codegen/cli/docs-generator.d.ts +26 -0
- package/esm/core/codegen/cli/docs-generator.js +1387 -0
- package/esm/core/codegen/cli/executor-generator.d.ts +11 -0
- package/esm/core/codegen/cli/executor-generator.js +180 -0
- package/esm/core/codegen/cli/index.d.ts +53 -0
- package/esm/core/codegen/cli/index.js +128 -0
- package/esm/core/codegen/cli/infra-generator.d.ts +9 -0
- package/esm/core/codegen/cli/infra-generator.js +1156 -0
- package/esm/core/codegen/cli/table-command-generator.d.ts +7 -0
- package/esm/core/codegen/cli/table-command-generator.js +287 -0
- package/esm/core/codegen/docs-utils.d.ts +30 -0
- package/esm/core/codegen/docs-utils.js +112 -0
- package/esm/core/codegen/hooks-docs-generator.d.ts +6 -0
- package/esm/core/codegen/hooks-docs-generator.js +462 -0
- package/esm/core/codegen/orm/docs-generator.d.ts +6 -0
- package/esm/core/codegen/orm/docs-generator.js +410 -0
- package/esm/core/codegen/target-docs-generator.d.ts +20 -0
- package/esm/core/codegen/target-docs-generator.js +105 -0
- package/esm/core/database/index.d.ts +0 -12
- package/esm/core/database/index.js +1 -17
- package/esm/core/generate.d.ts +34 -2
- package/esm/core/generate.js +417 -12
- package/esm/core/index.d.ts +0 -2
- package/esm/core/index.js +0 -2
- package/esm/core/introspect/source/database.js +2 -2
- package/esm/core/introspect/source/pgpm-module.js +2 -2
- package/esm/core/output/index.d.ts +1 -1
- package/esm/core/output/index.js +1 -1
- package/esm/core/output/writer.d.ts +0 -10
- package/esm/core/output/writer.js +0 -30
- package/esm/generators/index.d.ts +0 -3
- package/esm/generators/index.js +0 -3
- package/esm/index.d.ts +4 -3
- package/esm/index.js +4 -2
- package/esm/types/config.d.ts +78 -0
- package/generators/index.d.ts +0 -3
- package/generators/index.js +0 -3
- package/index.d.ts +4 -3
- package/index.js +7 -2
- package/package.json +8 -7
- package/types/config.d.ts +78 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CleanTable } from '../../../types/schema';
|
|
2
|
+
import type { GeneratedFile } from './executor-generator';
|
|
3
|
+
export interface TableCommandOptions {
|
|
4
|
+
targetName?: string;
|
|
5
|
+
executorImportPath?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function generateTableCommand(table: CleanTable, options?: TableCommandOptions): GeneratedFile;
|
|
@@ -0,0 +1,323 @@
|
|
|
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.generateTableCommand = generateTableCommand;
|
|
37
|
+
const t = __importStar(require("@babel/types"));
|
|
38
|
+
const komoji_1 = require("komoji");
|
|
39
|
+
const babel_ast_1 = require("../babel-ast");
|
|
40
|
+
const utils_1 = require("../utils");
|
|
41
|
+
function createImportDeclaration(moduleSpecifier, namedImports, typeOnly = false) {
|
|
42
|
+
const specifiers = namedImports.map((name) => t.importSpecifier(t.identifier(name), t.identifier(name)));
|
|
43
|
+
const decl = t.importDeclaration(specifiers, t.stringLiteral(moduleSpecifier));
|
|
44
|
+
decl.importKind = typeOnly ? 'type' : 'value';
|
|
45
|
+
return decl;
|
|
46
|
+
}
|
|
47
|
+
function buildSelectObject(table) {
|
|
48
|
+
const fields = (0, utils_1.getScalarFields)(table);
|
|
49
|
+
return t.objectExpression(fields.map((f) => t.objectProperty(t.identifier(f.name), t.booleanLiteral(true))));
|
|
50
|
+
}
|
|
51
|
+
function buildJsonLog(expr) {
|
|
52
|
+
return t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [
|
|
53
|
+
t.callExpression(t.memberExpression(t.identifier('JSON'), t.identifier('stringify')), [expr, t.nullLiteral(), t.numericLiteral(2)]),
|
|
54
|
+
]));
|
|
55
|
+
}
|
|
56
|
+
function buildOrmCall(singularName, methodName, args) {
|
|
57
|
+
return t.callExpression(t.memberExpression(t.callExpression(t.memberExpression(t.memberExpression(t.identifier('client'), t.identifier(singularName)), t.identifier(methodName)), [args]), t.identifier('execute')), []);
|
|
58
|
+
}
|
|
59
|
+
function buildErrorCatch(errorMessage) {
|
|
60
|
+
return t.catchClause(t.identifier('error'), t.blockStatement([
|
|
61
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [t.stringLiteral(errorMessage)])),
|
|
62
|
+
t.ifStatement(t.binaryExpression('instanceof', t.identifier('error'), t.identifier('Error')), t.blockStatement([
|
|
63
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('error')), [
|
|
64
|
+
t.memberExpression(t.identifier('error'), t.identifier('message')),
|
|
65
|
+
])),
|
|
66
|
+
])),
|
|
67
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
|
|
68
|
+
]));
|
|
69
|
+
}
|
|
70
|
+
function buildGetClientStatement(targetName) {
|
|
71
|
+
const args = targetName
|
|
72
|
+
? [t.stringLiteral(targetName)]
|
|
73
|
+
: [];
|
|
74
|
+
return t.variableDeclaration('const', [
|
|
75
|
+
t.variableDeclarator(t.identifier('client'), t.callExpression(t.identifier('getClient'), args)),
|
|
76
|
+
]);
|
|
77
|
+
}
|
|
78
|
+
function buildArgvType() {
|
|
79
|
+
return t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Partial'), t.tsTypeParameterInstantiation([
|
|
80
|
+
t.tsTypeReference(t.identifier('Record'), t.tsTypeParameterInstantiation([
|
|
81
|
+
t.tsStringKeyword(),
|
|
82
|
+
t.tsUnknownKeyword(),
|
|
83
|
+
])),
|
|
84
|
+
])));
|
|
85
|
+
}
|
|
86
|
+
function buildSubcommandSwitch(subcommands, handlerPrefix, usageVarName) {
|
|
87
|
+
const cases = subcommands.map((sub) => t.switchCase(t.stringLiteral(sub), [
|
|
88
|
+
t.returnStatement(t.callExpression(t.identifier(`${handlerPrefix}${(0, utils_1.ucFirst)(sub)}`), [
|
|
89
|
+
t.identifier('argv'),
|
|
90
|
+
t.identifier('prompter'),
|
|
91
|
+
])),
|
|
92
|
+
]));
|
|
93
|
+
cases.push(t.switchCase(null, [
|
|
94
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.identifier(usageVarName)])),
|
|
95
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(1)])),
|
|
96
|
+
]));
|
|
97
|
+
return t.switchStatement(t.identifier('subcommand'), cases);
|
|
98
|
+
}
|
|
99
|
+
function buildListHandler(table, targetName) {
|
|
100
|
+
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
101
|
+
const selectObj = buildSelectObject(table);
|
|
102
|
+
const tryBody = [
|
|
103
|
+
buildGetClientStatement(targetName),
|
|
104
|
+
t.variableDeclaration('const', [
|
|
105
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCall(singularName, 'findMany', t.objectExpression([
|
|
106
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
107
|
+
])))),
|
|
108
|
+
]),
|
|
109
|
+
buildJsonLog(t.identifier('result')),
|
|
110
|
+
];
|
|
111
|
+
const argvParam = t.identifier('_argv');
|
|
112
|
+
argvParam.typeAnnotation = buildArgvType();
|
|
113
|
+
const prompterParam = t.identifier('_prompter');
|
|
114
|
+
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
115
|
+
return t.functionDeclaration(t.identifier('handleList'), [argvParam, prompterParam], t.blockStatement([
|
|
116
|
+
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch('Failed to list records.')),
|
|
117
|
+
]), false, true);
|
|
118
|
+
}
|
|
119
|
+
function buildGetHandler(table, targetName) {
|
|
120
|
+
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
121
|
+
const pkFields = (0, utils_1.getPrimaryKeyInfo)(table);
|
|
122
|
+
const pk = pkFields[0];
|
|
123
|
+
const selectObj = buildSelectObject(table);
|
|
124
|
+
const promptQuestion = t.objectExpression([
|
|
125
|
+
t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
|
|
126
|
+
t.objectProperty(t.identifier('name'), t.stringLiteral(pk.name)),
|
|
127
|
+
t.objectProperty(t.identifier('message'), t.stringLiteral(pk.name)),
|
|
128
|
+
t.objectProperty(t.identifier('required'), t.booleanLiteral(true)),
|
|
129
|
+
]);
|
|
130
|
+
const ormArgs = t.objectExpression([
|
|
131
|
+
t.objectProperty(t.identifier(pk.name), t.memberExpression(t.identifier('answers'), t.identifier(pk.name))),
|
|
132
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
133
|
+
]);
|
|
134
|
+
const tryBody = [
|
|
135
|
+
t.variableDeclaration('const', [
|
|
136
|
+
t.variableDeclarator(t.identifier('answers'), t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('prompter'), t.identifier('prompt')), [t.identifier('argv'), t.arrayExpression([promptQuestion])]))),
|
|
137
|
+
]),
|
|
138
|
+
buildGetClientStatement(targetName),
|
|
139
|
+
t.variableDeclaration('const', [
|
|
140
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCall(singularName, 'findOne', ormArgs))),
|
|
141
|
+
]),
|
|
142
|
+
buildJsonLog(t.identifier('result')),
|
|
143
|
+
];
|
|
144
|
+
const argvParam = t.identifier('argv');
|
|
145
|
+
argvParam.typeAnnotation = buildArgvType();
|
|
146
|
+
const prompterParam = t.identifier('prompter');
|
|
147
|
+
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
148
|
+
return t.functionDeclaration(t.identifier('handleGet'), [argvParam, prompterParam], t.blockStatement([
|
|
149
|
+
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch('Record not found.')),
|
|
150
|
+
]), false, true);
|
|
151
|
+
}
|
|
152
|
+
function buildMutationHandler(table, operation, targetName) {
|
|
153
|
+
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
154
|
+
const pkFields = (0, utils_1.getPrimaryKeyInfo)(table);
|
|
155
|
+
const pk = pkFields[0];
|
|
156
|
+
const editableFields = (0, utils_1.getScalarFields)(table).filter((f) => f.name !== pk.name &&
|
|
157
|
+
f.name !== 'nodeId' &&
|
|
158
|
+
f.name !== 'createdAt' &&
|
|
159
|
+
f.name !== 'updatedAt');
|
|
160
|
+
const questions = [];
|
|
161
|
+
if (operation === 'update' || operation === 'delete') {
|
|
162
|
+
questions.push(t.objectExpression([
|
|
163
|
+
t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
|
|
164
|
+
t.objectProperty(t.identifier('name'), t.stringLiteral(pk.name)),
|
|
165
|
+
t.objectProperty(t.identifier('message'), t.stringLiteral(pk.name)),
|
|
166
|
+
t.objectProperty(t.identifier('required'), t.booleanLiteral(true)),
|
|
167
|
+
]));
|
|
168
|
+
}
|
|
169
|
+
if (operation !== 'delete') {
|
|
170
|
+
for (const field of editableFields) {
|
|
171
|
+
questions.push(t.objectExpression([
|
|
172
|
+
t.objectProperty(t.identifier('type'), t.stringLiteral('text')),
|
|
173
|
+
t.objectProperty(t.identifier('name'), t.stringLiteral(field.name)),
|
|
174
|
+
t.objectProperty(t.identifier('message'), t.stringLiteral(field.name)),
|
|
175
|
+
t.objectProperty(t.identifier('required'), t.booleanLiteral(operation === 'create')),
|
|
176
|
+
]));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const selectObj = operation === 'delete'
|
|
180
|
+
? t.objectExpression([
|
|
181
|
+
t.objectProperty(t.identifier(pk.name), t.booleanLiteral(true)),
|
|
182
|
+
])
|
|
183
|
+
: buildSelectObject(table);
|
|
184
|
+
let ormArgs;
|
|
185
|
+
if (operation === 'create') {
|
|
186
|
+
const dataProps = editableFields.map((f) => t.objectProperty(t.identifier(f.name), t.memberExpression(t.identifier('answers'), t.identifier(f.name)), false, true));
|
|
187
|
+
ormArgs = t.objectExpression([
|
|
188
|
+
t.objectProperty(t.identifier('data'), t.objectExpression(dataProps)),
|
|
189
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
190
|
+
]);
|
|
191
|
+
}
|
|
192
|
+
else if (operation === 'update') {
|
|
193
|
+
const dataProps = editableFields.map((f) => t.objectProperty(t.identifier(f.name), t.memberExpression(t.identifier('answers'), t.identifier(f.name)), false, true));
|
|
194
|
+
ormArgs = t.objectExpression([
|
|
195
|
+
t.objectProperty(t.identifier(pk.name), t.memberExpression(t.identifier('answers'), t.identifier(pk.name))),
|
|
196
|
+
t.objectProperty(t.identifier('data'), t.objectExpression(dataProps)),
|
|
197
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
198
|
+
]);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
ormArgs = t.objectExpression([
|
|
202
|
+
t.objectProperty(t.identifier(pk.name), t.memberExpression(t.identifier('answers'), t.identifier(pk.name))),
|
|
203
|
+
t.objectProperty(t.identifier('select'), selectObj),
|
|
204
|
+
]);
|
|
205
|
+
}
|
|
206
|
+
const tryBody = [
|
|
207
|
+
t.variableDeclaration('const', [
|
|
208
|
+
t.variableDeclarator(t.identifier('answers'), t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('prompter'), t.identifier('prompt')), [t.identifier('argv'), t.arrayExpression(questions)]))),
|
|
209
|
+
]),
|
|
210
|
+
buildGetClientStatement(targetName),
|
|
211
|
+
t.variableDeclaration('const', [
|
|
212
|
+
t.variableDeclarator(t.identifier('result'), t.awaitExpression(buildOrmCall(singularName, operation, ormArgs))),
|
|
213
|
+
]),
|
|
214
|
+
buildJsonLog(t.identifier('result')),
|
|
215
|
+
];
|
|
216
|
+
const argvParam = t.identifier('argv');
|
|
217
|
+
argvParam.typeAnnotation = buildArgvType();
|
|
218
|
+
const prompterParam = t.identifier('prompter');
|
|
219
|
+
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
220
|
+
const handlerName = `handle${(0, utils_1.ucFirst)(operation)}`;
|
|
221
|
+
return t.functionDeclaration(t.identifier(handlerName), [argvParam, prompterParam], t.blockStatement([
|
|
222
|
+
t.tryStatement(t.blockStatement(tryBody), buildErrorCatch(`Failed to ${operation} record.`)),
|
|
223
|
+
]), false, true);
|
|
224
|
+
}
|
|
225
|
+
function generateTableCommand(table, options) {
|
|
226
|
+
const { singularName } = (0, utils_1.getTableNames)(table);
|
|
227
|
+
const commandName = (0, komoji_1.toKebabCase)(singularName);
|
|
228
|
+
const statements = [];
|
|
229
|
+
const executorPath = options?.executorImportPath ?? '../executor';
|
|
230
|
+
statements.push(createImportDeclaration('inquirerer', [
|
|
231
|
+
'CLIOptions',
|
|
232
|
+
'Inquirerer',
|
|
233
|
+
'extractFirst',
|
|
234
|
+
]));
|
|
235
|
+
statements.push(createImportDeclaration(executorPath, ['getClient']));
|
|
236
|
+
const subcommands = ['list', 'get', 'create', 'update', 'delete'];
|
|
237
|
+
const usageLines = [
|
|
238
|
+
'',
|
|
239
|
+
`${commandName} <command>`,
|
|
240
|
+
'',
|
|
241
|
+
'Commands:',
|
|
242
|
+
` list List all ${singularName} records`,
|
|
243
|
+
` get Get a ${singularName} by ID`,
|
|
244
|
+
` create Create a new ${singularName}`,
|
|
245
|
+
` update Update an existing ${singularName}`,
|
|
246
|
+
` delete Delete a ${singularName}`,
|
|
247
|
+
'',
|
|
248
|
+
' --help, -h Show this help message',
|
|
249
|
+
'',
|
|
250
|
+
];
|
|
251
|
+
statements.push(t.variableDeclaration('const', [
|
|
252
|
+
t.variableDeclarator(t.identifier('usage'), t.stringLiteral(usageLines.join('\n'))),
|
|
253
|
+
]));
|
|
254
|
+
const argvParam = t.identifier('argv');
|
|
255
|
+
argvParam.typeAnnotation = buildArgvType();
|
|
256
|
+
const prompterParam = t.identifier('prompter');
|
|
257
|
+
prompterParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
258
|
+
const optionsParam = t.identifier('_options');
|
|
259
|
+
optionsParam.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('CLIOptions')));
|
|
260
|
+
const mainBody = [
|
|
261
|
+
t.ifStatement(t.logicalExpression('||', t.memberExpression(t.identifier('argv'), t.identifier('help')), t.memberExpression(t.identifier('argv'), t.identifier('h'))), t.blockStatement([
|
|
262
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('console'), t.identifier('log')), [t.identifier('usage')])),
|
|
263
|
+
t.expressionStatement(t.callExpression(t.memberExpression(t.identifier('process'), t.identifier('exit')), [t.numericLiteral(0)])),
|
|
264
|
+
])),
|
|
265
|
+
t.variableDeclaration('const', [
|
|
266
|
+
t.variableDeclarator(t.objectPattern([
|
|
267
|
+
t.objectProperty(t.identifier('first'), t.identifier('subcommand')),
|
|
268
|
+
t.objectProperty(t.identifier('newArgv'), t.identifier('newArgv'), false, true),
|
|
269
|
+
]), t.callExpression(t.identifier('extractFirst'), [
|
|
270
|
+
t.identifier('argv'),
|
|
271
|
+
])),
|
|
272
|
+
]),
|
|
273
|
+
t.ifStatement(t.unaryExpression('!', t.identifier('subcommand')), t.blockStatement([
|
|
274
|
+
t.variableDeclaration('const', [
|
|
275
|
+
t.variableDeclarator(t.identifier('answer'), t.awaitExpression(t.callExpression(t.memberExpression(t.identifier('prompter'), t.identifier('prompt')), [
|
|
276
|
+
t.identifier('argv'),
|
|
277
|
+
t.arrayExpression([
|
|
278
|
+
t.objectExpression([
|
|
279
|
+
t.objectProperty(t.identifier('type'), t.stringLiteral('autocomplete')),
|
|
280
|
+
t.objectProperty(t.identifier('name'), t.stringLiteral('subcommand')),
|
|
281
|
+
t.objectProperty(t.identifier('message'), t.stringLiteral('What do you want to do?')),
|
|
282
|
+
t.objectProperty(t.identifier('options'), t.arrayExpression(subcommands.map((s) => t.stringLiteral(s)))),
|
|
283
|
+
]),
|
|
284
|
+
]),
|
|
285
|
+
]))),
|
|
286
|
+
]),
|
|
287
|
+
t.returnStatement(t.callExpression(t.identifier('handleTableSubcommand'), [
|
|
288
|
+
t.memberExpression(t.identifier('answer'), t.identifier('subcommand')),
|
|
289
|
+
t.identifier('newArgv'),
|
|
290
|
+
t.identifier('prompter'),
|
|
291
|
+
])),
|
|
292
|
+
])),
|
|
293
|
+
t.returnStatement(t.callExpression(t.identifier('handleTableSubcommand'), [
|
|
294
|
+
t.identifier('subcommand'),
|
|
295
|
+
t.identifier('newArgv'),
|
|
296
|
+
t.identifier('prompter'),
|
|
297
|
+
])),
|
|
298
|
+
];
|
|
299
|
+
statements.push(t.exportDefaultDeclaration(t.arrowFunctionExpression([argvParam, prompterParam, optionsParam], t.blockStatement(mainBody), true)));
|
|
300
|
+
const subcmdParam = t.identifier('subcommand');
|
|
301
|
+
subcmdParam.typeAnnotation = t.tsTypeAnnotation(t.tsStringKeyword());
|
|
302
|
+
const argvParam2 = t.identifier('argv');
|
|
303
|
+
argvParam2.typeAnnotation = buildArgvType();
|
|
304
|
+
const prompterParam2 = t.identifier('prompter');
|
|
305
|
+
prompterParam2.typeAnnotation = t.tsTypeAnnotation(t.tsTypeReference(t.identifier('Inquirerer')));
|
|
306
|
+
statements.push(t.functionDeclaration(t.identifier('handleTableSubcommand'), [subcmdParam, argvParam2, prompterParam2], t.blockStatement([
|
|
307
|
+
buildSubcommandSwitch(subcommands, 'handle', 'usage'),
|
|
308
|
+
]), false, true));
|
|
309
|
+
const tn = options?.targetName;
|
|
310
|
+
statements.push(buildListHandler(table, tn));
|
|
311
|
+
statements.push(buildGetHandler(table, tn));
|
|
312
|
+
statements.push(buildMutationHandler(table, 'create', tn));
|
|
313
|
+
statements.push(buildMutationHandler(table, 'update', tn));
|
|
314
|
+
statements.push(buildMutationHandler(table, 'delete', tn));
|
|
315
|
+
const header = (0, utils_1.getGeneratedFileHeader)(`CLI commands for ${table.name}`);
|
|
316
|
+
const code = (0, babel_ast_1.generateCode)(statements);
|
|
317
|
+
return {
|
|
318
|
+
fileName: options?.targetName
|
|
319
|
+
? `commands/${options.targetName}/${commandName}.ts`
|
|
320
|
+
: `commands/${commandName}.ts`,
|
|
321
|
+
content: header + '\n' + code,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DocsConfig } from '../../types/config';
|
|
2
|
+
import type { CleanField, CleanOperation, CleanTable } from '../../types/schema';
|
|
3
|
+
export interface GeneratedDocFile {
|
|
4
|
+
fileName: string;
|
|
5
|
+
content: string;
|
|
6
|
+
}
|
|
7
|
+
export interface McpTool {
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
inputSchema: Record<string, unknown>;
|
|
11
|
+
_meta?: Record<string, unknown>;
|
|
12
|
+
}
|
|
13
|
+
export interface SkillDefinition {
|
|
14
|
+
name: string;
|
|
15
|
+
description: string;
|
|
16
|
+
usage: string[];
|
|
17
|
+
examples: {
|
|
18
|
+
description: string;
|
|
19
|
+
code: string[];
|
|
20
|
+
}[];
|
|
21
|
+
language?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function getReadmeHeader(title: string): string[];
|
|
24
|
+
export declare function getReadmeFooter(): string[];
|
|
25
|
+
export declare function resolveDocsConfig(docs: DocsConfig | boolean | undefined): DocsConfig;
|
|
26
|
+
export declare function formatArgType(arg: CleanOperation['args'][number]): string;
|
|
27
|
+
export declare function formatTypeRef(t: CleanOperation['args'][number]['type']): string;
|
|
28
|
+
export declare function getEditableFields(table: CleanTable): CleanField[];
|
|
29
|
+
export declare function gqlTypeToJsonSchemaType(gqlType: string): string;
|
|
30
|
+
export declare function buildSkillFile(skill: SkillDefinition): string;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getReadmeHeader = getReadmeHeader;
|
|
4
|
+
exports.getReadmeFooter = getReadmeFooter;
|
|
5
|
+
exports.resolveDocsConfig = resolveDocsConfig;
|
|
6
|
+
exports.formatArgType = formatArgType;
|
|
7
|
+
exports.formatTypeRef = formatTypeRef;
|
|
8
|
+
exports.getEditableFields = getEditableFields;
|
|
9
|
+
exports.gqlTypeToJsonSchemaType = gqlTypeToJsonSchemaType;
|
|
10
|
+
exports.buildSkillFile = buildSkillFile;
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
|
+
const CONSTRUCTIVE_LOGO_URL = 'https://raw.githubusercontent.com/constructive-io/constructive/refs/heads/main/assets/outline-logo.svg';
|
|
13
|
+
const CONSTRUCTIVE_REPO = 'https://github.com/constructive-io/constructive';
|
|
14
|
+
function getReadmeHeader(title) {
|
|
15
|
+
return [
|
|
16
|
+
`# ${title}`,
|
|
17
|
+
'',
|
|
18
|
+
'<p align="center" width="100%">',
|
|
19
|
+
` <img height="120" src="${CONSTRUCTIVE_LOGO_URL}" />`,
|
|
20
|
+
'</p>',
|
|
21
|
+
'',
|
|
22
|
+
`> @generated by @constructive-io/graphql-codegen - DO NOT EDIT`,
|
|
23
|
+
'',
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
function getReadmeFooter() {
|
|
27
|
+
return [
|
|
28
|
+
'---',
|
|
29
|
+
'',
|
|
30
|
+
'Built by the [Constructive](https://constructive.io) team.',
|
|
31
|
+
'',
|
|
32
|
+
'## Disclaimer',
|
|
33
|
+
'',
|
|
34
|
+
'AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.',
|
|
35
|
+
'',
|
|
36
|
+
'No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.',
|
|
37
|
+
'',
|
|
38
|
+
];
|
|
39
|
+
}
|
|
40
|
+
function resolveDocsConfig(docs) {
|
|
41
|
+
if (docs === true) {
|
|
42
|
+
return { readme: true, agents: true, mcp: true, skills: true };
|
|
43
|
+
}
|
|
44
|
+
if (docs === false) {
|
|
45
|
+
return { readme: false, agents: false, mcp: false, skills: false };
|
|
46
|
+
}
|
|
47
|
+
if (!docs) {
|
|
48
|
+
return { readme: true, agents: true, mcp: false, skills: false };
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
readme: docs.readme ?? true,
|
|
52
|
+
agents: docs.agents ?? true,
|
|
53
|
+
mcp: docs.mcp ?? false,
|
|
54
|
+
skills: docs.skills ?? false,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function formatArgType(arg) {
|
|
58
|
+
const t = arg.type;
|
|
59
|
+
if (t.kind === 'NON_NULL' && t.ofType) {
|
|
60
|
+
return `${formatTypeRef(t.ofType)} (required)`;
|
|
61
|
+
}
|
|
62
|
+
return formatTypeRef(t);
|
|
63
|
+
}
|
|
64
|
+
function formatTypeRef(t) {
|
|
65
|
+
if (t.kind === 'LIST' && t.ofType) {
|
|
66
|
+
return `[${formatTypeRef(t.ofType)}]`;
|
|
67
|
+
}
|
|
68
|
+
if (t.kind === 'NON_NULL' && t.ofType) {
|
|
69
|
+
return `${formatTypeRef(t.ofType)}!`;
|
|
70
|
+
}
|
|
71
|
+
return t.name ?? 'unknown';
|
|
72
|
+
}
|
|
73
|
+
function getEditableFields(table) {
|
|
74
|
+
const pk = (0, utils_1.getPrimaryKeyInfo)(table)[0];
|
|
75
|
+
return (0, utils_1.getScalarFields)(table).filter((f) => f.name !== pk.name &&
|
|
76
|
+
f.name !== 'nodeId' &&
|
|
77
|
+
f.name !== 'createdAt' &&
|
|
78
|
+
f.name !== 'updatedAt');
|
|
79
|
+
}
|
|
80
|
+
function gqlTypeToJsonSchemaType(gqlType) {
|
|
81
|
+
switch (gqlType) {
|
|
82
|
+
case 'Int':
|
|
83
|
+
return 'integer';
|
|
84
|
+
case 'Float':
|
|
85
|
+
return 'number';
|
|
86
|
+
case 'Boolean':
|
|
87
|
+
return 'boolean';
|
|
88
|
+
default:
|
|
89
|
+
return 'string';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function buildSkillFile(skill) {
|
|
93
|
+
const lang = skill.language ?? 'bash';
|
|
94
|
+
const lines = [];
|
|
95
|
+
lines.push(`# ${skill.name}`);
|
|
96
|
+
lines.push('');
|
|
97
|
+
lines.push('> @generated by @constructive-io/graphql-codegen - DO NOT EDIT');
|
|
98
|
+
lines.push('');
|
|
99
|
+
lines.push(skill.description);
|
|
100
|
+
lines.push('');
|
|
101
|
+
lines.push('## Usage');
|
|
102
|
+
lines.push('');
|
|
103
|
+
lines.push(`\`\`\`${lang}`);
|
|
104
|
+
for (const u of skill.usage) {
|
|
105
|
+
lines.push(u);
|
|
106
|
+
}
|
|
107
|
+
lines.push('```');
|
|
108
|
+
lines.push('');
|
|
109
|
+
lines.push('## Examples');
|
|
110
|
+
lines.push('');
|
|
111
|
+
for (const ex of skill.examples) {
|
|
112
|
+
lines.push(`### ${ex.description}`);
|
|
113
|
+
lines.push('');
|
|
114
|
+
lines.push(`\`\`\`${lang}`);
|
|
115
|
+
for (const cmd of ex.code) {
|
|
116
|
+
lines.push(cmd);
|
|
117
|
+
}
|
|
118
|
+
lines.push('```');
|
|
119
|
+
lines.push('');
|
|
120
|
+
}
|
|
121
|
+
return lines.join('\n');
|
|
122
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CleanOperation, CleanTable } from '../../types/schema';
|
|
2
|
+
import type { GeneratedDocFile, McpTool } from './docs-utils';
|
|
3
|
+
export declare function generateHooksReadme(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
4
|
+
export declare function generateHooksAgentsDocs(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile;
|
|
5
|
+
export declare function getHooksMcpTools(tables: CleanTable[], customOperations: CleanOperation[]): McpTool[];
|
|
6
|
+
export declare function generateHooksSkills(tables: CleanTable[], customOperations: CleanOperation[]): GeneratedDocFile[];
|