@sdk-it/cli 0.32.0 → 0.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/index.js +493 -46
- package/dist/index.js.map +4 -4
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/commands/find-framework.d.ts +10 -0
- package/dist/lib/commands/find-framework.d.ts.map +1 -0
- package/dist/lib/commands/find-spec-file.d.ts +2 -0
- package/dist/lib/commands/find-spec-file.d.ts.map +1 -0
- package/dist/lib/commands/guess-default-package-name.d.ts +2 -0
- package/dist/lib/commands/guess-default-package-name.d.ts.map +1 -0
- package/dist/lib/commands/init.d.ts +4 -0
- package/dist/lib/commands/init.d.ts.map +1 -0
- package/dist/lib/find-framework.d.ts +10 -0
- package/dist/lib/find-framework.d.ts.map +1 -0
- package/dist/lib/generators/dart.d.ts +4 -14
- package/dist/lib/generators/dart.d.ts.map +1 -1
- package/dist/lib/generators/python.d.ts +2 -14
- package/dist/lib/generators/python.d.ts.map +1 -1
- package/dist/lib/generators/typescript.d.ts +5 -22
- package/dist/lib/generators/typescript.d.ts.map +1 -1
- package/dist/lib/types.d.ts +58 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/package.json +8 -7
package/dist/index.js
CHANGED
|
@@ -1,13 +1,460 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// packages/cli/src/lib/cli.ts
|
|
4
|
-
import { Command as
|
|
5
|
-
import {
|
|
4
|
+
import { Command as Command7, program } from "commander";
|
|
5
|
+
import { readJson as readJson2 } from "@sdk-it/core/file-system.js";
|
|
6
6
|
|
|
7
|
-
// packages/cli/src/lib/
|
|
7
|
+
// packages/cli/src/lib/commands/init.ts
|
|
8
|
+
import { checkbox, confirm, input, select } from "@inquirer/prompts";
|
|
8
9
|
import { Command } from "commander";
|
|
10
|
+
import { writeFile } from "node:fs/promises";
|
|
11
|
+
import { resolve as resolve3 } from "node:path";
|
|
12
|
+
|
|
13
|
+
// packages/cli/src/lib/commands/find-framework.ts
|
|
14
|
+
import { resolve } from "node:path";
|
|
15
|
+
import { exist } from "@sdk-it/core/file-system.js";
|
|
16
|
+
var monorepoIndicators = {
|
|
17
|
+
lerna: () => exist(resolve(process.cwd(), "lerna.json")),
|
|
18
|
+
nx: () => exist(resolve(process.cwd(), "nx.json")),
|
|
19
|
+
pnpm: () => exist(resolve(process.cwd(), "pnpm-workspace.yaml")),
|
|
20
|
+
rush: () => exist(resolve(process.cwd(), "rush.json"))
|
|
21
|
+
};
|
|
22
|
+
async function detectMonorepo() {
|
|
23
|
+
for (const [indicator, check] of Object.entries(monorepoIndicators)) {
|
|
24
|
+
if (await check()) {
|
|
25
|
+
return indicator;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// packages/cli/src/lib/commands/find-spec-file.ts
|
|
32
|
+
import { resolve as resolve2 } from "node:path";
|
|
33
|
+
import { exist as exist2 } from "@sdk-it/core/file-system.js";
|
|
34
|
+
async function findSpecFile() {
|
|
35
|
+
const commonNames = [
|
|
36
|
+
"openapi.json",
|
|
37
|
+
"openapi.yaml",
|
|
38
|
+
"openapi.yml",
|
|
39
|
+
"swagger.json",
|
|
40
|
+
"swagger.yaml",
|
|
41
|
+
"swagger.yml",
|
|
42
|
+
"api.json",
|
|
43
|
+
"api.yaml",
|
|
44
|
+
"api.yml",
|
|
45
|
+
"spec.json",
|
|
46
|
+
"spec.yaml",
|
|
47
|
+
"spec.yml",
|
|
48
|
+
"schema.json",
|
|
49
|
+
"schema.yaml",
|
|
50
|
+
"schema.yml"
|
|
51
|
+
];
|
|
52
|
+
for (const name of commonNames) {
|
|
53
|
+
if (await exist2(resolve2(process.cwd(), name))) {
|
|
54
|
+
return `./${name}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return void 0;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// packages/cli/src/lib/commands/guess-default-package-name.ts
|
|
61
|
+
import { join } from "node:path";
|
|
62
|
+
import { readJson } from "@sdk-it/core/file-system.js";
|
|
63
|
+
async function guessTypescriptPackageName(consideringMultipleGenerator) {
|
|
64
|
+
try {
|
|
65
|
+
const packageJson = await readJson(
|
|
66
|
+
join(process.cwd(), "package.json")
|
|
67
|
+
);
|
|
68
|
+
if (packageJson.name) {
|
|
69
|
+
const match = packageJson.name.match(/^@([^/]+)/);
|
|
70
|
+
if (match) {
|
|
71
|
+
const scope = match[1];
|
|
72
|
+
return consideringMultipleGenerator ? `@${scope}/ts-sdk` : `@${scope}/sdk`;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
return consideringMultipleGenerator ? "ts-sdk" : "sdk";
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// packages/cli/src/lib/commands/init.ts
|
|
81
|
+
var specInput = async (defaultValue) => {
|
|
82
|
+
return input({
|
|
83
|
+
message: "OpenAPI or Postman specification file path:",
|
|
84
|
+
default: defaultValue || "./openapi.json"
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
var generatorConfigs = {
|
|
88
|
+
typescript: {
|
|
89
|
+
name: async (isMultipleGenerators = false) => {
|
|
90
|
+
const defaultName = await guessTypescriptPackageName(isMultipleGenerators);
|
|
91
|
+
return input({
|
|
92
|
+
message: "SDK package name:",
|
|
93
|
+
default: defaultName
|
|
94
|
+
});
|
|
95
|
+
},
|
|
96
|
+
spec: specInput,
|
|
97
|
+
output: async () => {
|
|
98
|
+
let defaultValue = "./ts-sdk";
|
|
99
|
+
const monorepo = await detectMonorepo();
|
|
100
|
+
if (monorepo === "nx") {
|
|
101
|
+
defaultValue = "./packages/ts-sdk";
|
|
102
|
+
}
|
|
103
|
+
return await input({
|
|
104
|
+
message: "Output directory:",
|
|
105
|
+
default: defaultValue
|
|
106
|
+
});
|
|
107
|
+
},
|
|
108
|
+
mode: async () => {
|
|
109
|
+
const options = {
|
|
110
|
+
mode: "full",
|
|
111
|
+
install: false
|
|
112
|
+
};
|
|
113
|
+
options.mode = await select({
|
|
114
|
+
message: "Generation mode:",
|
|
115
|
+
choices: [
|
|
116
|
+
{
|
|
117
|
+
name: "Full (generates package.json and tsconfig.json)",
|
|
118
|
+
value: "full"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: "Minimal (generates only the client TypeScript files)",
|
|
122
|
+
value: "minimal"
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
default: options.mode
|
|
126
|
+
});
|
|
127
|
+
if (options.mode === "full") {
|
|
128
|
+
const installDeps = await confirm({
|
|
129
|
+
message: "Install dependencies automatically?",
|
|
130
|
+
default: true
|
|
131
|
+
});
|
|
132
|
+
options.install = installDeps;
|
|
133
|
+
}
|
|
134
|
+
return options;
|
|
135
|
+
},
|
|
136
|
+
pagination: async () => {
|
|
137
|
+
let pagination = {
|
|
138
|
+
guess: false
|
|
139
|
+
};
|
|
140
|
+
const result = await confirm({
|
|
141
|
+
message: "Enable pagination support?",
|
|
142
|
+
default: false
|
|
143
|
+
});
|
|
144
|
+
if (result) {
|
|
145
|
+
pagination.guess = await confirm({
|
|
146
|
+
message: "Would you like to guess pagination parameters?",
|
|
147
|
+
default: false
|
|
148
|
+
});
|
|
149
|
+
} else {
|
|
150
|
+
pagination = false;
|
|
151
|
+
}
|
|
152
|
+
return pagination;
|
|
153
|
+
},
|
|
154
|
+
outputType: () => select({
|
|
155
|
+
message: "Endpoint output type:",
|
|
156
|
+
choices: [
|
|
157
|
+
{ name: "Default", value: "default" },
|
|
158
|
+
{ name: "Status", value: "status" }
|
|
159
|
+
],
|
|
160
|
+
default: "default"
|
|
161
|
+
}),
|
|
162
|
+
readme: () => confirm({
|
|
163
|
+
message: "Generate README file?",
|
|
164
|
+
default: true
|
|
165
|
+
}),
|
|
166
|
+
defaultFormatter: () => confirm({
|
|
167
|
+
message: "Use default formatter (prettier)?",
|
|
168
|
+
default: true
|
|
169
|
+
}),
|
|
170
|
+
framework: () => input({
|
|
171
|
+
message: "Framework integrating with the SDK (optional):"
|
|
172
|
+
}),
|
|
173
|
+
formatter: () => input({
|
|
174
|
+
message: 'Custom formatter command (optional, e.g., "prettier $SDK_IT_OUTPUT --write"):'
|
|
175
|
+
})
|
|
176
|
+
},
|
|
177
|
+
python: {
|
|
178
|
+
name: () => input({
|
|
179
|
+
message: "SDK package name:",
|
|
180
|
+
default: "my-python-sdk"
|
|
181
|
+
}),
|
|
182
|
+
spec: specInput,
|
|
183
|
+
output: () => input({
|
|
184
|
+
message: "Output directory:",
|
|
185
|
+
default: "./python-sdk"
|
|
186
|
+
}),
|
|
187
|
+
mode: async () => {
|
|
188
|
+
const isMonorepo = await detectMonorepo();
|
|
189
|
+
return select({
|
|
190
|
+
message: "Generation mode:",
|
|
191
|
+
choices: [
|
|
192
|
+
{
|
|
193
|
+
name: "Full (generates complete project structure)",
|
|
194
|
+
value: "full"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
name: "Minimal (generates only the client files)",
|
|
198
|
+
value: "minimal"
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
default: isMonorepo ? "full" : "full"
|
|
202
|
+
// Default to full, especially for monorepos
|
|
203
|
+
}).then((value) => value);
|
|
204
|
+
},
|
|
205
|
+
formatter: () => input({
|
|
206
|
+
message: 'Custom formatter command (optional, e.g., "black $SDK_IT_OUTPUT" or "ruff format $SDK_IT_OUTPUT"):'
|
|
207
|
+
})
|
|
208
|
+
},
|
|
209
|
+
dart: {
|
|
210
|
+
name: () => input({
|
|
211
|
+
message: "SDK package name:",
|
|
212
|
+
default: "my-dart-sdk"
|
|
213
|
+
}),
|
|
214
|
+
spec: specInput,
|
|
215
|
+
output: () => input({
|
|
216
|
+
message: "Output directory:",
|
|
217
|
+
default: "./dart-sdk"
|
|
218
|
+
}),
|
|
219
|
+
mode: async () => {
|
|
220
|
+
const isMonorepo = await detectMonorepo();
|
|
221
|
+
return select({
|
|
222
|
+
message: "Generation mode:",
|
|
223
|
+
choices: [
|
|
224
|
+
{
|
|
225
|
+
name: "Full (generates complete project structure)",
|
|
226
|
+
value: "full"
|
|
227
|
+
},
|
|
228
|
+
{
|
|
229
|
+
name: "Minimal (generates only the client files)",
|
|
230
|
+
value: "minimal"
|
|
231
|
+
}
|
|
232
|
+
],
|
|
233
|
+
default: isMonorepo ? "full" : "full"
|
|
234
|
+
// Default to full, especially for monorepos
|
|
235
|
+
}).then((value) => value);
|
|
236
|
+
},
|
|
237
|
+
pagination: async () => {
|
|
238
|
+
let pagination = {
|
|
239
|
+
guess: false
|
|
240
|
+
};
|
|
241
|
+
const result = await confirm({
|
|
242
|
+
message: "Enable pagination support?",
|
|
243
|
+
default: false
|
|
244
|
+
});
|
|
245
|
+
if (result) {
|
|
246
|
+
pagination.guess = await confirm({
|
|
247
|
+
message: "Would you like to guess pagination parameters?",
|
|
248
|
+
default: false
|
|
249
|
+
});
|
|
250
|
+
} else {
|
|
251
|
+
pagination = false;
|
|
252
|
+
}
|
|
253
|
+
return pagination;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
var init = new Command("init").description("Initialize SDK-IT configuration interactively").action(async () => {
|
|
258
|
+
console.log("Welcome to SDK-IT! Let's set up your configuration.\n");
|
|
259
|
+
const possibleSpecFile = await findSpecFile();
|
|
260
|
+
const monorepo = await detectMonorepo();
|
|
261
|
+
if (possibleSpecFile) {
|
|
262
|
+
console.log(`\u{1F50D} Auto-detected API specification: ${possibleSpecFile}`);
|
|
263
|
+
}
|
|
264
|
+
if (monorepo) {
|
|
265
|
+
console.log(`\u{1F4E6} Detected monorepo setup`);
|
|
266
|
+
}
|
|
267
|
+
if (possibleSpecFile || monorepo) {
|
|
268
|
+
console.log("");
|
|
269
|
+
}
|
|
270
|
+
const config = {
|
|
271
|
+
generators: {}
|
|
272
|
+
};
|
|
273
|
+
const generators = await checkbox({
|
|
274
|
+
message: "Which SDK generators would you like to configure?",
|
|
275
|
+
loop: false,
|
|
276
|
+
instructions: false,
|
|
277
|
+
required: true,
|
|
278
|
+
choices: [
|
|
279
|
+
{ name: "TypeScript", value: "typescript" },
|
|
280
|
+
{ name: "Python", value: "python" },
|
|
281
|
+
{ name: "Dart", value: "dart" }
|
|
282
|
+
]
|
|
283
|
+
});
|
|
284
|
+
for (const generator of generators) {
|
|
285
|
+
console.log(`
|
|
286
|
+
Configuring ${generator} generator:`);
|
|
287
|
+
if (generator === "typescript") {
|
|
288
|
+
const tsConfig = generatorConfigs.typescript;
|
|
289
|
+
const isMultipleGenerators = generators.length > 1;
|
|
290
|
+
const generatorConfig = {
|
|
291
|
+
spec: await tsConfig.spec(possibleSpecFile),
|
|
292
|
+
output: await tsConfig.output(),
|
|
293
|
+
name: await tsConfig.name(isMultipleGenerators),
|
|
294
|
+
defaultFormatter: await tsConfig.defaultFormatter(),
|
|
295
|
+
outputType: await tsConfig.outputType(),
|
|
296
|
+
readme: await tsConfig.readme(),
|
|
297
|
+
pagination: await tsConfig.pagination(),
|
|
298
|
+
...await tsConfig.mode()
|
|
299
|
+
};
|
|
300
|
+
const customFramework = await tsConfig.framework();
|
|
301
|
+
if (customFramework) {
|
|
302
|
+
generatorConfig.framework = customFramework;
|
|
303
|
+
}
|
|
304
|
+
const customFormatter = await tsConfig.formatter();
|
|
305
|
+
if (customFormatter) {
|
|
306
|
+
generatorConfig.formatter = customFormatter;
|
|
307
|
+
}
|
|
308
|
+
config.generators.typescript = generatorConfig;
|
|
309
|
+
} else if (generator === "python") {
|
|
310
|
+
config.generators.python = {
|
|
311
|
+
spec: await generatorConfigs.python.spec(),
|
|
312
|
+
output: await generatorConfigs.python.output(),
|
|
313
|
+
mode: await generatorConfigs.python.mode(),
|
|
314
|
+
name: await generatorConfigs.python.name()
|
|
315
|
+
};
|
|
316
|
+
} else if (generator === "dart") {
|
|
317
|
+
config.generators.dart = {
|
|
318
|
+
spec: await generatorConfigs.dart.spec(),
|
|
319
|
+
output: await generatorConfigs.dart.output(),
|
|
320
|
+
mode: await generatorConfigs.dart.mode(),
|
|
321
|
+
name: await generatorConfigs.dart.name(),
|
|
322
|
+
pagination: await generatorConfigs.dart.pagination()
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
const generateReadme = await confirm({
|
|
327
|
+
message: "\nGenerate README documentation?",
|
|
328
|
+
default: true
|
|
329
|
+
});
|
|
330
|
+
if (generateReadme) {
|
|
331
|
+
const readmeSpec = await input({
|
|
332
|
+
message: "OpenAPI specification for README:",
|
|
333
|
+
default: config.generators.typescript?.spec || possibleSpecFile || "./openapi.yaml"
|
|
334
|
+
});
|
|
335
|
+
const readmeOutput = await input({
|
|
336
|
+
message: "README output file:",
|
|
337
|
+
default: "./README.md"
|
|
338
|
+
});
|
|
339
|
+
config.readme = {
|
|
340
|
+
spec: readmeSpec,
|
|
341
|
+
output: readmeOutput
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
const generateApiRef = await confirm({
|
|
345
|
+
message: "\nGenerate API reference documentation?",
|
|
346
|
+
default: false
|
|
347
|
+
});
|
|
348
|
+
if (generateApiRef) {
|
|
349
|
+
const autoDetected = await findSpecFile();
|
|
350
|
+
const apirefSpec = await input({
|
|
351
|
+
message: "OpenAPI specification for API reference:",
|
|
352
|
+
default: config.generators.typescript?.spec || autoDetected || "./openapi.yaml"
|
|
353
|
+
});
|
|
354
|
+
const apirefOutput = await input({
|
|
355
|
+
message: "API reference output directory:",
|
|
356
|
+
default: "./docs"
|
|
357
|
+
});
|
|
358
|
+
config.apiref = {
|
|
359
|
+
spec: apirefSpec,
|
|
360
|
+
output: apirefOutput
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
const configPath = resolve3(process.cwd(), "sdk-it.json");
|
|
364
|
+
await writeFile(configPath, JSON.stringify(config, null, 2));
|
|
365
|
+
console.log(`
|
|
366
|
+
\u2705 Configuration saved to ${configPath}`);
|
|
367
|
+
console.log("\n\u{1F680} Next Steps:\n");
|
|
368
|
+
console.log("1. Generate your SDK(s):");
|
|
369
|
+
console.log(" npx @sdk-it/cli");
|
|
370
|
+
if (config.generators.typescript) {
|
|
371
|
+
console.log("2. Integrate TypeScript SDK:");
|
|
372
|
+
const importName = config.generators.typescript.name.replace(
|
|
373
|
+
/[^a-zA-Z0-9]/g,
|
|
374
|
+
""
|
|
375
|
+
);
|
|
376
|
+
const outputDir = config.generators.typescript.output.replace("./", "");
|
|
377
|
+
console.log(` import { ${importName} } from './${outputDir}';`);
|
|
378
|
+
console.log(` const client = new ${importName}();`);
|
|
379
|
+
console.log(` const result = await client.request('GET /users');
|
|
380
|
+
`);
|
|
381
|
+
}
|
|
382
|
+
if (config.generators.python) {
|
|
383
|
+
console.log("2. Integrate Python SDK:");
|
|
384
|
+
const outputDir = config.generators.python.output.replace("./", "");
|
|
385
|
+
console.log(` # Add to your Python path or install locally`);
|
|
386
|
+
console.log(` from ${outputDir} import Client`);
|
|
387
|
+
console.log(` client = Client()`);
|
|
388
|
+
console.log(` result = client.users.list_users()
|
|
389
|
+
`);
|
|
390
|
+
}
|
|
391
|
+
if (config.generators.dart) {
|
|
392
|
+
console.log("2. Integrate Dart SDK:");
|
|
393
|
+
const outputDir = config.generators.dart.output.replace("./", "");
|
|
394
|
+
console.log(` # Add dependency to pubspec.yaml`);
|
|
395
|
+
console.log(` import 'package:${outputDir}/client.dart';`);
|
|
396
|
+
console.log(` final client = Client();`);
|
|
397
|
+
console.log(` final result = await client.users.listUsers();
|
|
398
|
+
`);
|
|
399
|
+
}
|
|
400
|
+
console.log("3. Check generated documentation:");
|
|
401
|
+
const outputs = [];
|
|
402
|
+
if (config.generators.typescript)
|
|
403
|
+
outputs.push(config.generators.typescript.output);
|
|
404
|
+
if (config.generators.python) outputs.push(config.generators.python.output);
|
|
405
|
+
if (config.generators.dart) outputs.push(config.generators.dart.output);
|
|
406
|
+
outputs.forEach((output) => {
|
|
407
|
+
if (output) {
|
|
408
|
+
console.log(
|
|
409
|
+
` \u{1F4D6} ${output}/README.md - Usage examples and API reference`
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
if (config.readme) {
|
|
414
|
+
console.log(
|
|
415
|
+
` \u{1F4D6} ${config.readme.output} - Generated API documentation`
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
if (config.apiref) {
|
|
419
|
+
console.log(` \u{1F310} ${config.apiref.output} - Interactive API reference`);
|
|
420
|
+
}
|
|
421
|
+
console.log("\n4. Useful commands:");
|
|
422
|
+
console.log(
|
|
423
|
+
" npx @sdk-it/cli # Regenerate SDKs after API changes"
|
|
424
|
+
);
|
|
425
|
+
console.log(
|
|
426
|
+
" npx @sdk-it/cli typescript --help # See TypeScript-specific options"
|
|
427
|
+
);
|
|
428
|
+
console.log(
|
|
429
|
+
" npx @sdk-it/cli python --help # See Python-specific options"
|
|
430
|
+
);
|
|
431
|
+
console.log(
|
|
432
|
+
" npx @sdk-it/cli dart --help # See Dart-specific options"
|
|
433
|
+
);
|
|
434
|
+
console.log("\n\u{1F4A1} Tips:");
|
|
435
|
+
console.log(
|
|
436
|
+
" \u2022 Update your API spec and re-run `npx @sdk-it/cli generate` to sync changes"
|
|
437
|
+
);
|
|
438
|
+
console.log(
|
|
439
|
+
" \u2022 Generated SDKs include TypeScript definitions for excellent IDE support"
|
|
440
|
+
);
|
|
441
|
+
console.log(
|
|
442
|
+
" \u2022 Check the README files for authentication and configuration options"
|
|
443
|
+
);
|
|
444
|
+
console.log("\n\u{1F4DA} Need help?");
|
|
445
|
+
console.log(" \u2022 Documentation: https://sdk-it.dev/docs");
|
|
446
|
+
console.log(
|
|
447
|
+
" \u2022 Examples: https://github.com/JanuaryLabs/sdk-it/tree/main/docs/examples"
|
|
448
|
+
);
|
|
449
|
+
console.log(" \u2022 Issues: https://github.com/JanuaryLabs/sdk-it/issues");
|
|
450
|
+
console.log("\nHappy coding! \u{1F389}\n");
|
|
451
|
+
});
|
|
452
|
+
var init_default = init;
|
|
453
|
+
|
|
454
|
+
// packages/cli/src/lib/generators/apiref.ts
|
|
455
|
+
import { Command as Command2 } from "commander";
|
|
9
456
|
import { execa } from "execa";
|
|
10
|
-
import { dirname, join } from "node:path";
|
|
457
|
+
import { dirname, join as join2 } from "node:path";
|
|
11
458
|
|
|
12
459
|
// packages/cli/src/lib/options.ts
|
|
13
460
|
import { Option } from "commander";
|
|
@@ -61,11 +508,11 @@ function parsePagination(config) {
|
|
|
61
508
|
}
|
|
62
509
|
|
|
63
510
|
// packages/cli/src/lib/generators/apiref.ts
|
|
64
|
-
var apiref_default = new
|
|
511
|
+
var apiref_default = new Command2("apiref").description("Generate APIREF").addOption(specOption.makeOptionMandatory(true)).addOption(outputOption.makeOptionMandatory(true)).action(async (options) => {
|
|
65
512
|
await runApiRef(options.spec, options.output);
|
|
66
513
|
});
|
|
67
514
|
function runApiRef(spec, output) {
|
|
68
|
-
const packageDir =
|
|
515
|
+
const packageDir = join2(dirname(import.meta.url), "..", "..", "apiref");
|
|
69
516
|
return execa("nx", ["run", "apiref:build", "--verbose"], {
|
|
70
517
|
stdio: "inherit",
|
|
71
518
|
extendEnv: true,
|
|
@@ -78,11 +525,11 @@ function runApiRef(spec, output) {
|
|
|
78
525
|
}
|
|
79
526
|
|
|
80
527
|
// packages/cli/src/lib/generators/dart.ts
|
|
81
|
-
import { Command as
|
|
528
|
+
import { Command as Command3 } from "commander";
|
|
82
529
|
import { execFile, execSync } from "node:child_process";
|
|
83
530
|
import { generate } from "@sdk-it/dart";
|
|
84
531
|
import { loadSpec } from "@sdk-it/spec";
|
|
85
|
-
var dart_default = new
|
|
532
|
+
var dart_default = new Command3("dart").description("Generate Dart SDK").addOption(specOption.makeOptionMandatory(true)).addOption(outputOption.makeOptionMandatory(true)).option("-n, --name <name>", "Name of the generated client", "Client").option(
|
|
86
533
|
"--pagination <pagination>",
|
|
87
534
|
'Configure pagination (e.g., "false", "true", "guess=false")',
|
|
88
535
|
"true"
|
|
@@ -94,7 +541,7 @@ async function runDart(options) {
|
|
|
94
541
|
output: options.output,
|
|
95
542
|
mode: options.mode || "full",
|
|
96
543
|
name: options.name,
|
|
97
|
-
pagination: parsePagination(parseDotConfig(options.pagination ?? "true")),
|
|
544
|
+
pagination: typeof options.pagination === "string" ? parsePagination(parseDotConfig(options.pagination ?? "true")) : options.pagination,
|
|
98
545
|
formatCode: ({ output }) => {
|
|
99
546
|
if (options.formatter) {
|
|
100
547
|
const [command, ...args] = options.formatter.split(" ");
|
|
@@ -112,12 +559,12 @@ async function runDart(options) {
|
|
|
112
559
|
}
|
|
113
560
|
|
|
114
561
|
// packages/cli/src/lib/generators/python.ts
|
|
115
|
-
import { Command as
|
|
562
|
+
import { Command as Command4 } from "commander";
|
|
116
563
|
import { execFile as execFile2, execSync as execSync2 } from "node:child_process";
|
|
117
564
|
|
|
118
565
|
// packages/python/dist/index.js
|
|
119
566
|
import { readdir } from "node:fs/promises";
|
|
120
|
-
import { join as
|
|
567
|
+
import { join as join3 } from "node:path";
|
|
121
568
|
import { snakecase as snakecase2 } from "stringcase";
|
|
122
569
|
import { isEmpty, isRef as isRef2, pascalcase as pascalcase2 } from "@sdk-it/core";
|
|
123
570
|
import {
|
|
@@ -1730,7 +2177,7 @@ async function generate2(openapi, settings) {
|
|
|
1730
2177
|
const files = await readdir(folder, { withFileTypes: true });
|
|
1731
2178
|
return files.map((file) => ({
|
|
1732
2179
|
fileName: file.name,
|
|
1733
|
-
filePath:
|
|
2180
|
+
filePath: join3(file.parentPath, file.name),
|
|
1734
2181
|
isFolder: file.isDirectory()
|
|
1735
2182
|
}));
|
|
1736
2183
|
};
|
|
@@ -1741,7 +2188,7 @@ async function generate2(openapi, settings) {
|
|
|
1741
2188
|
className: `${pascalcase2(entry.tag)}Api`,
|
|
1742
2189
|
methods: []
|
|
1743
2190
|
};
|
|
1744
|
-
const
|
|
2191
|
+
const input2 = toInputs(spec, { entry, operation });
|
|
1745
2192
|
const response = toOutput(spec, operation);
|
|
1746
2193
|
const methodName = snakecase2(
|
|
1747
2194
|
operation.operationId || `${entry.method}_${entry.path.replace(/[^a-zA-Z0-9]/g, "_")}`
|
|
@@ -1749,16 +2196,16 @@ async function generate2(openapi, settings) {
|
|
|
1749
2196
|
const returnType = response ? response.returnType : "httpx.Response";
|
|
1750
2197
|
const docstring = operation.summary || operation.description ? ` """${operation.summary || operation.description}"""` : "";
|
|
1751
2198
|
group.methods.push(`
|
|
1752
|
-
async def ${methodName}(self${
|
|
2199
|
+
async def ${methodName}(self${input2.haveInput ? `, input_data: ${input2.inputName}` : ""}) -> ${returnType}:
|
|
1753
2200
|
${docstring}
|
|
1754
2201
|
config = RequestConfig(
|
|
1755
2202
|
method='${entry.method.toUpperCase()}',
|
|
1756
2203
|
url='${entry.path}',
|
|
1757
2204
|
)
|
|
1758
2205
|
|
|
1759
|
-
${
|
|
2206
|
+
${input2.haveInput ? "config = input_data.to_request_config(config)" : ""}
|
|
1760
2207
|
|
|
1761
|
-
response = await self.dispatcher.${
|
|
2208
|
+
response = await self.dispatcher.${input2.contentType}(config)
|
|
1762
2209
|
${response ? `return await self.receiver.json(response, ${response.successModel || "None"}, ${response.errorModel || "None"})` : "return response"}
|
|
1763
2210
|
`);
|
|
1764
2211
|
});
|
|
@@ -1924,19 +2371,19 @@ python-dateutil>=2.8.0
|
|
|
1924
2371
|
}
|
|
1925
2372
|
await settings.writer(output, {
|
|
1926
2373
|
"models/__init__.py": await generateModuleInit(
|
|
1927
|
-
|
|
2374
|
+
join3(output, "models"),
|
|
1928
2375
|
settings.readFolder
|
|
1929
2376
|
),
|
|
1930
2377
|
"inputs/__init__.py": await generateModuleInit(
|
|
1931
|
-
|
|
2378
|
+
join3(output, "inputs"),
|
|
1932
2379
|
settings.readFolder
|
|
1933
2380
|
),
|
|
1934
2381
|
"outputs/__init__.py": await generateModuleInit(
|
|
1935
|
-
|
|
2382
|
+
join3(output, "outputs"),
|
|
1936
2383
|
settings.readFolder
|
|
1937
2384
|
),
|
|
1938
2385
|
"api/__init__.py": await generateModuleInit(
|
|
1939
|
-
|
|
2386
|
+
join3(output, "api"),
|
|
1940
2387
|
settings.readFolder
|
|
1941
2388
|
),
|
|
1942
2389
|
"http/__init__.py": `"""HTTP utilities."""
|
|
@@ -2077,7 +2524,7 @@ ${content}`;
|
|
|
2077
2524
|
|
|
2078
2525
|
// packages/cli/src/lib/generators/python.ts
|
|
2079
2526
|
import { loadSpec as loadSpec2, toIR as toIR2 } from "@sdk-it/spec";
|
|
2080
|
-
var python_default = new
|
|
2527
|
+
var python_default = new Command4("python").description("Generate Python SDK").addOption(specOption.makeOptionMandatory(true)).addOption(outputOption.makeOptionMandatory(true)).option("-n, --name <n>", "Name of the generated client", "Client").option("-v, --verbose", "Verbose output", false).option("--formatter <formatter>", "Formatter to use for the generated code").action(async (options) => {
|
|
2081
2528
|
await runPython(options);
|
|
2082
2529
|
});
|
|
2083
2530
|
async function runPython(options) {
|
|
@@ -2118,31 +2565,31 @@ async function runPython(options) {
|
|
|
2118
2565
|
}
|
|
2119
2566
|
|
|
2120
2567
|
// packages/cli/src/lib/generators/readme.ts
|
|
2121
|
-
import { Command as
|
|
2122
|
-
import { writeFile } from "node:fs/promises";
|
|
2568
|
+
import { Command as Command5 } from "commander";
|
|
2569
|
+
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
2123
2570
|
import { toReadme } from "@sdk-it/readme";
|
|
2124
2571
|
import { loadSpec as loadSpec3, toIR as toIR3 } from "@sdk-it/spec";
|
|
2125
|
-
var readme_default = new
|
|
2572
|
+
var readme_default = new Command5("readme").description("Generate README").addOption(specOption.makeOptionMandatory(true)).addOption(outputOption.makeOptionMandatory(true)).action(async (options) => {
|
|
2126
2573
|
await runReadme(options.spec, options.output);
|
|
2127
2574
|
});
|
|
2128
2575
|
async function runReadme(specFile, output) {
|
|
2129
2576
|
const spec = toIR3({ spec: await loadSpec3(specFile) });
|
|
2130
2577
|
const content = toReadme(spec);
|
|
2131
|
-
await
|
|
2578
|
+
await writeFile2(output, content, "utf-8");
|
|
2132
2579
|
}
|
|
2133
2580
|
|
|
2134
2581
|
// packages/cli/src/lib/generators/typescript.ts
|
|
2135
|
-
import { Command as
|
|
2582
|
+
import { Command as Command6, Option as Option2 } from "commander";
|
|
2136
2583
|
import { publish } from "libnpmpublish";
|
|
2137
2584
|
import { execFile as execFile3, execSync as execSync3, spawnSync } from "node:child_process";
|
|
2138
2585
|
import { readFile } from "node:fs/promises";
|
|
2139
2586
|
import { tmpdir } from "node:os";
|
|
2140
|
-
import { join as
|
|
2587
|
+
import { join as join4 } from "node:path";
|
|
2141
2588
|
import getAuthToken from "registry-auth-token";
|
|
2142
2589
|
import { writeFiles as writeFiles2 } from "@sdk-it/core/file-system.js";
|
|
2143
2590
|
import { loadSpec as loadSpec4 } from "@sdk-it/spec";
|
|
2144
2591
|
import { generate as generate3 } from "@sdk-it/typescript";
|
|
2145
|
-
var typescript_default = new
|
|
2592
|
+
var typescript_default = new Command6("typescript").alias("ts").description("Generate TypeScript SDK").addOption(specOption.makeOptionMandatory(true)).addOption(outputOption.makeOptionMandatory(false)).option(
|
|
2146
2593
|
"--useTsExtension [value]",
|
|
2147
2594
|
"Use .ts extension for generated files",
|
|
2148
2595
|
(value) => value === "false" ? false : true,
|
|
@@ -2185,7 +2632,10 @@ async function runTypescript(options) {
|
|
|
2185
2632
|
}
|
|
2186
2633
|
const spec = await loadSpec4(options.spec);
|
|
2187
2634
|
if (options.output) {
|
|
2188
|
-
await emitLocal(spec, {
|
|
2635
|
+
await emitLocal(spec, {
|
|
2636
|
+
...options,
|
|
2637
|
+
output: options.output
|
|
2638
|
+
});
|
|
2189
2639
|
}
|
|
2190
2640
|
if (options.publish) {
|
|
2191
2641
|
await emitRemote(spec, {
|
|
@@ -2200,7 +2650,7 @@ async function emitLocal(spec, options) {
|
|
|
2200
2650
|
output: options.output,
|
|
2201
2651
|
mode: options.mode || "minimal",
|
|
2202
2652
|
name: options.name,
|
|
2203
|
-
pagination: parsePagination(parseDotConfig(options.pagination ?? "true")),
|
|
2653
|
+
pagination: typeof options.pagination === "string" ? parsePagination(parseDotConfig(options.pagination ?? "true")) : options.pagination,
|
|
2204
2654
|
style: {
|
|
2205
2655
|
name: "github",
|
|
2206
2656
|
outputType: options.outputType,
|
|
@@ -2237,7 +2687,7 @@ async function emitLocal(spec, options) {
|
|
|
2237
2687
|
async function emitRemote(spec, options) {
|
|
2238
2688
|
const registry = options.publish === "npm" ? "https://registry.npmjs.org/" : options.publish === "github" ? "https://npm.pkg.github.com/" : options.publish;
|
|
2239
2689
|
console.log("Publishing to registry:", registry);
|
|
2240
|
-
const path =
|
|
2690
|
+
const path = join4(tmpdir(), crypto.randomUUID());
|
|
2241
2691
|
await emitLocal(spec, {
|
|
2242
2692
|
...options,
|
|
2243
2693
|
output: path,
|
|
@@ -2245,7 +2695,7 @@ async function emitRemote(spec, options) {
|
|
|
2245
2695
|
mode: "full"
|
|
2246
2696
|
});
|
|
2247
2697
|
const manifest = JSON.parse(
|
|
2248
|
-
await readFile(
|
|
2698
|
+
await readFile(join4(path, "package.json"), "utf-8")
|
|
2249
2699
|
);
|
|
2250
2700
|
const registryUrl = new URL(registry);
|
|
2251
2701
|
const npmrc = process.env.NPM_TOKEN ? {
|
|
@@ -2262,7 +2712,7 @@ async function emitRemote(spec, options) {
|
|
|
2262
2712
|
}
|
|
2263
2713
|
const packResult = execSync3("npm pack --pack-destination .", { cwd: path });
|
|
2264
2714
|
const [tgzName] = packResult.toString().trim().split("\n");
|
|
2265
|
-
await publish(manifest, await readFile(
|
|
2715
|
+
await publish(manifest, await readFile(join4(path, tgzName)), {
|
|
2266
2716
|
registry,
|
|
2267
2717
|
defaultTag: "latest",
|
|
2268
2718
|
forceAuth: {
|
|
@@ -2274,11 +2724,9 @@ async function emitRemote(spec, options) {
|
|
|
2274
2724
|
}
|
|
2275
2725
|
|
|
2276
2726
|
// packages/cli/src/lib/cli.ts
|
|
2277
|
-
var generate4 = new
|
|
2727
|
+
var generate4 = new Command7("generate").action(async (options) => {
|
|
2278
2728
|
options.config ??= "sdk-it.json";
|
|
2279
|
-
const config = await
|
|
2280
|
-
(data) => JSON.parse(data)
|
|
2281
|
-
);
|
|
2729
|
+
const config = await readJson2(options.config);
|
|
2282
2730
|
const promises = [];
|
|
2283
2731
|
if (config.generators?.typescript) {
|
|
2284
2732
|
promises.push(
|
|
@@ -2287,13 +2735,13 @@ var generate4 = new Command6("generate").action(async (options) => {
|
|
|
2287
2735
|
output: config.generators.typescript.output,
|
|
2288
2736
|
mode: config.generators.typescript.mode,
|
|
2289
2737
|
name: config.generators.typescript.name,
|
|
2290
|
-
useTsExtension: true,
|
|
2291
|
-
install:
|
|
2738
|
+
useTsExtension: config.generators.typescript.useTsExtension ?? true,
|
|
2739
|
+
install: config.generators.typescript.install ?? false,
|
|
2292
2740
|
verbose: false,
|
|
2293
|
-
defaultFormatter: true,
|
|
2741
|
+
defaultFormatter: config.generators.typescript.defaultFormatter ?? true,
|
|
2294
2742
|
outputType: "default",
|
|
2295
|
-
readme: true,
|
|
2296
|
-
pagination: config.generators.typescript.pagination
|
|
2743
|
+
readme: config.generators.typescript.readme ?? true,
|
|
2744
|
+
pagination: config.generators.typescript.pagination
|
|
2297
2745
|
})
|
|
2298
2746
|
);
|
|
2299
2747
|
}
|
|
@@ -2315,9 +2763,8 @@ var generate4 = new Command6("generate").action(async (options) => {
|
|
|
2315
2763
|
output: config.generators.dart.output,
|
|
2316
2764
|
mode: config.generators.dart.mode,
|
|
2317
2765
|
name: config.generators.dart.name,
|
|
2318
|
-
useTsExtension: false,
|
|
2319
2766
|
verbose: false,
|
|
2320
|
-
pagination: config.generators.dart.pagination
|
|
2767
|
+
pagination: config.generators.dart.pagination
|
|
2321
2768
|
})
|
|
2322
2769
|
);
|
|
2323
2770
|
}
|
|
@@ -2327,8 +2774,8 @@ var generate4 = new Command6("generate").action(async (options) => {
|
|
|
2327
2774
|
await Promise.all(promises);
|
|
2328
2775
|
console.log("All configured generators completed successfully!");
|
|
2329
2776
|
}).addCommand(typescript_default).addCommand(python_default).addCommand(dart_default).addCommand(apiref_default).addCommand(readme_default);
|
|
2330
|
-
var cli = program.description(`CLI tool to interact with SDK-IT.`).addCommand(generate4, { isDefault: true }).addCommand(
|
|
2331
|
-
new
|
|
2777
|
+
var cli = program.description(`CLI tool to interact with SDK-IT.`).addCommand(generate4, { isDefault: true }).addCommand(init_default).addCommand(
|
|
2778
|
+
new Command7("_internal").action(() => {
|
|
2332
2779
|
}),
|
|
2333
2780
|
{ hidden: true }
|
|
2334
2781
|
).parse(process.argv);
|