@longsightgroup/qti3-migrator 0.9.6 → 0.9.8

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 (60) hide show
  1. package/README.md +54 -0
  2. package/dist/assets.d.ts +10 -0
  3. package/dist/assets.d.ts.map +1 -0
  4. package/dist/assets.js +19 -0
  5. package/dist/assets.js.map +1 -0
  6. package/dist/diagnostics.d.ts +2 -1
  7. package/dist/diagnostics.d.ts.map +1 -1
  8. package/dist/diagnostics.js +7 -0
  9. package/dist/diagnostics.js.map +1 -1
  10. package/dist/identifiers.d.ts +3 -0
  11. package/dist/identifiers.d.ts.map +1 -0
  12. package/dist/identifiers.js +11 -0
  13. package/dist/identifiers.js.map +1 -0
  14. package/dist/index.d.ts +5 -3
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +24 -133
  17. package/dist/index.js.map +1 -1
  18. package/dist/item-finalize.d.ts +12 -0
  19. package/dist/item-finalize.d.ts.map +1 -0
  20. package/dist/item-finalize.js +93 -0
  21. package/dist/item-finalize.js.map +1 -0
  22. package/dist/item-hrefs.d.ts +2 -0
  23. package/dist/item-hrefs.d.ts.map +1 -0
  24. package/dist/item-hrefs.js +19 -0
  25. package/dist/item-hrefs.js.map +1 -0
  26. package/dist/migrate-items.d.ts +6 -0
  27. package/dist/migrate-items.d.ts.map +1 -0
  28. package/dist/migrate-items.js +31 -0
  29. package/dist/migrate-items.js.map +1 -0
  30. package/dist/package-result.d.ts +12 -0
  31. package/dist/package-result.d.ts.map +1 -0
  32. package/dist/package-result.js +109 -0
  33. package/dist/package-result.js.map +1 -0
  34. package/dist/paths.d.ts +4 -0
  35. package/dist/paths.d.ts.map +1 -0
  36. package/dist/paths.js +16 -0
  37. package/dist/paths.js.map +1 -0
  38. package/dist/resource-migration.d.ts +4 -0
  39. package/dist/resource-migration.d.ts.map +1 -0
  40. package/dist/resource-migration.js +128 -0
  41. package/dist/resource-migration.js.map +1 -0
  42. package/dist/source.d.ts +5 -0
  43. package/dist/source.d.ts.map +1 -1
  44. package/dist/source.js +26 -6
  45. package/dist/source.js.map +1 -1
  46. package/dist/types.d.ts +43 -1
  47. package/dist/types.d.ts.map +1 -1
  48. package/package.json +3 -3
  49. package/src/assets.ts +23 -0
  50. package/src/diagnostics.ts +12 -0
  51. package/src/identifiers.ts +12 -0
  52. package/src/index.ts +45 -176
  53. package/src/item-finalize.ts +133 -0
  54. package/src/item-hrefs.ts +23 -0
  55. package/src/migrate-items.ts +39 -0
  56. package/src/package-result.ts +157 -0
  57. package/src/paths.ts +33 -0
  58. package/src/resource-migration.ts +197 -0
  59. package/src/source.ts +40 -6
  60. package/src/types.ts +53 -1
package/README.md CHANGED
@@ -10,4 +10,58 @@ import { migrateQtiToQti3 } from "@longsightgroup/qti3-migrator";
10
10
  const result = await migrateQtiToQti3({ filename: "quiz.zip", bytes });
11
11
  ```
12
12
 
13
+ Use `migrateQtiToQti3Package` for complete legacy QTI packages when the output should be passed directly to
14
+ `@longsightgroup/qti3-writer` package APIs. Package migration preserves manifest item and asset
15
+ paths from the source package:
16
+
17
+ ```ts
18
+ import { migrateQtiToQti3Package } from "@longsightgroup/qti3-migrator";
19
+ import { writeQti3PackageZipResult } from "@longsightgroup/qti3-writer";
20
+
21
+ const migrated = await migrateQtiToQti3Package({ filename: "quiz.zip", bytes });
22
+
23
+ if (migrated.ok) {
24
+ const qti3Package = writeQti3PackageZipResult(migrated.package);
25
+ console.log(qti3Package);
26
+ }
27
+ ```
28
+
29
+ Use `migrateQtiResourceToQti3` when a host package, such as IMS Common Cartridge, has already
30
+ identified one QTI resource and can provide that resource's local file closure. The result includes
31
+ launchable QTI 3 package entries, a `launchHref`, item hrefs, and diagnostics:
32
+
33
+ ```ts
34
+ import { migrateQtiResourceToQti3 } from "@longsightgroup/qti3-migrator";
35
+
36
+ const migrated = await migrateQtiResourceToQti3({
37
+ sourcePath: "assessment/quiz.xml",
38
+ files: {
39
+ "assessment/quiz.xml": quizXmlBytes,
40
+ "assessment/map.png": mapPngBytes,
41
+ },
42
+ });
43
+
44
+ if (migrated.ok) {
45
+ console.log(migrated.title);
46
+ console.log(migrated.launchHref);
47
+ console.log(migrated.entries);
48
+ }
49
+ ```
50
+
51
+ `files` is the local file closure for one IMS Common Cartridge QTI resource: keys are package-relative
52
+ paths within that resource, backslashes are normalized to forward slashes, and `sourcePath` must match
53
+ one of those keys after normalization. On success, `entries` is a standalone QTI 3 package file set
54
+ rooted at `imsmanifest.xml`; the caller decides where to store or repackage those files.
55
+
56
+ QTI 1.2 XML resources that contain multiple `<item>` elements are emitted as stable sibling item
57
+ paths so package output does not duplicate item paths while source-relative asset references keep the
58
+ same base directory.
59
+
60
+ Resource migration attaches every non-XML file in the provided closure to each migrated item. The
61
+ writer emits shared asset paths once when the referenced bytes are identical across items.
62
+
13
63
  Defaults are strict: source repair is disabled and unsupported interactions are reported as diagnostics instead of silently converted.
64
+
65
+ QTI assessment-test structure preservation is not implemented yet. When a legacy package contains an
66
+ assessment-test resource, migration returns a flat review part and reports
67
+ `assessment_test_structure_not_migrated`.
@@ -0,0 +1,10 @@
1
+ import type { MigrationEntry } from "./source.js";
2
+ import type { QtiMigrationAsset } from "./types.js";
3
+ export declare function migrationPackageAssets(entries: readonly MigrationEntry[]): QtiMigrationAsset[];
4
+ /**
5
+ * Asset hrefs for resource-level migration. Every migrated item receives the full non-XML file
6
+ * closure so host-provided dependencies remain available regardless of which sibling item references
7
+ * them.
8
+ */
9
+ export declare function resourceClosureAssetHrefs(entries: readonly MigrationEntry[]): readonly string[];
10
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,iBAAiB,EAAE,CAQ9F;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,cAAc,EAAE,GAAG,SAAS,MAAM,EAAE,CAE/F"}
package/dist/assets.js ADDED
@@ -0,0 +1,19 @@
1
+ import { detectPackageMediaType } from "@longsightgroup/qti3-core";
2
+ export function migrationPackageAssets(entries) {
3
+ return entries
4
+ .filter((entry) => !entry.path.toLowerCase().endsWith(".xml"))
5
+ .map((entry) => ({
6
+ path: entry.path,
7
+ data: entry.bytes,
8
+ mediaType: detectPackageMediaType(entry.path),
9
+ }));
10
+ }
11
+ /**
12
+ * Asset hrefs for resource-level migration. Every migrated item receives the full non-XML file
13
+ * closure so host-provided dependencies remain available regardless of which sibling item references
14
+ * them.
15
+ */
16
+ export function resourceClosureAssetHrefs(entries) {
17
+ return migrationPackageAssets(entries).map((asset) => asset.path);
18
+ }
19
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAKnE,MAAM,UAAU,sBAAsB,CAAC,OAAkC;IACvE,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SAC7D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,KAAK;QACjB,SAAS,EAAE,sBAAsB,CAAC,KAAK,CAAC,IAAI,CAAC;KAC9C,CAAC,CAAC,CAAC;AACR,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAkC;IAC1E,OAAO,sBAAsB,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AACpE,CAAC"}
@@ -1,7 +1,8 @@
1
- import type { QtiMigrationDiagnostic, QtiMigrationDiagnosticSeverity, QtiMigrationSourceFormat } from "./types.js";
1
+ import type { QtiMigrationDiagnostic, QtiMigrationDiagnosticSeverity, QtiMigrationResult, QtiMigrationSourceFormat } from "./types.js";
2
2
  export declare function diagnostic(code: string, severity: QtiMigrationDiagnosticSeverity, message: string, options?: {
3
3
  readonly path?: string | undefined;
4
4
  readonly sourceFormat?: QtiMigrationSourceFormat | undefined;
5
5
  }): QtiMigrationDiagnostic;
6
6
  export declare function hasErrors(diagnostics: readonly QtiMigrationDiagnostic[]): boolean;
7
+ export declare function aggregateMigrationDiagnostics(migration: QtiMigrationResult, extraDiagnostics?: readonly QtiMigrationDiagnostic[]): readonly QtiMigrationDiagnostic[];
7
8
  //# sourceMappingURL=diagnostics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,8BAA8B,EAC9B,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,8BAA8B,EACxC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACzD,GACL,sBAAsB,CAExB;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,SAAS,sBAAsB,EAAE,GAAG,OAAO,CAEjF"}
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,8BAA8B,EAC9B,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,8BAA8B,EACxC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IACP,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,YAAY,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;CACzD,GACL,sBAAsB,CAExB;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,SAAS,sBAAsB,EAAE,GAAG,OAAO,CAEjF;AAED,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,kBAAkB,EAC7B,gBAAgB,GAAE,SAAS,sBAAsB,EAAO,GACvD,SAAS,sBAAsB,EAAE,CAMnC"}
@@ -4,4 +4,11 @@ export function diagnostic(code, severity, message, options = {}) {
4
4
  export function hasErrors(diagnostics) {
5
5
  return diagnostics.some((entry) => entry.severity === "error");
6
6
  }
7
+ export function aggregateMigrationDiagnostics(migration, extraDiagnostics = []) {
8
+ return [
9
+ ...migration.diagnostics,
10
+ ...migration.items.flatMap((item) => item.diagnostics),
11
+ ...extraDiagnostics,
12
+ ];
13
+ }
7
14
  //# sourceMappingURL=diagnostics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,QAAwC,EACxC,OAAe,EACf,UAGI,EAAE;IAEN,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,WAA8C;IACtE,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;AACjE,CAAC"}
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,QAAwC,EACxC,OAAe,EACf,UAGI,EAAE;IAEN,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,WAA8C;IACtE,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,SAA6B,EAC7B,mBAAsD,EAAE;IAExD,OAAO;QACL,GAAG,SAAS,CAAC,WAAW;QACxB,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;QACtD,GAAG,gBAAgB;KACpB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ export declare function migrationPathIdentifier(path: string): string;
2
+ export declare function migrationPackageIdentifier(title: string): string;
3
+ //# sourceMappingURL=identifiers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifiers.d.ts","sourceRoot":"","sources":["../src/identifiers.ts"],"names":[],"mappings":"AAAA,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhE"}
@@ -0,0 +1,11 @@
1
+ export function migrationPathIdentifier(path) {
2
+ return sanitizeMigrationIdentifier(path, "ITEM", "ITEM");
3
+ }
4
+ export function migrationPackageIdentifier(title) {
5
+ return sanitizeMigrationIdentifier(title, "PACKAGE", "PACKAGE");
6
+ }
7
+ function sanitizeMigrationIdentifier(value, fallback, prefix) {
8
+ const normalized = value.replace(/\.[^.]+$/, "").replace(/[^A-Za-z0-9_]/g, "_") || fallback;
9
+ return /^[A-Za-z_]/.test(normalized) ? normalized : `${prefix}_${normalized}`;
10
+ }
11
+ //# sourceMappingURL=identifiers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifiers.js","sourceRoot":"","sources":["../src/identifiers.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,OAAO,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,UAAU,0BAA0B,CAAC,KAAa;IACtD,OAAO,2BAA2B,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,2BAA2B,CAAC,KAAa,EAAE,QAAgB,EAAE,MAAc;IAClF,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,QAAQ,CAAC;IAC5F,OAAO,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC;AAChF,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,9 @@
1
+ import { migrateQtiResourceToQti3 } from "./resource-migration.js";
1
2
  import { detectQtiMigrationSource } from "./source.js";
2
- import type { QtiMigrationItemResult, QtiMigrationOptions, QtiMigrationResult, QtiMigrationSourceInput } from "./types.js";
3
- export { detectQtiMigrationSource };
4
- export type { QtiMigrationAsset, QtiMigrationDetectionResult, QtiMigrationDiagnostic, QtiMigrationDiagnosticSeverity, QtiMigrationItemResult, QtiMigrationOptions, QtiMigrationPart, QtiMigrationRepairPolicy, QtiMigrationResult, QtiMigrationSourceFormat, QtiMigrationSourceInput, QtiMigrationUnsupportedPolicy, } from "./types.js";
3
+ import type { QtiMigrationItemResult, QtiMigrationOptions, QtiMigrationResult, QtiMigrationSourceInput, QtiPackageMigrationResult } from "./types.js";
4
+ export { detectQtiMigrationSource, migrateQtiResourceToQti3 };
5
+ export type { QtiMigrationAsset, QtiMigrationDetectionResult, QtiMigrationDiagnostic, QtiMigrationDiagnosticSeverity, QtiMigrationItemResult, QtiMigrationOptions, QtiPackageMigrationResult, QtiMigrationPart, QtiMigrationResourceEntry, QtiMigrationResourceInput, QtiMigrationRepairPolicy, QtiMigrationResult, QtiMigrationSourceFormat, QtiMigrationSourceInput, QtiMigrationUnsupportedPolicy, QtiResourceMigrationResult, QtiResourceMigrationStatus, } from "./types.js";
5
6
  export declare function migrateQtiToQti3(input: QtiMigrationSourceInput, options?: QtiMigrationOptions): Promise<QtiMigrationResult>;
7
+ export declare function migrateQtiToQti3Package(input: QtiMigrationSourceInput, options?: QtiMigrationOptions): Promise<QtiPackageMigrationResult>;
6
8
  export declare function migrateQtiItemToQti3(input: QtiMigrationSourceInput, options?: QtiMigrationOptions): QtiMigrationItemResult;
7
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAEL,wBAAwB,EAKzB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAIV,sBAAsB,EACtB,mBAAmB,EAEnB,kBAAkB,EAElB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,wBAAwB,EAAE,CAAC;AACpC,YAAY,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,sBAAsB,EACtB,8BAA8B,EAC9B,sBAAsB,EACtB,mBAAmB,EACnB,gBAAgB,EAChB,wBAAwB,EACxB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,GAC9B,MAAM,YAAY,CAAC;AAEpB,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,mBAAwB,GAChC,sBAAsB,CA8CxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAEL,wBAAwB,EAIzB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAGV,sBAAsB,EACtB,mBAAmB,EAEnB,kBAAkB,EAClB,uBAAuB,EACvB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,CAAC;AAC9D,YAAY,EACV,iBAAiB,EACjB,2BAA2B,EAC3B,sBAAsB,EACtB,8BAA8B,EAC9B,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,gBAAgB,EAChB,yBAAyB,EACzB,yBAAyB,EACzB,wBAAwB,EACxB,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,EACvB,6BAA6B,EAC7B,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,YAAY,CAAC;AAEpB,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;AAED,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,yBAAyB,CAAC,CAGpC;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,uBAAuB,EAC9B,OAAO,GAAE,mBAAwB,GAChC,sBAAsB,CA8CxB"}
package/dist/index.js CHANGED
@@ -1,11 +1,13 @@
1
- import { parseQtiXml, validateAssessmentItem } from "@longsightgroup/qti3-core";
2
- import { qti3TrustedXmlFragment, writeQti3AssessmentItemResult, } from "@longsightgroup/qti3-writer";
3
- import { diagnostic, hasErrors } from "./diagnostics.js";
1
+ import { diagnostic } from "./diagnostics.js";
2
+ import { migrationPathIdentifier } from "./identifiers.js";
3
+ import { finalizeItemResult, finalizeItemResults } from "./item-finalize.js";
4
+ import { migrateItemXml } from "./migrate-items.js";
5
+ import { migrationPackageAssets } from "./assets.js";
4
6
  import { resolveOptions } from "./options.js";
5
- import { migrateQti12Xml } from "./qti12-item.js";
6
- import { itemTitleFromXml, migrateQti2ItemXml } from "./qti2-item.js";
7
+ import { migrationResultToPackage } from "./package-result.js";
8
+ import { migrateQtiResourceToQti3 } from "./resource-migration.js";
7
9
  import { detectMigrationSource, detectQtiMigrationSource, parseLegacyManifest, readMigrationSource, } from "./source.js";
8
- export { detectQtiMigrationSource };
10
+ export { detectQtiMigrationSource, migrateQtiResourceToQti3 };
9
11
  export async function migrateQtiToQti3(input, options = {}) {
10
12
  const resolvedOptions = resolveOptions(options);
11
13
  const source = readMigrationSource(input);
@@ -29,6 +31,10 @@ export async function migrateQtiToQti3(input, options = {}) {
29
31
  : migrateItemSource(source, detection, resolvedOptions);
30
32
  return Promise.resolve(migrated);
31
33
  }
34
+ export async function migrateQtiToQti3Package(input, options = {}) {
35
+ const migration = await migrateQtiToQti3(input, options);
36
+ return migrationResultToPackage(migration);
37
+ }
32
38
  export function migrateQtiItemToQti3(input, options = {}) {
33
39
  const resolvedOptions = resolveOptions(options);
34
40
  const source = readMigrationSource(input);
@@ -85,6 +91,12 @@ function migratePackageSource(source, detection, options) {
85
91
  diagnostics.push(diagnostic("assessment_test_structure_not_migrated", "warning", "QTI assessment-test structure is not migrated yet; items are returned in a flat review part.", { sourceFormat, path: "imsmanifest.xml" }));
86
92
  }
87
93
  const entriesByPath = new Map(source.entries.map((entry) => [entry.path, entry]));
94
+ const assetHrefsByItemHref = new Map();
95
+ for (const resource of manifest.resources) {
96
+ if (!resource.href)
97
+ continue;
98
+ assetHrefsByItemHref.set(resource.href, resource.files.filter((file) => file !== resource.href && !file.toLowerCase().endsWith(".xml")));
99
+ }
88
100
  const itemHrefs = manifest.itemHrefs.length
89
101
  ? manifest.itemHrefs
90
102
  : source.entries
@@ -95,7 +107,7 @@ function migratePackageSource(source, detection, options) {
95
107
  const entry = entriesByPath.get(href) ?? entriesByPath.get(href.replace(/^\.\//, ""));
96
108
  if (!entry?.text) {
97
109
  items.push({
98
- identifier: pathIdentifier(href),
110
+ identifier: migrationPathIdentifier(href),
99
111
  title: href,
100
112
  href,
101
113
  diagnostics: [
@@ -107,9 +119,9 @@ function migratePackageSource(source, detection, options) {
107
119
  });
108
120
  continue;
109
121
  }
110
- const migratedItems = migrateItemXml(entry.text, href, sourceFormat, options);
122
+ const migratedItems = finalizeItemResults(migrateItemXml(entry.text, href, sourceFormat, options), href, options);
111
123
  for (const item of migratedItems) {
112
- items.push(finalizeItemResult(item, `${item.identifier}.xml`, options));
124
+ items.push({ ...item, assetHrefs: assetHrefsByItemHref.get(href) ?? [] });
113
125
  }
114
126
  }
115
127
  return {
@@ -117,14 +129,15 @@ function migratePackageSource(source, detection, options) {
117
129
  sourceFormat,
118
130
  parts: [partFromItems("PART_1", manifest.title, items)],
119
131
  items,
120
- assets: packageAssets(source.entries),
132
+ assets: migrationPackageAssets(source.entries),
121
133
  diagnostics,
122
134
  };
123
135
  }
124
136
  function migrateItemSource(source, detection, options) {
125
137
  const sourceFormat = detection.sourceFormat;
126
138
  const xml = source.xml ?? "";
127
- const migratedItems = migrateItemXml(xml, source.filename ?? "item.xml", sourceFormat, options).map((item) => finalizeItemResult(item, `${item.identifier}.xml`, options));
139
+ const href = source.filename ?? "item.xml";
140
+ const migratedItems = finalizeItemResults(migrateItemXml(xml, href, sourceFormat, options), href, options);
128
141
  return {
129
142
  title: migratedItems[0]?.title ?? source.filename ?? "Imported QTI Item",
130
143
  sourceFormat,
@@ -134,129 +147,7 @@ function migrateItemSource(source, detection, options) {
134
147
  diagnostics: [],
135
148
  };
136
149
  }
137
- function migrateItemXml(xml, path, sourceFormat, options) {
138
- if (sourceFormat === "qti12") {
139
- return migrateQti12Xml(xml, path, options).map((result, index) => ({
140
- identifier: result.authoringItem?.identifier ?? `ITEM_${index + 1}`,
141
- title: result.authoringItem?.title ?? itemTitleFromXmlSafe(xml),
142
- authoringItem: result.authoringItem,
143
- diagnostics: result.diagnostics,
144
- }));
145
- }
146
- const result = migrateQti2ItemXml(xml, path, sourceFormat, options);
147
- return [
148
- {
149
- identifier: result.authoringItem?.identifier ?? pathIdentifier(path),
150
- title: result.authoringItem?.title ?? itemTitleFromXmlSafe(xml),
151
- authoringItem: result.authoringItem,
152
- diagnostics: result.diagnostics,
153
- },
154
- ];
155
- }
156
- function finalizeItemResult(pending, href, options) {
157
- const diagnostics = [...pending.diagnostics];
158
- if (pending.authoringItem && !hasErrors(diagnostics)) {
159
- const writer = writeQti3AssessmentItemResult(pending.authoringItem);
160
- if (writer.ok) {
161
- diagnostics.push(...validateWrittenXml(writer.xml));
162
- return {
163
- identifier: pending.identifier,
164
- title: pending.title,
165
- href,
166
- authoringItem: pending.authoringItem,
167
- xml: writer.xml,
168
- diagnostics,
169
- };
170
- }
171
- diagnostics.push({
172
- code: "writer_diagnostics",
173
- severity: "error",
174
- message: "QTI 3 writer rejected migrated authoring item.",
175
- writerDiagnostics: writer.diagnostics,
176
- });
177
- }
178
- if (options.unsupportedPolicy === "stub") {
179
- const stub = stubItem(pending.identifier, pending.title);
180
- const writer = writeQti3AssessmentItemResult(stub);
181
- return {
182
- identifier: pending.identifier,
183
- title: pending.title,
184
- href,
185
- authoringItem: stub,
186
- xml: writer.ok ? writer.xml : undefined,
187
- diagnostics: [
188
- ...diagnostics,
189
- diagnostic("unsupported_item_stubbed", "warning", "Unsupported item migrated as an extended-text review stub."),
190
- ],
191
- };
192
- }
193
- return {
194
- identifier: pending.identifier,
195
- title: pending.title,
196
- href,
197
- authoringItem: options.unsupportedPolicy === "skip" ? undefined : pending.authoringItem,
198
- diagnostics,
199
- };
200
- }
201
- function validateWrittenXml(xml) {
202
- const parsed = parseQtiXml(xml);
203
- const diagnostics = [];
204
- if (!parsed.ok || !parsed.document) {
205
- diagnostics.push(...coreDiagnostics("core_parse", parsed.diagnostics));
206
- return diagnostics;
207
- }
208
- const validation = validateAssessmentItem(parsed.document);
209
- if (!validation.ok)
210
- diagnostics.push(...coreDiagnostics("core_validate", validation.diagnostics));
211
- return diagnostics;
212
- }
213
- function coreDiagnostics(prefix, diagnostics) {
214
- return diagnostics.map((entry) => diagnostic(`${prefix}.${entry.code}`, entry.severity === "error" ? "error" : "warning", entry.message));
215
- }
216
- function stubItem(identifier, title) {
217
- return {
218
- interactionType: "extendedText",
219
- identifier,
220
- title,
221
- bodyHtml: qti3TrustedXmlFragment("<p>This item requires manual migration review.</p>"),
222
- responseIdentifier: "RESPONSE",
223
- responseBaseType: "string",
224
- responseCardinality: "single",
225
- expectedLines: 6,
226
- };
227
- }
228
- function packageAssets(entries) {
229
- return entries
230
- .filter((entry) => !entry.path.toLowerCase().endsWith(".xml"))
231
- .map((entry) => ({ path: entry.path, data: entry.bytes, mediaType: mediaType(entry.path) }));
232
- }
233
150
  function partFromItems(identifier, title, items) {
234
151
  return { identifier, title, itemHrefs: items.map((item) => item.href) };
235
152
  }
236
- function pathIdentifier(path) {
237
- return path.replace(/\.[^.]+$/, "").replace(/[^A-Za-z0-9_]/g, "_") || "ITEM";
238
- }
239
- function itemTitleFromXmlSafe(xml) {
240
- try {
241
- return itemTitleFromXml(xml);
242
- }
243
- catch {
244
- return "Imported Item";
245
- }
246
- }
247
- function mediaType(path) {
248
- if (/\.png$/i.test(path))
249
- return "image/png";
250
- if (/\.jpe?g$/i.test(path))
251
- return "image/jpeg";
252
- if (/\.gif$/i.test(path))
253
- return "image/gif";
254
- if (/\.svg$/i.test(path))
255
- return "image/svg+xml";
256
- if (/\.mp3$/i.test(path))
257
- return "audio/mpeg";
258
- if (/\.mp4$/i.test(path))
259
- return "video/mp4";
260
- return undefined;
261
- }
262
153
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAsB,MAAM,2BAA2B,CAAC;AACpG,OAAO,EACL,sBAAsB,EACtB,6BAA6B,GAE9B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,wBAAwB,EACxB,mBAAmB,EACnB,mBAAmB,GAGpB,MAAM,aAAa,CAAC;AAarB,OAAO,EAAE,wBAAwB,EAAE,CAAC;AAgBpC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAA8B,EAC9B,UAA+B,EAAE;IAEjC,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,SAAS,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;QACpD,OAAO;YACL,KAAK,EAAE,KAAK,CAAC,QAAQ,IAAI,cAAc;YACvC,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,WAAW,EAAE;gBACX,UAAU,CACR,oBAAoB,EACpB,OAAO,EACP,qCAAqC,SAAS,CAAC,MAAM,GAAG,EACxD;oBACE,YAAY,EAAE,SAAS,CAAC,YAAY;iBACrC,CACF;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS;QAC/B,CAAC,CAAC,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC;QAC1D,CAAC,CAAC,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;IAC1D,OAAO,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAA8B,EAC9B,UAA+B,EAAE;IAEjC,MAAM,eAAe,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,CAAC,SAAS,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QAC3C,OAAO;YACL,UAAU,EAAE,MAAM;YAClB,KAAK,EAAE,KAAK,CAAC,QAAQ,IAAI,eAAe;YACxC,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE;gBACX,UAAU,CACR,qBAAqB,EACrB,OAAO,EACP,+CAA+C,EAC/C;oBACE,YAAY,EAAE,SAAS,CAAC,YAAY;iBACrC,CACF;aACF;SACF,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,cAAc,CAC5B,MAAM,CAAC,GAAG,EACV,KAAK,CAAC,QAAQ,IAAI,UAAU,EAC5B,SAAS,CAAC,YAAY,EACtB,eAAe,CAChB,CAAC;IACF,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO;YACL,UAAU,EAAE,MAAM;YAClB,KAAK,EAAE,KAAK,CAAC,QAAQ,IAAI,eAAe;YACxC,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE;gBACX,UAAU,CACR,sBAAsB,EACtB,OAAO,EACP,8CAA8C,EAC9C;oBACE,YAAY,EAAE,SAAS,CAAC,YAAY;iBACrC,CACF;aACF;SACF,CAAC;IACJ,CAAC;IACD,OAAO,kBAAkB,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,IAAI,GAAG,MAAM,CAAC,UAAU,MAAM,EAAE,eAAe,CAAC,CAAC;AACnG,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAAuB,EACvB,SAAsC,EACtC,OAA0C;IAE1C,MAAM,YAAY,GAAG,SAAS,CAAC,YAAa,CAAC;IAC7C,MAAM,aAAa,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CACvC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,iBAAiB,CAC1D,CAAC;IACF,MAAM,WAAW,GAA6B,EAAE,CAAC;IACjD,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC;QACzB,WAAW,CAAC,IAAI,CACd,UAAU,CAAC,kBAAkB,EAAE,OAAO,EAAE,yCAAyC,EAAE;YACjF,YAAY;YACZ,IAAI,EAAE,iBAAiB;SACxB,CAAC,CACH,CAAC;QACF,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,QAAQ,IAAI,sBAAsB;YAChD,YAAY;YACZ,KAAK,EAAE,EAAE;YACT,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,WAAW;SACZ,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IACzD,WAAW,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,CAAC;IACvF,IAAI,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;QAC9B,WAAW,CAAC,IAAI,CACd,UAAU,CACR,wCAAwC,EACxC,SAAS,EACT,8FAA8F,EAC9F,EAAE,YAAY,EAAE,IAAI,EAAE,iBAAiB,EAAE,CAC1C,CACF,CAAC;IACJ,CAAC;IACD,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAClF,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM;QACzC,CAAC,CAAC,QAAQ,CAAC,SAAS;QACpB,CAAC,CAAC,MAAM,CAAC,OAAO;aACX,MAAM,CACL,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,CACzF;aACA,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,KAAK,GAA6B,EAAE,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;QACtF,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC;gBACT,UAAU,EAAE,cAAc,CAAC,IAAI,CAAC;gBAChC,KAAK,EAAE,IAAI;gBACX,IAAI;gBACJ,WAAW,EAAE;oBACX,UAAU,CAAC,sBAAsB,EAAE,OAAO,EAAE,gBAAgB,IAAI,iBAAiB,EAAE;wBACjF,IAAI,EAAE,IAAI;wBACV,YAAY;qBACb,CAAC;iBACH;aACF,CAAC,CAAC;YACH,SAAS;QACX,CAAC;QACD,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;QAC9E,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1E,CAAC;IACH,CAAC;IACD,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,YAAY;QACZ,KAAK,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACvD,KAAK;QACL,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC;QACrC,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CACxB,MAAuB,EACvB,SAAsC,EACtC,OAA0C;IAE1C,MAAM,YAAY,GAAG,SAAS,CAAC,YAAa,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,IAAI,EAAE,CAAC;IAC7B,MAAM,aAAa,GAAG,cAAc,CAClC,GAAG,EACH,MAAM,CAAC,QAAQ,IAAI,UAAU,EAC7B,YAAY,EACZ,OAAO,CACR,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,UAAU,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7E,OAAO;QACL,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,MAAM,CAAC,QAAQ,IAAI,mBAAmB;QACxE,YAAY;QACZ,KAAK,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,gBAAgB,EAAE,aAAa,CAAC,CAAC;QACjE,KAAK,EAAE,aAAa;QACpB,MAAM,EAAE,EAAE;QACV,WAAW,EAAE,EAAE;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CACrB,GAAW,EACX,IAAY,EACZ,YAAsC,EACtC,OAA0C;IAE1C,IAAI,YAAY,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,eAAe,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACjE,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,UAAU,IAAI,QAAQ,KAAK,GAAG,CAAC,EAAE;YACnE,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,KAAK,IAAI,oBAAoB,CAAC,GAAG,CAAC;YAC/D,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,CAAC,CAAC,CAAC;IACN,CAAC;IACD,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,CAAC;IACpE,OAAO;QACL;YACE,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,UAAU,IAAI,cAAc,CAAC,IAAI,CAAC;YACpE,KAAK,EAAE,MAAM,CAAC,aAAa,EAAE,KAAK,IAAI,oBAAoB,CAAC,GAAG,CAAC;YAC/D,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC;KACF,CAAC;AACJ,CAAC;AASD,SAAS,kBAAkB,CACzB,OAA6B,EAC7B,IAAY,EACZ,OAA0C;IAE1C,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC7C,IAAI,OAAO,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,6BAA6B,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QACpE,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,WAAW,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACpD,OAAO;gBACL,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI;gBACJ,aAAa,EAAE,OAAO,CAAC,aAAa;gBACpC,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,WAAW;aACZ,CAAC;QACJ,CAAC;QACD,WAAW,CAAC,IAAI,CAAC;YACf,IAAI,EAAE,oBAAoB;YAC1B,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,gDAAgD;YACzD,iBAAiB,EAAE,MAAM,CAAC,WAAW;SACtC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,OAAO,CAAC,iBAAiB,KAAK,MAAM,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,6BAA6B,CAAC,IAAI,CAAC,CAAC;QACnD,OAAO;YACL,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,IAAI;YACJ,aAAa,EAAE,IAAI;YACnB,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;YACvC,WAAW,EAAE;gBACX,GAAG,WAAW;gBACd,UAAU,CACR,0BAA0B,EAC1B,SAAS,EACT,4DAA4D,CAC7D;aACF;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,IAAI;QACJ,aAAa,EAAE,OAAO,CAAC,iBAAiB,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa;QACvF,WAAW;KACZ,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,WAAW,GAA6B,EAAE,CAAC;IACjD,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACnC,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC;QACvE,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,UAAU,GAAG,sBAAsB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3D,IAAI,CAAC,UAAU,CAAC,EAAE;QAAE,WAAW,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,eAAe,EAAE,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;IAClG,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,SAAS,eAAe,CACtB,MAAc,EACd,WAAqC;IAErC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAC/B,UAAU,CACR,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,EACzB,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,EAChD,KAAK,CAAC,OAAO,CACd,CACF,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,UAAkB,EAAE,KAAa;IACjD,OAAO;QACL,eAAe,EAAE,cAAc;QAC/B,UAAU;QACV,KAAK;QACL,QAAQ,EAAE,sBAAsB,CAAC,oDAAoD,CAAC;QACtF,kBAAkB,EAAE,UAAU;QAC9B,gBAAgB,EAAE,QAAQ;QAC1B,mBAAmB,EAAE,QAAQ;QAC7B,aAAa,EAAE,CAAC;KACjB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,OAAkC;IACvD,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;SAC7D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,aAAa,CACpB,UAAkB,EAClB,KAAa,EACb,KAAwC;IAExC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,SAAS,cAAc,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC;AAC/E,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAY;IAC7B,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC;IAC7C,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IAChD,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC;IAC7C,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,eAAe,CAAC;IACjD,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IAC9C,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC;IAC7C,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type Qti3AuthoringItem } from "@longsightgroup/qti3-writer";
2
+ import type { QtiMigrationDiagnostic, QtiMigrationItemResult } from "./types.js";
3
+ import type { ResolvedQtiMigrationOptions } from "./types.js";
4
+ export interface PendingMigrationItem {
5
+ readonly identifier: string;
6
+ readonly title: string;
7
+ readonly authoringItem?: Qti3AuthoringItem | undefined;
8
+ readonly diagnostics: readonly QtiMigrationDiagnostic[];
9
+ }
10
+ export declare function finalizeItemResults(pendingItems: readonly PendingMigrationItem[], sourceHref: string, options: ResolvedQtiMigrationOptions): readonly QtiMigrationItemResult[];
11
+ export declare function finalizeItemResult(pending: PendingMigrationItem, href: string, options: ResolvedQtiMigrationOptions): QtiMigrationItemResult;
12
+ //# sourceMappingURL=item-finalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item-finalize.d.ts","sourceRoot":"","sources":["../src/item-finalize.ts"],"names":[],"mappings":"AACA,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,6BAA6B,CAAC;AAIrC,OAAO,KAAK,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACjF,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,aAAa,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;CACzD;AAED,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,SAAS,oBAAoB,EAAE,EAC7C,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,2BAA2B,GACnC,SAAS,sBAAsB,EAAE,CAenC;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,2BAA2B,GACnC,sBAAsB,CAkDxB"}
@@ -0,0 +1,93 @@
1
+ import { parseQtiXml, validateAssessmentItem } from "@longsightgroup/qti3-core";
2
+ import { qti3TrustedXmlFragment, writeQti3AssessmentItemResult, } from "@longsightgroup/qti3-writer";
3
+ import { diagnostic, hasErrors } from "./diagnostics.js";
4
+ import { uniqueSiblingItemHref } from "./item-hrefs.js";
5
+ export function finalizeItemResults(pendingItems, sourceHref, options) {
6
+ if (pendingItems.length <= 1) {
7
+ return pendingItems.map((item) => finalizeItemResult(item, sourceHref, options));
8
+ }
9
+ const identifiers = new Set();
10
+ const paths = new Set();
11
+ return pendingItems.map((item, index) => {
12
+ const identifier = item.identifier.trim();
13
+ const uniqueIdentifier = identifier && !identifiers.has(identifier);
14
+ if (uniqueIdentifier)
15
+ identifiers.add(identifier);
16
+ const suffix = uniqueIdentifier ? identifier : `ITEM_${index + 1}`;
17
+ const href = uniqueSiblingItemHref(sourceHref, suffix, paths);
18
+ return finalizeItemResult(item, href, options);
19
+ });
20
+ }
21
+ export function finalizeItemResult(pending, href, options) {
22
+ const diagnostics = [...pending.diagnostics];
23
+ if (pending.authoringItem && !hasErrors(diagnostics)) {
24
+ const writer = writeQti3AssessmentItemResult(pending.authoringItem);
25
+ if (writer.ok) {
26
+ diagnostics.push(...validateWrittenXml(writer.xml));
27
+ return {
28
+ identifier: pending.identifier,
29
+ title: pending.title,
30
+ href,
31
+ authoringItem: pending.authoringItem,
32
+ xml: writer.xml,
33
+ diagnostics,
34
+ };
35
+ }
36
+ diagnostics.push({
37
+ code: "writer_diagnostics",
38
+ severity: "error",
39
+ message: "QTI 3 writer rejected migrated authoring item.",
40
+ writerDiagnostics: writer.diagnostics,
41
+ });
42
+ }
43
+ if (options.unsupportedPolicy === "stub") {
44
+ const stub = stubItem(pending.identifier, pending.title);
45
+ const writer = writeQti3AssessmentItemResult(stub);
46
+ return {
47
+ identifier: pending.identifier,
48
+ title: pending.title,
49
+ href,
50
+ authoringItem: stub,
51
+ xml: writer.ok ? writer.xml : undefined,
52
+ diagnostics: [
53
+ ...diagnostics,
54
+ diagnostic("unsupported_item_stubbed", "warning", "Unsupported item migrated as an extended-text review stub."),
55
+ ],
56
+ };
57
+ }
58
+ return {
59
+ identifier: pending.identifier,
60
+ title: pending.title,
61
+ href,
62
+ authoringItem: options.unsupportedPolicy === "skip" ? undefined : pending.authoringItem,
63
+ diagnostics,
64
+ };
65
+ }
66
+ function validateWrittenXml(xml) {
67
+ const parsed = parseQtiXml(xml);
68
+ const diagnostics = [];
69
+ if (!parsed.ok || !parsed.document) {
70
+ diagnostics.push(...coreDiagnostics("core_parse", parsed.diagnostics));
71
+ return diagnostics;
72
+ }
73
+ const validation = validateAssessmentItem(parsed.document);
74
+ if (!validation.ok)
75
+ diagnostics.push(...coreDiagnostics("core_validate", validation.diagnostics));
76
+ return diagnostics;
77
+ }
78
+ function coreDiagnostics(prefix, diagnostics) {
79
+ return diagnostics.map((entry) => diagnostic(`${prefix}.${entry.code}`, entry.severity === "error" ? "error" : "warning", entry.message));
80
+ }
81
+ function stubItem(identifier, title) {
82
+ return {
83
+ interactionType: "extendedText",
84
+ identifier,
85
+ title,
86
+ bodyHtml: qti3TrustedXmlFragment("<p>This item requires manual migration review.</p>"),
87
+ responseIdentifier: "RESPONSE",
88
+ responseBaseType: "string",
89
+ responseCardinality: "single",
90
+ expectedLines: 6,
91
+ };
92
+ }
93
+ //# sourceMappingURL=item-finalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item-finalize.js","sourceRoot":"","sources":["../src/item-finalize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function uniqueSiblingItemHref(sourceHref: string, suffix: string, usedPaths: Set<string>): string;
2
+ //# sourceMappingURL=item-hrefs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item-hrefs.d.ts","sourceRoot":"","sources":["../src/item-hrefs.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,MAAM,CAgBR"}
@@ -0,0 +1,19 @@
1
+ import { migrationPathIdentifier } from "./identifiers.js";
2
+ export function uniqueSiblingItemHref(sourceHref, suffix, usedPaths) {
3
+ const slashIndex = sourceHref.lastIndexOf("/");
4
+ const directory = slashIndex >= 0 ? sourceHref.slice(0, slashIndex + 1) : "";
5
+ const fileName = slashIndex >= 0 ? sourceHref.slice(slashIndex + 1) : sourceHref;
6
+ const dotIndex = fileName.toLowerCase().endsWith(".xml")
7
+ ? fileName.length - 4
8
+ : fileName.lastIndexOf(".");
9
+ const baseName = dotIndex > 0 ? fileName.slice(0, dotIndex) : fileName || "item";
10
+ const extension = dotIndex > 0 ? fileName.slice(dotIndex) : ".xml";
11
+ const safeSuffix = migrationPathIdentifier(suffix);
12
+ let candidate = `${directory}${baseName}_${safeSuffix}${extension}`;
13
+ for (let index = 2; usedPaths.has(candidate); index += 1) {
14
+ candidate = `${directory}${baseName}_${safeSuffix}_${index}${extension}`;
15
+ }
16
+ usedPaths.add(candidate);
17
+ return candidate;
18
+ }
19
+ //# sourceMappingURL=item-hrefs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"item-hrefs.js","sourceRoot":"","sources":["../src/item-hrefs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,MAAM,UAAU,qBAAqB,CACnC,UAAkB,EAClB,MAAc,EACd,SAAsB;IAEtB,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/C,MAAM,SAAS,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7E,MAAM,QAAQ,GAAG,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;IACjF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC;QACtD,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;QACrB,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC9B,MAAM,QAAQ,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC;IACjF,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACnE,MAAM,UAAU,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACnD,IAAI,SAAS,GAAG,GAAG,SAAS,GAAG,QAAQ,IAAI,UAAU,GAAG,SAAS,EAAE,CAAC;IACpE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACzD,SAAS,GAAG,GAAG,SAAS,GAAG,QAAQ,IAAI,UAAU,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;IAC3E,CAAC;IACD,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACzB,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { PendingMigrationItem } from "./item-finalize.js";
2
+ import type { QtiMigrationSourceFormat } from "./types.js";
3
+ import type { ResolvedQtiMigrationOptions } from "./types.js";
4
+ export declare function migrateItemXml(xml: string, path: string, sourceFormat: QtiMigrationSourceFormat, options: ResolvedQtiMigrationOptions): readonly PendingMigrationItem[];
5
+ export declare function itemTitleFromXmlSafe(xml: string): string;
6
+ //# sourceMappingURL=migrate-items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-items.d.ts","sourceRoot":"","sources":["../src/migrate-items.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG/D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,YAAY,CAAC;AAE9D,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,wBAAwB,EACtC,OAAO,EAAE,2BAA2B,GACnC,SAAS,oBAAoB,EAAE,CAkBjC;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMxD"}
@@ -0,0 +1,31 @@
1
+ import { migrationPathIdentifier } from "./identifiers.js";
2
+ import { migrateQti12Xml } from "./qti12-item.js";
3
+ import { itemTitleFromXml, migrateQti2ItemXml } from "./qti2-item.js";
4
+ export function migrateItemXml(xml, path, sourceFormat, options) {
5
+ if (sourceFormat === "qti12") {
6
+ return migrateQti12Xml(xml, path, options).map((result, index) => ({
7
+ identifier: result.authoringItem?.identifier ?? `ITEM_${index + 1}`,
8
+ title: result.authoringItem?.title ?? itemTitleFromXmlSafe(xml),
9
+ authoringItem: result.authoringItem,
10
+ diagnostics: result.diagnostics,
11
+ }));
12
+ }
13
+ const result = migrateQti2ItemXml(xml, path, sourceFormat, options);
14
+ return [
15
+ {
16
+ identifier: result.authoringItem?.identifier ?? migrationPathIdentifier(path),
17
+ title: result.authoringItem?.title ?? itemTitleFromXmlSafe(xml),
18
+ authoringItem: result.authoringItem,
19
+ diagnostics: result.diagnostics,
20
+ },
21
+ ];
22
+ }
23
+ export function itemTitleFromXmlSafe(xml) {
24
+ try {
25
+ return itemTitleFromXml(xml);
26
+ }
27
+ catch {
28
+ return "Imported Item";
29
+ }
30
+ }
31
+ //# sourceMappingURL=migrate-items.js.map