{"version":3,"sources":["../src/backend/missing-peer-ledger.ts"],"names":["ConfigurationError"],"mappings":";;;;;AA4BO,IAAM,oBAAA,GAAuB,aAAA;AAG7B,IAAM,4BAAA,GAA+B,yBAAA;AAyH5C,IAAM,0BAAA,uBAAsD,GAAA,CAAI;AAAA,EAC9D,sBAAA;AAAA,EACA;AACF,CAAC,CAAA;AAQD,IAAM,yBAAA,GAA4B,0CAAA;AAGlC,IAAM,6BAAA,GAAgC,oBAAA;AAGtC,SAAS,SAAS,KAAA,EAA4D;AAC5E,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA;AAChD;AASO,SAAS,0BAA0B,KAAA,EAAyB;AACjE,EAAA,IAAI,CAAC,QAAA,CAAS,KAAK,CAAA,EAAG,OAAO,KAAA;AAE7B,EAAA,MAAM,IAAA,GAAO,MAAM,MAAM,CAAA;AACzB,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,0BAAA,CAA2B,GAAA,CAAI,IAAI,CAAA,EAAG;AACrE,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAU,MAAM,SAAS,CAAA;AAC/B,EAAA,IAAI,OAAO,OAAA,KAAY,QAAA,EAAU,OAAO,KAAA;AAExC,EAAA,MAAM,SAAA,GAAY,yBAAA,CAA0B,IAAA,CAAK,OAAO,IAAI,CAAC,CAAA;AAC7D,EAAA,IAAI,SAAA,KAAc,QAAW,OAAO,KAAA;AAEpC,EAAA,OAAO,6BAAA,CAA8B,KAAK,SAAS,CAAA;AACrD;AAaA,SAAS,uBAAA,CACP,YACA,KAAA,EACoB;AACpB,EAAA,MAAM,gBAAA,GAAmB,CAAA,mBAAA,EAAsB,UAAA,CAAW,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAClE,EAAA,MAAM,UAAA,GAAa,SAAS,4BAA4B,CAAA,GAAA,CAAA;AACxD,EAAA,OAAO,IAAIA,oCAAA;AAAA,IACT,CAAA,EAAG,gBAAgB,CAAA,wCAAA,EAA2C,oBAAoB,8BAA8B,UAAU,CAAA,CAAA;AAAA,IAC1H;AAAA,MACE,IAAA,EAAM,yBAAA;AAAA,MACN,OAAA,EAAS,oBAAA;AAAA,MACT;AAAA,KACF;AAAA,IACA,EAAE,OAAO,UAAA;AAAW,GACtB;AACF;AAaA,eAAsB,uBAAA,CACpB,YACA,IAAA,EACY;AACZ,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,IAAA,EAAK;AAAA,EACpB,SAAS,KAAA,EAAO;AACd,IAAA,IAAI,yBAAA,CAA0B,KAAK,CAAA,EAAG;AACpC,MAAA,MAAM,uBAAA,CAAwB,YAAY,KAAK,CAAA;AAAA,IACjD;AACA,IAAA,MAAM,KAAA;AAAA,EACR;AACF","file":"chunk-MUKIEXH5.cjs","sourcesContent":["/**\n * The missing-peer ledger and typed refusal for `drizzle-orm`, an optional\n * peer dependency (design §4.4b, ruling OQ1).\n *\n * Two published entrypoints (`./sqlite/local`, `./postgres/pglite`)\n * construct their Drizzle connection internally, behind a dynamic import —\n * they are the only entrypoints a consumer can reach WITHOUT themselves\n * importing `drizzle-orm` first, and therefore the only ones that can turn\n * \"drizzle-orm is not installed\" into a typed, actionable error instead of a\n * bare module-resolution stack. The seven explicit `./adapters/drizzle/*`\n * entrypoints expose Drizzle-native backends, connections, or schema builders\n * — `./adapters/drizzle/engine`'s `createSqlBackend` included, whose module\n * tree reaches `drizzle-orm` through the shared member modules it assembles\n * a backend from — and load `drizzle-orm` when their module is evaluated.\n * Their raw resolution failure is an accepted, documented exemption (ruling\n * r3-OQ2), not a mechanism this module builds.\n *\n * {@link isMissingDrizzlePeerError} is the single narrow both factories call\n * (through {@link loadDrizzleBackedModule}), so the decision is spelled\n * exactly once. It narrows on the FAILING SPECIFIER captured out of the\n * message, never on the whole message text: the ESM message also names the\n * importer's own path (`… imported from …/node_modules/drizzle-orm/bs3.js`),\n * and a whole-message regex would launder a genuinely missing dependency OF\n * `drizzle-orm` into a false \"install drizzle-orm\" instruction.\n */\nimport { ConfigurationError } from \"../errors\";\n\n/** The optional peer dependency the typed refusal names. */\nexport const MISSING_PEER_PACKAGE = \"drizzle-orm\";\n\n/** The install command the typed refusal's message and suggestion carry. */\nexport const MISSING_PEER_INSTALL_COMMAND = \"npm install drizzle-orm\";\n\n/**\n * One published, non-portable entrypoint's disposition when `drizzle-orm` is\n * absent — a discriminated union on `arm`, not a shape with optional fields:\n * a `typed-refusal` row cannot carry (and a `documented-resolution-error`\n * row cannot omit) `reason`/`documentedIn`, so \"each exempt row names where\n * it is documented\" is structural rather than a convention a future row\n * could silently drop.\n */\nexport type MissingPeerLedgerEntry =\n  | Readonly<{\n      entrypoint: string;\n      arm: \"typed-refusal\";\n      formats: readonly (\"import\" | \"require\")[];\n    }>\n  | Readonly<{\n      entrypoint: string;\n      arm: \"documented-resolution-error\";\n      formats: readonly (\"import\" | \"require\")[];\n      reason: string;\n      documentedIn: readonly string[];\n    }>;\n\nconst SYNCHRONOUS_HANDLE_ADAPTER_REASON =\n  \"synchronous pass-a-Drizzle-handle factory: deferring the adapter implementation to translate its module-resolution failure would require an async signature change\";\n\nconst SYNCHRONOUS_CONNECTION_ADAPTER_REASON =\n  \"synchronous connection-owning adapter factory: deferring its Drizzle-backed implementation to translate the module-resolution failure would require an async signature change\";\n\nconst ASYNC_DRIZZLE_NATIVE_ADAPTER_REASON =\n  \"explicit Drizzle-native adapter entrypoint: it eagerly exposes a Drizzle database alongside the GraphBackend, so a missing drizzle-orm fails at module evaluation with the raw resolution error\";\n\nconst DRIZZLE_INDEX_BUILDERS_REASON =\n  \"Drizzle-native schema-builder entrypoint with no factory boundary at which to translate a missing drizzle-orm import\";\n\nconst ASSEMBLED_PROFILE_MODULE_TREE_REASON =\n  \"the factory takes a caller-assembled engine profile, never a raw Drizzle handle or connection, but its module tree statically imports the shared member modules that construct Drizzle-backed row access, so a missing drizzle-orm fails at module evaluation with the raw resolution error\";\n\n/**\n * Repo-root-relative, POSIX paths (matching `scripts/drizzle-claim-inventory.ts`'s\n * path grain) naming every file that states the peer's optionality and the\n * install command for the seven documented-resolution-error rows.\n */\nconst SYNCHRONOUS_ADAPTER_DOCUMENTED_IN: readonly string[] = [\n  \"README.md\",\n  \"packages/typegraph/README.md\",\n  \"apps/docs/src/content/docs/backend-setup.md\",\n];\n\n/**\n * Every non-portable published entrypoint, in exactly one arm. The two\n * \"batteries included\" entrypoints get the typed refusal because their\n * factory owns the connection; the seven `./adapters/drizzle/*` entrypoints\n * are the documented, accepted exemption. `tests/missing-peer-refusal.test.ts`\n * asserts this set equals `Object.keys(classifyEntrypoints())` minus the\n * portable entrypoints, both directions — so the covered set and the\n * asserted set are one object.\n */\nexport const MISSING_PEER_LEDGER = [\n  {\n    entrypoint: \"./sqlite/local\",\n    arm: \"typed-refusal\",\n    formats: [\"import\", \"require\"],\n  },\n  {\n    entrypoint: \"./postgres/pglite\",\n    arm: \"typed-refusal\",\n    formats: [\"import\", \"require\"],\n  },\n  {\n    entrypoint: \"./adapters/drizzle/sqlite\",\n    arm: \"documented-resolution-error\",\n    formats: [\"import\", \"require\"],\n    reason: SYNCHRONOUS_HANDLE_ADAPTER_REASON,\n    documentedIn: SYNCHRONOUS_ADAPTER_DOCUMENTED_IN,\n  },\n  {\n    entrypoint: \"./adapters/drizzle/postgres\",\n    arm: \"documented-resolution-error\",\n    formats: [\"import\", \"require\"],\n    reason: SYNCHRONOUS_HANDLE_ADAPTER_REASON,\n    documentedIn: SYNCHRONOUS_ADAPTER_DOCUMENTED_IN,\n  },\n  {\n    entrypoint: \"./adapters/drizzle/postgres/pglite\",\n    arm: \"documented-resolution-error\",\n    formats: [\"import\", \"require\"],\n    reason: ASYNC_DRIZZLE_NATIVE_ADAPTER_REASON,\n    documentedIn: SYNCHRONOUS_ADAPTER_DOCUMENTED_IN,\n  },\n  {\n    entrypoint: \"./adapters/drizzle/sqlite/local\",\n    arm: \"documented-resolution-error\",\n    formats: [\"import\", \"require\"],\n    reason: SYNCHRONOUS_CONNECTION_ADAPTER_REASON,\n    documentedIn: SYNCHRONOUS_ADAPTER_DOCUMENTED_IN,\n  },\n  {\n    entrypoint: \"./adapters/drizzle/sqlite/libsql\",\n    arm: \"documented-resolution-error\",\n    formats: [\"import\", \"require\"],\n    reason: ASYNC_DRIZZLE_NATIVE_ADAPTER_REASON,\n    documentedIn: SYNCHRONOUS_ADAPTER_DOCUMENTED_IN,\n  },\n  {\n    entrypoint: \"./adapters/drizzle/indexes\",\n    arm: \"documented-resolution-error\",\n    formats: [\"import\", \"require\"],\n    reason: DRIZZLE_INDEX_BUILDERS_REASON,\n    documentedIn: SYNCHRONOUS_ADAPTER_DOCUMENTED_IN,\n  },\n  {\n    entrypoint: \"./adapters/drizzle/engine\",\n    arm: \"documented-resolution-error\",\n    formats: [\"import\", \"require\"],\n    reason: ASSEMBLED_PROFILE_MODULE_TREE_REASON,\n    documentedIn: SYNCHRONOUS_ADAPTER_DOCUMENTED_IN,\n  },\n] as const satisfies readonly MissingPeerLedgerEntry[];\n\nconst MISSING_MODULE_ERROR_CODES: ReadonlySet<string> = new Set([\n  \"ERR_MODULE_NOT_FOUND\",\n  \"MODULE_NOT_FOUND\",\n]);\n\n/**\n * Both the ESM (`Cannot find package '<specifier>' imported from …`) and CJS\n * (`Cannot find module '<specifier>'`) forms put the failing specifier in\n * this first quoted group — the ONLY input this predicate reads from the\n * message. The importer path that follows it (ESM only) is never inspected.\n */\nconst MISSING_SPECIFIER_PATTERN = /Cannot find (?:package|module) '([^']+)'/;\n\n/** Matches `drizzle-orm` and `drizzle-orm/<subpath>`, never a mere substring of a longer specifier or an importer path. */\nconst DRIZZLE_ORM_SPECIFIER_PATTERN = /^drizzle-orm(\\/|$)/;\n\n/** Narrows `unknown` to a plain object whose string-keyed members can be read defensively — never an assertion. */\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n  return typeof value === \"object\" && value !== null;\n}\n\n/**\n * Whether `error` is a Node module-resolution failure naming a MISSING\n * `drizzle-orm` (or `drizzle-orm/<subpath>`) specifier — never a whole-message\n * scan (see the module doc comment for why). This is the single owner of the\n * narrow; both {@link createLocalSqliteStore} and {@link createLocalPgliteStore}\n * reach it only through {@link loadDrizzleBackedModule}.\n */\nexport function isMissingDrizzlePeerError(error: unknown): boolean {\n  if (!isRecord(error)) return false;\n\n  const code = error[\"code\"];\n  if (typeof code !== \"string\" || !MISSING_MODULE_ERROR_CODES.has(code)) {\n    return false;\n  }\n\n  const message = error[\"message\"];\n  if (typeof message !== \"string\") return false;\n\n  const specifier = MISSING_SPECIFIER_PATTERN.exec(message)?.[1];\n  if (specifier === undefined) return false;\n\n  return DRIZZLE_ORM_SPECIFIER_PATTERN.test(specifier);\n}\n\n/**\n * Builds the typed refusal for `entrypoint`. The MESSAGE itself (not only\n * `details`) carries the package name and the install command, because\n * downstream consumers of the packed tarball assert message text, not only\n * structured details. No new error class: `ConfigurationError` with a code\n * is the established pattern (`store.ts`'s `IDENTITY_REQUIRES_ATOMIC_BACKEND`),\n * and a dedicated missing-peer class would have exactly two call sites and\n * no distinct handling. Module-private: only {@link loadDrizzleBackedModule}\n * calls it, so it carries no `export` beyond this file — an unused export\n * knip would otherwise flag correctly.\n */\nfunction missingDrizzlePeerError(\n  entrypoint: string,\n  cause: unknown,\n): ConfigurationError {\n  const packageSpecifier = `@nicia-ai/typegraph${entrypoint.slice(1)}`;\n  const suggestion = `Run \\`${MISSING_PEER_INSTALL_COMMAND}\\`.`;\n  return new ConfigurationError(\n    `${packageSpecifier} requires the optional peer dependency \"${MISSING_PEER_PACKAGE}\", which is not installed. ${suggestion}`,\n    {\n      code: \"MISSING_PEER_DEPENDENCY\",\n      package: MISSING_PEER_PACKAGE,\n      entrypoint,\n    },\n    { cause, suggestion },\n  );\n}\n\n/**\n * The single wiring owner: loads a Drizzle-backed impl module, rethrowing a\n * missing-peer failure as a typed {@link ConfigurationError} naming\n * `entrypoint`, and rethrowing anything else — including\n * `ERR_PACKAGE_PATH_NOT_EXPORTED` and a missing dependency OF `drizzle-orm`\n * itself — completely untouched, so a genuine bug in the impl module, or in\n * one of Drizzle's own dependencies, is never laundered into a missing-peer\n * message. Both `createLocalSqliteStore` and `createLocalPgliteStore` call\n * this rather than `await import(...)` directly, so the refusal's wiring is\n * spelled once.\n */\nexport async function loadDrizzleBackedModule<T>(\n  entrypoint: string,\n  load: () => Promise<T>,\n): Promise<T> {\n  try {\n    return await load();\n  } catch (error) {\n    if (isMissingDrizzlePeerError(error)) {\n      throw missingDrizzlePeerError(entrypoint, error);\n    }\n    throw error;\n  }\n}\n"]}