@clivly/core 0.9.2 → 0.9.4

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.
package/README.md CHANGED
@@ -35,8 +35,15 @@ npm install @clivly/core
35
35
  Every subpath below is importable independently, so you pull in only what you
36
36
  use. The root (`.`) re-exports the contracts, entity config, mapping form, sync
37
37
  engine and view compiler — but **not** `/drizzle` (which needs the optional
38
- peer), `/entity-heuristics`, `/mapping-score`, `/integration-state` or
39
- `/env-file`.
38
+ peer), `/entity-heuristics`, `/mapping-score` or `/env-file`.
39
+
40
+ `/integration-state` is a deliberate half-exception: the root re-exports its
41
+ **types only** (`IntegrationState`, `IntegrationStep`, `IntegrationFacts`,
42
+ `IntegrationStatus`, `ConnectionLiveness`, `NextAction`, `StepId`, `StepState`,
43
+ `StepProblem`), so a consumer can describe a setup ladder without reaching for
44
+ the subpath. `computeIntegrationState` stays behind `/integration-state`, so
45
+ there is one implementation of the ladder rather than a second one growing in a
46
+ client.
40
47
 
41
48
  | Entry | Contents |
42
49
  | --- | --- |
@@ -47,7 +54,7 @@ peer), `/entity-heuristics`, `/mapping-score`, `/integration-state` or
47
54
  | `@clivly/core/types` | Shared domain types (`Contact`, `Company`, `Deal`, `Task`, `Note`, `Activity`, inputs, filters, `CrmRole`) |
48
55
  | `@clivly/core/drizzle` | `discoverFromDrizzle(schema)` — derive the discovery shape (including keys, types, nullability and FK edges) from a Drizzle schema object; plus `buildUniqueConstraints` / `buildColumnsMeta` for reflecting a single table. Requires the optional `drizzle-orm` peer |
49
56
  | `@clivly/core/view-compiler` | `compileEntityView`, `compileEntityViews`, `explainEntitiesConfig`, `DEFAULT_VIEW_PREFIX` |
50
- | `@clivly/core/mappings-config` | `mappingsToEntitiesConfig`, `EntityMappingRow` — turn `crm_entity_mappings` rows into an entities config |
57
+ | `@clivly/core/mappings-config` | `mappingsToEntitiesConfig`, `EntityMappingRow` — turn `crm_entity_mappings` rows into an entities config; `entitiesToMappings`, `MappingFromConfig` — the inverse, turning a config into the mapping rows `clivly push-schema` writes |
51
58
  | `@clivly/core/mapping-form` | `buildFilterFromDiscriminator`, `buildRelationships`, `relationshipViaSignature` — mapping-UI helpers |
52
59
  | `@clivly/core/mapping-score` | Scoring helpers for ranking candidate mappings |
53
60
  | `@clivly/core/entity-heuristics` | Table-name heuristics that guess which table holds contacts/companies |
@@ -1,4 +1,4 @@
1
- import { i as projectionSchema, r as identityRefs, t as BASE_REF } from "./projection-C_EMRmZ8.mjs";
1
+ import { i as projectionSchema, r as identityRefs, t as BASE_REF } from "./projection-SCNrLJMV.mjs";
2
2
  import { z } from "zod";
3
3
  //#region src/schema-meta.ts
4
4
  /**
@@ -1,4 +1,4 @@
1
- const require_projection = require("./projection-BXBkh7qp.cjs");
1
+ const require_projection = require("./projection-DFgCoyZl.cjs");
2
2
  let zod = require("zod");
3
3
  //#region src/schema-meta.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_entity_config = require("./entity-config-Bfq3OkCU.cjs");
2
+ const require_entity_config = require("./entity-config-ZSv3XuW_.cjs");
3
3
  exports.CANONICAL_FIELDS = require_entity_config.CANONICAL_FIELDS;
4
4
  exports.CRM_CONCEPTS = require_entity_config.CRM_CONCEPTS;
5
5
  exports.CUSTOM_CONCEPT = require_entity_config.CUSTOM_CONCEPT;
@@ -1,2 +1,2 @@
1
- import { a as MATERIALIZING_CONCEPTS, c as entitiesConfigSchema, d as relationshipSchema, f as relationshipsSchema, i as ClivlyConfigError, l as filterSchema, n as CRM_CONCEPTS, o as customObjectDeclarations, p as validateEntitiesConfig, r as CUSTOM_CONCEPT, s as defineClivlyConfig, t as CANONICAL_FIELDS, u as projectionFields } from "./entity-config-DFJ8L9jm.mjs";
1
+ import { a as MATERIALIZING_CONCEPTS, c as entitiesConfigSchema, d as relationshipSchema, f as relationshipsSchema, i as ClivlyConfigError, l as filterSchema, n as CRM_CONCEPTS, o as customObjectDeclarations, p as validateEntitiesConfig, r as CUSTOM_CONCEPT, s as defineClivlyConfig, t as CANONICAL_FIELDS, u as projectionFields } from "./entity-config-Dt_KfgRl.mjs";
2
2
  export { CANONICAL_FIELDS, CRM_CONCEPTS, CUSTOM_CONCEPT, ClivlyConfigError, MATERIALIZING_CONCEPTS, customObjectDeclarations, defineClivlyConfig, entitiesConfigSchema, filterSchema, projectionFields, relationshipSchema, relationshipsSchema, validateEntitiesConfig };
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_entity_config = require("./entity-config-Bfq3OkCU.cjs");
2
+ const require_entity_config = require("./entity-config-ZSv3XuW_.cjs");
3
3
  const require_mapping_score = require("./mapping-score.cjs");
4
4
  //#region src/entity-heuristics.ts
5
5
  const TARGET_CONCEPTS = [
@@ -1,4 +1,4 @@
1
- import { a as MATERIALIZING_CONCEPTS } from "./entity-config-DFJ8L9jm.mjs";
1
+ import { a as MATERIALIZING_CONCEPTS } from "./entity-config-Dt_KfgRl.mjs";
2
2
  import { CONCEPT_TIERS, FIELD_TIERS, RELATIONSHIP_TIERS, W, isAmbiguous, isNumericLike, isTextLike, isTimestampLike, tierFor } from "./mapping-score.mjs";
3
3
  //#region src/entity-heuristics.ts
4
4
  const TARGET_CONCEPTS = [
package/dist/index.cjs CHANGED
@@ -1,10 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_auth_adapter = require("./auth-adapter.cjs");
3
- const require_projection = require("./projection-BXBkh7qp.cjs");
4
- const require_entity_config = require("./entity-config-Bfq3OkCU.cjs");
3
+ const require_projection = require("./projection-DFgCoyZl.cjs");
4
+ const require_entity_config = require("./entity-config-ZSv3XuW_.cjs");
5
5
  const require_mapping_form = require("./mapping-form.cjs");
6
6
  const require_mappings_config = require("./mappings-config.cjs");
7
- const require_view_compiler = require("./view-compiler-BpNI8Ttw.cjs");
7
+ const require_view_compiler = require("./view-compiler-DTGSwTcz.cjs");
8
8
  const require_sync_engine = require("./sync-engine.cjs");
9
9
  //#region src/projection-draft.ts
10
10
  function emptyProjectionDraft(baseTable) {
@@ -83,6 +83,9 @@ exports.buildRelationships = require_mapping_form.buildRelationships;
83
83
  exports.columnMetaFor = require_entity_config.columnMetaFor;
84
84
  exports.compileEntityView = require_view_compiler.compileEntityView;
85
85
  exports.compileEntityViews = require_view_compiler.compileEntityViews;
86
+ exports.compileProjectionFrom = require_view_compiler.compileProjectionFrom;
87
+ exports.compileProjectionIdentity = require_view_compiler.compileProjectionIdentity;
88
+ exports.compileProjectionJoins = require_view_compiler.compileProjectionJoins;
86
89
  exports.coversUniqueKey = require_entity_config.coversUniqueKey;
87
90
  exports.defineClivlyConfig = require_entity_config.defineClivlyConfig;
88
91
  exports.describeCardinality = describeCardinality;
@@ -99,6 +102,7 @@ exports.joinFansOut = require_entity_config.joinFansOut;
99
102
  exports.mappingsToEntitiesConfig = require_mappings_config.mappingsToEntitiesConfig;
100
103
  exports.primaryKeyColumns = require_entity_config.primaryKeyColumns;
101
104
  exports.projectionSchema = require_projection.projectionSchema;
105
+ exports.quoteIdent = require_view_compiler.quoteIdent;
102
106
  exports.reconcile = require_sync_engine.reconcile;
103
107
  exports.relationshipSchema = require_entity_config.relationshipSchema;
104
108
  exports.relationshipViaSignature = require_mapping_form.relationshipViaSignature;
package/dist/index.d.cts CHANGED
@@ -2,6 +2,7 @@ import { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus
2
2
  import { CRMAdapter } from "./adapter.cjs";
3
3
  import { ClivlyAuthAdapter, ClivlyUser, CrmMembership, MembershipResolver, authCustom } from "./auth-adapter.cjs";
4
4
  import { A as BASE_REF, C as defineClivlyConfig, D as relationshipSchema, F as ProjectionRef, I as identityRefs, L as projectionSchema, M as ProjectionIdentity, N as ProjectionJoin, O as relationshipsSchema, P as ProjectionMapping, T as filterSchema, _ as MATERIALIZING_CONCEPTS, a as ClivlyEntitiesConfig, b as RelationshipVia, d as CrmConcept, g as FilterValue, h as FilterExpr, i as ClivlyConfigError, j as ProjectionFieldBinding, k as validateEntitiesConfig, l as ConfigValidationError, m as DiscoveredSchemaTable, n as CRM_CONCEPTS, p as DiscoveredColumnMeta, s as ClivlyEntityConfig, t as CANONICAL_FIELDS, u as ConfigValidationResult, v as MaterializingConcept, w as entitiesConfigSchema, x as RelationshipsMap, y as RelationshipSpec } from "./entity-config-buOIVtMM.cjs";
5
+ import { ConnectionLiveness, IntegrationFacts, IntegrationState, IntegrationStatus, IntegrationStep, NextAction, StepId, StepProblem, StepState } from "./integration-state.cjs";
5
6
  import { RelationshipCandidate, buildFilterFromDiscriminator, buildRelationships, relationshipViaSignature } from "./mapping-form.cjs";
6
7
  import { EntityMappingRow, mappingsToEntitiesConfig } from "./mappings-config.cjs";
7
8
  import { CompileOptions, CompiledView, DEFAULT_VIEW_PREFIX, ExplainResult, compileEntityView, compileEntityViews, explainEntitiesConfig } from "./view-compiler.cjs";
@@ -43,6 +44,34 @@ declare function describeCardinality(draft: ProjectionDraft, schema: DiscoveredS
43
44
  joinKey: string;
44
45
  }>;
45
46
  //#endregion
47
+ //#region src/projection-sql.d.ts
48
+ /**
49
+ * SQL generation for projection-backed entities.
50
+ *
51
+ * Base and joins are aliased by their ref key (`base`, then each join's `key`),
52
+ * which is what allows the same table to be joined twice and keeps generated
53
+ * SQL independent of host table names.
54
+ *
55
+ * Pure string generation — no DB access. Identifiers are escaped so output is
56
+ * deterministic and injection-safe.
57
+ */
58
+ /** Quote a single identifier part, escaping embedded double-quotes. */
59
+ declare function quoteIdent(name: string): string;
60
+ /**
61
+ * The identity expression. Composite identities concatenate their parts with
62
+ * `::`; validation guarantees every part is NOT NULL and non-text, which is
63
+ * what makes the concatenation collision-free.
64
+ *
65
+ * Exported unaliased because two paths need the same expression under different
66
+ * names: the view compiler aliases it `id`, and the SDK's projection push source
67
+ * also orders and keyset-paginates by it. Sharing one definition is what keeps
68
+ * a pushed row's `id` identical to the one the view would have produced.
69
+ */
70
+ declare function compileProjectionIdentity(projection: ProjectionMapping, basePkColumn: string): string;
71
+ declare function compileProjectionJoins(projection: ProjectionMapping): string[];
72
+ /** `FROM <baseTable> AS "base"` — the alias every ref resolves against. */
73
+ declare function compileProjectionFrom(projection: ProjectionMapping): string;
74
+ //#endregion
46
75
  //#region src/projection-validate.d.ts
47
76
  /**
48
77
  * Validate a projection against the discovered schema. Returns every error
@@ -76,4 +105,4 @@ declare function coversUniqueKey(table: DiscoveredSchemaTable, columns: string[]
76
105
  /** Is this table's payload rich enough to validate a projection against? */
77
106
  declare function hasRichMeta(table: DiscoveredSchemaTable): boolean;
78
107
  //#endregion
79
- export { type Activity, type ActivityType, BASE_REF, CANONICAL_FIELDS, type CRMAdapter, CRM_CONCEPTS, type ClivlyAuthAdapter, ClivlyConfigError, type ClivlyEntitiesConfig, type ClivlyEntityConfig, type ClivlyUser, type Company, type CompileOptions, type CompiledView, type ConfigValidationError, type ConfigValidationResult, type Contact, type ContactFilters, type ContactStatus, type CreateActivityInput, type CreateCompanyInput, type CreateContactInput, type CreateDealInput, type CreateTaskInput, type CrmConcept, type CrmMembership, type CrmRole, DEFAULT_VIEW_PREFIX, type Deal, type DealStage, type DiscoveredColumnMeta, type DiscoveredSchemaTable, type EntityMappingRow, type EntitySyncResult, type ExplainResult, type FilterExpr, type FilterValue, MATERIALIZING_CONCEPTS, type MaterializingConcept, type MembershipResolver, type MirrorRecord, type Note, type PersistAction, type ProjectionDraft, type ProjectionFieldBinding, type ProjectionIdentity, type ProjectionJoin, type ProjectionMapping, type ProjectionRef, type RecordSource, type RelationshipCandidate, type RelationshipSpec, type RelationshipVia, type RelationshipsMap, type SourceRow, type SyncAction, type SyncResult, type SyncStore, type Task, type TaskEntityType, type TaskFilters, type TaskPriority, type TaskStatus, type UpdateContactInput, type UpdateDealInput, type UpdateTaskInput, authCustom, buildFilterFromDiscriminator, buildRelationships, columnMetaFor, compileEntityView, compileEntityViews, coversUniqueKey, defineClivlyConfig, describeCardinality, draftErrors, draftToProjection, emptyProjectionDraft, entitiesConfigSchema, explainEntitiesConfig, fanOutJoins, filterSchema, hasRichMeta, identityRefs, joinFansOut, mappingsToEntitiesConfig, primaryKeyColumns, projectionSchema, reconcile, relationshipSchema, relationshipViaSignature, relationshipsSchema, runSync, suggestJoinConditions, validateEntitiesConfig, validateProjection };
108
+ export { type Activity, type ActivityType, BASE_REF, CANONICAL_FIELDS, type CRMAdapter, CRM_CONCEPTS, type ClivlyAuthAdapter, ClivlyConfigError, type ClivlyEntitiesConfig, type ClivlyEntityConfig, type ClivlyUser, type Company, type CompileOptions, type CompiledView, type ConfigValidationError, type ConfigValidationResult, type ConnectionLiveness, type Contact, type ContactFilters, type ContactStatus, type CreateActivityInput, type CreateCompanyInput, type CreateContactInput, type CreateDealInput, type CreateTaskInput, type CrmConcept, type CrmMembership, type CrmRole, DEFAULT_VIEW_PREFIX, type Deal, type DealStage, type DiscoveredColumnMeta, type DiscoveredSchemaTable, type EntityMappingRow, type EntitySyncResult, type ExplainResult, type FilterExpr, type FilterValue, type IntegrationFacts, type IntegrationState, type IntegrationStatus, type IntegrationStep, MATERIALIZING_CONCEPTS, type MaterializingConcept, type MembershipResolver, type MirrorRecord, type NextAction, type Note, type PersistAction, type ProjectionDraft, type ProjectionFieldBinding, type ProjectionIdentity, type ProjectionJoin, type ProjectionMapping, type ProjectionRef, type RecordSource, type RelationshipCandidate, type RelationshipSpec, type RelationshipVia, type RelationshipsMap, type SourceRow, type StepId, type StepProblem, type StepState, type SyncAction, type SyncResult, type SyncStore, type Task, type TaskEntityType, type TaskFilters, type TaskPriority, type TaskStatus, type UpdateContactInput, type UpdateDealInput, type UpdateTaskInput, authCustom, buildFilterFromDiscriminator, buildRelationships, columnMetaFor, compileEntityView, compileEntityViews, compileProjectionFrom, compileProjectionIdentity, compileProjectionJoins, coversUniqueKey, defineClivlyConfig, describeCardinality, draftErrors, draftToProjection, emptyProjectionDraft, entitiesConfigSchema, explainEntitiesConfig, fanOutJoins, filterSchema, hasRichMeta, identityRefs, joinFansOut, mappingsToEntitiesConfig, primaryKeyColumns, projectionSchema, quoteIdent, reconcile, relationshipSchema, relationshipViaSignature, relationshipsSchema, runSync, suggestJoinConditions, validateEntitiesConfig, validateProjection };
package/dist/index.d.mts CHANGED
@@ -2,6 +2,7 @@ import { Activity, ActivityType, Company, Contact, ContactFilters, ContactStatus
2
2
  import { CRMAdapter } from "./adapter.mjs";
3
3
  import { ClivlyAuthAdapter, ClivlyUser, CrmMembership, MembershipResolver, authCustom } from "./auth-adapter.mjs";
4
4
  import { A as BASE_REF, C as defineClivlyConfig, D as relationshipSchema, F as ProjectionRef, I as identityRefs, L as projectionSchema, M as ProjectionIdentity, N as ProjectionJoin, O as relationshipsSchema, P as ProjectionMapping, T as filterSchema, _ as MATERIALIZING_CONCEPTS, a as ClivlyEntitiesConfig, b as RelationshipVia, d as CrmConcept, g as FilterValue, h as FilterExpr, i as ClivlyConfigError, j as ProjectionFieldBinding, k as validateEntitiesConfig, l as ConfigValidationError, m as DiscoveredSchemaTable, n as CRM_CONCEPTS, p as DiscoveredColumnMeta, s as ClivlyEntityConfig, t as CANONICAL_FIELDS, u as ConfigValidationResult, v as MaterializingConcept, w as entitiesConfigSchema, x as RelationshipsMap, y as RelationshipSpec } from "./entity-config-buOIVtMM.mjs";
5
+ import { ConnectionLiveness, IntegrationFacts, IntegrationState, IntegrationStatus, IntegrationStep, NextAction, StepId, StepProblem, StepState } from "./integration-state.mjs";
5
6
  import { RelationshipCandidate, buildFilterFromDiscriminator, buildRelationships, relationshipViaSignature } from "./mapping-form.mjs";
6
7
  import { EntityMappingRow, mappingsToEntitiesConfig } from "./mappings-config.mjs";
7
8
  import { CompileOptions, CompiledView, DEFAULT_VIEW_PREFIX, ExplainResult, compileEntityView, compileEntityViews, explainEntitiesConfig } from "./view-compiler.mjs";
@@ -43,6 +44,34 @@ declare function describeCardinality(draft: ProjectionDraft, schema: DiscoveredS
43
44
  joinKey: string;
44
45
  }>;
45
46
  //#endregion
47
+ //#region src/projection-sql.d.ts
48
+ /**
49
+ * SQL generation for projection-backed entities.
50
+ *
51
+ * Base and joins are aliased by their ref key (`base`, then each join's `key`),
52
+ * which is what allows the same table to be joined twice and keeps generated
53
+ * SQL independent of host table names.
54
+ *
55
+ * Pure string generation — no DB access. Identifiers are escaped so output is
56
+ * deterministic and injection-safe.
57
+ */
58
+ /** Quote a single identifier part, escaping embedded double-quotes. */
59
+ declare function quoteIdent(name: string): string;
60
+ /**
61
+ * The identity expression. Composite identities concatenate their parts with
62
+ * `::`; validation guarantees every part is NOT NULL and non-text, which is
63
+ * what makes the concatenation collision-free.
64
+ *
65
+ * Exported unaliased because two paths need the same expression under different
66
+ * names: the view compiler aliases it `id`, and the SDK's projection push source
67
+ * also orders and keyset-paginates by it. Sharing one definition is what keeps
68
+ * a pushed row's `id` identical to the one the view would have produced.
69
+ */
70
+ declare function compileProjectionIdentity(projection: ProjectionMapping, basePkColumn: string): string;
71
+ declare function compileProjectionJoins(projection: ProjectionMapping): string[];
72
+ /** `FROM <baseTable> AS "base"` — the alias every ref resolves against. */
73
+ declare function compileProjectionFrom(projection: ProjectionMapping): string;
74
+ //#endregion
46
75
  //#region src/projection-validate.d.ts
47
76
  /**
48
77
  * Validate a projection against the discovered schema. Returns every error
@@ -76,4 +105,4 @@ declare function coversUniqueKey(table: DiscoveredSchemaTable, columns: string[]
76
105
  /** Is this table's payload rich enough to validate a projection against? */
77
106
  declare function hasRichMeta(table: DiscoveredSchemaTable): boolean;
78
107
  //#endregion
79
- export { type Activity, type ActivityType, BASE_REF, CANONICAL_FIELDS, type CRMAdapter, CRM_CONCEPTS, type ClivlyAuthAdapter, ClivlyConfigError, type ClivlyEntitiesConfig, type ClivlyEntityConfig, type ClivlyUser, type Company, type CompileOptions, type CompiledView, type ConfigValidationError, type ConfigValidationResult, type Contact, type ContactFilters, type ContactStatus, type CreateActivityInput, type CreateCompanyInput, type CreateContactInput, type CreateDealInput, type CreateTaskInput, type CrmConcept, type CrmMembership, type CrmRole, DEFAULT_VIEW_PREFIX, type Deal, type DealStage, type DiscoveredColumnMeta, type DiscoveredSchemaTable, type EntityMappingRow, type EntitySyncResult, type ExplainResult, type FilterExpr, type FilterValue, MATERIALIZING_CONCEPTS, type MaterializingConcept, type MembershipResolver, type MirrorRecord, type Note, type PersistAction, type ProjectionDraft, type ProjectionFieldBinding, type ProjectionIdentity, type ProjectionJoin, type ProjectionMapping, type ProjectionRef, type RecordSource, type RelationshipCandidate, type RelationshipSpec, type RelationshipVia, type RelationshipsMap, type SourceRow, type SyncAction, type SyncResult, type SyncStore, type Task, type TaskEntityType, type TaskFilters, type TaskPriority, type TaskStatus, type UpdateContactInput, type UpdateDealInput, type UpdateTaskInput, authCustom, buildFilterFromDiscriminator, buildRelationships, columnMetaFor, compileEntityView, compileEntityViews, coversUniqueKey, defineClivlyConfig, describeCardinality, draftErrors, draftToProjection, emptyProjectionDraft, entitiesConfigSchema, explainEntitiesConfig, fanOutJoins, filterSchema, hasRichMeta, identityRefs, joinFansOut, mappingsToEntitiesConfig, primaryKeyColumns, projectionSchema, reconcile, relationshipSchema, relationshipViaSignature, relationshipsSchema, runSync, suggestJoinConditions, validateEntitiesConfig, validateProjection };
108
+ export { type Activity, type ActivityType, BASE_REF, CANONICAL_FIELDS, type CRMAdapter, CRM_CONCEPTS, type ClivlyAuthAdapter, ClivlyConfigError, type ClivlyEntitiesConfig, type ClivlyEntityConfig, type ClivlyUser, type Company, type CompileOptions, type CompiledView, type ConfigValidationError, type ConfigValidationResult, type ConnectionLiveness, type Contact, type ContactFilters, type ContactStatus, type CreateActivityInput, type CreateCompanyInput, type CreateContactInput, type CreateDealInput, type CreateTaskInput, type CrmConcept, type CrmMembership, type CrmRole, DEFAULT_VIEW_PREFIX, type Deal, type DealStage, type DiscoveredColumnMeta, type DiscoveredSchemaTable, type EntityMappingRow, type EntitySyncResult, type ExplainResult, type FilterExpr, type FilterValue, type IntegrationFacts, type IntegrationState, type IntegrationStatus, type IntegrationStep, MATERIALIZING_CONCEPTS, type MaterializingConcept, type MembershipResolver, type MirrorRecord, type NextAction, type Note, type PersistAction, type ProjectionDraft, type ProjectionFieldBinding, type ProjectionIdentity, type ProjectionJoin, type ProjectionMapping, type ProjectionRef, type RecordSource, type RelationshipCandidate, type RelationshipSpec, type RelationshipVia, type RelationshipsMap, type SourceRow, type StepId, type StepProblem, type StepState, type SyncAction, type SyncResult, type SyncStore, type Task, type TaskEntityType, type TaskFilters, type TaskPriority, type TaskStatus, type UpdateContactInput, type UpdateDealInput, type UpdateTaskInput, authCustom, buildFilterFromDiscriminator, buildRelationships, columnMetaFor, compileEntityView, compileEntityViews, compileProjectionFrom, compileProjectionIdentity, compileProjectionJoins, coversUniqueKey, defineClivlyConfig, describeCardinality, draftErrors, draftToProjection, emptyProjectionDraft, entitiesConfigSchema, explainEntitiesConfig, fanOutJoins, filterSchema, hasRichMeta, identityRefs, joinFansOut, mappingsToEntitiesConfig, primaryKeyColumns, projectionSchema, quoteIdent, reconcile, relationshipSchema, relationshipViaSignature, relationshipsSchema, runSync, suggestJoinConditions, validateEntitiesConfig, validateProjection };
package/dist/index.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  import { authCustom } from "./auth-adapter.mjs";
2
- import { i as projectionSchema, n as PROJECTION_KEY_PATTERN, r as identityRefs, t as BASE_REF } from "./projection-C_EMRmZ8.mjs";
3
- import { _ as columnMetaFor, a as MATERIALIZING_CONCEPTS, b as primaryKeyColumns, c as entitiesConfigSchema, d as relationshipSchema, f as relationshipsSchema, g as joinFansOut, h as fanOutJoins, i as ClivlyConfigError, l as filterSchema, m as validateProjection, n as CRM_CONCEPTS, p as validateEntitiesConfig, s as defineClivlyConfig, t as CANONICAL_FIELDS, v as coversUniqueKey, y as hasRichMeta } from "./entity-config-DFJ8L9jm.mjs";
2
+ import { i as projectionSchema, n as PROJECTION_KEY_PATTERN, r as identityRefs, t as BASE_REF } from "./projection-SCNrLJMV.mjs";
3
+ import { _ as columnMetaFor, a as MATERIALIZING_CONCEPTS, b as primaryKeyColumns, c as entitiesConfigSchema, d as relationshipSchema, f as relationshipsSchema, g as joinFansOut, h as fanOutJoins, i as ClivlyConfigError, l as filterSchema, m as validateProjection, n as CRM_CONCEPTS, p as validateEntitiesConfig, s as defineClivlyConfig, t as CANONICAL_FIELDS, v as coversUniqueKey, y as hasRichMeta } from "./entity-config-Dt_KfgRl.mjs";
4
4
  import { buildFilterFromDiscriminator, buildRelationships, relationshipViaSignature } from "./mapping-form.mjs";
5
5
  import { mappingsToEntitiesConfig } from "./mappings-config.mjs";
6
- import { i as explainEntitiesConfig, n as compileEntityView, r as compileEntityViews, t as DEFAULT_VIEW_PREFIX } from "./view-compiler-CcqsGxv4.mjs";
6
+ import { c as compileProjectionJoins, i as explainEntitiesConfig, l as quoteIdent, n as compileEntityView, o as compileProjectionFrom, r as compileEntityViews, s as compileProjectionIdentity, t as DEFAULT_VIEW_PREFIX } from "./view-compiler-DjzRXiAJ.mjs";
7
7
  import { reconcile, runSync } from "./sync-engine.mjs";
8
8
  //#region src/projection-draft.ts
9
9
  function emptyProjectionDraft(baseTable) {
@@ -70,4 +70,4 @@ function describeCardinality(draft, schema) {
70
70
  }));
71
71
  }
72
72
  //#endregion
73
- export { BASE_REF, CANONICAL_FIELDS, CRM_CONCEPTS, ClivlyConfigError, DEFAULT_VIEW_PREFIX, MATERIALIZING_CONCEPTS, authCustom, buildFilterFromDiscriminator, buildRelationships, columnMetaFor, compileEntityView, compileEntityViews, coversUniqueKey, defineClivlyConfig, describeCardinality, draftErrors, draftToProjection, emptyProjectionDraft, entitiesConfigSchema, explainEntitiesConfig, fanOutJoins, filterSchema, hasRichMeta, identityRefs, joinFansOut, mappingsToEntitiesConfig, primaryKeyColumns, projectionSchema, reconcile, relationshipSchema, relationshipViaSignature, relationshipsSchema, runSync, suggestJoinConditions, validateEntitiesConfig, validateProjection };
73
+ export { BASE_REF, CANONICAL_FIELDS, CRM_CONCEPTS, ClivlyConfigError, DEFAULT_VIEW_PREFIX, MATERIALIZING_CONCEPTS, authCustom, buildFilterFromDiscriminator, buildRelationships, columnMetaFor, compileEntityView, compileEntityViews, compileProjectionFrom, compileProjectionIdentity, compileProjectionJoins, coversUniqueKey, defineClivlyConfig, describeCardinality, draftErrors, draftToProjection, emptyProjectionDraft, entitiesConfigSchema, explainEntitiesConfig, fanOutJoins, filterSchema, hasRichMeta, identityRefs, joinFansOut, mappingsToEntitiesConfig, primaryKeyColumns, projectionSchema, quoteIdent, reconcile, relationshipSchema, relationshipViaSignature, relationshipsSchema, runSync, suggestJoinConditions, validateEntitiesConfig, validateProjection };
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_entity_config = require("./entity-config-Bfq3OkCU.cjs");
2
+ const require_entity_config = require("./entity-config-ZSv3XuW_.cjs");
3
3
  //#region src/mappings-config.ts
4
4
  const RESERVED_FIELD = "id";
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { t as CANONICAL_FIELDS } from "./entity-config-DFJ8L9jm.mjs";
1
+ import { t as CANONICAL_FIELDS } from "./entity-config-Dt_KfgRl.mjs";
2
2
  //#region src/mappings-config.ts
3
3
  const RESERVED_FIELD = "id";
4
4
  /**
@@ -16,8 +16,29 @@ let zod = require("zod");
16
16
  */
17
17
  /** The reserved ref name for the projection's base table. */
18
18
  const BASE_REF = "base";
19
- /** Entity keys become view names (`crm_src_<entityKey>`), so keep them slugs. */
20
- const PROJECTION_KEY_PATTERN = /^[a-z][a-z0-9_]*$/;
19
+ /**
20
+ * Entity keys become view names (`crm_src_<entityKey>`), so keep them slugs.
21
+ *
22
+ * Accepts hyphens as well as underscores, matching `OBJECT_TYPE_SLUG_PATTERN`
23
+ * on the server. Those two were widened apart: the server learned hyphens
24
+ * because the SDK's own `slugify` collapses non-alphanumerics to them and
25
+ * `clivly status` reports that form as canonical — but this pattern was missed,
26
+ * so `clivly status` would tell you to key an entity `client-accounts` and then
27
+ * `defineClivlyConfig` would reject the config it had just asked for. Same bug,
28
+ * opposite half of the product.
29
+ *
30
+ * Widening is the safe direction: every key that was valid before still is, so
31
+ * nothing existing is renamed. Safe at all because neither use is ever a bare
32
+ * SQL identifier — the view name is quoted (`view-compiler.ts`, `quoteIdent`),
33
+ * and so is a join's `key` when it is emitted as an alias.
34
+ */
35
+ const PROJECTION_KEY_PATTERN = /^[a-z][a-z0-9_-]*$/;
36
+ /**
37
+ * Stated in prose because the default for a failed `.regex()` reports only the
38
+ * pattern — the developer is told the config is wrong and handed a regex to
39
+ * decode. Naming the rule is what makes the failure actionable.
40
+ */
41
+ const PROJECTION_KEY_MESSAGE = "must be lowercase letters, digits, \"-\" or \"_\", starting with a letter";
21
42
  const projectionRefSchema = zod.z.strictObject({
22
43
  table: zod.z.string().min(1),
23
44
  column: zod.z.string().min(1)
@@ -29,7 +50,7 @@ const projectionJoinConditionSchema = zod.z.strictObject({
29
50
  });
30
51
  const projectionJoinSchema = zod.z.strictObject({
31
52
  /** SQL alias and ref target. Unique within the projection. */
32
- key: zod.z.string().regex(PROJECTION_KEY_PATTERN),
53
+ key: zod.z.string().regex(PROJECTION_KEY_PATTERN, { message: `join key ${PROJECTION_KEY_MESSAGE}` }),
33
54
  table: zod.z.string().min(1),
34
55
  type: zod.z.enum(["inner", "left"]),
35
56
  on: zod.z.array(projectionJoinConditionSchema).min(1)
@@ -53,7 +74,7 @@ const projectionIdentitySchema = zod.z.union([
53
74
  const projectionSchema = zod.z.strictObject({
54
75
  version: zod.z.literal(1),
55
76
  kind: zod.z.literal("projection"),
56
- entityKey: zod.z.string().regex(PROJECTION_KEY_PATTERN),
77
+ entityKey: zod.z.string().regex(PROJECTION_KEY_PATTERN, { message: `entityKey ${PROJECTION_KEY_MESSAGE}` }),
57
78
  baseTable: zod.z.string().min(1),
58
79
  joins: zod.z.array(projectionJoinSchema),
59
80
  fieldBindings: zod.z.record(zod.z.string(), projectionFieldBindingSchema).refine((b) => Object.keys(b).length > 0, { message: "at least one field must be bound" }),
@@ -16,8 +16,29 @@ import { z } from "zod";
16
16
  */
17
17
  /** The reserved ref name for the projection's base table. */
18
18
  const BASE_REF = "base";
19
- /** Entity keys become view names (`crm_src_<entityKey>`), so keep them slugs. */
20
- const PROJECTION_KEY_PATTERN = /^[a-z][a-z0-9_]*$/;
19
+ /**
20
+ * Entity keys become view names (`crm_src_<entityKey>`), so keep them slugs.
21
+ *
22
+ * Accepts hyphens as well as underscores, matching `OBJECT_TYPE_SLUG_PATTERN`
23
+ * on the server. Those two were widened apart: the server learned hyphens
24
+ * because the SDK's own `slugify` collapses non-alphanumerics to them and
25
+ * `clivly status` reports that form as canonical — but this pattern was missed,
26
+ * so `clivly status` would tell you to key an entity `client-accounts` and then
27
+ * `defineClivlyConfig` would reject the config it had just asked for. Same bug,
28
+ * opposite half of the product.
29
+ *
30
+ * Widening is the safe direction: every key that was valid before still is, so
31
+ * nothing existing is renamed. Safe at all because neither use is ever a bare
32
+ * SQL identifier — the view name is quoted (`view-compiler.ts`, `quoteIdent`),
33
+ * and so is a join's `key` when it is emitted as an alias.
34
+ */
35
+ const PROJECTION_KEY_PATTERN = /^[a-z][a-z0-9_-]*$/;
36
+ /**
37
+ * Stated in prose because the default for a failed `.regex()` reports only the
38
+ * pattern — the developer is told the config is wrong and handed a regex to
39
+ * decode. Naming the rule is what makes the failure actionable.
40
+ */
41
+ const PROJECTION_KEY_MESSAGE = "must be lowercase letters, digits, \"-\" or \"_\", starting with a letter";
21
42
  const projectionRefSchema = z.strictObject({
22
43
  table: z.string().min(1),
23
44
  column: z.string().min(1)
@@ -29,7 +50,7 @@ const projectionJoinConditionSchema = z.strictObject({
29
50
  });
30
51
  const projectionJoinSchema = z.strictObject({
31
52
  /** SQL alias and ref target. Unique within the projection. */
32
- key: z.string().regex(PROJECTION_KEY_PATTERN),
53
+ key: z.string().regex(PROJECTION_KEY_PATTERN, { message: `join key ${PROJECTION_KEY_MESSAGE}` }),
33
54
  table: z.string().min(1),
34
55
  type: z.enum(["inner", "left"]),
35
56
  on: z.array(projectionJoinConditionSchema).min(1)
@@ -53,7 +74,7 @@ const projectionIdentitySchema = z.union([
53
74
  const projectionSchema = z.strictObject({
54
75
  version: z.literal(1),
55
76
  kind: z.literal("projection"),
56
- entityKey: z.string().regex(PROJECTION_KEY_PATTERN),
77
+ entityKey: z.string().regex(PROJECTION_KEY_PATTERN, { message: `entityKey ${PROJECTION_KEY_MESSAGE}` }),
57
78
  baseTable: z.string().min(1),
58
79
  joins: z.array(projectionJoinSchema),
59
80
  fieldBindings: z.record(z.string(), projectionFieldBindingSchema).refine((b) => Object.keys(b).length > 0, { message: "at least one field must be bound" }),
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_view_compiler = require("./view-compiler-BpNI8Ttw.cjs");
2
+ const require_view_compiler = require("./view-compiler-DTGSwTcz.cjs");
3
3
  //#region src/sync-engine.ts
4
4
  /**
5
5
  * Diff a view's rows against the current mirror population for one entity.
@@ -1,4 +1,4 @@
1
- import { r as compileEntityViews } from "./view-compiler-CcqsGxv4.mjs";
1
+ import { r as compileEntityViews } from "./view-compiler-DjzRXiAJ.mjs";
2
2
  //#region src/sync-engine.ts
3
3
  /**
4
4
  * Diff a view's rows against the current mirror population for one entity.
@@ -1,4 +1,4 @@
1
- const require_projection = require("./projection-BXBkh7qp.cjs");
1
+ const require_projection = require("./projection-DFgCoyZl.cjs");
2
2
  //#region src/projection-sql.ts
3
3
  /**
4
4
  * SQL generation for projection-backed entities.
@@ -18,16 +18,25 @@ function refSql(ref) {
18
18
  return `${quoteIdent(ref.table)}.${quoteIdent(ref.column)}`;
19
19
  }
20
20
  /**
21
- * The identity expression, aliased as `id`. Composite identities concatenate
22
- * their parts with `::`; validation guarantees every part is NOT NULL and
23
- * non-text, which is what makes the concatenation collision-free.
21
+ * The identity expression. Composite identities concatenate their parts with
22
+ * `::`; validation guarantees every part is NOT NULL and non-text, which is
23
+ * what makes the concatenation collision-free.
24
+ *
25
+ * Exported unaliased because two paths need the same expression under different
26
+ * names: the view compiler aliases it `id`, and the SDK's projection push source
27
+ * also orders and keyset-paginates by it. Sharing one definition is what keeps
28
+ * a pushed row's `id` identical to the one the view would have produced.
24
29
  */
25
- function identitySql(projection, basePkColumn) {
30
+ function compileProjectionIdentity(projection, basePkColumn) {
26
31
  const refs = require_projection.identityRefs(projection.identity, basePkColumn);
27
- if (projection.identity.kind === "composite") return `CONCAT_WS('::', ${refs.map((ref) => `${refSql(ref)}::text`).join(", ")}) AS ${quoteIdent("id")}`;
32
+ if (projection.identity.kind === "composite") return `CONCAT_WS('::', ${refs.map((ref) => `${refSql(ref)}::text`).join(", ")})`;
28
33
  const [ref] = refs;
29
34
  if (!ref) throw new Error("projection identity resolved to no column");
30
- return `${refSql(ref)} AS ${quoteIdent("id")}`;
35
+ return refSql(ref);
36
+ }
37
+ /** The identity expression, aliased as `id`. */
38
+ function identitySql(projection, basePkColumn) {
39
+ return `${compileProjectionIdentity(projection, basePkColumn)} AS ${quoteIdent("id")}`;
31
40
  }
32
41
  function compileProjectionSelect(projection, basePkColumn) {
33
42
  const selectItems = [identitySql(projection, basePkColumn)];
@@ -285,6 +294,24 @@ Object.defineProperty(exports, "compileEntityViews", {
285
294
  return compileEntityViews;
286
295
  }
287
296
  });
297
+ Object.defineProperty(exports, "compileProjectionFrom", {
298
+ enumerable: true,
299
+ get: function() {
300
+ return compileProjectionFrom;
301
+ }
302
+ });
303
+ Object.defineProperty(exports, "compileProjectionIdentity", {
304
+ enumerable: true,
305
+ get: function() {
306
+ return compileProjectionIdentity;
307
+ }
308
+ });
309
+ Object.defineProperty(exports, "compileProjectionJoins", {
310
+ enumerable: true,
311
+ get: function() {
312
+ return compileProjectionJoins;
313
+ }
314
+ });
288
315
  Object.defineProperty(exports, "explainEntitiesConfig", {
289
316
  enumerable: true,
290
317
  get: function() {
@@ -297,3 +324,9 @@ Object.defineProperty(exports, "explainViewExecutionError", {
297
324
  return explainViewExecutionError;
298
325
  }
299
326
  });
327
+ Object.defineProperty(exports, "quoteIdent", {
328
+ enumerable: true,
329
+ get: function() {
330
+ return quoteIdent;
331
+ }
332
+ });
@@ -1,4 +1,4 @@
1
- import { r as identityRefs, t as BASE_REF } from "./projection-C_EMRmZ8.mjs";
1
+ import { r as identityRefs, t as BASE_REF } from "./projection-SCNrLJMV.mjs";
2
2
  //#region src/projection-sql.ts
3
3
  /**
4
4
  * SQL generation for projection-backed entities.
@@ -18,16 +18,25 @@ function refSql(ref) {
18
18
  return `${quoteIdent(ref.table)}.${quoteIdent(ref.column)}`;
19
19
  }
20
20
  /**
21
- * The identity expression, aliased as `id`. Composite identities concatenate
22
- * their parts with `::`; validation guarantees every part is NOT NULL and
23
- * non-text, which is what makes the concatenation collision-free.
21
+ * The identity expression. Composite identities concatenate their parts with
22
+ * `::`; validation guarantees every part is NOT NULL and non-text, which is
23
+ * what makes the concatenation collision-free.
24
+ *
25
+ * Exported unaliased because two paths need the same expression under different
26
+ * names: the view compiler aliases it `id`, and the SDK's projection push source
27
+ * also orders and keyset-paginates by it. Sharing one definition is what keeps
28
+ * a pushed row's `id` identical to the one the view would have produced.
24
29
  */
25
- function identitySql(projection, basePkColumn) {
30
+ function compileProjectionIdentity(projection, basePkColumn) {
26
31
  const refs = identityRefs(projection.identity, basePkColumn);
27
- if (projection.identity.kind === "composite") return `CONCAT_WS('::', ${refs.map((ref) => `${refSql(ref)}::text`).join(", ")}) AS ${quoteIdent("id")}`;
32
+ if (projection.identity.kind === "composite") return `CONCAT_WS('::', ${refs.map((ref) => `${refSql(ref)}::text`).join(", ")})`;
28
33
  const [ref] = refs;
29
34
  if (!ref) throw new Error("projection identity resolved to no column");
30
- return `${refSql(ref)} AS ${quoteIdent("id")}`;
35
+ return refSql(ref);
36
+ }
37
+ /** The identity expression, aliased as `id`. */
38
+ function identitySql(projection, basePkColumn) {
39
+ return `${compileProjectionIdentity(projection, basePkColumn)} AS ${quoteIdent("id")}`;
31
40
  }
32
41
  function compileProjectionSelect(projection, basePkColumn) {
33
42
  const selectItems = [identitySql(projection, basePkColumn)];
@@ -267,4 +276,4 @@ async function explainEntitiesConfig(config, run, options = {}) {
267
276
  return results;
268
277
  }
269
278
  //#endregion
270
- export { explainViewExecutionError as a, explainEntitiesConfig as i, compileEntityView as n, compileEntityViews as r, DEFAULT_VIEW_PREFIX as t };
279
+ export { explainViewExecutionError as a, compileProjectionJoins as c, explainEntitiesConfig as i, quoteIdent as l, compileEntityView as n, compileProjectionFrom as o, compileEntityViews as r, compileProjectionIdentity as s, DEFAULT_VIEW_PREFIX as t };
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_view_compiler = require("./view-compiler-BpNI8Ttw.cjs");
2
+ const require_view_compiler = require("./view-compiler-DTGSwTcz.cjs");
3
3
  exports.DEFAULT_VIEW_PREFIX = require_view_compiler.DEFAULT_VIEW_PREFIX;
4
4
  exports.compileEntityView = require_view_compiler.compileEntityView;
5
5
  exports.compileEntityViews = require_view_compiler.compileEntityViews;
@@ -1,2 +1,2 @@
1
- import { a as explainViewExecutionError, i as explainEntitiesConfig, n as compileEntityView, r as compileEntityViews, t as DEFAULT_VIEW_PREFIX } from "./view-compiler-CcqsGxv4.mjs";
1
+ import { a as explainViewExecutionError, i as explainEntitiesConfig, n as compileEntityView, r as compileEntityViews, t as DEFAULT_VIEW_PREFIX } from "./view-compiler-DjzRXiAJ.mjs";
2
2
  export { DEFAULT_VIEW_PREFIX, compileEntityView, compileEntityViews, explainEntitiesConfig, explainViewExecutionError };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clivly/core",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "ORM/auth-agnostic CRM adapter contracts and shared domain types for Clivly.",