@concavejs/docstore-memory 0.0.1-alpha.10 → 0.0.1-alpha.12
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/dist/index.js +1051 -502
- package/dist/memory-docstore.d.ts +1 -0
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -13,12 +13,236 @@ var __export = (target, all) => {
|
|
|
13
13
|
});
|
|
14
14
|
};
|
|
15
15
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (
|
|
20
|
-
return
|
|
21
|
-
|
|
16
|
+
|
|
17
|
+
// ../core/dist/id-codec/base32.js
|
|
18
|
+
function base32Encode(data) {
|
|
19
|
+
if (data.length === 0)
|
|
20
|
+
return "";
|
|
21
|
+
let result = "";
|
|
22
|
+
let buffer = 0;
|
|
23
|
+
let bitsLeft = 0;
|
|
24
|
+
for (const byte of data) {
|
|
25
|
+
buffer = buffer << 8 | byte;
|
|
26
|
+
bitsLeft += 8;
|
|
27
|
+
while (bitsLeft >= 5) {
|
|
28
|
+
bitsLeft -= 5;
|
|
29
|
+
const index = buffer >> bitsLeft & 31;
|
|
30
|
+
result += ALPHABET[index];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
if (bitsLeft > 0) {
|
|
34
|
+
const index = buffer << 5 - bitsLeft & 31;
|
|
35
|
+
result += ALPHABET[index];
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
function base32Decode(str) {
|
|
40
|
+
if (str.length === 0)
|
|
41
|
+
return new Uint8Array(0);
|
|
42
|
+
const outputLength = Math.floor(str.length * 5 / 8);
|
|
43
|
+
const result = new Uint8Array(outputLength);
|
|
44
|
+
let buffer = 0;
|
|
45
|
+
let bitsLeft = 0;
|
|
46
|
+
let outputIndex = 0;
|
|
47
|
+
for (const char of str) {
|
|
48
|
+
const value = ALPHABET_MAP.get(char);
|
|
49
|
+
if (value === undefined) {
|
|
50
|
+
throw new Error(`Invalid base32 character: ${char}`);
|
|
51
|
+
}
|
|
52
|
+
buffer = buffer << 5 | value;
|
|
53
|
+
bitsLeft += 5;
|
|
54
|
+
if (bitsLeft >= 8) {
|
|
55
|
+
bitsLeft -= 8;
|
|
56
|
+
result[outputIndex++] = buffer >> bitsLeft & 255;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
function isValidBase32(str) {
|
|
62
|
+
for (const char of str) {
|
|
63
|
+
if (!ALPHABET_MAP.has(char)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
var ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz", ALPHABET_MAP;
|
|
70
|
+
var init_base32 = __esm(() => {
|
|
71
|
+
ALPHABET_MAP = new Map;
|
|
72
|
+
for (let i = 0;i < ALPHABET.length; i++) {
|
|
73
|
+
ALPHABET_MAP.set(ALPHABET[i], i);
|
|
74
|
+
ALPHABET_MAP.set(ALPHABET[i].toUpperCase(), i);
|
|
75
|
+
}
|
|
76
|
+
ALPHABET_MAP.set("i", 1);
|
|
77
|
+
ALPHABET_MAP.set("I", 1);
|
|
78
|
+
ALPHABET_MAP.set("l", 1);
|
|
79
|
+
ALPHABET_MAP.set("L", 1);
|
|
80
|
+
ALPHABET_MAP.set("o", 0);
|
|
81
|
+
ALPHABET_MAP.set("O", 0);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
// ../core/dist/id-codec/vint.js
|
|
85
|
+
function vintEncode(value) {
|
|
86
|
+
if (value < 0) {
|
|
87
|
+
throw new Error("VInt cannot encode negative numbers");
|
|
88
|
+
}
|
|
89
|
+
if (value > 4294967295) {
|
|
90
|
+
throw new Error("VInt cannot encode values larger than 2^32-1");
|
|
91
|
+
}
|
|
92
|
+
value = value >>> 0;
|
|
93
|
+
if (value < 128) {
|
|
94
|
+
return new Uint8Array([value]);
|
|
95
|
+
}
|
|
96
|
+
if (value < 16512) {
|
|
97
|
+
const adjusted2 = value - 128;
|
|
98
|
+
return new Uint8Array([128 | adjusted2 >> 8 & 63, adjusted2 & 255]);
|
|
99
|
+
}
|
|
100
|
+
if (value < 2113664) {
|
|
101
|
+
const adjusted2 = value - 16512;
|
|
102
|
+
return new Uint8Array([192 | adjusted2 >> 16 & 31, adjusted2 >> 8 & 255, adjusted2 & 255]);
|
|
103
|
+
}
|
|
104
|
+
if (value < 270549120) {
|
|
105
|
+
const adjusted2 = value - 2113664;
|
|
106
|
+
return new Uint8Array([
|
|
107
|
+
224 | adjusted2 >> 24 & 15,
|
|
108
|
+
adjusted2 >> 16 & 255,
|
|
109
|
+
adjusted2 >> 8 & 255,
|
|
110
|
+
adjusted2 & 255
|
|
111
|
+
]);
|
|
112
|
+
}
|
|
113
|
+
const adjusted = value - 270549120;
|
|
114
|
+
return new Uint8Array([
|
|
115
|
+
240 | adjusted >> 32 & 7,
|
|
116
|
+
adjusted >> 24 & 255,
|
|
117
|
+
adjusted >> 16 & 255,
|
|
118
|
+
adjusted >> 8 & 255,
|
|
119
|
+
adjusted & 255
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
function vintDecode(data, offset = 0) {
|
|
123
|
+
if (offset >= data.length) {
|
|
124
|
+
throw new Error("VInt decode: unexpected end of data");
|
|
125
|
+
}
|
|
126
|
+
const first = data[offset];
|
|
127
|
+
if ((first & 128) === 0) {
|
|
128
|
+
return { value: first, bytesRead: 1 };
|
|
129
|
+
}
|
|
130
|
+
if ((first & 192) === 128) {
|
|
131
|
+
if (offset + 1 >= data.length) {
|
|
132
|
+
throw new Error("VInt decode: truncated 2-byte encoding");
|
|
133
|
+
}
|
|
134
|
+
const value = 128 + ((first & 63) << 8 | data[offset + 1]);
|
|
135
|
+
return { value, bytesRead: 2 };
|
|
136
|
+
}
|
|
137
|
+
if ((first & 224) === 192) {
|
|
138
|
+
if (offset + 2 >= data.length) {
|
|
139
|
+
throw new Error("VInt decode: truncated 3-byte encoding");
|
|
140
|
+
}
|
|
141
|
+
const value = 16512 + ((first & 31) << 16 | data[offset + 1] << 8 | data[offset + 2]);
|
|
142
|
+
return { value, bytesRead: 3 };
|
|
143
|
+
}
|
|
144
|
+
if ((first & 240) === 224) {
|
|
145
|
+
if (offset + 3 >= data.length) {
|
|
146
|
+
throw new Error("VInt decode: truncated 4-byte encoding");
|
|
147
|
+
}
|
|
148
|
+
const value = 2113664 + ((first & 15) << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]);
|
|
149
|
+
return { value: value >>> 0, bytesRead: 4 };
|
|
150
|
+
}
|
|
151
|
+
if ((first & 248) === 240) {
|
|
152
|
+
if (offset + 4 >= data.length) {
|
|
153
|
+
throw new Error("VInt decode: truncated 5-byte encoding");
|
|
154
|
+
}
|
|
155
|
+
const high = first & 7;
|
|
156
|
+
const low = (data[offset + 1] << 24 | data[offset + 2] << 16 | data[offset + 3] << 8 | data[offset + 4]) >>> 0;
|
|
157
|
+
const value = 270549120 + high * 4294967296 + low;
|
|
158
|
+
return { value: value >>> 0, bytesRead: 5 };
|
|
159
|
+
}
|
|
160
|
+
throw new Error("VInt decode: invalid prefix");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ../core/dist/id-codec/fletcher16.js
|
|
164
|
+
function fletcher16(data) {
|
|
165
|
+
let sum1 = 0;
|
|
166
|
+
let sum2 = 0;
|
|
167
|
+
for (const byte of data) {
|
|
168
|
+
sum1 = (sum1 + byte) % 255;
|
|
169
|
+
sum2 = (sum2 + sum1) % 255;
|
|
170
|
+
}
|
|
171
|
+
return new Uint8Array([sum1, sum2]);
|
|
172
|
+
}
|
|
173
|
+
function verifyFletcher16(data, checksum) {
|
|
174
|
+
if (checksum.length !== 2)
|
|
175
|
+
return false;
|
|
176
|
+
const computed = fletcher16(data);
|
|
177
|
+
return computed[0] === checksum[0] && computed[1] === checksum[1];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// ../core/dist/utils/crypto.js
|
|
181
|
+
var weakRandomState;
|
|
182
|
+
var init_crypto = __esm(() => {
|
|
183
|
+
weakRandomState = (Date.now() ^ 2654435769) >>> 0;
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
// ../core/dist/id-codec/document-id.js
|
|
187
|
+
function encodeDocumentId(tableNumber, internalId) {
|
|
188
|
+
if (internalId.length !== INTERNAL_ID_LENGTH) {
|
|
189
|
+
throw new Error(`Internal ID must be exactly ${INTERNAL_ID_LENGTH} bytes, got ${internalId.length}`);
|
|
190
|
+
}
|
|
191
|
+
if (tableNumber < 1 || tableNumber > 4294967295) {
|
|
192
|
+
throw new Error(`Table number must be between 1 and 2^32-1, got ${tableNumber}`);
|
|
193
|
+
}
|
|
194
|
+
const tableBytes = vintEncode(tableNumber);
|
|
195
|
+
const payload = new Uint8Array(tableBytes.length + INTERNAL_ID_LENGTH);
|
|
196
|
+
payload.set(tableBytes, 0);
|
|
197
|
+
payload.set(internalId, tableBytes.length);
|
|
198
|
+
const checksum = fletcher16(payload);
|
|
199
|
+
const final = new Uint8Array(payload.length + 2);
|
|
200
|
+
final.set(payload, 0);
|
|
201
|
+
final.set(checksum, payload.length);
|
|
202
|
+
return base32Encode(final);
|
|
203
|
+
}
|
|
204
|
+
function decodeDocumentId(encoded) {
|
|
205
|
+
if (encoded.length < MIN_ENCODED_LENGTH || encoded.length > MAX_ENCODED_LENGTH) {
|
|
206
|
+
throw new Error(`Invalid document ID length: ${encoded.length} (expected ${MIN_ENCODED_LENGTH}-${MAX_ENCODED_LENGTH})`);
|
|
207
|
+
}
|
|
208
|
+
if (!isValidBase32(encoded)) {
|
|
209
|
+
throw new Error("Invalid document ID: contains invalid base32 characters");
|
|
210
|
+
}
|
|
211
|
+
const bytes = base32Decode(encoded);
|
|
212
|
+
if (bytes.length < 19) {
|
|
213
|
+
throw new Error(`Invalid document ID: decoded to ${bytes.length} bytes (minimum 19)`);
|
|
214
|
+
}
|
|
215
|
+
const checksum = bytes.slice(bytes.length - 2);
|
|
216
|
+
const payload = bytes.slice(0, bytes.length - 2);
|
|
217
|
+
if (!verifyFletcher16(payload, checksum)) {
|
|
218
|
+
throw new Error("Invalid document ID: checksum verification failed");
|
|
219
|
+
}
|
|
220
|
+
const { value: tableNumber, bytesRead } = vintDecode(payload, 0);
|
|
221
|
+
const internalId = payload.slice(bytesRead, bytesRead + INTERNAL_ID_LENGTH);
|
|
222
|
+
if (internalId.length !== INTERNAL_ID_LENGTH) {
|
|
223
|
+
throw new Error(`Invalid document ID: internal ID is ${internalId.length} bytes (expected ${INTERNAL_ID_LENGTH})`);
|
|
224
|
+
}
|
|
225
|
+
return { tableNumber, internalId };
|
|
226
|
+
}
|
|
227
|
+
function isValidDocumentId(encoded) {
|
|
228
|
+
try {
|
|
229
|
+
decodeDocumentId(encoded);
|
|
230
|
+
return true;
|
|
231
|
+
} catch {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
function internalIdToHex(internalId) {
|
|
236
|
+
let hex = "";
|
|
237
|
+
for (let i = 0;i < internalId.length; i++) {
|
|
238
|
+
hex += internalId[i].toString(16).padStart(2, "0");
|
|
239
|
+
}
|
|
240
|
+
return hex;
|
|
241
|
+
}
|
|
242
|
+
var INTERNAL_ID_LENGTH = 16, MIN_ENCODED_LENGTH = 31, MAX_ENCODED_LENGTH = 37;
|
|
243
|
+
var init_document_id = __esm(() => {
|
|
244
|
+
init_base32();
|
|
245
|
+
init_crypto();
|
|
22
246
|
});
|
|
23
247
|
|
|
24
248
|
// ../core/dist/utils/utils.js
|
|
@@ -59,9 +283,15 @@ function deserializeDeveloperId(developerId) {
|
|
|
59
283
|
return null;
|
|
60
284
|
}
|
|
61
285
|
var DOC_ID_SEPARATOR = ":", LEGACY_DOC_ID_SEPARATOR = ";";
|
|
286
|
+
var init_utils = __esm(() => {
|
|
287
|
+
init_document_id();
|
|
288
|
+
});
|
|
62
289
|
|
|
63
290
|
// ../core/dist/tables/interface.js
|
|
64
291
|
function getFullTableName(tableName, componentPath) {
|
|
292
|
+
if (isSystemTable(tableName)) {
|
|
293
|
+
return tableName;
|
|
294
|
+
}
|
|
65
295
|
if (!componentPath || componentPath === "") {
|
|
66
296
|
return tableName;
|
|
67
297
|
}
|
|
@@ -78,23 +308,28 @@ function parseFullTableName(fullName) {
|
|
|
78
308
|
};
|
|
79
309
|
}
|
|
80
310
|
function isSystemTable(tableName) {
|
|
81
|
-
return
|
|
311
|
+
return Object.hasOwn(SYSTEM_TABLE_NUMBERS, tableName);
|
|
82
312
|
}
|
|
83
|
-
var SYSTEM_TABLE_NUMBERS, FIRST_USER_TABLE_NUMBER =
|
|
313
|
+
var SYSTEM_TABLE_NUMBERS, FIRST_USER_TABLE_NUMBER = 10001;
|
|
84
314
|
var init_interface = __esm(() => {
|
|
85
315
|
SYSTEM_TABLE_NUMBERS = {
|
|
86
316
|
_tables: 1,
|
|
87
317
|
_scheduled_functions: 2,
|
|
88
318
|
_storage: 3,
|
|
89
|
-
_crons: 4
|
|
319
|
+
_crons: 4,
|
|
320
|
+
_indexes: 5,
|
|
321
|
+
_schemas: 6,
|
|
322
|
+
_components: 7,
|
|
323
|
+
_component_definitions: 8,
|
|
324
|
+
_schema_validation_progress: 9
|
|
90
325
|
};
|
|
91
326
|
});
|
|
92
327
|
|
|
93
328
|
// ../core/dist/kernel/context-storage.js
|
|
94
|
-
function
|
|
329
|
+
function resolveFromModuleResolver(resolveModule) {
|
|
95
330
|
for (const specifier of ["node:async_hooks", "async_hooks"]) {
|
|
96
331
|
try {
|
|
97
|
-
const mod =
|
|
332
|
+
const mod = resolveModule(specifier);
|
|
98
333
|
if (mod?.AsyncLocalStorage) {
|
|
99
334
|
return mod.AsyncLocalStorage;
|
|
100
335
|
}
|
|
@@ -137,16 +372,16 @@ var resolveAsyncLocalStorage = () => {
|
|
|
137
372
|
if (globalCtor) {
|
|
138
373
|
return globalCtor;
|
|
139
374
|
}
|
|
140
|
-
const
|
|
141
|
-
if (
|
|
142
|
-
const ctor =
|
|
375
|
+
const getBuiltinModule = globalThis?.process?.getBuiltinModule;
|
|
376
|
+
if (typeof getBuiltinModule === "function") {
|
|
377
|
+
const ctor = resolveFromModuleResolver((specifier) => getBuiltinModule(specifier));
|
|
143
378
|
if (ctor) {
|
|
144
379
|
return ctor;
|
|
145
380
|
}
|
|
146
381
|
}
|
|
147
382
|
const globalRequire = globalThis?.require;
|
|
148
383
|
if (typeof globalRequire === "function") {
|
|
149
|
-
return
|
|
384
|
+
return resolveFromModuleResolver(globalRequire);
|
|
150
385
|
}
|
|
151
386
|
return;
|
|
152
387
|
}, AsyncLocalStorageCtor;
|
|
@@ -2217,7 +2452,7 @@ async function listSystemFunctions(options = {}) {
|
|
|
2217
2452
|
}
|
|
2218
2453
|
for (const route of httpRoutes) {
|
|
2219
2454
|
const method = route.route.method;
|
|
2220
|
-
const routePath = route.route.path;
|
|
2455
|
+
const routePath = mountHttpRoutePath(route.route.path, owningComponent);
|
|
2221
2456
|
results.push({
|
|
2222
2457
|
name: `${method} ${routePath}`,
|
|
2223
2458
|
module: listing.path,
|
|
@@ -2279,6 +2514,16 @@ async function loadAndAnalyzeModule(listing, componentPath) {
|
|
|
2279
2514
|
function makeCacheKey(componentPath, modulePath) {
|
|
2280
2515
|
return `${componentPath ?? ""}::${modulePath}`;
|
|
2281
2516
|
}
|
|
2517
|
+
function mountHttpRoutePath(routePath, componentPath) {
|
|
2518
|
+
if (!componentPath) {
|
|
2519
|
+
return routePath;
|
|
2520
|
+
}
|
|
2521
|
+
const prefix = `/${componentPath}`;
|
|
2522
|
+
if (routePath === "/") {
|
|
2523
|
+
return prefix;
|
|
2524
|
+
}
|
|
2525
|
+
return `${prefix}${routePath}`;
|
|
2526
|
+
}
|
|
2282
2527
|
function buildFallbackSourcePath(modulePath) {
|
|
2283
2528
|
const trimmed = modulePath.replace(/\\/g, "/").replace(/^\//, "");
|
|
2284
2529
|
const withConvex = trimmed.startsWith("convex/") ? trimmed : `convex/${trimmed}`;
|
|
@@ -3965,6 +4210,7 @@ var init_remote = __esm(() => {
|
|
|
3965
4210
|
// ../../node_modules/jose/dist/webapi/index.js
|
|
3966
4211
|
var init_webapi = __esm(() => {
|
|
3967
4212
|
init_verify4();
|
|
4213
|
+
init_local();
|
|
3968
4214
|
init_remote();
|
|
3969
4215
|
init_errors2();
|
|
3970
4216
|
});
|
|
@@ -4169,7 +4415,7 @@ function getRemoteJwks(jwksUrl, config) {
|
|
|
4169
4415
|
if (cached) {
|
|
4170
4416
|
JWKS_CACHE.delete(jwksUrl);
|
|
4171
4417
|
}
|
|
4172
|
-
const jwks = createRemoteJWKSet(new URL(jwksUrl));
|
|
4418
|
+
const jwks = jwksUrl.startsWith("data:") ? createLocalJWKSet(parseDataUriJson(jwksUrl)) : createRemoteJWKSet(new URL(jwksUrl));
|
|
4173
4419
|
const configuredTtl = config?.jwksCacheTtlMs;
|
|
4174
4420
|
const ttlMs = resolveJwksCacheTtlMs(configuredTtl);
|
|
4175
4421
|
JWKS_CACHE.set(jwksUrl, {
|
|
@@ -4178,6 +4424,24 @@ function getRemoteJwks(jwksUrl, config) {
|
|
|
4178
4424
|
});
|
|
4179
4425
|
return jwks;
|
|
4180
4426
|
}
|
|
4427
|
+
function parseDataUriJson(dataUri) {
|
|
4428
|
+
const match = /^data:([^;,]+)?(?:;charset=[^;,]+)?(;base64)?,(.*)$/i.exec(dataUri);
|
|
4429
|
+
if (!match) {
|
|
4430
|
+
throw new JWTValidationError("INVALID_TOKEN", "Invalid JWKS data URI");
|
|
4431
|
+
}
|
|
4432
|
+
const [, , isBase64, payload] = match;
|
|
4433
|
+
const jsonText = isBase64 ? decodeBase642(payload) : decodeURIComponent(payload);
|
|
4434
|
+
return JSON.parse(jsonText);
|
|
4435
|
+
}
|
|
4436
|
+
function decodeBase642(value) {
|
|
4437
|
+
if (typeof Buffer !== "undefined") {
|
|
4438
|
+
return Buffer.from(value, "base64").toString("utf8");
|
|
4439
|
+
}
|
|
4440
|
+
if (typeof atob === "function") {
|
|
4441
|
+
return new TextDecoder().decode(Uint8Array.from(atob(value), (char) => char.charCodeAt(0)));
|
|
4442
|
+
}
|
|
4443
|
+
throw new JWTValidationError("INVALID_TOKEN", "Base64 decoding is unavailable");
|
|
4444
|
+
}
|
|
4181
4445
|
function resolveJwksCacheTtlMs(configuredTtl) {
|
|
4182
4446
|
if (configuredTtl === undefined) {
|
|
4183
4447
|
return DEFAULT_JWKS_CACHE_TTL_MS;
|
|
@@ -4212,6 +4476,7 @@ async function verifyJwt(token, config) {
|
|
|
4212
4476
|
const options = {
|
|
4213
4477
|
issuer: effectiveConfig.issuer,
|
|
4214
4478
|
audience: effectiveConfig.audience,
|
|
4479
|
+
algorithms: effectiveConfig.algorithms,
|
|
4215
4480
|
clockTolerance: effectiveConfig.clockTolerance ?? DEFAULT_CLOCK_TOLERANCE_SECONDS
|
|
4216
4481
|
};
|
|
4217
4482
|
let payload;
|
|
@@ -4281,11 +4546,20 @@ var init_jwt = __esm(() => {
|
|
|
4281
4546
|
function getPrincipal() {
|
|
4282
4547
|
return principalContext.getStore();
|
|
4283
4548
|
}
|
|
4284
|
-
var authContext, principalContext;
|
|
4549
|
+
var AUTH_CONTEXT_SYMBOL, PRINCIPAL_CONTEXT_SYMBOL, globalAuthContext, authContext, principalContext;
|
|
4285
4550
|
var init_auth_context = __esm(() => {
|
|
4286
4551
|
init_context_storage();
|
|
4287
|
-
|
|
4288
|
-
|
|
4552
|
+
AUTH_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/auth-context");
|
|
4553
|
+
PRINCIPAL_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/principal-context");
|
|
4554
|
+
globalAuthContext = globalThis;
|
|
4555
|
+
authContext = globalAuthContext[AUTH_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
4556
|
+
principalContext = globalAuthContext[PRINCIPAL_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
4557
|
+
if (!globalAuthContext[AUTH_CONTEXT_SYMBOL]) {
|
|
4558
|
+
globalAuthContext[AUTH_CONTEXT_SYMBOL] = authContext;
|
|
4559
|
+
}
|
|
4560
|
+
if (!globalAuthContext[PRINCIPAL_CONTEXT_SYMBOL]) {
|
|
4561
|
+
globalAuthContext[PRINCIPAL_CONTEXT_SYMBOL] = principalContext;
|
|
4562
|
+
}
|
|
4289
4563
|
});
|
|
4290
4564
|
|
|
4291
4565
|
// ../core/dist/auth/principal.js
|
|
@@ -4760,47 +5034,231 @@ var init_auth = __esm(() => {
|
|
|
4760
5034
|
init_auth_config_service();
|
|
4761
5035
|
});
|
|
4762
5036
|
|
|
4763
|
-
// ../core/dist/
|
|
4764
|
-
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
5037
|
+
// ../core/dist/components/manifest.js
|
|
5038
|
+
var COMPONENT_MANIFEST_SYMBOL;
|
|
5039
|
+
var init_manifest = __esm(() => {
|
|
5040
|
+
COMPONENT_MANIFEST_SYMBOL = Symbol.for("concave.componentManifest");
|
|
5041
|
+
});
|
|
5042
|
+
|
|
5043
|
+
// ../core/dist/id-codec/index.js
|
|
5044
|
+
var init_id_codec = __esm(() => {
|
|
5045
|
+
init_base32();
|
|
5046
|
+
init_document_id();
|
|
5047
|
+
});
|
|
5048
|
+
|
|
5049
|
+
// ../core/dist/system/system-tables.js
|
|
5050
|
+
function getSystemTableDefinition(name) {
|
|
5051
|
+
return SYSTEM_TABLE_DEFINITIONS.find((definition) => definition.name === name) ?? null;
|
|
4770
5052
|
}
|
|
4771
|
-
function
|
|
4772
|
-
|
|
5053
|
+
function isPublicSystemTable(name) {
|
|
5054
|
+
return getSystemTableDefinition(name)?.visibility === "public";
|
|
5055
|
+
}
|
|
5056
|
+
function createTableInfo(name, tableNumber, componentPath = "", options = {}) {
|
|
5057
|
+
const fullName = getFullTableName(name, componentPath);
|
|
5058
|
+
return {
|
|
5059
|
+
tableNumber,
|
|
5060
|
+
name,
|
|
5061
|
+
componentPath: isSystemTableName(name) ? "" : componentPath,
|
|
5062
|
+
fullName,
|
|
5063
|
+
isSystem: options.isSystem ?? isSystemTableName(name),
|
|
5064
|
+
visibility: options.visibility ?? (isPublicSystemTable(name) ? "public" : "private"),
|
|
5065
|
+
state: "active",
|
|
5066
|
+
createdAt: options.createdAt ?? Date.now()
|
|
5067
|
+
};
|
|
5068
|
+
}
|
|
5069
|
+
function getReservedSystemTables() {
|
|
5070
|
+
return SYSTEM_TABLE_DEFINITIONS.map((definition) => createTableInfo(definition.name, SYSTEM_TABLE_NUMBERS[definition.name], "", {
|
|
5071
|
+
isSystem: true,
|
|
5072
|
+
visibility: definition.visibility
|
|
5073
|
+
}));
|
|
5074
|
+
}
|
|
5075
|
+
function tableInfoFromStoredDocument(value) {
|
|
5076
|
+
if (!value) {
|
|
5077
|
+
return null;
|
|
5078
|
+
}
|
|
5079
|
+
const name = typeof value.name === "string" ? value.name : null;
|
|
5080
|
+
const tableNumber = typeof value.tableNumber === "number" ? value.tableNumber : null;
|
|
5081
|
+
if (!name || !tableNumber) {
|
|
5082
|
+
return null;
|
|
5083
|
+
}
|
|
5084
|
+
const componentPath = typeof value.componentPath === "string" ? value.componentPath : "";
|
|
5085
|
+
const fullName = typeof value.fullName === "string" ? value.fullName : getFullTableName(name, componentPath);
|
|
5086
|
+
return {
|
|
5087
|
+
tableNumber,
|
|
5088
|
+
name,
|
|
5089
|
+
componentPath,
|
|
5090
|
+
fullName,
|
|
5091
|
+
isSystem: value.isSystem === true,
|
|
5092
|
+
visibility: value.visibility === "private" ? "private" : "public",
|
|
5093
|
+
state: "active",
|
|
5094
|
+
createdAt: typeof value.createdAt === "number" ? value.createdAt : Date.now()
|
|
5095
|
+
};
|
|
5096
|
+
}
|
|
5097
|
+
function nextUserTableNumber(tables) {
|
|
5098
|
+
let next = FIRST_USER_TABLE_NUMBER;
|
|
5099
|
+
for (const table of tables) {
|
|
5100
|
+
if (table.tableNumber >= next) {
|
|
5101
|
+
next = table.tableNumber + 1;
|
|
5102
|
+
}
|
|
5103
|
+
}
|
|
5104
|
+
return next;
|
|
5105
|
+
}
|
|
5106
|
+
function createSystemMetadata(partial) {
|
|
5107
|
+
const now = partial?.updatedAt ?? Date.now();
|
|
5108
|
+
return {
|
|
5109
|
+
version: 1,
|
|
5110
|
+
bootstrapped: true,
|
|
5111
|
+
tableIdStrategy: "registry_u32",
|
|
5112
|
+
developerIdCodec: "convex_base32",
|
|
5113
|
+
nextUserTableNumber: partial?.nextUserTableNumber ?? FIRST_USER_TABLE_NUMBER,
|
|
5114
|
+
registryVersion: partial?.registryVersion ?? now,
|
|
5115
|
+
runtimeMetadataVersion: partial?.runtimeMetadataVersion,
|
|
5116
|
+
bootstrappedAt: partial?.bootstrappedAt ?? now,
|
|
5117
|
+
updatedAt: now
|
|
5118
|
+
};
|
|
5119
|
+
}
|
|
5120
|
+
async function readSystemMetadata(docstore) {
|
|
5121
|
+
const metadata = await docstore.getGlobal(SYSTEM_METADATA_GLOBAL_KEY);
|
|
5122
|
+
if (!metadata || metadata.bootstrapped !== true || metadata.version !== 1) {
|
|
5123
|
+
return null;
|
|
5124
|
+
}
|
|
5125
|
+
return createSystemMetadata({
|
|
5126
|
+
nextUserTableNumber: metadata.nextUserTableNumber,
|
|
5127
|
+
registryVersion: metadata.registryVersion ?? metadata.updatedAt,
|
|
5128
|
+
runtimeMetadataVersion: metadata.runtimeMetadataVersion,
|
|
5129
|
+
bootstrappedAt: metadata.bootstrappedAt,
|
|
5130
|
+
updatedAt: metadata.updatedAt
|
|
5131
|
+
});
|
|
5132
|
+
}
|
|
5133
|
+
function createTableNumberReservationKey(tableNumber) {
|
|
5134
|
+
return `${TABLE_NUMBER_RESERVATION_GLOBAL_PREFIX}${tableNumber}`;
|
|
5135
|
+
}
|
|
5136
|
+
async function ensureSystemTablesBootstrapped(docstore) {
|
|
5137
|
+
const existingMetadata = await readSystemMetadata(docstore);
|
|
5138
|
+
if (existingMetadata?.version === 1 && existingMetadata.bootstrapped) {
|
|
5139
|
+
return;
|
|
5140
|
+
}
|
|
5141
|
+
const now = Date.now();
|
|
5142
|
+
const tableInfos = getReservedSystemTables();
|
|
5143
|
+
const existingEntries = await docstore.scan(stringToHex("_tables"));
|
|
5144
|
+
const existingByName = new Map;
|
|
5145
|
+
for (const entry of existingEntries) {
|
|
5146
|
+
const info = tableInfoFromStoredDocument(entry.value.value);
|
|
5147
|
+
if (info) {
|
|
5148
|
+
existingByName.set(info.fullName, info);
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5151
|
+
const docs = [];
|
|
5152
|
+
const oracle = docstore.timestampOracle;
|
|
5153
|
+
const allocateTimestamp = oracle?.allocateTimestamp?.bind(oracle) ?? (() => BigInt(Date.now()));
|
|
5154
|
+
for (const table of tableInfos) {
|
|
5155
|
+
const existing = existingByName.get(table.fullName);
|
|
5156
|
+
const createdAt = existing?.createdAt ?? now;
|
|
5157
|
+
docs.push(createTableMetadataEntry(table, allocateTimestamp(), createdAt));
|
|
5158
|
+
}
|
|
5159
|
+
if (docs.length > 0) {
|
|
5160
|
+
await docstore.write(docs, new Set, "Overwrite");
|
|
5161
|
+
}
|
|
5162
|
+
const metadata = createSystemMetadata({
|
|
5163
|
+
nextUserTableNumber: nextUserTableNumber([...tableInfos, ...existingByName.values()]),
|
|
5164
|
+
registryVersion: now,
|
|
5165
|
+
bootstrappedAt: existingMetadata?.bootstrappedAt ?? now,
|
|
5166
|
+
updatedAt: now
|
|
5167
|
+
});
|
|
5168
|
+
await docstore.writeGlobal(SYSTEM_METADATA_GLOBAL_KEY, metadata);
|
|
5169
|
+
}
|
|
5170
|
+
function createTableMetadataEntryForUserTable(table, timestamp) {
|
|
5171
|
+
return createTableMetadataEntry(table, timestamp, table.createdAt);
|
|
5172
|
+
}
|
|
5173
|
+
function createTableMetadataEntry(table, timestamp, createdAt) {
|
|
5174
|
+
const docId = createTableMetadataDocumentId(table.fullName);
|
|
5175
|
+
const developerId = encodeDocumentId(SYSTEM_TABLE_NUMBERS._tables, stableMetadataInternalIdBytes(table.fullName));
|
|
5176
|
+
const storedTable = {
|
|
5177
|
+
_id: developerId,
|
|
5178
|
+
_creationTime: Number(timestamp),
|
|
5179
|
+
name: table.name,
|
|
5180
|
+
componentPath: table.componentPath,
|
|
5181
|
+
fullName: table.fullName,
|
|
5182
|
+
tableNumber: table.tableNumber,
|
|
5183
|
+
isSystem: table.isSystem,
|
|
5184
|
+
visibility: table.visibility,
|
|
5185
|
+
state: table.state,
|
|
5186
|
+
createdAt
|
|
5187
|
+
};
|
|
5188
|
+
return {
|
|
5189
|
+
ts: timestamp,
|
|
5190
|
+
id: docId,
|
|
5191
|
+
value: {
|
|
5192
|
+
id: docId,
|
|
5193
|
+
value: storedTable
|
|
5194
|
+
},
|
|
5195
|
+
prev_ts: null
|
|
5196
|
+
};
|
|
5197
|
+
}
|
|
5198
|
+
function createTableMetadataDocumentId(fullTableName) {
|
|
5199
|
+
const internalIdBytes = stableMetadataInternalIdBytes(fullTableName);
|
|
5200
|
+
return {
|
|
5201
|
+
table: stringToHex("_tables"),
|
|
5202
|
+
internalId: internalIdToHex(internalIdBytes),
|
|
5203
|
+
tableNumber: SYSTEM_TABLE_NUMBERS._tables
|
|
5204
|
+
};
|
|
5205
|
+
}
|
|
5206
|
+
function stableMetadataInternalIdBytes(fullTableName) {
|
|
5207
|
+
const bytes = new Uint8Array(16);
|
|
5208
|
+
const input = new TextEncoder().encode(`table:${fullTableName}`);
|
|
5209
|
+
for (let i2 = 0;i2 < input.length; i2 += 1) {
|
|
5210
|
+
const target = i2 % 16;
|
|
5211
|
+
bytes[target] = bytes[target] * 33 + input[i2] & 255;
|
|
5212
|
+
}
|
|
5213
|
+
return bytes;
|
|
5214
|
+
}
|
|
5215
|
+
function isSystemTableName(name) {
|
|
5216
|
+
return Object.hasOwn(SYSTEM_TABLE_NUMBERS, name);
|
|
5217
|
+
}
|
|
5218
|
+
var SYSTEM_METADATA_GLOBAL_KEY = "concave:system_metadata:v1", TABLE_NUMBER_RESERVATION_GLOBAL_PREFIX = "concave:table_number:", SYSTEM_TABLE_DEFINITIONS;
|
|
5219
|
+
var init_system_tables = __esm(() => {
|
|
5220
|
+
init_manifest();
|
|
5221
|
+
init_id_codec();
|
|
5222
|
+
init_interface();
|
|
5223
|
+
init_utils();
|
|
5224
|
+
init_module_loader();
|
|
5225
|
+
SYSTEM_TABLE_DEFINITIONS = [
|
|
5226
|
+
{ name: "_tables", visibility: "public" },
|
|
5227
|
+
{ name: "_scheduled_functions", visibility: "public" },
|
|
5228
|
+
{ name: "_storage", visibility: "public" },
|
|
5229
|
+
{ name: "_crons", visibility: "public" },
|
|
5230
|
+
{ name: "_indexes", visibility: "private" },
|
|
5231
|
+
{ name: "_schemas", visibility: "private" },
|
|
5232
|
+
{ name: "_components", visibility: "private" },
|
|
5233
|
+
{ name: "_component_definitions", visibility: "private" },
|
|
5234
|
+
{ name: "_schema_validation_progress", visibility: "private" }
|
|
5235
|
+
];
|
|
5236
|
+
});
|
|
5237
|
+
|
|
5238
|
+
// ../core/dist/system/internal.js
|
|
5239
|
+
function requireSystemCapability(capability) {
|
|
5240
|
+
const principal2 = getPrincipal();
|
|
5241
|
+
if (!principal2) {
|
|
5242
|
+
throw new Error("System functions require authentication context");
|
|
5243
|
+
}
|
|
5244
|
+
requireAuthorization(principal2, { kind: "management_operation", capability });
|
|
5245
|
+
}
|
|
5246
|
+
function createSystemFunctions(deps) {
|
|
5247
|
+
const { query, mutation } = deps;
|
|
4773
5248
|
return {
|
|
4774
5249
|
systemListComponents: query({
|
|
4775
5250
|
args: {},
|
|
4776
|
-
handler: async (
|
|
5251
|
+
handler: async (ctx) => {
|
|
4777
5252
|
requireSystemCapability("components:read");
|
|
4778
|
-
const
|
|
4779
|
-
const
|
|
4780
|
-
|
|
4781
|
-
|
|
4782
|
-
|
|
4783
|
-
componentPaths.add(module.componentPath);
|
|
4784
|
-
}
|
|
4785
|
-
}
|
|
4786
|
-
const components = [];
|
|
4787
|
-
for (const path of componentPaths) {
|
|
4788
|
-
const componentModules = modules.filter((m) => path === "" ? !m.componentPath || m.componentPath === "" : m.componentPath === path);
|
|
4789
|
-
const functions = await listSystemFunctions({ componentPath: path || undefined });
|
|
4790
|
-
components.push({
|
|
4791
|
-
path: path || "(root)",
|
|
4792
|
-
isRoot: path === "",
|
|
4793
|
-
moduleCount: componentModules.length,
|
|
5253
|
+
const components = await loadComponentRows(ctx);
|
|
5254
|
+
const withFunctionCounts = await Promise.all(components.map(async (component) => {
|
|
5255
|
+
const functions = await listSystemFunctions({ componentPath: component.componentPath || undefined });
|
|
5256
|
+
return {
|
|
5257
|
+
...component,
|
|
4794
5258
|
functionCount: functions.length
|
|
4795
|
-
}
|
|
4796
|
-
}
|
|
4797
|
-
return
|
|
4798
|
-
if (a.isRoot)
|
|
4799
|
-
return -1;
|
|
4800
|
-
if (b.isRoot)
|
|
4801
|
-
return 1;
|
|
4802
|
-
return a.path.localeCompare(b.path);
|
|
4803
|
-
});
|
|
5259
|
+
};
|
|
5260
|
+
}));
|
|
5261
|
+
return sortComponentRows(withFunctionCounts);
|
|
4804
5262
|
}
|
|
4805
5263
|
}),
|
|
4806
5264
|
systemListTables: query({
|
|
@@ -4809,25 +5267,40 @@ function createSystemFunctions(deps) {
|
|
|
4809
5267
|
requireSystemCapability("tables:read");
|
|
4810
5268
|
const targetComponent = componentPath ?? "";
|
|
4811
5269
|
const schema2 = await loadSchemaDefinition(targetComponent);
|
|
4812
|
-
|
|
5270
|
+
const schemaTables = new Map;
|
|
4813
5271
|
if (schema2?.tables) {
|
|
4814
|
-
|
|
4815
|
-
|
|
4816
|
-
try {
|
|
4817
|
-
const systemTables = await ctx.db.system.query("_tables").collect();
|
|
4818
|
-
tableEntries = systemTables.map((table) => ({
|
|
4819
|
-
name: table.name,
|
|
4820
|
-
exported: {
|
|
4821
|
-
indexes: table.indexes || [],
|
|
4822
|
-
searchIndexes: table.searchIndexes || [],
|
|
4823
|
-
vectorIndexes: table.vectorIndexes || [],
|
|
4824
|
-
documentType: null
|
|
4825
|
-
}
|
|
4826
|
-
}));
|
|
4827
|
-
} catch {
|
|
4828
|
-
tableEntries = [];
|
|
5272
|
+
for (const table of extractTablesFromSchema(schema2)) {
|
|
5273
|
+
schemaTables.set(table.name, table);
|
|
4829
5274
|
}
|
|
4830
5275
|
}
|
|
5276
|
+
const discoveredTables = new Map;
|
|
5277
|
+
for (const name of schemaTables.keys()) {
|
|
5278
|
+
discoveredTables.set(name, {
|
|
5279
|
+
name,
|
|
5280
|
+
isSystem: isSystemTable(name),
|
|
5281
|
+
visibility: getDefaultSystemTableVisibility(name)
|
|
5282
|
+
});
|
|
5283
|
+
}
|
|
5284
|
+
try {
|
|
5285
|
+
const systemTables = await ctx.db.system.query("_tables").collect();
|
|
5286
|
+
discoveredTables.clear();
|
|
5287
|
+
for (const table of systemTables.filter((entry) => (entry.componentPath ?? "") === targetComponent)) {
|
|
5288
|
+
discoveredTables.set(table.name, {
|
|
5289
|
+
name: table.name,
|
|
5290
|
+
isSystem: table.isSystem === true || isSystemTable(table.name),
|
|
5291
|
+
visibility: table.visibility === "private" ? "private" : "public"
|
|
5292
|
+
});
|
|
5293
|
+
}
|
|
5294
|
+
} catch {}
|
|
5295
|
+
const tableEntries = Array.from(discoveredTables.values()).map((metadata) => ({
|
|
5296
|
+
...metadata,
|
|
5297
|
+
exported: schemaTables.get(metadata.name)?.exported ?? {
|
|
5298
|
+
indexes: [],
|
|
5299
|
+
searchIndexes: [],
|
|
5300
|
+
vectorIndexes: [],
|
|
5301
|
+
documentType: null
|
|
5302
|
+
}
|
|
5303
|
+
}));
|
|
4831
5304
|
const tableInfo = await Promise.all(tableEntries.map(async (table) => {
|
|
4832
5305
|
const fullName = getFullTableName(table.name, targetComponent);
|
|
4833
5306
|
const documentCount = await countDocuments(ctx, fullName);
|
|
@@ -4838,6 +5311,8 @@ function createSystemFunctions(deps) {
|
|
|
4838
5311
|
name: table.name,
|
|
4839
5312
|
fullName,
|
|
4840
5313
|
componentPath: targetComponent || undefined,
|
|
5314
|
+
isSystem: table.isSystem,
|
|
5315
|
+
visibility: table.visibility,
|
|
4841
5316
|
documentCount,
|
|
4842
5317
|
indexes: buildIndexList(exported?.indexes),
|
|
4843
5318
|
searchIndexes: searchIndexes.map((idx) => typeof idx === "string" ? idx : idx.indexDescriptor),
|
|
@@ -4871,7 +5346,7 @@ function createSystemFunctions(deps) {
|
|
|
4871
5346
|
}
|
|
4872
5347
|
try {
|
|
4873
5348
|
const fullName = getFullTableName(tableName, targetComponent);
|
|
4874
|
-
const sampleDoc = await ctx
|
|
5349
|
+
const sampleDoc = await getTableQuery(ctx, fullName).first();
|
|
4875
5350
|
const fields = sampleDoc ? Object.keys(sampleDoc).map((key) => ({
|
|
4876
5351
|
name: key,
|
|
4877
5352
|
type: typeof sampleDoc[key],
|
|
@@ -4906,7 +5381,7 @@ function createSystemFunctions(deps) {
|
|
|
4906
5381
|
handler: async (ctx, args) => {
|
|
4907
5382
|
requireSystemCapability("documents:read");
|
|
4908
5383
|
const fullName = getFullTableName(args.tableName, args.componentPath ?? "");
|
|
4909
|
-
let query2 = ctx
|
|
5384
|
+
let query2 = getTableQuery(ctx, fullName);
|
|
4910
5385
|
if (args.orderBy && args.orderBy !== "_creationTime") {
|
|
4911
5386
|
const allDocs2 = await query2.collect();
|
|
4912
5387
|
const sorted = allDocs2.sort((a, b) => {
|
|
@@ -4957,7 +5432,7 @@ function createSystemFunctions(deps) {
|
|
|
4957
5432
|
handler: async (ctx, args) => {
|
|
4958
5433
|
requireSystemCapability("documents:write");
|
|
4959
5434
|
const fullName = getFullTableName(args.tableName, args.componentPath ?? "");
|
|
4960
|
-
const docs = await ctx
|
|
5435
|
+
const docs = await getTableQuery(ctx, fullName).collect();
|
|
4961
5436
|
for (const doc of docs) {
|
|
4962
5437
|
await ctx.db.delete(doc._id);
|
|
4963
5438
|
}
|
|
@@ -5253,6 +5728,83 @@ function resolveFunctionReference(functionPath, componentPath) {
|
|
|
5253
5728
|
}
|
|
5254
5729
|
return functionPath;
|
|
5255
5730
|
}
|
|
5731
|
+
async function loadComponentRows(ctx) {
|
|
5732
|
+
try {
|
|
5733
|
+
const rows = await ctx.db.system.query("_components").collect();
|
|
5734
|
+
if (rows.length > 0) {
|
|
5735
|
+
return rows.map((row) => normalizeStoredComponentRow(row));
|
|
5736
|
+
}
|
|
5737
|
+
} catch {}
|
|
5738
|
+
const modules = await listRegisteredModules();
|
|
5739
|
+
const moduleCountByComponent = new Map;
|
|
5740
|
+
const hasHttpByComponent = new Map;
|
|
5741
|
+
const componentPaths = new Set([""]);
|
|
5742
|
+
for (const module of modules) {
|
|
5743
|
+
const componentPath = module.componentPath ?? "";
|
|
5744
|
+
componentPaths.add(componentPath);
|
|
5745
|
+
moduleCountByComponent.set(componentPath, (moduleCountByComponent.get(componentPath) ?? 0) + 1);
|
|
5746
|
+
if (module.path === "http") {
|
|
5747
|
+
hasHttpByComponent.set(componentPath, true);
|
|
5748
|
+
}
|
|
5749
|
+
}
|
|
5750
|
+
return Array.from(componentPaths).map((componentPath) => ({
|
|
5751
|
+
componentPath,
|
|
5752
|
+
path: componentPath || "(root)",
|
|
5753
|
+
isRoot: componentPath === "",
|
|
5754
|
+
parentPath: componentPath === "" ? null : componentPath.includes("/") ? componentPath.split("/").slice(0, -1).join("/") : "",
|
|
5755
|
+
depth: componentPath === "" ? 0 : componentPath.split("/").length,
|
|
5756
|
+
moduleCount: moduleCountByComponent.get(componentPath) ?? 0,
|
|
5757
|
+
childCount: 0,
|
|
5758
|
+
functionCount: 0,
|
|
5759
|
+
sourceType: "local",
|
|
5760
|
+
hasHttp: hasHttpByComponent.get(componentPath) === true
|
|
5761
|
+
}));
|
|
5762
|
+
}
|
|
5763
|
+
function normalizeStoredComponentRow(row) {
|
|
5764
|
+
const componentPath = typeof row.componentPath === "string" ? row.componentPath : "";
|
|
5765
|
+
return {
|
|
5766
|
+
componentPath,
|
|
5767
|
+
path: typeof row.displayPath === "string" ? row.displayPath : typeof row.path === "string" && row.path.length > 0 ? row.path : componentPath || "(root)",
|
|
5768
|
+
isRoot: row.isRoot === true || componentPath === "",
|
|
5769
|
+
parentPath: row.parentPath === null ? null : typeof row.parentPath === "string" ? row.parentPath : componentPath === "" ? null : "",
|
|
5770
|
+
depth: typeof row.depth === "number" ? row.depth : componentPath === "" ? 0 : componentPath.split("/").length,
|
|
5771
|
+
moduleCount: typeof row.moduleCount === "number" ? row.moduleCount : 0,
|
|
5772
|
+
childCount: typeof row.childCount === "number" ? row.childCount : 0,
|
|
5773
|
+
functionCount: 0,
|
|
5774
|
+
sourceType: row.sourceType === "npm" ? "npm" : row.sourceType === "local" ? "local" : undefined,
|
|
5775
|
+
sourcePath: typeof row.sourcePath === "string" ? row.sourcePath : undefined,
|
|
5776
|
+
packageName: typeof row.packageName === "string" ? row.packageName : undefined,
|
|
5777
|
+
packageVersion: typeof row.packageVersion === "string" ? row.packageVersion : undefined,
|
|
5778
|
+
hasHttp: row.hasHttp === true
|
|
5779
|
+
};
|
|
5780
|
+
}
|
|
5781
|
+
function sortComponentRows(rows) {
|
|
5782
|
+
const childrenByParent = new Map;
|
|
5783
|
+
for (const row of rows) {
|
|
5784
|
+
const parentKey = row.parentPath ?? null;
|
|
5785
|
+
const siblings = childrenByParent.get(parentKey) ?? [];
|
|
5786
|
+
siblings.push(row);
|
|
5787
|
+
childrenByParent.set(parentKey, siblings);
|
|
5788
|
+
}
|
|
5789
|
+
for (const siblings of childrenByParent.values()) {
|
|
5790
|
+
siblings.sort((a, b) => {
|
|
5791
|
+
if (a.isRoot)
|
|
5792
|
+
return -1;
|
|
5793
|
+
if (b.isRoot)
|
|
5794
|
+
return 1;
|
|
5795
|
+
return a.componentPath.localeCompare(b.componentPath);
|
|
5796
|
+
});
|
|
5797
|
+
}
|
|
5798
|
+
const ordered = [];
|
|
5799
|
+
const visit = (parentPath) => {
|
|
5800
|
+
for (const row of childrenByParent.get(parentPath) ?? []) {
|
|
5801
|
+
ordered.push(row);
|
|
5802
|
+
visit(row.componentPath);
|
|
5803
|
+
}
|
|
5804
|
+
};
|
|
5805
|
+
visit(null);
|
|
5806
|
+
return ordered;
|
|
5807
|
+
}
|
|
5256
5808
|
async function loadSchemaDefinition(componentPath) {
|
|
5257
5809
|
try {
|
|
5258
5810
|
const module = await loadConvexModule("schema", {
|
|
@@ -5286,13 +5838,26 @@ function extractTableMetadata(schema2, tableName) {
|
|
|
5286
5838
|
}
|
|
5287
5839
|
async function countDocuments(ctx, tableName) {
|
|
5288
5840
|
try {
|
|
5289
|
-
const documents = await ctx
|
|
5841
|
+
const documents = await getTableQuery(ctx, tableName).collect();
|
|
5290
5842
|
return documents.length;
|
|
5291
5843
|
} catch (error) {
|
|
5292
5844
|
console.warn(`Failed to count documents for table ${tableName}:`, error);
|
|
5293
5845
|
return 0;
|
|
5294
5846
|
}
|
|
5295
5847
|
}
|
|
5848
|
+
function getTableQuery(ctx, fullTableName) {
|
|
5849
|
+
const { tableName } = parseFullTableName(fullTableName);
|
|
5850
|
+
if (isSystemTable(tableName)) {
|
|
5851
|
+
return ctx.db.system.query(tableName);
|
|
5852
|
+
}
|
|
5853
|
+
return ctx.db.query(fullTableName);
|
|
5854
|
+
}
|
|
5855
|
+
function getDefaultSystemTableVisibility(tableName) {
|
|
5856
|
+
if (!isSystemTable(tableName)) {
|
|
5857
|
+
return "public";
|
|
5858
|
+
}
|
|
5859
|
+
return isPublicSystemTable(tableName) ? "public" : "private";
|
|
5860
|
+
}
|
|
5296
5861
|
function buildIndexList(indexes) {
|
|
5297
5862
|
const base = ["by_id", "by_creation_time"];
|
|
5298
5863
|
if (!indexes || indexes.length === 0) {
|
|
@@ -5394,6 +5959,7 @@ var init_internal = __esm(() => {
|
|
|
5394
5959
|
init_interface();
|
|
5395
5960
|
init_execution_log();
|
|
5396
5961
|
init_auth();
|
|
5962
|
+
init_system_tables();
|
|
5397
5963
|
});
|
|
5398
5964
|
|
|
5399
5965
|
// ../core/dist/system/system-functions-module.js
|
|
@@ -5551,8 +6117,9 @@ class ModuleRegistry {
|
|
|
5551
6117
|
const normalized = normalizeModuleListing(listing);
|
|
5552
6118
|
if (!normalized)
|
|
5553
6119
|
continue;
|
|
5554
|
-
|
|
5555
|
-
|
|
6120
|
+
const resultKey = `${normalized.componentPath ?? scope ?? ""}:${normalized.path}`;
|
|
6121
|
+
if (!results.has(resultKey)) {
|
|
6122
|
+
results.set(resultKey, {
|
|
5556
6123
|
...normalized,
|
|
5557
6124
|
scope: scope || undefined,
|
|
5558
6125
|
componentPath: normalized.componentPath ?? (scope || undefined)
|
|
@@ -5871,8 +6438,10 @@ var init_module_loader = __esm(() => {
|
|
|
5871
6438
|
class SchemaValidator {
|
|
5872
6439
|
schemaCache = new Map;
|
|
5873
6440
|
componentPath;
|
|
5874
|
-
|
|
6441
|
+
tableRegistry;
|
|
6442
|
+
constructor(componentPath, tableRegistry) {
|
|
5875
6443
|
this.componentPath = componentPath;
|
|
6444
|
+
this.tableRegistry = tableRegistry;
|
|
5876
6445
|
}
|
|
5877
6446
|
async loadTableSchema(tableName) {
|
|
5878
6447
|
if (this.schemaCache.has(tableName)) {
|
|
@@ -5915,8 +6484,11 @@ class SchemaValidator {
|
|
|
5915
6484
|
return;
|
|
5916
6485
|
}
|
|
5917
6486
|
try {
|
|
6487
|
+
const tableNumberToName = this.tableRegistry ? new Map((await this.tableRegistry.listTables()).map((table) => [table.tableNumber, table.fullName])) : undefined;
|
|
5918
6488
|
validateValidator(tableSchema, omit(document, ["_id", "_creationTime"]), "", {
|
|
5919
|
-
componentPath: this.componentPath ?? ""
|
|
6489
|
+
componentPath: this.componentPath ?? "",
|
|
6490
|
+
tableRegistry: this.tableRegistry,
|
|
6491
|
+
tableNumberToName
|
|
5920
6492
|
});
|
|
5921
6493
|
} catch (error) {
|
|
5922
6494
|
throw new ValidatorError(`Failed to insert or update a document in table "${tableName}" because it does not match the schema: ${error.message}`);
|
|
@@ -6014,6 +6586,16 @@ Path: ${formatPath(path)}
|
|
|
6014
6586
|
Value: ${formatValue(value)}
|
|
6015
6587
|
Validator: v.id("${validator2.tableName}")`);
|
|
6016
6588
|
}
|
|
6589
|
+
if (isValidDocumentId(value)) {
|
|
6590
|
+
const tableName2 = tableNameFromConvexId(value, options);
|
|
6591
|
+
if (!tableName2 || !isMatchingValidatorTable(tableName2, validator2.tableName, options.componentPath)) {
|
|
6592
|
+
throw new Error(`Value does not match validator.
|
|
6593
|
+
Path: ${formatPath(path)}
|
|
6594
|
+
Value: ${formatValue(value)}
|
|
6595
|
+
Validator: v.id("${validator2.tableName}")`);
|
|
6596
|
+
}
|
|
6597
|
+
return;
|
|
6598
|
+
}
|
|
6017
6599
|
const tableName = tableNameFromId(value);
|
|
6018
6600
|
if (!tableName || !isMatchingValidatorTable(tableName, validator2.tableName, options.componentPath)) {
|
|
6019
6601
|
throw new Error(`Value does not match validator.
|
|
@@ -6067,302 +6649,88 @@ Validator: v.object({...})`);
|
|
|
6067
6649
|
}
|
|
6068
6650
|
for (const [k, { fieldType, optional }] of Object.entries(validator2.value)) {
|
|
6069
6651
|
if (value[k] === undefined) {
|
|
6070
|
-
if (!optional) {
|
|
6071
|
-
throw new Error(`Object is missing the required field \`${k}\`. Consider wrapping the field validator in \`v.optional(...)\` if this is expected.
|
|
6072
|
-
|
|
6073
|
-
Object: ${JSON.stringify(value)}
|
|
6074
|
-
Validator: v.object({...})`);
|
|
6075
|
-
}
|
|
6076
|
-
} else {
|
|
6077
|
-
const fieldPath = path ? `${path}.${k}` : `.${k}`;
|
|
6078
|
-
validateValidator(fieldType, value[k], fieldPath, options);
|
|
6079
|
-
}
|
|
6080
|
-
}
|
|
6081
|
-
for (const k of Object.keys(value)) {
|
|
6082
|
-
if (validator2.value[k] === undefined) {
|
|
6083
|
-
throw new Error(`Object contains extra field \`${k}\` that is not in the validator.
|
|
6084
|
-
|
|
6085
|
-
Object: ${JSON.stringify(value)}
|
|
6086
|
-
Validator: v.object({...})`);
|
|
6087
|
-
}
|
|
6088
|
-
}
|
|
6089
|
-
return;
|
|
6090
|
-
}
|
|
6091
|
-
}
|
|
6092
|
-
}
|
|
6093
|
-
function tableNameFromId(id) {
|
|
6094
|
-
const parts = deserializeDeveloperId(id);
|
|
6095
|
-
if (!parts) {
|
|
6096
|
-
return null;
|
|
6097
|
-
}
|
|
6098
|
-
return hexToString(parts.table);
|
|
6099
|
-
}
|
|
6100
|
-
function isMatchingValidatorTable(idTableName, validatorTableName, componentPath) {
|
|
6101
|
-
if (idTableName === validatorTableName) {
|
|
6102
|
-
return true;
|
|
6103
|
-
}
|
|
6104
|
-
const { tableName: validatorBareName } = parseFullTableName(validatorTableName);
|
|
6105
|
-
const { tableName: idBareName } = parseFullTableName(idTableName);
|
|
6106
|
-
if (componentPath !== undefined) {
|
|
6107
|
-
const expectedFullName = getFullTableName(validatorBareName, componentPath);
|
|
6108
|
-
return idTableName === expectedFullName;
|
|
6109
|
-
}
|
|
6110
|
-
return idBareName === validatorBareName;
|
|
6111
|
-
}
|
|
6112
|
-
function isSimpleObject2(value) {
|
|
6113
|
-
const isObject2 = typeof value === "object";
|
|
6114
|
-
const prototype = Object.getPrototypeOf(value);
|
|
6115
|
-
const isSimple = prototype === null || prototype === Object.prototype || prototype?.constructor?.name === "Object";
|
|
6116
|
-
return isObject2 && isSimple;
|
|
6117
|
-
}
|
|
6118
|
-
var ValidatorError;
|
|
6119
|
-
var init_validator2 = __esm(() => {
|
|
6120
|
-
init_interface();
|
|
6121
|
-
init_module_loader();
|
|
6122
|
-
ValidatorError = class ValidatorError extends Error {
|
|
6123
|
-
path;
|
|
6124
|
-
constructor(message2, path = "") {
|
|
6125
|
-
super(message2);
|
|
6126
|
-
this.path = path;
|
|
6127
|
-
this.name = "ValidatorError";
|
|
6128
|
-
}
|
|
6129
|
-
};
|
|
6130
|
-
});
|
|
6131
|
-
|
|
6132
|
-
// ../core/dist/id-codec/base32.js
|
|
6133
|
-
function base32Encode(data) {
|
|
6134
|
-
if (data.length === 0)
|
|
6135
|
-
return "";
|
|
6136
|
-
let result = "";
|
|
6137
|
-
let buffer = 0;
|
|
6138
|
-
let bitsLeft = 0;
|
|
6139
|
-
for (const byte of data) {
|
|
6140
|
-
buffer = buffer << 8 | byte;
|
|
6141
|
-
bitsLeft += 8;
|
|
6142
|
-
while (bitsLeft >= 5) {
|
|
6143
|
-
bitsLeft -= 5;
|
|
6144
|
-
const index = buffer >> bitsLeft & 31;
|
|
6145
|
-
result += ALPHABET[index];
|
|
6146
|
-
}
|
|
6147
|
-
}
|
|
6148
|
-
if (bitsLeft > 0) {
|
|
6149
|
-
const index = buffer << 5 - bitsLeft & 31;
|
|
6150
|
-
result += ALPHABET[index];
|
|
6151
|
-
}
|
|
6152
|
-
return result;
|
|
6153
|
-
}
|
|
6154
|
-
function base32Decode(str) {
|
|
6155
|
-
if (str.length === 0)
|
|
6156
|
-
return new Uint8Array(0);
|
|
6157
|
-
const outputLength = Math.floor(str.length * 5 / 8);
|
|
6158
|
-
const result = new Uint8Array(outputLength);
|
|
6159
|
-
let buffer = 0;
|
|
6160
|
-
let bitsLeft = 0;
|
|
6161
|
-
let outputIndex = 0;
|
|
6162
|
-
for (const char of str) {
|
|
6163
|
-
const value = ALPHABET_MAP.get(char);
|
|
6164
|
-
if (value === undefined) {
|
|
6165
|
-
throw new Error(`Invalid base32 character: ${char}`);
|
|
6166
|
-
}
|
|
6167
|
-
buffer = buffer << 5 | value;
|
|
6168
|
-
bitsLeft += 5;
|
|
6169
|
-
if (bitsLeft >= 8) {
|
|
6170
|
-
bitsLeft -= 8;
|
|
6171
|
-
result[outputIndex++] = buffer >> bitsLeft & 255;
|
|
6172
|
-
}
|
|
6173
|
-
}
|
|
6174
|
-
return result;
|
|
6175
|
-
}
|
|
6176
|
-
function isValidBase32(str) {
|
|
6177
|
-
for (const char of str) {
|
|
6178
|
-
if (!ALPHABET_MAP.has(char)) {
|
|
6179
|
-
return false;
|
|
6180
|
-
}
|
|
6181
|
-
}
|
|
6182
|
-
return true;
|
|
6183
|
-
}
|
|
6184
|
-
var ALPHABET = "0123456789abcdefghjkmnpqrstvwxyz", ALPHABET_MAP;
|
|
6185
|
-
var init_base32 = __esm(() => {
|
|
6186
|
-
ALPHABET_MAP = new Map;
|
|
6187
|
-
for (let i2 = 0;i2 < ALPHABET.length; i2++) {
|
|
6188
|
-
ALPHABET_MAP.set(ALPHABET[i2], i2);
|
|
6189
|
-
ALPHABET_MAP.set(ALPHABET[i2].toUpperCase(), i2);
|
|
6190
|
-
}
|
|
6191
|
-
ALPHABET_MAP.set("i", 1);
|
|
6192
|
-
ALPHABET_MAP.set("I", 1);
|
|
6193
|
-
ALPHABET_MAP.set("l", 1);
|
|
6194
|
-
ALPHABET_MAP.set("L", 1);
|
|
6195
|
-
ALPHABET_MAP.set("o", 0);
|
|
6196
|
-
ALPHABET_MAP.set("O", 0);
|
|
6197
|
-
});
|
|
6198
|
-
|
|
6199
|
-
// ../core/dist/id-codec/vint.js
|
|
6200
|
-
function vintEncode(value) {
|
|
6201
|
-
if (value < 0) {
|
|
6202
|
-
throw new Error("VInt cannot encode negative numbers");
|
|
6203
|
-
}
|
|
6204
|
-
if (value > 4294967295) {
|
|
6205
|
-
throw new Error("VInt cannot encode values larger than 2^32-1");
|
|
6206
|
-
}
|
|
6207
|
-
value = value >>> 0;
|
|
6208
|
-
if (value < 128) {
|
|
6209
|
-
return new Uint8Array([value]);
|
|
6210
|
-
}
|
|
6211
|
-
if (value < 16512) {
|
|
6212
|
-
const adjusted2 = value - 128;
|
|
6213
|
-
return new Uint8Array([128 | adjusted2 >> 8 & 63, adjusted2 & 255]);
|
|
6214
|
-
}
|
|
6215
|
-
if (value < 2113664) {
|
|
6216
|
-
const adjusted2 = value - 16512;
|
|
6217
|
-
return new Uint8Array([192 | adjusted2 >> 16 & 31, adjusted2 >> 8 & 255, adjusted2 & 255]);
|
|
6218
|
-
}
|
|
6219
|
-
if (value < 270549120) {
|
|
6220
|
-
const adjusted2 = value - 2113664;
|
|
6221
|
-
return new Uint8Array([
|
|
6222
|
-
224 | adjusted2 >> 24 & 15,
|
|
6223
|
-
adjusted2 >> 16 & 255,
|
|
6224
|
-
adjusted2 >> 8 & 255,
|
|
6225
|
-
adjusted2 & 255
|
|
6226
|
-
]);
|
|
6227
|
-
}
|
|
6228
|
-
const adjusted = value - 270549120;
|
|
6229
|
-
return new Uint8Array([
|
|
6230
|
-
240 | adjusted >> 32 & 7,
|
|
6231
|
-
adjusted >> 24 & 255,
|
|
6232
|
-
adjusted >> 16 & 255,
|
|
6233
|
-
adjusted >> 8 & 255,
|
|
6234
|
-
adjusted & 255
|
|
6235
|
-
]);
|
|
6236
|
-
}
|
|
6237
|
-
function vintDecode(data, offset = 0) {
|
|
6238
|
-
if (offset >= data.length) {
|
|
6239
|
-
throw new Error("VInt decode: unexpected end of data");
|
|
6240
|
-
}
|
|
6241
|
-
const first = data[offset];
|
|
6242
|
-
if ((first & 128) === 0) {
|
|
6243
|
-
return { value: first, bytesRead: 1 };
|
|
6244
|
-
}
|
|
6245
|
-
if ((first & 192) === 128) {
|
|
6246
|
-
if (offset + 1 >= data.length) {
|
|
6247
|
-
throw new Error("VInt decode: truncated 2-byte encoding");
|
|
6248
|
-
}
|
|
6249
|
-
const value = 128 + ((first & 63) << 8 | data[offset + 1]);
|
|
6250
|
-
return { value, bytesRead: 2 };
|
|
6251
|
-
}
|
|
6252
|
-
if ((first & 224) === 192) {
|
|
6253
|
-
if (offset + 2 >= data.length) {
|
|
6254
|
-
throw new Error("VInt decode: truncated 3-byte encoding");
|
|
6255
|
-
}
|
|
6256
|
-
const value = 16512 + ((first & 31) << 16 | data[offset + 1] << 8 | data[offset + 2]);
|
|
6257
|
-
return { value, bytesRead: 3 };
|
|
6258
|
-
}
|
|
6259
|
-
if ((first & 240) === 224) {
|
|
6260
|
-
if (offset + 3 >= data.length) {
|
|
6261
|
-
throw new Error("VInt decode: truncated 4-byte encoding");
|
|
6262
|
-
}
|
|
6263
|
-
const value = 2113664 + ((first & 15) << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]);
|
|
6264
|
-
return { value: value >>> 0, bytesRead: 4 };
|
|
6265
|
-
}
|
|
6266
|
-
if ((first & 248) === 240) {
|
|
6267
|
-
if (offset + 4 >= data.length) {
|
|
6268
|
-
throw new Error("VInt decode: truncated 5-byte encoding");
|
|
6269
|
-
}
|
|
6270
|
-
const high = first & 7;
|
|
6271
|
-
const low = (data[offset + 1] << 24 | data[offset + 2] << 16 | data[offset + 3] << 8 | data[offset + 4]) >>> 0;
|
|
6272
|
-
const value = 270549120 + high * 4294967296 + low;
|
|
6273
|
-
return { value: value >>> 0, bytesRead: 5 };
|
|
6274
|
-
}
|
|
6275
|
-
throw new Error("VInt decode: invalid prefix");
|
|
6276
|
-
}
|
|
6277
|
-
|
|
6278
|
-
// ../core/dist/id-codec/fletcher16.js
|
|
6279
|
-
function fletcher16(data) {
|
|
6280
|
-
let sum1 = 0;
|
|
6281
|
-
let sum2 = 0;
|
|
6282
|
-
for (const byte of data) {
|
|
6283
|
-
sum1 = (sum1 + byte) % 255;
|
|
6284
|
-
sum2 = (sum2 + sum1) % 255;
|
|
6285
|
-
}
|
|
6286
|
-
return new Uint8Array([sum1, sum2]);
|
|
6287
|
-
}
|
|
6288
|
-
function verifyFletcher16(data, checksum) {
|
|
6289
|
-
if (checksum.length !== 2)
|
|
6290
|
-
return false;
|
|
6291
|
-
const computed = fletcher16(data);
|
|
6292
|
-
return computed[0] === checksum[0] && computed[1] === checksum[1];
|
|
6293
|
-
}
|
|
6294
|
-
|
|
6295
|
-
// ../core/dist/utils/crypto.js
|
|
6296
|
-
var weakRandomState;
|
|
6297
|
-
var init_crypto = __esm(() => {
|
|
6298
|
-
weakRandomState = (Date.now() ^ 2654435769) >>> 0;
|
|
6299
|
-
});
|
|
6300
|
-
|
|
6301
|
-
// ../core/dist/id-codec/document-id.js
|
|
6302
|
-
function encodeDocumentId(tableNumber, internalId) {
|
|
6303
|
-
if (internalId.length !== INTERNAL_ID_LENGTH) {
|
|
6304
|
-
throw new Error(`Internal ID must be exactly ${INTERNAL_ID_LENGTH} bytes, got ${internalId.length}`);
|
|
6305
|
-
}
|
|
6306
|
-
if (tableNumber < 1 || tableNumber > 4294967295) {
|
|
6307
|
-
throw new Error(`Table number must be between 1 and 2^32-1, got ${tableNumber}`);
|
|
6308
|
-
}
|
|
6309
|
-
const tableBytes = vintEncode(tableNumber);
|
|
6310
|
-
const payload = new Uint8Array(tableBytes.length + INTERNAL_ID_LENGTH);
|
|
6311
|
-
payload.set(tableBytes, 0);
|
|
6312
|
-
payload.set(internalId, tableBytes.length);
|
|
6313
|
-
const checksum = fletcher16(payload);
|
|
6314
|
-
const final = new Uint8Array(payload.length + 2);
|
|
6315
|
-
final.set(payload, 0);
|
|
6316
|
-
final.set(checksum, payload.length);
|
|
6317
|
-
return base32Encode(final);
|
|
6318
|
-
}
|
|
6319
|
-
function decodeDocumentId(encoded) {
|
|
6320
|
-
if (encoded.length < MIN_ENCODED_LENGTH || encoded.length > MAX_ENCODED_LENGTH) {
|
|
6321
|
-
throw new Error(`Invalid document ID length: ${encoded.length} (expected ${MIN_ENCODED_LENGTH}-${MAX_ENCODED_LENGTH})`);
|
|
6322
|
-
}
|
|
6323
|
-
if (!isValidBase32(encoded)) {
|
|
6324
|
-
throw new Error("Invalid document ID: contains invalid base32 characters");
|
|
6325
|
-
}
|
|
6326
|
-
const bytes = base32Decode(encoded);
|
|
6327
|
-
if (bytes.length < 19) {
|
|
6328
|
-
throw new Error(`Invalid document ID: decoded to ${bytes.length} bytes (minimum 19)`);
|
|
6329
|
-
}
|
|
6330
|
-
const checksum = bytes.slice(bytes.length - 2);
|
|
6331
|
-
const payload = bytes.slice(0, bytes.length - 2);
|
|
6332
|
-
if (!verifyFletcher16(payload, checksum)) {
|
|
6333
|
-
throw new Error("Invalid document ID: checksum verification failed");
|
|
6652
|
+
if (!optional) {
|
|
6653
|
+
throw new Error(`Object is missing the required field \`${k}\`. Consider wrapping the field validator in \`v.optional(...)\` if this is expected.
|
|
6654
|
+
|
|
6655
|
+
Object: ${JSON.stringify(value)}
|
|
6656
|
+
Validator: v.object({...})`);
|
|
6657
|
+
}
|
|
6658
|
+
} else {
|
|
6659
|
+
const fieldPath = path ? `${path}.${k}` : `.${k}`;
|
|
6660
|
+
validateValidator(fieldType, value[k], fieldPath, options);
|
|
6661
|
+
}
|
|
6662
|
+
}
|
|
6663
|
+
for (const k of Object.keys(value)) {
|
|
6664
|
+
if (validator2.value[k] === undefined) {
|
|
6665
|
+
throw new Error(`Object contains extra field \`${k}\` that is not in the validator.
|
|
6666
|
+
|
|
6667
|
+
Object: ${JSON.stringify(value)}
|
|
6668
|
+
Validator: v.object({...})`);
|
|
6669
|
+
}
|
|
6670
|
+
}
|
|
6671
|
+
return;
|
|
6672
|
+
}
|
|
6334
6673
|
}
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6674
|
+
}
|
|
6675
|
+
function tableNameFromId(id) {
|
|
6676
|
+
const parts = deserializeDeveloperId(id);
|
|
6677
|
+
if (!parts) {
|
|
6678
|
+
return null;
|
|
6339
6679
|
}
|
|
6340
|
-
return
|
|
6680
|
+
return hexToString(parts.table);
|
|
6341
6681
|
}
|
|
6342
|
-
function
|
|
6682
|
+
function tableNameFromConvexId(id, options) {
|
|
6343
6683
|
try {
|
|
6344
|
-
decodeDocumentId(
|
|
6345
|
-
|
|
6684
|
+
const decoded = decodeDocumentId(id);
|
|
6685
|
+
const fromMap = options.tableNumberToName?.get(decoded.tableNumber);
|
|
6686
|
+
if (fromMap) {
|
|
6687
|
+
return fromMap;
|
|
6688
|
+
}
|
|
6689
|
+
return null;
|
|
6346
6690
|
} catch {
|
|
6347
|
-
return
|
|
6691
|
+
return null;
|
|
6348
6692
|
}
|
|
6349
6693
|
}
|
|
6350
|
-
function
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
hex += internalId[i2].toString(16).padStart(2, "0");
|
|
6694
|
+
function isMatchingValidatorTable(idTableName, validatorTableName, componentPath) {
|
|
6695
|
+
if (idTableName === validatorTableName) {
|
|
6696
|
+
return true;
|
|
6354
6697
|
}
|
|
6355
|
-
|
|
6698
|
+
const { tableName: validatorBareName } = parseFullTableName(validatorTableName);
|
|
6699
|
+
const { tableName: idBareName } = parseFullTableName(idTableName);
|
|
6700
|
+
if (componentPath !== undefined) {
|
|
6701
|
+
const expectedFullName = getFullTableName(validatorBareName, componentPath);
|
|
6702
|
+
return idTableName === expectedFullName;
|
|
6703
|
+
}
|
|
6704
|
+
return idBareName === validatorBareName;
|
|
6356
6705
|
}
|
|
6357
|
-
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
|
|
6706
|
+
function isSimpleObject2(value) {
|
|
6707
|
+
const isObject2 = typeof value === "object";
|
|
6708
|
+
const prototype = Object.getPrototypeOf(value);
|
|
6709
|
+
const isSimple = prototype === null || prototype === Object.prototype || prototype?.constructor?.name === "Object";
|
|
6710
|
+
return isObject2 && isSimple;
|
|
6711
|
+
}
|
|
6712
|
+
var ValidatorError;
|
|
6713
|
+
var init_validator2 = __esm(() => {
|
|
6714
|
+
init_utils();
|
|
6715
|
+
init_interface();
|
|
6716
|
+
init_module_loader();
|
|
6717
|
+
init_id_codec();
|
|
6718
|
+
ValidatorError = class ValidatorError extends Error {
|
|
6719
|
+
path;
|
|
6720
|
+
constructor(message2, path = "") {
|
|
6721
|
+
super(message2);
|
|
6722
|
+
this.path = path;
|
|
6723
|
+
this.name = "ValidatorError";
|
|
6724
|
+
}
|
|
6725
|
+
};
|
|
6361
6726
|
});
|
|
6362
6727
|
|
|
6363
6728
|
// ../core/dist/docstore/interface.js
|
|
6364
6729
|
function documentIdKey(id) {
|
|
6365
|
-
const tableKey = id.table && id.table.length > 0 ? id.table : id.tableNumber !== undefined && Number.isInteger(id.tableNumber) && id.tableNumber > 0 ? `#${id.tableNumber}` :
|
|
6730
|
+
const tableKey = id.table && id.table.length > 0 ? id.table : id.tableNumber !== undefined && Number.isInteger(id.tableNumber) && id.tableNumber > 0 ? `#${id.tableNumber}` : null;
|
|
6731
|
+
if (!tableKey) {
|
|
6732
|
+
throw new Error("Invalid document ID: missing table and tableNumber");
|
|
6733
|
+
}
|
|
6366
6734
|
return `${tableKey}:${id.internalId}`;
|
|
6367
6735
|
}
|
|
6368
6736
|
var Order;
|
|
@@ -6392,6 +6760,9 @@ function extractSearchContent(docValue, searchField) {
|
|
|
6392
6760
|
}
|
|
6393
6761
|
return null;
|
|
6394
6762
|
}
|
|
6763
|
+
// ../core/dist/queryengine/indexing/index-manager.js
|
|
6764
|
+
init_utils();
|
|
6765
|
+
|
|
6395
6766
|
// ../core/dist/queryengine/indexing/index-key-codec.js
|
|
6396
6767
|
var TypeTag;
|
|
6397
6768
|
(function(TypeTag2) {
|
|
@@ -6441,8 +6812,9 @@ function encodeBigInt(n) {
|
|
|
6441
6812
|
return bytes;
|
|
6442
6813
|
}
|
|
6443
6814
|
function encodeString(s) {
|
|
6444
|
-
|
|
6445
|
-
|
|
6815
|
+
return encodeEscapedBytes(new TextEncoder().encode(s));
|
|
6816
|
+
}
|
|
6817
|
+
function encodeEscapedBytes(raw) {
|
|
6446
6818
|
let nullCount = 0;
|
|
6447
6819
|
for (const byte of raw) {
|
|
6448
6820
|
if (byte === 0)
|
|
@@ -6506,11 +6878,10 @@ function encodeValue(value) {
|
|
|
6506
6878
|
}
|
|
6507
6879
|
if (value instanceof ArrayBuffer || value instanceof Uint8Array) {
|
|
6508
6880
|
const bytes = value instanceof Uint8Array ? value : new Uint8Array(value);
|
|
6509
|
-
const
|
|
6881
|
+
const encoded = encodeEscapedBytes(bytes);
|
|
6882
|
+
const result = new Uint8Array(1 + encoded.length);
|
|
6510
6883
|
result[0] = TypeTag.Bytes;
|
|
6511
|
-
result.set(
|
|
6512
|
-
result[result.length - 2] = 0;
|
|
6513
|
-
result[result.length - 1] = 0;
|
|
6884
|
+
result.set(encoded, 1);
|
|
6514
6885
|
return result;
|
|
6515
6886
|
}
|
|
6516
6887
|
throw new Error(`Cannot encode value of type ${typeof value} in index key`);
|
|
@@ -6627,9 +6998,11 @@ class SchemaService {
|
|
|
6627
6998
|
tableCache = new Map;
|
|
6628
6999
|
schemaValidator;
|
|
6629
7000
|
componentPath;
|
|
6630
|
-
|
|
7001
|
+
tableRegistry;
|
|
7002
|
+
constructor(componentPath, tableRegistry) {
|
|
6631
7003
|
this.componentPath = componentPath;
|
|
6632
|
-
this.
|
|
7004
|
+
this.tableRegistry = tableRegistry;
|
|
7005
|
+
this.schemaValidator = new SchemaValidator(componentPath, tableRegistry);
|
|
6633
7006
|
}
|
|
6634
7007
|
async validate(tableName, document) {
|
|
6635
7008
|
try {
|
|
@@ -6754,6 +7127,10 @@ class SchemaService {
|
|
|
6754
7127
|
return this.cachedSchemaDefinition;
|
|
6755
7128
|
}
|
|
6756
7129
|
}
|
|
7130
|
+
|
|
7131
|
+
// ../core/dist/queryengine/index-query.js
|
|
7132
|
+
init_utils();
|
|
7133
|
+
|
|
6757
7134
|
// ../core/dist/observability/udf-trace.js
|
|
6758
7135
|
init_context_storage();
|
|
6759
7136
|
var TRACE_CONTEXT = new ContextStorage;
|
|
@@ -6997,11 +7374,10 @@ function evaluateFieldPath(fieldPath, document) {
|
|
|
6997
7374
|
}
|
|
6998
7375
|
return current;
|
|
6999
7376
|
}
|
|
7000
|
-
// ../core/dist/id-codec/index.js
|
|
7001
|
-
init_base32();
|
|
7002
|
-
init_document_id();
|
|
7003
7377
|
|
|
7004
7378
|
// ../core/dist/queryengine/developer-id.js
|
|
7379
|
+
init_utils();
|
|
7380
|
+
init_id_codec();
|
|
7005
7381
|
function parseDeveloperId(developerId) {
|
|
7006
7382
|
if (isValidDocumentId(developerId)) {
|
|
7007
7383
|
try {
|
|
@@ -7019,6 +7395,25 @@ function parseDeveloperId(developerId) {
|
|
|
7019
7395
|
}
|
|
7020
7396
|
return { table: parts.table, internalId: parts.internalId };
|
|
7021
7397
|
}
|
|
7398
|
+
async function parseDeveloperIdWithTableRegistry(developerId, tableRegistry) {
|
|
7399
|
+
if (isValidDocumentId(developerId)) {
|
|
7400
|
+
try {
|
|
7401
|
+
const decoded = decodeDocumentId(developerId);
|
|
7402
|
+
const tableInfo = await tableRegistry.getTableInfo(decoded.tableNumber);
|
|
7403
|
+
if (!tableInfo) {
|
|
7404
|
+
return null;
|
|
7405
|
+
}
|
|
7406
|
+
return {
|
|
7407
|
+
table: stringToHex(tableInfo.fullName),
|
|
7408
|
+
internalId: internalIdToHex(decoded.internalId),
|
|
7409
|
+
tableNumber: decoded.tableNumber
|
|
7410
|
+
};
|
|
7411
|
+
} catch {
|
|
7412
|
+
return null;
|
|
7413
|
+
}
|
|
7414
|
+
}
|
|
7415
|
+
return parseDeveloperId(developerId);
|
|
7416
|
+
}
|
|
7022
7417
|
function parseStorageId(storageId) {
|
|
7023
7418
|
const parsed = parseDeveloperId(storageId);
|
|
7024
7419
|
if (parsed) {
|
|
@@ -7035,7 +7430,12 @@ function parseStorageId(storageId) {
|
|
|
7035
7430
|
function isTablePlaceholder(table) {
|
|
7036
7431
|
return table.startsWith("#");
|
|
7037
7432
|
}
|
|
7433
|
+
|
|
7434
|
+
// ../core/dist/query/query-runtime.js
|
|
7435
|
+
init_utils();
|
|
7436
|
+
|
|
7038
7437
|
// ../core/dist/utils/keyspace.js
|
|
7438
|
+
init_utils();
|
|
7039
7439
|
var TABLE_PREFIX = "table";
|
|
7040
7440
|
var INDEX_PREFIX = "index";
|
|
7041
7441
|
function encodeComponent(component) {
|
|
@@ -7079,10 +7479,15 @@ function decodeIndexId(indexId) {
|
|
|
7079
7479
|
|
|
7080
7480
|
// ../core/dist/query/planner.js
|
|
7081
7481
|
init_interface();
|
|
7482
|
+
init_utils();
|
|
7483
|
+
|
|
7082
7484
|
// ../core/dist/query/actions.js
|
|
7485
|
+
init_utils();
|
|
7083
7486
|
init_interface();
|
|
7084
7487
|
|
|
7085
7488
|
// ../core/dist/queryengine/indexing/read-write-set.js
|
|
7489
|
+
init_utils();
|
|
7490
|
+
|
|
7086
7491
|
class RangeSet {
|
|
7087
7492
|
ranges = new Map;
|
|
7088
7493
|
addDocument(docId) {
|
|
@@ -7193,6 +7598,8 @@ function deserializeKeyRange(serialized) {
|
|
|
7193
7598
|
}
|
|
7194
7599
|
|
|
7195
7600
|
// ../core/dist/kernel/access-log.js
|
|
7601
|
+
init_utils();
|
|
7602
|
+
|
|
7196
7603
|
class AccessLog {
|
|
7197
7604
|
ranges = new RangeSet;
|
|
7198
7605
|
addDocument(docId) {
|
|
@@ -7217,104 +7624,9 @@ class AccessLog {
|
|
|
7217
7624
|
}
|
|
7218
7625
|
}
|
|
7219
7626
|
|
|
7220
|
-
// ../core/dist/
|
|
7627
|
+
// ../core/dist/kernel/kernel-context.js
|
|
7221
7628
|
init_interface();
|
|
7222
7629
|
|
|
7223
|
-
class MemoryTableRegistry {
|
|
7224
|
-
tablesByName = new Map;
|
|
7225
|
-
tablesByNumber = new Map;
|
|
7226
|
-
nextTableNumber = FIRST_USER_TABLE_NUMBER;
|
|
7227
|
-
constructor() {
|
|
7228
|
-
this.registerSystemTables();
|
|
7229
|
-
}
|
|
7230
|
-
registerSystemTables() {
|
|
7231
|
-
for (const [name, number] of Object.entries(SYSTEM_TABLE_NUMBERS)) {
|
|
7232
|
-
const info = {
|
|
7233
|
-
tableNumber: number,
|
|
7234
|
-
name,
|
|
7235
|
-
componentPath: "",
|
|
7236
|
-
fullName: name,
|
|
7237
|
-
isSystem: true,
|
|
7238
|
-
createdAt: Date.now()
|
|
7239
|
-
};
|
|
7240
|
-
this.tablesByName.set(name, info);
|
|
7241
|
-
this.tablesByNumber.set(number, info);
|
|
7242
|
-
}
|
|
7243
|
-
}
|
|
7244
|
-
async getOrAllocateTableNumber(tableName, componentPath = "") {
|
|
7245
|
-
const fullName = getFullTableName(tableName, componentPath);
|
|
7246
|
-
const existing = this.tablesByName.get(fullName);
|
|
7247
|
-
if (existing) {
|
|
7248
|
-
return existing.tableNumber;
|
|
7249
|
-
}
|
|
7250
|
-
if (isSystemTable(tableName) && componentPath === "") {
|
|
7251
|
-
const systemNumber = SYSTEM_TABLE_NUMBERS[tableName];
|
|
7252
|
-
if (systemNumber !== undefined) {
|
|
7253
|
-
return systemNumber;
|
|
7254
|
-
}
|
|
7255
|
-
}
|
|
7256
|
-
const tableNumber = this.nextTableNumber++;
|
|
7257
|
-
const info = {
|
|
7258
|
-
tableNumber,
|
|
7259
|
-
name: tableName,
|
|
7260
|
-
componentPath,
|
|
7261
|
-
fullName,
|
|
7262
|
-
isSystem: false,
|
|
7263
|
-
createdAt: Date.now()
|
|
7264
|
-
};
|
|
7265
|
-
this.tablesByName.set(fullName, info);
|
|
7266
|
-
this.tablesByNumber.set(tableNumber, info);
|
|
7267
|
-
return tableNumber;
|
|
7268
|
-
}
|
|
7269
|
-
async getTableInfo(tableNumber) {
|
|
7270
|
-
return this.tablesByNumber.get(tableNumber) ?? null;
|
|
7271
|
-
}
|
|
7272
|
-
async getTableInfoByName(tableName, componentPath = "") {
|
|
7273
|
-
const fullName = getFullTableName(tableName, componentPath);
|
|
7274
|
-
return this.tablesByName.get(fullName) ?? null;
|
|
7275
|
-
}
|
|
7276
|
-
async listTables(componentPath) {
|
|
7277
|
-
const tables = Array.from(this.tablesByNumber.values());
|
|
7278
|
-
if (componentPath === undefined) {
|
|
7279
|
-
return tables;
|
|
7280
|
-
}
|
|
7281
|
-
return tables.filter((t) => t.componentPath === componentPath);
|
|
7282
|
-
}
|
|
7283
|
-
async hasAccess(tableNumber, componentPath) {
|
|
7284
|
-
const info = await this.getTableInfo(tableNumber);
|
|
7285
|
-
if (!info) {
|
|
7286
|
-
return false;
|
|
7287
|
-
}
|
|
7288
|
-
if (info.isSystem) {
|
|
7289
|
-
return true;
|
|
7290
|
-
}
|
|
7291
|
-
return info.componentPath === componentPath;
|
|
7292
|
-
}
|
|
7293
|
-
getSystemTableNumber(systemTableName) {
|
|
7294
|
-
return SYSTEM_TABLE_NUMBERS[systemTableName];
|
|
7295
|
-
}
|
|
7296
|
-
reset() {
|
|
7297
|
-
this.tablesByName.clear();
|
|
7298
|
-
this.tablesByNumber.clear();
|
|
7299
|
-
this.nextTableNumber = FIRST_USER_TABLE_NUMBER;
|
|
7300
|
-
this.registerSystemTables();
|
|
7301
|
-
}
|
|
7302
|
-
getState() {
|
|
7303
|
-
return {
|
|
7304
|
-
tableCount: this.tablesByNumber.size,
|
|
7305
|
-
nextNumber: this.nextTableNumber
|
|
7306
|
-
};
|
|
7307
|
-
}
|
|
7308
|
-
}
|
|
7309
|
-
var globalRegistry = null;
|
|
7310
|
-
function getGlobalTableRegistry() {
|
|
7311
|
-
if (!globalRegistry) {
|
|
7312
|
-
globalRegistry = new MemoryTableRegistry;
|
|
7313
|
-
}
|
|
7314
|
-
return globalRegistry;
|
|
7315
|
-
}
|
|
7316
|
-
|
|
7317
|
-
// ../core/dist/kernel/kernel-context.js
|
|
7318
7630
|
class KernelContext {
|
|
7319
7631
|
authContext;
|
|
7320
7632
|
componentPath;
|
|
@@ -7331,11 +7643,14 @@ class KernelContext {
|
|
|
7331
7643
|
this.authContext = options.authContext;
|
|
7332
7644
|
this.componentPath = options.componentPath ?? "";
|
|
7333
7645
|
this.mutationTransaction = options.mutationTransaction;
|
|
7334
|
-
|
|
7335
|
-
|
|
7646
|
+
if (!options.tableRegistry) {
|
|
7647
|
+
throw new Error("KernelContext requires an explicit tableRegistry");
|
|
7648
|
+
}
|
|
7649
|
+
this.tableRegistry = options.tableRegistry;
|
|
7650
|
+
this.useConvexIdFormat = options.useConvexIdFormat ?? true;
|
|
7336
7651
|
}
|
|
7337
7652
|
async getTableNumber(tableName) {
|
|
7338
|
-
return this.tableRegistry.getOrAllocateTableNumber(tableName, this.componentPath);
|
|
7653
|
+
return this.tableRegistry.getOrAllocateTableNumber(tableName, isSystemTable(tableName) ? "" : this.componentPath);
|
|
7339
7654
|
}
|
|
7340
7655
|
nextSubrequestId(prefix, udfPath) {
|
|
7341
7656
|
return `${prefix}:${udfPath}:${Date.now()}:${Math.random()}:${this.subrequestCounter++}`;
|
|
@@ -7380,7 +7695,7 @@ class KernelContext {
|
|
|
7380
7695
|
this.writeLog.addDocument(docId);
|
|
7381
7696
|
}
|
|
7382
7697
|
recordLocalWrite(developerId, tableName, value, docId) {
|
|
7383
|
-
this.localWrites.set(developerId, { table: tableName, value });
|
|
7698
|
+
this.localWrites.set(developerId, { table: tableName, value, docId });
|
|
7384
7699
|
if (docId) {
|
|
7385
7700
|
this.recordDocumentWrite(docId);
|
|
7386
7701
|
return;
|
|
@@ -7422,7 +7737,13 @@ class KernelContext {
|
|
|
7422
7737
|
}
|
|
7423
7738
|
}
|
|
7424
7739
|
|
|
7740
|
+
// ../core/dist/kernel/udf-kernel.js
|
|
7741
|
+
init_id_codec();
|
|
7742
|
+
|
|
7425
7743
|
// ../core/dist/kernel/blob-store-gateway.js
|
|
7744
|
+
init_id_codec();
|
|
7745
|
+
init_utils();
|
|
7746
|
+
|
|
7426
7747
|
class BlobStoreGateway {
|
|
7427
7748
|
context;
|
|
7428
7749
|
docStore;
|
|
@@ -7471,7 +7792,7 @@ class BlobStoreGateway {
|
|
|
7471
7792
|
if (!this.storage) {
|
|
7472
7793
|
return null;
|
|
7473
7794
|
}
|
|
7474
|
-
const docId = parseStorageId(storageId);
|
|
7795
|
+
const docId = await parseDeveloperIdWithTableRegistry(storageId, this.context.tableRegistry) ?? parseStorageId(storageId);
|
|
7475
7796
|
if (!docId) {
|
|
7476
7797
|
console.debug(`[BlobStoreGateway] Failed to parse storage ID: ${storageId}`);
|
|
7477
7798
|
return null;
|
|
@@ -7492,7 +7813,7 @@ class BlobStoreGateway {
|
|
|
7492
7813
|
if (!this.storage) {
|
|
7493
7814
|
return null;
|
|
7494
7815
|
}
|
|
7495
|
-
const docId = parseStorageId(storageId);
|
|
7816
|
+
const docId = await parseDeveloperIdWithTableRegistry(storageId, this.context.tableRegistry) ?? parseStorageId(storageId);
|
|
7496
7817
|
if (!docId) {
|
|
7497
7818
|
return null;
|
|
7498
7819
|
}
|
|
@@ -7505,7 +7826,7 @@ class BlobStoreGateway {
|
|
|
7505
7826
|
}
|
|
7506
7827
|
async delete(storageId) {
|
|
7507
7828
|
const storage2 = this.requireStorage();
|
|
7508
|
-
const docId = parseStorageId(storageId);
|
|
7829
|
+
const docId = await parseDeveloperIdWithTableRegistry(storageId, this.context.tableRegistry) ?? parseStorageId(storageId);
|
|
7509
7830
|
if (!docId) {
|
|
7510
7831
|
return;
|
|
7511
7832
|
}
|
|
@@ -7530,13 +7851,17 @@ class BlobStoreGateway {
|
|
|
7530
7851
|
|
|
7531
7852
|
// ../core/dist/kernel/scheduler-gateway.js
|
|
7532
7853
|
init_values();
|
|
7854
|
+
init_id_codec();
|
|
7855
|
+
init_utils();
|
|
7856
|
+
|
|
7533
7857
|
// ../core/dist/kernel/syscalls/utils.js
|
|
7534
7858
|
init_values();
|
|
7859
|
+
init_utils();
|
|
7535
7860
|
async function resolveTableName(docId, tableRegistry) {
|
|
7536
7861
|
if (docId.tableNumber !== undefined) {
|
|
7537
7862
|
const info = await tableRegistry.getTableInfo(docId.tableNumber);
|
|
7538
7863
|
if (info) {
|
|
7539
|
-
return info.
|
|
7864
|
+
return info.fullName;
|
|
7540
7865
|
}
|
|
7541
7866
|
if (!isTablePlaceholder(docId.table)) {
|
|
7542
7867
|
return hexToString(docId.table);
|
|
@@ -7717,7 +8042,7 @@ class SchedulerGateway {
|
|
|
7717
8042
|
return developerId;
|
|
7718
8043
|
}
|
|
7719
8044
|
async cancel(id, state) {
|
|
7720
|
-
const docId =
|
|
8045
|
+
const docId = await parseDeveloperIdWithTableRegistry(id, this.context.tableRegistry);
|
|
7721
8046
|
if (!docId) {
|
|
7722
8047
|
throw new Error(`Scheduled job with id ${id} not found.`);
|
|
7723
8048
|
}
|
|
@@ -7842,6 +8167,8 @@ class ActionSyscalls {
|
|
|
7842
8167
|
|
|
7843
8168
|
// ../core/dist/kernel/syscalls/database-syscalls.js
|
|
7844
8169
|
init_values();
|
|
8170
|
+
init_id_codec();
|
|
8171
|
+
init_utils();
|
|
7845
8172
|
init_interface();
|
|
7846
8173
|
|
|
7847
8174
|
class DatabaseSyscalls {
|
|
@@ -7878,7 +8205,8 @@ class DatabaseSyscalls {
|
|
|
7878
8205
|
if (docId.tableNumber !== undefined) {
|
|
7879
8206
|
return { id: idString };
|
|
7880
8207
|
}
|
|
7881
|
-
|
|
8208
|
+
const expectedFullTableName = getFullTableName(tableName, isSystemTable(tableName) ? "" : this.context.componentPath);
|
|
8209
|
+
if (docId.table === stringToHex(expectedFullTableName)) {
|
|
7882
8210
|
return { id: idString };
|
|
7883
8211
|
}
|
|
7884
8212
|
return { id: null };
|
|
@@ -7937,29 +8265,28 @@ class DatabaseSyscalls {
|
|
|
7937
8265
|
return { _id: developerId };
|
|
7938
8266
|
}
|
|
7939
8267
|
async handleGet(args) {
|
|
7940
|
-
const { id } = args;
|
|
8268
|
+
const { id, table } = args;
|
|
7941
8269
|
if (typeof id !== "string") {
|
|
7942
8270
|
throw new Error("`id` argument for `get` must be a string.");
|
|
7943
8271
|
}
|
|
7944
|
-
const
|
|
7945
|
-
if (!
|
|
8272
|
+
const resolved = await this.resolveDocumentTarget(id, table, "get");
|
|
8273
|
+
if (!resolved) {
|
|
7946
8274
|
return null;
|
|
7947
8275
|
}
|
|
7948
|
-
this.context.recordDocumentRead(
|
|
7949
|
-
const doc = await this.queryRuntime.getVisibleDocumentById(id,
|
|
8276
|
+
this.context.recordDocumentRead(resolved.docId);
|
|
8277
|
+
const doc = await this.queryRuntime.getVisibleDocumentById(id, resolved.docId);
|
|
7950
8278
|
return doc ?? null;
|
|
7951
8279
|
}
|
|
7952
8280
|
async handleRemove(args) {
|
|
7953
|
-
const { id } = args;
|
|
8281
|
+
const { id, table } = args;
|
|
7954
8282
|
if (typeof id !== "string") {
|
|
7955
8283
|
throw new Error("`id` argument for `remove` must be a string.");
|
|
7956
8284
|
}
|
|
7957
|
-
const
|
|
7958
|
-
if (!
|
|
8285
|
+
const resolved = await this.resolveDocumentTarget(id, table, "remove", true);
|
|
8286
|
+
if (!resolved) {
|
|
7959
8287
|
throw new Error(`Document with id ${id} not found.`);
|
|
7960
8288
|
}
|
|
7961
|
-
const fullTableName
|
|
7962
|
-
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8289
|
+
const { docId, fullTableName, bareTableName } = resolved;
|
|
7963
8290
|
const latest = await this.docStore.fetchLatestDocument(docId, this.context.snapshotTimestamp);
|
|
7964
8291
|
if (!latest) {
|
|
7965
8292
|
throw new Error(`Document with id ${id} not found.`);
|
|
@@ -7975,16 +8302,15 @@ class DatabaseSyscalls {
|
|
|
7975
8302
|
return {};
|
|
7976
8303
|
}
|
|
7977
8304
|
async handleShallowMerge(args) {
|
|
7978
|
-
const { id, value } = args;
|
|
8305
|
+
const { id, table, value } = args;
|
|
7979
8306
|
if (typeof id !== "string") {
|
|
7980
8307
|
throw new Error("`id` argument for `shallowMerge` must be a string.");
|
|
7981
8308
|
}
|
|
7982
|
-
const
|
|
7983
|
-
if (!
|
|
8309
|
+
const resolved = await this.resolveDocumentTarget(id, table, "patch", true);
|
|
8310
|
+
if (!resolved) {
|
|
7984
8311
|
throw new Error(`Document with id ${id} not found.`);
|
|
7985
8312
|
}
|
|
7986
|
-
const fullTableName
|
|
7987
|
-
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8313
|
+
const { docId, fullTableName, bareTableName } = resolved;
|
|
7988
8314
|
if (value && typeof value === "object") {
|
|
7989
8315
|
if ("_id" in value) {
|
|
7990
8316
|
throw new Error("System field `_id` cannot be modified in a patch operation.");
|
|
@@ -8035,16 +8361,15 @@ class DatabaseSyscalls {
|
|
|
8035
8361
|
return {};
|
|
8036
8362
|
}
|
|
8037
8363
|
async handleReplace(args) {
|
|
8038
|
-
const { id, value } = args;
|
|
8364
|
+
const { id, table, value } = args;
|
|
8039
8365
|
if (typeof id !== "string") {
|
|
8040
8366
|
throw new Error("`id` argument for `replace` must be a string.");
|
|
8041
8367
|
}
|
|
8042
|
-
const
|
|
8043
|
-
if (!
|
|
8368
|
+
const resolved = await this.resolveDocumentTarget(id, table, "replace", true);
|
|
8369
|
+
if (!resolved) {
|
|
8044
8370
|
throw new Error(`Document with id ${id} not found.`);
|
|
8045
8371
|
}
|
|
8046
|
-
const fullTableName
|
|
8047
|
-
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8372
|
+
const { docId, fullTableName, bareTableName } = resolved;
|
|
8048
8373
|
const replaceValue = jsonToConvex(value);
|
|
8049
8374
|
if (typeof replaceValue !== "object" || replaceValue === null || Array.isArray(replaceValue)) {
|
|
8050
8375
|
throw new Error("The replacement value for `replace` must be an object.");
|
|
@@ -8067,6 +8392,27 @@ class DatabaseSyscalls {
|
|
|
8067
8392
|
this.context.recordLocalWrite(id, fullTableName, newValue, canonicalDocId);
|
|
8068
8393
|
return {};
|
|
8069
8394
|
}
|
|
8395
|
+
async resolveDocumentTarget(id, table, operation, throwOnMismatch = false) {
|
|
8396
|
+
if (table !== undefined && typeof table !== "string") {
|
|
8397
|
+
throw new Error(`\`table\` argument for \`${operation}\` must be a string.`);
|
|
8398
|
+
}
|
|
8399
|
+
const docId = await parseDeveloperIdWithTableRegistry(id, this.context.tableRegistry);
|
|
8400
|
+
if (!docId) {
|
|
8401
|
+
return null;
|
|
8402
|
+
}
|
|
8403
|
+
const fullTableName = await resolveTableName(docId, this.context.tableRegistry);
|
|
8404
|
+
if (typeof table === "string") {
|
|
8405
|
+
const expectedFullTableName = getFullTableName(table, isSystemTable(table) ? "" : this.context.componentPath);
|
|
8406
|
+
if (fullTableName !== expectedFullTableName) {
|
|
8407
|
+
if (throwOnMismatch) {
|
|
8408
|
+
throw new Error(`Document with id ${id} does not belong to table ${table}.`);
|
|
8409
|
+
}
|
|
8410
|
+
return null;
|
|
8411
|
+
}
|
|
8412
|
+
}
|
|
8413
|
+
const { tableName: bareTableName } = parseFullTableName(fullTableName);
|
|
8414
|
+
return { docId, fullTableName, bareTableName };
|
|
8415
|
+
}
|
|
8070
8416
|
}
|
|
8071
8417
|
|
|
8072
8418
|
// ../core/dist/kernel/syscalls/identity-syscalls.js
|
|
@@ -8382,11 +8728,203 @@ class KernelSyscalls {
|
|
|
8382
8728
|
return this.jsRouter.dispatch(op, args);
|
|
8383
8729
|
}
|
|
8384
8730
|
}
|
|
8731
|
+
|
|
8732
|
+
// ../core/dist/tables/docstore-table-registry.js
|
|
8733
|
+
init_system_tables();
|
|
8734
|
+
init_utils();
|
|
8735
|
+
init_interface();
|
|
8736
|
+
|
|
8737
|
+
class DocStoreTableRegistry {
|
|
8738
|
+
docstore;
|
|
8739
|
+
tablesByNumber = new Map;
|
|
8740
|
+
tablesByName = new Map;
|
|
8741
|
+
loadPromise = null;
|
|
8742
|
+
cachedRegistryVersion = 0;
|
|
8743
|
+
constructor(docstore) {
|
|
8744
|
+
this.docstore = docstore;
|
|
8745
|
+
}
|
|
8746
|
+
async getOrAllocateTableNumber(tableName, componentPath = "") {
|
|
8747
|
+
await this.ensureLoaded();
|
|
8748
|
+
await this.ensureFresh();
|
|
8749
|
+
const normalizedComponent = isSystemTable(tableName) ? "" : componentPath;
|
|
8750
|
+
const fullName = getFullTableName(tableName, normalizedComponent);
|
|
8751
|
+
let existing = this.tablesByName.get(fullName);
|
|
8752
|
+
if (existing) {
|
|
8753
|
+
return existing.tableNumber;
|
|
8754
|
+
}
|
|
8755
|
+
await this.reloadTables();
|
|
8756
|
+
existing = this.tablesByName.get(fullName);
|
|
8757
|
+
if (existing) {
|
|
8758
|
+
return existing.tableNumber;
|
|
8759
|
+
}
|
|
8760
|
+
const oracle = this.docstore.timestampOracle;
|
|
8761
|
+
for (;; ) {
|
|
8762
|
+
const metadata = await readSystemMetadata(this.docstore) ?? createSystemMetadata({
|
|
8763
|
+
nextUserTableNumber: Math.max(FIRST_USER_TABLE_NUMBER, nextUserTableNumber(this.tablesByNumber.values()))
|
|
8764
|
+
});
|
|
8765
|
+
const candidate = Math.max(metadata.nextUserTableNumber, nextUserTableNumber(this.tablesByNumber.values()));
|
|
8766
|
+
const reserved = await this.docstore.writeGlobalIfAbsent(createTableNumberReservationKey(candidate), {
|
|
8767
|
+
fullName,
|
|
8768
|
+
reservedAt: Date.now()
|
|
8769
|
+
});
|
|
8770
|
+
if (!reserved) {
|
|
8771
|
+
await this.reloadTables();
|
|
8772
|
+
const raced = this.tablesByName.get(fullName);
|
|
8773
|
+
if (raced) {
|
|
8774
|
+
return raced.tableNumber;
|
|
8775
|
+
}
|
|
8776
|
+
continue;
|
|
8777
|
+
}
|
|
8778
|
+
const createdAt = Date.now();
|
|
8779
|
+
const info = createTableInfo(tableName, candidate, normalizedComponent, { createdAt, visibility: "public" });
|
|
8780
|
+
const timestamp = oracle?.allocateTimestamp?.() ?? BigInt(createdAt);
|
|
8781
|
+
const entry = createTableMetadataEntryForUserTable(info, timestamp);
|
|
8782
|
+
try {
|
|
8783
|
+
await this.docstore.write([entry], new Set, "Error");
|
|
8784
|
+
} catch {
|
|
8785
|
+
await this.reloadTables();
|
|
8786
|
+
const raced = this.tablesByName.get(fullName);
|
|
8787
|
+
if (raced) {
|
|
8788
|
+
return raced.tableNumber;
|
|
8789
|
+
}
|
|
8790
|
+
throw new Error(`Failed to allocate table number for ${fullName}`);
|
|
8791
|
+
}
|
|
8792
|
+
const registryVersion = Number(timestamp > BigInt(Number.MAX_SAFE_INTEGER) ? BigInt(Date.now()) : timestamp);
|
|
8793
|
+
await this.docstore.writeGlobal(SYSTEM_METADATA_GLOBAL_KEY, createSystemMetadata({
|
|
8794
|
+
nextUserTableNumber: candidate + 1,
|
|
8795
|
+
registryVersion,
|
|
8796
|
+
bootstrappedAt: metadata.bootstrappedAt,
|
|
8797
|
+
updatedAt: registryVersion
|
|
8798
|
+
}));
|
|
8799
|
+
this.cachedRegistryVersion = registryVersion;
|
|
8800
|
+
this.tablesByName.set(fullName, info);
|
|
8801
|
+
this.tablesByNumber.set(candidate, info);
|
|
8802
|
+
return candidate;
|
|
8803
|
+
}
|
|
8804
|
+
}
|
|
8805
|
+
async getTableInfo(tableNumber) {
|
|
8806
|
+
await this.ensureLoaded();
|
|
8807
|
+
await this.ensureFresh();
|
|
8808
|
+
const existing = this.tablesByNumber.get(tableNumber);
|
|
8809
|
+
if (existing) {
|
|
8810
|
+
return existing;
|
|
8811
|
+
}
|
|
8812
|
+
await this.reloadTables();
|
|
8813
|
+
return this.tablesByNumber.get(tableNumber) ?? null;
|
|
8814
|
+
}
|
|
8815
|
+
async getTableInfoByName(tableName, componentPath = "") {
|
|
8816
|
+
await this.ensureLoaded();
|
|
8817
|
+
await this.ensureFresh();
|
|
8818
|
+
const fullName = getFullTableName(tableName, isSystemTable(tableName) ? "" : componentPath);
|
|
8819
|
+
const existing = this.tablesByName.get(fullName);
|
|
8820
|
+
if (existing) {
|
|
8821
|
+
return existing;
|
|
8822
|
+
}
|
|
8823
|
+
await this.reloadTables();
|
|
8824
|
+
return this.tablesByName.get(fullName) ?? null;
|
|
8825
|
+
}
|
|
8826
|
+
async listTables(componentPath) {
|
|
8827
|
+
await this.ensureLoaded();
|
|
8828
|
+
await this.ensureFresh();
|
|
8829
|
+
const values = Array.from(this.tablesByNumber.values());
|
|
8830
|
+
if (componentPath === undefined) {
|
|
8831
|
+
return values.sort((a, b) => a.tableNumber - b.tableNumber);
|
|
8832
|
+
}
|
|
8833
|
+
return values.filter((table) => table.componentPath === componentPath).sort((a, b) => a.tableNumber - b.tableNumber);
|
|
8834
|
+
}
|
|
8835
|
+
async hasAccess(tableNumber, componentPath) {
|
|
8836
|
+
const info = await this.getTableInfo(tableNumber);
|
|
8837
|
+
if (!info) {
|
|
8838
|
+
return false;
|
|
8839
|
+
}
|
|
8840
|
+
if (info.isSystem) {
|
|
8841
|
+
return true;
|
|
8842
|
+
}
|
|
8843
|
+
return info.componentPath === componentPath;
|
|
8844
|
+
}
|
|
8845
|
+
getSystemTableNumber(systemTableName) {
|
|
8846
|
+
return SYSTEM_TABLE_NUMBERS[systemTableName];
|
|
8847
|
+
}
|
|
8848
|
+
async ensureLoaded() {
|
|
8849
|
+
if (!this.loadPromise) {
|
|
8850
|
+
this.loadPromise = this.loadTables();
|
|
8851
|
+
}
|
|
8852
|
+
await this.loadPromise;
|
|
8853
|
+
}
|
|
8854
|
+
async ensureFresh() {
|
|
8855
|
+
const metadata = await readSystemMetadata(this.docstore);
|
|
8856
|
+
if (!metadata) {
|
|
8857
|
+
if (this.cachedRegistryVersion !== 0 || this.tablesByName.size > 0 || this.tablesByNumber.size > 0) {
|
|
8858
|
+
await this.reloadTables();
|
|
8859
|
+
}
|
|
8860
|
+
return;
|
|
8861
|
+
}
|
|
8862
|
+
if (metadata.registryVersion > this.cachedRegistryVersion) {
|
|
8863
|
+
await this.reloadTables();
|
|
8864
|
+
}
|
|
8865
|
+
}
|
|
8866
|
+
async reloadTables() {
|
|
8867
|
+
this.loadPromise = this.loadTables();
|
|
8868
|
+
await this.loadPromise;
|
|
8869
|
+
}
|
|
8870
|
+
async loadTables() {
|
|
8871
|
+
await ensureSystemTablesBootstrapped(this.docstore);
|
|
8872
|
+
const docs = await this.docstore.scan(stringToHex("_tables"));
|
|
8873
|
+
this.tablesByName.clear();
|
|
8874
|
+
this.tablesByNumber.clear();
|
|
8875
|
+
for (const doc of docs) {
|
|
8876
|
+
const info = tableInfoFromStoredDocument(doc.value.value);
|
|
8877
|
+
if (!info) {
|
|
8878
|
+
continue;
|
|
8879
|
+
}
|
|
8880
|
+
this.tablesByName.set(info.fullName, info);
|
|
8881
|
+
this.tablesByNumber.set(info.tableNumber, info);
|
|
8882
|
+
}
|
|
8883
|
+
if (this.tablesByNumber.size === 0) {
|
|
8884
|
+
for (const [name, tableNumber] of Object.entries(SYSTEM_TABLE_NUMBERS)) {
|
|
8885
|
+
const info = createTableInfo(name, tableNumber, "", { isSystem: true });
|
|
8886
|
+
this.tablesByName.set(info.fullName, info);
|
|
8887
|
+
this.tablesByNumber.set(info.tableNumber, info);
|
|
8888
|
+
}
|
|
8889
|
+
}
|
|
8890
|
+
const metadata = await readSystemMetadata(this.docstore);
|
|
8891
|
+
if (!metadata) {
|
|
8892
|
+
const now = Date.now();
|
|
8893
|
+
this.cachedRegistryVersion = now;
|
|
8894
|
+
await this.docstore.writeGlobal(SYSTEM_METADATA_GLOBAL_KEY, createSystemMetadata({
|
|
8895
|
+
nextUserTableNumber: Math.max(FIRST_USER_TABLE_NUMBER, nextUserTableNumber(this.tablesByNumber.values())),
|
|
8896
|
+
registryVersion: now,
|
|
8897
|
+
bootstrappedAt: now,
|
|
8898
|
+
updatedAt: now
|
|
8899
|
+
}));
|
|
8900
|
+
} else {
|
|
8901
|
+
this.cachedRegistryVersion = metadata.registryVersion;
|
|
8902
|
+
}
|
|
8903
|
+
}
|
|
8904
|
+
}
|
|
8905
|
+
|
|
8906
|
+
// ../core/dist/tables/transactional-table-registry.js
|
|
8907
|
+
init_system_tables();
|
|
8908
|
+
init_utils();
|
|
8909
|
+
init_interface();
|
|
8385
8910
|
// ../core/dist/kernel/contexts.js
|
|
8386
8911
|
init_context_storage();
|
|
8387
|
-
var
|
|
8388
|
-
var
|
|
8389
|
-
var
|
|
8912
|
+
var SNAPSHOT_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/snapshot-context");
|
|
8913
|
+
var TRANSACTION_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/transaction-context");
|
|
8914
|
+
var ID_GENERATOR_CONTEXT_SYMBOL = Symbol.for("@concavejs/core/id-generator-context");
|
|
8915
|
+
var globalContexts = globalThis;
|
|
8916
|
+
var snapshotContext = globalContexts[SNAPSHOT_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
8917
|
+
var transactionContext = globalContexts[TRANSACTION_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
8918
|
+
var idGeneratorContext = globalContexts[ID_GENERATOR_CONTEXT_SYMBOL] ?? new ContextStorage;
|
|
8919
|
+
if (!globalContexts[SNAPSHOT_CONTEXT_SYMBOL]) {
|
|
8920
|
+
globalContexts[SNAPSHOT_CONTEXT_SYMBOL] = snapshotContext;
|
|
8921
|
+
}
|
|
8922
|
+
if (!globalContexts[TRANSACTION_CONTEXT_SYMBOL]) {
|
|
8923
|
+
globalContexts[TRANSACTION_CONTEXT_SYMBOL] = transactionContext;
|
|
8924
|
+
}
|
|
8925
|
+
if (!globalContexts[ID_GENERATOR_CONTEXT_SYMBOL]) {
|
|
8926
|
+
globalContexts[ID_GENERATOR_CONTEXT_SYMBOL] = idGeneratorContext;
|
|
8927
|
+
}
|
|
8390
8928
|
// ../core/dist/queryengine/convex-ops.js
|
|
8391
8929
|
var debug = () => {};
|
|
8392
8930
|
class CfConvex {
|
|
@@ -8533,6 +9071,10 @@ class TimestampOracle {
|
|
|
8533
9071
|
this.logicalClock = ts;
|
|
8534
9072
|
}
|
|
8535
9073
|
}
|
|
9074
|
+
|
|
9075
|
+
// ../core/dist/utils/index.js
|
|
9076
|
+
init_utils();
|
|
9077
|
+
|
|
8536
9078
|
// src/memory-docstore.ts
|
|
8537
9079
|
class MemoryDocStore {
|
|
8538
9080
|
timestampOracle = new TimestampOracle;
|
|
@@ -8634,6 +9176,13 @@ class MemoryDocStore {
|
|
|
8634
9176
|
async writeGlobal(key, value) {
|
|
8635
9177
|
this.globals.set(key, cloneValue(value));
|
|
8636
9178
|
}
|
|
9179
|
+
async writeGlobalIfAbsent(key, value) {
|
|
9180
|
+
if (this.globals.has(key)) {
|
|
9181
|
+
return false;
|
|
9182
|
+
}
|
|
9183
|
+
this.globals.set(key, cloneValue(value));
|
|
9184
|
+
return true;
|
|
9185
|
+
}
|
|
8637
9186
|
async previous_revisions(queries) {
|
|
8638
9187
|
const results = new Map;
|
|
8639
9188
|
for (const query of queries) {
|