Skip to content

Commit 3823848

Browse files
authored
feat: stable enforce values validation (#905)
* refactor: move `enforce` from `bin` to `services` * feat(cli): enforce values validation * ci: add tests * chore: safety never hurts * feat: ensure config file props * docs: add `enforce` stable documentation
1 parent 135bc20 commit 3823848

File tree

12 files changed

+329
-125
lines changed

12 files changed

+329
-125
lines changed

src/bin/enforce.ts

-51
This file was deleted.

src/bin/help.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@ const summary: [string, string][] = [
3434
['--watchInterval', 'Set an interval for watch events.'],
3535
];
3636
const sortedSummary = summary.sort(([a], [b]) => a.localeCompare(b));
37-
const largeEndPad = (() =>
38-
Math.max(...summary.map(([start]) => start.length)))();
37+
const largeEndPad = Math.max(...summary.map(([start]) => start.length));
3938

4039
const header = `
4140
🐷 ${format(' Poku — CLI Usage ').bg('brightMagenta')}

src/bin/index.ts

+37-47
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
#! /usr/bin/env node
2-
3-
import type { Configs } from '../@types/poku.js';
42
import { escapeRegExp } from '../modules/helpers/list-files.js';
53
import { getArg, getPaths, hasArg, argToArray } from '../parsers/get-arg.js';
64
import { states } from '../configs/files.js';
@@ -10,26 +8,25 @@ import { envFile } from '../modules/helpers/env.js';
108
import { poku } from '../modules/essentials/poku.js';
119
import { log, hr } from '../services/write.js';
1210
import { getConfigs } from '../parsers/options.js';
11+
import { GLOBAL, VERSION } from '../configs/poku.js';
1312

1413
(async () => {
1514
if (hasArg('version') || hasArg('v', '-')) {
16-
const { VERSION } = require('../configs/poku.js');
17-
1815
log(VERSION);
1916
return;
2017
}
2118

2219
if (hasArg('help') || hasArg('h', '-')) {
23-
const { help } = require('./help.js');
24-
25-
help();
26-
20+
require('./help.js').help();
2721
return;
2822
}
2923

3024
const enforce = hasArg('enforce') || hasArg('x', '-');
3125
const configFile = getArg('config') || getArg('c', '-');
32-
const defaultConfigs = await getConfigs(configFile);
26+
27+
GLOBAL.defaultConfigs = await getConfigs(configFile);
28+
const { defaultConfigs } = GLOBAL;
29+
3330
const dirs: string[] =
3431
getPaths('-') ??
3532
(defaultConfigs?.include
@@ -98,13 +95,36 @@ import { getConfigs } from '../parsers/options.js';
9895
return;
9996
}
10097

101-
if (enforce) {
102-
const { checkFlags } = require('./enforce.js');
98+
GLOBAL.configFile = configFile;
99+
GLOBAL.options = {
100+
filter:
101+
typeof filter === 'string' ? new RegExp(escapeRegExp(filter)) : filter,
102+
exclude:
103+
typeof exclude === 'string' ? new RegExp(escapeRegExp(exclude)) : exclude,
104+
concurrency,
105+
sequential,
106+
quiet,
107+
debug,
108+
failFast,
109+
deno: {
110+
allow: denoAllow,
111+
deny: denoDeny,
112+
cjs: denoCJS,
113+
},
114+
noExit: watchMode,
115+
beforeEach:
116+
'beforeEach' in defaultConfigs ? defaultConfigs.beforeEach : undefined,
117+
afterEach:
118+
'afterEach' in defaultConfigs ? defaultConfigs.afterEach : undefined,
119+
};
120+
121+
const tasks: Promise<unknown>[] = [];
103122

104-
checkFlags();
123+
if (hasEnvFile || defaultConfigs?.envFile) {
124+
GLOBAL.envFile = getArg('envFile') ?? defaultConfigs?.envFile ?? '.env';
105125
}
106126

107-
const tasks: Promise<unknown>[] = [];
127+
if (enforce) require('../services/enforce.js').enforce();
108128

109129
/* c8 ignore start */ // Process-based
110130
if (killPort || defaultConfigs?.kill?.port) {
@@ -135,33 +155,7 @@ import { getConfigs } from '../parsers/options.js';
135155
}
136156
/* c8 ignore stop */
137157

138-
if (hasEnvFile || defaultConfigs?.envFile) {
139-
const envFilePath = getArg('envFile') ?? defaultConfigs?.envFile;
140-
141-
tasks.push(envFile(envFilePath));
142-
}
143-
144-
const options: Configs = {
145-
filter:
146-
typeof filter === 'string' ? new RegExp(escapeRegExp(filter)) : filter,
147-
exclude:
148-
typeof exclude === 'string' ? new RegExp(escapeRegExp(exclude)) : exclude,
149-
concurrency,
150-
sequential,
151-
quiet,
152-
debug,
153-
failFast,
154-
deno: {
155-
allow: denoAllow,
156-
deny: denoDeny,
157-
cjs: denoCJS,
158-
},
159-
noExit: watchMode,
160-
beforeEach:
161-
'beforeEach' in defaultConfigs ? defaultConfigs.beforeEach : undefined,
162-
afterEach:
163-
'afterEach' in defaultConfigs ? defaultConfigs.afterEach : undefined,
164-
};
158+
GLOBAL.envFile && tasks.push(envFile(GLOBAL.envFile));
165159

166160
if (debug || defaultConfigs?.debug) {
167161
hr();
@@ -170,15 +164,11 @@ import { getConfigs } from '../parsers/options.js';
170164
console.table(dirs);
171165
log('\n');
172166
log(`${format('…').info().italic()} ${format('Options').bold()}`);
173-
console.dir(options, { depth: null, colors: true });
167+
console.dir(GLOBAL.options, { depth: null, colors: true });
174168
}
175169

176170
await Promise.all(tasks);
177-
await poku(dirs, options);
178-
179-
if (watchMode) {
180-
const { startWatch } = require('./watch.js');
171+
await poku(dirs, GLOBAL.options);
181172

182-
await startWatch(dirs, options);
183-
}
173+
if (watchMode) await require('./watch.js').startWatch(dirs, GLOBAL.options);
184174
})();

src/configs/files.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { FileResults } from '../@types/list-files.js';
22
import type { FinalResults, States } from '../@types/poku.js';
33

4-
export const states = {} as States;
4+
export const states = Object.create(null) as States;
55

66
export const fileResults: FileResults = {
77
success: new Map(),
88
fail: new Map(),
99
};
1010

11-
export const finalResults = {} as FinalResults;
11+
export const finalResults = Object.create(null) as FinalResults;

src/configs/poku.ts

+5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { env, cwd } from 'node:process';
2+
import type { ConfigFile, ConfigJSONFile, Configs } from '../@types/poku.js';
23

34
export const results = {
45
success: 0,
@@ -16,4 +17,8 @@ export const GLOBAL = {
1617
runAsOnly: false,
1718
isPoku: typeof env?.POKU_FILE === 'string' && env?.POKU_FILE.length > 0,
1819
FILE: env.POKU_FILE,
20+
options: Object.create(null) as Configs,
21+
configFile: undefined as string | undefined,
22+
defaultConfigs: Object.create(null) as ConfigFile | ConfigJSONFile,
23+
envFile: undefined as string | undefined,
1924
};

src/modules/helpers/describe.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ export async function describeBase(
2929
if (title) {
3030
indentation.hasDescribe = true;
3131

32-
const { background, icon } = options ?? {};
32+
const { background, icon } =
33+
options ?? (Object.create(null) as DescribeOptions);
3334
const message = `${cb ? format('◌').dim() : (icon ?? '☰')} ${cb ? format(title).dim() : format(title).bold()}`;
3435
const noBackground = !background;
3536

src/parsers/options.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { normalize, join } from 'node:path';
33
import { readFile } from 'node:fs/promises';
44
import { JSONC } from '../polyfills/jsonc.js';
55
import { GLOBAL } from '../configs/poku.js';
6+
import { isWindows } from './get-runner.js';
67

78
export const getConfigs = async (
89
customPath?: string
@@ -18,16 +19,20 @@ export const getConfigs = async (
1819

1920
for (const file of expectedFiles) {
2021
const filePath = join(GLOBAL.cwd, file);
22+
let path = '';
23+
24+
if (isWindows) path += 'file://';
25+
path += normalize(filePath);
2126

2227
try {
2328
if (filePath.endsWith('.js') || filePath.endsWith('.cjs'))
24-
return require(`file://${normalize(filePath)}`);
29+
return require(path);
2530

2631
const configsFile = await readFile(filePath, 'utf8');
2732

2833
return JSONC.parse<ConfigJSONFile>(configsFile);
2934
} catch {}
3035
}
3136

32-
return {};
37+
return Object.create(null);
3338
};

0 commit comments

Comments
 (0)