@valbuild/cli 0.73.0 → 0.73.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.
@@ -9,6 +9,9 @@ var fastGlob = require('fast-glob');
|
|
9
9
|
var picocolors = require('picocolors');
|
10
10
|
var eslint = require('eslint');
|
11
11
|
var fs = require('fs/promises');
|
12
|
+
var vm = require('node:vm');
|
13
|
+
var ts = require('typescript');
|
14
|
+
var z = require('zod');
|
12
15
|
var fs$1 = require('fs');
|
13
16
|
|
14
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
@@ -36,12 +39,82 @@ var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
36
39
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
37
40
|
var picocolors__default = /*#__PURE__*/_interopDefault(picocolors);
|
38
41
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
42
|
+
var vm__default = /*#__PURE__*/_interopDefault(vm);
|
43
|
+
var ts__default = /*#__PURE__*/_interopDefault(ts);
|
44
|
+
var z__default = /*#__PURE__*/_interopDefault(z);
|
39
45
|
var fs__default$1 = /*#__PURE__*/_interopDefault(fs$1);
|
40
46
|
|
41
47
|
function error(message) {
|
42
48
|
console.error(chalk__default["default"].red("❌Error: ") + message);
|
43
49
|
}
|
44
50
|
|
51
|
+
const ValConfigSchema = z__default["default"].object({
|
52
|
+
project: z__default["default"].string().optional(),
|
53
|
+
root: z__default["default"].string().optional(),
|
54
|
+
files: z__default["default"].object({
|
55
|
+
directory: z__default["default"].string().refine(val => val.startsWith("/public/val"), {
|
56
|
+
message: "files.directory must start with '/public/val'"
|
57
|
+
})
|
58
|
+
}).optional(),
|
59
|
+
gitCommit: z__default["default"].string().optional(),
|
60
|
+
gitBranch: z__default["default"].string().optional(),
|
61
|
+
defaultTheme: z__default["default"].union([z__default["default"].literal("light"), z__default["default"].literal("dark")]).optional(),
|
62
|
+
ai: z__default["default"].object({
|
63
|
+
commitMessages: z__default["default"].object({
|
64
|
+
disabled: z__default["default"].boolean().optional()
|
65
|
+
}).optional()
|
66
|
+
}).optional()
|
67
|
+
});
|
68
|
+
async function evalValConfigFile(projectRoot, configFileName) {
|
69
|
+
const valConfigPath = path__default["default"].join(projectRoot, configFileName);
|
70
|
+
let code = null;
|
71
|
+
try {
|
72
|
+
code = await fs__default["default"].readFile(valConfigPath, "utf-8");
|
73
|
+
} catch (err) {
|
74
|
+
//
|
75
|
+
}
|
76
|
+
if (!code) {
|
77
|
+
return null;
|
78
|
+
}
|
79
|
+
const transpiled = ts__default["default"].transpileModule(code, {
|
80
|
+
compilerOptions: {
|
81
|
+
target: ts__default["default"].ScriptTarget.ES2020,
|
82
|
+
module: ts__default["default"].ModuleKind.CommonJS,
|
83
|
+
esModuleInterop: true
|
84
|
+
},
|
85
|
+
fileName: valConfigPath
|
86
|
+
});
|
87
|
+
const exportsObj = {};
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
89
|
+
const sandbox = {
|
90
|
+
exports: exportsObj,
|
91
|
+
module: {
|
92
|
+
exports: exportsObj
|
93
|
+
},
|
94
|
+
require,
|
95
|
+
// NOTE: this is a security risk, but this code is running in the users own environment at the CLI level
|
96
|
+
__filename: valConfigPath,
|
97
|
+
__dirname: path__default["default"].dirname(valConfigPath),
|
98
|
+
console,
|
99
|
+
process
|
100
|
+
};
|
101
|
+
sandbox.global = sandbox;
|
102
|
+
const context = vm__default["default"].createContext(sandbox);
|
103
|
+
const script = new vm__default["default"].Script(transpiled.outputText, {
|
104
|
+
filename: valConfigPath
|
105
|
+
});
|
106
|
+
script.runInContext(context);
|
107
|
+
const valConfig = sandbox.module.exports.config;
|
108
|
+
if (!valConfig) {
|
109
|
+
throw Error(`Val config file at path: '${valConfigPath}' must export a config object. Got: ${valConfig}`);
|
110
|
+
}
|
111
|
+
const result = ValConfigSchema.safeParse(valConfig);
|
112
|
+
if (!result.success) {
|
113
|
+
throw Error(`Val config file at path: '${valConfigPath}' has invalid schema: ${result.error.message}`);
|
114
|
+
}
|
115
|
+
return result.data;
|
116
|
+
}
|
117
|
+
|
45
118
|
async function validate({
|
46
119
|
root,
|
47
120
|
fix,
|
@@ -53,6 +126,8 @@ async function validate({
|
|
53
126
|
cwd: projectRoot,
|
54
127
|
ignore: false
|
55
128
|
});
|
129
|
+
const valConfigFile = (await evalValConfigFile(projectRoot, "val.config.ts")) || (await evalValConfigFile(projectRoot, "val.config.js"));
|
130
|
+
console.log(picocolors__default["default"].greenBright(`Validating project${valConfigFile !== null && valConfigFile !== void 0 && valConfigFile.project ? ` '${picocolors__default["default"].inverse(valConfigFile === null || valConfigFile === void 0 ? void 0 : valConfigFile.project)}'` : ""}...`));
|
56
131
|
const service = await server.createService(projectRoot, {});
|
57
132
|
const checkKeyIsValid = async (key, sourcePath) => {
|
58
133
|
const [moduleFilePath, modulePath] = core.Internal.splitModuleFilePathAndModulePath(sourcePath);
|
@@ -120,7 +195,7 @@ async function validate({
|
|
120
195
|
});
|
121
196
|
console.log(errors === 0 ? picocolors__default["default"].green("✔") : picocolors__default["default"].red("✘"), "ESlint complete", lintFiles.length, "files");
|
122
197
|
}
|
123
|
-
console.log("
|
198
|
+
console.log(picocolors__default["default"].greenBright(`Found ${valFiles.length} files...`));
|
124
199
|
let publicProjectId;
|
125
200
|
let didFix = false; // TODO: ugly
|
126
201
|
async function validateFile(file) {
|
@@ -208,7 +283,6 @@ async function validate({
|
|
208
283
|
if (valModule.source && valModule.schema) {
|
209
284
|
const resolvedRemoteFileAtSourcePath = core.Internal.resolvePath(modulePath, valModule.source, valModule.schema);
|
210
285
|
let filePath = null;
|
211
|
-
console.log(sourcePath, resolvedRemoteFileAtSourcePath.source);
|
212
286
|
try {
|
213
287
|
var _resolvedRemoteFileAt;
|
214
288
|
filePath = path__default["default"].join(projectRoot, // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
@@ -263,31 +337,7 @@ async function validate({
|
|
263
337
|
if (!publicProjectId || !remoteFileBuckets) {
|
264
338
|
let projectName = process.env.VAL_PROJECT;
|
265
339
|
if (!projectName) {
|
266
|
-
|
267
|
-
var _require;
|
268
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
269
|
-
projectName = (_require = require(`${root}/val.config`)) === null || _require === void 0 || (_require = _require.config) === null || _require === void 0 ? void 0 : _require.project;
|
270
|
-
} catch {
|
271
|
-
// ignore
|
272
|
-
}
|
273
|
-
}
|
274
|
-
if (!projectName) {
|
275
|
-
try {
|
276
|
-
var _require2;
|
277
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
278
|
-
projectName = (_require2 = require(`${root}/val.config.ts`)) === null || _require2 === void 0 || (_require2 = _require2.config) === null || _require2 === void 0 ? void 0 : _require2.project;
|
279
|
-
} catch {
|
280
|
-
// ignore
|
281
|
-
}
|
282
|
-
}
|
283
|
-
if (!projectName) {
|
284
|
-
try {
|
285
|
-
var _require3;
|
286
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
287
|
-
projectName = (_require3 = require(`${root}/val.config.js`)) === null || _require3 === void 0 || (_require3 = _require3.config) === null || _require3 === void 0 ? void 0 : _require3.project;
|
288
|
-
} catch {
|
289
|
-
// ignore
|
290
|
-
}
|
340
|
+
projectName = valConfigFile === null || valConfigFile === void 0 ? void 0 : valConfigFile.project;
|
291
341
|
}
|
292
342
|
if (!projectName) {
|
293
343
|
console.log(picocolors__default["default"].red("✘"), "Project name not found. Set VAL_PROJECT environment variable or add project name to val.config");
|
@@ -9,6 +9,9 @@ var fastGlob = require('fast-glob');
|
|
9
9
|
var picocolors = require('picocolors');
|
10
10
|
var eslint = require('eslint');
|
11
11
|
var fs = require('fs/promises');
|
12
|
+
var vm = require('node:vm');
|
13
|
+
var ts = require('typescript');
|
14
|
+
var z = require('zod');
|
12
15
|
var fs$1 = require('fs');
|
13
16
|
|
14
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
@@ -36,12 +39,82 @@ var chalk__default = /*#__PURE__*/_interopDefault(chalk);
|
|
36
39
|
var path__default = /*#__PURE__*/_interopDefault(path);
|
37
40
|
var picocolors__default = /*#__PURE__*/_interopDefault(picocolors);
|
38
41
|
var fs__default = /*#__PURE__*/_interopDefault(fs);
|
42
|
+
var vm__default = /*#__PURE__*/_interopDefault(vm);
|
43
|
+
var ts__default = /*#__PURE__*/_interopDefault(ts);
|
44
|
+
var z__default = /*#__PURE__*/_interopDefault(z);
|
39
45
|
var fs__default$1 = /*#__PURE__*/_interopDefault(fs$1);
|
40
46
|
|
41
47
|
function error(message) {
|
42
48
|
console.error(chalk__default["default"].red("❌Error: ") + message);
|
43
49
|
}
|
44
50
|
|
51
|
+
const ValConfigSchema = z__default["default"].object({
|
52
|
+
project: z__default["default"].string().optional(),
|
53
|
+
root: z__default["default"].string().optional(),
|
54
|
+
files: z__default["default"].object({
|
55
|
+
directory: z__default["default"].string().refine(val => val.startsWith("/public/val"), {
|
56
|
+
message: "files.directory must start with '/public/val'"
|
57
|
+
})
|
58
|
+
}).optional(),
|
59
|
+
gitCommit: z__default["default"].string().optional(),
|
60
|
+
gitBranch: z__default["default"].string().optional(),
|
61
|
+
defaultTheme: z__default["default"].union([z__default["default"].literal("light"), z__default["default"].literal("dark")]).optional(),
|
62
|
+
ai: z__default["default"].object({
|
63
|
+
commitMessages: z__default["default"].object({
|
64
|
+
disabled: z__default["default"].boolean().optional()
|
65
|
+
}).optional()
|
66
|
+
}).optional()
|
67
|
+
});
|
68
|
+
async function evalValConfigFile(projectRoot, configFileName) {
|
69
|
+
const valConfigPath = path__default["default"].join(projectRoot, configFileName);
|
70
|
+
let code = null;
|
71
|
+
try {
|
72
|
+
code = await fs__default["default"].readFile(valConfigPath, "utf-8");
|
73
|
+
} catch (err) {
|
74
|
+
//
|
75
|
+
}
|
76
|
+
if (!code) {
|
77
|
+
return null;
|
78
|
+
}
|
79
|
+
const transpiled = ts__default["default"].transpileModule(code, {
|
80
|
+
compilerOptions: {
|
81
|
+
target: ts__default["default"].ScriptTarget.ES2020,
|
82
|
+
module: ts__default["default"].ModuleKind.CommonJS,
|
83
|
+
esModuleInterop: true
|
84
|
+
},
|
85
|
+
fileName: valConfigPath
|
86
|
+
});
|
87
|
+
const exportsObj = {};
|
88
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
89
|
+
const sandbox = {
|
90
|
+
exports: exportsObj,
|
91
|
+
module: {
|
92
|
+
exports: exportsObj
|
93
|
+
},
|
94
|
+
require,
|
95
|
+
// NOTE: this is a security risk, but this code is running in the users own environment at the CLI level
|
96
|
+
__filename: valConfigPath,
|
97
|
+
__dirname: path__default["default"].dirname(valConfigPath),
|
98
|
+
console,
|
99
|
+
process
|
100
|
+
};
|
101
|
+
sandbox.global = sandbox;
|
102
|
+
const context = vm__default["default"].createContext(sandbox);
|
103
|
+
const script = new vm__default["default"].Script(transpiled.outputText, {
|
104
|
+
filename: valConfigPath
|
105
|
+
});
|
106
|
+
script.runInContext(context);
|
107
|
+
const valConfig = sandbox.module.exports.config;
|
108
|
+
if (!valConfig) {
|
109
|
+
throw Error(`Val config file at path: '${valConfigPath}' must export a config object. Got: ${valConfig}`);
|
110
|
+
}
|
111
|
+
const result = ValConfigSchema.safeParse(valConfig);
|
112
|
+
if (!result.success) {
|
113
|
+
throw Error(`Val config file at path: '${valConfigPath}' has invalid schema: ${result.error.message}`);
|
114
|
+
}
|
115
|
+
return result.data;
|
116
|
+
}
|
117
|
+
|
45
118
|
async function validate({
|
46
119
|
root,
|
47
120
|
fix,
|
@@ -53,6 +126,8 @@ async function validate({
|
|
53
126
|
cwd: projectRoot,
|
54
127
|
ignore: false
|
55
128
|
});
|
129
|
+
const valConfigFile = (await evalValConfigFile(projectRoot, "val.config.ts")) || (await evalValConfigFile(projectRoot, "val.config.js"));
|
130
|
+
console.log(picocolors__default["default"].greenBright(`Validating project${valConfigFile !== null && valConfigFile !== void 0 && valConfigFile.project ? ` '${picocolors__default["default"].inverse(valConfigFile === null || valConfigFile === void 0 ? void 0 : valConfigFile.project)}'` : ""}...`));
|
56
131
|
const service = await server.createService(projectRoot, {});
|
57
132
|
const checkKeyIsValid = async (key, sourcePath) => {
|
58
133
|
const [moduleFilePath, modulePath] = core.Internal.splitModuleFilePathAndModulePath(sourcePath);
|
@@ -120,7 +195,7 @@ async function validate({
|
|
120
195
|
});
|
121
196
|
console.log(errors === 0 ? picocolors__default["default"].green("✔") : picocolors__default["default"].red("✘"), "ESlint complete", lintFiles.length, "files");
|
122
197
|
}
|
123
|
-
console.log("
|
198
|
+
console.log(picocolors__default["default"].greenBright(`Found ${valFiles.length} files...`));
|
124
199
|
let publicProjectId;
|
125
200
|
let didFix = false; // TODO: ugly
|
126
201
|
async function validateFile(file) {
|
@@ -208,7 +283,6 @@ async function validate({
|
|
208
283
|
if (valModule.source && valModule.schema) {
|
209
284
|
const resolvedRemoteFileAtSourcePath = core.Internal.resolvePath(modulePath, valModule.source, valModule.schema);
|
210
285
|
let filePath = null;
|
211
|
-
console.log(sourcePath, resolvedRemoteFileAtSourcePath.source);
|
212
286
|
try {
|
213
287
|
var _resolvedRemoteFileAt;
|
214
288
|
filePath = path__default["default"].join(projectRoot, // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
@@ -263,31 +337,7 @@ async function validate({
|
|
263
337
|
if (!publicProjectId || !remoteFileBuckets) {
|
264
338
|
let projectName = process.env.VAL_PROJECT;
|
265
339
|
if (!projectName) {
|
266
|
-
|
267
|
-
var _require;
|
268
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
269
|
-
projectName = (_require = require(`${root}/val.config`)) === null || _require === void 0 || (_require = _require.config) === null || _require === void 0 ? void 0 : _require.project;
|
270
|
-
} catch {
|
271
|
-
// ignore
|
272
|
-
}
|
273
|
-
}
|
274
|
-
if (!projectName) {
|
275
|
-
try {
|
276
|
-
var _require2;
|
277
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
278
|
-
projectName = (_require2 = require(`${root}/val.config.ts`)) === null || _require2 === void 0 || (_require2 = _require2.config) === null || _require2 === void 0 ? void 0 : _require2.project;
|
279
|
-
} catch {
|
280
|
-
// ignore
|
281
|
-
}
|
282
|
-
}
|
283
|
-
if (!projectName) {
|
284
|
-
try {
|
285
|
-
var _require3;
|
286
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
287
|
-
projectName = (_require3 = require(`${root}/val.config.js`)) === null || _require3 === void 0 || (_require3 = _require3.config) === null || _require3 === void 0 ? void 0 : _require3.project;
|
288
|
-
} catch {
|
289
|
-
// ignore
|
290
|
-
}
|
340
|
+
projectName = valConfigFile === null || valConfigFile === void 0 ? void 0 : valConfigFile.project;
|
291
341
|
}
|
292
342
|
if (!projectName) {
|
293
343
|
console.log(picocolors__default["default"].red("✘"), "Project name not found. Set VAL_PROJECT environment variable or add project name to val.config");
|
@@ -7,12 +7,82 @@ import { glob } from 'fast-glob';
|
|
7
7
|
import picocolors from 'picocolors';
|
8
8
|
import { ESLint } from 'eslint';
|
9
9
|
import fs from 'fs/promises';
|
10
|
+
import vm from 'node:vm';
|
11
|
+
import ts from 'typescript';
|
12
|
+
import z from 'zod';
|
10
13
|
import fs$1 from 'fs';
|
11
14
|
|
12
15
|
function error(message) {
|
13
16
|
console.error(chalk.red("❌Error: ") + message);
|
14
17
|
}
|
15
18
|
|
19
|
+
const ValConfigSchema = z.object({
|
20
|
+
project: z.string().optional(),
|
21
|
+
root: z.string().optional(),
|
22
|
+
files: z.object({
|
23
|
+
directory: z.string().refine(val => val.startsWith("/public/val"), {
|
24
|
+
message: "files.directory must start with '/public/val'"
|
25
|
+
})
|
26
|
+
}).optional(),
|
27
|
+
gitCommit: z.string().optional(),
|
28
|
+
gitBranch: z.string().optional(),
|
29
|
+
defaultTheme: z.union([z.literal("light"), z.literal("dark")]).optional(),
|
30
|
+
ai: z.object({
|
31
|
+
commitMessages: z.object({
|
32
|
+
disabled: z.boolean().optional()
|
33
|
+
}).optional()
|
34
|
+
}).optional()
|
35
|
+
});
|
36
|
+
async function evalValConfigFile(projectRoot, configFileName) {
|
37
|
+
const valConfigPath = path.join(projectRoot, configFileName);
|
38
|
+
let code = null;
|
39
|
+
try {
|
40
|
+
code = await fs.readFile(valConfigPath, "utf-8");
|
41
|
+
} catch (err) {
|
42
|
+
//
|
43
|
+
}
|
44
|
+
if (!code) {
|
45
|
+
return null;
|
46
|
+
}
|
47
|
+
const transpiled = ts.transpileModule(code, {
|
48
|
+
compilerOptions: {
|
49
|
+
target: ts.ScriptTarget.ES2020,
|
50
|
+
module: ts.ModuleKind.CommonJS,
|
51
|
+
esModuleInterop: true
|
52
|
+
},
|
53
|
+
fileName: valConfigPath
|
54
|
+
});
|
55
|
+
const exportsObj = {};
|
56
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
57
|
+
const sandbox = {
|
58
|
+
exports: exportsObj,
|
59
|
+
module: {
|
60
|
+
exports: exportsObj
|
61
|
+
},
|
62
|
+
require,
|
63
|
+
// NOTE: this is a security risk, but this code is running in the users own environment at the CLI level
|
64
|
+
__filename: valConfigPath,
|
65
|
+
__dirname: path.dirname(valConfigPath),
|
66
|
+
console,
|
67
|
+
process
|
68
|
+
};
|
69
|
+
sandbox.global = sandbox;
|
70
|
+
const context = vm.createContext(sandbox);
|
71
|
+
const script = new vm.Script(transpiled.outputText, {
|
72
|
+
filename: valConfigPath
|
73
|
+
});
|
74
|
+
script.runInContext(context);
|
75
|
+
const valConfig = sandbox.module.exports.config;
|
76
|
+
if (!valConfig) {
|
77
|
+
throw Error(`Val config file at path: '${valConfigPath}' must export a config object. Got: ${valConfig}`);
|
78
|
+
}
|
79
|
+
const result = ValConfigSchema.safeParse(valConfig);
|
80
|
+
if (!result.success) {
|
81
|
+
throw Error(`Val config file at path: '${valConfigPath}' has invalid schema: ${result.error.message}`);
|
82
|
+
}
|
83
|
+
return result.data;
|
84
|
+
}
|
85
|
+
|
16
86
|
async function validate({
|
17
87
|
root,
|
18
88
|
fix,
|
@@ -24,6 +94,8 @@ async function validate({
|
|
24
94
|
cwd: projectRoot,
|
25
95
|
ignore: false
|
26
96
|
});
|
97
|
+
const valConfigFile = (await evalValConfigFile(projectRoot, "val.config.ts")) || (await evalValConfigFile(projectRoot, "val.config.js"));
|
98
|
+
console.log(picocolors.greenBright(`Validating project${valConfigFile !== null && valConfigFile !== void 0 && valConfigFile.project ? ` '${picocolors.inverse(valConfigFile === null || valConfigFile === void 0 ? void 0 : valConfigFile.project)}'` : ""}...`));
|
27
99
|
const service = await createService(projectRoot, {});
|
28
100
|
const checkKeyIsValid = async (key, sourcePath) => {
|
29
101
|
const [moduleFilePath, modulePath] = Internal.splitModuleFilePathAndModulePath(sourcePath);
|
@@ -91,7 +163,7 @@ async function validate({
|
|
91
163
|
});
|
92
164
|
console.log(errors === 0 ? picocolors.green("✔") : picocolors.red("✘"), "ESlint complete", lintFiles.length, "files");
|
93
165
|
}
|
94
|
-
console.log(
|
166
|
+
console.log(picocolors.greenBright(`Found ${valFiles.length} files...`));
|
95
167
|
let publicProjectId;
|
96
168
|
let didFix = false; // TODO: ugly
|
97
169
|
async function validateFile(file) {
|
@@ -179,7 +251,6 @@ async function validate({
|
|
179
251
|
if (valModule.source && valModule.schema) {
|
180
252
|
const resolvedRemoteFileAtSourcePath = Internal.resolvePath(modulePath, valModule.source, valModule.schema);
|
181
253
|
let filePath = null;
|
182
|
-
console.log(sourcePath, resolvedRemoteFileAtSourcePath.source);
|
183
254
|
try {
|
184
255
|
var _resolvedRemoteFileAt;
|
185
256
|
filePath = path.join(projectRoot, // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
@@ -234,31 +305,7 @@ async function validate({
|
|
234
305
|
if (!publicProjectId || !remoteFileBuckets) {
|
235
306
|
let projectName = process.env.VAL_PROJECT;
|
236
307
|
if (!projectName) {
|
237
|
-
|
238
|
-
var _require;
|
239
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
240
|
-
projectName = (_require = require(`${root}/val.config`)) === null || _require === void 0 || (_require = _require.config) === null || _require === void 0 ? void 0 : _require.project;
|
241
|
-
} catch {
|
242
|
-
// ignore
|
243
|
-
}
|
244
|
-
}
|
245
|
-
if (!projectName) {
|
246
|
-
try {
|
247
|
-
var _require2;
|
248
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
249
|
-
projectName = (_require2 = require(`${root}/val.config.ts`)) === null || _require2 === void 0 || (_require2 = _require2.config) === null || _require2 === void 0 ? void 0 : _require2.project;
|
250
|
-
} catch {
|
251
|
-
// ignore
|
252
|
-
}
|
253
|
-
}
|
254
|
-
if (!projectName) {
|
255
|
-
try {
|
256
|
-
var _require3;
|
257
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
258
|
-
projectName = (_require3 = require(`${root}/val.config.js`)) === null || _require3 === void 0 || (_require3 = _require3.config) === null || _require3 === void 0 ? void 0 : _require3.project;
|
259
|
-
} catch {
|
260
|
-
// ignore
|
261
|
-
}
|
308
|
+
projectName = valConfigFile === null || valConfigFile === void 0 ? void 0 : valConfigFile.project;
|
262
309
|
}
|
263
310
|
if (!projectName) {
|
264
311
|
console.log(picocolors.red("✘"), "Project name not found. Set VAL_PROJECT environment variable or add project name to val.config");
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@valbuild/cli",
|
3
3
|
"private": false,
|
4
|
-
"version": "0.73.
|
4
|
+
"version": "0.73.1",
|
5
5
|
"description": "Val CLI tools",
|
6
6
|
"bin": {
|
7
7
|
"val": "./bin.js"
|
@@ -18,9 +18,9 @@
|
|
18
18
|
"typecheck": "tsc --noEmit"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
|
-
"@valbuild/core": "~0.73.
|
22
|
-
"@valbuild/server": "~0.73.
|
23
|
-
"@valbuild/eslint-plugin": "~0.73.
|
21
|
+
"@valbuild/core": "~0.73.1",
|
22
|
+
"@valbuild/server": "~0.73.1",
|
23
|
+
"@valbuild/eslint-plugin": "~0.73.1",
|
24
24
|
"eslint": "^8.31.0",
|
25
25
|
"@inquirer/confirm": "^2.0.15",
|
26
26
|
"@inquirer/prompts": "^3.0.2",
|
@@ -34,7 +34,8 @@
|
|
34
34
|
"zod": "^3.22.4"
|
35
35
|
},
|
36
36
|
"peerDependencies": {
|
37
|
-
"prettier": "*"
|
37
|
+
"prettier": "*",
|
38
|
+
"typescript": ">=5.0.0"
|
38
39
|
},
|
39
40
|
"preconstruct": {
|
40
41
|
"entrypoints": [
|
@@ -0,0 +1,90 @@
|
|
1
|
+
import path from "path";
|
2
|
+
import fs from "fs/promises";
|
3
|
+
import vm from "node:vm";
|
4
|
+
import ts from "typescript"; // TODO: make this dependency optional (only required if the file is val.config.ts not val.config.js)
|
5
|
+
import z from "zod";
|
6
|
+
import { ValConfig } from "@valbuild/core";
|
7
|
+
|
8
|
+
const ValConfigSchema = z.object({
|
9
|
+
project: z.string().optional(),
|
10
|
+
root: z.string().optional(),
|
11
|
+
files: z
|
12
|
+
.object({
|
13
|
+
directory: z
|
14
|
+
.string()
|
15
|
+
.refine((val): val is `/public/val` => val.startsWith("/public/val"), {
|
16
|
+
message: "files.directory must start with '/public/val'",
|
17
|
+
}),
|
18
|
+
})
|
19
|
+
.optional(),
|
20
|
+
gitCommit: z.string().optional(),
|
21
|
+
gitBranch: z.string().optional(),
|
22
|
+
defaultTheme: z.union([z.literal("light"), z.literal("dark")]).optional(),
|
23
|
+
ai: z
|
24
|
+
.object({
|
25
|
+
commitMessages: z
|
26
|
+
.object({
|
27
|
+
disabled: z.boolean().optional(),
|
28
|
+
})
|
29
|
+
.optional(),
|
30
|
+
})
|
31
|
+
.optional(),
|
32
|
+
});
|
33
|
+
|
34
|
+
export async function evalValConfigFile(
|
35
|
+
projectRoot: string,
|
36
|
+
configFileName: string,
|
37
|
+
): Promise<ValConfig | null> {
|
38
|
+
const valConfigPath = path.join(projectRoot, configFileName);
|
39
|
+
|
40
|
+
let code: string | null = null;
|
41
|
+
try {
|
42
|
+
code = await fs.readFile(valConfigPath, "utf-8");
|
43
|
+
} catch (err) {
|
44
|
+
//
|
45
|
+
}
|
46
|
+
if (!code) {
|
47
|
+
return null;
|
48
|
+
}
|
49
|
+
|
50
|
+
const transpiled = ts.transpileModule(code, {
|
51
|
+
compilerOptions: {
|
52
|
+
target: ts.ScriptTarget.ES2020,
|
53
|
+
module: ts.ModuleKind.CommonJS,
|
54
|
+
esModuleInterop: true,
|
55
|
+
},
|
56
|
+
fileName: valConfigPath,
|
57
|
+
});
|
58
|
+
|
59
|
+
const exportsObj = {};
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
61
|
+
const sandbox: Record<string, any> = {
|
62
|
+
exports: exportsObj,
|
63
|
+
module: { exports: exportsObj },
|
64
|
+
require, // NOTE: this is a security risk, but this code is running in the users own environment at the CLI level
|
65
|
+
__filename: valConfigPath,
|
66
|
+
__dirname: path.dirname(valConfigPath),
|
67
|
+
console,
|
68
|
+
process,
|
69
|
+
};
|
70
|
+
sandbox.global = sandbox;
|
71
|
+
|
72
|
+
const context = vm.createContext(sandbox);
|
73
|
+
const script = new vm.Script(transpiled.outputText, {
|
74
|
+
filename: valConfigPath,
|
75
|
+
});
|
76
|
+
script.runInContext(context);
|
77
|
+
const valConfig = sandbox.module.exports.config;
|
78
|
+
if (!valConfig) {
|
79
|
+
throw Error(
|
80
|
+
`Val config file at path: '${valConfigPath}' must export a config object. Got: ${valConfig}`,
|
81
|
+
);
|
82
|
+
}
|
83
|
+
const result = ValConfigSchema.safeParse(valConfig);
|
84
|
+
if (!result.success) {
|
85
|
+
throw Error(
|
86
|
+
`Val config file at path: '${valConfigPath}' has invalid schema: ${result.error.message}`,
|
87
|
+
);
|
88
|
+
}
|
89
|
+
return result.data;
|
90
|
+
}
|
package/src/validate.ts
CHANGED
@@ -22,6 +22,7 @@ import { glob } from "fast-glob";
|
|
22
22
|
import picocolors from "picocolors";
|
23
23
|
import { ESLint } from "eslint";
|
24
24
|
import fs from "fs/promises";
|
25
|
+
import { evalValConfigFile } from "./utils/evalValConfigFile";
|
25
26
|
|
26
27
|
export async function validate({
|
27
28
|
root,
|
@@ -38,6 +39,14 @@ export async function validate({
|
|
38
39
|
cwd: projectRoot,
|
39
40
|
ignore: false,
|
40
41
|
});
|
42
|
+
const valConfigFile =
|
43
|
+
(await evalValConfigFile(projectRoot, "val.config.ts")) ||
|
44
|
+
(await evalValConfigFile(projectRoot, "val.config.js"));
|
45
|
+
console.log(
|
46
|
+
picocolors.greenBright(
|
47
|
+
`Validating project${valConfigFile?.project ? ` '${picocolors.inverse(valConfigFile?.project)}'` : ""}...`,
|
48
|
+
),
|
49
|
+
);
|
41
50
|
const service = await createService(projectRoot, {});
|
42
51
|
const checkKeyIsValid = async (
|
43
52
|
key: string,
|
@@ -130,8 +139,7 @@ export async function validate({
|
|
130
139
|
"files",
|
131
140
|
);
|
132
141
|
}
|
133
|
-
console.log(
|
134
|
-
|
142
|
+
console.log(picocolors.greenBright(`Found ${valFiles.length} files...`));
|
135
143
|
let publicProjectId: string | undefined;
|
136
144
|
let didFix = false; // TODO: ugly
|
137
145
|
async function validateFile(file: string): Promise<number> {
|
@@ -287,10 +295,6 @@ export async function validate({
|
|
287
295
|
valModule.schema,
|
288
296
|
);
|
289
297
|
let filePath: string | null = null;
|
290
|
-
console.log(
|
291
|
-
sourcePath,
|
292
|
-
resolvedRemoteFileAtSourcePath.source,
|
293
|
-
);
|
294
298
|
try {
|
295
299
|
filePath = path.join(
|
296
300
|
projectRoot,
|
@@ -383,31 +387,7 @@ export async function validate({
|
|
383
387
|
if (!publicProjectId || !remoteFileBuckets) {
|
384
388
|
let projectName = process.env.VAL_PROJECT;
|
385
389
|
if (!projectName) {
|
386
|
-
|
387
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
388
|
-
projectName = require(`${root}/val.config`)?.config
|
389
|
-
?.project;
|
390
|
-
} catch {
|
391
|
-
// ignore
|
392
|
-
}
|
393
|
-
}
|
394
|
-
if (!projectName) {
|
395
|
-
try {
|
396
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
397
|
-
projectName = require(`${root}/val.config.ts`)?.config
|
398
|
-
?.project;
|
399
|
-
} catch {
|
400
|
-
// ignore
|
401
|
-
}
|
402
|
-
}
|
403
|
-
if (!projectName) {
|
404
|
-
try {
|
405
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
406
|
-
projectName = require(`${root}/val.config.js`)?.config
|
407
|
-
?.project;
|
408
|
-
} catch {
|
409
|
-
// ignore
|
410
|
-
}
|
390
|
+
projectName = valConfigFile?.project;
|
411
391
|
}
|
412
392
|
if (!projectName) {
|
413
393
|
console.log(
|