@reliverse/dler 1.6.6 → 1.6.7
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/README.md +92 -10
- package/bin/app/build/cmd.js +1 -1
- package/bin/app/build/impl.js +1 -1
- package/bin/app/check/cmd.d.ts +0 -3
- package/bin/app/check/cmd.js +68 -351
- package/bin/app/cmds.d.ts +21 -437
- package/bin/app/cmds.js +38 -22
- package/bin/app/deps/cmd.js +2 -2
- package/bin/app/migrate/cmd.d.ts +12 -2
- package/bin/app/migrate/cmd.js +105 -58
- package/bin/app/migrate/codemods/anything-to-bun.d.ts +5 -0
- package/bin/app/migrate/codemods/anything-to-bun.js +597 -0
- package/bin/app/migrate/codemods/fs-to-relifso.d.ts +8 -0
- package/bin/app/migrate/codemods/fs-to-relifso.js +179 -0
- package/bin/app/migrate/codemods/path-to-pathkit.d.ts +8 -0
- package/bin/app/migrate/codemods/{lib-pathe-pathkit.js → path-to-pathkit.js} +22 -111
- package/bin/app/pub/cmd.js +1 -1
- package/bin/app/rempts/cmd/cmd.js +10 -3
- package/bin/cli.js +14 -4
- package/bin/libs/sdk/sdk-impl/build/build-library.js +23 -19
- package/bin/libs/sdk/sdk-impl/build/build-regular.js +13 -13
- package/bin/libs/sdk/sdk-impl/check/check-consts.d.ts +29 -0
- package/bin/libs/sdk/sdk-impl/check/check-consts.js +48 -0
- package/bin/libs/sdk/sdk-impl/check/check-mod.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/check/check-mod.js +87 -0
- package/bin/libs/sdk/sdk-impl/check/check-utils.d.ts +5 -0
- package/bin/libs/sdk/sdk-impl/check/check-utils.js +56 -0
- package/bin/libs/sdk/sdk-impl/check/rules/dler-config-health.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/check/rules/dler-config-health.js +37 -0
- package/bin/libs/sdk/sdk-impl/check/rules/file-extensions.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/check/rules/file-extensions.js +69 -0
- package/bin/{app/deps/impl/wrapper.d.ts → libs/sdk/sdk-impl/check/rules/missing-deps.d.ts} +1 -1
- package/bin/{app/deps/impl/wrapper.js → libs/sdk/sdk-impl/check/rules/missing-deps.js} +2 -2
- package/bin/libs/sdk/sdk-impl/check/rules/package-json-health.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/check/rules/package-json-health.js +67 -0
- package/bin/libs/sdk/sdk-impl/check/rules/path-extensions.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/check/rules/path-extensions.js +93 -0
- package/bin/libs/sdk/sdk-impl/check/rules/self-include.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/check/rules/self-include.js +98 -0
- package/bin/libs/sdk/sdk-impl/check/rules/tsconfig-health.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/check/rules/tsconfig-health.js +35 -0
- package/bin/libs/sdk/{default.d.ts → sdk-impl/config/default.d.ts} +1 -1
- package/bin/libs/sdk/{default.js → sdk-impl/config/default.js} +15 -5
- package/bin/libs/sdk/sdk-impl/config/define.d.ts +2 -0
- package/bin/libs/sdk/sdk-impl/config/define.js +4 -0
- package/bin/{init → libs/sdk/sdk-impl/config}/info.js +1 -1
- package/bin/{init → libs/sdk/sdk-impl/config}/init.js +8 -8
- package/bin/{init → libs/sdk/sdk-impl/config}/load.d.ts +2 -1
- package/bin/{init → libs/sdk/sdk-impl/config}/load.js +15 -6
- package/bin/libs/sdk/sdk-impl/library-flow.d.ts +1 -1
- package/bin/libs/sdk/sdk-impl/library-flow.js +3 -3
- package/bin/libs/sdk/sdk-impl/spell/spell-executors.js +1 -1
- package/bin/libs/sdk/sdk-impl/spell/spell-filesystem.d.ts +1 -1
- package/bin/libs/sdk/sdk-impl/spell/spell-filesystem.js +7 -1
- package/bin/libs/sdk/sdk-impl/utils/utils-build.d.ts +8 -2
- package/bin/libs/sdk/sdk-impl/utils/utils-build.js +5 -5
- package/bin/libs/sdk/sdk-impl/utils/utils-deps.js +36 -10
- package/bin/libs/sdk/sdk-impl/utils/utils-fs.js +20 -8
- package/bin/libs/sdk/sdk-impl/utils/utils-jsr-json.d.ts +2 -1
- package/bin/libs/sdk/sdk-impl/utils/utils-jsr-json.js +15 -4
- package/bin/libs/sdk/sdk-impl/utils/utils-pkg-json-libs.d.ts +5 -0
- package/bin/libs/sdk/sdk-impl/utils/utils-pkg-json-libs.js +98 -29
- package/bin/libs/sdk/sdk-impl/utils/utils-pkg-json-reg.js +12 -5
- package/bin/libs/sdk/sdk-types.d.ts +67 -33
- package/bin/mod.d.ts +1 -2
- package/bin/mod.js +1 -4
- package/package.json +1 -1
- package/bin/app/migrate/codemods/lib-pathe-pathkit.d.ts +0 -9
- /package/bin/app/migrate/codemods/{ts-module-resolution.d.ts → module-resolution.d.ts} +0 -0
- /package/bin/app/migrate/codemods/{ts-module-resolution.js → module-resolution.js} +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/analyzer.d.ts +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/analyzer.js +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/deps-types.d.ts +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/deps-types.js +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/filesystem.d.ts +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/filesystem.js +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/formatter.d.ts +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/formatter.js +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/parser.d.ts +0 -0
- /package/bin/{app/deps/impl → libs/sdk/sdk-impl/check/rules/deps}/parser.js +0 -0
- /package/bin/{init → libs/sdk/sdk-impl/config}/info.d.ts +0 -0
- /package/bin/{init → libs/sdk/sdk-impl/config}/init.d.ts +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
# dler (prev. relidler) •
|
|
1
|
+
# dler (prev. relidler) • framework for ts/js libs/cli/apps
|
|
2
2
|
|
|
3
|
-
> @reliverse/dler (`/ˈdiː.lər/`, dealer) is a flexible, unified, and fully automated bundler for
|
|
3
|
+
> @reliverse/dler (`/ˈdiː.lər/`, dealer) is a flexible, unified, and fully automated bundler for ts/js projects, as well as an npm/jsr publishing tool. dler is not only a bundler, it also tries to serve as the most powerful codemod toolkit for ts/js.
|
|
4
4
|
|
|
5
5
|
[sponsor](https://github.com/sponsors/blefnk) — [discord](https://discord.gg/pb8ukbwpsj) — [repo](https://github.com/reliverse/dler) — [npm](https://npmjs.com/@reliverse/dler) — [docs](https://docs.reliverse.org/reliverse/dler)
|
|
6
6
|
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
- 😘 replacement for `unjs/unbuild`
|
|
10
10
|
- ⚡ `dler` works via cli and sdk
|
|
11
11
|
- 📦 automated npm/jsr publishing
|
|
12
|
-
- ✅ ensures reliable js
|
|
12
|
+
- ✅ ensures reliable ts/js builds
|
|
13
13
|
- 🔄 handles automatic version bumps
|
|
14
14
|
- 🔧 eliminates `package.json` headaches
|
|
15
15
|
- 🎯 optimized for speed and modern workflows
|
|
@@ -170,6 +170,26 @@ checks your project for common issues and potential improvements. This command p
|
|
|
170
170
|
- Compares against package.json
|
|
171
171
|
- Reports missing dependencies
|
|
172
172
|
|
|
173
|
+
- **Self-Include**: Prevents circular dependencies and self-imports
|
|
174
|
+
- Checks for imports from the main package in dist directories
|
|
175
|
+
- Prevents libraries from importing themselves
|
|
176
|
+
- Allows libraries to import from other libraries
|
|
177
|
+
|
|
178
|
+
- **Module Resolution**: Validates TypeScript module resolution settings
|
|
179
|
+
- Ensures proper moduleResolution in tsconfig.json
|
|
180
|
+
- Supports both "bundler" and "nodenext" strategies
|
|
181
|
+
- Reports configuration issues
|
|
182
|
+
|
|
183
|
+
- **Dler Config Health**: Validates your dler configuration
|
|
184
|
+
- Checks libs main file format
|
|
185
|
+
- Ensures proper configuration structure
|
|
186
|
+
- Reports configuration issues
|
|
187
|
+
|
|
188
|
+
- **Package.json Validation**: Ensures your package.json follows best practices
|
|
189
|
+
- Requires: name, version, type=module, keywords
|
|
190
|
+
- Forbids: bin, exports, files, main, module (they are auto-generated by dler)
|
|
191
|
+
- Helps maintain consistent package configuration
|
|
192
|
+
|
|
173
193
|
```bash
|
|
174
194
|
# Fully interactive mode (when no args provided)
|
|
175
195
|
dler check
|
|
@@ -189,7 +209,7 @@ dler check --json
|
|
|
189
209
|
**arguments:**
|
|
190
210
|
|
|
191
211
|
- `--directory`: directory to check (src, dist-npm, dist-jsr, dist-libs/npm, dist-libs/jsr, or all)
|
|
192
|
-
- `--checks`: comma-separated list of checks to run (missing-
|
|
212
|
+
- `--checks`: comma-separated list of checks to run (missing-deps, file-extensions, path-extensions, dler-config-health, self-include, tsconfig-health, package-json-health)
|
|
193
213
|
- `--strict`: enable strict mode (requires explicit extensions)
|
|
194
214
|
- `--json`: output results in JSON format
|
|
195
215
|
|
|
@@ -277,7 +297,7 @@ libslist: {
|
|
|
277
297
|
libdeclarations: true,
|
|
278
298
|
libdescription: "@reliverse/dler without cli",
|
|
279
299
|
libdirname: "sdk",
|
|
280
|
-
libmainfile: "sdk
|
|
300
|
+
libmainfile: "sdk-mod.ts",
|
|
281
301
|
libpkgkeepdeps: false,
|
|
282
302
|
libtranspileminify: true,
|
|
283
303
|
},
|
|
@@ -304,9 +324,56 @@ not yet documented.
|
|
|
304
324
|
|
|
305
325
|
helps migrate between different libraries and module resolution strategies. currently supports:
|
|
306
326
|
|
|
307
|
-
- `
|
|
308
|
-
- `
|
|
327
|
+
- `path-to-pathkit`: migrate from node:path and unjs/pathe to pathkit library
|
|
328
|
+
- `fs-to-relifso`: migrate from node:fs and fs-extra to relifso library
|
|
309
329
|
- `module-resolution`: migrate between module resolution strategies
|
|
330
|
+
- `anything-to-bun`: migrate Node.js projects to Bun runtime
|
|
331
|
+
|
|
332
|
+
**path-to-pathkit features:**
|
|
333
|
+
|
|
334
|
+
- Migrates from both `pathe` and `node:path` to `@reliverse/pathkit`
|
|
335
|
+
- Handles both default and named exports
|
|
336
|
+
- Supports multi-line imports
|
|
337
|
+
- Converts require statements
|
|
338
|
+
- Updates package.json dependencies
|
|
339
|
+
|
|
340
|
+
**fs-to-relifso features:**
|
|
341
|
+
|
|
342
|
+
- Migrates from both `node:fs` and `fs-extra` to `@reliverse/relifso`
|
|
343
|
+
- Handles both default and named exports
|
|
344
|
+
- Supports multi-line imports
|
|
345
|
+
- Converts require statements
|
|
346
|
+
- Updates package.json dependencies
|
|
347
|
+
- Preserves import structure and formatting
|
|
348
|
+
|
|
349
|
+
**anything-to-bun features:**
|
|
350
|
+
|
|
351
|
+
- Migrates Node.js imports to use `node:` prefix
|
|
352
|
+
- Replaces npm/yarn/pnpm features with bun equivalents
|
|
353
|
+
- Converts to Bun-native APIs:
|
|
354
|
+
- Database: `pg`/`postgres` → `Bun.sql`, `sqlite3` → `bun:sqlite`
|
|
355
|
+
- Redis: `redis`/`ioredis` → `Bun.redis`
|
|
356
|
+
- Utilities: `glob` → `Bun.Glob`, `bcrypt`/`argon2` → `Bun.password`
|
|
357
|
+
- Testing: `jest`/`vitest` → `bun:test`
|
|
358
|
+
- FFI: `node-ffi` → `bun:ffi`
|
|
359
|
+
- Transforms file operations to `Bun.file` API
|
|
360
|
+
- Converts Express apps to `Bun.serve`
|
|
361
|
+
- Updates package.json scripts and dependencies
|
|
362
|
+
- Generates Bun configuration files
|
|
363
|
+
- Creates Dockerfile for Bun deployment
|
|
364
|
+
|
|
365
|
+
**usage example:**
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
# Preview changes without applying them
|
|
369
|
+
dler migrate --lib anything-to-bun --dryRun
|
|
370
|
+
|
|
371
|
+
# Apply changes
|
|
372
|
+
dler migrate --lib anything-to-bun
|
|
373
|
+
|
|
374
|
+
# Migrate specific project
|
|
375
|
+
dler migrate --lib anything-to-bun --project ./my-app
|
|
376
|
+
```
|
|
310
377
|
|
|
311
378
|
**module resolution targets:**
|
|
312
379
|
|
|
@@ -316,8 +383,11 @@ helps migrate between different libraries and module resolution strategies. curr
|
|
|
316
383
|
**usage examples:**
|
|
317
384
|
|
|
318
385
|
```bash
|
|
319
|
-
# Migrate from pathe to pathkit
|
|
320
|
-
dler migrate --lib
|
|
386
|
+
# Migrate from node:path and/or pathe to pathkit
|
|
387
|
+
dler migrate --lib path-to-pathkit
|
|
388
|
+
|
|
389
|
+
# Migrate from node:fs and/or fs-extra to relifso
|
|
390
|
+
dler migrate --lib fs-to-relifso
|
|
321
391
|
|
|
322
392
|
# Migrate to nodenext module resolution
|
|
323
393
|
dler migrate --lib module-resolution --target nodenext
|
|
@@ -340,16 +410,28 @@ dler migrate --lib module-resolution --target nodenext --dryRun
|
|
|
340
410
|
|
|
341
411
|
**next steps after migration:**
|
|
342
412
|
|
|
343
|
-
- for
|
|
413
|
+
- for path-to-pathkit:
|
|
344
414
|
1. run 'bun install' to install @reliverse/pathkit
|
|
345
415
|
2. test your application
|
|
346
416
|
3. consider using advanced pathkit features
|
|
347
417
|
|
|
418
|
+
- for fs-to-relifso:
|
|
419
|
+
1. run 'bun install' to install @reliverse/relifso
|
|
420
|
+
2. test your application
|
|
421
|
+
3. review any file system operations that might need manual updates
|
|
422
|
+
|
|
348
423
|
- for module-resolution:
|
|
349
424
|
1. test your application
|
|
350
425
|
2. ensure your build tools support the new module resolution
|
|
351
426
|
3. review any warnings in the migration output
|
|
352
427
|
|
|
428
|
+
- for anything-to-bun:
|
|
429
|
+
1. run 'bun install' to install dependencies with Bun
|
|
430
|
+
2. test your application thoroughly
|
|
431
|
+
3. review async/await usage in converted file operations
|
|
432
|
+
4. update any custom database queries to use Bun.sql syntax
|
|
433
|
+
5. review and update any custom middleware in Express apps
|
|
434
|
+
|
|
353
435
|
### 9. `pub`
|
|
354
436
|
|
|
355
437
|
pub command is separated for its own build-in plugin as well.
|
package/bin/app/build/cmd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { defineArgs, defineCommand } from "@reliverse/rempts";
|
|
2
2
|
import { dlerBuild } from "./impl.js";
|
|
3
|
-
import { ensureDlerConfig } from "../../
|
|
3
|
+
import { ensureDlerConfig } from "../../libs/sdk/sdk-impl/config/init.js";
|
|
4
4
|
export default defineCommand({
|
|
5
5
|
meta: {
|
|
6
6
|
name: "build",
|
package/bin/app/build/impl.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "@reliverse/bleump";
|
|
6
6
|
import path from "@reliverse/pathkit";
|
|
7
7
|
import fs from "@reliverse/relifso";
|
|
8
|
-
import { loadConfig } from "../../
|
|
8
|
+
import { loadConfig } from "../../libs/sdk/sdk-impl/config/load.js";
|
|
9
9
|
import { processLibraryFlow } from "../../libs/sdk/sdk-impl/library-flow.js";
|
|
10
10
|
import { processRegularFlow } from "../../libs/sdk/sdk-impl/regular-flow.js";
|
|
11
11
|
import { finalizeBuildPub } from "../../libs/sdk/sdk-impl/utils/finalize.js";
|
package/bin/app/check/cmd.d.ts
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import type { CheckResult, FileCheckOptions } from "../../libs/sdk/sdk-types.js";
|
|
2
|
-
export declare function checkFileExtensions(options: FileCheckOptions): Promise<CheckResult>;
|
|
3
|
-
export declare function checkPathExtensions(options: FileCheckOptions): Promise<CheckResult>;
|
|
4
1
|
declare const _default: import("@reliverse/rempts").Command<{
|
|
5
2
|
directory: {
|
|
6
3
|
type: "string";
|
package/bin/app/check/cmd.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { getFileImportsExports, extname, join } from "@reliverse/pathkit";
|
|
2
|
-
import fs from "@reliverse/relifso";
|
|
3
1
|
import { relinka } from "@reliverse/relinka";
|
|
4
2
|
import {
|
|
5
3
|
defineCommand,
|
|
@@ -8,335 +6,14 @@ import {
|
|
|
8
6
|
confirmPrompt,
|
|
9
7
|
defineArgs
|
|
10
8
|
} from "@reliverse/rempts";
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"dist-jsr": ["", ".ts", ".css", ".json"],
|
|
20
|
-
// ✅ .ts files allowed in jsr dist
|
|
21
|
-
"dist-libs/npm": ["", ".js", ".css", ".json"],
|
|
22
|
-
// ❌ no .ts files in npm libs
|
|
23
|
-
"dist-libs/jsr": ["", ".ts", ".css", ".json"]
|
|
24
|
-
// ✅ .ts files allowed in jsr libs
|
|
25
|
-
};
|
|
26
|
-
const STRICT_FILE_EXTENSIONS = {
|
|
27
|
-
src: [".ts", ".css", ".json"],
|
|
28
|
-
// ✅ .ts files required in src
|
|
29
|
-
"dist-npm": [".js", ".css", ".json"],
|
|
30
|
-
// ❌ no .ts files in npm dist
|
|
31
|
-
"dist-jsr": [".ts", ".css", ".json"],
|
|
32
|
-
// ✅ .ts files required in jsr dist
|
|
33
|
-
"dist-libs/npm": [".js", ".css", ".json"],
|
|
34
|
-
// ❌ no .ts files in npm libs
|
|
35
|
-
"dist-libs/jsr": [".ts", ".css", ".json"]
|
|
36
|
-
// ✅ .ts files required in jsr libs
|
|
37
|
-
};
|
|
38
|
-
const ALLOWED_IMPORT_EXTENSIONS = {
|
|
39
|
-
src: ["", ".js", ".css", ".json"],
|
|
40
|
-
// ❌ no .ts imports (use .js)
|
|
41
|
-
"dist-npm": ["", ".js", ".css", ".json"],
|
|
42
|
-
// ❌ no .ts imports
|
|
43
|
-
"dist-jsr": ["", ".ts", ".css", ".json"],
|
|
44
|
-
// ✅ .ts imports allowed
|
|
45
|
-
"dist-libs/npm": ["", ".js", ".css", ".json"],
|
|
46
|
-
// ❌ no .ts imports
|
|
47
|
-
"dist-libs/jsr": ["", ".ts", ".css", ".json"]
|
|
48
|
-
// ✅ .ts imports allowed
|
|
49
|
-
};
|
|
50
|
-
const STRICT_IMPORT_EXTENSIONS = {
|
|
51
|
-
src: [".js", ".css", ".json"],
|
|
52
|
-
// ❌ no .ts imports, no empty
|
|
53
|
-
"dist-npm": [".js", ".css", ".json"],
|
|
54
|
-
// ❌ no .ts imports
|
|
55
|
-
"dist-jsr": [".ts", ".css", ".json"],
|
|
56
|
-
// ✅ .ts imports required
|
|
57
|
-
"dist-libs/npm": [".js", ".css", ".json"],
|
|
58
|
-
// ❌ no .ts imports
|
|
59
|
-
"dist-libs/jsr": [".ts", ".css", ".json"]
|
|
60
|
-
// ✅ .ts imports required
|
|
61
|
-
};
|
|
62
|
-
async function validateDirectory(dir) {
|
|
63
|
-
try {
|
|
64
|
-
const stat = await fs.stat(dir);
|
|
65
|
-
return stat.isDirectory();
|
|
66
|
-
} catch {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
function shouldIgnoreFile(filePath) {
|
|
71
|
-
const pathSegments = filePath.split("/");
|
|
72
|
-
return IGNORE_PATTERNS.some(
|
|
73
|
-
(pattern) => pathSegments.some((segment) => segment.includes(pattern))
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
async function getAllFiles(dir, onProgress) {
|
|
77
|
-
const results = [];
|
|
78
|
-
let fileCount = 0;
|
|
79
|
-
async function searchDirectory(directory) {
|
|
80
|
-
try {
|
|
81
|
-
const files = await fs.readdir(directory);
|
|
82
|
-
for (const file of files) {
|
|
83
|
-
const fullPath = join(directory, file);
|
|
84
|
-
if (shouldIgnoreFile(fullPath)) {
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
try {
|
|
88
|
-
const stat = await fs.stat(fullPath);
|
|
89
|
-
if (stat.isDirectory()) {
|
|
90
|
-
if (file === "templates") continue;
|
|
91
|
-
await searchDirectory(fullPath);
|
|
92
|
-
} else {
|
|
93
|
-
results.push(fullPath);
|
|
94
|
-
fileCount++;
|
|
95
|
-
onProgress?.(fileCount, fileCount, fullPath);
|
|
96
|
-
}
|
|
97
|
-
} catch {
|
|
98
|
-
relinka("warn", `skipping inaccessible file: ${fullPath}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
} catch {
|
|
102
|
-
relinka("warn", `skipping inaccessible directory: ${directory}`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
if (!await validateDirectory(dir)) {
|
|
106
|
-
throw new Error(`directory "${dir}" does not exist or is not accessible`);
|
|
107
|
-
}
|
|
108
|
-
await searchDirectory(dir);
|
|
109
|
-
return results;
|
|
110
|
-
}
|
|
111
|
-
async function validateModuleResolution() {
|
|
112
|
-
try {
|
|
113
|
-
const tsconfig = await readTSConfig();
|
|
114
|
-
const moduleResolution = tsconfig?.compilerOptions?.moduleResolution;
|
|
115
|
-
if (!moduleResolution) {
|
|
116
|
-
throw new Error("moduleResolution is not specified in tsconfig.json");
|
|
117
|
-
}
|
|
118
|
-
if (moduleResolution !== "bundler" && moduleResolution !== "nodenext") {
|
|
119
|
-
throw new Error(
|
|
120
|
-
`unsupported moduleResolution: ${moduleResolution}. Only "bundler" and "nodenext" are supported`
|
|
121
|
-
);
|
|
122
|
-
}
|
|
123
|
-
return moduleResolution;
|
|
124
|
-
} catch (error) {
|
|
125
|
-
throw new Error(
|
|
126
|
-
`failed to read tsconfig.json: ${error instanceof Error ? error.message : "unknown error"}`
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
function getAllowedFileExtensions(directory, strict, moduleResolution) {
|
|
131
|
-
if (!strict) {
|
|
132
|
-
return ALLOWED_FILE_EXTENSIONS[directory];
|
|
133
|
-
}
|
|
134
|
-
if (moduleResolution === "bundler") {
|
|
135
|
-
return STRICT_FILE_EXTENSIONS[directory];
|
|
136
|
-
}
|
|
137
|
-
return STRICT_FILE_EXTENSIONS[directory];
|
|
138
|
-
}
|
|
139
|
-
function getAllowedImportExtensions(directory, strict) {
|
|
140
|
-
if (strict) {
|
|
141
|
-
return STRICT_IMPORT_EXTENSIONS[directory];
|
|
142
|
-
}
|
|
143
|
-
return ALLOWED_IMPORT_EXTENSIONS[directory];
|
|
144
|
-
}
|
|
145
|
-
export async function checkFileExtensions(options) {
|
|
146
|
-
const startTime = Date.now();
|
|
147
|
-
const issues = [];
|
|
148
|
-
const { directory, strict, moduleResolution, onProgress } = options;
|
|
149
|
-
const allowedExts = getAllowedFileExtensions(
|
|
150
|
-
directory,
|
|
151
|
-
strict,
|
|
152
|
-
moduleResolution
|
|
153
|
-
);
|
|
154
|
-
try {
|
|
155
|
-
const files = await getAllFiles(directory, onProgress);
|
|
156
|
-
const batchSize = 50;
|
|
157
|
-
const batches = [];
|
|
158
|
-
for (let i = 0; i < files.length; i += batchSize) {
|
|
159
|
-
batches.push(files.slice(i, i + batchSize));
|
|
160
|
-
}
|
|
161
|
-
for (const [batchIndex, batch] of batches.entries()) {
|
|
162
|
-
const batchPromises = batch.map(async (file, fileIndex) => {
|
|
163
|
-
const globalIndex = batchIndex * batchSize + fileIndex;
|
|
164
|
-
onProgress?.(globalIndex + 1, files.length, file);
|
|
165
|
-
const ext = extname(file);
|
|
166
|
-
if (!allowedExts.includes(ext)) {
|
|
167
|
-
let message = `file has disallowed extension "${ext}" (allowed: ${allowedExts.join(", ")})`;
|
|
168
|
-
if (ext === ".ts" && (directory === "dist-npm" || directory === "dist-libs/npm")) {
|
|
169
|
-
message = `typescript file found in javascript environment: ${file} (should be compiled to .js)`;
|
|
170
|
-
} else if (ext === ".js" && (directory === "src" || directory === "dist-jsr" || directory === "dist-libs/jsr")) {
|
|
171
|
-
message = `javascript file found in typescript environment: ${file} (should be .ts)`;
|
|
172
|
-
}
|
|
173
|
-
return {
|
|
174
|
-
file,
|
|
175
|
-
message,
|
|
176
|
-
type: "file-extension"
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
return null;
|
|
180
|
-
});
|
|
181
|
-
const batchResults = await Promise.all(batchPromises);
|
|
182
|
-
issues.push(...batchResults.filter(Boolean));
|
|
183
|
-
}
|
|
184
|
-
return {
|
|
185
|
-
success: issues.length === 0,
|
|
186
|
-
issues,
|
|
187
|
-
stats: {
|
|
188
|
-
filesChecked: files.length,
|
|
189
|
-
importsChecked: 0,
|
|
190
|
-
timeElapsed: Date.now() - startTime
|
|
191
|
-
}
|
|
192
|
-
};
|
|
193
|
-
} catch (error) {
|
|
194
|
-
throw new Error(
|
|
195
|
-
`failed to check file extensions: ${error instanceof Error ? error.message : "unknown error"}`
|
|
196
|
-
);
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
export async function checkPathExtensions(options) {
|
|
200
|
-
const startTime = Date.now();
|
|
201
|
-
const issues = [];
|
|
202
|
-
const { directory, strict, onProgress } = options;
|
|
203
|
-
const allowedExts = getAllowedImportExtensions(directory, strict);
|
|
204
|
-
try {
|
|
205
|
-
const files = await getAllFiles(directory);
|
|
206
|
-
let totalImports = 0;
|
|
207
|
-
const importableFiles = files.filter((file) => {
|
|
208
|
-
const ext = extname(file);
|
|
209
|
-
return [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext);
|
|
210
|
-
});
|
|
211
|
-
const batchSize = 20;
|
|
212
|
-
const batches = [];
|
|
213
|
-
for (let i = 0; i < importableFiles.length; i += batchSize) {
|
|
214
|
-
batches.push(importableFiles.slice(i, i + batchSize));
|
|
215
|
-
}
|
|
216
|
-
for (const [batchIndex, batch] of batches.entries()) {
|
|
217
|
-
const batchPromises = batch.map(async (file, fileIndex) => {
|
|
218
|
-
const globalIndex = batchIndex * batchSize + fileIndex;
|
|
219
|
-
onProgress?.(globalIndex + 1, importableFiles.length, file);
|
|
220
|
-
try {
|
|
221
|
-
const content = await fs.readFile(file, "utf-8");
|
|
222
|
-
const imports = getFileImportsExports(content, {
|
|
223
|
-
kind: "import",
|
|
224
|
-
pathTypes: ["relative", "alias"]
|
|
225
|
-
});
|
|
226
|
-
totalImports += imports.length;
|
|
227
|
-
const fileIssues = [];
|
|
228
|
-
for (const imp of imports) {
|
|
229
|
-
if (!imp.source) continue;
|
|
230
|
-
const ext = extname(imp.source);
|
|
231
|
-
if (!allowedExts.includes(ext)) {
|
|
232
|
-
const isTypeScriptImport = ext === ".ts";
|
|
233
|
-
const isJsEnvironment = directory === "src" || directory === "dist-npm" || directory === "dist-libs/npm";
|
|
234
|
-
let message;
|
|
235
|
-
if (isTypeScriptImport && isJsEnvironment) {
|
|
236
|
-
message = `import uses .ts extension in javascript environment: ${imp.source} (use .js extension instead)`;
|
|
237
|
-
} else {
|
|
238
|
-
message = `import has disallowed extension "${ext}": ${imp.source} (allowed: ${allowedExts.join(", ")})`;
|
|
239
|
-
}
|
|
240
|
-
fileIssues.push({
|
|
241
|
-
file,
|
|
242
|
-
message,
|
|
243
|
-
type: "path-extension",
|
|
244
|
-
line: getLineNumber(content, imp.start),
|
|
245
|
-
source: imp.source
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
return { issues: fileIssues, importCount: imports.length };
|
|
250
|
-
} catch {
|
|
251
|
-
relinka("warn", `skipping unreadable file: ${file}`);
|
|
252
|
-
return { issues: [], importCount: 0 };
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
const batchResults = await Promise.all(batchPromises);
|
|
256
|
-
for (const result of batchResults) {
|
|
257
|
-
issues.push(...result.issues);
|
|
258
|
-
totalImports += result.importCount;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return {
|
|
262
|
-
success: issues.length === 0,
|
|
263
|
-
issues,
|
|
264
|
-
stats: {
|
|
265
|
-
filesChecked: importableFiles.length,
|
|
266
|
-
importsChecked: totalImports,
|
|
267
|
-
timeElapsed: Date.now() - startTime
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
} catch (error) {
|
|
271
|
-
throw new Error(
|
|
272
|
-
`failed to check path extensions: ${error instanceof Error ? error.message : "unknown error"}`
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
function getLineNumber(content, position) {
|
|
277
|
-
return content.slice(0, position).split("\n").length;
|
|
278
|
-
}
|
|
279
|
-
function displayResults(checkType, directory, result) {
|
|
280
|
-
const { success, issues, stats } = result;
|
|
281
|
-
if (success) {
|
|
282
|
-
relinka("success", `\u2713 ${checkType} check passed for ${directory}`);
|
|
283
|
-
relinka(
|
|
284
|
-
"info",
|
|
285
|
-
` files checked: ${stats.filesChecked}, imports: ${stats.importsChecked}, time: ${stats.timeElapsed}ms`
|
|
286
|
-
);
|
|
287
|
-
} else {
|
|
288
|
-
relinka(
|
|
289
|
-
"error",
|
|
290
|
-
`\u2717 ${checkType} check failed for ${directory} (${issues.length} issues)`
|
|
291
|
-
);
|
|
292
|
-
const fileIssues = issues.filter((i) => i.type === "file-extension");
|
|
293
|
-
const pathIssues = issues.filter((i) => i.type === "path-extension");
|
|
294
|
-
const missingDepIssues = issues.filter(
|
|
295
|
-
(i) => i.type === "missing-dependency"
|
|
296
|
-
);
|
|
297
|
-
const builtinIssues = issues.filter((i) => i.type === "builtin-module");
|
|
298
|
-
if (fileIssues.length > 0) {
|
|
299
|
-
relinka("error", ` file extension issues (${fileIssues.length}):`);
|
|
300
|
-
for (const issue of fileIssues.slice(0, 10)) {
|
|
301
|
-
relinka("error", ` ${issue.file}: ${issue.message}`);
|
|
302
|
-
}
|
|
303
|
-
if (fileIssues.length > 10) {
|
|
304
|
-
relinka("error", ` ... and ${fileIssues.length - 10} more`);
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
if (pathIssues.length > 0) {
|
|
308
|
-
relinka("error", ` import extension issues (${pathIssues.length}):`);
|
|
309
|
-
for (const issue of pathIssues.slice(0, 10)) {
|
|
310
|
-
relinka("error", ` ${issue.file}:${issue.line}: ${issue.message}`);
|
|
311
|
-
}
|
|
312
|
-
if (pathIssues.length > 10) {
|
|
313
|
-
relinka("error", ` ... and ${pathIssues.length - 10} more`);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
if (missingDepIssues.length > 0) {
|
|
317
|
-
relinka("error", ` missing dependencies (${missingDepIssues.length}):`);
|
|
318
|
-
for (const issue of missingDepIssues.slice(0, 10)) {
|
|
319
|
-
relinka("error", ` ${issue.message}`);
|
|
320
|
-
}
|
|
321
|
-
if (missingDepIssues.length > 10) {
|
|
322
|
-
relinka("error", ` ... and ${missingDepIssues.length - 10} more`);
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
if (builtinIssues.length > 0) {
|
|
326
|
-
relinka("warn", ` builtin modules used (${builtinIssues.length}):`);
|
|
327
|
-
for (const issue of builtinIssues.slice(0, 10)) {
|
|
328
|
-
relinka("warn", ` ${issue.message}`);
|
|
329
|
-
}
|
|
330
|
-
if (builtinIssues.length > 10) {
|
|
331
|
-
relinka("warn", ` ... and ${builtinIssues.length - 10} more`);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
relinka(
|
|
335
|
-
"info",
|
|
336
|
-
` stats: ${stats.filesChecked} files, ${stats.importsChecked} imports, ${stats.timeElapsed}ms`
|
|
337
|
-
);
|
|
338
|
-
}
|
|
339
|
-
}
|
|
9
|
+
import { displayCheckResults } from "../../libs/sdk/sdk-impl/check/check-mod.js";
|
|
10
|
+
import { checkDlerConfigHealth } from "../../libs/sdk/sdk-impl/check/rules/dler-config-health.js";
|
|
11
|
+
import { checkFileExtensions } from "../../libs/sdk/sdk-impl/check/rules/file-extensions.js";
|
|
12
|
+
import { checkMissingDependencies } from "../../libs/sdk/sdk-impl/check/rules/missing-deps.js";
|
|
13
|
+
import { checkPackageJsonHealth } from "../../libs/sdk/sdk-impl/check/rules/package-json-health.js";
|
|
14
|
+
import { checkPathExtensions } from "../../libs/sdk/sdk-impl/check/rules/path-extensions.js";
|
|
15
|
+
import { checkSelfInclude } from "../../libs/sdk/sdk-impl/check/rules/self-include.js";
|
|
16
|
+
import { checkTsConfigHealth } from "../../libs/sdk/sdk-impl/check/rules/tsconfig-health.js";
|
|
340
17
|
export default defineCommand({
|
|
341
18
|
meta: {
|
|
342
19
|
name: "check",
|
|
@@ -350,7 +27,7 @@ export default defineCommand({
|
|
|
350
27
|
},
|
|
351
28
|
checks: {
|
|
352
29
|
type: "string",
|
|
353
|
-
description: "comma-separated list of checks to run (missing-
|
|
30
|
+
description: "comma-separated list of checks to run (missing-deps,file-extensions,path-extensions,dler-config-health,self-include,tsconfig-health,package-json-health)"
|
|
354
31
|
},
|
|
355
32
|
strict: {
|
|
356
33
|
type: "boolean",
|
|
@@ -374,17 +51,10 @@ export default defineCommand({
|
|
|
374
51
|
"info",
|
|
375
52
|
"\u{1F4E6} import rules: use .js imports in src/npm dirs, .ts imports in jsr dirs"
|
|
376
53
|
);
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
} catch (error) {
|
|
382
|
-
relinka(
|
|
383
|
-
"error",
|
|
384
|
-
error instanceof Error ? error.message : "unknown error"
|
|
385
|
-
);
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
54
|
+
relinka(
|
|
55
|
+
"info",
|
|
56
|
+
"\u{1F504} self-include rules: no importing from main package or self-imports in libs"
|
|
57
|
+
);
|
|
388
58
|
let dir;
|
|
389
59
|
let checks;
|
|
390
60
|
let strict;
|
|
@@ -395,7 +65,9 @@ export default defineCommand({
|
|
|
395
65
|
title: "select a directory to check",
|
|
396
66
|
options: [
|
|
397
67
|
{ label: "all directories", value: "all" },
|
|
68
|
+
// TODO: run this automatically BEFORE `dler build`
|
|
398
69
|
{ label: "src (typescript source)", value: "src" },
|
|
70
|
+
// TODO: run this automatically AFTER `dler build`
|
|
399
71
|
{ label: "dist-npm (compiled js)", value: "dist-npm" },
|
|
400
72
|
{ label: "dist-jsr (typescript)", value: "dist-jsr" },
|
|
401
73
|
{ label: "dist-libs/npm (compiled js)", value: "dist-libs/npm" },
|
|
@@ -409,7 +81,7 @@ export default defineCommand({
|
|
|
409
81
|
checks = await multiselectPrompt({
|
|
410
82
|
title: "select checks to run",
|
|
411
83
|
options: [
|
|
412
|
-
{ label: "missing dependencies", value: "missing-
|
|
84
|
+
{ label: "missing dependencies", value: "missing-deps" },
|
|
413
85
|
{
|
|
414
86
|
label: "file extensions (.ts/.js files)",
|
|
415
87
|
value: "file-extensions"
|
|
@@ -417,6 +89,22 @@ export default defineCommand({
|
|
|
417
89
|
{
|
|
418
90
|
label: "import path extensions (.ts/.js imports)",
|
|
419
91
|
value: "path-extensions"
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
label: "dler configuration",
|
|
95
|
+
value: "dler-config-health"
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
label: "self-include (no self-imports)",
|
|
99
|
+
value: "self-include"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
label: "tsconfig.json validation",
|
|
103
|
+
value: "tsconfig-health"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
label: "package.json validation",
|
|
107
|
+
value: "package-json-health"
|
|
420
108
|
}
|
|
421
109
|
]
|
|
422
110
|
});
|
|
@@ -449,40 +137,69 @@ checking directory: ${directory}`);
|
|
|
449
137
|
}
|
|
450
138
|
};
|
|
451
139
|
try {
|
|
452
|
-
if (checks.includes("
|
|
140
|
+
if (checks.includes("package-json-health")) {
|
|
141
|
+
process.stdout.write(" checking package.json health...\n");
|
|
142
|
+
const result = await checkPackageJsonHealth();
|
|
143
|
+
process.stdout.write("\r");
|
|
144
|
+
displayCheckResults("package.json health", directory, result);
|
|
145
|
+
}
|
|
146
|
+
if (checks.includes("tsconfig-health")) {
|
|
147
|
+
process.stdout.write(" checking tsconfig.json health...\n");
|
|
148
|
+
const result = await checkTsConfigHealth();
|
|
149
|
+
process.stdout.write("\r");
|
|
150
|
+
displayCheckResults("tsconfig.json health", directory, result);
|
|
151
|
+
}
|
|
152
|
+
if (checks.includes("dler-config-health")) {
|
|
153
|
+
process.stdout.write(" checking libs main file format...\n");
|
|
154
|
+
const result = await checkDlerConfigHealth();
|
|
155
|
+
process.stdout.write("\r");
|
|
156
|
+
displayCheckResults("libs main file format", directory, result);
|
|
157
|
+
}
|
|
158
|
+
if (checks.includes("missing-deps")) {
|
|
453
159
|
process.stdout.write(" checking missing dependencies...\n");
|
|
454
160
|
const result = await checkMissingDependencies({
|
|
455
161
|
directory,
|
|
456
162
|
strict: false,
|
|
457
163
|
// not used for deps check
|
|
458
|
-
moduleResolution,
|
|
164
|
+
moduleResolution: "bundler",
|
|
459
165
|
// not used for deps check
|
|
460
166
|
onProgress
|
|
461
167
|
});
|
|
462
168
|
process.stdout.write("\r");
|
|
463
|
-
|
|
169
|
+
displayCheckResults("missing dependencies", directory, result);
|
|
464
170
|
}
|
|
465
171
|
if (checks.includes("file-extensions")) {
|
|
466
172
|
process.stdout.write(" checking file extensions...\n");
|
|
467
173
|
const result = await checkFileExtensions({
|
|
468
174
|
directory,
|
|
469
175
|
strict,
|
|
470
|
-
moduleResolution,
|
|
176
|
+
moduleResolution: "bundler",
|
|
471
177
|
onProgress
|
|
472
178
|
});
|
|
473
179
|
process.stdout.write("\r");
|
|
474
|
-
|
|
180
|
+
displayCheckResults("file extensions", directory, result);
|
|
475
181
|
}
|
|
476
182
|
if (checks.includes("path-extensions")) {
|
|
477
183
|
process.stdout.write(" checking import path extensions...\n");
|
|
478
184
|
const result = await checkPathExtensions({
|
|
479
185
|
directory,
|
|
480
186
|
strict,
|
|
481
|
-
moduleResolution,
|
|
187
|
+
moduleResolution: "bundler",
|
|
188
|
+
onProgress
|
|
189
|
+
});
|
|
190
|
+
process.stdout.write("\r");
|
|
191
|
+
displayCheckResults("path extensions", directory, result);
|
|
192
|
+
}
|
|
193
|
+
if (checks.includes("self-include")) {
|
|
194
|
+
process.stdout.write(" checking self-includes...\n");
|
|
195
|
+
const result = await checkSelfInclude({
|
|
196
|
+
directory,
|
|
197
|
+
strict,
|
|
198
|
+
moduleResolution: "bundler",
|
|
482
199
|
onProgress
|
|
483
200
|
});
|
|
484
201
|
process.stdout.write("\r");
|
|
485
|
-
|
|
202
|
+
displayCheckResults("self-includes", directory, result);
|
|
486
203
|
}
|
|
487
204
|
} catch (error) {
|
|
488
205
|
relinka(
|