@rebasepro/server 0.13.0 → 0.13.1-canary.g249daa1

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 (56) hide show
  1. package/dist/{admin_block-CcSGdH7M.js → admin_block-CLeUMG8G.js} +3 -1
  2. package/dist/admin_block-CLeUMG8G.js.map +1 -0
  3. package/dist/api/errors.d.ts +0 -6
  4. package/dist/api/openapi-generator.d.ts +14 -0
  5. package/dist/api/rest/idempotency.d.ts +41 -4
  6. package/dist/api/rest/write-validation.d.ts +12 -5
  7. package/dist/auth/index.d.ts +1 -1
  8. package/dist/auth/jwt.d.ts +12 -0
  9. package/dist/{auth-CuC9M2x6.js → auth-BANhRhN9.js} +194 -84
  10. package/dist/auth-BANhRhN9.js.map +1 -0
  11. package/dist/{backup-CVggVhR2.js → backup-BJiY_mM-.js} +2 -2
  12. package/dist/{backup-CVggVhR2.js.map → backup-BJiY_mM-.js.map} +1 -1
  13. package/dist/boot/boot.d.ts +19 -0
  14. package/dist/boot/ddl-bootstrap.d.ts +70 -0
  15. package/dist/{contract-routes-Dj8i5AiM.js → contract-routes-FSt0Nyfk.js} +2 -2
  16. package/dist/{contract-routes-Dj8i5AiM.js.map → contract-routes-FSt0Nyfk.js.map} +1 -1
  17. package/dist/cron/cron-scheduler.d.ts +8 -3
  18. package/dist/cron/define-cron.d.ts +5 -3
  19. package/dist/{cron-routes-CrQ0tK-_.js → cron-routes-D5a9v1HY.js} +2 -2
  20. package/dist/{cron-routes-CrQ0tK-_.js.map → cron-routes-D5a9v1HY.js.map} +1 -1
  21. package/dist/{cron-scheduler-B3RFt0HS.js → cron-scheduler-CsQtYLMq.js} +28 -3
  22. package/dist/cron-scheduler-CsQtYLMq.js.map +1 -0
  23. package/dist/{cron-store-BywZsyfZ.js → cron-store-ZbjfuvMb.js} +65 -46
  24. package/dist/cron-store-ZbjfuvMb.js.map +1 -0
  25. package/dist/ddl-bootstrap-Bp3mr6Td.js +183 -0
  26. package/dist/ddl-bootstrap-Bp3mr6Td.js.map +1 -0
  27. package/dist/{errors-CgkCzoj7.js → errors-BpudWAVU.js} +2 -10
  28. package/dist/errors-BpudWAVU.js.map +1 -0
  29. package/dist/functions/define-function.d.ts +1 -1
  30. package/dist/history/history-routes.d.ts +6 -0
  31. package/dist/index.es.js +835 -276
  32. package/dist/index.es.js.map +1 -1
  33. package/dist/{jwt-DD6EtpGj.js → jwt-CzeviDcB.js} +17 -2
  34. package/dist/{jwt-DD6EtpGj.js.map → jwt-CzeviDcB.js.map} +1 -1
  35. package/dist/{openapi-generator-BEwyiaAr.js → openapi-generator-VB0MUH8h.js} +340 -128
  36. package/dist/openapi-generator-VB0MUH8h.js.map +1 -0
  37. package/dist/{schema-editor-routes-CbF20Mf1.js → schema-editor-routes-BqjzvvWU.js} +4 -4
  38. package/dist/{schema-editor-routes-CbF20Mf1.js.map → schema-editor-routes-BqjzvvWU.js.map} +1 -1
  39. package/dist/{src-_qQ3RNCK.js → src-Ca6NhxKs.js} +79 -2
  40. package/dist/src-Ca6NhxKs.js.map +1 -0
  41. package/dist/{src-Cum9kox5.js → src-DVb5a0bp.js} +153 -39
  42. package/dist/src-DVb5a0bp.js.map +1 -0
  43. package/dist/storage/keys.d.ts +65 -0
  44. package/dist/utils/logging.d.ts +0 -4
  45. package/dist/utils/sql.d.ts +11 -6
  46. package/package.json +6 -6
  47. package/dist/admin_block-CcSGdH7M.js.map +0 -1
  48. package/dist/auth-CuC9M2x6.js.map +0 -1
  49. package/dist/backend-CIxN4FVm.js +0 -15
  50. package/dist/backend-CIxN4FVm.js.map +0 -1
  51. package/dist/cron-scheduler-B3RFt0HS.js.map +0 -1
  52. package/dist/cron-store-BywZsyfZ.js.map +0 -1
  53. package/dist/errors-CgkCzoj7.js.map +0 -1
  54. package/dist/openapi-generator-BEwyiaAr.js.map +0 -1
  55. package/dist/src-Cum9kox5.js.map +0 -1
  56. package/dist/src-_qQ3RNCK.js.map +0 -1
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Canonical storage keys.
3
+ *
4
+ * Storage is not under RLS, so a `storageAuthorize` hook is the whole access
5
+ * control model — and a hook can only be correct if the key it is shown is the
6
+ * key that is written. That is the invariant this module exists to hold: one
7
+ * canonical string, computed once per request, handed to the hook, to the
8
+ * controller, and to the download token alike.
9
+ *
10
+ * ## Why rejecting beats stripping
11
+ *
12
+ * The previous `sanitizeStorageKey` *stripped* `../` in a single pass. Two
13
+ * things were wrong with that, and only one of them was the obvious one.
14
+ *
15
+ * The obvious one: a single pass is not a fixed point. `....//` contains `../`
16
+ * at offset 2, so removing it leaves `../` behind — the sanitizer manufactured
17
+ * the traversal it was there to remove. `users/alice/....//bob/x` came out as
18
+ * `users/alice/../bob/x`, which a prefix hook reads as alice's (it starts with
19
+ * `users/alice/`) and the filesystem reads as bob's. The hook approved one
20
+ * object and the controller wrote another.
21
+ *
22
+ * The subtler one, and the reason this is a rewrite rather than a loop: even a
23
+ * correct strip is a silent rewrite. A caller who asks to store at `a/../b` and
24
+ * gets an object at `a/b` was not protected, they were misled — and every later
25
+ * read, ownership row and audit line now refers to a path nobody chose. So a key
26
+ * that means something other than what it says is refused (400), not repaired.
27
+ *
28
+ * Note what is NOT traversal under this rule: `....` is an ordinary directory
29
+ * name, and `users/alice/....//bob/x` canonicalizes to
30
+ * `users/alice/..../bob/x` — still comfortably inside alice's prefix, which is
31
+ * exactly right. Only a real `..` segment is refused.
32
+ */
33
+ /** Longest key accepted, in UTF-16 code units. Matches the previous cap. */
34
+ export declare const MAX_STORAGE_KEY_LENGTH = 1024;
35
+ /**
36
+ * A key that cannot be canonicalized. Carries no path back to the caller
37
+ * beyond what they sent, so it is safe to surface as a 400 message.
38
+ */
39
+ export declare class InvalidStorageKeyError extends Error {
40
+ constructor(message: string);
41
+ }
42
+ /**
43
+ * Canonicalize a caller-supplied storage key, or throw
44
+ * {@link InvalidStorageKeyError}.
45
+ *
46
+ * Normalizations applied (safe, idempotent, and meaning-preserving):
47
+ * - leading slashes removed — `/a/b` and `a/b` name the same object
48
+ * - `.` segments and repeated slashes collapsed
49
+ *
50
+ * Refusals (the key means something other than what it says):
51
+ * - any `..` segment, on either separator, at any depth
52
+ * - null bytes
53
+ * - keys longer than {@link MAX_STORAGE_KEY_LENGTH}
54
+ *
55
+ * A trailing slash is preserved: it is how the folder route marks a prefix.
56
+ */
57
+ export declare function canonicalStorageKey(rawKey: string): string;
58
+ /**
59
+ * Canonicalize, or return `null` when the key is not canonicalizable.
60
+ *
61
+ * For callers that must fail closed without an exception — the download-token
62
+ * middleware compares a request path against a granted path, and a key it
63
+ * cannot canonicalize simply matches nothing.
64
+ */
65
+ export declare function tryCanonicalStorageKey(rawKey: string): string | null;
@@ -3,7 +3,3 @@
3
3
  * Call this early in your application to set up proper logging levels
4
4
  */
5
5
  export declare function configureLogLevel(logLevel?: string): void;
6
- /**
7
- * Reset console methods to their original state
8
- */
9
- export declare function resetConsole(): void;
@@ -1,27 +1,32 @@
1
1
  import { SQL } from "drizzle-orm";
2
2
  /**
3
- * Returns a SQL chunk calling `auth.uid()` — the current user's ID.
4
- * This is a PostgreSQL RLS helper function created in the `auth` schema
3
+ * Returns a SQL chunk calling `rebase.uid()` — the current user's ID.
4
+ * This is a PostgreSQL RLS helper function created in the `rebase` schema
5
5
  * that reads `app.uid` set per-transaction by `withAuth()`.
6
6
  *
7
+ * The function moved from `auth.uid()` to `rebase.uid()` in 1.0 — `auth` is
8
+ * Supabase's schema, and taking it meant Rebase could not be pointed at a
9
+ * database that already had one. Use this helper rather than writing the call
10
+ * by hand and the move costs you nothing.
11
+ *
7
12
  * @example
8
13
  * sql`${table.uid} = ${authUid()}`
9
14
  */
10
15
  export declare const authUid: () => SQL;
11
16
  /**
12
- * Returns a SQL chunk calling `auth.roles()` — the current user's roles
17
+ * Returns a SQL chunk calling `rebase.roles()` — the current user's roles
13
18
  * as a comma-separated string.
14
19
  * Reads `app.user_roles` set per-transaction by `withAuth()`.
15
20
  *
16
21
  * @example
17
- * sql`auth.roles() ~ 'admin'`
22
+ * sql`${authRoles()} ~ 'admin'`
18
23
  */
19
24
  export declare const authRoles: () => SQL;
20
25
  /**
21
- * Returns a SQL chunk calling `auth.jwt()` — the full JWT claims as JSONB.
26
+ * Returns a SQL chunk calling `rebase.jwt()` — the full JWT claims as JSONB.
22
27
  * Reads `app.jwt` set per-transaction by `withAuth()`.
23
28
  *
24
29
  * @example
25
- * sql`auth.jwt()->>'sub'`
30
+ * sql`${authJwt()}->>'sub'`
26
31
  */
27
32
  export declare const authJwt: () => SQL;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@rebasepro/server",
3
3
  "type": "module",
4
- "version": "0.13.0",
4
+ "version": "0.13.1-canary.g249daa1",
5
5
  "description": "Database-Agnostic Backend Core for Rebase",
6
6
  "funding": {
7
7
  "url": "https://github.com/sponsors/rebaseco"
@@ -44,10 +44,10 @@
44
44
  "jsonwebtoken": "^9.0.3",
45
45
  "ws": "^8.21.1",
46
46
  "zod": "^4.4.3",
47
- "@rebasepro/client": "0.13.0",
48
- "@rebasepro/common": "0.13.0",
49
- "@rebasepro/types": "0.13.0",
50
- "@rebasepro/utils": "0.13.0"
47
+ "@rebasepro/client": "0.13.1-canary.g249daa1",
48
+ "@rebasepro/common": "0.13.1-canary.g249daa1",
49
+ "@rebasepro/types": "0.13.1-canary.g249daa1",
50
+ "@rebasepro/utils": "0.13.1-canary.g249daa1"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@jest/globals": "^30.4.1",
@@ -57,7 +57,7 @@
57
57
  "@types/nodemailer": "^8.0.1",
58
58
  "@types/ws": "^8.18.1",
59
59
  "cross-env": "^10.1.0",
60
- "hono": "^4.12.27",
60
+ "hono": "^4.13.0",
61
61
  "jest": "^30.4.2",
62
62
  "ts-jest": "29.4.12",
63
63
  "typescript": "^6.0.3",
@@ -1 +0,0 @@
1
- {"version":3,"file":"admin_block-CcSGdH7M.js","names":[],"sources":["../../types/src/types/admin_block.ts"],"sourcesContent":["/**\n * The keys of a collection's admin block, as data.\n *\n * There is no *type* for the block in this package any more, and that is the point:\n * `admin` is not declared on `BaseCollectionConfig` or on any property here, so a\n * BaaS install cannot even write one. `@rebasepro/admin-types` adds the field back by\n * declaration merging, which is why installing it is what makes the admin surface\n * appear.\n *\n * The *list* still has to live here, because three runtime consumers need it and two\n * of them are core — see below.\n */\n\n/**\n * Every key that belongs inside a collection's `admin` block, as data.\n *\n * The type that describes these fields is `AdminCollectionOptions` in\n * `@rebasepro/admin-types`, and it is erased at build time — but three runtime\n * consumers need the list, and two of them are core:\n *\n * - `serializeCollections`, to drop the block from the contract\n * - the ts-morph schema editor in `@rebasepro/server`, which rewrites collection\n * files on disk from the admin panel and has to know where each key goes. A key\n * missing from this list gets written to the *top level* of the file, where the\n * backend ignores it and the panel never finds it again.\n * - the `collections-admin-block` codemod\n *\n * `@rebasepro/admin-types` re-exports this and asserts it names only real option\n * keys; the count is pinned by a test there.\n *\n * @group Models\n */\nexport const ADMIN_COLLECTION_KEYS = [\n \"Actions\",\n \"additionalFields\",\n \"alwaysApplyDefaultValues\",\n \"components\",\n \"defaultEntityAction\",\n \"defaultFilter\",\n \"defaultSelectedView\",\n \"defaultSize\",\n \"defaultViewMode\",\n \"disableDefaultActions\",\n \"enabledViews\",\n \"entityActions\",\n \"entityViews\",\n \"exportable\",\n \"filterPresets\",\n \"fixedFilter\",\n \"form\",\n \"formAutoSave\",\n \"formView\",\n \"group\",\n \"hideFromNavigation\",\n \"hideIdFromCollection\",\n \"hideIdFromForm\",\n \"icon\",\n \"includeJsonView\",\n \"inlineEditing\",\n \"kanban\",\n \"listProperties\",\n \"localChangesBackup\",\n \"openEntityMode\",\n \"orderProperty\",\n \"pagination\",\n \"previewProperties\",\n \"propertiesOrder\",\n \"selectionController\",\n \"selectionEnabled\",\n \"sideDialogWidth\",\n \"sort\",\n \"titleProperty\"\n] as const;\n\n/** A key of a collection's `admin` block. @group Models */\nexport type AdminCollectionKey = typeof ADMIN_COLLECTION_KEYS[number];\n\n/**\n * Every key that belongs inside a *property's* `admin` block, as data.\n *\n * The union of `AdminPropertyOptions` and its per-type extensions\n * (`AdminStringOptions`, `AdminArrayOptions`, …) in `@rebasepro/admin-types`.\n * It lives here for the same reason {@link ADMIN_COLLECTION_KEYS} does: the\n * runtime consumers are core packages that the BaaS guard forbids from\n * importing `@rebasepro/admin-types`. Here it is the boot-time collection\n * validator in `@rebasepro/server`, which has to tell \"you left `readOnly` at\n * the top of the property, where nothing reads it\" apart from \"you invented a\n * key we have never heard of\".\n *\n * `@rebasepro/admin-types` re-exports this and asserts it names only real\n * option keys.\n *\n * @group Models\n */\nexport const ADMIN_PROPERTY_KEYS = [\n \"canAddElements\",\n \"clearable\",\n \"columnWidth\",\n \"customProps\",\n \"disabled\",\n \"expanded\",\n \"Field\",\n \"Filter\",\n \"filterOperators\",\n \"fixedFilter\",\n \"hideFromCollection\",\n \"includeEntityLink\",\n \"includeId\",\n \"markdown\",\n \"minimalistView\",\n \"multiline\",\n \"Preview\",\n \"previewAsTag\",\n \"previewProperties\",\n \"readOnly\",\n \"sortable\",\n \"span\",\n \"spreadChildren\",\n \"urlPreview\",\n \"widget\",\n] as const;\n\n/** A key of a property's `admin` block. @group Models */\nexport type AdminPropertyKey = typeof ADMIN_PROPERTY_KEYS[number];\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,IAAa,wBAAwB;CACjC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ;;;;;;;;;;;;;;;;;;AAsBA,IAAa,sBAAsB;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACJ"}