@kurdel/runtime-node 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +36 -0
- package/lib/http/index.d.ts +2 -0
- package/lib/http/index.js +3 -0
- package/lib/http/index.js.map +1 -0
- package/lib/http/native-http-server-adapter.d.ts +29 -0
- package/lib/http/native-http-server-adapter.js +65 -0
- package/lib/http/native-http-server-adapter.js.map +1 -0
- package/lib/http/native-req-res-adapters.d.ts +27 -0
- package/lib/http/native-req-res-adapters.js +136 -0
- package/lib/http/native-req-res-adapters.js.map +1 -0
- package/lib/http/render-node-action-result.d.ts +7 -0
- package/lib/http/render-node-action-result.js +48 -0
- package/lib/http/render-node-action-result.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +3 -0
- package/lib/index.js.map +1 -0
- package/lib/middlewares/index.d.ts +1 -0
- package/lib/middlewares/index.js +2 -0
- package/lib/middlewares/index.js.map +1 -0
- package/lib/middlewares/serve-static-middleware.d.ts +12 -0
- package/lib/middlewares/serve-static-middleware.js +50 -0
- package/lib/middlewares/serve-static-middleware.js.map +1 -0
- package/lib/modules/index.d.ts +2 -0
- package/lib/modules/index.js +3 -0
- package/lib/modules/index.js.map +1 -0
- package/lib/modules/node-platform-module.d.ts +7 -0
- package/lib/modules/node-platform-module.js +26 -0
- package/lib/modules/node-platform-module.js.map +1 -0
- package/lib/modules/static-files-module.d.ts +21 -0
- package/lib/modules/static-files-module.js +24 -0
- package/lib/modules/static-files-module.js.map +1 -0
- package/package.json +65 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Andrii Sorokin
|
|
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,36 @@
|
|
|
1
|
+
# @kurdel/runtime-node
|
|
2
|
+
|
|
3
|
+
Native **Node.js HTTP adapter** for Kurdel runtime.
|
|
4
|
+
Implements the `ServerAdapter` interface using the built-in `http` module.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 📦 Installation
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install @kurdel/runtime-node
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 🧠Responsibilities
|
|
17
|
+
|
|
18
|
+
* Create and manage a native Node HTTP server
|
|
19
|
+
* Adapt Node’s `IncomingMessage` / `ServerResponse` to Kurdel `HttpRequest` / `HttpResponse`
|
|
20
|
+
* Dispatch incoming requests to the runtime handler
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🔧 Example
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { createNodeApplication } from '@kurdel/facade';
|
|
28
|
+
const app = await createNodeApplication({ modules: [] });
|
|
29
|
+
app.listen(3000);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
## 📄 License
|
|
35
|
+
|
|
36
|
+
MIT © Andrii Sorokin
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/http/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC;AAChD,cAAc,8BAA8B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Server } from 'node:http';
|
|
2
|
+
import type { HttpRequest, HttpResponse } from '@kurdel/common';
|
|
3
|
+
import type { ServerAdapter } from '@kurdel/core/http';
|
|
4
|
+
/**
|
|
5
|
+
* Node.js implementation of ServerAdapter.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Listen for native HTTP requests
|
|
9
|
+
* - Adapt Node's IncomingMessage / ServerResponse into
|
|
10
|
+
* framework-agnostic HttpRequest / HttpResponse
|
|
11
|
+
* - Delegate execution to the runtime handler
|
|
12
|
+
*/
|
|
13
|
+
export declare class NativeHttpServerAdapter implements ServerAdapter<HttpRequest, HttpResponse> {
|
|
14
|
+
private readonly server;
|
|
15
|
+
private handler?;
|
|
16
|
+
constructor();
|
|
17
|
+
/** Core dispatch: adapt and delegate to the framework handler. */
|
|
18
|
+
private dispatch;
|
|
19
|
+
/** Minimal fallback when handler throws unexpectedly. */
|
|
20
|
+
private handleDispatchError;
|
|
21
|
+
/** Register the runtime handler invoked for every request. */
|
|
22
|
+
on(cb: (req: HttpRequest, res: HttpResponse) => void | Promise<void>): void;
|
|
23
|
+
/** Start listening for HTTP connections. */
|
|
24
|
+
listen(port: number, hostOrCb?: string | (() => void), cb?: () => void): void;
|
|
25
|
+
/** Gracefully close the underlying HTTP server. */
|
|
26
|
+
close(): Promise<void>;
|
|
27
|
+
/** Expose the raw Node.js server (used by the runtime). */
|
|
28
|
+
raw<T = Server>(): T;
|
|
29
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createServer } from 'node:http';
|
|
2
|
+
import { adaptNodeRequest, adaptNodeResponse } from '../http/native-req-res-adapters.js';
|
|
3
|
+
/**
|
|
4
|
+
* Node.js implementation of ServerAdapter.
|
|
5
|
+
*
|
|
6
|
+
* Responsibilities:
|
|
7
|
+
* - Listen for native HTTP requests
|
|
8
|
+
* - Adapt Node's IncomingMessage / ServerResponse into
|
|
9
|
+
* framework-agnostic HttpRequest / HttpResponse
|
|
10
|
+
* - Delegate execution to the runtime handler
|
|
11
|
+
*/
|
|
12
|
+
export class NativeHttpServerAdapter {
|
|
13
|
+
constructor() {
|
|
14
|
+
// Delegate each incoming request to the unified dispatch method
|
|
15
|
+
this.server = createServer((req, res) => this.dispatch(req, res));
|
|
16
|
+
}
|
|
17
|
+
/** Core dispatch: adapt and delegate to the framework handler. */
|
|
18
|
+
async dispatch(req, res) {
|
|
19
|
+
if (!this.handler) {
|
|
20
|
+
res.statusCode = 404;
|
|
21
|
+
res.end('Not Found');
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const request = await adaptNodeRequest(req);
|
|
26
|
+
const response = adaptNodeResponse(res);
|
|
27
|
+
await Promise.resolve(this.handler(request, response));
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
this.handleDispatchError(res, err);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/** Minimal fallback when handler throws unexpectedly. */
|
|
34
|
+
handleDispatchError(res, err) {
|
|
35
|
+
console.error('Unhandled request error:', err);
|
|
36
|
+
if (res.headersSent)
|
|
37
|
+
return;
|
|
38
|
+
const status = err?.status ?? 500;
|
|
39
|
+
const message = err?.message ?? 'Internal Server Error';
|
|
40
|
+
res.statusCode = status;
|
|
41
|
+
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
|
|
42
|
+
res.end(`${status}: ${message}`);
|
|
43
|
+
}
|
|
44
|
+
/** Register the runtime handler invoked for every request. */
|
|
45
|
+
on(cb) {
|
|
46
|
+
this.handler = cb;
|
|
47
|
+
}
|
|
48
|
+
/** Start listening for HTTP connections. */
|
|
49
|
+
listen(port, hostOrCb, cb) {
|
|
50
|
+
const done = (typeof hostOrCb === 'function' ? hostOrCb : cb) ?? (() => { });
|
|
51
|
+
if (typeof hostOrCb === 'string')
|
|
52
|
+
this.server.listen(port, hostOrCb, done);
|
|
53
|
+
else
|
|
54
|
+
this.server.listen(port, done);
|
|
55
|
+
}
|
|
56
|
+
/** Gracefully close the underlying HTTP server. */
|
|
57
|
+
async close() {
|
|
58
|
+
await new Promise((resolve, reject) => this.server.close(err => (err ? reject(err) : resolve())));
|
|
59
|
+
}
|
|
60
|
+
/** Expose the raw Node.js server (used by the runtime). */
|
|
61
|
+
raw() {
|
|
62
|
+
return this.server;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=native-http-server-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-http-server-adapter.js","sourceRoot":"","sources":["../../src/http/native-http-server-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAKzC,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAE1F;;;;;;;;GAQG;AACH,MAAM,OAAO,uBAAuB;IAIlC;QACE,gEAAgE;QAChE,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,kEAAkE;IAC1D,KAAK,CAAC,QAAQ,CAAC,GAAoB,EAAE,GAAmB;QAC9D,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,GAAG,CAAC,CAAC;YAC5C,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAExC,MAAM,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACzD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED,yDAAyD;IACjD,mBAAmB,CAAC,GAAmB,EAAE,GAAY;QAC3D,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAC;QAE/C,IAAI,GAAG,CAAC,WAAW;YAAE,OAAO;QAE5B,MAAM,MAAM,GAAI,GAAW,EAAE,MAAM,IAAI,GAAG,CAAC;QAC3C,MAAM,OAAO,GAAI,GAAW,EAAE,OAAO,IAAI,uBAAuB,CAAC;QAEjE,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC;QACxB,GAAG,CAAC,SAAS,CAAC,cAAc,EAAE,2BAA2B,CAAC,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,OAAO,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,8DAA8D;IAC9D,EAAE,CAAC,EAAiE;QAClE,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;IAED,4CAA4C;IAC5C,MAAM,CAAC,IAAY,EAAE,QAAgC,EAAE,EAAe;QACpE,MAAM,IAAI,GAAG,CAAC,OAAO,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5E,IAAI,OAAO,QAAQ,KAAK,QAAQ;YAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;;YACtE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,mDAAmD;IACnD,KAAK,CAAC,KAAK;QACT,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAC1C,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAC1D,CAAC;IACJ,CAAC;IAED,2DAA2D;IAC3D,GAAG;QACD,OAAO,IAAI,CAAC,MAAsB,CAAC;IACrC,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IncomingMessage, ServerResponse } from 'node:http';
|
|
2
|
+
import type { HttpRequest, HttpResponseWithHeaders } from '@kurdel/common';
|
|
3
|
+
/**
|
|
4
|
+
* Adapts a native Node.js `IncomingMessage` into a platform-neutral `HttpRequest`.
|
|
5
|
+
*
|
|
6
|
+
* Responsibilities:
|
|
7
|
+
* - Read the request body (as text)
|
|
8
|
+
* - Parse JSON if `Content-Type` is `application/json`
|
|
9
|
+
* - Normalize headers into a consistent object
|
|
10
|
+
* - Extract query parameters from URL
|
|
11
|
+
*
|
|
12
|
+
* @param req - The native Node.js HTTP request object
|
|
13
|
+
* @returns A platform-agnostic {@link HttpRequest} used by Kurdel runtime
|
|
14
|
+
*/
|
|
15
|
+
export declare function adaptNodeRequest(req: IncomingMessage): Promise<HttpRequest>;
|
|
16
|
+
/**
|
|
17
|
+
* Adapts a native Node.js `ServerResponse` into a framework-agnostic `HttpResponse`.
|
|
18
|
+
*
|
|
19
|
+
* Responsibilities:
|
|
20
|
+
* - Provide a unified API (`status()`, `send()`, `json()`, etc.)
|
|
21
|
+
* - Automatically manage headers and content types
|
|
22
|
+
* - Support streaming and manual writes (`write()` / `end()`)
|
|
23
|
+
*
|
|
24
|
+
* @param res - The native Node.js ServerResponse instance
|
|
25
|
+
* @returns Wrapped {@link HttpResponseWithHeaders} compatible with Kurdel runtime
|
|
26
|
+
*/
|
|
27
|
+
export declare function adaptNodeResponse(res: ServerResponse): HttpResponseWithHeaders;
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { DEFAULT_INTERNAL_BASE } from '@kurdel/common';
|
|
2
|
+
/**
|
|
3
|
+
* Adapts a native Node.js `IncomingMessage` into a platform-neutral `HttpRequest`.
|
|
4
|
+
*
|
|
5
|
+
* Responsibilities:
|
|
6
|
+
* - Read the request body (as text)
|
|
7
|
+
* - Parse JSON if `Content-Type` is `application/json`
|
|
8
|
+
* - Normalize headers into a consistent object
|
|
9
|
+
* - Extract query parameters from URL
|
|
10
|
+
*
|
|
11
|
+
* @param req - The native Node.js HTTP request object
|
|
12
|
+
* @returns A platform-agnostic {@link HttpRequest} used by Kurdel runtime
|
|
13
|
+
*/
|
|
14
|
+
export async function adaptNodeRequest(req) {
|
|
15
|
+
const chunks = [];
|
|
16
|
+
// Collect request body (streamed)
|
|
17
|
+
if (Symbol.asyncIterator in req) {
|
|
18
|
+
for await (const chunk of req) {
|
|
19
|
+
chunks.push(chunk);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const rawBody = Buffer.concat(chunks).toString('utf8').trim();
|
|
23
|
+
// Normalize headers
|
|
24
|
+
const nodeHeaders = req.headers ?? {};
|
|
25
|
+
const headers = {};
|
|
26
|
+
for (const [key, value] of Object.entries(nodeHeaders)) {
|
|
27
|
+
if (value !== undefined)
|
|
28
|
+
headers[key] = value;
|
|
29
|
+
}
|
|
30
|
+
// Parse JSON body if applicable
|
|
31
|
+
const contentType = (req.headers?.['content-type'] ?? '').toString();
|
|
32
|
+
let parsedBody;
|
|
33
|
+
if (contentType.includes('application/json')) {
|
|
34
|
+
try {
|
|
35
|
+
parsedBody = rawBody ? JSON.parse(rawBody) : undefined;
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
parsedBody = undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Build absolute URL using default internal base (e.g., http://internal.local)
|
|
42
|
+
const url = new URL(req.url ?? '/', DEFAULT_INTERNAL_BASE);
|
|
43
|
+
// Extract query parameters
|
|
44
|
+
const query = {};
|
|
45
|
+
url.searchParams.forEach((value, key) => {
|
|
46
|
+
if (key in query) {
|
|
47
|
+
const prev = query[key];
|
|
48
|
+
query[key] = Array.isArray(prev) ? [...prev, value] : [prev, value];
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
query[key] = value;
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
// Return normalized HttpRequest
|
|
55
|
+
return {
|
|
56
|
+
method: req.method ?? 'GET',
|
|
57
|
+
url: req.url ?? '/',
|
|
58
|
+
headers,
|
|
59
|
+
body: parsedBody,
|
|
60
|
+
query,
|
|
61
|
+
params: {},
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Adapts a native Node.js `ServerResponse` into a framework-agnostic `HttpResponse`.
|
|
66
|
+
*
|
|
67
|
+
* Responsibilities:
|
|
68
|
+
* - Provide a unified API (`status()`, `send()`, `json()`, etc.)
|
|
69
|
+
* - Automatically manage headers and content types
|
|
70
|
+
* - Support streaming and manual writes (`write()` / `end()`)
|
|
71
|
+
*
|
|
72
|
+
* @param res - The native Node.js ServerResponse instance
|
|
73
|
+
* @returns Wrapped {@link HttpResponseWithHeaders} compatible with Kurdel runtime
|
|
74
|
+
*/
|
|
75
|
+
export function adaptNodeResponse(res) {
|
|
76
|
+
const response = {
|
|
77
|
+
get sent() {
|
|
78
|
+
return res.writableEnded || res.destroyed;
|
|
79
|
+
},
|
|
80
|
+
raw: res,
|
|
81
|
+
status(code) {
|
|
82
|
+
res.statusCode = code;
|
|
83
|
+
return this;
|
|
84
|
+
},
|
|
85
|
+
send(body) {
|
|
86
|
+
if (body == null) {
|
|
87
|
+
res.end();
|
|
88
|
+
return this;
|
|
89
|
+
}
|
|
90
|
+
const content = typeof body === 'object' ? JSON.stringify(body) : String(body);
|
|
91
|
+
if (!res.getHeader('Content-Type')) {
|
|
92
|
+
res.setHeader('Content-Type', typeof body === 'object' ? 'application/json; charset=utf-8' : 'text/plain; charset=utf-8');
|
|
93
|
+
}
|
|
94
|
+
res.end(content);
|
|
95
|
+
return this;
|
|
96
|
+
},
|
|
97
|
+
json(body) {
|
|
98
|
+
res.statusCode = res.statusCode || 200;
|
|
99
|
+
res.setHeader('Content-Type', 'application/json; charset=utf-8');
|
|
100
|
+
res.end(JSON.stringify(body));
|
|
101
|
+
return this;
|
|
102
|
+
},
|
|
103
|
+
redirect(code, location) {
|
|
104
|
+
res.statusCode = code;
|
|
105
|
+
res.setHeader('Location', location);
|
|
106
|
+
res.end();
|
|
107
|
+
return this;
|
|
108
|
+
},
|
|
109
|
+
setHeader(name, value) {
|
|
110
|
+
res.setHeader(name, value);
|
|
111
|
+
return this;
|
|
112
|
+
},
|
|
113
|
+
getHeader(name) {
|
|
114
|
+
const value = res.getHeader(name);
|
|
115
|
+
return typeof value === 'string'
|
|
116
|
+
? value
|
|
117
|
+
: Array.isArray(value)
|
|
118
|
+
? value.join(', ')
|
|
119
|
+
: undefined;
|
|
120
|
+
},
|
|
121
|
+
type(mime) {
|
|
122
|
+
this.setHeader('Content-Type', mime);
|
|
123
|
+
return this;
|
|
124
|
+
},
|
|
125
|
+
write(chunk) {
|
|
126
|
+
res.write(chunk);
|
|
127
|
+
return this;
|
|
128
|
+
},
|
|
129
|
+
end(chunk) {
|
|
130
|
+
res.end(chunk);
|
|
131
|
+
return this;
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
return response;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=native-req-res-adapters.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-req-res-adapters.js","sourceRoot":"","sources":["../../src/http/native-req-res-adapters.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { HttpResponse } from '@kurdel/common';
|
|
2
|
+
import type { ActionResult } from '@kurdel/core/http';
|
|
3
|
+
/**
|
|
4
|
+
* Node-specific renderer for ActionResult.
|
|
5
|
+
* Handles JSON, text, HTML, redirects, empties and stream bodies.
|
|
6
|
+
*/
|
|
7
|
+
export declare function renderNodeActionResult(res: HttpResponse, r: ActionResult): void;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Node-specific renderer for ActionResult.
|
|
3
|
+
* Handles JSON, text, HTML, redirects, empties and stream bodies.
|
|
4
|
+
*/
|
|
5
|
+
export function renderNodeActionResult(res, r) {
|
|
6
|
+
switch (r.kind) {
|
|
7
|
+
case 'json':
|
|
8
|
+
res.status(r.status).json(r.body);
|
|
9
|
+
break;
|
|
10
|
+
case 'text':
|
|
11
|
+
res.status(r.status).send(r.body);
|
|
12
|
+
break;
|
|
13
|
+
case 'html': {
|
|
14
|
+
const withHeaders = res;
|
|
15
|
+
withHeaders.setHeader?.('Content-Type', r.contentType ?? 'text/html; charset=utf-8');
|
|
16
|
+
res.status(r.status).send(r.body);
|
|
17
|
+
break;
|
|
18
|
+
}
|
|
19
|
+
case 'redirect':
|
|
20
|
+
res.redirect(r.status, r.location);
|
|
21
|
+
break;
|
|
22
|
+
case 'empty':
|
|
23
|
+
res.status(r.status).send('');
|
|
24
|
+
break;
|
|
25
|
+
case 'stream': {
|
|
26
|
+
const s = r;
|
|
27
|
+
const withHeaders = res;
|
|
28
|
+
const nodeRes = res.raw;
|
|
29
|
+
if (s.contentType)
|
|
30
|
+
withHeaders.setHeader?.('Content-Type', s.contentType);
|
|
31
|
+
if (s.contentLength)
|
|
32
|
+
withHeaders.setHeader?.('Content-Length', String(s.contentLength));
|
|
33
|
+
res.status(s.status);
|
|
34
|
+
const stream = s.body;
|
|
35
|
+
if (stream && typeof stream.pipe === 'function' && typeof nodeRes.write === 'function') {
|
|
36
|
+
// ✅ Pipe directly into native Node response
|
|
37
|
+
stream.pipe(nodeRes);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
res.status(500).send('Invalid stream body');
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
default:
|
|
45
|
+
res.status(500).send('Unsupported response type');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=render-node-action-result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-node-action-result.js","sourceRoot":"","sources":["../../src/http/render-node-action-result.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAiB,EAAE,CAAe;IACvE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,MAAM;YACT,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM;QAER,KAAK,MAAM;YACT,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM;QAER,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,WAAW,GAAG,GAA8B,CAAC;YACnD,WAAW,CAAC,SAAS,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,WAAW,IAAI,0BAA0B,CAAC,CAAC;YACrF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM;QACR,CAAC;QAED,KAAK,UAAU;YACb,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM;QAER,KAAK,OAAO;YACV,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC9B,MAAM;QAER,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,CAAC,GAAG,CAAwC,CAAC;YACnD,MAAM,WAAW,GAAG,GAA8B,CAAC;YACnD,MAAM,OAAO,GAAG,GAAG,CAAC,GAAgC,CAAC;YAErD,IAAI,CAAC,CAAC,WAAW;gBAAE,WAAW,CAAC,SAAS,EAAE,CAAC,cAAc,EAAE,CAAC,CAAC,WAAW,CAAC,CAAC;YAC1E,IAAI,CAAC,CAAC,aAAa;gBAAE,WAAW,CAAC,SAAS,EAAE,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC;YAExF,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAErB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC;YAEtB,IAAI,MAAM,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;gBACvF,4CAA4C;gBAC5C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAC9C,CAAC;YACD,MAAM;QACR,CAAC;QAED;YACE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IACtD,CAAC;AACH,CAAC"}
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
package/lib/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,iBAAiB,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/middlewares/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Middleware } from '@kurdel/core/http';
|
|
2
|
+
/**
|
|
3
|
+
* @kurdel
|
|
4
|
+
* Node.js static file middleware.
|
|
5
|
+
*
|
|
6
|
+
* Responsibilities:
|
|
7
|
+
* - Serve static files from a configured directory
|
|
8
|
+
* - Prevent directory traversal
|
|
9
|
+
* - Set correct MIME type
|
|
10
|
+
* - Fallback to `next()` if file not found
|
|
11
|
+
*/
|
|
12
|
+
export declare function serveStaticMiddleware(rootDir: string): Middleware<unknown, NodeJS.ReadableStream>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { createReadStream, promises as fs } from 'node:fs';
|
|
2
|
+
import { extname, join, normalize } from 'node:path';
|
|
3
|
+
import mime from 'mime-types';
|
|
4
|
+
/**
|
|
5
|
+
* @kurdel
|
|
6
|
+
* Node.js static file middleware.
|
|
7
|
+
*
|
|
8
|
+
* Responsibilities:
|
|
9
|
+
* - Serve static files from a configured directory
|
|
10
|
+
* - Prevent directory traversal
|
|
11
|
+
* - Set correct MIME type
|
|
12
|
+
* - Fallback to `next()` if file not found
|
|
13
|
+
*/
|
|
14
|
+
export function serveStaticMiddleware(rootDir) {
|
|
15
|
+
return async (ctx, next) => {
|
|
16
|
+
try {
|
|
17
|
+
// Normalize path to prevent traversal (`..`)
|
|
18
|
+
const urlPath = decodeURIComponent(ctx.url.pathname ?? '/');
|
|
19
|
+
const safePath = normalize(join(rootDir, urlPath)).replace(/\\/g, '/');
|
|
20
|
+
if (!safePath.startsWith(rootDir.replace(/\\/g, '/'))) {
|
|
21
|
+
// Security guard — attempt to escape root directory
|
|
22
|
+
return next();
|
|
23
|
+
}
|
|
24
|
+
let filePath = safePath;
|
|
25
|
+
// If it's a directory, try to serve index.html
|
|
26
|
+
const stat = await fs.stat(filePath).catch(() => null);
|
|
27
|
+
if (stat?.isDirectory()) {
|
|
28
|
+
filePath = join(filePath, 'index.html');
|
|
29
|
+
}
|
|
30
|
+
const finalStat = await fs.stat(filePath).catch(() => null);
|
|
31
|
+
if (!finalStat?.isFile()) {
|
|
32
|
+
return next();
|
|
33
|
+
}
|
|
34
|
+
const extension = extname(filePath);
|
|
35
|
+
const mimeType = mime.lookup(extension) || 'application/octet-stream';
|
|
36
|
+
const stream = createReadStream(filePath);
|
|
37
|
+
return {
|
|
38
|
+
kind: 'stream',
|
|
39
|
+
status: 200,
|
|
40
|
+
body: stream,
|
|
41
|
+
contentType: mimeType,
|
|
42
|
+
contentLength: finalStat.size,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return next();
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=serve-static-middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-static-middleware.js","sourceRoot":"","sources":["../../src/middlewares/serve-static-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,IAAI,MAAM,YAAY,CAAC;AAG9B;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,OAAO,KAAK,EAAE,GAAgB,EAAE,IAAI,EAAuD,EAAE;QAC3F,IAAI,CAAC;YACH,6CAA6C;YAC7C,MAAM,OAAO,GAAG,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,CAAC;YAC5D,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAEvE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;gBACtD,oDAAoD;gBACpD,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YAED,IAAI,QAAQ,GAAG,QAAQ,CAAC;YAExB,+CAA+C;YAC/C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YACvD,IAAI,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC;gBACxB,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;YAC5D,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC;gBACzB,OAAO,IAAI,EAAE,CAAC;YAChB,CAAC;YAED,MAAM,SAAS,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,0BAA0B,CAAC;YAEtE,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;YAE1C,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,MAAM;gBACZ,WAAW,EAAE,QAAQ;gBACrB,aAAa,EAAE,SAAS,CAAC,IAAI;aAC9B,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/modules/index.ts"],"names":[],"mappings":"AAAA,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ModulePriority } from '@kurdel/core/app';
|
|
2
|
+
import { TOKENS } from '@kurdel/core/tokens';
|
|
3
|
+
import { RuntimeResponseRenderer } from '@kurdel/runtime/http';
|
|
4
|
+
import { renderNodeActionResult } from '../http/render-node-action-result.js';
|
|
5
|
+
import { NativeHttpServerAdapter } from '../http/native-http-server-adapter.js';
|
|
6
|
+
/**
|
|
7
|
+
* Provides Node.js platform-level services:
|
|
8
|
+
* - native ServerAdapter
|
|
9
|
+
* - platform-aware ResponseRenderer
|
|
10
|
+
*/
|
|
11
|
+
export const NodePlatformModule = {
|
|
12
|
+
priority: ModulePriority.Platform,
|
|
13
|
+
providers: [
|
|
14
|
+
{
|
|
15
|
+
provide: TOKENS.ServerAdapter,
|
|
16
|
+
useFactory: () => new NativeHttpServerAdapter(),
|
|
17
|
+
singleton: true,
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
provide: TOKENS.ResponseRenderer,
|
|
21
|
+
useFactory: () => new RuntimeResponseRenderer(renderNodeActionResult),
|
|
22
|
+
singleton: true,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=node-platform-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-platform-module.js","sourceRoot":"","sources":["../../src/modules/node-platform-module.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AAEjF;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,QAAQ,EAAE,cAAc,CAAC,QAAQ;IACjC,SAAS,EAAE;QACT;YACE,OAAO,EAAE,MAAM,CAAC,aAAa;YAC7B,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,uBAAuB,EAAE;YAC/C,SAAS,EAAE,IAAI;SAChB;QACD;YACE,OAAO,EAAE,MAAM,CAAC,gBAAgB;YAChC,UAAU,EAAE,GAAG,EAAE,CAAC,IAAI,uBAAuB,CAAC,sBAAsB,CAAC;YACrE,SAAS,EAAE,IAAI;SAChB;KACF;CACF,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AppConfig } from '@kurdel/core/app';
|
|
2
|
+
import type { HttpModule } from '@kurdel/core/http';
|
|
3
|
+
/**
|
|
4
|
+
* StaticFilesModule
|
|
5
|
+
*
|
|
6
|
+
* HTTP module that provides a global middleware
|
|
7
|
+
* for serving static files from a specified directory.
|
|
8
|
+
*
|
|
9
|
+
* @example:
|
|
10
|
+
* ```ts
|
|
11
|
+
* export const AppModule: HttpModule = {
|
|
12
|
+
* imports: [StaticFilesModule.forRoot('public')],
|
|
13
|
+
* };
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export declare class StaticFilesModule implements HttpModule<AppConfig, NodeJS.ReadableStream> {
|
|
17
|
+
private readonly baseDir;
|
|
18
|
+
readonly middlewares: import("@kurdel/core/http").Middleware<unknown, NodeJS.ReadableStream>[];
|
|
19
|
+
constructor(baseDir: string);
|
|
20
|
+
static forRoot(baseDir: string): StaticFilesModule;
|
|
21
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { serveStaticMiddleware } from '../middlewares/serve-static-middleware.js';
|
|
2
|
+
/**
|
|
3
|
+
* StaticFilesModule
|
|
4
|
+
*
|
|
5
|
+
* HTTP module that provides a global middleware
|
|
6
|
+
* for serving static files from a specified directory.
|
|
7
|
+
*
|
|
8
|
+
* @example:
|
|
9
|
+
* ```ts
|
|
10
|
+
* export const AppModule: HttpModule = {
|
|
11
|
+
* imports: [StaticFilesModule.forRoot('public')],
|
|
12
|
+
* };
|
|
13
|
+
* ```
|
|
14
|
+
*/
|
|
15
|
+
export class StaticFilesModule {
|
|
16
|
+
constructor(baseDir) {
|
|
17
|
+
this.baseDir = baseDir;
|
|
18
|
+
this.middlewares = [serveStaticMiddleware(baseDir)];
|
|
19
|
+
}
|
|
20
|
+
static forRoot(baseDir) {
|
|
21
|
+
return new StaticFilesModule(baseDir);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=static-files-module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-files-module.js","sourceRoot":"","sources":["../../src/modules/static-files-module.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,4CAA4C,CAAC;AAEnF;;;;;;;;;;;;GAYG;AACH,MAAM,OAAO,iBAAiB;IAG5B,YAA6B,OAAe;QAAf,YAAO,GAAP,OAAO,CAAQ;QAC1C,IAAI,CAAC,WAAW,GAAG,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,OAAe;QAC5B,OAAO,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kurdel/runtime-node",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "Node.js HTTP runtime adapter for Kurdel",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": "./lib/index.js",
|
|
8
|
+
"./http": "./lib/http/index.js",
|
|
9
|
+
"./modules": "./lib/modules/index.js"
|
|
10
|
+
},
|
|
11
|
+
"main": "./lib/index.js",
|
|
12
|
+
"types": "./lib/index.d.ts",
|
|
13
|
+
"files": [
|
|
14
|
+
"lib"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"prepack": "npm run build",
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:ui": "vitest",
|
|
20
|
+
"test:watch": "vitest --watch",
|
|
21
|
+
"coverage": "vitest run --coverage",
|
|
22
|
+
"clean": "rimraf lib ../../.cache/tsconfig.runtime-node.build.tsbuildinfo",
|
|
23
|
+
"build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json",
|
|
24
|
+
"build:force": "npm run clean && tsc -p tsconfig.build.json --force && tsc-alias -p tsconfig.build.json"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"kurdel",
|
|
28
|
+
"node",
|
|
29
|
+
"http",
|
|
30
|
+
"adapter",
|
|
31
|
+
"framework"
|
|
32
|
+
],
|
|
33
|
+
"author": "Andrii Sorokin",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"engines": {
|
|
36
|
+
"node": "^20.19.0 || ^22.12.0 || >=24.0.0"
|
|
37
|
+
},
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/ignorantic/kurdel.git",
|
|
41
|
+
"directory": "packages/runtime-node"
|
|
42
|
+
},
|
|
43
|
+
"homepage": "https://github.com/ignorantic/kurdel/tree/main/packages/runtime-node#readme",
|
|
44
|
+
"bugs": {
|
|
45
|
+
"url": "https://github.com/ignorantic/kurdel/issues"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public",
|
|
49
|
+
"tag": "beta"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/mime-types": "^3.0.1",
|
|
53
|
+
"@types/node": "^20.9.0",
|
|
54
|
+
"@types/supertest": "^6.0.3",
|
|
55
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
56
|
+
"rimraf": "^6.0.1",
|
|
57
|
+
"supertest": "^7.1.4",
|
|
58
|
+
"tsc-alias": "^1.8.16"
|
|
59
|
+
},
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"@kurdel/common": "0.1.0-beta.1",
|
|
62
|
+
"@kurdel/core": "0.1.0-beta.1",
|
|
63
|
+
"@kurdel/runtime": "0.1.0-beta.1"
|
|
64
|
+
}
|
|
65
|
+
}
|