@wild-framework/cli 0.2.0 → 0.2.2
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/package.json +7 -7
- package/dist/frontend/codegen.d.ts +0 -27
- package/dist/frontend/codegen.d.ts.map +0 -1
- package/dist/frontend/codegen.js +0 -97
- package/dist/frontend/codegen.js.map +0 -1
- package/dist/frontend/command.d.ts +0 -22
- package/dist/frontend/command.d.ts.map +0 -1
- package/dist/frontend/command.js +0 -57
- package/dist/frontend/command.js.map +0 -1
- package/dist/frontend/react.d.ts +0 -14
- package/dist/frontend/react.d.ts.map +0 -1
- package/dist/frontend/react.js +0 -156
- package/dist/frontend/react.js.map +0 -1
- package/dist/frontend/scaffold.d.ts +0 -20
- package/dist/frontend/scaffold.d.ts.map +0 -1
- package/dist/frontend/scaffold.js +0 -157
- package/dist/frontend/scaffold.js.map +0 -1
- package/dist/frontend/spec.d.ts +0 -33
- package/dist/frontend/spec.d.ts.map +0 -1
- package/dist/frontend/spec.js +0 -74
- package/dist/frontend/spec.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wild-framework/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"author": "Sphah",
|
|
24
24
|
"repository": {
|
|
25
25
|
"type": "git",
|
|
26
|
-
"url": "git+https://github.com/
|
|
26
|
+
"url": "git+https://github.com/Khandasoftware/wild-framework.git"
|
|
27
27
|
},
|
|
28
28
|
"description": "Scaffolding CLI for Wild Framework — generate providers, services, controllers, events and more.",
|
|
29
29
|
"keywords": [
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"make"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@wild-framework/
|
|
39
|
-
"@wild-framework/
|
|
40
|
-
"@wild-framework/database-drizzle": "0.2.
|
|
41
|
-
"@wild-framework/database-
|
|
42
|
-
"@wild-framework/database-
|
|
38
|
+
"@wild-framework/database": "0.2.2",
|
|
39
|
+
"@wild-framework/config": "0.2.2",
|
|
40
|
+
"@wild-framework/database-drizzle": "0.2.2",
|
|
41
|
+
"@wild-framework/database-mysql": "0.2.2",
|
|
42
|
+
"@wild-framework/database-postgres": "0.2.2"
|
|
43
43
|
},
|
|
44
44
|
"scripts": {
|
|
45
45
|
"build": "tsc",
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import type { SpecOperation } from "./spec.js";
|
|
2
|
-
/**
|
|
3
|
-
* Convert an OpenAPI path param to a TS string interpolation key.
|
|
4
|
-
* "/users/{id}" with param "id" → "id" (used as `encodeURIComponent(String(id))`)
|
|
5
|
-
*/
|
|
6
|
-
export declare function pathParamKeys(path: string): string[];
|
|
7
|
-
/** Convert a schema name to a TypeScript type name. */
|
|
8
|
-
export declare function schemaToTsType(name: string | undefined, fallback?: string): string;
|
|
9
|
-
/** PascalCase → camelCase ("CreateUserRequest" → "createUserRequest"). */
|
|
10
|
-
export declare function camelCase(name: string): string;
|
|
11
|
-
/** Uppercase the first character. */
|
|
12
|
-
export declare function capitalize(name: string): string;
|
|
13
|
-
/**
|
|
14
|
-
* Derive a function name from an operation.
|
|
15
|
-
*
|
|
16
|
-
* Prefers method+path (deterministic, descriptive: `getProducts`,
|
|
17
|
-
* `postOrders`). Uses a custom operationId only when it's a clean
|
|
18
|
-
* identifier (no dot — e.g. "listProducts" from a hand-written spec).
|
|
19
|
-
* Auto-generated operationIds look like "ProductController.index",
|
|
20
|
-
* which we ignore in favour of the method+path name.
|
|
21
|
-
*/
|
|
22
|
-
export declare function functionName(op: SpecOperation): string;
|
|
23
|
-
/** Derive a hook name from a function name. */
|
|
24
|
-
export declare function hookName(fn: string): string;
|
|
25
|
-
/** Convert a JSON Schema object to a TS type string. */
|
|
26
|
-
export declare function jsonSchemaToTs(schema: Record<string, unknown> | undefined, schemas: Record<string, Record<string, unknown>>, depth?: number): string;
|
|
27
|
-
//# sourceMappingURL=codegen.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../../src/frontend/codegen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,WAAW,CAAC;AAE3D;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAQpD;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,QAAQ,SAAY,GAAG,MAAM,CAGrF;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,qCAAqC;AACrC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CActD;AAED,+CAA+C;AAC/C,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAAE,KAAK,SAAI,GAAG,MAAM,CAuC/I"}
|
package/dist/frontend/codegen.js
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Convert an OpenAPI path param to a TS string interpolation key.
|
|
3
|
-
* "/users/{id}" with param "id" → "id" (used as `encodeURIComponent(String(id))`)
|
|
4
|
-
*/
|
|
5
|
-
export function pathParamKeys(path) {
|
|
6
|
-
const keys = [];
|
|
7
|
-
const re = /\{([^}]+)\}/g;
|
|
8
|
-
let m;
|
|
9
|
-
while ((m = re.exec(path)) !== null) {
|
|
10
|
-
keys.push(m[1]);
|
|
11
|
-
}
|
|
12
|
-
return keys;
|
|
13
|
-
}
|
|
14
|
-
/** Convert a schema name to a TypeScript type name. */
|
|
15
|
-
export function schemaToTsType(name, fallback = "unknown") {
|
|
16
|
-
if (!name)
|
|
17
|
-
return fallback;
|
|
18
|
-
return name;
|
|
19
|
-
}
|
|
20
|
-
/** PascalCase → camelCase ("CreateUserRequest" → "createUserRequest"). */
|
|
21
|
-
export function camelCase(name) {
|
|
22
|
-
return name.charAt(0).toLowerCase() + name.slice(1);
|
|
23
|
-
}
|
|
24
|
-
/** Uppercase the first character. */
|
|
25
|
-
export function capitalize(name) {
|
|
26
|
-
return name.charAt(0).toUpperCase() + name.slice(1);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Derive a function name from an operation.
|
|
30
|
-
*
|
|
31
|
-
* Prefers method+path (deterministic, descriptive: `getProducts`,
|
|
32
|
-
* `postOrders`). Uses a custom operationId only when it's a clean
|
|
33
|
-
* identifier (no dot — e.g. "listProducts" from a hand-written spec).
|
|
34
|
-
* Auto-generated operationIds look like "ProductController.index",
|
|
35
|
-
* which we ignore in favour of the method+path name.
|
|
36
|
-
*/
|
|
37
|
-
export function functionName(op) {
|
|
38
|
-
if (op.operationId && !op.operationId.includes(".")) {
|
|
39
|
-
return camelCase(op.operationId);
|
|
40
|
-
}
|
|
41
|
-
const method = op.method;
|
|
42
|
-
const segments = op.path.split("/").filter(Boolean);
|
|
43
|
-
let last = segments.pop() ?? "resource";
|
|
44
|
-
// If the last segment is a param, use the resource name before it
|
|
45
|
-
if (/\{[^}]+\}/.test(last)) {
|
|
46
|
-
const base = segments.pop() ?? "resource";
|
|
47
|
-
last = `${base}ById`;
|
|
48
|
-
}
|
|
49
|
-
const plural = last.replace(/\{[^}]+\}/g, "ById");
|
|
50
|
-
return `${method}${capitalize(plural)}`;
|
|
51
|
-
}
|
|
52
|
-
/** Derive a hook name from a function name. */
|
|
53
|
-
export function hookName(fn) {
|
|
54
|
-
return `use${capitalize(fn)}`;
|
|
55
|
-
}
|
|
56
|
-
/** Convert a JSON Schema object to a TS type string. */
|
|
57
|
-
export function jsonSchemaToTs(schema, schemas, depth = 0) {
|
|
58
|
-
if (!schema)
|
|
59
|
-
return "unknown";
|
|
60
|
-
if (depth > 6)
|
|
61
|
-
return "unknown";
|
|
62
|
-
if (schema.$ref) {
|
|
63
|
-
return String(schema.$ref).replace("#/components/schemas/", "");
|
|
64
|
-
}
|
|
65
|
-
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
66
|
-
return schema.allOf.map((s) => jsonSchemaToTs(s, schemas, depth + 1)).join(" & ");
|
|
67
|
-
}
|
|
68
|
-
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
69
|
-
return schema.oneOf.map((s) => jsonSchemaToTs(s, schemas, depth + 1)).join(" | ");
|
|
70
|
-
}
|
|
71
|
-
const type = schema.type;
|
|
72
|
-
if (type === "string")
|
|
73
|
-
return "string";
|
|
74
|
-
if (type === "number" || type === "integer")
|
|
75
|
-
return "number";
|
|
76
|
-
if (type === "boolean")
|
|
77
|
-
return "boolean";
|
|
78
|
-
if (type === "null")
|
|
79
|
-
return "null";
|
|
80
|
-
if (type === "array" || Array.isArray(schema.items)) {
|
|
81
|
-
const items = schema.items;
|
|
82
|
-
return `${jsonSchemaToTs(items, schemas, depth + 1)}[]`;
|
|
83
|
-
}
|
|
84
|
-
if (type === "object" || schema.properties) {
|
|
85
|
-
const props = (schema.properties ?? {});
|
|
86
|
-
const required = (schema.required ?? []);
|
|
87
|
-
const lines = Object.entries(props).map(([key, propSchema]) => {
|
|
88
|
-
const isRequired = required.includes(key) || !schema.required;
|
|
89
|
-
const propType = jsonSchemaToTs(propSchema, schemas, depth + 1);
|
|
90
|
-
const optional = isRequired ? "" : "?";
|
|
91
|
-
return ` ${key}${optional}: ${propType};`;
|
|
92
|
-
});
|
|
93
|
-
return `{\n${lines.join("\n")}\n}`;
|
|
94
|
-
}
|
|
95
|
-
return "unknown";
|
|
96
|
-
}
|
|
97
|
-
//# sourceMappingURL=codegen.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../src/frontend/codegen.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Options for the `wild frontend` command.
|
|
3
|
-
*/
|
|
4
|
-
export interface FrontendOptions {
|
|
5
|
-
/** OpenAPI spec source: URL or file path. Default "./openapi.json". */
|
|
6
|
-
spec?: string;
|
|
7
|
-
/** Where to generate the frontend. Default "./frontend". */
|
|
8
|
-
path?: string;
|
|
9
|
-
/** Frontend target. Only "react" is supported for now. */
|
|
10
|
-
target?: string;
|
|
11
|
-
/** Base URL the generated client calls. */
|
|
12
|
-
baseUrl?: string;
|
|
13
|
-
/** Print what would be generated, write nothing. */
|
|
14
|
-
dryRun?: boolean;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Run the `wild frontend` generator.
|
|
18
|
-
*
|
|
19
|
-
* @returns true on success, false on error (error already printed)
|
|
20
|
-
*/
|
|
21
|
-
export declare function runFrontend(options: FrontendOptions): Promise<boolean>;
|
|
22
|
-
//# sourceMappingURL=command.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/frontend/command.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAiD5E"}
|
package/dist/frontend/command.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { resolve, relative } from "node:path";
|
|
2
|
-
import { loadSpec, parseSpec } from "./spec.js";
|
|
3
|
-
import { buildReactFrontend, writeFrontend } from "./scaffold.js";
|
|
4
|
-
/**
|
|
5
|
-
* Run the `wild frontend` generator.
|
|
6
|
-
*
|
|
7
|
-
* @returns true on success, false on error (error already printed)
|
|
8
|
-
*/
|
|
9
|
-
export async function runFrontend(options) {
|
|
10
|
-
const specSource = options.spec ?? "./openapi.json";
|
|
11
|
-
const target = options.target ?? "react";
|
|
12
|
-
if (target !== "react") {
|
|
13
|
-
console.error(`wild: frontend target "${target}" is not supported yet. Available: react`);
|
|
14
|
-
return false;
|
|
15
|
-
}
|
|
16
|
-
console.log(`\nLoading OpenAPI spec from ${specSource}...`);
|
|
17
|
-
let raw;
|
|
18
|
-
try {
|
|
19
|
-
raw = await loadSpec(specSource);
|
|
20
|
-
}
|
|
21
|
-
catch (error) {
|
|
22
|
-
console.error(`wild: ${error instanceof Error ? error.message : String(error)}`);
|
|
23
|
-
console.error("\nHint: start your app (so /openapi.json is served) or pass --spec <file>.");
|
|
24
|
-
return false;
|
|
25
|
-
}
|
|
26
|
-
const spec = parseSpec(raw);
|
|
27
|
-
console.log(` ${spec.title} v${spec.version} — ${spec.operations.length} operation(s)`);
|
|
28
|
-
// Default base URL: derive from spec URL host, or from --baseUrl.
|
|
29
|
-
const baseUrl = options.baseUrl ?? deriveBaseUrl(specSource);
|
|
30
|
-
const outRoot = resolve(options.path ?? "./frontend");
|
|
31
|
-
const files = buildReactFrontend(spec, { baseUrl, title: spec.title });
|
|
32
|
-
if (options.dryRun) {
|
|
33
|
-
console.log(`\nDry-run — would generate ${files.length} file(s) under ${relative(process.cwd(), outRoot)}:\n`);
|
|
34
|
-
for (const f of files) {
|
|
35
|
-
console.log(` ${f.path}`);
|
|
36
|
-
}
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
console.log(`\nGenerating frontend under ${relative(process.cwd(), outRoot)}...\n`);
|
|
40
|
-
const written = writeFrontend(files, outRoot);
|
|
41
|
-
if (written === 0) {
|
|
42
|
-
console.log("\nNothing to do — all files already exist.");
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
console.log(`\nDone. ${written} file(s) generated.`);
|
|
46
|
-
console.log("\nNext steps:");
|
|
47
|
-
console.log(` cd ${relative(process.cwd(), outRoot)}`);
|
|
48
|
-
console.log(" npm install");
|
|
49
|
-
console.log(" npm run dev");
|
|
50
|
-
}
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
function deriveBaseUrl(specSource) {
|
|
54
|
-
const m = specSource.match(/^https?:\/\/([^/]+)/);
|
|
55
|
-
return m ? `${m[0]}/` : "http://localhost:3000";
|
|
56
|
-
}
|
|
57
|
-
//# sourceMappingURL=command.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/frontend/command.ts"],"names":[],"mappings":"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"}
|
package/dist/frontend/react.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { ParsedSpec } from "./spec.js";
|
|
2
|
-
/**
|
|
3
|
-
* Generate the TypeScript types file from the spec's component schemas.
|
|
4
|
-
*/
|
|
5
|
-
export declare function generateTypes(spec: ParsedSpec): string;
|
|
6
|
-
/**
|
|
7
|
-
* Generate the typed fetch client (api.ts).
|
|
8
|
-
*/
|
|
9
|
-
export declare function generateApiClient(spec: ParsedSpec, baseUrl: string): string;
|
|
10
|
-
/**
|
|
11
|
-
* Generate TanStack Query hooks (hooks.ts).
|
|
12
|
-
*/
|
|
13
|
-
export declare function generateHooks(spec: ParsedSpec): string;
|
|
14
|
-
//# sourceMappingURL=react.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../src/frontend/react.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,WAAW,CAAC;AAG3D;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAwBtD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CA0B3E;AAqCD;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,CAmEtD"}
|
package/dist/frontend/react.js
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
import { functionName, hookName, pathParamKeys, jsonSchemaToTs } from "./codegen.js";
|
|
2
|
-
/**
|
|
3
|
-
* Generate the TypeScript types file from the spec's component schemas.
|
|
4
|
-
*/
|
|
5
|
-
export function generateTypes(spec) {
|
|
6
|
-
const lines = [];
|
|
7
|
-
lines.push("/**");
|
|
8
|
-
lines.push(` * Generated types for ${spec.title} v${spec.version}.`);
|
|
9
|
-
lines.push(" * Do not edit by hand — regenerate with `wild frontend`.");
|
|
10
|
-
lines.push(" */");
|
|
11
|
-
lines.push("");
|
|
12
|
-
for (const [name, schema] of Object.entries(spec.schemas)) {
|
|
13
|
-
lines.push(`export interface ${name} ${jsonSchemaToTs(schema, spec.schemas)}`);
|
|
14
|
-
lines.push("");
|
|
15
|
-
}
|
|
16
|
-
// Types for operations with request bodies but no named schema
|
|
17
|
-
const anonymous = spec.operations.filter((op) => op.hasRequestBody && !op.requestSchemaName);
|
|
18
|
-
if (anonymous.length > 0) {
|
|
19
|
-
lines.push("/** Request body payloads. */");
|
|
20
|
-
for (const op of anonymous) {
|
|
21
|
-
const fn = functionName(op);
|
|
22
|
-
lines.push(`export type ${fn}Body = unknown;`);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return lines.join("\n");
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Generate the typed fetch client (api.ts).
|
|
29
|
-
*/
|
|
30
|
-
export function generateApiClient(spec, baseUrl) {
|
|
31
|
-
const lines = [];
|
|
32
|
-
// api.ts lives in src/lib/, types.ts in src/ — import from ../types.js
|
|
33
|
-
lines.push(`import type { ${Object.keys(spec.schemas).join(", ")} } from "../types.js";`);
|
|
34
|
-
lines.push("");
|
|
35
|
-
lines.push(`/** Generated API client for ${spec.title} v${spec.version}. */`);
|
|
36
|
-
lines.push(`export const baseUrl = ${JSON.stringify(baseUrl)};`);
|
|
37
|
-
lines.push("");
|
|
38
|
-
lines.push(`async function request<T>(path: string, init?: RequestInit): Promise<T> {`);
|
|
39
|
-
lines.push(` const res = await fetch(baseUrl + path, {`);
|
|
40
|
-
lines.push(` ...init,`);
|
|
41
|
-
lines.push(` headers: { "Content-Type": "application/json", ...init?.headers },`);
|
|
42
|
-
lines.push(` });`);
|
|
43
|
-
lines.push(` if (!res.ok) {`);
|
|
44
|
-
lines.push(` throw new Error(\`\${res.status} \${await res.text()}\`);`);
|
|
45
|
-
lines.push(` }`);
|
|
46
|
-
lines.push(` return res.json() as Promise<T>;`);
|
|
47
|
-
lines.push(`}`);
|
|
48
|
-
lines.push("");
|
|
49
|
-
for (const op of spec.operations) {
|
|
50
|
-
lines.push(...operationClient(op));
|
|
51
|
-
lines.push("");
|
|
52
|
-
}
|
|
53
|
-
return lines.join("\n");
|
|
54
|
-
}
|
|
55
|
-
function operationClient(op) {
|
|
56
|
-
const fn = functionName(op);
|
|
57
|
-
const paramKeys = pathParamKeys(op.path);
|
|
58
|
-
const returnType = "unknown";
|
|
59
|
-
const out = [];
|
|
60
|
-
const args = [];
|
|
61
|
-
const usesBody = op.hasRequestBody;
|
|
62
|
-
const usesPath = paramKeys.length > 0;
|
|
63
|
-
if (usesPath) {
|
|
64
|
-
args.push(`params: { ${paramKeys.map((k) => `${k}: string | number`).join("; ")} }`);
|
|
65
|
-
}
|
|
66
|
-
if (usesBody) {
|
|
67
|
-
const bodyType = op.requestSchemaName ?? `${fn}Body`;
|
|
68
|
-
args.push(`body: ${bodyType}`);
|
|
69
|
-
}
|
|
70
|
-
out.push(`export function ${fn}(${args.join(", ")}): Promise<${returnType}> {`);
|
|
71
|
-
let url = `\`${op.path}\``;
|
|
72
|
-
if (paramKeys.length > 0) {
|
|
73
|
-
const interp = op.path.replace(/\{([^}]+)\}/g, (_, k) => `\${encodeURIComponent(String(params.${k}))}`);
|
|
74
|
-
url = `\`${interp}\``;
|
|
75
|
-
}
|
|
76
|
-
const init = [];
|
|
77
|
-
if (op.method !== "get") {
|
|
78
|
-
init.push(`method: ${JSON.stringify(op.method.toUpperCase())}`);
|
|
79
|
-
if (usesBody)
|
|
80
|
-
init.push(`body: JSON.stringify(body)`);
|
|
81
|
-
}
|
|
82
|
-
const initStr = init.length > 0 ? `{ ${init.join(", ")} }` : "";
|
|
83
|
-
out.push(` return request(${url}${initStr ? `, ${initStr}` : ""});`);
|
|
84
|
-
out.push(`}`);
|
|
85
|
-
return out;
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Generate TanStack Query hooks (hooks.ts).
|
|
89
|
-
*/
|
|
90
|
-
export function generateHooks(spec) {
|
|
91
|
-
const lines = [];
|
|
92
|
-
lines.push(`import { useQuery, useMutation } from "@tanstack/react-query";`);
|
|
93
|
-
lines.push(`import * as api from "./lib/api.js";`);
|
|
94
|
-
// hooks reference request body types (e.g. CreateOrderRequest) — import them.
|
|
95
|
-
const bodyTypes = new Set();
|
|
96
|
-
for (const op of spec.operations) {
|
|
97
|
-
if (op.hasRequestBody && op.requestSchemaName)
|
|
98
|
-
bodyTypes.add(op.requestSchemaName);
|
|
99
|
-
}
|
|
100
|
-
if (bodyTypes.size > 0) {
|
|
101
|
-
lines.push(`import type { ${[...bodyTypes].join(", ")} } from "./types.js";`);
|
|
102
|
-
}
|
|
103
|
-
lines.push("");
|
|
104
|
-
lines.push(`/** Generated TanStack Query hooks for ${spec.title}. */`);
|
|
105
|
-
lines.push("");
|
|
106
|
-
for (const op of spec.operations) {
|
|
107
|
-
const fn = functionName(op);
|
|
108
|
-
const hook = hookName(fn);
|
|
109
|
-
const paramKeys = pathParamKeys(op.path);
|
|
110
|
-
if (op.method === "get") {
|
|
111
|
-
const argTypes = paramKeys.length > 0
|
|
112
|
-
? `params: { ${paramKeys.map((k) => `${k}: string | number`).join("; ")} }`
|
|
113
|
-
: "";
|
|
114
|
-
const queryKey = `["${fn}", ${paramKeys.length > 0 ? "params" : "undefined"}]`;
|
|
115
|
-
lines.push(`export function ${hook}(${argTypes ? argTypes + ", " : ""}options?: { enabled?: boolean }) {`);
|
|
116
|
-
lines.push(` return useQuery({`);
|
|
117
|
-
lines.push(` queryKey: ${queryKey},`);
|
|
118
|
-
lines.push(` queryFn: () => api.${fn}(${paramKeys.length > 0 ? "params" : ""}),`);
|
|
119
|
-
lines.push(` ...options,`);
|
|
120
|
-
lines.push(` });`);
|
|
121
|
-
lines.push(`}`);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
// Mutations take a single variables argument. With both path params
|
|
125
|
-
// and a body, combine them: mutationFn({ params, body }) — the
|
|
126
|
-
// standard TanStack Query pattern.
|
|
127
|
-
const variablesType = [];
|
|
128
|
-
if (paramKeys.length > 0) {
|
|
129
|
-
variablesType.push(`params: { ${paramKeys.map((k) => `${k}: string | number`).join("; ")} }`);
|
|
130
|
-
}
|
|
131
|
-
if (op.hasRequestBody) {
|
|
132
|
-
const bodyType = op.requestSchemaName ?? `${fn}Body`;
|
|
133
|
-
variablesType.push(`body: ${bodyType}`);
|
|
134
|
-
}
|
|
135
|
-
lines.push(`export function ${hook}() {`);
|
|
136
|
-
lines.push(` return useMutation({`);
|
|
137
|
-
if (variablesType.length > 1) {
|
|
138
|
-
const destructure = variablesType.map((v) => v.split(":")[0]).join(", ");
|
|
139
|
-
const varsType = `{ ${variablesType.join("; ")} }`;
|
|
140
|
-
lines.push(` mutationFn: ({ ${destructure} }: ${varsType}) => api.${fn}(${destructure}),`);
|
|
141
|
-
}
|
|
142
|
-
else if (variablesType.length === 1) {
|
|
143
|
-
const arg = variablesType[0];
|
|
144
|
-
lines.push(` mutationFn: (${arg}) => api.${fn}(${arg.split(":")[0]}),`);
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
lines.push(` mutationFn: () => api.${fn}(),`);
|
|
148
|
-
}
|
|
149
|
-
lines.push(` });`);
|
|
150
|
-
lines.push(`}`);
|
|
151
|
-
}
|
|
152
|
-
lines.push("");
|
|
153
|
-
}
|
|
154
|
-
return lines.join("\n");
|
|
155
|
-
}
|
|
156
|
-
//# sourceMappingURL=react.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sourceRoot":"","sources":["../../src/frontend/react.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { ParsedSpec } from "./spec.js";
|
|
2
|
-
/**
|
|
3
|
-
* Files that make up a generated React + TanStack + Tailwind frontend.
|
|
4
|
-
*/
|
|
5
|
-
export interface FrontendFile {
|
|
6
|
-
path: string;
|
|
7
|
-
content: string;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Build the full file set for the React target.
|
|
11
|
-
*/
|
|
12
|
-
export declare function buildReactFrontend(spec: ParsedSpec, options: {
|
|
13
|
-
baseUrl: string;
|
|
14
|
-
title: string;
|
|
15
|
-
}): FrontendFile[];
|
|
16
|
-
/**
|
|
17
|
-
* Write generated files to disk, skipping existing ones.
|
|
18
|
-
*/
|
|
19
|
-
export declare function writeFrontend(files: FrontendFile[], root: string): number;
|
|
20
|
-
//# sourceMappingURL=scaffold.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../src/frontend/scaffold.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAG5C;;GAEG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAC9B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5C,YAAY,EAAE,CAgJhB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAczE"}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { mkdirSync, writeFileSync, existsSync } from "node:fs";
|
|
2
|
-
import { join, dirname } from "node:path";
|
|
3
|
-
import { generateTypes, generateApiClient, generateHooks } from "./react.js";
|
|
4
|
-
/**
|
|
5
|
-
* Build the full file set for the React target.
|
|
6
|
-
*/
|
|
7
|
-
export function buildReactFrontend(spec, options) {
|
|
8
|
-
const files = [];
|
|
9
|
-
const add = (path, content) => files.push({ path, content });
|
|
10
|
-
const appName = options.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "app";
|
|
11
|
-
// --- Project root files ---
|
|
12
|
-
add("package.json", `{
|
|
13
|
-
"name": "${appName}-frontend",
|
|
14
|
-
"private": true,
|
|
15
|
-
"type": "module",
|
|
16
|
-
"version": "0.0.0",
|
|
17
|
-
"scripts": {
|
|
18
|
-
"dev": "vite",
|
|
19
|
-
"build": "tsc -b && vite build",
|
|
20
|
-
"preview": "vite preview"
|
|
21
|
-
},
|
|
22
|
-
"dependencies": {
|
|
23
|
-
"@tanstack/react-query": "^5.0.0",
|
|
24
|
-
"react": "^18.3.1",
|
|
25
|
-
"react-dom": "^18.3.1"
|
|
26
|
-
},
|
|
27
|
-
"devDependencies": {
|
|
28
|
-
"@types/react": "^18.3.1",
|
|
29
|
-
"@types/react-dom": "^18.3.1",
|
|
30
|
-
"@vitejs/plugin-react": "^4.3.0",
|
|
31
|
-
"autoprefixer": "^10.4.20",
|
|
32
|
-
"postcss": "^8.4.40",
|
|
33
|
-
"tailwindcss": "^3.4.7",
|
|
34
|
-
"typescript": "^5.5.0",
|
|
35
|
-
"vite": "^5.4.0"
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
`);
|
|
39
|
-
add("index.html", `<!DOCTYPE html>
|
|
40
|
-
<html lang="en">
|
|
41
|
-
<head>
|
|
42
|
-
<meta charset="UTF-8" />
|
|
43
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
44
|
-
<title>${options.title} Frontend</title>
|
|
45
|
-
</head>
|
|
46
|
-
<body>
|
|
47
|
-
<div id="root"></div>
|
|
48
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
49
|
-
</body>
|
|
50
|
-
</html>
|
|
51
|
-
`);
|
|
52
|
-
add("vite.config.ts", `import { defineConfig } from "vite";
|
|
53
|
-
import react from "@vitejs/plugin-react";
|
|
54
|
-
|
|
55
|
-
export default defineConfig({
|
|
56
|
-
plugins: [react()],
|
|
57
|
-
});
|
|
58
|
-
`);
|
|
59
|
-
add("tailwind.config.ts", `import type { Config } from "tailwindcss";
|
|
60
|
-
|
|
61
|
-
export default {
|
|
62
|
-
content: ["./index.html", "./src/**/*.{ts,tsx}"],
|
|
63
|
-
theme: {
|
|
64
|
-
extend: {},
|
|
65
|
-
},
|
|
66
|
-
plugins: [],
|
|
67
|
-
} satisfies Config;
|
|
68
|
-
`);
|
|
69
|
-
add("postcss.config.js", `export default {
|
|
70
|
-
plugins: {
|
|
71
|
-
tailwindcss: {},
|
|
72
|
-
autoprefixer: {},
|
|
73
|
-
},
|
|
74
|
-
};
|
|
75
|
-
`);
|
|
76
|
-
add("tsconfig.json", `{
|
|
77
|
-
"compilerOptions": {
|
|
78
|
-
"target": "ES2020",
|
|
79
|
-
"useDefineForClassFields": true,
|
|
80
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
81
|
-
"module": "ESNext",
|
|
82
|
-
"skipLibCheck": true,
|
|
83
|
-
"moduleResolution": "bundler",
|
|
84
|
-
"allowImportingTsExtensions": true,
|
|
85
|
-
"isolatedModules": true,
|
|
86
|
-
"moduleDetection": "force",
|
|
87
|
-
"noEmit": true,
|
|
88
|
-
"jsx": "react-jsx",
|
|
89
|
-
"strict": true,
|
|
90
|
-
"noUnusedLocals": true,
|
|
91
|
-
"noUnusedParameters": true,
|
|
92
|
-
"noFallthroughCasesInSwitch": true
|
|
93
|
-
},
|
|
94
|
-
"include": ["src"]
|
|
95
|
-
}
|
|
96
|
-
`);
|
|
97
|
-
// --- src files ---
|
|
98
|
-
add("src/main.tsx", `import { StrictMode } from "react";
|
|
99
|
-
import { createRoot } from "react-dom/client";
|
|
100
|
-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
101
|
-
import { App } from "./App.js";
|
|
102
|
-
import "./index.css";
|
|
103
|
-
|
|
104
|
-
const queryClient = new QueryClient();
|
|
105
|
-
|
|
106
|
-
createRoot(document.getElementById("root")!).render(
|
|
107
|
-
<StrictMode>
|
|
108
|
-
<QueryClientProvider client={queryClient}>
|
|
109
|
-
<App />
|
|
110
|
-
</QueryClientProvider>
|
|
111
|
-
</StrictMode>,
|
|
112
|
-
);
|
|
113
|
-
`);
|
|
114
|
-
add("src/index.css", `@tailwind base;
|
|
115
|
-
@tailwind components;
|
|
116
|
-
@tailwind utilities;
|
|
117
|
-
`);
|
|
118
|
-
add("src/vite-env.d.ts", `/// <reference types="vite/client" />
|
|
119
|
-
`);
|
|
120
|
-
add("src/App.tsx", `/**
|
|
121
|
-
* Generated app shell.
|
|
122
|
-
* Replace with your own UI — import hooks from "./hooks.js".
|
|
123
|
-
*/
|
|
124
|
-
export function App() {
|
|
125
|
-
return (
|
|
126
|
-
<main className="min-h-screen bg-gray-50 p-8">
|
|
127
|
-
<h1 className="text-2xl font-bold text-gray-900">${options.title} Frontend</h1>
|
|
128
|
-
<p className="mt-2 text-gray-600">Generated with <code>wild frontend</code>.</p>
|
|
129
|
-
</main>
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
`);
|
|
133
|
-
// --- Generated lib + hooks ---
|
|
134
|
-
add("src/types.ts", generateTypes(spec));
|
|
135
|
-
add("src/lib/api.ts", generateApiClient(spec, options.baseUrl));
|
|
136
|
-
add("src/hooks.ts", generateHooks(spec));
|
|
137
|
-
return files;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Write generated files to disk, skipping existing ones.
|
|
141
|
-
*/
|
|
142
|
-
export function writeFrontend(files, root) {
|
|
143
|
-
let written = 0;
|
|
144
|
-
for (const file of files) {
|
|
145
|
-
const target = join(root, file.path);
|
|
146
|
-
if (existsSync(target)) {
|
|
147
|
-
console.log(` skip ${file.path}`);
|
|
148
|
-
continue;
|
|
149
|
-
}
|
|
150
|
-
mkdirSync(dirname(target), { recursive: true });
|
|
151
|
-
writeFileSync(target, file.content, "utf8");
|
|
152
|
-
console.log(` create ${file.path}`);
|
|
153
|
-
written++;
|
|
154
|
-
}
|
|
155
|
-
return written;
|
|
156
|
-
}
|
|
157
|
-
//# sourceMappingURL=scaffold.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/frontend/scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC/D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAU7E;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAC9B,IAAgB,EAChB,OAA2C;IAE3C,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,OAAe,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAE7E,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC;IAEzG,6BAA6B;IAC7B,GAAG,CAAC,cAAc,EAAE;aACX,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;CAyBnB,CAAC,CAAC;IAEC,GAAG,CAAC,YAAY,EAAE;;;;;aAKT,OAAO,CAAC,KAAK;;;;;;;CAOzB,CAAC,CAAC;IAEC,GAAG,CAAC,gBAAgB,EAAE;;;;;;CAMzB,CAAC,CAAC;IAEC,GAAG,CAAC,oBAAoB,EAAE;;;;;;;;;CAS7B,CAAC,CAAC;IAEC,GAAG,CAAC,mBAAmB,EAAE;;;;;;CAM5B,CAAC,CAAC;IAEC,GAAG,CAAC,eAAe,EAAE;;;;;;;;;;;;;;;;;;;;CAoBxB,CAAC,CAAC;IAEC,oBAAoB;IACpB,GAAG,CAAC,cAAc,EAAE;;;;;;;;;;;;;;;CAevB,CAAC,CAAC;IAEC,GAAG,CAAC,eAAe,EAAE;;;CAGxB,CAAC,CAAC;IAEC,GAAG,CAAC,mBAAmB,EAAE;CAC5B,CAAC,CAAC;IAEC,GAAG,CAAC,aAAa,EAAE;;;;;;;yDAOkC,OAAO,CAAC,KAAK;;;;;CAKrE,CAAC,CAAC;IAEC,gCAAgC;IAChC,GAAG,CAAC,cAAc,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,GAAG,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAChE,GAAG,CAAC,cAAc,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IAEzC,OAAO,KAAK,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAqB,EAAE,IAAY;IAC7D,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;YACpC,SAAS;QACb,CAAC;QACD,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACrC,OAAO,EAAE,CAAC;IACd,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC"}
|
package/dist/frontend/spec.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A single parsed operation from the OpenAPI spec.
|
|
3
|
-
*/
|
|
4
|
-
export interface SpecOperation {
|
|
5
|
-
method: "get" | "post" | "put" | "patch" | "delete";
|
|
6
|
-
path: string;
|
|
7
|
-
operationId?: string;
|
|
8
|
-
/** Component schema name for the request body, if any. */
|
|
9
|
-
requestSchemaName?: string;
|
|
10
|
-
/** Component schema names for path/query params, if any. */
|
|
11
|
-
pathParamNames: string[];
|
|
12
|
-
queryParamNames: string[];
|
|
13
|
-
hasRequestBody: boolean;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Normalized OpenAPI spec: the parts the generator needs.
|
|
17
|
-
*/
|
|
18
|
-
export interface ParsedSpec {
|
|
19
|
-
title: string;
|
|
20
|
-
version: string;
|
|
21
|
-
operations: SpecOperation[];
|
|
22
|
-
/** component schema name → JSON schema object */
|
|
23
|
-
schemas: Record<string, Record<string, unknown>>;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Load an OpenAPI spec from a file path (local) or a URL.
|
|
27
|
-
*/
|
|
28
|
-
export declare function loadSpec(source: string): Promise<Record<string, unknown>>;
|
|
29
|
-
/**
|
|
30
|
-
* Normalize a raw OpenAPI document into the model the generators consume.
|
|
31
|
-
*/
|
|
32
|
-
export declare function parseSpec(spec: Record<string, unknown>): ParsedSpec;
|
|
33
|
-
//# sourceMappingURL=spec.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spec.d.ts","sourceRoot":"","sources":["../../src/frontend/spec.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACpD;AAED;;GAEG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAc/E;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,UAAU,CAsDnE"}
|
package/dist/frontend/spec.js
DELETED
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
-
import { resolve } from "node:path";
|
|
3
|
-
/**
|
|
4
|
-
* Load an OpenAPI spec from a file path (local) or a URL.
|
|
5
|
-
*/
|
|
6
|
-
export async function loadSpec(source) {
|
|
7
|
-
if (/^https?:\/\//.test(source)) {
|
|
8
|
-
const res = await fetch(source);
|
|
9
|
-
if (!res.ok) {
|
|
10
|
-
throw new Error(`Failed to fetch spec from ${source}: HTTP ${res.status}`);
|
|
11
|
-
}
|
|
12
|
-
return (await res.json());
|
|
13
|
-
}
|
|
14
|
-
const filePath = resolve(source);
|
|
15
|
-
if (!existsSync(filePath)) {
|
|
16
|
-
throw new Error(`Spec file not found: ${source}`);
|
|
17
|
-
}
|
|
18
|
-
return JSON.parse(readFileSync(filePath, "utf8"));
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Normalize a raw OpenAPI document into the model the generators consume.
|
|
22
|
-
*/
|
|
23
|
-
export function parseSpec(spec) {
|
|
24
|
-
const info = (spec.info ?? {});
|
|
25
|
-
const paths = (spec.paths ?? {});
|
|
26
|
-
const components = (spec.components ?? {});
|
|
27
|
-
const schemas = (components.schemas ?? {});
|
|
28
|
-
const operations = [];
|
|
29
|
-
for (const [path, pathItem] of Object.entries(paths)) {
|
|
30
|
-
for (const method of ["get", "post", "put", "patch", "delete"]) {
|
|
31
|
-
const op = pathItem[method];
|
|
32
|
-
if (!op || typeof op !== "object")
|
|
33
|
-
continue;
|
|
34
|
-
const params = (op.parameters ?? []);
|
|
35
|
-
const pathParamNames = [];
|
|
36
|
-
const queryParamNames = [];
|
|
37
|
-
for (const param of params) {
|
|
38
|
-
const inLoc = param.in;
|
|
39
|
-
const name = String(param.name ?? "");
|
|
40
|
-
if (inLoc === "path")
|
|
41
|
-
pathParamNames.push(name);
|
|
42
|
-
if (inLoc === "query")
|
|
43
|
-
queryParamNames.push(name);
|
|
44
|
-
}
|
|
45
|
-
// Request body → component schema name
|
|
46
|
-
let requestSchemaName;
|
|
47
|
-
const requestBody = op.requestBody;
|
|
48
|
-
if (requestBody) {
|
|
49
|
-
const content = requestBody.content;
|
|
50
|
-
const json = content?.["application/json"];
|
|
51
|
-
const schema = json?.schema;
|
|
52
|
-
requestSchemaName = schema?.$ref
|
|
53
|
-
? String(schema.$ref).replace("#/components/schemas/", "")
|
|
54
|
-
: undefined;
|
|
55
|
-
}
|
|
56
|
-
operations.push({
|
|
57
|
-
method,
|
|
58
|
-
path,
|
|
59
|
-
operationId: op.operationId,
|
|
60
|
-
requestSchemaName,
|
|
61
|
-
pathParamNames,
|
|
62
|
-
queryParamNames,
|
|
63
|
-
hasRequestBody: !!requestBody,
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
title: String(info.title ?? "API"),
|
|
69
|
-
version: String(info.version ?? "1.0.0"),
|
|
70
|
-
operations,
|
|
71
|
-
schemas,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
//# sourceMappingURL=spec.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/frontend/spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BpC;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAc;IACzC,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAC;IACzD,CAAC;IAED,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA4B,CAAC;AACjF,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,IAA6B;IACnD,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC;IAC1D,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAA4C,CAAC;IAC5E,MAAM,UAAU,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAA4B,CAAC;IACtE,MAAM,OAAO,GAAG,CAAC,UAAU,CAAC,OAAO,IAAI,EAAE,CAA4C,CAAC;IAEtF,MAAM,UAAU,GAAoB,EAAE,CAAC;IAEvC,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnD,KAAK,MAAM,MAAM,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAU,EAAE,CAAC;YACtE,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAwC,CAAC;YACnE,IAAI,CAAC,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ;gBAAE,SAAS;YAE5C,MAAM,MAAM,GAAG,CAAC,EAAE,CAAC,UAAU,IAAI,EAAE,CAAmC,CAAC;YACvE,MAAM,cAAc,GAAa,EAAE,CAAC;YACpC,MAAM,eAAe,GAAa,EAAE,CAAC;YAErC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBACzB,MAAM,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBACtC,IAAI,KAAK,KAAK,MAAM;oBAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,KAAK,KAAK,OAAO;oBAAE,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtD,CAAC;YAED,uCAAuC;YACvC,IAAI,iBAAqC,CAAC;YAC1C,MAAM,WAAW,GAAG,EAAE,CAAC,WAAkD,CAAC;YAC1E,IAAI,WAAW,EAAE,CAAC;gBACd,MAAM,OAAO,GAAG,WAAW,CAAC,OAA8C,CAAC;gBAC3E,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC,kBAAkB,CAAwC,CAAC;gBAClF,MAAM,MAAM,GAAG,IAAI,EAAE,MAA6C,CAAC;gBACnE,iBAAiB,GAAG,MAAM,EAAE,IAAI;oBAC5B,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC;oBAC1D,CAAC,CAAC,SAAS,CAAC;YACpB,CAAC;YAED,UAAU,CAAC,IAAI,CAAC;gBACZ,MAAM;gBACN,IAAI;gBACJ,WAAW,EAAE,EAAE,CAAC,WAAiC;gBACjD,iBAAiB;gBACjB,cAAc;gBACd,eAAe;gBACf,cAAc,EAAE,CAAC,CAAC,WAAW;aAChC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;QAClC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC;QACxC,UAAU;QACV,OAAO;KACV,CAAC;AACN,CAAC"}
|