@tetrascience-npm/request 0.2.0-beta.106.2 → 0.2.1-beta.112.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate-schemas.d.ts","sourceRoot":"","sources":["../../src/cli/generate-schemas.ts"],"names":[],"mappings":";AA8DA;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5C;
|
|
1
|
+
{"version":3,"file":"generate-schemas.d.ts","sourceRoot":"","sources":["../../src/cli/generate-schemas.ts"],"names":[],"mappings":";AA8DA;;GAEG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS5C;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAkEnG"}
|
|
@@ -39,14 +39,14 @@ exports.generateRequestSchemas = generateRequestSchemas;
|
|
|
39
39
|
/**
|
|
40
40
|
* Generates Zod request-body schemas from an OpenAPI spec.
|
|
41
41
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
42
|
+
* Uses openapi-zod-client's programmatic API to:
|
|
43
|
+
* 1. Parse the OpenAPI spec into structured schema + endpoint data
|
|
44
|
+
* 2. Extract request body schema mappings from endpoint definitions
|
|
45
|
+
* 3. Output a validation map: "METHOD /path" -> Zod schema
|
|
45
46
|
*
|
|
46
47
|
* Usage:
|
|
47
48
|
* generate-request-schemas --spec <path-to-openapi-yaml> --out <output-dir>
|
|
48
49
|
*/
|
|
49
|
-
const child_process_1 = require("child_process");
|
|
50
50
|
const fs = __importStar(require("fs"));
|
|
51
51
|
const path = __importStar(require("path"));
|
|
52
52
|
function parseArgs() {
|
|
@@ -100,103 +100,53 @@ function findBin(name) {
|
|
|
100
100
|
console.error(`Error: ${name} not found. Install it as a devDependency: yarn add -D ${name}`);
|
|
101
101
|
process.exit(1);
|
|
102
102
|
}
|
|
103
|
-
function findZodClientBin() {
|
|
104
|
-
return findBin('openapi-zod-client');
|
|
105
|
-
}
|
|
106
103
|
function generateRequestSchemas(specPath, outDir, outFileName) {
|
|
107
|
-
const tmpFile = path.join(outDir, '.zod-raw.ts');
|
|
108
104
|
const outFile = path.join(outDir, outFileName || 'request-schemas.ts');
|
|
109
105
|
fs.mkdirSync(outDir, { recursive: true });
|
|
110
|
-
// 1.
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
let raw;
|
|
106
|
+
// 1. Load OpenAPI spec and get structured schema/endpoint data via programmatic API
|
|
107
|
+
const spec = loadYaml(specPath);
|
|
108
|
+
let getZodClientTemplateContext;
|
|
114
109
|
try {
|
|
115
|
-
|
|
110
|
+
({ getZodClientTemplateContext } = require('openapi-zod-client'));
|
|
116
111
|
}
|
|
117
112
|
catch {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
// Extract schema section (everything before `const endpoints = makeApi(`)
|
|
121
|
-
const endpointsIdx = raw.indexOf('const endpoints = makeApi(');
|
|
122
|
-
if (endpointsIdx === -1) {
|
|
123
|
-
fs.unlinkSync(tmpFile);
|
|
124
|
-
throw new Error('Could not find endpoints definition in generated file');
|
|
113
|
+
console.error('Error: openapi-zod-client is required for schema generation. Install it as a devDependency: yarn add -D openapi-zod-client');
|
|
114
|
+
process.exit(1);
|
|
125
115
|
}
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
.trim();
|
|
132
|
-
// 2. Parse the OpenAPI spec to find request body -> schema name mappings
|
|
133
|
-
const spec = loadYaml(specPath);
|
|
116
|
+
const ctx = getZodClientTemplateContext(spec, { shouldExportAllSchemas: true });
|
|
117
|
+
// 2. Build "METHOD /path" -> schema name map from endpoint definitions
|
|
118
|
+
// openapi-zod-client converts path params to Express format (:id),
|
|
119
|
+
// but openapi-fetch's schemaPath uses OpenAPI format ({id}).
|
|
120
|
+
const toOpenApiPath = (p) => p.replace(/:(\w+)/g, '{$1}');
|
|
134
121
|
const bodyMap = {};
|
|
135
|
-
for (const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
continue;
|
|
139
|
-
const op = operation;
|
|
140
|
-
const requestBody = op.requestBody;
|
|
141
|
-
if (!requestBody?.content?.['application/json']?.schema)
|
|
142
|
-
continue;
|
|
143
|
-
const schema = requestBody.content['application/json'].schema;
|
|
144
|
-
const key = `${method.toUpperCase()} ${pathStr}`;
|
|
145
|
-
if (schema.$ref) {
|
|
146
|
-
const schemaName = schema.$ref.split('/').pop();
|
|
147
|
-
bodyMap[key] = schemaName;
|
|
148
|
-
}
|
|
149
|
-
else if (schema.type === 'array' && schema.items?.$ref) {
|
|
150
|
-
const opId = op.operationId?.replace(/-/g, '_');
|
|
151
|
-
if (opId)
|
|
152
|
-
bodyMap[key] = `${opId}_Body`;
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
const opId = op.operationId?.replace(/-/g, '_');
|
|
156
|
-
if (opId)
|
|
157
|
-
bodyMap[key] = `${opId}_Body`;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
// 3. Verify all referenced schema names exist in the generated code
|
|
162
|
-
const exportedSchemaNames = [...raw.matchAll(/^const (\w+)\s*=\s*z[.\s]/gm)].map((m) => m[1]);
|
|
163
|
-
for (const [key, schemaName] of Object.entries(bodyMap)) {
|
|
164
|
-
if (raw.includes(`const ${schemaName} =`) || raw.includes(`const ${schemaName}=`)) {
|
|
122
|
+
for (const endpoint of ctx.endpoints) {
|
|
123
|
+
const bodyParam = endpoint.parameters.find((p) => p.type === 'Body');
|
|
124
|
+
if (!bodyParam)
|
|
165
125
|
continue;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const parts = schemaName.split('_');
|
|
169
|
-
const resourceHint = parts.slice(1, -1).join('_');
|
|
170
|
-
const fallback = exportedSchemaNames.find((name) => name.endsWith('_Body') && name.includes(resourceHint));
|
|
171
|
-
if (fallback) {
|
|
172
|
-
console.log(` info: ${key}: "${schemaName}" -> "${fallback}" (shared schema)`);
|
|
173
|
-
bodyMap[key] = fallback;
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
console.warn(` warn: Schema "${schemaName}" for ${key} not found — skipping`);
|
|
177
|
-
delete bodyMap[key];
|
|
178
|
-
}
|
|
126
|
+
const key = `${endpoint.method.toUpperCase()} ${toOpenApiPath(endpoint.path)}`;
|
|
127
|
+
bodyMap[key] = bodyParam.schema;
|
|
179
128
|
}
|
|
180
|
-
//
|
|
129
|
+
// 3. Build output file — schemas are already in dependency order (topologically sorted)
|
|
181
130
|
const lines = [
|
|
182
131
|
'// AUTO-GENERATED — do not edit. Run `generate-request-schemas` to regenerate.',
|
|
183
132
|
"import { z } from 'zod'",
|
|
184
133
|
'',
|
|
185
|
-
schemaSection,
|
|
186
|
-
'',
|
|
187
|
-
'/**',
|
|
188
|
-
' * Map of "METHOD /path" -> Zod schema for request body validation.',
|
|
189
|
-
' * Used by the request validation middleware.',
|
|
190
|
-
' */',
|
|
191
|
-
'export const requestBodySchemas: Record<string, z.ZodTypeAny> = {',
|
|
192
134
|
];
|
|
135
|
+
for (const [name, code] of Object.entries(ctx.schemas)) {
|
|
136
|
+
lines.push(`const ${name} = ${code}`);
|
|
137
|
+
}
|
|
138
|
+
lines.push('');
|
|
139
|
+
lines.push('/**');
|
|
140
|
+
lines.push(' * Map of "METHOD /path" -> Zod schema for request body validation.');
|
|
141
|
+
lines.push(' * Used by the request validation middleware.');
|
|
142
|
+
lines.push(' */');
|
|
143
|
+
lines.push('export const requestBodySchemas: Record<string, z.ZodTypeAny> = {');
|
|
193
144
|
for (const [key, schemaName] of Object.entries(bodyMap)) {
|
|
194
145
|
lines.push(` '${key}': ${schemaName},`);
|
|
195
146
|
}
|
|
196
147
|
lines.push('}');
|
|
197
148
|
lines.push('');
|
|
198
149
|
fs.writeFileSync(outFile, lines.join('\n'));
|
|
199
|
-
fs.unlinkSync(tmpFile);
|
|
200
150
|
console.log(`\nGenerated ${outFile}`);
|
|
201
151
|
console.log(` ${Object.keys(bodyMap).length} request body schemas mapped:`);
|
|
202
152
|
for (const [key, schemaName] of Object.entries(bodyMap)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAkBzC;AAaD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,MAAM,CA4E3F;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAsBT;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAKhD;AAED,wBAAgB,cAAc,IAAI,MAAM,
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAM7D;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAkBzC;AAaD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,GAAG,MAAM,CA4E3F;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE;IACjD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC1B,GAAG,MAAM,CAsBT;AAED,wBAAgB,uBAAuB,IAAI,MAAM,CAKhD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAGvC"}
|
package/dist/cli/templates.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tetrascience-npm/request",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1-beta.112.2",
|
|
4
4
|
"description": "Request tracking middleware for TetraScience services and data apps (client + server).",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"packageManager": "yarn@4.1.0",
|