@umec/core 0.1.0-alpha.8 → 0.1.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/dist/catalog-5BPLMAW2.js +15 -0
  2. package/dist/catalog-5BPLMAW2.js.map +1 -0
  3. package/dist/chunk-CYKUAS3D.js +9 -0
  4. package/dist/chunk-CYKUAS3D.js.map +1 -0
  5. package/dist/chunk-DN3J2NQC.js +298 -0
  6. package/dist/chunk-DN3J2NQC.js.map +1 -0
  7. package/dist/chunk-PNICEHSO.js +255 -0
  8. package/dist/chunk-PNICEHSO.js.map +1 -0
  9. package/dist/{chunk-JWTXQAOL.js → chunk-RFEX32LI.js} +1 -1
  10. package/dist/chunk-RFEX32LI.js.map +1 -0
  11. package/dist/chunk-T2PO3YLZ.js +64 -0
  12. package/dist/chunk-T2PO3YLZ.js.map +1 -0
  13. package/dist/cli.js +816 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/db/index.d.ts +130 -0
  16. package/dist/db/index.js +81 -0
  17. package/dist/db/index.js.map +1 -0
  18. package/dist/index.d.ts +2 -0
  19. package/dist/index.js +12 -1
  20. package/dist/notify.d.ts +5 -7
  21. package/dist/notify.js +1 -1
  22. package/dist/orders-DRZvcL3s.d.ts +99 -0
  23. package/dist/schema-version-F-YYC1UG.d.ts +25 -0
  24. package/dist/sql-J4YBS7N7.js +7 -0
  25. package/dist/sql-J4YBS7N7.js.map +1 -0
  26. package/package.json +10 -2
  27. package/schema/frozen-checksums.json +11 -0
  28. package/schema/migrations/0001_processed_events.sql +4 -0
  29. package/schema/migrations/0002_orders.sql +19 -0
  30. package/schema/migrations/0003_inventory.sql +5 -0
  31. package/schema/migrations/0004_admin_audit_log.sql +15 -0
  32. package/schema/migrations/0005_orders_tracking.sql +3 -0
  33. package/schema/migrations/0006_products.sql +15 -0
  34. package/schema/migrations/0007_orders_extras.sql +1 -0
  35. package/schema/snapshot.json +433 -0
  36. package/schema/upgrades/types.ts +16 -0
  37. package/schema/upgrades/v2-to-v6.ts +205 -0
  38. package/dist/chunk-JWTXQAOL.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cli/index.ts","../src/cli/doctor.ts","../schema/upgrades/v2-to-v6.ts","../src/cli/checksum.ts","../src/cli/extend.ts","../src/cli/migrate.ts","../src/cli/wrangler.ts","../src/cli/executor.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { loadSnapshotJson } from \"../db/catalog.js\";\nimport type { SchemaSnapshot } from \"../db/snapshot.js\";\nimport { findPackageRoot } from \"../package-root.js\";\nimport { runDoctor } from \"./doctor.js\";\nimport { runExtend } from \"./extend.js\";\nimport { coreVersionFromPackage, runMigrate, type MigrateOptions } from \"./migrate.js\";\nimport { createWranglerExecutor, readD1DatabaseName, type RunCommand } from \"./wrangler.js\";\nimport type { MigrationExecutor } from \"./executor.js\";\n\nexport type CliIo = {\n cwd?: string;\n stdout?: (message: string) => void;\n stderr?: (message: string) => void;\n executor?: MigrationExecutor;\n runCommand?: RunCommand;\n};\n\nexport function parseArgs(argv: string[]): {\n command: string | null;\n flags: Record<string, string | boolean>;\n} {\n const flags: Record<string, string | boolean> = {};\n let command: string | null = null;\n for (let i = 0; i < argv.length; i += 1) {\n const arg = argv[i];\n if (!arg) continue;\n if (arg.startsWith(\"--\")) {\n const eq = arg.indexOf(\"=\");\n if (eq > 0) {\n flags[arg.slice(2, eq)] = arg.slice(eq + 1);\n continue;\n }\n const name = arg.slice(2);\n const next = argv[i + 1];\n if (next && !next.startsWith(\"--\") && name !== \"dry-run\" && name !== \"adopt\" && name !== \"repair\" && name !== \"remote\" && name !== \"local\") {\n flags[name] = next;\n i += 1;\n } else {\n flags[name] = true;\n }\n continue;\n }\n if (!command) command = arg;\n }\n return { command, flags };\n}\n\nfunction usage(): string {\n return `Usage:\n umec migrate [--dry-run] [--local|--remote] [--adopt] [--repair] [--database NAME]\n umec doctor [--local|--remote] [--database NAME]\n umec extend [--key NAME] [--type boolean|string|number]`;\n}\n\nexport async function runCli(argv: string[], io: CliIo = {}): Promise<number> {\n const cwd = io.cwd ?? process.cwd();\n const stdout = io.stdout ?? ((message) => console.log(message));\n const stderr = io.stderr ?? ((message) => console.error(message));\n const { command, flags } = parseArgs(argv);\n\n if (!command || command === \"help\" || flags.help) {\n stdout(usage());\n return command ? 0 : 1;\n }\n\n const snapshot = loadSnapshotJson() as SchemaSnapshot;\n const remote = flags.remote === true;\n const database = typeof flags.database === \"string\" ? flags.database : readD1DatabaseName(cwd);\n\n const executor =\n io.executor ??\n (command === \"extend\" || (command === \"migrate\" && flags[\"dry-run\"] === true)\n ? undefined\n : database\n ? createWranglerExecutor({ cwd, database, remote, runCommand: io.runCommand })\n : undefined);\n\n if (command === \"migrate\") {\n if (flags[\"dry-run\"] === true && !io.executor) {\n const migrations = (await import(\"../db/catalog.js\")).listCoreMigrations();\n stdout(\"dry-run (no D1 connection)\");\n stdout(\"ensure umec_schema_version / umec_migrations\");\n for (const migration of migrations) stdout(`apply core/${migration.name}`);\n stdout(`would set umec_schema_version.version = ${snapshot.version}`);\n return 0;\n }\n if (!executor) {\n stderr(\"wrangler.jsonc の d1_databases[0].database_name が見つかりません。--database を指定してください。\");\n return 1;\n }\n const options: MigrateOptions = {\n cwd,\n executor,\n snapshot,\n dryRun: flags[\"dry-run\"] === true,\n adopt: flags.adopt === true,\n repair: flags.repair === true,\n coreVersion: coreVersionFromPackage(),\n print: stdout,\n };\n const result = await runMigrate(options);\n for (const warning of result.warnings) stdout(`warn: ${warning}`);\n if (result.error) stderr(result.error);\n return result.exitCode;\n }\n\n if (command === \"doctor\") {\n const result = await runDoctor({\n cwd,\n executor,\n snapshot,\n print: stdout,\n });\n return result.exitCode;\n }\n\n if (command === \"extend\") {\n const result = runExtend({\n cwd,\n key: typeof flags.key === \"string\" ? flags.key : undefined,\n type: typeof flags.type === \"string\" ? flags.type : undefined,\n print: stdout,\n });\n if (result.error) stderr(result.error);\n return result.exitCode;\n }\n\n stderr(usage());\n return 1;\n}\n\nfunction isDirectRun(): boolean {\n const invoked = process.argv[1];\n if (!invoked) return false;\n return /(?:^|[\\\\/])cli(?:\\.js)?$/.test(invoked) || invoked.includes(`${join(\"dist\", \"cli\")}`);\n}\n\nif (isDirectRun()) {\n const pkg = JSON.parse(readFileSync(join(findPackageRoot(), \"package.json\"), \"utf8\")) as { version: string };\n if (process.argv.includes(\"--version\") || process.argv.includes(\"-V\")) {\n console.log(pkg.version);\n process.exit(0);\n }\n runCli(process.argv.slice(2)).then(\n (code) => process.exit(code),\n (error) => {\n console.error(error instanceof Error ? error.message : error);\n process.exit(1);\n },\n );\n}\n","import { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { upgradeV2toV6 } from \"../../schema/upgrades/v2-to-v6.js\";\nimport { currentSchemaVersion, listCoreMigrations } from \"../db/catalog.js\";\nimport { classifyDrift } from \"../db/drift.js\";\nimport { introspectSnapshot } from \"../db/introspect.js\";\nimport type { SchemaSnapshot } from \"../db/snapshot.js\";\nimport { sha256File } from \"./checksum.js\";\nimport type { MigrationExecutor } from \"./executor.js\";\nimport type { Printer } from \"./migrate.js\";\n\nexport type DoctorOptions = {\n cwd: string;\n executor?: MigrationExecutor;\n snapshot: SchemaSnapshot;\n print?: Printer;\n};\n\nexport type DoctorResult = {\n exitCode: number;\n lines: string[];\n};\n\nexport async function runDoctor(options: DoctorOptions): Promise<DoctorResult> {\n const print = options.print ?? (() => {});\n const lines: string[] = [];\n const installed = currentSchemaVersion();\n let exitCode = 0;\n\n const say = (line: string) => {\n lines.push(line);\n print(line);\n };\n\n say(`installed schema version: ${installed}`);\n\n if (!options.executor) {\n say(\"no database executor; offline checks only\");\n } else {\n try {\n const version = await options.executor.first<{ version: number; core_version: string }>(\n \"SELECT version, core_version FROM umec_schema_version WHERE id = 1\",\n );\n if (!version) {\n say(\"umec_schema_version: missing (run umec migrate)\");\n } else {\n say(`database schema version: ${version.version} (core ${version.core_version})`);\n if (version.version > installed) {\n exitCode = 1;\n say(\n `DB は schema v${version.version}。インストール中の @umec/core は v${installed} までしか知らない。戻すには wrangler d1 time-travel restore --bookmark=<記録済み> のあと同じ core バージョンを入れ直すこと。down migration は無い。`,\n );\n }\n }\n } catch {\n say(\"umec_schema_version: unreadable (run umec migrate)\");\n }\n\n const actual = await introspectViaExecutor(options.executor, options.snapshot.version);\n const drift = classifyDrift(options.snapshot, actual);\n for (const finding of drift.compatible) say(`warn: ${finding.message}`);\n for (const finding of drift.incompatible) {\n exitCode = 1;\n say(`error: ${finding.message}`);\n }\n if (await upgradeV2toV6.canApply(options.executor)) {\n exitCode = 1;\n say(\"error: orders は event_id PK の旧スキーマです。umec migrate --repair を実行してください。\");\n }\n\n const applied = await options.executor.all<{ name: string; checksum: string }>(\n \"SELECT name, checksum FROM umec_migrations\",\n ).catch(() => []);\n const appliedByName = new Map(applied.map((row) => [row.name, row.checksum]));\n for (const migration of listCoreMigrations()) {\n const expected = sha256File(migration.path);\n const got = appliedByName.get(migration.name);\n if (got && got !== expected) {\n exitCode = 1;\n say(`error: checksum mismatch ${migration.name}`);\n }\n }\n }\n\n const extensionsPath = join(options.cwd, \"src/config/extensions.ts\");\n if (!existsSync(extensionsPath)) {\n say(\"warn: src/config/extensions.ts がありません。拡張は umec extend で extras_json に足してください。\");\n }\n\n return { exitCode, lines };\n}\n\nasync function introspectViaExecutor(executor: MigrationExecutor, version: number) {\n const db = {\n prepare(query: string) {\n return {\n bind(...values: unknown[]) {\n this._params = values;\n return this;\n },\n _params: [] as unknown[],\n async first<T>() {\n return executor.first<T>(query, this._params);\n },\n async all<T>() {\n return { results: await executor.all<T>(query, this._params) };\n },\n async run() {\n const result = await executor.run(query, this._params);\n return { meta: { changes: result.changes } };\n },\n };\n },\n async batch() {\n return [];\n },\n };\n return introspectSnapshot(db, version);\n}\n","import type { UpgradeExecutor, UpgradeModule } from \"./types.js\";\n\nexport const UPGRADE_PAGE_SIZE = 500;\n\nexport const LEGACY_0002_SQL = `CREATE TABLE IF NOT EXISTS orders (\n event_id TEXT PRIMARY KEY NOT NULL,\n session_id TEXT NOT NULL,\n amount_total INTEGER NOT NULL,\n currency TEXT NOT NULL,\n customer_email TEXT NOT NULL,\n run_id TEXT,\n created_at INTEGER NOT NULL\n);\n`;\n\nexport const V6_ORDERS_DDL = `CREATE TABLE orders_new (\n id TEXT PRIMARY KEY,\n email TEXT NOT NULL,\n name TEXT,\n phone TEXT,\n items_json TEXT NOT NULL,\n amount INTEGER NOT NULL,\n shipping INTEGER,\n address_json TEXT,\n payment_intent TEXT,\n custom_fields_json TEXT,\n status TEXT NOT NULL DEFAULT 'pending',\n run_id TEXT,\n email_status TEXT CHECK (email_status IN ('sent', 'failed')),\n created_at INTEGER NOT NULL,\n shipped_at INTEGER,\n tracking_number TEXT,\n carrier TEXT CHECK (carrier IN ('yamato', 'sagawa', 'japanpost', 'other') OR carrier IS NULL)\n)`;\n\ntype LegacyOrderRow = {\n event_id: string;\n session_id?: string | null;\n amount_total?: number | null;\n amount?: number | null;\n customer_email?: string | null;\n email?: string | null;\n name?: string | null;\n phone?: string | null;\n items_json?: string | null;\n shipping?: number | null;\n address_json?: string | null;\n payment_intent?: string | null;\n custom_fields_json?: string | null;\n status?: string | null;\n run_id?: string | null;\n email_status?: string | null;\n created_at: number;\n shipped_at?: number | null;\n tracking_number?: string | null;\n carrier?: string | null;\n};\n\ntype TableInfoRow = {\n name: string;\n pk: number;\n};\n\nfunction asString(value: unknown, fallback = \"\"): string {\n return typeof value === \"string\" ? value : fallback;\n}\n\nfunction asNullableString(value: unknown): string | null {\n return typeof value === \"string\" ? value : null;\n}\n\nfunction asNumber(value: unknown, fallback = 0): number {\n return typeof value === \"number\" && Number.isFinite(value) ? value : fallback;\n}\n\nfunction asNullableNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n}\n\nexport async function detectLegacyOrdersPk(db: UpgradeExecutor): Promise<boolean> {\n const columns = await db.all<TableInfoRow>(\"PRAGMA table_info(orders)\");\n if (columns.length === 0) return false;\n const eventId = columns.find((column) => column.name === \"event_id\");\n return eventId != null && eventId.pk === 1;\n}\n\nexport function mapLegacyOrder(row: LegacyOrderRow): {\n id: string;\n email: string;\n name: string | null;\n phone: string | null;\n items_json: string;\n amount: number;\n shipping: number | null;\n address_json: string | null;\n payment_intent: string | null;\n custom_fields_json: string | null;\n status: string;\n run_id: string | null;\n email_status: string | null;\n created_at: number;\n shipped_at: number | null;\n tracking_number: string | null;\n carrier: string | null;\n} {\n const sessionId = asNullableString(row.session_id);\n const eventId = asString(row.event_id);\n return {\n id: sessionId && sessionId.length > 0 ? sessionId : eventId,\n email: asString(row.customer_email ?? row.email),\n name: asNullableString(row.name),\n phone: asNullableString(row.phone),\n items_json: asNullableString(row.items_json) ?? \"[]\",\n amount: asNumber(row.amount_total ?? row.amount),\n shipping: asNullableNumber(row.shipping),\n address_json: asNullableString(row.address_json),\n payment_intent: asNullableString(row.payment_intent),\n custom_fields_json: asNullableString(row.custom_fields_json),\n status: asNullableString(row.status) ?? \"pending\",\n run_id: asNullableString(row.run_id),\n email_status: asNullableString(row.email_status),\n created_at: asNumber(row.created_at),\n shipped_at: asNullableNumber(row.shipped_at),\n tracking_number: asNullableString(row.tracking_number),\n carrier: asNullableString(row.carrier),\n };\n}\n\nexport async function applyV2toV6(db: UpgradeExecutor): Promise<void> {\n if (!(await detectLegacyOrdersPk(db))) {\n throw new Error(\"v2-to-v6: orders.event_id primary key not found; refuse to rebuild\");\n }\n\n await db.exec(\"DROP TABLE IF EXISTS orders_new\");\n await db.exec(V6_ORDERS_DDL);\n\n let cursor: string | null = null;\n for (;;) {\n const pageSql = cursor\n ? \"SELECT * FROM orders WHERE event_id > ? ORDER BY event_id LIMIT ?\"\n : \"SELECT * FROM orders ORDER BY event_id LIMIT ?\";\n const pageParams = cursor ? [cursor, UPGRADE_PAGE_SIZE] : [UPGRADE_PAGE_SIZE];\n const rows: LegacyOrderRow[] = await db.all<LegacyOrderRow>(pageSql, pageParams);\n if (rows.length === 0) break;\n\n for (const row of rows) {\n const mapped = mapLegacyOrder(row);\n await db.run(\n `INSERT INTO orders_new (\n id, email, name, phone, items_json, amount, shipping, address_json,\n payment_intent, custom_fields_json, status, run_id, email_status,\n created_at, shipped_at, tracking_number, carrier\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n [\n mapped.id,\n mapped.email,\n mapped.name,\n mapped.phone,\n mapped.items_json,\n mapped.amount,\n mapped.shipping,\n mapped.address_json,\n mapped.payment_intent,\n mapped.custom_fields_json,\n mapped.status,\n mapped.run_id,\n mapped.email_status,\n mapped.created_at,\n mapped.shipped_at,\n mapped.tracking_number,\n mapped.carrier,\n ],\n );\n }\n\n const last: LegacyOrderRow | undefined = rows[rows.length - 1];\n if (!last) break;\n cursor = last.event_id;\n if (rows.length < UPGRADE_PAGE_SIZE) break;\n }\n\n const oldCount = await db.first<{ n: number }>(\"SELECT COUNT(*) AS n FROM orders\");\n const newCount = await db.first<{ n: number }>(\"SELECT COUNT(*) AS n FROM orders_new\");\n const expected = oldCount?.n ?? -1;\n const copied = newCount?.n ?? -2;\n if (expected !== copied) {\n throw new Error(\n `v2-to-v6: COUNT mismatch orders=${expected} orders_new=${copied}. DROP skipped. Restore from Time Travel bookmark.`,\n );\n }\n\n await db.exec(\"DROP TABLE orders\");\n await db.exec(\"ALTER TABLE orders_new RENAME TO orders\");\n await db.exec(\"CREATE INDEX IF NOT EXISTS orders_payment_intent_idx ON orders(payment_intent)\");\n}\n\nexport const upgradeV2toV6: UpgradeModule = {\n name: \"v2-to-v6\",\n fromVersion: 2,\n toVersion: 6,\n description: \"Rebuild orders from event_id PK (v2) to id PK (v6)\",\n replacesChecksums: [\"ca6ec5c885f715a3ae65a7101787d66750ed831370dc2ecde0636cfc3cf83e24\"],\n canApply: detectLegacyOrdersPk,\n apply: applyV2toV6,\n};\n","import { createHash } from \"node:crypto\";\nimport { readFileSync } from \"node:fs\";\n\nexport function sha256Bytes(contents: Buffer | string): string {\n return createHash(\"sha256\").update(contents).digest(\"hex\");\n}\n\nexport function sha256File(path: string): string {\n return sha256Bytes(readFileSync(path));\n}\n\nexport function loadFrozenChecksums(path: string): Record<string, string> {\n return JSON.parse(readFileSync(path, \"utf8\")) as Record<string, string>;\n}\n","import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type { Printer } from \"./migrate.js\";\n\nconst EXTENSION_TYPES = {\n boolean: \"z.boolean().optional()\",\n string: \"z.string().optional()\",\n number: \"z.number().optional()\",\n} as const;\n\nexport type ExtendType = keyof typeof EXTENSION_TYPES;\n\nexport type ExtendOptions = {\n cwd: string;\n key?: string;\n type?: string;\n print?: Printer;\n};\n\nconst STUB = `import { z } from \"zod\";\n\nexport const orderExtensionSchema = z.object({\n});\n\nexport type OrderExtension = z.infer<typeof orderExtensionSchema>;\n`;\n\nfunction isExtendType(value: string): value is ExtendType {\n return value in EXTENSION_TYPES;\n}\n\nexport function runExtend(options: ExtendOptions): { exitCode: number; path: string; error?: string } {\n const print = options.print ?? (() => {});\n const path = join(options.cwd, \"src/config/extensions.ts\");\n mkdirSync(dirname(path), { recursive: true });\n\n if (!existsSync(path)) {\n writeFileSync(path, STUB);\n print(`created ${path}`);\n }\n\n const key = options.key;\n if (!key) {\n print(\"拡張は orders.extras_json に Zod で足す。orders を ALTER しないこと。\");\n print(`編集ファイル: ${path}`);\n return { exitCode: 0, path };\n }\n\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(key)) {\n return { exitCode: 1, path, error: `invalid extras key: ${key}` };\n }\n\n const typeName = options.type ?? \"string\";\n if (!isExtendType(typeName)) {\n return { exitCode: 1, path, error: `unsupported type ${typeName} (boolean|string|number)` };\n }\n\n let source = readFileSync(path, \"utf8\");\n if (new RegExp(`\\\\b${key}:`).test(source)) {\n print(`${key} already exists in ${path}`);\n return { exitCode: 0, path };\n }\n\n if (!source.includes(\"orderExtensionSchema\")) {\n return { exitCode: 1, path, error: \"orderExtensionSchema not found in extensions.ts\" };\n }\n\n source = source.replace(\n /export const orderExtensionSchema = z\\.object\\(\\{\\n/,\n `export const orderExtensionSchema = z.object({\\n ${key}: ${EXTENSION_TYPES[typeName]},\\n`,\n );\n writeFileSync(path, source);\n print(`added ${key}: ${typeName} to extras_json via ${path}`);\n print(\"orders テーブルを ALTER しないこと。予約列 extras_json だけを使う。\");\n return { exitCode: 0, path };\n}\n","import { readdirSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { upgradeV2toV6 } from \"../../schema/upgrades/v2-to-v6.js\";\nimport type { UpgradeModule } from \"../../schema/upgrades/types.js\";\nimport { currentSchemaVersion, listCoreMigrations } from \"../db/catalog.js\";\nimport { classifyDrift, type DriftFinding } from \"../db/drift.js\";\nimport { introspectSnapshot } from \"../db/introspect.js\";\nimport { TRACKING_TABLES_SQL } from \"../db/schema-version.js\";\nimport { CORE_TABLES, type SchemaSnapshot } from \"../db/snapshot.js\";\nimport { sha256File } from \"./checksum.js\";\nimport type { MigrationExecutor } from \"./executor.js\";\nimport { findPackageRoot } from \"../package-root.js\";\n\nexport const CORE_UPGRADES: UpgradeModule[] = [upgradeV2toV6];\n\nexport type Printer = (message: string) => void;\n\nexport type MigrateOptions = {\n cwd: string;\n executor: MigrationExecutor;\n snapshot: SchemaSnapshot;\n dryRun?: boolean;\n adopt?: boolean;\n repair?: boolean;\n coreVersion: string;\n now?: number;\n print?: Printer;\n};\n\nexport type MigrateResult = {\n exitCode: number;\n applied: string[];\n warnings: string[];\n error?: string;\n bookmark?: string | null;\n};\n\ntype AppliedRow = { name: string; checksum: string; kind: string };\n\nasync function ensureTracking(executor: MigrationExecutor, dryRun: boolean, print: Printer): Promise<void> {\n print(\"ensure umec_schema_version / umec_migrations\");\n if (dryRun) return;\n await executor.applySql(TRACKING_TABLES_SQL);\n}\n\nasync function readApplied(executor: MigrationExecutor): Promise<AppliedRow[]> {\n try {\n return await executor.all<AppliedRow>(\"SELECT name, checksum, kind FROM umec_migrations\");\n } catch {\n return [];\n }\n}\n\nasync function readVersion(executor: MigrationExecutor): Promise<number | null> {\n try {\n const row = await executor.first<{ version: number }>(\n \"SELECT version FROM umec_schema_version WHERE id = 1\",\n );\n return row?.version ?? null;\n } catch {\n return null;\n }\n}\n\nasync function recordMigration(\n executor: MigrationExecutor,\n name: string,\n checksum: string,\n kind: \"sql\" | \"upgrade\",\n now: number,\n): Promise<void> {\n await executor.run(\n `INSERT INTO umec_migrations (name, checksum, kind, applied_at) VALUES (?, ?, ?, ?)\n ON CONFLICT(name) DO UPDATE SET checksum = excluded.checksum, kind = excluded.kind, applied_at = excluded.applied_at`,\n [name, checksum, kind, now],\n );\n}\n\nasync function writeVersion(\n executor: MigrationExecutor,\n version: number,\n coreVersion: string,\n now: number,\n bookmark: string | null,\n): Promise<void> {\n await executor.run(\n `INSERT INTO umec_schema_version (id, version, core_version, applied_at, time_travel_bookmark)\n VALUES (1, ?, ?, ?, ?)\n ON CONFLICT(id) DO UPDATE SET\n version = excluded.version,\n core_version = excluded.core_version,\n applied_at = excluded.applied_at,\n time_travel_bookmark = excluded.time_travel_bookmark`,\n [version, coreVersion, now, bookmark],\n );\n}\n\nfunction listLocalMigrations(cwd: string): { name: string; path: string; sql: string }[] {\n const dir = join(cwd, \"migrations\", \"local\");\n try {\n return readdirSync(dir)\n .filter((name) => name.endsWith(\".sql\"))\n .sort()\n .map((name) => ({\n name: `local/${name}`,\n path: join(dir, name),\n sql: readFileSync(join(dir, name), \"utf8\"),\n }));\n } catch {\n return [];\n }\n}\n\nasync function adoptD1History(\n executor: MigrationExecutor,\n now: number,\n print: Printer,\n): Promise<{ adopted: string[]; warnings: string[] }> {\n const warnings: string[] = [];\n let names: string[] = [];\n try {\n const rows = await executor.all<{ name: string }>(\"SELECT name FROM d1_migrations\");\n names = rows.map((row) => row.name);\n } catch {\n throw new Error(\"d1_migrations が見つかりません。--adopt は wrangler 管理下の既存 D1 向けです。\");\n }\n\n const core = listCoreMigrations();\n const byFile = new Map(core.map((migration) => [migration.name, migration]));\n const adopted: string[] = [];\n const legacy = await upgradeV2toV6.canApply(executor);\n\n for (const rawName of names) {\n const fileName = rawName.split(\"/\").pop() ?? rawName;\n const migration = byFile.get(fileName);\n if (!migration) {\n warnings.push(`d1_migrations の ${rawName} は core に無いのでスキップ`);\n continue;\n }\n const checksum =\n fileName === \"0002_orders.sql\" && legacy\n ? (upgradeV2toV6.replacesChecksums[0] ?? sha256File(migration.path))\n : sha256File(migration.path);\n await recordMigration(executor, migration.name, checksum, \"sql\", now);\n adopted.push(migration.name);\n print(`adopt ${migration.name}`);\n }\n\n return { adopted, warnings };\n}\n\nasync function snapshotFromExecutor(\n executor: MigrationExecutor,\n version: number,\n): Promise<SchemaSnapshot> {\n const db = {\n prepare(query: string) {\n return {\n bind(...values: unknown[]) {\n this._params = values;\n return this;\n },\n _params: [] as unknown[],\n async first<T>() {\n return executor.first<T>(query, this._params);\n },\n async all<T>() {\n const results = await executor.all<T>(query, this._params);\n return { results };\n },\n async run() {\n const result = await executor.run(query, this._params);\n return { meta: { changes: result.changes } };\n },\n };\n },\n async batch() {\n return [];\n },\n };\n return introspectSnapshot(db, version);\n}\n\nexport async function runMigrate(options: MigrateOptions): Promise<MigrateResult> {\n const print = options.print ?? (() => {});\n const dryRun = options.dryRun === true;\n const now = options.now ?? Date.now();\n const applied: string[] = [];\n const warnings: string[] = [];\n const installedVersion = currentSchemaVersion();\n\n try {\n await ensureTracking(options.executor, dryRun, print);\n\n const dbVersion = dryRun ? null : await readVersion(options.executor);\n if (dbVersion != null && dbVersion > installedVersion) {\n return {\n exitCode: 1,\n applied,\n warnings,\n error: `DB は schema v${dbVersion}。インストール中の @umec/core は v${installedVersion} までしか知らない。戻すには wrangler d1 time-travel restore --bookmark=<記録済み> のあと同じ core バージョンを入れ直すこと。down migration は無い。`,\n };\n }\n\n if (options.adopt) {\n print(\"adopt d1_migrations → umec_migrations\");\n if (dryRun) {\n return { exitCode: 0, applied: [\"--adopt\"], warnings };\n }\n const result = await adoptD1History(options.executor, now, print);\n applied.push(...result.adopted);\n warnings.push(...result.warnings);\n const bookmark = await options.executor.captureBookmark();\n const maxAdopted = result.adopted.reduce((max, name) => Math.max(max, Number(name.slice(0, 4)) || 0), 0);\n await writeVersion(options.executor, maxAdopted, options.coreVersion, now, bookmark);\n return { exitCode: 0, applied, warnings, bookmark };\n }\n\n if (!dryRun) {\n const actual = await snapshotFromExecutor(options.executor, options.snapshot.version);\n const fresh = CORE_TABLES.every((table) => !actual.tables[table]);\n if (!fresh) {\n const alreadyForDrift = await readApplied(options.executor);\n const pendingSql = listCoreMigrations()\n .filter((migration) => !alreadyForDrift.some((row) => row.name === migration.name))\n .map((migration) => migration.sql)\n .join(\"\\n\");\n const drift = classifyDrift(options.snapshot, actual);\n for (const finding of drift.compatible) {\n warnings.push(finding.message);\n print(`warn: ${finding.message}`);\n }\n const blocking = drift.incompatible.filter((finding) => !pendingMigrationFixes(pendingSql, finding));\n const repairable = options.repair && (await upgradeV2toV6.canApply(options.executor));\n if (blocking.length > 0 && !repairable) {\n const details = blocking.map((finding) => finding.message).join(\"; \");\n const hint = (await upgradeV2toV6.canApply(options.executor))\n ? \" umec migrate --repair で v2-to-v6 を提案できます。\"\n : \"\";\n return {\n exitCode: 1,\n applied,\n warnings,\n error: `非互換 drift のため migrate を拒否: ${details}.${hint}`,\n };\n }\n }\n }\n\n const already = dryRun ? [] : await readApplied(options.executor);\n const alreadyByName = new Map(already.map((row) => [row.name, row]));\n const coreMigrations = listCoreMigrations();\n\n for (const migration of coreMigrations) {\n const currentHash = sha256File(migration.path);\n const recorded = alreadyByName.get(migration.name);\n if (recorded && recorded.checksum !== currentHash) {\n const knownLegacy = CORE_UPGRADES.some((upgrade) => upgrade.replacesChecksums.includes(recorded.checksum));\n const canRepair = options.repair && knownLegacy && (await upgradeV2toV6.canApply(options.executor));\n if (!canRepair) {\n return {\n exitCode: 1,\n applied,\n warnings,\n error: `公開済み migration ${migration.name} の checksum が食い違っています。in-place 改変は禁止です。${knownLegacy ? \"umec migrate --repair を使ってください。\" : \"\"}`,\n };\n }\n }\n }\n\n let bookmark: string | null = null;\n if (!dryRun) {\n bookmark = await options.executor.captureBookmark();\n print(bookmark ? `time-travel bookmark ${bookmark}` : \"time-travel bookmark unavailable\");\n }\n\n if (options.repair) {\n for (const upgrade of CORE_UPGRADES) {\n const needed = dryRun ? true : await upgrade.canApply(options.executor);\n if (!needed) continue;\n print(`upgrade ${upgrade.name} (${upgrade.fromVersion} → ${upgrade.toVersion})`);\n if (dryRun) {\n applied.push(upgrade.name);\n continue;\n }\n await upgrade.apply(options.executor);\n await recordMigration(options.executor, upgrade.name, `upgrade:${upgrade.name}`, \"upgrade\", now);\n applied.push(upgrade.name);\n const ordersMigration = coreMigrations.find((migration) => migration.name === \"0002_orders.sql\");\n if (ordersMigration) {\n await recordMigration(options.executor, ordersMigration.name, sha256File(ordersMigration.path), \"sql\", now);\n }\n }\n }\n\n for (const migration of coreMigrations) {\n if (alreadyByName.get(migration.name)?.checksum === sha256File(migration.path)) continue;\n if (alreadyByName.has(migration.name) && !options.repair) continue;\n print(`apply core/${migration.name}`);\n if (dryRun) {\n applied.push(migration.name);\n continue;\n }\n await options.executor.applySql(migration.sql);\n await recordMigration(options.executor, migration.name, sha256File(migration.path), \"sql\", now);\n applied.push(migration.name);\n }\n\n for (const local of listLocalMigrations(options.cwd)) {\n const hash = sha256File(local.path);\n if (alreadyByName.get(local.name)?.checksum === hash) continue;\n print(`apply ${local.name}`);\n if (dryRun) {\n applied.push(local.name);\n continue;\n }\n await options.executor.applySql(local.sql);\n await recordMigration(options.executor, local.name, hash, \"sql\", now);\n applied.push(local.name);\n }\n\n if (!dryRun) {\n await writeVersion(options.executor, installedVersion, options.coreVersion, now, bookmark);\n } else {\n print(`would set umec_schema_version.version = ${installedVersion}`);\n }\n\n return { exitCode: 0, applied, warnings, bookmark };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return { exitCode: 1, applied, warnings, error: message };\n }\n}\n\nfunction pendingMigrationFixes(pendingSql: string, finding: DriftFinding): boolean {\n if (finding.message.includes(`required table \"${finding.table}\" is missing`)) {\n return new RegExp(`CREATE TABLE(?: IF NOT EXISTS)?\\\\s+${finding.table}\\\\b`, \"i\").test(pendingSql);\n }\n const missingColumn = finding.message.match(/required column \"[^.\"]+\\.([^\"]+)\" is missing/);\n if (missingColumn?.[1]) {\n return new RegExp(`ADD COLUMN\\\\s+${missingColumn[1]}\\\\b`, \"i\").test(pendingSql);\n }\n return false;\n}\n\nexport function coreVersionFromPackage(root = findPackageRoot()): string {\n const pkg = JSON.parse(readFileSync(join(root, \"package.json\"), \"utf8\")) as { version: string };\n return pkg.version;\n}\n","import { spawn } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { bindSql, type MigrationExecutor } from \"./executor.js\";\n\nexport type WranglerRunResult = {\n code: number;\n stdout: string;\n stderr: string;\n};\n\nexport type RunCommand = (command: string, args: string[], cwd: string) => Promise<WranglerRunResult>;\n\nexport function defaultRunCommand(command: string, args: string[], cwd: string): Promise<WranglerRunResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(command, args, { cwd, stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n let stdout = \"\";\n let stderr = \"\";\n child.stdout.on(\"data\", (chunk: Buffer) => {\n stdout += chunk.toString();\n });\n child.stderr.on(\"data\", (chunk: Buffer) => {\n stderr += chunk.toString();\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n resolve({ code: code ?? 1, stdout, stderr });\n });\n });\n}\n\nexport function parseJsonc(text: string): unknown {\n const stripped = text.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\").replace(/^\\s*\\/\\/.*$/gm, \"\");\n return JSON.parse(stripped);\n}\n\nexport function readD1DatabaseName(cwd: string, override?: string): string | null {\n if (override) return override;\n const path = join(cwd, \"wrangler.jsonc\");\n try {\n const parsed = parseJsonc(readFileSync(path, \"utf8\")) as {\n d1_databases?: Array<{ database_name?: string }>;\n };\n return parsed.d1_databases?.[0]?.database_name ?? null;\n } catch {\n return null;\n }\n}\n\nfunction parseExecuteJson(stdout: string): { results: unknown[]; changes: number } {\n const trimmed = stdout.trim();\n if (!trimmed) return { results: [], changes: 0 };\n const start = trimmed.indexOf(\"[\");\n const objStart = trimmed.indexOf(\"{\");\n const cut =\n start >= 0 && (objStart < 0 || start < objStart)\n ? trimmed.slice(start)\n : objStart >= 0\n ? trimmed.slice(objStart)\n : trimmed;\n const parsed: unknown = JSON.parse(cut);\n const rows = Array.isArray(parsed) ? parsed : [parsed];\n const first = rows[0] as { results?: unknown[]; meta?: { changes?: number } } | undefined;\n return {\n results: first?.results ?? [],\n changes: first?.meta?.changes ?? 0,\n };\n}\n\nexport function createWranglerExecutor(options: {\n cwd: string;\n database: string;\n remote: boolean;\n runCommand?: RunCommand;\n}): MigrationExecutor {\n const runCommand = options.runCommand ?? defaultRunCommand;\n const location = options.remote ? \"--remote\" : \"--local\";\n\n const execute = async (sql: string) => {\n const result = await runCommand(\n \"wrangler\",\n [\"d1\", \"execute\", options.database, location, \"--json\", \"--command\", sql],\n options.cwd,\n );\n if (result.code !== 0) {\n throw new Error(result.stderr || result.stdout || `wrangler d1 execute failed (${result.code})`);\n }\n return parseExecuteJson(result.stdout);\n };\n\n return {\n async exec(sql: string) {\n await execute(sql);\n },\n async applySql(sql: string) {\n const { splitSqlStatements } = await import(\"../db/sql.js\");\n for (const statement of splitSqlStatements(sql)) {\n await execute(statement);\n }\n },\n async all<T>(sql: string, params: unknown[] = []) {\n const result = await execute(bindSql(sql, params));\n return result.results as T[];\n },\n async first<T>(sql: string, params: unknown[] = []) {\n const result = await execute(bindSql(sql, params));\n return (result.results[0] as T | undefined) ?? null;\n },\n async run(sql: string, params: unknown[] = []) {\n const result = await execute(bindSql(sql, params));\n return { changes: result.changes };\n },\n async captureBookmark() {\n const result = await runCommand(\n \"wrangler\",\n [\"d1\", \"time-travel\", \"info\", options.database, \"--json\"],\n options.cwd,\n );\n if (result.code !== 0) return null;\n try {\n const parsed = JSON.parse(result.stdout) as { bookmark?: string };\n return parsed.bookmark ?? null;\n } catch {\n return null;\n }\n },\n };\n}\n","import type { UpgradeExecutor } from \"../../schema/upgrades/types.js\";\nimport type { ShopDatabase } from \"../db/d1.js\";\nimport { splitSqlStatements } from \"../db/sql.js\";\n\nexport type MigrationExecutor = UpgradeExecutor & {\n applySql(sql: string): Promise<void>;\n captureBookmark(): Promise<string | null>;\n};\n\nexport function sqlLiteral(value: unknown): string {\n if (value === null || value === undefined) return \"NULL\";\n if (typeof value === \"boolean\") return value ? \"1\" : \"0\";\n if (typeof value === \"number\" && Number.isFinite(value)) return String(value);\n if (typeof value === \"string\") return `'${value.replaceAll(\"'\", \"''\")}'`;\n throw new Error(`Unsupported SQL bind: ${typeof value}`);\n}\n\nexport function bindSql(sql: string, params: unknown[] = []): string {\n let index = 0;\n return sql.replaceAll(\"?\", () => {\n if (index >= params.length) throw new Error(\"Not enough SQL bind parameters\");\n return sqlLiteral(params[index++]);\n });\n}\n\nexport function executorFromDatabase(\n db: ShopDatabase,\n captureBookmark: () => Promise<string | null> = async () => null,\n): MigrationExecutor {\n return {\n async exec(sql: string) {\n await db.prepare(sql).run();\n },\n async applySql(sql: string) {\n for (const statement of splitSqlStatements(sql)) {\n await db.prepare(statement).run();\n }\n },\n async all<T>(sql: string, params: unknown[] = []) {\n const statement = db.prepare(sql);\n if (params.length > 0) statement.bind(...params);\n const result = await statement.all<T>();\n return result.results ?? [];\n },\n async first<T>(sql: string, params: unknown[] = []) {\n const statement = db.prepare(sql);\n if (params.length > 0) statement.bind(...params);\n return statement.first<T>();\n },\n async run(sql: string, params: unknown[] = []) {\n const statement = db.prepare(sql);\n if (params.length > 0) statement.bind(...params);\n const result = await statement.run();\n return { changes: result.meta.changes };\n },\n captureBookmark,\n };\n}\n"],"mappings":"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","names":["readFileSync","join","existsSync","readFileSync","join","readFileSync","join","join","readFileSync","bookmark","readFileSync","join","join","readFileSync","splitSqlStatements","join","readFileSync"]}
@@ -0,0 +1,130 @@
1
+ import { a as ShopDatabase, A as AdminAuditLogRow, P as ProductsRow } from '../orders-DRZvcL3s.js';
2
+ export { C as Carrier, I as InventoryRow, M as MarkShippedResult, O as OrdersRow, b as ProcessedEventsRow, S as SNAPSHOT_SCHEMA_VERSION, c as ShopStatement, U as UnshippedOrder, d as UpdateTrackingResult, g as getOrder, l as listUnshipped, m as markShipped, r as recordEmailResult, e as recordExpiry, f as recordOrder, h as recordRefund, u as updateTracking } from '../orders-DRZvcL3s.js';
3
+ import { z } from 'zod';
4
+ export { A as AppliedMigrationRow, S as SchemaVersionError, b as SchemaVersionRow, T as TRACKING_TABLES_SQL, a as assertSchemaCompatible, l as listAppliedMigrations, r as readSchemaVersion } from '../schema-version-F-YYC1UG.js';
5
+ import '../webhook.js';
6
+ import 'stripe';
7
+
8
+ type AuditEntityType = "inventory" | "product" | "order";
9
+ type AuditActor = "human" | "system" | "agent";
10
+ type AdminAuditEntry = {
11
+ entityType: AuditEntityType;
12
+ entityId: string;
13
+ action: string;
14
+ delta?: number | null;
15
+ reason?: string | null;
16
+ adminEmail?: string | null;
17
+ actor?: AuditActor;
18
+ detail?: unknown;
19
+ };
20
+ declare function writeAuditLog(db: ShopDatabase, entry: AdminAuditEntry, createdAt?: number): Promise<void>;
21
+ declare function listAuditLog(db: ShopDatabase, options?: {
22
+ entityType?: AuditEntityType;
23
+ entityId?: string;
24
+ limit?: number;
25
+ }): Promise<AdminAuditLogRow[]>;
26
+
27
+ type CoreMigration = {
28
+ name: string;
29
+ version: number;
30
+ path: string;
31
+ sql: string;
32
+ };
33
+ declare function listCoreMigrations(root?: string): CoreMigration[];
34
+ declare function currentSchemaVersion(root?: string): number;
35
+ declare function loadSnapshotJson(root?: string): unknown;
36
+
37
+ type SnapshotColumn = {
38
+ cid: number;
39
+ name: string;
40
+ type: string;
41
+ notnull: number;
42
+ dflt_value: string | null;
43
+ pk: number;
44
+ };
45
+ type SnapshotIndex = {
46
+ name: string;
47
+ unique: number;
48
+ origin: string;
49
+ columns: string[];
50
+ };
51
+ type SnapshotForeignKey = {
52
+ id: number;
53
+ table: string;
54
+ from: string;
55
+ to: string;
56
+ on_update: string;
57
+ on_delete: string;
58
+ };
59
+ type SnapshotTable = {
60
+ name: string;
61
+ sql: string | null;
62
+ columns: SnapshotColumn[];
63
+ indexes: SnapshotIndex[];
64
+ foreignKeys: SnapshotForeignKey[];
65
+ };
66
+ type SchemaSnapshot = {
67
+ version: number;
68
+ tables: Record<string, SnapshotTable>;
69
+ };
70
+ declare const CORE_TABLES: readonly ["processed_events", "orders", "inventory", "admin_audit_log", "products"];
71
+
72
+ type DriftKind = "compatible" | "incompatible";
73
+ type DriftFinding = {
74
+ kind: DriftKind;
75
+ table: string;
76
+ message: string;
77
+ };
78
+ type DriftReport = {
79
+ compatible: DriftFinding[];
80
+ incompatible: DriftFinding[];
81
+ };
82
+ declare function classifyDrift(expected: SchemaSnapshot, actual: SchemaSnapshot): DriftReport;
83
+
84
+ declare function claimEvent(db: ShopDatabase, eventId: string, now?: number): Promise<boolean>;
85
+
86
+ declare function parseExtras<S extends z.ZodType>(schema: S, extrasJson: string | null): z.infer<S> | null;
87
+ declare function serializeExtras<S extends z.ZodType>(schema: S, value: unknown): string;
88
+
89
+ type InventoryItem = {
90
+ sku: string;
91
+ quantity: number;
92
+ };
93
+ declare const MAX_STOCK_DELTA = 10000;
94
+ type AdjustStockResult = "ok" | "not_found" | "insufficient";
95
+ type SetStockResult = "ok" | "not_found";
96
+ declare function getStock(db: ShopDatabase, skus: string[]): Promise<Map<string, number>>;
97
+ declare function decrementStock(db: ShopDatabase, items: InventoryItem[]): Promise<void>;
98
+ declare function restoreStock(db: ShopDatabase, items: InventoryItem[]): Promise<void>;
99
+ declare function setStock(db: ShopDatabase, sku: string, stock: number, updatedAt?: number): Promise<SetStockResult>;
100
+ declare function adjustStock(db: ShopDatabase, sku: string, delta: number): Promise<AdjustStockResult>;
101
+
102
+ declare function introspectSnapshot(db: ShopDatabase, version: number, tableNames?: readonly string[]): Promise<SchemaSnapshot>;
103
+
104
+ type ProductWriteFields = {
105
+ name: string;
106
+ description: string | null;
107
+ price: number;
108
+ shippingUnits: number;
109
+ images: string[];
110
+ gtin: string | null;
111
+ category: string | null;
112
+ active: 0 | 1;
113
+ lowStockThreshold: number | null;
114
+ };
115
+ type CreateProductResult = "ok" | "conflict";
116
+ type UpdateProductResult = "ok" | "not_found";
117
+ type DiscontinueProductResult = "ok" | "not_found" | "already_inactive";
118
+ declare function listProductRows(db: ShopDatabase, options?: {
119
+ includeInactive?: boolean;
120
+ }): Promise<ProductsRow[]>;
121
+ declare function getProductRow(db: ShopDatabase, sku: string): Promise<ProductsRow | null>;
122
+ declare function createProduct(db: ShopDatabase, sku: string, fields: ProductWriteFields, updatedBy: string | null, now?: number): Promise<CreateProductResult>;
123
+ declare function updateProduct(db: ShopDatabase, sku: string, fields: Partial<ProductWriteFields>, updatedBy: string | null, now?: number): Promise<{
124
+ result: UpdateProductResult;
125
+ before: ProductsRow | null;
126
+ after: ProductsRow | null;
127
+ }>;
128
+ declare function discontinueProduct(db: ShopDatabase, sku: string, updatedBy: string | null, now?: number): Promise<DiscontinueProductResult>;
129
+
130
+ export { type AdjustStockResult, type AdminAuditEntry, AdminAuditLogRow, type AuditActor, type AuditEntityType, CORE_TABLES, type CoreMigration, type CreateProductResult, type DiscontinueProductResult, type DriftFinding, type DriftKind, type DriftReport, type InventoryItem, MAX_STOCK_DELTA, type ProductWriteFields, ProductsRow, type SchemaSnapshot, type SetStockResult, ShopDatabase, type SnapshotColumn, type SnapshotForeignKey, type SnapshotIndex, type SnapshotTable, type UpdateProductResult, adjustStock, claimEvent, classifyDrift, createProduct, currentSchemaVersion, decrementStock, discontinueProduct, getProductRow, getStock, introspectSnapshot, listAuditLog, listCoreMigrations, listProductRows, loadSnapshotJson, parseExtras, restoreStock, serializeExtras, setStock, updateProduct, writeAuditLog };
@@ -0,0 +1,81 @@
1
+ import {
2
+ MAX_STOCK_DELTA,
3
+ SNAPSHOT_SCHEMA_VERSION,
4
+ adjustStock,
5
+ claimEvent,
6
+ createProduct,
7
+ decrementStock,
8
+ discontinueProduct,
9
+ getOrder,
10
+ getProductRow,
11
+ getStock,
12
+ listAuditLog,
13
+ listProductRows,
14
+ listUnshipped,
15
+ markShipped,
16
+ parseExtras,
17
+ recordEmailResult,
18
+ recordExpiry,
19
+ recordOrder,
20
+ recordRefund,
21
+ restoreStock,
22
+ serializeExtras,
23
+ setStock,
24
+ updateProduct,
25
+ updateTracking,
26
+ writeAuditLog
27
+ } from "../chunk-DN3J2NQC.js";
28
+ import {
29
+ CORE_TABLES,
30
+ SchemaVersionError,
31
+ TRACKING_TABLES_SQL,
32
+ assertSchemaCompatible,
33
+ classifyDrift,
34
+ introspectSnapshot,
35
+ listAppliedMigrations,
36
+ readSchemaVersion
37
+ } from "../chunk-PNICEHSO.js";
38
+ import {
39
+ currentSchemaVersion,
40
+ listCoreMigrations,
41
+ loadSnapshotJson
42
+ } from "../chunk-T2PO3YLZ.js";
43
+ export {
44
+ CORE_TABLES,
45
+ MAX_STOCK_DELTA,
46
+ SNAPSHOT_SCHEMA_VERSION,
47
+ SchemaVersionError,
48
+ TRACKING_TABLES_SQL,
49
+ adjustStock,
50
+ assertSchemaCompatible,
51
+ claimEvent,
52
+ classifyDrift,
53
+ createProduct,
54
+ currentSchemaVersion,
55
+ decrementStock,
56
+ discontinueProduct,
57
+ getOrder,
58
+ getProductRow,
59
+ getStock,
60
+ introspectSnapshot,
61
+ listAppliedMigrations,
62
+ listAuditLog,
63
+ listCoreMigrations,
64
+ listProductRows,
65
+ listUnshipped,
66
+ loadSnapshotJson,
67
+ markShipped,
68
+ parseExtras,
69
+ readSchemaVersion,
70
+ recordEmailResult,
71
+ recordExpiry,
72
+ recordOrder,
73
+ recordRefund,
74
+ restoreStock,
75
+ serializeExtras,
76
+ setStock,
77
+ updateProduct,
78
+ updateTracking,
79
+ writeAuditLog
80
+ };
81
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/index.d.ts CHANGED
@@ -6,6 +6,8 @@ export { UmecLimitedPage, UmecMiddleware, UmecMiddlewareContext, UmecMiddlewareN
6
6
  export { NotifyEnv, NotifyProduct, NotifyProductsMap, NotifyUnshippedOptions, UnshippedOrder, notifyUnshipped } from './notify.js';
7
7
  export { SubscribeHandler, SubscribeHandlerOptions, createSubscribeHandler } from './subscribe.js';
8
8
  export { OrderEmailData, OrderEmailLineItem, RenderOrderEmail, SupportedWebhookEvent, WebhookEmailResult, WebhookHandler, WebhookHandlerOptions, WebhookItem, WebhookOrder, WebhookRecordedOrder, createWebhookHandler, GET as webhookGET } from './webhook.js';
9
+ export { S as SNAPSHOT_SCHEMA_VERSION } from './orders-DRZvcL3s.js';
10
+ export { S as SchemaVersionError, a as assertSchemaCompatible } from './schema-version-F-YYC1UG.js';
9
11
  import 'jose';
10
12
  import 'stripe';
11
13
  import 'zod';
package/dist/index.js CHANGED
@@ -2,6 +2,14 @@ import {
2
2
  GET,
3
3
  createWebhookHandler
4
4
  } from "./chunk-ZP7IGPJW.js";
5
+ import {
6
+ SNAPSHOT_SCHEMA_VERSION
7
+ } from "./chunk-DN3J2NQC.js";
8
+ import {
9
+ SchemaVersionError,
10
+ assertSchemaCompatible
11
+ } from "./chunk-PNICEHSO.js";
12
+ import "./chunk-T2PO3YLZ.js";
5
13
  import {
6
14
  createAccessGuard
7
15
  } from "./chunk-2SNGXEIL.js";
@@ -18,7 +26,7 @@ import {
18
26
  } from "./chunk-4V4GYE7E.js";
19
27
  import {
20
28
  notifyUnshipped
21
- } from "./chunk-JWTXQAOL.js";
29
+ } from "./chunk-RFEX32LI.js";
22
30
  import {
23
31
  createSubscribeHandler
24
32
  } from "./chunk-X2SNVVFW.js";
@@ -26,6 +34,9 @@ import {
26
34
  getServerEnv
27
35
  } from "./chunk-7TJANK6S.js";
28
36
  export {
37
+ SNAPSHOT_SCHEMA_VERSION,
38
+ SchemaVersionError,
39
+ assertSchemaCompatible,
29
40
  createAccessGuard,
30
41
  createCheckoutHandler,
31
42
  createSubscribeHandler,
package/dist/notify.d.ts CHANGED
@@ -1,10 +1,8 @@
1
- type UnshippedOrder = {
2
- id: string;
3
- name: string | null;
4
- items_json: string | null;
5
- amount: number | null;
6
- created_at: number | string | null;
7
- };
1
+ import { U as UnshippedOrder$1 } from './orders-DRZvcL3s.js';
2
+ import './webhook.js';
3
+ import 'stripe';
4
+
5
+ type UnshippedOrder = UnshippedOrder$1;
8
6
  type NotifyEnv = {
9
7
  DISCORD_WEBHOOK_URL?: string;
10
8
  RESEND_API_KEY?: string;
package/dist/notify.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  notifyUnshipped
3
- } from "./chunk-JWTXQAOL.js";
3
+ } from "./chunk-RFEX32LI.js";
4
4
  export {
5
5
  notifyUnshipped
6
6
  };
@@ -0,0 +1,99 @@
1
+ import { WebhookRecordedOrder, WebhookOrder } from './webhook.js';
2
+
3
+ type ShopStatement = {
4
+ bind(...values: unknown[]): ShopStatement;
5
+ first<T = Record<string, unknown>>(): Promise<T | null>;
6
+ run(): Promise<{
7
+ meta: {
8
+ changes: number;
9
+ };
10
+ }>;
11
+ all<T = Record<string, unknown>>(): Promise<{
12
+ results: T[];
13
+ }>;
14
+ };
15
+ type ShopDatabase = {
16
+ prepare(query: string): ShopStatement;
17
+ batch(statements: ShopStatement[]): Promise<{
18
+ meta: {
19
+ changes: number;
20
+ };
21
+ }[]>;
22
+ };
23
+
24
+ declare const SNAPSHOT_SCHEMA_VERSION: 7;
25
+ type AdminAuditLogRow = {
26
+ id: number;
27
+ entity_type: string;
28
+ entity_id: string;
29
+ action: string;
30
+ delta: number | null;
31
+ reason: string | null;
32
+ admin_email: string | null;
33
+ actor: string;
34
+ detail_json: string | null;
35
+ created_at: number;
36
+ };
37
+ type InventoryRow = {
38
+ sku: string;
39
+ stock: number;
40
+ updated_at: number;
41
+ };
42
+ type OrdersRow = {
43
+ id: string;
44
+ email: string;
45
+ name: string | null;
46
+ phone: string | null;
47
+ items_json: string;
48
+ amount: number;
49
+ shipping: number | null;
50
+ address_json: string | null;
51
+ payment_intent: string | null;
52
+ custom_fields_json: string | null;
53
+ status: string;
54
+ run_id: string | null;
55
+ email_status: string | null;
56
+ created_at: number;
57
+ shipped_at: number | null;
58
+ tracking_number: string | null;
59
+ carrier: string | null;
60
+ extras_json: string | null;
61
+ };
62
+ type ProcessedEventsRow = {
63
+ event_id: string;
64
+ processed_at: number;
65
+ };
66
+ type ProductsRow = {
67
+ sku: string;
68
+ name: string;
69
+ description: string | null;
70
+ price: number;
71
+ shipping_units: number;
72
+ images_json: string | null;
73
+ gtin: string | null;
74
+ category: string | null;
75
+ active: number;
76
+ low_stock_threshold: number | null;
77
+ created_at: number;
78
+ updated_at: number;
79
+ updated_by: string | null;
80
+ };
81
+
82
+ type UnshippedOrder = Pick<OrdersRow, "id" | "name" | "items_json" | "amount" | "created_at">;
83
+ type Carrier = "yamato" | "sagawa" | "japanpost" | "other";
84
+ type MarkShippedResult = "ok" | "not_pending";
85
+ type UpdateTrackingResult = "ok" | "not_found";
86
+ declare function recordOrder(db: ShopDatabase, order: WebhookOrder, extrasJson?: string | null): Promise<void>;
87
+ declare function recordRefund(db: ShopDatabase, paymentIntentId: string): Promise<WebhookRecordedOrder | null>;
88
+ declare function recordExpiry(db: ShopDatabase, sessionId: string): Promise<WebhookRecordedOrder | null>;
89
+ declare function recordEmailResult(db: ShopDatabase, sessionId: string, status: "sent" | "failed"): Promise<void>;
90
+ declare function listUnshipped(db: ShopDatabase, cutoff: number): Promise<UnshippedOrder[]>;
91
+ declare function getOrder(db: ShopDatabase, id: string): Promise<Pick<OrdersRow, "id" | "status" | "tracking_number" | "carrier"> | null>;
92
+ declare function markShipped(db: ShopDatabase, id: string, options?: {
93
+ trackingNumber?: string | null;
94
+ carrier?: Carrier | null;
95
+ shippedAt?: number;
96
+ }): Promise<MarkShippedResult>;
97
+ declare function updateTracking(db: ShopDatabase, id: string, trackingNumber: string, carrier: string | null): Promise<UpdateTrackingResult>;
98
+
99
+ export { type AdminAuditLogRow as A, type Carrier as C, type InventoryRow as I, type MarkShippedResult as M, type OrdersRow as O, type ProductsRow as P, SNAPSHOT_SCHEMA_VERSION as S, type UnshippedOrder as U, type ShopDatabase as a, type ProcessedEventsRow as b, type ShopStatement as c, type UpdateTrackingResult as d, recordExpiry as e, recordOrder as f, getOrder as g, recordRefund as h, listUnshipped as l, markShipped as m, recordEmailResult as r, updateTracking as u };
@@ -0,0 +1,25 @@
1
+ import { a as ShopDatabase } from './orders-DRZvcL3s.js';
2
+
3
+ declare const TRACKING_TABLES_SQL = "\nCREATE TABLE IF NOT EXISTS umec_schema_version (\n id INTEGER PRIMARY KEY CHECK (id = 1),\n version INTEGER NOT NULL,\n core_version TEXT NOT NULL,\n applied_at INTEGER NOT NULL,\n time_travel_bookmark TEXT\n);\n\nCREATE TABLE IF NOT EXISTS umec_migrations (\n name TEXT PRIMARY KEY,\n checksum TEXT NOT NULL,\n kind TEXT NOT NULL CHECK (kind IN ('sql', 'upgrade')),\n applied_at INTEGER NOT NULL\n);\n";
4
+ type SchemaVersionRow = {
5
+ version: number;
6
+ core_version: string;
7
+ applied_at: number;
8
+ time_travel_bookmark: string | null;
9
+ };
10
+ type AppliedMigrationRow = {
11
+ name: string;
12
+ checksum: string;
13
+ kind: "sql" | "upgrade";
14
+ applied_at: number;
15
+ };
16
+ declare class SchemaVersionError extends Error {
17
+ readonly dbVersion: number;
18
+ readonly installedVersion: number;
19
+ constructor(dbVersion: number, installedVersion: number);
20
+ }
21
+ declare function readSchemaVersion(db: ShopDatabase): Promise<SchemaVersionRow | null>;
22
+ declare function listAppliedMigrations(db: ShopDatabase): Promise<AppliedMigrationRow[]>;
23
+ declare function assertSchemaCompatible(db: ShopDatabase, installedVersion?: number): Promise<void>;
24
+
25
+ export { type AppliedMigrationRow as A, SchemaVersionError as S, TRACKING_TABLES_SQL as T, assertSchemaCompatible as a, type SchemaVersionRow as b, listAppliedMigrations as l, readSchemaVersion as r };
@@ -0,0 +1,7 @@
1
+ import {
2
+ splitSqlStatements
3
+ } from "./chunk-CYKUAS3D.js";
4
+ export {
5
+ splitSqlStatements
6
+ };
7
+ //# sourceMappingURL=sql-J4YBS7N7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umec/core",
3
- "version": "0.1.0-alpha.8",
3
+ "version": "0.1.0-alpha.9",
4
4
  "description": "Headless EC logic for umec — config schema and shared handlers",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -51,10 +51,18 @@
51
51
  "./webhook": {
52
52
  "types": "./dist/webhook.d.ts",
53
53
  "import": "./dist/webhook.js"
54
+ },
55
+ "./db": {
56
+ "types": "./dist/db/index.d.ts",
57
+ "import": "./dist/db/index.js"
54
58
  }
55
59
  },
60
+ "bin": {
61
+ "umec": "./dist/cli.js"
62
+ },
56
63
  "files": [
57
- "dist"
64
+ "dist",
65
+ "schema"
58
66
  ],
59
67
  "scripts": {
60
68
  "build": "tsup",
@@ -0,0 +1,11 @@
1
+ {
2
+ "schema/migrations/0001_processed_events.sql": "a5f525d69fb9591d0bbe0701fa28e4e3c11316ec60edcf3970d0b947ccef1bb9",
3
+ "schema/migrations/0002_orders.sql": "4d6e8fb3ee46e9afc3b47a9312ffe9ad1cf20e36eed51055d4c073e2ae85afd5",
4
+ "schema/migrations/0003_inventory.sql": "9ec36f50c9d3514cd2a1607c58f05065b8d5ff89ff9ce3eb92e20f1895ddebf1",
5
+ "schema/migrations/0004_admin_audit_log.sql": "04f4afbe91b484afb2239691ea2eb42cd2c01cb5b9881de29bdc0020cf259c3f",
6
+ "schema/migrations/0005_orders_tracking.sql": "22a0707ac907f31341dbca5347d803f1668f0e5630c9b94f7644ddad5211757b",
7
+ "schema/migrations/0006_products.sql": "f5710befe27d0324bcb1adb4537f9b53ef69dfa9407ce271dd13b2fb972b4452",
8
+ "schema/migrations/0007_orders_extras.sql": "6dd00e5b3b4e554a89c4b5dc5cc6d46b77d681de57e36521c2e4449ba1ba1c60",
9
+ "schema/upgrades/v2-to-v6.ts": "419704d04f583133be5b8b0d45a674619d1bdf60f9077614effa306862ba0e2f",
10
+ "schema/upgrades/types.ts": "0e45a9037c5e957eadb4b9ff66034e77be64a475eb18ca69b59a554d87070c54"
11
+ }
@@ -0,0 +1,4 @@
1
+ CREATE TABLE IF NOT EXISTS processed_events (
2
+ event_id TEXT PRIMARY KEY,
3
+ processed_at INTEGER NOT NULL
4
+ );
@@ -0,0 +1,19 @@
1
+ CREATE TABLE IF NOT EXISTS orders (
2
+ id TEXT PRIMARY KEY,
3
+ email TEXT NOT NULL,
4
+ name TEXT,
5
+ phone TEXT,
6
+ items_json TEXT NOT NULL,
7
+ amount INTEGER NOT NULL,
8
+ shipping INTEGER,
9
+ address_json TEXT,
10
+ payment_intent TEXT,
11
+ custom_fields_json TEXT,
12
+ status TEXT NOT NULL DEFAULT 'pending',
13
+ run_id TEXT,
14
+ email_status TEXT CHECK (email_status IN ('sent', 'failed')),
15
+ created_at INTEGER NOT NULL,
16
+ shipped_at INTEGER
17
+ );
18
+
19
+ CREATE INDEX IF NOT EXISTS orders_payment_intent_idx ON orders(payment_intent);
@@ -0,0 +1,5 @@
1
+ CREATE TABLE IF NOT EXISTS inventory (
2
+ sku TEXT PRIMARY KEY,
3
+ stock INTEGER NOT NULL DEFAULT 0,
4
+ updated_at INTEGER NOT NULL
5
+ );