@ohos-cpf/3rdloop 0.0.7 → 0.0.9
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/README.md +44 -25
- package/lib/cli.js +54 -29
- package/lib/config-cmd.js +1 -1
- package/lib/config.js +32 -0
- package/lib/doctor.js +266 -48
- package/lib/mcp.js +498 -0
- package/lib/opencode.js +75 -29
- package/lib/orch.js +32 -10
- package/lib/runner.js +8 -5
- package/lib/serve.js +162 -149
- package/lib/step.js +15 -4
- package/lib/web.js +107 -265
- package/lib/workflow.js +18 -8
- package/package.json +6 -2
- package/vendor/Archive/data/.index/meta.json +7 -0
- package/vendor/Archive/data/.index/search.db +0 -0
- package/vendor/Archive/data/docs/experiences/arkts-check-tool-pitfalls-baseline-comparison.md +13 -0
- package/vendor/Archive/data/docs/experiences/arkts-deep-path-import-recognition.md +31 -0
- package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-entry-file-case-mismatch.md +25 -0
- package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-import-trailing-slash.md +20 -0
- package/vendor/Archive/data/docs/experiences/arkts-library-source-files-may-be-ts.md +18 -0
- package/vendor/Archive/data/docs/experiences/arkts-typedarray-buffer-interface-cast-compile-fixes.md +36 -0
- package/vendor/Archive/data/docs/experiences/arkts-xts-compile-error-clustering-fix.md +24 -0
- package/vendor/Archive/data/docs/experiences/arkts-xts-doc-expected-value-runtime-probe.md +35 -0
- package/vendor/Archive/data/docs/experiences/arkts-xts-fixture-rawfile-testability-injection.md +33 -0
- package/vendor/Archive/data/docs/experiences/code-linter-chinese-comment-false-positive.md +16 -0
- package/vendor/Archive/data/docs/experiences/esobject-new-expression-variable-tracking.md +33 -0
- package/vendor/Archive/data/docs/experiences/filesystem-case-sensitivity-module-resolution.md +31 -0
- package/vendor/Archive/data/docs/experiences/gitcode-clone-redirect-warning-normal.md +13 -0
- package/vendor/Archive/data/docs/experiences/kn_msgvq1w585ec8319.md +77 -0
- package/vendor/Archive/data/docs/experiences/kn_msovnm6rd46de72c.md +98 -0
- package/vendor/Archive/data/docs/experiences/kn_mspt8vntfe708576.md +87 -0
- package/vendor/Archive/data/docs/experiences/kn_mspu1ei77adbbb48.md +133 -0
- package/vendor/Archive/data/docs/experiences/kn_mspubgak8d30bfce.md +128 -0
- package/vendor/Archive/data/docs/experiences/kn_mspug2de3cb1f7c3.md +115 -0
- package/vendor/Archive/data/docs/experiences/kn_skill_opt_001.md +38 -0
- package/vendor/Archive/data/docs/experiences/loop-artifacts-verification-evidence-triangle.md +19 -0
- package/vendor/Archive/data/docs/experiences/macos-bash-replace-build-ps1.md +19 -0
- package/vendor/Archive/data/docs/experiences/macos-bsd-diff-q-illegal-option.md +15 -0
- package/vendor/Archive/data/docs/experiences/migrate-cjs-compatible-api-version-map-limit.md +17 -0
- package/vendor/Archive/data/docs/experiences/mp3agic-arkts-library-behavior-quirks.md +21 -0
- package/vendor/Archive/data/docs/experiences/ohos-face-detection-scan-api-mapping.md +15 -0
- package/vendor/Archive/data/docs/experiences/pr-metadata-and-diff-integrity-verification.md +12 -0
- package/vendor/Archive/data/docs/experiences/rn-coverage-index-signature-pseudo-member-false-negative.md +32 -0
- package/vendor/Archive/data/docs/experiences/rn-memory-check-severity-calibration.md +21 -0
- package/vendor/Archive/data/docs/experiences/rn-platform-specific-api-exclusion-evidence.md +24 -0
- package/vendor/Archive/data/docs/experiences/rn-upstream-version-diff-pitfalls.md +17 -0
- package/vendor/Archive/data/docs/experiences/rn-version-gap-risk-rating-rules.md +13 -0
- package/vendor/Archive/data/docs/experiences/rn-view-lib-native-contract-diff-fabric-spec.md +16 -0
- package/vendor/Archive/data/docs/experiences/rnoh-adapter-package-version-field-semantics.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-arkts-sqlite-rows-array-format.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-dependency-residue-scan-strategy.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-local-lib-dep-use-tgz.md +53 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-prereserve-rntesterlist.md +17 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-template-compatiblesdkversion-upgrade.md +29 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-turbomodule-shell-adaptation-checklist.md +41 -0
- package/vendor/Archive/data/docs/experiences/rnoh-mcp-build-project-tool-risk.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-npm-devdependencies-version-precheck.md +29 -0
- package/vendor/Archive/data/docs/experiences/rnoh-repo-baseline-version-verification.md +13 -0
- package/vendor/Archive/data/docs/experiences/rnoh-repo-upstream-directory-mapping.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-stateless-library-zero-leak-verification.md +31 -0
- package/vendor/Archive/data/docs/experiences/rnoh-template-npmrc-credential-removal.md +15 -0
- package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-codegen-wiring-verification.md +19 -0
- package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-cpp-methodmap-compatibility-check.md +20 -0
- package/vendor/Archive/data/docs/experiences/scenario-doc-vs-source-signature-diff-four-patterns.md +24 -0
- package/vendor/Archive/data/docs/experiences/static-analysis-grep-cross-validation.md +29 -0
- package/vendor/Archive/demo.js +489 -0
- package/vendor/Archive/index.js +43 -0
- package/vendor/Archive/package.json +16 -0
- package/vendor/Archive/src/constants.js +83 -0
- package/vendor/Archive/src/data/stopwords.txt +110 -0
- package/vendor/Archive/src/data/synonyms.json +25 -0
- package/vendor/Archive/src/data/terms.txt +59 -0
- package/vendor/Archive/src/db/sqlite-backend.js +312 -0
- package/vendor/Archive/src/db/sqlite-schema.js +64 -0
- package/vendor/Archive/src/engine.js +501 -0
- package/vendor/Archive/src/index/index-manager.js +203 -0
- package/vendor/Archive/src/index/index-state.js +94 -0
- package/vendor/Archive/src/index/search-text-builder.js +106 -0
- package/vendor/Archive/src/index.js +22 -0
- package/vendor/Archive/src/parser/api-identifiers.js +121 -0
- package/vendor/Archive/src/parser/api-suffixes.js +48 -0
- package/vendor/Archive/src/parser/heading-normalize.js +40 -0
- package/vendor/Archive/src/parser/markdown-splitter.js +215 -0
- package/vendor/Archive/src/search/catalog-routing.js +87 -0
- package/vendor/Archive/src/search/fts-search.js +289 -0
- package/vendor/Archive/src/search/query-normalizer.js +159 -0
- package/vendor/Archive/src/search/query-rewriter.js +72 -0
- package/vendor/Archive/src/search/search-engine.js +72 -0
- package/vendor/Archive/src/search/snippet.js +64 -0
- package/vendor/Archive/src/store/dir-store.js +103 -0
- package/vendor/Archive/src/store/doc-store.js +36 -0
- package/vendor/Archive/src/tokenizer/lexicon.js +151 -0
- package/vendor/Archive/src/tokenizer/tokenizer.js +167 -0
- package/vendor/Archive/src/types.js +86 -0
- package/vendor/Archive/src/utils/hash.js +16 -0
- package/vendor/Archive/src/utils/lock.js +73 -0
- package/vendor/Archive/src/utils/path-safety.js +96 -0
- package/vendor/Archive/src/utils/paths.js +39 -0
- package/vendor/BadCase/rn/INDEX.md +127 -0
- package/vendor/BadCase/rn/cases/KI-001-webview/350/247/206/351/242/221/346/227/240/346/263/225/346/250/252/345/261/217.md +52 -0
- package/vendor/BadCase/rn/cases/KI-002-fastImage/347/203/255/346/233/264/346/226/260/345/233/276/347/211/207/345/244/261/350/264/245.md +37 -0
- package/vendor/BadCase/rn/cases/KI-003-wechat/347/274/251/347/225/245/345/233/276/346/234/254/345/234/260/345/233/276/347/211/207.md +62 -0
- package/vendor/BadCase/rn/cases/KI-004-wechat/345/233/236/350/260/203/346/227/266/345/272/217.md +47 -0
- package/vendor/BadCase/rn/cases/KI-005-geolocation/345/257/274/345/205/245/350/267/257/345/276/204/345/220/216/347/274/200.md +31 -0
- package/vendor/BadCase/rn/cases/KI-006-SmartRefreshLayout/346/231/272/350/203/275/346/214/207/351/222/210/345/264/251/346/272/203.md +55 -0
- package/vendor/BadCase/rn/cases/KI-007-orientation-locker/344/274/240/346/204/237/345/231/250/345/210/235/345/247/213/345/214/226.md +58 -0
- package/vendor/BadCase/rn/cases/KI-008-orientation-locker/344/274/240/346/204/237/345/231/250/345/274/225/347/224/250/350/256/241/346/225/260.md +47 -0
- package/vendor/BadCase/rn/cases/KI-009-pager-view/345/265/214/345/245/227/346/273/221/345/212/250.md +38 -0
- package/vendor/BadCase/rn/cases/KI-010-screens/346/211/213/345/212/277/345/206/262/347/252/201.md +48 -0
- package/vendor/BadCase/rn/cases/KI-011-spring-scrollview/346/211/213/345/212/277/351/207/215/345/244/215/347/273/221/345/256/232.md +49 -0
- package/vendor/BadCase/rn/cases/KI-012-qr-camera/346/250/252/345/261/217/351/200/202/351/205/215.md +59 -0
- package/vendor/BadCase/rn/cases/KI-013-webview/346/267/261/350/211/262/346/250/241/345/274/217/350/203/214/346/231/257/350/211/262.md +37 -0
- package/vendor/BadCase/rn/cases/KI-014-amap-geolocation/345/233/236/350/260/203/347/274/272/345/244/261.md +42 -0
- package/vendor/BadCase/rn/cases/KI-015-reanimated/350/277/220/350/241/214/346/227/266/346/236/220/346/236/204/345/264/251/346/272/203.md +54 -0
- package/vendor/BadCase/rn/cases/KI-016-fs/346/226/207/344/273/266/350/257/273/345/217/226/347/274/226/347/240/201.md +58 -0
- package/vendor/BadCase/rn/cases/KI-017-blob-util/345/217/202/346/225/260/347/274/226/347/240/201/351/224/231/350/257/257.md +39 -0
- package/vendor/BadCase/rn/cases/KI-018-modal/345/274/271/347/252/227/351/227/252/347/203/201.md +53 -0
- package/vendor/BadCase/rn/cases/KI-019-code-push/351/207/215/345/220/257/351/200/273/350/276/221/345/244/261/346/225/210.md +79 -0
- package/vendor/BadCase/rn/cases/KI-020-netinfo/346/225/217/346/204/237/344/277/241/346/201/257/346/263/204/351/234/262.md +60 -0
- package/vendor/BadCase/rn/cases/KI-021-video/346/234/254/345/234/260/350/247/206/351/242/221/346/222/255/346/224/276/345/274/202/345/270/270.md +79 -0
- package/vendor/BadCase/rn/cases/KI-022-audio-recorder-player/346/236/232/344/270/276/347/274/272/345/244/261.md +38 -0
- package/vendor/BadCase/rn/cases/KI-023-svg/346/270/220/345/217/230/347/273/247/346/211/277/345/244/261/346/225/210.md +62 -0
- package/vendor/BadCase/rn/generalization-log.md +55 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.json +328 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.md +382 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.json +1351 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.md +1176 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.json +538 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.md +1488 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.json +211 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.md +35 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.json +2048 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.md +3866 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.md +40 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.json +751 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.md +883 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.json +1544 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.md +2598 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.json +246 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.md +554 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.json +211 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.md +54 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.json +1626 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.md +2213 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.json +208 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.md +77 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.json +377 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.md +174 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.json +232 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.md +194 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.md +67 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.md +38 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.json +208 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.md +34 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.json +222 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.md +56 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.json +463 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.md +383 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.json +464 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.md +565 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.md +47 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.json +232 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.md +422 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.json +295 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.md +1038 -0
- package/vendor/BadCase/rn/rules/R-01-/345/205/250/345/261/217/347/252/227/345/217/243/347/212/266/346/200/201/347/256/241/347/220/206/345/256/214/346/225/264/346/200/247.md +20 -0
- package/vendor/BadCase/rn/rules/R-02-/350/265/204/346/272/220URI/345/275/242/346/200/201/345/210/206/346/224/257/350/246/206/347/233/226.md +21 -0
- package/vendor/BadCase/rn/rules/R-03-/351/231/204/345/261/236/346/223/215/344/275/234/345/244/261/350/264/245/351/230/273/346/226/255/344/270/273/346/265/201/347/250/213.md +20 -0
- package/vendor/BadCase/rn/rules/R-04-/345/274/202/346/255/245/345/233/236/350/260/203/346/263/250/345/206/214/346/227/266/345/272/217.md +20 -0
- package/vendor/BadCase/rn/rules/R-05-/346/250/241/345/235/227/345/257/274/345/205/245/350/267/257/345/276/204/350/247/204/350/214/203.md +19 -0
- package/vendor/BadCase/rn/rules/R-06-/344/274/240/346/204/237/345/231/250/347/241/254/344/273/266/346/235/203/351/231/220/346/214/211/351/234/200/350/216/267/345/217/226.md +21 -0
- package/vendor/BadCase/rn/rules/R-07-/346/231/272/350/203/275/346/214/207/351/222/210/347/224/237/345/221/275/345/221/250/346/234/237/347/256/241/347/220/206.md +20 -0
- package/vendor/BadCase/rn/rules/R-08-/346/211/213/345/212/277/344/272/213/344/273/266/346/263/250/345/206/214/344/270/216/345/206/262/347/252/201/345/244/204/347/220/206.md +22 -0
- package/vendor/BadCase/rn/rules/R-09-/346/250/252/347/253/226/345/261/217/345/244/232/345/275/242/346/200/201/345/270/203/345/261/200/351/200/202/351/205/215.md +20 -0
- package/vendor/BadCase/rn/rules/R-10-/346/267/261/350/211/262/346/250/241/345/274/217/344/270/273/351/242/230/351/242/234/350/211/262/351/200/202/351/205/215.md +19 -0
- package/vendor/BadCase/rn/rules/R-11-/346/216/245/345/217/243/345/233/236/350/260/203/345/256/236/347/216/260/345/256/214/346/225/264/346/200/247.md +20 -0
- package/vendor/BadCase/rn/rules/R-12-/345/216/237/347/224/237/350/277/220/350/241/214/346/227/266/350/265/204/346/272/220/346/236/220/346/236/204/346/227/266/345/272/217.md +20 -0
- package/vendor/BadCase/rn/rules/R-13-/346/226/207/344/273/266/346/225/260/346/215/256/347/274/226/347/240/201/344/270/216/346/240/274/345/274/217/345/205/274/345/256/271.md +21 -0
- package/vendor/BadCase/rn/rules/R-14-/345/212/250/347/224/273/345/210/235/345/247/213/345/214/226/346/227/266/345/272/217/344/270/216/347/212/266/346/200/201/345/220/214/346/255/245.md +20 -0
- package/vendor/BadCase/rn/rules/R-15-/347/212/266/346/200/201/346/214/201/344/271/205/345/214/226/344/270/216/351/207/215/345/220/257/351/200/273/350/276/221/344/270/200/350/207/264/346/200/247.md +20 -0
- package/vendor/BadCase/rn/rules/R-16-/346/225/217/346/204/237/344/277/241/346/201/257/346/227/245/345/277/227/346/263/204/351/234/262.md +19 -0
- package/vendor/BadCase/rn/rules/R-17-/345/252/222/344/275/223/350/265/204/346/272/220/347/224/237/345/221/275/345/221/250/346/234/237/344/270/216/351/224/231/350/257/257/345/244/204/347/220/206.md +21 -0
- package/vendor/BadCase/rn/rules/R-18-/350/203/275/345/212/233/346/236/232/344/270/276/351/205/215/347/275/256/345/256/214/346/225/264/346/200/247.md +19 -0
- package/vendor/BadCase/rn/rules/R-19-/345/233/276/345/275/242/346/270/262/346/237/223/345/261/236/346/200/247/347/273/247/346/211/277/344/270/216/351/207/215/347/275/256.md +19 -0
- package/vendor/MCP/README.md +490 -0
- package/vendor/MCP/config.json +29 -0
- package/vendor/MCP/package.json +23 -0
- package/vendor/MCP/scripts/analyze-demo-coverage.cjs +1203 -0
- package/vendor/MCP/scripts/analyze-xts-coverage.cjs +1245 -0
- package/vendor/MCP/scripts/deveco_docs.js +247 -0
- package/vendor/MCP/scripts/extract-interfaces.cjs +1487 -0
- package/vendor/MCP/scripts/flutter-analyze-demo-coverage.cjs +666 -0
- package/vendor/MCP/scripts/flutter-analyze-xts-coverage.cjs +684 -0
- package/vendor/MCP/scripts/flutter-extract-interfaces.cjs +1251 -0
- package/vendor/MCP/scripts/flutter-render-spec-doc.cjs +351 -0
- package/vendor/MCP/scripts/render-spec-doc.cjs +347 -0
- package/vendor/MCP/scripts/rn-analyze-demo-coverage.cjs +645 -0
- package/vendor/MCP/scripts/rn-analyze-test-coverage.cjs +614 -0
- package/vendor/MCP/scripts/rn-extract-interfaces.cjs +1462 -0
- package/vendor/MCP/scripts/rn-render-spec-doc.cjs +327 -0
- package/vendor/MCP/scripts/rn-scan-exports.cjs +1336 -0
- package/vendor/MCP/src/client/MCPClientPool.js +220 -0
- package/vendor/MCP/src/config/ConfigLoader.js +189 -0
- package/vendor/MCP/src/executor/ScriptExecutor.js +110 -0
- package/vendor/MCP/src/gateway/Gateway.js +451 -0
- package/vendor/MCP/src/index.js +87 -0
- package/vendor/MCP/src/library/KBToolProvider.js +229 -0
- package/vendor/MCP/src/library/logger.js +60 -0
- package/vendor/MCP/src/registry/ScriptRegistry.js +238 -0
- package/vendor/MCP/src/registry/ToolRegistry.js +111 -0
- package/vendor/MCP/src/types.js +115 -0
- package/vendor/Server/CLI/cli.js +3 -3
- package/vendor/Server/Routes/server.js +3 -3
- package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +4 -2
- package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +3 -3
- package/vendor/Server/Skills/knowledge-import/SKILL.md +1 -1
- package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +12 -4
- package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +5 -4
- package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +2 -2
- package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +2 -2
- package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +1 -2
- package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +1 -1
- package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +1 -2
- package/vendor/Server/package.json +5 -1
- package/vendor/VERSION +3 -3
package/vendor/BadCase/rn/cases/KI-009-pager-view/345/265/214/345/245/227/346/273/221/345/212/250.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# KI-009 react-native-pager-view:嵌套滑动父子组件无法联动
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-08` · `verified: diff` · `source: dtse` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-pager-view/pull/32(merged,8 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-pager-view-32.md](../pr-info/rntpc_react-native-pager-view-32.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
RN pager-view 嵌套滑动问题——父子组件无法联动响应。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
SwiperNode 嵌套在 ScrollView 中时,未配置 NestedScroll 模式,导致手势事件被外层 ScrollView 独占,内层 pager-view 无法响应滑动。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前,C++ 层)
|
|
16
|
+
|
|
17
|
+
```cpp
|
|
18
|
+
// SwiperNode.cpp — init() 中无 NestedScroll 配置
|
|
19
|
+
void SwiperNode::init() {
|
|
20
|
+
// 未设置 NestedScrollMode ← 嵌套滚动时手势被外层拦截
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 正确代码(修复后)
|
|
25
|
+
|
|
26
|
+
```cpp
|
|
27
|
+
// SwiperNode.cpp — ① 设置 NestedScroll 模式
|
|
28
|
+
void SwiperNode::init() {
|
|
29
|
+
// 配置 NestedScrollMode 为 PARENT_FIRST,支持嵌套滚动联动
|
|
30
|
+
ArkUI_NumberValue value[] = {{.i32 = ARKUI_NESTED_SCROLL_PARENT_FIRST}};
|
|
31
|
+
ArkUI_AttributeItem item = {value, 1};
|
|
32
|
+
nativeModule->setAttribute(m_nodeHandle, NODE_NESTED_SCROLL, &item);
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## 修复方式
|
|
37
|
+
|
|
38
|
+
在 SwiperNode 初始化时配置 NestedScroll 模式,使嵌套在 ScrollView 中的 pager-view 能正确参与嵌套滚动手势分发。
|
package/vendor/BadCase/rn/cases/KI-010-screens/346/211/213/345/212/277/345/206/262/347/252/201.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# KI-010 react-native-screens:手势冲突与默认值错误
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-08` · `verified: diff` · `source: community-issue` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-screens/pull/87, https://gitcode.com/CPF-RN/rntpc_react-native-screens/pull/93(merged)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-screens-87.md](../pr-info/rntpc_react-native-screens-87.md), [../pr-info/rntpc_react-native-screens-93.md](../pr-info/rntpc_react-native-screens-93.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
houldBuiltInRecognizerParallelWith 无法触发回调;原生组件手势和库冲突。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
1. gestureEnabled 默认值为 false,导致手势整体失效;2. 手势冲突时缺少 onGestureRecognizerJudgeBegin 仲裁逻辑,系统手势(如返回)与库手势冲突。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// RNSScreen.ets
|
|
19
|
+
private gestureEnabled: boolean = false; // ← 默认 false,手势整体失效
|
|
20
|
+
// 无 onGestureRecognizerJudgeBegin 仲裁 ← 手势冲突
|
|
21
|
+
.gesture(
|
|
22
|
+
PanGesture({ direction: this.from ? PanDirection.None : PanDirection.All })
|
|
23
|
+
// ...
|
|
24
|
+
)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 正确代码(修复后)
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// ① gestureEnabled 默认值改为 true
|
|
31
|
+
private gestureEnabled: boolean = true;
|
|
32
|
+
|
|
33
|
+
// ② 添加手势仲裁逻辑
|
|
34
|
+
.onGestureRecognizerJudgeBegin((event: BaseGestureEvent, current: GestureRecognizer, others: Array<GestureRecognizer>): GestureJudgeResult => {
|
|
35
|
+
if (this.gestureEnabled && this.fullScreenSwipeEnabled && !this.isRootStackGesturePopDisallowed()) {
|
|
36
|
+
return GestureJudgeResult.CONTINUE; // ③ 允许手势继续
|
|
37
|
+
}
|
|
38
|
+
return GestureJudgeResult.REJECT; // ④ 拒绝手势
|
|
39
|
+
})
|
|
40
|
+
.gesture(
|
|
41
|
+
PanGesture({ direction: this.from ? PanDirection.None : PanDirection.All })
|
|
42
|
+
// ...
|
|
43
|
+
)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 修复方式
|
|
47
|
+
|
|
48
|
+
1. gestureEnabled 默认值从 false 改为 true(与功能声明一致);2. 添加 onGestureRecognizerJudgeBegin 仲裁回调,在手势开关开启且允许侧滑时返回 CONTINUE,否则返回 REJECT 避免冲突。
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# KI-011 react-native-spring-scrollview:手势重复绑定崩溃
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-08` · `verified: diff` · `source: dtse` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-spring-scrollview/pull/38(merged,2 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-spring-scrollview-38.md](../pr-info/rntpc_react-native-spring-scrollview-38.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
线上 crash,美团管家 app——SpringScrollView 崩溃,根因疑似手势重复绑定到同一节点。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
init() 方法中调用 registerPanGesture() 无防重入保护,当 init() 被多次调用时(如组件重建),手势被重复绑定到同一节点导致崩溃。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前,C++ 层)
|
|
16
|
+
|
|
17
|
+
```cpp
|
|
18
|
+
// SpringScrollViewNode.cpp — init() 中无条件注册手势
|
|
19
|
+
void SpringScrollViewNode::init() {
|
|
20
|
+
if (this->isInitialContentOffset) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
this->registerPanGesture(); // ← 无防重入,多次 init 会重复绑定手势
|
|
24
|
+
// ...
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 正确代码(修复后)
|
|
29
|
+
|
|
30
|
+
```cpp
|
|
31
|
+
// SpringScrollViewNode.h — ① 添加防重入标志
|
|
32
|
+
bool isPanGestureRegistered = false;
|
|
33
|
+
|
|
34
|
+
// SpringScrollViewNode.cpp — ② 注册前检查标志
|
|
35
|
+
void SpringScrollViewNode::init() {
|
|
36
|
+
if (this->isInitialContentOffset) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
if (!this->isPanGestureRegistered) { // ③ 仅首次注册
|
|
40
|
+
this->isPanGestureRegistered = true;
|
|
41
|
+
this->registerPanGesture();
|
|
42
|
+
}
|
|
43
|
+
// ...
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## 修复方式
|
|
48
|
+
|
|
49
|
+
引入 isPanGestureRegistered 标志位防止手势重复绑定:init() 中注册手势前检查标志,首次注册后置 true,后续 init() 调用跳过注册。
|
package/vendor/BadCase/rn/cases/KI-012-qr-camera/346/250/252/345/261/217/351/200/202/351/205/215.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# KI-012 react-native-qr-decode-image-camera:Pura X Max 横屏展示不正确
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-09` · `verified: diff` · `source: community-issue` · `severity: medium` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-qr-decode-image-camera/pull/37(merged,2 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-qr-decode-image-camera-37.md](../pr-info/rntpc_react-native-qr-decode-image-camera-37.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
react-native-qr-decode-image-camera 库在 Pura X Max 上横屏状态下相机视图向下偏移,展示不正确。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
相机组件使用固定 aspectRatio(3/4)和固定定位,未检测横竖屏状态动态调整布局——横屏时 aspectRatio 不再适用,提示文字固定 bottom 定位导致在横屏时位置错误。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// Camera.tsx — ① 固定 3:4 宽高比
|
|
19
|
+
camera: {
|
|
20
|
+
width: '100%',
|
|
21
|
+
aspectRatio: 3 / 4, // ← 横屏时比例不适用
|
|
22
|
+
},
|
|
23
|
+
|
|
24
|
+
// QRScannerView.js — ② 提示文字固定 bottom 定位
|
|
25
|
+
<View style={{ position: 'absolute', bottom: this.props.hintTextPosition }}>
|
|
26
|
+
<Text style={[this.props.hintTextStyle, { top: this.props.finderY, left: this.props.finderX }]}>
|
|
27
|
+
{this.props.hintText}
|
|
28
|
+
</Text>
|
|
29
|
+
</View>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## 正确代码(修复后)
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
// Camera.tsx — ① 改用 flex 自适应
|
|
36
|
+
camera: {
|
|
37
|
+
flex: 1, // 自适应横竖屏
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
// QRScannerView.js — ② 检测横竖屏状态
|
|
41
|
+
const { width, height } = Dimensions.get('window');
|
|
42
|
+
this.state = { isLandscape: width > height };
|
|
43
|
+
|
|
44
|
+
// ③ 根据横竖屏切换定位
|
|
45
|
+
<View style={{
|
|
46
|
+
position: 'absolute',
|
|
47
|
+
...(this.state.isLandscape
|
|
48
|
+
? { top: this.getBottomMaskHeight() - this.props.finderY + 10, left: 0, right: 0, alignItems: 'center' }
|
|
49
|
+
: { bottom: this.props.hintTextPosition })
|
|
50
|
+
}}>
|
|
51
|
+
<Text style={[this.props.hintTextStyle, !this.state.isLandscape ? { top: this.props.finderY, left: this.props.finderX } : {}]}>
|
|
52
|
+
{this.props.hintText}
|
|
53
|
+
</Text>
|
|
54
|
+
</View>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## 修复方式
|
|
58
|
+
|
|
59
|
+
1. 相机组件从固定 aspectRatio 改为 flex: 1 自适应;2. 通过 Dimensions.get('window') 检测横竖屏(width > height);3. 提示文字叠加层根据 isLandscape 状态切换 top/bottom 定位。
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# KI-013 react-native-webview:深色模式先闪白再变黑
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-10` · `verified: diff` · `source: dtse` · `severity: medium` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-webview/pull/112(merged,1 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-webview-112.md](../pr-info/rntpc_react-native-webview-112.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
RNCWebView 源码中深色模式时加了一个白背景,导致先闪一下白背景再变黑。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
深色模式(forceDarkOn)下 WebView 背景色取值错误——深色模式应使用 Color.Black 但错误使用了 Color.White,导致 WebView 先渲染白色背景再切换为深色。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// RNCWebView.ets — 深色模式用白色背景
|
|
19
|
+
.backgroundColor(BaseOperate.getColorMode(this.ctx.uiAbilityContext,
|
|
20
|
+
this.descriptorWrapper.rawProps.forceDarkOn) === WebDarkMode.On
|
|
21
|
+
? Color.White // ← 深色模式用白色,错误
|
|
22
|
+
: Color.Transparent)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## 正确代码(修复后)
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
// RNCWebView.ets — ① 深色模式用黑色背景
|
|
29
|
+
.backgroundColor(BaseOperate.getColorMode(this.ctx.uiAbilityContext,
|
|
30
|
+
this.descriptorWrapper.rawProps.forceDarkOn) === WebDarkMode.On
|
|
31
|
+
? Color.Black // ② 深色模式用黑色,正确
|
|
32
|
+
: Color.Transparent)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## 修复方式
|
|
36
|
+
|
|
37
|
+
深色模式分支中 backgroundColor 从 Color.White 改为 Color.Black,使 WebView 初始背景色与深色主题一致,消除白色闪烁。
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# KI-014 react-native-amap-geolocation:onLocationError 未实现
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-11` · `verified: diff` · `source: community-issue` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-amap-geolocation/pull/27(merged,48 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-amap-geolocation-27.md](../pr-info/rntpc_react-native-amap-geolocation-27.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
react-native-amap-geolocation 的 onLocationError 没实现——用户传入 onLocationError 回调但错误发生时无任何反馈。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
JS 层声明了 onLocationError 回调 prop,但鸿蒙侧 ArkTS 实现中定位失败时未触发该回调,调用方无法感知错误——接口声明与实现之间存在断层。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前,ArkTS 层)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// AMapGeolocationModule.ts — 定位失败时无 onLocationError 触发
|
|
19
|
+
try {
|
|
20
|
+
// 定位逻辑...
|
|
21
|
+
} catch (e) {
|
|
22
|
+
// ← 无 onLocationError 回调触发,调用方无法感知错误
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 正确代码(修复后)
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// AMapGeolocationModule.ts — ① 定位失败时触发 onLocationError
|
|
30
|
+
try {
|
|
31
|
+
// 定位逻辑...
|
|
32
|
+
} catch (e) {
|
|
33
|
+
this.ctx.emit('onLocationError', { // ② 触发声明的错误回调
|
|
34
|
+
code: e.code,
|
|
35
|
+
message: e.message
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 修复方式
|
|
41
|
+
|
|
42
|
+
在定位失败的错误分支中补充 onLocationError 回调触发代码,使鸿蒙侧实现与 JS 层接口声明对齐。
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# KI-015 react-native-reanimated:动画 crash(滴滴线上 0.01%)
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-12` · `verified: diff` · `source: dtse` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-reanimated/pull/82(merged,1 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-reanimated-82.md](../pr-info/rntpc_react-native-reanimated-82.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
鸿蒙 RN 0.77.48 动画 crash,滴滴线上 crash rate 0.01%。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
ReanimatedModuleProxy 析构时 uiWorkletRuntime_ 先于 UIManager 析构——Hermes GC 在 workletRuntime 析构时回收了相同持有 ShadowNode::Shared 的 JSI 对象,但此时 ComponentDescriptorRegistry 已失效,触发 ~ShadowNodeFamily → ~InstanceHandle 崩溃。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```cpp
|
|
18
|
+
// ReanimatedModuleProxy.cpp — 析构顺序错误
|
|
19
|
+
ReanimatedModuleProxy::~ReanimatedModuleProxy() {
|
|
20
|
+
// ...
|
|
21
|
+
layoutAnimationsProxy_.reset();
|
|
22
|
+
// ← 无主动 GC;commitHook_/mountHook_/uiManager_ 直接 reset
|
|
23
|
+
commitHook_.reset();
|
|
24
|
+
mountHook_.reset();
|
|
25
|
+
uiManager_.reset();
|
|
26
|
+
uiWorkletRuntime_.reset(); // ← 此时 GC 回收 ShadowNode 时 ComponentDescriptorRegistry 已失效
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 正确代码(修复后)
|
|
31
|
+
|
|
32
|
+
```cpp
|
|
33
|
+
// ReanimatedModuleProxy.cpp — ① 在 runtime 析构前主动 GC
|
|
34
|
+
#if JS_RUNTIME_HERMES
|
|
35
|
+
if (uiWorkletRuntime_) {
|
|
36
|
+
try {
|
|
37
|
+
auto &uiRuntime = uiWorkletRuntime_->getJSIRuntime();
|
|
38
|
+
auto gc = uiRuntime.global().getPropertyAsFunction(uiRuntime, "gc");
|
|
39
|
+
gc.call(uiRuntime); // ② 回收持有 ShadowNode::Shared 的 JSI 对象
|
|
40
|
+
} catch (const std::exception &) {
|
|
41
|
+
// ③ gc() 失败不阻止后续析构
|
|
42
|
+
} catch (...) {}
|
|
43
|
+
}
|
|
44
|
+
#endif
|
|
45
|
+
// ④ GC 之后再注销 hooks,确保 ComponentDescriptorRegistry 仍存活
|
|
46
|
+
commitHook_.reset();
|
|
47
|
+
mountHook_.reset();
|
|
48
|
+
uiManager_.reset();
|
|
49
|
+
uiWorkletRuntime_.reset(); // ⑤ 最后 reset runtime
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## 修复方式
|
|
53
|
+
|
|
54
|
+
调整析构顺序:在 uiWorkletRuntime_.reset() 之前主动调用 Hermes gc() 回收持有 ShadowNode::Shared 的 JSI 对象(此时 UIManager 仍存活),GC 后再 reset hooks/UIManager,最后 reset runtime;GC 调用有 try-catch 保护。
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# KI-016 react-native-fs:read 接口无法读取非文本文件
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-13` · `verified: diff` · `source: community-issue` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-fs/pull/38(merged,24 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-fs-38.md](../pr-info/rntpc_react-native-fs-38.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
react-native-fs 的 read 接口以前只能读取文本文件,无法读取其他格式文件。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
read 接口底层使用了 readText API,而 readText 仅支持文本编码,二进制文件(图片/音频等)读取时解码失败;且文件关闭逻辑不在 finally 块中,异常时 fd 泄漏。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// FsTurboModule.ts — read 使用 readText
|
|
19
|
+
read(path: string, length: number, position: number): Promise<string> {
|
|
20
|
+
return new Promise((resolve, reject) => {
|
|
21
|
+
let readTextOption: ReadTextOptions = { offset: position, length, encoding: this.UTF_8 };
|
|
22
|
+
fs.readText(path, readTextOption, (err: BusinessError, str: string) => { // ← 仅支持文本
|
|
23
|
+
// ...
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// readFile 中文件关闭不在 finally 块
|
|
29
|
+
let file = fs.openSync(path);
|
|
30
|
+
// ...读取循环...
|
|
31
|
+
fs.closeSync(file); // ← 异常时跳过,fd 泄漏
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 正确代码(修复后)
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// FsTurboModule.ts — ① read 改用 readSync(通用二进制读取)
|
|
38
|
+
read(path: string, length: number, position: number): Promise<string> {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
let file: fs.File | null = null;
|
|
41
|
+
try {
|
|
42
|
+
file = fs.openSync(path);
|
|
43
|
+
// ② 用 readSync 循环读取二进制内容
|
|
44
|
+
// ...
|
|
45
|
+
} catch (e) {
|
|
46
|
+
reject(e);
|
|
47
|
+
} finally { // ③ 文件关闭转移到 finally 块
|
|
48
|
+
if (file) {
|
|
49
|
+
try { fs.closeSync(file); } catch (closeErr) { /* log */ }
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 修复方式
|
|
57
|
+
|
|
58
|
+
1. read 接口底层从 readText 改为 readSync(通用二进制读取);2. 文件关闭逻辑从 try 块转移到 finally 块,确保异常时也关闭 fd。
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# KI-017 react-native-blob-util:字符串参数被错误转为文件流
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-13` · `verified: diff` · `source: community-issue` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-blob-util/pull/23(merged,1 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-blob-util-23.md](../pr-info/rntpc_react-native-blob-util-23.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
使用 react-native-blob-util 调用接口传递参数时,默认把 value 为 string 字符数字的参数(如 expectedQuota)转换成文件流形式传递给服务端,导致服务端报错。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
HTTP 请求体组装时(getABData 方法),当 data 为非 path 路径时使用 `buffer.alloc(data.length, data, 'base64')` 将其转化为二进制数据,字符串参数被错误地以 base64 编码为二进制流,而非以 utf-8 编码为文本。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// ReactNativeBlobUtilReq.ts — 非 path 数据错误地 base64 编码
|
|
19
|
+
if (fs.类型判断) {
|
|
20
|
+
// path 文件读取...
|
|
21
|
+
} else {
|
|
22
|
+
buf = buffer.alloc(data.length, data, 'base64').buffer; // ← 字符串被 base64 编码为二进制流
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 正确代码(修复后)
|
|
27
|
+
|
|
28
|
+
```typescript
|
|
29
|
+
// ReactNativeBlobUtilReq.ts — ① 非 path 数据用 utf-8 编码
|
|
30
|
+
if (fs.类型判断) {
|
|
31
|
+
// path 文件读取...
|
|
32
|
+
} else {
|
|
33
|
+
buf = buffer.from(data, 'utf-8').buffer; // ② 字符串用 utf-8 编码,与上游保持一致
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 修复方式
|
|
38
|
+
|
|
39
|
+
HTTP 请求体组装时,非文件路径的字符串参数从 `buffer.alloc(data.length, data, 'base64')` 改为 `buffer.from(data, 'utf-8')`,与上游一致使用 utf-8 编码,避免字符串参数被误转为二进制文件流。
|
package/vendor/BadCase/rn/cases/KI-018-modal/345/274/271/347/252/227/351/227/252/347/203/201.md
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# KI-018 react-native-modal:弹窗先闪一下
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-14` · `verified: diff` · `source: dtse` · `severity: medium` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-modal/pull/20(merged,3 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-modal-20.md](../pr-info/rntpc_react-native-modal-20.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
RN 工程中拉起弹窗,弹窗会先闪一下——升级到 rnoh 新框架后出现。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
弹窗打开时 animationValue 保留了上一次动画的终值(1.0),setAnimation 基于当前 animationValue 创建 animationStyle 时 content 瞬间显示在最终位置(一帧闪烁),然后 startAnimation 才重置 animationValue 到 0。同时 backdrop 使用 ref.transitionTo 在新框架下不兼容。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
// modal.tsx — ① animationValue 未重置就 setAnimation
|
|
19
|
+
this.contentRef.setAnimation(this.animationIn, () => { /* ... */ });
|
|
20
|
+
// ② backdrop 使用 ref.transitionTo(新框架不兼容)
|
|
21
|
+
if (this.backdropRef) {
|
|
22
|
+
this.backdropRef.transitionTo({ opacity: this.props.backdropOpacity }, timing);
|
|
23
|
+
}
|
|
24
|
+
// ③ showContent 初始为 true,内容立即显示
|
|
25
|
+
state = { showContent: true };
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 正确代码(修复后)
|
|
29
|
+
|
|
30
|
+
```tsx
|
|
31
|
+
// ① 先 stopAnimation + setValue(0) 再 setAnimation
|
|
32
|
+
this.contentRef.stopAnimation();
|
|
33
|
+
if (this.contentRef.state && this.contentRef.state.animationValue) {
|
|
34
|
+
this.contentRef.state.animationValue.setValue(0);
|
|
35
|
+
}
|
|
36
|
+
// ② 用 requestAnimationFrame 延迟 setAnimation
|
|
37
|
+
const rafId = requestAnimationFrame(() => {
|
|
38
|
+
this.contentRef.setAnimation(this.animationIn, () => { /* ... */ });
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// ③ backdrop 改用 Animated.Value 驱动
|
|
42
|
+
this.backdropAnimated = new Animated.Value(0);
|
|
43
|
+
Animated.timing(this.backdropAnimated, { toValue: opacity, duration, useNativeDriver }).start();
|
|
44
|
+
|
|
45
|
+
// ④ animationReady 控制渲染时机
|
|
46
|
+
state = { showContent: false, animationReady: false };
|
|
47
|
+
// ⑤ 卸载时清理 pendingRAF/pendingTimeout/stopAnimation
|
|
48
|
+
this._pendingRAF.forEach(id => cancelAnimationFrame(id));
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 修复方式
|
|
52
|
+
|
|
53
|
+
1. setAnimation 前先 stopAnimation + setValue(0) 重置动画值;2. 用 requestAnimationFrame 延迟 setAnimation 确保重置生效;3. backdrop 从 ref.transitionTo 改为 Animated.Value 驱动;4. 引入 animationReady 标志在动画初始化完成前阻止内容渲染;5. 组件卸载时清理所有 pending 动画资源。
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# KI-019 react-native-code-push:restartApp 在 ON_NEXT_RESTART 模式下失效
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-15` · `verified: diff` · `source: community-issue` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-code-push/pull/17(merged,76 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-code-push-17.md](../pr-info/rntpc_react-native-code-push-17.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
更新流程是先使用 ON_NEXT_RESTART 的 installMode 调用 CodePush.sync 方法,然后再视情况调用 CodePush.allowRestart()、CodePush.restartApp() 来重启 RN。但上面流程在 iOS 和安卓是正常的,在鸿蒙上无法工作,因为 this.installMode 是个属性,在调用 restartApp 的时候还是 -1。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
installMode 状态标志位在 restartApp 调用时未及时复位——ON_NEXT_RESTART(1) 模式下 restartApp 完成后 installMode 仍为 1,后续 restartApp 条件判断 `installMode === 0 || installMode === -1` 不满足,导致重启失效。同时 allow() 未设置 _allowed 标志,disallow 后 allow 无法恢复。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// CodePushNativeModule.ts — ① restartApp 条件判断遗漏 ON_NEXT_RESTART
|
|
19
|
+
if (this.installMode === 0 || this.installMode === -1) {
|
|
20
|
+
this.ctx.devToolsController.eventEmitter.emit("RELOAD", { reason: 'HotReload2' })
|
|
21
|
+
}
|
|
22
|
+
// ← ON_NEXT_RESTART(1) 分支未处理,installMode 未复位
|
|
23
|
+
|
|
24
|
+
// ② allow() 未设置 _allowed 标志
|
|
25
|
+
async allow() {
|
|
26
|
+
return new Promise((resolve) => {
|
|
27
|
+
Logger.info(TAG, "Re-allowing restarts");
|
|
28
|
+
// ← 未设置 this._allowed = true
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// ③ restartAppInternal 无防重入保护
|
|
33
|
+
restartAppInternal(onlyIfUpdateIsPending: boolean) {
|
|
34
|
+
this.loadBundle(); // ← 无 _restartInProgress 检查
|
|
35
|
+
}
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 正确代码(修复后)
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
// ① ON_NEXT_RESTART 分支复位 installMode
|
|
42
|
+
if (this.installMode === 1) {
|
|
43
|
+
this.installMode = -1; // ② 复位为 -1
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ③ allow() 设置 _allowed 标志并处理排队
|
|
47
|
+
async allow() {
|
|
48
|
+
this._allowed = true;
|
|
49
|
+
if (this._restartQueue.length > 0) {
|
|
50
|
+
let buf = this._restartQueue[0];
|
|
51
|
+
this._restartQueue.splice(0, 1);
|
|
52
|
+
this.restartAppInternal(buf);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ④ restartAppInternal 防重入 + 排队机制
|
|
57
|
+
restartAppInternal(onlyIfUpdateIsPending: boolean) {
|
|
58
|
+
if (this._restartInProgress) { // ⑤ 防重入
|
|
59
|
+
this._restartQueue.push(onlyIfUpdateIsPending);
|
|
60
|
+
return;
|
|
61
|
+
} else if (!this._allowed) { // ⑥ 允许检查
|
|
62
|
+
this._restartQueue.push(onlyIfUpdateIsPending);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
this._restartInProgress = true;
|
|
66
|
+
// ...执行重启...
|
|
67
|
+
this._restartInProgress = false;
|
|
68
|
+
// ⑦ 处理排队请求
|
|
69
|
+
if (this._restartQueue.length > 0) {
|
|
70
|
+
let buf = this._restartQueue[0];
|
|
71
|
+
this._restartQueue.splice(0, 1);
|
|
72
|
+
this.restartAppInternal(buf);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 修复方式
|
|
78
|
+
|
|
79
|
+
1. ON_NEXT_RESTART 模式完成后复位 installMode 为 -1;2. allow() 设置 _allowed = true 并处理排队请求;3. restartAppInternal 增加防重入保护(_restartInProgress)和排队机制(_restartQueue);4. disallow() 设置 _allowed = false。
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# KI-020 react-native-netinfo:打印 MAC 地址和 IP 地址
|
|
2
|
+
|
|
3
|
+
- **元数据**: `rule: R-16` · `verified: diff` · `source: community-issue` · `severity: high` · `status: draft`
|
|
4
|
+
- **PR**: https://gitcode.com/CPF-RN/rntpc_react-native-netinfo/pull/31(merged,1 文件)
|
|
5
|
+
- **diff 材料**: [../pr-info/rntpc_react-native-netinfo-31.md](../pr-info/rntpc_react-native-netinfo-31.md)
|
|
6
|
+
|
|
7
|
+
## 现象
|
|
8
|
+
|
|
9
|
+
@react-native-ohos/netinfo 三方库打印敏感信息——RN 侧调用 NetInfoTurboModule 里面 getCurrentState 会打印 MAC 地址和 IP 地址,安全测试不过。
|
|
10
|
+
|
|
11
|
+
## 根因
|
|
12
|
+
|
|
13
|
+
日志中直接 JSON.stringify 打印了网络连接事件数据(netConnection 回调数据),其中包含 MAC 地址、IP 地址等敏感信息,安全扫描检测到敏感信息泄露。
|
|
14
|
+
|
|
15
|
+
## 错误代码(修复前)
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
// NetInfoTurboModule.ts — 多处打印敏感数据
|
|
19
|
+
configure(config: Details): void {
|
|
20
|
+
Logger.info('configure,' + JSON.stringify(config)); // ← 打印配置信息
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getCurrentState(requestedInterface?: string): Promise<NetInfoState> {
|
|
24
|
+
// ...
|
|
25
|
+
Logger.info('events,' + JSON.stringify(events)); // ← 打印网络状态含 MAC/IP
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
this.netConnection.register((data) => {
|
|
29
|
+
Logger.info('netConnection,' + JSON.stringify(data)); // ← 打印连接数据
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
this.netConnection.on('netAvailable', (data) => {
|
|
33
|
+
Logger.info('netAvailable,' + JSON.stringify(data)); // ← 打印网络可用事件
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## 正确代码(修复后)
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
// NetInfoTurboModule.ts — ① 删除所有敏感日志
|
|
41
|
+
configure(config: Details): void {
|
|
42
|
+
// ② 不再打印 config
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getCurrentState(requestedInterface?: string): Promise<NetInfoState> {
|
|
46
|
+
// ③ 不再打印 events
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
this.netConnection.register((data) => {
|
|
50
|
+
// ④ 不再打印 netConnection 数据
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
this.netConnection.on('netAvailable', (data) => {
|
|
54
|
+
// ⑤ 不再打印 netAvailable 数据
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## 修复方式
|
|
59
|
+
|
|
60
|
+
删除所有打印网络连接原始数据的日志语句(Logger.info),包括 configure、getCurrentState、netConnection.register、netAvailable 等回调中的 JSON.stringify 日志。
|