@mirta/rollup 0.3.4 → 0.3.5

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 CHANGED
@@ -1,514 +1,19 @@
1
- import ts from '@rollup/plugin-typescript';
2
- import nodeResolve from '@rollup/plugin-node-resolve';
3
- import commonjs from '@rollup/plugin-commonjs';
4
- import replace from '@rollup/plugin-replace';
5
- import dts from 'rollup-plugin-dts';
6
- import { deleteAsync } from 'del';
7
- import nodePath from 'node:path';
8
- import { readFileSync } from 'fs';
9
- import multi from '@rollup/plugin-multi-entry';
10
- import ts$1 from 'rollup-plugin-typescript2';
11
- import dotenv from '@dotenv-run/rollup';
12
- import { getBabelOutputPlugin } from '@rollup/plugin-babel';
13
- import path from 'path';
14
- import MagicString from 'magic-string';
15
-
16
- function del(options = {}) {
17
- const { hook = 'buildStart', runOnce = false, targets = [], verbose = false, } = options;
18
- let isDeleted = false;
19
- return {
20
- name: 'del',
21
- [hook]: async () => {
22
- if (runOnce && isDeleted)
23
- return;
24
- const paths = await deleteAsync(targets, options);
25
- if (verbose || options.dryRun) {
26
- const message = options.dryRun
27
- ? `Expected files and folders to be deleted: ${paths.length.toString()}`
28
- : `Deleted files and folders: ${paths.length.toString()}`;
29
- console.log(message);
30
- if (paths.length)
31
- paths.forEach((path) => {
32
- console.log(path);
33
- });
34
- }
35
- isDeleted = true;
36
- },
37
- };
38
- }
39
-
40
- class BuildError extends Error {
41
- constructor(message) {
42
- super(message);
43
- // Убедимся, что экземпляр имеет правильный прототип
44
- Object.setPrototypeOf(this, BuildError.prototype);
45
- this.name = 'BuildError';
46
- this.message = message;
47
- Error.captureStackTrace(this, BuildError);
48
- }
49
- }
50
- const dtsOutputDir = 'dist/dts';
51
- function normalizeInput(input) {
52
- const inputs = [];
53
- // Нормализация входных данных.
54
- // Строка, массив или объект преобразуются в единый массив строк inputs.
55
- if (typeof input === 'string') {
56
- inputs.push(input);
57
- }
58
- else if (Array.isArray(input)) {
59
- inputs.push(...input);
60
- }
61
- else if (typeof input === 'object') {
62
- inputs.push(...Object.values(input));
63
- }
64
- if (inputs.length === 0)
65
- throw new BuildError('[Mirta Rollup] Input configuration cannot be empty');
66
- return inputs;
67
- }
68
- /**
69
- * Связывает исходные файлы проекта (`src/...`) с точками входа,
70
- * определенными в `package.exports`. Ее основная цель — создать
71
- * отображение между входными файлами (например, `src/index.ts`)
72
- * и их выходными файлами (например, `dist/index.js`), а также источниками типов (`.d.ts`).
73
- *
74
- * @param inputs Массив путей к исходным файлам (например, `['src/index.ts', 'src/utils.ts']`)
75
- * @param exports Объект из `package.exports`, описывающий точки входа пакета.
76
- *
77
- **/
78
- function getInputBindings(inputs, exports) {
79
- if (!inputs.length || !exports)
80
- return {};
81
- const candidates = {};
82
- for (const [key, value] of Object.entries(exports)) {
83
- if (!value.import?.default || !key.startsWith('.'))
84
- continue;
85
- // Формируем outputFile на основе данных package.json,
86
- // убирая префикс `dist/` из путей, так как он
87
- // уже указан в настройках сборки (output.dir).
88
- //
89
- const outputFile = value.import.default.startsWith('./dist/')
90
- ? value.import.default.slice(7)
91
- : value.import.default;
92
- const source = key === '.' ? 'index' : key.slice(2);
93
- // Генерация кандидатов для входных файлов.
94
- //
95
- // Для каждого ключа экспорта создает возможные пути
96
- // к исходным файлам (например, `src/utils.ts` и `src/utils/index.ts`),
97
- // учитывая как явные, так и неявные структуры каталогов.
98
- Object.assign(candidates, {
99
- // Варианты явного пути (например, `src/setup.ts`)
100
- [`src/${source}.ts`]: { key, outputFile, dtsSource: source },
101
- [`src/${source}.js`]: { key, outputFile, dtsSource: source },
102
- // Варианты неявного пути (например, `src/setup/index.ts`):
103
- [`src/${source}/index.ts`]: { key, outputFile, dtsSource: `${source}/index` },
104
- [`src/${source}/index.js`]: { key, outputFile, dtsSource: `${source}/index` },
105
- });
106
- }
107
- const result = {};
108
- // Сопоставление с реальными входными файлами.
109
- //
110
- // Ппроверяет, какие из сгенерированных путей действительно существуют в массиве inputs.
111
- //
112
- for (const input of inputs) {
113
- const entry = candidates[input];
114
- // Если точка входа не ассоциирована с конфигурацией `package.json` — выбрасываем ошибку и прерываем сборку.
115
- if (!entry)
116
- throw new BuildError(`[Mirta Rollup] The input file "${input}" is not associated with corresponding export in the package.json`);
117
- // Формирует итоговый объект result, где ключи — это точки входа из package.exports,
118
- // а значения — связи между исходными файлами, выходными файлами и источниками типов.
119
- //
120
- result[entry.key] = {
121
- sourceFile: input,
122
- outputFile: entry.outputFile,
123
- dtsSource: entry.dtsSource,
124
- };
125
- }
126
- for (const [key, value] of Object.entries(exports)) {
127
- if ((!value.import?.default && value.import?.types))
128
- continue;
129
- if (!(key in result))
130
- throw new BuildError(`[Mirta Rollup] Export "${key}" defined in package.json has no corresponding input file in Rollup configuration`);
131
- }
132
- return result;
133
- }
134
- /**
135
- * Создаёт отображение между файлами типов `.d.ts` и их выходными путями
136
- * на основе данных из `package.exports` и ранее сформированных связей ({@link inputBindings})
137
- *
138
- * @param inputBindings
139
- * @param exports
140
- * @returns
141
- */
142
- function getDtsMappings(inputBindings, exports) {
143
- if (!exports)
144
- return {};
145
- const result = {};
146
- // Для каждой точки входа из package.exports
147
- //
148
- for (const [key, value] of Object.entries(exports)) {
149
- // Где указан import.types
150
- //
151
- if (!value.import?.types || !key.startsWith('.'))
152
- continue;
153
- // Определяет путь к выходному файлу типов, убирая префикс `./dist/`
154
- //
155
- const outputFile = value.import.types.startsWith('./dist/')
156
- ? value.import.types.slice(7)
157
- : value.import.types;
158
- const binding = inputBindings[key];
159
- // Если для указанного ключа отсутствует точка входа — выбрасываем ошибку и прерываем сборку.
160
- if (!binding)
161
- throw new BuildError(`[Mirta Rollup] Type definition "${outputFile}" has no corresponding input file`);
162
- // Связывает с исходным файлом типов.
163
- //
164
- const dtsSource = binding.dtsSource;
165
- result[`${dtsOutputDir}/${dtsSource}.d.ts`] = outputFile;
166
- }
167
- return result;
168
- }
169
- // Проверка TypeScript выполняется только для первой конфигурации.
170
- let hasTsChecked = false;
171
- function definePackageConfig(options) {
172
- const { cwd = process.cwd(), input = 'src/index.ts', external = [], plugins, } = options;
173
- const pkgPath = nodePath.resolve(cwd, 'package.json');
174
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
175
- const { exports = {} } = pkg;
176
- const externalModules = [
177
- /node_modules/,
178
- pkgPath,
179
- ...external,
180
- ];
181
- const inputBindings = getInputBindings(normalizeInput(input), exports);
182
- const outputMappings = Object.keys(inputBindings)
183
- .reduce((mappings, nextKey) => {
184
- const inputMap = inputBindings[nextKey];
185
- mappings[inputMap.sourceFile] = inputMap.outputFile;
186
- return mappings;
187
- }, {});
188
- const dtsMappings = getDtsMappings(inputBindings, exports);
189
- const dtsInputs = Object.keys(dtsMappings);
190
- const rollupConfigs = [
191
- createBuildConfig('mjs', {
192
- cwd,
193
- input,
194
- external: externalModules,
195
- emitDeclarations: dtsInputs.length > 0,
196
- plugins,
197
- output: {
198
- dir: 'dist/',
199
- format: 'es',
200
- importAttributesKey: 'with',
201
- entryFileNames(chunk) {
202
- if (chunk.facadeModuleId) {
203
- const localPath = nodePath
204
- .relative(cwd, chunk.facadeModuleId)
205
- .replaceAll(nodePath.sep, nodePath.posix.sep);
206
- if (outputMappings[localPath])
207
- return outputMappings[localPath];
208
- }
209
- return `${chunk.name}.mjs`;
210
- },
211
- chunkFileNames: '[name].mjs',
212
- },
213
- }),
214
- ];
215
- if (dtsInputs.length > 0) {
216
- rollupConfigs.push({
217
- input: dtsInputs,
218
- external: externalModules,
219
- plugins: [
220
- nodeResolve(),
221
- commonjs(),
222
- dts(),
223
- del({
224
- targets: [dtsOutputDir],
225
- hook: 'closeBundle',
226
- }),
227
- ],
228
- output: {
229
- dir: 'dist/',
230
- format: 'es',
231
- entryFileNames(chunk) {
232
- if (chunk.facadeModuleId) {
233
- const localPath = nodePath
234
- .relative(cwd, chunk.facadeModuleId)
235
- .replaceAll(nodePath.sep, nodePath.posix.sep);
236
- if (dtsMappings[localPath])
237
- return dtsMappings[localPath];
238
- }
239
- return `${chunk.name}.mts`;
240
- },
241
- },
242
- });
243
- }
244
- return rollupConfigs;
245
- }
246
- function createBuildConfig(buildName, options) {
247
- const { cwd, external, input, emitDeclarations, plugins = [], output } = options;
248
- output.sourcemap = !!process.env.SOURCE_MAP;
249
- output.externalLiveBindings = false;
250
- process.env.NODE_ENV === 'production';
251
- const tsPlugin = ts({
252
- tsconfig: nodePath.resolve(cwd, './tsconfig.build.json'),
253
- compilerOptions: {
254
- noCheck: hasTsChecked,
255
- declaration: emitDeclarations,
256
- declarationDir: emitDeclarations ? dtsOutputDir : void 0,
257
- },
258
- exclude: [
259
- 'packages/*/tests',
260
- ],
261
- });
262
- // При запуске команды build, проверки TS и генерация определений
263
- // выполняются единожды - для первой конфигурации.
264
- hasTsChecked = true;
265
- return {
266
- input,
267
- external,
268
- plugins: [
269
- tsPlugin,
270
- createReplacePlugin(),
271
- nodeResolve(),
272
- commonjs(),
273
- ...plugins,
274
- // copy({
275
- // targets: [
276
- // { src: 'public/*', dest: 'dist' },
277
- // ],
278
- // }),
279
- ],
280
- output,
281
- };
282
- }
283
- function createReplacePlugin(isProduction, isBundlerEsmBuild, isNodeBuild) {
284
- const replacements = {
285
- // Preserve to be handled by bundlers
286
- __DEV__: `(process.env.NODE_ENV !== 'production')`
287
- ,
288
- __TEST__: `(process.env.NODE_ENV === 'test')`
289
- ,
290
- };
291
- // Allow inline overrides like
292
- // __DEV__=true pnpm build
293
- Object.keys(replacements).forEach((key) => {
294
- if (key in process.env)
295
- replacements[key] = process.env[key];
296
- });
297
- return replace({
298
- preventAssignment: true,
299
- values: replacements,
300
- delimiters: ['\\b', '\\b(?![\\.\\:])'],
301
- });
302
- }
303
-
304
- // Абсолютный путь к результирующему каталогу.
305
- const outputDir$1 = path.join(process.cwd(), 'dist');
306
- const modulesDir = path.join(outputDir$1, 'wb-rules-modules');
307
- // Расположение обрабатываемого чанка.
308
- const getChunkDir = (fileName) => path.dirname(path.join(outputDir$1, fileName));
309
- // Шаблон для отлова конструкций require.
310
- const patternRequire = /require\(['"]([^'"]+)'\)/g;
311
- /**
312
- * Плагин Rollup, перестраивающий пути импорта модулей
313
- * относительно каталога wb-rules-modules.
314
- * */
315
- function wbRulesImports() {
316
- return {
317
- name: 'wbRulesImports',
318
- // Выполняется перед записью содержимого
319
- // в результирующий файл.
320
- renderChunk(code, chunk) {
321
- // Виртуальный каталог не обрабатываем.
322
- if (chunk.fileName.startsWith('_virtual'))
323
- return;
324
- const magicString = new MagicString(code);
325
- let hasReplacements = false;
326
- let start;
327
- let end;
328
- const chunkDir = getChunkDir(chunk.fileName);
329
- // Преобразует путь подключения модуля в формат,
330
- // поддерживаемый контроллером Wirenboard.
331
- function rebaseRequire(match) {
332
- // Начальная позиция оригинального вхождения
333
- start = match.index;
334
- // Конечная позиция оригинального вхождения
335
- end = start + match[0].length;
336
- // Преобразует путь подключаемого модуля в абсолютный,
337
- // опираясь на каталог с текущим обрабатываемым файлом.
338
- const requireAbsolutePath = path.resolve(chunkDir, match[1]);
339
- // Если абсолютный путь начинается с каталога модулей...
340
- if (requireAbsolutePath.startsWith(modulesDir)) {
341
- const parsed = path.parse(path.relative(modulesDir, requireAbsolutePath));
342
- const rebased = path
343
- .join(parsed.dir, parsed.name)
344
- .replaceAll(path.sep, path.posix.sep);
345
- // Удаляет расширение файла для полного соответствия
346
- // принципам импорта модулей wb-rules.
347
- const replacement = match[0]
348
- .replace(match[1], rebased);
349
- magicString.overwrite(start, end, replacement);
350
- // Признак произведённой замены.
351
- return true;
352
- }
353
- }
354
- // Строит полный список конструкций require
355
- // в обрабатываемом файле.
356
- const matches = [...code.matchAll(patternRequire)];
357
- for (const match of matches) {
358
- if (rebaseRequire(match))
359
- hasReplacements = true;
360
- }
361
- // Если никаких замен не было, то файл пропускается.
362
- if (!hasReplacements)
363
- return null;
364
- return {
365
- code: magicString.toString(),
366
- };
367
- },
368
- };
369
- }
370
-
371
- const env = process.env.NODE_ENV;
372
- const isProduction = env === 'production';
373
- const packagesPattern = /(.*)node_modules[\\/]@?(.+)[\\/](.+)?/;
374
- const modulesPattern = /(?:src[\\/])?wb-rules-modules[\\/](.*)/;
375
- const scriptsPattern = /(?:src[\\/])?(?:wb-rules[\\/])?(.*)/;
376
- const outputDir = {
377
- es5: 'dist/es5',
378
- };
379
- function globRelative(path, pattern) {
380
- const pathParts = path.split('/');
381
- const patternParts = pattern.split('/');
382
- let i = 0; // Индекс текущего компонента пути.
383
- for (let j = 0; j < patternParts.length && i < pathParts.length; j++) {
384
- switch (patternParts[j]) {
385
- case '*':
386
- break;
387
- case '**':
388
- while (i < pathParts.length && !pathParts[i].startsWith(patternParts[j + 1])) {
389
- i += 1; // Пропускаем все элементы пути до следующего элемента шаблона.
390
- }
391
- break;
392
- default:
393
- if (patternParts[j] === pathParts[i]) {
394
- i += 1;
395
- }
396
- else {
397
- return void 0; // Несоответствие фиксированного значения.
398
- }
399
- }
400
- }
401
- return pathParts.slice(i).join('/');
402
- }
403
- function tryGetPackageEntry(sourcePath) {
404
- const pathParts = [];
405
- do {
406
- const match = packagesPattern.exec(sourcePath);
407
- if (!match)
408
- break;
409
- if (match[3])
410
- pathParts.unshift(match[3]);
411
- pathParts.unshift('packages/' + match[2].replace(/\/dist$/, ''));
412
- sourcePath = match[1];
413
- } while (sourcePath);
414
- if (pathParts.length)
415
- return `wb-rules-modules/${pathParts.join('/')}.js`;
416
- }
417
- function tryGetModuleEntry(sourcePath) {
418
- const match = modulesPattern.exec(sourcePath);
419
- if (!match)
420
- return;
421
- // if ((process.env.NODE_ENV !== 'production'))
422
- // console.debug(`Module Entry: ${entry}`)
423
- return `wb-rules-modules/${match[1]}.js`;
424
- }
425
- function tryGetScriptEntry(sourcePath) {
426
- const match = scriptsPattern.exec(sourcePath);
427
- if (!match)
428
- return;
429
- // if ((process.env.NODE_ENV !== 'production'))
430
- // console.debug(`Script Entry: ${entry}`)
431
- return `wb-rules/${match[1]}.js`;
432
- }
433
- function getEntry(path) {
434
- if (path.startsWith('_virtual'))
435
- return path;
436
- return tryGetPackageEntry(path) ?? tryGetModuleEntry(path) ?? tryGetScriptEntry(path)
437
- // None of the above matched.
438
- ?? path;
439
- }
440
- function defineRuntimeConfig(options = {}) {
441
- const { cwd = process.cwd(), external, monorepo, dotenv: dotenvOptions = {}, plugins = [], } = options;
442
- const defaultPlugins = [
443
- del({
444
- targets: 'dist/*',
445
- }),
446
- multi({
447
- exclude: ['src/wb-rules/*.disabled.[jt]s'],
448
- preserveModules: true,
449
- }),
450
- nodeResolve(),
451
- ts$1({
452
- clean: true,
453
- }),
454
- wbRulesImports(),
455
- dotenv(dotenvOptions),
456
- replace({
457
- preventAssignment: true,
458
- values: {
459
- __DEV__: JSON.stringify(!isProduction),
460
- // Автоматически меняется в процессе тестирования
461
- __TEST__: 'false',
462
- },
463
- }),
464
- getBabelOutputPlugin({
465
- presets: ['@babel/preset-env'],
466
- plugins: [
467
- '@babel/plugin-transform-spread',
468
- 'array-includes',
469
- ],
470
- }),
471
- del({
472
- targets: 'dist/*/_virtual',
473
- hook: 'closeBundle',
474
- }),
475
- ];
476
- return {
477
- input: 'src/wb-rules/*.[jt]s',
478
- external,
479
- plugins: [
480
- ...defaultPlugins,
481
- ...plugins,
482
- ],
483
- output: {
484
- format: 'cjs',
485
- strict: false,
486
- dir: outputDir.es5,
487
- preserveModules: true,
488
- entryFileNames(chunkInfo) {
489
- let chunkName = chunkInfo.name;
490
- if (monorepo) {
491
- const { rootDir, workspaces } = monorepo;
492
- const absolutePath = nodePath.resolve(rootDir, chunkInfo.name);
493
- if (absolutePath.startsWith(cwd)) {
494
- chunkName = nodePath
495
- .relative(cwd, absolutePath);
496
- }
497
- else {
498
- for (const workspace of workspaces) {
499
- const maybeChunkName = globRelative(chunkName, workspace);
500
- if (maybeChunkName) {
501
- // Обманка для упрощённого встраивания в packages.
502
- chunkName = 'node_modules/' + maybeChunkName;
503
- break;
504
- }
505
- }
506
- }
507
- }
508
- return getEntry(chunkName);
509
- },
510
- },
511
- };
512
- }
513
-
514
- export { defineRuntimeConfig as defineConfig, definePackageConfig };
1
+ export { a as defineConfig, d as definePackageConfig } from './runtime.mjs';
2
+ import '@rollup/plugin-typescript';
3
+ import '@rollup/plugin-node-resolve';
4
+ import '@rollup/plugin-commonjs';
5
+ import '@rollup/plugin-replace';
6
+ import 'rollup-plugin-copy';
7
+ import 'rollup-plugin-dts';
8
+ import 'typescript';
9
+ import 'node:path';
10
+ import '@rollup/plugin-multi-entry';
11
+ import 'rollup-plugin-typescript2';
12
+ import '@dotenv-run/rollup';
13
+ import '@rollup/plugin-babel';
14
+ import 'del';
15
+ import 'path';
16
+ import 'magic-string';
17
+ import '@pnpm/find-workspace-dir';
18
+ import '@pnpm/workspace.find-packages';
19
+ import 'fs';