pkgbld 1.35.1 → 2.0.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.
package/dist/index.mjs DELETED
@@ -1,1617 +0,0 @@
1
- import '@niceties/draftlog-appender';
2
- import { createLogger } from '@niceties/logger';
3
- import { rollup } from 'rollup';
4
- import fs, { readFile, access, stat, constants, writeFile, rm, readdir, mkdir, rename } from 'node:fs/promises';
5
- import path, { dirname, join } from 'node:path';
6
- import { cli, command } from 'cleye';
7
- import refiner from '@slimlib/refine-partition';
8
- import camelCase from 'lodash/camelCase.js';
9
- import kleur from 'kleur';
10
- import { fileURLToPath } from 'node:url';
11
- import cloneDeep from 'lodash/cloneDeep.js';
12
- import isEqual from 'lodash/isEqual.js';
13
-
14
- async function createSubpackages(inputs, config) {
15
- for (const input of inputs) {
16
- const basename = path.basename(input, path.extname(input));
17
- if (basename !== 'index') {
18
- const pkg = {
19
- type: 'module',
20
- types: `../${config.dir}/${basename}.d.ts`,
21
- main: `../${config.dir}/${basename}.mjs`
22
- };
23
- await fs.mkdir(basename, { recursive: true });
24
- await fs.writeFile(`${basename}/package.json`, JSON.stringify(pkg, null, 2));
25
- }
26
- }
27
- }
28
-
29
- function CommaSeparatedString(value) {
30
- return value.split(',').map((arg) => arg.trim());
31
- }
32
- function CommaSeparatedStringOrBoolean(value) {
33
- if (typeof value === 'boolean') {
34
- return value;
35
- }
36
- // TODO check how we get array here
37
- if (Array.isArray(value) && value.length === 0) {
38
- return true;
39
- }
40
- return CommaSeparatedString(value);
41
- }
42
- const cliFlagsDefaults = {
43
- formats: ['es', 'cjs'],
44
- umd: [],
45
- compress: ['umd'],
46
- sourcemaps: ['umd'],
47
- preprocess: [],
48
- dest: 'dist',
49
- src: 'src',
50
- bin: undefined,
51
- includeExternals: false,
52
- eject: false,
53
- noTsConfig: false,
54
- noUpdatePackageJson: false,
55
- commonjsPattern: '[name].cjs',
56
- esmPattern: '[name].mjs',
57
- umdPattern: '[name].umd.js',
58
- formatPackageJson: false
59
- };
60
- const cliFlags = {
61
- umd: {
62
- type: CommaSeparatedString,
63
- description: 'Package subpath exports in UMD format',
64
- default: cliFlagsDefaults.umd
65
- },
66
- compress: {
67
- type: CommaSeparatedString,
68
- description: 'Compress formats using terser',
69
- default: cliFlagsDefaults.compress
70
- },
71
- sourcemaps: {
72
- type: CommaSeparatedString,
73
- description: 'Emit sourcemaps for the specified formats',
74
- default: cliFlagsDefaults.sourcemaps
75
- },
76
- formats: {
77
- type: CommaSeparatedString,
78
- description: 'Formats to emit',
79
- default: cliFlagsDefaults.formats
80
- },
81
- preprocess: {
82
- type: CommaSeparatedString,
83
- description: 'Preprocess entry points / subpath exports',
84
- default: cliFlagsDefaults.preprocess
85
- },
86
- dest: {
87
- type: String,
88
- description: 'Output directory',
89
- default: cliFlagsDefaults.dest
90
- },
91
- src: {
92
- type: String,
93
- description: 'Source directory',
94
- default: cliFlagsDefaults.src
95
- },
96
- bin: {
97
- type: CommaSeparatedString,
98
- description: 'Executable files',
99
- default: cliFlagsDefaults.bin
100
- },
101
- includeExternals: {
102
- type: CommaSeparatedStringOrBoolean,
103
- description: 'Include all/specified externals into result bundle(s)',
104
- default: cliFlagsDefaults.includeExternals
105
- },
106
- eject: {
107
- type: Boolean,
108
- description: 'Eject config',
109
- default: cliFlagsDefaults.eject
110
- },
111
- noTsConfig: {
112
- type: Boolean,
113
- description: 'Do not create / update tsconfig.json',
114
- default: cliFlagsDefaults.noTsConfig
115
- },
116
- noUpdatePackageJson: {
117
- type: Boolean,
118
- description: 'Do not create / update package.json',
119
- default: cliFlagsDefaults.noUpdatePackageJson
120
- },
121
- commonjsPattern: {
122
- type: String,
123
- description: 'CommonJS output file name pattern',
124
- default: cliFlagsDefaults.commonjsPattern
125
- },
126
- esmPattern: {
127
- type: String,
128
- description: 'ES output file name pattern',
129
- default: cliFlagsDefaults.esmPattern
130
- },
131
- umdPattern: {
132
- type: String,
133
- description: 'UMD output file name pattern',
134
- default: cliFlagsDefaults.umdPattern
135
- },
136
- formatPackageJson: {
137
- type: Boolean,
138
- description: 'Format package.json',
139
- default: cliFlagsDefaults.formatPackageJson
140
- },
141
- noPack: {
142
- type: Boolean,
143
- description: 'Do not pack',
144
- default: false
145
- },
146
- noExports: {
147
- type: Boolean,
148
- description: 'Do not add exports field in package.json',
149
- default: false
150
- },
151
- noClean: {
152
- type: Boolean,
153
- description: 'Do not clean output directory',
154
- default: false
155
- },
156
- noBundle: {
157
- type: Boolean,
158
- description: 'Do not bundle',
159
- default: false
160
- },
161
- removeLegalComments: {
162
- type: Boolean,
163
- description: 'Remove legal comments',
164
- default: false
165
- }
166
- };
167
- const packageJsonFieldsOrder = new Set([
168
- 'private',
169
- 'type',
170
- 'version',
171
- 'name',
172
- 'scope', // custom
173
- 'description',
174
- 'license',
175
- 'author',
176
- 'contributors',
177
- 'funding',
178
- 'bin',
179
- 'main',
180
- 'browser',
181
- 'unpkg',
182
- 'module',
183
- 'svelte',
184
- 'exports',
185
- 'imports',
186
- 'types',
187
- 'typings',
188
- 'typesVersions', // non standard but required for typescript with resolution other than nodenext
189
- 'files',
190
- 'packageManager',
191
- 'sideEffects',
192
- 'engines',
193
- 'os',
194
- 'cpu',
195
- 'man',
196
- 'directories',
197
- 'repository',
198
- 'bugs',
199
- 'homepage',
200
- 'readme',
201
- 'keywords',
202
- 'scripts',
203
- 'config',
204
- 'dependencies',
205
- 'devDependencies',
206
- 'peerDependencies',
207
- 'peerDependenciesMeta',
208
- 'bundleDependencies',
209
- 'bundledDependencies',
210
- 'optionalDependencies',
211
- 'overrides',
212
- 'publishConfig',
213
- 'workspaces'
214
- ]);
215
- function processPackageJson(pkg, needTreatment, treatKey) {
216
- const newPkg = {};
217
- for (const key of packageJsonFieldsOrder) {
218
- if (needTreatment(key)) {
219
- newPkg[key] = treatKey(key);
220
- }
221
- }
222
- for (const key in pkg) {
223
- if (!packageJsonFieldsOrder.has(key)) {
224
- newPkg[key] = pkg[key];
225
- }
226
- }
227
- return newPkg;
228
- }
229
- function toFormattedJson(json) {
230
- return `${JSON.stringify(json, null, 2)}\n`;
231
- }
232
-
233
- function FlattenParam(value) {
234
- if (typeof value === 'boolean') {
235
- return value; // false
236
- }
237
- if (value === '') {
238
- return true; // means auto
239
- }
240
- return value; // string
241
- }
242
- function getCliOptions(plugins, pkg) {
243
- const cliOptions = cli({
244
- name: 'pkgbld',
245
- version: pkg.version ?? '<unknown>',
246
- flags: cliFlags,
247
- commands: [
248
- command({
249
- name: 'prune',
250
- description: 'prune devDependencies and redundant scripts from package.json',
251
- flags: {
252
- profile: {
253
- type: String,
254
- description: 'profile to use',
255
- default: 'library'
256
- },
257
- flatten: {
258
- type: FlattenParam,
259
- description: 'flatten package files',
260
- default: false
261
- },
262
- removeSourcemaps: {
263
- type: Boolean,
264
- description: 'remove sourcemaps',
265
- default: false
266
- },
267
- optimizeFiles: {
268
- type: Boolean,
269
- description: 'optimize files array',
270
- default: true
271
- }
272
- }
273
- })
274
- ]
275
- });
276
- if (cliOptions.command === 'prune') {
277
- return {
278
- kind: 'prune',
279
- profile: cliOptions.flags.profile,
280
- flatten: cliOptions.flags.flatten,
281
- removeSourcemaps: cliOptions.flags.removeSourcemaps,
282
- optimizeFiles: cliOptions.flags.optimizeFiles
283
- };
284
- }
285
- const flags = cliOptions.flags;
286
- const options = {
287
- kind: 'build',
288
- umdInputs: flags.umd,
289
- compressFormats: flags.compress,
290
- sourcemapFormats: flags.sourcemaps,
291
- formats: flags.formats,
292
- formatsOverridden: flags.formats !== cliFlagsDefaults.formats,
293
- preprocess: flags.preprocess,
294
- dir: flags.dest,
295
- sourceDir: flags.src,
296
- bin: flags.bin,
297
- includeExternals: flags.includeExternals,
298
- eject: flags.eject,
299
- noTsConfig: flags.noTsConfig,
300
- noUpdatePackageJson: flags.noUpdatePackageJson,
301
- commonjsPattern: flags.commonjsPattern,
302
- esPattern: flags.esmPattern,
303
- umdPattern: flags.umdPattern,
304
- formatPackageJson: flags.formatPackageJson,
305
- noPack: flags.noPack,
306
- noExports: flags.noExports,
307
- noClean: flags.noClean,
308
- noBundle: flags.noBundle,
309
- removeLegalComments: flags.removeLegalComments
310
- };
311
- for (const plugin of plugins) {
312
- plugin.options?.(flags, options);
313
- }
314
- return options;
315
- }
316
-
317
- async function getJson(fileName) {
318
- const pkgPath = path.resolve(fileName);
319
- const buffer = await fs.readFile(pkgPath);
320
- return [pkgPath, JSON.parse(buffer.toString())];
321
- }
322
-
323
- const Priority = {
324
- preprocess: 1000,
325
- cleanup: 1000,
326
- externals: 2000,
327
- resolve: 3000,
328
- commonjs: 4000,
329
- transpile: 6000,
330
- compress: 10000,
331
- finalize: 20000
332
- };
333
-
334
- async function clean (provider, config) {
335
- if (config.noClean) {
336
- return;
337
- }
338
- const pluginClean = await provider.import('@rollup-extras/plugin-clean');
339
- const pluginInstance = pluginClean();
340
- provider.provide(pluginFactory, Priority.cleanup, { outputPlugin: true });
341
- let firstPluginInstance = true;
342
- function pluginFactory() {
343
- const result = firstPluginInstance ? pluginInstance : pluginInstance.api.addInstance();
344
- firstPluginInstance = false;
345
- return result;
346
- }
347
- }
348
-
349
- async function commonjs (provider) {
350
- const pluginCommonjs = await provider.import('@rollup/plugin-commonjs');
351
- provider.provide(() => pluginCommonjs(), Priority.commonjs);
352
- }
353
-
354
- async function externals (provider, config, inputs, inputsExt) {
355
- if (config.includeExternals === true) {
356
- return;
357
- }
358
- const pluginExternals = await provider.import('@rollup-extras/plugin-externals');
359
- const allowGenericUmd = config.umdInputs.length === 1 && inputs.length === 1;
360
- if (config.formats.length > 0) {
361
- const format = (allowGenericUmd ? undefined : config.formats.filter(format => format !== 'umd'));
362
- provider.provide(() => pluginExternals(config.includeExternals === false
363
- ? {}
364
- : (id, external, importer) => includeExternals(importer, external, id, config)), Priority.externals, { format });
365
- // for eject config
366
- provider.globalImport('path', 'path');
367
- provider.globalSetup(includeExternals);
368
- }
369
- if (!allowGenericUmd && config.umdInputs.length > 0) {
370
- const curry = (await provider.import('lodash/curry.js'));
371
- for (const currentInput of config.umdInputs) {
372
- const isExternal = curry((currentInput, id, external, importer) => includeExternals(importer, external, id, config) || isExternalInput(currentInput, inputs, inputsExt, id, config))(currentInput);
373
- provider.provide(() => pluginExternals(isExternal), Priority.externals, { format: 'umd', inputs: [`./${config.sourceDir}/${currentInput}.${inputsExt.get(currentInput)}`] });
374
- }
375
- // for eject config
376
- if (config.formats.length === 0) {
377
- provider.globalImport('path', 'path');
378
- provider.globalSetup(includeExternals);
379
- }
380
- provider.globalSetup(isExternalInput);
381
- }
382
- }
383
- function includeExternals(importer, external, id, config) {
384
- if (config.includeExternals === false)
385
- return external;
386
- if (!external)
387
- return false;
388
- const internals = config.includeExternals;
389
- if (internals.includes(id) || internals.some(internal => id.includes(internal))) {
390
- return false;
391
- }
392
- return true;
393
- }
394
- function isExternalInput(currentInput, inputs, inputsExt, id, config) {
395
- const normalizedPath = path.isAbsolute(currentInput)
396
- ? `./${path.relative(process.cwd(), `${currentInput}.${inputsExt.get(currentInput)}`)}`
397
- : `./${path.join(config.sourceDir, `${currentInput}.${inputsExt.get(currentInput)}`)}`;
398
- const normalizedId = path.isAbsolute(id) ? `./${path.relative(process.cwd(), id)}` : id;
399
- return normalizedPath !== normalizedId && inputs.includes(normalizedPath);
400
- }
401
-
402
- async function preprocess (provider, config, inputs, inputsExt) {
403
- if (config.preprocess.length > 0) {
404
- const pluginPreprocess = await provider.import('rollup-plugin-preprocess');
405
- const include = config.preprocess.map(name => `${config.sourceDir}/${name}.${inputsExt.get(name)}`);
406
- for (const format of config.formats) {
407
- if (format !== 'umd') {
408
- provider.provide(() => pluginPreprocess.default({ include, context: { [format]: true } }), Priority.preprocess, { format });
409
- }
410
- else {
411
- for (const currentInput of config.umdInputs) {
412
- provider.provide(() => pluginPreprocess.default({ include, context: { umd: true } }), Priority.preprocess, { format, inputs: [`./${config.sourceDir}/${currentInput}.${inputsExt.get(currentInput)}`] });
413
- }
414
- }
415
- }
416
- }
417
- }
418
-
419
- async function resolve (provider) {
420
- const pluginResolve = await provider.import('@rollup/plugin-node-resolve');
421
- provider.provide(() => pluginResolve(), Priority.resolve);
422
- }
423
-
424
- async function terser (provider, config, inputs, inputsExt) {
425
- const filteredFormats = config.compressFormats.filter(format => config.formats.includes(format));
426
- if (filteredFormats.length > 0) {
427
- const pluginTerser = await provider.import('@rollup/plugin-terser');
428
- const options = {
429
- mangle: {
430
- properties: {
431
- regex: /_$/
432
- }
433
- }
434
- };
435
- if (config.removeLegalComments) {
436
- options.output = {
437
- comments: false,
438
- };
439
- }
440
- if (filteredFormats.length > 0) {
441
- for (const format of filteredFormats) {
442
- if (format !== 'umd') {
443
- provider.provide(() => pluginTerser(options), Priority.compress, { format, outputPlugin: true });
444
- }
445
- else {
446
- for (const currentInput of config.umdInputs) {
447
- provider.provide(() => pluginTerser(options), Priority.compress, { format, outputPlugin: true, inputs: [`./${config.sourceDir}/${currentInput}.${inputsExt.get(currentInput)}`] });
448
- }
449
- }
450
- }
451
- }
452
- }
453
- }
454
-
455
- async function typescript (provider, config, inputs) {
456
- const typescriptInputs = inputs.filter(input => input.endsWith('.ts') || input.endsWith('.tsx'));
457
- if (typescriptInputs.length > 0) {
458
- const pluginTypescript = await provider.import('rollup-plugin-typescript2');
459
- provider.provide(() => pluginTypescript(), Priority.transpile, typescriptInputs.length === inputs.length ? undefined : { inputs: typescriptInputs });
460
- }
461
- }
462
-
463
- async function binify (provider, config) {
464
- if (config.bin != null && config.bin.length > 0) {
465
- const pluginBinify = await provider.import('@rollup-extras/plugin-binify');
466
- provider.provide(() => pluginBinify({
467
- filter: (item) => item.type === 'chunk' && item.isEntry && config.bin.some(input => input === `./${config.dir}/${item.fileName}`)
468
- }), Priority.finalize, { outputPlugin: true, format: 'cjs' });
469
- }
470
- }
471
-
472
- async function json (provider) {
473
- const pluginJson = await provider.import('@rollup/plugin-json');
474
- provider.provide(() => pluginJson(), Priority.preprocess);
475
- }
476
-
477
- const plugins = [
478
- clean,
479
- commonjs,
480
- externals,
481
- preprocess,
482
- resolve,
483
- terser,
484
- typescript,
485
- binify,
486
- json
487
- ];
488
- const noop = () => undefined;
489
- function createProvider(preimportMap) {
490
- const plugins = [];
491
- return [{
492
- provide: (plugin, priority, options) => {
493
- plugins.push({ priority, plugin, format: options?.format, inputs: options?.inputs, outputPlugin: options?.outputPlugin });
494
- },
495
- import: async (name, exportName) => {
496
- const result = preimportMap.has(name) ? await preimportMap.get(name) : await import(name);
497
- return result[exportName ?? 'default'];
498
- },
499
- globalImport: noop,
500
- globalSetup: noop
501
- }, plugins];
502
- }
503
-
504
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
505
- function getHelpers(pkgName) {
506
- function getGlobalName(anInput) {
507
- return camelCase(path.join(pkgName, path.basename(anInput, path.extname(anInput)) !== 'index' ? path.basename(anInput, path.extname(anInput)) : ''));
508
- }
509
- function getExternalGlobalName(id) {
510
- if (path.isAbsolute(id)) {
511
- return getGlobalName(path.relative(__dirname, id));
512
- }
513
- return camelCase(id);
514
- }
515
- return {
516
- getGlobalName,
517
- getExternalGlobalName
518
- };
519
- }
520
- function toArray(object) {
521
- if (Array.isArray(object)) {
522
- return object;
523
- }
524
- if (object == null) {
525
- return [];
526
- }
527
- return [object];
528
- }
529
- function formatInput(input) {
530
- return (Array.isArray(input) ? input : [input ?? '']).map(item => kleur.magenta(path.basename(item, path.extname(item)))).join(', ');
531
- }
532
- function formatOutput(output, field) {
533
- //? can we avoid it
534
- if (output == null) {
535
- return '';
536
- }
537
- return (Array.isArray(output) ? output : [output ?? '']).map(item => kleur.cyan(item[field])).join(', ');
538
- }
539
- function getTimeDiff(starting) {
540
- const diff = Date.now() - starting;
541
- return diff >= 1000 ? `${(diff / 1000).toFixed(1)}s` : `${diff}ms`;
542
- }
543
- const areSetsEqual = (a, b) => a.size === b.size ? [...a].every(value => b.has(value)) : false;
544
- function formatPackageJson(pkg) {
545
- return processPackageJson(pkg, key => key in pkg, key => pkg[key]);
546
- }
547
- async function isExists(file) {
548
- try {
549
- await access(file);
550
- }
551
- catch (e) {
552
- if (typeof e === 'object' && e != null && 'code' in e && e.code === 'ENOENT') {
553
- return false;
554
- }
555
- throw e;
556
- }
557
- return file;
558
- }
559
- // it is borrowed from vite logic, basically the same but simplified
560
- // without recursion and fully async
561
- async function isReadable(file) {
562
- try {
563
- await stat(file);
564
- }
565
- catch {
566
- return false;
567
- }
568
- try {
569
- await access(file, constants.R_OK);
570
- return true;
571
- }
572
- catch {
573
- return false;
574
- }
575
- }
576
- function hasFile(root, file) {
577
- const path = join(root, file);
578
- return isExists(path);
579
- }
580
- async function hasWorkspacePackageJson(root) {
581
- const path = join(root, 'package.json');
582
- if (!await isReadable(path)) {
583
- return false;
584
- }
585
- try {
586
- const content = (JSON.parse(await readFile(path, 'utf-8')) || {});
587
- return !!content.workspaces;
588
- }
589
- catch {
590
- return false;
591
- }
592
- }
593
- async function searchForPackageRoot(current) {
594
- const root = current;
595
- let dir = current;
596
- while (dir) {
597
- if (await hasFile(dir, 'package.json'))
598
- return dir;
599
- const parentDir = dirname(dir);
600
- if (parentDir === dir)
601
- break; // Reached the filesystem root
602
- dir = parentDir;
603
- }
604
- return root;
605
- }
606
- async function searchForWorkspaceRoot(current) {
607
- const root = await searchForPackageRoot(current);
608
- let dir = current;
609
- while (dir) {
610
- if (await hasFile(dir, 'pnpm-workspace.yaml'))
611
- return dir;
612
- if (await hasWorkspacePackageJson(dir))
613
- return dir;
614
- const parentDir = dirname(dir);
615
- if (parentDir === dir)
616
- break; // Reached the filesystem root
617
- dir = parentDir;
618
- }
619
- return root;
620
- }
621
-
622
- async function getRollupConfigs([provider, plugins$1], inputs, inputsExt, config, helpers, externalPlugins) {
623
- const factoryInProgress = [];
624
- const fileNamePatterns = {
625
- 'es': config.esPattern,
626
- 'cjs': config.commonjsPattern,
627
- 'umd': config.umdPattern
628
- };
629
- for (const factory of plugins) {
630
- factoryInProgress.push(factory(provider, config, inputs, inputsExt));
631
- }
632
- for (const ePlugin of externalPlugins) {
633
- if (ePlugin.providePlugins) {
634
- factoryInProgress.push(ePlugin.providePlugins(provider, config, inputs, inputsExt));
635
- }
636
- }
637
- await Promise.all(factoryInProgress);
638
- const expandInputs = new Set;
639
- for (const plugin of plugins$1) {
640
- if (plugin.format && plugin.inputs?.length && !plugin.outputPlugin) {
641
- for (const format of toArray(plugin.format)) {
642
- expandInputs.add(format);
643
- }
644
- }
645
- }
646
- const refineNext = refiner();
647
- refineNext(doExpandInputs(toArray(config.formats)));
648
- for (const plugin of plugins$1) {
649
- if (plugin.format && !plugin.outputPlugin) {
650
- const formats = toArray(plugin.format);
651
- if (!plugin.inputs || plugin.inputs.length === 0) {
652
- refineNext(doExpandInputs(formats));
653
- }
654
- else if (inputs.length === 1) {
655
- refineNext(formats);
656
- }
657
- else {
658
- const expanded = [];
659
- for (const format of formats) {
660
- for (const input of plugin.inputs) {
661
- expanded.push(`${format}.${input}`);
662
- }
663
- }
664
- refineNext(expanded);
665
- }
666
- }
667
- }
668
- const refined = refineNext();
669
- const partitions = [];
670
- for (const partition of refined) {
671
- const result = [];
672
- for (const format of partition) {
673
- if (format.includes('.')) {
674
- const [, realFormat, input] = format.split(/(.*?)\.(.*)/gm);
675
- result.push({ format: realFormat, input });
676
- }
677
- else {
678
- result.push({ format });
679
- }
680
- }
681
- const mapFormatInputs = new Map;
682
- const formatsWithoutInputs = new Set;
683
- for (const { format, input } of result) {
684
- if (input) {
685
- if (mapFormatInputs.has(format)) {
686
- // biome-ignore lint/style/noNonNullAssertion: <explanation>
687
- mapFormatInputs.get(format).add(input);
688
- }
689
- else {
690
- mapFormatInputs.set(format, new Set([input]));
691
- }
692
- }
693
- else {
694
- formatsWithoutInputs.add(format);
695
- }
696
- }
697
- for (const format of formatsWithoutInputs) {
698
- if (mapFormatInputs.has(format)) {
699
- throw new Error(`${format} is both used with inputs and without in plugins configuration and was not expanded / handled correctly. Please file an issue for pkgbld.`);
700
- }
701
- mapFormatInputs.set(format, new Set(inputs));
702
- }
703
- let prevInputs;
704
- for (const inputs of mapFormatInputs.values()) {
705
- if (prevInputs) {
706
- if (!areSetsEqual(inputs, prevInputs)) {
707
- throw new Error(`unbalanced inputs for partition: ${JSON.stringify(partition)}`);
708
- }
709
- }
710
- prevInputs = inputs;
711
- }
712
- partitions.push({ formats: [...mapFormatInputs.keys()], inputs: [...prevInputs] });
713
- }
714
- return partitions.map(({ formats, inputs }) => {
715
- return {
716
- input: inputs,
717
- output: formats.map(format => ({
718
- format,
719
- dir: config.dir,
720
- entryFileNames: fileNamePatterns[format],
721
- plugins: getPlugins([format], inputs, true),
722
- sourcemap: config.sourcemapFormats.includes(format),
723
- // this requires more work
724
- // preserveModules: true,
725
- // preserveModulesRoot: config.sourceDir,
726
- ...getExtraOutputSettings(format, inputs)
727
- })),
728
- plugins: getPlugins(formats, inputs, false)
729
- };
730
- });
731
- function getExtraOutputSettings(format, inputs) {
732
- let result = {};
733
- switch (format) {
734
- case 'cjs':
735
- case 'es':
736
- result = { chunkFileNames: fileNamePatterns[format] };
737
- break;
738
- case 'umd':
739
- if (inputs.length <= 0) {
740
- break;
741
- }
742
- if (inputs.length > 1) {
743
- throw new Error(`Cannot produce global name for multiple umd inputs in one output: ${inputs}`);
744
- }
745
- result = {
746
- name: helpers.getGlobalName(inputs.join('_')),
747
- globals: helpers.getExternalGlobalName,
748
- };
749
- break;
750
- }
751
- for (const ePlugin of externalPlugins) {
752
- if (ePlugin.getExtraOutputSettings) {
753
- Object.assign(result, ePlugin.getExtraOutputSettings(format, inputs));
754
- }
755
- }
756
- return result;
757
- }
758
- function getPlugins(formats, inputs, outputPlugin) {
759
- const filteredPlugins = [];
760
- for (const plugin of plugins$1) {
761
- if ((!!plugin.outputPlugin) === outputPlugin) {
762
- if ((!plugin.format || toArray(plugin.format).some(format => formats.includes(format)))
763
- && (!plugin.inputs || plugin.inputs.every(input => inputs.includes(input)))) {
764
- filteredPlugins.push({
765
- instance: plugin.plugin(),
766
- priority: plugin.priority
767
- });
768
- }
769
- }
770
- }
771
- filteredPlugins.sort((a, b) => a.priority - b.priority);
772
- return filteredPlugins.map(plugin => plugin.instance);
773
- }
774
- function doExpandInputs(formats) {
775
- if (inputs.length === 1) {
776
- return formats;
777
- }
778
- const expanded = [];
779
- for (const format of formats) {
780
- if (expandInputs.has(format)) {
781
- if (format !== 'umd') {
782
- for (const input of inputs) {
783
- expanded.push(`${format}.${input}`);
784
- }
785
- }
786
- else {
787
- for (const input of config.umdInputs) {
788
- expanded.push(`${format}../${config.sourceDir}/${input}.${inputsExt.get(input)}`);
789
- }
790
- }
791
- }
792
- else {
793
- expanded.push(format);
794
- }
795
- }
796
- return expanded;
797
- }
798
- }
799
-
800
- const mainLoggerText = (sourceDir, dir, configsCount, startingTime, finishedCount = 0) => (final = false) => `${sourceDir} → ${dir} ${final ? configsCount : finishedCount++} / ${configsCount}${final ? (` in ${getTimeDiff(startingTime)}`) : ''}`;
801
-
802
- const emptySet = new Set;
803
- const sourceFileSuffixes = ['ts', 'tsx', 'js', 'jsx', 'cjs', 'mjs']; // svelte, vue, etc. are not supported yet
804
- async function processPackage(pkg, config, plugins, tsConfig) {
805
- const typingsFilePattern = '[name].d.ts';
806
- const indexId = 'index';
807
- const typesVersionsLastFields = new Set(['*']);
808
- // check if declarations enabled
809
- const isDeclarations = typeof tsConfig === 'object'
810
- && tsConfig != null && 'compilerOptions' in tsConfig
811
- && typeof tsConfig.compilerOptions === 'object' && tsConfig.compilerOptions !== null
812
- && 'declaration' in tsConfig.compilerOptions && tsConfig.compilerOptions.declaration === true;
813
- const inputs = [];
814
- const inputsExt = new Map;
815
- const logger = createLogger();
816
- const allowEsm = (config.formatsOverridden && config.formats.includes('es') || !config.formatsOverridden);
817
- const allowCjs = (config.formatsOverridden && config.formats.includes('cjs') || !config.formatsOverridden);
818
- const allowUmd = (config.formatsOverridden && config.formats.includes('umd') || !config.formatsOverridden || config.umdInputs);
819
- if (typeof pkg !== 'object' || Array.isArray(pkg) || pkg == null) {
820
- logger.finish('expecting object on top level of package.json', 3 /* LogLevel.error */);
821
- process.exit(-1);
822
- }
823
- if (typeof pkg.name !== 'string' && config.umdInputs.length > 0) {
824
- logger.finish('expecting name to be a string in package.json', 3 /* LogLevel.error */);
825
- process.exit(-1);
826
- }
827
- if (!Array.isArray(pkg.files)) {
828
- pkg.files = [];
829
- }
830
- if (!pkg.files.includes(config.dir)) {
831
- pkg.files.push(config.dir);
832
- }
833
- if (typeof pkg.scripts !== 'object' && pkg.scripts !== null) {
834
- pkg.scripts = {};
835
- }
836
- if (!config.noPack && !('prepack' in pkg.scripts)) {
837
- const binary = typeof pkg.scripts.build === 'string' && pkg.scripts.build?.startsWith('pkgbld-internal') ? 'pkgbld-internal' : 'pkgbld';
838
- pkg.scripts.prepack = `${binary} prune`;
839
- }
840
- if (allowEsm && !allowCjs && typeof pkg.type !== 'string') {
841
- pkg.type = 'module';
842
- }
843
- const exportsFields = new Set([
844
- 'types',
845
- 'svelte',
846
- pkg.type === 'module' ? 'require' : 'import',
847
- pkg.type === 'module' ? 'import' : 'require',
848
- 'default'
849
- ]);
850
- if (typeof pkg.typings === 'string') {
851
- pkg.typings = undefined;
852
- }
853
- if (isDeclarations) {
854
- pkg.types = `./${config.dir}/${patternToName(typingsFilePattern, 'index')}`;
855
- }
856
- if (allowUmd && typeof pkg.umd === 'string') {
857
- pkg.umd = `./${config.dir}/${patternToName(config.umdPattern, indexId)}`;
858
- if (!config.umdInputs.includes(indexId)) {
859
- config.umdInputs.push(indexId);
860
- }
861
- }
862
- if (allowCjs) {
863
- pkg.main = `./${config.dir}/${patternToName(config.commonjsPattern, indexId)}`;
864
- }
865
- if (allowEsm && !allowCjs) {
866
- pkg.main = `./${config.dir}/${patternToName(config.esPattern, indexId)}`;
867
- }
868
- if (allowCjs && allowEsm && typeof pkg.module !== 'string') {
869
- pkg.module = `./${config.dir}/${patternToName(config.esPattern, indexId)}`;
870
- }
871
- if (allowUmd && config.umdInputs.includes(indexId)) {
872
- pkg.unpkg = `./${config.dir}/${patternToName(config.umdPattern, indexId)}`;
873
- }
874
- if (isDeclarations) {
875
- if (typeof pkg.typesVersions !== 'object' && pkg.typesVersions !== null) {
876
- pkg.typesVersions = {};
877
- }
878
- if (typeof pkg.typesVersions['*'] !== 'object' && pkg.typesVersions['*'] !== null) {
879
- pkg.typesVersions['*'] = {};
880
- }
881
- }
882
- if (!config.noExports) {
883
- if (typeof pkg.exports !== 'object' && pkg.exports !== null) {
884
- pkg.exports = {};
885
- }
886
- if (pkg.exports['.'] == null) {
887
- pkg.exports['.'] = {};
888
- }
889
- pkg.exports['./package.json'] = './package.json';
890
- if (allowCjs && pkg.main !== pkg.exports['.'].require) {
891
- pkg.exports['.'].require = pkg.main;
892
- }
893
- if (pkg.module !== pkg.exports['.']?.default) {
894
- pkg.exports['.'].default = pkg.module;
895
- }
896
- for (const id in pkg.exports) {
897
- if (id === './package.json')
898
- continue;
899
- const basename = id === '.' ? indexId : path.join(path.dirname(id), path.basename(id));
900
- if (typeof pkg.exports[id] !== 'object') {
901
- pkg.exports[id] = {};
902
- }
903
- if (isDeclarations) {
904
- pkg.typesVersions['*'][id] = [`${config.dir}/${patternToName(typingsFilePattern, basename)}`];
905
- pkg.exports[id].types = `./${config.dir}/${patternToName(typingsFilePattern, basename)}`;
906
- }
907
- const cjsFieldName = pkg.type === 'module' ? 'require' : 'default';
908
- const esmFieldName = pkg.type === 'module' ? 'default' : 'import';
909
- if (allowEsm) {
910
- pkg.exports[id][esmFieldName] = `./${config.dir}/${patternToName(config.esPattern, basename)}`;
911
- }
912
- if (allowCjs) {
913
- pkg.exports[id][cjsFieldName] = `./${config.dir}/${patternToName(config.commonjsPattern, basename)}`;
914
- }
915
- pkg.exports[id] = orderFields(exportsFields, pkg.exports[id]);
916
- if (basename !== indexId) {
917
- if (!pkg.files.includes(basename)) {
918
- pkg.files.push(basename);
919
- }
920
- }
921
- await updateExtensions(basename);
922
- }
923
- }
924
- else {
925
- await updateExtensions(indexId);
926
- }
927
- if (isDeclarations) {
928
- pkg.typesVersions['*']['*'] = [
929
- `${config.dir}/${patternToName(typingsFilePattern, indexId)}`,
930
- `${config.dir}/*`
931
- ];
932
- pkg.typesVersions['*'] = orderFields(emptySet, pkg.typesVersions['*'], typesVersionsLastFields);
933
- }
934
- if (allowUmd && config.umdInputs.length > 0 && !config.formats.includes('umd')) {
935
- config.formats.push('umd');
936
- }
937
- for (const plugin of plugins) {
938
- plugin.processPackageJson?.(pkg, inputs);
939
- }
940
- if (config.bin) {
941
- if (config.bin.length > 0) {
942
- if (config.bin[0] !== '') {
943
- pkg.bin = config.bin[0];
944
- }
945
- config.bin = config.bin.filter(Boolean);
946
- if (config.bin.length === 0) {
947
- config.bin = undefined;
948
- }
949
- }
950
- }
951
- else if (allowCjs && inputs.length > 0) {
952
- if (typeof pkg.bin === 'string') {
953
- if (inputs.some(input => pkg.bin === `./${config.dir}/${patternToName(config.commonjsPattern, path.basename(input, path.extname(input)))}`)) {
954
- config.bin = [pkg.bin];
955
- }
956
- }
957
- else if (typeof pkg.bin === 'object' && pkg.bin !== null) {
958
- const executables = Object.values(pkg.bin).filter(value => typeof value === 'string' && inputs.some(input => value === `./${config.dir}/${patternToName(config.commonjsPattern, path.basename(input, path.extname(input)))}`));
959
- if (executables.length > 0) {
960
- config.bin = executables;
961
- }
962
- }
963
- if (typeof pkg.directories === 'object' && pkg.directories != null && 'bin' in pkg.directories && typeof pkg.directories.bin === 'string') {
964
- if (path.resolve(pkg.directories.bin) === path.resolve(config.dir)) {
965
- config.bin?.push(...inputs.map(input => `./${config.dir}/${patternToName(config.commonjsPattern, input)}`));
966
- config.bin = Array.from(new Set(config.bin));
967
- }
968
- }
969
- }
970
- return [inputs, inputsExt];
971
- async function updateExtensions(id) {
972
- const sourceFileWithoutSuffix = `./${config.sourceDir}/${id}.`;
973
- for (const suffix of sourceFileSuffixes) {
974
- const file = sourceFileWithoutSuffix + suffix;
975
- if (await isExists(file)) {
976
- inputs.push(file);
977
- inputsExt.set(id, suffix);
978
- break;
979
- }
980
- }
981
- }
982
- }
983
- function patternToName(pattern, input) {
984
- return pattern.replace('[name]', input);
985
- }
986
- function orderFields(firstFields, exports, lastFields = emptySet) {
987
- const ordered = {};
988
- for (const key of firstFields) {
989
- if (key in exports) {
990
- ordered[key] = exports[key];
991
- }
992
- }
993
- for (const key in exports) {
994
- if (!firstFields.has(key) && !lastFields.has(key)) {
995
- ordered[key] = exports[key];
996
- }
997
- }
998
- for (const key of lastFields) {
999
- if (key in exports) {
1000
- ordered[key] = exports[key];
1001
- }
1002
- }
1003
- return ordered;
1004
- }
1005
-
1006
- async function writeJson(path, json) {
1007
- await fs.writeFile(path, toFormattedJson(json));
1008
- }
1009
-
1010
- var dependencies = {
1011
- "@niceties/logger": "^1.1.13",
1012
- "@niceties/draftlog-appender": "^1.3.3",
1013
- lodash: "^4.17.21",
1014
- rollup: "^4.34.7",
1015
- "rollup-plugin-typescript2": "^0.36.0",
1016
- "rollup-plugin-preprocess": "^0.0.4",
1017
- "@rollup/plugin-commonjs": "^28.0.2",
1018
- "@rollup/plugin-terser": "^0.4.4",
1019
- "@rollup/plugin-json": "^6.1.0",
1020
- "@rollup/plugin-node-resolve": "^16.0.0",
1021
- "@rollup-extras/plugin-clean": "^1.3.9",
1022
- "@rollup-extras/plugin-binify": "^1.1.10",
1023
- "@rollup-extras/plugin-externals": "^1.2.2",
1024
- "@slimlib/refine-partition": "^1.0.3",
1025
- "@slimlib/smart-mock": "^0.1.6",
1026
- "is-builtin-module": "^3.2.1",
1027
- terser: "^5.39.0",
1028
- kleur: "^4.1.5",
1029
- cleye: "^1.3.4",
1030
- jsonata: "^2.0.6"
1031
- };
1032
- var pkgbldPkg = {
1033
- dependencies: dependencies};
1034
-
1035
- const imports = new Map;
1036
- const setup = new Set;
1037
- let generate, generateGlobals;
1038
- async function createEjectProvider(preimportMap) {
1039
- const createMockProvider = (await import('@slimlib/smart-mock')).default;
1040
- const provider = createMockProvider();
1041
- const createMock = provider.createMock;
1042
- generate = provider.generate;
1043
- generateGlobals = provider.generateGlobals;
1044
- const plugins = [];
1045
- return [{
1046
- provide: (plugin, priority, options) => {
1047
- plugins.push({ priority, plugin, format: options?.format, inputs: options?.inputs, outputPlugin: options?.outputPlugin });
1048
- },
1049
- import: async (name, exportName) => {
1050
- const result = preimportMap.has(name) ? await preimportMap.get(name) : await import(name);
1051
- const exports = result[exportName ?? 'default'];
1052
- const mangledName = camelCase(name);
1053
- imports.set(name, mangledName);
1054
- return createMock(exports, mangledName);
1055
- },
1056
- globalImport: (module, exportName) => {
1057
- imports.set(module, exportName ?? 'default');
1058
- },
1059
- // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
1060
- globalSetup: (code) => {
1061
- if (typeof code === 'function') {
1062
- setup.add(code.toString());
1063
- }
1064
- setup.add(String(code));
1065
- }
1066
- }, plugins];
1067
- }
1068
- async function ejectConfig(config, pkgPath, options, inputs, inputsExt, helpers, pkg) {
1069
- const pkgName = pkg.name;
1070
- // generate from config
1071
- const text = generate(config);
1072
- setup.add(generateGlobals());
1073
- // generate globals for config functions
1074
- setup.add(`const config = ${generate(options)}`);
1075
- setup.add(`const inputs = ${generate(inputs)}`);
1076
- setup.add(`const inputsExt = new Map(${generate(Array.from(inputsExt))})`);
1077
- // generate helpers code
1078
- if (options.formats.includes('umd')) {
1079
- imports.set('path', 'path');
1080
- imports.set('lodash/camelCase.js', 'camelCase');
1081
- imports.set('url', 'url'); // for __dirname polyfill
1082
- setup.add(`const pkgName = ${generate(pkgName)}`);
1083
- setup.add(helpers.getGlobalName.toString());
1084
- // polyfill __dirname
1085
- setup.add('const __dirname = url.fileURLToPath(new URL(\'.\', import.meta.url));');
1086
- }
1087
- // imports
1088
- const importsString = Array.from(imports)
1089
- .map((value) => `import ${value[1]} from '${value[0]}';`)
1090
- .join('\n');
1091
- const setupString = Array.from(setup)
1092
- .join('\n');
1093
- const { minify } = await import('terser');
1094
- const result = await minify(`${importsString}\n${setupString}\nexport default ${text};`, {
1095
- module: true,
1096
- compress: {
1097
- booleans: false,
1098
- ecma: 2020,
1099
- module: true,
1100
- passes: 3,
1101
- unsafe: true
1102
- },
1103
- mangle: false,
1104
- output: {
1105
- beautify: true,
1106
- ecma: 2020,
1107
- quote_style: 1
1108
- }
1109
- });
1110
- await fs.writeFile(path.join(path.dirname(pkgPath), 'rollup.config.mjs'), result.code);
1111
- await updatePackageJson(pkg);
1112
- }
1113
- async function updatePackageJson(pkg) {
1114
- if (typeof pkg.devDependencies !== 'object') {
1115
- pkg.devDependencies = {};
1116
- }
1117
- const devDependencies = pkg.devDependencies;
1118
- if ('pkgbld' in devDependencies) {
1119
- devDependencies.pkgbld = undefined;
1120
- }
1121
- devDependencies.rollup = pkgbldPkg.dependencies.rollup;
1122
- const isBuiltin = (await import('is-builtin-module')).default;
1123
- for (const key of imports.keys()) {
1124
- const packageName = getPackageName(key);
1125
- if (!isBuiltin(packageName)) {
1126
- devDependencies[packageName] = pkgbldPkg.dependencies[packageName] ?? '*';
1127
- }
1128
- }
1129
- }
1130
- function getPackageName(key) {
1131
- return key.split('/').slice(0, key.startsWith('@') ? 2 : 1).join('/');
1132
- }
1133
-
1134
- const defaultTsConfig = {
1135
- include: ['src', 'types'],
1136
- compilerOptions: {
1137
- lib: ['dom', 'esnext'],
1138
- target: 'esnext',
1139
- module: 'esnext',
1140
- esModuleInterop: true,
1141
- allowJs: true,
1142
- skipLibCheck: true,
1143
- strict: true,
1144
- sourceMap: true,
1145
- noUncheckedIndexedAccess: true,
1146
- declaration: true,
1147
- moduleResolution: 'node'
1148
- }
1149
- };
1150
- async function checkTsConfig(options, mainLogger, plugins) {
1151
- if (options.noTsConfig) {
1152
- return;
1153
- }
1154
- // biome-ignore lint/style/useSingleVarDeclarator: <explanation>
1155
- let config, needWrite = false;
1156
- try {
1157
- [, config] = await getJson('tsconfig.json');
1158
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1159
- }
1160
- catch (_) { /*ignore*/ }
1161
- try {
1162
- [, config] = await getJson('jsconfig.json');
1163
- if (config && typeof config === 'object' && !Array.isArray(config)) {
1164
- config.allowJs = true;
1165
- }
1166
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1167
- }
1168
- catch (_) { /*ignore*/ }
1169
- if (!config) {
1170
- config = defaultTsConfig;
1171
- needWrite = true;
1172
- }
1173
- const originalConfig = cloneDeep(config);
1174
- for (const plugin of plugins) {
1175
- plugin.processTsConfig?.(config);
1176
- }
1177
- if (!isEqual(originalConfig, config)) {
1178
- needWrite = true;
1179
- }
1180
- if (needWrite) {
1181
- mainLogger('no tsconfig.json or jsconfig.json and --no-ts-config not specified, writing tsconfig...');
1182
- await writeJson(path.resolve('tsconfig.json'), config);
1183
- mainLogger('done');
1184
- }
1185
- return config;
1186
- }
1187
-
1188
- async function loadPlugins(pkg, loaded) {
1189
- try {
1190
- return await Promise.all([...new Set([...Object.keys(pkg.devDependencies || {}), ...Object.keys(pkg.dependencies || {}), ...Object.keys(pkg.peerDependencies || {})])]
1191
- .filter(packageName => packageName.startsWith('pkgbld-plugin-') && !loaded.has(packageName))
1192
- .map(packageName => {
1193
- loaded.add(packageName);
1194
- return import(packageName).then((pluginFactory) => pluginFactory.create());
1195
- }));
1196
- }
1197
- catch (e) {
1198
- console.error(e);
1199
- return [];
1200
- }
1201
- }
1202
-
1203
- async function prunePkg(pkg, options, logger) {
1204
- const scriptsToKeep = getScriptsData();
1205
- const keys = scriptsToKeep[options.profile];
1206
- if (!keys) {
1207
- throw new Error(`unknown profile ${options.profile}`);
1208
- }
1209
- pkg.devDependencies = undefined;
1210
- pkg.packageManager = undefined;
1211
- if (pkg.scripts) {
1212
- for (const key of Object.keys(pkg.scripts)) {
1213
- if (!keys.has(key)) {
1214
- delete pkg.scripts[key];
1215
- }
1216
- }
1217
- if (Object.keys(pkg.scripts).length === 0) {
1218
- pkg.scripts = undefined;
1219
- }
1220
- }
1221
- if (options.flatten) {
1222
- await flatten(pkg, options.flatten, logger);
1223
- }
1224
- if (options.removeSourcemaps) {
1225
- const sourceMaps = await walkDir('.', ['node_modules']).then(files => files.filter(file => file.endsWith('.map')));
1226
- for (const sourceMap of sourceMaps) {
1227
- // find corresponding file
1228
- const sourceFile = sourceMap.slice(0, -4);
1229
- // load file
1230
- const sourceFileContent = await readFile(sourceFile, 'utf8');
1231
- // find sourceMappingURL
1232
- const sourceMappingUrl = `\n//# sourceMappingURL=${path.basename(sourceMap)}`;
1233
- // remove sourceMappingURL
1234
- const newContent = sourceFileContent.replace(sourceMappingUrl, '');
1235
- // write file
1236
- await writeFile(sourceFile, newContent, 'utf8');
1237
- // remove sourceMap
1238
- await rm(sourceMap);
1239
- }
1240
- }
1241
- if (pkg.files && Array.isArray(pkg.files) && options.optimizeFiles) {
1242
- const filterFiles = ['package.json'];
1243
- const specialFiles = ['README', 'LICENSE', 'LICENCE'];
1244
- if (pkg.main && typeof pkg.main === 'string') {
1245
- filterFiles.push(normalizePath(pkg.main));
1246
- }
1247
- if (pkg.bin) {
1248
- if (typeof pkg.bin === 'string') {
1249
- filterFiles.push(normalizePath(pkg.bin));
1250
- }
1251
- if (typeof pkg.bin === 'object' && pkg.bin !== null) {
1252
- filterFiles.push(...Object.values(pkg.bin).map(normalizePath));
1253
- }
1254
- }
1255
- const depthToFiles = new Map();
1256
- for (const file of pkg.files.concat(filterFiles)) {
1257
- const dirname = path.dirname(file);
1258
- const depth = dirname.split('/').length;
1259
- if (!depthToFiles.has(depth)) {
1260
- depthToFiles.set(depth, [file]);
1261
- }
1262
- else {
1263
- depthToFiles.get(depth)?.push(file);
1264
- }
1265
- }
1266
- // walk depth keys from the highest to the lowest
1267
- const maxDepth = Math.max(...depthToFiles.keys());
1268
- for (let depth = maxDepth; depth > 0; --depth) {
1269
- const files = depthToFiles.get(depth);
1270
- const mapDirToFiles = new Map();
1271
- for (const file of files) {
1272
- const dirname = path.dirname(file);
1273
- const basename = normalizePath(path.basename(file));
1274
- if (!mapDirToFiles.has(dirname)) {
1275
- mapDirToFiles.set(dirname, [basename]);
1276
- }
1277
- else {
1278
- mapDirToFiles.get(dirname)?.push(basename);
1279
- }
1280
- }
1281
- for (const [dirname, filesInDir] of mapDirToFiles) {
1282
- // find out real content of the directory
1283
- const realFiles = await readdir(dirname);
1284
- // check if all files in the directory are in the filesInDir
1285
- const allFilesInDir = realFiles.every(file => filesInDir.includes(file)) || realFiles.length === 0;
1286
- if (allFilesInDir && dirname !== '.') {
1287
- if (!depthToFiles.has(depth - 1)) {
1288
- depthToFiles.set(depth - 1, [dirname]);
1289
- }
1290
- else {
1291
- depthToFiles.get(depth - 1).push(dirname);
1292
- }
1293
- const thisDepth = depthToFiles.get(depth);
1294
- depthToFiles.set(depth, thisDepth.filter(file => filesInDir.every(fileInDir => path.join(dirname, fileInDir) !== file)));
1295
- }
1296
- }
1297
- }
1298
- pkg.files = [...new Set(Array.from(depthToFiles.values()).flat())];
1299
- pkg.files = pkg.files.filter(file => {
1300
- const fileNormalized = normalizePath(file);
1301
- const dirname = path.dirname(fileNormalized);
1302
- const basenameWithoutExtension = path.basename(fileNormalized, path.extname(fileNormalized)).toUpperCase();
1303
- return !filterFiles.includes(fileNormalized) && (dirname !== '' && dirname !== '.' || !specialFiles.includes(basenameWithoutExtension));
1304
- });
1305
- const ignoreDirs = [];
1306
- for (const fileOrDir of pkg.files) {
1307
- if (await isDirectory(fileOrDir)) {
1308
- const allFiles = await walkDir(fileOrDir);
1309
- if (allFiles.every(file => {
1310
- const fileNormalized = normalizePath(file);
1311
- return filterFiles.includes(fileNormalized);
1312
- })) {
1313
- ignoreDirs.push(fileOrDir);
1314
- }
1315
- }
1316
- }
1317
- pkg.files = pkg.files.filter(dir => !ignoreDirs.includes(dir));
1318
- if (pkg.files.length === 0) {
1319
- pkg.files = undefined;
1320
- }
1321
- }
1322
- }
1323
- async function flatten(pkg, flatten, logger) {
1324
- const { default: jsonata } = await import('jsonata');
1325
- // find out where is the dist folder
1326
- const expression = jsonata('[bin, bin.*, main, module, unpkg, umd, types, typings, exports[].*.*, typesVersions.*.*, directories.bin]');
1327
- const allReferences = (await expression.evaluate(pkg));
1328
- let distDir;
1329
- // at this point we requested directories.bin, but it is the only one that is directory and not a file
1330
- // later when we get dirname we can't flatten directories.bin completely
1331
- // it is easy to fix by checking element is a directory but it is kind of good
1332
- // to have it as a separate directory, but user still can flatten it by specifying the directory
1333
- if (flatten === true) {
1334
- let commonSegments;
1335
- for (const entry of allReferences) {
1336
- if (typeof entry !== 'string') {
1337
- continue;
1338
- }
1339
- const dirname = path.dirname(entry);
1340
- const cleanedSegments = dirname.split('/').filter(path => path && path !== '.');
1341
- if (!commonSegments) {
1342
- commonSegments = cleanedSegments;
1343
- }
1344
- else {
1345
- for (let i = 0; i < commonSegments.length; ++i) {
1346
- if (commonSegments[i] !== cleanedSegments[i]) {
1347
- commonSegments.length = i;
1348
- break;
1349
- }
1350
- }
1351
- }
1352
- }
1353
- distDir = commonSegments?.join('/');
1354
- }
1355
- else {
1356
- distDir = normalizePath(flatten);
1357
- }
1358
- if (!distDir) {
1359
- throw new Error('could not find dist folder');
1360
- }
1361
- logger.update(`flattening ${distDir}...`);
1362
- // check if dist can be flattened
1363
- const relativeDistDir = `./${distDir}`;
1364
- const existsPromises = [];
1365
- const filesInDist = await walkDir(relativeDistDir);
1366
- for (const file of filesInDist) {
1367
- // check file is not in root dir
1368
- const relativePath = path.relative(relativeDistDir, file);
1369
- existsPromises.push(isExists(relativePath));
1370
- }
1371
- const exists = await Promise.all(existsPromises);
1372
- const filesAlreadyExist = exists.filter(Boolean);
1373
- if (filesAlreadyExist.length) {
1374
- throw new Error(`dist folder cannot be flattened because files already exist: ${filesAlreadyExist.join(', ')}`);
1375
- }
1376
- if (typeof flatten === 'string' && 'directories' in pkg && pkg.directories != null
1377
- && typeof pkg.directories === 'object' && 'bin' in pkg.directories
1378
- && typeof pkg.directories.bin === 'string' && normalizePath(pkg.directories.bin) === normalizePath(flatten)) {
1379
- // biome-ignore lint/performance/noDelete: <explanation>
1380
- delete pkg.directories.bin;
1381
- if (Object.keys(pkg.directories).length === 0) {
1382
- pkg.directories = undefined;
1383
- }
1384
- const files = await readdir(flatten);
1385
- if (files.length === 1) {
1386
- pkg.bin = files[0];
1387
- }
1388
- else {
1389
- pkg.bin = {};
1390
- for (const file of files) {
1391
- pkg.bin[path.basename(file, path.extname(file))] = file;
1392
- }
1393
- }
1394
- }
1395
- // create new directory structure
1396
- const mkdirPromises = [];
1397
- for (const file of filesInDist) {
1398
- // check file is not in root dir
1399
- const relativePath = path.relative(relativeDistDir, file);
1400
- mkdirPromises.push(mkdir(path.dirname(relativePath), { recursive: true }));
1401
- }
1402
- await Promise.all(mkdirPromises);
1403
- // move files to root dir (rename)
1404
- const renamePromises = [];
1405
- const newFiles = [];
1406
- for (const file of filesInDist) {
1407
- // check file is not in root dir
1408
- const relativePath = path.relative(relativeDistDir, file);
1409
- newFiles.push(relativePath);
1410
- renamePromises.push(rename(file, relativePath));
1411
- }
1412
- await Promise.all(renamePromises);
1413
- let cleanedDir = relativeDistDir;
1414
- while (await isEmptyDir(cleanedDir)) {
1415
- await rm(cleanedDir, { recursive: true, force: true });
1416
- const parentDir = path.dirname(cleanedDir);
1417
- if (parentDir === '.') {
1418
- break;
1419
- }
1420
- cleanedDir = parentDir;
1421
- }
1422
- const normalizedCleanDir = normalizePath(cleanedDir);
1423
- const allReferencesSet = new Set(allReferences);
1424
- // update package.json
1425
- const stringToReplace = `${distDir}/`; // we append / to remove in from the middle of the string
1426
- const pkgClone = cloneAndUpdate(pkg, value => allReferencesSet.has(value) ? value.replace(stringToReplace, '') : value);
1427
- Object.assign(pkg, pkgClone);
1428
- // update files
1429
- let files = pkg.files;
1430
- if (files) {
1431
- files = files.filter(file => {
1432
- const fileNormalized = normalizePath(file);
1433
- return !isSubDirectory(cleanedDir, fileNormalized) && fileNormalized !== normalizedCleanDir;
1434
- });
1435
- files.push(...newFiles);
1436
- pkg.files = [...files];
1437
- }
1438
- // remove extra directories with package.json
1439
- const exports = pkg.exports ? Object.keys(pkg.exports) : [];
1440
- for (const key of exports) {
1441
- if (key === '.') {
1442
- continue;
1443
- }
1444
- const isDir = await isDirectory(key);
1445
- if (isDir) {
1446
- const pkgPath = path.join(key, 'package.json');
1447
- const pkgExists = await isExists(pkgPath);
1448
- // ensure nothing else is in the directory
1449
- const files = await readdir(key);
1450
- if (files.length === 1 && pkgExists) {
1451
- await rm(key, { recursive: true, force: true });
1452
- }
1453
- }
1454
- }
1455
- }
1456
- function normalizePath(file) {
1457
- let fileNormalized = path.normalize(file);
1458
- if (fileNormalized.endsWith('/') || fileNormalized.endsWith('\\')) {
1459
- // remove trailing slash
1460
- fileNormalized = fileNormalized.slice(0, -1);
1461
- }
1462
- return fileNormalized;
1463
- }
1464
- function cloneAndUpdate(pkg, updater) {
1465
- if (typeof pkg === 'string') {
1466
- return updater(pkg);
1467
- }
1468
- if (Array.isArray(pkg)) {
1469
- return pkg.map(value => cloneAndUpdate(value, updater));
1470
- }
1471
- if (typeof pkg === 'object' && pkg !== null) {
1472
- const clone = {};
1473
- for (const key of Object.keys(pkg)) {
1474
- clone[key] = cloneAndUpdate(pkg[key], updater);
1475
- }
1476
- return clone;
1477
- }
1478
- return pkg;
1479
- }
1480
- function isSubDirectory(parent, child) {
1481
- return path.relative(child, parent).startsWith('..');
1482
- }
1483
- async function isEmptyDir(dir) {
1484
- const entries = await readdir(dir, { withFileTypes: true });
1485
- return entries.filter(entry => !entry.isDirectory()).length === 0;
1486
- }
1487
- async function isDirectory(file) {
1488
- const fileStat = await stat(file);
1489
- return fileStat.isDirectory();
1490
- }
1491
- async function walkDir(dir, ignoreDirs = []) {
1492
- const entries = await readdir(dir, { withFileTypes: true });
1493
- const files = [];
1494
- await Promise.all(entries.map(entry => {
1495
- const childPath = path.join(dir, entry.name);
1496
- if (entry.isDirectory() && !ignoreDirs.includes(entry.name)) {
1497
- return walkDir(childPath)
1498
- .then(childFiles => {
1499
- files.push(...childFiles);
1500
- });
1501
- }
1502
- files.push(childPath);
1503
- }).filter(Boolean));
1504
- return files;
1505
- }
1506
- function getScriptsData() {
1507
- const libraryScripts = new Set([
1508
- 'preinstall',
1509
- 'install',
1510
- 'postinstall',
1511
- 'prepublish',
1512
- 'preprepare',
1513
- 'prepare',
1514
- 'postprepare'
1515
- ]);
1516
- const appScripts = new Set([
1517
- ...libraryScripts,
1518
- 'prestart',
1519
- 'start',
1520
- 'poststart',
1521
- 'prerestart',
1522
- 'restart',
1523
- 'postrestart',
1524
- 'prestop',
1525
- 'stop',
1526
- 'poststop',
1527
- 'pretest',
1528
- 'test',
1529
- 'posttest'
1530
- ]);
1531
- return {
1532
- library: libraryScripts,
1533
- app: appScripts
1534
- };
1535
- }
1536
-
1537
- // eslint-disable-next-line @typescript-eslint/triple-slash-reference
1538
- /// <reference path="./rollup-plugin-preprocess.d.ts" />
1539
- execute();
1540
- async function execute() {
1541
- const time = Date.now();
1542
- const mainLogger = createLogger();
1543
- mainLogger.update('preparing..');
1544
- try {
1545
- let pkg;
1546
- let pkgPath;
1547
- // eslint-disable-next-line prefer-const
1548
- [pkgPath, pkg] = await getJson('package.json');
1549
- const loadedPlugins = new Set;
1550
- const plugins = await loadPlugins(pkg, loadedPlugins);
1551
- const [rootPackagePath, rootPkg] = await getJson(join(await searchForWorkspaceRoot(dirname(pkgPath)), 'package.json'));
1552
- if (rootPackagePath !== pkgPath) {
1553
- plugins.push(...await loadPlugins(rootPkg, loadedPlugins));
1554
- }
1555
- mainLogger.update('');
1556
- process.stdout.moveCursor?.(0, -1);
1557
- const options = getCliOptions(plugins, pkg);
1558
- if (options.kind === 'prune') {
1559
- await prunePkg(pkg, options, mainLogger);
1560
- await writeJson(pkgPath, pkg);
1561
- process.exit(0);
1562
- }
1563
- process.stdout.moveCursor?.(0, 1);
1564
- mainLogger.update('preparing...');
1565
- const tsConfig = await checkTsConfig(options, mainLogger, plugins);
1566
- const [inputs, inputsExt] = await processPackage(pkg, options, plugins, tsConfig);
1567
- if (options.formatPackageJson) {
1568
- pkg = formatPackageJson(pkg);
1569
- }
1570
- const helpers = getHelpers(pkg.name);
1571
- const preimportMap = preimport();
1572
- const provider = options.eject ? await createEjectProvider(preimportMap) : createProvider(preimportMap);
1573
- const rollupConfigs = await getRollupConfigs(provider, inputs, inputsExt, options, helpers, plugins);
1574
- if (options.noBundle) {
1575
- rollupConfigs.length = 0;
1576
- }
1577
- if (options.eject) {
1578
- await ejectConfig(rollupConfigs, pkgPath, options, inputs, inputsExt, helpers, pkg);
1579
- mainLogger.finish(`ejected config in ${getTimeDiff(time)}`);
1580
- if (!options.noUpdatePackageJson) {
1581
- await writeJson(pkgPath, pkg);
1582
- }
1583
- }
1584
- else {
1585
- const updater = mainLoggerText(options.sourceDir, options.dir, rollupConfigs.length, time);
1586
- mainLogger.start(updater());
1587
- await Promise.all(rollupConfigs.map(config => buildConfig(config, updater)));
1588
- if (!options.noUpdatePackageJson) {
1589
- await writeJson(pkgPath, pkg);
1590
- }
1591
- await createSubpackages(inputs, options);
1592
- await Promise.all(plugins
1593
- .filter(plugin => plugin.buildEnd)
1594
- .map(plugin => plugin.buildEnd()));
1595
- mainLogger.finish(updater(true));
1596
- }
1597
- }
1598
- catch (e) {
1599
- mainLogger.finish(String(e), 3 /* LogLevel.error */);
1600
- process.exit(-1);
1601
- }
1602
- async function buildConfig(config, updater) {
1603
- const bundle = await rollup(config);
1604
- await Promise.all(toArray(config.output).map(config => bundle.write(config)));
1605
- await bundle.close();
1606
- mainLogger(`${kleur.green('✓')} ${formatInput(config.input)} [${formatOutput(config.output, 'format')}]`);
1607
- mainLogger.update(updater());
1608
- }
1609
- }
1610
- function preimport() {
1611
- return (process.env.PKGBLD_INTERNAL ? new Map([
1612
- ['@rollup-extras/plugin-binify', import('@rollup-extras/plugin-binify')],
1613
- ['@rollup-extras/plugin-clean', import('@rollup-extras/plugin-clean')],
1614
- ['@rollup-extras/plugin-externals', import('@rollup-extras/plugin-externals')]
1615
- ]) : new Map);
1616
- }
1617
- process.on('exit', () => { });