@citolab/tspci-tao 2.6.3-beta.1 → 2.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/package.json +2 -2
- package/src/createPackage.mjs +116 -31
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,30 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [2.6.5](https://github.com/Citolab/tspci/compare/v2.6.3-beta.3...v2.6.5) (2025-04-16)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @citolab/tspci-tao
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## [2.6.3-beta.3](https://github.com/Citolab/tspci/compare/v2.6.3-beta.2...v2.6.3-beta.3) (2025-04-16)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @citolab/tspci-tao
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
## [2.6.3-beta.2](https://github.com/Citolab/tspci/compare/v2.6.3-beta.1...v2.6.3-beta.2) (2025-04-16)
|
|
23
|
+
|
|
24
|
+
**Note:** Version bump only for package @citolab/tspci-tao
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
6
30
|
## [2.6.3-beta.1](https://github.com/Citolab/tspci/compare/v2.6.3-beta.0...v2.6.3-beta.1) (2025-04-14)
|
|
7
31
|
|
|
8
32
|
**Note:** Version bump only for package @citolab/tspci-tao
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@citolab/tspci-tao",
|
|
3
|
-
"version": "2.6.
|
|
3
|
+
"version": "2.6.5",
|
|
4
4
|
"description": "create a zip file that can be imported into TAO",
|
|
5
5
|
"author": "patrick <patrick.deklein@cito.nl>, Marcel Hoekstra <marcel.hoekstra@cito.nl>",
|
|
6
6
|
"repository": "",
|
|
@@ -12,5 +12,5 @@
|
|
|
12
12
|
"inquirer": "11.0.1"
|
|
13
13
|
},
|
|
14
14
|
"scripts": {},
|
|
15
|
-
"gitHead": "
|
|
15
|
+
"gitHead": "06a99429f9555a99fe3f877fb55c4bcbb9282b8a"
|
|
16
16
|
}
|
package/src/createPackage.mjs
CHANGED
|
@@ -5,7 +5,9 @@ import archiver from "archiver";
|
|
|
5
5
|
export const bundle = () => {
|
|
6
6
|
const PACKAGE_ROOT_PATH = process.cwd();
|
|
7
7
|
|
|
8
|
-
const PACKAGER_PATH = path.join(
|
|
8
|
+
const PACKAGER_PATH = path.join(
|
|
9
|
+
PACKAGE_ROOT_PATH + "/node_modules/@citolab/tspci-tao"
|
|
10
|
+
);
|
|
9
11
|
|
|
10
12
|
// PROPERTIES CAN BE OVERRIDEN BY VALUES IN YOUR Package.json INSIDE YOUR PCI FOLDER
|
|
11
13
|
// OTHER CONFIG VALUES ARE: "pciJsFile" THE BUNDLED PCI FILE DEFAULTS TO: "/dist/index.js"
|
|
@@ -46,7 +48,9 @@ export const bundle = () => {
|
|
|
46
48
|
"'typeIdentifier' should be added as an option in package.json and should match the typeIdentifier of the PCI code file."
|
|
47
49
|
);
|
|
48
50
|
return;
|
|
49
|
-
} else if (
|
|
51
|
+
} else if (
|
|
52
|
+
!/^[A-Za-z0-9]*$/.test(packageData.config.tspci[propertyName])
|
|
53
|
+
) {
|
|
50
54
|
console.error(
|
|
51
55
|
"'typeIdentifier' can only contain (alpha)numeric characters. The pci does not work in TAO if typeindentifier contains a hyphen therefor we restrict all non (alpha)numeric characters. Make sure typeIdentifier of the PCI code file matches the typeidentier in package.json."
|
|
52
56
|
);
|
|
@@ -64,7 +68,9 @@ export const bundle = () => {
|
|
|
64
68
|
propertiesToReplace.version = packageData.version;
|
|
65
69
|
|
|
66
70
|
if (migrated) {
|
|
67
|
-
console.warn(
|
|
71
|
+
console.warn(
|
|
72
|
+
'package.json has been migrated to use "{ config: { tspci: { typeIdentifier: ..., xx" properties.'
|
|
73
|
+
);
|
|
68
74
|
fs.writeFileSync(config, JSON.stringify(packageData, null, 2));
|
|
69
75
|
}
|
|
70
76
|
|
|
@@ -90,7 +96,11 @@ export const bundle = () => {
|
|
|
90
96
|
// to override these files for a specific PCI: add them in the same structure in the tao_pci folder
|
|
91
97
|
// of the pci.
|
|
92
98
|
|
|
93
|
-
copyDirectoryRecursiveSync(
|
|
99
|
+
copyDirectoryRecursiveSync(
|
|
100
|
+
path.join(PACKAGER_PATH, "toa_pci_default"),
|
|
101
|
+
outputDirectoryTemp,
|
|
102
|
+
false
|
|
103
|
+
);
|
|
94
104
|
|
|
95
105
|
// ---------------------------------------------------------------------
|
|
96
106
|
// ADD THE VALUES THAT ARE SHOULD BE CONFIGURABLE WITHIN TAO
|
|
@@ -138,7 +148,8 @@ export const bundle = () => {
|
|
|
138
148
|
if (defaultPackageJsonProperties.includes(propertyName)) {
|
|
139
149
|
propertiesToReplace[propertyName] = packageData[propertyName];
|
|
140
150
|
} else {
|
|
141
|
-
propertiesToReplace[propertyName] =
|
|
151
|
+
propertiesToReplace[propertyName] =
|
|
152
|
+
packageData.config.tspci[propertyName];
|
|
142
153
|
}
|
|
143
154
|
}
|
|
144
155
|
|
|
@@ -147,9 +158,15 @@ export const bundle = () => {
|
|
|
147
158
|
replace_string_in_file(
|
|
148
159
|
creatorFile,
|
|
149
160
|
"###_FIRST_SCORING_METHOD_###",
|
|
150
|
-
propertiesToReplace.score?.length > 0
|
|
161
|
+
propertiesToReplace.score?.length > 0
|
|
162
|
+
? propertiesToReplace.score[0]
|
|
163
|
+
: "NONE"
|
|
164
|
+
);
|
|
165
|
+
replace_string_in_file(
|
|
166
|
+
creatorFile,
|
|
167
|
+
`'##__DEFAULT_VALUES__##'`,
|
|
168
|
+
defaultValues
|
|
151
169
|
);
|
|
152
|
-
replace_string_in_file(creatorFile, `'##__DEFAULT_VALUES__##'`, defaultValues);
|
|
153
170
|
|
|
154
171
|
// add stuff in interaction/creator/widget/states/Question.js
|
|
155
172
|
const variableDeclaration = `
|
|
@@ -181,43 +198,83 @@ export const bundle = () => {
|
|
|
181
198
|
.join(",\r\n")}
|
|
182
199
|
`;
|
|
183
200
|
|
|
184
|
-
const widgetAnswerFile = path.join(
|
|
201
|
+
const widgetAnswerFile = path.join(
|
|
202
|
+
outputDirectoryTemp,
|
|
203
|
+
"interaction/creator/widget/states/Answer.js"
|
|
204
|
+
);
|
|
185
205
|
replace_string_in_file(
|
|
186
206
|
widgetAnswerFile,
|
|
187
207
|
`'###_RD_TEMPLATES_###'`,
|
|
188
|
-
JSON.stringify(propertiesToReplace.score)
|
|
208
|
+
JSON.stringify(propertiesToReplace.score)
|
|
209
|
+
.replace("[", "")
|
|
210
|
+
.replace("]", "")
|
|
189
211
|
);
|
|
190
212
|
|
|
191
|
-
const widgetQuestionFile = path.join(
|
|
213
|
+
const widgetQuestionFile = path.join(
|
|
214
|
+
outputDirectoryTemp,
|
|
215
|
+
"interaction/creator/widget/states/Question.js"
|
|
216
|
+
);
|
|
192
217
|
|
|
193
|
-
replace_string_in_file(
|
|
194
|
-
|
|
195
|
-
|
|
218
|
+
replace_string_in_file(
|
|
219
|
+
widgetQuestionFile,
|
|
220
|
+
`// ##__SET_VARIABLES__##`,
|
|
221
|
+
setVariables
|
|
222
|
+
);
|
|
223
|
+
replace_string_in_file(
|
|
224
|
+
widgetQuestionFile,
|
|
225
|
+
`// ##__DECLARE_VARIABLES__##`,
|
|
226
|
+
variableDeclaration
|
|
227
|
+
);
|
|
228
|
+
replace_string_in_file(
|
|
229
|
+
widgetQuestionFile,
|
|
230
|
+
`// ##__CALLBACK__##`,
|
|
231
|
+
callbacks
|
|
232
|
+
);
|
|
196
233
|
// add controls in
|
|
197
|
-
const propertiesFormFile = path.join(
|
|
234
|
+
const propertiesFormFile = path.join(
|
|
235
|
+
outputDirectoryTemp,
|
|
236
|
+
"interaction/creator/tpl/propertiesForm.tpl"
|
|
237
|
+
);
|
|
198
238
|
const template = `${configValues
|
|
199
239
|
.map((cv) => {
|
|
200
|
-
const capitalizedName =
|
|
240
|
+
const capitalizedName =
|
|
241
|
+
cv.name.charAt(0).toUpperCase() + cv.name.slice(1);
|
|
201
242
|
return `<label for="${cv.name}">{{__ "${capitalizedName}"}}</label>
|
|
202
243
|
<span class="icon-help tooltipstered" data-tooltip="~ .tooltip-content:first" data-tooltip-theme="info"></span>
|
|
203
244
|
<span class="tooltip-content">{{__ "${capitalizedName}"}}</span>
|
|
204
245
|
<input type="text"
|
|
205
246
|
name="${cv.name}"
|
|
206
|
-
type="${
|
|
247
|
+
type="${
|
|
248
|
+
cv.type === "string"
|
|
249
|
+
? "text"
|
|
250
|
+
: cv.type === "number"
|
|
251
|
+
? "number"
|
|
252
|
+
: "text"
|
|
253
|
+
}"
|
|
207
254
|
value="{{${cv.name}}}"
|
|
208
255
|
placeholder="e.g. ${replaceAll(cv.defaultValue, '"', "")}"
|
|
209
256
|
data-validate="${cv.optional ? "" : "$notEmpty"};">`;
|
|
210
257
|
})
|
|
211
258
|
.join("\r\n")}
|
|
212
259
|
`;
|
|
213
|
-
replace_string_in_file(
|
|
260
|
+
replace_string_in_file(
|
|
261
|
+
propertiesFormFile,
|
|
262
|
+
`<!-- ##_HTML_CONTROLS_## -->`,
|
|
263
|
+
template
|
|
264
|
+
);
|
|
214
265
|
} else {
|
|
215
|
-
console.warn(
|
|
266
|
+
console.warn(
|
|
267
|
+
"Create a config.json with properties to generate a TAO config"
|
|
268
|
+
);
|
|
216
269
|
}
|
|
217
270
|
|
|
218
271
|
// copy specific files
|
|
219
272
|
if (fs.existsSync(path.join(PACKAGE_ROOT_PATH, "tao_pci"))) {
|
|
220
|
-
copyDirectoryRecursiveSync(
|
|
273
|
+
copyDirectoryRecursiveSync(
|
|
274
|
+
path.join(PACKAGE_ROOT_PATH, "tao_pci"),
|
|
275
|
+
outputDirectoryTemp,
|
|
276
|
+
false
|
|
277
|
+
);
|
|
221
278
|
}
|
|
222
279
|
|
|
223
280
|
// files that contain values that should be replaced
|
|
@@ -234,14 +291,20 @@ export const bundle = () => {
|
|
|
234
291
|
for (const fileToEdit of filesToEdit) {
|
|
235
292
|
for (const propertyName in propertiesToReplace) {
|
|
236
293
|
const pathToFile = path.join(outputDirectoryTemp, fileToEdit);
|
|
237
|
-
replace_string_in_file(
|
|
294
|
+
replace_string_in_file(
|
|
295
|
+
pathToFile,
|
|
296
|
+
`##${propertyName}##`,
|
|
297
|
+
propertiesToReplace[propertyName]
|
|
298
|
+
);
|
|
238
299
|
}
|
|
239
300
|
}
|
|
240
301
|
|
|
241
302
|
// copy the actual PCI file
|
|
242
303
|
const pciFile = config.main || "/dist/index.js";
|
|
243
304
|
|
|
244
|
-
if (
|
|
305
|
+
if (
|
|
306
|
+
!fs.existsSync(path.join(outputDirectoryTemp, "/interaction/runtime/js"))
|
|
307
|
+
) {
|
|
245
308
|
mkdirSync(path.join(outputDirectoryTemp, "/interaction/runtime/js"));
|
|
246
309
|
}
|
|
247
310
|
|
|
@@ -251,9 +314,15 @@ export const bundle = () => {
|
|
|
251
314
|
);
|
|
252
315
|
|
|
253
316
|
// the icon can be replaced by a custom icon
|
|
254
|
-
const iconLocation = path.join(
|
|
317
|
+
const iconLocation = path.join(
|
|
318
|
+
PACKAGE_ROOT_PATH,
|
|
319
|
+
`${propertiesToReplace.typeIdentifier}.svg`
|
|
320
|
+
);
|
|
255
321
|
if (fs.existsSync(iconLocation)) {
|
|
256
|
-
fs.copyFileSync(
|
|
322
|
+
fs.copyFileSync(
|
|
323
|
+
iconLocation,
|
|
324
|
+
path.join(outputDirectoryTemp, "/interaction/creator/img/icon.svg")
|
|
325
|
+
);
|
|
257
326
|
} else {
|
|
258
327
|
console.warn(
|
|
259
328
|
`Cannot find svg file at: ${iconLocation} default icon will be used. To have a custom icon for the PCI in TAO add a svg file here: ${iconLocation}`
|
|
@@ -263,9 +332,10 @@ export const bundle = () => {
|
|
|
263
332
|
|
|
264
333
|
// zip the folder
|
|
265
334
|
const zipName = `tao-pci-${propertiesToReplace.typeIdentifier}_${packageData.version}.zip`;
|
|
266
|
-
zipDirectory(outputDirectoryTemp, path.join(outputDirectory, zipName)).then(
|
|
267
|
-
|
|
268
|
-
|
|
335
|
+
zipDirectory(outputDirectoryTemp, path.join(outputDirectory, zipName)).then(
|
|
336
|
+
() =>
|
|
337
|
+
// fs.rmdirSync(outputDirectoryTemp, { recursive: true });
|
|
338
|
+
console.log(`created tao pci zip: ${zipName}`)
|
|
269
339
|
);
|
|
270
340
|
};
|
|
271
341
|
|
|
@@ -280,11 +350,16 @@ function copyDirectoryRecursiveSync(source, target) {
|
|
|
280
350
|
if (!fs.lstatSync(source).isDirectory() || source.endsWith("tmp")) return;
|
|
281
351
|
// var operation = move ? fs.renameSync : fs.copyFileSync;
|
|
282
352
|
fs.readdirSync(source).forEach(function (itemName) {
|
|
283
|
-
if (
|
|
353
|
+
if (
|
|
354
|
+
!(itemName.indexOf("tao-pci-") !== -1 && itemName.indexOf(".zip") !== -1)
|
|
355
|
+
) {
|
|
284
356
|
var sourcePath = path.join(source, itemName);
|
|
285
357
|
var targetPath = path.join(target, itemName);
|
|
286
358
|
if (fs.lstatSync(sourcePath).isDirectory()) {
|
|
287
|
-
if (
|
|
359
|
+
if (
|
|
360
|
+
!fs.existsSync(targetPath) &&
|
|
361
|
+
!targetPath.toLocaleLowerCase().endsWith("tmp")
|
|
362
|
+
) {
|
|
288
363
|
fs.mkdirSync(targetPath);
|
|
289
364
|
}
|
|
290
365
|
copyDirectoryRecursiveSync(sourcePath, targetPath);
|
|
@@ -317,14 +392,24 @@ function replaceAll(str, find, replace) {
|
|
|
317
392
|
return str.replace(new RegExp(find, "g"), replace);
|
|
318
393
|
}
|
|
319
394
|
|
|
320
|
-
function isBoolean(
|
|
321
|
-
|
|
395
|
+
function isBoolean(val) {
|
|
396
|
+
// If val is already a boolean, return true
|
|
397
|
+
if (typeof val === "boolean") {
|
|
398
|
+
return true;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// If val is not a string, return false
|
|
402
|
+
if (typeof val !== "string") {
|
|
403
|
+
return false;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Handle string cases
|
|
407
|
+
switch (val.toLowerCase().trim()) {
|
|
322
408
|
case "true":
|
|
323
409
|
case "yes":
|
|
324
410
|
case "false":
|
|
325
411
|
case "no":
|
|
326
412
|
return true;
|
|
327
|
-
|
|
328
413
|
default:
|
|
329
414
|
return false;
|
|
330
415
|
}
|