{"version":3,"file":"read-contract-space-contract-DyLWOWSt.mjs","names":["hasErrnoCode","hasErrnoCode"],"sources":["../src/space-layout.ts","../src/read-contract-space-head-ref.ts","../src/verify-contract-spaces.ts","../src/read-contract-space-contract.ts"],"sourcesContent":["import { APP_SPACE_ID } from '@prisma-next/framework-components/control';\nimport { join } from 'pathe';\nimport { errorInvalidSpaceId } from './errors';\n\nexport { APP_SPACE_ID };\n\n/**\n * Branded string carrying a compile-time guarantee that the value has\n * been validated by {@link assertValidSpaceId}. Downstream filesystem\n * helpers (e.g. {@link spaceMigrationDirectory}) accept this type to\n * make \"validated\" tracking visible at the type level rather than\n * relying purely on a runtime check.\n */\nexport type ValidSpaceId = string & { readonly __brand: 'ValidSpaceId' };\n\n/**\n * Pattern a contract-space identifier must match. The constraint is\n * filesystem-friendly: lowercase letters / digits / hyphen / underscore,\n * starts with a letter, max 64 characters.\n */\nconst SPACE_ID_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;\n\nexport function isValidSpaceId(spaceId: string): spaceId is ValidSpaceId {\n  return SPACE_ID_PATTERN.test(spaceId);\n}\n\nexport function assertValidSpaceId(spaceId: string): asserts spaceId is ValidSpaceId {\n  if (!isValidSpaceId(spaceId)) {\n    throw errorInvalidSpaceId(spaceId);\n  }\n}\n\n/**\n * Resolve the migrations subdirectory for a given contract space.\n *\n * Every contract space — including the app space (default `'app'`) —\n * lands under `<projectMigrationsDir>/<spaceId>/`. The space id is\n * validated against {@link SPACE_ID_PATTERN} because it becomes a\n * filesystem directory name verbatim.\n *\n * `projectMigrationsDir` is the project's top-level `migrations/`\n * directory; the helper does not assume anything about its absolute /\n * relative shape and is symmetric with `pathe.join`.\n */\nexport function spaceMigrationDirectory(projectMigrationsDir: string, spaceId: string): string {\n  assertValidSpaceId(spaceId);\n  return join(projectMigrationsDir, spaceId);\n}\n\n/**\n * Per-space subdirectory name reserved for the ref store\n * (`migrations/<space>/<SPACE_REFS_DIRNAME>/*.json`). Single source of\n * truth: every helper that composes a per-space refs path imports this\n * constant, and the enumerator uses it (via\n * {@link RESERVED_SPACE_SUBDIR_NAMES}) to exclude reserved names from\n * the contract-space candidate list.\n */\nexport const SPACE_REFS_DIRNAME = 'refs';\n\n/**\n * Names reserved as per-space subdirectories of `migrations/<space>/`.\n * Used by the enumerator to filter contract-space candidates so a\n * reserved name (e.g. a top-level `migrations/refs/` left in the wrong\n * place) is never enumerated as a phantom contract space. Currently\n * holds `SPACE_REFS_DIRNAME`; extend if future per-space layouts add\n * more reserved subdirectories.\n */\nexport const RESERVED_SPACE_SUBDIR_NAMES: ReadonlySet<string> = new Set([SPACE_REFS_DIRNAME]);\n\n/**\n * Resolve the per-space refs directory for `spaceMigrationsDir`\n * (typically the value returned by {@link spaceMigrationDirectory}).\n * Composes the canonical {@link SPACE_REFS_DIRNAME} so callers do not\n * hard-code the literal.\n */\nexport function spaceRefsDirectory(spaceMigrationsDir: string): string {\n  return join(spaceMigrationsDir, SPACE_REFS_DIRNAME);\n}\n","import { readFile } from 'node:fs/promises';\nimport type { ContractSpaceHeadRef } from '@prisma-next/framework-components/control';\nimport { join } from 'pathe';\nimport { errorInvalidJson, errorInvalidRefFile } from './errors';\nimport { assertValidSpaceId, spaceMigrationDirectory, spaceRefsDirectory } from './space-layout';\n\nexport type { ContractSpaceHeadRef };\n\nfunction hasErrnoCode(error: unknown, code: string): boolean {\n  return error instanceof Error && (error as { code?: string }).code === code;\n}\n\n/**\n * Read the head ref (`hash` + `invariants`) for a contract space from\n * `<projectMigrationsDir>/<spaceId>/refs/head.json`.\n *\n * Returns `null` when the file does not exist (first emit). Surfaces\n * `MIGRATION.INVALID_JSON` / `MIGRATION.INVALID_REF_FILE` on a corrupt\n * `refs/head.json` so callers can distinguish \"no head ref on disk\"\n * (returns `null`) from \"head ref present but unreadable\" (throws).\n *\n * Validates the space id against `[a-z][a-z0-9_-]{0,63}` for the same\n * filesystem-safety reasons as the rest of the per-space helpers. The\n * helper is uniform across the app and extension spaces.\n */\nexport async function readContractSpaceHeadRef(\n  projectMigrationsDir: string,\n  spaceId: string,\n): Promise<ContractSpaceHeadRef | null> {\n  assertValidSpaceId(spaceId);\n\n  const filePath = join(\n    spaceRefsDirectory(spaceMigrationDirectory(projectMigrationsDir, spaceId)),\n    'head.json',\n  );\n\n  let raw: string;\n  try {\n    raw = await readFile(filePath, 'utf-8');\n  } catch (error) {\n    if (hasErrnoCode(error, 'ENOENT')) {\n      return null;\n    }\n    throw error;\n  }\n\n  let parsed: unknown;\n  try {\n    parsed = JSON.parse(raw);\n  } catch (e) {\n    throw errorInvalidJson(filePath, e instanceof Error ? e.message : String(e));\n  }\n\n  if (typeof parsed !== 'object' || parsed === null) {\n    throw errorInvalidRefFile(filePath, 'expected an object');\n  }\n  const obj = parsed as { hash?: unknown; invariants?: unknown };\n  if (typeof obj.hash !== 'string') {\n    throw errorInvalidRefFile(filePath, 'expected an object with a string `hash` field');\n  }\n  if (!Array.isArray(obj.invariants) || obj.invariants.some((value) => typeof value !== 'string')) {\n    throw errorInvalidRefFile(filePath, 'expected an object with an `invariants` array of strings');\n  }\n\n  return { hash: obj.hash, invariants: obj.invariants as readonly string[] };\n}\n","import { readdir, stat } from 'node:fs/promises';\nimport { join } from 'pathe';\nimport { MANIFEST_FILE } from './io';\nimport { APP_SPACE_ID } from './space-layout';\n\nfunction hasErrnoCode(error: unknown, code: string): boolean {\n  return error instanceof Error && (error as { code?: string }).code === code;\n}\n\n/**\n * List the per-space subdirectories under\n * `<projectRoot>/migrations/`. Returns space-id directory names (sorted\n * alphabetically) — i.e. any non-dot-prefixed subdirectory whose root\n * does **not** contain a `migration.json` manifest. The manifest is the\n * structural marker of a user-authored migration directory (see\n * `readMigrationsDir` in `./io`); directory names themselves belong to\n * the user and are not part of the contract.\n *\n * Returns `[]` if the migrations directory does not exist (greenfield\n * project).\n *\n * Reads only the user's repo. **No descriptor import.** The caller\n * (verifier) feeds the result into {@link verifyContractSpaces} alongside\n * the loaded-space set and the marker rows.\n */\nexport async function listContractSpaceDirectories(\n  projectMigrationsDir: string,\n): Promise<readonly string[]> {\n  let entries: { readonly name: string; readonly isDirectory: boolean }[];\n  try {\n    const dirents = await readdir(projectMigrationsDir, { withFileTypes: true });\n    entries = dirents.map((d) => ({ name: d.name, isDirectory: d.isDirectory() }));\n  } catch (error) {\n    if (hasErrnoCode(error, 'ENOENT')) {\n      return [];\n    }\n    throw error;\n  }\n\n  const namedCandidates = entries\n    .filter((e) => e.isDirectory)\n    .map((e) => e.name)\n    .filter((name) => !name.startsWith('.'))\n    .sort();\n\n  const manifestChecks = await Promise.all(\n    namedCandidates.map(async (name) => {\n      try {\n        await stat(join(projectMigrationsDir, name, MANIFEST_FILE));\n        return { name, isMigrationDir: true };\n      } catch (error) {\n        if (hasErrnoCode(error, 'ENOENT')) {\n          return { name, isMigrationDir: false };\n        }\n        throw error;\n      }\n    }),\n  );\n\n  return manifestChecks.filter((c) => !c.isMigrationDir).map((c) => c.name);\n}\n\n/**\n * On-disk head value (`(hash, invariants)`) for one contract space.\n * The verifier compares this against the marker row for the same space\n * to detect drift between the user-emitted artefacts and the live DB\n * marker.\n */\nexport interface ContractSpaceHeadRecord {\n  readonly hash: string;\n  readonly invariants: readonly string[];\n}\n\n/**\n * Marker row read from `prisma_contract.marker` (one per `space`).\n * Caller resolves these via the family runtime's marker reader before\n * invoking {@link verifyContractSpaces}.\n */\nexport interface SpaceMarkerRecord {\n  readonly hash: string;\n  readonly invariants: readonly string[];\n}\n\nexport interface VerifyContractSpacesInputs {\n  /**\n   * Set of contract spaces the project declares: `'app'` plus each\n   * extension space in `extensionPacks`. The caller's discovery path\n   * never reads the extension descriptor module — it walks the\n   * `extensionPacks` configuration in `prisma-next.config.ts` for the\n   * space ids.\n   */\n  readonly loadedSpaces: ReadonlySet<string>;\n\n  /**\n   * Per-space subdirectories observed under\n   * `<projectRoot>/migrations/`. Resolved via\n   * {@link listContractSpaceDirectories}.\n   */\n  readonly spaceDirsOnDisk: readonly string[];\n\n  /**\n   * Head ref per space, keyed by space id. Caller reads\n   * `<projectRoot>/migrations/<space-id>/contract.json` and\n   * `<projectRoot>/migrations/<space-id>/refs/head.json` to construct\n   * this map. Spaces with no contract-space dir on disk simply omit a\n   * map entry.\n   */\n  readonly headRefsBySpace: ReadonlyMap<string, ContractSpaceHeadRecord>;\n\n  /**\n   * Marker rows keyed by `space`. Caller reads them from the\n   * `prisma_contract.marker` table.\n   */\n  readonly markerRowsBySpace: ReadonlyMap<string, SpaceMarkerRecord>;\n}\n\nexport type SpaceVerifierViolation =\n  | {\n      readonly kind: 'declaredButUnmigrated';\n      readonly spaceId: string;\n      readonly remediation: string;\n    }\n  | {\n      readonly kind: 'orphanMarker';\n      readonly spaceId: string;\n      readonly remediation: string;\n    }\n  | {\n      readonly kind: 'orphanSpaceDir';\n      readonly spaceId: string;\n      readonly remediation: string;\n    }\n  | {\n      readonly kind: 'hashMismatch';\n      readonly spaceId: string;\n      readonly priorHeadHash: string;\n      readonly markerHash: string;\n      readonly remediation: string;\n    }\n  | {\n      readonly kind: 'invariantsMismatch';\n      readonly spaceId: string;\n      readonly onDiskInvariants: readonly string[];\n      readonly markerInvariants: readonly string[];\n      readonly remediation: string;\n    };\n\nexport type VerifyContractSpacesResult =\n  | { readonly ok: true }\n  | { readonly ok: false; readonly violations: readonly SpaceVerifierViolation[] };\n\n/**\n * Pure structural verifier for the per-space mechanism. Aggregates the\n * three orphan / missing checks plus per-space hash and invariant\n * comparison.\n *\n * Algorithm:\n *\n * - For every extension space declared in `loadedSpaces` (`'app'`\n *   excluded — the per-space verifier is scoped to extension members;\n *   the app is verified through the aggregate path):\n *   - If no contract-space dir on disk → `declaredButUnmigrated`.\n *   - Else if `markerRowsBySpace` lacks an entry → no violation here;\n *     the live-DB compare done outside this helper is where the\n *     absence shows up.\n *   - Else compare marker hash / invariants vs. on-disk head hash /\n *     invariants → `hashMismatch` / `invariantsMismatch` on drift.\n * - For every contract-space dir on disk that is not in `loadedSpaces` →\n *   `orphanSpaceDir`.\n * - For every marker row whose `space` is not in `loadedSpaces` →\n *   `orphanMarker`. The app-space marker is always loaded (`'app'` is\n *   in `loadedSpaces` by definition).\n *\n * Output is deterministic: violations are sorted first by `kind`\n * (`declaredButUnmigrated` → `orphanMarker` → `orphanSpaceDir` →\n * `hashMismatch` → `invariantsMismatch`) then by `spaceId`. Two callers\n * passing equivalent inputs see byte-identical violation lists.\n *\n * Synchronous, pure, no I/O. **Does not import the extension descriptor**\n * (the inputs are pre-resolved by the caller); the verifier reads only\n * the user repo, not `node_modules`.\n */\nexport function verifyContractSpaces(\n  inputs: VerifyContractSpacesInputs,\n): VerifyContractSpacesResult {\n  const violations: SpaceVerifierViolation[] = [];\n\n  for (const spaceId of [...inputs.loadedSpaces].sort()) {\n    if (spaceId === APP_SPACE_ID) continue;\n\n    if (!inputs.spaceDirsOnDisk.includes(spaceId)) {\n      violations.push({\n        kind: 'declaredButUnmigrated',\n        spaceId,\n        remediation: `Extension '${spaceId}' is declared in extensionPacks but has not been emitted; run \\`prisma-next migrate\\`.`,\n      });\n      continue;\n    }\n\n    const head = inputs.headRefsBySpace.get(spaceId);\n    const marker = inputs.markerRowsBySpace.get(spaceId);\n    if (!head || !marker) {\n      continue;\n    }\n\n    if (head.hash !== marker.hash) {\n      violations.push({\n        kind: 'hashMismatch',\n        spaceId,\n        priorHeadHash: head.hash,\n        markerHash: marker.hash,\n        remediation: `Marker row for space '${spaceId}' is keyed at ${marker.hash}, but the on-disk ${join('migrations', spaceId, 'contract.json')} resolves to ${head.hash}. Run \\`prisma-next db update\\` to advance the database, or \\`prisma-next migrate\\` if the descriptor was bumped without re-emitting.`,\n      });\n      continue;\n    }\n\n    const onDiskInvariants = [...head.invariants].sort();\n    const markerInvariants = new Set(marker.invariants);\n    const missing = onDiskInvariants.filter((id) => !markerInvariants.has(id));\n    if (missing.length > 0) {\n      violations.push({\n        kind: 'invariantsMismatch',\n        spaceId,\n        onDiskInvariants,\n        markerInvariants: [...marker.invariants].sort(),\n        remediation: `Marker row for space '${spaceId}' is missing invariants [${missing.map((s) => JSON.stringify(s)).join(', ')}]. Run \\`prisma-next db update\\` to apply the corresponding data-transform migrations.`,\n      });\n    }\n  }\n\n  for (const dir of [...inputs.spaceDirsOnDisk].sort()) {\n    if (!inputs.loadedSpaces.has(dir)) {\n      violations.push({\n        kind: 'orphanSpaceDir',\n        spaceId: dir,\n        remediation: `Orphan contract-space directory \\`${join('migrations', dir)}/\\` for an extension not in extensionPacks; remove the directory or re-add the extension.`,\n      });\n    }\n  }\n\n  for (const space of [...inputs.markerRowsBySpace.keys()].sort()) {\n    if (!inputs.loadedSpaces.has(space)) {\n      violations.push({\n        kind: 'orphanMarker',\n        spaceId: space,\n        remediation: `Orphan marker row for space '${space}' (no longer in extensionPacks); remediation: manually delete the row from \\`prisma_contract.marker\\`.`,\n      });\n    }\n  }\n\n  if (violations.length === 0) {\n    return { ok: true };\n  }\n\n  const kindOrder: Record<SpaceVerifierViolation['kind'], number> = {\n    declaredButUnmigrated: 0,\n    orphanMarker: 1,\n    orphanSpaceDir: 2,\n    hashMismatch: 3,\n    invariantsMismatch: 4,\n  };\n\n  violations.sort((a, b) => {\n    const k = kindOrder[a.kind] - kindOrder[b.kind];\n    if (k !== 0) return k;\n    if (a.spaceId < b.spaceId) return -1;\n    if (a.spaceId > b.spaceId) return 1;\n    return 0;\n  });\n\n  return { ok: false, violations };\n}\n","import { readFile } from 'node:fs/promises';\nimport { join } from 'pathe';\nimport { errorInvalidJson, errorMissingFile } from './errors';\nimport { assertValidSpaceId } from './space-layout';\n\nfunction hasErrnoCode(error: unknown, code: string): boolean {\n  return error instanceof Error && (error as { code?: string }).code === code;\n}\n\n/**\n * Read the on-disk contract value for a contract space\n * (`<projectMigrationsDir>/<spaceId>/contract.json`). Returns the parsed\n * JSON value as `unknown` — callers that need a typed contract validate\n * via their family's `deserializeContract` to surface schema issues.\n *\n * Companion to {@link import('./read-contract-space-head-ref').readContractSpaceHeadRef}\n * — same ENOENT-throws / corrupt-file-error semantics. Returns the\n * canonical-JSON value the framework wrote during emit, so re-running\n * this helper across machines / runs yields a byte-identical value.\n */\nexport async function readContractSpaceContract(\n  projectMigrationsDir: string,\n  spaceId: string,\n): Promise<unknown> {\n  assertValidSpaceId(spaceId);\n\n  const filePath = join(projectMigrationsDir, spaceId, 'contract.json');\n\n  let raw: string;\n  try {\n    raw = await readFile(filePath, 'utf-8');\n  } catch (error) {\n    if (hasErrnoCode(error, 'ENOENT')) {\n      throw errorMissingFile('contract.json', join(projectMigrationsDir, spaceId));\n    }\n    throw error;\n  }\n\n  try {\n    return JSON.parse(raw);\n  } catch (e) {\n    throw errorInvalidJson(filePath, e instanceof Error ? e.message : String(e));\n  }\n}\n"],"mappings":"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"}