@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.
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 +3 -3
@@ -1,31 +1,24 @@
1
1
  import type { RequestContext } from '../context.js';
2
2
  import type { PlatformProjectGrant } from './types.js';
3
3
  /**
4
- * Grants for `platform`-visibility projects. Enables `instance_admin` to
5
- * grant orgs or individual users view-only or view+solve access without
6
- * creating project membership rows.
4
+ * Grants for `platform`-visibility projects. Lets `instance_admin` grant orgs
5
+ * or individual users view-only or view+solve access without creating
6
+ * project membership rows.
7
7
  *
8
8
  * All deletes are hard-deletes — grants have no downstream references and
9
9
  * revocation is immediate.
10
10
  */
11
11
  export interface IPlatformProjectGrantStore {
12
12
  listByProject(ctx: RequestContext, projectId: string): Promise<PlatformProjectGrant[]>;
13
- /**
14
- * Grants for many projects in a single query. Keys are the requested
15
- * `projectIds`; a project with no grants maps to an empty array.
16
- */
13
+ /** Keys are the requested `projectIds`; a project with no grants maps to an empty array. */
17
14
  listByProjects(ctx: RequestContext, projectIds: readonly string[]): Promise<Map<string, PlatformProjectGrant[]>>;
18
15
  create(ctx: RequestContext, grant: PlatformProjectGrant): Promise<void>;
19
16
  delete(ctx: RequestContext, id: string): Promise<void>;
20
- /**
21
- * Cascade hook: drop every grant for a project. Called by `deleteProject`.
22
- * No-op when none exist.
23
- */
17
+ /** Cascade hook called by `deleteProject`. */
24
18
  deleteByProject(ctx: RequestContext, projectId: string): Promise<void>;
25
19
  /**
26
- * Cascade hook: drop every org grant whose `granteeId === orgId`. Called by
27
- * `deleteOrg`. User grants are identity-scoped and remain. No-op when none
28
- * exist.
20
+ * Cascade hook called by `deleteOrg`: drops every org grant whose
21
+ * `granteeId === orgId`. User grants are identity-scoped and remain.
29
22
  */
30
23
  deleteByGranteeOrg(ctx: RequestContext, orgId: string): Promise<void>;
31
24
  }
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/platformProjects/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IAC1C,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACvF;;;OAGG;IACH,cAAc,CACb,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;OAGG;IACH,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE;;;;OAIG;IACH,kBAAkB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/platformProjects/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,0BAA0B;IAC1C,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAAC;IACvF,4FAA4F;IAC5F,cAAc,CACb,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC;IAChD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,8CAA8C;IAC9C,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE;;;OAGG;IACH,kBAAkB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE"}
@@ -5,16 +5,13 @@ export type PlatformProjectGranteeType = 'org' | 'user';
5
5
  *
6
6
  * - `granteeType: 'org'` → applies to all members of that org
7
7
  * - `granteeType: 'user'` → applies to that specific user regardless of org
8
- * - `canSolve: false` → schema fetch / view only; submit-solve is blocked
9
- * - `canSolve: true` → view + solve
10
- *
11
- * Grants are hard-deleted on revocation — no soft-delete.
12
8
  */
13
9
  export interface PlatformProjectGrant {
14
10
  id: string;
15
11
  projectId: string;
16
12
  granteeType: PlatformProjectGranteeType;
17
13
  granteeId: string;
14
+ /** false = view/schema only; true = view + solve. */
18
15
  canSolve: boolean;
19
16
  createdBy: string;
20
17
  createdAt: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/platformProjects/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG,KAAK,GAAG,MAAM,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,0BAA0B,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/platformProjects/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG,KAAK,GAAG,MAAM,CAAC;AAExD;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,0BAA0B,CAAC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,qDAAqD;IACrD,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CAClB"}
@@ -12,31 +12,26 @@ export interface IProjectStore {
12
12
  getProjectBySlug(ctx: RequestContext, orgId: string, slug: string): Promise<Project | null>;
13
13
  createProject(ctx: RequestContext, project: Project): Promise<void>;
14
14
  updateProject(ctx: RequestContext, id: string, patch: Partial<Pick<Project, 'name' | 'slug' | 'description' | 'visibility' | 'autoJoinOnUpload'>>): Promise<void>;
15
- /**
16
- * Soft-delete the project. Cascades to project members and definitions.
17
- * Definition versions and share links cascade through the definition delete.
18
- */
15
+ /** Soft-delete. Cascades to project members and definitions (and, through the definition delete, to definition versions and share links). */
19
16
  deleteProject(ctx: RequestContext, id: string): Promise<void>;
20
17
  /**
21
- * Reactivate a previously soft-deleted project identified by its org + slug.
22
- * Clears `deleted_at` and reactivates the owner's `project_members` row.
23
- * Returns the live project, or `null` if no tombstone with that slug exists.
18
+ * Reactivates a soft-deleted project by org + slug: clears `deleted_at`
19
+ * and reactivates the owner's `project_members` row. Returns `null` if no
20
+ * tombstone with that slug exists.
24
21
  *
25
- * Use this when `createProject` fails with a duplicate-key error on a slug
26
- * that was soft-deleted — the unconditional unique constraint blocks creation
27
- * even though `getProjectBySlug` returns null for tombstones.
22
+ * Use this when `createProject` hits a duplicate-key error on a
23
+ * soft-deleted slug — the unique constraint isn't conditional, so it
24
+ * blocks creation even though `getProjectBySlug` returns null for tombstones.
28
25
  */
29
26
  reactivateProject(ctx: RequestContext, orgId: string, slug: string): Promise<Project | null>;
30
27
  listProjectMembers(ctx: RequestContext, projectId: string, opts?: ListOptions): Promise<Page<ProjectMember>>;
31
28
  getProjectMember(ctx: RequestContext, projectId: string, userId: string): Promise<ProjectMember | null>;
32
29
  /**
33
- * One user's membership row across many projects, in a single query.
34
- *
35
- * The access rules consult a membership row per project, so evaluating
36
- * `canView` over a project list otherwise costs one round-trip per project.
37
- * Keys are the requested `projectIds`; a project the user is not a member of
38
- * maps to `null` rather than being absent, so callers can distinguish
39
- * "checked, not a member" from "never asked".
30
+ * One user's membership row across many projects, in a single query
31
+ * avoids one round-trip per project when evaluating `canView` over a list.
32
+ * Keys are the requested `projectIds`; a project the user isn't a member of
33
+ * maps to `null` rather than being absent, distinguishing "checked, not a
34
+ * member" from "never asked".
40
35
  */
41
36
  getProjectMembersFor(ctx: RequestContext, projectIds: readonly string[], userId: string): Promise<Map<string, ProjectMember | null>>;
42
37
  addProjectMember(ctx: RequestContext, member: ProjectMember): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/projects/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,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAE7B,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7F,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrE,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC5F,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,aAAa,CACZ,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CACb,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,YAAY,GAAG,kBAAkB,CAAC,CAClF,GACC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;;;;;;;OAQG;IACH,iBAAiB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAG7F,kBAAkB,CACjB,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IAChC,gBAAgB,CACf,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IACjC;;;;;;;;OAQG;IACH,oBAAoB,CACnB,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9C,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,uBAAuB,CACtB,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3F"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/projects/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,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;GAGG;AACH,MAAM,WAAW,aAAa;IAE7B,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7F,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACrE,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAC5F,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,aAAa,CACZ,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CACb,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,GAAG,YAAY,GAAG,kBAAkB,CAAC,CAClF,GACC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,6IAA6I;IAC7I,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D;;;;;;;;OAQG;IACH,iBAAiB,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IAG7F,kBAAkB,CACjB,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;IAChC,gBAAgB,CACf,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAAC;IACjC;;;;;;OAMG;IACH,oBAAoB,CACnB,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC;IAC9C,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,uBAAuB,CACtB,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,WAAW,GACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3F"}
@@ -9,22 +9,19 @@ import type { ShareLink } from './types.js';
9
9
  * Reads filter `revokedAt IS NULL` defensively.
10
10
  */
11
11
  export interface IShareLinkStore {
12
- /** Insert a new link. Caller has already hashed the raw token. */
12
+ /** Caller has already hashed the raw token. */
13
13
  create(ctx: RequestContext, link: ShareLink): Promise<void>;
14
14
  /** Newest first by `createdAt`. Excludes revoked links. */
15
15
  listByDefinition(ctx: RequestContext, definitionId: string, opts?: ListOptions): Promise<Page<ShareLink>>;
16
16
  getById(ctx: RequestContext, id: string): Promise<ShareLink | null>;
17
- /**
18
- * Lookup by HMAC hash. Returns null when the link doesn't exist OR is
19
- * revoked OR its parent definition is soft-deleted.
20
- */
17
+ /** Returns null when the link doesn't exist, is revoked, or its parent definition is soft-deleted. */
21
18
  getByTokenHash(ctx: RequestContext, tokenHash: string): Promise<ShareLink | null>;
22
19
  /** Soft-delete (set `revokedAt`). Idempotent. */
23
20
  revoke(ctx: RequestContext, id: string): Promise<void>;
24
21
  /**
25
- * Atomic check-and-increment. Returns the new `solveCount`, or null when
26
- * the cap was reached. MUST be a single statement — read-then-write races
27
- * under load. `null` maxSolves means uncapped.
22
+ * Atomic check-and-increment; must be a single statement, since
23
+ * read-then-write races under load. Returns the new `solveCount`, or
24
+ * null when the cap was reached. `null` maxSolves means uncapped.
28
25
  */
29
26
  tryIncrementSolveCount(ctx: RequestContext, id: string): Promise<number | null>;
30
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/shareLinks/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,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC/B,kEAAkE;IAClE,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,2DAA2D;IAC3D,gBAAgB,CACf,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACpE;;;OAGG;IACH,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAClF,iDAAiD;IACjD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,sBAAsB,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChF"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/shareLinks/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,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC/B,+CAA+C;IAC/C,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,2DAA2D;IAC3D,gBAAgB,CACf,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACpE,sGAAsG;IACtG,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAClF,iDAAiD;IACjD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,sBAAsB,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChF"}
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/shareLinks/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;iBAWrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../src/shareLinks/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB;;;GAGG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;iBAOrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
@@ -8,12 +8,8 @@ export const CreateShareLinkInputSchema = z.object({
8
8
  channel: DefinitionChannelSchema.default('live'),
9
9
  name: z.string().max(128).optional(),
10
10
  allowSolve: z.boolean().default(true),
11
- /**
12
- * Null explicitly removes the cap. Omitted = apply default — null is the
13
- * minter's deliberate "uncap" choice.
14
- */
11
+ /** Null is the minter's deliberate "uncap" choice; omitted applies the default cap. */
15
12
  maxSolves: z.number().int().min(1).nullable().optional(),
16
- /** Optional ISO timestamp. Resolution compares to `now()`. */
17
13
  expiresAt: z.iso.datetime().nullable().optional()
18
14
  });
19
15
  //# sourceMappingURL=schemas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/shareLinks/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,uBAAuB,CAAC,OAAO,CAAC,MAAM,CAAC;IAChD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACpC,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACrC;;;OAGG;IACH,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACxD,8DAA8D;IAC9D,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACjD,CAAC,CAAC"}
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../src/shareLinks/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AAEpE;;;GAGG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,OAAO,EAAE,uBAAuB,CAAC,OAAO,CAAC,MAAM,CAAC;IAChD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IACpC,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACrC,uFAAuF;IACvF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACxD,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CACjD,CAAC,CAAC"}
@@ -1,26 +1,25 @@
1
1
  import type { DefinitionChannel } from '../definitions/types.js';
2
2
  /**
3
3
  * Per-definition token granting access to one (definitionId, channel)
4
- * without an account. The raw token is HMAC-hashed at rest; `tokenHash` is
5
- * the stored value. The plaintext token is shown to the minter exactly once.
4
+ * without an account. The plaintext token is shown to the minter exactly
5
+ * once; `tokenHash` is the HMAC stored at rest.
6
6
  */
7
7
  export interface ShareLink {
8
8
  id: string;
9
9
  definitionId: string;
10
10
  channel: DefinitionChannel;
11
- /** HMAC of the raw token. Lookup hashes the supplied token, then matches. */
12
11
  tokenHash: string;
13
- /** Optional UX label, e.g. "Demo for Acme". */
12
+ /** e.g. "Demo for Acme". */
14
13
  name?: string;
15
14
  createdBy: string;
16
15
  createdAt: string;
17
16
  /** Null = never expires. */
18
17
  expiresAt?: string | null;
19
- /** Non-null = revoked. Resolution checks IS NULL. */
18
+ /** Non-null = revoked. */
20
19
  revokedAt?: string | null;
21
20
  /** false = view/schema only; true = solve allowed. */
22
21
  allowSolve: boolean;
23
- /** Per-link cap. Null = unlimited. */
22
+ /** Null = unlimited. */
24
23
  maxSolves?: number | null;
25
24
  solveCount: number;
26
25
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,6EAA6E;IAC7E,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,qDAAqD;IACrD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sDAAsD;IACtD,UAAU,EAAE,OAAO,CAAC;IACpB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sDAAsD;IACtD,UAAU,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC"}
@@ -4,75 +4,61 @@ import type { RequestContext } from '../context.js';
4
4
  * inputKey)` where `inputKey` is a wide (SHA-256) hash of the transformed input
5
5
  * tree plus the solve-affecting config subset. A hit skips compute entirely.
6
6
  *
7
- * No backend ships today — see {@link ISolveResultCache} for why the interface
8
- * outlived the in-process implementation that used to sit behind it.
7
+ * Design contract:
9
8
  *
10
- * Design contract (decided 2026-07-11):
11
- *
12
- * - **Async from day one.** The memory backend returns promises too, so no call
13
- * site changes shape when a network store (Redis) arrives later.
14
- * - **Entries are opaque bytes** the pre-gzipped response envelope (R6) plus a
15
- * small metadata header. The backend never inspects them; memory stores the
16
- * same buffer Redis would, so a hit stays near-CPU-free in either backend and
17
- * there is no serialization drift between impls.
9
+ * - **Async from day one.** The in-memory backend returns promises too, so a
10
+ * network store (Redis) drops in later without any call site changing shape.
11
+ * - **Entries are opaque bytes** the pre-gzipped response envelope plus a
12
+ * small metadata header. The backend never inspects them, so a hit stays
13
+ * near-CPU-free in either backend and there's no serialization drift between
14
+ * implementations.
18
15
  * - **Best-effort.** `get` may miss at any time (restart, eviction, network
19
- * blip); `set` may silently drop. Correctness NEVER depends on cache presence
20
- * this is what makes backends interchangeable and what makes the
21
- * no-TTL/versionId keying safe under any eviction policy.
16
+ * blip); `set` may silently drop. Correctness never depends on cache presence
17
+ * this is what makes the no-TTL/versionId keying safe under any eviction
18
+ * policy.
22
19
  * - **Per-definition quota, passed at write time.** `set` carries
23
- * `maxEntriesForDefinition` so the backend holds no policy, only data. Eviction
24
- * is LRU *within* the definition: a slider-heavy definition churns only its own
25
- * entries, not everyone else's.
26
- * - **Version keying = no invalidation.** Publishing mints a new `versionId` →
27
- * fresh keyspace; rollback re-hits old entries; there is nothing to invalidate.
20
+ * `maxEntriesForDefinition` so the backend holds no policy, only data.
21
+ * Eviction is LRU *within* the definition: a slider-heavy definition churns
22
+ * only its own entries, not everyone else's.
23
+ * - **Version keying means no invalidation.** Publishing mints a new
24
+ * `versionId` → fresh keyspace; rollback re-hits old entries; there's
25
+ * nothing to invalidate.
28
26
  */
29
27
  /** The parts that address a cached solve. All four are folded into the stored key. */
30
28
  export interface SolveCacheKey {
31
29
  /**
32
- * Owning org (defense-in-depth against cross-tenant reads). Null for
33
- * remote-URL solves that have no org those are not cached (the app passes
34
- * the cache hook only for org-scoped live-channel solves).
30
+ * Owning org (defense-in-depth against cross-tenant reads). Always a real
31
+ * org, never null the app only builds a `SolveCacheKey` for org-scoped
32
+ * live-channel solves; remote-URL solves (no org) never reach this path.
35
33
  */
36
34
  orgId: string;
37
35
  /** The definition guid — the quota scope. */
38
36
  definitionId: string;
39
- /** The immutable version id — no TTL needed, so entries never go stale. */
37
+ /** The immutable version id. */
40
38
  versionId: string;
41
- /**
42
- * Wide hash of the transformed input tree + solve-affecting config subset
43
- * (SHA-256 hex; see the pipeline's key builder). This is the only part that
44
- * varies per solve of a given version.
45
- */
39
+ /** SHA-256 hex hash of the transformed input tree + solve-affecting config subset. */
46
40
  inputKey: string;
47
41
  }
48
42
  /** Options for a write; carries the per-definition quota so the backend stays stateless. */
49
43
  export interface SolveCacheSetOptions {
50
44
  /**
51
- * Max cached entries this definition may retain. The backend evicts
52
- * LRU-within-definition down to this count on write. A definition's quota is
53
- * `solveCacheLimit` on the definition record; a caller must not call `set` when
54
- * the resolved quota is `0` (caching off), so this is always `>= 1`.
45
+ * Max cached entries this definition may retain (`solveCacheLimit` on the
46
+ * definition record). Always `>= 1` callers must not call `set` when the
47
+ * resolved quota is `0` (caching off).
55
48
  */
56
49
  maxEntriesForDefinition: number;
57
50
  }
58
51
  /**
59
- * Durable solve-result cache — the seam a SHARED backend mounts on.
60
- *
61
- * There is deliberately no implementation today. The in-process one that used to
62
- * live behind this interface was redundant: it was a `Map` in the same heap as
63
- * the scheduler's own response cache, which is consulted first, so it could only
64
- * ever serve what that cache had already evicted. It was deleted; this interface
65
- * was not, because it is the piece that is correct for scaling.
52
+ * Durable solve-result cache — the seam a shared backend mounts on.
66
53
  *
67
- * The reason to keep it: the app runs on `adapter-node`, one long-lived process,
68
- * so in-process caches work well for a single instance. Run N instances behind a
69
- * proxy and every in-process hit rate divides by N. When that day comes the answer
70
- * is Redis behind this interface — async from day one, opaque bytes, best-effort
71
- * by contract, so a network backend drops in without any call site changing shape.
54
+ * No implementation ships today: the app runs on `adapter-node`, one
55
+ * long-lived process, where in-process caching already works. Run N instances
56
+ * behind a proxy and the in-process hit rate divides by N that's when Redis
57
+ * mounts here.
72
58
  *
73
- * Implementations MUST NOT throw — both methods are best-effort on the hot path
74
- * of every live solve. A backend failure resolves as a miss (`get`) or a silent
75
- * drop (`set`); it never becomes a request error.
59
+ * Implementations must not throw — both methods sit on the hot path of every
60
+ * live solve. A backend failure resolves as a miss (`get`) or a silent drop
61
+ * (`set`); it never becomes a request error.
76
62
  */
77
63
  export interface ISolveResultCache {
78
64
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/solveCache/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,4FAA4F;AAC5F,MAAM,WAAW,oBAAoB;IACpC;;;;;OAKG;IACH,uBAAuB,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACzE;;;OAGG;IACH,GAAG,CACF,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,oBAAoB,GACxB,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IACvD,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAG1E,GAAG,CACR,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC;CAChB"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/solveCache/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC7B;;;;OAIG;IACH,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,4FAA4F;AAC5F,MAAM,WAAW,oBAAoB;IACpC;;;;OAIG;IACH,uBAAuB,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IACjC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACzE;;;OAGG;IACH,GAAG,CACF,GAAG,EAAE,cAAc,EACnB,GAAG,EAAE,aAAa,EAClB,KAAK,EAAE,UAAU,EACjB,IAAI,EAAE,oBAAoB,GACxB,OAAO,CAAC,IAAI,CAAC,CAAC;CACjB;AAED;;;;GAIG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IACvD,GAAG,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAG1E,GAAG,CACR,IAAI,EAAE,cAAc,EACpB,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,oBAAoB,GACzB,OAAO,CAAC,IAAI,CAAC;CAChB"}
@@ -1 +1 @@
1
- {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/solveCache/interface.ts"],"names":[],"mappings":"AAkGA;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAChC,KAAK,CAAC,GAAG,CAAC,IAAoB,EAAE,IAAmB;QAClD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,GAAG,CACR,IAAoB,EACpB,IAAmB,EACnB,MAAkB,EAClB,KAA2B,IACV,CAAC;CACnB"}
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/solveCache/interface.ts"],"names":[],"mappings":"AAoFA;;;;GAIG;AACH,MAAM,OAAO,oBAAoB;IAChC,KAAK,CAAC,GAAG,CAAC,IAAoB,EAAE,IAAmB;QAClD,OAAO,IAAI,CAAC;IACb,CAAC;IACD,KAAK,CAAC,GAAG,CACR,IAAoB,EACpB,IAAmB,EACnB,MAAkB,EAClB,KAA2B,IACV,CAAC;CACnB"}
@@ -1,18 +1,12 @@
1
1
  /**
2
- * How a stored asset is allowed to be read. This is a property of the asset
3
- * *class* (its path prefix), never of the individual file — so a logo and a
4
- * pricing sheet differ only in which class they belong to, and adding a new
5
- * asset type is one entry in {@link ASSET_CLASSES} rather than a new route.
2
+ * How a stored asset is allowed to be read. A property of the asset *class*
3
+ * (its path prefix), never of the individual file — a new asset type is one
4
+ * entry in {@link ASSET_CLASSES} rather than a new route.
6
5
  *
7
- * - `public` — anyone, including logged-out visitors. Served with no auth via
8
- * a CDN/public bucket (Supabase) or a shape-gated proxy branch (local). Used
9
- * for branding (logo, favicon) that appears on viewer headers and login pages.
10
- * - `org` — members of the owning org only. The route resolves the orgId
11
- * from the path and runs an org-membership check. Used for org-private docs
12
- * (e.g. pricing sheets) once they exist.
13
- * - `project` — members of the owning project only. The route resolves the
14
- * definition guid → its project and runs the project-view check. Used for
15
- * definition cover images and other per-definition blobs.
6
+ * - `public` — anyone, including logged-out visitors (branding: logo, favicon).
7
+ * - `org` — members of the owning org only; route resolves orgId from the path.
8
+ * - `project` members of the owning project only; route resolves the
9
+ * definition guid to its project (cover images, per-definition blobs).
16
10
  */
17
11
  export type AssetVisibility = 'public' | 'org' | 'project';
18
12
  /**
@@ -37,21 +31,19 @@ export interface AssetMatch {
37
31
  readonly scopeId: string | null;
38
32
  }
39
33
  /**
40
- * The closed registry of servable asset classes. Order matters only for
41
- * readability patterns are mutually exclusive by prefix. Anything that
42
- * matches no class is unservable (the route 404s), which keeps the proxy
43
- * default-deny: a new blob type is opt-in by adding an entry here.
34
+ * The closed registry of servable asset classes. Patterns are mutually
35
+ * exclusive by prefix, order doesn't matter. Anything matching no class is
36
+ * unservable (the route 404s) — default-deny, so a new blob type is opt-in.
44
37
  */
45
38
  export declare const ASSET_CLASSES: readonly AssetClass[];
46
39
  /**
47
- * Classify a storage path into its asset class and scope id, or null when no
48
- * class matches (or the path is unsafe). Callers — `getPublicUrl` (to pick CDN
49
- * vs proxy) and the serving route (to pick the auth check) — consult this so
50
- * URL generation and authorization never drift apart.
40
+ * Classifies a storage path into its asset class and scope id, or null when
41
+ * no class matches (or the path is unsafe). `getPublicUrl` and the serving
42
+ * route both consult this so URL generation and authorization never drift
43
+ * apart.
51
44
  *
52
- * For `org-branding` the orgId is captured as group 1 but the class is public,
53
- * so `scopeId` is reported as the captured id only when the class actually
54
- * authorizes against it (`scope !== 'none'`); public classes report null.
45
+ * `scopeId` is null for `scope: 'none'` classes even when the pattern
46
+ * captures an id (e.g. `org-branding` captures orgId but is public).
55
47
  */
56
48
  export declare function classifyAssetPath(storagePath: string): AssetMatch | null;
57
49
  /** True when the path belongs to a `public` asset class (CDN-servable, no auth). */
@@ -1 +1 @@
1
- {"version":3,"file":"assetClasses.d.ts","sourceRoot":"","sources":["../../src/storage/assetClasses.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEpD,MAAM,WAAW,UAAU;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAoBD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAqB9C,CAAC;AAoBF;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQxE;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE9D"}
1
+ {"version":3,"file":"assetClasses.d.ts","sourceRoot":"","sources":["../../src/storage/assetClasses.ts"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,KAAK,GAAG,SAAS,CAAC;AAE3D;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEpD,MAAM,WAAW,UAAU;IAC1B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,uEAAuE;IACvE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAiBD;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,SAAS,UAAU,EAqB9C,CAAC;AAkBF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQxE;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAE9D"}
@@ -1,23 +1,19 @@
1
1
  import { ALL_ORG_ASSET_KINDS } from '../organizations/schemas.js';
2
2
  import { COVER_IMAGE_EXTENSIONS } from '../definitions/types.js';
3
- // Org branding kinds (logo, favicon, …) are the public set. Built from the
4
- // schema enum so adding a kind there extends this pattern automatically.
3
+ // Built from the schema enum so a new branding kind extends this pattern automatically.
5
4
  const BRANDING_KINDS = ALL_ORG_ASSET_KINDS.join('|');
6
- // Cover extensions are derived from the canonical `COVER_IMAGE_EXTENSIONS`
7
- // (definitions/types.ts) strip the leading dot and escape so adding a new
8
- // cover format there propagates here instead of silently 404ing legit covers.
5
+ // Derived from COVER_IMAGE_EXTENSIONS so a new cover format propagates here
6
+ // instead of silently 404ing legit covers.
9
7
  const COVER_EXTS = COVER_IMAGE_EXTENSIONS.map((ext) => ext.replace(/^\./, '').replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|');
10
- // Reusable segment alphabets. `SAFE_SEGMENT` mirrors the `assertSafeKey`
11
- // alphabet in the path helpers (traversal/empty segments are rejected
12
- // separately by `hasUnsafeSegment`); `GUID` is the canonical definition guid
13
- // shape — kept in sync with `UUID_REGEX` in definitions/schemas.ts.
8
+ // SAFE_SEGMENT mirrors the assertSafeKey alphabet in the path helpers
9
+ // (traversal/empty segments are rejected separately by hasUnsafeSegment);
10
+ // GUID is kept in sync with UUID_REGEX in definitions/schemas.ts.
14
11
  const SAFE_SEGMENT = String.raw `[A-Za-z0-9._-]+`;
15
12
  const GUID = String.raw `[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}`;
16
13
  /**
17
- * The closed registry of servable asset classes. Order matters only for
18
- * readability patterns are mutually exclusive by prefix. Anything that
19
- * matches no class is unservable (the route 404s), which keeps the proxy
20
- * default-deny: a new blob type is opt-in by adding an entry here.
14
+ * The closed registry of servable asset classes. Patterns are mutually
15
+ * exclusive by prefix, order doesn't matter. Anything matching no class is
16
+ * unservable (the route 404s) — default-deny, so a new blob type is opt-in.
21
17
  */
22
18
  export const ASSET_CLASSES = [
23
19
  {
@@ -40,14 +36,12 @@ export const ASSET_CLASSES = [
40
36
  }
41
37
  ];
42
38
  /**
43
- * Reject any path that contains a traversal, empty, or backslash segment
44
- * *before* it can match a class. The class patterns use a permissive segment
45
- * alphabet (`[A-Za-z0-9._-]+`) so dotted ids and filenames work, but that
46
- * alphabet also admits a bare `.` or `..` *as a whole segment* — which would
47
- * let `orgs/../branding/logo.webp` classify as public branding with `..`
48
- * captured as the orgId. This mirrors `assertSafeKey` in the path builders:
49
- * the registry is the read-side gate, those are the write-side gate, and both
50
- * forbid the same segments so a path that can't be *written* can't be *read*.
39
+ * Rejects traversal, empty, or backslash segments before a path can match a
40
+ * class. The permissive segment alphabet (`[A-Za-z0-9._-]+`) admits a bare
41
+ * `.` or `..` as a whole segment, which would otherwise let
42
+ * `orgs/../branding/logo.webp` classify as public branding with `..`
43
+ * captured as the orgId. Mirrors `assertSafeKey` on the write side, so a path
44
+ * that can't be written can't be read either.
51
45
  */
52
46
  function hasUnsafeSegment(storagePath) {
53
47
  if (storagePath.includes('\\'))
@@ -59,14 +53,13 @@ function hasUnsafeSegment(storagePath) {
59
53
  return false;
60
54
  }
61
55
  /**
62
- * Classify a storage path into its asset class and scope id, or null when no
63
- * class matches (or the path is unsafe). Callers — `getPublicUrl` (to pick CDN
64
- * vs proxy) and the serving route (to pick the auth check) — consult this so
65
- * URL generation and authorization never drift apart.
56
+ * Classifies a storage path into its asset class and scope id, or null when
57
+ * no class matches (or the path is unsafe). `getPublicUrl` and the serving
58
+ * route both consult this so URL generation and authorization never drift
59
+ * apart.
66
60
  *
67
- * For `org-branding` the orgId is captured as group 1 but the class is public,
68
- * so `scopeId` is reported as the captured id only when the class actually
69
- * authorizes against it (`scope !== 'none'`); public classes report null.
61
+ * `scopeId` is null for `scope: 'none'` classes even when the pattern
62
+ * captures an id (e.g. `org-branding` captures orgId but is public).
70
63
  */
71
64
  export function classifyAssetPath(storagePath) {
72
65
  if (hasUnsafeSegment(storagePath))
@@ -1 +1 @@
1
- {"version":3,"file":"assetClasses.js","sourceRoot":"","sources":["../../src/storage/assetClasses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AA4CjE,2EAA2E;AAC3E,yEAAyE;AACzE,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAErD,2EAA2E;AAC3E,4EAA4E;AAC5E,8EAA8E;AAC9E,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACrD,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAC7D,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,yEAAyE;AACzE,sEAAsE;AACtE,6EAA6E;AAC7E,oEAAoE;AACpE,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA,iBAAiB,CAAC;AACjD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA,8DAA8D,CAAC;AAEtF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAA0B;IACnD;QACC,EAAE,EAAE,cAAc;QAClB,UAAU,EAAE,QAAQ;QACpB,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,IAAI,MAAM,CAClB,MAAM,CAAC,GAAG,CAAA,WAAW,YAAY,mBAAmB,cAAc,UAAU,CAC5E;KACD;IACD;QACC,EAAE,EAAE,aAAa;QACjB,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,WAAW,YAAY,eAAe,YAAY,GAAG,CAAC;KACpF;IACD;QACC,EAAE,EAAE,kBAAkB;QACtB,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,kBAAkB,IAAI,gBAAgB,UAAU,IAAI,EAAE,GAAG,CAAC;KACxF;CACD,CAAC;AAEF;;;;;;;;;GASG;AACH,SAAS,gBAAgB,CAAC,WAAmB;IAC5C,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACpD,IAAI,gBAAgB,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACpD,OAAO,iBAAiB,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"assetClasses.js","sourceRoot":"","sources":["../../src/storage/assetClasses.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAsCjE,wFAAwF;AACxF,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAErD,4EAA4E;AAC5E,2CAA2C;AAC3C,MAAM,UAAU,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CACrD,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAC7D,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEZ,sEAAsE;AACtE,0EAA0E;AAC1E,kEAAkE;AAClE,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAA,iBAAiB,CAAC;AACjD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAA,8DAA8D,CAAC;AAEtF;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAA0B;IACnD;QACC,EAAE,EAAE,cAAc;QAClB,UAAU,EAAE,QAAQ;QACpB,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,IAAI,MAAM,CAClB,MAAM,CAAC,GAAG,CAAA,WAAW,YAAY,mBAAmB,cAAc,UAAU,CAC5E;KACD;IACD;QACC,EAAE,EAAE,aAAa;QACjB,UAAU,EAAE,KAAK;QACjB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,WAAW,YAAY,eAAe,YAAY,GAAG,CAAC;KACpF;IACD;QACC,EAAE,EAAE,kBAAkB;QACtB,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE,SAAS;QAChB,OAAO,EAAE,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,kBAAkB,IAAI,gBAAgB,UAAU,IAAI,EAAE,GAAG,CAAC;KACxF;CACD,CAAC;AAEF;;;;;;;GAOG;AACH,SAAS,gBAAgB,CAAC,WAAmB;IAC5C,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9C,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACpD,IAAI,gBAAgB,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACjC,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxC,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;IAC9E,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACpD,OAAO,iBAAiB,CAAC,WAAW,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,QAAQ,CAAC;AACtE,CAAC"}
@@ -1,21 +1,19 @@
1
1
  /**
2
- * Append a cache-busting token to a stored-asset URL.
2
+ * Appends a cache-busting token to a stored-asset URL.
3
3
  *
4
- * Mutable blobs are overwritten **in place** (`IStorageProvider.put` is upsert),
5
- * so a re-upload keeps the same storage path and therefore the same public
6
- * URL. A browser/CDN that cached the old bytes under that URL keeps serving them
7
- * until the TTL expires, which reads as "the replace didn't work". Appending a
8
- * token that changes only when the content changes gives each new version a
9
- * distinct URL (forcing a refetch) while letting unchanged assets stay cached.
4
+ * `IStorageProvider.put` upserts, so a re-upload keeps the same storage path
5
+ * and public URL a browser/CDN caching the old bytes under that URL keeps
6
+ * serving them past the TTL, which reads as "the replace didn't work."
7
+ * Appending a token that only changes with the content gives each version a
8
+ * distinct URL, forcing a refetch, while unchanged assets stay cached.
10
9
  *
11
- * Generic over asset kind: the caller supplies the token from whatever it has
12
- * that tracks the blob's version a content hash, the owning record's
13
- * `updatedAt`, a version counter. The serving route ignores the query string
14
- * (SvelteKit's `[...path]` param never includes it), so this is purely a
15
- * client-cache key and needs no route support.
10
+ * Generic over asset kind pass whatever tracks the blob's version (content
11
+ * hash, `updatedAt`, a counter). The serving route ignores the query string
12
+ * (SvelteKit's `[...path]` param never includes it), so this needs no route
13
+ * support.
16
14
  *
17
- * Empty/whitespace tokens are dropped (returns the URL unchanged) so a missing
18
- * token degrades to "no cache-bust" rather than `?v=`.
15
+ * Empty/whitespace tokens return the URL unchanged, so a missing token
16
+ * degrades to "no cache-bust" rather than `?v=`.
19
17
  */
20
18
  export declare function withCacheBust(url: string, token: string | number | undefined | null): string;
21
19
  //# sourceMappingURL=cacheBust.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cacheBust.d.ts","sourceRoot":"","sources":["../../src/storage/cacheBust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAM5F"}
1
+ {"version":3,"file":"cacheBust.d.ts","sourceRoot":"","sources":["../../src/storage/cacheBust.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAM5F"}