@scalar/json-magic 0.6.0 → 0.7.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 (46) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +22 -0
  3. package/dist/bundle/bundle.d.ts +1 -0
  4. package/dist/bundle/bundle.d.ts.map +1 -1
  5. package/dist/bundle/bundle.js +3 -3
  6. package/dist/bundle/bundle.js.map +2 -2
  7. package/dist/bundle/plugins/fetch-urls/index.d.ts.map +1 -1
  8. package/dist/bundle/plugins/fetch-urls/index.js +8 -1
  9. package/dist/bundle/plugins/fetch-urls/index.js.map +2 -2
  10. package/dist/bundle/plugins/parse-json/index.d.ts.map +1 -1
  11. package/dist/bundle/plugins/parse-json/index.js +7 -6
  12. package/dist/bundle/plugins/parse-json/index.js.map +2 -2
  13. package/dist/bundle/plugins/parse-yaml/index.d.ts.map +1 -1
  14. package/dist/bundle/plugins/parse-yaml/index.js +7 -6
  15. package/dist/bundle/plugins/parse-yaml/index.js.map +2 -2
  16. package/dist/bundle/plugins/read-files/index.d.ts.map +1 -1
  17. package/dist/bundle/plugins/read-files/index.js +2 -1
  18. package/dist/bundle/plugins/read-files/index.js.map +2 -2
  19. package/dist/diff/diff.d.ts.map +1 -1
  20. package/dist/diff/diff.js.map +2 -2
  21. package/dist/diff/utils.d.ts.map +1 -1
  22. package/dist/diff/utils.js.map +2 -2
  23. package/dist/magic-proxy/proxy.d.ts +7 -6
  24. package/dist/magic-proxy/proxy.d.ts.map +1 -1
  25. package/dist/magic-proxy/proxy.js +21 -11
  26. package/dist/magic-proxy/proxy.js.map +2 -2
  27. package/package.json +4 -4
  28. package/src/bundle/bundle.test.ts +278 -259
  29. package/src/bundle/bundle.ts +4 -4
  30. package/src/bundle/plugins/fetch-urls/index.test.ts +21 -24
  31. package/src/bundle/plugins/fetch-urls/index.ts +10 -0
  32. package/src/bundle/plugins/parse-json/index.test.ts +3 -1
  33. package/src/bundle/plugins/parse-json/index.ts +7 -6
  34. package/src/bundle/plugins/parse-yaml/index.test.ts +3 -1
  35. package/src/bundle/plugins/parse-yaml/index.ts +7 -6
  36. package/src/bundle/plugins/read-files/index.test.ts +4 -3
  37. package/src/bundle/plugins/read-files/index.ts +1 -0
  38. package/src/bundle/value-generator.test.ts +7 -8
  39. package/src/dereference/dereference.test.ts +6 -6
  40. package/src/diff/diff.ts +0 -1
  41. package/src/diff/utils.test.ts +2 -2
  42. package/src/diff/utils.ts +0 -2
  43. package/src/helpers/escape-json-pointer.test.ts +1 -1
  44. package/src/helpers/unescape-json-pointer.test.ts +1 -1
  45. package/src/magic-proxy/proxy.test.ts +108 -76
  46. package/src/magic-proxy/proxy.ts +34 -20
@@ -4,7 +4,7 @@ import { setTimeout } from 'node:timers/promises'
4
4
 
5
5
  import { consoleWarnSpy, resetConsoleSpies } from '@scalar/helpers/testing/console-spies'
6
6
  import fastify, { type FastifyInstance } from 'fastify'
7
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
7
+ import { beforeEach, describe, expect, it, vi } from 'vitest'
8
8
  import YAML from 'yaml'
9
9
 
10
10
  import { parseJson } from '@/bundle/plugins/parse-json'
@@ -32,11 +32,11 @@ describe('bundle', () => {
32
32
 
33
33
  beforeEach(() => {
34
34
  server = fastify({ logger: false })
35
- })
36
35
 
37
- afterEach(async () => {
38
- await server.close()
39
- await setTimeout(100)
36
+ return async () => {
37
+ await server.close()
38
+ await setTimeout(100)
39
+ }
40
40
  })
41
41
 
42
42
  it('bundles external urls', async () => {
@@ -1423,9 +1423,7 @@ describe('bundle', () => {
1423
1423
  await bundle(input, {
1424
1424
  plugins: [
1425
1425
  fetchUrls({
1426
- fetch: async () => {
1427
- return Response.json({ message: 'should not be called' })
1428
- },
1426
+ fetch: () => Promise.resolve(Response.json({ message: 'should not be called' })),
1429
1427
  }),
1430
1428
  readFiles(),
1431
1429
  ],
@@ -1519,7 +1517,15 @@ describe('bundle', () => {
1519
1517
  },
1520
1518
  }
1521
1519
 
1522
- const fn = vi.fn()
1520
+ const exec = vi.fn<LoaderPlugin['exec']>().mockResolvedValue({
1521
+ ok: true,
1522
+ data: {
1523
+ message: 'resolved value',
1524
+ },
1525
+ raw: JSON.stringify({
1526
+ message: 'resolved value',
1527
+ }),
1528
+ })
1523
1529
 
1524
1530
  await bundle(input, {
1525
1531
  treeShake: false,
@@ -1527,15 +1533,7 @@ describe('bundle', () => {
1527
1533
  {
1528
1534
  type: 'loader',
1529
1535
  validate: () => true,
1530
- exec: async (value) => {
1531
- fn(value)
1532
- return {
1533
- ok: true,
1534
- data: {
1535
- message: 'resolved value',
1536
- },
1537
- }
1538
- },
1536
+ exec,
1539
1537
  },
1540
1538
  ],
1541
1539
  })
@@ -1556,8 +1554,8 @@ describe('bundle', () => {
1556
1554
  },
1557
1555
  })
1558
1556
 
1559
- expect(fn).toHaveBeenCalled()
1560
- expect(fn).toHaveBeenCalledWith('https://example.com/b')
1557
+ expect(exec).toHaveBeenCalled()
1558
+ expect(exec).toHaveBeenCalledWith('https://example.com/b')
1561
1559
  })
1562
1560
 
1563
1561
  it('prioritizes $id when resolving refs with origin #1', async () => {
@@ -1574,7 +1572,15 @@ describe('bundle', () => {
1574
1572
  },
1575
1573
  }
1576
1574
 
1577
- const fn = vi.fn()
1575
+ const exec = vi.fn<LoaderPlugin['exec']>().mockResolvedValue({
1576
+ ok: true,
1577
+ data: {
1578
+ message: 'resolved value',
1579
+ },
1580
+ raw: JSON.stringify({
1581
+ message: 'resolved value',
1582
+ }),
1583
+ })
1578
1584
 
1579
1585
  await bundle(input, {
1580
1586
  treeShake: false,
@@ -1583,15 +1589,7 @@ describe('bundle', () => {
1583
1589
  {
1584
1590
  type: 'loader',
1585
1591
  validate: () => true,
1586
- exec: async (value) => {
1587
- fn(value)
1588
- return {
1589
- ok: true,
1590
- data: {
1591
- message: 'resolved value',
1592
- },
1593
- }
1594
- },
1592
+ exec,
1595
1593
  },
1596
1594
  ],
1597
1595
  })
@@ -1612,8 +1610,8 @@ describe('bundle', () => {
1612
1610
  },
1613
1611
  })
1614
1612
 
1615
- expect(fn).toHaveBeenCalled()
1616
- expect(fn).toHaveBeenCalledWith('/b')
1613
+ expect(exec).toHaveBeenCalled()
1614
+ expect(exec).toHaveBeenCalledWith('/b')
1617
1615
  })
1618
1616
 
1619
1617
  it('prioritizes $id when resolving refs with origin #2', async () => {
@@ -1630,7 +1628,25 @@ describe('bundle', () => {
1630
1628
  },
1631
1629
  }
1632
1630
 
1633
- const fn = vi.fn()
1631
+ const exec = vi.fn<LoaderPlugin['exec']>((value) => {
1632
+ if (value === url) {
1633
+ return Promise.resolve({
1634
+ ok: true,
1635
+ data: input,
1636
+ raw: JSON.stringify(input),
1637
+ })
1638
+ }
1639
+
1640
+ return Promise.resolve({
1641
+ ok: true,
1642
+ data: {
1643
+ message: 'resolved value',
1644
+ },
1645
+ raw: JSON.stringify({
1646
+ message: 'resolved value',
1647
+ }),
1648
+ })
1649
+ })
1634
1650
 
1635
1651
  await bundle(url, {
1636
1652
  treeShake: false,
@@ -1639,23 +1655,7 @@ describe('bundle', () => {
1639
1655
  {
1640
1656
  type: 'loader',
1641
1657
  validate: () => true,
1642
- exec: async (value) => {
1643
- fn(value)
1644
-
1645
- if (value === url) {
1646
- return {
1647
- ok: true,
1648
- data: input,
1649
- }
1650
- }
1651
-
1652
- return {
1653
- ok: true,
1654
- data: {
1655
- message: 'resolved value',
1656
- },
1657
- }
1658
- },
1658
+ exec,
1659
1659
  },
1660
1660
  ],
1661
1661
  })
@@ -1676,9 +1676,9 @@ describe('bundle', () => {
1676
1676
  },
1677
1677
  })
1678
1678
 
1679
- expect(fn).toHaveBeenCalledTimes(2)
1680
- expect(fn.mock.calls[0][0]).toBe(url)
1681
- expect(fn.mock.calls[1][0]).toBe('http://example.com/b')
1679
+ expect(exec).toHaveBeenCalledTimes(2)
1680
+ expect(exec).toHaveBeenNthCalledWith(1, url)
1681
+ expect(exec).toHaveBeenNthCalledWith(2, 'http://example.com/b')
1682
1682
  })
1683
1683
 
1684
1684
  it('correctly bundles when doing a partial bundle with $anchor on a different context', async () => {
@@ -1702,25 +1702,25 @@ describe('bundle', () => {
1702
1702
  },
1703
1703
  }
1704
1704
 
1705
- const fn = vi.fn()
1706
-
1707
1705
  await bundle(input.a, {
1708
1706
  treeShake: false,
1709
1707
  plugins: [
1710
1708
  {
1711
1709
  type: 'loader',
1712
1710
  validate: () => true,
1713
- exec: async (value) => {
1714
- fn(value)
1711
+ exec: (value) => {
1715
1712
  if (value === 'http://example.com') {
1716
- return {
1713
+ return Promise.resolve({
1717
1714
  ok: true,
1718
1715
  data: {
1719
1716
  message: 'resolved value',
1720
1717
  },
1721
- }
1718
+ raw: JSON.stringify({
1719
+ message: 'resolved value',
1720
+ }),
1721
+ })
1722
1722
  }
1723
- return { ok: false }
1723
+ return Promise.resolve({ ok: false })
1724
1724
  },
1725
1725
  },
1726
1726
  ],
@@ -1989,11 +1989,11 @@ describe('bundle', () => {
1989
1989
 
1990
1990
  beforeEach(() => {
1991
1991
  server = fastify({ logger: false })
1992
- })
1993
1992
 
1994
- afterEach(async () => {
1995
- await server.close()
1996
- await setTimeout(100)
1993
+ return async () => {
1994
+ await server.close()
1995
+ await setTimeout(100)
1996
+ }
1997
1997
  })
1998
1998
 
1999
1999
  it('should process yaml inputs', async () => {
@@ -2068,11 +2068,11 @@ describe('bundle', () => {
2068
2068
 
2069
2069
  beforeEach(() => {
2070
2070
  server = fastify({ logger: false })
2071
- })
2072
2071
 
2073
- afterEach(async () => {
2074
- await server.close()
2075
- await setTimeout(100)
2072
+ return async () => {
2073
+ await server.close()
2074
+ await setTimeout(100)
2075
+ }
2076
2076
  })
2077
2077
 
2078
2078
  it('bundles external urls', async () => {
@@ -2281,7 +2281,7 @@ describe('bundle', () => {
2281
2281
  describe('hooks', () => {
2282
2282
  describe('onBeforeNodeProcess', () => {
2283
2283
  it('should correctly call the `onBeforeNodeProcess` correctly on all the nodes', async () => {
2284
- const fn = vi.fn()
2284
+ const onBeforeNodeProcess = vi.fn()
2285
2285
 
2286
2286
  const input = {
2287
2287
  someKey: 'someValue',
@@ -2294,21 +2294,17 @@ describe('bundle', () => {
2294
2294
  plugins: [],
2295
2295
  treeShake: false,
2296
2296
  hooks: {
2297
- onBeforeNodeProcess(node) {
2298
- fn(node)
2299
- },
2297
+ onBeforeNodeProcess,
2300
2298
  },
2301
2299
  })
2302
2300
 
2303
- expect(fn).toHaveBeenCalled()
2304
- expect(fn).toBeCalledTimes(2)
2305
-
2306
- expect(fn.mock.calls[0][0]).toEqual(input)
2307
- expect(fn.mock.calls[1][0]).toEqual(input.anotherKey)
2301
+ expect(onBeforeNodeProcess).toBeCalledTimes(2)
2302
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(1, input, expect.any(Object))
2303
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(2, input.anotherKey, expect.any(Object))
2308
2304
  })
2309
2305
 
2310
2306
  it('should run bundle on the mutated object properties', async () => {
2311
- const fn = vi.fn()
2307
+ const onBeforeNodeProcessSpy = vi.fn()
2312
2308
 
2313
2309
  const input = {
2314
2310
  a: {
@@ -2328,21 +2324,19 @@ describe('bundle', () => {
2328
2324
  if ('e' in node) {
2329
2325
  node['processedKey'] = { 'message': 'Processed node' }
2330
2326
  }
2331
- fn(node)
2327
+ onBeforeNodeProcessSpy(node)
2332
2328
  },
2333
2329
  },
2334
2330
  })
2335
2331
 
2336
- expect(fn).toHaveBeenCalled()
2337
- expect(fn).toBeCalledTimes(4)
2338
-
2339
- expect(fn.mock.calls[3][0]).toEqual({ 'message': 'Processed node' })
2332
+ expect(onBeforeNodeProcessSpy).toBeCalledTimes(4)
2333
+ expect(onBeforeNodeProcessSpy).toHaveBeenNthCalledWith(4, { 'message': 'Processed node' })
2340
2334
  })
2341
2335
  })
2342
2336
 
2343
2337
  describe('onAfterNodeProcess', () => {
2344
2338
  it('should call `onAfterNodeProcess` hook on the nodes', async () => {
2345
- const fn = vi.fn()
2339
+ const onAfterNodeProcessSpy = vi.fn()
2346
2340
 
2347
2341
  const input = {
2348
2342
  a: {
@@ -2362,107 +2356,87 @@ describe('bundle', () => {
2362
2356
  if ('e' in node) {
2363
2357
  node['processedKey'] = { 'message': 'Processed node' }
2364
2358
  }
2365
- fn(node)
2359
+ onAfterNodeProcessSpy(node)
2366
2360
  },
2367
2361
  },
2368
2362
  })
2369
2363
 
2370
- expect(fn).toHaveBeenCalled()
2371
- expect(fn).toHaveBeenCalledTimes(3)
2364
+ expect(onAfterNodeProcessSpy).toHaveBeenCalledTimes(3)
2372
2365
  })
2373
2366
  })
2374
2367
  })
2375
2368
 
2376
2369
  describe('plugins', () => {
2377
2370
  it('use load plugins to load the documents', async () => {
2378
- const validate = vi.fn()
2379
- const exec = vi.fn()
2371
+ const validate = vi.fn<LoaderPlugin['validate']>().mockReturnValue(true)
2372
+ const exec = vi.fn<LoaderPlugin['exec']>().mockResolvedValue({
2373
+ ok: true,
2374
+ data: { message: 'Resolved document' },
2375
+ raw: JSON.stringify({ message: 'Resolved document' }),
2376
+ })
2380
2377
 
2381
2378
  const resolver = (): LoaderPlugin => {
2382
2379
  return {
2383
2380
  type: 'loader',
2384
- validate(value) {
2385
- validate(value)
2386
- return true
2387
- },
2388
- async exec(value) {
2389
- exec(value)
2390
- return {
2391
- ok: true,
2392
- data: { message: 'Resolved document' },
2393
- }
2394
- },
2381
+ validate,
2382
+ exec,
2395
2383
  }
2396
2384
  }
2397
2385
 
2398
2386
  const result = await bundle('hello', { treeShake: false, plugins: [resolver()] })
2399
2387
 
2400
2388
  expect(validate).toHaveBeenCalledOnce()
2401
- expect(exec).toHaveBeenCalledOnce()
2389
+ expect(validate).toHaveBeenLastCalledWith('hello')
2402
2390
 
2403
- expect(validate.mock.calls[0][0]).toBe('hello')
2404
- expect(exec.mock.calls[0][0]).toBe('hello')
2391
+ expect(exec).toHaveBeenCalledOnce()
2392
+ expect(exec).toHaveBeenLastCalledWith('hello')
2405
2393
 
2406
2394
  expect(result).toEqual({ message: 'Resolved document' })
2407
2395
  })
2408
2396
 
2409
2397
  it('throws if we can not process the input with any of the provided loaders', async () => {
2410
- const validate = vi.fn()
2411
- const exec = vi.fn()
2398
+ const validate = vi.fn<LoaderPlugin['validate']>().mockReturnValue(false)
2399
+ const exec = vi.fn<LoaderPlugin['exec']>()
2412
2400
 
2413
2401
  const resolver = (): LoaderPlugin => {
2414
2402
  return {
2415
2403
  type: 'loader',
2416
- validate(value) {
2417
- validate(value)
2418
- return false
2419
- },
2420
- async exec(value) {
2421
- exec(value)
2422
- return {
2423
- ok: true,
2424
- data: { message: 'Resolved document' },
2425
- }
2426
- },
2404
+ validate,
2405
+ exec,
2427
2406
  }
2428
2407
  }
2429
2408
 
2430
2409
  await expect(bundle('hello', { treeShake: false, plugins: [resolver()] })).rejects.toThrow()
2431
2410
 
2432
2411
  expect(validate).toHaveBeenCalledOnce()
2433
- expect(validate.mock.calls[0][0]).toBe('hello')
2412
+ expect(validate).toHaveBeenLastCalledWith('hello')
2434
2413
 
2435
2414
  expect(exec).not.toHaveBeenCalled()
2436
2415
  })
2437
2416
 
2438
2417
  it('use load plugin to resolve external refs', async () => {
2439
- const validate = vi.fn()
2440
- const exec = vi.fn()
2418
+ const validate = vi.fn<LoaderPlugin['validate']>().mockReturnValue(true)
2419
+ const exec = vi.fn<LoaderPlugin['exec']>().mockResolvedValue({
2420
+ ok: true,
2421
+ data: { message: 'Resolved document' },
2422
+ raw: JSON.stringify({ message: 'Resolved document' }),
2423
+ })
2441
2424
 
2442
2425
  const resolver = (): LoaderPlugin => {
2443
2426
  return {
2444
2427
  type: 'loader',
2445
- validate(value) {
2446
- validate(value)
2447
- return true
2448
- },
2449
- async exec(value) {
2450
- exec(value)
2451
- return {
2452
- ok: true,
2453
- data: { message: 'Resolved document' },
2454
- }
2455
- },
2428
+ validate,
2429
+ exec,
2456
2430
  }
2457
2431
  }
2458
2432
 
2459
2433
  const result = await bundle({ $ref: 'hello' }, { treeShake: false, plugins: [resolver()] })
2460
2434
 
2461
2435
  expect(validate).toHaveBeenCalledOnce()
2462
- expect(exec).toHaveBeenCalledOnce()
2436
+ expect(validate).toHaveBeenLastCalledWith('hello')
2463
2437
 
2464
- expect(validate.mock.calls[0][0]).toBe('hello')
2465
- expect(exec.mock.calls[0][0]).toBe('hello')
2438
+ expect(exec).toHaveBeenCalledOnce()
2439
+ expect(exec).toHaveBeenLastCalledWith('hello')
2466
2440
 
2467
2441
  expect(result).toEqual({
2468
2442
  $ref: '#/x-ext/aaf4c61',
@@ -2476,30 +2450,21 @@ describe('bundle', () => {
2476
2450
 
2477
2451
  it('emits warning when there is no loader to resolve the external ref', async () => {
2478
2452
  resetConsoleSpies()
2479
- const validate = vi.fn()
2480
- const exec = vi.fn()
2453
+ const validate = vi.fn<LoaderPlugin['validate']>().mockReturnValue(false)
2454
+ const exec = vi.fn<LoaderPlugin['exec']>()
2481
2455
 
2482
2456
  const resolver = (): LoaderPlugin => {
2483
2457
  return {
2484
2458
  type: 'loader',
2485
- validate(value) {
2486
- validate(value)
2487
- return false
2488
- },
2489
- async exec(value) {
2490
- exec(value)
2491
- return {
2492
- ok: true,
2493
- data: { message: 'Resolved document' },
2494
- }
2495
- },
2459
+ validate,
2460
+ exec,
2496
2461
  }
2497
2462
  }
2498
2463
 
2499
2464
  const result = await bundle({ $ref: 'hello' }, { treeShake: false, plugins: [resolver()] })
2500
2465
 
2501
2466
  expect(validate).toHaveBeenCalledOnce()
2502
- expect(validate.mock.calls[0][0]).toBe('hello')
2467
+ expect(validate).toHaveBeenLastCalledWith('hello')
2503
2468
 
2504
2469
  expect(exec).not.toHaveBeenCalled()
2505
2470
 
@@ -2512,8 +2477,8 @@ describe('bundle', () => {
2512
2477
  })
2513
2478
 
2514
2479
  it('lets plugins hook into nodes lifecycle #1', async () => {
2515
- const onBeforeNodeProcessCallback = vi.fn()
2516
- const onAfterNodeProcessCallback = vi.fn()
2480
+ const onBeforeNodeProcess = vi.fn()
2481
+ const onAfterNodeProcess = vi.fn()
2517
2482
 
2518
2483
  await bundle(
2519
2484
  {
@@ -2526,88 +2491,118 @@ describe('bundle', () => {
2526
2491
  plugins: [
2527
2492
  {
2528
2493
  type: 'lifecycle',
2529
- onBeforeNodeProcess: onBeforeNodeProcessCallback,
2530
- onAfterNodeProcess: onAfterNodeProcessCallback,
2494
+ onBeforeNodeProcess,
2495
+ onAfterNodeProcess,
2531
2496
  },
2532
2497
  ],
2533
2498
  },
2534
2499
  )
2535
2500
 
2536
- expect(onBeforeNodeProcessCallback).toHaveBeenCalledTimes(2)
2537
- expect(onBeforeNodeProcessCallback.mock.calls[0][0]).toEqual({
2538
- prop: {
2539
- innerProp: 'string',
2540
- },
2541
- })
2542
- expect(onBeforeNodeProcessCallback.mock.calls[0][1]).toEqual({
2543
- path: [],
2544
- resolutionCache: new Map(),
2545
- parentNode: null,
2546
- rootNode: {
2501
+ expect(onBeforeNodeProcess).toHaveBeenCalledTimes(2)
2502
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2503
+ 1,
2504
+ {
2547
2505
  prop: {
2548
2506
  innerProp: 'string',
2549
2507
  },
2550
2508
  },
2551
- loaders: [],
2552
- })
2553
- expect(onBeforeNodeProcessCallback.mock.calls[1][0]).toEqual({
2554
- innerProp: 'string',
2555
- })
2556
- expect(onBeforeNodeProcessCallback.mock.calls[1][1]).toEqual({
2557
- path: ['prop'],
2558
- resolutionCache: new Map(),
2559
- parentNode: {
2560
- prop: {
2561
- innerProp: 'string',
2509
+ {
2510
+ path: [],
2511
+ resolutionCache: new Map(),
2512
+ parentNode: null,
2513
+ rootNode: {
2514
+ prop: {
2515
+ innerProp: 'string',
2516
+ },
2562
2517
  },
2518
+ loaders: [],
2563
2519
  },
2564
- rootNode: {
2565
- prop: {
2566
- innerProp: 'string',
2567
- },
2520
+ )
2521
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2522
+ 2,
2523
+ {
2524
+ innerProp: 'string',
2568
2525
  },
2569
- loaders: [],
2570
- })
2571
- expect(onAfterNodeProcessCallback).toHaveBeenCalledTimes(2)
2572
- expect(onAfterNodeProcessCallback.mock.calls[0][0]).toEqual({
2573
- innerProp: 'string',
2574
- })
2575
- expect(onAfterNodeProcessCallback.mock.calls[0][1]).toEqual({
2576
- path: ['prop'],
2577
- resolutionCache: new Map(),
2578
- parentNode: {
2579
- prop: {
2580
- innerProp: 'string',
2526
+ {
2527
+ path: ['prop'],
2528
+ resolutionCache: new Map(),
2529
+ parentNode: {
2530
+ prop: {
2531
+ innerProp: 'string',
2532
+ },
2581
2533
  },
2582
- },
2583
- rootNode: {
2584
- prop: {
2585
- innerProp: 'string',
2534
+ rootNode: {
2535
+ prop: {
2536
+ innerProp: 'string',
2537
+ },
2586
2538
  },
2539
+ loaders: [],
2587
2540
  },
2588
- loaders: [],
2589
- })
2590
- expect(onAfterNodeProcessCallback.mock.calls[1][0]).toEqual({
2591
- prop: {
2541
+ )
2542
+
2543
+ expect(onAfterNodeProcess).toHaveBeenCalledTimes(2)
2544
+ expect(onAfterNodeProcess).toHaveBeenNthCalledWith(
2545
+ 1,
2546
+ {
2592
2547
  innerProp: 'string',
2593
2548
  },
2594
- })
2595
- expect(onAfterNodeProcessCallback.mock.calls[1][1]).toEqual({
2596
- path: [],
2597
- resolutionCache: new Map(),
2598
- parentNode: null,
2599
- rootNode: {
2549
+ {
2550
+ path: ['prop'],
2551
+ resolutionCache: new Map(),
2552
+ parentNode: {
2553
+ prop: {
2554
+ innerProp: 'string',
2555
+ },
2556
+ },
2557
+ rootNode: {
2558
+ prop: {
2559
+ innerProp: 'string',
2560
+ },
2561
+ },
2562
+ loaders: [],
2563
+ },
2564
+ )
2565
+ expect(onAfterNodeProcess).toHaveBeenNthCalledWith(
2566
+ 2,
2567
+ {
2600
2568
  prop: {
2601
2569
  innerProp: 'string',
2602
2570
  },
2603
2571
  },
2604
- loaders: [],
2605
- })
2572
+ {
2573
+ path: [],
2574
+ resolutionCache: new Map(),
2575
+ parentNode: null,
2576
+ rootNode: {
2577
+ prop: {
2578
+ innerProp: 'string',
2579
+ },
2580
+ },
2581
+ loaders: [],
2582
+ },
2583
+ )
2606
2584
  })
2607
2585
 
2608
2586
  it('lets plugins hook into nodes lifecycle #2', async () => {
2609
- const validate = vi.fn()
2610
- const exec = vi.fn()
2587
+ const validate = vi.fn<LoaderPlugin['validate']>((value) => {
2588
+ if (value === 'resolve') {
2589
+ return true
2590
+ }
2591
+ return false
2592
+ })
2593
+ const exec = vi.fn<LoaderPlugin['exec']>((value) =>
2594
+ Promise.resolve({
2595
+ ok: true,
2596
+ data: {
2597
+ message: 'Resolved value',
2598
+ 'x-original-value': value,
2599
+ },
2600
+ raw: JSON.stringify({
2601
+ message: 'Resolved value',
2602
+ 'x-original-value': value,
2603
+ }),
2604
+ }),
2605
+ )
2611
2606
  const onResolveStart = vi.fn()
2612
2607
  const onResolveError = vi.fn()
2613
2608
  const onResolveSuccess = vi.fn()
@@ -2625,23 +2620,8 @@ describe('bundle', () => {
2625
2620
  plugins: [
2626
2621
  {
2627
2622
  type: 'loader',
2628
- validate(value) {
2629
- validate()
2630
- if (value === 'resolve') {
2631
- return true
2632
- }
2633
- return false
2634
- },
2635
- async exec(value) {
2636
- exec()
2637
- return {
2638
- ok: true,
2639
- data: {
2640
- message: 'Resolved value',
2641
- 'x-original-value': value,
2642
- },
2643
- }
2644
- },
2623
+ validate,
2624
+ exec,
2645
2625
  },
2646
2626
  {
2647
2627
  type: 'lifecycle',
@@ -2657,20 +2637,14 @@ describe('bundle', () => {
2657
2637
  expect(exec).toHaveBeenCalledOnce()
2658
2638
 
2659
2639
  expect(onResolveStart).toHaveBeenCalledTimes(2)
2660
- expect(onResolveStart.mock.calls[0][0]).toEqual({
2661
- $ref: 'some-value',
2662
- })
2663
- expect(onResolveStart.mock.calls[1][0]).toEqual({
2664
- $ref: '#/x-ext/4e7a208',
2665
- })
2640
+ expect(onResolveStart).nthCalledWith(1, { $ref: 'some-value' })
2641
+ expect(onResolveStart).nthCalledWith(2, { $ref: '#/x-ext/4e7a208' })
2642
+
2666
2643
  expect(onResolveError).toHaveBeenCalledTimes(1)
2667
- expect(onResolveError.mock.calls[0][0]).toEqual({
2668
- $ref: 'some-value',
2669
- })
2644
+ expect(onResolveError).lastCalledWith({ $ref: 'some-value' })
2645
+
2670
2646
  expect(onResolveSuccess).toHaveBeenCalledTimes(1)
2671
- expect(onResolveSuccess.mock.calls[0][0]).toEqual({
2672
- $ref: '#/x-ext/4e7a208',
2673
- })
2647
+ expect(onResolveSuccess).lastCalledWith({ $ref: '#/x-ext/4e7a208' })
2674
2648
  })
2675
2649
 
2676
2650
  it('correctly provides the parent node in different levels', async () => {
@@ -2703,29 +2677,58 @@ describe('bundle', () => {
2703
2677
  treeShake: false,
2704
2678
  })
2705
2679
 
2706
- expect(onBeforeNodeProcess).toHaveBeenCalled()
2680
+ expect(onBeforeNodeProcess).toHaveBeenCalledTimes(7)
2707
2681
 
2708
2682
  // First call should be the root with a null parent
2709
- expect(onBeforeNodeProcess.mock.calls[0][0]).toEqual(input)
2710
- expect(onBeforeNodeProcess.mock.calls[0][1].parentNode).toEqual(null)
2683
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2684
+ 1,
2685
+ input,
2686
+ expect.objectContaining({
2687
+ parentNode: null,
2688
+ }),
2689
+ )
2711
2690
 
2712
- expect(onBeforeNodeProcess.mock.calls[1][0]).toEqual(input.a)
2713
- expect(onBeforeNodeProcess.mock.calls[1][1].parentNode).toEqual(input)
2691
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2692
+ 2,
2693
+ input.a,
2694
+ expect.objectContaining({
2695
+ parentNode: input,
2696
+ }),
2697
+ )
2714
2698
 
2715
- expect(onBeforeNodeProcess.mock.calls[2][0]).toEqual(input.d)
2716
- expect(onBeforeNodeProcess.mock.calls[2][1].parentNode).toEqual(input)
2699
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2700
+ 3,
2701
+ input.d,
2702
+ expect.objectContaining({
2703
+ parentNode: input,
2704
+ }),
2705
+ )
2717
2706
 
2718
- expect(onBeforeNodeProcess.mock.calls[3][0]).toEqual(input.e)
2719
- expect(onBeforeNodeProcess.mock.calls[3][1].parentNode).toEqual(input)
2707
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2708
+ 4,
2709
+ input.e,
2710
+ expect.objectContaining({
2711
+ parentNode: input,
2712
+ }),
2713
+ )
2720
2714
 
2721
- expect(onBeforeNodeProcess.mock.calls[4][0]).toEqual(input.a.b)
2722
- expect(onBeforeNodeProcess.mock.calls[4][1].parentNode).toEqual(input.a)
2715
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2716
+ 5,
2717
+ input.a.b,
2718
+ expect.objectContaining({ parentNode: input.a }),
2719
+ )
2723
2720
 
2724
- expect(onBeforeNodeProcess.mock.calls[5][0]).toEqual(input.e.f)
2725
- expect(onBeforeNodeProcess.mock.calls[5][1].parentNode).toEqual(input.e)
2721
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2722
+ 6,
2723
+ input.e.f,
2724
+ expect.objectContaining({ parentNode: input.e }),
2725
+ )
2726
2726
 
2727
- expect(onBeforeNodeProcess.mock.calls[6][0]).toEqual(input.a.b.c)
2728
- expect(onBeforeNodeProcess.mock.calls[6][1].parentNode).toEqual(input.a.b)
2727
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2728
+ 7,
2729
+ input.a.b.c,
2730
+ expect.objectContaining({ parentNode: input.a.b }),
2731
+ )
2729
2732
  })
2730
2733
 
2731
2734
  it('correctly provides the parent node on partial bundle for referenced nodes', async () => {
@@ -2753,15 +2756,31 @@ describe('bundle', () => {
2753
2756
  ],
2754
2757
  })
2755
2758
 
2756
- expect(onBeforeNodeProcess).toHaveBeenCalled()
2757
- expect(onBeforeNodeProcess.mock.calls[0][0]).toEqual(input.b)
2758
- expect(onBeforeNodeProcess.mock.calls[0][1].parentNode).toEqual(null)
2759
+ expect(onBeforeNodeProcess).toHaveBeenCalledTimes(3)
2759
2760
 
2760
- expect(onBeforeNodeProcess.mock.calls[1][0]).toEqual(input.b.c)
2761
- expect(onBeforeNodeProcess.mock.calls[1][1].parentNode).toEqual(input.b)
2761
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2762
+ 1,
2763
+ input.b,
2764
+ expect.objectContaining({
2765
+ parentNode: null,
2766
+ }),
2767
+ )
2762
2768
 
2763
- expect(onBeforeNodeProcess.mock.calls[2][0]).toEqual(input.a)
2764
- expect(onBeforeNodeProcess.mock.calls[2][1].parentNode).toEqual(input)
2769
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2770
+ 2,
2771
+ input.b.c,
2772
+ expect.objectContaining({
2773
+ parentNode: input.b,
2774
+ }),
2775
+ )
2776
+
2777
+ expect(onBeforeNodeProcess).toHaveBeenNthCalledWith(
2778
+ 3,
2779
+ input.a,
2780
+ expect.objectContaining({
2781
+ parentNode: input,
2782
+ }),
2783
+ )
2765
2784
  })
2766
2785
  })
2767
2786
  })
@@ -2873,7 +2892,7 @@ describe('resolveAndCopyReferences', () => {
2873
2892
  },
2874
2893
  }
2875
2894
 
2876
- it('correctly resolves and copies local references, and leaves out the rest', async () => {
2895
+ it('correctly resolves and copies local references, and leaves out the rest', () => {
2877
2896
  const target = {}
2878
2897
 
2879
2898
  resolveAndCopyReferences(target, source, '/paths/~1', '', '', true)