@citolab/qti-backend-firebase 0.0.3

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 (111) hide show
  1. package/LICENSE.md +674 -0
  2. package/dist/api/app-specific/base/application-specific-base.d.ts +45 -0
  3. package/dist/api/app-specific/base/application-specific-base.d.ts.map +1 -0
  4. package/dist/api/app-specific/base/application-specific-base.js +503 -0
  5. package/dist/api/app-specific/base/application-specific-base.js.map +1 -0
  6. package/dist/api/app-specific/base/cheerio-helper.d.ts +5 -0
  7. package/dist/api/app-specific/base/cheerio-helper.d.ts.map +1 -0
  8. package/dist/api/app-specific/base/cheerio-helper.js +16 -0
  9. package/dist/api/app-specific/base/cheerio-helper.js.map +1 -0
  10. package/dist/api/app-specific/baseImplementation.d.ts +6 -0
  11. package/dist/api/app-specific/baseImplementation.d.ts.map +1 -0
  12. package/dist/api/app-specific/baseImplementation.js +11 -0
  13. package/dist/api/app-specific/baseImplementation.js.map +1 -0
  14. package/dist/api/app-specific/index.d.ts +4 -0
  15. package/dist/api/app-specific/index.d.ts.map +1 -0
  16. package/dist/api/app-specific/index.js +4 -0
  17. package/dist/api/app-specific/index.js.map +1 -0
  18. package/dist/api/app-specific/interface/IApplicationSpecific.d.ts +31 -0
  19. package/dist/api/app-specific/interface/IApplicationSpecific.d.ts.map +1 -0
  20. package/dist/api/app-specific/interface/IApplicationSpecific.js +2 -0
  21. package/dist/api/app-specific/interface/IApplicationSpecific.js.map +1 -0
  22. package/dist/api/app-specific/specific.d.ts +1 -0
  23. package/dist/api/app-specific/specific.d.ts.map +1 -0
  24. package/dist/api/app-specific/specific.js +31 -0
  25. package/dist/api/app-specific/specific.js.map +1 -0
  26. package/dist/api/index.d.ts +3 -0
  27. package/dist/api/index.d.ts.map +1 -0
  28. package/dist/api/index.js +15 -0
  29. package/dist/api/index.js.map +1 -0
  30. package/dist/api/qti-data.d.ts +4 -0
  31. package/dist/api/qti-data.d.ts.map +1 -0
  32. package/dist/api/qti-data.js +622 -0
  33. package/dist/api/qti-data.js.map +1 -0
  34. package/dist/api/qti-resources.d.ts +4 -0
  35. package/dist/api/qti-resources.d.ts.map +1 -0
  36. package/dist/api/qti-resources.js +348 -0
  37. package/dist/api/qti-resources.js.map +1 -0
  38. package/dist/api/qti-teacher.d.ts +6 -0
  39. package/dist/api/qti-teacher.d.ts.map +1 -0
  40. package/dist/api/qti-teacher.js +807 -0
  41. package/dist/api/qti-teacher.js.map +1 -0
  42. package/dist/api/qti-tools.d.ts +3 -0
  43. package/dist/api/qti-tools.d.ts.map +1 -0
  44. package/dist/api/qti-tools.js +450 -0
  45. package/dist/api/qti-tools.js.map +1 -0
  46. package/dist/console.d.ts +2 -0
  47. package/dist/console.d.ts.map +1 -0
  48. package/dist/console.js +30 -0
  49. package/dist/console.js.map +1 -0
  50. package/dist/express-test.d.ts +2 -0
  51. package/dist/express-test.d.ts.map +1 -0
  52. package/dist/express-test.js +19 -0
  53. package/dist/express-test.js.map +1 -0
  54. package/dist/helpers/ci-bootstap.d.ts +4 -0
  55. package/dist/helpers/ci-bootstap.d.ts.map +1 -0
  56. package/dist/helpers/ci-bootstap.js +96 -0
  57. package/dist/helpers/ci-bootstap.js.map +1 -0
  58. package/dist/helpers/database.d.ts +110 -0
  59. package/dist/helpers/database.d.ts.map +1 -0
  60. package/dist/helpers/database.js +151 -0
  61. package/dist/helpers/database.js.map +1 -0
  62. package/dist/helpers/db.d.ts +3 -0
  63. package/dist/helpers/db.d.ts.map +1 -0
  64. package/dist/helpers/db.js +10 -0
  65. package/dist/helpers/db.js.map +1 -0
  66. package/dist/helpers/endpoint-helpers.d.ts +33 -0
  67. package/dist/helpers/endpoint-helpers.d.ts.map +1 -0
  68. package/dist/helpers/endpoint-helpers.js +149 -0
  69. package/dist/helpers/endpoint-helpers.js.map +1 -0
  70. package/dist/helpers/firebase.d.ts +7 -0
  71. package/dist/helpers/firebase.d.ts.map +1 -0
  72. package/dist/helpers/firebase.js +15 -0
  73. package/dist/helpers/firebase.js.map +1 -0
  74. package/dist/helpers/index.d.ts +11 -0
  75. package/dist/helpers/index.d.ts.map +1 -0
  76. package/dist/helpers/index.js +11 -0
  77. package/dist/helpers/index.js.map +1 -0
  78. package/dist/helpers/local-helpers.d.ts +2 -0
  79. package/dist/helpers/local-helpers.d.ts.map +1 -0
  80. package/dist/helpers/local-helpers.js +11 -0
  81. package/dist/helpers/local-helpers.js.map +1 -0
  82. package/dist/helpers/logic.d.ts +73 -0
  83. package/dist/helpers/logic.d.ts.map +1 -0
  84. package/dist/helpers/logic.js +759 -0
  85. package/dist/helpers/logic.js.map +1 -0
  86. package/dist/helpers/package-upload.d.ts +16 -0
  87. package/dist/helpers/package-upload.d.ts.map +1 -0
  88. package/dist/helpers/package-upload.js +160 -0
  89. package/dist/helpers/package-upload.js.map +1 -0
  90. package/dist/helpers/package.d.ts +32 -0
  91. package/dist/helpers/package.d.ts.map +1 -0
  92. package/dist/helpers/package.js +373 -0
  93. package/dist/helpers/package.js.map +1 -0
  94. package/dist/helpers/request-headers.d.ts +27 -0
  95. package/dist/helpers/request-headers.d.ts.map +1 -0
  96. package/dist/helpers/request-headers.js +144 -0
  97. package/dist/helpers/request-headers.js.map +1 -0
  98. package/dist/helpers/storage.d.ts +10 -0
  99. package/dist/helpers/storage.d.ts.map +1 -0
  100. package/dist/helpers/storage.js +132 -0
  101. package/dist/helpers/storage.js.map +1 -0
  102. package/dist/helpers/utils.d.ts +42 -0
  103. package/dist/helpers/utils.d.ts.map +1 -0
  104. package/dist/helpers/utils.js +228 -0
  105. package/dist/helpers/utils.js.map +1 -0
  106. package/dist/main.d.ts +2 -0
  107. package/dist/main.d.ts.map +1 -0
  108. package/dist/main.js +14 -0
  109. package/dist/main.js.map +1 -0
  110. package/package.json +101 -0
  111. package/readme.md +11 -0
@@ -0,0 +1,132 @@
1
+ import { readFileSync } from 'fs';
2
+ import * as cheerio from 'cheerio';
3
+ import * as admin from 'firebase-admin';
4
+ import fs from 'fs';
5
+ import { cleanXMLString } from '@citolab/qti-convert/qti-convert';
6
+ import path from 'path';
7
+ import { getStorage } from './firebase';
8
+ export const storeXml = async (location, xml) => {
9
+ const storage = getStorage();
10
+ const file = storage.bucket().file(`${location}`);
11
+ await file.save(xml);
12
+ };
13
+ export const storageFileToXml = async (file) => {
14
+ try {
15
+ const downloadResult = await file.download();
16
+ if (downloadResult) {
17
+ const content = cleanXMLString(downloadResult[0].toString('utf8'));
18
+ return cheerio.load(content, { xmlMode: true, xml: true });
19
+ }
20
+ }
21
+ catch (e) {
22
+ console.log('could not download or parse xml file: ' + e);
23
+ }
24
+ return cheerio.load('', { xmlMode: true, xml: true });
25
+ };
26
+ export async function deleteFilesRecursive(bucket, directory, excludeFiles = []) {
27
+ try {
28
+ // List all files in the directory
29
+ const [files] = await bucket.getFiles({ prefix: directory });
30
+ // Filter files to exclude the ones specified in excludeFiles array
31
+ const filesToDelete = files.filter((file) => !excludeFiles.includes(file.name.replace(directory, '').replace('/', '')));
32
+ // Delete the files
33
+ const deletePromises = filesToDelete.map((file) => file.delete());
34
+ // Wait for all deletions to complete
35
+ await Promise.all(deletePromises);
36
+ console.log(`Deleted ${filesToDelete.length} files from ${directory}`);
37
+ }
38
+ catch (error) {
39
+ console.error('Error deleting files:', error);
40
+ }
41
+ }
42
+ export const pollForStorageFile = async (bucketname, fileRef, maxAttempts = 8) => {
43
+ let found = false;
44
+ let attempt = 0;
45
+ while (!found && attempt < maxAttempts) {
46
+ attempt++;
47
+ const storage = getStorage();
48
+ const manifest = storage.bucket(bucketname).file(fileRef);
49
+ const manifestExists = await manifest.exists();
50
+ if (manifestExists.length > 0 && manifestExists[0]) {
51
+ found = true;
52
+ return manifest;
53
+ }
54
+ else {
55
+ await new Promise((resolve) => setTimeout(resolve, 500));
56
+ }
57
+ }
58
+ };
59
+ // Initialize Firebase Admin for two different projects
60
+ const initFirebaseApp = (adminSdkJson, appName) => {
61
+ const firebaseContent = readFileSync(adminSdkJson, 'utf8');
62
+ const config = JSON.parse(firebaseContent);
63
+ return admin.initializeApp({
64
+ credential: admin.credential.cert(config),
65
+ databaseURL: `https://${config.project_id}.firebaseio.com`,
66
+ storageBucket: `gs://${config.project_id}.appspot.com`,
67
+ }, appName);
68
+ };
69
+ const copyFilesRecursively = async (originBucket, destBucket, originPath, destPath) => {
70
+ try {
71
+ const tempDir = `${process.cwd()}/temp`;
72
+ if (!fs.existsSync(tempDir)) {
73
+ fs.mkdirSync(tempDir);
74
+ }
75
+ const [files] = await originBucket.getFiles({ prefix: originPath });
76
+ console.log(`Processing ${files.length} items in directory: ${originPath}`);
77
+ // Group files by full relative folder path
78
+ const folderGroups = {};
79
+ for (const file of files) {
80
+ const relativePath = file.name.substring(originPath.length);
81
+ const dirPath = path.dirname(relativePath); // full folder path relative to originPath
82
+ if (!folderGroups[dirPath]) {
83
+ folderGroups[dirPath] = [];
84
+ }
85
+ folderGroups[dirPath].push(file);
86
+ }
87
+ for (const folder in folderGroups) {
88
+ const groupFiles = folderGroups[folder];
89
+ const existingChecks = await Promise.all(groupFiles.map((file) => {
90
+ const destFilePath = `${destPath}${file.name.substring(originPath.length)}`;
91
+ return destBucket.file(destFilePath).exists();
92
+ }));
93
+ const allExist = existingChecks.every(([exists]) => exists);
94
+ if (allExist) {
95
+ console.log(`Skipped folder '${folder}' — all files already exist at destination.`);
96
+ continue;
97
+ }
98
+ for (let i = 0; i < groupFiles.length; i++) {
99
+ const file = groupFiles[i];
100
+ const [exists] = existingChecks[i];
101
+ const relativePath = file.name.substring(originPath.length);
102
+ const destFilePath = `${destPath}${relativePath}`;
103
+ const tempFileName = path.basename(relativePath);
104
+ if (exists) {
105
+ console.log(`Skipped '${file.name}' — already exists at destination.`);
106
+ continue;
107
+ }
108
+ const tempFilePath = `${tempDir}/${tempFileName}`;
109
+ await file.download({ destination: tempFilePath });
110
+ await destBucket.upload(tempFilePath, { destination: destFilePath });
111
+ fs.rmSync(tempFilePath);
112
+ console.log(`Copied '${file.name}' to '${destFilePath}'`);
113
+ }
114
+ }
115
+ }
116
+ catch (error) {
117
+ console.error(`Failed to copy from ${originPath} to ${destPath}:`, error);
118
+ }
119
+ };
120
+ export const copyStorageFiles = async (originPath, destPath, adminSdkJsonOrigin, adminSdkJsonDest) => {
121
+ // Initialize the Firebase applications
122
+ const originApp = initFirebaseApp(adminSdkJsonOrigin, 'originApp');
123
+ const destApp = initFirebaseApp(adminSdkJsonDest, 'destApp');
124
+ // Get the buckets
125
+ const orginStorage = getStorage(originApp);
126
+ const destStorage = getStorage(destApp);
127
+ const originBucket = orginStorage.bucket();
128
+ const destBucket = destStorage.bucket();
129
+ // Start the recursive copy
130
+ await copyFilesRecursively(originBucket, destBucket, originPath, destPath);
131
+ };
132
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/helpers/storage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AACnC,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,MAAM,CAAC,MAAM,QAAQ,GAAG,KAAK,EAAE,QAAgB,EAAE,GAAW,EAAE,EAAE;IAC9D,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAC7B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,CAAC;IAClD,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAEtC,EAA+B,EAAE;IAChC,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7C,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,OAAO,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YACnE,OAAO,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,wCAAwC,GAAG,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;AACxD,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAc,EACd,SAAiB,EACjB,eAAyB,EAAE;IAE3B,IAAI,CAAC;QACH,kCAAkC;QAClC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAE7D,mEAAmE;QACnE,MAAM,aAAa,GAAG,KAAK,CAAC,MAAM,CAChC,CAAC,IAAI,EAAE,EAAE,CACP,CAAC,YAAY,CAAC,QAAQ,CACpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAClD,CACJ,CAAC;QAEF,mBAAmB;QACnB,MAAM,cAAc,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAElE,qCAAqC;QACrC,MAAM,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAElC,OAAO,CAAC,GAAG,CAAC,WAAW,aAAa,CAAC,MAAM,eAAe,SAAS,EAAE,CAAC,CAAC;IACzE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,KAAK,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,UAAkB,EAClB,OAAe,EACf,WAAW,GAAG,CAAC,EACf,EAAE;IACF,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,CAAC,KAAK,IAAI,OAAO,GAAG,WAAW,EAAE,CAAC;QACvC,OAAO,EAAE,CAAC;QACV,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1D,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC/C,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,KAAK,GAAG,IAAI,CAAC;YACb,OAAO,QAAQ,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF,uDAAuD;AACvD,MAAM,eAAe,GAAG,CAAC,YAAoB,EAAE,OAAe,EAAE,EAAE;IAChE,MAAM,eAAe,GAAG,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;IAE3C,OAAO,KAAK,CAAC,aAAa,CACxB;QACE,UAAU,EAAE,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC;QACzC,WAAW,EAAE,WAAW,MAAM,CAAC,UAAU,iBAAiB;QAC1D,aAAa,EAAE,QAAQ,MAAM,CAAC,UAAU,cAAc;KACvD,EACD,OAAO,CACR,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,oBAAoB,GAAG,KAAK,EAChC,YAAoB,EACpB,UAAkB,EAClB,UAAkB,EAClB,QAAgB,EAChB,EAAE;IACF,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC;QACxC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACxB,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,MAAM,wBAAwB,UAAU,EAAE,CAAC,CAAC;QAE5E,2CAA2C;QAC3C,MAAM,YAAY,GAA2C,EAAE,CAAC;QAChE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YAC5D,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,0CAA0C;YAEtF,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC3B,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YAC7B,CAAC;YACD,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;QAED,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;YAClC,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;YAExC,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,GAAG,CACtC,UAAU,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;gBACtB,MAAM,YAAY,GAAG,GAAG,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CACpD,UAAU,CAAC,MAAM,CAClB,EAAE,CAAC;gBACJ,OAAO,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,CAAC;YAChD,CAAC,CAAC,CACH,CAAC;YAEF,MAAM,QAAQ,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC;YAC5D,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CACT,mBAAmB,MAAM,6CAA6C,CACvE,CAAC;gBACF,SAAS;YACX,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC3B,MAAM,CAAC,MAAM,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBACnC,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;gBAC5D,MAAM,YAAY,GAAG,GAAG,QAAQ,GAAG,YAAY,EAAE,CAAC;gBAClD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;gBAEjD,IAAI,MAAM,EAAE,CAAC;oBACX,OAAO,CAAC,GAAG,CACT,YAAY,IAAI,CAAC,IAAI,oCAAoC,CAC1D,CAAC;oBACF,SAAS;gBACX,CAAC;gBAED,MAAM,YAAY,GAAG,GAAG,OAAO,IAAI,YAAY,EAAE,CAAC;gBAClD,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,CAAC;gBACnD,MAAM,UAAU,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC,CAAC;gBACrE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,SAAS,YAAY,GAAG,CAAC,CAAC;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,uBAAuB,UAAU,OAAO,QAAQ,GAAG,EAAE,KAAK,CAAC,CAAC;IAC5E,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EACnC,UAAkB,EAClB,QAAgB,EAChB,kBAA0B,EAC1B,gBAAwB,EACxB,EAAE;IACF,uCAAuC;IACvC,MAAM,SAAS,GAAG,eAAe,CAAC,kBAAkB,EAAE,WAAW,CAAC,CAAC;IAEnE,MAAM,OAAO,GAAG,eAAe,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;IAE7D,kBAAkB;IAClB,MAAM,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAExC,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC;IAC3C,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC;IAExC,2BAA2B;IAC3B,MAAM,oBAAoB,CAAC,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;AAC7E,CAAC,CAAC"}
@@ -0,0 +1,42 @@
1
+ import { VariableDeclaration } from '@citolab/qti-components/exports/variables.js';
2
+ export declare const sum: (items: number[]) => number;
3
+ export declare function sumField<T>(items: T[], getKey: (item: T) => number): number;
4
+ export declare function avgField<T>(items: T[], getKey: (item: T) => number): number;
5
+ export declare function flatten<T>(nestedArrays: T[][]): T[];
6
+ export declare function isEmptyOrSpaces(str: string): boolean;
7
+ export declare function IsNullOrUndefined(value: unknown): value is null | undefined;
8
+ export declare function IsTrue(value: string | boolean | unknown | null): boolean;
9
+ export declare function removeDoubleSlashes(str: string): string;
10
+ export declare const toQtiCompatibleId: (id: string) => string;
11
+ export declare function sort<T, K>(list: T[], getKey: (item: T) => K, desc?: boolean): T[];
12
+ export declare const trimStart: (text: string, chars: string[]) => string;
13
+ export declare const dateId: () => string;
14
+ export declare const todayId: () => string;
15
+ export declare function convertFirebaseDate(dateObject: {
16
+ seconds: number;
17
+ nanoseconds: number;
18
+ } | Date): Date;
19
+ export declare function getUnique<T>(arr: T[]): T[];
20
+ export declare function splitArray<T>(flatArray: T[], numCols: number): T[][];
21
+ export declare function groupBy<T, K>(list: T[], getKey: (item: T) => K): [K, T[]][];
22
+ export declare const timeout: (ms: number) => Promise<unknown>;
23
+ export declare const getReadableResponseFromVariables: (variables: readonly VariableDeclaration<string | string[]>[]) => string;
24
+ export declare const createCode: (length: number) => string;
25
+ export declare const randomInt: (min: number, max: number) => number;
26
+ export declare const parseUrl: (url: string) => {
27
+ hash: string;
28
+ host: string;
29
+ hostname: string;
30
+ href: string;
31
+ origin: string;
32
+ pathname: string;
33
+ port: string;
34
+ protocol: string;
35
+ search: string;
36
+ username: string;
37
+ password: string;
38
+ } | null;
39
+ export declare const truncate: (text: string, length: number) => string;
40
+ export declare const trim: (s: string, c: string) => string;
41
+ export declare function httpCall<ResponseType, BodyType>(url: string | undefined, method: 'GET' | 'POST' | 'PATCH', data?: BodyType): Promise<ResponseType | null>;
42
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/helpers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,8CAA8C,CAAC;AAEnF,eAAO,MAAM,GAAG,GAAI,OAAO,MAAM,EAAE,WACiB,CAAC;AAErD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,UAElE;AAED,wBAAgB,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAAM,UAIlE;AACD,wBAAgB,OAAO,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAEnD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,WAE1C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,6BAE/C;AAED,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,IAAI,WAM9D;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,UAO9C;AAED,eAAO,MAAM,iBAAiB,GAAI,IAAI,MAAM,WAK3C,CAAC;AAEF,wBAAgB,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,UAAQ,OAazE;AAED,eAAO,MAAM,SAAS,GAAI,MAAM,MAAM,EAAE,OAAO,MAAM,EAAE,WAatD,CAAC;AAEF,eAAO,MAAM,MAAM,cAUlB,CAAC;AAEF,eAAO,MAAM,OAAO,cAMnB,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,UAAU,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,QAY5D;AAOD,wBAAgB,SAAS,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAG1C;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,CAAC,EAAE,EAAE,CAUpE;AAED,wBAAgB,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,cAY9D;AAED,eAAO,MAAM,OAAO,GAAI,IAAI,MAAM,qBACmB,CAAC;AAEtD,eAAO,MAAM,gCAAgC,GAC3C,WAAW,SAAS,mBAAmB,CAAC,MAAM,GAAG,MAAM,EAAE,CAAC,EAAE,WAY7D,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,QAAQ,MAAM,WAQxC,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,KAAK,MAAM,EAAE,KAAK,MAAM,WAGjD,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM;;;;;;;;;;;;QA2BnC,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,MAAM,MAAM,EAAE,QAAQ,MAAM,WAEpD,CAAC;AAEF,eAAO,MAAM,IAAI,GAAI,GAAG,MAAM,EAAE,GAAG,MAAM,WAKxC,CAAC;AAEF,wBAAsB,QAAQ,CAAC,YAAY,EAAE,QAAQ,EACnD,GAAG,oBAAK,EACR,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,EAChC,IAAI,CAAC,EAAE,QAAQ,GACd,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA0B9B"}
@@ -0,0 +1,228 @@
1
+ export const sum = (items) => items.reduce((sum, current) => +sum + +current, 0);
2
+ export function sumField(items, getKey) {
3
+ return sum(items.map(getKey));
4
+ }
5
+ export function avgField(items, getKey) {
6
+ if (items.length === 0)
7
+ return 0;
8
+ const summedValues = sum(items.map(getKey));
9
+ return Math.round(summedValues / items.length);
10
+ }
11
+ export function flatten(nestedArrays) {
12
+ return [].concat(...nestedArrays);
13
+ }
14
+ export function isEmptyOrSpaces(str) {
15
+ return str === null || str === undefined || str.match(/^ *$/) !== null;
16
+ }
17
+ export function IsNullOrUndefined(value) {
18
+ return value === null || value === undefined;
19
+ }
20
+ export function IsTrue(value) {
21
+ // lower case if it's a string
22
+ if (typeof value === 'string') {
23
+ value = value.toLowerCase();
24
+ }
25
+ return value === 'true' || value === true;
26
+ }
27
+ export function removeDoubleSlashes(str) {
28
+ const singleForwardSlashes = str
29
+ .replace(/([^:]\/)\/+/g, '$1')
30
+ .replace(/\/\//g, '/')
31
+ .replace('http:/', 'http://')
32
+ .replace('https:/', 'https://');
33
+ return singleForwardSlashes;
34
+ }
35
+ export const toQtiCompatibleId = (id) => {
36
+ if (id.startsWith('ITM-')) {
37
+ return id;
38
+ }
39
+ return `ITM-${id.replaceAll(' ', '_')}`;
40
+ };
41
+ export function sort(list, getKey, desc = false) {
42
+ list.sort((a, b) => {
43
+ const valueA = getKey(a);
44
+ const valueB = getKey(b);
45
+ if (valueA < valueB) {
46
+ return !desc ? -1 : 1;
47
+ }
48
+ else if (valueA > valueB) {
49
+ return !desc ? 1 : -1;
50
+ }
51
+ else {
52
+ return 0;
53
+ }
54
+ });
55
+ return list;
56
+ }
57
+ export const trimStart = (text, chars) => {
58
+ let stop = false;
59
+ while (!stop) {
60
+ if (text.length > 0) {
61
+ if (chars.includes(text[0])) {
62
+ text = text.substring(1, text.length - 1);
63
+ }
64
+ else {
65
+ stop = true;
66
+ return text;
67
+ }
68
+ }
69
+ }
70
+ return text;
71
+ };
72
+ export const dateId = () => {
73
+ const dt = new Date();
74
+ const year = dt.getFullYear();
75
+ const month = (dt.getMonth() + 1).toString().padStart(2, '0');
76
+ const day = dt.getDate().toString().padStart(2, '0');
77
+ const hour = dt.getHours().toString().padStart(2, '0');
78
+ const minutes = dt.getMinutes().toString().padStart(2, '0');
79
+ const seconds = dt.getSeconds().toString().padStart(2, '0');
80
+ const milliseconds = dt.getMilliseconds().toString().padStart(3, '0');
81
+ return `${year}${month}${day}${hour}${minutes}${seconds}${milliseconds}`;
82
+ };
83
+ export const todayId = () => {
84
+ const dt = new Date();
85
+ const year = dt.getFullYear();
86
+ const month = (dt.getMonth() + 1).toString().padStart(2, '0');
87
+ const day = dt.getDate().toString().padStart(2, '0');
88
+ return `${year}${month}${day}`;
89
+ };
90
+ export function convertFirebaseDate(dateObject) {
91
+ // let nanoseconds = 0;
92
+ // if ((dateObject as { nanoseconds: number }).nanoseconds) {
93
+ // nanoseconds = (dateObject as { nanoseconds: number }).nanoseconds;
94
+ // }
95
+ if (dateObject.seconds) {
96
+ const firebaseDate = dateObject;
97
+ const convertedDate = new Date(firebaseDate.seconds * 1000);
98
+ return convertedDate;
99
+ }
100
+ return dateObject;
101
+ }
102
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
103
+ function onlyUnique(value, index, self) {
104
+ return self.indexOf(value) === index;
105
+ }
106
+ export function getUnique(arr) {
107
+ return arr.filter(onlyUnique);
108
+ // return [...new Set(arr)];
109
+ }
110
+ export function splitArray(flatArray, numCols) {
111
+ const newArray = [];
112
+ for (let c = 0; c < numCols; c++) {
113
+ newArray.push([]);
114
+ }
115
+ for (let i = 0; i < flatArray.length; i++) {
116
+ const mod = i % numCols;
117
+ newArray[mod].push(flatArray[i]);
118
+ }
119
+ return newArray;
120
+ }
121
+ export function groupBy(list, getKey) {
122
+ const map = new Map();
123
+ list.forEach((item) => {
124
+ const key = getKey(item);
125
+ const collection = map.get(key);
126
+ if (!collection) {
127
+ map.set(key, [item]);
128
+ }
129
+ else {
130
+ collection.push(item);
131
+ }
132
+ });
133
+ return Array.from(map);
134
+ }
135
+ export const timeout = (ms) => new Promise((res) => setTimeout(() => res(''), ms));
136
+ export const getReadableResponseFromVariables = (variables) => {
137
+ const response = variables
138
+ .filter((i) => i.identifier.toLocaleLowerCase().startsWith('response'))
139
+ .map((i) => {
140
+ if (Array.isArray(i.value)) {
141
+ return i.value.join('&');
142
+ }
143
+ return i.value;
144
+ })
145
+ .join(' , ');
146
+ return response;
147
+ };
148
+ export const createCode = (length) => {
149
+ let result = '';
150
+ const characters = 'BCDFGHJKLMNPQRSTVWXYZ';
151
+ const charactersLength = characters.length;
152
+ for (let i = 0; i < length; i++) {
153
+ result += characters.charAt(Math.floor(Math.random() * charactersLength));
154
+ }
155
+ return result;
156
+ };
157
+ export const randomInt = (min, max) => {
158
+ // min and max included
159
+ return Math.floor(Math.random() * (max - min + 1) + min);
160
+ };
161
+ export const parseUrl = (url) => {
162
+ const m = url.match(
163
+ // eslint-disable-next-line no-useless-escape
164
+ /^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*):([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/);
165
+ if (m) {
166
+ const r = {
167
+ hash: m[10] || '', // #asd
168
+ host: m[3] || '', // localhost:257
169
+ hostname: m[6] || '', // localhost
170
+ href: m[0] || '', // http://username:password@localhost:257/deploy/?asd=asd#asd
171
+ origin: m[1] || '', // http://username:password@localhost:257
172
+ pathname: m[8] || (m[1] ? '/' : ''), // /deploy/
173
+ port: m[7] || '', // 257
174
+ protocol: m[2] || '', // http:
175
+ search: m[9] || '', // ?asd=asd
176
+ username: m[4] || '', // username
177
+ password: m[5] || '', // password
178
+ };
179
+ if (r.protocol.length == 2) {
180
+ r.protocol = 'file:///' + r.protocol.toUpperCase();
181
+ r.origin = r.protocol + '//' + r.host;
182
+ }
183
+ r.href = r.origin + r.pathname + r.search + r.hash;
184
+ return r;
185
+ }
186
+ return null;
187
+ };
188
+ export const truncate = (text, length) => {
189
+ return text.length > length ? text.substring(0, length - 3) + '...' : text;
190
+ };
191
+ export const trim = (s, c) => {
192
+ if (c === ']')
193
+ c = '\\]';
194
+ if (c === '^')
195
+ c = '\\^';
196
+ if (c === '\\')
197
+ c = '\\\\';
198
+ return s.replace(new RegExp('^[' + c + ']+|[' + c + ']+$', 'g'), '');
199
+ };
200
+ export async function httpCall(url = '', method, data) {
201
+ const headers = { 'Content-Type': 'application/json' };
202
+ let requestInit = {
203
+ method, // *GET, POST, PUT, DELETE, etc.
204
+ mode: 'cors', // no-cors, *cors, same-origin
205
+ cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
206
+ credentials: 'same-origin', // include, *same-origin, omit
207
+ headers,
208
+ redirect: 'follow', // manual, *follow, error
209
+ referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
210
+ };
211
+ if (data) {
212
+ requestInit = { ...requestInit, body: JSON.stringify(data) };
213
+ }
214
+ // Default options are marked with *
215
+ const response = await fetch(url, requestInit);
216
+ if (response.status === 200) {
217
+ try {
218
+ const jsonResult = await response.json();
219
+ return jsonResult;
220
+ }
221
+ catch (e) {
222
+ console.log(e);
223
+ return (await response.statusText);
224
+ }
225
+ }
226
+ return null;
227
+ }
228
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/helpers/utils.ts"],"names":[],"mappings":"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"}
package/dist/main.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const api: import("firebase-functions/v2/https").HttpsFunction;
2
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,GAAG,qDAGf,CAAC"}
package/dist/main.js ADDED
@@ -0,0 +1,14 @@
1
+ import { onRequest } from 'firebase-functions/v2/https';
2
+ import { setGlobalOptions } from 'firebase-functions/v2/options';
3
+ import { initializeApp } from 'firebase-admin/app';
4
+ import expressApp from './api';
5
+ // EXAMPLE MAIN FILE, SHOWS HOW TO INITIALIZE THE APP AND ADD THE API AS FIREBASE FUNCTION
6
+ initializeApp();
7
+ const memory = (process.env.MEMORY || '256MB'); // Default to 256MB if not set
8
+ const cpuRaw = parseInt(process.env.CPU_INSTANCES || '1');
9
+ const cpu = isNaN(cpuRaw) ? 1 : cpuRaw;
10
+ const timeoutSeconds = parseInt(process.env.TIMEOUT_SECONDS || '60');
11
+ setGlobalOptions({ region: 'europe-west4', memory: '1GiB' });
12
+ // we even can split api's here. Maybe in the future split the teacher and student api's
13
+ export const api = onRequest({ region: ['europe-west4'], memory, cpu, timeoutSeconds }, expressApp);
14
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACxD,OAAO,EAAgB,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAE/E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,UAAU,MAAM,OAAO,CAAC;AAE/B,0FAA0F;AAE1F,aAAa,EAAE,CAAC;AAChB,MAAM,MAAM,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,OAAO,CAAiB,CAAC,CAAC,8BAA8B;AAE9F,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,GAAG,CAAC,CAAC;AAC1D,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;AACvC,MAAM,cAAc,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,CAAC;AAErE,gBAAgB,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAE7D,wFAAwF;AACxF,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAC1B,EAAE,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,EAAE,EACzD,UAAU,CACX,CAAC"}
package/package.json ADDED
@@ -0,0 +1,101 @@
1
+ {
2
+ "name": "@citolab/qti-backend-firebase",
3
+ "version": "0.0.3",
4
+ "private": false,
5
+ "exports": {
6
+ "./qti-endpoints-data": "./dist/api/qti-data.js",
7
+ "./qti-endpoints-resources": "./dist/api/qti-resources.js",
8
+ "./qti-endpoints-teacher": "./dist/api/qti-teacher.js",
9
+ "./qti-endpoints-tools": "./dist/api/qti-tools.js",
10
+ "./specific": "./dist/api/app-specific/index.js",
11
+ "./qti-helpers": "./dist/helpers/index.js"
12
+ },
13
+ "typesVersions": {
14
+ "*": {
15
+ "qti-endpoints-data": [
16
+ "./dist/api/qti-data.d.ts"
17
+ ],
18
+ "qti-endpoints-resources": [
19
+ "./dist/api/qti-resources.d.ts"
20
+ ],
21
+ "qti-endpoints-teacher": [
22
+ "./dist/api/qti-teacher.d.ts"
23
+ ],
24
+ "qti-endpoints-tools": [
25
+ "./dist/api/qti-tools.d.ts"
26
+ ],
27
+ "specific": [
28
+ "./dist/api/app-specific/index.d.ts"
29
+ ],
30
+ "qti-helpers": [
31
+ "./dist/helpers/index.d.ts"
32
+ ]
33
+ }
34
+ },
35
+ "description": "Default endpoints for communcating with a applications that uses QTI-components as delivery system.",
36
+ "main": "dist/index.js",
37
+ "types": "dist/index.d.ts",
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "build-and-yalc": "tsc && yalc push",
44
+ "dev": "tsc --watch",
45
+ "lint": "eslint src/**/*.ts",
46
+ "prepublishOnly": "npm run build",
47
+ "release": "np --no-tests --no-install --no-cleanup",
48
+ "watch-lib": "nodemon --watch \"src/**\" --ext \"ts,json,css\" --ignore \"src/**/*.spec.ts\" --exec \"tsx scripts/build.ts\" watch"
49
+ },
50
+ "engines": {
51
+ "node": ">=20.0.0"
52
+ },
53
+ "keywords": [
54
+ "typescript",
55
+ "library"
56
+ ],
57
+ "author": "Patrick de Klein, Sander Looise, Marcel Hoekstra",
58
+ "license": "MIT",
59
+ "repository": {
60
+ "type": "git",
61
+ "url": "git+https://github.com/Citolab/qti-api.git"
62
+ },
63
+ "bugs": {
64
+ "url": "https://github.com/Citolab/qti-api/issues"
65
+ },
66
+ "homepage": "https://github.com/Citolab/qti-api#readme",
67
+ "devDependencies": {
68
+ "@types/busboy": "^1.5.4",
69
+ "@types/jest": "^29.5.0",
70
+ "@types/multer": "^1.4.13",
71
+ "@types/node": "^20.0.0",
72
+ "@types/unzipper": "^0.10.11",
73
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
74
+ "@typescript-eslint/parser": "^6.0.0",
75
+ "eslint": "^8.0.0",
76
+ "jest": "^29.5.0",
77
+ "nodemon": "^3.1.10",
78
+ "np": "^10.2.0",
79
+ "ts-jest": "^29.1.0",
80
+ "tsup": "^8.5.0",
81
+ "tsx": "^4.20.1",
82
+ "typescript": "^5.0.0"
83
+ },
84
+ "dependencies": {
85
+ "@citolab/qti-api": ">=8",
86
+ "@citolab/qti-components": ">=7.0.0-0 || >=7.0.0-beta.0 || >=7.0.0-next.0",
87
+ "@citolab/qti-convert": ">=0.3",
88
+ "axios": ">=1.6",
89
+ "busboy": ">=1.6.0",
90
+ "cheerio": ">=1.1.0",
91
+ "express": ">=4",
92
+ "express-rate-limit": ">=7.5",
93
+ "express-validator": ">=7.2",
94
+ "firebase-admin": ">=13",
95
+ "firebase-functions": ">=6",
96
+ "multer": ">=2",
97
+ "node-cache": ">=5",
98
+ "saxon-js": ">=2.7.0",
99
+ "unzipper": ">=0.12"
100
+ }
101
+ }
package/readme.md ADDED
@@ -0,0 +1,11 @@
1
+ # @citolab/backend-firebase
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ npm install @citolab/qti-backend-firebase
7
+ ```
8
+
9
+ ## License
10
+
11
+ This project is licensed under the [GPLv3 License](LICENSE).