@rebasepro/server 0.22.0 → 0.24.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 +1 -1
- package/bin/rebase-server.js +4 -2
- package/dist/{GCSStorageController-CLIJXwGS.js → GCSStorageController-BSiP1c-f.js} +57 -29
- package/dist/GCSStorageController-BSiP1c-f.js.map +1 -0
- package/dist/{S3StorageController-Dcuf8lMA.js → S3StorageController-CAwFRgjV.js} +19 -7
- package/dist/S3StorageController-CAwFRgjV.js.map +1 -0
- package/dist/api/ast-schema-editor.d.ts +127 -1
- package/dist/api/errors.d.ts +9 -0
- package/dist/api/live-schema-routes.d.ts +52 -8
- package/dist/api/logs-routes.d.ts +39 -1
- package/dist/api/openapi-generator.d.ts +17 -0
- package/dist/api/rest/api-generator.d.ts +158 -42
- package/dist/api/rest/auth-collection-writes.d.ts +85 -0
- package/dist/api/rest/field-access-query.d.ts +6 -2
- package/dist/api/rest/idempotency.d.ts +7 -1
- package/dist/api/rest/nested-write-access.d.ts +46 -0
- package/dist/api/rest/write-validation.d.ts +34 -2
- package/dist/api/types.d.ts +17 -1
- package/dist/{ast-schema-editor-CslO8Oje.js → ast-schema-editor-CWqS_sLJ.js} +411 -13
- package/dist/ast-schema-editor-CWqS_sLJ.js.map +1 -0
- package/dist/auth/access.d.ts +105 -0
- package/dist/auth/adapter-middleware.d.ts +2 -1
- package/dist/auth/address-ownership.d.ts +68 -0
- package/dist/auth/admin-roles-route.d.ts +4 -2
- package/dist/auth/admin-roles.d.ts +17 -20
- package/dist/auth/admin-user-ops.d.ts +35 -2
- package/dist/auth/admin-users-route.d.ts +1 -0
- package/dist/auth/api-keys/api-key-middleware.d.ts +56 -55
- package/dist/auth/api-keys/api-key-routes.d.ts +41 -11
- package/dist/auth/api-keys/api-key-store.d.ts +31 -8
- package/dist/auth/api-keys/api-key-types.d.ts +14 -16
- package/dist/auth/api-keys/http-operation.d.ts +19 -0
- package/dist/auth/api-keys/index.d.ts +11 -11
- package/dist/auth/api-keys/key-grant.d.ts +41 -0
- package/dist/auth/api-keys/legacy-permissions.d.ts +33 -0
- package/dist/auth/auth-hooks.d.ts +50 -7
- package/dist/auth/builtin-auth-adapter.d.ts +8 -0
- package/dist/auth/captcha.d.ts +5 -0
- package/dist/auth/cookie-utils.d.ts +7 -0
- package/dist/auth/deliverable-address.d.ts +6 -0
- package/dist/auth/email-change-routes.d.ts +41 -0
- package/dist/auth/expired-token-sweep.d.ts +67 -0
- package/dist/auth/impersonation.d.ts +110 -0
- package/dist/auth/index.d.ts +4 -2
- package/dist/auth/interfaces.d.ts +146 -65
- package/dist/auth/jwt.d.ts +66 -3
- package/dist/auth/magic-link-routes.d.ts +2 -6
- package/dist/auth/mfa-routes.d.ts +2 -9
- package/dist/auth/middleware.d.ts +17 -5
- package/dist/auth/oauth-signin-policy.d.ts +25 -8
- package/dist/auth/otp-routes.d.ts +2 -6
- package/dist/auth/passwordless-signup.d.ts +27 -0
- package/dist/auth/platform-token.d.ts +122 -0
- package/dist/auth/rate-limiter.d.ts +72 -1
- package/dist/auth/routes.d.ts +45 -0
- package/dist/auth/scope-routes.d.ts +22 -0
- package/dist/auth/session-routes.d.ts +18 -6
- package/dist/auth/token-revocation.d.ts +53 -1
- package/dist/auth/verify-credential.d.ts +28 -0
- package/dist/{auth-CCDpk2rn.js → auth-DMLngxn_.js} +2712 -711
- package/dist/auth-DMLngxn_.js.map +1 -0
- package/dist/backend-DTAOsLQc.js +30 -0
- package/dist/backend-DTAOsLQc.js.map +1 -0
- package/dist/backup/backup-common.d.ts +29 -0
- package/dist/backup/backup-routes.d.ts +24 -4
- package/dist/backup/backup-schedule.d.ts +33 -0
- package/dist/backup/backup-storage.d.ts +14 -0
- package/dist/backup/index.d.ts +2 -0
- package/dist/backup-CN0s50D2.js +444 -0
- package/dist/backup-CN0s50D2.js.map +1 -0
- package/dist/boot/bundle.d.ts +19 -0
- package/dist/boot/driver.d.ts +10 -0
- package/dist/boot/env.d.ts +51 -6
- package/dist/boot/fetch-bundle.d.ts +18 -1
- package/dist/boot/rls-audit-option.d.ts +26 -0
- package/dist/boot/security-headers.d.ts +26 -0
- package/dist/boot/sources.d.ts +1 -0
- package/dist/boot/static-routing.d.ts +56 -0
- package/dist/collection_patch-BRu-BvDv.js +472 -0
- package/dist/collection_patch-BRu-BvDv.js.map +1 -0
- package/dist/{contract-routes-eLxV0le1.js → contract-routes-fz8i4pxs.js} +17 -4
- package/dist/contract-routes-fz8i4pxs.js.map +1 -0
- package/dist/cron/cron-routes.d.ts +7 -2
- package/dist/cron/cron-scheduler.d.ts +146 -21
- package/dist/cron/cron-store.d.ts +76 -8
- package/dist/cron/index.d.ts +1 -1
- package/dist/{cron-loader-CQjvjpEw.js → cron-loader-CwaANlOG.js} +4 -4
- package/dist/cron-loader-CwaANlOG.js.map +1 -0
- package/dist/cron-routes-Bc-SB0Se.js +96 -0
- package/dist/cron-routes-Bc-SB0Se.js.map +1 -0
- package/dist/{cron-scheduler-COPQxlEq.js → cron-scheduler-CYQgco86.js} +427 -83
- package/dist/cron-scheduler-CYQgco86.js.map +1 -0
- package/dist/{cron-store-BYGZFNWk.js → cron-store-D2Q9-Aco.js} +139 -23
- package/dist/cron-store-D2Q9-Aco.js.map +1 -0
- package/dist/{ddl-bootstrap-CfNvxMuK.js → ddl-bootstrap-BaqMSa4Y.js} +3 -26
- package/dist/ddl-bootstrap-BaqMSa4Y.js.map +1 -0
- package/dist/email/index.d.ts +2 -2
- package/dist/email/link-base.d.ts +5 -4
- package/dist/email/smtp-email-service.d.ts +13 -1
- package/dist/email/templates.d.ts +31 -0
- package/dist/email/types.d.ts +29 -2
- package/dist/env.d.ts +25 -7
- package/dist/{errors-DWsX4yTd.js → errors-D6_y86c5.js} +102 -8
- package/dist/errors-D6_y86c5.js.map +1 -0
- package/dist/{function-loader-xnbDAPfa.js → function-loader-D7o5Epjj.js} +2 -2
- package/dist/{function-loader-xnbDAPfa.js.map → function-loader-D7o5Epjj.js.map} +1 -1
- package/dist/{function-routes-Chet4-lB.js → function-routes-CaNG4waN.js} +24 -12
- package/dist/function-routes-CaNG4waN.js.map +1 -0
- package/dist/functions/context.d.ts +17 -6
- package/dist/functions/guards.d.ts +22 -5
- package/dist/functions/index.d.ts +2 -2
- package/dist/functions/index.js +90 -36
- package/dist/functions/index.js.map +1 -1
- package/dist/{history-recorder-BQmB0P_j.js → history-recorder-Nr8zLvoU.js} +9 -7
- package/dist/history-recorder-Nr8zLvoU.js.map +1 -0
- package/dist/{history-store-CetkrBBD.js → history-store-rcAm_xFR.js} +2 -2
- package/dist/{history-store-CetkrBBD.js.map → history-store-rcAm_xFR.js.map} +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.es.js +5733 -1551
- package/dist/index.es.js.map +1 -1
- package/dist/init/docs.d.ts +5 -2
- package/dist/init/health.d.ts +17 -2
- package/dist/init/shutdown.d.ts +18 -3
- package/dist/init.d.ts +54 -0
- package/dist/jobs/index.d.ts +2 -2
- package/dist/jobs/job-queue.d.ts +23 -2
- package/dist/jobs/job-store.d.ts +37 -5
- package/dist/jobs/types.d.ts +8 -6
- package/dist/{jobs-Bjr8DZAi.js → jobs-DqYNfquG.js} +306 -167
- package/dist/jobs-DqYNfquG.js.map +1 -0
- package/dist/{jwt-C4OW-DNq.js → jwt-R6bSPMjk.js} +114 -38
- package/dist/{jwt-C4OW-DNq.js.map → jwt-R6bSPMjk.js.map} +1 -1
- package/dist/{keys-Qfc4XieN.js → keys-GAVZqbqx.js} +18 -17
- package/dist/{keys-Qfc4XieN.js.map → keys-GAVZqbqx.js.map} +1 -1
- package/dist/{logger-DO2PZc4i.js → logger-D-S-hO5e.js} +26 -3
- package/dist/logger-D-S-hO5e.js.map +1 -0
- package/dist/{logs-routes-3EEzPjhl.js → logs-routes-DAdv37GI.js} +54 -11
- package/dist/logs-routes-DAdv37GI.js.map +1 -0
- package/dist/mcp/consent-page.d.ts +1 -1
- package/dist/mcp/mcp-routes.d.ts +45 -2
- package/dist/mcp/mcp-tools.d.ts +22 -10
- package/dist/mcp/oauth-metadata.d.ts +21 -16
- package/dist/mcp/oauth-routes.d.ts +34 -1
- package/dist/mcp/oauth-store.d.ts +29 -13
- package/dist/metrics/history-recorder.d.ts +1 -1
- package/dist/{openapi-generator-D8uFz-LW.js → openapi-generator-DAq_XVDu.js} +135 -22
- package/dist/openapi-generator-DAq_XVDu.js.map +1 -0
- package/dist/{proxy-Czngl3p9.js → proxy-qRlqeUmO.js} +2 -2
- package/dist/{proxy-Czngl3p9.js.map → proxy-qRlqeUmO.js.map} +1 -1
- package/dist/{query-parser-BleZmY18.js → query-parser-BgiKJKvc.js} +41 -82
- package/dist/query-parser-BgiKJKvc.js.map +1 -0
- package/dist/{request-timeout-C_4C2BeR.js → request-timeout-DgH7j8qO.js} +3 -3
- package/dist/{request-timeout-C_4C2BeR.js.map → request-timeout-DgH7j8qO.js.map} +1 -1
- package/dist/rls-audit/index.d.ts +4 -0
- package/dist/schema-edit/apply-schema-change.d.ts +63 -3
- package/dist/schema-edit/project-root.d.ts +3 -2
- package/dist/schema-edit/remote-source.d.ts +9 -4
- package/dist/{schema-editor-routes-DdLihzp0.js → schema-editor-routes-oIyuWl3L.js} +12 -7
- package/dist/schema-editor-routes-oIyuWl3L.js.map +1 -0
- package/dist/serve-spa.d.ts +58 -0
- package/dist/services/routed-realtime-service.d.ts +11 -0
- package/dist/soft-delete-params-BWPilMPF.js +59 -0
- package/dist/soft-delete-params-BWPilMPF.js.map +1 -0
- package/dist/{src-Br6ARbs6.js → src-CatHFUym.js} +439 -45
- package/dist/src-CatHFUym.js.map +1 -0
- package/dist/{src-1vL-I1Po.js → src-I3aG1PcY.js} +371 -81
- package/dist/src-I3aG1PcY.js.map +1 -0
- package/dist/storage/GCSStorageController.d.ts +13 -1
- package/dist/storage/LocalStorageController.d.ts +2 -0
- package/dist/storage/S3StorageController.d.ts +2 -0
- package/dist/storage/index.d.ts +2 -2
- package/dist/storage/keys.d.ts +12 -0
- package/dist/storage/property-limits.d.ts +41 -6
- package/dist/storage/rendition-cache.d.ts +11 -1
- package/dist/storage/request-keys.d.ts +82 -0
- package/dist/storage/requested-object.d.ts +74 -0
- package/dist/storage/routes.d.ts +36 -18
- package/dist/storage/tus-handler.d.ts +30 -5
- package/dist/storage/types.d.ts +36 -1
- package/dist/types-BfKcm9do.js.map +1 -1
- package/dist/utils/logger.d.ts +12 -0
- package/package.json +9 -9
- package/dist/GCSStorageController-CLIJXwGS.js.map +0 -1
- package/dist/S3StorageController-Dcuf8lMA.js.map +0 -1
- package/dist/admin-roles-vYdp_Pil.js +0 -36
- package/dist/admin-roles-vYdp_Pil.js.map +0 -1
- package/dist/admin_block-DxKLmdiv.js +0 -206
- package/dist/admin_block-DxKLmdiv.js.map +0 -1
- package/dist/ast-schema-editor-CslO8Oje.js.map +0 -1
- package/dist/auth/api-keys/api-key-permission-guard.d.ts +0 -65
- package/dist/auth-CCDpk2rn.js.map +0 -1
- package/dist/backup-DzI9jLwc.js +0 -192
- package/dist/backup-DzI9jLwc.js.map +0 -1
- package/dist/contract-routes-eLxV0le1.js.map +0 -1
- package/dist/cron-loader-CQjvjpEw.js.map +0 -1
- package/dist/cron-routes-B7CRGfiq.js +0 -72
- package/dist/cron-routes-B7CRGfiq.js.map +0 -1
- package/dist/cron-scheduler-COPQxlEq.js.map +0 -1
- package/dist/cron-store-BYGZFNWk.js.map +0 -1
- package/dist/ddl-bootstrap-CfNvxMuK.js.map +0 -1
- package/dist/errors-DWsX4yTd.js.map +0 -1
- package/dist/function-routes-Chet4-lB.js.map +0 -1
- package/dist/history-recorder-BQmB0P_j.js.map +0 -1
- package/dist/jobs-Bjr8DZAi.js.map +0 -1
- package/dist/logger-DO2PZc4i.js.map +0 -1
- package/dist/logs-routes-3EEzPjhl.js.map +0 -1
- package/dist/openapi-generator-D8uFz-LW.js.map +0 -1
- package/dist/query-parser-BleZmY18.js.map +0 -1
- package/dist/schema-editor-routes-DdLihzp0.js.map +0 -1
- package/dist/src-1vL-I1Po.js.map +0 -1
- package/dist/src-Br6ARbs6.js.map +0 -1
package/dist/mcp/mcp-tools.d.ts
CHANGED
|
@@ -16,36 +16,48 @@
|
|
|
16
16
|
* - A write can fail with a permission error the tool cannot explain in
|
|
17
17
|
* detail, because the policy that refused it is not visible from here.
|
|
18
18
|
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
19
|
+
* The scopes gate which tools are *offered* and which collections each
|
|
20
|
+
* reaches — `data:write:posts` offers the write tools for `posts` alone. That
|
|
21
|
+
* is a second lock, not the main one: a `data:write` token still cannot write
|
|
22
|
+
* a row the user could not write themselves.
|
|
22
23
|
*/
|
|
23
|
-
import type { CollectionConfig, DataDriver } from "@rebasepro/types";
|
|
24
|
+
import type { AuthAdapter, CollectionConfig, DataDriver } from "@rebasepro/types";
|
|
25
|
+
import type { McpScope } from "./oauth-metadata.js";
|
|
24
26
|
/** The identity a tool call runs as. Comes from the verified access token. */
|
|
25
27
|
export interface McpCaller {
|
|
26
28
|
uid: string;
|
|
27
29
|
roles: string[];
|
|
28
|
-
|
|
30
|
+
/** The scopes granted to this connection — `data:read`, `data:write:posts`, … */
|
|
31
|
+
scopes: string[];
|
|
29
32
|
clientId: string;
|
|
30
33
|
}
|
|
31
34
|
export interface McpToolContext {
|
|
32
35
|
driver: DataDriver;
|
|
33
36
|
collections: CollectionConfig[];
|
|
34
37
|
caller: McpCaller;
|
|
38
|
+
/**
|
|
39
|
+
* The deployment's auth adapter. The auth collection's rows are the users,
|
|
40
|
+
* so the write tools hand a write to one to it, as REST and `/admin/users`
|
|
41
|
+
* do. See `api/rest/auth-collection-writes.ts`.
|
|
42
|
+
*/
|
|
43
|
+
authAdapter?: AuthAdapter;
|
|
35
44
|
}
|
|
36
45
|
export interface McpToolDefinition {
|
|
37
46
|
name: string;
|
|
38
47
|
description: string;
|
|
39
48
|
inputSchema: Record<string, unknown>;
|
|
40
|
-
/**
|
|
41
|
-
|
|
49
|
+
/**
|
|
50
|
+
* The scope a caller must hold — on at least one collection for the tool
|
|
51
|
+
* to be listed, and on the collection a call names for it to run.
|
|
52
|
+
*/
|
|
53
|
+
requiredScope: McpScope;
|
|
42
54
|
run(args: Record<string, unknown>, ctx: McpToolContext): Promise<unknown>;
|
|
43
55
|
}
|
|
44
56
|
/** An error whose message is safe to hand back to the model. */
|
|
45
57
|
export declare class McpToolError extends Error {
|
|
46
58
|
}
|
|
47
59
|
export declare const MCP_TOOLS: McpToolDefinition[];
|
|
48
|
-
/** The tools a caller holding `
|
|
49
|
-
export declare function
|
|
60
|
+
/** The tools a caller holding `scopes` may see and call: each needs its scope on at least one collection. */
|
|
61
|
+
export declare function toolsForScopes(scopes: readonly string[]): McpToolDefinition[];
|
|
50
62
|
/** Look up a tool by name, honouring scope — an unlisted tool is not callable. */
|
|
51
|
-
export declare function findTool(name: string,
|
|
63
|
+
export declare function findTool(name: string, scopes: readonly string[]): McpToolDefinition | undefined;
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* What a token may do at `/mcp
|
|
2
|
+
* What a token may do at `/mcp`: the data-plane scopes its tools need, in the
|
|
3
|
+
* vocabulary every other credential uses — `data:read`, `data:write`,
|
|
4
|
+
* `data:delete` — each narrowable to one collection (`data:read:posts`).
|
|
3
5
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* permissions is one nobody reads.
|
|
9
|
-
*
|
|
10
|
-
* They are not a substitute for RLS. A `mcp:read` token still reads through the
|
|
11
|
-
* user's own policies — the scope decides whether the tool exists for this
|
|
12
|
-
* session, the database decides which rows come back.
|
|
6
|
+
* They are not a substitute for RLS. A `data:read` token still reads through
|
|
7
|
+
* the user's own policies — the scope decides whether a tool exists for this
|
|
8
|
+
* session and which collections it reaches; the database decides which rows
|
|
9
|
+
* come back.
|
|
13
10
|
*/
|
|
14
|
-
export declare const MCP_SCOPES: readonly ["
|
|
11
|
+
export declare const MCP_SCOPES: readonly ["data:read", "data:write", "data:delete"];
|
|
15
12
|
export type McpScope = (typeof MCP_SCOPES)[number];
|
|
16
13
|
/** The scope a client gets when it asks for nothing in particular. */
|
|
17
|
-
export declare const DEFAULT_MCP_SCOPE = "
|
|
14
|
+
export declare const DEFAULT_MCP_SCOPE = "data:read";
|
|
15
|
+
/**
|
|
16
|
+
* A scope string as granted before `/mcp` spoke the shared vocabulary, read as
|
|
17
|
+
* what it granted: `mcp:read` was every read, `mcp:write` every create, change
|
|
18
|
+
* and delete. Applied to stored refresh grants and to access tokens still in
|
|
19
|
+
* flight, so a connection made before the change keeps exactly its reach.
|
|
20
|
+
*/
|
|
21
|
+
export declare function upgradeStoredMcpScope(scope: string): string;
|
|
18
22
|
/**
|
|
19
23
|
* The canonical resource identifier for this server's MCP endpoint.
|
|
20
24
|
*
|
|
@@ -93,12 +97,13 @@ export declare function redirectUriAllowed(candidate: string, registered: string
|
|
|
93
97
|
*
|
|
94
98
|
* An unknown scope is dropped rather than refused. RFC 6749 §3.3 allows either,
|
|
95
99
|
* and dropping is what keeps a client that asks for `openid profile email` out
|
|
96
|
-
* of habit from failing to connect at all — it gets the
|
|
97
|
-
* entitled to and none of the ones it invented.
|
|
100
|
+
* of habit from failing to connect at all — it gets the data scopes it is
|
|
101
|
+
* entitled to and none of the ones it invented. A collection target is kept:
|
|
102
|
+
* `data:read:posts` is a narrower grant, never a wider one.
|
|
98
103
|
*/
|
|
99
104
|
export declare function narrowScope(requested: string | undefined | null): string;
|
|
100
|
-
/**
|
|
101
|
-
export declare function
|
|
105
|
+
/** A granted scope string as the list of scopes it holds. */
|
|
106
|
+
export declare function scopeList(scope: string): string[];
|
|
102
107
|
/**
|
|
103
108
|
* The `WWW-Authenticate` value for an unauthenticated request.
|
|
104
109
|
*
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { Hono } from "hono";
|
|
27
27
|
import type { HonoEnv } from "../api/types.js";
|
|
28
|
+
import type { AuthRepository } from "../auth/interfaces.js";
|
|
28
29
|
import type { OAuthStore } from "./oauth-store.js";
|
|
29
30
|
export interface OAuthRoutesConfig {
|
|
30
31
|
store: OAuthStore;
|
|
@@ -36,7 +37,33 @@ export interface OAuthRoutesConfig {
|
|
|
36
37
|
authBasePath: string;
|
|
37
38
|
/** Whether open registration is permitted. */
|
|
38
39
|
allowDynamicRegistration: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Who a grant's user is now. Absent when the auth adapter exposes no user
|
|
42
|
+
* repository, and then a grant carries the roles it was consented with.
|
|
43
|
+
*/
|
|
44
|
+
identity?: McpGrantIdentity;
|
|
39
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* The account a grant acts for, read where a grant is issued or renewed.
|
|
48
|
+
*
|
|
49
|
+
* A refresh has no session to re-read anything from, so without this a grant
|
|
50
|
+
* is a snapshot of the moment of consent: the roles it was given, for an
|
|
51
|
+
* account that may since have been demoted, signed out everywhere, or deleted.
|
|
52
|
+
*/
|
|
53
|
+
export interface McpGrantIdentity {
|
|
54
|
+
/** The account's roles as they are now, or null when it no longer exists. */
|
|
55
|
+
currentRoles(uid: string): Promise<string[] | null>;
|
|
56
|
+
/** Where "sign out everywhere" and every password change leave their mark. */
|
|
57
|
+
revocation?: Pick<AuthRepository, "getTokensValidAfter">;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The grant identity the auth repository can answer, or undefined when the
|
|
61
|
+
* adapter exposes no repository that can say whether an account exists.
|
|
62
|
+
*
|
|
63
|
+
* The same repository the admin gate re-reads roles and the revocation
|
|
64
|
+
* watermark from, so a grant is held to what a session is held to.
|
|
65
|
+
*/
|
|
66
|
+
export declare function grantIdentityFromRepository(repo: Partial<Pick<AuthRepository, "getUserById" | "getUserRoleIds" | "getTokensValidAfter">> | undefined): McpGrantIdentity | undefined;
|
|
40
67
|
export declare function createOAuthRoutes(config: OAuthRoutesConfig): Hono<HonoEnv>;
|
|
41
68
|
/**
|
|
42
69
|
* Why a redirect URI cannot be registered, or null if it can.
|
|
@@ -45,7 +72,13 @@ export declare function createOAuthRoutes(config: OAuthRoutesConfig): Hono<HonoE
|
|
|
45
72
|
* means a stored row is never itself the hazard.
|
|
46
73
|
*/
|
|
47
74
|
export declare function redirectUriProblem(uri: string): string | null;
|
|
48
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* Human-readable consent lines, one per granted scope.
|
|
77
|
+
*
|
|
78
|
+
* Worded for the person consenting, not taken from the scope catalogue: what
|
|
79
|
+
* they need to read here is that the client gets *their own* access and no
|
|
80
|
+
* more, and which collections it reaches when the grant names some.
|
|
81
|
+
*/
|
|
49
82
|
export declare function describeScopes(scope: string): {
|
|
50
83
|
scope: string;
|
|
51
84
|
description: string;
|
|
@@ -53,26 +53,29 @@ export interface RefreshTokenRecord {
|
|
|
53
53
|
clientId: string;
|
|
54
54
|
uid: string;
|
|
55
55
|
/**
|
|
56
|
-
* The roles the
|
|
56
|
+
* The roles the token was minted with.
|
|
57
57
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* The consequence of storing them is that a role change does not reach an
|
|
66
|
-
* existing grant until the refresh token expires or the user revokes the
|
|
67
|
-
* client. That is stated in the docs, and it is the trade this design makes
|
|
68
|
-
* knowingly: the alternative is a user lookup on every refresh, which puts
|
|
69
|
-
* the auth adapter on a path that currently has no dependency on it.
|
|
58
|
+
* A refresh re-reads the account's roles when the routes are given an
|
|
59
|
+
* identity to ask (`McpGrantIdentity`), so these are what a grant falls
|
|
60
|
+
* back on when there is none — an auth adapter that exposes no user
|
|
61
|
+
* repository. The fallback is these rather than an empty list because an
|
|
62
|
+
* access token minted with no `roles` is not a smaller grant — it is a
|
|
63
|
+
* DIFFERENT identity to the database: any policy written as "a row this
|
|
64
|
+
* user's role may see" evaluates against an empty list and returns nothing.
|
|
70
65
|
*/
|
|
71
66
|
roles: string[];
|
|
72
67
|
scope: string;
|
|
73
68
|
resource: string;
|
|
74
69
|
family: string;
|
|
75
70
|
}
|
|
71
|
+
/** A refresh token that could be spent right now, and when it was minted. */
|
|
72
|
+
export interface LiveRefreshToken extends RefreshTokenRecord {
|
|
73
|
+
/**
|
|
74
|
+
* When this token — not its family — was issued. Compared with the user's
|
|
75
|
+
* revocation watermark: a token minted before "sign out everywhere" is void.
|
|
76
|
+
*/
|
|
77
|
+
issuedAt: Date;
|
|
78
|
+
}
|
|
76
79
|
export interface OAuthStore {
|
|
77
80
|
ensureTables(): Promise<void>;
|
|
78
81
|
registerClient(client: OAuthClient): Promise<void>;
|
|
@@ -91,6 +94,19 @@ export interface OAuthStore {
|
|
|
91
94
|
* the same family before returning null.
|
|
92
95
|
*/
|
|
93
96
|
consumeRefreshToken(token: string): Promise<RefreshTokenRecord | null>;
|
|
97
|
+
/**
|
|
98
|
+
* A live refresh token's grant, WITHOUT spending it.
|
|
99
|
+
*
|
|
100
|
+
* What the token endpoint checks before it rotates: whose client it is,
|
|
101
|
+
* the scope asked for, and whether the account behind it still stands.
|
|
102
|
+
* Spending first and checking after means a refusal — or a database blip
|
|
103
|
+
* in the account lookup — leaves the holder with a spent token, and their
|
|
104
|
+
* retry reads as a replay that kills the family.
|
|
105
|
+
*
|
|
106
|
+
* Returns null for anything {@link consumeRefreshToken} would refuse, and
|
|
107
|
+
* writes nothing: a replayed token is detected when it is spent.
|
|
108
|
+
*/
|
|
109
|
+
peekRefreshToken(token: string): Promise<LiveRefreshToken | null>;
|
|
94
110
|
revokeFamily(family: string): Promise<void>;
|
|
95
111
|
/**
|
|
96
112
|
* Revoke the family a token belongs to, for RFC 7009 — without spending it.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type DataDriver } from "@rebasepro/types";
|
|
2
2
|
import { type MetricSeries, type SeriesPoint } from "./history-store.js";
|
|
3
3
|
export interface MetricsHistory {
|
|
4
4
|
/** Create the table and sweep what has aged out. */
|
|
@@ -2,9 +2,44 @@ import { createRequire as __rebaseCreateRequire } from "module";
|
|
|
2
2
|
import __rebaseProcess from "process";
|
|
3
3
|
globalThis.process ??= __rebaseProcess;
|
|
4
4
|
__rebaseCreateRequire(import.meta.url);
|
|
5
|
-
import {
|
|
6
|
-
import "./src-
|
|
5
|
+
import { n as __exportAll } from "./rolldown-runtime-dW7B1o5h.js";
|
|
6
|
+
import { B as findRelation, H as isRelationRequired, L as getTenantConfig, T as effectiveAccess, W as resolveCollectionRelations, ft as isToMany, z as fieldKeyForColumn } from "./src-I3aG1PcY.js";
|
|
7
|
+
import "./src-CatHFUym.js";
|
|
8
|
+
import { n as HARD_DELETE_QUERY_PARAM, t as DELETED_QUERY_PARAM } from "./soft-delete-params-BWPilMPF.js";
|
|
9
|
+
/**
|
|
10
|
+
* The property a `softDelete` collection records a deletion in — its wire
|
|
11
|
+
* name, what a delete stamps and what a restore (an update to `null`) clears —
|
|
12
|
+
* or `undefined` for a collection without soft delete.
|
|
13
|
+
*
|
|
14
|
+
* One reading of the declaration for every layer that needs it: the driver
|
|
15
|
+
* that stamps and filters on it, and the REST route that has to recognise a
|
|
16
|
+
* restore before it looks the row up.
|
|
17
|
+
*/
|
|
18
|
+
function softDeleteFieldOf(collection) {
|
|
19
|
+
const declared = collection && "softDelete" in collection ? collection.softDelete : void 0;
|
|
20
|
+
if (!declared) return void 0;
|
|
21
|
+
return typeof declared === "object" && declared.field || "deletedAt";
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Whether an update's values restore a soft-deleted row: they set the
|
|
25
|
+
* soft-delete field back to `null`, the documented restore.
|
|
26
|
+
*
|
|
27
|
+
* A restore is an ordinary update of a row every default read hides, so a door
|
|
28
|
+
* that looks the row up before updating it has to include the trashed rows for
|
|
29
|
+
* this update — and only for this one: any other edit of a trashed row is a
|
|
30
|
+
* 404.
|
|
31
|
+
*/
|
|
32
|
+
function restoresSoftDeletedRow(collection, values) {
|
|
33
|
+
const field = softDeleteFieldOf(collection);
|
|
34
|
+
return field !== void 0 && values?.[field] === null;
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
7
37
|
//#region src/api/openapi-generator.ts
|
|
38
|
+
var openapi_generator_exports = /* @__PURE__ */ __exportAll({
|
|
39
|
+
buildCollectionInputSchema: () => buildCollectionInputSchema,
|
|
40
|
+
buildCollectionSchema: () => buildCollectionSchema,
|
|
41
|
+
generateOpenApiSpec: () => generateOpenApiSpec
|
|
42
|
+
});
|
|
8
43
|
function generateOpenApiSpec(collections, options = {}) {
|
|
9
44
|
const basePath = options.basePath ?? "/api";
|
|
10
45
|
const requireAuth = options.requireAuth ?? true;
|
|
@@ -108,7 +143,7 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
108
143
|
name: "distinct",
|
|
109
144
|
in: "query",
|
|
110
145
|
schema: { type: "boolean" },
|
|
111
|
-
description: "`SELECT DISTINCT` over the returned columns. Only meaningful alongside `fields`: the primary key is always in the projection, so without narrowing it every row is already distinct. `meta.total`
|
|
146
|
+
description: "`SELECT DISTINCT` over the returned columns. Only meaningful alongside `fields`: the primary key is always in the projection, so without narrowing it every row is already distinct. The response has no `meta.total` — the rows before deduplication are a different set, so their count would not describe the page — and `meta.hasMore` is true when the page came back full. Refused (400) alongside `searchString` or a vector search, which attach a per-row score that makes every row distinct by construction, and (400 DISTINCT_ORDER_BY_NOT_SELECTED) when `orderBy` names a column `fields` does not return.",
|
|
112
147
|
example: "true"
|
|
113
148
|
},
|
|
114
149
|
{
|
|
@@ -183,7 +218,7 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
183
218
|
properties: {
|
|
184
219
|
total: {
|
|
185
220
|
type: "integer",
|
|
186
|
-
description: "Total number of matching records"
|
|
221
|
+
description: "Total number of matching records. Absent on a `distinct` read, which has no count of the rows it returns."
|
|
187
222
|
},
|
|
188
223
|
limit: {
|
|
189
224
|
type: "integer",
|
|
@@ -220,7 +255,50 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
220
255
|
const paths = spec.paths;
|
|
221
256
|
const schemas = spec.components.schemas;
|
|
222
257
|
const tags = spec.tags;
|
|
223
|
-
const reservedParameterNames = new Set(listQueryParameters().map((p) => p.name));
|
|
258
|
+
const reservedParameterNames = /* @__PURE__ */ new Set([...listQueryParameters().map((p) => p.name), DELETED_QUERY_PARAM]);
|
|
259
|
+
/**
|
|
260
|
+
* `?deleted=` on the reads of a `softDelete` collection. A delete there
|
|
261
|
+
* moves the row to the trash, and every read hides trashed rows unless it
|
|
262
|
+
* asks for them; the list, the single row, the count and the aggregate all
|
|
263
|
+
* honour this. Empty for any other collection.
|
|
264
|
+
*/
|
|
265
|
+
const deletedParameters = (collection) => {
|
|
266
|
+
const field = softDeleteFieldOf(collection);
|
|
267
|
+
if (!field) return [];
|
|
268
|
+
return [{
|
|
269
|
+
name: DELETED_QUERY_PARAM,
|
|
270
|
+
in: "query",
|
|
271
|
+
required: false,
|
|
272
|
+
schema: {
|
|
273
|
+
type: "string",
|
|
274
|
+
enum: ["include", "only"]
|
|
275
|
+
},
|
|
276
|
+
description: `Rows a delete moved to the trash (\`${field}\` set) are left out unless this asks for them: \`include\` reads them with the live rows, \`only\` reads them alone. Any other value is a 400 INVALID_DELETED_PARAM.`
|
|
277
|
+
}];
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* `?hard=` on the deletes of a `softDelete` collection: delete for good
|
|
281
|
+
* rather than move to the trash. Empty for any other collection.
|
|
282
|
+
*/
|
|
283
|
+
const hardDeleteParameters = (collection) => {
|
|
284
|
+
if (!softDeleteFieldOf(collection)) return [];
|
|
285
|
+
return [{
|
|
286
|
+
name: HARD_DELETE_QUERY_PARAM,
|
|
287
|
+
in: "query",
|
|
288
|
+
required: false,
|
|
289
|
+
schema: {
|
|
290
|
+
type: "boolean",
|
|
291
|
+
default: false
|
|
292
|
+
},
|
|
293
|
+
description: "`true` deletes for good instead of moving to the trash — a row already in the trash included, which is how the trash is emptied. Only `true`/`1` and `false`/`0` are accepted; anything else is a 400 INVALID_HARD_PARAM."
|
|
294
|
+
}];
|
|
295
|
+
};
|
|
296
|
+
/** What a delete does to a `softDelete` collection's row, for the delete operations' descriptions. */
|
|
297
|
+
const softDeleteBehaviour = (collection) => {
|
|
298
|
+
const field = softDeleteFieldOf(collection);
|
|
299
|
+
if (!field) return void 0;
|
|
300
|
+
return `This collection soft-deletes: a delete moves the row to the trash by stamping \`${field}\`, and every read leaves it out unless it passes \`?deleted=include\` or \`?deleted=only\`. A PATCH setting \`${field}\` back to \`null\` restores it. Pass \`?hard=true\` to delete for good.`;
|
|
301
|
+
};
|
|
224
302
|
const registeredSchemas = new Set((collections || []).map(schemaNameFor));
|
|
225
303
|
/**
|
|
226
304
|
* `Prefer: return=minimal`, on every route that would otherwise send a row
|
|
@@ -387,12 +465,17 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
387
465
|
schemas[`${schemaName}Input`] = buildCollectionInputSchema(collection);
|
|
388
466
|
schemas[`${schemaName}Update`] = buildCollectionUpdateSchema(collection);
|
|
389
467
|
const dataPath = `/data/${slug}`;
|
|
468
|
+
const softDeleteNote = softDeleteBehaviour(collection);
|
|
390
469
|
paths[`${dataPath}/count`] = { get: {
|
|
391
470
|
tags: [collection.name],
|
|
392
471
|
summary: `Count ${collection.name}`,
|
|
393
472
|
description: "The number of rows the same filters would return, without returning them. Takes the filter and search parameters of the list endpoint; `limit`, `offset` and `orderBy` are not part of the question and are ignored.",
|
|
394
473
|
operationId: `count${schemaName}`,
|
|
395
|
-
parameters: [
|
|
474
|
+
parameters: [
|
|
475
|
+
...listQueryParameters().filter((p) => p.name === "searchString"),
|
|
476
|
+
...deletedParameters(collection),
|
|
477
|
+
...buildFilterParameters(collection, reservedParameterNames)
|
|
478
|
+
],
|
|
396
479
|
responses: {
|
|
397
480
|
200: {
|
|
398
481
|
description: "The number of matching rows",
|
|
@@ -430,7 +513,16 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
430
513
|
schema: { type: "string" },
|
|
431
514
|
example: "status"
|
|
432
515
|
},
|
|
433
|
-
...listQueryParameters().filter((p) => p.name === "searchString" || p.name === "limit"),
|
|
516
|
+
...listQueryParameters().filter((p) => p.name === "searchString" || p.name === "limit" || p.name === "offset" || p.name === "page"),
|
|
517
|
+
{
|
|
518
|
+
name: "orderBy",
|
|
519
|
+
in: "query",
|
|
520
|
+
required: false,
|
|
521
|
+
description: "Sort for the groups, by a `groupBy` field or an aggregate's result key (`count`, `sum_total`): `key:asc`, `key:desc` or `key:desc:last`. Groups it leaves tied are ordered by the `groupBy` fields, so every page boundary falls in the same place. `offset`, `page` and `orderBy` need `groupBy` — without it the result is one row — and are otherwise a 400 INVALID_AGGREGATE_WINDOW.",
|
|
522
|
+
schema: { type: "string" },
|
|
523
|
+
example: "count:desc"
|
|
524
|
+
},
|
|
525
|
+
...deletedParameters(collection),
|
|
434
526
|
...buildFilterParameters(collection, reservedParameterNames)
|
|
435
527
|
],
|
|
436
528
|
responses: {
|
|
@@ -439,13 +531,27 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
439
531
|
content: { "application/json": { schema: {
|
|
440
532
|
type: "object",
|
|
441
533
|
required: ["data"],
|
|
442
|
-
properties: {
|
|
443
|
-
|
|
444
|
-
|
|
534
|
+
properties: {
|
|
535
|
+
data: {
|
|
536
|
+
type: "array",
|
|
537
|
+
items: {
|
|
538
|
+
type: "object",
|
|
539
|
+
additionalProperties: true
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
meta: {
|
|
445
543
|
type: "object",
|
|
446
|
-
|
|
544
|
+
description: "The page of groups. Present when `groupBy` is.",
|
|
545
|
+
properties: {
|
|
546
|
+
limit: { type: "integer" },
|
|
547
|
+
offset: { type: "integer" },
|
|
548
|
+
hasMore: {
|
|
549
|
+
type: "boolean",
|
|
550
|
+
description: "Whether a group follows this page."
|
|
551
|
+
}
|
|
552
|
+
}
|
|
447
553
|
}
|
|
448
|
-
}
|
|
554
|
+
}
|
|
449
555
|
} } }
|
|
450
556
|
},
|
|
451
557
|
501: { description: "This backend's data driver does not implement aggregates" },
|
|
@@ -457,7 +563,11 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
457
563
|
tags: [collection.name],
|
|
458
564
|
summary: `List ${collection.name}`,
|
|
459
565
|
operationId: `list${schemaName}`,
|
|
460
|
-
parameters: [
|
|
566
|
+
parameters: [
|
|
567
|
+
...listQueryParameters(),
|
|
568
|
+
...deletedParameters(collection),
|
|
569
|
+
...buildFilterParameters(collection, reservedParameterNames)
|
|
570
|
+
],
|
|
461
571
|
responses: {
|
|
462
572
|
200: {
|
|
463
573
|
description: "Paginated list of entities",
|
|
@@ -627,9 +737,9 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
627
737
|
paths[`/data/${slug}/bulk/delete`] = { post: {
|
|
628
738
|
tags: [collection.name],
|
|
629
739
|
summary: `Delete many ${collection.name} in one transaction`,
|
|
630
|
-
description: "A POST, not `DELETE /bulk` with a body. Bodies on DELETE are permitted but widely dropped by proxies and CDNs, and several generators ignore `requestBody` on a DELETE operation — a generated client would send the request with no ids at all. Takes ids rather than a filter: a mistyped condition that empties a table cannot be reviewed at the call site the way an explicit list can. `beforeDelete`/`afterDelete` fire per row.",
|
|
740
|
+
description: "A POST, not `DELETE /bulk` with a body. Bodies on DELETE are permitted but widely dropped by proxies and CDNs, and several generators ignore `requestBody` on a DELETE operation — a generated client would send the request with no ids at all. Takes ids rather than a filter: a mistyped condition that empties a table cannot be reviewed at the call site the way an explicit list can. `beforeDelete`/`afterDelete` fire per row." + (softDeleteNote ? `\n\n${softDeleteNote}` : ""),
|
|
631
741
|
operationId: `deleteMany${schemaName}`,
|
|
632
|
-
parameters: [idempotencyHeader],
|
|
742
|
+
parameters: [idempotencyHeader, ...hardDeleteParameters(collection)],
|
|
633
743
|
requestBody: {
|
|
634
744
|
required: true,
|
|
635
745
|
content: { "application/json": { schema: {
|
|
@@ -643,7 +753,7 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
643
753
|
},
|
|
644
754
|
responses: {
|
|
645
755
|
200: {
|
|
646
|
-
description: "How many rows were deleted",
|
|
756
|
+
description: softDeleteNote ? "How many rows were moved to the trash, or deleted for good with `?hard=true`" : "How many rows were deleted",
|
|
647
757
|
content: { "application/json": { schema: {
|
|
648
758
|
type: "object",
|
|
649
759
|
properties: { meta: {
|
|
@@ -686,7 +796,8 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
686
796
|
schema: { type: "string" },
|
|
687
797
|
description: "Comma-separated columns to return, as a SELECT projection. The primary key always survives and `excludeFromApi` columns stay hidden.",
|
|
688
798
|
example: "id,title"
|
|
689
|
-
}
|
|
799
|
+
},
|
|
800
|
+
...deletedParameters(collection)
|
|
690
801
|
],
|
|
691
802
|
responses: {
|
|
692
803
|
200: {
|
|
@@ -713,6 +824,7 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
713
824
|
delete: {
|
|
714
825
|
tags: [collection.name],
|
|
715
826
|
summary: `Delete ${collection.singularName || collection.name}`,
|
|
827
|
+
...softDeleteNote ? { description: softDeleteNote } : {},
|
|
716
828
|
operationId: `delete${schemaName}`,
|
|
717
829
|
parameters: [
|
|
718
830
|
{
|
|
@@ -729,10 +841,11 @@ function generateOpenApiSpec(collections, options = {}) {
|
|
|
729
841
|
required: false,
|
|
730
842
|
schema: { type: "string" },
|
|
731
843
|
description: "Names this delete so a retry replays its answer. A delete replayed after the first attempt committed would otherwise answer 404 — which an offline queue reads as a permanent failure for a delete that in fact succeeded."
|
|
732
|
-
}
|
|
844
|
+
},
|
|
845
|
+
...hardDeleteParameters(collection)
|
|
733
846
|
],
|
|
734
847
|
responses: {
|
|
735
|
-
204: { description: "Deleted successfully" },
|
|
848
|
+
204: { description: softDeleteNote ? "Moved to the trash: the row still exists and can be restored. With `?hard=true`, deleted for good" : "Deleted successfully" },
|
|
736
849
|
404: {
|
|
737
850
|
description: "Entity not found",
|
|
738
851
|
content: { "application/json": { schema: { $ref: "#/components/schemas/ErrorResponse" } } }
|
|
@@ -1055,7 +1168,7 @@ function updateOperation(collection, schemaName, requireAuth, shared) {
|
|
|
1055
1168
|
return {
|
|
1056
1169
|
tags: [collection.name],
|
|
1057
1170
|
summary: `Update ${collection.singularName || collection.name}`,
|
|
1058
|
-
description: "Partial update: only the properties present in the body are written; the rest are left unchanged.\n\nA property's value may instead be a field operation — `{ \"views\": { \"$inc\": 1 } }`, `{ \"tags\": { \"$push\": \"new\" } }`, `{ \"tags\": { \"$pull\": \"old\" } }`, `{ \"meta\": { \"$merge\": { \"seen\": true } } }` — which is applied inside the statement holding the row lock. That is the difference between a counter that is correct under concurrency and one that silently loses increments, because expressing the same change as a value means reading it first. `$inc` needs a `number` property, `$push`/`$pull` an `array`, `$merge` a `map`; anything else is a 400. See the `FieldOperation` schema.",
|
|
1171
|
+
description: "Partial update: only the properties present in the body are written; the rest are left unchanged.\n\nA property's value may instead be a field operation — `{ \"views\": { \"$inc\": 1 } }`, `{ \"tags\": { \"$push\": \"new\" } }`, `{ \"tags\": { \"$pull\": \"old\" } }`, `{ \"meta\": { \"$merge\": { \"seen\": true } } }` — which is applied inside the statement holding the row lock. That is the difference between a counter that is correct under concurrency and one that silently loses increments, because expressing the same change as a value means reading it first. `$inc` needs a `number` property, `$push`/`$pull` an `array`, `$merge` a `map`; anything else is a 400. Pushed elements and merged keys answer to the property's own rules, as a value would. See the `FieldOperation` schema.",
|
|
1059
1172
|
operationId: `update${schemaName}`,
|
|
1060
1173
|
parameters: [
|
|
1061
1174
|
{
|
|
@@ -1424,6 +1537,6 @@ function toPascalCase(str) {
|
|
|
1424
1537
|
return str.replace(/[^a-zA-Z0-9]+/g, " ").split(" ").filter(Boolean).map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join("");
|
|
1425
1538
|
}
|
|
1426
1539
|
//#endregion
|
|
1427
|
-
export {
|
|
1540
|
+
export { softDeleteFieldOf as a, restoresSoftDeletedRow as i, buildCollectionSchema as n, openapi_generator_exports as r, buildCollectionInputSchema as t };
|
|
1428
1541
|
|
|
1429
|
-
//# sourceMappingURL=openapi-generator-
|
|
1542
|
+
//# sourceMappingURL=openapi-generator-DAq_XVDu.js.map
|