@qaecy/cue-cli 0.0.39 → 0.0.41

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.
Files changed (2) hide show
  1. package/main.js +410 -160
  2. package/package.json +2 -2
package/main.js CHANGED
@@ -29,6 +29,68 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
29
29
  mod
30
30
  ));
31
31
 
32
+ // libs/js/sync-tools/src/lib/helpers/worker-pool.js
33
+ var worker_pool_exports = {};
34
+ __export(worker_pool_exports, {
35
+ WorkerPool: () => WorkerPool
36
+ });
37
+ var Worker, os, WorkerPool;
38
+ var init_worker_pool = __esm({
39
+ "libs/js/sync-tools/src/lib/helpers/worker-pool.js"() {
40
+ ({ Worker } = require("worker_threads"));
41
+ os = require("os");
42
+ WorkerPool = class {
43
+ constructor(workerPath, poolSize = os.cpus().length) {
44
+ this.workerPath = workerPath;
45
+ this.poolSize = poolSize;
46
+ this.workers = [];
47
+ this.idleWorkers = [];
48
+ this.queue = [];
49
+ for (let i = 0; i < poolSize; i++) {
50
+ const worker = new Worker(workerPath);
51
+ worker.on("message", (result) => {
52
+ const callback = worker._currentCallback;
53
+ worker._currentCallback = null;
54
+ this.idleWorkers.push(worker);
55
+ callback(result);
56
+ this._next();
57
+ });
58
+ worker.on("error", (err) => {
59
+ if (worker._currentCallback)
60
+ worker._currentCallback({ error: err.message });
61
+ this.idleWorkers.push(worker);
62
+ this._next();
63
+ });
64
+ this.workers.push(worker);
65
+ this.idleWorkers.push(worker);
66
+ }
67
+ }
68
+ _next() {
69
+ if (this.queue.length > 0 && this.idleWorkers.length > 0) {
70
+ const { filePath, resolve: resolve2, reject } = this.queue.shift();
71
+ const worker = this.idleWorkers.pop();
72
+ worker._currentCallback = (result) => {
73
+ if (result.error)
74
+ reject(new Error(result.error));
75
+ else
76
+ resolve2(result.hash);
77
+ };
78
+ worker.postMessage(filePath);
79
+ }
80
+ }
81
+ hashFile(filePath) {
82
+ return new Promise((resolve2, reject) => {
83
+ this.queue.push({ filePath, resolve: resolve2, reject });
84
+ this._next();
85
+ });
86
+ }
87
+ async close() {
88
+ await Promise.all(this.workers.map((worker) => worker.terminate()));
89
+ }
90
+ };
91
+ }
92
+ });
93
+
32
94
  // libs/js/id-builders/src/lib/id-builders.ts
33
95
  function contextBasedGuid(contextString, verbose = false) {
34
96
  const namespace = "daca0510-72b5-48ba-9091-b918ca18136b";
@@ -246,68 +308,6 @@ var init_src = __esm({
246
308
  }
247
309
  });
248
310
 
249
- // libs/js/sync-tools/src/lib/helpers/worker-pool.js
250
- var worker_pool_exports = {};
251
- __export(worker_pool_exports, {
252
- WorkerPool: () => WorkerPool
253
- });
254
- var Worker, os, WorkerPool;
255
- var init_worker_pool = __esm({
256
- "libs/js/sync-tools/src/lib/helpers/worker-pool.js"() {
257
- ({ Worker } = require("worker_threads"));
258
- os = require("os");
259
- WorkerPool = class {
260
- constructor(workerPath, poolSize = os.cpus().length) {
261
- this.workerPath = workerPath;
262
- this.poolSize = poolSize;
263
- this.workers = [];
264
- this.idleWorkers = [];
265
- this.queue = [];
266
- for (let i = 0; i < poolSize; i++) {
267
- const worker = new Worker(workerPath);
268
- worker.on("message", (result) => {
269
- const callback = worker._currentCallback;
270
- worker._currentCallback = null;
271
- this.idleWorkers.push(worker);
272
- callback(result);
273
- this._next();
274
- });
275
- worker.on("error", (err) => {
276
- if (worker._currentCallback)
277
- worker._currentCallback({ error: err.message });
278
- this.idleWorkers.push(worker);
279
- this._next();
280
- });
281
- this.workers.push(worker);
282
- this.idleWorkers.push(worker);
283
- }
284
- }
285
- _next() {
286
- if (this.queue.length > 0 && this.idleWorkers.length > 0) {
287
- const { filePath, resolve: resolve2, reject } = this.queue.shift();
288
- const worker = this.idleWorkers.pop();
289
- worker._currentCallback = (result) => {
290
- if (result.error)
291
- reject(new Error(result.error));
292
- else
293
- resolve2(result.hash);
294
- };
295
- worker.postMessage(filePath);
296
- }
297
- }
298
- hashFile(filePath) {
299
- return new Promise((resolve2, reject) => {
300
- this.queue.push({ filePath, resolve: resolve2, reject });
301
- this._next();
302
- });
303
- }
304
- async close() {
305
- await Promise.all(this.workers.map((worker) => worker.terminate()));
306
- }
307
- };
308
- }
309
- });
310
-
311
311
  // libs/js/sync-tools/src/lib/helpers/md5-builder-node.ts
312
312
  var md5_builder_node_exports = {};
313
313
  __export(md5_builder_node_exports, {
@@ -545,11 +545,11 @@ var Fuseki = class _Fuseki {
545
545
  }
546
546
  }
547
547
  async ping() {
548
- const query4 = "ASK { }";
549
- const res = await this.query(query4);
548
+ const query3 = "ASK { }";
549
+ const res = await this.query(query3);
550
550
  return res.boolean;
551
551
  }
552
- async query(query4, accept = "application/sparql-results+json") {
552
+ async query(query3, accept = "application/sparql-results+json") {
553
553
  let res;
554
554
  try {
555
555
  res = await fetch(this.queryEndpoint, {
@@ -559,7 +559,7 @@ var Fuseki = class _Fuseki {
559
559
  Accept: accept
560
560
  },
561
561
  method: "POST",
562
- body: new URLSearchParams({ query: query4 })
562
+ body: new URLSearchParams({ query: query3 })
563
563
  });
564
564
  } catch (err) {
565
565
  throw new Error(
@@ -572,7 +572,7 @@ var Fuseki = class _Fuseki {
572
572
  }
573
573
  return await res.json();
574
574
  }
575
- async subset(query4, accept = "text/turtle") {
575
+ async subset(query3, accept = "text/turtle") {
576
576
  const res = await fetch(this.queryEndpoint, {
577
577
  headers: {
578
578
  ...this.baseHeaders,
@@ -581,7 +581,7 @@ var Fuseki = class _Fuseki {
581
581
  Accept: accept
582
582
  },
583
583
  method: "POST",
584
- body: new URLSearchParams({ query: query4 })
584
+ body: new URLSearchParams({ query: query3 })
585
585
  });
586
586
  if (accept === "application/ld+json") {
587
587
  return await res.json();
@@ -679,11 +679,11 @@ var QLever = class _QLever {
679
679
  this.baseHeaders["x-user-roles"] = "admin";
680
680
  }
681
681
  async ping() {
682
- const query4 = "ASK { }";
683
- const res = await this.query(query4);
682
+ const query3 = "ASK { }";
683
+ const res = await this.query(query3);
684
684
  return res.boolean;
685
685
  }
686
- async query(query4, accept = "application/sparql-results+json") {
686
+ async query(query3, accept = "application/sparql-results+json") {
687
687
  let res;
688
688
  try {
689
689
  res = await fetch(this.queryEndpoint, {
@@ -693,7 +693,7 @@ var QLever = class _QLever {
693
693
  Accept: accept
694
694
  },
695
695
  method: "POST",
696
- body: new URLSearchParams({ query: query4 })
696
+ body: new URLSearchParams({ query: query3 })
697
697
  });
698
698
  } catch (err) {
699
699
  throw new Error(
@@ -706,7 +706,7 @@ var QLever = class _QLever {
706
706
  }
707
707
  return await res.json();
708
708
  }
709
- async subset(query4, accept = "text/turtle") {
709
+ async subset(query3, accept = "text/turtle") {
710
710
  const res = await fetch(this.queryEndpoint, {
711
711
  headers: {
712
712
  ...this.baseHeaders,
@@ -714,7 +714,7 @@ var QLever = class _QLever {
714
714
  Accept: accept
715
715
  },
716
716
  method: "POST",
717
- body: new URLSearchParams({ query: query4 })
717
+ body: new URLSearchParams({ query: query3 })
718
718
  });
719
719
  return await res.text();
720
720
  }
@@ -4780,7 +4780,6 @@ async function getGraphFiles(providerId, queryHandler2) {
4780
4780
  }
4781
4781
 
4782
4782
  // libs/js/sync-tools/src/lib/list-local-files.ts
4783
- init_src();
4784
4783
  async function _path() {
4785
4784
  return import("path");
4786
4785
  }
@@ -4796,7 +4795,10 @@ async function listLocalFiles(dir, providerId = "", verbose = false, logInterval
4796
4795
  if (verbose)
4797
4796
  console.info(`Listing files in local dir: ${dir}`);
4798
4797
  if (unzipZipped) {
4799
- const zipFiles = await filesInLocalDirRecursive(dir, (entry) => entry.name.toLowerCase().endsWith(".zip"));
4798
+ const zipFiles = await filesInLocalDirRecursive(
4799
+ dir,
4800
+ (entry) => entry.name.toLowerCase().endsWith(".zip")
4801
+ );
4800
4802
  if (zipFiles.length && verbose)
4801
4803
  console.info(`Found ${zipFiles.length} zip files to unzip...`);
4802
4804
  for (const zipFile of zipFiles) {
@@ -4825,13 +4827,22 @@ async function listLocalFiles(dir, providerId = "", verbose = false, logInterval
4825
4827
  const { stat } = await _fs();
4826
4828
  const { relative } = await _path();
4827
4829
  const stats = await Promise.all(fullPaths.map((f) => stat(f)));
4830
+ const { contextBasedGuid: contextBasedGuid2, generateFileUUID: generateFileUUID2 } = await Promise.resolve().then(() => (init_src(), src_exports));
4828
4831
  return fullPaths.map((f, i) => {
4829
4832
  const relativePath = relative(dir, f);
4830
4833
  const md5 = hashes[i];
4831
- const contentUUID = contextBasedGuid(md5);
4832
- const locationUUID = generateFileUUID(relativePath, providerId);
4834
+ const contentUUID = contextBasedGuid2(md5);
4835
+ const locationUUID = generateFileUUID2(relativePath, providerId);
4833
4836
  const { mtimeMs, size } = stats[i];
4834
- return { relativePath, fullPath: f, size, md5, contentUUID, locationUUID, mtimeMs };
4837
+ return {
4838
+ relativePath,
4839
+ fullPath: f,
4840
+ size,
4841
+ md5,
4842
+ contentUUID,
4843
+ locationUUID,
4844
+ mtimeMs
4845
+ };
4835
4846
  });
4836
4847
  }
4837
4848
  async function filesInLocalDirRecursive(dir, filterFunc = () => true, excludeDirs = true) {
@@ -4864,7 +4875,9 @@ async function filesInLocalDirRecursive(dir, filterFunc = () => true, excludeDir
4864
4875
  if (error instanceof Error && "code" in error) {
4865
4876
  const nodeError = error;
4866
4877
  if (nodeError.code === "EPERM" || nodeError.code === "EACCES") {
4867
- console.warn(`Skipping directory due to permission error: ${currentDir}`);
4878
+ console.warn(
4879
+ `Skipping directory due to permission error: ${currentDir}`
4880
+ );
4868
4881
  return;
4869
4882
  }
4870
4883
  }
@@ -4882,7 +4895,9 @@ async function unzipFile(zipPath, recursive = true, options) {
4882
4895
  const currentDepth = options?.currentDepth ?? 0;
4883
4896
  const totalUncompressedSize = options?.totalUncompressedSize ?? { value: 0 };
4884
4897
  if (currentDepth > maxRecursionDepth) {
4885
- throw new Error(`Zip extraction aborted: exceeded max recursion depth (${maxRecursionDepth})`);
4898
+ throw new Error(
4899
+ `Zip extraction aborted: exceeded max recursion depth (${maxRecursionDepth})`
4900
+ );
4886
4901
  }
4887
4902
  const { mkdir: mkdir2, readFile, writeFile: writeFile2 } = await _fs();
4888
4903
  const { join: join4 } = await _path();
@@ -4901,7 +4916,9 @@ async function unzipFile(zipPath, recursive = true, options) {
4901
4916
  const promise = file.async("nodebuffer").then(async (content) => {
4902
4917
  totalUncompressedSize.value += content.length;
4903
4918
  if (totalUncompressedSize.value > maxUncompressedSize) {
4904
- throw new Error(`Zip extraction aborted: exceeded max uncompressed size (${maxUncompressedSize} bytes)`);
4919
+ throw new Error(
4920
+ `Zip extraction aborted: exceeded max uncompressed size (${maxUncompressedSize} bytes)`
4921
+ );
4905
4922
  }
4906
4923
  await writeFile2(targetPath, content);
4907
4924
  if (recursive && targetPath.toLowerCase().endsWith(".zip")) {
@@ -4924,7 +4941,11 @@ async function ensureDir(path) {
4924
4941
  }
4925
4942
  async function deleteUnzipped(dir) {
4926
4943
  const { rm } = await _fs();
4927
- const paths = await filesInLocalDirRecursive(dir, (entry) => entry.name.toLowerCase().endsWith(UNZIPPED_SUFFIX), false);
4944
+ const paths = await filesInLocalDirRecursive(
4945
+ dir,
4946
+ (entry) => entry.name.toLowerCase().endsWith(UNZIPPED_SUFFIX),
4947
+ false
4948
+ );
4928
4949
  for (const p of paths) {
4929
4950
  await rm(p, { recursive: true, force: true });
4930
4951
  }
@@ -4932,7 +4953,7 @@ async function deleteUnzipped(dir) {
4932
4953
 
4933
4954
  // apps/desktop/cue-cli/src/helpers/query-handler.ts
4934
4955
  var import_auth2 = require("firebase/auth");
4935
- async function queryHandler(query4, spaceId, useEmulator) {
4956
+ async function queryHandler(query3, spaceId, useEmulator) {
4936
4957
  const endpoint = useEmulator ? SPARQL_ENDPOINT_EMULATOR : SPARQL_ENDPOINT;
4937
4958
  const token = await (0, import_auth2.getAuth)().currentUser?.getIdToken();
4938
4959
  const res = await fetch(endpoint, {
@@ -4943,7 +4964,7 @@ async function queryHandler(query4, spaceId, useEmulator) {
4943
4964
  "Content-Type": "application/sparql-query",
4944
4965
  Accept: "application/sparql-results+json"
4945
4966
  },
4946
- body: query4
4967
+ body: query3
4947
4968
  });
4948
4969
  if (!res.ok) {
4949
4970
  console.error(
@@ -5027,8 +5048,8 @@ function cueComputed(deps, compute) {
5027
5048
  }
5028
5049
  };
5029
5050
  }
5030
- async function staleWhileRevalidate(query4, fetchFresh, onData, cache) {
5031
- const cacheKey = contextBasedGuid(query4);
5051
+ async function staleWhileRevalidate(query3, fetchFresh, onData, cache) {
5052
+ const cacheKey = contextBasedGuid(query3);
5032
5053
  let staleId;
5033
5054
  if (cache) {
5034
5055
  const stale = await cache.get(cacheKey);
@@ -5059,8 +5080,6 @@ var DEFAULT_SDK_CONFIG = {
5059
5080
  var FIREBASE_PROJECT_ID = "qaecy-mvp-406413";
5060
5081
  var FIREBASE_SENDER_ID = "734737865998";
5061
5082
  var GCP_REGION2 = "europe-west6";
5062
- var COLLECTION_API_KEYS2 = "apiKeys";
5063
- var COLLECTION_ORGANIZATIONS2 = "organizations";
5064
5083
  var COLLECTION_PROJECTS2 = "projects";
5065
5084
  var BUCKET_CHAT_SESSIONS2 = "spaces_chats_eu_west6";
5066
5085
  var BUCKET_RAW2 = "spaces_raw_eu_west6";
@@ -5069,6 +5088,9 @@ var BUCKET_LOGS2 = "spaces_logs_eu_west6";
5069
5088
  var BUCKET_PUBLIC2 = "cue_public_eu_west6";
5070
5089
  var BUCKET_PERSISTENCE2 = "db_persistence_eu_west6";
5071
5090
  var ENDPOINT_CONSUMPTION = "/data-views/admin/consumption";
5091
+ var ENDPOINT_PROFILE_ORGANIZATIONS = "/data-views/admin/profile/organizations";
5092
+ var ENDPOINT_PROFILE_API_KEYS = "/data-views/admin/profile/api-keys";
5093
+ var ENDPOINT_ORG_MEMBERS = (orgId) => `/data-views/admin/organizations/${orgId}/members`;
5072
5094
  var ENDPOINT_CREATE_PROJECT = "/commands/admin/project";
5073
5095
  var ENDPOINT_SEARCH = "/assistant/search";
5074
5096
  var ENDPOINT_FUSEKI_QUERY = "/triplestore/query";
@@ -5180,14 +5202,14 @@ var CueAuth = class {
5180
5202
  const tokenResult = await (0, import_auth3.getIdTokenResult)(user);
5181
5203
  return tokenResult.claims["role"] === SUPERADMIN_ROLE;
5182
5204
  }
5183
- /** Sign in with a Cue API key */
5205
+ /** Sign in with a Cue API key. `projectId` is optional — omit it when no project context is available (e.g. admin flows). */
5184
5206
  async signInWithApiKey(cueApiKey, projectId) {
5207
+ const headers = { "cue-api-key": cueApiKey };
5208
+ if (projectId)
5209
+ headers["x-project-id"] = projectId;
5185
5210
  const response = await fetch(this._endpoints.tokenUrl, {
5186
5211
  method: "GET",
5187
- headers: {
5188
- "x-project-id": projectId,
5189
- "cue-api-key": cueApiKey
5190
- }
5212
+ headers
5191
5213
  });
5192
5214
  if (!response.ok)
5193
5215
  throw new Error(`Failed to fetch custom token: ${response.statusText}`);
@@ -5293,12 +5315,12 @@ var CueApi = class {
5293
5315
  * Execute a SPARQL query against the project's triplestore.
5294
5316
  * The user must be authenticated before calling this.
5295
5317
  */
5296
- async sparql(query4, projectId, graphType) {
5318
+ async sparql(query3, projectId, graphType) {
5297
5319
  console.log(graphType);
5298
5320
  const endpoint = graphType === "qlever" ? ENDPOINT_QLEVER_QUERY : ENDPOINT_FUSEKI_QUERY;
5299
5321
  console.log(`Executing SPARQL query against ${endpoint} for project ${projectId} with graph type ${graphType ?? "fuseki"}`);
5300
5322
  const urlencoded = new URLSearchParams();
5301
- urlencoded.append("query", query4);
5323
+ urlencoded.append("query", query3);
5302
5324
  const response = await this._auth.authenticatedFetch(
5303
5325
  `${this._gatewayUrl}${endpoint}`,
5304
5326
  {
@@ -5434,27 +5456,32 @@ var CueProjects = class {
5434
5456
 
5435
5457
  // libs/js/cue-sdk/src/lib/profile.ts
5436
5458
  var import_auth4 = require("firebase/auth");
5437
- var import_firestore4 = require("firebase/firestore");
5438
5459
  var import_functions3 = require("firebase/functions");
5439
5460
  var CueProfile = class {
5440
- constructor(_auth, app, useEmulator, emulatorHost, emulatorPort) {
5461
+ constructor(_auth, app, useEmulator, _gatewayUrl) {
5441
5462
  this._auth = _auth;
5442
- this._db = (0, import_firestore4.getFirestore)(app);
5463
+ this._gatewayUrl = _gatewayUrl;
5443
5464
  this._functions = (0, import_functions3.getFunctions)(app, GCP_REGION2);
5444
5465
  if (useEmulator) {
5445
- (0, import_firestore4.connectFirestoreEmulator)(this._db, emulatorHost, emulatorPort);
5446
5466
  (0, import_functions3.connectFunctionsEmulator)(this._functions, "localhost", 5001);
5447
5467
  }
5448
5468
  }
5449
- _db;
5450
5469
  _functions;
5451
- _apiKeyDocRef;
5470
+ _url(endpoint) {
5471
+ return `${this._gatewayUrl}${endpoint}`;
5472
+ }
5473
+ async _fetch(path, init) {
5474
+ const response = await this._auth.authenticatedFetch(this._url(path), init);
5475
+ if (!response.ok) {
5476
+ throw new Error(`Profile API error ${response.status}: ${response.statusText}`);
5477
+ }
5478
+ const text = await response.text();
5479
+ return text ? JSON.parse(text) : null;
5480
+ }
5452
5481
  /** Whether the current user has an active API key. */
5453
5482
  async hasAPIKey() {
5454
- const uid = this._auth.currentUser?.uid;
5455
- if (!uid)
5456
- return false;
5457
- return this._checkIfUserHasAPIKey(uid);
5483
+ const info = await this._fetch(ENDPOINT_PROFILE_API_KEYS);
5484
+ return info !== null;
5458
5485
  }
5459
5486
  /** Returns the sign-in methods registered for the current user's email. */
5460
5487
  async getSignInMethods() {
@@ -5522,47 +5549,36 @@ var CueProfile = class {
5522
5549
  }
5523
5550
  /** Creates a new API key for the current user. */
5524
5551
  async createAPIKey(expiration) {
5525
- const uid = this._auth.currentUser?.uid;
5526
- if (!uid)
5527
- throw new Error("User not authenticated");
5528
- const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
5529
- const randomKey = Array.from(globalThis.crypto.getRandomValues(new Uint8Array(150)), (b) => alphabet[b & 63]).join("");
5530
- const data = { key: `cue-${randomKey}`, uid, expiration };
5531
- const col = (0, import_firestore4.collection)(this._db, COLLECTION_API_KEYS2);
5532
- this._apiKeyDocRef = await (0, import_firestore4.addDoc)(col, data);
5533
- return data;
5552
+ return this._fetch(ENDPOINT_PROFILE_API_KEYS, {
5553
+ method: "POST",
5554
+ headers: { "Content-Type": "application/json" },
5555
+ body: JSON.stringify({ expiration })
5556
+ });
5534
5557
  }
5535
5558
  /** Revokes the current user's API key. */
5536
5559
  async revokeAPIKey() {
5537
- if (!this._apiKeyDocRef)
5538
- throw new Error("No API key document reference");
5539
- await (0, import_firestore4.deleteDoc)(this._apiKeyDocRef);
5540
- this._apiKeyDocRef = void 0;
5560
+ const response = await this._auth.authenticatedFetch(
5561
+ this._url(ENDPOINT_PROFILE_API_KEYS),
5562
+ { method: "DELETE" }
5563
+ );
5564
+ if (!response.ok) {
5565
+ throw new Error(`Revoke API key error ${response.status}: ${response.statusText}`);
5566
+ }
5541
5567
  }
5542
5568
  /** Fetches the current user's existing API key. */
5543
5569
  async requestAPIKey() {
5544
- if (!this._apiKeyDocRef)
5545
- throw new Error("No API key document reference");
5546
- const doc3 = (await (0, import_firestore4.getDoc)(this._apiKeyDocRef)).data();
5547
- return { key: doc3.key, expiration: doc3.expiration };
5548
- }
5549
- async _checkIfUserHasAPIKey(uid) {
5550
- const col = (0, import_firestore4.collection)(this._db, COLLECTION_API_KEYS2);
5551
- const q = (0, import_firestore4.query)(col, (0, import_firestore4.where)("uid", "==", uid), (0, import_firestore4.limit)(1));
5552
- const snapshot = await (0, import_firestore4.getDocs)(q);
5553
- if (!snapshot.empty)
5554
- this._apiKeyDocRef = snapshot.docs[0].ref;
5555
- return !snapshot.empty;
5556
- }
5557
- /** Returns all organizations the current user is a member of. */
5570
+ const result = await this._fetch(ENDPOINT_PROFILE_API_KEYS);
5571
+ if (!result)
5572
+ throw new Error("No API key found");
5573
+ return result;
5574
+ }
5575
+ /** Returns organizations the current user is a member of. */
5558
5576
  async listOrganizations() {
5559
- const uid = this._auth.currentUser?.uid;
5560
- if (!uid)
5561
- throw new Error("Not authenticated. Call cue.auth.signIn() first.");
5562
- const col = (0, import_firestore4.collection)(this._db, COLLECTION_ORGANIZATIONS2);
5563
- const q = (0, import_firestore4.query)(col, (0, import_firestore4.where)("members", "array-contains", uid));
5564
- const snap = await (0, import_firestore4.getDocs)(q);
5565
- return snap.docs.map((d) => d.data());
5577
+ return this._fetch(ENDPOINT_PROFILE_ORGANIZATIONS);
5578
+ }
5579
+ /** Returns all members of the given organisation. Caller must be an org admin or superadmin. */
5580
+ async getOrgMembers(orgId) {
5581
+ return this._fetch(ENDPOINT_ORG_MEMBERS(orgId));
5566
5582
  }
5567
5583
  _requireUser() {
5568
5584
  const user = this._auth.currentUser;
@@ -5866,8 +5882,8 @@ WHERE {
5866
5882
  }
5867
5883
  GROUP BY ?iri ?parent`;
5868
5884
  }
5869
- async _runCategoriesQuery(query4) {
5870
- const data = await this._api.sparql(query4, this._projectId, this._graphType);
5885
+ async _runCategoriesQuery(query3) {
5886
+ const data = await this._api.sparql(query3, this._projectId, this._graphType);
5871
5887
  return data.results.bindings.filter((b) => b["iri"] !== void 0).map((b) => {
5872
5888
  const iri = b["iri"].value;
5873
5889
  return {
@@ -5894,8 +5910,8 @@ WHERE {
5894
5910
  }
5895
5911
  GROUP BY ?iri ?parent`;
5896
5912
  }
5897
- async _runRelationshipsQuery(query4) {
5898
- const data = await this._api.sparql(query4, this._projectId, this._graphType);
5913
+ async _runRelationshipsQuery(query3) {
5914
+ const data = await this._api.sparql(query3, this._projectId, this._graphType);
5899
5915
  return data.results.bindings.filter((b) => b["iri"] !== void 0).map((b) => {
5900
5916
  const iri = b["iri"].value;
5901
5917
  return {
@@ -7707,13 +7723,16 @@ function uploadedFileMetadata(originalName, projectId, userId, md5, providerId,
7707
7723
  }
7708
7724
 
7709
7725
  // libs/js/cue-sdk/src/lib/sync.ts
7726
+ async function _fs2() {
7727
+ return import("fs/promises");
7728
+ }
7710
7729
  async function _readNodeFile(fullPath) {
7711
7730
  if (typeof window !== "undefined") {
7712
7731
  throw new Error(
7713
7732
  `Cannot read file from path "${fullPath}" in a browser environment. Provide file.data (Uint8Array) instead.`
7714
7733
  );
7715
7734
  }
7716
- const { readFile } = await import("fs/promises");
7735
+ const { readFile } = await _fs2();
7717
7736
  return readFile(fullPath);
7718
7737
  }
7719
7738
  var _scanFn = null;
@@ -7739,7 +7758,7 @@ async function _initWasm() {
7739
7758
  await mod.default({ module_or_path: wasmBinary });
7740
7759
  _scanFn = mod.scan;
7741
7760
  } else {
7742
- const { readFile } = await import("fs/promises");
7761
+ const { readFile } = await _fs2();
7743
7762
  const { join: join4 } = await import("path");
7744
7763
  const { pathToFileURL } = await import("url");
7745
7764
  const wasmDir = join4(__dirname, "assets", "wasm");
@@ -7767,7 +7786,7 @@ async function _loadPending(spaceId) {
7767
7786
  return raw ? JSON.parse(raw) : null;
7768
7787
  }
7769
7788
  try {
7770
- const raw = await (await import("fs/promises")).readFile(await _pendingFilePath(spaceId), "utf-8");
7789
+ const raw = await (await _fs2()).readFile(await _pendingFilePath(spaceId), "utf-8");
7771
7790
  return JSON.parse(raw);
7772
7791
  } catch {
7773
7792
  return null;
@@ -7779,7 +7798,7 @@ async function _savePending(batch) {
7779
7798
  window.localStorage.setItem(`${PENDING_LS_PREFIX}${batch.spaceId}`, data);
7780
7799
  return;
7781
7800
  }
7782
- await (await import("fs/promises")).writeFile(await _pendingFilePath(batch.spaceId), data, "utf-8");
7801
+ await (await _fs2()).writeFile(await _pendingFilePath(batch.spaceId), data, "utf-8");
7783
7802
  }
7784
7803
  async function _clearPending(spaceId) {
7785
7804
  if (typeof window !== "undefined") {
@@ -7787,7 +7806,7 @@ async function _clearPending(spaceId) {
7787
7806
  return;
7788
7807
  }
7789
7808
  try {
7790
- await (await import("fs/promises")).unlink(await _pendingFilePath(spaceId));
7809
+ await (await _fs2()).unlink(await _pendingFilePath(spaceId));
7791
7810
  } catch {
7792
7811
  }
7793
7812
  }
@@ -8080,7 +8099,16 @@ WHERE {
8080
8099
  qcy:dateCreated ?created ;
8081
8100
  qcy:filePath ?fp .
8082
8101
  }`;
8083
- const res = await graph.query(q, "application/sparql-results+json");
8102
+ let res;
8103
+ try {
8104
+ res = await graph.query(q, "application/sparql-results+json");
8105
+ } catch (err) {
8106
+ const msg = err instanceof Error ? err.message : String(err);
8107
+ if (msg.includes("HTTP 500")) {
8108
+ throw new Error("GRAPH_UNAVAILABLE: The knowledge graph for this project has no database configured. Contact your administrator or check the project setup.");
8109
+ }
8110
+ throw err;
8111
+ }
8084
8112
  const map = {};
8085
8113
  if (typeof res === "string")
8086
8114
  return map;
@@ -8409,8 +8437,7 @@ var Cue = class _Cue {
8409
8437
  this.auth,
8410
8438
  this._app,
8411
8439
  this._isEmulator,
8412
- this._endpoints.firestoreEmulatorHost,
8413
- this._endpoints.firestoreEmulatorPort
8440
+ this._endpoints.gatewayUrl
8414
8441
  );
8415
8442
  this.privileges = new CuePrivileges(this.auth.isSuperAdmin);
8416
8443
  const storagePersistence = (0, import_storage5.getStorage)(this._app, BUCKET_PERSISTENCE2);
@@ -8457,7 +8484,7 @@ var Cue = class _Cue {
8457
8484
  const syncApi = new CueSyncApi(auth, projects, blob, endpoints.gatewayUrl);
8458
8485
  const api = new CueApi(auth, endpoints.gatewayUrl, projects, syncApi);
8459
8486
  syncApi._bindApi(api);
8460
- const profile = new CueProfile(auth, app, false, endpoints.firestoreEmulatorHost, endpoints.firestoreEmulatorPort);
8487
+ const profile = new CueProfile(auth, app, false, endpoints.gatewayUrl);
8461
8488
  const instance = Object.create(_Cue.prototype);
8462
8489
  const privileges = new CuePrivileges(auth.isSuperAdmin);
8463
8490
  const cache = new CueCache(storagePersistence);
@@ -8586,7 +8613,7 @@ async function compareHandler(options) {
8586
8613
  await authenticate(emulators, space, options.key, verbose);
8587
8614
  if (verbose)
8588
8615
  console.info("Building compare base \u23F3");
8589
- const qh = async (query4) => queryHandler(query4, space, emulators);
8616
+ const qh = async (query3) => queryHandler(query3, space, emulators);
8590
8617
  const [localFiles, remoteFiles] = await Promise.all([
8591
8618
  listLocalFiles(
8592
8619
  path,
@@ -8917,7 +8944,7 @@ async function _doGzip(filePath) {
8917
8944
  });
8918
8945
  await (0, import_promises3.unlink)(filePath);
8919
8946
  }
8920
- async function _doQuery(query4, spaceId, url) {
8947
+ async function _doQuery(query3, spaceId, url) {
8921
8948
  const token = await (0, import_auth9.getAuth)().currentUser?.getIdToken();
8922
8949
  try {
8923
8950
  const res = await fetch(url, {
@@ -8928,7 +8955,7 @@ async function _doQuery(query4, spaceId, url) {
8928
8955
  "Content-Type": "application/sparql-query",
8929
8956
  Accept: "application/n-quads"
8930
8957
  },
8931
- body: query4
8958
+ body: query3
8932
8959
  });
8933
8960
  if (!res.ok) {
8934
8961
  console.error(`Error: ${res.status} ${res.statusText}`);
@@ -9036,7 +9063,7 @@ async function uploadToLocalGraph(id, filePath, mimeType = "application/n-quads"
9036
9063
 
9037
9064
  // apps/desktop/cue-cli/src/cue-cli-dump.ts
9038
9065
  async function dumpHandler(options) {
9039
- const { space, verbose, emulators, jelly, query: query4, load } = options;
9066
+ const { space, verbose, emulators, jelly, query: query3, load } = options;
9040
9067
  try {
9041
9068
  const { isSuperAdmin } = await authenticate(emulators, space, options.key, verbose);
9042
9069
  if (!isSuperAdmin) {
@@ -9057,7 +9084,7 @@ async function dumpHandler(options) {
9057
9084
  } else {
9058
9085
  if (verbose)
9059
9086
  console.time("Downloaded and zipped graph \u2705");
9060
- if (query4) {
9087
+ if (query3) {
9061
9088
  if (verbose)
9062
9089
  console.info("Setting: Construct query");
9063
9090
  filePath = await dumpRdfGraphToFileConstruct(space, emulators, verbose);
@@ -9280,7 +9307,7 @@ async function syncHandler(options) {
9280
9307
  }
9281
9308
  if (preview.creditsToConsume > preview.creditsAvailable) {
9282
9309
  console.error(
9283
- `Insufficient credits: ${Math.round(preview.creditsToConsume)} required, ${Math.round(preview.creditsAvailable)} available.`
9310
+ `Insufficient credits: ${Math.round(preview.creditsToConsume)} required, ${Math.round(preview.creditsAvailable)} available. Contact the QAECY sales team at mail@qaecy.com to top up credits.`
9284
9311
  );
9285
9312
  process.exit(1);
9286
9313
  }
@@ -9320,7 +9347,9 @@ async function syncHandler(options) {
9320
9347
  process.exit(0);
9321
9348
  } catch (err) {
9322
9349
  const msg = err instanceof Error ? err.message : String(err);
9323
- if (msg.includes("GRAPH_TIMEOUT")) {
9350
+ if (msg.includes("GRAPH_UNAVAILABLE")) {
9351
+ console.error("The knowledge graph for this project has no database configured. Contact your administrator or check the project setup.");
9352
+ } else if (msg.includes("GRAPH_TIMEOUT")) {
9324
9353
  console.error("Could not reach the knowledge graph. Make sure all required services are running.");
9325
9354
  } else if (msg.includes("METADATA_SYNC_FAILED")) {
9326
9355
  console.error("Metadata sync failed. Try again.");
@@ -9515,6 +9544,226 @@ Triples only in file 2 (${result.triplesOnlyInFile2.size}):`);
9515
9544
  process.exitCode = 1;
9516
9545
  }
9517
9546
 
9547
+ // apps/desktop/cue-cli/src/cue-cli-create-project.ts
9548
+ var readline2 = __toESM(require("readline"));
9549
+ function ask(rl, question) {
9550
+ return new Promise((resolve2) => rl.question(question, (answer) => resolve2(answer.trim())));
9551
+ }
9552
+ async function pickOne(rl, label, items, display) {
9553
+ console.log(`
9554
+ ${label}`);
9555
+ items.forEach((item, i) => console.log(` ${i + 1}. ${display(item)}`));
9556
+ while (true) {
9557
+ const answer = await ask(rl, `Enter number (1-${items.length}): `);
9558
+ const idx = parseInt(answer, 10) - 1;
9559
+ if (idx >= 0 && idx < items.length)
9560
+ return items[idx];
9561
+ console.log(" Invalid selection, try again.");
9562
+ }
9563
+ }
9564
+ async function pickMultipleOrAll(rl, label, items, display) {
9565
+ if (items.length === 0)
9566
+ return [];
9567
+ console.log(`
9568
+ ${label}`);
9569
+ items.forEach((item, i) => console.log(` ${i + 1}. ${display(item)}`));
9570
+ console.log(` 0. All`);
9571
+ const answer = await ask(rl, `Enter comma-separated numbers or 0 for all: `);
9572
+ if (answer === "0")
9573
+ return items;
9574
+ const indices = answer.split(",").map((s) => parseInt(s.trim(), 10) - 1).filter((i) => i >= 0 && i < items.length);
9575
+ return [...new Set(indices)].map((i) => items[i]);
9576
+ }
9577
+ async function createProjectHandler(options) {
9578
+ const { emulators, verbose } = options;
9579
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
9580
+ try {
9581
+ const key = options.key ?? process.env.CUE_API_KEY;
9582
+ if (!key) {
9583
+ console.error("API key is required. Provide it via --key or CUE_API_KEY env variable.");
9584
+ process.exit(1);
9585
+ }
9586
+ const cue = new CueNode({
9587
+ apiKey: FIREBASE_CONFIG().apiKey,
9588
+ appId: FIREBASE_CONFIG().appId,
9589
+ measurementId: FIREBASE_CONFIG().measurementId,
9590
+ environment: emulators ? "emulator" : "production",
9591
+ ...emulators ? { endpoints: getEmulatorEndpoints() } : {}
9592
+ });
9593
+ if (verbose)
9594
+ console.info("Authenticating \u23F3");
9595
+ const user = await cue.auth.signInWithApiKey(key);
9596
+ const idTokenResult = await user.getIdTokenResult();
9597
+ const isSuperAdmin = idTokenResult.claims["role"] === "superadmin";
9598
+ if (verbose)
9599
+ console.info(`Authenticated as ${user.uid} (superadmin: ${isSuperAdmin}) \u2705`);
9600
+ const gatewayUrl = emulators ? getEmulatorEndpoints().gatewayUrl : "https://accessors-api-gateway-ueyeemwf2a-oa.a.run.app";
9601
+ let orgId;
9602
+ let orgName;
9603
+ let orgMembers = [];
9604
+ let callerIsOrgAdmin = false;
9605
+ if (isSuperAdmin) {
9606
+ const orgsRes = await cue.auth.authenticatedFetch(`${gatewayUrl}/data-views/admin/organizations`);
9607
+ if (!orgsRes.ok) {
9608
+ console.error(`Failed to list organisations: ${orgsRes.status} ${orgsRes.statusText}`);
9609
+ process.exit(1);
9610
+ }
9611
+ const allOrgs = await orgsRes.json();
9612
+ if (allOrgs.length === 0) {
9613
+ console.error("No organisations found on the platform.");
9614
+ process.exit(1);
9615
+ }
9616
+ const picked = await pickOne(rl, "Select organisation:", allOrgs, (o) => `${o.name} (${o.id})`);
9617
+ orgId = picked.id;
9618
+ orgName = picked.name;
9619
+ callerIsOrgAdmin = picked.admins?.includes(user.uid) ?? false;
9620
+ const membersRes = await cue.auth.authenticatedFetch(`${gatewayUrl}/data-views/admin/organizations/${orgId}/members`);
9621
+ if (membersRes.ok)
9622
+ orgMembers = await membersRes.json();
9623
+ } else {
9624
+ const myOrgs = await cue.profile.listOrganizations();
9625
+ const adminOrgs = myOrgs.filter((o) => o.isAdmin);
9626
+ if (adminOrgs.length === 0) {
9627
+ console.error("You are not an admin of any organisation. Cannot create a project.");
9628
+ process.exit(1);
9629
+ }
9630
+ const picked = await pickOne(rl, "Select organisation:", adminOrgs, (o) => `${o.name} (${o.id})`);
9631
+ orgId = picked.id;
9632
+ orgName = picked.name;
9633
+ callerIsOrgAdmin = true;
9634
+ orgMembers = await cue.profile.getOrgMembers(orgId);
9635
+ }
9636
+ console.log(`
9637
+ Organisation: ${orgName} (${orgId})`);
9638
+ const projectName = await ask(rl, "\nProject name: ");
9639
+ if (!projectName) {
9640
+ console.error("Project name is required.");
9641
+ process.exit(1);
9642
+ }
9643
+ const graphType = await pickOne(
9644
+ rl,
9645
+ "Select graph backend (default: QLever):",
9646
+ [
9647
+ { value: "qlever", label: "QLever (recommended)" },
9648
+ { value: "fuseki", label: "Fuseki" }
9649
+ ],
9650
+ (item) => item.label
9651
+ ).then((item) => item.value);
9652
+ const tier = await pickOne(
9653
+ rl,
9654
+ "Select processing tier (default: L \u2014 Large):",
9655
+ [
9656
+ { value: "l", label: "L \u2014 Large (default)" },
9657
+ { value: "m", label: "M \u2014 Medium" },
9658
+ { value: "s", label: "S \u2014 Small" }
9659
+ ],
9660
+ (item) => item.label
9661
+ ).then((item) => item.value);
9662
+ let selectedAdmins = [];
9663
+ let selectedSyncers = [];
9664
+ let selectedMembers = [];
9665
+ if (isSuperAdmin) {
9666
+ const orgAdmins = orgMembers.filter((m) => m.isAdmin);
9667
+ if (orgAdmins.length === 0) {
9668
+ console.error("This organisation has no admins. Cannot create a project without at least one admin.");
9669
+ process.exit(1);
9670
+ }
9671
+ while (selectedAdmins.length === 0) {
9672
+ selectedAdmins = await pickMultipleOrAll(
9673
+ rl,
9674
+ "Select project admin(s) \u2014 at least one required:",
9675
+ orgAdmins,
9676
+ (m) => `${m.name} <${m.email}>`
9677
+ );
9678
+ if (selectedAdmins.length === 0)
9679
+ console.log(" At least one admin must be selected.");
9680
+ }
9681
+ }
9682
+ const nonAdminMembers = orgMembers.filter((m) => !selectedAdmins.some((a5) => a5.uid === m.uid));
9683
+ if (nonAdminMembers.length > 0) {
9684
+ selectedMembers = await pickMultipleOrAll(
9685
+ rl,
9686
+ "Select project members:",
9687
+ nonAdminMembers,
9688
+ (m) => `${m.name} <${m.email}>${m.isAdmin ? " (org admin)" : ""}`
9689
+ );
9690
+ }
9691
+ if (selectedMembers.length > 0) {
9692
+ const answer = await ask(rl, `
9693
+ Set all selected members as syncers as well? (Y/n): `);
9694
+ if (answer.toLowerCase() !== "n") {
9695
+ selectedSyncers = selectedMembers;
9696
+ } else {
9697
+ selectedSyncers = await pickMultipleOrAll(
9698
+ rl,
9699
+ "Select project syncers:",
9700
+ selectedMembers,
9701
+ (m) => `${m.name} <${m.email}>`
9702
+ );
9703
+ }
9704
+ }
9705
+ console.log("\n\u2500\u2500 Summary \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
9706
+ console.log(` Organisation : ${orgName}`);
9707
+ console.log(` Name : ${projectName}`);
9708
+ console.log(` Graph : ${graphType}`);
9709
+ console.log(` Tier : ${tier.toUpperCase()}`);
9710
+ if (isSuperAdmin) {
9711
+ console.log(` Admins : ${selectedAdmins.map((m) => m.email).join(", ")}`);
9712
+ } else {
9713
+ console.log(` Admins : (you)`);
9714
+ }
9715
+ console.log(` Members : ${selectedMembers.length === 0 ? "(none)" : selectedMembers.map((m) => m.email).join(", ")}`);
9716
+ console.log(` Syncers : ${selectedSyncers.length === 0 ? "(none)" : selectedSyncers.map((m) => m.email).join(", ")}`);
9717
+ console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
9718
+ const confirm = await ask(rl, "\nCreate project? (Y/n): ");
9719
+ if (confirm.toLowerCase() === "n") {
9720
+ console.log("Aborted.");
9721
+ process.exit(0);
9722
+ }
9723
+ if (verbose)
9724
+ console.info("Creating project \u23F3");
9725
+ const body = {
9726
+ organizationID: orgId,
9727
+ name: projectName,
9728
+ graphType,
9729
+ tier,
9730
+ ...selectedAdmins.length > 0 ? { admins: selectedAdmins.map((m) => m.uid) } : {},
9731
+ ...selectedMembers.length > 0 ? { members: selectedMembers.map((m) => m.uid) } : {},
9732
+ ...selectedSyncers.length > 0 ? { syncers: selectedSyncers.map((m) => m.uid) } : {}
9733
+ };
9734
+ let created;
9735
+ if (isSuperAdmin) {
9736
+ const res = await cue.auth.authenticatedFetch(`${gatewayUrl}/commands/admin/project`, {
9737
+ method: "POST",
9738
+ headers: { "Content-Type": "application/json" },
9739
+ body: JSON.stringify(body)
9740
+ });
9741
+ if (!res.ok) {
9742
+ const detail = await res.text().catch(() => "");
9743
+ console.error(`Failed to create project: ${res.status} ${res.statusText}${detail ? ` \u2014 ${detail}` : ""}`);
9744
+ process.exit(1);
9745
+ }
9746
+ created = await res.json();
9747
+ } else {
9748
+ created = await cue.projects.createProject({
9749
+ organizationID: orgId,
9750
+ name: projectName,
9751
+ graphType,
9752
+ tier,
9753
+ ...selectedAdmins.length > 0 ? { admins: selectedAdmins.map((m) => m.uid) } : {},
9754
+ ...selectedMembers.length > 0 ? { members: selectedMembers.map((m) => m.uid) } : {},
9755
+ ...selectedSyncers.length > 0 ? { syncers: selectedSyncers.map((m) => m.uid) } : {}
9756
+ });
9757
+ }
9758
+ console.log(`
9759
+ Project created \u2705`);
9760
+ console.log(` ID : ${created["id"]}`);
9761
+ console.log(` Name : ${created["name"]}`);
9762
+ } finally {
9763
+ rl.close();
9764
+ }
9765
+ }
9766
+
9518
9767
  // apps/desktop/cue-cli/src/main.ts
9519
9768
  var packageJson;
9520
9769
  try {
@@ -9536,4 +9785,5 @@ program.command("dump-processed").description("Dump processed files to local fol
9536
9785
  program.command("repair-ttl").description("Repair TTL files in the specified space").requiredOption("-s, --space <id>", "Specify the space ID (required)").requiredOption("-p, --processor <id>", "Id of the processor to repair TTL files (required) [eg. writers-blob, processors-cad-files]").requiredOption("-f, --from <subString>", "Substring (Regex) to replace in the TTL file (required)").requiredOption("-t, --to <substituteString>", "Substring to replace in the TTL file (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).action(repairTtlHandler);
9537
9786
  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);
9538
9787
  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);
9788
+ 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);
9539
9789
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qaecy/cue-cli",
3
- "version": "0.0.39",
3
+ "version": "0.0.41",
4
4
  "description": "Cue CLI for QAECY platform",
5
5
  "main": "main.js",
6
6
  "bin": {
@@ -16,7 +16,7 @@
16
16
  "dependencies": {
17
17
  "@google-cloud/pubsub": "4.4.1",
18
18
  "axios": "1.14.0",
19
- "commander": "13.1.0",
19
+ "commander": "14.0.2",
20
20
  "firebase": "12.4.0",
21
21
  "firebase-admin": "13.0.2",
22
22
  "jsonld": "8.3.3",