@kurotako/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/README.md +27 -0
- package/dist/index.cjs +1238 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +435 -0
- package/dist/index.d.ts +435 -0
- package/dist/index.js +1177 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
import { IrIssue, IR, SourceIR } from '@kurotako/ir';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `TakoError` hierarchy. Every failure in the pipeline is fail-fast and carries
|
|
5
|
+
* enough context to name the offending source or generator. The CLI maps any
|
|
6
|
+
* `TakoError` to a formatted message + non-zero exit; a non-`TakoError` throw is
|
|
7
|
+
* a bug and surfaces as a stack trace.
|
|
8
|
+
*
|
|
9
|
+
* Error table: `backlog/features/core-pipeline/technical.md` §Error model.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
declare class TakoError extends Error {
|
|
13
|
+
readonly code: string;
|
|
14
|
+
constructor(code: string, message: string, options?: {
|
|
15
|
+
cause?: unknown;
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
declare class NamespaceMismatchError extends TakoError {
|
|
19
|
+
readonly namespace: string;
|
|
20
|
+
readonly returned: string;
|
|
21
|
+
constructor(namespace: string, returned: string);
|
|
22
|
+
}
|
|
23
|
+
declare class IrValidationError extends TakoError {
|
|
24
|
+
readonly issues: IrIssue[];
|
|
25
|
+
readonly namespace?: string;
|
|
26
|
+
constructor(issues: IrIssue[], namespace?: string);
|
|
27
|
+
}
|
|
28
|
+
declare class DuplicateNamespaceError extends TakoError {
|
|
29
|
+
readonly namespace: string;
|
|
30
|
+
constructor(namespace: string);
|
|
31
|
+
}
|
|
32
|
+
declare class UnknownDependencyError extends TakoError {
|
|
33
|
+
readonly generator: string;
|
|
34
|
+
readonly missing: string;
|
|
35
|
+
constructor(generator: string, missing: string);
|
|
36
|
+
}
|
|
37
|
+
declare class InvalidDependencyError extends TakoError {
|
|
38
|
+
readonly generator: string;
|
|
39
|
+
readonly dependency: string;
|
|
40
|
+
constructor(generator: string, dependency: string);
|
|
41
|
+
}
|
|
42
|
+
declare class DependencyCycleError extends TakoError {
|
|
43
|
+
readonly cycle: string[];
|
|
44
|
+
constructor(cycle: string[]);
|
|
45
|
+
}
|
|
46
|
+
declare class OutputCollisionError extends TakoError {
|
|
47
|
+
readonly path: string;
|
|
48
|
+
readonly generators: [string, string];
|
|
49
|
+
constructor(path: string, generators: [string, string], hint?: string);
|
|
50
|
+
}
|
|
51
|
+
declare class InvalidOutputPathError extends TakoError {
|
|
52
|
+
readonly path: string;
|
|
53
|
+
readonly generator: string;
|
|
54
|
+
constructor(path: string, generator: string);
|
|
55
|
+
}
|
|
56
|
+
declare class UnsupportedOutputModeError extends TakoError {
|
|
57
|
+
readonly mode: string;
|
|
58
|
+
constructor(mode: string);
|
|
59
|
+
}
|
|
60
|
+
declare class OutputPeerConflictError extends TakoError {
|
|
61
|
+
readonly namespace: string;
|
|
62
|
+
readonly package: string;
|
|
63
|
+
readonly ranges: string[];
|
|
64
|
+
readonly generators: string[];
|
|
65
|
+
constructor(namespace: string, pkg: string, ranges: string[], generators: string[]);
|
|
66
|
+
}
|
|
67
|
+
declare class PackageBuildError extends TakoError {
|
|
68
|
+
readonly namespace: string;
|
|
69
|
+
constructor(namespace: string, options?: {
|
|
70
|
+
cause?: unknown;
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
declare class MissingPackageWorkspaceFilesError extends TakoError {
|
|
74
|
+
readonly workspaceRoot: string;
|
|
75
|
+
readonly missing: string[];
|
|
76
|
+
constructor(workspaceRoot: string, missing: string[]);
|
|
77
|
+
}
|
|
78
|
+
declare class OutputNotGeneratedError extends TakoError {
|
|
79
|
+
readonly path: string;
|
|
80
|
+
constructor(path: string);
|
|
81
|
+
}
|
|
82
|
+
declare class PackageInstallError extends TakoError {
|
|
83
|
+
readonly pm: string;
|
|
84
|
+
constructor(pm: string, options?: {
|
|
85
|
+
cause?: unknown;
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
declare class DriverError extends TakoError {
|
|
89
|
+
readonly role: 'parser' | 'generator';
|
|
90
|
+
readonly driverName: string;
|
|
91
|
+
readonly namespace?: string;
|
|
92
|
+
constructor(role: 'parser' | 'generator', driverName: string, options?: {
|
|
93
|
+
cause?: unknown;
|
|
94
|
+
namespace?: string;
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
declare class HookError extends TakoError {
|
|
98
|
+
readonly hook: string;
|
|
99
|
+
constructor(hook: string, options?: {
|
|
100
|
+
cause?: unknown;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The Writer seam. `run()` aggregates a virtual tree and hands it to the writer
|
|
106
|
+
* selected by `output.mode`. Mode A (`directoryWriter`) and mode B
|
|
107
|
+
* (`packageWriter`) both live in this directory.
|
|
108
|
+
*/
|
|
109
|
+
|
|
110
|
+
interface WriteInput {
|
|
111
|
+
files: VirtualFile[];
|
|
112
|
+
output: OutputConfig;
|
|
113
|
+
/**
|
|
114
|
+
* Generator short name -> artifact. Mode B reads `peerDependencies` from it;
|
|
115
|
+
* mode A ignores it. Optional so a bare `directoryWriter.write({ files,
|
|
116
|
+
* output })` call still type-checks.
|
|
117
|
+
*/
|
|
118
|
+
artifacts?: Record<string, GeneratorArtifact>;
|
|
119
|
+
/** Mode B logs the manual install command here when no pm is resolved. */
|
|
120
|
+
logger?: Logger;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* One file a `write()` would emit, resolved to its absolute on-disk path with
|
|
124
|
+
* the exact bytes it would serialise (banner already applied by the caller, as
|
|
125
|
+
* for `write`). `plan()` computes these without any disk I/O; `write()` is
|
|
126
|
+
* `plan()` plus materialisation, so the two never drift.
|
|
127
|
+
*/
|
|
128
|
+
interface PlannedFile {
|
|
129
|
+
/** Absolute. */
|
|
130
|
+
path: string;
|
|
131
|
+
content: string;
|
|
132
|
+
}
|
|
133
|
+
interface Writer {
|
|
134
|
+
write(input: WriteInput): Promise<string[]>;
|
|
135
|
+
/**
|
|
136
|
+
* Same layout as `write()`, no disk I/O: the exact set of files `write()`
|
|
137
|
+
* would produce (mode B: `<pkgDir>/src/…` remap + synthesized manifest, but
|
|
138
|
+
* no `dist/`, no `pm install`).
|
|
139
|
+
*/
|
|
140
|
+
plan(input: WriteInput): Promise<PlannedFile[]>;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Public type surface of `@kurotako/core`. Runtime-code free: every export here
|
|
145
|
+
* is a type or an interface. The orchestrator (`run.ts`), the error hierarchy
|
|
146
|
+
* (`errors.ts`) and the writer seam (`writer/`) build on these.
|
|
147
|
+
*
|
|
148
|
+
* Product decisions: `backlog/features/core-pipeline/technical.md`. The IR types
|
|
149
|
+
* come from `@kurotako/ir`; core owns config, driver contracts, contexts,
|
|
150
|
+
* artifacts, hooks, the logger and the `run()` option / result shapes.
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Structured logger. Core ships a no-op default (`logger.ts`); the CLI injects a
|
|
155
|
+
* real one. Contexts receive a child logger tagged with the namespace /
|
|
156
|
+
* generator name.
|
|
157
|
+
*/
|
|
158
|
+
interface Logger {
|
|
159
|
+
debug(msg: string, meta?: unknown): void;
|
|
160
|
+
info(msg: string, meta?: unknown): void;
|
|
161
|
+
warn(msg: string, meta?: unknown): void;
|
|
162
|
+
error(msg: string, meta?: unknown): void;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* The already-resolved, already-validated configuration `run()` consumes.
|
|
166
|
+
* Construction, file format and driver-option validation belong to
|
|
167
|
+
* `@kurotako/config`; core only declares the shape it needs.
|
|
168
|
+
*/
|
|
169
|
+
interface ResolvedConfig {
|
|
170
|
+
/**
|
|
171
|
+
* Absolute path of the directory holding the config file. Anchor for relative
|
|
172
|
+
* output paths and for `ParseContext.cwd`.
|
|
173
|
+
*/
|
|
174
|
+
rootDir: string;
|
|
175
|
+
/** Key === namespace (ADR-0003). */
|
|
176
|
+
sources: Record<string, SourceConfig>;
|
|
177
|
+
/** Key === `Generator.name` (short name). */
|
|
178
|
+
generators: Record<string, GeneratorConfig>;
|
|
179
|
+
outputs: OutputConfig[];
|
|
180
|
+
hooks?: Hooks;
|
|
181
|
+
}
|
|
182
|
+
interface SourceConfig {
|
|
183
|
+
parser: Parser;
|
|
184
|
+
/** Opaque seam kept for `--emit` / debugging; core does not read it. */
|
|
185
|
+
options?: unknown;
|
|
186
|
+
}
|
|
187
|
+
interface GeneratorConfig {
|
|
188
|
+
generator: Generator;
|
|
189
|
+
/** Opaque seam kept for `--emit` / debugging; core does not read it. */
|
|
190
|
+
options?: unknown;
|
|
191
|
+
/** Restrict this generator to a subset of namespaces; default = all. */
|
|
192
|
+
namespaces?: string[];
|
|
193
|
+
}
|
|
194
|
+
interface OutputConfig {
|
|
195
|
+
/** Default `'dir'`. */
|
|
196
|
+
mode?: 'dir' | 'package';
|
|
197
|
+
/** Mode A; resolved absolute by config-system. */
|
|
198
|
+
dir?: string;
|
|
199
|
+
/** Mode B. */
|
|
200
|
+
packagesDir?: string;
|
|
201
|
+
/** Mode B (required for mode B — config-system enforces). */
|
|
202
|
+
scope?: string;
|
|
203
|
+
/** Mode B, optional — consumed by output-modes. */
|
|
204
|
+
packageManager?: 'bun' | 'pnpm' | 'yarn' | 'npm';
|
|
205
|
+
/** Restrict this destination to a subset of `config.generators`; default = all. */
|
|
206
|
+
generators?: string[];
|
|
207
|
+
}
|
|
208
|
+
interface Parser {
|
|
209
|
+
name: string;
|
|
210
|
+
parse(ctx: ParseContext): Promise<SourceIR> | SourceIR;
|
|
211
|
+
/**
|
|
212
|
+
* Metadata for `cli --watch` — the set of paths a watcher should observe.
|
|
213
|
+
* `run()` never calls it.
|
|
214
|
+
*/
|
|
215
|
+
watchPaths?(ctx: ParseContext): string[] | Promise<string[]>;
|
|
216
|
+
/**
|
|
217
|
+
* The directory this source is anchored at, for toolchain-dependency
|
|
218
|
+
* resolution. Already curried (options bound). `run()` calls it before
|
|
219
|
+
* `parse()` and passes the result as `ParseContext.anchorDir`. Return
|
|
220
|
+
* `undefined` (or omit the hook) to anchor on `rootDir`. Must not throw for an
|
|
221
|
+
* ordinary "not found" case — a bad path is the parser's problem to surface
|
|
222
|
+
* during `parse()`.
|
|
223
|
+
*/
|
|
224
|
+
anchor?(rootDir: string): string | undefined | Promise<string | undefined>;
|
|
225
|
+
}
|
|
226
|
+
interface ParseContext {
|
|
227
|
+
namespace: string;
|
|
228
|
+
/** Absolute; the config-file directory. Base for `options.schema` and output paths. */
|
|
229
|
+
cwd: string;
|
|
230
|
+
/**
|
|
231
|
+
* Absolute; the directory this source is anchored at — where its schema lives.
|
|
232
|
+
* A parser resolves the source's own toolchain dependencies (`@prisma/internals`
|
|
233
|
+
* and equivalents) from here, letting Node walk up `node_modules` to `cwd` and
|
|
234
|
+
* beyond. Absent (⇒ treat as `cwd`) when the parser declares no `anchor` hook.
|
|
235
|
+
*/
|
|
236
|
+
anchorDir?: string;
|
|
237
|
+
logger: Logger;
|
|
238
|
+
}
|
|
239
|
+
interface Generator {
|
|
240
|
+
name: string;
|
|
241
|
+
/** Hard dependency: absent from the config => error. Constrains order. */
|
|
242
|
+
dependsOn?: string[];
|
|
243
|
+
/** Optional dependency: used if present, else ignored. Constrains order. */
|
|
244
|
+
optionalDependsOn?: string[];
|
|
245
|
+
generate(ctx: GenerateContext): Promise<GenOutput> | GenOutput;
|
|
246
|
+
}
|
|
247
|
+
interface GenerateContext {
|
|
248
|
+
/** Namespace-filtered deep clone of the merged IR. */
|
|
249
|
+
ir: IR;
|
|
250
|
+
/** Only declared deps (`dependsOn ∪ optionalDependsOn`) that actually ran. */
|
|
251
|
+
dependencies: Record<string, GeneratorArtifact>;
|
|
252
|
+
logger: Logger;
|
|
253
|
+
}
|
|
254
|
+
interface GenOutput {
|
|
255
|
+
files: VirtualFile[];
|
|
256
|
+
artifact: GeneratorArtifact;
|
|
257
|
+
}
|
|
258
|
+
interface VirtualFile {
|
|
259
|
+
/**
|
|
260
|
+
* POSIX, relative to the output root. The generator owns the
|
|
261
|
+
* `<namespace>/<generatorName>/` prefix (one sub-tree per generator; core
|
|
262
|
+
* synthesizes `<namespace>/index.ts`).
|
|
263
|
+
*/
|
|
264
|
+
path: string;
|
|
265
|
+
content: string;
|
|
266
|
+
}
|
|
267
|
+
interface GeneratorArtifact {
|
|
268
|
+
/** Key === `${namespace}.${entity}`. */
|
|
269
|
+
entities: Record<string, EntitySymbols>;
|
|
270
|
+
/**
|
|
271
|
+
* Package -> semver range the emitted code imports. Mode B: core aggregates
|
|
272
|
+
* per namespace (output-modes).
|
|
273
|
+
*/
|
|
274
|
+
peerDependencies?: Record<string, string>;
|
|
275
|
+
/** Generator-defined; the consumer casts to the producer's published type. */
|
|
276
|
+
extra?: unknown;
|
|
277
|
+
}
|
|
278
|
+
interface EntitySymbols {
|
|
279
|
+
/** Module specifier a sibling generator imports from. */
|
|
280
|
+
module: string;
|
|
281
|
+
/** Role -> exported identifier, e.g. `{ schema: "UserSchema", type: "User" }`. */
|
|
282
|
+
symbols: Record<string, string>;
|
|
283
|
+
}
|
|
284
|
+
interface Hooks {
|
|
285
|
+
afterEmit?(ctx: AfterEmitContext): Promise<void> | void;
|
|
286
|
+
}
|
|
287
|
+
interface AfterEmitContext {
|
|
288
|
+
/** Absolute; the directory the Writer just populated. */
|
|
289
|
+
outputDir: string;
|
|
290
|
+
/** Absolute paths actually written, sorted. */
|
|
291
|
+
files: string[];
|
|
292
|
+
logger: Logger;
|
|
293
|
+
}
|
|
294
|
+
interface RunOptions {
|
|
295
|
+
/** Default: no-op. */
|
|
296
|
+
logger?: Logger;
|
|
297
|
+
/** Cooperative cancellation between steps (watch mode). */
|
|
298
|
+
signal?: AbortSignal;
|
|
299
|
+
/** Default `true`; `false` => run everything, skip the Writer. */
|
|
300
|
+
write?: boolean;
|
|
301
|
+
/**
|
|
302
|
+
* Default `false`. `true` => run everything up to (not including) emission,
|
|
303
|
+
* then ask each output's Writer for the files a `generate` would write
|
|
304
|
+
* (absolute path + exact bytes) via `Writer.plan()`, returned as
|
|
305
|
+
* `RunResult.plan`. No disk I/O, `afterEmit` does not fire. Wins over
|
|
306
|
+
* `write`: `{ plan: true, write: true }` still writes nothing.
|
|
307
|
+
*/
|
|
308
|
+
plan?: boolean;
|
|
309
|
+
}
|
|
310
|
+
interface RunResult {
|
|
311
|
+
/** Merged, validated IR (for `--emit-ir`, drift-guard). */
|
|
312
|
+
ir: IR;
|
|
313
|
+
/** Generator short names, in execution order. */
|
|
314
|
+
order: string[];
|
|
315
|
+
/** Aggregated virtual tree, sorted by path. */
|
|
316
|
+
files: VirtualFile[];
|
|
317
|
+
/** Generator short name -> its artifact. */
|
|
318
|
+
artifacts: Record<string, GeneratorArtifact>;
|
|
319
|
+
/** One entry per `config.outputs[]`, in order; `[]` when `write: false`. */
|
|
320
|
+
written: {
|
|
321
|
+
output: OutputConfig;
|
|
322
|
+
files: string[];
|
|
323
|
+
}[];
|
|
324
|
+
/**
|
|
325
|
+
* Present iff `opts.plan === true`: the files a fresh `generate` would write
|
|
326
|
+
* across every `config.outputs[]` entry, absolute paths, sorted by `path`.
|
|
327
|
+
* Basis of `tako check` (drift-guard).
|
|
328
|
+
*/
|
|
329
|
+
plan?: PlannedFile[];
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* The no-op `Logger` default and a `childLogger` wrapper that merges a
|
|
334
|
+
* `{ namespace }` / `{ generator }` tag into every call's `meta`.
|
|
335
|
+
*/
|
|
336
|
+
|
|
337
|
+
/** Default logger: swallows everything. The CLI injects a real one. */
|
|
338
|
+
declare const noopLogger: Logger;
|
|
339
|
+
/**
|
|
340
|
+
* Wrap `base` so every message carries `prefixMeta` (e.g. `{ namespace }` or
|
|
341
|
+
* `{ generator }`) merged into its `meta` argument.
|
|
342
|
+
*/
|
|
343
|
+
declare function childLogger(base: Logger, prefixMeta: Record<string, unknown>): Logger;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* `run()` — the single public entry point. Sequential, fail-fast: parse ->
|
|
347
|
+
* merge -> order -> generate -> collect -> write -> afterEmit. `opts.signal` is
|
|
348
|
+
* checked at each step boundary; `opts.write === false` runs everything but
|
|
349
|
+
* skips the Writer (basis of `--dry-run`). `opts.plan === true` also stops
|
|
350
|
+
* before emission but calls `Writer.plan()` per output and returns the planned
|
|
351
|
+
* tree as `RunResult.plan` — no disk I/O, no `afterEmit` (basis of `tako check`
|
|
352
|
+
* / drift-guard); it wins over `opts.write`.
|
|
353
|
+
*
|
|
354
|
+
* Steps 5b/5c (synthesize root barrels, apply banner) are added to this file by
|
|
355
|
+
* the output-modes feature; they are not part of the core-pipeline tasks.
|
|
356
|
+
*/
|
|
357
|
+
|
|
358
|
+
declare function run(config: ResolvedConfig, opts?: RunOptions): Promise<RunResult>;
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* The generated-file banner. `run.ts` calls `applyBanner` once, after barrel
|
|
362
|
+
* synthesis and before the writer, so every `.ts` file — generator output and
|
|
363
|
+
* synthesized barrels alike — carries the marker. `.json` files have no comment
|
|
364
|
+
* syntax: `packageWriter` sets a `"//"` key on `package.json` instead.
|
|
365
|
+
*
|
|
366
|
+
* Design: `backlog/features/output-modes/technical.md` §Banner.
|
|
367
|
+
*/
|
|
368
|
+
|
|
369
|
+
declare const BANNER = "// Generated by tako. Do not edit.\n";
|
|
370
|
+
declare const GITATTRIBUTES = "* linguist-generated=true\n";
|
|
371
|
+
/**
|
|
372
|
+
* Prepend `BANNER` to every `.ts` / `.tsx` file (and `tsconfig.json`). Pure,
|
|
373
|
+
* and idempotent-safe: a file that already starts with the banner is left
|
|
374
|
+
* untouched. `package.json` and other `.json` files pass through unchanged.
|
|
375
|
+
*/
|
|
376
|
+
declare function applyBanner(files: VirtualFile[]): VirtualFile[];
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Root-barrel synthesis. Each generator owns `<namespace>/<generatorName>/` and
|
|
380
|
+
* emits its own barrel there; `tako` synthesizes `<namespace>/index.ts` so
|
|
381
|
+
* `import … from '<scope>/<namespace>'` resolves regardless of how many
|
|
382
|
+
* generators ran. Mode-independent — mode A and mode B both get the barrel.
|
|
383
|
+
*
|
|
384
|
+
* Design: `backlog/features/output-modes/technical.md` §New orchestration step.
|
|
385
|
+
*/
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* One `VirtualFile { path: '<ns>/index.ts' }` per namespace present in `files`,
|
|
389
|
+
* its content one sorted `export * from './<generatorName>';` line per
|
|
390
|
+
* generator that contributed a file under `<ns>/<generatorName>/`. A
|
|
391
|
+
* single-generator namespace still gets a barrel.
|
|
392
|
+
*
|
|
393
|
+
* When `artifactsByGenerator` is supplied, `logger?.warn(...)` fires if the same
|
|
394
|
+
* exported identifier appears in two contributing artifacts for one namespace
|
|
395
|
+
* (an ambiguous star re-export TypeScript/ESM silently drops). Never throws.
|
|
396
|
+
*/
|
|
397
|
+
declare function synthesizeRootBarrels(files: VirtualFile[], artifactsByGenerator?: Record<string, GeneratorArtifact>, logger?: Logger): VirtualFile[];
|
|
398
|
+
|
|
399
|
+
declare const directoryWriter: Writer;
|
|
400
|
+
|
|
401
|
+
declare const packageWriter: Writer;
|
|
402
|
+
|
|
403
|
+
declare function selectWriter(output: OutputConfig): Writer;
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* Namespace -> (package -> semver range). Per namespace, union the
|
|
407
|
+
* `peerDependencies` of every generator that emitted a file under
|
|
408
|
+
* `<namespace>/<generatorName>/`. Identical ranges de-duplicate; the same
|
|
409
|
+
* package with two different ranges from two generators throws
|
|
410
|
+
* `OutputPeerConflictError` (fail-fast). Namespace and package keys are sorted.
|
|
411
|
+
*/
|
|
412
|
+
declare function collectPeerDependencies(artifactsByGenerator: Record<string, GeneratorArtifact>, files: VirtualFile[]): Record<string, Record<string, string>>;
|
|
413
|
+
|
|
414
|
+
type PackageManager = 'bun' | 'pnpm' | 'yarn' | 'npm';
|
|
415
|
+
/**
|
|
416
|
+
* Resolve the package manager to run `install` with, in order:
|
|
417
|
+
* 1. `configured` (from `output.packageManager`) — used verbatim;
|
|
418
|
+
* 2. lockfile walk-up from `startDir` (`bun.lock` / `bun.lockb` -> `bun`,
|
|
419
|
+
* `pnpm-lock.yaml` -> `pnpm`, `yarn.lock` -> `yarn`,
|
|
420
|
+
* `package-lock.json` -> `npm`), stopping at a `.git` marker or the root;
|
|
421
|
+
* 3. nearest ancestor `package.json` `packageManager` field (name before `@`);
|
|
422
|
+
* 4. `null` — do not guess.
|
|
423
|
+
*/
|
|
424
|
+
declare function resolvePackageManager(opts: {
|
|
425
|
+
configured?: PackageManager;
|
|
426
|
+
startDir: string;
|
|
427
|
+
}): PackageManager | null;
|
|
428
|
+
/**
|
|
429
|
+
* Run `<pm> install` in `cwd`. No `--frozen-lockfile` — the generated packages
|
|
430
|
+
* are new, the lockfile must change. A non-zero exit becomes
|
|
431
|
+
* `PackageInstallError { pm, cause }`.
|
|
432
|
+
*/
|
|
433
|
+
declare function runInstall(pm: PackageManager, cwd: string): Promise<void>;
|
|
434
|
+
|
|
435
|
+
export { type AfterEmitContext, BANNER, DependencyCycleError, DriverError, DuplicateNamespaceError, type EntitySymbols, GITATTRIBUTES, type GenOutput, type GenerateContext, type Generator, type GeneratorArtifact, type GeneratorConfig, HookError, type Hooks, InvalidDependencyError, InvalidOutputPathError, IrValidationError, type Logger, MissingPackageWorkspaceFilesError, NamespaceMismatchError, OutputCollisionError, type OutputConfig, OutputNotGeneratedError, OutputPeerConflictError, PackageBuildError, PackageInstallError, type PackageManager, type ParseContext, type Parser, type PlannedFile, type ResolvedConfig, type RunOptions, type RunResult, type SourceConfig, TakoError, UnknownDependencyError, UnsupportedOutputModeError, type VirtualFile, type WriteInput, type Writer, applyBanner, childLogger, collectPeerDependencies, directoryWriter, noopLogger, packageWriter, resolvePackageManager, run, runInstall, selectWriter, synthesizeRootBarrels };
|