@atproto-labs/fetch-node 0.3.0-next.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,26 +1,34 @@
1
1
  # @atproto-labs/fetch-node
2
2
 
3
- ## 0.3.0-next.0
3
+ ## 0.3.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#4967](https://github.com/bluesky-social/atproto/pull/4967) [`9fc720c`](https://github.com/bluesky-social/atproto/commit/9fc720ce75f3ee88a5e48a9be919b07c7647f6f5) Thanks [@matthieusieben](https://github.com/matthieusieben)! - Use TypeScript 7 to build package
8
+
9
+ - Updated dependencies [[`9fc720c`](https://github.com/bluesky-social/atproto/commit/9fc720ce75f3ee88a5e48a9be919b07c7647f6f5)]:
10
+ - @atproto-labs/fetch@0.3.1
11
+ - @atproto-labs/pipe@0.2.1
12
+
13
+ ## 0.3.0
4
14
 
5
15
  ### Minor Changes
6
16
 
7
- - [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
17
+ - [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`f01c59f`](https://github.com/bluesky-social/atproto/commit/f01c59f5bd3f75fb8b47a9eecd4858b84033fb7c) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Drop support for Node.js 18 and 20. Node.js 22 is now the minimum supported version. Docker images now use Node.js 24.
8
18
 
9
- - [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
19
+ - [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`c459153`](https://github.com/bluesky-social/atproto/commit/c459153395a30ce89e050892c8fab7dc98e019b9) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** Convert to pure ESM. All packages now ship `"type": "module"` with ES module output and Node16 module resolution.
10
20
 
11
21
  Node.js 22's `require()` compatibility layer can still load these packages in CommonJS code.
12
22
 
13
- - [#4943](https://github.com/bluesky-social/atproto/pull/4943) [`8e40db6`](https://github.com/bluesky-social/atproto/commit/8e40db65aab7ba5f9414c26dbe1ab658e3bffeca) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** `unicastFetchWrap` and `safeFetchWrap` no longer accept `dangerouslyForceKeepAliveAgent` — on Node.js 22+ the keep-alive dispatcher is always used via `new Request(input, { dispatcher })`, so the option was a no-op.
14
-
15
- - [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0. Emitted `.d.ts` files now use TypeScript 6's stricter `Uint8Array<ArrayBuffer>` typing in places where Web/Node APIs require buffer-backed (not shared-memory) byte arrays. Consumers compiling against these types on older TypeScript should see no runtime impact, but may need to widen or cast in spots that previously relied on `Uint8Array` defaulting to `<ArrayBufferLike>`.
23
+ - [#4929](https://github.com/bluesky-social/atproto/pull/4929) [`f01c59f`](https://github.com/bluesky-social/atproto/commit/f01c59f5bd3f75fb8b47a9eecd4858b84033fb7c) Thanks [@devinivy](https://github.com/devinivy)! - **BREAKING:** `unicastFetchWrap` and `safeFetchWrap` no longer accept `dangerouslyForceKeepAliveAgent` — on Node.js 22+ the keep-alive dispatcher is always used via `new Request(input, { dispatcher })`, so the option was a no-op.
16
24
 
17
- Internal: tsconfig `moduleResolution: "node"` is silenced via `ignoreDeprecations: "6.0"` for now; the proper migration to `node16`/`bundler` resolution is deferred.
25
+ - [#4930](https://github.com/bluesky-social/atproto/pull/4930) [`908bece`](https://github.com/bluesky-social/atproto/commit/908bece169258bff5ad121e5eec157d6ded6f705) Thanks [@devinivy](https://github.com/devinivy)! - Build with TypeScript 6.0.
18
26
 
19
27
  ### Patch Changes
20
28
 
21
- - Updated dependencies [[`bb7491c`](https://github.com/bluesky-social/atproto/commit/bb7491c29e06181e1d2f8cf6eb454f9bb8ab961b), [`07ae5d4`](https://github.com/bluesky-social/atproto/commit/07ae5d4452df51e045e0239da7a04cf0bc154028), [`042df15`](https://github.com/bluesky-social/atproto/commit/042df15087c0e62cd1e715fcbf58852fab875af9)]:
22
- - @atproto-labs/fetch@0.3.0-next.0
23
- - @atproto-labs/pipe@0.2.0-next.0
29
+ - Updated dependencies [[`f01c59f`](https://github.com/bluesky-social/atproto/commit/f01c59f5bd3f75fb8b47a9eecd4858b84033fb7c), [`c459153`](https://github.com/bluesky-social/atproto/commit/c459153395a30ce89e050892c8fab7dc98e019b9), [`908bece`](https://github.com/bluesky-social/atproto/commit/908bece169258bff5ad121e5eec157d6ded6f705)]:
30
+ - @atproto-labs/fetch@0.3.0
31
+ - @atproto-labs/pipe@0.2.0
24
32
 
25
33
  ## 0.2.0
26
34
 
package/dist/safe.d.ts CHANGED
@@ -37,5 +37,5 @@ export type SafeFetchWrapOptions<C> = UnicastFetchWrapOptions<C> & {
37
37
  * function would).
38
38
  */
39
39
  export declare function safeFetchWrap<C>({ fetch, responseMaxSize, // 512kB
40
- ssrfProtection, allowCustomPort, allowData, allowHttp, allowIpHost, allowPrivateIps, timeout, forbiddenDomainNames, allowImplicitRedirect, }?: SafeFetchWrapOptions<C>): (input: string | URL | Request, init?: RequestInit | undefined) => Promise<Response>;
40
+ ssrfProtection, allowCustomPort, allowData, allowHttp, allowIpHost, allowPrivateIps, timeout, forbiddenDomainNames, allowImplicitRedirect, }?: SafeFetchWrapOptions<C>): (input: string | Request | URL, init?: RequestInit | undefined) => Promise<Response>;
41
41
  //# sourceMappingURL=safe.d.ts.map
package/dist/safe.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"safe.js","sourceRoot":"","sources":["../src/safe.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAE9B,SAAS,EACT,qCAAqC,EACrC,qBAAqB,EACrB,mCAAmC,EACnC,6BAA6B,EAC7B,0BAA0B,EAC1B,UAAU,GACX,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAA2B,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAqBxE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAI,EAC/B,KAAK,GAAG,UAAU,CAAC,KAAiB,EACpC,eAAe,GAAG,GAAG,GAAG,IAAI,EAAE,QAAQ;AACtC,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,CAAC,cAAc,EACjC,SAAS,GAAG,KAAK,EACjB,SAAS,GAAG,CAAC,cAAc,EAC3B,WAAW,GAAG,IAAI,EAClB,eAAe,GAAG,CAAC,cAAc,EACjC,OAAO,GAAG,IAAI,EACd,oBAAoB,GAAG,8BAAkD,EACzE,qBAAqB,GAAG,KAAK,MACF,EAAE;IAC7B,OAAO,IAAI;IACT;;OAEG;IACH,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qCAAqC,EAAE;IAE3E;;OAEG;IACH,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,0BAA0B,EAAE;IAEtD;;OAEG;IACH,6BAA6B,CAAC;QAC5B,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,SAAS,IAAI,EAAE,eAAe,EAAE;QACzC,QAAQ,EAAE,EAAE,eAAe,EAAE;KAC9B,CAAC;IAEF;;;;;OAKG;IACH,mCAAmC,CAAC,oBAAoB,CAAC;IAEzD;;;OAGG;IACH,UAAU,CACR,OAAO;IAEP;;;;OAIG;IACH,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CACtD;IAED;;;OAGG;IACH,qBAAqB,CAAC,eAAe,CAAC,CACd,CAAA;AAC5B,CAAC","sourcesContent":["import {\n DEFAULT_FORBIDDEN_DOMAIN_NAMES,\n Fetch,\n asRequest,\n explicitRedirectCheckRequestTransform,\n fetchMaxSizeProcessor,\n forbiddenDomainNameRequestTransform,\n protocolCheckRequestTransform,\n requireHostHeaderTransform,\n timedFetch,\n} from '@atproto-labs/fetch'\nimport { pipe } from '@atproto-labs/pipe'\nimport { UnicastFetchWrapOptions, unicastFetchWrap } from './unicast.js'\n\nexport type SafeFetchWrapOptions<C> = UnicastFetchWrapOptions<C> & {\n responseMaxSize?: number\n ssrfProtection?: boolean\n allowCustomPort?: boolean\n allowData?: boolean\n allowHttp?: boolean\n allowIpHost?: boolean\n allowPrivateIps?: boolean\n timeout?: number\n forbiddenDomainNames?: Iterable<string>\n /**\n * When `false`, a {@link RequestInit['redirect']} value must be explicitly\n * provided as second argument to the returned function or requests will fail.\n *\n * @default false\n */\n allowImplicitRedirect?: boolean\n}\n\n/**\n * Wrap a fetch function with safety checks so that it can be safely used\n * with user provided input (URL).\n *\n * @see {@link https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html}\n *\n * @note When {@link SafeFetchWrapOptions.allowImplicitRedirect} is `false`\n * (default), then the returned function **must** be called setting the second\n * argument's `redirect` property to one of the allowed values. Otherwise, if\n * the returned fetch function is called with a `Request` object (and no\n * explicit `redirect` init object), then the verification code will not be able\n * to determine if the `redirect` property was explicitly set or based on the\n * default value (`follow`), causing it to preventively block the request (throw\n * an error). For this reason, unless you set\n * {@link SafeFetchWrapOptions.allowImplicitRedirect} to `true`, you should\n * **not** wrap the returned function into another function that creates a\n * {@link Request} object before passing it to the function (as a e.g. a logging\n * function would).\n */\nexport function safeFetchWrap<C>({\n fetch = globalThis.fetch as Fetch<C>,\n responseMaxSize = 512 * 1024, // 512kB\n ssrfProtection = true,\n allowCustomPort = !ssrfProtection,\n allowData = false,\n allowHttp = !ssrfProtection,\n allowIpHost = true,\n allowPrivateIps = !ssrfProtection,\n timeout = 10e3,\n forbiddenDomainNames = DEFAULT_FORBIDDEN_DOMAIN_NAMES as Iterable<string>,\n allowImplicitRedirect = false,\n}: SafeFetchWrapOptions<C> = {}) {\n return pipe(\n /**\n * Require explicit {@link RequestInit['redirect']} mode\n */\n allowImplicitRedirect ? asRequest : explicitRedirectCheckRequestTransform(),\n\n /**\n * Only requests that will be issued with a \"Host\" header are allowed.\n */\n allowIpHost ? asRequest : requireHostHeaderTransform(),\n\n /**\n * Prevent using http:, file: or data: protocols.\n */\n protocolCheckRequestTransform({\n 'about:': false,\n 'data:': allowData,\n 'file:': false,\n 'http:': allowHttp && { allowCustomPort },\n 'https:': { allowCustomPort },\n }),\n\n /**\n * Disallow fetching from domains we know are not atproto/OIDC client\n * implementation. Note that other domains can be blocked by providing a\n * custom fetch function combined with another\n * forbiddenDomainNameRequestTransform.\n */\n forbiddenDomainNameRequestTransform(forbiddenDomainNames),\n\n /**\n * Since we will be fetching from the network based on user provided\n * input, let's mitigate resource exhaustion attacks by setting a timeout.\n */\n timedFetch(\n timeout,\n\n /**\n * Since we will be fetching from the network based on user provided\n * input, we need to make sure that the request is not vulnerable to SSRF\n * attacks.\n */\n allowPrivateIps ? fetch : unicastFetchWrap({ fetch }),\n ),\n\n /**\n * Since we will be fetching user owned data, we need to make sure that an\n * attacker cannot force us to download a large amounts of data.\n */\n fetchMaxSizeProcessor(responseMaxSize),\n ) satisfies Fetch<unknown>\n}\n"]}
1
+ {"version":3,"file":"safe.js","sourceRoot":"","sources":["../src/safe.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,8BAA8B,EAE9B,SAAS,EACT,qCAAqC,EACrC,qBAAqB,EACrB,mCAAmC,EACnC,6BAA6B,EAC7B,0BAA0B,EAC1B,UAAU,GACX,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAA2B,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAqBxE;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,aAAa,CAAI,EAC/B,KAAK,GAAG,UAAU,CAAC,KAAiB,EACpC,eAAe,GAAG,GAAG,GAAG,IAAI,EAAE,QAAQ;AACtC,cAAc,GAAG,IAAI,EACrB,eAAe,GAAG,CAAC,cAAc,EACjC,SAAS,GAAG,KAAK,EACjB,SAAS,GAAG,CAAC,cAAc,EAC3B,WAAW,GAAG,IAAI,EAClB,eAAe,GAAG,CAAC,cAAc,EACjC,OAAO,GAAG,IAAI,EACd,oBAAoB,GAAG,8BAAkD,EACzE,qBAAqB,GAAG,KAAK,GAC9B,GAA4B,EAAE;IAC7B,OAAO,IAAI;IACT;;OAEG;IACH,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qCAAqC,EAAE;IAE3E;;OAEG;IACH,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,0BAA0B,EAAE;IAEtD;;OAEG;IACH,6BAA6B,CAAC;QAC5B,QAAQ,EAAE,KAAK;QACf,OAAO,EAAE,SAAS;QAClB,OAAO,EAAE,KAAK;QACd,OAAO,EAAE,SAAS,IAAI,EAAE,eAAe,EAAE;QACzC,QAAQ,EAAE,EAAE,eAAe,EAAE;KAC9B,CAAC;IAEF;;;;;OAKG;IACH,mCAAmC,CAAC,oBAAoB,CAAC;IAEzD;;;OAGG;IACH,UAAU,CACR,OAAO;IAEP;;;;OAIG;IACH,eAAe,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,CAAC,CACtD;IAED;;;OAGG;IACH,qBAAqB,CAAC,eAAe,CAAC,CACd,CAAA;AAC5B,CAAC","sourcesContent":["import {\n DEFAULT_FORBIDDEN_DOMAIN_NAMES,\n Fetch,\n asRequest,\n explicitRedirectCheckRequestTransform,\n fetchMaxSizeProcessor,\n forbiddenDomainNameRequestTransform,\n protocolCheckRequestTransform,\n requireHostHeaderTransform,\n timedFetch,\n} from '@atproto-labs/fetch'\nimport { pipe } from '@atproto-labs/pipe'\nimport { UnicastFetchWrapOptions, unicastFetchWrap } from './unicast.js'\n\nexport type SafeFetchWrapOptions<C> = UnicastFetchWrapOptions<C> & {\n responseMaxSize?: number\n ssrfProtection?: boolean\n allowCustomPort?: boolean\n allowData?: boolean\n allowHttp?: boolean\n allowIpHost?: boolean\n allowPrivateIps?: boolean\n timeout?: number\n forbiddenDomainNames?: Iterable<string>\n /**\n * When `false`, a {@link RequestInit['redirect']} value must be explicitly\n * provided as second argument to the returned function or requests will fail.\n *\n * @default false\n */\n allowImplicitRedirect?: boolean\n}\n\n/**\n * Wrap a fetch function with safety checks so that it can be safely used\n * with user provided input (URL).\n *\n * @see {@link https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html}\n *\n * @note When {@link SafeFetchWrapOptions.allowImplicitRedirect} is `false`\n * (default), then the returned function **must** be called setting the second\n * argument's `redirect` property to one of the allowed values. Otherwise, if\n * the returned fetch function is called with a `Request` object (and no\n * explicit `redirect` init object), then the verification code will not be able\n * to determine if the `redirect` property was explicitly set or based on the\n * default value (`follow`), causing it to preventively block the request (throw\n * an error). For this reason, unless you set\n * {@link SafeFetchWrapOptions.allowImplicitRedirect} to `true`, you should\n * **not** wrap the returned function into another function that creates a\n * {@link Request} object before passing it to the function (as a e.g. a logging\n * function would).\n */\nexport function safeFetchWrap<C>({\n fetch = globalThis.fetch as Fetch<C>,\n responseMaxSize = 512 * 1024, // 512kB\n ssrfProtection = true,\n allowCustomPort = !ssrfProtection,\n allowData = false,\n allowHttp = !ssrfProtection,\n allowIpHost = true,\n allowPrivateIps = !ssrfProtection,\n timeout = 10e3,\n forbiddenDomainNames = DEFAULT_FORBIDDEN_DOMAIN_NAMES as Iterable<string>,\n allowImplicitRedirect = false,\n}: SafeFetchWrapOptions<C> = {}) {\n return pipe(\n /**\n * Require explicit {@link RequestInit['redirect']} mode\n */\n allowImplicitRedirect ? asRequest : explicitRedirectCheckRequestTransform(),\n\n /**\n * Only requests that will be issued with a \"Host\" header are allowed.\n */\n allowIpHost ? asRequest : requireHostHeaderTransform(),\n\n /**\n * Prevent using http:, file: or data: protocols.\n */\n protocolCheckRequestTransform({\n 'about:': false,\n 'data:': allowData,\n 'file:': false,\n 'http:': allowHttp && { allowCustomPort },\n 'https:': { allowCustomPort },\n }),\n\n /**\n * Disallow fetching from domains we know are not atproto/OIDC client\n * implementation. Note that other domains can be blocked by providing a\n * custom fetch function combined with another\n * forbiddenDomainNameRequestTransform.\n */\n forbiddenDomainNameRequestTransform(forbiddenDomainNames),\n\n /**\n * Since we will be fetching from the network based on user provided\n * input, let's mitigate resource exhaustion attacks by setting a timeout.\n */\n timedFetch(\n timeout,\n\n /**\n * Since we will be fetching from the network based on user provided\n * input, we need to make sure that the request is not vulnerable to SSRF\n * attacks.\n */\n allowPrivateIps ? fetch : unicastFetchWrap({ fetch }),\n ),\n\n /**\n * Since we will be fetching user owned data, we need to make sure that an\n * attacker cannot force us to download a large amounts of data.\n */\n fetchMaxSizeProcessor(responseMaxSize),\n ) satisfies Fetch<unknown>\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atproto-labs/fetch-node",
3
- "version": "0.3.0-next.0",
3
+ "version": "0.3.1",
4
4
  "license": "MIT",
5
5
  "description": "SSRF protection for fetch() in Node.js",
6
6
  "keywords": [
@@ -27,13 +27,11 @@
27
27
  "dependencies": {
28
28
  "ipaddr.js": "^2.1.0",
29
29
  "undici": "^6.14.1",
30
- "@atproto-labs/pipe": "^0.2.0-next.0",
31
- "@atproto-labs/fetch": "^0.3.0-next.0"
32
- },
33
- "devDependencies": {
34
- "typescript": "^6.0.3"
30
+ "@atproto-labs/fetch": "^0.3.1",
31
+ "@atproto-labs/pipe": "^0.2.1"
35
32
  },
33
+ "devDependencies": {},
36
34
  "scripts": {
37
- "build": "tsc --build tsconfig.json"
35
+ "build": "tsgo --build tsconfig.json"
38
36
  }
39
37
  }
@@ -2,7 +2,7 @@
2
2
  "extends": ["../../../tsconfig/node.json"],
3
3
  "compilerOptions": {
4
4
  "outDir": "dist",
5
- "rootDir": "src"
5
+ "rootDir": "src",
6
6
  },
7
- "include": ["src"]
7
+ "include": ["src"],
8
8
  }
@@ -1 +1 @@
1
- {"root":["./src/index.ts","./src/safe.ts","./src/unicast.ts","./src/util.ts"],"version":"6.0.3"}
1
+ {"version":"7.0.0-dev.20260614.1","root":["./src/index.ts","./src/safe.ts","./src/unicast.ts","./src/util.ts"]}
package/tsconfig.json CHANGED
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "include": [],
3
- "references": [{ "path": "./tsconfig.build.json" }]
3
+ "references": [{ "path": "./tsconfig.build.json" }],
4
4
  }