@rexeus/typeweaver-gen 0.10.5 → 0.12.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/dist/index.cjs +384 -45
- package/dist/index.d.cts +25 -3
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +25 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +384 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -124,6 +124,175 @@ var PathParameterMismatchError = class extends Error {
|
|
|
124
124
|
}
|
|
125
125
|
};
|
|
126
126
|
//#endregion
|
|
127
|
+
//#region src/bodyNormalization.ts
|
|
128
|
+
const JSON_BODY_SCHEMA_TYPES = new Set([
|
|
129
|
+
"array",
|
|
130
|
+
"boolean",
|
|
131
|
+
"enum",
|
|
132
|
+
"intersection",
|
|
133
|
+
"literal",
|
|
134
|
+
"null",
|
|
135
|
+
"number",
|
|
136
|
+
"object",
|
|
137
|
+
"record",
|
|
138
|
+
"tuple",
|
|
139
|
+
"union"
|
|
140
|
+
]);
|
|
141
|
+
const normalizeBody = (input) => {
|
|
142
|
+
if (input.bodySchema === void 0) return { warnings: [] };
|
|
143
|
+
const warnings = [];
|
|
144
|
+
const contentTypeHeader = extractContentTypeHeader(input.headerSchema);
|
|
145
|
+
if (contentTypeHeader.kind === "literal") return {
|
|
146
|
+
body: createNormalizedBody({
|
|
147
|
+
schema: input.bodySchema,
|
|
148
|
+
mediaType: contentTypeHeader.value,
|
|
149
|
+
mediaTypeSource: "content-type-header"
|
|
150
|
+
}),
|
|
151
|
+
warnings
|
|
152
|
+
};
|
|
153
|
+
if (contentTypeHeader.kind === "ambiguous") warnings.push({
|
|
154
|
+
code: "ambiguous-content-type-header",
|
|
155
|
+
message: "Content-Type header is present but does not have one unambiguous literal value; inferred body media type instead.",
|
|
156
|
+
location: input.location
|
|
157
|
+
});
|
|
158
|
+
else warnings.push({
|
|
159
|
+
code: "missing-content-type-header",
|
|
160
|
+
message: "Body schema is present without a Content-Type header; inferred body media type from schema.",
|
|
161
|
+
location: input.location
|
|
162
|
+
});
|
|
163
|
+
const inferred = inferBodyMediaType(input.bodySchema);
|
|
164
|
+
if (inferred.mediaTypeSource === "raw-fallback") warnings.push({
|
|
165
|
+
code: "raw-body-media-type-fallback",
|
|
166
|
+
message: "Body schema does not imply a concrete media type; used application/octet-stream raw transport fallback.",
|
|
167
|
+
location: input.location
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
body: createNormalizedBody({
|
|
171
|
+
schema: input.bodySchema,
|
|
172
|
+
...inferred
|
|
173
|
+
}),
|
|
174
|
+
warnings
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
const createNormalizedBody = (input) => {
|
|
178
|
+
return {
|
|
179
|
+
schema: input.schema,
|
|
180
|
+
mediaType: input.mediaType,
|
|
181
|
+
mediaTypeSource: input.mediaTypeSource,
|
|
182
|
+
transport: resolveTransport(input.mediaType)
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
const extractContentTypeHeader = (headerSchema) => {
|
|
186
|
+
const headerObject = unwrapOptional(headerSchema);
|
|
187
|
+
if (headerObject === void 0 || !isZodObject$1(headerObject)) return { kind: "absent" };
|
|
188
|
+
const contentTypeEntries = Object.entries(headerObject.shape).filter(([headerName]) => headerName.toLowerCase() === "content-type");
|
|
189
|
+
if (contentTypeEntries.length === 0) return { kind: "absent" };
|
|
190
|
+
const literalValues = contentTypeEntries.flatMap(([, schema]) => extractStringLiteralValues(schema));
|
|
191
|
+
const distinctValues = new Set(literalValues);
|
|
192
|
+
if (contentTypeEntries.length === 1 && distinctValues.size === 1) {
|
|
193
|
+
const [value] = distinctValues;
|
|
194
|
+
return value === void 0 ? { kind: "ambiguous" } : {
|
|
195
|
+
kind: "literal",
|
|
196
|
+
value
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return { kind: "ambiguous" };
|
|
200
|
+
};
|
|
201
|
+
const inferBodyMediaType = (schema) => {
|
|
202
|
+
const inferenceSchema = unwrapMediaInferenceSchema(schema);
|
|
203
|
+
const schemaType = getSchemaType(inferenceSchema);
|
|
204
|
+
if (isTextBodySchema(inferenceSchema)) return {
|
|
205
|
+
mediaType: "text/plain",
|
|
206
|
+
mediaTypeSource: "body-schema"
|
|
207
|
+
};
|
|
208
|
+
if (schemaType === "any" || schemaType === "unknown") return {
|
|
209
|
+
mediaType: "application/octet-stream",
|
|
210
|
+
mediaTypeSource: "raw-fallback"
|
|
211
|
+
};
|
|
212
|
+
if (schemaType !== void 0 && JSON_BODY_SCHEMA_TYPES.has(schemaType)) return {
|
|
213
|
+
mediaType: "application/json",
|
|
214
|
+
mediaTypeSource: "body-schema"
|
|
215
|
+
};
|
|
216
|
+
return {
|
|
217
|
+
mediaType: "application/octet-stream",
|
|
218
|
+
mediaTypeSource: "raw-fallback"
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
const isTextBodySchema = (schema) => {
|
|
222
|
+
const schemaType = getSchemaType(schema);
|
|
223
|
+
if (schemaType === "string") return true;
|
|
224
|
+
if (schemaType === "literal") {
|
|
225
|
+
const values = literalSchemaValues(schema);
|
|
226
|
+
return values.length > 0 && values.every((value) => typeof value === "string");
|
|
227
|
+
}
|
|
228
|
+
if (schemaType === "enum") {
|
|
229
|
+
const values = enumSchemaValues(schema);
|
|
230
|
+
return values.length > 0 && values.every((value) => typeof value === "string");
|
|
231
|
+
}
|
|
232
|
+
return false;
|
|
233
|
+
};
|
|
234
|
+
const resolveTransport = (mediaType) => {
|
|
235
|
+
const normalizedMediaType = mediaType.split(";")[0]?.trim().toLowerCase();
|
|
236
|
+
if (normalizedMediaType === "application/json" || normalizedMediaType?.endsWith("+json") === true) return "json";
|
|
237
|
+
if (normalizedMediaType?.startsWith("text/") === true) return "text";
|
|
238
|
+
if (normalizedMediaType === "application/x-www-form-urlencoded") return "form-url-encoded";
|
|
239
|
+
if (normalizedMediaType === "multipart/form-data") return "multipart";
|
|
240
|
+
return "raw";
|
|
241
|
+
};
|
|
242
|
+
const unwrapMediaInferenceSchema = (schema) => {
|
|
243
|
+
const visitedSchemas = /* @__PURE__ */ new Set();
|
|
244
|
+
let current = schema;
|
|
245
|
+
while (current !== void 0 && !visitedSchemas.has(current)) {
|
|
246
|
+
visitedSchemas.add(current);
|
|
247
|
+
const definition = getSchemaDefinition(current);
|
|
248
|
+
const schemaType = definition?.type;
|
|
249
|
+
if (schemaType === "optional" || schemaType === "nullable" || schemaType === "default" || schemaType === "catch" || schemaType === "prefault" || schemaType === "readonly") {
|
|
250
|
+
current = definition?.innerType;
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
if (schemaType === "pipe") {
|
|
254
|
+
const outputType = getSchemaType(definition?.out);
|
|
255
|
+
if (outputType === void 0 || outputType === "transform") return;
|
|
256
|
+
current = definition?.out;
|
|
257
|
+
continue;
|
|
258
|
+
}
|
|
259
|
+
if (schemaType === "effects") {
|
|
260
|
+
current = definition?.schema;
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
return current;
|
|
264
|
+
}
|
|
265
|
+
return current;
|
|
266
|
+
};
|
|
267
|
+
const unwrapOptional = (schema) => {
|
|
268
|
+
return schema instanceof zod.z.ZodOptional ? schema.unwrap() : schema;
|
|
269
|
+
};
|
|
270
|
+
const isZodObject$1 = (schema) => {
|
|
271
|
+
return getSchemaType(schema) === "object" && "shape" in schema;
|
|
272
|
+
};
|
|
273
|
+
const extractStringLiteralValues = (schema) => {
|
|
274
|
+
const unwrappedSchema = unwrapOptional(schema);
|
|
275
|
+
if (unwrappedSchema === void 0) return [];
|
|
276
|
+
if (getSchemaType(unwrappedSchema) === "literal") return literalSchemaValues(unwrappedSchema).filter((value) => typeof value === "string");
|
|
277
|
+
if (getSchemaType(unwrappedSchema) === "enum") return enumSchemaValues(unwrappedSchema).filter((value) => typeof value === "string");
|
|
278
|
+
return [];
|
|
279
|
+
};
|
|
280
|
+
const literalSchemaValues = (schema) => {
|
|
281
|
+
const literalSchema = schema;
|
|
282
|
+
return Array.from(literalSchema?.values ?? []);
|
|
283
|
+
};
|
|
284
|
+
const enumSchemaValues = (schema) => {
|
|
285
|
+
const enumSchema = schema;
|
|
286
|
+
return enumSchema?.options ?? enumSchema?.def?.values ?? Object.values(enumSchema?.def?.entries ?? enumSchema?.enum ?? {});
|
|
287
|
+
};
|
|
288
|
+
const getSchemaType = (schema) => {
|
|
289
|
+
return getSchemaDefinition(schema)?.type;
|
|
290
|
+
};
|
|
291
|
+
const getSchemaDefinition = (schema) => {
|
|
292
|
+
const schemaWithDefinition = schema;
|
|
293
|
+
return schemaWithDefinition?.def ?? schemaWithDefinition?._def;
|
|
294
|
+
};
|
|
295
|
+
//#endregion
|
|
127
296
|
//#region src/helpers/namingUtils.ts
|
|
128
297
|
const startsWithDigit = (value) => /^[0-9]/u.test(value);
|
|
129
298
|
const isSupportedIdentifierName = (value) => {
|
|
@@ -198,25 +367,49 @@ const validateInlineDerivedResponses = (definition, canonicalResponses) => {
|
|
|
198
367
|
validateDerivedResponseAgainstCanonicalGraph(response, canonicalResponses);
|
|
199
368
|
}
|
|
200
369
|
};
|
|
201
|
-
const normalizeResponseDefinition = (response) => {
|
|
370
|
+
const normalizeResponseDefinition = (response, location) => {
|
|
371
|
+
const body = normalizeBody({
|
|
372
|
+
bodySchema: response.body,
|
|
373
|
+
headerSchema: response.header,
|
|
374
|
+
location: {
|
|
375
|
+
...location,
|
|
376
|
+
part: "response.body"
|
|
377
|
+
}
|
|
378
|
+
});
|
|
202
379
|
return {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
380
|
+
response: {
|
|
381
|
+
name: response.name,
|
|
382
|
+
statusCode: response.statusCode,
|
|
383
|
+
statusCodeName: _rexeus_typeweaver_core.HttpStatusCodeNameMap[response.statusCode],
|
|
384
|
+
description: response.description,
|
|
385
|
+
header: response.header,
|
|
386
|
+
body: body.body,
|
|
387
|
+
kind: response.derived === void 0 ? "response" : "derived-response",
|
|
388
|
+
derivedFrom: response.derived?.parentName,
|
|
389
|
+
lineage: response.derived?.lineage,
|
|
390
|
+
depth: response.derived?.depth
|
|
391
|
+
},
|
|
392
|
+
warnings: body.warnings
|
|
213
393
|
};
|
|
214
394
|
};
|
|
215
395
|
const collectCanonicalResponses = (definition) => {
|
|
216
396
|
const canonicalResponseDefinitions = collectCanonicalResponseDefinitions(definition);
|
|
397
|
+
const warnings = [];
|
|
217
398
|
validateDerivedResponseGraph(canonicalResponseDefinitions);
|
|
218
399
|
validateInlineDerivedResponses(definition, canonicalResponseDefinitions);
|
|
219
|
-
|
|
400
|
+
const responses = /* @__PURE__ */ new Map();
|
|
401
|
+
for (const [responseName, response] of canonicalResponseDefinitions) {
|
|
402
|
+
const normalized = normalizeResponseDefinition(response, {
|
|
403
|
+
responseName,
|
|
404
|
+
statusCode: response.statusCode
|
|
405
|
+
});
|
|
406
|
+
responses.set(responseName, normalized.response);
|
|
407
|
+
warnings.push(...normalized.warnings);
|
|
408
|
+
}
|
|
409
|
+
return {
|
|
410
|
+
responses,
|
|
411
|
+
warnings
|
|
412
|
+
};
|
|
220
413
|
};
|
|
221
414
|
//#endregion
|
|
222
415
|
//#region src/normalizeSpec.ts
|
|
@@ -230,7 +423,7 @@ const validateRequestSchema = (operationId, requestPart, schema) => {
|
|
|
230
423
|
if (!isZodType(schema)) throw new InvalidRequestSchemaError(operationId, requestPart);
|
|
231
424
|
if (requestPart === "param" && !isZodObject(schema)) throw new InvalidRequestSchemaError(operationId, requestPart);
|
|
232
425
|
};
|
|
233
|
-
const validateRequest = (operationId, path, request) => {
|
|
426
|
+
const validateRequest = (resourceName, operationId, path, request) => {
|
|
234
427
|
if (request.header !== void 0) validateRequestSchema(operationId, "header", request.header);
|
|
235
428
|
if (request.param !== void 0) validateRequestSchema(operationId, "param", request.param);
|
|
236
429
|
if (request.query !== void 0) validateRequestSchema(operationId, "query", request.query);
|
|
@@ -238,28 +431,51 @@ const validateRequest = (operationId, path, request) => {
|
|
|
238
431
|
const pathParams = getPathParameterNames(path);
|
|
239
432
|
const requestParams = request.param === void 0 ? [] : Object.keys(request.param.shape);
|
|
240
433
|
if (pathParams.length !== requestParams.length || pathParams.some((pathParam) => !requestParams.includes(pathParam))) throw new PathParameterMismatchError(operationId, path, pathParams, requestParams);
|
|
241
|
-
if (request.header === void 0 && request.param === void 0 && request.query === void 0 && request.body === void 0) return;
|
|
434
|
+
if (request.header === void 0 && request.param === void 0 && request.query === void 0 && request.body === void 0) return { warnings: [] };
|
|
435
|
+
const body = normalizeBody({
|
|
436
|
+
bodySchema: request.body,
|
|
437
|
+
headerSchema: request.header,
|
|
438
|
+
location: {
|
|
439
|
+
resourceName,
|
|
440
|
+
operationId,
|
|
441
|
+
part: "request.body"
|
|
442
|
+
}
|
|
443
|
+
});
|
|
242
444
|
return {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
445
|
+
request: {
|
|
446
|
+
header: request.header,
|
|
447
|
+
param: request.param,
|
|
448
|
+
query: request.query,
|
|
449
|
+
body: body.body
|
|
450
|
+
},
|
|
451
|
+
warnings: body.warnings
|
|
247
452
|
};
|
|
248
453
|
};
|
|
249
|
-
const normalizeOperationResponses = (responses) => {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
454
|
+
const normalizeOperationResponses = (resourceName, operationId, responses) => {
|
|
455
|
+
const warnings = [];
|
|
456
|
+
return {
|
|
457
|
+
responses: responses.map((response) => {
|
|
458
|
+
if ((0, _rexeus_typeweaver_core.isNamedResponseDefinition)(response)) return {
|
|
459
|
+
responseName: response.name,
|
|
460
|
+
source: "canonical"
|
|
461
|
+
};
|
|
462
|
+
const normalized = normalizeResponseDefinition(response, {
|
|
463
|
+
resourceName,
|
|
464
|
+
operationId,
|
|
465
|
+
responseName: response.name,
|
|
466
|
+
statusCode: response.statusCode
|
|
467
|
+
});
|
|
468
|
+
warnings.push(...normalized.warnings);
|
|
469
|
+
return {
|
|
470
|
+
responseName: response.name,
|
|
471
|
+
source: "inline",
|
|
472
|
+
response: normalized.response
|
|
473
|
+
};
|
|
474
|
+
}),
|
|
475
|
+
warnings
|
|
476
|
+
};
|
|
261
477
|
};
|
|
262
|
-
const normalizeOperation = (operationIds, routeKeys, operation) => {
|
|
478
|
+
const normalizeOperation = (resourceName, operationIds, routeKeys, operation) => {
|
|
263
479
|
if (!isSupportedOperationId(operation.operationId)) throw new InvalidOperationIdError(operation.operationId);
|
|
264
480
|
if (operationIds.has(operation.operationId)) throw new DuplicateOperationIdError(operation.operationId);
|
|
265
481
|
operationIds.add(operation.operationId);
|
|
@@ -268,13 +484,18 @@ const normalizeOperation = (operationIds, routeKeys, operation) => {
|
|
|
268
484
|
if (routeKeys.has(routeKey)) throw new DuplicateRouteError(operation.method, operation.path, normalizedPath);
|
|
269
485
|
routeKeys.add(routeKey);
|
|
270
486
|
if (operation.responses.length === 0) throw new EmptyOperationResponsesError(operation.operationId);
|
|
487
|
+
const request = validateRequest(resourceName, operation.operationId, operation.path, operation.request);
|
|
488
|
+
const responses = normalizeOperationResponses(resourceName, operation.operationId, operation.responses);
|
|
271
489
|
return {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
490
|
+
operation: {
|
|
491
|
+
operationId: operation.operationId,
|
|
492
|
+
method: operation.method,
|
|
493
|
+
path: operation.path,
|
|
494
|
+
summary: operation.summary,
|
|
495
|
+
request: request.request,
|
|
496
|
+
responses: responses.responses
|
|
497
|
+
},
|
|
498
|
+
warnings: [...request.warnings, ...responses.warnings]
|
|
278
499
|
};
|
|
279
500
|
};
|
|
280
501
|
const normalizeSpec = (definition) => {
|
|
@@ -284,16 +505,22 @@ const normalizeSpec = (definition) => {
|
|
|
284
505
|
const canonicalResponses = collectCanonicalResponses(definition);
|
|
285
506
|
const operationIds = /* @__PURE__ */ new Set();
|
|
286
507
|
const routeKeys = /* @__PURE__ */ new Set();
|
|
508
|
+
const warnings = [...canonicalResponses.warnings];
|
|
287
509
|
return {
|
|
288
510
|
resources: resourceEntries.map(([resourceName, resource]) => {
|
|
289
511
|
if (!isSupportedResourceName(resourceName)) throw new InvalidResourceNameError(resourceName);
|
|
290
512
|
if (resource.operations.length === 0) throw new EmptyResourceOperationsError(resourceName);
|
|
291
513
|
return {
|
|
292
514
|
name: resourceName,
|
|
293
|
-
operations: resource.operations.map((operation) =>
|
|
515
|
+
operations: resource.operations.map((operation) => {
|
|
516
|
+
const normalized = normalizeOperation(resourceName, operationIds, routeKeys, operation);
|
|
517
|
+
warnings.push(...normalized.warnings);
|
|
518
|
+
return normalized.operation;
|
|
519
|
+
})
|
|
294
520
|
};
|
|
295
521
|
}),
|
|
296
|
-
responses: Array.from(canonicalResponses.values())
|
|
522
|
+
responses: Array.from(canonicalResponses.responses.values()),
|
|
523
|
+
warnings
|
|
297
524
|
};
|
|
298
525
|
};
|
|
299
526
|
//#endregion
|
|
@@ -478,6 +705,112 @@ var MissingCanonicalResponseError = class extends Error {
|
|
|
478
705
|
};
|
|
479
706
|
//#endregion
|
|
480
707
|
//#region src/plugins/pluginContext.ts
|
|
708
|
+
const WINDOWS_DRIVE_PREFIX_PATTERN = /^[a-zA-Z]:/;
|
|
709
|
+
function pathContainsParentTraversal(projectPath) {
|
|
710
|
+
return projectPath.split("/").includes("..");
|
|
711
|
+
}
|
|
712
|
+
function pathEndsWithDirectorySeparator(projectPath) {
|
|
713
|
+
return projectPath.endsWith("/");
|
|
714
|
+
}
|
|
715
|
+
function pathNamesCurrentDirectory(projectPath) {
|
|
716
|
+
return projectPath === "." || projectPath.endsWith("/.");
|
|
717
|
+
}
|
|
718
|
+
function resolveSafeGeneratedFilePath(outputDir, requestedPath) {
|
|
719
|
+
if (requestedPath.length === 0) throwUnsafeGeneratedFilePath(requestedPath, "path must not be empty");
|
|
720
|
+
const projectPath = requestedPath.replace(/\\/g, "/");
|
|
721
|
+
if (node_path.default.isAbsolute(requestedPath) || node_path.default.posix.isAbsolute(projectPath) || node_path.default.win32.isAbsolute(requestedPath) || node_path.default.win32.isAbsolute(projectPath) || WINDOWS_DRIVE_PREFIX_PATTERN.test(requestedPath)) throwUnsafeGeneratedFilePath(requestedPath, "absolute paths are not allowed");
|
|
722
|
+
if (pathContainsParentTraversal(projectPath)) throwUnsafeGeneratedFilePath(requestedPath, "path contains parent-directory traversal");
|
|
723
|
+
if (pathEndsWithDirectorySeparator(projectPath)) throwUnsafeGeneratedFilePath(requestedPath, "path must name a file inside the output directory");
|
|
724
|
+
if (pathNamesCurrentDirectory(projectPath)) throwUnsafeGeneratedFilePath(requestedPath, "path must name a file inside the output directory");
|
|
725
|
+
const generatedPath = node_path.default.posix.normalize(projectPath);
|
|
726
|
+
if (generatedPath === ".") throwUnsafeGeneratedFilePath(requestedPath, "path must name a file inside the output directory");
|
|
727
|
+
if (pathContainsParentTraversal(generatedPath)) throwUnsafeGeneratedFilePath(requestedPath, "path contains parent-directory traversal");
|
|
728
|
+
const outputRoot = node_path.default.resolve(outputDir);
|
|
729
|
+
const fullPath = node_path.default.resolve(outputRoot, toNativePath(generatedPath));
|
|
730
|
+
if (!isStrictlyInsidePath(fullPath, outputRoot)) throwUnsafeGeneratedFilePath(requestedPath, "path escapes the output directory");
|
|
731
|
+
assertGeneratedPathHasNoSymlinkComponents({
|
|
732
|
+
outputRoot,
|
|
733
|
+
generatedPath,
|
|
734
|
+
requestedPath
|
|
735
|
+
});
|
|
736
|
+
return {
|
|
737
|
+
fullPath,
|
|
738
|
+
generatedPath
|
|
739
|
+
};
|
|
740
|
+
}
|
|
741
|
+
function toNativePath(projectPath) {
|
|
742
|
+
return projectPath.split("/").join(node_path.default.sep);
|
|
743
|
+
}
|
|
744
|
+
function assertGeneratedPathHasNoSymlinkComponents(config) {
|
|
745
|
+
assertExistingPathIsNotSymlink(config.outputRoot, config.requestedPath);
|
|
746
|
+
let currentPath = config.outputRoot;
|
|
747
|
+
for (const segment of config.generatedPath.split("/")) {
|
|
748
|
+
currentPath = node_path.default.join(currentPath, segment);
|
|
749
|
+
const pathStats = getExistingPathStats(currentPath);
|
|
750
|
+
if (pathStats === void 0) return;
|
|
751
|
+
assertPathStatsIsNotSymlink(pathStats, config.requestedPath);
|
|
752
|
+
if (!pathStats.isDirectory()) return;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
function assertExistingPathIsNotSymlink(absolutePath, requestedPath) {
|
|
756
|
+
const pathStats = getExistingPathStats(absolutePath);
|
|
757
|
+
if (pathStats === void 0) return;
|
|
758
|
+
assertPathStatsIsNotSymlink(pathStats, requestedPath);
|
|
759
|
+
}
|
|
760
|
+
function assertPathStatsIsNotSymlink(pathStats, requestedPath) {
|
|
761
|
+
if (!pathStats.isSymbolicLink()) return;
|
|
762
|
+
throwUnsafeGeneratedFilePath(requestedPath, "path contains a symbolic link");
|
|
763
|
+
}
|
|
764
|
+
function getExistingPathStats(absolutePath) {
|
|
765
|
+
try {
|
|
766
|
+
return node_fs.default.lstatSync(absolutePath);
|
|
767
|
+
} catch (error) {
|
|
768
|
+
if (isMissingPathError(error)) return;
|
|
769
|
+
throw error;
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
function isMissingPathError(error) {
|
|
773
|
+
if (!(error instanceof Error)) return false;
|
|
774
|
+
return ["ENOENT", "ENOTDIR"].includes(error.code ?? "");
|
|
775
|
+
}
|
|
776
|
+
function isStrictlyInsidePath(childPath, parentPath) {
|
|
777
|
+
const relativePath = node_path.default.relative(parentPath, childPath);
|
|
778
|
+
return relativePath !== "" && relativePath !== ".." && !relativePath.startsWith(`..${node_path.default.sep}`) && !node_path.default.isAbsolute(relativePath);
|
|
779
|
+
}
|
|
780
|
+
function throwUnsafeGeneratedFilePath(requestedPath, reason) {
|
|
781
|
+
throw new Error(`Unsafe generated file path '${requestedPath}': ${reason}. Generated writes must stay inside the output directory.`);
|
|
782
|
+
}
|
|
783
|
+
function revalidateGeneratedWritePath(outputDir, generatedPath) {
|
|
784
|
+
return resolveSafeGeneratedFilePath(outputDir, generatedPath);
|
|
785
|
+
}
|
|
786
|
+
function writeGeneratedFileByReplacingDestination(config) {
|
|
787
|
+
const existingFileMode = getExistingFileMode(revalidateGeneratedWritePath(config.outputDir, config.generatedPath).fullPath);
|
|
788
|
+
const tempParentPath = revalidateGeneratedWritePath(config.outputDir, config.generatedPath);
|
|
789
|
+
const destinationDir = node_path.default.dirname(tempParentPath.fullPath);
|
|
790
|
+
const tempDir = node_fs.default.mkdtempSync(node_path.default.join(destinationDir, ".typeweaver-"));
|
|
791
|
+
const tempFile = node_path.default.join(tempDir, "generated.tmp");
|
|
792
|
+
try {
|
|
793
|
+
revalidateGeneratedWritePath(config.outputDir, config.generatedPath);
|
|
794
|
+
node_fs.default.writeFileSync(tempFile, config.content, {
|
|
795
|
+
flag: "wx",
|
|
796
|
+
mode: existingFileMode ?? 438
|
|
797
|
+
});
|
|
798
|
+
if (existingFileMode !== void 0) node_fs.default.chmodSync(tempFile, existingFileMode);
|
|
799
|
+
const writablePath = revalidateGeneratedWritePath(config.outputDir, config.generatedPath);
|
|
800
|
+
node_fs.default.renameSync(tempFile, writablePath.fullPath);
|
|
801
|
+
return writablePath;
|
|
802
|
+
} finally {
|
|
803
|
+
node_fs.default.rmSync(tempDir, {
|
|
804
|
+
recursive: true,
|
|
805
|
+
force: true
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
function getExistingFileMode(absolutePath) {
|
|
810
|
+
const pathStats = getExistingPathStats(absolutePath);
|
|
811
|
+
if (pathStats?.isFile() !== true) return;
|
|
812
|
+
return pathStats.mode & 511;
|
|
813
|
+
}
|
|
481
814
|
function createPluginContextBuilder() {
|
|
482
815
|
const generatedFiles = /* @__PURE__ */ new Set();
|
|
483
816
|
const createPluginContext = (params) => {
|
|
@@ -543,19 +876,25 @@ function createPluginContextBuilder() {
|
|
|
543
876
|
getOperationOutputPaths,
|
|
544
877
|
getResourceOutputDir,
|
|
545
878
|
writeFile: (relativePath, content) => {
|
|
546
|
-
const
|
|
547
|
-
const dir = node_path.default.dirname(fullPath);
|
|
879
|
+
const safePath = resolveSafeGeneratedFilePath(params.outputDir, relativePath);
|
|
880
|
+
const dir = node_path.default.dirname(safePath.fullPath);
|
|
548
881
|
node_fs.default.mkdirSync(dir, { recursive: true });
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
882
|
+
const writablePath = revalidateGeneratedWritePath(params.outputDir, safePath.generatedPath);
|
|
883
|
+
const generatedFile = writeGeneratedFileByReplacingDestination({
|
|
884
|
+
outputDir: params.outputDir,
|
|
885
|
+
generatedPath: writablePath.generatedPath,
|
|
886
|
+
content
|
|
887
|
+
});
|
|
888
|
+
generatedFiles.add(generatedFile.generatedPath);
|
|
889
|
+
console.info(`Generated: ${generatedFile.generatedPath}`);
|
|
552
890
|
},
|
|
553
891
|
renderTemplate: (templatePath, data) => {
|
|
554
892
|
const fullTemplatePath = node_path.default.isAbsolute(templatePath) ? templatePath : node_path.default.join(params.templateDir, templatePath);
|
|
555
893
|
return renderTemplate(node_fs.default.readFileSync(fullTemplatePath, "utf8"), data ?? {});
|
|
556
894
|
},
|
|
557
895
|
addGeneratedFile: (relativePath) => {
|
|
558
|
-
|
|
896
|
+
const safePath = resolveSafeGeneratedFilePath(params.outputDir, relativePath);
|
|
897
|
+
generatedFiles.add(safePath.generatedPath);
|
|
559
898
|
},
|
|
560
899
|
getGeneratedFiles: () => {
|
|
561
900
|
return Array.from(generatedFiles);
|
package/dist/index.d.cts
CHANGED
|
@@ -44,6 +44,28 @@ declare class InvalidOperationIdError extends Error {
|
|
|
44
44
|
type NormalizedSpec = {
|
|
45
45
|
readonly resources: readonly NormalizedResource[];
|
|
46
46
|
readonly responses: readonly NormalizedResponse[];
|
|
47
|
+
readonly warnings: readonly NormalizedSpecWarning[];
|
|
48
|
+
};
|
|
49
|
+
type NormalizedBodyMediaTypeSource = "content-type-header" | "body-schema" | "raw-fallback";
|
|
50
|
+
type NormalizedBodyTransport = "json" | "text" | "form-url-encoded" | "multipart" | "raw";
|
|
51
|
+
type NormalizedHttpBody = {
|
|
52
|
+
readonly schema: HttpBodySchema;
|
|
53
|
+
readonly mediaType: string;
|
|
54
|
+
readonly mediaTypeSource: NormalizedBodyMediaTypeSource;
|
|
55
|
+
readonly transport: NormalizedBodyTransport;
|
|
56
|
+
};
|
|
57
|
+
type NormalizedSpecWarningCode = "ambiguous-content-type-header" | "missing-content-type-header" | "raw-body-media-type-fallback";
|
|
58
|
+
type NormalizedSpecWarningLocation = {
|
|
59
|
+
readonly part: "request.body" | "response.body";
|
|
60
|
+
readonly resourceName?: string;
|
|
61
|
+
readonly operationId?: string;
|
|
62
|
+
readonly responseName?: string;
|
|
63
|
+
readonly statusCode?: HttpStatusCode;
|
|
64
|
+
};
|
|
65
|
+
type NormalizedSpecWarning = {
|
|
66
|
+
readonly code: NormalizedSpecWarningCode;
|
|
67
|
+
readonly message: string;
|
|
68
|
+
readonly location: NormalizedSpecWarningLocation;
|
|
47
69
|
};
|
|
48
70
|
type NormalizedResource = {
|
|
49
71
|
readonly name: string;
|
|
@@ -61,7 +83,7 @@ type NormalizedRequest = {
|
|
|
61
83
|
readonly header?: HttpHeaderSchema;
|
|
62
84
|
readonly param?: HttpParamSchema;
|
|
63
85
|
readonly query?: HttpQuerySchema;
|
|
64
|
-
readonly body?:
|
|
86
|
+
readonly body?: NormalizedHttpBody;
|
|
65
87
|
};
|
|
66
88
|
type NormalizedResponse = {
|
|
67
89
|
readonly name: string;
|
|
@@ -69,7 +91,7 @@ type NormalizedResponse = {
|
|
|
69
91
|
readonly statusCodeName: string;
|
|
70
92
|
readonly description: string;
|
|
71
93
|
readonly header?: HttpHeaderSchema;
|
|
72
|
-
readonly body?:
|
|
94
|
+
readonly body?: NormalizedHttpBody;
|
|
73
95
|
readonly kind: "response" | "derived-response";
|
|
74
96
|
readonly derivedFrom?: string;
|
|
75
97
|
readonly lineage?: readonly string[];
|
|
@@ -347,5 +369,5 @@ declare const compareRoutes: (a: {
|
|
|
347
369
|
//#region src/helpers/templateEngine.d.ts
|
|
348
370
|
declare function renderTemplate(template: string, data: Record<string, unknown>): string;
|
|
349
371
|
//#endregion
|
|
350
|
-
export { BasePlugin, CreateJSDocCommentOptions, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidOperationIdError, InvalidRequestSchemaError, InvalidResourceNameError, MissingDerivedResponseParentError, NormalizedCanonicalResponseUsage, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createJSDocComment, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, isSupportedOperationId, isSupportedResourceName, normalizeRoutePath, normalizeSpec, relative, renderTemplate };
|
|
372
|
+
export { BasePlugin, CreateJSDocCommentOptions, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidOperationIdError, InvalidRequestSchemaError, InvalidResourceNameError, MissingDerivedResponseParentError, NormalizedBodyMediaTypeSource, NormalizedBodyTransport, NormalizedCanonicalResponseUsage, NormalizedHttpBody, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, NormalizedSpecWarning, NormalizedSpecWarningCode, NormalizedSpecWarningLocation, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createJSDocComment, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, isSupportedOperationId, isSupportedResourceName, normalizeRoutePath, normalizeSpec, relative, renderTemplate };
|
|
351
373
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/errors/InvalidOperationIdError.ts","../src/NormalizedSpec.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/InvalidResourceNameError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/plugins/pluginContext.ts","../src/helpers/namingUtils.ts","../src/helpers/jsdoc.ts","../src/helpers/path.ts","../src/helpers/routePath.ts","../src/helpers/routeSort.ts","../src/helpers/templateEngine.ts"],"mappings":";;;cAAa,yBAAA,SAAkC,KAAA;cAC1B,YAAA;AAAA;;;cCDR,yBAAA,SAAkC,KAAA;cAC1B,WAAA;AAAA;;;cCDR,mBAAA,SAA4B,KAAA;cACpB,MAAA,UAAgB,IAAA,UAAc,cAAA;AAAA;;;cCDtC,4BAAA,SAAqC,KAAA;cAC7B,WAAA;AAAA;;;cCDR,4BAAA,SAAqC,KAAA;cAC7B,YAAA;AAAA;;;cCDR,uBAAA,SAAgC,KAAA;EAAA,WAAA,CAAA;AAAA;;;cCAhC,2BAAA,SAAoC,KAAA;cAC5B,YAAA;AAAA;;;cCDR,uBAAA,SAAgC,KAAA;cACxB,WAAA;AAAA;;;KCQT,cAAA;EAAA,SACD,SAAA,WAAoB,kBAAA;EAAA,SACpB,SAAA,WAAoB,kBAAA;AAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/errors/DerivedResponseCycleError.ts","../src/errors/DuplicateOperationIdError.ts","../src/errors/DuplicateRouteError.ts","../src/errors/EmptyOperationResponsesError.ts","../src/errors/EmptyResourceOperationsError.ts","../src/errors/EmptySpecResourcesError.ts","../src/errors/InvalidDerivedResponseError.ts","../src/errors/InvalidOperationIdError.ts","../src/NormalizedSpec.ts","../src/errors/InvalidRequestSchemaError.ts","../src/errors/InvalidResourceNameError.ts","../src/errors/MissingDerivedResponseParentError.ts","../src/errors/PathParameterMismatchError.ts","../src/normalizeSpec.ts","../src/plugins/types.ts","../src/plugins/BasePlugin.ts","../src/plugins/pluginRegistry.ts","../src/plugins/pluginContext.ts","../src/helpers/namingUtils.ts","../src/helpers/jsdoc.ts","../src/helpers/path.ts","../src/helpers/routePath.ts","../src/helpers/routeSort.ts","../src/helpers/templateEngine.ts"],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -44,6 +44,28 @@ declare class InvalidOperationIdError extends Error {
|
|
|
44
44
|
type NormalizedSpec = {
|
|
45
45
|
readonly resources: readonly NormalizedResource[];
|
|
46
46
|
readonly responses: readonly NormalizedResponse[];
|
|
47
|
+
readonly warnings: readonly NormalizedSpecWarning[];
|
|
48
|
+
};
|
|
49
|
+
type NormalizedBodyMediaTypeSource = "content-type-header" | "body-schema" | "raw-fallback";
|
|
50
|
+
type NormalizedBodyTransport = "json" | "text" | "form-url-encoded" | "multipart" | "raw";
|
|
51
|
+
type NormalizedHttpBody = {
|
|
52
|
+
readonly schema: HttpBodySchema;
|
|
53
|
+
readonly mediaType: string;
|
|
54
|
+
readonly mediaTypeSource: NormalizedBodyMediaTypeSource;
|
|
55
|
+
readonly transport: NormalizedBodyTransport;
|
|
56
|
+
};
|
|
57
|
+
type NormalizedSpecWarningCode = "ambiguous-content-type-header" | "missing-content-type-header" | "raw-body-media-type-fallback";
|
|
58
|
+
type NormalizedSpecWarningLocation = {
|
|
59
|
+
readonly part: "request.body" | "response.body";
|
|
60
|
+
readonly resourceName?: string;
|
|
61
|
+
readonly operationId?: string;
|
|
62
|
+
readonly responseName?: string;
|
|
63
|
+
readonly statusCode?: HttpStatusCode;
|
|
64
|
+
};
|
|
65
|
+
type NormalizedSpecWarning = {
|
|
66
|
+
readonly code: NormalizedSpecWarningCode;
|
|
67
|
+
readonly message: string;
|
|
68
|
+
readonly location: NormalizedSpecWarningLocation;
|
|
47
69
|
};
|
|
48
70
|
type NormalizedResource = {
|
|
49
71
|
readonly name: string;
|
|
@@ -61,7 +83,7 @@ type NormalizedRequest = {
|
|
|
61
83
|
readonly header?: HttpHeaderSchema;
|
|
62
84
|
readonly param?: HttpParamSchema;
|
|
63
85
|
readonly query?: HttpQuerySchema;
|
|
64
|
-
readonly body?:
|
|
86
|
+
readonly body?: NormalizedHttpBody;
|
|
65
87
|
};
|
|
66
88
|
type NormalizedResponse = {
|
|
67
89
|
readonly name: string;
|
|
@@ -69,7 +91,7 @@ type NormalizedResponse = {
|
|
|
69
91
|
readonly statusCodeName: string;
|
|
70
92
|
readonly description: string;
|
|
71
93
|
readonly header?: HttpHeaderSchema;
|
|
72
|
-
readonly body?:
|
|
94
|
+
readonly body?: NormalizedHttpBody;
|
|
73
95
|
readonly kind: "response" | "derived-response";
|
|
74
96
|
readonly derivedFrom?: string;
|
|
75
97
|
readonly lineage?: readonly string[];
|
|
@@ -347,5 +369,5 @@ declare const compareRoutes: (a: {
|
|
|
347
369
|
//#region src/helpers/templateEngine.d.ts
|
|
348
370
|
declare function renderTemplate(template: string, data: Record<string, unknown>): string;
|
|
349
371
|
//#endregion
|
|
350
|
-
export { BasePlugin, CreateJSDocCommentOptions, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidOperationIdError, InvalidRequestSchemaError, InvalidResourceNameError, MissingDerivedResponseParentError, NormalizedCanonicalResponseUsage, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createJSDocComment, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, isSupportedOperationId, isSupportedResourceName, normalizeRoutePath, normalizeSpec, relative, renderTemplate };
|
|
372
|
+
export { BasePlugin, CreateJSDocCommentOptions, DerivedResponseCycleError, DuplicateOperationIdError, DuplicateRouteError, EmptyOperationResponsesError, EmptyResourceOperationsError, EmptySpecResourcesError, GeneratorContext, InvalidDerivedResponseError, InvalidOperationIdError, InvalidRequestSchemaError, InvalidResourceNameError, MissingDerivedResponseParentError, NormalizedBodyMediaTypeSource, NormalizedBodyTransport, NormalizedCanonicalResponseUsage, NormalizedHttpBody, NormalizedInlineResponseUsage, NormalizedOperation, NormalizedRequest, NormalizedResource, NormalizedResponse, NormalizedResponseUsage, NormalizedSpec, NormalizedSpecWarning, NormalizedSpecWarningCode, NormalizedSpecWarningLocation, OperationOutputPaths, PathParameterMismatchError, PluginConfig, PluginConstructor, PluginContext, type PluginContextBuilderApi, PluginDependencyError, PluginLoadError, PluginMetadata, PluginModule, PluginRegistration, type PluginRegistryApi, TypeweaverConfig, TypeweaverPlugin, compareRoutes, createJSDocComment, createPluginContextBuilder, createPluginRegistry, getMethodPriority, getPathParameterNames, isSupportedOperationId, isSupportedResourceName, normalizeRoutePath, normalizeSpec, relative, renderTemplate };
|
|
351
373
|
//# sourceMappingURL=index.d.mts.map
|