@terrascale/sdk 0.0.2 → 0.0.4

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 (84) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +193 -56
  3. package/package.json +14 -5
  4. package/sdk-public-v1-route-manifest.json +81 -0
  5. package/sdk-v1-route-manifest.json +8996 -1697
  6. package/src/database-codec.js +21 -26
  7. package/src/database-types.js +11 -11
  8. package/src/database-view.js +6 -6
  9. package/src/http.js +13 -48
  10. package/src/ids.js +22 -0
  11. package/src/index.js +77 -2
  12. package/src/local/better-auth.js +17 -6
  13. package/src/local/environment.js +0 -1
  14. package/src/local/index.js +2 -2
  15. package/src/local/legacy-client.js +5 -5
  16. package/src/local/router.js +12 -12
  17. package/src/local/store.js +29 -28
  18. package/src/local/test-environment.js +3 -2
  19. package/src/postgres.js +5 -4
  20. package/src/react/core.js +2 -2
  21. package/src/ts-auth-ids.js +122 -0
  22. package/src/ts-auth.js +75 -77
  23. package/src/v1/backups.js +111 -0
  24. package/src/v1/catalog.js +210 -0
  25. package/src/v1/changes.js +225 -0
  26. package/src/v1/database-schema.js +45 -0
  27. package/src/v1/decode.js +20 -8
  28. package/src/v1/errors.js +23 -3
  29. package/src/v1/ids.js +9 -59
  30. package/src/v1/imports.js +72 -0
  31. package/src/v1/indexes.js +76 -0
  32. package/src/v1/json.js +4 -3
  33. package/src/v1/management-decode.js +24 -0
  34. package/src/v1/management-routes.js +67 -0
  35. package/src/v1/management-validation.js +25 -0
  36. package/src/v1/routes.js +36 -11
  37. package/src/v1/saved-queries.js +58 -0
  38. package/src/v1/shape-crypto.js +125 -0
  39. package/src/v1/shape-manifest.js +31 -0
  40. package/src/v1/shape-reader.js +212 -0
  41. package/src/v1/shape-subscription.js +208 -0
  42. package/src/v1/shapes.js +15 -10
  43. package/src/v1/sql.js +98 -0
  44. package/src/v1/system.js +80 -0
  45. package/src/v1/terrabase-v1.js +192 -33
  46. package/src/v1/transport.js +80 -34
  47. package/src/v1/usage.js +101 -0
  48. package/types/database-codec.d.ts +1 -6
  49. package/types/database-types.d.ts +11 -11
  50. package/types/http.d.ts +2 -8
  51. package/types/ids.d.ts +10 -0
  52. package/types/index.d.ts +70 -1
  53. package/types/local/environment.d.ts +1 -1
  54. package/types/local/store.d.ts +10 -0
  55. package/types/local/test-environment.d.ts +2 -2
  56. package/types/postgres.d.ts +4 -4
  57. package/types/ts-auth-ids.d.ts +14 -0
  58. package/types/ts-auth.d.ts +99 -101
  59. package/types/v1/backups.d.ts +128 -0
  60. package/types/v1/catalog.d.ts +92 -0
  61. package/types/v1/changes.d.ts +53 -0
  62. package/types/v1/database-schema.d.ts +82 -0
  63. package/types/v1/decode.d.ts +17 -4
  64. package/types/v1/errors.d.ts +16 -1
  65. package/types/v1/ids.d.ts +4 -16
  66. package/types/v1/imports.d.ts +132 -0
  67. package/types/v1/indexes.d.ts +75 -0
  68. package/types/v1/management-decode.d.ts +15 -0
  69. package/types/v1/management-routes.d.ts +3 -0
  70. package/types/v1/management-validation.d.ts +8 -0
  71. package/types/v1/routes.d.ts +5 -2
  72. package/types/v1/saved-queries.d.ts +33 -0
  73. package/types/v1/shape-crypto.d.ts +39 -0
  74. package/types/v1/shape-manifest.d.ts +28 -0
  75. package/types/v1/shape-reader.d.ts +45 -0
  76. package/types/v1/shape-subscription.d.ts +35 -0
  77. package/types/v1/shapes.d.ts +14 -0
  78. package/types/v1/sql.d.ts +47 -0
  79. package/types/v1/system.d.ts +85 -0
  80. package/types/v1/terrabase-v1.d.ts +116 -7
  81. package/types/v1/transport.d.ts +27 -10
  82. package/types/v1/usage.d.ts +171 -0
  83. package/src/ts-auth-discovery.js +0 -207
  84. package/types/ts-auth-discovery.d.ts +0 -19
package/CHANGELOG.md CHANGED
@@ -1,5 +1,48 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.4
4
+
5
+ Publishes current main, including `db.sql`, `db.changes`, backups, indexes and
6
+ `allRegions` placement, plus every Unreleased entry below. Releases are now
7
+ tag-driven: pushing a `v0.0.N` tag that matches `package.json` runs
8
+ `.github/workflows/publish.yml`, which re-runs the checks and publishes to npm
9
+ with provenance.
10
+
11
+ ## Unreleased — ts-auth platform token contract
12
+
13
+ `createTsAuthClient` sends every call to `apiBaseUrl`. The Atlas auth discovery
14
+ lookup, regional `<region>.auth.terrascale.tech` routing and the
15
+ `useReverseProxy` option are removed: ts-auth has one global issuer per tenant
16
+ (`https://auth.terrascale.tech/terrascale` for the platform). Contract tests
17
+ pin the issuer, the `https://api.terrascale.tech` audience, the four TerraBase
18
+ scopes and distinct 401/403 handling.
19
+
20
+ ## Unreleased — TS-754
21
+
22
+ Entity IDs are plain uppercase Crockford ULIDs. `generateId()` uses the maintained
23
+ `ulid` library with monotonic generation; `isValidId()` and `requireId()` validate
24
+ the canonical 26-character, 128-bit form. UUIDs, prefixes, lowercase and legacy
25
+ keys fail validation. Project IDs, document requests/responses, snapshot keys,
26
+ hosted identity DTOs and explicit development storage use this contract.
27
+
28
+ The document key is the entity ID; document JSON and patches cannot duplicate it
29
+ in a top-level `id` field. The deterministic UUIDv5 `documentIdFor` helper is
30
+ removed. Store natural keys in indexed fields. Local Better Auth generates ULIDs
31
+ and stores the ID only in the record key, reconstructing its adapter view on read.
32
+
33
+ This is a greenfield cutover: there is no migration, ID rewrite, compatibility
34
+ shim or legacy fallback. Service owners wipe their verified affected stores and
35
+ recreate bootstrap state; this stateless SDK has no production data to delete.
36
+ Release qualification requires the matching immutable C# ULID producer release.
37
+
38
+ ## Unreleased — TS-592
39
+
40
+ The project-scoped data client accepts a ts-auth access JWT as `token`, while
41
+ retaining legacy C# `tb_` keys for the existing producer release. Header injection
42
+ and malformed credentials fail before I/O. TS-589 keeps data paths unchanged;
43
+ Management and Admin remain closed and make no retired route calls.
44
+ JWT producer qualification awaits the server implementation of `docs/api.md`.
45
+
3
46
  ## 0.0.2 — TS-650
4
47
 
5
48
  TerraBase version tokens are opaque: `tbv1-<32 hex>` and the coming `tbv2-…`
package/README.md CHANGED
@@ -1,27 +1,40 @@
1
1
  # @terrascale/sdk
2
2
 
3
3
  The JavaScript/JSDoc SDK for the project-scoped C#/.NET TerraBase server
4
- (`terrabase`, `origin/main`). Version 0.0.1 replaces the retired Rust client.
4
+ (`TerraScale/terrascale`). Current source compatibility is pinned at
5
+ `e30ffdc287530551b161b0130220be53d3c0475e`; see the
6
+ [compatibility audit](docs/api-compatibility-20261013.md) for exact evidence and open gates.
5
7
  The package targets Node.js 22 and 24 and current Chrome, Firefox, Safari, and Edge.
6
8
  Plain ES modules ship as written; `nice -n 19 npm run build` generates the
7
9
  TypeScript declarations in `types/`.
10
+ The latest published standard is [ECMAScript 2026](https://ecma-international.org/publications-and-standards/standards/ecma-262/).
11
+ The compiler uses [`ESNext`](https://www.typescriptlang.org/tsconfig/target.html),
12
+ its latest supported ECMAScript target. Source stays
13
+ in `.js` files; JSDoc supplies types through `allowJs` and `checkJs`. JSDoc typing
14
+ is a [tooling feature](https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html),
15
+ independent of the ECMAScript edition. Published runtime
16
+ support remains Node.js 22/24 and the browser targets listed above.
8
17
 
9
18
  ```sh
10
19
  npm install @terrascale/sdk
11
20
  ```
12
21
 
22
+ The following shows the current API with a trusted `discoveredOrigin` supplied
23
+ by your authorized integration. Built-in Atlas integration remains pending; see
24
+ [endpoint selection](#atlas-and-endpoint-selection).
25
+
13
26
  ```js
14
- import { createTerraBaseV1Client, documentIdFor, v1Filter } from "@terrascale/sdk";
27
+ import { createTerraBaseV1Client, generateId, v1Filter } from "@terrascale/sdk";
15
28
 
16
29
  const client = createTerraBaseV1Client({
17
30
  project: process.env.TERRABASE_PROJECT,
18
- token: process.env.TERRABASE_API_KEY,
19
- baseUrl: process.env.TERRABASE_BASE_URL,
31
+ token: process.env.TERRABASE_ACCESS_TOKEN,
32
+ baseUrl: discoveredOrigin,
20
33
  });
21
34
  const db = client.database("app");
22
35
  const todos = db.collection("todos");
23
36
 
24
- const id = await documentIdFor("todos", "first-task");
37
+ const id = generateId();
25
38
  await todos.put(id, { title: "Use TerraBase", done: false }, { ifNoneMatchAny: true });
26
39
  const doc = await todos.get(id);
27
40
  await todos.patch(id, { merge: { done: true } }, { ifMatch: doc.version });
@@ -32,21 +45,39 @@ for await (const page of todos.pages({ filter: v1Filter.eq("/done", true), limit
32
45
  ```
33
46
 
34
47
  Provision the project, database and collection before using their handles.
35
- API keys begin with `tb_` and travel as `Authorization: Bearer <key>`.
48
+ Current project routes authenticate ts-auth project access JWTs. Legacy C# `tb_`
49
+ keys remain accepted for their narrower data scopes; they cannot grant
50
+ `databases:read` or `databases:write`. The historical immutable release harness
51
+ still uses `tb_` keys and does not qualify the current JWT implementation.
52
+ Credentials travel as
53
+ `Authorization: Bearer <token>` and are held privately. The SDK validates
54
+ header-safe syntax; authentication and authorization belong to the producer.
36
55
  Reads and queries require `documents:read`; writes and transactions require
37
56
  `documents:write`. Transaction assertions additionally require `documents:read`.
38
- Keep keys private and out of logs and browser bundles. `createTerraBaseClient`
57
+ Keep service credentials private and out of logs and browser bundles. `createTerraBaseClient`
39
58
  is an alias of `createTerraBaseV1Client`; it no longer accepts tenant/shard options.
40
59
 
41
60
  ## Atlas and endpoint selection
42
61
 
43
- Supply exactly one of `baseUrl` or `endpointResolver`. A resolver receives
44
- `{ project, database }` and returns the service URL, synchronously or asynchronously.
45
- The URL is resolved once per database session and reused by its operations.
62
+ The [zero-configuration operating contract](AGENTS.md#zero-configuration-user-decision-2026-10-09-do-not-revert)
63
+ requires first-party services to discover every eligible serving region and
64
+ receive production credentials automatically, without regional activation or
65
+ manual endpoint/secret wiring. Customer project/database scope and authorized
66
+ access tokens remain required. This release has not implemented automatic Atlas
67
+ integration (TS-507); the endpoint examples show the current API boundary and
68
+ are not a first-party production setup recipe. No new resolver API is implied.
69
+
70
+ The current implementation requires exactly one of `baseUrl` or
71
+ `endpointResolver`. In these examples, `discoveredOrigin` is a trusted HTTPS
72
+ origin supplied by an authorized integration, not an SDK-created value.
73
+ A resolver receives
74
+ `{ project, database?, signal }` and returns the service URL, synchronously or asynchronously.
75
+ Project catalog operations omit `database`; each project/catalog or database session
76
+ resolves once and reuses its URL.
46
77
  Shared resolution expires after 30 seconds and supplies a cancellation signal
47
78
  to the resolver; a later operation can retry an expired or failed resolution.
48
79
  Cancelling one operation leaves other callers' shared resolution running.
49
- HTTPS is required except for loopback HTTP in local development; no regional
80
+ HTTPS is required except for loopback HTTP in isolated tests; no regional
50
81
  host is hardcoded and no implicit production endpoint is selected.
51
82
 
52
83
  ```js
@@ -54,41 +85,54 @@ import { createTerraBaseV1Client, staticBaseUrlResolver } from "@terrascale/sdk"
54
85
 
55
86
  const client = createTerraBaseV1Client({
56
87
  project: process.env.TERRABASE_PROJECT,
57
- token: process.env.TERRABASE_API_KEY,
58
- endpointResolver: staticBaseUrlResolver(process.env.TERRABASE_BASE_URL),
88
+ token: process.env.TERRABASE_ACCESS_TOKEN,
89
+ endpointResolver: staticBaseUrlResolver(discoveredOrigin),
59
90
  });
60
91
  const db = client.database("app");
61
92
  ```
62
93
 
63
- Atlas (`ts-atlas`, a TypeScript Cloudflare Worker) discovers the closest eligible
94
+ Atlas discovers the closest eligible
64
95
  region and the location of a project/database. The resolver seam allows that
65
96
  choice to stay pinned for the session. Atlas discovery integration is deferred
66
97
  to TS-507; this release requires an explicit URL or caller-supplied resolver.
67
98
 
68
- ## Documents, queries, transactions and shapes
99
+ ## Documents, SQL, change streams and catalog
69
100
 
70
- The C# producer owns these routes:
101
+ Current handler source implements project-scoped database names and point
102
+ addresses as `/documents/by-key?id=…`. The complete method/path/scope inventory
103
+ is in [sdk-v1-route-manifest.json](sdk-v1-route-manifest.json), with 25 current
104
+ source-backed routes and one retained historical shape route. Current generated
105
+ OpenAPI and immutable release qualification remain open gates.
71
106
 
72
- | Operation | Method and path |
107
+ | Surface | Public methods |
73
108
  | --- | --- |
74
- | Documents | `GET/PUT/PATCH/DELETE /v1/projects/{project}/databases/{db}/collections/{c}/documents/{id}`; `POST …/documents` |
75
- | Query | `POST /v1/projects/{project}/databases/{db}/collections/{c}/query` |
76
- | Transaction | `POST /v1/projects/{project}/databases/{db}/transactions` |
77
- | Shape | `GET /v1/projects/{project}/databases/{db}/collections/{c}/shape` |
78
-
79
- 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
109
+ | Documents | `collection.get/put/create/patch/delete/list/query/pages/items` |
110
+ | Collections and declared JSON Schema | `db.collections.create/get/list/drop`; `collection.getSchema/putSchema/deleteSchema` |
111
+ | Databases | `client.databases.create/list/get/update/delete/branch` |
112
+ | SQL | `db.sql/checkSql/explainSql` |
113
+ | Changes | `db.changes` (SSE async iterator) |
114
+
115
+ Project, collection catalog, and database catalog IDs are canonical uppercase
116
+ 26-character ULIDs. `generateId()`, `isValidId()` and `requireId()` retain that
117
+ entity-ID contract. Document keys independently accept 1–256 UTF-16 code units,
118
+ without controls or lone surrogates; natural keys, slashes and Unicode travel as
119
+ one query parameter. A root payload `id` is ordinary data unless it equals the
120
+ key; the producer then strips that redundant member.
121
+ Documents return
82
122
  `{ id, version, state: "value", document }`; a causal read can answer
83
123
  `state: "conflict"` with `siblings`, and unknown states pass through. Versions
84
124
  (`tbv1-…`, `tbv2-…`) are opaque tokens. Writes return the version and a
85
- decimal-string commit `offset`; preserve those opaque positions and use
125
+ decimal-string commit `offset`; PATCH also returns the stored `document`.
126
+ Ops PATCH supports top-level `inc`, `add` and `remove` alongside `set`, `unset`
127
+ and `append`. `inc` requires a nonzero signed Int64 integer; set elements are
128
+ JSON scalars of at most 1 KiB under the producer serializer.
129
+ Preserve those opaque positions and use
86
130
  `ifMatch` or `ifNoneMatchAny` for conditional writes.
87
131
 
88
132
  Queries support typed filters, sorting, projection and bounded cursor pages.
89
133
  `query` returns one page; `pages` and `items` follow `nextCursor`.
90
134
  `count.exact: false` means the count is a lower bound. The current C# producer
91
- does not support `lower` paths or `explain`; query number comparisons use its
135
+ does not support `lower` paths or query-body `explain`; query number comparisons use its
92
136
  64-bit integer/double arithmetic, even when the SDK preserves exact JSON numbers.
93
137
  `ExactDecimal` and bigint serialization require Node.js 22+ or a current browser.
94
138
 
@@ -100,29 +144,118 @@ or replay mutations after an uncertain result; this release does not promise
100
144
  mutation deduplication. Validation, authentication, authorization and
101
145
  precondition failures are not automatically retried.
102
146
 
103
- Shapes require `shapes:read` and use the collection's GET route with a `where`
104
- filter, handle, offset and live cursor. Snapshot bootstrap and checkpoint resume
105
- provide correctness; `must_refetch` requires discarding local state and starting
106
- a fresh snapshot. The C# producer has no shape gatekeeper, SSE route, edge shape
107
- token or projection support. Origin responses require private cache revalidation. Fresh shape bootstrap is
108
- server-only in this release: browsers hide the initial 307 redirect metadata.
109
- Browser callers need a handle and snapshot offset obtained on their server.
147
+ SQL is the producer's bounded read-only subset: `{ matched, truncated, rows }`,
148
+ with row `{ id, value }` and no pagination cursor. `checkSql` returns `ok: false`
149
+ for invalid SQL; `explainSql` returns an HTTP error for invalid SQL. All three
150
+ require `databases:read`, granted by a project access JWT.
151
+
152
+ ```js
153
+ const result = await db.sql("SELECT * FROM todos LIMIT 10");
154
+ const controller = new AbortController();
155
+ for await (const event of db.changes({ cursor: "now", collections: ["todos"] }, {
156
+ signal: controller.signal,
157
+ })) {
158
+ console.log(event);
159
+ // Stop with controller.abort(), or break to close this iterator.
160
+ }
161
+ ```
162
+
163
+ SSE emits `cursor` and `change` events. Cursors are opaque and must retain the
164
+ same collection filter. `lastEventId` takes precedence over `cursor`; normal
165
+ valid EOF reconnects with the latest issued cursor. Delivery is at least once;
166
+ deduplicate by origin, version, collection and id. `document` is its current
167
+ serving value, including null. Network failures, malformed streams, terminal
168
+ errors, denials, expired history (410) and overload (429) propagate. The SDK
169
+ never silently resets to `now` or broadens the view. Iterator `return()` also
170
+ interrupts an already pending read.
171
+
172
+ The exported collection `shape()` remains compatible with the historical
173
+ `6cb9745…` release. Its route is absent from the audited current server source;
174
+ do not use it as current producer evidence. SSE changes are a separate database
175
+ feed, not authorized bounded-query snapshots or the planned reactive WebSocket API.
176
+
177
+ ## Free shape subscriptions (protocol v1)
110
178
 
111
- The same public SDK supplies this metadata on the server. Pass the position to
112
- the browser and repeat that immutable snapshot page with the identical filter
113
- and collection:
179
+ `collection.subscribeShape({ where? }, { onUpdate?, signal? })` follows a collection's
180
+ sealed snapshot, log chunks, and live long-polls. Its `state` is a map from document
181
+ id to `{ version, document }`; `upToDate` becomes true only after a fresh response
182
+ reports `up_to_date`. Each callback sees the complete applied response or a
183
+ freshness change; freshness is cleared while a changed-lineage resume is pending.
114
184
 
115
185
  ```js
116
- // Server: use the public client with the caller's shapes:read key.
117
- const snapshot = await serverCollection.shape({ where });
118
- const position = { handle: snapshot.handle, offset: snapshot.offset };
119
- // Browser: resume using position supplied by your application server.
120
- const page = await browserCollection.shape({ where, ...position });
186
+ const shape = todos.subscribeShape({ where: v1Filter.eq("/done", false) }, {
187
+ onUpdate(subscription) {
188
+ console.log(subscription.state, subscription.upToDate);
189
+ },
190
+ });
191
+ try {
192
+ await shape.done; // Runs until close(), cancellation, or a terminal error.
193
+ } finally {
194
+ shape.close();
195
+ }
121
196
  ```
122
197
 
123
- Failures throw `TerraBaseV1Error` with the HTTP status and producer error code;
124
- transaction failures may also identify the failing `op`. Request cancellation
125
- uses `AbortSignal`.
198
+ `close()` cancels a pending read. Server errors reject `done` using the existing
199
+ TerraBase error types; malformed responses and network failures also stop it.
200
+ Observe `done` to detect terminal errors. A throwing `onUpdate` stops the
201
+ subscription and rejects `done` with the callback's error; already applied state
202
+ remains available. Calling `close()` or aborting takes precedence over a later
203
+ callback exception and resolves `done`. Document
204
+ upserts replace the prior value and deletes of unknown ids are harmless. Repeated
205
+ events are applied: a sealed value can be newer than its event, including after
206
+ failover. There are no durable local writes or offline mutation queue.
207
+
208
+ The client preserves state for one proven cursor-resume attempt when a different
209
+ machine rejects its handle. It never resumes an incomplete snapshot. A failed
210
+ resume or another `409 must_refetch` clears state and starts a fresh snapshot.
211
+ Opaque resume tokens travel verbatim in the query, or `TB-Shape-Resume` when the
212
+ request target would exceed the protocol limit. Only documented transient
213
+ `shape_busy`, `unavailable`, and `shape_too_large` errors retry with backoff and
214
+ `Retry-After` until success or cancellation; authorization, validation, and
215
+ network errors stop the subscription. The backoff delay is capped at 30 seconds
216
+ unless `Retry-After` requires longer. The maximum signed-64-bit live bucket is
217
+ accepted as a response, as §4 allows, but cannot be sent as the next input;
218
+ `done` rejects with a `TypeError` if that protocol limit is reached.
219
+
220
+ Origin JSON with a leading UTF-8 BOM is rejected by the v1 transport, including
221
+ historical routes; shape v1 §6 requires bytes without a BOM.
222
+ Subscriptions use unconditional reads; they do not send `If-None-Match` or use
223
+ the optional `304` cached-body path.
224
+
225
+ `collection.decryptShapeObject(bytes, { handle, offset, epoch, keyId }, { signal? })`
226
+ fetches the matching epoch key with `cache: "no-store"`, derives the per-object key
227
+ with WebCrypto HKDF, and verifies every AES-256-GCM TBS1 frame before returning a
228
+ page. Keys are cached only in process memory by `(handle, epoch, keyId)`, scoped
229
+ to the credential, database and collection. A key fetch bypasses HTTP caches;
230
+ keys are never persisted. Past epochs are evicted on access as time or the
231
+ latest served epoch advances; historical objects fetch their keys again without
232
+ retaining them. Any `409 must_refetch` on the shape or key route clears that
233
+ collection's key cache. A failed tag, binding, frame, or response validation
234
+ applies nothing. Key ids follow §12's 26 ASCII bytes without assuming a ULID.
235
+ Native browser Fetch hides manual redirect metadata, so subscription bootstrap
236
+ currently requires server fetch. TBS1 decryption uses WebCrypto in either runtime.
237
+
238
+ This implements the [proposed protocol](contracts/shape-v1/shape-reads.md) at
239
+ `993927ce7ecf8f9b889d24d4d1d21ec96eaf9416`, using `documents:read`. HTTP fakes and the
240
+ upstream [conformance vectors](test/fixtures/shape-vectors.json) verify client
241
+ behavior; they do not qualify a producer deployment. Current generated OpenAPI,
242
+ live endpoint availability, and automatic region discovery remain unqualified.
243
+ No TerraBase binary is downloaded or run by these tests. The existing historical
244
+ `shape()` method keeps its contract. Manifest/object delivery and 302 redirects
245
+ are deferred to FR-22; vector `presigned-manifest` is explicitly skipped until its
246
+ delivery contract is ready upstream.
247
+
248
+ Failures throw `TerraBaseV1Error` with status, code, optional transaction `op`,
249
+ parsed `body`, raw `responseText`, response `headers`, and a received
250
+ `X-Request-ID` as `requestId`. The actual producer uses `application/json`
251
+ `{error:{code,message,op,details}}`, not RFC 9457. The SDK preserves RFC 9457
252
+ bodies when received but does not invent producer support or request IDs.
253
+ Cancellation preserves the supplied `AbortSignal` reason.
254
+
255
+ **Browser gate remains red:** Chrome and Edge native fetch resend a buffered
256
+ mutation once after HTTP 421. Node uses one-shot request streams to prevent that
257
+ replay. Browser Fetch has no retry-control option; its one-wire assertions remain
258
+ failing in this draft. See the audit for exact results and producer dependencies.
126
259
 
127
260
  ## Ouroboros and qualification
128
261
 
@@ -140,14 +273,13 @@ Never commit keys, cookies, environment files or real tenant data.
140
273
 
141
274
  The immutable release pin is
142
275
  [`scripts/ci/terrabase-release.json`](scripts/ci/terrabase-release.json): C#
143
- TerraBase 0.1.0, release `ci-0248ad3ac6fb82ac900e38005840a619e5d0beac-run-13267`,
276
+ TerraBase 0.1.0, release `ci-6cb97456b9b52a92a61856601cc025c4f2833518-run-16729`,
144
277
  with binary SHA-256
145
- `8abcedaa6b8487f08ecafe4485862f1f9309154e58ac1a74eda2278b78500968`.
146
- This official release is currently a draft: the producer's fast checks failed
147
- and publication was skipped (terrabase #110). The SDK integration harness may
148
- consume its official asset read-only when the version, source revision, size and
149
- SHA-256 are verified; publication is not required. Draft status does not establish
150
- that the producer's source qualification passed.
278
+ `cc2db35b18c385c6d58036c6c94e59460b0e12b0d5616da2222713efbe666700`.
279
+ This official prerelease contains the qualified TS-754 ULID producer, the renamed
280
+ `TerraBase` assembly and `src/TerraBase` sources. Its asset name remains `terrabase-linux-amd64`.
281
+ The SDK integration harness consumes its official asset read-only when the
282
+ version, source revision, size and SHA-256 are verified.
151
283
  The acquisition script verifies the official release, revision, asset size and
152
284
  digest. Private downloads require `FORGEJO_TOKEN`. Missing or mismatched official
153
285
  assets block qualification rather than selecting older bytes.
@@ -187,11 +319,16 @@ See [CHANGELOG.md](CHANGELOG.md) for the 0.0.1 migration and breaking changes.
187
319
  client, with its own origin, instance and credentials. Management,
188
320
  administration and production Better Auth capabilities remain subject to their
189
321
  explicit admission errors; they are not a shortcut into the database transport.
322
+ Webhook dead-letter replay uses the documented `endpointId:eventId` delivery
323
+ selector; both references must be canonical ULIDs. Entity pages reject null and
324
+ primitive records; recovery-code pages contain strings.
190
325
 
191
326
  `@terrascale/sdk/local` (including `terrascale-local`) and `@terrascale/sdk/postgres` are
192
- **deprecated legacy entrypoints**. SQLite stays opt-in for development only and
193
- refuses CI, production, staging, qualification and deployment environments.
194
- It is no longer the required Dashboard backend and does not qualify the C# API.
327
+ **deprecated legacy entrypoints**. The operating contract confines fake/local
328
+ stores to test code and test binaries. Their current exported runtime paths
329
+ remain inventoried for removal; this docs change does not remove them.
330
+ Do not use them for application onboarding, production, staging or producer
331
+ qualification. A local adapter test does not qualify the real C# API.
195
332
  The PostgreSQL listener and retired tenant/shard client are outside the default
196
333
  v1 API. Existing framework, schema and SQL entrypoints are separate legacy
197
334
  surfaces; the root entrypoint exposes the C# v1 client API.
@@ -200,4 +337,4 @@ Hosted OAuth resource requests use one exact registered HTTPS `resource`. `oidc.
200
337
 
201
338
  `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.
202
339
 
203
- 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.
340
+ 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. ts-auth has one global issuer per tenant, `{apiBaseUrl}/{slug}` (the platform issuer is `https://auth.terrascale.tech/terrascale`, with no regional host and no trailing slash); every call goes to `apiBaseUrl`. Platform tokens for TerraBase use audience `https://api.terrascale.tech` and only the scopes `databases:read`, `databases:write`, `documents:read` and `documents:write`, sent as one space-separated `scope` string.
package/package.json CHANGED
@@ -1,9 +1,13 @@
1
1
  {
2
2
  "name": "@terrascale/sdk",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
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",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/TerraScale/ts-js.git"
10
+ },
7
11
  "private": false,
8
12
  "publishConfig": {
9
13
  "access": "public",
@@ -78,6 +82,7 @@
78
82
  "types",
79
83
  "!types/integration",
80
84
  "sdk-v1-route-manifest.json",
85
+ "sdk-public-v1-route-manifest.json",
81
86
  "README.md",
82
87
  "CHANGELOG.md",
83
88
  "LICENSE"
@@ -94,8 +99,6 @@
94
99
  "typecheck": "tsc -p tsconfig.json --noEmit",
95
100
  "lint": "npm run typecheck",
96
101
  "test": "vitest run",
97
- "provision:terrabase": "node scripts/ci/provision-terrabase.mjs",
98
- "test:integration": "node scripts/ci/run-terrabase-integration.mjs",
99
102
  "test:browser": "playwright test",
100
103
  "qualify:auth-authority": "node scripts/qualify-auth-authority.js",
101
104
  "check:frameworks": "vitest run src/database-view.test.js src/react/core.test.js src/svelte/index.test.js src/tanstack/index.test.js",
@@ -130,7 +133,7 @@
130
133
  "typescript": "^5.9.3",
131
134
  "vitest": "^4.1.11",
132
135
  "@tanstack/db": "0.9.2",
133
- "svelte": "5.55.1",
136
+ "svelte": "5.57.2",
134
137
  "react": "19.2.8",
135
138
  "react-test-renderer": "19.2.8",
136
139
  "@types/react": "19.2.14",
@@ -150,5 +153,11 @@
150
153
  "last 1 Edge major version"
151
154
  ]
152
155
  },
153
- "packageManager": "npm@11.18.0"
156
+ "packageManager": "npm@11.18.0",
157
+ "dependencies": {
158
+ "ulid": "3.0.2"
159
+ },
160
+ "overrides": {
161
+ "vite": "8.2.4"
162
+ }
154
163
  }
@@ -0,0 +1,81 @@
1
+ {
2
+ "producerRevision": "e7fa366ddb289f5612c93d316b316fb92c568151",
3
+ "routes": [
4
+ {"method":"GET","path":"/backupz","operation":"backupz","scopes":["anonymous"],"requestMediaTypes":[],"statuses":[200,503],"responseMediaType":"application/json","source":"src/TerraBase/Features/Backup/BackupHealthEndpoint.cs","request":"none"},
5
+ {"method":"GET","path":"/health/replication","operation":"replicationHealth","scopes":["anonymous"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Health/ReplicationHealthEndpoint.cs","request":"none"},
6
+ {"method":"GET","path":"/healthz","operation":"healthz","scopes":["anonymous"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Health/HealthzEndpoint.cs","request":"none"},
7
+ {"method":"GET","path":"/readyz","operation":"readyz","scopes":["anonymous"],"requestMediaTypes":[],"statuses":[200,503],"responseMediaType":"application/json","source":"src/TerraBase/Features/Health/ReadyzEndpoint.cs","request":"none"},
8
+ {"method":"GET","path":"/v1/platform/databases","operation":"listPlatformDatabases","scopes":["platform-admin"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Platform/ListPlatformDatabasesEndpoint.cs","request":"none"},
9
+ {"method":"GET","path":"/v1/platform/databases/{database}/collections","operation":"listPlatformCollections","scopes":["platform-admin"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Platform/ListPlatformCollectionsEndpoint.cs","request":"none"},
10
+ {"method":"GET","path":"/v1/platform/databases/{database}/collections/{collection}/documents","operation":"listPlatformDocuments","scopes":["platform-admin"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Platform/ListPlatformDocumentsEndpoint.cs","request":"none"},
11
+ {"method":"GET","path":"/v1/platform/databases/{database}/collections/{collection}/documents/by-key","operation":"getPlatformDocument","scopes":["platform-admin"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Platform/GetPlatformDocumentEndpoint.cs","request":"none"},
12
+ {"method":"GET","path":"/v1/projects/{project}/analytics","operation":"getProjectAnalytics","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Usage/GetProjectAnalyticsEndpoint.cs","request":"none"},
13
+ {"method":"DELETE","path":"/v1/projects/{project}/backup-destination","operation":"deleteBackupDestination","scopes":["databases:write"],"requestMediaTypes":[],"statuses":[204],"responseMediaType":"","source":"src/TerraBase/Features/Management/Backups/DeleteBackupDestinationEndpoint.cs","request":"none"},
14
+ {"method":"GET","path":"/v1/projects/{project}/backup-destination","operation":"getBackupDestination","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/GetBackupDestinationEndpoint.cs","request":"none"},
15
+ {"method":"PUT","path":"/v1/projects/{project}/backup-destination","operation":"setBackupDestination","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/SetBackupDestinationEndpoint.cs","request":"ProjectBackupDestinationRequest"},
16
+ {"method":"GET","path":"/v1/projects/{project}/databases","operation":"listDatabases","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/ListManagedDatabasesEndpoint.cs","request":"none"},
17
+ {"method":"POST","path":"/v1/projects/{project}/databases","operation":"createDatabase","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/CreateManagedDatabaseEndpoint.cs","request":"DatabaseRegionsRequest"},
18
+ {"method":"DELETE","path":"/v1/projects/{project}/databases/{database}","operation":"deleteDatabase","scopes":["databases:write"],"requestMediaTypes":[],"statuses":[204],"responseMediaType":"","source":"src/TerraBase/Features/Management/DeleteManagedDatabaseEndpoint.cs","request":"none"},
19
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}","operation":"getDatabase","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/GetManagedDatabaseEndpoint.cs","request":"none"},
20
+ {"method":"PATCH","path":"/v1/projects/{project}/databases/{database}","operation":"updateDatabase","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/UpdateManagedDatabaseEndpoint.cs","request":"DatabaseRegionsRequest"},
21
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/analytics","operation":"getDatabaseAnalytics","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Usage/GetDatabaseAnalyticsEndpoint.cs","request":"none"},
22
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/auto-index/{collection}","operation":"getAutoIndexPolicy","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Indexes/GetAutoIndexPolicyEndpoint.cs","request":"none"},
23
+ {"method":"PUT","path":"/v1/projects/{project}/databases/{database}/auto-index/{collection}","operation":"setAutoIndexPolicy","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Indexes/SetAutoIndexPolicyEndpoint.cs","request":"AutoIndexPolicyRequest"},
24
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/backup-policy","operation":"getBackupPolicy","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/GetBackupPolicyEndpoint.cs","request":"none"},
25
+ {"method":"PUT","path":"/v1/projects/{project}/databases/{database}/backup-policy","operation":"setBackupPolicy","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/SetBackupPolicyEndpoint.cs","request":"BackupPolicyRequest"},
26
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/backups","operation":"listBackups","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/ListBackupsEndpoint.cs","request":"none"},
27
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/backups","operation":"createBackup","scopes":["databases:write"],"requestMediaTypes":[],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/CreateBackupEndpoint.cs","request":"none"},
28
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/backups/{backup}/restore","operation":"restoreBackup","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/RestoreBackupEndpoint.cs","request":"NameRequest"},
29
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/branches","operation":"branchDatabase","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/BranchManagedDatabaseEndpoint.cs","request":"NameRequest"},
30
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/changes","operation":"streamDatabaseChanges","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"text/event-stream","source":"src/TerraBase/Features/Documents/GetDatabaseChangesEndpoint.cs","request":"none"},
31
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections","operation":"listCollections","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/ListCollectionsEndpoint.cs","request":"none"},
32
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/collections","operation":"createCollection","scopes":["documents:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/CreateCollectionEndpoint.cs","request":"CreateCollectionRequest"},
33
+ {"method":"DELETE","path":"/v1/projects/{project}/databases/{database}/collections/{collection}","operation":"dropCollection","scopes":["documents:write"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/DropCollectionEndpoint.cs","request":"none"},
34
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}","operation":"getCollection","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/GetCollectionEndpoint.cs","request":"none"},
35
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/documents","operation":"listDocuments","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/ListDocumentsEndpoint.cs","request":"none"},
36
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/documents","operation":"createDocument","scopes":["documents:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/CreateDocumentEndpoint.cs","request":"JsonElement"},
37
+ {"method":"DELETE","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/documents/by-key","operation":"deleteDocument","scopes":["documents:write"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/DeleteDocumentEndpoint.cs","request":"none"},
38
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/documents/by-key","operation":"getDocument","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/GetDocumentEndpoint.cs","request":"none"},
39
+ {"method":"PATCH","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/documents/by-key","operation":"patchDocument","scopes":["documents:write"],"requestMediaTypes":["application/merge-patch+json","application/vnd.terrabase.ops+json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/PatchDocumentEndpoint.cs","request":"JsonElement / PatchOpsRequest"},
40
+ {"method":"PUT","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/documents/by-key","operation":"putDocument","scopes":["documents:write"],"requestMediaTypes":["application/json"],"statuses":[200,201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/PutDocumentEndpoint.cs","request":"JsonElement"},
41
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/query","operation":"queryDocuments","scopes":["documents:read"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/QueryDocumentsEndpoint.cs","request":"QueryRequest"},
42
+ {"method":"DELETE","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/schema","operation":"deleteDeclaredCollectionSchema","scopes":["documents:write"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/DeleteCollectionSchemaEndpoint.cs","request":"none"},
43
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/schema","operation":"getDeclaredCollectionSchema","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/GetCollectionSchemaEndpoint.cs","request":"none"},
44
+ {"method":"PUT","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/schema","operation":"putDeclaredCollectionSchema","scopes":["documents:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/PutCollectionSchemaEndpoint.cs","request":"JsonElement"},
45
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/shape","operation":"getShape","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200,307],"responseMediaType":"application/json","source":"src/TerraBase/Features/Shapes/GetShapeEndpoint.cs","request":"none"},
46
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/shape/keys","operation":"getShapeKey","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Shapes/GetShapeKeyEndpoint.cs","request":"none"},
47
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/shape/manifest","operation":"getShapeManifest","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Shapes/GetShapeManifestEndpoint.cs","request":"none"},
48
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/import","operation":"getImport","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Import/GetImportEndpoint.cs","request":"none"},
49
+ {"method":"PATCH","path":"/v1/projects/{project}/databases/{database}/import","operation":"updateImport","scopes":["databases:write","documents:write"],"requestMediaTypes":["application/json"],"statuses":[202],"responseMediaType":"application/json","source":"src/TerraBase/Features/Import/UpdateImportEndpoint.cs","request":"UpdateImportRequest"},
50
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/import","operation":"createImport","scopes":["databases:write","documents:write"],"requestMediaTypes":["application/json"],"statuses":[200,201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Import/CreateImportEndpoint.cs","request":"CreateImportRequest"},
51
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/import/cancel","operation":"cancelImport","scopes":["databases:write"],"requestMediaTypes":[],"statuses":[202],"responseMediaType":"application/json","source":"src/TerraBase/Features/Import/CancelImportEndpoint.cs","request":"none"},
52
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/import/resume","operation":"resumeImport","scopes":["databases:write","documents:write"],"requestMediaTypes":[],"statuses":[202],"responseMediaType":"application/json","source":"src/TerraBase/Features/Import/ResumeImportEndpoint.cs","request":"none"},
53
+ {"method":"PUT","path":"/v1/projects/{project}/databases/{database}/import/source","operation":"uploadImportSource","scopes":["databases:write","documents:write"],"requestMediaTypes":["application/octet-stream"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Import/UploadImportSourceEndpoint.cs","request":"byte[]"},
54
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/import/start","operation":"startImport","scopes":["databases:write","documents:write"],"requestMediaTypes":["application/json"],"statuses":[202],"responseMediaType":"application/json","source":"src/TerraBase/Features/Import/StartImportEndpoint.cs","request":"StartImportRequest"},
55
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/index-recommendations","operation":"listIndexRecommendations","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Indexes/ListIndexRecommendationsEndpoint.cs","request":"none"},
56
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/index-recommendations/{recommendation}/apply","operation":"applyIndexRecommendation","scopes":["databases:write"],"requestMediaTypes":[],"statuses":[200,201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Indexes/ApplyIndexRecommendationEndpoint.cs","request":"none"},
57
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/indexes","operation":"listIndexes","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Indexes/ListIndexesEndpoint.cs","request":"none"},
58
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/indexes","operation":"createIndex","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Indexes/CreateIndexEndpoint.cs","request":"CreateIndexRequest"},
59
+ {"method":"DELETE","path":"/v1/projects/{project}/databases/{database}/indexes/{index}","operation":"dropIndex","scopes":["databases:write"],"requestMediaTypes":[],"statuses":[204],"responseMediaType":"","source":"src/TerraBase/Features/Management/Indexes/DropIndexEndpoint.cs","request":"none"},
60
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/point-in-time","operation":"getRestoreWindow","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/GetRestoreWindowEndpoint.cs","request":"none"},
61
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/point-in-time/plan","operation":"planPointInTime","scopes":["databases:read"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/PlanPointInTimeEndpoint.cs","request":"PointInTimePlanRequest"},
62
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/point-in-time/restore","operation":"restorePointInTime","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Backups/RestorePointInTimeEndpoint.cs","request":"PointInTimeRestoreRequest"},
63
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/query-shapes","operation":"listQueryShapes","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/ListQueryShapesEndpoint.cs","request":"none"},
64
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/replication","operation":"getDatabaseReplication","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Usage/GetDatabaseReplicationEndpoint.cs","request":"none"},
65
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/schema","operation":"getDatabaseSchema","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Schema/ListCollectionsEndpoint.cs","request":"none"},
66
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/schema/{collection}","operation":"getCollectionSchema","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Schema/GetCollectionSchemaEndpoint.cs","request":"none"},
67
+ {"method":"PUT","path":"/v1/projects/{project}/databases/{database}/schema/{collection}","operation":"declareCollectionSchema","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Schema/PutCollectionSchemaEndpoint.cs","request":"UniqueSchemaRequest"},
68
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/sql","operation":"runSql","scopes":["databases:read"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/RunSqlEndpoint.cs","request":"SqlRequest"},
69
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/sql/check","operation":"checkSql","scopes":["databases:read"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/CheckSqlEndpoint.cs","request":"SqlRequest"},
70
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/sql/explain","operation":"explainSql","scopes":["databases:read"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/ExplainSqlEndpoint.cs","request":"SqlRequest"},
71
+ {"method":"POST","path":"/v1/projects/{project}/databases/{database}/transactions","operation":"runTransaction","scopes":["documents:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/TransactionEndpoint.cs","request":"TransactionRequest"},
72
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/usage","operation":"getDatabaseUsage","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Usage/GetDatabaseUsageEndpoint.cs","request":"none"},
73
+ {"method":"GET","path":"/v1/projects/{project}/replication","operation":"getProjectReplication","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Usage/GetProjectReplicationEndpoint.cs","request":"none"},
74
+ {"method":"GET","path":"/v1/projects/{project}/saved-queries","operation":"listSavedQueries","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/ListSavedQueriesEndpoint.cs","request":"none"},
75
+ {"method":"POST","path":"/v1/projects/{project}/saved-queries","operation":"createSavedQuery","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[201],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/CreateSavedQueryEndpoint.cs","request":"SavedQueryRequest"},
76
+ {"method":"DELETE","path":"/v1/projects/{project}/saved-queries/{query}","operation":"deleteSavedQuery","scopes":["databases:write"],"requestMediaTypes":[],"statuses":[204],"responseMediaType":"","source":"src/TerraBase/Features/Management/Queries/DeleteSavedQueryEndpoint.cs","request":"none"},
77
+ {"method":"GET","path":"/v1/projects/{project}/saved-queries/{query}","operation":"getSavedQuery","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/GetSavedQueryEndpoint.cs","request":"none"},
78
+ {"method":"PUT","path":"/v1/projects/{project}/saved-queries/{query}","operation":"updateSavedQuery","scopes":["databases:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Queries/UpdateSavedQueryEndpoint.cs","request":"SavedQueryRequest"},
79
+ {"method":"GET","path":"/v1/projects/{project}/usage","operation":"getProjectUsage","scopes":["databases:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Management/Usage/GetProjectUsageEndpoint.cs","request":"none"}
80
+ ]
81
+ }