loredata 0.1.0
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 +9 -0
- package/README.md +119 -0
- package/data/breaking-bad/addresses.json +37 -0
- package/data/breaking-bad/characters.json +120 -0
- package/data/breaking-bad/domains.json +6 -0
- package/data/breaking-bad/meta.json +4 -0
- package/data/fast-and-furious/addresses.json +28 -0
- package/data/fast-and-furious/characters.json +115 -0
- package/data/fast-and-furious/domains.json +6 -0
- package/data/fast-and-furious/meta.json +4 -0
- package/data/friends/addresses.json +34 -0
- package/data/friends/characters.json +176 -0
- package/data/friends/domains.json +6 -0
- package/data/friends/meta.json +1 -0
- package/data/game-of-thrones/addresses.json +37 -0
- package/data/game-of-thrones/characters.json +270 -0
- package/data/game-of-thrones/domains.json +6 -0
- package/data/game-of-thrones/meta.json +4 -0
- package/data/harry-potter/addresses.json +37 -0
- package/data/harry-potter/characters.json +125 -0
- package/data/harry-potter/domains.json +6 -0
- package/data/harry-potter/meta.json +4 -0
- package/data/house-md/addresses.json +32 -0
- package/data/house-md/characters.json +213 -0
- package/data/house-md/domains.json +6 -0
- package/data/house-md/meta.json +1 -0
- package/data/lost/addresses.json +31 -0
- package/data/lost/characters.json +204 -0
- package/data/lost/domains.json +6 -0
- package/data/lost/meta.json +1 -0
- package/data/matrix/addresses.json +6 -0
- package/data/matrix/characters.json +194 -0
- package/data/matrix/domains.json +6 -0
- package/data/matrix/meta.json +1 -0
- package/data/peaky-blinders/addresses.json +26 -0
- package/data/peaky-blinders/characters.json +198 -0
- package/data/peaky-blinders/domains.json +6 -0
- package/data/peaky-blinders/meta.json +1 -0
- package/data/sherlock/addresses.json +31 -0
- package/data/sherlock/characters.json +184 -0
- package/data/sherlock/domains.json +6 -0
- package/data/sherlock/meta.json +1 -0
- package/data/the-office/addresses.json +30 -0
- package/data/the-office/characters.json +244 -0
- package/data/the-office/domains.json +6 -0
- package/data/the-office/meta.json +4 -0
- package/dist/browser.cjs +321 -0
- package/dist/browser.cjs.map +1 -0
- package/dist/browser.d.cts +11 -0
- package/dist/browser.d.ts +11 -0
- package/dist/browser.js +288 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli/cli.cjs +390 -0
- package/dist/cli/cli.cjs.map +1 -0
- package/dist/cli/cli.d.cts +1 -0
- package/dist/cli/cli.d.ts +1 -0
- package/dist/cli/cli.js +388 -0
- package/dist/cli/cli.js.map +1 -0
- package/dist/index.cjs +356 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +26 -0
- package/dist/index.d.ts +26 -0
- package/dist/index.js +323 -0
- package/dist/index.js.map +1 -0
- package/dist/universe-store-DJrm7bP7.d.cts +98 -0
- package/dist/universe-store-DJrm7bP7.d.ts +98 -0
- package/package.json +77 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
// src/universes/loader.ts
|
|
2
|
+
import { readFileSync, readdirSync } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
var dataDir = join(import.meta.dirname, "../data");
|
|
5
|
+
var UniverseLoader = class {
|
|
6
|
+
static cache = /* @__PURE__ */ new Map();
|
|
7
|
+
static register(data) {
|
|
8
|
+
this.cache.set(data.id, data);
|
|
9
|
+
}
|
|
10
|
+
static load(universeId) {
|
|
11
|
+
const cached = this.cache.get(universeId);
|
|
12
|
+
if (cached) {
|
|
13
|
+
return cached;
|
|
14
|
+
}
|
|
15
|
+
const universeDir = join(dataDir, universeId);
|
|
16
|
+
const meta = JSON.parse(readFileSync(join(universeDir, "meta.json"), "utf-8"));
|
|
17
|
+
const characters = JSON.parse(readFileSync(join(universeDir, "characters.json"), "utf-8"));
|
|
18
|
+
const addresses = JSON.parse(readFileSync(join(universeDir, "addresses.json"), "utf-8"));
|
|
19
|
+
const domains = JSON.parse(readFileSync(join(universeDir, "domains.json"), "utf-8"));
|
|
20
|
+
const universeData = {
|
|
21
|
+
id: meta.id,
|
|
22
|
+
name: meta.name,
|
|
23
|
+
characters,
|
|
24
|
+
addresses,
|
|
25
|
+
domains
|
|
26
|
+
};
|
|
27
|
+
this.cache.set(universeId, universeData);
|
|
28
|
+
return universeData;
|
|
29
|
+
}
|
|
30
|
+
static listAvailable() {
|
|
31
|
+
const entries = readdirSync(dataDir, { withFileTypes: true });
|
|
32
|
+
const ids = entries.filter((entry) => {
|
|
33
|
+
if (!entry.isDirectory()) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
readFileSync(join(dataDir, entry.name, "meta.json"), "utf-8");
|
|
38
|
+
return true;
|
|
39
|
+
} catch {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
}).map((entry) => entry.name);
|
|
43
|
+
return ids;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// src/generators/random.ts
|
|
48
|
+
function createRng(seed) {
|
|
49
|
+
if (seed === void 0) {
|
|
50
|
+
return Math.random;
|
|
51
|
+
}
|
|
52
|
+
let s = seed;
|
|
53
|
+
return function rng() {
|
|
54
|
+
s += 1831565813;
|
|
55
|
+
let z = s;
|
|
56
|
+
z = Math.imul(z ^ z >>> 15, z | 1);
|
|
57
|
+
z ^= z + Math.imul(z ^ z >>> 7, z | 61);
|
|
58
|
+
return ((z ^ z >>> 14) >>> 0) / 4294967296;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function pickRandom(array, rng) {
|
|
62
|
+
const index = Math.floor(rng() * array.length);
|
|
63
|
+
return array[index];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/generators/email.ts
|
|
67
|
+
var EmailGenerator = class {
|
|
68
|
+
static generate(firstName, lastName, domains, rng) {
|
|
69
|
+
const domain = pickRandom(domains.emailDomains, rng);
|
|
70
|
+
const first = firstName.toLowerCase();
|
|
71
|
+
const last = lastName.toLowerCase();
|
|
72
|
+
return `${first}.${last}@${domain}`;
|
|
73
|
+
}
|
|
74
|
+
static generateFromUsername(username, domains, rng) {
|
|
75
|
+
const domain = pickRandom(domains.emailDomains, rng);
|
|
76
|
+
return `${username}@${domain}`;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// src/generators/phone.ts
|
|
81
|
+
var PhoneGenerator = class {
|
|
82
|
+
static generate(domains, rng) {
|
|
83
|
+
if (domains.phoneEasterEggs && domains.phoneEasterEggs.length > 0 && rng() < 0.2) {
|
|
84
|
+
return pickRandom(domains.phoneEasterEggs, rng);
|
|
85
|
+
}
|
|
86
|
+
const prefix = pickRandom(domains.phonePrefixes, rng);
|
|
87
|
+
const suffix = this.randomDigits(7, rng);
|
|
88
|
+
return `${prefix}-${suffix.slice(0, 3)}-${suffix.slice(3)}`;
|
|
89
|
+
}
|
|
90
|
+
static randomDigits(count, rng) {
|
|
91
|
+
let result = "";
|
|
92
|
+
for (let i = 0; i < count; i++) {
|
|
93
|
+
result += Math.floor(rng() * 10).toString();
|
|
94
|
+
}
|
|
95
|
+
return result;
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/generators/password.ts
|
|
100
|
+
var PasswordGenerator = class {
|
|
101
|
+
static generate(domains, rng) {
|
|
102
|
+
if (domains.passwordEasterEggs && domains.passwordEasterEggs.length > 0 && rng() < 0.3) {
|
|
103
|
+
return pickRandom(domains.passwordEasterEggs, rng);
|
|
104
|
+
}
|
|
105
|
+
return this.randomPassword(12, rng);
|
|
106
|
+
}
|
|
107
|
+
static randomPassword(length, rng) {
|
|
108
|
+
const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$";
|
|
109
|
+
let result = "";
|
|
110
|
+
for (let i = 0; i < length; i++) {
|
|
111
|
+
result += chars[Math.floor(rng() * chars.length)];
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/engine/person-factory.ts
|
|
118
|
+
var PersonFactory = class {
|
|
119
|
+
static build(universe, seed) {
|
|
120
|
+
const rng = createRng(seed);
|
|
121
|
+
const character = pickRandom(universe.characters, rng);
|
|
122
|
+
return this.buildFromCharacter(character, universe, rng);
|
|
123
|
+
}
|
|
124
|
+
static buildByCharacterId(characterId, universe, seed) {
|
|
125
|
+
const character = universe.characters.find((c) => c.id === characterId);
|
|
126
|
+
if (!character) {
|
|
127
|
+
throw new Error(`Character "${characterId}" not found in universe "${universe.id}"`);
|
|
128
|
+
}
|
|
129
|
+
const rng = createRng(seed);
|
|
130
|
+
return this.buildFromCharacter(character, universe, rng);
|
|
131
|
+
}
|
|
132
|
+
static buildFromCharacter(character, universe, rng) {
|
|
133
|
+
const address = character.address ?? pickRandom(universe.addresses, rng);
|
|
134
|
+
const username = pickRandom(character.usernames, rng);
|
|
135
|
+
const domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;
|
|
136
|
+
const email = EmailGenerator.generateFromUsername(username, domains, rng);
|
|
137
|
+
const phone = PhoneGenerator.generate(universe.domains, rng);
|
|
138
|
+
const password = PasswordGenerator.generate(universe.domains, rng);
|
|
139
|
+
const quote = pickRandom(character.quotes, rng);
|
|
140
|
+
const avatarName = encodeURIComponent(`${character.firstName} ${character.lastName}`);
|
|
141
|
+
const avatar = `https://ui-avatars.com/api/?name=${avatarName}&background=random`;
|
|
142
|
+
const person2 = {
|
|
143
|
+
id: crypto.randomUUID(),
|
|
144
|
+
characterId: character.id,
|
|
145
|
+
firstName: character.firstName,
|
|
146
|
+
lastName: character.lastName,
|
|
147
|
+
username,
|
|
148
|
+
email,
|
|
149
|
+
password,
|
|
150
|
+
phone,
|
|
151
|
+
address: {
|
|
152
|
+
street: address.street,
|
|
153
|
+
city: address.city,
|
|
154
|
+
state: address.state ?? "",
|
|
155
|
+
zip: address.zip ?? "",
|
|
156
|
+
country: address.country
|
|
157
|
+
},
|
|
158
|
+
profession: character.profession,
|
|
159
|
+
interests: character.interests,
|
|
160
|
+
quote,
|
|
161
|
+
universe: universe.id,
|
|
162
|
+
universeName: universe.name,
|
|
163
|
+
avatar
|
|
164
|
+
};
|
|
165
|
+
return person2;
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/engine/persona-builder.ts
|
|
170
|
+
var PersonaBuilder = class {
|
|
171
|
+
static buildPersonFromData(universe, options) {
|
|
172
|
+
return PersonFactory.build(universe, options.seed);
|
|
173
|
+
}
|
|
174
|
+
static buildPerson(options) {
|
|
175
|
+
const universe = UniverseLoader.load(options.universe);
|
|
176
|
+
return PersonFactory.build(universe, options.seed);
|
|
177
|
+
}
|
|
178
|
+
static buildGroup(options) {
|
|
179
|
+
const persons = [];
|
|
180
|
+
for (let i = 0; i < options.size; i++) {
|
|
181
|
+
const seed = options.seed !== void 0 ? options.seed + i : void 0;
|
|
182
|
+
persons.push(this.buildPerson({ universe: options.universe, seed }));
|
|
183
|
+
}
|
|
184
|
+
return persons;
|
|
185
|
+
}
|
|
186
|
+
static listUniverses() {
|
|
187
|
+
const ids = UniverseLoader.listAvailable();
|
|
188
|
+
const result = ids.map((id) => {
|
|
189
|
+
const data = UniverseLoader.load(id);
|
|
190
|
+
const info = {
|
|
191
|
+
id,
|
|
192
|
+
name: data.name,
|
|
193
|
+
characterCount: data.characters.length
|
|
194
|
+
};
|
|
195
|
+
return info;
|
|
196
|
+
});
|
|
197
|
+
return result;
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// src/engine/universe-store.ts
|
|
202
|
+
var UniverseStore = class {
|
|
203
|
+
universes;
|
|
204
|
+
characterIndex;
|
|
205
|
+
constructor(universes2) {
|
|
206
|
+
this.universes = universes2;
|
|
207
|
+
this.characterIndex = this.buildIndex(universes2);
|
|
208
|
+
}
|
|
209
|
+
get index() {
|
|
210
|
+
return this.characterIndex;
|
|
211
|
+
}
|
|
212
|
+
getInterests(universeIds) {
|
|
213
|
+
const entries = universeIds && universeIds.length > 0 ? this.characterIndex.filter((e) => universeIds.includes(e.universeId)) : this.characterIndex;
|
|
214
|
+
const interestSet = /* @__PURE__ */ new Set();
|
|
215
|
+
for (const entry of entries) {
|
|
216
|
+
for (const interest of entry.interests) {
|
|
217
|
+
interestSet.add(interest);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
const result = Array.from(interestSet).sort();
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
getUniverses() {
|
|
224
|
+
const result = this.universes.map((u) => ({
|
|
225
|
+
id: u.id,
|
|
226
|
+
name: u.name,
|
|
227
|
+
characterCount: u.characters.length
|
|
228
|
+
}));
|
|
229
|
+
return result;
|
|
230
|
+
}
|
|
231
|
+
findCharacters(query) {
|
|
232
|
+
let entries = this.characterIndex;
|
|
233
|
+
if (query.universes && query.universes.length > 0) {
|
|
234
|
+
entries = entries.filter((e) => query.universes.includes(e.universeId));
|
|
235
|
+
}
|
|
236
|
+
if (query.name && query.name.trim().length > 0) {
|
|
237
|
+
const needle = query.name.toLowerCase();
|
|
238
|
+
entries = entries.filter((e) => {
|
|
239
|
+
const fullName = `${e.firstName} ${e.lastName}`.toLowerCase();
|
|
240
|
+
return fullName.includes(needle);
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (query.interests && query.interests.length > 0) {
|
|
244
|
+
const mode = query.interestsMode ?? "or";
|
|
245
|
+
if (mode === "and") {
|
|
246
|
+
entries = entries.filter((e) => query.interests.every((interest) => e.interests.includes(interest)));
|
|
247
|
+
} else {
|
|
248
|
+
entries = entries.filter((e) => query.interests.some((interest) => e.interests.includes(interest)));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return entries;
|
|
252
|
+
}
|
|
253
|
+
personByCharacterId(characterId, seed) {
|
|
254
|
+
const entry = this.characterIndex.find((e) => e.characterId === characterId);
|
|
255
|
+
if (!entry) {
|
|
256
|
+
throw new Error(`Character "${characterId}" not found in store`);
|
|
257
|
+
}
|
|
258
|
+
const universe = this.universes.find((u) => u.id === entry.universeId);
|
|
259
|
+
if (!universe) {
|
|
260
|
+
throw new Error(`Universe "${entry.universeId}" not found in store`);
|
|
261
|
+
}
|
|
262
|
+
return PersonFactory.buildByCharacterId(characterId, universe, seed);
|
|
263
|
+
}
|
|
264
|
+
generatePersonas(query, count, seed) {
|
|
265
|
+
const matching = this.findCharacters(query);
|
|
266
|
+
if (matching.length === 0) {
|
|
267
|
+
return [];
|
|
268
|
+
}
|
|
269
|
+
const rng = createRng(seed);
|
|
270
|
+
const actualCount = Math.min(count, matching.length);
|
|
271
|
+
const shuffled = [...matching].sort(() => rng() - 0.5);
|
|
272
|
+
const selected = shuffled.slice(0, actualCount);
|
|
273
|
+
const personas = [];
|
|
274
|
+
for (let i = 0; i < selected.length; i++) {
|
|
275
|
+
const entry = selected[i];
|
|
276
|
+
const universe = this.universes.find((u) => u.id === entry.universeId);
|
|
277
|
+
const personSeed = seed !== void 0 ? seed + i : void 0;
|
|
278
|
+
personas.push(PersonFactory.buildByCharacterId(entry.characterId, universe, personSeed));
|
|
279
|
+
}
|
|
280
|
+
return personas;
|
|
281
|
+
}
|
|
282
|
+
buildIndex(universes2) {
|
|
283
|
+
const index = [];
|
|
284
|
+
for (const universe of universes2) {
|
|
285
|
+
for (const character of universe.characters) {
|
|
286
|
+
const entry = {
|
|
287
|
+
characterId: character.id,
|
|
288
|
+
universeId: universe.id,
|
|
289
|
+
universeName: universe.name,
|
|
290
|
+
firstName: character.firstName,
|
|
291
|
+
lastName: character.lastName,
|
|
292
|
+
interests: character.interests,
|
|
293
|
+
profession: character.profession
|
|
294
|
+
};
|
|
295
|
+
index.push(entry);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return index;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// src/index.ts
|
|
303
|
+
function person(options) {
|
|
304
|
+
return PersonaBuilder.buildPerson(options);
|
|
305
|
+
}
|
|
306
|
+
function personFromData(universe, seed) {
|
|
307
|
+
return PersonaBuilder.buildPersonFromData(universe, { seed });
|
|
308
|
+
}
|
|
309
|
+
function group(options) {
|
|
310
|
+
return PersonaBuilder.buildGroup(options);
|
|
311
|
+
}
|
|
312
|
+
function universes() {
|
|
313
|
+
return PersonaBuilder.listUniverses();
|
|
314
|
+
}
|
|
315
|
+
export {
|
|
316
|
+
UniverseLoader,
|
|
317
|
+
UniverseStore,
|
|
318
|
+
group,
|
|
319
|
+
person,
|
|
320
|
+
personFromData,
|
|
321
|
+
universes
|
|
322
|
+
};
|
|
323
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/universes/loader.ts","../src/generators/random.ts","../src/generators/email.ts","../src/generators/phone.ts","../src/generators/password.ts","../src/engine/person-factory.ts","../src/engine/persona-builder.ts","../src/engine/universe-store.ts","../src/index.ts"],"sourcesContent":["import { readFileSync, readdirSync } from 'fs';\nimport { join } from 'path';\n\nimport type { UniverseData, CharacterData, AddressData, DomainsData } from '@/types';\n\nconst dataDir = join(import.meta.dirname, '../data');\n\nexport class UniverseLoader {\n\tprivate static cache = new Map<string, UniverseData>();\n\n\tstatic register(data: UniverseData): void {\n\t\tthis.cache.set(data.id, data);\n\t}\n\n\tstatic load(universeId: string): UniverseData {\n\t\tconst cached = this.cache.get(universeId);\n\n\t\tif (cached) {\n\t\t\treturn cached;\n\t\t}\n\n\t\tconst universeDir = join(dataDir, universeId);\n\t\tconst meta = JSON.parse(readFileSync(join(universeDir, 'meta.json'), 'utf-8')) as {\n\t\t\tid: string;\n\t\t\tname: string;\n\t\t};\n\n\t\tconst characters = JSON.parse(readFileSync(join(universeDir, 'characters.json'), 'utf-8')) as CharacterData[];\n\n\t\tconst addresses = JSON.parse(readFileSync(join(universeDir, 'addresses.json'), 'utf-8')) as AddressData[];\n\n\t\tconst domains = JSON.parse(readFileSync(join(universeDir, 'domains.json'), 'utf-8')) as DomainsData;\n\n\t\tconst universeData: UniverseData = {\n\t\t\tid: meta.id,\n\t\t\tname: meta.name,\n\t\t\tcharacters,\n\t\t\taddresses,\n\t\t\tdomains\n\t\t};\n\n\t\tthis.cache.set(universeId, universeData);\n\n\t\treturn universeData;\n\t}\n\n\tstatic listAvailable(): string[] {\n\t\tconst entries = readdirSync(dataDir, { withFileTypes: true });\n\n\t\tconst ids = entries\n\t\t\t.filter((entry) => {\n\t\t\t\tif (!entry.isDirectory()) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\treadFileSync(join(dataDir, entry.name, 'meta.json'), 'utf-8');\n\n\t\t\t\t\treturn true;\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t})\n\t\t\t.map((entry) => entry.name);\n\n\t\treturn ids;\n\t}\n}\n","/**\n * Seeded pseudo-random number generator (mulberry32).\n * Returns a function that produces values in [0, 1).\n */\nexport function createRng(seed?: number): () => number {\n\tif (seed === undefined) {\n\t\treturn Math.random;\n\t}\n\n\tlet s = seed;\n\n\treturn function rng(): number {\n\t\ts += 0x6d2b79f5;\n\t\tlet z = s;\n\t\tz = Math.imul(z ^ (z >>> 15), z | 1);\n\t\tz ^= z + Math.imul(z ^ (z >>> 7), z | 61);\n\n\t\treturn ((z ^ (z >>> 14)) >>> 0) / 4294967296;\n\t};\n}\n\nexport function pickRandom<T>(array: T[], rng: () => number): T {\n\tconst index = Math.floor(rng() * array.length);\n\n\treturn array[index];\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class EmailGenerator {\n\tstatic generate(firstName: string, lastName: string, domains: DomainsData, rng: () => number): string {\n\t\tconst domain = pickRandom(domains.emailDomains, rng);\n\t\tconst first = firstName.toLowerCase();\n\t\tconst last = lastName.toLowerCase();\n\n\t\treturn `${first}.${last}@${domain}`;\n\t}\n\n\tstatic generateFromUsername(username: string, domains: DomainsData, rng: () => number): string {\n\t\tconst domain = pickRandom(domains.emailDomains, rng);\n\n\t\treturn `${username}@${domain}`;\n\t}\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class PhoneGenerator {\n\tstatic generate(domains: DomainsData, rng: () => number): string {\n\t\tif (domains.phoneEasterEggs && domains.phoneEasterEggs.length > 0 && rng() < 0.2) {\n\t\t\treturn pickRandom(domains.phoneEasterEggs, rng);\n\t\t}\n\n\t\tconst prefix = pickRandom(domains.phonePrefixes, rng);\n\t\tconst suffix = this.randomDigits(7, rng);\n\n\t\treturn `${prefix}-${suffix.slice(0, 3)}-${suffix.slice(3)}`;\n\t}\n\n\tprivate static randomDigits(count: number, rng: () => number): string {\n\t\tlet result = '';\n\n\t\tfor (let i = 0; i < count; i++) {\n\t\t\tresult += Math.floor(rng() * 10).toString();\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { pickRandom } from './random';\n\nimport type { DomainsData } from '@/types';\n\nexport class PasswordGenerator {\n\tstatic generate(domains: DomainsData, rng: () => number): string {\n\t\tif (domains.passwordEasterEggs && domains.passwordEasterEggs.length > 0 && rng() < 0.3) {\n\t\t\treturn pickRandom(domains.passwordEasterEggs, rng);\n\t\t}\n\n\t\treturn this.randomPassword(12, rng);\n\t}\n\n\tprivate static randomPassword(length: number, rng: () => number): string {\n\t\tconst chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$';\n\t\tlet result = '';\n\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars[Math.floor(rng() * chars.length)];\n\t\t}\n\n\t\treturn result;\n\t}\n}\n","import { createRng, pickRandom, EmailGenerator, PhoneGenerator, PasswordGenerator } from '@/generators';\n\nimport type { Person, UniverseData, CharacterData } from '@/types';\n\nexport class PersonFactory {\n\tstatic build(universe: UniverseData, seed?: number): Person {\n\t\tconst rng = createRng(seed);\n\n\t\tconst character = pickRandom(universe.characters, rng);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tstatic buildByCharacterId(characterId: string, universe: UniverseData, seed?: number): Person {\n\t\tconst character = universe.characters.find((c) => c.id === characterId);\n\n\t\tif (!character) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in universe \"${universe.id}\"`);\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\n\t\treturn this.buildFromCharacter(character, universe, rng);\n\t}\n\n\tprivate static buildFromCharacter(character: CharacterData, universe: UniverseData, rng: () => number): Person {\n\t\tconst address = character.address ?? pickRandom(universe.addresses, rng);\n\n\t\tconst username = pickRandom(character.usernames, rng);\n\n\t\tconst domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;\n\n\t\tconst email = EmailGenerator.generateFromUsername(username, domains, rng);\n\t\tconst phone = PhoneGenerator.generate(universe.domains, rng);\n\t\tconst password = PasswordGenerator.generate(universe.domains, rng);\n\t\tconst quote = pickRandom(character.quotes, rng);\n\t\tconst avatarName = encodeURIComponent(`${character.firstName} ${character.lastName}`);\n\t\tconst avatar = `https://ui-avatars.com/api/?name=${avatarName}&background=random`;\n\n\t\tconst person: Person = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tcharacterId: character.id,\n\t\t\tfirstName: character.firstName,\n\t\t\tlastName: character.lastName,\n\t\t\tusername,\n\t\t\temail,\n\t\t\tpassword,\n\t\t\tphone,\n\t\t\taddress: {\n\t\t\t\tstreet: address.street,\n\t\t\t\tcity: address.city,\n\t\t\t\tstate: address.state ?? '',\n\t\t\t\tzip: address.zip ?? '',\n\t\t\t\tcountry: address.country\n\t\t\t},\n\t\t\tprofession: character.profession,\n\t\t\tinterests: character.interests,\n\t\t\tquote,\n\t\t\tuniverse: universe.id,\n\t\t\tuniverseName: universe.name,\n\t\t\tavatar\n\t\t};\n\n\t\treturn person;\n\t}\n}\n","import { UniverseLoader } from '@/universes';\n\nimport { PersonFactory } from './person-factory';\n\nimport type { Person, PersonOptions, GroupOptions, UniverseInfo, UniverseData } from '@/types';\n\nexport class PersonaBuilder {\n\tstatic buildPersonFromData(universe: UniverseData, options: Omit<PersonOptions, 'universe'>): Person {\n\t\treturn PersonFactory.build(universe, options.seed);\n\t}\n\n\tstatic buildPerson(options: PersonOptions): Person {\n\t\tconst universe = UniverseLoader.load(options.universe);\n\n\t\treturn PersonFactory.build(universe, options.seed);\n\t}\n\n\tstatic buildGroup(options: GroupOptions): Person[] {\n\t\tconst persons: Person[] = [];\n\n\t\tfor (let i = 0; i < options.size; i++) {\n\t\t\tconst seed = options.seed !== undefined ? options.seed + i : undefined;\n\n\t\t\tpersons.push(this.buildPerson({ universe: options.universe, seed }));\n\t\t}\n\n\t\treturn persons;\n\t}\n\n\tstatic listUniverses(): UniverseInfo[] {\n\t\tconst ids = UniverseLoader.listAvailable();\n\n\t\tconst result: UniverseInfo[] = ids.map((id) => {\n\t\t\tconst data = UniverseLoader.load(id);\n\n\t\t\tconst info: UniverseInfo = {\n\t\t\t\tid,\n\t\t\t\tname: data.name,\n\t\t\t\tcharacterCount: data.characters.length\n\t\t\t};\n\n\t\t\treturn info;\n\t\t});\n\n\t\treturn result;\n\t}\n}\n","import { createRng } from '@/generators';\n\nimport { PersonFactory } from './person-factory';\n\nimport type { UniverseData, Person, CharacterEntry, CharacterQuery } from '@/types';\n\nexport class UniverseStore {\n\tprivate universes: UniverseData[];\n\tprivate characterIndex: CharacterEntry[];\n\n\tconstructor(universes: UniverseData[]) {\n\t\tthis.universes = universes;\n\t\tthis.characterIndex = this.buildIndex(universes);\n\t}\n\n\tget index(): CharacterEntry[] {\n\t\treturn this.characterIndex;\n\t}\n\n\tgetInterests(universeIds?: string[]): string[] {\n\t\tconst entries =\n\t\t\tuniverseIds && universeIds.length > 0\n\t\t\t\t? this.characterIndex.filter((e) => universeIds.includes(e.universeId))\n\t\t\t\t: this.characterIndex;\n\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const entry of entries) {\n\t\t\tfor (const interest of entry.interests) {\n\t\t\t\tinterestSet.add(interest);\n\t\t\t}\n\t\t}\n\n\t\tconst result = Array.from(interestSet).sort();\n\n\t\treturn result;\n\t}\n\n\tgetUniverses(): { id: string; name: string; characterCount: number }[] {\n\t\tconst result = this.universes.map((u) => ({\n\t\t\tid: u.id,\n\t\t\tname: u.name,\n\t\t\tcharacterCount: u.characters.length\n\t\t}));\n\n\t\treturn result;\n\t}\n\n\tfindCharacters(query: CharacterQuery): CharacterEntry[] {\n\t\tlet entries = this.characterIndex;\n\n\t\tif (query.universes && query.universes.length > 0) {\n\t\t\tentries = entries.filter((e) => query.universes!.includes(e.universeId));\n\t\t}\n\n\t\tif (query.name && query.name.trim().length > 0) {\n\t\t\tconst needle = query.name.toLowerCase();\n\n\t\t\tentries = entries.filter((e) => {\n\t\t\t\tconst fullName = `${e.firstName} ${e.lastName}`.toLowerCase();\n\n\t\t\t\treturn fullName.includes(needle);\n\t\t\t});\n\t\t}\n\n\t\tif (query.interests && query.interests.length > 0) {\n\t\t\tconst mode = query.interestsMode ?? 'or';\n\n\t\t\tif (mode === 'and') {\n\t\t\t\tentries = entries.filter((e) => query.interests!.every((interest) => e.interests.includes(interest)));\n\t\t\t} else {\n\t\t\t\tentries = entries.filter((e) => query.interests!.some((interest) => e.interests.includes(interest)));\n\t\t\t}\n\t\t}\n\n\t\treturn entries;\n\t}\n\n\tpersonByCharacterId(characterId: string, seed?: number): Person {\n\t\tconst entry = this.characterIndex.find((e) => e.characterId === characterId);\n\n\t\tif (!entry) {\n\t\t\tthrow new Error(`Character \"${characterId}\" not found in store`);\n\t\t}\n\n\t\tconst universe = this.universes.find((u) => u.id === entry.universeId);\n\n\t\tif (!universe) {\n\t\t\tthrow new Error(`Universe \"${entry.universeId}\" not found in store`);\n\t\t}\n\n\t\treturn PersonFactory.buildByCharacterId(characterId, universe, seed);\n\t}\n\n\tgeneratePersonas(query: CharacterQuery, count: number, seed?: number): Person[] {\n\t\tconst matching = this.findCharacters(query);\n\n\t\tif (matching.length === 0) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst rng = createRng(seed);\n\t\tconst actualCount = Math.min(count, matching.length);\n\n\t\tconst shuffled = [...matching].sort(() => rng() - 0.5);\n\t\tconst selected = shuffled.slice(0, actualCount);\n\t\tconst personas: Person[] = [];\n\n\t\tfor (let i = 0; i < selected.length; i++) {\n\t\t\tconst entry = selected[i];\n\t\t\tconst universe = this.universes.find((u) => u.id === entry.universeId)!;\n\t\t\tconst personSeed = seed !== undefined ? seed + i : undefined;\n\n\t\t\tpersonas.push(PersonFactory.buildByCharacterId(entry.characterId, universe, personSeed));\n\t\t}\n\n\t\treturn personas;\n\t}\n\n\tprivate buildIndex(universes: UniverseData[]): CharacterEntry[] {\n\t\tconst index: CharacterEntry[] = [];\n\n\t\tfor (const universe of universes) {\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tconst entry: CharacterEntry = {\n\t\t\t\t\tcharacterId: character.id,\n\t\t\t\t\tuniverseId: universe.id,\n\t\t\t\t\tuniverseName: universe.name,\n\t\t\t\t\tfirstName: character.firstName,\n\t\t\t\t\tlastName: character.lastName,\n\t\t\t\t\tinterests: character.interests,\n\t\t\t\t\tprofession: character.profession\n\t\t\t\t};\n\n\t\t\t\tindex.push(entry);\n\t\t\t}\n\t\t}\n\n\t\treturn index;\n\t}\n}\n","import { PersonaBuilder } from '@/engine';\n\nimport type { Person, UniverseInfo, PersonOptions, GroupOptions, UniverseData } from '@/types';\n\nexport function person(options: PersonOptions): Person {\n\treturn PersonaBuilder.buildPerson(options);\n}\n\nexport function personFromData(universe: UniverseData, seed?: number): Person {\n\treturn PersonaBuilder.buildPersonFromData(universe, { seed });\n}\n\nexport function group(options: GroupOptions): Person[] {\n\treturn PersonaBuilder.buildGroup(options);\n}\n\nexport function universes(): UniverseInfo[] {\n\treturn PersonaBuilder.listUniverses();\n}\n\nexport { UniverseLoader } from '@/universes';\nexport { UniverseStore } from '@/engine';\n\nexport type { Person, UniverseInfo, PersonOptions, GroupOptions } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData, DomainsData } from '@/types';\nexport type { CharacterEntry, CharacterQuery } from '@/types';\n"],"mappings":"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","names":["person","universes"]}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
interface Address {
|
|
2
|
+
street?: string;
|
|
3
|
+
city?: string;
|
|
4
|
+
state?: string;
|
|
5
|
+
zip?: string;
|
|
6
|
+
country?: string;
|
|
7
|
+
}
|
|
8
|
+
interface Person {
|
|
9
|
+
id: string;
|
|
10
|
+
characterId: string;
|
|
11
|
+
firstName: string;
|
|
12
|
+
lastName: string;
|
|
13
|
+
username: string;
|
|
14
|
+
email: string;
|
|
15
|
+
password: string;
|
|
16
|
+
phone: string;
|
|
17
|
+
address: Address;
|
|
18
|
+
profession: string;
|
|
19
|
+
interests: string[];
|
|
20
|
+
quote: string;
|
|
21
|
+
universe: string;
|
|
22
|
+
universeName: string;
|
|
23
|
+
avatar: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface CharacterData {
|
|
27
|
+
id: string;
|
|
28
|
+
firstName: string;
|
|
29
|
+
lastName: string;
|
|
30
|
+
usernames: string[];
|
|
31
|
+
profession: string;
|
|
32
|
+
interests: string[];
|
|
33
|
+
quotes: string[];
|
|
34
|
+
gender?: 'male' | 'female' | 'other';
|
|
35
|
+
birthYear?: number;
|
|
36
|
+
address?: AddressData;
|
|
37
|
+
emailDomain?: string;
|
|
38
|
+
}
|
|
39
|
+
interface AddressData {
|
|
40
|
+
street?: string;
|
|
41
|
+
city?: string;
|
|
42
|
+
state?: string;
|
|
43
|
+
zip?: string;
|
|
44
|
+
country?: string;
|
|
45
|
+
}
|
|
46
|
+
interface DomainsData {
|
|
47
|
+
emailDomains: string[];
|
|
48
|
+
phonePrefixes: string[];
|
|
49
|
+
phoneEasterEggs?: string[];
|
|
50
|
+
passwordEasterEggs?: string[];
|
|
51
|
+
}
|
|
52
|
+
interface UniverseData {
|
|
53
|
+
id: string;
|
|
54
|
+
name: string;
|
|
55
|
+
characters: CharacterData[];
|
|
56
|
+
addresses: AddressData[];
|
|
57
|
+
domains: DomainsData;
|
|
58
|
+
}
|
|
59
|
+
interface UniverseInfo {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
characterCount: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface CharacterEntry {
|
|
66
|
+
characterId: string;
|
|
67
|
+
universeId: string;
|
|
68
|
+
universeName: string;
|
|
69
|
+
firstName: string;
|
|
70
|
+
lastName: string;
|
|
71
|
+
interests: string[];
|
|
72
|
+
profession: string;
|
|
73
|
+
}
|
|
74
|
+
interface CharacterQuery {
|
|
75
|
+
universes?: string[];
|
|
76
|
+
interests?: string[];
|
|
77
|
+
interestsMode?: 'and' | 'or';
|
|
78
|
+
name?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
declare class UniverseStore {
|
|
82
|
+
private universes;
|
|
83
|
+
private characterIndex;
|
|
84
|
+
constructor(universes: UniverseData[]);
|
|
85
|
+
get index(): CharacterEntry[];
|
|
86
|
+
getInterests(universeIds?: string[]): string[];
|
|
87
|
+
getUniverses(): {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
characterCount: number;
|
|
91
|
+
}[];
|
|
92
|
+
findCharacters(query: CharacterQuery): CharacterEntry[];
|
|
93
|
+
personByCharacterId(characterId: string, seed?: number): Person;
|
|
94
|
+
generatePersonas(query: CharacterQuery, count: number, seed?: number): Person[];
|
|
95
|
+
private buildIndex;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { type Address as A, type CharacterData as C, type DomainsData as D, type Person as P, type UniverseData as U, type AddressData as a, type CharacterEntry as b, type CharacterQuery as c, type UniverseInfo as d, UniverseStore as e };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
interface Address {
|
|
2
|
+
street?: string;
|
|
3
|
+
city?: string;
|
|
4
|
+
state?: string;
|
|
5
|
+
zip?: string;
|
|
6
|
+
country?: string;
|
|
7
|
+
}
|
|
8
|
+
interface Person {
|
|
9
|
+
id: string;
|
|
10
|
+
characterId: string;
|
|
11
|
+
firstName: string;
|
|
12
|
+
lastName: string;
|
|
13
|
+
username: string;
|
|
14
|
+
email: string;
|
|
15
|
+
password: string;
|
|
16
|
+
phone: string;
|
|
17
|
+
address: Address;
|
|
18
|
+
profession: string;
|
|
19
|
+
interests: string[];
|
|
20
|
+
quote: string;
|
|
21
|
+
universe: string;
|
|
22
|
+
universeName: string;
|
|
23
|
+
avatar: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface CharacterData {
|
|
27
|
+
id: string;
|
|
28
|
+
firstName: string;
|
|
29
|
+
lastName: string;
|
|
30
|
+
usernames: string[];
|
|
31
|
+
profession: string;
|
|
32
|
+
interests: string[];
|
|
33
|
+
quotes: string[];
|
|
34
|
+
gender?: 'male' | 'female' | 'other';
|
|
35
|
+
birthYear?: number;
|
|
36
|
+
address?: AddressData;
|
|
37
|
+
emailDomain?: string;
|
|
38
|
+
}
|
|
39
|
+
interface AddressData {
|
|
40
|
+
street?: string;
|
|
41
|
+
city?: string;
|
|
42
|
+
state?: string;
|
|
43
|
+
zip?: string;
|
|
44
|
+
country?: string;
|
|
45
|
+
}
|
|
46
|
+
interface DomainsData {
|
|
47
|
+
emailDomains: string[];
|
|
48
|
+
phonePrefixes: string[];
|
|
49
|
+
phoneEasterEggs?: string[];
|
|
50
|
+
passwordEasterEggs?: string[];
|
|
51
|
+
}
|
|
52
|
+
interface UniverseData {
|
|
53
|
+
id: string;
|
|
54
|
+
name: string;
|
|
55
|
+
characters: CharacterData[];
|
|
56
|
+
addresses: AddressData[];
|
|
57
|
+
domains: DomainsData;
|
|
58
|
+
}
|
|
59
|
+
interface UniverseInfo {
|
|
60
|
+
id: string;
|
|
61
|
+
name: string;
|
|
62
|
+
characterCount: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface CharacterEntry {
|
|
66
|
+
characterId: string;
|
|
67
|
+
universeId: string;
|
|
68
|
+
universeName: string;
|
|
69
|
+
firstName: string;
|
|
70
|
+
lastName: string;
|
|
71
|
+
interests: string[];
|
|
72
|
+
profession: string;
|
|
73
|
+
}
|
|
74
|
+
interface CharacterQuery {
|
|
75
|
+
universes?: string[];
|
|
76
|
+
interests?: string[];
|
|
77
|
+
interestsMode?: 'and' | 'or';
|
|
78
|
+
name?: string;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
declare class UniverseStore {
|
|
82
|
+
private universes;
|
|
83
|
+
private characterIndex;
|
|
84
|
+
constructor(universes: UniverseData[]);
|
|
85
|
+
get index(): CharacterEntry[];
|
|
86
|
+
getInterests(universeIds?: string[]): string[];
|
|
87
|
+
getUniverses(): {
|
|
88
|
+
id: string;
|
|
89
|
+
name: string;
|
|
90
|
+
characterCount: number;
|
|
91
|
+
}[];
|
|
92
|
+
findCharacters(query: CharacterQuery): CharacterEntry[];
|
|
93
|
+
personByCharacterId(characterId: string, seed?: number): Person;
|
|
94
|
+
generatePersonas(query: CharacterQuery, count: number, seed?: number): Person[];
|
|
95
|
+
private buildIndex;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export { type Address as A, type CharacterData as C, type DomainsData as D, type Person as P, type UniverseData as U, type AddressData as a, type CharacterEntry as b, type CharacterQuery as c, type UniverseInfo as d, UniverseStore as e };
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "loredata",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Generate fake personas using real characters from pop culture universes",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"fake-data",
|
|
7
|
+
"test-data",
|
|
8
|
+
"faker",
|
|
9
|
+
"mock-data",
|
|
10
|
+
"seed",
|
|
11
|
+
"persona",
|
|
12
|
+
"generator",
|
|
13
|
+
"fixtures",
|
|
14
|
+
"pop-culture",
|
|
15
|
+
"fictional",
|
|
16
|
+
"characters",
|
|
17
|
+
"cli"
|
|
18
|
+
],
|
|
19
|
+
"homepage": "https://github.com/orchidfiles/loredata#readme",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/orchidfiles/loredata"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/orchidfiles/loredata/issues"
|
|
26
|
+
},
|
|
27
|
+
"license": "MIT",
|
|
28
|
+
"author": {
|
|
29
|
+
"name": "orchidfiles",
|
|
30
|
+
"email": "orchid@orchidfiles.com",
|
|
31
|
+
"url": "https://orchidfiles.com"
|
|
32
|
+
},
|
|
33
|
+
"type": "module",
|
|
34
|
+
"exports": {
|
|
35
|
+
".": {
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"import": "./dist/index.js",
|
|
38
|
+
"require": "./dist/index.cjs"
|
|
39
|
+
},
|
|
40
|
+
"./browser": {
|
|
41
|
+
"types": "./dist/browser.d.ts",
|
|
42
|
+
"import": "./dist/browser.js",
|
|
43
|
+
"require": "./dist/browser.cjs"
|
|
44
|
+
},
|
|
45
|
+
"./data/*": "./data/*"
|
|
46
|
+
},
|
|
47
|
+
"bin": {
|
|
48
|
+
"loredata": "./dist/cli/cli.js"
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"data"
|
|
53
|
+
],
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=20.0.0"
|
|
56
|
+
},
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsup",
|
|
59
|
+
"build:watch": "tsup --watch",
|
|
60
|
+
"validate": "node --import tsx/esm scripts/validate-universe.ts",
|
|
61
|
+
"lint": "eslint .",
|
|
62
|
+
"lint:fix": "eslint . --fix",
|
|
63
|
+
"release": "npm publish --access public"
|
|
64
|
+
},
|
|
65
|
+
"dependencies": {
|
|
66
|
+
"commander": "~14.0.3"
|
|
67
|
+
},
|
|
68
|
+
"devDependencies": {
|
|
69
|
+
"@loredata/dev-kit": "workspace:*",
|
|
70
|
+
"@types/node": "~22.13.14",
|
|
71
|
+
"eslint": "~9.39.4",
|
|
72
|
+
"tsup": "~8.4.0",
|
|
73
|
+
"tsx": "~4.21.0",
|
|
74
|
+
"typescript": "~5.8.2",
|
|
75
|
+
"vite": "~6.2.7"
|
|
76
|
+
}
|
|
77
|
+
}
|