@sequenceholdings/orm 2.1.0 → 2.2.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 (77) hide show
  1. package/README.md +40 -1
  2. package/dist/authoring.cjs +1619 -121
  3. package/dist/authoring.cjs.map +1 -1
  4. package/dist/authoring.d.cts +252 -8
  5. package/dist/authoring.d.ts +252 -8
  6. package/dist/authoring.js +1607 -123
  7. package/dist/authoring.js.map +1 -1
  8. package/dist/canonical.cjs +713 -41
  9. package/dist/canonical.cjs.map +1 -1
  10. package/dist/canonical.d.cts +1520 -51
  11. package/dist/canonical.d.ts +1520 -51
  12. package/dist/canonical.js +693 -42
  13. package/dist/canonical.js.map +1 -1
  14. package/dist/cli.cjs +7103 -3901
  15. package/dist/cli.cjs.map +1 -1
  16. package/dist/cli.js +7104 -3902
  17. package/dist/cli.js.map +1 -1
  18. package/dist/client.cjs +122 -40
  19. package/dist/client.cjs.map +1 -1
  20. package/dist/client.d.cts +85 -25
  21. package/dist/client.d.ts +85 -25
  22. package/dist/client.js +119 -41
  23. package/dist/client.js.map +1 -1
  24. package/dist/compiler.cjs +2464 -450
  25. package/dist/compiler.cjs.map +1 -1
  26. package/dist/compiler.d.cts +79 -4
  27. package/dist/compiler.d.ts +79 -4
  28. package/dist/compiler.js +2457 -451
  29. package/dist/compiler.js.map +1 -1
  30. package/dist/constants-C6EG6Wq7.d.cts +99 -0
  31. package/dist/constants-C6EG6Wq7.d.ts +99 -0
  32. package/dist/definition-DjfC7Lll.d.cts +91 -0
  33. package/dist/definition-DjfC7Lll.d.ts +91 -0
  34. package/dist/dynamic-input.cjs +2 -1
  35. package/dist/dynamic-input.cjs.map +1 -1
  36. package/dist/dynamic-input.d.cts +9 -1
  37. package/dist/dynamic-input.d.ts +9 -1
  38. package/dist/dynamic-input.js +2 -1
  39. package/dist/dynamic-input.js.map +1 -1
  40. package/dist/index.cjs +2656 -418
  41. package/dist/index.cjs.map +1 -1
  42. package/dist/index.d.cts +693 -116
  43. package/dist/index.d.ts +693 -116
  44. package/dist/index.js +2622 -420
  45. package/dist/index.js.map +1 -1
  46. package/dist/ir.cjs +811 -48
  47. package/dist/ir.cjs.map +1 -1
  48. package/dist/ir.d.cts +670 -27
  49. package/dist/ir.d.ts +670 -27
  50. package/dist/ir.js +802 -49
  51. package/dist/ir.js.map +1 -1
  52. package/dist/{naming-DCn94LJ4.d.ts → naming-CPfx7EfF.d.ts} +14 -1
  53. package/dist/{naming-DPglwzkB.d.cts → naming-CU9ThP_E.d.cts} +14 -1
  54. package/dist/policy-1iZbGnZZ.d.cts +24 -0
  55. package/dist/policy-1iZbGnZZ.d.ts +24 -0
  56. package/dist/predicate-v2.cjs +804 -51
  57. package/dist/predicate-v2.cjs.map +1 -1
  58. package/dist/predicate-v2.d.cts +2 -1
  59. package/dist/predicate-v2.d.ts +2 -1
  60. package/dist/predicate-v2.js +804 -51
  61. package/dist/predicate-v2.js.map +1 -1
  62. package/dist/sdl.cjs +1014 -75
  63. package/dist/sdl.cjs.map +1 -1
  64. package/dist/sdl.d.cts +14 -3
  65. package/dist/sdl.d.ts +14 -3
  66. package/dist/sdl.js +1012 -76
  67. package/dist/sdl.js.map +1 -1
  68. package/package.json +13 -7
  69. package/src/codegen-gql/server-fns.cjs +2 -2
  70. package/templates/orm-namespace/AGENTS.md +10 -0
  71. package/templates/orm-namespace/CLAUDE.md +1 -82
  72. package/templates/orm-namespace/codegen.preset.d.cts +7 -0
  73. package/templates/orm-namespace/codegen.ts +2 -1
  74. package/templates/orm-namespace/graphql/example/queries.ts +4 -3
  75. package/templates/orm-namespace/package.json +2 -1
  76. package/templates/orm-namespace/schema/tables.ts +3 -2
  77. package/templates/orm-namespace/sequence.config.ts +7 -11
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sequenceholdings/orm",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "Sequence ORM v2 — TypeScript-defined governed tables and persisted GraphQL operations",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -28,9 +28,14 @@
28
28
  "require": "./dist/cli.cjs"
29
29
  },
30
30
  "./client": {
31
- "types": "./dist/client.d.ts",
32
- "import": "./dist/client.js",
33
- "require": "./dist/client.cjs"
31
+ "import": {
32
+ "types": "./dist/client.d.ts",
33
+ "default": "./dist/client.js"
34
+ },
35
+ "require": {
36
+ "types": "./dist/client.d.cts",
37
+ "default": "./dist/client.cjs"
38
+ }
34
39
  },
35
40
  "./ir": {
36
41
  "types": "./dist/ir.d.ts",
@@ -85,13 +90,14 @@
85
90
  "README.md"
86
91
  ],
87
92
  "dependencies": {
88
- "graphql": "^16.11.0",
89
- "jiti": "^2.4.2",
93
+ "@supabase/pg-parser": "0.1.7",
90
94
  "drizzle-kit": "^0.31.9",
91
95
  "drizzle-orm": "^0.45.2",
96
+ "graphql": "^16.11.0",
97
+ "jiti": "^2.4.2",
92
98
  "js-yaml": "^4.3.2",
93
99
  "zod": "^4.1.13",
94
- "@sequenceholdings/custom-roles-manifest": "0.1.0"
100
+ "@sequenceholdings/custom-roles-manifest": "0.2.0"
95
101
  },
96
102
  "devDependencies": {
97
103
  "@types/js-yaml": "^4.0.9",
@@ -45,8 +45,8 @@ export async function db${operationName}Full(variables: ${operationName}QueryVar
45
45
  return result;
46
46
  }`;
47
47
  } else if (type === 'mutation') {
48
- return `export async function db${operationName}(variables: ${operationName}MutationVariables) {
49
- const result = await executeOperation({ op: '${name}', variables });
48
+ return `export async function db${operationName}(variables: ${operationName}MutationVariables, options: { idempotencyKey?: string } = {}) {
49
+ const result = await executeOperation({ op: '${name}', variables, ...options });
50
50
 
51
51
  return result.${resultField};
52
52
  }`;
@@ -0,0 +1,10 @@
1
+ # Sequence development
2
+
3
+ Before every development task, read the live documentation for this project's
4
+ target environment. Find the environment's URL with `seq-studio envs list`
5
+ (or the project configuration), then open `<environment-url>/docs`.
6
+
7
+ Start with that site's `/docs/llms.txt` index and follow the relevant pages as
8
+ needed. The hosted docs are the single source of truth for platform usage;
9
+ do not duplicate their instructions in this file. If docs access is blocked,
10
+ open the same URL in the signed-in browser.
@@ -1,82 +1 @@
1
- # Sequence ORM namespace
2
-
3
- This directory defines ONE Sequence ORM namespace: TypeScript table
4
- definitions with row-level policies, plus handwritten GraphQL operations.
5
- `seq-studio orm apply` pushes it to Atlas, which validates, compiles, and
6
- applies it. Your app never talks to Postgres — it calls the data plane with
7
- `{ op: <hash>, variables }` through the generated hooks/functions.
8
-
9
- ## The loop
10
-
11
- 1. Edit `schema/*.ts` (tables, columns, links, policies) and/or
12
- `graphql/**/*.ts` (operations).
13
- 2. `seq-studio orm generate` — refreshes `schema.graphql` + generated types.
14
- 3. `seq-studio orm diff` — preview the migration for a schema change.
15
- 4. `seq-studio orm apply -e <env>` — pushes. Schema changes write a reviewed
16
- migration file into `migrations/`; operation-only edits take the fast path
17
- (seconds, no migration).
18
- 5. Commit `schema/`, `graphql/`, `schema.graphql`, `generated/`, and
19
- `migrations/` together.
20
-
21
- ## Hard rules
22
-
23
- - **Never hand-edit `migrations/`.** Migration files are generated by
24
- `seq-studio orm apply`/`diff` and replayed verbatim by the server. Editing
25
- or deleting a committed migration breaks the ledger.
26
- - **Never hand-edit `schema.graphql` or `generated/`.** Both are outputs of
27
- `seq-studio orm generate`. To change the API surface, change `schema/*.ts`.
28
- - **No raw SQL.** There is no query escape hatch: every read/write is a
29
- GraphQL document in `graphql/`, compiled at push time. For genuinely exotic
30
- multi-statement writes, declare a table `action` — parameterized, gated,
31
- audited.
32
- - **Every table needs row policies.** At minimum declare `read` plus either a
33
- legacy `write` policy or split `insert` / `update` policies when create and
34
- resolve are different actors. Policies are the row security boundary and are
35
- compiled into every operation touching the table. There is no "no policy"
36
- fallback — an unrestricted table must say so explicitly (`allow: true`
37
- variant or a `true` policy) so the decision is reviewable.
38
- - **Exactly one `defineNamespace`** (in `sequence.config.ts`), and every
39
- table module must call `defineTable` at import time — the CLI collects
40
- registrations by importing your files.
41
- - **Renames need hints.** Renaming a column or table without
42
- `.renamedFrom('old_name')` (column) / `renamedFrom` (table config) is a
43
- DROP + CREATE — data loss. The diff will refuse ambiguous renames; add the
44
- hint instead of forcing.
45
- - **Capabilities/roles are declared here, granted in the Permissions UI.**
46
- Never hardcode user identities in policies; use `claim('sub')` /
47
- `claim('org')` and grants.
48
-
49
- ## Policy DSL quick reference
50
-
51
- ```
52
- author_sub = claim('sub') -- row value vs caller claim
53
- org = claim('org') and status = 'open' -- boolean algebra
54
- exists(deal, org = claim('org')) -- traverse a declared link
55
- capability('deals-read') -- boolean grant check
56
- role('deal-manager') -- boolean role check
57
- ```
58
-
59
- Variants widen access per grant (permissive union):
60
-
61
- ```ts
62
- policies: {
63
- read: {
64
- default: "author_sub = claim('sub')",
65
- variants: [
66
- { when: "capability('deals-read')", policy: "org = claim('org')" },
67
- { when: "role('deal-manager')", allow: true },
68
- ],
69
- },
70
- }
71
- ```
72
-
73
- ## GraphQL operations
74
-
75
- - Named operations only; one export per document; gate with
76
- `@requires(capability: "…")` / `@requires(role: "…")`.
77
- - Dynamic filters are policy-bounded: `$where: <Table>BoolExp` /
78
- `$orderBy` / whole-input write objects are validated against a
79
- schema-derived whitelist and AND-ed with the table policy at runtime —
80
- they can never widen access.
81
- - Joins follow declared links (`toOne` / `toMany` / `toPlatformUser`) — there
82
- are no ad-hoc joins at query time. Declare the link, then select through it.
1
+ @AGENTS.md
@@ -0,0 +1,7 @@
1
+ import type { CodegenConfig } from '@graphql-codegen/cli'
2
+
3
+ // The runtime shim loads the package's preset object. Derive its type from the
4
+ // installed CLI so this declaration follows the consumer's codegen contract.
5
+ type ConfiguredOutput = Exclude<CodegenConfig['generates'][string], unknown[]>
6
+ declare const preset: Exclude<ConfiguredOutput['preset'], string | undefined>
7
+ export = preset
@@ -1,4 +1,5 @@
1
1
  import type { CodegenConfig } from '@graphql-codegen/cli'
2
+ import preset from './codegen.preset.cjs'
2
3
 
3
4
  /**
4
5
  * graphql-codegen config. `seq-studio orm generate` writes ./schema.graphql
@@ -14,7 +15,7 @@ const config: CodegenConfig = {
14
15
  documents: ['graphql/**/*.ts'],
15
16
  generates: {
16
17
  './generated/': {
17
- preset: './codegen.preset.cjs',
18
+ preset,
18
19
  },
19
20
  },
20
21
  }
@@ -4,9 +4,10 @@
4
4
  * variables }` — never query text, never SQL. Type names come from the
5
5
  * generated `schema.graphql` (`seq-studio orm generate`).
6
6
  *
7
- * Gate an operation with `@requires(capability: "…")` or
8
- * `@requires(role: "…")` — checked before execution, on top of the
9
- * table policies that are always compiled in.
7
+ * Gate an operation with `@requires(capability: "…")` — checked before
8
+ * execution, on top of the table policies that are always compiled in.
9
+ * Check capabilities, not roles: roles are created in Atlas and can change
10
+ * there.
10
11
  */
11
12
 
12
13
  export const GetOpenDeals = /* GraphQL */ `
@@ -11,7 +11,8 @@
11
11
  },
12
12
  "dependencies": {
13
13
  "@apollo/client": "^3.11.0",
14
- "@sequenceholdings/orm": "^2.0.0",
14
+ "@graphql-typed-document-node/core": "^3.2.0",
15
+ "@sequenceholdings/orm": "^2.2.0",
15
16
  "graphql": "^16.11.0"
16
17
  },
17
18
  "devDependencies": {
@@ -8,7 +8,8 @@ import { defineEnum, defineTable, t, toMany, toOne, toPlatformUser } from '@sequ
8
8
  *
9
9
  * Every table carries its own row-level policies. The policy DSL:
10
10
  * - `claim('sub')` / `claim('org')` — the caller's identity claims
11
- * - `capability('x')` / `role('y')` — boolean grants, resolved per caller
11
+ * - `capability('x')` — boolean grant, resolved per caller (check
12
+ * capabilities, not roles: roles are created in Atlas and can change)
12
13
  * - `exists(link, <predicate>)` — traverse a declared link
13
14
  * - variants: `default` applies to everyone; each variant WIDENS access
14
15
  * when its `when` guard matches (permissive union — grants only ever
@@ -39,7 +40,7 @@ export const deals = defineTable(
39
40
  default: "author_sub = claim('sub')",
40
41
  variants: [
41
42
  { when: "capability('deals-read')", policy: "org = claim('org')" },
42
- { when: "role('deal-manager')", allow: true },
43
+ { when: "capability('deals-admin')", allow: true },
43
44
  ],
44
45
  },
45
46
  write: "author_sub = claim('sub')",
@@ -3,9 +3,10 @@ import { defineNamespace } from '@sequenceholdings/orm/authoring'
3
3
  /**
4
4
  * The namespace config — exactly one per directory.
5
5
  *
6
- * Capabilities and roles are DECLARED here (verbatim custom-roles grammar);
7
- * who HOLDS them is granted later in the Permissions UI (FGA), never in code.
8
- * Table policies reference them with `capability('…')` / `role('…')`.
6
+ * Capabilities are DECLARED here (verbatim custom-roles grammar) — the
7
+ * contract your policies check with `capability('…')`. Roles that bundle
8
+ * them are created in Atlas (the namespace's Roles tab), and who HOLDS them
9
+ * is granted there too, never in code.
9
10
  */
10
11
  export default defineNamespace({
11
12
  // Rename me: the namespace becomes your Postgres schema (orm_<namespace>).
@@ -13,18 +14,13 @@ export default defineNamespace({
13
14
  description: 'Describe what this namespace stores and who uses it.',
14
15
  capabilities: {
15
16
  roles: {
16
- definitions: {
17
- 'deal-manager': {
18
- description: 'Full access to every deal in the namespace',
19
- default: false,
20
- inherits: [],
21
- grants: ['deals-read'],
22
- },
23
- },
24
17
  capabilities: {
25
18
  'deals-read': {
26
19
  description: 'Read all deals in the caller org (instead of author-only)',
27
20
  },
21
+ 'deals-admin': {
22
+ description: 'Read every deal in the namespace, in any org',
23
+ },
28
24
  },
29
25
  },
30
26
  uses: [],