@longsightgroup/qti3-migrator 0.9.7 → 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 (55) hide show
  1. package/README.md +39 -1
  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/index.d.ts +4 -3
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +11 -119
  13. package/dist/index.js.map +1 -1
  14. package/dist/item-finalize.d.ts +12 -0
  15. package/dist/item-finalize.d.ts.map +1 -0
  16. package/dist/item-finalize.js +93 -0
  17. package/dist/item-finalize.js.map +1 -0
  18. package/dist/item-hrefs.d.ts +2 -0
  19. package/dist/item-hrefs.d.ts.map +1 -0
  20. package/dist/item-hrefs.js +19 -0
  21. package/dist/item-hrefs.js.map +1 -0
  22. package/dist/migrate-items.d.ts +6 -0
  23. package/dist/migrate-items.d.ts.map +1 -0
  24. package/dist/migrate-items.js +31 -0
  25. package/dist/migrate-items.js.map +1 -0
  26. package/dist/package-result.d.ts +10 -1
  27. package/dist/package-result.d.ts.map +1 -1
  28. package/dist/package-result.js +32 -0
  29. package/dist/package-result.js.map +1 -1
  30. package/dist/paths.d.ts +4 -0
  31. package/dist/paths.d.ts.map +1 -0
  32. package/dist/paths.js +16 -0
  33. package/dist/paths.js.map +1 -0
  34. package/dist/resource-migration.d.ts +4 -0
  35. package/dist/resource-migration.d.ts.map +1 -0
  36. package/dist/resource-migration.js +128 -0
  37. package/dist/resource-migration.js.map +1 -0
  38. package/dist/source.d.ts +5 -0
  39. package/dist/source.d.ts.map +1 -1
  40. package/dist/source.js +26 -6
  41. package/dist/source.js.map +1 -1
  42. package/dist/types.d.ts +33 -0
  43. package/dist/types.d.ts.map +1 -1
  44. package/package.json +3 -3
  45. package/src/assets.ts +23 -0
  46. package/src/diagnostics.ts +12 -0
  47. package/src/index.ts +23 -172
  48. package/src/item-finalize.ts +133 -0
  49. package/src/item-hrefs.ts +23 -0
  50. package/src/migrate-items.ts +39 -0
  51. package/src/package-result.ts +46 -0
  52. package/src/paths.ts +33 -0
  53. package/src/resource-migration.ts +197 -0
  54. package/src/source.ts +40 -6
  55. package/src/types.ts +39 -0
package/README.md CHANGED
@@ -10,7 +10,7 @@ import { migrateQtiToQti3 } from "@longsightgroup/qti3-migrator";
10
10
  const result = await migrateQtiToQti3({ filename: "quiz.zip", bytes });
11
11
  ```
12
12
 
13
- Use `migrateQtiToQti3Package` when the output should be passed directly to
13
+ Use `migrateQtiToQti3Package` for complete legacy QTI packages when the output should be passed directly to
14
14
  `@longsightgroup/qti3-writer` package APIs. Package migration preserves manifest item and asset
15
15
  paths from the source package:
16
16
 
@@ -26,4 +26,42 @@ if (migrated.ok) {
26
26
  }
27
27
  ```
28
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
+
29
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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
+ import { migrateQtiResourceToQti3 } from "./resource-migration.js";
1
2
  import { detectQtiMigrationSource } from "./source.js";
2
- import type { QtiMigrationItemResult, QtiMigrationOptions, QtiPackageMigrationResult, QtiMigrationResult, QtiMigrationSourceInput } from "./types.js";
3
- export { detectQtiMigrationSource };
4
- export type { QtiMigrationAsset, QtiMigrationDetectionResult, QtiMigrationDiagnostic, QtiMigrationDiagnosticSeverity, QtiMigrationItemResult, QtiMigrationOptions, QtiPackageMigrationResult, 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>;
6
7
  export declare function migrateQtiToQti3Package(input: QtiMigrationSourceInput, options?: QtiMigrationOptions): Promise<QtiPackageMigrationResult>;
7
8
  export declare function migrateQtiItemToQti3(input: QtiMigrationSourceInput, options?: QtiMigrationOptions): QtiMigrationItemResult;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,EAEL,wBAAwB,EAKzB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAIV,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EAEzB,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,yBAAyB,EACzB,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,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"}
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,13 +1,13 @@
1
- import { detectPackageMediaType, 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";
4
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";
5
6
  import { resolveOptions } from "./options.js";
6
7
  import { migrationResultToPackage } from "./package-result.js";
7
- import { migrateQti12Xml } from "./qti12-item.js";
8
- import { itemTitleFromXml, migrateQti2ItemXml } from "./qti2-item.js";
8
+ import { migrateQtiResourceToQti3 } from "./resource-migration.js";
9
9
  import { detectMigrationSource, detectQtiMigrationSource, parseLegacyManifest, readMigrationSource, } from "./source.js";
10
- export { detectQtiMigrationSource };
10
+ export { detectQtiMigrationSource, migrateQtiResourceToQti3 };
11
11
  export async function migrateQtiToQti3(input, options = {}) {
12
12
  const resolvedOptions = resolveOptions(options);
13
13
  const source = readMigrationSource(input);
@@ -119,10 +119,9 @@ function migratePackageSource(source, detection, options) {
119
119
  });
120
120
  continue;
121
121
  }
122
- const migratedItems = migrateItemXml(entry.text, href, sourceFormat, options);
122
+ const migratedItems = finalizeItemResults(migrateItemXml(entry.text, href, sourceFormat, options), href, options);
123
123
  for (const item of migratedItems) {
124
- const finalized = finalizeItemResult(item, href, options);
125
- items.push({ ...finalized, assetHrefs: assetHrefsByItemHref.get(href) ?? [] });
124
+ items.push({ ...item, assetHrefs: assetHrefsByItemHref.get(href) ?? [] });
126
125
  }
127
126
  }
128
127
  return {
@@ -130,14 +129,15 @@ function migratePackageSource(source, detection, options) {
130
129
  sourceFormat,
131
130
  parts: [partFromItems("PART_1", manifest.title, items)],
132
131
  items,
133
- assets: packageAssets(source.entries),
132
+ assets: migrationPackageAssets(source.entries),
134
133
  diagnostics,
135
134
  };
136
135
  }
137
136
  function migrateItemSource(source, detection, options) {
138
137
  const sourceFormat = detection.sourceFormat;
139
138
  const xml = source.xml ?? "";
140
- const migratedItems = migrateItemXml(xml, source.filename ?? "item.xml", sourceFormat, options).map((item) => finalizeItemResult(item, source.filename ?? `${item.identifier}.xml`, options));
139
+ const href = source.filename ?? "item.xml";
140
+ const migratedItems = finalizeItemResults(migrateItemXml(xml, href, sourceFormat, options), href, options);
141
141
  return {
142
142
  title: migratedItems[0]?.title ?? source.filename ?? "Imported QTI Item",
143
143
  sourceFormat,
@@ -147,115 +147,7 @@ function migrateItemSource(source, detection, options) {
147
147
  diagnostics: [],
148
148
  };
149
149
  }
150
- function migrateItemXml(xml, path, sourceFormat, options) {
151
- if (sourceFormat === "qti12") {
152
- return migrateQti12Xml(xml, path, options).map((result, index) => ({
153
- identifier: result.authoringItem?.identifier ?? `ITEM_${index + 1}`,
154
- title: result.authoringItem?.title ?? itemTitleFromXmlSafe(xml),
155
- authoringItem: result.authoringItem,
156
- diagnostics: result.diagnostics,
157
- }));
158
- }
159
- const result = migrateQti2ItemXml(xml, path, sourceFormat, options);
160
- return [
161
- {
162
- identifier: result.authoringItem?.identifier ?? migrationPathIdentifier(path),
163
- title: result.authoringItem?.title ?? itemTitleFromXmlSafe(xml),
164
- authoringItem: result.authoringItem,
165
- diagnostics: result.diagnostics,
166
- },
167
- ];
168
- }
169
- function finalizeItemResult(pending, href, options) {
170
- const diagnostics = [...pending.diagnostics];
171
- if (pending.authoringItem && !hasErrors(diagnostics)) {
172
- const writer = writeQti3AssessmentItemResult(pending.authoringItem);
173
- if (writer.ok) {
174
- diagnostics.push(...validateWrittenXml(writer.xml));
175
- return {
176
- identifier: pending.identifier,
177
- title: pending.title,
178
- href,
179
- authoringItem: pending.authoringItem,
180
- xml: writer.xml,
181
- diagnostics,
182
- };
183
- }
184
- diagnostics.push({
185
- code: "writer_diagnostics",
186
- severity: "error",
187
- message: "QTI 3 writer rejected migrated authoring item.",
188
- writerDiagnostics: writer.diagnostics,
189
- });
190
- }
191
- if (options.unsupportedPolicy === "stub") {
192
- const stub = stubItem(pending.identifier, pending.title);
193
- const writer = writeQti3AssessmentItemResult(stub);
194
- return {
195
- identifier: pending.identifier,
196
- title: pending.title,
197
- href,
198
- authoringItem: stub,
199
- xml: writer.ok ? writer.xml : undefined,
200
- diagnostics: [
201
- ...diagnostics,
202
- diagnostic("unsupported_item_stubbed", "warning", "Unsupported item migrated as an extended-text review stub."),
203
- ],
204
- };
205
- }
206
- return {
207
- identifier: pending.identifier,
208
- title: pending.title,
209
- href,
210
- authoringItem: options.unsupportedPolicy === "skip" ? undefined : pending.authoringItem,
211
- diagnostics,
212
- };
213
- }
214
- function validateWrittenXml(xml) {
215
- const parsed = parseQtiXml(xml);
216
- const diagnostics = [];
217
- if (!parsed.ok || !parsed.document) {
218
- diagnostics.push(...coreDiagnostics("core_parse", parsed.diagnostics));
219
- return diagnostics;
220
- }
221
- const validation = validateAssessmentItem(parsed.document);
222
- if (!validation.ok)
223
- diagnostics.push(...coreDiagnostics("core_validate", validation.diagnostics));
224
- return diagnostics;
225
- }
226
- function coreDiagnostics(prefix, diagnostics) {
227
- return diagnostics.map((entry) => diagnostic(`${prefix}.${entry.code}`, entry.severity === "error" ? "error" : "warning", entry.message));
228
- }
229
- function stubItem(identifier, title) {
230
- return {
231
- interactionType: "extendedText",
232
- identifier,
233
- title,
234
- bodyHtml: qti3TrustedXmlFragment("<p>This item requires manual migration review.</p>"),
235
- responseIdentifier: "RESPONSE",
236
- responseBaseType: "string",
237
- responseCardinality: "single",
238
- expectedLines: 6,
239
- };
240
- }
241
- function packageAssets(entries) {
242
- return entries
243
- .filter((entry) => !entry.path.toLowerCase().endsWith(".xml"))
244
- .map((entry) => ({
245
- path: entry.path,
246
- data: entry.bytes,
247
- mediaType: detectPackageMediaType(entry.path),
248
- }));
249
- }
250
150
  function partFromItems(identifier, title, items) {
251
151
  return { identifier, title, itemHrefs: items.map((item) => item.href) };
252
152
  }
253
- function itemTitleFromXmlSafe(xml) {
254
- try {
255
- return itemTitleFromXml(xml);
256
- }
257
- catch {
258
- return "Imported Item";
259
- }
260
- }
261
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":"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"}
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-items.js","sourceRoot":"","sources":["../src/migrate-items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAItE,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,IAAY,EACZ,YAAsC,EACtC,OAAoC;IAEpC,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,uBAAuB,CAAC,IAAI,CAAC;YAC7E,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;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAW;IAC9C,IAAI,CAAC;QACH,OAAO,gBAAgB,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC"}
@@ -1,3 +1,12 @@
1
- import type { QtiMigrationResult, QtiPackageMigrationResult } from "./types.js";
1
+ import type { QtiMigrationDiagnostic, QtiMigrationResourceEntry, QtiMigrationResult, QtiPackageMigrationResult } from "./types.js";
2
+ export type MigrationPackageEntriesResult = {
3
+ readonly ok: true;
4
+ readonly entries: readonly QtiMigrationResourceEntry[];
5
+ readonly diagnostics: readonly QtiMigrationDiagnostic[];
6
+ } | {
7
+ readonly ok: false;
8
+ readonly diagnostics: readonly QtiMigrationDiagnostic[];
9
+ };
2
10
  export declare function migrationResultToPackage(result: QtiMigrationResult): QtiPackageMigrationResult;
11
+ export declare function migrationResultToPackageEntries(result: QtiMigrationResult): MigrationPackageEntriesResult;
3
12
  //# sourceMappingURL=package-result.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"package-result.d.ts","sourceRoot":"","sources":["../src/package-result.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAGV,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAEpB,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,yBAAyB,CAuB9F"}
1
+ {"version":3,"file":"package-result.d.ts","sourceRoot":"","sources":["../src/package-result.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEV,sBAAsB,EACtB,yBAAyB,EACzB,kBAAkB,EAClB,yBAAyB,EAC1B,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,6BAA6B,GACrC;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,OAAO,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACvD,QAAQ,CAAC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAC;CACzD,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,SAAS,sBAAsB,EAAE,CAAA;CAAE,CAAC;AAEpF,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,kBAAkB,GAAG,yBAAyB,CAuB9F;AAED,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,kBAAkB,GACzB,6BAA6B,CA+B/B"}
@@ -1,3 +1,5 @@
1
+ import { detectPackageMediaType } from "@longsightgroup/qti3-core";
2
+ import { writeQti3PackageFilesResult } from "@longsightgroup/qti3-writer";
1
3
  import { diagnostic, hasErrors } from "./diagnostics.js";
2
4
  import { migrationPackageIdentifier } from "./identifiers.js";
3
5
  export function migrationResultToPackage(result) {
@@ -24,6 +26,36 @@ export function migrationResultToPackage(result) {
24
26
  diagnostics,
25
27
  };
26
28
  }
29
+ export function migrationResultToPackageEntries(result) {
30
+ const packageResult = migrationResultToPackage(result);
31
+ if (!packageResult.ok) {
32
+ return { ok: false, diagnostics: packageResult.diagnostics };
33
+ }
34
+ const files = writeQti3PackageFilesResult(packageResult.package);
35
+ if (!files.ok) {
36
+ return {
37
+ ok: false,
38
+ diagnostics: [
39
+ ...packageResult.diagnostics,
40
+ {
41
+ code: "writer_diagnostics",
42
+ severity: "error",
43
+ message: "QTI 3 writer rejected migrated package files.",
44
+ writerDiagnostics: files.diagnostics,
45
+ },
46
+ ],
47
+ };
48
+ }
49
+ return {
50
+ ok: true,
51
+ entries: files.files.map((file) => ({
52
+ path: file.path,
53
+ data: file.data,
54
+ mediaType: detectPackageMediaType(file.path),
55
+ })),
56
+ diagnostics: packageResult.diagnostics,
57
+ };
58
+ }
27
59
  function buildPackageItems(result, assetsByPath, diagnostics) {
28
60
  const items = [];
29
61
  for (const item of result.items) {