@adminiumjs/meta 0.2.1 → 0.2.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 (193) hide show
  1. package/dist/bootstrap.d.ts +10 -2
  2. package/dist/bootstrap.d.ts.map +1 -1
  3. package/dist/bootstrap.js +12 -3
  4. package/dist/bootstrap.js.map +1 -1
  5. package/dist/columns.d.ts.map +1 -1
  6. package/dist/columns.js +1 -0
  7. package/dist/columns.js.map +1 -1
  8. package/dist/connect.d.ts.map +1 -1
  9. package/dist/connect.js +1 -0
  10. package/dist/connect.js.map +1 -1
  11. package/dist/ids.d.ts +4 -0
  12. package/dist/ids.d.ts.map +1 -1
  13. package/dist/ids.js +8 -0
  14. package/dist/ids.js.map +1 -1
  15. package/dist/index.d.ts +2 -0
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +3 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/migrate-lock.d.ts +104 -0
  20. package/dist/migrate-lock.d.ts.map +1 -0
  21. package/dist/migrate-lock.js +197 -0
  22. package/dist/migrate-lock.js.map +1 -0
  23. package/dist/migrations/0001_core_auth.d.ts.map +1 -1
  24. package/dist/migrations/0001_core_auth.js +1 -0
  25. package/dist/migrations/0001_core_auth.js.map +1 -1
  26. package/dist/migrations/0002_rbac.d.ts.map +1 -1
  27. package/dist/migrations/0002_rbac.js +1 -0
  28. package/dist/migrations/0002_rbac.js.map +1 -1
  29. package/dist/migrations/0003_connections_schema.d.ts.map +1 -1
  30. package/dist/migrations/0003_connections_schema.js +1 -0
  31. package/dist/migrations/0003_connections_schema.js.map +1 -1
  32. package/dist/migrations/0004_pages_views.d.ts.map +1 -1
  33. package/dist/migrations/0004_pages_views.js +1 -0
  34. package/dist/migrations/0004_pages_views.js.map +1 -1
  35. package/dist/migrations/0005_ops.d.ts.map +1 -1
  36. package/dist/migrations/0005_ops.js +1 -0
  37. package/dist/migrations/0005_ops.js.map +1 -1
  38. package/dist/migrations/0006_platform.d.ts.map +1 -1
  39. package/dist/migrations/0006_platform.js +1 -0
  40. package/dist/migrations/0006_platform.js.map +1 -1
  41. package/dist/migrations/0007_llm_runs.d.ts.map +1 -1
  42. package/dist/migrations/0007_llm_runs.js +1 -0
  43. package/dist/migrations/0007_llm_runs.js.map +1 -1
  44. package/dist/migrations/0008_llm_overrides.d.ts.map +1 -1
  45. package/dist/migrations/0008_llm_overrides.js +1 -0
  46. package/dist/migrations/0008_llm_overrides.js.map +1 -1
  47. package/dist/migrations/0009_views_kind.d.ts.map +1 -1
  48. package/dist/migrations/0009_views_kind.js +1 -0
  49. package/dist/migrations/0009_views_kind.js.map +1 -1
  50. package/dist/migrations/0010_llm_prompt_version_width.d.ts.map +1 -1
  51. package/dist/migrations/0010_llm_prompt_version_width.js +1 -0
  52. package/dist/migrations/0010_llm_prompt_version_width.js.map +1 -1
  53. package/dist/migrations/0011_i18n_runtime.d.ts.map +1 -1
  54. package/dist/migrations/0011_i18n_runtime.js +1 -0
  55. package/dist/migrations/0011_i18n_runtime.js.map +1 -1
  56. package/dist/migrations/0012_locale_width.d.ts.map +1 -1
  57. package/dist/migrations/0012_locale_width.js +1 -0
  58. package/dist/migrations/0012_locale_width.js.map +1 -1
  59. package/dist/migrations/0013_connection_last_error_hint.d.ts +17 -0
  60. package/dist/migrations/0013_connection_last_error_hint.d.ts.map +1 -0
  61. package/dist/migrations/0013_connection_last_error_hint.js +22 -0
  62. package/dist/migrations/0013_connection_last_error_hint.js.map +1 -0
  63. package/dist/migrations/0014_public_surface.d.ts +40 -0
  64. package/dist/migrations/0014_public_surface.d.ts.map +1 -0
  65. package/dist/migrations/0014_public_surface.js +186 -0
  66. package/dist/migrations/0014_public_surface.js.map +1 -0
  67. package/dist/migrations/index.d.ts.map +1 -1
  68. package/dist/migrations/index.js +5 -0
  69. package/dist/migrations/index.js.map +1 -1
  70. package/dist/migrator.d.ts +22 -3
  71. package/dist/migrator.d.ts.map +1 -1
  72. package/dist/migrator.js +27 -6
  73. package/dist/migrator.js.map +1 -1
  74. package/dist/prefix.d.ts.map +1 -1
  75. package/dist/prefix.js +1 -0
  76. package/dist/prefix.js.map +1 -1
  77. package/dist/relocate.d.ts +118 -0
  78. package/dist/relocate.d.ts.map +1 -0
  79. package/dist/relocate.js +376 -0
  80. package/dist/relocate.js.map +1 -0
  81. package/dist/repos/api-keys.d.ts.map +1 -1
  82. package/dist/repos/api-keys.js +1 -0
  83. package/dist/repos/api-keys.js.map +1 -1
  84. package/dist/repos/audit.d.ts.map +1 -1
  85. package/dist/repos/audit.js +1 -0
  86. package/dist/repos/audit.js.map +1 -1
  87. package/dist/repos/connections.d.ts +5 -0
  88. package/dist/repos/connections.d.ts.map +1 -1
  89. package/dist/repos/connections.js +8 -0
  90. package/dist/repos/connections.js.map +1 -1
  91. package/dist/repos/email-templates.d.ts.map +1 -1
  92. package/dist/repos/email-templates.js +1 -0
  93. package/dist/repos/email-templates.js.map +1 -1
  94. package/dist/repos/exports.d.ts.map +1 -1
  95. package/dist/repos/exports.js +1 -0
  96. package/dist/repos/exports.js.map +1 -1
  97. package/dist/repos/files.d.ts.map +1 -1
  98. package/dist/repos/files.js +1 -0
  99. package/dist/repos/files.js.map +1 -1
  100. package/dist/repos/i18n-version.d.ts.map +1 -1
  101. package/dist/repos/i18n-version.js +1 -0
  102. package/dist/repos/i18n-version.js.map +1 -1
  103. package/dist/repos/imports.d.ts.map +1 -1
  104. package/dist/repos/imports.js +1 -0
  105. package/dist/repos/imports.js.map +1 -1
  106. package/dist/repos/index.d.ts +1 -0
  107. package/dist/repos/index.d.ts.map +1 -1
  108. package/dist/repos/index.js +2 -0
  109. package/dist/repos/index.js.map +1 -1
  110. package/dist/repos/jobs.d.ts.map +1 -1
  111. package/dist/repos/jobs.js +1 -0
  112. package/dist/repos/jobs.js.map +1 -1
  113. package/dist/repos/llm-overrides.d.ts.map +1 -1
  114. package/dist/repos/llm-overrides.js +1 -0
  115. package/dist/repos/llm-overrides.js.map +1 -1
  116. package/dist/repos/llm-runs.d.ts.map +1 -1
  117. package/dist/repos/llm-runs.js +1 -0
  118. package/dist/repos/llm-runs.js.map +1 -1
  119. package/dist/repos/locales.d.ts.map +1 -1
  120. package/dist/repos/locales.js +1 -0
  121. package/dist/repos/locales.js.map +1 -1
  122. package/dist/repos/notification-prefs.d.ts.map +1 -1
  123. package/dist/repos/notification-prefs.js +1 -0
  124. package/dist/repos/notification-prefs.js.map +1 -1
  125. package/dist/repos/notifications.d.ts.map +1 -1
  126. package/dist/repos/notifications.js +1 -0
  127. package/dist/repos/notifications.js.map +1 -1
  128. package/dist/repos/overrides.d.ts.map +1 -1
  129. package/dist/repos/overrides.js +1 -0
  130. package/dist/repos/overrides.js.map +1 -1
  131. package/dist/repos/pages.d.ts +147 -1
  132. package/dist/repos/pages.d.ts.map +1 -1
  133. package/dist/repos/pages.js +318 -23
  134. package/dist/repos/pages.js.map +1 -1
  135. package/dist/repos/password-resets.d.ts.map +1 -1
  136. package/dist/repos/password-resets.js +1 -0
  137. package/dist/repos/password-resets.js.map +1 -1
  138. package/dist/repos/permissions.d.ts +15 -0
  139. package/dist/repos/permissions.d.ts.map +1 -1
  140. package/dist/repos/permissions.js +39 -0
  141. package/dist/repos/permissions.js.map +1 -1
  142. package/dist/repos/public-api.d.ts +116 -0
  143. package/dist/repos/public-api.d.ts.map +1 -0
  144. package/dist/repos/public-api.js +249 -0
  145. package/dist/repos/public-api.js.map +1 -0
  146. package/dist/repos/roles.d.ts.map +1 -1
  147. package/dist/repos/roles.js +1 -0
  148. package/dist/repos/roles.js.map +1 -1
  149. package/dist/repos/scheduled-reports.d.ts.map +1 -1
  150. package/dist/repos/scheduled-reports.js +1 -0
  151. package/dist/repos/scheduled-reports.js.map +1 -1
  152. package/dist/repos/sessions.d.ts +9 -0
  153. package/dist/repos/sessions.d.ts.map +1 -1
  154. package/dist/repos/sessions.js +26 -0
  155. package/dist/repos/sessions.js.map +1 -1
  156. package/dist/repos/settings.d.ts.map +1 -1
  157. package/dist/repos/settings.js +1 -0
  158. package/dist/repos/settings.js.map +1 -1
  159. package/dist/repos/snapshots.d.ts.map +1 -1
  160. package/dist/repos/snapshots.js +1 -0
  161. package/dist/repos/snapshots.js.map +1 -1
  162. package/dist/repos/translations.d.ts.map +1 -1
  163. package/dist/repos/translations.js +1 -0
  164. package/dist/repos/translations.js.map +1 -1
  165. package/dist/repos/user-prefs.d.ts.map +1 -1
  166. package/dist/repos/user-prefs.js +1 -0
  167. package/dist/repos/user-prefs.js.map +1 -1
  168. package/dist/repos/users.d.ts +31 -0
  169. package/dist/repos/users.d.ts.map +1 -1
  170. package/dist/repos/users.js +80 -4
  171. package/dist/repos/users.js.map +1 -1
  172. package/dist/repos/util.d.ts.map +1 -1
  173. package/dist/repos/util.js +1 -0
  174. package/dist/repos/util.js.map +1 -1
  175. package/dist/repos/views.d.ts.map +1 -1
  176. package/dist/repos/views.js +1 -0
  177. package/dist/repos/views.js.map +1 -1
  178. package/dist/schema/index.d.ts.map +1 -1
  179. package/dist/schema/index.js +1 -0
  180. package/dist/schema/index.js.map +1 -1
  181. package/dist/schema/json-payloads.d.ts +2 -1
  182. package/dist/schema/json-payloads.d.ts.map +1 -1
  183. package/dist/schema/json-payloads.js +7 -0
  184. package/dist/schema/json-payloads.js.map +1 -1
  185. package/dist/schema/settings-registry.d.ts +45 -0
  186. package/dist/schema/settings-registry.d.ts.map +1 -1
  187. package/dist/schema/settings-registry.js +60 -0
  188. package/dist/schema/settings-registry.js.map +1 -1
  189. package/dist/schema/tables.d.ts +91 -1
  190. package/dist/schema/tables.d.ts.map +1 -1
  191. package/dist/schema/tables.js +5 -0
  192. package/dist/schema/tables.js.map +1 -1
  193. package/package.json +2 -2
@@ -0,0 +1,186 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ /**
3
+ * Wave 0014 — the public surface (28-public-surface.md §3).
4
+ *
5
+ * Four tables behind the scoped, off-by-default `/api/v1/public` namespace:
6
+ * the browser-safe key kind, the scope document that says what a key may reach,
7
+ * the end-customer session a `claim` mints, and the one-time challenge the
8
+ * `email-code` claim tier needs.
9
+ *
10
+ * WHY THESE ARE NOT `adminium_api_keys` ROWS WITH A `kind` COLUMN (28 §3.3).
11
+ * Two properties diverge and both are load-bearing:
12
+ *
13
+ * 1. The secret is RE-READABLE by an admin. `adminium_api_keys` reveals once
14
+ * and never again, which is right for a server-side credential a human
15
+ * copies into a deployment. An `adm_pub_` secret lives in a public bundle
16
+ * and has to survive a rebuild months later, so the row keeps a reversible
17
+ * copy alongside the hash.
18
+ * 2. A publishable key is NEVER an `RbacPrincipal` (28 D3). `parseBearerApiKey`
19
+ * gates on the `adm_sk_` prefix, so a token from this table cannot resolve
20
+ * through the rbac plugin at all — which is what makes it inert on every
21
+ * other route BY CONSTRUCTION rather than by an allow-list somebody has to
22
+ * maintain. Sharing a table would invite exactly the `kind`-check-per-route
23
+ * that property exists to avoid.
24
+ *
25
+ * NO SETTINGS TABLE HERE, deliberately (28 D20). Tenant configuration is
26
+ * hybrid: the only key Adminium must own is the `timezone` it needs to
27
+ * interpret its own `timestamptz` values, and that rides on the SCOPE document
28
+ * below — already per-connection, already operator-authored, already served on
29
+ * `/public/config`. A global settings key would be one line cheaper and wrong
30
+ * the moment an instance holds two connections for businesses in different
31
+ * zones. Everything else an app needs (tax rates, tip presets, opening hours)
32
+ * stays in the app's own tables, where the generated dashboard edits it for
33
+ * free.
34
+ *
35
+ * `0013_connection_last_error_hint` is the latest applied migration; never edit
36
+ * a shipped one (the one-time checksum exception in `index.ts` was pre-release).
37
+ */
38
+ import { metaTable } from '../prefix.js';
39
+ export async function up(db, c) {
40
+ /*
41
+ * The scope document. One row per (connection, side) the operator publishes.
42
+ *
43
+ * `document` is the compiled-from JSON: resources, their logical refs, the
44
+ * `expose` column allow-list, `filterable`/`searchable`/`orderable`, the
45
+ * mandatory `where` predicate, and the claim strategy. It is validated by
46
+ * `compileScope` on every write and on every boot — never trusted from disk.
47
+ *
48
+ * `timezone` is a COLUMN rather than a field inside `document` because it is
49
+ * the one datum the SERIALIZER needs, not the caller: a reader has to reach it
50
+ * without parsing and validating the whole document first.
51
+ *
52
+ * `proposed_from_manifest` records whether this row was seeded from a
53
+ * manifest's `publicApi.propose` block (O2 option b) or authored from scratch
54
+ * in Studio (option c). It exists so widening past a publisher's proposal can
55
+ * be audited, and it is nullable because option (c) is unblocked today and
56
+ * option (b) is not yet ruled.
57
+ */
58
+ await db.schema
59
+ .createTable(metaTable('public_scopes'))
60
+ .ifNotExists()
61
+ .addColumn('id', c.id, (col) => col.primaryKey())
62
+ .addColumn('connection_id', c.id, (col) => col.notNull())
63
+ .addColumn('side', c.str(16), (col) => col.notNull())
64
+ .addColumn('name', c.str(80), (col) => col.notNull())
65
+ /** IANA zone, e.g. `Europe/London`. Required — see 28 D20. */
66
+ .addColumn('timezone', c.str(64), (col) => col.notNull())
67
+ .addColumn('document', c.json, (col) => col.notNull())
68
+ .addColumn('proposed_from_manifest', c.str(80))
69
+ .addColumn('created_by', c.id)
70
+ .addColumn('created_at', c.ts, (col) => col.notNull())
71
+ .addColumn('updated_at', c.ts, (col) => col.notNull())
72
+ .addForeignKeyConstraint('fk_adminium_public_scopes_connection', ['connection_id'], metaTable('connections'), ['id'], (cb) => cb.onDelete('cascade'))
73
+ .addForeignKeyConstraint('fk_adminium_public_scopes_created_by', ['created_by'], metaTable('users'), ['id'], (cb) => cb.onDelete('set null'))
74
+ .execute();
75
+ await db.schema
76
+ .createIndex('ix_adminium_public_scopes_connection')
77
+ .on(metaTable('public_scopes'))
78
+ .columns(['connection_id'])
79
+ .execute();
80
+ /*
81
+ * The publishable key.
82
+ *
83
+ * `token_hash` is what a request is verified against. `token_encrypted` is the
84
+ * reversible copy that makes the secret re-readable (see the header) — it uses
85
+ * the same `dsnCryptoFromSecret` envelope as connection DSNs, so it is
86
+ * unreadable without `ADMINIUM_SECRET` and it never leaves the server except
87
+ * through an authenticated reveal.
88
+ *
89
+ * `origins` is a JSON array narrowing the instance-wide
90
+ * `ADMINIUM_PUBLIC_API_ORIGINS` allow-list for this one key. Empty array means
91
+ * "no narrowing" — it does NOT mean "any origin", because the env var is
92
+ * always the outer bound.
93
+ *
94
+ * `scope_id` is `restrict` on delete, not `cascade`: deleting a scope out from
95
+ * under a live key would silently turn a working public surface into a 500,
96
+ * so the operator has to revoke the key first and see what they are breaking.
97
+ */
98
+ await db.schema
99
+ .createTable(metaTable('public_keys'))
100
+ .ifNotExists()
101
+ .addColumn('id', c.id, (col) => col.primaryKey())
102
+ .addColumn('name', c.str(80), (col) => col.notNull())
103
+ /** Display fragment, e.g. `adm_pub_4f2a91cd`. */
104
+ .addColumn('prefix', c.str(32), (col) => col.notNull())
105
+ .addColumn('token_hash', c.str(128), (col) => col.notNull())
106
+ .addColumn('token_encrypted', c.text, (col) => col.notNull())
107
+ .addColumn('scope_id', c.id, (col) => col.notNull())
108
+ .addColumn('side', c.str(16), (col) => col.notNull())
109
+ .addColumn('origins', c.json, (col) => col.notNull())
110
+ .addColumn('expires_at', c.ts)
111
+ .addColumn('revoked_at', c.ts)
112
+ .addColumn('last_used_at', c.ts)
113
+ .addColumn('created_by', c.id)
114
+ .addColumn('created_at', c.ts, (col) => col.notNull())
115
+ .addColumn('updated_at', c.ts, (col) => col.notNull())
116
+ .addForeignKeyConstraint('fk_adminium_public_keys_scope', ['scope_id'], metaTable('public_scopes'), ['id'], (cb) => cb.onDelete('restrict'))
117
+ .addForeignKeyConstraint('fk_adminium_public_keys_created_by', ['created_by'], metaTable('users'), ['id'], (cb) => cb.onDelete('set null'))
118
+ .execute();
119
+ /* Lookup is by prefix on every public request — the hot path of this wave. */
120
+ await db.schema
121
+ .createIndex('ix_adminium_public_keys_prefix')
122
+ .on(metaTable('public_keys'))
123
+ .columns(['prefix'])
124
+ .execute();
125
+ /*
126
+ * The end-customer session minted by `POST /public/claim` (28 §3.4).
127
+ *
128
+ * `grants` is the resolved claim — the mandatory predicate later requests are
129
+ * filtered by, e.g. "patient_id = 41". It is stored RESOLVED rather than
130
+ * re-derived per request so that editing a scope cannot retroactively widen a
131
+ * session that is already in someone's browser.
132
+ *
133
+ * There is no `user_id`. An end customer is deliberately NOT an
134
+ * `adminium_users` row (28 §3.4) — Adminium grows no second identity system,
135
+ * and this table is the whole of what a claimed customer is.
136
+ */
137
+ await db.schema
138
+ .createTable(metaTable('public_sessions'))
139
+ .ifNotExists()
140
+ .addColumn('id', c.id, (col) => col.primaryKey())
141
+ .addColumn('key_id', c.id, (col) => col.notNull())
142
+ .addColumn('token_hash', c.str(128), (col) => col.notNull())
143
+ .addColumn('grants', c.json, (col) => col.notNull())
144
+ .addColumn('expires_at', c.ts, (col) => col.notNull())
145
+ .addColumn('created_at', c.ts, (col) => col.notNull())
146
+ .addColumn('last_seen_at', c.ts)
147
+ .addForeignKeyConstraint('fk_adminium_public_sessions_key', ['key_id'], metaTable('public_keys'), ['id'], (cb) => cb.onDelete('cascade'))
148
+ .execute();
149
+ await db.schema
150
+ .createIndex('ix_adminium_public_sessions_token_hash')
151
+ .on(metaTable('public_sessions'))
152
+ .columns(['token_hash'])
153
+ .execute();
154
+ /*
155
+ * One-time challenges for the `email-code` claim tier (28 D11/D17).
156
+ *
157
+ * `attempts` is on the row rather than in a counter elsewhere because the
158
+ * containment property this tier is bought for — a low-entropy code is only
159
+ * safe if guesses are bounded — has to survive a process restart, and the
160
+ * rate limiter is an in-process `Map` that does not.
161
+ *
162
+ * `destination_hash` rather than the address itself: a challenge table is a
163
+ * list of customer email addresses otherwise, which is a needless standing
164
+ * disclosure for a row whose whole life is five minutes.
165
+ */
166
+ await db.schema
167
+ .createTable(metaTable('public_challenges'))
168
+ .ifNotExists()
169
+ .addColumn('id', c.id, (col) => col.primaryKey())
170
+ .addColumn('key_id', c.id, (col) => col.notNull())
171
+ .addColumn('ref', c.str(64), (col) => col.notNull())
172
+ .addColumn('destination_hash', c.str(128), (col) => col.notNull())
173
+ .addColumn('code_hash', c.str(128), (col) => col.notNull())
174
+ .addColumn('attempts', c.int, (col) => col.notNull().defaultTo(0))
175
+ .addColumn('consumed_at', c.ts)
176
+ .addColumn('expires_at', c.ts, (col) => col.notNull())
177
+ .addColumn('created_at', c.ts, (col) => col.notNull())
178
+ .addForeignKeyConstraint('fk_adminium_public_challenges_key', ['key_id'], metaTable('public_keys'), ['id'], (cb) => cb.onDelete('cascade'))
179
+ .execute();
180
+ await db.schema
181
+ .createIndex('ix_adminium_public_challenges_key_ref')
182
+ .on(metaTable('public_challenges'))
183
+ .columns(['key_id', 'ref'])
184
+ .execute();
185
+ }
186
+ //# sourceMappingURL=0014_public_surface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"0014_public_surface.js","sourceRoot":"","sources":["../../src/migrations/0014_public_surface.ts"],"names":[],"mappings":"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"}
@@ -1 +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;AAcnD,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,EAalD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAgBnD,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,EAelD,CAAC"}
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
1
2
  /**
2
3
  * Ordered, append-only migration list (07-meta-store.md §4). Up-only: a
3
4
  * mistake ships as a new compensating migration; an applied migration is never
@@ -30,6 +31,8 @@ import { up as up0009 } from './0009_views_kind.js';
30
31
  import { up as up0010 } from './0010_llm_prompt_version_width.js';
31
32
  import { up as up0011 } from './0011_i18n_runtime.js';
32
33
  import { up as up0012 } from './0012_locale_width.js';
34
+ import { up as up0013 } from './0013_connection_last_error_hint.js';
35
+ import { up as up0014 } from './0014_public_surface.js';
33
36
  export const ALL_MIGRATIONS = [
34
37
  { name: '0001_core_auth', up: up0001 },
35
38
  { name: '0002_rbac', up: up0002 },
@@ -43,5 +46,7 @@ export const ALL_MIGRATIONS = [
43
46
  { name: '0010_llm_prompt_version_width', up: up0010 },
44
47
  { name: '0011_i18n_runtime', up: up0011 },
45
48
  { name: '0012_locale_width', up: up0012 },
49
+ { name: '0013_connection_last_error_hint', up: up0013 },
50
+ { name: '0014_public_surface', up: up0014 },
46
51
  ];
47
52
  //# sourceMappingURL=index.js.map
@@ -1 +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;AAClE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAQtD,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;IACrD,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE;IACzC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE;CAC1C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;;;;;;;;;;;;;;;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;AAClE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAQxD,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;IACrD,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE;IACzC,EAAE,IAAI,EAAE,mBAAmB,EAAE,EAAE,EAAE,MAAM,EAAE;IACzC,EAAE,IAAI,EAAE,iCAAiC,EAAE,EAAE,EAAE,MAAM,EAAE;IACvD,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,MAAM,EAAE;CAC5C,CAAC"}
@@ -12,9 +12,12 @@
12
12
  * - Transactional per migration on PostgreSQL/SQLite (transactional DDL); on
13
13
  * MySQL the ledger row is written immediately after the last statement and
14
14
  * every DDL statement is individually re-runnable (ifNotExists guards).
15
+ * - Serialized across processes by a per-dialect advisory lock (migrate-lock.ts)
16
+ * so two replicas booting together cannot both enter the pending set.
15
17
  */
16
18
  import { type Kysely } from 'kysely';
17
19
  import { type MetaDialect } from './columns.js';
20
+ import { type MigrationLockOptions } from './migrate-lock.js';
18
21
  import { type MetaMigration } from './migrations/index.js';
19
22
  import type { MetaDB } from './schema/tables.js';
20
23
  /**
@@ -55,6 +58,17 @@ export interface MigratorOptions {
55
58
  version?: string;
56
59
  /** Clock override — tests only. */
57
60
  now?: () => number;
61
+ /**
62
+ * Advisory-lock settings for the pass, or `false` to run unlocked — for a
63
+ * caller that already holds the lock, or a test that wants the raw runner.
64
+ */
65
+ lock?: Omit<MigrationLockOptions, 'dialect'> | false;
66
+ /**
67
+ * Set when `db` is already inside a transaction the caller opened (the
68
+ * SQLite lock is). Suppresses the per-migration transaction: SQLite has no
69
+ * nested `BEGIN`, and the pass is already atomic as a whole.
70
+ */
71
+ inTransaction?: boolean;
58
72
  }
59
73
  export interface ApplyResult {
60
74
  /** Names applied by this call, in order (empty ⇒ already up to date). */
@@ -73,9 +87,14 @@ export interface MigrationStatusEntry {
73
87
  export declare function enableSqliteForeignKeys(db: Kysely<MetaDB>): Promise<void>;
74
88
  /**
75
89
  * 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.
90
+ * migrations are skipped via the ledger.
91
+ *
92
+ * Concurrent runners are serialized by the advisory lock (migrate-lock.ts),
93
+ * held on one pinned connection for the whole pass — the ledger PK alone only
94
+ * defends PostgreSQL/SQLite, where it shares a transaction with the DDL, and
95
+ * MySQL is exactly the dialect where it does not. Pass `lock: false` to opt
96
+ * out; a lock wait is bounded and fails with {@link MigrationLockTimeoutError}
97
+ * rather than hanging a container boot.
79
98
  */
80
99
  export declare function applyMigrations(db: Kysely<MetaDB>, options: MigratorOptions): Promise<ApplyResult>;
81
100
  /** Ledger vs file status for `adminium migrate --status`. */
@@ -1 +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"}
1
+ {"version":3,"file":"migrator.d.ts","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,EAAO,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAqB,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACjF,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;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC;IACrD;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;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;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,WAAW,CAAC,CASxG;AAkDD,6DAA6D;AAC7D,wBAAsB,eAAe,CACnC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,EAClB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAuBjC"}
package/dist/migrator.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
1
2
  /**
2
3
  * Adminium-owned migration runner (07-meta-store.md §4).
3
4
  *
@@ -12,11 +13,14 @@
12
13
  * - Transactional per migration on PostgreSQL/SQLite (transactional DDL); on
13
14
  * MySQL the ledger row is written immediately after the last statement and
14
15
  * every DDL statement is individually re-runnable (ifNotExists guards).
16
+ * - Serialized across processes by a per-dialect advisory lock (migrate-lock.ts)
17
+ * so two replicas booting together cannot both enter the pending set.
15
18
  */
16
19
  import { createHash } from 'node:crypto';
17
20
  import { readFileSync } from 'node:fs';
18
21
  import { sql } from 'kysely';
19
22
  import { columnHelpers } from './columns.js';
23
+ import { withMigrationLock } from './migrate-lock.js';
20
24
  import { ALL_MIGRATIONS } from './migrations/index.js';
21
25
  /**
22
26
  * Package version recorded in the ledger, read from package.json at module
@@ -104,15 +108,30 @@ async function readAndValidateLedger(db, migrations) {
104
108
  }
105
109
  /**
106
110
  * 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.
111
+ * migrations are skipped via the ledger.
112
+ *
113
+ * Concurrent runners are serialized by the advisory lock (migrate-lock.ts),
114
+ * held on one pinned connection for the whole pass — the ledger PK alone only
115
+ * defends PostgreSQL/SQLite, where it shares a transaction with the DDL, and
116
+ * MySQL is exactly the dialect where it does not. Pass `lock: false` to opt
117
+ * out; a lock wait is bounded and fails with {@link MigrationLockTimeoutError}
118
+ * rather than hanging a container boot.
110
119
  */
111
120
  export async function applyMigrations(db, options) {
121
+ // `db.connection()` cannot pin anything on a handle that is already a
122
+ // transaction, and an outer transaction is itself a serialization point.
123
+ if (options.lock === false || options.inTransaction === true || db.isTransaction) {
124
+ return applyMigrationsUnlocked(db, options);
125
+ }
126
+ return withMigrationLock(db, { dialect: options.dialect, ...options.lock }, (locked, ctx) => applyMigrationsUnlocked(locked, { ...options, lock: false, inTransaction: ctx.inTransaction }));
127
+ }
128
+ async function applyMigrationsUnlocked(db, options) {
112
129
  const migrations = orderedMigrations(options.migrations ?? ALL_MIGRATIONS);
113
130
  const now = options.now ?? Date.now;
114
131
  const version = options.version ?? META_PACKAGE_VERSION;
115
132
  const dialect = options.dialect;
133
+ // Kept for unlocked callers: inside the SQLite lock's transaction the pragma
134
+ // is a no-op, which is why the lock runs it before its BEGIN (migrate-lock.ts).
116
135
  if (dialect === 'sqlite')
117
136
  await enableSqliteForeignKeys(db);
118
137
  await ensureLedger(db, dialect);
@@ -130,9 +149,11 @@ export async function applyMigrations(db, options) {
130
149
  durationMs: Math.max(0, now() - startedAt),
131
150
  adminiumVersion: version,
132
151
  });
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.
152
+ if (dialect === 'mysql' || options.inTransaction === true) {
153
+ // MySQL: no transactional DDL, so statements are individually re-runnable
154
+ // (ifNotExists) and the ledger row lands right after the last one.
155
+ // `inTransaction`: the caller already opened one (the SQLite lock does),
156
+ // and SQLite has no nested BEGIN.
136
157
  await migration.up(db, c);
137
158
  await db.insertInto(LEDGER).values(ledgerRow()).execute();
138
159
  }
@@ -1 +1 @@
1
- {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,GAAG,EAAe,MAAM,QAAQ,CAAC;AAE1C,OAAO,EAAE,aAAa,EAAoB,MAAM,cAAc,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAsB,MAAM,uBAAuB,CAAC;AAG3E;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAC/B,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAG7E,CAAC,OAAO,CAAC;AAEV,MAAM,MAAM,GAAG,qBAAqB,CAAC;AAErC,MAAM,OAAO,2BAA4B,SAAQ,KAAK;IAE/B;IADZ,IAAI,GAAG,6BAA6B,CAAC;IAC9C,YAAqB,aAAqB;QACxC,KAAK,CACH,cAAc,aAAa,wDAAwD;YACjF,iHAAiH,CACpH,CAAC;QAJiB,kBAAa,GAAb,aAAa,CAAQ;IAK1C,CAAC;CACF;AAED,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAEzB;IADZ,IAAI,GAAG,uBAAuB,CAAC;IACxC,YAAqB,aAAqB;QACxC,KAAK,CACH,kCAAkC,aAAa,gDAAgD;YAC7F,mEAAmE,CACtE,CAAC;QAJiB,kBAAa,GAAb,aAAa,CAAQ;IAK1C,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IACnC,IAAI,GAAG,qBAAqB,CAAC;CACvC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAAwB;IACxD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,KAAK,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpG,CAAC;AA2BD,SAAS,iBAAiB,CAAC,UAAoC;IAC7D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,mBAAmB,CAAC,6BAA6B,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5F,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;YACnB,MAAM,IAAI,mBAAmB,CAAC,6BAA6B,CAAC,CAAC,IAAI,YAAY,IAAI,GAAG,CAAC,CAAC;QACxF,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC;IAChB,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,EAAkB,EAAE,OAAoB;IAClE,MAAM,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,EAAE,CAAC,MAAM;SACZ,WAAW,CAAC,MAAM,CAAC;SACnB,WAAW,EAAE;SACb,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;SACxD,SAAS,CAAC,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACxD,SAAS,CAAC,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACrD,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SACvD,SAAS,CAAC,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;SAChE,OAAO,EAAE,CAAC;AACf,CAAC;AAED,wFAAwF;AACxF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAAkB;IAC9D,MAAM,GAAG,CAAA,0BAA0B,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AAClD,CAAC;AAMD,KAAK,UAAU,qBAAqB,CAClC,EAAkB,EAClB,UAAoC;IAEpC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAU,CAAC,CAAC,CAAC;IACpE,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,SAAS;YAAE,MAAM,IAAI,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1D,IAAI,iBAAiB,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,2BAA2B,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,YAAY,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAkB,EAAE,OAAwB;IAChF,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,UAAU,IAAI,cAAc,CAAC,CAAC;IAC3E,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,oBAAoB,CAAC;IACxD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAEhC,IAAI,OAAO,KAAK,QAAQ;QAAE,MAAM,uBAAuB,CAAC,EAAE,CAAC,CAAC;IAC5D,MAAM,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,qBAAqB,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAErE,MAAM,CAAC,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACjC,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/C,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC;QACxB,MAAM,SAAS,GAAG,GAAG,EAAE,CAAC,CAAC;YACvB,IAAI,EAAE,SAAS,CAAC,IAAI;YACpB,QAAQ,EAAE,iBAAiB,CAAC,SAAS,CAAC;YACtC,SAAS,EAAE,GAAG,EAAE;YAChB,UAAU,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC;YAC1C,eAAe,EAAE,OAAO;SACzB,CAAC,CAAC;QAEH,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACxB,gEAAgE;YAChE,oEAAoE;YACpE,MAAM,SAAS,CAAC,EAAE,CAAC,EAAgC,EAAE,CAAC,CAAC,CAAC;YACxD,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC3C,MAAM,SAAS,CAAC,EAAE,CAAC,GAAiC,EAAE,CAAC,CAAC,CAAC;gBACzD,MAAM,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;YAC7D,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,6DAA6D;AAC7D,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,EAAkB,EAClB,OAAwB;IAExB,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,UAAU,IAAI,cAAc,CAAC,CAAC;IAC3E,MAAM,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAU,CAAC,CAAC,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAErD,MAAM,OAAO,GAA2B,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3D,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/B,OAAO;YACL,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,GAAG,KAAK,SAAS;YAC1B,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,IAAI;YACjC,KAAK,EAAE,GAAG,KAAK,SAAS,IAAI,iBAAiB,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,QAAQ;YACjE,KAAK,EAAE,IAAI;SACZ,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;QACxG,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"migrator.js","sourceRoot":"","sources":["../src/migrator.ts"],"names":[],"mappings":"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"}
@@ -1 +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"}
1
+ {"version":3,"file":"prefix.d.ts","sourceRoot":"","sources":["../src/prefix.ts"],"names":[],"mappings":"AACA;;;;;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 CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
1
2
  /**
2
3
  * Table-name prefix guard (07-meta-store.md §1, §4 "prefix safety").
3
4
  * All DDL and the migration runner go through {@link metaTable}, which asserts
@@ -1 +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"}
1
+ {"version":3,"file":"prefix.js","sourceRoot":"","sources":["../src/prefix.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC;;;;;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,118 @@
1
+ /**
2
+ * Whole-store copy, for moving a meta store from one database to another
3
+ * (07-meta-store.md §1; 01-architecture.md §3.1 meta placement).
4
+ *
5
+ * ── WHY THIS IS NOT `export-zip` / `import-zip` ─────────────────────────────
6
+ * The export bundle carries CONFIGURATION — settings, roles, rolePermissions,
7
+ * connections, snapshots, overrides, pages, views. Eight resources out of the
8
+ * tables in {@link META_TABLE_NAMES}. That is the right content for
9
+ * "replay this instance's setup somewhere else", and exactly the wrong content
10
+ * for "this instance is now living in a different database": it carries no
11
+ * users, no sessions and no user_roles, so a relocation built on it would log
12
+ * the operator out of the wizard they are standing in and strand the instance
13
+ * with no accounts at all. Relocation is a MOVE, not a replay, and a move has
14
+ * to be total.
15
+ *
16
+ * ── DIALECT PORTABILITY, AND WHY COERCION IS DRIVEN BY THE TARGET ───────────
17
+ * `columns.ts` maps one logical type onto three physical ones — `bool` is a
18
+ * postgres `boolean`, a mysql `tinyint(1)` and a sqlite `integer`; `json` is
19
+ * `jsonb`, `json` and `text`. So a value read from one dialect is not always a
20
+ * value the next dialect's driver will accept. SQLite hands back `0`/`1` where
21
+ * postgres wants a boolean, and `pg` hands back a parsed object where
22
+ * better-sqlite3 accepts only numbers, strings, bigints, buffers and null.
23
+ *
24
+ * Some of those mismatches happen to survive on their own — postgres will cast
25
+ * the text `'1'` to `boolean`, so sqlite → postgres appears to work untouched.
26
+ * Relying on that is how a copy engine ends up correct in exactly the direction
27
+ * it was first tested in. The coercion below is therefore driven by what the
28
+ * TARGET's columns actually are, read back with Kysely's introspection, so
29
+ * every direction is handled by the same rule rather than by luck.
30
+ *
31
+ * `ts` columns need no handling at all, which removes the worst class of
32
+ * cross-dialect bug before it starts: §2.1 pins every timestamp to epoch
33
+ * milliseconds in an integer column, so nothing here ever touches a native
34
+ * date.
35
+ *
36
+ * ── ATOMICITY ───────────────────────────────────────────────────────────────
37
+ * The whole copy runs in ONE transaction on the target. A relocation that
38
+ * failed halfway would otherwise leave a half-populated store that the next
39
+ * boot cannot tell from a real one; rolling back means the target is either
40
+ * fully written or untouched, and the caller can keep pointing at the source.
41
+ */
42
+ import type { MetaDb } from './connect.js';
43
+ /**
44
+ * The migration ledger is never copied. The target builds its own by running
45
+ * the migrations, and that ledger — not the source's — is the honest record of
46
+ * what has been applied to THIS database. Copying the source's on top would at
47
+ * best be a no-op and at worst re-assert checksums for DDL the target reached
48
+ * by a different route.
49
+ */
50
+ export declare const RELOCATE_SKIP_TABLES: readonly string[];
51
+ /**
52
+ * `name` is typed `string`, not narrowed to the literal, precisely so the
53
+ * subclasses below (and the server's, which extend this across the package
54
+ * boundary) can each declare their own — a literal here makes every `override
55
+ * readonly name` in a subclass a type error.
56
+ */
57
+ export declare class MetaRelocateError extends Error {
58
+ readonly name: string;
59
+ }
60
+ /** The target already holds Adminium data — refuse rather than merge into it. */
61
+ export declare class MetaStoreNotEmptyError extends MetaRelocateError {
62
+ readonly tables: readonly string[];
63
+ readonly name = "MetaStoreNotEmptyError";
64
+ constructor(tables: readonly string[]);
65
+ }
66
+ /** A table came out the other side with a different number of rows. */
67
+ export declare class MetaCopyVerificationError extends MetaRelocateError {
68
+ readonly table: string;
69
+ readonly expected: number;
70
+ readonly actual: number;
71
+ readonly name = "MetaCopyVerificationError";
72
+ constructor(table: string, expected: number, actual: number);
73
+ }
74
+ /** The tables this copies, in FK-safe insert order. */
75
+ export declare function relocatableTables(): readonly string[];
76
+ /**
77
+ * Kysely's `CamelCasePlugin` maps COLUMN names, so every row this module reads
78
+ * and writes is camelCase — but `introspection.getTables()` reports the
79
+ * PHYSICAL names, which are snake_case. This is that bridge, and it matches the
80
+ * plugin's own default transform: split on underscores, capitalize each
81
+ * subsequent segment.
82
+ */
83
+ export declare function snakeToCamel(name: string): string;
84
+ /**
85
+ * Row counts for every relocatable table. Used both to size the copy up front
86
+ * and to verify it afterwards.
87
+ */
88
+ export declare function countMetaRows(meta: MetaDb): Promise<Map<string, number>>;
89
+ /**
90
+ * Throw unless the store holds no Adminium data. Called against the TARGET
91
+ * before anything is written, so "already in use" is a refusal rather than a
92
+ * primary-key collision halfway through the copy.
93
+ */
94
+ export declare function assertMetaStoreEmpty(meta: MetaDb): Promise<void>;
95
+ export interface CopyMetaStoreOptions {
96
+ from: MetaDb;
97
+ /** Must already be migrated — run `applyMigrations` before calling. */
98
+ to: MetaDb;
99
+ /** Per-table progress, for a CLI spinner or a wizard's status line. */
100
+ onProgress?: ((table: string, rows: number) => void) | undefined;
101
+ }
102
+ export interface CopyMetaStoreResult {
103
+ tables: {
104
+ table: string;
105
+ rows: number;
106
+ }[];
107
+ totalRows: number;
108
+ }
109
+ /**
110
+ * Copy every `adminium_*` table from `from` to `to`, in one transaction.
111
+ *
112
+ * The target must be migrated and empty ({@link assertMetaStoreEmpty}). Insert
113
+ * order is {@link META_TABLE_NAMES}, which is declared in dependency-safe
114
+ * creation order and is therefore also FK-safe for inserts — so this needs no
115
+ * constraint juggling on any of the three dialects.
116
+ */
117
+ export declare function copyMetaStore(opts: CopyMetaStoreOptions): Promise<CopyMetaStoreResult>;
118
+ //# sourceMappingURL=relocate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relocate.d.ts","sourceRoot":"","sources":["../src/relocate.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAK3C;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAA4B,CAAC;AAmB/E;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,SAAkB,IAAI,EAAE,MAAM,CAAuB;CACtD;AAED,iFAAiF;AACjF,qBAAa,sBAAuB,SAAQ,iBAAiB;IAE/C,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE;IAD9C,SAAkB,IAAI,4BAA4B;gBAC7B,MAAM,EAAE,SAAS,MAAM,EAAE;CAO/C;AAED,uEAAuE;AACvE,qBAAa,yBAA0B,SAAQ,iBAAiB;IAElD,QAAQ,CAAC,KAAK,EAAE,MAAM;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM;IADtF,SAAkB,IAAI,+BAA+B;gBAChC,KAAK,EAAE,MAAM,EAAW,QAAQ,EAAE,MAAM,EAAW,MAAM,EAAE,MAAM;CAMvF;AAED,uDAAuD;AACvD,wBAAgB,iBAAiB,IAAI,SAAS,MAAM,EAAE,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AA4JD;;;GAGG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAM9E;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAItE;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,uEAAuE;IACvE,EAAE,EAAE,MAAM,CAAC;IACX,uEAAuE;IACvE,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAClE;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAyC5F"}