clivly 0.8.0 → 0.9.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 (114) hide show
  1. package/README.md +330 -134
  2. package/core-drizzle.cjs +3 -1
  3. package/core-drizzle.d.cts +3 -2
  4. package/core-drizzle.d.mts +3 -2
  5. package/core-drizzle.mjs +2 -2
  6. package/core-entity-config.cjs +1 -1
  7. package/core-entity-config.d.cts +2 -2
  8. package/core-entity-config.d.mts +2 -2
  9. package/core-entity-config.mjs +1 -1
  10. package/core-entity-heuristics.d.cts +3 -2
  11. package/core-entity-heuristics.d.mts +3 -2
  12. package/core-mapping-form.d.cts +1 -1
  13. package/core-mapping-form.d.mts +1 -1
  14. package/core-mappings-config.cjs +1 -1
  15. package/core-mappings-config.d.cts +1 -1
  16. package/core-mappings-config.d.mts +1 -1
  17. package/core-mappings-config.mjs +1 -1
  18. package/core-sync-engine.cjs +1 -1
  19. package/core-sync-engine.d.cts +1 -1
  20. package/core-sync-engine.d.mts +1 -1
  21. package/core-sync-engine.mjs +1 -1
  22. package/core-view-compiler.cjs +1 -1
  23. package/core-view-compiler.d.cts +1 -1
  24. package/core-view-compiler.d.mts +1 -1
  25. package/core-view-compiler.mjs +1 -1
  26. package/core.cjs +21 -5
  27. package/core.d.cts +7 -6
  28. package/core.d.mts +7 -6
  29. package/core.mjs +7 -6
  30. package/drizzle-3kvhkwO7.mjs +110 -0
  31. package/drizzle-BhN5M9zt.d.cts +41 -0
  32. package/drizzle-bfjVzYR6.cjs +127 -0
  33. package/drizzle-kBULBAOa.d.mts +41 -0
  34. package/drizzle.cjs +12 -40
  35. package/drizzle.d.cts +3 -11
  36. package/drizzle.d.mts +3 -11
  37. package/drizzle.mjs +12 -41
  38. package/{entity-config-DoUCXtq5.d.cts → entity-config-C4Yf_fPj.d.cts} +120 -1
  39. package/{entity-config-DoUCXtq5.d.mts → entity-config-C4Yf_fPj.d.mts} +120 -1
  40. package/entity-config-CsLl-ftC.cjs +727 -0
  41. package/entity-config-D3LmzgLb.mjs +612 -0
  42. package/index.cjs +764 -120
  43. package/index.d.cts +12 -0
  44. package/index.d.mts +12 -0
  45. package/index.mjs +765 -121
  46. package/internal-B8ydhsKd.d.cts +73 -0
  47. package/internal-BARjyN4n.cjs +97 -0
  48. package/internal-DMySVbM0.mjs +68 -0
  49. package/internal-MBkNo3bw.d.mts +73 -0
  50. package/internal-drizzle.cjs +3 -1
  51. package/internal-drizzle.d.cts +2 -2
  52. package/internal-drizzle.d.mts +2 -2
  53. package/internal-drizzle.mjs +2 -2
  54. package/internal-entity-config.cjs +1 -1
  55. package/internal-entity-config.d.cts +2 -2
  56. package/internal-entity-config.d.mts +2 -2
  57. package/internal-entity-config.mjs +1 -1
  58. package/internal-entity-heuristics.cjs +28 -8
  59. package/internal-entity-heuristics.d.cts +2 -12
  60. package/internal-entity-heuristics.d.mts +2 -12
  61. package/internal-entity-heuristics.mjs +28 -8
  62. package/internal-mapping-form.d.cts +1 -1
  63. package/internal-mapping-form.d.mts +1 -1
  64. package/internal-mappings-config.cjs +1 -1
  65. package/internal-mappings-config.d.cts +1 -1
  66. package/internal-mappings-config.d.mts +1 -1
  67. package/internal-mappings-config.mjs +1 -1
  68. package/internal-sync-engine.cjs +1 -1
  69. package/internal-sync-engine.d.cts +1 -1
  70. package/internal-sync-engine.d.mts +1 -1
  71. package/internal-sync-engine.mjs +1 -1
  72. package/internal-view-compiler.cjs +1 -1
  73. package/internal-view-compiler.d.cts +1 -1
  74. package/internal-view-compiler.d.mts +1 -1
  75. package/internal-view-compiler.mjs +1 -1
  76. package/internal.cjs +21 -4
  77. package/internal.d.cts +7 -6
  78. package/internal.d.mts +7 -6
  79. package/internal.mjs +7 -5
  80. package/{mapping-form-D93lhHEc.d.mts → mapping-form-43bwOTat.d.cts} +1 -1
  81. package/{mapping-form-lfyEE7EJ.d.cts → mapping-form-DUvWUYCo.d.mts} +1 -1
  82. package/{mappings-config-BsRADNRv.cjs → mappings-config-BSSwdHiq.cjs} +32 -6
  83. package/mappings-config-BpcR8bBo.d.mts +167 -0
  84. package/{mappings-config-Dbgxx3Nv.mjs → mappings-config-bJQT_gSa.mjs} +32 -6
  85. package/mappings-config-xsLMn3I-.d.cts +167 -0
  86. package/namespace-probe-BSH_p9TK.d.cts +381 -0
  87. package/namespace-probe-Dsp5uNkS.d.mts +381 -0
  88. package/package.json +1 -1
  89. package/{entity-config-va2bkH5o.mjs → projection-C5244vGa.cjs} +130 -309
  90. package/{entity-config-D87rV-tE.cjs → projection-D7xmQP4S.mjs} +60 -381
  91. package/{sdk-iqOXeWIp.cjs → sdk-Bj-ZDf4u.cjs} +126 -28
  92. package/{sdk-C6WANW8M.mjs → sdk-BvRD2jAp.mjs} +126 -28
  93. package/sdk.cjs +2 -2
  94. package/sdk.d.cts +36 -1
  95. package/sdk.d.mts +36 -1
  96. package/sdk.mjs +2 -2
  97. package/{sync-engine-Do5ru3WF.mjs → sync-engine-Bg6-SznL.mjs} +9 -2
  98. package/{sync-engine-CzEbpQGv.cjs → sync-engine-DEJvKw6E.cjs} +9 -2
  99. package/{sync-engine-DGk_AeHJ.d.mts → sync-engine-GNqRB8eS.d.cts} +2 -2
  100. package/{sync-engine-B7QIbXro.d.cts → sync-engine-ZsusW-q_.d.mts} +2 -2
  101. package/{view-compiler-BWz0sGdm.d.cts → view-compiler-Cin0neDO.d.mts} +1 -1
  102. package/{view-compiler-ChWr_Lml.mjs → view-compiler-DlTpOfZi.mjs} +81 -12
  103. package/{view-compiler-BIwvm-o2.cjs → view-compiler-DplczSjF.cjs} +81 -12
  104. package/{view-compiler-Bn_EJJMO.d.mts → view-compiler-Ll9cbIJz.d.cts} +1 -1
  105. package/vite.d.cts +1 -1
  106. package/vite.d.mts +1 -1
  107. package/drizzle-B89tLo4T.mjs +0 -31
  108. package/drizzle-CFOr9dU9.d.mts +0 -20
  109. package/drizzle-DiReZf6d.cjs +0 -36
  110. package/drizzle-DmeKSqeF.d.cts +0 -20
  111. package/mappings-config-DsUa7-1w.d.mts +0 -41
  112. package/mappings-config-XmzB4dag.d.cts +0 -41
  113. package/types-CsL0rFYh.d.cts +0 -155
  114. package/types-CsL0rFYh.d.mts +0 -155
package/drizzle.cjs CHANGED
@@ -1,43 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_drizzle_meta = require("./drizzle-meta-Bb1JWYqf.cjs");
3
- const require_drizzle = require("./drizzle-DiReZf6d.cjs");
3
+ const require_drizzle = require("./drizzle-bfjVzYR6.cjs");
4
4
  let drizzle_orm = require("drizzle-orm");
5
- let drizzle_orm_pg_core = require("drizzle-orm/pg-core");
6
5
  //#region ../sdk/src/drizzle.ts
7
- function buildColumnsMeta(table) {
8
- const columns = (0, drizzle_orm.getTableColumns)(table);
9
- const fkByColumn = /* @__PURE__ */ new Map();
10
- try {
11
- for (const fk of (0, drizzle_orm_pg_core.getTableConfig)(table).foreignKeys) {
12
- const ref = fk.reference();
13
- const foreignTable = (0, drizzle_orm.getTableName)(ref.foreignTable);
14
- ref.columns.forEach((col, i) => {
15
- const foreignCol = ref.foreignColumns[i];
16
- if (foreignCol) fkByColumn.set(col.name, {
17
- table: foreignTable,
18
- column: foreignCol.name
19
- });
20
- });
21
- }
22
- } catch {}
23
- return Object.values(columns).map((col) => {
24
- const references = fkByColumn.get(col.name);
25
- let type;
26
- try {
27
- type = col.getSQLType();
28
- } catch {
29
- type = void 0;
30
- }
31
- return {
32
- name: col.name,
33
- type,
34
- nullable: !col.notNull,
35
- isPrimaryKey: Boolean(col.primary),
36
- isForeignKey: references !== void 0,
37
- ...references ? { references } : {}
38
- };
39
- });
40
- }
41
6
  function inferIdField(table) {
42
7
  const columns = (0, drizzle_orm.getTableColumns)(table);
43
8
  const primaryKeys = Object.entries(columns).filter(([, column]) => column.primary);
@@ -65,18 +30,24 @@ function fromDrizzle(db, table, opts) {
65
30
  const idColumn = columns[idField];
66
31
  if (!cursorColumn) throw new Error(`fromDrizzle: cursorField "${opts.cursorField}" is not a column on "${(0, drizzle_orm.getTableName)(table)}".`);
67
32
  if (!idColumn) throw new Error(`fromDrizzle: idField "${idField}" is not a column on "${(0, drizzle_orm.getTableName)(table)}".`);
33
+ const projection = {};
34
+ for (const column of Object.values(columns)) projection[column.name] = column;
35
+ const cursorColumnName = cursorColumn.name;
36
+ const idColumnName = idColumn.name;
68
37
  const source = {
69
38
  entity: opts.entity,
70
- cursorField: opts.cursorField,
71
- idField,
72
- fetchPage: ({ since, limit }) => drizzleDb.select().from(table).where(since ? drizzle_orm.sql`(${cursorColumn}, ${idColumn}) > (${since.time}, ${since.id})` : void 0).orderBy((0, drizzle_orm.asc)(cursorColumn), (0, drizzle_orm.asc)(idColumn)).limit(limit)
39
+ cursorField: cursorColumnName,
40
+ idField: idColumnName,
41
+ fetchPage: ({ since, limit }) => drizzleDb.select(projection).from(table).where(since ? drizzle_orm.sql`(${cursorColumn}, ${idColumn}) > (${since.time}, ${since.id})` : void 0).orderBy((0, drizzle_orm.asc)(cursorColumn), (0, drizzle_orm.asc)(idColumn)).limit(limit)
73
42
  };
43
+ const uniqueConstraints = require_drizzle.buildUniqueConstraints(table);
74
44
  const meta = {
75
45
  columnKeys: Object.keys(columns),
76
46
  cursorField: opts.cursorField,
77
47
  idField,
78
48
  tableName: (0, drizzle_orm.getTableName)(table),
79
- columnsMeta: buildColumnsMeta(table)
49
+ columnsMeta: require_drizzle.buildColumnsMeta(table),
50
+ ...uniqueConstraints === void 0 ? {} : { uniqueConstraints }
80
51
  };
81
52
  Object.defineProperty(source, require_drizzle_meta.DRIZZLE_META, {
82
53
  value: meta,
@@ -104,6 +75,7 @@ function drizzleIntrospector(db) {
104
75
  };
105
76
  }
106
77
  //#endregion
78
+ exports.buildUniqueConstraints = require_drizzle.buildUniqueConstraints;
107
79
  exports.discoverFromDrizzle = require_drizzle.discoverFromDrizzle;
108
80
  exports.drizzleIntrospector = drizzleIntrospector;
109
81
  exports.fromDrizzle = fromDrizzle;
package/drizzle.d.cts CHANGED
@@ -1,14 +1,6 @@
1
- import { t as discoverFromDrizzle } from "./drizzle-DmeKSqeF.cjs";
2
- import { n as SyncSource } from "./types-CsL0rFYh.cjs";
1
+ import { n as buildUniqueConstraints, r as discoverFromDrizzle } from "./drizzle-BhN5M9zt.cjs";
2
+ import { m as SyncSource, t as NamespaceIntrospector } from "./namespace-probe-BSH_p9TK.cjs";
3
3
  import { Table } from "drizzle-orm";
4
- //#region ../sdk/src/namespace-probe.d.ts
5
- interface NamespaceIntrospector {
6
- /** All base table names in the reachable schema. */
7
- listTables(): Promise<string[]>;
8
- /** Prove a table is genuinely selectable (SELECT ... LIMIT 1). Throws if unreachable/denied. */
9
- sampleSelect(table: string): Promise<void>;
10
- }
11
- //#endregion
12
4
  //#region ../sdk/src/drizzle.d.ts
13
5
  interface DrizzleDb {
14
6
  select: (...args: any[]) => any;
@@ -33,4 +25,4 @@ declare function fromDrizzle(db: DrizzleDb, table: Table, opts: {
33
25
  */
34
26
  declare function drizzleIntrospector(db: unknown): NamespaceIntrospector;
35
27
  //#endregion
36
- export { discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
28
+ export { buildUniqueConstraints, discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
package/drizzle.d.mts CHANGED
@@ -1,14 +1,6 @@
1
- import { t as discoverFromDrizzle } from "./drizzle-CFOr9dU9.mjs";
2
- import { n as SyncSource } from "./types-CsL0rFYh.mjs";
1
+ import { n as buildUniqueConstraints, r as discoverFromDrizzle } from "./drizzle-kBULBAOa.mjs";
2
+ import { m as SyncSource, t as NamespaceIntrospector } from "./namespace-probe-Dsp5uNkS.mjs";
3
3
  import { Table } from "drizzle-orm";
4
- //#region ../sdk/src/namespace-probe.d.ts
5
- interface NamespaceIntrospector {
6
- /** All base table names in the reachable schema. */
7
- listTables(): Promise<string[]>;
8
- /** Prove a table is genuinely selectable (SELECT ... LIMIT 1). Throws if unreachable/denied. */
9
- sampleSelect(table: string): Promise<void>;
10
- }
11
- //#endregion
12
4
  //#region ../sdk/src/drizzle.d.ts
13
5
  interface DrizzleDb {
14
6
  select: (...args: any[]) => any;
@@ -33,4 +25,4 @@ declare function fromDrizzle(db: DrizzleDb, table: Table, opts: {
33
25
  */
34
26
  declare function drizzleIntrospector(db: unknown): NamespaceIntrospector;
35
27
  //#endregion
36
- export { discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
28
+ export { buildUniqueConstraints, discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
package/drizzle.mjs CHANGED
@@ -1,42 +1,7 @@
1
1
  import { t as DRIZZLE_META } from "./drizzle-meta-D-5k3n0i.mjs";
2
- import { t as discoverFromDrizzle } from "./drizzle-B89tLo4T.mjs";
2
+ import { n as buildUniqueConstraints, r as discoverFromDrizzle, t as buildColumnsMeta } from "./drizzle-3kvhkwO7.mjs";
3
3
  import { asc, getTableColumns, getTableName, sql } from "drizzle-orm";
4
- import { getTableConfig } from "drizzle-orm/pg-core";
5
4
  //#region ../sdk/src/drizzle.ts
6
- function buildColumnsMeta(table) {
7
- const columns = getTableColumns(table);
8
- const fkByColumn = /* @__PURE__ */ new Map();
9
- try {
10
- for (const fk of getTableConfig(table).foreignKeys) {
11
- const ref = fk.reference();
12
- const foreignTable = getTableName(ref.foreignTable);
13
- ref.columns.forEach((col, i) => {
14
- const foreignCol = ref.foreignColumns[i];
15
- if (foreignCol) fkByColumn.set(col.name, {
16
- table: foreignTable,
17
- column: foreignCol.name
18
- });
19
- });
20
- }
21
- } catch {}
22
- return Object.values(columns).map((col) => {
23
- const references = fkByColumn.get(col.name);
24
- let type;
25
- try {
26
- type = col.getSQLType();
27
- } catch {
28
- type = void 0;
29
- }
30
- return {
31
- name: col.name,
32
- type,
33
- nullable: !col.notNull,
34
- isPrimaryKey: Boolean(col.primary),
35
- isForeignKey: references !== void 0,
36
- ...references ? { references } : {}
37
- };
38
- });
39
- }
40
5
  function inferIdField(table) {
41
6
  const columns = getTableColumns(table);
42
7
  const primaryKeys = Object.entries(columns).filter(([, column]) => column.primary);
@@ -64,18 +29,24 @@ function fromDrizzle(db, table, opts) {
64
29
  const idColumn = columns[idField];
65
30
  if (!cursorColumn) throw new Error(`fromDrizzle: cursorField "${opts.cursorField}" is not a column on "${getTableName(table)}".`);
66
31
  if (!idColumn) throw new Error(`fromDrizzle: idField "${idField}" is not a column on "${getTableName(table)}".`);
32
+ const projection = {};
33
+ for (const column of Object.values(columns)) projection[column.name] = column;
34
+ const cursorColumnName = cursorColumn.name;
35
+ const idColumnName = idColumn.name;
67
36
  const source = {
68
37
  entity: opts.entity,
69
- cursorField: opts.cursorField,
70
- idField,
71
- fetchPage: ({ since, limit }) => drizzleDb.select().from(table).where(since ? sql`(${cursorColumn}, ${idColumn}) > (${since.time}, ${since.id})` : void 0).orderBy(asc(cursorColumn), asc(idColumn)).limit(limit)
38
+ cursorField: cursorColumnName,
39
+ idField: idColumnName,
40
+ fetchPage: ({ since, limit }) => drizzleDb.select(projection).from(table).where(since ? sql`(${cursorColumn}, ${idColumn}) > (${since.time}, ${since.id})` : void 0).orderBy(asc(cursorColumn), asc(idColumn)).limit(limit)
72
41
  };
42
+ const uniqueConstraints = buildUniqueConstraints(table);
73
43
  const meta = {
74
44
  columnKeys: Object.keys(columns),
75
45
  cursorField: opts.cursorField,
76
46
  idField,
77
47
  tableName: getTableName(table),
78
- columnsMeta: buildColumnsMeta(table)
48
+ columnsMeta: buildColumnsMeta(table),
49
+ ...uniqueConstraints === void 0 ? {} : { uniqueConstraints }
79
50
  };
80
51
  Object.defineProperty(source, DRIZZLE_META, {
81
52
  value: meta,
@@ -103,4 +74,4 @@ function drizzleIntrospector(db) {
103
74
  };
104
75
  }
105
76
  //#endregion
106
- export { discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
77
+ export { buildUniqueConstraints, discoverFromDrizzle, drizzleIntrospector, fromDrizzle };
@@ -2312,6 +2312,53 @@ declare const entitySchema: ZodObject<{
2312
2312
  }, $strict>]>;
2313
2313
  }, $strict>>>;
2314
2314
  targetObjectTypeId: ZodOptional<ZodString>;
2315
+ projection: ZodOptional<ZodObject<{
2316
+ version: ZodLiteral<1>;
2317
+ kind: ZodLiteral<"projection">;
2318
+ entityKey: ZodString;
2319
+ baseTable: ZodString;
2320
+ joins: ZodArray<ZodObject<{
2321
+ key: ZodString;
2322
+ table: ZodString;
2323
+ type: ZodEnum<{
2324
+ inner: "inner";
2325
+ left: "left";
2326
+ }>;
2327
+ on: ZodArray<ZodObject<{
2328
+ left: ZodObject<{
2329
+ table: ZodString;
2330
+ column: ZodString;
2331
+ }, $strict>;
2332
+ op: ZodLiteral<"eq">;
2333
+ right: ZodObject<{
2334
+ table: ZodString;
2335
+ column: ZodString;
2336
+ }, $strict>;
2337
+ }, $strict>>;
2338
+ }, $strict>>;
2339
+ fieldBindings: ZodRecord<ZodString, ZodObject<{
2340
+ from: ZodObject<{
2341
+ table: ZodString;
2342
+ column: ZodString;
2343
+ }, $strict>;
2344
+ }, $strict>>;
2345
+ identity: ZodUnion<readonly [ZodObject<{
2346
+ kind: ZodLiteral<"base_pk">;
2347
+ column: ZodOptional<ZodString>;
2348
+ }, $strict>, ZodObject<{
2349
+ kind: ZodLiteral<"column">;
2350
+ from: ZodObject<{
2351
+ table: ZodString;
2352
+ column: ZodString;
2353
+ }, $strict>;
2354
+ }, $strict>, ZodObject<{
2355
+ kind: ZodLiteral<"composite">;
2356
+ parts: ZodArray<ZodObject<{
2357
+ table: ZodString;
2358
+ column: ZodString;
2359
+ }, $strict>>;
2360
+ }, $strict>]>;
2361
+ }, $strict>>;
2315
2362
  }, $strict>;
2316
2363
  type ClivlyEntityConfig = output<typeof entitySchema>;
2317
2364
  declare const entitiesConfigSchema: ZodObject<{
@@ -2360,6 +2407,53 @@ declare const entitiesConfigSchema: ZodObject<{
2360
2407
  }, $strict>]>;
2361
2408
  }, $strict>>>;
2362
2409
  targetObjectTypeId: ZodOptional<ZodString>;
2410
+ projection: ZodOptional<ZodObject<{
2411
+ version: ZodLiteral<1>;
2412
+ kind: ZodLiteral<"projection">;
2413
+ entityKey: ZodString;
2414
+ baseTable: ZodString;
2415
+ joins: ZodArray<ZodObject<{
2416
+ key: ZodString;
2417
+ table: ZodString;
2418
+ type: ZodEnum<{
2419
+ inner: "inner";
2420
+ left: "left";
2421
+ }>;
2422
+ on: ZodArray<ZodObject<{
2423
+ left: ZodObject<{
2424
+ table: ZodString;
2425
+ column: ZodString;
2426
+ }, $strict>;
2427
+ op: ZodLiteral<"eq">;
2428
+ right: ZodObject<{
2429
+ table: ZodString;
2430
+ column: ZodString;
2431
+ }, $strict>;
2432
+ }, $strict>>;
2433
+ }, $strict>>;
2434
+ fieldBindings: ZodRecord<ZodString, ZodObject<{
2435
+ from: ZodObject<{
2436
+ table: ZodString;
2437
+ column: ZodString;
2438
+ }, $strict>;
2439
+ }, $strict>>;
2440
+ identity: ZodUnion<readonly [ZodObject<{
2441
+ kind: ZodLiteral<"base_pk">;
2442
+ column: ZodOptional<ZodString>;
2443
+ }, $strict>, ZodObject<{
2444
+ kind: ZodLiteral<"column">;
2445
+ from: ZodObject<{
2446
+ table: ZodString;
2447
+ column: ZodString;
2448
+ }, $strict>;
2449
+ }, $strict>, ZodObject<{
2450
+ kind: ZodLiteral<"composite">;
2451
+ parts: ZodArray<ZodObject<{
2452
+ table: ZodString;
2453
+ column: ZodString;
2454
+ }, $strict>>;
2455
+ }, $strict>]>;
2456
+ }, $strict>>;
2363
2457
  }, $strict>>;
2364
2458
  }, $strict>;
2365
2459
  type ClivlyEntitiesConfig = output<typeof entitiesConfigSchema>;
@@ -2384,14 +2478,39 @@ declare function defineClivlyConfig(config: ClivlyEntitiesConfig, options?: {
2384
2478
  strict?: boolean;
2385
2479
  onWarn?: (message: string) => void;
2386
2480
  }): ClivlyEntitiesConfig;
2481
+ /**
2482
+ * Per-column metadata a host reports for a discovered table. Structurally
2483
+ * identical to the SDK's `DiscoveredColumn` and to `entity-heuristics.ts`'s
2484
+ * (currently separate) `DiscoveredColumnMeta` — a later task converges that
2485
+ * module onto this one. Every field is optional: a v1 host reports column
2486
+ * names only.
2487
+ */
2488
+ interface DiscoveredColumnMeta {
2489
+ isForeignKey?: boolean;
2490
+ isPrimaryKey?: boolean;
2491
+ name: string;
2492
+ nullable?: boolean;
2493
+ references?: {
2494
+ table: string;
2495
+ column: string;
2496
+ };
2497
+ type?: string;
2498
+ }
2387
2499
  /**
2388
2500
  * A host table the SDK reported for discovery. Structurally identical to the
2389
2501
  * SDK's `DiscoveredTable`; duplicated here to keep `@clivly/core` free of an
2390
2502
  * SDK dependency (core is the base contract SDK builds on).
2503
+ *
2504
+ * `columns` is the stable v1 contract. `columnsMeta` and `uniqueConstraints`
2505
+ * are the enrichment projection mappings require — absent on v1 hosts, which
2506
+ * is why projection validation fails closed rather than assuming "no keys".
2391
2507
  */
2392
2508
  interface DiscoveredSchemaTable {
2393
2509
  columns: string[];
2510
+ columnsMeta?: DiscoveredColumnMeta[];
2394
2511
  name: string;
2512
+ /** Every unique key as DB column names; PKs included. Absent = unknown. */
2513
+ uniqueConstraints?: string[][];
2395
2514
  }
2396
2515
  interface ConfigValidationError {
2397
2516
  message: string;
@@ -2413,4 +2532,4 @@ interface ConfigValidationResult {
2413
2532
  */
2414
2533
  declare function validateEntitiesConfig(config: ClivlyEntitiesConfig, schema: DiscoveredSchemaTable[]): ConfigValidationResult;
2415
2534
  //#endregion
2416
- export { validateEntitiesConfig as C, relationshipsSchema as S, RelationshipsMap as _, ClivlyEntitiesConfig as a, filterSchema as b, ConfigValidationResult as c, FilterExpr as d, FilterValue as f, RelationshipVia as g, RelationshipSpec as h, ClivlyConfigError as i, CrmConcept as l, MaterializingConcept as m, CRM_CONCEPTS as n, ClivlyEntityConfig as o, MATERIALIZING_CONCEPTS as p, CUSTOM_CONCEPT as r, ConfigValidationError as s, CANONICAL_FIELDS as t, DiscoveredSchemaTable as u, defineClivlyConfig as v, relationshipSchema as x, entitiesConfigSchema as y };
2535
+ export { ZodRecord as A, relationshipsSchema as C, ZodLiteral as D, ZodEnum as E, ZodUnion as M, output as N, ZodObject as O, $strict as P, relationshipSchema as S, ZodArray as T, RelationshipVia as _, ClivlyEntitiesConfig as a, entitiesConfigSchema as b, ConfigValidationResult as c, DiscoveredSchemaTable as d, FilterExpr as f, RelationshipSpec as g, MaterializingConcept as h, ClivlyConfigError as i, ZodString as j, ZodOptional as k, CrmConcept as l, MATERIALIZING_CONCEPTS as m, CRM_CONCEPTS as n, ClivlyEntityConfig as o, FilterValue as p, CUSTOM_CONCEPT as r, ConfigValidationError as s, CANONICAL_FIELDS as t, DiscoveredColumnMeta as u, RelationshipsMap as v, validateEntitiesConfig as w, filterSchema as x, defineClivlyConfig as y };
@@ -2312,6 +2312,53 @@ declare const entitySchema: ZodObject<{
2312
2312
  }, $strict>]>;
2313
2313
  }, $strict>>>;
2314
2314
  targetObjectTypeId: ZodOptional<ZodString>;
2315
+ projection: ZodOptional<ZodObject<{
2316
+ version: ZodLiteral<1>;
2317
+ kind: ZodLiteral<"projection">;
2318
+ entityKey: ZodString;
2319
+ baseTable: ZodString;
2320
+ joins: ZodArray<ZodObject<{
2321
+ key: ZodString;
2322
+ table: ZodString;
2323
+ type: ZodEnum<{
2324
+ inner: "inner";
2325
+ left: "left";
2326
+ }>;
2327
+ on: ZodArray<ZodObject<{
2328
+ left: ZodObject<{
2329
+ table: ZodString;
2330
+ column: ZodString;
2331
+ }, $strict>;
2332
+ op: ZodLiteral<"eq">;
2333
+ right: ZodObject<{
2334
+ table: ZodString;
2335
+ column: ZodString;
2336
+ }, $strict>;
2337
+ }, $strict>>;
2338
+ }, $strict>>;
2339
+ fieldBindings: ZodRecord<ZodString, ZodObject<{
2340
+ from: ZodObject<{
2341
+ table: ZodString;
2342
+ column: ZodString;
2343
+ }, $strict>;
2344
+ }, $strict>>;
2345
+ identity: ZodUnion<readonly [ZodObject<{
2346
+ kind: ZodLiteral<"base_pk">;
2347
+ column: ZodOptional<ZodString>;
2348
+ }, $strict>, ZodObject<{
2349
+ kind: ZodLiteral<"column">;
2350
+ from: ZodObject<{
2351
+ table: ZodString;
2352
+ column: ZodString;
2353
+ }, $strict>;
2354
+ }, $strict>, ZodObject<{
2355
+ kind: ZodLiteral<"composite">;
2356
+ parts: ZodArray<ZodObject<{
2357
+ table: ZodString;
2358
+ column: ZodString;
2359
+ }, $strict>>;
2360
+ }, $strict>]>;
2361
+ }, $strict>>;
2315
2362
  }, $strict>;
2316
2363
  type ClivlyEntityConfig = output<typeof entitySchema>;
2317
2364
  declare const entitiesConfigSchema: ZodObject<{
@@ -2360,6 +2407,53 @@ declare const entitiesConfigSchema: ZodObject<{
2360
2407
  }, $strict>]>;
2361
2408
  }, $strict>>>;
2362
2409
  targetObjectTypeId: ZodOptional<ZodString>;
2410
+ projection: ZodOptional<ZodObject<{
2411
+ version: ZodLiteral<1>;
2412
+ kind: ZodLiteral<"projection">;
2413
+ entityKey: ZodString;
2414
+ baseTable: ZodString;
2415
+ joins: ZodArray<ZodObject<{
2416
+ key: ZodString;
2417
+ table: ZodString;
2418
+ type: ZodEnum<{
2419
+ inner: "inner";
2420
+ left: "left";
2421
+ }>;
2422
+ on: ZodArray<ZodObject<{
2423
+ left: ZodObject<{
2424
+ table: ZodString;
2425
+ column: ZodString;
2426
+ }, $strict>;
2427
+ op: ZodLiteral<"eq">;
2428
+ right: ZodObject<{
2429
+ table: ZodString;
2430
+ column: ZodString;
2431
+ }, $strict>;
2432
+ }, $strict>>;
2433
+ }, $strict>>;
2434
+ fieldBindings: ZodRecord<ZodString, ZodObject<{
2435
+ from: ZodObject<{
2436
+ table: ZodString;
2437
+ column: ZodString;
2438
+ }, $strict>;
2439
+ }, $strict>>;
2440
+ identity: ZodUnion<readonly [ZodObject<{
2441
+ kind: ZodLiteral<"base_pk">;
2442
+ column: ZodOptional<ZodString>;
2443
+ }, $strict>, ZodObject<{
2444
+ kind: ZodLiteral<"column">;
2445
+ from: ZodObject<{
2446
+ table: ZodString;
2447
+ column: ZodString;
2448
+ }, $strict>;
2449
+ }, $strict>, ZodObject<{
2450
+ kind: ZodLiteral<"composite">;
2451
+ parts: ZodArray<ZodObject<{
2452
+ table: ZodString;
2453
+ column: ZodString;
2454
+ }, $strict>>;
2455
+ }, $strict>]>;
2456
+ }, $strict>>;
2363
2457
  }, $strict>>;
2364
2458
  }, $strict>;
2365
2459
  type ClivlyEntitiesConfig = output<typeof entitiesConfigSchema>;
@@ -2384,14 +2478,39 @@ declare function defineClivlyConfig(config: ClivlyEntitiesConfig, options?: {
2384
2478
  strict?: boolean;
2385
2479
  onWarn?: (message: string) => void;
2386
2480
  }): ClivlyEntitiesConfig;
2481
+ /**
2482
+ * Per-column metadata a host reports for a discovered table. Structurally
2483
+ * identical to the SDK's `DiscoveredColumn` and to `entity-heuristics.ts`'s
2484
+ * (currently separate) `DiscoveredColumnMeta` — a later task converges that
2485
+ * module onto this one. Every field is optional: a v1 host reports column
2486
+ * names only.
2487
+ */
2488
+ interface DiscoveredColumnMeta {
2489
+ isForeignKey?: boolean;
2490
+ isPrimaryKey?: boolean;
2491
+ name: string;
2492
+ nullable?: boolean;
2493
+ references?: {
2494
+ table: string;
2495
+ column: string;
2496
+ };
2497
+ type?: string;
2498
+ }
2387
2499
  /**
2388
2500
  * A host table the SDK reported for discovery. Structurally identical to the
2389
2501
  * SDK's `DiscoveredTable`; duplicated here to keep `@clivly/core` free of an
2390
2502
  * SDK dependency (core is the base contract SDK builds on).
2503
+ *
2504
+ * `columns` is the stable v1 contract. `columnsMeta` and `uniqueConstraints`
2505
+ * are the enrichment projection mappings require — absent on v1 hosts, which
2506
+ * is why projection validation fails closed rather than assuming "no keys".
2391
2507
  */
2392
2508
  interface DiscoveredSchemaTable {
2393
2509
  columns: string[];
2510
+ columnsMeta?: DiscoveredColumnMeta[];
2394
2511
  name: string;
2512
+ /** Every unique key as DB column names; PKs included. Absent = unknown. */
2513
+ uniqueConstraints?: string[][];
2395
2514
  }
2396
2515
  interface ConfigValidationError {
2397
2516
  message: string;
@@ -2413,4 +2532,4 @@ interface ConfigValidationResult {
2413
2532
  */
2414
2533
  declare function validateEntitiesConfig(config: ClivlyEntitiesConfig, schema: DiscoveredSchemaTable[]): ConfigValidationResult;
2415
2534
  //#endregion
2416
- export { validateEntitiesConfig as C, relationshipsSchema as S, RelationshipsMap as _, ClivlyEntitiesConfig as a, filterSchema as b, ConfigValidationResult as c, FilterExpr as d, FilterValue as f, RelationshipVia as g, RelationshipSpec as h, ClivlyConfigError as i, CrmConcept as l, MaterializingConcept as m, CRM_CONCEPTS as n, ClivlyEntityConfig as o, MATERIALIZING_CONCEPTS as p, CUSTOM_CONCEPT as r, ConfigValidationError as s, CANONICAL_FIELDS as t, DiscoveredSchemaTable as u, defineClivlyConfig as v, relationshipSchema as x, entitiesConfigSchema as y };
2535
+ export { ZodRecord as A, relationshipsSchema as C, ZodLiteral as D, ZodEnum as E, ZodUnion as M, output as N, ZodObject as O, $strict as P, relationshipSchema as S, ZodArray as T, RelationshipVia as _, ClivlyEntitiesConfig as a, entitiesConfigSchema as b, ConfigValidationResult as c, DiscoveredSchemaTable as d, FilterExpr as f, RelationshipSpec as g, MaterializingConcept as h, ClivlyConfigError as i, ZodString as j, ZodOptional as k, CrmConcept as l, MATERIALIZING_CONCEPTS as m, CRM_CONCEPTS as n, ClivlyEntityConfig as o, FilterValue as p, CUSTOM_CONCEPT as r, ConfigValidationError as s, CANONICAL_FIELDS as t, DiscoveredColumnMeta as u, RelationshipsMap as v, validateEntitiesConfig as w, filterSchema as x, defineClivlyConfig as y };