pkgbld 1.36.0 → 2.1.0

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.
@@ -0,0 +1,44 @@
1
+ import binify from './builtin-plugins/binify.js';
2
+ import clean from './builtin-plugins/clean.js';
3
+ import commonjs from './builtin-plugins/commonjs.js';
4
+ import externals from './builtin-plugins/externals.js';
5
+ import json from './builtin-plugins/json.js';
6
+ import packageImports from './builtin-plugins/package-imports.js';
7
+ import preprocess from './builtin-plugins/preprocess.js';
8
+ import resolve from './builtin-plugins/resolve.js';
9
+ import terser from './builtin-plugins/terser.js';
10
+
11
+ /**
12
+ * @typedef {import('./types.js').PkgbldRollupPlugin} PkgbldRollupPlugin
13
+ * @typedef {import('./types.js').Provider} Provider
14
+ */
15
+
16
+ export const plugins = [clean, commonjs, externals, preprocess, packageImports, resolve, terser, binify, json];
17
+
18
+ const noop = () => undefined;
19
+
20
+ /**
21
+ * @returns {[Provider, PkgbldRollupPlugin[]]}
22
+ */
23
+ export function createProvider() {
24
+ /** @type {PkgbldRollupPlugin[]} */
25
+ const plugins = [];
26
+ return [
27
+ {
28
+ provide: (
29
+ /** @type {PkgbldRollupPlugin['plugin']} */ plugin,
30
+ /** @type {PkgbldRollupPlugin['priority']} */ priority,
31
+ /** @type {Omit<PkgbldRollupPlugin, 'plugin' | 'priority'>=} */ options
32
+ ) => {
33
+ plugins.push({ priority, plugin, format: options?.format, inputs: options?.inputs, outputPlugin: options?.outputPlugin });
34
+ },
35
+ import: async (/** @type {string} */ name, /** @type {string=} */ exportName) => {
36
+ const result = await import(name);
37
+ return result[exportName ?? 'default'];
38
+ },
39
+ globalImport: noop,
40
+ globalSetup: code => (typeof code === 'function' ? code : undefined),
41
+ },
42
+ plugins,
43
+ ];
44
+ }
@@ -0,0 +1,261 @@
1
+ import path from 'node:path';
2
+
3
+ import refiner from '@slimlib/refine-partition';
4
+
5
+ import { plugins as pluginFactories } from './get-plugins.js';
6
+ import { areSetsEqual, toArray } from './helpers.js';
7
+
8
+ /**
9
+ * @typedef {import('rollup').InternalModuleFormat} InternalModuleFormat
10
+ * @typedef {import('rollup').OutputOptions} OutputOptions
11
+ * @typedef {import('./types.js').BuildConfiguration} BuildConfiguration
12
+ * @typedef {import('./types.js').PackageProcessingResult} PackageProcessingResult
13
+ * @typedef {import('./types.js').PkgbldRollupPlugin} PkgbldRollupPlugin
14
+ * @typedef {import('./types.js').Provider} Provider
15
+ * @typedef {ReturnType<typeof import('./build-plugin-lifecycle.js').createBuildPluginLifecycle>} BuildPluginLifecycle
16
+ */
17
+
18
+ /**
19
+ * @param {[Provider, PkgbldRollupPlugin[]]} providerAndPlugins
20
+ * @param {PackageProcessingResult} packageResult
21
+ * @param {BuildConfiguration} configuration
22
+ * @param {ReturnType<import('./helpers.js').getHelpers>} helpers
23
+ * @param {BuildPluginLifecycle} pluginLifecycle
24
+ */
25
+ export async function getRollupConfigs([provider, plugins], packageResult, configuration, helpers, pluginLifecycle) {
26
+ const publicEntries = packageResult.entries.values.filter(entry => entry.origin !== 'import');
27
+ const privateEntries = packageResult.entries.values.filter(entry => entry.origin === 'import');
28
+ const inputs = publicEntries.map(entry => entry.sourcePath);
29
+ const publicInputSet = new Set(inputs);
30
+ const entriesBySourcePath = new Map(publicEntries.map(entry => [entry.sourcePath, entry]));
31
+ const factoryInProgress = [];
32
+
33
+ const fileNamePatterns = /** @type {{ [key in InternalModuleFormat]: string }} */ ({
34
+ es: configuration.outputs.patterns.es,
35
+ cjs: configuration.outputs.patterns.cjs,
36
+ umd: configuration.outputs.patterns.umd,
37
+ });
38
+
39
+ for (const factory of pluginFactories) {
40
+ factoryInProgress.push(factory(provider, configuration, packageResult));
41
+ }
42
+
43
+ factoryInProgress.push(pluginLifecycle.provideRollupPlugins(provider, configuration, packageResult));
44
+
45
+ await Promise.all(factoryInProgress);
46
+
47
+ /** @type {Set<string>} */
48
+ const expandInputs = new Set();
49
+
50
+ for (const plugin of plugins) {
51
+ if (plugin.format && plugin.inputs?.some(input => publicInputSet.has(input)) && !plugin.outputPlugin) {
52
+ for (const format of toArray(plugin.format)) {
53
+ expandInputs.add(format);
54
+ }
55
+ }
56
+ }
57
+
58
+ const refineNext = refiner();
59
+
60
+ refineNext(doExpandInputs(/** @type {InternalModuleFormat[]} */ ([...configuration.outputs.formats])));
61
+
62
+ for (const plugin of plugins) {
63
+ if (plugin.format && !plugin.outputPlugin) {
64
+ const publicPluginInputs = plugin.inputs?.filter(input => publicInputSet.has(input));
65
+ if (plugin.inputs && publicPluginInputs?.length === 0) continue;
66
+ const formats = toArray(plugin.format);
67
+ if (!plugin.inputs || plugin.inputs.length === 0) {
68
+ refineNext(doExpandInputs(formats));
69
+ } else if (inputs.length === 1) {
70
+ refineNext(formats);
71
+ } else {
72
+ const expanded = [];
73
+ for (const format of formats) {
74
+ for (const input of /** @type {string[]} */ (publicPluginInputs)) {
75
+ expanded.push(`${format}.${input}`);
76
+ }
77
+ }
78
+ refineNext(expanded);
79
+ }
80
+ }
81
+ }
82
+
83
+ const refined = refineNext();
84
+ /** @type {{ formats: InternalModuleFormat[]; inputs: string[] }[]} */
85
+ const partitions = [];
86
+
87
+ for (const partition of refined) {
88
+ /** @type {{ format: InternalModuleFormat; input?: string }[]} */
89
+ const result = [];
90
+ for (const format of partition) {
91
+ if (format.includes('.')) {
92
+ const [, realFormat, input] = format.split(/(.*?)\.(.*)/gm);
93
+ result.push({ format: /** @type {InternalModuleFormat} */ (realFormat), input });
94
+ } else {
95
+ result.push({ format: /** @type {InternalModuleFormat} */ (format) });
96
+ }
97
+ }
98
+ /** @type {Map<InternalModuleFormat, Set<string>>} */
99
+ const mapFormatInputs = new Map();
100
+ /** @type {Set<InternalModuleFormat>} */
101
+ const formatsWithoutInputs = new Set();
102
+ for (const { format, input } of result) {
103
+ if (input) {
104
+ if (mapFormatInputs.has(format)) {
105
+ /** @type {Set<string>} */ (mapFormatInputs.get(format)).add(input);
106
+ } else {
107
+ mapFormatInputs.set(format, new Set([input]));
108
+ }
109
+ } else {
110
+ formatsWithoutInputs.add(format);
111
+ }
112
+ }
113
+ for (const format of formatsWithoutInputs) {
114
+ if (mapFormatInputs.has(format)) {
115
+ throw new Error(
116
+ `${format} is both used with inputs and without in plugins configuration and was not expanded / handled correctly. Please file an issue for pkgbld.`
117
+ );
118
+ }
119
+ mapFormatInputs.set(format, new Set(inputs));
120
+ }
121
+ /** @type {Set<string> | undefined} */
122
+ let prevInputs;
123
+ for (const inputs of mapFormatInputs.values()) {
124
+ if (prevInputs) {
125
+ if (!areSetsEqual(inputs, prevInputs)) {
126
+ throw new Error(`unbalanced inputs for partition: ${JSON.stringify(partition)}`);
127
+ }
128
+ }
129
+ prevInputs = inputs;
130
+ }
131
+ partitions.push({ formats: [...mapFormatInputs.keys()], inputs: [.../** @type {Set<string>} */ (prevInputs)] });
132
+ }
133
+
134
+ const publicConfigs = partitions.map(({ formats, inputs }) => {
135
+ return {
136
+ input: Object.fromEntries(
137
+ inputs.map(input => [/** @type {import('./types.js').BuildEntry} */ (entriesBySourcePath.get(input)).name, input])
138
+ ),
139
+
140
+ output: formats.map(format => ({
141
+ format,
142
+ dir: configuration.paths.outputDir,
143
+ entryFileNames: fileNamePatterns[format],
144
+ plugins: getPlugins([format], inputs, true),
145
+ sourcemap: configuration.outputs.sourcemaps.some(value => value === format),
146
+ ...getExtraOutputSettings(format, inputs),
147
+ })),
148
+
149
+ plugins: getPlugins(formats, inputs, false),
150
+ };
151
+ });
152
+
153
+ const privateConfigs = privateEntries.map(entry => {
154
+ const [[format, outputPath]] = Object.entries(entry.outputPaths);
155
+ const input = entry.sourcePath;
156
+ const selectedFormat = /** @type {InternalModuleFormat} */ (format);
157
+ return {
158
+ input,
159
+ output: [
160
+ {
161
+ format: selectedFormat,
162
+ dir: configuration.paths.outputDir,
163
+ entryFileNames: path
164
+ .relative(path.resolve(configuration.paths.outputDir), path.resolve(outputPath))
165
+ .replaceAll('\\', '/'),
166
+ plugins: getPlugins([selectedFormat], [input], true, true),
167
+ sourcemap: configuration.outputs.sourcemaps.includes(/** @type {import('./types.js').BuildFormat} */ (selectedFormat)),
168
+ ...getExtraOutputSettings(selectedFormat, [input]),
169
+ },
170
+ ],
171
+ plugins: getPlugins([selectedFormat], [input], false, true),
172
+ };
173
+ });
174
+
175
+ return [...publicConfigs, ...privateConfigs];
176
+
177
+ /**
178
+ * @param {InternalModuleFormat} format
179
+ * @param {string[]} inputs
180
+ * @returns {Partial<OutputOptions>}
181
+ */
182
+ function getExtraOutputSettings(format, inputs) {
183
+ let result = {};
184
+ switch (format) {
185
+ case 'cjs':
186
+ case 'es':
187
+ result = { chunkFileNames: fileNamePatterns[format] };
188
+ break;
189
+ case 'umd':
190
+ if (inputs.length <= 0) {
191
+ break;
192
+ }
193
+ if (inputs.length > 1) {
194
+ throw new Error(`Cannot produce global name for multiple umd inputs in one output: ${inputs}`);
195
+ }
196
+ result = {
197
+ name: helpers.getGlobalName(inputs.join('_')),
198
+ globals: helpers.getExternalGlobalName,
199
+ };
200
+ break;
201
+ }
202
+ pluginLifecycle.extendOutputSettings(result, format, inputs, configuration);
203
+ return result;
204
+ }
205
+
206
+ /**
207
+ * @param {InternalModuleFormat[]} formats
208
+ * @param {string[]} inputs
209
+ * @param {boolean} outputPlugin
210
+ * @param {boolean} [privateOutput]
211
+ */
212
+ function getPlugins(formats, inputs, outputPlugin, privateOutput = false) {
213
+ const filteredPlugins = [];
214
+ for (const plugin of plugins) {
215
+ if (!!plugin.outputPlugin === outputPlugin) {
216
+ const publicPluginInputs = plugin.inputs?.filter(input => publicInputSet.has(input));
217
+ if (
218
+ (!plugin.format || toArray(plugin.format).some(format => formats.includes(format))) &&
219
+ (!plugin.inputs ||
220
+ plugin.inputs.length === 0 ||
221
+ (privateOutput
222
+ ? plugin.inputs.some(input => inputs.includes(input))
223
+ : publicPluginInputs?.length > 0 && publicPluginInputs.every(input => inputs.includes(input))))
224
+ ) {
225
+ filteredPlugins.push({
226
+ instance: plugin.plugin(),
227
+ priority: plugin.priority,
228
+ });
229
+ }
230
+ }
231
+ }
232
+ filteredPlugins.sort((a, b) => a.priority - b.priority);
233
+ return filteredPlugins.map(plugin => plugin.instance);
234
+ }
235
+
236
+ /**
237
+ * @param {InternalModuleFormat[]} formats
238
+ */
239
+ function doExpandInputs(formats) {
240
+ if (inputs.length === 1) {
241
+ return formats;
242
+ }
243
+ const expanded = [];
244
+ for (const format of formats) {
245
+ if (expandInputs.has(format)) {
246
+ if (format !== 'umd') {
247
+ for (const input of inputs) {
248
+ expanded.push(`${format}.${input}`);
249
+ }
250
+ } else {
251
+ for (const entryName of configuration.outputs.umdEntries) {
252
+ expanded.push(`${format}.${packageResult.entries.require(entryName).sourcePath}`);
253
+ }
254
+ }
255
+ } else {
256
+ expanded.push(format);
257
+ }
258
+ }
259
+ return expanded;
260
+ }
261
+ }
package/src/helpers.js ADDED
@@ -0,0 +1,229 @@
1
+ import { access, constants, readFile } from 'node:fs/promises';
2
+ import path, { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+
5
+ import { cyan, magenta } from '@niceties/ansi';
6
+
7
+ import { processPackageJson } from './options/index.js';
8
+
9
+ /**
10
+ * @typedef {import('rollup').OutputOptions} OutputOptions
11
+ * @typedef {import('type-fest').PackageJson} PackageJson
12
+ * @typedef {import('./options/index.js').PackageJson} PackageJsonO
13
+ */
14
+
15
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
+
17
+ /**
18
+ * @param {unknown} value
19
+ * @returns {string}
20
+ */
21
+ export function camelCase(value) {
22
+ const words = String(value)
23
+ .normalize('NFKD')
24
+ .replaceAll(/\p{Mark}/gu, '')
25
+ .replaceAll(/([\p{Ll}\d])(\p{Lu})/gu, '$1 $2')
26
+ .replaceAll(/(\p{Lu}+)(\p{Lu}\p{Ll})/gu, '$1 $2')
27
+ .match(/[\p{L}\d]+/gu);
28
+
29
+ return (words ?? [])
30
+ .map((word, index) => {
31
+ const lowerCaseWord = word.toLowerCase();
32
+ return index === 0 ? lowerCaseWord : lowerCaseWord[0].toUpperCase() + lowerCaseWord.slice(1);
33
+ })
34
+ .join('');
35
+ }
36
+
37
+ /**
38
+ * @param {string} pkgName
39
+ */
40
+ export function getHelpers(pkgName) {
41
+ /**
42
+ * @param {string} anInput
43
+ */
44
+ function getGlobalName(anInput) {
45
+ return camelCase(
46
+ path.join(
47
+ pkgName,
48
+ path.basename(anInput, path.extname(anInput)) !== 'index' ? path.basename(anInput, path.extname(anInput)) : ''
49
+ )
50
+ );
51
+ }
52
+
53
+ /**
54
+ * @param {string} id
55
+ */
56
+ function getExternalGlobalName(id) {
57
+ if (path.isAbsolute(id)) {
58
+ return getGlobalName(path.relative(__dirname, id));
59
+ }
60
+ return camelCase(id);
61
+ }
62
+
63
+ return {
64
+ getGlobalName,
65
+ getExternalGlobalName,
66
+ };
67
+ }
68
+
69
+ /**
70
+ * @template T
71
+ * @param {T | T[] | undefined} object
72
+ * @returns {T[]}
73
+ */
74
+ export function toArray(object) {
75
+ if (Array.isArray(object)) {
76
+ return object;
77
+ }
78
+ if (object == null) {
79
+ return [];
80
+ }
81
+ return [object];
82
+ }
83
+
84
+ /**
85
+ * @param {string[] | string} input
86
+ * @returns {string}
87
+ */
88
+ export function formatInput(input) {
89
+ return (Array.isArray(input) ? input : [input ?? '']).map(item => magenta(path.basename(item, path.extname(item)))).join(', ');
90
+ }
91
+
92
+ /**
93
+ * @param {OutputOptions | OutputOptions[] | undefined} output
94
+ * @param {'dir' | 'format'} field
95
+ * @returns {string}
96
+ */
97
+ export function formatOutput(output, field) {
98
+ if (output == null) {
99
+ return '';
100
+ }
101
+ return (Array.isArray(output) ? output : [output ?? '']).map(item => cyan(/** @type {string} */ (item[field]))).join(', ');
102
+ }
103
+
104
+ /**
105
+ * @param {number} starting
106
+ * @returns {string}
107
+ */
108
+ export function getTimeDiff(starting) {
109
+ const diff = Date.now() - starting;
110
+ return diff >= 1000 ? `${(diff / 1000).toFixed(1)}s` : `${diff}ms`;
111
+ }
112
+
113
+ /**
114
+ * @template T
115
+ * @param {Set<T>} a
116
+ * @param {Set<T>} b
117
+ * @returns {boolean}
118
+ */
119
+ export const areSetsEqual = (a, b) => (a.size === b.size ? [...a].every(value => b.has(value)) : false);
120
+
121
+ /**
122
+ * @param {PackageJson} pkg
123
+ * @returns {PackageJson}
124
+ */
125
+ export function formatPackageJson(pkg) {
126
+ return /** @type {PackageJson} */ (
127
+ processPackageJson(
128
+ /** @type {PackageJsonO} */ (pkg),
129
+ key => key in pkg,
130
+ key => /** @type {Record<string, unknown>} */ (pkg)[key]
131
+ )
132
+ );
133
+ }
134
+
135
+ /**
136
+ * @param {string} file
137
+ * @returns {Promise<string | false>}
138
+ */
139
+ export async function isExists(file) {
140
+ try {
141
+ await access(file);
142
+ } catch (e) {
143
+ if (typeof e === 'object' && e != null && 'code' in e && e.code === 'ENOENT') {
144
+ return /** @type {const} */ (false);
145
+ }
146
+ throw e;
147
+ }
148
+ return file;
149
+ }
150
+
151
+ /**
152
+ * @param {string} file
153
+ * @returns {Promise<boolean>}
154
+ */
155
+ export async function isReadable(file) {
156
+ try {
157
+ await access(file, constants.R_OK);
158
+ return true;
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+
164
+ /**
165
+ * @param {string} root
166
+ * @param {string} file
167
+ */
168
+ function hasFile(root, file) {
169
+ const path = join(root, file);
170
+ return isExists(path);
171
+ }
172
+
173
+ /**
174
+ * @param {string} root
175
+ * @returns {Promise<boolean>}
176
+ */
177
+ async function hasWorkspacePackageJson(root) {
178
+ const path = join(root, 'package.json');
179
+ if (!(await isReadable(path))) {
180
+ return false;
181
+ }
182
+ try {
183
+ const content = /** @type {PackageJson} */ (JSON.parse(await readFile(path, 'utf-8')) || {});
184
+ return !!content.workspaces;
185
+ } catch {
186
+ return false;
187
+ }
188
+ }
189
+
190
+ /**
191
+ * @param {string} current
192
+ * @returns {Promise<string>}
193
+ */
194
+ export async function searchForPackageRoot(current) {
195
+ const root = current;
196
+ let dir = current;
197
+
198
+ while (dir) {
199
+ if (await hasFile(dir, 'package.json')) return dir;
200
+
201
+ const parentDir = dirname(dir);
202
+ if (parentDir === dir) break;
203
+
204
+ dir = parentDir;
205
+ }
206
+
207
+ return root;
208
+ }
209
+
210
+ /**
211
+ * @param {string} current
212
+ * @returns {Promise<string>}
213
+ */
214
+ export async function searchForWorkspaceRoot(current) {
215
+ const root = await searchForPackageRoot(current);
216
+ let dir = current;
217
+
218
+ while (dir) {
219
+ if (await hasFile(dir, 'pnpm-workspace.yaml')) return dir;
220
+ if (await hasWorkspacePackageJson(dir)) return dir;
221
+
222
+ const parentDir = dirname(dir);
223
+ if (parentDir === dir) break;
224
+
225
+ dir = parentDir;
226
+ }
227
+
228
+ return root;
229
+ }
package/src/index.js ADDED
@@ -0,0 +1,133 @@
1
+ /// <reference path="./rollup-plugin-preprocess.d.ts" />
2
+ import '@niceties/draftlog-appender';
3
+ import { dirname, join } from 'node:path';
4
+
5
+ import { rollup } from 'rollup';
6
+
7
+ import { green } from '@niceties/ansi';
8
+ import { createLogger, LogLevel } from '@niceties/logger';
9
+
10
+ import { resolveBuildConfiguration } from './build-configuration.js';
11
+ import { createBuildPluginLifecycle } from './build-plugin-lifecycle.js';
12
+ import { createEjectProvider, ejectConfig } from './eject.js';
13
+ import { getJson } from './get-json.js';
14
+ import { createProvider } from './get-plugins.js';
15
+ import { getRollupConfigs } from './get-rollup-configs.js';
16
+ import { formatInput, formatOutput, formatPackageJson, getHelpers, getTimeDiff, searchForWorkspaceRoot, toArray } from './helpers.js';
17
+ import { loadPlugins } from './load-plugins.js';
18
+ import { mainLoggerText } from './messages.js';
19
+ import { processPackage } from './process-pkg.js';
20
+ import { checkTsConfig } from './process-ts-config.js';
21
+ import { writeJson } from './write-json.js';
22
+
23
+ /**
24
+ * @typedef {import('rollup').RollupOptions} RollupOptions
25
+ * @typedef {import('type-fest').PackageJson} PackageJson
26
+ * @typedef {import('./types.js').PkgbldPlugin} PkgbldPlugin
27
+ */
28
+
29
+ execute();
30
+
31
+ async function execute() {
32
+ const time = Date.now();
33
+ const mainLogger = createLogger();
34
+ mainLogger.update('preparing..');
35
+ try {
36
+ /** @type {PackageJson} */
37
+ let pkg;
38
+ /** @type {string} */
39
+ let pkgPath;
40
+ [pkgPath, pkg] = /** @type {[string, PackageJson]} */ (await getJson('package.json'));
41
+ /** @type {Set<string>} */
42
+ const loadedPlugins = new Set();
43
+ const plugins = await loadPlugins(pkg, loadedPlugins, pkgPath);
44
+ const [rootPackagePath, rootPkg] = await getJson(join(await searchForWorkspaceRoot(dirname(pkgPath)), 'package.json'));
45
+ if (rootPackagePath !== pkgPath) {
46
+ plugins.push(...(await loadPlugins(rootPkg, loadedPlugins, rootPackagePath)));
47
+ }
48
+ const pluginLifecycle = createBuildPluginLifecycle(plugins);
49
+ mainLogger.update('');
50
+ process.stdout.moveCursor?.(0, -1);
51
+ const configuration = resolveBuildConfiguration({ packageJson: pkg, pluginLifecycle });
52
+ process.stdout.moveCursor?.(0, 1);
53
+ mainLogger.update('preparing...');
54
+ await checkTsConfig(configuration, mainLogger, pluginLifecycle);
55
+ const packageResult = await processPackage(pkg, configuration, pluginLifecycle);
56
+ if (configuration.packageJson.format) {
57
+ pkg = formatPackageJson(pkg);
58
+ }
59
+ const helpers = getHelpers(/** @type {{ name: string }} */ (pkg).name);
60
+ const provider = configuration.execution.eject ? await createEjectProvider() : createProvider();
61
+ const rollupConfigs = await getRollupConfigs(provider, packageResult, configuration, helpers, pluginLifecycle);
62
+
63
+ if (!configuration.execution.bundle) {
64
+ rollupConfigs.length = 0;
65
+ }
66
+
67
+ if (configuration.execution.eject) {
68
+ await ejectConfig(rollupConfigs, pkgPath, configuration, packageResult, helpers, pkg);
69
+ mainLogger.finish(`ejected config in ${getTimeDiff(time)}`);
70
+ if (configuration.packageJson.update) {
71
+ await writeJson(pkgPath, pkg);
72
+ }
73
+ } else {
74
+ const updater = mainLoggerText(configuration.paths.sourceDir, configuration.paths.outputDir, rollupConfigs.length, time);
75
+ mainLogger.start(updater());
76
+
77
+ await Promise.all(rollupConfigs.map(config => buildConfig(config, updater)));
78
+
79
+ if (configuration.packageJson.update) {
80
+ await writeJson(pkgPath, pkg);
81
+ }
82
+ await pluginLifecycle.buildEnd(configuration);
83
+
84
+ mainLogger.finish(updater(true));
85
+ }
86
+ } catch (e) {
87
+ mainLogger.finish(String(e), LogLevel.error);
88
+ process.exit(-1);
89
+ }
90
+
91
+ /**
92
+ * @param {RollupOptions} config
93
+ * @param {() => string} updater
94
+ */
95
+ async function buildConfig(config, updater) {
96
+ const bundle = await rollup(config);
97
+ await Promise.all(toArray(config.output).map(config => bundle.write(config)));
98
+ await bundle.close();
99
+ mainLogger(
100
+ `${green('✓')} ${formatInput(
101
+ /** @type {string | string[]} */ (
102
+ typeof config.input === 'object' && !Array.isArray(config.input) ? Object.values(config.input) : config.input
103
+ )
104
+ )} [${formatOutput(config.output, 'format')}]`
105
+ );
106
+ mainLogger.update(updater());
107
+ }
108
+ }
109
+
110
+ /** @typedef {import('./types.js').Json} Json */
111
+ /** @typedef {import('./types.js').BuildConfiguration} BuildConfiguration */
112
+ /** @typedef {import('./types.js').BuildFormat} BuildFormat */
113
+ /** @typedef {import('./types.js').BuildConfigurationDraft} BuildConfigurationDraft */
114
+ /** @typedef {import('./types.js').BuildConfigurationSources} BuildConfigurationSources */
115
+ /** @typedef {import('./types.js').BuildEntry} BuildEntry */
116
+ /** @typedef {import('./types.js').BuildEntries} BuildEntries */
117
+ /** @typedef {import('./types.js').BuildEntryContribution} BuildEntryContribution */
118
+ /** @typedef {import('./types.js').BuildEntryContributions} BuildEntryContributions */
119
+ /** @typedef {import('./types.js').BuildEntryIssue} BuildEntryIssue */
120
+ /** @typedef {import('./types.js').ParsedOptions} ParsedOptions */
121
+ /** @typedef {import('./types.js').PackageProcessingResult} PackageProcessingResult */
122
+ /** @typedef {import('./types.js').PluginSharedState} PluginSharedState */
123
+ /** @typedef {import('./types.js').PluginConfigureContext} PluginConfigureContext */
124
+ /** @typedef {import('./types.js').PluginContributeEntriesContext} PluginContributeEntriesContext */
125
+ /** @typedef {import('./types.js').PluginPackageContext} PluginPackageContext */
126
+ /** @typedef {import('./types.js').PluginTsConfigContext} PluginTsConfigContext */
127
+ /** @typedef {import('./types.js').PluginRollupContext} PluginRollupContext */
128
+ /** @typedef {import('./types.js').PluginOutputContext} PluginOutputContext */
129
+ /** @typedef {import('./types.js').PluginBuildEndContext} PluginBuildEndContext */
130
+ /** @typedef {import('./types.js').PkgbldPluginFactory} PkgbldPluginFactory */
131
+ /** @typedef {import('./types.js').Provider} Provider */
132
+ /** @typedef {import('./types.js').ProvideFunction} ProvideFunction */
133
+ /** @typedef {import('./types.js').PkgbldRollupPlugin} PkgbldRollupPlugin */