@uniglot/wont-let-you-see 0.1.0 → 0.1.1
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/.github/CODEOWNERS +1 -0
- package/dist/index.js +32 -11
- package/package.json +1 -1
- package/src/__tests__/config.test.ts +90 -1
- package/src/config.ts +39 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @uniglot
|
package/dist/index.js
CHANGED
|
@@ -114,7 +114,7 @@ function getOriginal(sessionId, token) {
|
|
|
114
114
|
|
|
115
115
|
// src/config.ts
|
|
116
116
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
117
|
-
import { join as join2 } from "path";
|
|
117
|
+
import { join as join2, dirname } from "path";
|
|
118
118
|
import { homedir as homedir2 } from "os";
|
|
119
119
|
var DEFAULT_CONFIG = {
|
|
120
120
|
enabled: true,
|
|
@@ -122,18 +122,39 @@ var DEFAULT_CONFIG = {
|
|
|
122
122
|
customPatterns: []
|
|
123
123
|
};
|
|
124
124
|
var CONFIG_FILENAME = ".wont-let-you-see.json";
|
|
125
|
-
function
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
for (const configPath of paths) {
|
|
125
|
+
function findConfigInAncestors(startDir) {
|
|
126
|
+
const home = homedir2();
|
|
127
|
+
let currentDir = startDir;
|
|
128
|
+
while (true) {
|
|
129
|
+
const configPath = join2(currentDir, CONFIG_FILENAME);
|
|
131
130
|
if (existsSync2(configPath)) {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
131
|
+
return configPath;
|
|
132
|
+
}
|
|
133
|
+
if (currentDir === home) {
|
|
134
|
+
break;
|
|
136
135
|
}
|
|
136
|
+
const parentDir = dirname(currentDir);
|
|
137
|
+
if (parentDir === currentDir) {
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
currentDir = parentDir;
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
function loadJsonConfig() {
|
|
145
|
+
const ancestorConfig = findConfigInAncestors(process.cwd());
|
|
146
|
+
if (ancestorConfig) {
|
|
147
|
+
try {
|
|
148
|
+
const content = readFileSync2(ancestorConfig, "utf-8");
|
|
149
|
+
return JSON.parse(content);
|
|
150
|
+
} catch {}
|
|
151
|
+
}
|
|
152
|
+
const homeConfig = join2(homedir2(), CONFIG_FILENAME);
|
|
153
|
+
if (existsSync2(homeConfig)) {
|
|
154
|
+
try {
|
|
155
|
+
const content = readFileSync2(homeConfig, "utf-8");
|
|
156
|
+
return JSON.parse(content);
|
|
157
|
+
} catch {}
|
|
137
158
|
}
|
|
138
159
|
return {};
|
|
139
160
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,32 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
2
|
import { getConfig, resetConfig, isPatternEnabled } from "../config";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
|
|
6
|
+
vi.mock("fs", async () => {
|
|
7
|
+
const actual = await vi.importActual<typeof fs>("fs");
|
|
8
|
+
return {
|
|
9
|
+
...actual,
|
|
10
|
+
existsSync: vi.fn(),
|
|
11
|
+
readFileSync: vi.fn(),
|
|
12
|
+
};
|
|
13
|
+
});
|
|
3
14
|
|
|
4
15
|
describe("Config", () => {
|
|
5
16
|
const originalEnv = { ...process.env };
|
|
17
|
+
const originalCwd = process.cwd;
|
|
6
18
|
|
|
7
19
|
beforeEach(() => {
|
|
8
20
|
resetConfig();
|
|
21
|
+
vi.mocked(fs.existsSync).mockReturnValue(false);
|
|
22
|
+
vi.mocked(fs.readFileSync).mockReturnValue("{}");
|
|
9
23
|
});
|
|
10
24
|
|
|
11
25
|
afterEach(() => {
|
|
12
26
|
process.env = { ...originalEnv };
|
|
27
|
+
process.cwd = originalCwd;
|
|
13
28
|
resetConfig();
|
|
29
|
+
vi.clearAllMocks();
|
|
14
30
|
});
|
|
15
31
|
|
|
16
32
|
describe("getConfig", () => {
|
|
@@ -95,4 +111,77 @@ describe("Config", () => {
|
|
|
95
111
|
expect(isPatternEnabled("vpc")).toBe(true);
|
|
96
112
|
});
|
|
97
113
|
});
|
|
114
|
+
|
|
115
|
+
describe("ancestor directory config lookup", () => {
|
|
116
|
+
it("should find config in parent directory when cwd is subdirectory", () => {
|
|
117
|
+
process.cwd = () => "/project/packages/app";
|
|
118
|
+
|
|
119
|
+
vi.mocked(fs.existsSync).mockImplementation((p) => {
|
|
120
|
+
return p === path.join("/project", ".wont-let-you-see.json");
|
|
121
|
+
});
|
|
122
|
+
vi.mocked(fs.readFileSync).mockReturnValue(
|
|
123
|
+
JSON.stringify({ enabled: false, customPatterns: ["secret123"] }),
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
const config = getConfig();
|
|
127
|
+
expect(config.enabled).toBe(false);
|
|
128
|
+
expect(config.customPatterns).toEqual(["secret123"]);
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it("should find config in grandparent directory", () => {
|
|
132
|
+
process.cwd = () => "/project/packages/app/src/components";
|
|
133
|
+
|
|
134
|
+
vi.mocked(fs.existsSync).mockImplementation((p) => {
|
|
135
|
+
return p === path.join("/project", ".wont-let-you-see.json");
|
|
136
|
+
});
|
|
137
|
+
vi.mocked(fs.readFileSync).mockReturnValue(
|
|
138
|
+
JSON.stringify({ revealedPatterns: ["ipv4"] }),
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const config = getConfig();
|
|
142
|
+
expect(config.revealedPatterns).toEqual(["ipv4"]);
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it("should prefer config in closer ancestor over distant ancestor", () => {
|
|
146
|
+
process.cwd = () => "/project/packages/app";
|
|
147
|
+
|
|
148
|
+
vi.mocked(fs.existsSync).mockImplementation((p) => {
|
|
149
|
+
return (
|
|
150
|
+
p === path.join("/project/packages/app", ".wont-let-you-see.json") ||
|
|
151
|
+
p === path.join("/project", ".wont-let-you-see.json")
|
|
152
|
+
);
|
|
153
|
+
});
|
|
154
|
+
vi.mocked(fs.readFileSync).mockImplementation((p) => {
|
|
155
|
+
if (
|
|
156
|
+
p === path.join("/project/packages/app", ".wont-let-you-see.json")
|
|
157
|
+
) {
|
|
158
|
+
return JSON.stringify({ customPatterns: ["app-secret"] });
|
|
159
|
+
}
|
|
160
|
+
return JSON.stringify({ customPatterns: ["root-secret"] });
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const config = getConfig();
|
|
164
|
+
expect(config.customPatterns).toEqual(["app-secret"]);
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("should prefer cwd config over parent config", () => {
|
|
168
|
+
process.cwd = () => "/project/subdir";
|
|
169
|
+
|
|
170
|
+
vi.mocked(fs.existsSync).mockImplementation((p) => {
|
|
171
|
+
return (
|
|
172
|
+
p === path.join("/project/subdir", ".wont-let-you-see.json") ||
|
|
173
|
+
p === path.join("/project", ".wont-let-you-see.json")
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
vi.mocked(fs.readFileSync).mockImplementation((p) => {
|
|
177
|
+
if (p === path.join("/project/subdir", ".wont-let-you-see.json")) {
|
|
178
|
+
return JSON.stringify({ enabled: false });
|
|
179
|
+
}
|
|
180
|
+
return JSON.stringify({ enabled: true });
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
const config = getConfig();
|
|
184
|
+
expect(config.enabled).toBe(false);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
98
187
|
});
|
package/src/config.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "fs";
|
|
2
|
-
import { join } from "path";
|
|
2
|
+
import { join, dirname, parse } from "path";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
|
|
5
5
|
export interface Config {
|
|
@@ -16,19 +16,47 @@ const DEFAULT_CONFIG: Config = {
|
|
|
16
16
|
|
|
17
17
|
const CONFIG_FILENAME = ".wont-let-you-see.json";
|
|
18
18
|
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
join(homedir(), CONFIG_FILENAME),
|
|
23
|
-
];
|
|
19
|
+
function findConfigInAncestors(startDir: string): string | null {
|
|
20
|
+
const home = homedir();
|
|
21
|
+
let currentDir = startDir;
|
|
24
22
|
|
|
25
|
-
|
|
23
|
+
while (true) {
|
|
24
|
+
const configPath = join(currentDir, CONFIG_FILENAME);
|
|
26
25
|
if (existsSync(configPath)) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
return configPath;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (currentDir === home) {
|
|
30
|
+
break;
|
|
31
31
|
}
|
|
32
|
+
|
|
33
|
+
const parentDir = dirname(currentDir);
|
|
34
|
+
if (parentDir === currentDir) {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
currentDir = parentDir;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function loadJsonConfig(): Partial<Config> {
|
|
44
|
+
// First, search up from cwd to find nearest config
|
|
45
|
+
const ancestorConfig = findConfigInAncestors(process.cwd());
|
|
46
|
+
if (ancestorConfig) {
|
|
47
|
+
try {
|
|
48
|
+
const content = readFileSync(ancestorConfig, "utf-8");
|
|
49
|
+
return JSON.parse(content);
|
|
50
|
+
} catch {}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Fall back to home directory
|
|
54
|
+
const homeConfig = join(homedir(), CONFIG_FILENAME);
|
|
55
|
+
if (existsSync(homeConfig)) {
|
|
56
|
+
try {
|
|
57
|
+
const content = readFileSync(homeConfig, "utf-8");
|
|
58
|
+
return JSON.parse(content);
|
|
59
|
+
} catch {}
|
|
32
60
|
}
|
|
33
61
|
|
|
34
62
|
return {};
|