@emulsify/core 3.1.1 → 3.3.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.
- package/.storybook/main.js +4 -4
- package/config/webpack/loaders.js +29 -15
- package/config/webpack/optimizers.js +0 -1
- package/config/webpack/plugins.js +188 -41
- package/config/webpack/resolves.js +110 -44
- package/config/webpack/webpack.common.js +197 -156
- package/package.json +28 -29
- package/scripts/a11y.js +83 -23
- package/scripts/a11y.test.js +51 -38
|
@@ -1,26 +1,99 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @fileoverview Webpack
|
|
3
|
-
*
|
|
2
|
+
* @fileoverview Build Webpack entries and export the configuration.
|
|
3
|
+
* - Discovers JS/SCSS assets (base + component) via glob patterns
|
|
4
|
+
* - Shapes output paths based on platform and SDC (singleDirectoryComponents)
|
|
5
|
+
* - Wires up loaders, plugins, and optimizations
|
|
4
6
|
*/
|
|
5
7
|
|
|
6
|
-
import {
|
|
8
|
+
import { posix as path } from 'node:path';
|
|
7
9
|
import { sync as globSync } from 'glob';
|
|
8
10
|
import fs from 'fs-extra';
|
|
11
|
+
|
|
9
12
|
import loaders from './loaders.js';
|
|
10
13
|
import plugins from './plugins.js';
|
|
11
14
|
import resolves from './resolves.js';
|
|
12
15
|
import optimizers from './optimizers.js';
|
|
13
16
|
import emulsifyConfig from '../../../../../project.emulsify.json' with { type: 'json' };
|
|
14
17
|
|
|
15
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Resolve the directory of this file (without fileURLToPath).
|
|
20
|
+
* @type {string}
|
|
21
|
+
*/
|
|
16
22
|
let _filename = decodeURIComponent(new URL(import.meta.url).pathname);
|
|
17
|
-
|
|
18
|
-
// On Windows, remove the leading slash (e.g. "/C:/path" -> "C:/path")
|
|
19
23
|
if (process.platform === 'win32' && _filename.startsWith('/')) {
|
|
20
24
|
_filename = _filename.slice(1);
|
|
21
25
|
}
|
|
26
|
+
const _dirname = path.dirname(_filename);
|
|
27
|
+
|
|
28
|
+
/** @type {string} Absolute project root (five levels up from this file). */
|
|
29
|
+
const projectDir = path.resolve(_dirname, '../../../../..');
|
|
30
|
+
|
|
31
|
+
/** @type {boolean} True when a "src/" directory exists (WP layout). */
|
|
32
|
+
const hasSrc = fs.pathExistsSync(path.resolve(projectDir, 'src'));
|
|
33
|
+
|
|
34
|
+
/** @type {string} The canonical source directory ("src" if present, else "components"). */
|
|
35
|
+
const srcDir = hasSrc
|
|
36
|
+
? path.resolve(projectDir, 'src')
|
|
37
|
+
: path.resolve(projectDir, 'components');
|
|
38
|
+
|
|
39
|
+
/** @type {boolean} True when platform is Drupal (affects component output root). */
|
|
40
|
+
const isDrupal = emulsifyConfig?.project?.platform === 'drupal';
|
|
41
|
+
|
|
42
|
+
/** @type {boolean} Respect SDC (single-directory-components) layout if explicitly true. */
|
|
43
|
+
const SDC = Boolean(emulsifyConfig?.project?.singleDirectoryComponents);
|
|
44
|
+
|
|
45
|
+
/** @type {string} Output base for "global" assets. */
|
|
46
|
+
const globalOutBase = hasSrc ? 'dist/global' : 'dist';
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Create a path under the component output root.
|
|
50
|
+
* - In Drupal + src layout, components resolve to "components/…"
|
|
51
|
+
* - Otherwise, they resolve to "dist/components/…"
|
|
52
|
+
* @param {string} subpath - Component-local subpath (no extension).
|
|
53
|
+
* @returns {string} Component output path segment.
|
|
54
|
+
*/
|
|
55
|
+
const componentOutPath = (subpath) =>
|
|
56
|
+
(isDrupal && hasSrc ? 'components' : 'dist/components') + '/' + subpath;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Join segments with POSIX semantics (forward slashes), trimming empties.
|
|
60
|
+
* @param {...string} segs - Path segments.
|
|
61
|
+
* @returns {string} POSIX-joined path.
|
|
62
|
+
*/
|
|
63
|
+
const pj = (...segs) => path.join(...segs.filter(Boolean));
|
|
22
64
|
|
|
23
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Compute the “dist subpath” for a non-component asset.
|
|
67
|
+
* Inserts a type folder ("js" or "css") when SDC = false.
|
|
68
|
+
* Drops the original file extension.
|
|
69
|
+
* @param {string} absFile - Absolute file path.
|
|
70
|
+
* @param {'js'|'css'} type - Asset type.
|
|
71
|
+
* @returns {string} Subpath under the global output base (no extension).
|
|
72
|
+
*/
|
|
73
|
+
const distSubpathForBase = (absFile, type) => {
|
|
74
|
+
const rel = path.relative(srcDir, absFile);
|
|
75
|
+
const dir = path.dirname(rel);
|
|
76
|
+
const name = path.basename(rel, '.' + type);
|
|
77
|
+
return SDC ? pj(dir, name) : pj(dir, type, name);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Compute the “dist subpath” for a component asset located under "…/components".
|
|
82
|
+
* Inserts a type folder ("js" or "css") when SDC = false.
|
|
83
|
+
* Drops the original file extension.
|
|
84
|
+
* @param {string} absFile - Absolute file path.
|
|
85
|
+
* @param {'js'|'scss'} type - Source type (scss maps to 'css').
|
|
86
|
+
* @returns {string} Component-local subpath (no extension).
|
|
87
|
+
*/
|
|
88
|
+
const distSubpathForComponent = (absFile, type) => {
|
|
89
|
+
const relFromComponents = path.relative(pj(srcDir, 'components'), absFile);
|
|
90
|
+
const dir = path.dirname(relFromComponents);
|
|
91
|
+
const isStyle = type === 'scss';
|
|
92
|
+
const outTypeDir = isStyle ? 'css' : 'js';
|
|
93
|
+
const ext = isStyle ? '.scss' : '.js';
|
|
94
|
+
const name = path.basename(relFromComponents, ext);
|
|
95
|
+
return SDC ? pj(dir, name) : pj(dir, outTypeDir, name);
|
|
96
|
+
};
|
|
24
97
|
|
|
25
98
|
/**
|
|
26
99
|
* Sanitize a file path by removing unwanted characters.
|
|
@@ -30,170 +103,134 @@ const _dirname = dirname(_filename);
|
|
|
30
103
|
*/
|
|
31
104
|
const sanitizePath = (inputPath) => inputPath.replace(/[^a-zA-Z0-9/_-]/g, '');
|
|
32
105
|
|
|
33
|
-
|
|
34
|
-
|
|
106
|
+
/**
|
|
107
|
+
* Reject keys that could touch object internals even after sanitization.
|
|
108
|
+
* @param {string} k
|
|
109
|
+
* @returns {boolean}
|
|
110
|
+
*/
|
|
111
|
+
const isDangerousKey = (k) =>
|
|
112
|
+
k.includes('__proto__') || k.includes('prototype') || k === 'constructor';
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Add a file under an entry key; if the key exists, merge to an array.
|
|
116
|
+
* Keeps JS before SCSS for deterministic order.
|
|
117
|
+
*
|
|
118
|
+
* @param {Map<string, string | string[]>} map
|
|
119
|
+
* @param {string} key
|
|
120
|
+
* @param {string} file
|
|
121
|
+
* @returns {void}
|
|
122
|
+
*/
|
|
123
|
+
const addEntry = (map, key, file) => {
|
|
124
|
+
const safeKey = sanitizePath(String(key));
|
|
125
|
+
if (!safeKey || isDangerousKey(safeKey)) return;
|
|
35
126
|
|
|
36
|
-
const
|
|
37
|
-
const isSrcExists = fs.pathExistsSync(srcPath);
|
|
38
|
-
const srcDir = isSrcExists ? srcPath : resolve(projectDir, 'components');
|
|
39
|
-
const isDrupal = emulsifyConfig.project.platform === 'drupal';
|
|
127
|
+
const current = map.get(safeKey);
|
|
40
128
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const ComponentScssPattern = fs.pathExistsSync(resolve(projectDir, 'src'))
|
|
46
|
-
? resolve(srcDir, 'components/**/!(_*|cl-*|sb-*).scss')
|
|
47
|
-
: resolve(srcDir, '**/!(_*|cl-*|sb-*).scss');
|
|
48
|
-
const ComponentLibraryScssPattern = resolve(srcDir, '**/*{cl-*,sb-*}.scss');
|
|
49
|
-
|
|
50
|
-
// Glob pattern for JS files.
|
|
51
|
-
const BaseJsPattern = fs.pathExistsSync(resolve(projectDir, 'src'))
|
|
52
|
-
? resolve(
|
|
53
|
-
srcDir,
|
|
54
|
-
'!(components|util)/**/!(*.stories|*.component|*.min|*.test).js',
|
|
55
|
-
)
|
|
56
|
-
: '';
|
|
57
|
-
const ComponentJsPattern = fs.pathExistsSync(resolve(projectDir, 'src'))
|
|
58
|
-
? resolve(srcDir, 'components/**/!(*.stories|*.component|*.min|*.test).js')
|
|
59
|
-
: resolve(srcDir, '**/!(*.stories|*.component|*.min|*.test).js');
|
|
129
|
+
if (!current) {
|
|
130
|
+
map.set(safeKey, file);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
60
133
|
|
|
61
|
-
|
|
62
|
-
|
|
134
|
+
const arr = Array.isArray(current) ? current : [current];
|
|
135
|
+
if (!arr.includes(file)) arr.push(file);
|
|
136
|
+
|
|
137
|
+
// Optional: ensure JS comes before SCSS
|
|
138
|
+
arr.sort((a, b) => {
|
|
139
|
+
const ax = a.endsWith('.js') ? 0 : 1;
|
|
140
|
+
const bx = b.endsWith('.js') ? 0 : 1;
|
|
141
|
+
return ax - bx || a.localeCompare(b);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
map.set(safeKey, arr);
|
|
145
|
+
};
|
|
63
146
|
|
|
64
147
|
/**
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* @
|
|
68
|
-
* @param {string} replacement - The string to replace the last slash with.
|
|
69
|
-
* @returns {string} The modified string.
|
|
148
|
+
* Safe glob wrapper: returns [] if the pattern is falsy.
|
|
149
|
+
* @param {string} pattern - Glob pattern.
|
|
150
|
+
* @returns {string[]} Matching file paths.
|
|
70
151
|
*/
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
)
|
|
79
|
-
|
|
152
|
+
const glob = (pattern) => (pattern ? globSync(pattern) : []);
|
|
153
|
+
|
|
154
|
+
/* -------------------------------------------------------------------------- */
|
|
155
|
+
/* GLOBS */
|
|
156
|
+
/* -------------------------------------------------------------------------- */
|
|
157
|
+
|
|
158
|
+
const BaseScssPattern = hasSrc
|
|
159
|
+
? pj(srcDir, '!(components|util)/**/!(_*|cl-*|sb-*).scss')
|
|
160
|
+
: '';
|
|
161
|
+
|
|
162
|
+
const ComponentScssPattern = hasSrc
|
|
163
|
+
? pj(srcDir, 'components/**/!(_*|cl-*|sb-*).scss')
|
|
164
|
+
: pj(srcDir, '**/!(_*|cl-*|sb-*).scss');
|
|
165
|
+
|
|
166
|
+
const ComponentLibraryScssPattern = pj(srcDir, '**/*{cl-*,sb-*}.scss');
|
|
167
|
+
|
|
168
|
+
const BaseJsPattern = hasSrc
|
|
169
|
+
? pj(srcDir, '!(components|util)/**/!(*.stories|*.component|*.min|*.test).js')
|
|
170
|
+
: '';
|
|
171
|
+
|
|
172
|
+
const ComponentJsPattern = hasSrc
|
|
173
|
+
? pj(srcDir, 'components/**/!(*.stories|*.component|*.min|*.test).js')
|
|
174
|
+
: pj(srcDir, '**/!(*.stories|*.component|*.min|*.test).js');
|
|
175
|
+
|
|
176
|
+
/* -------------------------------------------------------------------------- */
|
|
177
|
+
/* ENTRY BUILD */
|
|
178
|
+
/* -------------------------------------------------------------------------- */
|
|
80
179
|
|
|
81
180
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
* @param {string} BaseJsMatcher - Glob pattern for base JS files.
|
|
85
|
-
* @param {string} jsMatcher - Glob pattern for component JS files.
|
|
86
|
-
* @param {string} BaseScssMatcher - Glob pattern for base SCSS files.
|
|
87
|
-
* @param {string} ComponentScssMatcher - Glob pattern for component SCSS files.
|
|
88
|
-
* @param {string} ComponentLibraryScssMatcher - Glob pattern for component library SCSS files.
|
|
89
|
-
* @param {string} spriteMatcher - Glob pattern for SVG sprite configuration.
|
|
90
|
-
* @returns {Object} An object containing the Webpack entries.
|
|
181
|
+
* Build the complete Webpack entries map.
|
|
182
|
+
* @returns {Record<string,string>} Webpack entries.
|
|
91
183
|
*/
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
BaseScssMatcher,
|
|
96
|
-
ComponentScssMatcher,
|
|
97
|
-
ComponentLibraryScssMatcher,
|
|
98
|
-
spriteMatcher,
|
|
99
|
-
) {
|
|
100
|
-
const entries = {};
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Add an entry to the entries object after sanitizing the key.
|
|
104
|
-
*
|
|
105
|
-
* @param {string} key - The key for the entry.
|
|
106
|
-
* @param {string} file - The file path to associate with the entry.
|
|
107
|
-
*/
|
|
108
|
-
const addEntry = (key, file) => {
|
|
109
|
-
const sanitizedKey = sanitizePath(key);
|
|
110
|
-
if (
|
|
111
|
-
sanitizedKey &&
|
|
112
|
-
!Object.prototype.hasOwnProperty.call(entries, sanitizedKey)
|
|
113
|
-
) {
|
|
114
|
-
// eslint-disable-next-line security/detect-object-injection
|
|
115
|
-
entries[sanitizedKey] = file;
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// Non-component or global JS entries.
|
|
120
|
-
globSync(BaseJsMatcher).forEach((file) => {
|
|
121
|
-
const filePath = file.split(`${srcDir}/`)[1];
|
|
122
|
-
const pathParts = filePath.split('/');
|
|
123
|
-
const filePathDist = `${pathParts.slice(0, -1).join('/')}/js/${pathParts
|
|
124
|
-
.at(-1)
|
|
125
|
-
.replace('.js', '')}`;
|
|
126
|
-
const newFilePath = fs.pathExistsSync(resolve(projectDir, 'src'))
|
|
127
|
-
? `dist/global/${filePathDist}`
|
|
128
|
-
: `dist/js/${filePathDist}`;
|
|
129
|
-
addEntry(newFilePath, file);
|
|
130
|
-
});
|
|
184
|
+
const buildEntries = () => {
|
|
185
|
+
/** @type {Map<string, string | string[]>} */
|
|
186
|
+
const entries = new Map();
|
|
131
187
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const newFilePath = `${prefix}/${filePathDist}`;
|
|
140
|
-
addEntry(newFilePath, file);
|
|
141
|
-
}
|
|
142
|
-
});
|
|
188
|
+
/* ----------------------------- Base / Global JS ----------------------------- */
|
|
189
|
+
for (const file of glob(BaseJsPattern)) {
|
|
190
|
+
const sub = distSubpathForBase(file, 'js');
|
|
191
|
+
// If no "src/", legacy layout puts global JS directly under "dist/js".
|
|
192
|
+
const outRoot = hasSrc ? pj(globalOutBase) : pj('dist', 'js');
|
|
193
|
+
addEntry(entries, pj(outRoot, sub), file);
|
|
194
|
+
}
|
|
143
195
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
.replace('.scss', '')}`;
|
|
151
|
-
const newFilePath = fs.pathExistsSync(resolve(projectDir, 'src'))
|
|
152
|
-
? `dist/global/${filePathDist}`
|
|
153
|
-
: `dist/css/${filePathDist}`;
|
|
154
|
-
addEntry(newFilePath, file);
|
|
155
|
-
});
|
|
196
|
+
/* --------------------------- Component JS (no dist) -------------------------- */
|
|
197
|
+
for (const file of glob(ComponentJsPattern)) {
|
|
198
|
+
if (file.includes('/dist/')) continue; // guard against accidental recursion
|
|
199
|
+
const sub = distSubpathForComponent(file, 'js');
|
|
200
|
+
addEntry(entries, componentOutPath(sub), file);
|
|
201
|
+
}
|
|
156
202
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
const
|
|
160
|
-
|
|
161
|
-
const
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
addEntry(newFilePath, file);
|
|
165
|
-
});
|
|
203
|
+
/* ------------------------------ Base / Global CSS --------------------------- */
|
|
204
|
+
for (const file of glob(BaseScssPattern)) {
|
|
205
|
+
const sub = distSubpathForBase(file, 'css');
|
|
206
|
+
// If no "src/", legacy layout puts global CSS directly under "dist/css".
|
|
207
|
+
const outRoot = hasSrc ? pj(globalOutBase) : pj('dist', 'css');
|
|
208
|
+
addEntry(entries, pj(outRoot, sub), file);
|
|
209
|
+
}
|
|
166
210
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
});
|
|
211
|
+
/* ---------------------------- Component CSS (SCSS) --------------------------- */
|
|
212
|
+
for (const file of glob(ComponentScssPattern)) {
|
|
213
|
+
const sub = distSubpathForComponent(file, 'scss'); // maps to css
|
|
214
|
+
addEntry(entries, componentOutPath(sub), file);
|
|
215
|
+
}
|
|
173
216
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
});
|
|
217
|
+
/* -------------------------- Component Library (Storybook) -------------------- */
|
|
218
|
+
for (const file of glob(ComponentLibraryScssPattern)) {
|
|
219
|
+
const rel = path.relative(srcDir, file).replace(/\.scss$/, '');
|
|
220
|
+
addEntry(entries, pj('dist', 'storybook', rel), file);
|
|
221
|
+
}
|
|
180
222
|
|
|
181
|
-
return entries;
|
|
182
|
-
}
|
|
223
|
+
return Object.fromEntries(entries);
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
/* -------------------------------------------------------------------------- */
|
|
227
|
+
/* WEBPACK CONFIG EXPORT */
|
|
228
|
+
/* -------------------------------------------------------------------------- */
|
|
183
229
|
|
|
184
230
|
export default {
|
|
185
231
|
target: 'web',
|
|
186
|
-
stats: {
|
|
187
|
-
|
|
188
|
-
},
|
|
189
|
-
entry: getEntries(
|
|
190
|
-
BaseJsPattern,
|
|
191
|
-
ComponentJsPattern,
|
|
192
|
-
BaseScssPattern,
|
|
193
|
-
ComponentScssPattern,
|
|
194
|
-
ComponentLibraryScssPattern,
|
|
195
|
-
spritePattern,
|
|
196
|
-
),
|
|
232
|
+
stats: { errorDetails: true },
|
|
233
|
+
entry: buildEntries(),
|
|
197
234
|
module: {
|
|
198
235
|
rules: [
|
|
199
236
|
loaders.CSSLoader,
|
|
@@ -204,22 +241,26 @@ export default {
|
|
|
204
241
|
],
|
|
205
242
|
},
|
|
206
243
|
plugins: [
|
|
244
|
+
plugins.RemoveEmptyJS,
|
|
207
245
|
plugins.MiniCssExtractPlugin,
|
|
208
246
|
plugins.ImageminPlugin,
|
|
209
|
-
plugins.
|
|
247
|
+
plugins.SpritePlugin,
|
|
210
248
|
plugins.ProgressPlugin,
|
|
211
249
|
plugins.CopyTwigPlugin,
|
|
250
|
+
plugins.CopyComponentAssetsPlugin,
|
|
251
|
+
...(plugins.CopyGlobalAssetsPlugin ? [plugins.CopyGlobalAssetsPlugin] : []),
|
|
212
252
|
plugins.CleanWebpackPlugin,
|
|
213
253
|
],
|
|
214
254
|
output: {
|
|
215
|
-
path:
|
|
255
|
+
path: projectDir,
|
|
216
256
|
filename: '[name].js',
|
|
217
257
|
},
|
|
218
258
|
resolve: resolves.TwigResolve,
|
|
219
259
|
optimization: optimizers,
|
|
260
|
+
// Quiet deprecation noise from Sass @import warnings
|
|
220
261
|
ignoreWarnings: [
|
|
221
262
|
(warning) =>
|
|
222
|
-
warning
|
|
263
|
+
Boolean(warning?.message) &&
|
|
223
264
|
/Sass @import rules are deprecated/.test(warning.message),
|
|
224
265
|
],
|
|
225
266
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emulsify/core",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Bundled tooling for Storybook development + Webpack Build",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"component library",
|
|
@@ -50,11 +50,11 @@
|
|
|
50
50
|
"twatch": "jest --no-coverage --watch --verbose"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@babel/core": "^7.
|
|
54
|
-
"@babel/eslint-parser": "^7.
|
|
55
|
-
"@babel/preset-env": "^7.
|
|
53
|
+
"@babel/core": "^7.28.4",
|
|
54
|
+
"@babel/eslint-parser": "^7.28.4",
|
|
55
|
+
"@babel/preset-env": "^7.28.3",
|
|
56
56
|
"@emulsify/cli": "^1.11.4",
|
|
57
|
-
"@eslint/js": "^9.
|
|
57
|
+
"@eslint/js": "^9.35.0",
|
|
58
58
|
"@storybook/addon-a11y": "^8.6.14",
|
|
59
59
|
"@storybook/addon-actions": "^8.6.14",
|
|
60
60
|
"@storybook/addon-essentials": "^8.6.14",
|
|
@@ -72,61 +72,60 @@
|
|
|
72
72
|
"babel-preset-minify": "^0.5.2",
|
|
73
73
|
"bem-twig-extension": "^0.1.1",
|
|
74
74
|
"breakpoint-sass": "^3.0.0",
|
|
75
|
-
"chalk": "^5.4.1",
|
|
76
75
|
"clean-webpack-plugin": "^4.0.0",
|
|
77
|
-
"concurrently": "^9.2.
|
|
78
|
-
"copy-webpack-plugin": "^13.0.
|
|
76
|
+
"concurrently": "^9.2.1",
|
|
77
|
+
"copy-webpack-plugin": "^13.0.1",
|
|
79
78
|
"css-loader": "^7.1.1",
|
|
80
|
-
"eslint": "^9.
|
|
81
|
-
"eslint-config-prettier": "^10.1.
|
|
79
|
+
"eslint": "^9.35.0",
|
|
80
|
+
"eslint-config-prettier": "^10.1.8",
|
|
82
81
|
"eslint-plugin-import": "^2.32.0",
|
|
83
82
|
"eslint-plugin-jest": "^29.0.1",
|
|
84
|
-
"eslint-plugin-prettier": "^5.5.
|
|
83
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
85
84
|
"eslint-plugin-security": "^3.0.1",
|
|
86
85
|
"eslint-plugin-storybook": "^0.12.0",
|
|
87
86
|
"eslint-webpack-plugin": "^5.0.2",
|
|
88
87
|
"file-loader": "^6.2.0",
|
|
89
|
-
"fs-extra": "^11.3.
|
|
88
|
+
"fs-extra": "^11.3.1",
|
|
90
89
|
"glob": "^11.0.3",
|
|
91
90
|
"graceful-fs": "^4.2.11",
|
|
92
|
-
"html-webpack-plugin": "^5.6.
|
|
93
|
-
"image-minimizer-webpack-plugin": "^4.1.
|
|
91
|
+
"html-webpack-plugin": "^5.6.4",
|
|
92
|
+
"image-minimizer-webpack-plugin": "^4.1.4",
|
|
94
93
|
"imagemin": "^9.0.1",
|
|
95
|
-
"imagemin-gifsicle": "^7.0.0",
|
|
96
94
|
"imagemin-jpegtran": "^8.0.0",
|
|
97
95
|
"imagemin-optipng": "^8.0.0",
|
|
98
|
-
"jest": "^30.
|
|
99
|
-
"jest-environment-jsdom": "^30.
|
|
96
|
+
"jest": "^30.1.3",
|
|
97
|
+
"jest-environment-jsdom": "^30.1.2",
|
|
100
98
|
"js-yaml": "^4.1.0",
|
|
101
99
|
"js-yaml-loader": "^1.2.2",
|
|
102
|
-
"mini-css-extract-plugin": "^2.9.
|
|
100
|
+
"mini-css-extract-plugin": "^2.9.4",
|
|
103
101
|
"node-sass-glob-importer": "^5.3.3",
|
|
104
102
|
"normalize.css": "^8.0.1",
|
|
105
103
|
"open-cli": "^8.0.0",
|
|
106
104
|
"pa11y": "^9.0.0",
|
|
107
105
|
"postcss": "^8.5.6",
|
|
108
|
-
"postcss-loader": "^8.
|
|
106
|
+
"postcss-loader": "^8.2.0",
|
|
109
107
|
"postcss-scss": "^4.0.9",
|
|
110
108
|
"ramda": "^0.31.3",
|
|
111
109
|
"regenerator-runtime": "^0.14.1",
|
|
112
|
-
"sass": "^1.
|
|
110
|
+
"sass": "^1.92.1",
|
|
113
111
|
"sass-loader": "^16.0.5",
|
|
114
112
|
"storybook": "^8.6.14",
|
|
115
|
-
"style-dictionary": "^
|
|
116
|
-
"stylelint": "^16.
|
|
113
|
+
"style-dictionary": "^5.0.4",
|
|
114
|
+
"stylelint": "^16.24.0",
|
|
117
115
|
"stylelint-config-standard-scss": "^15.0.1",
|
|
118
116
|
"stylelint-prettier": "^5.0.3",
|
|
119
117
|
"stylelint-selector-bem-pattern": "^4.0.1",
|
|
120
118
|
"stylelint-webpack-plugin": "^5.0.1",
|
|
121
|
-
"svg-
|
|
119
|
+
"svg-spritemap-webpack-plugin": "^5.0.1",
|
|
122
120
|
"token-transformer": "^0.0.33",
|
|
123
121
|
"twig-drupal-filters": "^3.2.0",
|
|
124
122
|
"twig-testing-library": "^1.2.0",
|
|
125
123
|
"twigjs-loader": "^1.0.3",
|
|
126
|
-
"webpack": "^5.
|
|
124
|
+
"webpack": "^5.101.3",
|
|
127
125
|
"webpack-cli": "^6.0.1",
|
|
128
126
|
"webpack-merge": "^6.0.1",
|
|
129
|
-
"
|
|
127
|
+
"webpack-remove-empty-scripts": "^1.1.1",
|
|
128
|
+
"yaml": "^2.8.1"
|
|
130
129
|
},
|
|
131
130
|
"devDependencies": {
|
|
132
131
|
"@commitlint/cli": "^19.8.1",
|
|
@@ -134,12 +133,12 @@
|
|
|
134
133
|
"@semantic-release/changelog": "^6.0.2",
|
|
135
134
|
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
136
135
|
"@semantic-release/git": "^10.0.1",
|
|
137
|
-
"@semantic-release/github": "^11.0.
|
|
138
|
-
"@semantic-release/release-notes-generator": "^14.0
|
|
136
|
+
"@semantic-release/github": "^11.0.5",
|
|
137
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
139
138
|
"all-contributors-cli": "^6.26.1",
|
|
140
139
|
"husky": "^9.1.7",
|
|
141
|
-
"lint-staged": "^16.1.
|
|
142
|
-
"semantic-release": "^24.2.
|
|
140
|
+
"lint-staged": "^16.1.6",
|
|
141
|
+
"semantic-release": "^24.2.7"
|
|
143
142
|
},
|
|
144
143
|
"overrides": {
|
|
145
144
|
"inflight": "^1.0.7",
|