@citolab/tspci 2.5.0 → 2.5.1-alpha.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.
package/package.json CHANGED
@@ -1,50 +1,50 @@
1
1
  {
2
2
  "name": "@citolab/tspci",
3
- "version": "2.5.0",
3
+ "version": "2.5.1-alpha.0",
4
4
  "description": "an opiniated typescript ims-pci builder with tao integration",
5
5
  "author": "patrick <patrick.deklein@cito.nl>",
6
6
  "repository": "@citolab/tspci",
7
7
  "bin": {
8
8
  "tspci": "src/cli.js"
9
9
  },
10
+ "scripts": {
11
+ "help": "tspci --help",
12
+ "init": "tspci init --force --path=../../pcis"
13
+ },
10
14
  "type": "module",
11
15
  "types": "types/index.d.ts",
12
16
  "dependencies": {
13
- "@rollup/plugin-alias": "^5.0.0",
14
- "@rollup/plugin-babel": "^6.0.3",
15
- "@rollup/plugin-commonjs": "^24.1.0",
16
- "@rollup/plugin-image": "^3.0.2",
17
- "@rollup/plugin-json": "^6.0.0",
18
- "@rollup/plugin-node-resolve": "^15.0.2",
19
- "@rollup/plugin-replace": "^5.0.2",
20
- "@rollup/plugin-terser": "^0.4.1",
21
- "@rollup/plugin-typescript": "^11.1.0",
17
+ "@rollup/plugin-alias": "^5.1.0",
18
+ "@rollup/plugin-babel": "^6.0.4",
19
+ "@rollup/plugin-commonjs": "^26.0.1",
20
+ "@rollup/plugin-image": "^3.0.3",
21
+ "@rollup/plugin-json": "^6.1.0",
22
+ "@rollup/plugin-node-resolve": "^15.2.3",
23
+ "@rollup/plugin-replace": "^5.0.7",
24
+ "@rollup/plugin-terser": "^0.4.4",
25
+ "@rollup/plugin-typescript": "^11.1.6",
22
26
  "@tailwindcss/nesting": "0.0.0-insiders.565cd3e",
23
- "@testing-library/dom": "^9.2.0",
24
- "@types/node": "^18.16.3",
25
- "@typescript-eslint/eslint-plugin": "^5.59.2",
26
- "@typescript-eslint/parser": "^5.59.2",
27
- "autoprefixer": "10.4.14",
28
- "chalk": "5.2.0",
27
+ "@testing-library/dom": "^10.4.0",
28
+ "@types/node": "^22.5.5",
29
+ "@typescript-eslint/eslint-plugin": "^8.5.0",
30
+ "@typescript-eslint/parser": "^8.5.0",
31
+ "autoprefixer": "10.4.20",
32
+ "chalk": "5.3.0",
29
33
  "clear": "0.1.0",
30
- "figlet": "1.6.0",
31
- "inquirer": "9.2.0",
34
+ "figlet": "1.7.0",
35
+ "inquirer": "11.0.1",
32
36
  "live-server": "^1.2.2",
33
- "postcss": "^8.4.23",
34
- "postcss-import": "^15.1.0",
35
- "rollup": "^3.21.4",
36
- "rollup-plugin-copy": "^3.4.0",
37
+ "postcss": "^8.4.47",
38
+ "postcss-import": "^16.1.0",
39
+ "rollup": "^4.21.3",
40
+ "rollup-plugin-copy": "^3.5.0",
37
41
  "rollup-plugin-live-server": "^2.0.0",
38
42
  "rollup-plugin-node-builtins": "^2.1.2",
39
43
  "rollup-plugin-node-globals": "^1.4.0",
40
44
  "rollup-plugin-postcss": "^4.0.2",
41
45
  "rollup-plugin-string": "^3.0.0",
42
46
  "rollup-plugin-watch-assets": "^1.0.1",
43
- "tailwindcss": "^3.3.2"
44
- },
45
- "scripts": {
46
- "help": "tspci --help",
47
- "init": "tspci init --force --path=../../pcis"
47
+ "tailwindcss": "^3.4.11"
48
48
  },
49
- "gitHead": "97b99b32afa946f3a85b3cfe6743fa7857d77091"
49
+ "gitHead": "ca12b53627968796843a752ab994b6b2e7a39cf8"
50
50
  }
@@ -0,0 +1,86 @@
1
+ import * as ctx from "qtiCustomInteractionContext";
2
+ import configProps from "./config.json";
3
+ import style from "./styles.css"; // import and bundle this style file ( you can use tailwind and nested css )
4
+ import procenten from "./assets/procenten.png"; // image types are bundled inside the js
5
+
6
+ class Pci {
7
+ /**
8
+ * @constructor
9
+ * @param {string} typeIdentifier - The unique identifier for this PCI type.
10
+ */
11
+ typeIdentifier; // typeIdentifier is mandatory for all PCI's
12
+ config; // reference to the interface of the config object which you get when getInstance is called by the player
13
+ state; // keep a reference to the state
14
+ shadowdom; // Not mandatory, but its wise to create a shadowroot
15
+
16
+ constructor() {
17
+ /**
18
+ * @type {string}
19
+ * @description The unique identifier for this PCI type.
20
+ */
21
+ this.typeIdentifier = "###___PCI_NAME___###"; // typeIdentifier is mandatory for all PCI's
22
+ ctx && ctx.register(this); // we assume the qtiCustomInteractionContext is avaible due to the import above
23
+ }
24
+
25
+ /**
26
+ * @method getInstance
27
+ * @description Creates a new instance of this portable custom interaction.
28
+ * This method will be called by the qtiCustomInteractionContext.
29
+ *
30
+ * @param {HTMLElement} dom - The DOM element to which this PCI is added.
31
+ * @param {Object<ConfigProperties>} config - The configuration to apply to this PCI.
32
+ * @param {string} state - A previously saved state to restore the PCI instance.
33
+ * This state must have been obtained from a prior call to getState for an instance of the same typeIdentifier.
34
+ */
35
+ getInstance = (dom, config, state) => {
36
+ config.properties = { ...configProps, ...config.properties }; // merge current props with incoming
37
+ this.config = config;
38
+ this.state = state ? state : "";
39
+
40
+ this.shadowdom = dom.attachShadow({ mode: "closed" });
41
+ this.render();
42
+
43
+ config.onready(this);
44
+ };
45
+
46
+ render = () => {
47
+ this.shadowdom.addEventListener("change", (e) => {
48
+ const value = (e.target).value;
49
+ this.state = value;
50
+ });
51
+ this.shadowdom.innerHTML = `<div class="pci-container">
52
+ <h1>${this.config.properties.title}</h1>
53
+ <div class="body">
54
+ <img width="${+this.config.properties.width}" height="${+this.config.properties.height}" src="${procenten}" />
55
+ </div>
56
+ <div class="interaction">
57
+ <label for="tentacles">${this.config.properties.prompt}</label>
58
+ <input type="number" value="${this.state}" min="0" max="100">%
59
+ </div>
60
+ </div>`;
61
+ const css = document.createElement("style");
62
+ css.innerHTML = style;
63
+ this.shadowdom.appendChild(css);
64
+ };
65
+
66
+ /**
67
+ * @method getResponse
68
+ * @description Retrieves the value to assign to the bound QTI response variable.
69
+ *
70
+ * @returns {Object} - The response value.
71
+ */
72
+ getResponse = () => {
73
+ const response = this.state === null || this.state === undefined ? undefined : { base: { integer: this.state } };
74
+ return response;
75
+ };
76
+
77
+ /**
78
+ * @method getState
79
+ * @description Retrieves the current state of this PCI. This state can be passed to getInstance to restore the instance later.
80
+ *
81
+ * @returns {string} - The current state of the PCI.
82
+ */
83
+ getState = () => this.state.toString();
84
+ }
85
+
86
+ export default new Pci();
@@ -1,6 +1,8 @@
1
1
  import { Configuration, IMSpci, QtiVariableJSON } from "@citolab/tspci";
2
2
  import * as ctx from "qtiCustomInteractionContext";
3
3
  import configProps from "./config.json";
4
+ import Interaction from "./interaction"; // import and bundle this interaction file
5
+
4
6
  import style from "./styles.css"; // import and bundle this style file ( you can use tailwind and nested css )
5
7
  import procenten from "./assets/procenten.png"; // image types are bundled inside the js
6
8
  // Configuration
@@ -30,8 +32,8 @@ class Pci implements IMSpci<PropTypes> {
30
32
  };
31
33
 
32
34
  private render = () => {
33
- this.shadowdom.addEventListener("change", (e: Event) => {
34
- const value = (e.target as HTMLInputElement).value;
35
+ this.shadowdom.addEventListener("change", (e) => {
36
+ const value = (e.target).value;
35
37
  this.state = value;
36
38
  });
37
39
  this.shadowdom.innerHTML = `<div class="pci-container">
package/src/cli.js CHANGED
@@ -132,7 +132,7 @@ function promptYesNo(prompt) {
132
132
  function selectOptions(prompt, options) {
133
133
  return inquirer.prompt([
134
134
  {
135
- type: "checkbox",
135
+ type: "list",
136
136
  message: prompt,
137
137
  name: "values",
138
138
  choices: options.map((o) => ({ name: o, checked: true })),
@@ -232,7 +232,10 @@ const run = async () => {
232
232
  console.log(chalk.green(figlet.textSync("@citolab/tspci", { horizontalLayout: "full" })));
233
233
 
234
234
  // prompt for name
235
- let pciName = (await askOption("What your pci identifier (typeIdentifier). this can only contain alphanumeric characters (default: myPci) ")) || "myPci";
235
+ let pciName =
236
+ (await askOption(
237
+ "What your pci identifier (typeIdentifier). this can only contain alphanumeric characters (default: myPci) "
238
+ )) || "myPci";
236
239
  let destinationFolder = path.join(process.cwd(), pciName);
237
240
  if (args.find((arg) => arg.startsWith("--path"))) {
238
241
  const pathIndex = args.findIndex((arg) => arg.startsWith("--path"));
@@ -266,7 +269,7 @@ const run = async () => {
266
269
  (await askOption("What is the description of your pci? (default: pci created with tspci)")) ||
267
270
  "pci created with tspci";
268
271
 
269
- const options = await selectOptions("Would you like to add other features?", ["tailwind css", "preact"]);
272
+ const options = await selectOptions("Type of project?", ["preact+tailwind", "typescript", "javascript"]);
270
273
  console.log(chalk.green(`Options: ${options.values.length === 0 ? "none" : options.values}`));
271
274
  // get relative path to executable
272
275
  const cliPath = __dirname;
@@ -298,7 +301,7 @@ const run = async () => {
298
301
  }
299
302
  packageJsonContentJson.config.tspci.typeIdentifier = pciName;
300
303
 
301
- if (options.values.includes("tailwind css")) {
304
+ if (options.values.includes("preact+tailwind")) {
302
305
  console.log(chalk.green("Adding tailwind css"));
303
306
 
304
307
  // read postcss.config.js
@@ -325,19 +328,19 @@ const run = async () => {
325
328
  copyDir(path.resolve(cliPath, "./../preset/tailwind"), destinationFolder);
326
329
  }
327
330
 
328
- if (options.values.includes("preact")) {
331
+ if (options.values.includes("preact+tailwind")) {
329
332
  console.log(chalk.green("Adding preact"));
330
333
  const packageJson = path.join(destinationFolder, "package.json");
331
334
  const packageJsonContent = fs.readFileSync(packageJson, "utf8");
332
335
  let packageJsonContentJson = JSON.parse(packageJsonContent);
333
336
  // delete index.ts
334
- fs.rmSync(path.join(destinationFolder, "src/index.ts"), { force: true });
337
+ // fs.rmSync(path.join(destinationFolder, "src/index.ts"), { force: true });
335
338
  const preactPresetFolder = path.resolve(cliPath, "./../preset/preact");
336
339
  copyDirAndReplaceInFiles(preactPresetFolder, destinationFolder, pciName);
337
340
  // add preact and @citolab/preact-store to the package json
338
341
  packageJsonContentJson.dependencies = {
339
342
  ...packageJsonContentJson.dependencies,
340
- preact: "^10.13.2",
343
+ preact: "^10.24.0",
341
344
  "@citolab/preact-store": "latest",
342
345
  };
343
346
  packageJsonContentJson = { ...packageJsonContentJson, source: "src/index.tsx" };
@@ -345,6 +348,28 @@ const run = async () => {
345
348
  fs.writeFileSync(packageJson, newPackageJsonContent);
346
349
  }
347
350
 
351
+ if (options.values.includes("typescript")) {
352
+ copyDir(path.resolve(cliPath, "./../preset/typescript/src"), path.join(destinationFolder,'src'));
353
+ // point to the javascript file
354
+ const packageJson = path.join(destinationFolder, "package.json");
355
+ const packageJsonContent = fs.readFileSync(packageJson, "utf8");
356
+ let packageJsonContentJson = JSON.parse(packageJsonContent);
357
+ packageJsonContentJson.source = "src/index.ts";
358
+ const newPackageJsonContent = JSON.stringify(packageJsonContentJson, null, 2);
359
+ fs.writeFileSync(packageJson, newPackageJsonContent);
360
+ }
361
+
362
+ if (options.values.includes("javascript")) {
363
+ copyDir(path.resolve(cliPath, "./../preset/javascript/src"), path.join(destinationFolder,'src'));
364
+ // point to the javascript file
365
+ const packageJson = path.join(destinationFolder, "package.json");
366
+ const packageJsonContent = fs.readFileSync(packageJson, "utf8");
367
+ let packageJsonContentJson = JSON.parse(packageJsonContent);
368
+ packageJsonContentJson.source = "src/index.js";
369
+ const newPackageJsonContent = JSON.stringify(packageJsonContentJson, null, 2);
370
+ fs.writeFileSync(packageJson, newPackageJsonContent);
371
+ }
372
+
348
373
  // run npm install in destination folder
349
374
  if (args.indexOf("--no-install") === -1) {
350
375
  console.log(chalk.green("📦 Installing dependencies"));
@@ -353,7 +378,7 @@ const run = async () => {
353
378
  console.log(chalk.blueBright(`Navigate to ${destinationFolder} or open this folder (e.g. with vscode).`));
354
379
  console.log(chalk.blueBright(`Start the dev server with: npm run dev`));
355
380
  console.log(chalk.blueBright(`Add support for TAO with: npm run tspci -- add --target tao`));
356
-
381
+
357
382
  return;
358
383
  } else {
359
384
  console.log(chalk.yellow("Skipping npm install, run npm install in the project folder to install dependencies"));
@@ -391,14 +416,16 @@ const run = async () => {
391
416
  }
392
417
  });
393
418
  }
394
-
395
419
  };
396
420
 
397
421
  // check if `@citolab/tspci-${targetname}]}` is already in devDependencies
398
422
  if (!packageJson.devDependencies || !packageJson.devDependencies[`@citolab/tspci-${targetname}`]) {
399
423
  console.log(chalk.white(`Adding @citolab/tspci-${targetname}`));
400
424
  // install @citolab/tspci-${targetname} to devDepencies
401
- execSync(`npm install @citolab/tspci-${targetname}@${version} --save-dev`, { cwd: PACKAGE_ROOT_PATH, stdio: [0, 1, 2] });
425
+ execSync(`npm install @citolab/tspci-${targetname}@${version} --save-dev`, {
426
+ cwd: PACKAGE_ROOT_PATH,
427
+ stdio: [0, 1, 2],
428
+ });
402
429
  }
403
430
  modifyPci();
404
431
 
@@ -413,7 +440,7 @@ const run = async () => {
413
440
  if (dev) {
414
441
  const devIndex = args.indexOf("--dev");
415
442
  if (args.length <= devIndex + 1) {
416
- console.error("Missing dev target name. Using IMS template");
443
+ console.log("Using IMS template");
417
444
  watchBuild(true);
418
445
  } else {
419
446
  const target = args[devIndex + 1];