@spacelr/sdk 0.5.0 → 0.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -1
- package/dist/index.d.mts +186 -5
- package/dist/index.d.ts +186 -5
- package/dist/index.js +197 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +189 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -22,9 +22,13 @@ var index_exports = {};
|
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
BrowserTokenStorage: () => BrowserTokenStorage,
|
|
24
24
|
CodeChallengeMethod: () => CodeChallengeMethod,
|
|
25
|
+
CursorInvalidError: () => CursorInvalidError,
|
|
25
26
|
FileVisibility: () => FileVisibility,
|
|
27
|
+
ForbiddenError: () => ForbiddenError,
|
|
26
28
|
GrantType: () => GrantType,
|
|
27
29
|
MemoryTokenStorage: () => MemoryTokenStorage,
|
|
30
|
+
NotFoundError: () => NotFoundError,
|
|
31
|
+
ServerConfigError: () => ServerConfigError,
|
|
28
32
|
SharePermission: () => SharePermission,
|
|
29
33
|
SpacelrAuthError: () => SpacelrAuthError,
|
|
30
34
|
SpacelrEmailVerificationRequiredError: () => SpacelrEmailVerificationRequiredError,
|
|
@@ -33,6 +37,10 @@ __export(index_exports, {
|
|
|
33
37
|
SpacelrSearchFilterRequiredError: () => SpacelrSearchFilterRequiredError,
|
|
34
38
|
SpacelrTimeoutError: () => SpacelrTimeoutError,
|
|
35
39
|
SpacelrTwoFactorRequiredError: () => SpacelrTwoFactorRequiredError,
|
|
40
|
+
TimelineError: () => TimelineError,
|
|
41
|
+
TimelineModule: () => TimelineModule,
|
|
42
|
+
TimeoutError: () => TimeoutError,
|
|
43
|
+
ValidationError: () => ValidationError,
|
|
36
44
|
createClient: () => createClient,
|
|
37
45
|
generatePKCEChallenge: () => generatePKCEChallenge,
|
|
38
46
|
localStorageCursorStorage: () => localStorageCursorStorage,
|
|
@@ -1819,6 +1827,144 @@ var StorageModule = class {
|
|
|
1819
1827
|
}
|
|
1820
1828
|
};
|
|
1821
1829
|
|
|
1830
|
+
// libs/sdk/src/modules/timeline.errors.ts
|
|
1831
|
+
var TimelineError = class extends SpacelrError {
|
|
1832
|
+
constructor(message, opts = {}) {
|
|
1833
|
+
super(message, opts.code ?? "TIMELINE_ERROR", opts.statusCode);
|
|
1834
|
+
this.name = "TimelineError";
|
|
1835
|
+
}
|
|
1836
|
+
};
|
|
1837
|
+
var CursorInvalidError = class extends TimelineError {
|
|
1838
|
+
constructor(message, opts = {}) {
|
|
1839
|
+
super(message, { statusCode: opts.statusCode ?? 400, code: opts.code ?? "CURSOR_INVALID" });
|
|
1840
|
+
this.name = "CursorInvalidError";
|
|
1841
|
+
}
|
|
1842
|
+
};
|
|
1843
|
+
var ValidationError = class extends TimelineError {
|
|
1844
|
+
constructor(message, opts = {}) {
|
|
1845
|
+
super(message, { statusCode: opts.statusCode ?? 400, code: opts.code ?? "BAD_REQUEST" });
|
|
1846
|
+
this.name = "ValidationError";
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
var ForbiddenError = class extends TimelineError {
|
|
1850
|
+
constructor(message, opts = {}) {
|
|
1851
|
+
super(message, { statusCode: opts.statusCode ?? 403, code: opts.code ?? "FORBIDDEN" });
|
|
1852
|
+
this.name = "ForbiddenError";
|
|
1853
|
+
}
|
|
1854
|
+
};
|
|
1855
|
+
var NotFoundError = class extends TimelineError {
|
|
1856
|
+
constructor(message, opts = {}) {
|
|
1857
|
+
super(message, { statusCode: opts.statusCode ?? 404, code: opts.code ?? "NOT_FOUND" });
|
|
1858
|
+
this.name = "NotFoundError";
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
var ServerConfigError = class extends TimelineError {
|
|
1862
|
+
constructor(message, opts = {}) {
|
|
1863
|
+
super(message, { statusCode: opts.statusCode ?? 500, code: opts.code ?? "CONFIG_INVALID" });
|
|
1864
|
+
this.name = "ServerConfigError";
|
|
1865
|
+
}
|
|
1866
|
+
};
|
|
1867
|
+
var TimeoutError = class extends TimelineError {
|
|
1868
|
+
constructor(message, opts = {}) {
|
|
1869
|
+
super(message, { statusCode: opts.statusCode ?? 504, code: opts.code ?? "TIMEOUT" });
|
|
1870
|
+
this.name = "TimeoutError";
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
function mapTimelineError(statusCode, body) {
|
|
1874
|
+
const code = body?.code;
|
|
1875
|
+
const message = body?.message ?? `Timeline request failed with HTTP ${statusCode}`;
|
|
1876
|
+
if (statusCode === 400) {
|
|
1877
|
+
if (code === "CURSOR_INVALID") {
|
|
1878
|
+
return new CursorInvalidError(message, { statusCode, code });
|
|
1879
|
+
}
|
|
1880
|
+
return new ValidationError(message, { statusCode, code });
|
|
1881
|
+
}
|
|
1882
|
+
if (statusCode === 403) {
|
|
1883
|
+
return new ForbiddenError(message, { statusCode, code });
|
|
1884
|
+
}
|
|
1885
|
+
if (statusCode === 404) {
|
|
1886
|
+
return new NotFoundError(message, { statusCode, code });
|
|
1887
|
+
}
|
|
1888
|
+
if (statusCode === 500) {
|
|
1889
|
+
return new ServerConfigError(message, { statusCode, code });
|
|
1890
|
+
}
|
|
1891
|
+
if (statusCode === 504) {
|
|
1892
|
+
return new TimeoutError(message, { statusCode, code });
|
|
1893
|
+
}
|
|
1894
|
+
return new TimelineError(message, { statusCode, code });
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
// libs/sdk/src/modules/timeline.module.ts
|
|
1898
|
+
var TimelineModule = class {
|
|
1899
|
+
constructor(http) {
|
|
1900
|
+
this.http = http;
|
|
1901
|
+
}
|
|
1902
|
+
async query(opts) {
|
|
1903
|
+
const body = {
|
|
1904
|
+
collection: opts.collection,
|
|
1905
|
+
partitionValue: opts.partitionValue
|
|
1906
|
+
};
|
|
1907
|
+
if (opts.where !== void 0) body["where"] = opts.where;
|
|
1908
|
+
if (opts.orderBy !== void 0) body["orderBy"] = opts.orderBy;
|
|
1909
|
+
if (opts.limit !== void 0) body["limit"] = opts.limit;
|
|
1910
|
+
if (opts.cursor !== void 0) body["cursor"] = opts.cursor;
|
|
1911
|
+
let raw;
|
|
1912
|
+
try {
|
|
1913
|
+
raw = await this.http.request({
|
|
1914
|
+
method: "POST",
|
|
1915
|
+
path: "/db/timeline",
|
|
1916
|
+
body,
|
|
1917
|
+
authenticated: true
|
|
1918
|
+
});
|
|
1919
|
+
} catch (err) {
|
|
1920
|
+
throw this.translateError(err);
|
|
1921
|
+
}
|
|
1922
|
+
if (!isTimelineQueryResponse(raw)) {
|
|
1923
|
+
throw new TimelineError(
|
|
1924
|
+
"Timeline gateway returned a response shape the SDK does not recognise",
|
|
1925
|
+
{ statusCode: 500, code: "INVALID_RESPONSE_SHAPE" }
|
|
1926
|
+
);
|
|
1927
|
+
}
|
|
1928
|
+
return raw;
|
|
1929
|
+
}
|
|
1930
|
+
translateError(err) {
|
|
1931
|
+
if (err instanceof SpacelrTimeoutError) {
|
|
1932
|
+
return new TimeoutError(err.message, { statusCode: 504, code: "TIMEOUT" });
|
|
1933
|
+
}
|
|
1934
|
+
if (err instanceof SpacelrAuthError) {
|
|
1935
|
+
if (err.statusCode === 403) {
|
|
1936
|
+
return new ForbiddenError(err.message, { statusCode: 403, code: err.code ?? "FORBIDDEN" });
|
|
1937
|
+
}
|
|
1938
|
+
return err;
|
|
1939
|
+
}
|
|
1940
|
+
if (err instanceof SpacelrNetworkError) {
|
|
1941
|
+
return err;
|
|
1942
|
+
}
|
|
1943
|
+
if (err instanceof SpacelrError) {
|
|
1944
|
+
return mapTimelineError(err.statusCode ?? 0, { code: err.code, message: err.message });
|
|
1945
|
+
}
|
|
1946
|
+
return err;
|
|
1947
|
+
}
|
|
1948
|
+
};
|
|
1949
|
+
function isTimelineQueryResponse(value) {
|
|
1950
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1951
|
+
const v = value;
|
|
1952
|
+
if (!Array.isArray(v["items"])) return false;
|
|
1953
|
+
if (v["nextCursor"] !== null && typeof v["nextCursor"] !== "string") return false;
|
|
1954
|
+
if (!isTimelineSourceStats(v["sourceStats"])) return false;
|
|
1955
|
+
return true;
|
|
1956
|
+
}
|
|
1957
|
+
function isTimelineSourceStats(value) {
|
|
1958
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1959
|
+
const v = value;
|
|
1960
|
+
if (typeof v["hot"] !== "number") return false;
|
|
1961
|
+
if (typeof v["cold"] !== "number") return false;
|
|
1962
|
+
if (v["segmentsScanned"] !== void 0 && typeof v["segmentsScanned"] !== "number") {
|
|
1963
|
+
return false;
|
|
1964
|
+
}
|
|
1965
|
+
return true;
|
|
1966
|
+
}
|
|
1967
|
+
|
|
1822
1968
|
// libs/sdk/src/modules/database.module.ts
|
|
1823
1969
|
var Paginator = class {
|
|
1824
1970
|
constructor(http, basePath, opts) {
|
|
@@ -2002,6 +2148,16 @@ var CollectionRef = class {
|
|
|
2002
2148
|
authenticated: true
|
|
2003
2149
|
});
|
|
2004
2150
|
}
|
|
2151
|
+
/**
|
|
2152
|
+
* Query the collection's **hot tier** (live MongoDB).
|
|
2153
|
+
*
|
|
2154
|
+
* **Cold-tier note:** if the collection has cold-tier archival enabled, aged
|
|
2155
|
+
* documents are moved to object storage and purged from the hot tier — they
|
|
2156
|
+
* will NOT appear in `find()` results (nor `findById`, `count`, `search`,
|
|
2157
|
+
* `paginate`, which are all hot-tier only). To read archived history, use
|
|
2158
|
+
* {@link TimelineModule.query} via `db.timeline.query(...)`, which transparently
|
|
2159
|
+
* merges hot and cold results for a partition.
|
|
2160
|
+
*/
|
|
2005
2161
|
find(filter) {
|
|
2006
2162
|
return new QueryBuilder(this.http, this.basePath, filter);
|
|
2007
2163
|
}
|
|
@@ -2036,6 +2192,9 @@ var CollectionRef = class {
|
|
|
2036
2192
|
*
|
|
2037
2193
|
* Limits: `query` 1–200 chars, `fields` 1–10 entries (each matching
|
|
2038
2194
|
* `/^[a-zA-Z0-9_.]+$/`, max 64 chars), `limit` max 100.
|
|
2195
|
+
*
|
|
2196
|
+
* **Cold-tier note:** searches the hot tier only; archived documents are not
|
|
2197
|
+
* included. See {@link CollectionRef.find} and `db.timeline.query(...)`.
|
|
2039
2198
|
*/
|
|
2040
2199
|
async search(opts) {
|
|
2041
2200
|
return this.http.request({
|
|
@@ -2045,6 +2204,13 @@ var CollectionRef = class {
|
|
|
2045
2204
|
authenticated: true
|
|
2046
2205
|
});
|
|
2047
2206
|
}
|
|
2207
|
+
/**
|
|
2208
|
+
* Fetch a single document by `_id` from the **hot tier**.
|
|
2209
|
+
*
|
|
2210
|
+
* **Cold-tier note:** returns null/throws for documents that have been
|
|
2211
|
+
* archived and purged from the hot tier. Archived history is reachable only
|
|
2212
|
+
* via `db.timeline.query(...)`. See {@link CollectionRef.find}.
|
|
2213
|
+
*/
|
|
2048
2214
|
async findById(id, options) {
|
|
2049
2215
|
const query = {};
|
|
2050
2216
|
if (options?.populate?.length) {
|
|
@@ -2074,6 +2240,13 @@ var CollectionRef = class {
|
|
|
2074
2240
|
authenticated: true
|
|
2075
2241
|
});
|
|
2076
2242
|
}
|
|
2243
|
+
/**
|
|
2244
|
+
* Count documents in the **hot tier** matching `filter`.
|
|
2245
|
+
*
|
|
2246
|
+
* **Cold-tier note:** counts hot-tier documents only — archived/purged
|
|
2247
|
+
* documents are not included, so this is not a total-history count. See
|
|
2248
|
+
* {@link CollectionRef.find} and `db.timeline.query(...)`.
|
|
2249
|
+
*/
|
|
2077
2250
|
async count(filter) {
|
|
2078
2251
|
const result = await this.http.request({
|
|
2079
2252
|
method: "POST",
|
|
@@ -2509,6 +2682,7 @@ var DatabaseModule = class {
|
|
|
2509
2682
|
this.http = http;
|
|
2510
2683
|
this.projectId = projectId;
|
|
2511
2684
|
this.realtime = realtime ?? null;
|
|
2685
|
+
this.timeline = new TimelineModule(http);
|
|
2512
2686
|
}
|
|
2513
2687
|
collection(name) {
|
|
2514
2688
|
return new CollectionRef(this.http, this.realtime, this.projectId, name);
|
|
@@ -2573,7 +2747,7 @@ var NotificationsModule = class {
|
|
|
2573
2747
|
authenticated: true
|
|
2574
2748
|
});
|
|
2575
2749
|
}
|
|
2576
|
-
/** Register a push subscription (web, android, or
|
|
2750
|
+
/** Register a push subscription (web, android, ios, or web-fcm) */
|
|
2577
2751
|
async subscribe(subscription, deviceName) {
|
|
2578
2752
|
return this.http.request({
|
|
2579
2753
|
method: "POST",
|
|
@@ -2659,6 +2833,20 @@ var NotificationsModule = class {
|
|
|
2659
2833
|
deviceName
|
|
2660
2834
|
);
|
|
2661
2835
|
}
|
|
2836
|
+
/**
|
|
2837
|
+
* Registers a web Firebase Cloud Messaging registration token (obtained via
|
|
2838
|
+
* the Firebase JS SDK `getToken()`), so `notifications.send` delivers to this
|
|
2839
|
+
* browser through the project's FCM provider instead of VAPID WebPush.
|
|
2840
|
+
*/
|
|
2841
|
+
async registerWebFcm(fcmToken, deviceName) {
|
|
2842
|
+
return this.subscribe(
|
|
2843
|
+
{
|
|
2844
|
+
platform: "web-fcm",
|
|
2845
|
+
deviceToken: fcmToken
|
|
2846
|
+
},
|
|
2847
|
+
deviceName
|
|
2848
|
+
);
|
|
2849
|
+
}
|
|
2662
2850
|
urlBase64ToUint8Array(base64String) {
|
|
2663
2851
|
const padding = "=".repeat((4 - base64String.length % 4) % 4);
|
|
2664
2852
|
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
|
|
@@ -2819,9 +3007,13 @@ function createClient(config) {
|
|
|
2819
3007
|
0 && (module.exports = {
|
|
2820
3008
|
BrowserTokenStorage,
|
|
2821
3009
|
CodeChallengeMethod,
|
|
3010
|
+
CursorInvalidError,
|
|
2822
3011
|
FileVisibility,
|
|
3012
|
+
ForbiddenError,
|
|
2823
3013
|
GrantType,
|
|
2824
3014
|
MemoryTokenStorage,
|
|
3015
|
+
NotFoundError,
|
|
3016
|
+
ServerConfigError,
|
|
2825
3017
|
SharePermission,
|
|
2826
3018
|
SpacelrAuthError,
|
|
2827
3019
|
SpacelrEmailVerificationRequiredError,
|
|
@@ -2830,6 +3022,10 @@ function createClient(config) {
|
|
|
2830
3022
|
SpacelrSearchFilterRequiredError,
|
|
2831
3023
|
SpacelrTimeoutError,
|
|
2832
3024
|
SpacelrTwoFactorRequiredError,
|
|
3025
|
+
TimelineError,
|
|
3026
|
+
TimelineModule,
|
|
3027
|
+
TimeoutError,
|
|
3028
|
+
ValidationError,
|
|
2833
3029
|
createClient,
|
|
2834
3030
|
generatePKCEChallenge,
|
|
2835
3031
|
localStorageCursorStorage,
|