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