@zero-server/sdk 0.9.1 → 0.9.3
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/body.d.ts +14 -0
- package/types/cli.d.ts +2 -0
- 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/orm/seed/index.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @module seed/index
|
|
5
|
-
* @description Public API for the seed subsystem.
|
|
6
|
-
*
|
|
7
|
-
* Re-exports:
|
|
8
|
-
* - `Fake` — static fake-data generator
|
|
9
|
-
* - `Factory` — model factory for defining / creating test fixtures
|
|
10
|
-
* - `Seeder` — base class for database seeders
|
|
11
|
-
* - `SeederRunner` — orchestrates running multiple seeders
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const { Fake } = require('./fake');
|
|
15
|
-
const { Factory } = require('./factory');
|
|
16
|
-
const { Seeder, SeederRunner } = require('./seeder');
|
|
17
|
-
|
|
18
|
-
module.exports = { Fake, Factory, Seeder, SeederRunner };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module seed/index
|
|
5
|
+
* @description Public API for the seed subsystem.
|
|
6
|
+
*
|
|
7
|
+
* Re-exports:
|
|
8
|
+
* - `Fake` — static fake-data generator
|
|
9
|
+
* - `Factory` — model factory for defining / creating test fixtures
|
|
10
|
+
* - `Seeder` — base class for database seeders
|
|
11
|
+
* - `SeederRunner` — orchestrates running multiple seeders
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const { Fake } = require('./fake');
|
|
15
|
+
const { Factory } = require('./factory');
|
|
16
|
+
const { Seeder, SeederRunner } = require('./seeder');
|
|
17
|
+
|
|
18
|
+
module.exports = { Fake, Factory, Seeder, SeederRunner };
|
package/lib/orm/seed/rng.js
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @module seed/rng
|
|
5
|
-
* @description Seeded PRNG (mulberry32) for reproducible fake data generation.
|
|
6
|
-
* When no seed is set, falls back to Math.random so default
|
|
7
|
-
* behaviour is indistinguishable from the original implementation.
|
|
8
|
-
*
|
|
9
|
-
* @example
|
|
10
|
-
* const { seed, rand } = require('./rng');
|
|
11
|
-
* seed(42); // deterministic from here on
|
|
12
|
-
* rand(); // always the same sequence for seed 42
|
|
13
|
-
* seed(null); // back to crypto-quality Math.random
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* mulberry32 — minimal, high-quality 32-bit PRNG.
|
|
18
|
-
* @param {number} s - Unsigned 32-bit integer seed.
|
|
19
|
-
* @returns {() => number} Float in [0, 1).
|
|
20
|
-
*/
|
|
21
|
-
function _mulberry32(s) {
|
|
22
|
-
s = s >>> 0;
|
|
23
|
-
return function () {
|
|
24
|
-
s += 0x6D2B79F5;
|
|
25
|
-
let t = s;
|
|
26
|
-
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
27
|
-
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
28
|
-
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** FNV-1a string → unsigned 32-bit integer. */
|
|
33
|
-
function _hashString(str) {
|
|
34
|
-
let h = 0x811c9dc5;
|
|
35
|
-
for (let i = 0; i < str.length; i++) {
|
|
36
|
-
h ^= str.charCodeAt(i);
|
|
37
|
-
h = Math.imul(h, 0x01000193);
|
|
38
|
-
}
|
|
39
|
-
return h >>> 0;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
let _rng = Math.random.bind(Math);
|
|
43
|
-
let _seed = null;
|
|
44
|
-
|
|
45
|
-
/** Return a random float in [0, 1). */
|
|
46
|
-
function rand() { return _rng(); }
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Set a deterministic seed. Pass `null` / `undefined` to reset to Math.random.
|
|
50
|
-
*
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module seed/rng
|
|
5
|
+
* @description Seeded PRNG (mulberry32) for reproducible fake data generation.
|
|
6
|
+
* When no seed is set, falls back to Math.random so default
|
|
7
|
+
* behaviour is indistinguishable from the original implementation.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* const { seed, rand } = require('./rng');
|
|
11
|
+
* seed(42); // deterministic from here on
|
|
12
|
+
* rand(); // always the same sequence for seed 42
|
|
13
|
+
* seed(null); // back to crypto-quality Math.random
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* mulberry32 — minimal, high-quality 32-bit PRNG.
|
|
18
|
+
* @param {number} s - Unsigned 32-bit integer seed.
|
|
19
|
+
* @returns {() => number} Float in [0, 1).
|
|
20
|
+
*/
|
|
21
|
+
function _mulberry32(s) {
|
|
22
|
+
s = s >>> 0;
|
|
23
|
+
return function () {
|
|
24
|
+
s += 0x6D2B79F5;
|
|
25
|
+
let t = s;
|
|
26
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
27
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
28
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** FNV-1a string → unsigned 32-bit integer. */
|
|
33
|
+
function _hashString(str) {
|
|
34
|
+
let h = 0x811c9dc5;
|
|
35
|
+
for (let i = 0; i < str.length; i++) {
|
|
36
|
+
h ^= str.charCodeAt(i);
|
|
37
|
+
h = Math.imul(h, 0x01000193);
|
|
38
|
+
}
|
|
39
|
+
return h >>> 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
let _rng = Math.random.bind(Math);
|
|
43
|
+
let _seed = null;
|
|
44
|
+
|
|
45
|
+
/** Return a random float in [0, 1). */
|
|
46
|
+
function rand() { return _rng(); }
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set a deterministic seed. Pass `null` / `undefined` to reset to Math.random.
|
|
50
|
+
*
|
|
51
51
|
* @param {number|string|null} [value] - Value to set.
|
|
52
|
-
* @returns {number|null} The numeric seed that was applied (or null if reset).
|
|
53
|
-
*/
|
|
54
|
-
function seed(value) {
|
|
55
|
-
if (value === undefined || value === null) {
|
|
56
|
-
_rng = Math.random.bind(Math);
|
|
57
|
-
_seed = null;
|
|
58
|
-
} else {
|
|
59
|
-
const n = typeof value === 'number'
|
|
60
|
-
? (value >>> 0)
|
|
61
|
-
: _hashString(String(value));
|
|
62
|
-
_seed = n;
|
|
63
|
-
_rng = _mulberry32(n);
|
|
64
|
-
}
|
|
65
|
-
return _seed;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/** @returns {number|null} Active numeric seed, or null when using Math.random. */
|
|
69
|
-
function getSeed() { return _seed; }
|
|
70
|
-
|
|
71
|
-
module.exports = { rand, seed, getSeed };
|
|
52
|
+
* @returns {number|null} The numeric seed that was applied (or null if reset).
|
|
53
|
+
*/
|
|
54
|
+
function seed(value) {
|
|
55
|
+
if (value === undefined || value === null) {
|
|
56
|
+
_rng = Math.random.bind(Math);
|
|
57
|
+
_seed = null;
|
|
58
|
+
} else {
|
|
59
|
+
const n = typeof value === 'number'
|
|
60
|
+
? (value >>> 0)
|
|
61
|
+
: _hashString(String(value));
|
|
62
|
+
_seed = n;
|
|
63
|
+
_rng = _mulberry32(n);
|
|
64
|
+
}
|
|
65
|
+
return _seed;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** @returns {number|null} Active numeric seed, or null when using Math.random. */
|
|
69
|
+
function getSeed() { return _seed; }
|
|
70
|
+
|
|
71
|
+
module.exports = { rand, seed, getSeed };
|
package/lib/orm/seed/seeder.js
CHANGED
|
@@ -1,125 +1,125 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @module seed/seeder
|
|
5
|
-
* @description Base Seeder class and SeederRunner for orchestrating database
|
|
6
|
-
* seeding operations.
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* class UserSeeder extends Seeder {
|
|
10
|
-
* async run(db) {
|
|
11
|
-
* const factory = new Factory(User);
|
|
12
|
-
* factory.define({ name: () => Fake.fullName(), email: () => Fake.email() });
|
|
13
|
-
* await factory.count(50).create();
|
|
14
|
-
* }
|
|
15
|
-
* }
|
|
16
|
-
*
|
|
17
|
-
* const runner = new SeederRunner(db);
|
|
18
|
-
* await runner.run(UserSeeder, PostSeeder);
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
const log = require('../../debug')('zero:seed');
|
|
22
|
-
|
|
23
|
-
// ================================================================
|
|
24
|
-
// Seeder base class
|
|
25
|
-
// ================================================================
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Extend this class to create a seeder. Override `run(db)` with your
|
|
29
|
-
* seeding logic.
|
|
30
|
-
*/
|
|
31
|
-
class Seeder
|
|
32
|
-
{
|
|
33
|
-
/**
|
|
34
|
-
* Run the seeder. Must be overridden in subclasses.
|
|
35
|
-
*
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module seed/seeder
|
|
5
|
+
* @description Base Seeder class and SeederRunner for orchestrating database
|
|
6
|
+
* seeding operations.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* class UserSeeder extends Seeder {
|
|
10
|
+
* async run(db) {
|
|
11
|
+
* const factory = new Factory(User);
|
|
12
|
+
* factory.define({ name: () => Fake.fullName(), email: () => Fake.email() });
|
|
13
|
+
* await factory.count(50).create();
|
|
14
|
+
* }
|
|
15
|
+
* }
|
|
16
|
+
*
|
|
17
|
+
* const runner = new SeederRunner(db);
|
|
18
|
+
* await runner.run(UserSeeder, PostSeeder);
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const log = require('../../debug')('zero:seed');
|
|
22
|
+
|
|
23
|
+
// ================================================================
|
|
24
|
+
// Seeder base class
|
|
25
|
+
// ================================================================
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Extend this class to create a seeder. Override `run(db)` with your
|
|
29
|
+
* seeding logic.
|
|
30
|
+
*/
|
|
31
|
+
class Seeder
|
|
32
|
+
{
|
|
33
|
+
/**
|
|
34
|
+
* Run the seeder. Must be overridden in subclasses.
|
|
35
|
+
*
|
|
36
36
|
* @param {import('../index').Database} db - Database instance.
|
|
37
|
-
* @returns {Promise<void>}
|
|
38
|
-
*/
|
|
39
|
-
async run(db) // eslint-disable-line no-unused-vars
|
|
40
|
-
{
|
|
41
|
-
throw new Error(`Seeder ${this.constructor.name}: run() is not implemented`);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// ================================================================
|
|
46
|
-
// SeederRunner
|
|
47
|
-
// ================================================================
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Orchestrates running one or more seeders against a database connection.
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* const runner = new SeederRunner(db);
|
|
54
|
-
* await runner.run(UserSeeder, PostSeeder);
|
|
55
|
-
* await runner.call(UserSeeder); // single seeder
|
|
56
|
-
* await runner.fresh(UserSeeder); // clear then seed
|
|
57
|
-
*/
|
|
58
|
-
class SeederRunner
|
|
59
|
-
{
|
|
60
|
-
/**
|
|
61
|
-
* @constructor
|
|
62
|
-
* @param {import('../index').Database} db - Database connection instance.
|
|
63
|
-
*/
|
|
64
|
-
constructor(db)
|
|
65
|
-
{
|
|
66
|
-
this._db = db;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Run one or more seeder classes (or instances) in order.
|
|
71
|
-
*
|
|
72
|
-
* @param {...(Function|Function[])} seeders - Seeder classes or instances.
|
|
73
|
-
* @returns {Promise<string[]>} Names of the seeders that ran.
|
|
74
|
-
*/
|
|
75
|
-
async run(...seeders)
|
|
76
|
-
{
|
|
77
|
-
const flat = seeders.flat();
|
|
78
|
-
const names = [];
|
|
79
|
-
|
|
80
|
-
for (const SeederClass of flat)
|
|
81
|
-
{
|
|
82
|
-
const instance = typeof SeederClass === 'function'
|
|
83
|
-
? new SeederClass()
|
|
84
|
-
: SeederClass;
|
|
85
|
-
|
|
86
|
-
const name = instance.constructor.name || 'AnonymousSeeder';
|
|
87
|
-
log('Seeding: %s', name);
|
|
88
|
-
|
|
89
|
-
await instance.run(this._db);
|
|
90
|
-
names.push(name);
|
|
91
|
-
|
|
92
|
-
log('Seeded: %s', name);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return names;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Run a single seeder class or instance.
|
|
100
|
-
*
|
|
101
|
-
* @param {Function} SeederClass - Seeder class or instance to run.
|
|
102
|
-
* @returns {Promise<void>}
|
|
103
|
-
*/
|
|
104
|
-
async call(SeederClass)
|
|
105
|
-
{
|
|
106
|
-
await this.run(SeederClass);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
* Clear all adapter data then run the provided seeders.
|
|
111
|
-
* Works with adapters that expose a `clear()` method (memory, json, redis).
|
|
112
|
-
*
|
|
113
|
-
* @param {...Function} seeders - Seeder classes to run after clearing.
|
|
114
|
-
* @returns {Promise<string[]>} Names of the seeders that ran.
|
|
115
|
-
*/
|
|
116
|
-
async fresh(...seeders)
|
|
117
|
-
{
|
|
118
|
-
if (typeof this._db.adapter.clear === 'function')
|
|
119
|
-
await this._db.adapter.clear();
|
|
120
|
-
|
|
121
|
-
return this.run(...seeders);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
module.exports = { Seeder, SeederRunner };
|
|
37
|
+
* @returns {Promise<void>}
|
|
38
|
+
*/
|
|
39
|
+
async run(db) // eslint-disable-line no-unused-vars
|
|
40
|
+
{
|
|
41
|
+
throw new Error(`Seeder ${this.constructor.name}: run() is not implemented`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// ================================================================
|
|
46
|
+
// SeederRunner
|
|
47
|
+
// ================================================================
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Orchestrates running one or more seeders against a database connection.
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* const runner = new SeederRunner(db);
|
|
54
|
+
* await runner.run(UserSeeder, PostSeeder);
|
|
55
|
+
* await runner.call(UserSeeder); // single seeder
|
|
56
|
+
* await runner.fresh(UserSeeder); // clear then seed
|
|
57
|
+
*/
|
|
58
|
+
class SeederRunner
|
|
59
|
+
{
|
|
60
|
+
/**
|
|
61
|
+
* @constructor
|
|
62
|
+
* @param {import('../index').Database} db - Database connection instance.
|
|
63
|
+
*/
|
|
64
|
+
constructor(db)
|
|
65
|
+
{
|
|
66
|
+
this._db = db;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Run one or more seeder classes (or instances) in order.
|
|
71
|
+
*
|
|
72
|
+
* @param {...(Function|Function[])} seeders - Seeder classes or instances.
|
|
73
|
+
* @returns {Promise<string[]>} Names of the seeders that ran.
|
|
74
|
+
*/
|
|
75
|
+
async run(...seeders)
|
|
76
|
+
{
|
|
77
|
+
const flat = seeders.flat();
|
|
78
|
+
const names = [];
|
|
79
|
+
|
|
80
|
+
for (const SeederClass of flat)
|
|
81
|
+
{
|
|
82
|
+
const instance = typeof SeederClass === 'function'
|
|
83
|
+
? new SeederClass()
|
|
84
|
+
: SeederClass;
|
|
85
|
+
|
|
86
|
+
const name = instance.constructor.name || 'AnonymousSeeder';
|
|
87
|
+
log('Seeding: %s', name);
|
|
88
|
+
|
|
89
|
+
await instance.run(this._db);
|
|
90
|
+
names.push(name);
|
|
91
|
+
|
|
92
|
+
log('Seeded: %s', name);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
return names;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Run a single seeder class or instance.
|
|
100
|
+
*
|
|
101
|
+
* @param {Function} SeederClass - Seeder class or instance to run.
|
|
102
|
+
* @returns {Promise<void>}
|
|
103
|
+
*/
|
|
104
|
+
async call(SeederClass)
|
|
105
|
+
{
|
|
106
|
+
await this.run(SeederClass);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Clear all adapter data then run the provided seeders.
|
|
111
|
+
* Works with adapters that expose a `clear()` method (memory, json, redis).
|
|
112
|
+
*
|
|
113
|
+
* @param {...Function} seeders - Seeder classes to run after clearing.
|
|
114
|
+
* @returns {Promise<string[]>} Names of the seeders that ran.
|
|
115
|
+
*/
|
|
116
|
+
async fresh(...seeders)
|
|
117
|
+
{
|
|
118
|
+
if (typeof this._db.adapter.clear === 'function')
|
|
119
|
+
await this._db.adapter.clear();
|
|
120
|
+
|
|
121
|
+
return this.run(...seeders);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
module.exports = { Seeder, SeederRunner };
|
package/lib/orm/seed/unique.js
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @module seed/unique
|
|
5
|
-
* @description Per-namespace deduplication tracker used by `Fake.unique()`.
|
|
6
|
-
* Keeps a `Set` of already-returned values per key and retries
|
|
7
|
-
* the generator until a fresh value is produced.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const DEFAULT_MAX_ATTEMPTS = 1000;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Tracks generated values per namespace so callers can guarantee uniqueness
|
|
14
|
-
* within a seeding session without maintaining external state.
|
|
15
|
-
*/
|
|
16
|
-
class UniqueTracker {
|
|
17
|
-
constructor() {
|
|
18
|
-
/** @type {Map<string, Set<any>>} */
|
|
19
|
-
this._store = new Map();
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Call `fn()` repeatedly until it returns a value not yet seen under `key`.
|
|
24
|
-
*
|
|
25
|
-
* @param {string} key - Uniqueness namespace (e.g. `'email'`).
|
|
26
|
-
* @param {() => any} fn - Value generator.
|
|
27
|
-
* @param {number} [maxAttempts] - Give up after this many retries.
|
|
28
|
-
* @returns {any} The unique generated value.
|
|
29
|
-
* @throws {Error} When the generator pool is exhausted.
|
|
30
|
-
*/
|
|
31
|
-
generate(key, fn, maxAttempts = DEFAULT_MAX_ATTEMPTS) {
|
|
32
|
-
if (!this._store.has(key)) this._store.set(key, new Set());
|
|
33
|
-
const seen = this._store.get(key);
|
|
34
|
-
|
|
35
|
-
for (let i = 0; i < maxAttempts; i++) {
|
|
36
|
-
const val = fn();
|
|
37
|
-
if (!seen.has(val)) {
|
|
38
|
-
seen.add(val);
|
|
39
|
-
return val;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
throw new Error(
|
|
44
|
-
`Fake.unique: exhausted ${maxAttempts} attempts for key "${key}". ` +
|
|
45
|
-
`The data pool may be too small. Call Fake.resetUnique("${key}") to start fresh.`
|
|
46
|
-
);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Clear uniqueness tracking.
|
|
51
|
-
* @param {string} [key] - Clear only this namespace, or all if omitted.
|
|
52
|
-
*/
|
|
53
|
-
reset(key) {
|
|
54
|
-
if (key !== undefined) this._store.delete(key);
|
|
55
|
-
else this._store.clear();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* How many unique values have been generated for a namespace.
|
|
60
|
-
* @param {string} key - Cache or storage key.
|
|
61
|
-
* @returns {number} Count of unique values tracked for the key.
|
|
62
|
-
*/
|
|
63
|
-
seen(key) {
|
|
64
|
-
return this._store.has(key) ? this._store.get(key).size : 0;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
module.exports = { UniqueTracker };
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @module seed/unique
|
|
5
|
+
* @description Per-namespace deduplication tracker used by `Fake.unique()`.
|
|
6
|
+
* Keeps a `Set` of already-returned values per key and retries
|
|
7
|
+
* the generator until a fresh value is produced.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const DEFAULT_MAX_ATTEMPTS = 1000;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Tracks generated values per namespace so callers can guarantee uniqueness
|
|
14
|
+
* within a seeding session without maintaining external state.
|
|
15
|
+
*/
|
|
16
|
+
class UniqueTracker {
|
|
17
|
+
constructor() {
|
|
18
|
+
/** @type {Map<string, Set<any>>} */
|
|
19
|
+
this._store = new Map();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Call `fn()` repeatedly until it returns a value not yet seen under `key`.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} key - Uniqueness namespace (e.g. `'email'`).
|
|
26
|
+
* @param {() => any} fn - Value generator.
|
|
27
|
+
* @param {number} [maxAttempts] - Give up after this many retries.
|
|
28
|
+
* @returns {any} The unique generated value.
|
|
29
|
+
* @throws {Error} When the generator pool is exhausted.
|
|
30
|
+
*/
|
|
31
|
+
generate(key, fn, maxAttempts = DEFAULT_MAX_ATTEMPTS) {
|
|
32
|
+
if (!this._store.has(key)) this._store.set(key, new Set());
|
|
33
|
+
const seen = this._store.get(key);
|
|
34
|
+
|
|
35
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
36
|
+
const val = fn();
|
|
37
|
+
if (!seen.has(val)) {
|
|
38
|
+
seen.add(val);
|
|
39
|
+
return val;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
throw new Error(
|
|
44
|
+
`Fake.unique: exhausted ${maxAttempts} attempts for key "${key}". ` +
|
|
45
|
+
`The data pool may be too small. Call Fake.resetUnique("${key}") to start fresh.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Clear uniqueness tracking.
|
|
51
|
+
* @param {string} [key] - Clear only this namespace, or all if omitted.
|
|
52
|
+
*/
|
|
53
|
+
reset(key) {
|
|
54
|
+
if (key !== undefined) this._store.delete(key);
|
|
55
|
+
else this._store.clear();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* How many unique values have been generated for a namespace.
|
|
60
|
+
* @param {string} key - Cache or storage key.
|
|
61
|
+
* @returns {number} Count of unique values tracked for the key.
|
|
62
|
+
*/
|
|
63
|
+
seen(key) {
|
|
64
|
+
return this._store.has(key) ? this._store.get(key).size : 0;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
module.exports = { UniqueTracker };
|