@rikalabs/repo-lint 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/bin/repo-lint +23 -0
- package/index.js +9 -0
- package/install.js +129 -0
- package/package.json +46 -0
- package/types/index.d.ts +74 -0
package/bin/repo-lint
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
|
|
7
|
+
const binName = process.platform === "win32" ? "repo-lint.exe" : "repo-lint";
|
|
8
|
+
const binPath = path.join(__dirname, binName);
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(binPath)) {
|
|
11
|
+
console.error("repo-lint binary not found. Try reinstalling the package:");
|
|
12
|
+
console.error(" npm install repo-lint");
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const child = spawn(binPath, process.argv.slice(2), {
|
|
17
|
+
stdio: "inherit",
|
|
18
|
+
shell: false,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
child.on("close", (code) => {
|
|
22
|
+
process.exit(code ?? 0);
|
|
23
|
+
});
|
package/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module.exports.defineConfig = (config) => config;
|
|
2
|
+
module.exports.dir = (children) => ({ type: "dir", children: children || {} });
|
|
3
|
+
module.exports.file = (pattern) => ({ type: "file", pattern });
|
|
4
|
+
module.exports.opt = (node) => ({ ...node, optional: true });
|
|
5
|
+
module.exports.param = (opts, child) => ({ type: "param", ...opts, child });
|
|
6
|
+
module.exports.many = (optsOrChild, child) => {
|
|
7
|
+
if (child) return { type: "many", ...optsOrChild, child };
|
|
8
|
+
return { type: "many", child: optsOrChild };
|
|
9
|
+
};
|
package/install.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { execSync, spawn } = require("child_process");
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const https = require("https");
|
|
7
|
+
const os = require("os");
|
|
8
|
+
const zlib = require("zlib");
|
|
9
|
+
|
|
10
|
+
const PACKAGE_VERSION = require("./package.json").version;
|
|
11
|
+
const REPO = "Rika-Labs/repo-lint";
|
|
12
|
+
const BIN_NAME = process.platform === "win32" ? "repo-lint.exe" : "repo-lint";
|
|
13
|
+
const BIN_DIR = path.join(__dirname, "bin");
|
|
14
|
+
const BIN_PATH = path.join(BIN_DIR, BIN_NAME);
|
|
15
|
+
|
|
16
|
+
function getPlatformInfo() {
|
|
17
|
+
const platform = os.platform();
|
|
18
|
+
const arch = os.arch();
|
|
19
|
+
|
|
20
|
+
const platformMap = {
|
|
21
|
+
darwin: {
|
|
22
|
+
x64: "repo-lint-darwin-x64",
|
|
23
|
+
arm64: "repo-lint-darwin-arm64",
|
|
24
|
+
},
|
|
25
|
+
linux: {
|
|
26
|
+
x64: "repo-lint-linux-x64",
|
|
27
|
+
arm64: "repo-lint-linux-arm64",
|
|
28
|
+
},
|
|
29
|
+
win32: {
|
|
30
|
+
x64: "repo-lint-windows-x64",
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const archMap = platformMap[platform];
|
|
35
|
+
if (!archMap) {
|
|
36
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const binaryName = archMap[arch];
|
|
40
|
+
if (!binaryName) {
|
|
41
|
+
throw new Error(`Unsupported architecture: ${arch} on ${platform}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const ext = platform === "win32" ? ".zip" : ".tar.gz";
|
|
45
|
+
return { binaryName, ext, platform };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function downloadFile(url) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
const handleResponse = (response) => {
|
|
51
|
+
if (response.statusCode === 302 || response.statusCode === 301) {
|
|
52
|
+
https.get(response.headers.location, handleResponse).on("error", reject);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (response.statusCode !== 200) {
|
|
57
|
+
reject(new Error(`Failed to download: ${response.statusCode}`));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const chunks = [];
|
|
62
|
+
response.on("data", (chunk) => chunks.push(chunk));
|
|
63
|
+
response.on("end", () => resolve(Buffer.concat(chunks)));
|
|
64
|
+
response.on("error", reject);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
https.get(url, handleResponse).on("error", reject);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function extractTarGz(buffer, destDir) {
|
|
72
|
+
const tar = require("tar");
|
|
73
|
+
const tmpFile = path.join(os.tmpdir(), `repo-lint-${Date.now()}.tar.gz`);
|
|
74
|
+
|
|
75
|
+
fs.writeFileSync(tmpFile, buffer);
|
|
76
|
+
|
|
77
|
+
await tar.extract({
|
|
78
|
+
file: tmpFile,
|
|
79
|
+
cwd: destDir,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
fs.unlinkSync(tmpFile);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function extractZip(buffer, destDir) {
|
|
86
|
+
const AdmZip = require("adm-zip");
|
|
87
|
+
const zip = new AdmZip(buffer);
|
|
88
|
+
zip.extractAllTo(destDir, true);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function install() {
|
|
92
|
+
try {
|
|
93
|
+
const { binaryName, ext, platform } = getPlatformInfo();
|
|
94
|
+
const version = `v${PACKAGE_VERSION}`;
|
|
95
|
+
const assetName = `${binaryName}${ext}`;
|
|
96
|
+
const url = `https://github.com/${REPO}/releases/download/${version}/${assetName}`;
|
|
97
|
+
|
|
98
|
+
console.log(`Downloading repo-lint ${version} for ${platform}...`);
|
|
99
|
+
|
|
100
|
+
if (!fs.existsSync(BIN_DIR)) {
|
|
101
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const buffer = await downloadFile(url);
|
|
105
|
+
|
|
106
|
+
console.log("Extracting...");
|
|
107
|
+
|
|
108
|
+
if (ext === ".tar.gz") {
|
|
109
|
+
await extractTarGz(buffer, BIN_DIR);
|
|
110
|
+
} else {
|
|
111
|
+
await extractZip(buffer, BIN_DIR);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (platform !== "win32") {
|
|
115
|
+
fs.chmodSync(BIN_PATH, 0o755);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
console.log(`repo-lint installed successfully to ${BIN_PATH}`);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error("Failed to install repo-lint binary:", error.message);
|
|
121
|
+
console.error("");
|
|
122
|
+
console.error("You can install manually:");
|
|
123
|
+
console.error(" - Download from: https://github.com/Rika-Labs/repo-lint/releases");
|
|
124
|
+
console.error(" - Or install via cargo: cargo install repo-lint");
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
install();
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rikalabs/repo-lint",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "High-performance filesystem layout linter with TypeScript DSL config",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/Rika-Labs/repo-lint"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/Rika-Labs/repo-lint",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/Rika-Labs/repo-lint/issues"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"linter",
|
|
16
|
+
"filesystem",
|
|
17
|
+
"structure",
|
|
18
|
+
"typescript",
|
|
19
|
+
"monorepo",
|
|
20
|
+
"architecture",
|
|
21
|
+
"lint"
|
|
22
|
+
],
|
|
23
|
+
"main": "index.js",
|
|
24
|
+
"types": "types/index.d.ts",
|
|
25
|
+
"bin": {
|
|
26
|
+
"repo-lint": "./bin/repo-lint"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"index.js",
|
|
30
|
+
"install.js",
|
|
31
|
+
"bin",
|
|
32
|
+
"types"
|
|
33
|
+
],
|
|
34
|
+
"scripts": {
|
|
35
|
+
"postinstall": "node install.js"
|
|
36
|
+
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"tar": "^7.0.0"
|
|
39
|
+
},
|
|
40
|
+
"optionalDependencies": {
|
|
41
|
+
"adm-zip": "^0.5.10"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=16"
|
|
45
|
+
}
|
|
46
|
+
}
|
package/types/index.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
export interface DefineConfigOptions {
|
|
2
|
+
mode?: "strict" | "warn";
|
|
3
|
+
layout: LayoutNode;
|
|
4
|
+
rules?: RulesConfig;
|
|
5
|
+
boundaries?: BoundariesConfig;
|
|
6
|
+
deps?: DepsConfig;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type LayoutNode =
|
|
10
|
+
| DirNode
|
|
11
|
+
| FileNode
|
|
12
|
+
| ParamNode
|
|
13
|
+
| ManyNode;
|
|
14
|
+
|
|
15
|
+
export interface DirNode {
|
|
16
|
+
type: "dir";
|
|
17
|
+
children: Record<string, LayoutNode>;
|
|
18
|
+
optional?: boolean;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FileNode {
|
|
22
|
+
type: "file";
|
|
23
|
+
pattern?: string;
|
|
24
|
+
optional?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface ParamNode {
|
|
28
|
+
type: "param";
|
|
29
|
+
name: string;
|
|
30
|
+
case: CaseStyle;
|
|
31
|
+
child: LayoutNode;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface ManyNode {
|
|
35
|
+
type: "many";
|
|
36
|
+
case?: CaseStyle;
|
|
37
|
+
child: LayoutNode;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type CaseStyle = "kebab" | "snake" | "camel" | "pascal" | "any";
|
|
41
|
+
|
|
42
|
+
export interface RulesConfig {
|
|
43
|
+
forbidPaths?: string[];
|
|
44
|
+
forbidNames?: string[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface BoundariesConfig {
|
|
48
|
+
modules: string;
|
|
49
|
+
publicApi: string;
|
|
50
|
+
forbidDeepImports?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface DepsAllowRule {
|
|
54
|
+
from: string;
|
|
55
|
+
to: string[];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface DepsConfig {
|
|
59
|
+
allow?: DepsAllowRule[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export function defineConfig(options: DefineConfigOptions): DefineConfigOptions;
|
|
63
|
+
|
|
64
|
+
export function dir(children?: Record<string, LayoutNode>): DirNode;
|
|
65
|
+
export function file(pattern?: string): FileNode;
|
|
66
|
+
export function opt<T extends LayoutNode>(node: T): T & { optional: true };
|
|
67
|
+
export function param(
|
|
68
|
+
options: { case: CaseStyle; name?: string },
|
|
69
|
+
child: LayoutNode
|
|
70
|
+
): ParamNode;
|
|
71
|
+
export function many(
|
|
72
|
+
options: { case?: CaseStyle } | LayoutNode,
|
|
73
|
+
child?: LayoutNode
|
|
74
|
+
): ManyNode;
|