@helia/verified-fetch 2.3.1 → 2.5.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 (119) hide show
  1. package/README.md +200 -0
  2. package/dist/index.min.js +357 -35
  3. package/dist/src/index.d.ts +220 -0
  4. package/dist/src/index.d.ts.map +1 -1
  5. package/dist/src/index.js +200 -0
  6. package/dist/src/index.js.map +1 -1
  7. package/dist/src/plugins/errors.d.ts +25 -0
  8. package/dist/src/plugins/errors.d.ts.map +1 -0
  9. package/dist/src/plugins/errors.js +33 -0
  10. package/dist/src/plugins/errors.js.map +1 -0
  11. package/dist/src/plugins/index.d.ts +8 -0
  12. package/dist/src/plugins/index.d.ts.map +1 -0
  13. package/dist/src/plugins/index.js +7 -0
  14. package/dist/src/plugins/index.js.map +1 -0
  15. package/dist/src/plugins/plugin-base.d.ts +19 -0
  16. package/dist/src/plugins/plugin-base.d.ts.map +1 -0
  17. package/dist/src/plugins/plugin-base.js +26 -0
  18. package/dist/src/plugins/plugin-base.js.map +1 -0
  19. package/dist/src/plugins/plugin-handle-car.d.ts +11 -0
  20. package/dist/src/plugins/plugin-handle-car.d.ts.map +1 -0
  21. package/dist/src/plugins/plugin-handle-car.js +28 -0
  22. package/dist/src/plugins/plugin-handle-car.js.map +1 -0
  23. package/dist/src/plugins/plugin-handle-dag-cbor.d.ts +11 -0
  24. package/dist/src/plugins/plugin-handle-dag-cbor.d.ts.map +1 -0
  25. package/dist/src/plugins/plugin-handle-dag-cbor.js +73 -0
  26. package/dist/src/plugins/plugin-handle-dag-cbor.js.map +1 -0
  27. package/dist/src/plugins/plugin-handle-dag-pb.d.ts +15 -0
  28. package/dist/src/plugins/plugin-handle-dag-pb.d.ts.map +1 -0
  29. package/dist/src/plugins/plugin-handle-dag-pb.js +152 -0
  30. package/dist/src/plugins/plugin-handle-dag-pb.js.map +1 -0
  31. package/dist/src/plugins/plugin-handle-dag-walk.d.ts +16 -0
  32. package/dist/src/plugins/plugin-handle-dag-walk.d.ts.map +1 -0
  33. package/dist/src/plugins/plugin-handle-dag-walk.js +45 -0
  34. package/dist/src/plugins/plugin-handle-dag-walk.js.map +1 -0
  35. package/dist/src/plugins/plugin-handle-dir-index-html.d.ts +9 -0
  36. package/dist/src/plugins/plugin-handle-dir-index-html.d.ts.map +1 -0
  37. package/dist/src/plugins/plugin-handle-dir-index-html.js +37 -0
  38. package/dist/src/plugins/plugin-handle-dir-index-html.js.map +1 -0
  39. package/dist/src/plugins/plugin-handle-ipns-record.d.ts +12 -0
  40. package/dist/src/plugins/plugin-handle-ipns-record.d.ts.map +1 -0
  41. package/dist/src/plugins/plugin-handle-ipns-record.js +62 -0
  42. package/dist/src/plugins/plugin-handle-ipns-record.js.map +1 -0
  43. package/dist/src/plugins/plugin-handle-json.d.ts +11 -0
  44. package/dist/src/plugins/plugin-handle-json.d.ts.map +1 -0
  45. package/dist/src/plugins/plugin-handle-json.js +51 -0
  46. package/dist/src/plugins/plugin-handle-json.js.map +1 -0
  47. package/dist/src/plugins/plugin-handle-raw.d.ts +8 -0
  48. package/dist/src/plugins/plugin-handle-raw.d.ts.map +1 -0
  49. package/dist/src/plugins/plugin-handle-raw.js +80 -0
  50. package/dist/src/plugins/plugin-handle-raw.js.map +1 -0
  51. package/dist/src/plugins/plugin-handle-tar.d.ts +12 -0
  52. package/dist/src/plugins/plugin-handle-tar.d.ts.map +1 -0
  53. package/dist/src/plugins/plugin-handle-tar.js +36 -0
  54. package/dist/src/plugins/plugin-handle-tar.js.map +1 -0
  55. package/dist/src/plugins/plugins.d.ts +5 -0
  56. package/dist/src/plugins/plugins.d.ts.map +1 -0
  57. package/dist/src/plugins/plugins.js +5 -0
  58. package/dist/src/plugins/plugins.js.map +1 -0
  59. package/dist/src/plugins/types.d.ts +68 -0
  60. package/dist/src/plugins/types.d.ts.map +1 -0
  61. package/dist/src/plugins/types.js +2 -0
  62. package/dist/src/plugins/types.js.map +1 -0
  63. package/dist/src/types.d.ts +0 -23
  64. package/dist/src/types.d.ts.map +1 -1
  65. package/dist/src/types.js +1 -2
  66. package/dist/src/types.js.map +1 -1
  67. package/dist/src/utils/dir-index-html.d.ts +16 -0
  68. package/dist/src/utils/dir-index-html.d.ts.map +1 -0
  69. package/dist/src/utils/dir-index-html.js +387 -0
  70. package/dist/src/utils/dir-index-html.js.map +1 -0
  71. package/dist/src/utils/get-e-tag.d.ts +1 -1
  72. package/dist/src/utils/get-e-tag.d.ts.map +1 -1
  73. package/dist/src/utils/get-e-tag.js +18 -3
  74. package/dist/src/utils/get-e-tag.js.map +1 -1
  75. package/dist/src/utils/parse-resource.d.ts +2 -1
  76. package/dist/src/utils/parse-resource.d.ts.map +1 -1
  77. package/dist/src/utils/parse-resource.js +4 -3
  78. package/dist/src/utils/parse-resource.js.map +1 -1
  79. package/dist/src/utils/parse-url-string.d.ts +8 -3
  80. package/dist/src/utils/parse-url-string.d.ts.map +1 -1
  81. package/dist/src/utils/parse-url-string.js +30 -4
  82. package/dist/src/utils/parse-url-string.js.map +1 -1
  83. package/dist/src/utils/server-timing.d.ts +13 -0
  84. package/dist/src/utils/server-timing.d.ts.map +1 -0
  85. package/dist/src/utils/server-timing.js +19 -0
  86. package/dist/src/utils/server-timing.js.map +1 -0
  87. package/dist/src/utils/walk-path.d.ts +3 -2
  88. package/dist/src/utils/walk-path.d.ts.map +1 -1
  89. package/dist/src/utils/walk-path.js +1 -1
  90. package/dist/src/utils/walk-path.js.map +1 -1
  91. package/dist/src/verified-fetch.d.ts +11 -20
  92. package/dist/src/verified-fetch.d.ts.map +1 -1
  93. package/dist/src/verified-fetch.js +174 -367
  94. package/dist/src/verified-fetch.js.map +1 -1
  95. package/dist/typedoc-urls.json +32 -24
  96. package/package.json +6 -2
  97. package/src/index.ts +223 -0
  98. package/src/plugins/errors.ts +37 -0
  99. package/src/plugins/index.ts +8 -0
  100. package/src/plugins/plugin-base.ts +30 -0
  101. package/src/plugins/plugin-handle-car.ts +32 -0
  102. package/src/plugins/plugin-handle-dag-cbor.ts +84 -0
  103. package/src/plugins/plugin-handle-dag-pb.ts +168 -0
  104. package/src/plugins/plugin-handle-dag-walk.ts +53 -0
  105. package/src/plugins/plugin-handle-dir-index-html.ts +44 -0
  106. package/src/plugins/plugin-handle-ipns-record.ts +69 -0
  107. package/src/plugins/plugin-handle-json.ts +57 -0
  108. package/src/plugins/plugin-handle-raw.ts +92 -0
  109. package/src/plugins/plugin-handle-tar.ts +44 -0
  110. package/src/plugins/plugins.ts +4 -0
  111. package/src/plugins/types.ts +73 -0
  112. package/src/types.ts +0 -29
  113. package/src/utils/dir-index-html.ts +445 -0
  114. package/src/utils/get-e-tag.ts +20 -3
  115. package/src/utils/parse-resource.ts +5 -4
  116. package/src/utils/parse-url-string.ts +38 -7
  117. package/src/utils/server-timing.ts +37 -0
  118. package/src/utils/walk-path.ts +3 -3
  119. package/src/verified-fetch.ts +198 -403
@@ -604,6 +604,14 @@
604
604
  * * https://specs.ipfs.tech/http-gateways/trustless-gateway/#response-headers
605
605
  * * https://specs.ipfs.tech/http-gateways/subdomain-gateway/#response-headers
606
606
  *
607
+ * #### Server Timing headers
608
+ *
609
+ * By default, we do not include [Server Timing](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Server_timing) headers in responses. If you want to include them, you can pass an
610
+ * `withServerTiming` option to the `createVerifiedFetch` function to include them in all future responses. You can
611
+ * also pass the `withServerTiming` option to each fetch call to include them only for that specific response.
612
+ *
613
+ * See PR where this was added, https://github.com/ipfs/helia-verified-fetch/pull/164, for more information.
614
+ *
607
615
  * ### Possible Scenarios that could cause confusion
608
616
  *
609
617
  * #### Attempting to fetch the CID for content that does not make sense
@@ -618,12 +626,204 @@
618
626
  * 2. `TypeError` - If the options argument is passed and not an object.
619
627
  * 3. `TypeError` - If the options argument is passed and is malformed.
620
628
  * 4. `AbortError` - If the content request is aborted due to user aborting provided AbortSignal. Note that this is a `AbortError` from `@libp2p/interface` and not the standard `AbortError` from the Fetch API.
629
+ *
630
+ * ## Pluggability and Extensibility
631
+ *
632
+ * Verified‑fetch can now be extended to alter how it handles requests by using plugins.
633
+ * Plugins are classes that extend the `BasePlugin` class and implement the `VerifiedFetchPlugin`
634
+ * interface. They are instantiated with `PluginOptions` when the `VerifiedFetch` class is created.
635
+ *
636
+ * Each plugin must implement two methods:
637
+ *
638
+ * - **`canHandle(context: PluginContext): boolean`**
639
+ * Inspects the current `PluginContext` (which includes the CID, path, query, accept header, etc.)
640
+ * and returns `true` if the plugin can operate on the current state of the request.
641
+ *
642
+ * - **`handle(context: PluginContext): Promise<Response | null>`**
643
+ * Performs the plugin’s work. It may:
644
+ * - **Return a final `Response`**: This stops the pipeline immediately.
645
+ * - **Return `null`**: This indicates that the plugin has only partially processed the request
646
+ * (for example, by performing path walking or decoding) and the pipeline should continue.
647
+ * - **Throw a `PluginError`**: This logs a non-fatal error and continues the pipeline.
648
+ * - **Throw a `PluginFatalError`**: This logs a fatal error and stops the pipeline immediately.
649
+ *
650
+ * Plugins are executed in a chain (a **plugin pipeline**):
651
+ *
652
+ * 1. **Initialization:**
653
+ * - The `VerifiedFetch` class is instantiated with a list of plugins.
654
+ * - When a request is made via the `fetch` method, the resource and options are parsed to
655
+ * create a mutable `PluginContext` object.
656
+ *
657
+ * 2. **Pipeline Execution:**
658
+ * - The pipeline repeatedly checks, up to a maximum number of passes (default = 3), which plugins
659
+ * are currently able to handle the request by calling each plugin’s `canHandle()` method.
660
+ * - Plugins that have not yet been called in the current run and return `true` for `canHandle()`
661
+ * are invoked in sequence.
662
+ * - If a plugin returns a final `Response` or throws a `PluginFatalError`, the pipeline immediately
663
+ * stops and that response is returned.
664
+ * - If a plugin returns `null`, it may have updated the context (for example, by
665
+ * performing path walking), other plugins that said they `canHandle` will run.
666
+ * - If no plugin modifies the context (i.e. no change to `context.modified`) and no final response is
667
+ * produced after iterating through all plugins, the pipeline exits and a default “Not Supported”
668
+ * response is returned.
669
+ *
670
+ * **Diagram of the Plugin Pipeline:**
671
+ *
672
+ * ```mermaid
673
+ * flowchart TD
674
+ * A[Resource & Options] --> B[Parse into PluginContext]
675
+ * B --> C[Plugin Pipeline]
676
+ * subgraph IP[Iterative Passes max 3 passes]
677
+ * C1[Check canHandle for each plugin]
678
+ * C2[Call handle on ready plugins]
679
+ * C3[Update PluginContext if partial work is done]
680
+ * C1 --> C2
681
+ * C2 --> C3
682
+ * end
683
+ * C --> IP
684
+ * IP --> D[Final Response]
685
+ * ```
686
+ *
687
+ * 3. **Finalization:**
688
+ * - After the pipeline completes, the resulting response & context is processed (e.g. headers such as ETag,
689
+ * Cache‑Control, and Content‑Disposition are set) and returned.
690
+ *
691
+ * Please see the original discussion on extensibility in [Issue #167](https://github.com/ipfs/helia-verified-fetch/issues/167).
692
+ *
693
+ * ---
694
+ *
695
+ * ### Extending Verified‑Fetch with Custom Plugins
696
+ *
697
+ * To add your own plugin:
698
+ *
699
+ * 1. **Extend the BasePlugin:**
700
+ *
701
+ * Create a new class that extends `BasePlugin` and implements:
702
+ *
703
+ * - `canHandle(context: PluginContext): boolean`
704
+ * - `handle(context: PluginContext): Promise<Response | null>`
705
+ *
706
+ * @example custom plugin
707
+ *
708
+ * ```typescript
709
+ * import { BasePlugin, type PluginContext, type VerifiedFetchPluginFactory, type PluginOptions } from '@helia/verified-fetch'
710
+ * import { okResponse } from './dist/src/utils/responses.js'
711
+ *
712
+ * export class MyCustomPlugin extends BasePlugin {
713
+ * // Optionally, list any codec codes your plugin supports:
714
+ * codes = [] //
715
+ *
716
+ * canHandle(context: PluginContext): boolean {
717
+ * // Only handle requests if the Accept header matches your custom type
718
+ * // Or check context for pathDetails, custom values, etc...
719
+ * return context.accept === 'application/vnd.my-custom-type'
720
+ * }
721
+ *
722
+ * async handle(context: PluginContext): Promise<Response | null> {
723
+ * // Perform any partial processing here, e.g., modify the context:
724
+ * context.customProcessed = true;
725
+ *
726
+ * // If you are ready to finalize the response:
727
+ * return new Response('Hello, world!', {
728
+ * status: 200,
729
+ * headers: {
730
+ * 'Content-Type': 'text/plain'
731
+ * }
732
+ });
733
+ *
734
+ * // Or, if further processing is needed by another plugin, simply return null.
735
+ * }
736
+ * }
737
+ * export const myCustomPluginFactory: VerifiedFetchPluginFactory = (opts: PluginOptions) => new MyCustomPlugin(opts)
738
+ * ```
739
+ *
740
+ * 2. **Integrate Your Plugin:**
741
+ *
742
+ * Add your custom plugin to Verified‑Fetch’s plugin list when instantiating Verified‑Fetch:
743
+ *
744
+ * @example Integrate custom plugin
745
+ *
746
+ * ```typescript
747
+ * import { createVerifiedFetch, type VerifiedFetchPluginFactory } from '@helia/verified-fetch'
748
+ * import { createHelia } from 'helia'
749
+ *
750
+ * const helia = await createHelia()
751
+ * const plugins: VerifiedFetchPluginFactory[] = [
752
+ * // myCustomPluginFactory
753
+ * ]
754
+ *
755
+ * const fetch = await createVerifiedFetch(helia, { plugins })
756
+ * ```
757
+ *
758
+ * ---
759
+ *
760
+ * ### Error Handling in the Plugin Pipeline
761
+ *
762
+ * Verified‑Fetch distinguishes between two types of errors thrown by plugins:
763
+ *
764
+ * - **PluginError (Non‑Fatal):**
765
+ * - Use this when your plugin encounters an issue that should be logged but does not prevent the pipeline
766
+ * from continuing.
767
+ * - When a plugin throws a `PluginError`, the error is logged and the pipeline continues with the next plugin.
768
+ *
769
+ * - **PluginFatalError (Fatal):**
770
+ * - Use this when a critical error occurs that should immediately abort the request.
771
+ * - When a plugin throws a `PluginFatalError`, the pipeline immediately terminates and the provided error
772
+ * response is returned.
773
+ *
774
+ * @example Plugin error Handling
775
+ *
776
+ * ```typescript
777
+ * import { PluginError, PluginFatalError } from '@helia/verified-fetch'
778
+ *
779
+ * // async handle(context: PluginContext): Promise<Response | null> {
780
+ * const recoverable = Math.random() > 0.5 // Use more sophisticated logic here ;)
781
+ * if (recoverable === true) {
782
+ * throw new PluginError('MY_CUSTOM_WARNING', 'A non‑fatal issue occurred', {
783
+ * details: {
784
+ * someKey: 'Additional details here'
785
+ * }
786
+ * });
787
+ * }
788
+ *
789
+ * if (recoverable === false) {
790
+ * throw new PluginFatalError('MY_CUSTOM_FATAL', 'A critical error occurred', {
791
+ * response: new Response('Something happened', { status: 500 }) // Required: supply your own error response
792
+ * });
793
+ * }
794
+ *
795
+ * // Otherwise, continue processing...
796
+ * // }
797
+ * ```
798
+ *
799
+ * ### How the Plugin Pipeline Works
800
+ *
801
+ * - **Shared Context:**
802
+ * A mutable `PluginContext` is created for each request. It includes the parsed CID, path, query parameters,
803
+ * accept header, and any other metadata. Plugins can update this context as they perform partial work (for example,
804
+ * by doing path walking or decoding).
805
+ *
806
+ * - **Iterative Processing:**
807
+ * The pipeline repeatedly checks which plugins can currently handle the request by calling `canHandle(context)`.
808
+ * - Plugins that perform partial processing update the context and return `null`, allowing subsequent passes by other plugins.
809
+ * - Once a plugin is ready to finalize the response, it returns a final `Response` and the pipeline terminates.
810
+ *
811
+ * - **No Strict Ordering:**
812
+ * Plugins are invoked based solely on whether they can handle the current state of the context.
813
+ * This means you do not have to specify a rigid order, each plugin simply checks the context and acts if appropriate.
814
+ *
815
+ * - **Error Handling:**
816
+ * - A thrown `PluginError` is considered non‑fatal and is logged, allowing the pipeline to continue.
817
+ * - A thrown `PluginFatalError` immediately stops the pipeline and returns the error response.
818
+ *
819
+ * For a detailed explanation of the pipeline, please refer to the discussion in [Issue #167](https://github.com/ipfs/helia-verified-fetch/issues/167).
621
820
  */
622
821
  import { type ResolveDNSLinkProgressEvents } from '@helia/ipns';
623
822
  import { type ServiceMap } from '@libp2p/interface';
624
823
  import { type HeliaInit } from 'helia';
625
824
  import { type Libp2pOptions } from 'libp2p';
626
825
  import { type ContentTypeParser } from './types.js';
826
+ import type { VerifiedFetchPluginFactory } from './plugins/types.js';
627
827
  import type { GetBlockProgressEvents, Helia } from '@helia/interface';
628
828
  import type { DNSResolvers } from '@multiformats/dns';
629
829
  import type { DNSResolver } from '@multiformats/dns/resolvers';
@@ -730,6 +930,18 @@ export interface CreateVerifiedFetchOptions {
730
930
  * @default 60000
731
931
  */
732
932
  sessionTTLms?: number;
933
+ /**
934
+ * Whether to include server-timing headers in responses. This option can be overridden on a per-request basis.
935
+ *
936
+ * @default false
937
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
938
+ */
939
+ withServerTiming?: boolean;
940
+ /**
941
+ * Plugins to use with the verified-fetch instance. Note that we have a set of default plugins that are always used.
942
+ * If you want to replace one of the default plugins, you can do so by passing a plugin with the same name.
943
+ */
944
+ plugins?: VerifiedFetchPluginFactory[];
733
945
  }
734
946
  export type { ContentTypeParser } from './types.js';
735
947
  export type BubbledProgressEvents = ExporterProgressEvents | GetBlockProgressEvents | ResolveDNSLinkProgressEvents;
@@ -780,10 +992,18 @@ export interface VerifiedFetchInit extends RequestInit, ProgressOptions<BubbledP
780
992
  * @default false
781
993
  */
782
994
  allowInsecure?: boolean;
995
+ /**
996
+ * Whether to include server-timing headers in the response for an individual request.
997
+ *
998
+ * @default false
999
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing
1000
+ */
1001
+ withServerTiming?: boolean;
783
1002
  }
784
1003
  /**
785
1004
  * Create and return a Helia node
786
1005
  */
787
1006
  export declare function createVerifiedFetch(init?: Helia | CreateVerifiedFetchInit, options?: CreateVerifiedFetchOptions): Promise<VerifiedFetch>;
788
1007
  export { verifiedFetch } from './singleton.js';
1008
+ export * from './plugins/index.js';
789
1009
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/dist/src/index.js CHANGED
@@ -604,6 +604,14 @@
604
604
  * * https://specs.ipfs.tech/http-gateways/trustless-gateway/#response-headers
605
605
  * * https://specs.ipfs.tech/http-gateways/subdomain-gateway/#response-headers
606
606
  *
607
+ * #### Server Timing headers
608
+ *
609
+ * By default, we do not include [Server Timing](https://developer.mozilla.org/en-US/docs/Web/API/Performance_API/Server_timing) headers in responses. If you want to include them, you can pass an
610
+ * `withServerTiming` option to the `createVerifiedFetch` function to include them in all future responses. You can
611
+ * also pass the `withServerTiming` option to each fetch call to include them only for that specific response.
612
+ *
613
+ * See PR where this was added, https://github.com/ipfs/helia-verified-fetch/pull/164, for more information.
614
+ *
607
615
  * ### Possible Scenarios that could cause confusion
608
616
  *
609
617
  * #### Attempting to fetch the CID for content that does not make sense
@@ -618,6 +626,197 @@
618
626
  * 2. `TypeError` - If the options argument is passed and not an object.
619
627
  * 3. `TypeError` - If the options argument is passed and is malformed.
620
628
  * 4. `AbortError` - If the content request is aborted due to user aborting provided AbortSignal. Note that this is a `AbortError` from `@libp2p/interface` and not the standard `AbortError` from the Fetch API.
629
+ *
630
+ * ## Pluggability and Extensibility
631
+ *
632
+ * Verified‑fetch can now be extended to alter how it handles requests by using plugins.
633
+ * Plugins are classes that extend the `BasePlugin` class and implement the `VerifiedFetchPlugin`
634
+ * interface. They are instantiated with `PluginOptions` when the `VerifiedFetch` class is created.
635
+ *
636
+ * Each plugin must implement two methods:
637
+ *
638
+ * - **`canHandle(context: PluginContext): boolean`**
639
+ * Inspects the current `PluginContext` (which includes the CID, path, query, accept header, etc.)
640
+ * and returns `true` if the plugin can operate on the current state of the request.
641
+ *
642
+ * - **`handle(context: PluginContext): Promise<Response | null>`**
643
+ * Performs the plugin’s work. It may:
644
+ * - **Return a final `Response`**: This stops the pipeline immediately.
645
+ * - **Return `null`**: This indicates that the plugin has only partially processed the request
646
+ * (for example, by performing path walking or decoding) and the pipeline should continue.
647
+ * - **Throw a `PluginError`**: This logs a non-fatal error and continues the pipeline.
648
+ * - **Throw a `PluginFatalError`**: This logs a fatal error and stops the pipeline immediately.
649
+ *
650
+ * Plugins are executed in a chain (a **plugin pipeline**):
651
+ *
652
+ * 1. **Initialization:**
653
+ * - The `VerifiedFetch` class is instantiated with a list of plugins.
654
+ * - When a request is made via the `fetch` method, the resource and options are parsed to
655
+ * create a mutable `PluginContext` object.
656
+ *
657
+ * 2. **Pipeline Execution:**
658
+ * - The pipeline repeatedly checks, up to a maximum number of passes (default = 3), which plugins
659
+ * are currently able to handle the request by calling each plugin’s `canHandle()` method.
660
+ * - Plugins that have not yet been called in the current run and return `true` for `canHandle()`
661
+ * are invoked in sequence.
662
+ * - If a plugin returns a final `Response` or throws a `PluginFatalError`, the pipeline immediately
663
+ * stops and that response is returned.
664
+ * - If a plugin returns `null`, it may have updated the context (for example, by
665
+ * performing path walking), other plugins that said they `canHandle` will run.
666
+ * - If no plugin modifies the context (i.e. no change to `context.modified`) and no final response is
667
+ * produced after iterating through all plugins, the pipeline exits and a default “Not Supported”
668
+ * response is returned.
669
+ *
670
+ * **Diagram of the Plugin Pipeline:**
671
+ *
672
+ * ```mermaid
673
+ * flowchart TD
674
+ * A[Resource & Options] --> B[Parse into PluginContext]
675
+ * B --> C[Plugin Pipeline]
676
+ * subgraph IP[Iterative Passes max 3 passes]
677
+ * C1[Check canHandle for each plugin]
678
+ * C2[Call handle on ready plugins]
679
+ * C3[Update PluginContext if partial work is done]
680
+ * C1 --> C2
681
+ * C2 --> C3
682
+ * end
683
+ * C --> IP
684
+ * IP --> D[Final Response]
685
+ * ```
686
+ *
687
+ * 3. **Finalization:**
688
+ * - After the pipeline completes, the resulting response & context is processed (e.g. headers such as ETag,
689
+ * Cache‑Control, and Content‑Disposition are set) and returned.
690
+ *
691
+ * Please see the original discussion on extensibility in [Issue #167](https://github.com/ipfs/helia-verified-fetch/issues/167).
692
+ *
693
+ * ---
694
+ *
695
+ * ### Extending Verified‑Fetch with Custom Plugins
696
+ *
697
+ * To add your own plugin:
698
+ *
699
+ * 1. **Extend the BasePlugin:**
700
+ *
701
+ * Create a new class that extends `BasePlugin` and implements:
702
+ *
703
+ * - `canHandle(context: PluginContext): boolean`
704
+ * - `handle(context: PluginContext): Promise<Response | null>`
705
+ *
706
+ * @example custom plugin
707
+ *
708
+ * ```typescript
709
+ * import { BasePlugin, type PluginContext, type VerifiedFetchPluginFactory, type PluginOptions } from '@helia/verified-fetch'
710
+ * import { okResponse } from './dist/src/utils/responses.js'
711
+ *
712
+ * export class MyCustomPlugin extends BasePlugin {
713
+ * // Optionally, list any codec codes your plugin supports:
714
+ * codes = [] //
715
+ *
716
+ * canHandle(context: PluginContext): boolean {
717
+ * // Only handle requests if the Accept header matches your custom type
718
+ * // Or check context for pathDetails, custom values, etc...
719
+ * return context.accept === 'application/vnd.my-custom-type'
720
+ * }
721
+ *
722
+ * async handle(context: PluginContext): Promise<Response | null> {
723
+ * // Perform any partial processing here, e.g., modify the context:
724
+ * context.customProcessed = true;
725
+ *
726
+ * // If you are ready to finalize the response:
727
+ * return new Response('Hello, world!', {
728
+ * status: 200,
729
+ * headers: {
730
+ * 'Content-Type': 'text/plain'
731
+ * }
732
+ });
733
+ *
734
+ * // Or, if further processing is needed by another plugin, simply return null.
735
+ * }
736
+ * }
737
+ * export const myCustomPluginFactory: VerifiedFetchPluginFactory = (opts: PluginOptions) => new MyCustomPlugin(opts)
738
+ * ```
739
+ *
740
+ * 2. **Integrate Your Plugin:**
741
+ *
742
+ * Add your custom plugin to Verified‑Fetch’s plugin list when instantiating Verified‑Fetch:
743
+ *
744
+ * @example Integrate custom plugin
745
+ *
746
+ * ```typescript
747
+ * import { createVerifiedFetch, type VerifiedFetchPluginFactory } from '@helia/verified-fetch'
748
+ * import { createHelia } from 'helia'
749
+ *
750
+ * const helia = await createHelia()
751
+ * const plugins: VerifiedFetchPluginFactory[] = [
752
+ * // myCustomPluginFactory
753
+ * ]
754
+ *
755
+ * const fetch = await createVerifiedFetch(helia, { plugins })
756
+ * ```
757
+ *
758
+ * ---
759
+ *
760
+ * ### Error Handling in the Plugin Pipeline
761
+ *
762
+ * Verified‑Fetch distinguishes between two types of errors thrown by plugins:
763
+ *
764
+ * - **PluginError (Non‑Fatal):**
765
+ * - Use this when your plugin encounters an issue that should be logged but does not prevent the pipeline
766
+ * from continuing.
767
+ * - When a plugin throws a `PluginError`, the error is logged and the pipeline continues with the next plugin.
768
+ *
769
+ * - **PluginFatalError (Fatal):**
770
+ * - Use this when a critical error occurs that should immediately abort the request.
771
+ * - When a plugin throws a `PluginFatalError`, the pipeline immediately terminates and the provided error
772
+ * response is returned.
773
+ *
774
+ * @example Plugin error Handling
775
+ *
776
+ * ```typescript
777
+ * import { PluginError, PluginFatalError } from '@helia/verified-fetch'
778
+ *
779
+ * // async handle(context: PluginContext): Promise<Response | null> {
780
+ * const recoverable = Math.random() > 0.5 // Use more sophisticated logic here ;)
781
+ * if (recoverable === true) {
782
+ * throw new PluginError('MY_CUSTOM_WARNING', 'A non‑fatal issue occurred', {
783
+ * details: {
784
+ * someKey: 'Additional details here'
785
+ * }
786
+ * });
787
+ * }
788
+ *
789
+ * if (recoverable === false) {
790
+ * throw new PluginFatalError('MY_CUSTOM_FATAL', 'A critical error occurred', {
791
+ * response: new Response('Something happened', { status: 500 }) // Required: supply your own error response
792
+ * });
793
+ * }
794
+ *
795
+ * // Otherwise, continue processing...
796
+ * // }
797
+ * ```
798
+ *
799
+ * ### How the Plugin Pipeline Works
800
+ *
801
+ * - **Shared Context:**
802
+ * A mutable `PluginContext` is created for each request. It includes the parsed CID, path, query parameters,
803
+ * accept header, and any other metadata. Plugins can update this context as they perform partial work (for example,
804
+ * by doing path walking or decoding).
805
+ *
806
+ * - **Iterative Processing:**
807
+ * The pipeline repeatedly checks which plugins can currently handle the request by calling `canHandle(context)`.
808
+ * - Plugins that perform partial processing update the context and return `null`, allowing subsequent passes by other plugins.
809
+ * - Once a plugin is ready to finalize the response, it returns a final `Response` and the pipeline terminates.
810
+ *
811
+ * - **No Strict Ordering:**
812
+ * Plugins are invoked based solely on whether they can handle the current state of the context.
813
+ * This means you do not have to specify a rigid order, each plugin simply checks the context and acts if appropriate.
814
+ *
815
+ * - **Error Handling:**
816
+ * - A thrown `PluginError` is considered non‑fatal and is logged, allowing the pipeline to continue.
817
+ * - A thrown `PluginFatalError` immediately stops the pipeline and returns the error response.
818
+ *
819
+ * For a detailed explanation of the pipeline, please refer to the discussion in [Issue #167](https://github.com/ipfs/helia-verified-fetch/issues/167).
621
820
  */
622
821
  import { bitswap, trustlessGateway } from '@helia/block-brokers';
623
822
  import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client';
@@ -678,6 +877,7 @@ export async function createVerifiedFetch(init, options) {
678
877
  return verifiedFetch;
679
878
  }
680
879
  export { verifiedFetch } from './singleton.js';
880
+ export * from './plugins/index.js';
681
881
  function isHelia(obj) {
682
882
  // test for the presence of known Helia properties, return a boolean value
683
883
  return obj?.blockstore != null &&
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4mBG;AAEH,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAChE,OAAO,EAAE,qCAAqC,EAAE,MAAM,6CAA6C,CAAA;AACnG,OAAO,EAAqC,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAgC,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AACvC,OAAO,EAAE,WAAW,EAAkB,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,YAAY,EAAsB,MAAM,QAAQ,CAAA;AACzD,OAAO,EAA0B,MAAM,YAAY,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,EAAE,aAAa,IAAI,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AA6LzE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAE,IAAsC,EAAE,OAAoC;IACrH,IAAI,MAA+B,CAAA;IACnC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,CAAA;QAEzC,MAAM,YAAY,GAAG,eAAe,EAAE,CAAA;QACtC,YAAY,CAAC,GAAG,GAAG,GAAG,CAAA;QAEtB,MAAM,gBAAgB,GAAG,IAAI,EAAE,OAAO,IAAI,CAAC,4BAA4B,CAAC,CAAA;QACxE,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,gBAAgB,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;YAC7D,MAAM,SAAS,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;YACzC,YAAY,CAAC,QAAQ,CAAC,mBAAmB,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,qCAAqC,CAAC,SAAS,CAAC,CAAA;QAC5G,CAAC;QACD,iFAAiF;QACjF,IAAI,IAAI,EAAE,YAAY,IAAI,IAAI,EAAE,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,CAAA;QAChD,CAAC;QACD,MAAM,GAAG,MAAM,YAAY,CAAC,YAAY,CAAC,CAAA;QAEzC,MAAM,YAAY,GAAG;YACnB,OAAO,EAAE;SACV,CAAA;QACD,MAAM,OAAO,GAA4B;YACvC,aAAa,CAAC,MAAM,CAAC;SACtB,CAAA;QACD,IAAI,IAAI,EAAE,QAAQ,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,4EAA4E;YAC5E,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,aAAa,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;YACzG,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,IAAI,CAAC,gCAAgC,CAAC,EAAE,CAAC,CAAC,CAAA;QACtG,CAAC;QAED,IAAI,GAAG,MAAM,WAAW,CAAC;YACvB,MAAM;YACN,YAAY;YACZ,GAAG;YACH,OAAO;YACP,OAAO,EAAE,IAAI,EAAE,OAAO;SACvB,CAAC,CAAA;QACF,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,KAAK,CAAC,+CAA+C,EAAE,YAAY,CAAC,CAAA;IACvH,CAAC;IAED,MAAM,qBAAqB,GAAG,IAAI,kBAAkB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,OAAO,CAAC,CAAA;IAC9E,KAAK,UAAU,aAAa,CAAE,QAAkB,EAAE,OAA2B;QAC3E,OAAO,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACvD,CAAC;IACD,aAAa,CAAC,KAAK,GAAG,qBAAqB,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;IAC7E,aAAa,CAAC,IAAI,GAAG,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;IAE3E,OAAO,aAAa,CAAA;AACtB,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAE9C,SAAS,OAAO,CAAE,GAAQ;IACxB,0EAA0E;IAC1E,OAAO,GAAG,EAAE,UAAU,IAAI,IAAI;QAC5B,GAAG,EAAE,SAAS,IAAI,IAAI;QACtB,GAAG,EAAE,EAAE,IAAI,IAAI;QACf,GAAG,EAAE,IAAI,IAAI,IAAI;QACjB,GAAG,EAAE,KAAK,IAAI,IAAI,CAAA;AACtB,CAAC;AAED,SAAS,SAAS,CAAE,SAAwC;IAC1D,IAAI,SAAS,IAAI,IAAI,EAAE,CAAC;QACtB,OAAM;IACR,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7B,OAAO,GAAG,CAAC;YACT,SAAS,EAAE;gBACT,GAAG,EAAE,SAAS;aACf;SACF,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,GAAG,CAAC,EAAE,SAAS,EAAE,CAAC,CAAA;AAC3B,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { FatalPluginErrorOptions, PluginErrorOptions } from './types.js';
2
+ /**
3
+ * If a plugin encounters an error, it should throw an instance of this class.
4
+ */
5
+ export declare class PluginError extends Error {
6
+ name: string;
7
+ code: string;
8
+ fatal: boolean;
9
+ details?: Record<string, any>;
10
+ response?: any;
11
+ constructor(code: string, message: string, options?: PluginErrorOptions);
12
+ }
13
+ /**
14
+ * If a plugin encounters a fatal error and verified-fetch should not continue processing the request, it should throw
15
+ * an instance of this class.
16
+ *
17
+ * Note that you should be very careful when throwing a `PluginFatalError`, as it will stop the request from being
18
+ * processed further. If you do not have a response to return to the client, you should consider throwing a
19
+ * `PluginError` instead.
20
+ */
21
+ export declare class PluginFatalError extends PluginError {
22
+ name: string;
23
+ constructor(code: string, message: string, options: FatalPluginErrorOptions);
24
+ }
25
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/plugins/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAE7E;;GAEG;AACH,qBAAa,WAAY,SAAQ,KAAK;IAC7B,IAAI,SAAgB;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC7B,QAAQ,CAAC,EAAE,GAAG,CAAA;gBAER,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB;CAOzE;AAED;;;;;;;GAOG;AACH,qBAAa,gBAAiB,SAAQ,WAAW;IACxC,IAAI,SAAqB;gBAEnB,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB;CAI7E"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * If a plugin encounters an error, it should throw an instance of this class.
3
+ */
4
+ export class PluginError extends Error {
5
+ name = 'PluginError';
6
+ code;
7
+ fatal;
8
+ details;
9
+ response;
10
+ constructor(code, message, options) {
11
+ super(message);
12
+ this.code = code;
13
+ this.fatal = options?.fatal ?? false;
14
+ this.details = options?.details;
15
+ this.response = options?.response;
16
+ }
17
+ }
18
+ /**
19
+ * If a plugin encounters a fatal error and verified-fetch should not continue processing the request, it should throw
20
+ * an instance of this class.
21
+ *
22
+ * Note that you should be very careful when throwing a `PluginFatalError`, as it will stop the request from being
23
+ * processed further. If you do not have a response to return to the client, you should consider throwing a
24
+ * `PluginError` instead.
25
+ */
26
+ export class PluginFatalError extends PluginError {
27
+ name = 'PluginFatalError';
28
+ constructor(code, message, options) {
29
+ super(code, message, { ...options, fatal: true });
30
+ this.name = 'PluginFatalError';
31
+ }
32
+ }
33
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/plugins/errors.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC7B,IAAI,GAAG,aAAa,CAAA;IACpB,IAAI,CAAQ;IACZ,KAAK,CAAS;IACd,OAAO,CAAsB;IAC7B,QAAQ,CAAM;IAErB,YAAa,IAAY,EAAE,OAAe,EAAE,OAA4B;QACtE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,KAAK,CAAA;QACpC,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,OAAO,CAAA;QAC/B,IAAI,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAA;IACnC,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,OAAO,gBAAiB,SAAQ,WAAW;IACxC,IAAI,GAAG,kBAAkB,CAAA;IAEhC,YAAa,IAAY,EAAE,OAAe,EAAE,OAAgC;QAC1E,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;QACjD,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;IAChC,CAAC;CACF"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * This file is the entry into all things we export from the `src/plugins` directory.
3
+ */
4
+ export { PluginError, PluginFatalError } from './errors.js';
5
+ export { BasePlugin } from './plugin-base.js';
6
+ export type { PluginOptions, PluginContext, VerifiedFetchPluginFactory } from './types.js';
7
+ export * from './plugins.js';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAC1F,cAAc,cAAc,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * This file is the entry into all things we export from the `src/plugins` directory.
3
+ */
4
+ export { PluginError, PluginFatalError } from './errors.js';
5
+ export { BasePlugin } from './plugin-base.js';
6
+ export * from './plugins.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,cAAc,cAAc,CAAA"}
@@ -0,0 +1,19 @@
1
+ import type { VerifiedFetchPlugin, PluginContext, PluginOptions } from './types.js';
2
+ import type { Logger } from '@libp2p/interface';
3
+ /**
4
+ * Base class for verified-fetch plugins. This class provides a basic implementation of the `FetchHandlerPlugin`
5
+ * interface.
6
+ *
7
+ * Subclasses should implement the `canHandle` and `handle` methods, and may override the `codes` and `log` properties.
8
+ *
9
+ * If your plugin adds/edits the context supplied in `handle`, you should increment the `context.modified` property.
10
+ */
11
+ export declare class BasePlugin implements VerifiedFetchPlugin {
12
+ readonly codes: number[];
13
+ readonly log: Logger;
14
+ readonly pluginOptions: PluginOptions;
15
+ constructor(options: PluginOptions);
16
+ canHandle(context: PluginContext): boolean;
17
+ handle(context: PluginContext): Promise<Response | null>;
18
+ }
19
+ //# sourceMappingURL=plugin-base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-base.d.ts","sourceRoot":"","sources":["../../../src/plugins/plugin-base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAE/C;;;;;;;GAOG;AACH,qBAAa,UAAW,YAAW,mBAAmB;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAK;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAA;gBACxB,OAAO,EAAE,aAAa;IAOnC,SAAS,CAAE,OAAO,EAAE,aAAa,GAAG,OAAO;IAIrC,MAAM,CAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;CAGhE"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Base class for verified-fetch plugins. This class provides a basic implementation of the `FetchHandlerPlugin`
3
+ * interface.
4
+ *
5
+ * Subclasses should implement the `canHandle` and `handle` methods, and may override the `codes` and `log` properties.
6
+ *
7
+ * If your plugin adds/edits the context supplied in `handle`, you should increment the `context.modified` property.
8
+ */
9
+ export class BasePlugin {
10
+ codes = [];
11
+ log;
12
+ pluginOptions;
13
+ constructor(options) {
14
+ // convert a CamelCase string to a kebab-case string for the logger name of subclasses
15
+ const loggerName = this.constructor.name.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
16
+ this.log = options.logger.forComponent(loggerName);
17
+ this.pluginOptions = options;
18
+ }
19
+ canHandle(context) {
20
+ throw new Error('Not implemented');
21
+ }
22
+ async handle(context) {
23
+ throw new Error('Not implemented');
24
+ }
25
+ }
26
+ //# sourceMappingURL=plugin-base.js.map