@ionic-hotfix/cordova-builders 13.0.1-testing.2 → 13.0.2-testing.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -3,7 +3,7 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- ## 13.0.1-testing.2 (2026-02-26)
6
+ ## 13.0.2-testing.2 (2026-02-27)
7
7
 
8
8
 
9
9
  ### Bug Fixes
@@ -44,7 +44,7 @@ update their angular.json to reflect the new package name
44
44
 
45
45
 
46
46
 
47
- ## 13.0.1-testing.1 (2026-02-26)
47
+ ## 13.0.2-testing.1 (2026-02-27)
48
48
 
49
49
 
50
50
  ### Bug Fixes
@@ -85,7 +85,7 @@ update their angular.json to reflect the new package name
85
85
 
86
86
 
87
87
 
88
- ## 13.0.1-testing.0 (2026-02-26)
88
+ ## 13.0.2-testing.0 (2026-02-27)
89
89
 
90
90
 
91
91
  ### Bug Fixes
@@ -4,97 +4,97 @@ exports.indexHtmlTransformFactory = void 0;
4
4
  exports.serveCordova = serveCordova;
5
5
  const architect_1 = require("@angular-devkit/architect");
6
6
  const build_angular_1 = require("@angular-devkit/build-angular");
7
- const promises_1 = require("fs/promises");
8
- const fs_1 = require("fs");
9
- const glob_1 = require("glob");
10
- const path_1 = require("path");
11
7
  const rxjs_1 = require("rxjs");
12
8
  const operators_1 = require("rxjs/operators");
13
9
  const utils_1 = require("../utils");
14
10
  const append_scripts_1 = require("../utils/append-scripts");
15
11
  const log_server_1 = require("./log-server");
12
+ /**
13
+ * Builders that are esbuild-based but not known to @angular-devkit/build-angular's
14
+ * isEsbuildBased() check. We remap them via builderSelector so the dev-server
15
+ * routes to the Vite path instead of falling through to webpack-server.js.
16
+ */
17
+ const CUSTOM_ESBUILD_REMAP = {
18
+ '@angular-builders/custom-esbuild:application': '@angular-devkit/build-angular:application',
19
+ '@angular-builders/custom-esbuild:browser': '@angular-devkit/build-angular:browser-esbuild',
20
+ };
21
+ /** Builders that use esbuild — scripts/assets are NOT passed via getTargetOptions for these. */
22
+ const ESBUILD_BUILDERS = new Set([
23
+ '@angular/build:application',
24
+ '@angular-devkit/build-angular:application',
25
+ '@angular-devkit/build-angular:browser-esbuild',
26
+ ...Object.keys(CUSTOM_ESBUILD_REMAP),
27
+ ]);
16
28
  function serveCordova(options, context) {
17
29
  const { devServerTarget, port, host, ssl } = options;
18
30
  const root = context.workspaceRoot;
19
31
  const devServerTargetSpec = (0, architect_1.targetFromTargetString)(devServerTarget);
20
32
  async function setup() {
33
+ var _a, _b, _c;
21
34
  const devServerTargetOptions = await context.getTargetOptions(devServerTargetSpec);
22
35
  const devServerName = await context.getBuilderNameForTarget(devServerTargetSpec);
23
36
  devServerTargetOptions.port = port;
24
37
  devServerTargetOptions.host = host;
25
38
  devServerTargetOptions.ssl = ssl;
26
- const formattedOptions = await context.validateOptions(devServerTargetOptions, devServerName);
27
- const formattedAssets = (0, utils_1.prepareServerConfig)(options, root);
39
+ const devServerOptions = (await context.validateOptions(devServerTargetOptions, devServerName));
40
+ const formattedAssets = await (0, utils_1.prepareServerConfig)(options, root);
28
41
  if (options.consolelogs && options.consolelogsPort) {
29
42
  await (0, log_server_1.createConsoleLogServer)(host, options.consolelogsPort);
30
43
  }
31
- return { formattedOptions, formattedAssets };
44
+ // Webpack-only: patch getTargetOptions so the dev-server picks up the extra
45
+ // Cordova scripts/assets when it reads the build target. Skip for esbuild
46
+ // builders — their outputPath is an object and would crash common.js:290.
47
+ const buildTargetString = (_a = devServerOptions.buildTarget) !== null && _a !== void 0 ? _a : devServerOptions.browserTarget;
48
+ if (buildTargetString && formattedAssets.extraScripts.length + formattedAssets.extraAssets.length > 0) {
49
+ const buildTargetSpec = (0, architect_1.targetFromTargetString)(buildTargetString);
50
+ const buildBuilderName = await context.getBuilderNameForTarget(buildTargetSpec);
51
+ if (!ESBUILD_BUILDERS.has(buildBuilderName)) {
52
+ const buildTargetOptions = await context.getTargetOptions(buildTargetSpec);
53
+ const existingScripts = (_b = buildTargetOptions.scripts) !== null && _b !== void 0 ? _b : [];
54
+ const existingAssets = (_c = buildTargetOptions.assets) !== null && _c !== void 0 ? _c : [];
55
+ const originalGet = context.getTargetOptions.bind(context);
56
+ context.getTargetOptions = async (target) => {
57
+ var _a, _b;
58
+ const raw = await originalGet(target);
59
+ const isMatchingBuild = target.project === buildTargetSpec.project &&
60
+ target.target === buildTargetSpec.target &&
61
+ ((_a = target.configuration) !== null && _a !== void 0 ? _a : '') === ((_b = buildTargetSpec.configuration) !== null && _b !== void 0 ? _b : '');
62
+ if (isMatchingBuild) {
63
+ return {
64
+ ...raw,
65
+ scripts: [...existingScripts, ...formattedAssets.extraScripts],
66
+ assets: [...existingAssets, ...formattedAssets.extraAssets],
67
+ };
68
+ }
69
+ return raw;
70
+ };
71
+ }
72
+ }
73
+ return { devServerOptions, formattedAssets };
32
74
  }
33
- return (0, rxjs_1.from)(setup()).pipe((0, operators_1.switchMap)(({ formattedOptions, formattedAssets }) => (0, build_angular_1.executeDevServerBuilder)(formattedOptions, context, getTransforms(formattedAssets, context))));
75
+ return (0, rxjs_1.from)(setup()).pipe((0, operators_1.switchMap)(({ devServerOptions, formattedAssets }) => (0, build_angular_1.executeDevServerBuilder)(devServerOptions, context, { indexHtml: (0, exports.indexHtmlTransformFactory)(formattedAssets) }, {
76
+ // Remap @angular-builders/custom-esbuild:* to the angular-devkit equivalents
77
+ // so executeDevServerBuilder's isEsbuildBased() check passes and routes to
78
+ // the Vite dev server instead of falling through to webpack-server.js.
79
+ builderSelector: (info, logger) => {
80
+ const remapped = CUSTOM_ESBUILD_REMAP[info.builderName];
81
+ if (remapped) {
82
+ return remapped;
83
+ }
84
+ // Fall back to the default selector behaviour
85
+ if (info.builderName === '@angular/build:application' ||
86
+ info.builderName === '@angular-devkit/build-angular:application' ||
87
+ info.builderName === '@angular-devkit/build-angular:browser-esbuild') {
88
+ return info.builderName;
89
+ }
90
+ if (info.forceEsbuild) {
91
+ return '@angular-devkit/build-angular:browser-esbuild';
92
+ }
93
+ return info.builderName;
94
+ },
95
+ })));
34
96
  }
35
97
  exports.default = (0, architect_1.createBuilder)(serveCordova);
36
- // ---------------------------------------------------------------------------
37
- // esbuild transforms (replaces former webpack-based transforms)
38
- // ---------------------------------------------------------------------------
39
- function getTransforms(formattedAssets, context) {
40
- return {
41
- /** esbuild plugin that injects Cordova global scripts as entry-point side-effects. */
42
- buildPlugins: [cordovaScriptsEsbuildPlugin(formattedAssets, context)],
43
- indexHtml: (0, exports.indexHtmlTransformFactory)(formattedAssets, context),
44
- };
45
- }
46
- /**
47
- * esbuild plugin that:
48
- * 1. Copies Cordova platform assets (cordova.js, plugins, etc.) to the output dir.
49
- * 2. Concatenates global script bundles and writes them as standalone JS files
50
- * so they can be referenced via <script> tags injected by indexHtmlTransformFactory.
51
- */
52
- const cordovaScriptsEsbuildPlugin = (formattedAssets, { workspaceRoot, getProjectMetadata, target }) => ({
53
- name: 'cordova-assets',
54
- setup(build) {
55
- var _a;
56
- const outdir = (_a = build.initialOptions.outdir) !== null && _a !== void 0 ? _a : (0, path_1.resolve)(workspaceRoot, 'www');
57
- build.onEnd(async () => {
58
- // 1. Copy asset patterns (replaces CopyWebpackPlugin)
59
- await Promise.all(formattedAssets.assetPatterns.map((pattern) => copyAssets(pattern, outdir)));
60
- // 2. Concatenate global scripts into named bundles (replaces ScriptsWebpackPlugin)
61
- await Promise.all(formattedAssets.globalScriptsByBundleName.map(({ bundleName, paths }) => concatScripts(paths, (0, path_1.join)(outdir, `${bundleName}.js`))));
62
- });
63
- },
64
- });
65
- /** Recursively copies files matching `pattern.glob` from `pattern.from` to `outdir/pattern.to`. */
66
- async function copyAssets(pattern, outdir) {
67
- const files = await (0, glob_1.glob)(pattern.glob, {
68
- cwd: pattern.from,
69
- dot: true,
70
- nodir: true,
71
- ignore: pattern.ignore,
72
- });
73
- await Promise.all(files.map(async (file) => {
74
- const src = (0, path_1.join)(pattern.from, file);
75
- const dest = (0, path_1.join)(outdir, pattern.to, file);
76
- await (0, promises_1.mkdir)((0, path_1.join)(outdir, pattern.to, file, '..'), { recursive: true });
77
- await (0, promises_1.copyFile)(src, dest);
78
- }));
79
- }
80
- /** Concatenates multiple JS files into a single output file. */
81
- async function concatScripts(paths, destPath) {
82
- await (0, promises_1.mkdir)((0, path_1.join)(destPath, '..'), { recursive: true });
83
- const out = (0, fs_1.createWriteStream)(destPath, { flags: 'w' });
84
- for (const src of paths) {
85
- await new Promise((res, rej) => {
86
- const rs = (0, fs_1.createReadStream)(src);
87
- rs.on('error', rej);
88
- rs.on('end', res);
89
- rs.pipe(out, { end: false });
90
- });
91
- out.write('\n');
92
- }
93
- await new Promise((res, rej) => out.end(res));
94
- }
95
- // ---------------------------------------------------------------------------
96
- // Index HTML transform (unchanged in behaviour, no webpack dependency)
97
- // ---------------------------------------------------------------------------
98
98
  const indexHtmlTransformFactory = ({ globalScriptsByBundleName }) => (indexTransform) => {
99
99
  const augmentedHtml = (0, append_scripts_1.augmentIndexHtml)(indexTransform, globalScriptsByBundleName);
100
100
  return Promise.resolve(augmentedHtml);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionic-hotfix/cordova-builders",
3
- "version": "13.0.1-testing.2",
3
+ "version": "13.0.2-testing.2",
4
4
  "license": "MIT",
5
5
  "description": "Cordova builders for @ionic/angular apps",
6
6
  "homepage": "https://ionicframework.com/",
@@ -42,7 +42,7 @@
42
42
  "@schematics/angular": "^20.0.0",
43
43
  "cheerio": "^1.0.0-rc.10",
44
44
  "colorette": "^2.0.16",
45
- "glob": "^11.0.0",
45
+ "copy-webpack-plugin": "^12.0.2",
46
46
  "ws": "^8.2.3"
47
47
  },
48
48
  "devDependencies": {
@@ -55,5 +55,5 @@
55
55
  },
56
56
  "builders": "./builders.json",
57
57
  "schematics": "./collection.json",
58
- "gitHead": "8da8939534e632afe029eebfeb9970b46e7df9aa"
58
+ "gitHead": "62a6a7dc897756c2a32b86a0b07a849fff9db140"
59
59
  }
package/utils/index.js CHANGED
@@ -23,34 +23,41 @@ function prepareBrowserConfig(options, browserOptions) {
23
23
  if (typeof options.sourceMap !== 'undefined') {
24
24
  optionsStarter.sourceMap = options.sourceMap;
25
25
  }
26
+ // We always need to output the build to `www` because it is a hard
27
+ // requirement of Cordova.
26
28
  if ('outputPath' in options) {
27
29
  optionsStarter.outputPath = (0, core_1.join)(cordovaBasePath, (0, core_1.normalize)('www'));
28
30
  }
31
+ // Cordova CLI will error if `www` is missing. The Angular CLI deletes it
32
+ // by default. Let's keep it around.
29
33
  if ('deleteOutputPath' in options) {
30
34
  optionsStarter.deleteOutputPath = false;
31
35
  }
36
+ // Initialize an empty script array to make sure assets are pushed even when
37
+ // scripts is not configured in angular.json
32
38
  if (!optionsStarter.scripts) {
33
39
  optionsStarter.scripts = [];
34
40
  }
35
41
  if (options.consolelogs) {
42
+ // Write the config to a file, and then include that in the bundle so it loads on window
36
43
  const configPath = (0, core_1.getSystemPath)((0, core_1.join)((0, core_1.normalize)(__dirname), '../assets', (0, core_1.normalize)('consolelog-config.js')));
37
44
  (0, fs_1.writeFileSync)(configPath, `window.Ionic = window.Ionic || {}; Ionic.ConsoleLogServerConfig = { wsPort: ${options.consolelogsPort} }`);
38
- optionsStarter.scripts.push({ input: configPath, bundleName: 'consolelogs' });
39
- optionsStarter.scripts.push({
40
- input: (0, core_1.getSystemPath)((0, core_1.join)((0, core_1.normalize)(__dirname), '../assets', (0, core_1.normalize)('consolelogs.js'))),
41
- bundleName: 'consolelogs',
42
- });
45
+ // Pass absolute paths as strings — some versions of the Webpack builder call
46
+ // path.resolve(root, entry) treating the entry as a plain string, so object
47
+ // form { input, bundleName } causes ERR_INVALID_ARG_TYPE at common.js.
48
+ optionsStarter.scripts.push(configPath);
49
+ optionsStarter.scripts.push((0, core_1.getSystemPath)((0, core_1.join)((0, core_1.normalize)(__dirname), '../assets', (0, core_1.normalize)('consolelogs.js'))));
43
50
  }
44
51
  if (options.cordovaMock) {
45
52
  if (browserOptions.scripts) {
46
- browserOptions.scripts.push({
47
- input: (0, core_1.getSystemPath)((0, core_1.join)((0, core_1.normalize)(__dirname), '../assets', (0, core_1.normalize)('cordova.js'))),
48
- bundleName: 'cordova',
49
- });
53
+ browserOptions.scripts.push((0, core_1.getSystemPath)((0, core_1.join)((0, core_1.normalize)(__dirname), '../assets', (0, core_1.normalize)('cordova.js'))));
50
54
  }
51
55
  }
52
56
  else if (options.cordovaAssets) {
53
57
  const platformWWWPath = (0, core_1.join)(cordovaBasePath, (0, core_1.normalize)(`platforms/${options.platform}/platform_www`));
58
+ // Add Cordova www assets that were generated whenever platform(s) and
59
+ // plugin(s) are added. This includes `cordova.js`,
60
+ // `cordova_plugins.js`, and all plugin JS.
54
61
  if (optionsStarter.assets) {
55
62
  optionsStarter.assets.push({
56
63
  glob: '**/*',
@@ -58,29 +65,15 @@ function prepareBrowserConfig(options, browserOptions) {
58
65
  output: './',
59
66
  });
60
67
  }
68
+ // Register `cordova.js` as a global script so it is included in
69
+ // `index.html`.
61
70
  if (optionsStarter.scripts) {
62
- optionsStarter.scripts.push({
63
- input: (0, core_1.getSystemPath)((0, core_1.join)(platformWWWPath, (0, core_1.normalize)('cordova.js'))),
64
- bundleName: 'cordova',
65
- });
71
+ optionsStarter.scripts.push((0, core_1.getSystemPath)((0, core_1.join)(platformWWWPath, (0, core_1.normalize)('cordova.js'))));
66
72
  }
67
73
  }
68
74
  return optionsStarter;
69
75
  }
70
- function normalizeScripts(scripts) {
71
- return scripts.reduce((prev, curr) => {
72
- const { bundleName, input } = curr;
73
- const existing = prev.find((el) => el.bundleName === bundleName);
74
- if (existing) {
75
- existing.paths.push(input);
76
- }
77
- else {
78
- prev.push({ bundleName, inject: true, paths: [input] });
79
- }
80
- return prev;
81
- }, []);
82
- }
83
- function prepareServerConfig(options, root) {
76
+ async function prepareServerConfig(options, root) {
84
77
  const scripts = [];
85
78
  const assets = [];
86
79
  const cordovaBasePath = (0, core_1.normalize)(options.cordovaBasePath ? options.cordovaBasePath : '.');
@@ -101,32 +94,31 @@ function prepareServerConfig(options, root) {
101
94
  }
102
95
  else if (options.cordovaAssets) {
103
96
  const platformWWWPath = (0, core_1.join)(cordovaBasePath, (0, core_1.normalize)(`platforms/${options.platform}/platform_www`));
104
- assets.push({ glob: '**/*', input: (0, core_1.getSystemPath)(platformWWWPath), output: './' });
97
+ assets.push({
98
+ glob: '**/*',
99
+ input: (0, core_1.getSystemPath)(platformWWWPath),
100
+ output: './',
101
+ });
105
102
  scripts.push({
106
103
  input: (0, core_1.getSystemPath)((0, core_1.join)(platformWWWPath, (0, core_1.normalize)('cordova.js'))),
107
104
  bundleName: 'cordova',
108
105
  });
109
106
  }
110
- // Resolve script paths relative to workspace root
111
- const resolvedScripts = scripts.map(({ input, bundleName }) => ({
112
- input: (0, path_1.resolve)(root, input),
113
- bundleName,
114
- }));
115
- const globalScriptsByBundleName = normalizeScripts(resolvedScripts);
116
- // Build esbuild-compatible asset patterns (no CopyWebpackPlugin dependency)
117
- const assetPatterns = assets.map((asset) => {
118
- var _a, _b;
119
- let input = (0, path_1.resolve)(root, asset.input).replace(/\\/g, '/');
120
- input = input.endsWith('/') ? input : input + '/';
121
- let output = ((_a = asset.output) !== null && _a !== void 0 ? _a : '').replace(/\\/g, '/');
122
- output = output.endsWith('/') ? output : output + '/';
123
- const extraIgnore = ((_b = asset.ignore) !== null && _b !== void 0 ? _b : []).map((i) => path_1.posix.join(input, i));
124
- return {
125
- from: input,
126
- to: output.replace(/^\//, ''),
127
- glob: asset.glob,
128
- ignore: ['.gitkeep', '**/.DS_Store', '**/Thumbs.db', ...extraIgnore],
129
- };
130
- });
131
- return { globalScriptsByBundleName, assetPatterns };
107
+ // Group scripts by bundleName for index.html augmentation.
108
+ const globalScriptsByBundleName = scripts.reduce((prev, curr) => {
109
+ const resolvedPath = (0, path_1.resolve)(root, curr.input);
110
+ const existingEntry = prev.find((el) => el.bundleName === curr.bundleName);
111
+ if (existingEntry) {
112
+ existingEntry.paths.push(resolvedPath);
113
+ }
114
+ else {
115
+ prev.push({ bundleName: curr.bundleName, inject: true, paths: [resolvedPath] });
116
+ }
117
+ return prev;
118
+ }, []);
119
+ return {
120
+ globalScriptsByBundleName,
121
+ extraScripts: scripts.map((s) => ({ input: (0, path_1.resolve)(root, s.input), bundleName: s.bundleName })),
122
+ extraAssets: assets,
123
+ };
132
124
  }