@deployowl/nosql 2.2.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.
- package/README.md +107 -0
- package/dist/index.d.mts +49 -0
- package/dist/index.d.ts +49 -0
- package/dist/index.js +520 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +498 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +30 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/index.ts
|
|
9
|
+
function getCrypto() {
|
|
10
|
+
if (typeof globalThis !== "undefined" && globalThis.crypto) {
|
|
11
|
+
return globalThis.crypto;
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const nodeCrypto = typeof __require !== "undefined" ? __require("crypto") : null;
|
|
15
|
+
if (nodeCrypto && nodeCrypto.webcrypto) {
|
|
16
|
+
return nodeCrypto.webcrypto;
|
|
17
|
+
}
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
throw new Error("Web Crypto API not available in this environment");
|
|
21
|
+
}
|
|
22
|
+
function arrayBufferToBase64Url(buffer) {
|
|
23
|
+
const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
24
|
+
let binary = "";
|
|
25
|
+
for (let i = 0; i < bytes.byteLength; i++) {
|
|
26
|
+
binary += String.fromCharCode(bytes[i]);
|
|
27
|
+
}
|
|
28
|
+
const base64 = typeof btoa !== "undefined" ? btoa(binary) : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
|
|
29
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
30
|
+
}
|
|
31
|
+
function base64UrlToArrayBuffer(base64url) {
|
|
32
|
+
const base64 = base64url.replace(/-/g, "+").replace(/_/g, "/") + "=".repeat((4 - base64url.length % 4) % 4);
|
|
33
|
+
const binary = typeof atob !== "undefined" ? atob(base64) : Buffer.from(base64, "base64").toString("binary");
|
|
34
|
+
const bytes = new Uint8Array(binary.length);
|
|
35
|
+
for (let i = 0; i < binary.length; i++) {
|
|
36
|
+
bytes[i] = binary.charCodeAt(i);
|
|
37
|
+
}
|
|
38
|
+
return bytes;
|
|
39
|
+
}
|
|
40
|
+
async function deriveKey(apiKey) {
|
|
41
|
+
const crypto = getCrypto();
|
|
42
|
+
const encoder = new TextEncoder();
|
|
43
|
+
const apiBytes = encoder.encode(apiKey);
|
|
44
|
+
const hash = await crypto.subtle.digest("SHA-256", apiBytes);
|
|
45
|
+
const keyBytes = new Uint8Array(hash, 0, 16);
|
|
46
|
+
return await crypto.subtle.importKey(
|
|
47
|
+
"raw",
|
|
48
|
+
keyBytes,
|
|
49
|
+
{ name: "AES-CTR" },
|
|
50
|
+
false,
|
|
51
|
+
["encrypt", "decrypt"]
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
async function encryptRoute(path, apiKey) {
|
|
55
|
+
const crypto = getCrypto();
|
|
56
|
+
const key = await deriveKey(apiKey);
|
|
57
|
+
const iv = crypto.getRandomValues(new Uint8Array(16));
|
|
58
|
+
const encoder = new TextEncoder();
|
|
59
|
+
const pathBytes = encoder.encode(path);
|
|
60
|
+
const ciphertext = await crypto.subtle.encrypt(
|
|
61
|
+
{
|
|
62
|
+
name: "AES-CTR",
|
|
63
|
+
counter: iv,
|
|
64
|
+
length: 64
|
|
65
|
+
},
|
|
66
|
+
key,
|
|
67
|
+
pathBytes
|
|
68
|
+
);
|
|
69
|
+
const combined = new Uint8Array(iv.length + ciphertext.byteLength);
|
|
70
|
+
combined.set(iv, 0);
|
|
71
|
+
combined.set(new Uint8Array(ciphertext), iv.length);
|
|
72
|
+
return arrayBufferToBase64Url(combined);
|
|
73
|
+
}
|
|
74
|
+
async function decryptRoute(token, apiKey) {
|
|
75
|
+
const crypto = getCrypto();
|
|
76
|
+
const key = await deriveKey(apiKey);
|
|
77
|
+
const combined = base64UrlToArrayBuffer(token);
|
|
78
|
+
if (combined.byteLength < 16) {
|
|
79
|
+
throw new Error("Invalid token length");
|
|
80
|
+
}
|
|
81
|
+
const iv = combined.slice(0, 16);
|
|
82
|
+
const ciphertext = combined.slice(16);
|
|
83
|
+
const decrypted = await crypto.subtle.decrypt(
|
|
84
|
+
{
|
|
85
|
+
name: "AES-CTR",
|
|
86
|
+
counter: new Uint8Array(iv),
|
|
87
|
+
length: 64
|
|
88
|
+
},
|
|
89
|
+
key,
|
|
90
|
+
ciphertext
|
|
91
|
+
);
|
|
92
|
+
return new TextDecoder().decode(decrypted);
|
|
93
|
+
}
|
|
94
|
+
var MessagePack = class {
|
|
95
|
+
static serialize(value) {
|
|
96
|
+
const chunks = [];
|
|
97
|
+
function encode(v) {
|
|
98
|
+
if (v === null || v === void 0) {
|
|
99
|
+
chunks.push(new Uint8Array([192]));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (typeof v === "boolean") {
|
|
103
|
+
chunks.push(new Uint8Array([v ? 195 : 194]));
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (typeof v === "number") {
|
|
107
|
+
if (Number.isInteger(v)) {
|
|
108
|
+
if (v >= 0 && v <= 127) {
|
|
109
|
+
chunks.push(new Uint8Array([v]));
|
|
110
|
+
} else if (v < 0 && v >= -32) {
|
|
111
|
+
chunks.push(new Uint8Array([224 | v + 32]));
|
|
112
|
+
} else if (v >= 0 && v <= 255) {
|
|
113
|
+
chunks.push(new Uint8Array([204, v]));
|
|
114
|
+
} else if (v >= 0 && v <= 65535) {
|
|
115
|
+
chunks.push(new Uint8Array([205, v >> 8 & 255, v & 255]));
|
|
116
|
+
} else if (v >= 0 && v <= 4294967295) {
|
|
117
|
+
const buf = new Uint8Array(5);
|
|
118
|
+
buf[0] = 206;
|
|
119
|
+
new DataView(buf.buffer).setUint32(1, v, false);
|
|
120
|
+
chunks.push(buf);
|
|
121
|
+
} else {
|
|
122
|
+
const buf = new Uint8Array(5);
|
|
123
|
+
buf[0] = 210;
|
|
124
|
+
new DataView(buf.buffer).setInt32(1, v, false);
|
|
125
|
+
chunks.push(buf);
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
const buf = new Uint8Array(9);
|
|
129
|
+
buf[0] = 203;
|
|
130
|
+
new DataView(buf.buffer).setFloat64(1, v, false);
|
|
131
|
+
chunks.push(buf);
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (typeof v === "string") {
|
|
136
|
+
const utf8 = new TextEncoder().encode(v);
|
|
137
|
+
const len = utf8.length;
|
|
138
|
+
if (len <= 31) {
|
|
139
|
+
chunks.push(new Uint8Array([160 | len]));
|
|
140
|
+
} else if (len <= 255) {
|
|
141
|
+
chunks.push(new Uint8Array([217, len]));
|
|
142
|
+
} else if (len <= 65535) {
|
|
143
|
+
chunks.push(new Uint8Array([218, len >> 8 & 255, len & 255]));
|
|
144
|
+
} else {
|
|
145
|
+
const buf = new Uint8Array(5);
|
|
146
|
+
buf[0] = 219;
|
|
147
|
+
new DataView(buf.buffer).setUint32(1, len, false);
|
|
148
|
+
chunks.push(buf);
|
|
149
|
+
}
|
|
150
|
+
chunks.push(utf8);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (Array.isArray(v)) {
|
|
154
|
+
const len = v.length;
|
|
155
|
+
if (len <= 15) {
|
|
156
|
+
chunks.push(new Uint8Array([144 | len]));
|
|
157
|
+
} else if (len <= 65535) {
|
|
158
|
+
chunks.push(new Uint8Array([220, len >> 8 & 255, len & 255]));
|
|
159
|
+
} else {
|
|
160
|
+
const buf = new Uint8Array(5);
|
|
161
|
+
buf[0] = 221;
|
|
162
|
+
new DataView(buf.buffer).setUint32(1, len, false);
|
|
163
|
+
chunks.push(buf);
|
|
164
|
+
}
|
|
165
|
+
for (const item of v) {
|
|
166
|
+
encode(item);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
if (typeof v === "object") {
|
|
171
|
+
const keys = Object.keys(v);
|
|
172
|
+
const len = keys.length;
|
|
173
|
+
if (len <= 15) {
|
|
174
|
+
chunks.push(new Uint8Array([128 | len]));
|
|
175
|
+
} else if (len <= 65535) {
|
|
176
|
+
chunks.push(new Uint8Array([222, len >> 8 & 255, len & 255]));
|
|
177
|
+
} else {
|
|
178
|
+
const buf = new Uint8Array(5);
|
|
179
|
+
buf[0] = 223;
|
|
180
|
+
new DataView(buf.buffer).setUint32(1, len, false);
|
|
181
|
+
chunks.push(buf);
|
|
182
|
+
}
|
|
183
|
+
for (const key of keys) {
|
|
184
|
+
encode(key);
|
|
185
|
+
encode(v[key]);
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
encode(value);
|
|
191
|
+
let totalLen = 0;
|
|
192
|
+
for (const c of chunks) totalLen += c.length;
|
|
193
|
+
const result = new Uint8Array(totalLen);
|
|
194
|
+
let offset = 0;
|
|
195
|
+
for (const c of chunks) {
|
|
196
|
+
result.set(c, offset);
|
|
197
|
+
offset += c.length;
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
static deserialize(buffer) {
|
|
202
|
+
const uint8 = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);
|
|
203
|
+
const view = new DataView(uint8.buffer, uint8.byteOffset, uint8.byteLength);
|
|
204
|
+
let offset = 0;
|
|
205
|
+
function decode() {
|
|
206
|
+
if (offset >= view.byteLength) {
|
|
207
|
+
throw new Error("[MessagePack] Unexpected end of buffer during deserialization");
|
|
208
|
+
}
|
|
209
|
+
const type = view.getUint8(offset++);
|
|
210
|
+
if (type === 192) return null;
|
|
211
|
+
if (type === 194) return false;
|
|
212
|
+
if (type === 195) return true;
|
|
213
|
+
if (type <= 127) return type;
|
|
214
|
+
if (type >= 224) return type - 256;
|
|
215
|
+
if (type === 204) {
|
|
216
|
+
return view.getUint8(offset++);
|
|
217
|
+
}
|
|
218
|
+
if (type === 205) {
|
|
219
|
+
const val = view.getUint16(offset, false);
|
|
220
|
+
offset += 2;
|
|
221
|
+
return val;
|
|
222
|
+
}
|
|
223
|
+
if (type === 206) {
|
|
224
|
+
const val = view.getUint32(offset, false);
|
|
225
|
+
offset += 4;
|
|
226
|
+
return val;
|
|
227
|
+
}
|
|
228
|
+
if (type === 208) {
|
|
229
|
+
return view.getInt8(offset++);
|
|
230
|
+
}
|
|
231
|
+
if (type === 209) {
|
|
232
|
+
const val = view.getInt16(offset, false);
|
|
233
|
+
offset += 2;
|
|
234
|
+
return val;
|
|
235
|
+
}
|
|
236
|
+
if (type === 210) {
|
|
237
|
+
const val = view.getInt32(offset, false);
|
|
238
|
+
offset += 4;
|
|
239
|
+
return val;
|
|
240
|
+
}
|
|
241
|
+
if (type === 203) {
|
|
242
|
+
const val = view.getFloat64(offset, false);
|
|
243
|
+
offset += 8;
|
|
244
|
+
return val;
|
|
245
|
+
}
|
|
246
|
+
if ((type & 224) === 160) {
|
|
247
|
+
const len = type & 31;
|
|
248
|
+
const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));
|
|
249
|
+
offset += len;
|
|
250
|
+
return str;
|
|
251
|
+
}
|
|
252
|
+
if (type === 217) {
|
|
253
|
+
const len = view.getUint8(offset++);
|
|
254
|
+
const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));
|
|
255
|
+
offset += len;
|
|
256
|
+
return str;
|
|
257
|
+
}
|
|
258
|
+
if (type === 218) {
|
|
259
|
+
const len = view.getUint16(offset, false);
|
|
260
|
+
offset += 2;
|
|
261
|
+
const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));
|
|
262
|
+
offset += len;
|
|
263
|
+
return str;
|
|
264
|
+
}
|
|
265
|
+
if (type === 219) {
|
|
266
|
+
const len = view.getUint32(offset, false);
|
|
267
|
+
offset += 4;
|
|
268
|
+
const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));
|
|
269
|
+
offset += len;
|
|
270
|
+
return str;
|
|
271
|
+
}
|
|
272
|
+
if ((type & 240) === 144) {
|
|
273
|
+
const len = type & 15;
|
|
274
|
+
const arr = [];
|
|
275
|
+
for (let i = 0; i < len; i++) arr.push(decode());
|
|
276
|
+
return arr;
|
|
277
|
+
}
|
|
278
|
+
if (type === 220) {
|
|
279
|
+
const len = view.getUint16(offset, false);
|
|
280
|
+
offset += 2;
|
|
281
|
+
const arr = [];
|
|
282
|
+
for (let i = 0; i < len; i++) arr.push(decode());
|
|
283
|
+
return arr;
|
|
284
|
+
}
|
|
285
|
+
if (type === 221) {
|
|
286
|
+
const len = view.getUint32(offset, false);
|
|
287
|
+
offset += 4;
|
|
288
|
+
const arr = [];
|
|
289
|
+
for (let i = 0; i < len; i++) arr.push(decode());
|
|
290
|
+
return arr;
|
|
291
|
+
}
|
|
292
|
+
if ((type & 240) === 128) {
|
|
293
|
+
const len = type & 15;
|
|
294
|
+
const obj = {};
|
|
295
|
+
for (let i = 0; i < len; i++) {
|
|
296
|
+
const key = decode();
|
|
297
|
+
obj[key] = decode();
|
|
298
|
+
}
|
|
299
|
+
return obj;
|
|
300
|
+
}
|
|
301
|
+
if (type === 222) {
|
|
302
|
+
const len = view.getUint16(offset, false);
|
|
303
|
+
offset += 2;
|
|
304
|
+
const obj = {};
|
|
305
|
+
for (let i = 0; i < len; i++) {
|
|
306
|
+
const key = decode();
|
|
307
|
+
obj[key] = decode();
|
|
308
|
+
}
|
|
309
|
+
return obj;
|
|
310
|
+
}
|
|
311
|
+
if (type === 223) {
|
|
312
|
+
const len = view.getUint32(offset, false);
|
|
313
|
+
offset += 4;
|
|
314
|
+
const obj = {};
|
|
315
|
+
for (let i = 0; i < len; i++) {
|
|
316
|
+
const key = decode();
|
|
317
|
+
obj[key] = decode();
|
|
318
|
+
}
|
|
319
|
+
return obj;
|
|
320
|
+
}
|
|
321
|
+
throw new Error(`[MessagePack] Unknown type prefix: 0x${type.toString(16)}`);
|
|
322
|
+
}
|
|
323
|
+
return decode();
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
var OwlError = class extends Error {
|
|
327
|
+
constructor(code, message, statusCode) {
|
|
328
|
+
super(message);
|
|
329
|
+
this.code = code;
|
|
330
|
+
this.statusCode = statusCode;
|
|
331
|
+
this.name = "OwlError";
|
|
332
|
+
}
|
|
333
|
+
code;
|
|
334
|
+
statusCode;
|
|
335
|
+
};
|
|
336
|
+
async function resolveDocumentId(id, autoHash) {
|
|
337
|
+
if (id.startsWith("_")) {
|
|
338
|
+
throw new Error('[OwlNoSQL] Document ID cannot start with reserved prefix "_"');
|
|
339
|
+
}
|
|
340
|
+
const isValid = /^[a-zA-Z0-9_\-]+$/.test(id);
|
|
341
|
+
if (isValid) {
|
|
342
|
+
if (id.length > 128) {
|
|
343
|
+
throw new Error("[OwlNoSQL] Document ID exceeds 128 characters");
|
|
344
|
+
}
|
|
345
|
+
return id;
|
|
346
|
+
}
|
|
347
|
+
if (!autoHash) {
|
|
348
|
+
throw new Error("[OwlNoSQL] Document ID contains invalid characters (allowed: alphanumeric, _, -)");
|
|
349
|
+
}
|
|
350
|
+
const crypto = getCrypto();
|
|
351
|
+
const encoder = new TextEncoder();
|
|
352
|
+
const data = encoder.encode(id);
|
|
353
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
354
|
+
const hashed = arrayBufferToBase64Url(hashBuffer);
|
|
355
|
+
return `hash_${hashed}`;
|
|
356
|
+
}
|
|
357
|
+
function createClient(options) {
|
|
358
|
+
if (typeof window !== "undefined") {
|
|
359
|
+
throw new Error(
|
|
360
|
+
"[OwlNoSQL] createClient() must only be called in a server environment. Initializing in browser context exposes your API key."
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
const { apiKey, gatewayUrl = "https://owlnosql.deployowl.com" } = options;
|
|
364
|
+
if (!apiKey || typeof apiKey !== "string" || apiKey.length < 32) {
|
|
365
|
+
throw new Error("[OwlNoSQL] Invalid API key format.");
|
|
366
|
+
}
|
|
367
|
+
const request = async (method, routePath, body, headers = {}) => {
|
|
368
|
+
let attempts = 0;
|
|
369
|
+
const maxAttempts = options.retry?.maxAttempts ?? 3;
|
|
370
|
+
const routeToken = await encryptRoute(routePath, apiKey);
|
|
371
|
+
while (true) {
|
|
372
|
+
attempts++;
|
|
373
|
+
try {
|
|
374
|
+
const response = await fetch(`${gatewayUrl}/v1/${routeToken}`, {
|
|
375
|
+
method,
|
|
376
|
+
headers: {
|
|
377
|
+
"Authorization": `Bearer ${apiKey}`,
|
|
378
|
+
"Content-Type": "application/octet-stream",
|
|
379
|
+
"Accept": "application/octet-stream",
|
|
380
|
+
...headers
|
|
381
|
+
},
|
|
382
|
+
body: body ? new Uint8Array(body) : void 0
|
|
383
|
+
});
|
|
384
|
+
const isRetryable = response.status === 429 || response.status >= 500;
|
|
385
|
+
if (response.ok || !isRetryable || attempts >= maxAttempts) {
|
|
386
|
+
if (!response.ok) {
|
|
387
|
+
let errInfo = { code: "UNKNOWN", message: response.statusText };
|
|
388
|
+
try {
|
|
389
|
+
const text = await response.text();
|
|
390
|
+
errInfo = JSON.parse(text);
|
|
391
|
+
} catch {
|
|
392
|
+
}
|
|
393
|
+
throw new OwlError(errInfo.code, errInfo.message, response.status);
|
|
394
|
+
}
|
|
395
|
+
return response;
|
|
396
|
+
}
|
|
397
|
+
} catch (err) {
|
|
398
|
+
if (err instanceof OwlError) throw err;
|
|
399
|
+
if (attempts >= maxAttempts) {
|
|
400
|
+
throw new OwlError(
|
|
401
|
+
"NETWORK_ERROR",
|
|
402
|
+
"Failed to communicate with DeployOwl NoSQL Gateway. Please check your network connectivity and verify that the gatewayUrl is correct and reachable.",
|
|
403
|
+
500
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
const delay = Math.min(
|
|
408
|
+
(options.retry?.initialDelayMs ?? 100) * Math.pow(2, attempts - 1),
|
|
409
|
+
options.retry?.maxDelayMs ?? 2e3
|
|
410
|
+
) + Math.random() * (options.retry?.jitterMs ?? 50);
|
|
411
|
+
await new Promise((res) => setTimeout(res, delay));
|
|
412
|
+
}
|
|
413
|
+
};
|
|
414
|
+
return {
|
|
415
|
+
collection: (collectionName) => {
|
|
416
|
+
if (!/^[a-zA-Z0-9_\-]+$/.test(collectionName) || collectionName.length > 64) {
|
|
417
|
+
throw new Error("[OwlNoSQL] Invalid collection name format");
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
find: async (id, findOpt) => {
|
|
421
|
+
const resolvedId = await resolveDocumentId(id, !!options.autoHashIds);
|
|
422
|
+
try {
|
|
423
|
+
const extraHeaders = {};
|
|
424
|
+
if (findOpt?.bypassCache) {
|
|
425
|
+
extraHeaders["Cache-Control"] = "no-cache";
|
|
426
|
+
}
|
|
427
|
+
const response = await request("GET", `collections/${collectionName}/${resolvedId}`, void 0, extraHeaders);
|
|
428
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
429
|
+
const doc = MessagePack.deserialize(arrayBuffer);
|
|
430
|
+
Object.defineProperty(doc, "__etag", {
|
|
431
|
+
value: response.headers.get("ETag"),
|
|
432
|
+
enumerable: false,
|
|
433
|
+
writable: false
|
|
434
|
+
});
|
|
435
|
+
return doc;
|
|
436
|
+
} catch (err) {
|
|
437
|
+
if (err instanceof OwlError && err.statusCode === 404) {
|
|
438
|
+
return null;
|
|
439
|
+
}
|
|
440
|
+
throw err;
|
|
441
|
+
}
|
|
442
|
+
},
|
|
443
|
+
insert: async (id, payload, opt) => {
|
|
444
|
+
const resolvedId = await resolveDocumentId(id, !!options.autoHashIds);
|
|
445
|
+
const binary = MessagePack.serialize(payload);
|
|
446
|
+
const extraHeaders = {};
|
|
447
|
+
if (opt?.ifMatch) {
|
|
448
|
+
extraHeaders["If-Match"] = opt.ifMatch;
|
|
449
|
+
}
|
|
450
|
+
const response = await request(
|
|
451
|
+
"POST",
|
|
452
|
+
`collections/${collectionName}/${resolvedId}`,
|
|
453
|
+
binary,
|
|
454
|
+
extraHeaders
|
|
455
|
+
);
|
|
456
|
+
const text = await response.text();
|
|
457
|
+
return JSON.parse(text);
|
|
458
|
+
},
|
|
459
|
+
delete: async (id) => {
|
|
460
|
+
const resolvedId = await resolveDocumentId(id, !!options.autoHashIds);
|
|
461
|
+
const response = await request("DELETE", `collections/${collectionName}/${resolvedId}`);
|
|
462
|
+
const text = await response.text();
|
|
463
|
+
return JSON.parse(text);
|
|
464
|
+
},
|
|
465
|
+
query: async (filter) => {
|
|
466
|
+
const binary = MessagePack.serialize(filter);
|
|
467
|
+
const response = await request("POST", `collections/${collectionName}/__query`, binary);
|
|
468
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
469
|
+
return MessagePack.deserialize(arrayBuffer);
|
|
470
|
+
},
|
|
471
|
+
list: async () => {
|
|
472
|
+
const response = await request("GET", `collections/${collectionName}/__list`);
|
|
473
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
474
|
+
return MessagePack.deserialize(arrayBuffer);
|
|
475
|
+
},
|
|
476
|
+
reindex: async () => {
|
|
477
|
+
const response = await request("POST", `collections/${collectionName}/__reindex`);
|
|
478
|
+
const text = await response.text();
|
|
479
|
+
return JSON.parse(text);
|
|
480
|
+
},
|
|
481
|
+
index: async (fields) => {
|
|
482
|
+
const binary = MessagePack.serialize({ indexes: fields });
|
|
483
|
+
const response = await request("POST", `collections/${collectionName}/__config`, binary);
|
|
484
|
+
const text = await response.text();
|
|
485
|
+
return JSON.parse(text);
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
export {
|
|
492
|
+
MessagePack,
|
|
493
|
+
OwlError,
|
|
494
|
+
createClient,
|
|
495
|
+
decryptRoute,
|
|
496
|
+
encryptRoute
|
|
497
|
+
};
|
|
498
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// @deployowl/nosql - Client SDK\n\n// ─── Native Web Crypto Helper ─────────────────────────────────────────\nfunction getCrypto(): Crypto {\n if (typeof globalThis !== 'undefined' && globalThis.crypto) {\n return globalThis.crypto as Crypto;\n }\n try {\n const nodeCrypto = typeof require !== 'undefined' ? require('node:crypto') : null;\n if (nodeCrypto && nodeCrypto.webcrypto) {\n return nodeCrypto.webcrypto as unknown as Crypto;\n }\n } catch {}\n throw new Error('Web Crypto API not available in this environment');\n}\n\n// ─── Base64Url Utilities ────────────────────────────────────────────────\nfunction arrayBufferToBase64Url(buffer: ArrayBuffer | Uint8Array): string {\n const bytes = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n let binary = '';\n for (let i = 0; i < bytes.byteLength; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n const base64 = typeof btoa !== 'undefined' ? btoa(binary) : Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64');\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\nfunction base64UrlToArrayBuffer(base64url: string): Uint8Array {\n const base64 = base64url.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - base64url.length % 4) % 4);\n const binary = typeof atob !== 'undefined' ? atob(base64) : Buffer.from(base64, 'base64').toString('binary');\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n}\n\n// ─── AES-128-CTR Route Encryption ──────────────────────────────────────\nasync function deriveKey(apiKey: string): Promise<CryptoKey> {\n const crypto = getCrypto();\n const encoder = new TextEncoder();\n const apiBytes = encoder.encode(apiKey);\n const hash = await crypto.subtle.digest('SHA-256', apiBytes);\n const keyBytes = new Uint8Array(hash, 0, 16); // Extract first 16 bytes for AES-128\n return await crypto.subtle.importKey(\n 'raw',\n keyBytes,\n { name: 'AES-CTR' },\n false,\n ['encrypt', 'decrypt']\n );\n}\n\nexport async function encryptRoute(path: string, apiKey: string): Promise<string> {\n const crypto = getCrypto();\n const key = await deriveKey(apiKey);\n const iv = crypto.getRandomValues(new Uint8Array(16));\n const encoder = new TextEncoder();\n const pathBytes = encoder.encode(path);\n \n const ciphertext = await crypto.subtle.encrypt(\n {\n name: 'AES-CTR',\n counter: iv,\n length: 64\n },\n key,\n pathBytes\n );\n \n const combined = new Uint8Array(iv.length + ciphertext.byteLength);\n combined.set(iv, 0);\n combined.set(new Uint8Array(ciphertext), iv.length);\n return arrayBufferToBase64Url(combined);\n}\n\nexport async function decryptRoute(token: string, apiKey: string): Promise<string> {\n const crypto = getCrypto();\n const key = await deriveKey(apiKey);\n const combined = base64UrlToArrayBuffer(token);\n \n if (combined.byteLength < 16) {\n throw new Error('Invalid token length');\n }\n \n const iv = combined.slice(0, 16);\n const ciphertext = combined.slice(16);\n \n const decrypted = await crypto.subtle.decrypt(\n {\n name: 'AES-CTR',\n counter: new Uint8Array(iv),\n length: 64\n },\n key,\n ciphertext\n );\n \n return new TextDecoder().decode(decrypted);\n}\n\n// ─── MessagePack Codec ──────────────────────────────────────────────────\nexport class MessagePack {\n static serialize(value: any): Uint8Array {\n const chunks: Uint8Array[] = [];\n \n function encode(v: any) {\n if (v === null || v === undefined) {\n chunks.push(new Uint8Array([0xc0]));\n return;\n }\n if (typeof v === 'boolean') {\n chunks.push(new Uint8Array([v ? 0xc3 : 0xc2]));\n return;\n }\n if (typeof v === 'number') {\n if (Number.isInteger(v)) {\n if (v >= 0 && v <= 127) {\n chunks.push(new Uint8Array([v]));\n } else if (v < 0 && v >= -32) {\n chunks.push(new Uint8Array([0xe0 | (v + 32)]));\n } else if (v >= 0 && v <= 0xff) {\n chunks.push(new Uint8Array([0xcc, v]));\n } else if (v >= 0 && v <= 0xffff) {\n chunks.push(new Uint8Array([0xcd, (v >> 8) & 0xff, v & 0xff]));\n } else if (v >= 0 && v <= 0xffffffff) {\n const buf = new Uint8Array(5);\n buf[0] = 0xce;\n new DataView(buf.buffer).setUint32(1, v, false);\n chunks.push(buf);\n } else {\n const buf = new Uint8Array(5);\n buf[0] = 0xd2;\n new DataView(buf.buffer).setInt32(1, v, false);\n chunks.push(buf);\n }\n } else {\n const buf = new Uint8Array(9);\n buf[0] = 0xcb;\n new DataView(buf.buffer).setFloat64(1, v, false);\n chunks.push(buf);\n }\n return;\n }\n if (typeof v === 'string') {\n const utf8 = new TextEncoder().encode(v);\n const len = utf8.length;\n if (len <= 31) {\n chunks.push(new Uint8Array([0xa0 | len]));\n } else if (len <= 0xff) {\n chunks.push(new Uint8Array([0xd9, len]));\n } else if (len <= 0xffff) {\n chunks.push(new Uint8Array([0xda, (len >> 8) & 0xff, len & 0xff]));\n } else {\n const buf = new Uint8Array(5);\n buf[0] = 0xdb;\n new DataView(buf.buffer).setUint32(1, len, false);\n chunks.push(buf);\n }\n chunks.push(utf8);\n return;\n }\n if (Array.isArray(v)) {\n const len = v.length;\n if (len <= 15) {\n chunks.push(new Uint8Array([0x90 | len]));\n } else if (len <= 0xffff) {\n chunks.push(new Uint8Array([0xdc, (len >> 8) & 0xff, len & 0xff]));\n } else {\n const buf = new Uint8Array(5);\n buf[0] = 0xdd;\n new DataView(buf.buffer).setUint32(1, len, false);\n chunks.push(buf);\n }\n for (const item of v) {\n encode(item);\n }\n return;\n }\n if (typeof v === 'object') {\n const keys = Object.keys(v);\n const len = keys.length;\n if (len <= 15) {\n chunks.push(new Uint8Array([0x80 | len]));\n } else if (len <= 0xffff) {\n chunks.push(new Uint8Array([0xde, (len >> 8) & 0xff, len & 0xff]));\n } else {\n const buf = new Uint8Array(5);\n buf[0] = 0xdf;\n new DataView(buf.buffer).setUint32(1, len, false);\n chunks.push(buf);\n }\n for (const key of keys) {\n encode(key);\n encode(v[key]);\n }\n return;\n }\n }\n \n encode(value);\n \n let totalLen = 0;\n for (const c of chunks) totalLen += c.length;\n const result = new Uint8Array(totalLen);\n let offset = 0;\n for (const c of chunks) {\n result.set(c, offset);\n offset += c.length;\n }\n return result;\n }\n\n static deserialize(buffer: ArrayBuffer | Uint8Array): any {\n const uint8 = buffer instanceof Uint8Array ? buffer : new Uint8Array(buffer);\n const view = new DataView(uint8.buffer, uint8.byteOffset, uint8.byteLength);\n let offset = 0;\n\n function decode(): any {\n if (offset >= view.byteLength) {\n throw new Error('[MessagePack] Unexpected end of buffer during deserialization');\n }\n const type = view.getUint8(offset++);\n if (type === 0xc0) return null;\n if (type === 0xc2) return false;\n if (type === 0xc3) return true;\n if (type <= 0x7f) return type;\n if (type >= 0xe0) return type - 0x100;\n \n if (type === 0xcc) {\n return view.getUint8(offset++);\n }\n if (type === 0xcd) {\n const val = view.getUint16(offset, false);\n offset += 2;\n return val;\n }\n if (type === 0xce) {\n const val = view.getUint32(offset, false);\n offset += 4;\n return val;\n }\n if (type === 0xd0) {\n return view.getInt8(offset++);\n }\n if (type === 0xd1) {\n const val = view.getInt16(offset, false);\n offset += 2;\n return val;\n }\n if (type === 0xd2) {\n const val = view.getInt32(offset, false);\n offset += 4;\n return val;\n }\n if (type === 0xcb) {\n const val = view.getFloat64(offset, false);\n offset += 8;\n return val;\n }\n\n if ((type & 0xe0) === 0xa0) {\n const len = type & 0x1f;\n const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n if (type === 0xd9) {\n const len = view.getUint8(offset++);\n const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n if (type === 0xda) {\n const len = view.getUint16(offset, false);\n offset += 2;\n const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n if (type === 0xdb) {\n const len = view.getUint32(offset, false);\n offset += 4;\n const str = new TextDecoder().decode(uint8.subarray(offset, offset + len));\n offset += len;\n return str;\n }\n\n if ((type & 0xf0) === 0x90) {\n const len = type & 0x0f;\n const arr = [];\n for (let i = 0; i < len; i++) arr.push(decode());\n return arr;\n }\n if (type === 0xdc) {\n const len = view.getUint16(offset, false);\n offset += 2;\n const arr = [];\n for (let i = 0; i < len; i++) arr.push(decode());\n return arr;\n }\n if (type === 0xdd) {\n const len = view.getUint32(offset, false);\n offset += 4;\n const arr = [];\n for (let i = 0; i < len; i++) arr.push(decode());\n return arr;\n }\n\n if ((type & 0xf0) === 0x80) {\n const len = type & 0x0f;\n const obj: any = {};\n for (let i = 0; i < len; i++) {\n const key = decode();\n obj[key] = decode();\n }\n return obj;\n }\n if (type === 0xde) {\n const len = view.getUint16(offset, false);\n offset += 2;\n const obj: any = {};\n for (let i = 0; i < len; i++) {\n const key = decode();\n obj[key] = decode();\n }\n return obj;\n }\n if (type === 0xdf) {\n const len = view.getUint32(offset, false);\n offset += 4;\n const obj: any = {};\n for (let i = 0; i < len; i++) {\n const key = decode();\n obj[key] = decode();\n }\n return obj;\n }\n\n throw new Error(`[MessagePack] Unknown type prefix: 0x${type.toString(16)}`);\n }\n\n return decode();\n }\n}\n\n// ─── OwlError Custom Class ──────────────────────────────────────────────\nexport class OwlError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n public readonly statusCode: number\n ) {\n super(message);\n this.name = 'OwlError';\n }\n}\n\n// ─── Client Runtime Options ─────────────────────────────────────────────\nexport interface ClientOptions {\n apiKey: string;\n gatewayUrl?: string;\n retry?: {\n maxAttempts?: number;\n initialDelayMs?: number;\n maxDelayMs?: number;\n jitterMs?: number;\n };\n autoHashIds?: boolean;\n}\n\nasync function resolveDocumentId(id: string, autoHash: boolean): Promise<string> {\n if (id.startsWith('_')) {\n throw new Error('[OwlNoSQL] Document ID cannot start with reserved prefix \"_\"');\n }\n const isValid = /^[a-zA-Z0-9_\\-]+$/.test(id);\n if (isValid) {\n if (id.length > 128) {\n throw new Error('[OwlNoSQL] Document ID exceeds 128 characters');\n }\n return id;\n }\n if (!autoHash) {\n throw new Error('[OwlNoSQL] Document ID contains invalid characters (allowed: alphanumeric, _, -)');\n }\n const crypto = getCrypto();\n const encoder = new TextEncoder();\n const data = encoder.encode(id);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const hashed = arrayBufferToBase64Url(hashBuffer);\n return `hash_${hashed}`;\n}\n\n// ─── createClient Implementation ────────────────────────────────────────\nexport function createClient(options: ClientOptions) {\n if (typeof window !== 'undefined') {\n throw new Error(\n '[OwlNoSQL] createClient() must only be called in a server environment. ' +\n 'Initializing in browser context exposes your API key.'\n );\n }\n\n const { apiKey, gatewayUrl = 'https://owlnosql.deployowl.com' } = options;\n if (!apiKey || typeof apiKey !== 'string' || apiKey.length < 32) {\n throw new Error('[OwlNoSQL] Invalid API key format.');\n }\n\n const request = async (\n method: string,\n routePath: string,\n body?: ArrayBuffer | Uint8Array,\n headers: Record<string, string> = {}\n ): Promise<Response> => {\n let attempts = 0;\n const maxAttempts = options.retry?.maxAttempts ?? 3;\n const routeToken = await encryptRoute(routePath, apiKey);\n\n while (true) {\n attempts++;\n try {\n const response = await fetch(`${gatewayUrl}/v1/${routeToken}`, {\n method,\n headers: {\n 'Authorization': `Bearer ${apiKey}`,\n 'Content-Type': 'application/octet-stream',\n 'Accept': 'application/octet-stream',\n ...headers\n },\n body: body ? new Uint8Array(body) : undefined\n });\n\n const isRetryable = response.status === 429 || response.status >= 500;\n if (response.ok || !isRetryable || attempts >= maxAttempts) {\n if (!response.ok) {\n let errInfo = { code: 'UNKNOWN', message: response.statusText };\n try {\n const text = await response.text();\n errInfo = JSON.parse(text);\n } catch {}\n throw new OwlError(errInfo.code, errInfo.message, response.status);\n }\n return response;\n }\n } catch (err: any) {\n if (err instanceof OwlError) throw err;\n if (attempts >= maxAttempts) {\n throw new OwlError(\n 'NETWORK_ERROR',\n 'Failed to communicate with DeployOwl NoSQL Gateway. Please check your network connectivity and verify that the gatewayUrl is correct and reachable.',\n 500\n );\n }\n }\n\n const delay = Math.min(\n (options.retry?.initialDelayMs ?? 100) * Math.pow(2, attempts - 1),\n options.retry?.maxDelayMs ?? 2000\n ) + Math.random() * (options.retry?.jitterMs ?? 50);\n\n await new Promise((res) => setTimeout(res, delay));\n }\n };\n\n return {\n collection: (collectionName: string) => {\n if (!/^[a-zA-Z0-9_\\-]+$/.test(collectionName) || collectionName.length > 64) {\n throw new Error('[OwlNoSQL] Invalid collection name format');\n }\n\n return {\n find: async <T = Record<string, any>>(id: string, findOpt?: { bypassCache?: boolean }): Promise<T | null> => {\n const resolvedId = await resolveDocumentId(id, !!options.autoHashIds);\n try {\n const extraHeaders: Record<string, string> = {};\n if (findOpt?.bypassCache) {\n extraHeaders['Cache-Control'] = 'no-cache';\n }\n const response = await request('GET', `collections/${collectionName}/${resolvedId}`, undefined, extraHeaders);\n const arrayBuffer = await response.arrayBuffer();\n const doc = MessagePack.deserialize(arrayBuffer) as T;\n \n Object.defineProperty(doc, '__etag', {\n value: response.headers.get('ETag'),\n enumerable: false,\n writable: false\n });\n return doc;\n } catch (err: any) {\n if (err instanceof OwlError && err.statusCode === 404) {\n return null;\n }\n throw err;\n }\n },\n\n insert: async (\n id: string,\n payload: Record<string, any>,\n opt?: { ifMatch?: string }\n ): Promise<{ id: string; written: boolean; bytes: number }> => {\n const resolvedId = await resolveDocumentId(id, !!options.autoHashIds);\n const binary = MessagePack.serialize(payload);\n const extraHeaders: Record<string, string> = {};\n if (opt?.ifMatch) {\n extraHeaders['If-Match'] = opt.ifMatch;\n }\n\n const response = await request(\n 'POST',\n `collections/${collectionName}/${resolvedId}`,\n binary,\n extraHeaders\n );\n const text = await response.text();\n return JSON.parse(text);\n },\n\n delete: async (id: string): Promise<{ deleted: boolean }> => {\n const resolvedId = await resolveDocumentId(id, !!options.autoHashIds);\n const response = await request('DELETE', `collections/${collectionName}/${resolvedId}`);\n const text = await response.text();\n return JSON.parse(text);\n },\n\n query: async <T = Record<string, any>>(filter: Record<string, any>): Promise<T[]> => {\n const binary = MessagePack.serialize(filter);\n const response = await request('POST', `collections/${collectionName}/__query`, binary);\n const arrayBuffer = await response.arrayBuffer();\n return MessagePack.deserialize(arrayBuffer) as T[];\n },\n\n list: async (): Promise<string[]> => {\n const response = await request('GET', `collections/${collectionName}/__list`);\n const arrayBuffer = await response.arrayBuffer();\n return MessagePack.deserialize(arrayBuffer) as string[];\n },\n\n reindex: async (): Promise<{ success: boolean }> => {\n const response = await request('POST', `collections/${collectionName}/__reindex`);\n const text = await response.text();\n return JSON.parse(text);\n },\n\n index: async (fields: string[]): Promise<{ success: boolean }> => {\n const binary = MessagePack.serialize({ indexes: fields });\n const response = await request('POST', `collections/${collectionName}/__config`, binary);\n const text = await response.text();\n return JSON.parse(text);\n }\n };\n }\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@deployowl/nosql",
|
|
3
|
+
"version": "2.2.5",
|
|
4
|
+
"description": "Zero-config edge NoSQL SDK for DeployOwl",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist",
|
|
7
|
+
"README.md"
|
|
8
|
+
],
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"module": "./dist/index.mjs",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"require": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
21
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
22
|
+
"lint": "tsc --noEmit"
|
|
23
|
+
},
|
|
24
|
+
"license": "Proprietary",
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.10.0",
|
|
27
|
+
"tsup": "^8.0.0",
|
|
28
|
+
"typescript": "^5.3.0"
|
|
29
|
+
}
|
|
30
|
+
}
|