@adminiumjs/meta 0.1.0-rc.1

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 (194) hide show
  1. package/LICENSE +661 -0
  2. package/dist/bootstrap.d.ts +103 -0
  3. package/dist/bootstrap.d.ts.map +1 -0
  4. package/dist/bootstrap.js +225 -0
  5. package/dist/bootstrap.js.map +1 -0
  6. package/dist/columns.d.ts +44 -0
  7. package/dist/columns.d.ts.map +1 -0
  8. package/dist/columns.js +57 -0
  9. package/dist/columns.js.map +1 -0
  10. package/dist/connect.d.ts +38 -0
  11. package/dist/connect.d.ts.map +1 -0
  12. package/dist/connect.js +57 -0
  13. package/dist/connect.js.map +1 -0
  14. package/dist/ids.d.ts +79 -0
  15. package/dist/ids.d.ts.map +1 -0
  16. package/dist/ids.js +165 -0
  17. package/dist/ids.js.map +1 -0
  18. package/dist/index.d.ts +21 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +21 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/migrations/0001_core_auth.d.ts +9 -0
  23. package/dist/migrations/0001_core_auth.d.ts.map +1 -0
  24. package/dist/migrations/0001_core_auth.js +102 -0
  25. package/dist/migrations/0001_core_auth.js.map +1 -0
  26. package/dist/migrations/0002_rbac.d.ts +8 -0
  27. package/dist/migrations/0002_rbac.d.ts.map +1 -0
  28. package/dist/migrations/0002_rbac.js +75 -0
  29. package/dist/migrations/0002_rbac.js.map +1 -0
  30. package/dist/migrations/0003_connections_schema.d.ts +9 -0
  31. package/dist/migrations/0003_connections_schema.d.ts.map +1 -0
  32. package/dist/migrations/0003_connections_schema.js +100 -0
  33. package/dist/migrations/0003_connections_schema.js.map +1 -0
  34. package/dist/migrations/0004_pages_views.d.ts +8 -0
  35. package/dist/migrations/0004_pages_views.d.ts.map +1 -0
  36. package/dist/migrations/0004_pages_views.js +59 -0
  37. package/dist/migrations/0004_pages_views.js.map +1 -0
  38. package/dist/migrations/0005_ops.d.ts +9 -0
  39. package/dist/migrations/0005_ops.d.ts.map +1 -0
  40. package/dist/migrations/0005_ops.js +104 -0
  41. package/dist/migrations/0005_ops.js.map +1 -0
  42. package/dist/migrations/0006_platform.d.ts +11 -0
  43. package/dist/migrations/0006_platform.d.ts.map +1 -0
  44. package/dist/migrations/0006_platform.js +259 -0
  45. package/dist/migrations/0006_platform.js.map +1 -0
  46. package/dist/migrations/0007_llm_runs.d.ts +33 -0
  47. package/dist/migrations/0007_llm_runs.d.ts.map +1 -0
  48. package/dist/migrations/0007_llm_runs.js +62 -0
  49. package/dist/migrations/0007_llm_runs.js.map +1 -0
  50. package/dist/migrations/0008_llm_overrides.d.ts +18 -0
  51. package/dist/migrations/0008_llm_overrides.d.ts.map +1 -0
  52. package/dist/migrations/0008_llm_overrides.js +24 -0
  53. package/dist/migrations/0008_llm_overrides.js.map +1 -0
  54. package/dist/migrations/0009_views_kind.d.ts +20 -0
  55. package/dist/migrations/0009_views_kind.d.ts.map +1 -0
  56. package/dist/migrations/0009_views_kind.js +24 -0
  57. package/dist/migrations/0009_views_kind.js.map +1 -0
  58. package/dist/migrations/0010_llm_prompt_version_width.d.ts +19 -0
  59. package/dist/migrations/0010_llm_prompt_version_width.d.ts.map +1 -0
  60. package/dist/migrations/0010_llm_prompt_version_width.js +28 -0
  61. package/dist/migrations/0010_llm_prompt_version_width.js.map +1 -0
  62. package/dist/migrations/index.d.ts +29 -0
  63. package/dist/migrations/index.d.ts.map +1 -0
  64. package/dist/migrations/index.js +43 -0
  65. package/dist/migrations/index.js.map +1 -0
  66. package/dist/migrator.d.ts +83 -0
  67. package/dist/migrator.d.ts.map +1 -0
  68. package/dist/migrator.js +173 -0
  69. package/dist/migrator.js.map +1 -0
  70. package/dist/prefix.d.ts +19 -0
  71. package/dist/prefix.d.ts.map +1 -0
  72. package/dist/prefix.js +33 -0
  73. package/dist/prefix.js.map +1 -0
  74. package/dist/repos/api-keys.d.ts +31 -0
  75. package/dist/repos/api-keys.d.ts.map +1 -0
  76. package/dist/repos/api-keys.js +62 -0
  77. package/dist/repos/api-keys.js.map +1 -0
  78. package/dist/repos/audit.d.ts +51 -0
  79. package/dist/repos/audit.d.ts.map +1 -0
  80. package/dist/repos/audit.js +78 -0
  81. package/dist/repos/audit.js.map +1 -0
  82. package/dist/repos/connections.d.ts +90 -0
  83. package/dist/repos/connections.d.ts.map +1 -0
  84. package/dist/repos/connections.js +191 -0
  85. package/dist/repos/connections.js.map +1 -0
  86. package/dist/repos/email-templates.d.ts +47 -0
  87. package/dist/repos/email-templates.d.ts.map +1 -0
  88. package/dist/repos/email-templates.js +93 -0
  89. package/dist/repos/email-templates.js.map +1 -0
  90. package/dist/repos/exports.d.ts +67 -0
  91. package/dist/repos/exports.d.ts.map +1 -0
  92. package/dist/repos/exports.js +132 -0
  93. package/dist/repos/exports.js.map +1 -0
  94. package/dist/repos/files.d.ts +52 -0
  95. package/dist/repos/files.d.ts.map +1 -0
  96. package/dist/repos/files.js +86 -0
  97. package/dist/repos/files.js.map +1 -0
  98. package/dist/repos/imports.d.ts +71 -0
  99. package/dist/repos/imports.d.ts.map +1 -0
  100. package/dist/repos/imports.js +111 -0
  101. package/dist/repos/imports.js.map +1 -0
  102. package/dist/repos/index.d.ts +26 -0
  103. package/dist/repos/index.d.ts.map +1 -0
  104. package/dist/repos/index.js +26 -0
  105. package/dist/repos/index.js.map +1 -0
  106. package/dist/repos/jobs.d.ts +71 -0
  107. package/dist/repos/jobs.d.ts.map +1 -0
  108. package/dist/repos/jobs.js +187 -0
  109. package/dist/repos/jobs.js.map +1 -0
  110. package/dist/repos/llm-overrides.d.ts +89 -0
  111. package/dist/repos/llm-overrides.d.ts.map +1 -0
  112. package/dist/repos/llm-overrides.js +205 -0
  113. package/dist/repos/llm-overrides.js.map +1 -0
  114. package/dist/repos/llm-runs.d.ts +114 -0
  115. package/dist/repos/llm-runs.d.ts.map +1 -0
  116. package/dist/repos/llm-runs.js +214 -0
  117. package/dist/repos/llm-runs.js.map +1 -0
  118. package/dist/repos/notification-prefs.d.ts +34 -0
  119. package/dist/repos/notification-prefs.d.ts.map +1 -0
  120. package/dist/repos/notification-prefs.js +80 -0
  121. package/dist/repos/notification-prefs.js.map +1 -0
  122. package/dist/repos/notifications.d.ts +60 -0
  123. package/dist/repos/notifications.d.ts.map +1 -0
  124. package/dist/repos/notifications.js +107 -0
  125. package/dist/repos/notifications.js.map +1 -0
  126. package/dist/repos/overrides.d.ts +59 -0
  127. package/dist/repos/overrides.d.ts.map +1 -0
  128. package/dist/repos/overrides.js +143 -0
  129. package/dist/repos/overrides.js.map +1 -0
  130. package/dist/repos/pages.d.ts +192 -0
  131. package/dist/repos/pages.d.ts.map +1 -0
  132. package/dist/repos/pages.js +374 -0
  133. package/dist/repos/pages.js.map +1 -0
  134. package/dist/repos/password-resets.d.ts +32 -0
  135. package/dist/repos/password-resets.d.ts.map +1 -0
  136. package/dist/repos/password-resets.js +56 -0
  137. package/dist/repos/password-resets.js.map +1 -0
  138. package/dist/repos/permissions.d.ts +28 -0
  139. package/dist/repos/permissions.d.ts.map +1 -0
  140. package/dist/repos/permissions.js +100 -0
  141. package/dist/repos/permissions.js.map +1 -0
  142. package/dist/repos/roles.d.ts +33 -0
  143. package/dist/repos/roles.d.ts.map +1 -0
  144. package/dist/repos/roles.js +89 -0
  145. package/dist/repos/roles.js.map +1 -0
  146. package/dist/repos/scheduled-reports.d.ts +73 -0
  147. package/dist/repos/scheduled-reports.d.ts.map +1 -0
  148. package/dist/repos/scheduled-reports.js +132 -0
  149. package/dist/repos/scheduled-reports.js.map +1 -0
  150. package/dist/repos/sessions.d.ts +33 -0
  151. package/dist/repos/sessions.d.ts.map +1 -0
  152. package/dist/repos/sessions.js +79 -0
  153. package/dist/repos/sessions.js.map +1 -0
  154. package/dist/repos/settings.d.ts +25 -0
  155. package/dist/repos/settings.d.ts.map +1 -0
  156. package/dist/repos/settings.js +73 -0
  157. package/dist/repos/settings.js.map +1 -0
  158. package/dist/repos/snapshots.d.ts +79 -0
  159. package/dist/repos/snapshots.d.ts.map +1 -0
  160. package/dist/repos/snapshots.js +191 -0
  161. package/dist/repos/snapshots.js.map +1 -0
  162. package/dist/repos/user-prefs.d.ts +56 -0
  163. package/dist/repos/user-prefs.d.ts.map +1 -0
  164. package/dist/repos/user-prefs.js +147 -0
  165. package/dist/repos/user-prefs.js.map +1 -0
  166. package/dist/repos/users.d.ts +38 -0
  167. package/dist/repos/users.d.ts.map +1 -0
  168. package/dist/repos/users.js +103 -0
  169. package/dist/repos/users.js.map +1 -0
  170. package/dist/repos/util.d.ts +45 -0
  171. package/dist/repos/util.d.ts.map +1 -0
  172. package/dist/repos/util.js +81 -0
  173. package/dist/repos/util.js.map +1 -0
  174. package/dist/repos/views.d.ts +75 -0
  175. package/dist/repos/views.d.ts.map +1 -0
  176. package/dist/repos/views.js +180 -0
  177. package/dist/repos/views.js.map +1 -0
  178. package/dist/schema/index.d.ts +4 -0
  179. package/dist/schema/index.d.ts.map +1 -0
  180. package/dist/schema/index.js +4 -0
  181. package/dist/schema/index.js.map +1 -0
  182. package/dist/schema/json-payloads.d.ts +479 -0
  183. package/dist/schema/json-payloads.d.ts.map +1 -0
  184. package/dist/schema/json-payloads.js +340 -0
  185. package/dist/schema/json-payloads.js.map +1 -0
  186. package/dist/schema/settings-registry.d.ts +187 -0
  187. package/dist/schema/settings-registry.d.ts.map +1 -0
  188. package/dist/schema/settings-registry.js +183 -0
  189. package/dist/schema/settings-registry.js.map +1 -0
  190. package/dist/schema/tables.d.ts +568 -0
  191. package/dist/schema/tables.d.ts.map +1 -0
  192. package/dist/schema/tables.js +51 -0
  193. package/dist/schema/tables.js.map +1 -0
  194. package/package.json +33 -0
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Wave 0008 — LLM apply overrides (06-llm-assist.md §8.3, T10b).
3
+ *
4
+ * The apply-EXECUTOR persists each accepted suggestion as an
5
+ * `adminium_schema_overrides` row (`origin: 'llm'`, `llm_run_id`) whose §8.3
6
+ * shape also carries a per-suggestion `confidence`. The base table (0003) has no
7
+ * confidence column, so this migration ADDS one (never edits a shipped
8
+ * migration).
9
+ *
10
+ * The column is NULLABLE and additive: existing user-remap rows keep `confidence
11
+ * = NULL` (a human edit has no model confidence), and `overridesRepo` — which
12
+ * omits the column on insert — is unaffected. `real` is portable (PG real /
13
+ * MySQL real≡double / SQLite REAL) and stores a 0..1 score with room to spare.
14
+ */
15
+ import { type Kysely } from 'kysely';
16
+ /** No {@link ColumnHelpers} needed — `real` is portable and added via raw SQL. */
17
+ export declare function up(db: Kysely<unknown>): Promise<void>;
18
+ //# sourceMappingURL=0008_llm_overrides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0008_llm_overrides.d.ts","sourceRoot":"","sources":["../../src/migrations/0008_llm_overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAI1C,kFAAkF;AAClF,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAK3D"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Wave 0008 — LLM apply overrides (06-llm-assist.md §8.3, T10b).
3
+ *
4
+ * The apply-EXECUTOR persists each accepted suggestion as an
5
+ * `adminium_schema_overrides` row (`origin: 'llm'`, `llm_run_id`) whose §8.3
6
+ * shape also carries a per-suggestion `confidence`. The base table (0003) has no
7
+ * confidence column, so this migration ADDS one (never edits a shipped
8
+ * migration).
9
+ *
10
+ * The column is NULLABLE and additive: existing user-remap rows keep `confidence
11
+ * = NULL` (a human edit has no model confidence), and `overridesRepo` — which
12
+ * omits the column on insert — is unaffected. `real` is portable (PG real /
13
+ * MySQL real≡double / SQLite REAL) and stores a 0..1 score with room to spare.
14
+ */
15
+ import { sql } from 'kysely';
16
+ import { metaTable } from '../prefix.js';
17
+ /** No {@link ColumnHelpers} needed — `real` is portable and added via raw SQL. */
18
+ export async function up(db) {
19
+ await db.schema
20
+ .alterTable(metaTable('schema_overrides'))
21
+ .addColumn('confidence', sql `real`)
22
+ .execute();
23
+ }
24
+ //# sourceMappingURL=0008_llm_overrides.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0008_llm_overrides.js","sourceRoot":"","sources":["../../src/migrations/0008_llm_overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,GAAG,EAAe,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB;IAC1C,MAAM,EAAE,CAAC,MAAM;SACZ,UAAU,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC;SACzC,SAAS,CAAC,YAAY,EAAE,GAAG,CAAA,MAAM,CAAC;SAClC,OAAO,EAAE,CAAC;AACf,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Wave 0009 — `adminium_views.kind` (04-widget-registry.md §6.3, 07-meta-store.md
3
+ * §3.18).
4
+ *
5
+ * A saved-views row now carries a `kind` discriminator: `'filters'` (the M5
6
+ * saved page-crud grid state) or `'layout'` (a per-user dashboard layout
7
+ * override — the "Reset layout" surface). The base table (0004) predates the
8
+ * layout track, so this migration ADDS the column (never edits a shipped
9
+ * migration).
10
+ *
11
+ * The column is NOT NULL with `DEFAULT 'filters'`: every existing row is a
12
+ * saved filter view, so the backfill is correct and `viewsRepo` inserts stay
13
+ * unaffected (they pass `kind` explicitly, defaulting to `'filters'`). The
14
+ * `(page_id, user_id, name)` uniqueness index still holds — layout rows use a
15
+ * reserved sentinel name, so at most one layout override exists per (page,user).
16
+ */
17
+ import type { Kysely } from 'kysely';
18
+ import type { ColumnHelpers } from '../columns.js';
19
+ export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
20
+ //# sourceMappingURL=0009_views_kind.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0009_views_kind.d.ts","sourceRoot":"","sources":["../../src/migrations/0009_views_kind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7E"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Wave 0009 — `adminium_views.kind` (04-widget-registry.md §6.3, 07-meta-store.md
3
+ * §3.18).
4
+ *
5
+ * A saved-views row now carries a `kind` discriminator: `'filters'` (the M5
6
+ * saved page-crud grid state) or `'layout'` (a per-user dashboard layout
7
+ * override — the "Reset layout" surface). The base table (0004) predates the
8
+ * layout track, so this migration ADDS the column (never edits a shipped
9
+ * migration).
10
+ *
11
+ * The column is NOT NULL with `DEFAULT 'filters'`: every existing row is a
12
+ * saved filter view, so the backfill is correct and `viewsRepo` inserts stay
13
+ * unaffected (they pass `kind` explicitly, defaulting to `'filters'`). The
14
+ * `(page_id, user_id, name)` uniqueness index still holds — layout rows use a
15
+ * reserved sentinel name, so at most one layout override exists per (page,user).
16
+ */
17
+ import { metaTable } from '../prefix.js';
18
+ export async function up(db, c) {
19
+ await db.schema
20
+ .alterTable(metaTable('views'))
21
+ .addColumn('kind', c.str(12), (col) => col.notNull().defaultTo('filters'))
22
+ .execute();
23
+ }
24
+ //# sourceMappingURL=0009_views_kind.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0009_views_kind.js","sourceRoot":"","sources":["../../src/migrations/0009_views_kind.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB,EAAE,CAAgB;IAC5D,MAAM,EAAE,CAAC,MAAM;SACZ,UAAU,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;SAC9B,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;SACzE,OAAO,EAAE,CAAC;AACf,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Wave 0010 — widen `adminium_llm_runs.prompt_version` (str(10) → str(40)).
3
+ *
4
+ * 0006 sized the column for a bare version tag, but the shipped prompt version
5
+ * is `adminium.prompt/v1` (@adminium/llm `PROMPT_VERSION`, 18 chars). SQLite
6
+ * masked the mismatch — `str(n)` maps to `text` there, lengths unenforced —
7
+ * while PostgreSQL and strict-mode MySQL reject every run insert with
8
+ * "value too long for type character varying(10)". 40 leaves headroom for
9
+ * future `adminium.prompt/vNN`-style tags.
10
+ *
11
+ * Up-only rule (index.ts): 0006 is applied and checksummed, so the fix ships
12
+ * as a compensating migration. Raw dialect-branched ALTERs because MySQL's
13
+ * MODIFY restates the whole column definition (NOT NULL must be repeated) and
14
+ * Kysely's `setDataType` would silently drop it; SQLite needs no ALTER at all.
15
+ */
16
+ import { type Kysely } from 'kysely';
17
+ import type { ColumnHelpers } from '../columns.js';
18
+ export declare function up(db: Kysely<unknown>, c: ColumnHelpers): Promise<void>;
19
+ //# sourceMappingURL=0010_llm_prompt_version_width.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0010_llm_prompt_version_width.d.ts","sourceRoot":"","sources":["../../src/migrations/0010_llm_prompt_version_width.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,wBAAsB,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAY7E"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Wave 0010 — widen `adminium_llm_runs.prompt_version` (str(10) → str(40)).
3
+ *
4
+ * 0006 sized the column for a bare version tag, but the shipped prompt version
5
+ * is `adminium.prompt/v1` (@adminium/llm `PROMPT_VERSION`, 18 chars). SQLite
6
+ * masked the mismatch — `str(n)` maps to `text` there, lengths unenforced —
7
+ * while PostgreSQL and strict-mode MySQL reject every run insert with
8
+ * "value too long for type character varying(10)". 40 leaves headroom for
9
+ * future `adminium.prompt/vNN`-style tags.
10
+ *
11
+ * Up-only rule (index.ts): 0006 is applied and checksummed, so the fix ships
12
+ * as a compensating migration. Raw dialect-branched ALTERs because MySQL's
13
+ * MODIFY restates the whole column definition (NOT NULL must be repeated) and
14
+ * Kysely's `setDataType` would silently drop it; SQLite needs no ALTER at all.
15
+ */
16
+ import { sql } from 'kysely';
17
+ import { metaTable } from '../prefix.js';
18
+ export async function up(db, c) {
19
+ const table = metaTable('llm_runs');
20
+ if (c.dialect === 'postgres') {
21
+ await sql `ALTER TABLE ${sql.table(table)} ALTER COLUMN prompt_version TYPE varchar(40)`.execute(db);
22
+ }
23
+ else if (c.dialect === 'mysql') {
24
+ await sql `ALTER TABLE ${sql.table(table)} MODIFY COLUMN prompt_version varchar(40) NOT NULL`.execute(db);
25
+ }
26
+ // sqlite: the column is `text`; nothing to widen.
27
+ }
28
+ //# sourceMappingURL=0010_llm_prompt_version_width.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0010_llm_prompt_version_width.js","sourceRoot":"","sources":["../../src/migrations/0010_llm_prompt_version_width.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,GAAG,EAAe,MAAM,QAAQ,CAAC;AAG1C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,MAAM,CAAC,KAAK,UAAU,EAAE,CAAC,EAAmB,EAAE,CAAgB;IAC5D,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,CAAC,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAC7B,MAAM,GAAG,CAAA,eAAe,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,+CAA+C,CAAC,OAAO,CAC7F,EAAE,CACH,CAAC;IACJ,CAAC;SAAM,IAAI,CAAC,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,GAAG,CAAA,eAAe,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,oDAAoD,CAAC,OAAO,CAClG,EAAE,CACH,CAAC;IACJ,CAAC;IACD,kDAAkD;AACpD,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Ordered, append-only migration list (07-meta-store.md §4). Up-only: a
3
+ * mistake ships as a new compensating migration; an applied migration is never
4
+ * edited (enforced by the runner's checksum drift detection).
5
+ *
6
+ * MySQL DDL constraint: `CREATE INDEX IF NOT EXISTS` does not exist on MySQL
7
+ * (tables: fine; indexes: parse error), so index creation here carries no
8
+ * `.ifNotExists()` — the ledger's exactly-once guarantee is the idempotency
9
+ * mechanism, and a rerun after a mid-migration crash failing loudly on a
10
+ * duplicate index beats silently diverging. DECISION (2026-07-20,
11
+ * pre-release): stripping those 29 index guards changed 0001–0007's checksums.
12
+ * Acceptable exactly once — no release exists, a MySQL meta store could never
13
+ * have migrated at all (this parse error, first caught by CI's first-ever
14
+ * [mysql] meta leg), and dev stores re-init. The same 2026-07-20 window also
15
+ * converted 0001–0006's 47 column-level REFERENCES clauses — which MySQL
16
+ * parses and silently discards, leaving a MySQL meta store with zero
17
+ * referential integrity — to named table-level `fk_adminium_*` constraints.
18
+ * After v1.0, checksum-changing edits are forbidden; ship compensating
19
+ * migrations instead.
20
+ */
21
+ import type { Kysely } from 'kysely';
22
+ import type { ColumnHelpers } from '../columns.js';
23
+ export interface MetaMigration {
24
+ /** Basename, e.g. `0001_core_auth` — the ledger PK. */
25
+ readonly name: string;
26
+ readonly up: (db: Kysely<unknown>, c: ColumnHelpers) => Promise<void>;
27
+ }
28
+ export declare const ALL_MIGRATIONS: readonly MetaMigration[];
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAYnD,MAAM,WAAW,aAAa;IAC5B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,aAAa,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvE;AAED,eAAO,MAAM,cAAc,EAAE,SAAS,aAAa,EAWlD,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Ordered, append-only migration list (07-meta-store.md §4). Up-only: a
3
+ * mistake ships as a new compensating migration; an applied migration is never
4
+ * edited (enforced by the runner's checksum drift detection).
5
+ *
6
+ * MySQL DDL constraint: `CREATE INDEX IF NOT EXISTS` does not exist on MySQL
7
+ * (tables: fine; indexes: parse error), so index creation here carries no
8
+ * `.ifNotExists()` — the ledger's exactly-once guarantee is the idempotency
9
+ * mechanism, and a rerun after a mid-migration crash failing loudly on a
10
+ * duplicate index beats silently diverging. DECISION (2026-07-20,
11
+ * pre-release): stripping those 29 index guards changed 0001–0007's checksums.
12
+ * Acceptable exactly once — no release exists, a MySQL meta store could never
13
+ * have migrated at all (this parse error, first caught by CI's first-ever
14
+ * [mysql] meta leg), and dev stores re-init. The same 2026-07-20 window also
15
+ * converted 0001–0006's 47 column-level REFERENCES clauses — which MySQL
16
+ * parses and silently discards, leaving a MySQL meta store with zero
17
+ * referential integrity — to named table-level `fk_adminium_*` constraints.
18
+ * After v1.0, checksum-changing edits are forbidden; ship compensating
19
+ * migrations instead.
20
+ */
21
+ import { up as up0001 } from './0001_core_auth.js';
22
+ import { up as up0002 } from './0002_rbac.js';
23
+ import { up as up0003 } from './0003_connections_schema.js';
24
+ import { up as up0004 } from './0004_pages_views.js';
25
+ import { up as up0005 } from './0005_ops.js';
26
+ import { up as up0006 } from './0006_platform.js';
27
+ import { up as up0007 } from './0007_llm_runs.js';
28
+ import { up as up0008 } from './0008_llm_overrides.js';
29
+ import { up as up0009 } from './0009_views_kind.js';
30
+ import { up as up0010 } from './0010_llm_prompt_version_width.js';
31
+ export const ALL_MIGRATIONS = [
32
+ { name: '0001_core_auth', up: up0001 },
33
+ { name: '0002_rbac', up: up0002 },
34
+ { name: '0003_connections_schema', up: up0003 },
35
+ { name: '0004_pages_views', up: up0004 },
36
+ { name: '0005_ops', up: up0005 },
37
+ { name: '0006_platform', up: up0006 },
38
+ { name: '0007_llm_runs', up: up0007 },
39
+ { name: '0008_llm_overrides', up: up0008 },
40
+ { name: '0009_views_kind', up: up0009 },
41
+ { name: '0010_llm_prompt_version_width', up: up0010 },
42
+ ];
43
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,oCAAoC,CAAC;AAQlE,MAAM,CAAC,MAAM,cAAc,GAA6B;IACtD,EAAE,IAAI,EAAE,gBAAgB,EAAE,EAAE,EAAE,MAAM,EAAE;IACtC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE;IACjC,EAAE,IAAI,EAAE,yBAAyB,EAAE,EAAE,EAAE,MAAM,EAAE;IAC/C,EAAE,IAAI,EAAE,kBAAkB,EAAE,EAAE,EAAE,MAAM,EAAE;IACxC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE;IAChC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,EAAE;IACrC,EAAE,IAAI,EAAE,oBAAoB,EAAE,EAAE,EAAE,MAAM,EAAE;IAC1C,EAAE,IAAI,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,EAAE;IACvC,EAAE,IAAI,EAAE,+BAA+B,EAAE,EAAE,EAAE,MAAM,EAAE;CACtD,CAAC"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Adminium-owned migration runner (07-meta-store.md §4).
3
+ *
4
+ * - Up-only, append-only, sequential migrations (src/migrations/).
5
+ * - `adminium_migrations` ledger (name PK, checksum, applied_at, duration_ms,
6
+ * adminium_version) — created with CREATE TABLE IF NOT EXISTS, the only DDL
7
+ * outside migration files.
8
+ * - Checksum drift detection: an applied migration whose contents changed
9
+ * aborts with the migration name and remedy.
10
+ * - Unknown ledger rows (database migrated by a newer Adminium) abort with an
11
+ * upgrade message.
12
+ * - Transactional per migration on PostgreSQL/SQLite (transactional DDL); on
13
+ * MySQL the ledger row is written immediately after the last statement and
14
+ * every DDL statement is individually re-runnable (ifNotExists guards).
15
+ */
16
+ import { type Kysely } from 'kysely';
17
+ import { type MetaDialect } from './columns.js';
18
+ import { type MetaMigration } from './migrations/index.js';
19
+ import type { MetaDB } from './schema/tables.js';
20
+ /**
21
+ * Package version recorded in the ledger, read from package.json at module
22
+ * load — the same trick `apps/server/src/version.ts` uses, and for the same
23
+ * reason: the relative hop works from both `src/` (vitest/tsx) and `dist/`
24
+ * (compiled) because both sit one level below the package root.
25
+ *
26
+ * It was a hardcoded `'0.0.0'`, which meant `adminium_migrations.adminium_version`
27
+ * — the column whose whole job is telling support which build touched a meta
28
+ * store — recorded a version that never shipped. Neither production caller
29
+ * passes `version`, so the literal was what every row got.
30
+ */
31
+ export declare const META_PACKAGE_VERSION: string;
32
+ export declare class MigrationChecksumDriftError extends Error {
33
+ readonly migrationName: string;
34
+ name: string;
35
+ constructor(migrationName: string);
36
+ }
37
+ export declare class UnknownMigrationError extends Error {
38
+ readonly migrationName: string;
39
+ name: string;
40
+ constructor(migrationName: string);
41
+ }
42
+ export declare class MigrationOrderError extends Error {
43
+ name: string;
44
+ }
45
+ /**
46
+ * SHA-256 over the migration name + its compiled `up` body. Editing an applied
47
+ * migration changes the digest, tripping drift detection on the next boot.
48
+ */
49
+ export declare function migrationChecksum(migration: MetaMigration): string;
50
+ export interface MigratorOptions {
51
+ dialect: MetaDialect;
52
+ /** Override the built-in list — tests only. */
53
+ migrations?: readonly MetaMigration[];
54
+ /** Version stamped into the ledger; defaults to {@link META_PACKAGE_VERSION}. */
55
+ version?: string;
56
+ /** Clock override — tests only. */
57
+ now?: () => number;
58
+ }
59
+ export interface ApplyResult {
60
+ /** Names applied by this call, in order (empty ⇒ already up to date). */
61
+ applied: string[];
62
+ }
63
+ export interface MigrationStatusEntry {
64
+ name: string;
65
+ applied: boolean;
66
+ appliedAt: number | null;
67
+ /** True when the ledger checksum no longer matches the file. */
68
+ drift: boolean;
69
+ /** False for ledger rows this Adminium version does not know. */
70
+ known: boolean;
71
+ }
72
+ /** SQLite enforces FKs per connection; must run before any FK-dependent work (§2.2). */
73
+ export declare function enableSqliteForeignKeys(db: Kysely<MetaDB>): Promise<void>;
74
+ /**
75
+ * Apply all pending migrations, in order. Idempotent: already-applied
76
+ * migrations are skipped via the ledger; concurrent runners racing on the same
77
+ * migration collide on the ledger PK inside the transaction (PG/SQLite), so
78
+ * each migration is applied exactly once.
79
+ */
80
+ export declare function applyMigrations(db: Kysely<MetaDB>, options: MigratorOptions): Promise<ApplyResult>;
81
+ /** Ledger vs file status for `adminium migrate --status`. */
82
+ export declare function migrationStatus(db: Kysely<MetaDB>, options: MigratorOptions): Promise<MigrationStatusEntry[]>;
83
+ //# sourceMappingURL=migrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,MAI1B,CAAC;AAIV,qBAAa,2BAA4B,SAAQ,KAAK;IAExC,QAAQ,CAAC,aAAa,EAAE,MAAM;IADjC,IAAI,SAAiC;gBACzB,aAAa,EAAE,MAAM;CAM3C;AAED,qBAAa,qBAAsB,SAAQ,KAAK;IAElC,QAAQ,CAAC,aAAa,EAAE,MAAM;IADjC,IAAI,SAA2B;gBACnB,aAAa,EAAE,MAAM;CAM3C;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IACnC,IAAI,SAAyB;CACvC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,aAAa,GAAG,MAAM,CAElE;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,WAAW,CAAC;IACrB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;IACtC,iFAAiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gEAAgE;IAChE,KAAK,EAAE,OAAO,CAAC;IACf,iEAAiE;IACjE,KAAK,EAAE,OAAO,CAAC;CAChB;AA6BD,wFAAwF;AACxF,wBAAsB,uBAAuB,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/E;AAsBD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CAuCxG;AAED,6DAA6D;AAC7D,wBAAsB,eAAe,CACnC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAClB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAuBjC"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Adminium-owned migration runner (07-meta-store.md §4).
3
+ *
4
+ * - Up-only, append-only, sequential migrations (src/migrations/).
5
+ * - `adminium_migrations` ledger (name PK, checksum, applied_at, duration_ms,
6
+ * adminium_version) — created with CREATE TABLE IF NOT EXISTS, the only DDL
7
+ * outside migration files.
8
+ * - Checksum drift detection: an applied migration whose contents changed
9
+ * aborts with the migration name and remedy.
10
+ * - Unknown ledger rows (database migrated by a newer Adminium) abort with an
11
+ * upgrade message.
12
+ * - Transactional per migration on PostgreSQL/SQLite (transactional DDL); on
13
+ * MySQL the ledger row is written immediately after the last statement and
14
+ * every DDL statement is individually re-runnable (ifNotExists guards).
15
+ */
16
+ import { createHash } from 'node:crypto';
17
+ import { readFileSync } from 'node:fs';
18
+ import { sql } from 'kysely';
19
+ import { columnHelpers } from './columns.js';
20
+ import { ALL_MIGRATIONS } from './migrations/index.js';
21
+ /**
22
+ * Package version recorded in the ledger, read from package.json at module
23
+ * load — the same trick `apps/server/src/version.ts` uses, and for the same
24
+ * reason: the relative hop works from both `src/` (vitest/tsx) and `dist/`
25
+ * (compiled) because both sit one level below the package root.
26
+ *
27
+ * It was a hardcoded `'0.0.0'`, which meant `adminium_migrations.adminium_version`
28
+ * — the column whose whole job is telling support which build touched a meta
29
+ * store — recorded a version that never shipped. Neither production caller
30
+ * passes `version`, so the literal was what every row got.
31
+ */
32
+ export const META_PACKAGE_VERSION = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8')).version;
33
+ const LEDGER = 'adminium_migrations';
34
+ export class MigrationChecksumDriftError extends Error {
35
+ migrationName;
36
+ name = 'MigrationChecksumDriftError';
37
+ constructor(migrationName) {
38
+ super(`Migration "${migrationName}" was modified after it was applied to this database. ` +
39
+ 'Restore the original migration file or ship a new compensating migration — applied migrations are never edited.');
40
+ this.migrationName = migrationName;
41
+ }
42
+ }
43
+ export class UnknownMigrationError extends Error {
44
+ migrationName;
45
+ name = 'UnknownMigrationError';
46
+ constructor(migrationName) {
47
+ super(`The migration ledger contains "${migrationName}", which this Adminium version does not know. ` +
48
+ 'This database was migrated by a newer Adminium — upgrade the app.');
49
+ this.migrationName = migrationName;
50
+ }
51
+ }
52
+ export class MigrationOrderError extends Error {
53
+ name = 'MigrationOrderError';
54
+ }
55
+ /**
56
+ * SHA-256 over the migration name + its compiled `up` body. Editing an applied
57
+ * migration changes the digest, tripping drift detection on the next boot.
58
+ */
59
+ export function migrationChecksum(migration) {
60
+ return createHash('sha256').update(`${migration.name}\n${migration.up.toString()}`).digest('hex');
61
+ }
62
+ function orderedMigrations(migrations) {
63
+ const names = new Set();
64
+ let prev = '';
65
+ for (const m of migrations) {
66
+ if (names.has(m.name))
67
+ throw new MigrationOrderError(`duplicate migration name: ${m.name}`);
68
+ if (m.name <= prev) {
69
+ throw new MigrationOrderError(`migrations out of order: "${m.name}" after "${prev}"`);
70
+ }
71
+ names.add(m.name);
72
+ prev = m.name;
73
+ }
74
+ return migrations;
75
+ }
76
+ async function ensureLedger(db, dialect) {
77
+ const c = columnHelpers(dialect);
78
+ await db.schema
79
+ .createTable(LEDGER)
80
+ .ifNotExists()
81
+ .addColumn('name', c.str(120), (col) => col.primaryKey())
82
+ .addColumn('checksum', c.str(64), (col) => col.notNull())
83
+ .addColumn('applied_at', c.ts, (col) => col.notNull())
84
+ .addColumn('duration_ms', c.int, (col) => col.notNull())
85
+ .addColumn('adminium_version', c.str(20), (col) => col.notNull())
86
+ .execute();
87
+ }
88
+ /** SQLite enforces FKs per connection; must run before any FK-dependent work (§2.2). */
89
+ export async function enableSqliteForeignKeys(db) {
90
+ await sql `PRAGMA foreign_keys = ON`.execute(db);
91
+ }
92
+ async function readAndValidateLedger(db, migrations) {
93
+ const rows = await db.selectFrom(LEDGER).selectAll().execute();
94
+ const byName = new Map(migrations.map((m) => [m.name, m]));
95
+ for (const row of rows) {
96
+ const migration = byName.get(row.name);
97
+ if (!migration)
98
+ throw new UnknownMigrationError(row.name);
99
+ if (migrationChecksum(migration) !== row.checksum) {
100
+ throw new MigrationChecksumDriftError(row.name);
101
+ }
102
+ }
103
+ return { appliedNames: new Set(rows.map((r) => r.name)) };
104
+ }
105
+ /**
106
+ * Apply all pending migrations, in order. Idempotent: already-applied
107
+ * migrations are skipped via the ledger; concurrent runners racing on the same
108
+ * migration collide on the ledger PK inside the transaction (PG/SQLite), so
109
+ * each migration is applied exactly once.
110
+ */
111
+ export async function applyMigrations(db, options) {
112
+ const migrations = orderedMigrations(options.migrations ?? ALL_MIGRATIONS);
113
+ const now = options.now ?? Date.now;
114
+ const version = options.version ?? META_PACKAGE_VERSION;
115
+ const dialect = options.dialect;
116
+ if (dialect === 'sqlite')
117
+ await enableSqliteForeignKeys(db);
118
+ await ensureLedger(db, dialect);
119
+ const { appliedNames } = await readAndValidateLedger(db, migrations);
120
+ const c = columnHelpers(dialect);
121
+ const applied = [];
122
+ for (const migration of migrations) {
123
+ if (appliedNames.has(migration.name))
124
+ continue;
125
+ const startedAt = now();
126
+ const ledgerRow = () => ({
127
+ name: migration.name,
128
+ checksum: migrationChecksum(migration),
129
+ appliedAt: now(),
130
+ durationMs: Math.max(0, now() - startedAt),
131
+ adminiumVersion: version,
132
+ });
133
+ if (dialect === 'mysql') {
134
+ // No transactional DDL: statements are individually re-runnable
135
+ // (ifNotExists), and the ledger row lands right after the last one.
136
+ await migration.up(db, c);
137
+ await db.insertInto(LEDGER).values(ledgerRow()).execute();
138
+ }
139
+ else {
140
+ await db.transaction().execute(async (trx) => {
141
+ await migration.up(trx, c);
142
+ await trx.insertInto(LEDGER).values(ledgerRow()).execute();
143
+ });
144
+ }
145
+ applied.push(migration.name);
146
+ }
147
+ return { applied };
148
+ }
149
+ /** Ledger vs file status for `adminium migrate --status`. */
150
+ export async function migrationStatus(db, options) {
151
+ const migrations = orderedMigrations(options.migrations ?? ALL_MIGRATIONS);
152
+ await ensureLedger(db, options.dialect);
153
+ const rows = await db.selectFrom(LEDGER).selectAll().execute();
154
+ const ledger = new Map(rows.map((r) => [r.name, r]));
155
+ const known = new Set(migrations.map((m) => m.name));
156
+ const entries = migrations.map((m) => {
157
+ const row = ledger.get(m.name);
158
+ return {
159
+ name: m.name,
160
+ applied: row !== undefined,
161
+ appliedAt: row?.appliedAt ?? null,
162
+ drift: row !== undefined && migrationChecksum(m) !== row.checksum,
163
+ known: true,
164
+ };
165
+ });
166
+ for (const row of rows) {
167
+ if (!known.has(row.name)) {
168
+ entries.push({ name: row.name, applied: true, appliedAt: row.appliedAt, drift: false, known: false });
169
+ }
170
+ }
171
+ return entries;
172
+ }
173
+ //# sourceMappingURL=migrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Table-name prefix guard (07-meta-store.md §1, §4 "prefix safety").
3
+ * All DDL and the migration runner go through {@link metaTable}, which asserts
4
+ * the final physical name carries the `adminium_` prefix — the runner refuses
5
+ * to touch any other table.
6
+ */
7
+ export declare const META_PREFIX = "adminium_";
8
+ export declare class MetaPrefixError extends Error {
9
+ name: string;
10
+ }
11
+ /**
12
+ * `metaTable('users')` → `'adminium_users'`.
13
+ * Rejects names that already carry the prefix (double-prefix bug) and names
14
+ * that would not resolve inside the adminium_ namespace.
15
+ */
16
+ export declare function metaTable(name: string): string;
17
+ /** Assert an already-qualified physical name lives in the adminium_ namespace. */
18
+ export declare function assertMetaTable(name: string): void;
19
+ //# sourceMappingURL=prefix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefix.d.ts","sourceRoot":"","sources":["../src/prefix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,WAAW,cAAc,CAAC;AAEvC,qBAAa,eAAgB,SAAQ,KAAK;IAC/B,IAAI,SAAqB;CACnC;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU9C;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAIlD"}
package/dist/prefix.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Table-name prefix guard (07-meta-store.md §1, §4 "prefix safety").
3
+ * All DDL and the migration runner go through {@link metaTable}, which asserts
4
+ * the final physical name carries the `adminium_` prefix — the runner refuses
5
+ * to touch any other table.
6
+ */
7
+ export const META_PREFIX = 'adminium_';
8
+ export class MetaPrefixError extends Error {
9
+ name = 'MetaPrefixError';
10
+ }
11
+ /**
12
+ * `metaTable('users')` → `'adminium_users'`.
13
+ * Rejects names that already carry the prefix (double-prefix bug) and names
14
+ * that would not resolve inside the adminium_ namespace.
15
+ */
16
+ export function metaTable(name) {
17
+ if (!/^[a-z][a-z0-9_]*$/.test(name)) {
18
+ throw new MetaPrefixError(`invalid meta table name: ${JSON.stringify(name)}`);
19
+ }
20
+ if (name.startsWith(META_PREFIX)) {
21
+ throw new MetaPrefixError(`table name already prefixed: ${name}`);
22
+ }
23
+ const full = `${META_PREFIX}${name}`;
24
+ assertMetaTable(full);
25
+ return full;
26
+ }
27
+ /** Assert an already-qualified physical name lives in the adminium_ namespace. */
28
+ export function assertMetaTable(name) {
29
+ if (!name.startsWith(META_PREFIX)) {
30
+ throw new MetaPrefixError(`refusing to touch non-adminium table: ${name}`);
31
+ }
32
+ }
33
+ //# sourceMappingURL=prefix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefix.js","sourceRoot":"","sources":["../src/prefix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,CAAC;AAEvC,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAC/B,IAAI,GAAG,iBAAiB,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,eAAe,CAAC,4BAA4B,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,eAAe,CAAC,gCAAgC,IAAI,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,IAAI,GAAG,GAAG,WAAW,GAAG,IAAI,EAAE,CAAC;IACrC,eAAe,CAAC,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kFAAkF;AAClF,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,eAAe,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * apiKeysRepo — adminium_api_keys (07-meta-store.md §3.7).
3
+ * Stripe-style `adm_live_…`: the secret is shown once by the server; only the
4
+ * SHA-256 hash lands here. The key acts with its role's permissions.
5
+ */
6
+ import type { Selectable } from 'kysely';
7
+ import type { MetaDb } from '../connect.js';
8
+ import type { AdminiumApiKeysTable } from '../schema/tables.js';
9
+ export type ApiKey = Selectable<AdminiumApiKeysTable>;
10
+ export interface CreateApiKeyInput {
11
+ name: string;
12
+ /** Display fragment, e.g. `adm_live_4f2…`. */
13
+ prefix: string;
14
+ tokenHash: string;
15
+ roleId: string;
16
+ createdBy?: string | null;
17
+ expiresAt?: number | null;
18
+ }
19
+ export declare function apiKeysRepo(meta: MetaDb): {
20
+ create(input: CreateApiKeyInput, at?: number): Promise<ApiKey>;
21
+ findByPrefix(prefix: string): Promise<ApiKey[]>;
22
+ findById(id: string): Promise<ApiKey | null>;
23
+ /** Auth lookup: un-revoked and unexpired at `at`. */
24
+ findValidByTokenHash(tokenHash: string, at?: number): Promise<ApiKey | null>;
25
+ list(): Promise<ApiKey[]>;
26
+ revoke(id: string, at?: number): Promise<boolean>;
27
+ /** Throttled by the caller (server) like session touches. */
28
+ touchLastUsed(id: string, at?: number): Promise<void>;
29
+ };
30
+ export type ApiKeysRepo = ReturnType<typeof apiKeysRepo>;
31
+ //# sourceMappingURL=api-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../../src/repos/api-keys.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEzC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAEhE,MAAM,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,CAAC;AAEtD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM;kBAGhB,iBAAiB,OAAM,MAAM,GAAgB,OAAO,CAAC,MAAM,CAAC;yBAiBrD,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;iBAIlC,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAKlD,qDAAqD;oCACf,MAAM,OAAM,MAAM,GAAgB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;YAWhF,OAAO,CAAC,MAAM,EAAE,CAAC;eAId,MAAM,OAAM,MAAM,GAAgB,OAAO,CAAC,OAAO,CAAC;IAUnE,6DAA6D;sBACrC,MAAM,OAAM,MAAM,GAAgB,OAAO,CAAC,IAAI,CAAC;EAI1E;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC"}