schema-seed-core 0.1.9 โ†’ 0.1.11

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/dist/index.cjs CHANGED
@@ -844,6 +844,12 @@ async function runSeedMongo(adapter, config, options = {}, context) {
844
844
  try {
845
845
  await adapter.connect();
846
846
  const plan = createMongoPlan(config);
847
+ if (config.truncate && plan.length > 0) {
848
+ if (!options.dryRun && adapter.truncateCollections) {
849
+ console.log(`\u{1F9F9} Truncating ${plan.length} collections...`);
850
+ await adapter.truncateCollections(plan);
851
+ }
852
+ }
847
853
  for (const collName of plan) {
848
854
  const collStartTime = Date.now();
849
855
  const collConfig = config.mongodb.collections[collName];
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/random.ts","../src/types.ts","../src/uniqueness.ts","../src/redaction.ts","../src/planner/graph.ts","../src/planner/toposort.ts","../src/planner/cycles.ts","../src/planner/plan.ts","../src/generate/refs.ts","../src/generate/row.ts","../src/plugins.ts","../src/validation.ts","../src/runner.ts","../src/mongo/planner.ts","../src/mongo/generator.ts","../src/mongo/runner.ts","../src/reporters/console.ts","../src/reporters/json.ts"],"sourcesContent":["export * from './random.js'\nexport * from './types.js'\nexport * from './adapter.js'\nexport * from './uniqueness.js'\nexport * from './redaction.js'\nexport * from './planner/graph.js'\nexport * from './planner/toposort.js'\nexport * from './planner/cycles.js'\nexport * from './planner/plan.js'\nexport * from './generate/refs.js'\nexport * from './generate/row.js'\nexport { runSeedSql } from './runner.js'\nexport { runSeedMongo } from './mongo/runner.js'\nexport * from './mongo/types.js'\nexport type { MongoSeedConfig } from './mongo/types.js'\nexport { loadPlugins } from './plugins.js'\nexport { reportToConsole } from './reporters/console.js'\nexport { reportToJson } from './reporters/json.js'\n\nexport const version = '0.0.1'\n\nexport function defineSeed(options: import('./types.js').SeedOptions) {\n return options\n}\n","/**\n * A deterministic pseudo-random number generator (PRNG) using the Mulberry32 algorithm.\n */\nexport class Random {\n private state: number\n\n constructor(seed: number | string) {\n this.state = typeof seed === 'string' ? this.hashString(seed) : seed\n }\n\n private hashString(str: string): number {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash |= 0\n }\n return hash\n }\n\n next(): number {\n let t = (this.state += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n nextInt(min: number, max: number): number {\n return Math.floor(this.next() * (max - min + 1)) + min\n }\n\n pick<T>(array: T[], weights?: number[]): T {\n if (!weights) {\n return array[this.nextInt(0, array.length - 1)]\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0)\n let r = this.next() * totalWeight\n for (let i = 0; i < array.length; i++) {\n r -= weights[i] || 0\n if (r <= 0) return array[i]\n }\n return array[array.length - 1]\n }\n\n boolean(probability = 0.5): boolean {\n return this.next() < probability\n }\n}\n","/**\n * Normalized SQL types that map various database-specific types to a common set.\n */\nexport enum NormalizedSqlType {\n STRING = 'string',\n TEXT = 'text',\n INT = 'int',\n BIGINT = 'bigint',\n FLOAT = 'float',\n DECIMAL = 'decimal',\n BOOLEAN = 'boolean',\n DATE = 'date',\n DATETIME = 'datetime',\n JSON = 'json',\n UUID = 'uuid',\n ENUM = 'enum',\n BINARY = 'binary',\n OBJECTID = 'objectid',\n}\n\n/**\n * Metadata for a single column in a table.\n */\nexport interface ColumnSchema {\n name: string\n type: NormalizedSqlType\n /** The raw database-specific type string */\n rawType: string\n nullable: boolean\n defaultValue?: any\n /** For ENUM types, the list of allowed values */\n enumValues?: string[]\n /** Precision for decimal/float types */\n precision?: number\n /** Scale for decimal types */\n scale?: number\n /** Maximum length for string/binary types */\n maxLength?: number\n /** Whether this column is auto-incrementing / identity */\n isAutoIncrement: boolean\n /** Documentation or comments from the database */\n comment?: string\n}\n\n/**\n * Primary key definition.\n */\nexport interface PrimaryKeySchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Foreign key relationship definition.\n */\nexport interface ForeignKeySchema {\n name?: string\n /** Columns in the current table */\n columns: string[]\n /** Referenced table name */\n referencedTable: string\n /** Referenced columns in the target table */\n referencedColumns: string[]\n onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n}\n\n/**\n * Unique constraint definition.\n */\nexport interface UniqueConstraintSchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Metadata for a single table.\n */\nexport interface TableSchema {\n name: string\n schema?: string\n columns: Record<string, ColumnSchema>\n primaryKey?: PrimaryKeySchema\n foreignKeys: ForeignKeySchema[]\n uniqueConstraints: UniqueConstraintSchema[]\n /** Estimated or actual row count */\n rowCount?: number\n comment?: string\n}\n\n/**\n * A complete representation of the database schema as a graph of tables.\n */\nexport interface SchemaGraph {\n tables: Record<string, TableSchema>\n}\n\n/**\n * Metadata for a single MongoDB collection.\n */\nexport interface MongoCollectionSchema {\n name: string\n fields: Record<string, ColumnSchema>\n /** Mapping of field names to referenced collections and fields, e.g. { \"userId\": \"users._id\" } */\n references?: Record<string, string>\n}\n\n/**\n * A complete representation of the MongoDB schema.\n */\nexport interface MongoSchema {\n collections: Record<string, MongoCollectionSchema>\n}\n\n/**\n * A batch of data to be inserted into a table.\n */\nexport interface SeedBatch {\n tableName: string\n rows: Record<string, any>[]\n}\n\n/**\n * The execution plan for seeding the database.\n */\nexport interface SeedPlan {\n /** The order in which tables should be seeded to satisfy foreign key constraints */\n insertOrder: string[]\n /** Grouped batches for execution */\n batches: SeedBatch[]\n /** Mapping of virtual IDs to actual database IDs for resolving references */\n referencesMap: Map<string, any>\n}\n\nexport type OverrideFunction = (ctx: { i: number; random: any; refs: any }) => any\n\nexport interface WeightedEnumOverride {\n enum: any[]\n weights?: number[]\n}\n\nexport interface DateBetweenOverride {\n dateBetween: [string | Date, string | Date]\n}\n\nexport type ColumnOverride = OverrideFunction | WeightedEnumOverride | DateBetweenOverride | any\n\nexport type TableOverrides = Record<string, ColumnOverride>\n\nexport interface Hooks {\n beforeInsert?: (table: string, rows: any[]) => any[] | Promise<any[]>\n afterInsert?: (table: string, result: { insertedCount: number; durationMs: number }) => void | Promise<void>\n}\n\nexport interface Plugin {\n name: string\n overrides?: Record<string, TableOverrides>\n generators?: Record<string, (ctx: any) => any>\n hooks?: Hooks\n}\n\n/**\n * Options for the seeding process.\n */\nexport interface SeedOptions {\n /** Number of rows to generate per table (can be a global number or per-table map) */\n rows?: number | Record<string, number>\n /** Seed for the random number generator to ensure reproducibility */\n seed?: number | string\n /** If true, only show what would happen without executing any writes */\n dryRun?: boolean\n /** Number of rows to insert in a single batch */\n batchSize?: number\n /** Safety flag to allow running against production environments */\n allowProduction?: boolean\n /** If true, also seed parent tables required by foreign keys even if not explicitly requested */\n withParents?: boolean\n /** If true, truncate tables before seeding */\n truncate?: boolean\n /** Specific tables to include in the seeding process */\n includeTables?: string[]\n /** Specific tables to exclude from the seeding process */\n excludeTables?: string[]\n /** Custom overrides for specific tables and columns */\n overrides?: Record<string, TableOverrides>\n /** Lifecycle hooks */\n hooks?: Hooks\n /** List of plugins to load */\n plugins?: (string | Plugin)[]\n}\n\nexport interface RunnerContext {\n generators: Record<string, (ctx: any) => any>\n inferGenerator: (columnName: string, sqlType: any) => { generatorId: string; options?: any }\n overrides?: Record<string, any>\n}\n\n/**\n * Detailed report of the seeding operation's effects.\n */\nexport interface EffectReport {\n success: boolean\n /** Total time taken in milliseconds */\n durationMs: number\n /** Stats per table */\n tables: Record<\n string,\n {\n insertedCount: number\n error?: string\n durationMs: number\n }\n >\n /** Any global errors that occurred during the process */\n errors: Error[]\n}\n","/**\n * Registry to track and enforce uniqueness for generated values.\n */\nexport class UniquenessRegistry {\n private registry: Map<string, Set<any>> = new Map()\n\n /**\n * Generates a unique key for a table and column.\n */\n private getRegistryKey(table: string, column: string): string {\n return `${table}.${column}`\n }\n\n /**\n * Attempts to generate a unique value using a generator function.\n * If the generated value is already in the registry, it retries up to `maxRetries` times.\n * If it still fails, it uses a deterministic fallback.\n * \n * @param table Table name\n * @param column Column name\n * @param generator Function that generates a value\n * @param maxRetries Maximum number of retries before fallback\n * @returns A unique value\n */\n async ensureUnique<T>(\n table: string,\n column: string,\n generator: () => T | Promise<T>,\n maxRetries = 100\n ): Promise<T> {\n const key = this.getRegistryKey(table, column)\n if (!this.registry.has(key)) {\n this.registry.set(key, new Set())\n }\n const usedValues = this.registry.get(key)!\n\n for (let i = 0; i < maxRetries; i++) {\n const value = await generator()\n if (!usedValues.has(value)) {\n usedValues.add(value)\n return value\n }\n }\n\n // Deterministic fallback: append a counter or hash if retries fail\n const fallbackValue = await generator()\n const finalValue = `${fallbackValue}_${usedValues.size}` as unknown as T\n usedValues.add(finalValue)\n return finalValue\n }\n\n /**\n * Clears the registry for a specific table/column or all.\n */\n clear(table?: string, column?: string) {\n if (table && column) {\n this.registry.delete(this.getRegistryKey(table, column))\n } else {\n this.registry.clear()\n }\n }\n}\n","/**\n * Helper to redact sensitive information from reports and logs.\n */\nexport class Redactor {\n private static readonly SENSITIVE_PATTERNS = [\n /password/i,\n /token/i,\n /secret/i,\n /api_?key/i,\n /auth/i,\n /cookie/i,\n /credit_?card/i,\n /ssn/i,\n ]\n\n /**\n * Checks if a column name is considered sensitive.\n */\n static isSensitive(columnName: string): boolean {\n return this.SENSITIVE_PATTERNS.some((pattern) => pattern.test(columnName))\n }\n\n /**\n * Redacts sensitive values in a row object.\n * @param row The row data to redact\n * @returns A new object with sensitive values replaced by a placeholder\n */\n static redactRow(row: Record<string, any>): Record<string, any> {\n const redacted: Record<string, any> = {}\n for (const [key, value] of Object.entries(row)) {\n if (this.isSensitive(key)) {\n redacted[key] = '[REDACTED]'\n } else {\n redacted[key] = value\n }\n }\n return redacted\n }\n\n /**\n * Redacts sensitive values in a list of rows.\n */\n static redactRows(rows: Record<string, any>[]): Record<string, any>[] {\n return rows.map((row) => this.redactRow(row))\n }\n}\n","import { SchemaGraph } from '../types.js'\n\nexport interface DependencyNode {\n tableName: string\n dependencies: Set<string> // Tables this table depends on\n dependents: Set<string> // Tables that depend on this table\n}\n\nexport class DependencyGraph {\n nodes: Map<string, DependencyNode> = new Map()\n\n constructor(schema: SchemaGraph) {\n // Initialize nodes\n for (const tableName of Object.keys(schema.tables)) {\n this.nodes.set(tableName, {\n tableName,\n dependencies: new Set(),\n dependents: new Set(),\n })\n }\n\n // Build edges from foreign keys\n for (const [tableName, table] of Object.entries(schema.tables)) {\n const node = this.nodes.get(tableName)!\n for (const fk of table.foreignKeys) {\n // Self-references are handled during cycle detection/resolution\n if (fk.referencedTable === tableName) continue\n\n if (this.nodes.has(fk.referencedTable)) {\n node.dependencies.add(fk.referencedTable)\n this.nodes.get(fk.referencedTable)!.dependents.add(tableName)\n }\n }\n }\n }\n\n getNodes() {\n return Array.from(this.nodes.values())\n }\n\n getNode(tableName: string) {\n return this.nodes.get(tableName)\n }\n}\n","import { DependencyGraph } from './graph.js'\n\nexport interface TopoSortResult {\n order: string[]\n cycles: string[][]\n}\n\n/**\n * Performs a topological sort on the dependency graph.\n * Uses Kahn's algorithm or DFS-based approach. Here we use DFS for easier cycle path extraction.\n */\nexport function topologicalSort(graph: DependencyGraph): TopoSortResult {\n const order: string[] = []\n const cycles: string[][] = []\n const visited = new Set<string>()\n const recStack = new Set<string>()\n const path: string[] = []\n\n function visit(tableName: string) {\n if (recStack.has(tableName)) {\n // Cycle detected\n const cycleStart = path.indexOf(tableName)\n cycles.push(path.slice(cycleStart))\n return\n }\n if (visited.has(tableName)) return\n\n visited.add(tableName)\n recStack.add(tableName)\n path.push(tableName)\n\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n visit(dep)\n }\n }\n\n recStack.delete(tableName)\n path.pop()\n order.push(tableName)\n }\n\n for (const node of graph.getNodes()) {\n if (!visited.has(node.tableName)) {\n visit(node.tableName)\n }\n }\n\n return { order, cycles }\n}\n","import { SchemaGraph, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\n\nexport interface CycleResolution {\n resolved: boolean\n strategy?: 'NULLABLE_FK' | 'DEFERRABLE'\n breakingTable?: string\n breakingColumn?: string\n}\n\n/**\n * Attempts to resolve cycles in the dependency graph.\n */\nexport function resolveCycles(\n cycles: string[][],\n schema: SchemaGraph,\n supportsDeferrable: boolean\n): CycleResolution[] {\n return cycles.map((cycle) => {\n // Strategy B: Deferrable constraints\n if (supportsDeferrable) {\n return { resolved: true, strategy: 'DEFERRABLE' }\n }\n\n // Strategy A: Nullable FK\n // Look for a table in the cycle that has a nullable foreign key pointing to another table in the cycle\n for (let i = 0; i < cycle.length; i++) {\n const currentTable = cycle[i]\n const nextTable = cycle[(i + 1) % cycle.length]\n const tableSchema = schema.tables[currentTable]\n\n const nullableFk = tableSchema.foreignKeys.find((fk) => {\n if (fk.referencedTable !== nextTable) return false\n // Check if all columns in this FK are nullable\n return fk.columns.every((colName) => tableSchema.columns[colName]?.nullable)\n })\n\n if (nullableFk) {\n return {\n resolved: true,\n strategy: 'NULLABLE_FK',\n breakingTable: currentTable,\n breakingColumn: nullableFk.columns[0], // Simplified: just track one\n }\n }\n }\n\n return { resolved: false }\n })\n}\n","import { SchemaGraph, SeedPlan, SeedOptions, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\nimport { topologicalSort } from './toposort.js'\nimport { resolveCycles } from './cycles.js'\n\nexport function createSeedPlan(\n schema: SchemaGraph,\n options: SeedOptions,\n supportsDeferrable = false\n): SeedPlan {\n const graph = new DependencyGraph(schema)\n const { order, cycles } = topologicalSort(graph)\n\n if (cycles.length > 0) {\n const resolutions = resolveCycles(cycles, schema, supportsDeferrable)\n const unresolvable = resolutions.filter((r) => !r.resolved)\n\n if (unresolvable.length > 0) {\n const cyclePaths = cycles\n .filter((_, i) => !resolutions[i].resolved)\n .map((c) => c.join(' -> '))\n .join('\\n')\n throw new Error(\n `Unresolvable cycles detected in schema:\\n${cyclePaths}\\nTry making one of the foreign keys nullable or use a database that supports deferrable constraints.`\n )\n }\n }\n\n let finalOrder = order\n\n // Apply include/exclude filters\n if (options.includeTables) {\n const includeSet = new Set(options.includeTables)\n if (options.withParents) {\n // Expand includeSet to include all parents\n const expanded = new Set<string>()\n const walk = (tableName: string) => {\n if (expanded.has(tableName)) return\n expanded.add(tableName)\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n walk(dep)\n }\n }\n }\n options.includeTables.forEach(walk)\n finalOrder = finalOrder.filter((t) => expanded.has(t))\n } else {\n finalOrder = finalOrder.filter((t) => includeSet.has(t))\n }\n }\n\n if (options.excludeTables) {\n const excludeSet = new Set(options.excludeTables)\n finalOrder = finalOrder.filter((t) => !excludeSet.has(t))\n }\n\n // Join table heuristics: tables with 2+ FKs and mostly FK columns\n // These should generally be seeded after their parents, which topological sort already handles.\n // But we can refine the order if needed. For now, toposort is sufficient.\n\n return {\n insertOrder: finalOrder,\n batches: [], // To be populated by the generator\n referencesMap: new Map(),\n }\n}\n\n/**\n * Heuristic to identify if a table is likely a join table.\n */\nexport function isJoinTable(table: TableSchema): boolean {\n const fkColumnCount = new Set(table.foreignKeys.flatMap((fk) => fk.columns)).size\n const totalColumnCount = Object.keys(table.columns).length\n\n return (\n table.foreignKeys.length >= 2 &&\n fkColumnCount >= totalColumnCount * 0.7 // 70% or more columns are FKs\n )\n}\n","import { Random } from '../random.js'\n\n/**\n * Registry to store and retrieve primary key values for foreign key resolution.\n */\nexport class ReferenceRegistry {\n private refs: Map<string, any[]> = new Map()\n\n /**\n * Records an inserted primary key for a table.\n */\n addReference(table: string, pk: any) {\n if (!this.refs.has(table)) {\n this.refs.set(table, [])\n }\n this.refs.get(table)!.push(pk)\n }\n\n /**\n * Picks a random primary key from the specified table.\n */\n getRandomReference(table: string, random: Random): any {\n const tableRefs = this.refs.get(table)\n if (!tableRefs || tableRefs.length === 0) {\n return null\n }\n return random.pick(tableRefs)\n }\n\n /**\n * Returns all recorded references for a table.\n */\n getReferences(table: string): any[] {\n return this.refs.get(table) || []\n }\n\n clear() {\n this.refs.clear()\n }\n}\n","import { TableSchema, ColumnSchema, NormalizedSqlType } from '../types.js'\nimport { Random } from '../random.js'\nimport { UniquenessRegistry } from '../uniqueness.js'\nimport { ReferenceRegistry } from './refs.js'\n\nexport interface GenerationContext {\n random: Random\n uniqueness: UniquenessRegistry\n refs: ReferenceRegistry\n /** Current row index in the batch */\n i: number\n /** Map of column name or table.column to a specific generator function */\n overrides?: Record<string, any>\n /** Map of generator IDs to their implementation */\n generators: Record<string, (ctx: any) => any>\n /** Function to infer generator ID from column metadata */\n inferGenerator: (columnName: string, sqlType: NormalizedSqlType) => { generatorId: string; options?: any }\n}\n\n/**\n * Generates multiple rows for a table.\n */\nexport async function generateRows(\n table: TableSchema,\n count: number,\n context: Omit<GenerationContext, 'i'>\n): Promise<Record<string, any>[]> {\n const rows: Record<string, any>[] = []\n for (let i = 0; i < count; i++) {\n rows.push(await generateRow(table, { ...context, i } as GenerationContext))\n }\n return rows\n}\n\n/**\n * Generates a single row for a table.\n */\nexport async function generateRow(\n table: TableSchema,\n context: GenerationContext\n): Promise<Record<string, any>> {\n const row: Record<string, any> = {}\n\n for (const column of Object.values(table.columns)) {\n // Skip auto-increment columns as they are handled by the DB\n if (column.isAutoIncrement) continue\n\n // Check for foreign keys\n const fk = table.foreignKeys.find((f) => f.columns.includes(column.name))\n if (fk) {\n const ref = context.refs.getRandomReference(fk.referencedTable, context.random)\n if (ref !== null) {\n // If it's a composite FK, we might need more complex logic. \n // For now, assume single column FK.\n row[column.name] = ref\n continue\n }\n }\n\n // Check for overrides\n const tableOverride = context.overrides?.[table.name]?.[column.name]\n const globalOverride = context.overrides?.[column.name]\n const override = tableOverride !== undefined ? tableOverride : globalOverride\n\n if (override !== undefined) {\n if (typeof override === 'function') {\n row[column.name] = await override({ i: context.i, random: context.random, refs: context.refs })\n continue\n } else if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n const values = override.enum\n const weights = override.weights\n row[column.name] = context.random.pick(values, weights)\n continue\n } else if ('dateBetween' in override) {\n const [start, end] = override.dateBetween\n const startTime = new Date(start).getTime()\n const endTime = new Date(end).getTime()\n const randomTime = context.random.nextInt(startTime, endTime)\n row[column.name] = new Date(randomTime).toISOString()\n continue\n }\n }\n // Literal value override\n row[column.name] = override\n continue\n }\n\n // Use semantic inference\n const { generatorId, options } = context.inferGenerator(column.name, column.type)\n const generator = context.generators[generatorId]\n\n if (generator) {\n // Wrap in uniqueness check if needed (e.g. if column is in uniqueConstraints)\n const isUnique = table.uniqueConstraints.some((uc) => uc.columns.includes(column.name)) ||\n table.primaryKey?.columns.includes(column.name)\n\n if (isUnique) {\n row[column.name] = await context.uniqueness.ensureUnique(\n table.name,\n column.name,\n () => generator({ ...context, options })\n )\n } else {\n row[column.name] = generator({ ...context, options })\n }\n } else {\n // Fallback to basic type-based generation if no generator found\n row[column.name] = generateDefaultValue(column, context.random)\n }\n }\n\n return row\n}\n\nfunction generateDefaultValue(column: ColumnSchema, random: Random): any {\n if (column.defaultValue !== undefined) return column.defaultValue\n if (column.nullable && random.boolean(0.1)) return null\n\n switch (column.type) {\n case NormalizedSqlType.INT:\n case NormalizedSqlType.BIGINT:\n return random.nextInt(1, 1000)\n case NormalizedSqlType.FLOAT:\n case NormalizedSqlType.DECIMAL:\n return parseFloat((random.next() * 100).toFixed(2))\n case NormalizedSqlType.BOOLEAN:\n return random.boolean()\n case NormalizedSqlType.DATE:\n case NormalizedSqlType.DATETIME:\n return new Date().toISOString()\n case NormalizedSqlType.JSON:\n return { mock: 'data' }\n case NormalizedSqlType.ENUM:\n return column.enumValues ? random.pick(column.enumValues) : 'VALUE'\n default:\n return 'mock-string'\n }\n}\n","import { Plugin, SeedOptions, RunnerContext } from './types.js'\n\nexport async function loadPlugins(options: SeedOptions, context: RunnerContext): Promise<void> {\n if (!options.plugins) return\n\n for (const pluginRef of options.plugins) {\n let plugin: Plugin\n if (typeof pluginRef === 'string') {\n try {\n // In a real scenario, we'd use dynamic import or a registry\n // For now, we'll assume it's already available or throw a helpful error\n const module = await import(pluginRef)\n plugin = module.default || module\n } catch (err: any) {\n throw new Error(`Failed to load plugin ${pluginRef}: ${err.message}`)\n }\n } else {\n plugin = pluginRef\n }\n\n // Merge plugin contributions\n if (plugin.generators) {\n context.generators = { ...context.generators, ...plugin.generators }\n }\n\n if (plugin.overrides) {\n options.overrides = mergeOverrides(options.overrides || {}, plugin.overrides)\n }\n\n if (plugin.hooks) {\n options.hooks = mergeHooks(options.hooks || {}, plugin.hooks)\n }\n }\n}\n\nfunction mergeOverrides(base: Record<string, any>, plugin: Record<string, any>): Record<string, any> {\n const merged = { ...base }\n for (const [table, tableOverrides] of Object.entries(plugin)) {\n merged[table] = { ...(merged[table] || {}), ...tableOverrides }\n }\n return merged\n}\n\nfunction mergeHooks(base: any, plugin: any): any {\n return {\n beforeInsert: async (table: string, rows: any[]) => {\n let currentRows = rows\n if (base.beforeInsert) currentRows = await base.beforeInsert(table, currentRows)\n if (plugin.beforeInsert) currentRows = await plugin.beforeInsert(table, currentRows)\n return currentRows\n },\n afterInsert: async (table: string, result: any) => {\n if (base.afterInsert) await base.afterInsert(table, result)\n if (plugin.afterInsert) await plugin.afterInsert(table, result)\n }\n }\n}\n","import { SeedOptions, TableOverrides } from './types.js'\n\nexport function validateOptions(options: SeedOptions): void {\n if (options.overrides) {\n for (const [tableName, tableOverrides] of Object.entries(options.overrides)) {\n if (typeof tableOverrides !== 'object' || tableOverrides === null) {\n throw new Error(`Invalid override for table \"${tableName}\": must be an object.`)\n }\n\n for (const [columnName, override] of Object.entries(tableOverrides)) {\n validateOverride(tableName, columnName, override)\n }\n }\n }\n}\n\nfunction validateOverride(table: string, column: string, override: any): void {\n if (typeof override === 'function') return\n\n if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n if (!Array.isArray(override.enum)) {\n throw new Error(`Invalid enum override for \"${table}.${column}\": \"enum\" must be an array.`)\n }\n if (override.weights && (!Array.isArray(override.weights) || override.weights.length !== override.enum.length)) {\n throw new Error(`Invalid weights for \"${table}.${column}\": \"weights\" must be an array of the same length as \"enum\".`)\n }\n return\n }\n\n if ('dateBetween' in override) {\n if (!Array.isArray(override.dateBetween) || override.dateBetween.length !== 2) {\n throw new Error(`Invalid dateBetween override for \"${table}.${column}\": must be an array of [start, end].`)\n }\n return\n }\n }\n\n // Literal values are always valid\n}\n","import { SqlAdapter, MongoAdapter } from './adapter.js'\nimport { SeedPlan, SeedOptions, EffectReport, TableSchema, MongoSchema, RunnerContext } from './types.js'\nimport { Random } from './random.js'\nimport { UniquenessRegistry } from './uniqueness.js'\nimport { ReferenceRegistry } from './generate/refs.js'\nimport { generateRows } from './generate/row.js'\nimport { Redactor } from './redaction.js'\nimport { loadPlugins } from './plugins.js'\nimport { validateOptions } from './validation.js'\n\nfunction checkProductionSafety(options: SeedOptions, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n // If URL parsing fails, we fallback to simple string check\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\n\nexport async function runSeedSql(\n adapter: SqlAdapter,\n schema: any, // SchemaGraph\n plan: SeedPlan,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).config?.connectionString || (adapter as any).config)\n\n try {\n await adapter.connect()\n\n if (options.truncate && plan.insertOrder.length > 0) {\n if (!options.allowProduction) {\n // Simple heuristic: check for common production indicators if needed\n // For now, we rely on the user's explicit flag\n }\n if (!options.dryRun) {\n await adapter.truncateTables([...plan.insertOrder].reverse())\n }\n }\n\n if (!options.dryRun) {\n await adapter.begin()\n }\n\n for (const tableName of plan.insertOrder) {\n const tableStartTime = Date.now()\n const tableSchema: TableSchema = schema.tables[tableName]\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[tableName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n let rows = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n rows = await options.hooks.beforeInsert(tableName, rows)\n }\n\n const batchSize = options.batchSize || 1000\n for (let i = 0; i < rows.length; i += batchSize) {\n const batch = rows.slice(i, i + batchSize)\n await adapter.insertBatch({ tableName, rows: batch })\n }\n\n // Record PKs for future FK resolution\n // This is a simplification: we assume the adapter might need to return IDs\n // or we use the generated ones if they aren't auto-inc\n for (const row of rows) {\n if (tableSchema.primaryKey) {\n // For simple single-column PKs\n const pkCol = tableSchema.primaryKey.columns[0]\n if (row[pkCol] !== undefined) {\n refs.addReference(tableName, row[pkCol])\n }\n }\n }\n }\n\n report.tables[tableName] = {\n insertedCount: rows.length,\n durationMs: Date.now() - tableStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(tableName, report.tables[tableName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[tableName] = {\n insertedCount: 0,\n durationMs: Date.now() - tableStartTime,\n error: err.message,\n }\n report.errors.push(err)\n if (!options.dryRun) {\n await adapter.rollback()\n throw err\n }\n }\n }\n\n if (!options.dryRun) {\n await adapter.commit()\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n schema: MongoSchema,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).uri)\n\n try {\n await adapter.connect()\n\n const collectionsToSeed = options.includeTables || Object.keys(schema.collections)\n\n if (options.truncate && collectionsToSeed.length > 0) {\n if (!options.dryRun && adapter.truncateCollections) {\n await adapter.truncateCollections(collectionsToSeed)\n }\n }\n\n for (const collName of collectionsToSeed) {\n const collStartTime = Date.now()\n const collSchema = schema.collections[collName]\n if (!collSchema) continue\n\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[collName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n // Map MongoCollectionSchema to TableSchema for generateRows\n const tableSchema: TableSchema = {\n name: collName,\n columns: collSchema.fields,\n foreignKeys: Object.entries(collSchema.references || {}).map(([col, ref]) => {\n const [refTable, refCol] = ref.split('.')\n return { columns: [col], referencedTable: refTable, referencedColumns: [refCol] }\n }),\n uniqueConstraints: [],\n }\n\n let docs = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n docs = await options.hooks.beforeInsert(collName, docs)\n }\n\n await adapter.insertMany(collName, docs)\n\n // Record IDs for future reference resolution\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(collName, report.tables[collName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { MongoSeedConfig } from './types.js'\n\nexport function createMongoPlan(config: MongoSeedConfig): string[] {\n const collections = Object.keys(config.mongodb.collections)\n const adj = new Map<string, string[]>()\n\n for (const [name, coll] of Object.entries(config.mongodb.collections)) {\n const deps: string[] = []\n for (const field of Object.values(coll.fields)) {\n if (typeof field === 'object' && field.ref) {\n const [refColl] = field.ref.split('.')\n if (!config.mongodb.collections[refColl]) {\n throw new Error(`Reference ${field.ref} not found. Ensure ${refColl} collection is defined in config.`)\n }\n if (refColl !== name) {\n deps.push(refColl)\n }\n }\n }\n adj.set(name, deps)\n }\n\n const visited = new Set<string>()\n const visiting = new Set<string>()\n const order: string[] = []\n\n function visit(name: string) {\n if (visiting.has(name)) {\n throw new Error(`Circular reference detected involving collection: ${name}`)\n }\n if (visited.has(name)) return\n\n visiting.add(name)\n for (const dep of adj.get(name) || []) {\n visit(dep)\n }\n visiting.delete(name)\n visited.add(name)\n order.push(name)\n }\n\n for (const name of collections) {\n visit(name)\n }\n\n return order\n}\n","import { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { MongoFieldConfig, MongoFieldType } from './types.js'\n\nexport interface MongoGeneratorContext {\n random: Random\n refs: ReferenceRegistry\n generators: Record<string, (ctx: any) => any>\n}\n\nexport function generateMongoDocument(\n fields: Record<string, MongoFieldConfig>,\n ctx: MongoGeneratorContext\n): any {\n const doc: any = {}\n for (const [name, config] of Object.entries(fields)) {\n doc[name] = generateFieldValue(config, ctx)\n }\n return doc\n}\n\nfunction generateFieldValue(config: MongoFieldConfig, ctx: MongoGeneratorContext): any {\n if (typeof config === 'string') {\n return generateByType(config as MongoFieldType, {}, ctx)\n }\n\n const cfg = config as any\n\n if (cfg.ref) {\n const [refColl, refField] = cfg.ref.split('.')\n const val = ctx.refs.getRandomReference(refColl, ctx.random)\n if (val === null) {\n throw new Error(`Reference ${cfg.ref} not found. Ensure ${refColl} collection is seeded first.`)\n }\n return val\n }\n\n if (cfg.type === 'enum') {\n return ctx.random.pick(cfg.values || [], cfg.weights)\n }\n\n if (cfg.type === 'object') {\n return generateMongoDocument(cfg.fields || {}, ctx)\n }\n\n if (cfg.type === 'array') {\n const count = ctx.random.nextInt(cfg.minItems ?? 1, cfg.maxItems ?? 5)\n return Array.from({ length: count }, () => generateFieldValue(cfg.of!, ctx))\n }\n\n return generateByType(cfg.type!, cfg, ctx)\n}\n\nfunction generateByType(type: MongoFieldType, config: any, ctx: MongoGeneratorContext): any {\n switch (type) {\n case 'objectId':\n return generateObjectId(ctx.random)\n case 'int':\n return ctx.random.nextInt(config.min ?? 0, config.max ?? 1000000)\n case 'float':\n case 'decimal':\n return parseFloat((ctx.random.next() * ((config.max ?? 100) - (config.min ?? 0)) + (config.min ?? 0)).toFixed(2))\n case 'boolean':\n return ctx.random.boolean()\n case 'date':\n return new Date(ctx.random.nextInt(0, Date.now())).toISOString()\n case 'dateRecent':\n return ctx.generators.dateRecent(ctx)\n case 'dateBetween': {\n const from = new Date(config.from ?? '2020-01-01').getTime()\n const to = new Date(config.to ?? Date.now()).getTime()\n return new Date(ctx.random.nextInt(from, to)).toISOString()\n }\n case 'email':\n return ctx.generators.email(ctx)\n case 'firstName':\n return ctx.generators.firstName(ctx)\n case 'lastName':\n return ctx.generators.lastName(ctx)\n case 'fullName':\n return ctx.generators.fullName(ctx)\n case 'city':\n return ctx.generators.city(ctx)\n case 'country':\n return ctx.generators.country(ctx)\n case 'street':\n return ctx.generators.address(ctx)\n case 'phone':\n return ctx.generators.phone(ctx)\n case 'uuid':\n return ctx.generators.uuid(ctx)\n case 'string':\n return ctx.generators.firstName(ctx) // Fallback\n default:\n // If it matches a generator name, use it\n if (ctx.generators[type]) {\n return ctx.generators[type](ctx)\n }\n return null\n }\n}\n\nfunction generateObjectId(random: Random): string {\n const chars = '0123456789abcdef'\n let id = ''\n for (let i = 0; i < 24; i++) {\n id += chars[random.nextInt(0, 15)]\n }\n return id\n}\n","import { MongoSeedConfig, MongoCollectionConfig } from './types.js'\nimport { createMongoPlan } from './planner.js'\nimport { generateMongoDocument } from './generator.js'\nimport { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { EffectReport, RunnerContext } from '../types.js'\nimport { MongoAdapter } from '../adapter.js'\n\nfunction checkProductionSafety(options: { allowProduction?: boolean }, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n config: MongoSeedConfig,\n options: { dryRun?: boolean; allowProduction?: boolean } = {},\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(config.seed || Date.now())\n const refs = new ReferenceRegistry()\n\n checkProductionSafety(options, config.mongodb.uri)\n\n // Validations\n if (!config.mongodb?.collections || Object.keys(config.mongodb.collections).length === 0) {\n throw new Error('No collections defined in MongoDB config.')\n }\n\n for (const [name, coll] of Object.entries(config.mongodb.collections) as [string, MongoCollectionConfig][]) {\n if (coll.rows <= 0) {\n throw new Error(`Collection ${name} must have rows > 0.`)\n }\n if (!coll.fields || Object.keys(coll.fields).length === 0) {\n throw new Error(`Collection ${name} must have fields defined.`)\n }\n for (const [fieldName, field] of Object.entries(coll.fields)) {\n if (typeof field === 'object' && field !== null && 'type' in field && field.type === 'enum') {\n const enumField = field as any\n if (enumField.weights && enumField.values && enumField.weights.length !== enumField.values.length) {\n throw new Error(`Enum weights and values length mismatch in ${name}.${fieldName}`)\n }\n }\n }\n }\n\n try {\n await adapter.connect()\n\n const plan = createMongoPlan(config)\n\n for (const collName of plan) {\n const collStartTime = Date.now()\n const collConfig = config.mongodb.collections[collName]\n const docs: any[] = []\n\n try {\n for (let i = 0; i < collConfig.rows; i++) {\n const doc = generateMongoDocument(collConfig.fields, {\n random,\n refs,\n generators: context.generators\n })\n docs.push(doc)\n }\n\n if (!options.dryRun) {\n await adapter.insertMany(collName, docs)\n\n // Store IDs for references\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToConsole(report: EffectReport) {\n console.log('\\n๐Ÿš€ Seed Report')\n console.log('====================================')\n console.log(`Status: ${report.success ? 'โœ… Success' : 'โŒ Failed'}`)\n console.log(`Duration: ${report.durationMs}ms`)\n console.log('------------------------------------')\n\n console.table(\n Object.entries(report.tables).map(([name, stats]) => ({\n Table: name,\n Rows: stats.insertedCount,\n Time: `${stats.durationMs}ms`,\n Status: stats.error ? 'โŒ' : 'โœ…'\n }))\n )\n\n if (report.errors.length > 0) {\n console.log('\\nErrors:')\n report.errors.forEach((err, i) => {\n console.log(`${i + 1}. ${err.message}`)\n })\n }\n console.log('====================================\\n')\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToJson(report: EffectReport): string {\n return JSON.stringify(report, (key, value) => {\n if (value instanceof Error) {\n return { message: value.message, stack: value.stack }\n }\n return value\n }, 2)\n}\n"],"mappings":"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","names":["NormalizedSqlType","module","checkProductionSafety"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/random.ts","../src/types.ts","../src/uniqueness.ts","../src/redaction.ts","../src/planner/graph.ts","../src/planner/toposort.ts","../src/planner/cycles.ts","../src/planner/plan.ts","../src/generate/refs.ts","../src/generate/row.ts","../src/plugins.ts","../src/validation.ts","../src/runner.ts","../src/mongo/planner.ts","../src/mongo/generator.ts","../src/mongo/runner.ts","../src/reporters/console.ts","../src/reporters/json.ts"],"sourcesContent":["export * from './random.js'\nexport * from './types.js'\nexport * from './adapter.js'\nexport * from './uniqueness.js'\nexport * from './redaction.js'\nexport * from './planner/graph.js'\nexport * from './planner/toposort.js'\nexport * from './planner/cycles.js'\nexport * from './planner/plan.js'\nexport * from './generate/refs.js'\nexport * from './generate/row.js'\nexport { runSeedSql } from './runner.js'\nexport { runSeedMongo } from './mongo/runner.js'\nexport * from './mongo/types.js'\nexport type { MongoSeedConfig } from './mongo/types.js'\nexport { loadPlugins } from './plugins.js'\nexport { reportToConsole } from './reporters/console.js'\nexport { reportToJson } from './reporters/json.js'\n\nexport const version = '0.0.1'\n\nexport function defineSeed(options: import('./types.js').SeedOptions) {\n return options\n}\n","/**\n * A deterministic pseudo-random number generator (PRNG) using the Mulberry32 algorithm.\n */\nexport class Random {\n private state: number\n\n constructor(seed: number | string) {\n this.state = typeof seed === 'string' ? this.hashString(seed) : seed\n }\n\n private hashString(str: string): number {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash |= 0\n }\n return hash\n }\n\n next(): number {\n let t = (this.state += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n nextInt(min: number, max: number): number {\n return Math.floor(this.next() * (max - min + 1)) + min\n }\n\n pick<T>(array: T[], weights?: number[]): T {\n if (!weights) {\n return array[this.nextInt(0, array.length - 1)]\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0)\n let r = this.next() * totalWeight\n for (let i = 0; i < array.length; i++) {\n r -= weights[i] || 0\n if (r <= 0) return array[i]\n }\n return array[array.length - 1]\n }\n\n boolean(probability = 0.5): boolean {\n return this.next() < probability\n }\n}\n","/**\n * Normalized SQL types that map various database-specific types to a common set.\n */\nexport enum NormalizedSqlType {\n STRING = 'string',\n TEXT = 'text',\n INT = 'int',\n BIGINT = 'bigint',\n FLOAT = 'float',\n DECIMAL = 'decimal',\n BOOLEAN = 'boolean',\n DATE = 'date',\n DATETIME = 'datetime',\n JSON = 'json',\n UUID = 'uuid',\n ENUM = 'enum',\n BINARY = 'binary',\n OBJECTID = 'objectid',\n}\n\n/**\n * Metadata for a single column in a table.\n */\nexport interface ColumnSchema {\n name: string\n type: NormalizedSqlType\n /** The raw database-specific type string */\n rawType: string\n nullable: boolean\n defaultValue?: any\n /** For ENUM types, the list of allowed values */\n enumValues?: string[]\n /** Precision for decimal/float types */\n precision?: number\n /** Scale for decimal types */\n scale?: number\n /** Maximum length for string/binary types */\n maxLength?: number\n /** Whether this column is auto-incrementing / identity */\n isAutoIncrement: boolean\n /** Documentation or comments from the database */\n comment?: string\n}\n\n/**\n * Primary key definition.\n */\nexport interface PrimaryKeySchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Foreign key relationship definition.\n */\nexport interface ForeignKeySchema {\n name?: string\n /** Columns in the current table */\n columns: string[]\n /** Referenced table name */\n referencedTable: string\n /** Referenced columns in the target table */\n referencedColumns: string[]\n onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n}\n\n/**\n * Unique constraint definition.\n */\nexport interface UniqueConstraintSchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Metadata for a single table.\n */\nexport interface TableSchema {\n name: string\n schema?: string\n columns: Record<string, ColumnSchema>\n primaryKey?: PrimaryKeySchema\n foreignKeys: ForeignKeySchema[]\n uniqueConstraints: UniqueConstraintSchema[]\n /** Estimated or actual row count */\n rowCount?: number\n comment?: string\n}\n\n/**\n * A complete representation of the database schema as a graph of tables.\n */\nexport interface SchemaGraph {\n tables: Record<string, TableSchema>\n}\n\n/**\n * Metadata for a single MongoDB collection.\n */\nexport interface MongoCollectionSchema {\n name: string\n fields: Record<string, ColumnSchema>\n /** Mapping of field names to referenced collections and fields, e.g. { \"userId\": \"users._id\" } */\n references?: Record<string, string>\n}\n\n/**\n * A complete representation of the MongoDB schema.\n */\nexport interface MongoSchema {\n collections: Record<string, MongoCollectionSchema>\n}\n\n/**\n * A batch of data to be inserted into a table.\n */\nexport interface SeedBatch {\n tableName: string\n rows: Record<string, any>[]\n}\n\n/**\n * The execution plan for seeding the database.\n */\nexport interface SeedPlan {\n /** The order in which tables should be seeded to satisfy foreign key constraints */\n insertOrder: string[]\n /** Grouped batches for execution */\n batches: SeedBatch[]\n /** Mapping of virtual IDs to actual database IDs for resolving references */\n referencesMap: Map<string, any>\n}\n\nexport type OverrideFunction = (ctx: { i: number; random: any; refs: any }) => any\n\nexport interface WeightedEnumOverride {\n enum: any[]\n weights?: number[]\n}\n\nexport interface DateBetweenOverride {\n dateBetween: [string | Date, string | Date]\n}\n\nexport type ColumnOverride = OverrideFunction | WeightedEnumOverride | DateBetweenOverride | any\n\nexport type TableOverrides = Record<string, ColumnOverride>\n\nexport interface Hooks {\n beforeInsert?: (table: string, rows: any[]) => any[] | Promise<any[]>\n afterInsert?: (table: string, result: { insertedCount: number; durationMs: number }) => void | Promise<void>\n}\n\nexport interface Plugin {\n name: string\n overrides?: Record<string, TableOverrides>\n generators?: Record<string, (ctx: any) => any>\n hooks?: Hooks\n}\n\n/**\n * Options for the seeding process.\n */\nexport interface SeedOptions {\n /** Number of rows to generate per table (can be a global number or per-table map) */\n rows?: number | Record<string, number>\n /** Seed for the random number generator to ensure reproducibility */\n seed?: number | string\n /** If true, only show what would happen without executing any writes */\n dryRun?: boolean\n /** Number of rows to insert in a single batch */\n batchSize?: number\n /** Safety flag to allow running against production environments */\n allowProduction?: boolean\n /** If true, also seed parent tables required by foreign keys even if not explicitly requested */\n withParents?: boolean\n /** If true, truncate tables before seeding */\n truncate?: boolean\n /** Specific tables to include in the seeding process */\n includeTables?: string[]\n /** Specific tables to exclude from the seeding process */\n excludeTables?: string[]\n /** Custom overrides for specific tables and columns */\n overrides?: Record<string, TableOverrides>\n /** Lifecycle hooks */\n hooks?: Hooks\n /** List of plugins to load */\n plugins?: (string | Plugin)[]\n}\n\nexport interface RunnerContext {\n generators: Record<string, (ctx: any) => any>\n inferGenerator: (columnName: string, sqlType: any) => { generatorId: string; options?: any }\n overrides?: Record<string, any>\n}\n\n/**\n * Detailed report of the seeding operation's effects.\n */\nexport interface EffectReport {\n success: boolean\n /** Total time taken in milliseconds */\n durationMs: number\n /** Stats per table */\n tables: Record<\n string,\n {\n insertedCount: number\n error?: string\n durationMs: number\n }\n >\n /** Any global errors that occurred during the process */\n errors: Error[]\n}\n","/**\n * Registry to track and enforce uniqueness for generated values.\n */\nexport class UniquenessRegistry {\n private registry: Map<string, Set<any>> = new Map()\n\n /**\n * Generates a unique key for a table and column.\n */\n private getRegistryKey(table: string, column: string): string {\n return `${table}.${column}`\n }\n\n /**\n * Attempts to generate a unique value using a generator function.\n * If the generated value is already in the registry, it retries up to `maxRetries` times.\n * If it still fails, it uses a deterministic fallback.\n * \n * @param table Table name\n * @param column Column name\n * @param generator Function that generates a value\n * @param maxRetries Maximum number of retries before fallback\n * @returns A unique value\n */\n async ensureUnique<T>(\n table: string,\n column: string,\n generator: () => T | Promise<T>,\n maxRetries = 100\n ): Promise<T> {\n const key = this.getRegistryKey(table, column)\n if (!this.registry.has(key)) {\n this.registry.set(key, new Set())\n }\n const usedValues = this.registry.get(key)!\n\n for (let i = 0; i < maxRetries; i++) {\n const value = await generator()\n if (!usedValues.has(value)) {\n usedValues.add(value)\n return value\n }\n }\n\n // Deterministic fallback: append a counter or hash if retries fail\n const fallbackValue = await generator()\n const finalValue = `${fallbackValue}_${usedValues.size}` as unknown as T\n usedValues.add(finalValue)\n return finalValue\n }\n\n /**\n * Clears the registry for a specific table/column or all.\n */\n clear(table?: string, column?: string) {\n if (table && column) {\n this.registry.delete(this.getRegistryKey(table, column))\n } else {\n this.registry.clear()\n }\n }\n}\n","/**\n * Helper to redact sensitive information from reports and logs.\n */\nexport class Redactor {\n private static readonly SENSITIVE_PATTERNS = [\n /password/i,\n /token/i,\n /secret/i,\n /api_?key/i,\n /auth/i,\n /cookie/i,\n /credit_?card/i,\n /ssn/i,\n ]\n\n /**\n * Checks if a column name is considered sensitive.\n */\n static isSensitive(columnName: string): boolean {\n return this.SENSITIVE_PATTERNS.some((pattern) => pattern.test(columnName))\n }\n\n /**\n * Redacts sensitive values in a row object.\n * @param row The row data to redact\n * @returns A new object with sensitive values replaced by a placeholder\n */\n static redactRow(row: Record<string, any>): Record<string, any> {\n const redacted: Record<string, any> = {}\n for (const [key, value] of Object.entries(row)) {\n if (this.isSensitive(key)) {\n redacted[key] = '[REDACTED]'\n } else {\n redacted[key] = value\n }\n }\n return redacted\n }\n\n /**\n * Redacts sensitive values in a list of rows.\n */\n static redactRows(rows: Record<string, any>[]): Record<string, any>[] {\n return rows.map((row) => this.redactRow(row))\n }\n}\n","import { SchemaGraph } from '../types.js'\n\nexport interface DependencyNode {\n tableName: string\n dependencies: Set<string> // Tables this table depends on\n dependents: Set<string> // Tables that depend on this table\n}\n\nexport class DependencyGraph {\n nodes: Map<string, DependencyNode> = new Map()\n\n constructor(schema: SchemaGraph) {\n // Initialize nodes\n for (const tableName of Object.keys(schema.tables)) {\n this.nodes.set(tableName, {\n tableName,\n dependencies: new Set(),\n dependents: new Set(),\n })\n }\n\n // Build edges from foreign keys\n for (const [tableName, table] of Object.entries(schema.tables)) {\n const node = this.nodes.get(tableName)!\n for (const fk of table.foreignKeys) {\n // Self-references are handled during cycle detection/resolution\n if (fk.referencedTable === tableName) continue\n\n if (this.nodes.has(fk.referencedTable)) {\n node.dependencies.add(fk.referencedTable)\n this.nodes.get(fk.referencedTable)!.dependents.add(tableName)\n }\n }\n }\n }\n\n getNodes() {\n return Array.from(this.nodes.values())\n }\n\n getNode(tableName: string) {\n return this.nodes.get(tableName)\n }\n}\n","import { DependencyGraph } from './graph.js'\n\nexport interface TopoSortResult {\n order: string[]\n cycles: string[][]\n}\n\n/**\n * Performs a topological sort on the dependency graph.\n * Uses Kahn's algorithm or DFS-based approach. Here we use DFS for easier cycle path extraction.\n */\nexport function topologicalSort(graph: DependencyGraph): TopoSortResult {\n const order: string[] = []\n const cycles: string[][] = []\n const visited = new Set<string>()\n const recStack = new Set<string>()\n const path: string[] = []\n\n function visit(tableName: string) {\n if (recStack.has(tableName)) {\n // Cycle detected\n const cycleStart = path.indexOf(tableName)\n cycles.push(path.slice(cycleStart))\n return\n }\n if (visited.has(tableName)) return\n\n visited.add(tableName)\n recStack.add(tableName)\n path.push(tableName)\n\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n visit(dep)\n }\n }\n\n recStack.delete(tableName)\n path.pop()\n order.push(tableName)\n }\n\n for (const node of graph.getNodes()) {\n if (!visited.has(node.tableName)) {\n visit(node.tableName)\n }\n }\n\n return { order, cycles }\n}\n","import { SchemaGraph, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\n\nexport interface CycleResolution {\n resolved: boolean\n strategy?: 'NULLABLE_FK' | 'DEFERRABLE'\n breakingTable?: string\n breakingColumn?: string\n}\n\n/**\n * Attempts to resolve cycles in the dependency graph.\n */\nexport function resolveCycles(\n cycles: string[][],\n schema: SchemaGraph,\n supportsDeferrable: boolean\n): CycleResolution[] {\n return cycles.map((cycle) => {\n // Strategy B: Deferrable constraints\n if (supportsDeferrable) {\n return { resolved: true, strategy: 'DEFERRABLE' }\n }\n\n // Strategy A: Nullable FK\n // Look for a table in the cycle that has a nullable foreign key pointing to another table in the cycle\n for (let i = 0; i < cycle.length; i++) {\n const currentTable = cycle[i]\n const nextTable = cycle[(i + 1) % cycle.length]\n const tableSchema = schema.tables[currentTable]\n\n const nullableFk = tableSchema.foreignKeys.find((fk) => {\n if (fk.referencedTable !== nextTable) return false\n // Check if all columns in this FK are nullable\n return fk.columns.every((colName) => tableSchema.columns[colName]?.nullable)\n })\n\n if (nullableFk) {\n return {\n resolved: true,\n strategy: 'NULLABLE_FK',\n breakingTable: currentTable,\n breakingColumn: nullableFk.columns[0], // Simplified: just track one\n }\n }\n }\n\n return { resolved: false }\n })\n}\n","import { SchemaGraph, SeedPlan, SeedOptions, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\nimport { topologicalSort } from './toposort.js'\nimport { resolveCycles } from './cycles.js'\n\nexport function createSeedPlan(\n schema: SchemaGraph,\n options: SeedOptions,\n supportsDeferrable = false\n): SeedPlan {\n const graph = new DependencyGraph(schema)\n const { order, cycles } = topologicalSort(graph)\n\n if (cycles.length > 0) {\n const resolutions = resolveCycles(cycles, schema, supportsDeferrable)\n const unresolvable = resolutions.filter((r) => !r.resolved)\n\n if (unresolvable.length > 0) {\n const cyclePaths = cycles\n .filter((_, i) => !resolutions[i].resolved)\n .map((c) => c.join(' -> '))\n .join('\\n')\n throw new Error(\n `Unresolvable cycles detected in schema:\\n${cyclePaths}\\nTry making one of the foreign keys nullable or use a database that supports deferrable constraints.`\n )\n }\n }\n\n let finalOrder = order\n\n // Apply include/exclude filters\n if (options.includeTables) {\n const includeSet = new Set(options.includeTables)\n if (options.withParents) {\n // Expand includeSet to include all parents\n const expanded = new Set<string>()\n const walk = (tableName: string) => {\n if (expanded.has(tableName)) return\n expanded.add(tableName)\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n walk(dep)\n }\n }\n }\n options.includeTables.forEach(walk)\n finalOrder = finalOrder.filter((t) => expanded.has(t))\n } else {\n finalOrder = finalOrder.filter((t) => includeSet.has(t))\n }\n }\n\n if (options.excludeTables) {\n const excludeSet = new Set(options.excludeTables)\n finalOrder = finalOrder.filter((t) => !excludeSet.has(t))\n }\n\n // Join table heuristics: tables with 2+ FKs and mostly FK columns\n // These should generally be seeded after their parents, which topological sort already handles.\n // But we can refine the order if needed. For now, toposort is sufficient.\n\n return {\n insertOrder: finalOrder,\n batches: [], // To be populated by the generator\n referencesMap: new Map(),\n }\n}\n\n/**\n * Heuristic to identify if a table is likely a join table.\n */\nexport function isJoinTable(table: TableSchema): boolean {\n const fkColumnCount = new Set(table.foreignKeys.flatMap((fk) => fk.columns)).size\n const totalColumnCount = Object.keys(table.columns).length\n\n return (\n table.foreignKeys.length >= 2 &&\n fkColumnCount >= totalColumnCount * 0.7 // 70% or more columns are FKs\n )\n}\n","import { Random } from '../random.js'\n\n/**\n * Registry to store and retrieve primary key values for foreign key resolution.\n */\nexport class ReferenceRegistry {\n private refs: Map<string, any[]> = new Map()\n\n /**\n * Records an inserted primary key for a table.\n */\n addReference(table: string, pk: any) {\n if (!this.refs.has(table)) {\n this.refs.set(table, [])\n }\n this.refs.get(table)!.push(pk)\n }\n\n /**\n * Picks a random primary key from the specified table.\n */\n getRandomReference(table: string, random: Random): any {\n const tableRefs = this.refs.get(table)\n if (!tableRefs || tableRefs.length === 0) {\n return null\n }\n return random.pick(tableRefs)\n }\n\n /**\n * Returns all recorded references for a table.\n */\n getReferences(table: string): any[] {\n return this.refs.get(table) || []\n }\n\n clear() {\n this.refs.clear()\n }\n}\n","import { TableSchema, ColumnSchema, NormalizedSqlType } from '../types.js'\nimport { Random } from '../random.js'\nimport { UniquenessRegistry } from '../uniqueness.js'\nimport { ReferenceRegistry } from './refs.js'\n\nexport interface GenerationContext {\n random: Random\n uniqueness: UniquenessRegistry\n refs: ReferenceRegistry\n /** Current row index in the batch */\n i: number\n /** Map of column name or table.column to a specific generator function */\n overrides?: Record<string, any>\n /** Map of generator IDs to their implementation */\n generators: Record<string, (ctx: any) => any>\n /** Function to infer generator ID from column metadata */\n inferGenerator: (columnName: string, sqlType: NormalizedSqlType) => { generatorId: string; options?: any }\n}\n\n/**\n * Generates multiple rows for a table.\n */\nexport async function generateRows(\n table: TableSchema,\n count: number,\n context: Omit<GenerationContext, 'i'>\n): Promise<Record<string, any>[]> {\n const rows: Record<string, any>[] = []\n for (let i = 0; i < count; i++) {\n rows.push(await generateRow(table, { ...context, i } as GenerationContext))\n }\n return rows\n}\n\n/**\n * Generates a single row for a table.\n */\nexport async function generateRow(\n table: TableSchema,\n context: GenerationContext\n): Promise<Record<string, any>> {\n const row: Record<string, any> = {}\n\n for (const column of Object.values(table.columns)) {\n // Skip auto-increment columns as they are handled by the DB\n if (column.isAutoIncrement) continue\n\n // Check for foreign keys\n const fk = table.foreignKeys.find((f) => f.columns.includes(column.name))\n if (fk) {\n const ref = context.refs.getRandomReference(fk.referencedTable, context.random)\n if (ref !== null) {\n // If it's a composite FK, we might need more complex logic. \n // For now, assume single column FK.\n row[column.name] = ref\n continue\n }\n }\n\n // Check for overrides\n const tableOverride = context.overrides?.[table.name]?.[column.name]\n const globalOverride = context.overrides?.[column.name]\n const override = tableOverride !== undefined ? tableOverride : globalOverride\n\n if (override !== undefined) {\n if (typeof override === 'function') {\n row[column.name] = await override({ i: context.i, random: context.random, refs: context.refs })\n continue\n } else if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n const values = override.enum\n const weights = override.weights\n row[column.name] = context.random.pick(values, weights)\n continue\n } else if ('dateBetween' in override) {\n const [start, end] = override.dateBetween\n const startTime = new Date(start).getTime()\n const endTime = new Date(end).getTime()\n const randomTime = context.random.nextInt(startTime, endTime)\n row[column.name] = new Date(randomTime).toISOString()\n continue\n }\n }\n // Literal value override\n row[column.name] = override\n continue\n }\n\n // Use semantic inference\n const { generatorId, options } = context.inferGenerator(column.name, column.type)\n const generator = context.generators[generatorId]\n\n if (generator) {\n // Wrap in uniqueness check if needed (e.g. if column is in uniqueConstraints)\n const isUnique = table.uniqueConstraints.some((uc) => uc.columns.includes(column.name)) ||\n table.primaryKey?.columns.includes(column.name)\n\n if (isUnique) {\n row[column.name] = await context.uniqueness.ensureUnique(\n table.name,\n column.name,\n () => generator({ ...context, options })\n )\n } else {\n row[column.name] = generator({ ...context, options })\n }\n } else {\n // Fallback to basic type-based generation if no generator found\n row[column.name] = generateDefaultValue(column, context.random)\n }\n }\n\n return row\n}\n\nfunction generateDefaultValue(column: ColumnSchema, random: Random): any {\n if (column.defaultValue !== undefined) return column.defaultValue\n if (column.nullable && random.boolean(0.1)) return null\n\n switch (column.type) {\n case NormalizedSqlType.INT:\n case NormalizedSqlType.BIGINT:\n return random.nextInt(1, 1000)\n case NormalizedSqlType.FLOAT:\n case NormalizedSqlType.DECIMAL:\n return parseFloat((random.next() * 100).toFixed(2))\n case NormalizedSqlType.BOOLEAN:\n return random.boolean()\n case NormalizedSqlType.DATE:\n case NormalizedSqlType.DATETIME:\n return new Date().toISOString()\n case NormalizedSqlType.JSON:\n return { mock: 'data' }\n case NormalizedSqlType.ENUM:\n return column.enumValues ? random.pick(column.enumValues) : 'VALUE'\n default:\n return 'mock-string'\n }\n}\n","import { Plugin, SeedOptions, RunnerContext } from './types.js'\n\nexport async function loadPlugins(options: SeedOptions, context: RunnerContext): Promise<void> {\n if (!options.plugins) return\n\n for (const pluginRef of options.plugins) {\n let plugin: Plugin\n if (typeof pluginRef === 'string') {\n try {\n // In a real scenario, we'd use dynamic import or a registry\n // For now, we'll assume it's already available or throw a helpful error\n const module = await import(pluginRef)\n plugin = module.default || module\n } catch (err: any) {\n throw new Error(`Failed to load plugin ${pluginRef}: ${err.message}`)\n }\n } else {\n plugin = pluginRef\n }\n\n // Merge plugin contributions\n if (plugin.generators) {\n context.generators = { ...context.generators, ...plugin.generators }\n }\n\n if (plugin.overrides) {\n options.overrides = mergeOverrides(options.overrides || {}, plugin.overrides)\n }\n\n if (plugin.hooks) {\n options.hooks = mergeHooks(options.hooks || {}, plugin.hooks)\n }\n }\n}\n\nfunction mergeOverrides(base: Record<string, any>, plugin: Record<string, any>): Record<string, any> {\n const merged = { ...base }\n for (const [table, tableOverrides] of Object.entries(plugin)) {\n merged[table] = { ...(merged[table] || {}), ...tableOverrides }\n }\n return merged\n}\n\nfunction mergeHooks(base: any, plugin: any): any {\n return {\n beforeInsert: async (table: string, rows: any[]) => {\n let currentRows = rows\n if (base.beforeInsert) currentRows = await base.beforeInsert(table, currentRows)\n if (plugin.beforeInsert) currentRows = await plugin.beforeInsert(table, currentRows)\n return currentRows\n },\n afterInsert: async (table: string, result: any) => {\n if (base.afterInsert) await base.afterInsert(table, result)\n if (plugin.afterInsert) await plugin.afterInsert(table, result)\n }\n }\n}\n","import { SeedOptions, TableOverrides } from './types.js'\n\nexport function validateOptions(options: SeedOptions): void {\n if (options.overrides) {\n for (const [tableName, tableOverrides] of Object.entries(options.overrides)) {\n if (typeof tableOverrides !== 'object' || tableOverrides === null) {\n throw new Error(`Invalid override for table \"${tableName}\": must be an object.`)\n }\n\n for (const [columnName, override] of Object.entries(tableOverrides)) {\n validateOverride(tableName, columnName, override)\n }\n }\n }\n}\n\nfunction validateOverride(table: string, column: string, override: any): void {\n if (typeof override === 'function') return\n\n if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n if (!Array.isArray(override.enum)) {\n throw new Error(`Invalid enum override for \"${table}.${column}\": \"enum\" must be an array.`)\n }\n if (override.weights && (!Array.isArray(override.weights) || override.weights.length !== override.enum.length)) {\n throw new Error(`Invalid weights for \"${table}.${column}\": \"weights\" must be an array of the same length as \"enum\".`)\n }\n return\n }\n\n if ('dateBetween' in override) {\n if (!Array.isArray(override.dateBetween) || override.dateBetween.length !== 2) {\n throw new Error(`Invalid dateBetween override for \"${table}.${column}\": must be an array of [start, end].`)\n }\n return\n }\n }\n\n // Literal values are always valid\n}\n","import { SqlAdapter, MongoAdapter } from './adapter.js'\nimport { SeedPlan, SeedOptions, EffectReport, TableSchema, MongoSchema, RunnerContext } from './types.js'\nimport { Random } from './random.js'\nimport { UniquenessRegistry } from './uniqueness.js'\nimport { ReferenceRegistry } from './generate/refs.js'\nimport { generateRows } from './generate/row.js'\nimport { Redactor } from './redaction.js'\nimport { loadPlugins } from './plugins.js'\nimport { validateOptions } from './validation.js'\n\nfunction checkProductionSafety(options: SeedOptions, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n // If URL parsing fails, we fallback to simple string check\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\n\nexport async function runSeedSql(\n adapter: SqlAdapter,\n schema: any, // SchemaGraph\n plan: SeedPlan,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).config?.connectionString || (adapter as any).config)\n\n try {\n await adapter.connect()\n\n if (options.truncate && plan.insertOrder.length > 0) {\n if (!options.allowProduction) {\n // Simple heuristic: check for common production indicators if needed\n // For now, we rely on the user's explicit flag\n }\n if (!options.dryRun) {\n await adapter.truncateTables([...plan.insertOrder].reverse())\n }\n }\n\n if (!options.dryRun) {\n await adapter.begin()\n }\n\n for (const tableName of plan.insertOrder) {\n const tableStartTime = Date.now()\n const tableSchema: TableSchema = schema.tables[tableName]\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[tableName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n let rows = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n rows = await options.hooks.beforeInsert(tableName, rows)\n }\n\n const batchSize = options.batchSize || 1000\n for (let i = 0; i < rows.length; i += batchSize) {\n const batch = rows.slice(i, i + batchSize)\n await adapter.insertBatch({ tableName, rows: batch })\n }\n\n // Record PKs for future FK resolution\n // This is a simplification: we assume the adapter might need to return IDs\n // or we use the generated ones if they aren't auto-inc\n for (const row of rows) {\n if (tableSchema.primaryKey) {\n // For simple single-column PKs\n const pkCol = tableSchema.primaryKey.columns[0]\n if (row[pkCol] !== undefined) {\n refs.addReference(tableName, row[pkCol])\n }\n }\n }\n }\n\n report.tables[tableName] = {\n insertedCount: rows.length,\n durationMs: Date.now() - tableStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(tableName, report.tables[tableName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[tableName] = {\n insertedCount: 0,\n durationMs: Date.now() - tableStartTime,\n error: err.message,\n }\n report.errors.push(err)\n if (!options.dryRun) {\n await adapter.rollback()\n throw err\n }\n }\n }\n\n if (!options.dryRun) {\n await adapter.commit()\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n schema: MongoSchema,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).uri)\n\n try {\n await adapter.connect()\n\n const collectionsToSeed = options.includeTables || Object.keys(schema.collections)\n\n if (options.truncate && collectionsToSeed.length > 0) {\n if (!options.dryRun && adapter.truncateCollections) {\n await adapter.truncateCollections(collectionsToSeed)\n }\n }\n\n for (const collName of collectionsToSeed) {\n const collStartTime = Date.now()\n const collSchema = schema.collections[collName]\n if (!collSchema) continue\n\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[collName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n // Map MongoCollectionSchema to TableSchema for generateRows\n const tableSchema: TableSchema = {\n name: collName,\n columns: collSchema.fields,\n foreignKeys: Object.entries(collSchema.references || {}).map(([col, ref]) => {\n const [refTable, refCol] = ref.split('.')\n return { columns: [col], referencedTable: refTable, referencedColumns: [refCol] }\n }),\n uniqueConstraints: [],\n }\n\n let docs = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n docs = await options.hooks.beforeInsert(collName, docs)\n }\n\n await adapter.insertMany(collName, docs)\n\n // Record IDs for future reference resolution\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(collName, report.tables[collName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { MongoSeedConfig } from './types.js'\n\nexport function createMongoPlan(config: MongoSeedConfig): string[] {\n const collections = Object.keys(config.mongodb.collections)\n const adj = new Map<string, string[]>()\n\n for (const [name, coll] of Object.entries(config.mongodb.collections)) {\n const deps: string[] = []\n for (const field of Object.values(coll.fields)) {\n if (typeof field === 'object' && field.ref) {\n const [refColl] = field.ref.split('.')\n if (!config.mongodb.collections[refColl]) {\n throw new Error(`Reference ${field.ref} not found. Ensure ${refColl} collection is defined in config.`)\n }\n if (refColl !== name) {\n deps.push(refColl)\n }\n }\n }\n adj.set(name, deps)\n }\n\n const visited = new Set<string>()\n const visiting = new Set<string>()\n const order: string[] = []\n\n function visit(name: string) {\n if (visiting.has(name)) {\n throw new Error(`Circular reference detected involving collection: ${name}`)\n }\n if (visited.has(name)) return\n\n visiting.add(name)\n for (const dep of adj.get(name) || []) {\n visit(dep)\n }\n visiting.delete(name)\n visited.add(name)\n order.push(name)\n }\n\n for (const name of collections) {\n visit(name)\n }\n\n return order\n}\n","import { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { MongoFieldConfig, MongoFieldType } from './types.js'\n\nexport interface MongoGeneratorContext {\n random: Random\n refs: ReferenceRegistry\n generators: Record<string, (ctx: any) => any>\n}\n\nexport function generateMongoDocument(\n fields: Record<string, MongoFieldConfig>,\n ctx: MongoGeneratorContext\n): any {\n const doc: any = {}\n for (const [name, config] of Object.entries(fields)) {\n doc[name] = generateFieldValue(config, ctx)\n }\n return doc\n}\n\nfunction generateFieldValue(config: MongoFieldConfig, ctx: MongoGeneratorContext): any {\n if (typeof config === 'string') {\n return generateByType(config as MongoFieldType, {}, ctx)\n }\n\n const cfg = config as any\n\n if (cfg.ref) {\n const [refColl, refField] = cfg.ref.split('.')\n const val = ctx.refs.getRandomReference(refColl, ctx.random)\n if (val === null) {\n throw new Error(`Reference ${cfg.ref} not found. Ensure ${refColl} collection is seeded first.`)\n }\n return val\n }\n\n if (cfg.type === 'enum') {\n return ctx.random.pick(cfg.values || [], cfg.weights)\n }\n\n if (cfg.type === 'object') {\n return generateMongoDocument(cfg.fields || {}, ctx)\n }\n\n if (cfg.type === 'array') {\n const count = ctx.random.nextInt(cfg.minItems ?? 1, cfg.maxItems ?? 5)\n return Array.from({ length: count }, () => generateFieldValue(cfg.of!, ctx))\n }\n\n return generateByType(cfg.type!, cfg, ctx)\n}\n\nfunction generateByType(type: MongoFieldType, config: any, ctx: MongoGeneratorContext): any {\n switch (type) {\n case 'objectId':\n return generateObjectId(ctx.random)\n case 'int':\n return ctx.random.nextInt(config.min ?? 0, config.max ?? 1000000)\n case 'float':\n case 'decimal':\n return parseFloat((ctx.random.next() * ((config.max ?? 100) - (config.min ?? 0)) + (config.min ?? 0)).toFixed(2))\n case 'boolean':\n return ctx.random.boolean()\n case 'date':\n return new Date(ctx.random.nextInt(0, Date.now())).toISOString()\n case 'dateRecent':\n return ctx.generators.dateRecent(ctx)\n case 'dateBetween': {\n const from = new Date(config.from ?? '2020-01-01').getTime()\n const to = new Date(config.to ?? Date.now()).getTime()\n return new Date(ctx.random.nextInt(from, to)).toISOString()\n }\n case 'email':\n return ctx.generators.email(ctx)\n case 'firstName':\n return ctx.generators.firstName(ctx)\n case 'lastName':\n return ctx.generators.lastName(ctx)\n case 'fullName':\n return ctx.generators.fullName(ctx)\n case 'city':\n return ctx.generators.city(ctx)\n case 'country':\n return ctx.generators.country(ctx)\n case 'street':\n return ctx.generators.address(ctx)\n case 'phone':\n return ctx.generators.phone(ctx)\n case 'uuid':\n return ctx.generators.uuid(ctx)\n case 'string':\n return ctx.generators.firstName(ctx) // Fallback\n default:\n // If it matches a generator name, use it\n if (ctx.generators[type]) {\n return ctx.generators[type](ctx)\n }\n return null\n }\n}\n\nfunction generateObjectId(random: Random): string {\n const chars = '0123456789abcdef'\n let id = ''\n for (let i = 0; i < 24; i++) {\n id += chars[random.nextInt(0, 15)]\n }\n return id\n}\n","import { MongoSeedConfig, MongoCollectionConfig } from './types.js'\nimport { createMongoPlan } from './planner.js'\nimport { generateMongoDocument } from './generator.js'\nimport { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { EffectReport, RunnerContext } from '../types.js'\nimport { MongoAdapter } from '../adapter.js'\n\nfunction checkProductionSafety(options: { allowProduction?: boolean }, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n config: MongoSeedConfig,\n options: { dryRun?: boolean; allowProduction?: boolean } = {},\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(config.seed || Date.now())\n const refs = new ReferenceRegistry()\n\n checkProductionSafety(options, config.mongodb.uri)\n\n // Validations\n if (!config.mongodb?.collections || Object.keys(config.mongodb.collections).length === 0) {\n throw new Error('No collections defined in MongoDB config.')\n }\n\n for (const [name, coll] of Object.entries(config.mongodb.collections) as [string, MongoCollectionConfig][]) {\n if (coll.rows <= 0) {\n throw new Error(`Collection ${name} must have rows > 0.`)\n }\n if (!coll.fields || Object.keys(coll.fields).length === 0) {\n throw new Error(`Collection ${name} must have fields defined.`)\n }\n for (const [fieldName, field] of Object.entries(coll.fields)) {\n if (typeof field === 'object' && field !== null && 'type' in field && field.type === 'enum') {\n const enumField = field as any\n if (enumField.weights && enumField.values && enumField.weights.length !== enumField.values.length) {\n throw new Error(`Enum weights and values length mismatch in ${name}.${fieldName}`)\n }\n }\n }\n }\n\n try {\n await adapter.connect()\n\n const plan = createMongoPlan(config)\n\n if (config.truncate && plan.length > 0) {\n if (!options.dryRun && adapter.truncateCollections) {\n console.log(`๐Ÿงน Truncating ${plan.length} collections...`)\n await adapter.truncateCollections(plan)\n }\n }\n\n for (const collName of plan) {\n const collStartTime = Date.now()\n const collConfig = config.mongodb.collections[collName]\n const docs: any[] = []\n\n try {\n for (let i = 0; i < collConfig.rows; i++) {\n const doc = generateMongoDocument(collConfig.fields, {\n random,\n refs,\n generators: context.generators\n })\n docs.push(doc)\n }\n\n if (!options.dryRun) {\n await adapter.insertMany(collName, docs)\n\n // Store IDs for references\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToConsole(report: EffectReport) {\n console.log('\\n๐Ÿš€ Seed Report')\n console.log('====================================')\n console.log(`Status: ${report.success ? 'โœ… Success' : 'โŒ Failed'}`)\n console.log(`Duration: ${report.durationMs}ms`)\n console.log('------------------------------------')\n\n console.table(\n Object.entries(report.tables).map(([name, stats]) => ({\n Table: name,\n Rows: stats.insertedCount,\n Time: `${stats.durationMs}ms`,\n Status: stats.error ? 'โŒ' : 'โœ…'\n }))\n )\n\n if (report.errors.length > 0) {\n console.log('\\nErrors:')\n report.errors.forEach((err, i) => {\n console.log(`${i + 1}. ${err.message}`)\n })\n }\n console.log('====================================\\n')\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToJson(report: EffectReport): string {\n return JSON.stringify(report, (key, value) => {\n if (value instanceof Error) {\n return { message: value.message, stack: value.stack }\n }\n return value\n }, 2)\n}\n"],"mappings":"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","names":["NormalizedSqlType","module","checkProductionSafety"]}
package/dist/index.js CHANGED
@@ -800,6 +800,12 @@ async function runSeedMongo(adapter, config, options = {}, context) {
800
800
  try {
801
801
  await adapter.connect();
802
802
  const plan = createMongoPlan(config);
803
+ if (config.truncate && plan.length > 0) {
804
+ if (!options.dryRun && adapter.truncateCollections) {
805
+ console.log(`\u{1F9F9} Truncating ${plan.length} collections...`);
806
+ await adapter.truncateCollections(plan);
807
+ }
808
+ }
803
809
  for (const collName of plan) {
804
810
  const collStartTime = Date.now();
805
811
  const collConfig = config.mongodb.collections[collName];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/random.ts","../src/types.ts","../src/uniqueness.ts","../src/redaction.ts","../src/planner/graph.ts","../src/planner/toposort.ts","../src/planner/cycles.ts","../src/planner/plan.ts","../src/generate/refs.ts","../src/generate/row.ts","../src/plugins.ts","../src/validation.ts","../src/runner.ts","../src/mongo/planner.ts","../src/mongo/generator.ts","../src/mongo/runner.ts","../src/reporters/console.ts","../src/reporters/json.ts","../src/index.ts"],"sourcesContent":["/**\n * A deterministic pseudo-random number generator (PRNG) using the Mulberry32 algorithm.\n */\nexport class Random {\n private state: number\n\n constructor(seed: number | string) {\n this.state = typeof seed === 'string' ? this.hashString(seed) : seed\n }\n\n private hashString(str: string): number {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash |= 0\n }\n return hash\n }\n\n next(): number {\n let t = (this.state += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n nextInt(min: number, max: number): number {\n return Math.floor(this.next() * (max - min + 1)) + min\n }\n\n pick<T>(array: T[], weights?: number[]): T {\n if (!weights) {\n return array[this.nextInt(0, array.length - 1)]\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0)\n let r = this.next() * totalWeight\n for (let i = 0; i < array.length; i++) {\n r -= weights[i] || 0\n if (r <= 0) return array[i]\n }\n return array[array.length - 1]\n }\n\n boolean(probability = 0.5): boolean {\n return this.next() < probability\n }\n}\n","/**\n * Normalized SQL types that map various database-specific types to a common set.\n */\nexport enum NormalizedSqlType {\n STRING = 'string',\n TEXT = 'text',\n INT = 'int',\n BIGINT = 'bigint',\n FLOAT = 'float',\n DECIMAL = 'decimal',\n BOOLEAN = 'boolean',\n DATE = 'date',\n DATETIME = 'datetime',\n JSON = 'json',\n UUID = 'uuid',\n ENUM = 'enum',\n BINARY = 'binary',\n OBJECTID = 'objectid',\n}\n\n/**\n * Metadata for a single column in a table.\n */\nexport interface ColumnSchema {\n name: string\n type: NormalizedSqlType\n /** The raw database-specific type string */\n rawType: string\n nullable: boolean\n defaultValue?: any\n /** For ENUM types, the list of allowed values */\n enumValues?: string[]\n /** Precision for decimal/float types */\n precision?: number\n /** Scale for decimal types */\n scale?: number\n /** Maximum length for string/binary types */\n maxLength?: number\n /** Whether this column is auto-incrementing / identity */\n isAutoIncrement: boolean\n /** Documentation or comments from the database */\n comment?: string\n}\n\n/**\n * Primary key definition.\n */\nexport interface PrimaryKeySchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Foreign key relationship definition.\n */\nexport interface ForeignKeySchema {\n name?: string\n /** Columns in the current table */\n columns: string[]\n /** Referenced table name */\n referencedTable: string\n /** Referenced columns in the target table */\n referencedColumns: string[]\n onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n}\n\n/**\n * Unique constraint definition.\n */\nexport interface UniqueConstraintSchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Metadata for a single table.\n */\nexport interface TableSchema {\n name: string\n schema?: string\n columns: Record<string, ColumnSchema>\n primaryKey?: PrimaryKeySchema\n foreignKeys: ForeignKeySchema[]\n uniqueConstraints: UniqueConstraintSchema[]\n /** Estimated or actual row count */\n rowCount?: number\n comment?: string\n}\n\n/**\n * A complete representation of the database schema as a graph of tables.\n */\nexport interface SchemaGraph {\n tables: Record<string, TableSchema>\n}\n\n/**\n * Metadata for a single MongoDB collection.\n */\nexport interface MongoCollectionSchema {\n name: string\n fields: Record<string, ColumnSchema>\n /** Mapping of field names to referenced collections and fields, e.g. { \"userId\": \"users._id\" } */\n references?: Record<string, string>\n}\n\n/**\n * A complete representation of the MongoDB schema.\n */\nexport interface MongoSchema {\n collections: Record<string, MongoCollectionSchema>\n}\n\n/**\n * A batch of data to be inserted into a table.\n */\nexport interface SeedBatch {\n tableName: string\n rows: Record<string, any>[]\n}\n\n/**\n * The execution plan for seeding the database.\n */\nexport interface SeedPlan {\n /** The order in which tables should be seeded to satisfy foreign key constraints */\n insertOrder: string[]\n /** Grouped batches for execution */\n batches: SeedBatch[]\n /** Mapping of virtual IDs to actual database IDs for resolving references */\n referencesMap: Map<string, any>\n}\n\nexport type OverrideFunction = (ctx: { i: number; random: any; refs: any }) => any\n\nexport interface WeightedEnumOverride {\n enum: any[]\n weights?: number[]\n}\n\nexport interface DateBetweenOverride {\n dateBetween: [string | Date, string | Date]\n}\n\nexport type ColumnOverride = OverrideFunction | WeightedEnumOverride | DateBetweenOverride | any\n\nexport type TableOverrides = Record<string, ColumnOverride>\n\nexport interface Hooks {\n beforeInsert?: (table: string, rows: any[]) => any[] | Promise<any[]>\n afterInsert?: (table: string, result: { insertedCount: number; durationMs: number }) => void | Promise<void>\n}\n\nexport interface Plugin {\n name: string\n overrides?: Record<string, TableOverrides>\n generators?: Record<string, (ctx: any) => any>\n hooks?: Hooks\n}\n\n/**\n * Options for the seeding process.\n */\nexport interface SeedOptions {\n /** Number of rows to generate per table (can be a global number or per-table map) */\n rows?: number | Record<string, number>\n /** Seed for the random number generator to ensure reproducibility */\n seed?: number | string\n /** If true, only show what would happen without executing any writes */\n dryRun?: boolean\n /** Number of rows to insert in a single batch */\n batchSize?: number\n /** Safety flag to allow running against production environments */\n allowProduction?: boolean\n /** If true, also seed parent tables required by foreign keys even if not explicitly requested */\n withParents?: boolean\n /** If true, truncate tables before seeding */\n truncate?: boolean\n /** Specific tables to include in the seeding process */\n includeTables?: string[]\n /** Specific tables to exclude from the seeding process */\n excludeTables?: string[]\n /** Custom overrides for specific tables and columns */\n overrides?: Record<string, TableOverrides>\n /** Lifecycle hooks */\n hooks?: Hooks\n /** List of plugins to load */\n plugins?: (string | Plugin)[]\n}\n\nexport interface RunnerContext {\n generators: Record<string, (ctx: any) => any>\n inferGenerator: (columnName: string, sqlType: any) => { generatorId: string; options?: any }\n overrides?: Record<string, any>\n}\n\n/**\n * Detailed report of the seeding operation's effects.\n */\nexport interface EffectReport {\n success: boolean\n /** Total time taken in milliseconds */\n durationMs: number\n /** Stats per table */\n tables: Record<\n string,\n {\n insertedCount: number\n error?: string\n durationMs: number\n }\n >\n /** Any global errors that occurred during the process */\n errors: Error[]\n}\n","/**\n * Registry to track and enforce uniqueness for generated values.\n */\nexport class UniquenessRegistry {\n private registry: Map<string, Set<any>> = new Map()\n\n /**\n * Generates a unique key for a table and column.\n */\n private getRegistryKey(table: string, column: string): string {\n return `${table}.${column}`\n }\n\n /**\n * Attempts to generate a unique value using a generator function.\n * If the generated value is already in the registry, it retries up to `maxRetries` times.\n * If it still fails, it uses a deterministic fallback.\n * \n * @param table Table name\n * @param column Column name\n * @param generator Function that generates a value\n * @param maxRetries Maximum number of retries before fallback\n * @returns A unique value\n */\n async ensureUnique<T>(\n table: string,\n column: string,\n generator: () => T | Promise<T>,\n maxRetries = 100\n ): Promise<T> {\n const key = this.getRegistryKey(table, column)\n if (!this.registry.has(key)) {\n this.registry.set(key, new Set())\n }\n const usedValues = this.registry.get(key)!\n\n for (let i = 0; i < maxRetries; i++) {\n const value = await generator()\n if (!usedValues.has(value)) {\n usedValues.add(value)\n return value\n }\n }\n\n // Deterministic fallback: append a counter or hash if retries fail\n const fallbackValue = await generator()\n const finalValue = `${fallbackValue}_${usedValues.size}` as unknown as T\n usedValues.add(finalValue)\n return finalValue\n }\n\n /**\n * Clears the registry for a specific table/column or all.\n */\n clear(table?: string, column?: string) {\n if (table && column) {\n this.registry.delete(this.getRegistryKey(table, column))\n } else {\n this.registry.clear()\n }\n }\n}\n","/**\n * Helper to redact sensitive information from reports and logs.\n */\nexport class Redactor {\n private static readonly SENSITIVE_PATTERNS = [\n /password/i,\n /token/i,\n /secret/i,\n /api_?key/i,\n /auth/i,\n /cookie/i,\n /credit_?card/i,\n /ssn/i,\n ]\n\n /**\n * Checks if a column name is considered sensitive.\n */\n static isSensitive(columnName: string): boolean {\n return this.SENSITIVE_PATTERNS.some((pattern) => pattern.test(columnName))\n }\n\n /**\n * Redacts sensitive values in a row object.\n * @param row The row data to redact\n * @returns A new object with sensitive values replaced by a placeholder\n */\n static redactRow(row: Record<string, any>): Record<string, any> {\n const redacted: Record<string, any> = {}\n for (const [key, value] of Object.entries(row)) {\n if (this.isSensitive(key)) {\n redacted[key] = '[REDACTED]'\n } else {\n redacted[key] = value\n }\n }\n return redacted\n }\n\n /**\n * Redacts sensitive values in a list of rows.\n */\n static redactRows(rows: Record<string, any>[]): Record<string, any>[] {\n return rows.map((row) => this.redactRow(row))\n }\n}\n","import { SchemaGraph } from '../types.js'\n\nexport interface DependencyNode {\n tableName: string\n dependencies: Set<string> // Tables this table depends on\n dependents: Set<string> // Tables that depend on this table\n}\n\nexport class DependencyGraph {\n nodes: Map<string, DependencyNode> = new Map()\n\n constructor(schema: SchemaGraph) {\n // Initialize nodes\n for (const tableName of Object.keys(schema.tables)) {\n this.nodes.set(tableName, {\n tableName,\n dependencies: new Set(),\n dependents: new Set(),\n })\n }\n\n // Build edges from foreign keys\n for (const [tableName, table] of Object.entries(schema.tables)) {\n const node = this.nodes.get(tableName)!\n for (const fk of table.foreignKeys) {\n // Self-references are handled during cycle detection/resolution\n if (fk.referencedTable === tableName) continue\n\n if (this.nodes.has(fk.referencedTable)) {\n node.dependencies.add(fk.referencedTable)\n this.nodes.get(fk.referencedTable)!.dependents.add(tableName)\n }\n }\n }\n }\n\n getNodes() {\n return Array.from(this.nodes.values())\n }\n\n getNode(tableName: string) {\n return this.nodes.get(tableName)\n }\n}\n","import { DependencyGraph } from './graph.js'\n\nexport interface TopoSortResult {\n order: string[]\n cycles: string[][]\n}\n\n/**\n * Performs a topological sort on the dependency graph.\n * Uses Kahn's algorithm or DFS-based approach. Here we use DFS for easier cycle path extraction.\n */\nexport function topologicalSort(graph: DependencyGraph): TopoSortResult {\n const order: string[] = []\n const cycles: string[][] = []\n const visited = new Set<string>()\n const recStack = new Set<string>()\n const path: string[] = []\n\n function visit(tableName: string) {\n if (recStack.has(tableName)) {\n // Cycle detected\n const cycleStart = path.indexOf(tableName)\n cycles.push(path.slice(cycleStart))\n return\n }\n if (visited.has(tableName)) return\n\n visited.add(tableName)\n recStack.add(tableName)\n path.push(tableName)\n\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n visit(dep)\n }\n }\n\n recStack.delete(tableName)\n path.pop()\n order.push(tableName)\n }\n\n for (const node of graph.getNodes()) {\n if (!visited.has(node.tableName)) {\n visit(node.tableName)\n }\n }\n\n return { order, cycles }\n}\n","import { SchemaGraph, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\n\nexport interface CycleResolution {\n resolved: boolean\n strategy?: 'NULLABLE_FK' | 'DEFERRABLE'\n breakingTable?: string\n breakingColumn?: string\n}\n\n/**\n * Attempts to resolve cycles in the dependency graph.\n */\nexport function resolveCycles(\n cycles: string[][],\n schema: SchemaGraph,\n supportsDeferrable: boolean\n): CycleResolution[] {\n return cycles.map((cycle) => {\n // Strategy B: Deferrable constraints\n if (supportsDeferrable) {\n return { resolved: true, strategy: 'DEFERRABLE' }\n }\n\n // Strategy A: Nullable FK\n // Look for a table in the cycle that has a nullable foreign key pointing to another table in the cycle\n for (let i = 0; i < cycle.length; i++) {\n const currentTable = cycle[i]\n const nextTable = cycle[(i + 1) % cycle.length]\n const tableSchema = schema.tables[currentTable]\n\n const nullableFk = tableSchema.foreignKeys.find((fk) => {\n if (fk.referencedTable !== nextTable) return false\n // Check if all columns in this FK are nullable\n return fk.columns.every((colName) => tableSchema.columns[colName]?.nullable)\n })\n\n if (nullableFk) {\n return {\n resolved: true,\n strategy: 'NULLABLE_FK',\n breakingTable: currentTable,\n breakingColumn: nullableFk.columns[0], // Simplified: just track one\n }\n }\n }\n\n return { resolved: false }\n })\n}\n","import { SchemaGraph, SeedPlan, SeedOptions, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\nimport { topologicalSort } from './toposort.js'\nimport { resolveCycles } from './cycles.js'\n\nexport function createSeedPlan(\n schema: SchemaGraph,\n options: SeedOptions,\n supportsDeferrable = false\n): SeedPlan {\n const graph = new DependencyGraph(schema)\n const { order, cycles } = topologicalSort(graph)\n\n if (cycles.length > 0) {\n const resolutions = resolveCycles(cycles, schema, supportsDeferrable)\n const unresolvable = resolutions.filter((r) => !r.resolved)\n\n if (unresolvable.length > 0) {\n const cyclePaths = cycles\n .filter((_, i) => !resolutions[i].resolved)\n .map((c) => c.join(' -> '))\n .join('\\n')\n throw new Error(\n `Unresolvable cycles detected in schema:\\n${cyclePaths}\\nTry making one of the foreign keys nullable or use a database that supports deferrable constraints.`\n )\n }\n }\n\n let finalOrder = order\n\n // Apply include/exclude filters\n if (options.includeTables) {\n const includeSet = new Set(options.includeTables)\n if (options.withParents) {\n // Expand includeSet to include all parents\n const expanded = new Set<string>()\n const walk = (tableName: string) => {\n if (expanded.has(tableName)) return\n expanded.add(tableName)\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n walk(dep)\n }\n }\n }\n options.includeTables.forEach(walk)\n finalOrder = finalOrder.filter((t) => expanded.has(t))\n } else {\n finalOrder = finalOrder.filter((t) => includeSet.has(t))\n }\n }\n\n if (options.excludeTables) {\n const excludeSet = new Set(options.excludeTables)\n finalOrder = finalOrder.filter((t) => !excludeSet.has(t))\n }\n\n // Join table heuristics: tables with 2+ FKs and mostly FK columns\n // These should generally be seeded after their parents, which topological sort already handles.\n // But we can refine the order if needed. For now, toposort is sufficient.\n\n return {\n insertOrder: finalOrder,\n batches: [], // To be populated by the generator\n referencesMap: new Map(),\n }\n}\n\n/**\n * Heuristic to identify if a table is likely a join table.\n */\nexport function isJoinTable(table: TableSchema): boolean {\n const fkColumnCount = new Set(table.foreignKeys.flatMap((fk) => fk.columns)).size\n const totalColumnCount = Object.keys(table.columns).length\n\n return (\n table.foreignKeys.length >= 2 &&\n fkColumnCount >= totalColumnCount * 0.7 // 70% or more columns are FKs\n )\n}\n","import { Random } from '../random.js'\n\n/**\n * Registry to store and retrieve primary key values for foreign key resolution.\n */\nexport class ReferenceRegistry {\n private refs: Map<string, any[]> = new Map()\n\n /**\n * Records an inserted primary key for a table.\n */\n addReference(table: string, pk: any) {\n if (!this.refs.has(table)) {\n this.refs.set(table, [])\n }\n this.refs.get(table)!.push(pk)\n }\n\n /**\n * Picks a random primary key from the specified table.\n */\n getRandomReference(table: string, random: Random): any {\n const tableRefs = this.refs.get(table)\n if (!tableRefs || tableRefs.length === 0) {\n return null\n }\n return random.pick(tableRefs)\n }\n\n /**\n * Returns all recorded references for a table.\n */\n getReferences(table: string): any[] {\n return this.refs.get(table) || []\n }\n\n clear() {\n this.refs.clear()\n }\n}\n","import { TableSchema, ColumnSchema, NormalizedSqlType } from '../types.js'\nimport { Random } from '../random.js'\nimport { UniquenessRegistry } from '../uniqueness.js'\nimport { ReferenceRegistry } from './refs.js'\n\nexport interface GenerationContext {\n random: Random\n uniqueness: UniquenessRegistry\n refs: ReferenceRegistry\n /** Current row index in the batch */\n i: number\n /** Map of column name or table.column to a specific generator function */\n overrides?: Record<string, any>\n /** Map of generator IDs to their implementation */\n generators: Record<string, (ctx: any) => any>\n /** Function to infer generator ID from column metadata */\n inferGenerator: (columnName: string, sqlType: NormalizedSqlType) => { generatorId: string; options?: any }\n}\n\n/**\n * Generates multiple rows for a table.\n */\nexport async function generateRows(\n table: TableSchema,\n count: number,\n context: Omit<GenerationContext, 'i'>\n): Promise<Record<string, any>[]> {\n const rows: Record<string, any>[] = []\n for (let i = 0; i < count; i++) {\n rows.push(await generateRow(table, { ...context, i } as GenerationContext))\n }\n return rows\n}\n\n/**\n * Generates a single row for a table.\n */\nexport async function generateRow(\n table: TableSchema,\n context: GenerationContext\n): Promise<Record<string, any>> {\n const row: Record<string, any> = {}\n\n for (const column of Object.values(table.columns)) {\n // Skip auto-increment columns as they are handled by the DB\n if (column.isAutoIncrement) continue\n\n // Check for foreign keys\n const fk = table.foreignKeys.find((f) => f.columns.includes(column.name))\n if (fk) {\n const ref = context.refs.getRandomReference(fk.referencedTable, context.random)\n if (ref !== null) {\n // If it's a composite FK, we might need more complex logic. \n // For now, assume single column FK.\n row[column.name] = ref\n continue\n }\n }\n\n // Check for overrides\n const tableOverride = context.overrides?.[table.name]?.[column.name]\n const globalOverride = context.overrides?.[column.name]\n const override = tableOverride !== undefined ? tableOverride : globalOverride\n\n if (override !== undefined) {\n if (typeof override === 'function') {\n row[column.name] = await override({ i: context.i, random: context.random, refs: context.refs })\n continue\n } else if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n const values = override.enum\n const weights = override.weights\n row[column.name] = context.random.pick(values, weights)\n continue\n } else if ('dateBetween' in override) {\n const [start, end] = override.dateBetween\n const startTime = new Date(start).getTime()\n const endTime = new Date(end).getTime()\n const randomTime = context.random.nextInt(startTime, endTime)\n row[column.name] = new Date(randomTime).toISOString()\n continue\n }\n }\n // Literal value override\n row[column.name] = override\n continue\n }\n\n // Use semantic inference\n const { generatorId, options } = context.inferGenerator(column.name, column.type)\n const generator = context.generators[generatorId]\n\n if (generator) {\n // Wrap in uniqueness check if needed (e.g. if column is in uniqueConstraints)\n const isUnique = table.uniqueConstraints.some((uc) => uc.columns.includes(column.name)) ||\n table.primaryKey?.columns.includes(column.name)\n\n if (isUnique) {\n row[column.name] = await context.uniqueness.ensureUnique(\n table.name,\n column.name,\n () => generator({ ...context, options })\n )\n } else {\n row[column.name] = generator({ ...context, options })\n }\n } else {\n // Fallback to basic type-based generation if no generator found\n row[column.name] = generateDefaultValue(column, context.random)\n }\n }\n\n return row\n}\n\nfunction generateDefaultValue(column: ColumnSchema, random: Random): any {\n if (column.defaultValue !== undefined) return column.defaultValue\n if (column.nullable && random.boolean(0.1)) return null\n\n switch (column.type) {\n case NormalizedSqlType.INT:\n case NormalizedSqlType.BIGINT:\n return random.nextInt(1, 1000)\n case NormalizedSqlType.FLOAT:\n case NormalizedSqlType.DECIMAL:\n return parseFloat((random.next() * 100).toFixed(2))\n case NormalizedSqlType.BOOLEAN:\n return random.boolean()\n case NormalizedSqlType.DATE:\n case NormalizedSqlType.DATETIME:\n return new Date().toISOString()\n case NormalizedSqlType.JSON:\n return { mock: 'data' }\n case NormalizedSqlType.ENUM:\n return column.enumValues ? random.pick(column.enumValues) : 'VALUE'\n default:\n return 'mock-string'\n }\n}\n","import { Plugin, SeedOptions, RunnerContext } from './types.js'\n\nexport async function loadPlugins(options: SeedOptions, context: RunnerContext): Promise<void> {\n if (!options.plugins) return\n\n for (const pluginRef of options.plugins) {\n let plugin: Plugin\n if (typeof pluginRef === 'string') {\n try {\n // In a real scenario, we'd use dynamic import or a registry\n // For now, we'll assume it's already available or throw a helpful error\n const module = await import(pluginRef)\n plugin = module.default || module\n } catch (err: any) {\n throw new Error(`Failed to load plugin ${pluginRef}: ${err.message}`)\n }\n } else {\n plugin = pluginRef\n }\n\n // Merge plugin contributions\n if (plugin.generators) {\n context.generators = { ...context.generators, ...plugin.generators }\n }\n\n if (plugin.overrides) {\n options.overrides = mergeOverrides(options.overrides || {}, plugin.overrides)\n }\n\n if (plugin.hooks) {\n options.hooks = mergeHooks(options.hooks || {}, plugin.hooks)\n }\n }\n}\n\nfunction mergeOverrides(base: Record<string, any>, plugin: Record<string, any>): Record<string, any> {\n const merged = { ...base }\n for (const [table, tableOverrides] of Object.entries(plugin)) {\n merged[table] = { ...(merged[table] || {}), ...tableOverrides }\n }\n return merged\n}\n\nfunction mergeHooks(base: any, plugin: any): any {\n return {\n beforeInsert: async (table: string, rows: any[]) => {\n let currentRows = rows\n if (base.beforeInsert) currentRows = await base.beforeInsert(table, currentRows)\n if (plugin.beforeInsert) currentRows = await plugin.beforeInsert(table, currentRows)\n return currentRows\n },\n afterInsert: async (table: string, result: any) => {\n if (base.afterInsert) await base.afterInsert(table, result)\n if (plugin.afterInsert) await plugin.afterInsert(table, result)\n }\n }\n}\n","import { SeedOptions, TableOverrides } from './types.js'\n\nexport function validateOptions(options: SeedOptions): void {\n if (options.overrides) {\n for (const [tableName, tableOverrides] of Object.entries(options.overrides)) {\n if (typeof tableOverrides !== 'object' || tableOverrides === null) {\n throw new Error(`Invalid override for table \"${tableName}\": must be an object.`)\n }\n\n for (const [columnName, override] of Object.entries(tableOverrides)) {\n validateOverride(tableName, columnName, override)\n }\n }\n }\n}\n\nfunction validateOverride(table: string, column: string, override: any): void {\n if (typeof override === 'function') return\n\n if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n if (!Array.isArray(override.enum)) {\n throw new Error(`Invalid enum override for \"${table}.${column}\": \"enum\" must be an array.`)\n }\n if (override.weights && (!Array.isArray(override.weights) || override.weights.length !== override.enum.length)) {\n throw new Error(`Invalid weights for \"${table}.${column}\": \"weights\" must be an array of the same length as \"enum\".`)\n }\n return\n }\n\n if ('dateBetween' in override) {\n if (!Array.isArray(override.dateBetween) || override.dateBetween.length !== 2) {\n throw new Error(`Invalid dateBetween override for \"${table}.${column}\": must be an array of [start, end].`)\n }\n return\n }\n }\n\n // Literal values are always valid\n}\n","import { SqlAdapter, MongoAdapter } from './adapter.js'\nimport { SeedPlan, SeedOptions, EffectReport, TableSchema, MongoSchema, RunnerContext } from './types.js'\nimport { Random } from './random.js'\nimport { UniquenessRegistry } from './uniqueness.js'\nimport { ReferenceRegistry } from './generate/refs.js'\nimport { generateRows } from './generate/row.js'\nimport { Redactor } from './redaction.js'\nimport { loadPlugins } from './plugins.js'\nimport { validateOptions } from './validation.js'\n\nfunction checkProductionSafety(options: SeedOptions, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n // If URL parsing fails, we fallback to simple string check\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\n\nexport async function runSeedSql(\n adapter: SqlAdapter,\n schema: any, // SchemaGraph\n plan: SeedPlan,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).config?.connectionString || (adapter as any).config)\n\n try {\n await adapter.connect()\n\n if (options.truncate && plan.insertOrder.length > 0) {\n if (!options.allowProduction) {\n // Simple heuristic: check for common production indicators if needed\n // For now, we rely on the user's explicit flag\n }\n if (!options.dryRun) {\n await adapter.truncateTables([...plan.insertOrder].reverse())\n }\n }\n\n if (!options.dryRun) {\n await adapter.begin()\n }\n\n for (const tableName of plan.insertOrder) {\n const tableStartTime = Date.now()\n const tableSchema: TableSchema = schema.tables[tableName]\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[tableName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n let rows = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n rows = await options.hooks.beforeInsert(tableName, rows)\n }\n\n const batchSize = options.batchSize || 1000\n for (let i = 0; i < rows.length; i += batchSize) {\n const batch = rows.slice(i, i + batchSize)\n await adapter.insertBatch({ tableName, rows: batch })\n }\n\n // Record PKs for future FK resolution\n // This is a simplification: we assume the adapter might need to return IDs\n // or we use the generated ones if they aren't auto-inc\n for (const row of rows) {\n if (tableSchema.primaryKey) {\n // For simple single-column PKs\n const pkCol = tableSchema.primaryKey.columns[0]\n if (row[pkCol] !== undefined) {\n refs.addReference(tableName, row[pkCol])\n }\n }\n }\n }\n\n report.tables[tableName] = {\n insertedCount: rows.length,\n durationMs: Date.now() - tableStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(tableName, report.tables[tableName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[tableName] = {\n insertedCount: 0,\n durationMs: Date.now() - tableStartTime,\n error: err.message,\n }\n report.errors.push(err)\n if (!options.dryRun) {\n await adapter.rollback()\n throw err\n }\n }\n }\n\n if (!options.dryRun) {\n await adapter.commit()\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n schema: MongoSchema,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).uri)\n\n try {\n await adapter.connect()\n\n const collectionsToSeed = options.includeTables || Object.keys(schema.collections)\n\n if (options.truncate && collectionsToSeed.length > 0) {\n if (!options.dryRun && adapter.truncateCollections) {\n await adapter.truncateCollections(collectionsToSeed)\n }\n }\n\n for (const collName of collectionsToSeed) {\n const collStartTime = Date.now()\n const collSchema = schema.collections[collName]\n if (!collSchema) continue\n\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[collName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n // Map MongoCollectionSchema to TableSchema for generateRows\n const tableSchema: TableSchema = {\n name: collName,\n columns: collSchema.fields,\n foreignKeys: Object.entries(collSchema.references || {}).map(([col, ref]) => {\n const [refTable, refCol] = ref.split('.')\n return { columns: [col], referencedTable: refTable, referencedColumns: [refCol] }\n }),\n uniqueConstraints: [],\n }\n\n let docs = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n docs = await options.hooks.beforeInsert(collName, docs)\n }\n\n await adapter.insertMany(collName, docs)\n\n // Record IDs for future reference resolution\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(collName, report.tables[collName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { MongoSeedConfig } from './types.js'\n\nexport function createMongoPlan(config: MongoSeedConfig): string[] {\n const collections = Object.keys(config.mongodb.collections)\n const adj = new Map<string, string[]>()\n\n for (const [name, coll] of Object.entries(config.mongodb.collections)) {\n const deps: string[] = []\n for (const field of Object.values(coll.fields)) {\n if (typeof field === 'object' && field.ref) {\n const [refColl] = field.ref.split('.')\n if (!config.mongodb.collections[refColl]) {\n throw new Error(`Reference ${field.ref} not found. Ensure ${refColl} collection is defined in config.`)\n }\n if (refColl !== name) {\n deps.push(refColl)\n }\n }\n }\n adj.set(name, deps)\n }\n\n const visited = new Set<string>()\n const visiting = new Set<string>()\n const order: string[] = []\n\n function visit(name: string) {\n if (visiting.has(name)) {\n throw new Error(`Circular reference detected involving collection: ${name}`)\n }\n if (visited.has(name)) return\n\n visiting.add(name)\n for (const dep of adj.get(name) || []) {\n visit(dep)\n }\n visiting.delete(name)\n visited.add(name)\n order.push(name)\n }\n\n for (const name of collections) {\n visit(name)\n }\n\n return order\n}\n","import { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { MongoFieldConfig, MongoFieldType } from './types.js'\n\nexport interface MongoGeneratorContext {\n random: Random\n refs: ReferenceRegistry\n generators: Record<string, (ctx: any) => any>\n}\n\nexport function generateMongoDocument(\n fields: Record<string, MongoFieldConfig>,\n ctx: MongoGeneratorContext\n): any {\n const doc: any = {}\n for (const [name, config] of Object.entries(fields)) {\n doc[name] = generateFieldValue(config, ctx)\n }\n return doc\n}\n\nfunction generateFieldValue(config: MongoFieldConfig, ctx: MongoGeneratorContext): any {\n if (typeof config === 'string') {\n return generateByType(config as MongoFieldType, {}, ctx)\n }\n\n const cfg = config as any\n\n if (cfg.ref) {\n const [refColl, refField] = cfg.ref.split('.')\n const val = ctx.refs.getRandomReference(refColl, ctx.random)\n if (val === null) {\n throw new Error(`Reference ${cfg.ref} not found. Ensure ${refColl} collection is seeded first.`)\n }\n return val\n }\n\n if (cfg.type === 'enum') {\n return ctx.random.pick(cfg.values || [], cfg.weights)\n }\n\n if (cfg.type === 'object') {\n return generateMongoDocument(cfg.fields || {}, ctx)\n }\n\n if (cfg.type === 'array') {\n const count = ctx.random.nextInt(cfg.minItems ?? 1, cfg.maxItems ?? 5)\n return Array.from({ length: count }, () => generateFieldValue(cfg.of!, ctx))\n }\n\n return generateByType(cfg.type!, cfg, ctx)\n}\n\nfunction generateByType(type: MongoFieldType, config: any, ctx: MongoGeneratorContext): any {\n switch (type) {\n case 'objectId':\n return generateObjectId(ctx.random)\n case 'int':\n return ctx.random.nextInt(config.min ?? 0, config.max ?? 1000000)\n case 'float':\n case 'decimal':\n return parseFloat((ctx.random.next() * ((config.max ?? 100) - (config.min ?? 0)) + (config.min ?? 0)).toFixed(2))\n case 'boolean':\n return ctx.random.boolean()\n case 'date':\n return new Date(ctx.random.nextInt(0, Date.now())).toISOString()\n case 'dateRecent':\n return ctx.generators.dateRecent(ctx)\n case 'dateBetween': {\n const from = new Date(config.from ?? '2020-01-01').getTime()\n const to = new Date(config.to ?? Date.now()).getTime()\n return new Date(ctx.random.nextInt(from, to)).toISOString()\n }\n case 'email':\n return ctx.generators.email(ctx)\n case 'firstName':\n return ctx.generators.firstName(ctx)\n case 'lastName':\n return ctx.generators.lastName(ctx)\n case 'fullName':\n return ctx.generators.fullName(ctx)\n case 'city':\n return ctx.generators.city(ctx)\n case 'country':\n return ctx.generators.country(ctx)\n case 'street':\n return ctx.generators.address(ctx)\n case 'phone':\n return ctx.generators.phone(ctx)\n case 'uuid':\n return ctx.generators.uuid(ctx)\n case 'string':\n return ctx.generators.firstName(ctx) // Fallback\n default:\n // If it matches a generator name, use it\n if (ctx.generators[type]) {\n return ctx.generators[type](ctx)\n }\n return null\n }\n}\n\nfunction generateObjectId(random: Random): string {\n const chars = '0123456789abcdef'\n let id = ''\n for (let i = 0; i < 24; i++) {\n id += chars[random.nextInt(0, 15)]\n }\n return id\n}\n","import { MongoSeedConfig, MongoCollectionConfig } from './types.js'\nimport { createMongoPlan } from './planner.js'\nimport { generateMongoDocument } from './generator.js'\nimport { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { EffectReport, RunnerContext } from '../types.js'\nimport { MongoAdapter } from '../adapter.js'\n\nfunction checkProductionSafety(options: { allowProduction?: boolean }, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n config: MongoSeedConfig,\n options: { dryRun?: boolean; allowProduction?: boolean } = {},\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(config.seed || Date.now())\n const refs = new ReferenceRegistry()\n\n checkProductionSafety(options, config.mongodb.uri)\n\n // Validations\n if (!config.mongodb?.collections || Object.keys(config.mongodb.collections).length === 0) {\n throw new Error('No collections defined in MongoDB config.')\n }\n\n for (const [name, coll] of Object.entries(config.mongodb.collections) as [string, MongoCollectionConfig][]) {\n if (coll.rows <= 0) {\n throw new Error(`Collection ${name} must have rows > 0.`)\n }\n if (!coll.fields || Object.keys(coll.fields).length === 0) {\n throw new Error(`Collection ${name} must have fields defined.`)\n }\n for (const [fieldName, field] of Object.entries(coll.fields)) {\n if (typeof field === 'object' && field !== null && 'type' in field && field.type === 'enum') {\n const enumField = field as any\n if (enumField.weights && enumField.values && enumField.weights.length !== enumField.values.length) {\n throw new Error(`Enum weights and values length mismatch in ${name}.${fieldName}`)\n }\n }\n }\n }\n\n try {\n await adapter.connect()\n\n const plan = createMongoPlan(config)\n\n for (const collName of plan) {\n const collStartTime = Date.now()\n const collConfig = config.mongodb.collections[collName]\n const docs: any[] = []\n\n try {\n for (let i = 0; i < collConfig.rows; i++) {\n const doc = generateMongoDocument(collConfig.fields, {\n random,\n refs,\n generators: context.generators\n })\n docs.push(doc)\n }\n\n if (!options.dryRun) {\n await adapter.insertMany(collName, docs)\n\n // Store IDs for references\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToConsole(report: EffectReport) {\n console.log('\\n๐Ÿš€ Seed Report')\n console.log('====================================')\n console.log(`Status: ${report.success ? 'โœ… Success' : 'โŒ Failed'}`)\n console.log(`Duration: ${report.durationMs}ms`)\n console.log('------------------------------------')\n\n console.table(\n Object.entries(report.tables).map(([name, stats]) => ({\n Table: name,\n Rows: stats.insertedCount,\n Time: `${stats.durationMs}ms`,\n Status: stats.error ? 'โŒ' : 'โœ…'\n }))\n )\n\n if (report.errors.length > 0) {\n console.log('\\nErrors:')\n report.errors.forEach((err, i) => {\n console.log(`${i + 1}. ${err.message}`)\n })\n }\n console.log('====================================\\n')\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToJson(report: EffectReport): string {\n return JSON.stringify(report, (key, value) => {\n if (value instanceof Error) {\n return { message: value.message, stack: value.stack }\n }\n return value\n }, 2)\n}\n","export * from './random.js'\nexport * from './types.js'\nexport * from './adapter.js'\nexport * from './uniqueness.js'\nexport * from './redaction.js'\nexport * from './planner/graph.js'\nexport * from './planner/toposort.js'\nexport * from './planner/cycles.js'\nexport * from './planner/plan.js'\nexport * from './generate/refs.js'\nexport * from './generate/row.js'\nexport { runSeedSql } from './runner.js'\nexport { runSeedMongo } from './mongo/runner.js'\nexport * from './mongo/types.js'\nexport type { MongoSeedConfig } from './mongo/types.js'\nexport { loadPlugins } from './plugins.js'\nexport { reportToConsole } from './reporters/console.js'\nexport { reportToJson } from './reporters/json.js'\n\nexport const version = '0.0.1'\n\nexport function defineSeed(options: import('./types.js').SeedOptions) {\n return options\n}\n"],"mappings":"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","names":["NormalizedSqlType","checkProductionSafety"]}
1
+ {"version":3,"sources":["../src/random.ts","../src/types.ts","../src/uniqueness.ts","../src/redaction.ts","../src/planner/graph.ts","../src/planner/toposort.ts","../src/planner/cycles.ts","../src/planner/plan.ts","../src/generate/refs.ts","../src/generate/row.ts","../src/plugins.ts","../src/validation.ts","../src/runner.ts","../src/mongo/planner.ts","../src/mongo/generator.ts","../src/mongo/runner.ts","../src/reporters/console.ts","../src/reporters/json.ts","../src/index.ts"],"sourcesContent":["/**\n * A deterministic pseudo-random number generator (PRNG) using the Mulberry32 algorithm.\n */\nexport class Random {\n private state: number\n\n constructor(seed: number | string) {\n this.state = typeof seed === 'string' ? this.hashString(seed) : seed\n }\n\n private hashString(str: string): number {\n let hash = 0\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i)\n hash = (hash << 5) - hash + char\n hash |= 0\n }\n return hash\n }\n\n next(): number {\n let t = (this.state += 0x6d2b79f5)\n t = Math.imul(t ^ (t >>> 15), t | 1)\n t ^= t + Math.imul(t ^ (t >>> 7), t | 61)\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296\n }\n\n nextInt(min: number, max: number): number {\n return Math.floor(this.next() * (max - min + 1)) + min\n }\n\n pick<T>(array: T[], weights?: number[]): T {\n if (!weights) {\n return array[this.nextInt(0, array.length - 1)]\n }\n const totalWeight = weights.reduce((a, b) => a + b, 0)\n let r = this.next() * totalWeight\n for (let i = 0; i < array.length; i++) {\n r -= weights[i] || 0\n if (r <= 0) return array[i]\n }\n return array[array.length - 1]\n }\n\n boolean(probability = 0.5): boolean {\n return this.next() < probability\n }\n}\n","/**\n * Normalized SQL types that map various database-specific types to a common set.\n */\nexport enum NormalizedSqlType {\n STRING = 'string',\n TEXT = 'text',\n INT = 'int',\n BIGINT = 'bigint',\n FLOAT = 'float',\n DECIMAL = 'decimal',\n BOOLEAN = 'boolean',\n DATE = 'date',\n DATETIME = 'datetime',\n JSON = 'json',\n UUID = 'uuid',\n ENUM = 'enum',\n BINARY = 'binary',\n OBJECTID = 'objectid',\n}\n\n/**\n * Metadata for a single column in a table.\n */\nexport interface ColumnSchema {\n name: string\n type: NormalizedSqlType\n /** The raw database-specific type string */\n rawType: string\n nullable: boolean\n defaultValue?: any\n /** For ENUM types, the list of allowed values */\n enumValues?: string[]\n /** Precision for decimal/float types */\n precision?: number\n /** Scale for decimal types */\n scale?: number\n /** Maximum length for string/binary types */\n maxLength?: number\n /** Whether this column is auto-incrementing / identity */\n isAutoIncrement: boolean\n /** Documentation or comments from the database */\n comment?: string\n}\n\n/**\n * Primary key definition.\n */\nexport interface PrimaryKeySchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Foreign key relationship definition.\n */\nexport interface ForeignKeySchema {\n name?: string\n /** Columns in the current table */\n columns: string[]\n /** Referenced table name */\n referencedTable: string\n /** Referenced columns in the target table */\n referencedColumns: string[]\n onUpdate?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n onDelete?: 'CASCADE' | 'SET NULL' | 'RESTRICT' | 'NO ACTION'\n}\n\n/**\n * Unique constraint definition.\n */\nexport interface UniqueConstraintSchema {\n name?: string\n columns: string[]\n}\n\n/**\n * Metadata for a single table.\n */\nexport interface TableSchema {\n name: string\n schema?: string\n columns: Record<string, ColumnSchema>\n primaryKey?: PrimaryKeySchema\n foreignKeys: ForeignKeySchema[]\n uniqueConstraints: UniqueConstraintSchema[]\n /** Estimated or actual row count */\n rowCount?: number\n comment?: string\n}\n\n/**\n * A complete representation of the database schema as a graph of tables.\n */\nexport interface SchemaGraph {\n tables: Record<string, TableSchema>\n}\n\n/**\n * Metadata for a single MongoDB collection.\n */\nexport interface MongoCollectionSchema {\n name: string\n fields: Record<string, ColumnSchema>\n /** Mapping of field names to referenced collections and fields, e.g. { \"userId\": \"users._id\" } */\n references?: Record<string, string>\n}\n\n/**\n * A complete representation of the MongoDB schema.\n */\nexport interface MongoSchema {\n collections: Record<string, MongoCollectionSchema>\n}\n\n/**\n * A batch of data to be inserted into a table.\n */\nexport interface SeedBatch {\n tableName: string\n rows: Record<string, any>[]\n}\n\n/**\n * The execution plan for seeding the database.\n */\nexport interface SeedPlan {\n /** The order in which tables should be seeded to satisfy foreign key constraints */\n insertOrder: string[]\n /** Grouped batches for execution */\n batches: SeedBatch[]\n /** Mapping of virtual IDs to actual database IDs for resolving references */\n referencesMap: Map<string, any>\n}\n\nexport type OverrideFunction = (ctx: { i: number; random: any; refs: any }) => any\n\nexport interface WeightedEnumOverride {\n enum: any[]\n weights?: number[]\n}\n\nexport interface DateBetweenOverride {\n dateBetween: [string | Date, string | Date]\n}\n\nexport type ColumnOverride = OverrideFunction | WeightedEnumOverride | DateBetweenOverride | any\n\nexport type TableOverrides = Record<string, ColumnOverride>\n\nexport interface Hooks {\n beforeInsert?: (table: string, rows: any[]) => any[] | Promise<any[]>\n afterInsert?: (table: string, result: { insertedCount: number; durationMs: number }) => void | Promise<void>\n}\n\nexport interface Plugin {\n name: string\n overrides?: Record<string, TableOverrides>\n generators?: Record<string, (ctx: any) => any>\n hooks?: Hooks\n}\n\n/**\n * Options for the seeding process.\n */\nexport interface SeedOptions {\n /** Number of rows to generate per table (can be a global number or per-table map) */\n rows?: number | Record<string, number>\n /** Seed for the random number generator to ensure reproducibility */\n seed?: number | string\n /** If true, only show what would happen without executing any writes */\n dryRun?: boolean\n /** Number of rows to insert in a single batch */\n batchSize?: number\n /** Safety flag to allow running against production environments */\n allowProduction?: boolean\n /** If true, also seed parent tables required by foreign keys even if not explicitly requested */\n withParents?: boolean\n /** If true, truncate tables before seeding */\n truncate?: boolean\n /** Specific tables to include in the seeding process */\n includeTables?: string[]\n /** Specific tables to exclude from the seeding process */\n excludeTables?: string[]\n /** Custom overrides for specific tables and columns */\n overrides?: Record<string, TableOverrides>\n /** Lifecycle hooks */\n hooks?: Hooks\n /** List of plugins to load */\n plugins?: (string | Plugin)[]\n}\n\nexport interface RunnerContext {\n generators: Record<string, (ctx: any) => any>\n inferGenerator: (columnName: string, sqlType: any) => { generatorId: string; options?: any }\n overrides?: Record<string, any>\n}\n\n/**\n * Detailed report of the seeding operation's effects.\n */\nexport interface EffectReport {\n success: boolean\n /** Total time taken in milliseconds */\n durationMs: number\n /** Stats per table */\n tables: Record<\n string,\n {\n insertedCount: number\n error?: string\n durationMs: number\n }\n >\n /** Any global errors that occurred during the process */\n errors: Error[]\n}\n","/**\n * Registry to track and enforce uniqueness for generated values.\n */\nexport class UniquenessRegistry {\n private registry: Map<string, Set<any>> = new Map()\n\n /**\n * Generates a unique key for a table and column.\n */\n private getRegistryKey(table: string, column: string): string {\n return `${table}.${column}`\n }\n\n /**\n * Attempts to generate a unique value using a generator function.\n * If the generated value is already in the registry, it retries up to `maxRetries` times.\n * If it still fails, it uses a deterministic fallback.\n * \n * @param table Table name\n * @param column Column name\n * @param generator Function that generates a value\n * @param maxRetries Maximum number of retries before fallback\n * @returns A unique value\n */\n async ensureUnique<T>(\n table: string,\n column: string,\n generator: () => T | Promise<T>,\n maxRetries = 100\n ): Promise<T> {\n const key = this.getRegistryKey(table, column)\n if (!this.registry.has(key)) {\n this.registry.set(key, new Set())\n }\n const usedValues = this.registry.get(key)!\n\n for (let i = 0; i < maxRetries; i++) {\n const value = await generator()\n if (!usedValues.has(value)) {\n usedValues.add(value)\n return value\n }\n }\n\n // Deterministic fallback: append a counter or hash if retries fail\n const fallbackValue = await generator()\n const finalValue = `${fallbackValue}_${usedValues.size}` as unknown as T\n usedValues.add(finalValue)\n return finalValue\n }\n\n /**\n * Clears the registry for a specific table/column or all.\n */\n clear(table?: string, column?: string) {\n if (table && column) {\n this.registry.delete(this.getRegistryKey(table, column))\n } else {\n this.registry.clear()\n }\n }\n}\n","/**\n * Helper to redact sensitive information from reports and logs.\n */\nexport class Redactor {\n private static readonly SENSITIVE_PATTERNS = [\n /password/i,\n /token/i,\n /secret/i,\n /api_?key/i,\n /auth/i,\n /cookie/i,\n /credit_?card/i,\n /ssn/i,\n ]\n\n /**\n * Checks if a column name is considered sensitive.\n */\n static isSensitive(columnName: string): boolean {\n return this.SENSITIVE_PATTERNS.some((pattern) => pattern.test(columnName))\n }\n\n /**\n * Redacts sensitive values in a row object.\n * @param row The row data to redact\n * @returns A new object with sensitive values replaced by a placeholder\n */\n static redactRow(row: Record<string, any>): Record<string, any> {\n const redacted: Record<string, any> = {}\n for (const [key, value] of Object.entries(row)) {\n if (this.isSensitive(key)) {\n redacted[key] = '[REDACTED]'\n } else {\n redacted[key] = value\n }\n }\n return redacted\n }\n\n /**\n * Redacts sensitive values in a list of rows.\n */\n static redactRows(rows: Record<string, any>[]): Record<string, any>[] {\n return rows.map((row) => this.redactRow(row))\n }\n}\n","import { SchemaGraph } from '../types.js'\n\nexport interface DependencyNode {\n tableName: string\n dependencies: Set<string> // Tables this table depends on\n dependents: Set<string> // Tables that depend on this table\n}\n\nexport class DependencyGraph {\n nodes: Map<string, DependencyNode> = new Map()\n\n constructor(schema: SchemaGraph) {\n // Initialize nodes\n for (const tableName of Object.keys(schema.tables)) {\n this.nodes.set(tableName, {\n tableName,\n dependencies: new Set(),\n dependents: new Set(),\n })\n }\n\n // Build edges from foreign keys\n for (const [tableName, table] of Object.entries(schema.tables)) {\n const node = this.nodes.get(tableName)!\n for (const fk of table.foreignKeys) {\n // Self-references are handled during cycle detection/resolution\n if (fk.referencedTable === tableName) continue\n\n if (this.nodes.has(fk.referencedTable)) {\n node.dependencies.add(fk.referencedTable)\n this.nodes.get(fk.referencedTable)!.dependents.add(tableName)\n }\n }\n }\n }\n\n getNodes() {\n return Array.from(this.nodes.values())\n }\n\n getNode(tableName: string) {\n return this.nodes.get(tableName)\n }\n}\n","import { DependencyGraph } from './graph.js'\n\nexport interface TopoSortResult {\n order: string[]\n cycles: string[][]\n}\n\n/**\n * Performs a topological sort on the dependency graph.\n * Uses Kahn's algorithm or DFS-based approach. Here we use DFS for easier cycle path extraction.\n */\nexport function topologicalSort(graph: DependencyGraph): TopoSortResult {\n const order: string[] = []\n const cycles: string[][] = []\n const visited = new Set<string>()\n const recStack = new Set<string>()\n const path: string[] = []\n\n function visit(tableName: string) {\n if (recStack.has(tableName)) {\n // Cycle detected\n const cycleStart = path.indexOf(tableName)\n cycles.push(path.slice(cycleStart))\n return\n }\n if (visited.has(tableName)) return\n\n visited.add(tableName)\n recStack.add(tableName)\n path.push(tableName)\n\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n visit(dep)\n }\n }\n\n recStack.delete(tableName)\n path.pop()\n order.push(tableName)\n }\n\n for (const node of graph.getNodes()) {\n if (!visited.has(node.tableName)) {\n visit(node.tableName)\n }\n }\n\n return { order, cycles }\n}\n","import { SchemaGraph, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\n\nexport interface CycleResolution {\n resolved: boolean\n strategy?: 'NULLABLE_FK' | 'DEFERRABLE'\n breakingTable?: string\n breakingColumn?: string\n}\n\n/**\n * Attempts to resolve cycles in the dependency graph.\n */\nexport function resolveCycles(\n cycles: string[][],\n schema: SchemaGraph,\n supportsDeferrable: boolean\n): CycleResolution[] {\n return cycles.map((cycle) => {\n // Strategy B: Deferrable constraints\n if (supportsDeferrable) {\n return { resolved: true, strategy: 'DEFERRABLE' }\n }\n\n // Strategy A: Nullable FK\n // Look for a table in the cycle that has a nullable foreign key pointing to another table in the cycle\n for (let i = 0; i < cycle.length; i++) {\n const currentTable = cycle[i]\n const nextTable = cycle[(i + 1) % cycle.length]\n const tableSchema = schema.tables[currentTable]\n\n const nullableFk = tableSchema.foreignKeys.find((fk) => {\n if (fk.referencedTable !== nextTable) return false\n // Check if all columns in this FK are nullable\n return fk.columns.every((colName) => tableSchema.columns[colName]?.nullable)\n })\n\n if (nullableFk) {\n return {\n resolved: true,\n strategy: 'NULLABLE_FK',\n breakingTable: currentTable,\n breakingColumn: nullableFk.columns[0], // Simplified: just track one\n }\n }\n }\n\n return { resolved: false }\n })\n}\n","import { SchemaGraph, SeedPlan, SeedOptions, TableSchema } from '../types.js'\nimport { DependencyGraph } from './graph.js'\nimport { topologicalSort } from './toposort.js'\nimport { resolveCycles } from './cycles.js'\n\nexport function createSeedPlan(\n schema: SchemaGraph,\n options: SeedOptions,\n supportsDeferrable = false\n): SeedPlan {\n const graph = new DependencyGraph(schema)\n const { order, cycles } = topologicalSort(graph)\n\n if (cycles.length > 0) {\n const resolutions = resolveCycles(cycles, schema, supportsDeferrable)\n const unresolvable = resolutions.filter((r) => !r.resolved)\n\n if (unresolvable.length > 0) {\n const cyclePaths = cycles\n .filter((_, i) => !resolutions[i].resolved)\n .map((c) => c.join(' -> '))\n .join('\\n')\n throw new Error(\n `Unresolvable cycles detected in schema:\\n${cyclePaths}\\nTry making one of the foreign keys nullable or use a database that supports deferrable constraints.`\n )\n }\n }\n\n let finalOrder = order\n\n // Apply include/exclude filters\n if (options.includeTables) {\n const includeSet = new Set(options.includeTables)\n if (options.withParents) {\n // Expand includeSet to include all parents\n const expanded = new Set<string>()\n const walk = (tableName: string) => {\n if (expanded.has(tableName)) return\n expanded.add(tableName)\n const node = graph.getNode(tableName)\n if (node) {\n for (const dep of node.dependencies) {\n walk(dep)\n }\n }\n }\n options.includeTables.forEach(walk)\n finalOrder = finalOrder.filter((t) => expanded.has(t))\n } else {\n finalOrder = finalOrder.filter((t) => includeSet.has(t))\n }\n }\n\n if (options.excludeTables) {\n const excludeSet = new Set(options.excludeTables)\n finalOrder = finalOrder.filter((t) => !excludeSet.has(t))\n }\n\n // Join table heuristics: tables with 2+ FKs and mostly FK columns\n // These should generally be seeded after their parents, which topological sort already handles.\n // But we can refine the order if needed. For now, toposort is sufficient.\n\n return {\n insertOrder: finalOrder,\n batches: [], // To be populated by the generator\n referencesMap: new Map(),\n }\n}\n\n/**\n * Heuristic to identify if a table is likely a join table.\n */\nexport function isJoinTable(table: TableSchema): boolean {\n const fkColumnCount = new Set(table.foreignKeys.flatMap((fk) => fk.columns)).size\n const totalColumnCount = Object.keys(table.columns).length\n\n return (\n table.foreignKeys.length >= 2 &&\n fkColumnCount >= totalColumnCount * 0.7 // 70% or more columns are FKs\n )\n}\n","import { Random } from '../random.js'\n\n/**\n * Registry to store and retrieve primary key values for foreign key resolution.\n */\nexport class ReferenceRegistry {\n private refs: Map<string, any[]> = new Map()\n\n /**\n * Records an inserted primary key for a table.\n */\n addReference(table: string, pk: any) {\n if (!this.refs.has(table)) {\n this.refs.set(table, [])\n }\n this.refs.get(table)!.push(pk)\n }\n\n /**\n * Picks a random primary key from the specified table.\n */\n getRandomReference(table: string, random: Random): any {\n const tableRefs = this.refs.get(table)\n if (!tableRefs || tableRefs.length === 0) {\n return null\n }\n return random.pick(tableRefs)\n }\n\n /**\n * Returns all recorded references for a table.\n */\n getReferences(table: string): any[] {\n return this.refs.get(table) || []\n }\n\n clear() {\n this.refs.clear()\n }\n}\n","import { TableSchema, ColumnSchema, NormalizedSqlType } from '../types.js'\nimport { Random } from '../random.js'\nimport { UniquenessRegistry } from '../uniqueness.js'\nimport { ReferenceRegistry } from './refs.js'\n\nexport interface GenerationContext {\n random: Random\n uniqueness: UniquenessRegistry\n refs: ReferenceRegistry\n /** Current row index in the batch */\n i: number\n /** Map of column name or table.column to a specific generator function */\n overrides?: Record<string, any>\n /** Map of generator IDs to their implementation */\n generators: Record<string, (ctx: any) => any>\n /** Function to infer generator ID from column metadata */\n inferGenerator: (columnName: string, sqlType: NormalizedSqlType) => { generatorId: string; options?: any }\n}\n\n/**\n * Generates multiple rows for a table.\n */\nexport async function generateRows(\n table: TableSchema,\n count: number,\n context: Omit<GenerationContext, 'i'>\n): Promise<Record<string, any>[]> {\n const rows: Record<string, any>[] = []\n for (let i = 0; i < count; i++) {\n rows.push(await generateRow(table, { ...context, i } as GenerationContext))\n }\n return rows\n}\n\n/**\n * Generates a single row for a table.\n */\nexport async function generateRow(\n table: TableSchema,\n context: GenerationContext\n): Promise<Record<string, any>> {\n const row: Record<string, any> = {}\n\n for (const column of Object.values(table.columns)) {\n // Skip auto-increment columns as they are handled by the DB\n if (column.isAutoIncrement) continue\n\n // Check for foreign keys\n const fk = table.foreignKeys.find((f) => f.columns.includes(column.name))\n if (fk) {\n const ref = context.refs.getRandomReference(fk.referencedTable, context.random)\n if (ref !== null) {\n // If it's a composite FK, we might need more complex logic. \n // For now, assume single column FK.\n row[column.name] = ref\n continue\n }\n }\n\n // Check for overrides\n const tableOverride = context.overrides?.[table.name]?.[column.name]\n const globalOverride = context.overrides?.[column.name]\n const override = tableOverride !== undefined ? tableOverride : globalOverride\n\n if (override !== undefined) {\n if (typeof override === 'function') {\n row[column.name] = await override({ i: context.i, random: context.random, refs: context.refs })\n continue\n } else if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n const values = override.enum\n const weights = override.weights\n row[column.name] = context.random.pick(values, weights)\n continue\n } else if ('dateBetween' in override) {\n const [start, end] = override.dateBetween\n const startTime = new Date(start).getTime()\n const endTime = new Date(end).getTime()\n const randomTime = context.random.nextInt(startTime, endTime)\n row[column.name] = new Date(randomTime).toISOString()\n continue\n }\n }\n // Literal value override\n row[column.name] = override\n continue\n }\n\n // Use semantic inference\n const { generatorId, options } = context.inferGenerator(column.name, column.type)\n const generator = context.generators[generatorId]\n\n if (generator) {\n // Wrap in uniqueness check if needed (e.g. if column is in uniqueConstraints)\n const isUnique = table.uniqueConstraints.some((uc) => uc.columns.includes(column.name)) ||\n table.primaryKey?.columns.includes(column.name)\n\n if (isUnique) {\n row[column.name] = await context.uniqueness.ensureUnique(\n table.name,\n column.name,\n () => generator({ ...context, options })\n )\n } else {\n row[column.name] = generator({ ...context, options })\n }\n } else {\n // Fallback to basic type-based generation if no generator found\n row[column.name] = generateDefaultValue(column, context.random)\n }\n }\n\n return row\n}\n\nfunction generateDefaultValue(column: ColumnSchema, random: Random): any {\n if (column.defaultValue !== undefined) return column.defaultValue\n if (column.nullable && random.boolean(0.1)) return null\n\n switch (column.type) {\n case NormalizedSqlType.INT:\n case NormalizedSqlType.BIGINT:\n return random.nextInt(1, 1000)\n case NormalizedSqlType.FLOAT:\n case NormalizedSqlType.DECIMAL:\n return parseFloat((random.next() * 100).toFixed(2))\n case NormalizedSqlType.BOOLEAN:\n return random.boolean()\n case NormalizedSqlType.DATE:\n case NormalizedSqlType.DATETIME:\n return new Date().toISOString()\n case NormalizedSqlType.JSON:\n return { mock: 'data' }\n case NormalizedSqlType.ENUM:\n return column.enumValues ? random.pick(column.enumValues) : 'VALUE'\n default:\n return 'mock-string'\n }\n}\n","import { Plugin, SeedOptions, RunnerContext } from './types.js'\n\nexport async function loadPlugins(options: SeedOptions, context: RunnerContext): Promise<void> {\n if (!options.plugins) return\n\n for (const pluginRef of options.plugins) {\n let plugin: Plugin\n if (typeof pluginRef === 'string') {\n try {\n // In a real scenario, we'd use dynamic import or a registry\n // For now, we'll assume it's already available or throw a helpful error\n const module = await import(pluginRef)\n plugin = module.default || module\n } catch (err: any) {\n throw new Error(`Failed to load plugin ${pluginRef}: ${err.message}`)\n }\n } else {\n plugin = pluginRef\n }\n\n // Merge plugin contributions\n if (plugin.generators) {\n context.generators = { ...context.generators, ...plugin.generators }\n }\n\n if (plugin.overrides) {\n options.overrides = mergeOverrides(options.overrides || {}, plugin.overrides)\n }\n\n if (plugin.hooks) {\n options.hooks = mergeHooks(options.hooks || {}, plugin.hooks)\n }\n }\n}\n\nfunction mergeOverrides(base: Record<string, any>, plugin: Record<string, any>): Record<string, any> {\n const merged = { ...base }\n for (const [table, tableOverrides] of Object.entries(plugin)) {\n merged[table] = { ...(merged[table] || {}), ...tableOverrides }\n }\n return merged\n}\n\nfunction mergeHooks(base: any, plugin: any): any {\n return {\n beforeInsert: async (table: string, rows: any[]) => {\n let currentRows = rows\n if (base.beforeInsert) currentRows = await base.beforeInsert(table, currentRows)\n if (plugin.beforeInsert) currentRows = await plugin.beforeInsert(table, currentRows)\n return currentRows\n },\n afterInsert: async (table: string, result: any) => {\n if (base.afterInsert) await base.afterInsert(table, result)\n if (plugin.afterInsert) await plugin.afterInsert(table, result)\n }\n }\n}\n","import { SeedOptions, TableOverrides } from './types.js'\n\nexport function validateOptions(options: SeedOptions): void {\n if (options.overrides) {\n for (const [tableName, tableOverrides] of Object.entries(options.overrides)) {\n if (typeof tableOverrides !== 'object' || tableOverrides === null) {\n throw new Error(`Invalid override for table \"${tableName}\": must be an object.`)\n }\n\n for (const [columnName, override] of Object.entries(tableOverrides)) {\n validateOverride(tableName, columnName, override)\n }\n }\n }\n}\n\nfunction validateOverride(table: string, column: string, override: any): void {\n if (typeof override === 'function') return\n\n if (typeof override === 'object' && override !== null) {\n if ('enum' in override) {\n if (!Array.isArray(override.enum)) {\n throw new Error(`Invalid enum override for \"${table}.${column}\": \"enum\" must be an array.`)\n }\n if (override.weights && (!Array.isArray(override.weights) || override.weights.length !== override.enum.length)) {\n throw new Error(`Invalid weights for \"${table}.${column}\": \"weights\" must be an array of the same length as \"enum\".`)\n }\n return\n }\n\n if ('dateBetween' in override) {\n if (!Array.isArray(override.dateBetween) || override.dateBetween.length !== 2) {\n throw new Error(`Invalid dateBetween override for \"${table}.${column}\": must be an array of [start, end].`)\n }\n return\n }\n }\n\n // Literal values are always valid\n}\n","import { SqlAdapter, MongoAdapter } from './adapter.js'\nimport { SeedPlan, SeedOptions, EffectReport, TableSchema, MongoSchema, RunnerContext } from './types.js'\nimport { Random } from './random.js'\nimport { UniquenessRegistry } from './uniqueness.js'\nimport { ReferenceRegistry } from './generate/refs.js'\nimport { generateRows } from './generate/row.js'\nimport { Redactor } from './redaction.js'\nimport { loadPlugins } from './plugins.js'\nimport { validateOptions } from './validation.js'\n\nfunction checkProductionSafety(options: SeedOptions, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n // If URL parsing fails, we fallback to simple string check\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\n\nexport async function runSeedSql(\n adapter: SqlAdapter,\n schema: any, // SchemaGraph\n plan: SeedPlan,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).config?.connectionString || (adapter as any).config)\n\n try {\n await adapter.connect()\n\n if (options.truncate && plan.insertOrder.length > 0) {\n if (!options.allowProduction) {\n // Simple heuristic: check for common production indicators if needed\n // For now, we rely on the user's explicit flag\n }\n if (!options.dryRun) {\n await adapter.truncateTables([...plan.insertOrder].reverse())\n }\n }\n\n if (!options.dryRun) {\n await adapter.begin()\n }\n\n for (const tableName of plan.insertOrder) {\n const tableStartTime = Date.now()\n const tableSchema: TableSchema = schema.tables[tableName]\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[tableName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n let rows = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n rows = await options.hooks.beforeInsert(tableName, rows)\n }\n\n const batchSize = options.batchSize || 1000\n for (let i = 0; i < rows.length; i += batchSize) {\n const batch = rows.slice(i, i + batchSize)\n await adapter.insertBatch({ tableName, rows: batch })\n }\n\n // Record PKs for future FK resolution\n // This is a simplification: we assume the adapter might need to return IDs\n // or we use the generated ones if they aren't auto-inc\n for (const row of rows) {\n if (tableSchema.primaryKey) {\n // For simple single-column PKs\n const pkCol = tableSchema.primaryKey.columns[0]\n if (row[pkCol] !== undefined) {\n refs.addReference(tableName, row[pkCol])\n }\n }\n }\n }\n\n report.tables[tableName] = {\n insertedCount: rows.length,\n durationMs: Date.now() - tableStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(tableName, report.tables[tableName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[tableName] = {\n insertedCount: 0,\n durationMs: Date.now() - tableStartTime,\n error: err.message,\n }\n report.errors.push(err)\n if (!options.dryRun) {\n await adapter.rollback()\n throw err\n }\n }\n }\n\n if (!options.dryRun) {\n await adapter.commit()\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n schema: MongoSchema,\n options: SeedOptions,\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(options.seed || Date.now())\n const uniqueness = new UniquenessRegistry()\n const refs = new ReferenceRegistry()\n\n await loadPlugins(options, context)\n validateOptions(options)\n checkProductionSafety(options, (adapter as any).uri)\n\n try {\n await adapter.connect()\n\n const collectionsToSeed = options.includeTables || Object.keys(schema.collections)\n\n if (options.truncate && collectionsToSeed.length > 0) {\n if (!options.dryRun && adapter.truncateCollections) {\n await adapter.truncateCollections(collectionsToSeed)\n }\n }\n\n for (const collName of collectionsToSeed) {\n const collStartTime = Date.now()\n const collSchema = schema.collections[collName]\n if (!collSchema) continue\n\n const rowCount = typeof options.rows === 'number'\n ? options.rows\n : (options.rows?.[collName] ?? 10)\n\n try {\n const genCtx = {\n random,\n uniqueness,\n refs,\n generators: context.generators,\n inferGenerator: context.inferGenerator,\n overrides: context.overrides,\n }\n\n // Map MongoCollectionSchema to TableSchema for generateRows\n const tableSchema: TableSchema = {\n name: collName,\n columns: collSchema.fields,\n foreignKeys: Object.entries(collSchema.references || {}).map(([col, ref]) => {\n const [refTable, refCol] = ref.split('.')\n return { columns: [col], referencedTable: refTable, referencedColumns: [refCol] }\n }),\n uniqueConstraints: [],\n }\n\n let docs = await generateRows(tableSchema, rowCount, genCtx as any)\n\n if (!options.dryRun) {\n if (options.hooks?.beforeInsert) {\n docs = await options.hooks.beforeInsert(collName, docs)\n }\n\n await adapter.insertMany(collName, docs)\n\n // Record IDs for future reference resolution\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n\n if (!options.dryRun && options.hooks?.afterInsert) {\n await options.hooks.afterInsert(collName, report.tables[collName])\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { MongoSeedConfig } from './types.js'\n\nexport function createMongoPlan(config: MongoSeedConfig): string[] {\n const collections = Object.keys(config.mongodb.collections)\n const adj = new Map<string, string[]>()\n\n for (const [name, coll] of Object.entries(config.mongodb.collections)) {\n const deps: string[] = []\n for (const field of Object.values(coll.fields)) {\n if (typeof field === 'object' && field.ref) {\n const [refColl] = field.ref.split('.')\n if (!config.mongodb.collections[refColl]) {\n throw new Error(`Reference ${field.ref} not found. Ensure ${refColl} collection is defined in config.`)\n }\n if (refColl !== name) {\n deps.push(refColl)\n }\n }\n }\n adj.set(name, deps)\n }\n\n const visited = new Set<string>()\n const visiting = new Set<string>()\n const order: string[] = []\n\n function visit(name: string) {\n if (visiting.has(name)) {\n throw new Error(`Circular reference detected involving collection: ${name}`)\n }\n if (visited.has(name)) return\n\n visiting.add(name)\n for (const dep of adj.get(name) || []) {\n visit(dep)\n }\n visiting.delete(name)\n visited.add(name)\n order.push(name)\n }\n\n for (const name of collections) {\n visit(name)\n }\n\n return order\n}\n","import { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { MongoFieldConfig, MongoFieldType } from './types.js'\n\nexport interface MongoGeneratorContext {\n random: Random\n refs: ReferenceRegistry\n generators: Record<string, (ctx: any) => any>\n}\n\nexport function generateMongoDocument(\n fields: Record<string, MongoFieldConfig>,\n ctx: MongoGeneratorContext\n): any {\n const doc: any = {}\n for (const [name, config] of Object.entries(fields)) {\n doc[name] = generateFieldValue(config, ctx)\n }\n return doc\n}\n\nfunction generateFieldValue(config: MongoFieldConfig, ctx: MongoGeneratorContext): any {\n if (typeof config === 'string') {\n return generateByType(config as MongoFieldType, {}, ctx)\n }\n\n const cfg = config as any\n\n if (cfg.ref) {\n const [refColl, refField] = cfg.ref.split('.')\n const val = ctx.refs.getRandomReference(refColl, ctx.random)\n if (val === null) {\n throw new Error(`Reference ${cfg.ref} not found. Ensure ${refColl} collection is seeded first.`)\n }\n return val\n }\n\n if (cfg.type === 'enum') {\n return ctx.random.pick(cfg.values || [], cfg.weights)\n }\n\n if (cfg.type === 'object') {\n return generateMongoDocument(cfg.fields || {}, ctx)\n }\n\n if (cfg.type === 'array') {\n const count = ctx.random.nextInt(cfg.minItems ?? 1, cfg.maxItems ?? 5)\n return Array.from({ length: count }, () => generateFieldValue(cfg.of!, ctx))\n }\n\n return generateByType(cfg.type!, cfg, ctx)\n}\n\nfunction generateByType(type: MongoFieldType, config: any, ctx: MongoGeneratorContext): any {\n switch (type) {\n case 'objectId':\n return generateObjectId(ctx.random)\n case 'int':\n return ctx.random.nextInt(config.min ?? 0, config.max ?? 1000000)\n case 'float':\n case 'decimal':\n return parseFloat((ctx.random.next() * ((config.max ?? 100) - (config.min ?? 0)) + (config.min ?? 0)).toFixed(2))\n case 'boolean':\n return ctx.random.boolean()\n case 'date':\n return new Date(ctx.random.nextInt(0, Date.now())).toISOString()\n case 'dateRecent':\n return ctx.generators.dateRecent(ctx)\n case 'dateBetween': {\n const from = new Date(config.from ?? '2020-01-01').getTime()\n const to = new Date(config.to ?? Date.now()).getTime()\n return new Date(ctx.random.nextInt(from, to)).toISOString()\n }\n case 'email':\n return ctx.generators.email(ctx)\n case 'firstName':\n return ctx.generators.firstName(ctx)\n case 'lastName':\n return ctx.generators.lastName(ctx)\n case 'fullName':\n return ctx.generators.fullName(ctx)\n case 'city':\n return ctx.generators.city(ctx)\n case 'country':\n return ctx.generators.country(ctx)\n case 'street':\n return ctx.generators.address(ctx)\n case 'phone':\n return ctx.generators.phone(ctx)\n case 'uuid':\n return ctx.generators.uuid(ctx)\n case 'string':\n return ctx.generators.firstName(ctx) // Fallback\n default:\n // If it matches a generator name, use it\n if (ctx.generators[type]) {\n return ctx.generators[type](ctx)\n }\n return null\n }\n}\n\nfunction generateObjectId(random: Random): string {\n const chars = '0123456789abcdef'\n let id = ''\n for (let i = 0; i < 24; i++) {\n id += chars[random.nextInt(0, 15)]\n }\n return id\n}\n","import { MongoSeedConfig, MongoCollectionConfig } from './types.js'\nimport { createMongoPlan } from './planner.js'\nimport { generateMongoDocument } from './generator.js'\nimport { Random } from '../random.js'\nimport { ReferenceRegistry } from '../generate/refs.js'\nimport { EffectReport, RunnerContext } from '../types.js'\nimport { MongoAdapter } from '../adapter.js'\n\nfunction checkProductionSafety(options: { allowProduction?: boolean }, dbUrl?: string) {\n if (options.allowProduction) return\n\n if (process.env.NODE_ENV === 'production') {\n throw new Error('Refusing to run in production environment (NODE_ENV=production). Use --allow-production to override.')\n }\n\n if (dbUrl) {\n const prodKeywords = ['prod', 'production', 'live', 'cloud', 'aws', 'azure', 'gcp']\n try {\n const url = new URL(dbUrl.includes('://') ? dbUrl : `sqlite://${dbUrl}`)\n const host = url.hostname.toLowerCase()\n if (prodKeywords.some(kw => host.includes(kw))) {\n throw new Error(`Refusing to run against a potential production database (${host}). Use --allow-production to override.`)\n }\n } catch (e) {\n const lowerUrl = dbUrl.toLowerCase()\n if (prodKeywords.some(kw => lowerUrl.includes(kw))) {\n throw new Error('Refusing to run against a potential production database. Use --allow-production to override.')\n }\n }\n }\n}\n\nexport async function runSeedMongo(\n adapter: MongoAdapter,\n config: MongoSeedConfig,\n options: { dryRun?: boolean; allowProduction?: boolean } = {},\n context: RunnerContext\n): Promise<EffectReport> {\n const startTime = Date.now()\n const report: EffectReport = {\n success: true,\n durationMs: 0,\n tables: {},\n errors: [],\n }\n\n const random = new Random(config.seed || Date.now())\n const refs = new ReferenceRegistry()\n\n checkProductionSafety(options, config.mongodb.uri)\n\n // Validations\n if (!config.mongodb?.collections || Object.keys(config.mongodb.collections).length === 0) {\n throw new Error('No collections defined in MongoDB config.')\n }\n\n for (const [name, coll] of Object.entries(config.mongodb.collections) as [string, MongoCollectionConfig][]) {\n if (coll.rows <= 0) {\n throw new Error(`Collection ${name} must have rows > 0.`)\n }\n if (!coll.fields || Object.keys(coll.fields).length === 0) {\n throw new Error(`Collection ${name} must have fields defined.`)\n }\n for (const [fieldName, field] of Object.entries(coll.fields)) {\n if (typeof field === 'object' && field !== null && 'type' in field && field.type === 'enum') {\n const enumField = field as any\n if (enumField.weights && enumField.values && enumField.weights.length !== enumField.values.length) {\n throw new Error(`Enum weights and values length mismatch in ${name}.${fieldName}`)\n }\n }\n }\n }\n\n try {\n await adapter.connect()\n\n const plan = createMongoPlan(config)\n\n if (config.truncate && plan.length > 0) {\n if (!options.dryRun && adapter.truncateCollections) {\n console.log(`๐Ÿงน Truncating ${plan.length} collections...`)\n await adapter.truncateCollections(plan)\n }\n }\n\n for (const collName of plan) {\n const collStartTime = Date.now()\n const collConfig = config.mongodb.collections[collName]\n const docs: any[] = []\n\n try {\n for (let i = 0; i < collConfig.rows; i++) {\n const doc = generateMongoDocument(collConfig.fields, {\n random,\n refs,\n generators: context.generators\n })\n docs.push(doc)\n }\n\n if (!options.dryRun) {\n await adapter.insertMany(collName, docs)\n\n // Store IDs for references\n for (const doc of docs) {\n if (doc._id) {\n refs.addReference(collName, doc._id)\n }\n }\n }\n\n report.tables[collName] = {\n insertedCount: docs.length,\n durationMs: Date.now() - collStartTime,\n }\n } catch (err: any) {\n report.success = false\n report.tables[collName] = {\n insertedCount: 0,\n durationMs: Date.now() - collStartTime,\n error: err.message,\n }\n report.errors.push(err)\n }\n }\n } catch (err: any) {\n report.success = false\n report.errors.push(err)\n } finally {\n await adapter.disconnect()\n report.durationMs = Date.now() - startTime\n }\n\n return report\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToConsole(report: EffectReport) {\n console.log('\\n๐Ÿš€ Seed Report')\n console.log('====================================')\n console.log(`Status: ${report.success ? 'โœ… Success' : 'โŒ Failed'}`)\n console.log(`Duration: ${report.durationMs}ms`)\n console.log('------------------------------------')\n\n console.table(\n Object.entries(report.tables).map(([name, stats]) => ({\n Table: name,\n Rows: stats.insertedCount,\n Time: `${stats.durationMs}ms`,\n Status: stats.error ? 'โŒ' : 'โœ…'\n }))\n )\n\n if (report.errors.length > 0) {\n console.log('\\nErrors:')\n report.errors.forEach((err, i) => {\n console.log(`${i + 1}. ${err.message}`)\n })\n }\n console.log('====================================\\n')\n}\n","import { EffectReport } from '../types.js'\n\nexport function reportToJson(report: EffectReport): string {\n return JSON.stringify(report, (key, value) => {\n if (value instanceof Error) {\n return { message: value.message, stack: value.stack }\n }\n return value\n }, 2)\n}\n","export * from './random.js'\nexport * from './types.js'\nexport * from './adapter.js'\nexport * from './uniqueness.js'\nexport * from './redaction.js'\nexport * from './planner/graph.js'\nexport * from './planner/toposort.js'\nexport * from './planner/cycles.js'\nexport * from './planner/plan.js'\nexport * from './generate/refs.js'\nexport * from './generate/row.js'\nexport { runSeedSql } from './runner.js'\nexport { runSeedMongo } from './mongo/runner.js'\nexport * from './mongo/types.js'\nexport type { MongoSeedConfig } from './mongo/types.js'\nexport { loadPlugins } from './plugins.js'\nexport { reportToConsole } from './reporters/console.js'\nexport { reportToJson } from './reporters/json.js'\n\nexport const version = '0.0.1'\n\nexport function defineSeed(options: import('./types.js').SeedOptions) {\n return options\n}\n"],"mappings":"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","names":["NormalizedSqlType","checkProductionSafety"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mongo/types.ts"],"sourcesContent":["export type MongoFieldType =\n | 'string'\n | 'int'\n | 'float'\n | 'decimal'\n | 'boolean'\n | 'date'\n | 'dateRecent'\n | 'dateBetween'\n | 'email'\n | 'firstName'\n | 'lastName'\n | 'fullName'\n | 'city'\n | 'country'\n | 'street'\n | 'phone'\n | 'uuid'\n | 'objectId'\n | 'enum'\n | 'object'\n | 'array'\n\nexport interface MongoFieldConfigObject {\n type?: MongoFieldType\n unique?: boolean\n min?: number\n max?: number\n from?: string | Date\n to?: string | Date\n values?: any[]\n weights?: number[]\n fields?: Record<string, MongoFieldConfig>\n of?: MongoFieldConfig\n minItems?: number\n maxItems?: number\n ref?: string\n}\n\nexport type MongoFieldConfig = MongoFieldType | MongoFieldConfigObject\n\nexport interface MongoCollectionConfig {\n rows: number\n fields: Record<string, MongoFieldConfig>\n}\n\nexport interface MongoSeedConfig {\n dbType: 'mongodb'\n seed?: number | string\n mongodb: {\n uri: string\n collections: Record<string, MongoCollectionConfig>\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
1
+ {"version":3,"sources":["../../src/mongo/types.ts"],"sourcesContent":["export type MongoFieldType =\n | 'string'\n | 'int'\n | 'float'\n | 'decimal'\n | 'boolean'\n | 'date'\n | 'dateRecent'\n | 'dateBetween'\n | 'email'\n | 'firstName'\n | 'lastName'\n | 'fullName'\n | 'city'\n | 'country'\n | 'street'\n | 'phone'\n | 'uuid'\n | 'objectId'\n | 'enum'\n | 'object'\n | 'array'\n\nexport interface MongoFieldConfigObject {\n type?: MongoFieldType\n unique?: boolean\n min?: number\n max?: number\n from?: string | Date\n to?: string | Date\n values?: any[]\n weights?: number[]\n fields?: Record<string, MongoFieldConfig>\n of?: MongoFieldConfig\n minItems?: number\n maxItems?: number\n ref?: string\n}\n\nexport type MongoFieldConfig = MongoFieldType | MongoFieldConfigObject\n\nexport interface MongoCollectionConfig {\n rows: number\n fields: Record<string, MongoFieldConfig>\n}\n\nexport interface MongoSeedConfig {\n dbType: 'mongodb'\n seed?: number | string\n truncate?: boolean\n mongodb: {\n uri: string\n collections: Record<string, MongoCollectionConfig>\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
@@ -22,6 +22,7 @@ interface MongoCollectionConfig {
22
22
  interface MongoSeedConfig {
23
23
  dbType: 'mongodb';
24
24
  seed?: number | string;
25
+ truncate?: boolean;
25
26
  mongodb: {
26
27
  uri: string;
27
28
  collections: Record<string, MongoCollectionConfig>;
@@ -22,6 +22,7 @@ interface MongoCollectionConfig {
22
22
  interface MongoSeedConfig {
23
23
  dbType: 'mongodb';
24
24
  seed?: number | string;
25
+ truncate?: boolean;
25
26
  mongodb: {
26
27
  uri: string;
27
28
  collections: Record<string, MongoCollectionConfig>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "schema-seed-core",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "type": "module",
5
5
  "description": "Core logic for schema-seed",
6
6
  "author": "Ali Nazar",