@rexeus/typeweaver-types 0.10.3 → 0.10.5

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.
@@ -20,7 +20,7 @@ export declare abstract class ResponseValidator<
20
20
  TResponse extends ITypedHttpResponse = ITypedHttpResponse,
21
21
  >
22
22
  extends Validator
23
- implements IResponseValidator
23
+ implements IResponseValidator<TResponse>
24
24
  {
25
25
  protected abstract readonly responseEntries: readonly ResponseEntry[];
26
26
  protected abstract readonly expectedStatusCodes: readonly number[];
@@ -29,9 +29,16 @@ export class ResponseValidator extends Validator {
29
29
  * @returns A result object containing either the validated response or error details
30
30
  */
31
31
  safeValidate(response) {
32
- const error = new ResponseValidationError(response.statusCode);
32
+ const statusCode = typeof response === "object" && response !== null
33
+ ? response.statusCode
34
+ : undefined;
35
+ const error = new ResponseValidationError(statusCode);
36
+ if (typeof statusCode !== "number") {
37
+ error.addStatusCodeIssue([...this.expectedStatusCodes]);
38
+ return { isValid: false, error };
39
+ }
33
40
  for (const entry of this.responseEntries) {
34
- if (response.statusCode === entry.statusCode) {
41
+ if (statusCode === entry.statusCode) {
35
42
  const result = this.validateResponseType(entry.name, entry.headerSchema, entry.bodySchema)(response, error);
36
43
  if (result.isValid)
37
44
  return result;
@@ -83,7 +83,7 @@ export class Validator {
83
83
  * @returns Coerced data object with proper key casing and array coercion
84
84
  */
85
85
  coerceToSchema(data, shape, caseSensitive) {
86
- if (typeof data !== "object" || data === null) {
86
+ if (typeof data !== "object" || data === null || Array.isArray(data)) {
87
87
  return data;
88
88
  }
89
89
  const schemaMap = this.analyzeSchema(shape, caseSensitive);
@@ -160,6 +160,9 @@ export class Validator {
160
160
  if (typeof header !== "object" || header === null) {
161
161
  return this.coerceToSchema(header ?? {}, shape, false);
162
162
  }
163
+ if (Array.isArray(header)) {
164
+ return header;
165
+ }
163
166
  const preprocessed = this.splitCommaDelimitedValues(header, shape);
164
167
  return this.coerceToSchema(preprocessed, shape, false);
165
168
  }
@@ -4,17 +4,19 @@
4
4
  *
5
5
  * @generated by @rexeus/typeweaver
6
6
  */
7
+ import { MissingOperationDefinitionError } from "./errors/MissingOperationDefinitionError.js";
8
+ import { MissingResponseDefinitionError } from "./errors/MissingResponseDefinitionError.js";
7
9
  export const getOperationDefinition = (spec, resourceName, operationId) => {
8
10
  const operation = spec.resources[resourceName]?.operations.find(candidate => candidate.operationId === operationId);
9
11
  if (operation === undefined) {
10
- throw new Error(`Missing operation definition '${String(resourceName)}.${String(operationId)}'.`);
12
+ throw new MissingOperationDefinitionError(String(resourceName), String(operationId));
11
13
  }
12
14
  return operation;
13
15
  };
14
16
  export const getResponseDefinition = (responses, responseName) => {
15
17
  const response = responses.find(candidate => candidate.name === responseName);
16
18
  if (response === undefined) {
17
- throw new Error(`Missing response definition '${String(responseName)}'.`);
19
+ throw new MissingResponseDefinitionError(String(responseName));
18
20
  }
19
21
  return response;
20
22
  };
@@ -0,0 +1,16 @@
1
+ /**
2
+ * This file was automatically generated by typeweaver.
3
+ * DO NOT EDIT. Instead, modify the source definition file and generate again.
4
+ *
5
+ * @generated by @rexeus/typeweaver
6
+ */
7
+ export class MissingOperationDefinitionError extends Error {
8
+ resourceName;
9
+ operationId;
10
+ name = "MissingOperationDefinitionError";
11
+ constructor(resourceName, operationId) {
12
+ super(`Missing operation definition '${resourceName}.${operationId}' in the generated spec runtime.`);
13
+ this.resourceName = resourceName;
14
+ this.operationId = operationId;
15
+ }
16
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * This file was automatically generated by typeweaver.
3
+ * DO NOT EDIT. Instead, modify the source definition file and generate again.
4
+ *
5
+ * @generated by @rexeus/typeweaver
6
+ */
7
+ export class MissingResponseDefinitionError extends Error {
8
+ responseName;
9
+ name = "MissingResponseDefinitionError";
10
+ constructor(responseName) {
11
+ super(`Missing response definition '${responseName}' in the generated spec runtime.`);
12
+ this.responseName = responseName;
13
+ }
14
+ }
@@ -24,7 +24,8 @@ export type I<%= pascalCaseOperationId %>RequestQuery = <%- queryTsType %>
24
24
  export type I<%= pascalCaseOperationId %>RequestBody = <%- bodyTsType %>
25
25
  <% } %>
26
26
 
27
- export type I<%= pascalCaseOperationId %>Request = {
27
+ <% if (requestJsDoc) { %><%- requestJsDoc %>
28
+ <% } %>export type I<%= pascalCaseOperationId %>Request = {
28
29
  path: string;
29
30
  method: HttpMethod.<%= method %>;
30
31
  <%= headerTsType ? `header: I${pascalCaseOperationId}RequestHeader;` : "" %>
@@ -32,4 +33,3 @@ export type I<%= pascalCaseOperationId %>Request = {
32
33
  <%= queryTsType ? `query: I${pascalCaseOperationId}RequestQuery;` : "" %>
33
34
  <%= bodyTsType ? `body: I${pascalCaseOperationId}RequestBody;` : "" %>
34
35
  };
35
-
@@ -26,7 +26,8 @@ import type { I<%= entityResponse.identifierName %>Response } from "<%= entityRe
26
26
  export type I<%= ownResponse.identifierName %>ResponseBody = <%- ownResponse.body %>;
27
27
  <% } %>
28
28
 
29
- export type I<%= ownResponse.identifierName %>Response = ITypedHttpResponse<
29
+ <% if (ownResponse.jsDoc) { %><%- ownResponse.jsDoc.split('\n').map(line => ` ${line}`).join('\n') %>
30
+ <% } %>export type I<%= ownResponse.identifierName %>Response = ITypedHttpResponse<
30
31
  "<%= ownResponse.typeValue %>",
31
32
  HttpStatusCode.<%= ownResponse.statusCodeKey %>,
32
33
  <%= ownResponse.hasHeader ? `I${ownResponse.identifierName}ResponseHeader` : 'undefined' %>,
@@ -1,4 +1,5 @@
1
- <%= indentation %>export const create<%= identifierName %>Response = <% if (hasHeader || hasBody) { %>(
1
+ <% if (jsDoc) { %><%- jsDoc.split('\n').map(line => `${indentation}${line}`).join('\n') %>
2
+ <% } %><%= indentation %>export const create<%= identifierName %>Response = <% if (hasHeader || hasBody) { %>(
2
3
  <%= indentation %>input: {
3
4
  <% if (hasHeader) { %><%= indentation %> header: I<%= identifierName %>ResponseHeader;
4
5
  <% } %><% if (hasBody) { %><%= indentation %> body: I<%= identifierName %>ResponseBody;
@@ -17,7 +17,8 @@ import type { ITypedHttpResponse } from "<%= coreDir %>";
17
17
  export type I<%= identifierName %>ResponseBody = <%- bodyTsType %>;
18
18
  <% } %>
19
19
 
20
- export type I<%= identifierName %>Response = ITypedHttpResponse<
20
+ <% if (jsDoc) { %><%- jsDoc %>
21
+ <% } %>export type I<%= identifierName %>Response = ITypedHttpResponse<
21
22
  "<%= typeValue %>",
22
23
  HttpStatusCode.<%= statusCodeKey %>,
23
24
  <%= hasHeader ? `I${identifierName}ResponseHeader` : 'undefined' %>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rexeus/typeweaver-types",
3
- "version": "0.10.3",
3
+ "version": "0.10.5",
4
4
  "description": "Generates request and response types plus validators aligned with your API contract. Powered by Typeweaver 🧵✨",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -47,17 +47,17 @@
47
47
  },
48
48
  "homepage": "https://github.com/rexeus/typeweaver#readme",
49
49
  "peerDependencies": {
50
- "@rexeus/typeweaver-core": "^0.10.3",
51
- "@rexeus/typeweaver-gen": "^0.10.3"
50
+ "@rexeus/typeweaver-core": "^0.10.5",
51
+ "@rexeus/typeweaver-gen": "^0.10.5"
52
52
  },
53
53
  "devDependencies": {
54
54
  "test-utils": "file:../test-utils",
55
- "@rexeus/typeweaver-core": "^0.10.3",
56
- "@rexeus/typeweaver-gen": "^0.10.3"
55
+ "@rexeus/typeweaver-core": "^0.10.5",
56
+ "@rexeus/typeweaver-gen": "^0.10.5"
57
57
  },
58
58
  "dependencies": {
59
59
  "polycase": "^1.1.0",
60
- "@rexeus/typeweaver-zod-to-ts": "^0.10.3"
60
+ "@rexeus/typeweaver-zod-to-ts": "^0.10.5"
61
61
  },
62
62
  "scripts": {
63
63
  "typecheck": "tsc --noEmit -p tsconfig.typecheck.json",