@faasjs/dev 8.0.0-beta.6 → 8.0.0-beta.7
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/README.md +7 -27
- package/dist/chunk-CtajNgzt.mjs +36 -0
- package/dist/cli.cjs +51 -319
- package/dist/cli.d.ts +3 -2
- package/dist/cli.mjs +50 -120
- package/dist/index.cjs +310 -582
- package/dist/index.d.ts +64 -87
- package/dist/index.mjs +273 -344
- package/dist/typegen-C6t9LIyi.cjs +183 -0
- package/dist/typegen-D5s91_xL.mjs +166 -0
- package/package.json +16 -22
- package/dist/chunk-3FXFWIBW.mjs +0 -221
package/dist/index.cjs
CHANGED
|
@@ -1,606 +1,334 @@
|
|
|
1
|
-
'
|
|
2
|
-
|
|
3
|
-
var pglite = require('@electric-sql/pglite');
|
|
4
|
-
var knex = require('knex');
|
|
5
|
-
var PgliteDialect = require('knex-pglite');
|
|
6
|
-
var zlib = require('zlib');
|
|
7
|
-
var deep_merge = require('@faasjs/deep_merge');
|
|
8
|
-
var http = require('@faasjs/http');
|
|
9
|
-
var load = require('@faasjs/load');
|
|
10
|
-
var logger = require('@faasjs/logger');
|
|
11
|
-
var func_star = require('@faasjs/func');
|
|
12
|
-
var fs = require('fs');
|
|
13
|
-
var promises = require('fs/promises');
|
|
14
|
-
var path = require('path');
|
|
15
|
-
var server = require('@faasjs/server');
|
|
16
|
-
|
|
17
|
-
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
18
|
-
|
|
19
|
-
function _interopNamespace(e) {
|
|
20
|
-
if (e && e.__esModule) return e;
|
|
21
|
-
var n = Object.create(null);
|
|
22
|
-
if (e) {
|
|
23
|
-
Object.keys(e).forEach(function (k) {
|
|
24
|
-
if (k !== 'default') {
|
|
25
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
26
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
27
|
-
enumerable: true,
|
|
28
|
-
get: function () { return e[k]; }
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
n.default = e;
|
|
34
|
-
return Object.freeze(n);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
var knex__default = /*#__PURE__*/_interopDefault(knex);
|
|
38
|
-
var PgliteDialect__default = /*#__PURE__*/_interopDefault(PgliteDialect);
|
|
39
|
-
var func_star__namespace = /*#__PURE__*/_interopNamespace(func_star);
|
|
40
|
-
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
//#region \0rolldown/runtime.js
|
|
41
3
|
var __defProp = Object.defineProperty;
|
|
42
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
43
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
44
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
45
|
-
var
|
|
46
|
-
|
|
47
|
-
|
|
7
|
+
var __exportAll = (all, no_symbols) => {
|
|
8
|
+
let target = {};
|
|
9
|
+
for (var name in all) {
|
|
10
|
+
__defProp(target, name, {
|
|
11
|
+
get: all[name],
|
|
12
|
+
enumerable: true
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
if (!no_symbols) {
|
|
16
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
17
|
+
}
|
|
18
|
+
return target;
|
|
48
19
|
};
|
|
49
20
|
var __copyProps = (to, from, except, desc) => {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
23
|
+
key = keys[i];
|
|
24
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
25
|
+
__defProp(to, key, {
|
|
26
|
+
get: ((k) => from[k]).bind(null, key),
|
|
27
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return to;
|
|
56
33
|
};
|
|
57
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget);
|
|
34
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
58
35
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
streamToString: () => streamToString,
|
|
68
|
-
test: () => test,
|
|
69
|
-
unmountFaasKnex: () => unmountFaasKnex,
|
|
70
|
-
viteFaasJsServer: () => viteFaasJsServer
|
|
71
|
-
});
|
|
72
|
-
var postgresTypeParsers = {
|
|
73
|
-
[pglite.types.INT2]: (v) => Number.parseInt(v, 10),
|
|
74
|
-
[pglite.types.INT4]: (v) => Number.parseInt(v, 10),
|
|
75
|
-
[pglite.types.INT8]: (v) => Number.parseInt(v, 10),
|
|
76
|
-
[pglite.types.FLOAT4]: (v) => Number.parseFloat(v),
|
|
77
|
-
[pglite.types.FLOAT8]: (v) => Number.parseFloat(v),
|
|
78
|
-
[pglite.types.NUMERIC]: (v) => Number.parseFloat(v)
|
|
79
|
-
};
|
|
80
|
-
function createPgliteKnex(config = {}, connection = {}) {
|
|
81
|
-
const pgliteConnection = connection;
|
|
82
|
-
const dataDir = typeof pgliteConnection.filename === "string" ? pgliteConnection.filename : typeof pgliteConnection.connectionString === "string" ? pgliteConnection.connectionString : void 0;
|
|
83
|
-
const pglite$1 = new pglite.PGlite({
|
|
84
|
-
...dataDir ? { dataDir } : {},
|
|
85
|
-
parsers: postgresTypeParsers
|
|
86
|
-
});
|
|
87
|
-
const pgliteKnexConnection = {
|
|
88
|
-
...connection,
|
|
89
|
-
pglite: pglite$1
|
|
90
|
-
};
|
|
91
|
-
return knex__default.default({
|
|
92
|
-
...config,
|
|
93
|
-
client: PgliteDialect__default.default,
|
|
94
|
-
connection: pgliteKnexConnection
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
function mountFaasKnex(db, options = {}) {
|
|
98
|
-
const globalWithFaasKnex = globalThis;
|
|
99
|
-
const name = options.name || "knex";
|
|
100
|
-
if (!globalWithFaasKnex.FaasJS_Knex) globalWithFaasKnex.FaasJS_Knex = {};
|
|
101
|
-
globalWithFaasKnex.FaasJS_Knex[name] = {
|
|
102
|
-
adapter: db,
|
|
103
|
-
query: db,
|
|
104
|
-
config: options.config || {}
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
function unmountFaasKnex(name = "knex") {
|
|
108
|
-
const globalWithFaasKnex = globalThis;
|
|
109
|
-
if (!globalWithFaasKnex.FaasJS_Knex) return;
|
|
110
|
-
delete globalWithFaasKnex.FaasJS_Knex[name];
|
|
111
|
-
}
|
|
36
|
+
//#endregion
|
|
37
|
+
const require_typegen = require('./typegen-C6t9LIyi.cjs');
|
|
38
|
+
let node_zlib = require("node:zlib");
|
|
39
|
+
let _faasjs_http = require("@faasjs/http");
|
|
40
|
+
let _faasjs_logger = require("@faasjs/logger");
|
|
41
|
+
let _faasjs_node_utils = require("@faasjs/node-utils");
|
|
42
|
+
let node_path = require("node:path");
|
|
43
|
+
let _faasjs_server = require("@faasjs/server");
|
|
112
44
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
while (true) {
|
|
128
|
-
const { done, value } = await reader.read();
|
|
129
|
-
if (done) break;
|
|
130
|
-
if (value) chunks.push(value);
|
|
131
|
-
}
|
|
132
|
-
} finally {
|
|
133
|
-
reader.releaseLock();
|
|
134
|
-
}
|
|
135
|
-
const decoder = new TextDecoder();
|
|
136
|
-
return decoder.decode(Buffer.concat(chunks.map((c) => Buffer.from(c))));
|
|
137
|
-
}
|
|
45
|
+
//#region src/test.ts
|
|
46
|
+
/**
|
|
47
|
+
* Test wrapper for a function.
|
|
48
|
+
*
|
|
49
|
+
* ```ts
|
|
50
|
+
* import { FuncWarper } from '@faasjs/dev'
|
|
51
|
+
* import Func from '../demo.func.ts'
|
|
52
|
+
*
|
|
53
|
+
* const func = new FuncWarper(Func)
|
|
54
|
+
*
|
|
55
|
+
* expect(await func.handler()).toEqual('Hello, world')
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
138
58
|
var FuncWarper = class {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
response.error = { message: error.message };
|
|
264
|
-
response.statusCode = 500;
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
if (response?.headers && response.body && response.headers["content-type"]?.includes("json")) {
|
|
268
|
-
const parsedBody = JSON.parse(response.body);
|
|
269
|
-
response.data = parsedBody.data;
|
|
270
|
-
response.error = parsedBody.error;
|
|
271
|
-
}
|
|
272
|
-
if (this.http) {
|
|
273
|
-
response.cookie = this.http.cookie.content;
|
|
274
|
-
response.session = this.http.session.content;
|
|
275
|
-
}
|
|
276
|
-
this.logger.debug("response: %j", response);
|
|
277
|
-
return response;
|
|
278
|
-
}
|
|
59
|
+
file;
|
|
60
|
+
staging;
|
|
61
|
+
logger;
|
|
62
|
+
func;
|
|
63
|
+
config;
|
|
64
|
+
plugins;
|
|
65
|
+
_handler;
|
|
66
|
+
/**
|
|
67
|
+
* @param initBy {Func} A FaasJS function
|
|
68
|
+
* ```ts
|
|
69
|
+
* import { FuncWarper } from '@faasjs/dev'
|
|
70
|
+
*
|
|
71
|
+
* new FuncWarper(__dirname + '/../demo.func.ts')
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
constructor(initBy) {
|
|
75
|
+
this.staging = process.env.FaasEnv ?? "default";
|
|
76
|
+
this.logger = new _faasjs_logger.Logger("TestCase");
|
|
77
|
+
this.func = initBy.default ? initBy.default : initBy;
|
|
78
|
+
if (this.func.filename) this.func.config = (0, _faasjs_node_utils.deepMerge)((0, _faasjs_node_utils.loadConfig)(process.cwd(), this.func.filename, this.staging, this.logger), this.func.config);
|
|
79
|
+
this.file = this.func.filename || "";
|
|
80
|
+
this.config = this.func.config;
|
|
81
|
+
this.plugins = this.func.plugins || [];
|
|
82
|
+
for (const plugin of this.plugins) {
|
|
83
|
+
if ([
|
|
84
|
+
"handler",
|
|
85
|
+
"config",
|
|
86
|
+
"plugins",
|
|
87
|
+
"logger",
|
|
88
|
+
"mount"
|
|
89
|
+
].includes(plugin.type)) continue;
|
|
90
|
+
this[plugin.type] = plugin;
|
|
91
|
+
}
|
|
92
|
+
this._handler = this.func.export().handler;
|
|
93
|
+
}
|
|
94
|
+
async mount(handler) {
|
|
95
|
+
if (!this.func.mounted) await this.func.mount();
|
|
96
|
+
if (handler) await handler(this);
|
|
97
|
+
}
|
|
98
|
+
async handler(event = Object.create(null), context = Object.create(null)) {
|
|
99
|
+
await this.mount();
|
|
100
|
+
const response = await this._handler(event, context);
|
|
101
|
+
this.logger.debug("response: %j", response);
|
|
102
|
+
return response;
|
|
103
|
+
}
|
|
104
|
+
async JSONhandler(body, options = Object.create(null)) {
|
|
105
|
+
await this.mount();
|
|
106
|
+
const headers = options.headers || Object.create(null);
|
|
107
|
+
if (this.http && this.http instanceof _faasjs_http.Http) {
|
|
108
|
+
if (options.cookie) for (const key in options.cookie) this.http.cookie.write(key, options.cookie[key]);
|
|
109
|
+
if (options.session) {
|
|
110
|
+
for (const key in options.session) this.http.session.write(key, options.session[key]);
|
|
111
|
+
this.http.session.update();
|
|
112
|
+
}
|
|
113
|
+
const cookie = this.http.cookie.headers()["Set-Cookie"]?.map((c) => c.split(";")[0]).join(";");
|
|
114
|
+
if (cookie) if (headers.cookie) headers.cookie += `;${cookie}`;
|
|
115
|
+
else headers.cookie = cookie;
|
|
116
|
+
}
|
|
117
|
+
const response = await this._handler({
|
|
118
|
+
httpMethod: "POST",
|
|
119
|
+
headers: Object.assign({ "content-type": "application/json" }, headers),
|
|
120
|
+
body: typeof body === "string" ? body : JSON.stringify(body)
|
|
121
|
+
});
|
|
122
|
+
if (response?.body instanceof ReadableStream) {
|
|
123
|
+
let stream = response.body;
|
|
124
|
+
const encoding = response.headers?.["Content-Encoding"] || response.headers?.["content-encoding"];
|
|
125
|
+
if (encoding) {
|
|
126
|
+
const chunks = [];
|
|
127
|
+
const reader = stream.getReader();
|
|
128
|
+
try {
|
|
129
|
+
while (true) {
|
|
130
|
+
const { done, value } = await reader.read();
|
|
131
|
+
if (done) break;
|
|
132
|
+
if (value) chunks.push(value);
|
|
133
|
+
}
|
|
134
|
+
} catch (error) {
|
|
135
|
+
this.logger.error("Failed to read ReadableStream: %s", error);
|
|
136
|
+
response.body = JSON.stringify({ error: { message: error.message } });
|
|
137
|
+
response.error = { message: error.message };
|
|
138
|
+
response.statusCode = 500;
|
|
139
|
+
reader.releaseLock();
|
|
140
|
+
return response;
|
|
141
|
+
}
|
|
142
|
+
reader.releaseLock();
|
|
143
|
+
const compressedBuffer = Buffer.concat(chunks);
|
|
144
|
+
try {
|
|
145
|
+
let decompressed;
|
|
146
|
+
if (encoding === "br") decompressed = (0, node_zlib.brotliDecompressSync)(compressedBuffer);
|
|
147
|
+
else if (encoding === "gzip") decompressed = (0, node_zlib.gunzipSync)(compressedBuffer);
|
|
148
|
+
else if (encoding === "deflate") decompressed = (0, node_zlib.inflateSync)(compressedBuffer);
|
|
149
|
+
else throw new Error(`Unsupported encoding: ${encoding}`);
|
|
150
|
+
stream = new ReadableStream({ start(controller) {
|
|
151
|
+
controller.enqueue(new Uint8Array(decompressed));
|
|
152
|
+
controller.close();
|
|
153
|
+
} });
|
|
154
|
+
} catch (error) {
|
|
155
|
+
this.logger.error("Failed to decompress: %s", error);
|
|
156
|
+
response.body = JSON.stringify({ error: { message: error.message } });
|
|
157
|
+
response.error = { message: error.message };
|
|
158
|
+
response.statusCode = 500;
|
|
159
|
+
return response;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
try {
|
|
163
|
+
response.body = await (0, _faasjs_node_utils.streamToText)(stream);
|
|
164
|
+
} catch (error) {
|
|
165
|
+
this.logger.error("Failed to decode ReadableStream: %s", error);
|
|
166
|
+
response.body = JSON.stringify({ error: { message: error.message } });
|
|
167
|
+
response.error = { message: error.message };
|
|
168
|
+
response.statusCode = 500;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (response?.headers && response.body && response.headers["content-type"]?.includes("json")) {
|
|
172
|
+
const parsedBody = JSON.parse(response.body);
|
|
173
|
+
response.data = parsedBody.data;
|
|
174
|
+
response.error = parsedBody.error;
|
|
175
|
+
}
|
|
176
|
+
if (this.http) {
|
|
177
|
+
response.cookie = this.http.cookie.content;
|
|
178
|
+
response.session = this.http.session.content;
|
|
179
|
+
}
|
|
180
|
+
this.logger.debug("response: %j", response);
|
|
181
|
+
return response;
|
|
182
|
+
}
|
|
279
183
|
};
|
|
184
|
+
/**
|
|
185
|
+
* A simple way to wrap a FaasJS function.
|
|
186
|
+
* @param initBy {Func} Full file path or a FaasJs function
|
|
187
|
+
*
|
|
188
|
+
* ```ts
|
|
189
|
+
* import { test } from '@faasjs/dev'
|
|
190
|
+
* import Func from '../demo.func.ts'
|
|
191
|
+
*
|
|
192
|
+
* const func = test(Func)
|
|
193
|
+
*
|
|
194
|
+
* expect(await func.handler()).toEqual('Hello, world')
|
|
195
|
+
* ```
|
|
196
|
+
*/
|
|
280
197
|
function test(initBy) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
198
|
+
const warper = new FuncWarper(initBy);
|
|
199
|
+
warper.mount = warper.mount.bind(warper);
|
|
200
|
+
warper.handler = warper.handler.bind(warper);
|
|
201
|
+
warper.JSONhandler = warper.JSONhandler.bind(warper);
|
|
202
|
+
return warper;
|
|
286
203
|
}
|
|
287
204
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
return process.env.FaasEnv || "development";
|
|
292
|
-
}
|
|
293
|
-
function resolveServerConfig(root, logger, defaultBase = "/") {
|
|
294
|
-
const projectRoot = path.resolve(root);
|
|
295
|
-
const staging = resolveFaasStaging();
|
|
296
|
-
const srcRoot = path.join(projectRoot, "src");
|
|
297
|
-
const config = load.loadConfig(
|
|
298
|
-
srcRoot,
|
|
299
|
-
path.join(srcRoot, "index.func.ts"),
|
|
300
|
-
staging,
|
|
301
|
-
logger
|
|
302
|
-
);
|
|
303
|
-
const server = config && typeof config === "object" ? config.server : void 0;
|
|
304
|
-
const resolvedRoot = server && typeof server.root === "string" && server.root.length ? path.resolve(projectRoot, server.root) : projectRoot;
|
|
305
|
-
const resolvedBase = server && typeof server.base === "string" && server.base.length ? server.base : defaultBase;
|
|
306
|
-
return {
|
|
307
|
-
root: resolvedRoot,
|
|
308
|
-
base: resolvedBase,
|
|
309
|
-
staging
|
|
310
|
-
};
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// src/typegen.ts
|
|
314
|
-
function normalizeSlashes(path) {
|
|
315
|
-
return path.replace(/\\/g, "/");
|
|
316
|
-
}
|
|
317
|
-
function normalizeRoute(path) {
|
|
318
|
-
const normalized = path.replace(/\/+/g, "/");
|
|
319
|
-
if (!normalized.length || normalized === "/") return "/";
|
|
320
|
-
return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
|
|
321
|
-
}
|
|
322
|
-
function toRoute(srcRoot, file) {
|
|
323
|
-
const relativePath = normalizeSlashes(path.relative(srcRoot, file));
|
|
324
|
-
const noTsPath = relativePath.replace(/\.ts$/, "");
|
|
325
|
-
if (noTsPath === "index.func") return { route: "/", priority: 2 };
|
|
326
|
-
if (noTsPath === "default.func") return { route: "/*", priority: 1 };
|
|
327
|
-
if (noTsPath.endsWith("/index.func"))
|
|
328
|
-
return {
|
|
329
|
-
route: normalizeRoute(`/${noTsPath.slice(0, -"/index.func".length)}`),
|
|
330
|
-
priority: 2
|
|
331
|
-
};
|
|
332
|
-
if (noTsPath.endsWith("/default.func"))
|
|
333
|
-
return {
|
|
334
|
-
route: normalizeRoute(`/${noTsPath.slice(0, -"/default.func".length)}/*`),
|
|
335
|
-
priority: 1
|
|
336
|
-
};
|
|
337
|
-
if (noTsPath.endsWith(".func"))
|
|
338
|
-
return {
|
|
339
|
-
route: normalizeRoute(`/${noTsPath.slice(0, -".func".length)}`),
|
|
340
|
-
priority: 3
|
|
341
|
-
};
|
|
342
|
-
throw Error(`[faas-types] Invalid func filename: ${file}`);
|
|
343
|
-
}
|
|
344
|
-
function toImportPath(fromFile, targetFile) {
|
|
345
|
-
const fromDir = path.dirname(fromFile);
|
|
346
|
-
const importPath = normalizeSlashes(path.relative(fromDir, targetFile)).replace(
|
|
347
|
-
/\.ts$/,
|
|
348
|
-
""
|
|
349
|
-
);
|
|
350
|
-
if (importPath.startsWith(".")) return importPath;
|
|
351
|
-
return `./${importPath}`;
|
|
352
|
-
}
|
|
353
|
-
function parsePluginTypes(config) {
|
|
354
|
-
const pluginConfig = config.plugins;
|
|
355
|
-
if (!pluginConfig || typeof pluginConfig !== "object") return [];
|
|
356
|
-
const pluginTypes = /* @__PURE__ */ new Set();
|
|
357
|
-
for (const key in pluginConfig) {
|
|
358
|
-
const data = pluginConfig[key];
|
|
359
|
-
if (typeof data === "string" && data.length) {
|
|
360
|
-
pluginTypes.add(data);
|
|
361
|
-
continue;
|
|
362
|
-
}
|
|
363
|
-
if (data && typeof data === "object") {
|
|
364
|
-
if (typeof data.type === "string" && data.type.length)
|
|
365
|
-
pluginTypes.add(data.type);
|
|
366
|
-
else pluginTypes.add(key);
|
|
367
|
-
continue;
|
|
368
|
-
}
|
|
369
|
-
pluginTypes.add(key);
|
|
370
|
-
}
|
|
371
|
-
return Array.from(pluginTypes).sort((a, b) => a.localeCompare(b));
|
|
372
|
-
}
|
|
373
|
-
async function readFuncFiles(dir) {
|
|
374
|
-
const result = [];
|
|
375
|
-
async function walk(currentDir) {
|
|
376
|
-
const entries = await promises.readdir(currentDir, {
|
|
377
|
-
withFileTypes: true
|
|
378
|
-
});
|
|
379
|
-
for (const entry of entries) {
|
|
380
|
-
if (entry.name === ".faasjs" || entry.name === "node_modules") continue;
|
|
381
|
-
const filePath = path.join(currentDir, entry.name);
|
|
382
|
-
if (entry.isDirectory()) {
|
|
383
|
-
await walk(filePath);
|
|
384
|
-
continue;
|
|
385
|
-
}
|
|
386
|
-
if (entry.isFile() && entry.name.endsWith(".func.ts"))
|
|
387
|
-
result.push(filePath);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
await walk(dir);
|
|
391
|
-
return result.sort((a, b) => a.localeCompare(b));
|
|
392
|
-
}
|
|
393
|
-
function formatTypes(items) {
|
|
394
|
-
const actionLines = items.map((item) => {
|
|
395
|
-
return ` ${JSON.stringify(item.route)}: __FaasFuncAction<__FaasModuleFunc<typeof import(${JSON.stringify(item.importPath)})>>`;
|
|
396
|
-
});
|
|
397
|
-
const eventLines = items.map((item) => {
|
|
398
|
-
const plugins = item.pluginTypes.length ? `[${item.pluginTypes.map((type) => JSON.stringify(type)).join(", ")}]` : "[]";
|
|
399
|
-
return ` ${JSON.stringify(item.route)}: InferPluginEvent<${plugins}>`;
|
|
400
|
-
});
|
|
401
|
-
return `/**
|
|
402
|
-
* Generated by @faasjs/dev.
|
|
403
|
-
*
|
|
404
|
-
* Do not edit this file manually.
|
|
405
|
-
*/
|
|
406
|
-
import type { Func, InferPluginEvent } from '@faasjs/func'
|
|
407
|
-
|
|
408
|
-
type __FaasModuleFunc<TModule> = TModule extends { func: infer TFunc }
|
|
409
|
-
? TFunc extends Func
|
|
410
|
-
? TFunc
|
|
411
|
-
: never
|
|
412
|
-
: TModule extends { default: infer TFunc }
|
|
413
|
-
? TFunc extends Func
|
|
414
|
-
? TFunc
|
|
415
|
-
: never
|
|
416
|
-
: never
|
|
417
|
-
|
|
418
|
-
type __FaasFuncAction<TFunc extends Func> = {
|
|
419
|
-
Params: Parameters<ReturnType<TFunc['export']>['handler']>[0]['params']
|
|
420
|
-
Data: Awaited<ReturnType<ReturnType<TFunc['export']>['handler']>>
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
declare module '@faasjs/types' {
|
|
424
|
-
interface FaasActions {
|
|
425
|
-
${actionLines.length ? `${actionLines.join("\n")}
|
|
426
|
-
` : ""} }
|
|
427
|
-
|
|
428
|
-
interface FaasEvents {
|
|
429
|
-
${eventLines.length ? `${eventLines.join("\n")}
|
|
430
|
-
` : ""} }
|
|
431
|
-
}
|
|
432
|
-
`;
|
|
433
|
-
}
|
|
434
|
-
function isTypegenSourceFile(filePath) {
|
|
435
|
-
return /\.func\.ts$/.test(filePath) || /(^|[\\/])faas\.ya?ml$/.test(filePath);
|
|
436
|
-
}
|
|
437
|
-
async function generateFaasTypes(options = {}) {
|
|
438
|
-
const logger$1 = options.logger || new logger.Logger("FaasJs:Typegen");
|
|
439
|
-
const { root: projectRoot, staging } = resolveServerConfig(
|
|
440
|
-
options.root || process.cwd(),
|
|
441
|
-
logger$1
|
|
442
|
-
);
|
|
443
|
-
const srcRoot = path.join(projectRoot, "src");
|
|
444
|
-
const output = path.join(srcRoot, ".faasjs", "types.d.ts");
|
|
445
|
-
if (!fs.existsSync(srcRoot))
|
|
446
|
-
throw Error(`[faas-types] Source directory not found: ${srcRoot}`);
|
|
447
|
-
const files = await readFuncFiles(srcRoot);
|
|
448
|
-
const routeMap = /* @__PURE__ */ new Map();
|
|
449
|
-
for (const file of files) {
|
|
450
|
-
const { route, priority } = toRoute(srcRoot, file);
|
|
451
|
-
const config = load.loadConfig(srcRoot, file, staging, logger$1);
|
|
452
|
-
const pluginTypes = parsePluginTypes(config);
|
|
453
|
-
const importPath = toImportPath(output, file);
|
|
454
|
-
const prev = routeMap.get(route);
|
|
455
|
-
if (!prev || priority > prev.priority)
|
|
456
|
-
routeMap.set(route, {
|
|
457
|
-
route,
|
|
458
|
-
importPath,
|
|
459
|
-
pluginTypes,
|
|
460
|
-
priority
|
|
461
|
-
});
|
|
462
|
-
}
|
|
463
|
-
const items = Array.from(routeMap.values()).sort(
|
|
464
|
-
(a, b) => a.route.localeCompare(b.route)
|
|
465
|
-
);
|
|
466
|
-
const content = formatTypes(items);
|
|
467
|
-
let changed = true;
|
|
468
|
-
try {
|
|
469
|
-
const previous = await promises.readFile(output, "utf8");
|
|
470
|
-
if (previous === content) changed = false;
|
|
471
|
-
} catch (_error) {
|
|
472
|
-
}
|
|
473
|
-
if (changed) {
|
|
474
|
-
await promises.mkdir(path.dirname(output), {
|
|
475
|
-
recursive: true
|
|
476
|
-
});
|
|
477
|
-
await promises.writeFile(output, content);
|
|
478
|
-
}
|
|
479
|
-
return {
|
|
480
|
-
output,
|
|
481
|
-
changed,
|
|
482
|
-
fileCount: files.length,
|
|
483
|
-
routeCount: items.length
|
|
484
|
-
};
|
|
485
|
-
}
|
|
486
|
-
var TYPEGEN_DEBOUNCE = 120;
|
|
205
|
+
//#endregion
|
|
206
|
+
//#region src/vite.ts
|
|
207
|
+
const TYPEGEN_DEBOUNCE = 120;
|
|
487
208
|
function normalizeBase(base) {
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
209
|
+
const normalized = base.startsWith("/") ? base : `/${base}`;
|
|
210
|
+
if (normalized === "/") return "/";
|
|
211
|
+
return normalized.endsWith("/") ? normalized.slice(0, -1) : normalized;
|
|
491
212
|
}
|
|
492
213
|
function stripBase(url, base) {
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
return url;
|
|
214
|
+
if (base === "/") return url;
|
|
215
|
+
const queryIndex = url.indexOf("?");
|
|
216
|
+
const pathname = queryIndex >= 0 ? url.slice(0, queryIndex) : url;
|
|
217
|
+
const search = queryIndex >= 0 ? url.slice(queryIndex) : "";
|
|
218
|
+
if (pathname === base) return `/${search}`;
|
|
219
|
+
if (pathname.startsWith(`${base}/`)) return `${pathname.slice(base.length)}${search}`;
|
|
220
|
+
return url;
|
|
501
221
|
}
|
|
222
|
+
/**
|
|
223
|
+
* Create a Vite plugin that proxies POST requests to an in-process FaasJS server.
|
|
224
|
+
*
|
|
225
|
+
* It resolves server root/base from `src/faas.yaml` and strips `base` from
|
|
226
|
+
* request URL before forwarding to `@faasjs/server`.
|
|
227
|
+
*/
|
|
502
228
|
function viteFaasJsServer() {
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
} catch (error) {
|
|
579
|
-
logger$1.error(error);
|
|
580
|
-
if (!res.headersSent && !res.writableEnded) {
|
|
581
|
-
res.writeHead(500, { "Content-Type": "application/json" });
|
|
582
|
-
res.write(
|
|
583
|
-
JSON.stringify({
|
|
584
|
-
error: { message: "Internal Server Error" }
|
|
585
|
-
})
|
|
586
|
-
);
|
|
587
|
-
res.end();
|
|
588
|
-
}
|
|
589
|
-
} finally {
|
|
590
|
-
req.url = originalUrl;
|
|
591
|
-
}
|
|
592
|
-
if (!res.writableEnded) next();
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
|
-
};
|
|
229
|
+
let config;
|
|
230
|
+
let server = null;
|
|
231
|
+
const logger = new _faasjs_logger.Logger("FaasJs:Vite");
|
|
232
|
+
return {
|
|
233
|
+
name: "vite:faasjs",
|
|
234
|
+
enforce: "pre",
|
|
235
|
+
configResolved(resolvedConfig) {
|
|
236
|
+
const serverConfig = require_typegen.resolveServerConfig(resolvedConfig.root, logger, resolvedConfig.base);
|
|
237
|
+
config = {
|
|
238
|
+
root: serverConfig.root,
|
|
239
|
+
base: normalizeBase(serverConfig.base)
|
|
240
|
+
};
|
|
241
|
+
},
|
|
242
|
+
configureServer: async ({ middlewares, watcher }) => {
|
|
243
|
+
if (process.env.VITEST) {
|
|
244
|
+
logger.debug("Skipping faas server in vitest environment");
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (!config) throw new Error("viteFaasJsServer: config is not resolved");
|
|
248
|
+
server = new _faasjs_server.Server((0, node_path.join)(config.root, "src"));
|
|
249
|
+
const runTypegen = async () => {
|
|
250
|
+
try {
|
|
251
|
+
const result = await require_typegen.generateFaasTypes({ root: config.root });
|
|
252
|
+
logger.debug("[faas-types] %s %s (%i routes)", result.changed ? "generated" : "up-to-date", result.output, result.routeCount);
|
|
253
|
+
} catch (error) {
|
|
254
|
+
logger.error("[faas-types] %s", error.message);
|
|
255
|
+
}
|
|
256
|
+
};
|
|
257
|
+
let timer = null;
|
|
258
|
+
let runningTypegen = false;
|
|
259
|
+
let pendingTypegen = false;
|
|
260
|
+
const flushTypegen = async () => {
|
|
261
|
+
if (runningTypegen || !pendingTypegen) return;
|
|
262
|
+
pendingTypegen = false;
|
|
263
|
+
runningTypegen = true;
|
|
264
|
+
try {
|
|
265
|
+
await runTypegen();
|
|
266
|
+
} finally {
|
|
267
|
+
runningTypegen = false;
|
|
268
|
+
if (pendingTypegen) flushTypegen();
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
const scheduleTypegen = () => {
|
|
272
|
+
pendingTypegen = true;
|
|
273
|
+
if (timer) clearTimeout(timer);
|
|
274
|
+
timer = setTimeout(() => {
|
|
275
|
+
flushTypegen();
|
|
276
|
+
}, TYPEGEN_DEBOUNCE);
|
|
277
|
+
};
|
|
278
|
+
await runTypegen();
|
|
279
|
+
watcher.on("all", (_eventName, filePath) => {
|
|
280
|
+
if (!require_typegen.isTypegenSourceFile(filePath)) return;
|
|
281
|
+
scheduleTypegen();
|
|
282
|
+
});
|
|
283
|
+
middlewares.use(async (req, res, next) => {
|
|
284
|
+
if (!req.url || req.method !== "POST" || !server) return next();
|
|
285
|
+
const originalUrl = req.url;
|
|
286
|
+
req.url = stripBase(req.url, config.base);
|
|
287
|
+
try {
|
|
288
|
+
logger.debug(`Request ${req.url}`);
|
|
289
|
+
await server.handle(req, res, { requestedAt: Date.now() });
|
|
290
|
+
} catch (error) {
|
|
291
|
+
logger.error(error);
|
|
292
|
+
if (!res.headersSent && !res.writableEnded) {
|
|
293
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
294
|
+
res.write(JSON.stringify({ error: { message: "Internal Server Error" } }));
|
|
295
|
+
res.end();
|
|
296
|
+
}
|
|
297
|
+
} finally {
|
|
298
|
+
req.url = originalUrl;
|
|
299
|
+
}
|
|
300
|
+
if (!res.writableEnded) next();
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
};
|
|
596
304
|
}
|
|
597
305
|
|
|
306
|
+
//#endregion
|
|
307
|
+
//#region src/index.ts
|
|
308
|
+
var src_exports = /* @__PURE__ */ __exportAll({
|
|
309
|
+
FuncWarper: () => FuncWarper,
|
|
310
|
+
generateFaasTypes: () => require_typegen.generateFaasTypes,
|
|
311
|
+
isTypegenSourceFile: () => require_typegen.isTypegenSourceFile,
|
|
312
|
+
streamToObject: () => _faasjs_node_utils.streamToObject,
|
|
313
|
+
streamToString: () => _faasjs_node_utils.streamToString,
|
|
314
|
+
streamToText: () => _faasjs_node_utils.streamToText,
|
|
315
|
+
test: () => test,
|
|
316
|
+
viteFaasJsServer: () => viteFaasJsServer
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
//#endregion
|
|
598
320
|
exports.FuncWarper = FuncWarper;
|
|
599
|
-
exports.
|
|
600
|
-
exports.
|
|
601
|
-
exports.
|
|
602
|
-
exports.
|
|
603
|
-
exports.
|
|
321
|
+
exports.generateFaasTypes = require_typegen.generateFaasTypes;
|
|
322
|
+
exports.isTypegenSourceFile = require_typegen.isTypegenSourceFile;
|
|
323
|
+
exports.streamToObject = _faasjs_node_utils.streamToObject;
|
|
324
|
+
exports.streamToString = _faasjs_node_utils.streamToString;
|
|
325
|
+
exports.streamToText = _faasjs_node_utils.streamToText;
|
|
604
326
|
exports.test = test;
|
|
605
|
-
exports.unmountFaasKnex = unmountFaasKnex;
|
|
606
327
|
exports.viteFaasJsServer = viteFaasJsServer;
|
|
328
|
+
var _faasjs_func = require("@faasjs/func");
|
|
329
|
+
Object.keys(_faasjs_func).forEach(function (k) {
|
|
330
|
+
if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
|
|
331
|
+
enumerable: true,
|
|
332
|
+
get: function () { return _faasjs_func[k]; }
|
|
333
|
+
});
|
|
334
|
+
});
|