@skyramp/mcp 0.4.1 → 0.4.2-rc.2
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/build/commands/localDevTestChangesCommand.js +2 -1
- package/build/commands/recommendTestsAndExecuteCommand.js +15 -7
- package/build/commands/testThisEndpointCommand.js +35 -6
- package/build/execution/wrapperConfig.d.ts +56 -0
- package/build/execution/wrapperConfig.js +155 -0
- package/build/index.js +40 -10
- package/build/playwright/blueprintDigest.js +28 -7
- package/build/playwright/registerPlaywrightTools.js +47 -28
- package/build/playwright/traceExportStore.d.ts +22 -0
- package/build/playwright/traceExportStore.js +81 -0
- package/build/playwright/traceRecordingPrompt.js +11 -3
- package/build/prompts/code-reuse.js +118 -49
- package/build/prompts/fix-error-prompt.d.ts +9 -1
- package/build/prompts/fix-error-prompt.js +31 -28
- package/build/prompts/local-dev/local-dev-plan.d.ts +3 -0
- package/build/prompts/local-dev/local-dev-plan.js +8 -23
- package/build/prompts/local-dev/local-dev-prompts.d.ts +1 -1
- package/build/prompts/local-dev/local-dev-prompts.js +31 -4
- package/build/prompts/modularization/integration-test-modularization.js +13 -6
- package/build/prompts/modularization/ui-test-modularization.js +1 -1
- package/build/prompts/personas.js +1 -1
- package/build/prompts/pom-aware-code-reuse.js +7 -9
- package/build/prompts/reuse-hand-off.d.ts +64 -0
- package/build/prompts/reuse-hand-off.js +130 -0
- package/build/prompts/shared-helper-policy.d.ts +124 -2
- package/build/prompts/shared-helper-policy.js +178 -12
- package/build/prompts/startTraceCollectionPrompts.js +1 -1
- package/build/prompts/sut-setup/modes/adaptWorkflowPrompt.js +7 -8
- package/build/prompts/sut-setup/modes/dockerComposePrompt.js +1 -1
- package/build/prompts/sut-setup/shared.d.ts +4 -1
- package/build/prompts/sut-setup/shared.js +6 -4
- package/build/prompts/test-maintenance/actionsInstructions.d.ts +19 -11
- package/build/prompts/test-maintenance/actionsInstructions.js +47 -26
- package/build/prompts/test-maintenance/drift-analysis-prompt.d.ts +16 -8
- package/build/prompts/test-maintenance/drift-analysis-prompt.js +93 -38
- package/build/prompts/test-maintenance/driftAnalysisSections.js +5 -3
- package/build/prompts/test-maintenance/driftAnalysisShared.js +4 -2
- package/build/prompts/test-maintenance/uiDriftAnalysisSections.js +8 -5
- package/build/prompts/test-recommendation/recommendationSections.js +19 -8
- package/build/prompts/test-recommendation/recommendationShared.d.ts +1 -1
- package/build/prompts/test-recommendation/recommendationShared.js +0 -1
- package/build/prompts/test-recommendation/registerRecommendTestsPrompt.js +5 -2
- package/build/prompts/test-recommendation/test-recommendation-prompt.js +10 -7
- package/build/prompts/testbot/testbot-prompts.js +133 -63
- package/build/recommendation/answers.js +18 -9
- package/build/recommendation/pullRequestText.js +1 -1
- package/build/recommendation/registerPlan.js +31 -17
- package/build/recommendation/subjectStep.d.ts +8 -10
- package/build/recommendation/subjectStep.js +17 -16
- package/build/recommendation/types.d.ts +71 -17
- package/build/recommendation/types.js +9 -15
- package/build/recommendation/verifierContracts.d.ts +7 -3
- package/build/recommendation/verifierContracts.js +8 -4
- package/build/recommendation/verifiers/changedFile.js +11 -13
- package/build/recommendation/verifiers/citedPath.d.ts +8 -0
- package/build/recommendation/verifiers/citedPath.js +16 -2
- package/build/recommendation/verifiers/coverage.d.ts +2 -2
- package/build/recommendation/verifiers/coverage.js +190 -134
- package/build/recommendation/verifiers/defects.js +56 -16
- package/build/recommendation/verifiers/deliveredMatchesPlan.d.ts +7 -1
- package/build/recommendation/verifiers/deliveredMatchesPlan.js +28 -14
- package/build/recommendation/verifiers/endpointGrounded.js +14 -8
- package/build/recommendation/verifiers/existingCoverage.d.ts +6 -0
- package/build/recommendation/verifiers/existingCoverage.js +30 -21
- package/build/recommendation/verifiers/expectedOutcome.js +17 -8
- package/build/recommendation/verifiers/expectedValueSourced.js +54 -43
- package/build/recommendation/verifiers/issueTraceability.d.ts +5 -0
- package/build/recommendation/verifiers/issueTraceability.js +64 -7
- package/build/recommendation/verifiers/removedElementGuarded.js +19 -11
- package/build/recommendation/verifiers/reportedCategory.js +9 -4
- package/build/recommendation/verifiers/requirementSourced.js +34 -21
- package/build/recommendation/verifiers/screenRoute.js +15 -10
- package/build/recommendation/verifiers/statedDifference.js +15 -8
- package/build/recommendation/verifiers/uiElementGrounded.js +50 -16
- package/build/resources/analysisResources.js +7 -3
- package/build/resources/progressResource.js +4 -2
- package/build/resources/sutSetupResource.js +20 -2
- package/build/resources/testbotResource.js +19 -1
- package/build/services/AnalyticsService.js +3 -1
- package/build/services/ScenarioGenerationService.js +5 -5
- package/build/services/TestDiscoveryService.js +53 -9
- package/build/services/TestExecutionService.js +63 -21
- package/build/services/TestGenerationService.d.ts +1 -1
- package/build/services/TestGenerationService.js +43 -24
- package/build/skills/enhanceAssertionsSkill.d.ts +45 -0
- package/build/skills/enhanceAssertionsSkill.js +103 -0
- package/build/skills/fixTestImportErrorsSkill.d.ts +2 -2
- package/build/skills/fixTestImportErrorsSkill.js +2 -2
- package/build/skills/runTestSkill.d.ts +6 -0
- package/build/skills/runTestSkill.js +17 -0
- package/build/skills/skillFiles.d.ts +38 -0
- package/build/skills/skillFiles.js +94 -0
- package/build/skills/validateAssertionAlignmentSkill.d.ts +34 -0
- package/build/skills/validateAssertionAlignmentSkill.js +59 -0
- package/build/tool-phases.js +4 -1
- package/build/tools/auth/loginTool.js +3 -1
- package/build/tools/auth/logoutTool.js +3 -1
- package/build/tools/budgetExcuse.d.ts +15 -0
- package/build/tools/budgetExcuse.js +113 -0
- package/build/tools/code-refactor/alignAssertionsTool.d.ts +2 -0
- package/build/tools/code-refactor/alignAssertionsTool.js +51 -0
- package/build/tools/code-refactor/assertion-state.d.ts +1 -1
- package/build/tools/code-refactor/assertion-state.js +1 -1
- package/build/tools/code-refactor/assertionOperations.d.ts +44 -0
- package/build/tools/code-refactor/assertionOperations.js +82 -0
- package/build/tools/code-refactor/assertionSkillTools.d.ts +3 -0
- package/build/tools/code-refactor/assertionSkillTools.js +86 -0
- package/build/tools/code-refactor/codeReuseTool.js +27 -3
- package/build/tools/code-refactor/enhanceAssertionsTool.js +19 -83
- package/build/tools/code-refactor/gate-markers.d.ts +51 -0
- package/build/tools/code-refactor/gate-markers.js +95 -0
- package/build/tools/code-refactor/retrofit-state.d.ts +3 -1
- package/build/tools/code-refactor/retrofit-state.js +44 -2
- package/build/tools/code-refactor/reuse-outcome.d.ts +23 -1
- package/build/tools/code-refactor/reuse-outcome.js +36 -13
- package/build/tools/code-refactor/reuse-state.d.ts +90 -16
- package/build/tools/code-refactor/reuse-state.js +191 -61
- package/build/tools/code-refactor/utils-verify-gates.d.ts +4 -0
- package/build/tools/code-refactor/utils-verify-gates.js +269 -30
- package/build/tools/code-refactor/verify-gates.d.ts +15 -1
- package/build/tools/code-refactor/verify-gates.js +36 -4
- package/build/tools/enrichTestWithMocksTool.d.ts +1 -1
- package/build/tools/enrichTestWithMocksTool.js +9 -5
- package/build/tools/executeSkyrampTestTool.d.ts +118 -48
- package/build/tools/executeSkyrampTestTool.js +998 -372
- package/build/tools/execution-video-state.js +1 -1
- package/build/tools/fixErrorTool.js +5 -6
- package/build/tools/generate-tests/batchMockGenerationTool.js +1 -1
- package/build/tools/generate-tests/generateBatchScenarioRestTool.js +114 -73
- package/build/tools/generate-tests/generateContractRestTool.js +34 -16
- package/build/tools/generate-tests/generateE2ERestTool.d.ts +1 -0
- package/build/tools/generate-tests/generateE2ERestTool.js +9 -1
- package/build/tools/generate-tests/generateIntegrationRestTool.js +22 -7
- package/build/tools/generate-tests/generateMockRestTool.js +3 -1
- package/build/tools/generate-tests/generateUIRestTool.d.ts +2 -0
- package/build/tools/generate-tests/generateUIRestTool.js +11 -2
- package/build/tools/generate-tests/loadTestSchema.js +1 -3
- package/build/tools/generate-tests/planGuard.js +6 -3
- package/build/tools/generate-tests/scenarioFileIdentity.js +4 -1
- package/build/tools/generate-tests/scenarioLint.js +17 -5
- package/build/tools/generate-tests/trace-reuse-guard.js +5 -2
- package/build/tools/generateEnrichedIntegrationTestTool.js +9 -3
- package/build/tools/one-click/oneClickTool.js +3 -1
- package/build/tools/preflightMockCheckTool.js +23 -7
- package/build/tools/submitReportTool.d.ts +51 -12
- package/build/tools/submitReportTool.js +988 -161
- package/build/tools/test-management/actionsTool.js +241 -51
- package/build/tools/test-management/analyzeChangesTool.d.ts +8 -9
- package/build/tools/test-management/analyzeChangesTool.js +127 -68
- package/build/tools/test-management/analyzeTestHealthTool.d.ts +0 -11
- package/build/tools/test-management/analyzeTestHealthTool.js +42 -76
- package/build/tools/test-management/registerTestPlanTool.d.ts +44 -34
- package/build/tools/test-management/registerTestPlanTool.js +255 -111
- package/build/tools/test-management/resolveScreenTool.js +33 -9
- package/build/tools/test-management/testsOwedBeforeRun.d.ts +28 -0
- package/build/tools/test-management/testsOwedBeforeRun.js +53 -0
- package/build/tools/trace/startTraceCollectionTool.js +3 -1
- package/build/tools/trace/stopTraceCollectionTool.js +42 -6
- package/build/tools/verifyTestDependenciesTool.d.ts +3 -0
- package/build/tools/verifyTestDependenciesTool.js +54 -0
- package/build/tools/workspace/initScanWorkspaceTool.js +9 -3
- package/build/tools/workspace/initializeWorkspaceTool.js +3 -1
- package/build/types/AssertionOutcome.d.ts +1 -1
- package/build/types/EnhanceType.d.ts +6 -0
- package/build/types/EnhanceType.js +1 -0
- package/build/types/RepositoryAnalysis.d.ts +32 -72
- package/build/types/ReuseOutcome.d.ts +100 -7
- package/build/types/ReuseOutcome.js +16 -0
- package/build/types/StepMethod.js +20 -6
- package/build/types/TestAnalysis.d.ts +10 -2
- package/build/types/TestExecution.d.ts +45 -0
- package/build/types/TestRecommendation.d.ts +1 -1
- package/build/types/TestRecommendation.js +4 -1
- package/build/types/TestTypes.d.ts +16 -0
- package/build/types/TestTypes.js +40 -3
- package/build/types/TestbotPromptOptions.d.ts +9 -1
- package/build/types/TestbotReport.d.ts +45 -9
- package/build/utils/AnalysisStateManager.d.ts +137 -34
- package/build/utils/AnalysisStateManager.js +228 -44
- package/build/utils/assertion-verify/api-shared-lints.js +34 -16
- package/build/utils/assertion-verify/metrics.js +39 -6
- package/build/utils/assertion-verify/ui-lints.js +4 -2
- package/build/utils/branchDiff.js +47 -12
- package/build/utils/canonicalJson.js +3 -1
- package/build/utils/connectionErrors.d.ts +10 -0
- package/build/utils/connectionErrors.js +10 -0
- package/build/utils/dartRouteExtractor.js +36 -7
- package/build/utils/fixAttempts.d.ts +26 -0
- package/build/utils/fixAttempts.js +109 -0
- package/build/utils/frontendSelectors.js +23 -4
- package/build/utils/generatedTestRecord.d.ts +19 -0
- package/build/utils/generatedTestRecord.js +61 -0
- package/build/utils/gitStaging.js +7 -2
- package/build/utils/initAgent.js +26 -6
- package/build/utils/language-helper.js +60 -45
- package/build/utils/pathMatching.js +2 -1
- package/build/utils/pathSignatures.js +6 -2
- package/build/utils/planMatchKeys.d.ts +2 -2
- package/build/utils/planMatchKeys.js +20 -14
- package/build/utils/pom-catalog-parse.js +7 -2
- package/build/utils/pom-scope/import-expansion.js +6 -1
- package/build/utils/pom-scope/index.js +50 -12
- package/build/utils/pom-scope/scoring.js +13 -3
- package/build/utils/pom-scope/selector-extractor.js +16 -3
- package/build/utils/pom-scope/strip.d.ts +8 -0
- package/build/utils/pom-scope/strip.js +238 -0
- package/build/utils/pom-scope/testIdDiscovery.js +14 -2
- package/build/utils/pom-verify/__fixtures__/af-style/asset-list.page.d.ts +1 -1
- package/build/utils/pom-verify/__fixtures__/af-style/asset-list.page.js +4 -2
- package/build/utils/pom-verify/__fixtures__/af-style/report.iframe.page.js +3 -1
- package/build/utils/pom-verify/__fixtures__/af-style/workflow-footer.page.js +3 -1
- package/build/utils/pom-verify/bindings.js +5 -1
- package/build/utils/pom-verify/calls.js +9 -2
- package/build/utils/pom-verify/verify.js +27 -5
- package/build/utils/pr-comment-parser.js +20 -7
- package/build/utils/progress.d.ts +1 -1
- package/build/utils/progress.js +1 -1
- package/build/utils/proxy-terminal.d.ts +19 -1
- package/build/utils/proxy-terminal.js +346 -21
- package/build/utils/rebaselineSnapshots.d.ts +1 -1
- package/build/utils/rebaselineSnapshots.js +6 -16
- package/build/utils/removedUiElements.js +1 -1
- package/build/utils/reportLanguage.js +35 -7
- package/build/utils/reportVerification.d.ts +14 -8
- package/build/utils/reportVerification.js +19 -19
- package/build/utils/repositorySlug.d.ts +32 -0
- package/build/utils/repositorySlug.js +77 -0
- package/build/utils/reuseRouting.d.ts +10 -0
- package/build/utils/reuseRouting.js +21 -2
- package/build/utils/runContextGauge.d.ts +27 -0
- package/build/utils/runContextGauge.js +181 -0
- package/build/utils/runSerialized.d.ts +3 -0
- package/build/utils/runSerialized.js +39 -0
- package/build/utils/screenRoutes.js +74 -18
- package/build/utils/skyrampMdContent.d.ts +1 -1
- package/build/utils/skyrampMdContent.js +1 -1
- package/build/utils/skyrampSdkVersion.d.ts +9 -0
- package/build/utils/skyrampSdkVersion.js +16 -0
- package/build/utils/sourceRouteExtractor.js +13 -6
- package/build/utils/telemetry.d.ts +1 -0
- package/build/utils/telemetry.js +8 -5
- package/build/utils/testDependencyPolicy.d.ts +9 -0
- package/build/utils/testDependencyPolicy.js +809 -0
- package/build/utils/testExecutionRecord.d.ts +94 -0
- package/build/utils/testExecutionRecord.js +269 -0
- package/build/utils/testFileClassification.d.ts +8 -0
- package/build/utils/testFileClassification.js +39 -4
- package/build/utils/trace-parser.js +62 -14
- package/build/utils/urlPath.js +3 -1
- package/build/utils/utils-verify/action-key.d.ts +46 -0
- package/build/utils/utils-verify/action-key.js +120 -38
- package/build/utils/utils-verify/action-sites.d.ts +32 -0
- package/build/utils/utils-verify/action-sites.js +202 -0
- package/build/utils/utils-verify/allow.d.ts +122 -3
- package/build/utils/utils-verify/allow.js +146 -21
- package/build/utils/utils-verify/body-reach.d.ts +120 -0
- package/build/utils/utils-verify/body-reach.js +333 -0
- package/build/utils/utils-verify/call-sites.d.ts +31 -7
- package/build/utils/utils-verify/call-sites.js +80 -13
- package/build/utils/utils-verify/delivered-imports.d.ts +43 -0
- package/build/utils/utils-verify/delivered-imports.js +84 -0
- package/build/utils/utils-verify/fixed-sleep.d.ts +96 -0
- package/build/utils/utils-verify/fixed-sleep.js +461 -0
- package/build/utils/utils-verify/in-house.d.ts +93 -0
- package/build/utils/utils-verify/in-house.js +719 -0
- package/build/utils/utils-verify/incumbent.d.ts +3 -0
- package/build/utils/utils-verify/incumbent.js +75 -0
- package/build/utils/utils-verify/index.d.ts +2 -0
- package/build/utils/utils-verify/index.js +2 -0
- package/build/utils/utils-verify/language-spec.d.ts +51 -10
- package/build/utils/utils-verify/language-spec.js +232 -21
- package/build/utils/utils-verify/locate.d.ts +26 -0
- package/build/utils/utils-verify/locate.js +125 -23
- package/build/utils/utils-verify/module-name.d.ts +40 -0
- package/build/utils/utils-verify/module-name.js +98 -0
- package/build/utils/utils-verify/parse.d.ts +56 -7
- package/build/utils/utils-verify/parse.js +195 -40
- package/build/utils/utils-verify/retrofit-equivalence.d.ts +5 -0
- package/build/utils/utils-verify/retrofit-equivalence.js +4 -2
- package/build/utils/utils-verify/stage.d.ts +5 -0
- package/build/utils/utils-verify/stage.js +47 -2
- package/build/utils/utils-verify/status-once.d.ts +62 -0
- package/build/utils/utils-verify/status-once.js +207 -0
- package/build/utils/utils-verify/typecheck.d.ts +61 -0
- package/build/utils/utils-verify/typecheck.js +338 -0
- package/build/utils/utils-verify/verify.d.ts +79 -3
- package/build/utils/utils-verify/verify.js +531 -61
- package/build/utils/versions.d.ts +3 -3
- package/build/utils/versions.js +1 -1
- package/build/utils/workspaceAuth.js +107 -37
- package/build/workspace/queryParamResolution.js +11 -4
- package/build/workspace/workspace.d.ts +72 -52
- package/build/workspace/workspace.js +19 -15
- package/node_modules/playwright/ThirdPartyNotices.txt +19 -19
- package/node_modules/playwright/lib/mcp/skyramp/assertTool.js +8 -2
- package/node_modules/playwright/lib/mcp/skyramp/common/cssValue.js +87 -0
- package/node_modules/playwright/lib/mcp/skyramp/loadTraceTool.js +31 -0
- package/node_modules/playwright/lib/mcp/skyramp/skyRampImport.js +3 -0
- package/node_modules/playwright/lib/mcp/skyramp/traceRecordingBackend.js +181 -15
- package/node_modules/playwright/lib/mcp/test/skyRampExport.js +24 -0
- package/node_modules/playwright/lib/transform/babelBundleImpl.js +2353 -190
- package/node_modules/playwright/node_modules/playwright-core/ThirdPartyNotices.txt +62 -34
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/.package-lock.json +72 -41
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/@hono/node-server/dist/serve-static.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/@hono/node-server/dist/serve-static.mjs +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/@hono/node-server/package.json +2 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/README.md +16 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/index.js +4 -20
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/read.js +17 -17
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/json.js +60 -32
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/raw.js +3 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/text.js +3 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/types/urlencoded.js +16 -20
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/lib/utils.js +18 -16
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/LICENSE +22 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/README.md +71 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/node_modules/content-type/package.json +52 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/body-parser/package.json +23 -10
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/CHANGELOG.md +21 -14
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/isObject.d.ts +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/package.json +6 -7
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/es-object-atoms/tsconfig.json +1 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/index.js +266 -45
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/lib/schemes.js +9 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/lib/utils.js +396 -92
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/package.json +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/component-safe-serialization.test.js +163 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/equal.test.js +31 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/fixtures/uri-js-parse.json +2 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/ipv6-canonical.test.js +34 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/ipv6-validation.test.js +124 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/malformed-percent.test.js +77 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/malformed-urn.test.js +61 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/parse.test.js +7 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/query-fragment-normalization.test.js +33 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/reserved-path-normalization.test.js +109 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/scheme-validation.test.js +124 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/security-normalization.test.js +101 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/security.test.js +301 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/urn-full-input.test.js +29 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/fast-uri/test/websocket-query-preservation.test.js +24 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hasown/CHANGELOG.md +7 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hasown/index.d.ts +0 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hasown/package.json +4 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/client/client.js +30 -16
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/client/utils.js +4 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/context.js +32 -13
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/accepts/accepts.js +36 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/proxy/index.js +4 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/ssg/ssg.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/ssg/utils.js +30 -10
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/helper/streaming/sse.js +5 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/hono-base.js +10 -8
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/base.js +44 -23
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/components.js +25 -26
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/context.js +5 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/dom/render.js +2 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/dom/server.js +5 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/hooks/index.js +16 -13
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/intrinsic-element/components.js +3 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/jsx/streaming.js +4 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/cache/index.js +103 -8
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/compress/index.js +5 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/cors/index.js +17 -14
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/csrf/index.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/etag/digest.js +47 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/etag/index.js +7 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/jwk/jwk.js +9 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/jwt/jwt.js +9 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/language/language.js +10 -6
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/method-not-allowed/index.js +90 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/pretty-json/index.js +3 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +16 -7
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/request.js +20 -13
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/linear-router/router.js +7 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/pattern-router/router.js +3 -9
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/reg-exp-router/node.js +65 -59
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/reg-exp-router/router.js +71 -128
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/reg-exp-router/trie.js +14 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/trie-router/node.js +47 -70
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/trie-router/router.js +3 -11
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router/utils.js +27 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/router.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/accept.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/body.js +21 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/cookie.js +4 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/ipaddr.js +5 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/stream.js +12 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/cjs/utils/url.js +19 -11
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/client/client.js +30 -16
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/client/utils.js +4 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/context.js +32 -13
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/accepts/accepts.js +36 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/proxy/index.js +4 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/ssg/ssg.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/ssg/utils.js +30 -10
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/helper/streaming/sse.js +5 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/hono-base.js +10 -8
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/base.js +41 -23
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/components.js +26 -27
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/context.js +6 -6
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/dom/render.js +2 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/dom/server.js +5 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/hooks/index.js +16 -13
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/intrinsic-element/components.js +4 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/jsx/streaming.js +5 -6
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/cache/index.js +103 -8
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/compress/index.js +5 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/cors/index.js +17 -14
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/csrf/index.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/etag/digest.js +47 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/etag/index.js +7 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/jwk/jwk.js +9 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/jwt/jwt.js +9 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/language/language.js +10 -6
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/method-not-allowed/index.js +68 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/pretty-json/index.js +3 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +16 -7
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/request.js +21 -14
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/linear-router/router.js +7 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/pattern-router/router.js +3 -9
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/reg-exp-router/node.js +61 -58
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/reg-exp-router/router.js +77 -129
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/reg-exp-router/trie.js +14 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/trie-router/node.js +47 -70
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/trie-router/router.js +3 -11
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router/utils.js +5 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/router.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/client/types.d.ts +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/context.d.ts +6 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/hono-base.d.ts +4 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/base.d.ts +7 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/dom/index.d.ts +5 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/dom/intrinsic-element/components.d.ts +2 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/dom/server.d.ts +5 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/hooks/index.d.ts +8 -6
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/jsx/index.d.ts +5 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/cache/index.d.ts +6 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/combine/index.d.ts +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/cors/index.d.ts +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/jsx-renderer/index.d.ts +2 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/jwk/jwk.d.ts +2 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/jwt/jwt.d.ts +2 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/method-not-allowed/index.d.ts +49 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/middleware/secure-headers/permissions-policy.d.ts +3 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/reg-exp-router/node.d.ts +4 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/reg-exp-router/trie.d.ts +2 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/trie-router/node.d.ts +1 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/trie-router/router.d.ts +0 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router/utils.d.ts +1 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/router.d.ts +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/utils/headers.d.ts +2 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/types/utils/url.d.ts +5 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/accept.js +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/body.js +21 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/cookie.js +5 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/ipaddr.js +5 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/stream.js +12 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/dist/utils/url.js +17 -10
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/hono/package.json +11 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/README.md +173 -143
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/address-error.d.ts +11 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/address-error.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/common.d.ts +49 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/common.js +79 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv4.d.ts +78 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv4.js +119 -24
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv6.d.ts +151 -10
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv6.js +316 -90
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v4/constants.d.ts +12 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v4/constants.js +45 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v6/constants.d.ts +14 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v6/constants.js +50 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/ip-address/package.json +6 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/.github/THREAT_MODEL.md +3 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/CHANGELOG.md +26 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/README.md +19 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/dist/qs.js +25 -25
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/eslint.config.mjs +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/lib/parse.js +16 -6
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/lib/stringify.js +23 -8
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/lib/utils.js +57 -11
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/package.json +8 -7
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/test/parse.js +419 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/test/stringify.js +317 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/qs/test/utils.js +206 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/CHANGELOG.md +10 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/README.md +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/index.js +5 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/package.json +10 -10
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/side-channel/test/index.js +16 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/index.js +8 -18
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/LICENSE +22 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/README.md +71 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/dist/index.d.ts +46 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/dist/index.js +176 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/dist/index.js.map +1 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/node_modules/content-type/package.json +52 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/node_modules/type-is/package.json +9 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/mcp/package-lock.json +72 -41
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/.package-lock.json +6 -6
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/brace-expansion/README.md +23 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/brace-expansion/index.js +265 -86
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/brace-expansion/package.json +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/README.md +173 -143
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/address-error.d.ts +11 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/address-error.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/common.d.ts +49 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/common.js +79 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/common.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv4.d.ts +78 -5
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv4.js +119 -24
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv6.d.ts +151 -10
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv6.js +316 -90
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v4/constants.d.ts +12 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v4/constants.js +45 -2
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v4/constants.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v6/constants.d.ts +14 -0
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v6/constants.js +50 -3
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/node_modules/ip-address/package.json +6 -4
- package/node_modules/playwright/node_modules/playwright-core/bundles/utils/package-lock.json +6 -6
- package/node_modules/playwright/node_modules/playwright-core/lib/cli/program.js +18 -9
- package/node_modules/playwright/node_modules/playwright-core/lib/mcpBundleImpl/index.js +47 -47
- package/node_modules/playwright/node_modules/playwright-core/lib/server/codegen/skyramp/jsonlReader.js +3 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/server/recorder/recorderRunner.js +42 -0
- package/node_modules/playwright/node_modules/playwright-core/lib/utilsBundleImpl/index.js +121 -121
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/{index.B7KbSQcC.js → index.BAkLd5DX.js} +1 -1
- package/node_modules/playwright/node_modules/playwright-core/lib/vite/traceViewer/index.html +1 -1
- package/node_modules/playwright/node_modules/playwright-core/package.json +1 -1
- package/node_modules/playwright/node_modules/playwright-core/src/cli/program.ts +31 -9
- package/node_modules/playwright/node_modules/playwright-core/src/server/codegen/skyramp/jsonlReader.ts +1 -0
- package/node_modules/playwright/node_modules/playwright-core/src/server/recorder/recorderRunner.ts +57 -1
- package/node_modules/playwright/package.json +2 -2
- package/package.json +7 -6
- package/plugin/prompts/code-reuse/hand-off.md +30 -0
- package/plugin/prompts/generate-tests/generation.md +1 -1
- package/plugin/prompts/plan-tests.md +14 -14
- package/plugin/prompts/testbot-task1.md +2 -2
- package/plugin/skills/enhance-assertions/SKILL.md +25 -0
- package/plugin/skills/enhance-assertions/reference/contract.md +51 -0
- package/plugin/skills/enhance-assertions/reference/integration.md +58 -0
- package/plugin/skills/enhance-assertions/reference/shared-rules.md +220 -0
- package/plugin/skills/enhance-assertions/reference/ui.md +373 -0
- package/plugin/skills/fix-test-import-errors/SKILL.md +45 -50
- package/plugin/skills/run-test/SKILL.md +16 -0
- package/plugin/skills/validate-assertion-alignment-post-execution/SKILL.md +32 -0
- package/plugin/skills/validate-assertion-alignment-post-execution/reference/checks.md +44 -0
- package/plugin/skills/validate-assertion-alignment-post-execution/reference/evidence.md +47 -0
- package/build/adapters/jestAdapter.d.ts +0 -14
- package/build/adapters/jestAdapter.js +0 -113
- package/build/adapters/mochaAdapter.d.ts +0 -13
- package/build/adapters/mochaAdapter.js +0 -87
- package/build/adapters/playwrightAdapter.d.ts +0 -17
- package/build/adapters/playwrightAdapter.js +0 -182
- package/build/adapters/pytestAdapter.d.ts +0 -15
- package/build/adapters/pytestAdapter.js +0 -108
- package/build/prompts/enhance-assertions/contractProviderAssertionsPrompt.d.ts +0 -2
- package/build/prompts/enhance-assertions/contractProviderAssertionsPrompt.js +0 -29
- package/build/prompts/enhance-assertions/integrationAssertionsPrompt.d.ts +0 -2
- package/build/prompts/enhance-assertions/integrationAssertionsPrompt.js +0 -36
- package/build/prompts/enhance-assertions/sharedAssertionRules.d.ts +0 -16
- package/build/prompts/enhance-assertions/sharedAssertionRules.js +0 -284
- package/build/prompts/enhance-assertions/uiAssertionsPrompt.d.ts +0 -2
- package/build/prompts/enhance-assertions/uiAssertionsPrompt.js +0 -388
- package/build/tools/runExistingTestsTool.d.ts +0 -138
- package/build/tools/runExistingTestsTool.js +0 -644
- package/build/types/ExternalTestExecution.d.ts +0 -67
- package/build/types/ExternalTestExecution.js +0 -8
- package/build/workspace/testSuites.d.ts +0 -20
- package/build/workspace/testSuites.js +0 -17
- package/node_modules/playwright/node_modules/playwright-core/.DS_Store +0 -0
|
@@ -0,0 +1,719 @@
|
|
|
1
|
+
import { execFile } from "child_process";
|
|
2
|
+
import { promisify } from "util";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
import { detectGitRoot } from "../gitStaging.js";
|
|
6
|
+
import { logger } from "../logger.js";
|
|
7
|
+
import { escapeRegExp } from "../regex.js";
|
|
8
|
+
import { importedModules, realpath, UTILS_FILE_HEADER_RE } from "./locate.js";
|
|
9
|
+
import { blankComments, blankCommentsAndStrings, defaultAt, hasDefault, parseUtilsFile, } from "./parse.js";
|
|
10
|
+
import { blankStringContents, matchingClose } from "./action-key.js";
|
|
11
|
+
const execFileAsync = promisify(execFile);
|
|
12
|
+
export async function locateInHouseModules(params) {
|
|
13
|
+
const root = params.cwd ?? detectGitRoot(params.testFile);
|
|
14
|
+
if (!root)
|
|
15
|
+
return [];
|
|
16
|
+
const realRoot = await realpath(root);
|
|
17
|
+
const testFile = await realpath(params.testFile);
|
|
18
|
+
const out = [];
|
|
19
|
+
// Every path the imports COULD resolve to, not only the ones on disk: a tracked
|
|
20
|
+
// module this run deleted is still the customer's module, and the spec still
|
|
21
|
+
// imports it — the additive gate has to see it to refuse the deletion.
|
|
22
|
+
for (const abs of await importedModules(testFile, params.spec, "all")) {
|
|
23
|
+
const real = await realpath(abs);
|
|
24
|
+
if (real === testFile)
|
|
25
|
+
continue;
|
|
26
|
+
const rel = path.relative(realRoot, real);
|
|
27
|
+
if (rel === "" || rel.startsWith("..") || path.isAbsolute(rel))
|
|
28
|
+
continue;
|
|
29
|
+
const head = await headContent(realRoot, rel.split(path.sep).join("/"));
|
|
30
|
+
if (head === undefined)
|
|
31
|
+
continue; // not tracked: created this run, or never a file
|
|
32
|
+
// Ownership is read at HEAD and nowhere else. A Skyramp module from an earlier
|
|
33
|
+
// run carries the header there and is the utils verifier's, whatever this run
|
|
34
|
+
// did to its first lines; a module headerless at HEAD is the customer's, and a
|
|
35
|
+
// header the working copy gained since is a change the additive gate refuses —
|
|
36
|
+
// reading the working copy here would let that stamp reclassify their file.
|
|
37
|
+
if (hasHeader(head))
|
|
38
|
+
continue;
|
|
39
|
+
out.push({ file: real, relPath: rel.split(path.sep).join("/") });
|
|
40
|
+
}
|
|
41
|
+
return out.sort((a, b) => a.file.localeCompare(b.file));
|
|
42
|
+
}
|
|
43
|
+
/** Whether a module's first lines carry the Skyramp utils header. */
|
|
44
|
+
function hasHeader(content) {
|
|
45
|
+
return UTILS_FILE_HEADER_RE.test(content.split("\n").slice(0, 5).join("\n"));
|
|
46
|
+
}
|
|
47
|
+
/** The module's content at HEAD, or `undefined` when HEAD does not hold it (or git
|
|
48
|
+
* cannot be asked). */
|
|
49
|
+
async function headContent(root, rel) {
|
|
50
|
+
try {
|
|
51
|
+
const { stdout } = await execFileAsync("git", ["show", `HEAD:${rel}`], {
|
|
52
|
+
cwd: root,
|
|
53
|
+
encoding: "utf8",
|
|
54
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
55
|
+
});
|
|
56
|
+
return stdout;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** The number of arguments a helper accepts: from the position of its last required
|
|
63
|
+
* parameter to its total, a rest parameter opening the top. A parameter with a
|
|
64
|
+
* default, an optional `x?`, or a Python `*args`/`**kw` is not required — but a
|
|
65
|
+
* required one AFTER a defaulted one still has to be reached positionally, so the
|
|
66
|
+
* minimum is its position, not the count of required parameters. `undefined` when
|
|
67
|
+
* the signature could not be read. */
|
|
68
|
+
export function argumentRange(helper) {
|
|
69
|
+
if (!helper.params)
|
|
70
|
+
return undefined;
|
|
71
|
+
let min = 0;
|
|
72
|
+
let max = 0;
|
|
73
|
+
for (const p of helper.params) {
|
|
74
|
+
if (p.startsWith("...") || p.startsWith("*")) {
|
|
75
|
+
max = Infinity;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
max++;
|
|
79
|
+
if (!hasDefault(p) && !isOptional(p))
|
|
80
|
+
min = max;
|
|
81
|
+
}
|
|
82
|
+
return { min, max };
|
|
83
|
+
}
|
|
84
|
+
/** Index of the `=` that introduces a parameter's default — at bracket depth 0 and
|
|
85
|
+
* not part of `=>`, `==`, `<=`, `>=`, `!=` — or -1 when the parameter has none. */
|
|
86
|
+
/** `name?: T` — an optional TypeScript parameter. */
|
|
87
|
+
function isOptional(param) {
|
|
88
|
+
return /^[A-Za-z_$][\w$]*\s*\?\s*(?::|$)/.test(param);
|
|
89
|
+
}
|
|
90
|
+
/** The default expression of a defaulted parameter, and its name. */
|
|
91
|
+
function splitDefault(param) {
|
|
92
|
+
const at = defaultAt(param);
|
|
93
|
+
const name = /^[A-Za-z_$][\w$]*/.exec(param.trim())?.[0];
|
|
94
|
+
if (at === -1 || !name)
|
|
95
|
+
return undefined;
|
|
96
|
+
return { name, value: param.slice(at + 1).trim() };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve — verify step 9. The imported name exists in the module's source, and each
|
|
100
|
+
* call passes an argument count between the definition's required count and its
|
|
101
|
+
* total. A range, not an exact count: every helper in the pilot's module has
|
|
102
|
+
* defaulted parameters, and an exact count rejects them all.
|
|
103
|
+
*
|
|
104
|
+
* `stem` is the module's basename without extension, which is how the language
|
|
105
|
+
* spec reads the spec's imports of it.
|
|
106
|
+
*/
|
|
107
|
+
export function resolveInHouseCalls(specContent, moduleContent, stem, spec, file = stem) {
|
|
108
|
+
const helpers = parseUtilsFile(moduleContent, spec);
|
|
109
|
+
const byName = new Map(helpers.map((h) => [h.name, h]));
|
|
110
|
+
const moduleCode = blankCommentsAndStrings(moduleContent, spec);
|
|
111
|
+
const moduleLines = moduleCode.split("\n");
|
|
112
|
+
const specCode = blankCommentsAndStrings(specContent, spec);
|
|
113
|
+
// Comments blanked, strings kept: what decides whether an argument list is empty.
|
|
114
|
+
// `login(/* defaults */)` passes nothing; `login("")` passes one.
|
|
115
|
+
const specNoComments = blankComments(specContent, spec);
|
|
116
|
+
const specLines = specContent.split("\n");
|
|
117
|
+
const out = {
|
|
118
|
+
resolved: [],
|
|
119
|
+
unverifiable: [],
|
|
120
|
+
violations: [],
|
|
121
|
+
};
|
|
122
|
+
for (const name of spec.importedNames(specContent, stem)) {
|
|
123
|
+
const helper = byName.get(name);
|
|
124
|
+
if (!helper) {
|
|
125
|
+
// A class, a constant, a re-export: not readable as a helper, so not checked —
|
|
126
|
+
// but only if the module EXPORTS it under that name. A private class or a
|
|
127
|
+
// default-only export fails `import { name }` at load time like any other
|
|
128
|
+
// missing binding.
|
|
129
|
+
const definition = definitionLineOf(moduleLines, name);
|
|
130
|
+
const exported = definition !== undefined
|
|
131
|
+
? isExported(moduleCode, definition, name)
|
|
132
|
+
: isReExported(moduleCode, name);
|
|
133
|
+
if (exported)
|
|
134
|
+
out.unverifiable.push(name);
|
|
135
|
+
else
|
|
136
|
+
out.violations.push({
|
|
137
|
+
kind: "in-house-unresolved",
|
|
138
|
+
file,
|
|
139
|
+
helper: name,
|
|
140
|
+
line: importLine(specLines, name),
|
|
141
|
+
detail: `the spec imports \`${name}\` from \`${path.basename(file)}\`, which does not ${definition !== undefined ? "export" : "define"} it${helpers.length > 0
|
|
142
|
+
? ` — it defines ${helpers.map((h) => `\`${h.name}\``).join(", ")}`
|
|
143
|
+
: ""}; call a helper the module defines, or add \`${name}\` to it`,
|
|
144
|
+
});
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
// `module.exports = { login: other }` exports `other` under this name: the local
|
|
148
|
+
// `login` says nothing about what the spec calls. Not readable, not blocked.
|
|
149
|
+
const mapped = cjsObjectValue(moduleCode, name);
|
|
150
|
+
if (mapped !== undefined && mapped !== name) {
|
|
151
|
+
out.unverifiable.push(name);
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
// Defined is not importable: a private module-level function satisfies the
|
|
155
|
+
// parser and fails the import at load time.
|
|
156
|
+
if (spec.language !== "python" &&
|
|
157
|
+
!isExported(moduleCode, moduleLines[helper.line - 1] ?? "", name)) {
|
|
158
|
+
out.violations.push({
|
|
159
|
+
kind: "in-house-unresolved",
|
|
160
|
+
file,
|
|
161
|
+
helper: name,
|
|
162
|
+
line: importLine(specLines, name),
|
|
163
|
+
detail: `the spec imports \`${name}\` from \`${path.basename(file)}\`, which defines it but does not export it (not exported: no \`export\` on the definition, no \`export { ${name} }\`, no \`module.exports\` entry); import an exported helper, or export this one only if the module's style already exports its helpers`,
|
|
164
|
+
});
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
out.resolved.push(name);
|
|
168
|
+
const range = argumentRange(helper);
|
|
169
|
+
if (!range)
|
|
170
|
+
continue;
|
|
171
|
+
for (const call of callSites(specCode, specNoComments, name)) {
|
|
172
|
+
if (call.args >= range.min && call.args <= range.max)
|
|
173
|
+
continue;
|
|
174
|
+
out.violations.push({
|
|
175
|
+
kind: "in-house-arity",
|
|
176
|
+
file,
|
|
177
|
+
helper: name,
|
|
178
|
+
line: call.line,
|
|
179
|
+
detail: `\`${name}\` is called with ${call.args} argument${call.args === 1 ? "" : "s"} at line ${call.line}; its definition in \`${path.basename(file)}\` accepts between ${range.min} and ${range.max === Infinity ? "any number" : range.max} (${helper.params.length === 0 ? "no parameters" : helper.params.map((p) => `\`${p.replace(/\s+/g, " ")}\``).join(", ")}). Pass what the signature accepts, or add a parameter WITH a default to the helper`,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return out;
|
|
184
|
+
}
|
|
185
|
+
/** Whether a helper defined on `definitionLine` reaches the module's exports UNDER
|
|
186
|
+
* ITS OWN NAME — what `import { name }` needs: an `export` on the definition, an
|
|
187
|
+
* unaliased entry in an `export { … }` list of this module's own bindings (not a
|
|
188
|
+
* re-export `from` elsewhere), or a CommonJS `exports.name =` / a `module.exports`
|
|
189
|
+
* object whose KEY is the name. `export default name` exports no named binding,
|
|
190
|
+
* and `export { name as other }` exports `other`. */
|
|
191
|
+
function isExported(moduleCode, definitionLine, name) {
|
|
192
|
+
if (/^\s*export\s+(?!default\b)/.test(definitionLine))
|
|
193
|
+
return true;
|
|
194
|
+
for (const m of moduleCode.matchAll(/\bexport\s*\{([^}]*)\}(\s*from\b)?/g)) {
|
|
195
|
+
if (m[2])
|
|
196
|
+
continue; // a re-export names another module's binding
|
|
197
|
+
for (const raw of m[1].split(",")) {
|
|
198
|
+
const [local, exported] = raw.trim().split(/\s+as\s+/);
|
|
199
|
+
if (local === name && (exported === undefined || exported === name))
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const n = escapeRegExp(name);
|
|
204
|
+
if (new RegExp(`\\b(?:module\\.)?exports\\.${n}\\s*=`).test(moduleCode))
|
|
205
|
+
return true;
|
|
206
|
+
return cjsObjectValue(moduleCode, name) !== undefined;
|
|
207
|
+
}
|
|
208
|
+
/** The VALUE a `module.exports = { … }` object binds to `key` — the key itself for
|
|
209
|
+
* a shorthand entry — or `undefined` when no such entry exists. */
|
|
210
|
+
function cjsObjectValue(moduleCode, key) {
|
|
211
|
+
const object = moduleCode.match(/module\.exports\s*=\s*\{([^}]*)\}/)?.[1];
|
|
212
|
+
if (!object)
|
|
213
|
+
return undefined;
|
|
214
|
+
for (const raw of object.split(",")) {
|
|
215
|
+
const [k, v] = raw.split(":").map((t) => t.trim());
|
|
216
|
+
if (k === key)
|
|
217
|
+
return v === undefined || v === "" ? key : v;
|
|
218
|
+
}
|
|
219
|
+
return undefined;
|
|
220
|
+
}
|
|
221
|
+
/** The line that defines `name` as something other than a module-level helper — a
|
|
222
|
+
* class, a constant, an enum, a type — or `undefined` when nothing does. */
|
|
223
|
+
function definitionLineOf(moduleLines, name) {
|
|
224
|
+
const re = new RegExp(`\\b(?:class|const|let|var|enum|interface|type|function|def)\\s+${escapeRegExp(name)}\\b`);
|
|
225
|
+
return moduleLines.find((l) => re.test(l));
|
|
226
|
+
}
|
|
227
|
+
/** `export { name } from "…"`, or `export * from "…"` — a binding of another module
|
|
228
|
+
* exported here. Exists as an export; not readable as a helper of this module. */
|
|
229
|
+
function isReExported(moduleCode, name) {
|
|
230
|
+
// `export * from "./x"` may legally provide any name; nothing here can read it.
|
|
231
|
+
if (/\bexport\s*\*\s*from\b/.test(moduleCode))
|
|
232
|
+
return true;
|
|
233
|
+
for (const m of moduleCode.matchAll(/\bexport\s*\{([^}]*)\}\s*from\b/g))
|
|
234
|
+
for (const raw of m[1].split(",")) {
|
|
235
|
+
const [local, exported] = raw.trim().split(/\s+as\s+/);
|
|
236
|
+
if ((exported ?? local) === name)
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
function importLine(lines, name) {
|
|
242
|
+
const re = new RegExp(`\\b${escapeRegExp(name)}\\b`);
|
|
243
|
+
const i = lines.findIndex((l) => /\b(?:import|require|from)\b/.test(l) && re.test(l));
|
|
244
|
+
return i === -1 ? 1 : i + 1;
|
|
245
|
+
}
|
|
246
|
+
/** Every call `name(...)` in the spec, with its top-level argument count and 1-based
|
|
247
|
+
* line. Structure is read on `code` (comments and string contents blanked, same
|
|
248
|
+
* offsets), so a comma inside a literal never splits; whether the text after the
|
|
249
|
+
* last comma is an argument or Prettier's trailing comma — and whether the list is
|
|
250
|
+
* empty at all — is read on `noComments` (comments blanked, strings kept, same
|
|
251
|
+
* offsets), where a blanked string and nothing at all are not the same and a
|
|
252
|
+
* comment-only list is nothing. A `.name(` is a method of something else. */
|
|
253
|
+
function callSites(code, noComments, name) {
|
|
254
|
+
const out = [];
|
|
255
|
+
const re = new RegExp(`(?<![\\w$.])${escapeRegExp(name)}\\s*\\(`, "g");
|
|
256
|
+
for (const m of code.matchAll(re)) {
|
|
257
|
+
const open = m.index + m[0].length - 1;
|
|
258
|
+
const close = matchingClose(code, open);
|
|
259
|
+
if (close === -1)
|
|
260
|
+
continue;
|
|
261
|
+
const inner = code.slice(open + 1, close);
|
|
262
|
+
let commas = 0;
|
|
263
|
+
let lastComma = -1;
|
|
264
|
+
let depth = 0;
|
|
265
|
+
for (let i = 0; i < inner.length; i++) {
|
|
266
|
+
const ch = inner[i];
|
|
267
|
+
if ("([{".includes(ch))
|
|
268
|
+
depth++;
|
|
269
|
+
else if (")]}".includes(ch))
|
|
270
|
+
depth--;
|
|
271
|
+
else if (ch === "," && depth === 0) {
|
|
272
|
+
commas++;
|
|
273
|
+
lastComma = i;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
const tail = noComments.slice(open + 1 + lastComma + 1, close);
|
|
277
|
+
const args = noComments.slice(open + 1, close).trim() === ""
|
|
278
|
+
? 0
|
|
279
|
+
: commas + (tail.trim() === "" ? 0 : 1);
|
|
280
|
+
const line = code.slice(0, m.index).split("\n").length;
|
|
281
|
+
out.push({ args, line });
|
|
282
|
+
}
|
|
283
|
+
return out;
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Additive only — verify step 11. Every change this run made to an in-house module
|
|
287
|
+
* adds a helper, or adds a parameter that carries a default. Anything else is
|
|
288
|
+
* refused: a helper removed or renamed, a body changed, a parameter added with no
|
|
289
|
+
* default, a line outside every helper deleted or edited.
|
|
290
|
+
*
|
|
291
|
+
* The widening rule is checked, not trusted: with each added parameter's name
|
|
292
|
+
* replaced by its default in the new body, and the added parameters dropped from
|
|
293
|
+
* the signature, the helper must read as it did at HEAD. That is what "the default
|
|
294
|
+
* is what the helper sends today" means, and it is decidable from the two texts.
|
|
295
|
+
*
|
|
296
|
+
* Compared on HEAD versus the working tree, so it holds at the verify call and again
|
|
297
|
+
* at the submit-time re-derivation. Fails open: a module HEAD does not hold, or a
|
|
298
|
+
* git that cannot be asked, reports `ran: false` with no violations.
|
|
299
|
+
*/
|
|
300
|
+
export async function additiveChanges(file, root, spec) {
|
|
301
|
+
const result = {
|
|
302
|
+
ran: false,
|
|
303
|
+
violations: [],
|
|
304
|
+
added: [],
|
|
305
|
+
widened: [],
|
|
306
|
+
duplicates: [],
|
|
307
|
+
};
|
|
308
|
+
const rel = path.relative(root, file).split(path.sep).join("/");
|
|
309
|
+
const head = await headContent(root, rel);
|
|
310
|
+
if (head === undefined) {
|
|
311
|
+
logger.warning("Could not read an in-house module at HEAD — the additive gate did not run", { file });
|
|
312
|
+
return result;
|
|
313
|
+
}
|
|
314
|
+
let work;
|
|
315
|
+
try {
|
|
316
|
+
work = await fs.promises.readFile(file, "utf8");
|
|
317
|
+
}
|
|
318
|
+
catch (err) {
|
|
319
|
+
if (err?.code !== "ENOENT") {
|
|
320
|
+
logger.warning("Could not read an in-house module in the working tree — the additive gate did not run", { file, error: String(err) });
|
|
321
|
+
return result;
|
|
322
|
+
}
|
|
323
|
+
// HEAD holds it and the working tree does not: the module was deleted — the
|
|
324
|
+
// least additive change there is, and the one a gate built on the files
|
|
325
|
+
// present could never see.
|
|
326
|
+
result.ran = true;
|
|
327
|
+
result.violations.push({
|
|
328
|
+
kind: "in-house-modified",
|
|
329
|
+
file,
|
|
330
|
+
helper: path.basename(file).replace(/\.[^.]+$/, ""),
|
|
331
|
+
line: 1,
|
|
332
|
+
detail: `\`${rel}\` is tracked at HEAD and deleted from the working tree — the reuse step never removes or renames the customer's module; restore it (\`git checkout HEAD -- ${rel}\`) and add what you need to it`,
|
|
333
|
+
});
|
|
334
|
+
return result;
|
|
335
|
+
}
|
|
336
|
+
result.ran = true;
|
|
337
|
+
// Rule 5 of the design, enforced: the file stays the customer's file.
|
|
338
|
+
if (hasHeader(work) && !hasHeader(head))
|
|
339
|
+
result.violations.push({
|
|
340
|
+
kind: "in-house-modified",
|
|
341
|
+
file,
|
|
342
|
+
helper: path.basename(file).replace(/\.[^.]+$/, ""),
|
|
343
|
+
line: 1,
|
|
344
|
+
detail: `a \`Generated by Skyramp on …\` header was written into the customer's module — it was not there at HEAD, and this run never marks their code as ours; delete the header line`,
|
|
345
|
+
});
|
|
346
|
+
const headHelpers = parseUtilsFile(head, spec);
|
|
347
|
+
const workHelpers = parseUtilsFile(work, spec);
|
|
348
|
+
const workByName = new Map(workHelpers.map((h) => [h.name, h]));
|
|
349
|
+
const headByName = new Map(headHelpers.map((h) => [h.name, h]));
|
|
350
|
+
const stem = path.basename(file).replace(/\.[^.]+$/, "");
|
|
351
|
+
// A name defined twice in the working copy: the module does not load
|
|
352
|
+
// (TypeScript) or the second definition replaces the first (Python). A Map
|
|
353
|
+
// would keep the last copy and compare it clean against HEAD.
|
|
354
|
+
const seenNames = new Set();
|
|
355
|
+
for (const w of workHelpers) {
|
|
356
|
+
if (seenNames.has(w.name))
|
|
357
|
+
result.violations.push({
|
|
358
|
+
kind: "in-house-modified",
|
|
359
|
+
file,
|
|
360
|
+
helper: w.name,
|
|
361
|
+
line: w.line,
|
|
362
|
+
detail: `\`${w.name}\` is defined twice in the working copy (also at line ${workHelpers.find((x) => x.name === w.name).line}); a module with two definitions of one name does not load — keep the one HEAD holds and delete the other`,
|
|
363
|
+
});
|
|
364
|
+
seenNames.add(w.name);
|
|
365
|
+
}
|
|
366
|
+
for (const h of headHelpers) {
|
|
367
|
+
const w = workByName.get(h.name);
|
|
368
|
+
if (!w) {
|
|
369
|
+
result.violations.push({
|
|
370
|
+
kind: "in-house-modified",
|
|
371
|
+
file,
|
|
372
|
+
helper: h.name,
|
|
373
|
+
line: h.line,
|
|
374
|
+
detail: `\`${h.name}\` is defined at HEAD and not in the working copy — an existing helper is never removed or renamed by the reuse step; restore it as it was`,
|
|
375
|
+
});
|
|
376
|
+
continue;
|
|
377
|
+
}
|
|
378
|
+
const before = helperText(head, h);
|
|
379
|
+
const after = helperText(work, w);
|
|
380
|
+
if (squash(before) === squash(after))
|
|
381
|
+
continue;
|
|
382
|
+
const reason = wideningFault(before, after, h, w);
|
|
383
|
+
if (reason === undefined) {
|
|
384
|
+
result.widened.push(h.name);
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
result.violations.push({
|
|
388
|
+
kind: "in-house-modified",
|
|
389
|
+
file,
|
|
390
|
+
helper: h.name,
|
|
391
|
+
line: w.line,
|
|
392
|
+
detail: `\`${h.name}\` differs from its definition at HEAD: ${reason}. The reuse step may add a parameter whose default is the value the helper used at HEAD, and nothing else; restore the helper and put the change in a new helper or a defaulted parameter`,
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
for (const w of workHelpers) {
|
|
396
|
+
if (headByName.has(w.name) || result.added.includes(w.name))
|
|
397
|
+
continue;
|
|
398
|
+
result.added.push(w.name);
|
|
399
|
+
if (!w.actionKey)
|
|
400
|
+
continue;
|
|
401
|
+
const existing = headHelpers.find((h) => h.actionKey === w.actionKey);
|
|
402
|
+
if (existing)
|
|
403
|
+
result.duplicates.push({ added: w.name, existing: existing.name });
|
|
404
|
+
}
|
|
405
|
+
// Lines outside every helper at HEAD must still be present: an import, a constant,
|
|
406
|
+
// a comment the customer wrote. Additions there are allowed — a new helper may need
|
|
407
|
+
// a type import or a default constant — deletions and edits are not. Compared
|
|
408
|
+
// whitespace-free, so a reflowed import is not a change.
|
|
409
|
+
// Lines outside every helper, compared in two parts.
|
|
410
|
+
//
|
|
411
|
+
// IMPORT STATEMENTS and EXPORT LISTS are compared by NAME: a new
|
|
412
|
+
// helper routinely needs one more symbol from a module the file already imports,
|
|
413
|
+
// and adding it is the edit STEP 3b asks for. Line-for-line that reads as a
|
|
414
|
+
// deletion — the formatter wraps the statement the moment it crosses the print
|
|
415
|
+
// width — and the finding was unanswerable: the agent cannot restore the old line
|
|
416
|
+
// and keep the symbol. A module that exports at the bottom has the same shape: the
|
|
417
|
+
// helper STEP 3b adds is callable only once its name joins the `export { … }`
|
|
418
|
+
// list. HEAD's names must still be imported from the same source and still be
|
|
419
|
+
// exported; extra names, and any wrapping, are additions. (A destructured
|
|
420
|
+
// `require` goes through the line check below, like any other statement.)
|
|
421
|
+
//
|
|
422
|
+
// EVERY OTHER LINE is compared as an ORDERED SUBSEQUENCE: each must still appear,
|
|
423
|
+
// in HEAD's order. Insertions are allowed; a deletion, a change or a reordering is
|
|
424
|
+
// not — `const client = makeClient()` moved below its first use breaks module
|
|
425
|
+
// initialisation. Whitespace outside strings is ignored, so a reflowed line is the
|
|
426
|
+
// same line only when it stays one line.
|
|
427
|
+
const headRest = splitImports(remainder(head, headHelpers));
|
|
428
|
+
const workRest = splitImports(remainder(work, workHelpers));
|
|
429
|
+
const missing = [];
|
|
430
|
+
for (const [source, names] of headRest.imports) {
|
|
431
|
+
const now = workRest.imports.get(source);
|
|
432
|
+
const lost = [...names].filter((n) => !now?.has(n));
|
|
433
|
+
if (lost.length > 0)
|
|
434
|
+
result.violations.push({
|
|
435
|
+
kind: "in-house-modified",
|
|
436
|
+
file,
|
|
437
|
+
helper: stem,
|
|
438
|
+
line: 1,
|
|
439
|
+
detail: `${lost.map((n) => `\`${n}\``).join(", ")} ${lost.length === 1 ? "is" : "are"} no longer imported from \`${source}\` — the reuse step may ADD a symbol to an existing import (and the formatter may wrap it), never remove one or change where it comes from; restore ${lost.length === 1 ? "it" : "them"}`,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
const lostExports = [...headRest.exports].filter((n) => !workRest.exports.has(n));
|
|
443
|
+
if (lostExports.length > 0)
|
|
444
|
+
result.violations.push({
|
|
445
|
+
kind: "in-house-modified",
|
|
446
|
+
file,
|
|
447
|
+
helper: stem,
|
|
448
|
+
line: 1,
|
|
449
|
+
detail: `${lostExports.map((n) => `\`${n}\``).join(", ")} ${lostExports.length === 1 ? "is" : "are"} no longer exported by this module — the reuse step may ADD a name to an \`export { … }\` list, so a helper it added is callable, never remove one; restore ${lostExports.length === 1 ? "it" : "them"}`,
|
|
450
|
+
});
|
|
451
|
+
const headLines = headRest.lines;
|
|
452
|
+
const workLines = workRest.lines;
|
|
453
|
+
const matched = new Set();
|
|
454
|
+
let cursor = 0;
|
|
455
|
+
for (const l of headLines) {
|
|
456
|
+
const at = workLines.indexOf(l, cursor);
|
|
457
|
+
if (at === -1)
|
|
458
|
+
missing.push(l);
|
|
459
|
+
else {
|
|
460
|
+
matched.add(at);
|
|
461
|
+
cursor = at + 1;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
// An added line may declare something new; it may not REBIND what HEAD holds. A
|
|
465
|
+
// helper's text and every HEAD line survive `login = async () => {}` appended
|
|
466
|
+
// below them, and the export now points at the new body.
|
|
467
|
+
const headBindings = new Set(headHelpers.map((h) => h.name));
|
|
468
|
+
for (const m of remainder(head, headHelpers).matchAll(/^\s*(?:export\s+)?(?:const|let|var|class|function)\s+([A-Za-z_$][\w$]*)/gm))
|
|
469
|
+
headBindings.add(m[1]);
|
|
470
|
+
workLines.forEach((l, i) => {
|
|
471
|
+
if (matched.has(i))
|
|
472
|
+
return;
|
|
473
|
+
const m = /^(?:module\.exports\.|exports\.)?([A-Za-z_$][\w$]*)\s*(?:=(?!=)|\.[\w$]+\s*=(?!=)|\[[^\]]*\]\s*=(?!=)|\()/.exec(l);
|
|
474
|
+
if (m && headBindings.has(m[1]))
|
|
475
|
+
result.violations.push({
|
|
476
|
+
kind: "in-house-modified",
|
|
477
|
+
file,
|
|
478
|
+
helper: m[1],
|
|
479
|
+
line: 1,
|
|
480
|
+
detail: `a line added outside every helper rebinds or calls \`${m[1]}\`, which HEAD defines (\`${l.slice(0, 60)}\`) — a new helper is a new definition; nothing already in the module is reassigned, mutated or executed at load; delete the line`,
|
|
481
|
+
});
|
|
482
|
+
});
|
|
483
|
+
if (missing.length > 0)
|
|
484
|
+
result.violations.push({
|
|
485
|
+
kind: "in-house-modified",
|
|
486
|
+
file,
|
|
487
|
+
helper: stem,
|
|
488
|
+
line: 1,
|
|
489
|
+
detail: `${missing.length} line${missing.length === 1 ? "" : "s"} outside every helper ${missing.length === 1 ? "is" : "are"} gone or changed since HEAD (${missing
|
|
490
|
+
.slice(0, 3)
|
|
491
|
+
.map((l) => `\`${l.slice(0, 60)}\``)
|
|
492
|
+
.join(", ")}${missing.length > 3 ? ", …" : ""}) — the reuse step adds to the customer's module and changes nothing already in it; restore ${missing.length === 1 ? "that line" : "those lines"}`,
|
|
493
|
+
});
|
|
494
|
+
return result;
|
|
495
|
+
}
|
|
496
|
+
/** A module's non-helper text, split into the parts a comparison must read by NAME
|
|
497
|
+
* rather than by line.
|
|
498
|
+
*
|
|
499
|
+
* An `import` statement, and an `export { … }` list, both run until their
|
|
500
|
+
* terminator and both are wrapped freely by the formatter. Both also grow by one
|
|
501
|
+
* name when a new helper arrives — the import it needs, and the export that makes
|
|
502
|
+
* it callable — which STEP 3b asks for and a line comparison read as a deletion.
|
|
503
|
+
* `imports` is keyed by SOURCE (a re-export `export { x } from "y"` is one of
|
|
504
|
+
* these); `exports` holds the names a bare `export { … }` list publishes;
|
|
505
|
+
* `lines` is everything else, squashed and blank-free. */
|
|
506
|
+
function splitImports(text) {
|
|
507
|
+
const imports = new Map();
|
|
508
|
+
const exports = new Set();
|
|
509
|
+
const lines = [];
|
|
510
|
+
const raw = text.split("\n");
|
|
511
|
+
for (let i = 0; i < raw.length; i++) {
|
|
512
|
+
if (!/^\s*(?:import\b|export\s*\{)/.test(raw[i])) {
|
|
513
|
+
const l = squash(raw[i]);
|
|
514
|
+
if (l !== "")
|
|
515
|
+
lines.push(l);
|
|
516
|
+
continue;
|
|
517
|
+
}
|
|
518
|
+
let statement = raw[i];
|
|
519
|
+
// Join continuations until the statement is complete — bounded, so an
|
|
520
|
+
// `import` inside prose cannot swallow the file.
|
|
521
|
+
const complete = (t) => /from\s*["'][^"']+["']/.test(t) ||
|
|
522
|
+
/^\s*import\s*["'][^"']+["']/.test(t) ||
|
|
523
|
+
(/^\s*export\s*\{/.test(t) && /\}/.test(t));
|
|
524
|
+
for (let joined = 0; joined < 30 && !complete(statement); joined++) {
|
|
525
|
+
if (i + 1 >= raw.length)
|
|
526
|
+
break;
|
|
527
|
+
i++;
|
|
528
|
+
statement += " " + raw[i];
|
|
529
|
+
}
|
|
530
|
+
// Where the statement ENDS, and what follows it on the same physical line.
|
|
531
|
+
// Reading the whole line as one statement let an assignment hide behind an
|
|
532
|
+
// export list or an import — `export { login }; login = async () => {…}` —
|
|
533
|
+
// where the rebind and subsequence checks, which read `lines`, never saw it.
|
|
534
|
+
const inert = blankStringContents(statement);
|
|
535
|
+
const m = /from\s*["']([^"']+)["']/.exec(inert) ??
|
|
536
|
+
/^\s*import\s*["']([^"']+)["']/.exec(inert);
|
|
537
|
+
let end;
|
|
538
|
+
let clause;
|
|
539
|
+
if (m) {
|
|
540
|
+
end = m.index + m[0].length;
|
|
541
|
+
clause = statement.slice(0, m.index);
|
|
542
|
+
}
|
|
543
|
+
else {
|
|
544
|
+
const open = inert.indexOf("{");
|
|
545
|
+
const close = open === -1 ? -1 : matchingClose(inert, open);
|
|
546
|
+
if (!/^\s*export\s*\{/.test(inert) || close === -1) {
|
|
547
|
+
const l = squash(statement);
|
|
548
|
+
if (l !== "")
|
|
549
|
+
lines.push(l);
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
end = close + 1;
|
|
553
|
+
clause = statement.slice(open + 1, close);
|
|
554
|
+
}
|
|
555
|
+
while (end < statement.length && /[\s;]/.test(statement[end]))
|
|
556
|
+
end++;
|
|
557
|
+
const tail = squash(statement.slice(end));
|
|
558
|
+
if (tail !== "")
|
|
559
|
+
lines.push(tail);
|
|
560
|
+
const names = new Set([...clause.matchAll(/[A-Za-z_$][\w$]*/g)]
|
|
561
|
+
.map((x) => x[0])
|
|
562
|
+
.filter((n) => !["import", "export", "from", "type", "as"].includes(n)));
|
|
563
|
+
if (!m) {
|
|
564
|
+
for (const n of names)
|
|
565
|
+
exports.add(n);
|
|
566
|
+
continue;
|
|
567
|
+
}
|
|
568
|
+
const held = imports.get(m[1]) ?? new Set();
|
|
569
|
+
for (const n of names)
|
|
570
|
+
held.add(n);
|
|
571
|
+
imports.set(m[1], held);
|
|
572
|
+
}
|
|
573
|
+
return { imports, exports, lines };
|
|
574
|
+
}
|
|
575
|
+
/** The helper's source, definition line through its last body line. */
|
|
576
|
+
function helperText(content, h) {
|
|
577
|
+
return content
|
|
578
|
+
.split("\n")
|
|
579
|
+
.slice(h.line - 1, h.endLine)
|
|
580
|
+
.join("\n");
|
|
581
|
+
}
|
|
582
|
+
/** The file with every helper's span blanked to empty lines. */
|
|
583
|
+
function remainder(content, helpers) {
|
|
584
|
+
const lines = content.split("\n");
|
|
585
|
+
for (const h of helpers)
|
|
586
|
+
for (let i = h.line - 1; i < h.endLine && i < lines.length; i++)
|
|
587
|
+
lines[i] = "";
|
|
588
|
+
return lines.join("\n");
|
|
589
|
+
}
|
|
590
|
+
/** Formatting whitespace outside string literals dropped, `'` normalised to `"` (a
|
|
591
|
+
* template literal keeps its backticks), Prettier's trailing commas removed — two spellings of one code compare equal, and
|
|
592
|
+
* a changed string content still compares unequal. Whitespace that SEPARATES two
|
|
593
|
+
* identifier characters is a token boundary, not formatting: it is kept as one
|
|
594
|
+
* space, so `await Promise` and `awaitPromise` stay two different texts.
|
|
595
|
+
* Whitespace inside a regex literal is not recognised as significant. */
|
|
596
|
+
export function squash(text) {
|
|
597
|
+
let out = "";
|
|
598
|
+
let quote = null;
|
|
599
|
+
const word = (c) => c !== undefined && /[\w$]/.test(c);
|
|
600
|
+
for (let i = 0; i < text.length; i++) {
|
|
601
|
+
const ch = text[i];
|
|
602
|
+
if (quote) {
|
|
603
|
+
if (ch === "\\") {
|
|
604
|
+
out += ch + (text[i + 1] ?? "");
|
|
605
|
+
i++;
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
if (ch === quote) {
|
|
609
|
+
quote = null;
|
|
610
|
+
out += ch === "`" ? "`" : '"';
|
|
611
|
+
}
|
|
612
|
+
else
|
|
613
|
+
out += ch;
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
if (ch === '"' || ch === "'" || ch === "`") {
|
|
617
|
+
quote = ch;
|
|
618
|
+
// Quote STYLE is formatting; a template literal is not — `${…}` interpolates
|
|
619
|
+
// there and is six characters of text in a plain string.
|
|
620
|
+
out += ch === "`" ? "`" : '"';
|
|
621
|
+
}
|
|
622
|
+
else if (/\s/.test(ch)) {
|
|
623
|
+
let j = i + 1;
|
|
624
|
+
while (j < text.length && /\s/.test(text[j]))
|
|
625
|
+
j++;
|
|
626
|
+
if (word(out[out.length - 1]) && word(text[j]))
|
|
627
|
+
out += " ";
|
|
628
|
+
i = j - 1;
|
|
629
|
+
}
|
|
630
|
+
else if (ch === ",") {
|
|
631
|
+
// Prettier's trailing comma — a `,` whose next token closes the list — is
|
|
632
|
+
// formatting. Decided here, outside literals: a `,` inside a string is data.
|
|
633
|
+
let j = i + 1;
|
|
634
|
+
while (j < text.length && /\s/.test(text[j]))
|
|
635
|
+
j++;
|
|
636
|
+
if (!")]}".includes(text[j] ?? ""))
|
|
637
|
+
out += ch;
|
|
638
|
+
}
|
|
639
|
+
else
|
|
640
|
+
out += ch;
|
|
641
|
+
}
|
|
642
|
+
return out;
|
|
643
|
+
}
|
|
644
|
+
/**
|
|
645
|
+
* Why `after` is not `before` widened by defaulted parameters — or `undefined` when
|
|
646
|
+
* it is exactly that. Each added parameter must carry a default; substituting the
|
|
647
|
+
* default for the parameter's name in the body, and dropping the added parameters
|
|
648
|
+
* from the signature, must give back the HEAD text.
|
|
649
|
+
*/
|
|
650
|
+
function wideningFault(before, after, h, w) {
|
|
651
|
+
const headParams = (h.params ?? []).map(squash);
|
|
652
|
+
const workParams = w.params ?? [];
|
|
653
|
+
// The HEAD parameters must stay an exact PREFIX, in order: a defaulted parameter
|
|
654
|
+
// inserted before them substitutes back cleanly and still shifts every positional
|
|
655
|
+
// caller onto the wrong argument. Only appended parameters are additions.
|
|
656
|
+
const prefixKept = headParams.every((p, i) => i < workParams.length && squash(workParams[i]) === p);
|
|
657
|
+
if (!prefixKept)
|
|
658
|
+
return `its parameter list no longer starts with HEAD's (${headParams.map((p) => `\`${p}\``).join(", ")}) — a parameter was changed, removed or reordered, or a new one was inserted before the existing ones; a new parameter is appended, so every positional caller keeps binding what it bound`;
|
|
659
|
+
const added = workParams.slice(headParams.length);
|
|
660
|
+
if (added.length === 0)
|
|
661
|
+
return "its body changed";
|
|
662
|
+
const noDefault = added.filter((p) => !hasDefault(p));
|
|
663
|
+
if (noDefault.length > 0)
|
|
664
|
+
return `parameter${noDefault.length === 1 ? "" : "s"} ${noDefault.map((p) => `\`${p.replace(/\s+/g, " ")}\``).join(", ")} ${noDefault.length === 1 ? "was" : "were"} added without a default, which breaks every existing caller`;
|
|
665
|
+
// Only a plain literal default is provable by substitution: an expression is
|
|
666
|
+
// evaluated at call entry, so `value = fallback, fallback = "x"` substitutes back
|
|
667
|
+
// to the HEAD text and still throws for every caller that omits both (the later
|
|
668
|
+
// parameter is in its temporal dead zone). STEP 3b promises the literal the helper
|
|
669
|
+
// used at HEAD, and that is what is accepted.
|
|
670
|
+
const nonLiteral = added.filter((p) => {
|
|
671
|
+
const d = splitDefault(p);
|
|
672
|
+
return !d || !isLiteralDefault(d.value);
|
|
673
|
+
});
|
|
674
|
+
if (nonLiteral.length > 0)
|
|
675
|
+
return `the default of ${nonLiteral.map((p) => `\`${p.replace(/\s+/g, " ")}\``).join(", ")} is not a plain literal — an added parameter's default is the string, number, boolean or null literal the helper used at HEAD, never an expression or another parameter`;
|
|
676
|
+
const span = paramSpan(after);
|
|
677
|
+
if (!span)
|
|
678
|
+
return "its signature could not be read";
|
|
679
|
+
let body = after.slice(span.close + 1);
|
|
680
|
+
for (const p of added) {
|
|
681
|
+
const d = splitDefault(p);
|
|
682
|
+
if (!d)
|
|
683
|
+
return "an added parameter's default could not be read";
|
|
684
|
+
body = replaceIdentifier(body, d.name, d.value);
|
|
685
|
+
}
|
|
686
|
+
const signature = after.slice(0, span.open + 1) +
|
|
687
|
+
workParams.slice(0, headParams.length).join(", ") +
|
|
688
|
+
after.slice(span.close, span.close + 1);
|
|
689
|
+
if (squash(signature + body) === squash(before))
|
|
690
|
+
return undefined;
|
|
691
|
+
return `its body changed beyond the use of the added parameter${added.length === 1 ? "" : "s"} ${added.map((p) => `\`${p.replace(/\s+/g, " ").split("=")[0].trim()}\``).join(", ")}`;
|
|
692
|
+
}
|
|
693
|
+
/** A string, number, boolean, `null` or `undefined` literal — the only defaults the
|
|
694
|
+
* substitution check can vouch for. */
|
|
695
|
+
function isLiteralDefault(value) {
|
|
696
|
+
return /^(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|`[^`$]*`|-?\d+(?:\.\d+)?|true|false|null|undefined)$/.test(value.trim());
|
|
697
|
+
}
|
|
698
|
+
/** The `(`…`)` of the parameter list: the first parenthesis pair on a copy whose
|
|
699
|
+
* string contents are blanked. */
|
|
700
|
+
function paramSpan(text) {
|
|
701
|
+
const inert = blankStringContents(text);
|
|
702
|
+
const open = inert.indexOf("(");
|
|
703
|
+
if (open === -1)
|
|
704
|
+
return undefined;
|
|
705
|
+
const close = matchingClose(inert, open);
|
|
706
|
+
return close === -1 ? undefined : { open, close };
|
|
707
|
+
}
|
|
708
|
+
/** `name` as an identifier, outside string literals, replaced by `value`. */
|
|
709
|
+
function replaceIdentifier(text, name, value) {
|
|
710
|
+
const inert = blankStringContents(text);
|
|
711
|
+
const re = new RegExp(`(?<![\\w$.])${escapeRegExp(name)}(?![\\w$])`, "g");
|
|
712
|
+
let out = "";
|
|
713
|
+
let last = 0;
|
|
714
|
+
for (const m of inert.matchAll(re)) {
|
|
715
|
+
out += text.slice(last, m.index) + value;
|
|
716
|
+
last = m.index + m[0].length;
|
|
717
|
+
}
|
|
718
|
+
return out + text.slice(last);
|
|
719
|
+
}
|