• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

devpow112 / codify-images / 4851918122

01 May 2023 02:21PM UTC coverage: 100.0%. Remained the same
4851918122

push

github

Devon Powell
chore(deps-dev): bump markdownlint-cli from 0.33.0 to 0.34.0

62 of 62 branches covered (100.0%)

Branch coverage included in aggregate %.

185 of 185 relevant lines covered (100.0%)

113.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

100.0
/src/codify-images.js
1
import * as errors from './errors.js';
3✔
2
import { basename, extname, join, resolve as resolvePath } from 'path';
1✔
3
import { readdirSync, readFileSync } from 'fs';
1✔
4
import camelCase from 'lodash.camelcase';
1✔
5
import svgToMiniDataURI from 'mini-svg-data-uri';
4✔
6

7
const { InvalidPathError, InvalidSvgModeError, UnsupportedTypeError } = errors;
1✔
8

9
const svgExtension = '.svg';
1✔
10
const supportedMimeTypes = {
1✔
11
  '.jpg': 'image/jpeg',
12
  '.jpeg': 'image/jpeg',
13
  '.png': 'image/png',
14
  '.gif': 'image/gif',
15
  '.webp': 'image/webp',
16
  '.svg': 'image/svg+xml'
17
};
18
const svgModes = ['base64', 'uri', 'mini', 'mini-srcset'];
1✔
19

20
const isObject = value => {
1✔
21
  return Object.prototype.toString.call(value) === '[object Object]';
93✔
22
};
23

24
const getEncoding = (isSvg, options) => {
1✔
25
  if (isSvg) {
474✔
26
    return options.svgMode;
79✔
27
  }
28

29
  return 'base64';
395✔
30
};
31

32
const getFormat = encoding => {
1✔
33
  switch (encoding) {
474✔
34
    case 'mini':
35
    case 'mini-srcset':
36
    case 'uri':
37
      return 'utf-8';
54✔
38
    default:
39
      return 'base64';
420✔
40
  }
41
};
42

43
const sanitizeFileData = data => {
1✔
44
  return data.replace(/[\r\n]+/gm, '');
474✔
45
};
46

47
const buildDataUri = (source, mime, encoding) => {
1✔
48
  if (encoding === 'uri') {
474✔
49
    return `data:${mime};${encodeURIComponent(source)}`;
18✔
50
  } else if (encoding === 'mini') {
456✔
51
    return svgToMiniDataURI(source);
18✔
52
  } else if (encoding === 'mini-srcset') {
438✔
53
    return svgToMiniDataURI.toSrcset(source);
18✔
54
  }
55

56
  return `data:${mime};${encoding},${source}`;
420✔
57
};
58

59
const isSupported = extension => {
1✔
60
  return supportedMimeTypes[extension] !== undefined;
641✔
61
};
62

63
const getImageDataUri = (path, mime, isSvg, options) => {
1✔
64
  const encoding = getEncoding(isSvg, options);
474✔
65
  const format = getFormat(encoding);
474✔
66
  const source = sanitizeFileData(readFileSync(path, format));
474✔
67

68
  return buildDataUri(source, mime, encoding);
474✔
69
};
70

71
const processFile = (path, extension, options) => {
1✔
72
  const mime = supportedMimeTypes[extension];
474✔
73
  const isSvg = mime === supportedMimeTypes[svgExtension];
474✔
74

75
  return {
474✔
76
    path,
77
    name: camelCase(basename(path)),
78
    data: getImageDataUri(path, mime, isSvg, options)
79
  };
80
};
81

82
const processFiles = (path, files, options) => {
1✔
83
  const images = {};
82✔
84

85
  for (const file of files) {
82✔
86
    const filePath = join(path, file);
641✔
87
    const extension = extname(filePath);
641✔
88

89
    if (!isSupported(extension)) {
641✔
90
      if (options.ignoreUnsupportedTypes === true) {
167✔
91
        continue;
165✔
92
      } else {
93
        throw new UnsupportedTypeError(extension);
2✔
94
      }
95
    }
96

97
    const image = processFile(filePath, extension, options);
474✔
98

99
    images[image.name] = image.data;
474✔
100

101
    options.log?.(image.path, image.name);
474✔
102
  }
103

104
  return images;
80✔
105
};
106

107
const hasObjectProperty = (options, property) => {
1✔
108
  return Object.prototype.hasOwnProperty.call(options, property);
186✔
109
};
110

111
const sanitizeOptions = options => {
1✔
112
  if (!isObject(options)) {
93✔
113
    options = {};
2✔
114
  }
115

116
  if (!hasObjectProperty(options, 'ignoreUnsupportedTypes')) {
93✔
117
    options.ignoreUnsupportedTypes = true;
83✔
118
  } else {
119
    options.ignoreUnsupportedTypes = options.ignoreUnsupportedTypes === true;
10✔
120
  }
121

122
  if (!hasObjectProperty(options, 'svgMode')) {
93✔
123
    options.svgMode = 'base64';
9✔
124
  } else if (!svgModes.includes(options.svgMode)) {
84✔
125
    throw new InvalidSvgModeError(options.svgMode);
2✔
126
  }
127

128
  return options;
91✔
129
};
130

131
export const codifyImagesSync = (path, options = {}) => {
1✔
132
  let files;
133

134
  try {
85✔
135
    files = readdirSync(resolvePath(path));
85✔
136
  } catch (_) {
137
    throw new InvalidPathError(path);
2✔
138
  }
139

140
  return processFiles(path, files, sanitizeOptions(options));
83✔
141
};
1✔
142

143
export const codifyImages = (path, options = {}) => {
1✔
144
  return new Promise((resolve, reject) => {
10✔
145
    try {
10✔
146
      resolve(codifyImagesSync(path, sanitizeOptions(options)));
10✔
147
    } catch (err) {
148
      reject(err);
3✔
149
    }
150
  });
151
};
1✔
152

153
export default {
1✔
154
  codifyImages,
155
  codifyImagesSync
156
};
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc