{
  "version": 3,
  "sources": ["../../../../src/packages/read-project-manifest/index.ts"],
  "sourcesContent": ["import { promises as fs, type Stats } from 'node:fs';\nimport path from 'node:path';\nimport { PnpmError } from '../error/index.ts';\nimport type { ProjectManifest } from '../types/index.ts';\nimport {\n  extractComments,\n  type CommentSpecifier,\n} from '../text.comments-parser/index.ts';\nimport { writeProjectManifest } from '../write-project-manifest/index.ts';\nimport readYamlFile from 'read-yaml-file';\nimport detectIndent from '@gwhitney/detect-indent';\nimport equal from 'fast-deep-equal';\nimport isWindows from 'is-windows';\nimport { readJson5File, readJsonFile } from './readFile.ts';\n\nexport type WriteProjectManifest = (\n  manifest: ProjectManifest,\n  force?: boolean | undefined\n) => Promise<void>;\n\nexport async function safeReadProjectManifestOnly(\n  projectDir: string\n): Promise<ProjectManifest | null> {\n  try {\n    return await readProjectManifestOnly(projectDir);\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  } catch (err: any) {\n    if (\n      (err as NodeJS.ErrnoException).code ===\n      'ERR_PNPM_NO_IMPORTER_MANIFEST_FOUND'\n    ) {\n      return null;\n    }\n    throw err;\n  }\n}\n\nexport async function readProjectManifest(projectDir: string): Promise<{\n  fileName: string;\n  manifest: ProjectManifest;\n  writeProjectManifest: WriteProjectManifest;\n}> {\n  const result = await tryReadProjectManifest(projectDir);\n  if (result.manifest !== null) {\n    return result as {\n      fileName: string;\n      manifest: ProjectManifest;\n      writeProjectManifest: WriteProjectManifest;\n    };\n  }\n  throw new PnpmError(\n    'NO_IMPORTER_MANIFEST_FOUND',\n    `No package.json (or package.yaml, or package.json5) was found in \"${projectDir}\".`\n  );\n}\n\nexport async function readProjectManifestOnly(\n  projectDir: string\n): Promise<ProjectManifest> {\n  const { manifest } = await readProjectManifest(projectDir);\n  return manifest;\n}\n\nexport async function tryReadProjectManifest(projectDir: string): Promise<{\n  fileName: string;\n  manifest: ProjectManifest | null;\n  writeProjectManifest: WriteProjectManifest;\n}> {\n  try {\n    const manifestPath = path.join(projectDir, 'package.json');\n    const { data, text } = await readJsonFile(manifestPath);\n    return {\n      fileName: 'package.json',\n      manifest: data,\n      writeProjectManifest: createManifestWriter({\n        ...detectFileFormatting(text),\n        initialManifest: data,\n        manifestPath,\n      }),\n    };\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  } catch (err: any) {\n    if (err.code !== 'ENOENT') throw err;\n  }\n  try {\n    const manifestPath = path.join(projectDir, 'package.json5');\n    const { data, text } = await readJson5File(manifestPath);\n    return {\n      fileName: 'package.json5',\n      manifest: data,\n      writeProjectManifest: createManifestWriter({\n        ...detectFileFormattingAndComments(text),\n        initialManifest: data,\n        manifestPath,\n      }),\n    };\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  } catch (err: any) {\n    if (err.code !== 'ENOENT') throw err;\n  }\n\n  try {\n    const manifestPath = path.join(projectDir, 'package.yaml');\n\n    const manifest = await readPackageYaml(manifestPath);\n\n    return {\n      fileName: 'package.yaml',\n      manifest,\n      writeProjectManifest: createManifestWriter({\n        initialManifest: manifest,\n        manifestPath,\n      }),\n    };\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  } catch (err: any) {\n    if (err.code !== 'ENOENT') throw err;\n  }\n\n  if (isWindows()) {\n    // ENOTDIR isn't used on Windows, but pnpm expects it.\n    let s: Stats | undefined;\n\n    try {\n      s = await fs.stat(projectDir);\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars\n    } catch (_err: any) {\n      // Ignore\n    }\n\n    if (s != null && !s.isDirectory()) {\n      const err = new Error(`\"${projectDir}\" is not a directory`);\n      // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n      // @ts-expect-error\n      err['code'] = 'ENOTDIR';\n      throw err;\n    }\n  }\n\n  const filePath = path.join(projectDir, 'package.json');\n\n  return {\n    fileName: 'package.json',\n    manifest: null,\n    writeProjectManifest: async (manifest: ProjectManifest) =>\n      writeProjectManifest(filePath, manifest),\n  };\n}\n\ninterface FileFormattingAndComments {\n  comments?: CommentSpecifier[] | undefined;\n  indent: string;\n  insertFinalNewline: boolean;\n}\n\nfunction detectFileFormattingAndComments(\n  text: string\n): FileFormattingAndComments {\n  const { comments, text: newText, hasFinalNewline } = extractComments(text);\n\n  return {\n    comments,\n    indent: detectIndent.default(newText).indent,\n    insertFinalNewline: hasFinalNewline,\n  };\n}\n\ninterface FileFormatting {\n  indent: string;\n  insertFinalNewline: boolean;\n}\n\nfunction detectFileFormatting(text: string): FileFormatting {\n  return {\n    indent: detectIndent.default(text).indent,\n    insertFinalNewline: text.endsWith('\\n'),\n  };\n}\n\ninterface ReadExactProjectManifestResult {\n  manifest: ProjectManifest;\n  writeProjectManifest: WriteProjectManifest;\n}\n\nexport async function readExactProjectManifest(\n  manifestPath: string\n): Promise<ReadExactProjectManifestResult> {\n  const base = path.basename(manifestPath).toLowerCase();\n  switch (base) {\n    case 'package.json': {\n      const { data, text } = await readJsonFile(manifestPath);\n      return {\n        manifest: data,\n        writeProjectManifest: createManifestWriter({\n          ...detectFileFormatting(text),\n          initialManifest: data,\n          manifestPath,\n        }),\n      };\n    }\n    case 'package.json5': {\n      const { data, text } = await readJson5File(manifestPath);\n      return {\n        manifest: data,\n        writeProjectManifest: createManifestWriter({\n          ...detectFileFormattingAndComments(text),\n          initialManifest: data,\n          manifestPath,\n        }),\n      };\n    }\n    case 'package.yaml': {\n      const manifest = await readPackageYaml(manifestPath);\n      return {\n        manifest,\n        writeProjectManifest: createManifestWriter({\n          initialManifest: manifest,\n          manifestPath,\n        }),\n      };\n    }\n  }\n  throw new Error(`Not supported manifest name \"${base}\"`);\n}\n\nasync function readPackageYaml(filePath: string): Promise<ProjectManifest> {\n  try {\n    return await readYamlFile.default<ProjectManifest>(filePath);\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  } catch (err: any) {\n    if (err.name !== 'YAMLException') throw err;\n    err.message = `${err.message as string}\\nin ${filePath}`;\n    err.code = 'ERR_PNPM_YAML_PARSE';\n    throw err;\n  }\n}\n\nfunction createManifestWriter(opts: {\n  initialManifest: ProjectManifest;\n  comments?: CommentSpecifier[] | undefined;\n  indent?: string | number | undefined;\n  insertFinalNewline?: boolean;\n  manifestPath: string;\n}): WriteProjectManifest {\n  let initialManifest = normalize(opts.initialManifest);\n  return async (updatedManifest: ProjectManifest, force?: boolean) => {\n    const newUpdatedManifest = normalize(updatedManifest);\n\n    if (force === true || !equal(initialManifest, newUpdatedManifest)) {\n      await writeProjectManifest(opts.manifestPath, newUpdatedManifest, {\n        comments: opts.comments,\n        indent: opts.indent,\n        insertFinalNewline: opts.insertFinalNewline,\n      });\n      initialManifest = normalize(newUpdatedManifest);\n      return Promise.resolve(undefined);\n    }\n    return Promise.resolve(undefined);\n  };\n}\n\nconst dependencyKeys = new Set([\n  'dependencies',\n  'devDependencies',\n  'optionalDependencies',\n  'peerDependencies',\n]);\n\nfunction normalize(manifest: ProjectManifest): ProjectManifest {\n  const result: Record<string, unknown> = {};\n\n  for (const key in manifest) {\n    if (Object.prototype.hasOwnProperty.call(manifest, key)) {\n      const value = manifest[key as keyof ProjectManifest];\n\n      if (typeof value !== 'object' || !dependencyKeys.has(key)) {\n        result[key] = structuredClone(value);\n      } else {\n        const keys = Object.keys(value);\n        if (keys.length !== 0) {\n          keys.sort();\n          const sortedValue: Record<string, unknown> = {};\n          for (const k of keys) {\n            // @ts-expect-error this is fine\n            sortedValue[k] = value[k];\n          }\n          result[key] = sortedValue;\n        }\n      }\n    }\n  }\n\n  // TODO: fix this\n  return result as unknown as ProjectManifest;\n}\n"],
  "mappings": "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",
  "names": []
}
