qa360 2.3.0 → 2.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -262
- package/{cli/dist → dist}/commands/ai.js +1 -1
- package/{cli/dist → dist}/commands/coverage.js +1 -1
- package/{cli/dist → dist}/commands/crawl.js +2 -2
- package/{cli/dist → dist}/commands/doctor.js +2 -2
- package/{cli/dist → dist}/commands/explain.js +2 -2
- package/{cli/dist → dist}/commands/flakiness.js +1 -1
- package/{cli/dist → dist}/commands/generate.js +1 -1
- package/{cli/dist → dist}/commands/history.js +1 -1
- package/{cli/dist → dist}/commands/monitor.js +3 -3
- package/{cli/dist → dist}/commands/ollama.js +1 -1
- package/{cli/dist → dist}/commands/pack.js +2 -2
- package/{cli/dist → dist}/commands/regression.js +1 -1
- package/{cli/dist → dist}/commands/repair.js +1 -1
- package/{cli/dist → dist}/commands/retry.js +1 -1
- package/{cli/dist → dist}/commands/run.d.ts +1 -1
- package/{cli/dist → dist}/commands/run.js +1 -1
- package/{cli/dist → dist}/commands/secrets.js +1 -1
- package/{cli/dist → dist}/commands/serve.js +1 -1
- package/{cli/dist → dist}/commands/slo.js +1 -1
- package/{cli/dist → dist}/commands/verify.js +1 -1
- package/{cli/dist → dist}/core/adapters/playwright-native-api.d.ts +2 -0
- package/{cli/dist → dist}/core/adapters/playwright-native-api.js +20 -1
- package/{cli/dist → dist}/core/adapters/playwright-ui.d.ts +21 -0
- package/dist/core/adapters/playwright-ui.js +2050 -0
- package/{cli/dist → dist}/core/ai/ollama-provider.js +15 -3
- package/{cli/dist → dist}/core/artifacts/ui-artifacts.js +24 -4
- package/dist/core/auth/backup-codes-provider.d.ts +91 -0
- package/dist/core/auth/backup-codes-provider.js +215 -0
- package/{cli/dist → dist}/core/auth/basic-auth-provider.d.ts +6 -0
- package/{cli/dist → dist}/core/auth/basic-auth-provider.js +24 -6
- package/dist/core/auth/digest-auth-provider.d.ts +116 -0
- package/dist/core/auth/digest-auth-provider.js +244 -0
- package/dist/core/auth/hcaptcha-handler.d.ts +103 -0
- package/dist/core/auth/hcaptcha-handler.js +288 -0
- package/{cli/dist → dist}/core/auth/index.d.ts +81 -4
- package/{cli/dist → dist}/core/auth/index.js +15 -1
- package/dist/core/auth/oauth-handler.d.ts +408 -0
- package/dist/core/auth/oauth-handler.js +636 -0
- package/{cli/dist → dist}/core/auth/oauth2-provider.d.ts +9 -0
- package/dist/core/auth/oauth2-provider.js +227 -0
- package/dist/core/auth/otp-provider.d.ts +93 -0
- package/dist/core/auth/otp-provider.js +288 -0
- package/dist/core/auth/recaptcha-handler.d.ts +119 -0
- package/dist/core/auth/recaptcha-handler.js +301 -0
- package/dist/core/auth/remember-me-handler.d.ts +142 -0
- package/dist/core/auth/remember-me-handler.js +255 -0
- package/dist/core/auth/saml-handler.d.ts +173 -0
- package/dist/core/auth/saml-handler.js +364 -0
- package/dist/core/auth/webauthn-handler.d.ts +182 -0
- package/dist/core/auth/webauthn-handler.js +310 -0
- package/dist/core/crawler/advanced-interactions.d.ts +342 -0
- package/dist/core/crawler/advanced-interactions.js +1069 -0
- package/dist/core/crawler/blob-url-download-handler.d.ts +145 -0
- package/dist/core/crawler/blob-url-download-handler.js +392 -0
- package/dist/core/crawler/consent-handler.d.ts +49 -0
- package/dist/core/crawler/consent-handler.js +258 -0
- package/dist/core/crawler/cookie-manager.d.ts +166 -0
- package/dist/core/crawler/cookie-manager.js +353 -0
- package/dist/core/crawler/coop-coep-handler.d.ts +136 -0
- package/dist/core/crawler/coop-coep-handler.js +338 -0
- package/dist/core/crawler/csp-handler.d.ts +151 -0
- package/dist/core/crawler/csp-handler.js +415 -0
- package/dist/core/crawler/download-handler.d.ts +155 -0
- package/dist/core/crawler/download-handler.js +370 -0
- package/dist/core/crawler/email-testing-handler.d.ts +214 -0
- package/dist/core/crawler/email-testing-handler.js +398 -0
- package/dist/core/crawler/error-tracking-handler.d.ts +177 -0
- package/dist/core/crawler/error-tracking-handler.js +378 -0
- package/dist/core/crawler/form-handler.d.ts +100 -0
- package/dist/core/crawler/form-handler.js +465 -0
- package/dist/core/crawler/framework-wait-handler.d.ts +96 -0
- package/dist/core/crawler/framework-wait-handler.js +464 -0
- package/dist/core/crawler/geolocation-handler.d.ts +112 -0
- package/dist/core/crawler/geolocation-handler.js +276 -0
- package/dist/core/crawler/index.d.ts +78 -0
- package/{cli/dist → dist}/core/crawler/index.js +74 -1
- package/dist/core/crawler/intelligent-selector-generator.d.ts +164 -0
- package/dist/core/crawler/intelligent-selector-generator.js +612 -0
- package/{cli/dist → dist}/core/crawler/journey-generator.js +44 -1
- package/{cli/dist → dist}/core/crawler/page-analyzer.d.ts +16 -1
- package/{cli/dist → dist}/core/crawler/page-analyzer.js +469 -17
- package/dist/core/crawler/permissions-handler.d.ts +112 -0
- package/dist/core/crawler/permissions-handler.js +236 -0
- package/dist/core/crawler/permissions-policy-handler.d.ts +113 -0
- package/dist/core/crawler/permissions-policy-handler.js +402 -0
- package/dist/core/crawler/presets.d.ts +100 -0
- package/dist/core/crawler/presets.js +887 -0
- package/dist/core/crawler/repl-debug-handler.d.ts +105 -0
- package/dist/core/crawler/repl-debug-handler.js +552 -0
- package/dist/core/crawler/reporting-api-handler.d.ts +212 -0
- package/dist/core/crawler/reporting-api-handler.js +344 -0
- package/{cli/dist → dist}/core/crawler/selector-generator.d.ts +9 -0
- package/{cli/dist → dist}/core/crawler/selector-generator.js +99 -23
- package/dist/core/crawler/site-profiler.d.ts +89 -0
- package/dist/core/crawler/site-profiler.js +290 -0
- package/dist/core/crawler/sourcemaps-handler.d.ts +144 -0
- package/dist/core/crawler/sourcemaps-handler.js +420 -0
- package/dist/core/crawler/stacked-modals-handler.d.ts +118 -0
- package/dist/core/crawler/stacked-modals-handler.js +429 -0
- package/dist/core/crawler/trusted-types-handler.d.ts +149 -0
- package/dist/core/crawler/trusted-types-handler.js +413 -0
- package/{cli/dist → dist}/core/crawler/types.d.ts +68 -2
- package/dist/core/crawler/wait-strategies.d.ts +108 -0
- package/dist/core/crawler/wait-strategies.js +399 -0
- package/dist/core/fixtures/factories.d.ts +180 -0
- package/dist/core/fixtures/factories.js +279 -0
- package/dist/core/fixtures/index.d.ts +6 -0
- package/dist/core/fixtures/index.js +6 -0
- package/{cli/dist → dist}/core/generation/crawler-pack-generator.d.ts +13 -3
- package/dist/core/generation/crawler-pack-generator.js +232 -0
- package/{cli/dist → dist}/core/generation/index.d.ts +2 -0
- package/{cli/dist → dist}/core/generation/index.js +2 -0
- package/{cli/dist → dist}/core/index.d.ts +2 -0
- package/{cli/dist → dist}/core/index.js +4 -0
- package/dist/core/network/index.d.ts +7 -0
- package/dist/core/network/index.js +7 -0
- package/dist/core/network/network-manager.d.ts +237 -0
- package/dist/core/network/network-manager.js +343 -0
- package/dist/core/network/network-simulator.d.ts +158 -0
- package/dist/core/network/network-simulator.js +261 -0
- package/{cli/dist → dist}/core/pack/validator.js +2 -2
- package/{cli/dist → dist}/core/pack-v2/migrator.d.ts +5 -0
- package/{cli/dist → dist}/core/pack-v2/migrator.js +81 -6
- package/{cli/dist → dist}/core/pack-v2/validator.js +4 -3
- package/{cli/dist → dist}/core/pom/base-page.js +1 -1
- package/{cli/dist → dist}/core/pom/loader.js +1 -1
- package/dist/core/reporting/index.d.ts +9 -0
- package/dist/core/reporting/index.js +10 -0
- package/dist/core/reporting/junit-reporter.d.ts +114 -0
- package/dist/core/reporting/junit-reporter.js +306 -0
- package/{cli/dist → dist}/core/runner/e2e-helpers.d.ts +1 -1
- package/{cli/dist → dist}/core/runner/e2e-helpers.js +2 -2
- package/{cli/dist → dist}/core/runner/phase3-runner.d.ts +3 -0
- package/{cli/dist → dist}/core/runner/phase3-runner.js +45 -14
- package/dist/core/sharding/test-sharding.d.ts +137 -0
- package/dist/core/sharding/test-sharding.js +233 -0
- package/dist/core/storage/cookie-manager.d.ts +160 -0
- package/dist/core/storage/cookie-manager.js +268 -0
- package/dist/core/storage/index.d.ts +7 -0
- package/dist/core/storage/index.js +7 -0
- package/dist/core/storage/storage-helpers.d.ts +138 -0
- package/dist/core/storage/storage-helpers.js +315 -0
- package/dist/core/test-helpers/index.d.ts +6 -0
- package/dist/core/test-helpers/index.js +6 -0
- package/dist/core/test-helpers/state-reset.d.ts +119 -0
- package/dist/core/test-helpers/state-reset.js +234 -0
- package/{cli/dist → dist}/core/types/pack-v1.d.ts +15 -2
- package/{cli/dist → dist}/core/types/pack-v2.d.ts +1 -1
- package/dist/core/upload/chunked-uploader.d.ts +150 -0
- package/dist/core/upload/chunked-uploader.js +289 -0
- package/dist/core/upload/index.d.ts +11 -0
- package/dist/core/upload/index.js +8 -0
- package/dist/core/upload/mime-validator.d.ts +119 -0
- package/dist/core/upload/mime-validator.js +373 -0
- package/dist/core/upload/presigned-uploader.d.ts +118 -0
- package/dist/core/upload/presigned-uploader.js +274 -0
- package/dist/core/utils/device-emulation.d.ts +194 -0
- package/dist/core/utils/device-emulation.js +380 -0
- package/dist/core/utils/index.d.ts +8 -0
- package/dist/core/utils/index.js +8 -0
- package/dist/core/utils/retry.d.ts +145 -0
- package/dist/core/utils/retry.js +242 -0
- package/dist/core/utils/smart-wait.d.ts +133 -0
- package/dist/core/utils/smart-wait.js +417 -0
- package/dist/core/visual/index.d.ts +7 -0
- package/dist/core/visual/index.js +7 -0
- package/dist/core/visual/pixel-diff.d.ts +87 -0
- package/dist/core/visual/pixel-diff.js +213 -0
- package/dist/core/visual/screenshot-helper.d.ts +130 -0
- package/dist/core/visual/screenshot-helper.js +223 -0
- package/{cli/dist → dist}/utils/config.d.ts +1 -1
- package/examples/README.md +160 -0
- package/examples/accessibility.yml +48 -0
- package/examples/api-basic.yml +27 -0
- package/examples/complete.yml +146 -0
- package/examples/crawler.yml +38 -0
- package/examples/fullstack.yml +78 -0
- package/examples/security.yml +58 -0
- package/examples/ui-advanced.yml +49 -0
- package/examples/ui-basic.yml +24 -0
- package/package.json +33 -67
- package/CHANGELOG.md +0 -330
- package/CONTRIBUTING.md +0 -273
- package/QUICK_START.md +0 -191
- package/cli/CHANGELOG.md +0 -84
- package/cli/LICENSE +0 -24
- package/cli/README.md +0 -222
- package/cli/dist/core/adapters/playwright-ui.js +0 -864
- package/cli/dist/core/auth/oauth2-provider.js +0 -114
- package/cli/dist/core/coverage/analyzer.d.ts +0 -101
- package/cli/dist/core/coverage/analyzer.js +0 -415
- package/cli/dist/core/coverage/collector.d.ts +0 -74
- package/cli/dist/core/coverage/collector.js +0 -459
- package/cli/dist/core/coverage/config.d.ts +0 -37
- package/cli/dist/core/coverage/config.js +0 -156
- package/cli/dist/core/coverage/index.d.ts +0 -11
- package/cli/dist/core/coverage/index.js +0 -15
- package/cli/dist/core/coverage/types.d.ts +0 -267
- package/cli/dist/core/coverage/types.js +0 -6
- package/cli/dist/core/coverage/vault.d.ts +0 -95
- package/cli/dist/core/coverage/vault.js +0 -405
- package/cli/dist/core/crawler/index.d.ts +0 -57
- package/cli/dist/core/fixtures/index.d.ts +0 -8
- package/cli/dist/core/fixtures/index.js +0 -8
- package/cli/dist/core/generation/crawler-pack-generator.js +0 -231
- package/cli/dist/core/reporting/index.d.ts +0 -6
- package/cli/dist/core/reporting/index.js +0 -6
- package/cli/dist/core/visual/index.d.ts +0 -6
- package/cli/dist/core/visual/index.js +0 -6
- package/cli/package.json +0 -76
- package/core/LICENSE +0 -24
- package/core/README.md +0 -105
- package/core/package.json +0 -90
- package/core/schemas/pack.schema.json +0 -236
- /package/{cli/bin → bin}/qa360.js +0 -0
- /package/{cli/dist → dist}/cli-minimal.d.ts +0 -0
- /package/{cli/dist → dist}/cli-minimal.js +0 -0
- /package/{cli/dist → dist}/commands/ai.d.ts +0 -0
- /package/{cli/dist → dist}/commands/ask.d.ts +0 -0
- /package/{cli/dist → dist}/commands/ask.js +0 -0
- /package/{cli/dist → dist}/commands/coverage.d.ts +0 -0
- /package/{cli/dist → dist}/commands/crawl.d.ts +0 -0
- /package/{cli/dist → dist}/commands/doctor.d.ts +0 -0
- /package/{cli/dist → dist}/commands/examples.d.ts +0 -0
- /package/{cli/dist → dist}/commands/examples.js +0 -0
- /package/{cli/dist → dist}/commands/explain.d.ts +0 -0
- /package/{cli/dist → dist}/commands/flakiness.d.ts +0 -0
- /package/{cli/dist → dist}/commands/generate.d.ts +0 -0
- /package/{cli/dist → dist}/commands/history.d.ts +0 -0
- /package/{cli/dist → dist}/commands/init.d.ts +0 -0
- /package/{cli/dist → dist}/commands/init.js +0 -0
- /package/{cli/dist → dist}/commands/monitor.d.ts +0 -0
- /package/{cli/dist → dist}/commands/ollama.d.ts +0 -0
- /package/{cli/dist → dist}/commands/pack.d.ts +0 -0
- /package/{cli/dist → dist}/commands/regression.d.ts +0 -0
- /package/{cli/dist → dist}/commands/repair.d.ts +0 -0
- /package/{cli/dist → dist}/commands/report.d.ts +0 -0
- /package/{cli/dist → dist}/commands/report.js +0 -0
- /package/{cli/dist → dist}/commands/retry.d.ts +0 -0
- /package/{cli/dist → dist}/commands/scan.d.ts +0 -0
- /package/{cli/dist → dist}/commands/scan.js +0 -0
- /package/{cli/dist → dist}/commands/secrets.d.ts +0 -0
- /package/{cli/dist → dist}/commands/serve.d.ts +0 -0
- /package/{cli/dist → dist}/commands/slo.d.ts +0 -0
- /package/{cli/dist → dist}/commands/verify.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.js +0 -0
- /package/{cli/dist → dist}/core/adapters/jest-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/jest-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/k6-perf.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/k6-perf.js +0 -0
- /package/{cli/dist → dist}/core/adapters/osv-deps.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/osv-deps.js +0 -0
- /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/pytest-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/pytest-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/semgrep-sast.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/semgrep-sast.js +0 -0
- /package/{cli/dist → dist}/core/adapters/unit-test-types.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/unit-test-types.js +0 -0
- /package/{cli/dist → dist}/core/adapters/vitest-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/vitest-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/zap-dast.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/zap-dast.js +0 -0
- /package/{cli/dist → dist}/core/ai/anthropic-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/anthropic-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/deepseek-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/deepseek-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/index.js +0 -0
- /package/{cli/dist → dist}/core/ai/llm-client.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/llm-client.js +0 -0
- /package/{cli/dist → dist}/core/ai/mock-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/mock-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/ollama-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/openai-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/openai-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/provider-factory.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/provider-factory.js +0 -0
- /package/{cli/dist → dist}/core/artifacts/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/artifacts/index.js +0 -0
- /package/{cli/dist → dist}/core/artifacts/ui-artifacts.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/engine.js +0 -0
- /package/{cli/dist → dist}/core/assertions/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/index.js +0 -0
- /package/{cli/dist → dist}/core/assertions/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/types.js +0 -0
- /package/{cli/dist → dist}/core/auth/api-key-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/api-key-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/aws-iam-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/aws-iam-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/azure-ad-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/azure-ad-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/gcp-adc-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/gcp-adc-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/jwt-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/jwt-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/manager.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/manager.js +0 -0
- /package/{cli/dist → dist}/core/auth/totp-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/totp-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/ui-login-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/ui-login-provider.js +0 -0
- /package/{cli/dist → dist}/core/cache/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/cache/index.js +0 -0
- /package/{cli/dist → dist}/core/cache/lru-cache.d.ts +0 -0
- /package/{cli/dist → dist}/core/cache/lru-cache.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/analyzer.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/analyzer.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/collector.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/collector.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/config.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/config.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/index.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/index.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/types.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/types.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/vault.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/vault.js +0 -0
- /package/{cli/dist → dist}/core/crawler/journey-generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/crawler/types.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/assets.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/assets.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/index.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/server.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/server.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/types.js +0 -0
- /package/{cli/dist → dist}/core/discoverer/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/discoverer/index.js +0 -0
- /package/{cli/dist → dist}/core/fixtures/loader.d.ts +0 -0
- /package/{cli/dist → dist}/core/fixtures/loader.js +0 -0
- /package/{cli/dist → dist}/core/fixtures/resolver.d.ts +0 -0
- /package/{cli/dist → dist}/core/fixtures/resolver.js +0 -0
- /package/{cli/dist → dist}/core/fixtures/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/fixtures/types.js +0 -0
- /package/{cli/dist → dist}/core/flakiness/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/flakiness/index.js +0 -0
- /package/{cli/dist → dist}/core/generation/code-formatter.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/code-formatter.js +0 -0
- /package/{cli/dist → dist}/core/generation/code-generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/code-generator.js +0 -0
- /package/{cli/dist → dist}/core/generation/generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/generator.js +0 -0
- /package/{cli/dist → dist}/core/generation/pack-generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/pack-generator.js +0 -0
- /package/{cli/dist → dist}/core/generation/prompt-builder.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/prompt-builder.js +0 -0
- /package/{cli/dist → dist}/core/generation/source-analyzer.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/source-analyzer.js +0 -0
- /package/{cli/dist → dist}/core/generation/test-optimizer.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/test-optimizer.js +0 -0
- /package/{cli/dist → dist}/core/generation/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/types.js +0 -0
- /package/{cli/dist → dist}/core/hooks/compose.d.ts +0 -0
- /package/{cli/dist → dist}/core/hooks/compose.js +0 -0
- /package/{cli/dist → dist}/core/hooks/runner.d.ts +0 -0
- /package/{cli/dist → dist}/core/hooks/runner.js +0 -0
- /package/{cli/dist → dist}/core/pack/migrator.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack/migrator.js +0 -0
- /package/{cli/dist → dist}/core/pack/validator.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack-v2/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack-v2/index.js +0 -0
- /package/{cli/dist → dist}/core/pack-v2/loader.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack-v2/loader.js +0 -0
- /package/{cli/dist → dist}/core/pack-v2/validator.d.ts +0 -0
- /package/{cli/dist → dist}/core/parallel/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/parallel/index.js +0 -0
- /package/{cli/dist → dist}/core/parallel/parallel-runner.d.ts +0 -0
- /package/{cli/dist → dist}/core/parallel/parallel-runner.js +0 -0
- /package/{cli/dist → dist}/core/pom/base-page.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/index.js +0 -0
- /package/{cli/dist → dist}/core/pom/loader.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/types.js +0 -0
- /package/{cli/dist → dist}/core/proof/bundle.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/bundle.js +0 -0
- /package/{cli/dist → dist}/core/proof/canonicalize.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/canonicalize.js +0 -0
- /package/{cli/dist → dist}/core/proof/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/index.js +0 -0
- /package/{cli/dist → dist}/core/proof/schema.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/schema.js +0 -0
- /package/{cli/dist → dist}/core/proof/signer.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/signer.js +0 -0
- /package/{cli/dist → dist}/core/proof/verifier.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/verifier.js +0 -0
- /package/{cli/dist → dist}/core/regression/detector.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/detector.js +0 -0
- /package/{cli/dist → dist}/core/regression/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/index.js +0 -0
- /package/{cli/dist → dist}/core/regression/trend-analyzer.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/trend-analyzer.js +0 -0
- /package/{cli/dist → dist}/core/regression/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/types.js +0 -0
- /package/{cli/dist → dist}/core/regression/vault.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/vault.js +0 -0
- /package/{cli/dist → dist}/core/repair/engine/fixer.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/engine/fixer.js +0 -0
- /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.js +0 -0
- /package/{cli/dist → dist}/core/repair/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/index.js +0 -0
- /package/{cli/dist → dist}/core/repair/repairer.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/repairer.js +0 -0
- /package/{cli/dist → dist}/core/repair/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/types.js +0 -0
- /package/{cli/dist → dist}/core/repair/utils/error-analyzer.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/utils/error-analyzer.js +0 -0
- /package/{cli/dist → dist}/core/reporting/html-reporter.d.ts +0 -0
- /package/{cli/dist → dist}/core/reporting/html-reporter.js +0 -0
- /package/{cli/dist → dist}/core/retry/flakiness-integration.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/flakiness-integration.js +0 -0
- /package/{cli/dist → dist}/core/retry/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/index.js +0 -0
- /package/{cli/dist → dist}/core/retry/retry-engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/retry-engine.js +0 -0
- /package/{cli/dist → dist}/core/retry/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/types.js +0 -0
- /package/{cli/dist → dist}/core/retry/vault.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/vault.js +0 -0
- /package/{cli/dist → dist}/core/schemas/pack.schema.json +0 -0
- /package/{cli/dist → dist}/core/secrets/crypto.d.ts +0 -0
- /package/{cli/dist → dist}/core/secrets/crypto.js +0 -0
- /package/{cli/dist → dist}/core/secrets/manager.d.ts +0 -0
- /package/{cli/dist → dist}/core/secrets/manager.js +0 -0
- /package/{cli/dist → dist}/core/security/redaction-patterns-extended.d.ts +0 -0
- /package/{cli/dist → dist}/core/security/redaction-patterns-extended.js +0 -0
- /package/{cli/dist → dist}/core/security/redactor.d.ts +0 -0
- /package/{cli/dist → dist}/core/security/redactor.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/assertion-healer.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/assertion-healer.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/engine.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/index.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/selector-healer.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/selector-healer.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/types.js +0 -0
- /package/{cli/dist → dist}/core/serve/diagnostics-collector.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/diagnostics-collector.js +0 -0
- /package/{cli/dist → dist}/core/serve/health-checker.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/health-checker.js +0 -0
- /package/{cli/dist → dist}/core/serve/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/index.js +0 -0
- /package/{cli/dist → dist}/core/serve/metrics-collector.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/metrics-collector.js +0 -0
- /package/{cli/dist → dist}/core/serve/process-manager.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/process-manager.js +0 -0
- /package/{cli/dist → dist}/core/serve/server.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/server.js +0 -0
- /package/{cli/dist → dist}/core/slo/config.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/config.js +0 -0
- /package/{cli/dist → dist}/core/slo/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/index.js +0 -0
- /package/{cli/dist → dist}/core/slo/sli-calculator.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/sli-calculator.js +0 -0
- /package/{cli/dist → dist}/core/slo/slo-tracker.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/slo-tracker.js +0 -0
- /package/{cli/dist → dist}/core/slo/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/types.js +0 -0
- /package/{cli/dist → dist}/core/slo/vault.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/vault.js +0 -0
- /package/{cli/dist → dist}/core/tui/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/index.js +0 -0
- /package/{cli/dist → dist}/core/tui/monitor.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/monitor.js +0 -0
- /package/{cli/dist → dist}/core/tui/renderer.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/renderer.js +0 -0
- /package/{cli/dist → dist}/core/tui/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/types.js +0 -0
- /package/{cli/dist → dist}/core/types/pack-v1.js +0 -0
- /package/{cli/dist → dist}/core/types/pack-v2.js +0 -0
- /package/{cli/dist → dist}/core/types/trust-score.d.ts +0 -0
- /package/{cli/dist → dist}/core/types/trust-score.js +0 -0
- /package/{cli/dist → dist}/core/vault/cas.d.ts +0 -0
- /package/{cli/dist → dist}/core/vault/cas.js +0 -0
- /package/{cli/dist → dist}/core/vault/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/vault/index.js +0 -0
- /package/{cli/dist → dist}/core/visual/visual-regression.d.ts +0 -0
- /package/{cli/dist → dist}/core/visual/visual-regression.js +0 -0
- /package/{cli/dist → dist}/core/watch/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/watch/index.js +0 -0
- /package/{cli/dist → dist}/core/watch/watch-mode.d.ts +0 -0
- /package/{cli/dist → dist}/core/watch/watch-mode.js +0 -0
- /package/{cli/dist → dist}/generators/index.d.ts +0 -0
- /package/{cli/dist → dist}/generators/index.js +0 -0
- /package/{cli/dist → dist}/generators/json-reporter.d.ts +0 -0
- /package/{cli/dist → dist}/generators/json-reporter.js +0 -0
- /package/{cli/dist → dist}/generators/test-generator.d.ts +0 -0
- /package/{cli/dist → dist}/generators/test-generator.js +0 -0
- /package/{cli/dist → dist}/index.d.ts +0 -0
- /package/{cli/dist → dist}/index.js +0 -0
- /package/{cli/dist → dist}/scanners/dom-scanner.d.ts +0 -0
- /package/{cli/dist → dist}/scanners/dom-scanner.js +0 -0
- /package/{cli/dist → dist}/scanners/index.d.ts +0 -0
- /package/{cli/dist → dist}/scanners/index.js +0 -0
- /package/{cli/dist → dist}/schemas/pack.schema.json +0 -0
- /package/{cli/dist → dist}/types/scan.d.ts +0 -0
- /package/{cli/dist → dist}/types/scan.js +0 -0
- /package/{cli/dist → dist}/utils/config.js +0 -0
|
@@ -10,9 +10,22 @@ export interface ApiTarget {
|
|
|
10
10
|
baseUrl: string;
|
|
11
11
|
smoke?: string[];
|
|
12
12
|
}
|
|
13
|
+
/** Page action for UI tests */
|
|
14
|
+
export interface PageAction {
|
|
15
|
+
type: 'goto' | 'navigate' | 'click' | 'fill' | 'select' | 'check' | 'uncheck' | 'wait' | 'waitFor' | 'screenshot' | 'assert';
|
|
16
|
+
selector?: string;
|
|
17
|
+
value?: string;
|
|
18
|
+
options?: Record<string, unknown>;
|
|
19
|
+
}
|
|
20
|
+
/** Page with optional actions */
|
|
21
|
+
export interface PageWithActions {
|
|
22
|
+
url: string;
|
|
23
|
+
actions?: PageAction[];
|
|
24
|
+
}
|
|
13
25
|
export interface WebTarget {
|
|
14
26
|
baseUrl: string;
|
|
15
|
-
|
|
27
|
+
/** Pages can be strings or objects with actions */
|
|
28
|
+
pages?: (string | PageWithActions)[];
|
|
16
29
|
/** Browser mode: true for headed (visible), false for headless (default) */
|
|
17
30
|
headless?: boolean;
|
|
18
31
|
/** Slow motion delay in ms between actions (for debugging) */
|
|
@@ -36,7 +49,7 @@ export interface WebTarget {
|
|
|
36
49
|
uiTests?: UiTestDefinition[];
|
|
37
50
|
}
|
|
38
51
|
/** UI Test Step Action */
|
|
39
|
-
export type UiAction = 'navigate' | 'click' | 'dblClick' | 'rightClick' | 'hover' | 'focus' | 'fill' | 'type' | 'clear' | 'select' | 'check' | 'uncheck' | 'upload' | 'press' | 'waitFor' | 'waitForSelector' | 'waitForNavigation' | 'waitForTimeout' | 'scroll' | 'dragAndDrop' | 'tap';
|
|
52
|
+
export type UiAction = 'navigate' | 'click' | 'dblClick' | 'rightClick' | 'hover' | 'focus' | 'fill' | 'type' | 'clear' | 'select' | 'check' | 'uncheck' | 'upload' | 'press' | 'waitFor' | 'waitForSelector' | 'waitForNavigation' | 'waitForTimeout' | 'scroll' | 'dragAndDrop' | 'tap' | 'expectDialog' | 'clickAndWaitForPopup' | 'switchToTab' | 'closeTab' | 'waitForNewTab' | 'switchToFrame' | 'switchToMainFrame' | 'waitForFrame' | 'clickInFrame' | 'fillInFrame' | 'clickShadow' | 'fillShadow' | 'waitForShadow' | 'clickAndDownload' | 'waitForDownload' | 'mockRoute' | 'unmockRoute' | 'waitForResponse' | 'setLocalStorage' | 'getLocalStorage' | 'clearLocalStorage' | 'setSessionStorage' | 'getSessionStorage' | 'clearSessionStorage' | 'setCookie' | 'getCookie' | 'clearCookies' | 'grantPermissions' | 'setGeolocation' | 'clearGeolocation' | 'setViewport' | 'emulateDevice' | 'touchAction' | 'retry' | 'waitForFunction' | 'evaluate' | 'waitForURL' | 'reload' | 'goBack' | 'goForward' | 'analyzeSite' | 'handleConsent' | 'generateSelector' | 'assertVisible' | 'assertHidden' | 'assertAttached' | 'assertText' | 'assertContains' | 'assertValue' | 'assertAttribute' | 'assertClass' | 'assertCount' | 'assertURL' | 'assertTitle' | 'assertEnabled' | 'assertDisabled' | 'assertChecked' | 'assertUnchecked' | 'assertFocused' | 'assertEmpty' | 'assertNotEmpty' | 'assertReadOnly' | 'assertEditable' | 'assertSelected' | 'assertHref' | 'assertSrc' | 'assertPlaceholder' | 'assertID' | 'assertTagName' | 'assertCSS' | 'assertInViewport' | 'assertHasAttribute' | 'screenshot' | 'hoverScreenshot' | 'fullPageScreenshot' | 'waitForLoadState' | 'waitForSelectorState' | 'selectOption' | 'deselectOption' | 'focus' | 'blur' | 'highlight' | 'getHTML' | 'getText' | 'getAttribute' | 'getBoundingBox' | 'getElementCount' | 'getAllText' | 'getTableData' | 'waitForText' | 'waitForValue' | 'waitForClass' | 'waitForAttribute' | 'waitForEnabled' | 'waitForDisabled';
|
|
40
53
|
/** UI Test Step */
|
|
41
54
|
export interface UiTestStep {
|
|
42
55
|
/** Step order */
|
|
@@ -415,7 +415,7 @@ export interface WebPage {
|
|
|
415
415
|
* Page action for UI tests
|
|
416
416
|
*/
|
|
417
417
|
export interface PageAction {
|
|
418
|
-
type: 'goto' | 'click' | 'fill' | 'select' | 'wait' | 'screenshot' | 'assert';
|
|
418
|
+
type: 'goto' | 'navigate' | 'click' | 'fill' | 'select' | 'check' | 'uncheck' | 'wait' | 'waitFor' | 'screenshot' | 'assert';
|
|
419
419
|
selector?: string;
|
|
420
420
|
value?: string;
|
|
421
421
|
options?: Record<string, unknown>;
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chunked File Uploader
|
|
3
|
+
*
|
|
4
|
+
* Handles large file uploads by splitting them into chunks.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Configurable chunk size
|
|
7
|
+
* - Progress tracking
|
|
8
|
+
* - Retry failed chunks
|
|
9
|
+
* - Parallel chunk upload
|
|
10
|
+
* - Pause/resume functionality
|
|
11
|
+
*/
|
|
12
|
+
export interface ChunkUploadConfig {
|
|
13
|
+
/** Size of each chunk in bytes (default: 5MB) */
|
|
14
|
+
chunkSize?: number;
|
|
15
|
+
/** Number of parallel uploads (default: 3) */
|
|
16
|
+
parallelUploads?: number;
|
|
17
|
+
/** Max retries per chunk (default: 3) */
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
/** Delay between retries in ms (default: 1000) */
|
|
20
|
+
retryDelay?: number;
|
|
21
|
+
/** Upload endpoint */
|
|
22
|
+
endpoint: string;
|
|
23
|
+
/** Headers to include with each chunk request */
|
|
24
|
+
headers?: Record<string, string>;
|
|
25
|
+
/** Query params for the upload request */
|
|
26
|
+
params?: Record<string, string>;
|
|
27
|
+
/** Additional form data fields */
|
|
28
|
+
fields?: Record<string, string>;
|
|
29
|
+
/** File field name (default: 'file') */
|
|
30
|
+
fileField?: string;
|
|
31
|
+
/** Chunk index field name (default: 'chunkIndex') */
|
|
32
|
+
chunkIndexField?: string;
|
|
33
|
+
/** Total chunks field name (default: 'totalChunks') */
|
|
34
|
+
totalChunksField?: string;
|
|
35
|
+
/** File ID field name (for resume, default: 'fileId') */
|
|
36
|
+
fileIdField?: string;
|
|
37
|
+
/** Progress callback */
|
|
38
|
+
onProgress?: (progress: UploadProgress) => void;
|
|
39
|
+
}
|
|
40
|
+
export interface UploadProgress {
|
|
41
|
+
/** Bytes uploaded */
|
|
42
|
+
uploaded: number;
|
|
43
|
+
/** Total bytes */
|
|
44
|
+
total: number;
|
|
45
|
+
/** Percentage (0-100) */
|
|
46
|
+
percentage: number;
|
|
47
|
+
/** Current chunk index */
|
|
48
|
+
chunkIndex: number;
|
|
49
|
+
/** Total chunks */
|
|
50
|
+
totalChunks: number;
|
|
51
|
+
/** Upload speed in bytes/second */
|
|
52
|
+
speed?: number;
|
|
53
|
+
/** Estimated remaining time in seconds */
|
|
54
|
+
remaining?: number;
|
|
55
|
+
}
|
|
56
|
+
export interface ChunkUploadResult {
|
|
57
|
+
/** Upload success status */
|
|
58
|
+
success: boolean;
|
|
59
|
+
/** File ID from server (for resume/combine) */
|
|
60
|
+
fileId?: string;
|
|
61
|
+
/** Server response */
|
|
62
|
+
response?: any;
|
|
63
|
+
/** Error if failed */
|
|
64
|
+
error?: string;
|
|
65
|
+
/** Upload progress */
|
|
66
|
+
progress: UploadProgress;
|
|
67
|
+
}
|
|
68
|
+
export interface ChunkInfo {
|
|
69
|
+
index: number;
|
|
70
|
+
start: number;
|
|
71
|
+
end: number;
|
|
72
|
+
size: number;
|
|
73
|
+
data: Blob;
|
|
74
|
+
retries: number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Chunked file uploader class
|
|
78
|
+
*/
|
|
79
|
+
export declare class ChunkedUploader {
|
|
80
|
+
private config;
|
|
81
|
+
private aborted;
|
|
82
|
+
private paused;
|
|
83
|
+
private uploadStartTime;
|
|
84
|
+
private lastProgressUpdate;
|
|
85
|
+
private fileId?;
|
|
86
|
+
private uploadedChunks;
|
|
87
|
+
constructor(config: ChunkUploadConfig);
|
|
88
|
+
/**
|
|
89
|
+
* Upload a file in chunks
|
|
90
|
+
*/
|
|
91
|
+
upload(file: File | Blob, fileId?: string): Promise<ChunkUploadResult>;
|
|
92
|
+
/**
|
|
93
|
+
* Create file chunks
|
|
94
|
+
*/
|
|
95
|
+
private createChunks;
|
|
96
|
+
/**
|
|
97
|
+
* Upload chunks with parallel processing
|
|
98
|
+
*/
|
|
99
|
+
private uploadChunks;
|
|
100
|
+
/**
|
|
101
|
+
* Upload a single chunk
|
|
102
|
+
*/
|
|
103
|
+
private uploadChunk;
|
|
104
|
+
/**
|
|
105
|
+
* Finalize upload (combine chunks on server)
|
|
106
|
+
*/
|
|
107
|
+
private finalizeUpload;
|
|
108
|
+
/**
|
|
109
|
+
* Get current progress
|
|
110
|
+
*/
|
|
111
|
+
private getProgress;
|
|
112
|
+
/**
|
|
113
|
+
* Report progress (throttled to avoid excessive updates)
|
|
114
|
+
*/
|
|
115
|
+
private reportProgress;
|
|
116
|
+
/**
|
|
117
|
+
* Pause the upload
|
|
118
|
+
*/
|
|
119
|
+
pause(): void;
|
|
120
|
+
/**
|
|
121
|
+
* Resume the upload
|
|
122
|
+
*/
|
|
123
|
+
resume(): void;
|
|
124
|
+
/**
|
|
125
|
+
* Abort the upload
|
|
126
|
+
*/
|
|
127
|
+
abort(): void;
|
|
128
|
+
/**
|
|
129
|
+
* Check if upload is paused
|
|
130
|
+
*/
|
|
131
|
+
isPaused(): boolean;
|
|
132
|
+
/**
|
|
133
|
+
* Check if upload is aborted
|
|
134
|
+
*/
|
|
135
|
+
isAborted(): boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Generate a unique file ID
|
|
138
|
+
*/
|
|
139
|
+
private generateFileId;
|
|
140
|
+
private sleep;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Create a chunked uploader instance
|
|
144
|
+
*/
|
|
145
|
+
export declare function createChunkedUploader(config: ChunkUploadConfig): ChunkedUploader;
|
|
146
|
+
/**
|
|
147
|
+
* Upload a file in chunks (convenience function)
|
|
148
|
+
*/
|
|
149
|
+
export declare function uploadFileInChunks(file: File | Blob, config: ChunkUploadConfig): Promise<ChunkUploadResult>;
|
|
150
|
+
export default ChunkedUploader;
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chunked File Uploader
|
|
3
|
+
*
|
|
4
|
+
* Handles large file uploads by splitting them into chunks.
|
|
5
|
+
* Supports:
|
|
6
|
+
* - Configurable chunk size
|
|
7
|
+
* - Progress tracking
|
|
8
|
+
* - Retry failed chunks
|
|
9
|
+
* - Parallel chunk upload
|
|
10
|
+
* - Pause/resume functionality
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Chunked file uploader class
|
|
14
|
+
*/
|
|
15
|
+
export class ChunkedUploader {
|
|
16
|
+
config;
|
|
17
|
+
aborted = false;
|
|
18
|
+
paused = false;
|
|
19
|
+
uploadStartTime = 0;
|
|
20
|
+
lastProgressUpdate = 0;
|
|
21
|
+
fileId;
|
|
22
|
+
uploadedChunks = new Set();
|
|
23
|
+
constructor(config) {
|
|
24
|
+
this.config = {
|
|
25
|
+
chunkSize: config.chunkSize || 5 * 1024 * 1024, // 5MB default
|
|
26
|
+
parallelUploads: config.parallelUploads || 3,
|
|
27
|
+
maxRetries: config.maxRetries || 3,
|
|
28
|
+
retryDelay: config.retryDelay || 1000,
|
|
29
|
+
endpoint: config.endpoint,
|
|
30
|
+
headers: config.headers || {},
|
|
31
|
+
params: config.params || {},
|
|
32
|
+
fields: config.fields || {},
|
|
33
|
+
fileField: config.fileField || 'file',
|
|
34
|
+
chunkIndexField: config.chunkIndexField || 'chunkIndex',
|
|
35
|
+
totalChunksField: config.totalChunksField || 'totalChunks',
|
|
36
|
+
fileIdField: config.fileIdField || 'fileId',
|
|
37
|
+
onProgress: config.onProgress || (() => { }),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Upload a file in chunks
|
|
42
|
+
*/
|
|
43
|
+
async upload(file, fileId) {
|
|
44
|
+
this.aborted = false;
|
|
45
|
+
this.paused = false;
|
|
46
|
+
this.uploadStartTime = Date.now();
|
|
47
|
+
this.fileId = fileId;
|
|
48
|
+
this.uploadedChunks.clear();
|
|
49
|
+
const fileSize = file.size;
|
|
50
|
+
const totalChunks = Math.ceil(fileSize / this.config.chunkSize);
|
|
51
|
+
// Create chunks
|
|
52
|
+
const chunks = this.createChunks(file, totalChunks);
|
|
53
|
+
// Upload chunks
|
|
54
|
+
try {
|
|
55
|
+
await this.uploadChunks(chunks, fileSize, totalChunks);
|
|
56
|
+
if (this.aborted) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: 'Upload aborted',
|
|
60
|
+
progress: this.getProgress(fileSize, totalChunks, 0),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Combine chunks on server (if needed)
|
|
64
|
+
const result = await this.finalizeUpload(fileId || this.generateFileId(), totalChunks, file);
|
|
65
|
+
return {
|
|
66
|
+
success: true,
|
|
67
|
+
fileId: result.fileId,
|
|
68
|
+
response: result.response,
|
|
69
|
+
progress: this.getProgress(fileSize, totalChunks, totalChunks),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
error: error instanceof Error ? error.message : 'Upload failed',
|
|
76
|
+
progress: this.getProgress(fileSize, totalChunks, this.uploadedChunks.size),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Create file chunks
|
|
82
|
+
*/
|
|
83
|
+
createChunks(file, totalChunks) {
|
|
84
|
+
const chunks = [];
|
|
85
|
+
for (let i = 0; i < totalChunks; i++) {
|
|
86
|
+
const start = i * this.config.chunkSize;
|
|
87
|
+
const end = Math.min(start + this.config.chunkSize, file.size);
|
|
88
|
+
const size = end - start;
|
|
89
|
+
chunks.push({
|
|
90
|
+
index: i,
|
|
91
|
+
start,
|
|
92
|
+
end,
|
|
93
|
+
size,
|
|
94
|
+
data: file.slice(start, end),
|
|
95
|
+
retries: 0,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return chunks;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Upload chunks with parallel processing
|
|
102
|
+
*/
|
|
103
|
+
async uploadChunks(chunks, fileSize, totalChunks) {
|
|
104
|
+
const queue = [...chunks];
|
|
105
|
+
const activeUploads = [];
|
|
106
|
+
while (queue.length > 0 && !this.aborted) {
|
|
107
|
+
while (this.paused) {
|
|
108
|
+
await this.sleep(100);
|
|
109
|
+
}
|
|
110
|
+
while (activeUploads.length < this.config.parallelUploads && queue.length > 0) {
|
|
111
|
+
const chunk = queue.shift();
|
|
112
|
+
const uploadPromise = this.uploadChunk(chunk, fileSize, totalChunks)
|
|
113
|
+
.then(() => {
|
|
114
|
+
activeUploads.splice(activeUploads.indexOf(uploadPromise), 1);
|
|
115
|
+
})
|
|
116
|
+
.catch(async (error) => {
|
|
117
|
+
activeUploads.splice(activeUploads.indexOf(uploadPromise), 1);
|
|
118
|
+
if (chunk.retries < this.config.maxRetries) {
|
|
119
|
+
chunk.retries++;
|
|
120
|
+
queue.push(chunk);
|
|
121
|
+
await this.sleep(this.config.retryDelay);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
activeUploads.push(uploadPromise);
|
|
128
|
+
}
|
|
129
|
+
await Promise.race(activeUploads);
|
|
130
|
+
}
|
|
131
|
+
await Promise.all(activeUploads);
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Upload a single chunk
|
|
135
|
+
*/
|
|
136
|
+
async uploadChunk(chunk, fileSize, totalChunks) {
|
|
137
|
+
const formData = new FormData();
|
|
138
|
+
// Add chunk data
|
|
139
|
+
formData.append(this.config.fileField, chunk.data);
|
|
140
|
+
// Add chunk metadata
|
|
141
|
+
formData.append(this.config.chunkIndexField, chunk.index.toString());
|
|
142
|
+
formData.append(this.config.totalChunksField, totalChunks.toString());
|
|
143
|
+
// Add file ID if resuming
|
|
144
|
+
if (this.fileId) {
|
|
145
|
+
formData.append(this.config.fileIdField, this.fileId);
|
|
146
|
+
}
|
|
147
|
+
// Add additional fields
|
|
148
|
+
Object.entries(this.config.fields).forEach(([key, value]) => {
|
|
149
|
+
formData.append(key, value);
|
|
150
|
+
});
|
|
151
|
+
// Build URL with params
|
|
152
|
+
let url = this.config.endpoint;
|
|
153
|
+
const queryParams = new URLSearchParams(this.config.params).toString();
|
|
154
|
+
if (queryParams) {
|
|
155
|
+
url += (url.includes('?') ? '&' : '?') + queryParams;
|
|
156
|
+
}
|
|
157
|
+
const response = await fetch(url, {
|
|
158
|
+
method: 'POST',
|
|
159
|
+
headers: this.config.headers,
|
|
160
|
+
body: formData,
|
|
161
|
+
});
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
throw new Error(`Chunk ${chunk.index} upload failed: ${response.statusText}`);
|
|
164
|
+
}
|
|
165
|
+
const result = await response.json().catch(() => ({}));
|
|
166
|
+
// Store file ID from first chunk if provided
|
|
167
|
+
if (chunk.index === 0 && result.fileId) {
|
|
168
|
+
this.fileId = result.fileId;
|
|
169
|
+
}
|
|
170
|
+
this.uploadedChunks.add(chunk.index);
|
|
171
|
+
// Report progress
|
|
172
|
+
this.reportProgress(fileSize, totalChunks, chunk.index + 1);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Finalize upload (combine chunks on server)
|
|
176
|
+
*/
|
|
177
|
+
async finalizeUpload(fileId, totalChunks, file) {
|
|
178
|
+
// Some servers auto-combine, others need explicit finalize call
|
|
179
|
+
const formData = new FormData();
|
|
180
|
+
formData.append(this.config.fileIdField, fileId);
|
|
181
|
+
formData.append(this.config.totalChunksField, totalChunks.toString());
|
|
182
|
+
formData.append('fileName', file.name || 'upload');
|
|
183
|
+
formData.append('fileSize', file.size.toString());
|
|
184
|
+
let url = this.config.endpoint.replace(/\/chunk$/, '/finalize');
|
|
185
|
+
const queryParams = new URLSearchParams(this.config.params).toString();
|
|
186
|
+
if (queryParams) {
|
|
187
|
+
url += (url.includes('?') ? '&' : '?') + queryParams;
|
|
188
|
+
}
|
|
189
|
+
try {
|
|
190
|
+
const response = await fetch(url, {
|
|
191
|
+
method: 'POST',
|
|
192
|
+
headers: this.config.headers,
|
|
193
|
+
body: formData,
|
|
194
|
+
});
|
|
195
|
+
if (response.ok) {
|
|
196
|
+
const result = await response.json().catch(() => ({}));
|
|
197
|
+
return { fileId, response: result };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
catch {
|
|
201
|
+
// Finalize endpoint might not exist, server may auto-combine
|
|
202
|
+
}
|
|
203
|
+
return { fileId };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Get current progress
|
|
207
|
+
*/
|
|
208
|
+
getProgress(fileSize, totalChunks, completedChunks) {
|
|
209
|
+
const uploaded = completedChunks * this.config.chunkSize;
|
|
210
|
+
const total = fileSize;
|
|
211
|
+
const percentage = Math.min(100, (uploaded / total) * 100);
|
|
212
|
+
const elapsed = (Date.now() - this.uploadStartTime) / 1000;
|
|
213
|
+
const speed = elapsed > 0 ? uploaded / elapsed : 0;
|
|
214
|
+
const remaining = speed > 0 ? (total - uploaded) / speed : 0;
|
|
215
|
+
return {
|
|
216
|
+
uploaded: Math.min(uploaded, fileSize),
|
|
217
|
+
total,
|
|
218
|
+
percentage,
|
|
219
|
+
chunkIndex: completedChunks,
|
|
220
|
+
totalChunks,
|
|
221
|
+
speed,
|
|
222
|
+
remaining,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Report progress (throttled to avoid excessive updates)
|
|
227
|
+
*/
|
|
228
|
+
reportProgress(fileSize, totalChunks, completedChunks) {
|
|
229
|
+
const now = Date.now();
|
|
230
|
+
if (now - this.lastProgressUpdate < 100)
|
|
231
|
+
return; // Throttle to 100ms
|
|
232
|
+
this.lastProgressUpdate = now;
|
|
233
|
+
const progress = this.getProgress(fileSize, totalChunks, completedChunks);
|
|
234
|
+
this.config.onProgress(progress);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Pause the upload
|
|
238
|
+
*/
|
|
239
|
+
pause() {
|
|
240
|
+
this.paused = true;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Resume the upload
|
|
244
|
+
*/
|
|
245
|
+
resume() {
|
|
246
|
+
this.paused = false;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Abort the upload
|
|
250
|
+
*/
|
|
251
|
+
abort() {
|
|
252
|
+
this.aborted = true;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Check if upload is paused
|
|
256
|
+
*/
|
|
257
|
+
isPaused() {
|
|
258
|
+
return this.paused;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Check if upload is aborted
|
|
262
|
+
*/
|
|
263
|
+
isAborted() {
|
|
264
|
+
return this.aborted;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Generate a unique file ID
|
|
268
|
+
*/
|
|
269
|
+
generateFileId() {
|
|
270
|
+
return `${Date.now()}-${Math.random().toString(36).substring(2, 15)}`;
|
|
271
|
+
}
|
|
272
|
+
sleep(ms) {
|
|
273
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Create a chunked uploader instance
|
|
278
|
+
*/
|
|
279
|
+
export function createChunkedUploader(config) {
|
|
280
|
+
return new ChunkedUploader(config);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Upload a file in chunks (convenience function)
|
|
284
|
+
*/
|
|
285
|
+
export async function uploadFileInChunks(file, config) {
|
|
286
|
+
const uploader = new ChunkedUploader(config);
|
|
287
|
+
return uploader.upload(file);
|
|
288
|
+
}
|
|
289
|
+
export default ChunkedUploader;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upload Module
|
|
3
|
+
*
|
|
4
|
+
* File upload utilities for QA360
|
|
5
|
+
*/
|
|
6
|
+
export { ChunkedUploader, createChunkedUploader, uploadFileInChunks } from './chunked-uploader.js';
|
|
7
|
+
export type { ChunkUploadConfig, UploadProgress, ChunkUploadResult } from './chunked-uploader.js';
|
|
8
|
+
export { PresignedUploader, createPresignedUploader, uploadWithPresignedUrl, S3PresignedUploader, AzurePresignedUploader, } from './presigned-uploader.js';
|
|
9
|
+
export type { PresignedUrlConfig, PresignedUrlResponse, PresignedUploadResult } from './presigned-uploader.js';
|
|
10
|
+
export { MimeValidator, createMimeValidator, validateMimeType, getMimeTypeFromExtension, getExtensionFromMimeType, } from './mime-validator.js';
|
|
11
|
+
export type { MimeTypeConfig, MimeTypeValidationResult } from './mime-validator.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upload Module
|
|
3
|
+
*
|
|
4
|
+
* File upload utilities for QA360
|
|
5
|
+
*/
|
|
6
|
+
export { ChunkedUploader, createChunkedUploader, uploadFileInChunks } from './chunked-uploader.js';
|
|
7
|
+
export { PresignedUploader, createPresignedUploader, uploadWithPresignedUrl, S3PresignedUploader, AzurePresignedUploader, } from './presigned-uploader.js';
|
|
8
|
+
export { MimeValidator, createMimeValidator, validateMimeType, getMimeTypeFromExtension, getExtensionFromMimeType, } from './mime-validator.js';
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MIME Type Validator
|
|
3
|
+
*
|
|
4
|
+
* Validates file types using:
|
|
5
|
+
* - File extension (quick check)
|
|
6
|
+
* - Magic bytes (file signature)
|
|
7
|
+
* - Server-side MIME type validation
|
|
8
|
+
*
|
|
9
|
+
* Supports comprehensive file type detection for:
|
|
10
|
+
* - Images: JPEG, PNG, GIF, WebP, SVG, ICO, AVIF, HEIC
|
|
11
|
+
* - Documents: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX
|
|
12
|
+
* - Audio: MP3, WAV, OGG, FLAC, M4A
|
|
13
|
+
* - Video: MP4, WEBM, AVI, MOV, MKV
|
|
14
|
+
* - Archives: ZIP, RAR, 7Z, TAR, GZIP
|
|
15
|
+
* - And more...
|
|
16
|
+
*/
|
|
17
|
+
export interface MimeTypeConfig {
|
|
18
|
+
/** Allowed MIME types */
|
|
19
|
+
allowedTypes?: string[];
|
|
20
|
+
/** Allowed file extensions */
|
|
21
|
+
allowedExtensions?: string[];
|
|
22
|
+
/** Maximum file size in bytes */
|
|
23
|
+
maxSize?: number;
|
|
24
|
+
/** Use magic bytes validation (default: true) */
|
|
25
|
+
useMagicBytes?: boolean;
|
|
26
|
+
/** Custom MIME type mappings */
|
|
27
|
+
customMappings?: Record<string, string>;
|
|
28
|
+
}
|
|
29
|
+
export interface MimeTypeValidationResult {
|
|
30
|
+
/** Validation success */
|
|
31
|
+
valid: boolean;
|
|
32
|
+
/** Detected MIME type */
|
|
33
|
+
mimeType?: string;
|
|
34
|
+
/** Detected extension */
|
|
35
|
+
extension?: string;
|
|
36
|
+
/** File size in bytes */
|
|
37
|
+
size?: number;
|
|
38
|
+
/** Validation errors */
|
|
39
|
+
errors?: string[];
|
|
40
|
+
/** Warnings (non-blocking) */
|
|
41
|
+
warnings?: string[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* MIME type validator class
|
|
45
|
+
*/
|
|
46
|
+
export declare class MimeValidator {
|
|
47
|
+
private config;
|
|
48
|
+
private customMappings;
|
|
49
|
+
constructor(config?: MimeTypeConfig);
|
|
50
|
+
/**
|
|
51
|
+
* Validate a file
|
|
52
|
+
*/
|
|
53
|
+
validate(file: File | Blob): Promise<MimeTypeValidationResult>;
|
|
54
|
+
/**
|
|
55
|
+
* Detect MIME type using magic bytes
|
|
56
|
+
*/
|
|
57
|
+
detectMimeType(file: File | Blob): Promise<string | undefined>;
|
|
58
|
+
/**
|
|
59
|
+
* Detect MIME type from magic bytes (file signature)
|
|
60
|
+
*/
|
|
61
|
+
private detectFromMagicBytes;
|
|
62
|
+
/**
|
|
63
|
+
* Check if bytes match signature at offset
|
|
64
|
+
*/
|
|
65
|
+
private matchesMagicBytes;
|
|
66
|
+
/**
|
|
67
|
+
* Check if MIME type is allowed
|
|
68
|
+
*/
|
|
69
|
+
isAllowedType(mimeType: string): boolean;
|
|
70
|
+
/**
|
|
71
|
+
* Check if extension is allowed
|
|
72
|
+
*/
|
|
73
|
+
isAllowedExtension(extension: string): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Check if a string is a valid MIME type
|
|
76
|
+
*/
|
|
77
|
+
isValidMimeType(mimeType: string): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Get file extension from filename
|
|
80
|
+
*/
|
|
81
|
+
getExtension(fileName: string): string;
|
|
82
|
+
/**
|
|
83
|
+
* Get MIME type from extension
|
|
84
|
+
*/
|
|
85
|
+
getMimeTypeFromExtension(extension: string): string | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Get extension from MIME type
|
|
88
|
+
*/
|
|
89
|
+
getExtensionFromMimeType(mimeType: string): string | undefined;
|
|
90
|
+
/**
|
|
91
|
+
* Update allowed types
|
|
92
|
+
*/
|
|
93
|
+
setAllowedTypes(types: string[]): void;
|
|
94
|
+
/**
|
|
95
|
+
* Update allowed extensions
|
|
96
|
+
*/
|
|
97
|
+
setAllowedExtensions(extensions: string[]): void;
|
|
98
|
+
/**
|
|
99
|
+
* Update max size
|
|
100
|
+
*/
|
|
101
|
+
setMaxSize(size: number): void;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create a MIME validator instance
|
|
105
|
+
*/
|
|
106
|
+
export declare function createMimeValidator(config?: MimeTypeConfig): MimeValidator;
|
|
107
|
+
/**
|
|
108
|
+
* Validate a file (convenience function)
|
|
109
|
+
*/
|
|
110
|
+
export declare function validateMimeType(file: File | Blob, config?: MimeTypeConfig): Promise<MimeTypeValidationResult>;
|
|
111
|
+
/**
|
|
112
|
+
* Get MIME type from extension
|
|
113
|
+
*/
|
|
114
|
+
export declare function getMimeTypeFromExtension(extension: string): string | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* Get extension from MIME type
|
|
117
|
+
*/
|
|
118
|
+
export declare function getExtensionFromMimeType(mimeType: string): string | undefined;
|
|
119
|
+
export default MimeValidator;
|