@terrascale/sdk 0.0.1 → 0.0.3

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +46 -17
  3. package/package.json +5 -2
  4. package/sdk-v1-route-manifest.json +7593 -1175
  5. package/src/database-codec.js +21 -26
  6. package/src/database-types.js +11 -11
  7. package/src/database-view.js +6 -6
  8. package/src/http.js +26 -5
  9. package/src/ids.js +22 -0
  10. package/src/index.js +2 -1
  11. package/src/local/better-auth.js +17 -6
  12. package/src/local/index.js +2 -2
  13. package/src/local/legacy-client.js +5 -5
  14. package/src/local/router.js +12 -12
  15. package/src/local/store.js +29 -28
  16. package/src/local/test-environment.js +3 -2
  17. package/src/postgres.js +5 -4
  18. package/src/react/core.js +2 -2
  19. package/src/ts-auth-discovery.js +17 -0
  20. package/src/ts-auth-ids.js +122 -0
  21. package/src/ts-auth.js +75 -72
  22. package/src/v1/decode.js +30 -10
  23. package/src/v1/ids.js +10 -62
  24. package/src/v1/routes.js +5 -5
  25. package/src/v1/shapes.js +6 -7
  26. package/src/v1/terrabase-v1.js +24 -16
  27. package/src/v1/transport.js +6 -4
  28. package/types/database-codec.d.ts +1 -6
  29. package/types/database-types.d.ts +11 -11
  30. package/types/http.d.ts +1 -0
  31. package/types/ids.d.ts +10 -0
  32. package/types/index.d.ts +2 -1
  33. package/types/local/store.d.ts +10 -0
  34. package/types/local/test-environment.d.ts +2 -2
  35. package/types/postgres.d.ts +4 -4
  36. package/types/ts-auth-discovery.d.ts +8 -0
  37. package/types/ts-auth-ids.d.ts +14 -0
  38. package/types/ts-auth.d.ts +99 -99
  39. package/types/v1/decode.d.ts +27 -11
  40. package/types/v1/ids.d.ts +5 -17
  41. package/types/v1/shapes.d.ts +2 -2
  42. package/types/v1/terrabase-v1.d.ts +3 -3
  43. package/types/v1/transport.d.ts +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased — TS-754
4
+
5
+ Entity IDs are plain uppercase Crockford ULIDs. `generateId()` uses the maintained
6
+ `ulid` library with monotonic generation; `isValidId()` and `requireId()` validate
7
+ the canonical 26-character, 128-bit form. UUIDs, prefixes, lowercase and legacy
8
+ keys fail validation. Project IDs, document requests/responses, snapshot keys,
9
+ hosted identity DTOs and explicit development storage use this contract.
10
+
11
+ The document key is the entity ID; document JSON and patches cannot duplicate it
12
+ in a top-level `id` field. The deterministic UUIDv5 `documentIdFor` helper is
13
+ removed. Store natural keys in indexed fields. Local Better Auth generates ULIDs
14
+ and stores the ID only in the record key, reconstructing its adapter view on read.
15
+
16
+ This is a greenfield cutover: there is no migration, ID rewrite, compatibility
17
+ shim or legacy fallback. Service owners wipe their verified affected stores and
18
+ recreate bootstrap state; this stateless SDK has no production data to delete.
19
+ Release qualification requires the matching immutable C# ULID producer release.
20
+
21
+ ## Unreleased — TS-592
22
+
23
+ The project-scoped data client accepts a ts-auth access JWT as `token`, while
24
+ retaining legacy C# `tb_` keys for the existing producer release. Header injection
25
+ and malformed credentials fail before I/O. TS-589 keeps data paths unchanged;
26
+ Management and Admin remain closed and make no retired route calls.
27
+ JWT producer qualification awaits the server implementation of `docs/api.md`.
28
+
29
+ ## 0.0.2 — TS-650
30
+
31
+ TerraBase version tokens are opaque: `tbv1-<32 hex>` and the coming `tbv2-…`
32
+ format are both accepted (any 1-256 visible ASCII characters without quotes, so
33
+ they stay safe in `If-Match`). Responses with new members no longer throw:
34
+ `durability` passes through any label, and documents pass through any `state`,
35
+ including a causal read's `"conflict"` with its `siblings` (the LWW winner stays
36
+ in `document`). Conditional writes and error handling are unchanged.
37
+
3
38
  ## 0.0.1 — TS-498
4
39
 
5
40
  The package moves from the unscoped `terrascale` npm name, which the owner has
package/README.md CHANGED
@@ -11,17 +11,17 @@ npm install @terrascale/sdk
11
11
  ```
12
12
 
13
13
  ```js
14
- import { createTerraBaseV1Client, documentIdFor, v1Filter } from "@terrascale/sdk";
14
+ import { createTerraBaseV1Client, generateId, v1Filter } from "@terrascale/sdk";
15
15
 
16
16
  const client = createTerraBaseV1Client({
17
17
  project: process.env.TERRABASE_PROJECT,
18
- token: process.env.TERRABASE_API_KEY,
18
+ token: process.env.TERRABASE_ACCESS_TOKEN,
19
19
  baseUrl: process.env.TERRABASE_BASE_URL,
20
20
  });
21
21
  const db = client.database("app");
22
22
  const todos = db.collection("todos");
23
23
 
24
- const id = await documentIdFor("todos", "first-task");
24
+ const id = generateId();
25
25
  await todos.put(id, { title: "Use TerraBase", done: false }, { ifNoneMatchAny: true });
26
26
  const doc = await todos.get(id);
27
27
  await todos.patch(id, { merge: { done: true } }, { ifMatch: doc.version });
@@ -32,10 +32,14 @@ for await (const page of todos.pages({ filter: v1Filter.eq("/done", true), limit
32
32
  ```
33
33
 
34
34
  Provision the project, database and collection before using their handles.
35
- API keys begin with `tb_` and travel as `Authorization: Bearer <key>`.
35
+ The pinned producer still requires a C# `tb_` key as `token`. The example also
36
+ accepts a ts-auth project access JWT for the published TS-589 target, whose
37
+ server implementation remains pending. Credentials travel as
38
+ `Authorization: Bearer <token>` and are held privately. The SDK validates
39
+ header-safe syntax; authentication and authorization belong to the producer.
36
40
  Reads and queries require `documents:read`; writes and transactions require
37
41
  `documents:write`. Transaction assertions additionally require `documents:read`.
38
- Keep keys private and out of logs and browser bundles. `createTerraBaseClient`
42
+ Keep service credentials private and out of logs and browser bundles. `createTerraBaseClient`
39
43
  is an alias of `createTerraBaseV1Client`; it no longer accepts tenant/shard options.
40
44
 
41
45
  ## Atlas and endpoint selection
@@ -54,7 +58,7 @@ import { createTerraBaseV1Client, staticBaseUrlResolver } from "@terrascale/sdk"
54
58
 
55
59
  const client = createTerraBaseV1Client({
56
60
  project: process.env.TERRABASE_PROJECT,
57
- token: process.env.TERRABASE_API_KEY,
61
+ token: process.env.TERRABASE_ACCESS_TOKEN,
58
62
  endpointResolver: staticBaseUrlResolver(process.env.TERRABASE_BASE_URL),
59
63
  });
60
64
  const db = client.database("app");
@@ -67,6 +71,19 @@ to TS-507; this release requires an explicit URL or caller-supplied resolver.
67
71
 
68
72
  ## Documents, queries, transactions and shapes
69
73
 
74
+ The published TS-589 route table (`terrabase/docs/api.md`) keeps these data
75
+ paths unchanged. Management moves to project-scoped paths using database names;
76
+ this SDK's Management and Admin entrypoints still make no HTTP calls.
77
+ Database creation belongs to Management (`POST /v1/projects/{project}/databases`)
78
+ in that target contract.
79
+
80
+ The current immutable producer release implements the renamed `TerraBase`
81
+ assembly, but still authenticates data calls with `tb_` keys and exposes the old
82
+ Management routes. Its real-release integration harness uses those existing
83
+ bootstrap operations. JWT server compatibility and the new Management routes
84
+ remain unqualified until the producer publishes their implementation; accepting
85
+ a JWT in SDK configuration does not establish server compatibility.
86
+
70
87
  The C# producer owns these routes:
71
88
 
72
89
  | Operation | Method and path |
@@ -77,9 +94,15 @@ The C# producer owns these routes:
77
94
  | Shape | `GET /v1/projects/{project}/databases/{db}/collections/{c}/shape` |
78
95
 
79
96
  Collection methods are `get`, `put`, `create`, `patch`, `delete`, `query`,
80
- `pages` and `items`. New document IDs are canonical UUIDs; `documentIdFor`
81
- generates a stable UUIDv5 from a natural key. Documents return
82
- `{ id, version, state: "value", document }`. Writes return the version and a
97
+ `pages` and `items`. Every entity ID is a plain 26-character Crockford ULID,
98
+ canonical uppercase, without a prefix. `generateId()` uses the maintained
99
+ `ulid` library and increases monotonically within a millisecond. `isValidId`
100
+ checks IDs; `requireId` throws for invalid IDs. UUIDs and legacy IDs are rejected.
101
+ The document key is the entity ID: keep it out of the JSON payload. Natural
102
+ keys belong in indexed document fields, not deterministic UUID IDs. Documents return
103
+ `{ id, version, state: "value", document }`; a causal read can answer
104
+ `state: "conflict"` with `siblings`, and unknown states pass through. Versions
105
+ (`tbv1-…`, `tbv2-…`) are opaque tokens. Writes return the version and a
83
106
  decimal-string commit `offset`; preserve those opaque positions and use
84
107
  `ifMatch` or `ifNoneMatchAny` for conditional writes.
85
108
 
@@ -138,14 +161,13 @@ Never commit keys, cookies, environment files or real tenant data.
138
161
 
139
162
  The immutable release pin is
140
163
  [`scripts/ci/terrabase-release.json`](scripts/ci/terrabase-release.json): C#
141
- TerraBase 0.1.0, release `ci-0248ad3ac6fb82ac900e38005840a619e5d0beac-run-13267`,
164
+ TerraBase 0.1.0, release `ci-6cb97456b9b52a92a61856601cc025c4f2833518-run-16729`,
142
165
  with binary SHA-256
143
- `8abcedaa6b8487f08ecafe4485862f1f9309154e58ac1a74eda2278b78500968`.
144
- This official release is currently a draft: the producer's fast checks failed
145
- and publication was skipped (terrabase #110). The SDK integration harness may
146
- consume its official asset read-only when the version, source revision, size and
147
- SHA-256 are verified; publication is not required. Draft status does not establish
148
- that the producer's source qualification passed.
166
+ `cc2db35b18c385c6d58036c6c94e59460b0e12b0d5616da2222713efbe666700`.
167
+ This official prerelease contains the qualified TS-754 ULID producer, the renamed
168
+ `TerraBase` assembly and `src/TerraBase` sources. Its asset name remains `terrabase-linux-amd64`.
169
+ The SDK integration harness consumes its official asset read-only when the
170
+ version, source revision, size and SHA-256 are verified.
149
171
  The acquisition script verifies the official release, revision, asset size and
150
172
  digest. Private downloads require `FORGEJO_TOKEN`. Missing or mismatched official
151
173
  assets block qualification rather than selecting older bytes.
@@ -185,11 +207,18 @@ See [CHANGELOG.md](CHANGELOG.md) for the 0.0.1 migration and breaking changes.
185
207
  client, with its own origin, instance and credentials. Management,
186
208
  administration and production Better Auth capabilities remain subject to their
187
209
  explicit admission errors; they are not a shortcut into the database transport.
210
+ Webhook dead-letter replay uses the documented `endpointId:eventId` delivery
211
+ selector; both references must be canonical ULIDs. Entity pages reject null and
212
+ primitive records; recovery-code pages contain strings.
188
213
 
189
214
  `@terrascale/sdk/local` (including `terrascale-local`) and `@terrascale/sdk/postgres` are
190
215
  **deprecated legacy entrypoints**. SQLite stays opt-in for development only and
191
216
  refuses CI, production, staging, qualification and deployment environments.
192
217
  It is no longer the required Dashboard backend and does not qualify the C# API.
218
+ Local SQLite uses fresh format 2. Older stores are refused before records are
219
+ read: stop the runtime, delete the exact configured `databasePath` and its
220
+ `-wal`/`-shm` files, then restart. Startup recreates bootstrap state; old auth
221
+ records and references are discarded together. There is no migration.
193
222
  The PostgreSQL listener and retired tenant/shard client are outside the default
194
223
  v1 API. Existing framework, schema and SQL entrypoints are separate legacy
195
224
  surfaces; the root entrypoint exposes the C# v1 client API.
@@ -198,4 +227,4 @@ Hosted OAuth resource requests use one exact registered HTTPS `resource`. `oidc.
198
227
 
199
228
  `oauthClients` and `oauthResources` provide the producer's snake_case policy records and named management operations. Resource PATCH requires `expected_auth_epoch`; client PATCH accepts it. JSON epochs outside JavaScript's exact integer range are rejected. Client PATCH returns a bare client view unless `rotate_secret` is true, when it returns the client and its one-time secret. Resource create/PATCH always return the resource and nullable one-time introspection secret.
200
229
 
201
- Use `oidc.introspectResource` with independently configured `issuer`, exact `audience`, `introspection_client_id`, and `introspection_secret`. It uses resource Basic authentication only, with each credential component form encoded before Base64. An active result requires the exact configured issuer/audience, `Bearer`, integer timestamps valid at the local clock with no default skew, and the required user/service session shape. Inactive results contain only `active: false`. Resource results expose no internal epochs, refresh family, or token-use fields. The provider checks current durable token/session/resource state; an active principal or scope does not grant project ownership or management authority. Product authorization remains at the caller's existing authorization boundary.
230
+ Use `oidc.introspectResource` with independently configured `issuer`, exact `audience`, `introspection_client_id`, and `introspection_secret`. It uses resource Basic authentication only, with each credential component form encoded before Base64. An active result requires the exact configured issuer/audience, `Bearer`, integer timestamps valid at the local clock with no default skew, and the required user/service session shape. Inactive results contain only `active: false`. Resource results expose no internal epochs, refresh family, or token-use fields. The provider checks current durable token/session/resource state; an active principal or scope does not grant project ownership or management authority. Product authorization remains at the caller's existing authorization boundary. Behind the Atlas proxy `apiBaseUrl` `https://auth.terrascale.tech`, ts-auth's issuer is regional, `https://<region>.auth.terrascale.tech/<slug>` (for example `https://gru.auth.terrascale.tech/<slug>`); configure that issuer, not the proxy host. Resource introspection then calls the issuer's regional host directly, because Atlas could rank another region, which is another issuer; `useReverseProxy` keeps it on the proxy.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@terrascale/sdk",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "JavaScript SDK, typed with JSDoc, for project-scoped C# TerraBase v1 and hosted TerraScale identity.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -150,5 +150,8 @@
150
150
  "last 1 Edge major version"
151
151
  ]
152
152
  },
153
- "packageManager": "npm@11.18.0"
153
+ "packageManager": "npm@11.18.0",
154
+ "dependencies": {
155
+ "ulid": "3.0.2"
156
+ }
154
157
  }