clivly 0.9.6 → 0.10.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.
- package/README.md +24 -12
- package/{adapter-C2eRbBfo.d.cts → adapter-1TN0zohk.d.cts} +1 -1
- package/{adapter-D5LRa-NA.d.mts → adapter-uxirB88i.d.mts} +1 -1
- package/{auth-adapter-Bjgo8LhN.d.mts → auth-adapter-CXTiW3Mb.d.cts} +1 -1
- package/{auth-adapter-DWzgl5Yq.d.cts → auth-adapter-DSuYwv1c.d.mts} +1 -1
- package/auth-better-auth.d.cts +1 -1
- package/auth-better-auth.d.mts +1 -1
- package/auth-clerk.d.cts +1 -1
- package/auth-clerk.d.mts +1 -1
- package/auth-workos.d.cts +1 -1
- package/auth-workos.d.mts +1 -1
- package/core-adapter.d.cts +1 -1
- package/core-adapter.d.mts +1 -1
- package/core-auth-adapter.cjs +1 -1
- package/core-auth-adapter.d.cts +1 -1
- package/core-auth-adapter.d.mts +1 -1
- package/core-auth-adapter.mjs +1 -1
- package/core-drizzle.cjs +1 -1
- package/core-drizzle.d.cts +1 -1
- package/core-drizzle.d.mts +1 -1
- package/core-drizzle.mjs +1 -1
- package/core-entity-config.cjs +1 -1
- package/core-entity-config.d.cts +1 -1
- package/core-entity-config.d.mts +1 -1
- package/core-entity-config.mjs +1 -1
- package/core-entity-heuristics.cjs +1 -0
- package/core-entity-heuristics.d.cts +3 -3
- package/core-entity-heuristics.d.mts +3 -3
- package/core-entity-heuristics.mjs +2 -2
- package/core-mapping-form.cjs +1 -1
- package/core-mapping-form.d.cts +1 -1
- package/core-mapping-form.d.mts +1 -1
- package/core-mapping-form.mjs +1 -1
- package/core-mappings-config.cjs +1 -1
- package/core-mappings-config.d.cts +1 -1
- package/core-mappings-config.d.mts +1 -1
- package/core-mappings-config.mjs +1 -1
- package/core-sync-engine.cjs +1 -1
- package/core-sync-engine.d.cts +1 -1
- package/core-sync-engine.d.mts +1 -1
- package/core-sync-engine.mjs +1 -1
- package/core-types.cjs +4 -0
- package/core-types.d.cts +2 -2
- package/core-types.d.mts +2 -2
- package/core-types.mjs +2 -1
- package/core-view-compiler.cjs +1 -1
- package/core-view-compiler.d.cts +1 -1
- package/core-view-compiler.d.mts +1 -1
- package/core-view-compiler.mjs +1 -1
- package/core.cjs +18 -17
- package/core.d.cts +10 -10
- package/core.d.mts +10 -10
- package/core.mjs +10 -9
- package/{drizzle-DEtRrqtc.d.cts → drizzle-DTOuGXEn.d.cts} +4 -2
- package/{drizzle-bfjVzYR6.cjs → drizzle-DcB7OfBp.cjs} +9 -1
- package/{drizzle-CiK8MMEZ.d.mts → drizzle-SGapoly2.d.mts} +4 -2
- package/{drizzle-3kvhkwO7.mjs → drizzle-wbcuG-cy.mjs} +9 -1
- package/drizzle.cjs +58 -24
- package/drizzle.d.cts +10 -4
- package/drizzle.d.mts +10 -4
- package/drizzle.mjs +58 -24
- package/{entity-config-CusbTOJ1.mjs → entity-config-C4d3K9CP.mjs} +114 -8
- package/{entity-config-B2RA53nw.d.cts → entity-config-DNQAMbMS.d.cts} +27 -1
- package/{entity-config-B2RA53nw.d.mts → entity-config-DNQAMbMS.d.mts} +27 -1
- package/{entity-config-DE30_RpU.cjs → entity-config-DgAe0_YD.cjs} +119 -7
- package/index.cjs +56 -15
- package/index.mjs +56 -15
- package/internal-BAOG5eE4.d.mts +226 -0
- package/internal-BHJ0X3fC.d.cts +226 -0
- package/internal-Bgiimp5D.mjs +144 -0
- package/internal-Cz59xMj8.cjs +167 -0
- package/internal-adapter.d.cts +1 -1
- package/internal-adapter.d.mts +1 -1
- package/internal-auth-adapter.d.cts +1 -1
- package/internal-auth-adapter.d.mts +1 -1
- package/internal-drizzle.cjs +1 -1
- package/internal-drizzle.d.cts +1 -1
- package/internal-drizzle.d.mts +1 -1
- package/internal-drizzle.mjs +1 -1
- package/internal-entity-config.cjs +1 -1
- package/internal-entity-config.d.cts +1 -1
- package/internal-entity-config.d.mts +1 -1
- package/internal-entity-config.mjs +1 -1
- package/internal-entity-heuristics.cjs +34 -1
- package/internal-entity-heuristics.d.cts +8 -2
- package/internal-entity-heuristics.d.mts +8 -2
- package/internal-entity-heuristics.mjs +34 -2
- package/internal-mapping-form.d.cts +1 -1
- package/internal-mapping-form.d.mts +1 -1
- package/internal-mappings-config.cjs +1 -1
- package/internal-mappings-config.d.cts +1 -1
- package/internal-mappings-config.d.mts +1 -1
- package/internal-mappings-config.mjs +1 -1
- package/internal-sync-engine.cjs +1 -1
- package/internal-sync-engine.d.cts +1 -1
- package/internal-sync-engine.d.mts +1 -1
- package/internal-sync-engine.mjs +1 -1
- package/internal-types.cjs +4 -0
- package/internal-types.d.cts +2 -2
- package/internal-types.d.mts +2 -2
- package/internal-types.mjs +2 -1
- package/internal-view-compiler.cjs +1 -1
- package/internal-view-compiler.d.cts +1 -1
- package/internal-view-compiler.d.mts +1 -1
- package/internal-view-compiler.mjs +1 -1
- package/internal.cjs +17 -15
- package/internal.d.cts +10 -10
- package/internal.d.mts +10 -10
- package/internal.mjs +9 -8
- package/{mapping-form-DH77BXLv.d.mts → mapping-form-Cc7Ewv8c.d.mts} +1 -1
- package/{mapping-form-J0aU6O7l.d.cts → mapping-form-DwdbYAfR.d.cts} +1 -1
- package/{mappings-config-D9dsonoi.d.mts → mappings-config-Be9D43Np.d.mts} +1 -1
- package/{mappings-config-RQLGx8ub.d.cts → mappings-config-DUt4-9iO.d.cts} +1 -1
- package/{mappings-config-CjCmT-aU.cjs → mappings-config-Dx9ldgdf.cjs} +2 -16
- package/{mappings-config-7qQ47p9K.mjs → mappings-config-MoXBeI8p.mjs} +1 -15
- package/{namespace-probe-Ckn9yJ6F.d.mts → namespace-probe-9ScMDR0t.d.mts} +42 -2
- package/{namespace-probe-DaTJINS-.d.cts → namespace-probe-DC4tbmLj.d.cts} +42 -2
- package/package.json +1 -1
- package/{projection-hnPSgH6G.mjs → projection-CSGJbZlZ.mjs} +1 -1
- package/{projection-DEwL-D8R.cjs → projection-Dz6_i1-w.cjs} +0 -6
- package/{projection-sql-iHy-Cx6V.cjs → projection-sql-CbXCKt3s.cjs} +1 -1
- package/{projection-sql-9zzTVGvf.mjs → projection-sql-iHoiYr1R.mjs} +1 -1
- package/{sdk-w8Kv_XnW.cjs → sdk-B1vX4kUJ.cjs} +347 -17
- package/{sdk-Dkq6ELkf.mjs → sdk-D6gX0TXS.mjs} +347 -17
- package/sdk.cjs +2 -2
- package/sdk.d.cts +3 -3
- package/sdk.d.mts +3 -3
- package/sdk.mjs +2 -2
- package/{sync-engine-BLgwLpR6.cjs → sync-engine-B0FT1ax6.cjs} +1 -1
- package/{sync-engine-B_IzoUSx.mjs → sync-engine-CTSIcLlZ.mjs} +1 -1
- package/{sync-engine-BG2O1an2.d.cts → sync-engine-Df0kHAoJ.d.cts} +2 -2
- package/{sync-engine-DgQbrJON.d.mts → sync-engine-ugFacJ6G.d.mts} +2 -2
- package/{types-B1oRXdNP.d.cts → types-Cq1uHUKp.d.cts} +28 -2
- package/{types-B1oRXdNP.d.mts → types-Cq1uHUKp.d.mts} +28 -2
- package/types-Cq5gHCTq.cjs +20 -0
- package/types-YJTkXKzU.mjs +9 -0
- package/{view-compiler-D_6gfXFr.mjs → view-compiler-BzKk8nY3.mjs} +2 -2
- package/{view-compiler-CmEdAMwj.d.cts → view-compiler-D3zp9S3K.d.cts} +1 -1
- package/{view-compiler-Bo7pqXW3.d.mts → view-compiler-TpzDTu7z.d.mts} +1 -1
- package/{view-compiler-BHI5E4QI.cjs → view-compiler-ZKZbd3SK.cjs} +2 -2
- package/vite.d.cts +1 -1
- package/vite.d.mts +1 -1
- package/internal-BQ47iN6f.cjs +0 -259
- package/internal-ChufvXE6.mjs +0 -212
- package/internal-CvlFk3KC.d.mts +0 -180
- package/internal-DGUOLQAq.d.cts +0 -180
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { i as projectionSchema } from "./projection-CSGJbZlZ.mjs";
|
|
2
|
+
import { m as validateProjection, o as customObjectDeclarations, x as primaryKeyColumns } from "./entity-config-C4d3K9CP.mjs";
|
|
3
|
+
import { t as entitiesToMappings } from "./mappings-config-MoXBeI8p.mjs";
|
|
3
4
|
import { t as DRIZZLE_META } from "./drizzle-meta-D-5k3n0i.mjs";
|
|
4
5
|
//#region ../sdk/src/deployment-identity.ts
|
|
5
6
|
const MAX_DEPLOYMENT_ID_LENGTH = 128;
|
|
@@ -989,6 +990,240 @@ function describeSilentPush(target, body) {
|
|
|
989
990
|
return `Clivly sync: pushed ${received} row(s) for ${objectType ? `"${source}" → "${objectType}"` : `"${source}"`} and none were stored — no active mapping in this workspace targets it, so the rows were dropped. Map it in Integrations → Mapping, then sync again.`;
|
|
990
991
|
}
|
|
991
992
|
//#endregion
|
|
993
|
+
//#region ../sdk/src/remote-projections.ts
|
|
994
|
+
const SYNC_CUSTOM_PATH$1 = "/clivly/sdk/sync/custom";
|
|
995
|
+
const MISSING_INTROSPECTOR = "this app cannot run dashboard-authored derived objects yet — add `introspector: drizzleIntrospector(db)` to clivly.config.ts";
|
|
996
|
+
/**
|
|
997
|
+
* Turn definitions fetched from the cloud into runnable sync sources.
|
|
998
|
+
*
|
|
999
|
+
* Revalidates every projection locally against the schema THIS app discovered,
|
|
1000
|
+
* never against the cloud's stored copy. Two reasons, and both matter:
|
|
1001
|
+
*
|
|
1002
|
+
* 1. Security. `checkTablesExist`/`checkRefs` bound every table and column ref
|
|
1003
|
+
* to the schema passed in, so validating against the locally-discovered
|
|
1004
|
+
* schema makes the blast radius exactly the namespace the developer handed
|
|
1005
|
+
* to `discoverFromDrizzle`. Trusting the cloud's verdict instead would let a
|
|
1006
|
+
* compromised cloud read any table in the database.
|
|
1007
|
+
* 2. Truth. The stored copy can be stale. A column dropped in the host app
|
|
1008
|
+
* becomes a readable quarantine here instead of a raw Postgres error out of
|
|
1009
|
+
* `sql.raw` at execution time.
|
|
1010
|
+
*/
|
|
1011
|
+
function resolveRemoteProjections(args) {
|
|
1012
|
+
const { entries, introspector, schema } = args;
|
|
1013
|
+
return entries.map((entry) => resolveOne(entry, schema, introspector));
|
|
1014
|
+
}
|
|
1015
|
+
/**
|
|
1016
|
+
* The base table's PK, resolved from the schema THIS app discovered — never
|
|
1017
|
+
* from the cloud's copy.
|
|
1018
|
+
*
|
|
1019
|
+
* `validateProjection` proved its uniqueness case against this exact source
|
|
1020
|
+
* (`primaryKeyColumns` over the locally-discovered schema, see
|
|
1021
|
+
* `projection-validate.ts`). Compiling a *different* column — the cloud's
|
|
1022
|
+
* `basePkColumn`, which can go stale the moment a host renames a PK and the
|
|
1023
|
+
* `updatedAt`-only ETag never invalidates — would defeat that proof and
|
|
1024
|
+
* revive the raw-Postgres-error failure mode local revalidation exists to
|
|
1025
|
+
* prevent. Only relevant when the identity is `base_pk` with no explicit
|
|
1026
|
+
* column; every other identity kind ignores `basePkColumn` entirely.
|
|
1027
|
+
*/
|
|
1028
|
+
function resolveLocalBasePk(projection, schema) {
|
|
1029
|
+
if (projection.identity.kind !== "base_pk" || projection.identity.column) return;
|
|
1030
|
+
const baseTable = schema.find((t) => t.name === projection.baseTable);
|
|
1031
|
+
if (!baseTable) return;
|
|
1032
|
+
return primaryKeyColumns(baseTable)[0];
|
|
1033
|
+
}
|
|
1034
|
+
function resolveOne(entry, schema, introspector) {
|
|
1035
|
+
const parsed = projectionSchema.safeParse(entry.projection);
|
|
1036
|
+
if (!parsed.success) return {
|
|
1037
|
+
id: entry.id,
|
|
1038
|
+
status: "invalid",
|
|
1039
|
+
reason: `projection did not parse: ${parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; ")}`
|
|
1040
|
+
};
|
|
1041
|
+
const projection = parsed.data;
|
|
1042
|
+
const errors = validateProjection(projection, schema, entry.entityKey);
|
|
1043
|
+
if (errors.length > 0) return {
|
|
1044
|
+
id: entry.id,
|
|
1045
|
+
status: "invalid",
|
|
1046
|
+
reason: errors.map((e) => `${e.path}: ${e.message}`).join("; ")
|
|
1047
|
+
};
|
|
1048
|
+
if (!introspector?.projectionSource) return {
|
|
1049
|
+
id: entry.id,
|
|
1050
|
+
status: "skipped",
|
|
1051
|
+
reason: MISSING_INTROSPECTOR
|
|
1052
|
+
};
|
|
1053
|
+
try {
|
|
1054
|
+
const basePkColumn = resolveLocalBasePk(projection, schema) ?? entry.basePkColumn;
|
|
1055
|
+
const source = introspector.projectionSource(projection, {
|
|
1056
|
+
objectType: entry.objectType,
|
|
1057
|
+
...basePkColumn ? { basePkColumn } : {}
|
|
1058
|
+
});
|
|
1059
|
+
return {
|
|
1060
|
+
id: entry.id,
|
|
1061
|
+
status: "ok",
|
|
1062
|
+
source
|
|
1063
|
+
};
|
|
1064
|
+
} catch (error) {
|
|
1065
|
+
return {
|
|
1066
|
+
id: entry.id,
|
|
1067
|
+
status: "failed",
|
|
1068
|
+
reason: error instanceof Error ? error.message : String(error)
|
|
1069
|
+
};
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
const PROJECTIONS_PATH = "/clivly/sdk/projections";
|
|
1073
|
+
const PROJECTIONS_REPORT_PATH = "/clivly/sdk/projections/report";
|
|
1074
|
+
const MAX_REASON = 2e3;
|
|
1075
|
+
/**
|
|
1076
|
+
* Merge what resolution decided with what the push actually did.
|
|
1077
|
+
*
|
|
1078
|
+
* A `status: "ok"` outcome means the projection *resolved*, not that its rows
|
|
1079
|
+
* landed. If the push then failed, the object did not sync and must not be
|
|
1080
|
+
* reported as healthy — so the push result wins for those.
|
|
1081
|
+
*/
|
|
1082
|
+
function buildRemoteProjectionReport(args) {
|
|
1083
|
+
return {
|
|
1084
|
+
...args.runId ? { runId: args.runId } : {},
|
|
1085
|
+
results: args.outcomes.map((outcome) => {
|
|
1086
|
+
if (outcome.status !== "ok") return {
|
|
1087
|
+
id: outcome.id,
|
|
1088
|
+
status: outcome.status,
|
|
1089
|
+
reason: outcome.reason.slice(0, MAX_REASON)
|
|
1090
|
+
};
|
|
1091
|
+
const result = args.pushed.get(outcome.source.entity);
|
|
1092
|
+
if (result?.ok) return {
|
|
1093
|
+
id: outcome.id,
|
|
1094
|
+
status: "ok",
|
|
1095
|
+
rows: result.count
|
|
1096
|
+
};
|
|
1097
|
+
return {
|
|
1098
|
+
id: outcome.id,
|
|
1099
|
+
status: "failed",
|
|
1100
|
+
reason: (result?.reason ?? "the push to Clivly failed; rows were read but not stored").slice(0, MAX_REASON)
|
|
1101
|
+
};
|
|
1102
|
+
})
|
|
1103
|
+
};
|
|
1104
|
+
}
|
|
1105
|
+
function createRemoteProjectionFetcher(args) {
|
|
1106
|
+
let etag = null;
|
|
1107
|
+
let cached = [];
|
|
1108
|
+
return { async fetch() {
|
|
1109
|
+
try {
|
|
1110
|
+
const response = await args.fetcher(`${args.apiUrl}${PROJECTIONS_PATH}`, { headers: {
|
|
1111
|
+
authorization: `Bearer ${args.apiKey}`,
|
|
1112
|
+
...etag ? { "if-none-match": etag } : {}
|
|
1113
|
+
} });
|
|
1114
|
+
if (response.status === 304) return cached;
|
|
1115
|
+
if (!response.ok) return [];
|
|
1116
|
+
const body = await response.json();
|
|
1117
|
+
etag = body.etag ?? null;
|
|
1118
|
+
cached = body.projections ?? [];
|
|
1119
|
+
return cached;
|
|
1120
|
+
} catch {
|
|
1121
|
+
return [];
|
|
1122
|
+
}
|
|
1123
|
+
} };
|
|
1124
|
+
}
|
|
1125
|
+
const REMOTE_PAGE_SIZE = 500;
|
|
1126
|
+
/**
|
|
1127
|
+
* Page one source to exhaustion, keyset-paging on identity alone (the id
|
|
1128
|
+
* field, no timestamp). Split out of `pushRemoteProjections` so that
|
|
1129
|
+
* function's own cognitive complexity stays under the lint threshold — this
|
|
1130
|
+
* is the piece that can throw (a `fetchPage` execution error), kept separate
|
|
1131
|
+
* from push-failure handling below.
|
|
1132
|
+
*/
|
|
1133
|
+
async function fetchAllPages(source, pageSize) {
|
|
1134
|
+
const idField = source.idField ?? "id";
|
|
1135
|
+
const all = [];
|
|
1136
|
+
let since = null;
|
|
1137
|
+
for (;;) {
|
|
1138
|
+
const rows = await source.fetchPage({
|
|
1139
|
+
since,
|
|
1140
|
+
limit: pageSize
|
|
1141
|
+
});
|
|
1142
|
+
if (rows.length === 0) break;
|
|
1143
|
+
all.push(...rows);
|
|
1144
|
+
const last = rows.at(-1);
|
|
1145
|
+
const nextId = String(last?.[idField]);
|
|
1146
|
+
if (since && nextId === since.id) break;
|
|
1147
|
+
since = { id: nextId };
|
|
1148
|
+
if (rows.length < pageSize) break;
|
|
1149
|
+
}
|
|
1150
|
+
return all;
|
|
1151
|
+
}
|
|
1152
|
+
/**
|
|
1153
|
+
* Page a remote projection by identity and push one `full` batch.
|
|
1154
|
+
*
|
|
1155
|
+
* `full` rather than `delta` because only a full push lets the server archive
|
|
1156
|
+
* rows that dropped out when a join or filter stopped matching — a delta cannot
|
|
1157
|
+
* express absence. And identity rather than a timestamp because a
|
|
1158
|
+
* dashboard-authored projection has no watermark column, while validation has
|
|
1159
|
+
* already proven the identity unique.
|
|
1160
|
+
*
|
|
1161
|
+
* `pageSize` defaults to `REMOTE_PAGE_SIZE` and exists so a test can force a
|
|
1162
|
+
* short page without either mutating the exported constant or constructing a
|
|
1163
|
+
* fixture hundreds of rows deep.
|
|
1164
|
+
*
|
|
1165
|
+
* Returns one entry per source, keyed by `source.entity`. `count` and `ok`
|
|
1166
|
+
* are independent: `count` is how many rows were pushed (0 for a projection
|
|
1167
|
+
* that legitimately matches nothing this run), `ok` is whether the push
|
|
1168
|
+
* itself succeeded. A caller that folds failures into a report must branch
|
|
1169
|
+
* on `ok`, never on `count === 0` — a correctly-working, legitimately-empty
|
|
1170
|
+
* projection has `ok: true, count: 0` and is not a failure.
|
|
1171
|
+
*
|
|
1172
|
+
* Each source's paging-and-push is wrapped individually: a projection can
|
|
1173
|
+
* validate cleanly and still fail at execution — permission denied, a type
|
|
1174
|
+
* error, a column dropped between validation and this run — and `fetchPage`
|
|
1175
|
+
* throwing is the realistic shape of that. Quarantine that one source as
|
|
1176
|
+
* `{ count: 0, ok: false, reason }` and keep going. The design's promise is
|
|
1177
|
+
* one bad object never takes down the others or the run's report; letting a
|
|
1178
|
+
* throw here escape the loop would break that promise for every source
|
|
1179
|
+
* queued after the failing one.
|
|
1180
|
+
*
|
|
1181
|
+
* Paging and pushing are caught separately, on purpose: `reason` is set only
|
|
1182
|
+
* when paging itself threw (no rows were ever read), so the reported cause
|
|
1183
|
+
* names execution — not the push, which is what actually failed when
|
|
1184
|
+
* `args.push` returns `false`. Conflating the two sent an author whose
|
|
1185
|
+
* projection can't even run to look at their push credentials instead of
|
|
1186
|
+
* their SQL.
|
|
1187
|
+
*/
|
|
1188
|
+
async function pushRemoteProjections(args) {
|
|
1189
|
+
const pageSize = args.pageSize ?? REMOTE_PAGE_SIZE;
|
|
1190
|
+
const pushed = /* @__PURE__ */ new Map();
|
|
1191
|
+
for (const source of args.sources) {
|
|
1192
|
+
let all;
|
|
1193
|
+
try {
|
|
1194
|
+
all = await fetchAllPages(source, pageSize);
|
|
1195
|
+
} catch (error) {
|
|
1196
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1197
|
+
pushed.set(source.entity, {
|
|
1198
|
+
count: 0,
|
|
1199
|
+
ok: false,
|
|
1200
|
+
reason: `the projection failed to execute: ${message}`.slice(0, MAX_REASON)
|
|
1201
|
+
});
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
try {
|
|
1205
|
+
const ok = await args.push(SYNC_CUSTOM_PATH$1, {
|
|
1206
|
+
source: source.entity,
|
|
1207
|
+
rows: all,
|
|
1208
|
+
mode: "full",
|
|
1209
|
+
fetched: all.length,
|
|
1210
|
+
cursor: null,
|
|
1211
|
+
objectType: source.objectType
|
|
1212
|
+
});
|
|
1213
|
+
pushed.set(source.entity, {
|
|
1214
|
+
count: all.length,
|
|
1215
|
+
ok
|
|
1216
|
+
});
|
|
1217
|
+
} catch {
|
|
1218
|
+
pushed.set(source.entity, {
|
|
1219
|
+
count: 0,
|
|
1220
|
+
ok: false
|
|
1221
|
+
});
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
return pushed;
|
|
1225
|
+
}
|
|
1226
|
+
//#endregion
|
|
992
1227
|
//#region ../sdk/src/self-check.ts
|
|
993
1228
|
function selfCheck(input) {
|
|
994
1229
|
const issues = [];
|
|
@@ -1337,12 +1572,25 @@ function resolveContactEntity(config) {
|
|
|
1337
1572
|
}
|
|
1338
1573
|
function collectSchemaMeta(config) {
|
|
1339
1574
|
const byTable = /* @__PURE__ */ new Map();
|
|
1340
|
-
|
|
1575
|
+
const merge = (name, meta) => {
|
|
1576
|
+
const existing = byTable.get(name);
|
|
1577
|
+
byTable.set(name, {
|
|
1578
|
+
columnsMeta: meta.columnsMeta ?? existing?.columnsMeta,
|
|
1579
|
+
uniqueConstraints: meta.uniqueConstraints ?? existing?.uniqueConstraints
|
|
1580
|
+
});
|
|
1581
|
+
};
|
|
1582
|
+
for (const table of config.schema ?? []) if (table.columnsMeta || table.uniqueConstraints) merge(table.name, {
|
|
1583
|
+
columnsMeta: table.columnsMeta,
|
|
1584
|
+
uniqueConstraints: table.uniqueConstraints
|
|
1585
|
+
});
|
|
1341
1586
|
const sources = [];
|
|
1342
1587
|
if (config.source) sources.push(config.source.contacts, config.source.companies, config.source.deals, ...config.source.custom ?? []);
|
|
1343
1588
|
for (const source of sources) {
|
|
1344
1589
|
const meta = source?.[DRIZZLE_META];
|
|
1345
|
-
if (meta?.tableName && meta.columnsMeta)
|
|
1590
|
+
if (meta?.tableName && (meta.columnsMeta || meta.uniqueConstraints)) merge(meta.tableName, {
|
|
1591
|
+
columnsMeta: meta.columnsMeta,
|
|
1592
|
+
uniqueConstraints: meta.uniqueConstraints
|
|
1593
|
+
});
|
|
1346
1594
|
}
|
|
1347
1595
|
return byTable;
|
|
1348
1596
|
}
|
|
@@ -1357,12 +1605,13 @@ function buildSchema(config) {
|
|
|
1357
1605
|
if (config.contactEntity && !byName.has(config.contactEntity)) byName.set(config.contactEntity, new Set(config.contactFields ?? []));
|
|
1358
1606
|
const metaByTable = collectSchemaMeta(config);
|
|
1359
1607
|
return [...byName].map(([name, columns]) => {
|
|
1360
|
-
const
|
|
1361
|
-
|
|
1608
|
+
const meta = metaByTable.get(name);
|
|
1609
|
+
for (const col of meta?.columnsMeta ?? []) columns.add(col.name);
|
|
1362
1610
|
return {
|
|
1363
1611
|
name,
|
|
1364
1612
|
columns: [...columns],
|
|
1365
|
-
...columnsMeta ? { columnsMeta } : {}
|
|
1613
|
+
...meta?.columnsMeta ? { columnsMeta: meta.columnsMeta } : {},
|
|
1614
|
+
...meta?.uniqueConstraints ? { uniqueConstraints: meta.uniqueConstraints } : {}
|
|
1366
1615
|
};
|
|
1367
1616
|
});
|
|
1368
1617
|
}
|
|
@@ -1397,6 +1646,24 @@ function timingSafeEqual(a, b) {
|
|
|
1397
1646
|
}
|
|
1398
1647
|
const RUN_ID_HEADER = "x-clivly-run-id";
|
|
1399
1648
|
const SIGNATURE_HEADER = "x-clivly-signature";
|
|
1649
|
+
/**
|
|
1650
|
+
* An error the mounted trigger route should answer with a specific HTTP
|
|
1651
|
+
* status, rather than the generic 500 it uses for a genuinely unhandled
|
|
1652
|
+
* error. A fail-safe rejection (e.g. an unresolvable sample `entityKey`) is a
|
|
1653
|
+
* configuration mismatch the caller can fix — surfacing it as "your app
|
|
1654
|
+
* crashed" sends a developer hunting through their own sync handler instead.
|
|
1655
|
+
*/
|
|
1656
|
+
var TriggerRequestError = class extends Error {
|
|
1657
|
+
status;
|
|
1658
|
+
constructor(status, message) {
|
|
1659
|
+
super(message);
|
|
1660
|
+
this.name = new.target.name;
|
|
1661
|
+
this.status = status;
|
|
1662
|
+
}
|
|
1663
|
+
};
|
|
1664
|
+
function triggerErrorStatus(error) {
|
|
1665
|
+
return error instanceof TriggerRequestError ? error.status : 500;
|
|
1666
|
+
}
|
|
1400
1667
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
1401
1668
|
const SIGNATURE_HEADER_RE = /^t=(\d+),v1=([0-9a-f]+)$/;
|
|
1402
1669
|
const SECONDS_PER_MS = 1e3;
|
|
@@ -1578,9 +1845,15 @@ function createClivlySDK(config) {
|
|
|
1578
1845
|
const cursorStore = config.cursorStore ?? createMemoryCursorStore();
|
|
1579
1846
|
const fetcher = createFetcher(config.retry);
|
|
1580
1847
|
let warnedUnsignedTrigger = false;
|
|
1848
|
+
const remoteProjections = createRemoteProjectionFetcher({
|
|
1849
|
+
apiKey: config.apiKey,
|
|
1850
|
+
apiUrl,
|
|
1851
|
+
fetcher
|
|
1852
|
+
});
|
|
1581
1853
|
let observedUrl;
|
|
1582
1854
|
let lastPushFailure = null;
|
|
1583
1855
|
let lastPush = { failed: false };
|
|
1856
|
+
let lastRemoteOutcomes = [];
|
|
1584
1857
|
const warnedSilentTargets = /* @__PURE__ */ new Set();
|
|
1585
1858
|
const warnIfSilent = async (target, response) => {
|
|
1586
1859
|
if (typeof response.json !== "function") return;
|
|
@@ -1652,18 +1925,58 @@ function createClivlySDK(config) {
|
|
|
1652
1925
|
for (const customSource of customSources ?? []) if (!await syncOne(customSource, SYNC_CUSTOM_PATH, mode, customSource.objectType, runId)) failed.push(customSource.entity);
|
|
1653
1926
|
return failed;
|
|
1654
1927
|
};
|
|
1928
|
+
const syncRemoteSources = async (sources, runId) => {
|
|
1929
|
+
const pushed = await pushRemoteProjections({
|
|
1930
|
+
push: createPush(runId),
|
|
1931
|
+
sources
|
|
1932
|
+
});
|
|
1933
|
+
const failed = [];
|
|
1934
|
+
for (const [entity, result] of pushed) if (!result.ok) failed.push(entity);
|
|
1935
|
+
return {
|
|
1936
|
+
failed,
|
|
1937
|
+
pushed
|
|
1938
|
+
};
|
|
1939
|
+
};
|
|
1940
|
+
const reportRemoteOutcomes = async (outcomes, pushed, runId) => {
|
|
1941
|
+
if (outcomes.length === 0) return;
|
|
1942
|
+
try {
|
|
1943
|
+
const report = buildRemoteProjectionReport({
|
|
1944
|
+
outcomes,
|
|
1945
|
+
pushed,
|
|
1946
|
+
runId
|
|
1947
|
+
});
|
|
1948
|
+
await fetcher(`${apiUrl}${PROJECTIONS_REPORT_PATH}`, {
|
|
1949
|
+
method: "POST",
|
|
1950
|
+
headers: {
|
|
1951
|
+
authorization: `Bearer ${config.apiKey}`,
|
|
1952
|
+
"content-type": "application/json"
|
|
1953
|
+
},
|
|
1954
|
+
body: JSON.stringify(report)
|
|
1955
|
+
});
|
|
1956
|
+
} catch {}
|
|
1957
|
+
};
|
|
1655
1958
|
const runSync = async (options) => {
|
|
1656
|
-
|
|
1959
|
+
const remoteOutcomes = resolveRemoteProjections({
|
|
1960
|
+
entries: await remoteProjections.fetch(),
|
|
1961
|
+
introspector: config.introspector,
|
|
1962
|
+
schema: buildSchema(config)
|
|
1963
|
+
});
|
|
1964
|
+
lastRemoteOutcomes = remoteOutcomes;
|
|
1965
|
+
const remoteSources = remoteOutcomes.filter((o) => o.status === "ok").map((o) => o.source);
|
|
1966
|
+
if (!config.source && remoteSources.length === 0 && remoteOutcomes.length === 0) return;
|
|
1657
1967
|
lastPushFailure = null;
|
|
1658
1968
|
const mode = options?.mode ?? "delta";
|
|
1659
1969
|
const runId = options?.runId;
|
|
1660
1970
|
const failed = [];
|
|
1661
|
-
if (config.source
|
|
1971
|
+
if (config.source?.companies) {
|
|
1662
1972
|
if (!await syncOne(config.source.companies, SYNC_COMPANIES_PATH, mode, void 0, runId)) failed.push(config.source.companies.entity);
|
|
1663
1973
|
}
|
|
1664
|
-
if (!await syncOne(config.source.contacts, SYNC_CONTACTS_PATH, mode, void 0, runId)) failed.push(config.source.contacts.entity);
|
|
1665
|
-
if (config.source
|
|
1666
|
-
failed.push(...await syncCustomSources(config.source
|
|
1974
|
+
if (config.source?.contacts && !await syncOne(config.source.contacts, SYNC_CONTACTS_PATH, mode, void 0, runId)) failed.push(config.source.contacts.entity);
|
|
1975
|
+
if (config.source?.deals && !await syncOne(config.source.deals, SYNC_DEALS_PATH, mode, void 0, runId)) failed.push(config.source.deals.entity);
|
|
1976
|
+
failed.push(...await syncCustomSources(config.source?.custom, mode, runId));
|
|
1977
|
+
const remote = await syncRemoteSources(remoteSources, runId);
|
|
1978
|
+
failed.push(...remote.failed);
|
|
1979
|
+
await reportRemoteOutcomes(lastRemoteOutcomes, remote.pushed, runId);
|
|
1667
1980
|
if (failed.length > 0) {
|
|
1668
1981
|
const message = describePushFailure(failed);
|
|
1669
1982
|
lastPush = {
|
|
@@ -1676,7 +1989,7 @@ function createClivlySDK(config) {
|
|
|
1676
1989
|
};
|
|
1677
1990
|
const runSampleSync = async (entityKey, runId) => {
|
|
1678
1991
|
const resolved = resolveSampleSource(config, entityKey);
|
|
1679
|
-
if (!resolved) throw new
|
|
1992
|
+
if (!resolved) throw new TriggerRequestError(400, `Clivly sync: no source is configured for entity "${entityKey}". The dashboard maps this table, but clivly.config declares no matching entity — add it to \`entities\`, or remove the mapping in Integrations → Mapping.`);
|
|
1680
1993
|
lastPushFailure = null;
|
|
1681
1994
|
if (!await syncOne(resolved.source, resolved.path, "delta", resolved.objectType, runId, SAMPLE_BATCH_SIZE, SAMPLE_BATCH_SIZE, false)) throw new Error(describePushFailure([resolved.source.entity]));
|
|
1682
1995
|
};
|
|
@@ -1689,6 +2002,20 @@ function createClivlySDK(config) {
|
|
|
1689
2002
|
observedUrl
|
|
1690
2003
|
})
|
|
1691
2004
|
});
|
|
2005
|
+
const describeRemoteProjections = () => {
|
|
2006
|
+
const counts = {
|
|
2007
|
+
failed: 0,
|
|
2008
|
+
invalid: 0,
|
|
2009
|
+
ok: 0,
|
|
2010
|
+
skipped: 0
|
|
2011
|
+
};
|
|
2012
|
+
for (const outcome of lastRemoteOutcomes) counts[outcome.status] += 1;
|
|
2013
|
+
return {
|
|
2014
|
+
capable: Boolean(config.introspector?.projectionSource),
|
|
2015
|
+
ran: lastRemoteOutcomes.length > 0,
|
|
2016
|
+
...counts
|
|
2017
|
+
};
|
|
2018
|
+
};
|
|
1692
2019
|
const sendHeartbeat = () => {
|
|
1693
2020
|
const triggerUrl = describeSyncTrigger().resolved;
|
|
1694
2021
|
return fetcher(`${apiUrl}/clivly/sdk/heartbeat`, {
|
|
@@ -1887,7 +2214,7 @@ function createClivlySDK(config) {
|
|
|
1887
2214
|
});
|
|
1888
2215
|
const runScheduled = async (options) => {
|
|
1889
2216
|
await heartbeat();
|
|
1890
|
-
if (config.source) await runSync(options);
|
|
2217
|
+
if (config.source || config.introspector) await runSync(options);
|
|
1891
2218
|
};
|
|
1892
2219
|
const triggerRequestAllowed = async (req, rawBody) => {
|
|
1893
2220
|
const secret = config.syncTrigger?.secret;
|
|
@@ -1901,7 +2228,9 @@ function createClivlySDK(config) {
|
|
|
1901
2228
|
const parseTriggerBody = (rawBody) => {
|
|
1902
2229
|
if (!rawBody) return {};
|
|
1903
2230
|
try {
|
|
1904
|
-
|
|
2231
|
+
const parsed = JSON.parse(rawBody);
|
|
2232
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
2233
|
+
return parsed;
|
|
1905
2234
|
} catch {
|
|
1906
2235
|
return {};
|
|
1907
2236
|
}
|
|
@@ -1934,7 +2263,7 @@ function createClivlySDK(config) {
|
|
|
1934
2263
|
ok: false,
|
|
1935
2264
|
runId,
|
|
1936
2265
|
error: error instanceof Error ? error.message : String(error)
|
|
1937
|
-
},
|
|
2266
|
+
}, triggerErrorStatus(error));
|
|
1938
2267
|
}
|
|
1939
2268
|
};
|
|
1940
2269
|
const start = async () => {
|
|
@@ -1981,7 +2310,7 @@ function createClivlySDK(config) {
|
|
|
1981
2310
|
presenceClient = null;
|
|
1982
2311
|
console.warn("Clivly presence socket unavailable; using HTTP heartbeat", error);
|
|
1983
2312
|
}
|
|
1984
|
-
if (!timers.sync && config.source) {
|
|
2313
|
+
if (!timers.sync && (config.source || config.introspector)) {
|
|
1985
2314
|
timers.sync = setInterval(() => {
|
|
1986
2315
|
runSync().catch(() => {});
|
|
1987
2316
|
}, syncIntervalMs);
|
|
@@ -2015,6 +2344,7 @@ function createClivlySDK(config) {
|
|
|
2015
2344
|
ping,
|
|
2016
2345
|
doctor,
|
|
2017
2346
|
describeSyncTrigger,
|
|
2347
|
+
describeRemoteProjections,
|
|
2018
2348
|
runScheduled,
|
|
2019
2349
|
createClivlyHandler,
|
|
2020
2350
|
sync: runSync,
|
package/sdk.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_entity_config = require("./entity-config-
|
|
3
|
-
const require_sdk = require("./sdk-
|
|
2
|
+
const require_entity_config = require("./entity-config-DgAe0_YD.cjs");
|
|
3
|
+
const require_sdk = require("./sdk-B1vX4kUJ.cjs");
|
|
4
4
|
exports.ClivlyAuthError = require_sdk.ClivlyAuthError;
|
|
5
5
|
exports.ClivlyError = require_sdk.ClivlyError;
|
|
6
6
|
exports.ClivlyNetworkError = require_sdk.ClivlyNetworkError;
|
package/sdk.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as defineClivlyConfig, S as customObjectDeclarations, a as ClivlyEntitiesConfig, f as CustomObjectDeclaration, k as validateEntitiesConfig, l as ConfigValidationError, m as DiscoveredSchemaTable, u as ConfigValidationResult } from "./entity-config-
|
|
2
|
-
import { a as ClivlyConnectResult, c as ClivlyUser, d as DiscoveredTable, f as DoctorCheck, g as EnsuredObjectTypeResult, h as EnsuredMappingResult, i as ClivlyConnectReason, l as CreateChatSessionHandlerOptions, m as EnsureSchemaResult, n as ChatSessionRequestBody, o as ClivlySDK, p as DoctorReport, r as ChatWidgetVisitor, s as ClivlySDKConfig, u as CursorStore,
|
|
1
|
+
import { C as defineClivlyConfig, S as customObjectDeclarations, a as ClivlyEntitiesConfig, f as CustomObjectDeclaration, k as validateEntitiesConfig, l as ConfigValidationError, m as DiscoveredSchemaTable, u as ConfigValidationResult } from "./entity-config-DNQAMbMS.cjs";
|
|
2
|
+
import { _ as RemoteProjectionsDescription, a as ClivlyConnectResult, c as ClivlyUser, d as DiscoveredTable, f as DoctorCheck, g as EnsuredObjectTypeResult, h as EnsuredMappingResult, i as ClivlyConnectReason, l as CreateChatSessionHandlerOptions, m as EnsureSchemaResult, n as ChatSessionRequestBody, o as ClivlySDK, p as DoctorReport, r as ChatWidgetVisitor, s as ClivlySDKConfig, u as CursorStore, y as SyncTriggerDescription } from "./namespace-probe-DC4tbmLj.cjs";
|
|
3
3
|
//#region ../sdk/src/trigger-url.d.ts
|
|
4
4
|
declare function isPlaceholderUrl(value: string): boolean;
|
|
5
5
|
//#endregion
|
|
@@ -36,4 +36,4 @@ declare class ClivlyNetworkError extends ClivlyError {}
|
|
|
36
36
|
*/
|
|
37
37
|
declare function createClivlySDK(config: ClivlySDKConfig): ClivlySDK;
|
|
38
38
|
//#endregion
|
|
39
|
-
export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, type ClivlyEntitiesConfig, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type ConfigValidationError, type ConfigValidationResult, type CreateChatSessionHandlerOptions, type CursorStore, type CustomObjectDeclaration, type DiscoveredSchemaTable, type DiscoveredTable, type DoctorCheck, type DoctorReport, type EnsureSchemaResult, type EnsuredMappingResult, type EnsuredObjectTypeResult, type SyncTriggerDescription, createChatSessionHandler, createClivlySDK, customObjectDeclarations, defineClivlyConfig, isPlaceholderUrl, validateEntitiesConfig };
|
|
39
|
+
export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, type ClivlyEntitiesConfig, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type ConfigValidationError, type ConfigValidationResult, type CreateChatSessionHandlerOptions, type CursorStore, type CustomObjectDeclaration, type DiscoveredSchemaTable, type DiscoveredTable, type DoctorCheck, type DoctorReport, type EnsureSchemaResult, type EnsuredMappingResult, type EnsuredObjectTypeResult, type RemoteProjectionsDescription, type SyncTriggerDescription, createChatSessionHandler, createClivlySDK, customObjectDeclarations, defineClivlyConfig, isPlaceholderUrl, validateEntitiesConfig };
|
package/sdk.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as defineClivlyConfig, S as customObjectDeclarations, a as ClivlyEntitiesConfig, f as CustomObjectDeclaration, k as validateEntitiesConfig, l as ConfigValidationError, m as DiscoveredSchemaTable, u as ConfigValidationResult } from "./entity-config-
|
|
2
|
-
import { a as ClivlyConnectResult, c as ClivlyUser, d as DiscoveredTable, f as DoctorCheck, g as EnsuredObjectTypeResult, h as EnsuredMappingResult, i as ClivlyConnectReason, l as CreateChatSessionHandlerOptions, m as EnsureSchemaResult, n as ChatSessionRequestBody, o as ClivlySDK, p as DoctorReport, r as ChatWidgetVisitor, s as ClivlySDKConfig, u as CursorStore,
|
|
1
|
+
import { C as defineClivlyConfig, S as customObjectDeclarations, a as ClivlyEntitiesConfig, f as CustomObjectDeclaration, k as validateEntitiesConfig, l as ConfigValidationError, m as DiscoveredSchemaTable, u as ConfigValidationResult } from "./entity-config-DNQAMbMS.mjs";
|
|
2
|
+
import { _ as RemoteProjectionsDescription, a as ClivlyConnectResult, c as ClivlyUser, d as DiscoveredTable, f as DoctorCheck, g as EnsuredObjectTypeResult, h as EnsuredMappingResult, i as ClivlyConnectReason, l as CreateChatSessionHandlerOptions, m as EnsureSchemaResult, n as ChatSessionRequestBody, o as ClivlySDK, p as DoctorReport, r as ChatWidgetVisitor, s as ClivlySDKConfig, u as CursorStore, y as SyncTriggerDescription } from "./namespace-probe-9ScMDR0t.mjs";
|
|
3
3
|
//#region ../sdk/src/trigger-url.d.ts
|
|
4
4
|
declare function isPlaceholderUrl(value: string): boolean;
|
|
5
5
|
//#endregion
|
|
@@ -36,4 +36,4 @@ declare class ClivlyNetworkError extends ClivlyError {}
|
|
|
36
36
|
*/
|
|
37
37
|
declare function createClivlySDK(config: ClivlySDKConfig): ClivlySDK;
|
|
38
38
|
//#endregion
|
|
39
|
-
export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, type ClivlyEntitiesConfig, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type ConfigValidationError, type ConfigValidationResult, type CreateChatSessionHandlerOptions, type CursorStore, type CustomObjectDeclaration, type DiscoveredSchemaTable, type DiscoveredTable, type DoctorCheck, type DoctorReport, type EnsureSchemaResult, type EnsuredMappingResult, type EnsuredObjectTypeResult, type SyncTriggerDescription, createChatSessionHandler, createClivlySDK, customObjectDeclarations, defineClivlyConfig, isPlaceholderUrl, validateEntitiesConfig };
|
|
39
|
+
export { type ChatSessionRequestBody, type ChatWidgetVisitor, ClivlyAuthError, type ClivlyConnectReason, type ClivlyConnectResult, type ClivlyEntitiesConfig, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, type ClivlySDK, type ClivlySDKConfig, type ClivlyUser, type ConfigValidationError, type ConfigValidationResult, type CreateChatSessionHandlerOptions, type CursorStore, type CustomObjectDeclaration, type DiscoveredSchemaTable, type DiscoveredTable, type DoctorCheck, type DoctorReport, type EnsureSchemaResult, type EnsuredMappingResult, type EnsuredObjectTypeResult, type RemoteProjectionsDescription, type SyncTriggerDescription, createChatSessionHandler, createClivlySDK, customObjectDeclarations, defineClivlyConfig, isPlaceholderUrl, validateEntitiesConfig };
|
package/sdk.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { o as customObjectDeclarations, p as validateEntitiesConfig, s as defineClivlyConfig } from "./entity-config-
|
|
2
|
-
import { a as ClivlyRateLimitError, i as ClivlyNetworkError, n as ClivlyAuthError, o as createChatSessionHandler, r as ClivlyError, s as isPlaceholderUrl, t as createClivlySDK } from "./sdk-
|
|
1
|
+
import { o as customObjectDeclarations, p as validateEntitiesConfig, s as defineClivlyConfig } from "./entity-config-C4d3K9CP.mjs";
|
|
2
|
+
import { a as ClivlyRateLimitError, i as ClivlyNetworkError, n as ClivlyAuthError, o as createChatSessionHandler, r as ClivlyError, s as isPlaceholderUrl, t as createClivlySDK } from "./sdk-D6gX0TXS.mjs";
|
|
3
3
|
export { ClivlyAuthError, ClivlyError, ClivlyNetworkError, ClivlyRateLimitError, createChatSessionHandler, createClivlySDK, customObjectDeclarations, defineClivlyConfig, isPlaceholderUrl, validateEntitiesConfig };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ClivlyEntitiesConfig } from "./entity-config-
|
|
2
|
-
import { n as CompiledView, t as CompileOptions } from "./view-compiler-
|
|
1
|
+
import { a as ClivlyEntitiesConfig } from "./entity-config-DNQAMbMS.cjs";
|
|
2
|
+
import { n as CompiledView, t as CompileOptions } from "./view-compiler-D3zp9S3K.cjs";
|
|
3
3
|
//#region ../core/src/sync-engine.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Sync engine (Phase 3) — materializes the read-only entity views into Clivly's
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as ClivlyEntitiesConfig } from "./entity-config-
|
|
2
|
-
import { n as CompiledView, t as CompileOptions } from "./view-compiler-
|
|
1
|
+
import { a as ClivlyEntitiesConfig } from "./entity-config-DNQAMbMS.mjs";
|
|
2
|
+
import { n as CompiledView, t as CompileOptions } from "./view-compiler-TpzDTu7z.mjs";
|
|
3
3
|
//#region ../core/src/sync-engine.d.ts
|
|
4
4
|
/**
|
|
5
5
|
* Sync engine (Phase 3) — materializes the read-only entity views into Clivly's
|
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
//#region ../core/src/types.d.ts
|
|
2
2
|
type ContactStatus = "lead" | "active" | "customer" | "churned";
|
|
3
|
-
type DealStage =
|
|
3
|
+
type DealStage = string;
|
|
4
|
+
type StageType = "open" | "won" | "lost";
|
|
5
|
+
type PipelineKind = "standard" | "recurring";
|
|
6
|
+
type ValueInterval = "one_time" | "monthly" | "annual";
|
|
7
|
+
/** Named once so SQL predicates and UI fallbacks cannot drift apart. */
|
|
8
|
+
declare const OPEN_STAGE_TYPE: "open";
|
|
9
|
+
/** A closed deal is a historical fact: automation never reopens one. */
|
|
10
|
+
declare function isClosedStageType(type: StageType): boolean;
|
|
11
|
+
interface PipelineStageConfig {
|
|
12
|
+
color: string | null;
|
|
13
|
+
id: string;
|
|
14
|
+
key: DealStage;
|
|
15
|
+
label: string;
|
|
16
|
+
position: number;
|
|
17
|
+
type: StageType;
|
|
18
|
+
valueFixed: number | null;
|
|
19
|
+
}
|
|
20
|
+
interface PipelineConfig {
|
|
21
|
+
id: string;
|
|
22
|
+
isDefault: boolean;
|
|
23
|
+
kind: PipelineKind;
|
|
24
|
+
name: string;
|
|
25
|
+
slug: string;
|
|
26
|
+
sourceMappingId: string | null;
|
|
27
|
+
stages: PipelineStageConfig[];
|
|
28
|
+
}
|
|
4
29
|
type TaskStatus = "todo" | "in_progress" | "done" | "cancelled";
|
|
5
30
|
type TaskPriority = "low" | "medium" | "high";
|
|
6
31
|
type TaskEntityType = "contact" | "company" | "deal";
|
|
@@ -103,6 +128,7 @@ interface CreateDealInput {
|
|
|
103
128
|
contactId?: string;
|
|
104
129
|
name: string;
|
|
105
130
|
owner?: string;
|
|
131
|
+
pipelineId?: string;
|
|
106
132
|
stage?: DealStage;
|
|
107
133
|
value?: number;
|
|
108
134
|
}
|
|
@@ -156,4 +182,4 @@ interface TaskFilters {
|
|
|
156
182
|
status?: TaskStatus;
|
|
157
183
|
}
|
|
158
184
|
//#endregion
|
|
159
|
-
export {
|
|
185
|
+
export { ValueInterval as A, TaskEntityType as C, UpdateContactInput as D, TaskStatus as E, UpdateDealInput as O, Task as S, TaskPriority as T, PipelineConfig as _, ContactFilters as a, RecordSource as b, CreateCompanyInput as c, CreateTaskInput as d, CrmRole as f, OPEN_STAGE_TYPE as g, Note as h, Contact as i, isClosedStageType as j, UpdateTaskInput as k, CreateContactInput as l, DealStage as m, ActivityType as n, ContactStatus as o, Deal as p, Company as r, CreateActivityInput as s, Activity as t, CreateDealInput as u, PipelineKind as v, TaskFilters as w, StageType as x, PipelineStageConfig as y };
|
|
@@ -1,6 +1,31 @@
|
|
|
1
1
|
//#region ../core/src/types.d.ts
|
|
2
2
|
type ContactStatus = "lead" | "active" | "customer" | "churned";
|
|
3
|
-
type DealStage =
|
|
3
|
+
type DealStage = string;
|
|
4
|
+
type StageType = "open" | "won" | "lost";
|
|
5
|
+
type PipelineKind = "standard" | "recurring";
|
|
6
|
+
type ValueInterval = "one_time" | "monthly" | "annual";
|
|
7
|
+
/** Named once so SQL predicates and UI fallbacks cannot drift apart. */
|
|
8
|
+
declare const OPEN_STAGE_TYPE: "open";
|
|
9
|
+
/** A closed deal is a historical fact: automation never reopens one. */
|
|
10
|
+
declare function isClosedStageType(type: StageType): boolean;
|
|
11
|
+
interface PipelineStageConfig {
|
|
12
|
+
color: string | null;
|
|
13
|
+
id: string;
|
|
14
|
+
key: DealStage;
|
|
15
|
+
label: string;
|
|
16
|
+
position: number;
|
|
17
|
+
type: StageType;
|
|
18
|
+
valueFixed: number | null;
|
|
19
|
+
}
|
|
20
|
+
interface PipelineConfig {
|
|
21
|
+
id: string;
|
|
22
|
+
isDefault: boolean;
|
|
23
|
+
kind: PipelineKind;
|
|
24
|
+
name: string;
|
|
25
|
+
slug: string;
|
|
26
|
+
sourceMappingId: string | null;
|
|
27
|
+
stages: PipelineStageConfig[];
|
|
28
|
+
}
|
|
4
29
|
type TaskStatus = "todo" | "in_progress" | "done" | "cancelled";
|
|
5
30
|
type TaskPriority = "low" | "medium" | "high";
|
|
6
31
|
type TaskEntityType = "contact" | "company" | "deal";
|
|
@@ -103,6 +128,7 @@ interface CreateDealInput {
|
|
|
103
128
|
contactId?: string;
|
|
104
129
|
name: string;
|
|
105
130
|
owner?: string;
|
|
131
|
+
pipelineId?: string;
|
|
106
132
|
stage?: DealStage;
|
|
107
133
|
value?: number;
|
|
108
134
|
}
|
|
@@ -156,4 +182,4 @@ interface TaskFilters {
|
|
|
156
182
|
status?: TaskStatus;
|
|
157
183
|
}
|
|
158
184
|
//#endregion
|
|
159
|
-
export {
|
|
185
|
+
export { ValueInterval as A, TaskEntityType as C, UpdateContactInput as D, TaskStatus as E, UpdateDealInput as O, Task as S, TaskPriority as T, PipelineConfig as _, ContactFilters as a, RecordSource as b, CreateCompanyInput as c, CreateTaskInput as d, CrmRole as f, OPEN_STAGE_TYPE as g, Note as h, Contact as i, isClosedStageType as j, UpdateTaskInput as k, CreateContactInput as l, DealStage as m, ActivityType as n, ContactStatus as o, Deal as p, Company as r, CreateActivityInput as s, Activity as t, CreateDealInput as u, PipelineKind as v, TaskFilters as w, StageType as x, PipelineStageConfig as y };
|