@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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","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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"}
1
+ {"version":3,"file":"index.d.mts","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;EAAA,SACpB,QAAA,WAAmB,qBAAA;AAAA;AAAA,KAGlB,6BAAA;AAAA,KAKA,uBAAA;AAAA,KAOA,kBAAA;EAAA,SACD,MAAA,EAAQ,cAAA;EAAA,SACR,SAAA;EAAA,SACA,eAAA,EAAiB,6BAAA;EAAA,SACjB,SAAA,EAAW,uBAAA;AAAA;AAAA,KAGV,yBAAA;AAAA,KAKA,6BAAA;EAAA,SACD,IAAA;EAAA,SACA,YAAA;EAAA,SACA,WAAA;EAAA,SACA,YAAA;EAAA,SACA,UAAA,GAAa,cAAA;AAAA;AAAA,KAGZ,qBAAA;EAAA,SACD,IAAA,EAAM,yBAAA;EAAA,SACN,OAAA;EAAA,SACA,QAAA,EAAU,6BAAA;AAAA;AAAA,KAGT,kBAAA;EAAA,SACD,IAAA;EAAA,SACA,UAAA,WAAqB,mBAAA;AAAA;AAAA,KAGpB,mBAAA;EAAA,SACD,WAAA;EAAA,SACA,MAAA,EAAQ,UAAA;EAAA,SACR,IAAA;EAAA,SACA,OAAA;EAAA,SACA,OAAA,GAAU,iBAAA;EAAA,SACV,SAAA,WAAoB,uBAAA;AAAA;AAAA,KAGnB,iBAAA;EAAA,SACD,MAAA,GAAS,gBAAA;EAAA,SACT,KAAA,GAAQ,eAAA;EAAA,SACR,KAAA,GAAQ,eAAA;EAAA,SACR,IAAA,GAAO,kBAAA;AAAA;AAAA,KAGN,kBAAA;EAAA,SACD,IAAA;EAAA,SACA,UAAA,EAAY,cAAA;EAAA,SACZ,cAAA;EAAA,SACA,WAAA;EAAA,SACA,MAAA,GAAS,gBAAA;EAAA,SACT,IAAA,GAAO,kBAAA;EAAA,SACP,IAAA;EAAA,SACA,WAAA;EAAA,SACA,OAAA;EAAA,SACA,KAAA;AAAA;AAAA,KAGC,gCAAA;EAAA,SACD,YAAA;EAAA,SACA,MAAA;AAAA;AAAA,KAGC,6BAAA;EAAA,SACD,YAAA;EAAA,SACA,MAAA;EAAA,SACA,QAAA,EAAU,kBAAA;AAAA;AAAA,KAGT,uBAAA,GACR,gCAAA,GACA,6BAAA;;;cClGS,yBAAA,SAAkC,KAAA;cAE3C,WAAA,UACA,WAAA,QAAmB,iBAAA;AAAA;;;cCLV,wBAAA,SAAiC,KAAA;cACzB,YAAA;AAAA;;;cCDR,iCAAA,SAA0C,KAAA;cAClC,YAAA,UAAsB,UAAA;AAAA;;;cCD9B,0BAAA,SAAmC,KAAA;cAE5C,WAAA,UACA,IAAA,UACA,UAAA,qBACA,aAAA;AAAA;;;cCwOS,aAAA,GAAiB,UAAA,EAAY,cAAA,KAAiB,cAAA;;;;;Ab7O3D;KcKY,YAAA,GAAe,MAAA;;;;KAKf,aAAA;EAAA,SACD,SAAA;EAAA,SACA,QAAA;EAAA,SACA,MAAA,EAAQ,YAAA;AAAA;AAAA,KAGP,oBAAA;EAAA,SACD,SAAA;EAAA,SACA,WAAA;EAAA,SACA,eAAA;EAAA,SACA,YAAA;EAAA,SACA,gBAAA;EAAA,SACA,qBAAA;EAAA,SACA,yBAAA;EAAA,SACA,sBAAA;EAAA,SACA,0BAAA;EAAA,SACA,UAAA;EAAA,SACA,cAAA;AAAA;;AZ3BX;;KYiCY,gBAAA,GAAmB,aAAA;EAAA,SACpB,cAAA,EAAgB,cAAA;EAAA,SAChB,OAAA;EAAA,SACA,kBAAA;EAAA,SACA,aAAA;EAAA,SAEA,oBAAA,GAAuB,YAAA,aAAyB,kBAAA;EAAA,SAChD,8BAAA,GAAiC,YAAA;EAAA,SACjC,8BAAA,GAAiC,MAAA;IAAA,SAC/B,WAAA;IAAA,SACA,YAAA;EAAA;EAAA,SAEF,iBAAA,GAAoB,MAAA;IAAA,SAClB,WAAA;EAAA;EAAA,SAEF,8BAAA,GAAiC,MAAA;IAAA,SAC/B,YAAA;IAAA,SACA,WAAA;EAAA;EAAA,SAEF,uBAAA,GAA0B,MAAA;IAAA,SACxB,YAAA;IAAA,SACA,WAAA;EAAA,MACL,oBAAA;EAAA,SACG,oBAAA,GAAuB,YAAA;EAAA,SACvB,SAAA,GAAY,YAAA,UAAsB,OAAA;EAAA,SAClC,cAAA,GAAiB,YAAA,UAAsB,IAAA;EAAA,SACvC,gBAAA,GAAmB,YAAA;EAAA,SACnB,iBAAA;AAAA;;;;KAMC,cAAA;EAAA,SACD,IAAA;EAAA,SACA,OAAA;AAAA;;ATpEX;;KS0EY,gBAAA,GAAmB,cAAA;ET1Ec;;;;ES+E3C,UAAA,EAAY,OAAA,EAAS,aAAA,GAAgB,OAAA;ER/E1B;;;;EQqFX,gBAAA,EACE,cAAA,EAAgB,cAAA,GACf,OAAA,CAAQ,cAAA,IAAkB,cAAA;;;;;EAM7B,QAAA,EAAU,OAAA,EAAS,gBAAA,GAAmB,OAAA;;;AP7FxC;;EOmGE,QAAA,EAAU,OAAA,EAAS,aAAA,GAAgB,OAAA;AAAA;;;;KAMzB,iBAAA,QAAyB,MAAA,GAAS,YAAA,KAAiB,gBAAA;;;;KAKnD,YAAA;EACV,OAAA,EAAS,iBAAA;AAAA;;;;KAMC,kBAAA;EACV,IAAA;EACA,MAAA,EAAQ,gBAAA;EACR,MAAA,GAAS,YAAA;AAAA;;;;KAMC,gBAAA;EACV,KAAA;EACA,MAAA;EACA,OAAA,sBAA6B,YAAA;EAC7B,MAAA;EACA,KAAA;AAAA;;AN/GF;;cMqHa,eAAA,SAAwB,KAAA;EAE1B,UAAA;cAAA,UAAA,UACP,OAAA;AAAA;;;;cAUS,qBAAA,SAA8B,KAAA;EAEhC,UAAA;EACA,iBAAA;cADA,UAAA,UACA,iBAAA,UACP,OAAA;AAAA;;;;Ad1JJ;;;uBecsB,UAAA,YAAsB,gBAAA;EAAA,SACjC,IAAA;EACT,WAAA;EACA,MAAA;EACA,OAAA;EAAA,UAEU,MAAA,EAAQ,YAAA;cAEN,MAAA,GAAQ,YAAA;;;AdtBtB;Ec6BQ,UAAA,CAAW,QAAA,EAAU,aAAA,GAAgB,OAAA;;;;EAO3C,gBAAA,CAAiB,cAAA,EAAgB,cAAA,GAAiB,cAAA;EdnC/B;;;EAAA,Sc0CV,QAAA,CAAS,OAAA,EAAS,gBAAA,GAAmB,OAAA;;;Ab3ChD;EagDQ,QAAA,CAAS,QAAA,EAAU,aAAA,GAAgB,OAAA;EAAA,UAI/B,YAAA,CACR,OAAA,EAAS,gBAAA,EACT,YAAA,UACA,YAAA;AAAA;;;KCpDQ,iBAAA;EAAA,SACD,QAAA,GAAW,MAAA,EAAQ,gBAAA,EAAkB,MAAA;EAAA,SACrC,GAAA,GAAM,IAAA,aAAiB,kBAAA;EAAA,SACvB,MAAA,QAAc,kBAAA;EAAA,SACd,GAAA,GAAM,IAAA;EAAA,SACN,KAAA;AAAA;AAAA,iBAGK,oBAAA,CAAA,GAAwB,iBAAA;;;KC6P5B,uBAAA;EAAA,SACD,mBAAA,GAAsB,MAAA;IAC7B,SAAA;IACA,QAAA;IACA,MAAA,EAAQ,YAAA;EAAA,MACJ,aAAA;EAAA,SACG,sBAAA,GAAyB,MAAA;IAAA,SACvB,SAAA;IAAA,SACA,QAAA;IAAA,SACA,MAAA,EAAQ,YAAA;IAAA,SACR,cAAA,EAAgB,cAAA;IAAA,SAChB,WAAA;IAAA,SACA,OAAA;IAAA,SACA,kBAAA;IAAA,SACA,aAAA;EAAA,MACL,gBAAA;EAAA,SACG,iBAAA;EAAA,SACA,mBAAA;AAAA;AAAA,iBAGK,0BAAA,CAAA,GAA8B,uBAAA;;;cChRjC,sBAAA,GAA0B,KAAA;AAAA,cAI1B,uBAAA,GAA2B,KAAA;;;KChB5B,yBAAA;EAAA,SACD,WAAA;AAAA;AAAA,iBAMK,kBAAA,CACd,IAAA,sBACA,OAAA,GAAS,yBAAA;;;iBCPK,QAAA,CAAS,IAAA,UAAc,EAAA;;;cCA1B,kBAAA,GAAsB,IAAA;AAAA,cAUtB,qBAAA,GAAyB,IAAA;;;;;;ArBZtC;csBoBa,iBAAA,GAAqB,MAAA;;;;;;;;;cA4BrB,aAAA,GACX,CAAA;EAAK,MAAA;EAAgB,IAAA;AAAA,GACrB,CAAA;EAAK,MAAA;EAAgB,IAAA;AAAA;;;iBCjCP,cAAA,CACd,QAAA,UACA,IAAA,EAAM,MAAA"}
package/dist/index.mjs CHANGED
@@ -99,6 +99,175 @@ var PathParameterMismatchError = class extends Error {
99
99
  }
100
100
  };
101
101
  //#endregion
102
+ //#region src/bodyNormalization.ts
103
+ const JSON_BODY_SCHEMA_TYPES = new Set([
104
+ "array",
105
+ "boolean",
106
+ "enum",
107
+ "intersection",
108
+ "literal",
109
+ "null",
110
+ "number",
111
+ "object",
112
+ "record",
113
+ "tuple",
114
+ "union"
115
+ ]);
116
+ const normalizeBody = (input) => {
117
+ if (input.bodySchema === void 0) return { warnings: [] };
118
+ const warnings = [];
119
+ const contentTypeHeader = extractContentTypeHeader(input.headerSchema);
120
+ if (contentTypeHeader.kind === "literal") return {
121
+ body: createNormalizedBody({
122
+ schema: input.bodySchema,
123
+ mediaType: contentTypeHeader.value,
124
+ mediaTypeSource: "content-type-header"
125
+ }),
126
+ warnings
127
+ };
128
+ if (contentTypeHeader.kind === "ambiguous") warnings.push({
129
+ code: "ambiguous-content-type-header",
130
+ message: "Content-Type header is present but does not have one unambiguous literal value; inferred body media type instead.",
131
+ location: input.location
132
+ });
133
+ else warnings.push({
134
+ code: "missing-content-type-header",
135
+ message: "Body schema is present without a Content-Type header; inferred body media type from schema.",
136
+ location: input.location
137
+ });
138
+ const inferred = inferBodyMediaType(input.bodySchema);
139
+ if (inferred.mediaTypeSource === "raw-fallback") warnings.push({
140
+ code: "raw-body-media-type-fallback",
141
+ message: "Body schema does not imply a concrete media type; used application/octet-stream raw transport fallback.",
142
+ location: input.location
143
+ });
144
+ return {
145
+ body: createNormalizedBody({
146
+ schema: input.bodySchema,
147
+ ...inferred
148
+ }),
149
+ warnings
150
+ };
151
+ };
152
+ const createNormalizedBody = (input) => {
153
+ return {
154
+ schema: input.schema,
155
+ mediaType: input.mediaType,
156
+ mediaTypeSource: input.mediaTypeSource,
157
+ transport: resolveTransport(input.mediaType)
158
+ };
159
+ };
160
+ const extractContentTypeHeader = (headerSchema) => {
161
+ const headerObject = unwrapOptional(headerSchema);
162
+ if (headerObject === void 0 || !isZodObject$1(headerObject)) return { kind: "absent" };
163
+ const contentTypeEntries = Object.entries(headerObject.shape).filter(([headerName]) => headerName.toLowerCase() === "content-type");
164
+ if (contentTypeEntries.length === 0) return { kind: "absent" };
165
+ const literalValues = contentTypeEntries.flatMap(([, schema]) => extractStringLiteralValues(schema));
166
+ const distinctValues = new Set(literalValues);
167
+ if (contentTypeEntries.length === 1 && distinctValues.size === 1) {
168
+ const [value] = distinctValues;
169
+ return value === void 0 ? { kind: "ambiguous" } : {
170
+ kind: "literal",
171
+ value
172
+ };
173
+ }
174
+ return { kind: "ambiguous" };
175
+ };
176
+ const inferBodyMediaType = (schema) => {
177
+ const inferenceSchema = unwrapMediaInferenceSchema(schema);
178
+ const schemaType = getSchemaType(inferenceSchema);
179
+ if (isTextBodySchema(inferenceSchema)) return {
180
+ mediaType: "text/plain",
181
+ mediaTypeSource: "body-schema"
182
+ };
183
+ if (schemaType === "any" || schemaType === "unknown") return {
184
+ mediaType: "application/octet-stream",
185
+ mediaTypeSource: "raw-fallback"
186
+ };
187
+ if (schemaType !== void 0 && JSON_BODY_SCHEMA_TYPES.has(schemaType)) return {
188
+ mediaType: "application/json",
189
+ mediaTypeSource: "body-schema"
190
+ };
191
+ return {
192
+ mediaType: "application/octet-stream",
193
+ mediaTypeSource: "raw-fallback"
194
+ };
195
+ };
196
+ const isTextBodySchema = (schema) => {
197
+ const schemaType = getSchemaType(schema);
198
+ if (schemaType === "string") return true;
199
+ if (schemaType === "literal") {
200
+ const values = literalSchemaValues(schema);
201
+ return values.length > 0 && values.every((value) => typeof value === "string");
202
+ }
203
+ if (schemaType === "enum") {
204
+ const values = enumSchemaValues(schema);
205
+ return values.length > 0 && values.every((value) => typeof value === "string");
206
+ }
207
+ return false;
208
+ };
209
+ const resolveTransport = (mediaType) => {
210
+ const normalizedMediaType = mediaType.split(";")[0]?.trim().toLowerCase();
211
+ if (normalizedMediaType === "application/json" || normalizedMediaType?.endsWith("+json") === true) return "json";
212
+ if (normalizedMediaType?.startsWith("text/") === true) return "text";
213
+ if (normalizedMediaType === "application/x-www-form-urlencoded") return "form-url-encoded";
214
+ if (normalizedMediaType === "multipart/form-data") return "multipart";
215
+ return "raw";
216
+ };
217
+ const unwrapMediaInferenceSchema = (schema) => {
218
+ const visitedSchemas = /* @__PURE__ */ new Set();
219
+ let current = schema;
220
+ while (current !== void 0 && !visitedSchemas.has(current)) {
221
+ visitedSchemas.add(current);
222
+ const definition = getSchemaDefinition(current);
223
+ const schemaType = definition?.type;
224
+ if (schemaType === "optional" || schemaType === "nullable" || schemaType === "default" || schemaType === "catch" || schemaType === "prefault" || schemaType === "readonly") {
225
+ current = definition?.innerType;
226
+ continue;
227
+ }
228
+ if (schemaType === "pipe") {
229
+ const outputType = getSchemaType(definition?.out);
230
+ if (outputType === void 0 || outputType === "transform") return;
231
+ current = definition?.out;
232
+ continue;
233
+ }
234
+ if (schemaType === "effects") {
235
+ current = definition?.schema;
236
+ continue;
237
+ }
238
+ return current;
239
+ }
240
+ return current;
241
+ };
242
+ const unwrapOptional = (schema) => {
243
+ return schema instanceof z.ZodOptional ? schema.unwrap() : schema;
244
+ };
245
+ const isZodObject$1 = (schema) => {
246
+ return getSchemaType(schema) === "object" && "shape" in schema;
247
+ };
248
+ const extractStringLiteralValues = (schema) => {
249
+ const unwrappedSchema = unwrapOptional(schema);
250
+ if (unwrappedSchema === void 0) return [];
251
+ if (getSchemaType(unwrappedSchema) === "literal") return literalSchemaValues(unwrappedSchema).filter((value) => typeof value === "string");
252
+ if (getSchemaType(unwrappedSchema) === "enum") return enumSchemaValues(unwrappedSchema).filter((value) => typeof value === "string");
253
+ return [];
254
+ };
255
+ const literalSchemaValues = (schema) => {
256
+ const literalSchema = schema;
257
+ return Array.from(literalSchema?.values ?? []);
258
+ };
259
+ const enumSchemaValues = (schema) => {
260
+ const enumSchema = schema;
261
+ return enumSchema?.options ?? enumSchema?.def?.values ?? Object.values(enumSchema?.def?.entries ?? enumSchema?.enum ?? {});
262
+ };
263
+ const getSchemaType = (schema) => {
264
+ return getSchemaDefinition(schema)?.type;
265
+ };
266
+ const getSchemaDefinition = (schema) => {
267
+ const schemaWithDefinition = schema;
268
+ return schemaWithDefinition?.def ?? schemaWithDefinition?._def;
269
+ };
270
+ //#endregion
102
271
  //#region src/helpers/namingUtils.ts
103
272
  const startsWithDigit = (value) => /^[0-9]/u.test(value);
104
273
  const isSupportedIdentifierName = (value) => {
@@ -173,25 +342,49 @@ const validateInlineDerivedResponses = (definition, canonicalResponses) => {
173
342
  validateDerivedResponseAgainstCanonicalGraph(response, canonicalResponses);
174
343
  }
175
344
  };
176
- const normalizeResponseDefinition = (response) => {
345
+ const normalizeResponseDefinition = (response, location) => {
346
+ const body = normalizeBody({
347
+ bodySchema: response.body,
348
+ headerSchema: response.header,
349
+ location: {
350
+ ...location,
351
+ part: "response.body"
352
+ }
353
+ });
177
354
  return {
178
- name: response.name,
179
- statusCode: response.statusCode,
180
- statusCodeName: HttpStatusCodeNameMap[response.statusCode],
181
- description: response.description,
182
- header: response.header,
183
- body: response.body,
184
- kind: response.derived === void 0 ? "response" : "derived-response",
185
- derivedFrom: response.derived?.parentName,
186
- lineage: response.derived?.lineage,
187
- depth: response.derived?.depth
355
+ response: {
356
+ name: response.name,
357
+ statusCode: response.statusCode,
358
+ statusCodeName: HttpStatusCodeNameMap[response.statusCode],
359
+ description: response.description,
360
+ header: response.header,
361
+ body: body.body,
362
+ kind: response.derived === void 0 ? "response" : "derived-response",
363
+ derivedFrom: response.derived?.parentName,
364
+ lineage: response.derived?.lineage,
365
+ depth: response.derived?.depth
366
+ },
367
+ warnings: body.warnings
188
368
  };
189
369
  };
190
370
  const collectCanonicalResponses = (definition) => {
191
371
  const canonicalResponseDefinitions = collectCanonicalResponseDefinitions(definition);
372
+ const warnings = [];
192
373
  validateDerivedResponseGraph(canonicalResponseDefinitions);
193
374
  validateInlineDerivedResponses(definition, canonicalResponseDefinitions);
194
- return new Map(Array.from(canonicalResponseDefinitions.entries(), ([responseName, response]) => [responseName, normalizeResponseDefinition(response)]));
375
+ const responses = /* @__PURE__ */ new Map();
376
+ for (const [responseName, response] of canonicalResponseDefinitions) {
377
+ const normalized = normalizeResponseDefinition(response, {
378
+ responseName,
379
+ statusCode: response.statusCode
380
+ });
381
+ responses.set(responseName, normalized.response);
382
+ warnings.push(...normalized.warnings);
383
+ }
384
+ return {
385
+ responses,
386
+ warnings
387
+ };
195
388
  };
196
389
  //#endregion
197
390
  //#region src/normalizeSpec.ts
@@ -205,7 +398,7 @@ const validateRequestSchema = (operationId, requestPart, schema) => {
205
398
  if (!isZodType(schema)) throw new InvalidRequestSchemaError(operationId, requestPart);
206
399
  if (requestPart === "param" && !isZodObject(schema)) throw new InvalidRequestSchemaError(operationId, requestPart);
207
400
  };
208
- const validateRequest = (operationId, path, request) => {
401
+ const validateRequest = (resourceName, operationId, path, request) => {
209
402
  if (request.header !== void 0) validateRequestSchema(operationId, "header", request.header);
210
403
  if (request.param !== void 0) validateRequestSchema(operationId, "param", request.param);
211
404
  if (request.query !== void 0) validateRequestSchema(operationId, "query", request.query);
@@ -213,28 +406,51 @@ const validateRequest = (operationId, path, request) => {
213
406
  const pathParams = getPathParameterNames(path);
214
407
  const requestParams = request.param === void 0 ? [] : Object.keys(request.param.shape);
215
408
  if (pathParams.length !== requestParams.length || pathParams.some((pathParam) => !requestParams.includes(pathParam))) throw new PathParameterMismatchError(operationId, path, pathParams, requestParams);
216
- if (request.header === void 0 && request.param === void 0 && request.query === void 0 && request.body === void 0) return;
409
+ if (request.header === void 0 && request.param === void 0 && request.query === void 0 && request.body === void 0) return { warnings: [] };
410
+ const body = normalizeBody({
411
+ bodySchema: request.body,
412
+ headerSchema: request.header,
413
+ location: {
414
+ resourceName,
415
+ operationId,
416
+ part: "request.body"
417
+ }
418
+ });
217
419
  return {
218
- header: request.header,
219
- param: request.param,
220
- query: request.query,
221
- body: request.body
420
+ request: {
421
+ header: request.header,
422
+ param: request.param,
423
+ query: request.query,
424
+ body: body.body
425
+ },
426
+ warnings: body.warnings
222
427
  };
223
428
  };
224
- const normalizeOperationResponses = (responses) => {
225
- return responses.map((response) => {
226
- if (isNamedResponseDefinition(response)) return {
227
- responseName: response.name,
228
- source: "canonical"
229
- };
230
- return {
231
- responseName: response.name,
232
- source: "inline",
233
- response: normalizeResponseDefinition(response)
234
- };
235
- });
429
+ const normalizeOperationResponses = (resourceName, operationId, responses) => {
430
+ const warnings = [];
431
+ return {
432
+ responses: responses.map((response) => {
433
+ if (isNamedResponseDefinition(response)) return {
434
+ responseName: response.name,
435
+ source: "canonical"
436
+ };
437
+ const normalized = normalizeResponseDefinition(response, {
438
+ resourceName,
439
+ operationId,
440
+ responseName: response.name,
441
+ statusCode: response.statusCode
442
+ });
443
+ warnings.push(...normalized.warnings);
444
+ return {
445
+ responseName: response.name,
446
+ source: "inline",
447
+ response: normalized.response
448
+ };
449
+ }),
450
+ warnings
451
+ };
236
452
  };
237
- const normalizeOperation = (operationIds, routeKeys, operation) => {
453
+ const normalizeOperation = (resourceName, operationIds, routeKeys, operation) => {
238
454
  if (!isSupportedOperationId(operation.operationId)) throw new InvalidOperationIdError(operation.operationId);
239
455
  if (operationIds.has(operation.operationId)) throw new DuplicateOperationIdError(operation.operationId);
240
456
  operationIds.add(operation.operationId);
@@ -243,13 +459,18 @@ const normalizeOperation = (operationIds, routeKeys, operation) => {
243
459
  if (routeKeys.has(routeKey)) throw new DuplicateRouteError(operation.method, operation.path, normalizedPath);
244
460
  routeKeys.add(routeKey);
245
461
  if (operation.responses.length === 0) throw new EmptyOperationResponsesError(operation.operationId);
462
+ const request = validateRequest(resourceName, operation.operationId, operation.path, operation.request);
463
+ const responses = normalizeOperationResponses(resourceName, operation.operationId, operation.responses);
246
464
  return {
247
- operationId: operation.operationId,
248
- method: operation.method,
249
- path: operation.path,
250
- summary: operation.summary,
251
- request: validateRequest(operation.operationId, operation.path, operation.request),
252
- responses: normalizeOperationResponses(operation.responses)
465
+ operation: {
466
+ operationId: operation.operationId,
467
+ method: operation.method,
468
+ path: operation.path,
469
+ summary: operation.summary,
470
+ request: request.request,
471
+ responses: responses.responses
472
+ },
473
+ warnings: [...request.warnings, ...responses.warnings]
253
474
  };
254
475
  };
255
476
  const normalizeSpec = (definition) => {
@@ -259,16 +480,22 @@ const normalizeSpec = (definition) => {
259
480
  const canonicalResponses = collectCanonicalResponses(definition);
260
481
  const operationIds = /* @__PURE__ */ new Set();
261
482
  const routeKeys = /* @__PURE__ */ new Set();
483
+ const warnings = [...canonicalResponses.warnings];
262
484
  return {
263
485
  resources: resourceEntries.map(([resourceName, resource]) => {
264
486
  if (!isSupportedResourceName(resourceName)) throw new InvalidResourceNameError(resourceName);
265
487
  if (resource.operations.length === 0) throw new EmptyResourceOperationsError(resourceName);
266
488
  return {
267
489
  name: resourceName,
268
- operations: resource.operations.map((operation) => normalizeOperation(operationIds, routeKeys, operation))
490
+ operations: resource.operations.map((operation) => {
491
+ const normalized = normalizeOperation(resourceName, operationIds, routeKeys, operation);
492
+ warnings.push(...normalized.warnings);
493
+ return normalized.operation;
494
+ })
269
495
  };
270
496
  }),
271
- responses: Array.from(canonicalResponses.values())
497
+ responses: Array.from(canonicalResponses.responses.values()),
498
+ warnings
272
499
  };
273
500
  };
274
501
  //#endregion
@@ -453,6 +680,112 @@ var MissingCanonicalResponseError = class extends Error {
453
680
  };
454
681
  //#endregion
455
682
  //#region src/plugins/pluginContext.ts
683
+ const WINDOWS_DRIVE_PREFIX_PATTERN = /^[a-zA-Z]:/;
684
+ function pathContainsParentTraversal(projectPath) {
685
+ return projectPath.split("/").includes("..");
686
+ }
687
+ function pathEndsWithDirectorySeparator(projectPath) {
688
+ return projectPath.endsWith("/");
689
+ }
690
+ function pathNamesCurrentDirectory(projectPath) {
691
+ return projectPath === "." || projectPath.endsWith("/.");
692
+ }
693
+ function resolveSafeGeneratedFilePath(outputDir, requestedPath) {
694
+ if (requestedPath.length === 0) throwUnsafeGeneratedFilePath(requestedPath, "path must not be empty");
695
+ const projectPath = requestedPath.replace(/\\/g, "/");
696
+ if (path.isAbsolute(requestedPath) || path.posix.isAbsolute(projectPath) || path.win32.isAbsolute(requestedPath) || path.win32.isAbsolute(projectPath) || WINDOWS_DRIVE_PREFIX_PATTERN.test(requestedPath)) throwUnsafeGeneratedFilePath(requestedPath, "absolute paths are not allowed");
697
+ if (pathContainsParentTraversal(projectPath)) throwUnsafeGeneratedFilePath(requestedPath, "path contains parent-directory traversal");
698
+ if (pathEndsWithDirectorySeparator(projectPath)) throwUnsafeGeneratedFilePath(requestedPath, "path must name a file inside the output directory");
699
+ if (pathNamesCurrentDirectory(projectPath)) throwUnsafeGeneratedFilePath(requestedPath, "path must name a file inside the output directory");
700
+ const generatedPath = path.posix.normalize(projectPath);
701
+ if (generatedPath === ".") throwUnsafeGeneratedFilePath(requestedPath, "path must name a file inside the output directory");
702
+ if (pathContainsParentTraversal(generatedPath)) throwUnsafeGeneratedFilePath(requestedPath, "path contains parent-directory traversal");
703
+ const outputRoot = path.resolve(outputDir);
704
+ const fullPath = path.resolve(outputRoot, toNativePath(generatedPath));
705
+ if (!isStrictlyInsidePath(fullPath, outputRoot)) throwUnsafeGeneratedFilePath(requestedPath, "path escapes the output directory");
706
+ assertGeneratedPathHasNoSymlinkComponents({
707
+ outputRoot,
708
+ generatedPath,
709
+ requestedPath
710
+ });
711
+ return {
712
+ fullPath,
713
+ generatedPath
714
+ };
715
+ }
716
+ function toNativePath(projectPath) {
717
+ return projectPath.split("/").join(path.sep);
718
+ }
719
+ function assertGeneratedPathHasNoSymlinkComponents(config) {
720
+ assertExistingPathIsNotSymlink(config.outputRoot, config.requestedPath);
721
+ let currentPath = config.outputRoot;
722
+ for (const segment of config.generatedPath.split("/")) {
723
+ currentPath = path.join(currentPath, segment);
724
+ const pathStats = getExistingPathStats(currentPath);
725
+ if (pathStats === void 0) return;
726
+ assertPathStatsIsNotSymlink(pathStats, config.requestedPath);
727
+ if (!pathStats.isDirectory()) return;
728
+ }
729
+ }
730
+ function assertExistingPathIsNotSymlink(absolutePath, requestedPath) {
731
+ const pathStats = getExistingPathStats(absolutePath);
732
+ if (pathStats === void 0) return;
733
+ assertPathStatsIsNotSymlink(pathStats, requestedPath);
734
+ }
735
+ function assertPathStatsIsNotSymlink(pathStats, requestedPath) {
736
+ if (!pathStats.isSymbolicLink()) return;
737
+ throwUnsafeGeneratedFilePath(requestedPath, "path contains a symbolic link");
738
+ }
739
+ function getExistingPathStats(absolutePath) {
740
+ try {
741
+ return fs.lstatSync(absolutePath);
742
+ } catch (error) {
743
+ if (isMissingPathError(error)) return;
744
+ throw error;
745
+ }
746
+ }
747
+ function isMissingPathError(error) {
748
+ if (!(error instanceof Error)) return false;
749
+ return ["ENOENT", "ENOTDIR"].includes(error.code ?? "");
750
+ }
751
+ function isStrictlyInsidePath(childPath, parentPath) {
752
+ const relativePath = path.relative(parentPath, childPath);
753
+ return relativePath !== "" && relativePath !== ".." && !relativePath.startsWith(`..${path.sep}`) && !path.isAbsolute(relativePath);
754
+ }
755
+ function throwUnsafeGeneratedFilePath(requestedPath, reason) {
756
+ throw new Error(`Unsafe generated file path '${requestedPath}': ${reason}. Generated writes must stay inside the output directory.`);
757
+ }
758
+ function revalidateGeneratedWritePath(outputDir, generatedPath) {
759
+ return resolveSafeGeneratedFilePath(outputDir, generatedPath);
760
+ }
761
+ function writeGeneratedFileByReplacingDestination(config) {
762
+ const existingFileMode = getExistingFileMode(revalidateGeneratedWritePath(config.outputDir, config.generatedPath).fullPath);
763
+ const tempParentPath = revalidateGeneratedWritePath(config.outputDir, config.generatedPath);
764
+ const destinationDir = path.dirname(tempParentPath.fullPath);
765
+ const tempDir = fs.mkdtempSync(path.join(destinationDir, ".typeweaver-"));
766
+ const tempFile = path.join(tempDir, "generated.tmp");
767
+ try {
768
+ revalidateGeneratedWritePath(config.outputDir, config.generatedPath);
769
+ fs.writeFileSync(tempFile, config.content, {
770
+ flag: "wx",
771
+ mode: existingFileMode ?? 438
772
+ });
773
+ if (existingFileMode !== void 0) fs.chmodSync(tempFile, existingFileMode);
774
+ const writablePath = revalidateGeneratedWritePath(config.outputDir, config.generatedPath);
775
+ fs.renameSync(tempFile, writablePath.fullPath);
776
+ return writablePath;
777
+ } finally {
778
+ fs.rmSync(tempDir, {
779
+ recursive: true,
780
+ force: true
781
+ });
782
+ }
783
+ }
784
+ function getExistingFileMode(absolutePath) {
785
+ const pathStats = getExistingPathStats(absolutePath);
786
+ if (pathStats?.isFile() !== true) return;
787
+ return pathStats.mode & 511;
788
+ }
456
789
  function createPluginContextBuilder() {
457
790
  const generatedFiles = /* @__PURE__ */ new Set();
458
791
  const createPluginContext = (params) => {
@@ -518,19 +851,25 @@ function createPluginContextBuilder() {
518
851
  getOperationOutputPaths,
519
852
  getResourceOutputDir,
520
853
  writeFile: (relativePath, content) => {
521
- const fullPath = path.join(params.outputDir, relativePath);
522
- const dir = path.dirname(fullPath);
854
+ const safePath = resolveSafeGeneratedFilePath(params.outputDir, relativePath);
855
+ const dir = path.dirname(safePath.fullPath);
523
856
  fs.mkdirSync(dir, { recursive: true });
524
- fs.writeFileSync(fullPath, content);
525
- generatedFiles.add(relativePath);
526
- console.info(`Generated: ${relativePath}`);
857
+ const writablePath = revalidateGeneratedWritePath(params.outputDir, safePath.generatedPath);
858
+ const generatedFile = writeGeneratedFileByReplacingDestination({
859
+ outputDir: params.outputDir,
860
+ generatedPath: writablePath.generatedPath,
861
+ content
862
+ });
863
+ generatedFiles.add(generatedFile.generatedPath);
864
+ console.info(`Generated: ${generatedFile.generatedPath}`);
527
865
  },
528
866
  renderTemplate: (templatePath, data) => {
529
867
  const fullTemplatePath = path.isAbsolute(templatePath) ? templatePath : path.join(params.templateDir, templatePath);
530
868
  return renderTemplate(fs.readFileSync(fullTemplatePath, "utf8"), data ?? {});
531
869
  },
532
870
  addGeneratedFile: (relativePath) => {
533
- generatedFiles.add(relativePath);
871
+ const safePath = resolveSafeGeneratedFilePath(params.outputDir, relativePath);
872
+ generatedFiles.add(safePath.generatedPath);
534
873
  },
535
874
  getGeneratedFiles: () => {
536
875
  return Array.from(generatedFiles);