@terrascale/sdk 0.0.3 → 0.0.5

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 (66) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +206 -67
  3. package/package.json +10 -4
  4. package/sdk-public-v1-route-manifest.json +85 -0
  5. package/sdk-v1-route-manifest.json +896 -15
  6. package/src/http.js +3 -48
  7. package/src/index.js +80 -1
  8. package/src/local/environment.js +0 -1
  9. package/src/ts-auth.js +1 -5
  10. package/src/v1/backups.js +111 -0
  11. package/src/v1/catalog.js +240 -0
  12. package/src/v1/changes.js +225 -0
  13. package/src/v1/database-schema.js +45 -0
  14. package/src/v1/decode.js +6 -5
  15. package/src/v1/errors.js +23 -3
  16. package/src/v1/export.js +68 -0
  17. package/src/v1/ids.js +5 -2
  18. package/src/v1/imports.js +72 -0
  19. package/src/v1/indexes.js +76 -0
  20. package/src/v1/json.js +4 -3
  21. package/src/v1/management-decode.js +24 -0
  22. package/src/v1/management-routes.js +72 -0
  23. package/src/v1/management-validation.js +25 -0
  24. package/src/v1/routes.js +32 -7
  25. package/src/v1/saved-queries.js +58 -0
  26. package/src/v1/shape-crypto.js +125 -0
  27. package/src/v1/shape-manifest.js +31 -0
  28. package/src/v1/shape-reader.js +214 -0
  29. package/src/v1/shape-subscription.js +208 -0
  30. package/src/v1/shapes.js +11 -5
  31. package/src/v1/sql.js +98 -0
  32. package/src/v1/system.js +80 -0
  33. package/src/v1/terrabase-v1.js +231 -30
  34. package/src/v1/transport.js +117 -33
  35. package/src/v1/usage.js +101 -0
  36. package/types/http.d.ts +2 -8
  37. package/types/index.d.ts +73 -0
  38. package/types/local/environment.d.ts +1 -1
  39. package/types/ts-auth.d.ts +0 -2
  40. package/types/v1/backups.d.ts +128 -0
  41. package/types/v1/catalog.d.ts +104 -0
  42. package/types/v1/changes.d.ts +53 -0
  43. package/types/v1/database-schema.d.ts +82 -0
  44. package/types/v1/decode.d.ts +20 -4
  45. package/types/v1/errors.d.ts +16 -1
  46. package/types/v1/export.d.ts +26 -0
  47. package/types/v1/ids.d.ts +2 -2
  48. package/types/v1/imports.d.ts +132 -0
  49. package/types/v1/indexes.d.ts +75 -0
  50. package/types/v1/management-decode.d.ts +15 -0
  51. package/types/v1/management-routes.d.ts +3 -0
  52. package/types/v1/management-validation.d.ts +8 -0
  53. package/types/v1/routes.d.ts +5 -2
  54. package/types/v1/saved-queries.d.ts +33 -0
  55. package/types/v1/shape-crypto.d.ts +39 -0
  56. package/types/v1/shape-manifest.d.ts +28 -0
  57. package/types/v1/shape-reader.d.ts +45 -0
  58. package/types/v1/shape-subscription.d.ts +35 -0
  59. package/types/v1/shapes.d.ts +16 -2
  60. package/types/v1/sql.d.ts +47 -0
  61. package/types/v1/system.d.ts +85 -0
  62. package/types/v1/terrabase-v1.d.ts +140 -6
  63. package/types/v1/transport.d.ts +33 -10
  64. package/types/v1/usage.d.ts +171 -0
  65. package/src/ts-auth-discovery.js +0 -207
  66. package/types/ts-auth-discovery.d.ts +0 -19
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased — collection TTL and vector near sort
4
+
5
+ `collection.putTtl(path)`, `getTtl()` and `deleteTtl()` call
6
+ `PUT/GET/DELETE .../collections/{collection}/ttl` and return `{ path }`
7
+ (`null` when unset). `query({ sort: [{ near: { path, vector, metric } }] })`
8
+ sorts by vector distance and each item carries `distance`.
9
+
10
+ ## Unreleased — database export
11
+
12
+ `db.export({ after, signal })` streams TerraBase's
13
+ `GET /v1/projects/{project}/databases/{database}/export` NDJSON as an async
14
+ iterable of `{ collection, id, document }`. `after: { collection, id }` resumes
15
+ after that document. Error answers raise the usual `TerraBaseV1Error`.
16
+
17
+ ## 0.0.4
18
+
19
+ Publishes current main, including `db.sql`, `db.changes`, backups, indexes and
20
+ `allRegions` placement, plus every Unreleased entry below. Releases are now
21
+ tag-driven: pushing a `v0.0.N` tag that matches `package.json` runs
22
+ `.github/workflows/publish.yml`, which re-runs the checks and publishes to npm
23
+ with provenance.
24
+
25
+ ## Unreleased — ts-auth platform token contract
26
+
27
+ `createTsAuthClient` sends every call to `apiBaseUrl`. The Atlas auth discovery
28
+ lookup, regional `<region>.auth.terrascale.tech` routing and the
29
+ `useReverseProxy` option are removed: ts-auth has one global issuer per tenant
30
+ (`https://auth.terrascale.tech/terrascale` for the platform). Contract tests
31
+ pin the issuer, the `https://api.terrascale.tech` audience, the four TerraBase
32
+ scopes and distinct 401/403 handling.
33
+
3
34
  ## Unreleased — TS-754
4
35
 
5
36
  Entity IDs are plain uppercase Crockford ULIDs. `generateId()` uses the maintained
package/README.md CHANGED
@@ -1,22 +1,35 @@
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
27
  import { createTerraBaseV1Client, generateId, v1Filter } from "@terrascale/sdk";
15
28
 
16
29
  const client = createTerraBaseV1Client({
17
30
  project: process.env.TERRABASE_PROJECT,
18
31
  token: process.env.TERRABASE_ACCESS_TOKEN,
19
- baseUrl: process.env.TERRABASE_BASE_URL,
32
+ baseUrl: discoveredOrigin,
20
33
  });
21
34
  const db = client.database("app");
22
35
  const todos = db.collection("todos");
@@ -32,9 +45,11 @@ 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
- 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
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
38
53
  `Authorization: Bearer <token>` and are held privately. The SDK validates
39
54
  header-safe syntax; authentication and authorization belong to the producer.
40
55
  Reads and queries require `documents:read`; writes and transactions require
@@ -44,13 +59,25 @@ is an alias of `createTerraBaseV1Client`; it no longer accepts tenant/shard opti
44
59
 
45
60
  ## Atlas and endpoint selection
46
61
 
47
- Supply exactly one of `baseUrl` or `endpointResolver`. A resolver receives
48
- `{ project, database }` and returns the service URL, synchronously or asynchronously.
49
- 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.
50
77
  Shared resolution expires after 30 seconds and supplies a cancellation signal
51
78
  to the resolver; a later operation can retry an expired or failed resolution.
52
79
  Cancelling one operation leaves other callers' shared resolution running.
53
- 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
54
81
  host is hardcoded and no implicit production endpoint is selected.
55
82
 
56
83
  ```js
@@ -59,60 +86,73 @@ import { createTerraBaseV1Client, staticBaseUrlResolver } from "@terrascale/sdk"
59
86
  const client = createTerraBaseV1Client({
60
87
  project: process.env.TERRABASE_PROJECT,
61
88
  token: process.env.TERRABASE_ACCESS_TOKEN,
62
- endpointResolver: staticBaseUrlResolver(process.env.TERRABASE_BASE_URL),
89
+ endpointResolver: staticBaseUrlResolver(discoveredOrigin),
63
90
  });
64
91
  const db = client.database("app");
65
92
  ```
66
93
 
67
- Atlas (`ts-atlas`, a TypeScript Cloudflare Worker) discovers the closest eligible
94
+ Atlas discovers the closest eligible
68
95
  region and the location of a project/database. The resolver seam allows that
69
96
  choice to stay pinned for the session. Atlas discovery integration is deferred
70
97
  to TS-507; this release requires an explicit URL or caller-supplied resolver.
71
98
 
72
- ## Documents, queries, transactions and shapes
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.
99
+ ## Documents, SQL, change streams and catalog
86
100
 
87
- 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.
88
106
 
89
- | Operation | Method and path |
107
+ | Surface | Public methods |
90
108
  | --- | --- |
91
- | Documents | `GET/PUT/PATCH/DELETE /v1/projects/{project}/databases/{db}/collections/{c}/documents/{id}`; `POST …/documents` |
92
- | Query | `POST /v1/projects/{project}/databases/{db}/collections/{c}/query` |
93
- | Transaction | `POST /v1/projects/{project}/databases/{db}/transactions` |
94
- | Shape | `GET /v1/projects/{project}/databases/{db}/collections/{c}/shape` |
95
-
96
- Collection methods are `get`, `put`, `create`, `patch`, `delete`, `query`,
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
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
+ | Collection TTL | `collection.putTtl/getTtl/deleteTtl` |
112
+ | Databases | `client.databases.create/list/get/update/delete/branch` |
113
+ | SQL | `db.sql/checkSql/explainSql` |
114
+ | Changes | `db.changes` (SSE async iterator) |
115
+ | Export | `db.export` (NDJSON async iterator) |
116
+
117
+ Project, collection catalog, and database catalog IDs are canonical uppercase
118
+ 26-character ULIDs. `generateId()`, `isValidId()` and `requireId()` retain that
119
+ entity-ID contract. Document keys independently accept 1–256 UTF-16 code units,
120
+ without controls or lone surrogates; natural keys, slashes and Unicode travel as
121
+ one query parameter. A root payload `id` is ordinary data unless it equals the
122
+ key; the producer then strips that redundant member.
123
+ Documents return
103
124
  `{ id, version, state: "value", document }`; a causal read can answer
104
125
  `state: "conflict"` with `siblings`, and unknown states pass through. Versions
105
126
  (`tbv1-…`, `tbv2-…`) are opaque tokens. Writes return the version and a
106
- decimal-string commit `offset`; preserve those opaque positions and use
127
+ decimal-string commit `offset`; PATCH also returns the stored `document`.
128
+ Ops PATCH supports top-level `inc`, `add` and `remove` alongside `set`, `unset`
129
+ and `append`. `inc` requires a nonzero signed Int64 integer; set elements are
130
+ JSON scalars of at most 1 KiB under the producer serializer.
131
+ Preserve those opaque positions and use
107
132
  `ifMatch` or `ifNoneMatchAny` for conditional writes.
108
133
 
109
134
  Queries support typed filters, sorting, projection and bounded cursor pages.
110
135
  `query` returns one page; `pages` and `items` follow `nextCursor`.
111
136
  `count.exact: false` means the count is a lower bound. The current C# producer
112
- does not support `lower` paths or `explain`; query number comparisons use its
137
+ does not support `lower` paths or query-body `explain`; query number comparisons use its
113
138
  64-bit integer/double arithmetic, even when the SDK preserves exact JSON numbers.
114
139
  `ExactDecimal` and bigint serialization require Node.js 22+ or a current browser.
115
140
 
141
+ A `near` sort orders by vector distance, nearest first, and adds `distance` to
142
+ each item. It is the only sort key, `metric` is `cosine` (default) or `l2`,
143
+ `limit` is at most 100 and there is one page (no cursor):
144
+
145
+ ```js
146
+ await users.putTtl("/expiresAt"); // getTtl() -> { path: "/expiresAt" }; deleteTtl() clears
147
+ const { items } = await docs.query({
148
+ sort: [{ near: { path: "/embedding", vector: [0.1, 0.2], metric: "cosine" } }], limit: 10,
149
+ });
150
+ ```
151
+
152
+ A collection TTL deletes documents whose member holds a past RFC 3339 UTC time.
153
+ An hourly home-region sweep does the delete, up to about an hour late; until
154
+ then expired documents stay readable.
155
+
116
156
  `db.transaction()` builds one bounded atomic group across collections in that
117
157
  database. It supports document operations, `assert`, `assertAbsent` and
118
158
  `assertCount`; assertions examine the state before the group's writes.
@@ -121,29 +161,130 @@ or replay mutations after an uncertain result; this release does not promise
121
161
  mutation deduplication. Validation, authentication, authorization and
122
162
  precondition failures are not automatically retried.
123
163
 
124
- Shapes require `shapes:read` and use the collection's GET route with a `where`
125
- filter, handle, offset and live cursor. Snapshot bootstrap and checkpoint resume
126
- provide correctness; `must_refetch` requires discarding local state and starting
127
- a fresh snapshot. The C# producer has no shape gatekeeper, SSE route, edge shape
128
- token or projection support. Origin responses require private cache revalidation. Fresh shape bootstrap is
129
- server-only in this release: browsers hide the initial 307 redirect metadata.
130
- Browser callers need a handle and snapshot offset obtained on their server.
164
+ SQL is the producer's bounded read-only subset: `{ matched, truncated, rows }`,
165
+ with row `{ id, value }` and no pagination cursor. `checkSql` returns `ok: false`
166
+ for invalid SQL; `explainSql` returns an HTTP error for invalid SQL. All three
167
+ require `databases:read`, granted by a project access JWT.
131
168
 
132
- The same public SDK supplies this metadata on the server. Pass the position to
133
- the browser and repeat that immutable snapshot page with the identical filter
134
- and collection:
169
+ ```js
170
+ const result = await db.sql("SELECT * FROM todos LIMIT 10");
171
+ const controller = new AbortController();
172
+ for await (const event of db.changes({ cursor: "now", collections: ["todos"] }, {
173
+ signal: controller.signal,
174
+ })) {
175
+ console.log(event);
176
+ // Stop with controller.abort(), or break to close this iterator.
177
+ }
178
+ ```
179
+
180
+ SSE emits `cursor` and `change` events. Cursors are opaque and must retain the
181
+ same collection filter. `lastEventId` takes precedence over `cursor`; normal
182
+ valid EOF reconnects with the latest issued cursor. Delivery is at least once;
183
+ deduplicate by origin, version, collection and id. `document` is its current
184
+ serving value, including null. Network failures, malformed streams, terminal
185
+ errors, denials, expired history (410) and overload (429) propagate. The SDK
186
+ never silently resets to `now` or broadens the view. Iterator `return()` also
187
+ interrupts an already pending read.
188
+
189
+ `db.export()` streams every live document as `{ collection, id, document }`,
190
+ in collection then id order, from one read snapshot (`documents:read`). Lines
191
+ are parsed as they arrive. A stream that ends inside a line throws; resume with
192
+ the last whole document received, which reads a new snapshot:
135
193
 
136
194
  ```js
137
- // Server: use the public client with the caller's shapes:read key.
138
- const snapshot = await serverCollection.shape({ where });
139
- const position = { handle: snapshot.handle, offset: snapshot.offset };
140
- // Browser: resume using position supplied by your application server.
141
- const page = await browserCollection.shape({ where, ...position });
195
+ let last;
196
+ for await (const row of db.export({ after: last, signal: controller.signal })) {
197
+ last = { collection: row.collection, id: row.id };
198
+ }
199
+ ```
200
+
201
+ The exported collection `shape()` remains compatible with the historical
202
+ `6cb9745…` release. Its route is absent from the audited current server source;
203
+ do not use it as current producer evidence. SSE changes are a separate database
204
+ feed, not authorized bounded-query snapshots or the planned reactive WebSocket API.
205
+
206
+ ## Free shape subscriptions (protocol v1)
207
+
208
+ `collection.subscribeShape({ where? }, { onUpdate?, signal? })` follows a collection's
209
+ sealed snapshot, log chunks, and live long-polls. Its `state` is a map from document
210
+ id to `{ version, document }`; `upToDate` becomes true only after a fresh response
211
+ reports `up_to_date`. Each callback sees the complete applied response or a
212
+ freshness change; freshness is cleared while a changed-lineage resume is pending.
213
+
214
+ ```js
215
+ const shape = todos.subscribeShape({ where: v1Filter.eq("/done", false) }, {
216
+ onUpdate(subscription) {
217
+ console.log(subscription.state, subscription.upToDate);
218
+ },
219
+ });
220
+ try {
221
+ await shape.done; // Runs until close(), cancellation, or a terminal error.
222
+ } finally {
223
+ shape.close();
224
+ }
142
225
  ```
143
226
 
144
- Failures throw `TerraBaseV1Error` with the HTTP status and producer error code;
145
- transaction failures may also identify the failing `op`. Request cancellation
146
- uses `AbortSignal`.
227
+ `close()` cancels a pending read. Server errors reject `done` using the existing
228
+ TerraBase error types; malformed responses and network failures also stop it.
229
+ Observe `done` to detect terminal errors. A throwing `onUpdate` stops the
230
+ subscription and rejects `done` with the callback's error; already applied state
231
+ remains available. Calling `close()` or aborting takes precedence over a later
232
+ callback exception and resolves `done`. Document
233
+ upserts replace the prior value and deletes of unknown ids are harmless. Repeated
234
+ events are applied: a sealed value can be newer than its event, including after
235
+ failover. There are no durable local writes or offline mutation queue.
236
+
237
+ The client preserves state for one proven cursor-resume attempt when a different
238
+ machine rejects its handle. It never resumes an incomplete snapshot. A failed
239
+ resume or another `409 must_refetch` clears state and starts a fresh snapshot.
240
+ Opaque resume tokens travel verbatim in the query, or `TB-Shape-Resume` when the
241
+ request target would exceed the protocol limit. Only documented transient
242
+ `shape_busy`, `unavailable`, and `shape_too_large` errors retry with backoff and
243
+ `Retry-After` until success or cancellation; authorization, validation, and
244
+ network errors stop the subscription. The backoff delay is capped at 30 seconds
245
+ unless `Retry-After` requires longer. The maximum signed-64-bit live bucket is
246
+ accepted as a response, as §4 allows, but cannot be sent as the next input;
247
+ `done` rejects with a `TypeError` if that protocol limit is reached.
248
+
249
+ Origin JSON with a leading UTF-8 BOM is rejected by the v1 transport, including
250
+ historical routes; shape v1 §6 requires bytes without a BOM.
251
+ Subscriptions use unconditional reads; they do not send `If-None-Match` or use
252
+ the optional `304` cached-body path.
253
+
254
+ `collection.decryptShapeObject(bytes, { handle, offset, epoch, keyId }, { signal? })`
255
+ fetches the matching epoch key with `cache: "no-store"`, derives the per-object key
256
+ with WebCrypto HKDF, and verifies every AES-256-GCM TBS1 frame before returning a
257
+ page. Keys are cached only in process memory by `(handle, epoch, keyId)`, scoped
258
+ to the credential, database and collection. A key fetch bypasses HTTP caches;
259
+ keys are never persisted. Past epochs are evicted on access as time or the
260
+ latest served epoch advances; historical objects fetch their keys again without
261
+ retaining them. Any `409 must_refetch` on the shape or key route clears that
262
+ collection's key cache. A failed tag, binding, frame, or response validation
263
+ applies nothing. Key ids follow §12's 26 ASCII bytes without assuming a ULID.
264
+ Native browser Fetch hides manual redirect metadata, so subscription bootstrap
265
+ currently requires server fetch. TBS1 decryption uses WebCrypto in either runtime.
266
+
267
+ This implements the [proposed protocol](contracts/shape-v1/shape-reads.md) at
268
+ `993927ce7ecf8f9b889d24d4d1d21ec96eaf9416`, using `documents:read`. HTTP fakes and the
269
+ upstream [conformance vectors](test/fixtures/shape-vectors.json) verify client
270
+ behavior; they do not qualify a producer deployment. Current generated OpenAPI,
271
+ live endpoint availability, and automatic region discovery remain unqualified.
272
+ No TerraBase binary is downloaded or run by these tests. The existing historical
273
+ `shape()` method keeps its contract. Manifest/object delivery and 302 redirects
274
+ are deferred to FR-22; vector `presigned-manifest` is explicitly skipped until its
275
+ delivery contract is ready upstream.
276
+
277
+ Failures throw `TerraBaseV1Error` with status, code, optional transaction `op`,
278
+ parsed `body`, raw `responseText`, response `headers`, and a received
279
+ `X-Request-ID` as `requestId`. The actual producer uses `application/json`
280
+ `{error:{code,message,op,details}}`, not RFC 9457. The SDK preserves RFC 9457
281
+ bodies when received but does not invent producer support or request IDs.
282
+ Cancellation preserves the supplied `AbortSignal` reason.
283
+
284
+ **Browser gate remains red:** Chrome and Edge native fetch resend a buffered
285
+ mutation once after HTTP 421. Node uses one-shot request streams to prevent that
286
+ replay. Browser Fetch has no retry-control option; its one-wire assertions remain
287
+ failing in this draft. See the audit for exact results and producer dependencies.
147
288
 
148
289
  ## Ouroboros and qualification
149
290
 
@@ -212,13 +353,11 @@ selector; both references must be canonical ULIDs. Entity pages reject null and
212
353
  primitive records; recovery-code pages contain strings.
213
354
 
214
355
  `@terrascale/sdk/local` (including `terrascale-local`) and `@terrascale/sdk/postgres` are
215
- **deprecated legacy entrypoints**. SQLite stays opt-in for development only and
216
- refuses CI, production, staging, qualification and deployment environments.
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.
356
+ **deprecated legacy entrypoints**. The operating contract confines fake/local
357
+ stores to test code and test binaries. Their current exported runtime paths
358
+ remain inventoried for removal; this docs change does not remove them.
359
+ Do not use them for application onboarding, production, staging or producer
360
+ qualification. A local adapter test does not qualify the real C# API.
222
361
  The PostgreSQL listener and retired tenant/shard client are outside the default
223
362
  v1 API. Existing framework, schema and SQL entrypoints are separate legacy
224
363
  surfaces; the root entrypoint exposes the C# v1 client API.
@@ -227,4 +366,4 @@ Hosted OAuth resource requests use one exact registered HTTPS `resource`. `oidc.
227
366
 
228
367
  `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.
229
368
 
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.
369
+ 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.3",
3
+ "version": "0.0.5",
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",
@@ -153,5 +156,8 @@
153
156
  "packageManager": "npm@11.18.0",
154
157
  "dependencies": {
155
158
  "ulid": "3.0.2"
159
+ },
160
+ "overrides": {
161
+ "vite": "8.2.4"
156
162
  }
157
163
  }
@@ -0,0 +1,85 @@
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":"DELETE","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/ttl","operation":"deleteCollectionTtl","scopes":["documents:write"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/DeleteCollectionTtlEndpoint.cs","request":"none","producerChange":"TerraScale/terrascale#416"},
49
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/ttl","operation":"getCollectionTtl","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/GetCollectionTtlEndpoint.cs","request":"none","producerChange":"TerraScale/terrascale#416"},
50
+ {"method":"PUT","path":"/v1/projects/{project}/databases/{database}/collections/{collection}/ttl","operation":"putCollectionTtl","scopes":["documents:write"],"requestMediaTypes":["application/json"],"statuses":[200],"responseMediaType":"application/json","source":"src/TerraBase/Features/Documents/PutCollectionTtlEndpoint.cs","request":"CollectionTtlBody","producerChange":"TerraScale/terrascale#416"},
51
+ {"method":"GET","path":"/v1/projects/{project}/databases/{database}/export","operation":"exportDatabase","scopes":["documents:read"],"requestMediaTypes":[],"statuses":[200],"responseMediaType":"application/x-ndjson","source":"src/TerraBase/Features/Documents/ExportDatabaseEndpoint.cs","request":"none","producerChange":"TerraScale/terrascale#412"},
52
+ {"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"},
53
+ {"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"},
54
+ {"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"},
55
+ {"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"},
56
+ {"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"},
57
+ {"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[]"},
58
+ {"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"},
59
+ {"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"},
60
+ {"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"},
61
+ {"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"},
62
+ {"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"},
63
+ {"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"},
64
+ {"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"},
65
+ {"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"},
66
+ {"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"},
67
+ {"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"},
68
+ {"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"},
69
+ {"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"},
70
+ {"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"},
71
+ {"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"},
72
+ {"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"},
73
+ {"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"},
74
+ {"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"},
75
+ {"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"},
76
+ {"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"},
77
+ {"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"},
78
+ {"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"},
79
+ {"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"},
80
+ {"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"},
81
+ {"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"},
82
+ {"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"},
83
+ {"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"}
84
+ ]
85
+ }