@furystack/rest-service 12.3.5 → 14.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.
- package/CHANGELOG.md +55 -0
- package/README.md +47 -28
- package/esm/actions/get-current-user.spec.js +10 -6
- package/esm/actions/get-current-user.spec.js.map +1 -1
- package/esm/actions/index.d.ts +0 -1
- package/esm/actions/index.d.ts.map +1 -1
- package/esm/actions/index.js +0 -1
- package/esm/actions/index.js.map +1 -1
- package/esm/actions/is-authenticated.spec.js +10 -6
- package/esm/actions/is-authenticated.spec.js.map +1 -1
- package/esm/actions/logout-action.spec.js +11 -9
- package/esm/actions/logout-action.spec.js.map +1 -1
- package/esm/actions/logout.js +1 -1
- package/esm/actions/logout.js.map +1 -1
- package/esm/actions/password-login-action.js +1 -1
- package/esm/actions/password-login-action.js.map +1 -1
- package/esm/actions/password-login-action.spec.js +23 -28
- package/esm/actions/password-login-action.spec.js.map +1 -1
- package/esm/authenticate.js +1 -1
- package/esm/authenticate.js.map +1 -1
- package/esm/authenticate.spec.js +41 -33
- package/esm/authenticate.spec.js.map +1 -1
- package/esm/authorize.spec.js +34 -29
- package/esm/authorize.spec.js.map +1 -1
- package/esm/endpoint-generators/create-delete-endpoint.d.ts +6 -11
- package/esm/endpoint-generators/create-delete-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-delete-endpoint.js +7 -11
- package/esm/endpoint-generators/create-delete-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-delete-endpoint.spec.js +14 -21
- package/esm/endpoint-generators/create-delete-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.d.ts +11 -11
- package/esm/endpoint-generators/create-get-collection-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.js +13 -12
- package/esm/endpoint-generators/create-get-collection-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-get-collection-endpoint.spec.js +43 -70
- package/esm/endpoint-generators/create-get-collection-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.d.ts +6 -11
- package/esm/endpoint-generators/create-get-entity-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.js +7 -11
- package/esm/endpoint-generators/create-get-entity-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-get-entity-endpoint.spec.js +16 -33
- package/esm/endpoint-generators/create-get-entity-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-get-openapi-document-action.d.ts +1 -15
- package/esm/endpoint-generators/create-get-openapi-document-action.d.ts.map +1 -1
- package/esm/endpoint-generators/create-get-openapi-document-action.js +1 -24
- package/esm/endpoint-generators/create-get-openapi-document-action.js.map +1 -1
- package/esm/endpoint-generators/create-get-schema-action.d.ts +1 -1
- package/esm/endpoint-generators/create-get-schema-action.d.ts.map +1 -1
- package/esm/endpoint-generators/create-get-schema-action.js.map +1 -1
- package/esm/endpoint-generators/create-patch-endpoint.d.ts +7 -13
- package/esm/endpoint-generators/create-patch-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-patch-endpoint.js +8 -13
- package/esm/endpoint-generators/create-patch-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-patch-endpoint.spec.js +10 -17
- package/esm/endpoint-generators/create-patch-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/create-post-endpoint.d.ts +7 -13
- package/esm/endpoint-generators/create-post-endpoint.d.ts.map +1 -1
- package/esm/endpoint-generators/create-post-endpoint.js +8 -13
- package/esm/endpoint-generators/create-post-endpoint.js.map +1 -1
- package/esm/endpoint-generators/create-post-endpoint.spec.js +41 -14
- package/esm/endpoint-generators/create-post-endpoint.spec.js.map +1 -1
- package/esm/endpoint-generators/utils.d.ts +17 -2
- package/esm/endpoint-generators/utils.d.ts.map +1 -1
- package/esm/endpoint-generators/utils.js +33 -20
- package/esm/endpoint-generators/utils.js.map +1 -1
- package/esm/endpoint-generators/with-schema-and-openapi-action.d.ts +0 -2
- package/esm/endpoint-generators/with-schema-and-openapi-action.d.ts.map +1 -1
- package/esm/get-schema-from-api.d.ts +1 -1
- package/esm/get-schema-from-api.d.ts.map +1 -1
- package/esm/get-schema-from-api.spec.js.map +1 -1
- package/esm/helpers.d.ts +53 -87
- package/esm/helpers.d.ts.map +1 -1
- package/esm/helpers.js +91 -92
- package/esm/helpers.js.map +1 -1
- package/esm/helpers.spec.d.ts +2 -1
- package/esm/helpers.spec.d.ts.map +1 -1
- package/esm/helpers.spec.js +41 -38
- package/esm/helpers.spec.js.map +1 -1
- package/esm/http-authentication-settings.d.ts +35 -12
- package/esm/http-authentication-settings.d.ts.map +1 -1
- package/esm/http-authentication-settings.js +21 -29
- package/esm/http-authentication-settings.js.map +1 -1
- package/esm/http-server-pool.d.ts +64 -0
- package/esm/http-server-pool.d.ts.map +1 -0
- package/esm/http-server-pool.js +95 -0
- package/esm/http-server-pool.js.map +1 -0
- package/esm/http-server-pool.spec.d.ts +2 -0
- package/esm/http-server-pool.spec.d.ts.map +1 -0
- package/esm/http-server-pool.spec.js +193 -0
- package/esm/http-server-pool.spec.js.map +1 -0
- package/esm/http-user-context.d.ts +31 -44
- package/esm/http-user-context.d.ts.map +1 -1
- package/esm/http-user-context.js +76 -95
- package/esm/http-user-context.js.map +1 -1
- package/esm/http-user-context.spec.d.ts +8 -2
- package/esm/http-user-context.spec.d.ts.map +1 -1
- package/esm/http-user-context.spec.js +189 -337
- package/esm/http-user-context.spec.js.map +1 -1
- package/esm/index.d.ts +6 -4
- package/esm/index.d.ts.map +1 -1
- package/esm/index.js +6 -4
- package/esm/index.js.map +1 -1
- package/esm/login-response-strategy.d.ts +11 -10
- package/esm/login-response-strategy.d.ts.map +1 -1
- package/esm/login-response-strategy.js +7 -6
- package/esm/login-response-strategy.js.map +1 -1
- package/esm/login-response-strategy.spec.js +25 -29
- package/esm/login-response-strategy.spec.js.map +1 -1
- package/esm/openapi/generate-openapi-document.d.ts +0 -8
- package/esm/openapi/generate-openapi-document.d.ts.map +1 -1
- package/esm/openapi/generate-openapi-document.js +0 -2
- package/esm/openapi/generate-openapi-document.js.map +1 -1
- package/esm/proxy-manager.spec.js +152 -176
- package/esm/proxy-manager.spec.js.map +1 -1
- package/esm/proxy-runtime.d.ts +27 -0
- package/esm/proxy-runtime.d.ts.map +1 -0
- package/esm/proxy-runtime.js +45 -0
- package/esm/proxy-runtime.js.map +1 -0
- package/esm/proxy-runtime.spec.d.ts +2 -0
- package/esm/proxy-runtime.spec.d.ts.map +1 -0
- package/esm/proxy-runtime.spec.js +39 -0
- package/esm/proxy-runtime.spec.js.map +1 -0
- package/esm/rest-api-runtime.d.ts +76 -0
- package/esm/rest-api-runtime.d.ts.map +1 -0
- package/esm/rest-api-runtime.js +131 -0
- package/esm/rest-api-runtime.js.map +1 -0
- package/esm/rest-api-runtime.spec.d.ts +2 -0
- package/esm/rest-api-runtime.spec.d.ts.map +1 -0
- package/esm/rest-api-runtime.spec.js +58 -0
- package/esm/rest-api-runtime.spec.js.map +1 -0
- package/esm/rest-service.integration.spec.d.ts +1 -1
- package/esm/rest-service.integration.spec.d.ts.map +1 -1
- package/esm/rest-service.integration.spec.js +60 -82
- package/esm/rest-service.integration.spec.js.map +1 -1
- package/esm/rest.integration.test.js +26 -84
- package/esm/rest.integration.test.js.map +1 -1
- package/esm/server-telemetry.d.ts +57 -0
- package/esm/server-telemetry.d.ts.map +1 -0
- package/esm/server-telemetry.js +26 -0
- package/esm/server-telemetry.js.map +1 -0
- package/esm/server-telemetry.spec.d.ts +2 -0
- package/esm/server-telemetry.spec.d.ts.map +1 -0
- package/esm/server-telemetry.spec.js +52 -0
- package/esm/server-telemetry.spec.js.map +1 -0
- package/esm/static-server-manager.spec.js +60 -125
- package/esm/static-server-manager.spec.js.map +1 -1
- package/esm/static-site-runtime.d.ts +21 -0
- package/esm/static-site-runtime.d.ts.map +1 -0
- package/esm/static-site-runtime.js +48 -0
- package/esm/static-site-runtime.js.map +1 -0
- package/esm/static-site-runtime.spec.d.ts +2 -0
- package/esm/static-site-runtime.spec.d.ts.map +1 -0
- package/esm/static-site-runtime.spec.js +30 -0
- package/esm/static-site-runtime.spec.js.map +1 -0
- package/esm/user-store.d.ts +39 -0
- package/esm/user-store.d.ts.map +1 -0
- package/esm/user-store.js +62 -0
- package/esm/user-store.js.map +1 -0
- package/esm/user-store.spec.d.ts +2 -0
- package/esm/user-store.spec.d.ts.map +1 -0
- package/esm/user-store.spec.js +72 -0
- package/esm/user-store.spec.js.map +1 -0
- package/esm/validate.integration.spec.js +26 -83
- package/esm/validate.integration.spec.js.map +1 -1
- package/package.json +8 -8
- package/src/actions/get-current-user.spec.ts +11 -10
- package/src/actions/index.ts +0 -1
- package/src/actions/is-authenticated.spec.ts +12 -7
- package/src/actions/logout-action.spec.ts +12 -12
- package/src/actions/logout.ts +1 -1
- package/src/actions/password-login-action.spec.ts +30 -30
- package/src/actions/password-login-action.ts +1 -1
- package/src/authenticate.spec.ts +45 -51
- package/src/authenticate.ts +1 -1
- package/src/authorize.spec.ts +37 -39
- package/src/endpoint-generators/create-delete-endpoint.spec.ts +16 -24
- package/src/endpoint-generators/create-delete-endpoint.ts +11 -17
- package/src/endpoint-generators/create-get-collection-endpoint.spec.ts +45 -78
- package/src/endpoint-generators/create-get-collection-endpoint.ts +17 -19
- package/src/endpoint-generators/create-get-entity-endpoint.spec.ts +17 -33
- package/src/endpoint-generators/create-get-entity-endpoint.ts +11 -17
- package/src/endpoint-generators/create-get-openapi-document-action.ts +2 -38
- package/src/endpoint-generators/create-get-schema-action.ts +1 -1
- package/src/endpoint-generators/create-patch-endpoint.spec.ts +11 -18
- package/src/endpoint-generators/create-patch-endpoint.ts +12 -23
- package/src/endpoint-generators/create-post-endpoint.spec.ts +45 -14
- package/src/endpoint-generators/create-post-endpoint.ts +13 -23
- package/src/endpoint-generators/utils.ts +36 -28
- package/src/endpoint-generators/with-schema-and-openapi-action.ts +0 -3
- package/src/get-schema-from-api.spec.ts +1 -1
- package/src/get-schema-from-api.ts +1 -1
- package/src/helpers.spec.ts +51 -41
- package/src/helpers.ts +140 -109
- package/src/http-authentication-settings.ts +51 -25
- package/src/http-server-pool.spec.ts +220 -0
- package/src/http-server-pool.ts +169 -0
- package/src/http-user-context.spec.ts +203 -383
- package/src/http-user-context.ts +114 -91
- package/src/index.ts +6 -4
- package/src/login-response-strategy.spec.ts +32 -31
- package/src/login-response-strategy.ts +13 -12
- package/src/openapi/generate-openapi-document.ts +0 -3
- package/src/proxy-manager.spec.ts +152 -182
- package/src/proxy-runtime.spec.ts +50 -0
- package/src/proxy-runtime.ts +75 -0
- package/src/rest-api-runtime.spec.ts +77 -0
- package/src/rest-api-runtime.ts +204 -0
- package/src/rest-service.integration.spec.ts +68 -87
- package/src/rest.integration.test.ts +27 -87
- package/src/server-telemetry.spec.ts +56 -0
- package/src/server-telemetry.ts +51 -0
- package/src/static-server-manager.spec.ts +63 -151
- package/src/static-site-runtime.spec.ts +39 -0
- package/src/static-site-runtime.ts +75 -0
- package/src/user-store.spec.ts +86 -0
- package/src/user-store.ts +68 -0
- package/src/validate.integration.spec.ts +39 -97
- package/esm/actions/login-action.spec.d.ts +0 -2
- package/esm/actions/login-action.spec.d.ts.map +0 -1
- package/esm/actions/login-action.spec.js +0 -34
- package/esm/actions/login-action.spec.js.map +0 -1
- package/esm/actions/login.d.ts +0 -19
- package/esm/actions/login.d.ts.map +0 -1
- package/esm/actions/login.js +0 -27
- package/esm/actions/login.js.map +0 -1
- package/esm/api-manager.d.ts +0 -104
- package/esm/api-manager.d.ts.map +0 -1
- package/esm/api-manager.js +0 -180
- package/esm/api-manager.js.map +0 -1
- package/esm/proxy-manager.d.ts +0 -53
- package/esm/proxy-manager.d.ts.map +0 -1
- package/esm/proxy-manager.js +0 -84
- package/esm/proxy-manager.js.map +0 -1
- package/esm/server-manager.d.ts +0 -48
- package/esm/server-manager.d.ts.map +0 -1
- package/esm/server-manager.js +0 -100
- package/esm/server-manager.js.map +0 -1
- package/esm/static-server-manager.d.ts +0 -19
- package/esm/static-server-manager.d.ts.map +0 -1
- package/esm/static-server-manager.js +0 -65
- package/esm/static-server-manager.js.map +0 -1
- package/esm/swagger/generate-swagger-json.spec.d.ts +0 -2
- package/esm/swagger/generate-swagger-json.spec.d.ts.map +0 -1
- package/esm/swagger/generate-swagger-json.spec.js +0 -215
- package/esm/swagger/generate-swagger-json.spec.js.map +0 -1
- package/src/actions/login-action.spec.ts +0 -42
- package/src/actions/login.ts +0 -32
- package/src/api-manager.ts +0 -308
- package/src/proxy-manager.ts +0 -102
- package/src/server-manager.ts +0 -135
- package/src/static-server-manager.ts +0 -90
- package/src/swagger/generate-swagger-json.spec.ts +0 -250
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"static-server-manager.spec.js","sourceRoot":"","sources":["../src/static-server-manager.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"static-server-manager.spec.js","sourceRoot":"","sources":["../src/static-server-manager.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { OutgoingHttpHeaders } from 'http';
|
|
2
|
+
import type { ServerApi } from './http-server-pool.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options accepted by {@link buildStaticSiteServerApi} and
|
|
5
|
+
* {@link useStaticFiles}.
|
|
6
|
+
*/
|
|
7
|
+
export interface StaticServerOptions {
|
|
8
|
+
baseUrl: string;
|
|
9
|
+
path: string;
|
|
10
|
+
hostName?: string;
|
|
11
|
+
port: number;
|
|
12
|
+
fallback?: string;
|
|
13
|
+
headers?: OutgoingHttpHeaders;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Builds a {@link ServerApi} that serves files under `options.path` for every
|
|
17
|
+
* GET request whose URL matches `options.baseUrl`. Falls back to
|
|
18
|
+
* `options.fallback` (if set) for missing files, otherwise responds with 404.
|
|
19
|
+
*/
|
|
20
|
+
export declare const buildStaticSiteServerApi: (options: StaticServerOptions) => ServerApi;
|
|
21
|
+
//# sourceMappingURL=static-site-runtime.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site-runtime.d.ts","sourceRoot":"","sources":["../src/static-site-runtime.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAmB,mBAAmB,EAAkB,MAAM,MAAM,CAAA;AAEhF,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAGtD;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAA;CAC9B;AAwBD;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,mBAAmB,KAAG,SA0BvE,CAAA"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { PathHelper } from '@furystack/utils';
|
|
2
|
+
import { createReadStream } from 'fs';
|
|
3
|
+
import { access, stat } from 'fs/promises';
|
|
4
|
+
import { join, normalize, sep } from 'path';
|
|
5
|
+
import { getMimeForFile } from './mime-types.js';
|
|
6
|
+
const sendFile = async ({ fullPath, headers, res, }) => {
|
|
7
|
+
const { size } = await stat(fullPath);
|
|
8
|
+
await access(fullPath);
|
|
9
|
+
const head = {
|
|
10
|
+
...headers,
|
|
11
|
+
'Content-Length': size,
|
|
12
|
+
'Content-Type': getMimeForFile(fullPath),
|
|
13
|
+
};
|
|
14
|
+
Object.entries(head).forEach(([key, value]) => res.setHeader(key, value));
|
|
15
|
+
await new Promise((resolve, reject) => createReadStream(fullPath, { autoClose: true }).once('finish', resolve).once('error', reject).pipe(res));
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Builds a {@link ServerApi} that serves files under `options.path` for every
|
|
19
|
+
* GET request whose URL matches `options.baseUrl`. Falls back to
|
|
20
|
+
* `options.fallback` (if set) for missing files, otherwise responds with 404.
|
|
21
|
+
*/
|
|
22
|
+
export const buildStaticSiteServerApi = (options) => {
|
|
23
|
+
const onRequest = async ({ req, res }) => {
|
|
24
|
+
const extractedPath = PathHelper.extractPath(req.url, options.baseUrl);
|
|
25
|
+
const filePath = (extractedPath || '/').replaceAll('/', sep);
|
|
26
|
+
const fullPath = normalize(join(options.path, filePath));
|
|
27
|
+
try {
|
|
28
|
+
await sendFile({ fullPath, res, headers: options.headers });
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
if (options.fallback) {
|
|
32
|
+
await sendFile({ fullPath: normalize(join(options.path, options.fallback)), res, headers: options.headers });
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
res.writeHead(404, { 'Content-Type': 'text/plain' });
|
|
36
|
+
res.end('Not found');
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
return {
|
|
40
|
+
shouldExec: ({ req }) => req.url !== undefined &&
|
|
41
|
+
req.method?.toUpperCase() === 'GET' &&
|
|
42
|
+
PathHelper.matchesBaseUrl(req.url, options.baseUrl)
|
|
43
|
+
? true
|
|
44
|
+
: false,
|
|
45
|
+
onRequest,
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=static-site-runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site-runtime.js","sourceRoot":"","sources":["../src/static-site-runtime.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site-runtime.spec.d.ts","sourceRoot":"","sources":["../src/static-site-runtime.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
import { buildStaticSiteServerApi } from './static-site-runtime.js';
|
|
3
|
+
const makeRequest = (url, method = 'GET') => ({ url, method, headers: {} });
|
|
4
|
+
// Full onRequest / sendFile behaviour (streaming, fallback, 404) is covered
|
|
5
|
+
// end-to-end via `static-server-manager.spec.ts` which drives the real HTTP
|
|
6
|
+
// pool. These tests cover the pure-function `shouldExec` gate which is
|
|
7
|
+
// exercised by the server pool before any request is handed to the API.
|
|
8
|
+
describe('buildStaticSiteServerApi / shouldExec', () => {
|
|
9
|
+
const api = buildStaticSiteServerApi({ baseUrl: '/static', path: '/tmp', port: 0 });
|
|
10
|
+
it('matches GET requests under the baseUrl', () => {
|
|
11
|
+
expect(api.shouldExec({ req: makeRequest('/static/index.html'), res: {} })).toBe(true);
|
|
12
|
+
});
|
|
13
|
+
it('is case-insensitive about the method (GET only)', () => {
|
|
14
|
+
expect(api.shouldExec({ req: makeRequest('/static/a.html', 'get'), res: {} })).toBe(true);
|
|
15
|
+
});
|
|
16
|
+
it('rejects non-GET methods', () => {
|
|
17
|
+
expect(api.shouldExec({ req: makeRequest('/static/index.html', 'POST'), res: {} })).toBe(false);
|
|
18
|
+
expect(api.shouldExec({ req: makeRequest('/static/index.html', 'DELETE'), res: {} })).toBe(false);
|
|
19
|
+
});
|
|
20
|
+
it('rejects URLs that do not match the baseUrl', () => {
|
|
21
|
+
expect(api.shouldExec({ req: makeRequest('/other/index.html'), res: {} })).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it('rejects requests without a URL', () => {
|
|
24
|
+
expect(api.shouldExec({ req: makeRequest(undefined), res: {} })).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
it('never exposes an onUpgrade hook (static sites do not handle upgrades)', () => {
|
|
27
|
+
expect(api.onUpgrade).toBeUndefined();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
//# sourceMappingURL=static-site-runtime.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-site-runtime.spec.js","sourceRoot":"","sources":["../src/static-site-runtime.spec.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,MAAM,WAAW,GAAG,CAAC,GAAuB,EAAE,SAA6B,KAAK,EAAmB,EAAE,CACnG,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,CAA+B,CAAA;AAE9D,4EAA4E;AAC5E,4EAA4E;AAC5E,uEAAuE;AACvE,wEAAwE;AACxE,QAAQ,CAAC,uCAAuC,EAAE,GAAG,EAAE;IACrD,MAAM,GAAG,GAAG,wBAAwB,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;IAEnF,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE,EAAoB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1G,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,gBAAgB,EAAE,KAAK,CAAC,EAAE,GAAG,EAAE,EAAoB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC7G,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,oBAAoB,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,EAAoB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjH,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,oBAAoB,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAoB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACrH,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,mBAAmB,CAAC,EAAE,GAAG,EAAE,EAAoB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1G,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;QACxC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,EAAoB,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAChG,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,CAAA;IACvC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type StoreToken, User } from '@furystack/core';
|
|
2
|
+
import { type DataSetToken } from '@furystack/repository';
|
|
3
|
+
import { DefaultSession } from './models/default-session.js';
|
|
4
|
+
/**
|
|
5
|
+
* Error thrown by the default factories of {@link UserStore} and
|
|
6
|
+
* {@link SessionStore} when they are resolved without a caller-provided
|
|
7
|
+
* override. Users and sessions must outlive a process restart, so the
|
|
8
|
+
* rest-service refuses to silently fall back to an in-memory store.
|
|
9
|
+
*/
|
|
10
|
+
export declare class HttpAuthenticationStoreNotConfiguredError extends Error {
|
|
11
|
+
constructor(storeName: string);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Store token for persisted {@link User} records. Applications must bind
|
|
15
|
+
* this token to a persistent implementation before resolving
|
|
16
|
+
* {@link HttpUserContext} (or any service that derives from it).
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* injector.bind(UserStore, () => myPersistentUserStore)
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export declare const UserStore: StoreToken<User, 'username'>;
|
|
24
|
+
/**
|
|
25
|
+
* Store token for persisted {@link DefaultSession} records. Shares the
|
|
26
|
+
* throw-by-default contract with {@link UserStore}.
|
|
27
|
+
*/
|
|
28
|
+
export declare const SessionStore: StoreToken<DefaultSession, 'sessionId'>;
|
|
29
|
+
/**
|
|
30
|
+
* Data set token over {@link UserStore}. Consumers of the authentication
|
|
31
|
+
* subsystem (cookie login, JWT authentication plugins, `HttpUserContext`)
|
|
32
|
+
* route all user I/O through this dataset.
|
|
33
|
+
*/
|
|
34
|
+
export declare const UserDataSet: DataSetToken<User, 'username'>;
|
|
35
|
+
/**
|
|
36
|
+
* Data set token over {@link SessionStore}.
|
|
37
|
+
*/
|
|
38
|
+
export declare const SessionDataSet: DataSetToken<DefaultSession, 'sessionId'>;
|
|
39
|
+
//# sourceMappingURL=user-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-store.d.ts","sourceRoot":"","sources":["../src/user-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,UAAU,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D;;;;;GAKG;AACH,qBAAa,yCAA0C,SAAQ,KAAK;gBACtD,SAAS,EAAE,MAAM;CAM9B;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,EAAE,UAAU,CAAC,IAAI,EAAE,UAAU,CAOjD,CAAA;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,UAAU,CAAC,cAAc,EAAE,WAAW,CAO/D,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,YAAY,CAAC,IAAI,EAAE,UAAU,CAGrD,CAAA;AAEF;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,YAAY,CAAC,cAAc,EAAE,WAAW,CAGnE,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { defineStore, User } from '@furystack/core';
|
|
2
|
+
import { defineDataSet } from '@furystack/repository';
|
|
3
|
+
import { DefaultSession } from './models/default-session.js';
|
|
4
|
+
/**
|
|
5
|
+
* Error thrown by the default factories of {@link UserStore} and
|
|
6
|
+
* {@link SessionStore} when they are resolved without a caller-provided
|
|
7
|
+
* override. Users and sessions must outlive a process restart, so the
|
|
8
|
+
* rest-service refuses to silently fall back to an in-memory store.
|
|
9
|
+
*/
|
|
10
|
+
export class HttpAuthenticationStoreNotConfiguredError extends Error {
|
|
11
|
+
constructor(storeName) {
|
|
12
|
+
super(`HTTP authentication store '${storeName}' has not been configured. Bind a persistent PhysicalStore before resolving the HttpUserContext.`);
|
|
13
|
+
this.name = 'HttpAuthenticationStoreNotConfiguredError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Store token for persisted {@link User} records. Applications must bind
|
|
18
|
+
* this token to a persistent implementation before resolving
|
|
19
|
+
* {@link HttpUserContext} (or any service that derives from it).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* injector.bind(UserStore, () => myPersistentUserStore)
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
export const UserStore = defineStore({
|
|
27
|
+
name: 'furystack/rest-service/UserStore',
|
|
28
|
+
model: User,
|
|
29
|
+
primaryKey: 'username',
|
|
30
|
+
factory: () => {
|
|
31
|
+
throw new HttpAuthenticationStoreNotConfiguredError('UserStore');
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* Store token for persisted {@link DefaultSession} records. Shares the
|
|
36
|
+
* throw-by-default contract with {@link UserStore}.
|
|
37
|
+
*/
|
|
38
|
+
export const SessionStore = defineStore({
|
|
39
|
+
name: 'furystack/rest-service/SessionStore',
|
|
40
|
+
model: DefaultSession,
|
|
41
|
+
primaryKey: 'sessionId',
|
|
42
|
+
factory: () => {
|
|
43
|
+
throw new HttpAuthenticationStoreNotConfiguredError('SessionStore');
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
/**
|
|
47
|
+
* Data set token over {@link UserStore}. Consumers of the authentication
|
|
48
|
+
* subsystem (cookie login, JWT authentication plugins, `HttpUserContext`)
|
|
49
|
+
* route all user I/O through this dataset.
|
|
50
|
+
*/
|
|
51
|
+
export const UserDataSet = defineDataSet({
|
|
52
|
+
name: 'furystack/rest-service/UserDataSet',
|
|
53
|
+
store: UserStore,
|
|
54
|
+
});
|
|
55
|
+
/**
|
|
56
|
+
* Data set token over {@link SessionStore}.
|
|
57
|
+
*/
|
|
58
|
+
export const SessionDataSet = defineDataSet({
|
|
59
|
+
name: 'furystack/rest-service/SessionDataSet',
|
|
60
|
+
store: SessionStore,
|
|
61
|
+
});
|
|
62
|
+
//# sourceMappingURL=user-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-store.js","sourceRoot":"","sources":["../src/user-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAmB,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACpE,OAAO,EAAE,aAAa,EAAqB,MAAM,uBAAuB,CAAA;AACxE,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAA;AAE5D;;;;;GAKG;AACH,MAAM,OAAO,yCAA0C,SAAQ,KAAK;IAClE,YAAY,SAAiB;QAC3B,KAAK,CACH,8BAA8B,SAAS,kGAAkG,CAC1I,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,2CAA2C,CAAA;IACzD,CAAC;CACF;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAiC,WAAW,CAAC;IACjE,IAAI,EAAE,kCAAkC;IACxC,KAAK,EAAE,IAAI;IACX,UAAU,EAAE,UAAU;IACtB,OAAO,EAAE,GAAG,EAAE;QACZ,MAAM,IAAI,yCAAyC,CAAC,WAAW,CAAC,CAAA;IAClE,CAAC;CACF,CAAC,CAAA;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAA4C,WAAW,CAAC;IAC/E,IAAI,EAAE,qCAAqC;IAC3C,KAAK,EAAE,cAAc;IACrB,UAAU,EAAE,WAAW;IACvB,OAAO,EAAE,GAAG,EAAE;QACZ,MAAM,IAAI,yCAAyC,CAAC,cAAc,CAAC,CAAA;IACrE,CAAC;CACF,CAAC,CAAA;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAmC,aAAa,CAAC;IACvE,IAAI,EAAE,oCAAoC;IAC1C,KAAK,EAAE,SAAS;CACjB,CAAC,CAAA;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAA8C,aAAa,CAAC;IACrF,IAAI,EAAE,uCAAuC;IAC7C,KAAK,EAAE,YAAY;CACpB,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-store.spec.d.ts","sourceRoot":"","sources":["../src/user-store.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { InMemoryStore, User } from '@furystack/core';
|
|
2
|
+
import { createInjector } from '@furystack/inject';
|
|
3
|
+
import { usingAsync } from '@furystack/utils';
|
|
4
|
+
import { describe, expect, it } from 'vitest';
|
|
5
|
+
import { DefaultSession } from './models/default-session.js';
|
|
6
|
+
import { HttpAuthenticationStoreNotConfiguredError, SessionDataSet, SessionStore, UserDataSet, UserStore, } from './user-store.js';
|
|
7
|
+
describe('UserStore', () => {
|
|
8
|
+
it('exposes the User model and username primary key on the token', () => {
|
|
9
|
+
expect(UserStore.model).toBe(User);
|
|
10
|
+
expect(UserStore.primaryKey).toBe('username');
|
|
11
|
+
expect(UserStore.lifetime).toBe('singleton');
|
|
12
|
+
});
|
|
13
|
+
it('throws HttpAuthenticationStoreNotConfiguredError when resolved without an override', async () => {
|
|
14
|
+
await usingAsync(createInjector(), async (injector) => {
|
|
15
|
+
expect(() => injector.get(UserStore)).toThrow(HttpAuthenticationStoreNotConfiguredError);
|
|
16
|
+
expect(() => injector.get(UserStore)).toThrow(/UserStore.*not been configured/);
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
it('returns the bound implementation after rebinding the token', async () => {
|
|
20
|
+
await usingAsync(createInjector(), async (injector) => {
|
|
21
|
+
const impl = new InMemoryStore({ model: User, primaryKey: 'username' });
|
|
22
|
+
injector.bind(UserStore, () => impl);
|
|
23
|
+
expect(injector.get(UserStore)).toBe(impl);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe('SessionStore', () => {
|
|
28
|
+
it('exposes the DefaultSession model and sessionId primary key on the token', () => {
|
|
29
|
+
expect(SessionStore.model).toBe(DefaultSession);
|
|
30
|
+
expect(SessionStore.primaryKey).toBe('sessionId');
|
|
31
|
+
expect(SessionStore.lifetime).toBe('singleton');
|
|
32
|
+
});
|
|
33
|
+
it('throws HttpAuthenticationStoreNotConfiguredError when resolved without an override', async () => {
|
|
34
|
+
await usingAsync(createInjector(), async (injector) => {
|
|
35
|
+
expect(() => injector.get(SessionStore)).toThrow(HttpAuthenticationStoreNotConfiguredError);
|
|
36
|
+
expect(() => injector.get(SessionStore)).toThrow(/SessionStore.*not been configured/);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
it('returns the bound implementation after rebinding the token', async () => {
|
|
40
|
+
await usingAsync(createInjector(), async (injector) => {
|
|
41
|
+
const impl = new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' });
|
|
42
|
+
injector.bind(SessionStore, () => impl);
|
|
43
|
+
expect(injector.get(SessionStore)).toBe(impl);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
describe('UserDataSet / SessionDataSet', () => {
|
|
48
|
+
it('mirror the backing store metadata onto the data-set token', () => {
|
|
49
|
+
expect(UserDataSet.model).toBe(User);
|
|
50
|
+
expect(UserDataSet.primaryKey).toBe('username');
|
|
51
|
+
expect(SessionDataSet.model).toBe(DefaultSession);
|
|
52
|
+
expect(SessionDataSet.primaryKey).toBe('sessionId');
|
|
53
|
+
});
|
|
54
|
+
it('resolves through the bound store implementation', async () => {
|
|
55
|
+
await usingAsync(createInjector(), async (injector) => {
|
|
56
|
+
injector.bind(UserStore, () => new InMemoryStore({ model: User, primaryKey: 'username' }));
|
|
57
|
+
const dataSet = injector.get(UserDataSet);
|
|
58
|
+
await dataSet.add(injector, { username: 'alice', roles: [] });
|
|
59
|
+
const result = await dataSet.get(injector, 'alice');
|
|
60
|
+
expect(result?.username).toBe('alice');
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe('HttpAuthenticationStoreNotConfiguredError', () => {
|
|
65
|
+
it('embeds the store name in the message and sets the error name', () => {
|
|
66
|
+
const error = new HttpAuthenticationStoreNotConfiguredError('SomeStore');
|
|
67
|
+
expect(error.name).toBe('HttpAuthenticationStoreNotConfiguredError');
|
|
68
|
+
expect(error.message).toContain("'SomeStore'");
|
|
69
|
+
expect(error).toBeInstanceOf(Error);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
//# sourceMappingURL=user-store.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-store.spec.js","sourceRoot":"","sources":["../src/user-store.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
2
|
-
import {
|
|
2
|
+
import { InMemoryStore, User as UserModel } from '@furystack/core';
|
|
3
3
|
import { getPort } from '@furystack/core/port-generator';
|
|
4
|
-
import {
|
|
5
|
-
import { getRepository } from '@furystack/repository';
|
|
4
|
+
import { createInjector } from '@furystack/inject';
|
|
6
5
|
import { createClient, ResponseError } from '@furystack/rest-client-fetch';
|
|
6
|
+
import { PasswordCredential, PasswordCredentialStore, PasswordResetToken, PasswordResetTokenStore, usePasswordPolicy, } from '@furystack/security';
|
|
7
7
|
import { usingAsync } from '@furystack/utils';
|
|
8
8
|
import { describe, expect, it } from 'vitest';
|
|
9
9
|
import { createDeleteEndpoint } from './endpoint-generators/create-delete-endpoint.js';
|
|
@@ -11,10 +11,11 @@ import { createGetCollectionEndpoint } from './endpoint-generators/create-get-co
|
|
|
11
11
|
import { createGetEntityEndpoint } from './endpoint-generators/create-get-entity-endpoint.js';
|
|
12
12
|
import { createPatchEndpoint } from './endpoint-generators/create-patch-endpoint.js';
|
|
13
13
|
import { createPostEndpoint } from './endpoint-generators/create-post-endpoint.js';
|
|
14
|
-
import {
|
|
14
|
+
import { MockDataSet, setupContext } from './endpoint-generators/utils.js';
|
|
15
15
|
import { useHttpAuthentication, useRestService } from './helpers.js';
|
|
16
16
|
import { DefaultSession } from './models/default-session.js';
|
|
17
17
|
import { JsonResult } from './request-action-implementation.js';
|
|
18
|
+
import { SessionStore, UserStore } from './user-store.js';
|
|
18
19
|
import schema from './validate.integration.spec.schema.json' with { type: 'json' };
|
|
19
20
|
import { Validate } from './validate.js';
|
|
20
21
|
// To recreate: yarn ts-json-schema-generator -f tsconfig.json --no-type-check -p packages/rest-service/src/validate.integration.schema.ts -o packages/rest-service/src/validate.integration.spec.schema.json
|
|
@@ -22,14 +23,11 @@ const name = crypto.randomUUID();
|
|
|
22
23
|
const description = crypto.randomUUID();
|
|
23
24
|
const version = crypto.randomUUID();
|
|
24
25
|
const createValidateApi = async (options = { enableGetSchema: false }) => {
|
|
25
|
-
const injector =
|
|
26
|
+
const injector = createInjector();
|
|
26
27
|
const port = getPort();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
getRepository(injector).createDataSet(MockClass, 'id');
|
|
31
|
-
getRepository(injector).createDataSet(User, 'username');
|
|
32
|
-
getRepository(injector).createDataSet(DefaultSession, 'sessionId');
|
|
28
|
+
injector.bind(UserStore, () => new InMemoryStore({ model: UserModel, primaryKey: 'username' }));
|
|
29
|
+
injector.bind(SessionStore, () => new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }));
|
|
30
|
+
setupContext(injector);
|
|
33
31
|
const api = await useRestService({
|
|
34
32
|
injector,
|
|
35
33
|
enableGetSchema: options.enableGetSchema,
|
|
@@ -53,11 +51,11 @@ const createValidateApi = async (options = { enableGetSchema: false }) => {
|
|
|
53
51
|
'/mock': Validate({
|
|
54
52
|
schema,
|
|
55
53
|
schemaName: 'GetMockCollectionEndpoint',
|
|
56
|
-
})(createGetCollectionEndpoint(
|
|
54
|
+
})(createGetCollectionEndpoint(MockDataSet)),
|
|
57
55
|
'/mock/:id': Validate({
|
|
58
56
|
schema,
|
|
59
57
|
schemaName: 'GetMockEntityEndpoint',
|
|
60
|
-
})(createGetEntityEndpoint(
|
|
58
|
+
})(createGetEntityEndpoint(MockDataSet)),
|
|
61
59
|
},
|
|
62
60
|
POST: {
|
|
63
61
|
'/validate-body': Validate({
|
|
@@ -70,19 +68,19 @@ const createValidateApi = async (options = { enableGetSchema: false }) => {
|
|
|
70
68
|
'/mock': Validate({
|
|
71
69
|
schema,
|
|
72
70
|
schemaName: 'PostMockEndpoint',
|
|
73
|
-
})(createPostEndpoint(
|
|
71
|
+
})(createPostEndpoint(MockDataSet)),
|
|
74
72
|
},
|
|
75
73
|
PATCH: {
|
|
76
74
|
'/mock/:id': Validate({
|
|
77
75
|
schema,
|
|
78
76
|
schemaName: 'PatchMockEndpoint',
|
|
79
|
-
})(createPatchEndpoint(
|
|
77
|
+
})(createPatchEndpoint(MockDataSet)),
|
|
80
78
|
},
|
|
81
79
|
DELETE: {
|
|
82
80
|
'/mock/:id': Validate({
|
|
83
81
|
schema,
|
|
84
82
|
schemaName: 'DeleteMockEndpoint',
|
|
85
|
-
})(createDeleteEndpoint(
|
|
83
|
+
})(createDeleteEndpoint(MockDataSet)),
|
|
86
84
|
},
|
|
87
85
|
},
|
|
88
86
|
port,
|
|
@@ -161,46 +159,6 @@ describe('Validation integration tests', () => {
|
|
|
161
159
|
});
|
|
162
160
|
});
|
|
163
161
|
});
|
|
164
|
-
describe('swagger.json backward compatibility', () => {
|
|
165
|
-
it('Should serve the same OpenAPI document at /swagger.json when enabled', async () => {
|
|
166
|
-
await usingAsync(await createValidateApi({ enableGetSchema: true }), async ({ client }) => {
|
|
167
|
-
const result = await client({
|
|
168
|
-
method: 'GET',
|
|
169
|
-
action: '/swagger.json',
|
|
170
|
-
});
|
|
171
|
-
expect(result.response.status).toBe(200);
|
|
172
|
-
expect(result.result).toBeDefined();
|
|
173
|
-
const openApiDoc = result.result;
|
|
174
|
-
expect(openApiDoc.openapi).toBe('3.1.0');
|
|
175
|
-
expect(openApiDoc.info?.title).toBe(name);
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
it('Should include Deprecation header on /swagger.json', async () => {
|
|
179
|
-
await usingAsync(await createValidateApi({ enableGetSchema: true }), async ({ client }) => {
|
|
180
|
-
const result = await client({
|
|
181
|
-
method: 'GET',
|
|
182
|
-
action: '/swagger.json',
|
|
183
|
-
});
|
|
184
|
-
expect(result.response.headers.get('deprecation')).toBe('true');
|
|
185
|
-
expect(result.response.headers.get('link')).toContain('/openapi.json');
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
it('Should return a 404 for /swagger.json when not enabled', async () => {
|
|
189
|
-
await usingAsync(await createValidateApi({ enableGetSchema: false }), async ({ client }) => {
|
|
190
|
-
try {
|
|
191
|
-
await client({
|
|
192
|
-
method: 'GET',
|
|
193
|
-
action: '/swagger.json',
|
|
194
|
-
});
|
|
195
|
-
expect.fail('Expected response error but got success');
|
|
196
|
-
}
|
|
197
|
-
catch (error) {
|
|
198
|
-
expect(error).toBeInstanceOf(ResponseError);
|
|
199
|
-
expect(error.response.status).toBe(404);
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
162
|
describe('Validation metadata', () => {
|
|
205
163
|
it('Should return 404 when not enabled', async () => {
|
|
206
164
|
expect.assertions(2);
|
|
@@ -456,14 +414,14 @@ describe('Validation integration tests', () => {
|
|
|
456
414
|
});
|
|
457
415
|
describe('OpenAPI security schemes from authentication providers', () => {
|
|
458
416
|
const createApiWithAuth = async () => {
|
|
459
|
-
const injector =
|
|
417
|
+
const injector = createInjector();
|
|
460
418
|
const port = getPort();
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
419
|
+
injector.bind(UserStore, () => new InMemoryStore({ model: UserModel, primaryKey: 'username' }));
|
|
420
|
+
injector.bind(SessionStore, () => new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }));
|
|
421
|
+
injector.bind(PasswordCredentialStore, () => new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }));
|
|
422
|
+
injector.bind(PasswordResetTokenStore, () => new InMemoryStore({ model: PasswordResetToken, primaryKey: 'token' }));
|
|
423
|
+
setupContext(injector);
|
|
424
|
+
usePasswordPolicy(injector);
|
|
467
425
|
useHttpAuthentication(injector);
|
|
468
426
|
await useRestService({
|
|
469
427
|
injector,
|
|
@@ -476,21 +434,21 @@ describe('Validation integration tests', () => {
|
|
|
476
434
|
'/validate-query': Validate({ schema, schemaName: 'ValidateQuery' })(async ({ getQuery }) => JsonResult({ ...getQuery() })),
|
|
477
435
|
'/validate-url/:id': Validate({ schema, schemaName: 'ValidateUrl' })(async ({ getUrlParams }) => JsonResult({ ...getUrlParams() })),
|
|
478
436
|
'/validate-headers': Validate({ schema, schemaName: 'ValidateHeaders' })(async ({ headers }) => JsonResult({ ...headers })),
|
|
479
|
-
'/mock': Validate({ schema, schemaName: 'GetMockCollectionEndpoint' })(createGetCollectionEndpoint(
|
|
480
|
-
'/mock/:id': Validate({ schema, schemaName: 'GetMockEntityEndpoint' })(createGetEntityEndpoint(
|
|
437
|
+
'/mock': Validate({ schema, schemaName: 'GetMockCollectionEndpoint' })(createGetCollectionEndpoint(MockDataSet)),
|
|
438
|
+
'/mock/:id': Validate({ schema, schemaName: 'GetMockEntityEndpoint' })(createGetEntityEndpoint(MockDataSet)),
|
|
481
439
|
},
|
|
482
440
|
POST: {
|
|
483
441
|
'/validate-body': Validate({ schema, schemaName: 'ValidateBody' })(async ({ getBody }) => {
|
|
484
442
|
const body = await getBody();
|
|
485
443
|
return JsonResult({ ...body });
|
|
486
444
|
}),
|
|
487
|
-
'/mock': Validate({ schema, schemaName: 'PostMockEndpoint' })(createPostEndpoint(
|
|
445
|
+
'/mock': Validate({ schema, schemaName: 'PostMockEndpoint' })(createPostEndpoint(MockDataSet)),
|
|
488
446
|
},
|
|
489
447
|
PATCH: {
|
|
490
|
-
'/mock/:id': Validate({ schema, schemaName: 'PatchMockEndpoint' })(createPatchEndpoint(
|
|
448
|
+
'/mock/:id': Validate({ schema, schemaName: 'PatchMockEndpoint' })(createPatchEndpoint(MockDataSet)),
|
|
491
449
|
},
|
|
492
450
|
DELETE: {
|
|
493
|
-
'/mock/:id': Validate({ schema, schemaName: 'DeleteMockEndpoint' })(createDeleteEndpoint(
|
|
451
|
+
'/mock/:id': Validate({ schema, schemaName: 'DeleteMockEndpoint' })(createDeleteEndpoint(MockDataSet)),
|
|
494
452
|
},
|
|
495
453
|
},
|
|
496
454
|
port,
|
|
@@ -519,21 +477,6 @@ describe('Validation integration tests', () => {
|
|
|
519
477
|
});
|
|
520
478
|
});
|
|
521
479
|
});
|
|
522
|
-
it('Should include detected security schemes in the deprecated /swagger.json endpoint', async () => {
|
|
523
|
-
await usingAsync(await createApiWithAuth(), async ({ client }) => {
|
|
524
|
-
const result = await client({
|
|
525
|
-
method: 'GET',
|
|
526
|
-
action: '/swagger.json',
|
|
527
|
-
});
|
|
528
|
-
const openApiDoc = result.result;
|
|
529
|
-
expect(openApiDoc.components?.securitySchemes?.basicAuth).toEqual({ type: 'http', scheme: 'basic' });
|
|
530
|
-
expect(openApiDoc.components?.securitySchemes?.cookieAuth).toEqual({
|
|
531
|
-
type: 'apiKey',
|
|
532
|
-
in: 'cookie',
|
|
533
|
-
name: 'session',
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
});
|
|
537
480
|
});
|
|
538
481
|
});
|
|
539
482
|
//# sourceMappingURL=validate.integration.spec.js.map
|