@sanity/plugin-kit
7.0.28.0.0
dist/package-YDElb3ND.js−
dist/package-YDElb3ND.jsDeleted−910
Index: package/dist/package-YDElb3ND.js
===================================================================
--- package/dist/package-YDElb3ND.js
+++ package/dist/package-YDElb3ND.js
@@ -1,910 +0,0 @@
-import { a as urls, i as requiredNodeEngine, r as incompatiblePluginPackage, t as cliName } from "./constants-BDxElAZy.js";
-import { t as log_default } from "./log-DgQL-Rv9.js";
-import { t as binname } from "./package-DnMp5nXi.js";
-import { createRequire } from "node:module";
-import chalk from "chalk";
-import path from "path";
-import outdent from "outdent";
-import fs from "fs";
-import util from "util";
-import githubUrlToObject from "github-url-to-object";
-import validNpmName from "validate-npm-package-name";
-import crypto from "crypto";
-import json5 from "json5";
-import pAny from "p-any";
-import { URL } from "url";
-import inquirer from "inquirer";
-import { getLatestVersion } from "get-latest-version";
-import pProps from "p-props";
-const mergedPackages = [
- "@sanity/base",
- "@sanity/core",
- "@sanity/types",
- "@sanity/data-aspects",
- "@sanity/default-layout",
- "@sanity/default-login",
- "@sanity/desk-tool",
- "@sanity/field",
- "@sanity/form-builder",
- "@sanity/initial-value-templates",
- "@sanity/language-filter",
- "@sanity/production-preview",
- "@sanity/react-hooks",
- "@sanity/resolver",
- "@sanity/state-router",
- "@sanity/structure",
- "@sanity/studio-hints"
-].sort(), deprecatedDevDeps = [
- "tsdx",
- "sanipack",
- "parcel",
- "@parcel/packager-ts",
- "@parcel/transformer-typescript-types"
-], buildExtensions = [
- ".js",
- ".jsx",
- ".es6",
- ".es",
- ".mjs",
- ".ts",
- ".tsx"
-];
-async function prompt(message, options) {
- let type = options.choices ? "list" : options.type, result = await inquirer.prompt([{
- ...options,
- type,
- message,
- name: "single"
- }]);
- return result && result.single;
-}
-prompt.separator = () => new inquirer.Separator();
-function promptForPackageName({ basePath }, defaultVal) {
- return prompt("Plugin name (sanity-plugin-...)", {
- default: defaultVal || path.basename(basePath),
- filter: (name) => {
- let prefixless = name.trim().replace(/^sanity-plugin-/, "");
- return name[0] === "@" ? name : `sanity-plugin-${prefixless}`;
- },
- validate: (name) => {
- let valid = validNpmName(name);
- return valid.errors ? valid.errors[0] : name[0] !== "@" && name.endsWith("plugin") ? `Name shouldn't include "plugin" multiple times (${name})` : !0;
- }
- });
-}
-function promptForRepoOrigin(_options, defaultVal) {
- return prompt("Git repository URL", {
- default: defaultVal,
- filter: (raw) => {
- let url = (raw || "").trim(), gh = githubUrlToObject(url);
- return gh ? `git+ssh://[email protected]/${gh.user}/${gh.repo}.git` : url;
- },
- validate: (url) => {
- if (!url) return !0;
- try {
- return new URL(url), !0;
- } catch {
- return "Invalid URL";
- }
- }
- });
-}
-const stat$1 = util.promisify(fs.stat), mkdir = util.promisify(fs.mkdir), readdir = util.promisify(fs.readdir), copyFile = util.promisify(fs.copyFile), readFile$2 = util.promisify(fs.readFile), writeFile = util.promisify(fs.writeFile);
-function hasSourceEquivalent(compiledFile, paths) {
- if (!paths.source) return fileExists(path.isAbsolute(compiledFile) ? compiledFile : path.resolve(paths.basePath, compiledFile));
- let baseDir = path.dirname(compiledFile.replace(paths.compiled, paths.source)), baseName = path.basename(compiledFile, path.extname(compiledFile));
- return buildCandidateExists(path.join(baseDir, baseName));
-}
-async function hasSourceFile(filePath, paths) {
- if (!paths?.source) return fileExists(path.isAbsolute(filePath) ? filePath : path.resolve(paths?.basePath ?? "", filePath));
- let pathStub = path.isAbsolute(filePath) ? filePath : path.resolve(paths.source, filePath);
- return await fileExists(pathStub) ? !0 : buildCandidateExists(pathStub);
-}
-function hasCompiledFile(filePath, paths) {
- if (!paths?.compiled) return fileExists(path.isAbsolute(filePath) ? filePath : path.resolve(paths?.basePath ?? "", filePath));
- let absPath = path.isAbsolute(filePath) ? filePath : path.resolve(paths.compiled, filePath);
- return fileExists(path.extname(absPath) === "" ? `${absPath}.js` : absPath);
-}
-function buildCandidateExists(pathStub) {
- return pAny(buildExtensions.map((extCandidate) => `${pathStub}${extCandidate}`).map((candidate) => stat$1(candidate))).then(() => !0).catch(() => !1);
-}
-function fileExists(filePath) {
- return stat$1(filePath).then(() => !0).catch(() => !1);
-}
-async function readJsonFile(filePath) {
- let content = await readFile$2(filePath, "utf8");
- return JSON.parse(content);
-}
-function writeJsonFile(filePath, content) {
- let data = JSON.stringify(content, null, 2) + "\n";
- return writeFile(filePath, data, { encoding: "utf8" });
-}
-async function writeFileWithOverwritePrompt(filePath, content, options) {
- let { default: defaultVal, force = !1, ...writeOptions } = options, printablePath = filePath.startsWith(process.cwd()) ? path.relative(process.cwd(), filePath) : filePath;
- return await fileEqualsData(filePath, content) || !force && await fileExists(filePath) && !await prompt(`File "${printablePath}" already exists. Overwrite?`, {
- type: "confirm",
- default: defaultVal
- }) ? !1 : (await writeFile(filePath, content, writeOptions), !0);
-}
-async function copyFileWithOverwritePrompt(from, to, flags) {
- let printablePath = to.startsWith(process.cwd()) ? path.relative(process.cwd(), to) : to;
- return await filesAreEqual(from, to) || (await ensureDirectoryExists(to), !flags.force && await fileExists(to) && !await prompt(`File "${printablePath}" already exists. Overwrite?`, {
- type: "confirm",
- default: !1
- })) ? !1 : (await copyFile(from, to), !0);
-}
-async function ensureDirectoryExists(filePath) {
- let dirname = path.dirname(filePath);
- await fileExists(dirname) || (await ensureDirectoryExists(dirname), await mkdir(dirname));
-}
-async function fileEqualsData(filePath, content) {
- return crypto.createHash("sha1").update(content).digest("hex") === await getFileHash(filePath);
-}
-async function filesAreEqual(file1, file2) {
- let [hash1, hash2] = await Promise.all([getFileHash(file1, !1), getFileHash(file2)]);
- return hash1 === hash2;
-}
-function getFileHash(filePath, allowMissing = !0) {
- return new Promise((resolve, reject) => {
- let hash = crypto.createHash("sha1"), stream = fs.createReadStream(filePath);
- stream.on("error", (err) => {
- err.code === "ENOENT" && allowMissing ? resolve(null) : reject(err);
- }), stream.on("end", () => resolve(hash.digest("hex"))), stream.on("data", (chunk) => hash.update(chunk));
- });
-}
-async function ensureDir(dirPath) {
- try {
- await mkdir(dirPath);
- } catch (err) {
- if (err.code !== "EEXIST") throw err;
- }
-}
-async function isEmptyish(dirPath) {
- let ignoredFiles = [
- ".git",
- ".gitignore",
- "license",
- "readme.md"
- ];
- return (await readdir(dirPath).catch(() => [])).filter((file) => !ignoredFiles.includes(file.toLowerCase())).length === 0;
-}
-async function readFileContent({ filename, basePath }) {
- let filepath = path.normalize(path.join(basePath, filename));
- try {
- return await readFile$2(filepath, "utf8");
- } catch (err) {
- if (err.code === "ENOENT") {
- log_default.debug(`No ${filename} file found.`);
- return;
- }
- throw Error(`Failed to read "${filepath}": ${err.message}`);
- }
-}
-async function readJson5File({ filename, basePath }) {
- let content = await readFileContent({
- filename,
- basePath
- });
- if (content) return parseJson5(content, filename);
-}
-function parseJson5(content, errorKey) {
- try {
- return json5.parse(content);
- } catch (err) {
- throw Error(`Error parsing "${errorKey}": ${err.message}`);
- }
-}
-const expectedScripts = {
- build: "plugin-kit verify-package --silent && pkg-utils build --strict --check --clean",
- watch: "pkg-utils watch --strict",
- "link-watch": "plugin-kit link-watch",
- prepublishOnly: "npm run build"
-};
-function filesWithSuffixes(fileBases, suffixes) {
- return fileBases.flatMap((file) => suffixes.map((suffix) => `${file}.${suffix}`));
-}
-function validateNodeEngine(packageJson) {
- return packageJson.engines?.node === ">=20.19 <22 || >=22.12" ? [] : [outdent`
- Expected package.json to contain engines.node: "${requiredNodeEngine}" to match @sanity/pkg-utils,
- but it was: ${packageJson.engines?.node}
-
- Please add the following to package.json:
-
- "engines": {
- "node": "${requiredNodeEngine}"
- }`.trimStart()];
-}
-function validateScripts(packageJson) {
- let errors = [], divergentScripts = Object.entries(expectedScripts).filter(([key, expectedCommand]) => {
- let command = packageJson.scripts?.[key];
- return !command || !command.includes(expectedCommand);
- });
- return divergentScripts.length && errors.push(outdent`
- The following script commands did not contain expected defaults: ${divergentScripts.map(([key]) => key).join(", ")}
-
- This checks for that the commands-strings includes these terms.
-
- Please add the following to your package.json "scripts":
-
- ${divergentScripts.map(([key, value]) => `"${key}": "${value}"`).join(",\n")}
- `.trimStart()), errors;
-}
-async function validateTsConfig(ts, options) {
- let { basePath, outDir, tsconfig } = options, errors = [], wrongEntries = Object.entries({
- target: "esnext",
- jsx: "preserve",
- module: "preserve",
- rootDir: ".",
- outDir,
- noEmit: !0
- }).filter(([key, value]) => {
- let option = ts.options[key];
- return key === "rootDir" && typeof option == "string" && (option = path.relative(basePath, option) || "."), key === "outDir" && typeof option == "string" && (option = path.relative(basePath, option) || "."), key === "target" && option === 99 && (option = "esnext"), key === "module" && option === 200 && (option = "preserve"), key === "jsx" && option === 1 && (option = "preserve"), typeof value == "string" && typeof option == "string" ? value.toLowerCase() !== option?.toLowerCase() : value !== option;
- });
- if (wrongEntries.length) {
- let expectedOutput = wrongEntries.map(([key, value]) => `"${key}": ${typeof value == "string" ? `"${value}"` : value},`).join("\n");
- errors.push(outdent`
- Recommended ${tsconfig} compilerOptions missing:
-
- The following fields had unexpected values: [${wrongEntries.map(([key]) => key).join(", ")}]
- Expected to find these values:
- ${expectedOutput}
-
- Please update your ${tsconfig} accordingly.
- `.trimStart());
- }
- return errors;
-}
-/**
-* Hard requirement: plugins must be ESM (`"type": "module"`).
-*
-* plugin-kit loads `package.config.ts` through `@sanity/pkg-utils`, which can only load ESM
-* TypeScript configs reliably when the plugin itself is ESM. CommonJS (or an omitted `type`)
-* is not supported and cannot be opted out of.
-*/
-function validatePackageType({ type }) {
- return type === "module" ? [] : [outdent`
- package.json must set "type": "module" — plugins built with @sanity/plugin-kit are ESM-only.
- Found: ${type ? `"type": "${type}"` : "no \"type\" field (defaults to \"commonjs\")"}
-
- Please add the following to package.json:
-
- "type": "module"
- `.trimStart()];
-}
-/**
-* Recursively collects the locations of any `require` condition within a package.json `exports`
-* field. Conditions can be nested arbitrarily deep (and inside fallback arrays), so we walk the
-* whole tree rather than only inspecting the first level.
-*
-* Subpath keys always start with `.` (e.g. `"./feature"`), while condition keys never do, so an
-* exact `require` key is unambiguously a CommonJS export condition.
-*/
-function findRequireConditions(node, pathSegments) {
- if (Array.isArray(node)) return node.flatMap((entry, index) => findRequireConditions(entry, [...pathSegments, String(index)]));
- if (!node || typeof node != "object") return [];
- let found = [];
- for (let [key, value] of Object.entries(node)) key === "require" && found.push(formatExportsPath(pathSegments)), found.push(...findRequireConditions(value, [...pathSegments, key]));
- return found;
-}
-function formatExportsPath(segments) {
- return `exports${segments.map((segment) => `[${JSON.stringify(segment)}]`).join("")}`;
-}
-/**
-* Bans CommonJS interop in package.json. The plugin baseline is Sanity Studio v5 or later, which is
-* pure ESM, so there is no reason to publish a parallel CJS build anymore. This flags:
-*
-* - `require` export conditions
-* - the top-level `main` field
-* - the top-level `module` field
-*/
-function validateEsmOnly(packageJson) {
- let offenders = [];
- packageJson.main !== void 0 && offenders.push(`- the top-level "main" field (${JSON.stringify(packageJson.main)})`), packageJson.module !== void 0 && offenders.push(`- the top-level "module" field (${JSON.stringify(packageJson.module)})`);
- let requireConditions = [...new Set(findRequireConditions(packageJson.exports, []))];
- for (let conditionPath of requireConditions) offenders.push(`- a "require" export condition at ${conditionPath}`);
- return offenders.length ? [outdent`
- package.json ships CommonJS (CJS) output, but Sanity plugins target Sanity Studio v5+, which is pure ESM.
-
- Remove the following so the package stays ESM-only:
- ${offenders.join("\n")}
-
- Supporting CJS is not worth it:
- - It can have unintended side-effects.
- - The Node.js versions plugin-kit supports (${requiredNodeEngine}) fully support require(esm), so a
- consumer that still uses require() loads the ESM build directly — which is far more predictable.
- - Publishing a single format guarantees two copies of the plugin's code (ESM + CJS) can't both end up
- in the module tree, bloating bundles and slowing down builds.
-
- Rely on "exports" together with "type": "module", and drop "main", "module" and any "require" conditions.
- `.trimStart()] : [];
-}
-function validatePkgUtilsDependency({ devDependencies }) {
- return devDependencies?.["@sanity/pkg-utils"] ? [] : [outdent`
- package.json does not list @sanity/pkg-utils as a devDependency.
- @sanity/pkg-utils replaced parcel as the recommended build tool in @sanity/plugin-kit 2.0.0
-
- Please add it by running 'npm install --save-dev @sanity/pkg-utils'.
- `.trimStart()];
-}
-/**
-* Verifies that the installed `@sanity/pkg-utils` (the peer dependency plugin-kit loads
-* `package.config.ts` with) is recent enough to expose the `loadConfig({cwd, pkgPath})` API.
-*/
-function validatePkgUtilsVersion({ basePath }) {
- let require = createRequire(path.join(basePath, "package.json")), installedVersion;
- try {
- installedVersion = require("@sanity/pkg-utils/package.json").version;
- } catch {
- return [outdent`
- @sanity/pkg-utils is not installed.
- plugin-kit loads package.config.ts through @sanity/pkg-utils (a peer dependency).
-
- Please install it by running 'npm install --save-dev @sanity/pkg-utils'.
- `.trimStart()];
- }
- let major = Number.parseInt(installedVersion?.split(".")[0] ?? "", 10);
- return !Number.isFinite(major) || major < 10 ? [outdent`
- @sanity/pkg-utils ${installedVersion} is too old.
- plugin-kit requires @sanity/pkg-utils >=${10} to load package.config.ts.
-
- Please upgrade it by running 'npm install --save-dev @sanity/pkg-utils@latest'.
- `.trimStart()] : [];
-}
-function validateSanityDependencies(packageJson) {
- let { dependencies, devDependencies, peerDependencies } = packageJson, allDependencies = {
- ...dependencies,
- ...devDependencies,
- ...peerDependencies
- }, illegalDeps = Object.keys(allDependencies).filter((dep) => mergedPackages.includes(dep)), unique = [...new Set(illegalDeps).values()];
- return unique.length ? [outdent`
- package.json depends on "@sanity/*" packages that have moved into "sanity" package.
-
- The following dependencies should be replaced with "sanity":
- - ${unique.join("\n- ")}
-
- Refer to the reference docs to find replacement imports:
- ${urls.refDocs}
- `.trimStart()] : [];
-}
-function validateDeprecatedDependencies(packageJson) {
- let { dependencies, devDependencies, peerDependencies } = packageJson, allDependencies = {
- ...dependencies,
- ...devDependencies,
- ...peerDependencies
- }, illegalDeps = Object.keys(allDependencies).filter((dep) => deprecatedDevDeps.includes(dep)), unique = [...new Set(illegalDeps).values()];
- return unique.length ? [outdent`
- package.json contains deprecated dependencies that should be removed:
- - ${unique.join("\n- ")}
- `.trimStart()] : [];
-}
-async function validateBabelConfig({ basePath }) {
- let filenames = [".babelrc", ...filesWithSuffixes([".babelrc", "babel.config"], [
- "json",
- "js",
- "cjs",
- "mjs"
- ])], babelFiles = [];
- for (let filename of filenames) await fileExists(path.normalize(path.join(basePath, filename))) && babelFiles.push(filename);
- return babelFiles.length ? [outdent`
- Found babel-config file: [${babelFiles.join(", ")}]. When using default @sanity/plugin-kit build command,
- this is probably not needed.
-
- Delete the file, or disable this check.
- `.trimStart()] : [];
-}
-async function validateStudioConfig({ basePath }) {
- let suffixes = [
- "ts",
- "js",
- "tsx",
- "jsx"
- ], filenames = filesWithSuffixes(["sanity.config", "sanity.cli"], suffixes), files = {};
- for (let filename of filenames) files[filename] = await fileExists(path.normalize(path.join(basePath, filename)));
- let sanityJson = await readJson5File({
- basePath,
- filename: "sanity.json"
- }), hasConfigFile = (fileBase) => filesWithSuffixes([fileBase], suffixes).some((filename) => files[filename]), hasCliConfig = hasConfigFile("sanity.cli"), hasStudioConfig = hasConfigFile("sanity.config"), errors = [];
- if (sanityJson) {
- let info = [outdent`
- Found sanity.json. This file is not used by Sanity Studio V3.
-
- Please consult the Studio V3 migration guide:
- ${urls.migrationGuideStudio}
- It will detail how to convert sanity.json to sanity.config.ts (or .js) and sanity.cli.ts (or .js) equivalents.
- `.trimStart(), sanityJson.plugins?.length && outdent`
- For V3 versions and alternatives to V2 plugins, please refer to the Sanity Exchange:
- ${urls.sanityExchange}
- `.trimStart()].filter((s) => !!s);
- errors.push(info.join("\n\n"));
- }
- return hasCliConfig || errors.push(outdent`
- sanity.cli.(${suffixes.join(" | ")}) missing. Please create a file named sanity.cli.ts with the following content:
-
- ${chalk.green(outdent`
- import {createCliConfig} from 'sanity/cli'
-
- export default createCliConfig({
- api: {
- projectId: '${sanityJson?.api?.projectId ?? "project-id"}',
- dataset: '${sanityJson?.api?.dataset ?? "dataset"}',
- }
- })`)}
-
- Make sure to replace the projectId and dataset fields with your own.
-
- For more, see ${urls.migrationGuideStudio}
- `.trimStart()), hasStudioConfig || errors.push(outdent`
- sanity.config.(${suffixes.join(" | ")}) missing. At a minimum sanity.config.ts should contain:
-
- ${chalk.green(outdent`
- import { defineConfig } from "sanity"
- import { deskTool } from "sanity/desk"
-
- export default defineConfig({
- name: "default",
-
- projectId: '${sanityJson?.api?.projectId ?? "project-id"}',
- dataset: '${sanityJson?.api?.dataset ?? "dataset"}',
-
- plugins: [
- deskTool(),
- ],
-
- schema: {
- types: [
- /* put your v2 schema-types here */
- ],
- },
- })`).trimStart()}
-
- Make sure to replace the projectId and dataset fields with your own.
-
- For more, see ${urls.migrationGuideStudio}
- `.trimStart()), errors.length ? [errors.join("\n\n---\n\n")] : [];
-}
-/**
-* Detects leftover usage of the legacy `@sanity/incompatible-plugin` shim and asks for its removal.
-*
-* The shim (a `sanity.json` + `v2-incompatible.js` entry point, plus the `@sanity/incompatible-plugin`
-* dependency) only rendered an error dialog in the long end-of-life Sanity Studio v2 when a v3 plugin
-* was installed there. plugin-kit no longer scaffolds it, so a plugin should not ship it anymore.
-*/
-async function validateIncompatiblePlugin({ basePath, packageJson }) {
- let { dependencies, devDependencies, peerDependencies } = packageJson, inDependencies = !!(dependencies?.["@sanity/incompatible-plugin"] || devDependencies?.["@sanity/incompatible-plugin"] || peerDependencies?.["@sanity/incompatible-plugin"]), hasShimFile = await fileExists(path.normalize(path.join(basePath, "v2-incompatible.js"))), sanityJsonReferencesShim = !!(await readJson5File({
- basePath,
- filename: "sanity.json"
- }))?.parts?.some((part) => part?.path?.includes("v2-incompatible"));
- return !inDependencies && !hasShimFile && !sanityJsonReferencesShim ? [] : [outdent`
- ${incompatiblePluginPackage} is no longer used and should be removed.
-
- It only rendered an error dialog in the long end-of-life Sanity Studio v2 when a v3 plugin was
- installed there. That compatibility shim is now obsolete, so plugin-kit no longer adds it.
-
- Found:
- ${[
- inDependencies ? `- "${incompatiblePluginPackage}" listed in package.json` : null,
- hasShimFile ? "- the v2-incompatible.js file" : null,
- sanityJsonReferencesShim ? "- a sanity.json referencing v2-incompatible.js" : null
- ].filter((e) => !!e).join("\n")}
-
- To fix this:
- - Remove "${incompatiblePluginPackage}" from package.json (dependencies/devDependencies/peerDependencies)
- - Delete the v2-incompatible.js file
- - Delete sanity.json (if it only contains the v2-incompatible "part")
- - Remove "sanity.json" and "v2-incompatible.js" from the package.json "files" array
-
- For more, see ${urls.incompatiblePlugin}
- `.trimStart()];
-}
-function validatePackageName$1(packageJson) {
- let valid = validNpmName(packageJson.name ?? "");
- return valid.validForNewPackages ? !packageJson.name?.startsWith("@") && !packageJson.name?.startsWith("sanity-plugin-") ? ["Invalid package.json: \"name\" should be prefixed with \"sanity-plugin-\" (or scoped - @your-company/plugin-name)"] : [] : [`Invalid package.json: "name" is invalid: ${(valid.errors ?? valid.warnings ?? []).join(", ")}`];
-}
-/**
-* Plugins built with @sanity/plugin-kit publish the compiled output (the `dist` directory) plus any
-* v2-compatibility files. The `src` directory should not be published: it bloats the package and can
-* cause bundlers that resolve the `source` export condition to pull in raw, uncompiled TypeScript.
-*/
-function validateBannedFiles(packageJson) {
- let { files } = packageJson;
- return !Array.isArray(files) || !files.some((entry) => typeof entry == "string" && entry.trim().replace(/^\.?\/+/, "").replace(/\/+$/, "") === "src") ? [] : [outdent`
- package.json "files" must not include "src".
-
- Plugins built with @sanity/plugin-kit publish the compiled output in "dist" (and any v2-compatibility files).
- Shipping the "src" directory bloats the published package and can cause bundlers that resolve the
- "source" export condition to import raw, uncompiled TypeScript.
-
- Please remove "src" from the "files" array in package.json.
- `.trimStart()];
-}
-async function validateSrcIndexFile(basePath) {
- let paths = ["index.js", "index.ts"].map((p) => path.join("src", p)), allowedIndexFiles = paths.map((file) => path.join(basePath, file)), hasIndex = !1;
- for (let indexFile of allowedIndexFiles) hasIndex ||= await fileExists(indexFile);
- return hasIndex ? [] : [outdent`
- Expected one of [${paths.join(", ")}] to exist.
-
- @sanity/pkg-utils expects a non-jsx file to be the source entry-point for the plugin.
- If you currently have JSX in your index file, extract it into a separate file and import it.
- `];
-}
-async function disallowDuplicateConfig({ basePath, pkgJson, configKey, files }) {
- let found = [];
- for (let file of files) await fileExists(path.join(basePath, file)) && found.push(file);
- return found.length > 1 ? [outdent`
- Found multiple config files that serve the same purpose: [${found.join(", ")}].
-
- There should be at most one of these files. Delete the rest.
- `] : found.length && pkgJson[configKey] ? [outdent`
- package.json contains ${configKey}, but there also exists a config file that serves the same purpose.
- Config file: ${found.join("")}]
-
- Either delete the file or remove ${configKey} entry from package.json.
- `] : [];
-}
-async function disallowDuplicateEslintConfig(basePath, pkgJson) {
- return disallowDuplicateConfig({
- basePath,
- pkgJson,
- configKey: "eslint",
- files: [
- ".eslintrc",
- ".eslintrc.js",
- ".eslintrc.cjs",
- ".eslintrc.yaml",
- ".eslintrc.yml",
- ".eslintrc.json"
- ]
- });
-}
-async function disallowDuplicatePrettierConfig(basePath, pkgJson) {
- return disallowDuplicateConfig({
- basePath,
- pkgJson,
- configKey: "prettier",
- files: [
- ".prettierrc",
- ".prettierrc.json5",
- ".prettierrc.json",
- ".prettierrc.yaml",
- ".prettierrc.yml",
- ".prettierrc.js",
- ".prettierrc.cjs",
- ".prettier.config,js",
- ".prettier.config.cjs",
- ".prettierrc.toml"
- ]
- });
-}
-const forcedPackageVersions = {}, forcedDevPackageVersions = {}, forcedPeerPackageVersions = {
- react: "^18",
- "react-dom": "^18",
- "@types/react": "^18",
- "@types/react-dom": "^18",
- sanity: "^5 || ^6.0.0-0",
- "styled-components": "^5.2"
-};
-function errorToUndefined(err) {
- if (err instanceof TypeError) throw err;
-}
-const stat = util.promisify(fs.stat), readFile$1 = util.promisify(fs.readFile), allowedPartProps = [
- "name",
- "implements",
- "path",
- "description"
-], disallowedPluginProps = [
- "api",
- "project",
- "plugins",
- "env"
-];
-async function getPaths(options) {
- let { basePath } = options, manifest = await readManifest(options);
- return manifest.paths ? absolutifyPaths(manifest.paths, basePath) : null;
-}
-function absolutifyPaths(paths, basePath) {
- let getPath = (relative) => relative ? path.resolve(path.join(basePath, relative)) : void 0;
- return paths ? {
- basePath,
- compiled: getPath(paths.compiled),
- source: getPath(paths.source)
- } : { basePath };
-}
-async function readManifest(options) {
- let { basePath, validate = !0 } = options, manifestPath = path.normalize(path.join(basePath, "sanity.json")), content;
- try {
- content = await readFile$1(manifestPath, "utf8");
- } catch (err) {
- throw err.code === "ENOENT" ? Error(`No sanity.json found. sanity.json is required for plugins to function. Use \`${binname} init\` for a new plugin, or create an empty \`sanity.json\` with an empty object (\`{}\`) for existing ones.`) : Error(`Failed to read "${manifestPath}": ${err.message}`);
- }
- let parsed;
- try {
- parsed = JSON.parse(content);
- } catch (err) {
- throw Error(`Error parsing "${manifestPath}": ${err.message}`);
- }
- return validate && await validateManifest(parsed, options), parsed;
-}
-async function validateManifest(manifest, opts) {
- let options = {
- isPlugin: !0,
- ...opts
- };
- if (!isObject$1(manifest)) throw Error("Invalid sanity.json: Root must be an object");
- if (options.isPlugin ? await validatePluginManifest(manifest, options) : validateProjectManifest(manifest), "root" in manifest && typeof manifest.root != "boolean") throw Error("Invalid sanity.json: \"root\" property must be a boolean if declared");
- await validateParts(manifest, {
- ...options,
- paths: absolutifyPaths(manifest.paths, options.basePath)
- });
-}
-function validateProjectManifest(manifest) {
- if ("paths" in manifest) throw Error("Invalid sanity.json: \"paths\" property has no meaning in a project manifest");
-}
-async function validatePluginManifest(manifest, options) {
- let disallowed = Object.keys(manifest).filter((key) => disallowedPluginProps.includes(key)).map((key) => `"${key}"`);
- if (disallowed.length > 0) {
- let plural = disallowed.length > 1 ? "s" : "", joined = disallowed.join(", ");
- throw Error(`Invalid sanity.json: Key${plural} ${joined} ${plural ? "are" : "is"} not allowed in a plugin manifest`);
- }
- if (manifest.root) throw Error("Invalid sanity.json: \"root\" cannot be truthy in a plugin manifest");
- await validatePaths$1(manifest, options);
-}
-async function validatePaths$1(manifest, options) {
- if (!("paths" in manifest)) return;
- if (!isObject$1(manifest.paths)) throw Error("Invalid sanity.json: \"paths\" must be an object if declared");
- if (typeof manifest.paths.compiled != "string") throw Error("Invalid sanity.json: \"paths\" must have a (string) \"compiled\" property if declared");
- if (typeof manifest.paths.source != "string") throw Error("Invalid sanity.json: \"paths\" must have a (string) \"source\" property if declared");
- let sourcePath = path.resolve(options.basePath, manifest.paths.source), srcStats;
- try {
- srcStats = await stat(sourcePath);
- } catch (err) {
- if (err.code === "ENOENT") throw Error(`sanity.json references "source" path which does not exist: "${sourcePath}"`);
- }
- if (!srcStats?.isDirectory()) throw Error(`sanity.json references "source" path which is not a directory: "${sourcePath}"`);
-}
-async function validateParts(manifest, options) {
- if (!("parts" in manifest)) return;
- if (!Array.isArray(manifest.parts)) throw Error("Invalid sanity.json: \"parts\" must be an array if declared");
- let i = 0;
- for (let part of manifest.parts) await validatePart(part, i, options), i++;
-}
-async function validatePart(part, index, options) {
- if (!isObject$1(part)) throw Error(`Invalid sanity.json: "parts[${index}]" must be an object`);
- validateAllowedPartKeys(part, index), validatePartStringValues(part, index), validatePartNames(part, index, options), await validatePartFiles(part, index, options);
-}
-async function validatePartFiles(part, index, options) {
- let { verifyCompiledParts, verifySourceParts, paths } = options;
- if (!part?.path) return;
- let ext = path.extname(part.path);
- if (paths?.source && ext && ext !== ".js" && buildExtensions.includes(ext)) throw Error(`Invalid sanity.json: Part path has extension which is not applicable after compiling. ${ext} becomes .js after compiling. Specify filename without extension (${path.basename(part.path)}) (parts[${index}])`);
- if (!verifySourceParts && !verifyCompiledParts) return;
- let [srcExists, outDirExists] = await Promise.all([hasSourceFile(part.path, paths), verifyCompiledParts && hasCompiledFile(part.path, paths)]);
- if (!srcExists) throw Error(`Invalid sanity.json: Part path references file that does not exist in source directory (${paths?.source || paths?.basePath}) (parts[${index}])`);
- if (verifyCompiledParts && !outDirExists) throw Error(`Invalid sanity.json: Part path references file ("${part.path}") that does not exist in compiled directory (${paths?.compiled}) (parts[${index}])`);
-}
-function validatePartNames(part, index, options) {
- let pluginName = options.pluginName ? options.pluginName.replace(/^sanity-plugin-/, "") : "";
- if (!part?.name || !part?.name?.startsWith(`part:${pluginName}/`)) throw Error(`Invalid sanity.json: "name" must be prefixed with "part:${pluginName}/" - got "${part?.name}" (parts[${index}])`);
- if (!part?.implements?.startsWith("part:")) throw Error(`Invalid sanity.json: "implements" must be prefixed with "part:" - got "${part?.implements}" (parts[${index}])`);
-}
-function validateAllowedPartKeys(part, index) {
- let disallowed = Object.keys(part).filter((key) => !allowedPartProps.includes(key)).map((key) => `"${key}"`);
- if (disallowed.length > 0) {
- let plural = disallowed.length > 1 ? "s" : "", joined = disallowed.join(", ");
- throw Error(`Invalid sanity.json: Key${plural} ${joined} ${plural ? "are" : "is"} not allowed in a part declaration (parts[${index}])`);
- }
-}
-function validatePartStringValues(part, index) {
- let nonStrings = Object.keys(part).filter((key) => typeof part[key] != "string").map((key) => `"${key}"`);
- if (nonStrings.length > 0) {
- let plural = nonStrings.length > 1 ? "s" : "", joined = nonStrings.join(", ");
- throw Error(`Invalid sanity.json: Key${plural} ${joined} should be of type string (parts[${index}])`);
- }
-}
-function isObject$1(obj) {
- return !Array.isArray(obj) && typeof obj == "object" && !!obj;
-}
-async function hasSanityJson(basePath) {
- let file = await readJsonFile(path.join(basePath, "sanity.json")).catch(errorToUndefined);
- return {
- exists: !!file,
- isRoot: !!(file && file.root)
- };
-}
-async function findStudioV3Config(basePath) {
- let jsFile = "sanity.config.js";
- if (await fileExists(path.join(basePath, jsFile))) return { v3ConfigFile: jsFile };
- let tsFile = "sanity.config.ts";
- return { v3ConfigFile: await fileExists(path.join(basePath, tsFile)) ? tsFile : void 0 };
-}
-const lockedDependencies = {
- "styled-components": "^6.1",
- eslint: "^8.57.0",
- typescript: "^6"
-};
-function resolveLatestVersions(packages) {
- let versions = {};
- for (let pkgName of packages) versions[pkgName] = pkgName in lockedDependencies ? lockedDependencies[pkgName] : "latest";
- return pProps(versions, async (range, pkgName) => {
- let version = await getLatestVersion(pkgName, { range });
- if (!version) throw Error(`Found no version for ${pkgName}`);
- return rangeify(version);
- }, { concurrency: 8 });
-}
-function rangeify(version) {
- return `^${version}`;
-}
-const defaultDependencies = [], defaultDevDependencies = [
- "sanity",
- "react",
- "react-dom",
- "styled-components"
-], defaultPeerDependencies = ["react", "sanity"], readFile = util.promisify(fs.readFile), pathKeys = [
- "main",
- "module",
- "browser",
- "types"
-];
-async function getPackage(opts) {
- let options = {
- flags: {},
- ...opts
- };
- validateOptions(options);
- let { basePath, validate = !0 } = options, manifestPath = path.normalize(path.join(basePath, "package.json")), content;
- try {
- content = await readFile(manifestPath, "utf8");
- } catch (err) {
- throw err.code === "ENOENT" ? Error(`No package.json found. package.json is required to publish to npm. Use \`${cliName} init\` for a new plugin, or \`npm init\` for an existing one`) : Error(`Failed to read "${manifestPath}": ${err.message}`);
- }
- let parsed;
- try {
- parsed = JSON.parse(content);
- } catch (err) {
- throw Error(`Error parsing "${manifestPath}": ${err.message}`);
- }
- if (!isObject(parsed)) throw Error("Invalid package.json: Root must be an object");
- return validate && await validatePackage(parsed, options), parsed;
-}
-async function validatePackage(manifest, opts) {
- validateOptions(opts);
- let options = {
- isPlugin: !0,
- ...opts
- };
- options.isPlugin && await validatePluginPackage(manifest, options), validateLockFiles(options);
-}
-function validateOptions(opts) {
- let options = opts || {};
- if (!isObject(options)) throw Error("Options must be an object");
- if (typeof options.basePath != "string") throw Error("\"options.basePath\" must be a string (path to plugin base path)");
-}
-async function validatePluginPackage(manifest, options) {
- validatePackageName(manifest), await validatePaths(manifest, options);
-}
-function validatePackageName(manifest) {
- if (typeof manifest.name != "string") throw Error("Invalid package.json: \"name\" must be a string");
- let valid = validNpmName(manifest.name);
- if (!valid.validForNewPackages) throw Error(`Invalid package.json: "name" is invalid: ${(valid.errors ?? []).join(", ")}`);
- if (manifest.name[0] !== "@" && !manifest.name.startsWith("sanity-plugin-")) throw Error("Invalid package.json: \"name\" should be prefixed with \"sanity-plugin-\" (or scoped - @your-company/plugin-name)");
-}
-async function validatePaths(manifest, options) {
- let paths = await getPaths({
- ...options,
- pluginName: manifest.name ?? "unknown",
- verifySourceParts: !1,
- verifyCompiledParts: !1
- }), abs = (file) => path.isAbsolute(file) ? file : path.resolve(path.join(options.basePath, file)), exists = (file) => fs.existsSync(abs(file)), willExist = (file) => paths && hasSourceEquivalent(abs(file), paths), withinSourceDir = (file) => paths?.source && abs(file).startsWith(paths.source), withinTargetDir = (file) => paths?.compiled && abs(file).startsWith(paths.compiled);
- for (let key of pathKeys) {
- if (!(key in manifest)) continue;
- let manifestValue = manifest[key];
- if (typeof manifestValue != "string") throw Error(`Invalid package.json: "${key}" must be a string if defined`);
- if (!options?.flags?.allowSourceTarget && paths && withinSourceDir(manifestValue)) throw Error(`Invalid package.json: "${key}" points to file within source (uncompiled) directory. Use --allow-source-target if you really want to do this.`);
- if (exists(manifestValue) && paths && withinTargetDir(manifestValue) && !await willExist(manifestValue)) throw Error(`Invalid package.json: "${key}" points to file that will not exist after compiling`);
- if (!exists(manifestValue) && !await willExist(manifestValue)) {
- if (!paths) throw Error(`Invalid package.json: "${key}" points to file that does not exist`);
- let inOutDir = paths.compiled && !abs(manifestValue).startsWith(paths.compiled);
- throw Error(inOutDir ? `Invalid package.json: "${key}" points to file that does not exist, and "paths" is not configured to compile to this location` : `Invalid package.json: "${key}" points to file that does not exist, and no equivalent is found in source directory`);
- }
- }
-}
-function isObject(obj) {
- return !Array.isArray(obj) && typeof obj == "object" && !!obj;
-}
-function validateLockFiles(options) {
- let npm = fs.existsSync(path.join(options.basePath, "package-lock.json")), yarn = fs.existsSync(path.join(options.basePath, "yarn.lock"));
- if (npm && yarn) throw Error("Invalid plugin: contains both package-lock.json and yarn.lock");
-}
-async function writePackageJson(data, options) {
- let { user, pluginName, license, description, pkg: prevPkg, gitOrigin } = data, { outDir, peerDependencies: addPeers, dependencies: addDeps, devDependencies: addDevDeps } = options, { flags } = options, prev = prevPkg || {}, usePrettier = flags.prettier !== !1, useEslint = flags.eslint !== !1, useTypescript = flags.eslint !== !1, newDevDependencies = [cliName, "@sanity/pkg-utils"];
- useTypescript && (log_default.debug("Using TypeScript. Adding to dev dependencies."), newDevDependencies.push("@types/react", "typescript")), usePrettier && (log_default.debug("Using prettier. Adding to dev dependencies."), newDevDependencies.push("prettier", "prettier-plugin-packagejson")), useEslint && (log_default.debug("Using eslint. Adding to dev dependencies."), newDevDependencies.push("eslint", "eslint-config-sanity", "eslint-plugin-react", "eslint-plugin-react-hooks"), usePrettier && newDevDependencies.push("eslint-config-prettier", "eslint-plugin-prettier"), useTypescript && newDevDependencies.push("@typescript-eslint/eslint-plugin", "@typescript-eslint/parser")), log_default.debug("Resolving latest versions for %s", newDevDependencies.join(", "));
- let dependencies = forceDependencyVersions({
- ...prev.dependencies || {},
- ...addDeps || {},
- ...await resolveLatestVersions(defaultDependencies)
- }, forcedPackageVersions), devDependencies = forceDependencyVersions({
- ...addDevDeps || {},
- ...prev.devDependencies || {},
- ...await resolveLatestVersions([...newDevDependencies, ...defaultDevDependencies])
- }, forcedDevPackageVersions), peerDependencies = forceDependencyVersions({
- ...prev.peerDependencies || {},
- ...addPeers || {},
- ...await resolveLatestVersions(defaultPeerDependencies)
- }, forcedPeerPackageVersions), source = flags.typescript ? "./src/index.ts" : "./src/index.js", files = [outDir];
- files.sort();
- let forcedOrder = {
- name: pluginName,
- version: prev.version ?? "1.0.0",
- description: description || "",
- keywords: prev.keywords ?? ["sanity", "sanity-plugin"],
- ...urlsFromOrigin(gitOrigin),
- ...repoFromOrigin(gitOrigin),
- license: license ? license.id : "UNLICENSED",
- author: user?.email ? `${user.name} <${user.email}>` : user?.name,
- sideEffects: !1,
- type: "module",
- exports: {
- ".": {
- source,
- default: `./${outDir}/index.js`
- },
- "./package.json": "./package.json"
- },
- ...flags.typescript ? { types: `./${outDir}/index.d.ts` } : {},
- files,
- scripts: { ...prev.scripts },
- dependencies: sortKeys(dependencies),
- devDependencies: sortKeys(devDependencies),
- peerDependencies: sortKeys(peerDependencies),
- engines: { node: requiredNodeEngine }
- }, manifest = {
- ...forcedOrder,
- ...prev || {},
- ...forcedOrder
- }, differs = JSON.stringify(prev) !== JSON.stringify(manifest);
- return log_default.debug("Does manifest differ? %s", differs ? "yes" : "no"), differs && await writePackageJsonDirect(manifest, options), differs ? manifest : prev;
-}
-function urlsFromOrigin(gitOrigin) {
- if (!gitOrigin) return {};
- let details = githubUrlToObject(gitOrigin);
- return details ? {
- homepage: `https://github.com/${details.user}/${details.repo}#readme`,
- bugs: { url: `https://github.com/${details.user}/${details.repo}/issues` }
- } : {};
-}
-function repoFromOrigin(gitOrigin) {
- return gitOrigin ? { repository: {
- type: "git",
- url: gitOrigin
- } } : {};
-}
-function addScript(cmd, existing) {
- return existing && existing.includes(cmd) ? existing : cmd;
-}
-async function addPackageJsonScripts(manifest, options, updateScripts) {
- let originalScripts = manifest.scripts || {}, scripts = updateScripts({ ...originalScripts }), differs = Object.keys(scripts).some((key) => scripts[key] !== originalScripts[key]);
- return differs && await writePackageJsonDirect({
- ...manifest,
- scripts
- }, options), differs;
-}
-async function writePackageJsonDirect(manifest, { basePath }) {
- await writeJsonFile(path.join(basePath, "package.json"), manifest);
-}
-async function addBuildScripts(manifest, options) {
- return options.flags.scripts ? addPackageJsonScripts(manifest, options, (scripts) => (scripts.build = addScript(expectedScripts.build, scripts.build), scripts.format = addScript("prettier --write --cache --ignore-unknown .", scripts.format), scripts["link-watch"] = addScript(expectedScripts["link-watch"], scripts["link-watch"]), scripts.lint = addScript("eslint .", scripts.lint), scripts.prepublishOnly = addScript(expectedScripts.prepublishOnly, scripts.prepublishOnly), scripts.watch = addScript(expectedScripts.watch, scripts.watch), scripts)) : !1;
-}
-function sortKeys(unordered) {
- return Object.keys(unordered).sort().reduce((obj, key) => (obj[key] = unordered[key], obj), {});
-}
-/** @internal */
-function forceDependencyVersions(deps, versions = forcedPackageVersions) {
- let entries = Object.entries(deps).map((entry) => {
- let [pkg] = entry, forceVersion = versions[pkg];
- return forceVersion ? [pkg, forceVersion] : entry;
- });
- return Object.fromEntries(entries);
-}
-export { validateStudioConfig as A, writeFileWithOverwritePrompt as B, validatePackageName$1 as C, validateSanityDependencies as D, validatePkgUtilsVersion as E, isEmptyish as F, promptForPackageName as H, mkdir as I, readFile$2 as L, copyFileWithOverwritePrompt as M, ensureDir as N, validateScripts as O, fileExists as P, readJsonFile as R, validateNodeEngine as S, validatePkgUtilsDependency as T, promptForRepoOrigin as U, prompt as V, mergedPackages as W, validateBabelConfig as _, getPackage as a, validateEsmOnly as b, writePackageJsonDirect as c, hasSanityJson as d, errorToUndefined as f, disallowDuplicatePrettierConfig as g, disallowDuplicateEslintConfig as h, forceDependencyVersions as i, validateTsConfig as j, validateSrcIndexFile as k, resolveLatestVersions as l, forcedPackageVersions as m, addPackageJsonScripts as n, sortKeys as o, forcedDevPackageVersions as p, addScript as r, writePackageJson as s, addBuildScripts as t, findStudioV3Config as u, validateBannedFiles as v, validatePackageType as w, validateIncompatiblePlugin as x, validateDeprecatedDependencies as y, writeFile as z };
-
-//# sourceMappingURL=package-YDElb3ND.js.map
\ No newline at end of file