@localnerve/sass-asset-functions 2.1.0 → 3.0.0

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.
Files changed (41) hide show
  1. package/.eslintrc.json +2 -4
  2. package/CHANGELOG.md +20 -0
  3. package/{LICENSE → LICENSE.md} +1 -1
  4. package/README.md +45 -47
  5. package/babel.config.json +11 -0
  6. package/cjs/index.cjs +69 -0
  7. package/cjs/lib/processor.cjs +175 -0
  8. package/index.js +22 -16
  9. package/jest.config.js +1 -1
  10. package/lib/processor.js +9 -8
  11. package/package.json +19 -6
  12. package/posttranspile.cjs +9 -0
  13. package/.github/workflows/verify.yml +0 -32
  14. package/__tests__/css/asset_cache_buster/path/font-files.css +0 -3
  15. package/__tests__/css/asset_cache_buster/path/font-url.css +0 -6
  16. package/__tests__/css/asset_cache_buster/path/image-size.css +0 -3
  17. package/__tests__/css/asset_cache_buster/path/image-url.css +0 -5
  18. package/__tests__/css/asset_cache_buster/path/inline-image.css +0 -2
  19. package/__tests__/css/asset_cache_buster/query/font-files.css +0 -3
  20. package/__tests__/css/asset_cache_buster/query/font-url.css +0 -6
  21. package/__tests__/css/asset_cache_buster/query/image-size.css +0 -3
  22. package/__tests__/css/asset_cache_buster/query/image-url.css +0 -5
  23. package/__tests__/css/asset_cache_buster/query/inline-image.css +0 -2
  24. package/__tests__/css/asset_host/font-files.css +0 -3
  25. package/__tests__/css/asset_host/font-url.css +0 -6
  26. package/__tests__/css/asset_host/image-size.css +0 -3
  27. package/__tests__/css/asset_host/image-url.css +0 -5
  28. package/__tests__/css/asset_host/inline-image.css +0 -2
  29. package/__tests__/css/basic/font-files.css +0 -3
  30. package/__tests__/css/basic/font-url.css +0 -6
  31. package/__tests__/css/basic/image-size.css +0 -3
  32. package/__tests__/css/basic/image-url.css +0 -5
  33. package/__tests__/css/basic/inline-image.css +0 -2
  34. package/__tests__/images/barney.gif +0 -0
  35. package/__tests__/images/npm.svg +0 -1
  36. package/__tests__/scss/font-files.scss +0 -4
  37. package/__tests__/scss/font-url.scss +0 -8
  38. package/__tests__/scss/image-size.scss +0 -4
  39. package/__tests__/scss/image-url.scss +0 -7
  40. package/__tests__/scss/inline-image.scss +0 -3
  41. package/__tests__/test.js +0 -145
package/.eslintrc.json CHANGED
@@ -1,9 +1,7 @@
1
1
  {
2
2
  "parserOptions": {
3
- "ecmaVersion": 9,
4
- "ecmaFeatures": {
5
- "impliedStrict": true
6
- }
3
+ "ecmaVersion": "latest",
4
+ "sourceType": "module"
7
5
  },
8
6
  "env": {
9
7
  "node": true
package/CHANGELOG.md ADDED
@@ -0,0 +1,20 @@
1
+ # Sass Asset Functions Change Log
2
+
3
+ ## 3.0.0
4
+ * **Breaking Change**
5
+ > ESM require support now requires destructuring `default` export.
6
+ ```js
7
+ const { default: assetFunctions } = require('@localnerve/sass-asset-functions');
8
+ // or
9
+ const assetFunctions = require('@localnerve/sass-asset-functions').default;
10
+ ```
11
+ * Dependency Update
12
+ * Full ESM module with cjs support
13
+
14
+ ## 2.0.0
15
+ * Support Node 14+, update dependencies.
16
+ * Dropped support for Node 12.
17
+
18
+ ## 1.0.0
19
+ * Dependency Update
20
+ * Dropped support for Node 10.
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2022, LocalNerve
3
+ Copyright (c) 2023, LocalNerve
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -35,16 +35,25 @@ This module provides some of the asset functions that came with [Compass](http:/
35
35
  Basic usage is as easy as setting the `functions` property:
36
36
 
37
37
  ```js
38
+ // non-module, require usage
38
39
  const sass = require('sass');
39
- const fiber = require('fibers');
40
- const assetFunctions = require('@localnerve/sass-asset-functions');
41
-
42
- sass.render({
43
- functions: assetFunctions(/* options */),
44
- file: scss_filename,
45
- fiber, // dart-sass async render performance detail
46
- [, options..]
47
- }, function(err, result) { /*...*/ });
40
+ const { default: assetFunctions } = require('@localnerve/sass-asset-functions');
41
+
42
+ const result = sass.compile(scss_filename, {
43
+ functions: assetFunctions(/* options */)
44
+ [, options...]
45
+ });
46
+ ```
47
+
48
+ ```js
49
+ // module usage
50
+ import sass from 'sass';
51
+ import assetFunctions from '@localnerve/sass-asset-functions';
52
+
53
+ const result = sass.compile(scss_filename, {
54
+ functions: assetFunctions(/* options */)
55
+ [, options...]
56
+ });
48
57
  ```
49
58
 
50
59
  ## Options
@@ -78,18 +87,15 @@ So if your project images reside in `public/img` at build-time instead of `publi
78
87
 
79
88
  ```js
80
89
  const sass = require('sass');
81
- const fiber = require('fibers');
82
- const assetFunctions = require('@localnerve/sass-asset-functions');
90
+ const { default: assetFunctions } = require('@localnerve/sass-asset-functions');
83
91
 
84
- sass.render({
92
+ const result = sass.compile(scss_filename, {
85
93
  functions: assetFunctions({
86
94
  images_path: 'public/img',
87
95
  http_images_path: '/images'
88
- }),
89
- file: scss_filename,
90
- fiber,
91
- [, options..]
92
- }, function(err, result) { /*...*/ });
96
+ })
97
+ [, options...]
98
+ });
93
99
  ```
94
100
 
95
101
  #### `sass`: Overriding the default compiler with Node-Sass
@@ -98,30 +104,27 @@ Example using the node-sass compiler using the new option `sass`.
98
104
 
99
105
  ```js
100
106
  const sass = require('node-sass');
101
- const assetFunctions = require('@localnerve/sass-asset-functions');
107
+ const { default: assetFunctions } = require('@localnerve/sass-asset-functions');
102
108
 
103
- sass.render({
104
- functions: assetFunctions({ sass }),
105
- file: scss_filename,
106
- [, options..]
107
- }, function(err, result) { /*...*/ });
109
+ const result = sass.compile(scss_filename, {
110
+ functions: assetFunctions({ sass })
111
+ [, options...]
112
+ });
108
113
  ```
109
114
 
110
115
  #### `asset_host`: a function which completes with a string used as asset host.
111
116
 
112
117
  ```js
113
- sass.render({
118
+ const result = sass.compile(scss_filename, {
114
119
  functions: assetFunctions({
115
- asset_host: function(http_path, done){
120
+ asset_host: (http_path, done) => {
116
121
  done('http://assets.example.com');
117
122
  // or use the supplied path to calculate a host
118
123
  done(`http://assets${http_path.length % 4}.example.com`);
119
124
  }
120
- }),
121
- file: scss_filename,
122
- fiber,
123
- [, options..]
124
- }, function(err, result) { /*...*/ });
125
+ })
126
+ [, options...]
127
+ });
125
128
  ```
126
129
 
127
130
  #### `asset_cache_buster`: a function to rewrite the asset path
@@ -129,16 +132,14 @@ sass.render({
129
132
  When this function returns a string, it's set as the query of the path. When returned an object, `path` and `query` will be used.
130
133
 
131
134
  ```js
132
- sass.render({
135
+ const result = sass.compile(scss_filename, {
133
136
  functions: assetFunctions({
134
- asset_cache_buster: function(http_path, real_path, done){
137
+ asset_cache_buster: (http_path, real_path, done) => {
135
138
  done('v=123');
136
139
  }
137
- }),
138
- file: scss_filename,
139
- fiber,
140
- [, options..]
141
- }, function(err, result) { /*...*/ });
140
+ })
141
+ [, options...]
142
+ });
142
143
  ```
143
144
 
144
145
  ##### A more advanced example:
@@ -149,16 +150,15 @@ For example, `/images/myimage.png` would become `/images/myimage-8557f1c9b01dd6f
149
150
 
150
151
  ```js
151
152
  const sass = require('sass');
152
- const fiber = require('fibers');
153
153
  const path = require('path');
154
154
  const fs = require('fs');
155
155
  const hexdigest = require('hexdigest');
156
- const assetFunctions = require('@localnerve/sass-asset-functions');
156
+ const { default: assetFunctions } = require('@localnerve/sass-asset-functions');
157
157
 
158
- sass.render({
158
+ const result = sass.compile(scss_filename, {
159
159
  functions: assetFunctions({
160
- asset_cache_buster: function(http_path, real_path, done){
161
- hexdigest(real_path, 'sha1', function(err, digest) {
160
+ asset_cache_buster: (http_path, real_path, done) => {
161
+ hexdigest(real_path, 'sha1', (err, digest) => {
162
162
  if (err) {
163
163
  // an error occurred, maybe the file doesn't exist.
164
164
  // Calling `done` without arguments will result in an unmodified path.
@@ -171,11 +171,9 @@ sass.render({
171
171
  }
172
172
  });
173
173
  }
174
- }),
175
- file: scss_filename,
176
- fiber,
177
- [, options..]
178
- }, function(err, result) { /*...*/ });
174
+ })
175
+ [, options...]
176
+ });
179
177
  ```
180
178
 
181
179
  ## Contributing
@@ -0,0 +1,11 @@
1
+ {
2
+ "presets": [
3
+ [
4
+ "@babel/preset-env", {
5
+ "targets": {
6
+ "node": "14"
7
+ }
8
+ }
9
+ ]
10
+ ]
11
+ }
package/cjs/index.cjs ADDED
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = sassFunctions;
7
+ var _sass = _interopRequireDefault(require("sass"));
8
+ var _processor = _interopRequireDefault(require("./lib/processor.cjs"));
9
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
+ /**
11
+ * Sass asset function suite.
12
+ *
13
+ * Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
14
+ * Licensed under the MIT license.
15
+ */
16
+
17
+ function sassFunctions(options = {}) {
18
+ const {
19
+ sass = _sass.default
20
+ } = options;
21
+ const processor = new _processor.default(options);
22
+ return {
23
+ 'image-url($filename, $only_path: false)': (filename, only_path, done) => {
24
+ processor.image_url(filename.getValue(), url => {
25
+ if (!only_path.getValue()) url = `url('${url}')`;
26
+ done(new sass.types.String(url));
27
+ });
28
+ },
29
+ 'inline-image($filename, $mime_type: null)': (filename, mime_type, done) => {
30
+ mime_type = mime_type instanceof sass.types.Null ? null : mime_type.getValue();
31
+ processor.inline_image(filename.getValue(), mime_type, dataUrl => {
32
+ done(new sass.types.String(`url('${dataUrl}')`));
33
+ });
34
+ },
35
+ 'image-width($filename)': (filename, done) => {
36
+ processor.image_width(filename.getValue(), image_width => {
37
+ done(new sass.types.Number(image_width, 'px'));
38
+ });
39
+ },
40
+ 'image-height($filename)': (filename, done) => {
41
+ processor.image_height(filename.getValue(), image_height => {
42
+ done(new sass.types.Number(image_height, 'px'));
43
+ });
44
+ },
45
+ 'font-url($filename, $only-path: false)': (filename, only_path, done) => {
46
+ processor.font_url(filename.getValue(), url => {
47
+ if (!only_path.getValue()) url = `url('${url}')`;
48
+ done(new sass.types.String(url));
49
+ });
50
+ },
51
+ 'font-files($filenames...)': (list, done) => {
52
+ let len = list.getLength(),
53
+ i = 0;
54
+ const filenames = [];
55
+ for (; i < len; ++i) {
56
+ filenames[i] = list.getValue(i).getValue();
57
+ }
58
+ processor.font_files(filenames, files => {
59
+ len = files.length;
60
+ i = 0;
61
+ list = new sass.types.List(len);
62
+ for (; i < len; ++i) {
63
+ list.setValue(i, new sass.types.String(`url('${files[i].url}') format('${files[i].type}')`));
64
+ }
65
+ done(list);
66
+ });
67
+ }
68
+ };
69
+ }
@@ -0,0 +1,175 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+ var _path = _interopRequireDefault(require("path"));
9
+ var _url = _interopRequireDefault(require("url"));
10
+ var _mime = _interopRequireDefault(require("mime"));
11
+ var _imageSize = _interopRequireDefault(require("image-size"));
12
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
+ /**
14
+ * Internal processor for the asset function suite.
15
+ *
16
+ * Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
17
+ * Licensed under the MIT license.
18
+ */
19
+
20
+ const defaultPaths = {
21
+ images_path: 'public/images',
22
+ fonts_path: 'public/fonts',
23
+ http_images_path: '/images',
24
+ http_fonts_path: '/fonts'
25
+ };
26
+ const FONT_TYPES = {
27
+ woff: 'woff',
28
+ woff2: 'woff2',
29
+ otf: 'opentype',
30
+ opentype: 'opentype',
31
+ ttf: 'truetype',
32
+ truetype: 'truetype',
33
+ svg: 'svg',
34
+ eot: 'embedded-opentype'
35
+ };
36
+ class Processor {
37
+ constructor(options = {}) {
38
+ this.options = options;
39
+ const {
40
+ images_path = defaultPaths.images_path,
41
+ fonts_path = defaultPaths.fonts_path,
42
+ http_images_path = defaultPaths.http_images_path,
43
+ http_fonts_path = defaultPaths.http_fonts_path
44
+ } = options;
45
+ this.paths = {
46
+ images_path,
47
+ fonts_path,
48
+ http_images_path,
49
+ http_fonts_path
50
+ };
51
+ }
52
+ asset_cache_buster(http_path, real_path, done) {
53
+ const {
54
+ asset_cache_buster: buster
55
+ } = this.options;
56
+ if (typeof buster !== 'function') {
57
+ throw new Error('asset_cache_buster should be a function');
58
+ }
59
+ const http_path_url = _url.default.parse(http_path);
60
+ buster(http_path, real_path, value => {
61
+ let new_url;
62
+ if (typeof value == 'object') {
63
+ const parsed_path = _url.default.parse(value.path);
64
+ new_url = {
65
+ pathname: parsed_path.pathname,
66
+ search: value.query || http_path_url.search
67
+ };
68
+ } else {
69
+ new_url = {
70
+ pathname: http_path_url.pathname,
71
+ search: value
72
+ };
73
+ }
74
+ done(_url.default.format(new_url));
75
+ });
76
+ }
77
+ asset_host(filepath, done) {
78
+ const {
79
+ asset_host: ahost
80
+ } = this.options;
81
+ if (typeof ahost !== 'function') {
82
+ throw new Error('asset_host should be a function');
83
+ }
84
+ ahost(filepath, host => {
85
+ done(_url.default.resolve(host, filepath));
86
+ });
87
+ }
88
+ real_path(filepath, segment) {
89
+ const sanitized_filepath = filepath.replace(/(#|\?).+$/, '');
90
+ return _path.default.resolve(this.paths[`${segment}_path`], sanitized_filepath);
91
+ }
92
+ http_path(filepath, segment) {
93
+ return _path.default.join(this.paths[`http_${segment}_path`], filepath).replace(/\\/g, '/');
94
+ }
95
+ image_width(filepath, done) {
96
+ done((0, _imageSize.default)(this.real_path(filepath, 'images')).width);
97
+ }
98
+ image_height(filepath, done) {
99
+ done((0, _imageSize.default)(this.real_path(filepath, 'images')).height);
100
+ }
101
+ inline_image(filepath, mime_type, done) {
102
+ const src = this.real_path(filepath, 'images');
103
+ mime_type = mime_type || _mime.default.getType(src);
104
+ _fs.default.readFile(src, (err, data) => {
105
+ if (err) {
106
+ throw new Error(`inline_image failed to read ${src}: ${err}`);
107
+ }
108
+ done(`data:${mime_type};base64,${data.toString('base64')}`);
109
+ });
110
+ }
111
+ asset_url(filepath, segment, done) {
112
+ let fragment = '';
113
+ let sanitized_http_path = this.http_path(filepath, segment);
114
+ const real_path = this.real_path(filepath, segment);
115
+ const fragmentIndex = sanitized_http_path.indexOf('#');
116
+ const restoreFragment = url => done(url + fragment);
117
+ const next = http_path => {
118
+ if (this.options.asset_host) {
119
+ this.asset_host(http_path, restoreFragment);
120
+ } else {
121
+ restoreFragment(http_path);
122
+ }
123
+ };
124
+ if (~fragmentIndex) {
125
+ fragment = sanitized_http_path.substring(fragmentIndex);
126
+ sanitized_http_path = sanitized_http_path.substring(0, fragmentIndex);
127
+ }
128
+ if (this.options.asset_cache_buster) {
129
+ this.asset_cache_buster(sanitized_http_path, real_path, next);
130
+ } else {
131
+ next(sanitized_http_path);
132
+ }
133
+ }
134
+ image_url(filepath, done) {
135
+ this.asset_url(filepath, 'images', done);
136
+ }
137
+ font_url(filepath, done) {
138
+ this.asset_url(filepath, 'fonts', done);
139
+ }
140
+ font_files(files, done) {
141
+ const processed_files = [];
142
+ let count = 0;
143
+ const complete = (index, type) => {
144
+ return url => {
145
+ processed_files[index] = {
146
+ url: url,
147
+ type: type
148
+ };
149
+ if (++count == files.length) {
150
+ done(processed_files);
151
+ }
152
+ };
153
+ };
154
+ let i = 0,
155
+ parts,
156
+ ext,
157
+ file,
158
+ next,
159
+ type;
160
+ for (; i < files.length; ++i) {
161
+ file = files[i];
162
+ next = files[i + 1];
163
+ parts = _url.default.parse(file);
164
+ if (FONT_TYPES[next]) {
165
+ type = files.splice(i + 1, 1);
166
+ } else {
167
+ ext = _path.default.extname(parts.path);
168
+ type = ext.substring(1);
169
+ }
170
+ type = FONT_TYPES[type];
171
+ this.font_url(file, complete(i, type));
172
+ }
173
+ }
174
+ }
175
+ exports.default = Processor;
package/index.js CHANGED
@@ -1,47 +1,53 @@
1
- const defaultSass = require('sass');
2
- const Processor = require('./lib/processor');
1
+ /**
2
+ * Sass asset function suite.
3
+ *
4
+ * Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
5
+ * Licensed under the MIT license.
6
+ */
7
+ import defaultSass from 'sass';
8
+ import Processor from './lib/processor.js';
3
9
 
4
- module.exports = function sassFunctions (options = {}) {
10
+ export default function sassFunctions (options = {}) {
5
11
  const { sass = defaultSass } = options;
6
12
  const processor = new Processor(options);
7
13
 
8
14
  return {
9
- 'image-url($filename, $only_path: false)': function (filename, only_path, done) {
10
- processor.image_url(filename.getValue(), function (url) {
15
+ 'image-url($filename, $only_path: false)': (filename, only_path, done) => {
16
+ processor.image_url(filename.getValue(), (url) => {
11
17
  if (!only_path.getValue()) url = `url('${url}')`;
12
18
  done(new sass.types.String(url));
13
19
  });
14
20
  },
15
- 'inline-image($filename, $mime_type: null)': function (filename, mime_type, done) {
21
+ 'inline-image($filename, $mime_type: null)': (filename, mime_type, done) => {
16
22
  mime_type = mime_type instanceof sass.types.Null ? null : mime_type.getValue();
17
- processor.inline_image(filename.getValue(), mime_type, function (dataUrl) {
23
+ processor.inline_image(filename.getValue(), mime_type, (dataUrl) => {
18
24
  done(new sass.types.String(`url('${dataUrl}')`));
19
25
  });
20
26
  },
21
- 'image-width($filename)': function (filename, done) {
22
- processor.image_width(filename.getValue(), function (image_width) {
27
+ 'image-width($filename)': (filename, done) => {
28
+ processor.image_width(filename.getValue(), (image_width) => {
23
29
  done(new sass.types.Number(image_width, 'px'));
24
30
  });
25
31
  },
26
- 'image-height($filename)': function (filename, done) {
27
- processor.image_height(filename.getValue(), function (image_height) {
32
+ 'image-height($filename)': (filename, done) => {
33
+ processor.image_height(filename.getValue(), (image_height) => {
28
34
  done(new sass.types.Number(image_height, 'px'));
29
35
  });
30
36
  },
31
- 'font-url($filename, $only-path: false)': function (filename, only_path, done) {
32
- processor.font_url(filename.getValue(), function (url) {
37
+ 'font-url($filename, $only-path: false)': (filename, only_path, done) => {
38
+ processor.font_url(filename.getValue(), (url) => {
33
39
  if (!only_path.getValue()) url = `url('${url}')`;
34
40
  done(new sass.types.String(url));
35
41
  });
36
42
  },
37
- 'font-files($filenames...)': function (list, done) {
43
+ 'font-files($filenames...)': (list, done) => {
38
44
  let len = list.getLength(), i = 0;
39
45
  const filenames = [];
40
46
  for(; i < len; ++i) {
41
47
  filenames[i] = list.getValue(i).getValue();
42
48
  }
43
49
 
44
- processor.font_files(filenames, function (files) {
50
+ processor.font_files(filenames, (files) => {
45
51
  len = files.length;
46
52
  i = 0;
47
53
  list = new sass.types.List(len);
@@ -52,4 +58,4 @@ module.exports = function sassFunctions (options = {}) {
52
58
  });
53
59
  }
54
60
  };
55
- };
61
+ }
package/jest.config.js CHANGED
@@ -1,4 +1,4 @@
1
- module.exports = {
1
+ export default {
2
2
  collectCoverage: true,
3
3
  coverageDirectory: 'coverage',
4
4
  verbose: true,
package/lib/processor.js CHANGED
@@ -1,11 +1,14 @@
1
1
  /**
2
2
  * Internal processor for the asset function suite.
3
+ *
4
+ * Copyright (c) 2023 Alex Grant (@localnerve), LocalNerve LLC
5
+ * Licensed under the MIT license.
3
6
  */
4
- const fs = require('fs');
5
- const path = require('path');
6
- const url = require('url');
7
- const mime = require('mime');
8
- const sizeOf = require('image-size');
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import url from 'url';
10
+ import mime from 'mime';
11
+ import sizeOf from 'image-size';
9
12
 
10
13
  const defaultPaths = {
11
14
  images_path: 'public/images',
@@ -25,7 +28,7 @@ const FONT_TYPES = {
25
28
  eot: 'embedded-opentype'
26
29
  };
27
30
 
28
- class Processor {
31
+ export default class Processor {
29
32
  constructor (options = {}) {
30
33
  this.options = options;
31
34
  const {
@@ -175,5 +178,3 @@ class Processor {
175
178
  }
176
179
  }
177
180
  }
178
-
179
- module.exports = Processor;
package/package.json CHANGED
@@ -1,11 +1,21 @@
1
1
  {
2
2
  "name": "@localnerve/sass-asset-functions",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "compass-style asset functions for dart-sass or other sass compilers",
5
5
  "main": "index.js",
6
+ "exports": {
7
+ "import": "./index.js",
8
+ "require": "./cjs/index.cjs",
9
+ "default": "./index.js"
10
+ },
11
+ "type": "module",
6
12
  "scripts": {
7
13
  "test": "jest",
8
- "lint": "eslint ."
14
+ "lint": "eslint .",
15
+ "pretranspile": "rimraf ./cjs",
16
+ "transpile": "babel index.js -o ./cjs/index.cjs && babel ./lib/processor.js -o ./cjs/lib/processor.cjs",
17
+ "posttranspile": "node posttranspile.cjs",
18
+ "prepublishOnly": "npm run transpile"
9
19
  },
10
20
  "repository": {
11
21
  "type": "git",
@@ -39,12 +49,15 @@
39
49
  "dependencies": {
40
50
  "image-size": "^1.0.2",
41
51
  "mime": "^3.0.0",
42
- "sass": "^1.54.9"
52
+ "sass": "^1.58.0"
43
53
  },
44
54
  "devDependencies": {
45
- "jest": "^29.0.3",
46
- "eslint": "^8.23.1",
47
- "node-sass": "^7.0.3"
55
+ "@babel/cli": "^7.20.7",
56
+ "@babel/preset-env": "^7.20.2",
57
+ "rimraf": "^4.1.2",
58
+ "jest": "^29.4.2",
59
+ "eslint": "^8.33.0",
60
+ "node-sass": "^8.0.0"
48
61
  },
49
62
  "engines": {
50
63
  "node": ">= 14"
@@ -0,0 +1,9 @@
1
+ const fs = require('node:fs');
2
+ const fileToChange = './cjs/index.cjs';
3
+ fs.readFile(fileToChange, 'utf8', (err, data) => {
4
+ if (err) throw err;
5
+ const newData = data.replace('./lib/processor.js', './lib/processor.cjs');
6
+ fs.writeFile(fileToChange, newData, err => {
7
+ if (err) throw err;
8
+ });
9
+ });
@@ -1,32 +0,0 @@
1
- name: Verify
2
- on:
3
- push:
4
- branches: [ master ]
5
- pull_request:
6
- branches: [ master ]
7
-
8
- jobs:
9
- verify:
10
-
11
- runs-on: ubuntu-latest
12
-
13
- strategy:
14
- matrix:
15
- node-version: [14.x, 16.x]
16
- # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
17
-
18
- steps:
19
- - uses: actions/checkout@v3
20
- - name: Use Node.js ${{ matrix.node-version }}
21
- uses: actions/setup-node@v3
22
- with:
23
- node-version: ${{ matrix.node-version }}
24
- - run: npm ci
25
- - name: Run Lint and Test
26
- run: npm run lint && npm test
27
- - name: Coverage Upload
28
- if: ${{ success() }}
29
- uses: coverallsapp/github-action@master
30
- with:
31
- github-token: ${{ secrets.GITHUB_TOKEN }}
32
- path-to-lcov: ./coverage/lcov.info
@@ -1,3 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('/fonts/SomeFont-v123.woff2') format('woff2'), url('/fonts/SomeFont-v123.woff') format('woff'), url('/fonts/SomeFont-v123.ttf') format('truetype'), url('/fonts/SomeFont-v123.svg#SomeFont') format('svg'); }
@@ -1,6 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('/fonts/SomeFont-v123.eot?#iefix'); }
4
-
5
- body {
6
- content: "/fonts/SomeFont-v123.eot?#iefix"; }
@@ -1,3 +0,0 @@
1
- #barney {
2
- width: 288px;
3
- height: 170px; }
@@ -1,5 +0,0 @@
1
- body {
2
- background: url('/images/barney-v123.gif') center center no-repeat; }
3
-
4
- #barney {
5
- content: "/images/barney-v123.gif"; }
@@ -1,2 +0,0 @@
1
- #npm {
2
- background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI5IiBoZWlnaHQ9IjUwIiB2aWV3Qm94PSIwIDAgMTI5IDUwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5VbnRpdGxlZCA5PC90aXRsZT48ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz48cGF0aCBkPSJNMCAwaDEyOXY0My4wNzdINjQuNVY1MEgzNS44NjJ2LTYuOTIzSDBWMHptNy4zMDIgMzUuNzY3aDE0LjI1di0yMS41Mmg3LjE2NHYyMS41Mmg3LjFWNy4zMDdINy4zMDJ2MjguNDZ6TTQyLjkxNCA3LjE4TDQzIDQzLjA3NmgxNC4xOXYtNy4xNjJoMTQuMzY1VjcuMThoLTI4LjY0em0xNC4xMDQgNi45MjNINjQuNXYxNC42MTVoLTcuNDgyVjE0LjEwM3pNNzguNzc2IDcuMTh2MjguNDZIOTMuMDVWMTQuMjc0aDcuMTRWMzUuNjRoNy4xM1YxNC4zNmg3LjE0NXYyMS4yOGg3LjE0VjcuMThoLTQyLjgzeiIgZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); }
@@ -1,3 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('/fonts/SomeFont.woff2?v=123') format('woff2'), url('/fonts/SomeFont.woff?v=123') format('woff'), url('/fonts/SomeFont.ttf?v=123') format('truetype'), url('/fonts/SomeFont.svg?v=123#SomeFont') format('svg'); }
@@ -1,6 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('/fonts/SomeFont.eot?v=123#iefix'); }
4
-
5
- body {
6
- content: "/fonts/SomeFont.eot?v=123#iefix"; }
@@ -1,3 +0,0 @@
1
- #barney {
2
- width: 288px;
3
- height: 170px; }
@@ -1,5 +0,0 @@
1
- body {
2
- background: url('/images/barney.gif?v=123') center center no-repeat; }
3
-
4
- #barney {
5
- content: "/images/barney.gif?v=123"; }
@@ -1,2 +0,0 @@
1
- #npm {
2
- background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI5IiBoZWlnaHQ9IjUwIiB2aWV3Qm94PSIwIDAgMTI5IDUwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5VbnRpdGxlZCA5PC90aXRsZT48ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz48cGF0aCBkPSJNMCAwaDEyOXY0My4wNzdINjQuNVY1MEgzNS44NjJ2LTYuOTIzSDBWMHptNy4zMDIgMzUuNzY3aDE0LjI1di0yMS41Mmg3LjE2NHYyMS41Mmg3LjFWNy4zMDdINy4zMDJ2MjguNDZ6TTQyLjkxNCA3LjE4TDQzIDQzLjA3NmgxNC4xOXYtNy4xNjJoMTQuMzY1VjcuMThoLTI4LjY0em0xNC4xMDQgNi45MjNINjQuNXYxNC42MTVoLTcuNDgyVjE0LjEwM3pNNzguNzc2IDcuMTh2MjguNDZIOTMuMDVWMTQuMjc0aDcuMTRWMzUuNjRoNy4xM1YxNC4zNmg3LjE0NXYyMS4yOGg3LjE0VjcuMThoLTQyLjgzeiIgZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); }
@@ -1,3 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('http://example.com/fonts/SomeFont.woff2') format('woff2'), url('http://example.com/fonts/SomeFont.woff') format('woff'), url('http://example.com/fonts/SomeFont.ttf') format('truetype'), url('http://example.com/fonts/SomeFont.svg#SomeFont') format('svg'); }
@@ -1,6 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('http://example.com/fonts/SomeFont.eot?#iefix'); }
4
-
5
- body {
6
- content: "http://example.com/fonts/SomeFont.eot?#iefix"; }
@@ -1,3 +0,0 @@
1
- #barney {
2
- width: 288px;
3
- height: 170px; }
@@ -1,5 +0,0 @@
1
- body {
2
- background: url('http://example.com/images/barney.gif') center center no-repeat; }
3
-
4
- #barney {
5
- content: "http://example.com/images/barney.gif"; }
@@ -1,2 +0,0 @@
1
- #npm {
2
- background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI5IiBoZWlnaHQ9IjUwIiB2aWV3Qm94PSIwIDAgMTI5IDUwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5VbnRpdGxlZCA5PC90aXRsZT48ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz48cGF0aCBkPSJNMCAwaDEyOXY0My4wNzdINjQuNVY1MEgzNS44NjJ2LTYuOTIzSDBWMHptNy4zMDIgMzUuNzY3aDE0LjI1di0yMS41Mmg3LjE2NHYyMS41Mmg3LjFWNy4zMDdINy4zMDJ2MjguNDZ6TTQyLjkxNCA3LjE4TDQzIDQzLjA3NmgxNC4xOXYtNy4xNjJoMTQuMzY1VjcuMThoLTI4LjY0em0xNC4xMDQgNi45MjNINjQuNXYxNC42MTVoLTcuNDgyVjE0LjEwM3pNNzguNzc2IDcuMTh2MjguNDZIOTMuMDVWMTQuMjc0aDcuMTRWMzUuNjRoNy4xM1YxNC4zNmg3LjE0NXYyMS4yOGg3LjE0VjcuMThoLTQyLjgzeiIgZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); }
@@ -1,3 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('/fonts/SomeFont.woff2') format('woff2'), url('/fonts/SomeFont.woff') format('woff'), url('/fonts/SomeFont.ttf') format('truetype'), url('/fonts/SomeFont.svg#SomeFont') format('svg'); }
@@ -1,6 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: url('/fonts/SomeFont.eot?#iefix'); }
4
-
5
- body {
6
- content: "/fonts/SomeFont.eot?#iefix"; }
@@ -1,3 +0,0 @@
1
- #barney {
2
- width: 288px;
3
- height: 170px; }
@@ -1,5 +0,0 @@
1
- body {
2
- background: url('/images/barney.gif') center center no-repeat; }
3
-
4
- #barney {
5
- content: "/images/barney.gif"; }
@@ -1,2 +0,0 @@
1
- #npm {
2
- background: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTI5IiBoZWlnaHQ9IjUwIiB2aWV3Qm94PSIwIDAgMTI5IDUwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjx0aXRsZT5VbnRpdGxlZCA5PC90aXRsZT48ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz48cGF0aCBkPSJNMCAwaDEyOXY0My4wNzdINjQuNVY1MEgzNS44NjJ2LTYuOTIzSDBWMHptNy4zMDIgMzUuNzY3aDE0LjI1di0yMS41Mmg3LjE2NHYyMS41Mmg3LjFWNy4zMDdINy4zMDJ2MjguNDZ6TTQyLjkxNCA3LjE4TDQzIDQzLjA3NmgxNC4xOXYtNy4xNjJoMTQuMzY1VjcuMThoLTI4LjY0em0xNC4xMDQgNi45MjNINjQuNXYxNC42MTVoLTcuNDgyVjE0LjEwM3pNNzguNzc2IDcuMTh2MjguNDZIOTMuMDVWMTQuMjc0aDcuMTRWMzUuNjRoNy4xM1YxNC4zNmg3LjE0NXYyMS4yOGg3LjE0VjcuMThoLTQyLjgzeiIgZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+'); }
Binary file
@@ -1 +0,0 @@
1
- <svg width="129" height="50" viewBox="0 0 129 50" xmlns="http://www.w3.org/2000/svg"><title>Untitled 9</title><desc>Created with Sketch.</desc><path d="M0 0h129v43.077H64.5V50H35.862v-6.923H0V0zm7.302 35.767h14.25v-21.52h7.164v21.52h7.1V7.307H7.302v28.46zM42.914 7.18L43 43.076h14.19v-7.162h14.365V7.18h-28.64zm14.104 6.923H64.5v14.615h-7.482V14.103zM78.776 7.18v28.46H93.05V14.274h7.14V35.64h7.13V14.36h7.145v21.28h7.14V7.18h-42.83z" fill="#000" fill-rule="evenodd"/></svg>
@@ -1,4 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: font-files('SomeFont.woff2', 'woff2', 'SomeFont.woff', 'SomeFont.ttf', 'SomeFont.svg#SomeFont');
4
- }
@@ -1,8 +0,0 @@
1
- @font-face {
2
- font-family: 'SomeFont';
3
- src: font-url('SomeFont.eot?#iefix');
4
- }
5
-
6
- body {
7
- content: '#{font-url('SomeFont.eot?#iefix', $only-path: true)}';
8
- }
@@ -1,4 +0,0 @@
1
- #barney {
2
- width: image-width('barney.gif');
3
- height: image-height('barney.gif');
4
- }
@@ -1,7 +0,0 @@
1
- body {
2
- background: image-url('barney.gif') center center no-repeat;
3
- }
4
-
5
- #barney {
6
- content: '#{image-url('barney.gif', $only-path: true)}';
7
- }
@@ -1,3 +0,0 @@
1
- #npm {
2
- background: inline-image('npm.svg');
3
- }
package/__tests__/test.js DELETED
@@ -1,145 +0,0 @@
1
- /**
2
- * Test driver.
3
- */
4
- /* eslint-env jest */
5
-
6
- const fs = require('fs');
7
- const path = require('path');
8
- const otherSass = require('node-sass');
9
- const defaultSass = require('sass');
10
- const assetFunctions = require('../');
11
-
12
- const sassDir = path.join(__dirname, 'scss');
13
- const cssDir = path.join(__dirname, 'css');
14
- const otherSassOpts = { sass: otherSass };
15
- const files = fs.readdirSync(sassDir);
16
-
17
- function renderAsync (file, options = {}, done) {
18
- const { sass = defaultSass } = options;
19
-
20
- options.images_path = `${__dirname}/images`;
21
- options.fonts_path = `${__dirname}/fonts`;
22
-
23
- return sass.render({
24
- functions: assetFunctions(options),
25
- file: `${__dirname}/scss/${file}` // dart-sass will not find w/o jest testEnvironment 'node'
26
- }, done);
27
- }
28
-
29
- function equalsFileAsync (file, suite, options, done) {
30
- renderAsync(file, options, (err, result) => {
31
- expect(err).toBeNull();
32
- if (err) {
33
- return done(err);
34
- }
35
-
36
- const cssPath = path.join(cssDir, suite, file.replace(/\.scss$/, '.css'));
37
- fs.readFile(cssPath, (err, expected) => {
38
- expect(err).toBeNull();
39
- if (err) {
40
- return done(err);
41
- }
42
-
43
- const rendered = result.css.toString();
44
- const raw = expected.toString();
45
-
46
- // Output style differences between node-sass and dart-sass, spacing and quotes '|".
47
- // For output equality comparison, strip quotes and spaces.
48
- const stripRendered = rendered.replace(/\s+|"|'/g, '');
49
- const stripRaw = raw.replace(/\s+|"|'/g, '');
50
-
51
- expect(stripRendered).toEqual(stripRaw);
52
- done();
53
- });
54
- });
55
- }
56
-
57
- function asset_host (http_path, done) {
58
- done('http://example.com');
59
- }
60
-
61
- function query_asset_cache_buster (http_path, real_path, done) {
62
- setTimeout(done, 10, 'v=123');
63
- }
64
-
65
- function path_asset_cache_buster (http_path, real_path, done) {
66
- setTimeout(() => {
67
- const extname = path.extname(http_path);
68
- const basename = path.basename(http_path, extname);
69
- const dirname = path.dirname(http_path);
70
-
71
- done({
72
- path: `${path.join(dirname, `${basename}-v123`)}${extname}`,
73
- query: null
74
- });
75
- }, 10);
76
- }
77
-
78
- function chain (done, next, err) {
79
- if (err) {
80
- return done(err);
81
- }
82
- next();
83
- }
84
-
85
- describe('basic', function () {
86
- files.forEach(file => {
87
- test(file, done => {
88
- const run = equalsFileAsync.bind(this, file, 'basic');
89
- const next = chain.bind(this, done, () => {
90
- run(otherSassOpts, done);
91
- });
92
- run({}, next);
93
- });
94
- });
95
- });
96
-
97
- describe('asset_host', function () {
98
- files.forEach(file => {
99
- test(file, done => {
100
- const run = equalsFileAsync.bind(this, file, 'asset_host');
101
- const opts = { asset_host: asset_host };
102
- const next = chain.bind(this, done, () => {
103
- run({
104
- ...otherSassOpts,
105
- ...opts
106
- }, done);
107
- });
108
- run(opts, next);
109
- });
110
- });
111
- });
112
-
113
- describe('asset_cache_buster', function () {
114
- describe('using query', function () {
115
- files.forEach(file => {
116
- test(file, done => {
117
- const run = equalsFileAsync.bind(this, file, 'asset_cache_buster/query');
118
- const opts = { asset_cache_buster: query_asset_cache_buster };
119
- const next = chain.bind(this, done, () => {
120
- run({
121
- ...otherSassOpts,
122
- ...opts
123
- }, done);
124
- });
125
- run(opts, next);
126
- });
127
- });
128
- });
129
-
130
- describe('using path', function () {
131
- files.forEach(file => {
132
- test(file, done => {
133
- const run = equalsFileAsync.bind(this, file, 'asset_cache_buster/path');
134
- const opts = { asset_cache_buster: path_asset_cache_buster };
135
- const next = chain.bind(this, done, () => {
136
- run({
137
- ...otherSassOpts,
138
- ...opts
139
- }, done);
140
- });
141
- run(opts, next);
142
- });
143
- });
144
- });
145
- });