qubu 0.4.0 → 0.4.2

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 (103) hide show
  1. package/dist/{canonical-BbnqavJm.mjs → canonical-BXUguqfo.mjs} +23 -23
  2. package/dist/codegen.d.mts +25 -33
  3. package/dist/codegen.mjs +38 -45
  4. package/dist/column-hqKr7-1I.mjs +620 -0
  5. package/dist/{complete-D5Djh-zo.mjs → complete-WYyVozgK.mjs} +50 -50
  6. package/dist/{complete-types-BavBtv8J.d.mts → complete-types-IjEn5VPN.d.mts} +56 -56
  7. package/dist/core.d.mts +2 -2
  8. package/dist/core.mjs +4 -4
  9. package/dist/ddl.d.mts +12 -12
  10. package/dist/ddl.mjs +13 -14
  11. package/dist/{dialect-b2-Z6uBF.mjs → dialect-wUKrnPMB.mjs} +2 -2
  12. package/dist/diff.d.mts +1 -1
  13. package/dist/diff.mjs +6 -7
  14. package/dist/{index-DH0qV6aS.d.mts → index-1DpA3mUh.d.mts} +20 -20
  15. package/dist/{index-D3ZOwPT-.d.mts → index-CPvfEheG.d.mts} +13 -15
  16. package/dist/index.d.mts +1 -1
  17. package/dist/index.mjs +94 -95
  18. package/dist/introspection.d.mts +8 -8
  19. package/dist/introspection.mjs +29 -30
  20. package/dist/{json-CUZlv4HT.mjs → json-Db7XRD91.mjs} +2 -2
  21. package/dist/migration.d.mts +20 -21
  22. package/dist/migration.mjs +5 -6
  23. package/dist/{mysql-CKEKGnj4.mjs → mysql-B_cYzzX2.mjs} +237 -7
  24. package/dist/mysql.d.mts +2 -2
  25. package/dist/mysql.mjs +3 -3
  26. package/dist/{on-conflict-4MOBl51J.mjs → on-conflict-hfPW0KmQ.mjs} +3 -4
  27. package/dist/postgres.d.mts +5 -5
  28. package/dist/postgres.mjs +6 -6
  29. package/dist/{registry-CXV8u7Pt.mjs → registry-BRMLYwDp.mjs} +26 -29
  30. package/dist/{relational-DuQ9IHSb.mjs → relational-BZ3WDPzC.mjs} +2 -2
  31. package/dist/schema.d.mts +1 -1
  32. package/dist/schema.mjs +5 -6
  33. package/dist/{snapshot-DJpfmxhQ.mjs → snapshot-C-W65HEd.mjs} +5 -5
  34. package/dist/snapshot.d.mts +3 -3
  35. package/dist/snapshot.mjs +5 -7
  36. package/dist/{source-DGO3DRgg.mjs → source-BcS2AsIg.mjs} +6 -8
  37. package/dist/{serialize-CFtYYAdk.mjs → sqlite-Cg0nwYEH.mjs} +326 -12
  38. package/dist/sqlite.d.mts +1 -1
  39. package/dist/sqlite.mjs +2 -2
  40. package/dist/{standard-BTVYKh_F.mjs → standard-DfcZEVOj.mjs} +1 -1
  41. package/dist/{table-D6rcs8SB.mjs → table-Bp5irMSj.mjs} +2 -3
  42. package/dist/{types-Deo_q43Y.d.mts → types-BK1COGZe.d.mts} +1113 -1128
  43. package/dist/{types-g-vVvj1B.mjs → types-JM3FcAnX.mjs} +7 -8
  44. package/dist/{types-CSNJTYaM.d.mts → types-JSZHpUEj.d.mts} +83 -84
  45. package/dist/{value-b6OFZXVS.mjs → value-Bi71Agyf.mjs} +1 -1
  46. package/dist/vite/ambient.d.ts +309 -340
  47. package/dist/vite.d.mts +5 -6
  48. package/dist/vite.mjs +3 -4
  49. package/docs/dialects-and-execution.md +45 -55
  50. package/docs/getting-started.md +4 -4
  51. package/docs/guides/better-auth.md +57 -0
  52. package/docs/guides/compose-queries.md +24 -67
  53. package/docs/guides/drizzle.md +23 -23
  54. package/docs/guides/extensions/dialects.md +4 -4
  55. package/docs/guides/extensions/sources-and-clauses.md +15 -15
  56. package/docs/guides/extensions/typed-expressions.md +13 -17
  57. package/docs/guides/extensions/unsafe-syntax.md +3 -3
  58. package/docs/guides/json.md +7 -7
  59. package/docs/guides/mutations.md +14 -21
  60. package/docs/guides/select/conditions.md +6 -8
  61. package/docs/guides/select/grouping-and-windows.md +4 -15
  62. package/docs/guides/select/ordering-and-pagination.md +6 -19
  63. package/docs/guides/select/overview.md +12 -26
  64. package/docs/guides/sql-templates.md +20 -24
  65. package/docs/guides/vite-plugin.md +9 -13
  66. package/docs/index.md +5 -7
  67. package/docs/query-model/fragments.md +4 -15
  68. package/docs/query-model/result-shapes.md +11 -14
  69. package/docs/query-model/source-scope.md +31 -49
  70. package/docs/reference/mysql-snapshot.md +2 -5
  71. package/docs/reference/postgres-snapshot.md +3 -3
  72. package/docs/reference/sqlite-snapshot.md +2 -5
  73. package/docs/reference/supported-surface.md +26 -26
  74. package/docs/schema/catalog-model.md +2 -5
  75. package/docs/schema/code-generation.md +18 -18
  76. package/docs/schema/columns-and-writes.md +17 -25
  77. package/docs/schema/constraints-and-indexes.md +36 -52
  78. package/docs/schema/ddl-emission.md +6 -6
  79. package/docs/schema/diff.md +5 -5
  80. package/docs/schema/introspection.md +7 -7
  81. package/docs/schema/migration-plans.md +9 -9
  82. package/docs/schema/snapshots.md +3 -3
  83. package/docs/schema/storage-and-schema-sql.md +11 -11
  84. package/docs/schema/tables-and-names.md +11 -14
  85. package/docs/sql-semantic-types.md +10 -10
  86. package/docs/troubleshooting.md +10 -10
  87. package/package.json +21 -33
  88. package/skills/qubu/agents/openai.yaml +3 -3
  89. package/dist/column-D-8OqGuV.mjs +0 -328
  90. package/dist/column-LV7oGQde.mjs +0 -296
  91. package/dist/drizzle-mysql.d.mts +0 -24
  92. package/dist/drizzle-mysql.mjs +0 -72
  93. package/dist/drizzle-postgres.d.mts +0 -24
  94. package/dist/drizzle-postgres.mjs +0 -73
  95. package/dist/drizzle-sqlite.d.mts +0 -57
  96. package/dist/drizzle-sqlite.mjs +0 -108
  97. package/dist/drizzle.d.mts +0 -13
  98. package/dist/drizzle.mjs +0 -2
  99. package/dist/errors-BGCoLe_r.mjs +0 -14
  100. package/dist/postgres-BK2APkKP.mjs +0 -236
  101. package/dist/runtime-Cn_Xgzta.mjs +0 -193
  102. package/dist/sqlite-CrsK0Fza.mjs +0 -320
  103. package/dist/types-DZsueVoI.d.mts +0 -45
@@ -54,20 +54,9 @@ Parameter values are not fragment metadata. A renderer calls
54
54
  `context.parameter(value)`, and `render()` collects values in placeholder order:
55
55
 
56
56
  ```ts
57
- import {
58
- and,
59
- eq,
60
- from,
61
- integer,
62
- like,
63
- render,
64
- select,
65
- table,
66
- text,
67
- where,
68
- } from 'qubu'
69
-
70
- const users = table('users', {
57
+ import { and, eq, from, integer, like, render, select, table, text, where } from "qubu"
58
+
59
+ const users = table("users", {
71
60
  id: integer(),
72
61
  name: text(),
73
62
  })
@@ -75,7 +64,7 @@ const users = table('users', {
75
64
  const query = select(
76
65
  { id: users.id },
77
66
  from(users),
78
- where(and(eq(users.id, 7), like(users.name, '%Ada%')))
67
+ where(and(eq(users.id, 7), like(users.name, "%Ada%"))),
79
68
  )
80
69
 
81
70
  render(query)
@@ -7,9 +7,9 @@
7
7
  An object projection uses its keys as result names:
8
8
 
9
9
  ```ts
10
- import { from, integer, select, table, text, upper } from 'qubu'
10
+ import { from, integer, select, table, text, upper } from "qubu"
11
11
 
12
- const users = table('users', {
12
+ const users = table("users", {
13
13
  id: integer(),
14
14
  name: text(),
15
15
  })
@@ -19,7 +19,7 @@ const query = select(
19
19
  id: users.id,
20
20
  displayName: upper(users.name),
21
21
  },
22
- from(users)
22
+ from(users),
23
23
  )
24
24
 
25
25
  type Row = typeof query.row
@@ -31,12 +31,9 @@ shaped result. Reserve `all(source)` for a whole-source result contract. It
31
31
  expands to named columns, so the SQL columns and inferred row keys stay aligned:
32
32
 
33
33
  ```ts
34
- import { all, from, select, upper } from 'qubu'
34
+ import { all, from, select, upper } from "qubu"
35
35
 
36
- const query = select(
37
- { ...all(users), normalizedName: upper(users.name) },
38
- from(users)
39
- )
36
+ const query = select({ ...all(users), normalizedName: upper(users.name) }, from(users))
40
37
  ```
41
38
 
42
39
  When a query becomes a CTE or derived table, its row shape becomes the columns
@@ -53,13 +50,13 @@ source widens with `null`, while an expression with its own non-null result
53
50
  contract can stay non-null:
54
51
 
55
52
  ```ts
56
- import { count, eq, from, integer, leftJoin, select, table, text } from 'qubu'
53
+ import { count, eq, from, integer, leftJoin, select, table, text } from "qubu"
57
54
 
58
- const users = table('users', {
55
+ const users = table("users", {
59
56
  id: integer(),
60
57
  name: text(),
61
58
  })
62
- const posts = table('posts', {
59
+ const posts = table("posts", {
63
60
  id: integer(),
64
61
  authorId: integer(),
65
62
  title: text(),
@@ -72,7 +69,7 @@ const query = select(
72
69
  postCount: count(posts.id),
73
70
  },
74
71
  from(users),
75
- leftJoin(posts, eq(users.id, posts.authorId))
72
+ leftJoin(posts, eq(users.id, posts.authorId)),
76
73
  )
77
74
 
78
75
  type Row = typeof query.row
@@ -89,9 +86,9 @@ expression with non-null branches can return a non-null result.
89
86
  result includes `null` when the query may return no rows:
90
87
 
91
88
  ```ts
92
- import { fetchFirst, from, scalar, select, table, value } from 'qubu'
89
+ import { fetchFirst, from, scalar, select, table, value } from "qubu"
93
90
 
94
- const users = table('users', { id: integer() })
91
+ const users = table("users", { id: integer() })
95
92
  const firstUser = select({ id: users.id }, from(users), fetchFirst(1))
96
93
 
97
94
  const firstId = scalar(firstUser)
@@ -13,12 +13,12 @@ Qubu reports a missing source when a query selects a column from a table that
13
13
  does not appear in the query:
14
14
 
15
15
  ```ts
16
- import { from, integer, select, table, text } from 'qubu'
16
+ import { from, integer, select, table, text } from "qubu"
17
17
 
18
- const users = table('users', {
18
+ const users = table("users", {
19
19
  id: integer(),
20
20
  })
21
- const posts = table('posts', {
21
+ const posts = table("posts", {
22
22
  id: integer(),
23
23
  title: text(),
24
24
  })
@@ -31,12 +31,12 @@ Add the source that owns the column, or join it with a condition that refers to
31
31
  both sources:
32
32
 
33
33
  ```ts
34
- import { eq, from, innerJoin, integer, select, table } from 'qubu'
34
+ import { eq, from, innerJoin, integer, select, table } from "qubu"
35
35
 
36
- const users = table('users', {
36
+ const users = table("users", {
37
37
  id: integer(),
38
38
  })
39
- const posts = table('posts', {
39
+ const posts = table("posts", {
40
40
  id: integer(),
41
41
  authorId: integer(),
42
42
  })
@@ -44,7 +44,7 @@ const posts = table('posts', {
44
44
  const query = select(
45
45
  { userId: users.id, postId: posts.id },
46
46
  from(users),
47
- innerJoin(posts, eq(users.id, posts.authorId))
47
+ innerJoin(posts, eq(users.id, posts.authorId)),
48
48
  )
49
49
  ```
50
50
 
@@ -54,14 +54,14 @@ Aliases, CTEs, derived queries, and custom sources expose new source identities.
54
54
  Use their columns after wrapping the original source:
55
55
 
56
56
  ```ts
57
- import { alias, from, integer, select, table, text } from 'qubu'
57
+ import { alias, from, integer, select, table, text } from "qubu"
58
58
 
59
- const users = table('users', {
59
+ const users = table("users", {
60
60
  id: integer(),
61
61
  name: text(),
62
62
  })
63
63
 
64
- const author = alias(users, 'author')
64
+ const author = alias(users, "author")
65
65
  const query = select({ name: author.name }, from(author))
66
66
  ```
67
67
 
@@ -72,10 +72,10 @@ The same rule applies to a CTE or derived query. A query's selected row becomes
72
72
  the set of columns exposed by its new source:
73
73
 
74
74
  ```ts
75
- import { alias, from, lower, select } from 'qubu'
75
+ import { alias, from, lower, select } from "qubu"
76
76
 
77
77
  const names = select({ name: lower(users.name) }, from(users))
78
- const namesSource = alias(names, 'names')
78
+ const namesSource = alias(names, "names")
79
79
 
80
80
  const query = select({ name: namesSource.name }, from(namesSource))
81
81
  ```
@@ -90,35 +90,31 @@ Use `customSource()` for a table-valued function or another relation that
90
90
  definitions, and complete relation renderer:
91
91
 
92
92
  ```ts
93
- import { eq, from, integer, select, text, where } from 'qubu'
94
- import { identifier } from 'qubu/core'
95
- import { customSource } from 'qubu/schema'
93
+ import { eq, from, integer, select, text, where } from "qubu"
94
+ import { identifier } from "qubu/core"
95
+ import { customSource } from "qubu/schema"
96
96
 
97
97
  const entries = customSource({
98
98
  identity: {
99
- sourceKind: 'table-function',
100
- name: 'json_each',
101
- alias: 'entry',
99
+ sourceKind: "table-function",
100
+ name: "json_each",
101
+ alias: "entry",
102
102
  },
103
- sourceKind: 'table-function',
104
- reference: identifier('entry'),
103
+ sourceKind: "table-function",
104
+ reference: identifier("entry"),
105
105
  columns: {
106
106
  key: integer(),
107
107
  value: text({ nullable: true }),
108
108
  },
109
109
  render(context) {
110
- context.append('json_each(')
110
+ context.append("json_each(")
111
111
  context.parameter('{"a":1}')
112
- context.append(') AS ')
113
- context.render(identifier('entry'))
112
+ context.append(") AS ")
113
+ context.render(identifier("entry"))
114
114
  },
115
115
  })
116
116
 
117
- const query = select(
118
- { value: entries.value },
119
- from(entries),
120
- where(eq(entries.key, 7))
121
- )
117
+ const query = select({ value: entries.value }, from(entries), where(eq(entries.key, 7)))
122
118
  ```
123
119
 
124
120
  `identity` is the type-level source key. `reference` is the SQL qualifier used
@@ -135,20 +131,10 @@ Use `correlate()` when an inner query intentionally reads a source from its
135
131
  enclosing query. The provision changes type checking but emits no SQL:
136
132
 
137
133
  ```ts
138
- import {
139
- correlate,
140
- crossJoin,
141
- eq,
142
- from,
143
- integer,
144
- lateral,
145
- select,
146
- table,
147
- where,
148
- } from 'qubu'
149
-
150
- const users = table('users', { id: integer() })
151
- const posts = table('posts', {
134
+ import { correlate, crossJoin, eq, from, integer, lateral, select, table, where } from "qubu"
135
+
136
+ const users = table("users", { id: integer() })
137
+ const posts = table("posts", {
152
138
  id: integer(),
153
139
  authorId: integer(),
154
140
  })
@@ -157,15 +143,11 @@ const recentPost = select(
157
143
  { id: posts.id },
158
144
  from(posts),
159
145
  correlate(users),
160
- where(eq(posts.authorId, users.id))
146
+ where(eq(posts.authorId, users.id)),
161
147
  )
162
148
 
163
- const recent = lateral(recentPost, 'recent_post')
164
- const query = select(
165
- { userId: users.id, postId: recent.id },
166
- from(users),
167
- crossJoin(recent)
168
- )
149
+ const recent = lateral(recentPost, "recent_post")
150
+ const query = select({ userId: users.id, postId: recent.id }, from(users), crossJoin(recent))
169
151
  ```
170
152
 
171
153
  The inner query consumes `posts` locally. The enclosing `users` source satisfies
@@ -7,10 +7,7 @@
7
7
  Import the adapter from the optional snapshot entrypoint:
8
8
 
9
9
  ```ts
10
- import {
11
- createMysqlSchemaSnapshot,
12
- tryCreateMysqlSchemaSnapshot,
13
- } from 'qubu/snapshot'
10
+ import { createMysqlSchemaSnapshot, tryCreateMysqlSchemaSnapshot } from "qubu/snapshot"
14
11
 
15
12
  const snapshot = createMysqlSchemaSnapshot(appSchema)
16
13
  const result = tryCreateMysqlSchemaSnapshot(appSchema)
@@ -44,7 +41,7 @@ a schema may include a MySQL engine or version-specific feature:
44
41
  const result = tryCreateMysqlSchemaSnapshot(appSchema)
45
42
  if (!result.ok) {
46
43
  for (const issue of result.diagnostics) {
47
- console.error(issue.path.join('.'), issue.code, issue.message)
44
+ console.error(issue.path.join("."), issue.code, issue.message)
48
45
  }
49
46
  }
50
47
  ```
@@ -11,7 +11,7 @@ import {
11
11
  createSchemaSnapshot,
12
12
  createPostgresSchemaSnapshot,
13
13
  postgresSnapshotAdapter,
14
- } from 'qubu/snapshot'
14
+ } from "qubu/snapshot"
15
15
 
16
16
  const snapshot = createPostgresSchemaSnapshot(appSchema)
17
17
  // Equivalent: createSchemaSnapshot(appSchema, { adapter: postgresSnapshotAdapter })
@@ -46,12 +46,12 @@ schema and application boundaries.
46
46
  Use the non-throwing form when a schema may contain a server-specific feature:
47
47
 
48
48
  ```ts
49
- import { tryCreatePostgresSchemaSnapshot } from 'qubu/snapshot'
49
+ import { tryCreatePostgresSchemaSnapshot } from "qubu/snapshot"
50
50
 
51
51
  const result = tryCreatePostgresSchemaSnapshot(appSchema)
52
52
  if (!result.ok) {
53
53
  for (const issue of result.diagnostics) {
54
- console.error(issue.path.join('.'), issue.code, issue.message)
54
+ console.error(issue.path.join("."), issue.code, issue.message)
55
55
  }
56
56
  }
57
57
  ```
@@ -5,10 +5,7 @@
5
5
  Import the adapter from the optional snapshot entrypoint:
6
6
 
7
7
  ```ts
8
- import {
9
- createSqliteSchemaSnapshot,
10
- tryCreateSqliteSchemaSnapshot,
11
- } from 'qubu/snapshot'
8
+ import { createSqliteSchemaSnapshot, tryCreateSqliteSchemaSnapshot } from "qubu/snapshot"
12
9
 
13
10
  const snapshot = createSqliteSchemaSnapshot(appSchema)
14
11
  const result = tryCreateSqliteSchemaSnapshot(appSchema)
@@ -42,7 +39,7 @@ schema may include a feature that depends on a SQLite version or table shape:
42
39
  const result = tryCreateSqliteSchemaSnapshot(appSchema)
43
40
  if (!result.ok) {
44
41
  for (const issue of result.diagnostics) {
45
- console.error(issue.path.join('.'), issue.code, issue.message)
42
+ console.error(issue.path.join("."), issue.code, issue.message)
46
43
  }
47
44
  }
48
45
  ```
@@ -4,32 +4,32 @@
4
4
 
5
5
  ## Package entrypoints
6
6
 
7
- | Import | Kind | Use it for |
8
- | ----------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------- |
9
- | `qubu` | Runtime | Ordinary query and schema definitions, reads, writes, SQL templates, rendering, EXPLAIN, and execution contracts |
10
- | `qubu/core` | Runtime | Fragment and rendering primitives, dialect construction, SQL types, and extension constructors |
11
- | `qubu/codegen` | Runtime | Deterministic machine-owned TypeScript schemas from complete, non-lossy introspection |
12
- | `qubu/ddl` | Runtime | DDL preflight and deterministic PostgreSQL, SQLite, or MySQL emission from a migration plan |
13
- | `qubu/diff` | Runtime | Canonical Snapshot v1 or v2 comparison, rename hints, suggestions, and safety diagnostics |
14
- | `qubu/drizzle` | Runtime | Shared Drizzle conversion errors and dialect types |
15
- | `qubu/introspection` | Runtime | Catalog readers, normalized catalogs, and mapping to Snapshot v1 or v2 |
16
- | `qubu/migration` | Runtime | Pure migration planning with dependencies, decisions, preconditions, and explicit custom SQL |
17
- | `qubu/mysql` | Runtime | The MySQL query dialect policy |
18
- | `qubu/postgres` | Runtime | PostgreSQL query dialect helpers such as `postgresDialect()` and `ilike()` |
19
- | `qubu/schema` | Runtime | Advanced schema metadata, storage and constraint models, source models, and schema-expression extensions |
20
- | `qubu/snapshot` | Runtime | Canonical Snapshot v1 and v2 traversal, encoding, decoding, diagnostics, and digests |
21
- | `qubu/sqlite` | Runtime | The SQLite query dialect policy |
22
- | `qubu/vite` | Runtime | The optional `qubu()` Vite compiler hint |
23
- | `qubu/package.json` | JSON | The published package manifest |
24
- | `qubu/drizzle/mysql` | Runtime | Runtime conversion from Qubu schemas to MySQL Drizzle tables |
25
- | `qubu/drizzle/postgres` | Runtime | Runtime conversion from Qubu schemas to PostgreSQL Drizzle tables |
26
- | `qubu/drizzle/sqlite` | Runtime | Runtime conversion from Qubu schemas to SQLite Drizzle tables |
27
- | `qubu/globals` | TypeScript types | Opt-in ambient declarations for directive-bearing modules |
28
-
29
- The package validator confirms 17 runtime entrypoints, 18 type entrypoints,
30
- `qubu/package.json` as JSON, and `qubu/globals` as type-only. Concrete dialect
31
- constructors live on their database subpaths. The root renderer uses Qubu's
32
- standard SQL policy by default.
7
+ | Import | Kind | Use it for |
8
+ | ------------------------ | ---------------- | ---------------------------------------------------------------------------------------------------------------- |
9
+ | `qubu` | Runtime | Ordinary query and schema definitions, reads, writes, SQL templates, rendering, EXPLAIN, and execution contracts |
10
+ | `qubu/core` | Runtime | Fragment and rendering primitives, dialect construction, SQL types, and extension constructors |
11
+ | `qubu/codegen` | Runtime | Deterministic machine-owned TypeScript schemas from complete, non-lossy introspection |
12
+ | `qubu/ddl` | Runtime | DDL preflight and deterministic PostgreSQL, SQLite, or MySQL emission from a migration plan |
13
+ | `qubu/diff` | Runtime | Canonical Snapshot v1 or v2 comparison, rename hints, suggestions, and safety diagnostics |
14
+ | `qubu/introspection` | Runtime | Catalog readers, normalized catalogs, and mapping to Snapshot v1 or v2 |
15
+ | `qubu/migration` | Runtime | Pure migration planning with dependencies, decisions, preconditions, and explicit custom SQL |
16
+ | `qubu/mysql` | Runtime | The MySQL query dialect policy |
17
+ | `qubu/postgres` | Runtime | PostgreSQL query dialect helpers such as `postgresDialect()` and `ilike()` |
18
+ | `qubu/schema` | Runtime | Advanced schema metadata, storage and constraint models, source models, and schema-expression extensions |
19
+ | `qubu/snapshot` | Runtime | Canonical Snapshot v1 and v2 traversal, encoding, decoding, diagnostics, and digests |
20
+ | `qubu/sqlite` | Runtime | The SQLite query dialect policy |
21
+ | `qubu/vite` | Runtime | The optional `qubu()` Vite compiler hint |
22
+ | `qubu/package.json` | JSON | The published package manifest |
23
+ | `@qubu/drizzle` | Runtime | Shared Drizzle conversion errors and dialect types |
24
+ | `@qubu/drizzle/mysql` | Runtime | Runtime conversion from Qubu schemas to MySQL Drizzle tables |
25
+ | `@qubu/drizzle/postgres` | Runtime | Runtime conversion from Qubu schemas to PostgreSQL Drizzle tables |
26
+ | `@qubu/drizzle/sqlite` | Runtime | Runtime conversion from Qubu schemas to SQLite Drizzle tables |
27
+ | `@qubu/better-auth` | Runtime | Better Auth schema derivation and native PostgreSQL, MySQL, and SQLite adapter behavior |
28
+ | `qubu/globals` | TypeScript types | Opt-in ambient declarations for directive-bearing modules |
29
+
30
+ The package validator checks every declared entrypoint in each packed workspace
31
+ package. Concrete dialect constructors live on their database subpaths. The
32
+ root renderer uses Qubu's standard SQL policy by default.
33
33
 
34
34
  Snapshot dialect behavior is documented in the [PostgreSQL](postgres-snapshot.md),
35
35
  [SQLite](sqlite-snapshot.md), and [MySQL](mysql-snapshot.md) support matrices.
@@ -12,7 +12,7 @@ families and an immutable materializer:
12
12
  import {
13
13
  createCompleteIntrospectionCatalog,
14
14
  mapCatalogToCompleteSnapshot,
15
- } from 'qubu/introspection'
15
+ } from "qubu/introspection"
16
16
 
17
17
  const completeCatalog = createCompleteIntrospectionCatalog(catalog)
18
18
  const result = mapCatalogToCompleteSnapshot(completeCatalog)
@@ -36,10 +36,7 @@ references and are not used as logical IDs.
36
36
  `qubu/snapshot` provides the strict complete format as a separate API:
37
37
 
38
38
  ```ts
39
- import {
40
- decodeCompleteSchemaSnapshot,
41
- encodeCompleteSchemaSnapshot,
42
- } from 'qubu/snapshot'
39
+ import { decodeCompleteSchemaSnapshot, encodeCompleteSchemaSnapshot } from "qubu/snapshot"
43
40
 
44
41
  const encoded = encodeCompleteSchemaSnapshot(snapshotV2)
45
42
  const decoded = decodeCompleteSchemaSnapshot(encoded)
@@ -12,19 +12,19 @@ Read and map one namespace in strict mode, then pass that exact result to the
12
12
  generator:
13
13
 
14
14
  ```ts
15
- import { writeFile } from 'node:fs/promises'
16
- import { generateSchemaSource } from 'qubu/codegen'
17
- import { mapCatalogToSnapshot, readSqliteCatalog } from 'qubu/introspection'
15
+ import { writeFile } from "node:fs/promises"
16
+ import { generateSchemaSource } from "qubu/codegen"
17
+ import { mapCatalogToSnapshot, readSqliteCatalog } from "qubu/introspection"
18
18
 
19
- const catalog = await readSqliteCatalog(connection, { namespace: 'main' })
20
- const introspection = mapCatalogToSnapshot(catalog, { namespace: 'main' })
19
+ const catalog = await readSqliteCatalog(connection, { namespace: "main" })
20
+ const introspection = mapCatalogToSnapshot(catalog, { namespace: "main" })
21
21
  const generated = generateSchemaSource(introspection)
22
22
 
23
23
  if (!generated.ok) {
24
- throw new Error(generated.diagnostics.map(issue => issue.message).join('\n'))
24
+ throw new Error(generated.diagnostics.map((issue) => issue.message).join("\n"))
25
25
  }
26
26
 
27
- await writeFile('src/schema.generated.ts', generated.source, 'utf8')
27
+ await writeFile("src/schema.generated.ts", generated.source, "utf8")
28
28
  ```
29
29
 
30
30
  `writeFile()` belongs to the application; `generateSchemaSource()` only
@@ -48,13 +48,13 @@ the generated module is accepted, its serialized snapshot becomes the identity
48
48
  baseline for the next catalog read:
49
49
 
50
50
  ```ts
51
- import { mapCatalogToSnapshot } from 'qubu/introspection'
52
- import { createSqliteSchemaSnapshot } from 'qubu/snapshot'
53
- import { mainSchema } from './schema.generated.ts'
51
+ import { mapCatalogToSnapshot } from "qubu/introspection"
52
+ import { createSqliteSchemaSnapshot } from "qubu/snapshot"
53
+ import { mainSchema } from "./schema.generated.ts"
54
54
 
55
55
  const previousSnapshot = createSqliteSchemaSnapshot(mainSchema)
56
56
  const next = mapCatalogToSnapshot(nextCatalog, {
57
- namespace: 'main',
57
+ namespace: "main",
58
58
  previousSnapshot,
59
59
  })
60
60
  ```
@@ -75,17 +75,17 @@ Use the controlled callbacks to adopt trusted names or application mappings:
75
75
  ```ts
76
76
  const generated = generateSchemaSource(introspection, {
77
77
  naming(context) {
78
- if (context.kind === 'table' && context.physicalName === 'user_records') {
79
- return 'users'
78
+ if (context.kind === "table" && context.physicalName === "user_records") {
79
+ return "users"
80
80
  }
81
81
  },
82
82
  mapColumn(context) {
83
- if (context.columnPhysicalName === 'account_id') {
83
+ if (context.columnPhysicalName === "account_id") {
84
84
  return {
85
- output: 'string',
86
- insert: 'string',
87
- update: 'string',
88
- sqlDomain: 'uuid',
85
+ output: "string",
86
+ insert: "string",
87
+ update: "string",
88
+ sqlDomain: "uuid",
89
89
  }
90
90
  }
91
91
  },
@@ -17,9 +17,9 @@ Use `column<Output, Insert, Update>()` when the driver returns a different type
17
17
  from the type the application writes:
18
18
 
19
19
  ```ts
20
- import { column, integer, table, text } from 'qubu'
20
+ import { column, integer, table, text } from "qubu"
21
21
 
22
- const accounts = table('accounts', {
22
+ const accounts = table("accounts", {
23
23
  id: integer({ generated: true }),
24
24
  email: text(),
25
25
  nickname: text({ nullable: true, hasDefault: true }),
@@ -36,27 +36,19 @@ The legacy hasDefault and generated flags describe the write contract. Use
36
36
  complete metadata when schema tooling also needs the database fact:
37
37
 
38
38
  ```ts
39
- import {
40
- boolean,
41
- generatedColumn,
42
- identityColumn,
43
- integer,
44
- table,
45
- text,
46
- value,
47
- } from 'qubu'
48
- import { defineSchemaExpression } from 'qubu/schema'
49
-
50
- const currentTimestamp = defineSchemaExpression('function', context => {
51
- context.append('CURRENT_TIMESTAMP')
39
+ import { boolean, generatedColumn, identityColumn, integer, table, text, value } from "qubu"
40
+ import { defineSchemaExpression } from "qubu/schema"
41
+
42
+ const currentTimestamp = defineSchemaExpression("function", (context) => {
43
+ context.append("CURRENT_TIMESTAMP")
52
44
  })
53
45
 
54
- const accounts = table('accounts', {
55
- id: integer({ identity: identityColumn('always') }),
56
- status: text({ default: 'pending' }),
46
+ const accounts = table("accounts", {
47
+ id: integer({ identity: identityColumn("always") }),
48
+ status: text({ default: "pending" }),
57
49
  active: boolean({ default: true }),
58
50
  score: integer({
59
- generatedColumn: generatedColumn(value(1), 'stored'),
51
+ generatedColumn: generatedColumn(value(1), "stored"),
60
52
  }),
61
53
  createdAt: text({
62
54
  default: currentTimestamp,
@@ -90,10 +82,10 @@ Use `$type<T>()` to narrow a helper's TypeScript type without changing its
90
82
  runtime column definition:
91
83
 
92
84
  ```ts
93
- import { table, text } from 'qubu'
85
+ import { table, text } from "qubu"
94
86
 
95
- const users = table('users', {
96
- status: text().$type<'active' | 'disabled'>(),
87
+ const users = table("users", {
88
+ status: text().$type<"active" | "disabled">(),
97
89
  })
98
90
  ```
99
91
 
@@ -106,14 +98,14 @@ does not validate values at runtime or add a database constraint.
106
98
  code. The following example uses the accounts table from the earlier example:
107
99
 
108
100
  ```ts
109
- import type { TableInsertInput, TableUpdateInput } from 'qubu'
101
+ import type { TableInsertInput, TableUpdateInput } from "qubu"
110
102
 
111
103
  type AccountInsert = TableInsertInput<typeof accounts.definitions>
112
104
  type AccountUpdate = TableUpdateInput<typeof accounts.definitions>
113
105
 
114
106
  const insert: AccountInsert = {
115
- email: 'ada@example.com',
116
- externalScore: '10',
107
+ email: "ada@example.com",
108
+ externalScore: "10",
117
109
  }
118
110
 
119
111
  const update: AccountUpdate = {