create-interview-cockpit 0.1.1 → 0.3.0

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.
@@ -1,5 +1,5 @@
1
1
  import { create } from "zustand";
2
- import type { Topic, Question, CodeSnippet } from "./types";
2
+ import type { Topic, Question, CodeSnippet, WorkspaceMeta } from "./types";
3
3
  import * as api from "./api";
4
4
 
5
5
  interface Store {
@@ -14,6 +14,48 @@ interface Store {
14
14
  showSidebar: boolean;
15
15
  viewingFile: string | null;
16
16
 
17
+ // ── Workspaces ───────────────────────────────────────────────
18
+ workspaces: WorkspaceMeta[];
19
+ activeWorkspaceId: string | null;
20
+ driveRootFolders: import("./api").DriveFolder[];
21
+ loadingDriveFolders: boolean;
22
+ fetchWorkspaces: () => Promise<void>;
23
+ createWorkspace: (
24
+ name: string,
25
+ type: "local" | "google_drive",
26
+ ) => Promise<void>;
27
+ activateWorkspace: (id: string) => Promise<void>;
28
+ deleteWorkspace: (id: string) => Promise<void>;
29
+ renameWorkspace: (id: string, name: string) => Promise<void>;
30
+ patchWorkspace: (id: string, data: object) => Promise<void>;
31
+ syncWorkspace: (id: string) => Promise<{
32
+ topicsUpserted: number;
33
+ filesImported: number;
34
+ filesSkipped: number;
35
+ errors: string[];
36
+ }>;
37
+ linkDriveFolder: (
38
+ workspaceId: string,
39
+ url: string,
40
+ ) => Promise<{ folders: import("./api").DriveFolder[] }>;
41
+ selectDriveSubfolder: (
42
+ workspaceId: string,
43
+ subFolderId: string,
44
+ subFolderName: string,
45
+ ) => Promise<void>;
46
+ clearDriveSubfolder: (workspaceId: string) => Promise<void>;
47
+ fetchDriveRootFolders: (workspaceId: string) => Promise<void>;
48
+ attachDriveFolder: (workspaceId: string, url: string) => Promise<void>;
49
+ exportWorkspace: (
50
+ id: string,
51
+ targetFolderId?: string,
52
+ ) => Promise<import("./api").ExportWorkspaceResult>;
53
+ fetchDriveSubfolders: (id: string) => Promise<import("./api").DriveFolder[]>;
54
+ createDriveSubfolder: (
55
+ id: string,
56
+ name: string,
57
+ ) => Promise<import("./api").DriveFolder>;
58
+
17
59
  fetchTopics: () => Promise<void>;
18
60
  fetchQuestions: (topicId: string) => Promise<void>;
19
61
  addTopic: (name: string) => Promise<void>;
@@ -74,6 +116,151 @@ export const useStore = create<Store>((set, get) => ({
74
116
  viewingFile: null,
75
117
  codeSnippets: [],
76
118
 
119
+ // ── Workspaces ───────────────────────────────────────────────
120
+ workspaces: [],
121
+ activeWorkspaceId: null,
122
+ driveRootFolders: [],
123
+ loadingDriveFolders: false,
124
+
125
+ fetchWorkspaces: async () => {
126
+ const registry = await api.fetchWorkspaces();
127
+ set({
128
+ workspaces: registry.workspaces,
129
+ activeWorkspaceId: registry.activeWorkspaceId,
130
+ });
131
+ },
132
+
133
+ createWorkspace: async (name, type) => {
134
+ const registry = await api.createWorkspace(name, type);
135
+ set({
136
+ workspaces: registry.workspaces,
137
+ activeWorkspaceId: registry.activeWorkspaceId,
138
+ });
139
+ },
140
+
141
+ activateWorkspace: async (id) => {
142
+ const registry = await api.activateWorkspaceApi(id);
143
+ set({
144
+ workspaces: registry.workspaces,
145
+ activeWorkspaceId: registry.activeWorkspaceId,
146
+ // Reset all topic/question state for the newly active workspace
147
+ topics: [],
148
+ questionsByTopic: {},
149
+ selectedTopicId: null,
150
+ selectedQuestionId: null,
151
+ currentQuestion: null,
152
+ expandedTopics: [],
153
+ codeSnippets: [],
154
+ });
155
+ const topics = await api.fetchTopics();
156
+ set({ topics });
157
+ },
158
+
159
+ deleteWorkspace: async (id) => {
160
+ const wasActive = get().activeWorkspaceId === id;
161
+ const registry = await api.deleteWorkspaceApi(id);
162
+ set({
163
+ workspaces: registry.workspaces,
164
+ activeWorkspaceId: registry.activeWorkspaceId,
165
+ });
166
+ if (wasActive) {
167
+ set({
168
+ topics: [],
169
+ questionsByTopic: {},
170
+ selectedTopicId: null,
171
+ selectedQuestionId: null,
172
+ currentQuestion: null,
173
+ expandedTopics: [],
174
+ codeSnippets: [],
175
+ });
176
+ const topics = await api.fetchTopics();
177
+ set({ topics });
178
+ }
179
+ },
180
+
181
+ renameWorkspace: async (id, name) => {
182
+ const registry = await api.renameWorkspace(id, name);
183
+ set({ workspaces: registry.workspaces });
184
+ },
185
+
186
+ patchWorkspace: async (id, data) => {
187
+ const registry = await api.patchWorkspace(id, data);
188
+ set({ workspaces: registry.workspaces });
189
+ },
190
+
191
+ syncWorkspace: async (id) => {
192
+ const result = await api.syncWorkspaceApi(id);
193
+ if (id === get().activeWorkspaceId) {
194
+ const topics = await api.fetchTopics();
195
+ set({ topics, questionsByTopic: {} });
196
+ }
197
+ const registry = await api.fetchWorkspaces();
198
+ set({ workspaces: registry.workspaces });
199
+ return result;
200
+ },
201
+
202
+ linkDriveFolder: async (workspaceId, url) => {
203
+ const { registry, folders } = await api.linkDriveFolder(workspaceId, url);
204
+ set({ workspaces: registry.workspaces, driveRootFolders: folders });
205
+ return { folders };
206
+ },
207
+
208
+ selectDriveSubfolder: async (workspaceId, subFolderId, subFolderName) => {
209
+ // Persist the selected subfolder on the workspace
210
+ await api.selectDriveSubfolder(workspaceId, subFolderId, subFolderName);
211
+ const registry = await api.fetchWorkspaces();
212
+ set({ workspaces: registry.workspaces });
213
+ // Sync so the topics update to reflect the chosen subfolder
214
+ if (workspaceId === get().activeWorkspaceId) {
215
+ set({ topics: [], questionsByTopic: {} });
216
+ const result = await api.syncWorkspaceApi(workspaceId);
217
+ const topics = await api.fetchTopics();
218
+ set({ topics, questionsByTopic: {} });
219
+ const reg2 = await api.fetchWorkspaces();
220
+ set({ workspaces: reg2.workspaces });
221
+ }
222
+ },
223
+
224
+ clearDriveSubfolder: async (workspaceId) => {
225
+ await api.selectDriveSubfolder(workspaceId, null, null);
226
+ const registry = await api.fetchWorkspaces();
227
+ set({
228
+ workspaces: registry.workspaces,
229
+ topics: [],
230
+ questionsByTopic: {},
231
+ selectedTopicId: null,
232
+ selectedQuestionId: null,
233
+ currentQuestion: null,
234
+ });
235
+ },
236
+
237
+ fetchDriveRootFolders: async (workspaceId) => {
238
+ set({ loadingDriveFolders: true });
239
+ try {
240
+ const folders = await api.fetchDriveSubfolders(workspaceId);
241
+ set({ driveRootFolders: folders });
242
+ } finally {
243
+ set({ loadingDriveFolders: false });
244
+ }
245
+ },
246
+
247
+ attachDriveFolder: async (workspaceId, url) => {
248
+ const registry = await api.attachDriveFolder(workspaceId, url);
249
+ set({ workspaces: registry.workspaces });
250
+ },
251
+
252
+ exportWorkspace: async (id, targetFolderId) => {
253
+ return api.exportWorkspaceToDrive(id, targetFolderId);
254
+ },
255
+
256
+ fetchDriveSubfolders: async (id) => {
257
+ return api.fetchDriveSubfolders(id);
258
+ },
259
+
260
+ createDriveSubfolder: async (id, name) => {
261
+ return api.createDriveSubfolder(id, name);
262
+ },
263
+
77
264
  fetchTopics: async () => {
78
265
  const topics = await api.fetchTopics();
79
266
  set({ topics });
@@ -175,6 +362,8 @@ export const useStore = create<Store>((set, get) => ({
175
362
  currentQuestion: question,
176
363
  codeSnippets: [],
177
364
  });
365
+ sessionStorage.setItem("lastTopicId", topicId);
366
+ sessionStorage.setItem("lastQuestionId", questionId);
178
367
  },
179
368
 
180
369
  addSnippet: (snippet) =>
@@ -2,9 +2,29 @@ export interface ContextFile {
2
2
  id: string;
3
3
  name: string;
4
4
  originalName: string;
5
+ driveFileId?: string;
5
6
  createdAt: string;
6
7
  }
7
8
 
9
+ export interface WorkspaceMeta {
10
+ id: string;
11
+ name: string;
12
+ type: "local" | "google_drive";
13
+ driveConfig?: {
14
+ folderId: string;
15
+ folderName: string;
16
+ lastSyncedAt?: string;
17
+ subFolderId?: string;
18
+ subFolderName?: string;
19
+ };
20
+ createdAt: string;
21
+ }
22
+
23
+ export interface WorkspacesRegistry {
24
+ activeWorkspaceId: string;
25
+ workspaces: WorkspaceMeta[];
26
+ }
27
+
8
28
  export interface Topic {
9
29
  id: string;
10
30
  name: string;
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "0.1.0"
2
+ "version": "0.2.0"
3
3
  }
@@ -13,6 +13,7 @@
13
13
  "cors": "^2.8.5",
14
14
  "dotenv": "^16.4.0",
15
15
  "express": "^4.21.0",
16
+ "googleapis": "^171.4.0",
16
17
  "mammoth": "^1.12.0",
17
18
  "multer": "^2.1.1",
18
19
  "pdf-parse": "^2.4.5",
@@ -922,6 +923,15 @@
922
923
  "node": ">= 0.6"
923
924
  }
924
925
  },
926
+ "node_modules/agent-base": {
927
+ "version": "7.1.4",
928
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
929
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
930
+ "license": "MIT",
931
+ "engines": {
932
+ "node": ">= 14"
933
+ }
934
+ },
925
935
  "node_modules/ai": {
926
936
  "version": "6.0.168",
927
937
  "resolved": "https://registry.npmjs.org/ai/-/ai-6.0.168.tgz",
@@ -981,6 +991,15 @@
981
991
  ],
982
992
  "license": "MIT"
983
993
  },
994
+ "node_modules/bignumber.js": {
995
+ "version": "9.3.1",
996
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz",
997
+ "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==",
998
+ "license": "MIT",
999
+ "engines": {
1000
+ "node": "*"
1001
+ }
1002
+ },
984
1003
  "node_modules/bluebird": {
985
1004
  "version": "3.4.7",
986
1005
  "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz",
@@ -1011,6 +1030,12 @@
1011
1030
  "npm": "1.2.8000 || >= 1.4.16"
1012
1031
  }
1013
1032
  },
1033
+ "node_modules/buffer-equal-constant-time": {
1034
+ "version": "1.0.1",
1035
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
1036
+ "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
1037
+ "license": "BSD-3-Clause"
1038
+ },
1014
1039
  "node_modules/buffer-from": {
1015
1040
  "version": "1.1.2",
1016
1041
  "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
@@ -1140,6 +1165,15 @@
1140
1165
  "url": "https://opencollective.com/express"
1141
1166
  }
1142
1167
  },
1168
+ "node_modules/data-uri-to-buffer": {
1169
+ "version": "4.0.1",
1170
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
1171
+ "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
1172
+ "license": "MIT",
1173
+ "engines": {
1174
+ "node": ">= 12"
1175
+ }
1176
+ },
1143
1177
  "node_modules/debug": {
1144
1178
  "version": "2.6.9",
1145
1179
  "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -1209,6 +1243,15 @@
1209
1243
  "node": ">= 0.4"
1210
1244
  }
1211
1245
  },
1246
+ "node_modules/ecdsa-sig-formatter": {
1247
+ "version": "1.0.11",
1248
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
1249
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
1250
+ "license": "Apache-2.0",
1251
+ "dependencies": {
1252
+ "safe-buffer": "^5.0.1"
1253
+ }
1254
+ },
1212
1255
  "node_modules/ee-first": {
1213
1256
  "version": "1.1.1",
1214
1257
  "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
@@ -1366,6 +1409,35 @@
1366
1409
  "url": "https://opencollective.com/express"
1367
1410
  }
1368
1411
  },
1412
+ "node_modules/extend": {
1413
+ "version": "3.0.2",
1414
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
1415
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
1416
+ "license": "MIT"
1417
+ },
1418
+ "node_modules/fetch-blob": {
1419
+ "version": "3.2.0",
1420
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
1421
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
1422
+ "funding": [
1423
+ {
1424
+ "type": "github",
1425
+ "url": "https://github.com/sponsors/jimmywarting"
1426
+ },
1427
+ {
1428
+ "type": "paypal",
1429
+ "url": "https://paypal.me/jimmywarting"
1430
+ }
1431
+ ],
1432
+ "license": "MIT",
1433
+ "dependencies": {
1434
+ "node-domexception": "^1.0.0",
1435
+ "web-streams-polyfill": "^3.0.3"
1436
+ },
1437
+ "engines": {
1438
+ "node": "^12.20 || >= 14.13"
1439
+ }
1440
+ },
1369
1441
  "node_modules/finalhandler": {
1370
1442
  "version": "1.3.2",
1371
1443
  "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz",
@@ -1384,6 +1456,18 @@
1384
1456
  "node": ">= 0.8"
1385
1457
  }
1386
1458
  },
1459
+ "node_modules/formdata-polyfill": {
1460
+ "version": "4.0.10",
1461
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
1462
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
1463
+ "license": "MIT",
1464
+ "dependencies": {
1465
+ "fetch-blob": "^3.1.2"
1466
+ },
1467
+ "engines": {
1468
+ "node": ">=12.20.0"
1469
+ }
1470
+ },
1387
1471
  "node_modules/forwarded": {
1388
1472
  "version": "0.2.0",
1389
1473
  "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -1426,6 +1510,34 @@
1426
1510
  "url": "https://github.com/sponsors/ljharb"
1427
1511
  }
1428
1512
  },
1513
+ "node_modules/gaxios": {
1514
+ "version": "7.1.4",
1515
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-7.1.4.tgz",
1516
+ "integrity": "sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==",
1517
+ "license": "Apache-2.0",
1518
+ "dependencies": {
1519
+ "extend": "^3.0.2",
1520
+ "https-proxy-agent": "^7.0.1",
1521
+ "node-fetch": "^3.3.2"
1522
+ },
1523
+ "engines": {
1524
+ "node": ">=18"
1525
+ }
1526
+ },
1527
+ "node_modules/gcp-metadata": {
1528
+ "version": "8.1.2",
1529
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-8.1.2.tgz",
1530
+ "integrity": "sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==",
1531
+ "license": "Apache-2.0",
1532
+ "dependencies": {
1533
+ "gaxios": "^7.0.0",
1534
+ "google-logging-utils": "^1.0.0",
1535
+ "json-bigint": "^1.0.0"
1536
+ },
1537
+ "engines": {
1538
+ "node": ">=18"
1539
+ }
1540
+ },
1429
1541
  "node_modules/get-intrinsic": {
1430
1542
  "version": "1.3.0",
1431
1543
  "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
@@ -1476,6 +1588,61 @@
1476
1588
  "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
1477
1589
  }
1478
1590
  },
1591
+ "node_modules/google-auth-library": {
1592
+ "version": "10.6.2",
1593
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-10.6.2.tgz",
1594
+ "integrity": "sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==",
1595
+ "license": "Apache-2.0",
1596
+ "dependencies": {
1597
+ "base64-js": "^1.3.0",
1598
+ "ecdsa-sig-formatter": "^1.0.11",
1599
+ "gaxios": "^7.1.4",
1600
+ "gcp-metadata": "8.1.2",
1601
+ "google-logging-utils": "1.1.3",
1602
+ "jws": "^4.0.0"
1603
+ },
1604
+ "engines": {
1605
+ "node": ">=18"
1606
+ }
1607
+ },
1608
+ "node_modules/google-logging-utils": {
1609
+ "version": "1.1.3",
1610
+ "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-1.1.3.tgz",
1611
+ "integrity": "sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==",
1612
+ "license": "Apache-2.0",
1613
+ "engines": {
1614
+ "node": ">=14"
1615
+ }
1616
+ },
1617
+ "node_modules/googleapis": {
1618
+ "version": "171.4.0",
1619
+ "resolved": "https://registry.npmjs.org/googleapis/-/googleapis-171.4.0.tgz",
1620
+ "integrity": "sha512-xybFL2SmmUgIifgsbsRQYRdNrSAYwxWZDmkZTGjUIaRnX5jPqR8el/cEvo6rCqh7iaZx6MfEPS/lrDgZ0bymkg==",
1621
+ "license": "Apache-2.0",
1622
+ "dependencies": {
1623
+ "google-auth-library": "^10.2.0",
1624
+ "googleapis-common": "^8.0.0"
1625
+ },
1626
+ "engines": {
1627
+ "node": ">=18"
1628
+ }
1629
+ },
1630
+ "node_modules/googleapis-common": {
1631
+ "version": "8.0.1",
1632
+ "resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-8.0.1.tgz",
1633
+ "integrity": "sha512-eCzNACUXPb1PW5l0ULTzMHaL/ltPRADoPgjBlT8jWsTbxkCp6siv+qKJ/1ldaybCthGwsYFYallF7u9AkU4L+A==",
1634
+ "license": "Apache-2.0",
1635
+ "dependencies": {
1636
+ "extend": "^3.0.2",
1637
+ "gaxios": "^7.0.0-rc.4",
1638
+ "google-auth-library": "^10.1.0",
1639
+ "qs": "^6.7.0",
1640
+ "url-template": "^2.0.8"
1641
+ },
1642
+ "engines": {
1643
+ "node": ">=18.0.0"
1644
+ }
1645
+ },
1479
1646
  "node_modules/gopd": {
1480
1647
  "version": "1.2.0",
1481
1648
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -1532,6 +1699,42 @@
1532
1699
  "url": "https://opencollective.com/express"
1533
1700
  }
1534
1701
  },
1702
+ "node_modules/https-proxy-agent": {
1703
+ "version": "7.0.6",
1704
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
1705
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
1706
+ "license": "MIT",
1707
+ "dependencies": {
1708
+ "agent-base": "^7.1.2",
1709
+ "debug": "4"
1710
+ },
1711
+ "engines": {
1712
+ "node": ">= 14"
1713
+ }
1714
+ },
1715
+ "node_modules/https-proxy-agent/node_modules/debug": {
1716
+ "version": "4.4.3",
1717
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
1718
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
1719
+ "license": "MIT",
1720
+ "dependencies": {
1721
+ "ms": "^2.1.3"
1722
+ },
1723
+ "engines": {
1724
+ "node": ">=6.0"
1725
+ },
1726
+ "peerDependenciesMeta": {
1727
+ "supports-color": {
1728
+ "optional": true
1729
+ }
1730
+ }
1731
+ },
1732
+ "node_modules/https-proxy-agent/node_modules/ms": {
1733
+ "version": "2.1.3",
1734
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1735
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1736
+ "license": "MIT"
1737
+ },
1535
1738
  "node_modules/iconv-lite": {
1536
1739
  "version": "0.4.24",
1537
1740
  "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -1571,6 +1774,15 @@
1571
1774
  "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
1572
1775
  "license": "MIT"
1573
1776
  },
1777
+ "node_modules/json-bigint": {
1778
+ "version": "1.0.0",
1779
+ "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
1780
+ "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
1781
+ "license": "MIT",
1782
+ "dependencies": {
1783
+ "bignumber.js": "^9.0.0"
1784
+ }
1785
+ },
1574
1786
  "node_modules/json-schema": {
1575
1787
  "version": "0.4.0",
1576
1788
  "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
@@ -1619,6 +1831,27 @@
1619
1831
  "safe-buffer": "~5.1.0"
1620
1832
  }
1621
1833
  },
1834
+ "node_modules/jwa": {
1835
+ "version": "2.0.1",
1836
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz",
1837
+ "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==",
1838
+ "license": "MIT",
1839
+ "dependencies": {
1840
+ "buffer-equal-constant-time": "^1.0.1",
1841
+ "ecdsa-sig-formatter": "1.0.11",
1842
+ "safe-buffer": "^5.0.1"
1843
+ }
1844
+ },
1845
+ "node_modules/jws": {
1846
+ "version": "4.0.1",
1847
+ "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz",
1848
+ "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==",
1849
+ "license": "MIT",
1850
+ "dependencies": {
1851
+ "jwa": "^2.0.1",
1852
+ "safe-buffer": "^5.0.1"
1853
+ }
1854
+ },
1622
1855
  "node_modules/lie": {
1623
1856
  "version": "3.3.0",
1624
1857
  "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
@@ -1766,6 +1999,44 @@
1766
1999
  "node": ">= 0.6"
1767
2000
  }
1768
2001
  },
2002
+ "node_modules/node-domexception": {
2003
+ "version": "1.0.0",
2004
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
2005
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
2006
+ "deprecated": "Use your platform's native DOMException instead",
2007
+ "funding": [
2008
+ {
2009
+ "type": "github",
2010
+ "url": "https://github.com/sponsors/jimmywarting"
2011
+ },
2012
+ {
2013
+ "type": "github",
2014
+ "url": "https://paypal.me/jimmywarting"
2015
+ }
2016
+ ],
2017
+ "license": "MIT",
2018
+ "engines": {
2019
+ "node": ">=10.5.0"
2020
+ }
2021
+ },
2022
+ "node_modules/node-fetch": {
2023
+ "version": "3.3.2",
2024
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
2025
+ "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
2026
+ "license": "MIT",
2027
+ "dependencies": {
2028
+ "data-uri-to-buffer": "^4.0.0",
2029
+ "fetch-blob": "^3.1.4",
2030
+ "formdata-polyfill": "^4.0.10"
2031
+ },
2032
+ "engines": {
2033
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
2034
+ },
2035
+ "funding": {
2036
+ "type": "opencollective",
2037
+ "url": "https://opencollective.com/node-fetch"
2038
+ }
2039
+ },
1769
2040
  "node_modules/object-assign": {
1770
2041
  "version": "4.1.1",
1771
2042
  "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -2220,6 +2491,12 @@
2220
2491
  "node": ">= 0.8"
2221
2492
  }
2222
2493
  },
2494
+ "node_modules/url-template": {
2495
+ "version": "2.0.8",
2496
+ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
2497
+ "integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==",
2498
+ "license": "BSD"
2499
+ },
2223
2500
  "node_modules/util-deprecate": {
2224
2501
  "version": "1.0.2",
2225
2502
  "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -2244,6 +2521,15 @@
2244
2521
  "node": ">= 0.8"
2245
2522
  }
2246
2523
  },
2524
+ "node_modules/web-streams-polyfill": {
2525
+ "version": "3.3.3",
2526
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
2527
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
2528
+ "license": "MIT",
2529
+ "engines": {
2530
+ "node": ">= 8"
2531
+ }
2532
+ },
2247
2533
  "node_modules/xmlbuilder": {
2248
2534
  "version": "10.1.1",
2249
2535
  "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-10.1.1.tgz",
@@ -14,6 +14,7 @@
14
14
  "cors": "^2.8.5",
15
15
  "dotenv": "^16.4.0",
16
16
  "express": "^4.21.0",
17
+ "googleapis": "^171.4.0",
17
18
  "mammoth": "^1.12.0",
18
19
  "multer": "^2.1.1",
19
20
  "pdf-parse": "^2.4.5",