@rebasepro/server-postgresql 0.6.1 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/dist/PostgresBackendDriver.d.ts +8 -0
  2. package/dist/auth/services.d.ts +21 -1
  3. package/dist/cli-errors.d.ts +29 -0
  4. package/dist/cli-helpers.d.ts +7 -0
  5. package/dist/collections/PostgresCollectionRegistry.d.ts +2 -2
  6. package/dist/index.es.js +2987 -230
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/schema/auth-default-policies.d.ts +12 -0
  9. package/dist/schema/auth-schema.d.ts +227 -0
  10. package/dist/schema/generate-postgres-ddl-logic.d.ts +5 -0
  11. package/dist/schema/generate-postgres-ddl.d.ts +1 -0
  12. package/dist/services/entityService.d.ts +1 -1
  13. package/dist/utils/pg-error-utils.d.ts +10 -0
  14. package/dist/utils/table-classification.d.ts +8 -0
  15. package/package.json +15 -9
  16. package/src/PostgresBackendDriver.ts +200 -68
  17. package/src/PostgresBootstrapper.ts +34 -2
  18. package/src/auth/ensure-tables.ts +56 -1
  19. package/src/auth/services.ts +94 -1
  20. package/src/cli-errors.ts +162 -0
  21. package/src/cli-helpers.ts +183 -0
  22. package/src/cli.ts +264 -245
  23. package/src/collections/PostgresCollectionRegistry.ts +6 -6
  24. package/src/data-transformer.ts +2 -2
  25. package/src/schema/auth-default-policies.ts +97 -0
  26. package/src/schema/auth-schema.ts +25 -2
  27. package/src/schema/doctor.ts +2 -4
  28. package/src/schema/generate-drizzle-schema-logic.ts +20 -82
  29. package/src/schema/generate-drizzle-schema.ts +3 -5
  30. package/src/schema/generate-postgres-ddl-logic.ts +487 -0
  31. package/src/schema/generate-postgres-ddl.ts +116 -0
  32. package/src/services/EntityPersistService.ts +10 -8
  33. package/src/services/entityService.ts +28 -3
  34. package/src/services/realtimeService.ts +26 -2
  35. package/src/utils/pg-error-utils.ts +16 -0
  36. package/src/utils/table-classification.ts +16 -0
  37. package/src/websocket.ts +9 -0
  38. package/test/auth-default-policies.test.ts +89 -0
  39. package/test/cli-helpers-extended.test.ts +324 -0
  40. package/test/cli-helpers.test.ts +59 -0
  41. package/test/connection.test.ts +292 -0
  42. package/test/databasePoolManager.test.ts +289 -0
  43. package/test/doctor-extended.test.ts +443 -0
  44. package/test/e2e/db-e2e.test.ts +293 -0
  45. package/test/e2e/pg-setup.ts +79 -0
  46. package/test/entity-callbacks-redaction.test.ts +86 -0
  47. package/test/entity-persist-composite-keys.test.ts +451 -0
  48. package/test/generate-postgres-ddl-edge-cases.test.ts +716 -0
  49. package/test/generate-postgres-ddl.test.ts +300 -0
  50. package/test/mfa-service.test.ts +544 -0
  51. package/test/pg-error-utils.test.ts +50 -1
  52. package/test/postgresDataDriver.test.ts +2 -1
  53. package/test/realtimeService-channels.test.ts +696 -0
  54. package/test/unmapped-tables-safety.test.ts +55 -342
  55. package/vitest.e2e.config.ts +10 -0
package/dist/index.es.js CHANGED
@@ -152,15 +152,118 @@ var Vector = class {
152
152
  }
153
153
  };
154
154
  //#endregion
155
+ //#region ../types/src/types/filter-operators.ts
156
+ /** Maps REST short-code operators to their canonical equivalents. */
157
+ var REST_TO_CANONICAL = {
158
+ "eq": "==",
159
+ "neq": "!=",
160
+ "gt": ">",
161
+ "gte": ">=",
162
+ "lt": "<",
163
+ "lte": "<=",
164
+ "in": "in",
165
+ "nin": "not-in",
166
+ "cs": "array-contains",
167
+ "csa": "array-contains-any"
168
+ };
169
+ /** All canonical operator strings for runtime validation. */
170
+ var CANONICAL_OPS = new Set([
171
+ "<",
172
+ "<=",
173
+ "==",
174
+ "!=",
175
+ ">=",
176
+ ">",
177
+ "in",
178
+ "not-in",
179
+ "array-contains",
180
+ "array-contains-any"
181
+ ]);
182
+ /**
183
+ * Resolve any operator string (canonical or REST short-code) to its
184
+ * canonical `WhereFilterOp` form. Returns `undefined` for unknown operators.
185
+ *
186
+ * @example
187
+ * toCanonicalOp("==") // "=="
188
+ * toCanonicalOp("eq") // "=="
189
+ * toCanonicalOp("cs") // "array-contains"
190
+ * toCanonicalOp("xyz") // undefined
191
+ */
192
+ function toCanonicalOp(op) {
193
+ if (CANONICAL_OPS.has(op)) return op;
194
+ return REST_TO_CANONICAL[op];
195
+ }
196
+ //#endregion
155
197
  //#region ../types/src/types/collections.ts
156
198
  /**
157
199
  * Type guard for PostgreSQL collections.
158
- * Returns true if the collection uses the Postgres driver (or the default driver).
200
+ * Returns true if the collection uses the Postgres engine (or the default engine).
159
201
  * @group Models
160
202
  */
161
203
  function isPostgresCollection(collection) {
162
- return !collection.driver || collection.driver === "postgres";
204
+ return !collection.engine || collection.engine === "postgres";
163
205
  }
206
+ /**
207
+ * Reads a collection's driver-declared subcollections thunk (the `subcollections`
208
+ * field) independent of engine identity, so engine-agnostic code doesn't have to
209
+ * type-guard against a specific driver. Returns `undefined` when the collection
210
+ * declares none.
211
+ *
212
+ * Pair with `getDataSourceCapabilities(engine).supportsSubcollections` to decide
213
+ * whether the engine honours subcollections at all before reading them.
214
+ * @group Models
215
+ */
216
+ function getDeclaredSubcollections(collection) {
217
+ return collection.subcollections;
218
+ }
219
+ //#endregion
220
+ //#region ../types/src/types/policy.ts
221
+ /** @group Models */
222
+ var policy = {
223
+ true: () => ({ kind: "true" }),
224
+ false: () => ({ kind: "false" }),
225
+ and: (...operands) => ({
226
+ kind: "and",
227
+ operands
228
+ }),
229
+ or: (...operands) => ({
230
+ kind: "or",
231
+ operands
232
+ }),
233
+ not: (operand) => ({
234
+ kind: "not",
235
+ operand
236
+ }),
237
+ compare: (left, op, right) => ({
238
+ kind: "compare",
239
+ op,
240
+ left,
241
+ right
242
+ }),
243
+ rolesOverlap: (roles) => ({
244
+ kind: "rolesOverlap",
245
+ roles
246
+ }),
247
+ rolesContain: (roles) => ({
248
+ kind: "rolesContain",
249
+ roles
250
+ }),
251
+ authenticated: () => ({ kind: "authenticated" }),
252
+ raw: (sql) => ({
253
+ kind: "raw",
254
+ sql
255
+ }),
256
+ field: (name) => ({
257
+ kind: "field",
258
+ name
259
+ }),
260
+ literal: (value) => ({
261
+ kind: "literal",
262
+ value
263
+ }),
264
+ authUid: () => ({ kind: "authUid" }),
265
+ authRoles: () => ({ kind: "authRoles" })
266
+ };
164
267
  //#endregion
165
268
  //#region ../types/src/types/backend.ts
166
269
  /**
@@ -177,8 +280,6 @@ function isSQLAdmin(admin) {
177
280
  function isSchemaAdmin(admin) {
178
281
  return !!admin && (typeof admin.fetchUnmappedTables === "function" || typeof admin.fetchTableMetadata === "function");
179
282
  }
180
- //#endregion
181
- //#region ../types/src/types/data_source.ts
182
283
  /** @group Models */
183
284
  var POSTGRES_CAPABILITIES = {
184
285
  key: "postgres",
@@ -246,13 +347,13 @@ var CAPABILITIES_REGISTRY = {
246
347
  "(default)": DEFAULT_CAPABILITIES
247
348
  };
248
349
  /**
249
- * Look up capabilities for a given driver key.
250
- * If `driver` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
350
+ * Look up capabilities for a given engine key.
351
+ * If `engine` is undefined or not found, returns `DEFAULT_CAPABILITIES`.
251
352
  * @group Models
252
353
  */
253
- function getDataSourceCapabilities(driver) {
254
- if (!driver) return POSTGRES_CAPABILITIES;
255
- return CAPABILITIES_REGISTRY[driver] ?? DEFAULT_CAPABILITIES;
354
+ function getDataSourceCapabilities(engine) {
355
+ if (!engine) return POSTGRES_CAPABILITIES;
356
+ return CAPABILITIES_REGISTRY[engine] ?? DEFAULT_CAPABILITIES;
256
357
  }
257
358
  var snakeCaseRegex = /[A-Z]{2,}(?=[A-Z][a-z]|\b)|[A-Z]?[a-z]+|[0-9]+(?:[a-z](?![a-z]))?|[A-Z]/g;
258
359
  var toSnakeCase = (str) => {
@@ -1443,7 +1544,7 @@ function sanitizeRelation(relation, sourceCollection, resolveCollection) {
1443
1544
  if (!newRelation.foreignKeyOnTarget) {
1444
1545
  let foundForeignKey = false;
1445
1546
  try {
1446
- const targetRelations = getDataSourceCapabilities(targetCollection.driver).supportsRelations ? targetCollection.relations || [] : [];
1547
+ const targetRelations = getDataSourceCapabilities(targetCollection.engine).supportsRelations ? targetCollection.relations || [] : [];
1447
1548
  for (const targetRel of targetRelations) if (targetRel.direction === "owning" && targetRel.cardinality === "one" && targetRel.localKey) try {
1448
1549
  if (targetRel.target().slug === sourceCollection.slug) {
1449
1550
  newRelation.foreignKeyOnTarget = targetRel.localKey;
@@ -1459,7 +1560,7 @@ function sanitizeRelation(relation, sourceCollection, resolveCollection) {
1459
1560
  } else if (newRelation.cardinality === "many" && newRelation.direction === "inverse") {
1460
1561
  let isManyToManyInverse = false;
1461
1562
  if (newRelation.inverseRelationName && !newRelation.foreignKeyOnTarget) try {
1462
- const targetRelations = getDataSourceCapabilities(targetCollection.driver).supportsRelations ? targetCollection.relations || [] : [];
1563
+ const targetRelations = getDataSourceCapabilities(targetCollection.engine).supportsRelations ? targetCollection.relations || [] : [];
1463
1564
  for (const targetRel of targetRelations) if (targetRel.cardinality === "many" && (targetRel.direction === "owning" || !targetRel.direction) && targetRel.relationName === newRelation.inverseRelationName) {
1464
1565
  isManyToManyInverse = true;
1465
1566
  break;
@@ -1494,11 +1595,10 @@ var _resolvedRelationsCache = /* @__PURE__ */ new WeakMap();
1494
1595
  function resolveCollectionRelations(collection) {
1495
1596
  const cached = _resolvedRelationsCache.get(collection);
1496
1597
  if (cached) return cached;
1497
- if (!getDataSourceCapabilities(collection.driver).supportsRelations) return {};
1498
- const relCollection = collection;
1598
+ if (!getDataSourceCapabilities(collection.engine).supportsRelations) return {};
1499
1599
  const relations = {};
1500
1600
  const registeredRelationNames = /* @__PURE__ */ new Set();
1501
- if (relCollection.relations) relCollection.relations.forEach((relation) => {
1601
+ if (collection.relations) collection.relations.forEach((relation) => {
1502
1602
  try {
1503
1603
  const normalizedRelation = sanitizeRelation(relation, collection);
1504
1604
  const relationKey = normalizedRelation.relationName;
@@ -1545,7 +1645,7 @@ function resolvePropertyRelation({ propertyKey, property, sourceCollection }) {
1545
1645
  console.warn(`Unrecognized or missing relation target for property '${propertyKey}' in collection '${sourceCollection.slug}'`);
1546
1646
  }
1547
1647
  function getTableName$1(collection) {
1548
- if (getDataSourceCapabilities(collection.driver).supportsRelations) return collection.table ?? toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);
1648
+ if (getDataSourceCapabilities(collection.engine).supportsRelations) return collection.table ?? toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);
1549
1649
  return toSnakeCase(collection.slug) ?? toSnakeCase(collection.name);
1550
1650
  }
1551
1651
  function getTableVarName(tableName) {
@@ -1577,8 +1677,9 @@ function findRelation(resolvedRelations, key) {
1577
1677
  //#region ../common/src/util/resolutions.ts
1578
1678
  function getSubcollections(collection) {
1579
1679
  if (collection.childCollections) return collection.childCollections() ?? [];
1580
- if (getDataSourceCapabilities(collection.driver).supportsSubcollections && collection.subcollections) return collection.subcollections() ?? [];
1581
- if (getDataSourceCapabilities(collection.driver).supportsRelations) {
1680
+ const declaredSubcollections = getDeclaredSubcollections(collection);
1681
+ if (getDataSourceCapabilities(collection.engine).supportsSubcollections && declaredSubcollections) return declaredSubcollections() ?? [];
1682
+ if (getDataSourceCapabilities(collection.engine).supportsRelations) {
1582
1683
  const resolvedRelations = resolveCollectionRelations(collection);
1583
1684
  return Object.values(resolvedRelations).filter((r) => r.cardinality === "many").map((r) => {
1584
1685
  const target = r.target();
@@ -1604,6 +1705,164 @@ function getSubcollections(collection) {
1604
1705
  return [];
1605
1706
  }
1606
1707
  //#endregion
1708
+ //#region ../common/src/util/policy/sqlToPolicy.ts
1709
+ /**
1710
+ * A tiny, regex-based SQL "parser" for security rules.
1711
+ *
1712
+ * This is NOT a full SQL parser. It is designed to handle the subset of SQL
1713
+ * commonly used in `USING` and `WITH CHECK` clauses, enough to drive the
1714
+ * optimistic client-side UI decision.
1715
+ *
1716
+ * It handles:
1717
+ * - `field = 'literal'`
1718
+ * - `field != 'literal'`
1719
+ * - `field = current_setting('app.user_id')`
1720
+ * - `A AND B`
1721
+ * - `true`
1722
+ * - `IN (...)` (as optimistic true)
1723
+ *
1724
+ * For anything it doesn't understand, it returns a `raw` expression, which
1725
+ * the evaluator treats as "unknown" (and usually optimistic true).
1726
+ */
1727
+ function sqlToPolicy(sql) {
1728
+ const trimmed = sql.trim();
1729
+ if (trimmed.toLowerCase() === "true") return policy.true();
1730
+ if (trimmed.toLowerCase() === "false") return policy.false();
1731
+ const overlapMatch = trimmed.match(/^string_to_array\s*\(\s*auth\.roles\(\)\s*,\s*','\s*\)\s*&&\s*ARRAY\s*\[(.+)\]$/i);
1732
+ if (overlapMatch) {
1733
+ const roles = overlapMatch[1].split(",").map((s) => s.trim().replace(/^'|'$/g, ""));
1734
+ return policy.rolesOverlap(roles);
1735
+ }
1736
+ const containMatch = trimmed.match(/^string_to_array\s*\(\s*auth\.roles\(\)\s*,\s*','\s*\)\s*@>\s*ARRAY\s*\[(.+)\]$/i);
1737
+ if (containMatch) {
1738
+ const roles = containMatch[1].split(",").map((s) => s.trim().replace(/^'|'$/g, ""));
1739
+ return policy.rolesContain(roles);
1740
+ }
1741
+ if (trimmed.toUpperCase().includes(" OR ")) {
1742
+ const parts = trimmed.split(/ OR /i);
1743
+ return policy.or(...parts.map(sqlToPolicy));
1744
+ }
1745
+ if (trimmed.toUpperCase().includes(" AND ")) {
1746
+ const parts = trimmed.split(/ AND /i);
1747
+ return policy.and(...parts.map(sqlToPolicy));
1748
+ }
1749
+ const match = trimmed.match(/^(.+?)\s*(!?=)\s*(.+)$/);
1750
+ if (match) {
1751
+ const [, leftStr, op, rightStr] = match;
1752
+ const left = parseOperand(leftStr.trim());
1753
+ const right = parseOperand(rightStr.trim());
1754
+ if (left && right) return policy.compare(left, op === "=" ? "eq" : "neq", right);
1755
+ }
1756
+ return policy.raw(sql);
1757
+ }
1758
+ function parseOperand(str) {
1759
+ if (/current_setting\s*\(\s*'app\.user_id'\s*\)/i.test(str) || /auth\.uid\(\)/i.test(str)) return policy.authUid();
1760
+ const stringMatch = str.match(/^'(.+)'$/);
1761
+ if (stringMatch) return policy.literal(stringMatch[1]);
1762
+ if (/^\w+$/.test(str)) return policy.field(str);
1763
+ return null;
1764
+ }
1765
+ //#endregion
1766
+ //#region ../common/src/util/policy/securityRuleToConditions.ts
1767
+ /**
1768
+ * Desugars a {@link SecurityRule} — its `access`/`ownerField`/`roles` shortcuts,
1769
+ * structured `condition`/`check`, and raw `using`/`withCheck` — into a single
1770
+ * normalized {@link PolicyExpression} pair.
1771
+ *
1772
+ * **This is the linchpin against drift:** both the Postgres DDL generators and
1773
+ * the client-side evaluator consume this one function, so there is exactly one
1774
+ * definition of what a rule means. In particular, application `roles` are folded
1775
+ * into the expression here (AND'd with the base condition, matching how Postgres
1776
+ * generates the clause) rather than being handled separately by each consumer.
1777
+ */
1778
+ function securityRuleToConditions(rule) {
1779
+ return {
1780
+ usingExpr: withRoles(baseUsing(rule), rule),
1781
+ withCheckExpr: withRoles(baseWithCheck(rule), rule)
1782
+ };
1783
+ }
1784
+ function baseUsing(rule) {
1785
+ if (rule.condition) return rule.condition;
1786
+ if (rule.using != null) return sqlToPolicy(rule.using);
1787
+ if (rule.access === "public") return policy.true();
1788
+ if (rule.ownerField) return policy.compare(policy.field(rule.ownerField), "eq", policy.authUid());
1789
+ return null;
1790
+ }
1791
+ function baseWithCheck(rule) {
1792
+ if (rule.check) return rule.check;
1793
+ if (rule.withCheck != null) return sqlToPolicy(rule.withCheck);
1794
+ return baseUsing(rule);
1795
+ }
1796
+ /**
1797
+ * AND the base condition with an application-role check, or produce a roles-only
1798
+ * condition when there is no base. Mirrors the Postgres generator so that a
1799
+ * role-scoped restrictive rule denies exactly the same set of users on both
1800
+ * sides.
1801
+ */
1802
+ function withRoles(base, rule) {
1803
+ if (!rule.roles || rule.roles.length === 0) return base;
1804
+ const rolesExpr = policy.rolesOverlap(rule.roles);
1805
+ if (rule.mode === "restrictive") return base ? policy.or(policy.not(rolesExpr), base) : policy.not(rolesExpr);
1806
+ return base ? policy.and(base, rolesExpr) : rolesExpr;
1807
+ }
1808
+ //#endregion
1809
+ //#region ../common/src/util/policy/policyToPostgres.ts
1810
+ /**
1811
+ * Compiles a {@link PolicyExpression} to a PostgreSQL boolean SQL string,
1812
+ * suitable for a `USING (...)` / `WITH CHECK (...)` clause.
1813
+ *
1814
+ * This is one of the two consumers of the shared policy model (the other being
1815
+ * {@link evaluatePolicy}); the Postgres schema generators call it so that DDL
1816
+ * and the admin UI derive from the exact same expression.
1817
+ */
1818
+ function policyToPostgres(expr, collection) {
1819
+ switch (expr.kind) {
1820
+ case "true": return "true";
1821
+ case "false": return "false";
1822
+ case "and": return expr.operands.length === 0 ? "true" : expr.operands.map((o) => `(${policyToPostgres(o, collection)})`).join(" AND ");
1823
+ case "or": return expr.operands.length === 0 ? "false" : expr.operands.map((o) => `(${policyToPostgres(o, collection)})`).join(" OR ");
1824
+ case "not":
1825
+ if (expr.operand.kind === "authenticated") return "auth.uid() IS NULL";
1826
+ return `NOT (${policyToPostgres(expr.operand, collection)})`;
1827
+ case "compare": return `${operandToSql(expr.left, collection)} ${COMPARE_SQL[expr.op]} ${operandToSql(expr.right, collection)}`;
1828
+ case "rolesOverlap": return `string_to_array(auth.roles(), ',') && ${rolesArraySql(expr.roles)}`;
1829
+ case "rolesContain": return `string_to_array(auth.roles(), ',') @> ${rolesArraySql(expr.roles)}`;
1830
+ case "authenticated": return "auth.uid() IS NOT NULL";
1831
+ case "raw": return expr.sql.replace(/\{(\w+)\}/g, (_, col) => col);
1832
+ }
1833
+ }
1834
+ var COMPARE_SQL = {
1835
+ eq: "=",
1836
+ neq: "!=",
1837
+ lt: "<",
1838
+ lte: "<=",
1839
+ gt: ">",
1840
+ gte: ">="
1841
+ };
1842
+ function operandToSql(operand, collection) {
1843
+ switch (operand.kind) {
1844
+ case "field": return resolveColumnName$1(operand.name, collection);
1845
+ case "literal": return quoteLiteral(operand.value);
1846
+ case "authUid": return "auth.uid()";
1847
+ case "authRoles": return "string_to_array(auth.roles(), ',')";
1848
+ }
1849
+ }
1850
+ function resolveColumnName$1(propName, collection) {
1851
+ const prop = collection?.properties?.[propName];
1852
+ if (prop && "columnName" in prop && typeof prop.columnName === "string") return prop.columnName;
1853
+ return toSnakeCase(propName);
1854
+ }
1855
+ function quoteLiteral(value) {
1856
+ if (value === null) return "NULL";
1857
+ if (typeof value === "boolean") return value ? "true" : "false";
1858
+ if (typeof value === "number") return String(value);
1859
+ return `'${value.replace(/'/g, "''")}'`;
1860
+ }
1861
+ /** Sorted, single-quoted `ARRAY['a','b']` — matches the generators' output. */
1862
+ function rolesArraySql(roles) {
1863
+ return `ARRAY[${[...roles].sort().map((r) => `'${r}'`).join(",")}]`;
1864
+ }
1865
+ //#endregion
1607
1866
  //#region ../common/src/util/callbacks.ts
1608
1867
  /**
1609
1868
  * Helper function to recursively check if there are any callbacks in the properties.
@@ -2366,8 +2625,67 @@ function createCustomEqual(options = {}) {
2366
2625
  });
2367
2626
  }
2368
2627
  //#endregion
2628
+ //#region ../common/src/data/resolveDataSource.ts
2629
+ /**
2630
+ * Resolve the effective data source for a collection — the single source of
2631
+ * truth shared by the frontend router, the backend driver registry, and the
2632
+ * editor's capability lookups.
2633
+ *
2634
+ * Resolution order:
2635
+ * 1. The routing **key** is `collection.dataSource`, else
2636
+ * {@link DEFAULT_DATA_SOURCE_KEY}.
2637
+ * 2. If a definition is registered for that key, it provides `engine`,
2638
+ * `transport`, and `databaseId`.
2639
+ * 3. Otherwise values are synthesized: `engine` from `collection.engine`
2640
+ * (or the key, or `"postgres"`), `transport` defaults to `"server"`,
2641
+ * and `databaseId` from the collection.
2642
+ *
2643
+ * `capabilities` are always derived from the resolved `engine`, so two
2644
+ * data sources sharing an engine share capabilities.
2645
+ *
2646
+ * @param collection the collection (or any object carrying the routing fields)
2647
+ * @param registry optional registry of declared data sources
2648
+ */
2649
+ function resolveDataSource(collection, registry) {
2650
+ const key = collection?.dataSource ?? "(default)";
2651
+ const def = registry?.[key];
2652
+ const engine = def?.engine ?? collection?.engine ?? (key !== "(default)" ? key : "postgres");
2653
+ return {
2654
+ key,
2655
+ engine,
2656
+ transport: def?.transport ?? "server",
2657
+ databaseId: collection?.databaseId ?? def?.databaseId,
2658
+ capabilities: getDataSourceCapabilities(engine)
2659
+ };
2660
+ }
2661
+ //#endregion
2369
2662
  //#region ../common/src/collections/CollectionRegistry.ts
2370
2663
  var CollectionRegistry = class {
2664
+ /**
2665
+ * Declared data sources, used during normalization to resolve each
2666
+ * collection's engine (so `dataSource`-only collections get the right
2667
+ * capabilities). Empty by default.
2668
+ */
2669
+ dataSources = {};
2670
+ /**
2671
+ * Global lifecycle callbacks applied to every collection.
2672
+ * Runs on all data paths (REST, WebSocket, `rebase.data`).
2673
+ * Execution order: global → collection → property callbacks.
2674
+ */
2675
+ _globalCallbacks;
2676
+ /**
2677
+ * Set global lifecycle callbacks that apply to every collection.
2678
+ * Typically called once during backend initialization.
2679
+ */
2680
+ setGlobalCallbacks(callbacks) {
2681
+ this._globalCallbacks = callbacks;
2682
+ }
2683
+ /**
2684
+ * Get the currently registered global callbacks, if any.
2685
+ */
2686
+ getGlobalCallbacks() {
2687
+ return this._globalCallbacks;
2688
+ }
2371
2689
  collectionsByTableName = /* @__PURE__ */ new Map();
2372
2690
  collectionsBySlug = /* @__PURE__ */ new Map();
2373
2691
  rootCollections = [];
@@ -2377,9 +2695,20 @@ var CollectionRegistry = class {
2377
2695
  rawRootCollections = [];
2378
2696
  cachedRawCollectionsList = null;
2379
2697
  lastRawInputSnapshot = null;
2380
- constructor(collections) {
2698
+ constructor(collections, dataSources) {
2699
+ if (dataSources) this.dataSources = dataSources;
2381
2700
  if (collections) this.registerMultiple(collections);
2382
2701
  }
2702
+ /**
2703
+ * Provide the declared data sources used to resolve each collection's
2704
+ * engine during normalization. Set this before registering collections.
2705
+ * Returns true if the registry changed (callers may re-register).
2706
+ */
2707
+ setDataSources(dataSources) {
2708
+ if (deepEqual$1(this.dataSources, dataSources)) return false;
2709
+ this.dataSources = dataSources ?? {};
2710
+ return true;
2711
+ }
2383
2712
  reset() {
2384
2713
  this.collectionsByTableName.clear();
2385
2714
  this.collectionsBySlug.clear();
@@ -2448,9 +2777,14 @@ var CollectionRegistry = class {
2448
2777
  }
2449
2778
  normalizeCollection(collection) {
2450
2779
  const result = { ...collection };
2780
+ {
2781
+ const resolved = resolveDataSource(result, this.dataSources);
2782
+ if (!result.dataSource) result.dataSource = resolved.key;
2783
+ if (!result.engine) result.engine = resolved.engine;
2784
+ }
2451
2785
  const extractedRelations = this.extractRelationsFromProperties(result.properties);
2452
2786
  const relResult = result;
2453
- const manualRelations = getDataSourceCapabilities(result.driver).supportsRelations ? relResult.relations ?? [] : [];
2787
+ const manualRelations = getDataSourceCapabilities(result.engine).supportsRelations ? relResult.relations ?? [] : [];
2454
2788
  const mergedRelationsRaw = [...extractedRelations];
2455
2789
  for (const manual of manualRelations) {
2456
2790
  const name = manual.relationName;
@@ -2465,7 +2799,7 @@ var CollectionRegistry = class {
2465
2799
  }
2466
2800
  }
2467
2801
  let mergedRelations = mergedRelationsRaw;
2468
- if (getDataSourceCapabilities(result.driver).supportsRelations) {
2802
+ if (getDataSourceCapabilities(result.engine).supportsRelations) {
2469
2803
  mergedRelations = mergedRelationsRaw.map((r) => {
2470
2804
  try {
2471
2805
  return sanitizeRelation(r, result, (slug) => this.get(slug));
@@ -2477,8 +2811,10 @@ var CollectionRegistry = class {
2477
2811
  }
2478
2812
  result.properties = this.normalizeProperties(result.properties, mergedRelations);
2479
2813
  if (!result.childCollections) {
2480
- if (getDataSourceCapabilities(result.driver).supportsSubcollections && result.subcollections) result.childCollections = result.subcollections;
2481
- else if (getDataSourceCapabilities(result.driver).supportsRelations && relResult.relations) {
2814
+ const capabilities = getDataSourceCapabilities(result.engine);
2815
+ const declaredSubcollections = getDeclaredSubcollections(result);
2816
+ if (capabilities.supportsSubcollections && declaredSubcollections) result.childCollections = declaredSubcollections;
2817
+ else if (capabilities.supportsRelations && relResult.relations) {
2482
2818
  const manyRelations = relResult.relations.filter((r) => r.cardinality === "many");
2483
2819
  if (manyRelations.length > 0) result.childCollections = () => manyRelations.map((r) => {
2484
2820
  const target = r.target();
@@ -2580,7 +2916,7 @@ var CollectionRegistry = class {
2580
2916
  if (!currentCollection) throw new Error(`Root collection not found: ${rootCollectionPath}`);
2581
2917
  for (let i = 2; i < pathSegments.length; i += 2) {
2582
2918
  const relationKey = pathSegments[i];
2583
- if (!getDataSourceCapabilities(currentCollection.driver).supportsRelations) throw new Error(`Relation path navigation requires a collection that supports relations, but '${currentCollection.slug}' uses driver '${currentCollection.driver}'`);
2919
+ if (!getDataSourceCapabilities(currentCollection.engine).supportsRelations) throw new Error(`Relation path navigation requires a collection that supports relations, but '${currentCollection.slug}' uses engine '${currentCollection.engine}'`);
2584
2920
  const relation = findRelation(resolveCollectionRelations(currentCollection), relationKey);
2585
2921
  if (!relation) throw new Error(`Relation '${relationKey}' not found in collection '${currentCollection.slug}'`);
2586
2922
  const target = relation.target();
@@ -2664,8 +3000,8 @@ var QueryBuilder = class {
2664
3000
  * @example
2665
3001
  * client.collection('users').orderBy('createdAt', 'desc').find()
2666
3002
  */
2667
- orderBy(column, ascending = "asc") {
2668
- this.params.orderBy = `${column}:${ascending}`;
3003
+ orderBy(column, direction = "asc") {
3004
+ this.params.orderBy = `${column}:${direction}`;
2669
3005
  return this;
2670
3006
  }
2671
3007
  /**
@@ -2720,80 +3056,83 @@ var QueryBuilder = class {
2720
3056
  }
2721
3057
  };
2722
3058
  //#endregion
2723
- //#region ../common/src/data/buildRebaseData.ts
3059
+ //#region ../common/src/data/filter-dialect.ts
2724
3060
  /**
2725
- * Convert where-clause filter object to the internal DataDriver FilterValues format.
3061
+ * REST wire-format adapter for the unified filter system.
2726
3062
  *
2727
- * Supports multiple value formats:
2728
- * - PostgREST string: { status: "eq.published", age: "gte.18" }
2729
- * - Equality shorthand: { company_profile_id: null, status: "active", age: 18 }
2730
- * - Tuple syntax: { age: [">=", 18], role: ["in", ["admin", "editor"]] }
3063
+ * This module is the ONLY code in the entire codebase that knows about
3064
+ * PostgREST-style dot-syntax strings (`eq.active`, `gt.18`, `in.(a,b)`).
3065
+ * Everything else speaks `FilterValues` exclusively.
2731
3066
  *
2732
- * Internal: { status: ["==", "published"], age: [">=", 18] }
3067
+ * @module
2733
3068
  */
2734
- function convertWhereToFilter(where) {
2735
- if (!where) return void 0;
2736
- const operatorMap = {
2737
- "eq": "==",
2738
- "neq": "!=",
2739
- "gt": ">",
2740
- "gte": ">=",
2741
- "lt": "<",
2742
- "lte": "<=",
2743
- "in": "in",
2744
- "nin": "not-in",
2745
- "not-in": "not-in",
2746
- "cs": "array-contains",
2747
- "csa": "array-contains-any",
2748
- "==": "==",
2749
- "!=": "!=",
2750
- ">": ">",
2751
- ">=": ">=",
2752
- "<": "<",
2753
- "<=": "<=",
2754
- "array-contains": "array-contains",
2755
- "array-contains-any": "array-contains-any"
2756
- };
2757
- const filter = {};
2758
- for (const [field, rawValue] of Object.entries(where)) {
2759
- if (rawValue === null) {
2760
- filter[field] = ["==", null];
2761
- continue;
2762
- }
2763
- if (typeof rawValue === "boolean") {
2764
- filter[field] = ["==", rawValue];
2765
- continue;
2766
- }
2767
- if (typeof rawValue === "number") {
2768
- filter[field] = ["==", rawValue];
2769
- continue;
2770
- }
2771
- if (Array.isArray(rawValue)) {
2772
- const mappedConditions = (Array.isArray(rawValue[0]) ? rawValue : [rawValue]).map(([rawOp, val]) => {
2773
- return [operatorMap[rawOp] ?? "==", val];
2774
- });
2775
- filter[field] = Array.isArray(rawValue[0]) ? mappedConditions : mappedConditions[0];
3069
+ /**
3070
+ * Coerce a raw querystring value to its natural JS type.
3071
+ * - `"true"` / `"false"` → boolean
3072
+ * - `"null"` → null
3073
+ * - Numeric strings → number
3074
+ * - Everything else → string (unchanged)
3075
+ */
3076
+ function coerceValue(raw) {
3077
+ if (raw === "true") return true;
3078
+ if (raw === "false") return false;
3079
+ if (raw === "null") return null;
3080
+ if (raw !== "" && !isNaN(Number(raw))) return Number(raw);
3081
+ return raw;
3082
+ }
3083
+ /**
3084
+ * Parse a single PostgREST dot-string into a `[WhereFilterOp, unknown]` tuple.
3085
+ *
3086
+ * If the string doesn't match a known operator prefix, falls back to
3087
+ * `["==", originalString]` (treating the whole string as an equality value).
3088
+ */
3089
+ function deserializeSingle(raw) {
3090
+ const dotIndex = raw.indexOf(".");
3091
+ if (dotIndex === -1) return ["==", coerceValue(raw)];
3092
+ const prefix = raw.substring(0, dotIndex);
3093
+ const rest = raw.substring(dotIndex + 1);
3094
+ const canonicalOp = REST_TO_CANONICAL[prefix];
3095
+ if (!canonicalOp) return ["==", raw];
3096
+ if (rest.startsWith("(") && rest.endsWith(")")) return [canonicalOp, rest.slice(1, -1).split(",").map((s) => coerceValue(s.trim()))];
3097
+ return [canonicalOp, coerceValue(rest)];
3098
+ }
3099
+ /**
3100
+ * Convert a PostgREST-style querystring record to `FilterValues`.
3101
+ *
3102
+ * - String values are parsed as single conditions.
3103
+ * - String arrays (repeated query params) become multiple conditions on the same field.
3104
+ *
3105
+ * @example
3106
+ * deserializeFilter({ status: "eq.active" })
3107
+ * // { status: ["==", "active"] }
3108
+ *
3109
+ * deserializeFilter({ age: ["gte.18", "lt.65"] })
3110
+ * // { age: [[">=", 18], ["<", 65]] }
3111
+ */
3112
+ function deserializeFilter(query) {
3113
+ const result = {};
3114
+ for (const [field, raw] of Object.entries(query)) {
3115
+ if (raw === void 0) continue;
3116
+ if (Array.isArray(raw) && raw.length === 2 && typeof raw[0] === "string" && toCanonicalOp(raw[0]) === raw[0]) {
3117
+ result[field] = raw;
2776
3118
  continue;
2777
3119
  }
2778
- if (typeof rawValue === "string") {
2779
- const dotIndex = rawValue.indexOf(".");
2780
- if (dotIndex === -1) {
2781
- filter[field] = ["==", rawValue];
3120
+ if (Array.isArray(raw)) {
3121
+ if (raw.length === 0) continue;
3122
+ if (Array.isArray(raw[0]) && raw[0].length === 2 && typeof raw[0][0] === "string" && toCanonicalOp(raw[0][0]) === raw[0][0]) {
3123
+ result[field] = raw;
2782
3124
  continue;
2783
3125
  }
2784
- const op = rawValue.substring(0, dotIndex);
2785
- let value = rawValue.substring(dotIndex + 1);
2786
- if (typeof value === "string" && value.startsWith("(") && value.endsWith(")")) value = value.slice(1, -1).split(",").map((v) => v.trim());
2787
- if (value === "null") value = null;
2788
- else if (value === "true") value = true;
2789
- else if (value === "false") value = false;
2790
- else if (typeof value === "string" && !isNaN(Number(value)) && value.trim() !== "") value = Number(value);
2791
- const mappedOp = operatorMap[op];
2792
- if (mappedOp) filter[field] = [mappedOp, value];
2793
- }
3126
+ if (raw.length === 1) result[field] = typeof raw[0] === "string" ? deserializeSingle(raw[0]) : ["==", raw[0]];
3127
+ else if (typeof raw[0] === "string" && raw[0].includes(".")) result[field] = raw.map((r) => typeof r === "string" ? deserializeSingle(r) : ["==", r]);
3128
+ else result[field] = ["in", raw];
3129
+ } else if (typeof raw === "string") result[field] = deserializeSingle(raw);
3130
+ else result[field] = ["==", raw];
2794
3131
  }
2795
- return Object.keys(filter).length > 0 ? filter : void 0;
3132
+ return result;
2796
3133
  }
3134
+ //#endregion
3135
+ //#region ../common/src/data/buildRebaseData.ts
2797
3136
  /**
2798
3137
  * Parse an orderBy string like "created_at:desc" into [field, direction].
2799
3138
  */
@@ -2806,11 +3145,12 @@ function createDriverAccessor(driver, slug) {
2806
3145
  const accessor = {
2807
3146
  async find(params) {
2808
3147
  const orderParsed = parseOrderBy(params?.orderBy);
3148
+ const filter = params?.where ? deserializeFilter(params.where) : void 0;
2809
3149
  const entities = await driver.fetchCollection({
2810
3150
  path: slug,
2811
3151
  limit: params?.limit,
2812
3152
  offset: params?.offset,
2813
- filter: convertWhereToFilter(params?.where),
3153
+ filter,
2814
3154
  orderBy: orderParsed?.[0],
2815
3155
  order: orderParsed?.[1],
2816
3156
  searchString: params?.searchString
@@ -2860,9 +3200,10 @@ function createDriverAccessor(driver, slug) {
2860
3200
  return driver.deleteAll(slug);
2861
3201
  } : void 0,
2862
3202
  count: driver.countEntities ? async (params) => {
3203
+ const filter = params?.where ? deserializeFilter(params.where) : void 0;
2863
3204
  return driver.countEntities({
2864
3205
  path: slug,
2865
- filter: convertWhereToFilter(params?.where)
3206
+ filter
2866
3207
  });
2867
3208
  } : void 0,
2868
3209
  listen: driver.listenCollection ? (params, onUpdate, onError) => {
@@ -2873,7 +3214,7 @@ function createDriverAccessor(driver, slug) {
2873
3214
  path: slug,
2874
3215
  limit: params?.limit,
2875
3216
  offset: params?.offset,
2876
- filter: convertWhereToFilter(params?.where),
3217
+ filter: params?.where,
2877
3218
  orderBy: orderParsed?.[0],
2878
3219
  order: orderParsed?.[1],
2879
3220
  searchString: params?.searchString,
@@ -2952,6 +3293,72 @@ function buildRebaseData(driver) {
2952
3293
  } });
2953
3294
  }
2954
3295
  //#endregion
3296
+ //#region ../common/src/table-classification.ts
3297
+ /** Schemas that are always considered Rebase-internal. */
3298
+ var REBASE_INTERNAL_SCHEMAS = ["rebase", "auth"];
3299
+ /** Table-name prefixes that mark a table as Rebase-internal regardless of schema. */
3300
+ var REBASE_INTERNAL_PREFIXES = [
3301
+ "_rebase_",
3302
+ "_auth_",
3303
+ "drizzle_"
3304
+ ];
3305
+ /**
3306
+ * Synchronously classify a table based on naming conventions.
3307
+ *
3308
+ * @param tableName - The unqualified name of the table.
3309
+ * @param schemaName - The schema the table belongs to (e.g. `"public"`, `"rebase"`).
3310
+ * @returns `"rebase-internal"` when the table belongs to a reserved schema or
3311
+ * carries a reserved prefix; `"user"` otherwise.
3312
+ *
3313
+ * @remarks
3314
+ * Junction-table detection requires an async database query and is therefore
3315
+ * **not** handled by this function. Use {@link detectJunctionTables} to obtain
3316
+ * the set of junction tables, then reclassify as needed.
3317
+ */
3318
+ function classifyTable(tableName, schemaName) {
3319
+ if (REBASE_INTERNAL_SCHEMAS.includes(schemaName) || REBASE_INTERNAL_PREFIXES.some((prefix) => tableName.startsWith(prefix))) return "rebase-internal";
3320
+ return "user";
3321
+ }
3322
+ /** SQL query that detects junction tables in the `public` schema. */
3323
+ var JUNCTION_TABLES_SQL = `
3324
+ SELECT t.table_name
3325
+ FROM information_schema.tables t
3326
+ WHERE t.table_schema = 'public'
3327
+ AND t.table_type = 'BASE TABLE'
3328
+ AND NOT EXISTS (
3329
+ SELECT 1
3330
+ FROM information_schema.columns c
3331
+ WHERE c.table_schema = t.table_schema
3332
+ AND c.table_name = t.table_name
3333
+ AND c.column_name NOT IN (
3334
+ SELECT kcu.column_name
3335
+ FROM information_schema.key_column_usage kcu
3336
+ JOIN information_schema.table_constraints tc
3337
+ ON tc.constraint_name = kcu.constraint_name
3338
+ AND tc.table_schema = kcu.table_schema
3339
+ WHERE tc.constraint_type = 'FOREIGN KEY'
3340
+ AND kcu.table_schema = t.table_schema
3341
+ AND kcu.table_name = t.table_name
3342
+ )
3343
+ )
3344
+ `;
3345
+ /**
3346
+ * Asynchronously detect junction (link) tables in the `public` schema.
3347
+ *
3348
+ * A junction table is defined as a table where **every** column participates in
3349
+ * at least one foreign-key constraint.
3350
+ *
3351
+ * @param executeSql - A callback that executes a raw SQL string and returns the
3352
+ * resulting rows.
3353
+ * @returns A `Set` containing the names of all detected junction tables.
3354
+ */
3355
+ async function detectJunctionTables(executeSql) {
3356
+ const rows = await executeSql(JUNCTION_TABLES_SQL);
3357
+ const junctionTables = /* @__PURE__ */ new Set();
3358
+ for (const row of rows) if (typeof row.table_name === "string") junctionTables.add(row.table_name);
3359
+ return junctionTables;
3360
+ }
3361
+ //#endregion
2955
3362
  //#region src/services/entity-helpers.ts
2956
3363
  /** Safely extract Drizzle column metadata from a column object. */
2957
3364
  function getColumnMeta(col) {
@@ -5700,6 +6107,21 @@ function extractCauseMessage(error) {
5700
6107
  return null;
5701
6108
  }
5702
6109
  /**
6110
+ * Detect whether an error is specifically a role-switching permission failure
6111
+ * (e.g. "permission denied to set role" or "must be member of role"),
6112
+ * as opposed to a table-level permission denial.
6113
+ *
6114
+ * This is used by the backend driver to auto-disable role switching when the
6115
+ * connection user lacks SET ROLE privileges, rather than surfacing a confusing
6116
+ * error to the Studio SQL Editor user.
6117
+ */
6118
+ function isRoleSwitchingPermissionError(error) {
6119
+ const pgError = extractPgError(error);
6120
+ if (!pgError || pgError.code !== "42501") return false;
6121
+ const msg = pgError.message.toLowerCase();
6122
+ return msg.includes("set role") || msg.includes("member of role");
6123
+ }
6124
+ /**
5703
6125
  * Translate a raw PostgreSQL error into a user-friendly message.
5704
6126
  *
5705
6127
  * @param pgError - The extracted PostgreSQL error (from {@link extractPgError})
@@ -5835,11 +6257,14 @@ var EntityPersistService = class {
5835
6257
  const collection = getCollectionByPath(collectionPath, this.registry);
5836
6258
  const table = getTableForCollection(collection, this.registry);
5837
6259
  const idInfoArray = getPrimaryKeys(collection, this.registry);
5838
- const idInfo = idInfoArray[0];
5839
- const idField = table[idInfo.fieldName];
5840
- if (!idField) throw new Error(`ID field '${idInfo.fieldName}' not found in table for collection '${collectionPath}'`);
5841
- const parsedId = parseIdValues(entityId, idInfoArray)[idInfo.fieldName];
5842
- await this.db.delete(table).where(eq(idField, parsedId));
6260
+ const parsedIdObj = parseIdValues(entityId, idInfoArray);
6261
+ const conditions = [];
6262
+ for (const info of idInfoArray) {
6263
+ const field = table[info.fieldName];
6264
+ if (!field) throw new Error(`ID field '${info.fieldName}' not found in table for collection '${collectionPath}'`);
6265
+ conditions.push(eq(field, parsedIdObj[info.fieldName]));
6266
+ }
6267
+ await this.db.delete(table).where(and(...conditions));
5843
6268
  }
5844
6269
  /**
5845
6270
  * Delete all entities from a collection
@@ -6082,10 +6507,23 @@ var EntityService = class {
6082
6507
  /**
6083
6508
  * Execute raw SQL
6084
6509
  */
6085
- async executeSql(sqlText) {
6086
- if (process.env.NODE_ENV !== "production") console.debug("Executing raw SQL:", sqlText);
6510
+ async executeSql(sqlText, params) {
6511
+ if (process.env.NODE_ENV !== "production") console.debug("Executing raw SQL:", sqlText, params?.length ? `with ${params.length} params` : "");
6087
6512
  const { sql } = await import("drizzle-orm");
6088
- const rows = (await this.db.execute(sql.raw(sqlText))).rows;
6513
+ let result;
6514
+ if (params && params.length > 0) {
6515
+ const parts = sqlText.split(/\$(\d+)/);
6516
+ const chunks = [];
6517
+ for (let i = 0; i < parts.length; i++) if (i % 2 === 0) {
6518
+ if (parts[i].length > 0) chunks.push(sql.raw(parts[i]));
6519
+ } else {
6520
+ const paramIndex = Number(parts[i]) - 1;
6521
+ chunks.push(sql.param(params[paramIndex]));
6522
+ }
6523
+ const query = sql.join(chunks, sql.raw(""));
6524
+ result = await this.db.execute(query);
6525
+ } else result = await this.db.execute(sql.raw(sqlText));
6526
+ const rows = result.rows;
6089
6527
  if (process.env.NODE_ENV !== "production") console.debug(`SQL executed successfully. Returned ${Array.isArray(rows) ? rows.length : "non-array"} rows.`);
6090
6528
  return rows;
6091
6529
  }
@@ -6287,6 +6725,13 @@ var PostgresBackendDriver = class {
6287
6725
  data;
6288
6726
  client;
6289
6727
  /**
6728
+ * Auto-set to `true` when a SET LOCAL ROLE fails with insufficient
6729
+ * privileges, so subsequent queries skip the doomed attempt.
6730
+ * Mirrors the static `DISABLE_DB_ROLE_SWITCHING` env var but is
6731
+ * learned at runtime.
6732
+ */
6733
+ _roleSwitchingDisabled = false;
6734
+ /**
6290
6735
  * When true, realtime notifications are deferred until after the
6291
6736
  * wrapping transaction commits. Set by `withAuth` → `withTransaction`.
6292
6737
  */
@@ -6345,6 +6790,7 @@ var PostgresBackendDriver = class {
6345
6790
  if (!collection && !path) return {
6346
6791
  collection: void 0,
6347
6792
  callbacks: void 0,
6793
+ globalCallbacks: void 0,
6348
6794
  propertyCallbacks: void 0
6349
6795
  };
6350
6796
  const registryCollection = this.registry?.getCollectionByPath(path);
@@ -6353,12 +6799,14 @@ var PostgresBackendDriver = class {
6353
6799
  ...registryCollection
6354
6800
  } : collection;
6355
6801
  const callbacks = resolvedCollection?.callbacks;
6802
+ const globalCallbacks = this.registry?.getGlobalCallbacks();
6356
6803
  const properties = resolvedCollection?.properties;
6357
6804
  let propertyCallbacks;
6358
6805
  if (properties) propertyCallbacks = buildPropertyCallbacks(properties);
6359
6806
  return {
6360
6807
  collection: resolvedCollection,
6361
6808
  callbacks,
6809
+ globalCallbacks,
6362
6810
  propertyCallbacks
6363
6811
  };
6364
6812
  }
@@ -6374,11 +6822,17 @@ var PostgresBackendDriver = class {
6374
6822
  searchString,
6375
6823
  vectorSearch
6376
6824
  });
6377
- const { collection: resolvedCollection, callbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, path);
6378
- if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
6825
+ const { collection: resolvedCollection, callbacks, globalCallbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, path);
6826
+ if (globalCallbacks?.afterRead || callbacks?.afterRead || propertyCallbacks?.afterRead) {
6379
6827
  const contextForCallback = this.buildCallContext();
6380
6828
  return Promise.all(entities.map(async (entity) => {
6381
6829
  let fetched = entity;
6830
+ if (globalCallbacks?.afterRead) fetched = await globalCallbacks.afterRead({
6831
+ collection: resolvedCollection,
6832
+ path,
6833
+ entity: fetched,
6834
+ context: contextForCallback
6835
+ });
6382
6836
  if (callbacks?.afterRead) fetched = await callbacks.afterRead({
6383
6837
  collection: resolvedCollection,
6384
6838
  path,
@@ -6390,7 +6844,7 @@ var PostgresBackendDriver = class {
6390
6844
  path,
6391
6845
  entity: fetched,
6392
6846
  context: contextForCallback
6393
- }) ?? fetched;
6847
+ });
6394
6848
  return fetched;
6395
6849
  }));
6396
6850
  }
@@ -6439,21 +6893,27 @@ var PostgresBackendDriver = class {
6439
6893
  }
6440
6894
  async fetchEntity({ path, entityId, databaseId, collection }) {
6441
6895
  let entity = await this.entityService.fetchEntity(path, entityId, databaseId || collection?.databaseId);
6442
- const { collection: resolvedCollection, callbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, path);
6443
- if (entity && (callbacks?.afterRead || propertyCallbacks?.afterRead)) {
6896
+ const { collection: resolvedCollection, callbacks, globalCallbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, path);
6897
+ if (entity && (globalCallbacks?.afterRead || callbacks?.afterRead || propertyCallbacks?.afterRead)) {
6444
6898
  const contextForCallback = this.buildCallContext();
6899
+ if (globalCallbacks?.afterRead) entity = await globalCallbacks.afterRead({
6900
+ collection: resolvedCollection,
6901
+ path,
6902
+ entity,
6903
+ context: contextForCallback
6904
+ });
6445
6905
  if (callbacks?.afterRead) entity = await callbacks.afterRead({
6446
6906
  collection: resolvedCollection,
6447
6907
  path,
6448
6908
  entity,
6449
6909
  context: contextForCallback
6450
- }) ?? entity;
6910
+ });
6451
6911
  if (propertyCallbacks?.afterRead) entity = await propertyCallbacks.afterRead({
6452
6912
  collection: resolvedCollection,
6453
6913
  path,
6454
6914
  entity,
6455
6915
  context: contextForCallback
6456
- }) ?? entity;
6916
+ });
6457
6917
  }
6458
6918
  return entity;
6459
6919
  }
@@ -6484,7 +6944,7 @@ var PostgresBackendDriver = class {
6484
6944
  };
6485
6945
  }
6486
6946
  async saveEntity({ path, entityId, values, collection, status }) {
6487
- const { collection: resolvedCollection, callbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, path);
6947
+ const { collection: resolvedCollection, callbacks, globalCallbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, path);
6488
6948
  let updatedValues = values;
6489
6949
  const contextForCallback = this.buildCallContext();
6490
6950
  let previousValuesForHistory;
@@ -6492,7 +6952,19 @@ var PostgresBackendDriver = class {
6492
6952
  const existing = await this.entityService.fetchEntity(path, entityId, resolvedCollection?.databaseId);
6493
6953
  if (existing) previousValuesForHistory = existing.values;
6494
6954
  }
6495
- if (callbacks?.beforeSave || propertyCallbacks?.beforeSave) {
6955
+ if (globalCallbacks?.beforeSave || callbacks?.beforeSave || propertyCallbacks?.beforeSave) {
6956
+ if (globalCallbacks?.beforeSave) {
6957
+ const result = await globalCallbacks.beforeSave({
6958
+ collection: resolvedCollection,
6959
+ path,
6960
+ entityId,
6961
+ values: updatedValues,
6962
+ previousValues: previousValuesForHistory,
6963
+ status,
6964
+ context: contextForCallback
6965
+ });
6966
+ if (result) updatedValues = mergeDeep(updatedValues, result);
6967
+ }
6496
6968
  if (callbacks?.beforeSave) {
6497
6969
  const result = await callbacks.beforeSave({
6498
6970
  collection: resolvedCollection,
@@ -6526,7 +6998,13 @@ var PostgresBackendDriver = class {
6526
6998
  });
6527
6999
  try {
6528
7000
  let savedEntity = await this.entityService.saveEntity(path, updatedValues, entityId, resolvedCollection?.databaseId);
6529
- if (savedEntity && (callbacks?.afterRead || propertyCallbacks?.afterRead)) {
7001
+ if (savedEntity && (globalCallbacks?.afterRead || callbacks?.afterRead || propertyCallbacks?.afterRead)) {
7002
+ if (globalCallbacks?.afterRead) savedEntity = await globalCallbacks.afterRead({
7003
+ collection: resolvedCollection,
7004
+ path,
7005
+ entity: savedEntity,
7006
+ context: contextForCallback
7007
+ });
6530
7008
  if (callbacks?.afterRead) savedEntity = await callbacks.afterRead({
6531
7009
  collection: resolvedCollection,
6532
7010
  path,
@@ -6538,9 +7016,18 @@ var PostgresBackendDriver = class {
6538
7016
  path,
6539
7017
  entity: savedEntity,
6540
7018
  context: contextForCallback
6541
- }) ?? savedEntity;
7019
+ });
6542
7020
  }
6543
- if (callbacks?.afterSave || propertyCallbacks?.afterSave) {
7021
+ if (globalCallbacks?.afterSave || callbacks?.afterSave || propertyCallbacks?.afterSave) {
7022
+ if (globalCallbacks?.afterSave) await globalCallbacks.afterSave({
7023
+ collection: resolvedCollection,
7024
+ path,
7025
+ entityId: savedEntity.id,
7026
+ values: savedEntity.values,
7027
+ previousValues: previousValuesForHistory,
7028
+ status,
7029
+ context: contextForCallback
7030
+ });
6544
7031
  if (callbacks?.afterSave) await callbacks.afterSave({
6545
7032
  collection: resolvedCollection,
6546
7033
  path,
@@ -6577,7 +7064,16 @@ var PostgresBackendDriver = class {
6577
7064
  else await this.realtimeService.notifyEntityUpdate(path, savedEntity.id.toString(), savedEntity, resolvedCollection?.databaseId);
6578
7065
  return savedEntity;
6579
7066
  } catch (error) {
6580
- if (callbacks?.afterSaveError || propertyCallbacks?.afterSaveError) {
7067
+ if (globalCallbacks?.afterSaveError || callbacks?.afterSaveError || propertyCallbacks?.afterSaveError) {
7068
+ if (globalCallbacks?.afterSaveError) await globalCallbacks.afterSaveError({
7069
+ collection: resolvedCollection,
7070
+ path,
7071
+ entityId: entityId || "unknown",
7072
+ values: updatedValues,
7073
+ previousValues: void 0,
7074
+ status,
7075
+ context: contextForCallback
7076
+ });
6581
7077
  if (callbacks?.afterSaveError) await callbacks.afterSaveError({
6582
7078
  collection: resolvedCollection,
6583
7079
  path,
@@ -6601,10 +7097,19 @@ var PostgresBackendDriver = class {
6601
7097
  }
6602
7098
  }
6603
7099
  async deleteEntity({ entity, collection }) {
6604
- const { collection: resolvedCollection, callbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, entity.path);
7100
+ const { collection: resolvedCollection, callbacks, globalCallbacks, propertyCallbacks } = this.resolveCollectionCallbacks(collection, entity.path);
6605
7101
  const contextForCallback = this.buildCallContext();
6606
- if (callbacks?.beforeDelete || propertyCallbacks?.beforeDelete) {
7102
+ if (globalCallbacks?.beforeDelete || callbacks?.beforeDelete || propertyCallbacks?.beforeDelete) {
6607
7103
  let preventDefault = false;
7104
+ if (globalCallbacks?.beforeDelete) {
7105
+ if (await globalCallbacks.beforeDelete({
7106
+ collection: resolvedCollection,
7107
+ path: entity.path,
7108
+ entityId: entity.id,
7109
+ entity,
7110
+ context: contextForCallback
7111
+ }) === false) preventDefault = true;
7112
+ }
6608
7113
  if (callbacks?.beforeDelete) {
6609
7114
  if (await callbacks.beforeDelete({
6610
7115
  collection: resolvedCollection,
@@ -6626,7 +7131,14 @@ var PostgresBackendDriver = class {
6626
7131
  if (preventDefault) return;
6627
7132
  }
6628
7133
  await this.entityService.deleteEntity(entity.path, entity.id, entity.databaseId || resolvedCollection?.databaseId);
6629
- if (callbacks?.afterDelete || propertyCallbacks?.afterDelete) {
7134
+ if (globalCallbacks?.afterDelete || callbacks?.afterDelete || propertyCallbacks?.afterDelete) {
7135
+ if (globalCallbacks?.afterDelete) await globalCallbacks.afterDelete({
7136
+ collection: resolvedCollection,
7137
+ path: entity.path,
7138
+ entityId: entity.id,
7139
+ entity,
7140
+ context: contextForCallback
7141
+ });
6630
7142
  if (callbacks?.afterDelete) await callbacks.afterDelete({
6631
7143
  collection: resolvedCollection,
6632
7144
  path: entity.path,
@@ -6676,11 +7188,11 @@ var PostgresBackendDriver = class {
6676
7188
  return this.poolManager.getDrizzle(databaseName);
6677
7189
  }
6678
7190
  async executeSql(sqlText, options) {
6679
- if (!options?.database && !options?.role) return this.entityService.executeSql(sqlText);
7191
+ if (!options?.database && !options?.role) return this.entityService.executeSql(sqlText, options?.params);
6680
7192
  const targetDb = this.getTargetDb(options?.database);
6681
7193
  try {
6682
7194
  let needsRoleSwitch = false;
6683
- if (options?.role && process.env.DISABLE_DB_ROLE_SWITCHING !== "true") try {
7195
+ if (options?.role && process.env.DISABLE_DB_ROLE_SWITCHING !== "true" && !this._roleSwitchingDisabled) try {
6684
7196
  const currentRole = ((await targetDb.execute(sql.raw("SELECT current_user AS role"))).rows?.[0])?.role;
6685
7197
  needsRoleSwitch = !!currentRole && currentRole !== options.role;
6686
7198
  } catch {
@@ -6688,12 +7200,37 @@ var PostgresBackendDriver = class {
6688
7200
  }
6689
7201
  if (needsRoleSwitch && options?.role) {
6690
7202
  const safeRole = options.role.replace(/"/g, "\"\"");
6691
- return await targetDb.transaction(async (tx) => {
6692
- await tx.execute(sql.raw(`SET LOCAL ROLE "${safeRole}"`));
6693
- return (await tx.execute(sql.raw(sqlText))).rows;
6694
- });
7203
+ try {
7204
+ return await targetDb.transaction(async (tx) => {
7205
+ await tx.execute(sql.raw(`SET LOCAL ROLE "${safeRole}"`));
7206
+ let result;
7207
+ if (options?.params && options.params.length > 0) {
7208
+ const parts = sqlText.split(/\$(\d+)/);
7209
+ const chunks = [];
7210
+ for (let i = 0; i < parts.length; i++) if (i % 2 === 0) {
7211
+ if (parts[i].length > 0) chunks.push(sql.raw(parts[i]));
7212
+ } else chunks.push(sql.param(options.params[Number(parts[i]) - 1]));
7213
+ result = await tx.execute(sql.join(chunks, sql.raw("")));
7214
+ } else result = await tx.execute(sql.raw(sqlText));
7215
+ return result.rows;
7216
+ });
7217
+ } catch (roleError) {
7218
+ if (isRoleSwitchingPermissionError(roleError)) {
7219
+ logger.warn(`[PostgresBackendDriver] SET LOCAL ROLE "${safeRole}" failed — the connection user lacks permission. Falling back to executing without role switching. To suppress this warning, set DISABLE_DB_ROLE_SWITCHING=true in your .env file.`);
7220
+ this._roleSwitchingDisabled = true;
7221
+ } else throw roleError;
7222
+ }
6695
7223
  }
6696
- return (await targetDb.execute(sql.raw(sqlText))).rows;
7224
+ let result;
7225
+ if (options?.params && options.params.length > 0) {
7226
+ const parts = sqlText.split(/\$(\d+)/);
7227
+ const chunks = [];
7228
+ for (let i = 0; i < parts.length; i++) if (i % 2 === 0) {
7229
+ if (parts[i].length > 0) chunks.push(sql.raw(parts[i]));
7230
+ } else chunks.push(sql.param(options.params[Number(parts[i]) - 1]));
7231
+ result = await targetDb.execute(sql.join(chunks, sql.raw("")));
7232
+ } else result = await targetDb.execute(sql.raw(sqlText));
7233
+ return result.rows;
6697
7234
  } catch (error) {
6698
7235
  const msg = error instanceof Error ? error.message : String(error);
6699
7236
  if (msg.includes("pg_hba.conf") || msg.includes("no encryption") || msg.includes("connection refused")) {
@@ -6731,53 +7268,16 @@ var PostgresBackendDriver = class {
6731
7268
  * and junction/connection tables used for many-to-many relations.
6732
7269
  */
6733
7270
  async fetchUnmappedTables(mappedPaths) {
6734
- const result = await this.executeSql(`
7271
+ const allTables = (await this.executeSql(`
6735
7272
  SELECT table_name
6736
7273
  FROM information_schema.tables
6737
7274
  WHERE table_schema = 'public'
6738
7275
  AND table_type = 'BASE TABLE'
6739
7276
  ORDER BY table_name;
6740
- `);
6741
- const internalPrefixes = ["_rebase_", "_auth_"];
6742
- const internalExact = [
6743
- "users",
6744
- "roles",
6745
- "user_roles",
6746
- "refresh_tokens",
6747
- "password_reset_tokens",
6748
- "email_verification_tokens"
6749
- ];
6750
- const allTables = result.map((r) => r.table_name).filter((name) => {
6751
- if (internalPrefixes.some((prefix) => name.startsWith(prefix))) return false;
6752
- if (internalExact.includes(name)) return false;
6753
- return true;
6754
- });
7277
+ `)).map((r) => r.table_name).filter((name) => classifyTable(name, "public") !== "rebase-internal");
6755
7278
  let junctionTables = /* @__PURE__ */ new Set();
6756
7279
  try {
6757
- const junctionResult = await this.executeSql(`
6758
- SELECT t.table_name
6759
- FROM information_schema.tables t
6760
- WHERE t.table_schema = 'public'
6761
- AND t.table_type = 'BASE TABLE'
6762
- AND NOT EXISTS (
6763
- -- Find columns that are NOT part of any foreign key
6764
- SELECT 1
6765
- FROM information_schema.columns c
6766
- WHERE c.table_schema = t.table_schema
6767
- AND c.table_name = t.table_name
6768
- AND c.column_name NOT IN (
6769
- SELECT kcu.column_name
6770
- FROM information_schema.key_column_usage kcu
6771
- JOIN information_schema.table_constraints tc
6772
- ON tc.constraint_name = kcu.constraint_name
6773
- AND tc.table_schema = kcu.table_schema
6774
- WHERE tc.constraint_type = 'FOREIGN KEY'
6775
- AND kcu.table_schema = t.table_schema
6776
- AND kcu.table_name = t.table_name
6777
- )
6778
- );
6779
- `);
6780
- junctionTables = new Set(junctionResult.map((r) => r.table_name));
7280
+ junctionTables = await detectJunctionTables(this.executeSql.bind(this));
6781
7281
  } catch (e) {
6782
7282
  logger.warn("Could not detect junction tables", { error: e });
6783
7283
  }
@@ -7146,6 +7646,14 @@ function createAuthSchema(usersSchemaName = "rebase") {
7146
7646
  codeHash: varchar("code_hash", { length: 255 }).notNull(),
7147
7647
  usedAt: timestamp("used_at"),
7148
7648
  createdAt: timestamp("created_at").defaultNow().notNull()
7649
+ }),
7650
+ magicLinkTokens: tableCreator("magic_link_tokens", {
7651
+ id: uuid("id").defaultRandom().primaryKey(),
7652
+ userId: uuid("user_id").notNull().references(() => users.id, { onDelete: "cascade" }),
7653
+ tokenHash: varchar("token_hash", { length: 255 }).notNull().unique(),
7654
+ expiresAt: timestamp("expires_at").notNull(),
7655
+ usedAt: timestamp("used_at"),
7656
+ createdAt: timestamp("created_at").defaultNow().notNull()
7149
7657
  })
7150
7658
  };
7151
7659
  }
@@ -7159,12 +7667,14 @@ var userIdentities = defaultAuthSchema.userIdentities;
7159
7667
  var mfaFactors = defaultAuthSchema.mfaFactors;
7160
7668
  var mfaChallenges = defaultAuthSchema.mfaChallenges;
7161
7669
  var recoveryCodes = defaultAuthSchema.recoveryCodes;
7670
+ var magicLinkTokens = defaultAuthSchema.magicLinkTokens;
7162
7671
  var usersRelations = relations(users, ({ many }) => ({
7163
7672
  refreshTokens: many(refreshTokens),
7164
7673
  passwordResetTokens: many(passwordResetTokens),
7165
7674
  userIdentities: many(userIdentities),
7166
7675
  mfaFactors: many(mfaFactors),
7167
- recoveryCodes: many(recoveryCodes)
7676
+ recoveryCodes: many(recoveryCodes),
7677
+ magicLinkTokens: many(magicLinkTokens)
7168
7678
  }));
7169
7679
  var refreshTokensRelations = relations(refreshTokens, ({ one }) => ({ user: one(users, {
7170
7680
  fields: [refreshTokens.userId],
@@ -7193,6 +7703,93 @@ var recoveryCodesRelations = relations(recoveryCodes, ({ one }) => ({ user: one(
7193
7703
  fields: [recoveryCodes.userId],
7194
7704
  references: [users.id]
7195
7705
  }) }));
7706
+ var magicLinkTokensRelations = relations(magicLinkTokens, ({ one }) => ({ user: one(users, {
7707
+ fields: [magicLinkTokens.userId],
7708
+ references: [users.id]
7709
+ }) }));
7710
+ //#endregion
7711
+ //#region src/schema/auth-default-policies.ts
7712
+ /**
7713
+ * Default RLS for authentication collections.
7714
+ *
7715
+ * Users are persisted through the same write path as any other collection —
7716
+ * the only thing that distinguishes them is the `auth` flag. That means
7717
+ * privileged columns (most importantly `roles`) would be editable by any
7718
+ * authenticated user unless the collection author remembers to write a correct
7719
+ * admin-only write policy.
7720
+ *
7721
+ * To make this safe by default, the schema generator injects two policies for
7722
+ * every write operation on an auth collection. Enforcement lives in the
7723
+ * database (RLS), so it applies to every write path — REST, WebSocket, and any
7724
+ * internal caller — not just one entry point:
7725
+ *
7726
+ * 1. A **restrictive** admin gate. Restrictive policies are AND'd with every
7727
+ * other policy, so this guarantees a write is rejected unless the caller is
7728
+ * an admin (or the trusted server context) — even if the author also wrote
7729
+ * a permissive rule such as "a user may edit their own row". Without this,
7730
+ * a permissive owner rule would let a user change their own `roles`.
7731
+ *
7732
+ * 2. A **permissive** admin grant. Restrictive policies only constrain; at
7733
+ * least one permissive policy must also pass for the write to be allowed.
7734
+ * This grants the baseline write so admins (and the server context) can
7735
+ * manage users even when the collection has no other permissive write rule.
7736
+ *
7737
+ * Both mirror the framework's trusted-server convention: the write is allowed
7738
+ * when there is no authenticated user context (`auth.uid() IS NULL`, used by
7739
+ * the built-in auth flows that run as the service role) OR the caller holds the
7740
+ * `admin` role. Net effect: only admins (or the server) can write the row, and
7741
+ * therefore only admins can change privileged columns like `roles`.
7742
+ *
7743
+ * Author-provided write rules are preserved but cannot loosen this guarantee —
7744
+ * a non-admin write is always blocked by the restrictive gate. To take full
7745
+ * control of an auth collection's write authorization, set
7746
+ * `disableDefaultAuthPolicies: true` on the collection.
7747
+ */
7748
+ var ADMIN_WRITE_EXPR = policy.or(policy.not(policy.authenticated()), policy.rolesOverlap(["admin"]));
7749
+ /** Write operations that must be admin-gated by default on auth collections. */
7750
+ var DEFAULT_GUARDED_OPS = [
7751
+ "insert",
7752
+ "update",
7753
+ "delete"
7754
+ ];
7755
+ /** Whether a collection is flagged as an authentication collection. */
7756
+ function isAuthCollection(collection) {
7757
+ const auth = collection.auth;
7758
+ return auth === true || typeof auth === "object" && auth?.enabled === true;
7759
+ }
7760
+ /**
7761
+ * Returns the security rules that should be applied to a collection: the
7762
+ * author's explicit `securityRules`, plus, for auth collections, an
7763
+ * auto-injected restrictive admin gate and permissive admin grant on every
7764
+ * write operation. Together these guarantee only admins (or the trusted server
7765
+ * context) can write the row.
7766
+ *
7767
+ * Non-auth collections, and auth collections that opt out via
7768
+ * `disableDefaultAuthPolicies`, are returned unchanged.
7769
+ */
7770
+ function getEffectiveSecurityRules(collection) {
7771
+ const explicit = (isPostgresCollection(collection) ? collection.securityRules : void 0) ?? [];
7772
+ if (!isAuthCollection(collection) || collection.disableDefaultAuthPolicies) return explicit;
7773
+ const tableName = getTableName$1(collection);
7774
+ const requireAdminGate = {
7775
+ name: `${tableName}_require_admin_write`,
7776
+ mode: "restrictive",
7777
+ operations: [...DEFAULT_GUARDED_OPS],
7778
+ condition: ADMIN_WRITE_EXPR,
7779
+ check: ADMIN_WRITE_EXPR
7780
+ };
7781
+ const allowAdminWrite = {
7782
+ name: `${tableName}_default_admin_write`,
7783
+ operations: [...DEFAULT_GUARDED_OPS],
7784
+ condition: ADMIN_WRITE_EXPR,
7785
+ check: ADMIN_WRITE_EXPR
7786
+ };
7787
+ return [
7788
+ ...explicit,
7789
+ allowAdminWrite,
7790
+ requireAdminGate
7791
+ ];
7792
+ }
7196
7793
  //#endregion
7197
7794
  //#region src/schema/generate-drizzle-schema-logic.ts
7198
7795
  /**
@@ -7269,7 +7866,7 @@ var getDrizzleColumn = (propName, prop, collection, collections) => {
7269
7866
  if (stringProp.enum) columnDefinition = `${getEnumVarName(getTableName$1(collection), propName)}("${colName}")`;
7270
7867
  else if ("isId" in stringProp && stringProp.isId === "uuid") columnDefinition = `uuid("${colName}")`;
7271
7868
  else if (stringProp.columnType === "uuid") columnDefinition = `uuid("${colName}")`;
7272
- else if (stringProp.columnType === "text") columnDefinition = `text("${colName}")`;
7869
+ else if (stringProp.columnType === "text" || stringProp.ui?.markdown || stringProp.ui?.multiline) columnDefinition = `text("${colName}")`;
7273
7870
  else if (stringProp.columnType === "char") columnDefinition = `char("${colName}")`;
7274
7871
  else columnDefinition = `varchar("${colName}")`;
7275
7872
  if (isIdProperty(propName, prop, collection)) columnDefinition += ".primaryKey()";
@@ -7388,47 +7985,9 @@ var getDrizzleColumn = (propName, prop, collection, collections) => {
7388
7985
  return ` ${propName}: ${columnDefinition}`;
7389
7986
  };
7390
7987
  /**
7391
- * Resolves a raw SQL string, replacing `{column_name}` with `${table.column_name}`.
7392
- * The result is wrapped in a Drizzle sql`` template literal.
7393
- */
7394
- var resolveRawSql = (expression) => {
7395
- return `sql\`${expression.replace(/\{(\w+)\}/g, (_, col) => col)}\``;
7396
- };
7397
- /**
7398
- * Wraps a SQL clause with a role check using AND.
7399
- * Generates: `(<clause>) AND (string_to_array(auth.roles(), ',') && ARRAY['<role1>','<role2>'])`
7400
- */
7401
- var wrapWithRoleCheck = (clause, roles) => {
7402
- const roleCondition = `string_to_array(auth.roles(), ',') && ${`ARRAY[${roles.map((r) => `'${r}'`).join(",")}]`}`;
7403
- return `sql\`(${unwrapSql(clause)}) AND (${roleCondition})\``;
7404
- };
7405
- /**
7406
- * Extracts the inner expression from a `sql\`...\`` wrapper.
7407
- */
7408
- var unwrapSql = (sqlExpr) => {
7409
- const match = sqlExpr.match(/^sql`(.*)`$/s);
7410
- return match ? match[1] : sqlExpr;
7411
- };
7412
- /**
7413
- * Builds the USING clause for a policy based on shortcuts or raw SQL.
7414
- */
7415
- var buildUsingClause = (rule, collection) => {
7416
- if (rule.using) return resolveRawSql(rule.using);
7417
- if (rule.access === "public") return "sql`true`";
7418
- if (rule.ownerField) {
7419
- const prop = collection.properties?.[rule.ownerField];
7420
- return `sql\`${resolveColumnName(rule.ownerField, prop)} = auth.uid()\``;
7421
- }
7422
- return null;
7423
- };
7424
- /**
7425
- * Builds the WITH CHECK clause for a policy based on shortcuts or raw SQL.
7426
- * Falls back to the USING clause if not explicitly provided.
7988
+ * Wraps a compiled SQL clause in a Drizzle `sql\`...\`` template literal.
7427
7989
  */
7428
- var buildWithCheckClause = (rule, collection) => {
7429
- if (rule.withCheck) return resolveRawSql(rule.withCheck);
7430
- return buildUsingClause(rule, collection);
7431
- };
7990
+ var wrapSql = (clause) => `sql\`${clause}\``;
7432
7991
  /**
7433
7992
  * Generates a deterministic hash based on the rule configuration.
7434
7993
  */
@@ -7442,7 +8001,9 @@ var getPolicyNameHash = (rule) => {
7442
8001
  rol: rule.roles?.slice().sort(),
7443
8002
  pg: rule.pgRoles?.slice().sort(),
7444
8003
  u: rule.using,
7445
- w: rule.withCheck
8004
+ w: rule.withCheck,
8005
+ c: rule.condition,
8006
+ ch: rule.check
7446
8007
  });
7447
8008
  return createHash("sha1").update(data).digest("hex").substring(0, 7);
7448
8009
  };
@@ -7469,17 +8030,11 @@ var generatePolicyCode = (collection, rule, index) => {
7469
8030
  */
7470
8031
  var generateSinglePolicyCode = (collection, rule, operation, policyName) => {
7471
8032
  const mode = rule.mode ?? "permissive";
7472
- const roles = rule.roles ? [...rule.roles].sort() : void 0;
7473
8033
  const needsUsing = operation !== "insert";
7474
8034
  const needsWithCheck = operation !== "select" && operation !== "delete";
7475
- let usingClause = needsUsing ? buildUsingClause(rule, collection) : null;
7476
- let withCheckClause = needsWithCheck ? buildWithCheckClause(rule, collection) : null;
7477
- if (roles && roles.length > 0) {
7478
- if (usingClause) usingClause = wrapWithRoleCheck(usingClause, roles);
7479
- else if (needsUsing) usingClause = `sql\`string_to_array(auth.roles(), ',') && ${`ARRAY[${roles.map((r) => `'${r}'`).join(",")}]`}\``;
7480
- if (withCheckClause) withCheckClause = wrapWithRoleCheck(withCheckClause, roles);
7481
- else if (needsWithCheck) withCheckClause = `sql\`string_to_array(auth.roles(), ',') && ${`ARRAY[${roles.map((r) => `'${r}'`).join(",")}]`}\``;
7482
- }
8035
+ const { usingExpr, withCheckExpr } = securityRuleToConditions(rule);
8036
+ let usingClause = needsUsing && usingExpr ? wrapSql(policyToPostgres(usingExpr, collection)) : null;
8037
+ let withCheckClause = needsWithCheck && withCheckExpr ? wrapSql(policyToPostgres(withCheckExpr, collection)) : null;
7483
8038
  if (!usingClause && needsUsing) usingClause = "sql`false`";
7484
8039
  if (!withCheckClause && needsWithCheck) withCheckClause = "sql`false`";
7485
8040
  const parts = [];
@@ -7587,7 +8142,7 @@ var generateSchema = async (collections, stripPolicies = false) => {
7587
8142
  if ("enum" in prop && (prop.type === "string" || prop.type === "number") && prop.enum) {
7588
8143
  const enumVarName = getEnumVarName(collectionPath, propName);
7589
8144
  const enumDbName = `${collectionPath}_${resolveColumnName(propName, prop)}`;
7590
- const values = Array.isArray(prop.enum) ? prop.enum.map((v) => String(v.id ?? v)) : Object.keys(prop.enum);
8145
+ const values = Array.isArray(prop.enum) ? prop.enum.map((v) => String(typeof v === "object" && v !== null && "id" in v ? v.id : v)) : Object.keys(prop.enum);
7591
8146
  if (values.length > 0) {
7592
8147
  schemaContent += `export const ${enumVarName} = pgEnum(\"${enumDbName}\", [${values.map((v) => `'${v}'`).join(", ")}]);\n`;
7593
8148
  if (!exportedEnumVars.includes(enumVarName)) exportedEnumVars.push(enumVarName);
@@ -7644,8 +8199,8 @@ var generateSchema = async (collections, stripPolicies = false) => {
7644
8199
  });
7645
8200
  if (!Array.from(columns).some((col) => col.includes(".primaryKey()"))) columns.add(" id: varchar(\"id\").primaryKey()");
7646
8201
  schemaContent += `${Array.from(columns).join(",\n")}`;
7647
- const securityRules = isPostgresCollection(collection) ? collection.securityRules : void 0;
7648
- if (!stripPolicies && securityRules && securityRules.length > 0) {
8202
+ const securityRules = getEffectiveSecurityRules(collection);
8203
+ if (!stripPolicies && securityRules.length > 0) {
7649
8204
  schemaContent += "\n}, (table) => ([\n";
7650
8205
  securityRules.forEach((rule, idx) => {
7651
8206
  schemaContent += generatePolicyCode(collection, rule, idx);
@@ -7781,8 +8336,7 @@ var runGeneration = async (collectionsFilePath, outputPath) => {
7781
8336
  for (const file of files) if ((file.endsWith(".ts") || file.endsWith(".js")) && !file.includes(".test.") && !file.endsWith(".d.ts") && file !== "index.ts" && file !== "index.js") {
7782
8337
  const filePath = path.join(resolvedPath, file);
7783
8338
  try {
7784
- const fileUrl = pathToFileURL(filePath).href;
7785
- const module = await new Function("url", "return import(url)")(fileUrl);
8339
+ const module = await import(pathToFileURL(filePath).href);
7786
8340
  if (module && module.default) collections.push(module.default);
7787
8341
  } catch (err) {
7788
8342
  const message = err instanceof Error ? err.message : String(err);
@@ -7790,8 +8344,7 @@ var runGeneration = async (collectionsFilePath, outputPath) => {
7790
8344
  }
7791
8345
  }
7792
8346
  } else {
7793
- const fileUrl = pathToFileURL(resolvedPath).href + `?t=${Date.now()}`;
7794
- const imported = await new Function("url", "return import(url)")(fileUrl);
8347
+ const imported = await import(pathToFileURL(resolvedPath).href + `?t=${Date.now()}`);
7795
8348
  collections = imported.backendCollections || imported.collections;
7796
8349
  }
7797
8350
  if (!collections || !Array.isArray(collections)) collections = [];
@@ -7801,7 +8354,7 @@ var runGeneration = async (collectionsFilePath, outputPath) => {
7801
8354
  const outputDir = path.dirname(outputPath);
7802
8355
  await promises.mkdir(outputDir, { recursive: true });
7803
8356
  await promises.writeFile(outputPath, schemaContent);
7804
- logger.info("✅ Drizzle schema generated successfully at", { detail: outputPath });
8357
+ logger.info(`✅ Drizzle schema generated successfully at ${outputPath}`);
7805
8358
  } else {
7806
8359
  logger.info("✅ Drizzle schema generated successfully.");
7807
8360
  logger.info(String(schemaContent));
@@ -8236,8 +8789,9 @@ var RealtimeService = class RealtimeService extends EventEmitter {
8236
8789
  ...registryCollection
8237
8790
  } : registryCollection;
8238
8791
  const callbacks = resolvedCollection?.callbacks;
8792
+ const globalCallbacks = this.registry?.getGlobalCallbacks();
8239
8793
  const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
8240
- if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
8794
+ if (globalCallbacks?.afterRead || callbacks?.afterRead || propertyCallbacks?.afterRead) {
8241
8795
  const contextForCallback = {
8242
8796
  user: {
8243
8797
  uid: activeAuth.userId,
@@ -8248,6 +8802,12 @@ var RealtimeService = class RealtimeService extends EventEmitter {
8248
8802
  };
8249
8803
  return await Promise.all(fetchedEntities.map(async (entity) => {
8250
8804
  let processedEntity = entity;
8805
+ if (globalCallbacks?.afterRead) processedEntity = await globalCallbacks.afterRead({
8806
+ collection: resolvedCollection,
8807
+ path: notifyPath,
8808
+ entity: processedEntity,
8809
+ context: contextForCallback
8810
+ }) ?? processedEntity;
8251
8811
  if (callbacks?.afterRead) processedEntity = await callbacks.afterRead({
8252
8812
  collection: resolvedCollection,
8253
8813
  path: notifyPath,
@@ -8344,8 +8904,9 @@ var RealtimeService = class RealtimeService extends EventEmitter {
8344
8904
  ...registryCollection
8345
8905
  } : registryCollection;
8346
8906
  const callbacks = resolvedCollection?.callbacks;
8907
+ const globalCallbacks = this.registry?.getGlobalCallbacks();
8347
8908
  const propertyCallbacks = resolvedCollection?.properties ? buildPropertyCallbacks(resolvedCollection.properties) : void 0;
8348
- if (callbacks?.afterRead || propertyCallbacks?.afterRead) {
8909
+ if (globalCallbacks?.afterRead || callbacks?.afterRead || propertyCallbacks?.afterRead) {
8349
8910
  const contextForCallback = {
8350
8911
  user: {
8351
8912
  uid: activeAuth.userId,
@@ -8354,6 +8915,12 @@ var RealtimeService = class RealtimeService extends EventEmitter {
8354
8915
  driver: this.driver,
8355
8916
  data: this.driver && "data" in this.driver ? this.driver.data : void 0
8356
8917
  };
8918
+ if (globalCallbacks?.afterRead) processedEntity = await globalCallbacks.afterRead({
8919
+ collection: resolvedCollection,
8920
+ path: notifyPath,
8921
+ entity: processedEntity,
8922
+ context: contextForCallback
8923
+ }) ?? processedEntity;
8357
8924
  if (callbacks?.afterRead) processedEntity = await callbacks.afterRead({
8358
8925
  collection: resolvedCollection,
8359
8926
  path: notifyPath,
@@ -8967,6 +9534,15 @@ function createPostgresWebSocket(server, realtimeService, driver, authConfig, au
8967
9534
  }
8968
9535
  const result = await admin.executeSql(sql, options);
8969
9536
  if (process.env.NODE_ENV !== "production") wsDebug(`⚡ [WebSocket Server] SQL executed. Returned ${Array.isArray(result) ? result.length : "non-array"} rows.`);
9537
+ const auditSession = clientSessions.get(clientId);
9538
+ console.log("[SQL Audit] WebSocket SQL execution", JSON.stringify({
9539
+ sql: typeof sql === "string" ? sql.substring(0, 500) : sql,
9540
+ options,
9541
+ resultRows: Array.isArray(result) ? result.length : "unknown",
9542
+ userId: auditSession?.user?.userId ?? "unknown",
9543
+ roles: auditSession?.user?.roles ?? [],
9544
+ isAdmin: auditSession?.user?.isAdmin ?? false
9545
+ }));
8970
9546
  const response = {
8971
9547
  type: "EXECUTE_SQL_SUCCESS",
8972
9548
  payload: { result },
@@ -9181,10 +9757,10 @@ var PostgresCollectionRegistry = class extends CollectionRegistry {
9181
9757
  return Array.from(this.tables.keys());
9182
9758
  }
9183
9759
  /**
9184
- * Finds collections assigned to a specific driver that do not have a registered table.
9760
+ * Finds collections assigned to a specific data source that do not have a registered table.
9185
9761
  */
9186
- getCollectionsWithoutTables(driverId = "(default)") {
9187
- return this.getCollections().filter((c) => c.driver === driverId || !c.driver && driverId === "(default)").filter((c) => !this.tables.has(getTableName$1(c)));
9762
+ getCollectionsWithoutTables(dataSourceKey = "(default)") {
9763
+ return this.getCollections().filter((c) => c.dataSource === dataSourceKey || !c.dataSource && dataSourceKey === "(default)").filter((c) => !this.tables.has(getTableName$1(c)));
9188
9764
  }
9189
9765
  registerEnums(enums) {
9190
9766
  Object.entries(enums).forEach(([name, value]) => this.enums.set(name, value));
@@ -9221,7 +9797,7 @@ var PostgresCollectionRegistry = class extends CollectionRegistry {
9221
9797
  */
9222
9798
  getRelationKeysForCollection(collectionPath) {
9223
9799
  const collection = this.getCollectionByPath(collectionPath);
9224
- if (!collection || !getDataSourceCapabilities(collection.driver).supportsRelations || !collection.relations) return [];
9800
+ if (!collection || !getDataSourceCapabilities(collection.engine).supportsRelations || !collection.relations) return [];
9225
9801
  return collection.relations.map((r) => r.relationName || r.localKey || "").filter(Boolean);
9226
9802
  }
9227
9803
  };
@@ -9277,6 +9853,24 @@ async function ensureAuthTablesExist(db, collection) {
9277
9853
  const refreshTokensTableName = `"${authSchema}"."refresh_tokens"`;
9278
9854
  const passwordResetTokensTableName = `"${authSchema}"."password_reset_tokens"`;
9279
9855
  const appConfigTableName = `"${authSchema}"."app_config"`;
9856
+ const idDefault = userIdType === "UUID" ? "DEFAULT gen_random_uuid()" : userIdType === "INTEGER" ? "GENERATED ALWAYS AS IDENTITY" : "DEFAULT gen_random_uuid()::text";
9857
+ await db.execute(sql`
9858
+ CREATE TABLE IF NOT EXISTS ${sql.raw(usersTableName)} (
9859
+ id ${sql.raw(userIdType)} PRIMARY KEY ${sql.raw(idDefault)},
9860
+ email VARCHAR(255) UNIQUE NOT NULL,
9861
+ display_name VARCHAR(255),
9862
+ photo_url VARCHAR(500),
9863
+ roles TEXT[] DEFAULT '{}' NOT NULL,
9864
+ password_hash VARCHAR(255),
9865
+ email_verified BOOLEAN DEFAULT FALSE NOT NULL,
9866
+ email_verification_token VARCHAR(255),
9867
+ email_verification_sent_at TIMESTAMP WITH TIME ZONE,
9868
+ is_anonymous BOOLEAN DEFAULT FALSE NOT NULL,
9869
+ metadata JSONB DEFAULT '{}' NOT NULL,
9870
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL,
9871
+ updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL
9872
+ )
9873
+ `);
9280
9874
  await db.execute(sql`
9281
9875
  CREATE TABLE IF NOT EXISTS ${sql.raw(userIdentitiesTable)} (
9282
9876
  id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
@@ -9330,6 +9924,25 @@ async function ensureAuthTablesExist(db, collection) {
9330
9924
  await db.execute(sql`
9331
9925
  CREATE INDEX IF NOT EXISTS idx_password_reset_tokens_user
9332
9926
  ON ${sql.raw(passwordResetTokensTableName)}(user_id)
9927
+ `);
9928
+ const magicLinkTokensTableName = `"${authSchema}"."magic_link_tokens"`;
9929
+ await db.execute(sql`
9930
+ CREATE TABLE IF NOT EXISTS ${sql.raw(magicLinkTokensTableName)} (
9931
+ id TEXT PRIMARY KEY DEFAULT gen_random_uuid()::text,
9932
+ user_id ${sql.raw(userIdType)} NOT NULL REFERENCES ${sql.raw(usersTableName)}(id) ON DELETE CASCADE,
9933
+ token_hash TEXT NOT NULL UNIQUE,
9934
+ expires_at TIMESTAMP WITH TIME ZONE NOT NULL,
9935
+ used_at TIMESTAMP WITH TIME ZONE,
9936
+ created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
9937
+ )
9938
+ `);
9939
+ await db.execute(sql`
9940
+ CREATE INDEX IF NOT EXISTS idx_magic_link_tokens_hash
9941
+ ON ${sql.raw(magicLinkTokensTableName)}(token_hash)
9942
+ `);
9943
+ await db.execute(sql`
9944
+ CREATE INDEX IF NOT EXISTS idx_magic_link_tokens_user
9945
+ ON ${sql.raw(magicLinkTokensTableName)}(user_id)
9333
9946
  `);
9334
9947
  await db.execute(sql`
9335
9948
  CREATE TABLE IF NOT EXISTS ${sql.raw(appConfigTableName)} (
@@ -9942,6 +10555,53 @@ var PasswordResetTokenService = class {
9942
10555
  }
9943
10556
  };
9944
10557
  /**
10558
+ * Magic link token service.
10559
+ * Handles magic link token storage for passwordless email login.
10560
+ */
10561
+ var MagicLinkTokenService = class {
10562
+ db;
10563
+ magicLinkTokensTable;
10564
+ constructor(db, tableOrTables) {
10565
+ this.db = db;
10566
+ this.magicLinkTokensTable = magicLinkTokens;
10567
+ }
10568
+ getQualifiedTableName() {
10569
+ const name = getTableName(this.magicLinkTokensTable);
10570
+ return `"${getTableConfig(this.magicLinkTokensTable).schema || "public"}"."${name}"`;
10571
+ }
10572
+ async createToken(userId, tokenHash, expiresAt) {
10573
+ const tableName = this.getQualifiedTableName();
10574
+ await this.db.execute(sql`
10575
+ DELETE FROM ${sql.raw(tableName)}
10576
+ WHERE user_id = ${userId} AND used_at IS NULL
10577
+ `);
10578
+ await this.db.insert(this.magicLinkTokensTable).values({
10579
+ userId,
10580
+ tokenHash,
10581
+ expiresAt
10582
+ });
10583
+ }
10584
+ async findValidByHash(tokenHash) {
10585
+ const tableName = this.getQualifiedTableName();
10586
+ const result = await this.db.execute(sql`
10587
+ SELECT user_id, expires_at
10588
+ FROM ${sql.raw(tableName)}
10589
+ WHERE token_hash = ${tokenHash}
10590
+ AND used_at IS NULL
10591
+ AND expires_at > NOW()
10592
+ `);
10593
+ if (result.rows.length === 0) return null;
10594
+ const row = result.rows[0];
10595
+ return {
10596
+ userId: row.user_id,
10597
+ expiresAt: new Date(row.expires_at)
10598
+ };
10599
+ }
10600
+ async markAsUsed(tokenHash) {
10601
+ await this.db.update(this.magicLinkTokensTable).set({ usedAt: /* @__PURE__ */ new Date() }).where(eq(this.magicLinkTokensTable.tokenHash, tokenHash));
10602
+ }
10603
+ };
10604
+ /**
9945
10605
  * PostgreSQL implementation of TokenRepository.
9946
10606
  * Combines refresh token and password reset token operations.
9947
10607
  */
@@ -9949,10 +10609,12 @@ var PostgresTokenRepository = class {
9949
10609
  db;
9950
10610
  refreshTokenService;
9951
10611
  passwordResetTokenService;
10612
+ magicLinkTokenService;
9952
10613
  constructor(db, tableOrTables) {
9953
10614
  this.db = db;
9954
10615
  this.refreshTokenService = new RefreshTokenService(db, tableOrTables);
9955
10616
  this.passwordResetTokenService = new PasswordResetTokenService(db, tableOrTables);
10617
+ this.magicLinkTokenService = new MagicLinkTokenService(db, tableOrTables);
9956
10618
  }
9957
10619
  async createRefreshToken(userId, tokenHash, expiresAt, userAgent, ipAddress) {
9958
10620
  await this.refreshTokenService.createToken(userId, tokenHash, expiresAt, userAgent, ipAddress);
@@ -9987,6 +10649,15 @@ var PostgresTokenRepository = class {
9987
10649
  async deleteExpiredTokens() {
9988
10650
  await this.passwordResetTokenService.deleteExpired();
9989
10651
  }
10652
+ async createMagicLinkToken(userId, tokenHash, expiresAt) {
10653
+ await this.magicLinkTokenService.createToken(userId, tokenHash, expiresAt);
10654
+ }
10655
+ async findValidMagicLinkToken(tokenHash) {
10656
+ return this.magicLinkTokenService.findValidByHash(tokenHash);
10657
+ }
10658
+ async markMagicLinkTokenUsed(tokenHash) {
10659
+ await this.magicLinkTokenService.markAsUsed(tokenHash);
10660
+ }
9990
10661
  };
9991
10662
  /**
9992
10663
  * PostgreSQL implementation of AuthRepository.
@@ -10145,6 +10816,15 @@ var PostgresAuthRepository = class {
10145
10816
  async deleteExpiredTokens() {
10146
10817
  await this.tokenRepository.deleteExpiredTokens();
10147
10818
  }
10819
+ async createMagicLinkToken(userId, tokenHash, expiresAt) {
10820
+ await this.tokenRepository.createMagicLinkToken(userId, tokenHash, expiresAt);
10821
+ }
10822
+ async findValidMagicLinkToken(tokenHash) {
10823
+ return this.tokenRepository.findValidMagicLinkToken(tokenHash);
10824
+ }
10825
+ async markMagicLinkTokenUsed(tokenHash) {
10826
+ await this.tokenRepository.markMagicLinkTokenUsed(tokenHash);
10827
+ }
10148
10828
  _mfaService = null;
10149
10829
  getMfaService() {
10150
10830
  if (!this._mfaService) this._mfaService = new MfaService(this.db);
@@ -10590,6 +11270,2071 @@ function patchPgArrayNullSafety(tables) {
10590
11270
  if (patchedCount > 0) logger.debug(`[PgArray] Patched ${patchedCount} array column(s) for null-safety`);
10591
11271
  }
10592
11272
  //#endregion
11273
+ //#region ../../node_modules/.pnpm/color-name@1.1.4/node_modules/color-name/index.js
11274
+ var require_color_name = /* @__PURE__ */ __commonJSMin(((exports, module) => {
11275
+ module.exports = {
11276
+ "aliceblue": [
11277
+ 240,
11278
+ 248,
11279
+ 255
11280
+ ],
11281
+ "antiquewhite": [
11282
+ 250,
11283
+ 235,
11284
+ 215
11285
+ ],
11286
+ "aqua": [
11287
+ 0,
11288
+ 255,
11289
+ 255
11290
+ ],
11291
+ "aquamarine": [
11292
+ 127,
11293
+ 255,
11294
+ 212
11295
+ ],
11296
+ "azure": [
11297
+ 240,
11298
+ 255,
11299
+ 255
11300
+ ],
11301
+ "beige": [
11302
+ 245,
11303
+ 245,
11304
+ 220
11305
+ ],
11306
+ "bisque": [
11307
+ 255,
11308
+ 228,
11309
+ 196
11310
+ ],
11311
+ "black": [
11312
+ 0,
11313
+ 0,
11314
+ 0
11315
+ ],
11316
+ "blanchedalmond": [
11317
+ 255,
11318
+ 235,
11319
+ 205
11320
+ ],
11321
+ "blue": [
11322
+ 0,
11323
+ 0,
11324
+ 255
11325
+ ],
11326
+ "blueviolet": [
11327
+ 138,
11328
+ 43,
11329
+ 226
11330
+ ],
11331
+ "brown": [
11332
+ 165,
11333
+ 42,
11334
+ 42
11335
+ ],
11336
+ "burlywood": [
11337
+ 222,
11338
+ 184,
11339
+ 135
11340
+ ],
11341
+ "cadetblue": [
11342
+ 95,
11343
+ 158,
11344
+ 160
11345
+ ],
11346
+ "chartreuse": [
11347
+ 127,
11348
+ 255,
11349
+ 0
11350
+ ],
11351
+ "chocolate": [
11352
+ 210,
11353
+ 105,
11354
+ 30
11355
+ ],
11356
+ "coral": [
11357
+ 255,
11358
+ 127,
11359
+ 80
11360
+ ],
11361
+ "cornflowerblue": [
11362
+ 100,
11363
+ 149,
11364
+ 237
11365
+ ],
11366
+ "cornsilk": [
11367
+ 255,
11368
+ 248,
11369
+ 220
11370
+ ],
11371
+ "crimson": [
11372
+ 220,
11373
+ 20,
11374
+ 60
11375
+ ],
11376
+ "cyan": [
11377
+ 0,
11378
+ 255,
11379
+ 255
11380
+ ],
11381
+ "darkblue": [
11382
+ 0,
11383
+ 0,
11384
+ 139
11385
+ ],
11386
+ "darkcyan": [
11387
+ 0,
11388
+ 139,
11389
+ 139
11390
+ ],
11391
+ "darkgoldenrod": [
11392
+ 184,
11393
+ 134,
11394
+ 11
11395
+ ],
11396
+ "darkgray": [
11397
+ 169,
11398
+ 169,
11399
+ 169
11400
+ ],
11401
+ "darkgreen": [
11402
+ 0,
11403
+ 100,
11404
+ 0
11405
+ ],
11406
+ "darkgrey": [
11407
+ 169,
11408
+ 169,
11409
+ 169
11410
+ ],
11411
+ "darkkhaki": [
11412
+ 189,
11413
+ 183,
11414
+ 107
11415
+ ],
11416
+ "darkmagenta": [
11417
+ 139,
11418
+ 0,
11419
+ 139
11420
+ ],
11421
+ "darkolivegreen": [
11422
+ 85,
11423
+ 107,
11424
+ 47
11425
+ ],
11426
+ "darkorange": [
11427
+ 255,
11428
+ 140,
11429
+ 0
11430
+ ],
11431
+ "darkorchid": [
11432
+ 153,
11433
+ 50,
11434
+ 204
11435
+ ],
11436
+ "darkred": [
11437
+ 139,
11438
+ 0,
11439
+ 0
11440
+ ],
11441
+ "darksalmon": [
11442
+ 233,
11443
+ 150,
11444
+ 122
11445
+ ],
11446
+ "darkseagreen": [
11447
+ 143,
11448
+ 188,
11449
+ 143
11450
+ ],
11451
+ "darkslateblue": [
11452
+ 72,
11453
+ 61,
11454
+ 139
11455
+ ],
11456
+ "darkslategray": [
11457
+ 47,
11458
+ 79,
11459
+ 79
11460
+ ],
11461
+ "darkslategrey": [
11462
+ 47,
11463
+ 79,
11464
+ 79
11465
+ ],
11466
+ "darkturquoise": [
11467
+ 0,
11468
+ 206,
11469
+ 209
11470
+ ],
11471
+ "darkviolet": [
11472
+ 148,
11473
+ 0,
11474
+ 211
11475
+ ],
11476
+ "deeppink": [
11477
+ 255,
11478
+ 20,
11479
+ 147
11480
+ ],
11481
+ "deepskyblue": [
11482
+ 0,
11483
+ 191,
11484
+ 255
11485
+ ],
11486
+ "dimgray": [
11487
+ 105,
11488
+ 105,
11489
+ 105
11490
+ ],
11491
+ "dimgrey": [
11492
+ 105,
11493
+ 105,
11494
+ 105
11495
+ ],
11496
+ "dodgerblue": [
11497
+ 30,
11498
+ 144,
11499
+ 255
11500
+ ],
11501
+ "firebrick": [
11502
+ 178,
11503
+ 34,
11504
+ 34
11505
+ ],
11506
+ "floralwhite": [
11507
+ 255,
11508
+ 250,
11509
+ 240
11510
+ ],
11511
+ "forestgreen": [
11512
+ 34,
11513
+ 139,
11514
+ 34
11515
+ ],
11516
+ "fuchsia": [
11517
+ 255,
11518
+ 0,
11519
+ 255
11520
+ ],
11521
+ "gainsboro": [
11522
+ 220,
11523
+ 220,
11524
+ 220
11525
+ ],
11526
+ "ghostwhite": [
11527
+ 248,
11528
+ 248,
11529
+ 255
11530
+ ],
11531
+ "gold": [
11532
+ 255,
11533
+ 215,
11534
+ 0
11535
+ ],
11536
+ "goldenrod": [
11537
+ 218,
11538
+ 165,
11539
+ 32
11540
+ ],
11541
+ "gray": [
11542
+ 128,
11543
+ 128,
11544
+ 128
11545
+ ],
11546
+ "green": [
11547
+ 0,
11548
+ 128,
11549
+ 0
11550
+ ],
11551
+ "greenyellow": [
11552
+ 173,
11553
+ 255,
11554
+ 47
11555
+ ],
11556
+ "grey": [
11557
+ 128,
11558
+ 128,
11559
+ 128
11560
+ ],
11561
+ "honeydew": [
11562
+ 240,
11563
+ 255,
11564
+ 240
11565
+ ],
11566
+ "hotpink": [
11567
+ 255,
11568
+ 105,
11569
+ 180
11570
+ ],
11571
+ "indianred": [
11572
+ 205,
11573
+ 92,
11574
+ 92
11575
+ ],
11576
+ "indigo": [
11577
+ 75,
11578
+ 0,
11579
+ 130
11580
+ ],
11581
+ "ivory": [
11582
+ 255,
11583
+ 255,
11584
+ 240
11585
+ ],
11586
+ "khaki": [
11587
+ 240,
11588
+ 230,
11589
+ 140
11590
+ ],
11591
+ "lavender": [
11592
+ 230,
11593
+ 230,
11594
+ 250
11595
+ ],
11596
+ "lavenderblush": [
11597
+ 255,
11598
+ 240,
11599
+ 245
11600
+ ],
11601
+ "lawngreen": [
11602
+ 124,
11603
+ 252,
11604
+ 0
11605
+ ],
11606
+ "lemonchiffon": [
11607
+ 255,
11608
+ 250,
11609
+ 205
11610
+ ],
11611
+ "lightblue": [
11612
+ 173,
11613
+ 216,
11614
+ 230
11615
+ ],
11616
+ "lightcoral": [
11617
+ 240,
11618
+ 128,
11619
+ 128
11620
+ ],
11621
+ "lightcyan": [
11622
+ 224,
11623
+ 255,
11624
+ 255
11625
+ ],
11626
+ "lightgoldenrodyellow": [
11627
+ 250,
11628
+ 250,
11629
+ 210
11630
+ ],
11631
+ "lightgray": [
11632
+ 211,
11633
+ 211,
11634
+ 211
11635
+ ],
11636
+ "lightgreen": [
11637
+ 144,
11638
+ 238,
11639
+ 144
11640
+ ],
11641
+ "lightgrey": [
11642
+ 211,
11643
+ 211,
11644
+ 211
11645
+ ],
11646
+ "lightpink": [
11647
+ 255,
11648
+ 182,
11649
+ 193
11650
+ ],
11651
+ "lightsalmon": [
11652
+ 255,
11653
+ 160,
11654
+ 122
11655
+ ],
11656
+ "lightseagreen": [
11657
+ 32,
11658
+ 178,
11659
+ 170
11660
+ ],
11661
+ "lightskyblue": [
11662
+ 135,
11663
+ 206,
11664
+ 250
11665
+ ],
11666
+ "lightslategray": [
11667
+ 119,
11668
+ 136,
11669
+ 153
11670
+ ],
11671
+ "lightslategrey": [
11672
+ 119,
11673
+ 136,
11674
+ 153
11675
+ ],
11676
+ "lightsteelblue": [
11677
+ 176,
11678
+ 196,
11679
+ 222
11680
+ ],
11681
+ "lightyellow": [
11682
+ 255,
11683
+ 255,
11684
+ 224
11685
+ ],
11686
+ "lime": [
11687
+ 0,
11688
+ 255,
11689
+ 0
11690
+ ],
11691
+ "limegreen": [
11692
+ 50,
11693
+ 205,
11694
+ 50
11695
+ ],
11696
+ "linen": [
11697
+ 250,
11698
+ 240,
11699
+ 230
11700
+ ],
11701
+ "magenta": [
11702
+ 255,
11703
+ 0,
11704
+ 255
11705
+ ],
11706
+ "maroon": [
11707
+ 128,
11708
+ 0,
11709
+ 0
11710
+ ],
11711
+ "mediumaquamarine": [
11712
+ 102,
11713
+ 205,
11714
+ 170
11715
+ ],
11716
+ "mediumblue": [
11717
+ 0,
11718
+ 0,
11719
+ 205
11720
+ ],
11721
+ "mediumorchid": [
11722
+ 186,
11723
+ 85,
11724
+ 211
11725
+ ],
11726
+ "mediumpurple": [
11727
+ 147,
11728
+ 112,
11729
+ 219
11730
+ ],
11731
+ "mediumseagreen": [
11732
+ 60,
11733
+ 179,
11734
+ 113
11735
+ ],
11736
+ "mediumslateblue": [
11737
+ 123,
11738
+ 104,
11739
+ 238
11740
+ ],
11741
+ "mediumspringgreen": [
11742
+ 0,
11743
+ 250,
11744
+ 154
11745
+ ],
11746
+ "mediumturquoise": [
11747
+ 72,
11748
+ 209,
11749
+ 204
11750
+ ],
11751
+ "mediumvioletred": [
11752
+ 199,
11753
+ 21,
11754
+ 133
11755
+ ],
11756
+ "midnightblue": [
11757
+ 25,
11758
+ 25,
11759
+ 112
11760
+ ],
11761
+ "mintcream": [
11762
+ 245,
11763
+ 255,
11764
+ 250
11765
+ ],
11766
+ "mistyrose": [
11767
+ 255,
11768
+ 228,
11769
+ 225
11770
+ ],
11771
+ "moccasin": [
11772
+ 255,
11773
+ 228,
11774
+ 181
11775
+ ],
11776
+ "navajowhite": [
11777
+ 255,
11778
+ 222,
11779
+ 173
11780
+ ],
11781
+ "navy": [
11782
+ 0,
11783
+ 0,
11784
+ 128
11785
+ ],
11786
+ "oldlace": [
11787
+ 253,
11788
+ 245,
11789
+ 230
11790
+ ],
11791
+ "olive": [
11792
+ 128,
11793
+ 128,
11794
+ 0
11795
+ ],
11796
+ "olivedrab": [
11797
+ 107,
11798
+ 142,
11799
+ 35
11800
+ ],
11801
+ "orange": [
11802
+ 255,
11803
+ 165,
11804
+ 0
11805
+ ],
11806
+ "orangered": [
11807
+ 255,
11808
+ 69,
11809
+ 0
11810
+ ],
11811
+ "orchid": [
11812
+ 218,
11813
+ 112,
11814
+ 214
11815
+ ],
11816
+ "palegoldenrod": [
11817
+ 238,
11818
+ 232,
11819
+ 170
11820
+ ],
11821
+ "palegreen": [
11822
+ 152,
11823
+ 251,
11824
+ 152
11825
+ ],
11826
+ "paleturquoise": [
11827
+ 175,
11828
+ 238,
11829
+ 238
11830
+ ],
11831
+ "palevioletred": [
11832
+ 219,
11833
+ 112,
11834
+ 147
11835
+ ],
11836
+ "papayawhip": [
11837
+ 255,
11838
+ 239,
11839
+ 213
11840
+ ],
11841
+ "peachpuff": [
11842
+ 255,
11843
+ 218,
11844
+ 185
11845
+ ],
11846
+ "peru": [
11847
+ 205,
11848
+ 133,
11849
+ 63
11850
+ ],
11851
+ "pink": [
11852
+ 255,
11853
+ 192,
11854
+ 203
11855
+ ],
11856
+ "plum": [
11857
+ 221,
11858
+ 160,
11859
+ 221
11860
+ ],
11861
+ "powderblue": [
11862
+ 176,
11863
+ 224,
11864
+ 230
11865
+ ],
11866
+ "purple": [
11867
+ 128,
11868
+ 0,
11869
+ 128
11870
+ ],
11871
+ "rebeccapurple": [
11872
+ 102,
11873
+ 51,
11874
+ 153
11875
+ ],
11876
+ "red": [
11877
+ 255,
11878
+ 0,
11879
+ 0
11880
+ ],
11881
+ "rosybrown": [
11882
+ 188,
11883
+ 143,
11884
+ 143
11885
+ ],
11886
+ "royalblue": [
11887
+ 65,
11888
+ 105,
11889
+ 225
11890
+ ],
11891
+ "saddlebrown": [
11892
+ 139,
11893
+ 69,
11894
+ 19
11895
+ ],
11896
+ "salmon": [
11897
+ 250,
11898
+ 128,
11899
+ 114
11900
+ ],
11901
+ "sandybrown": [
11902
+ 244,
11903
+ 164,
11904
+ 96
11905
+ ],
11906
+ "seagreen": [
11907
+ 46,
11908
+ 139,
11909
+ 87
11910
+ ],
11911
+ "seashell": [
11912
+ 255,
11913
+ 245,
11914
+ 238
11915
+ ],
11916
+ "sienna": [
11917
+ 160,
11918
+ 82,
11919
+ 45
11920
+ ],
11921
+ "silver": [
11922
+ 192,
11923
+ 192,
11924
+ 192
11925
+ ],
11926
+ "skyblue": [
11927
+ 135,
11928
+ 206,
11929
+ 235
11930
+ ],
11931
+ "slateblue": [
11932
+ 106,
11933
+ 90,
11934
+ 205
11935
+ ],
11936
+ "slategray": [
11937
+ 112,
11938
+ 128,
11939
+ 144
11940
+ ],
11941
+ "slategrey": [
11942
+ 112,
11943
+ 128,
11944
+ 144
11945
+ ],
11946
+ "snow": [
11947
+ 255,
11948
+ 250,
11949
+ 250
11950
+ ],
11951
+ "springgreen": [
11952
+ 0,
11953
+ 255,
11954
+ 127
11955
+ ],
11956
+ "steelblue": [
11957
+ 70,
11958
+ 130,
11959
+ 180
11960
+ ],
11961
+ "tan": [
11962
+ 210,
11963
+ 180,
11964
+ 140
11965
+ ],
11966
+ "teal": [
11967
+ 0,
11968
+ 128,
11969
+ 128
11970
+ ],
11971
+ "thistle": [
11972
+ 216,
11973
+ 191,
11974
+ 216
11975
+ ],
11976
+ "tomato": [
11977
+ 255,
11978
+ 99,
11979
+ 71
11980
+ ],
11981
+ "turquoise": [
11982
+ 64,
11983
+ 224,
11984
+ 208
11985
+ ],
11986
+ "violet": [
11987
+ 238,
11988
+ 130,
11989
+ 238
11990
+ ],
11991
+ "wheat": [
11992
+ 245,
11993
+ 222,
11994
+ 179
11995
+ ],
11996
+ "white": [
11997
+ 255,
11998
+ 255,
11999
+ 255
12000
+ ],
12001
+ "whitesmoke": [
12002
+ 245,
12003
+ 245,
12004
+ 245
12005
+ ],
12006
+ "yellow": [
12007
+ 255,
12008
+ 255,
12009
+ 0
12010
+ ],
12011
+ "yellowgreen": [
12012
+ 154,
12013
+ 205,
12014
+ 50
12015
+ ]
12016
+ };
12017
+ }));
12018
+ //#endregion
12019
+ //#region ../../node_modules/.pnpm/color-convert@2.0.1/node_modules/color-convert/conversions.js
12020
+ var require_conversions = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12021
+ var cssKeywords = require_color_name();
12022
+ var reverseKeywords = {};
12023
+ for (const key of Object.keys(cssKeywords)) reverseKeywords[cssKeywords[key]] = key;
12024
+ var convert = {
12025
+ rgb: {
12026
+ channels: 3,
12027
+ labels: "rgb"
12028
+ },
12029
+ hsl: {
12030
+ channels: 3,
12031
+ labels: "hsl"
12032
+ },
12033
+ hsv: {
12034
+ channels: 3,
12035
+ labels: "hsv"
12036
+ },
12037
+ hwb: {
12038
+ channels: 3,
12039
+ labels: "hwb"
12040
+ },
12041
+ cmyk: {
12042
+ channels: 4,
12043
+ labels: "cmyk"
12044
+ },
12045
+ xyz: {
12046
+ channels: 3,
12047
+ labels: "xyz"
12048
+ },
12049
+ lab: {
12050
+ channels: 3,
12051
+ labels: "lab"
12052
+ },
12053
+ lch: {
12054
+ channels: 3,
12055
+ labels: "lch"
12056
+ },
12057
+ hex: {
12058
+ channels: 1,
12059
+ labels: ["hex"]
12060
+ },
12061
+ keyword: {
12062
+ channels: 1,
12063
+ labels: ["keyword"]
12064
+ },
12065
+ ansi16: {
12066
+ channels: 1,
12067
+ labels: ["ansi16"]
12068
+ },
12069
+ ansi256: {
12070
+ channels: 1,
12071
+ labels: ["ansi256"]
12072
+ },
12073
+ hcg: {
12074
+ channels: 3,
12075
+ labels: [
12076
+ "h",
12077
+ "c",
12078
+ "g"
12079
+ ]
12080
+ },
12081
+ apple: {
12082
+ channels: 3,
12083
+ labels: [
12084
+ "r16",
12085
+ "g16",
12086
+ "b16"
12087
+ ]
12088
+ },
12089
+ gray: {
12090
+ channels: 1,
12091
+ labels: ["gray"]
12092
+ }
12093
+ };
12094
+ module.exports = convert;
12095
+ for (const model of Object.keys(convert)) {
12096
+ if (!("channels" in convert[model])) throw new Error("missing channels property: " + model);
12097
+ if (!("labels" in convert[model])) throw new Error("missing channel labels property: " + model);
12098
+ if (convert[model].labels.length !== convert[model].channels) throw new Error("channel and label counts mismatch: " + model);
12099
+ const { channels, labels } = convert[model];
12100
+ delete convert[model].channels;
12101
+ delete convert[model].labels;
12102
+ Object.defineProperty(convert[model], "channels", { value: channels });
12103
+ Object.defineProperty(convert[model], "labels", { value: labels });
12104
+ }
12105
+ convert.rgb.hsl = function(rgb) {
12106
+ const r = rgb[0] / 255;
12107
+ const g = rgb[1] / 255;
12108
+ const b = rgb[2] / 255;
12109
+ const min = Math.min(r, g, b);
12110
+ const max = Math.max(r, g, b);
12111
+ const delta = max - min;
12112
+ let h;
12113
+ let s;
12114
+ if (max === min) h = 0;
12115
+ else if (r === max) h = (g - b) / delta;
12116
+ else if (g === max) h = 2 + (b - r) / delta;
12117
+ else if (b === max) h = 4 + (r - g) / delta;
12118
+ h = Math.min(h * 60, 360);
12119
+ if (h < 0) h += 360;
12120
+ const l = (min + max) / 2;
12121
+ if (max === min) s = 0;
12122
+ else if (l <= .5) s = delta / (max + min);
12123
+ else s = delta / (2 - max - min);
12124
+ return [
12125
+ h,
12126
+ s * 100,
12127
+ l * 100
12128
+ ];
12129
+ };
12130
+ convert.rgb.hsv = function(rgb) {
12131
+ let rdif;
12132
+ let gdif;
12133
+ let bdif;
12134
+ let h;
12135
+ let s;
12136
+ const r = rgb[0] / 255;
12137
+ const g = rgb[1] / 255;
12138
+ const b = rgb[2] / 255;
12139
+ const v = Math.max(r, g, b);
12140
+ const diff = v - Math.min(r, g, b);
12141
+ const diffc = function(c) {
12142
+ return (v - c) / 6 / diff + 1 / 2;
12143
+ };
12144
+ if (diff === 0) {
12145
+ h = 0;
12146
+ s = 0;
12147
+ } else {
12148
+ s = diff / v;
12149
+ rdif = diffc(r);
12150
+ gdif = diffc(g);
12151
+ bdif = diffc(b);
12152
+ if (r === v) h = bdif - gdif;
12153
+ else if (g === v) h = 1 / 3 + rdif - bdif;
12154
+ else if (b === v) h = 2 / 3 + gdif - rdif;
12155
+ if (h < 0) h += 1;
12156
+ else if (h > 1) h -= 1;
12157
+ }
12158
+ return [
12159
+ h * 360,
12160
+ s * 100,
12161
+ v * 100
12162
+ ];
12163
+ };
12164
+ convert.rgb.hwb = function(rgb) {
12165
+ const r = rgb[0];
12166
+ const g = rgb[1];
12167
+ let b = rgb[2];
12168
+ const h = convert.rgb.hsl(rgb)[0];
12169
+ const w = 1 / 255 * Math.min(r, Math.min(g, b));
12170
+ b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
12171
+ return [
12172
+ h,
12173
+ w * 100,
12174
+ b * 100
12175
+ ];
12176
+ };
12177
+ convert.rgb.cmyk = function(rgb) {
12178
+ const r = rgb[0] / 255;
12179
+ const g = rgb[1] / 255;
12180
+ const b = rgb[2] / 255;
12181
+ const k = Math.min(1 - r, 1 - g, 1 - b);
12182
+ const c = (1 - r - k) / (1 - k) || 0;
12183
+ const m = (1 - g - k) / (1 - k) || 0;
12184
+ const y = (1 - b - k) / (1 - k) || 0;
12185
+ return [
12186
+ c * 100,
12187
+ m * 100,
12188
+ y * 100,
12189
+ k * 100
12190
+ ];
12191
+ };
12192
+ function comparativeDistance(x, y) {
12193
+ return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2;
12194
+ }
12195
+ convert.rgb.keyword = function(rgb) {
12196
+ const reversed = reverseKeywords[rgb];
12197
+ if (reversed) return reversed;
12198
+ let currentClosestDistance = Infinity;
12199
+ let currentClosestKeyword;
12200
+ for (const keyword of Object.keys(cssKeywords)) {
12201
+ const value = cssKeywords[keyword];
12202
+ const distance = comparativeDistance(rgb, value);
12203
+ if (distance < currentClosestDistance) {
12204
+ currentClosestDistance = distance;
12205
+ currentClosestKeyword = keyword;
12206
+ }
12207
+ }
12208
+ return currentClosestKeyword;
12209
+ };
12210
+ convert.keyword.rgb = function(keyword) {
12211
+ return cssKeywords[keyword];
12212
+ };
12213
+ convert.rgb.xyz = function(rgb) {
12214
+ let r = rgb[0] / 255;
12215
+ let g = rgb[1] / 255;
12216
+ let b = rgb[2] / 255;
12217
+ r = r > .04045 ? ((r + .055) / 1.055) ** 2.4 : r / 12.92;
12218
+ g = g > .04045 ? ((g + .055) / 1.055) ** 2.4 : g / 12.92;
12219
+ b = b > .04045 ? ((b + .055) / 1.055) ** 2.4 : b / 12.92;
12220
+ const x = r * .4124 + g * .3576 + b * .1805;
12221
+ const y = r * .2126 + g * .7152 + b * .0722;
12222
+ const z = r * .0193 + g * .1192 + b * .9505;
12223
+ return [
12224
+ x * 100,
12225
+ y * 100,
12226
+ z * 100
12227
+ ];
12228
+ };
12229
+ convert.rgb.lab = function(rgb) {
12230
+ const xyz = convert.rgb.xyz(rgb);
12231
+ let x = xyz[0];
12232
+ let y = xyz[1];
12233
+ let z = xyz[2];
12234
+ x /= 95.047;
12235
+ y /= 100;
12236
+ z /= 108.883;
12237
+ x = x > .008856 ? x ** (1 / 3) : 7.787 * x + 16 / 116;
12238
+ y = y > .008856 ? y ** (1 / 3) : 7.787 * y + 16 / 116;
12239
+ z = z > .008856 ? z ** (1 / 3) : 7.787 * z + 16 / 116;
12240
+ return [
12241
+ 116 * y - 16,
12242
+ 500 * (x - y),
12243
+ 200 * (y - z)
12244
+ ];
12245
+ };
12246
+ convert.hsl.rgb = function(hsl) {
12247
+ const h = hsl[0] / 360;
12248
+ const s = hsl[1] / 100;
12249
+ const l = hsl[2] / 100;
12250
+ let t2;
12251
+ let t3;
12252
+ let val;
12253
+ if (s === 0) {
12254
+ val = l * 255;
12255
+ return [
12256
+ val,
12257
+ val,
12258
+ val
12259
+ ];
12260
+ }
12261
+ if (l < .5) t2 = l * (1 + s);
12262
+ else t2 = l + s - l * s;
12263
+ const t1 = 2 * l - t2;
12264
+ const rgb = [
12265
+ 0,
12266
+ 0,
12267
+ 0
12268
+ ];
12269
+ for (let i = 0; i < 3; i++) {
12270
+ t3 = h + 1 / 3 * -(i - 1);
12271
+ if (t3 < 0) t3++;
12272
+ if (t3 > 1) t3--;
12273
+ if (6 * t3 < 1) val = t1 + (t2 - t1) * 6 * t3;
12274
+ else if (2 * t3 < 1) val = t2;
12275
+ else if (3 * t3 < 2) val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
12276
+ else val = t1;
12277
+ rgb[i] = val * 255;
12278
+ }
12279
+ return rgb;
12280
+ };
12281
+ convert.hsl.hsv = function(hsl) {
12282
+ const h = hsl[0];
12283
+ let s = hsl[1] / 100;
12284
+ let l = hsl[2] / 100;
12285
+ let smin = s;
12286
+ const lmin = Math.max(l, .01);
12287
+ l *= 2;
12288
+ s *= l <= 1 ? l : 2 - l;
12289
+ smin *= lmin <= 1 ? lmin : 2 - lmin;
12290
+ const v = (l + s) / 2;
12291
+ return [
12292
+ h,
12293
+ (l === 0 ? 2 * smin / (lmin + smin) : 2 * s / (l + s)) * 100,
12294
+ v * 100
12295
+ ];
12296
+ };
12297
+ convert.hsv.rgb = function(hsv) {
12298
+ const h = hsv[0] / 60;
12299
+ const s = hsv[1] / 100;
12300
+ let v = hsv[2] / 100;
12301
+ const hi = Math.floor(h) % 6;
12302
+ const f = h - Math.floor(h);
12303
+ const p = 255 * v * (1 - s);
12304
+ const q = 255 * v * (1 - s * f);
12305
+ const t = 255 * v * (1 - s * (1 - f));
12306
+ v *= 255;
12307
+ switch (hi) {
12308
+ case 0: return [
12309
+ v,
12310
+ t,
12311
+ p
12312
+ ];
12313
+ case 1: return [
12314
+ q,
12315
+ v,
12316
+ p
12317
+ ];
12318
+ case 2: return [
12319
+ p,
12320
+ v,
12321
+ t
12322
+ ];
12323
+ case 3: return [
12324
+ p,
12325
+ q,
12326
+ v
12327
+ ];
12328
+ case 4: return [
12329
+ t,
12330
+ p,
12331
+ v
12332
+ ];
12333
+ case 5: return [
12334
+ v,
12335
+ p,
12336
+ q
12337
+ ];
12338
+ }
12339
+ };
12340
+ convert.hsv.hsl = function(hsv) {
12341
+ const h = hsv[0];
12342
+ const s = hsv[1] / 100;
12343
+ const v = hsv[2] / 100;
12344
+ const vmin = Math.max(v, .01);
12345
+ let sl;
12346
+ let l;
12347
+ l = (2 - s) * v;
12348
+ const lmin = (2 - s) * vmin;
12349
+ sl = s * vmin;
12350
+ sl /= lmin <= 1 ? lmin : 2 - lmin;
12351
+ sl = sl || 0;
12352
+ l /= 2;
12353
+ return [
12354
+ h,
12355
+ sl * 100,
12356
+ l * 100
12357
+ ];
12358
+ };
12359
+ convert.hwb.rgb = function(hwb) {
12360
+ const h = hwb[0] / 360;
12361
+ let wh = hwb[1] / 100;
12362
+ let bl = hwb[2] / 100;
12363
+ const ratio = wh + bl;
12364
+ let f;
12365
+ if (ratio > 1) {
12366
+ wh /= ratio;
12367
+ bl /= ratio;
12368
+ }
12369
+ const i = Math.floor(6 * h);
12370
+ const v = 1 - bl;
12371
+ f = 6 * h - i;
12372
+ if ((i & 1) !== 0) f = 1 - f;
12373
+ const n = wh + f * (v - wh);
12374
+ let r;
12375
+ let g;
12376
+ let b;
12377
+ switch (i) {
12378
+ default:
12379
+ case 6:
12380
+ case 0:
12381
+ r = v;
12382
+ g = n;
12383
+ b = wh;
12384
+ break;
12385
+ case 1:
12386
+ r = n;
12387
+ g = v;
12388
+ b = wh;
12389
+ break;
12390
+ case 2:
12391
+ r = wh;
12392
+ g = v;
12393
+ b = n;
12394
+ break;
12395
+ case 3:
12396
+ r = wh;
12397
+ g = n;
12398
+ b = v;
12399
+ break;
12400
+ case 4:
12401
+ r = n;
12402
+ g = wh;
12403
+ b = v;
12404
+ break;
12405
+ case 5:
12406
+ r = v;
12407
+ g = wh;
12408
+ b = n;
12409
+ break;
12410
+ }
12411
+ return [
12412
+ r * 255,
12413
+ g * 255,
12414
+ b * 255
12415
+ ];
12416
+ };
12417
+ convert.cmyk.rgb = function(cmyk) {
12418
+ const c = cmyk[0] / 100;
12419
+ const m = cmyk[1] / 100;
12420
+ const y = cmyk[2] / 100;
12421
+ const k = cmyk[3] / 100;
12422
+ const r = 1 - Math.min(1, c * (1 - k) + k);
12423
+ const g = 1 - Math.min(1, m * (1 - k) + k);
12424
+ const b = 1 - Math.min(1, y * (1 - k) + k);
12425
+ return [
12426
+ r * 255,
12427
+ g * 255,
12428
+ b * 255
12429
+ ];
12430
+ };
12431
+ convert.xyz.rgb = function(xyz) {
12432
+ const x = xyz[0] / 100;
12433
+ const y = xyz[1] / 100;
12434
+ const z = xyz[2] / 100;
12435
+ let r;
12436
+ let g;
12437
+ let b;
12438
+ r = x * 3.2406 + y * -1.5372 + z * -.4986;
12439
+ g = x * -.9689 + y * 1.8758 + z * .0415;
12440
+ b = x * .0557 + y * -.204 + z * 1.057;
12441
+ r = r > .0031308 ? 1.055 * r ** (1 / 2.4) - .055 : r * 12.92;
12442
+ g = g > .0031308 ? 1.055 * g ** (1 / 2.4) - .055 : g * 12.92;
12443
+ b = b > .0031308 ? 1.055 * b ** (1 / 2.4) - .055 : b * 12.92;
12444
+ r = Math.min(Math.max(0, r), 1);
12445
+ g = Math.min(Math.max(0, g), 1);
12446
+ b = Math.min(Math.max(0, b), 1);
12447
+ return [
12448
+ r * 255,
12449
+ g * 255,
12450
+ b * 255
12451
+ ];
12452
+ };
12453
+ convert.xyz.lab = function(xyz) {
12454
+ let x = xyz[0];
12455
+ let y = xyz[1];
12456
+ let z = xyz[2];
12457
+ x /= 95.047;
12458
+ y /= 100;
12459
+ z /= 108.883;
12460
+ x = x > .008856 ? x ** (1 / 3) : 7.787 * x + 16 / 116;
12461
+ y = y > .008856 ? y ** (1 / 3) : 7.787 * y + 16 / 116;
12462
+ z = z > .008856 ? z ** (1 / 3) : 7.787 * z + 16 / 116;
12463
+ return [
12464
+ 116 * y - 16,
12465
+ 500 * (x - y),
12466
+ 200 * (y - z)
12467
+ ];
12468
+ };
12469
+ convert.lab.xyz = function(lab) {
12470
+ const l = lab[0];
12471
+ const a = lab[1];
12472
+ const b = lab[2];
12473
+ let x;
12474
+ let y;
12475
+ let z;
12476
+ y = (l + 16) / 116;
12477
+ x = a / 500 + y;
12478
+ z = y - b / 200;
12479
+ const y2 = y ** 3;
12480
+ const x2 = x ** 3;
12481
+ const z2 = z ** 3;
12482
+ y = y2 > .008856 ? y2 : (y - 16 / 116) / 7.787;
12483
+ x = x2 > .008856 ? x2 : (x - 16 / 116) / 7.787;
12484
+ z = z2 > .008856 ? z2 : (z - 16 / 116) / 7.787;
12485
+ x *= 95.047;
12486
+ y *= 100;
12487
+ z *= 108.883;
12488
+ return [
12489
+ x,
12490
+ y,
12491
+ z
12492
+ ];
12493
+ };
12494
+ convert.lab.lch = function(lab) {
12495
+ const l = lab[0];
12496
+ const a = lab[1];
12497
+ const b = lab[2];
12498
+ let h;
12499
+ h = Math.atan2(b, a) * 360 / 2 / Math.PI;
12500
+ if (h < 0) h += 360;
12501
+ return [
12502
+ l,
12503
+ Math.sqrt(a * a + b * b),
12504
+ h
12505
+ ];
12506
+ };
12507
+ convert.lch.lab = function(lch) {
12508
+ const l = lch[0];
12509
+ const c = lch[1];
12510
+ const hr = lch[2] / 360 * 2 * Math.PI;
12511
+ return [
12512
+ l,
12513
+ c * Math.cos(hr),
12514
+ c * Math.sin(hr)
12515
+ ];
12516
+ };
12517
+ convert.rgb.ansi16 = function(args, saturation = null) {
12518
+ const [r, g, b] = args;
12519
+ let value = saturation === null ? convert.rgb.hsv(args)[2] : saturation;
12520
+ value = Math.round(value / 50);
12521
+ if (value === 0) return 30;
12522
+ let ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
12523
+ if (value === 2) ansi += 60;
12524
+ return ansi;
12525
+ };
12526
+ convert.hsv.ansi16 = function(args) {
12527
+ return convert.rgb.ansi16(convert.hsv.rgb(args), args[2]);
12528
+ };
12529
+ convert.rgb.ansi256 = function(args) {
12530
+ const r = args[0];
12531
+ const g = args[1];
12532
+ const b = args[2];
12533
+ if (r === g && g === b) {
12534
+ if (r < 8) return 16;
12535
+ if (r > 248) return 231;
12536
+ return Math.round((r - 8) / 247 * 24) + 232;
12537
+ }
12538
+ return 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
12539
+ };
12540
+ convert.ansi16.rgb = function(args) {
12541
+ let color = args % 10;
12542
+ if (color === 0 || color === 7) {
12543
+ if (args > 50) color += 3.5;
12544
+ color = color / 10.5 * 255;
12545
+ return [
12546
+ color,
12547
+ color,
12548
+ color
12549
+ ];
12550
+ }
12551
+ const mult = (~~(args > 50) + 1) * .5;
12552
+ return [
12553
+ (color & 1) * mult * 255,
12554
+ (color >> 1 & 1) * mult * 255,
12555
+ (color >> 2 & 1) * mult * 255
12556
+ ];
12557
+ };
12558
+ convert.ansi256.rgb = function(args) {
12559
+ if (args >= 232) {
12560
+ const c = (args - 232) * 10 + 8;
12561
+ return [
12562
+ c,
12563
+ c,
12564
+ c
12565
+ ];
12566
+ }
12567
+ args -= 16;
12568
+ let rem;
12569
+ return [
12570
+ Math.floor(args / 36) / 5 * 255,
12571
+ Math.floor((rem = args % 36) / 6) / 5 * 255,
12572
+ rem % 6 / 5 * 255
12573
+ ];
12574
+ };
12575
+ convert.rgb.hex = function(args) {
12576
+ const string = (((Math.round(args[0]) & 255) << 16) + ((Math.round(args[1]) & 255) << 8) + (Math.round(args[2]) & 255)).toString(16).toUpperCase();
12577
+ return "000000".substring(string.length) + string;
12578
+ };
12579
+ convert.hex.rgb = function(args) {
12580
+ const match = args.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
12581
+ if (!match) return [
12582
+ 0,
12583
+ 0,
12584
+ 0
12585
+ ];
12586
+ let colorString = match[0];
12587
+ if (match[0].length === 3) colorString = colorString.split("").map((char) => {
12588
+ return char + char;
12589
+ }).join("");
12590
+ const integer = parseInt(colorString, 16);
12591
+ return [
12592
+ integer >> 16 & 255,
12593
+ integer >> 8 & 255,
12594
+ integer & 255
12595
+ ];
12596
+ };
12597
+ convert.rgb.hcg = function(rgb) {
12598
+ const r = rgb[0] / 255;
12599
+ const g = rgb[1] / 255;
12600
+ const b = rgb[2] / 255;
12601
+ const max = Math.max(Math.max(r, g), b);
12602
+ const min = Math.min(Math.min(r, g), b);
12603
+ const chroma = max - min;
12604
+ let grayscale;
12605
+ let hue;
12606
+ if (chroma < 1) grayscale = min / (1 - chroma);
12607
+ else grayscale = 0;
12608
+ if (chroma <= 0) hue = 0;
12609
+ else if (max === r) hue = (g - b) / chroma % 6;
12610
+ else if (max === g) hue = 2 + (b - r) / chroma;
12611
+ else hue = 4 + (r - g) / chroma;
12612
+ hue /= 6;
12613
+ hue %= 1;
12614
+ return [
12615
+ hue * 360,
12616
+ chroma * 100,
12617
+ grayscale * 100
12618
+ ];
12619
+ };
12620
+ convert.hsl.hcg = function(hsl) {
12621
+ const s = hsl[1] / 100;
12622
+ const l = hsl[2] / 100;
12623
+ const c = l < .5 ? 2 * s * l : 2 * s * (1 - l);
12624
+ let f = 0;
12625
+ if (c < 1) f = (l - .5 * c) / (1 - c);
12626
+ return [
12627
+ hsl[0],
12628
+ c * 100,
12629
+ f * 100
12630
+ ];
12631
+ };
12632
+ convert.hsv.hcg = function(hsv) {
12633
+ const s = hsv[1] / 100;
12634
+ const v = hsv[2] / 100;
12635
+ const c = s * v;
12636
+ let f = 0;
12637
+ if (c < 1) f = (v - c) / (1 - c);
12638
+ return [
12639
+ hsv[0],
12640
+ c * 100,
12641
+ f * 100
12642
+ ];
12643
+ };
12644
+ convert.hcg.rgb = function(hcg) {
12645
+ const h = hcg[0] / 360;
12646
+ const c = hcg[1] / 100;
12647
+ const g = hcg[2] / 100;
12648
+ if (c === 0) return [
12649
+ g * 255,
12650
+ g * 255,
12651
+ g * 255
12652
+ ];
12653
+ const pure = [
12654
+ 0,
12655
+ 0,
12656
+ 0
12657
+ ];
12658
+ const hi = h % 1 * 6;
12659
+ const v = hi % 1;
12660
+ const w = 1 - v;
12661
+ let mg = 0;
12662
+ switch (Math.floor(hi)) {
12663
+ case 0:
12664
+ pure[0] = 1;
12665
+ pure[1] = v;
12666
+ pure[2] = 0;
12667
+ break;
12668
+ case 1:
12669
+ pure[0] = w;
12670
+ pure[1] = 1;
12671
+ pure[2] = 0;
12672
+ break;
12673
+ case 2:
12674
+ pure[0] = 0;
12675
+ pure[1] = 1;
12676
+ pure[2] = v;
12677
+ break;
12678
+ case 3:
12679
+ pure[0] = 0;
12680
+ pure[1] = w;
12681
+ pure[2] = 1;
12682
+ break;
12683
+ case 4:
12684
+ pure[0] = v;
12685
+ pure[1] = 0;
12686
+ pure[2] = 1;
12687
+ break;
12688
+ default:
12689
+ pure[0] = 1;
12690
+ pure[1] = 0;
12691
+ pure[2] = w;
12692
+ }
12693
+ mg = (1 - c) * g;
12694
+ return [
12695
+ (c * pure[0] + mg) * 255,
12696
+ (c * pure[1] + mg) * 255,
12697
+ (c * pure[2] + mg) * 255
12698
+ ];
12699
+ };
12700
+ convert.hcg.hsv = function(hcg) {
12701
+ const c = hcg[1] / 100;
12702
+ const v = c + hcg[2] / 100 * (1 - c);
12703
+ let f = 0;
12704
+ if (v > 0) f = c / v;
12705
+ return [
12706
+ hcg[0],
12707
+ f * 100,
12708
+ v * 100
12709
+ ];
12710
+ };
12711
+ convert.hcg.hsl = function(hcg) {
12712
+ const c = hcg[1] / 100;
12713
+ const l = hcg[2] / 100 * (1 - c) + .5 * c;
12714
+ let s = 0;
12715
+ if (l > 0 && l < .5) s = c / (2 * l);
12716
+ else if (l >= .5 && l < 1) s = c / (2 * (1 - l));
12717
+ return [
12718
+ hcg[0],
12719
+ s * 100,
12720
+ l * 100
12721
+ ];
12722
+ };
12723
+ convert.hcg.hwb = function(hcg) {
12724
+ const c = hcg[1] / 100;
12725
+ const v = c + hcg[2] / 100 * (1 - c);
12726
+ return [
12727
+ hcg[0],
12728
+ (v - c) * 100,
12729
+ (1 - v) * 100
12730
+ ];
12731
+ };
12732
+ convert.hwb.hcg = function(hwb) {
12733
+ const w = hwb[1] / 100;
12734
+ const v = 1 - hwb[2] / 100;
12735
+ const c = v - w;
12736
+ let g = 0;
12737
+ if (c < 1) g = (v - c) / (1 - c);
12738
+ return [
12739
+ hwb[0],
12740
+ c * 100,
12741
+ g * 100
12742
+ ];
12743
+ };
12744
+ convert.apple.rgb = function(apple) {
12745
+ return [
12746
+ apple[0] / 65535 * 255,
12747
+ apple[1] / 65535 * 255,
12748
+ apple[2] / 65535 * 255
12749
+ ];
12750
+ };
12751
+ convert.rgb.apple = function(rgb) {
12752
+ return [
12753
+ rgb[0] / 255 * 65535,
12754
+ rgb[1] / 255 * 65535,
12755
+ rgb[2] / 255 * 65535
12756
+ ];
12757
+ };
12758
+ convert.gray.rgb = function(args) {
12759
+ return [
12760
+ args[0] / 100 * 255,
12761
+ args[0] / 100 * 255,
12762
+ args[0] / 100 * 255
12763
+ ];
12764
+ };
12765
+ convert.gray.hsl = function(args) {
12766
+ return [
12767
+ 0,
12768
+ 0,
12769
+ args[0]
12770
+ ];
12771
+ };
12772
+ convert.gray.hsv = convert.gray.hsl;
12773
+ convert.gray.hwb = function(gray) {
12774
+ return [
12775
+ 0,
12776
+ 100,
12777
+ gray[0]
12778
+ ];
12779
+ };
12780
+ convert.gray.cmyk = function(gray) {
12781
+ return [
12782
+ 0,
12783
+ 0,
12784
+ 0,
12785
+ gray[0]
12786
+ ];
12787
+ };
12788
+ convert.gray.lab = function(gray) {
12789
+ return [
12790
+ gray[0],
12791
+ 0,
12792
+ 0
12793
+ ];
12794
+ };
12795
+ convert.gray.hex = function(gray) {
12796
+ const val = Math.round(gray[0] / 100 * 255) & 255;
12797
+ const string = ((val << 16) + (val << 8) + val).toString(16).toUpperCase();
12798
+ return "000000".substring(string.length) + string;
12799
+ };
12800
+ convert.rgb.gray = function(rgb) {
12801
+ return [(rgb[0] + rgb[1] + rgb[2]) / 3 / 255 * 100];
12802
+ };
12803
+ }));
12804
+ //#endregion
12805
+ //#region ../../node_modules/.pnpm/color-convert@2.0.1/node_modules/color-convert/route.js
12806
+ var require_route = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12807
+ var conversions = require_conversions();
12808
+ function buildGraph() {
12809
+ const graph = {};
12810
+ const models = Object.keys(conversions);
12811
+ for (let len = models.length, i = 0; i < len; i++) graph[models[i]] = {
12812
+ distance: -1,
12813
+ parent: null
12814
+ };
12815
+ return graph;
12816
+ }
12817
+ function deriveBFS(fromModel) {
12818
+ const graph = buildGraph();
12819
+ const queue = [fromModel];
12820
+ graph[fromModel].distance = 0;
12821
+ while (queue.length) {
12822
+ const current = queue.pop();
12823
+ const adjacents = Object.keys(conversions[current]);
12824
+ for (let len = adjacents.length, i = 0; i < len; i++) {
12825
+ const adjacent = adjacents[i];
12826
+ const node = graph[adjacent];
12827
+ if (node.distance === -1) {
12828
+ node.distance = graph[current].distance + 1;
12829
+ node.parent = current;
12830
+ queue.unshift(adjacent);
12831
+ }
12832
+ }
12833
+ }
12834
+ return graph;
12835
+ }
12836
+ function link(from, to) {
12837
+ return function(args) {
12838
+ return to(from(args));
12839
+ };
12840
+ }
12841
+ function wrapConversion(toModel, graph) {
12842
+ const path = [graph[toModel].parent, toModel];
12843
+ let fn = conversions[graph[toModel].parent][toModel];
12844
+ let cur = graph[toModel].parent;
12845
+ while (graph[cur].parent) {
12846
+ path.unshift(graph[cur].parent);
12847
+ fn = link(conversions[graph[cur].parent][cur], fn);
12848
+ cur = graph[cur].parent;
12849
+ }
12850
+ fn.conversion = path;
12851
+ return fn;
12852
+ }
12853
+ module.exports = function(fromModel) {
12854
+ const graph = deriveBFS(fromModel);
12855
+ const conversion = {};
12856
+ const models = Object.keys(graph);
12857
+ for (let len = models.length, i = 0; i < len; i++) {
12858
+ const toModel = models[i];
12859
+ if (graph[toModel].parent === null) continue;
12860
+ conversion[toModel] = wrapConversion(toModel, graph);
12861
+ }
12862
+ return conversion;
12863
+ };
12864
+ }));
12865
+ //#endregion
12866
+ //#region ../../node_modules/.pnpm/color-convert@2.0.1/node_modules/color-convert/index.js
12867
+ var require_color_convert = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12868
+ var conversions = require_conversions();
12869
+ var route = require_route();
12870
+ var convert = {};
12871
+ var models = Object.keys(conversions);
12872
+ function wrapRaw(fn) {
12873
+ const wrappedFn = function(...args) {
12874
+ const arg0 = args[0];
12875
+ if (arg0 === void 0 || arg0 === null) return arg0;
12876
+ if (arg0.length > 1) args = arg0;
12877
+ return fn(args);
12878
+ };
12879
+ if ("conversion" in fn) wrappedFn.conversion = fn.conversion;
12880
+ return wrappedFn;
12881
+ }
12882
+ function wrapRounded(fn) {
12883
+ const wrappedFn = function(...args) {
12884
+ const arg0 = args[0];
12885
+ if (arg0 === void 0 || arg0 === null) return arg0;
12886
+ if (arg0.length > 1) args = arg0;
12887
+ const result = fn(args);
12888
+ if (typeof result === "object") for (let len = result.length, i = 0; i < len; i++) result[i] = Math.round(result[i]);
12889
+ return result;
12890
+ };
12891
+ if ("conversion" in fn) wrappedFn.conversion = fn.conversion;
12892
+ return wrappedFn;
12893
+ }
12894
+ models.forEach((fromModel) => {
12895
+ convert[fromModel] = {};
12896
+ Object.defineProperty(convert[fromModel], "channels", { value: conversions[fromModel].channels });
12897
+ Object.defineProperty(convert[fromModel], "labels", { value: conversions[fromModel].labels });
12898
+ const routes = route(fromModel);
12899
+ Object.keys(routes).forEach((toModel) => {
12900
+ const fn = routes[toModel];
12901
+ convert[fromModel][toModel] = wrapRounded(fn);
12902
+ convert[fromModel][toModel].raw = wrapRaw(fn);
12903
+ });
12904
+ });
12905
+ module.exports = convert;
12906
+ }));
12907
+ //#endregion
12908
+ //#region ../../node_modules/.pnpm/ansi-styles@4.3.0/node_modules/ansi-styles/index.js
12909
+ var require_ansi_styles = /* @__PURE__ */ __commonJSMin(((exports, module) => {
12910
+ var wrapAnsi16 = (fn, offset) => (...args) => {
12911
+ return `\u001B[${fn(...args) + offset}m`;
12912
+ };
12913
+ var wrapAnsi256 = (fn, offset) => (...args) => {
12914
+ const code = fn(...args);
12915
+ return `\u001B[${38 + offset};5;${code}m`;
12916
+ };
12917
+ var wrapAnsi16m = (fn, offset) => (...args) => {
12918
+ const rgb = fn(...args);
12919
+ return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
12920
+ };
12921
+ var ansi2ansi = (n) => n;
12922
+ var rgb2rgb = (r, g, b) => [
12923
+ r,
12924
+ g,
12925
+ b
12926
+ ];
12927
+ var setLazyProperty = (object, property, get) => {
12928
+ Object.defineProperty(object, property, {
12929
+ get: () => {
12930
+ const value = get();
12931
+ Object.defineProperty(object, property, {
12932
+ value,
12933
+ enumerable: true,
12934
+ configurable: true
12935
+ });
12936
+ return value;
12937
+ },
12938
+ enumerable: true,
12939
+ configurable: true
12940
+ });
12941
+ };
12942
+ /** @type {typeof import('color-convert')} */
12943
+ var colorConvert;
12944
+ var makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => {
12945
+ if (colorConvert === void 0) colorConvert = require_color_convert();
12946
+ const offset = isBackground ? 10 : 0;
12947
+ const styles = {};
12948
+ for (const [sourceSpace, suite] of Object.entries(colorConvert)) {
12949
+ const name = sourceSpace === "ansi16" ? "ansi" : sourceSpace;
12950
+ if (sourceSpace === targetSpace) styles[name] = wrap(identity, offset);
12951
+ else if (typeof suite === "object") styles[name] = wrap(suite[targetSpace], offset);
12952
+ }
12953
+ return styles;
12954
+ };
12955
+ function assembleStyles() {
12956
+ const codes = /* @__PURE__ */ new Map();
12957
+ const styles = {
12958
+ modifier: {
12959
+ reset: [0, 0],
12960
+ bold: [1, 22],
12961
+ dim: [2, 22],
12962
+ italic: [3, 23],
12963
+ underline: [4, 24],
12964
+ inverse: [7, 27],
12965
+ hidden: [8, 28],
12966
+ strikethrough: [9, 29]
12967
+ },
12968
+ color: {
12969
+ black: [30, 39],
12970
+ red: [31, 39],
12971
+ green: [32, 39],
12972
+ yellow: [33, 39],
12973
+ blue: [34, 39],
12974
+ magenta: [35, 39],
12975
+ cyan: [36, 39],
12976
+ white: [37, 39],
12977
+ blackBright: [90, 39],
12978
+ redBright: [91, 39],
12979
+ greenBright: [92, 39],
12980
+ yellowBright: [93, 39],
12981
+ blueBright: [94, 39],
12982
+ magentaBright: [95, 39],
12983
+ cyanBright: [96, 39],
12984
+ whiteBright: [97, 39]
12985
+ },
12986
+ bgColor: {
12987
+ bgBlack: [40, 49],
12988
+ bgRed: [41, 49],
12989
+ bgGreen: [42, 49],
12990
+ bgYellow: [43, 49],
12991
+ bgBlue: [44, 49],
12992
+ bgMagenta: [45, 49],
12993
+ bgCyan: [46, 49],
12994
+ bgWhite: [47, 49],
12995
+ bgBlackBright: [100, 49],
12996
+ bgRedBright: [101, 49],
12997
+ bgGreenBright: [102, 49],
12998
+ bgYellowBright: [103, 49],
12999
+ bgBlueBright: [104, 49],
13000
+ bgMagentaBright: [105, 49],
13001
+ bgCyanBright: [106, 49],
13002
+ bgWhiteBright: [107, 49]
13003
+ }
13004
+ };
13005
+ styles.color.gray = styles.color.blackBright;
13006
+ styles.bgColor.bgGray = styles.bgColor.bgBlackBright;
13007
+ styles.color.grey = styles.color.blackBright;
13008
+ styles.bgColor.bgGrey = styles.bgColor.bgBlackBright;
13009
+ for (const [groupName, group] of Object.entries(styles)) {
13010
+ for (const [styleName, style] of Object.entries(group)) {
13011
+ styles[styleName] = {
13012
+ open: `\u001B[${style[0]}m`,
13013
+ close: `\u001B[${style[1]}m`
13014
+ };
13015
+ group[styleName] = styles[styleName];
13016
+ codes.set(style[0], style[1]);
13017
+ }
13018
+ Object.defineProperty(styles, groupName, {
13019
+ value: group,
13020
+ enumerable: false
13021
+ });
13022
+ }
13023
+ Object.defineProperty(styles, "codes", {
13024
+ value: codes,
13025
+ enumerable: false
13026
+ });
13027
+ styles.color.close = "\x1B[39m";
13028
+ styles.bgColor.close = "\x1B[49m";
13029
+ setLazyProperty(styles.color, "ansi", () => makeDynamicStyles(wrapAnsi16, "ansi16", ansi2ansi, false));
13030
+ setLazyProperty(styles.color, "ansi256", () => makeDynamicStyles(wrapAnsi256, "ansi256", ansi2ansi, false));
13031
+ setLazyProperty(styles.color, "ansi16m", () => makeDynamicStyles(wrapAnsi16m, "rgb", rgb2rgb, false));
13032
+ setLazyProperty(styles.bgColor, "ansi", () => makeDynamicStyles(wrapAnsi16, "ansi16", ansi2ansi, true));
13033
+ setLazyProperty(styles.bgColor, "ansi256", () => makeDynamicStyles(wrapAnsi256, "ansi256", ansi2ansi, true));
13034
+ setLazyProperty(styles.bgColor, "ansi16m", () => makeDynamicStyles(wrapAnsi16m, "rgb", rgb2rgb, true));
13035
+ return styles;
13036
+ }
13037
+ Object.defineProperty(module, "exports", {
13038
+ enumerable: true,
13039
+ get: assembleStyles
13040
+ });
13041
+ }));
13042
+ //#endregion
13043
+ //#region ../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/browser.js
13044
+ var require_browser = /* @__PURE__ */ __commonJSMin(((exports, module) => {
13045
+ module.exports = {
13046
+ stdout: false,
13047
+ stderr: false
13048
+ };
13049
+ }));
13050
+ //#endregion
13051
+ //#region ../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/util.js
13052
+ var require_util = /* @__PURE__ */ __commonJSMin(((exports, module) => {
13053
+ var stringReplaceAll = (string, substring, replacer) => {
13054
+ let index = string.indexOf(substring);
13055
+ if (index === -1) return string;
13056
+ const substringLength = substring.length;
13057
+ let endIndex = 0;
13058
+ let returnValue = "";
13059
+ do {
13060
+ returnValue += string.substr(endIndex, index - endIndex) + substring + replacer;
13061
+ endIndex = index + substringLength;
13062
+ index = string.indexOf(substring, endIndex);
13063
+ } while (index !== -1);
13064
+ returnValue += string.substr(endIndex);
13065
+ return returnValue;
13066
+ };
13067
+ var stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => {
13068
+ let endIndex = 0;
13069
+ let returnValue = "";
13070
+ do {
13071
+ const gotCR = string[index - 1] === "\r";
13072
+ returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
13073
+ endIndex = index + 1;
13074
+ index = string.indexOf("\n", endIndex);
13075
+ } while (index !== -1);
13076
+ returnValue += string.substr(endIndex);
13077
+ return returnValue;
13078
+ };
13079
+ module.exports = {
13080
+ stringReplaceAll,
13081
+ stringEncaseCRLFWithFirstIndex
13082
+ };
13083
+ }));
13084
+ //#endregion
13085
+ //#region ../../node_modules/.pnpm/chalk@4.1.2/node_modules/chalk/source/templates.js
13086
+ var require_templates = /* @__PURE__ */ __commonJSMin(((exports, module) => {
13087
+ var TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
13088
+ var STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
13089
+ var STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
13090
+ var ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi;
13091
+ var ESCAPES = new Map([
13092
+ ["n", "\n"],
13093
+ ["r", "\r"],
13094
+ ["t", " "],
13095
+ ["b", "\b"],
13096
+ ["f", "\f"],
13097
+ ["v", "\v"],
13098
+ ["0", "\0"],
13099
+ ["\\", "\\"],
13100
+ ["e", "\x1B"],
13101
+ ["a", "\x07"]
13102
+ ]);
13103
+ function unescape(c) {
13104
+ const u = c[0] === "u";
13105
+ const bracket = c[1] === "{";
13106
+ if (u && !bracket && c.length === 5 || c[0] === "x" && c.length === 3) return String.fromCharCode(parseInt(c.slice(1), 16));
13107
+ if (u && bracket) return String.fromCodePoint(parseInt(c.slice(2, -1), 16));
13108
+ return ESCAPES.get(c) || c;
13109
+ }
13110
+ function parseArguments(name, arguments_) {
13111
+ const results = [];
13112
+ const chunks = arguments_.trim().split(/\s*,\s*/g);
13113
+ let matches;
13114
+ for (const chunk of chunks) {
13115
+ const number = Number(chunk);
13116
+ if (!Number.isNaN(number)) results.push(number);
13117
+ else if (matches = chunk.match(STRING_REGEX)) results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character));
13118
+ else throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
13119
+ }
13120
+ return results;
13121
+ }
13122
+ function parseStyle(style) {
13123
+ STYLE_REGEX.lastIndex = 0;
13124
+ const results = [];
13125
+ let matches;
13126
+ while ((matches = STYLE_REGEX.exec(style)) !== null) {
13127
+ const name = matches[1];
13128
+ if (matches[2]) {
13129
+ const args = parseArguments(name, matches[2]);
13130
+ results.push([name].concat(args));
13131
+ } else results.push([name]);
13132
+ }
13133
+ return results;
13134
+ }
13135
+ function buildStyle(chalk, styles) {
13136
+ const enabled = {};
13137
+ for (const layer of styles) for (const style of layer.styles) enabled[style[0]] = layer.inverse ? null : style.slice(1);
13138
+ let current = chalk;
13139
+ for (const [styleName, styles] of Object.entries(enabled)) {
13140
+ if (!Array.isArray(styles)) continue;
13141
+ if (!(styleName in current)) throw new Error(`Unknown Chalk style: ${styleName}`);
13142
+ current = styles.length > 0 ? current[styleName](...styles) : current[styleName];
13143
+ }
13144
+ return current;
13145
+ }
13146
+ module.exports = (chalk, temporary) => {
13147
+ const styles = [];
13148
+ const chunks = [];
13149
+ let chunk = [];
13150
+ temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => {
13151
+ if (escapeCharacter) chunk.push(unescape(escapeCharacter));
13152
+ else if (style) {
13153
+ const string = chunk.join("");
13154
+ chunk = [];
13155
+ chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string));
13156
+ styles.push({
13157
+ inverse,
13158
+ styles: parseStyle(style)
13159
+ });
13160
+ } else if (close) {
13161
+ if (styles.length === 0) throw new Error("Found extraneous } in Chalk template literal");
13162
+ chunks.push(buildStyle(chalk, styles)(chunk.join("")));
13163
+ chunk = [];
13164
+ styles.pop();
13165
+ } else chunk.push(character);
13166
+ });
13167
+ chunks.push(chunk.join(""));
13168
+ if (styles.length > 0) {
13169
+ const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? "" : "s"} (\`}\`)`;
13170
+ throw new Error(errMessage);
13171
+ }
13172
+ return chunks.join("");
13173
+ };
13174
+ }));
13175
+ (/* @__PURE__ */ __commonJSMin(((exports, module) => {
13176
+ var ansiStyles = require_ansi_styles();
13177
+ var { stdout: stdoutColor, stderr: stderrColor } = require_browser();
13178
+ var { stringReplaceAll, stringEncaseCRLFWithFirstIndex } = require_util();
13179
+ var { isArray } = Array;
13180
+ var levelMapping = [
13181
+ "ansi",
13182
+ "ansi",
13183
+ "ansi256",
13184
+ "ansi16m"
13185
+ ];
13186
+ var styles = Object.create(null);
13187
+ var applyOptions = (object, options = {}) => {
13188
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) throw new Error("The `level` option should be an integer from 0 to 3");
13189
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
13190
+ object.level = options.level === void 0 ? colorLevel : options.level;
13191
+ };
13192
+ var ChalkClass = class {
13193
+ constructor(options) {
13194
+ return chalkFactory(options);
13195
+ }
13196
+ };
13197
+ var chalkFactory = (options) => {
13198
+ const chalk = {};
13199
+ applyOptions(chalk, options);
13200
+ chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_);
13201
+ Object.setPrototypeOf(chalk, Chalk.prototype);
13202
+ Object.setPrototypeOf(chalk.template, chalk);
13203
+ chalk.template.constructor = () => {
13204
+ throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
13205
+ };
13206
+ chalk.template.Instance = ChalkClass;
13207
+ return chalk.template;
13208
+ };
13209
+ function Chalk(options) {
13210
+ return chalkFactory(options);
13211
+ }
13212
+ for (const [styleName, style] of Object.entries(ansiStyles)) styles[styleName] = { get() {
13213
+ const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty);
13214
+ Object.defineProperty(this, styleName, { value: builder });
13215
+ return builder;
13216
+ } };
13217
+ styles.visible = { get() {
13218
+ const builder = createBuilder(this, this._styler, true);
13219
+ Object.defineProperty(this, "visible", { value: builder });
13220
+ return builder;
13221
+ } };
13222
+ var usedModels = [
13223
+ "rgb",
13224
+ "hex",
13225
+ "keyword",
13226
+ "hsl",
13227
+ "hsv",
13228
+ "hwb",
13229
+ "ansi",
13230
+ "ansi256"
13231
+ ];
13232
+ for (const model of usedModels) styles[model] = { get() {
13233
+ const { level } = this;
13234
+ return function(...arguments_) {
13235
+ const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler);
13236
+ return createBuilder(this, styler, this._isEmpty);
13237
+ };
13238
+ } };
13239
+ for (const model of usedModels) {
13240
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
13241
+ styles[bgModel] = { get() {
13242
+ const { level } = this;
13243
+ return function(...arguments_) {
13244
+ const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler);
13245
+ return createBuilder(this, styler, this._isEmpty);
13246
+ };
13247
+ } };
13248
+ }
13249
+ var proto = Object.defineProperties(() => {}, {
13250
+ ...styles,
13251
+ level: {
13252
+ enumerable: true,
13253
+ get() {
13254
+ return this._generator.level;
13255
+ },
13256
+ set(level) {
13257
+ this._generator.level = level;
13258
+ }
13259
+ }
13260
+ });
13261
+ var createStyler = (open, close, parent) => {
13262
+ let openAll;
13263
+ let closeAll;
13264
+ if (parent === void 0) {
13265
+ openAll = open;
13266
+ closeAll = close;
13267
+ } else {
13268
+ openAll = parent.openAll + open;
13269
+ closeAll = close + parent.closeAll;
13270
+ }
13271
+ return {
13272
+ open,
13273
+ close,
13274
+ openAll,
13275
+ closeAll,
13276
+ parent
13277
+ };
13278
+ };
13279
+ var createBuilder = (self, _styler, _isEmpty) => {
13280
+ const builder = (...arguments_) => {
13281
+ if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) return applyStyle(builder, chalkTag(builder, ...arguments_));
13282
+ return applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
13283
+ };
13284
+ Object.setPrototypeOf(builder, proto);
13285
+ builder._generator = self;
13286
+ builder._styler = _styler;
13287
+ builder._isEmpty = _isEmpty;
13288
+ return builder;
13289
+ };
13290
+ var applyStyle = (self, string) => {
13291
+ if (self.level <= 0 || !string) return self._isEmpty ? "" : string;
13292
+ let styler = self._styler;
13293
+ if (styler === void 0) return string;
13294
+ const { openAll, closeAll } = styler;
13295
+ if (string.indexOf("\x1B") !== -1) while (styler !== void 0) {
13296
+ string = stringReplaceAll(string, styler.close, styler.open);
13297
+ styler = styler.parent;
13298
+ }
13299
+ const lfIndex = string.indexOf("\n");
13300
+ if (lfIndex !== -1) string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
13301
+ return openAll + string + closeAll;
13302
+ };
13303
+ var template;
13304
+ var chalkTag = (chalk, ...strings) => {
13305
+ const [firstString] = strings;
13306
+ if (!isArray(firstString) || !isArray(firstString.raw)) return strings.join(" ");
13307
+ const arguments_ = strings.slice(1);
13308
+ const parts = [firstString.raw[0]];
13309
+ for (let i = 1; i < firstString.length; i++) parts.push(String(arguments_[i - 1]).replace(/[{}\\]/g, "\\$&"), String(firstString.raw[i]));
13310
+ if (template === void 0) template = require_templates();
13311
+ return template(chalk, parts.join(""));
13312
+ };
13313
+ Object.defineProperties(Chalk.prototype, styles);
13314
+ var chalk = Chalk();
13315
+ chalk.supportsColor = stdoutColor;
13316
+ chalk.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
13317
+ chalk.stderr.supportsColor = stderrColor;
13318
+ module.exports = chalk;
13319
+ })))();
13320
+ /**
13321
+ * Detect whether an error (or AggregateError wrapping multiple attempts)
13322
+ * represents an ECONNREFUSED — i.e. the database is simply not running.
13323
+ *
13324
+ * Handles:
13325
+ * - Direct `{ code: "ECONNREFUSED" }` errors from Node `net`
13326
+ * - `AggregateError` from dual-stack IPv4+IPv6 connection attempts
13327
+ * - Drizzle's `cause`-wrapped pg errors
13328
+ */
13329
+ function isEconnrefused(err) {
13330
+ if (!err || typeof err !== "object") return false;
13331
+ const e = err;
13332
+ if (e.code === "ECONNREFUSED") return true;
13333
+ if (Array.isArray(e.errors)) return e.errors.some((inner) => inner && typeof inner === "object" && inner.code === "ECONNREFUSED");
13334
+ if (e.cause && typeof e.cause === "object") return isEconnrefused(e.cause);
13335
+ return false;
13336
+ }
13337
+ //#endregion
10593
13338
  //#region src/PostgresBootstrapper.ts
10594
13339
  /**
10595
13340
  * PostgresBootstrapper
@@ -10636,6 +13381,18 @@ function createPostgresBootstrapper(pgConfig) {
10636
13381
  try {
10637
13382
  await schemaAwareDb.execute(sql`SELECT 1`);
10638
13383
  } catch (err) {
13384
+ if (isEconnrefused(err)) {
13385
+ let hostInfo = pgConfig.connectionString || "unknown";
13386
+ try {
13387
+ const parsed = new URL(pgConfig.connectionString || "");
13388
+ hostInfo = `${parsed.hostname}:${parsed.port || 5432}`;
13389
+ } catch {}
13390
+ const message = `
13391
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
13392
+ ❌ Cannot connect to PostgreSQL at ${hostInfo}\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n The database server is not running or is not accepting\n connections. Common fixes:\n\n • brew services start postgresql@18\n • docker compose up -d postgres\n • Verify DATABASE_URL in your .env file\n\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n`;
13393
+ logger.error(message);
13394
+ throw new Error(`Cannot connect to PostgreSQL at ${hostInfo}: connection refused. Is the database running?`);
13395
+ }
10639
13396
  logger.error("❌ Failed to connect to PostgreSQL", { error: err });
10640
13397
  logger.warn("⚠️ Continuing without initial database verification. Drizzle/PG will attempt to connect on subsequent queries.");
10641
13398
  }
@@ -10798,6 +13555,6 @@ function createPostgresAdapter(pgConfig) {
10798
13555
  };
10799
13556
  }
10800
13557
  //#endregion
10801
- export { AuthenticatedPostgresBackendDriver, BranchService, DatabasePoolManager, DrizzleConditionBuilder, PostgresBackendDriver, PostgresCollectionRegistry, PostgresConditionBuilder, PostgresRealtimeProvider, RealtimeService, appConfig, createAuthSchema, createDirectDatabaseConnection, createPostgresAdapter, createPostgresBootstrapper, createPostgresDatabaseConnection, createPostgresWebSocket, createReadReplicaConnection, generateSchema, mfaChallenges, mfaChallengesRelations, mfaFactors, mfaFactorsRelations, passwordResetTokens, passwordResetTokensRelations, recoveryCodes, recoveryCodesRelations, refreshTokens, refreshTokensRelations, userIdentities, userIdentitiesRelations, users, usersRelations, usersSchema };
13558
+ export { AuthenticatedPostgresBackendDriver, BranchService, DatabasePoolManager, DrizzleConditionBuilder, PostgresBackendDriver, PostgresCollectionRegistry, PostgresConditionBuilder, PostgresRealtimeProvider, RealtimeService, appConfig, createAuthSchema, createDirectDatabaseConnection, createPostgresAdapter, createPostgresBootstrapper, createPostgresDatabaseConnection, createPostgresWebSocket, createReadReplicaConnection, generateSchema, magicLinkTokens, magicLinkTokensRelations, mfaChallenges, mfaChallengesRelations, mfaFactors, mfaFactorsRelations, passwordResetTokens, passwordResetTokensRelations, recoveryCodes, recoveryCodesRelations, refreshTokens, refreshTokensRelations, userIdentities, userIdentitiesRelations, users, usersRelations, usersSchema };
10802
13559
 
10803
13560
  //# sourceMappingURL=index.es.js.map