@ddd-ts-kit/http 0.4.1 → 0.6.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/README.md +34 -2
- package/dist/controller/controller-routes.js +1 -0
- package/dist/controller/controller-routes.js.map +1 -1
- package/dist/controller/declared-route.d.ts +2 -0
- package/dist/controller/declared-route.d.ts.map +1 -1
- package/dist/controller/declared-route.js +3 -1
- package/dist/controller/declared-route.js.map +1 -1
- package/dist/docs/default-assets.d.ts +4 -0
- package/dist/docs/default-assets.d.ts.map +1 -0
- package/dist/docs/default-assets.js +7 -0
- package/dist/docs/default-assets.js.map +1 -0
- package/dist/docs/docs-page.d.ts.map +1 -1
- package/dist/docs/docs-page.js +1 -3
- package/dist/docs/docs-page.js.map +1 -1
- package/dist/docs/documents-page.d.ts +23 -0
- package/dist/docs/documents-page.d.ts.map +1 -0
- package/dist/docs/documents-page.js +16 -0
- package/dist/docs/documents-page.js.map +1 -0
- package/dist/docs/escape-html.d.ts +3 -0
- package/dist/docs/escape-html.d.ts.map +1 -0
- package/dist/docs/escape-html.js +5 -0
- package/dist/docs/escape-html.js.map +1 -0
- package/dist/docs/open-api-docs-routes.d.ts.map +1 -1
- package/dist/docs/open-api-docs-routes.js +2 -19
- package/dist/docs/open-api-docs-routes.js.map +1 -1
- package/dist/docs/open-api-documents-routes.d.ts +24 -0
- package/dist/docs/open-api-documents-routes.d.ts.map +1 -0
- package/dist/docs/open-api-documents-routes.js +57 -0
- package/dist/docs/open-api-documents-routes.js.map +1 -0
- package/dist/docs/text-route.d.ts +12 -0
- package/dist/docs/text-route.d.ts.map +1 -0
- package/dist/docs/text-route.js +15 -0
- package/dist/docs/text-route.js.map +1 -0
- package/dist/docs.d.ts +1 -0
- package/dist/docs.d.ts.map +1 -1
- package/dist/docs.js +1 -0
- package/dist/docs.js.map +1 -1
- package/dist/openapi/document-routes.d.ts +8 -0
- package/dist/openapi/document-routes.d.ts.map +1 -0
- package/dist/openapi/document-routes.js +2 -0
- package/dist/openapi/document-routes.js.map +1 -0
- package/dist/openapi/open-api-document-selection.d.ts +13 -0
- package/dist/openapi/open-api-document-selection.d.ts.map +1 -0
- package/dist/openapi/open-api-document-selection.js +2 -0
- package/dist/openapi/open-api-document-selection.js.map +1 -0
- package/dist/openapi/routes-by-document.d.ts +10 -0
- package/dist/openapi/routes-by-document.d.ts.map +1 -0
- package/dist/openapi/routes-by-document.js +31 -0
- package/dist/openapi/routes-by-document.js.map +1 -0
- package/dist/openapi.d.ts +3 -0
- package/dist/openapi.d.ts.map +1 -1
- package/dist/openapi.js +1 -0
- package/dist/openapi.js.map +1 -1
- package/dist/route/route.d.ts +5 -0
- package/dist/route/route.d.ts.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -429,14 +429,19 @@ const document = generateOpenApi({
|
|
|
429
429
|
errorMapper, // the one the server runs with
|
|
430
430
|
});
|
|
431
431
|
|
|
432
|
-
writeFileSync('openapi.json', stringifyOpenApi(document));
|
|
432
|
+
writeFileSync('openapi/openapi.json', stringifyOpenApi(document));
|
|
433
433
|
|
|
434
434
|
// In CI: regenerate and fail on a difference.
|
|
435
|
-
if (checkOpenApiDrift(document, readFileSync('openapi.json', 'utf8')).drift) {
|
|
435
|
+
if (checkOpenApiDrift(document, readFileSync('openapi/openapi.json', 'utf8')).drift) {
|
|
436
436
|
process.exit(1);
|
|
437
437
|
}
|
|
438
438
|
```
|
|
439
439
|
|
|
440
|
+
`stringifyOpenApi` writes two-space JSON. A project generated by the CLI commits the contract in
|
|
441
|
+
YAML instead, `openapi/openapi.yaml`, through `stringifyContract(document, 'yaml')` of
|
|
442
|
+
`ddd-ts-kit/dist/contracts.js` in its `scripts/openapi.ts` (`openapi.format` of its config
|
|
443
|
+
chooses), and compares the text it writes with the committed one.
|
|
444
|
+
|
|
440
445
|
What is generated: `{param}` paths, one parameter per property of the params, query and headers
|
|
441
446
|
schemas, the request body, the declared responses, the `security` of every operation (an empty
|
|
442
447
|
list for a public route), one `application/problem+json` response per
|
|
@@ -462,6 +467,33 @@ self-hosted files when it must work offline or under a strict content security p
|
|
|
462
467
|
project generated by the CLI mounts them in `src/platform/http/with-documentation.ts`, with
|
|
463
468
|
the UI chosen by `--docs-ui`, unless documentation is switched off by its configuration.
|
|
464
469
|
|
|
470
|
+
## A contract split into documents
|
|
471
|
+
|
|
472
|
+
```ts
|
|
473
|
+
import { openApiDocumentsRoutes } from '@ddd-ts-kit/http/docs';
|
|
474
|
+
import { generateOpenApi, routesByDocument } from '@ddd-ts-kit/http/openapi';
|
|
475
|
+
|
|
476
|
+
const documents = routesByDocument(routes, [
|
|
477
|
+
{ name: 'public', title: 'Booking API', groups: ['AppointmentRoutes'] },
|
|
478
|
+
{ name: 'back-office', title: 'Back office', tags: ['audit'], operations: ['openPractice'] },
|
|
479
|
+
]).map(({ name, title, routes: selected }) => ({
|
|
480
|
+
name,
|
|
481
|
+
document: generateOpenApi({ info: { title: title ?? 'API', version: '1.0.0' }, routes: selected }),
|
|
482
|
+
}));
|
|
483
|
+
|
|
484
|
+
const served = [...routes, ...openApiDocumentsRoutes(documents, { ui: 'swagger' })];
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
`routesByDocument` gives each document the routes of its route groups (a controller route
|
|
488
|
+
carries in `groups` the class names of its group and of every group above it), of its tags and
|
|
489
|
+
of its operations; a route may be in several documents, and a route in none is refused with a
|
|
490
|
+
`DeclarationError` naming it. Each document is generated on its own, so it holds every schema
|
|
491
|
+
it uses. `openApiDocumentsRoutes` serves each at `/openapi/<name>.json` with a page at
|
|
492
|
+
`/docs/<name>`, and on `/docs` Swagger UI with a selector between them (Scalar and Redoc show
|
|
493
|
+
one document at a time: `/docs` lists their pages); one document is served as
|
|
494
|
+
`openApiDocsRoutes` serves it. A generated project reads the documents from
|
|
495
|
+
`openapi.documents` of `ddd-ts-kit.config.json`, through `src/platform/http/openapi-documents.ts`.
|
|
496
|
+
|
|
465
497
|
## Limits
|
|
466
498
|
|
|
467
499
|
- A body the framework itself refuses (malformed JSON, payload too large) is answered by the
|
|
@@ -21,6 +21,7 @@ function routeOf(resolved, options) {
|
|
|
21
21
|
summary: spec.summary,
|
|
22
22
|
...(spec.description === undefined ? {} : { description: spec.description }),
|
|
23
23
|
...(declared.tags.length === 0 ? {} : { tags: declared.tags }),
|
|
24
|
+
...(declared.groups.length === 0 ? {} : { groups: declared.groups }),
|
|
24
25
|
...requestOf(spec),
|
|
25
26
|
responses: { [status]: { description: description ?? defaultDescription(body), ...bodyOf(body) } },
|
|
26
27
|
errors: [...new Set([...declared.errors, ...resolved.guards.flatMap((guard) => guard.documents?.errors ?? [])])],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller-routes.js","sourceRoot":"","sources":["../../src/controller/controller-routes.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"controller-routes.js","sourceRoot":"","sources":["../../src/controller/controller-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ export interface DeclaredRoute {
|
|
|
7
7
|
readonly tags: readonly string[];
|
|
8
8
|
readonly guards: readonly GuardReference[];
|
|
9
9
|
readonly errors: readonly string[];
|
|
10
|
+
/** The class names of its route group and of every group above it, nearest first. */
|
|
11
|
+
readonly groups: readonly string[];
|
|
10
12
|
}
|
|
11
13
|
/** Folds the groups of a controller into its declaration, and refuses one that cannot stand. */
|
|
12
14
|
export declare function declaredRoute(className: string, spec: ControllerSpec): DeclaredRoute;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declared-route.d.ts","sourceRoot":"","sources":["../../src/controller/declared-route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;
|
|
1
|
+
{"version":3,"file":"declared-route.d.ts","sourceRoot":"","sources":["../../src/controller/declared-route.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAK3D,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,qFAAqF;IACrF,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC;AAYD,gGAAgG;AAChG,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,aAAa,CAgBpF"}
|
|
@@ -2,7 +2,7 @@ import { DeclarationError } from '@ddd-ts-kit/kernel/declarations';
|
|
|
2
2
|
import { ROUTE_PATH_PATTERN } from '../route/route-path-pattern.js';
|
|
3
3
|
import { Public } from './guards/public.js';
|
|
4
4
|
import { presentationRegistry } from './presentation-registry.js';
|
|
5
|
-
const NOTHING = { prefix: '', tags: [], guards: [], errors: [] };
|
|
5
|
+
const NOTHING = { groups: [], prefix: '', tags: [], guards: [], errors: [] };
|
|
6
6
|
/** Folds the groups of a controller into its declaration, and refuses one that cannot stand. */
|
|
7
7
|
export function declaredRoute(className, spec) {
|
|
8
8
|
const inherited = spec.group === undefined ? NOTHING : inheritedFrom(className, spec.group);
|
|
@@ -16,6 +16,7 @@ export function declaredRoute(className, spec) {
|
|
|
16
16
|
tags: distinct([...inherited.tags, ...(spec.tags ?? [])]),
|
|
17
17
|
guards,
|
|
18
18
|
errors: distinct([...inherited.errors, ...(spec.errors ?? [])]),
|
|
19
|
+
groups: inherited.groups,
|
|
19
20
|
};
|
|
20
21
|
}
|
|
21
22
|
function inheritedFrom(className, group) {
|
|
@@ -25,6 +26,7 @@ function inheritedFrom(className, group) {
|
|
|
25
26
|
}
|
|
26
27
|
const above = options.parent === undefined ? NOTHING : inheritedFrom(className, options.parent);
|
|
27
28
|
return {
|
|
29
|
+
groups: [group.name, ...above.groups],
|
|
28
30
|
prefix: `${above.prefix}${options.prefix ?? ''}`,
|
|
29
31
|
tags: [...above.tags, ...(options.tags ?? [])],
|
|
30
32
|
guards: [...above.guards, ...(options.guards ?? [])],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declared-route.js","sourceRoot":"","sources":["../../src/controller/declared-route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAGpE,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"declared-route.js","sourceRoot":"","sources":["../../src/controller/declared-route.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-assets.d.ts","sourceRoot":"","sources":["../../src/docs/default-assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,2GAA2G;AAC3G,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAI3D,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Where each documentation page loads its UI from by default: a public CDN, pinned to a major version. */
|
|
2
|
+
export const DEFAULT_ASSETS = {
|
|
3
|
+
swagger: 'https://cdn.jsdelivr.net/npm/swagger-ui-dist@5',
|
|
4
|
+
scalar: 'https://cdn.jsdelivr.net/npm/@scalar/api-reference@1',
|
|
5
|
+
redoc: 'https://cdn.jsdelivr.net/npm/redoc@2/bundles',
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=default-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-assets.js","sourceRoot":"","sources":["../../src/docs/default-assets.ts"],"names":[],"mappings":"AAEA,2GAA2G;AAC3G,MAAM,CAAC,MAAM,cAAc,GAAqC;IAC9D,OAAO,EAAE,gDAAgD;IACzD,MAAM,EAAE,sDAAsD;IAC9D,KAAK,EAAE,8CAA8C;CACtD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs-page.d.ts","sourceRoot":"","sources":["../../src/docs/docs-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"docs-page.d.ts","sourceRoot":"","sources":["../../src/docs/docs-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C,UAAU,QAAQ;IAChB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,GAAG,MAAM,CAazE"}
|
package/dist/docs/docs-page.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { escapeHtml } from './escape-html.js';
|
|
1
2
|
/** The HTML page that loads the chosen UI and points it at the contract. */
|
|
2
3
|
export function docsPage({ ui, title, specUrl, assets }) {
|
|
3
4
|
const head = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${escapeHtml(title)}</title>`;
|
|
@@ -12,7 +13,4 @@ export function docsPage({ ui, title, specUrl, assets }) {
|
|
|
12
13
|
return `${head}</head><body><redoc spec-url="${spec}"></redoc><script src="${base}/redoc.standalone.js"></script></body></html>`;
|
|
13
14
|
}
|
|
14
15
|
}
|
|
15
|
-
function escapeHtml(value) {
|
|
16
|
-
return value.replace(/[&<>"']/g, (char) => `&#${char.charCodeAt(0)};`);
|
|
17
|
-
}
|
|
18
16
|
//# sourceMappingURL=docs-page.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs-page.js","sourceRoot":"","sources":["../../src/docs/docs-page.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"docs-page.js","sourceRoot":"","sources":["../../src/docs/docs-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAS9C,4EAA4E;AAC5E,MAAM,UAAU,QAAQ,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAY;IAC/D,MAAM,IAAI,GAAG,wIAAwI,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC;IACjL,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAEhC,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,SAAS;YACZ,OAAO,GAAG,IAAI,gCAAgC,IAAI,iEAAiE,IAAI,kEAAkE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,4CAA4C,CAAC;QAC/P,KAAK,QAAQ;YACX,OAAO,GAAG,IAAI,qDAAqD,IAAI,2BAA2B,IAAI,2BAA2B,CAAC;QACpI,KAAK,OAAO;YACV,OAAO,GAAG,IAAI,iCAAiC,IAAI,0BAA0B,IAAI,+CAA+C,CAAC;IACrI,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { DocsUi } from './docs-ui.js';
|
|
2
|
+
/** One document of a split contract, as the documentation page lists it. */
|
|
3
|
+
export interface ListedDocument {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly title: string;
|
|
6
|
+
/** Where its JSON is served. */
|
|
7
|
+
readonly url: string;
|
|
8
|
+
/** Where its own page is served. */
|
|
9
|
+
readonly page: string;
|
|
10
|
+
}
|
|
11
|
+
interface DocumentsPage {
|
|
12
|
+
readonly ui: DocsUi;
|
|
13
|
+
readonly title: string;
|
|
14
|
+
readonly documents: readonly ListedDocument[];
|
|
15
|
+
readonly assets: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The page of a contract split into documents: Swagger UI with its selector between them; for
|
|
19
|
+
* the other pages, which show one document at a time, the list of the page of each document.
|
|
20
|
+
*/
|
|
21
|
+
export declare function documentsPage({ ui, title, documents, assets }: DocumentsPage): string;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=documents-page.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documents-page.d.ts","sourceRoot":"","sources":["../../src/docs/documents-page.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oCAAoC;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,UAAU,aAAa;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,aAAa,GAAG,MAAM,CAerF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { escapeHtml } from './escape-html.js';
|
|
2
|
+
/**
|
|
3
|
+
* The page of a contract split into documents: Swagger UI with its selector between them; for
|
|
4
|
+
* the other pages, which show one document at a time, the list of the page of each document.
|
|
5
|
+
*/
|
|
6
|
+
export function documentsPage({ ui, title, documents, assets }) {
|
|
7
|
+
const head = `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${escapeHtml(title)}</title>`;
|
|
8
|
+
if (ui !== 'swagger') {
|
|
9
|
+
const links = documents.map((document) => `<li><a href="${escapeHtml(document.page)}">${escapeHtml(document.title)}</a></li>`);
|
|
10
|
+
return `${head}</head><body><h1>${escapeHtml(title)}</h1><ul>${links.join('')}</ul></body></html>`;
|
|
11
|
+
}
|
|
12
|
+
const base = escapeHtml(assets);
|
|
13
|
+
const urls = JSON.stringify(documents.map(({ url, title: name }) => ({ url, name }))).replaceAll('<', '\\u003c');
|
|
14
|
+
return `${head}<link rel="stylesheet" href="${base}/swagger-ui.css"></head><body><div id="ui"></div><script src="${base}/swagger-ui-bundle.js"></script><script src="${base}/swagger-ui-standalone-preset.js"></script><script>SwaggerUIBundle({ urls: ${urls}, dom_id: '#ui', presets: [SwaggerUIBundle.presets.apis, SwaggerUIStandalonePreset], layout: 'StandaloneLayout' });</script></body></html>`;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=documents-page.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"documents-page.js","sourceRoot":"","sources":["../../src/docs/documents-page.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAmB9C;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAiB;IAC3E,MAAM,IAAI,GAAG,wIAAwI,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC;IAEjL,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;QACrB,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CACzB,CAAC,QAAQ,EAAE,EAAE,CAAC,gBAAgB,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAClG,CAAC;QAEF,OAAO,GAAG,IAAI,oBAAoB,UAAU,CAAC,KAAK,CAAC,YAAY,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,qBAAqB,CAAC;IACrG,CAAC;IAED,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAEjH,OAAO,GAAG,IAAI,gCAAgC,IAAI,iEAAiE,IAAI,gDAAgD,IAAI,8EAA8E,IAAI,4IAA4I,CAAC;AAC5Y,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape-html.d.ts","sourceRoot":"","sources":["../../src/docs/escape-html.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"escape-html.js","sourceRoot":"","sources":["../../src/docs/escape-html.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-api-docs-routes.d.ts","sourceRoot":"","sources":["../../src/docs/open-api-docs-routes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"open-api-docs-routes.d.ts","sourceRoot":"","sources":["../../src/docs/open-api-docs-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAG3C,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,GAAE,iBAAsB,GAAG,SAAS,KAAK,EAAE,CA6B9G"}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
|
-
import { ok } from '@ddd-ts-kit/kernel';
|
|
2
|
-
import { customSchema } from '@ddd-ts-kit/validation';
|
|
3
1
|
import { stringifyOpenApi } from '../openapi/stringify-open-api.js';
|
|
4
|
-
import {
|
|
2
|
+
import { DEFAULT_ASSETS } from './default-assets.js';
|
|
5
3
|
import { docsPage } from './docs-page.js';
|
|
6
|
-
|
|
7
|
-
swagger: 'https://cdn.jsdelivr.net/npm/swagger-ui-dist@5',
|
|
8
|
-
scalar: 'https://cdn.jsdelivr.net/npm/@scalar/api-reference@1',
|
|
9
|
-
redoc: 'https://cdn.jsdelivr.net/npm/redoc@2/bundles',
|
|
10
|
-
};
|
|
11
|
-
const text = customSchema((input) => ok(String(input)), { type: 'string' });
|
|
4
|
+
import { textRoute } from './text-route.js';
|
|
12
5
|
/**
|
|
13
6
|
* Two routes serving the generated contract and an interactive page for it. Mount them next
|
|
14
7
|
* to the application routes; they are deliberately not part of the contract they display.
|
|
@@ -41,14 +34,4 @@ export function openApiDocsRoutes(document, options = {}) {
|
|
|
41
34
|
}),
|
|
42
35
|
];
|
|
43
36
|
}
|
|
44
|
-
function textRoute(route) {
|
|
45
|
-
return defineRoute({
|
|
46
|
-
method: 'GET',
|
|
47
|
-
path: route.path,
|
|
48
|
-
operationId: route.operationId,
|
|
49
|
-
summary: route.summary,
|
|
50
|
-
responses: { 200: { description: route.description, body: text } },
|
|
51
|
-
security: false,
|
|
52
|
-
}, async () => ({ status: 200, body: route.body, headers: { 'content-type': route.contentType } }));
|
|
53
|
-
}
|
|
54
37
|
//# sourceMappingURL=open-api-docs-routes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"open-api-docs-routes.js","sourceRoot":"","sources":["../../src/docs/open-api-docs-routes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"open-api-docs-routes.js","sourceRoot":"","sources":["../../src/docs/open-api-docs-routes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAgB5C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAyB,EAAE,OAAO,GAAsB,EAAE;IAC1F,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC;IACrD,MAAM,EAAE,GAAG,OAAO,CAAC,EAAE,IAAI,SAAS,CAAC;IAEnC,MAAM,IAAI,GAAG,QAAQ,CAAC;QACpB,EAAE;QACF,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK;QAC3C,OAAO,EAAE,QAAQ;QACjB,MAAM,EAAE,OAAO,CAAC,SAAS,IAAI,cAAc,CAAC,EAAE,CAAC;KAChD,CAAC,CAAC;IAEH,OAAO;QACL,SAAS,CAAC;YACR,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,oBAAoB;YACjC,OAAO,EAAE,kBAAkB;YAC3B,WAAW,EAAE,2BAA2B;YACxC,WAAW,EAAE,iCAAiC;YAC9C,IAAI,EAAE,gBAAgB,CAAC,QAAQ,CAAC;SACjC,CAAC;QACF,SAAS,CAAC;YACR,IAAI,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO;YAC/B,WAAW,EAAE,cAAc;YAC3B,OAAO,EAAE,+BAA+B;YACxC,WAAW,EAAE,eAAe;YAC5B,WAAW,EAAE,0BAA0B;YACvC,IAAI,EAAE,IAAI;SACX,CAAC;KACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { OpenApiDocument } from '../openapi/open-api-document.js';
|
|
2
|
+
import type { Route } from '../route/route.js';
|
|
3
|
+
import type { DocsUi } from './docs-ui.js';
|
|
4
|
+
/** One document of the contract and the name it is served under. */
|
|
5
|
+
export interface NamedOpenApiDocument {
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly document: OpenApiDocument;
|
|
8
|
+
}
|
|
9
|
+
export interface DocumentsRoutesOptions {
|
|
10
|
+
/** Where the JSON of each document is served, `<contractsPath>/<name>.json`. Default `/openapi`. */
|
|
11
|
+
readonly contractsPath?: string;
|
|
12
|
+
/** Where the page is served, and the page of each document under it. Default `/docs`. */
|
|
13
|
+
readonly uiPath?: string;
|
|
14
|
+
readonly ui?: DocsUi;
|
|
15
|
+
readonly assetsUrl?: string;
|
|
16
|
+
readonly title?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The routes of a contract split into documents: the JSON of each, a page per document and a
|
|
20
|
+
* page that offers them all (Swagger UI selects between them; the other pages link to each). One
|
|
21
|
+
* document is served as `openApiDocsRoutes` serves it, at `/openapi.json` and `/docs`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function openApiDocumentsRoutes(documents: readonly NamedOpenApiDocument[], options?: DocumentsRoutesOptions): readonly Route[];
|
|
24
|
+
//# sourceMappingURL=open-api-documents-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-api-documents-routes.d.ts","sourceRoot":"","sources":["../../src/docs/open-api-documents-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAI/C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAI3C,oEAAoE;AACpE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;CACpC;AAED,MAAM,WAAW,sBAAsB;IACrC,oGAAoG;IACpG,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,yFAAyF;IACzF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,SAAS,oBAAoB,EAAE,EAC1C,OAAO,GAAE,sBAA2B,GACnC,SAAS,KAAK,EAAE,CAgBlB"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { stringifyOpenApi } from '../openapi/stringify-open-api.js';
|
|
2
|
+
import { DEFAULT_ASSETS } from './default-assets.js';
|
|
3
|
+
import { docsPage } from './docs-page.js';
|
|
4
|
+
import { documentsPage } from './documents-page.js';
|
|
5
|
+
import { openApiDocsRoutes } from './open-api-docs-routes.js';
|
|
6
|
+
import { textRoute } from './text-route.js';
|
|
7
|
+
/**
|
|
8
|
+
* The routes of a contract split into documents: the JSON of each, a page per document and a
|
|
9
|
+
* page that offers them all (Swagger UI selects between them; the other pages link to each). One
|
|
10
|
+
* document is served as `openApiDocsRoutes` serves it, at `/openapi.json` and `/docs`.
|
|
11
|
+
*/
|
|
12
|
+
export function openApiDocumentsRoutes(documents, options = {}) {
|
|
13
|
+
const [only] = documents;
|
|
14
|
+
const { contractsPath = '/openapi', uiPath = '/docs', ui = 'swagger', ...shown } = options;
|
|
15
|
+
if (documents.length === 1 && only !== undefined) {
|
|
16
|
+
return openApiDocsRoutes(only.document, { ...shown, ui, uiPath });
|
|
17
|
+
}
|
|
18
|
+
const assets = shown.assetsUrl ?? DEFAULT_ASSETS[ui];
|
|
19
|
+
const listed = documents.map(({ name, document }) => listedDocument(name, document, { contractsPath, uiPath }));
|
|
20
|
+
const title = shown.title ?? 'API documentation';
|
|
21
|
+
return [
|
|
22
|
+
...documents.flatMap(({ document }, index) => documentRoutes(document, listed[index], { ui, assets })),
|
|
23
|
+
page(uiPath, 'getOpenApiUi', documentsPage({ ui, title, documents: listed, assets })),
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
function listedDocument(name, document, { contractsPath, uiPath }) {
|
|
27
|
+
return { name, title: document.info.title, url: `${contractsPath}/${name}.json`, page: `${uiPath}/${name}` };
|
|
28
|
+
}
|
|
29
|
+
function documentRoutes(document, listed, { ui, assets }) {
|
|
30
|
+
if (listed === undefined) {
|
|
31
|
+
return [];
|
|
32
|
+
}
|
|
33
|
+
const html = docsPage({ ui, title: listed.title, specUrl: listed.url, assets });
|
|
34
|
+
const id = listed.name.replace(/-(\w)/g, (_dash, letter) => letter.toUpperCase());
|
|
35
|
+
return [
|
|
36
|
+
textRoute({
|
|
37
|
+
path: listed.url,
|
|
38
|
+
operationId: `getOpenApiDocument_${id}`,
|
|
39
|
+
summary: `OpenAPI contract: ${listed.name}`,
|
|
40
|
+
description: 'An OpenAPI 3.1 document.',
|
|
41
|
+
contentType: 'application/json; charset=utf-8',
|
|
42
|
+
body: stringifyOpenApi(document),
|
|
43
|
+
}),
|
|
44
|
+
page(listed.page, `getOpenApiUi_${id}`, html),
|
|
45
|
+
];
|
|
46
|
+
}
|
|
47
|
+
function page(path, operationId, body) {
|
|
48
|
+
return textRoute({
|
|
49
|
+
path,
|
|
50
|
+
operationId,
|
|
51
|
+
summary: 'Interactive API documentation',
|
|
52
|
+
description: 'An HTML page.',
|
|
53
|
+
contentType: 'text/html; charset=utf-8',
|
|
54
|
+
body,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=open-api-documents-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-api-documents-routes.js","sourceRoot":"","sources":["../../src/docs/open-api-documents-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Route } from '../route/route.js';
|
|
2
|
+
/** A public GET route answering a fixed text: a contract or a page of the documentation. */
|
|
3
|
+
export interface TextRoute {
|
|
4
|
+
readonly path: string;
|
|
5
|
+
readonly operationId: string;
|
|
6
|
+
readonly summary: string;
|
|
7
|
+
readonly description: string;
|
|
8
|
+
readonly contentType: string;
|
|
9
|
+
readonly body: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function textRoute(route: TextRoute): Route;
|
|
12
|
+
//# sourceMappingURL=text-route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-route.d.ts","sourceRoot":"","sources":["../../src/docs/text-route.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,4FAA4F;AAC5F,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAID,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,KAAK,CAYjD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ok } from '@ddd-ts-kit/kernel';
|
|
2
|
+
import { customSchema } from '@ddd-ts-kit/validation';
|
|
3
|
+
import { defineRoute } from '../route/define-route.js';
|
|
4
|
+
const text = customSchema((input) => ok(String(input)), { type: 'string' });
|
|
5
|
+
export function textRoute(route) {
|
|
6
|
+
return defineRoute({
|
|
7
|
+
method: 'GET',
|
|
8
|
+
path: route.path,
|
|
9
|
+
operationId: route.operationId,
|
|
10
|
+
summary: route.summary,
|
|
11
|
+
responses: { 200: { description: route.description, body: text } },
|
|
12
|
+
security: false,
|
|
13
|
+
}, async () => ({ status: 200, body: route.body, headers: { 'content-type': route.contentType } }));
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=text-route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-route.js","sourceRoot":"","sources":["../../src/docs/text-route.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAavD,MAAM,IAAI,GAAG,YAAY,CAAS,CAAC,KAAK,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAEpF,MAAM,UAAU,SAAS,CAAC,KAAgB;IACxC,OAAO,WAAW,CAChB;QACE,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;QAClE,QAAQ,EAAE,KAAK;KAChB,EACD,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC,CAChG,CAAC;AACJ,CAAC"}
|
package/dist/docs.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export type { DocsUi } from './docs/docs-ui.js';
|
|
2
2
|
export { openApiDocsRoutes, type DocsRoutesOptions } from './docs/open-api-docs-routes.js';
|
|
3
|
+
export { openApiDocumentsRoutes, type DocumentsRoutesOptions, type NamedOpenApiDocument, } from './docs/open-api-documents-routes.js';
|
|
3
4
|
//# sourceMappingURL=docs.d.ts.map
|
package/dist/docs.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EACL,sBAAsB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,GAC1B,MAAM,qCAAqC,CAAC"}
|
package/dist/docs.js
CHANGED
package/dist/docs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAA0B,MAAM,gCAAgC,CAAC"}
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../src/docs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAA0B,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EACL,sBAAsB,GAGvB,MAAM,qCAAqC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Route } from '../route/route.js';
|
|
2
|
+
/** The routes of one document of the contract. */
|
|
3
|
+
export interface DocumentRoutes {
|
|
4
|
+
readonly name: string;
|
|
5
|
+
readonly title?: string;
|
|
6
|
+
readonly routes: readonly Route[];
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=document-routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-routes.d.ts","sourceRoot":"","sources":["../../src/openapi/document-routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE/C,kDAAkD;AAClD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,CAAC;CACnC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-routes.js","sourceRoot":"","sources":["../../src/openapi/document-routes.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One document of a split contract, as `ddd-ts-kit docs` writes it from `openapi.documents` of
|
|
3
|
+
* the config: a route belongs to it when one of its route groups, one of its tags or its
|
|
4
|
+
* operation id is listed (the operations of the contexts the config names, read from the sources).
|
|
5
|
+
*/
|
|
6
|
+
export interface OpenApiDocumentSelection {
|
|
7
|
+
readonly name: string;
|
|
8
|
+
readonly title?: string;
|
|
9
|
+
readonly groups?: readonly string[];
|
|
10
|
+
readonly tags?: readonly string[];
|
|
11
|
+
readonly operations?: readonly string[];
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=open-api-document-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-api-document-selection.d.ts","sourceRoot":"","sources":["../../src/openapi/open-api-document-selection.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open-api-document-selection.js","sourceRoot":"","sources":["../../src/openapi/open-api-document-selection.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Route } from '../route/route.js';
|
|
2
|
+
import type { DocumentRoutes } from './document-routes.js';
|
|
3
|
+
import type { OpenApiDocumentSelection } from './open-api-document-selection.js';
|
|
4
|
+
/**
|
|
5
|
+
* Splits the routes between the documents of the contract. Each document holds the routes it
|
|
6
|
+
* selects, a route may be in several on purpose, and a route in none is refused: nothing
|
|
7
|
+
* leaves the contract silently. Without any selection there is one document, `openapi`.
|
|
8
|
+
*/
|
|
9
|
+
export declare function routesByDocument(routes: readonly Route[], selections: readonly OpenApiDocumentSelection[]): DocumentRoutes[];
|
|
10
|
+
//# sourceMappingURL=routes-by-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes-by-document.d.ts","sourceRoot":"","sources":["../../src/openapi/routes-by-document.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAKjF;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,EACxB,UAAU,EAAE,SAAS,wBAAwB,EAAE,GAC9C,cAAc,EAAE,CAkBlB"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { DeclarationError } from '@ddd-ts-kit/kernel/declarations';
|
|
2
|
+
/** Without a selection, the one document every project had before the contract could be split. */
|
|
3
|
+
const WHOLE = 'openapi';
|
|
4
|
+
/**
|
|
5
|
+
* Splits the routes between the documents of the contract. Each document holds the routes it
|
|
6
|
+
* selects, a route may be in several on purpose, and a route in none is refused: nothing
|
|
7
|
+
* leaves the contract silently. Without any selection there is one document, `openapi`.
|
|
8
|
+
*/
|
|
9
|
+
export function routesByDocument(routes, selections) {
|
|
10
|
+
if (selections.length === 0) {
|
|
11
|
+
return [{ name: WHOLE, routes }];
|
|
12
|
+
}
|
|
13
|
+
const unplaced = routes.filter((route) => !selections.some((selection) => selects(selection, route)));
|
|
14
|
+
if (unplaced.length > 0) {
|
|
15
|
+
throw new DeclarationError(`No document of "openapi.documents" holds ${unplaced.map(described).join(', ')}. Name its route group, its context or one of its tags in a document of ddd-ts-kit.config.json, then run \`ddd-ts-kit docs\`.`);
|
|
16
|
+
}
|
|
17
|
+
return selections.map(({ name, title, ...selection }) => ({
|
|
18
|
+
name,
|
|
19
|
+
...(title === undefined ? {} : { title }),
|
|
20
|
+
routes: routes.filter((route) => selects(selection, route)),
|
|
21
|
+
}));
|
|
22
|
+
}
|
|
23
|
+
function selects(selection, route) {
|
|
24
|
+
return ((route.groups ?? []).some((group) => selection.groups?.includes(group) === true) ||
|
|
25
|
+
(route.tags ?? []).some((tag) => selection.tags?.includes(tag) === true) ||
|
|
26
|
+
selection.operations?.includes(route.operationId) === true);
|
|
27
|
+
}
|
|
28
|
+
function described(route) {
|
|
29
|
+
return `${route.method} ${route.path} (${route.operationId})`;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=routes-by-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes-by-document.js","sourceRoot":"","sources":["../../src/openapi/routes-by-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAKnE,kGAAkG;AAClG,MAAM,KAAK,GAAG,SAAS,CAAC;AAExB;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAwB,EACxB,UAA+C;IAE/C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEtG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,gBAAgB,CACxB,4CAA4C,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,+HAA+H,CAC9M,CAAC;IACJ,CAAC;IAED,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC;QACxD,IAAI;QACJ,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;QACzC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;KAC5D,CAAC,CAAC,CAAC;AACN,CAAC;AAED,SAAS,OAAO,CAAC,SAA2D,EAAE,KAAY;IACxF,OAAO,CACL,CAAC,KAAK,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC;QAChF,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;QACxE,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,KAAK,IAAI,CAC3D,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAC,KAAY;IAC7B,OAAO,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,WAAW,GAAG,CAAC;AAChE,CAAC"}
|
package/dist/openapi.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export { checkOpenApiDrift } from './openapi/check-open-api-drift.js';
|
|
2
|
+
export type { DocumentRoutes } from './openapi/document-routes.js';
|
|
2
3
|
export { generateOpenApi, type GenerateOpenApiOptions } from './openapi/generate-open-api.js';
|
|
3
4
|
export type { OpenApiDocument } from './openapi/open-api-document.js';
|
|
5
|
+
export type { OpenApiDocumentSelection } from './openapi/open-api-document-selection.js';
|
|
4
6
|
export type { OpenApiInfo } from './openapi/open-api-info.js';
|
|
5
7
|
export type { OpenApiServer } from './openapi/open-api-server.js';
|
|
8
|
+
export { routesByDocument } from './openapi/routes-by-document.js';
|
|
6
9
|
export { stringifyOpenApi } from './openapi/stringify-open-api.js';
|
|
7
10
|
//# sourceMappingURL=openapi.d.ts.map
|
package/dist/openapi.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
1
|
+
{"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,YAAY,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,KAAK,sBAAsB,EAAE,MAAM,gCAAgC,CAAC;AAC9F,YAAY,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,YAAY,EAAE,wBAAwB,EAAE,MAAM,0CAA0C,CAAC;AACzF,YAAY,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,YAAY,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/openapi.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { checkOpenApiDrift } from './openapi/check-open-api-drift.js';
|
|
2
2
|
export { generateOpenApi } from './openapi/generate-open-api.js';
|
|
3
|
+
export { routesByDocument } from './openapi/routes-by-document.js';
|
|
3
4
|
export { stringifyOpenApi } from './openapi/stringify-open-api.js';
|
|
4
5
|
//# sourceMappingURL=openapi.js.map
|
package/dist/openapi.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EAAE,eAAe,EAA+B,MAAM,gCAAgC,CAAC;AAK9F,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC"}
|
package/dist/route/route.d.ts
CHANGED
|
@@ -6,6 +6,11 @@ import type { RouteSpec } from './route-spec.js';
|
|
|
6
6
|
* shape sit in one list; they are checked where it matters, in `defineRoute`.
|
|
7
7
|
*/
|
|
8
8
|
export interface Route extends RouteSpec {
|
|
9
|
+
/**
|
|
10
|
+
* The class names of the route group of a controller and of every group above it, nearest
|
|
11
|
+
* first: what a document of a split contract selects by. Not part of the contract.
|
|
12
|
+
*/
|
|
13
|
+
readonly groups?: readonly string[];
|
|
9
14
|
handle(input: RouteInput): RouteOutput | Promise<RouteOutput>;
|
|
10
15
|
}
|
|
11
16
|
//# sourceMappingURL=route.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/route/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;GAGG;AACH,MAAM,WAAW,KAAM,SAAQ,SAAS;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../src/route/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;GAGG;AACH,MAAM,WAAW,KAAM,SAAQ,SAAS;IACtC;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAIpC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;CAC/D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ddd-ts-kit/http",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Framework-agnostic route definitions with Express, Fastify and NestJS adapters and OpenAPI 3.1 generation.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"dist"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@ddd-ts-kit/kernel": "0.
|
|
50
|
-
"@ddd-ts-kit/validation": "0.
|
|
49
|
+
"@ddd-ts-kit/kernel": "0.6.0",
|
|
50
|
+
"@ddd-ts-kit/validation": "0.6.0"
|
|
51
51
|
},
|
|
52
52
|
"peerDependencies": {
|
|
53
53
|
"@nestjs/common": ">=11.0.0",
|