@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/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAgB9F,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAM5F,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAgB9F,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAM5F,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKtD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQpD,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,4BAA4B,CAAC;AAUpC,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACN,0BAA0B,EAC1B,gCAAgC,EAChC,MAAM,+BAA+B,CAAC;AAavC,OAAO,EACN,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EACN,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAMrE,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,sBAAsB,EACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAOhG,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAgBvD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAazE,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,0BAA0B,CAAC;AAclC,OAAO,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,SAAS,EACT,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAajE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAU7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAMjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAM9D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMhE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AASrE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const CreateInviteInputSchema: z.ZodObject<{
|
|
3
|
+
email: z.ZodPipe<z.ZodString, z.ZodTransform<string, string>>;
|
|
4
|
+
orgId: z.ZodString;
|
|
5
|
+
orgRole: z.ZodEnum<{
|
|
6
|
+
owner: "owner";
|
|
7
|
+
admin: "admin";
|
|
8
|
+
member: "member";
|
|
9
|
+
}>;
|
|
10
|
+
orgPermissions: z.ZodDefault<z.ZodArray<z.ZodEnum<{
|
|
11
|
+
manage_org_members: "manage_org_members";
|
|
12
|
+
manage_org_compute: "manage_org_compute";
|
|
13
|
+
manage_definitions: "manage_definitions";
|
|
14
|
+
manage_projects: "manage_projects";
|
|
15
|
+
}>>>;
|
|
16
|
+
}, z.core.$strip>;
|
|
17
|
+
export declare const AcceptInviteInputSchema: z.ZodObject<{
|
|
18
|
+
token: z.ZodString;
|
|
19
|
+
password: z.ZodString;
|
|
20
|
+
displayName: z.ZodOptional<z.ZodString>;
|
|
21
|
+
}, z.core.$strip>;
|
|
22
|
+
export type CreateInviteInput = z.infer<typeof CreateInviteInputSchema>;
|
|
23
|
+
export type AcceptInviteInput = z.infer<typeof AcceptInviteInputSchema>;
|
|
24
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/invites/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,uBAAuB;;;;;;;;;;;;;;iBAQlC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;iBAIlC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AACxE,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { OrgRoleSchema, OrgPermissionSchema } from '../organizations/schemas.js';
|
|
3
|
+
export const CreateInviteInputSchema = z.object({
|
|
4
|
+
email: z
|
|
5
|
+
.string()
|
|
6
|
+
.email('Valid email is required')
|
|
7
|
+
.transform((s) => s.toLowerCase()),
|
|
8
|
+
orgId: z.string().uuid(),
|
|
9
|
+
orgRole: OrgRoleSchema,
|
|
10
|
+
orgPermissions: z.array(OrgPermissionSchema).default([])
|
|
11
|
+
});
|
|
12
|
+
export const AcceptInviteInputSchema = z.object({
|
|
13
|
+
token: z.string().min(20),
|
|
14
|
+
password: z.string().min(8, 'Password must be at least 8 characters'),
|
|
15
|
+
displayName: z.string().trim().max(128).optional()
|
|
16
|
+
});
|
|
17
|
+
//# sourceMappingURL=schemas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/invites/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAEjF,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,CAAC;SACN,MAAM,EAAE;SACR,KAAK,CAAC,yBAAyB,CAAC;SAChC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACnC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE;IACxB,OAAO,EAAE,aAAa;IACtB,cAAc,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;CACxD,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IACzB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;IACrE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;CAClD,CAAC,CAAC"}
|
|
@@ -18,6 +18,12 @@ export type SolveFailureKind =
|
|
|
18
18
|
| 'share_cap'
|
|
19
19
|
/** Result exceeded the response size limit (HTTP 413). */
|
|
20
20
|
| 'too_large'
|
|
21
|
+
/**
|
|
22
|
+
* Shed by scheduler backpressure — the per-server queue was full, or the solve
|
|
23
|
+
* sat queued past its wait deadline, so it was rejected before executing
|
|
24
|
+
* (HTTP 503 + Retry-After). Distinct from `compute_error`: no compute ran.
|
|
25
|
+
*/
|
|
26
|
+
| 'shed'
|
|
21
27
|
/** Compute server unreachable or the solve threw for any other reason. */
|
|
22
28
|
| 'compute_error';
|
|
23
29
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/metrics/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB;AAC3B,gEAAgE;AAC9D,IAAI;AACN,8CAA8C;GAC5C,SAAS;AACX,4EAA4E;GAC1E,cAAc;AAChB,sEAAsE;GACpE,cAAc;AAChB,8DAA8D;GAC5D,WAAW;AACb,0DAA0D;GACxD,WAAW;AACb,0EAA0E;GACxE,eAAe,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC3B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qDAAqD;IACrD,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,sFAAsF;IACtF,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,EAAE,EAAE,OAAO,CAAC;IACZ,iEAAiE;IACjE,WAAW,EAAE,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,gBAAgB;IACrD,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CACvE"}
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/metrics/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB;AAC3B,gEAAgE;AAC9D,IAAI;AACN,8CAA8C;GAC5C,SAAS;AACX,4EAA4E;GAC1E,cAAc;AAChB,sEAAsE;GACpE,cAAc;AAChB,8DAA8D;GAC5D,WAAW;AACb,0DAA0D;GACxD,WAAW;AACb;;;;GAIG;GACD,MAAM;AACR,0EAA0E;GACxE,eAAe,CAAC;AAEnB;;;;;;;GAOG;AACH,MAAM,WAAW,WAAW;IAC3B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;OAIG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,qDAAqD;IACrD,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1B,+EAA+E;IAC/E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,sFAAsF;IACtF,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,EAAE,EAAE,OAAO,CAAC;IACZ,iEAAiE;IACjE,WAAW,EAAE,gBAAgB,CAAC;IAC9B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,YAAW,gBAAgB;IACrD,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CACvE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/metrics/interface.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/metrics/interface.ts"],"names":[],"mappings":"AAoFA;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAC/B,KAAK,CAAC,MAAM,CAAC,IAAoB,EAAE,OAAoB,IAAkB,CAAC;CAC1E"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export type { Organization, OrgMember } from './types.js';
|
|
1
|
+
export type { Organization, OrgMember, OrgAssets } from './types.js';
|
|
2
2
|
export type { IOrgStore } from './interface.js';
|
|
3
|
-
export
|
|
4
|
-
export {
|
|
3
|
+
export { orgPaths } from './paths.js';
|
|
4
|
+
export type { OrgRole, OrgPermission, OrgAssetKind, CreateOrgInput, UpdateOrgInput } from './schemas.js';
|
|
5
|
+
export { OrgRoleSchema, OrgPermissionSchema, OrgAssetKindSchema, ALL_ORG_ASSET_KINDS, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './schemas.js';
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EACX,OAAO,EACP,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,cAAc,CAAC"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { orgPaths } from './paths.js';
|
|
2
|
+
export { OrgRoleSchema, OrgPermissionSchema, OrgAssetKindSchema, ALL_ORG_ASSET_KINDS, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './schemas.js';
|
|
2
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQtC,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,cAAc,CAAC"}
|
|
@@ -11,7 +11,7 @@ export interface IOrgStore {
|
|
|
11
11
|
getOrg(ctx: RequestContext, id: string): Promise<Organization | null>;
|
|
12
12
|
getOrgBySlug(ctx: RequestContext, slug: string): Promise<Organization | null>;
|
|
13
13
|
createOrg(ctx: RequestContext, org: Organization): Promise<void>;
|
|
14
|
-
updateOrg(ctx: RequestContext, id: string, patch: Partial<Pick<Organization, 'name' | 'slug'>>): Promise<void>;
|
|
14
|
+
updateOrg(ctx: RequestContext, id: string, patch: Partial<Pick<Organization, 'name' | 'slug' | 'assets'>>): Promise<void>;
|
|
15
15
|
/**
|
|
16
16
|
* Soft-delete the org. Cascades soft-delete to org members, projects in the
|
|
17
17
|
* org, and project members. Definitions and share links cascade through the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/organizations/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,SAAS;IAEzB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/E,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACtE,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9E,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,CACR,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/organizations/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,SAAS;IAEzB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/E,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACtE,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9E,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,CACR,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG1D,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjG,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5F;;;;;;;;;;;;OAYG;IACH,kBAAkB,CACjB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,GAAG,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5D,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,mBAAmB,CAClB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;OAIG;IACH,0BAA0B,CACzB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,aAAa,EAAE,GACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { OrgAssetKind } from './schemas.js';
|
|
2
|
+
/**
|
|
3
|
+
* Storage keys for org-scoped assets. Every branding asset is stored as `.webp`
|
|
4
|
+
* (uploads are rasterized through the shared transcoder), so the path per kind
|
|
5
|
+
* is fixed — a re-upload overwrites in place via `IStorageProvider.put`'s
|
|
6
|
+
* upsert. The filename IS the kind, so the layout is generic: a new branding
|
|
7
|
+
* kind needs no new helper.
|
|
8
|
+
*
|
|
9
|
+
* Branding lives under `orgs/{id}/branding/` because it is a *public* asset
|
|
10
|
+
* class — anyone, incl. logged-out viewers, may read a company logo. The
|
|
11
|
+
* `branding/` segment keeps it distinguishable from future org-private blobs
|
|
12
|
+
* under `orgs/{id}/private/` (e.g. pricing sheets), which are members-only.
|
|
13
|
+
* The serving route and `getPublicUrl` decide public-vs-private by classifying
|
|
14
|
+
* these prefixes — see `classifyAssetPath` / `ASSET_CLASSES`.
|
|
15
|
+
*/
|
|
16
|
+
export declare const orgPaths: {
|
|
17
|
+
readonly asset: (id: string, kind: OrgAssetKind) => string;
|
|
18
|
+
/** Members-only blob under the org's private tier. `name` includes the extension. */
|
|
19
|
+
readonly privateAsset: (id: string, name: string) => string;
|
|
20
|
+
readonly prefix: (id: string) => string;
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/organizations/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAcjD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ;yBACR,MAAM,QAAQ,YAAY;IAKtC,qFAAqF;gCAClE,MAAM,QAAQ,MAAM;0BAK1B,MAAM;CAIV,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path-segment safety check. Blocks traversal, separators, NUL, and empty
|
|
3
|
+
* segments. Allowed alphabet `[A-Za-z0-9._-]+` covers GUIDs and sanitized
|
|
4
|
+
* refs. Called by every helper so a malicious `id` can't escape the
|
|
5
|
+
* `orgs/` prefix. Mirrors `definitionPaths`' guard.
|
|
6
|
+
*/
|
|
7
|
+
function assertSafeKey(value, label) {
|
|
8
|
+
if (!value || !/^[A-Za-z0-9._-]+$/.test(value) || value === '.' || value === '..') {
|
|
9
|
+
throw new Error(`Unsafe ${label}: ${JSON.stringify(value)}`);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Storage keys for org-scoped assets. Every branding asset is stored as `.webp`
|
|
14
|
+
* (uploads are rasterized through the shared transcoder), so the path per kind
|
|
15
|
+
* is fixed — a re-upload overwrites in place via `IStorageProvider.put`'s
|
|
16
|
+
* upsert. The filename IS the kind, so the layout is generic: a new branding
|
|
17
|
+
* kind needs no new helper.
|
|
18
|
+
*
|
|
19
|
+
* Branding lives under `orgs/{id}/branding/` because it is a *public* asset
|
|
20
|
+
* class — anyone, incl. logged-out viewers, may read a company logo. The
|
|
21
|
+
* `branding/` segment keeps it distinguishable from future org-private blobs
|
|
22
|
+
* under `orgs/{id}/private/` (e.g. pricing sheets), which are members-only.
|
|
23
|
+
* The serving route and `getPublicUrl` decide public-vs-private by classifying
|
|
24
|
+
* these prefixes — see `classifyAssetPath` / `ASSET_CLASSES`.
|
|
25
|
+
*/
|
|
26
|
+
export const orgPaths = {
|
|
27
|
+
asset: (id, kind) => {
|
|
28
|
+
assertSafeKey(id, 'orgId');
|
|
29
|
+
assertSafeKey(kind, 'assetKind');
|
|
30
|
+
return `orgs/${id}/branding/${kind}.webp`;
|
|
31
|
+
},
|
|
32
|
+
/** Members-only blob under the org's private tier. `name` includes the extension. */
|
|
33
|
+
privateAsset: (id, name) => {
|
|
34
|
+
assertSafeKey(id, 'orgId');
|
|
35
|
+
assertSafeKey(name, 'assetName');
|
|
36
|
+
return `orgs/${id}/private/${name}`;
|
|
37
|
+
},
|
|
38
|
+
prefix: (id) => {
|
|
39
|
+
assertSafeKey(id, 'orgId');
|
|
40
|
+
return `orgs/${id}/`;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/organizations/paths.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IAClD,IAAI,CAAC,KAAK,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACvB,KAAK,EAAE,CAAC,EAAU,EAAE,IAAkB,EAAE,EAAE;QACzC,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3B,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjC,OAAO,QAAQ,EAAE,aAAa,IAAI,OAAO,CAAC;IAC3C,CAAC;IACD,qFAAqF;IACrF,YAAY,EAAE,CAAC,EAAU,EAAE,IAAY,EAAE,EAAE;QAC1C,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3B,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjC,OAAO,QAAQ,EAAE,YAAY,IAAI,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,EAAE,CAAC,EAAU,EAAE,EAAE;QACtB,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3B,OAAO,QAAQ,EAAE,GAAG,CAAC;IACtB,CAAC;CACQ,CAAC"}
|
|
@@ -7,6 +7,16 @@ export declare const OrgRoleSchema: z.ZodEnum<{
|
|
|
7
7
|
member: "member";
|
|
8
8
|
}>;
|
|
9
9
|
export type OrgRole = z.infer<typeof OrgRoleSchema>;
|
|
10
|
+
/**
|
|
11
|
+
* Kinds of org-scoped branding asset. Adding a new kind is a single entry here
|
|
12
|
+
* — the storage path, upload route, store, and UI are all generic over it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const OrgAssetKindSchema: z.ZodEnum<{
|
|
15
|
+
logo: "logo";
|
|
16
|
+
favicon: "favicon";
|
|
17
|
+
}>;
|
|
18
|
+
export type OrgAssetKind = z.infer<typeof OrgAssetKindSchema>;
|
|
19
|
+
export declare const ALL_ORG_ASSET_KINDS: readonly OrgAssetKind[];
|
|
10
20
|
/** Org-scope permissions. A user may hold different sets in different orgs. */
|
|
11
21
|
export declare const OrgPermissionSchema: z.ZodEnum<{
|
|
12
22
|
manage_org_members: "manage_org_members";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/organizations/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gEAAgE;AAChE,eAAO,MAAM,UAAU,aAOrB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;EAAuC,CAAC;AAClE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB;;;;;EAK9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,mBAAmB,EAAE,SAAS,aAAa,EAAgC,CAAC;AAEzF,sDAAsD;AACtD,eAAO,MAAM,4BAA4B,EAAE,SAAS,aAAa,EAGhE,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,SAAS,aAAa,EAEjE,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAI7E,CAAC;AAEF,eAAO,MAAM,eAAe;;;iBAG1B,CAAC;AAEH,eAAO,MAAM,eAAe;;;iBAA4B,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC7D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/organizations/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gEAAgE;AAChE,eAAO,MAAM,UAAU,aAOrB,CAAC;AAEH,eAAO,MAAM,aAAa;;;;EAAuC,CAAC;AAClE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,kBAAkB;;;EAA8B,CAAC;AAC9D,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,mBAAmB,EAAE,SAAS,YAAY,EAA+B,CAAC;AAEvF,+EAA+E;AAC/E,eAAO,MAAM,mBAAmB;;;;;EAK9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,mBAAmB,EAAE,SAAS,aAAa,EAAgC,CAAC;AAEzF,sDAAsD;AACtD,eAAO,MAAM,4BAA4B,EAAE,SAAS,aAAa,EAGhE,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,SAAS,aAAa,EAEjE,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAI7E,CAAC;AAEF,eAAO,MAAM,eAAe;;;iBAG1B,CAAC;AAEH,eAAO,MAAM,eAAe;;;iBAA4B,CAAC;AAEzD,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAC7D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
|
@@ -6,6 +6,12 @@ export const SlugSchema = z
|
|
|
6
6
|
.max(63, 'Slug must be at most 63 characters')
|
|
7
7
|
.regex(/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/, 'Slug must be lowercase alphanumeric with hyphens (no leading/trailing/consecutive hyphens)');
|
|
8
8
|
export const OrgRoleSchema = z.enum(['owner', 'admin', 'member']);
|
|
9
|
+
/**
|
|
10
|
+
* Kinds of org-scoped branding asset. Adding a new kind is a single entry here
|
|
11
|
+
* — the storage path, upload route, store, and UI are all generic over it.
|
|
12
|
+
*/
|
|
13
|
+
export const OrgAssetKindSchema = z.enum(['logo', 'favicon']);
|
|
14
|
+
export const ALL_ORG_ASSET_KINDS = OrgAssetKindSchema.options;
|
|
9
15
|
/** Org-scope permissions. A user may hold different sets in different orgs. */
|
|
10
16
|
export const OrgPermissionSchema = z.enum([
|
|
11
17
|
'manage_org_members',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/organizations/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gEAAgE;AAChE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACzB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,oCAAoC,CAAC;KAC5C,GAAG,CAAC,EAAE,EAAE,oCAAoC,CAAC;KAC7C,KAAK,CACL,iCAAiC,EACjC,4FAA4F,CAC5F,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGlE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC;IACzC,oBAAoB;IACpB,oBAAoB;IACpB,oBAAoB;IACpB,iBAAiB;CACjB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,mBAAmB,GAA6B,mBAAmB,CAAC,OAAO,CAAC;AAEzF,sDAAsD;AACtD,MAAM,CAAC,MAAM,4BAA4B,GAA6B;IACrE,oBAAoB;IACpB,oBAAoB;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAA6B,mBAAmB,CAAC,MAAM,CAChG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAChD,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAA8C;IACjF,KAAK,EAAE,CAAC,GAAG,mBAAmB,CAAC;IAC/B,KAAK,EAAE,CAAC,GAAG,mBAAmB,CAAC;IAC/B,MAAM,EAAE,EAAE;CACV,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,+BAA+B,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjE,IAAI,EAAE,UAAU;CAChB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/organizations/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gEAAgE;AAChE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC;KACzB,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,EAAE,oCAAoC,CAAC;KAC5C,GAAG,CAAC,EAAE,EAAE,oCAAoC,CAAC;KAC7C,KAAK,CACL,iCAAiC,EACjC,4FAA4F,CAC5F,CAAC;AAEH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGlE;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAG9D,MAAM,CAAC,MAAM,mBAAmB,GAA4B,kBAAkB,CAAC,OAAO,CAAC;AAEvF,+EAA+E;AAC/E,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,IAAI,CAAC;IACzC,oBAAoB;IACpB,oBAAoB;IACpB,oBAAoB;IACpB,iBAAiB;CACjB,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,mBAAmB,GAA6B,mBAAmB,CAAC,OAAO,CAAC;AAEzF,sDAAsD;AACtD,MAAM,CAAC,MAAM,4BAA4B,GAA6B;IACrE,oBAAoB;IACpB,oBAAoB;CACpB,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAA6B,mBAAmB,CAAC,MAAM,CAChG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,4BAA4B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAChD,CAAC;AAEF,yEAAyE;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAA8C;IACjF,KAAK,EAAE,CAAC,GAAG,mBAAmB,CAAC;IAC/B,KAAK,EAAE,CAAC,GAAG,mBAAmB,CAAC;IAC/B,MAAM,EAAE,EAAE;CACV,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,+BAA+B,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IACjE,IAAI,EAAE,UAAU;CAChB,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC"}
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import type { OrgRole, OrgPermission } from './schemas.js';
|
|
1
|
+
import type { OrgRole, OrgPermission, OrgAssetKind } from './schemas.js';
|
|
2
|
+
/**
|
|
3
|
+
* Public URLs of an org's branding assets, keyed by kind. Each value is what
|
|
4
|
+
* `IStorageProvider.getPublicUrl` returned for the stored blob; a kind is
|
|
5
|
+
* absent when unset. One small map so adding a new asset kind never touches
|
|
6
|
+
* the `Organization` shape, the migration, or the row mappers again.
|
|
7
|
+
*/
|
|
8
|
+
export type OrgAssets = Partial<Record<OrgAssetKind, string>>;
|
|
2
9
|
export interface Organization {
|
|
3
10
|
id: string;
|
|
4
11
|
name: string;
|
|
@@ -9,6 +16,8 @@ export interface Organization {
|
|
|
9
16
|
/** Immutable even on ownership transfer. */
|
|
10
17
|
createdBy: string;
|
|
11
18
|
updatedBy: string;
|
|
19
|
+
/** Branding assets (logo, favicon, …) by kind. Blobs live under `orgPaths.asset()`. */
|
|
20
|
+
assets?: OrgAssets;
|
|
12
21
|
createdAt: string;
|
|
13
22
|
updatedAt: string;
|
|
14
23
|
deletedAt?: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/organizations/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/organizations/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEzE;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,OAAO,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,uFAAuF;IACvF,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Organization and Project provider interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Models a three-level ownership hierarchy:
|
|
5
|
+
* Platform → Organization → Project → Definition
|
|
6
|
+
*
|
|
7
|
+
* Implement for any backend:
|
|
8
|
+
* - Local JSON files (built-in default)
|
|
9
|
+
* - Supabase (row-level security tables)
|
|
10
|
+
* - Firebase Firestore
|
|
11
|
+
* - Any relational database
|
|
12
|
+
*/
|
|
13
|
+
export interface Organization {
|
|
14
|
+
/** UUID v4 primary key */
|
|
15
|
+
id: string;
|
|
16
|
+
/** Human-readable display name */
|
|
17
|
+
name: string;
|
|
18
|
+
/** URL-safe unique identifier, e.g. "acme-corp" */
|
|
19
|
+
slug: string;
|
|
20
|
+
/** UUID of the user who owns this org */
|
|
21
|
+
ownerId: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
updatedAt: string;
|
|
24
|
+
}
|
|
25
|
+
export type OrgRole = 'owner' | 'admin' | 'member';
|
|
26
|
+
export interface OrgMember {
|
|
27
|
+
orgId: string;
|
|
28
|
+
userId: string;
|
|
29
|
+
role: OrgRole;
|
|
30
|
+
joinedAt: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Who can invoke solve on definitions in this project:
|
|
34
|
+
* - 'public' — any authenticated user
|
|
35
|
+
* - 'org' — any member of the parent organization
|
|
36
|
+
* - 'private' — only users listed in ProjectMember
|
|
37
|
+
*/
|
|
38
|
+
export type ProjectVisibility = 'public' | 'org' | 'private';
|
|
39
|
+
export type ProjectRole = 'owner' | 'editor' | 'viewer';
|
|
40
|
+
export interface Project {
|
|
41
|
+
/** UUID v4 primary key */
|
|
42
|
+
id: string;
|
|
43
|
+
/** UUID of the owning organization */
|
|
44
|
+
orgId: string;
|
|
45
|
+
name: string;
|
|
46
|
+
/** URL-safe, unique within the organization */
|
|
47
|
+
slug: string;
|
|
48
|
+
description?: string;
|
|
49
|
+
visibility: ProjectVisibility;
|
|
50
|
+
/** UUID of the user who created this project */
|
|
51
|
+
ownerId: string;
|
|
52
|
+
createdAt: string;
|
|
53
|
+
updatedAt: string;
|
|
54
|
+
}
|
|
55
|
+
export interface ProjectMember {
|
|
56
|
+
projectId: string;
|
|
57
|
+
userId: string;
|
|
58
|
+
role: ProjectRole;
|
|
59
|
+
joinedAt: string;
|
|
60
|
+
}
|
|
61
|
+
export interface IOrganizationProvider {
|
|
62
|
+
listOrgs(): Promise<Organization[]>;
|
|
63
|
+
getOrg(id: string): Promise<Organization | null>;
|
|
64
|
+
getOrgBySlug(slug: string): Promise<Organization | null>;
|
|
65
|
+
createOrg(org: Organization): Promise<void>;
|
|
66
|
+
/** Patch mutable org fields. Only name and slug may be changed after creation. */
|
|
67
|
+
updateOrg(id: string, patch: Partial<Pick<Organization, 'name' | 'slug'>>): Promise<void>;
|
|
68
|
+
/** Delete an org and all its projects (cascade is implementation-specific). */
|
|
69
|
+
deleteOrg(id: string): Promise<void>;
|
|
70
|
+
listOrgMembers(orgId: string): Promise<OrgMember[]>;
|
|
71
|
+
getOrgMember(orgId: string, userId: string): Promise<OrgMember | null>;
|
|
72
|
+
addOrgMember(member: OrgMember): Promise<void>;
|
|
73
|
+
updateOrgMemberRole(orgId: string, userId: string, role: OrgRole): Promise<void>;
|
|
74
|
+
removeOrgMember(orgId: string, userId: string): Promise<void>;
|
|
75
|
+
listProjects(orgId: string): Promise<Project[]>;
|
|
76
|
+
getProject(id: string): Promise<Project | null>;
|
|
77
|
+
getProjectBySlug(orgId: string, slug: string): Promise<Project | null>;
|
|
78
|
+
createProject(project: Project): Promise<void>;
|
|
79
|
+
updateProject(id: string, patch: Partial<Pick<Project, 'name' | 'slug' | 'description' | 'visibility'>>): Promise<void>;
|
|
80
|
+
deleteProject(id: string): Promise<void>;
|
|
81
|
+
listProjectMembers(projectId: string): Promise<ProjectMember[]>;
|
|
82
|
+
getProjectMember(projectId: string, userId: string): Promise<ProjectMember | null>;
|
|
83
|
+
addProjectMember(member: ProjectMember): Promise<void>;
|
|
84
|
+
updateProjectMemberRole(projectId: string, userId: string, role: ProjectRole): Promise<void>;
|
|
85
|
+
removeProjectMember(projectId: string, userId: string): Promise<void>;
|
|
86
|
+
/** Returns true if the user may invoke solve on any definition in the project. */
|
|
87
|
+
canSolve(userId: string, projectId: string): Promise<boolean>;
|
|
88
|
+
/** Returns true if the user may upload or modify definitions in the project. */
|
|
89
|
+
canEdit(userId: string, projectId: string): Promise<boolean>;
|
|
90
|
+
/** Returns true if the user may manage project members and settings. */
|
|
91
|
+
canManage(userId: string, projectId: string): Promise<boolean>;
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=organizations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organizations.d.ts","sourceRoot":"","sources":["../src/organizations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Organization and Project provider interfaces.
|
|
3
|
+
*
|
|
4
|
+
* Models a three-level ownership hierarchy:
|
|
5
|
+
* Platform → Organization → Project → Definition
|
|
6
|
+
*
|
|
7
|
+
* Implement for any backend:
|
|
8
|
+
* - Local JSON files (built-in default)
|
|
9
|
+
* - Supabase (row-level security tables)
|
|
10
|
+
* - Firebase Firestore
|
|
11
|
+
* - Any relational database
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=organizations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"organizations.js","sourceRoot":"","sources":["../src/organizations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { RequestContext } from '../context.js';
|
|
2
|
+
/**
|
|
3
|
+
* Durable L2 solve-result cache (H1). The scheduler's in-process `Map` is L1 —
|
|
4
|
+
* 20 entries, 5-min TTL, per app instance. This is the shared, longer-lived
|
|
5
|
+
* layer keyed on `(orgId, definitionId, versionId, inputKey)` where `inputKey`
|
|
6
|
+
* is a wide (SHA-256) hash of the transformed input tree plus the solve-affecting
|
|
7
|
+
* config subset (H2/R8). A hit skips compute entirely.
|
|
8
|
+
*
|
|
9
|
+
* Design contract (decided 2026-07-11):
|
|
10
|
+
*
|
|
11
|
+
* - **Async from day one.** The memory backend returns promises too, so no call
|
|
12
|
+
* site changes shape when a network store (Redis) arrives later.
|
|
13
|
+
* - **Entries are opaque bytes** — the pre-gzipped response envelope (R6) plus a
|
|
14
|
+
* small metadata header. The backend never inspects them; memory stores the
|
|
15
|
+
* same buffer Redis would, so a hit stays near-CPU-free in either backend and
|
|
16
|
+
* there is no serialization drift between impls.
|
|
17
|
+
* - **Best-effort.** `get` may miss at any time (restart, eviction, network
|
|
18
|
+
* blip); `set` may silently drop. Correctness NEVER depends on cache presence —
|
|
19
|
+
* this is what makes backends interchangeable and what makes the
|
|
20
|
+
* no-TTL/versionId keying safe under any eviction policy.
|
|
21
|
+
* - **Per-definition quota, passed at write time.** `set` carries
|
|
22
|
+
* `maxEntriesForDefinition` so the backend holds no policy, only data. Eviction
|
|
23
|
+
* is LRU *within* the definition: a slider-heavy definition churns only its own
|
|
24
|
+
* entries, not everyone else's.
|
|
25
|
+
* - **Version keying = no invalidation.** Publishing mints a new `versionId` →
|
|
26
|
+
* fresh keyspace; rollback re-hits old entries; there is nothing to invalidate.
|
|
27
|
+
*/
|
|
28
|
+
/** The parts that address a cached solve. All four are folded into the stored key. */
|
|
29
|
+
export interface SolveCacheKey {
|
|
30
|
+
/**
|
|
31
|
+
* Owning org (defense-in-depth against cross-tenant reads). Null for
|
|
32
|
+
* remote-URL solves that have no org — those are not cached (the app passes
|
|
33
|
+
* the cache hook only for org-scoped live-channel solves).
|
|
34
|
+
*/
|
|
35
|
+
orgId: string;
|
|
36
|
+
/** The definition guid — the quota scope. */
|
|
37
|
+
definitionId: string;
|
|
38
|
+
/** The immutable version id — no TTL needed, so entries never go stale. */
|
|
39
|
+
versionId: string;
|
|
40
|
+
/**
|
|
41
|
+
* Wide hash of the transformed input tree + solve-affecting config subset
|
|
42
|
+
* (SHA-256 hex; see the pipeline's key builder). This is the only part that
|
|
43
|
+
* varies per solve of a given version.
|
|
44
|
+
*/
|
|
45
|
+
inputKey: string;
|
|
46
|
+
}
|
|
47
|
+
/** Options for a write; carries the per-definition quota so the backend stays stateless. */
|
|
48
|
+
export interface SolveCacheSetOptions {
|
|
49
|
+
/**
|
|
50
|
+
* Max cached entries this definition may retain. The backend evicts
|
|
51
|
+
* LRU-within-definition down to this count on write. A definition's quota is
|
|
52
|
+
* `solveCacheLimit` (absent → the global default); the app never calls `set`
|
|
53
|
+
* when the resolved quota is `0` (caching off), so this is always `>= 1`.
|
|
54
|
+
*/
|
|
55
|
+
maxEntriesForDefinition: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Durable solve-result cache. The solve pipeline talks only to this interface;
|
|
59
|
+
* the backend (memory today, Redis later) is a config change, not a redesign.
|
|
60
|
+
*
|
|
61
|
+
* Implementations MUST NOT throw — both methods are best-effort on the hot path
|
|
62
|
+
* of every live solve. A backend failure resolves as a miss (`get`) or a silent
|
|
63
|
+
* drop (`set`); it never becomes a request error.
|
|
64
|
+
*/
|
|
65
|
+
export interface ISolveResultCache {
|
|
66
|
+
/**
|
|
67
|
+
* Look up a cached envelope. Resolves the opaque bytes on a hit, or `null` on
|
|
68
|
+
* a miss (including any backend error). Bumps the entry's recency.
|
|
69
|
+
*/
|
|
70
|
+
get(ctx: RequestContext, key: SolveCacheKey): Promise<Uint8Array | null>;
|
|
71
|
+
/**
|
|
72
|
+
* Store an envelope, evicting LRU-within-definition down to
|
|
73
|
+
* `opts.maxEntriesForDefinition`. Best-effort: silently drops on any failure.
|
|
74
|
+
*/
|
|
75
|
+
set(ctx: RequestContext, key: SolveCacheKey, bytes: Uint8Array, opts: SolveCacheSetOptions): Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Default `ISolveResultCache` — never stores, always misses. Used when
|
|
79
|
+
* `SOLVE_CACHE_PROVIDER=off` (or unset). Swap in the memory backend
|
|
80
|
+
* (`@selvajs/server`) or a shared store to enable the durable L2.
|
|
81
|
+
*/
|
|
82
|
+
export declare class NoopSolveResultCache implements ISolveResultCache {
|
|
83
|
+
get(_ctx: RequestContext, _key: SolveCacheKey): Promise<Uint8Array | null>;
|
|
84
|
+
set(_ctx: RequestContext, _key: SolveCacheKey, _bytes: Uint8Array, _opts: SolveCacheSetOptions): Promise<void>;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/solveCache/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,4FAA4F;AAC5F,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,uBAAuB,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACzE;;;OAGG;IACH,GAAG,CACF,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,oBAAoB,GACxB,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IACvD,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAG1E,GAAG,CACR,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC;CAChB"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default `ISolveResultCache` — never stores, always misses. Used when
|
|
3
|
+
* `SOLVE_CACHE_PROVIDER=off` (or unset). Swap in the memory backend
|
|
4
|
+
* (`@selvajs/server`) or a shared store to enable the durable L2.
|
|
5
|
+
*/
|
|
6
|
+
export class NoopSolveResultCache {
|
|
7
|
+
async get(_ctx, _key) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
async set(_ctx, _key, _bytes, _opts) { }
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/solveCache/interface.ts"],"names":[],"mappings":"AAsFA;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAChC,KAAK,CAAC,GAAG,CAAC,IAAoB,EAAE,IAAmB;QAClD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,GAAG,CACR,IAAoB,EACpB,IAAmB,EACnB,MAAkB,EAClB,KAA2B,IACV,CAAC;CACnB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a stored asset is allowed to be read. This is a property of the asset
|
|
3
|
+
* *class* (its path prefix), never of the individual file — so a logo and a
|
|
4
|
+
* pricing sheet differ only in which class they belong to, and adding a new
|
|
5
|
+
* asset type is one entry in {@link ASSET_CLASSES} rather than a new route.
|
|
6
|
+
*
|
|
7
|
+
* - `public` — anyone, including logged-out visitors. Served with no auth via
|
|
8
|
+
* a CDN/public bucket (Supabase) or a shape-gated proxy branch (local). Used
|
|
9
|
+
* for branding (logo, favicon) that appears on viewer headers and login pages.
|
|
10
|
+
* - `org` — members of the owning org only. The route resolves the orgId
|
|
11
|
+
* from the path and runs an org-membership check. Used for org-private docs
|
|
12
|
+
* (e.g. pricing sheets) once they exist.
|
|
13
|
+
* - `project` — members of the owning project only. The route resolves the
|
|
14
|
+
* definition guid → its project and runs the project-view check. Used for
|
|
15
|
+
* definition cover images and other per-definition blobs.
|
|
16
|
+
*/
|
|
17
|
+
export type AssetVisibility = 'public' | 'org' | 'project';
|
|
18
|
+
/**
|
|
19
|
+
* What scope id the route must authorize against. `none` for public assets
|
|
20
|
+
* (no scope to check); `org`/`project` carry the id extracted from the path.
|
|
21
|
+
*/
|
|
22
|
+
export type AssetScope = 'none' | 'org' | 'project';
|
|
23
|
+
export interface AssetClass {
|
|
24
|
+
/** Stable identifier — for logging and tests, not user-facing. */
|
|
25
|
+
readonly id: string;
|
|
26
|
+
readonly visibility: AssetVisibility;
|
|
27
|
+
readonly scope: AssetScope;
|
|
28
|
+
/**
|
|
29
|
+
* Anchored matcher for this class's storage paths. Capture group 1 (when
|
|
30
|
+
* present) is the scope id (orgId or guid) the route authorizes against.
|
|
31
|
+
*/
|
|
32
|
+
readonly pattern: RegExp;
|
|
33
|
+
}
|
|
34
|
+
export interface AssetMatch {
|
|
35
|
+
readonly class: AssetClass;
|
|
36
|
+
/** The scope id from the path, or null for `scope: 'none'` classes. */
|
|
37
|
+
readonly scopeId: string | null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The closed registry of servable asset classes. Order matters only for
|
|
41
|
+
* readability — patterns are mutually exclusive by prefix. Anything that
|
|
42
|
+
* matches no class is unservable (the route 404s), which keeps the proxy
|
|
43
|
+
* default-deny: a new blob type is opt-in by adding an entry here.
|
|
44
|
+
*/
|
|
45
|
+
export declare const ASSET_CLASSES: readonly AssetClass[];
|
|
46
|
+
/**
|
|
47
|
+
* Classify a storage path into its asset class and scope id, or null when no
|
|
48
|
+
* class matches (or the path is unsafe). Callers — `getPublicUrl` (to pick CDN
|
|
49
|
+
* vs proxy) and the serving route (to pick the auth check) — consult this so
|
|
50
|
+
* URL generation and authorization never drift apart.
|
|
51
|
+
*
|
|
52
|
+
* For `org-branding` the orgId is captured as group 1 but the class is public,
|
|
53
|
+
* so `scopeId` is reported as the captured id only when the class actually
|
|
54
|
+
* authorizes against it (`scope !== 'none'`); public classes report null.
|
|
55
|
+
*/
|
|
56
|
+
export declare function classifyAssetPath(storagePath: string): AssetMatch | null;
|
|
57
|
+
/** True when the path belongs to a `public` asset class (CDN-servable, no auth). */
|
|
58
|
+
export declare function isPublicAssetPath(storagePath: string): boolean;
|
|
59
|
+
//# sourceMappingURL=assetClasses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assetClasses.d.ts","sourceRoot":"","sources":["../../src/storage/assetClasses.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEpD,MAAM,WAAW,UAAU;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAoBD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAqB9C,CAAC;AAoBF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQxE;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE9D"}
|