@degenerate/endpoints 0.1.7 → 0.4.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 +18 -0
- package/dist/cors/authority/jwt/build-validate-jwt-for-audience.d.ts +41 -0
- package/dist/cors/authority/jwt/build-validate-jwt-for-audience.d.ts.map +1 -0
- package/dist/cors/authority/jwt/build-validate-jwt-for-audience.js +75 -0
- package/dist/cors/authority/jwt/validate-jwt-authorities.d.ts +5 -13
- package/dist/cors/authority/jwt/validate-jwt-authorities.d.ts.map +1 -1
- package/dist/cors/authority/jwt/validate-jwt-authorities.js +7 -27
- package/dist/cors/authority/jwt/validate-jwt-endpoints.d.ts +5 -13
- package/dist/cors/authority/jwt/validate-jwt-endpoints.d.ts.map +1 -1
- package/dist/cors/authority/jwt/validate-jwt-endpoints.js +7 -27
- package/dist/cors/authority/jwt/validate-jwt-events.d.ts +5 -13
- package/dist/cors/authority/jwt/validate-jwt-events.d.ts.map +1 -1
- package/dist/cors/authority/jwt/validate-jwt-events.js +7 -27
- package/dist/cors/authority/jwt/validate-jwt-functions.d.ts +5 -13
- package/dist/cors/authority/jwt/validate-jwt-functions.d.ts.map +1 -1
- package/dist/cors/authority/jwt/validate-jwt-functions.js +7 -27
- package/dist/cors/authority/jwt/validate-jwt-rules.d.ts +5 -13
- package/dist/cors/authority/jwt/validate-jwt-rules.d.ts.map +1 -1
- package/dist/cors/authority/jwt/validate-jwt-rules.js +7 -27
- package/dist/cors/authority/jwt/validate-jwt-share-data.d.ts +5 -13
- package/dist/cors/authority/jwt/validate-jwt-share-data.d.ts.map +1 -1
- package/dist/cors/authority/jwt/validate-jwt-share-data.js +7 -27
- package/dist/cors/endpoints/helpers/validate-incoming-request-data.d.ts.map +1 -1
- package/dist/cors/endpoints/helpers/validate-incoming-request-data.js +1 -1
- package/dist/cors/index.d.ts +1 -0
- package/dist/cors/index.d.ts.map +1 -1
- package/dist/cors/index.js +1 -0
- package/dist/examples/express-server/app.d.ts +20 -2
- package/dist/examples/express-server/app.d.ts.map +1 -1
- package/dist/examples/express-server/app.js +42 -21
- package/dist/examples/express-server/authenticate-realtime.d.ts +27 -0
- package/dist/examples/express-server/authenticate-realtime.d.ts.map +1 -0
- package/dist/examples/express-server/authenticate-realtime.js +23 -0
- package/dist/examples/express-server/server.d.ts +32 -1
- package/dist/examples/express-server/server.d.ts.map +1 -1
- package/dist/examples/express-server/server.js +61 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/openapi/build-openapi-document.d.ts +27 -0
- package/dist/openapi/build-openapi-document.d.ts.map +1 -0
- package/dist/openapi/build-openapi-document.js +223 -0
- package/dist/openapi/domain-schemas.d.ts +16 -0
- package/dist/openapi/domain-schemas.d.ts.map +1 -0
- package/dist/openapi/domain-schemas.js +39 -0
- package/dist/openapi/index.d.ts +6 -0
- package/dist/openapi/index.d.ts.map +1 -0
- package/dist/openapi/index.js +21 -0
- package/dist/openapi/operations.d.ts +8 -0
- package/dist/openapi/operations.d.ts.map +1 -0
- package/dist/openapi/operations.js +22 -0
- package/dist/openapi/response-schemas.d.ts +32 -0
- package/dist/openapi/response-schemas.d.ts.map +1 -0
- package/dist/openapi/response-schemas.js +30 -0
- package/dist/openapi/types.d.ts +29 -0
- package/dist/openapi/types.d.ts.map +1 -0
- package/dist/openapi/types.js +2 -0
- package/dist/routes/authorities/v1.openapi.d.ts +4 -0
- package/dist/routes/authorities/v1.openapi.d.ts.map +1 -0
- package/dist/routes/authorities/v1.openapi.js +68 -0
- package/dist/routes/events/v1.openapi.d.ts +4 -0
- package/dist/routes/events/v1.openapi.d.ts.map +1 -0
- package/dist/routes/events/v1.openapi.js +54 -0
- package/dist/routes/events/v1.routes.d.ts.map +1 -1
- package/dist/routes/events/v1.routes.js +5 -3
- package/dist/routes/events.routes.d.ts.map +1 -1
- package/dist/routes/events.routes.js +10 -60
- package/dist/routes/functions/v1.openapi.d.ts +4 -0
- package/dist/routes/functions/v1.openapi.d.ts.map +1 -0
- package/dist/routes/functions/v1.openapi.js +68 -0
- package/dist/routes/functions.routes.d.ts.map +1 -1
- package/dist/routes/functions.routes.js +10 -60
- package/dist/routes/rules/v1/rule-set.openapi.d.ts +4 -0
- package/dist/routes/rules/v1/rule-set.openapi.d.ts.map +1 -0
- package/dist/routes/rules/v1/rule-set.openapi.js +72 -0
- package/dist/routes/rules/v1/rule-set.routes.js +3 -3
- package/dist/routes/share-data.routes.d.ts.map +1 -1
- package/dist/routes/share-data.routes.js +17 -59
- package/dist/routes/sharedata/v1.openapi.d.ts +8 -0
- package/dist/routes/sharedata/v1.openapi.d.ts.map +1 -0
- package/dist/routes/sharedata/v1.openapi.js +60 -0
- package/dist/routes/sharedata/v1.routes.d.ts.map +1 -1
- package/dist/routes/sharedata/v1.routes.js +195 -9
- package/dist/routes/validation/rules/validate-rules.openapi.d.ts +8 -0
- package/dist/routes/validation/rules/validate-rules.openapi.d.ts.map +1 -0
- package/dist/routes/validation/rules/validate-rules.openapi.js +76 -0
- package/package.json +28 -15
|
@@ -1,3 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import express, { type Express } from 'express';
|
|
2
|
+
import { AuthorizedAuthorities } from '@degenerate/generic';
|
|
3
|
+
import { ShareDataManager } from '@degenerate/sharedata';
|
|
4
|
+
export interface CreateAppResult {
|
|
5
|
+
app: Express;
|
|
6
|
+
authorizedAuthorities: AuthorizedAuthorities;
|
|
7
|
+
shareDataManager: ShareDataManager;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Builds a fresh Express app with all SAFE routes wired in. Returns the app
|
|
11
|
+
* along with the shared `ShareDataManager` instance — handed back so callers
|
|
12
|
+
* (e.g. `createSafeServer` for realtime attachment) can subscribe to its
|
|
13
|
+
* events without reaching into `app.locals`.
|
|
14
|
+
*
|
|
15
|
+
* Route handlers access the manager via `req.app.get('shareDataManager')`,
|
|
16
|
+
* matching the existing `authorizedAuthorities` pattern.
|
|
17
|
+
*/
|
|
18
|
+
export declare function createApp(): CreateAppResult;
|
|
19
|
+
declare const _default: express.Express;
|
|
20
|
+
export default _default;
|
|
3
21
|
//# sourceMappingURL=app.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/examples/express-server/app.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../src/examples/express-server/app.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,EAAE,EAAE,KAAK,OAAO,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAYzD,MAAM,WAAW,eAAe;IAC5B,GAAG,EAAE,OAAO,CAAC;IACb,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,gBAAgB,EAAE,gBAAgB,CAAC;CACtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,IAAI,eAAe,CA6B3C;;AAKD,wBAAmC"}
|
|
@@ -3,7 +3,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.createApp = createApp;
|
|
6
7
|
const express_1 = __importDefault(require("express"));
|
|
8
|
+
const generic_1 = require("@degenerate/generic");
|
|
9
|
+
const sharedata_1 = require("@degenerate/sharedata");
|
|
7
10
|
//#region Route Imports
|
|
8
11
|
const authorities_routes_1 = require("../../routes/authorities.routes");
|
|
9
12
|
const events_routes_1 = require("../../routes/events.routes");
|
|
@@ -11,25 +14,43 @@ const functions_routes_1 = require("../../routes/functions.routes");
|
|
|
11
14
|
const rules_routes_1 = require("../../routes/rules.routes");
|
|
12
15
|
const share_data_routes_1 = require("../../routes/share-data.routes");
|
|
13
16
|
const validation_routes_1 = require("../../routes/validation.routes");
|
|
14
|
-
const generic_1 = require("@degenerate/generic");
|
|
15
17
|
const cors_1 = require("../../cors");
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
app
|
|
28
|
-
app.use(
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
app.
|
|
32
|
-
app.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
18
|
+
const openapi_1 = require("../../openapi");
|
|
19
|
+
/**
|
|
20
|
+
* Builds a fresh Express app with all SAFE routes wired in. Returns the app
|
|
21
|
+
* along with the shared `ShareDataManager` instance — handed back so callers
|
|
22
|
+
* (e.g. `createSafeServer` for realtime attachment) can subscribe to its
|
|
23
|
+
* events without reaching into `app.locals`.
|
|
24
|
+
*
|
|
25
|
+
* Route handlers access the manager via `req.app.get('shareDataManager')`,
|
|
26
|
+
* matching the existing `authorizedAuthorities` pattern.
|
|
27
|
+
*/
|
|
28
|
+
function createApp() {
|
|
29
|
+
const app = (0, express_1.default)();
|
|
30
|
+
app.use(express_1.default.json());
|
|
31
|
+
const authorizedAuthorities = new generic_1.AuthorizedAuthorities();
|
|
32
|
+
const shareDataManager = new sharedata_1.ShareDataManager();
|
|
33
|
+
app.set('authorizedAuthorities', authorizedAuthorities);
|
|
34
|
+
app.set('shareDataManager', shareDataManager);
|
|
35
|
+
// Public, unauthenticated machine-readable API description. Generated once
|
|
36
|
+
// from the same Zod schemas the routes validate against; no auth so tooling
|
|
37
|
+
// (codegen, Swagger UI, contract tests) can fetch it freely.
|
|
38
|
+
const openApiDocument = (0, openapi_1.buildOpenApiDocument)();
|
|
39
|
+
app.get('/openapi.json', (_req, res) => {
|
|
40
|
+
res.status(200).json(openApiDocument);
|
|
41
|
+
});
|
|
42
|
+
app.use('/authorities', authorities_routes_1.authorities);
|
|
43
|
+
app.use('/events', events_routes_1.events);
|
|
44
|
+
app.use('/functions', functions_routes_1.functions);
|
|
45
|
+
app.use('/rules', rules_routes_1.rules);
|
|
46
|
+
app.use('/share-data', share_data_routes_1.shareData);
|
|
47
|
+
app.use('/validation', validation_routes_1.validation);
|
|
48
|
+
app.use(cors_1.unauthorizedHandler);
|
|
49
|
+
app.use(cors_1.badRequestHandler);
|
|
50
|
+
app.use(cors_1.allErrorHandler);
|
|
51
|
+
return { app, authorizedAuthorities, shareDataManager };
|
|
52
|
+
}
|
|
53
|
+
// Back-compat: tests and existing callers import the default app singleton.
|
|
54
|
+
// New code should prefer `createApp()` so each instance is isolated.
|
|
55
|
+
const defaultInstance = createApp();
|
|
56
|
+
exports.default = defaultInstance.app;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AuthenticateUpgrade } from '@degenerate/realtime';
|
|
2
|
+
/**
|
|
3
|
+
* Context attached to every accepted WebSocket connection. Replace the
|
|
4
|
+
* placeholder fields with whatever your application needs to authorize
|
|
5
|
+
* subsequent messages (subject, scopes, tenant id, etc.).
|
|
6
|
+
*/
|
|
7
|
+
export interface ExampleRealtimeContext {
|
|
8
|
+
subject: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Example upgrade authenticator. Accepts every connection with a synthetic
|
|
12
|
+
* subject — adequate for demos and integration tests, not for production.
|
|
13
|
+
*
|
|
14
|
+
* To wire real JWT auth, replace the body with something like:
|
|
15
|
+
*
|
|
16
|
+
* import { ... } from '@degenerate/generic';
|
|
17
|
+
* const token = extractTokenFromHeaderOrQuery(req);
|
|
18
|
+
* if (!token) return null;
|
|
19
|
+
* const payload = await verifyJwt(token, authorizedAuthorities);
|
|
20
|
+
* return payload ? { subject: payload.sub } : null;
|
|
21
|
+
*
|
|
22
|
+
* `validateJWTShareData` in `cors/authority/jwt/` is the HTTP-side equivalent
|
|
23
|
+
* — reuse the same key resolution + claim checks here so HTTP and WS share an
|
|
24
|
+
* authorization model.
|
|
25
|
+
*/
|
|
26
|
+
export declare const exampleAuthenticate: AuthenticateUpgrade<ExampleRealtimeContext>;
|
|
27
|
+
//# sourceMappingURL=authenticate-realtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authenticate-realtime.d.ts","sourceRoot":"","sources":["../../../src/examples/express-server/authenticate-realtime.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACnC,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,sBAAsB,CAI3E,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.exampleAuthenticate = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Example upgrade authenticator. Accepts every connection with a synthetic
|
|
6
|
+
* subject — adequate for demos and integration tests, not for production.
|
|
7
|
+
*
|
|
8
|
+
* To wire real JWT auth, replace the body with something like:
|
|
9
|
+
*
|
|
10
|
+
* import { ... } from '@degenerate/generic';
|
|
11
|
+
* const token = extractTokenFromHeaderOrQuery(req);
|
|
12
|
+
* if (!token) return null;
|
|
13
|
+
* const payload = await verifyJwt(token, authorizedAuthorities);
|
|
14
|
+
* return payload ? { subject: payload.sub } : null;
|
|
15
|
+
*
|
|
16
|
+
* `validateJWTShareData` in `cors/authority/jwt/` is the HTTP-side equivalent
|
|
17
|
+
* — reuse the same key resolution + claim checks here so HTTP and WS share an
|
|
18
|
+
* authorization model.
|
|
19
|
+
*/
|
|
20
|
+
const exampleAuthenticate = (_req) => {
|
|
21
|
+
return { subject: 'example-anonymous' };
|
|
22
|
+
};
|
|
23
|
+
exports.exampleAuthenticate = exampleAuthenticate;
|
|
@@ -1,2 +1,33 @@
|
|
|
1
|
-
|
|
1
|
+
import { type Server as HttpServer } from 'http';
|
|
2
|
+
import type { Express } from 'express';
|
|
3
|
+
import { ShareDataManager } from '@degenerate/sharedata';
|
|
4
|
+
import { type RealtimeServerHandle } from '@degenerate/realtime';
|
|
5
|
+
export interface SafeServerHandle {
|
|
6
|
+
/** The Express application — the same instance imported from `./app`. */
|
|
7
|
+
readonly app: Express;
|
|
8
|
+
/** The underlying Node HTTP server. Call `.listen()` to start accepting. */
|
|
9
|
+
readonly httpServer: HttpServer;
|
|
10
|
+
/** ShareDataManager broadcasting to subscribed WebSocket clients. */
|
|
11
|
+
readonly manager: ShareDataManager;
|
|
12
|
+
/** Realtime websocket handle. Call `.close()` during shutdown. */
|
|
13
|
+
readonly realtime: RealtimeServerHandle;
|
|
14
|
+
/** Convenience: cleanly stop realtime + close the HTTP server. */
|
|
15
|
+
close(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Builds the example SAFE server: the existing Express app wrapped in a Node
|
|
19
|
+
* HTTP server, with the realtime WebSocket transport attached at `/realtime`.
|
|
20
|
+
* Returns handles for caller-controlled `listen()` and shutdown so this is
|
|
21
|
+
* safe to use from tests as well as a `bin/` entry point.
|
|
22
|
+
*
|
|
23
|
+
* The returned `manager` is the one wired to the realtime broadcast loop and
|
|
24
|
+
* also the one routes resolve via `req.app.get('shareDataManager')`. HTTP
|
|
25
|
+
* route mutations therefore appear as `transaction` frames on the websocket.
|
|
26
|
+
*
|
|
27
|
+
* `propose` is wired to the id-based function resolver: any `IShareFunction`
|
|
28
|
+
* registered on a ShareData with an `id` becomes addressable by clients via
|
|
29
|
+
* the `functionId` field in a `propose` message. Functions without an `id`
|
|
30
|
+
* remain invisible to the wire — useful for purely-internal functions.
|
|
31
|
+
*/
|
|
32
|
+
export declare function createSafeServer(): SafeServerHandle;
|
|
2
33
|
//# sourceMappingURL=server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/examples/express-server/server.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/examples/express-server/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAC;AAC/D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAGH,KAAK,oBAAoB,EAC5B,MAAM,sBAAsB,CAAC;AAI9B,MAAM,WAAW,gBAAgB;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,qEAAqE;IACrE,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,kEAAkE;IAClE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,IAAI,gBAAgB,CA6BnD"}
|
|
@@ -1,9 +1,63 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
3
|
+
exports.createSafeServer = createSafeServer;
|
|
4
|
+
const http_1 = require("http");
|
|
5
|
+
const realtime_1 = require("@degenerate/realtime");
|
|
6
|
+
const app_1 = require("./app");
|
|
7
|
+
const authenticate_realtime_1 = require("./authenticate-realtime");
|
|
8
|
+
/**
|
|
9
|
+
* Builds the example SAFE server: the existing Express app wrapped in a Node
|
|
10
|
+
* HTTP server, with the realtime WebSocket transport attached at `/realtime`.
|
|
11
|
+
* Returns handles for caller-controlled `listen()` and shutdown so this is
|
|
12
|
+
* safe to use from tests as well as a `bin/` entry point.
|
|
13
|
+
*
|
|
14
|
+
* The returned `manager` is the one wired to the realtime broadcast loop and
|
|
15
|
+
* also the one routes resolve via `req.app.get('shareDataManager')`. HTTP
|
|
16
|
+
* route mutations therefore appear as `transaction` frames on the websocket.
|
|
17
|
+
*
|
|
18
|
+
* `propose` is wired to the id-based function resolver: any `IShareFunction`
|
|
19
|
+
* registered on a ShareData with an `id` becomes addressable by clients via
|
|
20
|
+
* the `functionId` field in a `propose` message. Functions without an `id`
|
|
21
|
+
* remain invisible to the wire — useful for purely-internal functions.
|
|
22
|
+
*/
|
|
23
|
+
function createSafeServer() {
|
|
24
|
+
const { app, shareDataManager: manager } = (0, app_1.createApp)();
|
|
25
|
+
const httpServer = (0, http_1.createServer)(app);
|
|
26
|
+
const realtime = (0, realtime_1.attachRealtimeServer)({
|
|
27
|
+
server: httpServer,
|
|
28
|
+
manager,
|
|
29
|
+
authenticate: authenticate_realtime_1.exampleAuthenticate,
|
|
30
|
+
path: '/realtime',
|
|
31
|
+
resolveFunction: (0, realtime_1.createIdBasedFunctionResolver)(manager),
|
|
32
|
+
});
|
|
33
|
+
let closed = false;
|
|
34
|
+
return {
|
|
35
|
+
app,
|
|
36
|
+
httpServer,
|
|
37
|
+
manager,
|
|
38
|
+
realtime,
|
|
39
|
+
async close() {
|
|
40
|
+
if (closed)
|
|
41
|
+
return;
|
|
42
|
+
closed = true;
|
|
43
|
+
await realtime.close();
|
|
44
|
+
// `httpServer.close()` errors if the server is already closed.
|
|
45
|
+
// The realtime handle may have already terminated all WS sockets,
|
|
46
|
+
// but the HTTP listener still needs to be stopped. Swallow the
|
|
47
|
+
// "not running" error so close() is idempotent.
|
|
48
|
+
await new Promise((resolve) => {
|
|
49
|
+
httpServer.close(() => resolve());
|
|
50
|
+
});
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// When run directly (e.g. `node dist/examples/express-server/server.js`),
|
|
55
|
+
// start the server on port 3000. Tests should call `createSafeServer()` and
|
|
56
|
+
// drive `.httpServer.listen(0, ...)` themselves.
|
|
57
|
+
if (require.main === module) {
|
|
58
|
+
const handle = createSafeServer();
|
|
59
|
+
handle.httpServer.listen(3000, () => {
|
|
60
|
+
// eslint-disable-next-line no-console
|
|
61
|
+
console.log('SAFE example server listening on :3000 (WS at /realtime)');
|
|
62
|
+
});
|
|
63
|
+
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,QAAQ,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,3 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
// This is the main file for the package
|
|
18
18
|
__exportStar(require("./cors"), exports);
|
|
19
|
+
__exportStar(require("./openapi"), exports);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { OperationDescriptor } from './types';
|
|
2
|
+
export interface OpenApiInfo {
|
|
3
|
+
title: string;
|
|
4
|
+
version: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Minimal structural shape of the emitted document. Component and path values
|
|
9
|
+
* are JSON Schema / OpenAPI fragments produced by Zod, so they are typed
|
|
10
|
+
* loosely rather than re-modeling the whole OpenAPI 3.0 type tree.
|
|
11
|
+
*/
|
|
12
|
+
export interface OpenApiDocument {
|
|
13
|
+
openapi: string;
|
|
14
|
+
info: OpenApiInfo;
|
|
15
|
+
components: {
|
|
16
|
+
securitySchemes: Record<string, unknown>;
|
|
17
|
+
schemas: Record<string, unknown>;
|
|
18
|
+
};
|
|
19
|
+
paths: Record<string, Record<string, unknown>>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Build an OpenAPI 3.0 document from the operation descriptors. Pure function:
|
|
23
|
+
* same input, same output, no side effects — so it can be computed once at
|
|
24
|
+
* server start and served as static JSON.
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildOpenApiDocument(operations?: OperationDescriptor[], info?: OpenApiInfo): OpenApiDocument;
|
|
27
|
+
//# sourceMappingURL=build-openapi-document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-openapi-document.d.ts","sourceRoot":"","sources":["../../src/openapi/build-openapi-document.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAOnD,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,WAAW,CAAC;IAClB,UAAU,EAAE;QACR,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CAClD;AAqOD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAChC,UAAU,GAAE,mBAAmB,EAAkB,EACjD,IAAI,GAAE,WAA0B,GACjC,eAAe,CAuBjB"}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildOpenApiDocument = buildOpenApiDocument;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const operations_1 = require("./operations");
|
|
6
|
+
const domain_schemas_1 = require("./domain-schemas");
|
|
7
|
+
/** Stable component names for the raw `@degenerate/generic` domain schemas. */
|
|
8
|
+
const domainNames = new Map(domain_schemas_1.domainComponentNames);
|
|
9
|
+
const DEFAULT_INFO = {
|
|
10
|
+
title: 'SAFE Endpoints API',
|
|
11
|
+
version: '1.0.0',
|
|
12
|
+
description: 'HTTP surface for the SAFE platform. Request and response schemas are ' +
|
|
13
|
+
'generated from the same Zod schemas the routes validate against.',
|
|
14
|
+
};
|
|
15
|
+
const STATUS_DESCRIPTIONS = {
|
|
16
|
+
200: 'Success',
|
|
17
|
+
400: 'Validation error',
|
|
18
|
+
403: 'Unauthorized',
|
|
19
|
+
404: 'Not found',
|
|
20
|
+
500: 'Internal server error',
|
|
21
|
+
501: 'Not implemented',
|
|
22
|
+
};
|
|
23
|
+
const statusDescription = (code) => STATUS_DESCRIPTIONS[code] ?? `Status ${code}`;
|
|
24
|
+
/** Names of `{param}` placeholders in an OpenAPI path template, in order. */
|
|
25
|
+
const pathParamNames = (path) => {
|
|
26
|
+
const names = [];
|
|
27
|
+
const matcher = /\{([^}]+)\}/g;
|
|
28
|
+
let match;
|
|
29
|
+
while ((match = matcher.exec(path)) !== null) {
|
|
30
|
+
names.push(match[1]);
|
|
31
|
+
}
|
|
32
|
+
return names;
|
|
33
|
+
};
|
|
34
|
+
const componentRef = (name) => ({
|
|
35
|
+
$ref: `#/components/schemas/${name}`,
|
|
36
|
+
});
|
|
37
|
+
/**
|
|
38
|
+
* Prefix of the `$ref`s Zod emits into its internal `__shared` defs bucket when
|
|
39
|
+
* a non-registered sub-schema is reused across two or more registered roots.
|
|
40
|
+
*/
|
|
41
|
+
const SHARED_REF_PREFIX = '#/components/schemas/__shared#/definitions/';
|
|
42
|
+
/**
|
|
43
|
+
* Inline any `__shared` `$ref` with the actual sub-schema it points at, leaving
|
|
44
|
+
* every real `#/components/schemas/<Name>` `$ref` untouched. Returns a fresh
|
|
45
|
+
* deep copy — never mutates the input.
|
|
46
|
+
*
|
|
47
|
+
* Why this is needed: `IShareRuleAppliedSchema` is `IShareRuleSchema.extend(...)`,
|
|
48
|
+
* so both share the very same `z.array(IConditionSchema)` instance for
|
|
49
|
+
* `currentDataConditions` / `proposedDataConditions`. When several rule schemas
|
|
50
|
+
* are registered together, Zod hoists that shared array into a `__shared`
|
|
51
|
+
* defs entry and points to it with a `__shared#/definitions/schemaN` `$ref`,
|
|
52
|
+
* which is not a resolvable OpenAPI component. Inlining the (small, acyclic)
|
|
53
|
+
* shared sub-schema yields a clean spec; the genuinely recursive schemas
|
|
54
|
+
* (`ShareRule` ↔ `Condition`) stay as proper component `$ref`s because they are
|
|
55
|
+
* registered.
|
|
56
|
+
*/
|
|
57
|
+
const inlineSharedRefs = (value, defs, active) => {
|
|
58
|
+
if (Array.isArray(value)) {
|
|
59
|
+
return value.map((item) => inlineSharedRefs(item, defs, active));
|
|
60
|
+
}
|
|
61
|
+
if (value && typeof value === 'object') {
|
|
62
|
+
const obj = value;
|
|
63
|
+
const ref = obj.$ref;
|
|
64
|
+
if (typeof ref === 'string' && ref.startsWith(SHARED_REF_PREFIX)) {
|
|
65
|
+
const defName = ref.slice(SHARED_REF_PREFIX.length);
|
|
66
|
+
if (active.has(defName)) {
|
|
67
|
+
throw new Error(`Cyclic __shared definition while inlining: ${defName}`);
|
|
68
|
+
}
|
|
69
|
+
if (!(defName in defs)) {
|
|
70
|
+
throw new Error(`Unresolved __shared definition: ${defName}`);
|
|
71
|
+
}
|
|
72
|
+
active.add(defName);
|
|
73
|
+
const resolved = inlineSharedRefs(defs[defName], defs, active);
|
|
74
|
+
active.delete(defName);
|
|
75
|
+
return resolved;
|
|
76
|
+
}
|
|
77
|
+
const out = {};
|
|
78
|
+
for (const [key, val] of Object.entries(obj)) {
|
|
79
|
+
out[key] = inlineSharedRefs(val, defs, active);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
return value;
|
|
84
|
+
};
|
|
85
|
+
/** Collect distinct schema instances (request + every response) in encounter order. */
|
|
86
|
+
const collectSchemas = (operations) => {
|
|
87
|
+
const seen = new Set();
|
|
88
|
+
const distinct = [];
|
|
89
|
+
const add = (schema) => {
|
|
90
|
+
if (schema && !seen.has(schema)) {
|
|
91
|
+
seen.add(schema);
|
|
92
|
+
distinct.push(schema);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
for (const op of operations) {
|
|
96
|
+
add(op.request);
|
|
97
|
+
for (const schema of Object.values(op.response)) {
|
|
98
|
+
add(schema);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return distinct;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* Register each distinct schema under a stable component name, convert the
|
|
105
|
+
* whole registry to OpenAPI-3.0 JSON Schema in one pass, and return both the
|
|
106
|
+
* `components.schemas` map and the schema→name lookup used to build `$ref`s.
|
|
107
|
+
*
|
|
108
|
+
* One pass with `io: 'output'` is correct for both request and response
|
|
109
|
+
* positions here because no SAFE schema uses a transform / default / coercion —
|
|
110
|
+
* so a schema's input and output JSON Schema are identical. Conversion via the
|
|
111
|
+
* registry overload makes a schema reused across operations (or nested inside a
|
|
112
|
+
* response envelope) emit as a single `$ref`'d component automatically.
|
|
113
|
+
*/
|
|
114
|
+
const buildComponents = (distinct) => {
|
|
115
|
+
const registry = zod_1.z.registry();
|
|
116
|
+
const nameBySchema = new Map();
|
|
117
|
+
const usedNames = new Set();
|
|
118
|
+
let autoCounter = 0;
|
|
119
|
+
for (const schema of distinct) {
|
|
120
|
+
const metaId = schema.meta()?.id ?? domainNames.get(schema);
|
|
121
|
+
let name = metaId ?? `Component${++autoCounter}`;
|
|
122
|
+
// Defensive: distinct schemas must map to distinct component names.
|
|
123
|
+
while (usedNames.has(name)) {
|
|
124
|
+
name = `${name}_${++autoCounter}`;
|
|
125
|
+
}
|
|
126
|
+
usedNames.add(name);
|
|
127
|
+
nameBySchema.set(schema, name);
|
|
128
|
+
registry.add(schema, { id: name });
|
|
129
|
+
}
|
|
130
|
+
const { schemas } = zod_1.z.toJSONSchema(registry, {
|
|
131
|
+
target: 'openapi-3.0',
|
|
132
|
+
io: 'output',
|
|
133
|
+
unrepresentable: 'any',
|
|
134
|
+
uri: (id) => `#/components/schemas/${id}`,
|
|
135
|
+
});
|
|
136
|
+
// Zod parks sub-schemas reused across registered roots in a `__shared`
|
|
137
|
+
// bucket; inline those back into the components and drop the bucket so every
|
|
138
|
+
// remaining `$ref` resolves to a real component. See `inlineSharedRefs`.
|
|
139
|
+
const sharedDefs = schemas.__shared?.definitions ?? {};
|
|
140
|
+
// Strip the non-OpenAPI `$id` Zod stamps on each component; `$ref`s between
|
|
141
|
+
// components are unaffected.
|
|
142
|
+
const cleaned = {};
|
|
143
|
+
for (const [name, schema] of Object.entries(schemas)) {
|
|
144
|
+
if (name === '__shared') {
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const inlined = inlineSharedRefs(schema, sharedDefs, new Set());
|
|
148
|
+
const { $id, ...rest } = inlined;
|
|
149
|
+
void $id;
|
|
150
|
+
cleaned[name] = rest;
|
|
151
|
+
}
|
|
152
|
+
return { schemas: cleaned, nameBySchema };
|
|
153
|
+
};
|
|
154
|
+
const buildPaths = (operations, nameBySchema) => {
|
|
155
|
+
const paths = {};
|
|
156
|
+
for (const op of operations) {
|
|
157
|
+
const pathItem = paths[op.path] ?? (paths[op.path] = {});
|
|
158
|
+
const responses = {};
|
|
159
|
+
for (const [status, schema] of Object.entries(op.response)) {
|
|
160
|
+
responses[status] = {
|
|
161
|
+
description: statusDescription(Number(status)),
|
|
162
|
+
content: { 'application/json': { schema: componentRef(nameBySchema.get(schema)) } },
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
const operationObject = {
|
|
166
|
+
summary: op.summary,
|
|
167
|
+
description: op.security === 'public'
|
|
168
|
+
? 'Public — no authentication required.'
|
|
169
|
+
: `Requires a valid JWT for the ${op.security} audience.`,
|
|
170
|
+
security: op.security === 'public' ? [] : [{ bearerAuth: [] }],
|
|
171
|
+
responses,
|
|
172
|
+
};
|
|
173
|
+
if (op.deprecated) {
|
|
174
|
+
operationObject.deprecated = true;
|
|
175
|
+
}
|
|
176
|
+
const params = pathParamNames(op.path);
|
|
177
|
+
if (params.length > 0) {
|
|
178
|
+
operationObject.parameters = params.map((name) => ({
|
|
179
|
+
name,
|
|
180
|
+
in: 'path',
|
|
181
|
+
required: true,
|
|
182
|
+
schema: { type: 'string' },
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
if (op.request) {
|
|
186
|
+
operationObject.requestBody = {
|
|
187
|
+
required: true,
|
|
188
|
+
content: {
|
|
189
|
+
'application/json': { schema: componentRef(nameBySchema.get(op.request)) },
|
|
190
|
+
},
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
pathItem[op.method] = operationObject;
|
|
194
|
+
}
|
|
195
|
+
return paths;
|
|
196
|
+
};
|
|
197
|
+
/**
|
|
198
|
+
* Build an OpenAPI 3.0 document from the operation descriptors. Pure function:
|
|
199
|
+
* same input, same output, no side effects — so it can be computed once at
|
|
200
|
+
* server start and served as static JSON.
|
|
201
|
+
*/
|
|
202
|
+
function buildOpenApiDocument(operations = operations_1.operations, info = DEFAULT_INFO) {
|
|
203
|
+
const { schemas, nameBySchema } = buildComponents(collectSchemas(operations));
|
|
204
|
+
const paths = buildPaths(operations, nameBySchema);
|
|
205
|
+
return {
|
|
206
|
+
openapi: '3.0.3',
|
|
207
|
+
info,
|
|
208
|
+
components: {
|
|
209
|
+
securitySchemes: {
|
|
210
|
+
bearerAuth: {
|
|
211
|
+
type: 'http',
|
|
212
|
+
scheme: 'bearer',
|
|
213
|
+
bearerFormat: 'JWT',
|
|
214
|
+
description: 'JWT bearer token. The token audience (aud) selects which route group it ' +
|
|
215
|
+
'authorizes: AUTHORITIES, EVENTS, FUNCTIONS, RULES, or SHAREDATA. Operations ' +
|
|
216
|
+
'on /share-data additionally enforce a per-resource (BOLA) check.',
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
schemas,
|
|
220
|
+
},
|
|
221
|
+
paths,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Stable OpenAPI component names for the centralized request/domain schemas in
|
|
4
|
+
* `@degenerate/generic`, keyed by the **raw** schema instance.
|
|
5
|
+
*
|
|
6
|
+
* Keyed by the raw instance (not a `.meta()` clone) on purpose: several rule
|
|
7
|
+
* schemas are recursive (`IShareRuleSchema` ↔ `IConditionSchema`, and
|
|
8
|
+
* `IShareRuleGroupSchema` via `z.lazy`), and those `z.lazy` thunks resolve to
|
|
9
|
+
* the raw generic instances. The generator must register the very instances
|
|
10
|
+
* the schema graph references, otherwise the recursive sub-schemas have no
|
|
11
|
+
* component id and Zod hoists them into a malformed shared-defs bucket. Every
|
|
12
|
+
* recursive schema below is also mounted as a `/validation` request body, so
|
|
13
|
+
* registering these names makes the whole graph resolve to clean `$ref`s.
|
|
14
|
+
*/
|
|
15
|
+
export declare const domainComponentNames: ReadonlyArray<readonly [z.ZodType, string]>;
|
|
16
|
+
//# sourceMappingURL=domain-schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-schemas.d.ts","sourceRoot":"","sources":["../../src/openapi/domain-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAwB7B;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,CAAC,CAqB5E,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.domainComponentNames = void 0;
|
|
4
|
+
const generic_1 = require("@degenerate/generic");
|
|
5
|
+
/**
|
|
6
|
+
* Stable OpenAPI component names for the centralized request/domain schemas in
|
|
7
|
+
* `@degenerate/generic`, keyed by the **raw** schema instance.
|
|
8
|
+
*
|
|
9
|
+
* Keyed by the raw instance (not a `.meta()` clone) on purpose: several rule
|
|
10
|
+
* schemas are recursive (`IShareRuleSchema` ↔ `IConditionSchema`, and
|
|
11
|
+
* `IShareRuleGroupSchema` via `z.lazy`), and those `z.lazy` thunks resolve to
|
|
12
|
+
* the raw generic instances. The generator must register the very instances
|
|
13
|
+
* the schema graph references, otherwise the recursive sub-schemas have no
|
|
14
|
+
* component id and Zod hoists them into a malformed shared-defs bucket. Every
|
|
15
|
+
* recursive schema below is also mounted as a `/validation` request body, so
|
|
16
|
+
* registering these names makes the whole graph resolve to clean `$ref`s.
|
|
17
|
+
*/
|
|
18
|
+
exports.domainComponentNames = [
|
|
19
|
+
[generic_1.ISAFETransactionAuthorityAddSchema, 'SAFETransactionAuthorityAdd'],
|
|
20
|
+
[generic_1.ISAFETransactionAuthorityUpdateSchema, 'SAFETransactionAuthorityUpdate'],
|
|
21
|
+
[generic_1.ISAFETransactionAuthorityDeleteSchema, 'SAFETransactionAuthorityDelete'],
|
|
22
|
+
[generic_1.ISAFETransactionEventAddSchema, 'SAFETransactionEventAdd'],
|
|
23
|
+
[generic_1.ISAFETransactionEventUpdateSchema, 'SAFETransactionEventUpdate'],
|
|
24
|
+
[generic_1.ISAFETransactionEventDeleteSchema, 'SAFETransactionEventDelete'],
|
|
25
|
+
[generic_1.ISAFETransactionFunctionAddSchema, 'SAFETransactionFunctionAdd'],
|
|
26
|
+
[generic_1.ISAFETransactionFunctionUpdateSchema, 'SAFETransactionFunctionUpdate'],
|
|
27
|
+
[generic_1.ISAFETransactionFunctionDeleteSchema, 'SAFETransactionFunctionDelete'],
|
|
28
|
+
[generic_1.ISAFETransactionRuleSetAddSchema, 'SAFETransactionRuleSetAdd'],
|
|
29
|
+
[generic_1.ISAFETransactionRuleSetUpdateSchema, 'SAFETransactionRuleSetUpdate'],
|
|
30
|
+
[generic_1.ISAFETransactionRuleSetDeleteSchema, 'SAFETransactionRuleSetDelete'],
|
|
31
|
+
[generic_1.ISAFETransactionShareDataAddSchema, 'SAFETransactionShareDataAdd'],
|
|
32
|
+
[generic_1.ISAFETransactionShareDataUpdateSchema, 'SAFETransactionShareDataUpdate'],
|
|
33
|
+
[generic_1.ISAFETransactionShareDataDeleteSchema, 'SAFETransactionShareDataDelete'],
|
|
34
|
+
[generic_1.IShareRuleSetSchema, 'ShareRuleSet'],
|
|
35
|
+
[generic_1.IShareRuleGroupSchema, 'ShareRuleGroup'],
|
|
36
|
+
[generic_1.IShareRuleAppliedSchema, 'ShareRuleApplied'],
|
|
37
|
+
[generic_1.IShareRuleSchema, 'ShareRule'],
|
|
38
|
+
[generic_1.IConditionSchema, 'Condition'],
|
|
39
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/openapi/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./types"), exports);
|
|
18
|
+
__exportStar(require("./response-schemas"), exports);
|
|
19
|
+
__exportStar(require("./domain-schemas"), exports);
|
|
20
|
+
__exportStar(require("./operations"), exports);
|
|
21
|
+
__exportStar(require("./build-openapi-document"), exports);
|