From 39c84709fbf44cbec8bb4021a2a55d86fb4d0bb5 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 27 Feb 2026 14:36:10 -0500 Subject: [PATCH 1/4] Add prod build --- .gitignore | 1 + package.json | 9 +++-- rollup.config.mjs | 91 ++++++++++++++++++++++++++--------------------- 3 files changed, 59 insertions(+), 42 deletions(-) diff --git a/.gitignore b/.gitignore index 4a4c99b4f3e..9bf32df156f 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ assets/bpm_libs.js assets/bpm_styles.css coverage dist +dist-prod /docs lib/*/tests/all.js lib/*/tests/qunit* diff --git a/package.json b/package.json index 97b545d7f6e..4dea45b9693 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,11 @@ "ember-addon" ], "exports": { - "./*": "./dist/packages/*", + "./*": { + "development": "./dist/packages/*", + "production": "./dist-prod/packages/*", + "default": "./dist/packages/*" + }, "./types": { "types": "./types/stable/index.d.ts" }, @@ -24,6 +28,7 @@ "blueprints", "dist/packages", "dist/dependencies", + "dist-prod/packages", "dist/ember-template-compiler.js", "dist/ember-template-compiler.js.map", "dist/ember.debug.js", @@ -390,4 +395,4 @@ } }, "packageManager": "pnpm@10.5.0" -} +} \ No newline at end of file diff --git a/rollup.config.mjs b/rollup.config.mjs index 6885fae4533..36e7e121b14 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -27,7 +27,7 @@ const testDependencies = [ let configs = [ esmConfig(), - esmTemplateCompiler(), + esmProdConfig(), legacyBundleConfig('./broccoli/amd-compat-entrypoints/ember.debug.js', 'ember.debug.js', { isDeveloping: true, }), @@ -55,34 +55,36 @@ export default configs; function esmConfig() { return sharedESMConfig({ - input: { - ...renameEntrypoints(exposedDependencies(), (name) => join('packages', name, 'index')), - ...renameEntrypoints(packages(), (name) => join('packages', name)), - }, + input: esmInputs(), debugMacrosMode: '@embroider/macros', + includePackageMeta: true, }); } -function esmTemplateCompiler() { +function esmProdConfig() { return sharedESMConfig({ - input: { - // the actual authored "./packages/ember-template-compiler/index.ts" is - // part of what powers the historical dist/ember-template-compiler.js AMD - // bundle. It has historical cruft that has never been present in our ESM - // builds. - // - // On the ESM build, the main entrypoint of ember-template-compiler is the - // "minimal.ts" version, which has a lot less in it. - - 'packages/ember-template-compiler/index': 'ember-template-compiler/minimal.ts', - }, - // the template compiler is always in debug mode (and doesn't use - // embroider/macros, so it's directly invokable on node) - debugMacrosMode: true, + input: esmInputs(), + debugMacrosMode: false, }); } -function sharedESMConfig({ input, debugMacrosMode }) { +function esmInputs() { + return { + ...renameEntrypoints(exposedDependencies(), (name) => join('packages', name, 'index')), + ...renameEntrypoints(packages(), (name) => join('packages', name)), + // the actual authored "./packages/ember-template-compiler/index.ts" is + // part of what powers the historical dist/ember-template-compiler.js AMD + // bundle. It has historical cruft that has never been present in our ESM + // builds. + // + // On the ESM build, the main entrypoint of ember-template-compiler is the + // "minimal.ts" version, which has a lot less in it. + 'packages/ember-template-compiler/index': 'ember-template-compiler/minimal.ts', + }; +} + +function sharedESMConfig({ input, debugMacrosMode, includePackageMeta = false }) { + let outputDir = debugMacrosMode === false ? 'dist-prod' : 'dist'; let babelConfig = { ...sharedBabelConfig }; babelConfig.plugins = [ ...babelConfig.plugins, @@ -90,29 +92,34 @@ function sharedESMConfig({ input, debugMacrosMode }) { canaryFeatures(), ]; + let plugins = [ + babel({ + babelHelpers: 'bundled', + extensions: ['.js', '.ts'], + configFile: false, + ...babelConfig, + }), + resolveTS(), + version(), + resolvePackages({ ...exposedDependencies(), ...hiddenDependencies() }), + pruneEmptyBundles(), + ]; + + if (includePackageMeta) { + plugins.push(packageMeta()); + } + return { onLog: handleRollupWarnings, input, output: { format: 'es', - dir: 'dist', + dir: outputDir, hoistTransitiveImports: false, generatedCode: 'es2015', chunkFileNames: 'packages/shared-chunks/[name]-[hash].js', }, - plugins: [ - babel({ - babelHelpers: 'bundled', - extensions: ['.js', '.ts'], - configFile: false, - ...babelConfig, - }), - resolveTS(), - version(), - resolvePackages({ ...exposedDependencies(), ...hiddenDependencies() }), - pruneEmptyBundles(), - packageMeta(), - ], + plugins, }; } @@ -148,7 +155,7 @@ function renameEntrypoints(entrypoints, fn) { function legacyBundleConfig(input, output, { isDeveloping, isExternal }) { let babelConfig = { ...sharedBabelConfig }; - babelConfig.plugins = [...babelConfig.plugins, buildDebugMacroPlugin(isDeveloping)]; + babelConfig.plugins = [...babelConfig.plugins]; return { input, @@ -644,11 +651,15 @@ function pruneEmptyBundles() { function packageMeta() { return { name: 'package-meta', - generateBundle() { + generateBundle(_outputOptions, bundle) { let renamedModules = Object.fromEntries( - glob - .sync('packages/**/*.js', { cwd: 'dist', nodir: true }) - .filter((name) => !name.startsWith('packages/shared-chunks/')) + Object.keys(bundle) + .filter( + (name) => + name.startsWith('packages/') && + !name.startsWith('packages/shared-chunks/') && + name.endsWith('.js') + ) .sort() .map((name) => { return [ From cdb86a49039524176018f3fe983df9cbe36b0747 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 27 Feb 2026 14:58:15 -0500 Subject: [PATCH 2/4] Update rollup to ditch the @embroider/macros --- rollup.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rollup.config.mjs b/rollup.config.mjs index 36e7e121b14..4e790dc28d9 100644 --- a/rollup.config.mjs +++ b/rollup.config.mjs @@ -56,7 +56,7 @@ export default configs; function esmConfig() { return sharedESMConfig({ input: esmInputs(), - debugMacrosMode: '@embroider/macros', + debugMacrosMode: true, includePackageMeta: true, }); } From 392e649e67c0eaa3dd2bad0631440b03175dc05d Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Thu, 19 Feb 2026 13:54:46 -0500 Subject: [PATCH 3/4] Migrate Node tests to ESM --- pnpm-lock.yaml | 1231 ++++++++++++++--- smoke-tests/node-template/package.json | 17 + .../node-template/tests/node/app-boot.test.js | 158 +++ .../tests/node/component-rendering.test.js | 51 + .../tests/node/fastboot-sandbox.test.js | 84 ++ .../tests/node/helpers/assert-html-matches.js | 16 + .../tests/node/helpers/build-owner.js | 38 + .../node/helpers/load-template-compiler.js | 3 + .../tests/node/helpers/macros-shim.js | 11 + .../tests/node/helpers/register-loader.js | 22 + .../tests/node/helpers/setup-app.js | 156 +++ .../tests/node/helpers/setup-component.js | 108 ++ .../tests/node/instrumentation.test.js | 19 + .../tests/node/overrides.test.js | 205 +++ .../tests/node/sourcemap.test.js | 25 + .../tests/node/template-compiler.test.js | 19 + .../node-template/tests/node/visit.test.js | 316 +++++ smoke-tests/scenarios/node-test.ts | 27 + smoke-tests/scenarios/scenarios.ts | 14 + tests/node/app-boot-test.js | 137 -- tests/node/component-rendering-test.js | 45 - tests/node/fastboot-sandbox-test.js | 120 -- tests/node/fixtures/project.js | 148 -- tests/node/helpers/assert-html-matches.js | 27 - tests/node/helpers/build-owner.js | 28 - tests/node/helpers/load-ember.js | 47 - tests/node/helpers/setup-app.js | 199 --- tests/node/helpers/setup-component.js | 111 -- tests/node/instrumentation-test.js | 25 - tests/node/overrides-test.js | 789 ----------- tests/node/sourcemap-test.js | 23 - tests/node/template-compiler-test.js | 68 - tests/node/visit-test.js | 357 ----- 33 files changed, 2343 insertions(+), 2301 deletions(-) create mode 100644 smoke-tests/node-template/package.json create mode 100644 smoke-tests/node-template/tests/node/app-boot.test.js create mode 100644 smoke-tests/node-template/tests/node/component-rendering.test.js create mode 100644 smoke-tests/node-template/tests/node/fastboot-sandbox.test.js create mode 100644 smoke-tests/node-template/tests/node/helpers/assert-html-matches.js create mode 100644 smoke-tests/node-template/tests/node/helpers/build-owner.js create mode 100644 smoke-tests/node-template/tests/node/helpers/load-template-compiler.js create mode 100644 smoke-tests/node-template/tests/node/helpers/macros-shim.js create mode 100644 smoke-tests/node-template/tests/node/helpers/register-loader.js create mode 100644 smoke-tests/node-template/tests/node/helpers/setup-app.js create mode 100644 smoke-tests/node-template/tests/node/helpers/setup-component.js create mode 100644 smoke-tests/node-template/tests/node/instrumentation.test.js create mode 100644 smoke-tests/node-template/tests/node/overrides.test.js create mode 100644 smoke-tests/node-template/tests/node/sourcemap.test.js create mode 100644 smoke-tests/node-template/tests/node/template-compiler.test.js create mode 100644 smoke-tests/node-template/tests/node/visit.test.js create mode 100644 smoke-tests/scenarios/node-test.ts delete mode 100644 tests/node/app-boot-test.js delete mode 100644 tests/node/component-rendering-test.js delete mode 100644 tests/node/fastboot-sandbox-test.js delete mode 100644 tests/node/fixtures/project.js delete mode 100644 tests/node/helpers/assert-html-matches.js delete mode 100644 tests/node/helpers/build-owner.js delete mode 100644 tests/node/helpers/load-ember.js delete mode 100644 tests/node/helpers/setup-app.js delete mode 100644 tests/node/helpers/setup-component.js delete mode 100644 tests/node/instrumentation-test.js delete mode 100644 tests/node/overrides-test.js delete mode 100644 tests/node/sourcemap-test.js delete mode 100644 tests/node/template-compiler-test.js delete mode 100644 tests/node/visit-test.js diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5e16a8f4afc..c64954f2bc0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,7 +20,7 @@ importers: dependencies: '@babel/core': specifier: ^7.24.4 - version: 7.29.0(supports-color@8.1.1) + version: 7.29.0 '@ember/edition-utils': specifier: ^1.2.0 version: 1.2.0 @@ -99,7 +99,7 @@ importers: version: 7.28.6(@babel/core@7.29.0) '@babel/preset-env': specifier: ^7.16.11 - version: 7.29.0(@babel/core@7.29.0)(supports-color@8.1.1) + version: 7.29.0(@babel/core@7.29.0) '@babel/types': specifier: ^7.22.5 version: 7.29.0 @@ -2803,7 +2803,7 @@ importers: devDependencies: '@babel/core': specifier: ^7.24.4 - version: 7.29.0(supports-color@8.1.1) + version: 7.29.0 '@ember/optional-features': specifier: ^2.3.0 version: 2.3.0 @@ -2926,7 +2926,7 @@ importers: devDependencies: '@babel/core': specifier: ^7.28.5 - version: 7.29.0(supports-color@8.1.1) + version: 7.29.0 '@babel/plugin-transform-runtime': specifier: ^7.28.5 version: 7.29.0(@babel/core@7.29.0) @@ -2967,6 +2967,15 @@ importers: specifier: ^7.3.0 version: 7.3.1(@types/node@22.19.11)(terser@5.46.0)(yaml@2.8.2) + smoke-tests/node-template: + dependencies: + html-differ: + specifier: ^1.4.0 + version: 1.4.0 + simple-dom: + specifier: ^1.4.0 + version: 1.4.0 + smoke-tests/scenarios: devDependencies: '@embroider/compat': @@ -3010,7 +3019,7 @@ importers: devDependencies: '@babel/core': specifier: ^7.27.1 - version: 7.29.0(supports-color@8.1.1) + version: 7.29.0 '@babel/eslint-parser': specifier: ^7.27.1 version: 7.28.6(@babel/core@7.29.0)(eslint@9.39.2) @@ -13853,6 +13862,26 @@ snapshots: '@babel/compat-data@7.29.0': {} + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3(supports-color@8.1.1) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + '@babel/core@7.29.0(supports-color@8.1.1)': dependencies: '@babel/code-frame': 7.29.0 @@ -13875,7 +13904,7 @@ snapshots: '@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@8.57.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 eslint: 8.57.1 eslint-visitor-keys: 2.1.0 @@ -13883,7 +13912,7 @@ snapshots: '@babel/eslint-parser@7.28.6(@babel/core@7.29.0)(eslint@9.39.2)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 eslint: 9.39.2 eslint-visitor-keys: 2.1.0 @@ -13916,27 +13945,61 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-member-expression-to-functions': 7.28.5(supports-color@8.1.1) '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5(supports-color@8.1.1) + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-class-features-plugin@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-member-expression-to-functions': 7.28.5(supports-color@8.1.1) + '@babel/helper-optimise-call-expression': 7.27.1 '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) '@babel/traverse': 7.29.0(supports-color@8.1.1) semver: 6.3.1 transitivePeerDependencies: - supports-color + optional: true - '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-annotate-as-pure': 7.27.3 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-compilation-targets': 7.28.6 @@ -13947,6 +14010,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-define-polyfill-provider@0.6.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3(supports-color@8.1.1) + lodash.debounce: 4.0.8 + resolve: 1.22.11 + transitivePeerDependencies: + - supports-color + '@babel/helper-environment-visitor@7.24.7': dependencies: '@babel/types': 7.29.0 @@ -13976,7 +14050,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) @@ -13985,13 +14059,31 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/helper-optimise-call-expression@7.27.1': dependencies: '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.28.6': {} - '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-annotate-as-pure': 7.27.3 @@ -14000,7 +14092,26 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-member-expression-to-functions': 7.28.5(supports-color@8.1.1) @@ -14009,6 +14120,25 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5(supports-color@8.1.1) + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5(supports-color@8.1.1) + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true + '@babel/helper-skip-transparent-expression-wrappers@7.27.1(supports-color@8.1.1)': dependencies: '@babel/traverse': 7.29.0(supports-color@8.1.1) @@ -14043,7 +14173,7 @@ snapshots: dependencies: '@babel/types': 7.29.0 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 @@ -14051,26 +14181,63 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) transitivePeerDependencies: - supports-color + optional: true - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 @@ -14078,18 +14245,26 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) transitivePeerDependencies: @@ -14097,21 +14272,25 @@ snapshots: '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color - '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) transitivePeerDependencies: @@ -14119,164 +14298,372 @@ snapshots: '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/traverse': 7.29.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color + optional: true - '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-globals': 7.28.0 + '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/traverse': 7.29.0(supports-color@8.1.1) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/template': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.29.0(supports-color@8.1.1) + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0)(supports-color@8.1.1) transitivePeerDependencies: - supports-color + optional: true - '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color + optional: true - '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-compilation-targets': 7.28.6 @@ -14285,159 +14672,405 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color + optional: true - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color + optional: true + + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color '@babel/plugin-transform-modules-systemjs@7.29.0(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.29.0(supports-color@8.1.1) - transitivePeerDependencies: - - supports-color + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + optional: true - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) - '@babel/traverse': 7.29.0(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-plugin-utils': 7.28.6 - - '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color + optional: true - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color - '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 transitivePeerDependencies: - supports-color + optional: true + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-runtime@7.29.0(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0)(supports-color@8.1.1) @@ -14447,39 +15080,76 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)(supports-color@8.1.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) transitivePeerDependencies: - supports-color + optional: true + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/helper-create-class-features-plugin': 7.28.6(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-skip-transparent-expression-wrappers': 7.27.1(supports-color@8.1.1) '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) @@ -14488,30 +15158,53 @@ snapshots: '@babel/plugin-transform-typescript@7.4.5(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': + dependencies: + '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) '@babel/helper-plugin-utils': 7.28.6 @@ -14520,13 +15213,165 @@ snapshots: core-js: 2.6.12 regenerator-runtime: 0.13.11 - '@babel/preset-env@7.29.0(@babel/core@7.29.0)(supports-color@8.1.1)': + '@babel/preset-env@7.29.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1)': dependencies: '@babel/compat-data': 7.29.0 '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0(supports-color@8.1.1)) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0(supports-color@8.1.1)) + babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + babel-plugin-polyfill-corejs3: 0.14.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + core-js-compat: 3.48.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-env@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.29.0)(supports-color@8.1.1) + babel-plugin-polyfill-corejs3: 0.14.0(@babel/core@7.29.0)(supports-color@8.1.1) + babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.29.0)(supports-color@8.1.1) + core-js-compat: 3.48.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-env@7.29.0(@babel/core@7.29.0)(supports-color@8.1.1)': + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0)(supports-color@8.1.1) '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) @@ -14595,14 +15440,22 @@ snapshots: semver: 6.3.1 transitivePeerDependencies: - supports-color + optional: true - '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0(supports-color@8.1.1))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@babel/helper-plugin-utils': 7.28.6 '@babel/types': 7.29.0 esutils: 2.0.3 + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 + esutils: 2.0.3 + '@babel/runtime@7.12.18': dependencies: regenerator-runtime: 0.13.11 @@ -15128,7 +15981,7 @@ snapshots: dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) '@embroider/core': 3.5.9 - babel-loader: 9.2.1(@babel/core@7.29.0)(webpack@5.105.1(@swc/core@1.15.11)) + babel-loader: 9.2.1(@babel/core@7.29.0(supports-color@8.1.1))(webpack@5.105.1(@swc/core@1.15.11)) transitivePeerDependencies: - supports-color - webpack @@ -15146,12 +15999,12 @@ snapshots: '@embroider/compat@3.9.3(@embroider/core@3.5.9)': dependencies: '@babel/code-frame': 7.29.0 - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) - '@babel/preset-env': 7.29.0(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.28.6 '@babel/traverse': 7.29.0(supports-color@8.1.1) '@embroider/core': 3.5.9 @@ -15199,12 +16052,12 @@ snapshots: '@embroider/compat@4.1.13(@embroider/core@4.4.3)': dependencies: '@babel/code-frame': 7.29.0 - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) - '@babel/preset-env': 7.29.0(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.28.6 '@babel/traverse': 7.29.0(supports-color@8.1.1) '@embroider/core': 4.4.3 @@ -15253,7 +16106,7 @@ snapshots: '@embroider/core@3.5.9': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/parser': 7.29.0 '@babel/traverse': 7.29.0(supports-color@8.1.1) '@embroider/macros': 1.19.7(@babel/core@7.29.0) @@ -15287,7 +16140,7 @@ snapshots: '@embroider/core@4.4.3': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/parser': 7.29.0 '@babel/traverse': 7.29.0(supports-color@8.1.1) '@embroider/macros': 1.19.7(@babel/core@7.29.0) @@ -15408,7 +16261,7 @@ snapshots: '@embroider/vite@1.5.2(@embroider/core@4.4.3)(rollup@4.57.1)(vite@5.4.21(@types/node@22.19.11)(terser@5.46.0))': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@embroider/core': 4.4.3 '@embroider/macros': 1.19.7(@babel/core@7.29.0) '@embroider/reverse-exports': 0.2.0 @@ -15436,7 +16289,7 @@ snapshots: '@embroider/vite@1.5.2(@embroider/core@4.4.3)(rollup@4.57.1)(vite@6.4.1(@types/node@22.19.11)(terser@5.46.0)(yaml@2.8.2))': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@embroider/core': 4.4.3 '@embroider/macros': 1.19.7(@babel/core@7.29.0) '@embroider/reverse-exports': 0.2.0 @@ -15464,7 +16317,7 @@ snapshots: '@embroider/vite@1.5.2(@embroider/core@4.4.3)(rollup@4.57.1)(vite@7.3.1(@types/node@22.19.11)(terser@5.46.0)(yaml@2.8.2))': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@embroider/core': 4.4.3 '@embroider/macros': 1.19.7(@babel/core@7.29.0) '@embroider/reverse-exports': 0.2.0 @@ -15493,14 +16346,14 @@ snapshots: '@embroider/webpack@4.1.2(@embroider/core@3.5.9)(webpack@5.105.1(@swc/core@1.15.11))': dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) - '@babel/preset-env': 7.29.0(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) '@embroider/babel-loader-9': 3.1.3(@embroider/core@3.5.9)(supports-color@8.1.1)(webpack@5.105.1(@swc/core@1.15.11)) '@embroider/core': 3.5.9 '@embroider/hbs-loader': 3.0.5(@embroider/core@3.5.9)(webpack@5.105.1(@swc/core@1.15.11)) '@embroider/shared-internals': 2.9.2(supports-color@8.1.1) '@types/supports-color': 8.1.3 assert-never: 1.4.0 - babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.105.1(@swc/core@1.15.11)) + babel-loader: 8.4.1(@babel/core@7.29.0(supports-color@8.1.1))(webpack@5.105.1(@swc/core@1.15.11)) css-loader: 5.2.7(webpack@5.105.1(@swc/core@1.15.11)) csso: 4.2.0 debug: 4.4.3(supports-color@8.1.1) @@ -16621,7 +17474,7 @@ snapshots: '@rollup/plugin-babel@6.1.0(@babel/core@7.29.0)(rollup@4.57.1)': dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-module-imports': 7.28.6(supports-color@8.1.1) '@rollup/pluginutils': 5.3.0(rollup@4.57.1) optionalDependencies: @@ -18097,7 +18950,7 @@ snapshots: babel-import-util@3.0.1: {} - babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.105.1(@swc/core@1.15.11)): + babel-loader@8.4.1(@babel/core@7.29.0(supports-color@8.1.1))(webpack@5.105.1(@swc/core@1.15.11)): dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) find-cache-dir: 3.3.2 @@ -18108,14 +18961,14 @@ snapshots: babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.105.1): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 webpack: 5.105.1 - babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.105.1(@swc/core@1.15.11)): + babel-loader@9.2.1(@babel/core@7.29.0(supports-color@8.1.1))(webpack@5.105.1(@swc/core@1.15.11)): dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) find-cache-dir: 4.0.0 @@ -18124,7 +18977,7 @@ snapshots: babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.105.1): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 find-cache-dir: 4.0.0 schema-utils: 4.3.3 webpack: 5.105.1 @@ -18132,18 +18985,18 @@ snapshots: babel-plugin-debug-macros@0.3.4(@babel/core@7.29.0): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 semver: 5.7.2 babel-plugin-debug-macros@1.0.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 babel-import-util: 2.1.1 semver: 7.7.4 babel-plugin-debug-macros@2.0.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 babel-import-util: 2.1.1 semver: 7.7.4 @@ -18201,10 +19054,19 @@ snapshots: reselect: 4.1.8 resolve: 1.22.11 - babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0)(supports-color@8.1.1): + babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1): dependencies: '@babel/compat-data': 7.29.0 '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.29.0)(supports-color@8.1.1): + dependencies: + '@babel/compat-data': 7.29.0 + '@babel/core': 7.29.0 '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0)(supports-color@8.1.1) semver: 6.3.1 transitivePeerDependencies: @@ -18212,23 +19074,38 @@ snapshots: babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.0): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0)(supports-color@8.1.1) core-js-compat: 3.48.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0)(supports-color@8.1.1): + babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1): dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + core-js-compat: 3.48.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.14.0(@babel/core@7.29.0)(supports-color@8.1.1): + dependencies: + '@babel/core': 7.29.0 '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0)(supports-color@8.1.1) core-js-compat: 3.48.0 transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0)(supports-color@8.1.1): + babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1): dependencies: '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0(supports-color@8.1.1))(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.29.0)(supports-color@8.1.1): + dependencies: + '@babel/core': 7.29.0 '@babel/helper-define-polyfill-provider': 0.6.6(@babel/core@7.29.0)(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -18237,7 +19114,7 @@ snapshots: babel-remove-types@1.1.0: dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) prettier: 2.8.8 @@ -18440,7 +19317,7 @@ snapshots: broccoli-babel-transpiler@7.8.1: dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/polyfill': 7.12.1 broccoli-funnel: 2.0.2 broccoli-merge-trees: 3.0.2 @@ -18457,7 +19334,7 @@ snapshots: broccoli-babel-transpiler@8.0.2(@babel/core@7.29.0): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 broccoli-persistent-filter: 3.1.3 clone: 2.1.2 hash-for-dep: 1.5.1 @@ -19761,12 +20638,12 @@ snapshots: ember-auto-import@2.12.0(webpack@5.105.1): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0) '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.29.0) - '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/preset-env': 7.29.0(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@embroider/macros': 1.19.7(@babel/core@7.29.0) '@embroider/reverse-exports': 0.2.0 '@embroider/shared-internals': 2.9.2(supports-color@8.1.1) @@ -19815,17 +20692,17 @@ snapshots: ember-cli-babel@7.26.11: dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0) '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.29.0) '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.29.0) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) '@babel/polyfill': 7.12.1 - '@babel/preset-env': 7.29.0(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.12.18 amd-name-resolver: 1.3.1 babel-plugin-debug-macros: 0.3.4(@babel/core@7.29.0) @@ -19850,17 +20727,17 @@ snapshots: ember-cli-babel@8.3.1(@babel/core@7.29.0): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) - '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-runtime': 7.29.0(@babel/core@7.29.0) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) - '@babel/preset-env': 7.29.0(@babel/core@7.29.0)(supports-color@8.1.1) + '@babel/preset-env': 7.29.0(@babel/core@7.29.0) '@babel/runtime': 7.12.18 amd-name-resolver: 1.3.1 babel-plugin-debug-macros: 0.3.4(@babel/core@7.29.0) @@ -19924,7 +20801,7 @@ snapshots: ember-cli-deprecation-workflow@3.4.0(ember-source@): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 ember-cli-babel: 8.3.1(@babel/core@7.29.0) ember-source: 'link:' transitivePeerDependencies: @@ -19953,7 +20830,7 @@ snapshots: ember-cli-htmlbars@7.0.0(@babel/core@7.29.0)(ember-source@): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@ember/edition-utils': 1.2.0 babel-plugin-ember-template-compilation: 2.4.1 broccoli-debug: 0.6.5 @@ -20437,7 +21314,7 @@ snapshots: ember-eslint-parser@0.5.13(@babel/core@7.29.0)(@typescript-eslint/parser@8.55.0(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@8.57.1) '@glimmer/syntax': 0.95.0 '@typescript-eslint/tsconfig-utils': 8.55.0(typescript@5.9.3) @@ -20454,7 +21331,7 @@ snapshots: ember-eslint-parser@0.5.13(@babel/core@7.29.0)(@typescript-eslint/parser@8.55.0(eslint@9.39.2)(typescript@5.9.3))(eslint@9.39.2)(typescript@5.9.3): dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/eslint-parser': 7.28.6(@babel/core@7.29.0)(eslint@9.39.2) '@glimmer/syntax': 0.95.0 '@typescript-eslint/tsconfig-utils': 8.55.0(typescript@5.9.3) @@ -24566,7 +25443,7 @@ snapshots: remove-types@1.0.0: dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) prettier: 2.8.8 @@ -26516,7 +27393,7 @@ snapshots: workerpool@3.1.2: dependencies: - '@babel/core': 7.29.0(supports-color@8.1.1) + '@babel/core': 7.29.0 object-assign: 4.1.1 rsvp: 4.8.5 transitivePeerDependencies: diff --git a/smoke-tests/node-template/package.json b/smoke-tests/node-template/package.json new file mode 100644 index 00000000000..1432194ae6a --- /dev/null +++ b/smoke-tests/node-template/package.json @@ -0,0 +1,17 @@ +{ + "name": "ember-test-node-template", + "version": "0.0.0", + "private": true, + "type": "module", + "description": "Node-focused smoke test template for ember-source", + "scripts": { + "test:node": "node --import ./tests/node/helpers/register-loader.js --test tests/node/*.test.js" + }, + "dependencies": { + "simple-dom": "^1.4.0", + "html-differ": "^1.4.0" + }, + "engines": { + "node": ">= 20.6.0" + } +} \ No newline at end of file diff --git a/smoke-tests/node-template/tests/node/app-boot.test.js b/smoke-tests/node-template/tests/node/app-boot.test.js new file mode 100644 index 00000000000..72ee9bc7648 --- /dev/null +++ b/smoke-tests/node-template/tests/node/app-boot.test.js @@ -0,0 +1,158 @@ +import { describe, test, beforeEach, afterEach } from 'node:test'; +import assert from 'node:assert/strict'; +import { createAppContext } from './helpers/setup-app.js'; +import { assertHtmlMatches } from './helpers/assert-html-matches.js'; + +describe('App Boot', () => { + let ctx; + + beforeEach(async () => { + ctx = await createAppContext(); + }); + + afterEach(() => { + ctx.destroy(); + }); + + test('App boots and routes to a URL', async () => { + await ctx.visit('/'); + assert.ok(ctx.app); + }); + + test('nested {{component}}', async () => { + ctx.template('index', '{{root-component}}'); + + ctx.component( + 'root-component', + { + location: 'World', + hasExistence: true, + }, + '

Hello {{#if this.hasExistence}}{{this.location}}{{/if}}

{{component "foo-bar"}}
' + ); + + ctx.component( + 'foo-bar', + undefined, + '

The files are *inside* the computer?!

' + ); + + const html = await ctx.renderToHTML('/'); + assert.ok( + assertHtmlMatches( + html, + '

Hello World

The files are *inside* the computer?!

' + ), + `HTML should match, got: ${html}` + ); + }); + + test('', async () => { + ctx.template('application', "

Go to photos

"); + ctx.routes(function () { + this.route('photos'); + }); + + const html = await ctx.renderToHTML('/'); + assert.ok( + assertHtmlMatches( + html, + '

Go to photos

' + ), + `HTML should match, got: ${html}` + ); + }); + + test('{{link-to}}', async () => { + ctx.template('application', "

{{#link-to route='photos'}}Go to photos{{/link-to}}

"); + ctx.routes(function () { + this.route('photos'); + }); + + const html = await ctx.renderToHTML('/'); + assert.ok( + assertHtmlMatches( + html, + '

Go to photos

' + ), + `HTML should match, got: ${html}` + ); + }); + + test('non-escaped content', async () => { + ctx.routes(function () { + this.route('photos'); + }); + + ctx.template('application', '

{{{this.title}}}

'); + ctx.controller('application', { + title: 'Hello world', + }); + + const html = await ctx.renderToHTML('/'); + assert.ok( + assertHtmlMatches(html, '

Hello world

'), + `HTML should match, got: ${html}` + ); + }); + + test('outlets', async () => { + ctx.routes(function () { + this.route('photos'); + }); + + ctx.template('application', '

{{outlet}}

'); + ctx.template('index', 'index'); + ctx.template('photos', 'photos'); + + const [indexHtml, photosHtml] = await ctx.all([ + ctx.renderToHTML('/'), + ctx.renderToHTML('/photos'), + ]); + + assert.ok( + assertHtmlMatches(indexHtml, '

index

'), + `index HTML should match, got: ${indexHtml}` + ); + assert.ok( + assertHtmlMatches(photosHtml, '

photos

'), + `photos HTML should match, got: ${photosHtml}` + ); + }); + + test('lifecycle hooks disabled', async () => { + let didReceiveAttrsCalled = false; + let willRenderCalled = false; + let didRenderCalled = false; + let willInsertElementCalled = false; + let didInsertElementCalled = false; + + ctx.template('application', "{{my-component foo='bar'}}{{outlet}}"); + + ctx.component('my-component', { + didReceiveAttrs() { + didReceiveAttrsCalled = true; + }, + willRender() { + willRenderCalled = true; + }, + didRender() { + didRenderCalled = true; + }, + willInsertElement() { + willInsertElementCalled = true; + }, + didInsertElement() { + didInsertElementCalled = true; + }, + }); + + await ctx.renderToHTML('/'); + + assert.ok(didReceiveAttrsCalled, 'should trigger didReceiveAttrs hook'); + assert.ok(!willRenderCalled, 'should not trigger willRender hook'); + assert.ok(!didRenderCalled, 'should not trigger didRender hook'); + assert.ok(!willInsertElementCalled, 'should not trigger willInsertElement hook'); + assert.ok(!didInsertElementCalled, 'should not trigger didInsertElement hook'); + }); +}); diff --git a/smoke-tests/node-template/tests/node/component-rendering.test.js b/smoke-tests/node-template/tests/node/component-rendering.test.js new file mode 100644 index 00000000000..1636fd8f6b5 --- /dev/null +++ b/smoke-tests/node-template/tests/node/component-rendering.test.js @@ -0,0 +1,51 @@ +import { describe, test, beforeEach, afterEach } from 'node:test'; +import assert from 'node:assert/strict'; +import { createComponentContext } from './helpers/setup-component.js'; + +describe('Components can be rendered without a DOM dependency', () => { + let ctx; + + beforeEach(async () => { + ctx = await createComponentContext(); + }); + + afterEach(() => { + ctx.destroy(); + }); + + test('Simple component', () => { + let html = ctx.render('

Hello

'); + assert.ok(html.match(/

Hello<\/h1>/), `expected

Hello

in: ${html}`); + }); + + test('Component with dynamic value', () => { + ctx.set('location', 'World'); + + let html = ctx.render('

Hello {{this.location}}

'); + assert.ok(html.match(/

Hello World<\/h1>/), `expected

Hello World

in: ${html}`); + }); + + test('Ensure undefined attributes requiring protocol sanitization do not error', () => { + ctx.owner.register( + 'component:fake-link', + class extends ctx.Component { + tagName = 'link'; + attributeBindings = ['href', 'rel']; + rel = 'canonical'; + } + ); + + let html = ctx.render('{{fake-link}}'); + assert.ok(html.match(/rel="canonical"/), `expected rel="canonical" in: ${html}`); + }); + + test('attributes requiring protocol sanitization do not error', () => { + ctx.set('someHref', 'https://foo.com/'); + + let html = ctx.render('Some Link'); + assert.ok( + html.match(/Some Link<\/a>/), + `expected link in: ${html}` + ); + }); +}); diff --git a/smoke-tests/node-template/tests/node/fastboot-sandbox.test.js b/smoke-tests/node-template/tests/node/fastboot-sandbox.test.js new file mode 100644 index 00000000000..b34500f097d --- /dev/null +++ b/smoke-tests/node-template/tests/node/fastboot-sandbox.test.js @@ -0,0 +1,84 @@ +/** + * ESM port of tests/node/fastboot-sandbox-test.js + * + * The original test loaded Ember via vm.Script in a sandbox, simulating + * FastBoot's execution model with the AMD bundle. In the ESM world, + * we test that Ember can be dynamically imported and used to boot an app + * with SimpleDOM, which is the ESM equivalent of the FastBoot sandbox pattern. + */ +import { describe, test } from 'node:test'; +import assert from 'node:assert/strict'; +import SimpleDOM from 'simple-dom'; +import Application from 'ember-source/@ember/application/index.js'; +import EmberObject from 'ember-source/@ember/object/index.js'; +import EmberRouter from 'ember-source/@ember/routing/router.js'; +import { run } from 'ember-source/@ember/runloop/index.js'; +import { precompile } from 'ember-source/ember-template-compiler/index.js'; +import { createTemplateFactory } from 'ember-source/@ember/template-factory/index.js'; + +const HTMLSerializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); + +function compile(templateString, options) { + let templateSpec = precompile(templateString, options); + return createTemplateFactory(JSON.parse(templateSpec)); +} + +async function fastbootVisit(app, url) { + let doc = new SimpleDOM.Document(); + let rootElement = doc.body; + let options = { isBrowser: false, document: doc, rootElement: rootElement }; + + await app.boot(); + + let instance = await app.buildInstance(); + + try { + await instance.boot(options); + await instance.visit(url, options); + + return { + url: instance.getURL(), + title: doc.title, + body: HTMLSerializer.serialize(rootElement), + }; + } finally { + instance.destroy(); + } +} + +describe('FastBoot sandbox ESM equivalent', () => { + test('FastBoot: basic', async () => { + let Router = class extends EmberRouter {}; + Router.map(function () { + this.route('a'); + this.route('b'); + }); + + let registry = { + 'router:main': Router, + 'template:application': compile('

Hello world!

\n{{outlet}}'), + }; + + class Resolver extends EmberObject { + resolve(specifier) { + return registry[specifier]; + } + } + + let app = class extends Application {}.create({ + autoboot: false, + Resolver, + }); + + let result = await fastbootVisit(app, '/'); + + assert.equal(result.url, '/', 'landed on correct url'); + assert.equal( + result.body, + '

Hello world!

\n', + 'results in expected HTML' + ); + + run(app, 'destroy'); + }); +}); diff --git a/smoke-tests/node-template/tests/node/helpers/assert-html-matches.js b/smoke-tests/node-template/tests/node/helpers/assert-html-matches.js new file mode 100644 index 00000000000..89e6489e41a --- /dev/null +++ b/smoke-tests/node-template/tests/node/helpers/assert-html-matches.js @@ -0,0 +1,16 @@ +/** + * ESM port of tests/node/helpers/assert-html-matches.js + * + * Tests whether two fragments of HTML 'appear' to match. + * Ignores whitespace and ID attributes (which Ember auto-generates). + */ +import { HtmlDiffer } from 'html-differ'; + +const htmlDiffer = new HtmlDiffer({ + ignoreAttributes: ['id'], + ignoreWhitespaces: true, +}); + +export function assertHtmlMatches(actual, expected) { + return htmlDiffer.isEqual(actual, expected); +} diff --git a/smoke-tests/node-template/tests/node/helpers/build-owner.js b/smoke-tests/node-template/tests/node/helpers/build-owner.js new file mode 100644 index 00000000000..1ed54637c7e --- /dev/null +++ b/smoke-tests/node-template/tests/node/helpers/build-owner.js @@ -0,0 +1,38 @@ +/** + * ESM port of tests/node/helpers/build-owner.js + */ +import EmberObject from 'ember-source/@ember/object/index.js'; +import Application from 'ember-source/@ember/application/index.js'; +import ApplicationInstance from 'ember-source/@ember/application/instance.js'; +import { Registry } from 'ember-source/@ember/-internals/container/index.js'; +import RegistryProxyMixin from 'ember-source/@ember/-internals/runtime/lib/mixins/registry_proxy.js'; +import ContainerProxyMixin from 'ember-source/@ember/-internals/runtime/lib/mixins/container_proxy.js'; + +export function buildOwner(resolver) { + let Owner = EmberObject.extend(RegistryProxyMixin, ContainerProxyMixin); + + let namespace = EmberObject.create({ + Resolver: { + create: function () { + return resolver; + }, + }, + }); + + let fallbackRegistry = Application.buildRegistry(namespace); + let registry = new Registry({ + fallback: fallbackRegistry, + }); + + ApplicationInstance.setupRegistry(registry); + + let owner = Owner.create({ + __registry__: registry, + __container__: null, + }); + + let container = registry.container({ owner: owner }); + owner.__container__ = container; + + return owner; +} diff --git a/smoke-tests/node-template/tests/node/helpers/load-template-compiler.js b/smoke-tests/node-template/tests/node/helpers/load-template-compiler.js new file mode 100644 index 00000000000..d823691ccff --- /dev/null +++ b/smoke-tests/node-template/tests/node/helpers/load-template-compiler.js @@ -0,0 +1,3 @@ +export async function loadTemplateCompiler() { + return import('ember-source/ember-template-compiler/index.js'); +} diff --git a/smoke-tests/node-template/tests/node/helpers/macros-shim.js b/smoke-tests/node-template/tests/node/helpers/macros-shim.js new file mode 100644 index 00000000000..47eff275a06 --- /dev/null +++ b/smoke-tests/node-template/tests/node/helpers/macros-shim.js @@ -0,0 +1,11 @@ +/** + * @embroider/macros shim for Node.js ESM loading. + * + * The Ember ESM packages in dist/packages/ contain unresolved imports from + * '@embroider/macros' (specifically isDevelopingApp). In a real app build, + * these are resolved at compile time by a Babel plugin. For Node.js testing + * we provide a runtime shim. + */ +export function isDevelopingApp() { + return true; +} diff --git a/smoke-tests/node-template/tests/node/helpers/register-loader.js b/smoke-tests/node-template/tests/node/helpers/register-loader.js new file mode 100644 index 00000000000..276021062ee --- /dev/null +++ b/smoke-tests/node-template/tests/node/helpers/register-loader.js @@ -0,0 +1,22 @@ +/** + * Node.js module loader hook that intercepts '@embroider/macros' imports + * and redirects them to our local shim. + * + * Usage: node --import ./tests/node/helpers/register-loader.js --test ... + */ +import { register } from 'node:module'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { dirname, resolve } from 'node:path'; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const shimPath = resolve(__dirname, 'macros-shim.js'); +const shimURL = pathToFileURL(shimPath).href; + +register('data:text/javascript,' + encodeURIComponent(` +export async function resolve(specifier, context, nextResolve) { + if (specifier === '@embroider/macros') { + return { url: ${JSON.stringify(shimURL)}, shortCircuit: true }; + } + return nextResolve(specifier, context); +} +`), pathToFileURL(import.meta.url)); diff --git a/smoke-tests/node-template/tests/node/helpers/setup-app.js b/smoke-tests/node-template/tests/node/helpers/setup-app.js new file mode 100644 index 00000000000..d76dd61cd0a --- /dev/null +++ b/smoke-tests/node-template/tests/node/helpers/setup-app.js @@ -0,0 +1,156 @@ +/** + * ESM port of tests/node/helpers/setup-app.js + * + * Sets up a test context with Ember app creation, routing, template registration, + * and renderToHTML support for server-side rendering tests. + */ +import SimpleDOM from 'simple-dom'; +import Application from 'ember-source/@ember/application/index.js'; +import Component from 'ember-source/@ember/component/index.js'; +import { setComponentTemplate } from 'ember-source/@ember/component/index.js'; +import templateOnly from 'ember-source/@ember/component/template-only.js'; +import Controller from 'ember-source/@ember/controller/index.js'; +import EmberObject from 'ember-source/@ember/object/index.js'; +import Route from 'ember-source/@ember/routing/route.js'; +import EmberRouter from 'ember-source/@ember/routing/router.js'; +import { service } from 'ember-source/@ember/service/index.js'; +import { run } from 'ember-source/@ember/runloop/index.js'; +import RSVP from 'ember-source/@ember/-internals/runtime/lib/ext/rsvp.js'; +import { setTesting } from 'ember-source/@ember/debug/lib/testing.js'; +import { precompile } from 'ember-source/ember-template-compiler/index.js'; +import { createTemplateFactory } from 'ember-source/@ember/template-factory/index.js'; + +function compile(templateString, options) { + let templateSpec = precompile(templateString, options); + return createTemplateFactory(JSON.parse(templateSpec)); +} + +export async function createAppContext() { + setTesting(true); + + const ctx = { + compile, + setComponentTemplate, + templateOnlyComponent: templateOnly, + run, + all: RSVP.all.bind(RSVP), + registry: {}, + routesCallback: null, + app: null, + }; + + ctx.register = function (containerKey, klass) { + ctx.registry[containerKey] = klass; + }; + + ctx.template = function (name, templateContents) { + ctx.register('template:' + name, ctx.compile(templateContents)); + }; + + ctx.component = function (name, componentProps, templateContents) { + let component = ctx.setComponentTemplate( + ctx.compile(templateContents), + componentProps + ? Component.extend(componentProps) + : ctx.templateOnlyComponent() + ); + ctx.register('component:' + name, component); + }; + + ctx.controller = function (name, controllerProps) { + let controller = Controller.extend(controllerProps); + ctx.register('controller:' + name, controller); + }; + + ctx.route = function (name, routeProps) { + let route = Route.extend({ + router: service('router'), + ...routeProps, + }); + ctx.register('route:' + name, route); + }; + + ctx.service = function (name, serviceProps) { + let service = EmberObject.extend(serviceProps); + ctx.register('service:' + name, service); + }; + + ctx.routes = function (cb) { + ctx.routesCallback = cb; + }; + + ctx.createApplication = function () { + if (ctx.app) return ctx.app; + + let app = class extends Application {}.create({ + autoboot: false, + Resolver: { + create: () => { + return null; + }, + }, + }); + + let Router = class extends EmberRouter { + location = 'none'; + }; + + if (ctx.routesCallback) { + Router.map(ctx.routesCallback); + } + + ctx.register('router:main', Router); + + // Register application classes via initializer + app.initializer({ + name: 'register-application-classes', + initialize: function (application) { + for (let key in ctx.registry) { + application.register(key, ctx.registry[key]); + } + }, + }); + + run(app, 'boot'); + ctx.app = app; + + return app; + }; + + ctx.visit = function (url) { + let app = ctx.createApplication(); + let dom = new SimpleDOM.Document(); + + return run(app, 'visit', url, { + isBrowser: false, + document: dom, + rootElement: dom.body, + }).catch(function (error) { + console.error(error.stack); + }); + }; + + ctx.renderToHTML = function (url) { + let app = ctx.createApplication(); + let dom = new SimpleDOM.Document(); + let root = dom.body; + + return run(app, 'visit', url, { + isBrowser: false, + document: dom, + rootElement: root, + }).then(function () { + let serializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); + return serializer.serialize(root); + }); + }; + + ctx.destroy = function () { + if (ctx.app) { + run(ctx.app, 'destroy'); + } + setTesting(false); + }; + + return ctx; +} diff --git a/smoke-tests/node-template/tests/node/helpers/setup-component.js b/smoke-tests/node-template/tests/node/helpers/setup-component.js new file mode 100644 index 00000000000..252c7c66a62 --- /dev/null +++ b/smoke-tests/node-template/tests/node/helpers/setup-component.js @@ -0,0 +1,108 @@ +/** + * ESM port of tests/node/helpers/setup-component.js + * + * Sets up a test context for rendering components without a real DOM, + * using SimpleDOM. + */ +import SimpleDOM from 'simple-dom'; +import Component from 'ember-source/@ember/component/index.js'; +import { set } from 'ember-source/@ember/object/index.js'; +import { run } from 'ember-source/@ember/runloop/index.js'; +import { setTesting } from 'ember-source/@ember/debug/lib/testing.js'; +import { precompile } from 'ember-source/ember-template-compiler/index.js'; +import { createTemplateFactory } from 'ember-source/@ember/template-factory/index.js'; +import { buildOwner } from './build-owner.js'; + +function compile(templateString, options) { + let templateSpec = precompile(templateString, options); + return createTemplateFactory(JSON.parse(templateSpec)); +} + +export async function createComponentContext() { + setTesting(true); + + const ctx = { + Component, + compile, + run, + _hasRendered: false, + }; + + ctx.element = new SimpleDOM.Document(); + ctx.owner = buildOwner({ resolve: function () {} }); + ctx.owner.register('service:-document', new SimpleDOM.Document(), { + instantiate: false, + }); + + let OutletView = ctx.owner.factoryFor('view:-outlet'); + let outletTemplateFactory = ctx.owner.lookup('template:-outlet'); + let environment = ctx.owner.lookup('-environment:main'); + ctx.component = OutletView.create({ environment, template: outletTemplateFactory }); + ctx._outletState = { + render: { + owner: ctx.owner || undefined, + name: 'application', + controller: ctx, + model: undefined, + template: outletTemplateFactory(ctx.owner), + }, + outlets: {}, + }; + + run(function () { + ctx.component.setOutletState(ctx._outletState); + }); + + ctx.set = function (property, value) { + run(function () { + set(ctx, property, value); + }); + }; + + ctx.render = function (_template) { + let templateFactory = ctx.compile(_template); + + let stateToRender = { + owner: ctx.owner, + name: 'index', + controller: ctx, + model: undefined, + template: templateFactory(ctx.owner), + }; + + stateToRender.name = 'index'; + ctx._outletState.outlets.main = { render: stateToRender, outlets: {} }; + + run(function () { + ctx.component.setOutletState(ctx._outletState); + }); + + if (!ctx._hasRendered) { + run(function () { + ctx.component.appendTo(ctx.element); + }); + ctx._hasRendered = true; + } + + return ctx.serializeElement(); + }; + + ctx.serializeElement = function () { + let serializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); + return serializer.serialize(ctx.element); + }; + + ctx.destroy = function () { + if (ctx.component) { + run(function () { + ctx.component.destroy(); + }); + ctx.component = null; + } + run(ctx.owner, 'destroy'); + ctx.owner = null; + setTesting(false); + }; + + return ctx; +} diff --git a/smoke-tests/node-template/tests/node/instrumentation.test.js b/smoke-tests/node-template/tests/node/instrumentation.test.js new file mode 100644 index 00000000000..8dbf6dbe11d --- /dev/null +++ b/smoke-tests/node-template/tests/node/instrumentation.test.js @@ -0,0 +1,19 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { instrument } from 'ember-source/@ember/instrumentation/index.js'; + +test('instrumentation works in FastBoot environment', async () => { + let _originalWindow = globalThis.window; + + globalThis.window = {}; // mock window without `performance` property + + try { + let result = instrument('render', {}, function () { + return 'hello'; + }); + + assert.equal(result, 'hello', 'called block'); + } finally { + globalThis.window = _originalWindow; + } +}); diff --git a/smoke-tests/node-template/tests/node/overrides.test.js b/smoke-tests/node-template/tests/node/overrides.test.js new file mode 100644 index 00000000000..bd86e09c324 --- /dev/null +++ b/smoke-tests/node-template/tests/node/overrides.test.js @@ -0,0 +1,205 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import Overrides from '../../node_modules/ember-source/lib/overrides.js'; + +function makeAddon({ name = 'my-addon', version = '1.0.0', dependencies = {}, addons = [], hasJSFiles = true } = {}, parent) { + let addon = { + name, + parent, + pkg: { name, version, dependencies, devDependencies: {} }, + _fileSystemInfo: () => ({ hasJSFiles }), + addons: [], + }; + addon.addons = addons.map((a) => makeAddon(a, addon)); + return addon; +} + +function makeProject({ name = 'my-app', dependencies = {}, devDependencies = {}, addons = [] } = {}) { + let project = { + name: () => name, + parent: null, + pkg: { name, dependencies, devDependencies }, + addons: [], + }; + project.addons = addons.map((a) => makeAddon(a, project)); + return project; +} + +function cmp(a, b) { + if (a == undefined || a < b) { + return -1; + } + + if (b == undefined || a > b) { + return 1; + } + + return 0; +} + +function addonsInfoFor(project) { + let addonsInfo = [...Overrides.addonsInfoFor(project)]; + addonsInfo.sort((a, b) => cmp(a.topLevel, b.topLevel) || cmp(a.parent, b.parent)); + return addonsInfo; +} + +test('overrides: old babel added by app', () => { + let project = makeProject({ + devDependencies: { 'ember-cli-babel': '^6.0.0' }, + addons: [{ name: 'ember-cli-babel', version: '6.0.0' }], + }); + + assert.deepEqual(addonsInfoFor(project), [ + { + parent: 'my-app (your app)', + topLevel: null, + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: [], + }, + ]); +}); + +test('overrides: compatible old babel added by app', () => { + let project = makeProject({ + devDependencies: { 'ember-cli-babel': '^7.0.0' }, + addons: [{ name: 'ember-cli-babel', version: '7.0.0' }], + }); + + assert.deepEqual(addonsInfoFor(project), [ + { + parent: 'my-app (your app)', + topLevel: null, + version: '7.0.0', + requirement: '^7.0.0', + compatible: true, + dormant: false, + path: [], + }, + ]); +}); + +test('overrides: new babel added by app is ignored', () => { + let project = makeProject({ + devDependencies: { 'ember-cli-babel': '^7.26.6' }, + addons: [{ name: 'ember-cli-babel', version: '7.26.6' }], + }); + + assert.deepEqual(addonsInfoFor(project), []); +}); + +test('overrides: old babel added by direct dependency', () => { + let project = makeProject({ + addons: [ + { + name: 'my-addon', + version: '1.0.0', + addons: [{ name: 'ember-cli-babel', version: '6.0.0', dependencies: { 'ember-cli-babel': '^6.0.0' } }], + dependencies: { 'ember-cli-babel': '^6.0.0' }, + }, + ], + }); + + assert.deepEqual(addonsInfoFor(project), [ + { + parent: 'my-addon@1.0.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: ['my-addon@1.0.0'], + }, + ]); +}); + +test('overrides: dormant direct dependency is marked dormant', () => { + let project = makeProject({ + addons: [ + { + name: 'my-addon', + version: '1.0.0', + hasJSFiles: false, + addons: [{ name: 'ember-cli-babel', version: '6.0.0' }], + dependencies: { 'ember-cli-babel': '^6.0.0' }, + }, + ], + }); + + assert.deepEqual(addonsInfoFor(project), [ + { + parent: 'my-addon@1.0.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: true, + path: ['my-addon@1.0.0'], + }, + ]); +}); + +test('overrides: transient dependency records full path', () => { + let project = makeProject({ + addons: [ + { + name: 'my-addon', + version: '1.0.0', + addons: [ + { + name: 'my-nested-addon', + version: '0.1.0', + addons: [{ name: 'ember-cli-babel', version: '6.0.0' }], + dependencies: { 'ember-cli-babel': '^6.0.0' }, + }, + ], + }, + ], + }); + + assert.deepEqual(addonsInfoFor(project), [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ]); +}); + +test('overrides: transient through dormant dependency is marked dormant', () => { + let project = makeProject({ + addons: [ + { + name: 'my-addon', + version: '1.0.0', + hasJSFiles: false, + addons: [ + { + name: 'my-nested-addon', + version: '0.1.0', + addons: [{ name: 'ember-cli-babel', version: '6.0.0' }], + dependencies: { 'ember-cli-babel': '^6.0.0' }, + }, + ], + }, + ], + }); + + assert.deepEqual(addonsInfoFor(project), [ + { + parent: 'my-nested-addon@0.1.0', + topLevel: 'my-addon', + version: '6.0.0', + requirement: '^6.0.0', + compatible: false, + dormant: false, + path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], + }, + ]); +}); diff --git a/smoke-tests/node-template/tests/node/sourcemap.test.js b/smoke-tests/node-template/tests/node/sourcemap.test.js new file mode 100644 index 00000000000..02ddc31e5aa --- /dev/null +++ b/smoke-tests/node-template/tests/node/sourcemap.test.js @@ -0,0 +1,25 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { readFileSync, existsSync } from 'node:fs'; +import { createRequire } from 'node:module'; + +const require = createRequire(import.meta.url); +const emberSourceRoot = require.resolve('ember-source/package.json').replace('/package.json', ''); + +function count(source, find) { + let num = 0; + let i = -1; + while ((i = source.indexOf(find, i + 1)) !== -1) { + num += 1; + } + return num; +} + +test('ember.js has only a single sourcemaps comment', () => { + let jsPath = `${emberSourceRoot}/dist/ember.debug.js`; + assert.ok(existsSync(jsPath), `${jsPath} should exist`); + + let contents = readFileSync(jsPath, 'utf-8'); + let num = count(contents, '//# sourceMappingURL='); + assert.equal(num, 1); +}); diff --git a/smoke-tests/node-template/tests/node/template-compiler.test.js b/smoke-tests/node-template/tests/node/template-compiler.test.js new file mode 100644 index 00000000000..0433159d296 --- /dev/null +++ b/smoke-tests/node-template/tests/node/template-compiler.test.js @@ -0,0 +1,19 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { loadTemplateCompiler } from './helpers/load-template-compiler.js'; + +test('template compiler exports are available', async () => { + const templateCompiler = await loadTemplateCompiler(); + + assert.equal(typeof templateCompiler.precompile, 'function'); + assert.equal(typeof templateCompiler._buildCompileOptions, 'function'); + assert.equal(typeof templateCompiler._preprocess, 'function'); + assert.equal(typeof templateCompiler._print, 'function'); +}); + +test('template compiler precompile returns string', async () => { + const templateCompiler = await loadTemplateCompiler(); + let result = templateCompiler.precompile('

Hello

'); + + assert.equal(typeof result, 'string'); +}); diff --git a/smoke-tests/node-template/tests/node/visit.test.js b/smoke-tests/node-template/tests/node/visit.test.js new file mode 100644 index 00000000000..7d307468e19 --- /dev/null +++ b/smoke-tests/node-template/tests/node/visit.test.js @@ -0,0 +1,316 @@ +import { describe, test, beforeEach, afterEach } from 'node:test'; +import assert from 'node:assert/strict'; +import SimpleDOM from 'simple-dom'; +import { createAppContext } from './helpers/setup-app.js'; + +function assertHTMLMatches(actualHTML, expectedHTML) { + assert.ok(actualHTML.match(expectedHTML), actualHTML + ' matches ' + expectedHTML); +} + +let HTMLSerializer; + +// This is based on what fastboot-server does +function fastbootVisit(App, url) { + if (!HTMLSerializer) { + HTMLSerializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); + } + let doc = new SimpleDOM.Document(); + let rootElement = doc.body; + let options = { isBrowser: false, document: doc, rootElement: rootElement }; + + return App.visit(url, options).then(function (instance) { + try { + return { + url: instance.getURL(), + title: doc.title, + body: HTMLSerializer.serialize(rootElement), + }; + } finally { + instance.destroy(); + } + }); +} + +function assertFastbootResult(expected) { + return function (actual) { + assert.equal(actual.url, expected.url); + assertHTMLMatches(actual.body, expected.body); + }; +} + +describe('Ember.Application - visit() Integration Tests', () => { + let ctx; + + beforeEach(async () => { + ctx = await createAppContext(); + }); + + afterEach(() => { + ctx.destroy(); + }); + + test('FastBoot: basic', async () => { + ctx.routes(function () { + this.route('a'); + this.route('b'); + }); + + ctx.template('application', '

Hello world

\n{{outlet}}'); + ctx.template('a', '

Welcome to {{x-foo page="A"}}

'); + ctx.template('b', '

{{x-foo page="B"}}

'); + + let initCalled = false; + let didInsertElementCalled = false; + + ctx.component( + 'x-foo', + { + tagName: 'span', + init: function () { + this._super(); + initCalled = true; + }, + didInsertElement: function () { + didInsertElementCalled = true; + }, + }, + 'Page {{this.page}}' + ); + + let App = ctx.createApplication(); + + const [resultA, resultB] = await Promise.all([ + fastbootVisit(App, '/a'), + fastbootVisit(App, '/b'), + ]); + + assertFastbootResult({ + url: '/a', + body: '

Hello world

\n

Welcome to Page A

', + })(resultA); + + assertFastbootResult({ + url: '/b', + body: '

Hello world

\n

Page B

', + })(resultB); + + assert.ok(initCalled, 'Component#init should be called'); + assert.ok(!didInsertElementCalled, 'Component#didInsertElement should not be called'); + }); + + test('FastBoot: redirect', async () => { + ctx.routes(function () { + this.route('a'); + this.route('b'); + this.route('c'); + }); + + ctx.template('a', '

Hello from A

'); + ctx.template('b', '

Hello from B

'); + ctx.template('c', '

Hello from C

'); + + ctx.route('a', { + beforeModel: function () { + this.router.replaceWith('b'); + }, + }); + + ctx.route('b', { + afterModel: function () { + this.router.transitionTo('c'); + }, + }); + + let App = ctx.createApplication(); + + const [resultA, resultB] = await Promise.all([ + fastbootVisit(App, '/a'), + fastbootVisit(App, '/b'), + ]); + + assertFastbootResult({ + url: '/c', + body: '

Hello from C

', + })(resultA); + + assertFastbootResult({ + url: '/c', + body: '

Hello from C

', + })(resultB); + }); + + test('FastBoot: attributes are sanitized', async () => { + ctx.template('application', '
'); + + ctx.controller('application', { + test: 'javascript:alert("hello")', + }); + + let App = ctx.createApplication(); + + const result = await fastbootVisit(App, '/'); + assertFastbootResult({ + url: '/', + body: '', + })(result); + }); + + test('FastBoot: route error', async () => { + ctx.routes(function () { + this.route('a'); + this.route('b'); + }); + + ctx.template('a', '

Hello from A

'); + ctx.template('b', '

Hello from B

'); + + ctx.route('a', { + beforeModel: function () { + throw new Error('Error from A'); + }, + }); + + ctx.route('b', { + afterModel: function () { + throw new Error('Error from B'); + }, + }); + + let App = ctx.createApplication(); + + // Route errors propagate as synchronous throws via backburner's queue flush, + // so we need to catch them as either sync or async errors. + try { + await fastbootVisit(App, '/a'); + assert.ok(false, 'It should not render route a'); + } catch (error) { + assert.equal(error.message, 'Error from A'); + } + + try { + await fastbootVisit(App, '/b'); + assert.ok(false, 'It should not render route b'); + } catch (error) { + assert.equal(error.message, 'Error from B'); + } + }); + + test('FastBoot: route error template', async () => { + ctx.routes(function () { + this.route('a'); + }); + + ctx.template('error', '

Error template rendered!

'); + ctx.template('a', '

Hello from A

'); + + ctx.route('a', { + model: function () { + throw new Error('Error from A'); + }, + }); + + let App = ctx.createApplication(); + + const result = await fastbootVisit(App, '/a'); + assertFastbootResult({ + url: '/a', + body: '

Error template rendered!

', + })(result); + }); + + test('Resource-discovery setup', async () => { + class Network { + constructor() { + this.requests = []; + } + fetch(url) { + this.requests.push(url); + return Promise.resolve(); + } + } + + ctx.routes(function () { + this.route('a'); + this.route('b'); + this.route('c'); + this.route('d'); + this.route('e'); + }); + + let network; + + ctx.route('a', { + model: function () { return network.fetch('/a'); }, + afterModel: function () { this.router.replaceWith('b'); }, + }); + + ctx.route('b', { + model: function () { return network.fetch('/b'); }, + afterModel: function () { this.router.replaceWith('c'); }, + }); + + ctx.route('c', { + model: function () { return network.fetch('/c'); }, + }); + + ctx.route('d', { + model: function () { return network.fetch('/d'); }, + afterModel: function () { this.router.replaceWith('e'); }, + }); + + ctx.route('e', { + model: function () { return network.fetch('/e'); }, + }); + + ctx.template('a', '{{x-foo}}'); + ctx.template('b', '{{x-foo}}'); + ctx.template('c', '{{x-foo}}'); + ctx.template('d', '{{x-foo}}'); + ctx.template('e', '{{x-foo}}'); + + let xFooInstances = 0; + + ctx.component('x-foo', { + init: function () { + this._super(); + xFooInstances++; + }, + }); + + let App = ctx.createApplication(); + + async function assertResources(url, resources) { + network = new Network(); + + let instance = await App.visit(url, { isBrowser: false, shouldRender: false }); + try { + let viewRegistry = instance.lookup('-view-registry:main'); + assert.equal(Object.keys(viewRegistry).length, 0, 'did not create any views'); + assert.deepEqual(network.requests, resources); + } finally { + instance.destroy(); + } + } + + await assertResources('/a', ['/a', '/b', '/c']); + await assertResources('/b', ['/b', '/c']); + await assertResources('/c', ['/c']); + await assertResources('/d', ['/d', '/e']); + await assertResources('/e', ['/e']); + + assert.equal(xFooInstances, 0, 'it should not create any x-foo components'); + }); + + test('FastBoot: tagless components can render', async () => { + ctx.template('application', "
{{my-component}}
"); + ctx.component('my-component', { tagName: '' }, '

hello world

'); + + let App = ctx.createApplication(); + + const result = await fastbootVisit(App, '/'); + assertFastbootResult({ + url: '/', + body: /

hello world<\/h1><\/div>/, + })(result); + }); +}); diff --git a/smoke-tests/scenarios/node-test.ts b/smoke-tests/scenarios/node-test.ts new file mode 100644 index 00000000000..54e90ec8e79 --- /dev/null +++ b/smoke-tests/scenarios/node-test.ts @@ -0,0 +1,27 @@ +import { nodeScenarios } from './scenarios'; +import type { PreparedApp, Scenarios } from 'scenario-tester'; +import * as QUnit from 'qunit'; + +const { module: Qmodule, test } = QUnit; +QUnit.config.testTimeout = 120_000; + +function nodeTests(scenarios: Scenarios) { + scenarios + .map('node-tests', (_project) => {}) + .forEachScenario((scenario) => { + Qmodule(scenario.name, function (hooks) { + let app: PreparedApp; + + hooks.before(async () => { + app = await scenario.prepare(); + }); + + test('node esm imports', async function (assert) { + let result = await app.execute(`pnpm test:node`); + assert.equal(result.exitCode, 0, result.output); + }); + }); + }); +} + +nodeTests(nodeScenarios); diff --git a/smoke-tests/scenarios/scenarios.ts b/smoke-tests/scenarios/scenarios.ts index 66b04ce10ed..a00fd7016e6 100644 --- a/smoke-tests/scenarios/scenarios.ts +++ b/smoke-tests/scenarios/scenarios.ts @@ -29,6 +29,12 @@ function embroiderWebpack(project: Project) { function embroiderVite(project: Project) {} +function node(project: Project) { + project.linkDevDependency('ember-source', { + baseDir: dirname(require.resolve('../app-template/package.json')), + }); +} + export const v1AppScenarios = Scenarios.fromProject(() => Project.fromDir(dirname(require.resolve('../app-template/package.json')), { linkDevDeps: true }) ).expand({ @@ -44,3 +50,11 @@ export const v2AppScenarios = Scenarios.fromProject(() => ).expand({ embroiderVite, }); + +export const nodeScenarios = Scenarios.fromProject(() => + Project.fromDir(dirname(require.resolve('../node-template/package.json')), { + linkDevDeps: true, + }) +).expand({ + node, +}); diff --git a/tests/node/app-boot-test.js b/tests/node/app-boot-test.js deleted file mode 100644 index 6f16236bc3c..00000000000 --- a/tests/node/app-boot-test.js +++ /dev/null @@ -1,137 +0,0 @@ -const setupAppTest = require('./helpers/setup-app'); - -require('./helpers/assert-html-matches').register(); - -QUnit.module('App Boot', function (hooks) { - setupAppTest(hooks); - - QUnit.test('App boots and routes to a URL', function (assert) { - this.visit('/'); - assert.ok(this.app); - }); - - QUnit.test('nested {{component}}', function (assert) { - this.template('index', '{{root-component}}'); - - this.component( - 'root-component', - { - location: 'World', - hasExistence: true, - }, - "\ -

Hello {{#if this.hasExistence}}{{this.location}}{{/if}}

\ -
{{component 'foo-bar'}}
\ - " - ); - - this.component( - 'foo-bar', - undefined, - '\ -

The files are *inside* the computer?!

\ - ' - ); - - return this.renderToHTML('/').then(function (html) { - assert.htmlMatches( - html, - '

Hello World

The files are *inside* the computer?!

' - ); - }); - }); - - QUnit.test('', function (assert) { - this.template('application', "

Go to photos

"); - this.routes(function () { - this.route('photos'); - }); - - return this.renderToHTML('/').then(function (html) { - assert.htmlMatches( - html, - '

Go to photos

' - ); - }); - }); - - QUnit.test('{{link-to}}', function (assert) { - this.template('application', "

{{#link-to route='photos'}}Go to photos{{/link-to}}

"); - this.routes(function () { - this.route('photos'); - }); - - return this.renderToHTML('/').then(function (html) { - assert.htmlMatches( - html, - '

Go to photos

' - ); - }); - }); - - QUnit.test('non-escaped content', function (assert) { - this.routes(function () { - this.route('photos'); - }); - - this.template('application', '

{{{this.title}}}

'); - this.controller('application', { - title: 'Hello world', - }); - - return this.renderToHTML('/').then(function (html) { - assert.htmlMatches(html, '

Hello world

'); - }); - }); - - QUnit.test('outlets', function (assert) { - this.routes(function () { - this.route('photos'); - }); - - this.template('application', '

{{outlet}}

'); - this.template('index', 'index'); - this.template('photos', 'photos'); - - let promises = []; - promises.push( - this.renderToHTML('/').then(function (html) { - assert.htmlMatches(html, '

index

'); - }) - ); - - promises.push( - this.renderToHTML('/photos').then(function (html) { - assert.htmlMatches(html, '

photos

'); - }) - ); - - return this.all(promises); - }); - - QUnit.test('lifecycle hooks disabled', function (assert) { - assert.expect(1); - - this.template('application', "{{my-component foo='bar'}}{{outlet}}"); - - this.component('my-component', { - didReceiveAttrs() { - assert.ok(true, 'should trigger didReceiveAttrs hook'); - }, - willRender() { - assert.ok(false, 'should not trigger willRender hook'); - }, - didRender() { - assert.ok(false, 'should not trigger didRender hook'); - }, - willInsertElement() { - assert.ok(false, 'should not trigger willInsertElement hook'); - }, - didInsertElement() { - assert.ok(false, 'should not trigger didInsertElement hook'); - }, - }); - - return this.renderToHTML('/'); - }); -}); diff --git a/tests/node/component-rendering-test.js b/tests/node/component-rendering-test.js deleted file mode 100644 index 826c9322ca4..00000000000 --- a/tests/node/component-rendering-test.js +++ /dev/null @@ -1,45 +0,0 @@ -const setupComponentTest = require('./helpers/setup-component'); - -QUnit.module('Components can be rendered without a DOM dependency', function (hooks) { - setupComponentTest(hooks); - - QUnit.test('Simple component', function (assert) { - let html = this.render('

Hello

'); - - assert.ok(html.match(/

Hello<\/h1>/)); - }); - - QUnit.test('Component with dynamic value', function (assert) { - this.set('location', 'World'); - - let html = this.render('

Hello {{this.location}}

'); - - assert.ok(html.match(/

Hello World<\/h1>/)); - }); - - QUnit.test( - 'Ensure undefined attributes requiring protocol sanitization do not error', - function (assert) { - this.owner.register( - 'component:fake-link', - class extends this.Ember.Component { - tagName = 'link'; - attributeBindings = ['href', 'rel']; - rel = 'canonical'; - } - ); - - let html = this.render('{{fake-link}}'); - - assert.ok(html.match(/rel="canonical"/)); - } - ); - - QUnit.test('attributes requiring protocol sanitization do not error', function (assert) { - this.set('someHref', 'https://foo.com/'); - - let html = this.render('Some Link'); - - assert.ok(html.match(/Some Link<\/a>/)); - }); -}); diff --git a/tests/node/fastboot-sandbox-test.js b/tests/node/fastboot-sandbox-test.js deleted file mode 100644 index 741256e2211..00000000000 --- a/tests/node/fastboot-sandbox-test.js +++ /dev/null @@ -1,120 +0,0 @@ -const fs = require('fs'); -const vm = require('vm'); -const SimpleDOM = require('simple-dom'); -const { emberPath, loadEmber, clearEmber } = require('./helpers/load-ember'); - -// This is based on what fastboot-server does -let HTMLSerializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); - -async function fastbootVisit(context, url) { - let doc = new SimpleDOM.Document(); - let rootElement = doc.body; - let options = { isBrowser: false, document: doc, rootElement: rootElement }; - - let { app } = context; - - await app.boot(); - - let instance = await app.buildInstance(); - - try { - await instance.boot(options); - await instance.visit(url, options); - - return { - url: instance.getURL(), - title: doc.title, - body: HTMLSerializer.serialize(rootElement), - }; - } finally { - instance.destroy(); - } -} - -// essentially doing the same as what is done in FastBoot 3.1.0 -// https://github.com/ember-fastboot/fastboot/blob/v3.1.0/src/sandbox.js -function buildSandboxContext(precompile) { - let URL = require('url'); - - let sandbox = { - console, - setTimeout, - clearTimeout, - URL, - - // Convince jQuery not to assume it's in a browser - module: { exports: {}, require() {} }, - }; - - // Set the global as `window` - sandbox.window = sandbox; - sandbox.window.self = sandbox; - - let context = vm.createContext(sandbox); - - let environmentSetupScript = new vm.Script( - ` -var EmberENV = { - _DEFAULT_ASYNC_OBSERVERS: true, - _JQUERY_INTEGRATION: false, -};`, - { filename: 'prepend.js' } - ); - environmentSetupScript.runInContext(context); - - let emberSource = fs.readFileSync(emberPath, { encoding: 'utf-8' }); - let emberScript = new vm.Script(emberSource, { filename: emberPath }); - emberScript.runInContext(context); - - let applicationSource = ` -let Ember = module.exports; - -class Router extends Ember.Router {} -Router.map(function() { - this.route('a'); - this.route('b'); -}); - -const registry = { - 'router:main': Router, - 'template:application': ${precompile('

Hello world!

\n{{outlet}}')} -}; - -class Resolver extends Ember.Object { - resolve(specifier) { - return registry[specifier]; - } -} - -var app = class extends Ember.Application {}.create({ - autoboot: false, - Resolver, -}); -`; - let appScript = new vm.Script(applicationSource, { filename: 'app.js' }); - appScript.runInContext(context); - - return context; -} - -QUnit.module('Ember.Application - visit() Integration Tests', function (hooks) { - hooks.beforeEach(function () { - let { precompile } = loadEmber(); - this.context = buildSandboxContext(precompile); - }); - - hooks.afterEach(function () { - clearEmber(); - }); - - QUnit.test('FastBoot: basic', async function (assert) { - let result = await fastbootVisit(this.context, '/'); - - assert.equal(result.url, '/', 'landed on correct url'); - assert.equal( - result.body, - '

Hello world!

\n', - 'results in expected HTML' - ); - }); -}); diff --git a/tests/node/fixtures/project.js b/tests/node/fixtures/project.js deleted file mode 100644 index bcc867af91c..00000000000 --- a/tests/node/fixtures/project.js +++ /dev/null @@ -1,148 +0,0 @@ -module.exports = class Project { - static withDep(depOptions = {}, projectOptions = {}) { - let addons = projectOptions.addons || []; - - return new Project({ - ...projectOptions, - addons: [...addons, new Addon(depOptions)], - }); - } - - static withTransientDep(transientDepOptions = {}, depOptions = {}, projectOptions = {}) { - let addons = depOptions.addons || []; - - return Project.withDep( - { - ...depOptions, - addons: [ - ...addons, - new Addon({ - name: 'my-nested-addon', - version: '0.1.0', - ...transientDepOptions, - }), - ], - }, - projectOptions - ); - } - - constructor({ - name = 'my-app', - emberCliBabel, - dependencies = {}, - devDependencies = {}, - addons = [], - } = {}) { - this.name = () => name; - this.parent = null; - this.pkg = { - name, - dependencies: { ...dependencies }, - devDependencies: { ...devDependencies }, - }; - this.addons = [...addons]; - - if (typeof emberCliBabel === 'string') { - this.pkg.devDependencies['ember-cli-babel'] = emberCliBabel; - } - - reifyAddons(this); - addMissingAddons(this, this.pkg.devDependencies); - addMissingAddons(this, this.pkg.dependencies); - addMissingDeps(this, true); - } -}; - -class Addon { - constructor({ - parent, - name = 'my-addon', - version = '1.0.0', - emberCliBabel, - dependencies = {}, - addons = [], - hasJSFiles = name !== 'ember-cli-babel', - } = {}) { - this.parent = parent; - this.name = name; - this.pkg = { - name, - version, - dependencies: { ...dependencies }, - devDependencies: {}, - }; - this.addons = [...addons]; - this._fileSystemInfo = () => ({ hasJSFiles }); - - if (typeof emberCliBabel === 'string') { - this.pkg.dependencies['ember-cli-babel'] = emberCliBabel; - } - - reifyAddons(this); - addMissingAddons(this, this.pkg.dependencies); - addMissingDeps(this); - } -} - -// Can only handle the few hardcoded cases -function resolve(requirement) { - if (requirement.startsWith('link:')) { - // Expecting something like "link:1.2.3" - return requirement.slice(5); - } else { - // Only handles "^1.0.0" -> "1.0.0", doesn't work for the general case - return requirement.slice(1); - } -} - -function reifyAddons(parent) { - parent.addons = parent.addons.map((addon) => { - if (addon instanceof Addon) { - addon.parent = parent; - return addon; - } else { - let version = addon.version; - - if (!version) { - if (parent.pkg.devDependencies[addon.name]) { - version = resolve(parent.pkg.devDependencies[addon.name]); - } else if (parent.pkg.dependencies[addon.name]) { - version = resolve(parent.pkg.dependencies[addon.name]); - } - } - - return new Addon({ ...addon, parent, version }); - } - }); -} - -function addMissingAddons(parent, deps) { - for (let [name, requirement] of Object.entries(deps)) { - if (!parent.addons.find((addon) => addon.name === name)) { - parent.addons.push( - new Addon({ - parent, - name, - version: resolve(requirement), - }) - ); - } - } -} - -function addMissingDeps(parent, devDeps = false) { - for (let addon of parent.addons) { - let target = parent.pkg.dependencies; - let isMissing = !(addon.name in target); - - if (devDeps) { - target = parent.pkg.devDependencies; - isMissing = isMissing && !(addon.name in target); - } - - if (isMissing) { - target[addon.name] = `^${addon.pkg.version}`; - } - } -} diff --git a/tests/node/helpers/assert-html-matches.js b/tests/node/helpers/assert-html-matches.js deleted file mode 100644 index 49cb64c23bb..00000000000 --- a/tests/node/helpers/assert-html-matches.js +++ /dev/null @@ -1,27 +0,0 @@ -const { HtmlDiffer } = require('html-differ'); - -const htmlDiffer = new HtmlDiffer({ - ignoreAttributes: ['id'], - ignoreWhitespaces: true, -}); - -module.exports = { - /* - * This assertion helper tests whether two fragments of Html 'appear' - * to match. In terms of fragments rendered by Ember, we want to explicitly - * ignore whitespace and certain attributes values, such as IDs, which Ember - * auto-generates. Attribute ordering is also ignored. - */ - register() { - QUnit.assert.htmlMatches = function (actual, expected, message) { - let isEqual = htmlDiffer.isEqual(actual, expected); - - this.pushResult({ - result: isEqual, - actual, - expected, - message, - }); - }; - }, -}; diff --git a/tests/node/helpers/build-owner.js b/tests/node/helpers/build-owner.js deleted file mode 100644 index 672a399838e..00000000000 --- a/tests/node/helpers/build-owner.js +++ /dev/null @@ -1,28 +0,0 @@ -module.exports = function buildOwner(Ember, resolver) { - let Owner = Ember.Object.extend(Ember._RegistryProxyMixin, Ember._ContainerProxyMixin); - - let namespace = Ember.Object.create({ - Resolver: { - create: function () { - return resolver; - }, - }, - }); - - let fallbackRegistry = Ember.Application.buildRegistry(namespace); - let registry = new Ember.Registry({ - fallback: fallbackRegistry, - }); - - Ember.ApplicationInstance.setupRegistry(registry); - - let owner = Owner.create({ - __registry__: registry, - __container__: null, - }); - - let container = registry.container({ owner: owner }); - owner.__container__ = container; - - return owner; -}; diff --git a/tests/node/helpers/load-ember.js b/tests/node/helpers/load-ember.js deleted file mode 100644 index 740ae9c3c61..00000000000 --- a/tests/node/helpers/load-ember.js +++ /dev/null @@ -1,47 +0,0 @@ -const path = require('path'); -const distPath = path.join(__dirname, '../../../dist'); -const emberPath = path.join(distPath, 'ember.debug.js'); -const templateCompilerPath = path.join(distPath, 'ember-template-compiler'); - -// We store the global symbols beforehand so that we can reset the state -// properly to avoid the @glimmer/validator assertion -const originalGlobalSymbols = Object.getOwnPropertySymbols(global).map((sym) => [sym, global[sym]]); - -module.exports.emberPath = require.resolve(emberPath); - -module.exports.loadEmber = function () { - let Ember = require(emberPath); - - let _precompile = require(templateCompilerPath).precompile; - - let precompile = function (templateString, options) { - let templateSpec = _precompile(templateString, options); - - return `Ember.HTMLBars.template(${templateSpec})`; - }; - - let compile = function (templateString, options) { - let templateSpec = _precompile(templateString, options); - let template = new Function('return ' + templateSpec)(); - - return Ember.HTMLBars.template(template); - }; - - return { Ember, compile, precompile }; -}; - -module.exports.clearEmber = function () { - delete global.Ember; - - Object.getOwnPropertySymbols(global).forEach((sym) => { - delete global[sym]; - }); - - originalGlobalSymbols.forEach(([sym, value]) => { - global[sym] = value; - }); - - // clear the previously cached version of this module - delete require.cache[emberPath + '.js']; - delete require.cache[templateCompilerPath + '.js']; -}; diff --git a/tests/node/helpers/setup-app.js b/tests/node/helpers/setup-app.js deleted file mode 100644 index 0254933f12a..00000000000 --- a/tests/node/helpers/setup-app.js +++ /dev/null @@ -1,199 +0,0 @@ -/* eslint-disable no-console */ - -const SimpleDOM = require('simple-dom'); -const { loadEmber, clearEmber } = require('./load-ember'); - -/* - * This helper sets up a QUnit test module with all of the environment and - * helper methods necessary to test an Ember.js application running in the - * server-side environment. - * - * On each test, it loads a fresh version of the compiled Ember.js library - * from `dist`, just like how FastBoot works. It uses the new `visit()` API - * to simulate a FastBoot environment (enabling that feature flag if it is - * not already turned on). - * - * To test an app, register the objects that make up the app. For example, - * to register a component: - * - * this.component('component-name', { - * componentProperty: true - * }); - * - * Or a template: - * - * this.template('application', '{{outlet}}'); - * this.template('components/foo-bar', '

Hello world

'); - * - * Or a controller: - * - * this.controller('controller-name', { - * actions: { - * sendEmail: function() { } - * } - * }); - * - * You can also provide the routes for the application by calling `this.routes()`, - * which is equivalent to `App.Router.map()`: - * - * this.routes(function() { - * this.route('photos'); - * this.route('admin', function() { - * this.route('logout'); - * }); - * }); - * - * Once all of the constituent parts of the app are registered, you can kick off - * app boot by calling either `this.visit(url)` or `this.renderToHTML(url)`. - * - * `visit` returns a promise that resolves to the application instance, and - * `renderToHTML` returns a promise that resolves to the rendered HTML of the - * application. - * - * return this.renderToHTML('/'photos).then(function(html) { - * assert.ok(html.matches('

Hello world

')); - * }); - */ - -module.exports = function (hooks) { - hooks.beforeEach(function () { - let { Ember, compile } = loadEmber(); - - this.Ember = Ember; - this.compile = compile; - this.setComponentTemplate = Ember._setComponentTemplate; - this.templateOnlyComponent = Ember._templateOnlyComponent; - - Ember.testing = true; - - this.run = Ember.run; - this.all = Ember.RSVP.all; - - this.visit = visit; - this.createApplication = createApplication; - this.register = register; - this.template = registerTemplate; - this.component = registerComponent; - this.controller = registerController; - this.route = registerRoute; - this.service = registerService; - this.routes = registerRoutes; - this.registry = {}; - this.renderToHTML = renderToHTML; - }); - - hooks.afterEach(function () { - this.run(this.app, 'destroy'); - - clearEmber(); - }); -}; - -function createApplication() { - if (this.app) return this.app; - - let app = class extends this.Ember.Application {}.create({ - autoboot: false, - Resolver: { - create: (specifier) => { - return this.registry[specifier]; - }, - }, - }); - - let Router = class extends this.Ember.Router { - location = 'none'; - }; - - if (this.routesCallback) { - Router.map(this.routesCallback); - } - - this.register('router:main', Router); - - registerApplicationClasses(app, this.registry); - - // Run application initializers - this.run(app, 'boot'); - - this.app = app; - - return app; -} - -function register(containerKey, klass) { - this.registry[containerKey] = klass; -} - -function visit(url) { - let app = this.createApplication(); - let dom = new SimpleDOM.Document(); - - return this.run(app, 'visit', url, { - isBrowser: false, - document: dom, - rootElement: dom.body, - }).catch(function (error) { - console.error(error.stack); - }); -} - -function renderToHTML(url) { - let app = this.createApplication(); - let dom = new SimpleDOM.Document(); - let root = dom.body; - - return this.run(app, 'visit', url, { - isBrowser: false, - document: dom, - rootElement: root, - }).then(function () { - let serializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); - return serializer.serialize(root); - }); -} - -function registerApplicationClasses(app, registry) { - app.initializer({ - name: 'register-application-classes', - initialize: function (app) { - for (let key in registry) { - app.register(key, registry[key]); - } - }, - }); -} - -function registerTemplate(name, template) { - this.register('template:' + name, this.compile(template)); -} - -function registerComponent(name, componentProps, templateContents) { - let component = this.setComponentTemplate( - this.compile(templateContents), - componentProps ? this.Ember.Component.extend(componentProps) : this.templateOnlyComponent() - ); - this.register('component:' + name, component); -} - -function registerController(name, controllerProps) { - let controller = this.Ember.Controller.extend(controllerProps); - this.register('controller:' + name, controller); -} - -function registerRoute(name, routeProps) { - let route = this.Ember.Route.extend({ - router: this.Ember.inject.service('router'), - ...routeProps, - }); - this.register('route:' + name, route); -} - -function registerService(name, serviceProps) { - let service = this.Ember.Object.extend(serviceProps); - this.register('service:' + name, service); -} - -function registerRoutes(cb) { - this.routesCallback = cb; -} diff --git a/tests/node/helpers/setup-component.js b/tests/node/helpers/setup-component.js deleted file mode 100644 index 7f21d180a50..00000000000 --- a/tests/node/helpers/setup-component.js +++ /dev/null @@ -1,111 +0,0 @@ -'use strict'; - -const SimpleDOM = require('simple-dom'); -const buildOwner = require('./build-owner'); -const { loadEmber, clearEmber } = require('./load-ember'); - -module.exports = function (hooks) { - hooks.beforeEach(function () { - let { Ember, compile } = loadEmber(); - - this.compile = compile; - this.Ember = Ember; - - Ember.testing = true; - this.run = Ember.run; - - setupComponentTest.call(this); - }); - - hooks.afterEach(function () { - let module = this; - - if (this.component) { - this.run(function () { - module.component.destroy(); - }); - - this.component = null; - } - - this.run(this.owner, 'destroy'); - this.owner = null; - this.Ember = null; - - clearEmber(); - }); -}; - -function setupComponentTest() { - let module = this; - - module.element = new SimpleDOM.Document(); - module.owner = buildOwner(this.Ember, { resolve: function () {} }); - module.owner.register('service:-document', new SimpleDOM.Document(), { - instantiate: false, - }); - - this._hasRendered = false; - let OutletView = module.owner.factoryFor('view:-outlet'); - let outletTemplateFactory = module.owner.lookup('template:-outlet'); - let environment = module.owner.lookup('-environment:main'); - module.component = OutletView.create({ environment, template: outletTemplateFactory }); - this._outletState = { - render: { - owner: module.owner || undefined, - name: 'application', - controller: module, - model: undefined, - template: outletTemplateFactory(module.owner), - }, - - outlets: {}, - }; - - this.run(function () { - module.component.setOutletState(module._outletState); - }); - - module.render = render; - module.serializeElement = serializeElement; - module.set = function (property, value) { - module.run(function () { - module.Ember.set(module, property, value); - }); - }; -} - -function render(_template) { - let module = this; - let templateFactory = this.compile(_template); - - let stateToRender = { - owner: this.owner, - name: 'index', - controller: this, - model: undefined, - template: templateFactory(this.owner), - }; - - stateToRender.name = 'index'; - this._outletState.outlets.main = { render: stateToRender, outlets: {} }; - - this.run(function () { - module.component.setOutletState(module._outletState); - }); - - if (!this._hasRendered) { - this.run(function () { - module.component.appendTo(module.element); - }); - this._hasRendered = true; - } - - return this.serializeElement(); -} - -function serializeElement() { - let serializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); - - return serializer.serialize(this.element); -} diff --git a/tests/node/instrumentation-test.js b/tests/node/instrumentation-test.js deleted file mode 100644 index b6c5f665fff..00000000000 --- a/tests/node/instrumentation-test.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -const { loadEmber, clearEmber } = require('./helpers/load-ember'); - -const { Ember } = loadEmber(); - -QUnit.module('instrumentation', function (hooks) { - hooks.afterEach(function () { - clearEmber(); - }); - - QUnit.test('it works in FastBoot environment', function (assert) { - let _originalWindow = global.window; - - global.window = {}; // mock window without `performance` property - - let result = Ember.instrument('render', {}, function () { - return 'hello'; - }); - - assert.equal(result, 'hello', 'called block'); - - global.window = _originalWindow; - }); -}); diff --git a/tests/node/overrides-test.js b/tests/node/overrides-test.js deleted file mode 100644 index fad26650362..00000000000 --- a/tests/node/overrides-test.js +++ /dev/null @@ -1,789 +0,0 @@ -'use strict'; - -const Project = require('./fixtures/project'); -const Overrides = require('../../lib/overrides'); - -function cmp(a, b) { - if (a == undefined || a < b) { - return -1; - } else if (b == undefined || a > b) { - return 1; - } else { - return 0; - } -} - -function addonsInfoFor(project) { - if (!(project instanceof Project)) { - project = new Project(project); - } - - let addonsInfo = [...Overrides.addonsInfoFor(project)]; - - addonsInfo.sort((a, b) => cmp(a.topLevel, b.topLevel) || cmp(a.parent, b.parent)); - - return addonsInfo; -} - -function fullExample() { - return { - name: 'direwolf', - devDependencies: { - 'active-model-adapter': '^2.2.0', - 'ember-animated': '^0.11.0', - 'ember-cli-babel': '^7.26.3', - 'ember-fetch': '^8.0.5', - 'ember-source': 'link:3.27.3', - }, - addons: [ - { - name: 'active-model-adapter', - dependencies: { - 'ember-cli-babel': '^6.18.0', - }, - }, - { - name: 'ember-animated', - dependencies: { - 'ember-angle-bracket-invocation-polyfill': '^2.0.0', - 'ember-cli-babel': '^7.26.3', - }, - addons: [ - { - name: 'ember-angle-bracket-invocation-polyfill', - dependencies: { - 'ember-cli-babel': '^6.16.0', - }, - addons: [ - { - name: 'ember-cli-babel', - version: '6.18.0', - }, - ], - }, - { - name: 'ember-cli-babel', - version: '7.26.5', - }, - ], - }, - { - name: 'ember-cli-babel', - version: '7.26.5', - }, - { - name: 'ember-fetch', - hasJSFiles: false, - dependencies: { - 'ember-cli-babel': '^7.26.0', - }, - }, - { - name: 'ember-source', - dependencies: { - 'ember-cli-babel': '^7.26.6', - }, - }, - ], - }; -} - -function infoForApp({ - name = 'direwolf', - version = '7.26.6', - requirement = `^${version}`, - compatible = requirement.startsWith('^7'), -} = {}) { - return { - parent: `${name} (your app)`, - topLevel: null, - version, - requirement, - compatible, - dormant: false, - path: [], - }; -} - -// function info({ -// parent, -// topLevel = parent, -// version = '7.26.6', -// requirement = `^${version}`, -// compatible = requirement.startsWith('^7'), -// dormant = false, -// path = [`${parent}@${version}`], -// } = {}) { -// return { -// parent, -// topLevel, -// version, -// requirement, -// compatible, -// dormant, -// path, -// }; -// } - -QUnit.module('Overrides', function () { - QUnit.module('.addonsInfoFor', function () { - // app - - QUnit.test('it returns old babel added by app', function (assert) { - assert.deepEqual(addonsInfoFor({ emberCliBabel: '^6.0.0' }), [ - { - parent: 'my-app (your app)', - topLevel: null, - version: '6.0.0', - requirement: '^6.0.0', - compatible: false, - dormant: false, - path: [], - }, - ]); - }); - - QUnit.test('it returns old but compatible babel added by app', function (assert) { - assert.deepEqual(addonsInfoFor({ emberCliBabel: '^7.0.0' }), [ - { - parent: 'my-app (your app)', - topLevel: null, - version: '7.0.0', - requirement: '^7.0.0', - compatible: true, - dormant: false, - path: [], - }, - ]); - }); - - QUnit.test('it does not return new babel added by app', function (assert) { - assert.deepEqual(addonsInfoFor({ emberCliBabel: '^7.26.6' }), []); - }); - - // direct dependency - - QUnit.test('it returns old babel added by a dependency', function (assert) { - assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^6.0.0' })), [ - { - parent: 'my-addon@1.0.0', - topLevel: 'my-addon', - version: '6.0.0', - requirement: '^6.0.0', - compatible: false, - dormant: false, - path: ['my-addon@1.0.0'], - }, - ]); - }); - - QUnit.test('it returns old but compatible babel added by a dependency', function (assert) { - assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^7.0.0' })), [ - { - parent: 'my-addon@1.0.0', - topLevel: 'my-addon', - version: '7.0.0', - requirement: '^7.0.0', - compatible: true, - dormant: false, - path: ['my-addon@1.0.0'], - }, - ]); - }); - - QUnit.test('it does not return new babel added by a dependency', function (assert) { - assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6' })), []); - }); - - // direct dependency (dormant) - - QUnit.test('it returns old babel added by a dormant dependency', function (assert) { - assert.deepEqual( - addonsInfoFor(Project.withDep({ emberCliBabel: '^6.0.0', hasJSFiles: false })), - [ - { - parent: 'my-addon@1.0.0', - topLevel: 'my-addon', - version: '6.0.0', - requirement: '^6.0.0', - compatible: false, - dormant: true, - path: ['my-addon@1.0.0'], - }, - ] - ); - }); - - QUnit.test( - 'it returns old but compatible babel added by a dormant dependency', - function (assert) { - assert.deepEqual( - addonsInfoFor(Project.withDep({ emberCliBabel: '^7.0.0', hasJSFiles: false })), - [ - { - parent: 'my-addon@1.0.0', - topLevel: 'my-addon', - version: '7.0.0', - requirement: '^7.0.0', - compatible: true, - dormant: true, - path: ['my-addon@1.0.0'], - }, - ] - ); - } - ); - - QUnit.test('it does not return new babel added by a dormant dependency', function (assert) { - assert.deepEqual( - addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6', hasJSFiles: false })), - [] - ); - }); - - // transient dep - - QUnit.test('it returns old babel added by a transient dependency', function (assert) { - assert.deepEqual(addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^6.0.0' })), [ - { - parent: 'my-nested-addon@0.1.0', - topLevel: 'my-addon', - version: '6.0.0', - requirement: '^6.0.0', - compatible: false, - dormant: false, - path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], - }, - ]); - }); - - QUnit.test( - 'it returns old but compatible babel added by a transient dependency', - function (assert) { - assert.deepEqual(addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^7.0.0' })), [ - { - parent: 'my-nested-addon@0.1.0', - topLevel: 'my-addon', - version: '7.0.0', - requirement: '^7.0.0', - compatible: true, - dormant: false, - path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], - }, - ]); - } - ); - - QUnit.test('it does not return new babel added by a transient dependency', function (assert) { - assert.deepEqual(addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6' })), []); - }); - - // dormant transient dep - - QUnit.test('it returns old babel added by a dormant transient dependency', function (assert) { - assert.deepEqual( - addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^6.0.0', hasJSFiles: false })), - [ - { - parent: 'my-nested-addon@0.1.0', - topLevel: 'my-addon', - version: '6.0.0', - requirement: '^6.0.0', - compatible: false, - dormant: true, - path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], - }, - ] - ); - }); - - QUnit.test( - 'it returns old but compatible babel added by a dormant transient dependency', - function (assert) { - assert.deepEqual( - addonsInfoFor(Project.withTransientDep({ emberCliBabel: '^7.0.0', hasJSFiles: false })), - [ - { - parent: 'my-nested-addon@0.1.0', - topLevel: 'my-addon', - version: '7.0.0', - requirement: '^7.0.0', - compatible: true, - dormant: true, - path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], - }, - ] - ); - } - ); - - QUnit.test( - 'it does not return new babel added by a dormant transient dependency', - function (assert) { - assert.deepEqual( - addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6', hasJSFiles: false })), - [] - ); - } - ); - - // transient dep through a dormant dep - - QUnit.test( - 'it returns old babel added by a transient dependency through a dormant dependency', - function (assert) { - assert.deepEqual( - addonsInfoFor( - Project.withTransientDep({ emberCliBabel: '^6.0.0' }, { hasJSFiles: false }) - ), - [ - { - parent: 'my-nested-addon@0.1.0', - topLevel: 'my-addon', - version: '6.0.0', - requirement: '^6.0.0', - compatible: false, - dormant: false, - path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], - }, - ] - ); - } - ); - - QUnit.test( - 'it returns old but compatible babel added by a transient dependency through a dormant dependency', - function (assert) { - assert.deepEqual( - addonsInfoFor( - Project.withTransientDep({ emberCliBabel: '^7.0.0' }, { hasJSFiles: false }) - ), - [ - { - parent: 'my-nested-addon@0.1.0', - topLevel: 'my-addon', - version: '7.0.0', - requirement: '^7.0.0', - compatible: true, - dormant: false, - path: ['my-addon@1.0.0', 'my-nested-addon@0.1.0'], - }, - ] - ); - } - ); - - QUnit.test( - 'it does not return new babel added by a transient dependency through a dormant dependency', - function (assert) { - assert.deepEqual( - addonsInfoFor(Project.withDep({ emberCliBabel: '^7.26.6' }, { hasJSFiles: false })), - [] - ); - } - ); - - // linked dep - - QUnit.test('it returns old babel added by a linked dependency', function (assert) { - assert.deepEqual( - addonsInfoFor( - new Project({ - devDependencies: { - 'ember-source': 'link:3.27.3', - }, - addons: [ - { - name: 'ember-source', - emberCliBabel: '^6.0.0', - }, - ], - }) - ), - [ - { - parent: 'ember-source@3.27.3', - topLevel: 'ember-source', - version: '6.0.0', - requirement: '^6.0.0', - compatible: false, - dormant: false, - path: ['ember-source@3.27.3'], - }, - ] - ); - }); - - QUnit.test( - 'it returns old but compatible babel added by a linked dependency', - function (assert) { - assert.deepEqual( - addonsInfoFor( - new Project({ - devDependencies: { - 'ember-source': 'link:3.27.3', - }, - addons: [ - { - name: 'ember-source', - emberCliBabel: '^7.0.0', - }, - ], - }) - ), - [ - { - parent: 'ember-source@3.27.3', - topLevel: 'ember-source', - version: '7.0.0', - requirement: '^7.0.0', - compatible: true, - dormant: false, - path: ['ember-source@3.27.3'], - }, - ] - ); - } - ); - - QUnit.test('it does not return new babel added by a linked dependency', function (assert) { - assert.deepEqual( - addonsInfoFor( - new Project({ - devDependencies: { - 'ember-source': 'link:3.27.3', - }, - addons: [ - { - name: 'ember-source', - emberCliBabel: '^7.26.6', - }, - ], - }) - ), - [] - ); - }); - - // full example - - QUnit.test('full example', function (assert) { - let project = new Project(fullExample()); - - assert.deepEqual(addonsInfoFor(project), [ - { - parent: 'direwolf (your app)', - topLevel: null, - version: '7.26.5', - requirement: '^7.26.3', - compatible: true, - dormant: false, - path: [], - }, - { - parent: 'active-model-adapter@2.2.0', - topLevel: 'active-model-adapter', - version: '6.18.0', - requirement: '^6.18.0', - compatible: false, - dormant: false, - path: ['active-model-adapter@2.2.0'], - }, - { - parent: 'ember-angle-bracket-invocation-polyfill@2.0.0', - topLevel: 'ember-animated', - version: '6.18.0', - requirement: '^6.16.0', - compatible: false, - dormant: true, - path: ['ember-animated@0.11.0', 'ember-angle-bracket-invocation-polyfill@2.0.0'], - }, - { - parent: 'ember-animated@0.11.0', - topLevel: 'ember-animated', - version: '7.26.5', - requirement: '^7.26.3', - compatible: true, - dormant: false, - path: ['ember-animated@0.11.0'], - }, - { - parent: 'ember-fetch@8.0.5', - topLevel: 'ember-fetch', - version: '7.26.0', - requirement: '^7.26.0', - compatible: true, - dormant: true, - path: ['ember-fetch@8.0.5'], - }, - ]); - }); - }); - - QUnit.module('.printList', function () { - QUnit.test('it can print a flat list', function (assert) { - assert.equal( - Overrides.printList(['first', 'second', 'third'], ' '), - `\ - * first - * second - * third -` - ); - }); - - QUnit.test('it can print a nested list', function (assert) { - assert.equal( - Overrides.printList( - [ - 'first', - [ - 'second', - ['second.1', ['second.2', ['second.2.1', 'second.2.2', 'second.2.3']], 'second.3'], - ], - 'third', - ], - ' ' - ), - `\ - * first - * second - * second.1 - * second.2 - * second.2.1 - * second.2.2 - * second.2.3 - * second.3 - * third -` - ); - }); - }); - - QUnit.test('it does nothing when in production', function (assert) { - let project = new Project(fullExample()); - let overrides = Overrides.for(project, { EMBER_ENV: 'production' }); - - assert.false(overrides.hasOverrides, 'hasOverrides'); - assert.false(overrides.hasBuildTimeWarning, 'hasBuildTimeWarning'); - }); - - QUnit.test('it does nothing when everything is on new babel', function (assert) { - let overrides = new Overrides([]); - - assert.false(overrides.hasOverrides, 'hasOverrides'); - assert.false(overrides.hasBuildTimeWarning, 'hasBuildTimeWarning'); - }); - - QUnit.test('when app is on old babel', function (assert) { - let overrides = new Overrides([infoForApp({ version: '6.0.0' })]); - - assert.true(overrides.hasOverrides, 'hasOverrides'); - assert.true(overrides.hasBuildTimeWarning, 'hasBuildTimeWarning'); - assert.true(overrides.hasActionableSuggestions, 'hasActionableSuggestions'); - assert.false(overrides.hasCompatibleAddons, 'hasCompatibleAddons'); - assert.false(overrides.hasDormantAddons, 'hasDormantAddons'); - }); - - // let project, env; - - // function buildBabel(parent, version) { - // return { - // name: 'ember-cli-babel', - // parent, - // pkg: { - // version, - // }, - // addons: [], - // }; - // } - - // hooks.beforeEach(function () { - // project = { - // name() { - // return 'fake-project'; - // }, - // pkg: { - // dependencies: {}, - // devDependencies: {}, - // }, - // addons: [], - // }; - // env = Object.create(null); - // }); - - // hooks.afterEach(function () {}); - - // QUnit.test('when in production, does nothing', function (assert) { - // env.EMBER_ENV = 'production'; - - // let result = globalDeprecationInfo(project, env); - - // assert.deepEqual(result, { - // globalMessage: '', - // hasActionableSuggestions: false, - // shouldIssueSingleDeprecation: false, - // bootstrap: `require('@ember/-internals/bootstrap').default()`, - // }); - // }); - - // QUnit.test('without addons, does nothing', function (assert) { - // project.addons = []; - // let result = globalDeprecationInfo(project, env); - - // assert.deepEqual(result, { - // globalMessage: '', - // hasActionableSuggestions: false, - // shouldIssueSingleDeprecation: false, - // bootstrap: `require('@ember/-internals/bootstrap').default()`, - // }); - // }); - - // QUnit.test('projects own ember-cli-babel is too old', function (assert) { - // project.pkg.devDependencies = { - // 'ember-cli-babel': '^7.26.0', - // }; - - // project.addons.push({ - // name: 'ember-cli-babel', - // parent: project, - // pkg: { - // version: '7.26.5', - // }, - // addons: [], - // }); - - // let result = globalDeprecationInfo(project, env); - // assert.strictEqual(result.shouldIssueSingleDeprecation, true); - // assert.strictEqual(result.hasActionableSuggestions, true); - // assert.ok( - // result.globalMessage.includes( - // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' - // ) - // ); - // }); - - // QUnit.test('projects has ember-cli-babel in dependencies', function (assert) { - // project.pkg.dependencies = { - // 'ember-cli-babel': '^7.25.0', - // }; - - // project.addons.push({ - // name: 'ember-cli-babel', - // parent: project, - // pkg: { - // version: '7.26.5', - // }, - // addons: [], - // }); - - // let result = globalDeprecationInfo(project, env); - // assert.strictEqual(result.shouldIssueSingleDeprecation, true); - // assert.strictEqual(result.hasActionableSuggestions, true); - // assert.ok( - // result.globalMessage.includes( - // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' - // ) - // ); - // }); - // QUnit.test( - // 'projects has no devDependencies, but old ember-cli-babel found in addons array', - // function (assert) { - // project.pkg.devDependencies = {}; - - // project.addons.push({ - // name: 'ember-cli-babel', - // parent: project, - // pkg: { - // version: '7.26.5', - // }, - // addons: [], - // }); - - // let result = globalDeprecationInfo(project, env); - // assert.strictEqual(result.shouldIssueSingleDeprecation, true); - // assert.strictEqual(result.hasActionableSuggestions, true); - // assert.ok( - // result.globalMessage.includes( - // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' - // ) - // ); - // } - // ); - - // QUnit.test('projects uses linked ember-cli-babel', function (assert) { - // project.pkg.devDependencies = { - // 'ember-cli-babel': 'link:./some/path/here', - // }; - - // let otherAddon = { - // name: 'other-thing-here', - // parent: project, - // pkg: {}, - // addons: [], - // }; - - // otherAddon.addons.push(buildBabel(otherAddon, '7.26.5')); - // project.addons.push(buildBabel(project, '7.26.6'), otherAddon); - - // let result = globalDeprecationInfo(project, env); - // assert.strictEqual(result.shouldIssueSingleDeprecation, true); - // assert.strictEqual(result.hasActionableSuggestions, true); - - // assert.ok( - // result.globalMessage.includes( - // '* If using yarn, run `npx yarn-deduplicate --packages ember-cli-babel`' - // ) - // ); - // assert.ok(result.globalMessage.includes('* If using npm, run `npm dedupe`')); - // }); - - // QUnit.test('projects own ember-cli-babel is up to date', function (assert) { - // project.pkg.devDependencies = { - // 'ember-cli-babel': '^7.26.0', - // }; - - // project.addons.push({ - // name: 'ember-cli-babel', - // parent: project, - // pkg: { - // version: '7.26.6', - // }, - // addons: [], - // }); - - // let result = globalDeprecationInfo(project, env); - // assert.strictEqual(result.shouldIssueSingleDeprecation, false); - // assert.strictEqual(result.hasActionableSuggestions, false); - // assert.notOk( - // result.globalMessage.includes( - // '* Upgrade your `devDependencies` on `ember-cli-babel` to `^7.26.6`' - // ) - // ); - // }); - - // QUnit.test('transient babel that is out of date', function (assert) { - // project.pkg.devDependencies = { - // 'ember-cli-babel': '^7.26.0', - // }; - - // let otherAddon = { - // name: 'other-thing-here', - // parent: project, - // pkg: { - // dependencies: { - // 'ember-cli-babel': '^7.25.0', - // }, - // }, - // addons: [], - // }; - - // otherAddon.addons.push(buildBabel(otherAddon, '7.26.5')); - // project.addons.push(buildBabel(project, '7.26.6'), otherAddon); - - // let result = globalDeprecationInfo(project, env); - // assert.strictEqual(result.shouldIssueSingleDeprecation, true); - // assert.strictEqual(result.hasActionableSuggestions, true); - // assert.ok(result.globalMessage.includes('* other-thing-here@7.26.5 (Compatible)')); - // }); -}); diff --git a/tests/node/sourcemap-test.js b/tests/node/sourcemap-test.js deleted file mode 100644 index 16000c99d86..00000000000 --- a/tests/node/sourcemap-test.js +++ /dev/null @@ -1,23 +0,0 @@ -const fs = require('fs'); - -QUnit.module('sourcemap validation', function () { - QUnit.test(`ember.js has only a single sourcemaps comment`, function (assert) { - let jsPath = `dist/ember.debug.js`; - assert.ok(fs.existsSync(jsPath)); - - let contents = fs.readFileSync(jsPath, 'utf-8'); - let num = count(contents, '//# sourceMappingURL='); - assert.equal(num, 1); - }); -}); - -function count(source, find) { - let num = 0; - - let i = -1; - while ((i = source.indexOf(find, i + 1)) !== -1) { - num += 1; - } - - return num; -} diff --git a/tests/node/template-compiler-test.js b/tests/node/template-compiler-test.js deleted file mode 100644 index 4fcb051a8ee..00000000000 --- a/tests/node/template-compiler-test.js +++ /dev/null @@ -1,68 +0,0 @@ -const path = require('path'); - -const distPath = path.join(__dirname, '../../dist'); - -let templateCompiler; - -QUnit.module('ember-template-compiler.js', function () { - QUnit.module('modern', function (hooks) { - hooks.beforeEach(function () { - this.templateCompilerPath = path.resolve(path.join(distPath, 'ember-template-compiler.js')); - templateCompiler = require(this.templateCompilerPath); - }); - - hooks.afterEach(function () { - // clear the previously cached version of this module - delete require.cache[this.templateCompilerPath]; - }); - - QUnit.test('can be required', function (assert) { - assert.strictEqual( - typeof templateCompiler.precompile, - 'function', - 'precompile function is present' - ); - assert.strictEqual( - typeof templateCompiler.compile, - 'function', - 'compile function is present' - ); - }); - - QUnit.test('can access _Ember.ENV (private API used by ember-cli-htmlbars)', function (assert) { - assert.equal(typeof templateCompiler._Ember.ENV, 'object', '_Ember.ENV is present'); - assert.notEqual(typeof templateCompiler._Ember.ENV, null, '_Ember.ENV is not null'); - }); - - QUnit.test('_Ember.ENV (private API used by ember-cli-htmlbars) is stable', function (assert) { - assert.strictEqual( - templateCompiler._Ember.ENV, - templateCompiler._Ember.ENV, - '_Ember.ENV is stable' - ); - }); - - QUnit.test( - 'can access _Ember.FEATURES (private API used by ember-cli-htmlbars)', - function (assert) { - assert.equal( - typeof templateCompiler._Ember.FEATURES, - 'object', - '_Ember.FEATURES is present' - ); - assert.notEqual( - typeof templateCompiler._Ember.FEATURES, - null, - '_Ember.FEATURES is not null' - ); - } - ); - - QUnit.test( - 'can access _Ember.VERSION (private API used by ember-cli-htmlbars)', - function (assert) { - assert.equal(typeof templateCompiler._Ember.VERSION, 'string', '_Ember.VERSION is present'); - } - ); - }); -}); diff --git a/tests/node/visit-test.js b/tests/node/visit-test.js deleted file mode 100644 index 4b7dca9008a..00000000000 --- a/tests/node/visit-test.js +++ /dev/null @@ -1,357 +0,0 @@ -const SimpleDOM = require('simple-dom'); -const setupAppTest = require('./helpers/setup-app'); - -function assertHTMLMatches(assert, actualHTML, expectedHTML) { - assert.ok(actualHTML.match(expectedHTML), actualHTML + ' matches ' + expectedHTML); -} - -function handleError(assert) { - return function (error) { - assert.ok(false, error.stack); - }; -} - -// This is based on what fastboot-server does -let HTMLSerializer = new SimpleDOM.HTMLSerializer(SimpleDOM.voidMap); - -function fastbootVisit(App, url) { - let doc = new SimpleDOM.Document(); - let rootElement = doc.body; - let options = { isBrowser: false, document: doc, rootElement: rootElement }; - - return App.visit(url, options).then(function (instance) { - try { - return { - url: instance.getURL(), - title: doc.title, - body: HTMLSerializer.serialize(rootElement), - }; - } finally { - instance.destroy(); - } - }); -} - -function assertFastbootResult(assert, expected) { - return function (actual) { - assert.equal(actual.url, expected.url); - assertHTMLMatches(assert, actual.body, expected.body); - }; -} - -QUnit.module('Ember.Application - visit() Integration Tests', function (hooks) { - setupAppTest(hooks); - - QUnit.test('FastBoot: basic', function (assert) { - this.routes(function () { - this.route('a'); - this.route('b'); - }); - - this.template('application', '

Hello world

\n{{outlet}}'); - this.template('a', '

Welcome to {{x-foo page="A"}}

'); - this.template('b', '

{{x-foo page="B"}}

'); - - let initCalled = false; - let didInsertElementCalled = false; - - this.component( - 'x-foo', - { - tagName: 'span', - init: function () { - this._super(); - initCalled = true; - }, - didInsertElement: function () { - didInsertElementCalled = true; - }, - }, - 'Page {{this.page}}' - ); - - let App = this.createApplication(); - - return Promise.all([ - fastbootVisit(App, '/a').then( - assertFastbootResult(assert, { - url: '/a', - body: '

Hello world

\n

Welcome to Page A

', - }), - handleError(assert) - ), - fastbootVisit(App, '/b').then( - assertFastbootResult(assert, { - url: '/b', - body: '

Hello world

\n

Page B

', - }), - handleError - ), - ]).then(function () { - assert.ok(initCalled, 'Component#init should be called'); - assert.notOk(didInsertElementCalled, 'Component#didInsertElement should not be called'); - }); - }); - - QUnit.test('FastBoot: redirect', function (assert) { - this.routes(function () { - this.route('a'); - this.route('b'); - this.route('c'); - }); - - this.template('a', '

Hello from A

'); - this.template('b', '

Hello from B

'); - this.template('c', '

Hello from C

'); - - this.route('a', { - beforeModel: function () { - this.router.replaceWith('b'); - }, - }); - - this.route('b', { - afterModel: function () { - this.router.transitionTo('c'); - }, - }); - - let App = this.createApplication(); - - return Promise.all([ - fastbootVisit(App, '/a').then( - assertFastbootResult(assert, { - url: '/c', - body: '

Hello from C

', - }), - handleError(assert) - ), - fastbootVisit(App, '/b').then( - assertFastbootResult(assert, { - url: '/c', - body: '

Hello from C

', - }), - handleError(assert) - ), - ]); - }); - - QUnit.test('FastBoot: attributes are sanitized', function (assert) { - this.template('application', '
'); - - this.controller('application', { - test: 'javascript:alert("hello")', - }); - - let App = this.createApplication(); - - return Promise.all([ - fastbootVisit(App, '/').then( - assertFastbootResult(assert, { - url: '/', - body: '', - }), - handleError(assert) - ), - ]); - }); - - QUnit.test('FastBoot: route error', function (assert) { - this.routes(function () { - this.route('a'); - this.route('b'); - }); - - this.template('a', '

Hello from A

'); - this.template('b', '

Hello from B

'); - - this.route('a', { - beforeModel: function () { - throw new Error('Error from A'); - }, - }); - - this.route('b', { - afterModel: function () { - throw new Error('Error from B'); - }, - }); - - let App = this.createApplication(); - - return Promise.all([ - fastbootVisit(App, '/a').then( - function (instance) { - assert.ok(false, 'It should not render'); - instance.destroy(); - }, - function (error) { - assert.equal(error.message, 'Error from A'); - } - ), - fastbootVisit(App, '/b').then( - function (instance) { - assert.ok(false, 'It should not render'); - instance.destroy(); - }, - function (error) { - assert.equal(error.message, 'Error from B'); - } - ), - ]); - }); - - QUnit.test('FastBoot: route error template', function (assert) { - this.routes(function () { - this.route('a'); - }); - - this.template('error', '

Error template rendered!

'); - this.template('a', '

Hello from A

'); - - this.route('a', { - model: function () { - throw new Error('Error from A'); - }, - }); - - let App = this.createApplication(); - - return Promise.all([ - fastbootVisit(App, '/a').then( - assertFastbootResult(assert, { - url: '/a', - body: '

Error template rendered!

', - }), - handleError(assert) - ), - ]); - }); - - QUnit.test('Resource-discovery setup', function (assert) { - class Network { - constructor() { - this.requests = []; - } - - fetch(url) { - this.requests.push(url); - return Promise.resolve(); - } - } - - this.routes(function () { - this.route('a'); - this.route('b'); - this.route('c'); - this.route('d'); - this.route('e'); - }); - - let network; - this.route('a', { - model: function () { - return network.fetch('/a'); - }, - afterModel: function () { - this.router.replaceWith('b'); - }, - }); - - this.route('b', { - model: function () { - return network.fetch('/b'); - }, - afterModel: function () { - this.router.replaceWith('c'); - }, - }); - - this.route('c', { - model: function () { - return network.fetch('/c'); - }, - }); - - this.route('d', { - model: function () { - return network.fetch('/d'); - }, - afterModel: function () { - this.router.replaceWith('e'); - }, - }); - - this.route('e', { - model: function () { - return network.fetch('/e'); - }, - }); - - this.template('a', '{{x-foo}}'); - this.template('b', '{{x-foo}}'); - this.template('c', '{{x-foo}}'); - this.template('d', '{{x-foo}}'); - this.template('e', '{{x-foo}}'); - - let xFooInstances = 0; - - this.component('x-foo', { - init: function () { - this._super(); - xFooInstances++; - }, - }); - - let App = this.createApplication(); - - function assertResources(url, resources) { - network = new Network(); - - return App.visit(url, { isBrowser: false, shouldRender: false }).then(function (instance) { - try { - let viewRegistry = instance.lookup('-view-registry:main'); - assert.strictEqual(Object.keys(viewRegistry).length, 0, 'did not create any views'); - - assert.deepEqual(network.requests, resources); - } finally { - instance.destroy(); - } - }, handleError(assert)); - } - - return assertResources('/a', ['/a', '/b', '/c']) - .then(() => { - return assertResources('/b', ['/b', '/c']); - }) - .then(() => { - return assertResources('/c', ['/c']); - }) - .then(() => { - return assertResources('/d', ['/d', '/e']); - }) - .then(() => { - return assertResources('/e', ['/e']); - }) - .then(() => { - assert.strictEqual(xFooInstances, 0, 'it should not create any x-foo components'); - }); - }); - - QUnit.test('FastBoot: tagless components can render', function (assert) { - this.template('application', "
{{my-component}}
"); - this.component('my-component', { tagName: '' }, '

hello world

'); - - let App = this.createApplication(); - - return Promise.all([ - fastbootVisit(App, '/').then( - assertFastbootResult(assert, { - url: '/', - body: /

hello world<\/h1><\/div>/, - }), - handleError(assert) - ), - ]); - }); -}); From 0a4b9f298ca8f388985cd8744d802b6644940388 Mon Sep 17 00:00:00 2001 From: NullVoxPopuli <199018+NullVoxPopuli@users.noreply.github.com> Date: Fri, 27 Feb 2026 20:44:56 -0500 Subject: [PATCH 4/4] Delete the loader --- smoke-tests/node-template/package.json | 4 ++-- .../tests/node/helpers/macros-shim.js | 11 ---------- .../tests/node/helpers/register-loader.js | 22 ------------------- 3 files changed, 2 insertions(+), 35 deletions(-) delete mode 100644 smoke-tests/node-template/tests/node/helpers/macros-shim.js delete mode 100644 smoke-tests/node-template/tests/node/helpers/register-loader.js diff --git a/smoke-tests/node-template/package.json b/smoke-tests/node-template/package.json index 1432194ae6a..88144d26bb0 100644 --- a/smoke-tests/node-template/package.json +++ b/smoke-tests/node-template/package.json @@ -5,7 +5,7 @@ "type": "module", "description": "Node-focused smoke test template for ember-source", "scripts": { - "test:node": "node --import ./tests/node/helpers/register-loader.js --test tests/node/*.test.js" + "test:node": "node --test tests/node/*.test.js" }, "dependencies": { "simple-dom": "^1.4.0", @@ -14,4 +14,4 @@ "engines": { "node": ">= 20.6.0" } -} \ No newline at end of file +} diff --git a/smoke-tests/node-template/tests/node/helpers/macros-shim.js b/smoke-tests/node-template/tests/node/helpers/macros-shim.js deleted file mode 100644 index 47eff275a06..00000000000 --- a/smoke-tests/node-template/tests/node/helpers/macros-shim.js +++ /dev/null @@ -1,11 +0,0 @@ -/** - * @embroider/macros shim for Node.js ESM loading. - * - * The Ember ESM packages in dist/packages/ contain unresolved imports from - * '@embroider/macros' (specifically isDevelopingApp). In a real app build, - * these are resolved at compile time by a Babel plugin. For Node.js testing - * we provide a runtime shim. - */ -export function isDevelopingApp() { - return true; -} diff --git a/smoke-tests/node-template/tests/node/helpers/register-loader.js b/smoke-tests/node-template/tests/node/helpers/register-loader.js deleted file mode 100644 index 276021062ee..00000000000 --- a/smoke-tests/node-template/tests/node/helpers/register-loader.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Node.js module loader hook that intercepts '@embroider/macros' imports - * and redirects them to our local shim. - * - * Usage: node --import ./tests/node/helpers/register-loader.js --test ... - */ -import { register } from 'node:module'; -import { fileURLToPath, pathToFileURL } from 'node:url'; -import { dirname, resolve } from 'node:path'; - -const __dirname = dirname(fileURLToPath(import.meta.url)); -const shimPath = resolve(__dirname, 'macros-shim.js'); -const shimURL = pathToFileURL(shimPath).href; - -register('data:text/javascript,' + encodeURIComponent(` -export async function resolve(specifier, context, nextResolve) { - if (specifier === '@embroider/macros') { - return { url: ${JSON.stringify(shimURL)}, shortCircuit: true }; - } - return nextResolve(specifier, context); -} -`), pathToFileURL(import.meta.url));