@dashai/sdk 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ClientConfig, a as Client, T as TokenResolver } from './types-BLNQ1S1C.js';
2
- export { B as BaseInsert, b as BaseRow, c as BaseUpdate, D as Deps, F as FetchImpl, d as FileRef, e as FilterOps, f as FilterValue, L as ListOpts, P as Page, R as ReadOnlyTableClient, S as SlowQueryInfo, g as SortClause, h as SortDir, i as TableClient, W as Where } from './types-BLNQ1S1C.js';
1
+ import { C as ClientConfig, a as Client, T as TokenResolver } from './types-DXsbCVkb.js';
2
+ export { B as BaseInsert, b as BaseRow, c as BaseUpdate, d as DatahubClient, e as DatahubListResult, f as DatahubTableClient, D as Deps, F as FetchImpl, g as FileRef, h as FilterOps, i as FilterValue, L as ListOpts, P as Page, R as ReadOnlyTableClient, S as SlowQueryInfo, j as SortClause, k as SortDir, l as TableClient, W as Where } from './types-DXsbCVkb.js';
3
3
  export { C as ContractViolationError, a as DashwiseError, b as DashwiseErrorCode, D as DependencyContractError, F as ForbiddenError, J as JoinError, N as NetworkError, O as OperationNotAllowedByProviderError, P as ProviderTableMissingError, R as RowNotFoundError, T as TimeoutError, U as UnauthenticatedError, V as ValidationError, f as fromBackendEnvelope } from './errors-BV75u7b9.js';
4
4
 
5
5
  /**
@@ -51,33 +51,64 @@ declare function createClient(config: ClientConfig): Client;
51
51
  * `createDevClient()` — `createClient()`'s zero-config sibling for local dev.
52
52
  *
53
53
  * Resolves `baseUrl`, `installationId`, and `getToken` from a layered
54
- * config chain so a developer who has run `dashwise login` can do:
54
+ * config chain so a developer who has run `dashwise login` (and, for the
55
+ * full local-dev experience, `dashwise init`) can do:
55
56
  *
56
57
  * ```ts
57
58
  * import { createDevClient } from '@dashai/sdk';
58
- * const client = createDevClient(); // just works
59
+ * const client = createDevClient({ moduleSlug: 'my-tasks' });
59
60
  * ```
60
61
  *
61
- * …without having to copy a token from `~/.config/dashwise/auth.json`
62
- * into a `.env.local` file by hand. The flow this enables is the
63
- * end-to-end "spin up a module in 30 seconds" path that the CLI's
64
- * `dashwise dev` command surfaces.
62
+ * …without copying tokens or installation ids around. The flow this
63
+ * enables is the end-to-end "two-command bootstrap" the CLI's
64
+ * `dashwise login` + `dashwise init` pair targets.
65
65
  *
66
66
  * ## Resolution chain
67
67
  *
68
68
  * For each field, the first non-empty source wins:
69
69
  *
70
- * 1. Explicit `overrides` argument (per-call escape hatch)
71
- * 2. `process.env.DASHWISE_API_URL` / `DASHWISE_API_TOKEN` /
72
- * `DASHWISE_INSTALLATION_ID` (the existing env-var contract — still
73
- * the right thing for CI, Docker, prod-like setups)
70
+ * 1. Explicit `overrides` argument (per-call escape hatch).
71
+ * 2. Environment variables — `DASHWISE_API_URL` / `DASHWISE_API_TOKEN`
72
+ * / `DASHWISE_INSTALLATION_ID` / `DASHWISE_RUNTIME_TOKEN` (HH-CC-LDI-5).
73
+ * Standard for CI, Docker, prod-like setups; also the path
74
+ * `dashwise dev` uses to inject per-module credentials into the
75
+ * Next.js child process.
74
76
  * 3. The CLI's saved config at `$XDG_CONFIG_HOME/dashwise/auth.json`
75
- * (or platform default) — written by `dashwise login`
77
+ * (or platform default) — written by `dashwise login` (top-level
78
+ * `apiUrl` + `token`) and `dashwise init` (per-module entry under
79
+ * `modules[slug]`).
80
+ *
81
+ * ## Per-module local-dev tokens (HH-CC-LDI-5)
82
+ *
83
+ * When `overrides.moduleSlug` is set, the SDK looks up the per-module
84
+ * entry in `auth.json`:
85
+ *
86
+ * ```jsonc
87
+ * {
88
+ * "apiUrl": "http://localhost:3000",
89
+ * "token": "dwc_...", // CLI bearer (login)
90
+ * "modules": {
91
+ * "my-tasks": {
92
+ * "runtimeToken": "<JWT>", // long-lived runtime token (LDI-2)
93
+ * "installationId": 4242, // numeric install id (LDI-2)
94
+ * "expiresAt": "2026-08-22T..." // informational only
95
+ * }
96
+ * }
97
+ * }
98
+ * ```
99
+ *
100
+ * Per-module entries are written by `dashwise init` (HH-CC-LDI-6) when
101
+ * a developer provisions a local-dev install. The SDK prefers the
102
+ * `runtimeToken` over the legacy CLI bearer (`token`) when both
103
+ * exist, and sets `installationId` to the literal `'sandbox'` — the
104
+ * URL placeholder the backend's `RuntimeTokenGuard` accepts (the
105
+ * token resolves to the actual install on the server side).
76
106
  *
77
- * `installationId` falls back to the literal string `"local"` if none of
78
- * the above provide one matches the dev-mode contract the backend
79
- * accepts (a stub installation that resolves to whatever workspace the
80
- * token is scoped to).
107
+ * If `moduleSlug` is unset, OR the named module isn't in the
108
+ * `modules` map, OR the entry lacks a `runtimeToken`, the resolver
109
+ * falls back to the legacy chain (`token` field + `'local'` install
110
+ * id, which the backend will reject — surfacing as a typed
111
+ * `UnauthenticatedError` on the first request).
81
112
  *
82
113
  * ## Safety rails
83
114
  *
@@ -119,6 +150,28 @@ interface CreateDevClientOptions extends Partial<Omit<ClientConfig, 'getToken'>>
119
150
  * attachment (rare — only useful for hitting public endpoints).
120
151
  */
121
152
  getToken?: TokenResolver;
153
+ /**
154
+ * HH-CC-LDI-5 — module slug for per-module runtime-token lookup.
155
+ *
156
+ * When set, `createDevClient` reads
157
+ * `~/.config/dashwise/auth.json#modules[<moduleSlug>]` looking for
158
+ * a `runtimeToken`. If found, that token is used as the bearer
159
+ * (overriding `DASHWISE_API_TOKEN` / file-level `token`) and the
160
+ * SDK sends `installationId='sandbox'` — the URL placeholder
161
+ * accepted by the backend's `RuntimeTokenGuard`. The runtime
162
+ * token itself binds to a specific install on the server side.
163
+ *
164
+ * If `moduleSlug` is unset or the entry is missing, the legacy
165
+ * resolution chain applies (CLI bearer + `'local'` installation
166
+ * id, which the backend will 401 — surfacing as a typed
167
+ * `UnauthenticatedError` on the first request).
168
+ *
169
+ * Typical usage: scaffolded modules read `module.json#module.slug`
170
+ * and pass it here. The CLI's `dashwise dev` command also exports
171
+ * it as the `DASHWISE_RUNTIME_TOKEN` env var so child processes
172
+ * (e.g. `next dev`) can authenticate without re-reading the file.
173
+ */
174
+ moduleSlug?: string;
122
175
  }
123
176
  /**
124
177
  * Resolve config from env + saved CLI file + overrides, then hand off
package/dist/index.js CHANGED
@@ -343,7 +343,7 @@ function createHttp(config) {
343
343
  async function request(method, path, body) {
344
344
  const normalizedPath = `/${path.replace(LEADING_SLASH, "")}`;
345
345
  const url = normalizedPath.startsWith("/api/") ? `${config.baseUrl.replace(/\/+$/, "")}${normalizedPath}` : `${base}${normalizedPath}`;
346
- const token = config.getToken ? await config.getToken() : null;
346
+ const token = (config.getToken ? await config.getToken() : null) ?? config.apiKey ?? null;
347
347
  const headers = { ...staticHeaders };
348
348
  if (body !== void 0) {
349
349
  headers["Content-Type"] = "application/json";
@@ -527,6 +527,7 @@ function createClient(config) {
527
527
  deps(providerSlug) {
528
528
  return makeDeps(transport, providerSlug);
529
529
  },
530
+ datahub: makeDatahubClient(transport),
530
531
  request(method, path, body) {
531
532
  return transport.request(method, path, body);
532
533
  },
@@ -591,6 +592,50 @@ function assertValidTableSlug2(slug) {
591
592
  );
592
593
  }
593
594
  }
595
+ function makeDatahubClient(transport) {
596
+ return {
597
+ table(tableId) {
598
+ assertValidTableId(tableId);
599
+ const root = `/datahub/tables/${tableId}/rows`;
600
+ return {
601
+ async list(query) {
602
+ const qs = query ? new URLSearchParams(query).toString() : "";
603
+ const path = qs ? `${root}?${qs}` : root;
604
+ return transport.request("GET", path);
605
+ },
606
+ async get(rowId) {
607
+ return transport.request(
608
+ "GET",
609
+ `${root}/${rowId}`
610
+ );
611
+ },
612
+ async create(body) {
613
+ return transport.request("POST", root, body);
614
+ },
615
+ async update(rowId, body) {
616
+ return transport.request(
617
+ "PATCH",
618
+ `${root}/${rowId}`,
619
+ body
620
+ );
621
+ },
622
+ async delete(rowId) {
623
+ return transport.request(
624
+ "DELETE",
625
+ `${root}/${rowId}`
626
+ );
627
+ }
628
+ };
629
+ }
630
+ };
631
+ }
632
+ function assertValidTableId(tableId) {
633
+ if (!Number.isInteger(tableId) || tableId <= 0) {
634
+ throw new Error(
635
+ `@dashai/sdk: invalid Data Hub table id "${tableId}". Must be a positive integer.`
636
+ );
637
+ }
638
+ }
594
639
  function makeTableClient(transport, tableSlug) {
595
640
  const root = `/db/${tableSlug}`;
596
641
  return {
@@ -640,8 +685,10 @@ function createDevClient(overrides = {}) {
640
685
  "@dashai/sdk: createDevClient() could not resolve a baseUrl. Pass `{ baseUrl }` explicitly, set `DASHWISE_API_URL`, or run `dashwise login` to create the CLI config file."
641
686
  );
642
687
  }
643
- const installationId = overrides.installationId ?? readEnv("DASHWISE_INSTALLATION_ID") ?? "local";
644
- const snapshotToken = readEnv("DASHWISE_API_TOKEN") ?? fileConfig?.token ?? null;
688
+ const moduleEntry = overrides.moduleSlug ? fileConfig?.modules?.[overrides.moduleSlug] : void 0;
689
+ const runtimeToken = readEnv("DASHWISE_RUNTIME_TOKEN") ?? moduleEntry?.runtimeToken ?? null;
690
+ const installationId = overrides.installationId ?? readEnv("DASHWISE_INSTALLATION_ID") ?? (runtimeToken !== null ? "sandbox" : "local");
691
+ const snapshotToken = runtimeToken ?? readEnv("DASHWISE_API_KEY") ?? readEnv("DASHWISE_API_TOKEN") ?? fileConfig?.token ?? null;
645
692
  const resolvedGetToken = overrides.getToken ?? (() => snapshotToken);
646
693
  return createClient({
647
694
  ...overrides,
@@ -692,11 +739,14 @@ function resolveConfigDir(path, os) {
692
739
  function isPlausibleFileShape(v) {
693
740
  if (!v || typeof v !== "object") return false;
694
741
  const o = v;
695
- return (o.apiUrl === void 0 || typeof o.apiUrl === "string") && (o.token === void 0 || typeof o.token === "string");
742
+ const apiUrlOk = o.apiUrl === void 0 || typeof o.apiUrl === "string";
743
+ const tokenOk = o.token === void 0 || typeof o.token === "string";
744
+ const modulesOk = o.modules === void 0 || typeof o.modules === "object" && o.modules !== null;
745
+ return apiUrlOk && tokenOk && modulesOk;
696
746
  }
697
747
 
698
748
  // src/index.ts
699
- var VERSION = "0.7.0" ;
749
+ var VERSION = "0.9.0" ;
700
750
 
701
751
  export { ContractViolationError, DashwiseError, DashwiseErrorCode, DependencyContractError, ForbiddenError, JoinError, NetworkError, OperationNotAllowedByProviderError, ProviderTableMissingError, RowNotFoundError, TimeoutError, UnauthenticatedError, VERSION, ValidationError, createClient, createDevClient, fromBackendEnvelope };
702
752
  //# sourceMappingURL=index.js.map