@geekmidas/cli 1.10.27 → 1.10.28
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/CHANGELOG.md +6 -0
- package/dist/index.cjs +13 -57
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +13 -57
- package/dist/index.mjs.map +1 -1
- package/dist/{openapi-BXuCY14q.cjs → openapi-CBU4TEi-.cjs} +23 -130
- package/dist/openapi-CBU4TEi-.cjs.map +1 -0
- package/dist/{openapi-DeG0ffQ8.mjs → openapi-CQCoLuzh.mjs} +24 -113
- package/dist/openapi-CQCoLuzh.mjs.map +1 -0
- package/dist/openapi.cjs +1 -1
- package/dist/openapi.mjs +1 -1
- package/package.json +1 -1
- package/src/dev/index.ts +5 -100
- package/src/init/generators/monorepo.ts +0 -3
- package/src/init/generators/package.ts +1 -4
- package/src/init/generators/web.ts +7 -3
- package/dist/openapi-BXuCY14q.cjs.map +0 -1
- package/dist/openapi-DeG0ffQ8.mjs.map +0 -1
|
@@ -20,7 +20,7 @@ var ConstructGenerator = class {
|
|
|
20
20
|
return generator.build(context, constructs, outputDir, options);
|
|
21
21
|
}
|
|
22
22
|
async load(patterns, cwd = process.cwd(), bustCache = false) {
|
|
23
|
-
const logger
|
|
23
|
+
const logger = console;
|
|
24
24
|
let globPatterns;
|
|
25
25
|
let partitionFn;
|
|
26
26
|
if (isPartitionedRoutes(patterns)) {
|
|
@@ -49,8 +49,8 @@ var ConstructGenerator = class {
|
|
|
49
49
|
});
|
|
50
50
|
} catch (error) {
|
|
51
51
|
const err = error;
|
|
52
|
-
logger
|
|
53
|
-
if (err.stack) logger
|
|
52
|
+
logger.error(`Failed to load ${f}: ${err.message}`);
|
|
53
|
+
if (err.stack) logger.error(err.stack);
|
|
54
54
|
throw error;
|
|
55
55
|
}
|
|
56
56
|
return constructs;
|
|
@@ -646,7 +646,7 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
646
646
|
async build(context, constructs, outputDir, options) {
|
|
647
647
|
const provider = options?.provider || "aws-apigatewayv2";
|
|
648
648
|
const enableOpenApi = options?.enableOpenApi || false;
|
|
649
|
-
const logger
|
|
649
|
+
const logger = console;
|
|
650
650
|
const routes = [];
|
|
651
651
|
if (constructs.length === 0) return routes;
|
|
652
652
|
if (provider === "server") {
|
|
@@ -658,7 +658,7 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
658
658
|
handler: relative(process.cwd(), appFile),
|
|
659
659
|
authorizer: "none"
|
|
660
660
|
});
|
|
661
|
-
logger
|
|
661
|
+
logger.log(`Generated server with ${constructs.length} endpoints${enableOpenApi ? " (OpenAPI enabled)" : ""}`);
|
|
662
662
|
} else if (provider === "aws-lambda") {
|
|
663
663
|
const routesDir = join(outputDir, "routes");
|
|
664
664
|
await mkdir(routesDir, { recursive: true });
|
|
@@ -674,7 +674,7 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
674
674
|
authorizer: construct.authorizer?.name ?? "none"
|
|
675
675
|
};
|
|
676
676
|
routes.push(routeInfo);
|
|
677
|
-
logger
|
|
677
|
+
logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
|
|
678
678
|
}
|
|
679
679
|
} else for (const { key, construct, path } of constructs) {
|
|
680
680
|
const handlerFile = await this.generateHandlerFile(outputDir, path.relative, key, provider, construct, context);
|
|
@@ -688,7 +688,7 @@ var EndpointGenerator = class extends ConstructGenerator {
|
|
|
688
688
|
authorizer: construct.authorizer?.name ?? "none"
|
|
689
689
|
};
|
|
690
690
|
routes.push(routeInfo);
|
|
691
|
-
logger
|
|
691
|
+
logger.log(`Generated handler for ${routeInfo.method} ${routeInfo.path}`);
|
|
692
692
|
}
|
|
693
693
|
return routes;
|
|
694
694
|
}
|
|
@@ -777,7 +777,7 @@ export async function setupEndpoints(
|
|
|
777
777
|
* Generate optimized endpoints files with nested folder structure (per-endpoint files)
|
|
778
778
|
*/
|
|
779
779
|
async generateOptimizedEndpointsFile(endpointsPath, endpoints, _endpointImports, _allExportNames) {
|
|
780
|
-
const logger
|
|
780
|
+
const logger = console;
|
|
781
781
|
const outputDir = dirname(endpointsPath);
|
|
782
782
|
const endpointsDir = join(outputDir, "endpoints");
|
|
783
783
|
await mkdir(join(endpointsDir, "minimal"), { recursive: true });
|
|
@@ -794,11 +794,11 @@ export async function setupEndpoints(
|
|
|
794
794
|
};
|
|
795
795
|
});
|
|
796
796
|
const summary = summarizeAnalysis(analyses);
|
|
797
|
-
logger
|
|
798
|
-
logger
|
|
799
|
-
logger
|
|
800
|
-
logger
|
|
801
|
-
logger
|
|
797
|
+
logger.log(`\n📊 Endpoint Analysis:`);
|
|
798
|
+
logger.log(` Total: ${summary.total} endpoints`);
|
|
799
|
+
logger.log(` - Minimal (near-raw-Hono): ${summary.byTier.minimal} endpoints`);
|
|
800
|
+
logger.log(` - Standard (auth/services): ${summary.byTier.standard} endpoints`);
|
|
801
|
+
logger.log(` - Full (audits/rls/rate-limit): ${summary.byTier.full} endpoints`);
|
|
802
802
|
const files = generateEndpointFilesNested(analyses, endpointImports);
|
|
803
803
|
for (const [filename, content] of Object.entries(files)) {
|
|
804
804
|
const filePath = join(endpointsDir, filename);
|
|
@@ -807,7 +807,7 @@ export async function setupEndpoints(
|
|
|
807
807
|
}
|
|
808
808
|
const endpointFiles = Object.keys(files).filter((f) => !f.endsWith("index.ts") && !f.endsWith("validators.ts")).length;
|
|
809
809
|
const indexFiles = Object.keys(files).filter((f) => f.endsWith("index.ts")).length;
|
|
810
|
-
logger
|
|
810
|
+
logger.log(` Generated ${endpointFiles} endpoint files + ${indexFiles} index files + validators.ts`);
|
|
811
811
|
return join(endpointsDir, "index.ts");
|
|
812
812
|
}
|
|
813
813
|
async generateAppFile(outputDir, context) {
|
|
@@ -1688,7 +1688,6 @@ ${createApiSection}
|
|
|
1688
1688
|
|
|
1689
1689
|
//#endregion
|
|
1690
1690
|
//#region src/workspace/client-generator.ts
|
|
1691
|
-
const logger = console;
|
|
1692
1691
|
/**
|
|
1693
1692
|
* Normalize routes to an array of patterns.
|
|
1694
1693
|
* Handles string, string[], and PartitionedRoutes (extracts paths).
|
|
@@ -1699,94 +1698,6 @@ function normalizeRoutes(routes) {
|
|
|
1699
1698
|
if (isPartitionedRoutes(routes)) return Array.isArray(routes.paths) ? routes.paths : [routes.paths];
|
|
1700
1699
|
return Array.isArray(routes) ? routes : [routes];
|
|
1701
1700
|
}
|
|
1702
|
-
/**
|
|
1703
|
-
* Get frontend apps that depend on a backend app.
|
|
1704
|
-
*/
|
|
1705
|
-
function getDependentFrontends(workspace, backendAppName) {
|
|
1706
|
-
const dependentApps = [];
|
|
1707
|
-
for (const [appName, app] of Object.entries(workspace.apps)) if (app.type === "frontend" && app.dependencies.includes(backendAppName)) dependentApps.push(appName);
|
|
1708
|
-
return dependentApps;
|
|
1709
|
-
}
|
|
1710
|
-
/**
|
|
1711
|
-
* Get the path to a backend's OpenAPI spec file.
|
|
1712
|
-
*/
|
|
1713
|
-
function getBackendOpenApiPath(workspace, backendAppName) {
|
|
1714
|
-
const app = workspace.apps[backendAppName];
|
|
1715
|
-
if (!app || app.type !== "backend") return null;
|
|
1716
|
-
return join(workspace.root, app.path, ".gkm", "openapi.ts");
|
|
1717
|
-
}
|
|
1718
|
-
/**
|
|
1719
|
-
* Count endpoints in an OpenAPI spec content.
|
|
1720
|
-
*/
|
|
1721
|
-
function countEndpoints(content) {
|
|
1722
|
-
const endpointMatches = content.match(/'(GET|POST|PUT|PATCH|DELETE)\s+\/[^']+'/g);
|
|
1723
|
-
return endpointMatches?.length ?? 0;
|
|
1724
|
-
}
|
|
1725
|
-
/**
|
|
1726
|
-
* Copy the OpenAPI client from a backend to all dependent frontend apps.
|
|
1727
|
-
* Called when the backend's .gkm/openapi.ts file changes.
|
|
1728
|
-
*/
|
|
1729
|
-
async function copyClientToFrontends(workspace, backendAppName, options = {}) {
|
|
1730
|
-
const log = options.silent ? () => {} : logger.log.bind(logger);
|
|
1731
|
-
const results = [];
|
|
1732
|
-
const backendApp = workspace.apps[backendAppName];
|
|
1733
|
-
if (!backendApp || backendApp.type !== "backend") return results;
|
|
1734
|
-
const openApiPath = join(workspace.root, backendApp.path, ".gkm", "openapi.ts");
|
|
1735
|
-
if (!existsSync(openApiPath)) return results;
|
|
1736
|
-
const content = await readFile(openApiPath, "utf-8");
|
|
1737
|
-
const endpointCount = countEndpoints(content);
|
|
1738
|
-
const dependentFrontends = getDependentFrontends(workspace, backendAppName);
|
|
1739
|
-
for (const frontendAppName of dependentFrontends) {
|
|
1740
|
-
const frontendApp = workspace.apps[frontendAppName];
|
|
1741
|
-
if (!frontendApp || frontendApp.type !== "frontend") continue;
|
|
1742
|
-
const clientOutput = frontendApp.client?.output;
|
|
1743
|
-
if (!clientOutput) continue;
|
|
1744
|
-
const result = {
|
|
1745
|
-
frontendApp: frontendAppName,
|
|
1746
|
-
backendApp: backendAppName,
|
|
1747
|
-
outputPath: "",
|
|
1748
|
-
endpointCount,
|
|
1749
|
-
success: false
|
|
1750
|
-
};
|
|
1751
|
-
try {
|
|
1752
|
-
const frontendPath = join(workspace.root, frontendApp.path);
|
|
1753
|
-
const outputDir = join(frontendPath, clientOutput);
|
|
1754
|
-
await mkdir(outputDir, { recursive: true });
|
|
1755
|
-
const fileName = `${backendAppName}.ts`;
|
|
1756
|
-
const outputPath = join(outputDir, fileName);
|
|
1757
|
-
const backendRelPath = relative(dirname(outputPath), join(workspace.root, backendApp.path));
|
|
1758
|
-
const clientContent = `/**
|
|
1759
|
-
* Auto-generated API client for ${backendAppName}
|
|
1760
|
-
* Generated from: ${backendRelPath}
|
|
1761
|
-
*
|
|
1762
|
-
* DO NOT EDIT - This file is automatically regenerated when backend schemas change.
|
|
1763
|
-
*/
|
|
1764
|
-
|
|
1765
|
-
${content}
|
|
1766
|
-
`;
|
|
1767
|
-
await writeFile(outputPath, clientContent);
|
|
1768
|
-
result.outputPath = outputPath;
|
|
1769
|
-
result.success = true;
|
|
1770
|
-
log(`📦 Copied client to ${frontendAppName} from ${backendAppName} (${endpointCount} endpoints)`);
|
|
1771
|
-
} catch (error) {
|
|
1772
|
-
result.error = error.message;
|
|
1773
|
-
}
|
|
1774
|
-
results.push(result);
|
|
1775
|
-
}
|
|
1776
|
-
return results;
|
|
1777
|
-
}
|
|
1778
|
-
/**
|
|
1779
|
-
* Copy clients from all backends to their dependent frontends.
|
|
1780
|
-
* Useful for initial setup or force refresh.
|
|
1781
|
-
*/
|
|
1782
|
-
async function copyAllClients(workspace, options = {}) {
|
|
1783
|
-
const allResults = [];
|
|
1784
|
-
for (const [appName, app] of Object.entries(workspace.apps)) if (app.type === "backend" && app.routes) {
|
|
1785
|
-
const results = await copyClientToFrontends(workspace, appName, options);
|
|
1786
|
-
allResults.push(...results);
|
|
1787
|
-
}
|
|
1788
|
-
return allResults;
|
|
1789
|
-
}
|
|
1790
1701
|
|
|
1791
1702
|
//#endregion
|
|
1792
1703
|
//#region src/openapi.ts
|
|
@@ -1817,13 +1728,13 @@ function resolveOpenApiConfig(config) {
|
|
|
1817
1728
|
* @returns Object with output path and endpoint count, or null if disabled
|
|
1818
1729
|
*/
|
|
1819
1730
|
async function generateOpenApi(config, options = {}) {
|
|
1820
|
-
const logger
|
|
1731
|
+
const logger = options.silent ? { log: () => {} } : console;
|
|
1821
1732
|
const openApiConfig = resolveOpenApiConfig(config);
|
|
1822
1733
|
if (!openApiConfig.enabled) return null;
|
|
1823
1734
|
const endpointGenerator = new EndpointGenerator();
|
|
1824
1735
|
const loadedEndpoints = await endpointGenerator.load(config.routes, void 0, options.bustCache);
|
|
1825
1736
|
if (loadedEndpoints.length === 0) {
|
|
1826
|
-
logger
|
|
1737
|
+
logger.log("No valid endpoints found for OpenAPI generation");
|
|
1827
1738
|
return null;
|
|
1828
1739
|
}
|
|
1829
1740
|
const endpoints = loadedEndpoints.map(({ construct }) => construct);
|
|
@@ -1836,27 +1747,27 @@ async function generateOpenApi(config, options = {}) {
|
|
|
1836
1747
|
description: openApiConfig.description
|
|
1837
1748
|
});
|
|
1838
1749
|
await writeFile(outputPath, tsContent);
|
|
1839
|
-
logger
|
|
1750
|
+
logger.log(`📄 OpenAPI client generated: ${OPENAPI_OUTPUT_PATH}`);
|
|
1840
1751
|
return {
|
|
1841
1752
|
outputPath,
|
|
1842
1753
|
endpointCount: loadedEndpoints.length
|
|
1843
1754
|
};
|
|
1844
1755
|
}
|
|
1845
1756
|
async function openapiCommand(options = {}) {
|
|
1846
|
-
const logger
|
|
1757
|
+
const logger = console;
|
|
1847
1758
|
try {
|
|
1848
1759
|
const loadedConfig = await loadWorkspaceConfig(options.cwd);
|
|
1849
1760
|
if (loadedConfig.type === "single") {
|
|
1850
1761
|
const config = loadedConfig.raw;
|
|
1851
1762
|
if (!config.openapi) config.openapi = { enabled: true };
|
|
1852
1763
|
const result = await generateOpenApi(config);
|
|
1853
|
-
if (result) logger
|
|
1764
|
+
if (result) logger.log(`Found ${result.endpointCount} endpoints`);
|
|
1854
1765
|
} else {
|
|
1855
1766
|
const { workspace } = loadedConfig;
|
|
1856
1767
|
const workspaceRoot = options.cwd || process.cwd();
|
|
1857
1768
|
const backendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "backend" && (app.openapi === true || typeof app.openapi === "object" && app.openapi.enabled !== false));
|
|
1858
1769
|
if (backendApps.length === 0) {
|
|
1859
|
-
logger
|
|
1770
|
+
logger.log("No backend apps with OpenAPI enabled found");
|
|
1860
1771
|
return;
|
|
1861
1772
|
}
|
|
1862
1773
|
const frontendApps = Object.entries(workspace.apps).filter(([_, app]) => app.type === "frontend" && app.client?.output);
|
|
@@ -1876,7 +1787,7 @@ async function openapiCommand(options = {}) {
|
|
|
1876
1787
|
const result = await generateOpenApi(gkmConfig, { silent: true });
|
|
1877
1788
|
process.chdir(originalCwd);
|
|
1878
1789
|
if (result) {
|
|
1879
|
-
logger
|
|
1790
|
+
logger.log(`📄 [${appName}] Generated OpenAPI (${result.endpointCount} endpoints)`);
|
|
1880
1791
|
for (const [frontendName, frontendApp] of frontendApps) {
|
|
1881
1792
|
if (frontendApp.type !== "frontend") continue;
|
|
1882
1793
|
const dependsOnBackend = !frontendApp.dependencies || frontendApp.dependencies.includes(appName);
|
|
@@ -1887,7 +1798,7 @@ async function openapiCommand(options = {}) {
|
|
|
1887
1798
|
const { readFile: readFile$1 } = await import("node:fs/promises");
|
|
1888
1799
|
const content = await readFile$1(result.outputPath, "utf-8");
|
|
1889
1800
|
await writeFile(clientOutputPath, content);
|
|
1890
|
-
logger
|
|
1801
|
+
logger.log(` → [${frontendName}] ${frontendApp.client.output}/openapi.ts`);
|
|
1891
1802
|
}
|
|
1892
1803
|
}
|
|
1893
1804
|
}
|
|
@@ -1899,5 +1810,5 @@ async function openapiCommand(options = {}) {
|
|
|
1899
1810
|
}
|
|
1900
1811
|
|
|
1901
1812
|
//#endregion
|
|
1902
|
-
export { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH,
|
|
1903
|
-
//# sourceMappingURL=openapi-
|
|
1813
|
+
export { ConstructGenerator, EndpointGenerator, OPENAPI_OUTPUT_PATH, generateOpenApi, isPartitionedRoutes, normalizeRoutes, openapiCommand, resolveOpenApiConfig };
|
|
1814
|
+
//# sourceMappingURL=openapi-CQCoLuzh.mjs.map
|