@spfn/core 0.1.0-alpha.62 → 0.1.0-alpha.63
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.
|
@@ -250,9 +250,13 @@ async function generateClient(mappings, options) {
|
|
|
250
250
|
const startTime = Date.now();
|
|
251
251
|
const grouped = groupByResource(mappings);
|
|
252
252
|
const resourceNames = Object.keys(grouped);
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
if (options.splitByResource === false) {
|
|
254
|
+
const code = generateClientCode(mappings, grouped, options);
|
|
255
|
+
await mkdir(dirname(options.outputPath), { recursive: true });
|
|
256
|
+
await writeFile(options.outputPath, code, "utf-8");
|
|
257
|
+
} else {
|
|
258
|
+
await generateSplitClient(mappings, grouped, options);
|
|
259
|
+
}
|
|
256
260
|
return {
|
|
257
261
|
routesScanned: mappings.length,
|
|
258
262
|
contractsFound: mappings.length,
|
|
@@ -269,7 +273,7 @@ function generateClientCode(mappings, grouped, options) {
|
|
|
269
273
|
{
|
|
270
274
|
code += generateTypes(mappings);
|
|
271
275
|
}
|
|
272
|
-
code += generateApiObject(grouped);
|
|
276
|
+
code += generateApiObject(grouped, options);
|
|
273
277
|
code += generateFooter();
|
|
274
278
|
return code;
|
|
275
279
|
}
|
|
@@ -382,7 +386,7 @@ export const api = {
|
|
|
382
386
|
`;
|
|
383
387
|
for (let j = 0; j < routes.length; j++) {
|
|
384
388
|
const route = routes[j];
|
|
385
|
-
code += generateMethodCode(route);
|
|
389
|
+
code += generateMethodCode(route, options);
|
|
386
390
|
}
|
|
387
391
|
code += ` }`;
|
|
388
392
|
if (i < resourceNames.length - 1) {
|
|
@@ -398,12 +402,11 @@ export const api = {
|
|
|
398
402
|
}
|
|
399
403
|
function generateMethodCode(mapping, options) {
|
|
400
404
|
const methodName = generateMethodName(mapping);
|
|
401
|
-
const contractType = `typeof ${mapping.contractName}`;
|
|
402
405
|
const hasParams = mapping.hasParams || mapping.path.includes(":");
|
|
403
406
|
const hasQuery = mapping.hasQuery || false;
|
|
404
407
|
const hasBody = mapping.hasBody || false;
|
|
405
408
|
let code = "";
|
|
406
|
-
{
|
|
409
|
+
if (options.includeJsDoc !== false) {
|
|
407
410
|
code += ` /**
|
|
408
411
|
`;
|
|
409
412
|
code += ` * ${mapping.method} ${mapping.path}
|
|
@@ -413,14 +416,15 @@ function generateMethodCode(mapping, options) {
|
|
|
413
416
|
}
|
|
414
417
|
code += ` ${methodName}: (`;
|
|
415
418
|
const params = [];
|
|
419
|
+
const typeName = generateTypeName(mapping);
|
|
416
420
|
if (hasParams) {
|
|
417
|
-
params.push(`params:
|
|
421
|
+
params.push(`params: ${typeName}Params`);
|
|
418
422
|
}
|
|
419
423
|
if (hasQuery) {
|
|
420
|
-
params.push(`query?:
|
|
424
|
+
params.push(`query?: ${typeName}Query`);
|
|
421
425
|
}
|
|
422
426
|
if (hasBody) {
|
|
423
|
-
params.push(`body:
|
|
427
|
+
params.push(`body: ${typeName}Body`);
|
|
424
428
|
}
|
|
425
429
|
if (params.length > 0) {
|
|
426
430
|
code += `options: { ${params.join(", ")} }`;
|
|
@@ -487,6 +491,130 @@ function countUniqueContractFiles(mappings) {
|
|
|
487
491
|
}
|
|
488
492
|
return files.size;
|
|
489
493
|
}
|
|
494
|
+
async function generateSplitClient(_mappings, grouped, options) {
|
|
495
|
+
const outputPath = options.outputPath;
|
|
496
|
+
const outputDir = outputPath.endsWith(".ts") || outputPath.endsWith(".js") ? outputPath.replace(/\.[jt]s$/, "") : outputPath;
|
|
497
|
+
await mkdir(outputDir, { recursive: true });
|
|
498
|
+
const resourceNames = Object.keys(grouped);
|
|
499
|
+
for (let i = 0; i < resourceNames.length; i++) {
|
|
500
|
+
const resourceName = resourceNames[i];
|
|
501
|
+
const routes = grouped[resourceName];
|
|
502
|
+
const code = generateResourceFile(resourceName, routes, options);
|
|
503
|
+
const filePath = `${outputDir}/${resourceName}.ts`;
|
|
504
|
+
await writeFile(filePath, code, "utf-8");
|
|
505
|
+
}
|
|
506
|
+
const indexCode = generateIndexFile(resourceNames);
|
|
507
|
+
const indexPath = `${outputDir}/index.ts`;
|
|
508
|
+
await writeFile(indexPath, indexCode, "utf-8");
|
|
509
|
+
}
|
|
510
|
+
function generateResourceFile(resourceName, routes, options) {
|
|
511
|
+
let code = "";
|
|
512
|
+
code += generateHeader();
|
|
513
|
+
code += `import { client } from '@spfn/core/client';
|
|
514
|
+
`;
|
|
515
|
+
{
|
|
516
|
+
code += `import type { InferContract } from '@spfn/core';
|
|
517
|
+
`;
|
|
518
|
+
}
|
|
519
|
+
code += `
|
|
520
|
+
`;
|
|
521
|
+
const importGroups = groupContractsByImportPath(routes);
|
|
522
|
+
const importPaths = Object.keys(importGroups);
|
|
523
|
+
for (let i = 0; i < importPaths.length; i++) {
|
|
524
|
+
const importPath = importPaths[i];
|
|
525
|
+
const contracts = importGroups[importPath];
|
|
526
|
+
code += `import { ${contracts.join(", ")} } from '${importPath}';
|
|
527
|
+
`;
|
|
528
|
+
}
|
|
529
|
+
code += `
|
|
530
|
+
`;
|
|
531
|
+
{
|
|
532
|
+
code += `// ============================================
|
|
533
|
+
`;
|
|
534
|
+
code += `// Types
|
|
535
|
+
`;
|
|
536
|
+
code += `// ============================================
|
|
537
|
+
|
|
538
|
+
`;
|
|
539
|
+
for (let i = 0; i < routes.length; i++) {
|
|
540
|
+
const route = routes[i];
|
|
541
|
+
const typeName = generateTypeName(route);
|
|
542
|
+
const contractType = `typeof ${route.contractName}`;
|
|
543
|
+
code += `export type ${typeName}Response = InferContract<${contractType}>['response'];
|
|
544
|
+
`;
|
|
545
|
+
if (route.hasQuery) {
|
|
546
|
+
code += `export type ${typeName}Query = InferContract<${contractType}>['query'];
|
|
547
|
+
`;
|
|
548
|
+
}
|
|
549
|
+
if (route.hasParams || route.path.includes(":")) {
|
|
550
|
+
code += `export type ${typeName}Params = InferContract<${contractType}>['params'];
|
|
551
|
+
`;
|
|
552
|
+
}
|
|
553
|
+
if (route.hasBody) {
|
|
554
|
+
code += `export type ${typeName}Body = InferContract<${contractType}>['body'];
|
|
555
|
+
`;
|
|
556
|
+
}
|
|
557
|
+
code += `
|
|
558
|
+
`;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
code += `/**
|
|
562
|
+
`;
|
|
563
|
+
code += ` * ${resourceName} API
|
|
564
|
+
`;
|
|
565
|
+
code += ` */
|
|
566
|
+
`;
|
|
567
|
+
code += `export const ${resourceName} = {
|
|
568
|
+
`;
|
|
569
|
+
for (let i = 0; i < routes.length; i++) {
|
|
570
|
+
const route = routes[i];
|
|
571
|
+
code += generateMethodCode(route, options);
|
|
572
|
+
}
|
|
573
|
+
code += `} as const;
|
|
574
|
+
`;
|
|
575
|
+
return code;
|
|
576
|
+
}
|
|
577
|
+
function generateIndexFile(resourceNames, _options) {
|
|
578
|
+
let code = "";
|
|
579
|
+
code += generateHeader();
|
|
580
|
+
code += `export { client } from '@spfn/core/client';
|
|
581
|
+
|
|
582
|
+
`;
|
|
583
|
+
for (let i = 0; i < resourceNames.length; i++) {
|
|
584
|
+
const resourceName = resourceNames[i];
|
|
585
|
+
code += `export * from './${resourceName}.js';
|
|
586
|
+
`;
|
|
587
|
+
}
|
|
588
|
+
code += `
|
|
589
|
+
`;
|
|
590
|
+
for (let i = 0; i < resourceNames.length; i++) {
|
|
591
|
+
const resourceName = resourceNames[i];
|
|
592
|
+
code += `import { ${resourceName} } from './${resourceName}.js';
|
|
593
|
+
`;
|
|
594
|
+
}
|
|
595
|
+
code += `
|
|
596
|
+
`;
|
|
597
|
+
code += `/**
|
|
598
|
+
`;
|
|
599
|
+
code += ` * Type-safe API client
|
|
600
|
+
`;
|
|
601
|
+
code += ` */
|
|
602
|
+
`;
|
|
603
|
+
code += `export const api = {
|
|
604
|
+
`;
|
|
605
|
+
for (let i = 0; i < resourceNames.length; i++) {
|
|
606
|
+
const resourceName = resourceNames[i];
|
|
607
|
+
code += ` ${resourceName}`;
|
|
608
|
+
if (i < resourceNames.length - 1) {
|
|
609
|
+
code += `,`;
|
|
610
|
+
}
|
|
611
|
+
code += `
|
|
612
|
+
`;
|
|
613
|
+
}
|
|
614
|
+
code += `} as const;
|
|
615
|
+
`;
|
|
616
|
+
return code;
|
|
617
|
+
}
|
|
490
618
|
var PinoAdapter = class _PinoAdapter {
|
|
491
619
|
logger;
|
|
492
620
|
constructor(config) {
|
|
@@ -1281,7 +1409,9 @@ function createContractGenerator(config = {}) {
|
|
|
1281
1409
|
}
|
|
1282
1410
|
const stats = await generateClient(allContracts, {
|
|
1283
1411
|
// For backwards compatibility
|
|
1284
|
-
outputPath
|
|
1412
|
+
outputPath,
|
|
1413
|
+
includeJsDoc: true
|
|
1414
|
+
});
|
|
1285
1415
|
if (options.debug) {
|
|
1286
1416
|
contractLogger.info("Client generated", {
|
|
1287
1417
|
endpoints: stats.methodsGenerated,
|