@selvajs/platform 0.14.2 → 0.14.3-beta.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 (85) hide show
  1. package/dist/computeServer/index.d.ts +2 -0
  2. package/dist/computeServer/index.d.ts.map +1 -1
  3. package/dist/computeServer/index.js +6 -0
  4. package/dist/computeServer/index.js.map +1 -1
  5. package/dist/computeServer/interface.d.ts +10 -0
  6. package/dist/computeServer/interface.d.ts.map +1 -1
  7. package/dist/computeServer/secrets.d.ts +53 -0
  8. package/dist/computeServer/secrets.d.ts.map +1 -0
  9. package/dist/computeServer/secrets.js +67 -0
  10. package/dist/computeServer/secrets.js.map +1 -0
  11. package/dist/context.d.ts +7 -0
  12. package/dist/context.d.ts.map +1 -1
  13. package/dist/context.js +13 -0
  14. package/dist/context.js.map +1 -1
  15. package/dist/definitions/interface.d.ts +8 -0
  16. package/dist/definitions/interface.d.ts.map +1 -1
  17. package/dist/errors/interface.d.ts +44 -0
  18. package/dist/errors/interface.d.ts.map +1 -0
  19. package/dist/errors/interface.js +9 -0
  20. package/dist/errors/interface.js.map +1 -0
  21. package/dist/index.d.ts +11 -4
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +6 -2
  24. package/dist/index.js.map +1 -1
  25. package/dist/organizations/index.d.ts +4 -3
  26. package/dist/organizations/index.d.ts.map +1 -1
  27. package/dist/organizations/index.js +2 -1
  28. package/dist/organizations/index.js.map +1 -1
  29. package/dist/organizations/interface.d.ts +1 -1
  30. package/dist/organizations/interface.d.ts.map +1 -1
  31. package/dist/organizations/paths.d.ts +22 -0
  32. package/dist/organizations/paths.d.ts.map +1 -0
  33. package/dist/organizations/paths.js +43 -0
  34. package/dist/organizations/paths.js.map +1 -0
  35. package/dist/organizations/schemas.d.ts +10 -0
  36. package/dist/organizations/schemas.d.ts.map +1 -1
  37. package/dist/organizations/schemas.js +6 -0
  38. package/dist/organizations/schemas.js.map +1 -1
  39. package/dist/organizations/types.d.ts +10 -1
  40. package/dist/organizations/types.d.ts.map +1 -1
  41. package/dist/storage/assetClasses.d.ts +59 -0
  42. package/dist/storage/assetClasses.d.ts.map +1 -0
  43. package/dist/storage/assetClasses.js +86 -0
  44. package/dist/storage/assetClasses.js.map +1 -0
  45. package/dist/storage/cacheBust.d.ts +21 -0
  46. package/dist/storage/cacheBust.d.ts.map +1 -0
  47. package/dist/storage/cacheBust.js +29 -0
  48. package/dist/storage/cacheBust.js.map +1 -0
  49. package/dist/storage/image.d.ts +6 -1
  50. package/dist/storage/image.d.ts.map +1 -1
  51. package/dist/storage/image.js +8 -3
  52. package/dist/storage/image.js.map +1 -1
  53. package/dist/storage/index.d.ts +3 -0
  54. package/dist/storage/index.d.ts.map +1 -1
  55. package/dist/storage/index.js +2 -0
  56. package/dist/storage/index.js.map +1 -1
  57. package/dist/testing/suites/definitionStoreSuite.d.ts.map +1 -1
  58. package/dist/testing/suites/definitionStoreSuite.js +30 -0
  59. package/dist/testing/suites/definitionStoreSuite.js.map +1 -1
  60. package/dist/testing/suites/orgStoreSuite.d.ts.map +1 -1
  61. package/dist/testing/suites/orgStoreSuite.js +12 -0
  62. package/dist/testing/suites/orgStoreSuite.js.map +1 -1
  63. package/dist/testing/suites/storageProviderSuite.d.ts.map +1 -1
  64. package/dist/testing/suites/storageProviderSuite.js +18 -0
  65. package/dist/testing/suites/storageProviderSuite.js.map +1 -1
  66. package/package.json +2 -2
  67. package/src/computeServer/index.ts +11 -0
  68. package/src/computeServer/interface.ts +11 -0
  69. package/src/computeServer/secrets.ts +102 -0
  70. package/src/context.ts +14 -0
  71. package/src/definitions/interface.ts +9 -0
  72. package/src/errors/interface.ts +45 -0
  73. package/src/index.ts +30 -2
  74. package/src/organizations/index.ts +11 -2
  75. package/src/organizations/interface.ts +1 -1
  76. package/src/organizations/paths.ts +45 -0
  77. package/src/organizations/schemas.ts +9 -0
  78. package/src/organizations/types.ts +11 -1
  79. package/src/storage/assetClasses.ts +134 -0
  80. package/src/storage/cacheBust.ts +26 -0
  81. package/src/storage/image.ts +8 -3
  82. package/src/storage/index.ts +3 -0
  83. package/src/testing/suites/definitionStoreSuite.ts +45 -0
  84. package/src/testing/suites/orgStoreSuite.ts +17 -0
  85. package/src/testing/suites/storageProviderSuite.ts +21 -0
@@ -1,6 +1,8 @@
1
1
  export type { ComputeServerConfig, ComputeConfig, PlatformComputeServer, OrgComputeServer } from './types.js';
2
2
  export { isPlatformServer, isOrgServer } from './types.js';
3
3
  export type { IComputeServerStore } from './interface.js';
4
+ export { isEncryptedSecret, encryptSecret, decryptSecret, decodeSecretKey } from './secrets.js';
5
+ export type { SecretVerificationReport, SecretVerificationFailure, SecretVerificationFailureReason } from './secrets.js';
4
6
  export type { ResolveOptions } from './utils.js';
5
7
  export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor } from './utils.js';
6
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,mBAAmB,EACnB,aAAa,EACb,qBAAqB,EACrB,gBAAgB,EAChB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAM1D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAChG,YAAY,EACX,wBAAwB,EACxB,yBAAyB,EACzB,+BAA+B,EAC/B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,YAAY,CAAC"}
@@ -1,3 +1,9 @@
1
1
  export { isPlatformServer, isOrgServer } from './types.js';
2
+ // At-rest secret crypto (uses `node:crypto`). Server-only — deliberately NOT
3
+ // re-exported from the root barrel, which client `.svelte` code imports and
4
+ // where a browser bundle can't resolve `node:crypto`. Import these from
5
+ // `@selvajs/platform/computeServer` in server code. The report TYPES are erased
6
+ // at build, so they also stay re-exported from the root barrel for convenience.
7
+ export { isEncryptedSecret, encryptSecret, decryptSecret, decodeSecretKey } from './secrets.js';
2
8
  export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor } from './utils.js';
3
9
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG3D,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/computeServer/index.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE3D,6EAA6E;AAC7E,4EAA4E;AAC5E,wEAAwE;AACxE,gFAAgF;AAChF,gFAAgF;AAChF,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAOhG,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,YAAY,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import type { RequestContext } from '../context.js';
2
2
  import type { ComputeConfig, ComputeServerConfig } from './types.js';
3
+ import type { SecretVerificationReport } from './secrets.js';
3
4
  /**
4
5
  * Compute-server configuration. Architecture spec §4.8.
5
6
  *
@@ -45,5 +46,14 @@ export interface IComputeServerStore {
45
46
  * compute config behind.
46
47
  */
47
48
  deleteByOrg(ctx: RequestContext, orgId: string): Promise<void>;
49
+ /**
50
+ * Boot-time integrity check: attempt to decrypt every stored `apiKey` and
51
+ * report any that are plaintext-at-rest or fail to decrypt under the current
52
+ * `SELVA_AT_REST_KEY`. Does NOT throw — returns a structured report so the
53
+ * caller (boot health) decides whether to refuse boot / drive `/api/health`
54
+ * to 503. Both encrypting stores (local file, Supabase) implement this;
55
+ * optional so a hypothetical non-encrypting store can omit it.
56
+ */
57
+ verifySecrets?(): Promise<SecretVerificationReport>;
48
58
  }
49
59
  //# sourceMappingURL=interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/computeServer/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAErE;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEvD;;;OAGG;IACH,mBAAmB,CAClB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;;OAMG;IACH,cAAc,CACb,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1F;;;;;;OAMG;IACH,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/computeServer/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAE7D;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IACnC;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEvD;;;OAGG;IACH,mBAAmB,CAClB,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,EAAE,MAAM,GAAG,SAAS,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;;OAMG;IACH,cAAc,CACb,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,EAAE,EAC9B,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;OAKG;IACH,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1F;;;;;;OAMG;IACH,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/D;;;;;;;OAOG;IACH,aAAa,CAAC,IAAI,OAAO,CAAC,wBAAwB,CAAC,CAAC;CACpD"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * AES-256-GCM envelope for at-rest secrets (e.g. compute API keys).
3
+ *
4
+ * Wire format: `enc:v1:<base64(iv|tag|ciphertext)>`. The version prefix lets
5
+ * us migrate to a new algorithm later without ambiguity. Plaintext never sits
6
+ * at rest — on disk (local provider) or in the DB (Supabase provider).
7
+ *
8
+ * Security model: defends against backup leaks, accidental file/DB sharing,
9
+ * and read-only storage access. An attacker with both the stored ciphertext
10
+ * *and* the master key (`SELVA_AT_REST_KEY` env var, process memory) can still
11
+ * decrypt — this is encryption at rest, not a secret manager.
12
+ *
13
+ * Provider-agnostic: pure `node:crypto`, no fs or DB coupling, so both the
14
+ * local and Supabase compute-server stores share this one implementation.
15
+ */
16
+ export declare function isEncryptedSecret(value: string): boolean;
17
+ export declare function encryptSecret(plaintext: string, key: Buffer): string;
18
+ export declare function decryptSecret(envelope: string, key: Buffer): string;
19
+ /**
20
+ * Decode a `SELVA_AT_REST_KEY` env var into a 32-byte buffer. Accepts either
21
+ * 64-char hex or base64 (with or without padding). Throws on anything else
22
+ * so misconfiguration fails loudly at boot rather than silently producing
23
+ * an undecryptable value.
24
+ */
25
+ export declare function decodeSecretKey(raw: string): Buffer;
26
+ /**
27
+ * Result of a compute-server store's `verifySecrets()`. One `failures` entry
28
+ * per server whose `apiKey` couldn't be loaded:
29
+ * - `plaintext_on_disk` — the field exists but isn't an `enc:v1:` envelope.
30
+ * Either a hand-edit, a legacy row from before encryption, or a migration
31
+ * regression. Security-relevant.
32
+ * - `key_mismatch` — envelope is valid but GCM auth-tag verification
33
+ * fails under the current `SELVA_AT_REST_KEY`. The key was rotated or the
34
+ * data came from another deployment.
35
+ *
36
+ * Storage-agnostic (`plaintext_on_disk` reads "plaintext at rest" for both the
37
+ * file- and DB-backed stores) so boot health can treat every provider alike.
38
+ */
39
+ export type SecretVerificationFailureReason = 'key_mismatch' | 'plaintext_on_disk';
40
+ export interface SecretVerificationFailure {
41
+ serverId: string;
42
+ serverLabel: string;
43
+ reason: SecretVerificationFailureReason;
44
+ /** Underlying error message for `key_mismatch`. Absent for plaintext. */
45
+ cause?: string;
46
+ }
47
+ export interface SecretVerificationReport {
48
+ ok: boolean;
49
+ failures: SecretVerificationFailure[];
50
+ /** True if at least one row holds an unencrypted apiKey at rest. */
51
+ plaintextFound: boolean;
52
+ }
53
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/computeServer/secrets.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;GAcG;AAEH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAYpE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAcnE;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,+BAA+B,GAAG,cAAc,GAAG,mBAAmB,CAAC;AAEnF,MAAM,WAAW,yBAAyB;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,+BAA+B,CAAC;IACxC,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,wBAAwB;IACxC,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,yBAAyB,EAAE,CAAC;IACtC,oEAAoE;IACpE,cAAc,EAAE,OAAO,CAAC;CACxB"}
@@ -0,0 +1,67 @@
1
+ import { randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';
2
+ const ALGO = 'aes-256-gcm';
3
+ const IV_BYTES = 12;
4
+ const TAG_BYTES = 16;
5
+ const PREFIX = 'enc:v1:';
6
+ /**
7
+ * AES-256-GCM envelope for at-rest secrets (e.g. compute API keys).
8
+ *
9
+ * Wire format: `enc:v1:<base64(iv|tag|ciphertext)>`. The version prefix lets
10
+ * us migrate to a new algorithm later without ambiguity. Plaintext never sits
11
+ * at rest — on disk (local provider) or in the DB (Supabase provider).
12
+ *
13
+ * Security model: defends against backup leaks, accidental file/DB sharing,
14
+ * and read-only storage access. An attacker with both the stored ciphertext
15
+ * *and* the master key (`SELVA_AT_REST_KEY` env var, process memory) can still
16
+ * decrypt — this is encryption at rest, not a secret manager.
17
+ *
18
+ * Provider-agnostic: pure `node:crypto`, no fs or DB coupling, so both the
19
+ * local and Supabase compute-server stores share this one implementation.
20
+ */
21
+ export function isEncryptedSecret(value) {
22
+ return value.startsWith(PREFIX);
23
+ }
24
+ export function encryptSecret(plaintext, key) {
25
+ if (key.length !== 32) {
26
+ throw new Error(`Secret key must be 32 bytes; got ${key.length}`);
27
+ }
28
+ if (isEncryptedSecret(plaintext)) {
29
+ throw new Error('Refusing to encrypt a value that is already encrypted');
30
+ }
31
+ const iv = randomBytes(IV_BYTES);
32
+ const cipher = createCipheriv(ALGO, key, iv);
33
+ const ciphertext = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
34
+ const tag = cipher.getAuthTag();
35
+ return PREFIX + Buffer.concat([iv, tag, ciphertext]).toString('base64');
36
+ }
37
+ export function decryptSecret(envelope, key) {
38
+ if (key.length !== 32) {
39
+ throw new Error(`Secret key must be 32 bytes; got ${key.length}`);
40
+ }
41
+ if (!isEncryptedSecret(envelope)) {
42
+ throw new Error('Value is not an encrypted secret envelope');
43
+ }
44
+ const buf = Buffer.from(envelope.slice(PREFIX.length), 'base64');
45
+ const iv = buf.subarray(0, IV_BYTES);
46
+ const tag = buf.subarray(IV_BYTES, IV_BYTES + TAG_BYTES);
47
+ const ciphertext = buf.subarray(IV_BYTES + TAG_BYTES);
48
+ const decipher = createDecipheriv(ALGO, key, iv);
49
+ decipher.setAuthTag(tag);
50
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString('utf8');
51
+ }
52
+ /**
53
+ * Decode a `SELVA_AT_REST_KEY` env var into a 32-byte buffer. Accepts either
54
+ * 64-char hex or base64 (with or without padding). Throws on anything else
55
+ * so misconfiguration fails loudly at boot rather than silently producing
56
+ * an undecryptable value.
57
+ */
58
+ export function decodeSecretKey(raw) {
59
+ if (/^[0-9a-fA-F]{64}$/.test(raw))
60
+ return Buffer.from(raw, 'hex');
61
+ const buf = Buffer.from(raw, 'base64');
62
+ if (buf.length === 32)
63
+ return buf;
64
+ throw new Error('SELVA_AT_REST_KEY must be 32 bytes encoded as 64-char hex or base64. ' +
65
+ "Generate one with: node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\"");
66
+ }
67
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/computeServer/secrets.ts"],"names":[],"mappings":"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"}
package/dist/context.d.ts CHANGED
@@ -38,4 +38,11 @@ export declare const SYSTEM_CONTEXT: RequestContext;
38
38
  * `actingOrgId` returns false unless `instance_admin` or `system`.
39
39
  */
40
40
  export declare function hasPermission(ctx: RequestContext, permission: PlatformPermission | OrgPermission): boolean;
41
+ /**
42
+ * Return the org the caller is acting as, or throw `ProviderError(403)` when
43
+ * the context has none. Stores that scope every row to an acting org repeat
44
+ * this guard; centralizing it keeps the failure a single, consistent 403
45
+ * rather than a `null` that leaks into a query as `org_id = undefined`.
46
+ */
47
+ export declare function requireActingOrg(ctx: RequestContext): string;
41
48
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC9B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,6CAA6C;IAC7C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,wCAAwC;IACxC,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,cAK5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,kBAAkB,GAAG,aAAa,GAC5C,OAAO,CAOT"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,cAAc;IAC9B,wCAAwC;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,kBAAkB,EAAE,CAAC;IAC1C,6CAA6C;IAC7C,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,wCAAwC;IACxC,MAAM,CAAC,EAAE,IAAI,CAAC;IACd;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,cAK5B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,aAAa,CAC5B,GAAG,EAAE,cAAc,EACnB,UAAU,EAAE,kBAAkB,GAAG,aAAa,GAC5C,OAAO,CAOT;AAQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,MAAM,CAK5D"}
package/dist/context.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ALL_PLATFORM_PERMISSIONS } from './permissions/types.js';
2
2
  import { ALL_ORG_PERMISSIONS } from './organizations/schemas.js';
3
+ import { ProviderError } from './errors.js';
3
4
  /**
4
5
  * For server-internal operations outside any HTTP request (bootstrap,
5
6
  * janitors, migrations). Treated as fully authorized.
@@ -29,4 +30,16 @@ const PLATFORM_PERMISSION_VALUES = new Set(ALL_PLATFORM_PERMISSIONS);
29
30
  function isPlatformPermission(p) {
30
31
  return PLATFORM_PERMISSION_VALUES.has(p);
31
32
  }
33
+ /**
34
+ * Return the org the caller is acting as, or throw `ProviderError(403)` when
35
+ * the context has none. Stores that scope every row to an acting org repeat
36
+ * this guard; centralizing it keeps the failure a single, consistent 403
37
+ * rather than a `null` that leaks into a query as `org_id = undefined`.
38
+ */
39
+ export function requireActingOrg(ctx) {
40
+ if (!ctx.actingOrgId) {
41
+ throw new ProviderError('No acting organization in context', 403);
42
+ }
43
+ return ctx.actingOrgId;
44
+ }
32
45
  //# sourceMappingURL=context.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AA8BjE;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC7C,MAAM,EAAE,EAAE;IACV,mBAAmB,EAAE,CAAC,GAAG,wBAAwB,CAAC;IAClD,cAAc,EAAE,CAAC,GAAG,mBAAmB,CAAC;IACxC,MAAM,EAAE,IAAI;CACZ,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC5B,GAAmB,EACnB,UAA8C;IAE9C,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC5B,IAAI,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE7E,SAAS,oBAAoB,CAAC,CAAS;IACtC,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC"}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAElE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AA8B5C;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC7C,MAAM,EAAE,EAAE;IACV,mBAAmB,EAAE,CAAC,GAAG,wBAAwB,CAAC;IAClD,cAAc,EAAE,CAAC,GAAG,mBAAmB,CAAC;IACxC,MAAM,EAAE,IAAI;CACZ,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC5B,GAAmB,EACnB,UAA8C;IAE9C,IAAI,GAAG,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAC5B,IAAI,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,gBAAgB,CAAC;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,oBAAoB,CAAC,UAAU,CAAC,EAAE,CAAC;QACtC,OAAO,GAAG,CAAC,mBAAmB,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,0BAA0B,GAAG,IAAI,GAAG,CAAS,wBAAwB,CAAC,CAAC;AAE7E,SAAS,oBAAoB,CAAC,CAAS;IACtC,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAmB;IACnD,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACtB,MAAM,IAAI,aAAa,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,CAAC;AACxB,CAAC"}
@@ -22,6 +22,14 @@ export interface IDefinitionStore {
22
22
  create(ctx: RequestContext, record: DefinitionRecord): Promise<void>;
23
23
  update(ctx: RequestContext, guid: string, patch: DefinitionRecordPatch): Promise<void>;
24
24
  delete(ctx: RequestContext, guid: string): Promise<void>;
25
+ /**
26
+ * Cascade hook: soft-delete every live definition in a project. Called by
27
+ * `IProjectStore.deleteProject` — a deleted project must never keep serving
28
+ * its definitions (they surface in the library/public listings independent
29
+ * of the project row). No-op when the project has none. Mirrors the
30
+ * `deleteByProject` cascade hooks on `IPlatformProjectGrantStore`.
31
+ */
32
+ deleteByProject(ctx: RequestContext, projectId: string): Promise<void>;
25
33
  /** Atomic +1 on the solve counter. No-op if the record doesn't exist. */
26
34
  incrementSolveCount(ctx: RequestContext, guid: string): Promise<void>;
27
35
  createVersion(ctx: RequestContext, version: DefinitionVersion): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/definitions/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE7F;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAEhC,IAAI,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACzF,aAAa,CACZ,GAAG,EAAE,cAAc,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnC;;;;OAIG;IACH,UAAU,CACT,GAAG,EAAE,cAAc,EACnB,IAAI,CAAC,EAAE,qBAAqB,GAAG;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/C,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IACnC,GAAG,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IACzE,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvF,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD,yEAAyE;IACzE,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAGtE,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,uCAAuC;IACvC,YAAY,CACX,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAEtF;;;;;OAKG;IACH,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1F;;;OAGG;IACH,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErE,+EAA+E;IAC/E,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5F,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE7F;;;;;;;;;;;;;OAaG;IACH,oBAAoB,CAAC,GAAG,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAClG"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/definitions/interface.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Structured context attached to a reported error. All fields optional — a
3
+ * report can fire before any request context is built (e.g. an
4
+ * `unhandledRejection` with no active request). Deliberately NOT a
5
+ * `RequestContext`: reporters must never receive the opaque `authToken`, so
6
+ * only non-sensitive routing/identity fields are surfaced here.
7
+ */
8
+ export interface ErrorContext {
9
+ /** HTTP method, when the error happened inside a request. */
10
+ method?: string;
11
+ /** Route pathname (never the query string — it can carry share tokens). */
12
+ route?: string;
13
+ /** Acting user id, when known. */
14
+ userId?: string;
15
+ /** Org the user was acting as, when known. */
16
+ orgId?: string;
17
+ /** Non-sensitive tags for grouping/search in the backend. */
18
+ tags?: Record<string, string>;
19
+ }
20
+ /**
21
+ * Sink for unexpected server errors. Called from `handleError` and the
22
+ * process-level `unhandledRejection`/`uncaughtException` hooks.
23
+ *
24
+ * MUST NOT throw — reporting is best-effort and sits on the error path, where a
25
+ * second failure would mask the first. Implementations catch and log their own
26
+ * failures. MAY be fire-and-forget.
27
+ */
28
+ export interface IErrorReporter {
29
+ /**
30
+ * Report an unexpected error. `error` is whatever was thrown/rejected —
31
+ * often an `Error`, but adapters occasionally reject with a plain object,
32
+ * so implementations must render defensively.
33
+ */
34
+ capture(error: unknown, context?: ErrorContext): void;
35
+ }
36
+ /**
37
+ * Default `IErrorReporter` — discards every report. Used when no error-tracking
38
+ * backend is configured (e.g. `SENTRY_DSN` unset), so call sites can report
39
+ * unconditionally. Swap in a real reporter to ship errors off-box.
40
+ */
41
+ export declare class NoopErrorReporter implements IErrorReporter {
42
+ capture(_error: unknown, _context?: ErrorContext): void;
43
+ }
44
+ //# sourceMappingURL=interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/errors/interface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC5B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,cAAc;IAC9B;;;;OAIG;IACH,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;CACtD;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,cAAc;IACvD,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,IAAI;CACvD"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Default `IErrorReporter` — discards every report. Used when no error-tracking
3
+ * backend is configured (e.g. `SENTRY_DSN` unset), so call sites can report
4
+ * unconditionally. Swap in a real reporter to ship errors off-box.
5
+ */
6
+ export class NoopErrorReporter {
7
+ capture(_error, _context) { }
8
+ }
9
+ //# sourceMappingURL=interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/errors/interface.ts"],"names":[],"mappings":"AAqCA;;;;GAIG;AACH,MAAM,OAAO,iBAAiB;IAC7B,OAAO,CAAC,MAAe,EAAE,QAAuB,IAAS,CAAC;CAC1D"}
package/dist/index.d.ts CHANGED
@@ -6,10 +6,11 @@ export type { IPlatformPermissionStore } from './permissions/interface.js';
6
6
  export type { IUserProfileStore } from './userProfile/interface.js';
7
7
  export type { UserProfile, RecentRun } from './userProfile/types.js';
8
8
  export { emptyProfile } from './userProfile/types.js';
9
- export type { Organization, OrgMember } from './organizations/types.js';
9
+ export type { Organization, OrgMember, OrgAssets } from './organizations/types.js';
10
10
  export type { IOrgStore } from './organizations/interface.js';
11
- export type { OrgRole, OrgPermission, CreateOrgInput, UpdateOrgInput } from './organizations/schemas.js';
12
- export { OrgRoleSchema, OrgPermissionSchema, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './organizations/schemas.js';
11
+ export { orgPaths } from './organizations/paths.js';
12
+ export type { OrgRole, OrgPermission, OrgAssetKind, CreateOrgInput, UpdateOrgInput } from './organizations/schemas.js';
13
+ export { OrgRoleSchema, OrgPermissionSchema, OrgAssetKindSchema, ALL_ORG_ASSET_KINDS, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './organizations/schemas.js';
13
14
  export type { Invite } from './invites/types.js';
14
15
  export type { IInviteStore } from './invites/interface.js';
15
16
  export type { Project, ProjectMember } from './projects/types.js';
@@ -34,10 +35,14 @@ export { CreateShareLinkInputSchema } from './shareLinks/schemas.js';
34
35
  export type { IStorageProvider } from './storage/interface.js';
35
36
  export { IMAGE_MAX_WIDTH, IMAGE_WEBP_QUALITY, isImageUpload, toWebpPath, transcodeImageIfNeeded } from './storage/image.js';
36
37
  export type { TranscodeResult } from './storage/image.js';
38
+ export { ASSET_CLASSES, classifyAssetPath, isPublicAssetPath } from './storage/assetClasses.js';
39
+ export type { AssetVisibility, AssetScope, AssetClass, AssetMatch } from './storage/assetClasses.js';
40
+ export { withCacheBust } from './storage/cacheBust.js';
37
41
  export type { IDataProvider } from './data/interface.js';
38
42
  export type { ComputeServerConfig, ComputeConfig, PlatformComputeServer, OrgComputeServer } from './computeServer/types.js';
39
43
  export { isPlatformServer, isOrgServer } from './computeServer/types.js';
40
44
  export type { IComputeServerStore } from './computeServer/interface.js';
45
+ export type { SecretVerificationReport, SecretVerificationFailure, SecretVerificationFailureReason } from './computeServer/secrets.js';
41
46
  export type { ResolveOptions } from './computeServer/utils.js';
42
47
  export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor } from './computeServer/utils.js';
43
48
  export type { ProjectAccessInput, DefinitionAccessInput, VisibilityChangeInput, ReclaimAccessInput, CreateProjectAccessInput, OwnerRemovalInput, OwnerRemovalCheck } from './access/rules.js';
@@ -47,12 +52,14 @@ export { actorFrom, NoopEventSink } from './events/interface.js';
47
52
  export type { AuditEventRow, AuditCursor, AuditQueryFilters, AuditQueryResult, IAuditQuery } from './events/audit.js';
48
53
  export type { ISolveMetricSink, SolveMetric, SolveFailureKind } from './metrics/interface.js';
49
54
  export { NoopSolveMetricSink } from './metrics/interface.js';
55
+ export type { IErrorReporter, ErrorContext } from './errors/interface.js';
56
+ export { NoopErrorReporter } from './errors/interface.js';
50
57
  export type { IBindingResolver } from './bindings/interface.js';
51
58
  export { NoopBindingResolver } from './bindings/interface.js';
52
59
  export type { AuditUpdate, AuditSoftDelete } from './utils/audit.js';
53
60
  export { auditUpdate, auditSoftDelete } from './utils/audit.js';
54
61
  export type { RequestContext } from './context.js';
55
- export { SYSTEM_CONTEXT, hasPermission } from './context.js';
62
+ export { SYSTEM_CONTEXT, hasPermission, requireActingOrg } from './context.js';
56
63
  export type { ListOptions, DefinitionListOptions, Page } from './pagination.js';
57
64
  export { DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT } from './pagination.js';
58
65
  export type { TenancyMode, SelvaFlags, SelvaBranding, SelvaConfig, SelvaConfigFactory } from './config.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
1
  // @selvajs/platform — published API contract. Every symbol here is breaking-change-protected.
2
2
  export { PlatformPermissionSchema, ALL_PLATFORM_PERMISSIONS } from './permissions/types.js';
3
3
  export { emptyProfile } from './userProfile/types.js';
4
- export { OrgRoleSchema, OrgPermissionSchema, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './organizations/schemas.js';
4
+ export { orgPaths } from './organizations/paths.js';
5
+ export { OrgRoleSchema, OrgPermissionSchema, OrgAssetKindSchema, ALL_ORG_ASSET_KINDS, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './organizations/schemas.js';
5
6
  export { ProjectVisibilitySchema, ProjectRoleSchema, validateProjectFlags } from './projects/schemas.js';
6
7
  export { PlatformProjectGrantSchema, PlatformProjectGranteeTypeSchema } from './platformProjects/schemas.js';
7
8
  export { GH_EXTENSIONS, COVER_IMAGE_EXTENSIONS, ALLOWED_UPLOAD_EXTENSIONS, COVER_IMAGE_CONTENT_TYPES } from './definitions/types.js';
@@ -10,14 +11,17 @@ export { DefinitionChannelSchema, PublishVersionInputSchema, CreateDefinitionInp
10
11
  export { DEFAULT_SHARE_LINK_MAX_SOLVES } from './shareLinks/types.js';
11
12
  export { CreateShareLinkInputSchema } from './shareLinks/schemas.js';
12
13
  export { IMAGE_MAX_WIDTH, IMAGE_WEBP_QUALITY, isImageUpload, toWebpPath, transcodeImageIfNeeded } from './storage/image.js';
14
+ export { ASSET_CLASSES, classifyAssetPath, isPublicAssetPath } from './storage/assetClasses.js';
15
+ export { withCacheBust } from './storage/cacheBust.js';
13
16
  export { isPlatformServer, isOrgServer } from './computeServer/types.js';
14
17
  export { serversVisibleTo, defaultServerIdFor, resolveServerForOrg, findServerById, platformServers, orgServersFor } from './computeServer/utils.js';
15
18
  export { canView, canSolve, canEdit, canManage, canEditProjectSettings, canChangeVisibilityToPublic, canEditDefinition, canReclaim, canCreateProject, checkOwnerRemoval, withAdminBypass } from './access/rules.js';
16
19
  export { actorFrom, NoopEventSink } from './events/interface.js';
17
20
  export { NoopSolveMetricSink } from './metrics/interface.js';
21
+ export { NoopErrorReporter } from './errors/interface.js';
18
22
  export { NoopBindingResolver } from './bindings/interface.js';
19
23
  export { auditUpdate, auditSoftDelete } from './utils/audit.js';
20
- export { SYSTEM_CONTEXT, hasPermission } from './context.js';
24
+ export { SYSTEM_CONTEXT, hasPermission, requireActingOrg } from './context.js';
21
25
  export { DEFAULT_PAGE_LIMIT, MAX_PAGE_LIMIT } from './pagination.js';
22
26
  export { isFlagEnabled, defineConfig } from './config.js';
23
27
  export { ProviderError } from './errors.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAgB9F,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAM5F,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAWtD,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,4BAA4B,CAAC;AAUpC,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACN,0BAA0B,EAC1B,gCAAgC,EAChC,MAAM,+BAA+B,CAAC;AAavC,OAAO,EACN,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EACN,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAMrE,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,sBAAsB,EACtB,MAAM,oBAAoB,CAAC;AAiB5B,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAGzE,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,0BAA0B,CAAC;AAclC,OAAO,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,SAAS,EACT,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAajE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAM7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAM9D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMhE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7D,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AASrE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAgB9F,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAM5F,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAKtD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQpD,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,4BAA4B,CAAC;AAUpC,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EACpB,MAAM,uBAAuB,CAAC;AAK/B,OAAO,EACN,0BAA0B,EAC1B,gCAAgC,EAChC,MAAM,+BAA+B,CAAC;AAavC,OAAO,EACN,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EACN,uBAAuB,EACvB,yBAAyB,EACzB,2BAA2B,EAC3B,yBAAyB,EACzB,UAAU,EACV,UAAU,EACV,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAEtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAMrE,OAAO,EACN,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,UAAU,EACV,sBAAsB,EACtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAOhG,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAgBvD,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAazE,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,aAAa,EACb,MAAM,0BAA0B,CAAC;AAclC,OAAO,EACN,OAAO,EACP,QAAQ,EACR,OAAO,EACP,SAAS,EACT,sBAAsB,EACtB,2BAA2B,EAC3B,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAajE,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAM7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAM1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAM9D,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMhE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAG/E,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AASrE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -1,5 +1,6 @@
1
- export type { Organization, OrgMember } from './types.js';
1
+ export type { Organization, OrgMember, OrgAssets } from './types.js';
2
2
  export type { IOrgStore } from './interface.js';
3
- export type { OrgRole, OrgPermission, CreateOrgInput, UpdateOrgInput } from './schemas.js';
4
- export { OrgRoleSchema, OrgPermissionSchema, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './schemas.js';
3
+ export { orgPaths } from './paths.js';
4
+ export type { OrgRole, OrgPermission, OrgAssetKind, CreateOrgInput, UpdateOrgInput } from './schemas.js';
5
+ export { OrgRoleSchema, OrgPermissionSchema, OrgAssetKindSchema, ALL_ORG_ASSET_KINDS, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './schemas.js';
5
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,YAAY,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC3F,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACrE,YAAY,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EACX,OAAO,EACP,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,cAAc,CAAC"}
@@ -1,2 +1,3 @@
1
- export { OrgRoleSchema, OrgPermissionSchema, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './schemas.js';
1
+ export { orgPaths } from './paths.js';
2
+ export { OrgRoleSchema, OrgPermissionSchema, OrgAssetKindSchema, ALL_ORG_ASSET_KINDS, SlugSchema, CreateOrgSchema, UpdateOrgSchema, ALL_ORG_PERMISSIONS, DEFAULT_ORG_PERMISSIONS, OWNER_ADMIN_ONLY_PERMISSIONS, MEMBER_ASSIGNABLE_PERMISSIONS } from './schemas.js';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/organizations/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQtC,OAAO,EACN,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,EACnB,uBAAuB,EACvB,4BAA4B,EAC5B,6BAA6B,EAC7B,MAAM,cAAc,CAAC"}
@@ -11,7 +11,7 @@ export interface IOrgStore {
11
11
  getOrg(ctx: RequestContext, id: string): Promise<Organization | null>;
12
12
  getOrgBySlug(ctx: RequestContext, slug: string): Promise<Organization | null>;
13
13
  createOrg(ctx: RequestContext, org: Organization): Promise<void>;
14
- updateOrg(ctx: RequestContext, id: string, patch: Partial<Pick<Organization, 'name' | 'slug'>>): Promise<void>;
14
+ updateOrg(ctx: RequestContext, id: string, patch: Partial<Pick<Organization, 'name' | 'slug' | 'assets'>>): Promise<void>;
15
15
  /**
16
16
  * Soft-delete the org. Cascades soft-delete to org members, projects in the
17
17
  * org, and project members. Definitions and share links cascade through the
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/organizations/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,SAAS;IAEzB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/E,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACtE,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9E,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,CACR,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAAC,CAAC,GACjD,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG1D,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjG,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5F;;;;;;;;;;;;OAYG;IACH,kBAAkB,CACjB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,GAAG,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5D,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,mBAAmB,CAClB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;OAIG;IACH,0BAA0B,CACzB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,aAAa,EAAE,GACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnF"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/organizations/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,SAAS;IAEzB,QAAQ,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/E,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IACtE,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9E,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,SAAS,CACR,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC,GAC5D,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAG1D,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjG,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAC5F;;;;;;;;;;;;OAYG;IACH,kBAAkB,CACjB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC;QAAE,GAAG,EAAE,YAAY,CAAC;QAAC,MAAM,EAAE,SAAS,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAC5D,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpE,mBAAmB,CAClB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,OAAO,GACX,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB;;;;OAIG;IACH,0BAA0B,CACzB,GAAG,EAAE,cAAc,EACnB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,aAAa,EAAE,GACnC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,eAAe,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnF"}
@@ -0,0 +1,22 @@
1
+ import type { OrgAssetKind } from './schemas.js';
2
+ /**
3
+ * Storage keys for org-scoped assets. Every branding asset is stored as `.webp`
4
+ * (uploads are rasterized through the shared transcoder), so the path per kind
5
+ * is fixed — a re-upload overwrites in place via `IStorageProvider.put`'s
6
+ * upsert. The filename IS the kind, so the layout is generic: a new branding
7
+ * kind needs no new helper.
8
+ *
9
+ * Branding lives under `orgs/{id}/branding/` because it is a *public* asset
10
+ * class — anyone, incl. logged-out viewers, may read a company logo. The
11
+ * `branding/` segment keeps it distinguishable from future org-private blobs
12
+ * under `orgs/{id}/private/` (e.g. pricing sheets), which are members-only.
13
+ * The serving route and `getPublicUrl` decide public-vs-private by classifying
14
+ * these prefixes — see `classifyAssetPath` / `ASSET_CLASSES`.
15
+ */
16
+ export declare const orgPaths: {
17
+ readonly asset: (id: string, kind: OrgAssetKind) => string;
18
+ /** Members-only blob under the org's private tier. `name` includes the extension. */
19
+ readonly privateAsset: (id: string, name: string) => string;
20
+ readonly prefix: (id: string) => string;
21
+ };
22
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/organizations/paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAcjD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,QAAQ;yBACR,MAAM,QAAQ,YAAY;IAKtC,qFAAqF;gCAClE,MAAM,QAAQ,MAAM;0BAK1B,MAAM;CAIV,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Path-segment safety check. Blocks traversal, separators, NUL, and empty
3
+ * segments. Allowed alphabet `[A-Za-z0-9._-]+` covers GUIDs and sanitized
4
+ * refs. Called by every helper so a malicious `id` can't escape the
5
+ * `orgs/` prefix. Mirrors `definitionPaths`' guard.
6
+ */
7
+ function assertSafeKey(value, label) {
8
+ if (!value || !/^[A-Za-z0-9._-]+$/.test(value) || value === '.' || value === '..') {
9
+ throw new Error(`Unsafe ${label}: ${JSON.stringify(value)}`);
10
+ }
11
+ }
12
+ /**
13
+ * Storage keys for org-scoped assets. Every branding asset is stored as `.webp`
14
+ * (uploads are rasterized through the shared transcoder), so the path per kind
15
+ * is fixed — a re-upload overwrites in place via `IStorageProvider.put`'s
16
+ * upsert. The filename IS the kind, so the layout is generic: a new branding
17
+ * kind needs no new helper.
18
+ *
19
+ * Branding lives under `orgs/{id}/branding/` because it is a *public* asset
20
+ * class — anyone, incl. logged-out viewers, may read a company logo. The
21
+ * `branding/` segment keeps it distinguishable from future org-private blobs
22
+ * under `orgs/{id}/private/` (e.g. pricing sheets), which are members-only.
23
+ * The serving route and `getPublicUrl` decide public-vs-private by classifying
24
+ * these prefixes — see `classifyAssetPath` / `ASSET_CLASSES`.
25
+ */
26
+ export const orgPaths = {
27
+ asset: (id, kind) => {
28
+ assertSafeKey(id, 'orgId');
29
+ assertSafeKey(kind, 'assetKind');
30
+ return `orgs/${id}/branding/${kind}.webp`;
31
+ },
32
+ /** Members-only blob under the org's private tier. `name` includes the extension. */
33
+ privateAsset: (id, name) => {
34
+ assertSafeKey(id, 'orgId');
35
+ assertSafeKey(name, 'assetName');
36
+ return `orgs/${id}/private/${name}`;
37
+ },
38
+ prefix: (id) => {
39
+ assertSafeKey(id, 'orgId');
40
+ return `orgs/${id}/`;
41
+ }
42
+ };
43
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/organizations/paths.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,SAAS,aAAa,CAAC,KAAa,EAAE,KAAa;IAClD,IAAI,CAAC,KAAK,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnF,MAAM,IAAI,KAAK,CAAC,UAAU,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC9D,CAAC;AACF,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG;IACvB,KAAK,EAAE,CAAC,EAAU,EAAE,IAAkB,EAAE,EAAE;QACzC,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3B,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjC,OAAO,QAAQ,EAAE,aAAa,IAAI,OAAO,CAAC;IAC3C,CAAC;IACD,qFAAqF;IACrF,YAAY,EAAE,CAAC,EAAU,EAAE,IAAY,EAAE,EAAE;QAC1C,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3B,aAAa,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjC,OAAO,QAAQ,EAAE,YAAY,IAAI,EAAE,CAAC;IACrC,CAAC;IACD,MAAM,EAAE,CAAC,EAAU,EAAE,EAAE;QACtB,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QAC3B,OAAO,QAAQ,EAAE,GAAG,CAAC;IACtB,CAAC;CACQ,CAAC"}
@@ -7,6 +7,16 @@ export declare const OrgRoleSchema: z.ZodEnum<{
7
7
  member: "member";
8
8
  }>;
9
9
  export type OrgRole = z.infer<typeof OrgRoleSchema>;
10
+ /**
11
+ * Kinds of org-scoped branding asset. Adding a new kind is a single entry here
12
+ * — the storage path, upload route, store, and UI are all generic over it.
13
+ */
14
+ export declare const OrgAssetKindSchema: z.ZodEnum<{
15
+ logo: "logo";
16
+ favicon: "favicon";
17
+ }>;
18
+ export type OrgAssetKind = z.infer<typeof OrgAssetKindSchema>;
19
+ export declare const ALL_ORG_ASSET_KINDS: readonly OrgAssetKind[];
10
20
  /** Org-scope permissions. A user may hold different sets in different orgs. */
11
21
  export declare const OrgPermissionSchema: z.ZodEnum<{
12
22
  manage_org_members: "manage_org_members";