@danceroutine/tango-openapi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/domain/index.d.ts +4 -0
- package/dist/domain/index.js +4 -0
- package/dist/domain/types.d.ts +93 -0
- package/dist/domain/types.js +1 -0
- package/dist/domain-Cufz6y1q.js +7 -0
- package/dist/domain-Cufz6y1q.js.map +1 -0
- package/dist/generators/index.d.ts +6 -0
- package/dist/generators/index.js +4 -0
- package/dist/generators/spec/generateOpenAPISpec.d.ts +2 -0
- package/dist/generators/spec/generateOpenAPISpec.js +133 -0
- package/dist/generators/spec/index.d.ts +4 -0
- package/dist/generators-Bvwyyja4.js +131 -0
- package/dist/generators-Bvwyyja4.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/mappers/index.d.ts +6 -0
- package/dist/mappers/index.js +4 -0
- package/dist/mappers/schema/generateSchemaFromModel.d.ts +2 -0
- package/dist/mappers/schema/generateSchemaFromModel.js +19 -0
- package/dist/mappers/schema/index.d.ts +5 -0
- package/dist/mappers/schema/mapTypeToOpenAPI.d.ts +1 -0
- package/dist/mappers-CIfnOwl2.js +13 -0
- package/dist/mappers-CIfnOwl2.js.map +1 -0
- package/dist/schema-DVxdID48.js +60 -0
- package/dist/schema-DVxdID48.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain boundary barrel: centralizes this subdomain's public contract.
|
|
3
|
+
*/
|
|
4
|
+
export type { ComponentsObject, MediaTypeObject, OperationObject, OpenAPIModel, OpenAPIModelFieldMeta, OpenAPIOptions, OpenAPISpec, OpenAPIGeneratorConfig, ParameterObject, PathItemObject, ReferenceObject, RequestBodyObject, ResponseObject, SchemaObject, ViewSetLike, } from './types';
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
export type OpenAPIModelFieldMeta = {
|
|
3
|
+
type: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
nullable?: boolean;
|
|
6
|
+
default?: unknown;
|
|
7
|
+
primaryKey?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type OpenAPIModel = {
|
|
10
|
+
name: string;
|
|
11
|
+
fields: Record<string, OpenAPIModelFieldMeta>;
|
|
12
|
+
};
|
|
13
|
+
export type ViewSetLike = {
|
|
14
|
+
repository?: {
|
|
15
|
+
model?: OpenAPIModel;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export type ReferenceObject = {
|
|
19
|
+
$ref: string;
|
|
20
|
+
};
|
|
21
|
+
export type SchemaObject = {
|
|
22
|
+
type?: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
nullable?: boolean;
|
|
25
|
+
default?: unknown;
|
|
26
|
+
properties?: Record<string, SchemaObject>;
|
|
27
|
+
required?: string[];
|
|
28
|
+
items?: SchemaObject | ReferenceObject;
|
|
29
|
+
};
|
|
30
|
+
export type MediaTypeObject = {
|
|
31
|
+
schema: SchemaObject | ReferenceObject;
|
|
32
|
+
};
|
|
33
|
+
export type ResponseObject = {
|
|
34
|
+
description: string;
|
|
35
|
+
content?: Record<string, MediaTypeObject>;
|
|
36
|
+
};
|
|
37
|
+
export type ParameterObject = {
|
|
38
|
+
name: string;
|
|
39
|
+
in: 'query' | 'path' | 'header' | 'cookie';
|
|
40
|
+
required?: boolean;
|
|
41
|
+
schema: SchemaObject;
|
|
42
|
+
};
|
|
43
|
+
export type RequestBodyObject = {
|
|
44
|
+
required?: boolean;
|
|
45
|
+
content: Record<string, MediaTypeObject>;
|
|
46
|
+
};
|
|
47
|
+
export type OperationObject = {
|
|
48
|
+
summary?: string;
|
|
49
|
+
tags?: string[];
|
|
50
|
+
parameters?: ParameterObject[];
|
|
51
|
+
requestBody?: RequestBodyObject;
|
|
52
|
+
responses: Record<string, ResponseObject>;
|
|
53
|
+
};
|
|
54
|
+
export type PathItemObject = {
|
|
55
|
+
get?: OperationObject;
|
|
56
|
+
post?: OperationObject;
|
|
57
|
+
patch?: OperationObject;
|
|
58
|
+
delete?: OperationObject;
|
|
59
|
+
};
|
|
60
|
+
export type ComponentsObject = {
|
|
61
|
+
schemas?: Record<string, SchemaObject>;
|
|
62
|
+
securitySchemes?: Record<string, Record<string, unknown>>;
|
|
63
|
+
};
|
|
64
|
+
export interface OpenAPISpec {
|
|
65
|
+
openapi: string;
|
|
66
|
+
info: {
|
|
67
|
+
title: string;
|
|
68
|
+
version: string;
|
|
69
|
+
description?: string;
|
|
70
|
+
};
|
|
71
|
+
servers?: Array<{
|
|
72
|
+
url: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
}>;
|
|
75
|
+
paths: Record<string, PathItemObject>;
|
|
76
|
+
components?: ComponentsObject;
|
|
77
|
+
}
|
|
78
|
+
export interface OpenAPIOptions {
|
|
79
|
+
title: string;
|
|
80
|
+
version: string;
|
|
81
|
+
description?: string;
|
|
82
|
+
servers?: Array<{
|
|
83
|
+
url: string;
|
|
84
|
+
description?: string;
|
|
85
|
+
}>;
|
|
86
|
+
}
|
|
87
|
+
export type OpenAPIGeneratorConfig = OpenAPIOptions & {
|
|
88
|
+
resources?: Array<{
|
|
89
|
+
path: string;
|
|
90
|
+
schema: z.ZodType;
|
|
91
|
+
}>;
|
|
92
|
+
viewsets?: Record<string, ViewSetLike>;
|
|
93
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-Cufz6y1q.js","names":[],"sources":["../src/domain/index.ts"],"sourcesContent":["/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport type {\n OpenAPIModel,\n OpenAPIModelFieldMeta,\n OpenAPIOptions,\n OpenAPISpec,\n OpenAPIGeneratorConfig,\n ViewSetLike,\n} from './types';\n"],"mappings":""}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { generateSchemaFromModel } from '../../mappers/schema';
|
|
2
|
+
export function generateOpenAPISpec(config) {
|
|
3
|
+
const paths = {};
|
|
4
|
+
const schemas = {};
|
|
5
|
+
if (config.viewsets) {
|
|
6
|
+
for (const [basePath, viewset] of Object.entries(config.viewsets)) {
|
|
7
|
+
const model = viewset.repository?.model;
|
|
8
|
+
if (!model)
|
|
9
|
+
continue;
|
|
10
|
+
const modelName = model.name;
|
|
11
|
+
const collectionPath = `/${basePath}`;
|
|
12
|
+
const itemPath = `/${basePath}/{id}`;
|
|
13
|
+
schemas[modelName] = generateSchemaFromModel(model);
|
|
14
|
+
paths[collectionPath] = {
|
|
15
|
+
get: {
|
|
16
|
+
summary: `List ${modelName}s`,
|
|
17
|
+
tags: [modelName],
|
|
18
|
+
parameters: [
|
|
19
|
+
{ name: 'limit', in: 'query', schema: { type: 'integer' } },
|
|
20
|
+
{ name: 'offset', in: 'query', schema: { type: 'integer' } },
|
|
21
|
+
],
|
|
22
|
+
responses: {
|
|
23
|
+
'200': {
|
|
24
|
+
description: 'Successful response',
|
|
25
|
+
content: {
|
|
26
|
+
'application/json': {
|
|
27
|
+
schema: {
|
|
28
|
+
type: 'array',
|
|
29
|
+
items: { $ref: `#/components/schemas/${modelName}` },
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
post: {
|
|
37
|
+
summary: `Create ${modelName}`,
|
|
38
|
+
tags: [modelName],
|
|
39
|
+
requestBody: {
|
|
40
|
+
required: true,
|
|
41
|
+
content: {
|
|
42
|
+
'application/json': {
|
|
43
|
+
schema: { $ref: `#/components/schemas/${modelName}` },
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
responses: {
|
|
48
|
+
'201': {
|
|
49
|
+
description: 'Created',
|
|
50
|
+
content: {
|
|
51
|
+
'application/json': {
|
|
52
|
+
schema: { $ref: `#/components/schemas/${modelName}` },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
paths[itemPath] = {
|
|
60
|
+
get: {
|
|
61
|
+
summary: `Get ${modelName}`,
|
|
62
|
+
tags: [modelName],
|
|
63
|
+
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
|
64
|
+
responses: {
|
|
65
|
+
'200': {
|
|
66
|
+
description: 'Successful response',
|
|
67
|
+
content: {
|
|
68
|
+
'application/json': {
|
|
69
|
+
schema: { $ref: `#/components/schemas/${modelName}` },
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
'404': {
|
|
74
|
+
description: 'Not found',
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
patch: {
|
|
79
|
+
summary: `Update ${modelName}`,
|
|
80
|
+
tags: [modelName],
|
|
81
|
+
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
|
82
|
+
requestBody: {
|
|
83
|
+
required: true,
|
|
84
|
+
content: {
|
|
85
|
+
'application/json': {
|
|
86
|
+
schema: { $ref: `#/components/schemas/${modelName}` },
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
responses: {
|
|
91
|
+
'200': {
|
|
92
|
+
description: 'Updated',
|
|
93
|
+
content: {
|
|
94
|
+
'application/json': {
|
|
95
|
+
schema: { $ref: `#/components/schemas/${modelName}` },
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
'404': {
|
|
100
|
+
description: 'Not found',
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
delete: {
|
|
105
|
+
summary: `Delete ${modelName}`,
|
|
106
|
+
tags: [modelName],
|
|
107
|
+
parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],
|
|
108
|
+
responses: {
|
|
109
|
+
'204': {
|
|
110
|
+
description: 'Deleted',
|
|
111
|
+
},
|
|
112
|
+
'404': {
|
|
113
|
+
description: 'Not found',
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
openapi: '3.1.0',
|
|
122
|
+
info: {
|
|
123
|
+
title: config.title,
|
|
124
|
+
version: config.version,
|
|
125
|
+
description: config.description,
|
|
126
|
+
},
|
|
127
|
+
servers: config.servers,
|
|
128
|
+
paths,
|
|
129
|
+
components: {
|
|
130
|
+
schemas,
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { __export, generateSchemaFromModel } from "./schema-DVxdID48.js";
|
|
2
|
+
|
|
3
|
+
//#region src/generators/spec/generateOpenAPISpec.ts
|
|
4
|
+
function generateOpenAPISpec(config) {
|
|
5
|
+
const paths = {};
|
|
6
|
+
const schemas = {};
|
|
7
|
+
if (config.viewsets) for (const [basePath, viewset] of Object.entries(config.viewsets)) {
|
|
8
|
+
const model = viewset.repository?.model;
|
|
9
|
+
if (!model) continue;
|
|
10
|
+
const modelName = model.name;
|
|
11
|
+
const collectionPath = `/${basePath}`;
|
|
12
|
+
const itemPath = `/${basePath}/{id}`;
|
|
13
|
+
schemas[modelName] = generateSchemaFromModel(model);
|
|
14
|
+
paths[collectionPath] = {
|
|
15
|
+
get: {
|
|
16
|
+
summary: `List ${modelName}s`,
|
|
17
|
+
tags: [modelName],
|
|
18
|
+
parameters: [{
|
|
19
|
+
name: "limit",
|
|
20
|
+
in: "query",
|
|
21
|
+
schema: { type: "integer" }
|
|
22
|
+
}, {
|
|
23
|
+
name: "offset",
|
|
24
|
+
in: "query",
|
|
25
|
+
schema: { type: "integer" }
|
|
26
|
+
}],
|
|
27
|
+
responses: { "200": {
|
|
28
|
+
description: "Successful response",
|
|
29
|
+
content: { "application/json": { schema: {
|
|
30
|
+
type: "array",
|
|
31
|
+
items: { $ref: `#/components/schemas/${modelName}` }
|
|
32
|
+
} } }
|
|
33
|
+
} }
|
|
34
|
+
},
|
|
35
|
+
post: {
|
|
36
|
+
summary: `Create ${modelName}`,
|
|
37
|
+
tags: [modelName],
|
|
38
|
+
requestBody: {
|
|
39
|
+
required: true,
|
|
40
|
+
content: { "application/json": { schema: { $ref: `#/components/schemas/${modelName}` } } }
|
|
41
|
+
},
|
|
42
|
+
responses: { "201": {
|
|
43
|
+
description: "Created",
|
|
44
|
+
content: { "application/json": { schema: { $ref: `#/components/schemas/${modelName}` } } }
|
|
45
|
+
} }
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
paths[itemPath] = {
|
|
49
|
+
get: {
|
|
50
|
+
summary: `Get ${modelName}`,
|
|
51
|
+
tags: [modelName],
|
|
52
|
+
parameters: [{
|
|
53
|
+
name: "id",
|
|
54
|
+
in: "path",
|
|
55
|
+
required: true,
|
|
56
|
+
schema: { type: "string" }
|
|
57
|
+
}],
|
|
58
|
+
responses: {
|
|
59
|
+
"200": {
|
|
60
|
+
description: "Successful response",
|
|
61
|
+
content: { "application/json": { schema: { $ref: `#/components/schemas/${modelName}` } } }
|
|
62
|
+
},
|
|
63
|
+
"404": { description: "Not found" }
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
patch: {
|
|
67
|
+
summary: `Update ${modelName}`,
|
|
68
|
+
tags: [modelName],
|
|
69
|
+
parameters: [{
|
|
70
|
+
name: "id",
|
|
71
|
+
in: "path",
|
|
72
|
+
required: true,
|
|
73
|
+
schema: { type: "string" }
|
|
74
|
+
}],
|
|
75
|
+
requestBody: {
|
|
76
|
+
required: true,
|
|
77
|
+
content: { "application/json": { schema: { $ref: `#/components/schemas/${modelName}` } } }
|
|
78
|
+
},
|
|
79
|
+
responses: {
|
|
80
|
+
"200": {
|
|
81
|
+
description: "Updated",
|
|
82
|
+
content: { "application/json": { schema: { $ref: `#/components/schemas/${modelName}` } } }
|
|
83
|
+
},
|
|
84
|
+
"404": { description: "Not found" }
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
delete: {
|
|
88
|
+
summary: `Delete ${modelName}`,
|
|
89
|
+
tags: [modelName],
|
|
90
|
+
parameters: [{
|
|
91
|
+
name: "id",
|
|
92
|
+
in: "path",
|
|
93
|
+
required: true,
|
|
94
|
+
schema: { type: "string" }
|
|
95
|
+
}],
|
|
96
|
+
responses: {
|
|
97
|
+
"204": { description: "Deleted" },
|
|
98
|
+
"404": { description: "Not found" }
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
openapi: "3.1.0",
|
|
105
|
+
info: {
|
|
106
|
+
title: config.title,
|
|
107
|
+
version: config.version,
|
|
108
|
+
description: config.description
|
|
109
|
+
},
|
|
110
|
+
servers: config.servers,
|
|
111
|
+
paths,
|
|
112
|
+
components: { schemas }
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/generators/spec/index.ts
|
|
118
|
+
var spec_exports = {};
|
|
119
|
+
__export(spec_exports, { generateOpenAPISpec: () => generateOpenAPISpec });
|
|
120
|
+
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region src/generators/index.ts
|
|
123
|
+
var generators_exports = {};
|
|
124
|
+
__export(generators_exports, {
|
|
125
|
+
generateOpenAPISpec: () => generateOpenAPISpec,
|
|
126
|
+
spec: () => spec_exports
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
export { generateOpenAPISpec, generators_exports, spec_exports };
|
|
131
|
+
//# sourceMappingURL=generators-Bvwyyja4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generators-Bvwyyja4.js","names":["config: OpenAPIGeneratorConfig","paths: Record<string, any>","schemas: Record<string, any>"],"sources":["../src/generators/spec/generateOpenAPISpec.ts","../src/generators/spec/index.ts","../src/generators/index.ts"],"sourcesContent":["import { generateSchemaFromModel } from '../../mappers/schema';\nimport type { OpenAPIGeneratorConfig, OpenAPISpec } from '../../domain';\n\nexport function generateOpenAPISpec(config: OpenAPIGeneratorConfig): OpenAPISpec {\n const paths: Record<string, any> = {};\n const schemas: Record<string, any> = {};\n\n if (config.viewsets) {\n for (const [basePath, viewset] of Object.entries(config.viewsets)) {\n const model = (viewset as any).repository?.model;\n if (!model) continue;\n\n const modelName = model.name;\n const collectionPath = `/${basePath}`;\n const itemPath = `/${basePath}/{id}`;\n\n schemas[modelName] = generateSchemaFromModel(model);\n\n paths[collectionPath] = {\n get: {\n summary: `List ${modelName}s`,\n tags: [modelName],\n parameters: [\n { name: 'limit', in: 'query', schema: { type: 'integer' } },\n { name: 'offset', in: 'query', schema: { type: 'integer' } },\n ],\n responses: {\n '200': {\n description: 'Successful response',\n content: {\n 'application/json': {\n schema: {\n type: 'array',\n items: { $ref: `#/components/schemas/${modelName}` },\n },\n },\n },\n },\n },\n },\n post: {\n summary: `Create ${modelName}`,\n tags: [modelName],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${modelName}` },\n },\n },\n },\n responses: {\n '201': {\n description: 'Created',\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${modelName}` },\n },\n },\n },\n },\n },\n };\n\n paths[itemPath] = {\n get: {\n summary: `Get ${modelName}`,\n tags: [modelName],\n parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],\n responses: {\n '200': {\n description: 'Successful response',\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${modelName}` },\n },\n },\n },\n '404': {\n description: 'Not found',\n },\n },\n },\n patch: {\n summary: `Update ${modelName}`,\n tags: [modelName],\n parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],\n requestBody: {\n required: true,\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${modelName}` },\n },\n },\n },\n responses: {\n '200': {\n description: 'Updated',\n content: {\n 'application/json': {\n schema: { $ref: `#/components/schemas/${modelName}` },\n },\n },\n },\n '404': {\n description: 'Not found',\n },\n },\n },\n delete: {\n summary: `Delete ${modelName}`,\n tags: [modelName],\n parameters: [{ name: 'id', in: 'path', required: true, schema: { type: 'string' } }],\n responses: {\n '204': {\n description: 'Deleted',\n },\n '404': {\n description: 'Not found',\n },\n },\n },\n };\n }\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","/**\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":";;;AAGO,SAAS,oBAAoBA,QAA6C;CAC7E,MAAMC,QAA6B,CAAE;CACrC,MAAMC,UAA+B,CAAE;AAEvC,KAAI,OAAO,SACP,MAAK,MAAM,CAAC,UAAU,QAAQ,IAAI,OAAO,QAAQ,OAAO,SAAS,EAAE;EAC/D,MAAM,QAAS,QAAgB,YAAY;AAC3C,OAAK,MAAO;EAEZ,MAAM,YAAY,MAAM;EACxB,MAAM,kBAAkB,GAAG,SAAS;EACpC,MAAM,YAAY,GAAG,SAAS;AAE9B,UAAQ,aAAa,wBAAwB,MAAM;AAEnD,QAAM,kBAAkB;GACpB,KAAK;IACD,UAAU,OAAO,UAAU;IAC3B,MAAM,CAAC,SAAU;IACjB,YAAY,CACR;KAAE,MAAM;KAAS,IAAI;KAAS,QAAQ,EAAE,MAAM,UAAW;IAAE,GAC3D;KAAE,MAAM;KAAU,IAAI;KAAS,QAAQ,EAAE,MAAM,UAAW;IAC7D,CAAA;IACD,WAAW,EACP,OAAO;KACH,aAAa;KACb,SAAS,EACL,oBAAoB,EAChB,QAAQ;MACJ,MAAM;MACN,OAAO,EAAE,OAAO,uBAAuB,UAAU,EAAG;KACvD,EACJ,EACJ;IACJ,EACJ;GACJ;GACD,MAAM;IACF,UAAU,SAAS,UAAU;IAC7B,MAAM,CAAC,SAAU;IACjB,aAAa;KACT,UAAU;KACV,SAAS,EACL,oBAAoB,EAChB,QAAQ,EAAE,OAAO,uBAAuB,UAAU,EAAG,EACxD,EACJ;IACJ;IACD,WAAW,EACP,OAAO;KACH,aAAa;KACb,SAAS,EACL,oBAAoB,EAChB,QAAQ,EAAE,OAAO,uBAAuB,UAAU,EAAG,EACxD,EACJ;IACJ,EACJ;GACJ;EACJ;AAED,QAAM,YAAY;GACd,KAAK;IACD,UAAU,MAAM,UAAU;IAC1B,MAAM,CAAC,SAAU;IACjB,YAAY,CAAC;KAAE,MAAM;KAAM,IAAI;KAAQ,UAAU;KAAM,QAAQ,EAAE,MAAM,SAAU;IAAG,CAAA;IACpF,WAAW;KACP,OAAO;MACH,aAAa;MACb,SAAS,EACL,oBAAoB,EAChB,QAAQ,EAAE,OAAO,uBAAuB,UAAU,EAAG,EACxD,EACJ;KACJ;KACD,OAAO,EACH,aAAa,YAChB;IACJ;GACJ;GACD,OAAO;IACH,UAAU,SAAS,UAAU;IAC7B,MAAM,CAAC,SAAU;IACjB,YAAY,CAAC;KAAE,MAAM;KAAM,IAAI;KAAQ,UAAU;KAAM,QAAQ,EAAE,MAAM,SAAU;IAAG,CAAA;IACpF,aAAa;KACT,UAAU;KACV,SAAS,EACL,oBAAoB,EAChB,QAAQ,EAAE,OAAO,uBAAuB,UAAU,EAAG,EACxD,EACJ;IACJ;IACD,WAAW;KACP,OAAO;MACH,aAAa;MACb,SAAS,EACL,oBAAoB,EAChB,QAAQ,EAAE,OAAO,uBAAuB,UAAU,EAAG,EACxD,EACJ;KACJ;KACD,OAAO,EACH,aAAa,YAChB;IACJ;GACJ;GACD,QAAQ;IACJ,UAAU,SAAS,UAAU;IAC7B,MAAM,CAAC,SAAU;IACjB,YAAY,CAAC;KAAE,MAAM;KAAM,IAAI;KAAQ,UAAU;KAAM,QAAQ,EAAE,MAAM,SAAU;IAAG,CAAA;IACpF,WAAW;KACP,OAAO,EACH,aAAa,UAChB;KACD,OAAO,EACH,aAAa,YAChB;IACJ;GACJ;EACJ;CACJ;AAGL,QAAO;EACH,SAAS;EACT,MAAM;GACF,OAAO,OAAO;GACd,SAAS,OAAO;GAChB,aAAa,OAAO;EACvB;EACD,SAAS,OAAO;EAChB;EACA,YAAY,EACR,QACH;CACJ;AACJ"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bundled exports for Django-style domain drill-down imports, plus curated
|
|
3
|
+
* top-level symbols for TS-native ergonomic imports.
|
|
4
|
+
*/
|
|
5
|
+
export * as domain from './domain/index';
|
|
6
|
+
export * as generators from './generators/index';
|
|
7
|
+
export * as mappers from './mappers/index';
|
|
8
|
+
export { VERSION as version } from './version';
|
|
9
|
+
export type { OpenAPIGeneratorConfig, OpenAPIModel, OpenAPIModelFieldMeta, OpenAPIOptions, OpenAPISpec, ViewSetLike, } from './domain/index';
|
|
10
|
+
export { generateOpenAPISpec } from './generators/index';
|
|
11
|
+
export { generateSchemaFromModel, mapTypeToOpenAPI } from './mappers/index';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { generateSchemaFromModel, mapTypeToOpenAPI } from "./schema-DVxdID48.js";
|
|
2
|
+
import { domain_exports } from "./domain-Cufz6y1q.js";
|
|
3
|
+
import { generateOpenAPISpec, generators_exports } from "./generators-Bvwyyja4.js";
|
|
4
|
+
import { mappers_exports } from "./mappers-CIfnOwl2.js";
|
|
5
|
+
|
|
6
|
+
//#region src/version.ts
|
|
7
|
+
const VERSION = "0.1.0";
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
export { domain_exports as domain, generateOpenAPISpec, generateSchemaFromModel, generators_exports as generators, mapTypeToOpenAPI, mappers_exports as mappers, VERSION as version };
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/version.ts"],"sourcesContent":["export const VERSION = '0.1.0';\n"],"mappings":";;;;;;MAAa,UAAU"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain boundary barrel: exposes namespaced exports for Django-style drill-down
|
|
3
|
+
* imports and curated flat exports for TS-native ergonomics.
|
|
4
|
+
*/
|
|
5
|
+
export * as schema from './schema/index';
|
|
6
|
+
export { generateSchemaFromModel, mapTypeToOpenAPI } from './schema/index';
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { mapTypeToOpenAPI } from './mapTypeToOpenAPI';
|
|
2
|
+
export function generateSchemaFromModel(model) {
|
|
3
|
+
const properties = {};
|
|
4
|
+
const required = [];
|
|
5
|
+
for (const [name, meta] of Object.entries(model.fields)) {
|
|
6
|
+
properties[name] = {
|
|
7
|
+
type: mapTypeToOpenAPI(meta.type),
|
|
8
|
+
description: meta.description,
|
|
9
|
+
};
|
|
10
|
+
if (!meta.nullable && meta.default === undefined && !meta.primaryKey) {
|
|
11
|
+
required.push(name);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties,
|
|
17
|
+
required: required.length > 0 ? required : undefined,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function mapTypeToOpenAPI(type: string): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { __export, generateSchemaFromModel, mapTypeToOpenAPI, schema_exports } from "./schema-DVxdID48.js";
|
|
2
|
+
|
|
3
|
+
//#region src/mappers/index.ts
|
|
4
|
+
var mappers_exports = {};
|
|
5
|
+
__export(mappers_exports, {
|
|
6
|
+
generateSchemaFromModel: () => generateSchemaFromModel,
|
|
7
|
+
mapTypeToOpenAPI: () => mapTypeToOpenAPI,
|
|
8
|
+
schema: () => schema_exports
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { mappers_exports };
|
|
13
|
+
//# sourceMappingURL=mappers-CIfnOwl2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mappers-CIfnOwl2.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, mapTypeToOpenAPI } from './schema/index';\n"],"mappings":""}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
|
|
2
|
+
//#region rolldown:runtime
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __export = (target, all) => {
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/mappers/schema/mapTypeToOpenAPI.ts
|
|
13
|
+
function mapTypeToOpenAPI(type) {
|
|
14
|
+
const typeMap = {
|
|
15
|
+
string: "string",
|
|
16
|
+
number: "number",
|
|
17
|
+
boolean: "boolean",
|
|
18
|
+
date: "string",
|
|
19
|
+
serial: "integer",
|
|
20
|
+
int: "integer",
|
|
21
|
+
bigint: "integer",
|
|
22
|
+
text: "string",
|
|
23
|
+
bool: "boolean",
|
|
24
|
+
uuid: "string",
|
|
25
|
+
jsonb: "object",
|
|
26
|
+
timestamptz: "string"
|
|
27
|
+
};
|
|
28
|
+
return typeMap[type] || "string";
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/mappers/schema/generateSchemaFromModel.ts
|
|
33
|
+
function generateSchemaFromModel(model) {
|
|
34
|
+
const properties = {};
|
|
35
|
+
const required = [];
|
|
36
|
+
for (const [name, meta] of Object.entries(model.fields)) {
|
|
37
|
+
properties[name] = {
|
|
38
|
+
type: mapTypeToOpenAPI(meta.type),
|
|
39
|
+
description: meta.description
|
|
40
|
+
};
|
|
41
|
+
if (!meta.nullable && meta.default === undefined && !meta.primaryKey) required.push(name);
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties,
|
|
46
|
+
required: required.length > 0 ? required : undefined
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
//#endregion
|
|
51
|
+
//#region src/mappers/schema/index.ts
|
|
52
|
+
var schema_exports = {};
|
|
53
|
+
__export(schema_exports, {
|
|
54
|
+
generateSchemaFromModel: () => generateSchemaFromModel,
|
|
55
|
+
mapTypeToOpenAPI: () => mapTypeToOpenAPI
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
//#endregion
|
|
59
|
+
export { __export, generateSchemaFromModel, mapTypeToOpenAPI, schema_exports };
|
|
60
|
+
//# sourceMappingURL=schema-DVxdID48.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-DVxdID48.js","names":["type: string","typeMap: Record<string, string>","model: OpenAPIModel","properties: Record<string, any>","required: string[]"],"sources":["../src/mappers/schema/mapTypeToOpenAPI.ts","../src/mappers/schema/generateSchemaFromModel.ts","../src/mappers/schema/index.ts"],"sourcesContent":["export 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 } from '../../domain';\nimport { mapTypeToOpenAPI } from './mapTypeToOpenAPI';\n\nexport function generateSchemaFromModel(model: OpenAPIModel): any {\n const properties: Record<string, any> = {};\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","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { generateSchemaFromModel } from './generateSchemaFromModel';\nexport { mapTypeToOpenAPI } from './mapTypeToOpenAPI';\n"],"mappings":";;;;;;;;;;;;AAAO,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,OAA0B;CAC9D,MAAMC,aAAkC,CAAE;CAC1C,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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const VERSION = "0.1.0";
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@danceroutine/tango-openapi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "OpenAPI generation for Tango resources",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./domain": {
|
|
14
|
+
"types": "./dist/domain/index.d.ts",
|
|
15
|
+
"import": "./dist/domain/index.js"
|
|
16
|
+
},
|
|
17
|
+
"./generators": {
|
|
18
|
+
"types": "./dist/generators/index.d.ts",
|
|
19
|
+
"import": "./dist/generators/index.js"
|
|
20
|
+
},
|
|
21
|
+
"./mappers": {
|
|
22
|
+
"types": "./dist/mappers/index.d.ts",
|
|
23
|
+
"import": "./dist/mappers/index.js"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist"
|
|
28
|
+
],
|
|
29
|
+
"scripts": {
|
|
30
|
+
"build": "tsdown",
|
|
31
|
+
"test": "vitest run --coverage",
|
|
32
|
+
"test:watch": "vitest",
|
|
33
|
+
"typecheck": "tsc --noEmit"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"tango",
|
|
37
|
+
"openapi",
|
|
38
|
+
"swagger",
|
|
39
|
+
"api-docs"
|
|
40
|
+
],
|
|
41
|
+
"author": "Pedro Del Moral Lopez",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "https://github.com/danceroutine/tango.git",
|
|
46
|
+
"directory": "packages/openapi"
|
|
47
|
+
},
|
|
48
|
+
"dependencies": {
|
|
49
|
+
"@danceroutine/tango-resources": "workspace:*",
|
|
50
|
+
"zod": "^4.0.0"
|
|
51
|
+
},
|
|
52
|
+
"devDependencies": {
|
|
53
|
+
"@types/node": "^22.9.0",
|
|
54
|
+
"tsdown": "^0.4.0",
|
|
55
|
+
"typescript": "^5.6.3",
|
|
56
|
+
"vitest": "^4.0.6"
|
|
57
|
+
}
|
|
58
|
+
}
|