@dashai/sdk 0.9.0 → 2.0.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 +53 -13
- package/dist/auth/client.cjs +23 -1
- package/dist/auth/client.cjs.map +1 -1
- package/dist/auth/client.d.cts +30 -5
- package/dist/auth/client.d.ts +30 -5
- package/dist/auth/client.js +23 -1
- package/dist/auth/client.js.map +1 -1
- package/dist/auth/middleware.cjs +11 -1
- package/dist/auth/middleware.cjs.map +1 -1
- package/dist/auth/middleware.js +11 -1
- package/dist/auth/middleware.js.map +1 -1
- package/dist/auth/server.cjs +36 -7
- package/dist/auth/server.cjs.map +1 -1
- package/dist/auth/server.js +36 -7
- package/dist/auth/server.js.map +1 -1
- package/dist/auth/types.cjs.map +1 -1
- package/dist/auth/types.d.cts +13 -0
- package/dist/auth/types.d.ts +13 -0
- package/dist/auth/types.js.map +1 -1
- package/dist/deps/index.cjs +82 -7
- package/dist/deps/index.cjs.map +1 -1
- package/dist/deps/index.d.cts +28 -10
- package/dist/deps/index.d.ts +28 -10
- package/dist/deps/index.js +81 -8
- package/dist/deps/index.js.map +1 -1
- package/dist/index-BsSFz58g.d.cts +431 -0
- package/dist/index-BsSFz58g.d.ts +431 -0
- package/dist/index.cjs +318 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +66 -53
- package/dist/index.d.ts +66 -53
- package/dist/index.js +313 -26
- package/dist/index.js.map +1 -1
- package/dist/query/index.cjs +158 -2
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +7 -7
- package/dist/query/index.d.ts +7 -7
- package/dist/query/index.js +158 -2
- package/dist/query/index.js.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/{types-DXsbCVkb.d.cts → types-CkAfiS4k.d.cts} +106 -38
- package/dist/{types-DXsbCVkb.d.ts → types-CkAfiS4k.d.ts} +106 -38
- package/dist/uses/index.cjs +147 -0
- package/dist/uses/index.cjs.map +1 -0
- package/dist/uses/index.d.cts +1 -0
- package/dist/uses/index.d.ts +1 -0
- package/dist/uses/index.js +142 -0
- package/dist/uses/index.js.map +1 -0
- package/package.json +6 -1
- package/dist/errors-BV75u7b9.d.cts +0 -207
- package/dist/errors-BV75u7b9.d.ts +0 -207
package/dist/index.cjs
CHANGED
|
@@ -34,23 +34,39 @@ function makeDeps(transport, providerSlug) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
function makeBorrowedTableClient(transport, providerSlug, tableSlug) {
|
|
37
|
-
const
|
|
37
|
+
const tablesRoot = `/deps/${providerSlug}/tables/${tableSlug}`;
|
|
38
38
|
return {
|
|
39
39
|
async list(opts) {
|
|
40
|
-
const
|
|
41
|
-
|
|
40
|
+
const ast = {
|
|
41
|
+
v: 1,
|
|
42
|
+
from: { kind: "dep", module: providerSlug, slug: tableSlug }
|
|
43
|
+
};
|
|
44
|
+
if (opts?.filter !== void 0) ast.where = opts.filter;
|
|
45
|
+
if (opts?.sort !== void 0 && opts.sort.length > 0) {
|
|
46
|
+
ast.orderBy = opts.sort;
|
|
47
|
+
}
|
|
48
|
+
if (typeof opts?.limit === "number") ast.limit = opts.limit;
|
|
49
|
+
if (typeof opts?.offset === "number") ast.offset = opts.offset;
|
|
50
|
+
const result = await transport.request("POST", "/query", { ast });
|
|
42
51
|
if (Array.isArray(result)) {
|
|
43
52
|
return {
|
|
44
53
|
rows: result,
|
|
45
54
|
total: result.length,
|
|
46
|
-
limit:
|
|
47
|
-
offset:
|
|
55
|
+
limit: opts?.limit ?? result.length,
|
|
56
|
+
offset: opts?.offset ?? 0
|
|
48
57
|
};
|
|
49
58
|
}
|
|
50
59
|
return result;
|
|
51
60
|
},
|
|
52
61
|
async get(id) {
|
|
53
|
-
|
|
62
|
+
const result = await transport.request(
|
|
63
|
+
"GET",
|
|
64
|
+
`${tablesRoot}/${id}`
|
|
65
|
+
);
|
|
66
|
+
if (result && typeof result === "object" && "row" in result) {
|
|
67
|
+
return result.row;
|
|
68
|
+
}
|
|
69
|
+
return result;
|
|
54
70
|
}
|
|
55
71
|
};
|
|
56
72
|
}
|
|
@@ -75,6 +91,44 @@ var DashwiseErrorCode = {
|
|
|
75
91
|
TABLE_NOT_IN_CONTRACT: "TABLE_NOT_IN_CONTRACT",
|
|
76
92
|
PROVIDER_TABLE_MISSING: "PROVIDER_TABLE_MISSING",
|
|
77
93
|
OPERATION_NOT_ALLOWED_BY_PROVIDER: "OPERATION_NOT_ALLOWED_BY_PROVIDER",
|
|
94
|
+
// Cross-module dependency PARK state (Phase 3 modules-platform-v2 —
|
|
95
|
+
// dependency connect/bind lifecycle). Surfaced at RUNTIME (409) when a
|
|
96
|
+
// module reads a borrowed table (`client.deps(slug)` / `qb.deps.<slug>`)
|
|
97
|
+
// or invokes a dep action whose `module_dependencies` row is currently
|
|
98
|
+
// `status='unbound'` — the dependency is declared but not connected to a
|
|
99
|
+
// provider installation (no provider in the workspace, version mismatch,
|
|
100
|
+
// manually unbound, provider uninstalled, etc.). The consumer app should
|
|
101
|
+
// render a "connect your provider" state rather than treating this as a
|
|
102
|
+
// hard failure. `err.context` carries `{ provider, range, reason }`.
|
|
103
|
+
DEP_UNBOUND: "DEP_UNBOUND",
|
|
104
|
+
// Workspace-table `uses` plane (Phase 4 modules-platform-v2 — the
|
|
105
|
+
// declared/portable path for a module to read+write a WORKSPACE table
|
|
106
|
+
// the workspace already owns, as opposed to `deps` = another module's
|
|
107
|
+
// tables). Surfaced at RUNTIME against `client.uses(slug)` /
|
|
108
|
+
// `qb.uses.<slug>` / the `POST /api/module-api/uses/:slug/...` REST
|
|
109
|
+
// plane. The BINDING is the grant on this plane (for sandbox AND
|
|
110
|
+
// api_key auth alike — a kind-local key does NOT bypass it):
|
|
111
|
+
// - USES_UNBOUND 409 — the `uses` slot is declared but its
|
|
112
|
+
// `module_table_bindings` row isn't `status='bound'` (never bound,
|
|
113
|
+
// ambiguous match, no match, table trashed, ops widened pending
|
|
114
|
+
// re-consent, manually unbound). `err.context` carries
|
|
115
|
+
// `{ uses_slug, reason }`. Recoverable: a workspace admin binds a
|
|
116
|
+
// table (`dashwise bind <uses_slug>`), then the read succeeds.
|
|
117
|
+
// - USES_OP_NOT_ALLOWED 403 — the operation isn't in the binding's
|
|
118
|
+
// enforcement set (manifest `ops` ∩ `consented_ops`). `err.context`
|
|
119
|
+
// carries `{ uses_slug, op }`. Fix: widen the manifest ops +
|
|
120
|
+
// re-consent (re-bind), or the admin re-binds to consent.
|
|
121
|
+
// - CONTRACT_FIELD_MISSING 409 — a field the binding maps no longer
|
|
122
|
+
// exists on the physical table (schema drift). `err.context`
|
|
123
|
+
// carries `{ uses_slug, field }`. The binding is best-effort parked
|
|
124
|
+
// on detection; an admin re-binds to a table that has the field.
|
|
125
|
+
USES_UNBOUND: "USES_UNBOUND",
|
|
126
|
+
USES_OP_NOT_ALLOWED: "USES_OP_NOT_ALLOWED",
|
|
127
|
+
CONTRACT_FIELD_MISSING: "CONTRACT_FIELD_MISSING",
|
|
128
|
+
// `uses`-plane query joins are NOT supported in v1 — a
|
|
129
|
+
// `qb.uses.<slug>.join(...)` / cross-plane join is rejected with a
|
|
130
|
+
// typed 400. (Joins WITH a uses table as a target are v2 territory.)
|
|
131
|
+
USES_JOIN_UNSUPPORTED: "USES_JOIN_UNSUPPORTED",
|
|
78
132
|
// Query-plane joins (Phase 3 — see
|
|
79
133
|
// dashwise-devops-docs/plans/modules-sdk-query-v1-p3-execution.md).
|
|
80
134
|
// Surfaced when `.join('<slug>')` / `.leftJoin('<slug>')` can't
|
|
@@ -87,8 +141,8 @@ var DashwiseErrorCode = {
|
|
|
87
141
|
// Cross-module actions (Phase 7 slice 7.3a — see
|
|
88
142
|
// dashwise-devops-docs/plans/modules-sdk-query-v1-p7-cross-module-writes.md).
|
|
89
143
|
// Surfaced when `qb.deps.<dep>.actions.<name>(input)` (generated
|
|
90
|
-
// factory) dispatches against the
|
|
91
|
-
// `POST
|
|
144
|
+
// factory) dispatches against the backend endpoint
|
|
145
|
+
// `POST /api/module-api/deps/:providerSlug/actions/:actionName`.
|
|
92
146
|
// Slice 7.2b ships the backend emitter; slice 7.3a (this slice)
|
|
93
147
|
// reserves the codes + maps them to DepActionError in the SDK.
|
|
94
148
|
ACTION_NOT_EXPOSED: "ACTION_NOT_EXPOSED",
|
|
@@ -214,6 +268,132 @@ var OperationNotAllowedByProviderError = class extends DashwiseError {
|
|
|
214
268
|
});
|
|
215
269
|
}
|
|
216
270
|
};
|
|
271
|
+
var DepUnboundReason = {
|
|
272
|
+
MISSING_DEPENDENCY: "MISSING_DEPENDENCY",
|
|
273
|
+
DEPENDENCY_VERSION_MISMATCH: "DEPENDENCY_VERSION_MISMATCH",
|
|
274
|
+
PROVIDER_VERSION_RECORD_MISSING: "PROVIDER_VERSION_RECORD_MISSING",
|
|
275
|
+
EXPOSES_MISSING: "EXPOSES_MISSING",
|
|
276
|
+
EXPOSES_PRIVATE: "EXPOSES_PRIVATE",
|
|
277
|
+
ACTION_NOT_EXPOSED: "ACTION_NOT_EXPOSED",
|
|
278
|
+
PROVIDER_NOT_PRODUCTION: "PROVIDER_NOT_PRODUCTION",
|
|
279
|
+
MANUALLY_UNBOUND: "MANUALLY_UNBOUND",
|
|
280
|
+
PROVIDER_UPGRADE_BROKE_CONTRACT: "PROVIDER_UPGRADE_BROKE_CONTRACT",
|
|
281
|
+
PROVIDER_UNINSTALLED: "PROVIDER_UNINSTALLED"
|
|
282
|
+
};
|
|
283
|
+
var DepUnboundError = class extends DashwiseError {
|
|
284
|
+
constructor(message, context, requestId = null) {
|
|
285
|
+
super(DashwiseErrorCode.DEP_UNBOUND, message, {
|
|
286
|
+
status: 409,
|
|
287
|
+
context,
|
|
288
|
+
requestId
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* The provider module slug the parked dependency points at (kebab-case,
|
|
293
|
+
* e.g. `crm`). Read from `context.provider`; `undefined` if the backend
|
|
294
|
+
* omitted it.
|
|
295
|
+
*/
|
|
296
|
+
get provider() {
|
|
297
|
+
const v = this.context?.provider;
|
|
298
|
+
return typeof v === "string" ? v : void 0;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* The SemVer range the consumer's manifest declared for this dependency
|
|
302
|
+
* (e.g. `^1.2.0`). Read from `context.range`; `undefined` if omitted.
|
|
303
|
+
*/
|
|
304
|
+
get range() {
|
|
305
|
+
const v = this.context?.range;
|
|
306
|
+
return typeof v === "string" ? v : void 0;
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Why the dependency is unbound — one of {@link DepUnboundReason} (but
|
|
310
|
+
* typed as `string` for forward-compat with reasons the backend may add).
|
|
311
|
+
* Read from `context.reason`; `undefined` if omitted.
|
|
312
|
+
*/
|
|
313
|
+
get reason() {
|
|
314
|
+
const v = this.context?.reason;
|
|
315
|
+
return typeof v === "string" ? v : void 0;
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
var UsesUnboundReason = {
|
|
319
|
+
NOT_BOUND_YET: "NOT_BOUND_YET",
|
|
320
|
+
AMBIGUOUS_MATCH: "AMBIGUOUS_MATCH",
|
|
321
|
+
NO_MATCH: "NO_MATCH",
|
|
322
|
+
TABLE_DELETED: "TABLE_DELETED",
|
|
323
|
+
OPS_WIDENED_PENDING_CONSENT: "OPS_WIDENED_PENDING_CONSENT",
|
|
324
|
+
MANUALLY_UNBOUND: "MANUALLY_UNBOUND"
|
|
325
|
+
};
|
|
326
|
+
var UsesUnboundError = class extends DashwiseError {
|
|
327
|
+
constructor(message, context, requestId = null) {
|
|
328
|
+
super(DashwiseErrorCode.USES_UNBOUND, message, {
|
|
329
|
+
status: 409,
|
|
330
|
+
context,
|
|
331
|
+
requestId
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* The manifest `uses[].tables[].slug` of the unbound slot (kebab-case,
|
|
336
|
+
* e.g. `employees`). Read from `context.uses_slug`; `undefined` if the
|
|
337
|
+
* backend omitted it.
|
|
338
|
+
*/
|
|
339
|
+
get usesSlug() {
|
|
340
|
+
const v = this.context?.uses_slug;
|
|
341
|
+
return typeof v === "string" ? v : void 0;
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Why the slot is unbound — one of {@link UsesUnboundReason} (typed as
|
|
345
|
+
* `string` for forward-compat with reasons the backend may add). Read
|
|
346
|
+
* from `context.reason`; `undefined` if omitted.
|
|
347
|
+
*/
|
|
348
|
+
get reason() {
|
|
349
|
+
const v = this.context?.reason;
|
|
350
|
+
return typeof v === "string" ? v : void 0;
|
|
351
|
+
}
|
|
352
|
+
};
|
|
353
|
+
var UsesOpNotAllowedError = class extends DashwiseError {
|
|
354
|
+
constructor(message, context, requestId = null) {
|
|
355
|
+
super(DashwiseErrorCode.USES_OP_NOT_ALLOWED, message, {
|
|
356
|
+
status: 403,
|
|
357
|
+
context,
|
|
358
|
+
requestId
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
/** The `uses` slot slug the rejected op targeted. Read from `context.uses_slug`. */
|
|
362
|
+
get usesSlug() {
|
|
363
|
+
const v = this.context?.uses_slug;
|
|
364
|
+
return typeof v === "string" ? v : void 0;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* The operation that was rejected — one of `create` / `read` /
|
|
368
|
+
* `update` / `delete`. Read from `context.op`; `undefined` if omitted.
|
|
369
|
+
*/
|
|
370
|
+
get op() {
|
|
371
|
+
const v = this.context?.op;
|
|
372
|
+
return typeof v === "string" ? v : void 0;
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
var ContractFieldMissingError = class extends DashwiseError {
|
|
376
|
+
constructor(message, context, requestId = null) {
|
|
377
|
+
super(DashwiseErrorCode.CONTRACT_FIELD_MISSING, message, {
|
|
378
|
+
status: 409,
|
|
379
|
+
context,
|
|
380
|
+
requestId
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
/** The `uses` slot slug whose contract broke. Read from `context.uses_slug`. */
|
|
384
|
+
get usesSlug() {
|
|
385
|
+
const v = this.context?.uses_slug;
|
|
386
|
+
return typeof v === "string" ? v : void 0;
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* The declared field slug (the `uses` side name) whose mapped physical
|
|
390
|
+
* field is gone. Read from `context.field`; `undefined` if omitted.
|
|
391
|
+
*/
|
|
392
|
+
get field() {
|
|
393
|
+
const v = this.context?.field;
|
|
394
|
+
return typeof v === "string" ? v : void 0;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
217
397
|
var JoinError = class extends DashwiseError {
|
|
218
398
|
constructor(code, message, context, requestId = null) {
|
|
219
399
|
super(code, message, { status: 400, context, requestId });
|
|
@@ -255,9 +435,21 @@ function fromBackendEnvelope(status, envelope, requestId = null) {
|
|
|
255
435
|
return new ProviderTableMissingError(message, context, requestId);
|
|
256
436
|
case DashwiseErrorCode.OPERATION_NOT_ALLOWED_BY_PROVIDER:
|
|
257
437
|
return new OperationNotAllowedByProviderError(message, context, requestId);
|
|
438
|
+
case DashwiseErrorCode.DEP_UNBOUND:
|
|
439
|
+
return new DepUnboundError(message, context, requestId);
|
|
440
|
+
case DashwiseErrorCode.USES_UNBOUND:
|
|
441
|
+
return new UsesUnboundError(message, context, requestId);
|
|
442
|
+
case DashwiseErrorCode.USES_OP_NOT_ALLOWED:
|
|
443
|
+
return new UsesOpNotAllowedError(message, context, requestId);
|
|
444
|
+
case DashwiseErrorCode.CONTRACT_FIELD_MISSING:
|
|
445
|
+
return new ContractFieldMissingError(message, context, requestId);
|
|
258
446
|
case DashwiseErrorCode.LINK_FIELD_NOT_FOUND:
|
|
259
447
|
case DashwiseErrorCode.NOT_A_LINK_FIELD:
|
|
260
448
|
case DashwiseErrorCode.JOIN_NOT_LINKED:
|
|
449
|
+
// `uses`-plane joins are unsupported in v1; the backend emits a 400
|
|
450
|
+
// with this code. Map to JoinError so it lands in the same
|
|
451
|
+
// "your join can't be resolved" family (code preserved for `err.code`).
|
|
452
|
+
case DashwiseErrorCode.USES_JOIN_UNSUPPORTED:
|
|
261
453
|
return new JoinError(code, message, context, requestId);
|
|
262
454
|
case DashwiseErrorCode.ACTION_NOT_EXPOSED:
|
|
263
455
|
case DashwiseErrorCode.ACTION_NOT_DECLARED:
|
|
@@ -292,12 +484,13 @@ var DEFAULT_TIMEOUT_MS = 3e4;
|
|
|
292
484
|
var DEFAULT_SLOW_QUERY_THRESHOLD_MS = 500;
|
|
293
485
|
var TRAILING_SLASH = /\/+$/;
|
|
294
486
|
var LEADING_SLASH = /^\/+/;
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
487
|
+
var MODULE_API_PREFIX = "/api/module-api";
|
|
488
|
+
function buildBaseUrl(apiUrl) {
|
|
489
|
+
if (!apiUrl) {
|
|
490
|
+
throw new Error("@dashai/sdk: `apiUrl` is required");
|
|
298
491
|
}
|
|
299
|
-
const trimmed =
|
|
300
|
-
return `${trimmed}
|
|
492
|
+
const trimmed = apiUrl.replace(TRAILING_SLASH, "");
|
|
493
|
+
return `${trimmed}${MODULE_API_PREFIX}`;
|
|
301
494
|
}
|
|
302
495
|
function resolveFetch(custom) {
|
|
303
496
|
if (custom) return custom;
|
|
@@ -325,7 +518,7 @@ async function readBody(res) {
|
|
|
325
518
|
}
|
|
326
519
|
}
|
|
327
520
|
function createHttp(config) {
|
|
328
|
-
const base = buildBaseUrl(config.
|
|
521
|
+
const base = buildBaseUrl(config.apiUrl ?? config.baseUrl);
|
|
329
522
|
const doFetch = resolveFetch(config.fetch);
|
|
330
523
|
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
331
524
|
const staticHeaders = {
|
|
@@ -344,7 +537,7 @@ function createHttp(config) {
|
|
|
344
537
|
}
|
|
345
538
|
async function request(method, path, body) {
|
|
346
539
|
const normalizedPath = `/${path.replace(LEADING_SLASH, "")}`;
|
|
347
|
-
const url =
|
|
540
|
+
const url = `${base}${normalizedPath}`;
|
|
348
541
|
const token = (config.getToken ? await config.getToken() : null) ?? config.apiKey ?? null;
|
|
349
542
|
const headers = { ...staticHeaders };
|
|
350
543
|
if (body !== void 0) {
|
|
@@ -539,9 +732,7 @@ function createClient(config) {
|
|
|
539
732
|
async _callAction(providerSlug, actionName, input, opts) {
|
|
540
733
|
assertValidModuleSlug(providerSlug);
|
|
541
734
|
assertValidActionName(actionName);
|
|
542
|
-
const path = `/
|
|
543
|
-
providerSlug
|
|
544
|
-
)}/actions/${encodeURIComponent(actionName)}`;
|
|
735
|
+
const path = `/deps/${encodeURIComponent(providerSlug)}/actions/${encodeURIComponent(actionName)}`;
|
|
545
736
|
const body = { input };
|
|
546
737
|
if (opts?.idempotencyKey !== void 0) {
|
|
547
738
|
body.idempotency_key = opts.idempotencyKey;
|
|
@@ -600,8 +791,12 @@ function makeDatahubClient(transport) {
|
|
|
600
791
|
assertValidTableId(tableId);
|
|
601
792
|
const root = `/datahub/tables/${tableId}/rows`;
|
|
602
793
|
return {
|
|
603
|
-
async list(
|
|
604
|
-
const
|
|
794
|
+
async list(opts) {
|
|
795
|
+
const arg = opts;
|
|
796
|
+
const flat = isDatahubListOpts(
|
|
797
|
+
arg
|
|
798
|
+
) ? compileDatahubListOpts(arg) : arg;
|
|
799
|
+
const qs = flat ? new URLSearchParams(flat).toString() : "";
|
|
605
800
|
const path = qs ? `${root}?${qs}` : root;
|
|
606
801
|
return transport.request("GET", path);
|
|
607
802
|
},
|
|
@@ -638,6 +833,100 @@ function assertValidTableId(tableId) {
|
|
|
638
833
|
);
|
|
639
834
|
}
|
|
640
835
|
}
|
|
836
|
+
var DATAHUB_LIST_OPT_KEYS = /* @__PURE__ */ new Set([
|
|
837
|
+
"filter",
|
|
838
|
+
"sort",
|
|
839
|
+
"search",
|
|
840
|
+
"limit",
|
|
841
|
+
"page"
|
|
842
|
+
]);
|
|
843
|
+
var FILTER_GROUP_KEYS = /* @__PURE__ */ new Set(["AND", "OR"]);
|
|
844
|
+
function isDatahubListOpts(opts) {
|
|
845
|
+
if (opts === void 0 || opts === null || typeof opts !== "object") {
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
848
|
+
return Object.keys(opts).some((k) => DATAHUB_LIST_OPT_KEYS.has(k));
|
|
849
|
+
}
|
|
850
|
+
function compileDatahubListOpts(opts) {
|
|
851
|
+
const out = {};
|
|
852
|
+
if (opts.filter !== void 0) {
|
|
853
|
+
const where = opts.filter;
|
|
854
|
+
if (hasFilterGrouping(where)) {
|
|
855
|
+
out.filters = JSON.stringify(whereToBackendTree(where));
|
|
856
|
+
} else {
|
|
857
|
+
for (const [field, value] of Object.entries(where)) {
|
|
858
|
+
if (value === void 0) continue;
|
|
859
|
+
if (isFilterOpsObject(value)) {
|
|
860
|
+
for (const [op, opValue] of Object.entries(value)) {
|
|
861
|
+
if (opValue === void 0) continue;
|
|
862
|
+
out[`filter__${field}__${op}`] = stringifyFilterValue(opValue);
|
|
863
|
+
}
|
|
864
|
+
} else {
|
|
865
|
+
out[`filter__${field}__equal`] = stringifyFilterValue(value);
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
if (opts.sort !== void 0 && opts.sort.length > 0) {
|
|
871
|
+
out.order_by = opts.sort.map(
|
|
872
|
+
(s) => s.dir === "desc" ? `-${s.field}` : s.field
|
|
873
|
+
).join(",");
|
|
874
|
+
}
|
|
875
|
+
if (opts.search !== void 0) out.search = opts.search;
|
|
876
|
+
if (typeof opts.limit === "number") out.size = String(opts.limit);
|
|
877
|
+
if (typeof opts.page === "number") out.page = String(opts.page);
|
|
878
|
+
if (opts.filter !== void 0 || opts.sort !== void 0 && opts.sort.length > 0) {
|
|
879
|
+
out.user_field_names = "true";
|
|
880
|
+
}
|
|
881
|
+
return out;
|
|
882
|
+
}
|
|
883
|
+
function hasFilterGrouping(where) {
|
|
884
|
+
return Object.keys(where).some((k) => FILTER_GROUP_KEYS.has(k));
|
|
885
|
+
}
|
|
886
|
+
function isFilterGroupNode(node) {
|
|
887
|
+
return Object.keys(node).some((k) => FILTER_GROUP_KEYS.has(k));
|
|
888
|
+
}
|
|
889
|
+
function fieldLeaves(node) {
|
|
890
|
+
const leaves = [];
|
|
891
|
+
for (const [field, value] of Object.entries(node)) {
|
|
892
|
+
if (FILTER_GROUP_KEYS.has(field) || value === void 0) continue;
|
|
893
|
+
if (isFilterOpsObject(value)) {
|
|
894
|
+
for (const [op, opValue] of Object.entries(value)) {
|
|
895
|
+
if (opValue === void 0) continue;
|
|
896
|
+
leaves.push({ field, type: op, value: stringifyFilterValue(opValue) });
|
|
897
|
+
}
|
|
898
|
+
} else {
|
|
899
|
+
leaves.push({ field, type: "equal", value: stringifyFilterValue(value) });
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return leaves;
|
|
903
|
+
}
|
|
904
|
+
function whereToBackendTree(where, defaultType = "AND") {
|
|
905
|
+
const obj = where;
|
|
906
|
+
const groupKey = Object.keys(obj).find((k) => FILTER_GROUP_KEYS.has(k));
|
|
907
|
+
if (groupKey) {
|
|
908
|
+
const children = obj[groupKey] ?? [];
|
|
909
|
+
const filters = [];
|
|
910
|
+
const filter_groups = [];
|
|
911
|
+
for (const child of children) {
|
|
912
|
+
const childObj = child;
|
|
913
|
+
if (isFilterGroupNode(childObj)) {
|
|
914
|
+
filter_groups.push(whereToBackendTree(child));
|
|
915
|
+
} else {
|
|
916
|
+
filters.push(...fieldLeaves(childObj));
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
return { filter_type: groupKey, filters, filter_groups };
|
|
920
|
+
}
|
|
921
|
+
return { filter_type: defaultType, filters: fieldLeaves(obj), filter_groups: [] };
|
|
922
|
+
}
|
|
923
|
+
function isFilterOpsObject(value) {
|
|
924
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
925
|
+
}
|
|
926
|
+
function stringifyFilterValue(value) {
|
|
927
|
+
if (value === null) return "";
|
|
928
|
+
return String(value);
|
|
929
|
+
}
|
|
641
930
|
function makeTableClient(transport, tableSlug) {
|
|
642
931
|
const root = `/db/${tableSlug}`;
|
|
643
932
|
return {
|
|
@@ -688,14 +977,12 @@ function createDevClient(overrides = {}) {
|
|
|
688
977
|
);
|
|
689
978
|
}
|
|
690
979
|
const moduleEntry = overrides.moduleSlug ? fileConfig?.modules?.[overrides.moduleSlug] : void 0;
|
|
691
|
-
const
|
|
692
|
-
const
|
|
693
|
-
const snapshotToken = runtimeToken ?? readEnv("DASHWISE_API_KEY") ?? readEnv("DASHWISE_API_TOKEN") ?? fileConfig?.token ?? null;
|
|
980
|
+
const devModuleToken = moduleEntry?.apiKey ?? moduleEntry?.runtimeToken ?? null;
|
|
981
|
+
const snapshotToken = devModuleToken ?? readEnv("DASHWISE_API_KEY") ?? fileConfig?.token ?? null;
|
|
694
982
|
const resolvedGetToken = overrides.getToken ?? (() => snapshotToken);
|
|
695
983
|
return createClient({
|
|
696
984
|
...overrides,
|
|
697
985
|
baseUrl,
|
|
698
|
-
installationId,
|
|
699
986
|
getToken: resolvedGetToken
|
|
700
987
|
});
|
|
701
988
|
}
|
|
@@ -748,11 +1035,14 @@ function isPlausibleFileShape(v) {
|
|
|
748
1035
|
}
|
|
749
1036
|
|
|
750
1037
|
// src/index.ts
|
|
751
|
-
var VERSION = "0.
|
|
1038
|
+
var VERSION = "2.0.0" ;
|
|
752
1039
|
|
|
1040
|
+
exports.ContractFieldMissingError = ContractFieldMissingError;
|
|
753
1041
|
exports.ContractViolationError = ContractViolationError;
|
|
754
1042
|
exports.DashwiseError = DashwiseError;
|
|
755
1043
|
exports.DashwiseErrorCode = DashwiseErrorCode;
|
|
1044
|
+
exports.DepUnboundError = DepUnboundError;
|
|
1045
|
+
exports.DepUnboundReason = DepUnboundReason;
|
|
756
1046
|
exports.DependencyContractError = DependencyContractError;
|
|
757
1047
|
exports.ForbiddenError = ForbiddenError;
|
|
758
1048
|
exports.JoinError = JoinError;
|
|
@@ -762,6 +1052,9 @@ exports.ProviderTableMissingError = ProviderTableMissingError;
|
|
|
762
1052
|
exports.RowNotFoundError = RowNotFoundError;
|
|
763
1053
|
exports.TimeoutError = TimeoutError;
|
|
764
1054
|
exports.UnauthenticatedError = UnauthenticatedError;
|
|
1055
|
+
exports.UsesOpNotAllowedError = UsesOpNotAllowedError;
|
|
1056
|
+
exports.UsesUnboundError = UsesUnboundError;
|
|
1057
|
+
exports.UsesUnboundReason = UsesUnboundReason;
|
|
765
1058
|
exports.VERSION = VERSION;
|
|
766
1059
|
exports.ValidationError = ValidationError;
|
|
767
1060
|
exports.createClient = createClient;
|