@percy/cli-config 1.0.0 → 1.0.3

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/dist/config.js ADDED
@@ -0,0 +1,9 @@
1
+ import command from '@percy/cli-command';
2
+ import create from './create.js';
3
+ import validate from './validate.js';
4
+ import migrate from './migrate.js';
5
+ export const config = command('config', {
6
+ description: 'Manage Percy config files',
7
+ commands: [create, validate, migrate]
8
+ });
9
+ export default config;
package/dist/create.js ADDED
@@ -0,0 +1,73 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import command, { PercyConfig } from '@percy/cli-command';
4
+ const DEFAULT_FILES = {
5
+ rc: '.percyrc',
6
+ yaml: '.percy.yaml',
7
+ yml: '.percy.yml',
8
+ json: '.percy.json',
9
+ js: '.percy.js'
10
+ };
11
+ const FILETYPES = Object.keys(DEFAULT_FILES);
12
+ export const create = command('create', {
13
+ description: 'Create a Percy config file',
14
+ args: [{
15
+ name: 'filepath',
16
+ description: 'Optional config filepath'
17
+ }],
18
+ flags: [{
19
+ name: 'rc',
20
+ description: 'Create a .percyrc file',
21
+ conflicts: FILETYPES.filter(t => t !== 'rc'),
22
+ type: 'boolean'
23
+ }, {
24
+ name: 'yaml',
25
+ description: 'Create a .percy.yaml file',
26
+ conflicts: FILETYPES.filter(t => t !== 'yaml'),
27
+ type: 'boolean'
28
+ }, {
29
+ name: 'yml',
30
+ description: 'Create a .percy.yml file',
31
+ conflicts: FILETYPES.filter(t => t !== 'yml'),
32
+ type: 'boolean'
33
+ }, {
34
+ name: 'json',
35
+ description: 'Create a .percy.json file',
36
+ conflicts: FILETYPES.filter(t => t !== 'json'),
37
+ type: 'boolean'
38
+ }, {
39
+ name: 'js',
40
+ description: 'Create a .percy.js file',
41
+ conflicts: FILETYPES.filter(t => t !== 'js'),
42
+ type: 'boolean'
43
+ }],
44
+ examples: ['$0', '$0 --yaml', '$0 --json', '$0 --js', '$0 --rc', '$0 ./config/percy.yml']
45
+ }, async ({
46
+ flags,
47
+ args,
48
+ log,
49
+ exit
50
+ }) => {
51
+ // discern the filetype
52
+ let filetype = args.filepath ? path.extname(args.filepath).replace(/^./, '') : FILETYPES.find(t => flags[t]) ?? 'yml'; // verify the filetype is supported
53
+
54
+ if (!DEFAULT_FILES[filetype]) {
55
+ exit(1, `Unsupported filetype: ${filetype}`);
56
+ } // default filepath based on filetype
57
+
58
+
59
+ let filepath = args.filepath || DEFAULT_FILES[filetype]; // verify the file does not already exist
60
+
61
+ if (fs.existsSync(filepath)) {
62
+ exit(1, `Percy config already exists: ${filepath}`);
63
+ } // write stringified default config options to the filepath
64
+
65
+
66
+ let format = ['rc', 'yaml', 'yml'].includes(filetype) ? 'yaml' : filetype;
67
+ fs.mkdirSync(path.dirname(filepath), {
68
+ recursive: true
69
+ });
70
+ fs.writeFileSync(filepath, PercyConfig.stringify(format));
71
+ log.info(`Created Percy config: ${filepath}`);
72
+ });
73
+ export default create;
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { default, config } from './config.js';
2
+ export { create } from './create.js';
3
+ export { validate } from './validate.js';
4
+ export { migrate } from './migrate.js';
@@ -0,0 +1,81 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import command, { PercyConfig } from '@percy/cli-command';
4
+ export const migrate = command('migrate', {
5
+ description: 'Migrate a Percy config file to the latest version',
6
+ args: [{
7
+ name: 'filepath',
8
+ description: 'Current config filepath, detected by default'
9
+ }, {
10
+ name: 'output',
11
+ description: 'New config filepath to write to, defaults to \'filepath\''
12
+ }],
13
+ flags: [{
14
+ name: 'dry-run',
15
+ description: 'Print the new config without writing it',
16
+ short: 'd'
17
+ }],
18
+ examples: ['$0', '$0 --dry-run', '$0 ./config/percy.yml', '$0 .percy.yml .percy.js']
19
+ }, async ({
20
+ args,
21
+ flags,
22
+ log,
23
+ exit
24
+ }) => {
25
+ let {
26
+ config,
27
+ filepath: input
28
+ } = PercyConfig.search(args.filepath);
29
+ let output = args.output ? path.resolve(args.output) : input;
30
+ if (!config) exit(1, 'Config file not found');
31
+ log.info(`Found config file: ${path.relative('', input)}`); // if migrating versions, warn when latest
32
+
33
+ if (input === output && config.version === 2) {
34
+ exit(0, 'Config is already the latest version');
35
+ } // migrate config
36
+
37
+
38
+ log.info('Migrating config file...');
39
+ let format = path.extname(output).replace(/^./, '') || 'yaml';
40
+ let migrated = PercyConfig.migrate(config); // prefer kebab-case for yaml
41
+
42
+ if (/^ya?ml$/.test(format)) {
43
+ migrated = PercyConfig.normalize(migrated, {
44
+ schema: '/config',
45
+ kebab: true
46
+ });
47
+ } // stringify to the desired format
48
+
49
+
50
+ let body = PercyConfig.stringify(format, migrated);
51
+
52
+ if (!flags.dryRun) {
53
+ let content = body;
54
+
55
+ if (path.basename(output) === 'package.json') {
56
+ // update the package.json entry by reading and modifying it
57
+ let pkg = JSON.parse(fs.readFileSync(output));
58
+ content = PercyConfig.stringify(format, { ...pkg,
59
+ percy: migrated
60
+ });
61
+ } else if (input === output) {
62
+ // rename input if it is the output
63
+ let {
64
+ dir,
65
+ name,
66
+ ext
67
+ } = path.parse(input);
68
+ fs.renameSync(input, path.join(dir, `${name}.old${ext}`));
69
+ } // write to output
70
+
71
+
72
+ fs.writeFileSync(output, content);
73
+ }
74
+
75
+ log.info('Config file migrated!'); // when dry-running, print config to stdout when finished
76
+
77
+ if (flags.dryRun) {
78
+ log.stdout.write('\n' + body);
79
+ }
80
+ });
81
+ export default migrate;
@@ -0,0 +1,29 @@
1
+ import command, { PercyConfig } from '@percy/cli-command';
2
+ export const validate = command('validate', {
3
+ description: 'Validate a Percy config file',
4
+ args: [{
5
+ name: 'filepath',
6
+ description: 'Config filepath, detected by default'
7
+ }],
8
+ examples: ['$0', '$0 ./config/percy.yml']
9
+ }, async ({
10
+ args,
11
+ log,
12
+ exit
13
+ }) => {
14
+ // verify a config file can be located
15
+ let {
16
+ config,
17
+ filepath
18
+ } = PercyConfig.search(args.filepath);
19
+ if (!config) exit(1, 'Config file not found'); // when `bail` is true, .load() returns undefined when validation fails
20
+
21
+ let result = PercyConfig.load({
22
+ path: filepath,
23
+ print: true,
24
+ bail: true
25
+ }); // exit 1 when config is empty
26
+
27
+ if (!result) exit(1);
28
+ });
29
+ export default validate;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/cli-config",
3
- "version": "1.0.0",
3
+ "version": "1.0.3",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -14,7 +14,7 @@
14
14
  "node": ">=14"
15
15
  },
16
16
  "files": [
17
- "./dist"
17
+ "dist"
18
18
  ],
19
19
  "main": "./dist/index.js",
20
20
  "type": "module",
@@ -32,7 +32,7 @@
32
32
  ]
33
33
  },
34
34
  "dependencies": {
35
- "@percy/cli-command": "1.0.0"
35
+ "@percy/cli-command": "1.0.3"
36
36
  },
37
- "gitHead": "6df509421a60144e4f9f5d59dc57a5675372a0b2"
37
+ "gitHead": "a259d5cff0933711bced21a979c577e70765d318"
38
38
  }