@clivly/sdk 0.9.7 → 0.10.1
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 +1 -1
- package/dist/index.cjs +23 -3
- package/dist/index.mjs +23 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -460,7 +460,7 @@ is honoured. Other `4xx` responses return immediately.
|
|
|
460
460
|
| `retry.maxAttempts` / `retry.baseDelayMs` | `number` | `3` / `500` | |
|
|
461
461
|
| `syncTrigger.path` / `.url` / `.secret` | `string` | — | See above |
|
|
462
462
|
| `verifyToken` | `string` | — | For `createAuthVerifyHandler`. **Nothing calls that endpoint today** |
|
|
463
|
-
| `introspector` | `NamespaceIntrospector` | — | `drizzleIntrospector(db)`. Used
|
|
463
|
+
| `introspector` | `NamespaceIntrospector` | — | `drizzleIntrospector(db)`. Used by `doctor()`, derived-object previews, and dashboard-authored derived-object sync |
|
|
464
464
|
| `namespaceReady` | `boolean` | `false` | Self-reported; no live check |
|
|
465
465
|
| `env` | `Record<string, string \| undefined>` | `process.env` | For trigger-URL discovery in non-Node runtimes |
|
|
466
466
|
| `framework` / `orm` / `sdkVersion` | `string` | — | Reported for dashboard display |
|
package/dist/index.cjs
CHANGED
|
@@ -1559,6 +1559,24 @@ function timingSafeEqual(a, b) {
|
|
|
1559
1559
|
}
|
|
1560
1560
|
const RUN_ID_HEADER = "x-clivly-run-id";
|
|
1561
1561
|
const SIGNATURE_HEADER = "x-clivly-signature";
|
|
1562
|
+
/**
|
|
1563
|
+
* An error the mounted trigger route should answer with a specific HTTP
|
|
1564
|
+
* status, rather than the generic 500 it uses for a genuinely unhandled
|
|
1565
|
+
* error. A fail-safe rejection (e.g. an unresolvable sample `entityKey`) is a
|
|
1566
|
+
* configuration mismatch the caller can fix — surfacing it as "your app
|
|
1567
|
+
* crashed" sends a developer hunting through their own sync handler instead.
|
|
1568
|
+
*/
|
|
1569
|
+
var TriggerRequestError = class extends Error {
|
|
1570
|
+
status;
|
|
1571
|
+
constructor(status, message) {
|
|
1572
|
+
super(message);
|
|
1573
|
+
this.name = new.target.name;
|
|
1574
|
+
this.status = status;
|
|
1575
|
+
}
|
|
1576
|
+
};
|
|
1577
|
+
function triggerErrorStatus(error) {
|
|
1578
|
+
return error instanceof TriggerRequestError ? error.status : 500;
|
|
1579
|
+
}
|
|
1562
1580
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
1563
1581
|
const SIGNATURE_HEADER_RE = /^t=(\d+),v1=([0-9a-f]+)$/;
|
|
1564
1582
|
const SECONDS_PER_MS = 1e3;
|
|
@@ -1884,7 +1902,7 @@ function createClivlySDK(config) {
|
|
|
1884
1902
|
};
|
|
1885
1903
|
const runSampleSync = async (entityKey, runId) => {
|
|
1886
1904
|
const resolved = resolveSampleSource(config, entityKey);
|
|
1887
|
-
if (!resolved) throw new
|
|
1905
|
+
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.`);
|
|
1888
1906
|
lastPushFailure = null;
|
|
1889
1907
|
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]));
|
|
1890
1908
|
};
|
|
@@ -2123,7 +2141,9 @@ function createClivlySDK(config) {
|
|
|
2123
2141
|
const parseTriggerBody = (rawBody) => {
|
|
2124
2142
|
if (!rawBody) return {};
|
|
2125
2143
|
try {
|
|
2126
|
-
|
|
2144
|
+
const parsed = JSON.parse(rawBody);
|
|
2145
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
2146
|
+
return parsed;
|
|
2127
2147
|
} catch {
|
|
2128
2148
|
return {};
|
|
2129
2149
|
}
|
|
@@ -2156,7 +2176,7 @@ function createClivlySDK(config) {
|
|
|
2156
2176
|
ok: false,
|
|
2157
2177
|
runId,
|
|
2158
2178
|
error: error instanceof Error ? error.message : String(error)
|
|
2159
|
-
},
|
|
2179
|
+
}, triggerErrorStatus(error));
|
|
2160
2180
|
}
|
|
2161
2181
|
};
|
|
2162
2182
|
const start = async () => {
|
package/dist/index.mjs
CHANGED
|
@@ -1558,6 +1558,24 @@ function timingSafeEqual(a, b) {
|
|
|
1558
1558
|
}
|
|
1559
1559
|
const RUN_ID_HEADER = "x-clivly-run-id";
|
|
1560
1560
|
const SIGNATURE_HEADER = "x-clivly-signature";
|
|
1561
|
+
/**
|
|
1562
|
+
* An error the mounted trigger route should answer with a specific HTTP
|
|
1563
|
+
* status, rather than the generic 500 it uses for a genuinely unhandled
|
|
1564
|
+
* error. A fail-safe rejection (e.g. an unresolvable sample `entityKey`) is a
|
|
1565
|
+
* configuration mismatch the caller can fix — surfacing it as "your app
|
|
1566
|
+
* crashed" sends a developer hunting through their own sync handler instead.
|
|
1567
|
+
*/
|
|
1568
|
+
var TriggerRequestError = class extends Error {
|
|
1569
|
+
status;
|
|
1570
|
+
constructor(status, message) {
|
|
1571
|
+
super(message);
|
|
1572
|
+
this.name = new.target.name;
|
|
1573
|
+
this.status = status;
|
|
1574
|
+
}
|
|
1575
|
+
};
|
|
1576
|
+
function triggerErrorStatus(error) {
|
|
1577
|
+
return error instanceof TriggerRequestError ? error.status : 500;
|
|
1578
|
+
}
|
|
1561
1579
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
1562
1580
|
const SIGNATURE_HEADER_RE = /^t=(\d+),v1=([0-9a-f]+)$/;
|
|
1563
1581
|
const SECONDS_PER_MS = 1e3;
|
|
@@ -1883,7 +1901,7 @@ function createClivlySDK(config) {
|
|
|
1883
1901
|
};
|
|
1884
1902
|
const runSampleSync = async (entityKey, runId) => {
|
|
1885
1903
|
const resolved = resolveSampleSource(config, entityKey);
|
|
1886
|
-
if (!resolved) throw new
|
|
1904
|
+
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.`);
|
|
1887
1905
|
lastPushFailure = null;
|
|
1888
1906
|
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]));
|
|
1889
1907
|
};
|
|
@@ -2122,7 +2140,9 @@ function createClivlySDK(config) {
|
|
|
2122
2140
|
const parseTriggerBody = (rawBody) => {
|
|
2123
2141
|
if (!rawBody) return {};
|
|
2124
2142
|
try {
|
|
2125
|
-
|
|
2143
|
+
const parsed = JSON.parse(rawBody);
|
|
2144
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) return {};
|
|
2145
|
+
return parsed;
|
|
2126
2146
|
} catch {
|
|
2127
2147
|
return {};
|
|
2128
2148
|
}
|
|
@@ -2155,7 +2175,7 @@ function createClivlySDK(config) {
|
|
|
2155
2175
|
ok: false,
|
|
2156
2176
|
runId,
|
|
2157
2177
|
error: error instanceof Error ? error.message : String(error)
|
|
2158
|
-
},
|
|
2178
|
+
}, triggerErrorStatus(error));
|
|
2159
2179
|
}
|
|
2160
2180
|
};
|
|
2161
2181
|
const start = async () => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clivly/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Clivly SDK — connect your app to Clivly Cloud (heartbeat, discovery, auth bridge).",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"access": "public"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
|
-
"@clivly/core": "0.
|
|
58
|
+
"@clivly/core": "0.10.1"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"drizzle-orm": ">=0.30 || >=1.0.0-rc.0",
|