@sanity/cli 7.0.2 → 7.2.0
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.
- package/README.md +18 -12
- package/dist/actions/dev/getDevServerConfig.js +1 -1
- package/dist/actions/dev/getDevServerConfig.js.map +1 -1
- package/dist/actions/init/initAction.js +23 -23
- package/dist/actions/init/initAction.js.map +1 -1
- package/dist/actions/init/initNextJs.js +4 -4
- package/dist/actions/init/initNextJs.js.map +1 -1
- package/dist/actions/mcp/promptForMCPSetup.js +1 -1
- package/dist/actions/mcp/promptForMCPSetup.js.map +1 -1
- package/dist/actions/mcp/setupMCP.js +5 -5
- package/dist/actions/mcp/setupMCP.js.map +1 -1
- package/dist/actions/mcp/types.js.map +1 -1
- package/dist/actions/skills/readSkillState.js +14 -7
- package/dist/actions/skills/readSkillState.js.map +1 -1
- package/dist/actions/skills/setupSkills.js +5 -2
- package/dist/actions/skills/setupSkills.js.map +1 -1
- package/dist/commands/init.js +4 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/server/devServer.js.map +1 -1
- package/dist/util/packageManager/getPeerDependencies.js +2 -2
- package/dist/util/packageManager/getPeerDependencies.js.map +1 -1
- package/dist/util/packageManager/installPackages.js +41 -1
- package/dist/util/packageManager/installPackages.js.map +1 -1
- package/oclif.manifest.json +596 -596
- package/package.json +7 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/skills/readSkillState.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\nimport {execa} from 'execa'\n\nimport {SKILLS_BIN_PATH} from './setupSkills.js'\n\nconst debug = subdebug('skills:state')\n\ninterface ReadSkillStateOptions {\n /**
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/skills/readSkillState.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\nimport {execa} from 'execa'\n\nimport {SKILLS_BIN_PATH} from './setupSkills.js'\n\nconst debug = subdebug('skills:state')\n\ninterface ReadSkillStateOptions {\n /** Names of the skills to look up (match the `name` field in `skills list --json`). */\n skillNames: string[]\n}\n\ninterface SkillState {\n /** Display names of agents that have all of these skills installed globally. */\n installedAgentDisplayNames: Set<string>\n}\n\ninterface SkillListEntry {\n agents?: unknown\n name?: unknown\n}\n\n/**\n * Runs the bundled `skills list -g --json` and returns the set of agent\n * display names that have every skill in `skillNames` installed globally.\n * Agents missing any of the skills are excluded, so they get a (idempotent)\n * re-install that fills the gap.\n *\n * Any failure (spawn, parse, timeout, non-zero exit) is debug-logged and\n * resolved with an empty set. Callers should treat that as \"treat all agents\n * as not installed\" — re-installing is idempotent, so over-installing is\n * safer than skipping based on a flaky probe.\n */\nexport async function readSkillState(opts: ReadSkillStateOptions): Promise<SkillState> {\n const empty: SkillState = {installedAgentDisplayNames: new Set()}\n\n let stdout: string\n try {\n const result = await execa(process.execPath, [SKILLS_BIN_PATH, 'list', '-g', '--json'], {\n stdio: 'pipe',\n timeout: 10_000,\n })\n stdout = result.stdout\n } catch (error) {\n debug('skills list failed: %O', error)\n return empty\n }\n\n let parsed: unknown\n try {\n parsed = JSON.parse(stdout)\n } catch (error) {\n debug('Failed to parse skills list JSON: %O', error)\n return empty\n }\n\n if (!Array.isArray(parsed)) {\n debug('Unexpected skills list JSON shape (not an array)')\n return empty\n }\n\n const agentSets = opts.skillNames.map((skillName) => {\n const match = (parsed as SkillListEntry[]).find((entry) => entry?.name === skillName)\n if (!match || !Array.isArray(match.agents)) {\n return new Set<string>()\n }\n return new Set(match.agents.filter((a): a is string => typeof a === 'string'))\n })\n\n const installedEverywhere = [...(agentSets[0] ?? [])].filter((agent) =>\n agentSets.every((set) => set.has(agent)),\n )\n return {installedAgentDisplayNames: new Set(installedEverywhere)}\n}\n"],"names":["subdebug","execa","SKILLS_BIN_PATH","debug","readSkillState","opts","empty","installedAgentDisplayNames","Set","stdout","result","process","execPath","stdio","timeout","error","parsed","JSON","parse","Array","isArray","agentSets","skillNames","map","skillName","match","find","entry","name","agents","filter","a","installedEverywhere","agent","every","set","has"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,KAAK,QAAO,QAAO;AAE3B,SAAQC,eAAe,QAAO,mBAAkB;AAEhD,MAAMC,QAAQH,SAAS;AAiBvB;;;;;;;;;;CAUC,GACD,OAAO,eAAeI,eAAeC,IAA2B;IAC9D,MAAMC,QAAoB;QAACC,4BAA4B,IAAIC;IAAK;IAEhE,IAAIC;IACJ,IAAI;QACF,MAAMC,SAAS,MAAMT,MAAMU,QAAQC,QAAQ,EAAE;YAACV;YAAiB;YAAQ;YAAM;SAAS,EAAE;YACtFW,OAAO;YACPC,SAAS;QACX;QACAL,SAASC,OAAOD,MAAM;IACxB,EAAE,OAAOM,OAAO;QACdZ,MAAM,0BAA0BY;QAChC,OAAOT;IACT;IAEA,IAAIU;IACJ,IAAI;QACFA,SAASC,KAAKC,KAAK,CAACT;IACtB,EAAE,OAAOM,OAAO;QACdZ,MAAM,wCAAwCY;QAC9C,OAAOT;IACT;IAEA,IAAI,CAACa,MAAMC,OAAO,CAACJ,SAAS;QAC1Bb,MAAM;QACN,OAAOG;IACT;IAEA,MAAMe,YAAYhB,KAAKiB,UAAU,CAACC,GAAG,CAAC,CAACC;QACrC,MAAMC,QAAQ,AAACT,OAA4BU,IAAI,CAAC,CAACC,QAAUA,OAAOC,SAASJ;QAC3E,IAAI,CAACC,SAAS,CAACN,MAAMC,OAAO,CAACK,MAAMI,MAAM,GAAG;YAC1C,OAAO,IAAIrB;QACb;QACA,OAAO,IAAIA,IAAIiB,MAAMI,MAAM,CAACC,MAAM,CAAC,CAACC,IAAmB,OAAOA,MAAM;IACtE;IAEA,MAAMC,sBAAsB;WAAKX,SAAS,CAAC,EAAE,IAAI,EAAE;KAAE,CAACS,MAAM,CAAC,CAACG,QAC5DZ,UAAUa,KAAK,CAAC,CAACC,MAAQA,IAAIC,GAAG,CAACH;IAEnC,OAAO;QAAC1B,4BAA4B,IAAIC,IAAIwB;IAAoB;AAClE"}
|
|
@@ -6,7 +6,10 @@ import { execa } from 'execa';
|
|
|
6
6
|
import { getErrorMessage, toError } from '../../util/getErrorMessage.js';
|
|
7
7
|
const skillsDebug = subdebug('skills:setup');
|
|
8
8
|
/** Source repo for the bundled `skills` CLI. See https://www.sanity.io/docs/ai/skills. */ export const SANITY_SKILLS_REPO = 'sanity-io/agent-toolkit';
|
|
9
|
-
/**
|
|
9
|
+
/** Names of the skills we install — must match the entries in the source repo. */ export const SANITY_SKILL_NAMES = [
|
|
10
|
+
'sanity-best-practices',
|
|
11
|
+
'sanity-migration'
|
|
12
|
+
];
|
|
10
13
|
/**
|
|
11
14
|
* Absolute path to the bundled `skills` CLI bin. Resolved once at module load
|
|
12
15
|
* via `import.meta.resolve` so we run the version pinned in our package.json
|
|
@@ -32,7 +35,7 @@ const skillsDebug = subdebug('skills:setup');
|
|
|
32
35
|
'add',
|
|
33
36
|
SANITY_SKILLS_REPO,
|
|
34
37
|
'--skill',
|
|
35
|
-
|
|
38
|
+
...SANITY_SKILL_NAMES,
|
|
36
39
|
'-g',
|
|
37
40
|
...uniqueAgents.flatMap((agent)=>[
|
|
38
41
|
'-a',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/skills/setupSkills.ts"],"sourcesContent":["import {fileURLToPath} from 'node:url'\n\nimport {ux} from '@oclif/core'\nimport {subdebug} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {execa} from 'execa'\n\nimport {getErrorMessage, toError} from '../../util/getErrorMessage.js'\n\nconst skillsDebug = subdebug('skills:setup')\n\n/** Source repo for the bundled `skills` CLI. See https://www.sanity.io/docs/ai/skills. */\nexport const SANITY_SKILLS_REPO = 'sanity-io/agent-toolkit'\n\n/**
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/skills/setupSkills.ts"],"sourcesContent":["import {fileURLToPath} from 'node:url'\n\nimport {ux} from '@oclif/core'\nimport {subdebug} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {execa} from 'execa'\n\nimport {getErrorMessage, toError} from '../../util/getErrorMessage.js'\n\nconst skillsDebug = subdebug('skills:setup')\n\n/** Source repo for the bundled `skills` CLI. See https://www.sanity.io/docs/ai/skills. */\nexport const SANITY_SKILLS_REPO = 'sanity-io/agent-toolkit'\n\n/** Names of the skills we install — must match the entries in the source repo. */\nexport const SANITY_SKILL_NAMES = ['sanity-best-practices', 'sanity-migration']\n\n/**\n * Absolute path to the bundled `skills` CLI bin. Resolved once at module load\n * via `import.meta.resolve` so we run the version pinned in our package.json\n * instead of paying the `npx -y` registry lookup at runtime.\n */\nexport const SKILLS_BIN_PATH = fileURLToPath(\n import.meta.resolve('skills/bin/cli.mjs', import.meta.url),\n)\n\ninterface SetupSkillsOptions {\n /** Skills-CLI agent IDs (e.g. 'cursor', 'claude-code') to install for. */\n agents: string[]\n}\n\ninterface SetupSkillsResult {\n /** Deduplicated `--agent` values passed to `skills add`. */\n installedAgents: string[]\n skipped: boolean\n\n error?: Error\n}\n\n/**\n * Runs the bundled `skills add` globally for the given agents. Failures are\n * surfaced as warnings and never throw — skills install is best-effort and\n * must not abort `sanity init`.\n */\nexport async function setupSkills(options: SetupSkillsOptions): Promise<SetupSkillsResult> {\n const uniqueAgents = [...new Set(options.agents)]\n\n if (uniqueAgents.length === 0) {\n skillsDebug('No agents passed — skipping skills install')\n return {installedAgents: [], skipped: true}\n }\n\n const args = [\n SKILLS_BIN_PATH,\n 'add',\n SANITY_SKILLS_REPO,\n '--skill',\n ...SANITY_SKILL_NAMES,\n '-g',\n ...uniqueAgents.flatMap((agent) => ['-a', agent]),\n '-y',\n ]\n\n skillsDebug('Running: %s %s', process.execPath, args.join(' '))\n\n try {\n const result = await execa(process.execPath, args, {stdio: 'pipe', timeout: 90_000})\n skillsDebug('skills stdout: %s', result.stdout)\n skillsDebug('skills stderr: %s', result.stderr)\n ux.stdout(`${logSymbols.success} Installed Sanity agent skills for ${uniqueAgents.join(', ')}`)\n return {installedAgents: uniqueAgents, skipped: false}\n } catch (error) {\n skillsDebug('Error installing skills %O', error)\n const err = toError(error)\n ux.warn(`Could not install Sanity agent skills: ${getErrorMessage(error)}`)\n if (error && typeof error === 'object') {\n const {stderr, stdout} = error as {stderr?: string; stdout?: string}\n if (stdout) ux.warn(stdout)\n if (stderr) ux.warn(stderr)\n }\n return {error: err, installedAgents: [], skipped: false}\n }\n}\n"],"names":["fileURLToPath","ux","subdebug","logSymbols","execa","getErrorMessage","toError","skillsDebug","SANITY_SKILLS_REPO","SANITY_SKILL_NAMES","SKILLS_BIN_PATH","resolve","url","setupSkills","options","uniqueAgents","Set","agents","length","installedAgents","skipped","args","flatMap","agent","process","execPath","join","result","stdio","timeout","stdout","stderr","success","error","err","warn"],"mappings":"AAAA,SAAQA,aAAa,QAAO,WAAU;AAEtC,SAAQC,EAAE,QAAO,cAAa;AAC9B,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,UAAU,QAAO,sBAAqB;AAC9C,SAAQC,KAAK,QAAO,QAAO;AAE3B,SAAQC,eAAe,EAAEC,OAAO,QAAO,gCAA+B;AAEtE,MAAMC,cAAcL,SAAS;AAE7B,wFAAwF,GACxF,OAAO,MAAMM,qBAAqB,0BAAyB;AAE3D,gFAAgF,GAChF,OAAO,MAAMC,qBAAqB;IAAC;IAAyB;CAAmB,CAAA;AAE/E;;;;CAIC,GACD,OAAO,MAAMC,kBAAkBV,cAC7B,YAAYW,OAAO,CAAC,sBAAsB,YAAYC,GAAG,GAC1D;AAeD;;;;CAIC,GACD,OAAO,eAAeC,YAAYC,OAA2B;IAC3D,MAAMC,eAAe;WAAI,IAAIC,IAAIF,QAAQG,MAAM;KAAE;IAEjD,IAAIF,aAAaG,MAAM,KAAK,GAAG;QAC7BX,YAAY;QACZ,OAAO;YAACY,iBAAiB,EAAE;YAAEC,SAAS;QAAI;IAC5C;IAEA,MAAMC,OAAO;QACXX;QACA;QACAF;QACA;WACGC;QACH;WACGM,aAAaO,OAAO,CAAC,CAACC,QAAU;gBAAC;gBAAMA;aAAM;QAChD;KACD;IAEDhB,YAAY,kBAAkBiB,QAAQC,QAAQ,EAAEJ,KAAKK,IAAI,CAAC;IAE1D,IAAI;QACF,MAAMC,SAAS,MAAMvB,MAAMoB,QAAQC,QAAQ,EAAEJ,MAAM;YAACO,OAAO;YAAQC,SAAS;QAAM;QAClFtB,YAAY,qBAAqBoB,OAAOG,MAAM;QAC9CvB,YAAY,qBAAqBoB,OAAOI,MAAM;QAC9C9B,GAAG6B,MAAM,CAAC,GAAG3B,WAAW6B,OAAO,CAAC,mCAAmC,EAAEjB,aAAaW,IAAI,CAAC,OAAO;QAC9F,OAAO;YAACP,iBAAiBJ;YAAcK,SAAS;QAAK;IACvD,EAAE,OAAOa,OAAO;QACd1B,YAAY,8BAA8B0B;QAC1C,MAAMC,MAAM5B,QAAQ2B;QACpBhC,GAAGkC,IAAI,CAAC,CAAC,uCAAuC,EAAE9B,gBAAgB4B,QAAQ;QAC1E,IAAIA,SAAS,OAAOA,UAAU,UAAU;YACtC,MAAM,EAACF,MAAM,EAAED,MAAM,EAAC,GAAGG;YACzB,IAAIH,QAAQ7B,GAAGkC,IAAI,CAACL;YACpB,IAAIC,QAAQ9B,GAAGkC,IAAI,CAACJ;QACtB;QACA,OAAO;YAACE,OAAOC;YAAKf,iBAAiB,EAAE;YAAEC,SAAS;QAAK;IACzD;AACF"}
|
package/dist/commands/init.js
CHANGED
|
@@ -4,7 +4,6 @@ import { SanityCommand } from '@sanity/cli-core';
|
|
|
4
4
|
import { initAction } from '../actions/init/initAction.js';
|
|
5
5
|
import { InitError } from '../actions/init/initError.js';
|
|
6
6
|
import { flagsToInitOptions } from '../actions/init/types.js';
|
|
7
|
-
import { getSanityEnv } from '../util/getSanityEnv.js';
|
|
8
7
|
export class InitCommand extends SanityCommand {
|
|
9
8
|
static args = {
|
|
10
9
|
type: Args.string({
|
|
@@ -244,15 +243,15 @@ export class InitCommand extends SanityCommand {
|
|
|
244
243
|
};
|
|
245
244
|
async run() {
|
|
246
245
|
let mcpMode = 'prompt';
|
|
247
|
-
if (!this.flags.mcp || !this.resolveIsInteractive()
|
|
246
|
+
if (!this.flags.mcp || !this.resolveIsInteractive()) {
|
|
248
247
|
mcpMode = 'skip';
|
|
249
248
|
} else if (this.flags.yes) {
|
|
250
249
|
mcpMode = 'auto';
|
|
251
250
|
}
|
|
252
|
-
// Mirror MCP's environment gating: skip
|
|
253
|
-
//
|
|
251
|
+
// Mirror MCP's environment gating: skip install in test environments
|
|
252
|
+
// ensure e2e / CI tests don't run the bundled skills CLI.
|
|
254
253
|
let skillsMode = 'auto';
|
|
255
|
-
if (!this.flags.skills || !this.resolveIsInteractive()
|
|
254
|
+
if (!this.flags.skills || !this.resolveIsInteractive()) {
|
|
256
255
|
skillsMode = 'skip';
|
|
257
256
|
}
|
|
258
257
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import {Args, Command, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {initAction} from '../actions/init/initAction.js'\nimport {InitError} from '../actions/init/initError.js'\nimport {flagsToInitOptions} from '../actions/init/types.js'\nimport {getSanityEnv} from '../util/getSanityEnv.js'\n\nexport class InitCommand extends SanityCommand<typeof InitCommand> {\n static override args = {type: Args.string({hidden: true})}\n static override description = 'Initialize a new Sanity Studio, project and/or app'\n static override enableJsonFlag = true\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {\n command: '<%= config.bin %> <%= command.id %> --dataset-default',\n description: 'Initialize a new project with a public dataset named \"production\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset production --output-path ~/myproj',\n description: 'Initialize a project with the given project ID and dataset to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset staging --template moviedb --output-path .',\n description:\n 'Initialize a project with the given project ID and dataset using the moviedb template to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project-name \"Movies Unlimited\" --dataset moviedb --visibility private --template moviedb --output-path /Users/espenh/movies-unlimited',\n description: 'Create a brand new project with name \"Movies Unlimited\"',\n },\n ] satisfies Array<Command.Example>\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable auto updates of studio versions',\n exclusive: ['bare'],\n }),\n bare: Flags.boolean({\n description:\n 'Skip the Studio initialization and only print the selected project ID and dataset name to stdout',\n }),\n coupon: Flags.string({\n description:\n 'Optionally select a coupon for a new project (cannot be used with --project-plan)',\n exclusive: ['project-plan'],\n helpValue: '<code>',\n }),\n 'create-project': Flags.string({\n deprecated: {message: 'Use --project-name instead'},\n description: 'Create a new project with the given name',\n helpValue: '<name>',\n hidden: true,\n }),\n dataset: Flags.string({\n description: 'Dataset name for the studio',\n exclusive: ['dataset-default'],\n helpValue: '<name>',\n }),\n 'dataset-default': Flags.boolean({\n description: 'Set up a project with a public dataset named \"production\"',\n }),\n env: Flags.string({\n description: 'Write environment variables to file',\n exclusive: ['bare'],\n helpValue: '<filename>',\n parse: async (input) => {\n if (!input.startsWith('.env')) {\n throw new CLIError('Env filename (`--env`) must start with `.env`')\n }\n return input\n },\n }),\n 'from-create': Flags.boolean({\n description: 'Internal flag to indicate that the command is run from create-sanity',\n hidden: true,\n }),\n git: Flags.string({\n default: undefined,\n description: 'Specify a commit message for initial commit, or disable git init',\n exclusive: ['bare'],\n // oclif doesn't indent correctly with custom help labels, thus leading space :/\n helpLabel: ' --[no-]git',\n helpValue: '<message>',\n }),\n 'import-dataset': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Import template sample dataset',\n }),\n mcp: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable AI editor integration (MCP) setup',\n }),\n 'nextjs-add-config-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Add config files to Next.js project',\n helpGroup: 'Next.js',\n }),\n 'nextjs-append-env': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Append project ID and dataset to .env file',\n helpGroup: 'Next.js',\n }),\n 'nextjs-embed-studio': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Embed the Studio in Next.js application',\n helpGroup: 'Next.js',\n }),\n // oclif doesn't support a boolean/string flag combination, but listing both a\n // `--git` and a `--no-git` flag in help breaks conventions, so we hide this one,\n // but use it to \"combine\" the two in the actual logic.\n 'no-git': Flags.boolean({\n description: 'Disable git initialization',\n exclusive: ['git'],\n hidden: true,\n }),\n organization: Flags.string({\n description: 'Organization ID to use for the project',\n helpValue: '<id>',\n }),\n 'output-path': Flags.string({\n description: 'Path to write studio project to',\n exclusive: ['bare'],\n helpValue: '<path>',\n }),\n 'overwrite-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Overwrite existing files',\n }),\n 'package-manager': Flags.string({\n description: 'Specify which package manager to use [allowed: npm, yarn, pnpm]',\n exclusive: ['bare'],\n helpValue: '<manager>',\n options: ['npm', 'yarn', 'pnpm'],\n }),\n project: Flags.string({\n aliases: ['project-id'],\n description: 'Project ID to use for the studio',\n exclusive: ['create-project', 'project-name'],\n helpValue: '<id>',\n }),\n 'project-name': Flags.string({\n description: 'Create a new project with the given name',\n exclusive: ['project', 'create-project'],\n helpValue: '<name>',\n }),\n 'project-plan': Flags.string({\n description: 'Optionally select a plan for a new project',\n helpValue: '<name>',\n }),\n provider: Flags.string({\n description: 'Login provider to use',\n helpValue: '<provider>',\n }),\n quickstart: Flags.boolean({\n deprecated: true,\n description:\n 'Used for initializing a project from a server schema that is saved in the Journey API',\n hidden: true,\n }),\n reconfigure: Flags.boolean({\n deprecated: {\n message: 'This flag is no longer supported',\n version: '3.0.0',\n },\n description: 'Reconfigure an existing project',\n hidden: true,\n }),\n skills: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Install Sanity agent skills globally for detected AI editors',\n }),\n template: Flags.string({\n description: 'Project template to use [default: \"clean\"]',\n exclusive: ['bare'],\n helpValue: '<template>',\n }),\n // Porting over a beta flag\n // Oclif doesn't seem to support something in beta so hiding for now\n 'template-token': Flags.string({\n description: 'Used for accessing private GitHub repo templates',\n hidden: true,\n }),\n typescript: Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Enable TypeScript support',\n exclusive: ['bare'],\n }),\n visibility: Flags.string({\n description: 'Visibility mode for dataset',\n helpValue: '<mode>',\n options: ['public', 'private'],\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n let mcpMode: 'auto' | 'prompt' | 'skip' = 'prompt'\n if (!this.flags.mcp || !this.resolveIsInteractive() || getSanityEnv() !== 'production') {\n mcpMode = 'skip'\n } else if (this.flags.yes) {\n mcpMode = 'auto'\n }\n\n // Mirror MCP's environment gating: skip skills install in non-production\n // Sanity envs so e2e / UI tests don't run the bundled skills CLI.\n let skillsMode: 'auto' | 'prompt' | 'skip' = 'auto'\n if (!this.flags.skills || !this.resolveIsInteractive() || getSanityEnv() !== 'production') {\n skillsMode = 'skip'\n }\n\n try {\n await initAction(\n flagsToInitOptions(this.flags, this.isUnattended(), this.args, mcpMode, skillsMode),\n {\n output: this.output,\n telemetry: this.telemetry,\n workDir: process.cwd(),\n },\n )\n } catch (error) {\n if (error instanceof InitError) {\n this.error(error.message, {exit: error.exitCode})\n }\n throw error\n }\n }\n}\n"],"names":["Args","Flags","CLIError","SanityCommand","initAction","InitError","flagsToInitOptions","getSanityEnv","InitCommand","args","type","string","hidden","description","enableJsonFlag","examples","command","flags","boolean","allowNo","default","exclusive","bare","coupon","helpValue","deprecated","message","dataset","env","parse","input","startsWith","git","undefined","helpLabel","mcp","helpGroup","organization","options","project","aliases","provider","quickstart","reconfigure","version","skills","template","typescript","visibility","yes","char","run","mcpMode","resolveIsInteractive","skillsMode","isUnattended","output","telemetry","workDir","process","cwd","error","exit","exitCode"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import {Args, Command, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {initAction} from '../actions/init/initAction.js'\nimport {InitError} from '../actions/init/initError.js'\nimport {flagsToInitOptions} from '../actions/init/types.js'\n\nexport class InitCommand extends SanityCommand<typeof InitCommand> {\n static override args = {type: Args.string({hidden: true})}\n static override description = 'Initialize a new Sanity Studio, project and/or app'\n static override enableJsonFlag = true\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {\n command: '<%= config.bin %> <%= command.id %> --dataset-default',\n description: 'Initialize a new project with a public dataset named \"production\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset production --output-path ~/myproj',\n description: 'Initialize a project with the given project ID and dataset to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset staging --template moviedb --output-path .',\n description:\n 'Initialize a project with the given project ID and dataset using the moviedb template to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project-name \"Movies Unlimited\" --dataset moviedb --visibility private --template moviedb --output-path /Users/espenh/movies-unlimited',\n description: 'Create a brand new project with name \"Movies Unlimited\"',\n },\n ] satisfies Array<Command.Example>\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable auto updates of studio versions',\n exclusive: ['bare'],\n }),\n bare: Flags.boolean({\n description:\n 'Skip the Studio initialization and only print the selected project ID and dataset name to stdout',\n }),\n coupon: Flags.string({\n description:\n 'Optionally select a coupon for a new project (cannot be used with --project-plan)',\n exclusive: ['project-plan'],\n helpValue: '<code>',\n }),\n 'create-project': Flags.string({\n deprecated: {message: 'Use --project-name instead'},\n description: 'Create a new project with the given name',\n helpValue: '<name>',\n hidden: true,\n }),\n dataset: Flags.string({\n description: 'Dataset name for the studio',\n exclusive: ['dataset-default'],\n helpValue: '<name>',\n }),\n 'dataset-default': Flags.boolean({\n description: 'Set up a project with a public dataset named \"production\"',\n }),\n env: Flags.string({\n description: 'Write environment variables to file',\n exclusive: ['bare'],\n helpValue: '<filename>',\n parse: async (input) => {\n if (!input.startsWith('.env')) {\n throw new CLIError('Env filename (`--env`) must start with `.env`')\n }\n return input\n },\n }),\n 'from-create': Flags.boolean({\n description: 'Internal flag to indicate that the command is run from create-sanity',\n hidden: true,\n }),\n git: Flags.string({\n default: undefined,\n description: 'Specify a commit message for initial commit, or disable git init',\n exclusive: ['bare'],\n // oclif doesn't indent correctly with custom help labels, thus leading space :/\n helpLabel: ' --[no-]git',\n helpValue: '<message>',\n }),\n 'import-dataset': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Import template sample dataset',\n }),\n mcp: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable AI editor integration (MCP) setup',\n }),\n 'nextjs-add-config-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Add config files to Next.js project',\n helpGroup: 'Next.js',\n }),\n 'nextjs-append-env': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Append project ID and dataset to .env file',\n helpGroup: 'Next.js',\n }),\n 'nextjs-embed-studio': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Embed the Studio in Next.js application',\n helpGroup: 'Next.js',\n }),\n // oclif doesn't support a boolean/string flag combination, but listing both a\n // `--git` and a `--no-git` flag in help breaks conventions, so we hide this one,\n // but use it to \"combine\" the two in the actual logic.\n 'no-git': Flags.boolean({\n description: 'Disable git initialization',\n exclusive: ['git'],\n hidden: true,\n }),\n organization: Flags.string({\n description: 'Organization ID to use for the project',\n helpValue: '<id>',\n }),\n 'output-path': Flags.string({\n description: 'Path to write studio project to',\n exclusive: ['bare'],\n helpValue: '<path>',\n }),\n 'overwrite-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Overwrite existing files',\n }),\n 'package-manager': Flags.string({\n description: 'Specify which package manager to use [allowed: npm, yarn, pnpm]',\n exclusive: ['bare'],\n helpValue: '<manager>',\n options: ['npm', 'yarn', 'pnpm'],\n }),\n project: Flags.string({\n aliases: ['project-id'],\n description: 'Project ID to use for the studio',\n exclusive: ['create-project', 'project-name'],\n helpValue: '<id>',\n }),\n 'project-name': Flags.string({\n description: 'Create a new project with the given name',\n exclusive: ['project', 'create-project'],\n helpValue: '<name>',\n }),\n 'project-plan': Flags.string({\n description: 'Optionally select a plan for a new project',\n helpValue: '<name>',\n }),\n provider: Flags.string({\n description: 'Login provider to use',\n helpValue: '<provider>',\n }),\n quickstart: Flags.boolean({\n deprecated: true,\n description:\n 'Used for initializing a project from a server schema that is saved in the Journey API',\n hidden: true,\n }),\n reconfigure: Flags.boolean({\n deprecated: {\n message: 'This flag is no longer supported',\n version: '3.0.0',\n },\n description: 'Reconfigure an existing project',\n hidden: true,\n }),\n skills: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Install Sanity agent skills globally for detected AI editors',\n }),\n template: Flags.string({\n description: 'Project template to use [default: \"clean\"]',\n exclusive: ['bare'],\n helpValue: '<template>',\n }),\n // Porting over a beta flag\n // Oclif doesn't seem to support something in beta so hiding for now\n 'template-token': Flags.string({\n description: 'Used for accessing private GitHub repo templates',\n hidden: true,\n }),\n typescript: Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Enable TypeScript support',\n exclusive: ['bare'],\n }),\n visibility: Flags.string({\n description: 'Visibility mode for dataset',\n helpValue: '<mode>',\n options: ['public', 'private'],\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n let mcpMode: 'auto' | 'prompt' | 'skip' = 'prompt'\n if (!this.flags.mcp || !this.resolveIsInteractive()) {\n mcpMode = 'skip'\n } else if (this.flags.yes) {\n mcpMode = 'auto'\n }\n\n // Mirror MCP's environment gating: skip install in test environments\n // ensure e2e / CI tests don't run the bundled skills CLI.\n let skillsMode: 'auto' | 'prompt' | 'skip' = 'auto'\n if (!this.flags.skills || !this.resolveIsInteractive()) {\n skillsMode = 'skip'\n }\n\n try {\n await initAction(\n flagsToInitOptions(this.flags, this.isUnattended(), this.args, mcpMode, skillsMode),\n {\n output: this.output,\n telemetry: this.telemetry,\n workDir: process.cwd(),\n },\n )\n } catch (error) {\n if (error instanceof InitError) {\n this.error(error.message, {exit: error.exitCode})\n }\n throw error\n }\n }\n}\n"],"names":["Args","Flags","CLIError","SanityCommand","initAction","InitError","flagsToInitOptions","InitCommand","args","type","string","hidden","description","enableJsonFlag","examples","command","flags","boolean","allowNo","default","exclusive","bare","coupon","helpValue","deprecated","message","dataset","env","parse","input","startsWith","git","undefined","helpLabel","mcp","helpGroup","organization","options","project","aliases","provider","quickstart","reconfigure","version","skills","template","typescript","visibility","yes","char","run","mcpMode","resolveIsInteractive","skillsMode","isUnattended","output","telemetry","workDir","process","cwd","error","exit","exitCode"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import {\n extendViteConfigWithUserConfig,\n getViteConfig,\n writeSanityRuntime,\n} from '@sanity/cli-build/_internal/build'\nimport {CliConfig, getCliTelemetry, type UserViteConfig} from '@sanity/cli-core'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {\n getAppEnvironmentVariables,\n getStudioEnvironmentVariables,\n} from '../actions/build/getEnvironmentVariables.js'\nimport {serverDebug} from './serverDebug.js'\nimport {sanityTypegenPlugin} from './vite/plugin-typegen.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: ReactCompilerConfig | undefined\n reactStrictMode: boolean\n\n staticPath: string\n\n appTitle?: string\n entry?: string\n httpHost?: string\n isApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n typegen?: CliConfig['typegen']\n vite?: UserViteConfig\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n appTitle,\n basePath,\n cwd,\n entry,\n httpHost,\n httpPort,\n isApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n typegen,\n vite: extendViteConfig,\n } = options\n\n debug('Writing Sanity runtime files')\n const watcher = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n function getEnvironmentVariables() {\n return isApp\n ? getAppEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n : getStudioEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n }\n\n let viteConfig: InlineConfig = await getViteConfig({\n additionalPlugins: [\n // Add typegen when enabled\n ...(typegen?.enabled\n ? [\n sanityTypegenPlugin({\n config: typegen,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n }),\n ]\n : []),\n ],\n basePath,\n cwd,\n getEnvironmentVariables,\n isApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n })\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","getCliTelemetry","createServer","getAppEnvironmentVariables","getStudioEnvironmentVariables","serverDebug","sanityTypegenPlugin","debug","extend","startDevServer","options","appTitle","basePath","cwd","entry","httpHost","httpPort","isApp","reactCompiler","reactStrictMode","schemaExtraction","typegen","vite","extendViteConfig","watcher","watch","mode","getEnvironmentVariables","jsonEncode","prefix","viteConfig","additionalPlugins","enabled","config","telemetryLogger","workDir","server","host","port","command","listen","close"],"mappings":"AAAA,SACEA,8BAA8B,EAC9BC,aAAa,EACbC,kBAAkB,QACb,oCAAmC;AAC1C,SAAmBC,eAAe,QAA4B,mBAAkB;AAGhF,SAAQC,YAAY,QAA8C,OAAM;AAExE,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,8CAA6C;AACpD,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,QAAQF,YAAYG,MAAM,CAAC;AA6BjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,GAAG,EACHC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,OAAO,EACPC,MAAMC,gBAAgB,EACvB,GAAGb;IAEJH,MAAM;IACN,MAAMiB,UAAU,MAAMxB,mBAAmB;QACvCW;QACAC;QACAC;QACAC;QACAG;QACAE;QACAM,OAAO;IACT;IAEAlB,MAAM;IACN,MAAMmB,OAAO;IAEb,SAASC;QACP,OAAOV,QACHd,2BAA2B;YAACyB,YAAY;YAAMC,QAAQ;QAAc,KACpEzB,8BAA8B;YAACwB,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAM/B,cAAc;QACjDgC,mBAAmB;YACjB,2BAA2B;eACvBV,SAASW,UACT;gBACE1B,oBAAoB;oBAClB2B,QAAQZ;oBACRa,iBAAiBjC;oBACjBkC,SAAStB;gBACX;aACD,GACD,EAAE;SACP;QACDD;QACAC;QACAc;QACAV;QACAS,MAAM;QACNR;QACAE;QACAgB,QAAQ;YAACC,MAAMtB;YAAUuB,MAAMtB;QAAQ;IACzC;IAEA,sDAAsD;IACtD,IAAIO,kBAAkB;QACpBO,aAAa,MAAMhC,+BACjB;YAACyC,SAAS;YAASb;QAAI,GACvBI,YACAP;IAEJ;IAEAhB,MAAM;IACN,MAAM6B,SAAS,MAAMlC,aAAa4B;IAElCvB,MAAM;IACN,MAAM6B,OAAOI,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAIjB,SAAS;gBACX,MAAMA,QAAQiB,KAAK;YACrB;YACA,MAAML,OAAOK,KAAK;QACpB;QACAL;QACAZ;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import {\n extendViteConfigWithUserConfig,\n getViteConfig,\n writeSanityRuntime,\n} from '@sanity/cli-build/_internal/build'\nimport {CliConfig, getCliTelemetry, type UserViteConfig} from '@sanity/cli-core'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {\n getAppEnvironmentVariables,\n getStudioEnvironmentVariables,\n} from '../actions/build/getEnvironmentVariables.js'\nimport {serverDebug} from './serverDebug.js'\nimport {sanityTypegenPlugin} from './vite/plugin-typegen.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: ReactCompilerConfig | undefined\n reactStrictMode: boolean | undefined\n\n staticPath: string\n\n appTitle?: string\n entry?: string\n httpHost?: string\n isApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n typegen?: CliConfig['typegen']\n vite?: UserViteConfig\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n appTitle,\n basePath,\n cwd,\n entry,\n httpHost,\n httpPort,\n isApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n typegen,\n vite: extendViteConfig,\n } = options\n\n debug('Writing Sanity runtime files')\n const watcher = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n function getEnvironmentVariables() {\n return isApp\n ? getAppEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n : getStudioEnvironmentVariables({jsonEncode: true, prefix: 'process.env.'})\n }\n\n let viteConfig: InlineConfig = await getViteConfig({\n additionalPlugins: [\n // Add typegen when enabled\n ...(typegen?.enabled\n ? [\n sanityTypegenPlugin({\n config: typegen,\n telemetryLogger: getCliTelemetry(),\n workDir: cwd,\n }),\n ]\n : []),\n ],\n basePath,\n cwd,\n getEnvironmentVariables,\n isApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n })\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","getCliTelemetry","createServer","getAppEnvironmentVariables","getStudioEnvironmentVariables","serverDebug","sanityTypegenPlugin","debug","extend","startDevServer","options","appTitle","basePath","cwd","entry","httpHost","httpPort","isApp","reactCompiler","reactStrictMode","schemaExtraction","typegen","vite","extendViteConfig","watcher","watch","mode","getEnvironmentVariables","jsonEncode","prefix","viteConfig","additionalPlugins","enabled","config","telemetryLogger","workDir","server","host","port","command","listen","close"],"mappings":"AAAA,SACEA,8BAA8B,EAC9BC,aAAa,EACbC,kBAAkB,QACb,oCAAmC;AAC1C,SAAmBC,eAAe,QAA4B,mBAAkB;AAGhF,SAAQC,YAAY,QAA8C,OAAM;AAExE,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,8CAA6C;AACpD,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,QAAQF,YAAYG,MAAM,CAAC;AA6BjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,GAAG,EACHC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,OAAO,EACPC,MAAMC,gBAAgB,EACvB,GAAGb;IAEJH,MAAM;IACN,MAAMiB,UAAU,MAAMxB,mBAAmB;QACvCW;QACAC;QACAC;QACAC;QACAG;QACAE;QACAM,OAAO;IACT;IAEAlB,MAAM;IACN,MAAMmB,OAAO;IAEb,SAASC;QACP,OAAOV,QACHd,2BAA2B;YAACyB,YAAY;YAAMC,QAAQ;QAAc,KACpEzB,8BAA8B;YAACwB,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAM/B,cAAc;QACjDgC,mBAAmB;YACjB,2BAA2B;eACvBV,SAASW,UACT;gBACE1B,oBAAoB;oBAClB2B,QAAQZ;oBACRa,iBAAiBjC;oBACjBkC,SAAStB;gBACX;aACD,GACD,EAAE;SACP;QACDD;QACAC;QACAc;QACAV;QACAS,MAAM;QACNR;QACAE;QACAgB,QAAQ;YAACC,MAAMtB;YAAUuB,MAAMtB;QAAQ;IACzC;IAEA,sDAAsD;IACtD,IAAIO,kBAAkB;QACpBO,aAAa,MAAMhC,+BACjB;YAACyC,SAAS;YAASb;QAAI,GACvBI,YACAP;IAEJ;IAEAhB,MAAM;IACN,MAAM6B,SAAS,MAAMlC,aAAa4B;IAElCvB,MAAM;IACN,MAAM6B,OAAOI,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAIjB,SAAS;gBACX,MAAMA,QAAQiB,KAAK;YACrB;YACA,MAAML,OAAOK,KAAK;QACpB;QACAL;QACAZ;IACF;AACF"}
|
|
@@ -3,9 +3,9 @@ import { getPartialEnvWithNpmPath } from './packageManagerChoice.js';
|
|
|
3
3
|
/**
|
|
4
4
|
* Resolves the peer dependencies of a package by querying the npm registry.
|
|
5
5
|
*
|
|
6
|
-
* @param packageName - Package name with version (e.g. "next-sanity\@
|
|
6
|
+
* @param packageName - Package name with version (e.g. "next-sanity\@13")
|
|
7
7
|
* @param cwd - Working directory (used to resolve local npm paths)
|
|
8
|
-
* @returns Array of peer dependency strings (e.g. ["next\@^
|
|
8
|
+
* @returns Array of peer dependency strings (e.g. ["next\@^16.0.0", "react\@^19.0.0"])
|
|
9
9
|
*/ export async function getPeerDependencies(packageName, cwd) {
|
|
10
10
|
let stdout;
|
|
11
11
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/util/packageManager/getPeerDependencies.ts"],"sourcesContent":["import {execa} from 'execa'\n\nimport {getPartialEnvWithNpmPath} from './packageManagerChoice.js'\n\n/**\n * Resolves the peer dependencies of a package by querying the npm registry.\n *\n * @param packageName - Package name with version (e.g. \"next-sanity\\@
|
|
1
|
+
{"version":3,"sources":["../../../src/util/packageManager/getPeerDependencies.ts"],"sourcesContent":["import {execa} from 'execa'\n\nimport {getPartialEnvWithNpmPath} from './packageManagerChoice.js'\n\n/**\n * Resolves the peer dependencies of a package by querying the npm registry.\n *\n * @param packageName - Package name with version (e.g. \"next-sanity\\@13\")\n * @param cwd - Working directory (used to resolve local npm paths)\n * @returns Array of peer dependency strings (e.g. [\"next\\@^16.0.0\", \"react\\@^19.0.0\"])\n */\nexport async function getPeerDependencies(packageName: string, cwd: string): Promise<string[]> {\n let stdout: string\n try {\n const result = await execa('npm', ['view', packageName, 'peerDependencies', '--json'], {\n cwd,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(cwd),\n })\n stdout = result.stdout\n } catch (error) {\n throw new Error(`Failed to resolve peer dependencies for ${packageName}`, {cause: error})\n }\n\n if (!stdout.trim()) {\n return []\n }\n\n try {\n const peerDeps: Record<string, string> | null = JSON.parse(stdout)\n if (!peerDeps || typeof peerDeps !== 'object') {\n return []\n }\n return Object.entries(peerDeps).map(([name, range]) => `${name}@${range}`)\n } catch (error) {\n throw new Error(`Failed to resolve peer dependencies for ${packageName}`, {cause: error})\n }\n}\n"],"names":["execa","getPartialEnvWithNpmPath","getPeerDependencies","packageName","cwd","stdout","result","encoding","env","error","Error","cause","trim","peerDeps","JSON","parse","Object","entries","map","name","range"],"mappings":"AAAA,SAAQA,KAAK,QAAO,QAAO;AAE3B,SAAQC,wBAAwB,QAAO,4BAA2B;AAElE;;;;;;CAMC,GACD,OAAO,eAAeC,oBAAoBC,WAAmB,EAAEC,GAAW;IACxE,IAAIC;IACJ,IAAI;QACF,MAAMC,SAAS,MAAMN,MAAM,OAAO;YAAC;YAAQG;YAAa;YAAoB;SAAS,EAAE;YACrFC;YACAG,UAAU;YACVC,KAAKP,yBAAyBG;QAChC;QACAC,SAASC,OAAOD,MAAM;IACxB,EAAE,OAAOI,OAAO;QACd,MAAM,IAAIC,MAAM,CAAC,wCAAwC,EAAEP,aAAa,EAAE;YAACQ,OAAOF;QAAK;IACzF;IAEA,IAAI,CAACJ,OAAOO,IAAI,IAAI;QAClB,OAAO,EAAE;IACX;IAEA,IAAI;QACF,MAAMC,WAA0CC,KAAKC,KAAK,CAACV;QAC3D,IAAI,CAACQ,YAAY,OAAOA,aAAa,UAAU;YAC7C,OAAO,EAAE;QACX;QACA,OAAOG,OAAOC,OAAO,CAACJ,UAAUK,GAAG,CAAC,CAAC,CAACC,MAAMC,MAAM,GAAK,GAAGD,KAAK,CAAC,EAAEC,OAAO;IAC3E,EAAE,OAAOX,OAAO;QACd,MAAM,IAAIC,MAAM,CAAC,wCAAwC,EAAEP,aAAa,EAAE;YAACQ,OAAOF;QAAK;IACzF;AACF"}
|
|
@@ -37,12 +37,50 @@ const PACKAGE_MANAGER_COMMANDS = {
|
|
|
37
37
|
]
|
|
38
38
|
}
|
|
39
39
|
};
|
|
40
|
+
const IGNORED_BUILDS_NOTICE = 'pnpm skipped build scripts for some dependencies. Run "pnpm approve-builds" in the project directory to pick which dependencies should be allowed to run scripts.';
|
|
41
|
+
// Matches pnpm's `ERR_PNPM_IGNORED_BUILDS` error against whitespace-normalized
|
|
42
|
+
// output (pnpm may wrap the message), capturing the list of skipped packages,
|
|
43
|
+
// eg `esbuild@0.25.0, sharp@0.34.0.` - the `<pkg>@<version>` token sequence
|
|
44
|
+
// ends the capture where the trailing `Run "pnpm approve-builds"…` hint starts
|
|
45
|
+
const IGNORED_BUILDS_PATTERN = /ERR_PNPM_IGNORED_BUILDS.*?Ignored build scripts: ?((?:[^\s,]+@[^\s,]+[, ]*)+)/;
|
|
46
|
+
function getIgnoredBuildScripts(commandOutput) {
|
|
47
|
+
const match = commandOutput.replaceAll(/\s+/g, ' ').match(IGNORED_BUILDS_PATTERN);
|
|
48
|
+
if (!match) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
// The capture allows both comma and whitespace separators (pnpm may print
|
|
52
|
+
// either, and wrapping can drop the comma), so split on both.
|
|
53
|
+
return match[1].split(/[\s,]+/).map((entry)=>entry.replace(/\.$/, '')).filter(Boolean);
|
|
54
|
+
}
|
|
55
|
+
function isEsbuild(ignoredEntry) {
|
|
56
|
+
// Entries are on the form `<pkg-name>@<version>` - strip the version,
|
|
57
|
+
// keeping in mind that scoped package names also start with `@`
|
|
58
|
+
return ignoredEntry.replace(/@[^@]+$/, '') === 'esbuild';
|
|
59
|
+
}
|
|
40
60
|
async function executePackageManagerCommand(packageManager, args, execOptions, output, errorMessage) {
|
|
41
61
|
const progress = spinner(`Running ${packageManager} ${args.join(' ')}\n`).start();
|
|
42
62
|
const result = await execa(packageManager, args, execOptions);
|
|
43
63
|
if (result?.exitCode || result?.failed) {
|
|
64
|
+
// pnpm exits non-zero if dependency build scripts were skipped, even though
|
|
65
|
+
// the install itself succeeded. Treat it as a success, but point to
|
|
66
|
+
// `pnpm approve-builds` if anything other than esbuild was skipped
|
|
67
|
+
// (esbuild works without its build script through a JS fallback).
|
|
68
|
+
const commandOutput = [
|
|
69
|
+
result.stdout,
|
|
70
|
+
result.stderr
|
|
71
|
+
].filter((chunk)=>typeof chunk === 'string').join('\n');
|
|
72
|
+
const ignoredBuilds = packageManager === 'pnpm' ? getIgnoredBuildScripts(commandOutput) : undefined;
|
|
73
|
+
if (ignoredBuilds) {
|
|
74
|
+
progress.succeed();
|
|
75
|
+
if (ignoredBuilds.some((entry)=>!isEsbuild(entry))) {
|
|
76
|
+
output.warn(IGNORED_BUILDS_NOTICE);
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
44
80
|
progress.fail();
|
|
45
|
-
|
|
81
|
+
// Log both streams - package managers often print the actionable error
|
|
82
|
+
// details to stderr, so logging stdout alone can hide the failure reason.
|
|
83
|
+
output.log(commandOutput);
|
|
46
84
|
output.error(errorMessage, {
|
|
47
85
|
exit: 1
|
|
48
86
|
});
|
|
@@ -56,6 +94,7 @@ export async function installDeclaredPackages(cwd, packageManager, context) {
|
|
|
56
94
|
cwd,
|
|
57
95
|
encoding: 'utf8',
|
|
58
96
|
env: getPartialEnvWithNpmPath(cwd),
|
|
97
|
+
reject: false,
|
|
59
98
|
stdio: 'pipe'
|
|
60
99
|
};
|
|
61
100
|
if (packageManager === 'manual') {
|
|
@@ -73,6 +112,7 @@ export async function installNewPackages(options, context) {
|
|
|
73
112
|
cwd: workDir,
|
|
74
113
|
encoding: 'utf8',
|
|
75
114
|
env: getPartialEnvWithNpmPath(workDir),
|
|
115
|
+
reject: false,
|
|
76
116
|
stdio: 'pipe'
|
|
77
117
|
};
|
|
78
118
|
if (packageManager === 'manual') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/util/packageManager/installPackages.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {execa, type Options} from 'execa'\n\nimport {getPartialEnvWithNpmPath, type PackageManager} from './packageManagerChoice.js'\n\ntype PackageManagerLibs = Exclude<PackageManager, 'manual'>\n\n/**\n * @internal\n */\ninterface InstallOptions {\n packageManager: PackageManager\n packages: string[]\n}\n\ninterface PackageManagerCommands {\n add: {[key in PackageManagerLibs]: (packages: string[]) => string[]}\n install: {[key in PackageManagerLibs]: string[]}\n}\n\nconst PACKAGE_MANAGER_COMMANDS: PackageManagerCommands = {\n add: {\n bun: (packages) => ['add', ...packages],\n npm: (packages) => ['install', '--save', ...packages],\n pnpm: (packages) => ['add', '--save-prod', ...packages],\n yarn: (packages) => ['add', ...packages],\n },\n install: {\n bun: ['install'],\n npm: ['install'],\n pnpm: ['install'],\n yarn: ['install'],\n },\n}\n\nasync function executePackageManagerCommand(\n packageManager: PackageManagerLibs,\n args: string[],\n execOptions: Options,\n output: Output,\n errorMessage: string,\n): Promise<void> {\n const progress = spinner(`Running ${packageManager} ${args.join(' ')}\\n`).start()\n\n const result = await execa(packageManager, args, execOptions)\n\n if (result?.exitCode || result?.failed) {\n progress.fail()\n output.log(
|
|
1
|
+
{"version":3,"sources":["../../../src/util/packageManager/installPackages.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {execa, type Options} from 'execa'\n\nimport {getPartialEnvWithNpmPath, type PackageManager} from './packageManagerChoice.js'\n\ntype PackageManagerLibs = Exclude<PackageManager, 'manual'>\n\n/**\n * @internal\n */\ninterface InstallOptions {\n packageManager: PackageManager\n packages: string[]\n}\n\ninterface PackageManagerCommands {\n add: {[key in PackageManagerLibs]: (packages: string[]) => string[]}\n install: {[key in PackageManagerLibs]: string[]}\n}\n\nconst PACKAGE_MANAGER_COMMANDS: PackageManagerCommands = {\n add: {\n bun: (packages) => ['add', ...packages],\n npm: (packages) => ['install', '--save', ...packages],\n pnpm: (packages) => ['add', '--save-prod', ...packages],\n yarn: (packages) => ['add', ...packages],\n },\n install: {\n bun: ['install'],\n npm: ['install'],\n pnpm: ['install'],\n yarn: ['install'],\n },\n}\n\nconst IGNORED_BUILDS_NOTICE =\n 'pnpm skipped build scripts for some dependencies. Run \"pnpm approve-builds\" in the project directory to pick which dependencies should be allowed to run scripts.'\n\n// Matches pnpm's `ERR_PNPM_IGNORED_BUILDS` error against whitespace-normalized\n// output (pnpm may wrap the message), capturing the list of skipped packages,\n// eg `esbuild@0.25.0, sharp@0.34.0.` - the `<pkg>@<version>` token sequence\n// ends the capture where the trailing `Run \"pnpm approve-builds\"…` hint starts\nconst IGNORED_BUILDS_PATTERN =\n /ERR_PNPM_IGNORED_BUILDS.*?Ignored build scripts: ?((?:[^\\s,]+@[^\\s,]+[, ]*)+)/\n\nfunction getIgnoredBuildScripts(commandOutput: string): string[] | undefined {\n const match = commandOutput.replaceAll(/\\s+/g, ' ').match(IGNORED_BUILDS_PATTERN)\n if (!match) {\n return undefined\n }\n\n // The capture allows both comma and whitespace separators (pnpm may print\n // either, and wrapping can drop the comma), so split on both.\n return match[1]\n .split(/[\\s,]+/)\n .map((entry) => entry.replace(/\\.$/, ''))\n .filter(Boolean)\n}\n\nfunction isEsbuild(ignoredEntry: string): boolean {\n // Entries are on the form `<pkg-name>@<version>` - strip the version,\n // keeping in mind that scoped package names also start with `@`\n return ignoredEntry.replace(/@[^@]+$/, '') === 'esbuild'\n}\n\nasync function executePackageManagerCommand(\n packageManager: PackageManagerLibs,\n args: string[],\n execOptions: Options,\n output: Output,\n errorMessage: string,\n): Promise<void> {\n const progress = spinner(`Running ${packageManager} ${args.join(' ')}\\n`).start()\n\n const result = await execa(packageManager, args, execOptions)\n\n if (result?.exitCode || result?.failed) {\n // pnpm exits non-zero if dependency build scripts were skipped, even though\n // the install itself succeeded. Treat it as a success, but point to\n // `pnpm approve-builds` if anything other than esbuild was skipped\n // (esbuild works without its build script through a JS fallback).\n const commandOutput = [result.stdout, result.stderr]\n .filter((chunk): chunk is string => typeof chunk === 'string')\n .join('\\n')\n const ignoredBuilds =\n packageManager === 'pnpm' ? getIgnoredBuildScripts(commandOutput) : undefined\n\n if (ignoredBuilds) {\n progress.succeed()\n if (ignoredBuilds.some((entry) => !isEsbuild(entry))) {\n output.warn(IGNORED_BUILDS_NOTICE)\n }\n return\n }\n\n progress.fail()\n // Log both streams - package managers often print the actionable error\n // details to stderr, so logging stdout alone can hide the failure reason.\n output.log(commandOutput)\n output.error(errorMessage, {exit: 1})\n } else {\n progress.succeed()\n }\n}\n\nexport async function installDeclaredPackages(\n cwd: string,\n packageManager: PackageManager,\n context: {output: Output; workDir: string},\n): Promise<void> {\n const {output} = context\n const execOptions: Options = {\n cwd,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(cwd),\n reject: false,\n stdio: 'pipe',\n }\n\n if (packageManager === 'manual') {\n const npmCommand = PACKAGE_MANAGER_COMMANDS.install.npm\n output.log(`Manual installation selected — run 'npm ${npmCommand.join(' ')}' or equivalent`)\n } else {\n const args = PACKAGE_MANAGER_COMMANDS.install[packageManager]\n await executePackageManagerCommand(\n packageManager,\n args,\n execOptions,\n output,\n 'Dependency installation failed',\n )\n }\n}\n\nexport async function installNewPackages(\n options: InstallOptions,\n context: {output: Output; workDir: string},\n): Promise<void> {\n const {packageManager, packages} = options\n const {output, workDir} = context\n const execOptions: Options = {\n cwd: workDir,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(workDir),\n reject: false,\n stdio: 'pipe',\n }\n\n if (packageManager === 'manual') {\n const npmCommand = PACKAGE_MANAGER_COMMANDS.add.npm(packages)\n output.log(`Manual installation selected - run 'npm ${npmCommand.join(' ')}' or equivalent`)\n } else {\n const args = PACKAGE_MANAGER_COMMANDS.add[packageManager](packages)\n await executePackageManagerCommand(\n packageManager,\n args,\n execOptions,\n output,\n 'Package installation failed',\n )\n }\n}\n"],"names":["spinner","execa","getPartialEnvWithNpmPath","PACKAGE_MANAGER_COMMANDS","add","bun","packages","npm","pnpm","yarn","install","IGNORED_BUILDS_NOTICE","IGNORED_BUILDS_PATTERN","getIgnoredBuildScripts","commandOutput","match","replaceAll","undefined","split","map","entry","replace","filter","Boolean","isEsbuild","ignoredEntry","executePackageManagerCommand","packageManager","args","execOptions","output","errorMessage","progress","join","start","result","exitCode","failed","stdout","stderr","chunk","ignoredBuilds","succeed","some","warn","fail","log","error","exit","installDeclaredPackages","cwd","context","encoding","env","reject","stdio","npmCommand","installNewPackages","options","workDir"],"mappings":"AACA,SAAQA,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,KAAK,QAAqB,QAAO;AAEzC,SAAQC,wBAAwB,QAA4B,4BAA2B;AAiBvF,MAAMC,2BAAmD;IACvDC,KAAK;QACHC,KAAK,CAACC,WAAa;gBAAC;mBAAUA;aAAS;QACvCC,KAAK,CAACD,WAAa;gBAAC;gBAAW;mBAAaA;aAAS;QACrDE,MAAM,CAACF,WAAa;gBAAC;gBAAO;mBAAkBA;aAAS;QACvDG,MAAM,CAACH,WAAa;gBAAC;mBAAUA;aAAS;IAC1C;IACAI,SAAS;QACPL,KAAK;YAAC;SAAU;QAChBE,KAAK;YAAC;SAAU;QAChBC,MAAM;YAAC;SAAU;QACjBC,MAAM;YAAC;SAAU;IACnB;AACF;AAEA,MAAME,wBACJ;AAEF,+EAA+E;AAC/E,8EAA8E;AAC9E,4EAA4E;AAC5E,+EAA+E;AAC/E,MAAMC,yBACJ;AAEF,SAASC,uBAAuBC,aAAqB;IACnD,MAAMC,QAAQD,cAAcE,UAAU,CAAC,QAAQ,KAAKD,KAAK,CAACH;IAC1D,IAAI,CAACG,OAAO;QACV,OAAOE;IACT;IAEA,0EAA0E;IAC1E,8DAA8D;IAC9D,OAAOF,KAAK,CAAC,EAAE,CACZG,KAAK,CAAC,UACNC,GAAG,CAAC,CAACC,QAAUA,MAAMC,OAAO,CAAC,OAAO,KACpCC,MAAM,CAACC;AACZ;AAEA,SAASC,UAAUC,YAAoB;IACrC,sEAAsE;IACtE,gEAAgE;IAChE,OAAOA,aAAaJ,OAAO,CAAC,WAAW,QAAQ;AACjD;AAEA,eAAeK,6BACbC,cAAkC,EAClCC,IAAc,EACdC,WAAoB,EACpBC,MAAc,EACdC,YAAoB;IAEpB,MAAMC,WAAWhC,QAAQ,CAAC,QAAQ,EAAE2B,eAAe,CAAC,EAAEC,KAAKK,IAAI,CAAC,KAAK,EAAE,CAAC,EAAEC,KAAK;IAE/E,MAAMC,SAAS,MAAMlC,MAAM0B,gBAAgBC,MAAMC;IAEjD,IAAIM,QAAQC,YAAYD,QAAQE,QAAQ;QACtC,4EAA4E;QAC5E,oEAAoE;QACpE,mEAAmE;QACnE,kEAAkE;QAClE,MAAMvB,gBAAgB;YAACqB,OAAOG,MAAM;YAAEH,OAAOI,MAAM;SAAC,CACjDjB,MAAM,CAAC,CAACkB,QAA2B,OAAOA,UAAU,UACpDP,IAAI,CAAC;QACR,MAAMQ,gBACJd,mBAAmB,SAASd,uBAAuBC,iBAAiBG;QAEtE,IAAIwB,eAAe;YACjBT,SAASU,OAAO;YAChB,IAAID,cAAcE,IAAI,CAAC,CAACvB,QAAU,CAACI,UAAUJ,SAAS;gBACpDU,OAAOc,IAAI,CAACjC;YACd;YACA;QACF;QAEAqB,SAASa,IAAI;QACb,uEAAuE;QACvE,0EAA0E;QAC1Ef,OAAOgB,GAAG,CAAChC;QACXgB,OAAOiB,KAAK,CAAChB,cAAc;YAACiB,MAAM;QAAC;IACrC,OAAO;QACLhB,SAASU,OAAO;IAClB;AACF;AAEA,OAAO,eAAeO,wBACpBC,GAAW,EACXvB,cAA8B,EAC9BwB,OAA0C;IAE1C,MAAM,EAACrB,MAAM,EAAC,GAAGqB;IACjB,MAAMtB,cAAuB;QAC3BqB;QACAE,UAAU;QACVC,KAAKnD,yBAAyBgD;QAC9BI,QAAQ;QACRC,OAAO;IACT;IAEA,IAAI5B,mBAAmB,UAAU;QAC/B,MAAM6B,aAAarD,yBAAyBO,OAAO,CAACH,GAAG;QACvDuB,OAAOgB,GAAG,CAAC,CAAC,wCAAwC,EAAEU,WAAWvB,IAAI,CAAC,KAAK,eAAe,CAAC;IAC7F,OAAO;QACL,MAAML,OAAOzB,yBAAyBO,OAAO,CAACiB,eAAe;QAC7D,MAAMD,6BACJC,gBACAC,MACAC,aACAC,QACA;IAEJ;AACF;AAEA,OAAO,eAAe2B,mBACpBC,OAAuB,EACvBP,OAA0C;IAE1C,MAAM,EAACxB,cAAc,EAAErB,QAAQ,EAAC,GAAGoD;IACnC,MAAM,EAAC5B,MAAM,EAAE6B,OAAO,EAAC,GAAGR;IAC1B,MAAMtB,cAAuB;QAC3BqB,KAAKS;QACLP,UAAU;QACVC,KAAKnD,yBAAyByD;QAC9BL,QAAQ;QACRC,OAAO;IACT;IAEA,IAAI5B,mBAAmB,UAAU;QAC/B,MAAM6B,aAAarD,yBAAyBC,GAAG,CAACG,GAAG,CAACD;QACpDwB,OAAOgB,GAAG,CAAC,CAAC,wCAAwC,EAAEU,WAAWvB,IAAI,CAAC,KAAK,eAAe,CAAC;IAC7F,OAAO;QACL,MAAML,OAAOzB,yBAAyBC,GAAG,CAACuB,eAAe,CAACrB;QAC1D,MAAMoB,6BACJC,gBACAC,MACAC,aACAC,QACA;IAEJ;AACF"}
|