limina 0.0.3 → 0.0.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/LICENSE.md +11 -0
- package/README.md +16 -369
- package/README.zh-CN.md +30 -0
- package/bin/limina.js +32 -21
- package/chunks/dep-CBKvJc4Y.js +846 -0
- package/chunks/dep-DTGmTTL7.js +4968 -0
- package/cli.js +2710 -2158
- package/config.d.ts +211 -23
- package/config.js +2 -2
- package/index.d.ts +22 -2
- package/index.js +3 -3
- package/package.json +18 -3
- package/schemas/tsconfig-schema.json +42 -0
- package/chunks/dep-DzYrmtQJ.js +0 -360
- package/chunks/dep-UWxsul2A.js +0 -2400
package/LICENSE.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
<!-- markdownlint-disable MD003 MD009 MD025 MD035 MD026 -->
|
|
2
|
+
# limina license
|
|
3
|
+
|
|
4
|
+
limina is released under the MIT license:
|
|
5
|
+
|
|
1
6
|
MIT License
|
|
2
7
|
|
|
3
8
|
Copyright (c) 2025-present, Senao Xi. and docs islands contributors.
|
|
@@ -19,3 +24,9 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
19
24
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
25
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
26
|
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
# Licenses of bundled dependencies
|
|
29
|
+
|
|
30
|
+
The published limina artifact additionally contains code with the following licenses:
|
|
31
|
+
|
|
32
|
+
# Bundled dependencies:
|
package/README.md
CHANGED
|
@@ -1,383 +1,30 @@
|
|
|
1
1
|
# limina
|
|
2
2
|
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://docs.senao.me/docs-islands/limina" target="_blank" rel="noopener noreferrer">
|
|
5
|
+
<img width="180" src="https://docs.senao.me/docs-islands/limina/logo.svg" alt="limina logo">
|
|
6
|
+
</a>
|
|
7
|
+
</p>
|
|
3
8
|
<p align="center">
|
|
4
9
|
<a href="https://npmjs.com/package/limina"><img src="https://img.shields.io/npm/v/limina.svg" alt="npm package"></a>
|
|
5
10
|
<a href="https://nodejs.org/en/about/previous-releases"><img src="https://img.shields.io/node/v/limina.svg" alt="node compatibility"></a>
|
|
6
11
|
<a href="https://github.com/XiSenao/docs-islands/actions/workflows/ci.yml"><img src="https://github.com/XiSenao/docs-islands/actions/workflows/ci.yml/badge.svg?branch=main" alt="build status"></a>
|
|
7
|
-
<a href="https://github.com/XiSenao/docs-islands/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/limina.svg" alt="license"></a>
|
|
12
|
+
<a href="https://github.com/XiSenao/docs-islands/blob/main/packages/limina/LICENSE.md"><img src="https://img.shields.io/npm/l/limina.svg" alt="license"></a>
|
|
8
13
|
</p>
|
|
9
14
|
|
|
10
15
|
English | [简体中文](./README.zh-CN.md)
|
|
11
16
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Limina is not a bundler and does not replace `tsc`, `vue-tsc`, tests, or release tooling. It coordinates them and verifies that the architecture they depend on stays consistent.
|
|
15
|
-
|
|
16
|
-
## Why Limina?
|
|
17
|
-
|
|
18
|
-
Large TypeScript workspaces often need more than `tsc --noEmit`:
|
|
19
|
-
|
|
20
|
-
- project references must match real cross-project imports;
|
|
21
|
-
- production graph projects should not depend on tools or tests;
|
|
22
|
-
- browser/runtime output should not import Node builtins;
|
|
23
|
-
- `workspace:*` dependencies should resolve to source during graph checks;
|
|
24
|
-
- generated compatibility `paths` should not silently drift;
|
|
25
|
-
- built package outputs need consumer-facing checks before release;
|
|
26
|
-
- Vue, docs, playground, and smoke checks may need checker-specific tooling outside native `tsc -b`.
|
|
27
|
-
|
|
28
|
-
Limina makes these rules reviewable, runnable, and suitable for CI.
|
|
29
|
-
|
|
30
|
-
## Features
|
|
31
|
-
|
|
32
|
-
- **Project graph validation**: checks reachable TypeScript declaration leaves, references, graph-owned imports, package boundaries, and label-based deny rules.
|
|
33
|
-
- **Typecheck coverage proof**: verifies that reachable declaration leaves match strict local typecheck companions and that source files are covered by checker entries or allowlist entries.
|
|
34
|
-
- **Compatibility path generation**: writes opt-in `tsconfig.dts.paths.generated.json` files for `workspace:*` dependencies whose package exports still point at build artifacts.
|
|
35
|
-
- **Checker target runner**: runs configured TypeScript and UI-framework checker entries in `typecheck` or `build` execution mode.
|
|
36
|
-
- **Published package checks**: validates built package outputs with `publint`, Are The Types Wrong, and a runtime import boundary audit.
|
|
37
|
-
- **Composable pipelines**: combines built-in checks and shell commands into named workflows such as `typecheck`, `package`, and `publish`.
|
|
38
|
-
- **Typed configuration**: ships `defineConfig(...)` for editor hints and typed user configs.
|
|
39
|
-
|
|
40
|
-
## Requirements
|
|
41
|
-
|
|
42
|
-
- Node.js `^20.19.0 || >=22.12.0`
|
|
43
|
-
- pnpm workspace with `pnpm-workspace.yaml`
|
|
44
|
-
- TypeScript installed in the consuming repository
|
|
45
|
-
- ESM-compatible `limina.config.mjs`
|
|
46
|
-
|
|
47
|
-
## Installation
|
|
48
|
-
|
|
49
|
-
```sh
|
|
50
|
-
pnpm add -D limina typescript
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## Quick start
|
|
54
|
-
|
|
55
|
-
Create `limina.config.mjs` at the workspace root:
|
|
56
|
-
|
|
57
|
-
```js
|
|
58
|
-
import { defineConfig } from 'limina';
|
|
59
|
-
|
|
60
|
-
export default defineConfig({
|
|
61
|
-
config: {
|
|
62
|
-
checkers: {
|
|
63
|
-
typescript: {
|
|
64
|
-
preset: 'tsc',
|
|
65
|
-
entry: 'tsconfig.build.json',
|
|
66
|
-
},
|
|
67
|
-
vue: {
|
|
68
|
-
preset: 'vue-tsc',
|
|
69
|
-
entry: 'tsconfig.vue.build.json',
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
|
|
74
|
-
graph: {
|
|
75
|
-
rules: {
|
|
76
|
-
'runtime-client': {
|
|
77
|
-
deny: {
|
|
78
|
-
refs: [
|
|
79
|
-
{
|
|
80
|
-
path: 'packages/app/src/node/tsconfig.lib.dts.json',
|
|
81
|
-
reason: 'client runtime must not depend on the Node runtime',
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
},
|
|
88
|
-
|
|
89
|
-
proof: {
|
|
90
|
-
allowlist: [
|
|
91
|
-
{
|
|
92
|
-
file: 'src/generated/runtime.d.ts',
|
|
93
|
-
reason: 'Generated declaration stub covered by the runtime build process.',
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
packageChecks: {
|
|
99
|
-
targets: [
|
|
100
|
-
{
|
|
101
|
-
name: '@acme/core',
|
|
102
|
-
outDir: 'packages/core/dist',
|
|
103
|
-
},
|
|
104
|
-
],
|
|
105
|
-
},
|
|
106
|
-
|
|
107
|
-
pipelines: {
|
|
108
|
-
package: ['package:check'],
|
|
109
|
-
publish: ['graph:check', 'proof:check', 'package:check'],
|
|
110
|
-
},
|
|
111
|
-
});
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Add scripts:
|
|
115
|
-
|
|
116
|
-
```json
|
|
117
|
-
{
|
|
118
|
-
"scripts": {
|
|
119
|
-
"typecheck": "limina check",
|
|
120
|
-
"lint:package": "limina package check",
|
|
121
|
-
"prepublishOnly": "limina check publish"
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Run checks:
|
|
127
|
-
|
|
128
|
-
```sh
|
|
129
|
-
pnpm typecheck
|
|
130
|
-
pnpm exec limina graph check
|
|
131
|
-
pnpm exec limina package check --package @acme/core
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## Concepts
|
|
135
|
-
|
|
136
|
-
### Checker entry
|
|
137
|
-
|
|
138
|
-
Each checker has one required `config.checkers.<name>.entry`, usually a `tsconfig*.build.json` graph aggregator. Built-in first-class presets (`tsc` and `vue-tsc`) participate in graph, source, proof, and build checks. Source-only presets such as `svelte-check` prove source coverage and run direct checker execution through `limina checker typecheck`.
|
|
139
|
-
|
|
140
|
-
### Declaration leaf and local companion
|
|
141
|
-
|
|
142
|
-
Declaration leaves should have strict local companions. For example, `tsconfig.lib.dts.json` pairs with `tsconfig.lib.json`, and `tsconfig.dts.json` pairs with `tsconfig.json`.
|
|
143
|
-
|
|
144
|
-
The default `tsconfig.json` is the IDE/typecheck entry for its directory. A single-environment directory should use it as the local leaf; a multi-environment directory should make it a pure aggregator with `files: []` and `references`.
|
|
145
|
-
|
|
146
|
-
### Source dependencies and artifact dependencies
|
|
147
|
-
|
|
148
|
-
A dependency declared as `workspace:*` is considered a source dependency. It should be represented by project references and source-facing package exports.
|
|
149
|
-
|
|
150
|
-
A dependency declared as `link:`, `file:`, `catalog:`, or normal semver is treated as an artifact dependency. It should not be modeled as a project reference unless it is intentionally consumed as source.
|
|
151
|
-
|
|
152
|
-
### Package checks
|
|
153
|
-
|
|
154
|
-
Source graph checks do not prove that an installed package works for consumers. `limina package check` inspects built package outputs under `packageChecks.targets[].outDir` and checks the actual package manifest, exports, type resolution, and runtime imports. Publishable outputs whose `package.json` does not set `private: true` must also include root `README.md` and `LICENSE.md` files.
|
|
155
|
-
|
|
156
|
-
## CLI
|
|
157
|
-
|
|
158
|
-
```sh
|
|
159
|
-
limina [--config limina.config.mjs] [--mode mode] <command>
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
| Command | Description |
|
|
163
|
-
| ----------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
164
|
-
| `limina check` | Run the built-in default check pipeline. |
|
|
165
|
-
| `limina check <pipeline>` | Run a named user pipeline from `pipelines`. |
|
|
166
|
-
| `limina graph check` | Validate project references and architecture import rules. |
|
|
167
|
-
| `limina proof check` | Prove declaration configs, local typecheck configs, and source coverage stay aligned. |
|
|
168
|
-
| `limina paths generate` | Generate compatibility source `paths` configs for artifact-facing workspace exports. |
|
|
169
|
-
| `limina paths apply` | Compatibility alias for `paths generate`. |
|
|
170
|
-
| `limina paths check` | Fail when generated path files are stale. |
|
|
171
|
-
| `limina checker build` | Run build execution for checker entries that support it. |
|
|
172
|
-
| `limina checker typecheck` | Run source-only checker entries such as `svelte-check`. |
|
|
173
|
-
| `limina package check` | Run configured package output checks. |
|
|
174
|
-
| `limina package check --package <name>` | Check one configured package target. |
|
|
175
|
-
| `limina package check --tool <tool>` | Run only `publint`, `attw`, or `boundary`. |
|
|
176
|
-
| `limina package check --attw-profile <profile>` | Override the ATTW profile: `strict`, `node16`, or `esm-only`. |
|
|
177
|
-
|
|
178
|
-
## Configuration reference
|
|
179
|
-
|
|
180
|
-
### `config`
|
|
181
|
-
|
|
182
|
-
```js
|
|
183
|
-
config: {
|
|
184
|
-
checkers: {
|
|
185
|
-
typescript: {
|
|
186
|
-
preset: 'tsc',
|
|
187
|
-
entry: 'tsconfig.build.json',
|
|
188
|
-
},
|
|
189
|
-
vue: {
|
|
190
|
-
preset: 'vue-tsc',
|
|
191
|
-
entry: 'tsconfig.vue.build.json',
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
source: {
|
|
195
|
-
exclude: ['node_modules', 'dist', '.tsbuild'],
|
|
196
|
-
},
|
|
197
|
-
}
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
`config.checkers` defines checker entries. Every configured checker must declare a non-empty `entry` and use a built-in preset. Checker `extensions` are fixed by Limina and cannot be configured; if `source.include` is omitted, Limina derives the source boundary from configured checker extensions, then applies `source.exclude`.
|
|
201
|
-
|
|
202
|
-
### `graph`
|
|
203
|
-
|
|
204
|
-
```js
|
|
205
|
-
graph: {
|
|
206
|
-
rules: {
|
|
207
|
-
'runtime-client': {
|
|
208
|
-
deny: {
|
|
209
|
-
refs: [
|
|
210
|
-
{
|
|
211
|
-
path: 'packages/app/src/node/tsconfig.lib.dts.json',
|
|
212
|
-
reason: 'client runtime must stay independent from Node runtime',
|
|
213
|
-
},
|
|
214
|
-
],
|
|
215
|
-
deps: [
|
|
216
|
-
{
|
|
217
|
-
name: '@acme/internal-node',
|
|
218
|
-
reason: 'client runtime must not consume Node-only packages',
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
name: 'node:*',
|
|
222
|
-
reason: 'client runtime must not import Node builtins',
|
|
223
|
-
},
|
|
224
|
-
{
|
|
225
|
-
name: '#server/*',
|
|
226
|
-
reason: 'client runtime must not use server-only package imports',
|
|
227
|
-
},
|
|
228
|
-
],
|
|
229
|
-
},
|
|
230
|
-
},
|
|
231
|
-
},
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
A declaration leaf opts into a rule by adding a `limina` label:
|
|
236
|
-
|
|
237
|
-
```jsonc
|
|
238
|
-
{
|
|
239
|
-
"limina": "runtime-client",
|
|
240
|
-
"extends": ["./tsconfig.json", "../../tsconfig.dts.base.json"],
|
|
241
|
-
"references": [],
|
|
242
|
-
}
|
|
243
|
-
```
|
|
244
|
-
|
|
245
|
-
### `paths`
|
|
246
|
-
|
|
247
|
-
```js
|
|
248
|
-
paths: {
|
|
249
|
-
generatedFileName: 'tsconfig.dts.paths.generated.json',
|
|
250
|
-
conditionPriority: ['source', 'development', 'types'],
|
|
251
|
-
artifactDirectories: ['dist', 'build', 'lib', 'esm', 'cjs', 'out'],
|
|
252
|
-
}
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
Use generated paths only when a workspace package must keep artifact-facing exports while still being consumed as a graph-owned source dependency.
|
|
256
|
-
|
|
257
|
-
### `proof`
|
|
258
|
-
|
|
259
|
-
```js
|
|
260
|
-
proof: {
|
|
261
|
-
allowlist: [
|
|
262
|
-
{
|
|
263
|
-
file: 'src/generated/runtime.d.ts',
|
|
264
|
-
reason: 'Generated file validated by the build pipeline.',
|
|
265
|
-
},
|
|
266
|
-
],
|
|
267
|
-
}
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
Checker entries cover files validated by TypeScript or framework-aware tools. Allowlist entries are the final fallback after all configured checker entries fail to cover a source file; they should be rare and must include a reason.
|
|
271
|
-
|
|
272
|
-
### `packageChecks`
|
|
273
|
-
|
|
274
|
-
```js
|
|
275
|
-
packageChecks: {
|
|
276
|
-
targets: [
|
|
277
|
-
{
|
|
278
|
-
name: '@acme/core',
|
|
279
|
-
outDir: 'packages/core/dist',
|
|
280
|
-
checks: ['publint', 'attw', 'boundary'],
|
|
281
|
-
publint: { strict: true },
|
|
282
|
-
attw: { profile: 'esm-only' },
|
|
283
|
-
boundary: {
|
|
284
|
-
environment: (file) => file.startsWith('node/') ? 'node' : 'browser',
|
|
285
|
-
ignoredExternalPackages: ['@acme/runtime-shim'],
|
|
286
|
-
},
|
|
287
|
-
},
|
|
288
|
-
],
|
|
289
|
-
}
|
|
290
|
-
```
|
|
291
|
-
|
|
292
|
-
`outDir` must point at the built package directory that contains the publish-ready `package.json`. If that manifest does not set `private: true`, the same directory must also contain `README.md` and `LICENSE.md`.
|
|
293
|
-
|
|
294
|
-
### `pipelines`
|
|
295
|
-
|
|
296
|
-
```js
|
|
297
|
-
pipelines: {
|
|
298
|
-
package: [
|
|
299
|
-
{ type: 'command', command: 'pnpm', args: ['build'] },
|
|
300
|
-
'package:check',
|
|
301
|
-
],
|
|
302
|
-
}
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
`limina check` runs the built-in default pipeline: `graph:check`, `source:check`, `proof:check`, `checker:build`, and `checker:typecheck`. `limina check <pipeline>` only runs user pipelines from `limina.config.mjs#pipelines`; if the name is missing, Limina reports the missing pipeline and asks you to define it there.
|
|
306
|
-
|
|
307
|
-
String steps can be built-in task names or simple commands. Use object command steps when arguments, `cwd`, or `env` need to be explicit.
|
|
308
|
-
|
|
309
|
-
## CI example
|
|
310
|
-
|
|
311
|
-
```yaml
|
|
312
|
-
name: Typecheck
|
|
313
|
-
|
|
314
|
-
on:
|
|
315
|
-
pull_request:
|
|
316
|
-
push:
|
|
317
|
-
branches: [main]
|
|
318
|
-
|
|
319
|
-
jobs:
|
|
320
|
-
typecheck:
|
|
321
|
-
runs-on: ubuntu-latest
|
|
322
|
-
steps:
|
|
323
|
-
- uses: actions/checkout@v4
|
|
324
|
-
- uses: pnpm/action-setup@v4
|
|
325
|
-
- uses: actions/setup-node@v4
|
|
326
|
-
with:
|
|
327
|
-
node-version: 20.19.0
|
|
328
|
-
cache: pnpm
|
|
329
|
-
- run: pnpm install --frozen-lockfile
|
|
330
|
-
- run: pnpm exec limina check
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
## Programmatic API
|
|
334
|
-
|
|
335
|
-
```ts
|
|
336
|
-
import { defineConfig, loadConfig } from 'limina';
|
|
337
|
-
|
|
338
|
-
export default defineConfig({
|
|
339
|
-
pipelines: {
|
|
340
|
-
typecheck: ['graph:check'],
|
|
341
|
-
},
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
const config = await loadConfig();
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
Most users only need `defineConfig(...)`. `loadConfig(...)` is available for custom wrappers and tests.
|
|
348
|
-
|
|
349
|
-
## Troubleshooting
|
|
350
|
-
|
|
351
|
-
### `Unable to find limina config`
|
|
352
|
-
|
|
353
|
-
Run the command from inside the workspace, or pass `--config ./limina.config.mjs`.
|
|
354
|
-
|
|
355
|
-
### `no pnpm-workspace.yaml was found`
|
|
356
|
-
|
|
357
|
-
Limina infers the workspace root from `pnpm-workspace.yaml`. Place the config inside the workspace or pass a config path located under the workspace root.
|
|
358
|
-
|
|
359
|
-
### `packageChecks.targets[x].outDir` is invalid
|
|
360
|
-
|
|
361
|
-
Set `outDir` to the built package directory, not the source package directory, unless that directory is itself the publish-ready package output.
|
|
362
|
-
|
|
363
|
-
### Generated paths are stale
|
|
364
|
-
|
|
365
|
-
Run:
|
|
366
|
-
|
|
367
|
-
```sh
|
|
368
|
-
pnpm exec limina paths generate
|
|
369
|
-
```
|
|
370
|
-
|
|
371
|
-
Then add the generated file to the first position of the listed `extends` arrays and commit the generated file if your repository policy requires reproducible `tsc -b` without a pre-generation step.
|
|
17
|
+
> Architecture governance CLI for TypeScript monorepos
|
|
372
18
|
|
|
373
|
-
|
|
19
|
+
- Keep source dependency graphs aligned with type build graphs
|
|
20
|
+
- Guard package, runtime, and workspace boundaries
|
|
21
|
+
- Cover TypeScript and framework-specific checkers
|
|
22
|
+
- Manage compatibility paths for workspace source dependencies
|
|
23
|
+
- Validate package outputs before release
|
|
24
|
+
- Compose checks for local development, CI, and publishing
|
|
374
25
|
|
|
375
|
-
|
|
376
|
-
- Source graph checks and package artifact checks validate different surfaces.
|
|
377
|
-
- Build graph configs should be strict, small, and directly referenced.
|
|
378
|
-
- Generated compatibility paths should be transitional, not the default architecture.
|
|
379
|
-
- Limina should fail with actionable messages instead of silently accepting graph drift.
|
|
26
|
+
Limina helps teams turn drifting TypeScript monorepo constraints into explicit, reviewable, runnable checks. It keeps source relationships, type coverage, build coordination, package metadata, and publishable outputs aligned across everyday development, code review, and pre-release workflows.
|
|
380
27
|
|
|
381
|
-
|
|
28
|
+
Limina is not a bundler, test runner, or release tool, and it does not replace TypeScript or framework checkers. It runs those existing tools and verifies that the monorepo structure they rely on is still trustworthy.
|
|
382
29
|
|
|
383
|
-
|
|
30
|
+
[Read the Docs to Learn More](https://docs.senao.me/docs-islands/limina/)
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# limina
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<a href="https://docs.senao.me/docs-islands/limina/zh" target="_blank" rel="noopener noreferrer">
|
|
5
|
+
<img width="180" src="https://docs.senao.me/docs-islands/limina/logo.svg" alt="limina logo">
|
|
6
|
+
</a>
|
|
7
|
+
</p>
|
|
8
|
+
<p align="center">
|
|
9
|
+
<a href="https://npmjs.com/package/limina"><img src="https://img.shields.io/npm/v/limina.svg" alt="npm package"></a>
|
|
10
|
+
<a href="https://nodejs.org/en/about/previous-releases"><img src="https://img.shields.io/node/v/limina.svg" alt="node compatibility"></a>
|
|
11
|
+
<a href="https://github.com/XiSenao/docs-islands/actions/workflows/ci.yml"><img src="https://github.com/XiSenao/docs-islands/actions/workflows/ci.yml/badge.svg?branch=main" alt="build status"></a>
|
|
12
|
+
<a href="https://github.com/XiSenao/docs-islands/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/limina.svg" alt="license"></a>
|
|
13
|
+
</p>
|
|
14
|
+
|
|
15
|
+
[English](./README.md) | 简体中文
|
|
16
|
+
|
|
17
|
+
> TypeScript monorepo 的架构治理 CLI
|
|
18
|
+
|
|
19
|
+
- 保持源码依赖图与类型构建图一致
|
|
20
|
+
- 守住 package、运行时与工程边界
|
|
21
|
+
- 覆盖 TypeScript 与框架专属 checker
|
|
22
|
+
- 管理 workspace 源码依赖的兼容路径
|
|
23
|
+
- 验证发布前 package 产物
|
|
24
|
+
- 组合适合本地、CI 与发布流程的检查
|
|
25
|
+
|
|
26
|
+
Limina 帮助团队把 TypeScript monorepo 中容易漂移的工程约束变成显式、可审查、可运行的检查。它让源码关系、类型覆盖、构建协作、package metadata 和发布产物保持一致,适合放进日常开发、代码审查和发布前流程。
|
|
27
|
+
|
|
28
|
+
Limina 不是 bundler、测试框架或发布工具,也不会替代 TypeScript / framework checker。它调用这些已有工具,并验证它们依赖的 monorepo 结构是否仍然可靠。
|
|
29
|
+
|
|
30
|
+
[阅读文档了解更多](https://docs.senao.me/docs-islands/limina/zh/)
|
package/bin/limina.js
CHANGED
|
@@ -1,25 +1,36 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
3
|
-
import { existsSync } from
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync } from 'node:fs';
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
|
+
import path from 'pathe';
|
|
6
|
+
|
|
7
|
+
const packageDir = path.resolve(fileURLToPath(new URL('..', import.meta.url)));
|
|
8
|
+
const distCliPath = path.join(packageDir, 'cli.js');
|
|
9
|
+
const sourceCliPath = path.join(packageDir, 'src/cli.ts');
|
|
10
|
+
const tsxBinName = process.platform === 'win32' ? 'tsx.cmd' : 'tsx';
|
|
11
|
+
const tsxCliPath =
|
|
12
|
+
[
|
|
13
|
+
path.join(packageDir, 'node_modules/.bin', tsxBinName),
|
|
14
|
+
path.join(packageDir, '../../node_modules/.bin', tsxBinName),
|
|
15
|
+
].find((candidate) => existsSync(candidate)) ?? 'tsx';
|
|
7
16
|
|
|
8
|
-
//#region bin/limina.js
|
|
9
|
-
const packageDir = path.resolve(fileURLToPath(new URL("..", import.meta.url)));
|
|
10
|
-
const distCliPath = path.join(packageDir, "cli.js");
|
|
11
|
-
const sourceCliPath = path.join(packageDir, "src/cli.ts");
|
|
12
|
-
const tsxBinName = process.platform === "win32" ? "tsx.cmd" : "tsx";
|
|
13
|
-
const tsxCliPath = [path.join(packageDir, "node_modules/.bin", tsxBinName), path.join(packageDir, "../../node_modules/.bin", tsxBinName)].find((candidate) => existsSync(candidate)) ?? "tsx";
|
|
14
17
|
if (existsSync(sourceCliPath)) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
18
|
+
const result = spawnSync(
|
|
19
|
+
tsxCliPath,
|
|
20
|
+
[sourceCliPath, ...process.argv.slice(2)],
|
|
21
|
+
{
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
shell: process.platform === 'win32',
|
|
24
|
+
},
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (result.error) {
|
|
28
|
+
throw result.error;
|
|
29
|
+
}
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
process.exit(result.status ?? 1);
|
|
32
|
+
} else if (existsSync(distCliPath)) {
|
|
33
|
+
await import(pathToFileURL(distCliPath).href);
|
|
34
|
+
} else {
|
|
35
|
+
throw new Error(`Unable to find limina CLI entry. Expected ${distCliPath}.`);
|
|
36
|
+
}
|