loredata 0.2.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +126 -65
  2. package/data/avengers/addresses.json +27 -0
  3. package/data/avengers/characters.json +305 -0
  4. package/data/avengers/meta.json +13 -0
  5. package/data/better-call-saul/addresses.json +37 -0
  6. package/data/better-call-saul/characters.json +268 -0
  7. package/data/better-call-saul/meta.json +13 -0
  8. package/data/big-bang-theory/addresses.json +31 -0
  9. package/data/big-bang-theory/characters.json +198 -0
  10. package/data/big-bang-theory/meta.json +13 -0
  11. package/data/breaking-bad/characters.json +249 -148
  12. package/data/breaking-bad/meta.json +8 -1
  13. package/data/fast-and-furious/addresses.json +1 -2
  14. package/data/fast-and-furious/characters.json +226 -133
  15. package/data/fast-and-furious/meta.json +13 -1
  16. package/data/friends/characters.json +402 -281
  17. package/data/friends/meta.json +8 -1
  18. package/data/game-of-thrones/addresses.json +6 -22
  19. package/data/game-of-thrones/characters.json +507 -299
  20. package/data/game-of-thrones/meta.json +8 -1
  21. package/data/guardians-of-the-galaxy/addresses.json +17 -0
  22. package/data/guardians-of-the-galaxy/characters.json +226 -0
  23. package/data/guardians-of-the-galaxy/meta.json +13 -0
  24. package/data/harry-potter/addresses.json +6 -11
  25. package/data/harry-potter/characters.json +239 -147
  26. package/data/harry-potter/meta.json +8 -1
  27. package/data/house-md/characters.json +184 -52
  28. package/data/house-md/meta.json +8 -1
  29. package/data/lost/characters.json +420 -299
  30. package/data/lost/meta.json +8 -1
  31. package/data/matrix/characters.json +144 -34
  32. package/data/matrix/meta.json +13 -1
  33. package/data/peaky-blinders/characters.json +191 -37
  34. package/data/peaky-blinders/meta.json +8 -1
  35. package/data/prison-break/addresses.json +24 -0
  36. package/data/prison-break/characters.json +188 -0
  37. package/data/prison-break/meta.json +13 -0
  38. package/data/sherlock/characters.json +369 -263
  39. package/data/sherlock/meta.json +8 -1
  40. package/data/simpsons/addresses.json +21 -0
  41. package/data/simpsons/characters.json +383 -0
  42. package/data/simpsons/meta.json +13 -0
  43. package/data/sopranos/addresses.json +37 -0
  44. package/data/sopranos/characters.json +292 -0
  45. package/data/sopranos/meta.json +13 -0
  46. package/data/south-park/addresses.json +31 -0
  47. package/data/south-park/characters.json +372 -0
  48. package/data/south-park/meta.json +13 -0
  49. package/data/spider-man/addresses.json +31 -0
  50. package/data/spider-man/characters.json +219 -0
  51. package/data/spider-man/meta.json +13 -0
  52. package/data/star-wars/addresses.json +19 -0
  53. package/data/star-wars/characters.json +254 -0
  54. package/data/star-wars/meta.json +13 -0
  55. package/data/stranger-things/addresses.json +31 -0
  56. package/data/stranger-things/characters.json +226 -0
  57. package/data/stranger-things/meta.json +13 -0
  58. package/data/supernatural/addresses.json +25 -0
  59. package/data/supernatural/characters.json +190 -0
  60. package/data/supernatural/meta.json +13 -0
  61. package/data/the-crown/addresses.json +27 -0
  62. package/data/the-crown/characters.json +275 -0
  63. package/data/the-crown/meta.json +13 -0
  64. package/data/the-office/characters.json +478 -283
  65. package/data/the-office/meta.json +8 -1
  66. package/data/the-walking-dead/addresses.json +25 -0
  67. package/data/the-walking-dead/characters.json +186 -0
  68. package/data/the-walking-dead/meta.json +13 -0
  69. package/data/the-witcher/addresses.json +22 -0
  70. package/data/the-witcher/characters.json +272 -0
  71. package/data/the-witcher/meta.json +13 -0
  72. package/data/vikings/addresses.json +26 -0
  73. package/data/vikings/characters.json +240 -0
  74. package/data/vikings/meta.json +13 -0
  75. package/data/westworld/addresses.json +19 -0
  76. package/data/westworld/characters.json +161 -0
  77. package/data/westworld/meta.json +13 -0
  78. package/data/x-men/addresses.json +24 -0
  79. package/data/x-men/characters.json +242 -0
  80. package/data/x-men/meta.json +18 -0
  81. package/dist/browser.cjs +18 -72
  82. package/dist/browser.cjs.map +1 -1
  83. package/dist/browser.d.cts +3 -3
  84. package/dist/browser.d.ts +3 -3
  85. package/dist/browser.js +18 -72
  86. package/dist/browser.js.map +1 -1
  87. package/dist/cli/cli.cjs +41 -73
  88. package/dist/cli/cli.cjs.map +1 -1
  89. package/dist/cli/cli.js +41 -73
  90. package/dist/cli/cli.js.map +1 -1
  91. package/dist/index.cjs +41 -72
  92. package/dist/index.cjs.map +1 -1
  93. package/dist/index.d.cts +5 -4
  94. package/dist/index.d.ts +5 -4
  95. package/dist/index.js +41 -72
  96. package/dist/index.js.map +1 -1
  97. package/dist/{universe-store-Del1UHgn.d.cts → universe-store-CWhCn3U6.d.cts} +21 -11
  98. package/dist/{universe-store-Del1UHgn.d.ts → universe-store-CWhCn3U6.d.ts} +21 -11
  99. package/package.json +85 -81
  100. package/data/breaking-bad/domains.json +0 -6
  101. package/data/fast-and-furious/domains.json +0 -6
  102. package/data/friends/domains.json +0 -6
  103. package/data/game-of-thrones/domains.json +0 -6
  104. package/data/harry-potter/domains.json +0 -6
  105. package/data/house-md/domains.json +0 -6
  106. package/data/lost/domains.json +0 -6
  107. package/data/matrix/domains.json +0 -6
  108. package/data/peaky-blinders/domains.json +0 -6
  109. package/data/sherlock/domains.json +0 -6
  110. package/data/the-office/domains.json +0 -6
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../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"],"sourcesContent":["import { PersonaBuilder } from '@/engine';\n\nimport type { Person, UniverseMeta, 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(): UniverseMeta[] {\n\treturn PersonaBuilder.listUniverses();\n}\n\nexport { UniverseLoader } from '@/universes';\nexport { UniverseStore, PersonFactory } from '@/engine';\n\nexport type { Person, UniverseMeta, PersonOptions, GroupOptions } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData, DomainsData } from '@/types';\nexport type { CharacterEntry, CharacterQuery } from '@/types';\n","import { readFileSync, readdirSync } from 'fs';\nimport { createRequire } from 'module';\nimport { dirname, join } from 'path';\n\nimport type { UniverseData, UniverseMeta, CharacterData, AddressData, DomainsData } from '@/types';\n\nconst require = createRequire(import.meta.url);\nconst packageRoot = dirname(require.resolve('loredata/package.json'));\nconst dataDir = join(packageRoot, '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\tif (process.env.NODE_ENV !== 'development') {\n\t\t\tconst cached = this.cache.get(universeId);\n\n\t\t\tif (cached) {\n\t\t\t\treturn cached;\n\t\t\t}\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\tgenre: string[];\n\t\t\tdescription: 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\tgenre: meta.genre,\n\t\t\tdescription: meta.description,\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 getManifest(): UniverseMeta[] {\n\t\tconst ids = this.listAvailable();\n\n\t\tconst result = ids.map((id) => {\n\t\t\tconst universeDir = join(dataDir, id);\n\t\t\tconst meta = JSON.parse(readFileSync(join(universeDir, 'meta.json'), 'utf-8')) as UniverseMeta;\n\n\t\t\tconst entry: UniverseMeta = {\n\t\t\t\tid: meta.id,\n\t\t\t\tname: meta.name,\n\t\t\t\tgenre: meta.genre,\n\t\t\t\tdescription: meta.description\n\t\t\t};\n\n\t\t\treturn entry;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tstatic getAllInterests(): string[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tfor (const interest of character.interests) {\n\t\t\t\t\tinterestSet.add(interest);\n\t\t\t\t}\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\tstatic getAllLocations(): string[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst citySet = new Set<string>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const address of universe.addresses) {\n\t\t\t\tif (address.city) {\n\t\t\t\t\tcitySet.add(address.city);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst result = Array.from(citySet).sort();\n\n\t\treturn result;\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\tstatic buildCanonical(characterId: string, universe: UniverseData): 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 address = character.address ?? universe.addresses[0];\n\t\tconst username = character.usernames[0];\n\t\tconst domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;\n\t\tconst rng = createRng(0);\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 = character.quotes[0];\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\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\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst ids = UniverseLoader.listAvailable();\n\n\t\tconst result: UniverseMeta[] = ids.map((id) => {\n\t\t\tconst data = UniverseLoader.load(id);\n\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid,\n\t\t\t\tname: data.name,\n\t\t\t\tgenre: data.genre,\n\t\t\t\tdescription: data.description\n\t\t\t};\n\n\t\t\treturn meta;\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst result = this.universes.map((u) => {\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid: u.id,\n\t\t\t\tname: u.name,\n\t\t\t\tgenre: u.genre,\n\t\t\t\tdescription: u.description\n\t\t\t};\n\n\t\t\treturn meta;\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"],"mappings":"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","names":["require","person","universes"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/universes/loader.ts","../src/generators/random.ts","../src/generators/email.ts","../src/engine/person-factory.ts","../src/engine/persona-builder.ts","../src/engine/universe-store.ts"],"sourcesContent":["import { PersonaBuilder } from '@/engine';\n\nimport type { Person, UniverseMeta, 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(): UniverseMeta[] {\n\treturn PersonaBuilder.listUniverses();\n}\n\nexport { UniverseLoader } from '@/universes';\nexport { UniverseStore, PersonFactory } from '@/engine';\n\nexport type { Person, UniverseMeta, PersonOptions, GroupOptions } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData } from '@/types';\nexport type { CharacterEntry, CharacterQuery, LocationEntry, LocationType } from '@/types';\n","import { readFileSync, readdirSync } from 'fs';\nimport { createRequire } from 'module';\nimport { dirname, join } from 'path';\n\nimport type { UniverseData, UniverseMeta, CharacterData, AddressData, CharacterEntry, LocationEntry } from '@/types';\n\nconst require = createRequire(import.meta.url);\nconst packageRoot = dirname(require.resolve('loredata/package.json'));\nconst dataDir = join(packageRoot, '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\tif (process.env.NODE_ENV !== 'development') {\n\t\t\tconst cached = this.cache.get(universeId);\n\n\t\t\tif (cached) {\n\t\t\t\treturn cached;\n\t\t\t}\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 UniverseMeta;\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 universeData: UniverseData = {\n\t\t\tid: meta.id,\n\t\t\tname: meta.name,\n\t\t\tgenre: meta.genre,\n\t\t\tdescription: meta.description,\n\t\t\tcharacters,\n\t\t\taddresses,\n\t\t\t...(meta.tmdbId !== undefined && { tmdbId: meta.tmdbId }),\n\t\t\t...(meta.mediaType !== undefined && { mediaType: meta.mediaType }),\n\t\t\t...(meta.rating !== undefined && { rating: meta.rating }),\n\t\t\t...(meta.year !== undefined && { year: meta.year }),\n\t\t\t...(meta.networks !== undefined && { networks: meta.networks }),\n\t\t\t...(meta.posterPath !== undefined && { posterPath: meta.posterPath }),\n\t\t\t...(meta.backdropPath !== undefined && { backdropPath: meta.backdropPath })\n\t\t};\n\n\t\tthis.cache.set(universeId, universeData);\n\n\t\treturn universeData;\n\t}\n\n\tstatic getManifest(): UniverseMeta[] {\n\t\tconst ids = this.listAvailable();\n\n\t\tconst result = ids.map((id) => {\n\t\t\tconst universeDir = join(dataDir, id);\n\n\t\t\treturn JSON.parse(readFileSync(join(universeDir, 'meta.json'), 'utf-8')) as UniverseMeta;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tstatic getAllInterests(): string[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tfor (const interest of character.interests) {\n\t\t\t\t\tinterestSet.add(interest);\n\t\t\t\t}\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\tstatic getAllLocations(): LocationEntry[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst seen = new Map<string, LocationEntry>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const address of universe.addresses) {\n\t\t\t\tif (address.city && !seen.has(`city:${address.city}`)) {\n\t\t\t\t\tseen.set(`city:${address.city}`, { name: address.city, type: 'city' });\n\t\t\t\t}\n\n\t\t\t\tif (address.state && !seen.has(`state:${address.state}`)) {\n\t\t\t\t\tseen.set(`state:${address.state}`, { name: address.state, type: 'state' });\n\t\t\t\t}\n\n\t\t\t\tif (address.country && !seen.has(`country:${address.country}`)) {\n\t\t\t\t\tseen.set(`country:${address.country}`, { name: address.country, type: 'country' });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tstatic buildCharacterIndex(): CharacterEntry[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst entries: CharacterEntry[] = [];\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tentries.push({\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\t\t\t}\n\t\t}\n\n\t\treturn entries;\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\nexport class EmailGenerator {\n\tstatic generateFromUsername(username: string, emailDomains: string[], rng: () => number): string {\n\t\tconst domain = pickRandom(emailDomains, rng);\n\n\t\treturn `${username}@${domain}`;\n\t}\n}\n","import { createRng, pickRandom, EmailGenerator } 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\tstatic buildCanonical(characterId: string, universe: UniverseData): 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 address = character.address ?? universe.addresses[0];\n\t\tconst username = character.usernames[0];\n\t\tconst rng = createRng(0);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = character.quotes[0];\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\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\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\t\tconst username = pickRandom(character.usernames, rng);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = pickRandom(character.quotes, rng);\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\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst ids = UniverseLoader.listAvailable();\n\n\t\tconst result: UniverseMeta[] = ids.map((id) => {\n\t\t\tconst data = UniverseLoader.load(id);\n\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid,\n\t\t\t\tname: data.name,\n\t\t\t\tgenre: data.genre,\n\t\t\t\tdescription: data.description\n\t\t\t};\n\n\t\t\treturn meta;\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst result = this.universes.map((u) => {\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid: u.id,\n\t\t\t\tname: u.name,\n\t\t\t\tgenre: u.genre,\n\t\t\t\tdescription: u.description\n\t\t\t};\n\n\t\t\treturn meta;\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"],"mappings":"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","names":["require","person","universes"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as UniverseData, U as UniverseMeta, P as Person } from './universe-store-Del1UHgn.cjs';
2
- export { A as Address, b as AddressData, C as CharacterData, c as CharacterEntry, d as CharacterQuery, D as DomainsData, e as UniverseStore } from './universe-store-Del1UHgn.cjs';
1
+ import { a as UniverseData, U as UniverseMeta, L as LocationEntry, c as CharacterEntry, P as Person } from './universe-store-CWhCn3U6.cjs';
2
+ export { A as Address, b as AddressData, C as CharacterData, d as CharacterQuery, f as LocationType, e as UniverseStore } from './universe-store-CWhCn3U6.cjs';
3
3
 
4
4
  interface PersonOptions {
5
5
  universe: string;
@@ -17,7 +17,8 @@ declare class UniverseLoader {
17
17
  static load(universeId: string): UniverseData;
18
18
  static getManifest(): UniverseMeta[];
19
19
  static getAllInterests(): string[];
20
- static getAllLocations(): string[];
20
+ static getAllLocations(): LocationEntry[];
21
+ static buildCharacterIndex(): CharacterEntry[];
21
22
  static listAvailable(): string[];
22
23
  }
23
24
 
@@ -33,4 +34,4 @@ declare function personFromData(universe: UniverseData, seed?: number): Person;
33
34
  declare function group(options: GroupOptions): Person[];
34
35
  declare function universes(): UniverseMeta[];
35
36
 
36
- export { type GroupOptions, Person, PersonFactory, type PersonOptions, UniverseData, UniverseLoader, UniverseMeta, group, person, personFromData, universes };
37
+ export { CharacterEntry, type GroupOptions, LocationEntry, Person, PersonFactory, type PersonOptions, UniverseData, UniverseLoader, UniverseMeta, group, person, personFromData, universes };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { a as UniverseData, U as UniverseMeta, P as Person } from './universe-store-Del1UHgn.js';
2
- export { A as Address, b as AddressData, C as CharacterData, c as CharacterEntry, d as CharacterQuery, D as DomainsData, e as UniverseStore } from './universe-store-Del1UHgn.js';
1
+ import { a as UniverseData, U as UniverseMeta, L as LocationEntry, c as CharacterEntry, P as Person } from './universe-store-CWhCn3U6.js';
2
+ export { A as Address, b as AddressData, C as CharacterData, d as CharacterQuery, f as LocationType, e as UniverseStore } from './universe-store-CWhCn3U6.js';
3
3
 
4
4
  interface PersonOptions {
5
5
  universe: string;
@@ -17,7 +17,8 @@ declare class UniverseLoader {
17
17
  static load(universeId: string): UniverseData;
18
18
  static getManifest(): UniverseMeta[];
19
19
  static getAllInterests(): string[];
20
- static getAllLocations(): string[];
20
+ static getAllLocations(): LocationEntry[];
21
+ static buildCharacterIndex(): CharacterEntry[];
21
22
  static listAvailable(): string[];
22
23
  }
23
24
 
@@ -33,4 +34,4 @@ declare function personFromData(universe: UniverseData, seed?: number): Person;
33
34
  declare function group(options: GroupOptions): Person[];
34
35
  declare function universes(): UniverseMeta[];
35
36
 
36
- export { type GroupOptions, Person, PersonFactory, type PersonOptions, UniverseData, UniverseLoader, UniverseMeta, group, person, personFromData, universes };
37
+ export { CharacterEntry, type GroupOptions, LocationEntry, Person, PersonFactory, type PersonOptions, UniverseData, UniverseLoader, UniverseMeta, group, person, personFromData, universes };
package/dist/index.js CHANGED
@@ -21,7 +21,6 @@ var UniverseLoader = class {
21
21
  const meta = JSON.parse(readFileSync(join(universeDir, "meta.json"), "utf-8"));
22
22
  const characters = JSON.parse(readFileSync(join(universeDir, "characters.json"), "utf-8"));
23
23
  const addresses = JSON.parse(readFileSync(join(universeDir, "addresses.json"), "utf-8"));
24
- const domains = JSON.parse(readFileSync(join(universeDir, "domains.json"), "utf-8"));
25
24
  const universeData = {
26
25
  id: meta.id,
27
26
  name: meta.name,
@@ -29,7 +28,13 @@ var UniverseLoader = class {
29
28
  description: meta.description,
30
29
  characters,
31
30
  addresses,
32
- domains
31
+ ...meta.tmdbId !== void 0 && { tmdbId: meta.tmdbId },
32
+ ...meta.mediaType !== void 0 && { mediaType: meta.mediaType },
33
+ ...meta.rating !== void 0 && { rating: meta.rating },
34
+ ...meta.year !== void 0 && { year: meta.year },
35
+ ...meta.networks !== void 0 && { networks: meta.networks },
36
+ ...meta.posterPath !== void 0 && { posterPath: meta.posterPath },
37
+ ...meta.backdropPath !== void 0 && { backdropPath: meta.backdropPath }
33
38
  };
34
39
  this.cache.set(universeId, universeData);
35
40
  return universeData;
@@ -38,14 +43,7 @@ var UniverseLoader = class {
38
43
  const ids = this.listAvailable();
39
44
  const result = ids.map((id) => {
40
45
  const universeDir = join(dataDir, id);
41
- const meta = JSON.parse(readFileSync(join(universeDir, "meta.json"), "utf-8"));
42
- const entry = {
43
- id: meta.id,
44
- name: meta.name,
45
- genre: meta.genre,
46
- description: meta.description
47
- };
48
- return entry;
46
+ return JSON.parse(readFileSync(join(universeDir, "meta.json"), "utf-8"));
49
47
  });
50
48
  return result;
51
49
  }
@@ -65,17 +63,41 @@ var UniverseLoader = class {
65
63
  }
66
64
  static getAllLocations() {
67
65
  const ids = this.listAvailable();
68
- const citySet = /* @__PURE__ */ new Set();
66
+ const seen = /* @__PURE__ */ new Map();
69
67
  for (const id of ids) {
70
68
  const universe = this.load(id);
71
69
  for (const address of universe.addresses) {
72
- if (address.city) {
73
- citySet.add(address.city);
70
+ if (address.city && !seen.has(`city:${address.city}`)) {
71
+ seen.set(`city:${address.city}`, { name: address.city, type: "city" });
72
+ }
73
+ if (address.state && !seen.has(`state:${address.state}`)) {
74
+ seen.set(`state:${address.state}`, { name: address.state, type: "state" });
75
+ }
76
+ if (address.country && !seen.has(`country:${address.country}`)) {
77
+ seen.set(`country:${address.country}`, { name: address.country, type: "country" });
74
78
  }
75
79
  }
76
80
  }
77
- const result = Array.from(citySet).sort();
78
- return result;
81
+ return Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));
82
+ }
83
+ static buildCharacterIndex() {
84
+ const ids = this.listAvailable();
85
+ const entries = [];
86
+ for (const id of ids) {
87
+ const universe = this.load(id);
88
+ for (const character of universe.characters) {
89
+ entries.push({
90
+ characterId: character.id,
91
+ universeId: universe.id,
92
+ universeName: universe.name,
93
+ firstName: character.firstName ?? "",
94
+ lastName: character.lastName ?? "",
95
+ interests: character.interests,
96
+ profession: character.profession
97
+ });
98
+ }
99
+ }
100
+ return entries;
79
101
  }
80
102
  static listAvailable() {
81
103
  const entries = readdirSync(dataDir, { withFileTypes: true });
@@ -115,55 +137,12 @@ function pickRandom(array, rng) {
115
137
 
116
138
  // src/generators/email.ts
117
139
  var EmailGenerator = class {
118
- static generate(firstName, lastName, domains, rng) {
119
- const domain = pickRandom(domains.emailDomains, rng);
120
- const first = firstName.toLowerCase();
121
- const last = lastName.toLowerCase();
122
- return `${first}.${last}@${domain}`;
123
- }
124
- static generateFromUsername(username, domains, rng) {
125
- const domain = pickRandom(domains.emailDomains, rng);
140
+ static generateFromUsername(username, emailDomains, rng) {
141
+ const domain = pickRandom(emailDomains, rng);
126
142
  return `${username}@${domain}`;
127
143
  }
128
144
  };
129
145
 
130
- // src/generators/phone.ts
131
- var PhoneGenerator = class {
132
- static generate(domains, rng) {
133
- if (domains.phoneEasterEggs && domains.phoneEasterEggs.length > 0 && rng() < 0.2) {
134
- return pickRandom(domains.phoneEasterEggs, rng);
135
- }
136
- const prefix = pickRandom(domains.phonePrefixes, rng);
137
- const suffix = this.randomDigits(7, rng);
138
- return `${prefix}-${suffix.slice(0, 3)}-${suffix.slice(3)}`;
139
- }
140
- static randomDigits(count, rng) {
141
- let result = "";
142
- for (let i = 0; i < count; i++) {
143
- result += Math.floor(rng() * 10).toString();
144
- }
145
- return result;
146
- }
147
- };
148
-
149
- // src/generators/password.ts
150
- var PasswordGenerator = class {
151
- static generate(domains, rng) {
152
- if (domains.passwordEasterEggs && domains.passwordEasterEggs.length > 0 && rng() < 0.3) {
153
- return pickRandom(domains.passwordEasterEggs, rng);
154
- }
155
- return this.randomPassword(12, rng);
156
- }
157
- static randomPassword(length, rng) {
158
- const chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$";
159
- let result = "";
160
- for (let i = 0; i < length; i++) {
161
- result += chars[Math.floor(rng() * chars.length)];
162
- }
163
- return result;
164
- }
165
- };
166
-
167
146
  // src/engine/person-factory.ts
168
147
  var PersonFactory = class {
169
148
  static build(universe, seed) {
@@ -186,11 +165,8 @@ var PersonFactory = class {
186
165
  }
187
166
  const address = character.address ?? universe.addresses[0];
188
167
  const username = character.usernames[0];
189
- const domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;
190
168
  const rng = createRng(0);
191
- const email = EmailGenerator.generateFromUsername(username, domains, rng);
192
- const phone = PhoneGenerator.generate(universe.domains, rng);
193
- const password = PasswordGenerator.generate(universe.domains, rng);
169
+ const email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);
194
170
  const quote = character.quotes[0];
195
171
  const person2 = {
196
172
  id: crypto.randomUUID(),
@@ -199,8 +175,6 @@ var PersonFactory = class {
199
175
  lastName: character.lastName,
200
176
  username,
201
177
  email,
202
- password,
203
- phone,
204
178
  address: {
205
179
  street: address.street,
206
180
  city: address.city,
@@ -221,10 +195,7 @@ var PersonFactory = class {
221
195
  static buildFromCharacter(character, universe, rng) {
222
196
  const address = character.address ?? pickRandom(universe.addresses, rng);
223
197
  const username = pickRandom(character.usernames, rng);
224
- const domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;
225
- const email = EmailGenerator.generateFromUsername(username, domains, rng);
226
- const phone = PhoneGenerator.generate(universe.domains, rng);
227
- const password = PasswordGenerator.generate(universe.domains, rng);
198
+ const email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);
228
199
  const quote = pickRandom(character.quotes, rng);
229
200
  const person2 = {
230
201
  id: crypto.randomUUID(),
@@ -233,8 +204,6 @@ var PersonFactory = class {
233
204
  lastName: character.lastName,
234
205
  username,
235
206
  email,
236
- password,
237
- phone,
238
207
  address: {
239
208
  street: address.street,
240
209
  city: address.city,
package/dist/index.js.map CHANGED
@@ -1 +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 { createRequire } from 'module';\nimport { dirname, join } from 'path';\n\nimport type { UniverseData, UniverseMeta, CharacterData, AddressData, DomainsData } from '@/types';\n\nconst require = createRequire(import.meta.url);\nconst packageRoot = dirname(require.resolve('loredata/package.json'));\nconst dataDir = join(packageRoot, '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\tif (process.env.NODE_ENV !== 'development') {\n\t\t\tconst cached = this.cache.get(universeId);\n\n\t\t\tif (cached) {\n\t\t\t\treturn cached;\n\t\t\t}\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\tgenre: string[];\n\t\t\tdescription: 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\tgenre: meta.genre,\n\t\t\tdescription: meta.description,\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 getManifest(): UniverseMeta[] {\n\t\tconst ids = this.listAvailable();\n\n\t\tconst result = ids.map((id) => {\n\t\t\tconst universeDir = join(dataDir, id);\n\t\t\tconst meta = JSON.parse(readFileSync(join(universeDir, 'meta.json'), 'utf-8')) as UniverseMeta;\n\n\t\t\tconst entry: UniverseMeta = {\n\t\t\t\tid: meta.id,\n\t\t\t\tname: meta.name,\n\t\t\t\tgenre: meta.genre,\n\t\t\t\tdescription: meta.description\n\t\t\t};\n\n\t\t\treturn entry;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tstatic getAllInterests(): string[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tfor (const interest of character.interests) {\n\t\t\t\t\tinterestSet.add(interest);\n\t\t\t\t}\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\tstatic getAllLocations(): string[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst citySet = new Set<string>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const address of universe.addresses) {\n\t\t\t\tif (address.city) {\n\t\t\t\t\tcitySet.add(address.city);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst result = Array.from(citySet).sort();\n\n\t\treturn result;\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\tstatic buildCanonical(characterId: string, universe: UniverseData): 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 address = character.address ?? universe.addresses[0];\n\t\tconst username = character.usernames[0];\n\t\tconst domains = character.emailDomain ? { ...universe.domains, emailDomains: [character.emailDomain] } : universe.domains;\n\t\tconst rng = createRng(0);\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 = character.quotes[0];\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\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\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst ids = UniverseLoader.listAvailable();\n\n\t\tconst result: UniverseMeta[] = ids.map((id) => {\n\t\t\tconst data = UniverseLoader.load(id);\n\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid,\n\t\t\t\tname: data.name,\n\t\t\t\tgenre: data.genre,\n\t\t\t\tdescription: data.description\n\t\t\t};\n\n\t\t\treturn meta;\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst result = this.universes.map((u) => {\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid: u.id,\n\t\t\t\tname: u.name,\n\t\t\t\tgenre: u.genre,\n\t\t\t\tdescription: u.description\n\t\t\t};\n\n\t\t\treturn meta;\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, UniverseMeta, 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(): UniverseMeta[] {\n\treturn PersonaBuilder.listUniverses();\n}\n\nexport { UniverseLoader } from '@/universes';\nexport { UniverseStore, PersonFactory } from '@/engine';\n\nexport type { Person, UniverseMeta, 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":["require","person","universes"]}
1
+ {"version":3,"sources":["../src/universes/loader.ts","../src/generators/random.ts","../src/generators/email.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 { createRequire } from 'module';\nimport { dirname, join } from 'path';\n\nimport type { UniverseData, UniverseMeta, CharacterData, AddressData, CharacterEntry, LocationEntry } from '@/types';\n\nconst require = createRequire(import.meta.url);\nconst packageRoot = dirname(require.resolve('loredata/package.json'));\nconst dataDir = join(packageRoot, '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\tif (process.env.NODE_ENV !== 'development') {\n\t\t\tconst cached = this.cache.get(universeId);\n\n\t\t\tif (cached) {\n\t\t\t\treturn cached;\n\t\t\t}\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 UniverseMeta;\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 universeData: UniverseData = {\n\t\t\tid: meta.id,\n\t\t\tname: meta.name,\n\t\t\tgenre: meta.genre,\n\t\t\tdescription: meta.description,\n\t\t\tcharacters,\n\t\t\taddresses,\n\t\t\t...(meta.tmdbId !== undefined && { tmdbId: meta.tmdbId }),\n\t\t\t...(meta.mediaType !== undefined && { mediaType: meta.mediaType }),\n\t\t\t...(meta.rating !== undefined && { rating: meta.rating }),\n\t\t\t...(meta.year !== undefined && { year: meta.year }),\n\t\t\t...(meta.networks !== undefined && { networks: meta.networks }),\n\t\t\t...(meta.posterPath !== undefined && { posterPath: meta.posterPath }),\n\t\t\t...(meta.backdropPath !== undefined && { backdropPath: meta.backdropPath })\n\t\t};\n\n\t\tthis.cache.set(universeId, universeData);\n\n\t\treturn universeData;\n\t}\n\n\tstatic getManifest(): UniverseMeta[] {\n\t\tconst ids = this.listAvailable();\n\n\t\tconst result = ids.map((id) => {\n\t\t\tconst universeDir = join(dataDir, id);\n\n\t\t\treturn JSON.parse(readFileSync(join(universeDir, 'meta.json'), 'utf-8')) as UniverseMeta;\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tstatic getAllInterests(): string[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst interestSet = new Set<string>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tfor (const interest of character.interests) {\n\t\t\t\t\tinterestSet.add(interest);\n\t\t\t\t}\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\tstatic getAllLocations(): LocationEntry[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst seen = new Map<string, LocationEntry>();\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const address of universe.addresses) {\n\t\t\t\tif (address.city && !seen.has(`city:${address.city}`)) {\n\t\t\t\t\tseen.set(`city:${address.city}`, { name: address.city, type: 'city' });\n\t\t\t\t}\n\n\t\t\t\tif (address.state && !seen.has(`state:${address.state}`)) {\n\t\t\t\t\tseen.set(`state:${address.state}`, { name: address.state, type: 'state' });\n\t\t\t\t}\n\n\t\t\t\tif (address.country && !seen.has(`country:${address.country}`)) {\n\t\t\t\t\tseen.set(`country:${address.country}`, { name: address.country, type: 'country' });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn Array.from(seen.values()).sort((a, b) => a.name.localeCompare(b.name));\n\t}\n\n\tstatic buildCharacterIndex(): CharacterEntry[] {\n\t\tconst ids = this.listAvailable();\n\t\tconst entries: CharacterEntry[] = [];\n\n\t\tfor (const id of ids) {\n\t\t\tconst universe = this.load(id);\n\n\t\t\tfor (const character of universe.characters) {\n\t\t\t\tentries.push({\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\t\t\t}\n\t\t}\n\n\t\treturn entries;\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\nexport class EmailGenerator {\n\tstatic generateFromUsername(username: string, emailDomains: string[], rng: () => number): string {\n\t\tconst domain = pickRandom(emailDomains, rng);\n\n\t\treturn `${username}@${domain}`;\n\t}\n}\n","import { createRng, pickRandom, EmailGenerator } 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\tstatic buildCanonical(characterId: string, universe: UniverseData): 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 address = character.address ?? universe.addresses[0];\n\t\tconst username = character.usernames[0];\n\t\tconst rng = createRng(0);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = character.quotes[0];\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\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\n\t\t};\n\n\t\treturn person;\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\t\tconst username = pickRandom(character.usernames, rng);\n\t\tconst email = EmailGenerator.generateFromUsername(username, character.emailDomains, rng);\n\t\tconst quote = pickRandom(character.quotes, rng);\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\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\t...(character.symbol ? { symbol: character.symbol } : {}),\n\t\t\t...(character.color ? { color: character.color } : {})\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst ids = UniverseLoader.listAvailable();\n\n\t\tconst result: UniverseMeta[] = ids.map((id) => {\n\t\t\tconst data = UniverseLoader.load(id);\n\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid,\n\t\t\t\tname: data.name,\n\t\t\t\tgenre: data.genre,\n\t\t\t\tdescription: data.description\n\t\t\t};\n\n\t\t\treturn meta;\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, UniverseMeta, 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(): UniverseMeta[] {\n\t\tconst result = this.universes.map((u) => {\n\t\t\tconst meta: UniverseMeta = {\n\t\t\t\tid: u.id,\n\t\t\t\tname: u.name,\n\t\t\t\tgenre: u.genre,\n\t\t\t\tdescription: u.description\n\t\t\t};\n\n\t\t\treturn meta;\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, UniverseMeta, 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(): UniverseMeta[] {\n\treturn PersonaBuilder.listUniverses();\n}\n\nexport { UniverseLoader } from '@/universes';\nexport { UniverseStore, PersonFactory } from '@/engine';\n\nexport type { Person, UniverseMeta, PersonOptions, GroupOptions } from '@/types';\nexport type { Address, UniverseData, CharacterData, AddressData } from '@/types';\nexport type { CharacterEntry, CharacterQuery, LocationEntry, LocationType } from '@/types';\n"],"mappings":"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","names":["require","person","universes"]}
@@ -12,8 +12,6 @@ interface Person {
12
12
  lastName: string;
13
13
  username: string;
14
14
  email: string;
15
- password: string;
16
- phone: string;
17
15
  address: Address;
18
16
  profession: string;
19
17
  interests: string[];
@@ -29,13 +27,13 @@ interface CharacterData {
29
27
  firstName: string;
30
28
  lastName: string;
31
29
  usernames: string[];
30
+ emailDomains: string[];
32
31
  profession: string;
33
32
  interests: string[];
34
33
  quotes: string[];
35
34
  gender?: 'male' | 'female' | 'other';
36
35
  birthYear?: number;
37
36
  address?: AddressData;
38
- emailDomain?: string;
39
37
  symbol?: string;
40
38
  color?: string;
41
39
  }
@@ -46,12 +44,6 @@ interface AddressData {
46
44
  zip?: string;
47
45
  country?: string;
48
46
  }
49
- interface DomainsData {
50
- emailDomains: string[];
51
- phonePrefixes: string[];
52
- phoneEasterEggs?: string[];
53
- passwordEasterEggs?: string[];
54
- }
55
47
  interface UniverseData {
56
48
  id: string;
57
49
  name: string;
@@ -59,13 +51,26 @@ interface UniverseData {
59
51
  description: string;
60
52
  characters: CharacterData[];
61
53
  addresses: AddressData[];
62
- domains: DomainsData;
54
+ tmdbId?: number;
55
+ mediaType?: 'tv' | 'movie';
56
+ rating?: number;
57
+ year?: number;
58
+ networks?: string[];
59
+ posterPath?: string;
60
+ backdropPath?: string;
63
61
  }
64
62
  interface UniverseMeta {
65
63
  id: string;
66
64
  name: string;
67
65
  genre: string[];
68
66
  description: string;
67
+ tmdbId?: number;
68
+ mediaType?: 'tv' | 'movie';
69
+ rating?: number;
70
+ year?: number;
71
+ networks?: string[];
72
+ posterPath?: string;
73
+ backdropPath?: string;
69
74
  }
70
75
 
71
76
  interface CharacterEntry {
@@ -77,6 +82,11 @@ interface CharacterEntry {
77
82
  interests: string[];
78
83
  profession: string;
79
84
  }
85
+ type LocationType = 'city' | 'state' | 'country';
86
+ interface LocationEntry {
87
+ name: string;
88
+ type: LocationType;
89
+ }
80
90
  interface CharacterQuery {
81
91
  universes?: string[];
82
92
  interests?: string[];
@@ -97,4 +107,4 @@ declare class UniverseStore {
97
107
  private buildIndex;
98
108
  }
99
109
 
100
- export { type Address as A, type CharacterData as C, type DomainsData as D, type Person as P, type UniverseMeta as U, type UniverseData as a, type AddressData as b, type CharacterEntry as c, type CharacterQuery as d, UniverseStore as e };
110
+ export { type Address as A, type CharacterData as C, type LocationEntry as L, type Person as P, type UniverseMeta as U, type UniverseData as a, type AddressData as b, type CharacterEntry as c, type CharacterQuery as d, UniverseStore as e, type LocationType as f };