@autoview/cli 0.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/LICENSE +661 -0
- package/README.md +407 -0
- package/lib/AutoViewAgent.d.ts +109 -0
- package/lib/AutoViewAgent.js +123 -0
- package/lib/AutoViewAgent.js.map +1 -0
- package/lib/agent/emitMcpServer.d.ts +15 -0
- package/lib/agent/emitMcpServer.js +157 -0
- package/lib/agent/emitMcpServer.js.map +1 -0
- package/lib/agent/emitReport.d.ts +14 -0
- package/lib/agent/emitReport.js +85 -0
- package/lib/agent/emitReport.js.map +1 -0
- package/lib/agent/toolSurface.d.ts +130 -0
- package/lib/agent/toolSurface.js +342 -0
- package/lib/agent/toolSurface.js.map +1 -0
- package/lib/agent/verifyAgentTasks.d.ts +87 -0
- package/lib/agent/verifyAgentTasks.js +126 -0
- package/lib/agent/verifyAgentTasks.js.map +1 -0
- package/lib/cli/main.d.ts +2 -0
- package/lib/cli/main.js +295 -0
- package/lib/cli/main.js.map +1 -0
- package/lib/compiler/AutoViewInterfaceCompiler.d.ts +27 -0
- package/lib/compiler/AutoViewInterfaceCompiler.js +68 -0
- package/lib/compiler/AutoViewInterfaceCompiler.js.map +1 -0
- package/lib/constants/AutoViewFrontendTemplate.d.ts +1 -0
- package/lib/constants/AutoViewFrontendTemplate.js +46 -0
- package/lib/constants/AutoViewFrontendTemplate.js.map +1 -0
- package/lib/constants/AutoViewSystemPromptConstant.d.ts +5 -0
- package/lib/constants/AutoViewSystemPromptConstant.js +4 -0
- package/lib/constants/AutoViewSystemPromptConstant.js.map +1 -0
- package/lib/context/IAutoViewAgentContext.d.ts +60 -0
- package/lib/context/IAutoViewAgentContext.js +3 -0
- package/lib/context/IAutoViewAgentContext.js.map +1 -0
- package/lib/fromSwagger.d.ts +53 -0
- package/lib/fromSwagger.js +513 -0
- package/lib/fromSwagger.js.map +1 -0
- package/lib/generateDeterministic.d.ts +26 -0
- package/lib/generateDeterministic.js +75 -0
- package/lib/generateDeterministic.js.map +1 -0
- package/lib/index.d.ts +15 -0
- package/lib/index.js +41 -0
- package/lib/index.js.map +1 -0
- package/lib/orchestrate/orchestrateAutoView.d.ts +17 -0
- package/lib/orchestrate/orchestrateAutoView.js +491 -0
- package/lib/orchestrate/orchestrateAutoView.js.map +1 -0
- package/lib/orchestrate/orchestrateAutoViewProductPlan.d.ts +37 -0
- package/lib/orchestrate/orchestrateAutoViewProductPlan.js +109 -0
- package/lib/orchestrate/orchestrateAutoViewProductPlan.js.map +1 -0
- package/lib/orchestrate/orchestrateAutoViewRender.d.ts +133 -0
- package/lib/orchestrate/orchestrateAutoViewRender.js +943 -0
- package/lib/orchestrate/orchestrateAutoViewRender.js.map +1 -0
- package/lib/orchestrate/orchestrateAutoViewRenderDeterministic.d.ts +24 -0
- package/lib/orchestrate/orchestrateAutoViewRenderDeterministic.js +92 -0
- package/lib/orchestrate/orchestrateAutoViewRenderDeterministic.js.map +1 -0
- package/lib/orchestrate/orchestrateAutoViewReview.d.ts +48 -0
- package/lib/orchestrate/orchestrateAutoViewReview.js +328 -0
- package/lib/orchestrate/orchestrateAutoViewReview.js.map +1 -0
- package/lib/orchestrate/orchestrateAutoViewScaffold.d.ts +45 -0
- package/lib/orchestrate/orchestrateAutoViewScaffold.js +586 -0
- package/lib/orchestrate/orchestrateAutoViewScaffold.js.map +1 -0
- package/lib/orchestrate/orchestrateAutoViewSdkStudy.d.ts +26 -0
- package/lib/orchestrate/orchestrateAutoViewSdkStudy.js +85 -0
- package/lib/orchestrate/orchestrateAutoViewSdkStudy.js.map +1 -0
- package/lib/orchestrate/structures/IAutoViewProductPlan.d.ts +96 -0
- package/lib/orchestrate/structures/IAutoViewProductPlan.js +3 -0
- package/lib/orchestrate/structures/IAutoViewProductPlan.js.map +1 -0
- package/lib/orchestrate/structures/IAutoViewProductPlanApplication.d.ts +38 -0
- package/lib/orchestrate/structures/IAutoViewProductPlanApplication.js +3 -0
- package/lib/orchestrate/structures/IAutoViewProductPlanApplication.js.map +1 -0
- package/lib/orchestrate/structures/IAutoViewRenderApplication.d.ts +38 -0
- package/lib/orchestrate/structures/IAutoViewRenderApplication.js +3 -0
- package/lib/orchestrate/structures/IAutoViewRenderApplication.js.map +1 -0
- package/lib/orchestrate/structures/IAutoViewReviewApplication.d.ts +40 -0
- package/lib/orchestrate/structures/IAutoViewReviewApplication.js +3 -0
- package/lib/orchestrate/structures/IAutoViewReviewApplication.js.map +1 -0
- package/lib/orchestrate/structures/IAutoViewSdkMap.d.ts +63 -0
- package/lib/orchestrate/structures/IAutoViewSdkMap.js +3 -0
- package/lib/orchestrate/structures/IAutoViewSdkMap.js.map +1 -0
- package/lib/orchestrate/structures/IAutoViewSdkStudyApplication.d.ts +37 -0
- package/lib/orchestrate/structures/IAutoViewSdkStudyApplication.js +3 -0
- package/lib/orchestrate/structures/IAutoViewSdkStudyApplication.js.map +1 -0
- package/lib/orchestrate/utils/HistoryMessage.d.ts +10 -0
- package/lib/orchestrate/utils/HistoryMessage.js +25 -0
- package/lib/orchestrate/utils/HistoryMessage.js.map +1 -0
- package/lib/orchestrate/utils/auditFrontendRuntime.d.ts +53 -0
- package/lib/orchestrate/utils/auditFrontendRuntime.js +362 -0
- package/lib/orchestrate/utils/auditFrontendRuntime.js.map +1 -0
- package/lib/orchestrate/utils/buildDeterministicPlan.d.ts +4 -0
- package/lib/orchestrate/utils/buildDeterministicPlan.js +233 -0
- package/lib/orchestrate/utils/buildDeterministicPlan.js.map +1 -0
- package/lib/orchestrate/utils/buildDeterministicSdkMap.d.ts +22 -0
- package/lib/orchestrate/utils/buildDeterministicSdkMap.js +154 -0
- package/lib/orchestrate/utils/buildDeterministicSdkMap.js.map +1 -0
- package/lib/orchestrate/utils/cacheNodeModules.d.ts +31 -0
- package/lib/orchestrate/utils/cacheNodeModules.js +134 -0
- package/lib/orchestrate/utils/cacheNodeModules.js.map +1 -0
- package/lib/orchestrate/utils/describeEndpointPropsShape.d.ts +37 -0
- package/lib/orchestrate/utils/describeEndpointPropsShape.js +192 -0
- package/lib/orchestrate/utils/describeEndpointPropsShape.js.map +1 -0
- package/lib/orchestrate/utils/describeEndpointRequestBodyShape.d.ts +22 -0
- package/lib/orchestrate/utils/describeEndpointRequestBodyShape.js +29 -0
- package/lib/orchestrate/utils/describeEndpointRequestBodyShape.js.map +1 -0
- package/lib/orchestrate/utils/describeEndpointResponseShape.d.ts +19 -0
- package/lib/orchestrate/utils/describeEndpointResponseShape.js +30 -0
- package/lib/orchestrate/utils/describeEndpointResponseShape.js.map +1 -0
- package/lib/orchestrate/utils/executeCachedBatch.d.ts +22 -0
- package/lib/orchestrate/utils/executeCachedBatch.js +64 -0
- package/lib/orchestrate/utils/executeCachedBatch.js.map +1 -0
- package/lib/orchestrate/utils/loadShoppingFixture.d.ts +33 -0
- package/lib/orchestrate/utils/loadShoppingFixture.js +17 -0
- package/lib/orchestrate/utils/loadShoppingFixture.js.map +1 -0
- package/lib/orchestrate/utils/normalizeProductPlanPaths.d.ts +24 -0
- package/lib/orchestrate/utils/normalizeProductPlanPaths.js +77 -0
- package/lib/orchestrate/utils/normalizeProductPlanPaths.js.map +1 -0
- package/lib/orchestrate/utils/renderJsonSchema.d.ts +23 -0
- package/lib/orchestrate/utils/renderJsonSchema.js +122 -0
- package/lib/orchestrate/utils/renderJsonSchema.js.map +1 -0
- package/lib/orchestrate/utils/renderResourcePage.d.ts +36 -0
- package/lib/orchestrate/utils/renderResourcePage.js +1415 -0
- package/lib/orchestrate/utils/renderResourcePage.js.map +1 -0
- package/lib/orchestrate/utils/validateFrontendTypecheck.d.ts +109 -0
- package/lib/orchestrate/utils/validateFrontendTypecheck.js +274 -0
- package/lib/orchestrate/utils/validateFrontendTypecheck.js.map +1 -0
- package/lib/preview/renderPreview.d.ts +22 -0
- package/lib/preview/renderPreview.js +198 -0
- package/lib/preview/renderPreview.js.map +1 -0
- package/lib/typings/compiler.d.ts +39 -0
- package/lib/typings/compiler.js +3 -0
- package/lib/typings/compiler.js.map +1 -0
- package/lib/typings/events.d.ts +106 -0
- package/lib/typings/events.js +3 -0
- package/lib/typings/events.js.map +1 -0
- package/lib/typings/index.d.ts +10 -0
- package/lib/typings/index.js +27 -0
- package/lib/typings/index.js.map +1 -0
- package/lib/typings/misc.d.ts +78 -0
- package/lib/typings/misc.js +3 -0
- package/lib/typings/misc.js.map +1 -0
- package/lib/utils/ArrayUtil.d.ts +8 -0
- package/lib/utils/ArrayUtil.js +30 -0
- package/lib/utils/ArrayUtil.js.map +1 -0
- package/lib/utils/StringUtil.d.ts +11 -0
- package/lib/utils/StringUtil.js +28 -0
- package/lib/utils/StringUtil.js.map +1 -0
- package/lib/utils/classifyEndpoints.d.ts +62 -0
- package/lib/utils/classifyEndpoints.js +216 -0
- package/lib/utils/classifyEndpoints.js.map +1 -0
- package/lib/utils/endpointFilter.d.ts +26 -0
- package/lib/utils/endpointFilter.js +0 -0
- package/lib/utils/endpointFilter.js.map +1 -0
- package/lib/utils/extractFields.d.ts +85 -0
- package/lib/utils/extractFields.js +231 -0
- package/lib/utils/extractFields.js.map +1 -0
- package/lib/utils/index.d.ts +13 -0
- package/lib/utils/index.js +30 -0
- package/lib/utils/index.js.map +1 -0
- package/lib/utils/normalizeForNestia.d.ts +34 -0
- package/lib/utils/normalizeForNestia.js +133 -0
- package/lib/utils/normalizeForNestia.js.map +1 -0
- package/lib/utils/resourcePlan.d.ts +39 -0
- package/lib/utils/resourcePlan.js +95 -0
- package/lib/utils/resourcePlan.js.map +1 -0
- package/lib/utils/sliceDocument.d.ts +17 -0
- package/lib/utils/sliceDocument.js +114 -0
- package/lib/utils/sliceDocument.js.map +1 -0
- package/lib/utils/toEndpoints.d.ts +90 -0
- package/lib/utils/toEndpoints.js +227 -0
- package/lib/utils/toEndpoints.js.map +1 -0
- package/lib/verify/runWorkflows.d.ts +25 -0
- package/lib/verify/runWorkflows.js +366 -0
- package/lib/verify/runWorkflows.js.map +1 -0
- package/lib/verify/workflows.d.ts +53 -0
- package/lib/verify/workflows.js +107 -0
- package/lib/verify/workflows.js.map +1 -0
- package/package.json +82 -0
- package/prompts/AUTOVIEW_RENDER.md +398 -0
- package/prompts/AUTOVIEW_REVIEW.md +60 -0
- package/prompts/AUTOVIEW_SDK_STUDY.md +89 -0
- package/src/AutoViewAgent.ts +222 -0
- package/src/agent/emitMcpServer.integration.test.ts +168 -0
- package/src/agent/emitMcpServer.test.ts +51 -0
- package/src/agent/emitMcpServer.ts +178 -0
- package/src/agent/emitReport.ts +117 -0
- package/src/agent/toolSurface.test.ts +243 -0
- package/src/agent/toolSurface.ts +501 -0
- package/src/agent/verifyAgentTasks.test.ts +106 -0
- package/src/agent/verifyAgentTasks.ts +171 -0
- package/src/cli/main.ts +363 -0
- package/src/compiler/AutoViewInterfaceCompiler.ts +69 -0
- package/src/constants/AutoViewFrontendTemplate.ts +42 -0
- package/src/constants/AutoViewSystemPromptConstant.ts +6 -0
- package/src/context/IAutoViewAgentContext.ts +84 -0
- package/src/fromSwagger.test.ts +269 -0
- package/src/fromSwagger.ts +500 -0
- package/src/generateDeterministic.test.ts +39 -0
- package/src/generateDeterministic.ts +77 -0
- package/src/index.ts +30 -0
- package/src/orchestrate/orchestrateAutoView.ts +590 -0
- package/src/orchestrate/orchestrateAutoViewProductPlan.ts +121 -0
- package/src/orchestrate/orchestrateAutoViewRender.ts +1117 -0
- package/src/orchestrate/orchestrateAutoViewRenderDeterministic.ts +101 -0
- package/src/orchestrate/orchestrateAutoViewReview.ts +272 -0
- package/src/orchestrate/orchestrateAutoViewScaffold.ts +627 -0
- package/src/orchestrate/orchestrateAutoViewSdkStudy.ts +90 -0
- package/src/orchestrate/renderNavTs.test.ts +74 -0
- package/src/orchestrate/structures/IAutoViewProductPlan.ts +119 -0
- package/src/orchestrate/structures/IAutoViewProductPlanApplication.ts +41 -0
- package/src/orchestrate/structures/IAutoViewRenderApplication.ts +40 -0
- package/src/orchestrate/structures/IAutoViewReviewApplication.ts +42 -0
- package/src/orchestrate/structures/IAutoViewSdkMap.ts +72 -0
- package/src/orchestrate/structures/IAutoViewSdkStudyApplication.ts +40 -0
- package/src/orchestrate/utils/HistoryMessage.ts +41 -0
- package/src/orchestrate/utils/auditFrontendRuntime.test.ts +18 -0
- package/src/orchestrate/utils/auditFrontendRuntime.ts +454 -0
- package/src/orchestrate/utils/buildDeterministicPlan.test.ts +170 -0
- package/src/orchestrate/utils/buildDeterministicPlan.ts +289 -0
- package/src/orchestrate/utils/buildDeterministicSdkMap.test.ts +90 -0
- package/src/orchestrate/utils/buildDeterministicSdkMap.ts +169 -0
- package/src/orchestrate/utils/cacheNodeModules.ts +136 -0
- package/src/orchestrate/utils/describeEndpointPropsShape.test.ts +86 -0
- package/src/orchestrate/utils/describeEndpointPropsShape.ts +202 -0
- package/src/orchestrate/utils/describeEndpointRequestBodyShape.test.ts +87 -0
- package/src/orchestrate/utils/describeEndpointRequestBodyShape.ts +31 -0
- package/src/orchestrate/utils/describeEndpointResponseShape.test.ts +70 -0
- package/src/orchestrate/utils/describeEndpointResponseShape.ts +32 -0
- package/src/orchestrate/utils/executeCachedBatch.ts +59 -0
- package/src/orchestrate/utils/loadShoppingFixture.ts +52 -0
- package/src/orchestrate/utils/normalizeProductPlanPaths.ts +92 -0
- package/src/orchestrate/utils/renderJsonSchema.test.ts +162 -0
- package/src/orchestrate/utils/renderJsonSchema.ts +133 -0
- package/src/orchestrate/utils/renderResourcePage.test.ts +468 -0
- package/src/orchestrate/utils/renderResourcePage.ts +1624 -0
- package/src/orchestrate/utils/validateFrontendTypecheck.test.ts +32 -0
- package/src/orchestrate/utils/validateFrontendTypecheck.ts +335 -0
- package/src/preview/renderPreview.ts +273 -0
- package/src/typings/compiler.ts +47 -0
- package/src/typings/events.ts +155 -0
- package/src/typings/index.ts +10 -0
- package/src/typings/misc.ts +93 -0
- package/src/utils/ArrayUtil.ts +16 -0
- package/src/utils/StringUtil.ts +29 -0
- package/src/utils/classifyEndpoints.test.ts +86 -0
- package/src/utils/classifyEndpoints.ts +291 -0
- package/src/utils/endpointFilter.test.ts +50 -0
- package/src/utils/endpointFilter.ts +0 -0
- package/src/utils/extractFields.test.ts +82 -0
- package/src/utils/extractFields.ts +306 -0
- package/src/utils/index.ts +13 -0
- package/src/utils/normalizeForNestia.test.ts +93 -0
- package/src/utils/normalizeForNestia.ts +139 -0
- package/src/utils/resourcePlan.test.ts +104 -0
- package/src/utils/resourcePlan.ts +180 -0
- package/src/utils/sliceDocument.test.ts +85 -0
- package/src/utils/sliceDocument.ts +119 -0
- package/src/utils/toEndpoints.test.ts +251 -0
- package/src/utils/toEndpoints.ts +343 -0
- package/src/verify/runWorkflows.ts +403 -0
- package/src/verify/workflows.test.ts +117 -0
- package/src/verify/workflows.ts +154 -0
- package/template/CLAUDE.md +140 -0
- package/template/Dockerfile +31 -0
- package/template/PROMPT.md +80 -0
- package/template/SANDBOX.md +70 -0
- package/template/app/api/health/route.ts +10 -0
- package/template/app/globals.css +97 -0
- package/template/app/layout.tsx +30 -0
- package/template/app/page.tsx +19 -0
- package/template/components/AppShell.tsx +114 -0
- package/template/components/auto/CatalogGrid.tsx +159 -0
- package/template/components/auto/ConfirmButton.tsx +67 -0
- package/template/components/auto/EmbeddedCollection.tsx +144 -0
- package/template/components/auto/ResourceDashboard.tsx +104 -0
- package/template/components/auto/ResourceDetail.tsx +93 -0
- package/template/components/auto/ResourceForm.tsx +235 -0
- package/template/components/auto/ResourceIcon.tsx +88 -0
- package/template/components/auto/ResourceLanding.tsx +155 -0
- package/template/components/auto/ResourceTable.tsx +223 -0
- package/template/components/auto/formatValue.tsx +186 -0
- package/template/components/auto/types.ts +42 -0
- package/template/components/ui/badge.tsx +40 -0
- package/template/components/ui/button.tsx +57 -0
- package/template/components/ui/card.tsx +86 -0
- package/template/components/ui/dialog.tsx +119 -0
- package/template/components/ui/input.tsx +23 -0
- package/template/components/ui/label.tsx +24 -0
- package/template/components/ui/pagination.tsx +117 -0
- package/template/components/ui/select.tsx +92 -0
- package/template/components/ui/sheet.tsx +135 -0
- package/template/components/ui/skeleton.tsx +15 -0
- package/template/components/ui/table.tsx +120 -0
- package/template/components/ui/tabs.tsx +55 -0
- package/template/lib/utils.ts +35 -0
- package/template/next.config.mjs +52 -0
- package/template/package.json +46 -0
- package/template/postcss.config.js +6 -0
- package/template/scripts/start-shopping-backend.sh +56 -0
- package/template/tailwind.config.ts +96 -0
- package/template/tsconfig.json +29 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained replacements for the `@autobe/utils` surface this package
|
|
3
|
+
* uses. Migrated 2026-06-01 as Step 2 of the AutoBE-independence track — the
|
|
4
|
+
* underlying conversions still rely on the typia / nestia ecosystem
|
|
5
|
+
* (`@typia/utils`, `@typia/interface`), which are not AutoBE packages.
|
|
6
|
+
*/
|
|
7
|
+
export * from "./StringUtil";
|
|
8
|
+
export * from "./ArrayUtil";
|
|
9
|
+
export * from "./toEndpoints";
|
|
10
|
+
export * from "./classifyEndpoints";
|
|
11
|
+
export * from "./endpointFilter";
|
|
12
|
+
export * from "./extractFields";
|
|
13
|
+
export * from "./resourcePlan";
|
|
@@ -0,0 +1,30 @@
|
|
|
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* Self-contained replacements for the `@autobe/utils` surface this package
|
|
19
|
+
* uses. Migrated 2026-06-01 as Step 2 of the AutoBE-independence track — the
|
|
20
|
+
* underlying conversions still rely on the typia / nestia ecosystem
|
|
21
|
+
* (`@typia/utils`, `@typia/interface`), which are not AutoBE packages.
|
|
22
|
+
*/
|
|
23
|
+
__exportStar(require("./StringUtil"), exports);
|
|
24
|
+
__exportStar(require("./ArrayUtil"), exports);
|
|
25
|
+
__exportStar(require("./toEndpoints"), exports);
|
|
26
|
+
__exportStar(require("./classifyEndpoints"), exports);
|
|
27
|
+
__exportStar(require("./endpointFilter"), exports);
|
|
28
|
+
__exportStar(require("./extractFields"), exports);
|
|
29
|
+
__exportStar(require("./resourcePlan"), exports);
|
|
30
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;;;GAKG;AACH,+CAA6B;AAC7B,8CAA4B;AAC5B,gDAA8B;AAC9B,sDAAoC;AACpC,mDAAiC;AACjC,kDAAgC;AAChC,iDAA+B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { OpenApi } from "@typia/interface";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a real-world OpenAPI document so nestia (`HttpMigration` and
|
|
4
|
+
* `@nestia/migrate`) can turn EVERY operation into a compilable typed route.
|
|
5
|
+
* Real swaggers carry shapes that nestia faithfully reproduces but its own typed
|
|
6
|
+
* fetcher then rejects (or refuses to emit), silently dropping screens and SDK
|
|
7
|
+
* functions. This pass rewrites only those shapes — additively, never removing a
|
|
8
|
+
* route that already worked — and is applied identically by the READ layer
|
|
9
|
+
* (`toEndpoints`) and the SDK compiler so the screen plan and the SDK stay in
|
|
10
|
+
* lockstep.
|
|
11
|
+
*
|
|
12
|
+
* Two corrections, both seen in the wild:
|
|
13
|
+
*
|
|
14
|
+
* 1. **Multi-object query → dropped route.** nestia drops an entire route when
|
|
15
|
+
* its query has more than one object-typed parameter
|
|
16
|
+
* (`query typed parameters must be only one object type`). Apideck's
|
|
17
|
+
* `GET /accounting/invoices` carries `filter`, `sort` AND `pass_through`
|
|
18
|
+
* objects — the very list that produces ids for navigation. We keep only the
|
|
19
|
+
* first object-typed query param; AutoView rebuilds the complete query from
|
|
20
|
+
* the untouched original document (`buildQuerySchema`) and the list page
|
|
21
|
+
* casts its query argument, so nothing the UI sees is lost.
|
|
22
|
+
*
|
|
23
|
+
* 2. **Body on a GET/HEAD → uncompilable SDK.** Notion's `GET /v1/comments` and
|
|
24
|
+
* `GET /v1/users/{id}` declare an `application/x-www-form-urlencoded`
|
|
25
|
+
* requestBody. A body on GET/HEAD is invalid HTTP; nestia still emits a GET
|
|
26
|
+
* SDK function carrying a request body, which its fetcher (body only on
|
|
27
|
+
* DELETE/POST/PUT/PATCH) rejects — a hard type error that also leaves those
|
|
28
|
+
* pages empty at runtime. We strip the requestBody from GET/HEAD operations.
|
|
29
|
+
*
|
|
30
|
+
* Pure: the input document is never mutated. Only operations that actually need
|
|
31
|
+
* a correction are rebuilt; everything else is shared by reference, and a
|
|
32
|
+
* document needing no correction is returned as-is (same reference).
|
|
33
|
+
*/
|
|
34
|
+
export declare function normalizeForNestia(document: OpenApi.IDocument): OpenApi.IDocument;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.normalizeForNestia = normalizeForNestia;
|
|
15
|
+
const utils_1 = require("@typia/utils");
|
|
16
|
+
/**
|
|
17
|
+
* Normalize a real-world OpenAPI document so nestia (`HttpMigration` and
|
|
18
|
+
* `@nestia/migrate`) can turn EVERY operation into a compilable typed route.
|
|
19
|
+
* Real swaggers carry shapes that nestia faithfully reproduces but its own typed
|
|
20
|
+
* fetcher then rejects (or refuses to emit), silently dropping screens and SDK
|
|
21
|
+
* functions. This pass rewrites only those shapes — additively, never removing a
|
|
22
|
+
* route that already worked — and is applied identically by the READ layer
|
|
23
|
+
* (`toEndpoints`) and the SDK compiler so the screen plan and the SDK stay in
|
|
24
|
+
* lockstep.
|
|
25
|
+
*
|
|
26
|
+
* Two corrections, both seen in the wild:
|
|
27
|
+
*
|
|
28
|
+
* 1. **Multi-object query → dropped route.** nestia drops an entire route when
|
|
29
|
+
* its query has more than one object-typed parameter
|
|
30
|
+
* (`query typed parameters must be only one object type`). Apideck's
|
|
31
|
+
* `GET /accounting/invoices` carries `filter`, `sort` AND `pass_through`
|
|
32
|
+
* objects — the very list that produces ids for navigation. We keep only the
|
|
33
|
+
* first object-typed query param; AutoView rebuilds the complete query from
|
|
34
|
+
* the untouched original document (`buildQuerySchema`) and the list page
|
|
35
|
+
* casts its query argument, so nothing the UI sees is lost.
|
|
36
|
+
*
|
|
37
|
+
* 2. **Body on a GET/HEAD → uncompilable SDK.** Notion's `GET /v1/comments` and
|
|
38
|
+
* `GET /v1/users/{id}` declare an `application/x-www-form-urlencoded`
|
|
39
|
+
* requestBody. A body on GET/HEAD is invalid HTTP; nestia still emits a GET
|
|
40
|
+
* SDK function carrying a request body, which its fetcher (body only on
|
|
41
|
+
* DELETE/POST/PUT/PATCH) rejects — a hard type error that also leaves those
|
|
42
|
+
* pages empty at runtime. We strip the requestBody from GET/HEAD operations.
|
|
43
|
+
*
|
|
44
|
+
* Pure: the input document is never mutated. Only operations that actually need
|
|
45
|
+
* a correction are rebuilt; everything else is shared by reference, and a
|
|
46
|
+
* document needing no correction is returned as-is (same reference).
|
|
47
|
+
*/
|
|
48
|
+
function normalizeForNestia(document) {
|
|
49
|
+
var _a;
|
|
50
|
+
const paths = (_a = document.paths) !== null && _a !== void 0 ? _a : {};
|
|
51
|
+
let changed = false;
|
|
52
|
+
const nextPaths = {};
|
|
53
|
+
for (const [path, item] of Object.entries(paths)) {
|
|
54
|
+
const relaxed = normalizePathItem(item, document);
|
|
55
|
+
nextPaths[path] = relaxed.item;
|
|
56
|
+
changed = changed || relaxed.changed;
|
|
57
|
+
}
|
|
58
|
+
if (!changed)
|
|
59
|
+
return document;
|
|
60
|
+
// biome-ignore lint: structurally an OpenApi.IDocument with a rebuilt paths map
|
|
61
|
+
return Object.assign(Object.assign({}, document), { paths: nextPaths });
|
|
62
|
+
}
|
|
63
|
+
const HTTP_METHODS = ["get", "post", "put", "patch", "delete", "head"];
|
|
64
|
+
/** HTTP methods whose request body nestia's typed fetcher cannot carry. */
|
|
65
|
+
const BODYLESS_METHODS = new Set(["get", "head"]);
|
|
66
|
+
function normalizePathItem(item, document) {
|
|
67
|
+
let changed = false;
|
|
68
|
+
const next = Object.assign({}, item);
|
|
69
|
+
for (const method of HTTP_METHODS) {
|
|
70
|
+
const op = item[method];
|
|
71
|
+
if (op === undefined)
|
|
72
|
+
continue;
|
|
73
|
+
const normalized = normalizeOperation(op, method, document);
|
|
74
|
+
if (normalized !== op) {
|
|
75
|
+
next[method] = normalized;
|
|
76
|
+
changed = true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return changed ? { item: next, changed } : { item, changed: false };
|
|
80
|
+
}
|
|
81
|
+
function normalizeOperation(operation, method, document) {
|
|
82
|
+
let next = operation;
|
|
83
|
+
next = stripBodyFromBodylessMethod(next, method);
|
|
84
|
+
next = relaxMultiObjectQuery(next, document);
|
|
85
|
+
return next;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Remove the requestBody from a GET/HEAD operation — a body is invalid there and
|
|
89
|
+
* makes nestia emit an SDK function its own fetcher rejects.
|
|
90
|
+
*/
|
|
91
|
+
function stripBodyFromBodylessMethod(operation, method) {
|
|
92
|
+
if (!BODYLESS_METHODS.has(method))
|
|
93
|
+
return operation;
|
|
94
|
+
if (operation.requestBody === undefined)
|
|
95
|
+
return operation;
|
|
96
|
+
const _a = operation, { requestBody: _dropped } = _a, rest = __rest(_a, ["requestBody"]);
|
|
97
|
+
return rest;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Keep only the first object-typed query parameter, or return the operation
|
|
101
|
+
* unchanged when it has ≤1 such param.
|
|
102
|
+
*/
|
|
103
|
+
function relaxMultiObjectQuery(operation, document) {
|
|
104
|
+
const params = operation.parameters;
|
|
105
|
+
if (!Array.isArray(params))
|
|
106
|
+
return operation;
|
|
107
|
+
const objectQueryIndexes = params
|
|
108
|
+
.map((p, i) => p.in === "query" && isObjectQuerySchema(p.schema, document) ? i : -1)
|
|
109
|
+
.filter((i) => i >= 0);
|
|
110
|
+
if (objectQueryIndexes.length <= 1)
|
|
111
|
+
return operation;
|
|
112
|
+
const drop = new Set(objectQueryIndexes.slice(1));
|
|
113
|
+
return Object.assign(Object.assign({}, operation), { parameters: params.filter((_, i) => !drop.has(i)) });
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Mirror of the composer's object test (HttpMigrateRouteComposer): a query param
|
|
117
|
+
* counts as an "object" when its schema is an object, or a `$ref` to a component
|
|
118
|
+
* schema that is an object.
|
|
119
|
+
*/
|
|
120
|
+
function isObjectQuerySchema(schema, document) {
|
|
121
|
+
var _a, _b, _c;
|
|
122
|
+
if (schema === undefined)
|
|
123
|
+
return false;
|
|
124
|
+
if (utils_1.OpenApiTypeChecker.isObject(schema))
|
|
125
|
+
return true;
|
|
126
|
+
if (utils_1.OpenApiTypeChecker.isReference(schema)) {
|
|
127
|
+
const name = (_a = schema.$ref.split("/").pop()) !== null && _a !== void 0 ? _a : "";
|
|
128
|
+
const target = ((_c = (_b = document.components) === null || _b === void 0 ? void 0 : _b.schemas) !== null && _c !== void 0 ? _c : {})[name];
|
|
129
|
+
return target !== undefined && utils_1.OpenApiTypeChecker.isObject(target);
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=normalizeForNestia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalizeForNestia.js","sourceRoot":"","sources":["../../src/utils/normalizeForNestia.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { OpenApi } from "@typia/interface";
|
|
2
|
+
import { IClassifiedEndpoint, IResourceGroup } from "./classifyEndpoints";
|
|
3
|
+
import { IAutoViewEndpoint } from "./toEndpoints";
|
|
4
|
+
/**
|
|
5
|
+
* Deterministic information architecture — the second brick of the "정확한 틀".
|
|
6
|
+
*
|
|
7
|
+
* Turns the classified resource groups into a concrete, reproducible screen
|
|
8
|
+
* set: for each resource, exactly the screens its CRUD roles justify, with real
|
|
9
|
+
* Next.js paths and the endpoints each screen composes. No LLM, no commerce
|
|
10
|
+
* baseline, no "5-25 screens, compose, don't enumerate" guesswork — every
|
|
11
|
+
* resource that exposes a capability gets the corresponding screen, and
|
|
12
|
+
* nothing more.
|
|
13
|
+
*
|
|
14
|
+
* This is what replaces the LLM ProductPlan's IShop-flavored improvisation:
|
|
15
|
+
* the Render phase later fills these slots with TSX, but the SET of screens is
|
|
16
|
+
* decided here, structurally.
|
|
17
|
+
*/
|
|
18
|
+
export type ScreenKind = "list" | "detail" | "create" | "edit";
|
|
19
|
+
export interface IPlannedScreen {
|
|
20
|
+
/** Next.js App Router path, dynamic segments in `[brackets]`. */
|
|
21
|
+
path: string;
|
|
22
|
+
resource: string;
|
|
23
|
+
kind: ScreenKind;
|
|
24
|
+
/** Hierarchy depth: 1 = top-level resource, ≥2 = nested under a parent. */
|
|
25
|
+
depth: number;
|
|
26
|
+
/** Parent collection path (`/sales/[saleId]`) for a nested resource, else null. */
|
|
27
|
+
parentPath: string | null;
|
|
28
|
+
title: string;
|
|
29
|
+
/** Primary data-source / target endpoint for the screen. */
|
|
30
|
+
primary: IAutoViewEndpoint;
|
|
31
|
+
/**
|
|
32
|
+
* Secondary endpoints the screen wires in — e.g. a detail screen surfaces
|
|
33
|
+
* its update / delete / action endpoints as buttons; a list screen links to
|
|
34
|
+
* detail. Empty for create.
|
|
35
|
+
*/
|
|
36
|
+
secondary: IClassifiedEndpoint[];
|
|
37
|
+
}
|
|
38
|
+
export declare function planResource(group: IResourceGroup): IPlannedScreen[];
|
|
39
|
+
export declare function resourcePlan(endpoints: IAutoViewEndpoint[], document?: OpenApi.IDocument): IPlannedScreen[];
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.planResource = planResource;
|
|
4
|
+
exports.resourcePlan = resourcePlan;
|
|
5
|
+
const classifyEndpoints_1 = require("./classifyEndpoints");
|
|
6
|
+
function pick(group, role) {
|
|
7
|
+
return group.endpoints.filter((c) => c.role === role);
|
|
8
|
+
}
|
|
9
|
+
function titleize(resource) {
|
|
10
|
+
const spaced = resource.replace(/[_-]+/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2");
|
|
11
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Canonical route param name for a resource: `<name>Id`. Derived from the
|
|
15
|
+
* resource NAME (not the endpoint's param), so it is identical everywhere the
|
|
16
|
+
* resource appears (its own detail and as a parent of a sub-resource) and
|
|
17
|
+
* distinct from every other resource's param. This guarantees a route never has
|
|
18
|
+
* a sibling-slug conflict (`/sales/[id]` vs `/sales/[saleId]`) nor a repeated
|
|
19
|
+
* slug within one path (`/sales/[id]/questions/[id]`) — both of which Next.js
|
|
20
|
+
* rejects at boot. The SDK's own param names are recovered separately by
|
|
21
|
+
* position when the page issues its fetch.
|
|
22
|
+
*/
|
|
23
|
+
function canonParam(name) {
|
|
24
|
+
return `${name.replace(/[^A-Za-z0-9]/g, "")}Id`;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The collection route for a resource group, mirroring the swagger hierarchy:
|
|
28
|
+
* every parent link contributes `<name>/[<canonParam>]`, the leaf its bare name.
|
|
29
|
+
* `[sales, questions]` → `/sales/[salesId]/questions`. `[sales]` → `/sales`.
|
|
30
|
+
*/
|
|
31
|
+
/** A parent link's route part: `sales/[salesId]` when item-addressed, else just
|
|
32
|
+
* `coupons` (a path prefix with no `{param}`, so no bracket). */
|
|
33
|
+
function parentPart(link) {
|
|
34
|
+
return link.param !== null ? `${link.name}/[${canonParam(link.name)}]` : link.name;
|
|
35
|
+
}
|
|
36
|
+
function collectionPath(group) {
|
|
37
|
+
const links = group.chain;
|
|
38
|
+
const parts = links.map((c, i) => (i < links.length - 1 ? parentPart(c) : c.name));
|
|
39
|
+
return `/${parts.join("/")}`;
|
|
40
|
+
}
|
|
41
|
+
/** The parent collection path (`/sales/[salesId]`) for a nested group, else null. */
|
|
42
|
+
function parentPathOf(group) {
|
|
43
|
+
if (group.chain.length < 2)
|
|
44
|
+
return null;
|
|
45
|
+
const parents = group.chain.slice(0, -1);
|
|
46
|
+
return `/${parents.map(parentPart).join("/")}`;
|
|
47
|
+
}
|
|
48
|
+
/** Item route param for a group's own entity (`/sales` → `[salesId]`). */
|
|
49
|
+
function itemParam(group) {
|
|
50
|
+
return canonParam(group.resource);
|
|
51
|
+
}
|
|
52
|
+
function planResource(group) {
|
|
53
|
+
const screens = [];
|
|
54
|
+
const resource = group.resource;
|
|
55
|
+
const label = titleize(resource);
|
|
56
|
+
const depth = group.chain.length;
|
|
57
|
+
const parentPath = parentPathOf(group);
|
|
58
|
+
const base = collectionPath(group);
|
|
59
|
+
const common = { resource, depth, parentPath };
|
|
60
|
+
// Prefer the top-level enumeration as the resource's primary list: the real
|
|
61
|
+
// `/v2/droplets` (no path params) over an id-scoped sub-view that happens to
|
|
62
|
+
// classify as a list (`/v2/droplets/{id}/destroy_with_associated_resources`),
|
|
63
|
+
// whose response is NOT the resource's own rows. Fewest path params wins;
|
|
64
|
+
// stable otherwise (list before search at equal depth).
|
|
65
|
+
const listish = [...pick(group, "list"), ...pick(group, "search")].sort((a, b) => a.endpoint.parameters.length - b.endpoint.parameters.length);
|
|
66
|
+
const details = pick(group, "detail");
|
|
67
|
+
const creates = pick(group, "create");
|
|
68
|
+
const updates = pick(group, "update");
|
|
69
|
+
const deletes = pick(group, "delete");
|
|
70
|
+
const actions = pick(group, "action");
|
|
71
|
+
// List / search screen — the resource's home.
|
|
72
|
+
if (listish.length > 0) {
|
|
73
|
+
screens.push(Object.assign(Object.assign({}, common), { path: base, kind: "list", title: label, primary: listish[0].endpoint,
|
|
74
|
+
// extra search variants + the row-action targets (detail/delete) the
|
|
75
|
+
// list links to.
|
|
76
|
+
secondary: [...listish.slice(1), ...details, ...deletes] }));
|
|
77
|
+
}
|
|
78
|
+
// Detail screen — one entity. Hosts update/delete/action as buttons.
|
|
79
|
+
if (details.length > 0) {
|
|
80
|
+
screens.push(Object.assign(Object.assign({}, common), { path: `${base}/[${itemParam(group)}]`, kind: "detail", title: `${label} detail`, primary: details[0].endpoint, secondary: [...updates, ...deletes, ...actions] }));
|
|
81
|
+
}
|
|
82
|
+
// Create screen — a form from the POST requestBody schema.
|
|
83
|
+
if (creates.length > 0) {
|
|
84
|
+
screens.push(Object.assign(Object.assign({}, common), { path: `${base}/new`, kind: "create", title: `New ${label.toLowerCase()}`, primary: creates[0].endpoint, secondary: [] }));
|
|
85
|
+
}
|
|
86
|
+
// Edit screen — a form from the PUT/PATCH requestBody, prefilled by detail.
|
|
87
|
+
if (updates.length > 0) {
|
|
88
|
+
screens.push(Object.assign(Object.assign({}, common), { path: `${base}/[${itemParam(group)}]/edit`, kind: "edit", title: `Edit ${label.toLowerCase()}`, primary: updates[0].endpoint, secondary: details }));
|
|
89
|
+
}
|
|
90
|
+
return screens;
|
|
91
|
+
}
|
|
92
|
+
function resourcePlan(endpoints, document) {
|
|
93
|
+
return (0, classifyEndpoints_1.classifyEndpoints)(endpoints, document).flatMap(planResource);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=resourcePlan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resourcePlan.js","sourceRoot":"","sources":["../../src/utils/resourcePlan.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { OpenApi } from "@typia/interface";
|
|
2
|
+
import { IEndpointFilter } from "./endpointFilter";
|
|
3
|
+
/**
|
|
4
|
+
* Slice an OpenAPI document down to an operator-selected surface — the fix for
|
|
5
|
+
* "`--include` only trims the endpoint list, but the SDK Study still compiles
|
|
6
|
+
* the WHOLE document and overflows the model's context on a large swagger".
|
|
7
|
+
*
|
|
8
|
+
* {@link filterEndpoints} answers *which screens*; this answers *which document*.
|
|
9
|
+
* It keeps only the filtered paths/methods AND prunes `components.schemas` to
|
|
10
|
+
* the transitive closure those operations actually reference, so every
|
|
11
|
+
* downstream phase (SDK Study, Product Plan, Render) sees a document whose size
|
|
12
|
+
* matches the requested slice — not the original 300-type spec.
|
|
13
|
+
*
|
|
14
|
+
* Pure: returns a new document; the input is never mutated. A no-op filter
|
|
15
|
+
* returns an equivalent document (schemas reachable from all operations).
|
|
16
|
+
*/
|
|
17
|
+
export declare function sliceDocument(document: OpenApi.IDocument, filter?: IEndpointFilter): OpenApi.IDocument;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sliceDocument = sliceDocument;
|
|
4
|
+
const endpointFilter_1 = require("./endpointFilter");
|
|
5
|
+
const toEndpoints_1 = require("./toEndpoints");
|
|
6
|
+
/**
|
|
7
|
+
* Slice an OpenAPI document down to an operator-selected surface — the fix for
|
|
8
|
+
* "`--include` only trims the endpoint list, but the SDK Study still compiles
|
|
9
|
+
* the WHOLE document and overflows the model's context on a large swagger".
|
|
10
|
+
*
|
|
11
|
+
* {@link filterEndpoints} answers *which screens*; this answers *which document*.
|
|
12
|
+
* It keeps only the filtered paths/methods AND prunes `components.schemas` to
|
|
13
|
+
* the transitive closure those operations actually reference, so every
|
|
14
|
+
* downstream phase (SDK Study, Product Plan, Render) sees a document whose size
|
|
15
|
+
* matches the requested slice — not the original 300-type spec.
|
|
16
|
+
*
|
|
17
|
+
* Pure: returns a new document; the input is never mutated. A no-op filter
|
|
18
|
+
* returns an equivalent document (schemas reachable from all operations).
|
|
19
|
+
*/
|
|
20
|
+
function sliceDocument(document, filter = {}) {
|
|
21
|
+
var _a, _b, _c;
|
|
22
|
+
const kept = new Set((0, endpointFilter_1.filterEndpoints)((0, toEndpoints_1.toEndpoints)(document), filter).map((e) => `${e.method.toLowerCase()} ${e.path}`));
|
|
23
|
+
// Rebuild paths, keeping only the (method, path) pairs that survived the
|
|
24
|
+
// filter. A path with no surviving method is dropped entirely.
|
|
25
|
+
const paths = {};
|
|
26
|
+
for (const [path, item] of Object.entries((_a = document.paths) !== null && _a !== void 0 ? _a : {})) {
|
|
27
|
+
if (item === undefined)
|
|
28
|
+
continue;
|
|
29
|
+
const keptItem = {};
|
|
30
|
+
for (const [key, value] of Object.entries(item)) {
|
|
31
|
+
// Non-method members of a path item (parameters, $ref, summary…) are
|
|
32
|
+
// carried over only when at least one method on the path survives.
|
|
33
|
+
if (!HTTP_METHODS.has(key.toLowerCase()))
|
|
34
|
+
continue;
|
|
35
|
+
if (kept.has(`${key.toLowerCase()} ${path}`))
|
|
36
|
+
keptItem[key] = value;
|
|
37
|
+
}
|
|
38
|
+
if (Object.keys(keptItem).length === 0)
|
|
39
|
+
continue;
|
|
40
|
+
for (const [key, value] of Object.entries(item)) {
|
|
41
|
+
if (!HTTP_METHODS.has(key.toLowerCase()))
|
|
42
|
+
keptItem[key] = value;
|
|
43
|
+
}
|
|
44
|
+
paths[path] = keptItem;
|
|
45
|
+
}
|
|
46
|
+
// Compute the transitive schema closure reachable from the kept operations.
|
|
47
|
+
const allSchemas = (_c = (_b = document.components) === null || _b === void 0 ? void 0 : _b.schemas) !== null && _c !== void 0 ? _c : {};
|
|
48
|
+
const reachable = new Set();
|
|
49
|
+
const frontier = [];
|
|
50
|
+
const seed = (schema) => {
|
|
51
|
+
for (const name of collectRefs(schema)) {
|
|
52
|
+
if (!reachable.has(name)) {
|
|
53
|
+
reachable.add(name);
|
|
54
|
+
frontier.push(name);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
for (const item of Object.values(paths)) {
|
|
59
|
+
for (const [key, op] of Object.entries(item !== null && item !== void 0 ? item : {})) {
|
|
60
|
+
if (!HTTP_METHODS.has(key.toLowerCase()))
|
|
61
|
+
continue;
|
|
62
|
+
seed(op);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
while (frontier.length > 0) {
|
|
66
|
+
const name = frontier.pop();
|
|
67
|
+
seed(allSchemas[name]);
|
|
68
|
+
}
|
|
69
|
+
const schemas = {};
|
|
70
|
+
for (const name of reachable) {
|
|
71
|
+
const schema = allSchemas[name];
|
|
72
|
+
if (schema !== undefined)
|
|
73
|
+
schemas[name] = schema;
|
|
74
|
+
}
|
|
75
|
+
return Object.assign(Object.assign({}, document), { paths, components: Object.assign(Object.assign({}, document.components), { schemas }) });
|
|
76
|
+
}
|
|
77
|
+
const HTTP_METHODS = new Set([
|
|
78
|
+
"get",
|
|
79
|
+
"post",
|
|
80
|
+
"put",
|
|
81
|
+
"patch",
|
|
82
|
+
"delete",
|
|
83
|
+
"head",
|
|
84
|
+
"options",
|
|
85
|
+
"trace",
|
|
86
|
+
]);
|
|
87
|
+
/**
|
|
88
|
+
* Every component name a JSON value references via `$ref`, found by walking the
|
|
89
|
+
* whole subtree (properties, items, allOf/oneOf/anyOf, additionalProperties,
|
|
90
|
+
* and arbitrarily nested objects/arrays). Returns bare names (`Sale`), not
|
|
91
|
+
* pointers.
|
|
92
|
+
*/
|
|
93
|
+
function collectRefs(value) {
|
|
94
|
+
const out = [];
|
|
95
|
+
const walk = (node) => {
|
|
96
|
+
if (node === null || typeof node !== "object")
|
|
97
|
+
return;
|
|
98
|
+
if (Array.isArray(node)) {
|
|
99
|
+
for (const child of node)
|
|
100
|
+
walk(child);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const obj = node;
|
|
104
|
+
const ref = obj.$ref;
|
|
105
|
+
if (typeof ref === "string" && ref.startsWith("#/components/schemas/")) {
|
|
106
|
+
out.push(ref.slice("#/components/schemas/".length));
|
|
107
|
+
}
|
|
108
|
+
for (const child of Object.values(obj))
|
|
109
|
+
walk(child);
|
|
110
|
+
};
|
|
111
|
+
walk(value);
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=sliceDocument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sliceDocument.js","sourceRoot":"","sources":["../../src/utils/sliceDocument.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { OpenApi } from "@typia/interface";
|
|
2
|
+
/**
|
|
3
|
+
* Swagger-native endpoint model — Step toward "swagger만 읽고 정확하게".
|
|
4
|
+
*
|
|
5
|
+
* Built directly from nestia's `HttpMigration.application(doc).routes`, the
|
|
6
|
+
* single source of truth that already carries accessor + query + path params +
|
|
7
|
+
* body + response for EVERY operation. Replaces the former
|
|
8
|
+
* `invertOpenApiDocument`, whose `r.query === null` filter silently dropped
|
|
9
|
+
* every query-string endpoint (search / filter / pagination) — see the bug
|
|
10
|
+
* this migration fixes.
|
|
11
|
+
*
|
|
12
|
+
* Shape mirrors the former endpoint model so the orchestrators change minimally
|
|
13
|
+
* (`document.operations` → `toEndpoints(document)`), plus the one field the old
|
|
14
|
+
* model could not express: {@link IAutoViewEndpoint.query}.
|
|
15
|
+
*
|
|
16
|
+
* Schemas are typed as `OpenApi.IJsonSchema` purely for structural reuse
|
|
17
|
+
* — at runtime they ARE standard OpenAPI schemas (the old invert did the same
|
|
18
|
+
* `as any` cast), so the existing `describeEndpoint*` / `renderJsonSchema`
|
|
19
|
+
* helpers keep working unchanged.
|
|
20
|
+
*/
|
|
21
|
+
export interface IAutoViewEndpoint {
|
|
22
|
+
method: string;
|
|
23
|
+
path: string;
|
|
24
|
+
/** SDK function path nestia assigns, e.g. `["items","search","get"]`. */
|
|
25
|
+
accessor: string[];
|
|
26
|
+
/** Last accessor segment — the SDK function name. */
|
|
27
|
+
name: string;
|
|
28
|
+
/** Human description (summary + description merged). */
|
|
29
|
+
description: string;
|
|
30
|
+
/** Path parameters (primitive). */
|
|
31
|
+
parameters: IAutoViewEndpoint.IParameter[];
|
|
32
|
+
/**
|
|
33
|
+
* Query-string schema as a single object, or `null` when the endpoint has no
|
|
34
|
+
* query. THIS is what the old AutoBE model could not hold.
|
|
35
|
+
*/
|
|
36
|
+
query: OpenApi.IJsonSchema | null;
|
|
37
|
+
/** Request body reference, or `null`. */
|
|
38
|
+
requestBody: IAutoViewEndpoint.IBody | null;
|
|
39
|
+
/** Response body reference, or `null`. */
|
|
40
|
+
responseBody: IAutoViewEndpoint.IBody | null;
|
|
41
|
+
/**
|
|
42
|
+
* The raw success response schema, captured even when {@link responseBody} is
|
|
43
|
+
* `null` because the response is an INLINE object (not a named `$ref`) — e.g.
|
|
44
|
+
* DigitalOcean's `{ databases: [...] }`. Lets the consumability analysis
|
|
45
|
+
* introspect inline collection responses without changing the frontend path
|
|
46
|
+
* (which keys off the named {@link responseBody.typeName}).
|
|
47
|
+
*/
|
|
48
|
+
responseSchema: OpenApi.IJsonSchema | null;
|
|
49
|
+
}
|
|
50
|
+
export declare namespace IAutoViewEndpoint {
|
|
51
|
+
interface IParameter {
|
|
52
|
+
name: string;
|
|
53
|
+
description: string;
|
|
54
|
+
schema: OpenApi.IJsonSchema;
|
|
55
|
+
}
|
|
56
|
+
interface IBody {
|
|
57
|
+
description: string;
|
|
58
|
+
/**
|
|
59
|
+
* Component schema name. For an array response (`Pet[]`) this is the
|
|
60
|
+
* ELEMENT type (`Pet`) with {@link isArray} set — so a list screen knows
|
|
61
|
+
* its row type and can derive table columns deterministically.
|
|
62
|
+
*/
|
|
63
|
+
typeName: string;
|
|
64
|
+
/** True when the payload is an array of `typeName` (list response). */
|
|
65
|
+
isArray: boolean;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* True when every accessor segment is a valid JS identifier, so the generator
|
|
70
|
+
* can emit `api.functional.<a>.<b>(…)`. Some real swaggers (Box) use `#`
|
|
71
|
+
* fragments in their paths (`/shared_items#folders`, `/schema#add`), which
|
|
72
|
+
* nestia turns into accessor segments containing `#` — unusable as a dotted
|
|
73
|
+
* property and a hard syntax error in the generated TSX. Such operations are
|
|
74
|
+
* dropped from {@link toEndpoints} and surfaced by {@link unsupportedOperations}.
|
|
75
|
+
*/
|
|
76
|
+
export declare function isRenderableAccessor(accessor: string[]): boolean;
|
|
77
|
+
export declare function toEndpoints(document: OpenApi.IDocument): IAutoViewEndpoint[];
|
|
78
|
+
/**
|
|
79
|
+
* Operations `HttpMigration` could not turn into a route at all — typically an
|
|
80
|
+
* unsupported request/response content type (e.g. `application/octet-stream`,
|
|
81
|
+
* raw binary upload/download). These never reach {@link toEndpoints}, so
|
|
82
|
+
* surfacing them is the only way to keep the READ layer from dropping
|
|
83
|
+
* endpoints silently.
|
|
84
|
+
*/
|
|
85
|
+
export interface IUnsupportedOperation {
|
|
86
|
+
method: string;
|
|
87
|
+
path: string;
|
|
88
|
+
reason: string;
|
|
89
|
+
}
|
|
90
|
+
export declare function unsupportedOperations(document: OpenApi.IDocument): IUnsupportedOperation[];
|