@danceroutine/tango-openapi 1.11.0 → 1.11.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/dist/chunk-D7D4PA-g.js +13 -0
- package/dist/domain/index.d.ts +2 -5
- package/dist/domain/index.js +2 -3
- package/dist/{domain-B-7sApJT.js → domain-C8g_q6ip.js} +5 -8
- package/dist/domain-C8g_q6ip.js.map +1 -0
- package/dist/generators/index.d.ts +2 -6
- package/dist/generators/index.js +2 -4
- package/dist/{generators-JMALItMS.js → generators-BLTcbhxj.js} +17 -23
- package/dist/generators-BLTcbhxj.js.map +1 -0
- package/dist/index-C0KpWWY9.d.ts +16 -0
- package/dist/index-CjqHxnkO.d.ts +187 -0
- package/dist/index-CyPT9p0e.d.ts +29 -0
- package/dist/index.d.ts +4 -11
- package/dist/index.js +5 -6
- package/dist/mappers/index.d.ts +2 -6
- package/dist/mappers/index.js +12 -3
- package/dist/mappers/index.js.map +1 -0
- package/dist/{schema-D3ybOrpr.js → schema-DyzwamHF.js} +19 -19
- package/dist/schema-DyzwamHF.js.map +1 -0
- package/package.json +6 -6
- package/dist/chunk-BkvOhyD0.js +0 -12
- package/dist/domain/describeResources.d.ts +0 -10
- package/dist/domain/types.d.ts +0 -170
- package/dist/domain-B-7sApJT.js.map +0 -1
- package/dist/generators/spec/generateOpenAPISpec.d.ts +0 -5
- package/dist/generators/spec/index.d.ts +0 -4
- package/dist/generators-JMALItMS.js.map +0 -1
- package/dist/mappers/schema/generateSchemaFromModel.d.ts +0 -5
- package/dist/mappers/schema/generateSchemaFromZod.d.ts +0 -6
- package/dist/mappers/schema/index.d.ts +0 -6
- package/dist/mappers/schema/mapTypeToOpenAPI.d.ts +0 -4
- package/dist/mappers-bmN95TGV.js +0 -15
- package/dist/mappers-bmN95TGV.js.map +0 -1
- package/dist/schema-D3ybOrpr.js.map +0 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/dist/domain/index.d.ts
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
*/
|
|
4
|
-
export type { ComponentsObject, MediaTypeObject, OperationObject, OpenAPIAPIViewDescriptor, OpenAPIModel, OpenAPIModelFieldMeta, OpenAPIOptions, OpenAPIOperationOverride, OpenAPIResponseOverride, OpenAPIResourceDescriptor, OpenAPISchemaInput, OpenAPISpec, OpenAPIGeneratorConfig, OpenAPIGenericAPIViewDescriptor, OpenAPIViewSetDescriptor, ParameterObject, PathItemObject, ReferenceObject, RequestBodyObject, ResponseObject, SchemaObject, } from './types';
|
|
5
|
-
export { describeAPIView, describeGenericAPIView, describeViewSet } from './describeResources';
|
|
1
|
+
import { C as RequestBodyObject, S as ReferenceObject, T as SchemaObject, _ as OpenAPISpec, a as ComponentsObject, b as ParameterObject, c as OpenAPIGeneratorConfig, d as OpenAPIModelFieldMeta, f as OpenAPIOperationOverride, g as OpenAPISchemaInput, h as OpenAPIResponseOverride, i as describeViewSet, l as OpenAPIGenericAPIViewDescriptor, m as OpenAPIResourceDescriptor, n as describeAPIView, o as MediaTypeObject, p as OpenAPIOptions, r as describeGenericAPIView, s as OpenAPIAPIViewDescriptor, u as OpenAPIModel, v as OpenAPIViewSetDescriptor, w as ResponseObject, x as PathItemObject, y as OperationObject } from "../index-CjqHxnkO.js";
|
|
2
|
+
export { type ComponentsObject, type MediaTypeObject, type OpenAPIAPIViewDescriptor, type OpenAPIGeneratorConfig, type OpenAPIGenericAPIViewDescriptor, type OpenAPIModel, type OpenAPIModelFieldMeta, type OpenAPIOperationOverride, type OpenAPIOptions, type OpenAPIResourceDescriptor, type OpenAPIResponseOverride, type OpenAPISchemaInput, type OpenAPISpec, type OpenAPIViewSetDescriptor, type OperationObject, type ParameterObject, type PathItemObject, type ReferenceObject, type RequestBodyObject, type ResponseObject, type SchemaObject, describeAPIView, describeGenericAPIView, describeViewSet };
|
package/dist/domain/index.js
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
|
-
import { describeAPIView, describeGenericAPIView
|
|
2
|
-
|
|
3
|
-
export { describeAPIView, describeGenericAPIView, describeViewSet };
|
|
1
|
+
import { i as describeViewSet, n as describeAPIView, r as describeGenericAPIView } from "../domain-C8g_q6ip.js";
|
|
2
|
+
export { describeAPIView, describeGenericAPIView, describeViewSet };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { t as __exportAll } from "./chunk-D7D4PA-g.js";
|
|
3
2
|
//#region src/domain/describeResources.ts
|
|
4
3
|
function describeViewSet(descriptor) {
|
|
5
4
|
return {
|
|
@@ -19,16 +18,14 @@ function describeAPIView(descriptor) {
|
|
|
19
18
|
...descriptor
|
|
20
19
|
};
|
|
21
20
|
}
|
|
22
|
-
|
|
23
21
|
//#endregion
|
|
24
22
|
//#region src/domain/index.ts
|
|
25
|
-
var domain_exports = {
|
|
26
|
-
__export(domain_exports, {
|
|
23
|
+
var domain_exports = /* @__PURE__ */ __exportAll({
|
|
27
24
|
describeAPIView: () => describeAPIView,
|
|
28
25
|
describeGenericAPIView: () => describeGenericAPIView,
|
|
29
26
|
describeViewSet: () => describeViewSet
|
|
30
27
|
});
|
|
31
|
-
|
|
32
28
|
//#endregion
|
|
33
|
-
export { describeAPIView, describeGenericAPIView
|
|
34
|
-
|
|
29
|
+
export { describeViewSet as i, describeAPIView as n, describeGenericAPIView as r, domain_exports as t };
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=domain-C8g_q6ip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-C8g_q6ip.js","names":[],"sources":["../src/domain/describeResources.ts","../src/domain/index.ts"],"sourcesContent":["import type { APIViewMethod, AnyModelSerializer, AnyModelSerializerClass } from '@danceroutine/tango-resources';\nimport type { OpenAPIViewSetDescriptor, OpenAPIGenericAPIViewDescriptor, OpenAPIAPIViewDescriptor } from './types';\n\nexport function describeViewSet(\n descriptor: Omit<OpenAPIViewSetDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>\n): OpenAPIViewSetDescriptor;\nexport function describeViewSet<\n TModel extends Record<string, unknown>,\n TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>,\n>(\n descriptor: Omit<OpenAPIViewSetDescriptor<TModel, TSerializer>, 'kind'>\n): OpenAPIViewSetDescriptor<TModel, TSerializer>;\nexport function describeViewSet(descriptor: Omit<OpenAPIViewSetDescriptor, 'kind'>) {\n return {\n kind: 'viewset',\n ...descriptor,\n };\n}\n\nexport function describeGenericAPIView(\n descriptor: Omit<OpenAPIGenericAPIViewDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>\n): OpenAPIGenericAPIViewDescriptor;\nexport function describeGenericAPIView<\n TModel extends Record<string, unknown>,\n TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>,\n>(\n descriptor: Omit<OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>, 'kind'>\n): OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>;\nexport function describeGenericAPIView(descriptor: Omit<OpenAPIGenericAPIViewDescriptor, 'kind'>) {\n return {\n kind: 'generic',\n ...descriptor,\n };\n}\n\nexport function describeAPIView(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'>): OpenAPIAPIViewDescriptor;\nexport function describeAPIView<\n TMethods extends Partial<Record<APIViewMethod, OpenAPIAPIViewDescriptor['methods'][APIViewMethod]>>,\n>(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'> & { methods: TMethods }): OpenAPIAPIViewDescriptor;\nexport function describeAPIView(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'>) {\n return {\n kind: 'api',\n ...descriptor,\n };\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type {\n ComponentsObject,\n MediaTypeObject,\n OperationObject,\n OpenAPIAPIViewDescriptor,\n OpenAPIModel,\n OpenAPIModelFieldMeta,\n OpenAPIOptions,\n OpenAPIOperationOverride,\n OpenAPIResponseOverride,\n OpenAPIResourceDescriptor,\n OpenAPISchemaInput,\n OpenAPISpec,\n OpenAPIGeneratorConfig,\n OpenAPIGenericAPIViewDescriptor,\n OpenAPIViewSetDescriptor,\n ParameterObject,\n PathItemObject,\n ReferenceObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n} from './types';\nexport { describeAPIView, describeGenericAPIView, describeViewSet } from './describeResources';\n"],"mappings":";;AAYA,SAAgB,gBAAgB,YAAoD;CAChF,OAAO;EACH,MAAM;EACN,GAAG;CACP;AACJ;AAWA,SAAgB,uBAAuB,YAA2D;CAC9F,OAAO;EACH,MAAM;EACN,GAAG;CACP;AACJ;AAMA,SAAgB,gBAAgB,YAAoD;CAChF,OAAO;EACH,MAAM;EACN,GAAG;CACP;AACJ"}
|
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* imports and curated flat exports for TS-native ergonomics.
|
|
4
|
-
*/
|
|
5
|
-
export * as spec from './spec/index';
|
|
6
|
-
export { generateOpenAPISpec } from './spec/index';
|
|
1
|
+
import { n as index_d_exports, r as generateOpenAPISpec } from "../index-C0KpWWY9.js";
|
|
2
|
+
export { generateOpenAPISpec, index_d_exports as spec };
|
package/dist/generators/index.js
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import "../
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export { generateOpenAPISpec, spec_exports as spec };
|
|
1
|
+
import { n as spec_exports, r as generateOpenAPISpec } from "../generators-BLTcbhxj.js";
|
|
2
|
+
export { generateOpenAPISpec, spec_exports as spec };
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./chunk-D7D4PA-g.js";
|
|
2
|
+
import { n as generateSchemaFromZod, r as generateSchemaFromModel } from "./schema-DyzwamHF.js";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
-
|
|
5
4
|
//#region src/generators/spec/generateOpenAPISpec.ts
|
|
6
5
|
const JSON_CONTENT_TYPE = "application/json";
|
|
7
6
|
function toOpenAPIModel(metadata) {
|
|
@@ -84,14 +83,11 @@ function withOverride(operation, override, fallbackTags) {
|
|
|
84
83
|
};
|
|
85
84
|
if (override.responses) {
|
|
86
85
|
nextOperation.responses = Object.fromEntries(Object.entries(override.responses).map(([status, response]) => {
|
|
87
|
-
return [status, jsonResponse(response.description, response.schema ? toSchema(response.schema) :
|
|
86
|
+
return [status, jsonResponse(response.description, response.schema ? toSchema(response.schema) : void 0)];
|
|
88
87
|
}));
|
|
89
88
|
return nextOperation;
|
|
90
89
|
}
|
|
91
|
-
if (override.responseSchema || override.responseStatus || override.responseDescription) {
|
|
92
|
-
const status = override.responseStatus ?? "200";
|
|
93
|
-
nextOperation.responses = { [status]: jsonResponse(override.responseDescription ?? "Successful response", override.responseSchema ? toSchema(override.responseSchema) : undefined) };
|
|
94
|
-
}
|
|
90
|
+
if (override.responseSchema || override.responseStatus || override.responseDescription) nextOperation.responses = { [override.responseStatus ?? "200"]: jsonResponse(override.responseDescription ?? "Successful response", override.responseSchema ? toSchema(override.responseSchema) : void 0) };
|
|
95
91
|
return nextOperation;
|
|
96
92
|
}
|
|
97
93
|
function ensurePath(paths, path) {
|
|
@@ -158,13 +154,12 @@ function registerViewSetDescriptor(paths, schemas, descriptor) {
|
|
|
158
154
|
const writeSchema = toSchema(metadata.createSchema);
|
|
159
155
|
const updateSchema = toSchema(metadata.updateSchema);
|
|
160
156
|
ensureModelSchema(schemas, metadata.model.metadata);
|
|
161
|
-
|
|
157
|
+
setOperation(paths, collectionPath, "GET", withOverride({
|
|
162
158
|
summary: `List ${modelName}s`,
|
|
163
159
|
tags,
|
|
164
160
|
parameters: buildListParameters(stringifyFields(metadata.searchFields), stringifyFields(metadata.orderingFields), metadata.usesDefaultOffsetPagination),
|
|
165
|
-
responses: { "200": jsonResponse("Successful response", metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) :
|
|
166
|
-
},
|
|
167
|
-
setOperation(paths, collectionPath, "GET", listOperation);
|
|
161
|
+
responses: { "200": jsonResponse("Successful response", metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) : void 0) }
|
|
162
|
+
}, void 0, tags));
|
|
168
163
|
setOperation(paths, collectionPath, "POST", {
|
|
169
164
|
summary: `Create ${modelName}`,
|
|
170
165
|
tags,
|
|
@@ -235,7 +230,7 @@ function registerGenericDescriptor(paths, schemas, descriptor) {
|
|
|
235
230
|
summary: `List ${modelName}s`,
|
|
236
231
|
tags,
|
|
237
232
|
parameters: buildListParameters(stringifyFields(metadata.searchFields), stringifyFields(metadata.orderingFields), metadata.usesDefaultOffsetPagination),
|
|
238
|
-
responses: { "200": jsonResponse("Successful response", metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) :
|
|
233
|
+
responses: { "200": jsonResponse("Successful response", metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) : void 0) }
|
|
239
234
|
}, descriptor.methods?.GET, tags));
|
|
240
235
|
if (allowed.has("POST")) setOperation(paths, collectionPath, "POST", withOverride({
|
|
241
236
|
summary: `Create ${modelName}`,
|
|
@@ -296,10 +291,13 @@ function registerAPIViewDescriptor(paths, descriptor) {
|
|
|
296
291
|
if (!allowed.has(method)) throw new Error(`APIView method '${method}' is not implemented on ${descriptor.resource.constructor.name}.`);
|
|
297
292
|
setOperation(paths, path, method, withOverride({
|
|
298
293
|
summary: `${method} ${titleize(descriptor.resource.constructor.name.replace(/APIView$/, ""))}`.trim(),
|
|
299
|
-
responses: { [override.responseStatus ?? "200"]: jsonResponse(override.responseDescription ?? "Successful response", override.responseSchema ? toSchema(override.responseSchema) :
|
|
294
|
+
responses: { [override.responseStatus ?? "200"]: jsonResponse(override.responseDescription ?? "Successful response", override.responseSchema ? toSchema(override.responseSchema) : void 0) }
|
|
300
295
|
}, override, descriptor.tags ?? [descriptor.resource.constructor.name.replace(/APIView$/, "") || "APIView"]));
|
|
301
296
|
}
|
|
302
297
|
}
|
|
298
|
+
/**
|
|
299
|
+
* Build an OpenAPI 3.1 document from Tango resource configuration.
|
|
300
|
+
*/
|
|
303
301
|
function generateOpenAPISpec(config) {
|
|
304
302
|
const paths = {};
|
|
305
303
|
const schemas = {};
|
|
@@ -327,20 +325,16 @@ function registerDescriptor(paths, schemas, descriptor) {
|
|
|
327
325
|
}
|
|
328
326
|
registerAPIViewDescriptor(paths, descriptor);
|
|
329
327
|
}
|
|
330
|
-
|
|
331
328
|
//#endregion
|
|
332
329
|
//#region src/generators/spec/index.ts
|
|
333
|
-
var spec_exports = {};
|
|
334
|
-
__export(spec_exports, { generateOpenAPISpec: () => generateOpenAPISpec });
|
|
335
|
-
|
|
330
|
+
var spec_exports = /* @__PURE__ */ __exportAll({ generateOpenAPISpec: () => generateOpenAPISpec });
|
|
336
331
|
//#endregion
|
|
337
332
|
//#region src/generators/index.ts
|
|
338
|
-
var generators_exports = {
|
|
339
|
-
__export(generators_exports, {
|
|
333
|
+
var generators_exports = /* @__PURE__ */ __exportAll({
|
|
340
334
|
generateOpenAPISpec: () => generateOpenAPISpec,
|
|
341
335
|
spec: () => spec_exports
|
|
342
336
|
});
|
|
343
|
-
|
|
344
337
|
//#endregion
|
|
345
|
-
export { generateOpenAPISpec, generators_exports
|
|
346
|
-
|
|
338
|
+
export { spec_exports as n, generateOpenAPISpec as r, generators_exports as t };
|
|
339
|
+
|
|
340
|
+
//# sourceMappingURL=generators-BLTcbhxj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generators-BLTcbhxj.js","names":[],"sources":["../src/generators/spec/generateOpenAPISpec.ts","../src/generators/spec/index.ts","../src/generators/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { generateSchemaFromModel, generateSchemaFromZod } from '../../mappers/schema';\nimport type {\n OpenAPIAPIViewDescriptor,\n OpenAPIGeneratorConfig,\n OpenAPIGenericAPIViewDescriptor,\n OpenAPIOperationOverride,\n OpenAPIResourceDescriptor,\n OpenAPIViewSetDescriptor,\n OpenAPISpec,\n OperationObject,\n ParameterObject,\n PathItemObject,\n ReferenceObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n} from '../../domain';\n\nconst JSON_CONTENT_TYPE = 'application/json';\nconst HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] as const;\ntype HttpMethod = (typeof HTTP_METHODS)[number];\ntype PathMethodKey = Lowercase<HttpMethod>;\n\ntype ResourceModelMetadata = {\n name: string;\n fields: Array<{\n name: string;\n type: string;\n notNull?: boolean;\n default?: unknown;\n primaryKey?: boolean;\n }>;\n};\n\nfunction toOpenAPIModel(metadata: ResourceModelMetadata) {\n return {\n name: metadata.name,\n fields: Object.fromEntries(\n metadata.fields.map((field) => [\n field.name,\n {\n type: field.type,\n nullable: field.notNull !== true,\n default: field.default,\n primaryKey: field.primaryKey,\n },\n ])\n ),\n };\n}\n\nfunction normalizePath(path: string): string {\n const trimmed = path.trim();\n if (!trimmed) {\n throw new Error('OpenAPI paths must not be empty.');\n }\n if (/(^|\\/):/.test(trimmed)) {\n throw new Error(`OpenAPI paths must use {param} syntax, received '${trimmed}'.`);\n }\n\n const withLeadingSlash = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;\n if (withLeadingSlash === '/') {\n return '/';\n }\n\n return withLeadingSlash.replace(/\\/+$/g, '');\n}\n\nfunction joinPath(base: string, segment: string): string {\n const normalizedSegment = segment.replace(/^\\/+|\\/+$/g, '');\n return base === '/' ? `/${normalizedSegment}` : `${base}/${normalizedSegment}`;\n}\n\nfunction toMethodKey(method: HttpMethod): PathMethodKey {\n return method.toLowerCase() as PathMethodKey;\n}\n\nfunction isReferenceObject(value: unknown): value is ReferenceObject {\n return typeof value === 'object' && value !== null && typeof (value as { $ref?: unknown }).$ref === 'string';\n}\n\nfunction isZodSchema(value: unknown): value is z.ZodType {\n // oxlint-disable-next-line eslint-js/no-restricted-syntax\n return value instanceof z.ZodType;\n}\n\nfunction toSchema(value: z.ZodType | SchemaObject | ReferenceObject): SchemaObject | ReferenceObject {\n if (isReferenceObject(value)) {\n return value;\n }\n if (isZodSchema(value)) {\n return generateSchemaFromZod(value);\n }\n return value;\n}\n\nfunction arraySchema(items: SchemaObject | ReferenceObject): SchemaObject {\n return {\n type: 'array',\n items,\n };\n}\n\nfunction paginatedResultsSchema(items: SchemaObject | ReferenceObject): SchemaObject {\n return {\n type: 'object',\n properties: {\n count: { type: 'integer' },\n next: { type: 'string' },\n previous: { type: 'string' },\n results: arraySchema(items),\n },\n required: ['count', 'results'],\n };\n}\n\nfunction jsonResponse(description: string, schema?: SchemaObject | ReferenceObject): ResponseObject {\n return schema\n ? {\n description,\n content: {\n [JSON_CONTENT_TYPE]: {\n schema,\n },\n },\n }\n : { description };\n}\n\nfunction jsonRequestBody(schema: SchemaObject | ReferenceObject, required: boolean = true): RequestBodyObject {\n return {\n required,\n content: {\n [JSON_CONTENT_TYPE]: {\n schema,\n },\n },\n };\n}\n\nfunction withOverride(\n operation: OperationObject,\n override: OpenAPIOperationOverride | undefined,\n fallbackTags: string[]\n): OperationObject {\n if (!override) {\n return operation;\n }\n\n const nextOperation: OperationObject = {\n ...operation,\n summary: override.summary ?? operation.summary,\n description: override.description ?? operation.description,\n tags: override.tags ?? operation.tags ?? fallbackTags,\n parameters: override.parameters ?? operation.parameters,\n requestBody: override.requestBody\n ? jsonRequestBody(toSchema(override.requestBody.schema), override.requestBody.required ?? true)\n : operation.requestBody,\n responses: operation.responses,\n };\n\n if (override.responses) {\n nextOperation.responses = Object.fromEntries(\n Object.entries(override.responses).map(([status, response]) => {\n return [\n status,\n jsonResponse(response.description, response.schema ? toSchema(response.schema) : undefined),\n ];\n })\n );\n return nextOperation;\n }\n\n if (override.responseSchema || override.responseStatus || override.responseDescription) {\n const status = override.responseStatus ?? '200';\n nextOperation.responses = {\n [status]: jsonResponse(\n override.responseDescription ?? 'Successful response',\n override.responseSchema ? toSchema(override.responseSchema) : undefined\n ),\n };\n }\n\n return nextOperation;\n}\n\nfunction ensurePath(paths: Record<string, PathItemObject>, path: string): PathItemObject {\n const existing = paths[path];\n if (existing) {\n return existing;\n }\n\n const created: PathItemObject = {};\n paths[path] = created;\n return created;\n}\n\nfunction setOperation(\n paths: Record<string, PathItemObject>,\n path: string,\n method: HttpMethod,\n operation: OperationObject\n): void {\n const pathItem = ensurePath(paths, path);\n pathItem[toMethodKey(method)] = operation;\n}\n\nfunction buildListParameters(\n searchFields: readonly string[],\n orderingFields: readonly string[],\n usesDefaultOffsetPagination: boolean\n): ParameterObject[] {\n const parameters: ParameterObject[] = [];\n\n if (usesDefaultOffsetPagination) {\n parameters.push(\n {\n name: 'limit',\n in: 'query',\n schema: { type: 'integer' },\n },\n {\n name: 'offset',\n in: 'query',\n schema: { type: 'integer' },\n }\n );\n }\n\n if (searchFields.length > 0) {\n parameters.push({\n name: 'search',\n in: 'query',\n schema: { type: 'string' },\n });\n }\n\n if (orderingFields.length > 0) {\n parameters.push({\n name: 'ordering',\n in: 'query',\n schema: { type: 'string' },\n });\n }\n\n return parameters;\n}\n\nfunction buildPathParameter(name: string): ParameterObject {\n return {\n name,\n in: 'path',\n required: true,\n schema: { type: 'string' },\n };\n}\n\nfunction stringifyFields(fields: readonly unknown[]): string[] {\n return fields.map(String);\n}\n\nfunction titleize(input: string): string {\n return input\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[-_]+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nfunction validateGenericDetailPath(detailPath: string, lookupParam: string): void {\n if (!detailPath.includes(`{${lookupParam}}`)) {\n throw new Error(`GenericAPIView detail paths must include '{${lookupParam}}', received '${detailPath}'.`);\n }\n}\n\nfunction ensureModelSchema(schemas: Record<string, SchemaObject>, metadata: ResourceModelMetadata): void {\n schemas[metadata.name] = generateSchemaFromModel(toOpenAPIModel(metadata));\n}\n\nfunction registerViewSetDescriptor(\n paths: Record<string, PathItemObject>,\n schemas: Record<string, SchemaObject>,\n descriptor: OpenAPIViewSetDescriptor\n): void {\n const metadata = descriptor.resource.describeOpenAPI();\n const modelName = metadata.model.metadata.name;\n const tags = descriptor.tags ?? [modelName];\n const collectionPath = normalizePath(descriptor.basePath);\n const detailPath = collectionPath === '/' ? '/{id}' : `${collectionPath}/{id}`;\n const readSchema = toSchema(metadata.outputSchema);\n const writeSchema = toSchema(metadata.createSchema);\n const updateSchema = toSchema(metadata.updateSchema);\n\n ensureModelSchema(schemas, metadata.model.metadata);\n\n const listOperation = withOverride(\n {\n summary: `List ${modelName}s`,\n tags,\n parameters: buildListParameters(\n stringifyFields(metadata.searchFields),\n stringifyFields(metadata.orderingFields),\n metadata.usesDefaultOffsetPagination\n ),\n responses: {\n '200': jsonResponse(\n 'Successful response',\n metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) : undefined\n ),\n },\n },\n undefined,\n tags\n );\n\n setOperation(paths, collectionPath, 'GET', listOperation);\n setOperation(paths, collectionPath, 'POST', {\n summary: `Create ${modelName}`,\n tags,\n requestBody: jsonRequestBody(writeSchema),\n responses: {\n '201': jsonResponse('Created', readSchema),\n },\n });\n setOperation(paths, detailPath, 'GET', {\n summary: `Get ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n responses: {\n '200': jsonResponse('Successful response', readSchema),\n '404': { description: 'Not found' },\n },\n });\n const updateResponses = {\n '200': jsonResponse('Updated', readSchema),\n '404': { description: 'Not found' },\n };\n setOperation(paths, detailPath, 'PUT', {\n summary: `Update ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n requestBody: jsonRequestBody(updateSchema),\n responses: updateResponses,\n });\n setOperation(paths, detailPath, 'PATCH', {\n summary: `Update ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n requestBody: jsonRequestBody(updateSchema),\n responses: updateResponses,\n });\n setOperation(paths, detailPath, 'DELETE', {\n summary: `Delete ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n responses: {\n '204': { description: 'Deleted' },\n '404': { description: 'Not found' },\n },\n });\n\n for (const action of metadata.actions) {\n const actionPath =\n action.scope === 'detail' ? joinPath(detailPath, action.path) : joinPath(collectionPath, action.path);\n const baseOperation: OperationObject = {\n summary: titleize(action.name),\n tags,\n ...(action.scope === 'detail' ? { parameters: [buildPathParameter('id')] } : {}),\n responses: {\n '200': { description: 'Successful response' },\n },\n };\n\n const override = descriptor.actions?.[action.name];\n for (const method of action.methods) {\n setOperation(paths, actionPath, method, withOverride(baseOperation, override, tags));\n }\n }\n}\n\nfunction registerGenericDescriptor(\n paths: Record<string, PathItemObject>,\n schemas: Record<string, SchemaObject>,\n descriptor: OpenAPIGenericAPIViewDescriptor\n): void {\n if (!descriptor.collectionPath && !descriptor.detailPath) {\n throw new Error('GenericAPIView OpenAPI descriptors require at least one of collectionPath or detailPath.');\n }\n\n const metadata = descriptor.resource.describeOpenAPI();\n const modelName = metadata.model.metadata.name;\n const tags = descriptor.tags ?? [modelName];\n const readSchema = toSchema(metadata.outputSchema);\n const writeSchema = toSchema(metadata.createSchema);\n const updateSchema = toSchema(metadata.updateSchema);\n const allowed = new Set(metadata.allowedMethods);\n\n ensureModelSchema(schemas, metadata.model.metadata);\n\n if (descriptor.collectionPath) {\n const collectionPath = normalizePath(descriptor.collectionPath);\n if (allowed.has('GET')) {\n setOperation(\n paths,\n collectionPath,\n 'GET',\n withOverride(\n {\n summary: `List ${modelName}s`,\n tags,\n parameters: buildListParameters(\n stringifyFields(metadata.searchFields),\n stringifyFields(metadata.orderingFields),\n metadata.usesDefaultOffsetPagination\n ),\n responses: {\n '200': jsonResponse(\n 'Successful response',\n metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) : undefined\n ),\n },\n },\n descriptor.methods?.GET,\n tags\n )\n );\n }\n\n if (allowed.has('POST')) {\n setOperation(\n paths,\n collectionPath,\n 'POST',\n withOverride(\n {\n summary: `Create ${modelName}`,\n tags,\n requestBody: jsonRequestBody(writeSchema),\n responses: {\n '201': jsonResponse('Created', readSchema),\n },\n },\n descriptor.methods?.POST,\n tags\n )\n );\n }\n }\n\n if (descriptor.detailPath) {\n const detailPath = normalizePath(descriptor.detailPath);\n validateGenericDetailPath(detailPath, metadata.lookupParam);\n const detailParameters = [buildPathParameter(metadata.lookupParam)];\n\n if (allowed.has('GET')) {\n setOperation(\n paths,\n detailPath,\n 'GET',\n withOverride(\n {\n summary: `Get ${modelName}`,\n tags,\n parameters: detailParameters,\n responses: {\n '200': jsonResponse('Successful response', readSchema),\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.GET,\n tags\n )\n );\n }\n\n if (allowed.has('PUT')) {\n setOperation(\n paths,\n detailPath,\n 'PUT',\n withOverride(\n {\n summary: `Update ${modelName}`,\n tags,\n parameters: detailParameters,\n requestBody: jsonRequestBody(updateSchema),\n responses: {\n '200': jsonResponse('Updated', readSchema),\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.PUT,\n tags\n )\n );\n }\n\n if (allowed.has('PATCH')) {\n setOperation(\n paths,\n detailPath,\n 'PATCH',\n withOverride(\n {\n summary: `Update ${modelName}`,\n tags,\n parameters: detailParameters,\n requestBody: jsonRequestBody(updateSchema),\n responses: {\n '200': jsonResponse('Updated', readSchema),\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.PATCH,\n tags\n )\n );\n }\n\n if (allowed.has('DELETE')) {\n setOperation(\n paths,\n detailPath,\n 'DELETE',\n withOverride(\n {\n summary: `Delete ${modelName}`,\n tags,\n parameters: detailParameters,\n responses: {\n '204': { description: 'Deleted' },\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.DELETE,\n tags\n )\n );\n }\n }\n}\n\nfunction registerAPIViewDescriptor(paths: Record<string, PathItemObject>, descriptor: OpenAPIAPIViewDescriptor): void {\n const path = normalizePath(descriptor.path);\n const allowed = new Set(descriptor.resource.getAllowedMethods());\n const methods = Object.entries(descriptor.methods) as Array<[HttpMethod, OpenAPIOperationOverride]>;\n\n for (const [method, override] of methods) {\n if (!allowed.has(method)) {\n throw new Error(\n `APIView method '${method}' is not implemented on ${descriptor.resource.constructor.name}.`\n );\n }\n\n setOperation(\n paths,\n path,\n method,\n withOverride(\n {\n summary:\n `${method} ${titleize(descriptor.resource.constructor.name.replace(/APIView$/, ''))}`.trim(),\n responses: {\n [(override.responseStatus ?? '200') as string]: jsonResponse(\n override.responseDescription ?? 'Successful response',\n override.responseSchema ? toSchema(override.responseSchema) : undefined\n ),\n },\n },\n override,\n descriptor.tags ?? [descriptor.resource.constructor.name.replace(/APIView$/, '') || 'APIView']\n )\n );\n }\n}\n\n/**\n * Build an OpenAPI 3.1 document from Tango resource configuration.\n */\nexport function generateOpenAPISpec(config: OpenAPIGeneratorConfig): OpenAPISpec {\n const paths: Record<string, PathItemObject> = {};\n const schemas: Record<string, SchemaObject> = {};\n\n for (const resource of config.resources ?? []) {\n registerDescriptor(paths, schemas, resource);\n }\n\n return {\n openapi: '3.1.0',\n info: {\n title: config.title,\n version: config.version,\n description: config.description,\n },\n servers: config.servers,\n paths,\n components: {\n schemas,\n },\n };\n}\n\nfunction registerDescriptor(\n paths: Record<string, PathItemObject>,\n schemas: Record<string, SchemaObject>,\n descriptor: OpenAPIResourceDescriptor\n): void {\n if (descriptor.kind === 'viewset') {\n registerViewSetDescriptor(paths, schemas, descriptor);\n return;\n }\n\n if (descriptor.kind === 'generic') {\n registerGenericDescriptor(paths, schemas, descriptor);\n return;\n }\n\n registerAPIViewDescriptor(paths, descriptor);\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateOpenAPISpec } from './generateOpenAPISpec';\n","/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as spec from './spec/index';\nexport { generateOpenAPISpec } from './spec/index';\n"],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { _ as OpenAPISpec, c as OpenAPIGeneratorConfig } from "./index-CjqHxnkO.js";
|
|
2
|
+
|
|
3
|
+
//#region src/generators/spec/generateOpenAPISpec.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Build an OpenAPI 3.1 document from Tango resource configuration.
|
|
6
|
+
*/
|
|
7
|
+
declare function generateOpenAPISpec(config: OpenAPIGeneratorConfig): OpenAPISpec;
|
|
8
|
+
declare namespace index_d_exports$1 {
|
|
9
|
+
export { generateOpenAPISpec };
|
|
10
|
+
}
|
|
11
|
+
declare namespace index_d_exports {
|
|
12
|
+
export { generateOpenAPISpec, index_d_exports$1 as spec };
|
|
13
|
+
}
|
|
14
|
+
//#endregion
|
|
15
|
+
export { index_d_exports$1 as n, generateOpenAPISpec as r, index_d_exports as t };
|
|
16
|
+
//# sourceMappingURL=index-C0KpWWY9.d.ts.map
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { APIView, APIViewMethod, AnyModelSerializer, AnyModelSerializerClass, GenericAPIView, ModelViewSet } from "@danceroutine/tango-resources";
|
|
3
|
+
|
|
4
|
+
//#region src/domain/types.d.ts
|
|
5
|
+
/** Model field metadata used by low-level model-to-schema OpenAPI generation. */
|
|
6
|
+
type OpenAPIModelFieldMeta = {
|
|
7
|
+
type: string;
|
|
8
|
+
description?: string;
|
|
9
|
+
nullable?: boolean;
|
|
10
|
+
default?: unknown;
|
|
11
|
+
primaryKey?: boolean;
|
|
12
|
+
};
|
|
13
|
+
/** Minimal model shape consumed by low-level OpenAPI mappers. */
|
|
14
|
+
type OpenAPIModel = {
|
|
15
|
+
name: string;
|
|
16
|
+
fields: Record<string, OpenAPIModelFieldMeta>;
|
|
17
|
+
};
|
|
18
|
+
/** OpenAPI `$ref` object. */
|
|
19
|
+
type ReferenceObject = {
|
|
20
|
+
$ref: string;
|
|
21
|
+
};
|
|
22
|
+
/** OpenAPI schema object subset used by Tango. */
|
|
23
|
+
type SchemaObject = {
|
|
24
|
+
type?: string;
|
|
25
|
+
description?: string;
|
|
26
|
+
nullable?: boolean;
|
|
27
|
+
default?: unknown;
|
|
28
|
+
properties?: Record<string, SchemaObject | ReferenceObject>;
|
|
29
|
+
required?: string[];
|
|
30
|
+
items?: SchemaObject | ReferenceObject;
|
|
31
|
+
additionalProperties?: boolean | SchemaObject | ReferenceObject;
|
|
32
|
+
enum?: unknown[];
|
|
33
|
+
oneOf?: Array<SchemaObject | ReferenceObject>;
|
|
34
|
+
anyOf?: Array<SchemaObject | ReferenceObject>;
|
|
35
|
+
allOf?: Array<SchemaObject | ReferenceObject>;
|
|
36
|
+
format?: string;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
};
|
|
39
|
+
/** Schema inputs accepted by resource-aware OpenAPI descriptors. */
|
|
40
|
+
type OpenAPISchemaInput = z.ZodType | SchemaObject | ReferenceObject;
|
|
41
|
+
/** OpenAPI media type object. */
|
|
42
|
+
type MediaTypeObject = {
|
|
43
|
+
schema: SchemaObject | ReferenceObject;
|
|
44
|
+
};
|
|
45
|
+
/** OpenAPI response object. */
|
|
46
|
+
type ResponseObject = {
|
|
47
|
+
description: string;
|
|
48
|
+
content?: Record<string, MediaTypeObject>;
|
|
49
|
+
};
|
|
50
|
+
/** OpenAPI parameter object. */
|
|
51
|
+
type ParameterObject = {
|
|
52
|
+
name: string;
|
|
53
|
+
in: 'query' | 'path' | 'header' | 'cookie';
|
|
54
|
+
required?: boolean;
|
|
55
|
+
schema: SchemaObject | ReferenceObject;
|
|
56
|
+
description?: string;
|
|
57
|
+
};
|
|
58
|
+
/** OpenAPI request body object. */
|
|
59
|
+
type RequestBodyObject = {
|
|
60
|
+
required?: boolean;
|
|
61
|
+
content: Record<string, MediaTypeObject>;
|
|
62
|
+
};
|
|
63
|
+
/** OpenAPI operation object subset. */
|
|
64
|
+
type OperationObject = {
|
|
65
|
+
summary?: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
tags?: string[];
|
|
68
|
+
parameters?: ParameterObject[];
|
|
69
|
+
requestBody?: RequestBodyObject;
|
|
70
|
+
responses: Record<string, ResponseObject>;
|
|
71
|
+
};
|
|
72
|
+
/** Override shape for one explicit response. */
|
|
73
|
+
type OpenAPIResponseOverride = {
|
|
74
|
+
description: string;
|
|
75
|
+
schema?: OpenAPISchemaInput;
|
|
76
|
+
};
|
|
77
|
+
/** Override shape for one operation. */
|
|
78
|
+
type OpenAPIOperationOverride = {
|
|
79
|
+
summary?: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
tags?: string[];
|
|
82
|
+
parameters?: ParameterObject[];
|
|
83
|
+
requestBody?: {
|
|
84
|
+
required?: boolean;
|
|
85
|
+
schema: OpenAPISchemaInput;
|
|
86
|
+
};
|
|
87
|
+
responseStatus?: string;
|
|
88
|
+
responseDescription?: string;
|
|
89
|
+
responseSchema?: OpenAPISchemaInput;
|
|
90
|
+
responses?: Record<string, OpenAPIResponseOverride>;
|
|
91
|
+
};
|
|
92
|
+
/** OpenAPI path item object subset. */
|
|
93
|
+
type PathItemObject = {
|
|
94
|
+
get?: OperationObject;
|
|
95
|
+
post?: OperationObject;
|
|
96
|
+
put?: OperationObject;
|
|
97
|
+
patch?: OperationObject;
|
|
98
|
+
delete?: OperationObject;
|
|
99
|
+
};
|
|
100
|
+
/** OpenAPI components object subset. */
|
|
101
|
+
type ComponentsObject = {
|
|
102
|
+
schemas?: Record<string, SchemaObject>;
|
|
103
|
+
securitySchemes?: Record<string, Record<string, unknown>>;
|
|
104
|
+
};
|
|
105
|
+
/** Root OpenAPI specification document shape. */
|
|
106
|
+
interface OpenAPISpec {
|
|
107
|
+
openapi: string;
|
|
108
|
+
info: {
|
|
109
|
+
title: string;
|
|
110
|
+
version: string;
|
|
111
|
+
description?: string;
|
|
112
|
+
};
|
|
113
|
+
servers?: Array<{
|
|
114
|
+
url: string;
|
|
115
|
+
description?: string;
|
|
116
|
+
}>;
|
|
117
|
+
paths: Record<string, PathItemObject>;
|
|
118
|
+
components?: ComponentsObject;
|
|
119
|
+
}
|
|
120
|
+
/** Options for generating an OpenAPI spec document. */
|
|
121
|
+
interface OpenAPIOptions {
|
|
122
|
+
title: string;
|
|
123
|
+
version: string;
|
|
124
|
+
description?: string;
|
|
125
|
+
servers?: Array<{
|
|
126
|
+
url: string;
|
|
127
|
+
description?: string;
|
|
128
|
+
}>;
|
|
129
|
+
}
|
|
130
|
+
type OpenAPIViewSetDescriptor<TModel extends Record<string, unknown> = Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>> = {
|
|
131
|
+
kind: 'viewset';
|
|
132
|
+
basePath: string;
|
|
133
|
+
resource: ModelViewSet<TModel, TSerializer>;
|
|
134
|
+
tags?: string[];
|
|
135
|
+
actions?: Record<string, OpenAPIOperationOverride>;
|
|
136
|
+
};
|
|
137
|
+
type OpenAPIGenericAPIViewDescriptor<TModel extends Record<string, unknown> = Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>> = {
|
|
138
|
+
kind: 'generic';
|
|
139
|
+
collectionPath?: string;
|
|
140
|
+
detailPath?: string;
|
|
141
|
+
resource: GenericAPIView<TModel, TSerializer>;
|
|
142
|
+
tags?: string[];
|
|
143
|
+
methods?: Partial<Record<APIViewMethod, OpenAPIOperationOverride>>;
|
|
144
|
+
};
|
|
145
|
+
type OpenAPIAPIViewDescriptor = {
|
|
146
|
+
kind: 'api';
|
|
147
|
+
path: string;
|
|
148
|
+
resource: APIView;
|
|
149
|
+
tags?: string[];
|
|
150
|
+
methods: Partial<Record<APIViewMethod, OpenAPIOperationOverride>>;
|
|
151
|
+
};
|
|
152
|
+
type AnyOpenAPIViewSetDescriptor = {
|
|
153
|
+
kind: 'viewset';
|
|
154
|
+
basePath: string;
|
|
155
|
+
resource: ModelViewSet<any, AnyModelSerializerClass>;
|
|
156
|
+
tags?: string[];
|
|
157
|
+
actions?: Record<string, OpenAPIOperationOverride>;
|
|
158
|
+
};
|
|
159
|
+
type AnyOpenAPIGenericAPIViewDescriptor = {
|
|
160
|
+
kind: 'generic';
|
|
161
|
+
collectionPath?: string;
|
|
162
|
+
detailPath?: string;
|
|
163
|
+
resource: GenericAPIView<any, AnyModelSerializerClass>;
|
|
164
|
+
tags?: string[];
|
|
165
|
+
methods?: Partial<Record<APIViewMethod, OpenAPIOperationOverride>>;
|
|
166
|
+
};
|
|
167
|
+
type OpenAPIResourceDescriptor = AnyOpenAPIViewSetDescriptor | AnyOpenAPIGenericAPIViewDescriptor | OpenAPIAPIViewDescriptor;
|
|
168
|
+
/** Extended generator configuration used by Tango's OpenAPI builder. */
|
|
169
|
+
type OpenAPIGeneratorConfig = OpenAPIOptions & {
|
|
170
|
+
resources?: OpenAPIResourceDescriptor[];
|
|
171
|
+
};
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/domain/describeResources.d.ts
|
|
174
|
+
declare function describeViewSet(descriptor: Omit<OpenAPIViewSetDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>): OpenAPIViewSetDescriptor;
|
|
175
|
+
declare function describeViewSet<TModel extends Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>>(descriptor: Omit<OpenAPIViewSetDescriptor<TModel, TSerializer>, 'kind'>): OpenAPIViewSetDescriptor<TModel, TSerializer>;
|
|
176
|
+
declare function describeGenericAPIView(descriptor: Omit<OpenAPIGenericAPIViewDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>): OpenAPIGenericAPIViewDescriptor;
|
|
177
|
+
declare function describeGenericAPIView<TModel extends Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>>(descriptor: Omit<OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>, 'kind'>): OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>;
|
|
178
|
+
declare function describeAPIView(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'>): OpenAPIAPIViewDescriptor;
|
|
179
|
+
declare function describeAPIView<TMethods extends Partial<Record<APIViewMethod, OpenAPIAPIViewDescriptor['methods'][APIViewMethod]>>>(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'> & {
|
|
180
|
+
methods: TMethods;
|
|
181
|
+
}): OpenAPIAPIViewDescriptor;
|
|
182
|
+
declare namespace index_d_exports {
|
|
183
|
+
export { ComponentsObject, MediaTypeObject, OpenAPIAPIViewDescriptor, OpenAPIGeneratorConfig, OpenAPIGenericAPIViewDescriptor, OpenAPIModel, OpenAPIModelFieldMeta, OpenAPIOperationOverride, OpenAPIOptions, OpenAPIResourceDescriptor, OpenAPIResponseOverride, OpenAPISchemaInput, OpenAPISpec, OpenAPIViewSetDescriptor, OperationObject, ParameterObject, PathItemObject, ReferenceObject, RequestBodyObject, ResponseObject, SchemaObject, describeAPIView, describeGenericAPIView, describeViewSet };
|
|
184
|
+
}
|
|
185
|
+
//#endregion
|
|
186
|
+
export { RequestBodyObject as C, ReferenceObject as S, SchemaObject as T, OpenAPISpec as _, ComponentsObject as a, ParameterObject as b, OpenAPIGeneratorConfig as c, OpenAPIModelFieldMeta as d, OpenAPIOperationOverride as f, OpenAPISchemaInput as g, OpenAPIResponseOverride as h, describeViewSet as i, OpenAPIGenericAPIViewDescriptor as l, OpenAPIResourceDescriptor as m, describeAPIView as n, MediaTypeObject as o, OpenAPIOptions as p, describeGenericAPIView as r, OpenAPIAPIViewDescriptor as s, index_d_exports as t, OpenAPIModel as u, OpenAPIViewSetDescriptor as v, ResponseObject as w, PathItemObject as x, OperationObject as y };
|
|
187
|
+
//# sourceMappingURL=index-CjqHxnkO.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { T as SchemaObject, u as OpenAPIModel } from "./index-CjqHxnkO.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
//#region src/mappers/schema/generateSchemaFromModel.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Derive an OpenAPI schema object from Tango model metadata.
|
|
7
|
+
*/
|
|
8
|
+
declare function generateSchemaFromModel(model: OpenAPIModel): SchemaObject;
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/mappers/schema/generateSchemaFromZod.d.ts
|
|
11
|
+
/**
|
|
12
|
+
* Derive an OpenAPI-compatible schema object from a Zod schema.
|
|
13
|
+
*/
|
|
14
|
+
declare function generateSchemaFromZod(schema: z.ZodType): SchemaObject;
|
|
15
|
+
//#endregion
|
|
16
|
+
//#region src/mappers/schema/mapTypeToOpenAPI.d.ts
|
|
17
|
+
/**
|
|
18
|
+
* Map Tango field types to OpenAPI scalar/object type names.
|
|
19
|
+
*/
|
|
20
|
+
declare function mapTypeToOpenAPI(type: string): string;
|
|
21
|
+
declare namespace index_d_exports$1 {
|
|
22
|
+
export { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI };
|
|
23
|
+
}
|
|
24
|
+
declare namespace index_d_exports {
|
|
25
|
+
export { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI, index_d_exports$1 as schema };
|
|
26
|
+
}
|
|
27
|
+
//#endregion
|
|
28
|
+
export { generateSchemaFromModel as a, generateSchemaFromZod as i, index_d_exports$1 as n, mapTypeToOpenAPI as r, index_d_exports as t };
|
|
29
|
+
//# sourceMappingURL=index-CyPT9p0e.d.ts.map
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export * as domain from './domain/index';
|
|
6
|
-
export * as generators from './generators/index';
|
|
7
|
-
export * as mappers from './mappers/index';
|
|
8
|
-
export type { OpenAPIAPIViewDescriptor, OpenAPIGeneratorConfig, OpenAPIModel, OpenAPIModelFieldMeta, OpenAPIOptions, OpenAPIOperationOverride, OpenAPIResponseOverride, OpenAPIResourceDescriptor, OpenAPISchemaInput, OpenAPISpec, OpenAPIGenericAPIViewDescriptor, OpenAPIViewSetDescriptor, } from './domain/index';
|
|
9
|
-
export { describeAPIView, describeGenericAPIView, describeViewSet } from './domain/index';
|
|
10
|
-
export { generateOpenAPISpec } from './generators/index';
|
|
11
|
-
export { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI } from './mappers/index';
|
|
1
|
+
import { _ as OpenAPISpec, c as OpenAPIGeneratorConfig, d as OpenAPIModelFieldMeta, f as OpenAPIOperationOverride, g as OpenAPISchemaInput, h as OpenAPIResponseOverride, i as describeViewSet, l as OpenAPIGenericAPIViewDescriptor, m as OpenAPIResourceDescriptor, n as describeAPIView, p as OpenAPIOptions, r as describeGenericAPIView, s as OpenAPIAPIViewDescriptor, t as index_d_exports, u as OpenAPIModel, v as OpenAPIViewSetDescriptor } from "./index-CjqHxnkO.js";
|
|
2
|
+
import { r as generateOpenAPISpec, t as index_d_exports$1 } from "./index-C0KpWWY9.js";
|
|
3
|
+
import { a as generateSchemaFromModel, i as generateSchemaFromZod, r as mapTypeToOpenAPI, t as index_d_exports$2 } from "./index-CyPT9p0e.js";
|
|
4
|
+
export { type OpenAPIAPIViewDescriptor, type OpenAPIGeneratorConfig, type OpenAPIGenericAPIViewDescriptor, type OpenAPIModel, type OpenAPIModelFieldMeta, type OpenAPIOperationOverride, type OpenAPIOptions, type OpenAPIResourceDescriptor, type OpenAPIResponseOverride, type OpenAPISchemaInput, type OpenAPISpec, type OpenAPIViewSetDescriptor, describeAPIView, describeGenericAPIView, describeViewSet, index_d_exports as domain, generateOpenAPISpec, generateSchemaFromModel, generateSchemaFromZod, index_d_exports$1 as generators, mapTypeToOpenAPI, index_d_exports$2 as mappers };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { describeAPIView, describeGenericAPIView,
|
|
2
|
-
import {
|
|
3
|
-
import { generateOpenAPISpec, generators_exports } from "./generators-
|
|
4
|
-
import { mappers_exports } from "./mappers
|
|
5
|
-
|
|
6
|
-
export { describeAPIView, describeGenericAPIView, describeViewSet, domain_exports as domain, generateOpenAPISpec, generateSchemaFromModel, generateSchemaFromZod, generators_exports as generators, mapTypeToOpenAPI, mappers_exports as mappers };
|
|
1
|
+
import { i as describeViewSet, n as describeAPIView, r as describeGenericAPIView, t as domain_exports } from "./domain-C8g_q6ip.js";
|
|
2
|
+
import { i as mapTypeToOpenAPI, n as generateSchemaFromZod, r as generateSchemaFromModel } from "./schema-DyzwamHF.js";
|
|
3
|
+
import { r as generateOpenAPISpec, t as generators_exports } from "./generators-BLTcbhxj.js";
|
|
4
|
+
import { t as mappers_exports } from "./mappers/index.js";
|
|
5
|
+
export { describeAPIView, describeGenericAPIView, describeViewSet, domain_exports as domain, generateOpenAPISpec, generateSchemaFromModel, generateSchemaFromZod, generators_exports as generators, mapTypeToOpenAPI, mappers_exports as mappers };
|
package/dist/mappers/index.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* imports and curated flat exports for TS-native ergonomics.
|
|
4
|
-
*/
|
|
5
|
-
export * as schema from './schema/index';
|
|
6
|
-
export { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI } from './schema/index';
|
|
1
|
+
import { a as generateSchemaFromModel, i as generateSchemaFromZod, n as index_d_exports, r as mapTypeToOpenAPI } from "../index-CyPT9p0e.js";
|
|
2
|
+
export { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI, index_d_exports as schema };
|
package/dist/mappers/index.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "../
|
|
1
|
+
import { t as __exportAll } from "../chunk-D7D4PA-g.js";
|
|
2
|
+
import { i as mapTypeToOpenAPI, n as generateSchemaFromZod, r as generateSchemaFromModel, t as schema_exports } from "../schema-DyzwamHF.js";
|
|
3
|
+
//#region src/mappers/index.ts
|
|
4
|
+
var mappers_exports = /* @__PURE__ */ __exportAll({
|
|
5
|
+
generateSchemaFromModel: () => generateSchemaFromModel,
|
|
6
|
+
generateSchemaFromZod: () => generateSchemaFromZod,
|
|
7
|
+
mapTypeToOpenAPI: () => mapTypeToOpenAPI,
|
|
8
|
+
schema: () => schema_exports
|
|
9
|
+
});
|
|
10
|
+
//#endregion
|
|
11
|
+
export { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI, schema_exports as schema, mappers_exports as t };
|
|
3
12
|
|
|
4
|
-
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/mappers/index.ts"],"sourcesContent":["/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as schema from './schema/index';\nexport { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI } from './schema/index';\n"],"mappings":""}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as __exportAll } from "./chunk-D7D4PA-g.js";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
-
|
|
4
3
|
//#region src/mappers/schema/mapTypeToOpenAPI.ts
|
|
4
|
+
/**
|
|
5
|
+
* Map Tango field types to OpenAPI scalar/object type names.
|
|
6
|
+
*/
|
|
5
7
|
function mapTypeToOpenAPI(type) {
|
|
6
|
-
|
|
8
|
+
return {
|
|
7
9
|
string: "string",
|
|
8
10
|
number: "number",
|
|
9
11
|
boolean: "boolean",
|
|
@@ -16,12 +18,13 @@ function mapTypeToOpenAPI(type) {
|
|
|
16
18
|
uuid: "string",
|
|
17
19
|
jsonb: "object",
|
|
18
20
|
timestamptz: "string"
|
|
19
|
-
};
|
|
20
|
-
return typeMap[type] || "string";
|
|
21
|
+
}[type] || "string";
|
|
21
22
|
}
|
|
22
|
-
|
|
23
23
|
//#endregion
|
|
24
24
|
//#region src/mappers/schema/generateSchemaFromModel.ts
|
|
25
|
+
/**
|
|
26
|
+
* Derive an OpenAPI schema object from Tango model metadata.
|
|
27
|
+
*/
|
|
25
28
|
function generateSchemaFromModel(model) {
|
|
26
29
|
const properties = {};
|
|
27
30
|
const required = [];
|
|
@@ -30,38 +33,35 @@ function generateSchemaFromModel(model) {
|
|
|
30
33
|
type: mapTypeToOpenAPI(meta.type),
|
|
31
34
|
description: meta.description
|
|
32
35
|
};
|
|
33
|
-
if (!meta.nullable && meta.default ===
|
|
36
|
+
if (!meta.nullable && meta.default === void 0 && !meta.primaryKey) required.push(name);
|
|
34
37
|
}
|
|
35
38
|
return {
|
|
36
39
|
type: "object",
|
|
37
40
|
properties,
|
|
38
|
-
required: required.length > 0 ? required :
|
|
41
|
+
required: required.length > 0 ? required : void 0
|
|
39
42
|
};
|
|
40
43
|
}
|
|
41
|
-
|
|
42
44
|
//#endregion
|
|
43
45
|
//#region src/mappers/schema/generateSchemaFromZod.ts
|
|
44
46
|
function stripDialect(schema) {
|
|
45
47
|
if (Array.isArray(schema)) return schema.map((entry) => stripDialect(entry));
|
|
46
|
-
if (schema && typeof schema === "object")
|
|
47
|
-
const input = schema;
|
|
48
|
-
return Object.fromEntries(Object.entries(input).filter(([key]) => key !== "$schema").map(([key, value]) => [key, stripDialect(value)]));
|
|
49
|
-
}
|
|
48
|
+
if (schema && typeof schema === "object") return Object.fromEntries(Object.entries(schema).filter(([key]) => key !== "$schema").map(([key, value]) => [key, stripDialect(value)]));
|
|
50
49
|
return schema;
|
|
51
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Derive an OpenAPI-compatible schema object from a Zod schema.
|
|
53
|
+
*/
|
|
52
54
|
function generateSchemaFromZod(schema) {
|
|
53
55
|
return stripDialect(z.toJSONSchema(schema));
|
|
54
56
|
}
|
|
55
|
-
|
|
56
57
|
//#endregion
|
|
57
58
|
//#region src/mappers/schema/index.ts
|
|
58
|
-
var schema_exports = {
|
|
59
|
-
__export(schema_exports, {
|
|
59
|
+
var schema_exports = /* @__PURE__ */ __exportAll({
|
|
60
60
|
generateSchemaFromModel: () => generateSchemaFromModel,
|
|
61
61
|
generateSchemaFromZod: () => generateSchemaFromZod,
|
|
62
62
|
mapTypeToOpenAPI: () => mapTypeToOpenAPI
|
|
63
63
|
});
|
|
64
|
-
|
|
65
64
|
//#endregion
|
|
66
|
-
export {
|
|
67
|
-
|
|
65
|
+
export { mapTypeToOpenAPI as i, generateSchemaFromZod as n, generateSchemaFromModel as r, schema_exports as t };
|
|
66
|
+
|
|
67
|
+
//# sourceMappingURL=schema-DyzwamHF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-DyzwamHF.js","names":["input"],"sources":["../src/mappers/schema/mapTypeToOpenAPI.ts","../src/mappers/schema/generateSchemaFromModel.ts","../src/mappers/schema/generateSchemaFromZod.ts","../src/mappers/schema/index.ts"],"sourcesContent":["/**\n * Map Tango field types to OpenAPI scalar/object type names.\n */\nexport function mapTypeToOpenAPI(type: string): string {\n const typeMap: Record<string, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'string',\n serial: 'integer',\n int: 'integer',\n bigint: 'integer',\n text: 'string',\n bool: 'boolean',\n uuid: 'string',\n jsonb: 'object',\n timestamptz: 'string',\n };\n\n return typeMap[type] || 'string';\n}\n","import type { OpenAPIModel, SchemaObject } from '../../domain';\nimport { mapTypeToOpenAPI } from './mapTypeToOpenAPI';\n\n/**\n * Derive an OpenAPI schema object from Tango model metadata.\n */\nexport function generateSchemaFromModel(model: OpenAPIModel): SchemaObject {\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n\n for (const [name, meta] of Object.entries(model.fields)) {\n properties[name] = {\n type: mapTypeToOpenAPI(meta.type),\n description: meta.description,\n };\n\n if (!meta.nullable && meta.default === undefined && !meta.primaryKey) {\n required.push(name);\n }\n }\n\n return {\n type: 'object',\n properties,\n required: required.length > 0 ? required : undefined,\n };\n}\n","import { z } from 'zod';\nimport type { SchemaObject } from '../../domain';\n\nfunction stripDialect(schema: unknown): unknown {\n if (Array.isArray(schema)) {\n return schema.map((entry) => stripDialect(entry));\n }\n\n if (schema && typeof schema === 'object') {\n const input = schema as Record<string, unknown>;\n return Object.fromEntries(\n Object.entries(input)\n .filter(([key]) => key !== '$schema')\n .map(([key, value]) => [key, stripDialect(value)])\n );\n }\n\n return schema;\n}\n\n/**\n * Derive an OpenAPI-compatible schema object from a Zod schema.\n */\nexport function generateSchemaFromZod(schema: z.ZodType): SchemaObject {\n return stripDialect(z.toJSONSchema(schema)) as SchemaObject;\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateSchemaFromModel } from './generateSchemaFromModel';\nexport { generateSchemaFromZod } from './generateSchemaFromZod';\nexport { mapTypeToOpenAPI } from './mapTypeToOpenAPI';\n"],"mappings":";;;;;;AAGA,SAAgB,iBAAiB,MAAsB;CAgBnD,OAAO;EAdH,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,MAAM;EACN,QAAQ;EACR,KAAK;EACL,QAAQ;EACR,MAAM;EACN,MAAM;EACN,MAAM;EACN,OAAO;EACP,aAAa;CAGJ,EAAE,SAAS;AAC5B;;;;;;ACdA,SAAgB,wBAAwB,OAAmC;CACvE,MAAM,aAA2C,CAAC;CAClD,MAAM,WAAqB,CAAC;CAE5B,KAAK,MAAM,CAAC,MAAM,SAAS,OAAO,QAAQ,MAAM,MAAM,GAAG;EACrD,WAAW,QAAQ;GACf,MAAM,iBAAiB,KAAK,IAAI;GAChC,aAAa,KAAK;EACtB;EAEA,IAAI,CAAC,KAAK,YAAY,KAAK,YAAY,KAAA,KAAa,CAAC,KAAK,YACtD,SAAS,KAAK,IAAI;CAE1B;CAEA,OAAO;EACH,MAAM;EACN;EACA,UAAU,SAAS,SAAS,IAAI,WAAW,KAAA;CAC/C;AACJ;;;ACvBA,SAAS,aAAa,QAA0B;CAC5C,IAAI,MAAM,QAAQ,MAAM,GACpB,OAAO,OAAO,KAAK,UAAU,aAAa,KAAK,CAAC;CAGpD,IAAI,UAAU,OAAO,WAAW,UAE5B,OAAO,OAAO,YACV,OAAO,QAAQA,MAAK,EACf,QAAQ,CAAC,SAAS,QAAQ,SAAS,EACnC,KAAK,CAAC,KAAK,WAAW,CAAC,KAAK,aAAa,KAAK,CAAC,CAAC,CACzD;CAGJ,OAAO;AACX;;;;AAKA,SAAgB,sBAAsB,QAAiC;CACnE,OAAO,aAAa,EAAE,aAAa,MAAM,CAAC;AAC9C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@danceroutine/tango-openapi",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.2",
|
|
4
4
|
"description": "OpenAPI generation for Tango resources",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -41,15 +41,15 @@
|
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"zod": "^4.0.0",
|
|
44
|
-
"@danceroutine/tango-resources": "1.11.
|
|
44
|
+
"@danceroutine/tango-resources": "1.11.2"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^22.9.0",
|
|
48
|
-
"tsdown": "^0.
|
|
48
|
+
"tsdown": "^0.22.1",
|
|
49
49
|
"typescript": "^5.6.3",
|
|
50
|
-
"vitest": "^4.
|
|
51
|
-
"@danceroutine/tango-core": "1.11.
|
|
52
|
-
"@danceroutine/tango-testing": "1.11.
|
|
50
|
+
"vitest": "^4.1.7",
|
|
51
|
+
"@danceroutine/tango-core": "1.11.2",
|
|
52
|
+
"@danceroutine/tango-testing": "1.11.2"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"build": "tsdown",
|
package/dist/chunk-BkvOhyD0.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { APIViewMethod, AnyModelSerializer, AnyModelSerializerClass } from '@danceroutine/tango-resources';
|
|
2
|
-
import type { OpenAPIViewSetDescriptor, OpenAPIGenericAPIViewDescriptor, OpenAPIAPIViewDescriptor } from './types';
|
|
3
|
-
export declare function describeViewSet(descriptor: Omit<OpenAPIViewSetDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>): OpenAPIViewSetDescriptor;
|
|
4
|
-
export declare function describeViewSet<TModel extends Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>>(descriptor: Omit<OpenAPIViewSetDescriptor<TModel, TSerializer>, 'kind'>): OpenAPIViewSetDescriptor<TModel, TSerializer>;
|
|
5
|
-
export declare function describeGenericAPIView(descriptor: Omit<OpenAPIGenericAPIViewDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>): OpenAPIGenericAPIViewDescriptor;
|
|
6
|
-
export declare function describeGenericAPIView<TModel extends Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>>(descriptor: Omit<OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>, 'kind'>): OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>;
|
|
7
|
-
export declare function describeAPIView(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'>): OpenAPIAPIViewDescriptor;
|
|
8
|
-
export declare function describeAPIView<TMethods extends Partial<Record<APIViewMethod, OpenAPIAPIViewDescriptor['methods'][APIViewMethod]>>>(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'> & {
|
|
9
|
-
methods: TMethods;
|
|
10
|
-
}): OpenAPIAPIViewDescriptor;
|
package/dist/domain/types.d.ts
DELETED
|
@@ -1,170 +0,0 @@
|
|
|
1
|
-
import type { APIView, APIViewMethod, AnyModelSerializer, AnyModelSerializerClass, GenericAPIView, ModelViewSet } from '@danceroutine/tango-resources';
|
|
2
|
-
import type { z } from 'zod';
|
|
3
|
-
/** Model field metadata used by low-level model-to-schema OpenAPI generation. */
|
|
4
|
-
export type OpenAPIModelFieldMeta = {
|
|
5
|
-
type: string;
|
|
6
|
-
description?: string;
|
|
7
|
-
nullable?: boolean;
|
|
8
|
-
default?: unknown;
|
|
9
|
-
primaryKey?: boolean;
|
|
10
|
-
};
|
|
11
|
-
/** Minimal model shape consumed by low-level OpenAPI mappers. */
|
|
12
|
-
export type OpenAPIModel = {
|
|
13
|
-
name: string;
|
|
14
|
-
fields: Record<string, OpenAPIModelFieldMeta>;
|
|
15
|
-
};
|
|
16
|
-
/** OpenAPI `$ref` object. */
|
|
17
|
-
export type ReferenceObject = {
|
|
18
|
-
$ref: string;
|
|
19
|
-
};
|
|
20
|
-
/** OpenAPI schema object subset used by Tango. */
|
|
21
|
-
export type SchemaObject = {
|
|
22
|
-
type?: string;
|
|
23
|
-
description?: string;
|
|
24
|
-
nullable?: boolean;
|
|
25
|
-
default?: unknown;
|
|
26
|
-
properties?: Record<string, SchemaObject | ReferenceObject>;
|
|
27
|
-
required?: string[];
|
|
28
|
-
items?: SchemaObject | ReferenceObject;
|
|
29
|
-
additionalProperties?: boolean | SchemaObject | ReferenceObject;
|
|
30
|
-
enum?: unknown[];
|
|
31
|
-
oneOf?: Array<SchemaObject | ReferenceObject>;
|
|
32
|
-
anyOf?: Array<SchemaObject | ReferenceObject>;
|
|
33
|
-
allOf?: Array<SchemaObject | ReferenceObject>;
|
|
34
|
-
format?: string;
|
|
35
|
-
[key: string]: unknown;
|
|
36
|
-
};
|
|
37
|
-
/** Schema inputs accepted by resource-aware OpenAPI descriptors. */
|
|
38
|
-
export type OpenAPISchemaInput = z.ZodType | SchemaObject | ReferenceObject;
|
|
39
|
-
/** OpenAPI media type object. */
|
|
40
|
-
export type MediaTypeObject = {
|
|
41
|
-
schema: SchemaObject | ReferenceObject;
|
|
42
|
-
};
|
|
43
|
-
/** OpenAPI response object. */
|
|
44
|
-
export type ResponseObject = {
|
|
45
|
-
description: string;
|
|
46
|
-
content?: Record<string, MediaTypeObject>;
|
|
47
|
-
};
|
|
48
|
-
/** OpenAPI parameter object. */
|
|
49
|
-
export type ParameterObject = {
|
|
50
|
-
name: string;
|
|
51
|
-
in: 'query' | 'path' | 'header' | 'cookie';
|
|
52
|
-
required?: boolean;
|
|
53
|
-
schema: SchemaObject | ReferenceObject;
|
|
54
|
-
description?: string;
|
|
55
|
-
};
|
|
56
|
-
/** OpenAPI request body object. */
|
|
57
|
-
export type RequestBodyObject = {
|
|
58
|
-
required?: boolean;
|
|
59
|
-
content: Record<string, MediaTypeObject>;
|
|
60
|
-
};
|
|
61
|
-
/** OpenAPI operation object subset. */
|
|
62
|
-
export type OperationObject = {
|
|
63
|
-
summary?: string;
|
|
64
|
-
description?: string;
|
|
65
|
-
tags?: string[];
|
|
66
|
-
parameters?: ParameterObject[];
|
|
67
|
-
requestBody?: RequestBodyObject;
|
|
68
|
-
responses: Record<string, ResponseObject>;
|
|
69
|
-
};
|
|
70
|
-
/** Override shape for one explicit response. */
|
|
71
|
-
export type OpenAPIResponseOverride = {
|
|
72
|
-
description: string;
|
|
73
|
-
schema?: OpenAPISchemaInput;
|
|
74
|
-
};
|
|
75
|
-
/** Override shape for one operation. */
|
|
76
|
-
export type OpenAPIOperationOverride = {
|
|
77
|
-
summary?: string;
|
|
78
|
-
description?: string;
|
|
79
|
-
tags?: string[];
|
|
80
|
-
parameters?: ParameterObject[];
|
|
81
|
-
requestBody?: {
|
|
82
|
-
required?: boolean;
|
|
83
|
-
schema: OpenAPISchemaInput;
|
|
84
|
-
};
|
|
85
|
-
responseStatus?: string;
|
|
86
|
-
responseDescription?: string;
|
|
87
|
-
responseSchema?: OpenAPISchemaInput;
|
|
88
|
-
responses?: Record<string, OpenAPIResponseOverride>;
|
|
89
|
-
};
|
|
90
|
-
/** OpenAPI path item object subset. */
|
|
91
|
-
export type PathItemObject = {
|
|
92
|
-
get?: OperationObject;
|
|
93
|
-
post?: OperationObject;
|
|
94
|
-
put?: OperationObject;
|
|
95
|
-
patch?: OperationObject;
|
|
96
|
-
delete?: OperationObject;
|
|
97
|
-
};
|
|
98
|
-
/** OpenAPI components object subset. */
|
|
99
|
-
export type ComponentsObject = {
|
|
100
|
-
schemas?: Record<string, SchemaObject>;
|
|
101
|
-
securitySchemes?: Record<string, Record<string, unknown>>;
|
|
102
|
-
};
|
|
103
|
-
/** Root OpenAPI specification document shape. */
|
|
104
|
-
export interface OpenAPISpec {
|
|
105
|
-
openapi: string;
|
|
106
|
-
info: {
|
|
107
|
-
title: string;
|
|
108
|
-
version: string;
|
|
109
|
-
description?: string;
|
|
110
|
-
};
|
|
111
|
-
servers?: Array<{
|
|
112
|
-
url: string;
|
|
113
|
-
description?: string;
|
|
114
|
-
}>;
|
|
115
|
-
paths: Record<string, PathItemObject>;
|
|
116
|
-
components?: ComponentsObject;
|
|
117
|
-
}
|
|
118
|
-
/** Options for generating an OpenAPI spec document. */
|
|
119
|
-
export interface OpenAPIOptions {
|
|
120
|
-
title: string;
|
|
121
|
-
version: string;
|
|
122
|
-
description?: string;
|
|
123
|
-
servers?: Array<{
|
|
124
|
-
url: string;
|
|
125
|
-
description?: string;
|
|
126
|
-
}>;
|
|
127
|
-
}
|
|
128
|
-
export type OpenAPIViewSetDescriptor<TModel extends Record<string, unknown> = Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>> = {
|
|
129
|
-
kind: 'viewset';
|
|
130
|
-
basePath: string;
|
|
131
|
-
resource: ModelViewSet<TModel, TSerializer>;
|
|
132
|
-
tags?: string[];
|
|
133
|
-
actions?: Record<string, OpenAPIOperationOverride>;
|
|
134
|
-
};
|
|
135
|
-
export type OpenAPIGenericAPIViewDescriptor<TModel extends Record<string, unknown> = Record<string, unknown>, TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>> = {
|
|
136
|
-
kind: 'generic';
|
|
137
|
-
collectionPath?: string;
|
|
138
|
-
detailPath?: string;
|
|
139
|
-
resource: GenericAPIView<TModel, TSerializer>;
|
|
140
|
-
tags?: string[];
|
|
141
|
-
methods?: Partial<Record<APIViewMethod, OpenAPIOperationOverride>>;
|
|
142
|
-
};
|
|
143
|
-
export type OpenAPIAPIViewDescriptor = {
|
|
144
|
-
kind: 'api';
|
|
145
|
-
path: string;
|
|
146
|
-
resource: APIView;
|
|
147
|
-
tags?: string[];
|
|
148
|
-
methods: Partial<Record<APIViewMethod, OpenAPIOperationOverride>>;
|
|
149
|
-
};
|
|
150
|
-
type AnyOpenAPIViewSetDescriptor = {
|
|
151
|
-
kind: 'viewset';
|
|
152
|
-
basePath: string;
|
|
153
|
-
resource: ModelViewSet<any, AnyModelSerializerClass>;
|
|
154
|
-
tags?: string[];
|
|
155
|
-
actions?: Record<string, OpenAPIOperationOverride>;
|
|
156
|
-
};
|
|
157
|
-
type AnyOpenAPIGenericAPIViewDescriptor = {
|
|
158
|
-
kind: 'generic';
|
|
159
|
-
collectionPath?: string;
|
|
160
|
-
detailPath?: string;
|
|
161
|
-
resource: GenericAPIView<any, AnyModelSerializerClass>;
|
|
162
|
-
tags?: string[];
|
|
163
|
-
methods?: Partial<Record<APIViewMethod, OpenAPIOperationOverride>>;
|
|
164
|
-
};
|
|
165
|
-
export type OpenAPIResourceDescriptor = AnyOpenAPIViewSetDescriptor | AnyOpenAPIGenericAPIViewDescriptor | OpenAPIAPIViewDescriptor;
|
|
166
|
-
/** Extended generator configuration used by Tango's OpenAPI builder. */
|
|
167
|
-
export type OpenAPIGeneratorConfig = OpenAPIOptions & {
|
|
168
|
-
resources?: OpenAPIResourceDescriptor[];
|
|
169
|
-
};
|
|
170
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domain-B-7sApJT.js","names":["descriptor: Omit<OpenAPIViewSetDescriptor, 'kind'>","descriptor: Omit<OpenAPIGenericAPIViewDescriptor, 'kind'>","descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'>"],"sources":["../src/domain/describeResources.ts","../src/domain/index.ts"],"sourcesContent":["import type { APIViewMethod, AnyModelSerializer, AnyModelSerializerClass } from '@danceroutine/tango-resources';\nimport type { OpenAPIViewSetDescriptor, OpenAPIGenericAPIViewDescriptor, OpenAPIAPIViewDescriptor } from './types';\n\nexport function describeViewSet(\n descriptor: Omit<OpenAPIViewSetDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>\n): OpenAPIViewSetDescriptor;\nexport function describeViewSet<\n TModel extends Record<string, unknown>,\n TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>,\n>(\n descriptor: Omit<OpenAPIViewSetDescriptor<TModel, TSerializer>, 'kind'>\n): OpenAPIViewSetDescriptor<TModel, TSerializer>;\nexport function describeViewSet(descriptor: Omit<OpenAPIViewSetDescriptor, 'kind'>) {\n return {\n kind: 'viewset',\n ...descriptor,\n };\n}\n\nexport function describeGenericAPIView(\n descriptor: Omit<OpenAPIGenericAPIViewDescriptor<Record<string, unknown>, AnyModelSerializerClass>, 'kind'>\n): OpenAPIGenericAPIViewDescriptor;\nexport function describeGenericAPIView<\n TModel extends Record<string, unknown>,\n TSerializer extends AnyModelSerializer<TModel> = AnyModelSerializer<TModel>,\n>(\n descriptor: Omit<OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>, 'kind'>\n): OpenAPIGenericAPIViewDescriptor<TModel, TSerializer>;\nexport function describeGenericAPIView(descriptor: Omit<OpenAPIGenericAPIViewDescriptor, 'kind'>) {\n return {\n kind: 'generic',\n ...descriptor,\n };\n}\n\nexport function describeAPIView(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'>): OpenAPIAPIViewDescriptor;\nexport function describeAPIView<\n TMethods extends Partial<Record<APIViewMethod, OpenAPIAPIViewDescriptor['methods'][APIViewMethod]>>,\n>(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'> & { methods: TMethods }): OpenAPIAPIViewDescriptor;\nexport function describeAPIView(descriptor: Omit<OpenAPIAPIViewDescriptor, 'kind'>) {\n return {\n kind: 'api',\n ...descriptor,\n };\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type {\n ComponentsObject,\n MediaTypeObject,\n OperationObject,\n OpenAPIAPIViewDescriptor,\n OpenAPIModel,\n OpenAPIModelFieldMeta,\n OpenAPIOptions,\n OpenAPIOperationOverride,\n OpenAPIResponseOverride,\n OpenAPIResourceDescriptor,\n OpenAPISchemaInput,\n OpenAPISpec,\n OpenAPIGeneratorConfig,\n OpenAPIGenericAPIViewDescriptor,\n OpenAPIViewSetDescriptor,\n ParameterObject,\n PathItemObject,\n ReferenceObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n} from './types';\nexport { describeAPIView, describeGenericAPIView, describeViewSet } from './describeResources';\n"],"mappings":";;;AAYO,SAAS,gBAAgBA,YAAoD;AAChF,QAAO;EACH,MAAM;EACN,GAAG;CACN;AACJ;AAWM,SAAS,uBAAuBC,YAA2D;AAC9F,QAAO;EACH,MAAM;EACN,GAAG;CACN;AACJ;AAMM,SAAS,gBAAgBC,YAAoD;AAChF,QAAO;EACH,MAAM;EACN,GAAG;CACN;AACJ"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generators-JMALItMS.js","names":["metadata: ResourceModelMetadata","path: string","base: string","segment: string","method: HttpMethod","value: unknown","value: z.ZodType | SchemaObject | ReferenceObject","items: SchemaObject | ReferenceObject","description: string","schema?: SchemaObject | ReferenceObject","schema: SchemaObject | ReferenceObject","required: boolean","operation: OperationObject","override: OpenAPIOperationOverride | undefined","fallbackTags: string[]","nextOperation: OperationObject","paths: Record<string, PathItemObject>","created: PathItemObject","searchFields: readonly string[]","orderingFields: readonly string[]","usesDefaultOffsetPagination: boolean","parameters: ParameterObject[]","name: string","fields: readonly unknown[]","input: string","detailPath: string","lookupParam: string","schemas: Record<string, SchemaObject>","descriptor: OpenAPIViewSetDescriptor","baseOperation: OperationObject","descriptor: OpenAPIGenericAPIViewDescriptor","descriptor: OpenAPIAPIViewDescriptor","config: OpenAPIGeneratorConfig","descriptor: OpenAPIResourceDescriptor"],"sources":["../src/generators/spec/generateOpenAPISpec.ts","../src/generators/spec/index.ts","../src/generators/index.ts"],"sourcesContent":["import { z } from 'zod';\nimport { generateSchemaFromModel, generateSchemaFromZod } from '../../mappers/schema';\nimport type {\n OpenAPIAPIViewDescriptor,\n OpenAPIGeneratorConfig,\n OpenAPIGenericAPIViewDescriptor,\n OpenAPIOperationOverride,\n OpenAPIResourceDescriptor,\n OpenAPIViewSetDescriptor,\n OpenAPISpec,\n OperationObject,\n ParameterObject,\n PathItemObject,\n ReferenceObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n} from '../../domain';\n\nconst JSON_CONTENT_TYPE = 'application/json';\nconst HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'] as const;\ntype HttpMethod = (typeof HTTP_METHODS)[number];\ntype PathMethodKey = Lowercase<HttpMethod>;\n\ntype ResourceModelMetadata = {\n name: string;\n fields: Array<{\n name: string;\n type: string;\n notNull?: boolean;\n default?: unknown;\n primaryKey?: boolean;\n }>;\n};\n\nfunction toOpenAPIModel(metadata: ResourceModelMetadata) {\n return {\n name: metadata.name,\n fields: Object.fromEntries(\n metadata.fields.map((field) => [\n field.name,\n {\n type: field.type,\n nullable: field.notNull !== true,\n default: field.default,\n primaryKey: field.primaryKey,\n },\n ])\n ),\n };\n}\n\nfunction normalizePath(path: string): string {\n const trimmed = path.trim();\n if (!trimmed) {\n throw new Error('OpenAPI paths must not be empty.');\n }\n if (/(^|\\/):/.test(trimmed)) {\n throw new Error(`OpenAPI paths must use {param} syntax, received '${trimmed}'.`);\n }\n\n const withLeadingSlash = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;\n if (withLeadingSlash === '/') {\n return '/';\n }\n\n return withLeadingSlash.replace(/\\/+$/g, '');\n}\n\nfunction joinPath(base: string, segment: string): string {\n const normalizedSegment = segment.replace(/^\\/+|\\/+$/g, '');\n return base === '/' ? `/${normalizedSegment}` : `${base}/${normalizedSegment}`;\n}\n\nfunction toMethodKey(method: HttpMethod): PathMethodKey {\n return method.toLowerCase() as PathMethodKey;\n}\n\nfunction isReferenceObject(value: unknown): value is ReferenceObject {\n return typeof value === 'object' && value !== null && typeof (value as { $ref?: unknown }).$ref === 'string';\n}\n\nfunction isZodSchema(value: unknown): value is z.ZodType {\n // oxlint-disable-next-line eslint-js/no-restricted-syntax\n return value instanceof z.ZodType;\n}\n\nfunction toSchema(value: z.ZodType | SchemaObject | ReferenceObject): SchemaObject | ReferenceObject {\n if (isReferenceObject(value)) {\n return value;\n }\n if (isZodSchema(value)) {\n return generateSchemaFromZod(value);\n }\n return value;\n}\n\nfunction arraySchema(items: SchemaObject | ReferenceObject): SchemaObject {\n return {\n type: 'array',\n items,\n };\n}\n\nfunction paginatedResultsSchema(items: SchemaObject | ReferenceObject): SchemaObject {\n return {\n type: 'object',\n properties: {\n count: { type: 'integer' },\n next: { type: 'string' },\n previous: { type: 'string' },\n results: arraySchema(items),\n },\n required: ['count', 'results'],\n };\n}\n\nfunction jsonResponse(description: string, schema?: SchemaObject | ReferenceObject): ResponseObject {\n return schema\n ? {\n description,\n content: {\n [JSON_CONTENT_TYPE]: {\n schema,\n },\n },\n }\n : { description };\n}\n\nfunction jsonRequestBody(schema: SchemaObject | ReferenceObject, required: boolean = true): RequestBodyObject {\n return {\n required,\n content: {\n [JSON_CONTENT_TYPE]: {\n schema,\n },\n },\n };\n}\n\nfunction withOverride(\n operation: OperationObject,\n override: OpenAPIOperationOverride | undefined,\n fallbackTags: string[]\n): OperationObject {\n if (!override) {\n return operation;\n }\n\n const nextOperation: OperationObject = {\n ...operation,\n summary: override.summary ?? operation.summary,\n description: override.description ?? operation.description,\n tags: override.tags ?? operation.tags ?? fallbackTags,\n parameters: override.parameters ?? operation.parameters,\n requestBody: override.requestBody\n ? jsonRequestBody(toSchema(override.requestBody.schema), override.requestBody.required ?? true)\n : operation.requestBody,\n responses: operation.responses,\n };\n\n if (override.responses) {\n nextOperation.responses = Object.fromEntries(\n Object.entries(override.responses).map(([status, response]) => {\n return [\n status,\n jsonResponse(response.description, response.schema ? toSchema(response.schema) : undefined),\n ];\n })\n );\n return nextOperation;\n }\n\n if (override.responseSchema || override.responseStatus || override.responseDescription) {\n const status = override.responseStatus ?? '200';\n nextOperation.responses = {\n [status]: jsonResponse(\n override.responseDescription ?? 'Successful response',\n override.responseSchema ? toSchema(override.responseSchema) : undefined\n ),\n };\n }\n\n return nextOperation;\n}\n\nfunction ensurePath(paths: Record<string, PathItemObject>, path: string): PathItemObject {\n const existing = paths[path];\n if (existing) {\n return existing;\n }\n\n const created: PathItemObject = {};\n paths[path] = created;\n return created;\n}\n\nfunction setOperation(\n paths: Record<string, PathItemObject>,\n path: string,\n method: HttpMethod,\n operation: OperationObject\n): void {\n const pathItem = ensurePath(paths, path);\n pathItem[toMethodKey(method)] = operation;\n}\n\nfunction buildListParameters(\n searchFields: readonly string[],\n orderingFields: readonly string[],\n usesDefaultOffsetPagination: boolean\n): ParameterObject[] {\n const parameters: ParameterObject[] = [];\n\n if (usesDefaultOffsetPagination) {\n parameters.push(\n {\n name: 'limit',\n in: 'query',\n schema: { type: 'integer' },\n },\n {\n name: 'offset',\n in: 'query',\n schema: { type: 'integer' },\n }\n );\n }\n\n if (searchFields.length > 0) {\n parameters.push({\n name: 'search',\n in: 'query',\n schema: { type: 'string' },\n });\n }\n\n if (orderingFields.length > 0) {\n parameters.push({\n name: 'ordering',\n in: 'query',\n schema: { type: 'string' },\n });\n }\n\n return parameters;\n}\n\nfunction buildPathParameter(name: string): ParameterObject {\n return {\n name,\n in: 'path',\n required: true,\n schema: { type: 'string' },\n };\n}\n\nfunction stringifyFields(fields: readonly unknown[]): string[] {\n return fields.map(String);\n}\n\nfunction titleize(input: string): string {\n return input\n .replace(/([a-z0-9])([A-Z])/g, '$1 $2')\n .replace(/[-_]+/g, ' ')\n .trim()\n .replace(/\\b\\w/g, (char) => char.toUpperCase());\n}\n\nfunction validateGenericDetailPath(detailPath: string, lookupParam: string): void {\n if (!detailPath.includes(`{${lookupParam}}`)) {\n throw new Error(`GenericAPIView detail paths must include '{${lookupParam}}', received '${detailPath}'.`);\n }\n}\n\nfunction ensureModelSchema(schemas: Record<string, SchemaObject>, metadata: ResourceModelMetadata): void {\n schemas[metadata.name] = generateSchemaFromModel(toOpenAPIModel(metadata));\n}\n\nfunction registerViewSetDescriptor(\n paths: Record<string, PathItemObject>,\n schemas: Record<string, SchemaObject>,\n descriptor: OpenAPIViewSetDescriptor\n): void {\n const metadata = descriptor.resource.describeOpenAPI();\n const modelName = metadata.model.metadata.name;\n const tags = descriptor.tags ?? [modelName];\n const collectionPath = normalizePath(descriptor.basePath);\n const detailPath = collectionPath === '/' ? '/{id}' : `${collectionPath}/{id}`;\n const readSchema = toSchema(metadata.outputSchema);\n const writeSchema = toSchema(metadata.createSchema);\n const updateSchema = toSchema(metadata.updateSchema);\n\n ensureModelSchema(schemas, metadata.model.metadata);\n\n const listOperation = withOverride(\n {\n summary: `List ${modelName}s`,\n tags,\n parameters: buildListParameters(\n stringifyFields(metadata.searchFields),\n stringifyFields(metadata.orderingFields),\n metadata.usesDefaultOffsetPagination\n ),\n responses: {\n '200': jsonResponse(\n 'Successful response',\n metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) : undefined\n ),\n },\n },\n undefined,\n tags\n );\n\n setOperation(paths, collectionPath, 'GET', listOperation);\n setOperation(paths, collectionPath, 'POST', {\n summary: `Create ${modelName}`,\n tags,\n requestBody: jsonRequestBody(writeSchema),\n responses: {\n '201': jsonResponse('Created', readSchema),\n },\n });\n setOperation(paths, detailPath, 'GET', {\n summary: `Get ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n responses: {\n '200': jsonResponse('Successful response', readSchema),\n '404': { description: 'Not found' },\n },\n });\n const updateResponses = {\n '200': jsonResponse('Updated', readSchema),\n '404': { description: 'Not found' },\n };\n setOperation(paths, detailPath, 'PUT', {\n summary: `Update ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n requestBody: jsonRequestBody(updateSchema),\n responses: updateResponses,\n });\n setOperation(paths, detailPath, 'PATCH', {\n summary: `Update ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n requestBody: jsonRequestBody(updateSchema),\n responses: updateResponses,\n });\n setOperation(paths, detailPath, 'DELETE', {\n summary: `Delete ${modelName}`,\n tags,\n parameters: [buildPathParameter('id')],\n responses: {\n '204': { description: 'Deleted' },\n '404': { description: 'Not found' },\n },\n });\n\n for (const action of metadata.actions) {\n const actionPath =\n action.scope === 'detail' ? joinPath(detailPath, action.path) : joinPath(collectionPath, action.path);\n const baseOperation: OperationObject = {\n summary: titleize(action.name),\n tags,\n ...(action.scope === 'detail' ? { parameters: [buildPathParameter('id')] } : {}),\n responses: {\n '200': { description: 'Successful response' },\n },\n };\n\n const override = descriptor.actions?.[action.name];\n for (const method of action.methods) {\n setOperation(paths, actionPath, method, withOverride(baseOperation, override, tags));\n }\n }\n}\n\nfunction registerGenericDescriptor(\n paths: Record<string, PathItemObject>,\n schemas: Record<string, SchemaObject>,\n descriptor: OpenAPIGenericAPIViewDescriptor\n): void {\n if (!descriptor.collectionPath && !descriptor.detailPath) {\n throw new Error('GenericAPIView OpenAPI descriptors require at least one of collectionPath or detailPath.');\n }\n\n const metadata = descriptor.resource.describeOpenAPI();\n const modelName = metadata.model.metadata.name;\n const tags = descriptor.tags ?? [modelName];\n const readSchema = toSchema(metadata.outputSchema);\n const writeSchema = toSchema(metadata.createSchema);\n const updateSchema = toSchema(metadata.updateSchema);\n const allowed = new Set(metadata.allowedMethods);\n\n ensureModelSchema(schemas, metadata.model.metadata);\n\n if (descriptor.collectionPath) {\n const collectionPath = normalizePath(descriptor.collectionPath);\n if (allowed.has('GET')) {\n setOperation(\n paths,\n collectionPath,\n 'GET',\n withOverride(\n {\n summary: `List ${modelName}s`,\n tags,\n parameters: buildListParameters(\n stringifyFields(metadata.searchFields),\n stringifyFields(metadata.orderingFields),\n metadata.usesDefaultOffsetPagination\n ),\n responses: {\n '200': jsonResponse(\n 'Successful response',\n metadata.usesDefaultOffsetPagination ? paginatedResultsSchema(readSchema) : undefined\n ),\n },\n },\n descriptor.methods?.GET,\n tags\n )\n );\n }\n\n if (allowed.has('POST')) {\n setOperation(\n paths,\n collectionPath,\n 'POST',\n withOverride(\n {\n summary: `Create ${modelName}`,\n tags,\n requestBody: jsonRequestBody(writeSchema),\n responses: {\n '201': jsonResponse('Created', readSchema),\n },\n },\n descriptor.methods?.POST,\n tags\n )\n );\n }\n }\n\n if (descriptor.detailPath) {\n const detailPath = normalizePath(descriptor.detailPath);\n validateGenericDetailPath(detailPath, metadata.lookupParam);\n const detailParameters = [buildPathParameter(metadata.lookupParam)];\n\n if (allowed.has('GET')) {\n setOperation(\n paths,\n detailPath,\n 'GET',\n withOverride(\n {\n summary: `Get ${modelName}`,\n tags,\n parameters: detailParameters,\n responses: {\n '200': jsonResponse('Successful response', readSchema),\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.GET,\n tags\n )\n );\n }\n\n if (allowed.has('PUT')) {\n setOperation(\n paths,\n detailPath,\n 'PUT',\n withOverride(\n {\n summary: `Update ${modelName}`,\n tags,\n parameters: detailParameters,\n requestBody: jsonRequestBody(updateSchema),\n responses: {\n '200': jsonResponse('Updated', readSchema),\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.PUT,\n tags\n )\n );\n }\n\n if (allowed.has('PATCH')) {\n setOperation(\n paths,\n detailPath,\n 'PATCH',\n withOverride(\n {\n summary: `Update ${modelName}`,\n tags,\n parameters: detailParameters,\n requestBody: jsonRequestBody(updateSchema),\n responses: {\n '200': jsonResponse('Updated', readSchema),\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.PATCH,\n tags\n )\n );\n }\n\n if (allowed.has('DELETE')) {\n setOperation(\n paths,\n detailPath,\n 'DELETE',\n withOverride(\n {\n summary: `Delete ${modelName}`,\n tags,\n parameters: detailParameters,\n responses: {\n '204': { description: 'Deleted' },\n '404': { description: 'Not found' },\n },\n },\n descriptor.methods?.DELETE,\n tags\n )\n );\n }\n }\n}\n\nfunction registerAPIViewDescriptor(paths: Record<string, PathItemObject>, descriptor: OpenAPIAPIViewDescriptor): void {\n const path = normalizePath(descriptor.path);\n const allowed = new Set(descriptor.resource.getAllowedMethods());\n const methods = Object.entries(descriptor.methods) as Array<[HttpMethod, OpenAPIOperationOverride]>;\n\n for (const [method, override] of methods) {\n if (!allowed.has(method)) {\n throw new Error(\n `APIView method '${method}' is not implemented on ${descriptor.resource.constructor.name}.`\n );\n }\n\n setOperation(\n paths,\n path,\n method,\n withOverride(\n {\n summary:\n `${method} ${titleize(descriptor.resource.constructor.name.replace(/APIView$/, ''))}`.trim(),\n responses: {\n [(override.responseStatus ?? '200') as string]: jsonResponse(\n override.responseDescription ?? 'Successful response',\n override.responseSchema ? toSchema(override.responseSchema) : undefined\n ),\n },\n },\n override,\n descriptor.tags ?? [descriptor.resource.constructor.name.replace(/APIView$/, '') || 'APIView']\n )\n );\n }\n}\n\n/**\n * Build an OpenAPI 3.1 document from Tango resource configuration.\n */\nexport function generateOpenAPISpec(config: OpenAPIGeneratorConfig): OpenAPISpec {\n const paths: Record<string, PathItemObject> = {};\n const schemas: Record<string, SchemaObject> = {};\n\n for (const resource of config.resources ?? []) {\n registerDescriptor(paths, schemas, resource);\n }\n\n return {\n openapi: '3.1.0',\n info: {\n title: config.title,\n version: config.version,\n description: config.description,\n },\n servers: config.servers,\n paths,\n components: {\n schemas,\n },\n };\n}\n\nfunction registerDescriptor(\n paths: Record<string, PathItemObject>,\n schemas: Record<string, SchemaObject>,\n descriptor: OpenAPIResourceDescriptor\n): void {\n if (descriptor.kind === 'viewset') {\n registerViewSetDescriptor(paths, schemas, descriptor);\n return;\n }\n\n if (descriptor.kind === 'generic') {\n registerGenericDescriptor(paths, schemas, descriptor);\n return;\n }\n\n registerAPIViewDescriptor(paths, descriptor);\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateOpenAPISpec } from './generateOpenAPISpec';\n","/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as spec from './spec/index';\nexport { generateOpenAPISpec } from './spec/index';\n"],"mappings":"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"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Domain boundary barrel: centralizes this subdomain's public contract.
|
|
3
|
-
*/
|
|
4
|
-
export { generateSchemaFromModel } from './generateSchemaFromModel';
|
|
5
|
-
export { generateSchemaFromZod } from './generateSchemaFromZod';
|
|
6
|
-
export { mapTypeToOpenAPI } from './mapTypeToOpenAPI';
|
package/dist/mappers-bmN95TGV.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { __export } from "./chunk-BkvOhyD0.js";
|
|
2
|
-
import { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI, schema_exports } from "./schema-D3ybOrpr.js";
|
|
3
|
-
|
|
4
|
-
//#region src/mappers/index.ts
|
|
5
|
-
var mappers_exports = {};
|
|
6
|
-
__export(mappers_exports, {
|
|
7
|
-
generateSchemaFromModel: () => generateSchemaFromModel,
|
|
8
|
-
generateSchemaFromZod: () => generateSchemaFromZod,
|
|
9
|
-
mapTypeToOpenAPI: () => mapTypeToOpenAPI,
|
|
10
|
-
schema: () => schema_exports
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
//#endregion
|
|
14
|
-
export { mappers_exports };
|
|
15
|
-
//# sourceMappingURL=mappers-bmN95TGV.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mappers-bmN95TGV.js","names":[],"sources":["../src/mappers/index.ts"],"sourcesContent":["/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as schema from './schema/index';\nexport { generateSchemaFromModel, generateSchemaFromZod, mapTypeToOpenAPI } from './schema/index';\n"],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"schema-D3ybOrpr.js","names":["type: string","typeMap: Record<string, string>","model: OpenAPIModel","properties: Record<string, SchemaObject>","required: string[]","schema: unknown","schema: z.ZodType"],"sources":["../src/mappers/schema/mapTypeToOpenAPI.ts","../src/mappers/schema/generateSchemaFromModel.ts","../src/mappers/schema/generateSchemaFromZod.ts","../src/mappers/schema/index.ts"],"sourcesContent":["/**\n * Map Tango field types to OpenAPI scalar/object type names.\n */\nexport function mapTypeToOpenAPI(type: string): string {\n const typeMap: Record<string, string> = {\n string: 'string',\n number: 'number',\n boolean: 'boolean',\n date: 'string',\n serial: 'integer',\n int: 'integer',\n bigint: 'integer',\n text: 'string',\n bool: 'boolean',\n uuid: 'string',\n jsonb: 'object',\n timestamptz: 'string',\n };\n\n return typeMap[type] || 'string';\n}\n","import type { OpenAPIModel, SchemaObject } from '../../domain';\nimport { mapTypeToOpenAPI } from './mapTypeToOpenAPI';\n\n/**\n * Derive an OpenAPI schema object from Tango model metadata.\n */\nexport function generateSchemaFromModel(model: OpenAPIModel): SchemaObject {\n const properties: Record<string, SchemaObject> = {};\n const required: string[] = [];\n\n for (const [name, meta] of Object.entries(model.fields)) {\n properties[name] = {\n type: mapTypeToOpenAPI(meta.type),\n description: meta.description,\n };\n\n if (!meta.nullable && meta.default === undefined && !meta.primaryKey) {\n required.push(name);\n }\n }\n\n return {\n type: 'object',\n properties,\n required: required.length > 0 ? required : undefined,\n };\n}\n","import { z } from 'zod';\nimport type { SchemaObject } from '../../domain';\n\nfunction stripDialect(schema: unknown): unknown {\n if (Array.isArray(schema)) {\n return schema.map((entry) => stripDialect(entry));\n }\n\n if (schema && typeof schema === 'object') {\n const input = schema as Record<string, unknown>;\n return Object.fromEntries(\n Object.entries(input)\n .filter(([key]) => key !== '$schema')\n .map(([key, value]) => [key, stripDialect(value)])\n );\n }\n\n return schema;\n}\n\n/**\n * Derive an OpenAPI-compatible schema object from a Zod schema.\n */\nexport function generateSchemaFromZod(schema: z.ZodType): SchemaObject {\n return stripDialect(z.toJSONSchema(schema)) as SchemaObject;\n}\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateSchemaFromModel } from './generateSchemaFromModel';\nexport { generateSchemaFromZod } from './generateSchemaFromZod';\nexport { mapTypeToOpenAPI } from './mapTypeToOpenAPI';\n"],"mappings":";;;;AAGO,SAAS,iBAAiBA,MAAsB;CACnD,MAAMC,UAAkC;EACpC,QAAQ;EACR,QAAQ;EACR,SAAS;EACT,MAAM;EACN,QAAQ;EACR,KAAK;EACL,QAAQ;EACR,MAAM;EACN,MAAM;EACN,MAAM;EACN,OAAO;EACP,aAAa;CAChB;AAED,QAAO,QAAQ,SAAS;AAC3B;;;;ACdM,SAAS,wBAAwBC,OAAmC;CACvE,MAAMC,aAA2C,CAAE;CACnD,MAAMC,WAAqB,CAAE;AAE7B,MAAK,MAAM,CAAC,MAAM,KAAK,IAAI,OAAO,QAAQ,MAAM,OAAO,EAAE;AACrD,aAAW,QAAQ;GACf,MAAM,iBAAiB,KAAK,KAAK;GACjC,aAAa,KAAK;EACrB;AAED,OAAK,KAAK,YAAY,KAAK,YAAY,cAAc,KAAK,WACtD,UAAS,KAAK,KAAK;CAE1B;AAED,QAAO;EACH,MAAM;EACN;EACA,UAAU,SAAS,SAAS,IAAI,WAAW;CAC9C;AACJ;;;;ACvBD,SAAS,aAAaC,QAA0B;AAC5C,KAAI,MAAM,QAAQ,OAAO,CACrB,QAAO,OAAO,IAAI,CAAC,UAAU,aAAa,MAAM,CAAC;AAGrD,KAAI,iBAAiB,WAAW,UAAU;EACtC,MAAM,QAAQ;AACd,SAAO,OAAO,YACV,OAAO,QAAQ,MAAM,CAChB,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,UAAU,CACpC,IAAI,CAAC,CAAC,KAAK,MAAM,KAAK,CAAC,KAAK,aAAa,MAAM,AAAC,EAAC,CACzD;CACJ;AAED,QAAO;AACV;AAKM,SAAS,sBAAsBC,QAAiC;AACnE,QAAO,aAAa,EAAE,aAAa,OAAO,CAAC;AAC9C"}
|