@hmos-library-adapter/fast 0.0.17-beta.0 → 0.0.17-beta.1
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/node_modules/@hmos-library-adapter/executer/README.md +2 -2
- package/node_modules/@hmos-library-adapter/executer/shared/skill-map.json +5 -1
- package/node_modules/@hmos-library-adapter/executer/shared/skills/arkts-rules/SKILL.md +400 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/CHANGELOG.md +1391 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/COMPATIBILITY.md +53 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/README.md +123 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/SKILL.md +48 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/agents/upgrade-assess-change.md +37 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/agents/upgrade-fix-file.md +23 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/package.json +19 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/26.0.0/beta1-changes-for-all-apps.md +1793 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/26.0.0/beta1-ux-style-and-effect-changes.md +288 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/26.0.0/beta2-changes-for-all-apps.md +148 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/26.0.0/release-changes-for-all-apps.md +662 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.1(13)/beta3-os-api-behavior-changes.md +652 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.1(13)/beta3-ux-style-and-effect-changes.md +222 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.1(13)/release-os-api-behavior-changes.md +444 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.1(13)/release-ux-style-and-effect-changes.md +221 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.2(14)/os-api-behavior-changes.md +1767 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.2(14)/ux-style-and-effect-changes.md +134 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.3(15)/beta1-os-api-behavior-changes.md +430 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.3(15)/beta1-ux-style-and-effect-changes.md +49 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.3(15)/beta2-os-api-behavior-changes.md +240 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.3(15)/beta2-ux-style-and-effect-changes.md +90 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.0.3(15)/release-os-api-behavior-changes.md +69 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.1.0(18)/os-api-behavior-changes.md +1294 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/5.1.0(18)/ux-style-and-effect-changes.md +147 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/6.0.0(20)/beta1-os-api-behavior-changes.md +1019 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/6.0.0(20)/beta1-ux-style-and-effect-changes.md +153 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/6.0.0(20)/beta2-os-api-behavior-changes.md +662 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/6.0.0(20)/beta2-ux-style-and-effect-changes.md +78 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/6.0.0(20)/beta3-os-api-behavior-changes.md +167 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/6.0.0(20)/beta5-os-api-behavior-changes.md +52 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs/6.1.0(23)/changes-for-all-apps.md +397 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/changelogs-index.json +883 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/arkts-coding-standards.md +53 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/compatibility.md +207 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/native-adaptation.md +21 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/runtime-functional-tests.md +62 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/sdk-versions.md +77 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/troubleshooting.md +54 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/verification.md +79 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/common/workflow-scan.md +41 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/deprecated/context-migration.md +274 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/deprecated/deprecated-api-adaptation.md +157 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/deprecated/deprecated-api-examples.md +219 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/toolchain/hvigor.md +50 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/upgrade/har-upgrade.md +60 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/upgrade/scanner-missed-cases.md +171 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/upgrade/upgrade-compatibility.md +112 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/upgrade/upgrade-examples.md +289 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/references/upgrade/upgrade-workflow.md +122 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/references/generate-behavior-policy.mjs +96 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/references/references.mjs +9 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/regression/compare-deprecated.mjs +57 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/regression/compare-golden.mjs +130 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/regression/regress-deprecated.mjs +120 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/behavior-catalog-generation.test.mjs +59 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/behavior-local-sources.test.mjs +44 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/changelog-index.test.mjs +66 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/compare-golden.test.mjs +103 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/fixtures/behavior/local-sources.csv +5 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/references.test.mjs +16 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/skill-content.test.mjs +139 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/skill-frontmatter.test.mjs +11 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/test/test-suite.test.mjs +65 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/validation/skill-content.mjs +125 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/validation/skill-frontmatter.mjs +6 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/maintenance/validation/validate-skill.mjs +57 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/CHANGELOG.md +506 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/GOLDEN_VALIDATION.md +42 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/README.md +137 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/behavior/behavior-policy.mjs +117 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/behavior/upgrade-coverage.mjs +29 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/bin/deveco-worker-compat.cjs +21 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/bin/harmony-api-scan.mjs +17 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/core/cli.mjs +416 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/core/deveco.mjs +348 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/core/project.mjs +81 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/core/rules.mjs +425 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/core/runtime-identity.mjs +23 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/core/scan-runner.mjs +521 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/core/sdk-deprecations.mjs +204 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/data/behavior-change-policy.json +4378 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/deprecated/arkts-deprecations.mjs +363 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/deprecated/build-log.mjs +72 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/native/native.mjs +95 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/package.json +16 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/batch-layout.test.mjs +94 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/behavior-policy.test.mjs +75 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/build-log.test.mjs +69 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/cli.test.mjs +102 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/csv.test.mjs +35 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/deprecations.test.mjs +283 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/deveco.test.mjs +262 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/helpers/scan-batch.mjs +10 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/native.test.mjs +108 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/project.test.mjs +42 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/rules.test.mjs +190 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/runtime-identity.test.mjs +53 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/scan-mode.test.mjs +38 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/scan-runner.test.mjs +481 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/scan-scope.test.mjs +110 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/source-inputs.test.mjs +64 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/scanner/test/upgrade.test.mjs +164 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/format/args.mjs +66 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/format/csv.mjs +85 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/format/json5.mjs +92 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/format/upgrade-results.mjs +45 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/format/zip.mjs +87 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/io/fs-utils.mjs +60 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/artifact-layout.mjs +74 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/changelog-index.mjs +29 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/deveco-version.mjs +40 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/document-links.mjs +30 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/errors.mjs +41 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/fs.mjs +72 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/paths.mjs +34 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/process.mjs +154 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/scan-mode.mjs +7 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/scan-statistics.mjs +7 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/scan-version-catalog.json +43 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/scan-versions.mjs +51 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/sdk-layout.mjs +27 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/source-scope.mjs +108 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/source-types.mjs +7 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/platform/version.mjs +76 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/deveco-version.test.mjs +50 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/document-links.test.mjs +13 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/errors.test.mjs +40 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/fs-utils.test.mjs +31 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/platform-paths.test.mjs +19 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/process-utils.test.mjs +68 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/scan-versions.test.mjs +26 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/sdk-version.test.mjs +17 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/shared/test/upgrade-results.test.mjs +140 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/scripts/test-suite.mjs +29 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/templates/deprecated-report.md +86 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/templates/progress.md +150 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/templates/results.md +110 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/templates/upgrade-report.md +105 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/templates/upgrade-spec.md +58 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-api-upgrade-adapter/templates/upgrade-test-report.md +47 -0
- package/node_modules/@hmos-library-adapter/executer/shared/skills/harmonyos-knowledge/SKILL.md +70 -0
- package/node_modules/@hmos-library-adapter/executer/src/config.js +3 -4
- package/node_modules/@hmos-library-adapter/executer/src/doctor.js +1 -1
- package/node_modules/@hmos-library-adapter/executer/src/install.js +1 -1
- package/node_modules/@hmos-library-adapter/executer/src/paths.js +4 -4
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"source": {
|
|
4
|
+
"ideVersion": "26.0.0.821",
|
|
5
|
+
"resourceDirectory": "plugins/harmony/arkanalyzer-apiscan/resources/apiChange",
|
|
6
|
+
"resourceArchive": "plugins/harmony/lib/project-api-change-assistant-26.0.0.821.jar",
|
|
7
|
+
"directoryVersionNamesSha256": "63a3aa73b3c0f3d78867b150b0265aea518127c93c7dd3aaef2abb9b0d3e4847",
|
|
8
|
+
"archiveVersionNamesSha256": "63a3aa73b3c0f3d78867b150b0265aea518127c93c7dd3aaef2abb9b0d3e4847"
|
|
9
|
+
},
|
|
10
|
+
"versions": [
|
|
11
|
+
"26.0.0(26) Beta1",
|
|
12
|
+
"26.0.0(26) Beta2",
|
|
13
|
+
"26.0.0(26) Release",
|
|
14
|
+
"5.0.1(13) Beta3",
|
|
15
|
+
"5.0.1(13) Release",
|
|
16
|
+
"5.0.2(14) Beta1",
|
|
17
|
+
"5.0.2(14) Release",
|
|
18
|
+
"5.0.3(15) Beta1",
|
|
19
|
+
"5.0.3(15) Beta2",
|
|
20
|
+
"5.0.3(15) Release",
|
|
21
|
+
"5.0.4(16) Release",
|
|
22
|
+
"5.0.5(17) Beta1",
|
|
23
|
+
"5.0.5(17) Release",
|
|
24
|
+
"5.1.0(18) Release",
|
|
25
|
+
"5.1.1(19) Beta1",
|
|
26
|
+
"5.1.1(19) Release",
|
|
27
|
+
"6.0.0(20) Beta1",
|
|
28
|
+
"6.0.0(20) Beta2",
|
|
29
|
+
"6.0.0(20) Beta3",
|
|
30
|
+
"6.0.0(20) Beta5",
|
|
31
|
+
"6.0.0(20) Release",
|
|
32
|
+
"6.0.1(21) Beta1",
|
|
33
|
+
"6.0.1(21) Release",
|
|
34
|
+
"6.0.2(22) Beta1",
|
|
35
|
+
"6.0.2(22) Release",
|
|
36
|
+
"6.1.0(23) Beta1",
|
|
37
|
+
"6.1.0(23) Beta2",
|
|
38
|
+
"6.1.0(23) Release",
|
|
39
|
+
"6.1.1(24) Beta1",
|
|
40
|
+
"6.1.1(24) Release"
|
|
41
|
+
],
|
|
42
|
+
"versionsSha256": "aba4bd23484de909da0e852bd3165de3b39dd5470eabb5e9710c4f20d1876df5"
|
|
43
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { readdir } from 'node:fs/promises';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { parseHarmonyVersion, compareHarmonyVersions, canonicalHarmonyVersion } from './version.mjs';
|
|
6
|
+
import { errorWithCode } from './errors.mjs';
|
|
7
|
+
import { listZipEntries } from '../format/zip.mjs';
|
|
8
|
+
|
|
9
|
+
const catalog = JSON.parse(readFileSync(new URL('./scan-version-catalog.json', import.meta.url), 'utf8'));
|
|
10
|
+
if (createHash('sha256').update(JSON.stringify(catalog.versions)).digest('hex') !== catalog.versionsSha256)
|
|
11
|
+
throw errorWithCode('Bundled scan version catalog checksum differs', 'SCAN_VERSION_CATALOG_INVALID');
|
|
12
|
+
export const bundledScanVersions = Object.freeze([...catalog.versions]);
|
|
13
|
+
export const scanVersionCatalogSource = Object.freeze(catalog.source);
|
|
14
|
+
export async function discoverScanVersions(toolchain = {}) {
|
|
15
|
+
const analyzer = toolchain.analyzer ?? toolchain;
|
|
16
|
+
const versions = new Set(bundledScanVersions);
|
|
17
|
+
const add = name => {
|
|
18
|
+
try { versions.add(canonicalHarmonyVersion(parseHarmonyVersion(path.basename(name, '.json')))); }
|
|
19
|
+
catch { /* Other resource files do not declare a version. */ }
|
|
20
|
+
};
|
|
21
|
+
async function visit(directory) {
|
|
22
|
+
let entries;
|
|
23
|
+
try { entries = await readdir(directory, { withFileTypes: true }); }
|
|
24
|
+
catch (error) { if (error.code === 'ENOENT') return; throw error; }
|
|
25
|
+
for (const entry of entries) {
|
|
26
|
+
if (entry.isDirectory()) await visit(path.join(directory, entry.name));
|
|
27
|
+
else if (entry.isFile() && entry.name.endsWith('.json')) add(entry.name);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (analyzer.apiChangeResourceRoot) await visit(analyzer.apiChangeResourceRoot);
|
|
31
|
+
if (analyzer.apiChangeResourceArchive) for (const name of await listZipEntries(analyzer.apiChangeResourceArchive))
|
|
32
|
+
if (/^apiChange\/.*\.json$/i.test(name)) add(name);
|
|
33
|
+
return [...versions].sort(compareHarmonyVersions);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function resolveScanVersion(input, { endpoint, compileSdkVersion = null, versions = bundledScanVersions } = {}) {
|
|
37
|
+
const parsed = parseHarmonyVersion(input);
|
|
38
|
+
const explicit = /(?:\s|_)(?:Beta\d*|Release|Canary\d*)$/i.test(String(input).trim());
|
|
39
|
+
// API12 is the existing behavior baseline; it has no scan rule resource.
|
|
40
|
+
const known = [...new Set(['5.0.0(12) Release', ...versions].map(value => canonicalHarmonyVersion(value)))];
|
|
41
|
+
let candidates = known.filter(value => {
|
|
42
|
+
const version = parseHarmonyVersion(value);
|
|
43
|
+
return version.apiLevel === parsed.apiLevel && version.platformVersion === parsed.platformVersion;
|
|
44
|
+
}).sort(compareHarmonyVersions);
|
|
45
|
+
if (explicit) candidates = candidates.filter(value => compareHarmonyVersions(value, parsed) === 0);
|
|
46
|
+
if (!candidates.length) throw errorWithCode(`No verified scan version for ${input}`, 'SCAN_VERSION_UNKNOWN', { input, endpoint });
|
|
47
|
+
if (endpoint === 'to' && compileSdkVersion) candidates = candidates.filter(value => compareHarmonyVersions(value, compileSdkVersion) <= 0);
|
|
48
|
+
if (!candidates.length) throw errorWithCode(`Scan endpoint ${input} exceeds compile SDK ${compileSdkVersion}`,
|
|
49
|
+
'SCAN_TARGET_NOT_COVERED', { input, compileSdkVersion });
|
|
50
|
+
return endpoint === 'from' ? candidates[0] : candidates.at(-1);
|
|
51
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { access } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { errorWithCode } from './errors.mjs';
|
|
4
|
+
|
|
5
|
+
async function exists(file) {
|
|
6
|
+
try { await access(file); return true; }
|
|
7
|
+
catch (error) { if (error.code === 'ENOENT' || error.code === 'ENOTDIR') return false; throw error; }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function resolveSdkRoot(input, { required = true } = {}) {
|
|
11
|
+
const inputPath = path.resolve(input);
|
|
12
|
+
let root = inputPath;
|
|
13
|
+
const checkedPaths = [path.join(root, 'default', 'sdk-pkg.json')];
|
|
14
|
+
if (!await exists(checkedPaths[0])) {
|
|
15
|
+
if ((process.platform === 'win32' ? path.basename(inputPath).toLowerCase() : path.basename(inputPath)) === 'default') {
|
|
16
|
+
checkedPaths.push(path.join(inputPath, 'sdk-pkg.json'));
|
|
17
|
+
if (await exists(checkedPaths[1])) root = path.dirname(inputPath);
|
|
18
|
+
else root = null;
|
|
19
|
+
} else root = null;
|
|
20
|
+
}
|
|
21
|
+
if (!root) {
|
|
22
|
+
if (!required) return null;
|
|
23
|
+
throw errorWithCode(`DevEco SDK metadata not found: ${inputPath}。请选择 SDK 根目录或其 default 目录。`,
|
|
24
|
+
'SDK_ROOT_INVALID', { inputPath, checkedPaths, hint: 'SDK 根目录应包含 default/sdk-pkg.json' });
|
|
25
|
+
}
|
|
26
|
+
return { root, inputPath, defaultRoot: path.join(root, 'default'), packagePath: path.join(root, 'default', 'sdk-pkg.json') };
|
|
27
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { existsSync, realpathSync } from 'node:fs';
|
|
3
|
+
import { readFile, realpath, stat } from 'node:fs/promises';
|
|
4
|
+
import { createHash } from 'node:crypto';
|
|
5
|
+
import { parseJson5 } from '../format/json5.mjs';
|
|
6
|
+
import { errorWithCode } from './errors.mjs';
|
|
7
|
+
|
|
8
|
+
export const SOURCE_EXCLUDED = new Set(['.git', 'oh_modules', 'node_modules', 'build', 'build-tools', '.hvigor', '.cxx',
|
|
9
|
+
'.test', '.preview', 'test', 'ohosTest', '.api-change-output', 'api-change-output', 'api-upgrade-runs']);
|
|
10
|
+
export const inside = (root, file) => {
|
|
11
|
+
const relative = path.relative(root, file);
|
|
12
|
+
return relative === '' || relative !== '..' && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
|
|
13
|
+
};
|
|
14
|
+
export const overlaps = (left, right) => inside(left, right) || inside(right, left);
|
|
15
|
+
export const relativeSource = (root, file) => path.relative(root, file).split(path.sep).join('/');
|
|
16
|
+
|
|
17
|
+
// Existing paths and parents of new helpers are checked physically, including junctions.
|
|
18
|
+
function physical(file) {
|
|
19
|
+
let parent = path.resolve(file), tail = [];
|
|
20
|
+
while (!existsSync(parent)) {
|
|
21
|
+
const next = path.dirname(parent);
|
|
22
|
+
if (next === parent) return path.resolve(file);
|
|
23
|
+
tail.unshift(path.basename(parent)); parent = next;
|
|
24
|
+
}
|
|
25
|
+
return path.join(realpathSync.native(parent), ...tail);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function resolveSourcePath(root, file, scope = null) {
|
|
29
|
+
const resolved = path.resolve(root, file), actual = physical(resolved);
|
|
30
|
+
const roots = [root, ...(scope?.modules ?? []).map(module => module.root)];
|
|
31
|
+
if (!roots.some(directory => inside(physical(directory), actual)))
|
|
32
|
+
throw errorWithCode(`Source path is outside the project and registered modules: ${file}`, 'SOURCE_PATH_OUTSIDE_PROJECT');
|
|
33
|
+
return resolved;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function projectModules(root, profile) {
|
|
37
|
+
const modules = [];
|
|
38
|
+
for (const item of profile.modules ?? []) {
|
|
39
|
+
if (typeof item.name !== 'string' || typeof item.srcPath !== 'string') continue;
|
|
40
|
+
const declared = path.resolve(root, item.srcPath);
|
|
41
|
+
let moduleRoot, json;
|
|
42
|
+
try {
|
|
43
|
+
moduleRoot = await realpath(declared);
|
|
44
|
+
json = parseJson5(await readFile(path.join(moduleRoot, 'src/main/module.json5'), 'utf8'));
|
|
45
|
+
} catch (error) { if (error.code === 'ENOENT') continue; throw error; }
|
|
46
|
+
let build = {};
|
|
47
|
+
try { build = parseJson5(await readFile(path.join(moduleRoot, 'build-profile.json5'), 'utf8')); }
|
|
48
|
+
catch (error) { if (error.code !== 'ENOENT') throw error; }
|
|
49
|
+
modules.push({ name: item.name, root: moduleRoot, relativeRoot: relativeSource(root, moduleRoot),
|
|
50
|
+
type: json.module?.type ?? null, deviceTypes: json.module?.deviceTypes ?? [],
|
|
51
|
+
target: build.targets?.find(target => target.name === 'default')?.name ?? build.targets?.[0]?.name ?? 'default',
|
|
52
|
+
hasNativeConfig: typeof build.buildOption?.externalNativeOptions?.path === 'string' });
|
|
53
|
+
}
|
|
54
|
+
return modules;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export async function createSourceScope(root, modules, { scanDirs = [], scanModules = [], projectType = 'app' } = {}) {
|
|
58
|
+
if (!['app', 'har'].includes(projectType)) throw errorWithCode('project-type must be app or har', 'INVALID_PROJECT_TYPE');
|
|
59
|
+
if (projectType === 'har' && !scanDirs.length && !scanModules.length)
|
|
60
|
+
throw errorWithCode('HAR requires --scan-module or --scan-dir', 'HAR_SCAN_SCOPE_REQUIRED');
|
|
61
|
+
for (const name of scanModules) if (modules.filter(module => module.name === name).length !== 1)
|
|
62
|
+
throw errorWithCode(`Unknown or ambiguous scan module: ${name}`, 'SCAN_MODULE_INVALID');
|
|
63
|
+
const directories = [];
|
|
64
|
+
for (const directory of scanDirs) {
|
|
65
|
+
const absolute = resolveSourcePath(root, directory, { modules });
|
|
66
|
+
if (!(await stat(absolute)).isDirectory()) throw errorWithCode(`Not a scan directory: ${directory}`, 'SCAN_DIRECTORY_INVALID');
|
|
67
|
+
directories.push(await realpath(absolute));
|
|
68
|
+
}
|
|
69
|
+
const selected = modules.filter(module => (!scanModules.length || scanModules.includes(module.name))
|
|
70
|
+
&& (!directories.length || directories.some(directory => overlaps(module.root, directory))));
|
|
71
|
+
if (!selected.length) throw errorWithCode('No HarmonyOS modules intersect the requested scan scope', 'SCAN_SCOPE_EMPTY');
|
|
72
|
+
if (projectType === 'har' && selected.some(module => module.type !== 'har'))
|
|
73
|
+
throw errorWithCode('HAR scan scope must contain only HAR modules', 'HAR_SCAN_SCOPE_INVALID');
|
|
74
|
+
const roots = scanModules.length || projectType === 'har' ? selected.map(module => module.root)
|
|
75
|
+
: [root, ...selected.filter(module => !inside(root, module.root)).map(module => module.root)];
|
|
76
|
+
const scope = { projectType, modules, scanModules: [...new Set(scanModules)].sort(),
|
|
77
|
+
scanDirs: [...new Set(directories)].sort(), roots: [...new Set(roots)].sort(),
|
|
78
|
+
selectedModules: selected.map(module => module.name).sort(), restricted: Boolean(scanDirs.length || scanModules.length || projectType === 'har') };
|
|
79
|
+
scope.fingerprint = createHash('sha256').update(JSON.stringify(scope)).digest('hex');
|
|
80
|
+
return scope;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function sourceInScope(root, file, scope) {
|
|
84
|
+
if (!scope) return inside(root, path.resolve(root, file));
|
|
85
|
+
let absolute;
|
|
86
|
+
try { absolute = physical(resolveSourcePath(root, file, scope)); } catch { return false; }
|
|
87
|
+
return scope.roots.some(directory => inside(directory, absolute))
|
|
88
|
+
&& (!scope.scanDirs.length || scope.scanDirs.some(directory => inside(directory, absolute)))
|
|
89
|
+
&& !relativeSource(root, absolute).split('/').some(segment => SOURCE_EXCLUDED.has(segment));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function sourceLocation(root, modules, location) {
|
|
93
|
+
const match = String(location).match(/^(.*?):(\d+)(?::(\d+))?$/);
|
|
94
|
+
if (!match) throw errorWithCode(`Invalid Code Location: ${location}`, 'SOURCE_LOCATION_INVALID');
|
|
95
|
+
const normalized = match[1].replaceAll('\\', '/'), first = normalized.split('/')[0];
|
|
96
|
+
const exact = modules.filter(module => module.name === first);
|
|
97
|
+
const candidates = exact.length ? exact : modules.filter(module => path.basename(module.root) === first);
|
|
98
|
+
if (candidates.length > 1) throw errorWithCode(`Ambiguous module in Code Location: ${location}`, 'SOURCE_LOCATION_AMBIGUOUS');
|
|
99
|
+
const file = candidates.length ? path.join(candidates[0].root, ...normalized.split('/').slice(1)) : path.resolve(root, normalized);
|
|
100
|
+
const absolutePath = resolveSourcePath(root, file, { modules });
|
|
101
|
+
const owners = modules.filter(module => inside(module.root, absolutePath)).sort((a,b) => b.root.length-a.root.length);
|
|
102
|
+
return { absolutePath, projectRelative: relativeSource(root, absolutePath), moduleName: owners[0]?.name ?? null,
|
|
103
|
+
line: Number(match[2]), column: match[3] ? Number(match[3]) : null };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function sourceDiscoveryRoots(root, scope) {
|
|
107
|
+
return [...new Set([root, ...(scope?.modules ?? []).map(module => module.root).filter(directory => !inside(root, directory))])].sort();
|
|
108
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
|
|
3
|
+
const arkTs = new Set(['.ets', '.ts']);
|
|
4
|
+
const native = new Set(['.c', '.cc', '.cpp', '.cxx', '.h', '.hpp']);
|
|
5
|
+
|
|
6
|
+
export const isArkTsSource = file => typeof file === 'string' && arkTs.has(path.extname(file).toLowerCase());
|
|
7
|
+
export const isSourceFile = file => isArkTsSource(file) || typeof file === 'string' && native.has(path.extname(file).toLowerCase());
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export const API_PLATFORM = new Map([
|
|
2
|
+
[12, '5.0.0'], [13, '5.0.1'], [14, '5.0.2'], [15, '5.0.3'], [16, '5.0.4'], [17, '5.0.5'],
|
|
3
|
+
[18, '5.1.0'], [19, '5.1.1'], [20, '6.0.0'], [21, '6.0.1'], [22, '6.0.2'], [23, '6.1.0'],
|
|
4
|
+
[24, '6.1.1'], [26, '26.0.0'],
|
|
5
|
+
]);
|
|
6
|
+
const PLATFORM_API = new Map([...API_PLATFORM].map(([level, platform]) => [platform, level]));
|
|
7
|
+
const CHANNEL_RANK = { canary: 0, beta: 1, release: 2 };
|
|
8
|
+
|
|
9
|
+
export function parseHarmonyVersion(input) {
|
|
10
|
+
if (!['string', 'number'].includes(typeof input)) throw new Error('SDK version must be a string or number');
|
|
11
|
+
let value = String(input).trim().replace(/^HarmonyOS_/i, '').replaceAll('_', ' ');
|
|
12
|
+
if (/^\d+$/.test(value)) {
|
|
13
|
+
const platform = API_PLATFORM.get(Number(value));
|
|
14
|
+
if (!platform) throw new Error(`Unknown HarmonyOS API level: ${value}`);
|
|
15
|
+
value = `${platform}(${value})`;
|
|
16
|
+
}
|
|
17
|
+
const match = value.match(/^(\d+)\.(\d+)\.(\d+)(?:\((\d+)(?:\.\d+\.\d+)?\))?(?:\s+(Canary|Beta|Release)(\d*)?)?$/i);
|
|
18
|
+
if (!match) throw new Error(`Unsupported SDK version: ${input}`);
|
|
19
|
+
let platformVersion = `${match[1]}.${match[2]}.${match[3]}`;
|
|
20
|
+
const apiLevel = match[4] ? Number(match[4]) : PLATFORM_API.get(platformVersion) ?? null;
|
|
21
|
+
if (apiLevel === 26 && platformVersion === '7.0.0') platformVersion = '26.0.0';
|
|
22
|
+
const [major, minor, patch] = platformVersion.split('.').map(Number);
|
|
23
|
+
const channel = (match[5] || 'Release').toLowerCase();
|
|
24
|
+
const channelNumber = Number(match[6] || 0);
|
|
25
|
+
const rank = apiLevel ?? major;
|
|
26
|
+
return { raw: String(input), platformVersion, major, minor, patch, apiLevel, rank,
|
|
27
|
+
channel, channelNumber, channelRank: CHANNEL_RANK[channel],
|
|
28
|
+
key: [rank, major, minor, patch, CHANNEL_RANK[channel], channelNumber] };
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function compareHarmonyVersions(left, right) {
|
|
32
|
+
const a = typeof left === 'object' ? left : parseHarmonyVersion(left);
|
|
33
|
+
const b = typeof right === 'object' ? right : parseHarmonyVersion(right);
|
|
34
|
+
const key = value => [value.apiLevel ?? value.rank ?? value.major,
|
|
35
|
+
...(value.platformVersion ? value.platformVersion.split('.').map(Number) : [value.major, value.minor, value.patch]),
|
|
36
|
+
CHANNEL_RANK[value.channel], value.channelNumber];
|
|
37
|
+
const ak = key(a), bk = key(b);
|
|
38
|
+
for (let i = 0; i < ak.length; i += 1) if (ak[i] !== bk[i]) return Math.sign(ak[i] - bk[i]);
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Build profiles contain platform/API versions, not SDK release channels.
|
|
43
|
+
export function compareConfigurationVersions(left, right) {
|
|
44
|
+
const a = typeof left === 'object' ? left : parseHarmonyVersion(left);
|
|
45
|
+
const b = typeof right === 'object' ? right : parseHarmonyVersion(right);
|
|
46
|
+
return compareHarmonyVersions({ ...a, channel: 'release', channelNumber: 0 },
|
|
47
|
+
{ ...b, channel: 'release', channelNumber: 0 });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function canonicalHarmonyVersion(input, includeChannel = true) {
|
|
51
|
+
const v = typeof input === 'object' ? input : parseHarmonyVersion(input);
|
|
52
|
+
const base = `${v.platformVersion ?? `${v.major}.${v.minor}.${v.patch}`}${v.apiLevel === null ? '' : `(${v.apiLevel})`}`;
|
|
53
|
+
return includeChannel ? `${base} ${v.channel[0].toUpperCase()}${v.channel.slice(1)}${v.channelNumber || ''}` : base;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function parseVersion(input) {
|
|
57
|
+
const version = parseHarmonyVersion(input);
|
|
58
|
+
if (version.apiLevel === null) throw new Error(`SDK API level is required for unknown version: ${input}`);
|
|
59
|
+
return version;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function assertUpgradeRange(from, to) {
|
|
63
|
+
const start = parseVersion(from);
|
|
64
|
+
const end = parseVersion(to);
|
|
65
|
+
if (compareHarmonyVersions(start, end) >= 0) {
|
|
66
|
+
throw new Error(`--from must be lower than --to: ${from} >= ${to}`);
|
|
67
|
+
}
|
|
68
|
+
return { start, end };
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function devecoVersionName(version) {
|
|
72
|
+
const parsed = typeof version === 'string' ? parseVersion(version) : version;
|
|
73
|
+
const channel = parsed.channel === 'release' ? 'Release'
|
|
74
|
+
: `${parsed.channel[0].toUpperCase()}${parsed.channel.slice(1)}${parsed.channelNumber || ''}`;
|
|
75
|
+
return `HarmonyOS_${parsed.platformVersion}(${parsed.apiLevel})_${channel}`;
|
|
76
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { assertDevEcoCompatibility, inspectDevEcoCompatibility } from '../platform/deveco-version.mjs';
|
|
4
|
+
|
|
5
|
+
test('DevEco minimum follows the target API mapping and compares numeric version components', () => {
|
|
6
|
+
for (const [version, target, status, required] of [
|
|
7
|
+
['26.0.0', '26', 'COMPATIBLE', '26.0.0'],
|
|
8
|
+
['26.0.0.821', '26.0.0(26) Beta2', 'COMPATIBLE', '26.0.0'],
|
|
9
|
+
['6.1.1.280', '24', 'COMPATIBLE', '6.1.1'],
|
|
10
|
+
['6.1.1', '6.1.1(24)', 'COMPATIBLE', '6.1.1'],
|
|
11
|
+
['26.0.0.821', '24', 'COMPATIBLE', '6.1.1'],
|
|
12
|
+
['6.1.1.999', '26', 'TOO_OLD', '26.0.0'],
|
|
13
|
+
['6.1.0.999', '24', 'TOO_OLD', '6.1.1'],
|
|
14
|
+
['6.0.9', '24', 'TOO_OLD', '6.1.1'],
|
|
15
|
+
['6.10.0', '24', 'COMPATIBLE', '6.1.1'],
|
|
16
|
+
['5.0.1.100', '13', 'COMPATIBLE', '5.0.1'],
|
|
17
|
+
]) {
|
|
18
|
+
const result = inspectDevEcoCompatibility({ version }, target);
|
|
19
|
+
assert.equal(result.status, status, `${version} -> ${target}`);
|
|
20
|
+
assert.equal(result.requiredVersion, required);
|
|
21
|
+
assert.equal(result.installedVersion, version);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('missing or malformed IDE versions never fall back to SDK or build numbers', () => {
|
|
26
|
+
for (const version of [undefined, null, 26, '', '26', '26.0', '26.0.0.1.2', '26.0.0 Beta1', 'invalid', '9007199254740992.0.0']) {
|
|
27
|
+
const result = inspectDevEcoCompatibility({ version, buildNumber: '26.0.0.821', file: '/IDE/product-info.json' }, '26', '/IDE');
|
|
28
|
+
assert.equal(result.status, 'UNRESOLVED');
|
|
29
|
+
assert.throws(() => assertDevEcoCompatibility(result), error => {
|
|
30
|
+
assert.equal(error.code, 'DEVECO_VERSION_UNRESOLVED');
|
|
31
|
+
assert.equal(error.stage, 'VALIDATE_DEVECO_VERSION');
|
|
32
|
+
assert.equal(error.details.metadataPath, '/IDE/product-info.json');
|
|
33
|
+
assert.match(error.message, /修复本地环境/);
|
|
34
|
+
return true;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('old IDE errors preserve the actual version and actionable target requirements', () => {
|
|
40
|
+
const result = inspectDevEcoCompatibility({ version: '6.1.1.280' }, '26');
|
|
41
|
+
assert.throws(() => assertDevEcoCompatibility(result), error => {
|
|
42
|
+
assert.equal(error.code, 'DEVECO_TARGET_NOT_COVERED');
|
|
43
|
+
assert.equal(error.details.installedVersion, '6.1.1.280');
|
|
44
|
+
assert.equal(error.details.requiredVersion, '26.0.0');
|
|
45
|
+
assert.match(error.message, /不在当前环境扫描范围内/);
|
|
46
|
+
assert.match(error.message, /降低预期目标版本或升级/);
|
|
47
|
+
return true;
|
|
48
|
+
});
|
|
49
|
+
assert.doesNotThrow(() => assertDevEcoCompatibility(inspectDevEcoCompatibility({ version: '26.0.0.821' }, '26')));
|
|
50
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {normalizeDocumentUrl,ruleDocumentLink} from '../platform/document-links.mjs';
|
|
4
|
+
test('synthetic and other-rule anchors cannot override a verified canonical change entry',()=>{
|
|
5
|
+
const expected='https://developer.huawei.com/consumer/cn/doc/doccenter-release-notes/changelogs-ux-7001#ch2026031846233';
|
|
6
|
+
const old='https://developer.huawei.com/consumer/cn/doc/harmonyos-releases/changelogs-ux-7001/';
|
|
7
|
+
for(const [fragment,reason]of [['scan-a45022895e24852a8a1f','SYNTHETIC_SCAN_ANCHOR'],['ch2026032801249','RULE_LINK_MISMATCH']]){
|
|
8
|
+
const result=ruleDocumentLink({url:expected},old+'#'+fragment);assert.equal(result.url,expected);assert.equal(result.rejectedReason,reason);
|
|
9
|
+
}
|
|
10
|
+
assert.equal(normalizeDocumentUrl(old+'#ch2026031846233'),expected);
|
|
11
|
+
assert.equal(ruleDocumentLink({url:expected},old+'#ch2026031846233').source,'VERIFIED_DEVECO_REPORT');
|
|
12
|
+
assert.equal(ruleDocumentLink({url:old},old+'#scan-fake').url,'');
|
|
13
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { execFile } from 'node:child_process';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { serializeError } from '../platform/errors.mjs';
|
|
8
|
+
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
const skillRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../..');
|
|
11
|
+
|
|
12
|
+
test('serializes stack, command, stage, cause and diagnostic artifacts', () => {
|
|
13
|
+
const cause = Object.assign(new Error('scanner failed'), { code: 'SCAN_FAILED', stage: 'RUN_DEVECO_SCAN' });
|
|
14
|
+
const error = Object.assign(new Error('adapter failed', { cause }), {
|
|
15
|
+
code: 'PREPARE_FAILED',
|
|
16
|
+
stage: 'RESOLVE_SDK_REFERENCE',
|
|
17
|
+
details: { file: 'D:/SDK/api/test.d.ts' },
|
|
18
|
+
validationErrors: ['missing source'],
|
|
19
|
+
artifactPaths: ['D:/project/diagnostics.json'],
|
|
20
|
+
});
|
|
21
|
+
const result = serializeError(error, { command: 'prepare' });
|
|
22
|
+
assert.equal(result.command, 'prepare');
|
|
23
|
+
assert.equal(result.stage, 'RESOLVE_SDK_REFERENCE');
|
|
24
|
+
assert.match(result.stack, /adapter failed/);
|
|
25
|
+
assert.equal(result.cause.code, 'SCAN_FAILED');
|
|
26
|
+
assert.deepEqual(result.artifactPaths, ['D:/project/diagnostics.json']);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test('scanner CLI failures expose structured stacks', async () => {
|
|
30
|
+
for (const script of ['scripts/scanner/bin/harmony-api-scan.mjs']) {
|
|
31
|
+
await assert.rejects(execFileAsync(process.execPath, [path.join(skillRoot, script), 'unknown-command']), error => {
|
|
32
|
+
const response = JSON.parse(error.stderr);
|
|
33
|
+
assert.equal(response.ok, false);
|
|
34
|
+
assert.equal(response.error.command, 'unknown-command');
|
|
35
|
+
assert.match(response.error.stack, /Unknown command/);
|
|
36
|
+
assert.ok(response.error.code);
|
|
37
|
+
return true;
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdtemp, mkdir, readFile, writeFile, rm } from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { atomicWrite, exists, pathExists, listFiles } from '../io/fs-utils.mjs';
|
|
7
|
+
|
|
8
|
+
test('shared traversal preserves strict scanner and optional maintenance missing-directory behavior', async t => {
|
|
9
|
+
const root = await mkdtemp(path.join(os.tmpdir(), 'shared-files-中文 空格-'));
|
|
10
|
+
t.after(() => rm(root, { recursive: true, force: true }));
|
|
11
|
+
const missing = path.join(root, 'missing');
|
|
12
|
+
await assert.rejects(listFiles(missing), { code: 'ENOENT' });
|
|
13
|
+
assert.deepEqual(await listFiles(missing, () => true, () => true, { allowMissing: true }), []);
|
|
14
|
+
assert.equal(await exists(missing), false);
|
|
15
|
+
assert.equal(await pathExists(missing), false);
|
|
16
|
+
assert.equal(await exists(null), false);
|
|
17
|
+
await assert.rejects(pathExists(null), TypeError);
|
|
18
|
+
await mkdir(path.join(root, 'excluded'));
|
|
19
|
+
await writeFile(path.join(root, 'a.txt'), 'a');
|
|
20
|
+
await writeFile(path.join(root, 'excluded', 'b.txt'), 'b');
|
|
21
|
+
assert.deepEqual(await listFiles(root, file => file.endsWith('.txt'), directory => path.basename(directory) !== 'excluded'), [path.join(root, 'a.txt')]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('shared atomic writes replace an existing file', async t => {
|
|
25
|
+
const root = await mkdtemp(path.join(os.tmpdir(), 'shared-write-'));
|
|
26
|
+
t.after(() => rm(root, { recursive: true, force: true }));
|
|
27
|
+
const file = path.join(root, 'existing.txt');
|
|
28
|
+
await writeFile(file, 'before');
|
|
29
|
+
await atomicWrite(file, 'after');
|
|
30
|
+
assert.equal(await readFile(file, 'utf8'), 'after');
|
|
31
|
+
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { portablePath, samePath, relativePathInside, comparableCodeLocation } from '../platform/paths.mjs';
|
|
4
|
+
|
|
5
|
+
test('normalizes Windows path identity and portable report paths', () => {
|
|
6
|
+
assert.equal(samePath('C:\\Work\\App\\Entry.ets', 'c:\\work\\app\\entry.ets', 'win32'), true);
|
|
7
|
+
assert.equal(samePath('C:\\Work\\App', 'D:\\Work\\App', 'win32'), false);
|
|
8
|
+
assert.equal(portablePath('entry\\src\\main\\A.ets'), 'entry/src/main/A.ets');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test('Windows containment and locations handle drives, UNC, casing and line numbers', () => {
|
|
12
|
+
assert.equal(relativePathInside('C:\\工程 空格','c:/工程 空格/Entry/A.ts','win32'),'Entry/A.ts');
|
|
13
|
+
assert.equal(relativePathInside('C:\\App','D:\\App\\A.ts','win32'),null);
|
|
14
|
+
assert.equal(relativePathInside('C:\\App','C:\\Application\\A.ts','win32'),null);
|
|
15
|
+
assert.equal(relativePathInside('C:\\App','C:\\App\\..\\secret.ts','win32'),null);
|
|
16
|
+
assert.equal(relativePathInside('\\\\server\\share\\App','\\\\SERVER\\SHARE\\app\\A.ts','win32'),'A.ts');
|
|
17
|
+
assert.equal(comparableCodeLocation('c:/WORK/App/Entry/A.ts:12:4','C:\\Work\\App','win32'),'entry/a.ts:12:4');
|
|
18
|
+
assert.notEqual(comparableCodeLocation('Entry/A.ts:1',null,'darwin'),comparableCodeLocation('entry/A.ts:1',null,'darwin'));
|
|
19
|
+
});
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdtemp, readFile, writeFile } from 'node:fs/promises';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { runProcess } from '../platform/process.mjs';
|
|
7
|
+
import { prependPath } from '../platform/process.mjs';
|
|
8
|
+
|
|
9
|
+
test('Windows PATH keeps the original search path with exactly one case-insensitive key', () => {
|
|
10
|
+
const original={Path:'C:\\Windows',OTHER:'kept'};
|
|
11
|
+
const env=prependPath(original,['D:\\工具 空格'],'win32');
|
|
12
|
+
assert.deepEqual(Object.keys(env).filter(key=>key.toLowerCase()==='path'),['Path']);
|
|
13
|
+
assert.equal(env.Path,'D:\\工具 空格;C:\\Windows');
|
|
14
|
+
assert.equal(original.Path,'C:\\Windows');
|
|
15
|
+
assert.equal(prependPath({Path:'old',PATH:'explicit'},['tools'],'win32').Path,'tools;explicit');
|
|
16
|
+
assert.deepEqual(prependPath({Path:'unrelated',PATH:'/bin'},['/tools'],'darwin'),{Path:'unrelated',PATH:'/tools:/bin'});
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test('output callbacks preserve stream arrival order, and spawn failure is explicit', async () => {
|
|
20
|
+
const output=[];
|
|
21
|
+
const result=await runProcess(process.execPath,['-e',"process.stdout.write('中文');setTimeout(()=>process.stderr.write('error'),30);setTimeout(()=>process.stdout.write('done'),60)"],
|
|
22
|
+
{onOutput:(chunk,stream)=>output.push([chunk,stream]),timeoutMs:3000});
|
|
23
|
+
assert.equal(result.exitCode,0);
|
|
24
|
+
assert.equal(output.filter(([,stream])=>stream==='stdout').map(([chunk])=>chunk).join(''),result.stdout);
|
|
25
|
+
assert.equal(output.filter(([,stream])=>stream==='stderr').map(([chunk])=>chunk).join(''),result.stderr);
|
|
26
|
+
assert.equal(result.stdout,'中文done');assert.equal(result.stderr,'error');
|
|
27
|
+
const missing=await runProcess(path.join(os.tmpdir(),'missing-adapter-executable'),[],{timeoutMs:1000});
|
|
28
|
+
assert.equal(missing.exitCode,null);assert.match(missing.error,/ENOENT/);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('a timeout terminates the spawned process tree', async () => {
|
|
32
|
+
const root = await mkdtemp(path.join(os.tmpdir(), 'adapter-process-tree-'));
|
|
33
|
+
const marker = path.join(root, 'orphan-marker.txt');
|
|
34
|
+
const grandchild = path.join(root, 'grandchild.mjs');
|
|
35
|
+
const parent = path.join(root, 'parent.mjs');
|
|
36
|
+
await writeFile(grandchild, `
|
|
37
|
+
import { writeFile } from 'node:fs/promises';
|
|
38
|
+
setTimeout(() => writeFile(process.argv[2], 'orphaned'), 500);
|
|
39
|
+
setInterval(() => {}, 1000);
|
|
40
|
+
`);
|
|
41
|
+
await writeFile(parent, `
|
|
42
|
+
import { spawn } from 'node:child_process';
|
|
43
|
+
spawn(process.execPath, [process.argv[2], process.argv[3]], { stdio: 'ignore' });
|
|
44
|
+
setInterval(() => {}, 1000);
|
|
45
|
+
`);
|
|
46
|
+
const result = await runProcess(process.execPath, [parent, grandchild, marker], {
|
|
47
|
+
detached: true,
|
|
48
|
+
timeoutMs: 75,
|
|
49
|
+
terminationGraceMs: 100,
|
|
50
|
+
});
|
|
51
|
+
assert.equal(result.timedOut, true);
|
|
52
|
+
await new Promise((resolve) => setTimeout(resolve, 650));
|
|
53
|
+
await assert.rejects(readFile(marker, 'utf8'), /ENOENT/);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('Windows command wrappers preserve spaces, Unicode, and shell metacharacters', {
|
|
57
|
+
skip: process.platform !== 'win32',
|
|
58
|
+
}, async () => {
|
|
59
|
+
const root = await mkdtemp(path.join(os.tmpdir(), 'adapter cmd 中文-'));
|
|
60
|
+
const capture = path.join(root, 'capture.mjs');
|
|
61
|
+
const wrapper = path.join(root, 'capture args.cmd');
|
|
62
|
+
await writeFile(capture, 'process.stdout.write(JSON.stringify(process.argv.slice(2)));\n');
|
|
63
|
+
await writeFile(wrapper, '@echo off\r\n"%NODE_PATH%" "%~dp0capture.mjs" %*\r\n');
|
|
64
|
+
const expected = ['plain', 'space value', '中文 参数', 'a&b', 'caret^value', 'pipe|value', 'percent%value', 'bang!value'];
|
|
65
|
+
const result = await runProcess(wrapper, expected, { env: { ...process.env, NODE_PATH: process.execPath } });
|
|
66
|
+
assert.equal(result.exitCode, 0, result.stderr);
|
|
67
|
+
assert.deepEqual(JSON.parse(result.stdout), expected);
|
|
68
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { bundledScanVersions, resolveScanVersion } from '../platform/scan-versions.mjs';
|
|
5
|
+
import { compareConfigurationVersions, compareHarmonyVersions } from '../platform/version.mjs';
|
|
6
|
+
|
|
7
|
+
test('version guide lists exactly the thirty supported API13+ versions in chronological order', async () => {
|
|
8
|
+
const guide = await readFile(new URL('../../../references/common/sdk-versions.md', import.meta.url), 'utf8');
|
|
9
|
+
const listed = [...guide.matchAll(/^\| \d+ \| `([^`]+)` \|/gm)].map(match => match[1]);
|
|
10
|
+
assert.deepEqual(listed, [...bundledScanVersions].sort(compareHarmonyVersions));
|
|
11
|
+
assert.equal(listed.length, 30);
|
|
12
|
+
assert.doesNotMatch(guide, /API\s*12|5\.0\.0\(12\)/i);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test('verified catalog chooses earliest starts, latest bounded ends and preserves explicit channels',()=>{
|
|
16
|
+
assert.equal(bundledScanVersions.length,30);
|
|
17
|
+
for (const [input,expected] of [['13','5.0.1(13) Beta3'],['16','5.0.4(16) Release'],['22','6.0.2(22) Beta1'],['23','6.1.0(23) Beta1']])
|
|
18
|
+
assert.equal(resolveScanVersion(input,{endpoint:'from'}),expected);
|
|
19
|
+
assert.equal(resolveScanVersion('20',{endpoint:'to',compileSdkVersion:'6.0.0(20) Beta5'}),'6.0.0(20) Beta5');
|
|
20
|
+
for(const channel of ['Beta1','Beta2','Release']) {
|
|
21
|
+
assert.equal(compareConfigurationVersions(`26.0.0 ${channel}`,'26.0.0'),0);
|
|
22
|
+
}
|
|
23
|
+
assert.equal(resolveScanVersion('6.1.0(23) Beta2',{endpoint:'from'}),'6.1.0(23) Beta2');
|
|
24
|
+
assert.throws(()=>resolveScanVersion('26.0.0(26) Release',{endpoint:'to',compileSdkVersion:'26.0.0 Beta1'}),{code:'SCAN_TARGET_NOT_COVERED'});
|
|
25
|
+
assert.throws(()=>resolveScanVersion('6.0.0(20) Beta4',{endpoint:'from'}),{code:'SCAN_VERSION_UNKNOWN'});
|
|
26
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import {
|
|
4
|
+
assertUpgradeRange,
|
|
5
|
+
compareHarmonyVersions as compareVersions,
|
|
6
|
+
devecoVersionName,
|
|
7
|
+
} from '../platform/version.mjs';
|
|
8
|
+
|
|
9
|
+
test('orders beta channels before release and validates an exclusive-inclusive range', () => {
|
|
10
|
+
assert.equal(devecoVersionName('26.0.0(26) Release'), 'HarmonyOS_26.0.0(26)_Release');
|
|
11
|
+
assert.ok(compareVersions('26.0.0(26) Canary1', '26.0.0(26) Beta') < 0);
|
|
12
|
+
assert.ok(compareVersions('26.0.0(26) Beta', '26.0.0(26) Beta1') < 0);
|
|
13
|
+
assert.ok(compareVersions('26.0.0(26) Beta1', '26.0.0(26) Beta2') < 0);
|
|
14
|
+
assert.ok(compareVersions('26.0.0(26) Beta2', '26.0.0(26) Release') < 0);
|
|
15
|
+
assert.equal(assertUpgradeRange('5.0.0(12)', '6.1.1(24)').end.apiLevel, 24);
|
|
16
|
+
assert.throws(() => assertUpgradeRange('6.1.1(24)', '6.1.1(24)'), /must be lower/);
|
|
17
|
+
});
|