shakapacker 9.3.0.beta.7 → 9.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +46 -109
  3. data/Gemfile.lock +1 -1
  4. data/README.md +53 -2
  5. data/docs/configuration.md +28 -0
  6. data/docs/rspack_migration_guide.md +238 -2
  7. data/docs/troubleshooting.md +21 -21
  8. data/eslint.config.fast.js +8 -0
  9. data/eslint.config.js +47 -10
  10. data/knip.ts +8 -1
  11. data/lib/install/config/shakapacker.yml +6 -6
  12. data/lib/shakapacker/configuration.rb +227 -4
  13. data/lib/shakapacker/dev_server.rb +88 -1
  14. data/lib/shakapacker/doctor.rb +4 -4
  15. data/lib/shakapacker/instance.rb +85 -1
  16. data/lib/shakapacker/manifest.rb +85 -11
  17. data/lib/shakapacker/version.rb +1 -1
  18. data/lib/shakapacker.rb +143 -3
  19. data/lib/tasks/shakapacker/doctor.rake +1 -1
  20. data/lib/tasks/shakapacker/export_bundler_config.rake +4 -4
  21. data/package/config.ts +0 -1
  22. data/package/configExporter/buildValidator.ts +53 -29
  23. data/package/configExporter/cli.ts +81 -56
  24. data/package/configExporter/configFile.ts +33 -26
  25. data/package/configExporter/types.ts +64 -0
  26. data/package/configExporter/yamlSerializer.ts +118 -43
  27. data/package/dev_server.ts +2 -1
  28. data/package/env.ts +1 -1
  29. data/package/environments/base.ts +4 -4
  30. data/package/environments/development.ts +7 -6
  31. data/package/environments/production.ts +6 -7
  32. data/package/environments/test.ts +2 -1
  33. data/package/index.ts +28 -4
  34. data/package/loaders.d.ts +2 -2
  35. data/package/optimization/webpack.ts +29 -31
  36. data/package/rspack/index.ts +2 -1
  37. data/package/rules/file.ts +1 -0
  38. data/package/rules/jscommon.ts +1 -0
  39. data/package/utils/helpers.ts +0 -1
  40. data/package/utils/pathValidation.ts +68 -7
  41. data/package/utils/requireOrError.ts +10 -2
  42. data/package/utils/typeGuards.ts +43 -46
  43. data/package/webpack-types.d.ts +2 -2
  44. data/package/webpackDevServerConfig.ts +1 -0
  45. data/package.json +2 -3
  46. data/test/package/configExporter/cli.test.js +440 -0
  47. data/test/package/configExporter/types.test.js +163 -0
  48. data/test/package/configExporter.test.js +264 -0
  49. data/test/package/yamlSerializer.test.js +204 -0
  50. data/test/typescript/pathValidation.test.js +44 -0
  51. data/test/typescript/requireOrError.test.js +49 -0
  52. data/yarn.lock +0 -32
  53. metadata +11 -5
  54. data/.eslintrc.fast.js +0 -40
  55. data/.eslintrc.js +0 -84
@@ -105,6 +105,223 @@ describe("configExporter", () => {
105
105
  })
106
106
  })
107
107
 
108
+ describe("yamlSerializer", () => {
109
+ test("serializes object keys in alphabetical order", () => {
110
+ const {
111
+ YamlSerializer
112
+ } = require("../../package/configExporter/yamlSerializer")
113
+ const serializer = new YamlSerializer({
114
+ annotate: false,
115
+ appRoot: "/test/app"
116
+ })
117
+
118
+ // Create an object with keys intentionally out of alphabetical order
119
+ const config = {
120
+ mode: "production",
121
+ entry: "./src/index.js",
122
+ optimization: {
123
+ minimize: true
124
+ },
125
+ output: {
126
+ path: "/dist",
127
+ filename: "bundle.js"
128
+ },
129
+ devtool: "source-map"
130
+ }
131
+
132
+ const metadata = {
133
+ exportedAt: "2025-10-28",
134
+ environment: "production",
135
+ bundler: "webpack",
136
+ configType: "client",
137
+ configCount: 1
138
+ }
139
+
140
+ const result = serializer.serialize(config, metadata)
141
+
142
+ // Extract just the config part (skip the header)
143
+ const lines = result.split("\n")
144
+ const keyMatches = lines
145
+ .map((line) => line.match(/^(\w+):/))
146
+ .filter(Boolean)
147
+ .map((match) => match[1])
148
+
149
+ // Expected order: devtool, entry, mode, optimization, output
150
+ expect(keyMatches).toStrictEqual([
151
+ "devtool",
152
+ "entry",
153
+ "mode",
154
+ "optimization",
155
+ "output"
156
+ ])
157
+ })
158
+
159
+ test("serializes nested object keys in alphabetical order", () => {
160
+ const {
161
+ YamlSerializer
162
+ } = require("../../package/configExporter/yamlSerializer")
163
+ const serializer = new YamlSerializer({
164
+ annotate: false,
165
+ appRoot: "/test/app"
166
+ })
167
+
168
+ const config = {
169
+ output: {
170
+ path: "/dist",
171
+ filename: "bundle.js",
172
+ clean: true
173
+ }
174
+ }
175
+
176
+ const metadata = {
177
+ exportedAt: "2025-10-28",
178
+ environment: "production",
179
+ bundler: "webpack",
180
+ configType: "client",
181
+ configCount: 1
182
+ }
183
+
184
+ const result = serializer.serialize(config, metadata)
185
+
186
+ // Extract nested keys from the output section
187
+ const lines = result.split("\n")
188
+ const outputKeys = lines
189
+ .map((line) => line.match(/^ {2}(\w+):/))
190
+ .filter(Boolean)
191
+ .map((match) => match[1])
192
+
193
+ // Expected order: clean, filename, path
194
+ expect(outputKeys).toStrictEqual(["clean", "filename", "path"])
195
+ })
196
+
197
+ test("quotes strings containing square brackets", () => {
198
+ const {
199
+ YamlSerializer
200
+ } = require("../../package/configExporter/yamlSerializer")
201
+ const yaml = require("js-yaml")
202
+
203
+ const serializer = new YamlSerializer({
204
+ annotate: false,
205
+ appRoot: process.cwd()
206
+ })
207
+
208
+ const testConfig = {
209
+ options: {
210
+ modules: {
211
+ localIdentName: "[name]-[local]__[contenthash]"
212
+ }
213
+ }
214
+ }
215
+
216
+ const metadata = {
217
+ exportedAt: new Date().toISOString(),
218
+ environment: "test",
219
+ bundler: "webpack",
220
+ configType: "test",
221
+ configCount: 1
222
+ }
223
+
224
+ const yamlOutput = serializer.serialize(testConfig, metadata)
225
+
226
+ // Verify YAML can be parsed without errors
227
+ expect(() => yaml.load(yamlOutput)).not.toThrow()
228
+
229
+ // Verify the parsed value matches the original
230
+ const parsed = yaml.load(yamlOutput)
231
+ expect(parsed.options.modules.localIdentName).toBe(
232
+ "[name]-[local]__[contenthash]"
233
+ )
234
+ })
235
+
236
+ test("quotes RegExp strings containing special characters", () => {
237
+ const {
238
+ YamlSerializer
239
+ } = require("../../package/configExporter/yamlSerializer")
240
+ const yaml = require("js-yaml")
241
+
242
+ const serializer = new YamlSerializer({
243
+ annotate: false,
244
+ appRoot: process.cwd()
245
+ })
246
+
247
+ const testConfig = {
248
+ options: {
249
+ modules: {
250
+ localIdentRegExp: /([^/-]+|[^/]+)(?:-styles)?.module.scss$/,
251
+ localIdentName: "[name]-[local]__[contenthash]"
252
+ }
253
+ }
254
+ }
255
+
256
+ const metadata = {
257
+ exportedAt: new Date().toISOString(),
258
+ environment: "test",
259
+ bundler: "webpack",
260
+ configType: "test",
261
+ configCount: 1
262
+ }
263
+
264
+ const yamlOutput = serializer.serialize(testConfig, metadata)
265
+
266
+ // Verify YAML can be parsed without errors
267
+ expect(() => yaml.load(yamlOutput)).not.toThrow()
268
+
269
+ // Verify the parsed values match the originals
270
+ const parsed = yaml.load(yamlOutput)
271
+ expect(parsed.options.modules.localIdentName).toBe(
272
+ "[name]-[local]__[contenthash]"
273
+ )
274
+ // RegExp becomes a string in YAML
275
+ expect(parsed.options.modules.localIdentRegExp).toBe(
276
+ "([^/-]+|[^/]+)(?:-styles)?.module.scss$"
277
+ )
278
+ })
279
+
280
+ test("quotes strings with YAML special characters", () => {
281
+ const {
282
+ YamlSerializer
283
+ } = require("../../package/configExporter/yamlSerializer")
284
+ const yaml = require("js-yaml")
285
+
286
+ const serializer = new YamlSerializer({
287
+ annotate: false,
288
+ appRoot: process.cwd()
289
+ })
290
+
291
+ // Test various YAML special characters
292
+ const testConfig = {
293
+ curlyBraces: "{value}",
294
+ asterisk: "*value*",
295
+ ampersand: "&value",
296
+ exclamation: "!important",
297
+ atSign: "@import",
298
+ backtick: "`value`"
299
+ }
300
+
301
+ const metadata = {
302
+ exportedAt: new Date().toISOString(),
303
+ environment: "test",
304
+ bundler: "webpack",
305
+ configType: "test",
306
+ configCount: 1
307
+ }
308
+
309
+ const yamlOutput = serializer.serialize(testConfig, metadata)
310
+
311
+ // Verify YAML can be parsed without errors
312
+ expect(() => yaml.load(yamlOutput)).not.toThrow()
313
+
314
+ // Verify all special characters are preserved
315
+ const parsed = yaml.load(yamlOutput)
316
+ expect(parsed.curlyBraces).toBe("{value}")
317
+ expect(parsed.asterisk).toBe("*value*")
318
+ expect(parsed.ampersand).toBe("&value")
319
+ expect(parsed.exclamation).toBe("!important")
320
+ expect(parsed.atSign).toBe("@import")
321
+ expect(parsed.backtick).toBe("`value`")
322
+ })
323
+ })
324
+
108
325
  describe("environment variable preservation in runDoctorMode", () => {
109
326
  let originalEnv
110
327
 
@@ -192,4 +409,51 @@ describe("configExporter", () => {
192
409
  expect(process.env.SERVER_BUNDLE_ONLY).toBeUndefined()
193
410
  })
194
411
  })
412
+
413
+ describe("argument validation", () => {
414
+ let mockExit
415
+
416
+ beforeEach(() => {
417
+ // Mock process.exit to prevent yargs from killing the test process
418
+ mockExit = jest.spyOn(process, "exit").mockImplementation(() => {
419
+ throw new Error("process.exit called")
420
+ })
421
+ })
422
+
423
+ afterEach(() => {
424
+ mockExit.mockRestore()
425
+ })
426
+
427
+ test("rejects --all-builds with --output", () => {
428
+ const { parseArguments } = require("../../package/configExporter/cli")
429
+
430
+ expect(() => {
431
+ parseArguments(["--all-builds", "--output=config.yml"])
432
+ }).toThrow("process.exit called")
433
+ })
434
+
435
+ test("rejects --all-builds with --stdout", () => {
436
+ const { parseArguments } = require("../../package/configExporter/cli")
437
+
438
+ expect(() => {
439
+ parseArguments(["--all-builds", "--stdout"])
440
+ }).toThrow("process.exit called")
441
+ })
442
+
443
+ test("rejects --stdout with --output", () => {
444
+ const { parseArguments } = require("../../package/configExporter/cli")
445
+
446
+ expect(() => {
447
+ parseArguments(["--stdout", "--output=config.yml"])
448
+ }).toThrow("process.exit called")
449
+ })
450
+
451
+ test("allows --all-builds with --save-dir", () => {
452
+ const { parseArguments } = require("../../package/configExporter/cli")
453
+
454
+ expect(() => {
455
+ parseArguments(["--all-builds", "--save-dir=./configs"])
456
+ }).not.toThrow()
457
+ })
458
+ })
195
459
  })
@@ -0,0 +1,204 @@
1
+ const {
2
+ YamlSerializer
3
+ } = require("../../package/configExporter/yamlSerializer")
4
+
5
+ describe("YamlSerializer", () => {
6
+ let serializer
7
+
8
+ beforeEach(() => {
9
+ serializer = new YamlSerializer({
10
+ annotate: false,
11
+ appRoot: "/test/app"
12
+ })
13
+ })
14
+
15
+ describe("serialize", () => {
16
+ test("includes metadata header in serialized output", () => {
17
+ const config = { mode: "development" }
18
+ const metadata = {
19
+ exportedAt: "2025-01-15T12:00:00Z",
20
+ environment: "development",
21
+ bundler: "webpack",
22
+ configType: "client",
23
+ configCount: 1
24
+ }
25
+
26
+ const result = serializer.serialize(config, metadata)
27
+
28
+ expect(result).toContain("# Webpack/Rspack Configuration Export")
29
+ expect(result).toContain("# Generated: 2025-01-15T12:00:00Z")
30
+ expect(result).toContain("# Environment: development")
31
+ expect(result).toContain("# Bundler: webpack")
32
+ expect(result).toContain("# Config Type: client")
33
+ expect(result).toContain("mode: development")
34
+ })
35
+
36
+ test("includes config count when multiple configs present", () => {
37
+ const config = { mode: "production" }
38
+ const metadata = {
39
+ exportedAt: "2025-01-15T12:00:00Z",
40
+ environment: "production",
41
+ bundler: "rspack",
42
+ configType: "server",
43
+ configCount: 3
44
+ }
45
+
46
+ const result = serializer.serialize(config, metadata)
47
+
48
+ expect(result).toContain("# Total Configs: 3")
49
+ })
50
+
51
+ test("omits config count when only one config present", () => {
52
+ const config = { mode: "production" }
53
+ const metadata = {
54
+ exportedAt: "2025-01-15T12:00:00Z",
55
+ environment: "production",
56
+ bundler: "rspack",
57
+ configType: "server",
58
+ configCount: 1
59
+ }
60
+
61
+ const result = serializer.serialize(config, metadata)
62
+
63
+ expect(result).not.toContain("# Total Configs:")
64
+ })
65
+
66
+ test("serializes simple objects correctly", () => {
67
+ const config = {
68
+ mode: "development",
69
+ devtool: "source-map"
70
+ }
71
+ const metadata = {
72
+ exportedAt: "2025-01-15T12:00:00Z",
73
+ environment: "development",
74
+ bundler: "webpack",
75
+ configType: "client",
76
+ configCount: 1
77
+ }
78
+
79
+ const result = serializer.serialize(config, metadata)
80
+
81
+ expect(result).toContain("mode: development")
82
+ expect(result).toContain("devtool: source-map")
83
+ })
84
+
85
+ test("serializes nested objects", () => {
86
+ const config = {
87
+ output: {
88
+ path: "/dist",
89
+ filename: "bundle.js"
90
+ }
91
+ }
92
+ const metadata = {
93
+ exportedAt: "2025-01-15T12:00:00Z",
94
+ environment: "development",
95
+ bundler: "webpack",
96
+ configType: "client",
97
+ configCount: 1
98
+ }
99
+
100
+ const result = serializer.serialize(config, metadata)
101
+
102
+ expect(result).toContain("output:")
103
+ expect(result).toContain("path: /dist")
104
+ expect(result).toContain("filename: bundle.js")
105
+ })
106
+
107
+ test("handles empty objects with constructor names", () => {
108
+ class CustomPlugin {}
109
+ const config = {
110
+ plugins: [new CustomPlugin()]
111
+ }
112
+ const metadata = {
113
+ exportedAt: "2025-01-15T12:00:00Z",
114
+ environment: "development",
115
+ bundler: "webpack",
116
+ configType: "client",
117
+ configCount: 1
118
+ }
119
+
120
+ const result = serializer.serialize(config, metadata)
121
+
122
+ expect(result).toContain("plugins:")
123
+ expect(result).toContain("CustomPlugin")
124
+ })
125
+
126
+ test("serializes arrays", () => {
127
+ const config = {
128
+ entry: ["./src/index.js", "./src/app.js"]
129
+ }
130
+ const metadata = {
131
+ exportedAt: "2025-01-15T12:00:00Z",
132
+ environment: "development",
133
+ bundler: "webpack",
134
+ configType: "client",
135
+ configCount: 1
136
+ }
137
+
138
+ const result = serializer.serialize(config, metadata)
139
+
140
+ expect(result).toContain("entry:")
141
+ expect(result).toContain("- ./src/index.js")
142
+ expect(result).toContain("- ./src/app.js")
143
+ })
144
+
145
+ test("handles functions in config", () => {
146
+ const config = {
147
+ output: {
148
+ filename() {
149
+ return "bundle.js"
150
+ }
151
+ }
152
+ }
153
+ const metadata = {
154
+ exportedAt: "2025-01-15T12:00:00Z",
155
+ environment: "development",
156
+ bundler: "webpack",
157
+ configType: "client",
158
+ configCount: 1
159
+ }
160
+
161
+ const result = serializer.serialize(config, metadata)
162
+
163
+ expect(result).toContain("output:")
164
+ expect(result).toContain("filename: |")
165
+ expect(result).toContain("filename()")
166
+ })
167
+
168
+ test("handles RegExp in config without flags", () => {
169
+ const config = {
170
+ test: /\.js$/
171
+ }
172
+ const metadata = {
173
+ exportedAt: "2025-01-15T12:00:00Z",
174
+ environment: "development",
175
+ bundler: "webpack",
176
+ configType: "client",
177
+ configCount: 1
178
+ }
179
+
180
+ const result = serializer.serialize(config, metadata)
181
+
182
+ // RegExp objects serialize as their pattern without slashes
183
+ expect(result).toContain("test: \\.js$")
184
+ })
185
+
186
+ test("handles RegExp with flags in config", () => {
187
+ const config = {
188
+ test: /\.js$/i
189
+ }
190
+ const metadata = {
191
+ exportedAt: "2025-01-15T12:00:00Z",
192
+ environment: "development",
193
+ bundler: "webpack",
194
+ configType: "client",
195
+ configCount: 1
196
+ }
197
+
198
+ const result = serializer.serialize(config, metadata)
199
+
200
+ // RegExp with flags includes flags as inline comment
201
+ expect(result).toContain("test: \\.js$ # flags: i")
202
+ })
203
+ })
204
+ })
@@ -63,6 +63,50 @@ describe("Path Validation Security", () => {
63
63
  safeResolvePath(basePath, maliciousPath)
64
64
  }).toThrow("Path traversal attempt detected")
65
65
  })
66
+
67
+ it("rethrows non-ENOENT errors for better security", () => {
68
+ const fs = require("fs")
69
+
70
+ // Mock fs.realpathSync to throw EACCES (permission denied)
71
+ const realpathSyncSpy = jest
72
+ .spyOn(fs, "realpathSync")
73
+ .mockImplementation(() => {
74
+ const error = new Error("Permission denied")
75
+ error.code = "EACCES"
76
+ throw error
77
+ })
78
+
79
+ const basePath = path.join(path.sep, "app")
80
+ const userPath = path.join("src", "index.js")
81
+
82
+ expect(() => {
83
+ safeResolvePath(basePath, userPath)
84
+ }).toThrow("Permission denied")
85
+
86
+ // Restore original function
87
+ realpathSyncSpy.mockRestore()
88
+ })
89
+
90
+ it("handles errors without code property gracefully", () => {
91
+ const fs = require("fs")
92
+
93
+ // Mock fs.realpathSync to throw error without code property
94
+ const realpathSyncSpy = jest
95
+ .spyOn(fs, "realpathSync")
96
+ .mockImplementation(() => {
97
+ throw new Error("Unknown error")
98
+ })
99
+
100
+ const basePath = path.join(path.sep, "app")
101
+ const userPath = path.join("src", "index.js")
102
+
103
+ expect(() => {
104
+ safeResolvePath(basePath, userPath)
105
+ }).toThrow("Unknown error")
106
+
107
+ // Restore original function
108
+ realpathSyncSpy.mockRestore()
109
+ })
66
110
  })
67
111
 
68
112
  describe("validatePaths", () => {
@@ -0,0 +1,49 @@
1
+ // Tests for requireOrError utility
2
+ const { requireOrError } = require("../../package/utils/requireOrError")
3
+
4
+ describe("requireOrError", () => {
5
+ describe("successful require", () => {
6
+ it("returns the required module", () => {
7
+ const result = requireOrError("path")
8
+ expect(result).toBeDefined()
9
+ expect(typeof result.join).toBe("function")
10
+ })
11
+ })
12
+
13
+ describe("failed require", () => {
14
+ it("throws error with helpful message when module not found", () => {
15
+ expect(() => {
16
+ requireOrError("nonexistent-module-that-does-not-exist")
17
+ }).toThrow("[SHAKAPACKER]")
18
+ expect(() => {
19
+ requireOrError("nonexistent-module-that-does-not-exist")
20
+ }).toThrow("is required for")
21
+ })
22
+
23
+ it("includes original error as cause for debugging", () => {
24
+ let caughtError
25
+ try {
26
+ requireOrError("nonexistent-module-that-does-not-exist")
27
+ } catch (error) {
28
+ caughtError = error
29
+ }
30
+
31
+ expect(caughtError).toBeDefined()
32
+ expect(caughtError.cause).toBeDefined()
33
+ expect(caughtError.cause.code).toBe("MODULE_NOT_FOUND")
34
+ })
35
+
36
+ it("preserves original error stack in cause", () => {
37
+ let caughtError
38
+ try {
39
+ requireOrError("another-nonexistent-module")
40
+ } catch (error) {
41
+ caughtError = error
42
+ }
43
+
44
+ expect(caughtError.cause).toBeDefined()
45
+ expect(caughtError.cause.stack).toBeDefined()
46
+ expect(typeof caughtError.cause.stack).toBe("string")
47
+ })
48
+ })
49
+ })
data/yarn.lock CHANGED
@@ -972,11 +972,6 @@
972
972
  resolved "https://registry.npmjs.org/@oxc-resolver/binding-win32-x64-msvc/-/binding-win32-x64-msvc-11.9.0.tgz#3e8127b5c225cb2d99b991f251768188efbda25f"
973
973
  integrity sha512-gE3QJvhh0Yj9cSAkkHjRLKPmC7BTJeiaB5YyhVKVUwbnWQgTszV92lZ9pvZtNPEghP7jPbhEs4c6983A0ojQwA==
974
974
 
975
- "@pkgr/core@^0.2.9":
976
- version "0.2.9"
977
- resolved "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b"
978
- integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==
979
-
980
975
  "@polka/url@^1.0.0-next.24":
981
976
  version "1.0.0-next.29"
982
977
  resolved "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1"
@@ -3027,14 +3022,6 @@ eslint-plugin-jsx-a11y@^6.10.2:
3027
3022
  safe-regex-test "^1.0.3"
3028
3023
  string.prototype.includes "^2.0.1"
3029
3024
 
3030
- eslint-plugin-prettier@^5.5.4:
3031
- version "5.5.4"
3032
- resolved "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.4.tgz#9d61c4ea11de5af704d4edf108c82ccfa7f2e61c"
3033
- integrity sha512-swNtI95SToIz05YINMA6Ox5R057IMAmWZ26GqPxusAp1TZzj+IdY9tXNWWD3vkF/wEqydCONcwjTFpxybBqZsg==
3034
- dependencies:
3035
- prettier-linter-helpers "^1.0.0"
3036
- synckit "^0.11.7"
3037
-
3038
3025
  eslint-plugin-react-hooks@^7.0.0:
3039
3026
  version "7.0.0"
3040
3027
  resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.0.0.tgz#a255a1db826ea42b0e37f160430e4bd0b4b659f9"
@@ -3293,11 +3280,6 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
3293
3280
  resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
3294
3281
  integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
3295
3282
 
3296
- fast-diff@^1.1.2:
3297
- version "1.3.0"
3298
- resolved "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0"
3299
- integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==
3300
-
3301
3283
  fast-glob@^3.3.2, fast-glob@^3.3.3:
3302
3284
  version "3.3.3"
3303
3285
  resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818"
@@ -5458,13 +5440,6 @@ prelude-ls@^1.2.1:
5458
5440
  resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
5459
5441
  integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
5460
5442
 
5461
- prettier-linter-helpers@^1.0.0:
5462
- version "1.0.0"
5463
- resolved "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b"
5464
- integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==
5465
- dependencies:
5466
- fast-diff "^1.1.2"
5467
-
5468
5443
  prettier@^3.2.5:
5469
5444
  version "3.6.2"
5470
5445
  resolved "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393"
@@ -6306,13 +6281,6 @@ swc-loader@^0.1.15:
6306
6281
  resolved "https://registry.npmjs.org/swc-loader/-/swc-loader-0.1.16.tgz#4c718d698e518f3e6ceb9f7872c1855cdb187066"
6307
6282
  integrity sha512-NKIm8aJjK/z/yfzk+v7YGwJMjBKaLaUs9ZKI2zoaIGKAjtkwjO92ZLI0fiTZuwzRqVLQl/29fBdSgFCBzquR0w==
6308
6283
 
6309
- synckit@^0.11.7:
6310
- version "0.11.11"
6311
- resolved "https://registry.npmjs.org/synckit/-/synckit-0.11.11.tgz#c0b619cf258a97faa209155d9cd1699b5c998cb0"
6312
- integrity sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==
6313
- dependencies:
6314
- "@pkgr/core" "^0.2.9"
6315
-
6316
6284
  tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1, tapable@^2.3.0:
6317
6285
  version "2.3.0"
6318
6286
  resolved "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6"