@terrascale/sdk 0.0.6 → 0.0.8

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.
@@ -0,0 +1,98 @@
1
+ /** Project file buckets, authenticated by the same token as documents. */
2
+ export class V1FileStorage {
3
+ /** @param {V1Transport} transport @param {FetchLike} fetcher */
4
+ constructor(transport: V1Transport, fetcher: FetchLike);
5
+ /** @param {string} name @param {FileAccessRules} accessRules @param {FileRequestOptions} [options] @returns {Promise<FileBucketInfo>} */
6
+ createBucket(name: string, accessRules: FileAccessRules, options?: FileRequestOptions): Promise<FileBucketInfo>;
7
+ /** @param {FileListOptions} [options] @returns {Promise<{items: FileBucketInfo[], next: string | null}>} */
8
+ listBuckets(options?: FileListOptions): Promise<{
9
+ items: FileBucketInfo[];
10
+ next: string | null;
11
+ }>;
12
+ /** @param {string} id @returns {V1FileBucket} */
13
+ bucket(id: string): V1FileBucket;
14
+ #private;
15
+ }
16
+ /** Immutable files in one project bucket. */
17
+ export class V1FileBucket {
18
+ /** @param {V1Transport} transport @param {FetchLike} fetcher @param {string} bucket */
19
+ constructor(transport: V1Transport, fetcher: FetchLike, bucket: string);
20
+ /** @param {FileAccessRules} accessRules @param {FileRequestOptions} [options] @returns {Promise<FileBucketInfo>} */
21
+ setRules(accessRules: FileAccessRules, options?: FileRequestOptions): Promise<FileBucketInfo>;
22
+ /** @param {FileRequestOptions} [options] @returns {Promise<void>} */
23
+ delete(options?: FileRequestOptions): Promise<void>;
24
+ /** @param {FileUploadRequest} request @param {FileRequestOptions} [options] @returns {Promise<SignedFileUrl>} */
25
+ createUpload(request: FileUploadRequest, options?: FileRequestOptions): Promise<SignedFileUrl>;
26
+ /** @param {string} id @param {FileRequestOptions} [options] @returns {Promise<StoredFile>} */
27
+ completeUpload(id: string, options?: FileRequestOptions): Promise<StoredFile>;
28
+ /** @param {FileListOptions} [options] @returns {Promise<{items: StoredFile[], next: string | null}>} */
29
+ list(options?: FileListOptions): Promise<{
30
+ items: StoredFile[];
31
+ next: string | null;
32
+ }>;
33
+ /** @param {string} id @param {FileRequestOptions} [options] @returns {Promise<SignedFileUrl>} */
34
+ downloadUrl(id: string, options?: FileRequestOptions): Promise<SignedFileUrl>;
35
+ /** @param {string} id @param {FileRequestOptions} [options] @returns {Promise<void>} */
36
+ deleteFile(id: string, options?: FileRequestOptions): Promise<void>;
37
+ /** Hashes a private byte snapshot, uploads it without project credentials, and verifies completion. No retries.
38
+ * @param {string} name @param {Uint8Array | Blob} input @param {FileUploadOptions} options @returns {Promise<StoredFile>} */
39
+ upload(name: string, input: Uint8Array | Blob, options: FileUploadOptions): Promise<StoredFile>;
40
+ /** Fetches file bytes without sending the project token to the object store.
41
+ * @param {string} id @param {FileRequestOptions} [options] @returns {Promise<Blob>} */
42
+ download(id: string, options?: FileRequestOptions): Promise<Blob>;
43
+ #private;
44
+ }
45
+ export type FileAccessPolicy = {
46
+ owner: boolean;
47
+ public: boolean;
48
+ roles: readonly string[];
49
+ };
50
+ export type FileAccessRules = {
51
+ owner: string | null;
52
+ read: FileAccessPolicy;
53
+ write: FileAccessPolicy;
54
+ };
55
+ export type FileBucketInfo = {
56
+ id: string;
57
+ name: string;
58
+ region: string;
59
+ rules: FileAccessRules;
60
+ };
61
+ export type StoredFile = {
62
+ id: string;
63
+ name: string;
64
+ contentType: string;
65
+ size: number;
66
+ sha256: string;
67
+ metadata: JsonObject;
68
+ status: string;
69
+ uploadExpiresAt: string;
70
+ };
71
+ export type SignedFileUrl = {
72
+ id: string;
73
+ url: string;
74
+ expiresAt: string;
75
+ headers: Readonly<Record<string, string>>;
76
+ };
77
+ export type FileUploadRequest = {
78
+ name: string;
79
+ contentType: string;
80
+ size: number;
81
+ sha256: string;
82
+ metadata: JsonObject;
83
+ };
84
+ export type FileRequestOptions = {
85
+ signal?: AbortSignal | undefined;
86
+ };
87
+ export type FileListOptions = {
88
+ after?: string | undefined;
89
+ signal?: AbortSignal | undefined;
90
+ };
91
+ export type FileUploadOptions = {
92
+ metadata: JsonObject;
93
+ contentType?: string | undefined;
94
+ signal?: AbortSignal | undefined;
95
+ };
96
+ import type { V1Transport } from "./transport.js";
97
+ import type { FetchLike } from "../config.js";
98
+ import type { JsonObject } from "./json.js";
@@ -10,6 +10,14 @@ export function isJsonPointer(pointer: unknown): pointer is string;
10
10
  * @returns {V1Path}
11
11
  */
12
12
  export function requirePath(path: V1Path): V1Path;
13
+ /** @param {V1Filter | null | undefined} filter @returns {number} */
14
+ export function searchCount(filter: V1Filter | null | undefined): number;
15
+ /**
16
+ * @param {unknown} lat
17
+ * @param {unknown} lon
18
+ * @returns {void}
19
+ */
20
+ export function requireGeoPoint(lat: unknown, lon: unknown): void;
13
21
  /**
14
22
  * Validates a filter against the query-v1 grammar (operators, arity, paths,
15
23
  * scalar operands, depth 8 and 256 nodes), so a malformed filter fails locally
@@ -100,6 +108,13 @@ export const v1Filter: Readonly<{
100
108
  * @returns {V1Filter}
101
109
  */
102
110
  prefix: (path: V1Path, prefix: string) => V1Filter;
111
+ /**
112
+ * Full-text search on a document member.
113
+ * @param {V1Path} path
114
+ * @param {string} terms
115
+ * @returns {V1Filter}
116
+ */
117
+ search: (path: V1Path, terms: string) => V1Filter;
103
118
  /**
104
119
  * The value is an array containing the scalar.
105
120
  * @param {V1Path} path
@@ -107,6 +122,20 @@ export const v1Filter: Readonly<{
107
122
  * @returns {V1Filter}
108
123
  */
109
124
  contains: (path: V1Path, value: V1Scalar) => V1Filter;
125
+ /**
126
+ * The `{lat, lon}` object at `path` lies within `meters` of the center (haversine, WGS 84 mean radius).
127
+ * @param {string} path JSON Pointer of a `{lat, lon}` point.
128
+ * @param {V1GeoCircle} circle `meters` is more than 0, at most 20000000.
129
+ * @returns {V1Filter}
130
+ */
131
+ withinRadius: (path: string, circle: V1GeoCircle) => V1Filter;
132
+ /**
133
+ * The `{lat, lon}` object at `path` lies in the box; `west > east` crosses the antimeridian.
134
+ * @param {string} path JSON Pointer of a `{lat, lon}` point.
135
+ * @param {V1GeoBox} box
136
+ * @returns {V1Filter}
137
+ */
138
+ withinBox: (path: string, box: V1GeoBox) => V1Filter;
110
139
  }>;
111
140
  /**
112
141
  * A filter or sort path: an RFC 6901 JSON Pointer or "$id".
@@ -144,5 +173,26 @@ export type V1Filter = {
144
173
  readonly prefix: readonly [V1Path, string];
145
174
  } | {
146
175
  readonly contains: readonly [V1Path, V1Scalar];
176
+ } | {
177
+ readonly within: readonly [string, V1GeoCircle | V1GeoBox];
178
+ } | {
179
+ readonly search: readonly [V1Path, string];
180
+ };
181
+ /**
182
+ * Points within `meters` (more than 0, at most 20000000) of a WGS 84 point, by haversine distance.
183
+ */
184
+ export type V1GeoCircle = {
185
+ readonly lat: number;
186
+ readonly lon: number;
187
+ readonly meters: number;
188
+ };
189
+ /**
190
+ * Points in a latitude/longitude box; `west > east` crosses the antimeridian.
191
+ */
192
+ export type V1GeoBox = {
193
+ readonly south: number;
194
+ readonly west: number;
195
+ readonly north: number;
196
+ readonly east: number;
147
197
  };
148
198
  import { ExactDecimal } from "./json.js";
package/types/v1/ids.d.ts CHANGED
@@ -10,8 +10,10 @@ export function requireName(kind: "database" | "collection", name: unknown): str
10
10
  * @returns {import("../ids.js").EntityId}
11
11
  */
12
12
  export function requireProject(project: unknown): import("../ids.js").EntityId;
13
- /** A caller-supplied key is not a generated entity ID. @param {unknown} id @returns {string} */
13
+ /** Every document id is a canonical ULID. @param {unknown} id @returns {string} */
14
14
  export function requireDocumentId(id: unknown): string;
15
+ /** SQL-backed collections can return non-ULID primary keys. @param {unknown} id @returns {string} */
16
+ export function requireStoredId(id: unknown): string;
15
17
  /**
16
18
  * @param {unknown} version
17
19
  * @returns {string}
@@ -27,10 +27,12 @@ export type V1IndexList = ReturnType<typeof indexes>;
27
27
  export type V1AutoIndexPolicy = ReturnType<typeof policy>;
28
28
  export type V1IndexRecommendations = ReturnType<typeof recommendations>;
29
29
  export type V1AppliedIndexRecommendation = ReturnType<typeof applied>;
30
+ export type V1IndexKind = "btree" | "text";
30
31
  export type V1CreateIndexRequest = {
31
32
  readonly collection: string;
32
33
  readonly fields: readonly string[];
33
34
  readonly name?: string | null;
35
+ readonly kind?: V1IndexKind;
34
36
  };
35
37
  import type { V1RequestOptions } from "./terrabase-v1.js";
36
38
  import type { V1Transport } from "./transport.js";
@@ -41,6 +43,7 @@ declare const index: import("./management-decode.js").Decoder<Readonly<{
41
43
  collection: string;
42
44
  fields: readonly string[];
43
45
  state: string;
46
+ kind: string | undefined;
44
47
  }>>;
45
48
  declare const indexes: import("./management-decode.js").Decoder<Readonly<{
46
49
  items: readonly Readonly<{
@@ -48,6 +51,7 @@ declare const indexes: import("./management-decode.js").Decoder<Readonly<{
48
51
  collection: string;
49
52
  fields: readonly string[];
50
53
  state: string;
54
+ kind: string | undefined;
51
55
  }>[];
52
56
  }>>;
53
57
  declare const policy: import("./management-decode.js").Decoder<Readonly<{
@@ -70,6 +74,7 @@ declare const applied: import("./management-decode.js").Decoder<Readonly<{
70
74
  collection: string;
71
75
  fields: readonly string[];
72
76
  state: string;
77
+ kind: string | undefined;
73
78
  }>;
74
79
  }>>;
75
80
  export {};
@@ -6,7 +6,7 @@ export function v1RoutePath(route: V1Route, params: Readonly<Record<string, stri
6
6
  export const v1Routes: readonly V1Route[];
7
7
  /** @type {readonly V1Route[]} */
8
8
  export const shapeV1Routes: readonly V1Route[];
9
- export type V1Operation = import("./management-routes.js").ManagementOperation | "readFreeShape" | "getShapeKey" | "getDocument" | "putDocument" | "createDocument" | "patchDocument" | "deleteDocument" | "commitTransaction" | "queryDocuments" | "createCollection" | "getCollection" | "listCollections" | "dropCollection" | "readShape" | "runSql" | "checkSql" | "explainSql" | "streamDatabaseChanges" | "listDocuments" | "getCollectionSchema" | "putCollectionSchema" | "deleteCollectionSchema" | "createDatabase" | "listDatabases" | "getDatabase" | "updateDatabase" | "deleteDatabase" | "branchDatabase";
9
+ export type V1Operation = import("./file-storage-routes.js").FileStorageOperation | import("./management-routes.js").ManagementOperation | "readFreeShape" | "getShapeKey" | "getDocument" | "putDocument" | "createDocument" | "patchDocument" | "deleteDocument" | "commitTransaction" | "queryDocuments" | "createCollection" | "getCollection" | "listCollections" | "dropCollection" | "readShape" | "runSql" | "checkSql" | "explainSql" | "streamDatabaseChanges" | "listDocuments" | "getCollectionSchema" | "putCollectionSchema" | "deleteCollectionSchema" | "createDatabase" | "listDatabases" | "getDatabase" | "updateDatabase" | "deleteDatabase" | "branchDatabase";
10
10
  export type V1Route = {
11
11
  operation: V1Operation;
12
12
  method: "GET" | "PUT" | "POST" | "PATCH" | "DELETE";
@@ -0,0 +1,8 @@
1
+ /** @import { V1ShapeReplicaStore } from "./shape-subscription.js" */
2
+ /**
3
+ * A V1ShapeReplicaStore kept in browser IndexedDB, one record per key.
4
+ * @param {string} key Names one subject's shape, e.g. `${userId}/notes/open`; clear it on sign-out.
5
+ * @returns {V1ShapeReplicaStore}
6
+ */
7
+ export function indexedDbShapeReplica(key: string): V1ShapeReplicaStore;
8
+ import type { V1ShapeReplicaStore } from "./shape-subscription.js";
@@ -25,6 +25,21 @@ export type V1ShapeSubscribeOptions = {
25
25
  * Runs after validated responses and freshness changes; throwing rejects `done` unless already closed or aborted.
26
26
  */
27
27
  onUpdate?: ((subscription: V1ShapeSubscription) => void) | undefined;
28
+ /**
29
+ * Keeps the last resumable state for reads across restarts and while offline; writes still go to the server.
30
+ */
31
+ replica?: V1ShapeReplicaStore | undefined;
32
+ };
33
+ /**
34
+ * Holds one subscription's state as exact JSON text, e.g. in IndexedDB or React Native storage. Scope one store
35
+ * to one signed-in subject: the replica holds that subject's authorized documents. A failing store rejects `done`.
36
+ */
37
+ export type V1ShapeReplicaStore = {
38
+ load: () => string | undefined | Promise<string | undefined>;
39
+ /**
40
+ * Receives undefined after must_refetch discards state.
41
+ */
42
+ save: (text: string | undefined) => void | Promise<void>;
28
43
  };
29
44
  export type V1ShapeDocument = {
30
45
  readonly version: string;
@@ -341,6 +341,8 @@ export class TerraBaseV1Client {
341
341
  database(name: string): V1Database;
342
342
  /** @returns {V1Databases} Project-scoped database catalog. */
343
343
  get databases(): V1Databases;
344
+ /** @returns {V1FileStorage} Project file buckets. */
345
+ get storage(): V1FileStorage;
344
346
  /** @returns {V1SavedQueries} */
345
347
  get savedQueries(): V1SavedQueries;
346
348
  /** @returns {V1ProjectUsageClient} */
@@ -438,7 +440,67 @@ export type V1NearSortKey = {
438
440
  readonly metric?: "cosine" | "l2" | undefined;
439
441
  };
440
442
  };
441
- export type V1SortKey = V1FieldSortKey | V1NearSortKey;
443
+ /**
444
+ * Geo distance sort: meters from a WGS 84 point to each document's `{lat, lon}` object at `path`, nearest first,
445
+ * returned as `distance`. Like the vector `near`, it is the only sort key, limit is at most 100 and there is no cursor.
446
+ */
447
+ export type V1GeoNearSortKey = {
448
+ readonly near: {
449
+ readonly path: string;
450
+ readonly lat: number;
451
+ readonly lon: number;
452
+ };
453
+ };
454
+ /**
455
+ * Relevance order, only sort key with exactly one search predicate.
456
+ */
457
+ export type V1ScoreSortKey = {
458
+ readonly path: "$score";
459
+ readonly order: "desc";
460
+ };
461
+ export type V1SortKey = V1FieldSortKey | V1NearSortKey | V1GeoNearSortKey | V1ScoreSortKey;
462
+ /**
463
+ * Groups matches instead of returning documents. Summaries consider numbers only; at most 16 summary paths in total.
464
+ */
465
+ export type V1Aggregate = {
466
+ /**
467
+ * 0-4 paths; without it every match is one group.
468
+ */
469
+ groupBy?: readonly V1Path[] | undefined;
470
+ /**
471
+ * Distinct JSON Pointers.
472
+ */
473
+ sum?: readonly string[] | undefined;
474
+ /**
475
+ * Distinct JSON Pointers.
476
+ */
477
+ avg?: readonly string[] | undefined;
478
+ /**
479
+ * Distinct JSON Pointers.
480
+ */
481
+ min?: readonly string[] | undefined;
482
+ /**
483
+ * Distinct JSON Pointers.
484
+ */
485
+ max?: readonly string[] | undefined;
486
+ };
487
+ /**
488
+ * One aggregate group. Summaries are keyed by the requested JSON Pointer; `sum` is 0 and the others null without numbers.
489
+ */
490
+ export type V1Group = {
491
+ /**
492
+ * One value per `groupBy` path (missing members group as null).
493
+ */
494
+ key: readonly JsonValue[];
495
+ /**
496
+ * Matching documents in the group (decimal u64).
497
+ */
498
+ count: string;
499
+ sum?: Readonly<Record<string, number | null>> | undefined;
500
+ avg?: Readonly<Record<string, number | null>> | undefined;
501
+ min?: Readonly<Record<string, number | null>> | undefined;
502
+ max?: Readonly<Record<string, number | null>> | undefined;
503
+ };
442
504
  /**
443
505
  * A query-v1 request. Every member is optional.
444
506
  */
@@ -464,6 +526,10 @@ export type V1Query = {
464
526
  * Count every match (first page only).
465
527
  */
466
528
  count?: boolean | undefined;
529
+ /**
530
+ * Answer `groups` instead of items; `limit` bounds the groups. No sort, project, cursor or count.
531
+ */
532
+ aggregate?: V1Aggregate | undefined;
467
533
  };
468
534
  export type V1Count = {
469
535
  readonly value: string;
@@ -476,6 +542,10 @@ export type V1QueryPage = {
476
542
  items: readonly V1Document[];
477
543
  nextCursor: string | null;
478
544
  count: V1Count | undefined;
545
+ /**
546
+ * An aggregate query's groups in key order (`items` is then empty).
547
+ */
548
+ groups: readonly V1Group[] | undefined;
479
549
  };
480
550
  export type V1Precondition = {
481
551
  readonly ifMatch: string;
@@ -524,6 +594,7 @@ import { V1DatabaseUsageClient } from "./usage.js";
524
594
  import { V1Indexes } from "./indexes.js";
525
595
  import { V1DatabaseSchemaClient } from "./database-schema.js";
526
596
  import { V1Databases } from "./catalog.js";
597
+ import { V1FileStorage } from "./file-storage.js";
527
598
  import { V1SavedQueries } from "./saved-queries.js";
528
599
  import { V1ProjectUsageClient } from "./usage.js";
529
600
  import { V1BackupDestinationClient } from "./backups.js";
@@ -23,6 +23,15 @@ export class BodyTransportError extends Error {
23
23
  /** @param {unknown} cause */
24
24
  constructor(cause: unknown);
25
25
  }
26
+ /** A request that failed in transit before any response; the native failure is the cause. */
27
+ export class RequestTransportError extends TypeError {
28
+ /** @param {unknown} cause */
29
+ constructor(cause: unknown);
30
+ }
31
+ /** A browser hid a 307 behind an opaque redirect; only the shape bootstrap may follow it. */
32
+ export class OpaqueRedirectError extends TypeError {
33
+ constructor();
34
+ }
26
35
  /** Internal transport bound to one project credential. */
27
36
  export class V1Transport {
28
37
  /**
@@ -128,11 +137,19 @@ export type V1CallOptions = {
128
137
  * Authenticated shape epoch keys must bypass caches.
129
138
  */
130
139
  cache?: "no-store" | undefined;
140
+ /**
141
+ * Only the shape bootstrap, after a browser hides its 307 behind an opaque redirect.
142
+ */
143
+ redirect?: "follow" | undefined;
131
144
  };
132
145
  export type V1CallResult = {
133
146
  status: number;
134
147
  headers: Headers;
135
148
  value: JsonValue | undefined;
149
+ /**
150
+ * The final URL after a followed redirect.
151
+ */
152
+ redirectedTo?: string | undefined;
136
153
  };
137
154
  import type { V1Operation } from "./routes.js";
138
155
  import type { JsonValue } from "./json.js";
@@ -63,6 +63,7 @@ declare const projectUsage: import("./management-decode.js").Decoder<Readonly<{
63
63
  databases: number | import("./json.js").ExactDecimal;
64
64
  storageBytes: number | import("./json.js").ExactDecimal;
65
65
  logicalBytes: number | import("./json.js").ExactDecimal;
66
+ fileBytes: number | import("./json.js").ExactDecimal;
66
67
  documents: number | import("./json.js").ExactDecimal;
67
68
  reads: number | import("./json.js").ExactDecimal;
68
69
  writes: number | import("./json.js").ExactDecimal;