@zero-server/sdk 0.9.1 → 0.9.2
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 -21
- package/README.md +460 -443
- package/index.js +414 -412
- package/lib/app.js +1172 -1172
- package/lib/auth/authorize.js +399 -399
- package/lib/auth/enrollment.js +367 -367
- package/lib/auth/index.js +57 -57
- package/lib/auth/jwt.js +731 -731
- package/lib/auth/oauth.js +362 -362
- package/lib/auth/session.js +588 -588
- package/lib/auth/trustedDevice.js +409 -409
- package/lib/auth/twoFactor.js +1150 -1150
- package/lib/auth/webauthn.js +946 -946
- package/lib/body/index.js +14 -14
- package/lib/body/json.js +109 -109
- package/lib/body/multipart.js +440 -440
- package/lib/body/raw.js +71 -71
- package/lib/body/rawBuffer.js +160 -160
- package/lib/body/sendError.js +25 -25
- package/lib/body/text.js +75 -75
- package/lib/body/typeMatch.js +41 -41
- package/lib/body/urlencoded.js +235 -235
- package/lib/cli.js +845 -845
- package/lib/cluster.js +666 -666
- package/lib/debug.js +372 -372
- package/lib/env/index.js +465 -465
- package/lib/errors.js +683 -683
- package/lib/fetch/index.js +256 -256
- package/lib/grpc/balancer.js +378 -378
- package/lib/grpc/call.js +708 -708
- package/lib/grpc/client.js +764 -764
- package/lib/grpc/codec.js +1221 -1221
- package/lib/grpc/credentials.js +398 -398
- package/lib/grpc/frame.js +262 -262
- package/lib/grpc/health.js +287 -287
- package/lib/grpc/index.js +121 -121
- package/lib/grpc/metadata.js +461 -461
- package/lib/grpc/proto.js +821 -821
- package/lib/grpc/reflection.js +590 -590
- package/lib/grpc/server.js +445 -445
- package/lib/grpc/status.js +118 -118
- package/lib/grpc/watch.js +173 -173
- package/lib/http/index.js +10 -10
- package/lib/http/request.js +727 -727
- package/lib/http/response.js +799 -799
- package/lib/lifecycle.js +557 -557
- package/lib/middleware/compress.js +230 -230
- package/lib/middleware/cookieParser.js +237 -237
- package/lib/middleware/cors.js +93 -93
- package/lib/middleware/csrf.js +137 -137
- package/lib/middleware/errorHandler.js +101 -101
- package/lib/middleware/helmet.js +175 -175
- package/lib/middleware/index.js +19 -17
- package/lib/middleware/logger.js +74 -74
- package/lib/middleware/rateLimit.js +88 -88
- package/lib/middleware/requestId.js +53 -53
- package/lib/middleware/static.js +326 -326
- package/lib/middleware/timeout.js +71 -71
- package/lib/middleware/validator.js +255 -255
- package/lib/observe/health.js +326 -326
- package/lib/observe/index.js +50 -50
- package/lib/observe/logger.js +359 -359
- package/lib/observe/metrics.js +805 -805
- package/lib/observe/tracing.js +592 -592
- package/lib/orm/adapters/json.js +290 -290
- package/lib/orm/adapters/memory.js +764 -764
- package/lib/orm/adapters/mongo.js +764 -764
- package/lib/orm/adapters/mysql.js +933 -933
- package/lib/orm/adapters/postgres.js +1144 -1144
- package/lib/orm/adapters/redis.js +1534 -1534
- package/lib/orm/adapters/sql-base.js +212 -212
- package/lib/orm/adapters/sqlite.js +858 -858
- package/lib/orm/audit.js +649 -649
- package/lib/orm/cache.js +394 -394
- package/lib/orm/geo.js +387 -387
- package/lib/orm/index.js +784 -784
- package/lib/orm/migrate.js +432 -432
- package/lib/orm/model.js +1706 -1706
- package/lib/orm/plugin.js +375 -375
- package/lib/orm/procedures.js +836 -836
- package/lib/orm/profiler.js +233 -233
- package/lib/orm/query.js +1772 -1772
- package/lib/orm/replicas.js +241 -241
- package/lib/orm/schema.js +307 -307
- package/lib/orm/search.js +380 -380
- package/lib/orm/seed/data/commerce.js +136 -136
- package/lib/orm/seed/data/internet.js +111 -111
- package/lib/orm/seed/data/locations.js +204 -204
- package/lib/orm/seed/data/names.js +338 -338
- package/lib/orm/seed/data/person.js +128 -128
- package/lib/orm/seed/data/phone.js +211 -211
- package/lib/orm/seed/data/words.js +134 -134
- package/lib/orm/seed/factory.js +178 -178
- package/lib/orm/seed/fake.js +1186 -1186
- package/lib/orm/seed/index.js +18 -18
- package/lib/orm/seed/rng.js +70 -70
- package/lib/orm/seed/seeder.js +124 -124
- package/lib/orm/seed/unique.js +68 -68
- package/lib/orm/snapshot.js +366 -366
- package/lib/orm/tenancy.js +605 -605
- package/lib/orm/views.js +350 -350
- package/lib/router/index.js +436 -436
- package/lib/sse/index.js +8 -8
- package/lib/sse/stream.js +349 -349
- package/lib/ws/connection.js +451 -451
- package/lib/ws/handshake.js +125 -125
- package/lib/ws/index.js +14 -14
- package/lib/ws/room.js +223 -223
- package/package.json +73 -73
- package/types/app.d.ts +223 -223
- package/types/auth.d.ts +520 -520
- package/types/cluster.d.ts +75 -75
- package/types/env.d.ts +80 -80
- package/types/errors.d.ts +316 -316
- package/types/fetch.d.ts +43 -43
- package/types/grpc.d.ts +432 -432
- package/types/index.d.ts +384 -384
- package/types/lifecycle.d.ts +60 -60
- package/types/middleware.d.ts +320 -320
- package/types/observe.d.ts +304 -304
- package/types/orm.d.ts +1887 -1887
- package/types/request.d.ts +109 -109
- package/types/response.d.ts +157 -157
- package/types/router.d.ts +78 -78
- package/types/sse.d.ts +78 -78
- package/types/websocket.d.ts +126 -126
package/lib/body/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module body
|
|
3
|
-
* @description Barrel export for all body-parsing utilities and middleware.
|
|
4
|
-
*/
|
|
5
|
-
const rawBuffer = require('./rawBuffer');
|
|
6
|
-
const isTypeMatch = require('./typeMatch');
|
|
7
|
-
const sendError = require('./sendError');
|
|
8
|
-
const json = require('./json');
|
|
9
|
-
const urlencoded = require('./urlencoded');
|
|
10
|
-
const text = require('./text');
|
|
11
|
-
const raw = require('./raw');
|
|
12
|
-
const multipart = require('./multipart');
|
|
13
|
-
|
|
14
|
-
module.exports = { rawBuffer, isTypeMatch, sendError, json, urlencoded, text, raw, multipart };
|
|
1
|
+
/**
|
|
2
|
+
* @module body
|
|
3
|
+
* @description Barrel export for all body-parsing utilities and middleware.
|
|
4
|
+
*/
|
|
5
|
+
const rawBuffer = require('./rawBuffer');
|
|
6
|
+
const isTypeMatch = require('./typeMatch');
|
|
7
|
+
const sendError = require('./sendError');
|
|
8
|
+
const json = require('./json');
|
|
9
|
+
const urlencoded = require('./urlencoded');
|
|
10
|
+
const text = require('./text');
|
|
11
|
+
const raw = require('./raw');
|
|
12
|
+
const multipart = require('./multipart');
|
|
13
|
+
|
|
14
|
+
module.exports = { rawBuffer, isTypeMatch, sendError, json, urlencoded, text, raw, multipart };
|
package/lib/body/json.js
CHANGED
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module body/json
|
|
3
|
-
* @description JSON body-parsing middleware.
|
|
4
|
-
* Reads the request body, parses it as JSON, and sets `req.body`.
|
|
5
|
-
* Stores the raw buffer on `req.rawBody` for signature verification.
|
|
6
|
-
*/
|
|
7
|
-
const rawBuffer = require('./rawBuffer');
|
|
8
|
-
const { charsetFromContentType } = require('./rawBuffer');
|
|
9
|
-
const isTypeMatch = require('./typeMatch');
|
|
10
|
-
const sendError = require('./sendError');
|
|
11
|
-
|
|
12
|
-
/** @private Recursively remove __proto__, constructor, and prototype keys to prevent prototype pollution. */
|
|
13
|
-
function _sanitize(obj)
|
|
14
|
-
{
|
|
15
|
-
if (!obj || typeof obj !== 'object') return;
|
|
16
|
-
const keys = Object.keys(obj);
|
|
17
|
-
for (let i = 0; i < keys.length; i++)
|
|
18
|
-
{
|
|
19
|
-
const k = keys[i];
|
|
20
|
-
if (k === '__proto__' || k === 'constructor' || k === 'prototype')
|
|
21
|
-
{
|
|
22
|
-
delete obj[k];
|
|
23
|
-
}
|
|
24
|
-
else if (typeof obj[k] === 'object' && obj[k] !== null)
|
|
25
|
-
{
|
|
26
|
-
_sanitize(obj[k]);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Create a JSON body-parsing middleware.
|
|
33
|
-
*
|
|
34
|
-
* @param {object} [options] - Configuration options.
|
|
35
|
-
* @param {string|number} [options.limit] - Max body size (e.g. `'10kb'`). Default `'1mb'`.
|
|
36
|
-
* @param {Function} [options.reviver] - `JSON.parse` reviver function.
|
|
37
|
-
* @param {boolean} [options.strict=true] - When true, reject non-object/array roots.
|
|
38
|
-
* @param {string|string[]|Function} [options.type='application/json'] - Content-Type(s) to match.
|
|
39
|
-
* @param {boolean} [options.requireSecure=false] - When true, reject non-HTTPS requests with 403.
|
|
40
|
-
* @param {Function} [options.verify] - `verify(req, res, buf, encoding)` — called before parsing. Throw to reject with 403.
|
|
41
|
-
* @param {boolean} [options.inflate=true] - Decompress gzip/deflate/br bodies. When false, compressed bodies return 415.
|
|
42
|
-
* @returns {Function} Async middleware `(req, res, next) => void`.
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* const { json } = require('@zero-server/sdk');
|
|
46
|
-
*
|
|
47
|
-
* app.use(json({ limit: '500kb', strict: true }));
|
|
48
|
-
*
|
|
49
|
-
* app.post('/api/data', (req, res) => {
|
|
50
|
-
* console.log(req.body); // parsed JSON object
|
|
51
|
-
* res.json({ ok: true });
|
|
52
|
-
* });
|
|
53
|
-
*/
|
|
54
|
-
function json(options = {})
|
|
55
|
-
{
|
|
56
|
-
const opts = options || {};
|
|
57
|
-
const limit = opts.limit !== undefined ? opts.limit : '1mb';
|
|
58
|
-
const reviver = opts.reviver;
|
|
59
|
-
const strict = (opts.hasOwnProperty('strict')) ? !!opts.strict : true;
|
|
60
|
-
const typeOpt = opts.type || 'application/json';
|
|
61
|
-
const requireSecure = !!opts.requireSecure;
|
|
62
|
-
const verify = opts.verify;
|
|
63
|
-
const inflate = opts.inflate !== undefined ? opts.inflate : true;
|
|
64
|
-
|
|
65
|
-
return async (req, res, next) =>
|
|
66
|
-
{
|
|
67
|
-
if (requireSecure && !req.secure) return sendError(res, 403, 'HTTPS required');
|
|
68
|
-
const ct = (req.headers['content-type'] || '');
|
|
69
|
-
if (!isTypeMatch(ct, typeOpt)) return next();
|
|
70
|
-
try
|
|
71
|
-
{
|
|
72
|
-
const buf = await rawBuffer(req, { limit, inflate });
|
|
73
|
-
const encoding = charsetFromContentType(ct) || 'utf8';
|
|
74
|
-
|
|
75
|
-
// Store raw body for webhook signature verification (Stripe, GitHub, etc.)
|
|
76
|
-
req.rawBody = buf;
|
|
77
|
-
|
|
78
|
-
// Optional verification callback (e.g. HMAC signature check)
|
|
79
|
-
if (verify)
|
|
80
|
-
{
|
|
81
|
-
try { verify(req, res, buf, encoding); }
|
|
82
|
-
catch (e) { return sendError(res, 403, e.message || 'verification failed'); }
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const txt = buf.toString(encoding);
|
|
86
|
-
if (!txt) { req.body = null; return next(); }
|
|
87
|
-
let parsed;
|
|
88
|
-
try { parsed = JSON.parse(txt, reviver); } catch (e) { return sendError(res, 400, 'invalid JSON'); }
|
|
89
|
-
if (strict && (typeof parsed !== 'object' || parsed === null))
|
|
90
|
-
{
|
|
91
|
-
return sendError(res, 400, 'invalid JSON: root must be object or array');
|
|
92
|
-
}
|
|
93
|
-
// Prevent prototype pollution
|
|
94
|
-
if (parsed && typeof parsed === 'object')
|
|
95
|
-
{
|
|
96
|
-
_sanitize(parsed);
|
|
97
|
-
}
|
|
98
|
-
req.body = parsed;
|
|
99
|
-
} catch (err)
|
|
100
|
-
{
|
|
101
|
-
if (err && err.status === 413) return sendError(res, 413, 'payload too large');
|
|
102
|
-
if (err && err.status === 415) return sendError(res, 415, err.message || 'unsupported encoding');
|
|
103
|
-
req.body = null;
|
|
104
|
-
}
|
|
105
|
-
next();
|
|
106
|
-
};
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
module.exports = json;
|
|
1
|
+
/**
|
|
2
|
+
* @module body/json
|
|
3
|
+
* @description JSON body-parsing middleware.
|
|
4
|
+
* Reads the request body, parses it as JSON, and sets `req.body`.
|
|
5
|
+
* Stores the raw buffer on `req.rawBody` for signature verification.
|
|
6
|
+
*/
|
|
7
|
+
const rawBuffer = require('./rawBuffer');
|
|
8
|
+
const { charsetFromContentType } = require('./rawBuffer');
|
|
9
|
+
const isTypeMatch = require('./typeMatch');
|
|
10
|
+
const sendError = require('./sendError');
|
|
11
|
+
|
|
12
|
+
/** @private Recursively remove __proto__, constructor, and prototype keys to prevent prototype pollution. */
|
|
13
|
+
function _sanitize(obj)
|
|
14
|
+
{
|
|
15
|
+
if (!obj || typeof obj !== 'object') return;
|
|
16
|
+
const keys = Object.keys(obj);
|
|
17
|
+
for (let i = 0; i < keys.length; i++)
|
|
18
|
+
{
|
|
19
|
+
const k = keys[i];
|
|
20
|
+
if (k === '__proto__' || k === 'constructor' || k === 'prototype')
|
|
21
|
+
{
|
|
22
|
+
delete obj[k];
|
|
23
|
+
}
|
|
24
|
+
else if (typeof obj[k] === 'object' && obj[k] !== null)
|
|
25
|
+
{
|
|
26
|
+
_sanitize(obj[k]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Create a JSON body-parsing middleware.
|
|
33
|
+
*
|
|
34
|
+
* @param {object} [options] - Configuration options.
|
|
35
|
+
* @param {string|number} [options.limit] - Max body size (e.g. `'10kb'`). Default `'1mb'`.
|
|
36
|
+
* @param {Function} [options.reviver] - `JSON.parse` reviver function.
|
|
37
|
+
* @param {boolean} [options.strict=true] - When true, reject non-object/array roots.
|
|
38
|
+
* @param {string|string[]|Function} [options.type='application/json'] - Content-Type(s) to match.
|
|
39
|
+
* @param {boolean} [options.requireSecure=false] - When true, reject non-HTTPS requests with 403.
|
|
40
|
+
* @param {Function} [options.verify] - `verify(req, res, buf, encoding)` — called before parsing. Throw to reject with 403.
|
|
41
|
+
* @param {boolean} [options.inflate=true] - Decompress gzip/deflate/br bodies. When false, compressed bodies return 415.
|
|
42
|
+
* @returns {Function} Async middleware `(req, res, next) => void`.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* const { json } = require('@zero-server/sdk');
|
|
46
|
+
*
|
|
47
|
+
* app.use(json({ limit: '500kb', strict: true }));
|
|
48
|
+
*
|
|
49
|
+
* app.post('/api/data', (req, res) => {
|
|
50
|
+
* console.log(req.body); // parsed JSON object
|
|
51
|
+
* res.json({ ok: true });
|
|
52
|
+
* });
|
|
53
|
+
*/
|
|
54
|
+
function json(options = {})
|
|
55
|
+
{
|
|
56
|
+
const opts = options || {};
|
|
57
|
+
const limit = opts.limit !== undefined ? opts.limit : '1mb';
|
|
58
|
+
const reviver = opts.reviver;
|
|
59
|
+
const strict = (opts.hasOwnProperty('strict')) ? !!opts.strict : true;
|
|
60
|
+
const typeOpt = opts.type || 'application/json';
|
|
61
|
+
const requireSecure = !!opts.requireSecure;
|
|
62
|
+
const verify = opts.verify;
|
|
63
|
+
const inflate = opts.inflate !== undefined ? opts.inflate : true;
|
|
64
|
+
|
|
65
|
+
return async (req, res, next) =>
|
|
66
|
+
{
|
|
67
|
+
if (requireSecure && !req.secure) return sendError(res, 403, 'HTTPS required');
|
|
68
|
+
const ct = (req.headers['content-type'] || '');
|
|
69
|
+
if (!isTypeMatch(ct, typeOpt)) return next();
|
|
70
|
+
try
|
|
71
|
+
{
|
|
72
|
+
const buf = await rawBuffer(req, { limit, inflate });
|
|
73
|
+
const encoding = charsetFromContentType(ct) || 'utf8';
|
|
74
|
+
|
|
75
|
+
// Store raw body for webhook signature verification (Stripe, GitHub, etc.)
|
|
76
|
+
req.rawBody = buf;
|
|
77
|
+
|
|
78
|
+
// Optional verification callback (e.g. HMAC signature check)
|
|
79
|
+
if (verify)
|
|
80
|
+
{
|
|
81
|
+
try { verify(req, res, buf, encoding); }
|
|
82
|
+
catch (e) { return sendError(res, 403, e.message || 'verification failed'); }
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const txt = buf.toString(encoding);
|
|
86
|
+
if (!txt) { req.body = null; return next(); }
|
|
87
|
+
let parsed;
|
|
88
|
+
try { parsed = JSON.parse(txt, reviver); } catch (e) { return sendError(res, 400, 'invalid JSON'); }
|
|
89
|
+
if (strict && (typeof parsed !== 'object' || parsed === null))
|
|
90
|
+
{
|
|
91
|
+
return sendError(res, 400, 'invalid JSON: root must be object or array');
|
|
92
|
+
}
|
|
93
|
+
// Prevent prototype pollution
|
|
94
|
+
if (parsed && typeof parsed === 'object')
|
|
95
|
+
{
|
|
96
|
+
_sanitize(parsed);
|
|
97
|
+
}
|
|
98
|
+
req.body = parsed;
|
|
99
|
+
} catch (err)
|
|
100
|
+
{
|
|
101
|
+
if (err && err.status === 413) return sendError(res, 413, 'payload too large');
|
|
102
|
+
if (err && err.status === 415) return sendError(res, 415, err.message || 'unsupported encoding');
|
|
103
|
+
req.body = null;
|
|
104
|
+
}
|
|
105
|
+
next();
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
module.exports = json;
|