@sdxc/http 0.0.0-pre.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.
@@ -0,0 +1,171 @@
1
+ /**
2
+ * Response builders that pair a body with its matching Content-Type
3
+ * header, covering the common content kinds a server returns.
4
+ * @author [Sergio Xalambrí](https://sergiodxa.com)
5
+ * @copyright Sergio Xalambrí 2026
6
+ */
7
+ import { Location } from "@sdxc/location";
8
+ /**
9
+ * Creates a Response with JSON content.
10
+ * Uses the built-in Response.json() method for proper serialization.
11
+ * @param body - The value to serialize as JSON
12
+ * @param init - Optional response options (status, headers, etc.)
13
+ * @returns A new Response instance with JSON content
14
+ * @example
15
+ * return json({ success: true, data: [1, 2, 3] });
16
+ * @example
17
+ * return json({ error: "Not found" }, { status: 404 });
18
+ */
19
+ export declare function json<T>(body: T, init?: ResponseInit): Response;
20
+ /**
21
+ * Creates a Response with plain text content and appropriate Content-Type header.
22
+ * @param body - The text string to send
23
+ * @param init - Optional response options (status, headers, etc.)
24
+ * @returns A new Response instance with plain text content
25
+ * @example
26
+ * return text("Hello, World!");
27
+ * @example
28
+ * return text("Error occurred", { status: 500 });
29
+ */
30
+ export declare function text(body: string, init?: ResponseInit): Response;
31
+ /**
32
+ * Creates a Response with HTML content and appropriate Content-Type header.
33
+ * @param body - The HTML string to send
34
+ * @param init - Optional response options (status, headers, etc.)
35
+ * @returns A new Response instance with HTML content
36
+ * @example
37
+ * return html("<h1>Hello World</h1>");
38
+ * @example
39
+ * return html("<h1>Not Found</h1>", { status: 404 });
40
+ */
41
+ export declare function html(body: string, init?: ResponseInit): Response;
42
+ /**
43
+ * Creates a Response with CSS content and appropriate Content-Type header.
44
+ * @param body - The CSS string to send
45
+ * @param init - Optional response options (status, headers, etc.)
46
+ * @returns A new Response instance with CSS content
47
+ * @example
48
+ * return css("body { color: red; }");
49
+ * @example
50
+ * return css(".error { color: red; }", { headers: { "Cache-Control": "max-age=3600" } });
51
+ */
52
+ export declare function css(body: string, init?: ResponseInit): Response;
53
+ /**
54
+ * Creates a Response with JavaScript content and appropriate Content-Type header.
55
+ * @param body - The JavaScript string to send
56
+ * @param init - Optional response options (status, headers, etc.)
57
+ * @returns A new Response instance with JavaScript content
58
+ * @example
59
+ * return javascript("console.log('Hello');");
60
+ * @example
61
+ * return javascript("export default 42;", { headers: { "Cache-Control": "max-age=3600" } });
62
+ */
63
+ export declare function javascript(body: string, init?: ResponseInit): Response;
64
+ /**
65
+ * Creates a Response with XML content and appropriate Content-Type header.
66
+ * @param body - The XML string to send
67
+ * @param init - Optional response options (status, headers, etc.)
68
+ * @returns A new Response instance with XML content
69
+ * @example
70
+ * return xml("<root><item>Hello</item></root>");
71
+ * @example
72
+ * return xml("<error>Not found</error>", { status: 404 });
73
+ */
74
+ export declare function xml(body: string, init?: ResponseInit): Response;
75
+ /**
76
+ * Creates a Response with CSV content and appropriate Content-Type header.
77
+ * @param body - The CSV string to send
78
+ * @param init - Optional response options (status, headers, etc.)
79
+ * @returns A new Response instance with CSV content
80
+ * @example
81
+ * return csv("name,age\nJohn,30\nJane,25");
82
+ * @example
83
+ * return csv("id,value\n1,100", { headers: { "Content-Disposition": "attachment; filename=data.csv" } });
84
+ */
85
+ export declare function csv(body: string, init?: ResponseInit): Response;
86
+ /**
87
+ * Creates a Response with Markdown content and appropriate Content-Type header.
88
+ * @param body - The Markdown string to send
89
+ * @param init - Optional response options (status, headers, etc.)
90
+ * @returns A new Response instance with Markdown content
91
+ * @example
92
+ * return markdown("# Hello World\n\nThis is **bold** text.");
93
+ * @example
94
+ * return markdown("# Error\n\nPage not found.", { status: 404 });
95
+ */
96
+ export declare function markdown(body: string, init?: ResponseInit): Response;
97
+ /**
98
+ * Creates a Response with PDF content and appropriate Content-Type header.
99
+ * Accepts binary data in various formats for flexibility.
100
+ * @param body - The PDF content as Blob, ArrayBuffer, or ReadableStream
101
+ * @param init - Optional response options (status, headers, etc.)
102
+ * @returns A new Response instance with PDF content
103
+ * @example
104
+ * return pdf(pdfBuffer);
105
+ * @example
106
+ * return pdf(pdfBlob, { headers: { "Content-Disposition": "inline; filename=document.pdf" } });
107
+ */
108
+ export declare function pdf(body: Blob | ArrayBuffer | ReadableStream, init?: ResponseInit): Response;
109
+ /**
110
+ * Creates a Response for file downloads with Content-Disposition header.
111
+ * Sets appropriate headers to trigger browser download behavior.
112
+ * @param body - The file content as Blob, ArrayBuffer, or ReadableStream
113
+ * @param filename - The filename to suggest for the download
114
+ * @param init - Optional response options (status, headers, etc.)
115
+ * @returns A new Response instance configured for file download
116
+ * @example
117
+ * return file(zipBuffer, "archive.zip");
118
+ * @example
119
+ * return file(imageBlob, "photo.png", { headers: { "Cache-Control": "no-store" } });
120
+ */
121
+ export declare function file(body: Blob | ArrayBuffer | ReadableStream, filename: string, init?: ResponseInit): Response;
122
+ /**
123
+ * Creates a Response for Server-Sent Events (SSE) streaming.
124
+ * Sets appropriate headers for SSE including Cache-Control and Connection.
125
+ * @param body - The ReadableStream producing SSE events
126
+ * @param init - Optional response options (status, headers, etc.)
127
+ * @returns A new Response instance configured for SSE streaming
128
+ * @example
129
+ * return stream(new ReadableStream({ start(controller) { controller.enqueue("data: hello\n\n"); } }));
130
+ * @example
131
+ * return stream(eventStream, { headers: { "X-Custom-Header": "value" } });
132
+ */
133
+ export declare function stream(body: ReadableStream, init?: ResponseInit): Response;
134
+ /**
135
+ * Creates a 204 No Content response with no body.
136
+ * Used when an operation succeeds but has no content to return.
137
+ * @param init - Optional response options (headers, etc.) - status is always 204
138
+ * @returns A new Response instance with 204 status and no body
139
+ * @example
140
+ * return noContent();
141
+ * @example
142
+ * return noContent({ headers: { "X-Request-Id": "abc123" } });
143
+ */
144
+ export declare function noContent(init?: Omit<ResponseInit, "status" | "statusText">): Response;
145
+ /**
146
+ * Creates a redirect response to the specified target URL or Location.
147
+ * Validates the target and defaults to 307 Temporary Redirect status.
148
+ * @param target - The URL, Location, or string to redirect to
149
+ * @param init - Optional response options including redirect status
150
+ * @returns A new Response instance with redirect status and Location header
151
+ * @throws Error if the target is not a valid URL or Location
152
+ * @example
153
+ * return redirect("/dashboard");
154
+ * @example
155
+ * return redirect(new URL("https://example.com"), { status: redirect.Status.Permanent });
156
+ */
157
+ export declare function redirect(target: URL | Location | string, init?: redirect.Init): Response;
158
+ export declare namespace redirect {
159
+ /** Use for POST-Redirect-GET pattern. Always changes method to GET. */
160
+ enum Status {
161
+ /** Use for POST-Redirect-GET pattern. Always changes method to GET. */
162
+ SeeOther = 303,
163
+ /** Temporary redirect that preserves HTTP method. */
164
+ Temporary = 307,
165
+ /** Permanent redirect that preserves HTTP method. */
166
+ Permanent = 308
167
+ }
168
+ type Init = Omit<ResponseInit, "status" | "statusText"> & {
169
+ status?: Status;
170
+ };
171
+ }
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Response builders that pair a body with its matching Content-Type
3
+ * header, covering the common content kinds a server returns.
4
+ * @author [Sergio Xalambrí](https://sergiodxa.com)
5
+ * @copyright Sergio Xalambrí 2026
6
+ */
7
+ import { Location } from "@sdxc/location";
8
+ import * as ContentType from "./content-type.js";
9
+ /**
10
+ * Creates a Response with JSON content.
11
+ * Uses the built-in Response.json() method for proper serialization.
12
+ * @param body - The value to serialize as JSON
13
+ * @param init - Optional response options (status, headers, etc.)
14
+ * @returns A new Response instance with JSON content
15
+ * @example
16
+ * return json({ success: true, data: [1, 2, 3] });
17
+ * @example
18
+ * return json({ error: "Not found" }, { status: 404 });
19
+ */
20
+ export function json(body, init) {
21
+ return Response.json(body, init);
22
+ }
23
+ /**
24
+ * Creates a Response with plain text content and appropriate Content-Type header.
25
+ * @param body - The text string to send
26
+ * @param init - Optional response options (status, headers, etc.)
27
+ * @returns A new Response instance with plain text content
28
+ * @example
29
+ * return text("Hello, World!");
30
+ * @example
31
+ * return text("Error occurred", { status: 500 });
32
+ */
33
+ export function text(body, init) {
34
+ let headers = new Headers(init?.headers);
35
+ headers.set("Content-Type", ContentType.Text);
36
+ return new Response(body, { ...init, headers });
37
+ }
38
+ /**
39
+ * Creates a Response with HTML content and appropriate Content-Type header.
40
+ * @param body - The HTML string to send
41
+ * @param init - Optional response options (status, headers, etc.)
42
+ * @returns A new Response instance with HTML content
43
+ * @example
44
+ * return html("<h1>Hello World</h1>");
45
+ * @example
46
+ * return html("<h1>Not Found</h1>", { status: 404 });
47
+ */
48
+ export function html(body, init) {
49
+ let headers = new Headers(init?.headers);
50
+ headers.set("Content-Type", ContentType.HTML);
51
+ return new Response(body, { ...init, headers });
52
+ }
53
+ /**
54
+ * Creates a Response with CSS content and appropriate Content-Type header.
55
+ * @param body - The CSS string to send
56
+ * @param init - Optional response options (status, headers, etc.)
57
+ * @returns A new Response instance with CSS content
58
+ * @example
59
+ * return css("body { color: red; }");
60
+ * @example
61
+ * return css(".error { color: red; }", { headers: { "Cache-Control": "max-age=3600" } });
62
+ */
63
+ export function css(body, init) {
64
+ let headers = new Headers(init?.headers);
65
+ headers.set("Content-Type", ContentType.CSS);
66
+ return new Response(body, { ...init, headers });
67
+ }
68
+ /**
69
+ * Creates a Response with JavaScript content and appropriate Content-Type header.
70
+ * @param body - The JavaScript string to send
71
+ * @param init - Optional response options (status, headers, etc.)
72
+ * @returns A new Response instance with JavaScript content
73
+ * @example
74
+ * return javascript("console.log('Hello');");
75
+ * @example
76
+ * return javascript("export default 42;", { headers: { "Cache-Control": "max-age=3600" } });
77
+ */
78
+ export function javascript(body, init) {
79
+ let headers = new Headers(init?.headers);
80
+ headers.set("Content-Type", ContentType.JavaScript);
81
+ return new Response(body, { ...init, headers });
82
+ }
83
+ /**
84
+ * Creates a Response with XML content and appropriate Content-Type header.
85
+ * @param body - The XML string to send
86
+ * @param init - Optional response options (status, headers, etc.)
87
+ * @returns A new Response instance with XML content
88
+ * @example
89
+ * return xml("<root><item>Hello</item></root>");
90
+ * @example
91
+ * return xml("<error>Not found</error>", { status: 404 });
92
+ */
93
+ export function xml(body, init) {
94
+ let headers = new Headers(init?.headers);
95
+ headers.set("Content-Type", ContentType.XML);
96
+ return new Response(body, { ...init, headers });
97
+ }
98
+ /**
99
+ * Creates a Response with CSV content and appropriate Content-Type header.
100
+ * @param body - The CSV string to send
101
+ * @param init - Optional response options (status, headers, etc.)
102
+ * @returns A new Response instance with CSV content
103
+ * @example
104
+ * return csv("name,age\nJohn,30\nJane,25");
105
+ * @example
106
+ * return csv("id,value\n1,100", { headers: { "Content-Disposition": "attachment; filename=data.csv" } });
107
+ */
108
+ export function csv(body, init) {
109
+ let headers = new Headers(init?.headers);
110
+ headers.set("Content-Type", ContentType.CSV);
111
+ return new Response(body, { ...init, headers });
112
+ }
113
+ /**
114
+ * Creates a Response with Markdown content and appropriate Content-Type header.
115
+ * @param body - The Markdown string to send
116
+ * @param init - Optional response options (status, headers, etc.)
117
+ * @returns A new Response instance with Markdown content
118
+ * @example
119
+ * return markdown("# Hello World\n\nThis is **bold** text.");
120
+ * @example
121
+ * return markdown("# Error\n\nPage not found.", { status: 404 });
122
+ */
123
+ export function markdown(body, init) {
124
+ let headers = new Headers(init?.headers);
125
+ headers.set("Content-Type", ContentType.Markdown);
126
+ return new Response(body, { ...init, headers });
127
+ }
128
+ /**
129
+ * Creates a Response with PDF content and appropriate Content-Type header.
130
+ * Accepts binary data in various formats for flexibility.
131
+ * @param body - The PDF content as Blob, ArrayBuffer, or ReadableStream
132
+ * @param init - Optional response options (status, headers, etc.)
133
+ * @returns A new Response instance with PDF content
134
+ * @example
135
+ * return pdf(pdfBuffer);
136
+ * @example
137
+ * return pdf(pdfBlob, { headers: { "Content-Disposition": "inline; filename=document.pdf" } });
138
+ */
139
+ export function pdf(body, init) {
140
+ let headers = new Headers(init?.headers);
141
+ headers.set("Content-Type", ContentType.PDF);
142
+ return new Response(body, { ...init, headers });
143
+ }
144
+ /**
145
+ * Creates a Response for file downloads with Content-Disposition header.
146
+ * Sets appropriate headers to trigger browser download behavior.
147
+ * @param body - The file content as Blob, ArrayBuffer, or ReadableStream
148
+ * @param filename - The filename to suggest for the download
149
+ * @param init - Optional response options (status, headers, etc.)
150
+ * @returns A new Response instance configured for file download
151
+ * @example
152
+ * return file(zipBuffer, "archive.zip");
153
+ * @example
154
+ * return file(imageBlob, "photo.png", { headers: { "Cache-Control": "no-store" } });
155
+ */
156
+ export function file(body, filename, init) {
157
+ let headers = new Headers(init?.headers);
158
+ headers.set("Content-Type", ContentType.OctetStream);
159
+ headers.set("Content-Disposition", `attachment; filename="${filename}"`);
160
+ return new Response(body, { ...init, headers });
161
+ }
162
+ /**
163
+ * Creates a Response for Server-Sent Events (SSE) streaming.
164
+ * Sets appropriate headers for SSE including Cache-Control and Connection.
165
+ * @param body - The ReadableStream producing SSE events
166
+ * @param init - Optional response options (status, headers, etc.)
167
+ * @returns A new Response instance configured for SSE streaming
168
+ * @example
169
+ * return stream(new ReadableStream({ start(controller) { controller.enqueue("data: hello\n\n"); } }));
170
+ * @example
171
+ * return stream(eventStream, { headers: { "X-Custom-Header": "value" } });
172
+ */
173
+ export function stream(body, init) {
174
+ let headers = new Headers(init?.headers);
175
+ headers.set("Content-Type", ContentType.EventStream);
176
+ headers.set("Cache-Control", "no-cache");
177
+ headers.set("Connection", "keep-alive");
178
+ return new Response(body, { ...init, headers });
179
+ }
180
+ /**
181
+ * Creates a 204 No Content response with no body.
182
+ * Used when an operation succeeds but has no content to return.
183
+ * @param init - Optional response options (headers, etc.) - status is always 204
184
+ * @returns A new Response instance with 204 status and no body
185
+ * @example
186
+ * return noContent();
187
+ * @example
188
+ * return noContent({ headers: { "X-Request-Id": "abc123" } });
189
+ */
190
+ export function noContent(init) {
191
+ return new Response(null, { ...init, status: 204, statusText: "No Content" });
192
+ }
193
+ /**
194
+ * Creates a redirect response to the specified target URL or Location.
195
+ * Validates the target and defaults to 307 Temporary Redirect status.
196
+ * @param target - The URL, Location, or string to redirect to
197
+ * @param init - Optional response options including redirect status
198
+ * @returns A new Response instance with redirect status and Location header
199
+ * @throws Error if the target is not a valid URL or Location
200
+ * @example
201
+ * return redirect("/dashboard");
202
+ * @example
203
+ * return redirect(new URL("https://example.com"), { status: redirect.Status.Permanent });
204
+ */
205
+ export function redirect(target, init) {
206
+ if (!Location.canParse(target)) {
207
+ throw new Error(`Invalid redirect target: ${String(target)}`);
208
+ }
209
+ let headers = new Headers(init?.headers);
210
+ headers.set("Location", String(target));
211
+ let status = init?.status ?? redirect.Status.Temporary;
212
+ return new Response(null, { ...init, status, headers });
213
+ }
214
+ (function (redirect) {
215
+ /** Use for POST-Redirect-GET pattern. Always changes method to GET. */
216
+ let Status;
217
+ (function (Status) {
218
+ /** Use for POST-Redirect-GET pattern. Always changes method to GET. */
219
+ Status[Status["SeeOther"] = 303] = "SeeOther";
220
+ /** Temporary redirect that preserves HTTP method. */
221
+ Status[Status["Temporary"] = 307] = "Temporary";
222
+ /** Permanent redirect that preserves HTTP method. */
223
+ Status[Status["Permanent"] = 308] = "Permanent";
224
+ })(Status = redirect.Status || (redirect.Status = {}));
225
+ })(redirect || (redirect = {}));