@gjsify/cli 0.3.12 → 0.3.14

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/src/config.ts CHANGED
@@ -92,7 +92,7 @@ export class Config {
92
92
  merge(merged, fileResult.config);
93
93
  }
94
94
 
95
- merged.esbuild ||= {};
95
+ merged.bundler ||= {};
96
96
  merged.library ||= {};
97
97
  merged.typescript ||= {};
98
98
 
@@ -168,16 +168,52 @@ export class Config {
168
168
  configData.aliases = { ...(configData.aliases ?? {}), ...aliasMap };
169
169
  }
170
170
 
171
- merge(configData.esbuild ??= {}, {
172
- format: cliArgs.format,
173
- minify: cliArgs.minify,
174
- entryPoints: cliArgs.entryPoints,
175
- outfile: cliArgs.outfile,
176
- outdir: cliArgs.outdir,
177
- logLevel: cliArgs.logLevel || 'warning',
178
- ...(cliArgs.external?.length ? { external: cliArgs.external } : {}),
179
- ...(Object.keys(defineMap).length ? { define: defineMap } : {}),
180
- });
171
+ // Merge CLI flags into the Rolldown-shape `bundler` field. Mappings:
172
+ // --entry-points → bundler.input
173
+ // --outfile → bundler.output.file
174
+ // --outdir → bundler.output.dir
175
+ // --format → bundler.output.format
176
+ // --minify → bundler.output.minify
177
+ // --log-level → bundler.logLevel
178
+ // --external bundler.external
179
+ // --define → bundler.transform.define
180
+ const bundler = (configData.bundler ??= {});
181
+ const output = (bundler.output ??= {});
182
+ const transform = (bundler.transform ??= {});
183
+
184
+ if (cliArgs.entryPoints?.length) bundler.input = cliArgs.entryPoints;
185
+ if (cliArgs.outfile !== undefined) output.file = cliArgs.outfile;
186
+ if (cliArgs.outdir !== undefined) output.dir = cliArgs.outdir;
187
+ if (cliArgs.format !== undefined) output.format = cliArgs.format as 'esm' | 'cjs' | 'iife';
188
+ if (cliArgs.minify !== undefined) output.minify = cliArgs.minify;
189
+ if (cliArgs.logLevel) {
190
+ // Map esbuild log levels to Rolldown's narrower set:
191
+ // esbuild → rolldown
192
+ // silent → silent
193
+ // error → warn (rolldown has no error-only)
194
+ // warning → warn
195
+ // info → info
196
+ // debug → debug
197
+ // verbose → debug (rolldown has no verbose)
198
+ const map: Record<string, 'silent' | 'warn' | 'info' | 'debug'> = {
199
+ silent: 'silent',
200
+ error: 'warn',
201
+ warning: 'warn',
202
+ warn: 'warn',
203
+ info: 'info',
204
+ debug: 'debug',
205
+ verbose: 'debug',
206
+ };
207
+ const level = map[cliArgs.logLevel] ?? 'warn';
208
+ bundler.logLevel = level;
209
+ }
210
+ if (cliArgs.external?.length) {
211
+ const userExternal = Array.isArray(bundler.external) ? bundler.external : [];
212
+ bundler.external = [...userExternal, ...cliArgs.external];
213
+ }
214
+ if (Object.keys(defineMap).length) {
215
+ transform.define = { ...(transform.define ?? {}), ...defineMap };
216
+ }
181
217
 
182
218
  if(configData.verbose) console.debug("configData", configData);
183
219
 
@@ -1,4 +1,4 @@
1
- import type { App } from '@gjsify/esbuild-plugin-gjsify';
1
+ import type { App } from '@gjsify/rolldown-plugin-gjsify';
2
2
 
3
3
  export interface CliBuildOptions {
4
4
  /**
@@ -1,10 +1,59 @@
1
- import type { BuildOptions as EsbuildOptions} from 'esbuild';
1
+ import type { RolldownOptions, OutputOptions } from 'rolldown';
2
2
  import type { ConfigDataLibrary, ConfigDataTypescript } from './index.js';
3
3
 
4
+ /**
5
+ * Subset of `RolldownOptions` accepted in `.gjsifyrc.js`. Mirrors the legacy
6
+ * `esbuild?: BuildOptions` field — a thin pass-through. The orchestrator
7
+ * applies platform defaults on top of these, so most projects only need
8
+ * `output.file` / `output.dir` here.
9
+ *
10
+ * `output` is constrained to a single `OutputOptions` object (Rolldown also
11
+ * accepts an array for multi-output builds, but the CLI surface targets the
12
+ * single-output use case).
13
+ */
14
+ export type BundlerOptions = Omit<RolldownOptions, 'output'> & {
15
+ output?: OutputOptions;
16
+ };
17
+
18
+ /**
19
+ * Legacy `esbuild?: BuildOptions` shape — kept as a compatibility shim for
20
+ * one minor release. Setting it logs a deprecation warning; the supported
21
+ * subset of fields is mapped into `bundler` at config-load time.
22
+ *
23
+ * Drop in 0.5.0.
24
+ */
25
+ export interface LegacyEsbuildOptions {
26
+ outfile?: string;
27
+ outdir?: string;
28
+ format?: 'esm' | 'cjs' | 'iife';
29
+ external?: string[];
30
+ define?: Record<string, string>;
31
+ inject?: string[];
32
+ banner?: { js?: string };
33
+ target?: string | string[];
34
+ minify?: boolean;
35
+ sourcemap?: boolean | 'inline' | 'external' | 'both';
36
+ mainFields?: string[];
37
+ conditions?: string[];
38
+ platform?: 'browser' | 'node' | 'neutral';
39
+ loader?: Record<string, string>;
40
+ }
41
+
4
42
  export interface ConfigData {
5
43
  /** Switch on the verbose mode */
6
44
  verbose?: boolean;
7
- esbuild?: EsbuildOptions;
45
+ /**
46
+ * Bundler-level options forwarded to Rolldown. Replaces the legacy
47
+ * `esbuild` field. The orchestrator applies platform-specific defaults
48
+ * on top — most projects only need to set `output.file` / `output.dir`.
49
+ */
50
+ bundler?: BundlerOptions;
51
+ /**
52
+ * @deprecated Use `bundler` instead. Will be removed in 0.5.0. The shim
53
+ * maps the supported subset of esbuild fields into the equivalent
54
+ * Rolldown shape and logs a deprecation warning.
55
+ */
56
+ esbuild?: LegacyEsbuildOptions;
8
57
  library?: ConfigDataLibrary;
9
58
  typescript?: ConfigDataTypescript;
10
59
  /** An array of glob patterns to exclude matches and aliases */
@@ -0,0 +1,129 @@
1
+ // One-release deprecation shim: maps the legacy `esbuild?: BuildOptions`
2
+ // field on `.gjsifyrc.js` / `package.json#gjsify` into the equivalent
3
+ // `bundler?: RolldownOptions` shape. Logs a single warning per build.
4
+ //
5
+ // Drop in 0.5.0.
6
+
7
+ import type { OutputOptions } from 'rolldown';
8
+ import type { ConfigData, BundlerOptions, LegacyEsbuildOptions } from '../types/config-data.js';
9
+
10
+ let warnedOnce = false;
11
+
12
+ export function normalizeBundlerOptions(configData: ConfigData): BundlerOptions {
13
+ const fromBundler: BundlerOptions = (configData.bundler ?? {}) as BundlerOptions;
14
+ if (!configData.esbuild) return fromBundler;
15
+
16
+ if (!warnedOnce) {
17
+ warnedOnce = true;
18
+ // eslint-disable-next-line no-console
19
+ console.warn(
20
+ "[gjsify] DEPRECATION: the 'esbuild' config key is deprecated and will be removed in 0.5.0. " +
21
+ "Rename it to 'bundler' (typed as RolldownOptions). See the migration notes in the gjsify CHANGELOG.",
22
+ );
23
+ }
24
+
25
+ const fromEsbuild = legacyEsbuildToRolldown(configData.esbuild);
26
+ // Plain user-config merge — we deliberately do NOT call
27
+ // `mergeBundlerOptions` here, because that function strips `input` and
28
+ // `external` from its overrides arg (it assumes the *orchestrator* is
29
+ // the override source and the user the base). Here both inputs are
30
+ // user-provided config and `input` must survive the merge.
31
+ const out: BundlerOptions = { ...fromEsbuild, ...fromBundler };
32
+ if (fromEsbuild.output || fromBundler.output) {
33
+ out.output = { ...(fromEsbuild.output ?? {}), ...(fromBundler.output ?? {}) };
34
+ }
35
+ if (fromEsbuild.transform || fromBundler.transform) {
36
+ out.transform = { ...(fromEsbuild.transform ?? {}), ...(fromBundler.transform ?? {}) };
37
+ if (fromEsbuild.transform?.define || fromBundler.transform?.define) {
38
+ out.transform.define = {
39
+ ...(fromEsbuild.transform?.define ?? {}),
40
+ ...(fromBundler.transform?.define ?? {}),
41
+ };
42
+ }
43
+ }
44
+ if (fromEsbuild.resolve || fromBundler.resolve) {
45
+ out.resolve = { ...(fromEsbuild.resolve ?? {}), ...(fromBundler.resolve ?? {}) };
46
+ }
47
+ return out;
48
+ }
49
+
50
+ /** Map the supported subset of esbuild BuildOptions into RolldownOptions. */
51
+ function legacyEsbuildToRolldown(esb: LegacyEsbuildOptions): BundlerOptions {
52
+ const out: BundlerOptions = {};
53
+ const output: OutputOptions = {};
54
+ const transform: NonNullable<BundlerOptions['transform']> = {};
55
+ const resolve: NonNullable<BundlerOptions['resolve']> = {};
56
+
57
+ if (esb.outfile !== undefined) output.file = esb.outfile;
58
+ if (esb.outdir !== undefined) output.dir = esb.outdir;
59
+ if (esb.format !== undefined) output.format = esb.format;
60
+ if (esb.minify !== undefined) output.minify = esb.minify;
61
+ if (esb.sourcemap !== undefined) {
62
+ // esbuild has 'external' / 'both' which Rolldown doesn't — coerce to boolean.
63
+ output.sourcemap =
64
+ esb.sourcemap === 'inline'
65
+ ? 'inline'
66
+ : Boolean(esb.sourcemap);
67
+ }
68
+ if (esb.banner?.js !== undefined) output.banner = esb.banner.js;
69
+
70
+ if (esb.target !== undefined) {
71
+ transform.target = Array.isArray(esb.target) ? esb.target.join(',') : esb.target;
72
+ }
73
+ if (esb.define !== undefined) transform.define = esb.define;
74
+
75
+ if (esb.mainFields !== undefined) resolve.mainFields = esb.mainFields;
76
+ if (esb.conditions !== undefined) resolve.conditionNames = esb.conditions;
77
+
78
+ if (esb.external !== undefined) out.external = esb.external;
79
+ if (esb.platform !== undefined) out.platform = esb.platform;
80
+
81
+ if (Object.keys(output).length > 0) out.output = output;
82
+ if (Object.keys(transform).length > 0) out.transform = transform;
83
+ if (Object.keys(resolve).length > 0) out.resolve = resolve;
84
+
85
+ // Discarded silently:
86
+ // esb.inject — esbuild's array-of-side-effect-files; surfaced at the
87
+ // CLI layer instead, via input expansion.
88
+ // esb.loader — Rolldown infers module types from extensions natively.
89
+ return out;
90
+ }
91
+
92
+ /**
93
+ * Shallow merge with deep-merge of `output`, `transform`, and `resolve`. The
94
+ * second argument wins on conflicts, matching `merge(target, ...sources)`
95
+ * semantics from `@gjsify/rolldown-plugin-gjsify/utils/merge`.
96
+ *
97
+ * `base` is typically the Rolldown-generic shape returned by the orchestrator;
98
+ * `overrides` is the user's `BundlerOptions` from `.gjsifyrc.js` plus CLI
99
+ * flag merges. Single-output assumption matches `BundlerOptions['output']`.
100
+ *
101
+ * The orchestrator-side `input` is authoritative — it's the post-glob-expansion
102
+ * value. Overriding it with the user's raw glob string would re-introduce
103
+ * unresolved glob patterns into the final Rolldown call. Same for `external`,
104
+ * which the orchestrator concatenates with platform defaults already.
105
+ */
106
+ export function mergeBundlerOptions(
107
+ base: BundlerOptions,
108
+ overrides: BundlerOptions,
109
+ ): BundlerOptions {
110
+ // Strip fields the orchestrator owns authoritatively — the user has
111
+ // already had their say via the orchestrator's `userExternal` / input
112
+ // expansion; merging the raw values back on top would clobber the
113
+ // post-processing.
114
+ const { input: _ignoredInput, external: _ignoredExternal, ...overridesRest } = overrides;
115
+ const out: BundlerOptions = { ...base, ...overridesRest };
116
+ if (base.output || overrides.output) {
117
+ out.output = { ...(base.output ?? {}), ...(overrides.output ?? {}) };
118
+ }
119
+ if (base.transform || overrides.transform) {
120
+ out.transform = { ...(base.transform ?? {}), ...(overrides.transform ?? {}) };
121
+ if (base.transform?.define || overrides.transform?.define) {
122
+ out.transform.define = { ...(base.transform?.define ?? {}), ...(overrides.transform?.define ?? {}) };
123
+ }
124
+ }
125
+ if (base.resolve || overrides.resolve) {
126
+ out.resolve = { ...(base.resolve ?? {}), ...(overrides.resolve ?? {}) };
127
+ }
128
+ return out;
129
+ }