@terminator-network/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +356 -0
- package/dist/index.js +1109 -0
- package/dist/index.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/config.ts","../src/identity/persona.ts","../src/kill-switch.ts","../src/parsers/verification.ts","../src/policies/engine.ts","../src/providers/card/mock.ts","../src/providers/email/mock.ts","../src/providers/phone/mock.ts","../src/store/activity-log.ts","../src/store/database.ts","../src/store/identities.ts","../src/identity/state-machine.ts","../src/store/policies.ts","../src/terminator.ts"],"sourcesContent":["import { z } from \"zod\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nconst ConfigSchema = z.object({\n\t// Cloudflare Email\n\tcfApiToken: z.string().optional(),\n\tcfAccountId: z.string().optional(),\n\tcfZoneId: z.string().optional(),\n\temailDomain: z.string().optional(),\n\n\t// Twilio\n\ttwilioAccountSid: z.string().optional(),\n\ttwilioAuthToken: z.string().optional(),\n\n\t// Lithic\n\tlithicApiKey: z.string().optional(),\n\tlithicEnvironment: z.enum([\"sandbox\", \"production\"]).default(\"sandbox\"),\n\n\t// General\n\tdbPath: z.string().default(join(homedir(), \".terminator\", \"terminator.db\")),\n\tlogLevel: z.enum([\"debug\", \"info\", \"warn\", \"error\"]).default(\"info\"),\n\tmaxIdentities: z.coerce.number().int().positive().default(50),\n\tdefaultTtlMinutes: z.coerce.number().int().positive().default(60),\n\tdefaultSpendLimitCents: z.coerce.number().int().positive().default(5000),\n});\n\nexport type TerminatorConfig = z.infer<typeof ConfigSchema>;\n\nexport function loadConfig(overrides?: Partial<TerminatorConfig>): TerminatorConfig {\n\tconst raw = {\n\t\tcfApiToken: process.env.TERMINATOR_CF_API_TOKEN,\n\t\tcfAccountId: process.env.TERMINATOR_CF_ACCOUNT_ID,\n\t\tcfZoneId: process.env.TERMINATOR_CF_ZONE_ID,\n\t\temailDomain: process.env.TERMINATOR_EMAIL_DOMAIN,\n\t\ttwilioAccountSid: process.env.TERMINATOR_TWILIO_ACCOUNT_SID,\n\t\ttwilioAuthToken: process.env.TERMINATOR_TWILIO_AUTH_TOKEN,\n\t\tlithicApiKey: process.env.TERMINATOR_LITHIC_API_KEY,\n\t\tlithicEnvironment: process.env.TERMINATOR_LITHIC_ENVIRONMENT,\n\t\tdbPath: process.env.TERMINATOR_DB_PATH,\n\t\tlogLevel: process.env.TERMINATOR_LOG_LEVEL,\n\t\tmaxIdentities: process.env.TERMINATOR_MAX_IDENTITIES,\n\t\tdefaultTtlMinutes: process.env.TERMINATOR_DEFAULT_TTL_MINUTES,\n\t\tdefaultSpendLimitCents: process.env.TERMINATOR_DEFAULT_SPEND_LIMIT_CENTS,\n\t\t...overrides,\n\t};\n\n\t// Filter undefined so Zod defaults apply\n\tconst filtered = Object.fromEntries(\n\t\tObject.entries(raw).filter(([_, v]) => v !== undefined),\n\t);\n\n\tconst result = ConfigSchema.safeParse(filtered);\n\n\tif (!result.success) {\n\t\tconst issues = result.error.issues.map((i) => ` ${i.path.join(\".\")}: ${i.message}`);\n\t\tthrow new Error(`Terminator configuration error:\\n${issues.join(\"\\n\")}`);\n\t}\n\n\treturn result.data;\n}\n\nexport function getConfiguredProviders(config: TerminatorConfig) {\n\treturn {\n\t\temail: !!(config.cfApiToken && config.cfAccountId && config.emailDomain),\n\t\tphone: !!(config.twilioAccountSid && config.twilioAuthToken),\n\t\tcard: !!config.lithicApiKey,\n\t};\n}\n","export interface Persona {\n\tfirstName: string;\n\tlastName: string;\n\tfullName: string;\n\temail?: string;\n\tphone?: string;\n\taddress: {\n\t\tline1: string;\n\t\tcity: string;\n\t\tstate: string;\n\t\tpostalCode: string;\n\t\tcountry: string;\n\t};\n}\n\nconst FIRST_NAMES = [\n\t\"Alex\", \"Jordan\", \"Taylor\", \"Morgan\", \"Casey\",\n\t\"Riley\", \"Quinn\", \"Avery\", \"Blake\", \"Drew\",\n\t\"Ellis\", \"Finley\", \"Harper\", \"Jamie\", \"Kai\",\n\t\"Lane\", \"Marley\", \"Nico\", \"Parker\", \"Reese\",\n\t\"Sage\", \"Skyler\", \"Tatum\", \"Val\", \"Wren\",\n];\n\nconst LAST_NAMES = [\n\t\"Anderson\", \"Brooks\", \"Chen\", \"Davis\", \"Evans\",\n\t\"Foster\", \"Garcia\", \"Hayes\", \"Ito\", \"Jensen\",\n\t\"Kim\", \"Lambert\", \"Mitchell\", \"Nakamura\", \"Ortiz\",\n\t\"Palmer\", \"Reed\", \"Shaw\", \"Torres\", \"Vance\",\n\t\"Walsh\", \"Young\", \"Zhang\", \"Barrett\", \"Cole\",\n];\n\nconst STREETS = [\n\t\"123 Oak Ave\", \"456 Maple St\", \"789 Pine Rd\",\n\t\"321 Elm Dr\", \"654 Cedar Ln\", \"987 Birch Way\",\n\t\"147 Willow Ct\", \"258 Spruce Blvd\", \"369 Aspen Pl\",\n\t\"741 Walnut Ter\",\n];\n\nconst CITIES_STATES = [\n\t{ city: \"Portland\", state: \"OR\", zip: \"97201\" },\n\t{ city: \"Austin\", state: \"TX\", zip: \"78701\" },\n\t{ city: \"Denver\", state: \"CO\", zip: \"80202\" },\n\t{ city: \"Seattle\", state: \"WA\", zip: \"98101\" },\n\t{ city: \"Chicago\", state: \"IL\", zip: \"60601\" },\n\t{ city: \"Boston\", state: \"MA\", zip: \"02101\" },\n\t{ city: \"Atlanta\", state: \"GA\", zip: \"30301\" },\n\t{ city: \"Miami\", state: \"FL\", zip: \"33101\" },\n\t{ city: \"Phoenix\", state: \"AZ\", zip: \"85001\" },\n\t{ city: \"Minneapolis\", state: \"MN\", zip: \"55401\" },\n];\n\nfunction pick<T>(arr: T[]): T {\n\treturn arr[Math.floor(Math.random() * arr.length)];\n}\n\nexport function createPersona(): Persona {\n\tconst firstName = pick(FIRST_NAMES);\n\tconst lastName = pick(LAST_NAMES);\n\tconst location = pick(CITIES_STATES);\n\tconst street = pick(STREETS);\n\n\treturn {\n\t\tfirstName,\n\t\tlastName,\n\t\tfullName: `${firstName} ${lastName}`,\n\t\taddress: {\n\t\t\tline1: street,\n\t\t\tcity: location.city,\n\t\t\tstate: location.state,\n\t\t\tpostalCode: location.zip,\n\t\t\tcountry: \"US\",\n\t\t},\n\t};\n}\n","import type { Identity } from \"./identity/identity.js\";\nimport type { CardProvider, EmailProvider, PhoneProvider } from \"./providers/types.js\";\nimport type { ActivityLog } from \"./store/activity-log.js\";\nimport type { IdentityStore } from \"./store/identities.js\";\n\nexport interface KillResult {\n\tidentityId: string;\n\temailRevoked: boolean;\n\tphoneRevoked: boolean;\n\tcardRevoked: boolean;\n\terrors: string[];\n}\n\nexport class KillSwitch {\n\tconstructor(\n\t\tprivate identityStore: IdentityStore,\n\t\tprivate activityLog: ActivityLog,\n\t\tprivate emailProvider?: EmailProvider,\n\t\tprivate phoneProvider?: PhoneProvider,\n\t\tprivate cardProvider?: CardProvider,\n\t) {}\n\n\tasync killIdentity(id: string): Promise<KillResult> {\n\t\tconst identity = this.identityStore.get(id);\n\t\tif (!identity) throw new Error(`Identity not found: ${id}`);\n\n\t\tthis.identityStore.updateStatus(id, \"killing\");\n\t\tthis.activityLog.append({\n\t\t\tidentityId: id,\n\t\t\teventType: \"identity.killing\",\n\t\t\tprovider: null,\n\t\t\tresourceType: \"identity\",\n\t\t\tresourceId: id,\n\t\t\tdetails: null,\n\t\t\tcostEstimateCents: null,\n\t\t});\n\n\t\tconst result: KillResult = {\n\t\t\tidentityId: id,\n\t\t\temailRevoked: false,\n\t\t\tphoneRevoked: false,\n\t\t\tcardRevoked: false,\n\t\t\terrors: [],\n\t\t};\n\n\t\t// Revoke all resources in parallel\n\t\tconst tasks: Promise<void>[] = [];\n\n\t\tif (identity.email && identity.emailProviderId && this.emailProvider) {\n\t\t\ttasks.push(\n\t\t\t\tthis.revokeEmail(identity, result),\n\t\t\t);\n\t\t}\n\n\t\tif (identity.phone && identity.phoneProviderId && this.phoneProvider) {\n\t\t\ttasks.push(\n\t\t\t\tthis.revokePhone(identity, result),\n\t\t\t);\n\t\t}\n\n\t\tif (identity.cardProviderId && this.cardProvider) {\n\t\t\ttasks.push(\n\t\t\t\tthis.revokeCard(identity, result),\n\t\t\t);\n\t\t}\n\n\t\tawait Promise.allSettled(tasks);\n\n\t\tthis.identityStore.updateStatus(id, \"killed\");\n\t\tthis.activityLog.append({\n\t\t\tidentityId: id,\n\t\t\teventType: \"identity.killed\",\n\t\t\tprovider: null,\n\t\t\tresourceType: \"identity\",\n\t\t\tresourceId: id,\n\t\t\tdetails: {\n\t\t\t\temailRevoked: result.emailRevoked,\n\t\t\t\tphoneRevoked: result.phoneRevoked,\n\t\t\t\tcardRevoked: result.cardRevoked,\n\t\t\t\terrors: result.errors,\n\t\t\t},\n\t\t\tcostEstimateCents: null,\n\t\t});\n\n\t\treturn result;\n\t}\n\n\tasync killAll(): Promise<KillResult[]> {\n\t\tconst active = this.identityStore.list(\"active\");\n\t\tconst provisioning = this.identityStore.list(\"provisioning\");\n\t\tconst all = [...active, ...provisioning];\n\n\t\tconst results: KillResult[] = [];\n\t\tfor (const identity of all) {\n\t\t\ttry {\n\t\t\t\tconst result = await this.killIdentity(identity.id);\n\t\t\t\tresults.push(result);\n\t\t\t} catch (error) {\n\t\t\t\tresults.push({\n\t\t\t\t\tidentityId: identity.id,\n\t\t\t\t\temailRevoked: false,\n\t\t\t\t\tphoneRevoked: false,\n\t\t\t\t\tcardRevoked: false,\n\t\t\t\t\terrors: [error instanceof Error ? error.message : String(error)],\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn results;\n\t}\n\n\tprivate async revokeEmail(identity: Identity, result: KillResult): Promise<void> {\n\t\ttry {\n\t\t\tawait this.emailProvider!.deleteInbox({\n\t\t\t\taddress: identity.email!,\n\t\t\t\tproviderId: identity.emailProviderId!,\n\t\t\t\tprovider: this.emailProvider!.name,\n\t\t\t});\n\t\t\tresult.emailRevoked = true;\n\t\t\tthis.activityLog.append({\n\t\t\t\tidentityId: identity.id,\n\t\t\t\teventType: \"email.inbox_deleted\",\n\t\t\t\tprovider: this.emailProvider!.name,\n\t\t\t\tresourceType: \"email\",\n\t\t\t\tresourceId: identity.emailProviderId!,\n\t\t\t\tdetails: { address: identity.email },\n\t\t\t\tcostEstimateCents: null,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tresult.errors.push(`Email: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n\n\tprivate async revokePhone(identity: Identity, result: KillResult): Promise<void> {\n\t\ttry {\n\t\t\tawait this.phoneProvider!.releaseNumber({\n\t\t\t\tnumber: identity.phone!,\n\t\t\t\tproviderId: identity.phoneProviderId!,\n\t\t\t\tprovider: this.phoneProvider!.name,\n\t\t\t});\n\t\t\tresult.phoneRevoked = true;\n\t\t\tthis.activityLog.append({\n\t\t\t\tidentityId: identity.id,\n\t\t\t\teventType: \"phone.released\",\n\t\t\t\tprovider: this.phoneProvider!.name,\n\t\t\t\tresourceType: \"phone\",\n\t\t\t\tresourceId: identity.phoneProviderId!,\n\t\t\t\tdetails: { number: identity.phone },\n\t\t\t\tcostEstimateCents: null,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tresult.errors.push(`Phone: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n\n\tprivate async revokeCard(identity: Identity, result: KillResult): Promise<void> {\n\t\ttry {\n\t\t\tawait this.cardProvider!.deactivateCard({\n\t\t\t\tlastFour: identity.cardLastFour!,\n\t\t\t\tproviderId: identity.cardProviderId!,\n\t\t\t\tprovider: this.cardProvider!.name,\n\t\t\t});\n\t\t\tresult.cardRevoked = true;\n\t\t\tthis.activityLog.append({\n\t\t\t\tidentityId: identity.id,\n\t\t\t\teventType: \"card.deactivated\",\n\t\t\t\tprovider: this.cardProvider!.name,\n\t\t\t\tresourceType: \"card\",\n\t\t\t\tresourceId: identity.cardProviderId!,\n\t\t\t\tdetails: { lastFour: identity.cardLastFour },\n\t\t\t\tcostEstimateCents: null,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tresult.errors.push(`Card: ${error instanceof Error ? error.message : String(error)}`);\n\t\t}\n\t}\n}\n","const CODE_PATTERNS = [\n\t// \"Your code is 123456\" or \"verification code: 123456\"\n\t/(?:code|otp|pin|token)\\s*(?:is|:)\\s*(\\d{4,8})/i,\n\t// \"123456 is your verification code\"\n\t/(\\d{4,8})\\s+is\\s+your\\s+(?:verification|confirmation|security)\\s+code/i,\n\t// \"Enter 123456 to verify\"\n\t/enter\\s+(\\d{4,8})\\s+to/i,\n\t// Standalone 6-digit code on its own line\n\t/^(\\d{6})$/m,\n\t// \"G-123456\" (Google-style)\n\t/[A-Z]-(\\d{4,8})/,\n];\n\nexport interface VerificationCodeResult {\n\tcode: string;\n\tpattern: string;\n}\n\nexport function parseVerificationCode(text: string): VerificationCodeResult | null {\n\tfor (const pattern of CODE_PATTERNS) {\n\t\tconst match = text.match(pattern);\n\t\tif (match?.[1]) {\n\t\t\treturn {\n\t\t\t\tcode: match[1],\n\t\t\t\tpattern: pattern.source,\n\t\t\t};\n\t\t}\n\t}\n\treturn null;\n}\n","import type { TerminatorConfig } from \"../config.js\";\nimport type { IdentityResources } from \"../identity/identity.js\";\nimport type { IdentityStore } from \"../store/identities.js\";\nimport type { Policy } from \"../store/policies.js\";\nimport type { PolicyStore } from \"../store/policies.js\";\n\nexport interface PolicyViolation {\n\tpolicy: string;\n\truleType: string;\n\tmessage: string;\n}\n\nexport class PolicyEngine {\n\tconstructor(\n\t\tprivate policyStore: PolicyStore,\n\t\tprivate identityStore: IdentityStore,\n\t\tprivate config: TerminatorConfig,\n\t) {}\n\n\tcheckCreateIdentity(resources: IdentityResources, spendLimitCents?: number): PolicyViolation[] {\n\t\tconst violations: PolicyViolation[] = [];\n\t\tconst policies = this.policyStore.getEnabled();\n\n\t\tfor (const policy of policies) {\n\t\t\tconst violation = this.evaluateForCreate(policy, resources, spendLimitCents);\n\t\t\tif (violation) violations.push(violation);\n\t\t}\n\n\t\t// Built-in: max identities from config\n\t\tconst activeCount = this.identityStore.countActive();\n\t\tif (activeCount >= this.config.maxIdentities) {\n\t\t\tviolations.push({\n\t\t\t\tpolicy: \"built-in:max_identities\",\n\t\t\t\truleType: \"max_identities\",\n\t\t\t\tmessage: `Maximum active identities reached (${activeCount}/${this.config.maxIdentities})`,\n\t\t\t});\n\t\t}\n\n\t\treturn violations;\n\t}\n\n\tprivate evaluateForCreate(\n\t\tpolicy: Policy,\n\t\tresources: IdentityResources,\n\t\tspendLimitCents?: number,\n\t): PolicyViolation | null {\n\t\tswitch (policy.ruleType) {\n\t\t\tcase \"max_identities\": {\n\t\t\t\tconst max = policy.ruleValue as number;\n\t\t\t\tconst activeCount = this.identityStore.countActive();\n\t\t\t\tif (activeCount >= max) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpolicy: policy.name,\n\t\t\t\t\t\truleType: policy.ruleType,\n\t\t\t\t\t\tmessage: `Policy \"${policy.name}\": max identities (${max}) reached`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"max_spend_per_identity\": {\n\t\t\t\tconst maxSpend = policy.ruleValue as number;\n\t\t\t\tconst requestedSpend = spendLimitCents ?? this.config.defaultSpendLimitCents;\n\t\t\t\tif (resources.includes(\"card\") && requestedSpend > maxSpend) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpolicy: policy.name,\n\t\t\t\t\t\truleType: policy.ruleType,\n\t\t\t\t\t\tmessage: `Policy \"${policy.name}\": spend limit $${(requestedSpend / 100).toFixed(2)} exceeds max $${(maxSpend / 100).toFixed(2)}`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tcase \"require_card_approval\": {\n\t\t\t\tif (resources.includes(\"card\") && policy.ruleValue === true) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tpolicy: policy.name,\n\t\t\t\t\t\truleType: policy.ruleType,\n\t\t\t\t\t\tmessage: `Policy \"${policy.name}\": card creation requires explicit approval`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\treturn null;\n\t\t}\n\t}\n}\n","import { ulid } from \"ulid\";\nimport type { Identity } from \"../../identity/identity.js\";\nimport type {\n\tCardDetails,\n\tCardOptions,\n\tCardProvider,\n\tProviderHealthResult,\n\tVirtualCard,\n} from \"../types.js\";\n\nexport class MockCardProvider implements CardProvider {\n\tname = \"mock\";\n\tprivate cards = new Map<string, { details: CardDetails; active: boolean }>();\n\n\tasync createCard(_identity: Identity, options: CardOptions): Promise<VirtualCard> {\n\t\tconst id = ulid();\n\t\tconst lastFour = String(Math.floor(1000 + Math.random() * 9000));\n\t\tconst details: CardDetails = {\n\t\t\tpan: `4242424242${String(Math.floor(100000 + Math.random() * 900000))}${lastFour}`,\n\t\t\tcvv: String(Math.floor(100 + Math.random() * 900)),\n\t\t\texpMonth: new Date().getMonth() + 1,\n\t\t\texpYear: new Date().getFullYear() + 2,\n\t\t\tlastFour,\n\t\t};\n\t\tthis.cards.set(id, { details, active: true });\n\t\treturn { lastFour, providerId: id, provider: this.name };\n\t}\n\n\tasync getCardDetails(card: VirtualCard): Promise<CardDetails> {\n\t\tconst entry = this.cards.get(card.providerId);\n\t\tif (!entry) throw new Error(`Card not found: ${card.providerId}`);\n\t\tif (!entry.active) throw new Error(`Card is deactivated: ${card.providerId}`);\n\t\treturn entry.details;\n\t}\n\n\tasync deactivateCard(card: VirtualCard): Promise<void> {\n\t\tconst entry = this.cards.get(card.providerId);\n\t\tif (entry) entry.active = false;\n\t}\n\n\tasync healthCheck(): Promise<ProviderHealthResult> {\n\t\treturn { provider: this.name, healthy: true, message: \"Mock provider always healthy\" };\n\t}\n}\n","import { ulid } from \"ulid\";\nimport type { Identity } from \"../../identity/identity.js\";\nimport type {\n\tEmailInbox,\n\tEmailMessage,\n\tEmailProvider,\n\tProviderHealthResult,\n} from \"../types.js\";\n\nexport class MockEmailProvider implements EmailProvider {\n\tname = \"mock\";\n\tprivate inboxes = new Map<string, EmailMessage[]>();\n\n\tasync createInbox(identity: Identity): Promise<EmailInbox> {\n\t\tconst id = ulid();\n\t\tconst address = `${identity.persona.firstName.toLowerCase()}-${id.slice(-6).toLowerCase()}@mock.terminator.test`;\n\t\tthis.inboxes.set(address, []);\n\t\treturn { address, providerId: id, provider: this.name };\n\t}\n\n\tasync getMessages(inbox: EmailInbox, since?: Date): Promise<EmailMessage[]> {\n\t\tconst messages = this.inboxes.get(inbox.address) ?? [];\n\t\tif (!since) return messages;\n\t\treturn messages.filter((m) => new Date(m.receivedAt) >= since);\n\t}\n\n\tasync deleteInbox(inbox: EmailInbox): Promise<void> {\n\t\tthis.inboxes.delete(inbox.address);\n\t}\n\n\tasync healthCheck(): Promise<ProviderHealthResult> {\n\t\treturn { provider: this.name, healthy: true, message: \"Mock provider always healthy\" };\n\t}\n\n\t// Test helper: inject a message into an inbox\n\tinjectMessage(address: string, message: Omit<EmailMessage, \"id\" | \"receivedAt\">): void {\n\t\tconst messages = this.inboxes.get(address);\n\t\tif (!messages) throw new Error(`No inbox found for ${address}`);\n\t\tmessages.push({\n\t\t\t...message,\n\t\t\tid: ulid(),\n\t\t\treceivedAt: new Date().toISOString(),\n\t\t});\n\t}\n}\n","import { ulid } from \"ulid\";\nimport type { Identity } from \"../../identity/identity.js\";\nimport type {\n\tPhoneNumber,\n\tPhoneOptions,\n\tPhoneProvider,\n\tProviderHealthResult,\n\tSmsMessage,\n} from \"../types.js\";\n\nexport class MockPhoneProvider implements PhoneProvider {\n\tname = \"mock\";\n\tprivate numbers = new Map<string, SmsMessage[]>();\n\n\tasync provisionNumber(_identity: Identity, _options?: PhoneOptions): Promise<PhoneNumber> {\n\t\tconst id = ulid();\n\t\tconst areaCode = Math.floor(200 + Math.random() * 800);\n\t\tconst lineNumber = Math.floor(1000000 + Math.random() * 9000000);\n\t\tconst number = `+1${areaCode}${lineNumber}`;\n\t\tthis.numbers.set(number, []);\n\t\treturn { number, providerId: id, provider: this.name };\n\t}\n\n\tasync getMessages(phone: PhoneNumber, since?: Date): Promise<SmsMessage[]> {\n\t\tconst messages = this.numbers.get(phone.number) ?? [];\n\t\tif (!since) return messages;\n\t\treturn messages.filter((m) => new Date(m.receivedAt) >= since);\n\t}\n\n\tasync releaseNumber(phone: PhoneNumber): Promise<void> {\n\t\tthis.numbers.delete(phone.number);\n\t}\n\n\tasync healthCheck(): Promise<ProviderHealthResult> {\n\t\treturn { provider: this.name, healthy: true, message: \"Mock provider always healthy\" };\n\t}\n\n\t// Test helper: inject an SMS into a number\n\tinjectSms(number: string, message: Omit<SmsMessage, \"id\" | \"receivedAt\">): void {\n\t\tconst messages = this.numbers.get(number);\n\t\tif (!messages) throw new Error(`No phone number found for ${number}`);\n\t\tmessages.push({\n\t\t\t...message,\n\t\t\tid: ulid(),\n\t\t\treceivedAt: new Date().toISOString(),\n\t\t});\n\t}\n}\n","import type Database from \"better-sqlite3\";\nimport { ulid } from \"ulid\";\n\nexport type ActivityEventType =\n\t| \"identity.created\"\n\t| \"identity.provisioning\"\n\t| \"identity.active\"\n\t| \"identity.killing\"\n\t| \"identity.killed\"\n\t| \"identity.failed\"\n\t| \"email.inbox_created\"\n\t| \"email.received\"\n\t| \"email.inbox_deleted\"\n\t| \"phone.provisioned\"\n\t| \"phone.sms_received\"\n\t| \"phone.released\"\n\t| \"card.created\"\n\t| \"card.deactivated\"\n\t| \"policy.violated\"\n\t| \"system.error\";\n\nexport interface ActivityEvent {\n\tid: string;\n\tidentityId: string | null;\n\ttimestamp: string;\n\teventType: ActivityEventType;\n\tprovider: string | null;\n\tresourceType: string | null;\n\tresourceId: string | null;\n\tdetails: Record<string, unknown> | null;\n\tcostEstimateCents: number | null;\n}\n\ninterface ActivityRow {\n\tid: string;\n\tidentity_id: string | null;\n\ttimestamp: string;\n\tevent_type: string;\n\tprovider: string | null;\n\tresource_type: string | null;\n\tresource_id: string | null;\n\tdetails: string | null;\n\tcost_estimate_cents: number | null;\n}\n\nfunction rowToEvent(row: ActivityRow): ActivityEvent {\n\treturn {\n\t\tid: row.id,\n\t\tidentityId: row.identity_id,\n\t\ttimestamp: row.timestamp,\n\t\teventType: row.event_type as ActivityEventType,\n\t\tprovider: row.provider,\n\t\tresourceType: row.resource_type,\n\t\tresourceId: row.resource_id,\n\t\tdetails: row.details ? JSON.parse(row.details) : null,\n\t\tcostEstimateCents: row.cost_estimate_cents,\n\t};\n}\n\nexport class ActivityLog {\n\tconstructor(private db: Database.Database) {}\n\n\tappend(event: Omit<ActivityEvent, \"id\" | \"timestamp\">): ActivityEvent {\n\t\tconst id = ulid();\n\t\tconst timestamp = new Date().toISOString();\n\n\t\tthis.db.prepare(`\n\t\t\tINSERT INTO activity_log (\n\t\t\t\tid, identity_id, timestamp, event_type, provider,\n\t\t\t\tresource_type, resource_id, details, cost_estimate_cents\n\t\t\t) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)\n\t\t`).run(\n\t\t\tid,\n\t\t\tevent.identityId,\n\t\t\ttimestamp,\n\t\t\tevent.eventType,\n\t\t\tevent.provider,\n\t\t\tevent.resourceType,\n\t\t\tevent.resourceId,\n\t\t\tevent.details ? JSON.stringify(event.details) : null,\n\t\t\tevent.costEstimateCents,\n\t\t);\n\n\t\treturn { id, timestamp, ...event };\n\t}\n\n\tquery(options?: {\n\t\tidentityId?: string;\n\t\teventType?: ActivityEventType;\n\t\tlimit?: number;\n\t\tsince?: string;\n\t}): ActivityEvent[] {\n\t\tconst conditions: string[] = [];\n\t\tconst values: (string | number)[] = [];\n\n\t\tif (options?.identityId) {\n\t\t\tconditions.push(\"identity_id = ?\");\n\t\t\tvalues.push(options.identityId);\n\t\t}\n\t\tif (options?.eventType) {\n\t\t\tconditions.push(\"event_type = ?\");\n\t\t\tvalues.push(options.eventType);\n\t\t}\n\t\tif (options?.since) {\n\t\t\tconditions.push(\"timestamp >= ?\");\n\t\t\tvalues.push(options.since);\n\t\t}\n\n\t\tconst where = conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n\t\tconst limit = options?.limit ? `LIMIT ${options.limit}` : \"LIMIT 100\";\n\n\t\tconst rows = this.db.prepare(\n\t\t\t`SELECT * FROM activity_log ${where} ORDER BY timestamp DESC ${limit}`,\n\t\t).all(...values) as ActivityRow[];\n\n\t\treturn rows.map(rowToEvent);\n\t}\n}\n","import Database from \"better-sqlite3\";\nimport { mkdirSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS identities (\n id TEXT PRIMARY KEY,\n persona_first_name TEXT NOT NULL,\n persona_last_name TEXT NOT NULL,\n persona_full_name TEXT NOT NULL,\n persona_address_json TEXT NOT NULL,\n email TEXT,\n email_provider_id TEXT,\n phone TEXT,\n phone_provider_id TEXT,\n card_last_four TEXT,\n card_provider_id TEXT,\n status TEXT NOT NULL DEFAULT 'created',\n spend_limit_cents INTEGER,\n ttl_expires_at TEXT,\n resources_json TEXT NOT NULL DEFAULT '[]',\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS activity_log (\n id TEXT PRIMARY KEY,\n identity_id TEXT,\n timestamp TEXT NOT NULL,\n event_type TEXT NOT NULL,\n provider TEXT,\n resource_type TEXT,\n resource_id TEXT,\n details TEXT,\n cost_estimate_cents INTEGER,\n FOREIGN KEY (identity_id) REFERENCES identities(id)\n);\n\nCREATE TABLE IF NOT EXISTS policies (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n rule_type TEXT NOT NULL,\n rule_value TEXT NOT NULL,\n enabled INTEGER NOT NULL DEFAULT 1,\n created_at TEXT NOT NULL\n);\n\nCREATE INDEX IF NOT EXISTS idx_activity_identity ON activity_log(identity_id);\nCREATE INDEX IF NOT EXISTS idx_activity_timestamp ON activity_log(timestamp);\nCREATE INDEX IF NOT EXISTS idx_activity_event_type ON activity_log(event_type);\nCREATE INDEX IF NOT EXISTS idx_identities_status ON identities(status);\n`;\n\nexport function createDatabase(dbPath: string): Database.Database {\n\tmkdirSync(dirname(dbPath), { recursive: true });\n\n\tconst db = new Database(dbPath);\n\tdb.pragma(\"journal_mode = WAL\");\n\tdb.pragma(\"foreign_keys = ON\");\n\tdb.exec(SCHEMA);\n\n\treturn db;\n}\n\nexport function createInMemoryDatabase(): Database.Database {\n\tconst db = new Database(\":memory:\");\n\tdb.pragma(\"foreign_keys = ON\");\n\tdb.exec(SCHEMA);\n\treturn db;\n}\n","import type Database from \"better-sqlite3\";\nimport { ulid } from \"ulid\";\nimport type { Identity, IdentityResources, IdentityStatus } from \"../identity/identity.js\";\nimport type { Persona } from \"../identity/persona.js\";\nimport { assertTransition } from \"../identity/state-machine.js\";\n\ninterface IdentityRow {\n\tid: string;\n\tpersona_first_name: string;\n\tpersona_last_name: string;\n\tpersona_full_name: string;\n\tpersona_address_json: string;\n\temail: string | null;\n\temail_provider_id: string | null;\n\tphone: string | null;\n\tphone_provider_id: string | null;\n\tcard_last_four: string | null;\n\tcard_provider_id: string | null;\n\tstatus: string;\n\tspend_limit_cents: number | null;\n\tttl_expires_at: string | null;\n\tresources_json: string;\n\tcreated_at: string;\n\tupdated_at: string;\n}\n\nfunction rowToIdentity(row: IdentityRow): Identity {\n\treturn {\n\t\tid: row.id,\n\t\tpersona: {\n\t\t\tfirstName: row.persona_first_name,\n\t\t\tlastName: row.persona_last_name,\n\t\t\tfullName: row.persona_full_name,\n\t\t\taddress: JSON.parse(row.persona_address_json),\n\t\t},\n\t\tstatus: row.status as IdentityStatus,\n\t\temail: row.email ?? undefined,\n\t\temailProviderId: row.email_provider_id ?? undefined,\n\t\tphone: row.phone ?? undefined,\n\t\tphoneProviderId: row.phone_provider_id ?? undefined,\n\t\tcardLastFour: row.card_last_four ?? undefined,\n\t\tcardProviderId: row.card_provider_id ?? undefined,\n\t\tspendLimitCents: row.spend_limit_cents ?? undefined,\n\t\tttlExpiresAt: row.ttl_expires_at ?? undefined,\n\t\tresources: JSON.parse(row.resources_json) as IdentityResources,\n\t\tcreatedAt: row.created_at,\n\t\tupdatedAt: row.updated_at,\n\t};\n}\n\nexport class IdentityStore {\n\tconstructor(private db: Database.Database) {}\n\n\tcreate(persona: Persona, resources: IdentityResources, options?: {\n\t\tspendLimitCents?: number;\n\t\tttlMinutes?: number;\n\t}): Identity {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\t\tconst ttlExpiresAt = options?.ttlMinutes\n\t\t\t? new Date(Date.now() + options.ttlMinutes * 60_000).toISOString()\n\t\t\t: null;\n\n\t\tthis.db.prepare(`\n\t\t\tINSERT INTO identities (\n\t\t\t\tid, persona_first_name, persona_last_name, persona_full_name,\n\t\t\t\tpersona_address_json, status, spend_limit_cents, ttl_expires_at,\n\t\t\t\tresources_json, created_at, updated_at\n\t\t\t) VALUES (?, ?, ?, ?, ?, 'created', ?, ?, ?, ?, ?)\n\t\t`).run(\n\t\t\tid,\n\t\t\tpersona.firstName,\n\t\t\tpersona.lastName,\n\t\t\tpersona.fullName,\n\t\t\tJSON.stringify(persona.address),\n\t\t\toptions?.spendLimitCents ?? null,\n\t\t\tttlExpiresAt,\n\t\t\tJSON.stringify(resources),\n\t\t\tnow,\n\t\t\tnow,\n\t\t);\n\n\t\treturn this.get(id)!;\n\t}\n\n\tget(id: string): Identity | null {\n\t\tconst row = this.db.prepare(\"SELECT * FROM identities WHERE id = ?\").get(id) as\n\t\t\t| IdentityRow\n\t\t\t| undefined;\n\t\treturn row ? rowToIdentity(row) : null;\n\t}\n\n\tlist(status?: IdentityStatus): Identity[] {\n\t\tconst rows = status\n\t\t\t? (this.db.prepare(\"SELECT * FROM identities WHERE status = ? ORDER BY created_at DESC\").all(status) as IdentityRow[])\n\t\t\t: (this.db.prepare(\"SELECT * FROM identities ORDER BY created_at DESC\").all() as IdentityRow[]);\n\t\treturn rows.map(rowToIdentity);\n\t}\n\n\tupdateStatus(id: string, newStatus: IdentityStatus): Identity {\n\t\tconst current = this.get(id);\n\t\tif (!current) throw new Error(`Identity not found: ${id}`);\n\t\tassertTransition(current.status, newStatus);\n\n\t\tthis.db.prepare(\"UPDATE identities SET status = ?, updated_at = ? WHERE id = ?\").run(\n\t\t\tnewStatus,\n\t\t\tnew Date().toISOString(),\n\t\t\tid,\n\t\t);\n\n\t\treturn this.get(id)!;\n\t}\n\n\tupdateResources(\n\t\tid: string,\n\t\tupdates: Partial<Pick<Identity, \"email\" | \"emailProviderId\" | \"phone\" | \"phoneProviderId\" | \"cardLastFour\" | \"cardProviderId\">>,\n\t): Identity {\n\t\tconst sets: string[] = [];\n\t\tconst values: (string | null)[] = [];\n\n\t\tif (updates.email !== undefined) {\n\t\t\tsets.push(\"email = ?\");\n\t\t\tvalues.push(updates.email ?? null);\n\t\t}\n\t\tif (updates.emailProviderId !== undefined) {\n\t\t\tsets.push(\"email_provider_id = ?\");\n\t\t\tvalues.push(updates.emailProviderId ?? null);\n\t\t}\n\t\tif (updates.phone !== undefined) {\n\t\t\tsets.push(\"phone = ?\");\n\t\t\tvalues.push(updates.phone ?? null);\n\t\t}\n\t\tif (updates.phoneProviderId !== undefined) {\n\t\t\tsets.push(\"phone_provider_id = ?\");\n\t\t\tvalues.push(updates.phoneProviderId ?? null);\n\t\t}\n\t\tif (updates.cardLastFour !== undefined) {\n\t\t\tsets.push(\"card_last_four = ?\");\n\t\t\tvalues.push(updates.cardLastFour ?? null);\n\t\t}\n\t\tif (updates.cardProviderId !== undefined) {\n\t\t\tsets.push(\"card_provider_id = ?\");\n\t\t\tvalues.push(updates.cardProviderId ?? null);\n\t\t}\n\n\t\tif (sets.length === 0) return this.get(id)!;\n\n\t\tsets.push(\"updated_at = ?\");\n\t\tvalues.push(new Date().toISOString());\n\t\tvalues.push(id);\n\n\t\tthis.db.prepare(`UPDATE identities SET ${sets.join(\", \")} WHERE id = ?`).run(...values);\n\t\treturn this.get(id)!;\n\t}\n\n\tgetExpired(): Identity[] {\n\t\tconst now = new Date().toISOString();\n\t\tconst rows = this.db.prepare(\n\t\t\t\"SELECT * FROM identities WHERE ttl_expires_at IS NOT NULL AND ttl_expires_at <= ? AND status = 'active'\",\n\t\t).all(now) as IdentityRow[];\n\t\treturn rows.map(rowToIdentity);\n\t}\n\n\tcountActive(): number {\n\t\tconst row = this.db.prepare(\n\t\t\t\"SELECT COUNT(*) as count FROM identities WHERE status IN ('created', 'provisioning', 'active')\",\n\t\t).get() as { count: number };\n\t\treturn row.count;\n\t}\n}\n","import type { IdentityStatus } from \"./identity.js\";\n\nconst VALID_TRANSITIONS: Record<IdentityStatus, IdentityStatus[]> = {\n\tcreated: [\"provisioning\", \"failed\"],\n\tprovisioning: [\"active\", \"failed\", \"killing\"],\n\tactive: [\"killing\"],\n\tkilling: [\"killed\", \"failed\"],\n\tkilled: [],\n\tfailed: [\"provisioning\", \"killing\"],\n};\n\nexport function canTransition(from: IdentityStatus, to: IdentityStatus): boolean {\n\treturn VALID_TRANSITIONS[from]?.includes(to) ?? false;\n}\n\nexport function assertTransition(from: IdentityStatus, to: IdentityStatus): void {\n\tif (!canTransition(from, to)) {\n\t\tthrow new Error(`Invalid identity transition: ${from} -> ${to}`);\n\t}\n}\n","import type Database from \"better-sqlite3\";\nimport { ulid } from \"ulid\";\n\nexport type PolicyRuleType =\n\t| \"max_identities\"\n\t| \"max_spend_per_identity\"\n\t| \"default_ttl_minutes\"\n\t| \"require_card_approval\";\n\nexport interface Policy {\n\tid: string;\n\tname: string;\n\truleType: PolicyRuleType;\n\truleValue: unknown;\n\tenabled: boolean;\n\tcreatedAt: string;\n}\n\ninterface PolicyRow {\n\tid: string;\n\tname: string;\n\trule_type: string;\n\trule_value: string;\n\tenabled: number;\n\tcreated_at: string;\n}\n\nfunction rowToPolicy(row: PolicyRow): Policy {\n\treturn {\n\t\tid: row.id,\n\t\tname: row.name,\n\t\truleType: row.rule_type as PolicyRuleType,\n\t\truleValue: JSON.parse(row.rule_value),\n\t\tenabled: row.enabled === 1,\n\t\tcreatedAt: row.created_at,\n\t};\n}\n\nexport class PolicyStore {\n\tconstructor(private db: Database.Database) {}\n\n\tcreate(name: string, ruleType: PolicyRuleType, ruleValue: unknown): Policy {\n\t\tconst id = ulid();\n\t\tconst now = new Date().toISOString();\n\n\t\tthis.db.prepare(`\n\t\t\tINSERT INTO policies (id, name, rule_type, rule_value, enabled, created_at)\n\t\t\tVALUES (?, ?, ?, ?, 1, ?)\n\t\t`).run(id, name, ruleType, JSON.stringify(ruleValue), now);\n\n\t\treturn this.get(id)!;\n\t}\n\n\tget(id: string): Policy | null {\n\t\tconst row = this.db.prepare(\"SELECT * FROM policies WHERE id = ?\").get(id) as\n\t\t\t| PolicyRow\n\t\t\t| undefined;\n\t\treturn row ? rowToPolicy(row) : null;\n\t}\n\n\tlist(): Policy[] {\n\t\tconst rows = this.db.prepare(\"SELECT * FROM policies ORDER BY created_at DESC\").all() as PolicyRow[];\n\t\treturn rows.map(rowToPolicy);\n\t}\n\n\tgetEnabled(): Policy[] {\n\t\tconst rows = this.db.prepare(\n\t\t\t\"SELECT * FROM policies WHERE enabled = 1 ORDER BY created_at DESC\",\n\t\t).all() as PolicyRow[];\n\t\treturn rows.map(rowToPolicy);\n\t}\n\n\tsetEnabled(id: string, enabled: boolean): void {\n\t\tthis.db.prepare(\"UPDATE policies SET enabled = ? WHERE id = ?\").run(enabled ? 1 : 0, id);\n\t}\n\n\tdelete(id: string): void {\n\t\tthis.db.prepare(\"DELETE FROM policies WHERE id = ?\").run(id);\n\t}\n}\n","import type Database from \"better-sqlite3\";\nimport { type TerminatorConfig, loadConfig } from \"./config.js\";\nimport type { Identity, IdentityResources } from \"./identity/identity.js\";\nimport { createPersona } from \"./identity/persona.js\";\nimport { KillSwitch, type KillResult } from \"./kill-switch.js\";\nimport { parseVerificationCode } from \"./parsers/verification.js\";\nimport { PolicyEngine, type PolicyViolation } from \"./policies/engine.js\";\nimport { MockCardProvider } from \"./providers/card/mock.js\";\nimport { MockEmailProvider } from \"./providers/email/mock.js\";\nimport { MockPhoneProvider } from \"./providers/phone/mock.js\";\nimport type {\n\tCardDetails,\n\tCardProvider,\n\tEmailMessage,\n\tEmailProvider,\n\tPhoneProvider,\n\tProviderHealthResult,\n\tSmsMessage,\n} from \"./providers/types.js\";\nimport { ActivityLog, type ActivityEvent, type ActivityEventType } from \"./store/activity-log.js\";\nimport { createDatabase, createInMemoryDatabase } from \"./store/database.js\";\nimport { IdentityStore } from \"./store/identities.js\";\nimport { PolicyStore } from \"./store/policies.js\";\n\nexport interface TerminatorOptions {\n\tconfig?: Partial<TerminatorConfig>;\n\temailProvider?: EmailProvider;\n\tphoneProvider?: PhoneProvider;\n\tcardProvider?: CardProvider;\n\tinMemory?: boolean;\n}\n\nexport interface CreateIdentityOptions {\n\tresources?: IdentityResources;\n\tspendLimitCents?: number;\n\tttlMinutes?: number;\n\tconfirm?: boolean;\n}\n\nexport class Terminator {\n\treadonly config: TerminatorConfig;\n\treadonly identityStore: IdentityStore;\n\treadonly activityLog: ActivityLog;\n\treadonly policyStore: PolicyStore;\n\treadonly policyEngine: PolicyEngine;\n\treadonly killSwitch: KillSwitch;\n\n\tprivate emailProvider?: EmailProvider;\n\tprivate phoneProvider?: PhoneProvider;\n\tprivate cardProvider?: CardProvider;\n\tprivate db: Database.Database;\n\n\tconstructor(options: TerminatorOptions = {}) {\n\t\tthis.config = loadConfig(options.config);\n\n\t\tthis.db = options.inMemory\n\t\t\t? createInMemoryDatabase()\n\t\t\t: createDatabase(this.config.dbPath);\n\n\t\tthis.identityStore = new IdentityStore(this.db);\n\t\tthis.activityLog = new ActivityLog(this.db);\n\t\tthis.policyStore = new PolicyStore(this.db);\n\n\t\t// Use provided providers or fall back to mocks\n\t\tthis.emailProvider = options.emailProvider ?? new MockEmailProvider();\n\t\tthis.phoneProvider = options.phoneProvider ?? new MockPhoneProvider();\n\t\tthis.cardProvider = options.cardProvider ?? new MockCardProvider();\n\n\t\tthis.policyEngine = new PolicyEngine(\n\t\t\tthis.policyStore,\n\t\t\tthis.identityStore,\n\t\t\tthis.config,\n\t\t);\n\n\t\tthis.killSwitch = new KillSwitch(\n\t\t\tthis.identityStore,\n\t\t\tthis.activityLog,\n\t\t\tthis.emailProvider,\n\t\t\tthis.phoneProvider,\n\t\t\tthis.cardProvider,\n\t\t);\n\t}\n\n\tasync createIdentity(options: CreateIdentityOptions = {}): Promise<Identity> {\n\t\tconst resources = options.resources ?? [\"email\", \"phone\", \"card\"];\n\t\tconst spendLimitCents = options.spendLimitCents ?? this.config.defaultSpendLimitCents;\n\t\tconst ttlMinutes = options.ttlMinutes ?? this.config.defaultTtlMinutes;\n\n\t\t// Check policies\n\t\tconst violations = this.policyEngine.checkCreateIdentity(resources, spendLimitCents);\n\t\tconst cardApprovalViolation = violations.find(\n\t\t\t(v) => v.ruleType === \"require_card_approval\",\n\t\t);\n\t\tconst otherViolations = violations.filter((v) => v.ruleType !== \"require_card_approval\");\n\n\t\tif (otherViolations.length > 0) {\n\t\t\tthrow new PolicyViolationError(otherViolations);\n\t\t}\n\n\t\t// Card approval check — if policy requires it and confirm not set\n\t\tif (cardApprovalViolation && resources.includes(\"card\") && !options.confirm) {\n\t\t\tthrow new PolicyViolationError([cardApprovalViolation]);\n\t\t}\n\n\t\t// Create persona and identity record\n\t\tconst persona = createPersona();\n\t\tlet identity = this.identityStore.create(persona, resources, {\n\t\t\tspendLimitCents,\n\t\t\tttlMinutes,\n\t\t});\n\n\t\tthis.activityLog.append({\n\t\t\tidentityId: identity.id,\n\t\t\teventType: \"identity.created\",\n\t\t\tprovider: null,\n\t\t\tresourceType: \"identity\",\n\t\t\tresourceId: identity.id,\n\t\t\tdetails: { resources, persona: { name: persona.fullName } },\n\t\t\tcostEstimateCents: null,\n\t\t});\n\n\t\t// Provision resources\n\t\tidentity = this.identityStore.updateStatus(identity.id, \"provisioning\");\n\t\tthis.activityLog.append({\n\t\t\tidentityId: identity.id,\n\t\t\teventType: \"identity.provisioning\",\n\t\t\tprovider: null,\n\t\t\tresourceType: \"identity\",\n\t\t\tresourceId: identity.id,\n\t\t\tdetails: { resources },\n\t\t\tcostEstimateCents: null,\n\t\t});\n\n\t\tconst errors: string[] = [];\n\n\t\tif (resources.includes(\"email\") && this.emailProvider) {\n\t\t\ttry {\n\t\t\t\tconst inbox = await this.emailProvider.createInbox(identity);\n\t\t\t\tidentity = this.identityStore.updateResources(identity.id, {\n\t\t\t\t\temail: inbox.address,\n\t\t\t\t\temailProviderId: inbox.providerId,\n\t\t\t\t});\n\t\t\t\tpersona.email = inbox.address;\n\t\t\t\tthis.activityLog.append({\n\t\t\t\t\tidentityId: identity.id,\n\t\t\t\t\teventType: \"email.inbox_created\",\n\t\t\t\t\tprovider: this.emailProvider.name,\n\t\t\t\t\tresourceType: \"email\",\n\t\t\t\t\tresourceId: inbox.providerId,\n\t\t\t\t\tdetails: { address: inbox.address },\n\t\t\t\t\tcostEstimateCents: 0,\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(`email: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\n\t\tif (resources.includes(\"phone\") && this.phoneProvider) {\n\t\t\ttry {\n\t\t\t\tconst phone = await this.phoneProvider.provisionNumber(identity);\n\t\t\t\tidentity = this.identityStore.updateResources(identity.id, {\n\t\t\t\t\tphone: phone.number,\n\t\t\t\t\tphoneProviderId: phone.providerId,\n\t\t\t\t});\n\t\t\t\tpersona.phone = phone.number;\n\t\t\t\tthis.activityLog.append({\n\t\t\t\t\tidentityId: identity.id,\n\t\t\t\t\teventType: \"phone.provisioned\",\n\t\t\t\t\tprovider: this.phoneProvider.name,\n\t\t\t\t\tresourceType: \"phone\",\n\t\t\t\t\tresourceId: phone.providerId,\n\t\t\t\t\tdetails: { number: phone.number },\n\t\t\t\t\tcostEstimateCents: 115, // ~$1.15/month for Twilio number\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(`phone: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\n\t\tif (resources.includes(\"card\") && this.cardProvider) {\n\t\t\ttry {\n\t\t\t\tconst card = await this.cardProvider.createCard(identity, {\n\t\t\t\t\tspendLimitCents,\n\t\t\t\t\ttype: \"single_use\",\n\t\t\t\t});\n\t\t\t\tidentity = this.identityStore.updateResources(identity.id, {\n\t\t\t\t\tcardLastFour: card.lastFour,\n\t\t\t\t\tcardProviderId: card.providerId,\n\t\t\t\t});\n\t\t\t\tthis.activityLog.append({\n\t\t\t\t\tidentityId: identity.id,\n\t\t\t\t\teventType: \"card.created\",\n\t\t\t\t\tprovider: this.cardProvider.name,\n\t\t\t\t\tresourceType: \"card\",\n\t\t\t\t\tresourceId: card.providerId,\n\t\t\t\t\tdetails: { lastFour: card.lastFour, spendLimitCents },\n\t\t\t\t\tcostEstimateCents: 10, // ~$0.10 per virtual card\n\t\t\t\t});\n\t\t\t} catch (error) {\n\t\t\t\terrors.push(`card: ${error instanceof Error ? error.message : String(error)}`);\n\t\t\t}\n\t\t}\n\n\t\t// Transition to active (or failed if nothing was provisioned)\n\t\tconst hasAnyResource = identity.email || identity.phone || identity.cardProviderId;\n\t\tif (hasAnyResource) {\n\t\t\tidentity = this.identityStore.updateStatus(identity.id, \"active\");\n\t\t\tthis.activityLog.append({\n\t\t\t\tidentityId: identity.id,\n\t\t\t\teventType: \"identity.active\",\n\t\t\t\tprovider: null,\n\t\t\t\tresourceType: \"identity\",\n\t\t\t\tresourceId: identity.id,\n\t\t\t\tdetails: errors.length > 0 ? { partialErrors: errors } : null,\n\t\t\t\tcostEstimateCents: null,\n\t\t\t});\n\t\t} else {\n\t\t\tidentity = this.identityStore.updateStatus(identity.id, \"failed\");\n\t\t\tthis.activityLog.append({\n\t\t\t\tidentityId: identity.id,\n\t\t\t\teventType: \"identity.failed\",\n\t\t\t\tprovider: null,\n\t\t\t\tresourceType: \"identity\",\n\t\t\t\tresourceId: identity.id,\n\t\t\t\tdetails: { errors },\n\t\t\t\tcostEstimateCents: null,\n\t\t\t});\n\t\t}\n\n\t\treturn identity;\n\t}\n\n\tgetIdentity(id: string): Identity | null {\n\t\treturn this.identityStore.get(id);\n\t}\n\n\tlistIdentities(status?: \"active\" | \"killed\" | \"all\"): Identity[] {\n\t\tif (status === \"all\" || status === undefined) return this.identityStore.list();\n\t\treturn this.identityStore.list(status);\n\t}\n\n\tasync readMessages(identityId: string, since?: Date): Promise<{\n\t\temails: EmailMessage[];\n\t\tsms: SmsMessage[];\n\t}> {\n\t\tconst identity = this.identityStore.get(identityId);\n\t\tif (!identity) throw new Error(`Identity not found: ${identityId}`);\n\n\t\tconst emails: EmailMessage[] = [];\n\t\tconst sms: SmsMessage[] = [];\n\n\t\tif (identity.email && identity.emailProviderId && this.emailProvider) {\n\t\t\tconst inbox = {\n\t\t\t\taddress: identity.email,\n\t\t\t\tproviderId: identity.emailProviderId,\n\t\t\t\tprovider: this.emailProvider.name,\n\t\t\t};\n\t\t\tconst messages = await this.emailProvider.getMessages(inbox, since);\n\t\t\temails.push(...messages);\n\t\t}\n\n\t\tif (identity.phone && identity.phoneProviderId && this.phoneProvider) {\n\t\t\tconst phone = {\n\t\t\t\tnumber: identity.phone,\n\t\t\t\tproviderId: identity.phoneProviderId,\n\t\t\t\tprovider: this.phoneProvider.name,\n\t\t\t};\n\t\t\tconst messages = await this.phoneProvider.getMessages(phone, since);\n\t\t\tsms.push(...messages);\n\t\t}\n\n\t\treturn { emails, sms };\n\t}\n\n\tasync getCardDetails(identityId: string): Promise<CardDetails> {\n\t\tconst identity = this.identityStore.get(identityId);\n\t\tif (!identity) throw new Error(`Identity not found: ${identityId}`);\n\t\tif (!identity.cardProviderId || !this.cardProvider) {\n\t\t\tthrow new Error(\"No card associated with this identity\");\n\t\t}\n\n\t\treturn this.cardProvider.getCardDetails({\n\t\t\tlastFour: identity.cardLastFour!,\n\t\t\tproviderId: identity.cardProviderId,\n\t\t\tprovider: this.cardProvider.name,\n\t\t});\n\t}\n\n\tasync extractCode(identityId: string): Promise<string | null> {\n\t\tconst { emails, sms } = await this.readMessages(identityId);\n\n\t\t// Check SMS first (more likely to have codes), newest first\n\t\tfor (const msg of [...sms].reverse()) {\n\t\t\tconst result = parseVerificationCode(msg.body);\n\t\t\tif (result) return result.code;\n\t\t}\n\n\t\t// Then check emails\n\t\tfor (const msg of [...emails].reverse()) {\n\t\t\tconst text = msg.text || msg.subject;\n\t\t\tconst result = parseVerificationCode(text);\n\t\t\tif (result) return result.code;\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tasync killIdentity(id: string): Promise<KillResult> {\n\t\treturn this.killSwitch.killIdentity(id);\n\t}\n\n\tasync killAll(): Promise<KillResult[]> {\n\t\treturn this.killSwitch.killAll();\n\t}\n\n\tgetActivityLog(options?: {\n\t\tidentityId?: string;\n\t\teventType?: ActivityEventType;\n\t\tlimit?: number;\n\t\tsince?: string;\n\t}): ActivityEvent[] {\n\t\treturn this.activityLog.query(options);\n\t}\n\n\tasync checkStatus(): Promise<{\n\t\tproviders: ProviderHealthResult[];\n\t\tactiveIdentities: number;\n\t\tconfiguredProviders: { email: boolean; phone: boolean; card: boolean };\n\t}> {\n\t\tconst providers: ProviderHealthResult[] = [];\n\n\t\tif (this.emailProvider) {\n\t\t\tproviders.push(await this.emailProvider.healthCheck());\n\t\t}\n\t\tif (this.phoneProvider) {\n\t\t\tproviders.push(await this.phoneProvider.healthCheck());\n\t\t}\n\t\tif (this.cardProvider) {\n\t\t\tproviders.push(await this.cardProvider.healthCheck());\n\t\t}\n\n\t\treturn {\n\t\t\tproviders,\n\t\t\tactiveIdentities: this.identityStore.countActive(),\n\t\t\tconfiguredProviders: {\n\t\t\t\temail: !!this.emailProvider,\n\t\t\t\tphone: !!this.phoneProvider,\n\t\t\t\tcard: !!this.cardProvider,\n\t\t\t},\n\t\t};\n\t}\n\n\tclose(): void {\n\t\tthis.db.close();\n\t}\n}\n\nexport class PolicyViolationError extends Error {\n\tconstructor(public violations: PolicyViolation[]) {\n\t\tsuper(violations.map((v) => v.message).join(\"; \"));\n\t\tthis.name = \"PolicyViolationError\";\n\t}\n}\n"],"mappings":"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","names":["ulid","ulid","ulid","ulid","ulid","ulid"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@terminator-network/core",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"types": "dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": ["dist"],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"test:watch": "vitest",
|
|
21
|
+
"clean": "rm -rf dist"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"better-sqlite3": "^11.7.0",
|
|
25
|
+
"drizzle-orm": "^0.38.0",
|
|
26
|
+
"ulid": "^2.3.0",
|
|
27
|
+
"zod": "^3.24.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
31
|
+
"drizzle-kit": "^0.30.0",
|
|
32
|
+
"tsup": "^8.3.0",
|
|
33
|
+
"typescript": "^5.7.0",
|
|
34
|
+
"vitest": "^3.0.0"
|
|
35
|
+
},
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20.0.0"
|
|
38
|
+
}
|
|
39
|
+
}
|