@qaecy/cue-cli 0.0.46 → 0.0.47
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/main.js +450 -30
- package/package.json +1 -1
- package/readme.md +36 -0
package/main.js
CHANGED
|
@@ -372,7 +372,7 @@ var init_md5_builder_node = __esm({
|
|
|
372
372
|
});
|
|
373
373
|
|
|
374
374
|
// apps/desktop/cue-cli/src/main.ts
|
|
375
|
-
var
|
|
375
|
+
var import_commander2 = require("commander");
|
|
376
376
|
var import_fs8 = require("fs");
|
|
377
377
|
var import_path4 = require("path");
|
|
378
378
|
|
|
@@ -4721,6 +4721,53 @@ var prefixCC = {
|
|
|
4721
4721
|
rex: "http://purl.obolibrary.org/obo/REX_"
|
|
4722
4722
|
};
|
|
4723
4723
|
|
|
4724
|
+
// libs/js/prefixes/src/lib/compact-expand.ts
|
|
4725
|
+
var CompactExpand = class _CompactExpand {
|
|
4726
|
+
static _instance;
|
|
4727
|
+
// Opposite map is built once
|
|
4728
|
+
_nsMap;
|
|
4729
|
+
static getInstance() {
|
|
4730
|
+
if (this._instance) {
|
|
4731
|
+
return this._instance;
|
|
4732
|
+
}
|
|
4733
|
+
this._instance = new _CompactExpand();
|
|
4734
|
+
return this._instance;
|
|
4735
|
+
}
|
|
4736
|
+
compactIRI(iri) {
|
|
4737
|
+
let nsMap = this._nsMap;
|
|
4738
|
+
if (nsMap === void 0)
|
|
4739
|
+
nsMap = this._buildNSMap();
|
|
4740
|
+
let ns = iri;
|
|
4741
|
+
if (iri.includes("#"))
|
|
4742
|
+
ns = `${iri.split("#")[0]}#`;
|
|
4743
|
+
else {
|
|
4744
|
+
const parts = iri.split("/");
|
|
4745
|
+
parts.pop();
|
|
4746
|
+
ns = parts.join("/") + "/";
|
|
4747
|
+
}
|
|
4748
|
+
if (ns === void 0)
|
|
4749
|
+
return iri;
|
|
4750
|
+
const pfx = nsMap[ns];
|
|
4751
|
+
if (pfx === void 0)
|
|
4752
|
+
return iri;
|
|
4753
|
+
return iri.replace(ns, `${pfx}:`);
|
|
4754
|
+
}
|
|
4755
|
+
expandIRI(iri) {
|
|
4756
|
+
const prefix = iri.split(":")[0];
|
|
4757
|
+
const ns = prefixCC[prefix] ?? qaecyPrefixes[prefix];
|
|
4758
|
+
return iri.replace(`${prefix}:`, ns);
|
|
4759
|
+
}
|
|
4760
|
+
_buildNSMap() {
|
|
4761
|
+
const map = {};
|
|
4762
|
+
Object.keys(prefixCC).forEach((key) => map[prefixCC[key]] = key);
|
|
4763
|
+
Object.keys(qaecyPrefixes).forEach(
|
|
4764
|
+
(key) => map[qaecyPrefixes[key]] = key
|
|
4765
|
+
);
|
|
4766
|
+
this._nsMap = map;
|
|
4767
|
+
return map;
|
|
4768
|
+
}
|
|
4769
|
+
};
|
|
4770
|
+
|
|
4724
4771
|
// libs/js/sync-tools/src/lib/list-remote-files.ts
|
|
4725
4772
|
async function listRemoteFiles(spaceId, providerId, queryHandler2, verbose = false) {
|
|
4726
4773
|
const firebase = CueFirebase.getInstance();
|
|
@@ -5097,8 +5144,10 @@ var ENDPOINT_CREATE_PROJECT = "/commands/admin/project";
|
|
|
5097
5144
|
var ENDPOINT_SEARCH = "/assistant/search";
|
|
5098
5145
|
var ENDPOINT_FUSEKI_QUERY = "/triplestore/query";
|
|
5099
5146
|
var ENDPOINT_FUSEKI_UPDATE = "/triplestore/update";
|
|
5147
|
+
var ENDPOINT_FUSEKI_SHACL = "/triplestore/shacl";
|
|
5100
5148
|
var ENDPOINT_QLEVER_QUERY = "/qlever-server/qlever/query";
|
|
5101
5149
|
var ENDPOINT_QLEVER_UPDATE = "/qlever-server/qlever/update";
|
|
5150
|
+
var ENDPOINT_QLEVER_SHACL = "/qlever-server/qlever/shacl";
|
|
5102
5151
|
var ENDPOINT_FSS_BATCH = "/commands/file-system-structure/batch";
|
|
5103
5152
|
var MICROSOFT_PROVIDER_ID = "microsoft.com";
|
|
5104
5153
|
var SUPERADMIN_ROLE = "superadmin";
|
|
@@ -5290,6 +5339,49 @@ var CueAuth = class {
|
|
|
5290
5339
|
}
|
|
5291
5340
|
};
|
|
5292
5341
|
|
|
5342
|
+
// libs/js/cue-sdk/src/lib/tables.ts
|
|
5343
|
+
var ENDPOINT_DATA_VIEWS_TABLES = "/data-views/tables";
|
|
5344
|
+
var ENDPOINT_COMMANDS_TABLES = "/commands/tables";
|
|
5345
|
+
var CueTables = class {
|
|
5346
|
+
constructor(_auth, _gatewayUrl) {
|
|
5347
|
+
this._auth = _auth;
|
|
5348
|
+
this._gatewayUrl = _gatewayUrl;
|
|
5349
|
+
}
|
|
5350
|
+
async listTables(projectId) {
|
|
5351
|
+
const response = await this._auth.authenticatedFetch(
|
|
5352
|
+
`${this._gatewayUrl}${ENDPOINT_DATA_VIEWS_TABLES}`,
|
|
5353
|
+
{
|
|
5354
|
+
headers: {
|
|
5355
|
+
"Content-Type": "application/json",
|
|
5356
|
+
"x-project-id": projectId,
|
|
5357
|
+
"cue-project-id": projectId
|
|
5358
|
+
}
|
|
5359
|
+
}
|
|
5360
|
+
);
|
|
5361
|
+
if (!response.ok) {
|
|
5362
|
+
throw new Error(`Failed to list tables: ${response.status} ${response.statusText}`);
|
|
5363
|
+
}
|
|
5364
|
+
return response.json();
|
|
5365
|
+
}
|
|
5366
|
+
async saveTables(tables, projectId) {
|
|
5367
|
+
const response = await this._auth.authenticatedFetch(
|
|
5368
|
+
`${this._gatewayUrl}${ENDPOINT_COMMANDS_TABLES}`,
|
|
5369
|
+
{
|
|
5370
|
+
method: "PUT",
|
|
5371
|
+
headers: {
|
|
5372
|
+
"Content-Type": "application/json",
|
|
5373
|
+
"x-project-id": projectId,
|
|
5374
|
+
"cue-project-id": projectId
|
|
5375
|
+
},
|
|
5376
|
+
body: JSON.stringify(tables)
|
|
5377
|
+
}
|
|
5378
|
+
);
|
|
5379
|
+
if (!response.ok) {
|
|
5380
|
+
throw new Error(`Failed to save tables: ${response.status} ${response.statusText}`);
|
|
5381
|
+
}
|
|
5382
|
+
}
|
|
5383
|
+
};
|
|
5384
|
+
|
|
5293
5385
|
// libs/js/cue-sdk/src/lib/api.ts
|
|
5294
5386
|
var CueApi = class {
|
|
5295
5387
|
constructor(_auth, _gatewayUrl, projects, sync) {
|
|
@@ -5297,6 +5389,14 @@ var CueApi = class {
|
|
|
5297
5389
|
this._gatewayUrl = _gatewayUrl;
|
|
5298
5390
|
this.projects = projects;
|
|
5299
5391
|
this.sync = sync;
|
|
5392
|
+
this.tables = new CueTables(_auth, _gatewayUrl);
|
|
5393
|
+
}
|
|
5394
|
+
tables;
|
|
5395
|
+
/** Active language used for language-sensitive SPARQL queries across all project classes. */
|
|
5396
|
+
language = "en";
|
|
5397
|
+
/** Updates the active language. All project classes (`CueProjectSchema`, `CueProjectDocuments`, `CueProjectEntities`) read this at query time. */
|
|
5398
|
+
setLanguage(lang) {
|
|
5399
|
+
this.language = lang;
|
|
5300
5400
|
}
|
|
5301
5401
|
/**
|
|
5302
5402
|
* Returns standard authentication headers for the current user.
|
|
@@ -5368,6 +5468,57 @@ var CueApi = class {
|
|
|
5368
5468
|
}
|
|
5369
5469
|
return response.json();
|
|
5370
5470
|
}
|
|
5471
|
+
/**
|
|
5472
|
+
* Validate a SHACL shape against the project's triplestore.
|
|
5473
|
+
*
|
|
5474
|
+
* @param shape - SHACL shapes graph in Turtle syntax.
|
|
5475
|
+
* @param projectId - Project to validate against.
|
|
5476
|
+
* @param options - `format`: `'json-ld'` (default, structured result) or `'turtle'` (raw string).
|
|
5477
|
+
* `verbose`: include server-side timing logs.
|
|
5478
|
+
*
|
|
5479
|
+
* Returns a {@link ShaclValidationReport} for JSON-LD, or a Turtle string.
|
|
5480
|
+
*/
|
|
5481
|
+
async shacl(shape, projectId, options) {
|
|
5482
|
+
const fmt = options?.format ?? "json-ld";
|
|
5483
|
+
const accept = fmt === "turtle" ? "text/turtle" : "application/ld+json";
|
|
5484
|
+
if (options?.graphType === "fuseki") {
|
|
5485
|
+
const response2 = await this._auth.authenticatedFetch(
|
|
5486
|
+
`${this._gatewayUrl}${ENDPOINT_FUSEKI_SHACL}`,
|
|
5487
|
+
{
|
|
5488
|
+
method: "POST",
|
|
5489
|
+
headers: {
|
|
5490
|
+
"Content-Type": "text/turtle",
|
|
5491
|
+
"Accept": accept,
|
|
5492
|
+
"x-project-id": projectId,
|
|
5493
|
+
"cue-project-id": projectId
|
|
5494
|
+
},
|
|
5495
|
+
body: shape
|
|
5496
|
+
}
|
|
5497
|
+
);
|
|
5498
|
+
if (!response2.ok) {
|
|
5499
|
+
const msg = await response2.text().catch(() => "");
|
|
5500
|
+
throw new Error(`SHACL validation failed: ${response2.status} ${response2.statusText}${msg ? " \u2014 " + msg.slice(0, 200) : ""}`);
|
|
5501
|
+
}
|
|
5502
|
+
return fmt === "turtle" ? response2.text() : response2.json();
|
|
5503
|
+
}
|
|
5504
|
+
const url = `${this._gatewayUrl}${ENDPOINT_QLEVER_SHACL}${options?.verbose ? "?verbose=true" : ""}`;
|
|
5505
|
+
const body = new URLSearchParams({ shape });
|
|
5506
|
+
const response = await this._auth.authenticatedFetch(url, {
|
|
5507
|
+
method: "POST",
|
|
5508
|
+
headers: {
|
|
5509
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
5510
|
+
"Accept": accept,
|
|
5511
|
+
"x-project-id": projectId,
|
|
5512
|
+
"cue-project-id": projectId
|
|
5513
|
+
},
|
|
5514
|
+
body
|
|
5515
|
+
});
|
|
5516
|
+
if (!response.ok) {
|
|
5517
|
+
const msg = await response.text().catch(() => "");
|
|
5518
|
+
throw new Error(`SHACL validation failed: ${response.status} ${response.statusText}${msg ? " \u2014 " + msg.slice(0, 200) : ""}`);
|
|
5519
|
+
}
|
|
5520
|
+
return fmt === "turtle" ? response.text() : response.json();
|
|
5521
|
+
}
|
|
5371
5522
|
async getConsumption(projectId) {
|
|
5372
5523
|
const response = await this._auth.authenticatedFetch(
|
|
5373
5524
|
`${this._gatewayUrl}${ENDPOINT_CONSUMPTION}`,
|
|
@@ -7552,19 +7703,20 @@ var CueProjectSchema = class {
|
|
|
7552
7703
|
this._projectId = _projectId;
|
|
7553
7704
|
this._queryCache = _queryCache;
|
|
7554
7705
|
this._graphType = _graphType;
|
|
7555
|
-
this.
|
|
7706
|
+
this._currentLang = language;
|
|
7707
|
+
this._api.setLanguage(language);
|
|
7556
7708
|
this._contentCategories = new CueSignal([]);
|
|
7557
7709
|
this._entityCategories = new CueSignal([]);
|
|
7558
7710
|
this._relationships = new CueSignal([]);
|
|
7559
7711
|
this.availableContentCategories = this._contentCategories.asReadonly();
|
|
7560
7712
|
this.availableEntityCategories = this._entityCategories.asReadonly();
|
|
7561
7713
|
this.availableEntityRelationships = this._relationships.asReadonly();
|
|
7562
|
-
this._load(language).catch(
|
|
7714
|
+
this.ready = this._load(language).catch(
|
|
7563
7715
|
(err) => console.error("[CueProjectSchema] Initial load failed:", err)
|
|
7564
7716
|
);
|
|
7565
7717
|
}
|
|
7566
7718
|
_cache = /* @__PURE__ */ new Map();
|
|
7567
|
-
|
|
7719
|
+
_currentLang;
|
|
7568
7720
|
_contentCategories;
|
|
7569
7721
|
_entityCategories;
|
|
7570
7722
|
_relationships;
|
|
@@ -7574,9 +7726,14 @@ var CueProjectSchema = class {
|
|
|
7574
7726
|
availableEntityCategories;
|
|
7575
7727
|
/** Currently active entity relationship types for the selected language. */
|
|
7576
7728
|
availableEntityRelationships;
|
|
7729
|
+
/**
|
|
7730
|
+
* Resolves when the initial schema load for the constructor language has
|
|
7731
|
+
* completed (or failed). Await this before reading signal values imperatively.
|
|
7732
|
+
*/
|
|
7733
|
+
ready;
|
|
7577
7734
|
/** Returns the currently active language. */
|
|
7578
7735
|
get language() {
|
|
7579
|
-
return this.
|
|
7736
|
+
return this._api.language;
|
|
7580
7737
|
}
|
|
7581
7738
|
/**
|
|
7582
7739
|
* Switch the active language. If the data for this language has already been
|
|
@@ -7584,9 +7741,10 @@ var CueProjectSchema = class {
|
|
|
7584
7741
|
* is triggered.
|
|
7585
7742
|
*/
|
|
7586
7743
|
setLanguage(lang) {
|
|
7587
|
-
if (this.
|
|
7744
|
+
if (this._currentLang === lang)
|
|
7588
7745
|
return;
|
|
7589
|
-
this.
|
|
7746
|
+
this._currentLang = lang;
|
|
7747
|
+
this._api.setLanguage(lang);
|
|
7590
7748
|
this._load(lang).catch(
|
|
7591
7749
|
(err) => console.error("[CueProjectSchema] Language switch failed:", err)
|
|
7592
7750
|
);
|
|
@@ -7596,7 +7754,7 @@ var CueProjectSchema = class {
|
|
|
7596
7754
|
* Useful when the triplestore data has changed.
|
|
7597
7755
|
*/
|
|
7598
7756
|
async refresh() {
|
|
7599
|
-
const lang = this.
|
|
7757
|
+
const lang = this._api.language;
|
|
7600
7758
|
this._cache.delete(lang);
|
|
7601
7759
|
await this._load(lang);
|
|
7602
7760
|
}
|
|
@@ -7622,7 +7780,7 @@ var CueProjectSchema = class {
|
|
|
7622
7780
|
},
|
|
7623
7781
|
(snapshot) => {
|
|
7624
7782
|
this._cache.set(lang, snapshot);
|
|
7625
|
-
if (this.
|
|
7783
|
+
if (this._currentLang === lang)
|
|
7626
7784
|
this._apply(snapshot);
|
|
7627
7785
|
},
|
|
7628
7786
|
this._queryCache
|
|
@@ -7711,7 +7869,9 @@ var CueProjectEntities = class {
|
|
|
7711
7869
|
baseURL;
|
|
7712
7870
|
// ── Internal writable slices ───────────────────────────────────────────────
|
|
7713
7871
|
_entityDetails = new CueSignal({});
|
|
7714
|
-
_entityDocuments = new CueSignal(
|
|
7872
|
+
_entityDocuments = new CueSignal(
|
|
7873
|
+
{}
|
|
7874
|
+
);
|
|
7715
7875
|
_entityRelationships = new CueSignal({});
|
|
7716
7876
|
_entityOSMMap = new CueSignal({});
|
|
7717
7877
|
_osmWKTMap = new CueSignal({});
|
|
@@ -7753,7 +7913,10 @@ var CueProjectEntities = class {
|
|
|
7753
7913
|
this._entityGraph.set(void 0);
|
|
7754
7914
|
this._fetchingOSMIds.clear();
|
|
7755
7915
|
this._fetchEntityGraph().catch(
|
|
7756
|
-
(err) => console.error(
|
|
7916
|
+
(err) => console.error(
|
|
7917
|
+
"[CueProjectEntities] Entity graph fetch failed after reset:",
|
|
7918
|
+
err
|
|
7919
|
+
)
|
|
7757
7920
|
);
|
|
7758
7921
|
}
|
|
7759
7922
|
// ── Public imperative API ──────────────────────────────────────────────────
|
|
@@ -7764,7 +7927,9 @@ var CueProjectEntities = class {
|
|
|
7764
7927
|
* Data is merged into `entityInfoMap` once the SPARQL response arrives.
|
|
7765
7928
|
*/
|
|
7766
7929
|
requestEntityData(uuids, includeMentionCount = false) {
|
|
7767
|
-
const newUUIDs = uuids.filter(
|
|
7930
|
+
const newUUIDs = uuids.filter(
|
|
7931
|
+
(id) => this._entityDetails.get()[id] === void 0
|
|
7932
|
+
);
|
|
7768
7933
|
if (newUUIDs.length === 0)
|
|
7769
7934
|
return;
|
|
7770
7935
|
const values = newUUIDs.map((id) => `r:${id}`).join(" ");
|
|
@@ -7782,7 +7947,9 @@ WHERE {
|
|
|
7782
7947
|
GROUP BY ?id ?mentionCount`;
|
|
7783
7948
|
this._api.sparql(q, this._projectId, this._graphType).then((data) => {
|
|
7784
7949
|
const result = data;
|
|
7785
|
-
const updates = {
|
|
7950
|
+
const updates = {
|
|
7951
|
+
...this._entityDetails.get()
|
|
7952
|
+
};
|
|
7786
7953
|
result.results.bindings.forEach((b) => {
|
|
7787
7954
|
if (!b["id"])
|
|
7788
7955
|
return;
|
|
@@ -7806,7 +7973,9 @@ GROUP BY ?id ?mentionCount`;
|
|
|
7806
7973
|
* query and merged into `entityInfoMap` reactively once it arrives.
|
|
7807
7974
|
*/
|
|
7808
7975
|
async requestEntityLocations(uuids) {
|
|
7809
|
-
const newUUIDs = uuids.filter(
|
|
7976
|
+
const newUUIDs = uuids.filter(
|
|
7977
|
+
(id) => this._entityOSMMap.get()[id] === void 0
|
|
7978
|
+
);
|
|
7810
7979
|
if (newUUIDs.length === 0)
|
|
7811
7980
|
return;
|
|
7812
7981
|
const osmInit = { ...this._entityOSMMap.get() };
|
|
@@ -7842,7 +8011,11 @@ WHERE {
|
|
|
7842
8011
|
}
|
|
7843
8012
|
BIND(REPLACE(STR(?iri), "^.*/([^/]*)$", "$1") AS ?id)
|
|
7844
8013
|
}`;
|
|
7845
|
-
const data = await this._api.sparql(
|
|
8014
|
+
const data = await this._api.sparql(
|
|
8015
|
+
q,
|
|
8016
|
+
this._projectId,
|
|
8017
|
+
this._graphType
|
|
8018
|
+
);
|
|
7846
8019
|
const update = { ...this._entityOSMMap.get() };
|
|
7847
8020
|
data.results.bindings.forEach((b) => {
|
|
7848
8021
|
if (!b["id"] || !b["osm"])
|
|
@@ -7881,7 +8054,10 @@ WHERE {
|
|
|
7881
8054
|
this._fetchIncomingRelationships(iri)
|
|
7882
8055
|
]);
|
|
7883
8056
|
const result = { outgoing, incoming };
|
|
7884
|
-
this._entityRelationships.set({
|
|
8057
|
+
this._entityRelationships.set({
|
|
8058
|
+
...this._entityRelationships.get(),
|
|
8059
|
+
[uuid]: result
|
|
8060
|
+
});
|
|
7885
8061
|
return result;
|
|
7886
8062
|
}
|
|
7887
8063
|
/**
|
|
@@ -7905,11 +8081,111 @@ WHERE {
|
|
|
7905
8081
|
qcy:about ?iri .
|
|
7906
8082
|
BIND(REPLACE(STR(?doc), "^.*/([^/]*)$", "$1") AS ?id)
|
|
7907
8083
|
}`;
|
|
7908
|
-
const data = await this._api.sparql(
|
|
8084
|
+
const data = await this._api.sparql(
|
|
8085
|
+
q,
|
|
8086
|
+
this._projectId,
|
|
8087
|
+
this._graphType
|
|
8088
|
+
);
|
|
7909
8089
|
const ids = data.results.bindings.filter((b) => b["id"] !== void 0).map((b) => b["id"].value);
|
|
7910
8090
|
this._entityDocuments.set({ ...this._entityDocuments.get(), [uuid]: ids });
|
|
7911
8091
|
return ids;
|
|
7912
8092
|
}
|
|
8093
|
+
/**
|
|
8094
|
+
* Fetches all `qcy:EntityCategory` IRIs and their preferred labels for this
|
|
8095
|
+
* project. Uses `api.language` (default `'en'`);
|
|
8096
|
+
* falls back to an untagged label when no match is found.
|
|
8097
|
+
*/
|
|
8098
|
+
async contentCategoriesInProject(orderByOccurences = true) {
|
|
8099
|
+
const language = this._api.language;
|
|
8100
|
+
const q = `PREFIX qcy: <${qaecyPrefixes["qcy"]}>
|
|
8101
|
+
PREFIX skos: <${prefixCC["skos"]}>
|
|
8102
|
+
SELECT ?iri (SAMPLE(?l) AS ?label) ?count
|
|
8103
|
+
WHERE {
|
|
8104
|
+
?iri a qcy:EntityCategory .
|
|
8105
|
+
OPTIONAL { ?iri skos:prefLabel ?lang_label FILTER(LANG(?lang_label) = "${language}") }
|
|
8106
|
+
OPTIONAL { ?iri skos:prefLabel ?no_lang_label }
|
|
8107
|
+
BIND(COALESCE(?lang_label, ?no_lang_label) AS ?l)
|
|
8108
|
+
${orderByOccurences ? "{ SELECT (COUNT(?x) AS ?count) ?iri where { ?x a qcy:CanonicalEntity ; qcy:hasEntityCategory ?iri } GROUP BY ?iri }" : ""}
|
|
8109
|
+
}
|
|
8110
|
+
GROUP BY ?iri ?count
|
|
8111
|
+
ORDER BY ${orderByOccurences ? "DESC(?count)" : "ASC(?label)"}`;
|
|
8112
|
+
const data = await this._api.sparql(
|
|
8113
|
+
q,
|
|
8114
|
+
this._projectId,
|
|
8115
|
+
this._graphType
|
|
8116
|
+
);
|
|
8117
|
+
return data.results.bindings.filter((b) => b["iri"] !== void 0).map((b) => {
|
|
8118
|
+
const count = b["count"] ? parseInt(b["count"].value, 10) : 0;
|
|
8119
|
+
const label = b["label"]?.value ?? b["iri"].value.split("#").at(-1);
|
|
8120
|
+
const labelWithCount = count > 0 ? `${label} (${count})` : label ?? "";
|
|
8121
|
+
return {
|
|
8122
|
+
iri: b["iri"].value,
|
|
8123
|
+
label: labelWithCount
|
|
8124
|
+
};
|
|
8125
|
+
});
|
|
8126
|
+
}
|
|
8127
|
+
async buildSummaryGraph(format) {
|
|
8128
|
+
const q = `PREFIX qcy: <${qaecyPrefixes["qcy"]}>
|
|
8129
|
+
SELECT
|
|
8130
|
+
?sourceCat
|
|
8131
|
+
?predicate
|
|
8132
|
+
?targetCat
|
|
8133
|
+
(COUNT(*) AS ?weight)
|
|
8134
|
+
WHERE {
|
|
8135
|
+
?s a qcy:CanonicalEntity ;
|
|
8136
|
+
qcy:hasEntityCategory ?sourceCat .
|
|
8137
|
+
?o a qcy:CanonicalEntity ;
|
|
8138
|
+
qcy:hasEntityCategory ?targetCat .
|
|
8139
|
+
?s ?predicate ?o .
|
|
8140
|
+
FILTER(isIRI(?s) && isIRI(?o))
|
|
8141
|
+
FILTER(?predicate != qcy:relatedEntity)
|
|
8142
|
+
}
|
|
8143
|
+
GROUP BY ?sourceCat ?predicate ?targetCat
|
|
8144
|
+
ORDER BY DESC(?weight)`;
|
|
8145
|
+
const data = await this._api.sparql(
|
|
8146
|
+
q,
|
|
8147
|
+
this._projectId,
|
|
8148
|
+
this._graphType
|
|
8149
|
+
);
|
|
8150
|
+
const bindings = data.results.bindings.filter(
|
|
8151
|
+
(b) => b["sourceCat"] && b["predicate"] && b["targetCat"]
|
|
8152
|
+
);
|
|
8153
|
+
if (format === "graph") {
|
|
8154
|
+
const irisSet = /* @__PURE__ */ new Set();
|
|
8155
|
+
const relations = [];
|
|
8156
|
+
for (const b of bindings) {
|
|
8157
|
+
const sourceID = b["sourceCat"].value;
|
|
8158
|
+
const predicate = b["predicate"].value;
|
|
8159
|
+
const targetID = b["targetCat"].value;
|
|
8160
|
+
const weight = parseInt(b["weight"].value, 10);
|
|
8161
|
+
irisSet.add(sourceID);
|
|
8162
|
+
irisSet.add(targetID);
|
|
8163
|
+
relations.push({ sourceID, predicate, targetID, weight });
|
|
8164
|
+
}
|
|
8165
|
+
return {
|
|
8166
|
+
entities: Array.from(irisSet).map((iri) => ({ iri })),
|
|
8167
|
+
relations
|
|
8168
|
+
};
|
|
8169
|
+
}
|
|
8170
|
+
if (format === "md") {
|
|
8171
|
+
const ce = CompactExpand.getInstance();
|
|
8172
|
+
const rows = bindings.map((b) => ({
|
|
8173
|
+
src: ce.compactIRI(b["sourceCat"].value),
|
|
8174
|
+
pred: ce.compactIRI(b["predicate"].value),
|
|
8175
|
+
tgt: ce.compactIRI(b["targetCat"].value),
|
|
8176
|
+
weight: parseInt(b["weight"].value, 10)
|
|
8177
|
+
}));
|
|
8178
|
+
if (rows.length === 0)
|
|
8179
|
+
return "(no results)";
|
|
8180
|
+
const maxSrc = Math.max(...rows.map((r) => r.src.length));
|
|
8181
|
+
const maxPred = Math.max(...rows.map((r) => r.pred.length));
|
|
8182
|
+
const maxTgt = Math.max(...rows.map((r) => r.tgt.length));
|
|
8183
|
+
return rows.map(
|
|
8184
|
+
(r) => `${r.src.padEnd(maxSrc)} -> ${r.pred.padEnd(maxPred)} -> ${r.tgt.padEnd(maxTgt)} (${r.weight})`
|
|
8185
|
+
).join("\n");
|
|
8186
|
+
}
|
|
8187
|
+
return data;
|
|
8188
|
+
}
|
|
7913
8189
|
// ── Private helpers ────────────────────────────────────────────────────────
|
|
7914
8190
|
_computeEntityInfoMap() {
|
|
7915
8191
|
const details = this._entityDetails.get();
|
|
@@ -7983,7 +8259,11 @@ WHERE {
|
|
|
7983
8259
|
FILTER(?rel != qcy:relatedEntity)
|
|
7984
8260
|
}
|
|
7985
8261
|
GROUP BY ?rel ?related`;
|
|
7986
|
-
const data = await this._api.sparql(
|
|
8262
|
+
const data = await this._api.sparql(
|
|
8263
|
+
q,
|
|
8264
|
+
this._projectId,
|
|
8265
|
+
this._graphType
|
|
8266
|
+
);
|
|
7987
8267
|
const result = [];
|
|
7988
8268
|
const detailsUpdate = { ...this._entityDetails.get() };
|
|
7989
8269
|
data.results.bindings.forEach((b) => {
|
|
@@ -8017,7 +8297,11 @@ WHERE {
|
|
|
8017
8297
|
FILTER(?rel != qcy:relatedEntity)
|
|
8018
8298
|
}
|
|
8019
8299
|
GROUP BY ?rel ?relating`;
|
|
8020
|
-
const data = await this._api.sparql(
|
|
8300
|
+
const data = await this._api.sparql(
|
|
8301
|
+
q,
|
|
8302
|
+
this._projectId,
|
|
8303
|
+
this._graphType
|
|
8304
|
+
);
|
|
8021
8305
|
const result = [];
|
|
8022
8306
|
const detailsUpdate = { ...this._entityDetails.get() };
|
|
8023
8307
|
data.results.bindings.forEach((b) => {
|
|
@@ -8052,7 +8336,11 @@ GROUP BY ?e1Cat ?e2Cat`;
|
|
|
8052
8336
|
await staleWhileRevalidate(
|
|
8053
8337
|
q,
|
|
8054
8338
|
async () => {
|
|
8055
|
-
const data = await this._api.sparql(
|
|
8339
|
+
const data = await this._api.sparql(
|
|
8340
|
+
q,
|
|
8341
|
+
this._projectId,
|
|
8342
|
+
this._graphType
|
|
8343
|
+
);
|
|
8056
8344
|
const entities = [];
|
|
8057
8345
|
const relations = [];
|
|
8058
8346
|
data.results.bindings.forEach((b) => {
|
|
@@ -8109,7 +8397,11 @@ SELECT * WHERE {
|
|
|
8109
8397
|
?s geo:hasGeometry/geo:asWKT ?wkt
|
|
8110
8398
|
}
|
|
8111
8399
|
}`;
|
|
8112
|
-
const data = await this._api.sparql(
|
|
8400
|
+
const data = await this._api.sparql(
|
|
8401
|
+
q,
|
|
8402
|
+
this._projectId,
|
|
8403
|
+
this._graphType
|
|
8404
|
+
);
|
|
8113
8405
|
const update = { ...this._osmWKTMap.get() };
|
|
8114
8406
|
data.results.bindings.forEach((b) => {
|
|
8115
8407
|
if (!b["s"] || !b["wkt"])
|
|
@@ -8129,13 +8421,14 @@ var CueProjectDocuments = class {
|
|
|
8129
8421
|
this._queryCache = _queryCache;
|
|
8130
8422
|
this._graphType = _graphType;
|
|
8131
8423
|
this.baseURL = `${rdfBase}${_projectId}/`;
|
|
8132
|
-
this.
|
|
8424
|
+
this._currentLang = language ?? this._api.language;
|
|
8133
8425
|
this.documentInfoMap = this._documentInfoMap.asReadonly();
|
|
8134
8426
|
this.projectDocumentsData = this._projectDocumentsData.asReadonly();
|
|
8135
8427
|
}
|
|
8136
8428
|
/** Full RDF base URL for this project, e.g. `https://cue.qaecy.com/r/{pid}/` */
|
|
8137
8429
|
baseURL;
|
|
8138
|
-
|
|
8430
|
+
/** Tracks the language for which `_documentInfoMap` is currently populated. */
|
|
8431
|
+
_currentLang;
|
|
8139
8432
|
_documentInfoMap = new CueSignal({});
|
|
8140
8433
|
_projectDocumentsData = new CueSignal({
|
|
8141
8434
|
duplicateCount: 0,
|
|
@@ -8165,9 +8458,10 @@ var CueProjectDocuments = class {
|
|
|
8165
8458
|
* `requestDocumentData()` call.
|
|
8166
8459
|
*/
|
|
8167
8460
|
setLanguage(lang) {
|
|
8168
|
-
if (this.
|
|
8461
|
+
if (this._currentLang === lang)
|
|
8169
8462
|
return;
|
|
8170
|
-
this.
|
|
8463
|
+
this._currentLang = lang;
|
|
8464
|
+
this._api.setLanguage(lang);
|
|
8171
8465
|
this._documentInfoMap.set({});
|
|
8172
8466
|
}
|
|
8173
8467
|
// ── Public API ─────────────────────────────────────────────────────────────
|
|
@@ -8209,7 +8503,7 @@ var CueProjectDocuments = class {
|
|
|
8209
8503
|
if (newUUIDs.length === 0)
|
|
8210
8504
|
return;
|
|
8211
8505
|
const values = newUUIDs.map((id) => `r:${id}`).join(" ");
|
|
8212
|
-
const lang = this.
|
|
8506
|
+
const lang = this._api.language;
|
|
8213
8507
|
const q = `PREFIX qcy: <${qaecyPrefixes["qcy"]}>
|
|
8214
8508
|
PREFIX r: <${this.baseURL}>
|
|
8215
8509
|
SELECT ?id ?contentIRI ?suffix ?size ?subject ?summary
|
|
@@ -8262,6 +8556,21 @@ GROUP BY ?id ?contentIRI ?suffix ?size ?subject ?summary`;
|
|
|
8262
8556
|
(err) => console.error("[CueProjectDocuments] requestDocumentData failed:", err)
|
|
8263
8557
|
);
|
|
8264
8558
|
}
|
|
8559
|
+
/**
|
|
8560
|
+
* Returns a single arbitrary file path from the project's triplestore.
|
|
8561
|
+
* Useful for pre-filling path-based query inputs with a realistic example.
|
|
8562
|
+
*/
|
|
8563
|
+
async randomFilePath() {
|
|
8564
|
+
const q = `PREFIX qcy: <${qaecyPrefixes["qcy"]}>
|
|
8565
|
+
SELECT ?path
|
|
8566
|
+
WHERE {
|
|
8567
|
+
?fl a qcy:FileLocation ;
|
|
8568
|
+
qcy:filePath ?path .
|
|
8569
|
+
}
|
|
8570
|
+
LIMIT 1`;
|
|
8571
|
+
const data = await this._api.sparql(q, this._projectId, this._graphType);
|
|
8572
|
+
return data.results.bindings[0]?.["path"]?.value ?? null;
|
|
8573
|
+
}
|
|
8265
8574
|
// ── Private helpers ────────────────────────────────────────────────────────
|
|
8266
8575
|
async _fetchDocumentsBySuffix() {
|
|
8267
8576
|
return this._runDocumentsBySuffixQuery(this._buildDocumentsBySuffixQuery());
|
|
@@ -8364,6 +8673,7 @@ var CueProjectView = class {
|
|
|
8364
8673
|
this.availableContentCategories = this.schema.availableContentCategories;
|
|
8365
8674
|
this.availableEntityCategories = this.schema.availableEntityCategories;
|
|
8366
8675
|
this.availableEntityRelationships = this.schema.availableEntityRelationships;
|
|
8676
|
+
this.schemaReady = this.schema.ready;
|
|
8367
8677
|
this.entityInfoMap = this.entities.entityInfoMap;
|
|
8368
8678
|
this.entityGraph = this.entities.entityGraph;
|
|
8369
8679
|
this.documentInfoMap = this.documents.documentInfoMap;
|
|
@@ -8384,6 +8694,11 @@ var CueProjectView = class {
|
|
|
8384
8694
|
availableEntityCategories;
|
|
8385
8695
|
/** Available entity relationship types. Auto-fetched on init. */
|
|
8386
8696
|
availableEntityRelationships;
|
|
8697
|
+
/**
|
|
8698
|
+
* Resolves when the initial schema load has completed. Await before reading
|
|
8699
|
+
* schema signal values imperatively.
|
|
8700
|
+
*/
|
|
8701
|
+
schemaReady;
|
|
8387
8702
|
/** Merged per-entity detail map. Populated lazily via `requestEntityData()` etc. */
|
|
8388
8703
|
entityInfoMap;
|
|
8389
8704
|
/** Project-level entity co-occurrence graph. Fetched once on init. */
|
|
@@ -11201,10 +11516,17 @@ async function syncHandler(options) {
|
|
|
11201
11516
|
process.exit(0);
|
|
11202
11517
|
} catch (err) {
|
|
11203
11518
|
const msg = err instanceof Error ? err.message : String(err);
|
|
11519
|
+
const cause = err instanceof Error ? err.cause : void 0;
|
|
11520
|
+
const causeCode = cause instanceof Error ? cause.code : void 0;
|
|
11521
|
+
const causeMsg = cause instanceof Error ? cause.message : void 0;
|
|
11522
|
+
const isTimeout = causeCode === "UND_ERR_HEADERS_TIMEOUT" || causeCode === "UND_ERR_BODY_TIMEOUT" || causeCode === "UND_ERR_CONNECT_TIMEOUT" || causeMsg?.includes("Timeout") || msg.includes("fetch failed");
|
|
11204
11523
|
if (msg.includes("GRAPH_UNAVAILABLE")) {
|
|
11205
11524
|
console.error("The knowledge graph for this project has no database configured. Contact your administrator or check the project setup.");
|
|
11206
|
-
} else if (msg.includes("GRAPH_TIMEOUT")) {
|
|
11207
|
-
console.error("Could not reach the
|
|
11525
|
+
} else if (msg.includes("GRAPH_TIMEOUT") || isTimeout) {
|
|
11526
|
+
console.error("Could not reach the QAECY API \u2014 the request timed out or the server could not be reached.");
|
|
11527
|
+
console.error("Check your internet connection and try again. If the problem persists, the service may be temporarily unavailable.");
|
|
11528
|
+
if (verbose && causeCode)
|
|
11529
|
+
console.error(` Cause: ${causeMsg ?? causeCode}`);
|
|
11208
11530
|
} else if (msg.includes("METADATA_SYNC_FAILED")) {
|
|
11209
11531
|
console.error("Metadata sync failed. Try again.");
|
|
11210
11532
|
} else if (msg.includes("LEDGER_WRITE_FAILED") || msg.includes("File structure batch POST failed")) {
|
|
@@ -11212,7 +11534,13 @@ async function syncHandler(options) {
|
|
|
11212
11534
|
"Failed communication with the knowledge graph. The files are up to date but metadata is not. Run the tool again to sync metadata. This is a swift job."
|
|
11213
11535
|
);
|
|
11214
11536
|
} else {
|
|
11215
|
-
console.error("
|
|
11537
|
+
console.error("An unexpected error occurred during sync.");
|
|
11538
|
+
if (verbose) {
|
|
11539
|
+
console.error("Details:", err);
|
|
11540
|
+
} else {
|
|
11541
|
+
console.error(` ${msg}`);
|
|
11542
|
+
console.error("Re-run with --verbose for more details.");
|
|
11543
|
+
}
|
|
11216
11544
|
}
|
|
11217
11545
|
process.exit(1);
|
|
11218
11546
|
}
|
|
@@ -11675,6 +12003,97 @@ Project created \u2705`);
|
|
|
11675
12003
|
}
|
|
11676
12004
|
}
|
|
11677
12005
|
|
|
12006
|
+
// apps/desktop/cue-cli/src/cue-cli-app-builder-tools.ts
|
|
12007
|
+
var import_commander = require("commander");
|
|
12008
|
+
async function buildCueClient(options) {
|
|
12009
|
+
const key = options.key ?? process.env["CUE_API_KEY"];
|
|
12010
|
+
if (!key) {
|
|
12011
|
+
console.error("API key is required. Provide it via --key or CUE_API_KEY env variable.");
|
|
12012
|
+
process.exit(1);
|
|
12013
|
+
}
|
|
12014
|
+
const cue = new CueNode({
|
|
12015
|
+
apiKey: FIREBASE_CONFIG().apiKey,
|
|
12016
|
+
appId: FIREBASE_CONFIG().appId,
|
|
12017
|
+
measurementId: FIREBASE_CONFIG().measurementId,
|
|
12018
|
+
environment: options.emulators ? "emulator" : "production",
|
|
12019
|
+
...options.emulators ? { endpoints: getEmulatorEndpoints() } : {}
|
|
12020
|
+
});
|
|
12021
|
+
await cue.auth.signInWithApiKey(key);
|
|
12022
|
+
return cue;
|
|
12023
|
+
}
|
|
12024
|
+
async function listProjectsHandler(options) {
|
|
12025
|
+
try {
|
|
12026
|
+
const cue = await buildCueClient(options);
|
|
12027
|
+
if (options.verbose)
|
|
12028
|
+
console.error("Fetching projects...");
|
|
12029
|
+
const projects = await cue.api.projects.listProjects();
|
|
12030
|
+
const output = projects.map((p) => ({
|
|
12031
|
+
id: p.id,
|
|
12032
|
+
name: p.name,
|
|
12033
|
+
organizationID: p.organizationID,
|
|
12034
|
+
isPublic: p.isPublic,
|
|
12035
|
+
graphType: p.projectSettings?.graph?.type ?? "qlever",
|
|
12036
|
+
lastSync: p.lastSync
|
|
12037
|
+
}));
|
|
12038
|
+
console.log(JSON.stringify(output, null, 2));
|
|
12039
|
+
} catch (err) {
|
|
12040
|
+
console.error("Error:", err instanceof Error ? err.message : String(err));
|
|
12041
|
+
process.exit(1);
|
|
12042
|
+
}
|
|
12043
|
+
}
|
|
12044
|
+
async function entitySummaryGraphHandler(options) {
|
|
12045
|
+
try {
|
|
12046
|
+
const cue = await buildCueClient(options);
|
|
12047
|
+
if (options.verbose)
|
|
12048
|
+
console.error(`Fetching entity summary graph for project ${options.space}...`);
|
|
12049
|
+
const entities = new CueProjectEntities(cue.api, options.space);
|
|
12050
|
+
if (options.format === "graph") {
|
|
12051
|
+
const graph = await entities.buildSummaryGraph("graph");
|
|
12052
|
+
console.log(JSON.stringify(graph, null, 2));
|
|
12053
|
+
} else if (options.format === "md") {
|
|
12054
|
+
const md = await entities.buildSummaryGraph("md");
|
|
12055
|
+
console.log(md);
|
|
12056
|
+
} else {
|
|
12057
|
+
const raw = await entities.buildSummaryGraph();
|
|
12058
|
+
console.log(JSON.stringify(raw, null, 2));
|
|
12059
|
+
}
|
|
12060
|
+
} catch (err) {
|
|
12061
|
+
console.error("Error:", err instanceof Error ? err.message : String(err));
|
|
12062
|
+
process.exit(1);
|
|
12063
|
+
}
|
|
12064
|
+
}
|
|
12065
|
+
async function sparqlHandler(options) {
|
|
12066
|
+
try {
|
|
12067
|
+
let sparqlQuery = options.query;
|
|
12068
|
+
if (!sparqlQuery) {
|
|
12069
|
+
if (process.stdin.isTTY) {
|
|
12070
|
+
console.error("Provide a SPARQL query via --query or pipe it via stdin.");
|
|
12071
|
+
process.exit(1);
|
|
12072
|
+
}
|
|
12073
|
+
const chunks = [];
|
|
12074
|
+
for await (const chunk of process.stdin)
|
|
12075
|
+
chunks.push(chunk);
|
|
12076
|
+
sparqlQuery = Buffer.concat(chunks).toString("utf8").trim();
|
|
12077
|
+
}
|
|
12078
|
+
if (!sparqlQuery) {
|
|
12079
|
+
console.error("SPARQL query is empty.");
|
|
12080
|
+
process.exit(1);
|
|
12081
|
+
}
|
|
12082
|
+
const cue = await buildCueClient(options);
|
|
12083
|
+
if (options.verbose)
|
|
12084
|
+
console.error(`Executing SPARQL query against project ${options.space}...`);
|
|
12085
|
+
const result = await cue.api.sparql(sparqlQuery, options.space);
|
|
12086
|
+
console.log(JSON.stringify(result, null, 2));
|
|
12087
|
+
} catch (err) {
|
|
12088
|
+
console.error("Error:", err instanceof Error ? err.message : String(err));
|
|
12089
|
+
process.exit(1);
|
|
12090
|
+
}
|
|
12091
|
+
}
|
|
12092
|
+
var appBuilderToolsCommand = new import_commander.Command("app-builder-tools").description("Tools for agent-assisted Cue app development. Outputs JSON for machine consumption.");
|
|
12093
|
+
appBuilderToolsCommand.command("list-projects").description("List all projects accessible to the authenticated user").option("-k, --key <api-key>", "Specify the API key (or set CUE_API_KEY env variable)").option("-e, --emulators", "Use emulators", false).option("-v, --verbose", "Enable verbose output", false).action(listProjectsHandler);
|
|
12094
|
+
appBuilderToolsCommand.command("entity-summary-graph").description("Fetch the entity category relationship summary graph for a project").requiredOption("-s, --space <id>", "Project ID (required)").option("-k, --key <api-key>", "Specify the API key (or set CUE_API_KEY env variable)").option("-e, --emulators", "Use emulators", false).option("-f, --format <format>", "Output format: md (aligned text), graph (JSON nodes+edges), json (raw SPARQL)", "md").option("-v, --verbose", "Enable verbose output", false).action(entitySummaryGraphHandler);
|
|
12095
|
+
appBuilderToolsCommand.command("sparql").description("Execute a SPARQL SELECT query against a project triplestore. Query via --query or stdin.").requiredOption("-s, --space <id>", "Project ID (required)").option("-q, --query <sparql>", "SPARQL query string (or pipe query via stdin)").option("-k, --key <api-key>", "Specify the API key (or set CUE_API_KEY env variable)").option("-e, --emulators", "Use emulators", false).option("-v, --verbose", "Enable verbose output", false).action(sparqlHandler);
|
|
12096
|
+
|
|
11678
12097
|
// apps/desktop/cue-cli/src/main.ts
|
|
11679
12098
|
var packageJson;
|
|
11680
12099
|
try {
|
|
@@ -11687,7 +12106,7 @@ try {
|
|
|
11687
12106
|
console.warn("Could not find package.json, using fallback version");
|
|
11688
12107
|
}
|
|
11689
12108
|
}
|
|
11690
|
-
var program = new
|
|
12109
|
+
var program = new import_commander2.Command();
|
|
11691
12110
|
program.name("cue-cli").description("Cue Command Line Interface").version(packageJson.version);
|
|
11692
12111
|
program.command("sync").description("Sync files to Cue").option("-s, --space <id>", "Specify the space ID (omit to pick interactively)").requiredOption("-p, --path <id>", "Specify the folder path (required)").option("-k, --key <api-key>", "Specify the API key (or set CUE_API_KEY env variable)").option("--provider <provider ID>", "Specify the provider ID (eg. sharepoint, drive, dropbox) or leave empty for default provider", "").option("-v, --verbose", "Enable verbose output", false).option("-e, --emulators", "Uses emulators for sync", false).option("-z, --zip", 'Include zipped content (will be unzipped to path "<zip_path>_unzipped". Max uncompressed size: 500 MB, max recursion depth: 3)', false).option("--legacy", "Write RDF as BLOBs to the processed bucket instead of patching the graph directly", false).option("--metadata-only", "Push filesystem-structure metadata for all local files without checking credits or remote state", false).action(syncHandler);
|
|
11693
12112
|
program.command("dump").description("Dump Cue Knowledge Graph data to file\n Examples:\n $ cue-cli dump -s <space_id> -l -v\n $ cue-cli dump -s <space_id> -j -v").requiredOption("-s, --space <id>", "Specify the space ID (required)").option("-k, --key <api-key>", "Specify the API key (or set CUE_API_KEY env variable)").option("-v, --verbose", "Enable verbose output", false).option("-e, --emulators", "Uses emulators for sync", false).option("-q, --query", "Uses a construct query to get the dump rather than using the /data endpoint", false).option("-j, --jelly", "Downloads a Jelly file rather than the standard Gzipped NQuads format", false).option("-l, --load", "Loads the dumped file into a local triplestore (requires emulators)", false).action(dumpHandler);
|
|
@@ -11697,4 +12116,5 @@ program.command("repair-ttl").description("Repair TTL files in the specified spa
|
|
|
11697
12116
|
program.command("util-rdf-compare").description("Compare two Turtle (.ttl) files and report semantic differences").requiredOption("--file1 <path>", "Path to the first TTL file").requiredOption("--file2 <path>", "Path to the second TTL file").option("-v, --verbose", "Enable verbose output", false).action(utilRdfCompareHandler);
|
|
11698
12117
|
program.command("util-remove-rdf-star").description("Remove RDF-star (quoted) triples from an NQuads file. Supports .nq and .nq.gz input/output.").requiredOption("-i, --input <path>", "Input file path (.nq or .nq.gz)").requiredOption("-o, --output <path>", "Output file path (.nq or .nq.gz)").option("-v, --verbose", "Enable verbose output", false).action(utilRemoveRdfStarHandler);
|
|
11699
12118
|
program.command("create-project").description("Interactively create a new project under an organisation").option("-k, --key <api-key>", "Specify the API key (or set CUE_API_KEY env variable)").option("-e, --emulators", "Uses emulators", false).option("-v, --verbose", "Enable verbose output", false).action(createProjectHandler);
|
|
12119
|
+
program.addCommand(appBuilderToolsCommand);
|
|
11700
12120
|
program.parse(process.argv);
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -35,6 +35,42 @@ To sync the current dir to the space with id `<space-id>` under the provider id
|
|
|
35
35
|
| `--legacy` | Write RDF metadata as serialised Turtle BLOBs to the processed storage bucket instead of patching the knowledge graph directly. Use this when the ledger and graph services are not yet available for the target environment. | `false` |
|
|
36
36
|
| `--metadata-only` | Push filesystem-structure metadata for every local file directly to the commands API, without checking what is already on the remote, running a credit estimate, or uploading any file content. Useful for repairing missing graph metadata after a migration or interrupted sync. Can be combined with `--legacy` to write the metadata as BLOBs. | `false` |
|
|
37
37
|
|
|
38
|
+
### app-builder-tools
|
|
39
|
+
|
|
40
|
+
A set of JSON-output commands designed for agent-assisted Cue app development. All sub-commands accept `-k/--key` (or `CUE_API_KEY`), `-e/--emulators`, and `-v/--verbose`.
|
|
41
|
+
|
|
42
|
+
#### list-projects
|
|
43
|
+
|
|
44
|
+
List all projects accessible to the authenticated user.
|
|
45
|
+
|
|
46
|
+
`npx @qaecy/cue-cli app-builder-tools list-projects`
|
|
47
|
+
|
|
48
|
+
Outputs a JSON array with `id`, `name`, `organizationID`, `isPublic`, `graphType`, and `lastSync` for each project.
|
|
49
|
+
|
|
50
|
+
#### entity-summary-graph
|
|
51
|
+
|
|
52
|
+
Fetch the entity category relationship summary graph for a project — useful for understanding the knowledge graph schema before writing queries.
|
|
53
|
+
|
|
54
|
+
`npx @qaecy/cue-cli app-builder-tools entity-summary-graph -s <project-id>`
|
|
55
|
+
|
|
56
|
+
| Option | Description | Default |
|
|
57
|
+
|----------------------|----------------------------------------------------------------------------------------------|---------|
|
|
58
|
+
| `-s, --space <id>` | Project ID (required) | N/A |
|
|
59
|
+
| `-f, --format <fmt>` | Output format: `md` (aligned text table), `graph` (JSON nodes + weighted edges), `json` (raw SPARQL result) | `md` |
|
|
60
|
+
|
|
61
|
+
#### sparql
|
|
62
|
+
|
|
63
|
+
Execute a SPARQL SELECT query against a project triplestore. The query can be passed inline or piped via stdin. Outputs raw SPARQL JSON results.
|
|
64
|
+
|
|
65
|
+
`npx @qaecy/cue-cli app-builder-tools sparql -s <project-id> -q "SELECT * WHERE { ?s ?p ?o } LIMIT 10"`
|
|
66
|
+
|
|
67
|
+
`echo "SELECT * WHERE { ?s ?p ?o } LIMIT 10" | npx @qaecy/cue-cli app-builder-tools sparql -s <project-id>`
|
|
68
|
+
|
|
69
|
+
| Option | Description | Default |
|
|
70
|
+
|---------------------|-----------------------------------------------------------|---------|
|
|
71
|
+
| `-s, --space <id>` | Project ID (required) | N/A |
|
|
72
|
+
| `-q, --query <sparql>` | SPARQL query string (or pipe query via stdin) | N/A |
|
|
73
|
+
|
|
38
74
|
### util-remove-rdf-star
|
|
39
75
|
|
|
40
76
|
Remove RDF-star (quoted triple) statements from an NQuads file. Supports both plain `.nq` and gzipped `.nq.gz` files. If the input is gzipped the output will also be gzipped.
|