@percy/cli-upload 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,50 @@
1
+ export const schema = {
2
+ upload: {
3
+ type: 'object',
4
+ additionalProperties: false,
5
+ properties: {
6
+ files: {
7
+ anyOf: [{
8
+ type: 'string'
9
+ }, {
10
+ type: 'array',
11
+ items: {
12
+ type: 'string'
13
+ }
14
+ }],
15
+ default: '**/*.{png,jpg,jpeg}'
16
+ },
17
+ ignore: {
18
+ anyOf: [{
19
+ type: 'string'
20
+ }, {
21
+ type: 'array',
22
+ items: {
23
+ type: 'string'
24
+ }
25
+ }],
26
+ default: ''
27
+ },
28
+ stripExtensions: {
29
+ type: 'boolean',
30
+ default: false
31
+ },
32
+ concurrency: {
33
+ type: 'number',
34
+ minimum: 1
35
+ }
36
+ }
37
+ }
38
+ };
39
+ export function migration(config, {
40
+ map,
41
+ del
42
+ }) {
43
+ /* eslint-disable curly */
44
+ if (config.version < 2) {
45
+ // image-snapshots and options were renamed
46
+ map('imageSnapshots.files', 'upload.files');
47
+ map('imageSnapshots.ignore', 'upload.ignore');
48
+ del('imageSnapshots');
49
+ }
50
+ }
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export { default, upload } from './upload.js';
@@ -0,0 +1,54 @@
1
+ import path from 'path';
2
+ import { sha256hash } from '@percy/client/utils'; // Returns a root resource object with a sha and mimetype.
3
+
4
+ function createRootResource(url, content) {
5
+ return {
6
+ url,
7
+ content,
8
+ sha: sha256hash(content),
9
+ mimetype: 'text/html',
10
+ root: true
11
+ };
12
+ } // Returns an image resource object with a sha.
13
+
14
+
15
+ function createImageResource(url, content, mimetype) {
16
+ return {
17
+ url,
18
+ content,
19
+ sha: sha256hash(content),
20
+ mimetype
21
+ };
22
+ } // Returns root resource and image resource objects based on an image's
23
+ // filename, contents, and dimensions. The root resource is a generated DOM
24
+ // designed to display an image at it's native size without margins or padding.
25
+
26
+
27
+ export function createImageResources(filename, content, size) {
28
+ let {
29
+ dir,
30
+ name,
31
+ ext
32
+ } = path.parse(filename);
33
+ let rootUrl = `/${encodeURIComponent(path.join(dir, name))}`;
34
+ let imageUrl = `/${encodeURIComponent(filename)}`;
35
+ let mimetype = ext === '.png' ? 'image/png' : 'image/jpeg';
36
+ return [createRootResource(rootUrl, `
37
+ <!doctype html>
38
+ <html lang="en">
39
+ <head>
40
+ <meta charset="utf-8">
41
+ <title>${filename}</title>
42
+ <style>
43
+ *, *::before, *::after { margin: 0; padding: 0; font-size: 0; }
44
+ html, body { width: 100%; }
45
+ img { max-width: 100%; }
46
+ </style>
47
+ </head>
48
+ <body>
49
+ <img src="${imageUrl}" width="${size.width}px" height="${size.height}px"/>
50
+ </body>
51
+ </html>
52
+ `), createImageResource(imageUrl, content, mimetype)];
53
+ }
54
+ export default createImageResources;
package/dist/upload.js ADDED
@@ -0,0 +1,125 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import command from '@percy/cli-command';
4
+ import * as UploadConfig from './config.js';
5
+ const ALLOWED_FILE_TYPES = /\.(png|jpg|jpeg)$/i;
6
+ export const upload = command('upload', {
7
+ description: 'Upload a directory of images to Percy',
8
+ args: [{
9
+ name: 'dirname',
10
+ description: 'Directory of images to upload',
11
+ required: true,
12
+ validate: dir => {
13
+ if (!fs.existsSync(dir)) {
14
+ throw new Error(`Not found: ${dir}`);
15
+ } else if (!fs.lstatSync(dir).isDirectory()) {
16
+ throw new Error(`Not a directory: ${dir}`);
17
+ }
18
+ }
19
+ }],
20
+ flags: [{
21
+ name: 'files',
22
+ description: 'One or more globs matching image file paths to upload',
23
+ default: UploadConfig.schema.upload.properties.files.default,
24
+ percyrc: 'upload.files',
25
+ type: 'pattern',
26
+ multiple: true,
27
+ short: 'f'
28
+ }, {
29
+ name: 'ignore',
30
+ description: 'One or more globs matching image file paths to ignore',
31
+ percyrc: 'upload.ignore',
32
+ type: 'pattern',
33
+ multiple: true,
34
+ short: 'i'
35
+ }, {
36
+ name: 'strip-extensions',
37
+ description: 'Strips file extensions from snapshot names',
38
+ percyrc: 'upload.stripExtensions',
39
+ short: 'e'
40
+ }],
41
+ examples: ['$0 ./images'],
42
+ percy: {
43
+ discoveryFlags: false,
44
+ deferUploads: true
45
+ },
46
+ config: {
47
+ schemas: [UploadConfig.schema],
48
+ migrations: [UploadConfig.migration]
49
+ }
50
+ }, async function* ({
51
+ flags,
52
+ args,
53
+ percy,
54
+ log,
55
+ exit
56
+ }) {
57
+ if (!percy) exit(0, 'Percy is disabled');
58
+ let config = percy.config.upload;
59
+ let {
60
+ default: glob
61
+ } = await import('fast-glob');
62
+ let pathnames = yield glob(config.files, {
63
+ ignore: [].concat(config.ignore || []),
64
+ cwd: args.dirname,
65
+ fs
66
+ });
67
+
68
+ if (!pathnames.length) {
69
+ exit(1, `No matching files found in '${args.dirname}'`);
70
+ }
71
+
72
+ let {
73
+ default: imageSize
74
+ } = await import('image-size');
75
+ let {
76
+ createImageResources
77
+ } = await import('./resources.js'); // the internal upload queue shares a concurrency with the snapshot queue
78
+
79
+ percy.setConfig({
80
+ discovery: {
81
+ concurrency: config.concurrency
82
+ }
83
+ }); // do not launch a browser when starting
84
+
85
+ yield* percy.yield.start({
86
+ browser: false
87
+ });
88
+
89
+ for (let filename of pathnames) {
90
+ let file = path.parse(filename);
91
+ let name = config.stripExtensions ? path.join(file.dir, file.name) : filename;
92
+
93
+ if (!ALLOWED_FILE_TYPES.test(filename)) {
94
+ log.info(`Skipping unsupported file type: ${filename}`);
95
+ } else {
96
+ if (percy.dryRun) log.info(`Snapshot found: ${name}`);
97
+
98
+ percy._scheduleUpload(filename, async () => {
99
+ let filepath = path.resolve(args.dirname, filename);
100
+ let buffer = fs.readFileSync(filepath); // width and height is clamped to API min and max
101
+
102
+ let size = imageSize(filepath);
103
+ let widths = [Math.max(10, Math.min(size.width, 2000))];
104
+ let minHeight = Math.max(10, Math.min(size.height, 2000));
105
+ let resources = createImageResources(filename, buffer, size);
106
+ return {
107
+ name,
108
+ widths,
109
+ minHeight,
110
+ resources
111
+ };
112
+ }).then(() => {
113
+ log.info(`Snapshot uploaded: ${name}`);
114
+ });
115
+ }
116
+ }
117
+
118
+ try {
119
+ yield* percy.yield.stop();
120
+ } catch (error) {
121
+ await percy.stop(true);
122
+ throw error;
123
+ }
124
+ });
125
+ export default upload;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@percy/cli-upload",
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,9 +32,9 @@
32
32
  ]
33
33
  },
34
34
  "dependencies": {
35
- "@percy/cli-command": "1.0.0",
35
+ "@percy/cli-command": "1.0.3",
36
36
  "fast-glob": "^3.2.11",
37
37
  "image-size": "^1.0.0"
38
38
  },
39
- "gitHead": "6df509421a60144e4f9f5d59dc57a5675372a0b2"
39
+ "gitHead": "a259d5cff0933711bced21a979c577e70765d318"
40
40
  }