oxlint-architecture-rules 0.1.0-beta.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/LICENSE +21 -0
- package/build/dts/adapters/cli/main.d.ts +3 -0
- package/build/dts/adapters/cli/main.d.ts.map +1 -0
- package/build/dts/adapters/cli/run.d.ts +19 -0
- package/build/dts/adapters/cli/run.d.ts.map +1 -0
- package/build/dts/adapters/cli/source-facts.d.ts +9 -0
- package/build/dts/adapters/cli/source-facts.d.ts.map +1 -0
- package/build/dts/adapters/cli/source-files.d.ts +2 -0
- package/build/dts/adapters/cli/source-files.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/config-loader.d.ts +23 -0
- package/build/dts/adapters/oxlint/config-loader.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/exports-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/exports-rule.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/imports-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/imports-rule.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/members-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/members-rule.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/oxlint-api.d.ts +19 -0
- package/build/dts/adapters/oxlint/oxlint-api.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/plugin.d.ts +15 -0
- package/build/dts/adapters/oxlint/plugin.d.ts.map +1 -0
- package/build/dts/adapters/oxlint/structure-rule.d.ts +4 -0
- package/build/dts/adapters/oxlint/structure-rule.d.ts.map +1 -0
- package/build/dts/core/baseline.d.ts +16 -0
- package/build/dts/core/baseline.d.ts.map +1 -0
- package/build/dts/core/exports.d.ts +39 -0
- package/build/dts/core/exports.d.ts.map +1 -0
- package/build/dts/core/imports.d.ts +27 -0
- package/build/dts/core/imports.d.ts.map +1 -0
- package/build/dts/core/members.d.ts +28 -0
- package/build/dts/core/members.d.ts.map +1 -0
- package/build/dts/core/patterns.d.ts +19 -0
- package/build/dts/core/patterns.d.ts.map +1 -0
- package/build/dts/core/structure.d.ts +48 -0
- package/build/dts/core/structure.d.ts.map +1 -0
- package/build/dts/domain/architecture-config.d.ts +177 -0
- package/build/dts/domain/architecture-config.d.ts.map +1 -0
- package/build/dts/domain/architecture-error.d.ts +27 -0
- package/build/dts/domain/architecture-error.d.ts.map +1 -0
- package/build/dts/domain/violation.d.ts +11 -0
- package/build/dts/domain/violation.d.ts.map +1 -0
- package/build/dts/index.d.ts +10 -0
- package/build/dts/index.d.ts.map +1 -0
- package/build/dts/infrastructure/file-system-fake.d.ts +3 -0
- package/build/dts/infrastructure/file-system-fake.d.ts.map +1 -0
- package/build/dts/infrastructure/file-system-live.d.ts +3 -0
- package/build/dts/infrastructure/file-system-live.d.ts.map +1 -0
- package/build/dts/infrastructure/module-resolver-fake.d.ts +3 -0
- package/build/dts/infrastructure/module-resolver-fake.d.ts.map +1 -0
- package/build/dts/infrastructure/module-resolver-live.d.ts +4 -0
- package/build/dts/infrastructure/module-resolver-live.d.ts.map +1 -0
- package/build/dts/manifest/compile.d.ts +16 -0
- package/build/dts/manifest/compile.d.ts.map +1 -0
- package/build/dts/manifest/glob.d.ts +14 -0
- package/build/dts/manifest/glob.d.ts.map +1 -0
- package/build/dts/manifest/manifest.d.ts +96 -0
- package/build/dts/manifest/manifest.d.ts.map +1 -0
- package/build/dts/ports/file-system.d.ts +4 -0
- package/build/dts/ports/file-system.d.ts.map +1 -0
- package/build/dts/ports/module-resolver.d.ts +11 -0
- package/build/dts/ports/module-resolver.d.ts.map +1 -0
- package/build/esm/adapters/cli/main.js +17 -0
- package/build/esm/adapters/cli/main.js.map +1 -0
- package/build/esm/adapters/cli/run.js +188 -0
- package/build/esm/adapters/cli/run.js.map +1 -0
- package/build/esm/adapters/cli/source-facts.js +117 -0
- package/build/esm/adapters/cli/source-facts.js.map +1 -0
- package/build/esm/adapters/cli/source-files.js +40 -0
- package/build/esm/adapters/cli/source-files.js.map +1 -0
- package/build/esm/adapters/oxlint/config-loader.js +81 -0
- package/build/esm/adapters/oxlint/config-loader.js.map +1 -0
- package/build/esm/adapters/oxlint/exports-rule.js +104 -0
- package/build/esm/adapters/oxlint/exports-rule.js.map +1 -0
- package/build/esm/adapters/oxlint/imports-rule.js +55 -0
- package/build/esm/adapters/oxlint/imports-rule.js.map +1 -0
- package/build/esm/adapters/oxlint/members-rule.js +75 -0
- package/build/esm/adapters/oxlint/members-rule.js.map +1 -0
- package/build/esm/adapters/oxlint/oxlint-api.js +7 -0
- package/build/esm/adapters/oxlint/oxlint-api.js.map +1 -0
- package/build/esm/adapters/oxlint/plugin.js +23 -0
- package/build/esm/adapters/oxlint/plugin.js.map +1 -0
- package/build/esm/adapters/oxlint/structure-rule.js +37 -0
- package/build/esm/adapters/oxlint/structure-rule.js.map +1 -0
- package/build/esm/core/baseline.js +30 -0
- package/build/esm/core/baseline.js.map +1 -0
- package/build/esm/core/exports.js +96 -0
- package/build/esm/core/exports.js.map +1 -0
- package/build/esm/core/imports.js +85 -0
- package/build/esm/core/imports.js.map +1 -0
- package/build/esm/core/members.js +84 -0
- package/build/esm/core/members.js.map +1 -0
- package/build/esm/core/patterns.js +78 -0
- package/build/esm/core/patterns.js.map +1 -0
- package/build/esm/core/structure.js +256 -0
- package/build/esm/core/structure.js.map +1 -0
- package/build/esm/domain/architecture-config.js +172 -0
- package/build/esm/domain/architecture-config.js.map +1 -0
- package/build/esm/domain/architecture-error.js +29 -0
- package/build/esm/domain/architecture-error.js.map +1 -0
- package/build/esm/domain/violation.js +8 -0
- package/build/esm/domain/violation.js.map +1 -0
- package/build/esm/index.js +8 -0
- package/build/esm/index.js.map +1 -0
- package/build/esm/infrastructure/file-system-fake.js +5 -0
- package/build/esm/infrastructure/file-system-fake.js.map +1 -0
- package/build/esm/infrastructure/file-system-live.js +19 -0
- package/build/esm/infrastructure/file-system-live.js.map +1 -0
- package/build/esm/infrastructure/module-resolver-fake.js +23 -0
- package/build/esm/infrastructure/module-resolver-fake.js.map +1 -0
- package/build/esm/infrastructure/module-resolver-live.js +71 -0
- package/build/esm/infrastructure/module-resolver-live.js.map +1 -0
- package/build/esm/manifest/compile.js +503 -0
- package/build/esm/manifest/compile.js.map +1 -0
- package/build/esm/manifest/glob.js +77 -0
- package/build/esm/manifest/glob.js.map +1 -0
- package/build/esm/manifest/manifest.js +120 -0
- package/build/esm/manifest/manifest.js.map +1 -0
- package/build/esm/ports/file-system.js +2 -0
- package/build/esm/ports/file-system.js.map +1 -0
- package/build/esm/ports/module-resolver.js +2 -0
- package/build/esm/ports/module-resolver.js.map +1 -0
- package/package.json +73 -0
- package/src/adapters/cli/main.ts +20 -0
- package/src/adapters/cli/run.ts +270 -0
- package/src/adapters/cli/source-facts.ts +137 -0
- package/src/adapters/cli/source-files.ts +42 -0
- package/src/adapters/oxlint/config-loader.ts +136 -0
- package/src/adapters/oxlint/exports-rule.ts +144 -0
- package/src/adapters/oxlint/imports-rule.ts +67 -0
- package/src/adapters/oxlint/members-rule.ts +114 -0
- package/src/adapters/oxlint/oxlint-api.ts +25 -0
- package/src/adapters/oxlint/plugin.ts +35 -0
- package/src/adapters/oxlint/structure-rule.ts +39 -0
- package/src/core/baseline.ts +62 -0
- package/src/core/exports.ts +164 -0
- package/src/core/imports.ts +138 -0
- package/src/core/members.ts +131 -0
- package/src/core/patterns.ts +122 -0
- package/src/core/structure.ts +348 -0
- package/src/domain/architecture-config.ts +206 -0
- package/src/domain/architecture-error.ts +43 -0
- package/src/domain/violation.ts +24 -0
- package/src/index.ts +28 -0
- package/src/infrastructure/file-system-fake.ts +6 -0
- package/src/infrastructure/file-system-live.ts +20 -0
- package/src/infrastructure/module-resolver-fake.ts +29 -0
- package/src/infrastructure/module-resolver-live.ts +100 -0
- package/src/manifest/compile.ts +736 -0
- package/src/manifest/glob.ts +108 -0
- package/src/manifest/manifest.ts +178 -0
- package/src/ports/file-system.ts +5 -0
- package/src/ports/module-resolver.ts +23 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as Result from "effect/Result";
|
|
2
|
+
|
|
3
|
+
import { ImportUnresolved } from "../domain/architecture-error.js";
|
|
4
|
+
import type { ModuleResolver, ResolvedTarget } from "../ports/module-resolver.js";
|
|
5
|
+
|
|
6
|
+
// Keyed by specifier alone: a core-evaluator test states the edges it is about
|
|
7
|
+
// and never the resolution algorithm, which has its own tests against the real
|
|
8
|
+
// resolver.
|
|
9
|
+
export const makeModuleResolverFake = (
|
|
10
|
+
targets: Readonly<Record<string, string>>,
|
|
11
|
+
): ModuleResolver => ({
|
|
12
|
+
resolve: (fromFile, specifier) => {
|
|
13
|
+
const path = targets[specifier];
|
|
14
|
+
if (path === undefined) {
|
|
15
|
+
return Result.fail(
|
|
16
|
+
new ImportUnresolved({ fromFile, specifier, detail: "not staged in the fake" }),
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
const target: ResolvedTarget = {
|
|
20
|
+
path,
|
|
21
|
+
kind: path.startsWith("node:")
|
|
22
|
+
? "builtin"
|
|
23
|
+
: path.includes("node_modules/")
|
|
24
|
+
? "external"
|
|
25
|
+
: "local",
|
|
26
|
+
};
|
|
27
|
+
return Result.succeed(target);
|
|
28
|
+
},
|
|
29
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
|
|
3
|
+
import * as Result from "effect/Result";
|
|
4
|
+
import { ResolverFactory } from "unrs-resolver";
|
|
5
|
+
|
|
6
|
+
import type { ResolveConfig } from "../domain/architecture-config.js";
|
|
7
|
+
import { ImportUnresolved } from "../domain/architecture-error.js";
|
|
8
|
+
import type { ModuleResolver, ResolvedTarget } from "../ports/module-resolver.js";
|
|
9
|
+
|
|
10
|
+
// `.js` in a NodeNext import specifier points at a `.ts` on disk. Without this,
|
|
11
|
+
// every relative import in the repo resolves to nothing and every path rule about
|
|
12
|
+
// it goes silently vacuous — the failure this package exists to make impossible.
|
|
13
|
+
const EXTENSION_ALIAS = {
|
|
14
|
+
".js": [".ts", ".tsx", ".js"],
|
|
15
|
+
".mjs": [".mts", ".mjs"],
|
|
16
|
+
".cjs": [".cts", ".cjs"],
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const DEFAULT_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".json"];
|
|
20
|
+
const DEFAULT_CONDITION_NAMES = ["import", "require", "node", "default"];
|
|
21
|
+
const DEFAULT_MAIN_FIELDS = ["main", "types"];
|
|
22
|
+
|
|
23
|
+
const toPosix = (value: string): string => value.replaceAll(path.sep, "/");
|
|
24
|
+
|
|
25
|
+
const toResolvedTarget = (repoRoot: string, absolutePath: string): ResolvedTarget => {
|
|
26
|
+
const relative = toPosix(path.relative(repoRoot, absolutePath));
|
|
27
|
+
return { path: relative, kind: relative.includes("node_modules/") ? "external" : "local" };
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
type Scope = {
|
|
31
|
+
readonly matches: RegExp;
|
|
32
|
+
readonly factory: ResolverFactory;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const makeModuleResolverLive = (repoRoot: string, config: ResolveConfig): ModuleResolver => {
|
|
36
|
+
const scopes: ReadonlyArray<Scope> = config.scopes.map((scope) => ({
|
|
37
|
+
matches: new RegExp(scope.files),
|
|
38
|
+
factory: new ResolverFactory({
|
|
39
|
+
tsconfig: { configFile: path.resolve(repoRoot, scope.tsconfig) },
|
|
40
|
+
extensions: [...(config.extensions ?? DEFAULT_EXTENSIONS)],
|
|
41
|
+
extensionAlias: EXTENSION_ALIAS,
|
|
42
|
+
conditionNames: [...(config.conditionNames ?? DEFAULT_CONDITION_NAMES)],
|
|
43
|
+
mainFields: [...(config.mainFields ?? DEFAULT_MAIN_FIELDS)],
|
|
44
|
+
builtinModules: true,
|
|
45
|
+
}),
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
const cache = new Map<string, Result.Result<ResolvedTarget, ImportUnresolved>>();
|
|
49
|
+
|
|
50
|
+
const resolveUncached = (
|
|
51
|
+
scope: Scope,
|
|
52
|
+
fromDirectory: string,
|
|
53
|
+
fromFile: string,
|
|
54
|
+
specifier: string,
|
|
55
|
+
): Result.Result<ResolvedTarget, ImportUnresolved> => {
|
|
56
|
+
const resolved = scope.factory.sync(fromDirectory, specifier);
|
|
57
|
+
|
|
58
|
+
const builtin = resolved.builtin;
|
|
59
|
+
if (builtin !== undefined) {
|
|
60
|
+
return Result.succeed({ path: builtin.resolved, kind: "builtin" });
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const resolvedPath = resolved.path;
|
|
64
|
+
if (resolvedPath === undefined) {
|
|
65
|
+
return Result.fail(
|
|
66
|
+
new ImportUnresolved({
|
|
67
|
+
fromFile,
|
|
68
|
+
specifier,
|
|
69
|
+
detail: resolved.error ?? "unknown resolution failure",
|
|
70
|
+
}),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return Result.succeed(toResolvedTarget(repoRoot, resolvedPath));
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
resolve: (fromFile, specifier) => {
|
|
79
|
+
const scope = scopes.find((candidate) => candidate.matches.test(fromFile));
|
|
80
|
+
if (scope === undefined) {
|
|
81
|
+
return Result.fail(
|
|
82
|
+
new ImportUnresolved({
|
|
83
|
+
fromFile,
|
|
84
|
+
specifier,
|
|
85
|
+
detail: "no resolve scope in the architecture config matches this file",
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const fromDirectory = path.resolve(repoRoot, path.dirname(fromFile));
|
|
91
|
+
const key = `${scope.matches.source} ${fromDirectory} ${specifier}`;
|
|
92
|
+
const cached = cache.get(key);
|
|
93
|
+
if (cached !== undefined) return cached;
|
|
94
|
+
|
|
95
|
+
const outcome = resolveUncached(scope, fromDirectory, fromFile, specifier);
|
|
96
|
+
cache.set(key, outcome);
|
|
97
|
+
return outcome;
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
};
|