@selvajs/platform 0.17.0-beta.3 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -28
- package/dist/access/rules.d.ts +20 -26
- package/dist/access/rules.d.ts.map +1 -1
- package/dist/access/rules.js +16 -16
- package/dist/access/rules.js.map +1 -1
- package/dist/auth/interface.d.ts +99 -116
- package/dist/auth/interface.d.ts.map +1 -1
- package/dist/auth/types.d.ts +1 -4
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/bindings/interface.d.ts +19 -32
- package/dist/bindings/interface.d.ts.map +1 -1
- package/dist/bindings/interface.js +6 -12
- package/dist/bindings/interface.js.map +1 -1
- package/dist/computeServer/interface.d.ts +34 -41
- package/dist/computeServer/interface.d.ts.map +1 -1
- package/dist/computeServer/secrets.d.ts +16 -20
- package/dist/computeServer/secrets.d.ts.map +1 -1
- package/dist/computeServer/secrets.js +11 -12
- package/dist/computeServer/secrets.js.map +1 -1
- package/dist/computeServer/types.d.ts +15 -17
- package/dist/computeServer/types.d.ts.map +1 -1
- package/dist/computeServer/types.js.map +1 -1
- package/dist/computeServer/utils.d.ts +8 -14
- package/dist/computeServer/utils.d.ts.map +1 -1
- package/dist/computeServer/utils.js +8 -16
- package/dist/computeServer/utils.js.map +1 -1
- package/dist/config.d.ts +16 -39
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -2
- package/dist/config.js.map +1 -1
- package/dist/context.d.ts +12 -19
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +6 -10
- package/dist/context.js.map +1 -1
- package/dist/data/interface.d.ts +32 -47
- package/dist/data/interface.d.ts.map +1 -1
- package/dist/data/interface.js +7 -10
- package/dist/data/interface.js.map +1 -1
- package/dist/definitions/interface.d.ts +24 -31
- package/dist/definitions/interface.d.ts.map +1 -1
- package/dist/definitions/schemas.d.ts.map +1 -1
- package/dist/definitions/schemas.js +6 -9
- package/dist/definitions/schemas.js.map +1 -1
- package/dist/definitions/types.d.ts +26 -42
- package/dist/definitions/types.d.ts.map +1 -1
- package/dist/definitions/types.js +0 -1
- package/dist/definitions/types.js.map +1 -1
- package/dist/errors/interface.d.ts +4 -8
- package/dist/errors/interface.d.ts.map +1 -1
- package/dist/errors/interface.js.map +1 -1
- package/dist/errors.d.ts +2 -5
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +2 -5
- package/dist/errors.js.map +1 -1
- package/dist/events/audit.d.ts +13 -26
- package/dist/events/audit.d.ts.map +1 -1
- package/dist/events/interface.d.ts +17 -33
- package/dist/events/interface.d.ts.map +1 -1
- package/dist/events/interface.js +7 -22
- package/dist/events/interface.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/invites/interface.d.ts +3 -9
- package/dist/invites/interface.d.ts.map +1 -1
- package/dist/invites/types.d.ts +4 -11
- package/dist/invites/types.d.ts.map +1 -1
- package/dist/logging/interface.d.ts +19 -33
- package/dist/logging/interface.d.ts.map +1 -1
- package/dist/logging/interface.js +9 -17
- package/dist/logging/interface.js.map +1 -1
- package/dist/metrics/interface.d.ts +16 -31
- package/dist/metrics/interface.d.ts.map +1 -1
- package/dist/metrics/interface.js +1 -5
- package/dist/metrics/interface.js.map +1 -1
- package/dist/organizations/interface.d.ts +14 -23
- package/dist/organizations/interface.d.ts.map +1 -1
- package/dist/organizations/paths.d.ts +9 -12
- package/dist/organizations/paths.d.ts.map +1 -1
- package/dist/organizations/paths.js +12 -16
- package/dist/organizations/paths.js.map +1 -1
- package/dist/organizations/schemas.d.ts +10 -19
- package/dist/organizations/schemas.d.ts.map +1 -1
- package/dist/organizations/schemas.js +10 -19
- package/dist/organizations/schemas.js.map +1 -1
- package/dist/organizations/types.d.ts +3 -4
- package/dist/organizations/types.d.ts.map +1 -1
- package/dist/pagination.d.ts +13 -21
- package/dist/pagination.d.ts.map +1 -1
- package/dist/pagination.js.map +1 -1
- package/dist/permissions/interface.d.ts +12 -21
- package/dist/permissions/interface.d.ts.map +1 -1
- package/dist/permissions/types.d.ts +5 -5
- package/dist/permissions/types.js +5 -5
- package/dist/platformProjects/interface.d.ts +7 -14
- package/dist/platformProjects/interface.d.ts.map +1 -1
- package/dist/platformProjects/types.d.ts +1 -4
- package/dist/platformProjects/types.d.ts.map +1 -1
- package/dist/projects/interface.d.ts +12 -17
- package/dist/projects/interface.d.ts.map +1 -1
- package/dist/shareLinks/interface.d.ts +5 -8
- package/dist/shareLinks/interface.d.ts.map +1 -1
- package/dist/shareLinks/schemas.d.ts.map +1 -1
- package/dist/shareLinks/schemas.js +1 -5
- package/dist/shareLinks/schemas.js.map +1 -1
- package/dist/shareLinks/types.d.ts +5 -6
- package/dist/shareLinks/types.d.ts.map +1 -1
- package/dist/shareLinks/types.js.map +1 -1
- package/dist/solveCache/interface.d.ts +32 -46
- package/dist/solveCache/interface.d.ts.map +1 -1
- package/dist/solveCache/interface.js.map +1 -1
- package/dist/storage/assetClasses.d.ts +16 -24
- package/dist/storage/assetClasses.d.ts.map +1 -1
- package/dist/storage/assetClasses.js +21 -28
- package/dist/storage/assetClasses.js.map +1 -1
- package/dist/storage/cacheBust.d.ts +12 -14
- package/dist/storage/cacheBust.d.ts.map +1 -1
- package/dist/storage/cacheBust.js +12 -14
- package/dist/storage/cacheBust.js.map +1 -1
- package/dist/storage/image.d.ts +9 -13
- package/dist/storage/image.d.ts.map +1 -1
- package/dist/storage/image.js +9 -13
- package/dist/storage/image.js.map +1 -1
- package/dist/userProfile/interface.d.ts +1 -1
- package/dist/userProfile/types.d.ts +1 -5
- package/dist/userProfile/types.d.ts.map +1 -1
- package/dist/userProfile/types.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type { RequestContext } from '../context.js';
|
|
2
2
|
/**
|
|
3
3
|
* Why a solve did not produce a usable result. `ok` means the solve completed
|
|
4
|
-
* (it may still carry Grasshopper runtime errors — see `errorCount`).
|
|
5
|
-
*
|
|
6
|
-
* distinguishes, so the recorded reason matches the HTTP status the client saw.
|
|
4
|
+
* (it may still carry Grasshopper runtime errors — see `errorCount`). Each
|
|
5
|
+
* kind mirrors an HTTP status the compute route already distinguishes.
|
|
7
6
|
*/
|
|
8
7
|
export type SolveFailureKind =
|
|
9
8
|
/** Solve completed; the response was returned to the client. */
|
|
@@ -27,62 +26,48 @@ export type SolveFailureKind =
|
|
|
27
26
|
/** Compute server unreachable or the solve threw for any other reason. */
|
|
28
27
|
| 'compute_error';
|
|
29
28
|
/**
|
|
30
|
-
* One solve's timing and outcome, recorded once per
|
|
29
|
+
* One solve's timing and outcome, recorded once per attempt — including
|
|
31
30
|
* attempts rejected before `scheduler.solve()` runs (rate limit, share cap).
|
|
32
|
-
*
|
|
33
|
-
* `durationMs` is wall time around the Rhino.Compute solve call only — it
|
|
34
|
-
* excludes definition loading, auth, schema work, and result serialization. It
|
|
35
|
-
* is 0 for attempts rejected before the solve started.
|
|
36
31
|
*/
|
|
37
32
|
export interface SolveMetric {
|
|
38
33
|
/** Definition the solve ran against. `local:<guid>` or a remote URL. */
|
|
39
34
|
definitionUrl: string;
|
|
40
|
-
/**
|
|
41
|
-
* Local definition id (the `local:` guid), or null for remote-URL solves.
|
|
42
|
-
* Stored alongside `definitionUrl` so timings join to the definition record.
|
|
43
|
-
*/
|
|
35
|
+
/** Local definition id (the `local:` guid), or null for remote-URL solves. */
|
|
44
36
|
definitionId: string | null;
|
|
45
|
-
/**
|
|
46
|
-
* The exact version solved, or null for remote-URL solves (and for local
|
|
47
|
-
* attempts rejected before the version resolved). Lets you compare timings
|
|
48
|
-
* across versions of the same definition.
|
|
49
|
-
*/
|
|
37
|
+
/** Exact version solved, or null for remote-URL solves and attempts rejected before the version resolved. */
|
|
50
38
|
versionId: string | null;
|
|
51
39
|
/** Channel solved, mirroring the compute request. */
|
|
52
40
|
channel: 'live' | 'draft';
|
|
53
41
|
/** Org whose compute pool served the solve, or null for remote definitions. */
|
|
54
42
|
orgId: string | null;
|
|
55
|
-
/**
|
|
43
|
+
/**
|
|
44
|
+
* Wall time around the Rhino.Compute solve call only — excludes definition
|
|
45
|
+
* loading, auth, schema work, and result serialization. 0 if never started.
|
|
46
|
+
*/
|
|
56
47
|
durationMs: number;
|
|
57
48
|
/** Whether the solve completed and returned a result. */
|
|
58
49
|
ok: boolean;
|
|
59
50
|
/** Why the solve did not return a result; `'ok'` when it did. */
|
|
60
51
|
failureKind: SolveFailureKind;
|
|
61
52
|
/**
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* `failureKind`. 0 when the solve never returned a response.
|
|
53
|
+
* Grasshopper runtime errors in the solve response. A solve can be `ok`
|
|
54
|
+
* yet still report component-level errors. 0 when no response returned.
|
|
65
55
|
*/
|
|
66
56
|
errorCount: number;
|
|
67
|
-
/**
|
|
57
|
+
/** Grasshopper runtime warnings in the solve response. */
|
|
68
58
|
warningCount: number;
|
|
69
59
|
}
|
|
70
60
|
/**
|
|
71
|
-
* Sink for per-solve timing telemetry
|
|
72
|
-
*
|
|
61
|
+
* Sink for per-solve timing telemetry, called once per attempt after the
|
|
62
|
+
* solve resolves or rejects.
|
|
73
63
|
*
|
|
74
64
|
* MUST NOT throw — recording is best-effort and sits on the hot path of every
|
|
75
|
-
* solve. Implementations catch and log their own failures
|
|
76
|
-
* effect visible to the caller is a fulfilled promise. MAY be fire-and-forget.
|
|
65
|
+
* solve. Implementations catch and log their own failures.
|
|
77
66
|
*/
|
|
78
67
|
export interface ISolveMetricSink {
|
|
79
68
|
record(ctx: RequestContext, metric: SolveMetric): Promise<void>;
|
|
80
69
|
}
|
|
81
|
-
/**
|
|
82
|
-
* Default `ISolveMetricSink` — discards every metric. Used when
|
|
83
|
-
* `SelvaConfig.solveMetrics` is omitted. Swap in a real sink to persist or
|
|
84
|
-
* aggregate solve timings.
|
|
85
|
-
*/
|
|
70
|
+
/** Default `ISolveMetricSink` — discards every metric. Used when `SelvaConfig.solveMetrics` is omitted. */
|
|
86
71
|
export declare class NoopSolveMetricSink implements ISolveMetricSink {
|
|
87
72
|
record(_ctx: RequestContext, _metric: SolveMetric): Promise<void>;
|
|
88
73
|
}
|
|
@@ -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
|
|
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;;;;GAIG;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;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC3B,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,6GAA6G;IAC7G,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;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,EAAE,EAAE,OAAO,CAAC;IACZ,iEAAiE;IACjE,WAAW,EAAE,gBAAgB,CAAC;IAC9B;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,YAAY,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAChC,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAChE;AAED,2GAA2G;AAC3G,qBAAa,mBAAoB,YAAW,gBAAgB;IACrD,MAAM,CAAC,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;CACvE"}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Default `ISolveMetricSink` — discards every metric. Used when
|
|
3
|
-
* `SelvaConfig.solveMetrics` is omitted. Swap in a real sink to persist or
|
|
4
|
-
* aggregate solve timings.
|
|
5
|
-
*/
|
|
1
|
+
/** Default `ISolveMetricSink` — discards every metric. Used when `SelvaConfig.solveMetrics` is omitted. */
|
|
6
2
|
export class NoopSolveMetricSink {
|
|
7
3
|
async record(_ctx, _metric) { }
|
|
8
4
|
}
|
|
@@ -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":"AAyEA,2GAA2G;AAC3G,MAAM,OAAO,mBAAmB;IAC/B,KAAK,CAAC,MAAM,CAAC,IAAoB,EAAE,OAAoB,IAAkB,CAAC;CAC1E"}
|
|
@@ -13,34 +13,25 @@ export interface IOrgStore {
|
|
|
13
13
|
createOrg(ctx: RequestContext, org: Organization): Promise<void>;
|
|
14
14
|
updateOrg(ctx: RequestContext, id: string, patch: Partial<Pick<Organization, 'name' | 'slug' | 'assets'>>): Promise<void>;
|
|
15
15
|
/**
|
|
16
|
-
* Soft-
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
16
|
+
* Soft-deletes the org, cascading to org members, projects, and project
|
|
17
|
+
* members (definitions and share links cascade through project deletion).
|
|
18
|
+
* Invites and the org compute-server override are NOT cascaded — clean
|
|
19
|
+
* those up explicitly if needed.
|
|
20
20
|
*/
|
|
21
21
|
deleteOrg(ctx: RequestContext, id: string): Promise<void>;
|
|
22
22
|
listOrgMembers(ctx: RequestContext, orgId: string, opts?: ListOptions): Promise<Page<OrgMember>>;
|
|
23
23
|
getOrgMember(ctx: RequestContext, orgId: string, userId: string): Promise<OrgMember | null>;
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* Keys are the requested `orgIds`; an org the user is not a member of maps to
|
|
29
|
-
* `null` rather than being absent.
|
|
25
|
+
* Bulk counterpart to `getOrgMember`, for evaluating access rules over a
|
|
26
|
+
* list of orgs in one query. Keys are the requested `orgIds`; an org the
|
|
27
|
+
* user is not a member of maps to `null` rather than being absent.
|
|
30
28
|
*/
|
|
31
29
|
getOrgMembersFor(ctx: RequestContext, orgIds: readonly string[], userId: string): Promise<Map<string, OrgMember | null>>;
|
|
32
30
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
* multiple memberships (multi-tenant deployments), the choice between
|
|
38
|
-
* them is adapter-defined — single-tenant deployments have exactly one,
|
|
39
|
-
* and multi-tenant deployments will eventually use a URL prefix
|
|
40
|
-
* (`/o/{slug}/...`) to pick explicitly. Soft-deleted memberships are
|
|
41
|
-
* excluded.
|
|
42
|
-
*
|
|
43
|
-
* Both `org` and `member` are scoped by `ctx` (RLS-aware on Supabase).
|
|
31
|
+
* Finds one org membership for the user, to resolve `actingOrgId` during
|
|
32
|
+
* request bootstrap without N+1-ing over `listOrgs`. Returns `null` when
|
|
33
|
+
* the user has no live membership (soft-deleted ones are excluded). If the
|
|
34
|
+
* user has multiple memberships, which one comes back is adapter-defined.
|
|
44
35
|
*/
|
|
45
36
|
findUserMembership(ctx: RequestContext, userId: string): Promise<{
|
|
46
37
|
org: Organization;
|
|
@@ -49,9 +40,9 @@ export interface IOrgStore {
|
|
|
49
40
|
addOrgMember(ctx: RequestContext, member: OrgMember): Promise<void>;
|
|
50
41
|
updateOrgMemberRole(ctx: RequestContext, orgId: string, userId: string, role: OrgRole): Promise<void>;
|
|
51
42
|
/**
|
|
52
|
-
*
|
|
53
|
-
* permission edits — round-tripping through remove + add
|
|
54
|
-
* org-removal soft-delete into project memberships.
|
|
43
|
+
* Replaces the `OrgPermission` set without changing role. Use this for
|
|
44
|
+
* permission edits — round-tripping through remove + add would cascade
|
|
45
|
+
* the org-removal soft-delete into project memberships.
|
|
55
46
|
*/
|
|
56
47
|
updateOrgMemberPermissions(ctx: RequestContext, orgId: string, userId: string, permissions: readonly OrgPermission[]): Promise<void>;
|
|
57
48
|
removeOrgMember(ctx: RequestContext, orgId: string, userId: string): Promise<void>;
|
|
@@ -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,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
|
|
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;;;;OAIG;IACH,gBAAgB,CACf,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C;;;;;OAKG;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"}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import type { OrgAssetKind } from './schemas.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* upsert. The filename IS the kind, so the layout is generic: a new branding
|
|
7
|
-
* kind needs no new helper.
|
|
3
|
+
* Every branding asset is stored as `.webp` (uploads go through the shared
|
|
4
|
+
* transcoder), so the path per kind is fixed and a re-upload overwrites in
|
|
5
|
+
* place via `IStorageProvider.put`'s upsert.
|
|
8
6
|
*
|
|
9
|
-
* Branding lives under `orgs/{id}/branding/` because it
|
|
10
|
-
* class — anyone,
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* these prefixes — see `classifyAssetPath` / `ASSET_CLASSES`.
|
|
7
|
+
* Branding lives under `orgs/{id}/branding/` because it's a *public* asset
|
|
8
|
+
* class — anyone, including logged-out viewers, may read a company logo.
|
|
9
|
+
* That segment distinguishes it from `orgs/{id}/private/` (members-only).
|
|
10
|
+
* `classifyAssetPath` / `ASSET_CLASSES` decide public-vs-private from these
|
|
11
|
+
* prefixes.
|
|
15
12
|
*/
|
|
16
13
|
export declare const orgPaths: {
|
|
17
14
|
readonly asset: (id: string, kind: OrgAssetKind) => string;
|
|
18
|
-
/** Members-only blob
|
|
15
|
+
/** Members-only blob; `name` includes the extension. */
|
|
19
16
|
readonly privateAsset: (id: string, name: string) => string;
|
|
20
17
|
readonly prefix: (id: string) => string;
|
|
21
18
|
};
|
|
@@ -1 +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;
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/organizations/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAajD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ;yBACR,MAAM,QAAQ,YAAY;IAKtC,wDAAwD;gCACrC,MAAM,QAAQ,MAAM;0BAK1B,MAAM;CAIV,CAAC"}
|
|
@@ -1,27 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* refs. Called by every helper so a malicious `id` can't escape the
|
|
5
|
-
* `orgs/` prefix. Mirrors `definitionPaths`' guard.
|
|
2
|
+
* Blocks path traversal, separators, and empty segments. Called by every
|
|
3
|
+
* helper below so a malicious `id` can't escape the `orgs/` prefix.
|
|
6
4
|
*/
|
|
7
5
|
function assertSafeKey(value, label) {
|
|
6
|
+
// The regex alone allows '.' and '..' — both fully match the allowed alphabet — so they need an explicit check.
|
|
8
7
|
if (!value || !/^[A-Za-z0-9._-]+$/.test(value) || value === '.' || value === '..') {
|
|
9
8
|
throw new Error(`Unsafe ${label}: ${JSON.stringify(value)}`);
|
|
10
9
|
}
|
|
11
10
|
}
|
|
12
11
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* upsert. The filename IS the kind, so the layout is generic: a new branding
|
|
17
|
-
* kind needs no new helper.
|
|
12
|
+
* Every branding asset is stored as `.webp` (uploads go through the shared
|
|
13
|
+
* transcoder), so the path per kind is fixed and a re-upload overwrites in
|
|
14
|
+
* place via `IStorageProvider.put`'s upsert.
|
|
18
15
|
*
|
|
19
|
-
* Branding lives under `orgs/{id}/branding/` because it
|
|
20
|
-
* class — anyone,
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* these prefixes — see `classifyAssetPath` / `ASSET_CLASSES`.
|
|
16
|
+
* Branding lives under `orgs/{id}/branding/` because it's a *public* asset
|
|
17
|
+
* class — anyone, including logged-out viewers, may read a company logo.
|
|
18
|
+
* That segment distinguishes it from `orgs/{id}/private/` (members-only).
|
|
19
|
+
* `classifyAssetPath` / `ASSET_CLASSES` decide public-vs-private from these
|
|
20
|
+
* prefixes.
|
|
25
21
|
*/
|
|
26
22
|
export const orgPaths = {
|
|
27
23
|
asset: (id, kind) => {
|
|
@@ -29,7 +25,7 @@ export const orgPaths = {
|
|
|
29
25
|
assertSafeKey(kind, 'assetKind');
|
|
30
26
|
return `orgs/${id}/branding/${kind}.webp`;
|
|
31
27
|
},
|
|
32
|
-
/** Members-only blob
|
|
28
|
+
/** Members-only blob; `name` includes the extension. */
|
|
33
29
|
privateAsset: (id, name) => {
|
|
34
30
|
assertSafeKey(id, 'orgId');
|
|
35
31
|
assertSafeKey(name, 'assetName');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/organizations/paths.ts"],"names":[],"mappings":"AAEA
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/organizations/paths.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IAClD,gHAAgH;IAChH,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;;;;;;;;;;GAUG;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,wDAAwD;IACxD,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"}
|
|
@@ -1,24 +1,18 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/**
|
|
3
3
|
* Top-level path segments a tenant slug must never equal, so a slug can never
|
|
4
|
-
* shadow (or be shadowed by) a route
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `/o/{slug}/…` (or any flat tenant route) collision-free from day one,
|
|
11
|
-
* before any external link is minted against a slug.
|
|
12
|
-
* Lowercase; the slug is lowercased/matched case-insensitively so `Admin` can't
|
|
13
|
-
* slip through. Keep in sync with the route tree's top-level directories.
|
|
4
|
+
* shadow (or be shadowed by) a route. `/o/{slug}/` is the planned shape for
|
|
5
|
+
* per-org URLs, so `o` is reserved even though the length gate below already
|
|
6
|
+
* makes a 1-char slug impossible — that keeps a future move to `/o/{slug}/…`
|
|
7
|
+
* collision-free before any external link is minted against a slug.
|
|
8
|
+
* Lowercase; matching is case-insensitive so `Admin` can't slip through. Keep
|
|
9
|
+
* in sync with the route tree's top-level directories.
|
|
14
10
|
*/
|
|
15
11
|
export declare const RESERVED_SLUGS: readonly string[];
|
|
16
12
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* validity (a name of all-symbols yields `''`, and reserved words pass through);
|
|
21
|
-
* run the result through `SlugSchema` where a valid slug is required.
|
|
13
|
+
* Coerces an arbitrary name into a slug candidate. Does not guarantee a valid
|
|
14
|
+
* slug — an all-symbols name yields `''`, and reserved words pass through
|
|
15
|
+
* untouched — run the result through `SlugSchema` where validity matters.
|
|
22
16
|
*/
|
|
23
17
|
export declare function slugify(name: string): string;
|
|
24
18
|
/** Lowercase alphanumeric with internal hyphens, 3–63 chars, not a reserved word. */
|
|
@@ -29,10 +23,7 @@ export declare const OrgRoleSchema: z.ZodEnum<{
|
|
|
29
23
|
member: "member";
|
|
30
24
|
}>;
|
|
31
25
|
export type OrgRole = z.infer<typeof OrgRoleSchema>;
|
|
32
|
-
/**
|
|
33
|
-
* Kinds of org-scoped branding asset. Adding a new kind is a single entry here
|
|
34
|
-
* — the storage path, upload route, store, and UI are all generic over it.
|
|
35
|
-
*/
|
|
26
|
+
/** Kinds of org-scoped branding asset. Adding a kind is a single entry here — path, upload route, store, and UI are all generic over it. */
|
|
36
27
|
export declare const OrgAssetKindSchema: z.ZodEnum<{
|
|
37
28
|
logo: "logo";
|
|
38
29
|
favicon: "favicon";
|
|
@@ -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
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/organizations/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAY3C,CAAC;AAIF;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO5C;AAED,qFAAqF;AACrF,eAAO,MAAM,UAAU,aAUpB,CAAC;AAEJ,eAAO,MAAM,aAAa;;;;EAAuC,CAAC;AAClE,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,4IAA4I;AAC5I,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"}
|
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/**
|
|
3
3
|
* Top-level path segments a tenant slug must never equal, so a slug can never
|
|
4
|
-
* shadow (or be shadowed by) a route
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* `/o/{slug}/…` (or any flat tenant route) collision-free from day one,
|
|
11
|
-
* before any external link is minted against a slug.
|
|
12
|
-
* Lowercase; the slug is lowercased/matched case-insensitively so `Admin` can't
|
|
13
|
-
* slip through. Keep in sync with the route tree's top-level directories.
|
|
4
|
+
* shadow (or be shadowed by) a route. `/o/{slug}/` is the planned shape for
|
|
5
|
+
* per-org URLs, so `o` is reserved even though the length gate below already
|
|
6
|
+
* makes a 1-char slug impossible — that keeps a future move to `/o/{slug}/…`
|
|
7
|
+
* collision-free before any external link is minted against a slug.
|
|
8
|
+
* Lowercase; matching is case-insensitive so `Admin` can't slip through. Keep
|
|
9
|
+
* in sync with the route tree's top-level directories.
|
|
14
10
|
*/
|
|
15
11
|
export const RESERVED_SLUGS = [
|
|
16
12
|
'o',
|
|
@@ -27,11 +23,9 @@ export const RESERVED_SLUGS = [
|
|
|
27
23
|
];
|
|
28
24
|
const RESERVED_SLUG_SET = new Set(RESERVED_SLUGS);
|
|
29
25
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* validity (a name of all-symbols yields `''`, and reserved words pass through);
|
|
34
|
-
* run the result through `SlugSchema` where a valid slug is required.
|
|
26
|
+
* Coerces an arbitrary name into a slug candidate. Does not guarantee a valid
|
|
27
|
+
* slug — an all-symbols name yields `''`, and reserved words pass through
|
|
28
|
+
* untouched — run the result through `SlugSchema` where validity matters.
|
|
35
29
|
*/
|
|
36
30
|
export function slugify(name) {
|
|
37
31
|
return name
|
|
@@ -51,10 +45,7 @@ export const SlugSchema = z
|
|
|
51
45
|
message: 'Slug is reserved and cannot be used'
|
|
52
46
|
});
|
|
53
47
|
export const OrgRoleSchema = z.enum(['owner', 'admin', 'member']);
|
|
54
|
-
/**
|
|
55
|
-
* Kinds of org-scoped branding asset. Adding a new kind is a single entry here
|
|
56
|
-
* — the storage path, upload route, store, and UI are all generic over it.
|
|
57
|
-
*/
|
|
48
|
+
/** Kinds of org-scoped branding asset. Adding a kind is a single entry here — path, upload route, store, and UI are all generic over it. */
|
|
58
49
|
export const OrgAssetKindSchema = z.enum(['logo', 'favicon']);
|
|
59
50
|
export const ALL_ORG_ASSET_KINDS = OrgAssetKindSchema.options;
|
|
60
51
|
/** Org-scope permissions. A user may hold different sets in different orgs. */
|
|
@@ -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
|
|
1
|
+
{"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/organizations/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,cAAc,GAAsB;IAChD,GAAG;IACH,KAAK;IACL,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,OAAO;IACP,MAAM;IACN,SAAS;IACT,UAAU;IACV,eAAe;CACf,CAAC;AAEF,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,CAAC;AAElD;;;;GAIG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IACnC,OAAO,IAAI;SACT,IAAI,EAAE;SACN,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC;SACrB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAChB,CAAC;AAED,qFAAqF;AACrF,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;KACA,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;IACzC,OAAO,EAAE,qCAAqC;CAC9C,CAAC,CAAC;AAEJ,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AAGlE,4IAA4I;AAC5I,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,9 +1,8 @@
|
|
|
1
1
|
import type { OrgRole, OrgPermission, OrgAssetKind } from './schemas.js';
|
|
2
2
|
/**
|
|
3
|
-
* Public URLs of an org's branding assets, keyed by kind
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* the `Organization` shape, the migration, or the row mappers again.
|
|
3
|
+
* Public URLs of an org's branding assets, keyed by kind; a kind is absent
|
|
4
|
+
* when unset. Kept as one map so a new asset kind never touches the
|
|
5
|
+
* `Organization` shape, the migration, or the row mappers.
|
|
7
6
|
*/
|
|
8
7
|
export type OrgAssets = Partial<Record<OrgAssetKind, string>>;
|
|
9
8
|
export interface Organization {
|
|
@@ -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,YAAY,EAAE,MAAM,cAAc,CAAC;AAEzE
|
|
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;;;;GAIG;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"}
|
package/dist/pagination.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { DefinitionStatus } from './definitions/types.js';
|
|
2
2
|
/**
|
|
3
|
-
* Cursor-paginated list options. Adapters
|
|
4
|
-
*
|
|
3
|
+
* Cursor-paginated list options. Adapters default to limit=50, orderBy=createdAt
|
|
4
|
+
* desc, and clamp limit to `MAX_PAGE_LIMIT`.
|
|
5
5
|
*
|
|
6
|
-
* Cursors are opaque — adapters may use row ids, offsets, or keyset
|
|
7
|
-
*
|
|
6
|
+
* Cursors are opaque — adapters may use row ids, offsets, or keyset encodings.
|
|
7
|
+
* Callers must not inspect them.
|
|
8
8
|
*/
|
|
9
9
|
export interface ListOptions {
|
|
10
10
|
limit?: number;
|
|
@@ -16,31 +16,23 @@ export interface ListOptions {
|
|
|
16
16
|
/** Definition-specific filtering on top of `ListOptions`. */
|
|
17
17
|
export interface DefinitionListOptions extends Omit<ListOptions, 'orderBy'> {
|
|
18
18
|
orderBy?: 'createdAt' | 'updatedAt' | 'name' | 'solveCount';
|
|
19
|
-
/**
|
|
20
|
-
* Include records with `status='pending'`. Default false — consumers don't
|
|
21
|
-
* see half-written state unless they explicitly opt in.
|
|
22
|
-
*/
|
|
19
|
+
/** Include `status='pending'` records. Default false. */
|
|
23
20
|
includePending?: boolean;
|
|
24
|
-
/**
|
|
25
|
-
* Include records with `status='archived'`. Default false — archived
|
|
26
|
-
* definitions are hidden from normal views; opt in for archive browsers.
|
|
27
|
-
*/
|
|
21
|
+
/** Include `status='archived'` records. Default false. */
|
|
28
22
|
includeArchived?: boolean;
|
|
29
23
|
/**
|
|
30
24
|
* Filter to specific editorial statuses. Omit for the default view (all
|
|
31
|
-
* non-pending, non-archived).
|
|
32
|
-
*
|
|
25
|
+
* non-pending, non-archived). When set, `includePending` / `includeArchived`
|
|
26
|
+
* are ignored.
|
|
33
27
|
*/
|
|
34
28
|
statuses?: DefinitionStatus[];
|
|
35
29
|
/**
|
|
36
|
-
* Restrict to definitions in these projects. An empty array matches nothing
|
|
37
|
-
*
|
|
30
|
+
* Restrict to definitions in these projects. An empty array matches nothing,
|
|
31
|
+
* distinct from omitting the filter.
|
|
38
32
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
* cursor. Filtering a fetched page afterwards makes `limit` and `nextCursor`
|
|
43
|
-
* describe pre-filter positions — a page of 50 can come back with 3 items.
|
|
33
|
+
* Applying this in the adapter query — rather than filtering a fetched page
|
|
34
|
+
* afterwards — is what keeps `limit` and `nextCursor` accurate: filtering
|
|
35
|
+
* post-fetch can return a page of 50 with 3 items.
|
|
44
36
|
*/
|
|
45
37
|
projectIds?: readonly string[];
|
|
46
38
|
}
|
package/dist/pagination.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;IAC7C,uBAAuB;IACvB,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC1B;AAED,6DAA6D;AAC7D,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;IAC1E,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,YAAY,CAAC;IAC5D
|
|
1
|
+
{"version":3,"file":"pagination.d.ts","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAAC;IAC7C,uBAAuB;IACvB,QAAQ,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAC1B;AAED,6DAA6D;AAC7D,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CAAC,WAAW,EAAE,SAAS,CAAC;IAC1E,OAAO,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,YAAY,CAAC;IAC5D,yDAAyD;IACzD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,IAAI,CAAC,CAAC;IACtB,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,eAAO,MAAM,cAAc,MAAM,CAAC"}
|
package/dist/pagination.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AA8CA,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC"}
|
|
@@ -6,43 +6,34 @@ import type { PlatformPermission } from './types.js';
|
|
|
6
6
|
* `IAuthProvider`) so external IdPs don't need to model Selva-specific
|
|
7
7
|
* authorization.
|
|
8
8
|
*
|
|
9
|
-
* **The sole-`instance_admin` invariant is enforced here
|
|
10
|
-
* that would leave zero users holding `instance_admin`
|
|
11
|
-
* `'last_admin'`.
|
|
12
|
-
* before any destructive op so the invariant holds across edits, deletes,
|
|
13
|
-
* and disables.
|
|
9
|
+
* **The sole-`instance_admin` invariant is enforced here**: any operation
|
|
10
|
+
* that would leave zero users holding `instance_admin` must return
|
|
11
|
+
* `'last_admin'`.
|
|
14
12
|
*
|
|
15
13
|
* Reads are scoped to "self or admin"; writes restricted to `instance_admin`.
|
|
16
14
|
* Pass `SYSTEM_CONTEXT` for trusted server flows (bootstrap, hooks).
|
|
17
15
|
*/
|
|
18
16
|
export interface IPlatformPermissionStore {
|
|
19
|
-
/**
|
|
20
|
-
* Read permissions for a single user. Empty array for users with no
|
|
21
|
-
* admin grants (the common case). Non-admin callers may only read self.
|
|
22
|
-
*/
|
|
17
|
+
/** Empty array for users with no admin grants. Non-admin callers may only read self. */
|
|
23
18
|
getFor(ctx: RequestContext, userId: string): Promise<PlatformPermission[]>;
|
|
24
|
-
/**
|
|
19
|
+
/** Admin-only. */
|
|
25
20
|
getForBatch(ctx: RequestContext, userIds: readonly string[]): Promise<Map<string, PlatformPermission[]>>;
|
|
26
21
|
/**
|
|
27
|
-
* Replace the user's permissions. Idempotent.
|
|
28
|
-
*
|
|
29
|
-
* - `not_found` — target user doesn't exist
|
|
30
|
-
* - `last_admin` — refused; would leave zero `instance_admin` users
|
|
31
|
-
*
|
|
22
|
+
* Replace the user's permissions. Idempotent.
|
|
23
|
+
* `last_admin` — refused; would leave zero `instance_admin` users.
|
|
32
24
|
* `not_supported` is intentionally absent — every deployment must provide
|
|
33
25
|
* a permission store.
|
|
34
26
|
*/
|
|
35
27
|
set(ctx: RequestContext, userId: string, permissions: readonly PlatformPermission[]): Promise<UserManagementResult>;
|
|
36
28
|
/**
|
|
37
|
-
* True if at least one *enabled* user holds `instance_admin`.
|
|
38
|
-
*
|
|
39
|
-
* MUST exclude disabled users (over-count is safer than under-count).
|
|
29
|
+
* True if at least one *enabled* user holds `instance_admin`. Adapters
|
|
30
|
+
* must exclude disabled users — over-count is safer than under-count.
|
|
40
31
|
*/
|
|
41
32
|
hasInstanceAdmin(ctx: RequestContext): Promise<boolean>;
|
|
42
33
|
/**
|
|
43
|
-
* Count *other* users holding `instance_admin`.
|
|
44
|
-
*
|
|
45
|
-
*
|
|
34
|
+
* Count *other* users holding `instance_admin`. Callers check this
|
|
35
|
+
* before a destructive op — `count === 0` means the target is the last
|
|
36
|
+
* admin and the op must be refused. Must exclude disabled users.
|
|
46
37
|
*/
|
|
47
38
|
countInstanceAdminsExcluding(ctx: RequestContext, excludeUserId: string): Promise<number>;
|
|
48
39
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/permissions/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/permissions/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,wBAAwB;IACxC,wFAAwF;IACxF,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE3E,kBAAkB;IAClB,WAAW,CACV,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,GAAG,CACF,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;OAGG;IACH,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAExD;;;;OAIG;IACH,4BAA4B,CAAC,GAAG,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1F"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/**
|
|
3
|
-
* Platform-scope permissions. Reserved for Selva
|
|
3
|
+
* Platform-scope permissions. Reserved for Selva staff and instance operators;
|
|
4
4
|
* regular users hold an empty array.
|
|
5
5
|
*
|
|
6
|
-
* - `instance_admin` — superuser; implies every other permission
|
|
7
|
-
* - `manage_compute` — configure the instance-wide Rhino.Compute pool
|
|
8
|
-
* - `manage_instance_users` — disable/enable any user on the instance
|
|
9
|
-
* - `manage_updates` — run system updates
|
|
6
|
+
* - `instance_admin` — superuser; implies every other permission
|
|
7
|
+
* - `manage_compute` — configure the instance-wide Rhino.Compute pool
|
|
8
|
+
* - `manage_instance_users` — disable/enable any user on the instance
|
|
9
|
+
* - `manage_updates` — run system updates
|
|
10
10
|
*/
|
|
11
11
|
export declare const PlatformPermissionSchema: z.ZodEnum<{
|
|
12
12
|
instance_admin: "instance_admin";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
/**
|
|
3
|
-
* Platform-scope permissions. Reserved for Selva
|
|
3
|
+
* Platform-scope permissions. Reserved for Selva staff and instance operators;
|
|
4
4
|
* regular users hold an empty array.
|
|
5
5
|
*
|
|
6
|
-
* - `instance_admin` — superuser; implies every other permission
|
|
7
|
-
* - `manage_compute` — configure the instance-wide Rhino.Compute pool
|
|
8
|
-
* - `manage_instance_users` — disable/enable any user on the instance
|
|
9
|
-
* - `manage_updates` — run system updates
|
|
6
|
+
* - `instance_admin` — superuser; implies every other permission
|
|
7
|
+
* - `manage_compute` — configure the instance-wide Rhino.Compute pool
|
|
8
|
+
* - `manage_instance_users` — disable/enable any user on the instance
|
|
9
|
+
* - `manage_updates` — run system updates
|
|
10
10
|
*/
|
|
11
11
|
export const PlatformPermissionSchema = z.enum([
|
|
12
12
|
'instance_admin',
|