@qaecy/cue-sdk 0.0.30 → 0.0.31
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/{cue-DWCLcFvj.js → cue-VOCN5IEZ.js} +664 -469
- package/index.d.ts +3 -1
- package/index.js +17 -16
- package/lib/api.d.ts +3 -0
- package/lib/contexts.d.ts +17 -0
- package/lib/entities.d.ts +7 -0
- package/lib/models.d.ts +43 -0
- package/lib/schema.d.ts +30 -16
- package/lib/storage.d.ts +26 -10
- package/node.js +40 -38
- package/package.json +1 -1
- package/variables.d.ts +4 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { getApps as
|
|
2
|
-
import { ref as
|
|
3
|
-
import { Writer as
|
|
4
|
-
import { getFirestore as
|
|
5
|
-
import { getAuth as
|
|
6
|
-
import { v5 as
|
|
1
|
+
import { getApps as xe, initializeApp as Ce } from "firebase/app";
|
|
2
|
+
import { ref as k, getDownloadURL as X, getMetadata as $, getBlob as ne, updateMetadata as Ie, uploadBytesResumable as ft, uploadBytes as st, StringFormat as Se, uploadString as Te, listAll as U, getStorage as C, connectStorageEmulator as K } from "firebase/storage";
|
|
3
|
+
import { Writer as Re, DataFactory as j } from "n3";
|
|
4
|
+
import { getFirestore as Ae, connectFirestoreEmulator as Pe, collection as yt, getDocs as Oe, query as De, where as Le, limit as qe, doc as bt, getDoc as je, setDoc as ze, serverTimestamp as $e, increment as Ue } from "firebase/firestore";
|
|
5
|
+
import { getAuth as Me, connectAuthEmulator as Ne, onIdTokenChanged as Fe, getIdTokenResult as at, signInWithEmailAndPassword as Be, GoogleAuthProvider as it, OAuthProvider as nt, signInWithPopup as Ge, signInWithRedirect as He, getRedirectResult as We, signInWithCustomToken as vt, signOut as Ve, onAuthStateChanged as Xe, fetchSignInMethodsForEmail as Ke, linkWithPopup as Qe, unlink as Ye, reauthenticateWithCredential as _t, EmailAuthProvider as Q, updatePassword as Ze, linkWithCredential as Je, verifyBeforeUpdateEmail as to, sendEmailVerification as eo } from "firebase/auth";
|
|
6
|
+
import { v5 as oo } from "uuid";
|
|
7
7
|
import "spark-md5";
|
|
8
|
-
import { getFunctions as
|
|
8
|
+
import { getFunctions as pe, connectFunctionsEmulator as ce, httpsCallable as F } from "firebase/functions";
|
|
9
9
|
class ht {
|
|
10
10
|
queryEndpoint;
|
|
11
11
|
updateEndpoint;
|
|
@@ -86,7 +86,7 @@ class Y extends Error {
|
|
|
86
86
|
super(`QLever is locked (rebuild in progress): ${t}`), this.name = "QLeverLockedError";
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
class
|
|
89
|
+
class A {
|
|
90
90
|
queryEndpoint;
|
|
91
91
|
updateEndpoint;
|
|
92
92
|
dataEndpoint;
|
|
@@ -113,7 +113,7 @@ class R {
|
|
|
113
113
|
* 423 means qlever accessor has an ongoing rebuild; we should wait and retry.
|
|
114
114
|
*/
|
|
115
115
|
static async _retryOnLocked(t) {
|
|
116
|
-
const e =
|
|
116
|
+
const e = A.LOCKED_MAX_RETRIES, o = A.LOCKED_BASE_DELAY_MS;
|
|
117
117
|
let r;
|
|
118
118
|
for (let s = 0; s <= e; s++)
|
|
119
119
|
try {
|
|
@@ -131,7 +131,7 @@ class R {
|
|
|
131
131
|
constructor(t) {
|
|
132
132
|
this.queryEndpoint = t.queryEndpoint, this.updateEndpoint = t.updateEndpoint, this.dataEndpoint = this.updateEndpoint.replace(/\/update$/, "/data"), this.baseHeaders = Object.fromEntries(
|
|
133
133
|
Object.entries(t.originalHeaders || {}).filter(
|
|
134
|
-
([e]) =>
|
|
134
|
+
([e]) => A.RELEVANT_HEADER_KEYS.includes(e)
|
|
135
135
|
)
|
|
136
136
|
), this.baseHeaders["x-user-roles"] = "admin";
|
|
137
137
|
}
|
|
@@ -173,7 +173,7 @@ class R {
|
|
|
173
173
|
})).text();
|
|
174
174
|
}
|
|
175
175
|
async update(t) {
|
|
176
|
-
return
|
|
176
|
+
return A._retryOnLocked(async () => {
|
|
177
177
|
const e = await fetch(this.updateEndpoint, {
|
|
178
178
|
headers: {
|
|
179
179
|
...this.baseHeaders,
|
|
@@ -204,8 +204,8 @@ class R {
|
|
|
204
204
|
await this._postToDataEndpoint(t, `${this.dataEndpoint}/delete`);
|
|
205
205
|
}
|
|
206
206
|
async _postToDataEndpoint(t, e) {
|
|
207
|
-
const o = await this._quadsToNQuads(t), r = await
|
|
208
|
-
await
|
|
207
|
+
const o = await this._quadsToNQuads(t), r = await ro(Buffer.from(o, "utf-8"));
|
|
208
|
+
await A._retryOnLocked(async () => {
|
|
209
209
|
const s = await fetch(e, {
|
|
210
210
|
method: "POST",
|
|
211
211
|
headers: {
|
|
@@ -223,12 +223,12 @@ class R {
|
|
|
223
223
|
}
|
|
224
224
|
_quadsToNQuads(t) {
|
|
225
225
|
return new Promise((e, o) => {
|
|
226
|
-
const r = new
|
|
226
|
+
const r = new Re({ format: "application/n-quads" });
|
|
227
227
|
r.addQuads(t), r.end((s, a) => s ? o(s) : e(a));
|
|
228
228
|
});
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
|
-
async function
|
|
231
|
+
async function ro(i) {
|
|
232
232
|
const t = new CompressionStream("gzip"), e = t.writable.getWriter();
|
|
233
233
|
e.write(new Uint8Array(i)), e.close();
|
|
234
234
|
const o = [], r = t.readable.getReader();
|
|
@@ -243,11 +243,11 @@ async function Ze(i) {
|
|
|
243
243
|
a.set(p, n), n += p.byteLength;
|
|
244
244
|
return a.buffer;
|
|
245
245
|
}
|
|
246
|
-
class
|
|
246
|
+
class so {
|
|
247
247
|
constructor(t) {
|
|
248
248
|
switch (this.options = t, this.options.graphType) {
|
|
249
249
|
case "qlever":
|
|
250
|
-
this._db = new
|
|
250
|
+
this._db = new A(this.options);
|
|
251
251
|
break;
|
|
252
252
|
case "fuseki":
|
|
253
253
|
this._db = new ht(this.options);
|
|
@@ -298,7 +298,7 @@ class Je {
|
|
|
298
298
|
return this.options.graphType === "qlever" ? this._db.deleteData(t) : Promise.reject(new Error("deleteData not supported for Fuseki — use update() with SPARQL DELETE DATA"));
|
|
299
299
|
}
|
|
300
300
|
}
|
|
301
|
-
class
|
|
301
|
+
class Et {
|
|
302
302
|
constructor(t) {
|
|
303
303
|
this.options = t;
|
|
304
304
|
}
|
|
@@ -320,14 +320,16 @@ class kt {
|
|
|
320
320
|
return this.options.storagePublic;
|
|
321
321
|
case "persistence":
|
|
322
322
|
return this.options.storagePersistence;
|
|
323
|
+
case "sessions":
|
|
324
|
+
return this.options.storageSessions;
|
|
323
325
|
}
|
|
324
326
|
}
|
|
325
327
|
// ─── Downloads ────────────────────────────────────────────────────────────
|
|
326
328
|
/** Get an authenticated download URL. Returns undefined if the file does not exist. */
|
|
327
329
|
async getDownloadURL(t, e) {
|
|
328
|
-
const o =
|
|
330
|
+
const o = k(this._bucket(t), e);
|
|
329
331
|
try {
|
|
330
|
-
return await
|
|
332
|
+
return await X(o);
|
|
331
333
|
} catch (r) {
|
|
332
334
|
if (r?.code === "storage/object-not-found") return;
|
|
333
335
|
throw r;
|
|
@@ -340,10 +342,10 @@ class kt {
|
|
|
340
342
|
async getCacheBustedUrl(t, e) {
|
|
341
343
|
const o = `${t}:${e}`;
|
|
342
344
|
if (this._knownMissing.has(o)) return;
|
|
343
|
-
const r =
|
|
345
|
+
const r = k(this._bucket(t), e);
|
|
344
346
|
try {
|
|
345
|
-
const s = await
|
|
346
|
-
return `${await
|
|
347
|
+
const s = await $(r);
|
|
348
|
+
return `${await X(r)}&t=${encodeURIComponent(s.updated)}`;
|
|
347
349
|
} catch (s) {
|
|
348
350
|
if (s?.code === "storage/object-not-found" || s?.status === 404) {
|
|
349
351
|
this._knownMissing.add(o), console.debug(`[CueBlobStorage] ${e} not found (404 OK — optional cache file)`);
|
|
@@ -354,9 +356,9 @@ class kt {
|
|
|
354
356
|
}
|
|
355
357
|
/** Download a file as a Blob. Returns undefined if the file does not exist. */
|
|
356
358
|
async getFile(t, e) {
|
|
357
|
-
const o =
|
|
359
|
+
const o = k(this._bucket(t), e);
|
|
358
360
|
try {
|
|
359
|
-
return await
|
|
361
|
+
return await ne(o);
|
|
360
362
|
} catch (r) {
|
|
361
363
|
if (r?.code === "storage/object-not-found") return;
|
|
362
364
|
throw r;
|
|
@@ -371,7 +373,7 @@ class kt {
|
|
|
371
373
|
* Uses a cache-busted URL to ensure the latest version is fetched.
|
|
372
374
|
*/
|
|
373
375
|
async downloadPublic(t) {
|
|
374
|
-
const e =
|
|
376
|
+
const e = k(this.options.storagePublic, t), o = new AbortController(), r = setTimeout(() => o.abort(), 1e4), s = (a) => Promise.race([
|
|
375
377
|
a,
|
|
376
378
|
new Promise((n, p) => {
|
|
377
379
|
o.signal.addEventListener(
|
|
@@ -382,8 +384,8 @@ class kt {
|
|
|
382
384
|
]);
|
|
383
385
|
try {
|
|
384
386
|
const [a, n] = await Promise.all([
|
|
385
|
-
s(
|
|
386
|
-
s(
|
|
387
|
+
s(X(e)),
|
|
388
|
+
s($(e))
|
|
387
389
|
]), p = `${a}&t=${encodeURIComponent(n.updated)}`, c = await fetch(p, { signal: o.signal });
|
|
388
390
|
if (!c.ok) throw new Error(`HTTP ${c.status}`);
|
|
389
391
|
return c.text();
|
|
@@ -397,9 +399,9 @@ class kt {
|
|
|
397
399
|
// ─── Metadata ─────────────────────────────────────────────────────────────
|
|
398
400
|
/** Read file metadata. Returns undefined if the file does not exist. */
|
|
399
401
|
async getMetadata(t, e) {
|
|
400
|
-
const o =
|
|
402
|
+
const o = k(this._bucket(t), e);
|
|
401
403
|
try {
|
|
402
|
-
const r = await
|
|
404
|
+
const r = await $(o);
|
|
403
405
|
return {
|
|
404
406
|
updated: r.updated,
|
|
405
407
|
contentType: r.contentType,
|
|
@@ -413,8 +415,8 @@ class kt {
|
|
|
413
415
|
}
|
|
414
416
|
/** Update custom metadata on an existing file. */
|
|
415
417
|
async setMetadata(t, e, o) {
|
|
416
|
-
const r =
|
|
417
|
-
await
|
|
418
|
+
const r = k(this._bucket(t), e);
|
|
419
|
+
await Ie(r, { customMetadata: o });
|
|
418
420
|
}
|
|
419
421
|
// ─── Uploads ──────────────────────────────────────────────────────────────
|
|
420
422
|
/**
|
|
@@ -423,7 +425,7 @@ class kt {
|
|
|
423
425
|
* upload progress needs to be surfaced in the UI.
|
|
424
426
|
*/
|
|
425
427
|
uploadResumable(t, e, o, r) {
|
|
426
|
-
const s =
|
|
428
|
+
const s = k(this._bucket(t), e), a = ft(s, o, r ? { customMetadata: r } : void 0);
|
|
427
429
|
return {
|
|
428
430
|
complete: () => new Promise((n, p) => a.then(() => n(), p)),
|
|
429
431
|
pause: () => a.pause(),
|
|
@@ -442,19 +444,19 @@ class kt {
|
|
|
442
444
|
* Use for small files where progress feedback is not needed.
|
|
443
445
|
*/
|
|
444
446
|
async uploadBytes(t, e, o, r) {
|
|
445
|
-
const s =
|
|
447
|
+
const s = k(this._bucket(t), e);
|
|
446
448
|
await st(s, o, r ? { customMetadata: r } : void 0);
|
|
447
449
|
}
|
|
448
450
|
/** Upload a string or base64-encoded value. */
|
|
449
|
-
async uploadString(t, e, o, r =
|
|
450
|
-
const a =
|
|
451
|
-
await
|
|
451
|
+
async uploadString(t, e, o, r = Se.RAW, s) {
|
|
452
|
+
const a = k(this._bucket(t), e);
|
|
453
|
+
await Te(a, o, r, s ? { customMetadata: s } : void 0);
|
|
452
454
|
}
|
|
453
455
|
// ─── Listing ──────────────────────────────────────────────────────────────
|
|
454
456
|
/** List all item names directly under `prefix` in the given bucket. */
|
|
455
457
|
async listFiles(t, e) {
|
|
456
|
-
const o =
|
|
457
|
-
return (await
|
|
458
|
+
const o = k(this._bucket(t), e);
|
|
459
|
+
return (await U(o)).items.map((s) => s.name);
|
|
458
460
|
}
|
|
459
461
|
/**
|
|
460
462
|
* Recursively list all file full-paths under `prefix` in the given bucket.
|
|
@@ -462,7 +464,7 @@ class kt {
|
|
|
462
464
|
*/
|
|
463
465
|
async listFilesRecursive(t, e) {
|
|
464
466
|
const o = this._bucket(t), r = async (s) => {
|
|
465
|
-
const a = await
|
|
467
|
+
const a = await U(k(o, s));
|
|
466
468
|
let n = a.items.map((p) => p.fullPath);
|
|
467
469
|
for (const p of a.prefixes)
|
|
468
470
|
n = n.concat(await r(p.fullPath));
|
|
@@ -478,7 +480,7 @@ class kt {
|
|
|
478
480
|
const { deleteObject: o } = await import("firebase/storage"), r = this._bucket(t);
|
|
479
481
|
let s = 0;
|
|
480
482
|
const a = async (n) => {
|
|
481
|
-
const p = await
|
|
483
|
+
const p = await U(k(r, n));
|
|
482
484
|
for (const c of p.items)
|
|
483
485
|
await o(c), s++;
|
|
484
486
|
for (const c of p.prefixes)
|
|
@@ -490,7 +492,7 @@ class kt {
|
|
|
490
492
|
// (used by loaders / processors that were already depending on CueBlobStorage)
|
|
491
493
|
/** Upload binary data to the raw bucket with retry logic. */
|
|
492
494
|
async uploadRaw(t, e, o, r = 3, s, a) {
|
|
493
|
-
const n =
|
|
495
|
+
const n = k(this.options.storageRaw, t);
|
|
494
496
|
let p = 0, c;
|
|
495
497
|
for (; p < r; )
|
|
496
498
|
try {
|
|
@@ -531,16 +533,16 @@ class kt {
|
|
|
531
533
|
* Skips upload and returns `false` if the blob already exists.
|
|
532
534
|
*/
|
|
533
535
|
async uploadProcessed(t, e, o) {
|
|
534
|
-
const r =
|
|
535
|
-
return await
|
|
536
|
+
const r = k(this.options.storageProcessed, t);
|
|
537
|
+
return await $(r).catch(() => null) ? !1 : (await st(r, e, { customMetadata: o }), !0);
|
|
536
538
|
}
|
|
537
539
|
/** List all blob names directly under `prefix` in the raw bucket. */
|
|
538
540
|
async listRaw(t) {
|
|
539
|
-
const e =
|
|
540
|
-
return (await
|
|
541
|
+
const e = k(this.options.storageRaw, t);
|
|
542
|
+
return (await U(e)).items.map((r) => r.name);
|
|
541
543
|
}
|
|
542
544
|
}
|
|
543
|
-
const
|
|
545
|
+
const kt = {
|
|
544
546
|
ä: "ae",
|
|
545
547
|
ä: "ae",
|
|
546
548
|
Ä: "AE",
|
|
@@ -576,18 +578,18 @@ const Et = {
|
|
|
576
578
|
};
|
|
577
579
|
function D(i, t = !1) {
|
|
578
580
|
const e = "daca0510-72b5-48ba-9091-b918ca18136b";
|
|
579
|
-
return i =
|
|
581
|
+
return i = ao(i, t), oo(i, e);
|
|
580
582
|
}
|
|
581
|
-
function
|
|
583
|
+
function ao(i, t = !1) {
|
|
582
584
|
let e = i;
|
|
583
|
-
for (const o in
|
|
584
|
-
e = e.replace(new RegExp(o, "g"),
|
|
585
|
+
for (const o in kt)
|
|
586
|
+
e = e.replace(new RegExp(o, "g"), kt[o]);
|
|
585
587
|
return t && e !== i && console.info(`${i} -> ${e}`), e;
|
|
586
588
|
}
|
|
587
|
-
function
|
|
589
|
+
function io(i, t = "") {
|
|
588
590
|
return D(`${t}${i}`);
|
|
589
591
|
}
|
|
590
|
-
class
|
|
592
|
+
class x {
|
|
591
593
|
_value;
|
|
592
594
|
_listeners = /* @__PURE__ */ new Set();
|
|
593
595
|
constructor(t) {
|
|
@@ -646,13 +648,13 @@ const Z = {
|
|
|
646
648
|
apiKey: "AIzaSyAiW42QBx9HS4Khu88pCW7MV66IhBAQul0",
|
|
647
649
|
appId: "1:151132927589:web:d2ffdb377dfadfd23ab88c",
|
|
648
650
|
measurementId: "G-YT4PK6HGZD"
|
|
649
|
-
}, xt = "qaecy-mvp-406413",
|
|
650
|
-
class
|
|
651
|
+
}, xt = "qaecy-mvp-406413", no = "734737865998", le = "europe-west6", Ct = "projects", It = "sessions_eu_west6", St = "spaces_chats_eu_west6", Tt = "spaces_raw_eu_west6", Rt = "spaces_processed_eu_west6", At = "spaces_logs_eu_west6", Pt = "cue_public_eu_west6", Ot = "db_persistence_eu_west6", po = "/data-views/admin/consumption", co = "/data-views/admin/profile/organizations", Dt = "/data-views/admin/profile/api-keys", Lt = "/commands/admin/profile/api-keys", lo = "/commands/admin/profile/terms", ho = (i) => `/data-views/admin/organizations/${i}/members`, go = "/commands/admin/project", uo = (i) => `/commands/admin/project/${i}`, mo = "/assistant/search", he = "/triplestore/query", wo = "/triplestore/update", fo = "/triplestore/shacl", de = "/qlever-server/qlever/query", yo = "/qlever-server/qlever/update", bo = "/qlever-server/qlever/shacl", qt = "/commands/file-system-structure/batch", vo = "/storage/sessions", _o = "/storage/raw", ge = "/storage/processed", jt = "microsoft.com", zt = "superadmin", ut = "https://cue.qaecy.com/r/";
|
|
652
|
+
class $t {
|
|
651
653
|
_auth;
|
|
652
654
|
_endpoints;
|
|
653
|
-
_userSignal = new
|
|
654
|
-
_tokenSignal = new
|
|
655
|
-
_isSuperAdminSignal = new
|
|
655
|
+
_userSignal = new x(null);
|
|
656
|
+
_tokenSignal = new x(null);
|
|
657
|
+
_isSuperAdminSignal = new x(!1);
|
|
656
658
|
_userIdsSignal;
|
|
657
659
|
_stopTokenListener;
|
|
658
660
|
/** Reactive auth state — emits the signed-in `User`, or `null` when signed out. */
|
|
@@ -664,19 +666,19 @@ class Ut {
|
|
|
664
666
|
/** All unique UIDs for the current user (Firebase UID + linked provider UIDs). */
|
|
665
667
|
userIds;
|
|
666
668
|
constructor(t, e = !1, o) {
|
|
667
|
-
this._auth =
|
|
669
|
+
this._auth = Me(t), this._endpoints = o, e && Ne(this._auth, o.authEmulatorUrl, {
|
|
668
670
|
disableWarnings: !0
|
|
669
671
|
}), this.user = this._userSignal.asReadonly(), this.token = this._tokenSignal.asReadonly(), this.isSuperAdmin = this._isSuperAdminSignal.asReadonly(), this._userIdsSignal = dt([this._userSignal], () => {
|
|
670
672
|
const r = this._userSignal.get();
|
|
671
673
|
if (!r) return [];
|
|
672
674
|
const s = /* @__PURE__ */ new Set([r.uid]);
|
|
673
675
|
return r.providerData.forEach((a) => s.add(a.uid)), Array.from(s);
|
|
674
|
-
}), this.userIds = this._userIdsSignal, this._stopTokenListener =
|
|
676
|
+
}), this.userIds = this._userIdsSignal, this._stopTokenListener = Fe(this._auth, async (r) => {
|
|
675
677
|
if (this._userSignal.set(r), r) {
|
|
676
678
|
const s = await r.getIdToken();
|
|
677
679
|
this._tokenSignal.set(s);
|
|
678
680
|
const a = await at(r);
|
|
679
|
-
this._isSuperAdminSignal.set(a.claims.role ===
|
|
681
|
+
this._isSuperAdminSignal.set(a.claims.role === zt);
|
|
680
682
|
} else
|
|
681
683
|
this._tokenSignal.set(null), this._isSuperAdminSignal.set(!1);
|
|
682
684
|
});
|
|
@@ -689,14 +691,14 @@ class Ut {
|
|
|
689
691
|
if (t === "password") {
|
|
690
692
|
if (!e)
|
|
691
693
|
throw new Error("credentials are required for password sign-in");
|
|
692
|
-
return (await
|
|
694
|
+
return (await Be(
|
|
693
695
|
this._auth,
|
|
694
696
|
e.email,
|
|
695
697
|
e.password
|
|
696
698
|
)).user;
|
|
697
699
|
}
|
|
698
|
-
const o = t === "google" ? new it() : new nt(
|
|
699
|
-
return (await
|
|
700
|
+
const o = t === "google" ? new it() : new nt(jt);
|
|
701
|
+
return (await Ge(this._auth, o)).user;
|
|
700
702
|
}
|
|
701
703
|
/**
|
|
702
704
|
* Initiate a redirect-based sign-in (mobile / iframe contexts where popups
|
|
@@ -704,8 +706,8 @@ class Ut {
|
|
|
704
706
|
* retrieve the result.
|
|
705
707
|
*/
|
|
706
708
|
async signInWithRedirect(t) {
|
|
707
|
-
const e = t === "google" ? new it() : new nt(
|
|
708
|
-
await
|
|
709
|
+
const e = t === "google" ? new it() : new nt(jt);
|
|
710
|
+
await He(this._auth, e);
|
|
709
711
|
}
|
|
710
712
|
/**
|
|
711
713
|
* Retrieve the result of a redirect sign-in. Returns the signed-in `User`
|
|
@@ -713,7 +715,7 @@ class Ut {
|
|
|
713
715
|
* Call this once on app startup before showing a sign-in UI.
|
|
714
716
|
*/
|
|
715
717
|
async checkRedirectResult() {
|
|
716
|
-
return (await
|
|
718
|
+
return (await We(this._auth))?.user ?? null;
|
|
717
719
|
}
|
|
718
720
|
/**
|
|
719
721
|
* One-shot async check — returns `true` if the current user has the
|
|
@@ -722,7 +724,7 @@ class Ut {
|
|
|
722
724
|
*/
|
|
723
725
|
async checkSuperAdmin() {
|
|
724
726
|
const t = this._auth.currentUser;
|
|
725
|
-
return t ? (await at(t)).claims.role ===
|
|
727
|
+
return t ? (await at(t)).claims.role === zt : !1;
|
|
726
728
|
}
|
|
727
729
|
/** Sign in with a Cue API key. `projectId` is optional — omit it when no project context is available (e.g. admin flows). */
|
|
728
730
|
async signInWithApiKey(t, e) {
|
|
@@ -743,7 +745,7 @@ class Ut {
|
|
|
743
745
|
}
|
|
744
746
|
/** Sign out the current user */
|
|
745
747
|
async signOut() {
|
|
746
|
-
await
|
|
748
|
+
await Ve(this._auth);
|
|
747
749
|
}
|
|
748
750
|
/**
|
|
749
751
|
* Register a new user by name and email.
|
|
@@ -773,7 +775,7 @@ class Ut {
|
|
|
773
775
|
}
|
|
774
776
|
/** Subscribe to authentication state changes. Returns an unsubscribe function. */
|
|
775
777
|
onAuthStateChanged(t) {
|
|
776
|
-
return
|
|
778
|
+
return Xe(this._auth, t);
|
|
777
779
|
}
|
|
778
780
|
/** Get the Firebase ID token for the current user, or null if not authenticated */
|
|
779
781
|
async getToken(t = !1) {
|
|
@@ -805,29 +807,33 @@ class Ut {
|
|
|
805
807
|
return this._auth;
|
|
806
808
|
}
|
|
807
809
|
}
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
810
|
+
const Eo = {
|
|
811
|
+
raw: _o,
|
|
812
|
+
processed: ge
|
|
813
|
+
};
|
|
814
|
+
class Ut {
|
|
815
|
+
constructor(t, e) {
|
|
816
|
+
this._auth = t, this._gatewayUrl = e;
|
|
811
817
|
}
|
|
812
|
-
|
|
818
|
+
_auth;
|
|
819
|
+
_gatewayUrl;
|
|
813
820
|
/**
|
|
814
|
-
* Returns a
|
|
821
|
+
* Returns a gateway download URL for a document stored in Cue.
|
|
815
822
|
*
|
|
816
823
|
* The storage path is `{projectId}/{uuid}{suffix}`, e.g. `my-project/abc-123.pdf`.
|
|
824
|
+
* The returned URL must be fetched with an Authorization header.
|
|
817
825
|
*
|
|
818
826
|
* @param projectId - The Cue project (space) ID.
|
|
819
827
|
* @param uuid - The document UUID.
|
|
820
828
|
* @param suffix - File suffix including the leading dot, e.g. `'.pdf'`, `'.ifc'`.
|
|
821
829
|
* @param bucket - `'raw'` (default, original uploads) or `'processed'` (derived artefacts).
|
|
822
830
|
*/
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
if (!a) throw new Error(`File not found in storage: ${s} (bucket: ${r})`);
|
|
826
|
-
return a;
|
|
831
|
+
getDownloadUrl(t, e, o, r = "raw") {
|
|
832
|
+
return `${this._gatewayUrl}${Eo[r]}/${t}/${e}${o}`;
|
|
827
833
|
}
|
|
828
834
|
/**
|
|
829
|
-
* Returns a
|
|
830
|
-
*
|
|
835
|
+
* Returns a gateway download URL for an alternative representation using its
|
|
836
|
+
* full `qcy:remoteRelativePath` stored in the processed bucket.
|
|
831
837
|
*
|
|
832
838
|
* Use this instead of `getDownloadUrl` when the document info was obtained via
|
|
833
839
|
* `fetchAlternativeRepresentations` and carries a `remoteRelativePath`.
|
|
@@ -835,14 +841,24 @@ class zt {
|
|
|
835
841
|
* @param remoteRelativePath - The full path in the processed bucket,
|
|
836
842
|
* e.g. `{projectId}/fragments/{uuid}.fragments`.
|
|
837
843
|
*/
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
844
|
+
getAltRepDownloadUrl(t) {
|
|
845
|
+
return `${this._gatewayUrl}${ge}/${t}`;
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Fetch a file through the gateway and return it as a Blob.
|
|
849
|
+
* Convenience wrapper around `getDownloadUrl` + `authenticatedFetch`.
|
|
850
|
+
*/
|
|
851
|
+
async downloadBlob(t, e, o, r = "raw") {
|
|
852
|
+
const s = this.getDownloadUrl(t, e, o, r), a = await this._auth.authenticatedFetch(s, {
|
|
853
|
+
headers: { "cue-project-id": t }
|
|
854
|
+
});
|
|
855
|
+
if (!a.ok)
|
|
856
|
+
throw new Error(`Failed to download file: ${a.status} ${a.statusText}`);
|
|
857
|
+
return a.blob();
|
|
842
858
|
}
|
|
843
859
|
}
|
|
844
|
-
const
|
|
845
|
-
class
|
|
860
|
+
const ko = "/data-views/tables", xo = "/commands/tables";
|
|
861
|
+
class Co {
|
|
846
862
|
constructor(t, e) {
|
|
847
863
|
this._auth = t, this._gatewayUrl = e;
|
|
848
864
|
}
|
|
@@ -850,7 +866,7 @@ class fo {
|
|
|
850
866
|
_gatewayUrl;
|
|
851
867
|
async listTables(t) {
|
|
852
868
|
const e = await this._auth.authenticatedFetch(
|
|
853
|
-
`${this._gatewayUrl}${
|
|
869
|
+
`${this._gatewayUrl}${ko}`,
|
|
854
870
|
{
|
|
855
871
|
headers: {
|
|
856
872
|
"Content-Type": "application/json",
|
|
@@ -865,7 +881,7 @@ class fo {
|
|
|
865
881
|
}
|
|
866
882
|
async saveTables(t, e) {
|
|
867
883
|
const o = await this._auth.authenticatedFetch(
|
|
868
|
-
`${this._gatewayUrl}${
|
|
884
|
+
`${this._gatewayUrl}${xo}`,
|
|
869
885
|
{
|
|
870
886
|
method: "PUT",
|
|
871
887
|
headers: {
|
|
@@ -880,8 +896,8 @@ class fo {
|
|
|
880
896
|
throw new Error(`Failed to save tables: ${o.status} ${o.statusText}`);
|
|
881
897
|
}
|
|
882
898
|
}
|
|
883
|
-
const
|
|
884
|
-
class
|
|
899
|
+
const Io = "/semantic-extraction/extract";
|
|
900
|
+
class So {
|
|
885
901
|
constructor(t, e) {
|
|
886
902
|
this._auth = t, this._gatewayUrl = e;
|
|
887
903
|
}
|
|
@@ -898,7 +914,7 @@ class bo {
|
|
|
898
914
|
const e = t.rdfFormat ?? "json-ld", o = new FormData();
|
|
899
915
|
o.append("file", t.image, "page.png"), o.append("template", JSON.stringify(t.template)), o.append("space_id", t.projectId), o.append("rdf_format", e), t.category && o.append("category", t.category), t.text && o.append("text", t.text);
|
|
900
916
|
const r = await this._auth.authenticatedFetch(
|
|
901
|
-
`${this._gatewayUrl}${
|
|
917
|
+
`${this._gatewayUrl}${Io}`,
|
|
902
918
|
{
|
|
903
919
|
method: "POST",
|
|
904
920
|
// Do NOT set Content-Type; browser sets it with the correct boundary.
|
|
@@ -919,9 +935,38 @@ class bo {
|
|
|
919
935
|
return { jsonld: await r.json() };
|
|
920
936
|
}
|
|
921
937
|
}
|
|
922
|
-
class
|
|
938
|
+
class To {
|
|
939
|
+
constructor(t, e) {
|
|
940
|
+
this._auth = t, this._gatewayUrl = e;
|
|
941
|
+
}
|
|
942
|
+
_auth;
|
|
943
|
+
_gatewayUrl;
|
|
944
|
+
/**
|
|
945
|
+
* Fetch and decompress a session context document.
|
|
946
|
+
*
|
|
947
|
+
* Context files are stored as `sessions_eu_west6/{projectId}/contexts/{contextId}.json.gz`
|
|
948
|
+
* and served via the gateway at `GET /storage/sessions/{projectId}/contexts/{contextId}.json.gz`.
|
|
949
|
+
*
|
|
950
|
+
* @param projectId - The project the context belongs to.
|
|
951
|
+
* @param contextId - The context document ID (without the `.json.gz` suffix).
|
|
952
|
+
*/
|
|
953
|
+
async getContext(t, e) {
|
|
954
|
+
const o = `${this._gatewayUrl}${vo}/${t}/contexts/${e}.json.gz`, r = await this._auth.authenticatedFetch(o, {
|
|
955
|
+
headers: {
|
|
956
|
+
"cue-project-id": t,
|
|
957
|
+
// Prevent the HTTP layer from auto-decompressing so we can handle it explicitly.
|
|
958
|
+
"Accept-Encoding": "identity"
|
|
959
|
+
}
|
|
960
|
+
});
|
|
961
|
+
if (!r.ok)
|
|
962
|
+
throw new Error(`Failed to fetch context ${e}: ${r.status} ${r.statusText}`);
|
|
963
|
+
const s = new DecompressionStream("gzip"), a = r.body.pipeThrough(s);
|
|
964
|
+
return JSON.parse(await new Response(a).text());
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
class Mt {
|
|
923
968
|
constructor(t, e, o, r) {
|
|
924
|
-
this._auth = t, this._gatewayUrl = e, this.projects = o, this.sync = r, this.tables = new
|
|
969
|
+
this._auth = t, this._gatewayUrl = e, this.projects = o, this.sync = r, this.tables = new Co(t, e), this.extraction = new So(t, e), this.contexts = new To(t, e);
|
|
925
970
|
}
|
|
926
971
|
_auth;
|
|
927
972
|
_gatewayUrl;
|
|
@@ -930,6 +975,8 @@ class $t {
|
|
|
930
975
|
tables;
|
|
931
976
|
/** Semantic extraction client — call document pages against a SemanticTemplate. */
|
|
932
977
|
extraction;
|
|
978
|
+
/** Session context file client — fetch and decompress context documents. */
|
|
979
|
+
contexts;
|
|
933
980
|
/** Active language used for language-sensitive SPARQL queries across all project classes. */
|
|
934
981
|
language = "en";
|
|
935
982
|
/** Updates the active language. All project classes (`CueProjectSchema`, `CueProjectDocuments`, `CueProjectEntities`) read this at query time. */
|
|
@@ -955,7 +1002,7 @@ class $t {
|
|
|
955
1002
|
*/
|
|
956
1003
|
async search(t) {
|
|
957
1004
|
const e = await this._auth.authenticatedFetch(
|
|
958
|
-
`${this._gatewayUrl}${
|
|
1005
|
+
`${this._gatewayUrl}${mo}`,
|
|
959
1006
|
{
|
|
960
1007
|
method: "POST",
|
|
961
1008
|
headers: { "Content-Type": "application/json", "cue-project-id": t.projectId },
|
|
@@ -978,7 +1025,7 @@ class $t {
|
|
|
978
1025
|
*/
|
|
979
1026
|
async sparql(t, e, o) {
|
|
980
1027
|
o || (o = (await this.projects.getProject(e))?.projectSettings?.graph?.type ?? "qlever");
|
|
981
|
-
const r = o === "fuseki" ?
|
|
1028
|
+
const r = o === "fuseki" ? he : de;
|
|
982
1029
|
console.log(`Executing SPARQL query against ${r} for project ${e} with graph type ${o}`);
|
|
983
1030
|
const s = new URLSearchParams();
|
|
984
1031
|
s.append("query", t);
|
|
@@ -1015,7 +1062,7 @@ class $t {
|
|
|
1015
1062
|
const r = o?.format ?? "json-ld", s = r === "turtle" ? "text/turtle" : "application/ld+json";
|
|
1016
1063
|
if (o?.graphType === "fuseki") {
|
|
1017
1064
|
const c = await this._auth.authenticatedFetch(
|
|
1018
|
-
`${this._gatewayUrl}${
|
|
1065
|
+
`${this._gatewayUrl}${fo}`,
|
|
1019
1066
|
{
|
|
1020
1067
|
method: "POST",
|
|
1021
1068
|
headers: {
|
|
@@ -1033,7 +1080,7 @@ class $t {
|
|
|
1033
1080
|
}
|
|
1034
1081
|
return r === "turtle" ? c.text() : c.json();
|
|
1035
1082
|
}
|
|
1036
|
-
const a = `${this._gatewayUrl}${
|
|
1083
|
+
const a = `${this._gatewayUrl}${bo}${o?.verbose ? "?verbose=true" : ""}`, n = new URLSearchParams({ shape: t }), p = await this._auth.authenticatedFetch(a, {
|
|
1037
1084
|
method: "POST",
|
|
1038
1085
|
headers: {
|
|
1039
1086
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
@@ -1051,7 +1098,7 @@ class $t {
|
|
|
1051
1098
|
}
|
|
1052
1099
|
async getConsumption(t) {
|
|
1053
1100
|
const e = await this._auth.authenticatedFetch(
|
|
1054
|
-
`${this._gatewayUrl}${
|
|
1101
|
+
`${this._gatewayUrl}${po}`,
|
|
1055
1102
|
{
|
|
1056
1103
|
headers: {
|
|
1057
1104
|
"Content-Type": "application/json",
|
|
@@ -1078,13 +1125,13 @@ const pt = [
|
|
|
1078
1125
|
"railway",
|
|
1079
1126
|
"natural",
|
|
1080
1127
|
"manmade"
|
|
1081
|
-
],
|
|
1128
|
+
], ue = [
|
|
1082
1129
|
"address",
|
|
1083
1130
|
"poi",
|
|
1084
1131
|
"railway",
|
|
1085
1132
|
"natural",
|
|
1086
1133
|
"manmade"
|
|
1087
|
-
],
|
|
1134
|
+
], Ro = {
|
|
1088
1135
|
address: {
|
|
1089
1136
|
category: "address",
|
|
1090
1137
|
label: "Address",
|
|
@@ -1147,9 +1194,9 @@ const pt = [
|
|
|
1147
1194
|
}
|
|
1148
1195
|
};
|
|
1149
1196
|
function T(i) {
|
|
1150
|
-
return
|
|
1197
|
+
return Ro[i];
|
|
1151
1198
|
}
|
|
1152
|
-
const
|
|
1199
|
+
const Ao = {
|
|
1153
1200
|
"land-use-plan": "#f59e0b",
|
|
1154
1201
|
// amber – primary zoning
|
|
1155
1202
|
"local-plan": "#ec4899",
|
|
@@ -1180,7 +1227,7 @@ const _o = {
|
|
|
1180
1227
|
function M(i, t) {
|
|
1181
1228
|
return i[0] < t[2] && i[2] > t[0] && i[1] < t[3] && i[3] > t[1];
|
|
1182
1229
|
}
|
|
1183
|
-
const
|
|
1230
|
+
const Po = "https://nominatim.openstreetmap.org", Oo = "cue-gis/0.0.1", Do = {
|
|
1184
1231
|
address: "street",
|
|
1185
1232
|
poi: "shop",
|
|
1186
1233
|
railway: "station",
|
|
@@ -1195,7 +1242,7 @@ const ko = "https://nominatim.openstreetmap.org", Eo = "cue-gis/0.0.1", xo = {
|
|
|
1195
1242
|
function B(i) {
|
|
1196
1243
|
return `${L}:${i}`;
|
|
1197
1244
|
}
|
|
1198
|
-
function
|
|
1245
|
+
function Lo(i) {
|
|
1199
1246
|
const t = T(i);
|
|
1200
1247
|
return {
|
|
1201
1248
|
id: B(i),
|
|
@@ -1210,17 +1257,17 @@ function Io(i) {
|
|
|
1210
1257
|
descriptionKey: `gis.layer.${L}.${i}.description`
|
|
1211
1258
|
};
|
|
1212
1259
|
}
|
|
1213
|
-
class
|
|
1260
|
+
class qo {
|
|
1214
1261
|
baseUrl;
|
|
1215
1262
|
userAgent;
|
|
1216
1263
|
email;
|
|
1217
1264
|
limit;
|
|
1218
1265
|
constructor(t = {}) {
|
|
1219
|
-
this.baseUrl = t.baseUrl ??
|
|
1266
|
+
this.baseUrl = t.baseUrl ?? Po, this.userAgent = t.userAgent ?? Oo, this.email = t.email, this.limit = Math.min(t.limit ?? 40, 40);
|
|
1220
1267
|
}
|
|
1221
1268
|
async listFeatureCategoryDescriptors(t) {
|
|
1222
1269
|
return (await Promise.allSettled(
|
|
1223
|
-
|
|
1270
|
+
ue.map(async (o) => {
|
|
1224
1271
|
const r = await this.search(t, o);
|
|
1225
1272
|
return { category: o, hasResults: r.length > 0 };
|
|
1226
1273
|
})
|
|
@@ -1229,7 +1276,7 @@ class Co {
|
|
|
1229
1276
|
).map((o) => T(o.value.category));
|
|
1230
1277
|
}
|
|
1231
1278
|
async listAvailableLayers(t) {
|
|
1232
|
-
return (await this.listFeatureCategoryDescriptors(t)).map((o) =>
|
|
1279
|
+
return (await this.listFeatureCategoryDescriptors(t)).map((o) => Lo(o.category));
|
|
1233
1280
|
}
|
|
1234
1281
|
async getFeaturesForLayer(t, e) {
|
|
1235
1282
|
const o = pt.find((r) => B(r) === e);
|
|
@@ -1246,7 +1293,7 @@ class Co {
|
|
|
1246
1293
|
* so bounded viewbox searches return meaningful results.
|
|
1247
1294
|
*/
|
|
1248
1295
|
async search(t, e) {
|
|
1249
|
-
const [o, r, s, a] = t, n = e ?
|
|
1296
|
+
const [o, r, s, a] = t, n = e ? Do[e] : "place", p = new URLSearchParams({
|
|
1250
1297
|
q: n,
|
|
1251
1298
|
format: "jsonv2",
|
|
1252
1299
|
viewbox: `${o},${a},${s},${r}`,
|
|
@@ -1289,7 +1336,7 @@ class Co {
|
|
|
1289
1336
|
};
|
|
1290
1337
|
}
|
|
1291
1338
|
}
|
|
1292
|
-
const
|
|
1339
|
+
const Nt = {
|
|
1293
1340
|
// 100s – Residential
|
|
1294
1341
|
110: "residential",
|
|
1295
1342
|
120: "residential",
|
|
@@ -1368,7 +1415,7 @@ const Mt = {
|
|
|
1368
1415
|
960: "agricultural",
|
|
1369
1416
|
970: "agricultural",
|
|
1370
1417
|
990: "other"
|
|
1371
|
-
},
|
|
1418
|
+
}, Ft = {
|
|
1372
1419
|
1010: "residential",
|
|
1373
1420
|
1020: "mixed",
|
|
1374
1421
|
1030: "residential",
|
|
@@ -1398,7 +1445,7 @@ const Mt = {
|
|
|
1398
1445
|
1281: "infrastructure",
|
|
1399
1446
|
1282: "infrastructure",
|
|
1400
1447
|
9999: "other"
|
|
1401
|
-
},
|
|
1448
|
+
}, jo = {
|
|
1402
1449
|
// Residential
|
|
1403
1450
|
1110: "residential",
|
|
1404
1451
|
// Einfamilienhaus
|
|
@@ -1460,7 +1507,7 @@ const Mt = {
|
|
|
1460
1507
|
// Empfangsgebäude Bahn/Bus
|
|
1461
1508
|
1282: "infrastructure"
|
|
1462
1509
|
// Parkhaus, Garage
|
|
1463
|
-
},
|
|
1510
|
+
}, zo = [
|
|
1464
1511
|
// "Gebäude" is the Swiss AV BoFlaeche land-cover label for a building footprint.
|
|
1465
1512
|
// It does not encode the actual use type, so map it to 'other' as a safe fallback.
|
|
1466
1513
|
[/^geb[äa]ude$/i, "other"],
|
|
@@ -1474,22 +1521,22 @@ const Mt = {
|
|
|
1474
1521
|
[/gemischt|mixed|blandet/i, "mixed"]
|
|
1475
1522
|
];
|
|
1476
1523
|
function O(i) {
|
|
1477
|
-
for (const [t, e] of
|
|
1524
|
+
for (const [t, e] of zo)
|
|
1478
1525
|
if (t.test(i)) return e;
|
|
1479
1526
|
}
|
|
1480
|
-
function
|
|
1527
|
+
function $o(i, t) {
|
|
1481
1528
|
if (i == null) return;
|
|
1482
1529
|
const e = String(i).trim();
|
|
1483
|
-
return t === "swiss-gwr" ?
|
|
1530
|
+
return t === "swiss-gwr" ? jo[e] ?? O(e) : t === "danish-matrikel" ? Nt[e] ?? O(e) : t === "zurich-wfs" || t === "swiss-av-wfs" ? Ft[e] ?? O(e) : Ft[e] ?? Nt[e] ?? O(e);
|
|
1484
1531
|
}
|
|
1485
|
-
function
|
|
1532
|
+
function Uo(i, t) {
|
|
1486
1533
|
if (i != null)
|
|
1487
1534
|
return O(String(i).trim());
|
|
1488
1535
|
}
|
|
1489
|
-
function
|
|
1536
|
+
function me(i) {
|
|
1490
1537
|
return i.trim().toLowerCase().replace(/[\s_\-]/g, "");
|
|
1491
1538
|
}
|
|
1492
|
-
const
|
|
1539
|
+
const Mo = {
|
|
1493
1540
|
// Swiss ÖREB rechtsstatus
|
|
1494
1541
|
inkraft: "in-force",
|
|
1495
1542
|
laufendeanderung: "amendment-pending",
|
|
@@ -1508,11 +1555,11 @@ const Po = {
|
|
|
1508
1555
|
forslag: "proposed",
|
|
1509
1556
|
aflyst: "repealed"
|
|
1510
1557
|
};
|
|
1511
|
-
function
|
|
1558
|
+
function we(i) {
|
|
1512
1559
|
if (i)
|
|
1513
|
-
return
|
|
1560
|
+
return Mo[me(i)];
|
|
1514
1561
|
}
|
|
1515
|
-
const
|
|
1562
|
+
const Bt = {
|
|
1516
1563
|
// Swiss Nutzungsplanung (typ_gde_bezeichnung and common variants)
|
|
1517
1564
|
grundnutzungszonenplan: "land-use-plan",
|
|
1518
1565
|
nutzungszonenplan: "land-use-plan",
|
|
@@ -1566,7 +1613,7 @@ const Ft = {
|
|
|
1566
1613
|
// Danish plandata.dk
|
|
1567
1614
|
lokalplan: "local-plan",
|
|
1568
1615
|
kommuneplanramme: "municipal-plan-framework"
|
|
1569
|
-
},
|
|
1616
|
+
}, No = [
|
|
1570
1617
|
[/quartiererhalt/i, "neighbourhood-conservation-plan"],
|
|
1571
1618
|
[/lärmempfindlich|laermempfindlich/i, "noise-sensitivity-plan"],
|
|
1572
1619
|
[/gewässerschutz|grundwasserschutz/i, "water-protection-plan"],
|
|
@@ -1606,24 +1653,24 @@ const Ft = {
|
|
|
1606
1653
|
// Catch-all: any remaining Xzone / Xareal designation from the Grundnutzungszonenplan
|
|
1607
1654
|
[/zone$|areal$/i, "land-use-plan"]
|
|
1608
1655
|
];
|
|
1609
|
-
function
|
|
1656
|
+
function fe(i) {
|
|
1610
1657
|
if (!i) return;
|
|
1611
|
-
const t =
|
|
1612
|
-
if (t in
|
|
1613
|
-
for (const [e, o] of
|
|
1658
|
+
const t = me(i);
|
|
1659
|
+
if (t in Bt) return Bt[t];
|
|
1660
|
+
for (const [e, o] of No)
|
|
1614
1661
|
if (e.test(i)) return o;
|
|
1615
1662
|
console.warn(
|
|
1616
1663
|
`[cue-gis] Unknown zone plan type — add "${i}" to classifyZonePlanType: no ZonePlanType mapping found.`
|
|
1617
1664
|
);
|
|
1618
1665
|
}
|
|
1619
|
-
const
|
|
1666
|
+
const Fo = "https://maps.zh.ch/wfs/OGDZHWFS", Bo = "zurich-wfs", Go = [8.35, 47.15, 8.95, 47.7], Ho = [5.9, 45.7, 10.55, 47.85];
|
|
1620
1667
|
function J(i) {
|
|
1621
1668
|
return typeof i == "string" ? i : i.typeName;
|
|
1622
1669
|
}
|
|
1623
1670
|
function tt(i) {
|
|
1624
1671
|
return typeof i == "string" ? void 0 : i.cqlFilter;
|
|
1625
1672
|
}
|
|
1626
|
-
function
|
|
1673
|
+
function Wo(i) {
|
|
1627
1674
|
if (!i) return [0, 0];
|
|
1628
1675
|
const t = i.coordinates;
|
|
1629
1676
|
switch (i.type) {
|
|
@@ -1641,20 +1688,20 @@ function Uo(i) {
|
|
|
1641
1688
|
return [0, 0];
|
|
1642
1689
|
}
|
|
1643
1690
|
}
|
|
1644
|
-
function
|
|
1691
|
+
function Vo(i, t) {
|
|
1645
1692
|
if (!i) return t;
|
|
1646
1693
|
for (const e of ["plannavn", "bezeichnung", "name", "strassenname", "objektname", "title", "label"])
|
|
1647
1694
|
if (typeof i[e] == "string" && i[e]) return i[e];
|
|
1648
1695
|
return t;
|
|
1649
1696
|
}
|
|
1650
|
-
function
|
|
1697
|
+
function Xo(i, t, e) {
|
|
1651
1698
|
return e ? `${i}:${t}[${e}]` : `${i}:${t}`;
|
|
1652
1699
|
}
|
|
1653
|
-
const
|
|
1700
|
+
const Ko = /* @__PURE__ */ new Set(["building", "cadastre", "greenspace", "paved", "zone"]);
|
|
1654
1701
|
function et(i, t, e, o) {
|
|
1655
|
-
const r = e.replace(/^ms:/, ""), s = T(t), a =
|
|
1702
|
+
const r = e.replace(/^ms:/, ""), s = T(t), a = Ko.has(t) ? "priority" : "raw";
|
|
1656
1703
|
return {
|
|
1657
|
-
id:
|
|
1704
|
+
id: Xo(i, e, o),
|
|
1658
1705
|
sourceId: i,
|
|
1659
1706
|
sourceLayerId: e,
|
|
1660
1707
|
category: t,
|
|
@@ -1666,32 +1713,32 @@ function et(i, t, e, o) {
|
|
|
1666
1713
|
descriptionKey: `gis.layer.${i}.${r}.description`
|
|
1667
1714
|
};
|
|
1668
1715
|
}
|
|
1669
|
-
function
|
|
1716
|
+
function Qo(i, t) {
|
|
1670
1717
|
if (!i) return { featureType: "building" };
|
|
1671
1718
|
const e = i.grundflaeche ?? i.gbf ?? i.gebaeudegrundrissflaeche ?? i.flaeche ?? void 0, o = i.vollgeschosse ?? i.geschossanzahl ?? i.anzahl_geschosse ?? void 0, r = i.gebaeudefunktion ?? i.gfkode ?? i.art ?? i.objektart ?? void 0, s = i.baujahr ?? i.bauperiode ?? void 0, a = String(i.egid ?? i.gwr_egid ?? i.egris_egid ?? "").trim() || void 0;
|
|
1672
1719
|
return {
|
|
1673
1720
|
featureType: "building",
|
|
1674
1721
|
areaM2: typeof e == "number" ? e : void 0,
|
|
1675
1722
|
buildingUse: r ? String(r) : void 0,
|
|
1676
|
-
buildingUseGeneric:
|
|
1723
|
+
buildingUseGeneric: $o(r, t),
|
|
1677
1724
|
floors: typeof o == "number" ? o : void 0,
|
|
1678
1725
|
yearBuilt: typeof s == "number" ? s : void 0,
|
|
1679
1726
|
registryId: a
|
|
1680
1727
|
};
|
|
1681
1728
|
}
|
|
1682
|
-
function
|
|
1729
|
+
function Yo(i, t) {
|
|
1683
1730
|
if (!i) return { featureType: "plot" };
|
|
1684
1731
|
const e = i.egris_egrid ?? i.egrid ?? void 0, o = i.nummer ?? void 0, r = i.nbident ?? void 0, s = o && r ? `${o}, ${r}` : o ?? void 0, a = i.flaechenmass ?? i.flaeche ?? void 0, n = i.art ?? i.nutzungsart ?? void 0;
|
|
1685
1732
|
return {
|
|
1686
1733
|
featureType: "plot",
|
|
1687
1734
|
areaM2: typeof a == "number" ? a : void 0,
|
|
1688
1735
|
plotUse: n ? String(n) : void 0,
|
|
1689
|
-
plotUseGeneric:
|
|
1736
|
+
plotUseGeneric: Uo(n),
|
|
1690
1737
|
plotId: s,
|
|
1691
1738
|
registryId: e
|
|
1692
1739
|
};
|
|
1693
1740
|
}
|
|
1694
|
-
function
|
|
1741
|
+
function Zo(i) {
|
|
1695
1742
|
if (!i) return { featureType: "greenspace" };
|
|
1696
1743
|
const t = i.flaeche ?? void 0, e = i.art ?? void 0;
|
|
1697
1744
|
return {
|
|
@@ -1700,7 +1747,7 @@ function Bo(i) {
|
|
|
1700
1747
|
surfaceType: e ? String(e) : void 0
|
|
1701
1748
|
};
|
|
1702
1749
|
}
|
|
1703
|
-
function
|
|
1750
|
+
function Jo(i) {
|
|
1704
1751
|
if (!i) return { featureType: "paved" };
|
|
1705
1752
|
const t = i.flaeche ?? void 0, e = i.art ?? void 0;
|
|
1706
1753
|
return {
|
|
@@ -1709,9 +1756,9 @@ function Go(i) {
|
|
|
1709
1756
|
surfaceType: e ? String(e) : void 0
|
|
1710
1757
|
};
|
|
1711
1758
|
}
|
|
1712
|
-
function
|
|
1759
|
+
function tr(i) {
|
|
1713
1760
|
if (!i) return { featureType: "zone" };
|
|
1714
|
-
const t = i.plannavn ?? i.bezeichnung ?? i.typ_bezeichnung ?? i.art ?? void 0, e = i.planid ?? i.plannummer ?? void 0, o = i.artcode ?? i.typ_code ?? i.abkuerzung ?? e ?? void 0, r = i.rechtsstatus ?? i.status ?? void 0, s =
|
|
1761
|
+
const t = i.plannavn ?? i.bezeichnung ?? i.typ_bezeichnung ?? i.art ?? void 0, e = i.planid ?? i.plannummer ?? void 0, o = i.artcode ?? i.typ_code ?? i.abkuerzung ?? e ?? void 0, r = i.rechtsstatus ?? i.status ?? void 0, s = we(r), a = i.typ_gde_bezeichnung ?? void 0, n = fe(a), p = i.dagsordenpunkt_url ?? i.dokument_url ?? i.link ?? void 0, c = i.auflagedatum ?? void 0, h = i.festsetzungsdatum ?? void 0, d = i.genehmigungsdatum ?? void 0, g = i.inkraftsetzungsdatum ?? void 0, u = i.flaeche ?? i.flaeche_m2 ?? void 0;
|
|
1715
1762
|
return {
|
|
1716
1763
|
featureType: "zone",
|
|
1717
1764
|
zoneType: t ? String(t) : void 0,
|
|
@@ -1727,7 +1774,7 @@ function Ho(i) {
|
|
|
1727
1774
|
areaM2: typeof u == "number" ? u : void 0
|
|
1728
1775
|
};
|
|
1729
1776
|
}
|
|
1730
|
-
function
|
|
1777
|
+
function er(i) {
|
|
1731
1778
|
const t = i.match(/^(\w+)\s*=\s*'([^']+)'$/);
|
|
1732
1779
|
if (t) {
|
|
1733
1780
|
const [, o, r] = t;
|
|
@@ -1748,7 +1795,7 @@ class ot {
|
|
|
1748
1795
|
sourceId;
|
|
1749
1796
|
outputFormat;
|
|
1750
1797
|
constructor(t) {
|
|
1751
|
-
this.categoryMap = t.categoryMap, this.baseUrl = t.baseUrl ??
|
|
1798
|
+
this.categoryMap = t.categoryMap, this.baseUrl = t.baseUrl ?? Fo, this.sourceId = t.sourceId ?? Bo, this.outputFormat = t.outputFormat ?? "application/json; subtype=geojson";
|
|
1752
1799
|
}
|
|
1753
1800
|
async listFeatureCategoryDescriptors(t) {
|
|
1754
1801
|
const e = await this.listAvailableLayers(t);
|
|
@@ -1772,7 +1819,7 @@ class ot {
|
|
|
1772
1819
|
return o ? this._fetchAndConvert(t, o.descriptor, o.cqlFilter) : [];
|
|
1773
1820
|
}
|
|
1774
1821
|
async _fetchAndConvert(t, e, o) {
|
|
1775
|
-
const r = await this._fetchFeatures(t, e.sourceLayerId, void 0, o), s = o ?
|
|
1822
|
+
const r = await this._fetchFeatures(t, e.sourceLayerId, void 0, o), s = o ? er(o) : void 0;
|
|
1776
1823
|
return (s ? r.features.filter((n) => s(n.properties)) : r.features).map((n, p) => this.toGisFeature(n, e, p));
|
|
1777
1824
|
}
|
|
1778
1825
|
/**
|
|
@@ -1821,7 +1868,7 @@ class ot {
|
|
|
1821
1868
|
return g.json();
|
|
1822
1869
|
}
|
|
1823
1870
|
toGisFeature(t, e, o) {
|
|
1824
|
-
const [r, s] =
|
|
1871
|
+
const [r, s] = Wo(t.geometry), a = Vo(t.properties, `${e.sourceLayerId}[${o}]`), n = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, p = e.tier, c = p === "priority" ? this._extractNormalisedProperties(t, e) : void 0;
|
|
1825
1872
|
return {
|
|
1826
1873
|
id: t.id ?? `${e.sourceLayerId}/${o}`,
|
|
1827
1874
|
preferredColor: e.preferredColor,
|
|
@@ -1842,10 +1889,10 @@ class ot {
|
|
|
1842
1889
|
};
|
|
1843
1890
|
}
|
|
1844
1891
|
_extractNormalisedProperties(t, e) {
|
|
1845
|
-
return e.category === "building" ?
|
|
1892
|
+
return e.category === "building" ? Qo(t.properties, this.sourceId) : e.category === "greenspace" ? Zo(t.properties) : e.category === "paved" ? Jo(t.properties) : e.category === "zone" ? tr(t.properties) : Yo(t.properties, this.sourceId);
|
|
1846
1893
|
}
|
|
1847
1894
|
}
|
|
1848
|
-
const
|
|
1895
|
+
const ye = [8, 54.5, 15.2, 57.8], be = {
|
|
1849
1896
|
building: [
|
|
1850
1897
|
{ source: "danish-matrikel", typename: "bbr_v001:bygning_current" }
|
|
1851
1898
|
],
|
|
@@ -1854,7 +1901,7 @@ const ge = [8, 54.5, 15.2, 57.8], ue = {
|
|
|
1854
1901
|
{ source: "danish-matrikel", typename: "mat_v001:samletfastejendom_current" }
|
|
1855
1902
|
]
|
|
1856
1903
|
};
|
|
1857
|
-
function
|
|
1904
|
+
function or(i) {
|
|
1858
1905
|
if (!i) return [0, 0];
|
|
1859
1906
|
const t = i.coordinates;
|
|
1860
1907
|
switch (i.type) {
|
|
@@ -1872,7 +1919,7 @@ function Vo(i) {
|
|
|
1872
1919
|
return [0, 0];
|
|
1873
1920
|
}
|
|
1874
1921
|
}
|
|
1875
|
-
function
|
|
1922
|
+
function rr(i, t) {
|
|
1876
1923
|
if (!i) return t;
|
|
1877
1924
|
for (const e of [
|
|
1878
1925
|
"mat:matrikelnummer",
|
|
@@ -1888,14 +1935,14 @@ function Ko(i, t) {
|
|
|
1888
1935
|
if (typeof i[e] == "string" && i[e]) return i[e];
|
|
1889
1936
|
return t;
|
|
1890
1937
|
}
|
|
1891
|
-
function
|
|
1938
|
+
function sr(i, t, e) {
|
|
1892
1939
|
return `${i}:${t}:${e}`;
|
|
1893
1940
|
}
|
|
1894
|
-
const
|
|
1941
|
+
const ar = /* @__PURE__ */ new Set(["building", "cadastre", "zone"]);
|
|
1895
1942
|
function rt(i, t, e) {
|
|
1896
|
-
const o = e.typename.replace(/^[^:]+:/, ""), r = T(t), s =
|
|
1943
|
+
const o = e.typename.replace(/^[^:]+:/, ""), r = T(t), s = ar.has(t) ? "priority" : "raw";
|
|
1897
1944
|
return {
|
|
1898
|
-
id:
|
|
1945
|
+
id: sr(i, e.source, e.typename),
|
|
1899
1946
|
sourceId: i,
|
|
1900
1947
|
sourceLayerId: e.typename,
|
|
1901
1948
|
category: t,
|
|
@@ -1907,7 +1954,7 @@ function rt(i, t, e) {
|
|
|
1907
1954
|
descriptionKey: `gis.layer.${i}.${e.source}.${o}.description`
|
|
1908
1955
|
};
|
|
1909
1956
|
}
|
|
1910
|
-
function
|
|
1957
|
+
function ir(i, t) {
|
|
1911
1958
|
if (t === "building") {
|
|
1912
1959
|
const a = i?.byg041BebyggetAreal ?? i?.byg038SamletBygningsareal, n = i?.byg021BygningensAnvendelse, p = i?.id_lokalId, c = i?.byg026Opførelsesår;
|
|
1913
1960
|
return {
|
|
@@ -1924,8 +1971,8 @@ function Yo(i, t) {
|
|
|
1924
1971
|
featureType: "zone",
|
|
1925
1972
|
zoneType: a ?? void 0,
|
|
1926
1973
|
zoneCode: p ?? void 0,
|
|
1927
|
-
legalStatus:
|
|
1928
|
-
planType:
|
|
1974
|
+
legalStatus: we(c),
|
|
1975
|
+
planType: fe(i?.typ_gde_bezeichnung),
|
|
1929
1976
|
planId: n ?? void 0,
|
|
1930
1977
|
planDocumentLink: h ?? void 0,
|
|
1931
1978
|
publicationDate: i?.auflagedatum ?? void 0,
|
|
@@ -1943,13 +1990,13 @@ function Yo(i, t) {
|
|
|
1943
1990
|
registryId: s ?? void 0
|
|
1944
1991
|
};
|
|
1945
1992
|
}
|
|
1946
|
-
class
|
|
1993
|
+
class nr {
|
|
1947
1994
|
categoryMap;
|
|
1948
1995
|
dataViewsBaseUrl;
|
|
1949
1996
|
getHeaders;
|
|
1950
1997
|
sourceId;
|
|
1951
1998
|
constructor(t) {
|
|
1952
|
-
this.dataViewsBaseUrl = t.dataViewsBaseUrl.replace(/\/$/, ""), this.getHeaders = t.getHeaders, this.categoryMap = t.categoryMap ??
|
|
1999
|
+
this.dataViewsBaseUrl = t.dataViewsBaseUrl.replace(/\/$/, ""), this.getHeaders = t.getHeaders, this.categoryMap = t.categoryMap ?? be, this.sourceId = t.sourceId ?? "cue-sdk-gis";
|
|
1953
2000
|
}
|
|
1954
2001
|
async listFeatureCategoryDescriptors(t) {
|
|
1955
2002
|
const e = await this.listAvailableLayers(t);
|
|
@@ -2012,7 +2059,7 @@ class Zo {
|
|
|
2012
2059
|
return d.json();
|
|
2013
2060
|
}
|
|
2014
2061
|
_toGisFeature(t, e, o) {
|
|
2015
|
-
const [r, s] =
|
|
2062
|
+
const [r, s] = or(t.geometry), a = t.id ?? `${e.sourceLayerId}/${o}`, n = rr(t.properties, a), p = t.bbox ? [t.bbox[0], t.bbox[1], t.bbox[2], t.bbox[3]] : void 0, c = e.tier, h = c === "priority" ? ir(t.properties, e.category) : void 0;
|
|
2016
2063
|
return {
|
|
2017
2064
|
id: a,
|
|
2018
2065
|
sourceId: this.sourceId,
|
|
@@ -2033,7 +2080,7 @@ class Zo {
|
|
|
2033
2080
|
};
|
|
2034
2081
|
}
|
|
2035
2082
|
}
|
|
2036
|
-
const
|
|
2083
|
+
const pr = {
|
|
2037
2084
|
address: [
|
|
2038
2085
|
"ms:ogd-0406_arv_basis_avzh_hausnummer_pos_p",
|
|
2039
2086
|
"ms:ogd-0571_afv_gv_strat_strassennetz_l"
|
|
@@ -2081,19 +2128,19 @@ const Jo = {
|
|
|
2081
2128
|
// ÖREB Überlagernde Festlegungen (Flächen) – overlaying planning constraints
|
|
2082
2129
|
"ms:ogd-0155_arv_basis_np_ul_flaeche_f"
|
|
2083
2130
|
]
|
|
2084
|
-
},
|
|
2131
|
+
}, ve = [
|
|
2085
2132
|
{
|
|
2086
2133
|
name: "Canton of Zürich",
|
|
2087
|
-
coverageBBox:
|
|
2134
|
+
coverageBBox: Go,
|
|
2088
2135
|
supportedCategories: ["address", "poi", "railway", "natural", "manmade", "building", "cadastre", "greenspace", "paved", "zone"],
|
|
2089
2136
|
priority: 10,
|
|
2090
2137
|
adapter: new ot({
|
|
2091
|
-
categoryMap:
|
|
2138
|
+
categoryMap: pr
|
|
2092
2139
|
})
|
|
2093
2140
|
},
|
|
2094
2141
|
{
|
|
2095
2142
|
name: "Switzerland (national AV cadastre)",
|
|
2096
|
-
coverageBBox:
|
|
2143
|
+
coverageBBox: Ho,
|
|
2097
2144
|
supportedCategories: ["cadastre"],
|
|
2098
2145
|
priority: 5,
|
|
2099
2146
|
// Lower priority than canton-specific adapters. For ZH, the canton adapter (priority 10) wins.
|
|
@@ -2121,7 +2168,7 @@ const Jo = {
|
|
|
2121
2168
|
* - `pdk:kommuneplanramme_vedtaget` – adopted municipal plan frameworks
|
|
2122
2169
|
*/
|
|
2123
2170
|
name: "Denmark (Plandata.dk – planning zones)",
|
|
2124
|
-
coverageBBox:
|
|
2171
|
+
coverageBBox: ye,
|
|
2125
2172
|
supportedCategories: ["zone"],
|
|
2126
2173
|
priority: 10,
|
|
2127
2174
|
adapter: new ot({
|
|
@@ -2139,12 +2186,12 @@ const Jo = {
|
|
|
2139
2186
|
})
|
|
2140
2187
|
}
|
|
2141
2188
|
];
|
|
2142
|
-
function
|
|
2189
|
+
function Gt(i) {
|
|
2143
2190
|
return [...i].sort(
|
|
2144
2191
|
(t, e) => pt.indexOf(t.category) - pt.indexOf(e.category)
|
|
2145
2192
|
);
|
|
2146
2193
|
}
|
|
2147
|
-
class
|
|
2194
|
+
class cr {
|
|
2148
2195
|
nominatim;
|
|
2149
2196
|
regions;
|
|
2150
2197
|
/**
|
|
@@ -2159,9 +2206,9 @@ class tr {
|
|
|
2159
2206
|
zonePlanTypeColors: r,
|
|
2160
2207
|
...s
|
|
2161
2208
|
} = t;
|
|
2162
|
-
this.nominatim = new
|
|
2163
|
-
const a = o ?
|
|
2164
|
-
this.regions = e ?? a, this.zonePlanTypeColors = { ...
|
|
2209
|
+
this.nominatim = new qo(s);
|
|
2210
|
+
const a = o ? ve : [];
|
|
2211
|
+
this.regions = e ?? a, this.zonePlanTypeColors = { ...Ao, ...r };
|
|
2165
2212
|
}
|
|
2166
2213
|
/**
|
|
2167
2214
|
* Return the available feature categories together with UI metadata such as
|
|
@@ -2180,12 +2227,12 @@ class tr {
|
|
|
2180
2227
|
for (const a of e)
|
|
2181
2228
|
for (const n of a.supportedCategories ?? [])
|
|
2182
2229
|
r.has(n) || (r.add(n), s.push(T(n)));
|
|
2183
|
-
for (const a of
|
|
2230
|
+
for (const a of ue)
|
|
2184
2231
|
r.has(a) || s.push(T(a));
|
|
2185
|
-
return
|
|
2232
|
+
return Gt(s);
|
|
2186
2233
|
}
|
|
2187
2234
|
const o = await this._adapterFor(t).listFeatureCategoryDescriptors(t);
|
|
2188
|
-
return
|
|
2235
|
+
return Gt(o);
|
|
2189
2236
|
}
|
|
2190
2237
|
/**
|
|
2191
2238
|
* Return the feature categories that have at least one result within the
|
|
@@ -2258,7 +2305,7 @@ class tr {
|
|
|
2258
2305
|
const { features: n, idx: p } = await Promise.race(a.values());
|
|
2259
2306
|
a.delete(p);
|
|
2260
2307
|
for (const c of n) {
|
|
2261
|
-
const h =
|
|
2308
|
+
const h = Ht(c), d = W(c), g = s.get(h);
|
|
2262
2309
|
(g === void 0 || d > g) && (s.set(h, d), yield c);
|
|
2263
2310
|
}
|
|
2264
2311
|
}
|
|
@@ -2292,9 +2339,9 @@ class tr {
|
|
|
2292
2339
|
), a = [], n = [];
|
|
2293
2340
|
for (const d of s)
|
|
2294
2341
|
d.status === "fulfilled" && (d.value.isNominatim ? n.push(...d.value.features) : a.push(...d.value.features));
|
|
2295
|
-
const p =
|
|
2342
|
+
const p = dr(a, n), c = /* @__PURE__ */ new Map(), h = [];
|
|
2296
2343
|
for (const d of p) {
|
|
2297
|
-
const g =
|
|
2344
|
+
const g = Ht(d), u = W(d), m = c.get(g);
|
|
2298
2345
|
(m === void 0 || u > m) && (c.set(g, u), h.push(d));
|
|
2299
2346
|
}
|
|
2300
2347
|
return h;
|
|
@@ -2312,22 +2359,22 @@ function W(i) {
|
|
|
2312
2359
|
const t = i.geometry?.type;
|
|
2313
2360
|
return t === "Polygon" || t === "MultiPolygon" ? 3 : t === "LineString" || t === "MultiLineString" ? 2 : 1;
|
|
2314
2361
|
}
|
|
2315
|
-
function
|
|
2362
|
+
function Ht(i) {
|
|
2316
2363
|
const t = Math.round(i.lat * 1e3) / 1e3, e = Math.round(i.lon * 1e3) / 1e3;
|
|
2317
2364
|
return `${(i.name ?? i.id ?? "").toLowerCase().trim()}|${t}|${e}`;
|
|
2318
2365
|
}
|
|
2319
|
-
const
|
|
2320
|
-
function
|
|
2366
|
+
const lr = 1e-3;
|
|
2367
|
+
function hr(i, t) {
|
|
2321
2368
|
const e = i.lat - t.lat, o = i.lon - t.lon;
|
|
2322
2369
|
return Math.sqrt(e * e + o * o);
|
|
2323
2370
|
}
|
|
2324
|
-
function
|
|
2371
|
+
function dr(i, t) {
|
|
2325
2372
|
if (t.length === 0) return i;
|
|
2326
2373
|
const e = i.filter((a) => W(a) === 3), o = i.filter((a) => W(a) !== 3), r = e.map((a) => ({ feature: { ...a, originalData: { ...a.originalData } }, matched: !1 })), s = [];
|
|
2327
2374
|
for (const a of t) {
|
|
2328
|
-
let n = -1, p =
|
|
2375
|
+
let n = -1, p = lr;
|
|
2329
2376
|
for (let c = 0; c < r.length; c++) {
|
|
2330
|
-
const h =
|
|
2377
|
+
const h = hr(a, r[c].feature);
|
|
2331
2378
|
h < p && (p = h, n = c);
|
|
2332
2379
|
}
|
|
2333
2380
|
n >= 0 ? (r[n].feature.originalData = {
|
|
@@ -2341,8 +2388,8 @@ function rr(i, t) {
|
|
|
2341
2388
|
...s
|
|
2342
2389
|
];
|
|
2343
2390
|
}
|
|
2344
|
-
const
|
|
2345
|
-
class
|
|
2391
|
+
const gr = "/data-views", ur = 1500;
|
|
2392
|
+
class mr {
|
|
2346
2393
|
// undefined = not yet built
|
|
2347
2394
|
/** @internal — construct via `cue.gis`, not directly. */
|
|
2348
2395
|
constructor(t, e) {
|
|
@@ -2425,25 +2472,25 @@ class ir {
|
|
|
2425
2472
|
}
|
|
2426
2473
|
// ── Private ───────────────────────────────────────────────────────────────
|
|
2427
2474
|
_scheduleDebouncedQuery() {
|
|
2428
|
-
this._debounceTimer !== null && clearTimeout(this._debounceTimer), this._debounceTimer = setTimeout(() => this._queryLayers(),
|
|
2475
|
+
this._debounceTimer !== null && clearTimeout(this._debounceTimer), this._debounceTimer = setTimeout(() => this._queryLayers(), ur);
|
|
2429
2476
|
}
|
|
2430
2477
|
_getGateway() {
|
|
2431
2478
|
if (this._gatewayCache !== null && this._gatewayProjectId === this._projectId)
|
|
2432
2479
|
return this._gatewayCache;
|
|
2433
|
-
const t = this._projectId, e = [...
|
|
2480
|
+
const t = this._projectId, e = [...ve];
|
|
2434
2481
|
return t && e.unshift({
|
|
2435
2482
|
name: "Cue SDK (authenticated)",
|
|
2436
|
-
coverageBBox:
|
|
2437
|
-
supportedCategories: Object.keys(
|
|
2483
|
+
coverageBBox: ye,
|
|
2484
|
+
supportedCategories: Object.keys(be),
|
|
2438
2485
|
priority: 10,
|
|
2439
|
-
adapter: new
|
|
2440
|
-
dataViewsBaseUrl: `${this._gatewayUrl}${
|
|
2486
|
+
adapter: new nr({
|
|
2487
|
+
dataViewsBaseUrl: `${this._gatewayUrl}${gr}`,
|
|
2441
2488
|
getHeaders: async () => ({
|
|
2442
2489
|
...await this._getAuthHeaders(),
|
|
2443
2490
|
"x-project-id": t
|
|
2444
2491
|
})
|
|
2445
2492
|
})
|
|
2446
|
-
}), this._gatewayCache = new
|
|
2493
|
+
}), this._gatewayCache = new cr({ regions: e }), this._gatewayProjectId = t, this._gatewayCache;
|
|
2447
2494
|
}
|
|
2448
2495
|
async _queryLayers() {
|
|
2449
2496
|
const t = this._bbox;
|
|
@@ -2487,11 +2534,11 @@ class ir {
|
|
|
2487
2534
|
this._loadListeners.forEach((e) => e(t));
|
|
2488
2535
|
}
|
|
2489
2536
|
}
|
|
2490
|
-
class
|
|
2537
|
+
class Wt {
|
|
2491
2538
|
constructor(t, e, o = !1, r) {
|
|
2492
|
-
if (this._auth = t, this._db =
|
|
2539
|
+
if (this._auth = t, this._db = Ae(e), this._functions = pe(e, le), this._gatewayUrl = r?.gatewayUrl ?? "", o) {
|
|
2493
2540
|
const s = r?.firestoreEmulatorHost ?? "localhost", a = r?.firestoreEmulatorPort ?? 8080;
|
|
2494
|
-
|
|
2541
|
+
Pe(this._db, s, a), ce(this._functions, "localhost", 5001);
|
|
2495
2542
|
}
|
|
2496
2543
|
}
|
|
2497
2544
|
_auth;
|
|
@@ -2508,7 +2555,7 @@ class Ht {
|
|
|
2508
2555
|
* Throws if a project with the given ID already exists.
|
|
2509
2556
|
*/
|
|
2510
2557
|
async createProject(t) {
|
|
2511
|
-
const e = await this._auth.authenticatedFetch(`${this._gatewayUrl}${
|
|
2558
|
+
const e = await this._auth.authenticatedFetch(`${this._gatewayUrl}${go}`, {
|
|
2512
2559
|
method: "POST",
|
|
2513
2560
|
headers: { "Content-Type": "application/json" },
|
|
2514
2561
|
body: JSON.stringify(t)
|
|
@@ -2524,12 +2571,12 @@ class Ht {
|
|
|
2524
2571
|
* Access is gated by Firestore rules which check membership.
|
|
2525
2572
|
*/
|
|
2526
2573
|
async listProjects() {
|
|
2527
|
-
const t = this._requireUser(), e = yt(this._db,
|
|
2528
|
-
return (await
|
|
2574
|
+
const t = this._requireUser(), e = yt(this._db, Ct);
|
|
2575
|
+
return (await Oe(De(e, Le("members", "array-contains", t), qe(100)))).docs.map((r) => r.data());
|
|
2529
2576
|
}
|
|
2530
2577
|
/** Fetch a single project by ID. Returns null if not found. */
|
|
2531
2578
|
async getProject(t) {
|
|
2532
|
-
const e = bt(yt(this._db,
|
|
2579
|
+
const e = bt(yt(this._db, Ct), t), o = await je(e);
|
|
2533
2580
|
return o.exists() ? o.data() : null;
|
|
2534
2581
|
}
|
|
2535
2582
|
/**
|
|
@@ -2539,9 +2586,9 @@ class Ht {
|
|
|
2539
2586
|
async incrementUnitsConsumed(t, e, o) {
|
|
2540
2587
|
if (e <= 0) return;
|
|
2541
2588
|
const r = bt(this._db, "clientSync", t);
|
|
2542
|
-
await
|
|
2543
|
-
unitsConsumed:
|
|
2544
|
-
lastUpdated:
|
|
2589
|
+
await ze(r, {
|
|
2590
|
+
unitsConsumed: Ue(e),
|
|
2591
|
+
lastUpdated: $e(),
|
|
2545
2592
|
lastUserId: o
|
|
2546
2593
|
}, { merge: !0 });
|
|
2547
2594
|
}
|
|
@@ -2564,7 +2611,7 @@ class Ht {
|
|
|
2564
2611
|
*/
|
|
2565
2612
|
async deleteProject(t) {
|
|
2566
2613
|
const e = await this._auth.authenticatedFetch(
|
|
2567
|
-
`${this._gatewayUrl}${
|
|
2614
|
+
`${this._gatewayUrl}${uo(t)}`,
|
|
2568
2615
|
{ method: "DELETE" }
|
|
2569
2616
|
);
|
|
2570
2617
|
if (!e.ok) {
|
|
@@ -2573,9 +2620,9 @@ class Ht {
|
|
|
2573
2620
|
}
|
|
2574
2621
|
}
|
|
2575
2622
|
}
|
|
2576
|
-
class
|
|
2623
|
+
class Vt {
|
|
2577
2624
|
constructor(t, e, o, r) {
|
|
2578
|
-
this._auth = t, this._gatewayUrl = r, this._functions =
|
|
2625
|
+
this._auth = t, this._gatewayUrl = r, this._functions = pe(e, le), o && ce(this._functions, "localhost", 5001);
|
|
2579
2626
|
}
|
|
2580
2627
|
_auth;
|
|
2581
2628
|
_gatewayUrl;
|
|
@@ -2592,13 +2639,13 @@ class Wt {
|
|
|
2592
2639
|
}
|
|
2593
2640
|
/** Whether the current user has an active API key. */
|
|
2594
2641
|
async hasAPIKey() {
|
|
2595
|
-
return await this._fetch(
|
|
2642
|
+
return await this._fetch(Dt) !== null;
|
|
2596
2643
|
}
|
|
2597
2644
|
/** Returns the sign-in methods registered for the current user's email. */
|
|
2598
2645
|
async getSignInMethods() {
|
|
2599
2646
|
const t = this._auth.currentUser;
|
|
2600
2647
|
if (!t?.email) throw new Error("User has no e-mail");
|
|
2601
|
-
return
|
|
2648
|
+
return Ke(this._auth.firebaseAuth, t.email);
|
|
2602
2649
|
}
|
|
2603
2650
|
/** Builds a human-readable label from a Firebase UserInfo provider entry. */
|
|
2604
2651
|
buildProviderLabel(t) {
|
|
@@ -2611,14 +2658,14 @@ class Wt {
|
|
|
2611
2658
|
}
|
|
2612
2659
|
/** Links a Google or Microsoft provider to the current account via popup. Returns the new provider label. */
|
|
2613
2660
|
async linkProvider(t) {
|
|
2614
|
-
const e = this._requireUser(), o = t === "google.com" ? new it() : new nt(t), s = (await
|
|
2661
|
+
const e = this._requireUser(), o = t === "google.com" ? new it() : new nt(t), s = (await Qe(e, o)).user.providerData.find(
|
|
2615
2662
|
(a) => a.providerId === t
|
|
2616
2663
|
);
|
|
2617
2664
|
return s ? this.buildProviderLabel(s) : "-";
|
|
2618
2665
|
}
|
|
2619
2666
|
/** Unlinks a provider from the current account. */
|
|
2620
2667
|
async unlinkProvider(t) {
|
|
2621
|
-
await
|
|
2668
|
+
await Ye(this._requireUser(), t);
|
|
2622
2669
|
}
|
|
2623
2670
|
/** Changes the password. Reauthenticates first. */
|
|
2624
2671
|
async updatePassword(t, e) {
|
|
@@ -2627,13 +2674,13 @@ class Wt {
|
|
|
2627
2674
|
await _t(
|
|
2628
2675
|
o,
|
|
2629
2676
|
Q.credential(o.email, t)
|
|
2630
|
-
), await
|
|
2677
|
+
), await Ze(o, e);
|
|
2631
2678
|
}
|
|
2632
2679
|
/** Adds (sets) a password for an account that currently only uses SSO. */
|
|
2633
2680
|
async addPassword(t) {
|
|
2634
2681
|
const e = this._requireUser();
|
|
2635
2682
|
if (!e.email) throw new Error("User has no e-mail");
|
|
2636
|
-
await
|
|
2683
|
+
await Je(e, Q.credential(e.email, t));
|
|
2637
2684
|
}
|
|
2638
2685
|
/** Requests an e-mail change. Sends a verification e-mail to the new address. */
|
|
2639
2686
|
async updateEmail(t, e) {
|
|
@@ -2642,11 +2689,11 @@ class Wt {
|
|
|
2642
2689
|
await _t(
|
|
2643
2690
|
o,
|
|
2644
2691
|
Q.credential(o.email, e)
|
|
2645
|
-
), await
|
|
2692
|
+
), await to(o, t), await eo(o);
|
|
2646
2693
|
}
|
|
2647
2694
|
/** Creates a new API key for the current user. */
|
|
2648
2695
|
async createAPIKey(t) {
|
|
2649
|
-
return this._fetch(
|
|
2696
|
+
return this._fetch(Lt, {
|
|
2650
2697
|
method: "POST",
|
|
2651
2698
|
headers: { "Content-Type": "application/json" },
|
|
2652
2699
|
body: JSON.stringify({ expiration: t })
|
|
@@ -2655,7 +2702,7 @@ class Wt {
|
|
|
2655
2702
|
/** Revokes the current user's API key. */
|
|
2656
2703
|
async revokeAPIKey() {
|
|
2657
2704
|
const t = await this._auth.authenticatedFetch(
|
|
2658
|
-
this._url(
|
|
2705
|
+
this._url(Lt),
|
|
2659
2706
|
{ method: "DELETE" }
|
|
2660
2707
|
);
|
|
2661
2708
|
if (!t.ok)
|
|
@@ -2663,17 +2710,17 @@ class Wt {
|
|
|
2663
2710
|
}
|
|
2664
2711
|
/** Fetches the current user's existing API key. */
|
|
2665
2712
|
async requestAPIKey() {
|
|
2666
|
-
const t = await this._fetch(
|
|
2713
|
+
const t = await this._fetch(Dt);
|
|
2667
2714
|
if (!t) throw new Error("No API key found");
|
|
2668
2715
|
return t;
|
|
2669
2716
|
}
|
|
2670
2717
|
/** Returns organizations the current user is a member of. */
|
|
2671
2718
|
async listOrganizations() {
|
|
2672
|
-
return this._fetch(
|
|
2719
|
+
return this._fetch(co);
|
|
2673
2720
|
}
|
|
2674
2721
|
/** Returns all members of the given organisation. Caller must be an org admin or superadmin. */
|
|
2675
2722
|
async getOrgMembers(t) {
|
|
2676
|
-
return this._fetch(
|
|
2723
|
+
return this._fetch(ho(t));
|
|
2677
2724
|
}
|
|
2678
2725
|
_requireUser() {
|
|
2679
2726
|
const t = this._auth.currentUser;
|
|
@@ -2689,7 +2736,7 @@ class Wt {
|
|
|
2689
2736
|
}
|
|
2690
2737
|
/** Record that the current user has accepted the terms of service. Sets a `terms` custom claim on the token. */
|
|
2691
2738
|
async acceptTerms(t) {
|
|
2692
|
-
await this._fetch(
|
|
2739
|
+
await this._fetch(lo, {
|
|
2693
2740
|
method: "POST",
|
|
2694
2741
|
headers: { "Content-Type": "application/json" },
|
|
2695
2742
|
body: JSON.stringify({ version: t })
|
|
@@ -2706,7 +2753,7 @@ class Wt {
|
|
|
2706
2753
|
return t ? (await at(t)).claims.terms ?? null : null;
|
|
2707
2754
|
}
|
|
2708
2755
|
}
|
|
2709
|
-
const
|
|
2756
|
+
const Xt = ["superadmin", "admin", "syncer", "member"], Kt = {
|
|
2710
2757
|
createEntities: "admin",
|
|
2711
2758
|
createProvider: "superadmin",
|
|
2712
2759
|
changeContentCategories: "syncer",
|
|
@@ -2722,7 +2769,7 @@ const Vt = ["superadmin", "admin", "syncer", "member"], Kt = {
|
|
|
2722
2769
|
uploadDocuments: "syncer",
|
|
2723
2770
|
viewEntities: "member"
|
|
2724
2771
|
};
|
|
2725
|
-
function
|
|
2772
|
+
function wr() {
|
|
2726
2773
|
return {
|
|
2727
2774
|
changeContentCategories: !1,
|
|
2728
2775
|
createEntities: !1,
|
|
@@ -2741,9 +2788,9 @@ function nr() {
|
|
|
2741
2788
|
viewEntities: !1
|
|
2742
2789
|
};
|
|
2743
2790
|
}
|
|
2744
|
-
class
|
|
2791
|
+
class Qt {
|
|
2745
2792
|
constructor(t) {
|
|
2746
|
-
this._isSuperAdmin = t, this._projectRoles = new
|
|
2793
|
+
this._isSuperAdmin = t, this._projectRoles = new x([]), this._orgRole = new x(null), this.privileges = dt(
|
|
2747
2794
|
[this._projectRoles, this._orgRole, t],
|
|
2748
2795
|
() => this._compute()
|
|
2749
2796
|
);
|
|
@@ -2780,17 +2827,17 @@ class Xt {
|
|
|
2780
2827
|
_expand(t) {
|
|
2781
2828
|
if (this._isSuperAdmin.get())
|
|
2782
2829
|
return ["superadmin", "admin", "syncer", "member"];
|
|
2783
|
-
const e =
|
|
2784
|
-
return e === -1 ? [] : Array.from(
|
|
2830
|
+
const e = Xt.findIndex((o) => t.includes(o));
|
|
2831
|
+
return e === -1 ? [] : Array.from(Xt.slice(e));
|
|
2785
2832
|
}
|
|
2786
2833
|
_compute() {
|
|
2787
|
-
const t = this._projectRoles.get(), e = this._isSuperAdmin.get(), o =
|
|
2834
|
+
const t = this._projectRoles.get(), e = this._isSuperAdmin.get(), o = wr();
|
|
2788
2835
|
for (const r of Object.keys(Kt))
|
|
2789
2836
|
o[r] = t.includes(Kt[r]);
|
|
2790
2837
|
return o.createProject = e || this._orgRole.get() === "admin", o;
|
|
2791
2838
|
}
|
|
2792
2839
|
}
|
|
2793
|
-
class
|
|
2840
|
+
class Yt {
|
|
2794
2841
|
constructor(t) {
|
|
2795
2842
|
this._storage = t;
|
|
2796
2843
|
}
|
|
@@ -2823,7 +2870,7 @@ class Qt {
|
|
|
2823
2870
|
// ── Internal helpers ───────────────────────────────────────────────────────
|
|
2824
2871
|
async _get(t, e) {
|
|
2825
2872
|
try {
|
|
2826
|
-
const r = await (await
|
|
2873
|
+
const r = await (await ne(k(this._storage, `${t}/${e}.json.gz`))).arrayBuffer(), s = new DecompressionStream("gzip"), a = s.writable.getWriter(), n = s.readable.getReader();
|
|
2827
2874
|
a.write(new Uint8Array(r)), a.close();
|
|
2828
2875
|
const p = [];
|
|
2829
2876
|
let c = await n.read();
|
|
@@ -2835,7 +2882,7 @@ class Qt {
|
|
|
2835
2882
|
d.set(u, g), g += u.length;
|
|
2836
2883
|
return JSON.parse(new TextDecoder().decode(d));
|
|
2837
2884
|
} catch (o) {
|
|
2838
|
-
if (
|
|
2885
|
+
if (fr(o)) return;
|
|
2839
2886
|
throw o;
|
|
2840
2887
|
}
|
|
2841
2888
|
}
|
|
@@ -2851,13 +2898,13 @@ class Qt {
|
|
|
2851
2898
|
for (const u of p)
|
|
2852
2899
|
d.set(u, g), g += u.length;
|
|
2853
2900
|
await st(
|
|
2854
|
-
|
|
2901
|
+
k(this._storage, `${t}/${e}.json.gz`),
|
|
2855
2902
|
d,
|
|
2856
2903
|
{ contentType: "application/gzip" }
|
|
2857
2904
|
);
|
|
2858
2905
|
}
|
|
2859
2906
|
}
|
|
2860
|
-
function
|
|
2907
|
+
function fr(i) {
|
|
2861
2908
|
return typeof i == "object" && i !== null && "code" in i && i.code === "storage/object-not-found";
|
|
2862
2909
|
}
|
|
2863
2910
|
const y = {
|
|
@@ -2880,7 +2927,7 @@ const y = {
|
|
|
2880
2927
|
dicu: "https://w3id.org/digitalconstruction/0.5/Units#",
|
|
2881
2928
|
diclvl: "https://w3id.org/digitalconstruction/0.5/Levels#",
|
|
2882
2929
|
dicstg: "https://w3id.org/digitalconstruction/0.5/Stages#"
|
|
2883
|
-
},
|
|
2930
|
+
}, R = {
|
|
2884
2931
|
madsrdf: "http://www.loc.gov/mads/rdf/v1#",
|
|
2885
2932
|
bflc: "http://id.loc.gov/ontologies/bflc/",
|
|
2886
2933
|
foaf: "http://xmlns.com/foaf/0.1/",
|
|
@@ -6129,28 +6176,42 @@ class V {
|
|
|
6129
6176
|
return r === void 0 ? t : t.replace(o, `${r}:`);
|
|
6130
6177
|
}
|
|
6131
6178
|
expandIRI(t) {
|
|
6132
|
-
const e = t.split(":")[0], o =
|
|
6179
|
+
const e = t.split(":")[0], o = R[e] ?? y[e];
|
|
6133
6180
|
return t.replace(`${e}:`, o);
|
|
6134
6181
|
}
|
|
6135
6182
|
_buildNSMap() {
|
|
6136
6183
|
const t = {};
|
|
6137
|
-
return Object.keys(
|
|
6184
|
+
return Object.keys(R).forEach((e) => t[R[e]] = e), Object.keys(y).forEach(
|
|
6138
6185
|
(e) => t[y[e]] = e
|
|
6139
6186
|
), this._nsMap = t, t;
|
|
6140
6187
|
}
|
|
6141
6188
|
}
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
|
|
6145
|
-
|
|
6189
|
+
const yr = `${y.qcy}ContentCategory`, br = `${y.qcy}EntityCategory`, vr = `${y.qcy}relatedEntity`, _r = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
|
|
6190
|
+
SELECT ?iri ?type ?parent ?deprecated ?label ?definition
|
|
6191
|
+
WHERE {
|
|
6192
|
+
SERVICE view:schemas {
|
|
6193
|
+
_:cfg view:column-iri ?iri ;
|
|
6194
|
+
view:column-type ?type ;
|
|
6195
|
+
view:column-parent ?parent ;
|
|
6196
|
+
view:column-deprecated ?deprecated ;
|
|
6197
|
+
view:column-label ?label ;
|
|
6198
|
+
view:column-definition ?definition .
|
|
6199
|
+
}
|
|
6200
|
+
}`;
|
|
6201
|
+
class Er {
|
|
6202
|
+
constructor(t, e, o, r, s, a) {
|
|
6203
|
+
this._api = t, this._projectId = e, this._queryCache = r, this._graphType = s, this._verbose = a ?? !1, this._currentLang = o, this._api.setLanguage(o), this._contentCategories = new x([]), this._entityCategories = new x([]), this._relationships = new x([]), this.availableContentCategories = this._contentCategories.asReadonly(), this.availableEntityCategories = this._entityCategories.asReadonly(), this.availableEntityRelationships = this._relationships.asReadonly(), this.ready = this._load().catch(
|
|
6204
|
+
(n) => console.error("[CueProjectSchema] Initial load failed:", n)
|
|
6146
6205
|
);
|
|
6147
6206
|
}
|
|
6148
6207
|
_api;
|
|
6149
6208
|
_projectId;
|
|
6150
6209
|
_queryCache;
|
|
6151
6210
|
_graphType;
|
|
6152
|
-
|
|
6211
|
+
_snapshot;
|
|
6212
|
+
_inflight;
|
|
6153
6213
|
_currentLang;
|
|
6214
|
+
_verbose;
|
|
6154
6215
|
_contentCategories;
|
|
6155
6216
|
_entityCategories;
|
|
6156
6217
|
_relationships;
|
|
@@ -6170,106 +6231,166 @@ class lr {
|
|
|
6170
6231
|
return this._api.language;
|
|
6171
6232
|
}
|
|
6172
6233
|
/**
|
|
6173
|
-
* Switch the active language.
|
|
6174
|
-
*
|
|
6175
|
-
*
|
|
6234
|
+
* Switch the active language. Re-projects the already-fetched schema for the
|
|
6235
|
+
* new language without re-querying; only triggers a fetch if nothing has been
|
|
6236
|
+
* loaded yet.
|
|
6176
6237
|
*/
|
|
6177
6238
|
setLanguage(t) {
|
|
6178
|
-
|
|
6179
|
-
(
|
|
6180
|
-
|
|
6239
|
+
if (this._currentLang !== t) {
|
|
6240
|
+
if (this._currentLang = t, this._api.setLanguage(t), this._snapshot) {
|
|
6241
|
+
this._apply(this._snapshot);
|
|
6242
|
+
return;
|
|
6243
|
+
}
|
|
6244
|
+
this._load().catch(
|
|
6245
|
+
(e) => console.error("[CueProjectSchema] Language switch failed:", e)
|
|
6246
|
+
);
|
|
6247
|
+
}
|
|
6181
6248
|
}
|
|
6182
6249
|
/**
|
|
6183
|
-
* Force a re-fetch
|
|
6250
|
+
* Force a re-fetch of the schema, bypassing the cache.
|
|
6184
6251
|
* Useful when the triplestore data has changed.
|
|
6185
6252
|
*/
|
|
6186
6253
|
async refresh() {
|
|
6187
|
-
|
|
6188
|
-
this._cache.delete(t), await this._load(t);
|
|
6254
|
+
this._snapshot = void 0, await this._load();
|
|
6189
6255
|
}
|
|
6190
6256
|
// ── Private helpers ─────────────────────────────────────────────────────────
|
|
6191
|
-
async _load(
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
this._apply(e);
|
|
6257
|
+
async _load() {
|
|
6258
|
+
if (this._snapshot) {
|
|
6259
|
+
this._apply(this._snapshot);
|
|
6195
6260
|
return;
|
|
6196
6261
|
}
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
(a) => {
|
|
6209
|
-
this._cache.set(t, a), this._currentLang === t && this._apply(a);
|
|
6262
|
+
if (this._inflight) return this._inflight;
|
|
6263
|
+
this._verbose && console.log(
|
|
6264
|
+
`[CueProjectSchema] Fetching schema — project: ${this._projectId}, graphType: ${this._graphType ?? "default"}`
|
|
6265
|
+
);
|
|
6266
|
+
const t = `cue-schema:${this._projectId}:${this._graphType ?? "default"}`, e = gt(
|
|
6267
|
+
t,
|
|
6268
|
+
() => this._fetchSnapshot(),
|
|
6269
|
+
(o, r) => {
|
|
6270
|
+
this._verbose && console.log(
|
|
6271
|
+
`[CueProjectSchema] Applying ${r ? "stale (cached)" : "fresh"} snapshot — contentCategories: ${o.contentCategories.length}, entityCategories: ${o.entityCategories.length}, relationships: ${o.relationships.length}`
|
|
6272
|
+
), this._snapshot = o, this._apply(o);
|
|
6210
6273
|
},
|
|
6211
6274
|
this._queryCache
|
|
6212
|
-
)
|
|
6275
|
+
).then(() => {
|
|
6276
|
+
}).finally(() => {
|
|
6277
|
+
this._inflight = void 0;
|
|
6278
|
+
});
|
|
6279
|
+
return this._inflight = e, e;
|
|
6280
|
+
}
|
|
6281
|
+
/**
|
|
6282
|
+
* Fetches the schema once. On QLever the pre-computed `schemas` materialized
|
|
6283
|
+
* view is tried first; if it yields no rows we warn and fall back to the live
|
|
6284
|
+
* schema query.
|
|
6285
|
+
*/
|
|
6286
|
+
async _fetchSnapshot() {
|
|
6287
|
+
if (this._graphType !== "fuseki") {
|
|
6288
|
+
const e = await this._runSchemaQuery(_r);
|
|
6289
|
+
if (e.contentCategories.length + e.entityCategories.length + e.relationships.length > 0) return e;
|
|
6290
|
+
console.warn(
|
|
6291
|
+
`[CueProjectSchema] Materialized view "schemas" returned no rows for project ${this._projectId} — falling back to the live schema query.`
|
|
6292
|
+
);
|
|
6293
|
+
}
|
|
6294
|
+
return this._runSchemaQuery(this._buildSchemaQuery());
|
|
6213
6295
|
}
|
|
6214
6296
|
_apply(t) {
|
|
6215
|
-
|
|
6297
|
+
const e = this._currentLang;
|
|
6298
|
+
this._contentCategories.set(
|
|
6299
|
+
t.contentCategories.map((o) => this._toDef(o, e))
|
|
6300
|
+
), this._entityCategories.set(
|
|
6301
|
+
t.entityCategories.map((o) => this._toDef(o, e))
|
|
6302
|
+
), this._relationships.set(
|
|
6303
|
+
t.relationships.map((o) => this._toDef(o, e))
|
|
6304
|
+
);
|
|
6216
6305
|
}
|
|
6217
|
-
|
|
6218
|
-
|
|
6306
|
+
/** Projects a language-independent {@link SchemaNode} into a {@link CategoryDef}. */
|
|
6307
|
+
_toDef(t, e) {
|
|
6308
|
+
const o = te(t.labels, e) ?? t.iri.split("#").at(-1) ?? t.iri, r = te(t.definitions, e), s = Object.keys(t.definitions).length > 0;
|
|
6309
|
+
return {
|
|
6310
|
+
iri: t.iri,
|
|
6311
|
+
label: o,
|
|
6312
|
+
labels: t.labels,
|
|
6313
|
+
...r !== void 0 ? { definition: r } : {},
|
|
6314
|
+
...s ? { definitions: t.definitions } : {},
|
|
6315
|
+
...t.parent !== void 0 ? { parent: t.parent } : {},
|
|
6316
|
+
...t.deprecated !== void 0 ? { deprecated: t.deprecated } : {}
|
|
6317
|
+
};
|
|
6219
6318
|
}
|
|
6220
|
-
|
|
6319
|
+
/**
|
|
6320
|
+
* Single query covering content categories, entity categories and entity
|
|
6321
|
+
* relationship types. Labels/definitions are returned untouched (with their
|
|
6322
|
+
* language tags) so they can be grouped into {@link LangMap}s client-side.
|
|
6323
|
+
*/
|
|
6324
|
+
_buildSchemaQuery() {
|
|
6221
6325
|
return `PREFIX qcy: <${y.qcy}>
|
|
6222
|
-
PREFIX skos: <${
|
|
6223
|
-
|
|
6326
|
+
PREFIX skos: <${R.skos}>
|
|
6327
|
+
PREFIX rdfs: <${R.rdfs}>
|
|
6328
|
+
PREFIX owl: <${R.owl}>
|
|
6329
|
+
SELECT ?iri ?type ?parent ?deprecated ?label ?definition
|
|
6224
6330
|
WHERE {
|
|
6225
|
-
|
|
6226
|
-
|
|
6227
|
-
|
|
6228
|
-
|
|
6229
|
-
|
|
6230
|
-
}
|
|
6231
|
-
|
|
6232
|
-
|
|
6233
|
-
|
|
6234
|
-
|
|
6235
|
-
|
|
6236
|
-
|
|
6237
|
-
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6241
|
-
}
|
|
6331
|
+
{
|
|
6332
|
+
VALUES ?type { qcy:ContentCategory qcy:EntityCategory }
|
|
6333
|
+
?iri a ?type ;
|
|
6334
|
+
skos:prefLabel ?label ;
|
|
6335
|
+
skos:definition ?definition .
|
|
6336
|
+
OPTIONAL { ?iri skos:broader ?parent }
|
|
6337
|
+
OPTIONAL { ?iri owl:deprecated ?deprecated }
|
|
6338
|
+
}
|
|
6339
|
+
UNION
|
|
6340
|
+
{
|
|
6341
|
+
?iri rdfs:subPropertyOf+ qcy:relatedEntity .
|
|
6342
|
+
?iri rdfs:label ?label ;
|
|
6343
|
+
rdfs:comment ?definition .
|
|
6344
|
+
OPTIONAL { ?iri rdfs:subPropertyOf ?parent }
|
|
6345
|
+
OPTIONAL { ?iri owl:deprecated ?deprecated }
|
|
6346
|
+
BIND(qcy:relatedEntity AS ?type)
|
|
6347
|
+
}
|
|
6348
|
+
}`;
|
|
6242
6349
|
}
|
|
6243
|
-
|
|
6244
|
-
|
|
6350
|
+
/** Runs a schema query and groups the flat rows into a {@link SchemaSnapshot}. */
|
|
6351
|
+
async _runSchemaQuery(t) {
|
|
6352
|
+
const e = await this._api.sparql(
|
|
6353
|
+
t,
|
|
6354
|
+
this._projectId,
|
|
6355
|
+
this._graphType
|
|
6356
|
+
), o = /* @__PURE__ */ new Map();
|
|
6357
|
+
for (const s of e.results.bindings) {
|
|
6358
|
+
const a = s.iri?.value, n = s.type?.value;
|
|
6359
|
+
if (!a || !n) continue;
|
|
6360
|
+
let p = o.get(a);
|
|
6361
|
+
p || (p = { iri: a, type: n, labels: {}, definitions: {} }, o.set(a, p)), p.parent === void 0 && s.parent?.value && (p.parent = s.parent.value);
|
|
6362
|
+
const c = s.deprecated?.value;
|
|
6363
|
+
c !== void 0 && (p.deprecated = c === "true" || c === "1"), Zt(p.labels, s.label), Zt(p.definitions, s.definition);
|
|
6364
|
+
}
|
|
6365
|
+
const r = {
|
|
6366
|
+
contentCategories: [],
|
|
6367
|
+
entityCategories: [],
|
|
6368
|
+
relationships: []
|
|
6369
|
+
};
|
|
6370
|
+
for (const s of o.values())
|
|
6371
|
+
Jt(s.labels), Jt(s.definitions), s.type === yr ? r.contentCategories.push(s) : s.type === br ? r.entityCategories.push(s) : s.type === vr && r.relationships.push(s);
|
|
6372
|
+
return r;
|
|
6245
6373
|
}
|
|
6246
|
-
_buildRelationshipsQuery(t) {
|
|
6247
|
-
return `PREFIX qcy: <${y.qcy}>
|
|
6248
|
-
PREFIX rdfs: <${A.rdfs}>
|
|
6249
|
-
SELECT ?iri ?parent (SAMPLE(?l) AS ?label)
|
|
6250
|
-
WHERE {
|
|
6251
|
-
?x qcy:relatedEntity ?y ;
|
|
6252
|
-
?iri ?y .
|
|
6253
|
-
OPTIONAL { ?iri rdfs:label ?lang_label FILTER(LANG(?lang_label) = "${t}") }
|
|
6254
|
-
OPTIONAL { ?iri rdfs:label ?no_lang_label }
|
|
6255
|
-
BIND(COALESCE(?lang_label, ?no_lang_label) AS ?l)
|
|
6256
|
-
OPTIONAL { ?iri rdfs:subPropertyOf ?parent }
|
|
6257
6374
|
}
|
|
6258
|
-
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
|
|
6263
|
-
|
|
6264
|
-
|
|
6265
|
-
|
|
6266
|
-
|
|
6267
|
-
};
|
|
6268
|
-
});
|
|
6375
|
+
function Zt(i, t) {
|
|
6376
|
+
if (!t || t.value === void 0) return;
|
|
6377
|
+
const e = t["xml:lang"], o = e && e.length > 0 ? e : "default";
|
|
6378
|
+
i[o] === void 0 && (i[o] = t.value);
|
|
6379
|
+
}
|
|
6380
|
+
function Jt(i) {
|
|
6381
|
+
if (i.en !== void 0) {
|
|
6382
|
+
i.default = i.en;
|
|
6383
|
+
return;
|
|
6269
6384
|
}
|
|
6385
|
+
if (i.default !== void 0) return;
|
|
6386
|
+
const t = Object.values(i)[0];
|
|
6387
|
+
t !== void 0 && (i.default = t);
|
|
6388
|
+
}
|
|
6389
|
+
function te(i, t) {
|
|
6390
|
+
return i[t] ?? i.default;
|
|
6270
6391
|
}
|
|
6271
|
-
const
|
|
6272
|
-
class
|
|
6392
|
+
const kr = "https://qlever.dev/api/osm-planet";
|
|
6393
|
+
class _e {
|
|
6273
6394
|
constructor(t, e, o = ut, r, s, a = !1) {
|
|
6274
6395
|
this._api = t, this._projectId = e, this._queryCache = r, this._graphType = s, this._verbose = a, this.baseURL = `${o}${e}/`, this.entityInfoMap = this._entityInfoMapComputed, this.entityGraph = this._entityGraph.asReadonly(), this._entityOSMMap.subscribe(() => this._checkPendingOSMFetches()), this._fetchEntityGraph().catch(
|
|
6275
6396
|
(n) => console.error("[CueProjectEntities] Entity graph fetch failed:", n)
|
|
@@ -6283,17 +6404,17 @@ class we {
|
|
|
6283
6404
|
/** Full RDF base URL for this project, e.g. `https://cue.qaecy.com/r/{pid}/` */
|
|
6284
6405
|
baseURL;
|
|
6285
6406
|
// ── Internal writable slices ───────────────────────────────────────────────
|
|
6286
|
-
_entityDetails = new
|
|
6287
|
-
_entityDocuments = new
|
|
6407
|
+
_entityDetails = new x({});
|
|
6408
|
+
_entityDocuments = new x(
|
|
6288
6409
|
{}
|
|
6289
6410
|
);
|
|
6290
|
-
_entityRelationships = new
|
|
6291
|
-
_entityOSMMap = new
|
|
6292
|
-
_osmWKTMap = new
|
|
6411
|
+
_entityRelationships = new x({});
|
|
6412
|
+
_entityOSMMap = new x({});
|
|
6413
|
+
_osmWKTMap = new x({});
|
|
6293
6414
|
_fetchingOSMIds = /* @__PURE__ */ new Set();
|
|
6294
6415
|
/** Cumulative unique entity UUIDs ever passed to request methods (survives cache hits). */
|
|
6295
6416
|
_seenIds = /* @__PURE__ */ new Set();
|
|
6296
|
-
_entityGraph = new
|
|
6417
|
+
_entityGraph = new x(void 0);
|
|
6297
6418
|
// ── Derived signals ────────────────────────────────────────────────────────
|
|
6298
6419
|
_entityInfoMapComputed = dt(
|
|
6299
6420
|
[
|
|
@@ -6488,7 +6609,7 @@ WHERE {
|
|
|
6488
6609
|
*/
|
|
6489
6610
|
async contentCategoriesInProject(t = !0) {
|
|
6490
6611
|
const e = this._api.language, o = `PREFIX qcy: <${y.qcy}>
|
|
6491
|
-
PREFIX skos: <${
|
|
6612
|
+
PREFIX skos: <${R.skos}>
|
|
6492
6613
|
SELECT ?iri (SAMPLE(?l) AS ?label) ?count
|
|
6493
6614
|
WHERE {
|
|
6494
6615
|
?iri a qcy:EntityCategory .
|
|
@@ -6562,11 +6683,7 @@ WHERE {
|
|
|
6562
6683
|
${s}
|
|
6563
6684
|
}
|
|
6564
6685
|
GROUP BY ?sourceCat ?predicate ?targetCat
|
|
6565
|
-
ORDER BY DESC(?weight)`, n = await this.
|
|
6566
|
-
a,
|
|
6567
|
-
this._projectId,
|
|
6568
|
-
this._graphType
|
|
6569
|
-
), p = n.results.bindings.filter(
|
|
6686
|
+
ORDER BY DESC(?weight)`, n = await this._fetchSummaryData(a, s), p = n.results.bindings.filter(
|
|
6570
6687
|
(c) => c.sourceCat && c.predicate && c.targetCat
|
|
6571
6688
|
);
|
|
6572
6689
|
if (t === "graph") {
|
|
@@ -6597,6 +6714,41 @@ ORDER BY DESC(?weight)`, n = await this._api.sparql(
|
|
|
6597
6714
|
return n;
|
|
6598
6715
|
}
|
|
6599
6716
|
// ── Private helpers ────────────────────────────────────────────────────────
|
|
6717
|
+
/**
|
|
6718
|
+
* Fetches the category-summary rows. On QLever the pre-computed
|
|
6719
|
+
* `entity-summary` materialized view is tried first; if it yields no rows we
|
|
6720
|
+
* warn and fall back to the live aggregation query. Fuseki always uses the
|
|
6721
|
+
* live query.
|
|
6722
|
+
*/
|
|
6723
|
+
async _fetchSummaryData(t, e) {
|
|
6724
|
+
if (this._graphType !== "fuseki") {
|
|
6725
|
+
const r = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
|
|
6726
|
+
SELECT ?sourceCat ?predicate ?targetCat ?weight
|
|
6727
|
+
WHERE {
|
|
6728
|
+
SERVICE view:entity-summary {
|
|
6729
|
+
_:cfg view:column-sourceCat ?sourceCat ;
|
|
6730
|
+
view:column-predicate ?predicate ;
|
|
6731
|
+
view:column-targetCat ?targetCat ;
|
|
6732
|
+
view:column-weight ?weight .
|
|
6733
|
+
}
|
|
6734
|
+
${e}
|
|
6735
|
+
}
|
|
6736
|
+
ORDER BY DESC(?weight)`, s = await this._api.sparql(
|
|
6737
|
+
r,
|
|
6738
|
+
this._projectId,
|
|
6739
|
+
this._graphType
|
|
6740
|
+
);
|
|
6741
|
+
if (s?.results?.bindings?.length) return s;
|
|
6742
|
+
console.warn(
|
|
6743
|
+
'[CueProjectEntities] Materialized view "entity-summary" returned no rows — falling back to the live query.'
|
|
6744
|
+
);
|
|
6745
|
+
}
|
|
6746
|
+
return await this._api.sparql(
|
|
6747
|
+
t,
|
|
6748
|
+
this._projectId,
|
|
6749
|
+
this._graphType
|
|
6750
|
+
);
|
|
6751
|
+
}
|
|
6600
6752
|
_computeEntityInfoMap() {
|
|
6601
6753
|
const t = this._entityDetails.get(), e = this._entityDocuments.get(), o = this._entityRelationships.get(), r = this._entityOSMMap.get(), s = this._osmWKTMap.get(), a = /* @__PURE__ */ new Set([
|
|
6602
6754
|
...Object.keys(t),
|
|
@@ -6614,18 +6766,18 @@ ORDER BY DESC(?weight)`, n = await this._api.sparql(
|
|
|
6614
6766
|
(f) => s[f] !== void 0 && !u.has(f) && !!u.add(f)
|
|
6615
6767
|
).map((f) => ({ osmIRI: f, wkt: s[f] }));
|
|
6616
6768
|
const m = /* @__PURE__ */ new Map();
|
|
6617
|
-
for (const { osm: f, viaRels:
|
|
6618
|
-
const
|
|
6619
|
-
if (
|
|
6620
|
-
for (const I of
|
|
6769
|
+
for (const { osm: f, viaRels: _, entityUUID: w } of h.indirect) {
|
|
6770
|
+
const E = s[f];
|
|
6771
|
+
if (E)
|
|
6772
|
+
for (const I of _) {
|
|
6621
6773
|
const v = `${I}:${w}`, b = m.get(v) ?? { geometries: [], entityUUID: w };
|
|
6622
|
-
b.geometries.some((
|
|
6774
|
+
b.geometries.some((S) => S.osmIRI === f) || (b.geometries.push({ osmIRI: f, wkt: E }), m.set(v, b));
|
|
6623
6775
|
}
|
|
6624
6776
|
}
|
|
6625
6777
|
m.size > 0 && (g = Array.from(m.entries()).map(
|
|
6626
|
-
([f, { geometries:
|
|
6778
|
+
([f, { geometries: _, entityUUID: w }]) => ({
|
|
6627
6779
|
rel: f.split(":")[0],
|
|
6628
|
-
geometries:
|
|
6780
|
+
geometries: _,
|
|
6629
6781
|
entityUUID: w
|
|
6630
6782
|
})
|
|
6631
6783
|
));
|
|
@@ -6753,10 +6905,10 @@ GROUP BY ?e1Cat ?e2Cat`;
|
|
|
6753
6905
|
async _fetchOSMLocations(t) {
|
|
6754
6906
|
const e = t.filter((n) => !n.includes("/relation/"));
|
|
6755
6907
|
if (e.length === 0) return;
|
|
6756
|
-
const o = e.map((n) => `<${n}>`).join(" "), r = `PREFIX geo: <${
|
|
6908
|
+
const o = e.map((n) => `<${n}>`).join(" "), r = `PREFIX geo: <${R.geo}>
|
|
6757
6909
|
SELECT * WHERE {
|
|
6758
6910
|
VALUES ?s { ${o} }
|
|
6759
|
-
SERVICE <${
|
|
6911
|
+
SERVICE <${kr}> {
|
|
6760
6912
|
?s geo:hasGeometry/geo:asWKT ?wkt
|
|
6761
6913
|
}
|
|
6762
6914
|
}`, s = await this._api.sparql(
|
|
@@ -6770,7 +6922,7 @@ SELECT * WHERE {
|
|
|
6770
6922
|
}
|
|
6771
6923
|
}
|
|
6772
6924
|
var l = /* @__PURE__ */ ((i) => (i.AUTOMATION = "automation", i.ARCHIVE = "archive", i.AUDIO = "audio", i.BACKUP = "backup", i.BINARY = "binary", i.BIM = "bim", i.CAD = "cad", i.DATA = "data", i.EMAIL = "email", i.FONT = "font", i.GEOSPATIAL = "geospatial", i.IMAGE = "image", i.INSTALLER = "installer", i.MARKUP = "markup", i.MULTIMEDIA = "multimedia", i.PLANNING = "planning", i.PRESENTATION = "presentation", i.SCRIPT = "script", i.SPREADSHEET = "spreadsheet", i.TEXT = "text", i.THREE_D = "3d", i.UNKNOWN = "unknown", i.VIDEO = "video", i))(l || {});
|
|
6773
|
-
const
|
|
6925
|
+
const ct = {
|
|
6774
6926
|
".aac": {
|
|
6775
6927
|
type: l.AUDIO,
|
|
6776
6928
|
open: !0,
|
|
@@ -7631,7 +7783,30 @@ const lt = {
|
|
|
7631
7783
|
}
|
|
7632
7784
|
};
|
|
7633
7785
|
l.AUDIO + "", l.VIDEO + "", l.IMAGE + "", l.TEXT + "", l.MARKUP + "", l.SCRIPT + "", l.DATA + "", l.ARCHIVE + "", l.INSTALLER + "", l.BINARY + "", l.BACKUP + "", l.AUTOMATION + "", l.PRESENTATION + "", l.SPREADSHEET + "", l.FONT + "", l.GEOSPATIAL + "", l.THREE_D + "", l.CAD + "", l.BIM + "", l.PLANNING + "", l.EMAIL + "", l.MULTIMEDIA + "", l.UNKNOWN + "";
|
|
7634
|
-
|
|
7786
|
+
const xr = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
|
|
7787
|
+
SELECT ?ext ?totalSize ?docCount
|
|
7788
|
+
WHERE {
|
|
7789
|
+
SERVICE view:docs-by-suffix {
|
|
7790
|
+
_:cfg view:column-ext ?ext ;
|
|
7791
|
+
view:column-totalSize ?totalSize ;
|
|
7792
|
+
view:column-docCount ?docCount .
|
|
7793
|
+
}
|
|
7794
|
+
}`, Cr = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
|
|
7795
|
+
SELECT ?cat ?totalSize ?docCount
|
|
7796
|
+
WHERE {
|
|
7797
|
+
SERVICE view:docs-by-category {
|
|
7798
|
+
_:cfg view:column-cat ?cat ;
|
|
7799
|
+
view:column-totalSize ?totalSize ;
|
|
7800
|
+
view:column-docCount ?docCount .
|
|
7801
|
+
}
|
|
7802
|
+
}`, Ir = `PREFIX view: <https://qlever.cs.uni-freiburg.de/materializedView/>
|
|
7803
|
+
SELECT ?count
|
|
7804
|
+
WHERE {
|
|
7805
|
+
SERVICE view:doc-duplicates {
|
|
7806
|
+
_:cfg view:column-count ?count .
|
|
7807
|
+
}
|
|
7808
|
+
}`;
|
|
7809
|
+
class lt {
|
|
7635
7810
|
constructor(t, e, o, r = ut, s, a, n = !1) {
|
|
7636
7811
|
this._api = t, this._projectId = e, this._queryCache = s, this._graphType = a, this._verbose = n, this.baseURL = `${r}${e}/`, this._currentLang = o ?? this._api.language, this.documentInfoMap = this._documentInfoMap.asReadonly(), this.projectDocumentsData = this._projectDocumentsData.asReadonly();
|
|
7637
7812
|
}
|
|
@@ -7644,10 +7819,10 @@ class ct {
|
|
|
7644
7819
|
baseURL;
|
|
7645
7820
|
/** Tracks the language for which `_documentInfoMap` is currently populated. */
|
|
7646
7821
|
_currentLang;
|
|
7647
|
-
_documentInfoMap = new
|
|
7822
|
+
_documentInfoMap = new x({});
|
|
7648
7823
|
/** Cumulative unique document UUIDs ever passed to request methods (survives cache hits). */
|
|
7649
7824
|
_seenIds = /* @__PURE__ */ new Set();
|
|
7650
|
-
_projectDocumentsData = new
|
|
7825
|
+
_projectDocumentsData = new x({
|
|
7651
7826
|
duplicateCount: 0,
|
|
7652
7827
|
documentsBySuffix: {},
|
|
7653
7828
|
documentsByContentCategory: {}
|
|
@@ -7693,9 +7868,9 @@ class ct {
|
|
|
7693
7868
|
t + e + o,
|
|
7694
7869
|
async () => {
|
|
7695
7870
|
const [r, s, a] = await Promise.all([
|
|
7696
|
-
this.
|
|
7697
|
-
this.
|
|
7698
|
-
this.
|
|
7871
|
+
this._fetchDocumentsBySuffix(),
|
|
7872
|
+
this._fetchDocumentsByContentCategory(),
|
|
7873
|
+
this._fetchDuplicateCount()
|
|
7699
7874
|
]);
|
|
7700
7875
|
return { duplicateCount: a, documentsBySuffix: r, documentsByContentCategory: s };
|
|
7701
7876
|
},
|
|
@@ -7850,7 +8025,7 @@ WHERE {
|
|
|
7850
8025
|
});
|
|
7851
8026
|
}
|
|
7852
8027
|
documentsByFileType(t, e = !1) {
|
|
7853
|
-
const o = new Set(t), r = Object.values(
|
|
8028
|
+
const o = new Set(t), r = Object.values(ct).filter((s) => o.has(s.type)).map((s) => s.suffix);
|
|
7854
8029
|
return this.documentsBySuffix(r, e);
|
|
7855
8030
|
}
|
|
7856
8031
|
async documentsByContentCategory(t, e = !1) {
|
|
@@ -7888,7 +8063,7 @@ WHERE {
|
|
|
7888
8063
|
});
|
|
7889
8064
|
}
|
|
7890
8065
|
documentsByMime(t, e = !1) {
|
|
7891
|
-
const o = new Set(t), r = Object.values(
|
|
8066
|
+
const o = new Set(t), r = Object.values(ct).filter((s) => o.has(s.mime)).map((s) => s.suffix);
|
|
7892
8067
|
return this.documentsBySuffix(r, e);
|
|
7893
8068
|
}
|
|
7894
8069
|
// ── Private helpers ────────────────────────────────────────────────────────
|
|
@@ -7979,6 +8154,11 @@ GROUP BY ?id ?suffix ?size`, r = await this._api.sparql(o, this._projectId, this
|
|
|
7979
8154
|
}), this._documentInfoMap.set(s), this._log(`fetchSimpleDocumentInfoBatch: ${Object.keys(a).length} fetched | cumulative: ${Object.keys(s).length} with metadata / ${this._seenIds.size} seen`), a;
|
|
7980
8155
|
}
|
|
7981
8156
|
async _fetchDocumentsBySuffix() {
|
|
8157
|
+
if (this._graphType !== "fuseki") {
|
|
8158
|
+
const e = await this._runDocumentsBySuffixQuery(xr);
|
|
8159
|
+
if (Object.keys(e).length > 0) return e;
|
|
8160
|
+
console.warn(`[CueProjectDocuments] Materialized view "docs-by-suffix" returned no rows for project ${this._projectId} — falling back to live query.`);
|
|
8161
|
+
}
|
|
7982
8162
|
return this._runDocumentsBySuffixQuery(this._buildDocumentsBySuffixQuery());
|
|
7983
8163
|
}
|
|
7984
8164
|
_buildDocumentsBySuffixQuery() {
|
|
@@ -8008,6 +8188,11 @@ ORDER BY DESC(?docCount)`;
|
|
|
8008
8188
|
}), o;
|
|
8009
8189
|
}
|
|
8010
8190
|
async _fetchDocumentsByContentCategory() {
|
|
8191
|
+
if (this._graphType !== "fuseki") {
|
|
8192
|
+
const e = await this._runDocumentsByContentCategoryQuery(Cr);
|
|
8193
|
+
if (Object.keys(e).length > 0) return e;
|
|
8194
|
+
console.warn(`[CueProjectDocuments] Materialized view "docs-by-category" returned no rows for project ${this._projectId} — falling back to live query.`);
|
|
8195
|
+
}
|
|
8011
8196
|
return this._runDocumentsByContentCategoryQuery(this._buildDocumentsByContentCategoryQuery());
|
|
8012
8197
|
}
|
|
8013
8198
|
_buildDocumentsByContentCategoryQuery() {
|
|
@@ -8037,6 +8222,14 @@ ORDER BY DESC(?docCount)`;
|
|
|
8037
8222
|
}), o;
|
|
8038
8223
|
}
|
|
8039
8224
|
async _fetchDuplicateCount() {
|
|
8225
|
+
if (this._graphType !== "fuseki") {
|
|
8226
|
+
const e = await this._api.sparql(Ir, this._projectId, this._graphType);
|
|
8227
|
+
if (e.results.bindings.length > 0) {
|
|
8228
|
+
const o = e.results.bindings[0];
|
|
8229
|
+
return o?.count ? parseInt(o.count.value, 10) : 0;
|
|
8230
|
+
}
|
|
8231
|
+
console.warn(`[CueProjectDocuments] Materialized view "doc-duplicates" returned no rows for project ${this._projectId} — falling back to live query.`);
|
|
8232
|
+
}
|
|
8040
8233
|
return this._runDuplicateCountQuery(this._buildDuplicateCountQuery());
|
|
8041
8234
|
}
|
|
8042
8235
|
_buildDuplicateCountQuery() {
|
|
@@ -8058,9 +8251,9 @@ WHERE {
|
|
|
8058
8251
|
return o?.count ? parseInt(o.count.value, 10) : 0;
|
|
8059
8252
|
}
|
|
8060
8253
|
}
|
|
8061
|
-
class
|
|
8254
|
+
class Sr {
|
|
8062
8255
|
constructor(t, e, { language: o, queryCache: r, rdfBase: s = ut, graphType: a, verbose: n }) {
|
|
8063
|
-
this._api = t, this._projectId = e, this.schema = new
|
|
8256
|
+
this._api = t, this._projectId = e, this.schema = new Er(t, e, o, r, a, n), this.entities = new _e(t, e, s, r, a, n), this.documents = new lt(t, e, o, s, r, a, n), this.availableContentCategories = this.schema.availableContentCategories, this.availableEntityCategories = this.schema.availableEntityCategories, this.availableEntityRelationships = this.schema.availableEntityRelationships, this.schemaReady = this.schema.ready, this.entityInfoMap = this.entities.entityInfoMap, this.entityGraph = this.entities.entityGraph, this.documentInfoMap = this.documents.documentInfoMap, this.projectDocumentsData = this.documents.projectDocumentsData, this.searchResults = this._searchResults.asReadonly(), this.documents.fetchOverview().catch((p) => console.error("[CueProjectView] fetchOverview failed:", p));
|
|
8064
8257
|
}
|
|
8065
8258
|
_api;
|
|
8066
8259
|
_projectId;
|
|
@@ -8091,7 +8284,7 @@ class hr {
|
|
|
8091
8284
|
/** Project document overview (counts by suffix and category). Fetched on init. */
|
|
8092
8285
|
projectDocumentsData;
|
|
8093
8286
|
// ── Search state ───────────────────────────────────────────────────────────
|
|
8094
|
-
_searchResults = new
|
|
8287
|
+
_searchResults = new x(void 0);
|
|
8095
8288
|
/** The result of the most recent `search()` call. `undefined` before first search. */
|
|
8096
8289
|
searchResults;
|
|
8097
8290
|
_destroyed = !1;
|
|
@@ -8178,7 +8371,7 @@ class hr {
|
|
|
8178
8371
|
this._destroyed = !0, this._searchResults.set(void 0);
|
|
8179
8372
|
}
|
|
8180
8373
|
}
|
|
8181
|
-
function
|
|
8374
|
+
function ee(i, t) {
|
|
8182
8375
|
return new Promise((e) => {
|
|
8183
8376
|
const o = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
|
|
8184
8377
|
for (const w of i)
|
|
@@ -8191,14 +8384,14 @@ function Yt(i, t) {
|
|
|
8191
8384
|
s.has(w.contentUUID) ? (s.get(w.contentUUID) || []).some((v) => v.locationUUID === w.locationUUID) || p.push(w) : n.push(w);
|
|
8192
8385
|
const c = [], h = [];
|
|
8193
8386
|
for (const w of t) {
|
|
8194
|
-
const
|
|
8195
|
-
|
|
8387
|
+
const E = o.get(w.contentUUID);
|
|
8388
|
+
E ? E.some((v) => v.locationUUID === w.locationUUID) || h.push(w) : c.push(w);
|
|
8196
8389
|
}
|
|
8197
8390
|
const d = i.length - n.length - p.length, g = i.length, u = g > 0 ? d / g : 1;
|
|
8198
8391
|
let m = 0, f = 0;
|
|
8199
8392
|
for (const w of i)
|
|
8200
8393
|
f += w.size || 0, (s.get(w.contentUUID) || []).some((v) => v.locationUUID === w.locationUUID) && (m += w.size || 0);
|
|
8201
|
-
const
|
|
8394
|
+
const _ = f > 0 ? m / f : 1;
|
|
8202
8395
|
e({
|
|
8203
8396
|
localNotOnRemote: n,
|
|
8204
8397
|
localNotOnRemotePathOnly: p,
|
|
@@ -8208,27 +8401,27 @@ function Yt(i, t) {
|
|
|
8208
8401
|
totalCount: g,
|
|
8209
8402
|
syncSize: m,
|
|
8210
8403
|
totalSize: f,
|
|
8211
|
-
synctPctSize:
|
|
8404
|
+
synctPctSize: _,
|
|
8212
8405
|
synctPctCount: u
|
|
8213
8406
|
});
|
|
8214
8407
|
});
|
|
8215
8408
|
}
|
|
8216
|
-
const { namedNode:
|
|
8217
|
-
|
|
8218
|
-
const { namedNode:
|
|
8219
|
-
|
|
8220
|
-
function
|
|
8409
|
+
const { namedNode: Tr, literal: Hr } = j;
|
|
8410
|
+
Tr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
8411
|
+
const { namedNode: Wr } = j, { namedNode: Rr, literal: Vr } = j;
|
|
8412
|
+
Rr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
8413
|
+
function Ar(i) {
|
|
8221
8414
|
const t = i.split(".");
|
|
8222
8415
|
return t.length > 1 ? "." + t.pop()?.toLowerCase() : "";
|
|
8223
8416
|
}
|
|
8224
|
-
const { namedNode:
|
|
8225
|
-
|
|
8226
|
-
const { namedNode:
|
|
8227
|
-
|
|
8228
|
-
function
|
|
8229
|
-
const c =
|
|
8230
|
-
a === void 0 && (a =
|
|
8231
|
-
const g =
|
|
8417
|
+
const { namedNode: Pr, literal: Xr } = j;
|
|
8418
|
+
Pr("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
8419
|
+
const { namedNode: Or, literal: Kr } = j;
|
|
8420
|
+
Or("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
|
|
8421
|
+
function oe(i, t, e, o, r, s, a, n = !1, p = !1) {
|
|
8422
|
+
const c = Ar(i), h = D(o), d = `${t}/${h}${c}`;
|
|
8423
|
+
a === void 0 && (a = ct[c]?.mime ?? "application/octet-stream");
|
|
8424
|
+
const g = io(i, r);
|
|
8232
8425
|
return {
|
|
8233
8426
|
name: i,
|
|
8234
8427
|
blob_name: d,
|
|
@@ -8248,25 +8441,25 @@ function Zt(i, t, e, o, r, s, a, n = !1, p = !1) {
|
|
|
8248
8441
|
})
|
|
8249
8442
|
};
|
|
8250
8443
|
}
|
|
8251
|
-
async function
|
|
8444
|
+
async function z() {
|
|
8252
8445
|
return import(
|
|
8253
8446
|
/* webpackIgnore: true */
|
|
8254
8447
|
"fs/promises"
|
|
8255
8448
|
);
|
|
8256
8449
|
}
|
|
8257
|
-
async function
|
|
8450
|
+
async function re(i) {
|
|
8258
8451
|
if (typeof window < "u")
|
|
8259
8452
|
throw new Error(
|
|
8260
8453
|
`Cannot read file from path "${i}" in a browser environment. Provide file.data (Uint8Array) instead.`
|
|
8261
8454
|
);
|
|
8262
|
-
const { readFile: t } = await
|
|
8455
|
+
const { readFile: t } = await z();
|
|
8263
8456
|
return t(i);
|
|
8264
8457
|
}
|
|
8265
8458
|
let q = null, G = null, H = null;
|
|
8266
|
-
function
|
|
8459
|
+
function Qr(i) {
|
|
8267
8460
|
H = i, G = null, q = null;
|
|
8268
8461
|
}
|
|
8269
|
-
async function
|
|
8462
|
+
async function Dr() {
|
|
8270
8463
|
if (typeof window < "u") {
|
|
8271
8464
|
if (!H)
|
|
8272
8465
|
throw new Error(
|
|
@@ -8278,7 +8471,7 @@ async function fr() {
|
|
|
8278
8471
|
const t = new Uint8Array(await i.arrayBuffer()), o = await import(`${H}/dir_scanner_wasm.mjs`);
|
|
8279
8472
|
await o.default({ module_or_path: t }), q = o.scan;
|
|
8280
8473
|
} else {
|
|
8281
|
-
const { readFile: i } = await
|
|
8474
|
+
const { readFile: i } = await z(), { join: t } = await import(
|
|
8282
8475
|
/* webpackIgnore: true */
|
|
8283
8476
|
"path"
|
|
8284
8477
|
), { pathToFileURL: e } = await import(
|
|
@@ -8288,7 +8481,7 @@ async function fr() {
|
|
|
8288
8481
|
await a.default({ module_or_path: r }), q = a.scan;
|
|
8289
8482
|
}
|
|
8290
8483
|
}
|
|
8291
|
-
const
|
|
8484
|
+
const Lr = "qlever", N = 1e3, mt = "cue:pending:";
|
|
8292
8485
|
async function wt(i) {
|
|
8293
8486
|
const { tmpdir: t } = await import(
|
|
8294
8487
|
/* webpackIgnore: true */
|
|
@@ -8299,37 +8492,37 @@ async function wt(i) {
|
|
|
8299
8492
|
);
|
|
8300
8493
|
return e(t(), `cue-sync-pending-${i}.json`);
|
|
8301
8494
|
}
|
|
8302
|
-
async function
|
|
8495
|
+
async function se(i) {
|
|
8303
8496
|
if (typeof window < "u") {
|
|
8304
8497
|
const t = window.localStorage.getItem(`${mt}${i}`);
|
|
8305
8498
|
return t ? JSON.parse(t) : null;
|
|
8306
8499
|
}
|
|
8307
8500
|
try {
|
|
8308
|
-
const t = await (await
|
|
8501
|
+
const t = await (await z()).readFile(await wt(i), "utf-8");
|
|
8309
8502
|
return JSON.parse(t);
|
|
8310
8503
|
} catch {
|
|
8311
8504
|
return null;
|
|
8312
8505
|
}
|
|
8313
8506
|
}
|
|
8314
|
-
async function
|
|
8507
|
+
async function ae(i) {
|
|
8315
8508
|
const t = JSON.stringify(i);
|
|
8316
8509
|
if (typeof window < "u") {
|
|
8317
8510
|
window.localStorage.setItem(`${mt}${i.spaceId}`, t);
|
|
8318
8511
|
return;
|
|
8319
8512
|
}
|
|
8320
|
-
await (await
|
|
8513
|
+
await (await z()).writeFile(await wt(i.spaceId), t, "utf-8");
|
|
8321
8514
|
}
|
|
8322
|
-
async function
|
|
8515
|
+
async function qr(i) {
|
|
8323
8516
|
if (typeof window < "u") {
|
|
8324
8517
|
window.localStorage.removeItem(`${mt}${i}`);
|
|
8325
8518
|
return;
|
|
8326
8519
|
}
|
|
8327
8520
|
try {
|
|
8328
|
-
await (await
|
|
8521
|
+
await (await z()).unlink(await wt(i));
|
|
8329
8522
|
} catch {
|
|
8330
8523
|
}
|
|
8331
8524
|
}
|
|
8332
|
-
class
|
|
8525
|
+
class jr {
|
|
8333
8526
|
constructor(t, e, o, r) {
|
|
8334
8527
|
this._auth = t, this._projects = e, this._blob = o, this._gatewayUrl = r;
|
|
8335
8528
|
}
|
|
@@ -8385,7 +8578,7 @@ class vr {
|
|
|
8385
8578
|
*/
|
|
8386
8579
|
async flushPendingMetadata(t, e, o) {
|
|
8387
8580
|
this._legacy = o ?? !1;
|
|
8388
|
-
const r = await
|
|
8581
|
+
const r = await se(t);
|
|
8389
8582
|
if (!(!r || r.items.length === 0)) {
|
|
8390
8583
|
console.info(`Trying to upload metadata (${r.items.length} item(s))...`), e && console.info(`Flushing ${r.items.length} pending file location(s) from previous sync ⏳`);
|
|
8391
8584
|
try {
|
|
@@ -8408,22 +8601,22 @@ class vr {
|
|
|
8408
8601
|
this._api?.getConsumption(o) ?? Promise.reject(new Error("CueSyncApi is not bound to a CueApi instance")),
|
|
8409
8602
|
this._fetchUnitCreditMap(s),
|
|
8410
8603
|
this._fetchTierNames()
|
|
8411
|
-
]), f = (await
|
|
8412
|
-
let w = 0,
|
|
8413
|
-
for (const v of
|
|
8604
|
+
]), f = (await ee(t, h)).localNotOnRemote ?? [], _ = f.length > 0 ? await this.scanCost(f) : [];
|
|
8605
|
+
let w = 0, E = 0;
|
|
8606
|
+
for (const v of _) {
|
|
8414
8607
|
w += v.units;
|
|
8415
|
-
const b = g[c],
|
|
8608
|
+
const b = g[c], S = b?.[v.ext] ?? 1;
|
|
8416
8609
|
s && b && !(v.ext in b) && console.info(` Unknown format: .${v.ext} (using default rate of 1 credit/unit)`);
|
|
8417
|
-
const P = v.units *
|
|
8418
|
-
|
|
8610
|
+
const P = v.units * S;
|
|
8611
|
+
E += P, v.credits = Math.round(P);
|
|
8419
8612
|
}
|
|
8420
8613
|
const I = u[c] ?? c;
|
|
8421
8614
|
return {
|
|
8422
|
-
costRecords:
|
|
8615
|
+
costRecords: _,
|
|
8423
8616
|
tier: c,
|
|
8424
8617
|
tierName: I,
|
|
8425
8618
|
unitsToConsume: w,
|
|
8426
|
-
creditsToConsume: Math.round(
|
|
8619
|
+
creditsToConsume: Math.round(E),
|
|
8427
8620
|
creditsAvailable: d.creditsAvailable,
|
|
8428
8621
|
unitsAvailable: d.unitsAvailable,
|
|
8429
8622
|
filesToUpload: f.length,
|
|
@@ -8440,44 +8633,44 @@ class vr {
|
|
|
8440
8633
|
const [d, g] = await Promise.all([
|
|
8441
8634
|
this._listRemoteFiles(h, o, r, a),
|
|
8442
8635
|
this._api?.getConsumption(o) ?? Promise.reject(new Error("CueSyncApi is not bound to a CueApi instance"))
|
|
8443
|
-
]), { unitsAvailable: u } = g, m = await
|
|
8636
|
+
]), { unitsAvailable: u } = g, m = await ee(t, d);
|
|
8444
8637
|
a && (console.info(`Total local files: ${t.length}`), console.info(`Total remote files: ${d.length}`), console.info(
|
|
8445
8638
|
`Total files to sync: ${(m.localNotOnRemote?.length ?? 0) + m.localNotOnRemotePathOnly.length}`
|
|
8446
8639
|
));
|
|
8447
|
-
let f = m.syncCount,
|
|
8640
|
+
let f = m.syncCount, _ = m.syncSize, w = 0, E = !1;
|
|
8448
8641
|
const I = m.localNotOnRemote ?? [];
|
|
8449
8642
|
if (I.length > 0) {
|
|
8450
|
-
const
|
|
8451
|
-
if (
|
|
8643
|
+
const S = (await this.scanCost(I)).reduce((P, ke) => P + ke.units, 0);
|
|
8644
|
+
if (S > u)
|
|
8452
8645
|
throw new Error(
|
|
8453
|
-
`Insufficient units: ${
|
|
8646
|
+
`Insufficient units: ${S} units required but only ${u} available.`
|
|
8454
8647
|
);
|
|
8455
8648
|
}
|
|
8456
8649
|
await this._initPendingBatch(o, a), a && I.length && console.info("Syncing missing files ⏳");
|
|
8457
8650
|
for (const b of I)
|
|
8458
8651
|
try {
|
|
8459
|
-
const
|
|
8652
|
+
const S = oe(
|
|
8460
8653
|
b.relativePath,
|
|
8461
8654
|
o,
|
|
8462
8655
|
s,
|
|
8463
8656
|
b.md5,
|
|
8464
8657
|
r
|
|
8465
8658
|
);
|
|
8466
|
-
if (!
|
|
8467
|
-
const P = b.data ?? new Uint8Array(await
|
|
8659
|
+
if (!S.blob_name) throw new Error(`blob_name missing for ${b.relativePath}`);
|
|
8660
|
+
const P = b.data ?? new Uint8Array(await re(b.fullPath));
|
|
8468
8661
|
await this._blob.uploadRaw(
|
|
8469
|
-
|
|
8662
|
+
S.blob_name,
|
|
8470
8663
|
P,
|
|
8471
|
-
|
|
8664
|
+
S
|
|
8472
8665
|
), await this._queueFileLocation({
|
|
8473
8666
|
relativePath: b.relativePath,
|
|
8474
8667
|
md5: b.md5,
|
|
8475
8668
|
size: b.size,
|
|
8476
8669
|
providerId: r,
|
|
8477
8670
|
fileContentExists: !1
|
|
8478
|
-
}),
|
|
8479
|
-
} catch (
|
|
8480
|
-
w += 1, console.error(`[CueSyncApi] Failed to upload file: ${b.fullPath}`), a && console.error("[CueSyncApi] Upload error details:",
|
|
8671
|
+
}), E = !0, f += 1, _ += b.size || 0, this._logProgress(f, m.totalCount, _, m.totalSize, n);
|
|
8672
|
+
} catch (S) {
|
|
8673
|
+
w += 1, console.error(`[CueSyncApi] Failed to upload file: ${b.fullPath}`), a && console.error("[CueSyncApi] Upload error details:", S);
|
|
8481
8674
|
}
|
|
8482
8675
|
a && m.localNotOnRemotePathOnly.length && console.info(`Syncing missing file locations (on provider "${r}") ⏳`);
|
|
8483
8676
|
for (const b of m.localNotOnRemotePathOnly)
|
|
@@ -8487,23 +8680,23 @@ class vr {
|
|
|
8487
8680
|
size: b.size,
|
|
8488
8681
|
providerId: r,
|
|
8489
8682
|
fileContentExists: !0
|
|
8490
|
-
}),
|
|
8683
|
+
}), E = !0, f += 1, _ += b.size || 0, this._logProgress(f, m.totalCount, _, m.totalSize, n);
|
|
8491
8684
|
await this._drainPending(a), this._stopFlushTimer();
|
|
8492
8685
|
const v = await (this._api?.getConsumption(o) ?? Promise.resolve({ creditsAvailable: 0 }));
|
|
8493
8686
|
return {
|
|
8494
8687
|
syncCount: f,
|
|
8495
|
-
syncSize:
|
|
8688
|
+
syncSize: _,
|
|
8496
8689
|
failedUploads: w,
|
|
8497
8690
|
totalCount: m.totalCount,
|
|
8498
8691
|
totalSize: m.totalSize,
|
|
8499
|
-
rdfWritten:
|
|
8692
|
+
rdfWritten: E,
|
|
8500
8693
|
creditsAvailable: v.creditsAvailable
|
|
8501
8694
|
};
|
|
8502
8695
|
}
|
|
8503
8696
|
async _getOrCreateGraph(t, e) {
|
|
8504
8697
|
const o = this._graphMap.get(t);
|
|
8505
8698
|
if (o) return o;
|
|
8506
|
-
const s = (await this._projects.getProject(t))?.projectSettings?.graph?.type ??
|
|
8699
|
+
const s = (await this._projects.getProject(t))?.projectSettings?.graph?.type ?? Lr, a = s === "qlever" ? `${this._gatewayUrl}${de}` : `${this._gatewayUrl}${he}`, n = s === "qlever" ? `${this._gatewayUrl}${yo}` : `${this._gatewayUrl}${wo}`, p = new so({
|
|
8507
8700
|
graphType: s,
|
|
8508
8701
|
queryEndpoint: a,
|
|
8509
8702
|
updateEndpoint: n,
|
|
@@ -8569,7 +8762,7 @@ WHERE {
|
|
|
8569
8762
|
}
|
|
8570
8763
|
async _initPendingBatch(t, e) {
|
|
8571
8764
|
this._flushTimer !== null && (clearInterval(this._flushTimer), this._flushTimer = null), this._pendingSpaceId = t, this._pendingItems = [];
|
|
8572
|
-
const o = await
|
|
8765
|
+
const o = await se(t);
|
|
8573
8766
|
if (o && o.items.length > 0) {
|
|
8574
8767
|
console.info(`Trying to upload metadata from interrupted sync (${o.items.length} item(s))...`), e && console.info(`Flushing ${o.items.length} pending file location(s) from previous sync ⏳`);
|
|
8575
8768
|
try {
|
|
@@ -8590,7 +8783,7 @@ WHERE {
|
|
|
8590
8783
|
typeof r == "object" && typeof r.unref == "function" && r.unref(), this._flushTimer = r;
|
|
8591
8784
|
}
|
|
8592
8785
|
async _queueFileLocation(t) {
|
|
8593
|
-
this._pendingItems.push(t), this._pendingSpaceId && await
|
|
8786
|
+
this._pendingItems.push(t), this._pendingSpaceId && await ae({ spaceId: this._pendingSpaceId, items: this._pendingItems });
|
|
8594
8787
|
}
|
|
8595
8788
|
/**
|
|
8596
8789
|
* Flush all queued file-location items to the commands API in a single batch.
|
|
@@ -8605,18 +8798,18 @@ WHERE {
|
|
|
8605
8798
|
}
|
|
8606
8799
|
async _flushBatch(t, e, o) {
|
|
8607
8800
|
const r = [...t];
|
|
8608
|
-
this._pendingSpaceId === e && (this._pendingItems = []), await
|
|
8801
|
+
this._pendingSpaceId === e && (this._pendingItems = []), await qr(e);
|
|
8609
8802
|
try {
|
|
8610
8803
|
for (let s = 0; s < r.length; s += N)
|
|
8611
8804
|
await this._postFssBatch(r.slice(s, s + N), e);
|
|
8612
8805
|
o && console.info(`Wrote ${r.length} file location(s) to commands API ✅`);
|
|
8613
8806
|
} catch (s) {
|
|
8614
8807
|
const a = [...r, ...this._pendingItems];
|
|
8615
|
-
throw this._pendingItems = a, await
|
|
8808
|
+
throw this._pendingItems = a, await ae({ spaceId: e, items: a }), s;
|
|
8616
8809
|
}
|
|
8617
8810
|
}
|
|
8618
8811
|
async _postFssBatch(t, e) {
|
|
8619
|
-
const o = this._legacy ? `${this._gatewayUrl}${
|
|
8812
|
+
const o = this._legacy ? `${this._gatewayUrl}${qt}?blob=true` : `${this._gatewayUrl}${qt}`;
|
|
8620
8813
|
let r;
|
|
8621
8814
|
try {
|
|
8622
8815
|
r = await this._auth.authenticatedFetch(o, {
|
|
@@ -8646,14 +8839,14 @@ WHERE {
|
|
|
8646
8839
|
* shown to the user before or after calling {@link sync}.
|
|
8647
8840
|
*/
|
|
8648
8841
|
async scanCost(t) {
|
|
8649
|
-
if (G || (G =
|
|
8842
|
+
if (G || (G = Dr()), await G, !q) throw new Error("WASM scan function not initialised");
|
|
8650
8843
|
const e = 200, o = /* @__PURE__ */ new Map();
|
|
8651
8844
|
for (let r = 0; r < t.length; r += e) {
|
|
8652
8845
|
const s = t.slice(r, r + e), a = await Promise.all(
|
|
8653
8846
|
s.map(async (p) => ({
|
|
8654
8847
|
originalPath: p.relativePath,
|
|
8655
8848
|
// Use pre-loaded data if available (browser), otherwise read from disk (Node.js).
|
|
8656
|
-
data: p.data ?? new Uint8Array(await
|
|
8849
|
+
data: p.data ?? new Uint8Array(await re(p.fullPath))
|
|
8657
8850
|
}))
|
|
8658
8851
|
), n = q(a);
|
|
8659
8852
|
for (const p of n) {
|
|
@@ -8713,7 +8906,7 @@ WHERE {
|
|
|
8713
8906
|
const { spaceId: o, providerId: r, userId: s, signal: a, onProgress: n } = e;
|
|
8714
8907
|
if (!t.data)
|
|
8715
8908
|
throw new Error("syncBrowserFile requires file.data (Uint8Array). Read the file with File.arrayBuffer() first.");
|
|
8716
|
-
const p =
|
|
8909
|
+
const p = oe(t.relativePath, o, s, t.md5, r);
|
|
8717
8910
|
if (!p.blob_name) throw new Error(`blob_name missing for ${t.relativePath}`);
|
|
8718
8911
|
await this._blob.uploadRaw(
|
|
8719
8912
|
p.blob_name,
|
|
@@ -8757,7 +8950,7 @@ WHERE {
|
|
|
8757
8950
|
s({ percent: a, syncCount: t, totalCount: e, syncSize: o, totalSize: r });
|
|
8758
8951
|
}
|
|
8759
8952
|
}
|
|
8760
|
-
const
|
|
8953
|
+
const ie = {
|
|
8761
8954
|
production: {
|
|
8762
8955
|
gatewayUrl: "https://accessors-api-gateway-ueyeemwf2a-oa.a.run.app",
|
|
8763
8956
|
tokenUrl: "https://accessors-api-gateway-ueyeemwf2a-oa.a.run.app/token",
|
|
@@ -8777,7 +8970,7 @@ const oe = {
|
|
|
8777
8970
|
firestoreEmulatorPort: 8080
|
|
8778
8971
|
}
|
|
8779
8972
|
};
|
|
8780
|
-
class
|
|
8973
|
+
class Ee {
|
|
8781
8974
|
auth;
|
|
8782
8975
|
api;
|
|
8783
8976
|
projects;
|
|
@@ -8805,7 +8998,7 @@ class fe {
|
|
|
8805
8998
|
* ```
|
|
8806
8999
|
*/
|
|
8807
9000
|
get gis() {
|
|
8808
|
-
return this._gis || (this._gis = new
|
|
9001
|
+
return this._gis || (this._gis = new mr(
|
|
8809
9002
|
() => this.api.getAuthHeaders(),
|
|
8810
9003
|
this._endpoints.gatewayUrl
|
|
8811
9004
|
)), this._gis;
|
|
@@ -8815,30 +9008,29 @@ class fe {
|
|
|
8815
9008
|
"Using default SDK app settings. Contact QAECY for your own configuration for any production code."
|
|
8816
9009
|
);
|
|
8817
9010
|
const o = t.apiKey ?? Z.apiKey, r = t.appId ?? Z.appId, s = t.measurementId ?? Z.measurementId, a = t.environment ?? "production";
|
|
8818
|
-
this._endpoints = { ...
|
|
9011
|
+
this._endpoints = { ...ie[a], ...t.endpoints }, this._isEmulator = a === "emulator", this._verbose = t.verbose ?? !1, this._app = xe().find((g) => g.name === "[DEFAULT]") ?? Ce({
|
|
8819
9012
|
apiKey: o,
|
|
8820
9013
|
appId: r,
|
|
8821
9014
|
measurementId: s,
|
|
8822
9015
|
authDomain: `${xt}.firebaseapp.com`,
|
|
8823
9016
|
projectId: xt,
|
|
8824
|
-
messagingSenderId:
|
|
8825
|
-
}), this.auth = new
|
|
8826
|
-
const n =
|
|
8827
|
-
this._isEmulator && (
|
|
8828
|
-
const d = new kt({
|
|
9017
|
+
messagingSenderId: no
|
|
9018
|
+
}), this.auth = new $t(this._app, this._isEmulator, this._endpoints), this.projects = new Wt(this.auth, this._app, this._isEmulator, this._endpoints), this._storageRaw = C(this._app, Tt), this._storageProcessed = C(this._app, Rt);
|
|
9019
|
+
const n = C(this._app, Pt), p = C(this._app, At), c = C(this._app, St), h = C(this._app, Ot), d = C(this._app, It);
|
|
9020
|
+
this._isEmulator && (K(this._storageRaw, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), K(this._storageProcessed, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort)), this.api = this._buildApi(this.projects), new Et({
|
|
8829
9021
|
storageRaw: this._storageRaw,
|
|
8830
9022
|
storageProcessed: this._storageProcessed,
|
|
8831
9023
|
storagePublic: n,
|
|
8832
9024
|
storageLogs: p,
|
|
8833
9025
|
storageChatSessions: c,
|
|
8834
|
-
storagePersistence: h
|
|
8835
|
-
|
|
8836
|
-
this.storage = new
|
|
9026
|
+
storagePersistence: h,
|
|
9027
|
+
storageSessions: d
|
|
9028
|
+
}), this.storage = new Ut(this.auth, this._endpoints.gatewayUrl), this.profile = new Vt(
|
|
8837
9029
|
this.auth,
|
|
8838
9030
|
this._app,
|
|
8839
9031
|
this._isEmulator,
|
|
8840
9032
|
this._endpoints.gatewayUrl
|
|
8841
|
-
), this.privileges = new
|
|
9033
|
+
), this.privileges = new Qt(this.auth.isSuperAdmin), this._isEmulator && K(h, this._endpoints.storageEmulatorHost, this._endpoints.storageEmulatorPort), this.cache = new Yt(h);
|
|
8842
9034
|
}
|
|
8843
9035
|
/**
|
|
8844
9036
|
* Create a `Cue` instance from an already-initialized Firebase app.
|
|
@@ -8857,34 +9049,35 @@ class fe {
|
|
|
8857
9049
|
* });
|
|
8858
9050
|
*/
|
|
8859
9051
|
static fromApp(t, e = {}) {
|
|
8860
|
-
const o = e.environment ?? "production", r = { ...
|
|
9052
|
+
const o = e.environment ?? "production", r = { ...ie[o], ...e.endpoints }, s = new $t(t, !1, r), a = new Wt(s, t, !1, r), n = C(t, Tt), p = C(t, Rt), c = C(t, Pt), h = C(t, At), d = C(t, St), g = C(t, Ot), u = C(t, It), m = new Et({
|
|
8861
9053
|
storageRaw: n,
|
|
8862
9054
|
storageProcessed: p,
|
|
8863
9055
|
storagePublic: c,
|
|
8864
9056
|
storageLogs: h,
|
|
8865
9057
|
storageChatSessions: d,
|
|
8866
|
-
storagePersistence: g
|
|
8867
|
-
|
|
8868
|
-
m.
|
|
8869
|
-
|
|
8870
|
-
|
|
9058
|
+
storagePersistence: g,
|
|
9059
|
+
storageSessions: u
|
|
9060
|
+
}), f = new jr(s, a, m, r.gatewayUrl), _ = new Mt(s, r.gatewayUrl, a, f);
|
|
9061
|
+
f._bindApi(_);
|
|
9062
|
+
const w = new Vt(s, t, !1, r.gatewayUrl), E = Object.create(Ee.prototype), I = new Qt(s.isSuperAdmin), v = new Yt(g), b = new Ut(s, r.gatewayUrl);
|
|
9063
|
+
return Object.assign(E, {
|
|
8871
9064
|
_app: t,
|
|
8872
9065
|
_endpoints: r,
|
|
8873
9066
|
_isEmulator: o === "emulator",
|
|
8874
9067
|
_storageRaw: n,
|
|
8875
9068
|
_storageProcessed: p,
|
|
8876
9069
|
auth: s,
|
|
8877
|
-
api:
|
|
9070
|
+
api: _,
|
|
8878
9071
|
projects: a,
|
|
8879
|
-
profile:
|
|
8880
|
-
privileges:
|
|
8881
|
-
cache:
|
|
8882
|
-
storage:
|
|
8883
|
-
}),
|
|
9072
|
+
profile: w,
|
|
9073
|
+
privileges: I,
|
|
9074
|
+
cache: v,
|
|
9075
|
+
storage: b
|
|
9076
|
+
}), E;
|
|
8884
9077
|
}
|
|
8885
9078
|
/** Override in subclasses to provide a custom CueApi (e.g. with sync). */
|
|
8886
9079
|
_buildApi(t) {
|
|
8887
|
-
return new
|
|
9080
|
+
return new Mt(this.auth, this._endpoints.gatewayUrl, t);
|
|
8888
9081
|
}
|
|
8889
9082
|
/** Convenience: get the current user's Firebase ID token */
|
|
8890
9083
|
getToken(t = !1) {
|
|
@@ -8909,7 +9102,7 @@ class fe {
|
|
|
8909
9102
|
get: (r) => this.cache.getQueryCache(t, r).then((s) => s?.results),
|
|
8910
9103
|
set: (r, s) => this.cache.setQueryCache(t, r, { query: r, results: s })
|
|
8911
9104
|
};
|
|
8912
|
-
return new
|
|
9105
|
+
return new Sr(this.api, t, { verbose: this._verbose, ...e, queryCache: o });
|
|
8913
9106
|
}
|
|
8914
9107
|
/**
|
|
8915
9108
|
* Creates a `CueProjectEntities` instance for the given project, with the
|
|
@@ -8933,7 +9126,7 @@ class fe {
|
|
|
8933
9126
|
get: (r) => this.cache.getQueryCache(t, r).then((s) => s?.results),
|
|
8934
9127
|
set: (r, s) => this.cache.setQueryCache(t, r, { query: r, results: s })
|
|
8935
9128
|
};
|
|
8936
|
-
return new
|
|
9129
|
+
return new _e(
|
|
8937
9130
|
this.api,
|
|
8938
9131
|
t,
|
|
8939
9132
|
e?.rdfBase,
|
|
@@ -8964,7 +9157,7 @@ class fe {
|
|
|
8964
9157
|
const a = {
|
|
8965
9158
|
get: (p) => this.cache.getQueryCache(t, p).then((c) => c?.results),
|
|
8966
9159
|
set: (p, c) => this.cache.setQueryCache(t, p, { query: p, results: c })
|
|
8967
|
-
}, n = new
|
|
9160
|
+
}, n = new lt(
|
|
8968
9161
|
this.api,
|
|
8969
9162
|
t,
|
|
8970
9163
|
this.api.language,
|
|
@@ -8979,7 +9172,7 @@ class fe {
|
|
|
8979
9172
|
get: (s) => this.cache.getQueryCache(t, s).then((a) => a?.results),
|
|
8980
9173
|
set: (s, a) => this.cache.setQueryCache(t, s, { query: s, results: a })
|
|
8981
9174
|
};
|
|
8982
|
-
return new
|
|
9175
|
+
return new lt(
|
|
8983
9176
|
this.api,
|
|
8984
9177
|
t,
|
|
8985
9178
|
e?.language ?? this.api.language,
|
|
@@ -8991,30 +9184,32 @@ class fe {
|
|
|
8991
9184
|
}
|
|
8992
9185
|
}
|
|
8993
9186
|
export {
|
|
8994
|
-
|
|
8995
|
-
|
|
9187
|
+
St as B,
|
|
9188
|
+
Ee as C,
|
|
8996
9189
|
Kt as R,
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
|
|
9012
|
-
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9018
|
-
|
|
9019
|
-
|
|
9190
|
+
Mt as a,
|
|
9191
|
+
$t as b,
|
|
9192
|
+
Yt as c,
|
|
9193
|
+
To as d,
|
|
9194
|
+
So as e,
|
|
9195
|
+
mr as f,
|
|
9196
|
+
Qt as g,
|
|
9197
|
+
Vt as h,
|
|
9198
|
+
lt as i,
|
|
9199
|
+
_e as j,
|
|
9200
|
+
Er as k,
|
|
9201
|
+
Sr as l,
|
|
9202
|
+
Wt as m,
|
|
9203
|
+
x as n,
|
|
9204
|
+
Ut as o,
|
|
9205
|
+
jr as p,
|
|
9206
|
+
Co as q,
|
|
9207
|
+
Qr as r,
|
|
9208
|
+
dt as s,
|
|
9209
|
+
gt as t,
|
|
9210
|
+
At as u,
|
|
9211
|
+
Ot as v,
|
|
9212
|
+
Pt as w,
|
|
9213
|
+
It as x,
|
|
9214
|
+
Et as y
|
|
9020
9215
|
};
|