@valbuild/cli 0.60.9 → 0.60.11
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/cli/dist/valbuild-cli-cli.cjs.dev.js +111 -6
- package/cli/dist/valbuild-cli-cli.cjs.prod.js +111 -6
- package/cli/dist/valbuild-cli-cli.esm.js +111 -6
- package/package.json +4 -3
- package/src/cli.ts +44 -6
- package/src/files.ts +99 -0
@@ -8,6 +8,7 @@ var fastGlob = require('fast-glob');
|
|
8
8
|
var picocolors = require('picocolors');
|
9
9
|
var eslint = require('eslint');
|
10
10
|
var fs = require('fs/promises');
|
11
|
+
var core = require('@valbuild/core');
|
11
12
|
|
12
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
13
14
|
|
@@ -143,23 +144,112 @@ function logEslintMessage(fileContent, filePath, eslintMessage) {
|
|
143
144
|
lineAfter && console.log(picocolors__default["default"].gray(" " + (eslintMessage.line + 1) + " |"), lineAfter);
|
144
145
|
}
|
145
146
|
|
147
|
+
async function files({
|
148
|
+
root,
|
149
|
+
cfg,
|
150
|
+
managedDir
|
151
|
+
}) {
|
152
|
+
const printFilesUsedByVal = !managedDir;
|
153
|
+
const projectRoot = root ? path__default["default"].resolve(root) : process.cwd();
|
154
|
+
const service = await server.createService(projectRoot, {
|
155
|
+
valConfigPath: cfg ?? "./val.config"
|
156
|
+
});
|
157
|
+
const valFiles = await fastGlob.glob("**/*.val.{js,ts}", {
|
158
|
+
ignore: ["node_modules/**"],
|
159
|
+
cwd: projectRoot
|
160
|
+
});
|
161
|
+
const absoluteFilesPathUsedByVal = [];
|
162
|
+
async function printOrGetFileRefs(file) {
|
163
|
+
const moduleId = `/${file}`.replace(/(\.val\.(ts|js))$/, ""); // TODO: check if this always works? (Windows?)
|
164
|
+
const valModule = await service.get(moduleId, "");
|
165
|
+
// TODO: not sure using validation is the best way to do this, but it works currently.
|
166
|
+
if (valModule.errors) {
|
167
|
+
if (valModule.errors.validation) {
|
168
|
+
for (const sourcePathS in valModule.errors.validation) {
|
169
|
+
const sourcePath = sourcePathS;
|
170
|
+
const validationError = valModule.errors.validation[sourcePath];
|
171
|
+
for (const error of validationError) {
|
172
|
+
const value = error.value;
|
173
|
+
if (isFileRef(value)) {
|
174
|
+
const absoluteFilePathUsedByVal = path__default["default"].join(projectRoot, ...value[core.FILE_REF_PROP].split("/"));
|
175
|
+
if (printFilesUsedByVal) {
|
176
|
+
console.log(absoluteFilePathUsedByVal);
|
177
|
+
} else {
|
178
|
+
absoluteFilesPathUsedByVal.push(absoluteFilePathUsedByVal);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
for (const file of valFiles) {
|
187
|
+
await printOrGetFileRefs(file);
|
188
|
+
}
|
189
|
+
if (managedDir) {
|
190
|
+
const managedRoot = path__default["default"].isAbsolute(managedDir) ? managedDir : path__default["default"].join(projectRoot, managedDir);
|
191
|
+
const allFilesInManagedDir = await fastGlob.glob("**/*", {
|
192
|
+
ignore: ["node_modules/**"],
|
193
|
+
cwd: managedRoot
|
194
|
+
});
|
195
|
+
for (const file of allFilesInManagedDir) {
|
196
|
+
const absoluteFilePath = path__default["default"].join(managedRoot, file);
|
197
|
+
if (!absoluteFilesPathUsedByVal.includes(absoluteFilePath)) {
|
198
|
+
console.log(path__default["default"].join(managedRoot, file));
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
service.dispose();
|
203
|
+
return;
|
204
|
+
}
|
205
|
+
function isFileRef(value) {
|
206
|
+
if (!value) return false;
|
207
|
+
if (typeof value !== "object") return false;
|
208
|
+
if (core.FILE_REF_PROP in value && core.VAL_EXTENSION in value) {
|
209
|
+
if (value[core.VAL_EXTENSION] === "file" && typeof value[core.FILE_REF_PROP] === "string") {
|
210
|
+
return true;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
return false;
|
214
|
+
}
|
215
|
+
|
146
216
|
async function main() {
|
147
217
|
const {
|
148
218
|
input,
|
149
219
|
flags,
|
150
220
|
showHelp
|
151
221
|
} = meow__default["default"](`
|
152
|
-
Usage
|
222
|
+
Usage:
|
153
223
|
$ val [command]
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
Options
|
224
|
+
|
225
|
+
Options:
|
158
226
|
--help Show this message
|
227
|
+
|
228
|
+
Commands:
|
229
|
+
validate
|
230
|
+
list-files
|
231
|
+
|
232
|
+
Command: validate
|
233
|
+
Description: val-idate val modules
|
234
|
+
Options:
|
159
235
|
--root [root], -r [root] Set project root directory (default process.cwd())
|
160
236
|
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
161
237
|
--fix [fix] Attempt to fix validation errors
|
162
|
-
--noEslint [noEslint] Disable eslint validation
|
238
|
+
--noEslint [noEslint] Disable eslint validation during validate
|
239
|
+
|
240
|
+
|
241
|
+
Command: files
|
242
|
+
Description: EXPERIMENTAL.
|
243
|
+
Perform file operations in Val.
|
244
|
+
By default it lists files (images, ...) currently in use by Val.
|
245
|
+
|
246
|
+
If a managed directory is specified,
|
247
|
+
it will list all files in the managed directory that ARE NOT currently used by Val.
|
248
|
+
This is useful for cleaning up unused files.
|
249
|
+
Options:
|
250
|
+
--managedDir [dir] If set, list files found in directory that are not managed by Val
|
251
|
+
--root [root], -r [root] Set project root directory (default process.cwd())
|
252
|
+
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
163
253
|
`, {
|
164
254
|
flags: {
|
165
255
|
port: {
|
@@ -180,6 +270,9 @@ async function main() {
|
|
180
270
|
},
|
181
271
|
noEslint: {
|
182
272
|
type: "boolean"
|
273
|
+
},
|
274
|
+
managedDir: {
|
275
|
+
type: "string"
|
183
276
|
}
|
184
277
|
},
|
185
278
|
hardRejection: false
|
@@ -192,8 +285,20 @@ async function main() {
|
|
192
285
|
}
|
193
286
|
const [command] = input;
|
194
287
|
switch (command) {
|
288
|
+
case "files":
|
289
|
+
if (flags.fix || flags.noEslint) {
|
290
|
+
return error(`Command "files" does not support --fix or --noEslint flags`);
|
291
|
+
}
|
292
|
+
return files({
|
293
|
+
root: flags.root,
|
294
|
+
cfg: flags.cfg,
|
295
|
+
managedDir: flags.managedDir
|
296
|
+
});
|
195
297
|
case "validate":
|
196
298
|
case "idate":
|
299
|
+
if (flags.managedDir) {
|
300
|
+
return error(`Command "validate" does not support --managedDir flag`);
|
301
|
+
}
|
197
302
|
return validate({
|
198
303
|
root: flags.root,
|
199
304
|
cfg: flags.cfg,
|
@@ -8,6 +8,7 @@ var fastGlob = require('fast-glob');
|
|
8
8
|
var picocolors = require('picocolors');
|
9
9
|
var eslint = require('eslint');
|
10
10
|
var fs = require('fs/promises');
|
11
|
+
var core = require('@valbuild/core');
|
11
12
|
|
12
13
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
13
14
|
|
@@ -143,23 +144,112 @@ function logEslintMessage(fileContent, filePath, eslintMessage) {
|
|
143
144
|
lineAfter && console.log(picocolors__default["default"].gray(" " + (eslintMessage.line + 1) + " |"), lineAfter);
|
144
145
|
}
|
145
146
|
|
147
|
+
async function files({
|
148
|
+
root,
|
149
|
+
cfg,
|
150
|
+
managedDir
|
151
|
+
}) {
|
152
|
+
const printFilesUsedByVal = !managedDir;
|
153
|
+
const projectRoot = root ? path__default["default"].resolve(root) : process.cwd();
|
154
|
+
const service = await server.createService(projectRoot, {
|
155
|
+
valConfigPath: cfg ?? "./val.config"
|
156
|
+
});
|
157
|
+
const valFiles = await fastGlob.glob("**/*.val.{js,ts}", {
|
158
|
+
ignore: ["node_modules/**"],
|
159
|
+
cwd: projectRoot
|
160
|
+
});
|
161
|
+
const absoluteFilesPathUsedByVal = [];
|
162
|
+
async function printOrGetFileRefs(file) {
|
163
|
+
const moduleId = `/${file}`.replace(/(\.val\.(ts|js))$/, ""); // TODO: check if this always works? (Windows?)
|
164
|
+
const valModule = await service.get(moduleId, "");
|
165
|
+
// TODO: not sure using validation is the best way to do this, but it works currently.
|
166
|
+
if (valModule.errors) {
|
167
|
+
if (valModule.errors.validation) {
|
168
|
+
for (const sourcePathS in valModule.errors.validation) {
|
169
|
+
const sourcePath = sourcePathS;
|
170
|
+
const validationError = valModule.errors.validation[sourcePath];
|
171
|
+
for (const error of validationError) {
|
172
|
+
const value = error.value;
|
173
|
+
if (isFileRef(value)) {
|
174
|
+
const absoluteFilePathUsedByVal = path__default["default"].join(projectRoot, ...value[core.FILE_REF_PROP].split("/"));
|
175
|
+
if (printFilesUsedByVal) {
|
176
|
+
console.log(absoluteFilePathUsedByVal);
|
177
|
+
} else {
|
178
|
+
absoluteFilesPathUsedByVal.push(absoluteFilePathUsedByVal);
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
183
|
+
}
|
184
|
+
}
|
185
|
+
}
|
186
|
+
for (const file of valFiles) {
|
187
|
+
await printOrGetFileRefs(file);
|
188
|
+
}
|
189
|
+
if (managedDir) {
|
190
|
+
const managedRoot = path__default["default"].isAbsolute(managedDir) ? managedDir : path__default["default"].join(projectRoot, managedDir);
|
191
|
+
const allFilesInManagedDir = await fastGlob.glob("**/*", {
|
192
|
+
ignore: ["node_modules/**"],
|
193
|
+
cwd: managedRoot
|
194
|
+
});
|
195
|
+
for (const file of allFilesInManagedDir) {
|
196
|
+
const absoluteFilePath = path__default["default"].join(managedRoot, file);
|
197
|
+
if (!absoluteFilesPathUsedByVal.includes(absoluteFilePath)) {
|
198
|
+
console.log(path__default["default"].join(managedRoot, file));
|
199
|
+
}
|
200
|
+
}
|
201
|
+
}
|
202
|
+
service.dispose();
|
203
|
+
return;
|
204
|
+
}
|
205
|
+
function isFileRef(value) {
|
206
|
+
if (!value) return false;
|
207
|
+
if (typeof value !== "object") return false;
|
208
|
+
if (core.FILE_REF_PROP in value && core.VAL_EXTENSION in value) {
|
209
|
+
if (value[core.VAL_EXTENSION] === "file" && typeof value[core.FILE_REF_PROP] === "string") {
|
210
|
+
return true;
|
211
|
+
}
|
212
|
+
}
|
213
|
+
return false;
|
214
|
+
}
|
215
|
+
|
146
216
|
async function main() {
|
147
217
|
const {
|
148
218
|
input,
|
149
219
|
flags,
|
150
220
|
showHelp
|
151
221
|
} = meow__default["default"](`
|
152
|
-
Usage
|
222
|
+
Usage:
|
153
223
|
$ val [command]
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
Options
|
224
|
+
|
225
|
+
Options:
|
158
226
|
--help Show this message
|
227
|
+
|
228
|
+
Commands:
|
229
|
+
validate
|
230
|
+
list-files
|
231
|
+
|
232
|
+
Command: validate
|
233
|
+
Description: val-idate val modules
|
234
|
+
Options:
|
159
235
|
--root [root], -r [root] Set project root directory (default process.cwd())
|
160
236
|
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
161
237
|
--fix [fix] Attempt to fix validation errors
|
162
|
-
--noEslint [noEslint] Disable eslint validation
|
238
|
+
--noEslint [noEslint] Disable eslint validation during validate
|
239
|
+
|
240
|
+
|
241
|
+
Command: files
|
242
|
+
Description: EXPERIMENTAL.
|
243
|
+
Perform file operations in Val.
|
244
|
+
By default it lists files (images, ...) currently in use by Val.
|
245
|
+
|
246
|
+
If a managed directory is specified,
|
247
|
+
it will list all files in the managed directory that ARE NOT currently used by Val.
|
248
|
+
This is useful for cleaning up unused files.
|
249
|
+
Options:
|
250
|
+
--managedDir [dir] If set, list files found in directory that are not managed by Val
|
251
|
+
--root [root], -r [root] Set project root directory (default process.cwd())
|
252
|
+
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
163
253
|
`, {
|
164
254
|
flags: {
|
165
255
|
port: {
|
@@ -180,6 +270,9 @@ async function main() {
|
|
180
270
|
},
|
181
271
|
noEslint: {
|
182
272
|
type: "boolean"
|
273
|
+
},
|
274
|
+
managedDir: {
|
275
|
+
type: "string"
|
183
276
|
}
|
184
277
|
},
|
185
278
|
hardRejection: false
|
@@ -192,8 +285,20 @@ async function main() {
|
|
192
285
|
}
|
193
286
|
const [command] = input;
|
194
287
|
switch (command) {
|
288
|
+
case "files":
|
289
|
+
if (flags.fix || flags.noEslint) {
|
290
|
+
return error(`Command "files" does not support --fix or --noEslint flags`);
|
291
|
+
}
|
292
|
+
return files({
|
293
|
+
root: flags.root,
|
294
|
+
cfg: flags.cfg,
|
295
|
+
managedDir: flags.managedDir
|
296
|
+
});
|
195
297
|
case "validate":
|
196
298
|
case "idate":
|
299
|
+
if (flags.managedDir) {
|
300
|
+
return error(`Command "validate" does not support --managedDir flag`);
|
301
|
+
}
|
197
302
|
return validate({
|
198
303
|
root: flags.root,
|
199
304
|
cfg: flags.cfg,
|
@@ -6,6 +6,7 @@ import { glob } from 'fast-glob';
|
|
6
6
|
import picocolors from 'picocolors';
|
7
7
|
import { ESLint } from 'eslint';
|
8
8
|
import fs from 'fs/promises';
|
9
|
+
import { FILE_REF_PROP, VAL_EXTENSION } from '@valbuild/core';
|
9
10
|
|
10
11
|
function error(message) {
|
11
12
|
console.error(chalk.red("❌Error: ") + message);
|
@@ -133,23 +134,112 @@ function logEslintMessage(fileContent, filePath, eslintMessage) {
|
|
133
134
|
lineAfter && console.log(picocolors.gray(" " + (eslintMessage.line + 1) + " |"), lineAfter);
|
134
135
|
}
|
135
136
|
|
137
|
+
async function files({
|
138
|
+
root,
|
139
|
+
cfg,
|
140
|
+
managedDir
|
141
|
+
}) {
|
142
|
+
const printFilesUsedByVal = !managedDir;
|
143
|
+
const projectRoot = root ? path.resolve(root) : process.cwd();
|
144
|
+
const service = await createService(projectRoot, {
|
145
|
+
valConfigPath: cfg ?? "./val.config"
|
146
|
+
});
|
147
|
+
const valFiles = await glob("**/*.val.{js,ts}", {
|
148
|
+
ignore: ["node_modules/**"],
|
149
|
+
cwd: projectRoot
|
150
|
+
});
|
151
|
+
const absoluteFilesPathUsedByVal = [];
|
152
|
+
async function printOrGetFileRefs(file) {
|
153
|
+
const moduleId = `/${file}`.replace(/(\.val\.(ts|js))$/, ""); // TODO: check if this always works? (Windows?)
|
154
|
+
const valModule = await service.get(moduleId, "");
|
155
|
+
// TODO: not sure using validation is the best way to do this, but it works currently.
|
156
|
+
if (valModule.errors) {
|
157
|
+
if (valModule.errors.validation) {
|
158
|
+
for (const sourcePathS in valModule.errors.validation) {
|
159
|
+
const sourcePath = sourcePathS;
|
160
|
+
const validationError = valModule.errors.validation[sourcePath];
|
161
|
+
for (const error of validationError) {
|
162
|
+
const value = error.value;
|
163
|
+
if (isFileRef(value)) {
|
164
|
+
const absoluteFilePathUsedByVal = path.join(projectRoot, ...value[FILE_REF_PROP].split("/"));
|
165
|
+
if (printFilesUsedByVal) {
|
166
|
+
console.log(absoluteFilePathUsedByVal);
|
167
|
+
} else {
|
168
|
+
absoluteFilesPathUsedByVal.push(absoluteFilePathUsedByVal);
|
169
|
+
}
|
170
|
+
}
|
171
|
+
}
|
172
|
+
}
|
173
|
+
}
|
174
|
+
}
|
175
|
+
}
|
176
|
+
for (const file of valFiles) {
|
177
|
+
await printOrGetFileRefs(file);
|
178
|
+
}
|
179
|
+
if (managedDir) {
|
180
|
+
const managedRoot = path.isAbsolute(managedDir) ? managedDir : path.join(projectRoot, managedDir);
|
181
|
+
const allFilesInManagedDir = await glob("**/*", {
|
182
|
+
ignore: ["node_modules/**"],
|
183
|
+
cwd: managedRoot
|
184
|
+
});
|
185
|
+
for (const file of allFilesInManagedDir) {
|
186
|
+
const absoluteFilePath = path.join(managedRoot, file);
|
187
|
+
if (!absoluteFilesPathUsedByVal.includes(absoluteFilePath)) {
|
188
|
+
console.log(path.join(managedRoot, file));
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
service.dispose();
|
193
|
+
return;
|
194
|
+
}
|
195
|
+
function isFileRef(value) {
|
196
|
+
if (!value) return false;
|
197
|
+
if (typeof value !== "object") return false;
|
198
|
+
if (FILE_REF_PROP in value && VAL_EXTENSION in value) {
|
199
|
+
if (value[VAL_EXTENSION] === "file" && typeof value[FILE_REF_PROP] === "string") {
|
200
|
+
return true;
|
201
|
+
}
|
202
|
+
}
|
203
|
+
return false;
|
204
|
+
}
|
205
|
+
|
136
206
|
async function main() {
|
137
207
|
const {
|
138
208
|
input,
|
139
209
|
flags,
|
140
210
|
showHelp
|
141
211
|
} = meow(`
|
142
|
-
Usage
|
212
|
+
Usage:
|
143
213
|
$ val [command]
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
Options
|
214
|
+
|
215
|
+
Options:
|
148
216
|
--help Show this message
|
217
|
+
|
218
|
+
Commands:
|
219
|
+
validate
|
220
|
+
list-files
|
221
|
+
|
222
|
+
Command: validate
|
223
|
+
Description: val-idate val modules
|
224
|
+
Options:
|
149
225
|
--root [root], -r [root] Set project root directory (default process.cwd())
|
150
226
|
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
151
227
|
--fix [fix] Attempt to fix validation errors
|
152
|
-
--noEslint [noEslint] Disable eslint validation
|
228
|
+
--noEslint [noEslint] Disable eslint validation during validate
|
229
|
+
|
230
|
+
|
231
|
+
Command: files
|
232
|
+
Description: EXPERIMENTAL.
|
233
|
+
Perform file operations in Val.
|
234
|
+
By default it lists files (images, ...) currently in use by Val.
|
235
|
+
|
236
|
+
If a managed directory is specified,
|
237
|
+
it will list all files in the managed directory that ARE NOT currently used by Val.
|
238
|
+
This is useful for cleaning up unused files.
|
239
|
+
Options:
|
240
|
+
--managedDir [dir] If set, list files found in directory that are not managed by Val
|
241
|
+
--root [root], -r [root] Set project root directory (default process.cwd())
|
242
|
+
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
153
243
|
`, {
|
154
244
|
flags: {
|
155
245
|
port: {
|
@@ -170,6 +260,9 @@ async function main() {
|
|
170
260
|
},
|
171
261
|
noEslint: {
|
172
262
|
type: "boolean"
|
263
|
+
},
|
264
|
+
managedDir: {
|
265
|
+
type: "string"
|
173
266
|
}
|
174
267
|
},
|
175
268
|
hardRejection: false
|
@@ -182,8 +275,20 @@ async function main() {
|
|
182
275
|
}
|
183
276
|
const [command] = input;
|
184
277
|
switch (command) {
|
278
|
+
case "files":
|
279
|
+
if (flags.fix || flags.noEslint) {
|
280
|
+
return error(`Command "files" does not support --fix or --noEslint flags`);
|
281
|
+
}
|
282
|
+
return files({
|
283
|
+
root: flags.root,
|
284
|
+
cfg: flags.cfg,
|
285
|
+
managedDir: flags.managedDir
|
286
|
+
});
|
185
287
|
case "validate":
|
186
288
|
case "idate":
|
289
|
+
if (flags.managedDir) {
|
290
|
+
return error(`Command "validate" does not support --managedDir flag`);
|
291
|
+
}
|
187
292
|
return validate({
|
188
293
|
root: flags.root,
|
189
294
|
cfg: flags.cfg,
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@valbuild/cli",
|
3
3
|
"private": false,
|
4
|
-
"version": "0.60.
|
4
|
+
"version": "0.60.11",
|
5
5
|
"description": "Val CLI tools",
|
6
6
|
"bin": {
|
7
7
|
"val": "./bin.js"
|
@@ -18,8 +18,9 @@
|
|
18
18
|
"typecheck": "tsc --noEmit"
|
19
19
|
},
|
20
20
|
"dependencies": {
|
21
|
-
"@valbuild/
|
22
|
-
"@valbuild/
|
21
|
+
"@valbuild/core": "~0.60.11",
|
22
|
+
"@valbuild/server": "~0.60.11",
|
23
|
+
"@valbuild/eslint-plugin": "~0.60.11",
|
23
24
|
"eslint": "^8.31.0",
|
24
25
|
"@inquirer/confirm": "^2.0.15",
|
25
26
|
"@inquirer/prompts": "^3.0.2",
|
package/src/cli.ts
CHANGED
@@ -1,21 +1,42 @@
|
|
1
1
|
import meow from "meow";
|
2
2
|
import { error } from "./logger";
|
3
3
|
import { validate } from "./validate";
|
4
|
+
import { files as files } from "./files";
|
4
5
|
|
5
6
|
async function main(): Promise<void> {
|
6
7
|
const { input, flags, showHelp } = meow(
|
7
8
|
`
|
8
|
-
Usage
|
9
|
+
Usage:
|
9
10
|
$ val [command]
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
Options
|
11
|
+
|
12
|
+
Options:
|
14
13
|
--help Show this message
|
14
|
+
|
15
|
+
Commands:
|
16
|
+
validate
|
17
|
+
list-files
|
18
|
+
|
19
|
+
Command: validate
|
20
|
+
Description: val-idate val modules
|
21
|
+
Options:
|
15
22
|
--root [root], -r [root] Set project root directory (default process.cwd())
|
16
23
|
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
17
24
|
--fix [fix] Attempt to fix validation errors
|
18
|
-
--noEslint [noEslint] Disable eslint validation
|
25
|
+
--noEslint [noEslint] Disable eslint validation during validate
|
26
|
+
|
27
|
+
|
28
|
+
Command: files
|
29
|
+
Description: EXPERIMENTAL.
|
30
|
+
Perform file operations in Val.
|
31
|
+
By default it lists files (images, ...) currently in use by Val.
|
32
|
+
|
33
|
+
If a managed directory is specified,
|
34
|
+
it will list all files in the managed directory that ARE NOT currently used by Val.
|
35
|
+
This is useful for cleaning up unused files.
|
36
|
+
Options:
|
37
|
+
--managedDir [dir] If set, list files found in directory that are not managed by Val
|
38
|
+
--root [root], -r [root] Set project root directory (default process.cwd())
|
39
|
+
--cfg [cfg], -c [cfg] Set path to config relative to root (default ./val.config)
|
19
40
|
`,
|
20
41
|
{
|
21
42
|
flags: {
|
@@ -38,6 +59,9 @@ async function main(): Promise<void> {
|
|
38
59
|
noEslint: {
|
39
60
|
type: "boolean",
|
40
61
|
},
|
62
|
+
managedDir: {
|
63
|
+
type: "string",
|
64
|
+
},
|
41
65
|
},
|
42
66
|
hardRejection: false,
|
43
67
|
}
|
@@ -53,8 +77,22 @@ async function main(): Promise<void> {
|
|
53
77
|
|
54
78
|
const [command] = input;
|
55
79
|
switch (command) {
|
80
|
+
case "files":
|
81
|
+
if (flags.fix || flags.noEslint) {
|
82
|
+
return error(
|
83
|
+
`Command "files" does not support --fix or --noEslint flags`
|
84
|
+
);
|
85
|
+
}
|
86
|
+
return files({
|
87
|
+
root: flags.root,
|
88
|
+
cfg: flags.cfg,
|
89
|
+
managedDir: flags.managedDir,
|
90
|
+
});
|
56
91
|
case "validate":
|
57
92
|
case "idate":
|
93
|
+
if (flags.managedDir) {
|
94
|
+
return error(`Command "validate" does not support --managedDir flag`);
|
95
|
+
}
|
58
96
|
return validate({
|
59
97
|
root: flags.root,
|
60
98
|
cfg: flags.cfg,
|
package/src/files.ts
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
import {
|
2
|
+
FILE_REF_PROP,
|
3
|
+
ModuleId,
|
4
|
+
ModulePath,
|
5
|
+
SourcePath,
|
6
|
+
VAL_EXTENSION,
|
7
|
+
} from "@valbuild/core";
|
8
|
+
import { createService } from "@valbuild/server";
|
9
|
+
import { glob } from "fast-glob";
|
10
|
+
import path from "path";
|
11
|
+
|
12
|
+
export async function files({
|
13
|
+
root,
|
14
|
+
cfg,
|
15
|
+
managedDir,
|
16
|
+
}: {
|
17
|
+
root?: string;
|
18
|
+
cfg?: string;
|
19
|
+
managedDir?: string;
|
20
|
+
}) {
|
21
|
+
const printFilesUsedByVal = !managedDir;
|
22
|
+
const projectRoot = root ? path.resolve(root) : process.cwd();
|
23
|
+
|
24
|
+
const service = await createService(projectRoot, {
|
25
|
+
valConfigPath: cfg ?? "./val.config",
|
26
|
+
});
|
27
|
+
|
28
|
+
const valFiles: string[] = await glob("**/*.val.{js,ts}", {
|
29
|
+
ignore: ["node_modules/**"],
|
30
|
+
cwd: projectRoot,
|
31
|
+
});
|
32
|
+
|
33
|
+
const absoluteFilesPathUsedByVal: string[] = [];
|
34
|
+
async function printOrGetFileRefs(file: string) {
|
35
|
+
const moduleId = `/${file}`.replace(/(\.val\.(ts|js))$/, "") as ModuleId; // TODO: check if this always works? (Windows?)
|
36
|
+
const valModule = await service.get(moduleId, "" as ModulePath);
|
37
|
+
// TODO: not sure using validation is the best way to do this, but it works currently.
|
38
|
+
if (valModule.errors) {
|
39
|
+
if (valModule.errors.validation) {
|
40
|
+
for (const sourcePathS in valModule.errors.validation) {
|
41
|
+
const sourcePath = sourcePathS as SourcePath;
|
42
|
+
const validationError = valModule.errors.validation[sourcePath];
|
43
|
+
for (const error of validationError) {
|
44
|
+
const value = error.value;
|
45
|
+
if (isFileRef(value)) {
|
46
|
+
const absoluteFilePathUsedByVal = path.join(
|
47
|
+
projectRoot,
|
48
|
+
...value[FILE_REF_PROP].split("/")
|
49
|
+
);
|
50
|
+
if (printFilesUsedByVal) {
|
51
|
+
console.log(absoluteFilePathUsedByVal);
|
52
|
+
} else {
|
53
|
+
absoluteFilesPathUsedByVal.push(absoluteFilePathUsedByVal);
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
61
|
+
for (const file of valFiles) {
|
62
|
+
await printOrGetFileRefs(file);
|
63
|
+
}
|
64
|
+
|
65
|
+
if (managedDir) {
|
66
|
+
const managedRoot = path.isAbsolute(managedDir)
|
67
|
+
? managedDir
|
68
|
+
: path.join(projectRoot, managedDir);
|
69
|
+
const allFilesInManagedDir = await glob("**/*", {
|
70
|
+
ignore: ["node_modules/**"],
|
71
|
+
cwd: managedRoot,
|
72
|
+
});
|
73
|
+
for (const file of allFilesInManagedDir) {
|
74
|
+
const absoluteFilePath = path.join(managedRoot, file);
|
75
|
+
if (!absoluteFilesPathUsedByVal.includes(absoluteFilePath)) {
|
76
|
+
console.log(path.join(managedRoot, file));
|
77
|
+
}
|
78
|
+
}
|
79
|
+
}
|
80
|
+
|
81
|
+
service.dispose();
|
82
|
+
return;
|
83
|
+
}
|
84
|
+
|
85
|
+
function isFileRef(
|
86
|
+
value: unknown
|
87
|
+
): value is { [FILE_REF_PROP]: string; [VAL_EXTENSION]: "file" } {
|
88
|
+
if (!value) return false;
|
89
|
+
if (typeof value !== "object") return false;
|
90
|
+
if (FILE_REF_PROP in value && VAL_EXTENSION in value) {
|
91
|
+
if (
|
92
|
+
value[VAL_EXTENSION] === "file" &&
|
93
|
+
typeof value[FILE_REF_PROP] === "string"
|
94
|
+
) {
|
95
|
+
return true;
|
96
|
+
}
|
97
|
+
}
|
98
|
+
return false;
|
99
|
+
}
|