ipx 2.0.0-0 → 2.0.0-1

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/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -7,8 +7,8 @@ High performance, secure and easy-to-use image optimizer.
7
7
 
8
8
  Powered by [sharp](https://github.com/lovell/sharp) and [libvips](https://github.com/libvips/libvips).
9
9
 
10
- > [!IMPORTANT]
11
- > This is the development branch for IPX v2. Check out [ipx/v1](https://github.com/unjs/ipx/tree/v1) for latest stable docs.
10
+ > [!IMPORTANT]
11
+ > This is the development branch for IPX v2. Check out [ipx/v1](https://github.com/unjs/ipx/tree/v1) for latest stable docs and [#71](https://github.com/unjs/ipx/issues/171) for v2 roadmap.
12
12
 
13
13
  ## Using CLI
14
14
 
@@ -17,13 +17,13 @@ You can use `ipx` command to start server.
17
17
  Using `npx`:
18
18
 
19
19
  ```bash
20
- npx ipx@latest serve --dir ./
20
+ npx ipx@next-2 serve --dir ./
21
21
  ```
22
22
 
23
23
  Usin `bun`
24
24
 
25
25
  ```bash
26
- bun x ipx@latest serve --dir ./
26
+ bun x npx ipx@next-2 serve --dir ./
27
27
  ```
28
28
 
29
29
  The default serve directory is the current working directory.
@@ -38,7 +38,7 @@ import {
38
38
  createIPXMiddleware,
39
39
  ipxFSStorage,
40
40
  ipxHttpStorage,
41
- } from "./src";
41
+ } from "ipx";
42
42
 
43
43
  const ipx = createIPX({
44
44
  storage: ipxFSStorage({ dir: "./public" }),
package/dist/cli.cjs CHANGED
@@ -3,7 +3,7 @@
3
3
  const listhen = require('listhen');
4
4
  const citty = require('citty');
5
5
  const cli = require('listhen/cli');
6
- const nodeFs = require('./shared/ipx.0fc4e4c7.cjs');
6
+ const nodeFs = require('./shared/ipx.680a50a5.cjs');
7
7
  require('defu');
8
8
  require('image-meta');
9
9
  require('ufo');
@@ -11,11 +11,11 @@ require('h3');
11
11
  require('destr');
12
12
  require('@fastify/accept-negotiator');
13
13
  require('etag');
14
- require('node-fetch-native');
14
+ require('ofetch');
15
15
  require('pathe');
16
16
 
17
17
  const name = "ipx";
18
- const version = "2.0.0-0";
18
+ const version = "2.0.0-1";
19
19
  const description = "High performance, secure and easy-to-use image optimizer.";
20
20
 
21
21
  const serve = citty.defineCommand({
package/dist/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import { listen } from 'listhen';
2
2
  import { defineCommand, runMain } from 'citty';
3
3
  import { getArgs, parseArgs } from 'listhen/cli';
4
- import { c as createIPX, g as ipxFSStorage, i as ipxHttpStorage, e as createIPXNodeServer } from './shared/ipx.42c0c175.mjs';
4
+ import { c as createIPX, g as ipxFSStorage, i as ipxHttpStorage, e as createIPXNodeServer } from './shared/ipx.57fad794.mjs';
5
5
  import 'defu';
6
6
  import 'image-meta';
7
7
  import 'ufo';
@@ -9,11 +9,11 @@ import 'h3';
9
9
  import 'destr';
10
10
  import '@fastify/accept-negotiator';
11
11
  import 'etag';
12
- import 'node-fetch-native';
12
+ import 'ofetch';
13
13
  import 'pathe';
14
14
 
15
15
  const name = "ipx";
16
- const version = "2.0.0-0";
16
+ const version = "2.0.0-1";
17
17
  const description = "High performance, secure and easy-to-use image optimizer.";
18
18
 
19
19
  const serve = defineCommand({
package/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- const nodeFs = require('./shared/ipx.0fc4e4c7.cjs');
3
+ const nodeFs = require('./shared/ipx.680a50a5.cjs');
4
4
  require('defu');
5
5
  require('image-meta');
6
6
  require('ufo');
@@ -8,7 +8,7 @@ require('h3');
8
8
  require('destr');
9
9
  require('@fastify/accept-negotiator');
10
10
  require('etag');
11
- require('node-fetch-native');
11
+ require('ofetch');
12
12
  require('pathe');
13
13
 
14
14
  function unstorageToIPXStorage(storage, prefix) {
package/dist/index.d.cts CHANGED
@@ -128,7 +128,11 @@ type IPXOptions = {
128
128
  };
129
129
  declare function createIPX(userOptions: IPXOptions): IPX;
130
130
 
131
- declare function createIPXH3Handler(ipx: IPX): h3.EventHandler<h3.EventHandlerRequest, Promise<Buffer | null>>;
131
+ declare function createIPXH3Handler(ipx: IPX): h3.EventHandler<h3.EventHandlerRequest, Promise<Buffer | {
132
+ error: {
133
+ message: string;
134
+ };
135
+ } | null>>;
132
136
  declare function createIPXH3App(ipx: IPX): h3.App;
133
137
  declare function createIPXWebServer(ipx: IPX): h3.WebHandler;
134
138
  declare function createIPXNodeServer(ipx: IPX): h3.NodeListener;
package/dist/index.d.mts CHANGED
@@ -128,7 +128,11 @@ type IPXOptions = {
128
128
  };
129
129
  declare function createIPX(userOptions: IPXOptions): IPX;
130
130
 
131
- declare function createIPXH3Handler(ipx: IPX): h3.EventHandler<h3.EventHandlerRequest, Promise<Buffer | null>>;
131
+ declare function createIPXH3Handler(ipx: IPX): h3.EventHandler<h3.EventHandlerRequest, Promise<Buffer | {
132
+ error: {
133
+ message: string;
134
+ };
135
+ } | null>>;
132
136
  declare function createIPXH3App(ipx: IPX): h3.App;
133
137
  declare function createIPXWebServer(ipx: IPX): h3.WebHandler;
134
138
  declare function createIPXNodeServer(ipx: IPX): h3.NodeListener;
package/dist/index.d.ts CHANGED
@@ -128,7 +128,11 @@ type IPXOptions = {
128
128
  };
129
129
  declare function createIPX(userOptions: IPXOptions): IPX;
130
130
 
131
- declare function createIPXH3Handler(ipx: IPX): h3.EventHandler<h3.EventHandlerRequest, Promise<Buffer | null>>;
131
+ declare function createIPXH3Handler(ipx: IPX): h3.EventHandler<h3.EventHandlerRequest, Promise<Buffer | {
132
+ error: {
133
+ message: string;
134
+ };
135
+ } | null>>;
132
136
  declare function createIPXH3App(ipx: IPX): h3.App;
133
137
  declare function createIPXWebServer(ipx: IPX): h3.WebHandler;
134
138
  declare function createIPXNodeServer(ipx: IPX): h3.NodeListener;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- export { c as createIPX, b as createIPXH3App, a as createIPXH3Handler, e as createIPXNodeServer, f as createIPXPlainServer, d as createIPXWebServer, g as ipxFSStorage, i as ipxHttpStorage } from './shared/ipx.42c0c175.mjs';
1
+ export { c as createIPX, b as createIPXH3App, a as createIPXH3Handler, e as createIPXNodeServer, f as createIPXPlainServer, d as createIPXWebServer, g as ipxFSStorage, i as ipxHttpStorage } from './shared/ipx.57fad794.mjs';
2
2
  import 'defu';
3
3
  import 'image-meta';
4
4
  import 'ufo';
@@ -6,7 +6,7 @@ import 'h3';
6
6
  import 'destr';
7
7
  import '@fastify/accept-negotiator';
8
8
  import 'etag';
9
- import 'node-fetch-native';
9
+ import 'ofetch';
10
10
  import 'pathe';
11
11
 
12
12
  function unstorageToIPXStorage(storage, prefix) {
@@ -1,11 +1,11 @@
1
1
  import { defu } from 'defu';
2
2
  import { imageMeta } from 'image-meta';
3
3
  import { withLeadingSlash, hasProtocol, joinURL, decode } from 'ufo';
4
- import { createError, defineEventHandler, getRequestHeader, setResponseHeader, setResponseStatus, createApp, toWebHandler, toNodeListener, toPlainHandler } from 'h3';
4
+ import { createError, defineEventHandler, setResponseStatus, createApp, toWebHandler, toNodeListener, toPlainHandler, getRequestHeader, setResponseHeader } from 'h3';
5
5
  import destr from 'destr';
6
6
  import { negotiate } from '@fastify/accept-negotiator';
7
7
  import getEtag from 'etag';
8
- import { fetch } from 'node-fetch-native';
8
+ import { ofetch } from 'ofetch';
9
9
  import { resolve, join, parse } from 'pathe';
10
10
 
11
11
  const Handlers = {
@@ -335,6 +335,7 @@ function createIPX(userOptions) {
335
335
  if (!id) {
336
336
  throw createError({
337
337
  statusCode: 400,
338
+ statusText: `IPX_MISSING_ID`,
338
339
  message: `Resource id is missing`
339
340
  });
340
341
  }
@@ -348,6 +349,7 @@ function createIPX(userOptions) {
348
349
  if (!storage) {
349
350
  throw createError({
350
351
  statusCode: 500,
352
+ statusText: `IPX_NO_STORAGE`,
351
353
  message: "No storage configured!"
352
354
  });
353
355
  }
@@ -356,6 +358,7 @@ function createIPX(userOptions) {
356
358
  if (!sourceMeta) {
357
359
  throw createError({
358
360
  statusCode: 404,
361
+ statusText: `IPX_RESOURCE_NOT_FOUND`,
359
362
  message: `Resource not found: ${id}`
360
363
  });
361
364
  }
@@ -369,6 +372,7 @@ function createIPX(userOptions) {
369
372
  if (!sourceData) {
370
373
  throw createError({
371
374
  statusCode: 404,
375
+ statusText: `IPX_RESOURCE_NOT_FOUND`,
372
376
  message: `Resource not found: ${id}`
373
377
  });
374
378
  }
@@ -376,7 +380,16 @@ function createIPX(userOptions) {
376
380
  });
377
381
  const process = cachedPromise(async () => {
378
382
  const sourceData = await getSourceData();
379
- const imageMeta$1 = imageMeta(sourceData);
383
+ let imageMeta$1;
384
+ try {
385
+ imageMeta$1 = imageMeta(sourceData);
386
+ } catch {
387
+ throw createError({
388
+ statusCode: 400,
389
+ statusText: `IPX_INVALID_IMAGE`,
390
+ message: `Cannot parse image metadata: ${id}`
391
+ });
392
+ }
380
393
  let mFormat = modifiers.f || modifiers.format;
381
394
  if (mFormat === "jpg") {
382
395
  mFormat = "jpeg";
@@ -432,7 +445,7 @@ function createIPX(userOptions) {
432
445
  const MODIFIER_SEP = /[&,]/g;
433
446
  const MODIFIER_VAL_SEP = /[:=_]/;
434
447
  function createIPXH3Handler(ipx) {
435
- return defineEventHandler(async (event) => {
448
+ const _handler = async (event) => {
436
449
  const [modifiersString = "", ...idSegments] = event.path.slice(
437
450
  1
438
451
  /* leading slash */
@@ -441,12 +454,14 @@ function createIPXH3Handler(ipx) {
441
454
  if (!modifiersString) {
442
455
  throw createError({
443
456
  statusCode: 400,
457
+ statusText: `IPX_MISSING_MODIFIERS`,
444
458
  message: `Modifiers are missing: ${id}`
445
459
  });
446
460
  }
447
461
  if (!id || id === "/") {
448
462
  throw createError({
449
463
  statusCode: 400,
464
+ statusText: `IPX_MISSING_ID`,
450
465
  message: `Resource id is missing: ${event.path}`
451
466
  });
452
467
  }
@@ -499,6 +514,19 @@ function createIPXH3Handler(ipx) {
499
514
  }
500
515
  setResponseHeader(event, "content-security-policy", "default-src 'none'");
501
516
  return data;
517
+ };
518
+ return defineEventHandler(async (event) => {
519
+ try {
520
+ return await _handler(event);
521
+ } catch (_error) {
522
+ const error = createError(_error);
523
+ setResponseStatus(event, error.statusCode, error.statusMessage);
524
+ return {
525
+ error: {
526
+ message: `[${error.statusCode}] [${error.statusMessage || "IPX_ERROR"}] ${error.message}`
527
+ }
528
+ };
529
+ }
502
530
  });
503
531
  }
504
532
  function createIPXH3App(ipx) {
@@ -557,24 +585,20 @@ function ipxHttpStorage(_options = {}) {
557
585
  if (!url.hostname) {
558
586
  throw createError({
559
587
  statusCode: 403,
588
+ statusText: `IPX_MISSING_HOSTNAME`,
560
589
  message: `Hostname is missing: ${id}`
561
590
  });
562
591
  }
563
592
  if (!allowAllDomains && !domains.has(url.hostname)) {
564
593
  throw createError({
565
594
  statusCode: 403,
595
+ statusText: `IPX_FORBIDDEN_HOST`,
566
596
  message: `Forbidden host: ${url.hostname}`
567
597
  });
568
598
  }
569
599
  return url.toString();
570
600
  }
571
601
  function parseResponse(response) {
572
- if (!response.ok) {
573
- throw createError({
574
- statusCode: response.status || 500,
575
- message: `Fetch error: ${response.statusText}`
576
- });
577
- }
578
602
  let maxAge = defaultMaxAge;
579
603
  const _cacheControl = response.headers.get("cache-control");
580
604
  if (_cacheControl) {
@@ -595,7 +619,10 @@ function ipxHttpStorage(_options = {}) {
595
619
  async getMeta(id) {
596
620
  const url = validateId(id);
597
621
  try {
598
- const response = await fetch(url, { ...fetchOptions, method: "HEAD" });
622
+ const response = await ofetch.raw(url, {
623
+ ...fetchOptions,
624
+ method: "HEAD"
625
+ });
599
626
  const { maxAge, mtime } = parseResponse(response);
600
627
  return { mtime, maxAge };
601
628
  } catch {
@@ -604,8 +631,12 @@ function ipxHttpStorage(_options = {}) {
604
631
  },
605
632
  async getData(id) {
606
633
  const url = validateId(id);
607
- const response = await fetch(url, { ...fetchOptions, method: "GET" });
608
- return response.arrayBuffer();
634
+ const response = await ofetch(url, {
635
+ ...fetchOptions,
636
+ method: "GET",
637
+ responseType: "arrayBuffer"
638
+ });
639
+ return response;
609
640
  }
610
641
  };
611
642
  }
@@ -618,6 +649,7 @@ function ipxFSStorage(_options = {}) {
618
649
  if (!isValidPath(resolved) || !resolved.startsWith(rootDir)) {
619
650
  throw createError({
620
651
  statusCode: 403,
652
+ statusText: `IPX_FORBIDDEN_PATH`,
621
653
  message: `Forbidden path: ${id}`
622
654
  });
623
655
  }
@@ -635,16 +667,19 @@ function ipxFSStorage(_options = {}) {
635
667
  } catch (error) {
636
668
  throw error.code === "ENOENT" ? createError({
637
669
  statusCode: 404,
638
- message: `File not found: ${fsPath}`
670
+ statusText: `IPX_FILE_NOT_FOUND`,
671
+ message: `File not found: ${id}`
639
672
  }) : createError({
640
673
  statusCode: 403,
641
- message: `File access error: (${error.code}) ${fsPath}`
674
+ statusText: `IPX_FORBIDDEN_FILE`,
675
+ message: `File access forbidden: (${error.code}) ${id}`
642
676
  });
643
677
  }
644
678
  if (!stats.isFile()) {
645
679
  throw createError({
646
680
  statusCode: 400,
647
- message: `Path should be a file: ${fsPath}`
681
+ statusText: `IPX_INVALID_FILE`,
682
+ message: `Path should be a file: ${id}`
648
683
  });
649
684
  }
650
685
  return {
@@ -7,7 +7,7 @@ const h3 = require('h3');
7
7
  const destr = require('destr');
8
8
  const acceptNegotiator = require('@fastify/accept-negotiator');
9
9
  const getEtag = require('etag');
10
- const nodeFetchNative = require('node-fetch-native');
10
+ const ofetch = require('ofetch');
11
11
  const pathe = require('pathe');
12
12
 
13
13
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
@@ -342,6 +342,7 @@ function createIPX(userOptions) {
342
342
  if (!id) {
343
343
  throw h3.createError({
344
344
  statusCode: 400,
345
+ statusText: `IPX_MISSING_ID`,
345
346
  message: `Resource id is missing`
346
347
  });
347
348
  }
@@ -355,6 +356,7 @@ function createIPX(userOptions) {
355
356
  if (!storage) {
356
357
  throw h3.createError({
357
358
  statusCode: 500,
359
+ statusText: `IPX_NO_STORAGE`,
358
360
  message: "No storage configured!"
359
361
  });
360
362
  }
@@ -363,6 +365,7 @@ function createIPX(userOptions) {
363
365
  if (!sourceMeta) {
364
366
  throw h3.createError({
365
367
  statusCode: 404,
368
+ statusText: `IPX_RESOURCE_NOT_FOUND`,
366
369
  message: `Resource not found: ${id}`
367
370
  });
368
371
  }
@@ -376,6 +379,7 @@ function createIPX(userOptions) {
376
379
  if (!sourceData) {
377
380
  throw h3.createError({
378
381
  statusCode: 404,
382
+ statusText: `IPX_RESOURCE_NOT_FOUND`,
379
383
  message: `Resource not found: ${id}`
380
384
  });
381
385
  }
@@ -383,7 +387,16 @@ function createIPX(userOptions) {
383
387
  });
384
388
  const process = cachedPromise(async () => {
385
389
  const sourceData = await getSourceData();
386
- const imageMeta$1 = imageMeta.imageMeta(sourceData);
390
+ let imageMeta$1;
391
+ try {
392
+ imageMeta$1 = imageMeta.imageMeta(sourceData);
393
+ } catch {
394
+ throw h3.createError({
395
+ statusCode: 400,
396
+ statusText: `IPX_INVALID_IMAGE`,
397
+ message: `Cannot parse image metadata: ${id}`
398
+ });
399
+ }
387
400
  let mFormat = modifiers.f || modifiers.format;
388
401
  if (mFormat === "jpg") {
389
402
  mFormat = "jpeg";
@@ -439,7 +452,7 @@ function createIPX(userOptions) {
439
452
  const MODIFIER_SEP = /[&,]/g;
440
453
  const MODIFIER_VAL_SEP = /[:=_]/;
441
454
  function createIPXH3Handler(ipx) {
442
- return h3.defineEventHandler(async (event) => {
455
+ const _handler = async (event) => {
443
456
  const [modifiersString = "", ...idSegments] = event.path.slice(
444
457
  1
445
458
  /* leading slash */
@@ -448,12 +461,14 @@ function createIPXH3Handler(ipx) {
448
461
  if (!modifiersString) {
449
462
  throw h3.createError({
450
463
  statusCode: 400,
464
+ statusText: `IPX_MISSING_MODIFIERS`,
451
465
  message: `Modifiers are missing: ${id}`
452
466
  });
453
467
  }
454
468
  if (!id || id === "/") {
455
469
  throw h3.createError({
456
470
  statusCode: 400,
471
+ statusText: `IPX_MISSING_ID`,
457
472
  message: `Resource id is missing: ${event.path}`
458
473
  });
459
474
  }
@@ -506,6 +521,19 @@ function createIPXH3Handler(ipx) {
506
521
  }
507
522
  h3.setResponseHeader(event, "content-security-policy", "default-src 'none'");
508
523
  return data;
524
+ };
525
+ return h3.defineEventHandler(async (event) => {
526
+ try {
527
+ return await _handler(event);
528
+ } catch (_error) {
529
+ const error = h3.createError(_error);
530
+ h3.setResponseStatus(event, error.statusCode, error.statusMessage);
531
+ return {
532
+ error: {
533
+ message: `[${error.statusCode}] [${error.statusMessage || "IPX_ERROR"}] ${error.message}`
534
+ }
535
+ };
536
+ }
509
537
  });
510
538
  }
511
539
  function createIPXH3App(ipx) {
@@ -564,24 +592,20 @@ function ipxHttpStorage(_options = {}) {
564
592
  if (!url.hostname) {
565
593
  throw h3.createError({
566
594
  statusCode: 403,
595
+ statusText: `IPX_MISSING_HOSTNAME`,
567
596
  message: `Hostname is missing: ${id}`
568
597
  });
569
598
  }
570
599
  if (!allowAllDomains && !domains.has(url.hostname)) {
571
600
  throw h3.createError({
572
601
  statusCode: 403,
602
+ statusText: `IPX_FORBIDDEN_HOST`,
573
603
  message: `Forbidden host: ${url.hostname}`
574
604
  });
575
605
  }
576
606
  return url.toString();
577
607
  }
578
608
  function parseResponse(response) {
579
- if (!response.ok) {
580
- throw h3.createError({
581
- statusCode: response.status || 500,
582
- message: `Fetch error: ${response.statusText}`
583
- });
584
- }
585
609
  let maxAge = defaultMaxAge;
586
610
  const _cacheControl = response.headers.get("cache-control");
587
611
  if (_cacheControl) {
@@ -602,7 +626,10 @@ function ipxHttpStorage(_options = {}) {
602
626
  async getMeta(id) {
603
627
  const url = validateId(id);
604
628
  try {
605
- const response = await nodeFetchNative.fetch(url, { ...fetchOptions, method: "HEAD" });
629
+ const response = await ofetch.ofetch.raw(url, {
630
+ ...fetchOptions,
631
+ method: "HEAD"
632
+ });
606
633
  const { maxAge, mtime } = parseResponse(response);
607
634
  return { mtime, maxAge };
608
635
  } catch {
@@ -611,8 +638,12 @@ function ipxHttpStorage(_options = {}) {
611
638
  },
612
639
  async getData(id) {
613
640
  const url = validateId(id);
614
- const response = await nodeFetchNative.fetch(url, { ...fetchOptions, method: "GET" });
615
- return response.arrayBuffer();
641
+ const response = await ofetch.ofetch(url, {
642
+ ...fetchOptions,
643
+ method: "GET",
644
+ responseType: "arrayBuffer"
645
+ });
646
+ return response;
616
647
  }
617
648
  };
618
649
  }
@@ -625,6 +656,7 @@ function ipxFSStorage(_options = {}) {
625
656
  if (!isValidPath(resolved) || !resolved.startsWith(rootDir)) {
626
657
  throw h3.createError({
627
658
  statusCode: 403,
659
+ statusText: `IPX_FORBIDDEN_PATH`,
628
660
  message: `Forbidden path: ${id}`
629
661
  });
630
662
  }
@@ -642,16 +674,19 @@ function ipxFSStorage(_options = {}) {
642
674
  } catch (error) {
643
675
  throw error.code === "ENOENT" ? h3.createError({
644
676
  statusCode: 404,
645
- message: `File not found: ${fsPath}`
677
+ statusText: `IPX_FILE_NOT_FOUND`,
678
+ message: `File not found: ${id}`
646
679
  }) : h3.createError({
647
680
  statusCode: 403,
648
- message: `File access error: (${error.code}) ${fsPath}`
681
+ statusText: `IPX_FORBIDDEN_FILE`,
682
+ message: `File access forbidden: (${error.code}) ${id}`
649
683
  });
650
684
  }
651
685
  if (!stats.isFile()) {
652
686
  throw h3.createError({
653
687
  statusCode: 400,
654
- message: `Path should be a file: ${fsPath}`
688
+ statusText: `IPX_INVALID_FILE`,
689
+ message: `Path should be a file: ${id}`
655
690
  });
656
691
  }
657
692
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ipx",
3
- "version": "2.0.0-0",
3
+ "version": "2.0.0-1",
4
4
  "repository": "unjs/ipx",
5
5
  "description": "High performance, secure and easy-to-use image optimizer.",
6
6
  "license": "MIT",
@@ -24,6 +24,18 @@
24
24
  "dist",
25
25
  "bin"
26
26
  ],
27
+ "scripts": {
28
+ "build": "unbuild",
29
+ "dev": "listhen -w playground",
30
+ "ipx": "jiti ./src/cli.ts",
31
+ "lint": "eslint --ext .ts . && prettier -c src test",
32
+ "lint:fix": "eslint --ext .ts . --fix && prettier -w src test",
33
+ "prepack": "pnpm build",
34
+ "release": "pnpm test && changelogen --release --push && npm publish",
35
+ "prerelease": "pnpm test && pnpm build && changelogen --release --prerelease --push --publish --publishTag next-2",
36
+ "start": "node bin/ipx.js",
37
+ "test": "pnpm lint && vitest run --coverage"
38
+ },
27
39
  "dependencies": {
28
40
  "@fastify/accept-negotiator": "^1.1.0",
29
41
  "citty": "^0.1.4",
@@ -31,39 +43,28 @@
31
43
  "defu": "^6.1.2",
32
44
  "destr": "^2.0.1",
33
45
  "etag": "^1.8.1",
34
- "h3": "^1.8.1",
46
+ "h3": "^1.8.2",
35
47
  "image-meta": "^0.1.1",
36
- "listhen": "^1.5.2",
37
- "node-fetch-native": "^1.4.0",
48
+ "listhen": "^1.5.5",
49
+ "ofetch": "^1.3.3",
38
50
  "pathe": "^1.1.1",
39
- "sharp": "^0.32.5",
51
+ "sharp": "^0.32.6",
40
52
  "ufo": "^1.3.0",
41
53
  "unstorage": "^1.9.0"
42
54
  },
43
55
  "devDependencies": {
44
56
  "@types/etag": "^1.8.1",
45
57
  "@types/is-valid-path": "^0.1.0",
46
- "@vitest/coverage-v8": "^0.34.4",
58
+ "@vitest/coverage-v8": "^0.34.5",
47
59
  "changelogen": "^0.5.5",
48
- "eslint": "^8.49.0",
60
+ "eslint": "^8.50.0",
49
61
  "eslint-config-unjs": "^0.2.1",
50
62
  "jiti": "^1.20.0",
51
63
  "prettier": "^3.0.3",
52
64
  "serve-handler": "^6.1.5",
53
65
  "typescript": "^5.2.2",
54
66
  "unbuild": "^2.0.0",
55
- "vitest": "^0.34.4"
67
+ "vitest": "^0.34.5"
56
68
  },
57
- "packageManager": "pnpm@8.7.5",
58
- "scripts": {
59
- "build": "unbuild",
60
- "dev": "listhen -w playground",
61
- "ipx": "jiti ./src/cli.ts",
62
- "lint": "eslint --ext .ts . && prettier -c src test",
63
- "lint:fix": "eslint --ext .ts . --fix && prettier -w src test",
64
- "release": "pnpm test && changelogen --release --push && npm publish",
65
- "prerelease": "pnpm test && pnpm build && changelogen --release --prerelease --push --publish --publishTag v2",
66
- "start": "node bin/ipx.js",
67
- "test": "pnpm lint && vitest run --coverage"
68
- }
69
+ "packageManager": "pnpm@8.8.0"
69
70
  }