@reformer/builder-plugin-cli 1.0.0-beta.1

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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -0
  3. package/dist/cli.d.ts +26 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +207 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/build.d.ts +57 -0
  8. package/dist/commands/build.d.ts.map +1 -0
  9. package/dist/commands/build.js +261 -0
  10. package/dist/commands/build.js.map +1 -0
  11. package/dist/commands/create.d.ts +31 -0
  12. package/dist/commands/create.d.ts.map +1 -0
  13. package/dist/commands/create.js +43 -0
  14. package/dist/commands/create.js.map +1 -0
  15. package/dist/commands/dev.d.ts +35 -0
  16. package/dist/commands/dev.d.ts.map +1 -0
  17. package/dist/commands/dev.js +79 -0
  18. package/dist/commands/dev.js.map +1 -0
  19. package/dist/commands/dry-run.d.ts +38 -0
  20. package/dist/commands/dry-run.d.ts.map +1 -0
  21. package/dist/commands/dry-run.js +148 -0
  22. package/dist/commands/dry-run.js.map +1 -0
  23. package/dist/commands/findings.d.ts +31 -0
  24. package/dist/commands/findings.d.ts.map +1 -0
  25. package/dist/commands/findings.js +14 -0
  26. package/dist/commands/findings.js.map +1 -0
  27. package/dist/commands/pack.d.ts +33 -0
  28. package/dist/commands/pack.d.ts.map +1 -0
  29. package/dist/commands/pack.js +78 -0
  30. package/dist/commands/pack.js.map +1 -0
  31. package/dist/commands/template.d.ts +34 -0
  32. package/dist/commands/template.d.ts.map +1 -0
  33. package/dist/commands/template.js +109 -0
  34. package/dist/commands/template.js.map +1 -0
  35. package/dist/commands/validate.d.ts +43 -0
  36. package/dist/commands/validate.d.ts.map +1 -0
  37. package/dist/commands/validate.js +128 -0
  38. package/dist/commands/validate.js.map +1 -0
  39. package/dist/index.d.ts +12 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +11 -0
  42. package/dist/index.js.map +1 -0
  43. package/package.json +58 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Alexandr Bukhtatyy
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # @reformer/builder-plugin-cli
2
+
3
+ `reformer-plugin` — командная строка автора плагина ReFormer Builder: создать плагин из шаблона,
4
+ проверить и собрать его **теми же правилами, которыми его проверит оболочка**, разрабатывать
5
+ прямо в открытом проекте и упаковать для npm.
6
+
7
+ ```bash
8
+ npx @reformer/builder-plugin-cli create acme-forms --name "Acme Forms"
9
+ cd acme-forms && npm install
10
+ npx reformer-plugin validate
11
+ npx reformer-plugin dev --project ../my-builder-project
12
+ npx reformer-plugin pack
13
+ ```
14
+
15
+ Нужен Node 20 или новее (`dev` наблюдает за каталогом рекурсивно).
16
+
17
+ ## Команды
18
+
19
+ ### `create <каталог> [--id <id>] [--name <имя>]`
20
+
21
+ Кладёт в пустой (или несуществующий) каталог готовый плагин:
22
+
23
+ | Файл | Что это |
24
+ | ------------------------------- | ----------------------------------------------------------------------------- |
25
+ | `manifest.json` | манифест исходников: `main` → `src/main.ts`, словари объявлены |
26
+ | `src/main.ts` | плагин с одной командой, подпись которой берётся из словаря |
27
+ | `src/main.test.ts` | `id` кода совпадает с `id` манифеста — иначе оболочка откажет (`id-mismatch`) |
28
+ | `locales/ru.json`, `en.json` | плоские словари «ключ → строка» |
29
+ | `package.json`, `tsconfig.json` | `@reformer/builder-plugin-api` в `devDependencies` |
30
+
31
+ Идентификатор по умолчанию — имя каталога. Годится ли он, решает разбор манифеста оболочки,
32
+ а не собственное правило CLI. В непустой каталог команда не пишет.
33
+
34
+ Созданный плагин можно положить в `.ui_builder/plugins/<id>/` проекта как есть: оболочка сама
35
+ транспилирует `src/main.ts`.
36
+
37
+ ### `validate [каталог]`
38
+
39
+ Код выхода `0` — оболочка плагин примет, `1` — нет, и почему именно, напечатано построчно.
40
+
41
+ - **манифест** — разбором из `@reformer/builder-plugin-api/tooling`, тем же, что у оболочки.
42
+ Отличий у исходников два: имя каталога с `id` не сверяется (репозиторий зовётся как угодно),
43
+ а `version` обязательна и должна быть версией — по ней публикуется пакет;
44
+ - **файлы, на которые ссылается манифест**: точка входа существует и это код, таблица стилей
45
+ существует, словари существуют и плоские. Эти отказы собираются все сразу;
46
+ - **версия `package.json`** совпадает с версией манифеста. Этого оболочка не проверяет —
47
+ `package.json` она не читает, — а расхождение означает пакет одной версии с плагином другой.
48
+
49
+ Коды отказов — коды оболочки (`manifest-invalid`, `api-version`, `entry-missing`,
50
+ `messages-invalid`, `provides-unregistered`…). Свои коды у CLI — для того, чего оболочка не видит:
51
+ `package-version`, `build-failed`, `module-unavailable`, `css-from-code`, `output-not-ours`,
52
+ `pack-failed`.
53
+
54
+ Соответствие `provides` регистрации и потолок числа файлов `validate` не проверяет: первое
55
+ требует исполнить код, второе относится к собранному каталогу. Обе проверки делает `build`.
56
+
57
+ ### `build [каталог] [--out <каталог>]`
58
+
59
+ Собирает каталог, который оболочка грузит как есть (по умолчанию `dist/`): `manifest.json`
60
+ с `main: "main.js"`, один `main.js`, `styles.css`, если стили объявлены, и словари по тем же путям.
61
+
62
+ - `main.js` — CommonJS: линковщик оболочки исполняет CommonJS, и готовый JS идёт у него без
63
+ транспиляции;
64
+ - модули, которые подставляет оболочка (`PLUGIN_RUNTIME_MODULES` контракта: React, `@reformer/*`,
65
+ сам контракт), остаются внешними. Импорт `@reformer/*` или `@builder/*` вне этого списка —
66
+ отказ `module-unavailable`: вложенная копия была бы вторым экземпляром пакета;
67
+ - импорт CSS из кода — отказ `css-from-code`: стили объявляются полем `styles` манифеста,
68
+ и только такую таблицу оболочка изолирует.
69
+
70
+ На выходе сборка проходит то, что пройдёт у оболочки: разбор манифеста поставки `project`, потолок
71
+ числа файлов кода и **«сухую» активацию** — `main.js` исполняется под Node с настоящим пакетом
72
+ контракта и заглушками остального. Так ловятся `not-a-plugin`, `id-mismatch` и
73
+ `provides-unregistered`. Если код падает на заглушке (например, `activate` трогает DOM), это
74
+ не отказ, а заметка `! … не проверено`: вне оболочки так ведут себя и рабочие плагины.
75
+
76
+ Каталог вывода очищается, только если он пуст или содержит сборку этого же плагина; иначе —
77
+ отказ `output-not-ours`. Не прошедшая проверки сборка прошлую не затирает.
78
+
79
+ ### `dev [каталог] --project <каталог проекта>`
80
+
81
+ Собирает в `<проект>/.ui_builder/plugins/<id>/` и пересобирает на каждое изменение исходников
82
+ (`node_modules`, `dist` и скрытые каталоги не наблюдаются). Перезагружает плагин оболочка:
83
+ отметьте его в списке плагинов «в разработке», и он перечитывается при возврате в окно билдера.
84
+
85
+ ### `pack [каталог] [--out <каталог>]`
86
+
87
+ Собирает во временный каталог и упаковывает `npm pack` в `<имя>-<версия>.tgz`. В архиве только
88
+ сборка и `package.json` (имя, описание, лицензия и ключевые слова из исходного, версия — из
89
+ манифеста, ключевое слово `reformer-builder-plugin` добавляется); исходников и зависимостей нет.
90
+
91
+ ## Программный вход
92
+
93
+ ```ts
94
+ import { buildPlugin } from '@reformer/builder-plugin-cli';
95
+
96
+ const result = await buildPlugin({ dir: './acme-forms', outDir: './out' });
97
+ if (!result.ok) console.log(result.findings);
98
+ ```
99
+
100
+ ## Лицензия
101
+
102
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `reformer-plugin` — точка входа командной строки.
4
+ *
5
+ * Разбор аргументов и печать отделены от процесса: {@link runCli} получает argv и куда писать,
6
+ * а возвращает код выхода. Так команды проверяются тестом целиком, без запуска дочернего
7
+ * процесса, а `process` трогает только последняя строка файла.
8
+ *
9
+ * @module @reformer/builder-plugin-cli/cli
10
+ */
11
+ import { type DevSession } from './commands/dev.js';
12
+ export interface CliIo {
13
+ readonly out: (line: string) => void;
14
+ readonly err: (line: string) => void;
15
+ /** Каталог, относительно которого читаются пути аргументов. */
16
+ readonly cwd: string;
17
+ /**
18
+ * Чем ждать конца `dev`: сеанс наблюдения живёт, пока его не закроют. Процесс ждёт сигнала,
19
+ * тест — закрывает сразу после первой сборки.
20
+ */
21
+ readonly waitDev?: (session: DevSession) => Promise<void>;
22
+ }
23
+ /** Версия CLI из его собственного package.json: `dist/cli.js` → `../package.json`. */
24
+ export declare function cliVersion(): string;
25
+ export declare function runCli(argv: readonly string[], io: CliIo): Promise<number>;
26
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;GAQG;AASH,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAK9D,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAeD,sFAAsF;AACtF,wBAAgB,UAAU,IAAI,MAAM,CAKnC;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CA8IhF"}
package/dist/cli.js ADDED
@@ -0,0 +1,207 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `reformer-plugin` — точка входа командной строки.
4
+ *
5
+ * Разбор аргументов и печать отделены от процесса: {@link runCli} получает argv и куда писать,
6
+ * а возвращает код выхода. Так команды проверяются тестом целиком, без запуска дочернего
7
+ * процесса, а `process` трогает только последняя строка файла.
8
+ *
9
+ * @module @reformer/builder-plugin-cli/cli
10
+ */
11
+ import { readFileSync, realpathSync } from 'node:fs';
12
+ import { resolve } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { parseArgs } from 'node:util';
15
+ import { buildPlugin } from './commands/build.js';
16
+ import { createPlugin } from './commands/create.js';
17
+ import { startDev } from './commands/dev.js';
18
+ import { formatFinding } from './commands/findings.js';
19
+ import { packPlugin } from './commands/pack.js';
20
+ import { validatePlugin } from './commands/validate.js';
21
+ const USAGE = `Использование: reformer-plugin <команда> [аргументы]
22
+
23
+ Команды:
24
+ create <каталог> [--id <id>] [--name <имя>] новый плагин из шаблона
25
+ validate [каталог] проверить плагин правилами оболочки
26
+ build [каталог] [--out <каталог>] собрать в каталог, который оболочка грузит как есть
27
+ dev [каталог] --project <каталог проекта> собирать в .ui_builder/plugins/<id>/ на каждое сохранение
28
+ pack [каталог] [--out <каталог>] собрать и упаковать в npm-архив
29
+
30
+ Параметры:
31
+ -h, --help эта справка
32
+ -v, --version версия CLI`;
33
+ /** Версия CLI из его собственного package.json: `dist/cli.js` → `../package.json`. */
34
+ export function cliVersion() {
35
+ const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
36
+ return pkg.version;
37
+ }
38
+ export async function runCli(argv, io) {
39
+ let parsed;
40
+ try {
41
+ parsed = parseArgs({
42
+ args: [...argv],
43
+ allowPositionals: true,
44
+ options: {
45
+ id: { type: 'string' },
46
+ name: { type: 'string' },
47
+ out: { type: 'string' },
48
+ project: { type: 'string' },
49
+ help: { type: 'boolean', short: 'h' },
50
+ version: { type: 'boolean', short: 'v' },
51
+ },
52
+ });
53
+ }
54
+ catch (error) {
55
+ io.err(error instanceof Error ? error.message : String(error));
56
+ io.err(USAGE);
57
+ return 2;
58
+ }
59
+ const { values, positionals } = parsed;
60
+ if (values.version === true) {
61
+ io.out(cliVersion());
62
+ return 0;
63
+ }
64
+ const [command, target, ...rest] = positionals;
65
+ if (values.help === true || command === undefined) {
66
+ io.out(USAGE);
67
+ return command === undefined && values.help !== true ? 2 : 0;
68
+ }
69
+ if (rest.length > 0) {
70
+ io.err(`лишние аргументы: ${rest.join(' ')}`);
71
+ return 2;
72
+ }
73
+ const path = (value) => resolve(io.cwd, value);
74
+ const printFindings = (findings) => {
75
+ for (const finding of findings)
76
+ io.err(formatFinding(finding));
77
+ };
78
+ /** Печатает отказы или заметки сборки; `true` — сборка удалась. */
79
+ const printBuild = (result) => {
80
+ if (!result.ok) {
81
+ printFindings(result.findings);
82
+ return false;
83
+ }
84
+ for (const notice of result.notices)
85
+ io.out(`! ${notice}`);
86
+ return true;
87
+ };
88
+ // Параметры принимаются только теми командами, которым они что-то значат: молча
89
+ // проигнорированный `--out` у validate хуже отказа.
90
+ const accepted = {
91
+ create: ['id', 'name'],
92
+ validate: [],
93
+ build: ['out'],
94
+ dev: ['project'],
95
+ pack: ['out'],
96
+ };
97
+ const extra = Object.keys(values).filter((key) => key !== 'help' && key !== 'version' && !(accepted[command] ?? []).includes(key));
98
+ if (command in accepted && extra.length > 0) {
99
+ io.err(`${command}: параметры ${extra.map((key) => `--${key}`).join(', ')} не принимаются`);
100
+ return 2;
101
+ }
102
+ switch (command) {
103
+ case 'create': {
104
+ if (target === undefined) {
105
+ io.err('create: не указан каталог нового плагина');
106
+ return 2;
107
+ }
108
+ const result = await createPlugin({
109
+ dir: path(target),
110
+ id: values.id,
111
+ name: values.name,
112
+ cliVersion: cliVersion(),
113
+ });
114
+ if (!result.ok) {
115
+ io.err(`✗ ${result.message}`);
116
+ return 1;
117
+ }
118
+ io.out(`✓ плагин создан в ${result.dir}`);
119
+ for (const file of result.files)
120
+ io.out(` ${file}`);
121
+ return 0;
122
+ }
123
+ case 'validate': {
124
+ const result = await validatePlugin(path(target ?? '.'));
125
+ if (result.ok) {
126
+ io.out(`✓ ${result.manifest.id} ${result.manifest.version}: оболочка его примет`);
127
+ return 0;
128
+ }
129
+ printFindings(result.findings);
130
+ return 1;
131
+ }
132
+ case 'build': {
133
+ const result = await buildPlugin({
134
+ dir: path(target ?? '.'),
135
+ outDir: values.out === undefined ? undefined : path(values.out),
136
+ });
137
+ if (!printBuild(result))
138
+ return 1;
139
+ io.out(`✓ ${result.manifest.id} ${result.manifest.version} собран в ${result.outDir}`);
140
+ return 0;
141
+ }
142
+ case 'dev': {
143
+ if (values.project === undefined) {
144
+ io.err('dev: не указан --project — корень проекта, в котором плагин будет подхвачен');
145
+ return 2;
146
+ }
147
+ const session = startDev({
148
+ dir: path(target ?? '.'),
149
+ project: path(values.project),
150
+ onBuild: (result) => {
151
+ if (printBuild(result)) {
152
+ io.out(`✓ ${new Date().toLocaleTimeString()} собран в ${result.outDir}`);
153
+ }
154
+ },
155
+ });
156
+ await session.ready;
157
+ await (io.waitDev ?? waitForSignal)(session);
158
+ session.close();
159
+ return 0;
160
+ }
161
+ case 'pack': {
162
+ const result = await packPlugin({
163
+ dir: path(target ?? '.'),
164
+ destination: values.out === undefined ? undefined : path(values.out),
165
+ });
166
+ if (!result.ok) {
167
+ printFindings(result.findings);
168
+ return 1;
169
+ }
170
+ for (const notice of result.notices)
171
+ io.out(`! ${notice}`);
172
+ io.out(`✓ ${result.file}`);
173
+ return 0;
174
+ }
175
+ default:
176
+ io.err(`неизвестная команда «${command}»`);
177
+ io.err(USAGE);
178
+ return 2;
179
+ }
180
+ }
181
+ /** Ждёт Ctrl+C: `dev` работает, пока его не остановят. */
182
+ function waitForSignal() {
183
+ return new Promise((done) => {
184
+ process.once('SIGINT', () => done());
185
+ });
186
+ }
187
+ /** Запущен ли файл как программа, а не импортирован (тестом). Через ссылку npm — тоже. */
188
+ function isMain() {
189
+ const entry = process.argv[1];
190
+ if (entry === undefined)
191
+ return false;
192
+ try {
193
+ return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url));
194
+ }
195
+ catch {
196
+ return false;
197
+ }
198
+ }
199
+ if (isMain()) {
200
+ const code = await runCli(process.argv.slice(2), {
201
+ out: (line) => process.stdout.write(`${line}\n`),
202
+ err: (line) => process.stderr.write(`${line}\n`),
203
+ cwd: process.cwd(),
204
+ });
205
+ process.exitCode = code;
206
+ }
207
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * `reformer-plugin build`: исходники плагина → каталог, который оболочка грузит как есть.
3
+ *
4
+ * ## Что получается
5
+ *
6
+ * `manifest.json` (тот же, с `main: "main.js"` и `styles.file: "styles.css"`), один `main.js`,
7
+ * `styles.css`, если стили объявлены, и словари по тем же путям, что в исходниках.
8
+ *
9
+ * - **`main.js` — CommonJS.** Линковщик оболочки исполняет модули как CommonJS, и готовый JS
10
+ * идёт у него без транспиляции (`shell/platform/modules/loader`): собери мы ESM, оболочке
11
+ * пришлось бы будить транспилятор ради уже собранного файла.
12
+ * - **Модули рантайма — внешние, ровно по списку** `PLUGIN_RUNTIME_MODULES`. Вложенная копия
13
+ * React или ядра форм — второй экземпляр и тихая поломка. Импорт `@reformer/*` или
14
+ * `@builder/*`, которого в списке нет, — ОТКАЗ сборки: вложить его нельзя (тот же второй
15
+ * экземпляр), а оставить внешним — значит плагин, падающий на спецификаторе при загрузке.
16
+ * - **Пакеты стеков — вкладываются** (`PLUGIN_BUNDLED_PACKAGES`): чистые функции без синглтонов,
17
+ * которых оболочка не подставляет, потому что стека не знает. Вместе с ними вкладывается то,
18
+ * что они сами берут из `@reformer/*` вне списка рантайма (глубокие импорты `@reformer/mcp`
19
+ * у стека ReFormer), — это их внутренность, а не выбор автора плагина. Модули рантайма и из
20
+ * пакета стека остаются внешними.
21
+ * - **CSS из кода — отказ.** Стили плагина объявляются в манифесте (`styles`), и только тогда
22
+ * оболочка их изолирует. Импорт `.css` из кода дал бы таблицу, о которой манифест молчит.
23
+ *
24
+ * ## Что проверяется на выходе
25
+ *
26
+ * Собранный каталог проходит то, что пройдёт у оболочки: разбор манифеста поставки `project`
27
+ * (с каталогом, названным по `id`), потолок числа файлов кода и «сухую» активацию
28
+ * (`./dry-run`) — узнавание плагина в экспортах, `id` кода и `provides`.
29
+ *
30
+ * ## Каталог вывода не чужой
31
+ *
32
+ * Перед записью каталог очищается, но только если он пуст или в нём лежит сборка ЭТОГО ЖЕ
33
+ * плагина (манифест с тем же `id`). Иначе — отказ: `--out ~/project` не должен стирать проект.
34
+ *
35
+ * @module @reformer/builder-plugin-cli/commands/build
36
+ */
37
+ import { type PluginSourceManifest } from '@reformer/builder-plugin-api/tooling';
38
+ import type { Finding } from './findings.js';
39
+ export interface BuildOptions {
40
+ /** Каталог исходников плагина (с `manifest.json`). */
41
+ readonly dir: string;
42
+ /** Куда класть сборку; умолчание — `dist` в каталоге исходников. */
43
+ readonly outDir?: string;
44
+ }
45
+ export type BuildResult = {
46
+ readonly ok: true;
47
+ readonly manifest: PluginSourceManifest;
48
+ readonly outDir: string;
49
+ readonly files: readonly string[];
50
+ /** Проверки, которые не удалось довести до конца вне оболочки. Не отказы. */
51
+ readonly notices: readonly string[];
52
+ } | {
53
+ readonly ok: false;
54
+ readonly findings: readonly Finding[];
55
+ };
56
+ export declare function buildPlugin(options: BuildOptions): Promise<BuildResult>;
57
+ //# sourceMappingURL=build.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/commands/build.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAMH,OAAO,EAOL,KAAK,oBAAoB,EAC1B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAG7C,MAAM,WAAW,YAAY;IAC3B,sDAAsD;IACtD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,WAAW,GACnB;IACE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAClB,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,6EAA6E;IAC7E,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,GACD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,CAAA;CAAE,CAAC;AA2HlE,wBAAsB,WAAW,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAmG7E"}