@alexfalconflores/safe-fetch 1.0.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.
- package/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/index.d.mts +53 -0
- package/dist/index.js +110 -0
- package/dist/index.mjs +87 -0
- package/logo.svg +6 -0
- package/package.json +41 -0
- package/src/index.ts +277 -0
- package/step.md +4 -0
- package/tsconfig.json +33 -0
- package/tsup.config.ts +10 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [1.0.0] - 2025-04-20
|
|
4
|
+
|
|
5
|
+
### 🛡️ The Journey Begins: safeFetch Rises
|
|
6
|
+
|
|
7
|
+
- First stable release of `safeFetch`.
|
|
8
|
+
- Introduces a safer and more expressive wrapper around the native `fetch` API.
|
|
9
|
+
- Full typing for `HeadersType`, `HttpMethod`, `ContentType`, `AuthorizationType`, and other common HTTP headers.
|
|
10
|
+
- Support for:
|
|
11
|
+
- Fully Promise-based, designed for async/await flow.
|
|
12
|
+
- Automatic `body` serialization in JSON format if `Content-Type` is `application/json`.
|
|
13
|
+
- `RequestInitExt` extension that overrides the original type `headers` to use a custom, typed one.
|
|
14
|
+
- `toHeaders()` function:
|
|
15
|
+
- Converts flat objects to valid `Headers`, ignoring undefined values.
|
|
16
|
+
- `Join(separator, ...args)` function:
|
|
17
|
+
- Auxiliary utility to concatenate strings/numbers or arrays of these.
|
|
18
|
+
- Types Added
|
|
19
|
+
- `HttpMethod`: Type support for all standard and custom HTTP methods.
|
|
20
|
+
- `ContentType`, `AcceptType`, `AuthorizationType`, `CacheControlType`, `UserAgentType`, among other common headers.
|
|
21
|
+
- `HeadersType`: Extensible object with validations for the most common HTTP request headers.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Alex Stefano Falcon Flores
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
safeFetch
|
|
3
|
+
<br />
|
|
4
|
+
<img src="https://github.com/alexfalconflores/safe-fetch/blob/4fd0a9af158b69fa3bab5861ce13c552203845d9/logo.svg" alt="safeFetch logo" width="150"/>
|
|
5
|
+
</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong><code>safeFetch</code> is a typed enhancement to the JavaScript <code>fetch</code> method.</strong><br />
|
|
9
|
+
This function is designed to facilitate the sending of HTTP requests with greater security and typed control over headers, including automatic handling of the body if <code>Content-Type: application/json</code> is specified.
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 🚀 Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @alexfalconflores/safe-fetch
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
✨ Features
|
|
21
|
+
|
|
22
|
+
- Auto-conversion from body to JSON if Content-Type: application/json is specified
|
|
23
|
+
- Strong typing for HTTP methods, headers and common network values
|
|
24
|
+
- Accepts extended and custom headers
|
|
25
|
+
- Supports standard fetch (can completely replace it)
|
|
26
|
+
|
|
27
|
+
## 📦 Examples of use
|
|
28
|
+
|
|
29
|
+
### ⚙️ Basic Example
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import safeFetch from "@alexfalconflores/safe-fetch";
|
|
33
|
+
|
|
34
|
+
const response = await safeFetch("/api/users", {
|
|
35
|
+
method: "POST",
|
|
36
|
+
headers: {
|
|
37
|
+
"Content-Type": "application/json",
|
|
38
|
+
Authorization: "Bearer abc123",
|
|
39
|
+
},
|
|
40
|
+
body: { name: "Alex", email: "alex@correo.com" },
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
const data = await response.json();
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### ⚙️ Advanced Example
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import safeFetch from "@alexfalconflores/safe-fetch";
|
|
50
|
+
|
|
51
|
+
const response = await safeFetch("/api/users", {
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: {
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
Accept: "application/json",
|
|
56
|
+
Authorization: "Bearer 123token",
|
|
57
|
+
"Cache-Control": "no-cache",
|
|
58
|
+
},
|
|
59
|
+
body: { name: "Alex", email: "alex@correo.com" },
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const data = await response.json();
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## 📦 API
|
|
66
|
+
|
|
67
|
+
`safeFetch(url: string, init?: RequestInitExt): Promise<Response>`
|
|
68
|
+
|
|
69
|
+
- `url`: Destination URL of the request.
|
|
70
|
+
- `init`: Optional object extending RequestInit, with typed headers.
|
|
71
|
+
|
|
72
|
+
## 🧩 Extended typing
|
|
73
|
+
|
|
74
|
+
- `RequestInitExt`
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
interface RequestInitExt extends Omit<RequestInit, "headers"> {
|
|
78
|
+
method?: HttpMethod;
|
|
79
|
+
headers?: HeadersType;
|
|
80
|
+
}
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
- `HttpMethod`
|
|
84
|
+
|
|
85
|
+
```ts
|
|
86
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | ...;
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- `HeadersType`
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
{
|
|
93
|
+
"Content-Type"?: ContentType;
|
|
94
|
+
Authorization?: AuthorizationType;
|
|
95
|
+
Accept?: AcceptType;
|
|
96
|
+
...
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Extendable types are included for:
|
|
101
|
+
|
|
102
|
+
- `AuthorizationType` (Bearer, Basic, ApiKey, etc.)
|
|
103
|
+
- `ContentType` (application/json, text/html, etc.)
|
|
104
|
+
- `AcceptType`
|
|
105
|
+
- `CacheControlType`
|
|
106
|
+
- `AcceptLanguageType`
|
|
107
|
+
- `UserAgentType`, y muchos más.
|
|
108
|
+
|
|
109
|
+
## 🛠️ Auxiliary function: `Join`
|
|
110
|
+
```ts
|
|
111
|
+
Join("-", "2025", "04", "19"); // "2025-04-19"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 🧩 Compatibility
|
|
115
|
+
Compatible with environments where fetch is available: modern browsers, Deno and Node.js (v18+ or with polyfill).
|
|
116
|
+
|
|
117
|
+
## 👤 Autor
|
|
118
|
+
|
|
119
|
+
Alex Stefano Falcon Flores
|
|
120
|
+
|
|
121
|
+
- 🐙 GitHub: [alexstefano](https://github.com/alexfalconflores)
|
|
122
|
+
- 💼 LinkedIn: [alexsfalconflores](https://www.linkedin.com/in/alexfalconflores/)
|
|
123
|
+
|
|
124
|
+
## 📄 License
|
|
125
|
+
|
|
126
|
+
This project is licensed under the MIT license. See the [LICENSE](./LICENSE) file for more details.
|
|
127
|
+
|
|
128
|
+
## ⭐ Do you like it?
|
|
129
|
+
|
|
130
|
+
Give the repo a star to support the project!
|
|
131
|
+
And if you use it in your projects, I'd love to see it! 🎉
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
declare function safeFetch(url: string, init?: RequestInitExt): Promise<Response>;
|
|
2
|
+
|
|
3
|
+
interface RequestInitExt extends Omit<RequestInit, "headers"> {
|
|
4
|
+
method?: HttpMethod;
|
|
5
|
+
headers?: HeadersType;
|
|
6
|
+
}
|
|
7
|
+
declare function Join(separator?: string, ...args: (string | number | (string | number)[])[]): string;
|
|
8
|
+
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "OPTIONS" | "HEAD" | "CONNECT" | (string & {});
|
|
9
|
+
type ContentType = "application/json" | "application/xml" | "application/x-www-form-urlencoded" | "multipart/form-data" | "text/plain" | "text/html" | "text/css" | "text/javascript" | "text/xml" | "image/png" | "image/jpeg" | "image/gif" | "image/webp" | "audio/mpeg" | "audio/wav" | "video/mp4" | "application/pdf" | "application/msword" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/octet-stream" | "application/javascript" | "application/graphql" | "application/yaml" | "application/zip" | (string & {});
|
|
10
|
+
type AuthorizationType = `Bearer ${string}` | `Basic ${string}` | `Digest ${string}` | `ApiKey ${string}` | `OAuth oauth_consumer_key="${string}", oauth_token="${string}", oauth_signature="${string}"` | `Hawk id="${string}", ts="${string}", nonce="${string}", mac="${string}"` | `AWS4-HMAC-SHA256 Credential=${string}, SignedHeaders=${string}, Signature=${string}` | (string & {});
|
|
11
|
+
type AcceptType = "application/json" | "application/xml" | "text/html" | "text/plain" | "text/css" | "text/javascript" | "image/png" | "image/jpeg" | "image/gif" | "image/webp" | "audio/mpeg" | "audio/ogg" | "video/mp4" | "video/webm" | "multipart/form-data" | "application/x-www-form-urlencoded" | "application/pdf" | "application/vnd.ms-excel" | "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | "application/vnd.ms-powerpoint" | "application/vnd.openxmlformats-officedocument.presentationml.presentation" | "application/vnd.ms-word" | "application/vnd.openxmlformats-officedocument.wordprocessingml.document" | "*/*" | `${string}/${string}`;
|
|
12
|
+
type AcceptEncodingType = "gzip" | "compress" | "deflate" | "br" | "identity" | "*" | `${string}`;
|
|
13
|
+
type AcceptLanguageType = "en" | "en-US" | "en-GB" | "es" | "es-ES" | "es-MX" | "fr" | "fr-FR" | "de" | "de-DE" | "it" | "it-IT" | "ja" | "ja-JP" | "zh" | "zh-CN" | "zh-TW" | "ru" | "ru-RU" | "*" | `${string}`;
|
|
14
|
+
type CacheControlType = "no-cache" | "no-store" | "must-revalidate" | "public" | "private" | "max-age=0" | `max-age=${number}` | `s-maxage=${number}` | "proxy-revalidate" | "immutable" | "stale-while-revalidate" | "stale-if-error" | `${string}`;
|
|
15
|
+
type ContentEncodingType = "gzip" | "compress" | "deflate" | "br" | "identity" | "zstd" | `${string}`;
|
|
16
|
+
type ContentLanguageType = "en" | "es" | "fr" | "de" | "it" | "pt" | "zh" | "ja" | "ko" | "ru" | "ar" | "hi" | "nl" | "sv" | "no" | "da" | "fi" | "pl" | "tr" | "cs" | "el" | "he" | "vi" | "th" | "id" | "ms" | string;
|
|
17
|
+
type ETagType = `W/"${string}"` | `"${string}"` | string;
|
|
18
|
+
type HostType = `${string}.${string}` | `${string}.${string}:${number}` | string;
|
|
19
|
+
type OriginType = `${"http" | "https"}://${string}.${string}` | `${"http" | "https"}://${string}.${string}:${number}`;
|
|
20
|
+
type RefererType = `${"http" | "https"}://${string}`;
|
|
21
|
+
type UserAgentType = `Mozilla/5.0 (${string}) AppleWebKit/${string} (KHTML, like Gecko) ${string}` | `curl/${string}` | `PostmanRuntime/${string}` | `okhttp/${string}` | string;
|
|
22
|
+
type AccessControlAllowOriginType = "*" | "null" | `${string}`;
|
|
23
|
+
type AccessControlAllowMethodsType = "*" | HttpMethod | `${HttpMethod}, ${HttpMethod}` | `${HttpMethod}, ${HttpMethod}, ${HttpMethod}` | `${HttpMethod}, ${HttpMethod}, ${HttpMethod}, ${HttpMethod}` | `${HttpMethod}, ${HttpMethod}, ${HttpMethod}, ${HttpMethod}, ${HttpMethod}` | string;
|
|
24
|
+
type AccessControlAllowHeadersType = string;
|
|
25
|
+
type HeadersType = {
|
|
26
|
+
"Content-Type"?: ContentType;
|
|
27
|
+
Authorization?: AuthorizationType;
|
|
28
|
+
Accept?: AcceptType;
|
|
29
|
+
"Accept-Encoding"?: AcceptEncodingType;
|
|
30
|
+
"Accept-Language"?: AcceptLanguageType;
|
|
31
|
+
"Cache-Control"?: CacheControlType;
|
|
32
|
+
Connection?: "keep-alive" | "close";
|
|
33
|
+
"Content-Length"?: `${number}`;
|
|
34
|
+
"Content-Encoding"?: ContentEncodingType;
|
|
35
|
+
"Content-Language"?: ContentLanguageType;
|
|
36
|
+
"Content-Disposition"?: string;
|
|
37
|
+
ETag?: ETagType;
|
|
38
|
+
Host?: HostType;
|
|
39
|
+
Origin?: OriginType;
|
|
40
|
+
Referer?: RefererType;
|
|
41
|
+
"User-Agent"?: UserAgentType;
|
|
42
|
+
"Access-Control-Allow-Origin"?: AccessControlAllowOriginType;
|
|
43
|
+
"Access-Control-Allow-Methods"?: AccessControlAllowMethodsType;
|
|
44
|
+
"Access-Control-Allow-Headers"?: AccessControlAllowHeadersType;
|
|
45
|
+
"X-Frame-Options"?: "DENY" | "SAMEORIGIN";
|
|
46
|
+
"X-XSS-Protection"?: "0" | "1; mode=block";
|
|
47
|
+
"X-Content-Type-Options"?: "nosniff";
|
|
48
|
+
"Content-Security-Policy"?: string;
|
|
49
|
+
"Strict-Transport-Security"?: string;
|
|
50
|
+
[key: string]: string | undefined;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export { type AcceptEncodingType, type AcceptLanguageType, type AcceptType, type AccessControlAllowHeadersType, type AccessControlAllowMethodsType, type AccessControlAllowOriginType, type AuthorizationType, type CacheControlType, type ContentEncodingType, type ContentLanguageType, type ContentType, type ETagType, type HeadersType, type HostType, type HttpMethod, Join, type OriginType, type RefererType, type RequestInitExt, type UserAgentType, safeFetch as default, safeFetch };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __objRest = (source, exclude) => {
|
|
21
|
+
var target = {};
|
|
22
|
+
for (var prop in source)
|
|
23
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
+
target[prop] = source[prop];
|
|
25
|
+
if (source != null && __getOwnPropSymbols)
|
|
26
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
};
|
|
32
|
+
var __export = (target, all) => {
|
|
33
|
+
for (var name in all)
|
|
34
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
35
|
+
};
|
|
36
|
+
var __copyProps = (to, from, except, desc) => {
|
|
37
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
38
|
+
for (let key of __getOwnPropNames(from))
|
|
39
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
40
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
41
|
+
}
|
|
42
|
+
return to;
|
|
43
|
+
};
|
|
44
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
45
|
+
var __async = (__this, __arguments, generator) => {
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
var fulfilled = (value) => {
|
|
48
|
+
try {
|
|
49
|
+
step(generator.next(value));
|
|
50
|
+
} catch (e) {
|
|
51
|
+
reject(e);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
var rejected = (value) => {
|
|
55
|
+
try {
|
|
56
|
+
step(generator.throw(value));
|
|
57
|
+
} catch (e) {
|
|
58
|
+
reject(e);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
62
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
// src/index.ts
|
|
67
|
+
var index_exports = {};
|
|
68
|
+
__export(index_exports, {
|
|
69
|
+
Join: () => Join,
|
|
70
|
+
default: () => index_default,
|
|
71
|
+
safeFetch: () => safeFetch
|
|
72
|
+
});
|
|
73
|
+
module.exports = __toCommonJS(index_exports);
|
|
74
|
+
function safeFetch(url, init) {
|
|
75
|
+
return __async(this, null, function* () {
|
|
76
|
+
const _a = init || {}, { method = "GET", headers, body } = _a, props = __objRest(_a, ["method", "headers", "body"]);
|
|
77
|
+
const contentTypeJson = "application/json";
|
|
78
|
+
let newBody = body;
|
|
79
|
+
if (body && typeof body === "object" && (headers == null ? void 0 : headers["Content-Type"]) === contentTypeJson) {
|
|
80
|
+
newBody = JSON.stringify(body);
|
|
81
|
+
}
|
|
82
|
+
const response = yield fetch(url, __spreadValues({
|
|
83
|
+
method,
|
|
84
|
+
headers: toHeaders(__spreadValues({}, headers)),
|
|
85
|
+
body: newBody
|
|
86
|
+
}, props));
|
|
87
|
+
return response;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
var index_default = safeFetch;
|
|
91
|
+
function Join(separator = "", ...args) {
|
|
92
|
+
return args.flat().join(separator);
|
|
93
|
+
}
|
|
94
|
+
var toHeaders = (headers) => {
|
|
95
|
+
if (headers instanceof Headers) return headers;
|
|
96
|
+
return new Headers(
|
|
97
|
+
Object.entries(headers).reduce((acc, [key, value]) => {
|
|
98
|
+
if (value !== void 0) {
|
|
99
|
+
acc.push([key, String(value)]);
|
|
100
|
+
}
|
|
101
|
+
return acc;
|
|
102
|
+
}, [])
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
106
|
+
0 && (module.exports = {
|
|
107
|
+
Join,
|
|
108
|
+
safeFetch
|
|
109
|
+
});
|
|
110
|
+
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
5
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
6
|
+
var __spreadValues = (a, b) => {
|
|
7
|
+
for (var prop in b || (b = {}))
|
|
8
|
+
if (__hasOwnProp.call(b, prop))
|
|
9
|
+
__defNormalProp(a, prop, b[prop]);
|
|
10
|
+
if (__getOwnPropSymbols)
|
|
11
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
12
|
+
if (__propIsEnum.call(b, prop))
|
|
13
|
+
__defNormalProp(a, prop, b[prop]);
|
|
14
|
+
}
|
|
15
|
+
return a;
|
|
16
|
+
};
|
|
17
|
+
var __objRest = (source, exclude) => {
|
|
18
|
+
var target = {};
|
|
19
|
+
for (var prop in source)
|
|
20
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
21
|
+
target[prop] = source[prop];
|
|
22
|
+
if (source != null && __getOwnPropSymbols)
|
|
23
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
24
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
25
|
+
target[prop] = source[prop];
|
|
26
|
+
}
|
|
27
|
+
return target;
|
|
28
|
+
};
|
|
29
|
+
var __async = (__this, __arguments, generator) => {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
var fulfilled = (value) => {
|
|
32
|
+
try {
|
|
33
|
+
step(generator.next(value));
|
|
34
|
+
} catch (e) {
|
|
35
|
+
reject(e);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
var rejected = (value) => {
|
|
39
|
+
try {
|
|
40
|
+
step(generator.throw(value));
|
|
41
|
+
} catch (e) {
|
|
42
|
+
reject(e);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
46
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/index.ts
|
|
51
|
+
function safeFetch(url, init) {
|
|
52
|
+
return __async(this, null, function* () {
|
|
53
|
+
const _a = init || {}, { method = "GET", headers, body } = _a, props = __objRest(_a, ["method", "headers", "body"]);
|
|
54
|
+
const contentTypeJson = "application/json";
|
|
55
|
+
let newBody = body;
|
|
56
|
+
if (body && typeof body === "object" && (headers == null ? void 0 : headers["Content-Type"]) === contentTypeJson) {
|
|
57
|
+
newBody = JSON.stringify(body);
|
|
58
|
+
}
|
|
59
|
+
const response = yield fetch(url, __spreadValues({
|
|
60
|
+
method,
|
|
61
|
+
headers: toHeaders(__spreadValues({}, headers)),
|
|
62
|
+
body: newBody
|
|
63
|
+
}, props));
|
|
64
|
+
return response;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
var index_default = safeFetch;
|
|
68
|
+
function Join(separator = "", ...args) {
|
|
69
|
+
return args.flat().join(separator);
|
|
70
|
+
}
|
|
71
|
+
var toHeaders = (headers) => {
|
|
72
|
+
if (headers instanceof Headers) return headers;
|
|
73
|
+
return new Headers(
|
|
74
|
+
Object.entries(headers).reduce((acc, [key, value]) => {
|
|
75
|
+
if (value !== void 0) {
|
|
76
|
+
acc.push([key, String(value)]);
|
|
77
|
+
}
|
|
78
|
+
return acc;
|
|
79
|
+
}, [])
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
export {
|
|
83
|
+
Join,
|
|
84
|
+
index_default as default,
|
|
85
|
+
safeFetch
|
|
86
|
+
};
|
|
87
|
+
//# sourceMappingURL=index.mjs.map
|
package/logo.svg
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path d="M3 13C3 11.3431 4.34315 10 6 10H8L9.5 9L10.5 10H17.5L19 9L20 10H22C23.6569 10 25 11.3431 25 13V26C25 27.6569 23.6569 29 22 29H6C4.34315 29 3 27.6569 3 26V13Z" fill="#F9C23C"/>
|
|
3
|
+
<path d="M15.5 19.5002C16.1072 19.0441 16.5 18.3179 16.5 17.5C16.5 16.1193 15.3807 15 14 15C12.6193 15 11.5 16.1193 11.5 17.5C11.5 18.3179 11.8928 19.0441 12.5 19.5002V23C12.5 23.8284 13.1716 24.5 14 24.5C14.8284 24.5 15.5 23.8284 15.5 23V19.5002Z" fill="#433B6B"/>
|
|
4
|
+
<path d="M14 1C10.6863 1 8 3.68629 8 7V10H10.5V7C10.5 5.067 12.067 3.5 14 3.5C15.933 3.5 17.5 5.067 17.5 7V10H20V7C20 3.68629 17.3137 1 14 1Z" fill="#D3D3D3"/>
|
|
5
|
+
<path d="M30 9.5C30 11.4593 28.7478 13.1262 27 13.7439V22.5C27 23.3284 26.3284 24 25.5 24C24.6716 24 24 23.3284 24 22.5L24 20.7458C24 20.5458 24.0785 20.3558 24.2157 20.2258L24.5294 19.9158C24.8236 19.6258 24.8236 19.1558 24.5294 18.8758C24.2353 18.5958 24.2353 18.1258 24.5294 17.8458C24.8236 17.5558 24.8236 17.0858 24.5294 16.8058L24.2157 16.4958C24.0785 16.3558 24 16.1758 24 15.9758L24 13.7439C22.2522 13.1262 21 11.4593 21 9.5C21 7.01472 23.0147 5 25.5 5C27.9853 5 30 7.01472 30 9.5ZM25.5 8C26.0523 8 26.5 7.55228 26.5 7C26.5 6.44772 26.0523 6 25.5 6C24.9477 6 24.5 6.44772 24.5 7C24.5 7.55228 24.9477 8 25.5 8Z" fill="#D3D3D3"/>
|
|
6
|
+
</svg>
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@alexfalconflores/safe-fetch",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A safe and customizable fetch wrapper for secure HTTP requests.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
"import": "./dist/index.mjs",
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "git+https://github.com/alexfalconflores/safe-fetch.git"
|
|
16
|
+
},
|
|
17
|
+
"bugs": {
|
|
18
|
+
"url": "https://github.com/alexfalconflores/safe-fetch/issues"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://github.com/alexfalconflores/safe-fetch#readme",
|
|
21
|
+
"keywords": [
|
|
22
|
+
"fetch",
|
|
23
|
+
"http",
|
|
24
|
+
"secure",
|
|
25
|
+
"api",
|
|
26
|
+
"http-client",
|
|
27
|
+
"request-wrapper"
|
|
28
|
+
],
|
|
29
|
+
"author": "Alex Stefano Falcon Flores",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"dev": "tsup src/index.ts --watch --dts",
|
|
34
|
+
"clean": "rm -rf dist",
|
|
35
|
+
"publish": "npm publish --access public"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"tsup": "^8.4.0",
|
|
39
|
+
"typescript": "^5.8.3"
|
|
40
|
+
}
|
|
41
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
export async function safeFetch(
|
|
2
|
+
url: string,
|
|
3
|
+
init?: RequestInitExt,
|
|
4
|
+
): Promise<Response> {
|
|
5
|
+
const { method = "GET", headers, body, ...props } = init || {};
|
|
6
|
+
const contentTypeJson: ContentType = "application/json";
|
|
7
|
+
let newBody = body;
|
|
8
|
+
if (
|
|
9
|
+
body &&
|
|
10
|
+
typeof body === "object" &&
|
|
11
|
+
headers?.["Content-Type"] === contentTypeJson
|
|
12
|
+
) {
|
|
13
|
+
newBody = JSON.stringify(body);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const response = await fetch(url, {
|
|
17
|
+
method,
|
|
18
|
+
headers: toHeaders({
|
|
19
|
+
...headers,
|
|
20
|
+
}),
|
|
21
|
+
body: newBody,
|
|
22
|
+
...props,
|
|
23
|
+
});
|
|
24
|
+
return response;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default safeFetch;
|
|
28
|
+
|
|
29
|
+
export interface RequestInitExt extends Omit<RequestInit, "headers"> {
|
|
30
|
+
method?: HttpMethod;
|
|
31
|
+
headers?: HeadersType;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function Join(
|
|
35
|
+
separator: string = "",
|
|
36
|
+
...args: (string | number | (string | number)[])[]
|
|
37
|
+
): string {
|
|
38
|
+
return args.flat().join(separator);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const toHeaders = (headers: HeadersType | Headers): Headers => {
|
|
42
|
+
if (headers instanceof Headers) return headers;
|
|
43
|
+
return new Headers(
|
|
44
|
+
Object.entries(headers).reduce<[string, string][]>((acc, [key, value]) => {
|
|
45
|
+
if (value !== undefined) {
|
|
46
|
+
acc.push([key, String(value)]);
|
|
47
|
+
}
|
|
48
|
+
return acc;
|
|
49
|
+
}, []),
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export type HttpMethod =
|
|
54
|
+
| "GET"
|
|
55
|
+
| "POST"
|
|
56
|
+
| "PUT"
|
|
57
|
+
| "DELETE"
|
|
58
|
+
| "PATCH"
|
|
59
|
+
| "OPTIONS"
|
|
60
|
+
| "HEAD"
|
|
61
|
+
| "CONNECT"
|
|
62
|
+
| (string & {});
|
|
63
|
+
|
|
64
|
+
export type ContentType =
|
|
65
|
+
| "application/json"
|
|
66
|
+
| "application/xml"
|
|
67
|
+
| "application/x-www-form-urlencoded"
|
|
68
|
+
| "multipart/form-data"
|
|
69
|
+
| "text/plain"
|
|
70
|
+
| "text/html"
|
|
71
|
+
| "text/css"
|
|
72
|
+
| "text/javascript"
|
|
73
|
+
| "text/xml"
|
|
74
|
+
| "image/png"
|
|
75
|
+
| "image/jpeg"
|
|
76
|
+
| "image/gif"
|
|
77
|
+
| "image/webp"
|
|
78
|
+
| "audio/mpeg"
|
|
79
|
+
| "audio/wav"
|
|
80
|
+
| "video/mp4"
|
|
81
|
+
| "application/pdf"
|
|
82
|
+
| "application/msword"
|
|
83
|
+
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
84
|
+
| "application/vnd.ms-excel"
|
|
85
|
+
| "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
86
|
+
| "application/octet-stream"
|
|
87
|
+
| "application/javascript"
|
|
88
|
+
| "application/graphql"
|
|
89
|
+
| "application/yaml"
|
|
90
|
+
| "application/zip"
|
|
91
|
+
| (string & {});
|
|
92
|
+
|
|
93
|
+
export type AuthorizationType =
|
|
94
|
+
| `Bearer ${string}` // OAuth 2.0, JWT
|
|
95
|
+
| `Basic ${string}` // Usuario:Contraseña en base64
|
|
96
|
+
| `Digest ${string}` // Digest Auth con hash
|
|
97
|
+
| `ApiKey ${string}` // Clave de API
|
|
98
|
+
| `OAuth oauth_consumer_key="${string}", oauth_token="${string}", oauth_signature="${string}"` // OAuth 1.0
|
|
99
|
+
| `Hawk id="${string}", ts="${string}", nonce="${string}", mac="${string}"` // Hawk Auth
|
|
100
|
+
| `AWS4-HMAC-SHA256 Credential=${string}, SignedHeaders=${string}, Signature=${string}` // AWS Signature
|
|
101
|
+
| (string & {});
|
|
102
|
+
|
|
103
|
+
export type AcceptType =
|
|
104
|
+
| "application/json"
|
|
105
|
+
| "application/xml"
|
|
106
|
+
| "text/html"
|
|
107
|
+
| "text/plain"
|
|
108
|
+
| "text/css"
|
|
109
|
+
| "text/javascript"
|
|
110
|
+
| "image/png"
|
|
111
|
+
| "image/jpeg"
|
|
112
|
+
| "image/gif"
|
|
113
|
+
| "image/webp"
|
|
114
|
+
| "audio/mpeg"
|
|
115
|
+
| "audio/ogg"
|
|
116
|
+
| "video/mp4"
|
|
117
|
+
| "video/webm"
|
|
118
|
+
| "multipart/form-data"
|
|
119
|
+
| "application/x-www-form-urlencoded"
|
|
120
|
+
| "application/pdf"
|
|
121
|
+
| "application/vnd.ms-excel"
|
|
122
|
+
| "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
123
|
+
| "application/vnd.ms-powerpoint"
|
|
124
|
+
| "application/vnd.openxmlformats-officedocument.presentationml.presentation"
|
|
125
|
+
| "application/vnd.ms-word"
|
|
126
|
+
| "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
127
|
+
| "*/*" // Para aceptar cualquier tipo de contenido
|
|
128
|
+
| `${string}/${string}`; // Permite valores personalizados
|
|
129
|
+
|
|
130
|
+
export type AcceptEncodingType =
|
|
131
|
+
| "gzip"
|
|
132
|
+
| "compress"
|
|
133
|
+
| "deflate"
|
|
134
|
+
| "br" // Brotli, usado en HTTP/2
|
|
135
|
+
| "identity" // Sin compresión
|
|
136
|
+
| "*" // Aceptar cualquier codificación
|
|
137
|
+
| `${string}`; // Permite valores personalizados
|
|
138
|
+
|
|
139
|
+
export type AcceptLanguageType =
|
|
140
|
+
| "en" // Inglés
|
|
141
|
+
| "en-US"
|
|
142
|
+
| "en-GB"
|
|
143
|
+
| "es" // Español
|
|
144
|
+
| "es-ES"
|
|
145
|
+
| "es-MX"
|
|
146
|
+
| "fr" // Francés
|
|
147
|
+
| "fr-FR"
|
|
148
|
+
| "de" // Alemán
|
|
149
|
+
| "de-DE"
|
|
150
|
+
| "it" // Italiano
|
|
151
|
+
| "it-IT"
|
|
152
|
+
| "ja" // Japonés
|
|
153
|
+
| "ja-JP"
|
|
154
|
+
| "zh" // Chino
|
|
155
|
+
| "zh-CN"
|
|
156
|
+
| "zh-TW"
|
|
157
|
+
| "ru" // Ruso
|
|
158
|
+
| "ru-RU"
|
|
159
|
+
| "*" // Aceptar cualquier idioma
|
|
160
|
+
| `${string}`; // Permite valores personalizados como "pt-BR", "ar-SA", etc.
|
|
161
|
+
|
|
162
|
+
export type CacheControlType =
|
|
163
|
+
| "no-cache" // Siempre debe validar en el servidor antes de usar la caché
|
|
164
|
+
| "no-store" // No almacenar en caché ni en el cliente ni en el servidor
|
|
165
|
+
| "must-revalidate" // Debe validar en el servidor antes de usar la caché
|
|
166
|
+
| "public" // Puede ser almacenado en cualquier caché intermedia
|
|
167
|
+
| "private" // Solo puede ser almacenado en la caché del cliente
|
|
168
|
+
| "max-age=0" // La respuesta es inmediatamente obsoleta
|
|
169
|
+
| `max-age=${number}` // Se puede usar hasta cierto número de segundos
|
|
170
|
+
| `s-maxage=${number}` // Similar a `max-age`, pero solo para cachés compartidas (CDN)
|
|
171
|
+
| "proxy-revalidate" // Similar a `must-revalidate`, pero para proxies
|
|
172
|
+
| "immutable" // Indica que la respuesta nunca cambiará (ideal para archivos estáticos)
|
|
173
|
+
| "stale-while-revalidate" // Permite servir una respuesta caducada mientras se obtiene una nueva en segundo plano
|
|
174
|
+
| "stale-if-error" // Permite servir una respuesta caducada si hay un error en la solicitud
|
|
175
|
+
| `${string}`; // Permite valores personalizados.
|
|
176
|
+
|
|
177
|
+
export type ContentEncodingType =
|
|
178
|
+
| "gzip"
|
|
179
|
+
| "compress"
|
|
180
|
+
| "deflate"
|
|
181
|
+
| "br"
|
|
182
|
+
| "identity"
|
|
183
|
+
| "zstd"
|
|
184
|
+
| `${string}`; // Nuevo estándar para compresión
|
|
185
|
+
|
|
186
|
+
export type ContentLanguageType =
|
|
187
|
+
| "en" // Inglés
|
|
188
|
+
| "es" // Español
|
|
189
|
+
| "fr" // Francés
|
|
190
|
+
| "de" // Alemán
|
|
191
|
+
| "it" // Italiano
|
|
192
|
+
| "pt" // Portugués
|
|
193
|
+
| "zh" // Chino
|
|
194
|
+
| "ja" // Japonés
|
|
195
|
+
| "ko" // Coreano
|
|
196
|
+
| "ru" // Ruso
|
|
197
|
+
| "ar" // Árabe
|
|
198
|
+
| "hi" // Hindi
|
|
199
|
+
| "nl" // Neerlandés
|
|
200
|
+
| "sv" // Sueco
|
|
201
|
+
| "no" // Noruego
|
|
202
|
+
| "da" // Danés
|
|
203
|
+
| "fi" // Finés
|
|
204
|
+
| "pl" // Polaco
|
|
205
|
+
| "tr" // Turco
|
|
206
|
+
| "cs" // Checo
|
|
207
|
+
| "el" // Griego
|
|
208
|
+
| "he" // Hebreo
|
|
209
|
+
| "vi" // Vietnamita
|
|
210
|
+
| "th" // Tailandés
|
|
211
|
+
| "id" // Indonesio
|
|
212
|
+
| "ms" // Malayo
|
|
213
|
+
| string; // Permite otros idiomas personalizados
|
|
214
|
+
|
|
215
|
+
export type ETagType =
|
|
216
|
+
| `W/"${string}"` // Weak ETag (ejemplo: W/"123456")
|
|
217
|
+
| `"${string}"` // Strong ETag (ejemplo: "abcdef")
|
|
218
|
+
| string; // Permitir otros valores dinámicos
|
|
219
|
+
|
|
220
|
+
export type HostType =
|
|
221
|
+
| `${string}.${string}`
|
|
222
|
+
| `${string}.${string}:${number}`
|
|
223
|
+
| string;
|
|
224
|
+
|
|
225
|
+
export type OriginType =
|
|
226
|
+
| `${"http" | "https"}://${string}.${string}`
|
|
227
|
+
| `${"http" | "https"}://${string}.${string}:${number}`;
|
|
228
|
+
|
|
229
|
+
export type RefererType = `${"http" | "https"}://${string}`;
|
|
230
|
+
|
|
231
|
+
export type UserAgentType =
|
|
232
|
+
| `Mozilla/5.0 (${string}) AppleWebKit/${string} (KHTML, like Gecko) ${string}`
|
|
233
|
+
| `curl/${string}`
|
|
234
|
+
| `PostmanRuntime/${string}`
|
|
235
|
+
| `okhttp/${string}`
|
|
236
|
+
| string; // Para permitir valores personalizados
|
|
237
|
+
|
|
238
|
+
export type AccessControlAllowOriginType = "*" | "null" | `${string}`;
|
|
239
|
+
|
|
240
|
+
export type AccessControlAllowMethodsType =
|
|
241
|
+
| "*"
|
|
242
|
+
| HttpMethod
|
|
243
|
+
| `${HttpMethod}, ${HttpMethod}`
|
|
244
|
+
| `${HttpMethod}, ${HttpMethod}, ${HttpMethod}`
|
|
245
|
+
| `${HttpMethod}, ${HttpMethod}, ${HttpMethod}, ${HttpMethod}`
|
|
246
|
+
| `${HttpMethod}, ${HttpMethod}, ${HttpMethod}, ${HttpMethod}, ${HttpMethod}`
|
|
247
|
+
| string; // Permite cualquier combinación personalizada
|
|
248
|
+
|
|
249
|
+
export type AccessControlAllowHeadersType = string; // Mantiene la flexibilidad y evita el error
|
|
250
|
+
|
|
251
|
+
export type HeadersType = {
|
|
252
|
+
"Content-Type"?: ContentType;
|
|
253
|
+
Authorization?: AuthorizationType;
|
|
254
|
+
Accept?: AcceptType; // Tipos de contenido aceptados
|
|
255
|
+
"Accept-Encoding"?: AcceptEncodingType; // Métodos de compresión aceptados (gzip, br)
|
|
256
|
+
"Accept-Language"?: AcceptLanguageType; // Idiomas aceptados (es-ES, en-US)
|
|
257
|
+
"Cache-Control"?: CacheControlType; // Control de caché (no-cache, max-age=3600)
|
|
258
|
+
Connection?: "keep-alive" | "close";
|
|
259
|
+
"Content-Length"?: `${number}`; // Tamaño del cuerpo en bytes
|
|
260
|
+
"Content-Encoding"?: ContentEncodingType; // Método de codificación (gzip, deflate, br)
|
|
261
|
+
"Content-Language"?: ContentLanguageType; // Idioma del contenido (es, en, fr)
|
|
262
|
+
"Content-Disposition"?: string; // Manejo del contenido (attachment; filename="file.pdf")
|
|
263
|
+
ETag?: ETagType; // Identificador único para cacheo de recursos
|
|
264
|
+
Host?: HostType; // Nombre del servidor al que se envía la solicitud
|
|
265
|
+
Origin?: OriginType; // Origen de la solicitud (https://example.com)
|
|
266
|
+
Referer?: RefererType; // URL de referencia
|
|
267
|
+
"User-Agent"?: UserAgentType; // Información del navegador o cliente
|
|
268
|
+
"Access-Control-Allow-Origin"?: AccessControlAllowOriginType; // Permitir acceso desde ciertos dominios (*, https://example.com)
|
|
269
|
+
"Access-Control-Allow-Methods"?: AccessControlAllowMethodsType; // Métodos permitidos (GET, POST, PUT)
|
|
270
|
+
"Access-Control-Allow-Headers"?: AccessControlAllowHeadersType; // Headers permitidos en la solicitud
|
|
271
|
+
"X-Frame-Options"?: "DENY" | "SAMEORIGIN"; // Protección contra Clickjacking
|
|
272
|
+
"X-XSS-Protection"?: "0" | "1; mode=block"; // Protección contra ataques XSS
|
|
273
|
+
"X-Content-Type-Options"?: "nosniff"; // Evita detección automática de MIME
|
|
274
|
+
"Content-Security-Policy"?: string; // Política de seguridad del contenido
|
|
275
|
+
"Strict-Transport-Security"?: string; // Fuerza el uso de HTTPS
|
|
276
|
+
[key: string]: string | undefined;
|
|
277
|
+
};
|
package/step.md
ADDED
package/tsconfig.json
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2016" /* Compilación a JavaScript ES2016 */,
|
|
4
|
+
"lib": [
|
|
5
|
+
"ES2016",
|
|
6
|
+
"ESNext",
|
|
7
|
+
"DOM"
|
|
8
|
+
] /* Usa características de ES2016 y ESNext */,
|
|
9
|
+
"module": "NodeNext" /* Usa módulos Node16 para compatibilidad con Node.js 16 */,
|
|
10
|
+
"moduleResolution": "nodenext" /* Usa la resolución de módulos de Node.js v16 */,
|
|
11
|
+
"esModuleInterop": true /* Habilita interoperabilidad con módulos CommonJS */,
|
|
12
|
+
"skipLibCheck": true /* Omitir la verificación de los archivos de declaración */,
|
|
13
|
+
"forceConsistentCasingInFileNames": true /* Asegurar consistencia en las mayúsculas/minúsculas en los nombres de archivo */,
|
|
14
|
+
"strict": true /* Habilitar todas las opciones de verificación estricta */,
|
|
15
|
+
"resolveJsonModule": true /* Permite importar archivos JSON */,
|
|
16
|
+
"allowSyntheticDefaultImports": true /* Permite importar por defecto incluso si el módulo no tiene un export por defecto */,
|
|
17
|
+
"skipDefaultLibCheck": true /* Omitir la comprobación de la librería predeterminada */,
|
|
18
|
+
"outDir": "./dist" /* Directorio de salida para los archivos compilados */,
|
|
19
|
+
"declaration": true /* Generar archivos .d.ts */,
|
|
20
|
+
"declarationMap": true /* Generar mapas de declaración */,
|
|
21
|
+
"sourceMap": true /* Generar mapas fuente para depuración */,
|
|
22
|
+
"noEmit": false /* No evitar la generación de archivos de salida */,
|
|
23
|
+
"resolvePackageJsonExports": true /* Usa el campo `exports` en `package.json` cuando resuelvas importaciones */,
|
|
24
|
+
"paths": {
|
|
25
|
+
"safe-fetch": ["./node_modules/safe-fetch"]
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"include": ["src/**/*" /* Incluir todos los archivos en la carpeta src */],
|
|
29
|
+
"exclude": [
|
|
30
|
+
"node_modules" /* Excluir node_modules */,
|
|
31
|
+
"dist" /* Excluir el directorio de salida */
|
|
32
|
+
]
|
|
33
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
entry: ["src/index.ts"], // Cambia esto según la ubicación de tu archivo principal
|
|
5
|
+
format: ["esm", "cjs"], // Formatos de salida (ESM y CommonJS)
|
|
6
|
+
dts: true, // Genera los archivos de declaración .d.ts
|
|
7
|
+
sourcemap: true, // Genera mapas de origen
|
|
8
|
+
clean: true, // Limpia la carpeta de salida antes de generar
|
|
9
|
+
outDir: "dist", // Carpeta de salida
|
|
10
|
+
});
|