@jsango/openapi 1.0.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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -0
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +2 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/public/admin-adapter.d.ts +26 -0
  8. package/dist/public/admin-adapter.d.ts.map +1 -0
  9. package/dist/public/admin-adapter.js +120 -0
  10. package/dist/public/admin-adapter.js.map +1 -0
  11. package/dist/public/endpoint.d.ts +13 -0
  12. package/dist/public/endpoint.d.ts.map +1 -0
  13. package/dist/public/endpoint.js +38 -0
  14. package/dist/public/endpoint.js.map +1 -0
  15. package/dist/public/errors.d.ts +15 -0
  16. package/dist/public/errors.d.ts.map +1 -0
  17. package/dist/public/errors.js +32 -0
  18. package/dist/public/errors.js.map +1 -0
  19. package/dist/public/formatter.d.ts +13 -0
  20. package/dist/public/formatter.d.ts.map +1 -0
  21. package/dist/public/formatter.js +77 -0
  22. package/dist/public/formatter.js.map +1 -0
  23. package/dist/public/generator.d.ts +37 -0
  24. package/dist/public/generator.d.ts.map +1 -0
  25. package/dist/public/generator.js +217 -0
  26. package/dist/public/generator.js.map +1 -0
  27. package/dist/public/index.d.ts +12 -0
  28. package/dist/public/index.d.ts.map +1 -0
  29. package/dist/public/index.js +11 -0
  30. package/dist/public/index.js.map +1 -0
  31. package/dist/public/orm-adapter.d.ts +28 -0
  32. package/dist/public/orm-adapter.d.ts.map +1 -0
  33. package/dist/public/orm-adapter.js +97 -0
  34. package/dist/public/orm-adapter.js.map +1 -0
  35. package/dist/public/registry.d.ts +51 -0
  36. package/dist/public/registry.d.ts.map +1 -0
  37. package/dist/public/registry.js +106 -0
  38. package/dist/public/registry.js.map +1 -0
  39. package/dist/public/schema-builder.d.ts +29 -0
  40. package/dist/public/schema-builder.d.ts.map +1 -0
  41. package/dist/public/schema-builder.js +117 -0
  42. package/dist/public/schema-builder.js.map +1 -0
  43. package/dist/public/types.d.ts +198 -0
  44. package/dist/public/types.d.ts.map +1 -0
  45. package/dist/public/types.js +2 -0
  46. package/dist/public/types.js.map +1 -0
  47. package/dist/public/validation-adapter.d.ts +24 -0
  48. package/dist/public/validation-adapter.d.ts.map +1 -0
  49. package/dist/public/validation-adapter.js +57 -0
  50. package/dist/public/validation-adapter.js.map +1 -0
  51. package/dist/public/validator.d.ts +14 -0
  52. package/dist/public/validator.d.ts.map +1 -0
  53. package/dist/public/validator.js +107 -0
  54. package/dist/public/validator.js.map +1 -0
  55. package/package.json +37 -0
@@ -0,0 +1,217 @@
1
+ import { OpenApiRegistry } from './registry.js';
2
+ import { DuplicateOperationIdError } from './errors.js';
3
+ import { SchemaBuilder } from './schema-builder.js';
4
+ export class OpenApiGenerator {
5
+ info;
6
+ version;
7
+ servers;
8
+ registry;
9
+ includeAdmin;
10
+ defaultSecurity;
11
+ tags;
12
+ constructor(options) {
13
+ this.info = options.info;
14
+ this.version = options.openapi ?? '3.1.0';
15
+ this.servers = options.servers ?? [];
16
+ this.registry = options.registry ?? new OpenApiRegistry();
17
+ this.includeAdmin = options.includeAdmin ?? false;
18
+ this.defaultSecurity = options.defaultSecurity;
19
+ this.tags = options.tags ?? [];
20
+ // Ensure standard error response schemas are registered in components
21
+ if (!this.registry.getSchema('ErrorResponse')) {
22
+ this.registry.registerSchema('ErrorResponse', SchemaBuilder.errorResponse());
23
+ }
24
+ if (!this.registry.getSchema('ValidationErrorResponse')) {
25
+ this.registry.registerSchema('ValidationErrorResponse', SchemaBuilder.validationErrorResponse());
26
+ }
27
+ }
28
+ getRegistry() {
29
+ return this.registry;
30
+ }
31
+ /**
32
+ * Generates a deterministic OpenApiDocument from the router and registry.
33
+ */
34
+ generate(router) {
35
+ const paths = {};
36
+ const operationIds = new Map();
37
+ if (router) {
38
+ const routes = router.routes();
39
+ for (const route of routes) {
40
+ if (this.shouldSkipRoute(route)) {
41
+ continue;
42
+ }
43
+ const { path, pathParams } = this.normalizePathAndParams(route);
44
+ const method = route.method.toLowerCase();
45
+ if (method !== 'get' &&
46
+ method !== 'post' &&
47
+ method !== 'put' &&
48
+ method !== 'patch' &&
49
+ method !== 'delete' &&
50
+ method !== 'options' &&
51
+ method !== 'head') {
52
+ continue;
53
+ }
54
+ // Get metadata & overrides
55
+ const routeMeta = route.metadata['openapi'] ?? {};
56
+ const override = this.registry.getRouteOverride(route.method, route.path);
57
+ const mergedMeta = { ...routeMeta, ...(override ?? {}) };
58
+ // Determine operation ID
59
+ const operationId = mergedMeta.operationId ?? route.routeName ?? this.generateOperationId(route.method, path);
60
+ // Check for duplicates
61
+ const existingOp = operationIds.get(operationId);
62
+ if (existingOp && (existingOp.path !== path || existingOp.method !== route.method)) {
63
+ throw new DuplicateOperationIdError(operationId, existingOp.path, existingOp.method, path, route.method);
64
+ }
65
+ operationIds.set(operationId, { path, method: route.method });
66
+ // Merge path parameters with metadata parameters
67
+ const combinedParams = [
68
+ ...pathParams,
69
+ ...(mergedMeta.parameters ?? []).filter((p) => p.in !== 'path'),
70
+ ];
71
+ // Build operation
72
+ const operation = {
73
+ summary: mergedMeta.summary ?? `${route.method} ${path}`,
74
+ description: mergedMeta.description,
75
+ operationId,
76
+ tags: mergedMeta.tags,
77
+ deprecated: mergedMeta.deprecated,
78
+ parameters: combinedParams.length > 0 ? combinedParams : undefined,
79
+ requestBody: mergedMeta.requestBody,
80
+ responses: mergedMeta.responses ?? this.defaultResponses(route.method),
81
+ security: mergedMeta.security ?? this.defaultSecurity,
82
+ };
83
+ if (!paths[path]) {
84
+ paths[path] = {};
85
+ }
86
+ paths[path][method] = operation;
87
+ }
88
+ }
89
+ // Sort paths alphabetically for deterministic generation
90
+ const sortedPaths = {};
91
+ for (const key of Object.keys(paths).sort()) {
92
+ sortedPaths[key] = paths[key];
93
+ }
94
+ // Build components
95
+ const components = this.buildComponents();
96
+ // Collect tags
97
+ const allTags = [...this.tags, ...this.registry.getAllTags()];
98
+ const uniqueTags = Array.from(new Map(allTags.map((t) => [t.name, t])).values()).sort((a, b) => a.name.localeCompare(b.name));
99
+ const doc = {
100
+ openapi: this.version,
101
+ info: this.info,
102
+ ...(this.servers.length > 0 || this.registry.getAllServers().length > 0
103
+ ? { servers: [...this.servers, ...this.registry.getAllServers()] }
104
+ : {}),
105
+ paths: sortedPaths,
106
+ ...(components ? { components } : {}),
107
+ ...(this.defaultSecurity ? { security: this.defaultSecurity } : {}),
108
+ ...(uniqueTags.length > 0 ? { tags: uniqueTags } : {}),
109
+ };
110
+ return doc;
111
+ }
112
+ shouldSkipRoute(route) {
113
+ const meta = route.metadata['openapi'];
114
+ if (meta?.hidden || meta?.excludeFromOpenApi) {
115
+ return true;
116
+ }
117
+ // Exclude admin routes unless explicitly enabled
118
+ if (!this.includeAdmin &&
119
+ (route.path.startsWith('/admin') || route.metadata['admin'])) {
120
+ return true;
121
+ }
122
+ return false;
123
+ }
124
+ /**
125
+ * Normalizes router path syntax (`/users/:id<number>`) to OpenAPI syntax (`/users/{id}`)
126
+ * and derives path parameter definitions from constraints.
127
+ */
128
+ normalizePathAndParams(route) {
129
+ const pathParams = [];
130
+ const normalized = route.path.replace(/:([a-zA-Z0-9_]+)(?:<([^>]+)>)?\??/g, (_, name, constraint) => {
131
+ let schemaType = 'string';
132
+ let schemaFormat = undefined;
133
+ if (constraint) {
134
+ if (constraint === 'number' || constraint === 'int' || constraint === 'integer') {
135
+ schemaType = 'integer';
136
+ }
137
+ else if (constraint === 'uuid') {
138
+ schemaType = 'string';
139
+ schemaFormat = 'uuid';
140
+ }
141
+ else if (constraint === 'slug') {
142
+ schemaType = 'string';
143
+ }
144
+ }
145
+ pathParams.push({
146
+ name,
147
+ in: 'path',
148
+ required: true,
149
+ schema: {
150
+ type: schemaType,
151
+ ...(schemaFormat ? { format: schemaFormat } : {}),
152
+ },
153
+ });
154
+ return `{${name}}`;
155
+ });
156
+ return { path: normalized, pathParams };
157
+ }
158
+ generateOperationId(method, path) {
159
+ const cleaned = path.replace(/[{}]/g, '').split('/').filter(Boolean).join('_');
160
+ return `${method.toLowerCase()}_${cleaned || 'root'}`;
161
+ }
162
+ defaultResponses(method) {
163
+ const successStatus = method.toUpperCase() === 'POST' ? '201' : '200';
164
+ return {
165
+ [successStatus]: {
166
+ description: 'Successful response',
167
+ },
168
+ '400': {
169
+ description: 'Bad Request',
170
+ },
171
+ '500': {
172
+ description: 'Internal Server Error',
173
+ },
174
+ };
175
+ }
176
+ buildComponents() {
177
+ const schemas = {};
178
+ const securitySchemes = {};
179
+ const responses = {};
180
+ const parameters = {};
181
+ for (const [key, schema] of this.registry.getAllSchemas().entries()) {
182
+ schemas[key] = schema;
183
+ }
184
+ for (const [key, scheme] of this.registry.getAllSecuritySchemes().entries()) {
185
+ securitySchemes[key] = scheme;
186
+ }
187
+ for (const [key, response] of this.registry.getAllResponses().entries()) {
188
+ responses[key] = response;
189
+ }
190
+ for (const [key, param] of this.registry.getAllParameters().entries()) {
191
+ parameters[key] = param;
192
+ }
193
+ const hasAny = Object.keys(schemas).length > 0 ||
194
+ Object.keys(securitySchemes).length > 0 ||
195
+ Object.keys(responses).length > 0 ||
196
+ Object.keys(parameters).length > 0;
197
+ if (!hasAny)
198
+ return undefined;
199
+ return {
200
+ ...(Object.keys(schemas).length > 0
201
+ ? { schemas: schemas }
202
+ : {}),
203
+ ...(Object.keys(securitySchemes).length > 0
204
+ ? {
205
+ securitySchemes: securitySchemes,
206
+ }
207
+ : {}),
208
+ ...(Object.keys(responses).length > 0
209
+ ? { responses: responses }
210
+ : {}),
211
+ ...(Object.keys(parameters).length > 0
212
+ ? { parameters: parameters }
213
+ : {}),
214
+ };
215
+ }
216
+ }
217
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/public/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export type { OpenApiVersion, OpenApiInfo, OpenApiContact, OpenApiLicense, OpenApiServer, OpenApiServerVariable, OpenApiParameterIn, OpenApiParameter, OpenApiMediaType, OpenApiRequestBody, OpenApiHeader, OpenApiResponse, OpenApiResponses, OpenApiSecuritySchemeType, OpenApiSecurityScheme, OpenApiSecurityRequirement, OpenApiTag, OpenApiSchema, OpenApiOperation, OpenApiPathItem, OpenApiPaths, OpenApiComponents, OpenApiDocument, OpenApiRouteMetadata, } from './types.js';
2
+ export { OpenApiError, DuplicateOperationIdError, ConflictingSchemaError, InvalidOpenApiDocumentError, } from './errors.js';
3
+ export { OpenApiRegistry } from './registry.js';
4
+ export { SchemaBuilder } from './schema-builder.js';
5
+ export { ValidationAdapter, type ValidationSchemaDescriptor } from './validation-adapter.js';
6
+ export { OrmAdapter, type ModelFieldDescriptor, type ModelMetadataDescriptor, } from './orm-adapter.js';
7
+ export { AdminAdapter, type AdminFieldDescriptor, type AdminResourceDescriptor, } from './admin-adapter.js';
8
+ export { OpenApiGenerator, type OpenApiGeneratorOptions } from './generator.js';
9
+ export { OpenApiValidator } from './validator.js';
10
+ export { OpenApiFormatter } from './formatter.js';
11
+ export { createOpenApiHandler, type OpenApiEndpointOptions } from './endpoint.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/public/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,cAAc,EACd,WAAW,EACX,cAAc,EACd,cAAc,EACd,aAAa,EACb,qBAAqB,EACrB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,yBAAyB,EACzB,qBAAqB,EACrB,0BAA0B,EAC1B,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,oBAAoB,GACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,yBAAyB,EACzB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,KAAK,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EACL,UAAU,EACV,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,YAAY,EACZ,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,GAC7B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,KAAK,sBAAsB,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1,11 @@
1
+ export { OpenApiError, DuplicateOperationIdError, ConflictingSchemaError, InvalidOpenApiDocumentError, } from './errors.js';
2
+ export { OpenApiRegistry } from './registry.js';
3
+ export { SchemaBuilder } from './schema-builder.js';
4
+ export { ValidationAdapter } from './validation-adapter.js';
5
+ export { OrmAdapter, } from './orm-adapter.js';
6
+ export { AdminAdapter, } from './admin-adapter.js';
7
+ export { OpenApiGenerator } from './generator.js';
8
+ export { OpenApiValidator } from './validator.js';
9
+ export { OpenApiFormatter } from './formatter.js';
10
+ export { createOpenApiHandler } from './endpoint.js';
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/public/index.ts"],"names":[],"mappings":"AA2BA,OAAO,EACL,YAAY,EACZ,yBAAyB,EACzB,sBAAsB,EACtB,2BAA2B,GAC5B,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAmC,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EACL,UAAU,GAGX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,YAAY,GAGb,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,gBAAgB,EAAgC,MAAM,gBAAgB,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAA+B,MAAM,eAAe,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { OpenApiSchema } from './types.js';
2
+ export interface ModelFieldDescriptor {
3
+ readonly name: string;
4
+ readonly type: string;
5
+ readonly nullable?: boolean | undefined;
6
+ readonly primaryKey?: boolean | undefined;
7
+ readonly autoIncrement?: boolean | undefined;
8
+ readonly defaultValue?: unknown;
9
+ }
10
+ export interface ModelMetadataDescriptor {
11
+ readonly name: string;
12
+ readonly tableName?: string | undefined;
13
+ readonly primaryKey?: string | undefined;
14
+ readonly fields: readonly ModelFieldDescriptor[];
15
+ }
16
+ export declare class OrmAdapter {
17
+ /**
18
+ * Generates a component schema for an ORM model representation.
19
+ */
20
+ static toModelSchema(model: ModelMetadataDescriptor): OpenApiSchema;
21
+ /**
22
+ * Generates a component schema for creating a new record of the model.
23
+ * Auto-incrementing or readonly primary keys are excluded or made optional.
24
+ */
25
+ static toCreateInputSchema(model: ModelMetadataDescriptor): OpenApiSchema;
26
+ private static fieldToSchema;
27
+ }
28
+ //# sourceMappingURL=orm-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm-adapter.d.ts","sourceRoot":"","sources":["../../src/public/orm-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7C,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,oBAAoB,EAAE,CAAC;CAClD;AAED,qBAAa,UAAU;IACrB;;OAEG;WACW,aAAa,CAAC,KAAK,EAAE,uBAAuB,GAAG,aAAa;IAmB1E;;;OAGG;WACW,mBAAmB,CAAC,KAAK,EAAE,uBAAuB,GAAG,aAAa;IAsBhF,OAAO,CAAC,MAAM,CAAC,aAAa;CAuD7B"}
@@ -0,0 +1,97 @@
1
+ export class OrmAdapter {
2
+ /**
3
+ * Generates a component schema for an ORM model representation.
4
+ */
5
+ static toModelSchema(model) {
6
+ const properties = {};
7
+ const required = [];
8
+ for (const field of model.fields) {
9
+ properties[field.name] = OrmAdapter.fieldToSchema(field);
10
+ if (!field.nullable) {
11
+ required.push(field.name);
12
+ }
13
+ }
14
+ return {
15
+ type: 'object',
16
+ title: model.name,
17
+ properties,
18
+ ...(required.length > 0 ? { required } : {}),
19
+ };
20
+ }
21
+ /**
22
+ * Generates a component schema for creating a new record of the model.
23
+ * Auto-incrementing or readonly primary keys are excluded or made optional.
24
+ */
25
+ static toCreateInputSchema(model) {
26
+ const properties = {};
27
+ const required = [];
28
+ for (const field of model.fields) {
29
+ if (field.autoIncrement || (field.primaryKey && field.type === 'number')) {
30
+ continue;
31
+ }
32
+ properties[field.name] = OrmAdapter.fieldToSchema(field);
33
+ if (!field.nullable && field.defaultValue === undefined) {
34
+ required.push(field.name);
35
+ }
36
+ }
37
+ return {
38
+ type: 'object',
39
+ title: `Create${model.name}Input`,
40
+ properties,
41
+ ...(required.length > 0 ? { required } : {}),
42
+ };
43
+ }
44
+ static fieldToSchema(field) {
45
+ const schema = {};
46
+ switch (field.type.toLowerCase()) {
47
+ case 'int':
48
+ case 'integer':
49
+ case 'bigint':
50
+ case 'smallint':
51
+ schema['type'] = 'integer';
52
+ break;
53
+ case 'number':
54
+ case 'float':
55
+ case 'double':
56
+ case 'decimal':
57
+ schema['type'] = 'number';
58
+ break;
59
+ case 'boolean':
60
+ case 'bool':
61
+ schema['type'] = 'boolean';
62
+ break;
63
+ case 'date':
64
+ schema['type'] = 'string';
65
+ schema['format'] = 'date';
66
+ break;
67
+ case 'datetime':
68
+ case 'timestamp':
69
+ schema['type'] = 'string';
70
+ schema['format'] = 'date-time';
71
+ break;
72
+ case 'uuid':
73
+ schema['type'] = 'string';
74
+ schema['format'] = 'uuid';
75
+ break;
76
+ case 'email':
77
+ schema['type'] = 'string';
78
+ schema['format'] = 'email';
79
+ break;
80
+ case 'json':
81
+ schema['type'] = 'object';
82
+ schema['additionalProperties'] = true;
83
+ break;
84
+ default:
85
+ schema['type'] = 'string';
86
+ break;
87
+ }
88
+ if (field.nullable) {
89
+ schema['nullable'] = true;
90
+ }
91
+ if (field.defaultValue !== undefined) {
92
+ schema['default'] = field.defaultValue;
93
+ }
94
+ return schema;
95
+ }
96
+ }
97
+ //# sourceMappingURL=orm-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orm-adapter.js","sourceRoot":"","sources":["../../src/public/orm-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { OpenApiSchema, OpenApiSecurityScheme, OpenApiTag, OpenApiServer, OpenApiResponse, OpenApiParameter, OpenApiRouteMetadata } from './types.js';
2
+ export declare class OpenApiRegistry {
3
+ private readonly schemas;
4
+ private readonly securitySchemes;
5
+ private readonly tags;
6
+ private readonly servers;
7
+ private readonly responses;
8
+ private readonly parameters;
9
+ private readonly headers;
10
+ private readonly requestBodies;
11
+ private readonly routeOverrides;
12
+ /**
13
+ * Registers a reusable component schema.
14
+ * If a schema with the same name already exists, verifies structural compatibility.
15
+ */
16
+ registerSchema(name: string, schema: OpenApiSchema): this;
17
+ getSchema(name: string): OpenApiSchema | undefined;
18
+ getAllSchemas(): ReadonlyMap<string, OpenApiSchema>;
19
+ /**
20
+ * Registers a security scheme (e.g. bearer, apiKey, etc.).
21
+ */
22
+ registerSecurityScheme(name: string, scheme: OpenApiSecurityScheme): this;
23
+ getAllSecuritySchemes(): ReadonlyMap<string, OpenApiSecurityScheme>;
24
+ /**
25
+ * Registers an OpenAPI tag with optional description.
26
+ */
27
+ registerTag(tag: OpenApiTag): this;
28
+ getAllTags(): readonly OpenApiTag[];
29
+ /**
30
+ * Registers a server target.
31
+ */
32
+ registerServer(server: OpenApiServer): this;
33
+ getAllServers(): readonly OpenApiServer[];
34
+ /**
35
+ * Registers a reusable response component.
36
+ */
37
+ registerResponse(name: string, response: OpenApiResponse): this;
38
+ getAllResponses(): ReadonlyMap<string, OpenApiResponse>;
39
+ /**
40
+ * Registers a reusable parameter component.
41
+ */
42
+ registerParameter(name: string, parameter: OpenApiParameter): this;
43
+ getAllParameters(): ReadonlyMap<string, OpenApiParameter>;
44
+ /**
45
+ * Registers an explicit route metadata override for a specific method and path.
46
+ */
47
+ registerRouteOverride(method: string, path: string, metadata: OpenApiRouteMetadata): this;
48
+ getRouteOverride(method: string, path: string): OpenApiRouteMetadata | undefined;
49
+ clear(): void;
50
+ }
51
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/public/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,qBAAqB,EACrB,UAAU,EACV,aAAa,EACb,eAAe,EACf,gBAAgB,EAGhB,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAGpB,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4C;IAC5E,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAiC;IACtD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuB;IAC/C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuC;IAClE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoC;IAC5D,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyC;IACvE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2C;IAE1E;;;OAGG;IACI,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI;IAezD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAIlD,aAAa,IAAI,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC;IAI1D;;OAEG;IACI,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,qBAAqB,GAAG,IAAI;IAKzE,qBAAqB,IAAI,WAAW,CAAC,MAAM,EAAE,qBAAqB,CAAC;IAI1E;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAKlC,UAAU,IAAI,SAAS,UAAU,EAAE;IAI1C;;OAEG;IACI,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAK3C,aAAa,IAAI,SAAS,aAAa,EAAE;IAIhD;;OAEG;IACI,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;IAK/D,eAAe,IAAI,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC;IAI9D;;OAEG;IACI,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,gBAAgB,GAAG,IAAI;IAKlE,gBAAgB,IAAI,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAIhE;;OAEG;IACI,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,oBAAoB,GAAG,IAAI;IAMzF,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,GAAG,SAAS;IAIhF,KAAK,IAAI,IAAI;CAWrB"}
@@ -0,0 +1,106 @@
1
+ import { ConflictingSchemaError } from './errors.js';
2
+ export class OpenApiRegistry {
3
+ schemas = new Map();
4
+ securitySchemes = new Map();
5
+ tags = new Map();
6
+ servers = [];
7
+ responses = new Map();
8
+ parameters = new Map();
9
+ headers = new Map();
10
+ requestBodies = new Map();
11
+ routeOverrides = new Map();
12
+ /**
13
+ * Registers a reusable component schema.
14
+ * If a schema with the same name already exists, verifies structural compatibility.
15
+ */
16
+ registerSchema(name, schema) {
17
+ const existing = this.schemas.get(name);
18
+ if (existing) {
19
+ if (JSON.stringify(existing) !== JSON.stringify(schema)) {
20
+ throw new ConflictingSchemaError(name, 'A different schema is already registered with this name.');
21
+ }
22
+ return this;
23
+ }
24
+ this.schemas.set(name, Object.freeze({ ...schema }));
25
+ return this;
26
+ }
27
+ getSchema(name) {
28
+ return this.schemas.get(name);
29
+ }
30
+ getAllSchemas() {
31
+ return this.schemas;
32
+ }
33
+ /**
34
+ * Registers a security scheme (e.g. bearer, apiKey, etc.).
35
+ */
36
+ registerSecurityScheme(name, scheme) {
37
+ this.securitySchemes.set(name, Object.freeze({ ...scheme }));
38
+ return this;
39
+ }
40
+ getAllSecuritySchemes() {
41
+ return this.securitySchemes;
42
+ }
43
+ /**
44
+ * Registers an OpenAPI tag with optional description.
45
+ */
46
+ registerTag(tag) {
47
+ this.tags.set(tag.name, Object.freeze({ ...tag }));
48
+ return this;
49
+ }
50
+ getAllTags() {
51
+ return Array.from(this.tags.values());
52
+ }
53
+ /**
54
+ * Registers a server target.
55
+ */
56
+ registerServer(server) {
57
+ this.servers.push(Object.freeze({ ...server }));
58
+ return this;
59
+ }
60
+ getAllServers() {
61
+ return this.servers;
62
+ }
63
+ /**
64
+ * Registers a reusable response component.
65
+ */
66
+ registerResponse(name, response) {
67
+ this.responses.set(name, Object.freeze({ ...response }));
68
+ return this;
69
+ }
70
+ getAllResponses() {
71
+ return this.responses;
72
+ }
73
+ /**
74
+ * Registers a reusable parameter component.
75
+ */
76
+ registerParameter(name, parameter) {
77
+ this.parameters.set(name, Object.freeze({ ...parameter }));
78
+ return this;
79
+ }
80
+ getAllParameters() {
81
+ return this.parameters;
82
+ }
83
+ /**
84
+ * Registers an explicit route metadata override for a specific method and path.
85
+ */
86
+ registerRouteOverride(method, path, metadata) {
87
+ const key = `${method.toUpperCase()} ${path}`;
88
+ this.routeOverrides.set(key, Object.freeze({ ...metadata }));
89
+ return this;
90
+ }
91
+ getRouteOverride(method, path) {
92
+ return this.routeOverrides.get(`${method.toUpperCase()} ${path}`);
93
+ }
94
+ clear() {
95
+ this.schemas.clear();
96
+ this.securitySchemes.clear();
97
+ this.tags.clear();
98
+ this.servers.length = 0;
99
+ this.responses.clear();
100
+ this.parameters.clear();
101
+ this.headers.clear();
102
+ this.requestBodies.clear();
103
+ this.routeOverrides.clear();
104
+ }
105
+ }
106
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/public/registry.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,OAAO,eAAe;IACT,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC3C,eAAe,GAAG,IAAI,GAAG,EAAiC,CAAC;IAC3D,IAAI,GAAG,IAAI,GAAG,EAAsB,CAAC;IACrC,OAAO,GAAoB,EAAE,CAAC;IAC9B,SAAS,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC/C,UAAU,GAAG,IAAI,GAAG,EAA4B,CAAC;IACjD,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC3C,aAAa,GAAG,IAAI,GAAG,EAA8B,CAAC;IACtD,cAAc,GAAG,IAAI,GAAG,EAAgC,CAAC;IAE1E;;;OAGG;IACI,cAAc,CAAC,IAAY,EAAE,MAAqB;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxD,MAAM,IAAI,sBAAsB,CAC9B,IAAI,EACJ,0DAA0D,CAC3D,CAAC;YACJ,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;QACrD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,SAAS,CAAC,IAAY;QAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChC,CAAC;IAEM,aAAa;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACI,sBAAsB,CAAC,IAAY,EAAE,MAA6B;QACvE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,qBAAqB;QAC1B,OAAO,IAAI,CAAC,eAAe,CAAC;IAC9B,CAAC;IAED;;OAEG;IACI,WAAW,CAAC,GAAe;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,UAAU;QACf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,MAAqB;QACzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,aAAa;QAClB,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACI,gBAAgB,CAAC,IAAY,EAAE,QAAyB;QAC7D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,eAAe;QACpB,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;OAEG;IACI,iBAAiB,CAAC,IAAY,EAAE,SAA2B;QAChE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,SAAS,EAAE,CAAC,CAAC,CAAC;QAC3D,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,gBAAgB;QACrB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACI,qBAAqB,CAAC,MAAc,EAAE,IAAY,EAAE,QAA8B;QACvF,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC;QAC9C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,gBAAgB,CAAC,MAAc,EAAE,IAAY;QAClD,OAAO,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,eAAe,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAClB,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QACvB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;CACF"}
@@ -0,0 +1,29 @@
1
+ import type { OpenApiSchema } from './types.js';
2
+ export declare class SchemaBuilder {
3
+ static string(options?: Partial<OpenApiSchema>): OpenApiSchema;
4
+ static number(options?: Partial<OpenApiSchema>): OpenApiSchema;
5
+ static integer(options?: Partial<OpenApiSchema>): OpenApiSchema;
6
+ static boolean(options?: Partial<OpenApiSchema>): OpenApiSchema;
7
+ static uuid(options?: Partial<OpenApiSchema>): OpenApiSchema;
8
+ static dateTime(options?: Partial<OpenApiSchema>): OpenApiSchema;
9
+ static date(options?: Partial<OpenApiSchema>): OpenApiSchema;
10
+ static email(options?: Partial<OpenApiSchema>): OpenApiSchema;
11
+ static binary(options?: Partial<OpenApiSchema>): OpenApiSchema;
12
+ static array(items: OpenApiSchema, options?: Partial<OpenApiSchema>): OpenApiSchema;
13
+ static object(properties: Record<string, OpenApiSchema>, required?: readonly string[], options?: Partial<OpenApiSchema>): OpenApiSchema;
14
+ static enum(values: readonly unknown[], options?: Partial<OpenApiSchema>): OpenApiSchema;
15
+ static ref(schemaName: string): OpenApiSchema;
16
+ /**
17
+ * Reusable error response schema matching framework's JsangoError / HTTP error format.
18
+ */
19
+ static errorResponse(): OpenApiSchema;
20
+ /**
21
+ * Reusable validation error response schema matching @jsango/validation format.
22
+ */
23
+ static validationErrorResponse(): OpenApiSchema;
24
+ /**
25
+ * Standard paginated response schema.
26
+ */
27
+ static paginated(itemSchema: OpenApiSchema): OpenApiSchema;
28
+ }
29
+ //# sourceMappingURL=schema-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-builder.d.ts","sourceRoot":"","sources":["../../src/public/schema-builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,aAAa;WACV,MAAM,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAI3D,MAAM,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAI3D,OAAO,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAI5D,OAAO,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAI5D,IAAI,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAIzD,QAAQ,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAI7D,IAAI,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAIzD,KAAK,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAI1D,MAAM,CAAC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAI3D,KAAK,CAAC,KAAK,EAAE,aAAa,EAAE,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GAAG,aAAa;WAIhF,MAAM,CAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,EACzC,QAAQ,GAAE,SAAS,MAAM,EAAO,EAChC,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GACnC,aAAa;WASF,IAAI,CAChB,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,OAAO,GAAE,OAAO,CAAC,aAAa,CAAM,GACnC,aAAa;WAKF,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAIpD;;OAEG;WACW,aAAa,IAAI,aAAa;IAmB5C;;OAEG;WACW,uBAAuB,IAAI,aAAa;IA8BtD;;OAEG;WACW,SAAS,CAAC,UAAU,EAAE,aAAa,GAAG,aAAa;CAalE"}