@selvajs/platform 0.16.1-beta.2 → 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.
Files changed (127) hide show
  1. package/README.md +25 -28
  2. package/dist/access/rules.d.ts +20 -26
  3. package/dist/access/rules.d.ts.map +1 -1
  4. package/dist/access/rules.js +16 -16
  5. package/dist/access/rules.js.map +1 -1
  6. package/dist/auth/interface.d.ts +99 -116
  7. package/dist/auth/interface.d.ts.map +1 -1
  8. package/dist/auth/types.d.ts +1 -4
  9. package/dist/auth/types.d.ts.map +1 -1
  10. package/dist/bindings/interface.d.ts +19 -32
  11. package/dist/bindings/interface.d.ts.map +1 -1
  12. package/dist/bindings/interface.js +6 -12
  13. package/dist/bindings/interface.js.map +1 -1
  14. package/dist/computeServer/interface.d.ts +34 -41
  15. package/dist/computeServer/interface.d.ts.map +1 -1
  16. package/dist/computeServer/secrets.d.ts +16 -20
  17. package/dist/computeServer/secrets.d.ts.map +1 -1
  18. package/dist/computeServer/secrets.js +11 -12
  19. package/dist/computeServer/secrets.js.map +1 -1
  20. package/dist/computeServer/types.d.ts +15 -17
  21. package/dist/computeServer/types.d.ts.map +1 -1
  22. package/dist/computeServer/types.js.map +1 -1
  23. package/dist/computeServer/utils.d.ts +8 -14
  24. package/dist/computeServer/utils.d.ts.map +1 -1
  25. package/dist/computeServer/utils.js +8 -16
  26. package/dist/computeServer/utils.js.map +1 -1
  27. package/dist/config.d.ts +16 -39
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +1 -2
  30. package/dist/config.js.map +1 -1
  31. package/dist/context.d.ts +12 -19
  32. package/dist/context.d.ts.map +1 -1
  33. package/dist/context.js +6 -10
  34. package/dist/context.js.map +1 -1
  35. package/dist/data/interface.d.ts +32 -47
  36. package/dist/data/interface.d.ts.map +1 -1
  37. package/dist/data/interface.js +7 -10
  38. package/dist/data/interface.js.map +1 -1
  39. package/dist/definitions/interface.d.ts +24 -31
  40. package/dist/definitions/interface.d.ts.map +1 -1
  41. package/dist/definitions/schemas.d.ts.map +1 -1
  42. package/dist/definitions/schemas.js +6 -9
  43. package/dist/definitions/schemas.js.map +1 -1
  44. package/dist/definitions/types.d.ts +26 -42
  45. package/dist/definitions/types.d.ts.map +1 -1
  46. package/dist/definitions/types.js +0 -1
  47. package/dist/definitions/types.js.map +1 -1
  48. package/dist/errors/interface.d.ts +4 -8
  49. package/dist/errors/interface.d.ts.map +1 -1
  50. package/dist/errors/interface.js.map +1 -1
  51. package/dist/errors.d.ts +2 -5
  52. package/dist/errors.d.ts.map +1 -1
  53. package/dist/errors.js +2 -5
  54. package/dist/errors.js.map +1 -1
  55. package/dist/events/audit.d.ts +13 -26
  56. package/dist/events/audit.d.ts.map +1 -1
  57. package/dist/events/interface.d.ts +17 -33
  58. package/dist/events/interface.d.ts.map +1 -1
  59. package/dist/events/interface.js +7 -22
  60. package/dist/events/interface.js.map +1 -1
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js.map +1 -1
  63. package/dist/invites/interface.d.ts +3 -9
  64. package/dist/invites/interface.d.ts.map +1 -1
  65. package/dist/invites/types.d.ts +4 -11
  66. package/dist/invites/types.d.ts.map +1 -1
  67. package/dist/logging/interface.d.ts +19 -33
  68. package/dist/logging/interface.d.ts.map +1 -1
  69. package/dist/logging/interface.js +9 -17
  70. package/dist/logging/interface.js.map +1 -1
  71. package/dist/metrics/interface.d.ts +16 -31
  72. package/dist/metrics/interface.d.ts.map +1 -1
  73. package/dist/metrics/interface.js +1 -5
  74. package/dist/metrics/interface.js.map +1 -1
  75. package/dist/organizations/interface.d.ts +14 -23
  76. package/dist/organizations/interface.d.ts.map +1 -1
  77. package/dist/organizations/paths.d.ts +9 -12
  78. package/dist/organizations/paths.d.ts.map +1 -1
  79. package/dist/organizations/paths.js +12 -16
  80. package/dist/organizations/paths.js.map +1 -1
  81. package/dist/organizations/schemas.d.ts +10 -19
  82. package/dist/organizations/schemas.d.ts.map +1 -1
  83. package/dist/organizations/schemas.js +10 -19
  84. package/dist/organizations/schemas.js.map +1 -1
  85. package/dist/organizations/types.d.ts +3 -4
  86. package/dist/organizations/types.d.ts.map +1 -1
  87. package/dist/pagination.d.ts +13 -21
  88. package/dist/pagination.d.ts.map +1 -1
  89. package/dist/pagination.js.map +1 -1
  90. package/dist/permissions/interface.d.ts +12 -21
  91. package/dist/permissions/interface.d.ts.map +1 -1
  92. package/dist/permissions/types.d.ts +5 -5
  93. package/dist/permissions/types.js +5 -5
  94. package/dist/platformProjects/interface.d.ts +7 -14
  95. package/dist/platformProjects/interface.d.ts.map +1 -1
  96. package/dist/platformProjects/types.d.ts +1 -4
  97. package/dist/platformProjects/types.d.ts.map +1 -1
  98. package/dist/projects/interface.d.ts +12 -17
  99. package/dist/projects/interface.d.ts.map +1 -1
  100. package/dist/shareLinks/interface.d.ts +5 -8
  101. package/dist/shareLinks/interface.d.ts.map +1 -1
  102. package/dist/shareLinks/schemas.d.ts.map +1 -1
  103. package/dist/shareLinks/schemas.js +1 -5
  104. package/dist/shareLinks/schemas.js.map +1 -1
  105. package/dist/shareLinks/types.d.ts +5 -6
  106. package/dist/shareLinks/types.d.ts.map +1 -1
  107. package/dist/shareLinks/types.js.map +1 -1
  108. package/dist/solveCache/interface.d.ts +32 -46
  109. package/dist/solveCache/interface.d.ts.map +1 -1
  110. package/dist/solveCache/interface.js.map +1 -1
  111. package/dist/storage/assetClasses.d.ts +16 -24
  112. package/dist/storage/assetClasses.d.ts.map +1 -1
  113. package/dist/storage/assetClasses.js +21 -28
  114. package/dist/storage/assetClasses.js.map +1 -1
  115. package/dist/storage/cacheBust.d.ts +12 -14
  116. package/dist/storage/cacheBust.d.ts.map +1 -1
  117. package/dist/storage/cacheBust.js +12 -14
  118. package/dist/storage/cacheBust.js.map +1 -1
  119. package/dist/storage/image.d.ts +9 -13
  120. package/dist/storage/image.d.ts.map +1 -1
  121. package/dist/storage/image.js +9 -13
  122. package/dist/storage/image.js.map +1 -1
  123. package/dist/userProfile/interface.d.ts +1 -1
  124. package/dist/userProfile/types.d.ts +1 -5
  125. package/dist/userProfile/types.d.ts.map +1 -1
  126. package/dist/userProfile/types.js.map +1 -1
  127. package/package.json +4 -4
@@ -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`). The
5
- * failure kinds mirror the distinct branches the compute route already
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 solve attempt — including
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
- /** Wall-clock duration of `scheduler.solve()` in milliseconds. 0 if never started. */
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
- * Count of Grasshopper runtime errors in the solve response. A solve can be
63
- * `ok` yet still report component-level errors this is distinct from
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
- /** Count of Grasshopper runtime warnings in the solve response. */
57
+ /** Grasshopper runtime warnings in the solve response. */
68
58
  warningCount: number;
69
59
  }
70
60
  /**
71
- * Sink for per-solve timing telemetry. Called once per solve attempt from the
72
- * compute route, AFTER the solve resolves or rejects.
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; the only side
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;;;;;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
+ {"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":"AAoFA;;;;GAIG;AACH,MAAM,OAAO,mBAAmB;IAC/B,KAAK,CAAC,MAAM,CAAC,IAAoB,EAAE,OAAoB,IAAkB,CAAC;CAC1E"}
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-delete the org. Cascades soft-delete to org members, projects in the
17
- * org, and project members. Definitions and share links cascade through the
18
- * project deletion. Invites and the org compute-server override are NOT
19
- * cascaded — clean those up explicitly if needed.
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
- * One user's membership row across many orgs, in a single query. The bulk
26
- * counterpart to `getOrgMember`, for evaluating access rules over a list.
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
- * Find ONE org membership for the user. Used by the request-bootstrap
34
- * path to resolve `actingOrgId` without N+1-ing over `listOrgs`.
35
- *
36
- * Returns `null` when the user has no live membership. When the user has
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
- * Replace `OrgPermission` set without changing role. Use this for
53
- * permission edits — round-tripping through remove + add cascades the
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;;;;;;OAMG;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;;;;;;;;;;;;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"}
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
- * 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.
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 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`.
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 under the org's private tier. `name` includes the extension. */
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;AAcjD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ;yBACR,MAAM,QAAQ,YAAY;IAKtC,qFAAqF;gCAClE,MAAM,QAAQ,MAAM;0BAK1B,MAAM;CAIV,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
- * 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.
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
- * 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.
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 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`.
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 under the org's private tier. `name` includes the extension. */
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;;;;;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"}
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 (audit D4). Two forces meet here:
5
- * - Reserved multi-org namespace: `/o/{slug}/` is the decided shape for
6
- * per-org URLs (see ADR 0006). `o` is reserved even though the length gate
7
- * below already makes a 1-char slug impossible belt-and-suspenders, and it
8
- * documents intent for anyone relaxing the length rule later.
9
- * - Existing flat top-level routes: reserving these keeps a future move to
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
- * Coerce an arbitrary name into a slug candidate: lowercase, non-alphanumeric
18
- * runs collapsed to single hyphens, trimmed of edge hyphens, capped at 63 chars.
19
- * Produces the shape `SlugSchema` validates but does not itself guarantee
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;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAY3C,CAAC;AAIF;;;;;;GAMG;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;;;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"}
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 (audit D4). Two forces meet here:
5
- * - Reserved multi-org namespace: `/o/{slug}/` is the decided shape for
6
- * per-org URLs (see ADR 0006). `o` is reserved even though the length gate
7
- * below already makes a 1-char slug impossible belt-and-suspenders, and it
8
- * documents intent for anyone relaxing the length rule later.
9
- * - Existing flat top-level routes: reserving these keeps a future move to
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
- * Coerce an arbitrary name into a slug candidate: lowercase, non-alphanumeric
31
- * runs collapsed to single hyphens, trimmed of edge hyphens, capped at 63 chars.
32
- * Produces the shape `SlugSchema` validates but does not itself guarantee
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;;;;;;;;;;;;GAYG;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;;;;;;GAMG;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;;;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
+ {"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. 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.
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;;;;;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"}
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"}
@@ -1,10 +1,10 @@
1
1
  import type { DefinitionStatus } from './definitions/types.js';
2
2
  /**
3
- * Cursor-paginated list options. Adapters MUST provide sensible defaults
4
- * (limit=50, orderBy=createdAt desc) and clamp limit to a safe upper bound.
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
- * encodings. Callers must not inspect them.
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). Pass `['published']` for the runner home.
32
- * When set, `includePending` / `includeArchived` are ignored.
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
- * (an empty page), which is distinct from omitting the filter.
30
+ * Restrict to definitions in these projects. An empty array matches nothing,
31
+ * distinct from omitting the filter.
38
32
  *
39
- * This is what lets visibility filtering happen *in* the query rather than
40
- * over the fetched page: the caller resolves the accessible project-id set
41
- * first, then passes it here so the adapter applies both the filter and the
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
  }
@@ -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;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC9B;;;;;;;;;OASG;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"}
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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pagination.js","sourceRoot":"","sources":["../src/pagination.ts"],"names":[],"mappings":"AAsDA,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AACrC,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,CAAC"}
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.** Any operation
10
- * that would leave zero users holding `instance_admin` MUST return
11
- * `'last_admin'`. Auth providers consult `countInstanceAdminsExcluding`
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
- /** Batch-read for the admin user list. Admin-only. */
19
+ /** Admin-only. */
25
20
  getForBatch(ctx: RequestContext, userIds: readonly string[]): Promise<Map<string, PlatformPermission[]>>;
26
21
  /**
27
- * Replace the user's permissions. Idempotent. Returns:
28
- * - `ok` — succeeded
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`. Used by
38
- * first-run detection and the destructive-op invariant check. Adapters
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`. `deleteUser` / `disableUser`
44
- * call this BEFORE the destructive op — `count === 0` `'last_admin'`.
45
- * MUST exclude disabled users.
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;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,wBAAwB;IACxC;;;OAGG;IACH,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE3E,sDAAsD;IACtD,WAAW,CACV,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAE9C;;;;;;;;OAQG;IACH,GAAG,CACF,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;;OAIG;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
+ {"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-staff and instance operators;
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-staff and instance operators;
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',