@selvajs/platform 0.14.2 → 0.15.0-beta.1
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/LICENSE +1 -1
- package/dist/auth.d.ts +60 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +12 -0
- package/dist/auth.js.map +1 -0
- package/dist/compute.d.ts +47 -0
- package/dist/compute.d.ts.map +1 -0
- package/dist/compute.js +11 -0
- package/dist/compute.js.map +1 -0
- package/dist/computeServer/index.d.ts +2 -0
- package/dist/computeServer/index.d.ts.map +1 -1
- package/dist/computeServer/index.js +6 -0
- package/dist/computeServer/index.js.map +1 -1
- package/dist/computeServer/interface.d.ts +10 -0
- package/dist/computeServer/interface.d.ts.map +1 -1
- package/dist/computeServer/secrets.d.ts +53 -0
- package/dist/computeServer/secrets.d.ts.map +1 -0
- package/dist/computeServer/secrets.js +67 -0
- package/dist/computeServer/secrets.js.map +1 -0
- package/dist/context.d.ts +7 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +13 -0
- package/dist/context.js.map +1 -1
- package/dist/data/interface.d.ts +33 -0
- package/dist/data/interface.d.ts.map +1 -1
- package/dist/definitions/interface.d.ts +18 -0
- package/dist/definitions/interface.d.ts.map +1 -1
- package/dist/definitions/schemas.d.ts +1 -0
- package/dist/definitions/schemas.d.ts.map +1 -1
- package/dist/definitions/schemas.js +3 -0
- package/dist/definitions/schemas.js.map +1 -1
- package/dist/definitions/service.d.ts +62 -0
- package/dist/definitions/service.d.ts.map +1 -0
- package/dist/definitions/service.js +149 -0
- package/dist/definitions/service.js.map +1 -0
- package/dist/definitions/types.d.ts +24 -1
- package/dist/definitions/types.d.ts.map +1 -1
- package/dist/definitions.d.ts +146 -0
- package/dist/definitions.d.ts.map +1 -0
- package/dist/definitions.js +23 -0
- package/dist/definitions.js.map +1 -0
- package/dist/errors/interface.d.ts +44 -0
- package/dist/errors/interface.d.ts.map +1 -0
- package/dist/errors/interface.js +9 -0
- package/dist/errors/interface.js.map +1 -0
- package/dist/events/interface.d.ts +23 -0
- package/dist/events/interface.d.ts.map +1 -1
- package/dist/events/interface.js.map +1 -1
- package/dist/index.d.ts +14 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -2
- package/dist/index.js.map +1 -1
- package/dist/invites/schemas.d.ts +24 -0
- package/dist/invites/schemas.d.ts.map +1 -0
- package/dist/invites/schemas.js +17 -0
- package/dist/invites/schemas.js.map +1 -0
- package/dist/metrics/interface.d.ts +6 -0
- package/dist/metrics/interface.d.ts.map +1 -1
- package/dist/metrics/interface.js.map +1 -1
- package/dist/organizations/index.d.ts +4 -3
- package/dist/organizations/index.d.ts.map +1 -1
- package/dist/organizations/index.js +2 -1
- package/dist/organizations/index.js.map +1 -1
- package/dist/organizations/interface.d.ts +1 -1
- package/dist/organizations/interface.d.ts.map +1 -1
- package/dist/organizations/paths.d.ts +22 -0
- package/dist/organizations/paths.d.ts.map +1 -0
- package/dist/organizations/paths.js +43 -0
- package/dist/organizations/paths.js.map +1 -0
- package/dist/organizations/schemas.d.ts +10 -0
- package/dist/organizations/schemas.d.ts.map +1 -1
- package/dist/organizations/schemas.js +6 -0
- package/dist/organizations/schemas.js.map +1 -1
- package/dist/organizations/types.d.ts +10 -1
- package/dist/organizations/types.d.ts.map +1 -1
- package/dist/organizations.d.ts +93 -0
- package/dist/organizations.d.ts.map +1 -0
- package/dist/organizations.js +14 -0
- package/dist/organizations.js.map +1 -0
- package/dist/solveCache/interface.d.ts +86 -0
- package/dist/solveCache/interface.d.ts.map +1 -0
- package/dist/solveCache/interface.js +12 -0
- package/dist/solveCache/interface.js.map +1 -0
- package/dist/storage/assetClasses.d.ts +59 -0
- package/dist/storage/assetClasses.d.ts.map +1 -0
- package/dist/storage/assetClasses.js +86 -0
- package/dist/storage/assetClasses.js.map +1 -0
- package/dist/storage/cacheBust.d.ts +21 -0
- package/dist/storage/cacheBust.d.ts.map +1 -0
- package/dist/storage/cacheBust.js +29 -0
- package/dist/storage/cacheBust.js.map +1 -0
- package/dist/storage/image.d.ts +6 -1
- package/dist/storage/image.d.ts.map +1 -1
- package/dist/storage/image.js +8 -3
- package/dist/storage/image.js.map +1 -1
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/testing/adapterSuite.d.ts +33 -0
- package/dist/testing/adapterSuite.d.ts.map +1 -0
- package/dist/testing/adapterSuite.js +166 -0
- package/dist/testing/adapterSuite.js.map +1 -0
- package/dist/testing/suites/definitionStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/definitionStoreSuite.js +87 -0
- package/dist/testing/suites/definitionStoreSuite.js.map +1 -1
- package/dist/testing/suites/eventSinkSuite.js +1 -0
- package/dist/testing/suites/eventSinkSuite.js.map +1 -1
- package/dist/testing/suites/orgStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/orgStoreSuite.js +12 -0
- package/dist/testing/suites/orgStoreSuite.js.map +1 -1
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts +9 -0
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/platformPermissionStoreSuite.js +34 -1
- package/dist/testing/suites/platformPermissionStoreSuite.js.map +1 -1
- package/dist/testing/suites/runner.d.ts +21 -0
- package/dist/testing/suites/runner.d.ts.map +1 -0
- package/dist/testing/suites/runner.js +7 -0
- package/dist/testing/suites/runner.js.map +1 -0
- package/dist/testing/suites/storageProviderSuite.d.ts.map +1 -1
- package/dist/testing/suites/storageProviderSuite.js +18 -0
- package/dist/testing/suites/storageProviderSuite.js.map +1 -1
- package/package.json +9 -24
- package/src/access/index.ts +0 -23
- package/src/access/rules.ts +0 -276
- package/src/auth/index.ts +0 -8
- package/src/auth/interface.ts +0 -279
- package/src/auth/types.ts +0 -32
- package/src/bindings/index.ts +0 -2
- package/src/bindings/interface.ts +0 -61
- package/src/computeServer/index.ts +0 -17
- package/src/computeServer/interface.ts +0 -62
- package/src/computeServer/types.ts +0 -74
- package/src/computeServer/utils.ts +0 -112
- package/src/config.ts +0 -99
- package/src/context.ts +0 -66
- package/src/data/index.ts +0 -1
- package/src/data/interface.ts +0 -70
- package/src/definitions/index.ts +0 -26
- package/src/definitions/interface.ts +0 -78
- package/src/definitions/paths.ts +0 -31
- package/src/definitions/schemas.ts +0 -64
- package/src/definitions/types.ts +0 -111
- package/src/errors.ts +0 -16
- package/src/events/audit.ts +0 -67
- package/src/events/index.ts +0 -9
- package/src/events/interface.ts +0 -102
- package/src/index.ts +0 -219
- package/src/invites/index.ts +0 -2
- package/src/invites/interface.ts +0 -38
- package/src/invites/types.ts +0 -39
- package/src/metrics/interface.ts +0 -86
- package/src/organizations/index.ts +0 -14
- package/src/organizations/interface.ts +0 -68
- package/src/organizations/schemas.ts +0 -52
- package/src/organizations/types.ts +0 -31
- package/src/pagination.ts +0 -45
- package/src/permissions/index.ts +0 -3
- package/src/permissions/interface.ts +0 -60
- package/src/permissions/types.ts +0 -21
- package/src/platformProjects/index.ts +0 -3
- package/src/platformProjects/interface.ts +0 -27
- package/src/platformProjects/schemas.ts +0 -13
- package/src/platformProjects/types.ts +0 -22
- package/src/projects/index.ts +0 -4
- package/src/projects/interface.ts +0 -58
- package/src/projects/schemas.ts +0 -28
- package/src/projects/types.ts +0 -36
- package/src/shareLinks/index.ts +0 -5
- package/src/shareLinks/interface.ts +0 -35
- package/src/shareLinks/schemas.ts +0 -21
- package/src/shareLinks/types.ts +0 -34
- package/src/storage/image.ts +0 -77
- package/src/storage/index.ts +0 -9
- package/src/storage/interface.ts +0 -27
- package/src/testing/index.ts +0 -47
- package/src/testing/suites/authProviderSuite.ts +0 -207
- package/src/testing/suites/computeServerStoreSuite.ts +0 -195
- package/src/testing/suites/definitionStoreSuite.ts +0 -585
- package/src/testing/suites/emailLinkAuthSuite.ts +0 -83
- package/src/testing/suites/eventSinkSuite.ts +0 -379
- package/src/testing/suites/helpers.ts +0 -87
- package/src/testing/suites/inviteStoreSuite.ts +0 -143
- package/src/testing/suites/orgStoreSuite.ts +0 -412
- package/src/testing/suites/platformPermissionStoreSuite.ts +0 -196
- package/src/testing/suites/platformProjectGrantStoreSuite.ts +0 -166
- package/src/testing/suites/projectStoreSuite.ts +0 -381
- package/src/testing/suites/shareLinkStoreSuite.ts +0 -203
- package/src/testing/suites/solveMetricSinkSuite.ts +0 -135
- package/src/testing/suites/storageProviderSuite.ts +0 -175
- package/src/testing/suites/userProfileStoreSuite.ts +0 -134
- package/src/userProfile/index.ts +0 -3
- package/src/userProfile/interface.ts +0 -48
- package/src/userProfile/types.ts +0 -24
- package/src/utils/audit.ts +0 -46
- package/src/utils/index.ts +0 -2
package/LICENSE
CHANGED
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication provider interface.
|
|
3
|
+
*
|
|
4
|
+
* Implement this to plug in any auth backend:
|
|
5
|
+
* - Local HMAC sessions (built-in default)
|
|
6
|
+
* - Firebase Auth
|
|
7
|
+
* - Supabase Auth
|
|
8
|
+
* - AWS Cognito
|
|
9
|
+
* - Any OIDC/JWT provider
|
|
10
|
+
*/
|
|
11
|
+
export type UserRole = 'platform_admin' | 'user';
|
|
12
|
+
export interface AuthUser {
|
|
13
|
+
id: string;
|
|
14
|
+
email?: string;
|
|
15
|
+
displayName?: string;
|
|
16
|
+
role: UserRole;
|
|
17
|
+
metadata?: Record<string, unknown>;
|
|
18
|
+
}
|
|
19
|
+
export interface IAuthProvider {
|
|
20
|
+
/**
|
|
21
|
+
* Verify a token string — session cookie value, JWT, Firebase ID token, etc.
|
|
22
|
+
* Returns the authenticated user, or null if the token is invalid or expired.
|
|
23
|
+
*/
|
|
24
|
+
verifyToken(token: string): Promise<AuthUser | null>;
|
|
25
|
+
/**
|
|
26
|
+
* Look up a user by their provider-specific ID.
|
|
27
|
+
* Returns null if the user does not exist.
|
|
28
|
+
*/
|
|
29
|
+
getUser(id: string): Promise<AuthUser | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Create a new opaque session token for an authenticated user.
|
|
32
|
+
* Stored in a cookie by the transport layer. Format is provider-specific:
|
|
33
|
+
* HMAC string, signed JWT, Firebase custom token, etc.
|
|
34
|
+
*/
|
|
35
|
+
createSessionToken(user: AuthUser): Promise<string>;
|
|
36
|
+
/**
|
|
37
|
+
* Verify login credentials (email + password).
|
|
38
|
+
* Returns the authenticated user, or null if credentials are invalid.
|
|
39
|
+
* Email may be an empty string for password-only auth (no users.json configured).
|
|
40
|
+
*/
|
|
41
|
+
verifyLoginCredentials(email: string, password: string): Promise<AuthUser | null>;
|
|
42
|
+
/**
|
|
43
|
+
* List all users. Returns null if this provider does not support user management
|
|
44
|
+
* (e.g. single-password mode).
|
|
45
|
+
*/
|
|
46
|
+
listUsers(): Promise<AuthUser[] | null>;
|
|
47
|
+
/**
|
|
48
|
+
* Create a new user. Returns null if not supported.
|
|
49
|
+
*/
|
|
50
|
+
createUser(email: string, password: string, role: UserRole): Promise<AuthUser | null>;
|
|
51
|
+
/**
|
|
52
|
+
* Update a user's role. Returns false if not supported or user not found.
|
|
53
|
+
*/
|
|
54
|
+
updateUserRole(id: string, role: UserRole): Promise<boolean>;
|
|
55
|
+
/**
|
|
56
|
+
* Delete a user by ID. Returns false if not supported or user not found.
|
|
57
|
+
*/
|
|
58
|
+
deleteUser(id: string): Promise<boolean>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,MAAM,QAAQ,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAEjD,MAAM,WAAW,QAAQ;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,aAAa;IAC7B;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAErD;;;OAGG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAE9C;;;;OAIG;IACH,kBAAkB,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEpD;;;;OAIG;IACH,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAIlF;;;OAGG;IACH,SAAS,IAAI,OAAO,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC;IAExC;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;IAEtF;;OAEG;IACH,cAAc,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE7D;;OAEG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACzC"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication provider interface.
|
|
3
|
+
*
|
|
4
|
+
* Implement this to plug in any auth backend:
|
|
5
|
+
* - Local HMAC sessions (built-in default)
|
|
6
|
+
* - Firebase Auth
|
|
7
|
+
* - Supabase Auth
|
|
8
|
+
* - AWS Cognito
|
|
9
|
+
* - Any OIDC/JWT provider
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute server provider interface.
|
|
3
|
+
*
|
|
4
|
+
* Implement to support:
|
|
5
|
+
* - Single server (built-in default)
|
|
6
|
+
* - Server pool with load balancing
|
|
7
|
+
* - Per-definition routing (e.g. definition A always goes to server B)
|
|
8
|
+
* - Dynamic provisioning
|
|
9
|
+
*/
|
|
10
|
+
export interface ComputeServerConfig {
|
|
11
|
+
/** UUID v4 primary key */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Human-readable display label */
|
|
14
|
+
label: string;
|
|
15
|
+
/** Base URL of the Rhino.Compute instance, e.g. http://localhost:5000 */
|
|
16
|
+
serverUrl: string;
|
|
17
|
+
/** Optional API key sent as RhinoComputeKey header */
|
|
18
|
+
apiKey?: string;
|
|
19
|
+
/** Request timeout in milliseconds. Default: 30000 */
|
|
20
|
+
timeoutMs?: number;
|
|
21
|
+
/** Number of retries on transient failure. Default: 0 */
|
|
22
|
+
retryCount?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface ComputeConfig {
|
|
25
|
+
servers: ComputeServerConfig[];
|
|
26
|
+
/** UUID of the server to use when no routing rule matches. Falls back to servers[0]. */
|
|
27
|
+
defaultServerId?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface SolveRequest {
|
|
30
|
+
/** GUID of the definition being solved — enables per-definition routing */
|
|
31
|
+
definitionGuid?: string;
|
|
32
|
+
/** Arbitrary hints for routing decisions (e.g. required plugin versions) */
|
|
33
|
+
hints?: Record<string, string>;
|
|
34
|
+
}
|
|
35
|
+
export interface IComputeServerProvider {
|
|
36
|
+
/** Resolve which compute server to use for a given solve request. */
|
|
37
|
+
getServer(request?: SolveRequest): Promise<ComputeServerConfig>;
|
|
38
|
+
/** Return the default server, or undefined if none configured. */
|
|
39
|
+
getDefaultServer(): Promise<ComputeServerConfig | undefined>;
|
|
40
|
+
/** Look up a specific server by its UUID. Returns undefined if not found. */
|
|
41
|
+
getServerById(id: string): Promise<ComputeServerConfig | undefined>;
|
|
42
|
+
/** Return the full config. Used by the admin UI. */
|
|
43
|
+
getConfig(): Promise<ComputeConfig>;
|
|
44
|
+
/** Replace the full config atomically. Used by the admin UI. */
|
|
45
|
+
saveConfig(config: ComputeConfig): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=compute.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute.d.ts","sourceRoot":"","sources":["../src/compute.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,mBAAmB;IACnC,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,yEAAyE;IACzE,SAAS,EAAE,MAAM,CAAC;IAClB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,wFAAwF;IACxF,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC5B,2EAA2E;IAC3E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,sBAAsB;IACtC,qEAAqE;IACrE,SAAS,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEhE,kEAAkE;IAClE,gBAAgB,IAAI,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;IAE7D,6EAA6E;IAC7E,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAAC;IAEpE,oDAAoD;IACpD,SAAS,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC;IAEpC,gEAAgE;IAChE,UAAU,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD"}
|
package/dist/compute.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute server provider interface.
|
|
3
|
+
*
|
|
4
|
+
* Implement to support:
|
|
5
|
+
* - Single server (built-in default)
|
|
6
|
+
* - Server pool with load balancing
|
|
7
|
+
* - Per-definition routing (e.g. definition A always goes to server B)
|
|
8
|
+
* - Dynamic provisioning
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=compute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compute.js","sourceRoot":"","sources":["../src/compute.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
export type { ComputeServerConfig, ComputeConfig, PlatformComputeServer, OrgComputeServer } from './types.js';
|
|
2
2
|
export { isPlatformServer, isOrgServer } from './types.js';
|
|
3
3
|
export type { IComputeServerStore } from './interface.js';
|
|
4
|
+
export { isEncryptedSecret, encryptSecret, decryptSecret, decodeSecretKey } from './secrets.js';
|
|
5
|
+
export type { SecretVerificationReport, SecretVerificationFailure, SecretVerificationFailureReason } from './secrets.js';
|
|
4
6
|
export type { ResolveOptions } from './utils.js';
|
|
5
7
|
export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor } from './utils.js';
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAM1D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChG,YAAY,EACX,wBAAwB,EACxB,yBAAyB,EACzB,+BAA+B,EAC/B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,YAAY,CAAC"}
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
export { isPlatformServer, isOrgServer } from './types.js';
|
|
2
|
+
// At-rest secret crypto (uses `node:crypto`). Server-only — deliberately NOT
|
|
3
|
+
// re-exported from the root barrel, which client `.svelte` code imports and
|
|
4
|
+
// where a browser bundle can't resolve `node:crypto`. Import these from
|
|
5
|
+
// `@selvajs/platform/computeServer` in server code. The report TYPES are erased
|
|
6
|
+
// at build, so they also stay re-exported from the root barrel for convenience.
|
|
7
|
+
export { isEncryptedSecret, encryptSecret, decryptSecret, decodeSecretKey } from './secrets.js';
|
|
2
8
|
export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor } from './utils.js';
|
|
3
9
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,6EAA6E;AAC7E,4EAA4E;AAC5E,wEAAwE;AACxE,gFAAgF;AAChF,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAOhG,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,YAAY,CAAC"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RequestContext } from '../context.js';
|
|
2
2
|
import type { ComputeConfig, ComputeServerConfig } from './types.js';
|
|
3
|
+
import type { SecretVerificationReport } from './secrets.js';
|
|
3
4
|
/**
|
|
4
5
|
* Compute-server configuration. Architecture spec §4.8.
|
|
5
6
|
*
|
|
@@ -45,5 +46,14 @@ export interface IComputeServerStore {
|
|
|
45
46
|
* compute config behind.
|
|
46
47
|
*/
|
|
47
48
|
deleteByOrg(ctx: RequestContext, orgId: string): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* Boot-time integrity check: attempt to decrypt every stored `apiKey` and
|
|
51
|
+
* report any that are plaintext-at-rest or fail to decrypt under the current
|
|
52
|
+
* `SELVA_AT_REST_KEY`. Does NOT throw — returns a structured report so the
|
|
53
|
+
* caller (boot health) decides whether to refuse boot / drive `/api/health`
|
|
54
|
+
* to 503. Both encrypting stores (local file, Supabase) implement this;
|
|
55
|
+
* optional so a hypothetical non-encrypting store can omit it.
|
|
56
|
+
*/
|
|
57
|
+
verifySecrets?(): Promise<SecretVerificationReport>;
|
|
48
58
|
}
|
|
49
59
|
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/computeServer/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/computeServer/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEvD;;;OAGG;IACH,mBAAmB,CAClB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;;OAMG;IACH,cAAc,CACb,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1F;;;;;;OAMG;IACH,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/D;;;;;;;OAOG;IACH,aAAa,CAAC,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACpD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-256-GCM envelope for at-rest secrets (e.g. compute API keys).
|
|
3
|
+
*
|
|
4
|
+
* Wire format: `enc:v1:<base64(iv|tag|ciphertext)>`. The version prefix lets
|
|
5
|
+
* us migrate to a new algorithm later without ambiguity. Plaintext never sits
|
|
6
|
+
* at rest — on disk (local provider) or in the DB (Supabase provider).
|
|
7
|
+
*
|
|
8
|
+
* Security model: defends against backup leaks, accidental file/DB sharing,
|
|
9
|
+
* and read-only storage access. An attacker with both the stored ciphertext
|
|
10
|
+
* *and* the master key (`SELVA_AT_REST_KEY` env var, process memory) can still
|
|
11
|
+
* decrypt — this is encryption at rest, not a secret manager.
|
|
12
|
+
*
|
|
13
|
+
* Provider-agnostic: pure `node:crypto`, no fs or DB coupling, so both the
|
|
14
|
+
* local and Supabase compute-server stores share this one implementation.
|
|
15
|
+
*/
|
|
16
|
+
export declare function isEncryptedSecret(value: string): boolean;
|
|
17
|
+
export declare function encryptSecret(plaintext: string, key: Buffer): string;
|
|
18
|
+
export declare function decryptSecret(envelope: string, key: Buffer): string;
|
|
19
|
+
/**
|
|
20
|
+
* Decode a `SELVA_AT_REST_KEY` env var into a 32-byte buffer. Accepts either
|
|
21
|
+
* 64-char hex or base64 (with or without padding). Throws on anything else
|
|
22
|
+
* so misconfiguration fails loudly at boot rather than silently producing
|
|
23
|
+
* an undecryptable value.
|
|
24
|
+
*/
|
|
25
|
+
export declare function decodeSecretKey(raw: string): Buffer;
|
|
26
|
+
/**
|
|
27
|
+
* Result of a compute-server store's `verifySecrets()`. One `failures` entry
|
|
28
|
+
* per server whose `apiKey` couldn't be loaded:
|
|
29
|
+
* - `plaintext_on_disk` — the field exists but isn't an `enc:v1:` envelope.
|
|
30
|
+
* Either a hand-edit, a legacy row from before encryption, or a migration
|
|
31
|
+
* regression. Security-relevant.
|
|
32
|
+
* - `key_mismatch` — envelope is valid but GCM auth-tag verification
|
|
33
|
+
* fails under the current `SELVA_AT_REST_KEY`. The key was rotated or the
|
|
34
|
+
* data came from another deployment.
|
|
35
|
+
*
|
|
36
|
+
* Storage-agnostic (`plaintext_on_disk` reads "plaintext at rest" for both the
|
|
37
|
+
* file- and DB-backed stores) so boot health can treat every provider alike.
|
|
38
|
+
*/
|
|
39
|
+
export type SecretVerificationFailureReason = 'key_mismatch' | 'plaintext_on_disk';
|
|
40
|
+
export interface SecretVerificationFailure {
|
|
41
|
+
serverId: string;
|
|
42
|
+
serverLabel: string;
|
|
43
|
+
reason: SecretVerificationFailureReason;
|
|
44
|
+
/** Underlying error message for `key_mismatch`. Absent for plaintext. */
|
|
45
|
+
cause?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface SecretVerificationReport {
|
|
48
|
+
ok: boolean;
|
|
49
|
+
failures: SecretVerificationFailure[];
|
|
50
|
+
/** True if at least one row holds an unencrypted apiKey at rest. */
|
|
51
|
+
plaintextFound: boolean;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=secrets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/computeServer/secrets.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;GAcG;AAEH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAYpE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAcnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,+BAA+B,GAAG,cAAc,GAAG,mBAAmB,CAAC;AAEnF,MAAM,WAAW,yBAAyB;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,+BAA+B,CAAC;IACxC,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACxC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,oEAAoE;IACpE,cAAc,EAAE,OAAO,CAAC;CACxB"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';
|
|
2
|
+
const ALGO = 'aes-256-gcm';
|
|
3
|
+
const IV_BYTES = 12;
|
|
4
|
+
const TAG_BYTES = 16;
|
|
5
|
+
const PREFIX = 'enc:v1:';
|
|
6
|
+
/**
|
|
7
|
+
* AES-256-GCM envelope for at-rest secrets (e.g. compute API keys).
|
|
8
|
+
*
|
|
9
|
+
* Wire format: `enc:v1:<base64(iv|tag|ciphertext)>`. The version prefix lets
|
|
10
|
+
* us migrate to a new algorithm later without ambiguity. Plaintext never sits
|
|
11
|
+
* at rest — on disk (local provider) or in the DB (Supabase provider).
|
|
12
|
+
*
|
|
13
|
+
* Security model: defends against backup leaks, accidental file/DB sharing,
|
|
14
|
+
* and read-only storage access. An attacker with both the stored ciphertext
|
|
15
|
+
* *and* the master key (`SELVA_AT_REST_KEY` env var, process memory) can still
|
|
16
|
+
* decrypt — this is encryption at rest, not a secret manager.
|
|
17
|
+
*
|
|
18
|
+
* Provider-agnostic: pure `node:crypto`, no fs or DB coupling, so both the
|
|
19
|
+
* local and Supabase compute-server stores share this one implementation.
|
|
20
|
+
*/
|
|
21
|
+
export function isEncryptedSecret(value) {
|
|
22
|
+
return value.startsWith(PREFIX);
|
|
23
|
+
}
|
|
24
|
+
export function encryptSecret(plaintext, key) {
|
|
25
|
+
if (key.length !== 32) {
|
|
26
|
+
throw new Error(`Secret key must be 32 bytes; got ${key.length}`);
|
|
27
|
+
}
|
|
28
|
+
if (isEncryptedSecret(plaintext)) {
|
|
29
|
+
throw new Error('Refusing to encrypt a value that is already encrypted');
|
|
30
|
+
}
|
|
31
|
+
const iv = randomBytes(IV_BYTES);
|
|
32
|
+
const cipher = createCipheriv(ALGO, key, iv);
|
|
33
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
34
|
+
const tag = cipher.getAuthTag();
|
|
35
|
+
return PREFIX + Buffer.concat([iv, tag, ciphertext]).toString('base64');
|
|
36
|
+
}
|
|
37
|
+
export function decryptSecret(envelope, key) {
|
|
38
|
+
if (key.length !== 32) {
|
|
39
|
+
throw new Error(`Secret key must be 32 bytes; got ${key.length}`);
|
|
40
|
+
}
|
|
41
|
+
if (!isEncryptedSecret(envelope)) {
|
|
42
|
+
throw new Error('Value is not an encrypted secret envelope');
|
|
43
|
+
}
|
|
44
|
+
const buf = Buffer.from(envelope.slice(PREFIX.length), 'base64');
|
|
45
|
+
const iv = buf.subarray(0, IV_BYTES);
|
|
46
|
+
const tag = buf.subarray(IV_BYTES, IV_BYTES + TAG_BYTES);
|
|
47
|
+
const ciphertext = buf.subarray(IV_BYTES + TAG_BYTES);
|
|
48
|
+
const decipher = createDecipheriv(ALGO, key, iv);
|
|
49
|
+
decipher.setAuthTag(tag);
|
|
50
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('utf8');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Decode a `SELVA_AT_REST_KEY` env var into a 32-byte buffer. Accepts either
|
|
54
|
+
* 64-char hex or base64 (with or without padding). Throws on anything else
|
|
55
|
+
* so misconfiguration fails loudly at boot rather than silently producing
|
|
56
|
+
* an undecryptable value.
|
|
57
|
+
*/
|
|
58
|
+
export function decodeSecretKey(raw) {
|
|
59
|
+
if (/^[0-9a-fA-F]{64}$/.test(raw))
|
|
60
|
+
return Buffer.from(raw, 'hex');
|
|
61
|
+
const buf = Buffer.from(raw, 'base64');
|
|
62
|
+
if (buf.length === 32)
|
|
63
|
+
return buf;
|
|
64
|
+
throw new Error('SELVA_AT_REST_KEY must be 32 bytes encoded as 64-char hex or base64. ' +
|
|
65
|
+
"Generate one with: node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"");
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/computeServer/secrets.ts"],"names":[],"mappings":"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"}
|
package/dist/context.d.ts
CHANGED
|
@@ -38,4 +38,11 @@ export declare const SYSTEM_CONTEXT: RequestContext;
|
|
|
38
38
|
* `actingOrgId` returns false unless `instance_admin` or `system`.
|
|
39
39
|
*/
|
|
40
40
|
export declare function hasPermission(ctx: RequestContext, permission: PlatformPermission | OrgPermission): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Return the org the caller is acting as, or throw `ProviderError(403)` when
|
|
43
|
+
* the context has none. Stores that scope every row to an acting org repeat
|
|
44
|
+
* this guard; centralizing it keeps the failure a single, consistent 403
|
|
45
|
+
* rather than a `null` that leaks into a query as `org_id = undefined`.
|
|
46
|
+
*/
|
|
47
|
+
export declare function requireActingOrg(ctx: RequestContext): string;
|
|
41
48
|
//# sourceMappingURL=context.d.ts.map
|
package/dist/context.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC9B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,6CAA6C;IAC7C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,wCAAwC;IACxC,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,cAK5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,kBAAkB,GAAG,aAAa,GAC5C,OAAO,CAOT;AAQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAK5D"}
|
package/dist/context.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ALL_PLATFORM_PERMISSIONS } from './permissions/types.js';
|
|
2
2
|
import { ALL_ORG_PERMISSIONS } from './organizations/schemas.js';
|
|
3
|
+
import { ProviderError } from './errors.js';
|
|
3
4
|
/**
|
|
4
5
|
* For server-internal operations outside any HTTP request (bootstrap,
|
|
5
6
|
* janitors, migrations). Treated as fully authorized.
|
|
@@ -29,4 +30,16 @@ const PLATFORM_PERMISSION_VALUES = new Set(ALL_PLATFORM_PERMISSIONS);
|
|
|
29
30
|
function isPlatformPermission(p) {
|
|
30
31
|
return PLATFORM_PERMISSION_VALUES.has(p);
|
|
31
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Return the org the caller is acting as, or throw `ProviderError(403)` when
|
|
35
|
+
* the context has none. Stores that scope every row to an acting org repeat
|
|
36
|
+
* this guard; centralizing it keeps the failure a single, consistent 403
|
|
37
|
+
* rather than a `null` that leaks into a query as `org_id = undefined`.
|
|
38
|
+
*/
|
|
39
|
+
export function requireActingOrg(ctx) {
|
|
40
|
+
if (!ctx.actingOrgId) {
|
|
41
|
+
throw new ProviderError('No acting organization in context', 403);
|
|
42
|
+
}
|
|
43
|
+
return ctx.actingOrgId;
|
|
44
|
+
}
|
|
32
45
|
//# sourceMappingURL=context.js.map
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA8B5C;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC7C,MAAM,EAAE,EAAE;IACV,mBAAmB,EAAE,CAAC,GAAG,wBAAwB,CAAC;IAClD,cAAc,EAAE,CAAC,GAAG,mBAAmB,CAAC;IACxC,MAAM,EAAE,IAAI;CACZ,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC5B,GAAmB,EACnB,UAA8C;IAE9C,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC5B,IAAI,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE7E,SAAS,oBAAoB,CAAC,CAAS;IACtC,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAmB;IACnD,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,IAAI,aAAa,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,CAAC;AACxB,CAAC"}
|
package/dist/data/interface.d.ts
CHANGED
|
@@ -21,7 +21,21 @@ import type { IInviteStore } from '../invites/interface.js';
|
|
|
21
21
|
import type { IUserProfileStore } from '../userProfile/interface.js';
|
|
22
22
|
import type { IPlatformPermissionStore } from '../permissions/interface.js';
|
|
23
23
|
import type { IAuditQuery } from '../events/audit.js';
|
|
24
|
+
import type { IEventSink } from '../events/interface.js';
|
|
24
25
|
import type { RequestContext } from '../context.js';
|
|
26
|
+
/**
|
|
27
|
+
* Result of the app↔DB schema handshake (audit O3). `expected` is the
|
|
28
|
+
* migration head the running app was built against; `actual` is what the
|
|
29
|
+
* database reports (`null` when the database can't even answer — e.g. the
|
|
30
|
+
* handshake function itself was never migrated in).
|
|
31
|
+
*/
|
|
32
|
+
export interface SchemaVersionReport {
|
|
33
|
+
ok: boolean;
|
|
34
|
+
expected: string;
|
|
35
|
+
actual: string | null;
|
|
36
|
+
/** Operator-facing explanation + recovery hint when not ok. */
|
|
37
|
+
message?: string;
|
|
38
|
+
}
|
|
25
39
|
export interface IDataProvider {
|
|
26
40
|
orgs: IOrgStore;
|
|
27
41
|
projects: IProjectStore;
|
|
@@ -38,6 +52,25 @@ export interface IDataProvider {
|
|
|
38
52
|
* `/admin/audit` UI degrades to its "no backend wired" state.
|
|
39
53
|
*/
|
|
40
54
|
auditQuery?: IAuditQuery;
|
|
55
|
+
/**
|
|
56
|
+
* The write-side event sink this provider's stores emit into. Optional —
|
|
57
|
+
* exposed so app code with no store mutation to piggyback on (e.g. the
|
|
58
|
+
* self-update route, audit O2) can emit domain events into the same log.
|
|
59
|
+
* Callers fall back to `NoopEventSink` when absent.
|
|
60
|
+
*/
|
|
61
|
+
events?: IEventSink;
|
|
62
|
+
/**
|
|
63
|
+
* App↔DB schema handshake (audit O3). Optional — implemented by adapters
|
|
64
|
+
* whose schema is migrated out-of-band (Supabase: `supabase db push` is a
|
|
65
|
+
* manual operator step the app can't run itself). Boot health calls this
|
|
66
|
+
* structurally (same pattern as `IComputeServerStore.verifySecrets`) and
|
|
67
|
+
* drives `/api/health` to 503 when the database is behind the app, so
|
|
68
|
+
* monitoring — and the self-update runner's health probe — catch schema
|
|
69
|
+
* skew instead of surfacing it as per-request store errors.
|
|
70
|
+
*
|
|
71
|
+
* MUST NOT throw: report failure via `ok: false`.
|
|
72
|
+
*/
|
|
73
|
+
verifySchemaVersion?(): Promise<SchemaVersionReport>;
|
|
41
74
|
/**
|
|
42
75
|
* Idempotently register a user in the data layer. Called by `hooks.server.ts`
|
|
43
76
|
* after `verifyToken` succeeds, so the data layer always has a row for the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/data/interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,EAAE,mBAAmB,CAAC;IACnC,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,WAAW,EAAE,wBAAwB,CAAC;IACtC,qBAAqB,EAAE,0BAA0B,CAAC;IAClD;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/data/interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAClE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAC5E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,WAAW,mBAAmB;IACnC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,WAAW,EAAE,gBAAgB,CAAC;IAC9B,aAAa,EAAE,mBAAmB,CAAC;IACnC,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,eAAe,CAAC;IAC5B,WAAW,EAAE,iBAAiB,CAAC;IAC/B,WAAW,EAAE,wBAAwB,CAAC;IACtC,qBAAqB,EAAE,0BAA0B,CAAC;IAClD;;;;OAIG;IACH,UAAU,CAAC,EAAE,WAAW,CAAC;IACzB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAErD;;;;;;;;;;;OAWG;IACH,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/D;;;;;;;;;;OAUG;IACH,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE"}
|
|
@@ -22,8 +22,26 @@ export interface IDefinitionStore {
|
|
|
22
22
|
create(ctx: RequestContext, record: DefinitionRecord): Promise<void>;
|
|
23
23
|
update(ctx: RequestContext, guid: string, patch: DefinitionRecordPatch): Promise<void>;
|
|
24
24
|
delete(ctx: RequestContext, guid: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Cascade hook: soft-delete every live definition in a project. Called by
|
|
27
|
+
* `IProjectStore.deleteProject` — a deleted project must never keep serving
|
|
28
|
+
* its definitions (they surface in the library/public listings independent
|
|
29
|
+
* of the project row). No-op when the project has none. Mirrors the
|
|
30
|
+
* `deleteByProject` cascade hooks on `IPlatformProjectGrantStore`.
|
|
31
|
+
*/
|
|
32
|
+
deleteByProject(ctx: RequestContext, projectId: string): Promise<void>;
|
|
25
33
|
/** Atomic +1 on the solve counter. No-op if the record doesn't exist. */
|
|
26
34
|
incrementSolveCount(ctx: RequestContext, guid: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* Atomically reserve the next `versionNumber` for a new version: returns the
|
|
37
|
+
* current `nextVersionNumber` and advances the counter by 1 in a single
|
|
38
|
+
* operation (so concurrent uploads never collide on a number/fileKey). The
|
|
39
|
+
* counter is monotonic and NEVER decremented — deleting the latest version
|
|
40
|
+
* does not free its number, so a delete-then-reupload mints a fresh number and
|
|
41
|
+
* fresh `fileKey` instead of overwriting the deleted blob's key. Throws if the
|
|
42
|
+
* definition doesn't exist.
|
|
43
|
+
*/
|
|
44
|
+
reserveNextVersionNumber(ctx: RequestContext, guid: string): Promise<number>;
|
|
27
45
|
createVersion(ctx: RequestContext, version: DefinitionVersion): Promise<void>;
|
|
28
46
|
/** Newest first by `versionNumber`. */
|
|
29
47
|
listVersions(ctx: RequestContext, definitionId: string, opts?: ListOptions): Promise<Page<DefinitionVersion>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/definitions/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE7F;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAEhC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACzF,aAAa,CACZ,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnC;;;;OAIG;IACH,UAAU,CACT,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE,qBAAqB,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/C,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvF,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD,yEAAyE;IACzE,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/definitions/interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,6 +54,7 @@ export declare const UpdateMetadataInputSchema: z.ZodObject<{
|
|
|
54
54
|
tags: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
|
|
55
55
|
projectId: z.ZodOptional<z.ZodString>;
|
|
56
56
|
computeServerId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
57
|
+
solveCacheLimit: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
57
58
|
status: z.ZodOptional<z.ZodEnum<{
|
|
58
59
|
draft: "draft";
|
|
59
60
|
published: "published";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/definitions/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,UAAU,QAAoE,CAAC;AAE5F,eAAO,MAAM,UAAU,aAAsD,CAAC;AAE9E,eAAO,MAAM,sBAAsB;;;;EAA6C,CAAC;AAEjF,eAAO,MAAM,uBAAuB;;;EAAwB,CAAC;AAE7D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;iBAclC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;EAA4B,CAAC;AAEjE,oDAAoD;AACpD,eAAO,MAAM,2BAA2B;;;;;;;;iBAQtC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/definitions/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,UAAU,QAAoE,CAAC;AAE5F,eAAO,MAAM,UAAU,aAAsD,CAAC;AAE9E,eAAO,MAAM,sBAAsB;;;;EAA6C,CAAC;AAEjF,eAAO,MAAM,uBAAuB;;;EAAwB,CAAC;AAE7D,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;;iBAclC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;EAA4B,CAAC;AAEjE,oDAAoD;AACpD,eAAO,MAAM,2BAA2B;;;;;;;;iBAQtC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;iBAYpC,CAAC;AAEH,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAC;AAE5E,uDAAuD;AACvD,eAAO,MAAM,yBAAyB;;kBAIzB,CAAC"}
|
|
@@ -43,6 +43,9 @@ export const UpdateMetadataInputSchema = z.object({
|
|
|
43
43
|
tags: z.array(z.string().max(64)).max(20).nullable().optional(),
|
|
44
44
|
projectId: GuidSchema.optional(),
|
|
45
45
|
computeServerId: GuidSchema.nullable().optional(),
|
|
46
|
+
// L2 cache quota (R9): 0 = off, N = per-definition entry cap, null = inherit
|
|
47
|
+
// the global default. Bounded so a settings typo can't request a runaway quota.
|
|
48
|
+
solveCacheLimit: z.number().int().min(0).max(100_000).nullable().optional(),
|
|
46
49
|
status: DefinitionStatusSchema.optional()
|
|
47
50
|
});
|
|
48
51
|
/** Body for `POST /api/definitions/[guid]/publish`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/definitions/schemas.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/definitions/schemas.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { IDataProvider } from '../data/interface.js';
|
|
2
|
+
import type { IStorageProvider } from '../storage/interface.js';
|
|
3
|
+
import type { RequestContext } from '../context.js';
|
|
4
|
+
import type { DefinitionRecord, DefinitionFileExt, DefinitionMeta } from './types.js';
|
|
5
|
+
import type { UpdateMetadataInput } from './schemas.js';
|
|
6
|
+
export interface CreateDefinitionInput {
|
|
7
|
+
guid: string;
|
|
8
|
+
projectId: string;
|
|
9
|
+
ownerId: string;
|
|
10
|
+
fileExt: DefinitionFileExt;
|
|
11
|
+
meta: DefinitionMeta;
|
|
12
|
+
computeServerId?: string;
|
|
13
|
+
maxHistory?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Default age threshold after which a 'pending' record is considered stale.
|
|
17
|
+
* Conservative — covers slow uploads over weak connections.
|
|
18
|
+
*/
|
|
19
|
+
export declare const PENDING_GC_AGE_MS: number;
|
|
20
|
+
/**
|
|
21
|
+
* Orchestrates writes that span IDataProvider + IStorageProvider.
|
|
22
|
+
*
|
|
23
|
+
* Ordering rules (see Phase 4 of the provider refactor):
|
|
24
|
+
*
|
|
25
|
+
* create — metadata-first:
|
|
26
|
+
* 1. Write record with status='pending'
|
|
27
|
+
* 2. Upload blob
|
|
28
|
+
* 3. Flip status to 'ready'
|
|
29
|
+
* If step 2 fails the record stays 'pending' with no blob. List queries
|
|
30
|
+
* filter 'pending' by default, so no consumer sees the half-written state.
|
|
31
|
+
* The janitor (gcStalePending) sweeps records older than PENDING_GC_AGE_MS.
|
|
32
|
+
*
|
|
33
|
+
* updateFile — best-effort with retry-safe shape:
|
|
34
|
+
* 1. Archive current file to history blob
|
|
35
|
+
* 2. Append history entry to record
|
|
36
|
+
* 3. Write new file to the active blob path
|
|
37
|
+
* 4. Prune history beyond maxHistory
|
|
38
|
+
* A failure between 2 and 3 leaves the record pointing at a missing active
|
|
39
|
+
* blob. The operation is idempotent — retrying with the same file restores
|
|
40
|
+
* a consistent state. This is an acknowledged limitation; the create path
|
|
41
|
+
* is where orphan risk is highest and is the one we fully guard.
|
|
42
|
+
*/
|
|
43
|
+
export declare class DefinitionService {
|
|
44
|
+
private data;
|
|
45
|
+
private storage;
|
|
46
|
+
constructor(data: IDataProvider, storage: IStorageProvider);
|
|
47
|
+
create(ctx: RequestContext, input: CreateDefinitionInput, file: Uint8Array): Promise<DefinitionRecord>;
|
|
48
|
+
updateFile(ctx: RequestContext, guid: string, file: Uint8Array, ext: DefinitionFileExt, originalName: string): Promise<void>;
|
|
49
|
+
updateMeta(ctx: RequestContext, guid: string, patch: UpdateMetadataInput): Promise<void>;
|
|
50
|
+
saveCoverImage(ctx: RequestContext, guid: string, imageData: Uint8Array): Promise<void>;
|
|
51
|
+
revertToVersion(ctx: RequestContext, guid: string, ref: string): Promise<void>;
|
|
52
|
+
delete(ctx: RequestContext, guid: string): Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Janitor — delete records stuck in 'pending' for longer than ageMs and
|
|
55
|
+
* any blobs they may have written. Safe to run on a schedule.
|
|
56
|
+
* Runs under SYSTEM_CONTEXT; callers don't pass one.
|
|
57
|
+
*
|
|
58
|
+
* @returns Number of records reclaimed.
|
|
59
|
+
*/
|
|
60
|
+
gcStalePending(ageMs?: number): Promise<number>;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/definitions/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAGpD,OAAO,KAAK,EACX,gBAAgB,EAEhB,iBAAiB,EACjB,cAAc,EACd,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAExD,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,IAAI,EAAE,cAAc,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,QAAiB,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,iBAAiB;IAE5B,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;gBADP,IAAI,EAAE,aAAa,EACnB,OAAO,EAAE,gBAAgB;IAG5B,MAAM,CACX,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,qBAAqB,EAC5B,IAAI,EAAE,UAAU,GACd,OAAO,CAAC,gBAAgB,CAAC;IAiCtB,UAAU,CACf,GAAG,EAAE,cAAc,EACnB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,GAAG,EAAE,iBAAiB,EACtB,YAAY,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAwCV,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAYxF,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAOvF,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9E,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQ9D;;;;;;OAMG;IACG,cAAc,CAAC,KAAK,GAAE,MAA0B,GAAG,OAAO,CAAC,MAAM,CAAC;CASxE"}
|