@sanity/cli 8.0.2 → 8.1.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.
Files changed (66) hide show
  1. package/README.md +4 -4
  2. package/dist/SanityHelp.js.map +1 -1
  3. package/dist/actions/backup/assertDatasetExist.js +2 -1
  4. package/dist/actions/backup/assertDatasetExist.js.map +1 -1
  5. package/dist/actions/build/buildStudio.js +3 -2
  6. package/dist/actions/build/buildStudio.js.map +1 -1
  7. package/dist/actions/build/eventListenerFactory.js +7 -6
  8. package/dist/actions/build/eventListenerFactory.js.map +1 -1
  9. package/dist/actions/build/shouldAutoUpdate.js +2 -1
  10. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  11. package/dist/actions/cors/filterAndValidateOrigin.js +3 -2
  12. package/dist/actions/cors/filterAndValidateOrigin.js.map +1 -1
  13. package/dist/actions/deploy/createUserApplication.js +2 -1
  14. package/dist/actions/deploy/createUserApplication.js.map +1 -1
  15. package/dist/actions/deploy/deployRunner.js +3 -2
  16. package/dist/actions/deploy/deployRunner.js.map +1 -1
  17. package/dist/actions/deploy/deployStudio.js +3 -3
  18. package/dist/actions/deploy/deployStudio.js.map +1 -1
  19. package/dist/actions/deploy/findUserApplication.js +8 -7
  20. package/dist/actions/deploy/findUserApplication.js.map +1 -1
  21. package/dist/actions/dev/servers/startAppDevServer.js +2 -1
  22. package/dist/actions/dev/servers/startAppDevServer.js.map +1 -1
  23. package/dist/actions/dev/servers/startStudioDevServer.js +3 -3
  24. package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
  25. package/dist/actions/documents/validate.js +5 -2
  26. package/dist/actions/documents/validate.js.map +1 -1
  27. package/dist/actions/init/env/createOrAppendEnvVars.js +2 -1
  28. package/dist/actions/init/env/createOrAppendEnvVars.js.map +1 -1
  29. package/dist/actions/init/env/parseAndUpdateEnvVars.js +2 -2
  30. package/dist/actions/init/env/parseAndUpdateEnvVars.js.map +1 -1
  31. package/dist/actions/init/sdkAppDependencies.js +2 -2
  32. package/dist/actions/init/sdkAppDependencies.js.map +1 -1
  33. package/dist/actions/init/studioDependencies.js +2 -2
  34. package/dist/actions/init/studioDependencies.js.map +1 -1
  35. package/dist/actions/scaffold/scaffoldProject.js +11 -6
  36. package/dist/actions/scaffold/scaffoldProject.js.map +1 -1
  37. package/dist/actions/schema/extractSchema.js +2 -2
  38. package/dist/actions/schema/extractSchema.js.map +1 -1
  39. package/dist/actions/schema/extractSchemaWatcher.js +2 -1
  40. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
  41. package/dist/actions/undeploy/runUndeploy.js +2 -2
  42. package/dist/actions/undeploy/runUndeploy.js.map +1 -1
  43. package/dist/commands/backups/list.js +5 -8
  44. package/dist/commands/backups/list.js.map +1 -1
  45. package/dist/commands/datasets/copy.js +5 -7
  46. package/dist/commands/datasets/copy.js.map +1 -1
  47. package/dist/commands/docs/search.js +2 -2
  48. package/dist/commands/docs/search.js.map +1 -1
  49. package/dist/commands/mcp/configure.js +2 -2
  50. package/dist/commands/mcp/configure.js.map +1 -1
  51. package/dist/commands/new.js +1 -2
  52. package/dist/commands/new.js.map +1 -1
  53. package/dist/commands/typegen/generate.js +6 -6
  54. package/dist/commands/typegen/generate.js.map +1 -1
  55. package/dist/services/assets.js +1 -1
  56. package/dist/services/assets.js.map +1 -1
  57. package/dist/services/mintProject.js +27 -3
  58. package/dist/services/mintProject.js.map +1 -1
  59. package/dist/util/appId.js +2 -1
  60. package/dist/util/appId.js.map +1 -1
  61. package/dist/util/dates.js +125 -0
  62. package/dist/util/dates.js.map +1 -0
  63. package/dist/util/getCliVersion.js +1 -11
  64. package/dist/util/getCliVersion.js.map +1 -1
  65. package/oclif.manifest.json +2 -2
  66. package/package.json +5 -8
package/README.md CHANGED
@@ -3035,10 +3035,10 @@ DESCRIPTION
3035
3035
  the deadline and the project and its content are deleted.
3036
3036
 
3037
3037
  Two things to keep private: the claim link, because anyone who opens it
3038
- becomes the owner, and the access token saved in ./sanity/.env.local and
3039
- ./web/.env.local, because it can read and change everything in the project.
3040
- Keep both env files out of git, and never put the token in code that runs in
3041
- the browser.
3038
+ becomes the owner, and the access token saved in ./sanity/.env.local, because
3039
+ it can read and change everything in the project. ./web/.env.local has only
3040
+ the project ID and dataset. Keep both env files out of git, and never put the
3041
+ token in code that runs in the browser.
3042
3042
 
3043
3043
  Run this command with --instructions for the full agent setup guide.
3044
3044
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/SanityHelp.ts"],"sourcesContent":["import {Command, CommandHelp, Help, Interfaces} from '@oclif/core'\nimport {getBinCommand, getRunningPackageManager} from '@sanity/cli-core/package-manager'\n\nimport {resolveTopicAliasInArgv} from './topicAliases.js'\n\n// Running `oclif readme`, we don't want to apply the `prefixBinName` transformation,\n// as it will include whatever pm was used to spawn the script in the generated readme.\n// argv will contain something like [nodeBinPath, oclifBinPath, 'readme', …] so check\n// for 'readme' with a preceeding argument that includes 'oclif' to be sure.\nconst IS_README_GENERATION = (process.argv[process.argv.indexOf('readme') - 1] ?? '').includes(\n 'oclif',\n)\n\n/**\n * Custom Help class for Sanity CLI that overrides the default help formatting to\n * prefix the bin name (e.g., `npx sanity`, `yarn sanity`, etc.) in the help text,\n * and to replace `sanity init` references with the appropriate `create` command\n * for the detected package manager when needed.\n *\n * @internal\n */\nexport default class SanityHelp extends Help {\n protected formatCommand(command: Command.Loadable): string {\n let help = super.formatCommand(command)\n\n // When `sanity init` is called, but originates from the `create-sanity`\n // package/binary (eg the one used by `npm create sanity@latest` etc), we want to\n // customize the help text to show that command instead of `sanity init`.\n const isFromCreate = process.argv.includes('--from-create') && command.id === 'init'\n if (isFromCreate) {\n help = replaceInitWithCreateCommand(help)\n }\n\n return prefixBinName(help)\n }\n\n protected formatRoot(): string {\n return prefixBinName(super.formatRoot())\n }\n\n protected formatTopic(topic: Interfaces.Topic): string {\n return prefixBinName(super.formatTopic(topic))\n }\n\n protected override getCommandHelpClass(command: Command.Loadable): CommandHelp {\n const commandHelp = super.getCommandHelpClass(command)\n if (command.id === 'login') {\n commandHelp.opts = {...commandHelp.opts, flagSortOrder: 'none'}\n }\n return commandHelp\n }\n\n async showHelp(argv: string[]): Promise<void> {\n return super.showHelp(resolveTopicAliasInArgv(argv))\n }\n}\n\n/**\n * @internal\n */\nexport function prefixBinName(help: string): string {\n if (IS_README_GENERATION) return help\n const binCommand = getBinCommand()\n if (binCommand === 'sanity') return help\n return help.replaceAll('$ sanity', `$ ${binCommand}`)\n}\n\n/**\n * Replace `sanity init` references in help text with the equivalent `create` command\n * for the detected package manager. Lines ending in just `sanity init\\n` (no flags)\n * are replaced without a flag separator, while lines with flags get the separator\n * (eg `--` for npm) so the flags are forwarded correctly.\n *\n * @internal\n */\nexport function replaceInitWithCreateCommand(help: string): string {\n const createCmd = guessCreateCommand()\n const flagSeparator = needsFlagSeparator() ? ' --' : ''\n\n // First replace all `sanity init` references that ends with a newline with the\n // create variant that does not include any flag separator (eg `--`). Then replace\n // the other references that do. Most package managers do not require the `--`\n // separator, but npm does. Only include it if we need to, as the commands look\n // cleaner without it.\n return help\n .replaceAll(/(\\s+)sanity\\s+init\\s*\\n/g, `$1${createCmd}\\n`)\n .replaceAll(/(\\s+)sanity(\\s+)init/g, `$1${createCmd}${flagSeparator}`)\n}\n\nfunction guessCreateCommand() {\n const pm = getRunningPackageManager()\n if (pm === 'yarn') return `yarn create sanity`\n if (pm === 'bun') return `bun create sanity@latest`\n if (pm === 'pnpm') return `pnpm create sanity@latest`\n return `npm create sanity@latest`\n}\n\nfunction needsFlagSeparator() {\n const pm = getRunningPackageManager()\n return pm === 'npm' || !pm\n}\n"],"names":["Help","getBinCommand","getRunningPackageManager","resolveTopicAliasInArgv","IS_README_GENERATION","process","argv","indexOf","includes","SanityHelp","formatCommand","command","help","isFromCreate","id","replaceInitWithCreateCommand","prefixBinName","formatRoot","formatTopic","topic","getCommandHelpClass","commandHelp","opts","flagSortOrder","showHelp","binCommand","replaceAll","createCmd","guessCreateCommand","flagSeparator","needsFlagSeparator","pm"],"mappings":"AAAA,SAA8BA,IAAI,QAAmB,cAAa;AAClE,SAAQC,aAAa,EAAEC,wBAAwB,QAAO,mCAAkC;AAExF,SAAQC,uBAAuB,QAAO,oBAAmB;AAEzD,qFAAqF;AACrF,uFAAuF;AACvF,qFAAqF;AACrF,4EAA4E;AAC5E,MAAMC,uBAAuB,AAACC,CAAAA,QAAQC,IAAI,CAACD,QAAQC,IAAI,CAACC,OAAO,CAAC,YAAY,EAAE,IAAI,EAAC,EAAGC,QAAQ,CAC5F;AAGF;;;;;;;CAOC,GACD,eAAe,MAAMC,mBAAmBT;IAC5BU,cAAcC,OAAyB,EAAU;QACzD,IAAIC,OAAO,KAAK,CAACF,cAAcC;QAE/B,wEAAwE;QACxE,iFAAiF;QACjF,yEAAyE;QACzE,MAAME,eAAeR,QAAQC,IAAI,CAACE,QAAQ,CAAC,oBAAoBG,QAAQG,EAAE,KAAK;QAC9E,IAAID,cAAc;YAChBD,OAAOG,6BAA6BH;QACtC;QAEA,OAAOI,cAAcJ;IACvB;IAEUK,aAAqB;QAC7B,OAAOD,cAAc,KAAK,CAACC;IAC7B;IAEUC,YAAYC,KAAuB,EAAU;QACrD,OAAOH,cAAc,KAAK,CAACE,YAAYC;IACzC;IAEmBC,oBAAoBT,OAAyB,EAAe;QAC7E,MAAMU,cAAc,KAAK,CAACD,oBAAoBT;QAC9C,IAAIA,QAAQG,EAAE,KAAK,SAAS;YAC1BO,YAAYC,IAAI,GAAG;gBAAC,GAAGD,YAAYC,IAAI;gBAAEC,eAAe;YAAM;QAChE;QACA,OAAOF;IACT;IAEA,MAAMG,SAASlB,IAAc,EAAiB;QAC5C,OAAO,KAAK,CAACkB,SAASrB,wBAAwBG;IAChD;AACF;AAEA;;CAEC,GACD,OAAO,SAASU,cAAcJ,IAAY;IACxC,IAAIR,sBAAsB,OAAOQ;IACjC,MAAMa,aAAaxB;IACnB,IAAIwB,eAAe,UAAU,OAAOb;IACpC,OAAOA,KAAKc,UAAU,CAAC,YAAY,CAAC,EAAE,EAAED,YAAY;AACtD;AAEA;;;;;;;CAOC,GACD,OAAO,SAASV,6BAA6BH,IAAY;IACvD,MAAMe,YAAYC;IAClB,MAAMC,gBAAgBC,uBAAuB,QAAQ;IAErD,+EAA+E;IAC/E,kFAAkF;IAClF,8EAA8E;IAC9E,+EAA+E;IAC/E,sBAAsB;IACtB,OAAOlB,KACJc,UAAU,CAAC,4BAA4B,CAAC,EAAE,EAAEC,UAAU,EAAE,CAAC,EACzDD,UAAU,CAAC,yBAAyB,CAAC,EAAE,EAAEC,YAAYE,eAAe;AACzE;AAEA,SAASD;IACP,MAAMG,KAAK7B;IACX,IAAI6B,OAAO,QAAQ,OAAO,CAAC,kBAAkB,CAAC;IAC9C,IAAIA,OAAO,OAAO,OAAO,CAAC,wBAAwB,CAAC;IACnD,IAAIA,OAAO,QAAQ,OAAO,CAAC,yBAAyB,CAAC;IACrD,OAAO,CAAC,wBAAwB,CAAC;AACnC;AAEA,SAASD;IACP,MAAMC,KAAK7B;IACX,OAAO6B,OAAO,SAAS,CAACA;AAC1B"}
1
+ {"version":3,"sources":["../src/SanityHelp.ts"],"sourcesContent":["import {Command, CommandHelp, Help, Interfaces} from '@oclif/core'\nimport {getBinCommand, getRunningPackageManager} from '@sanity/cli-core/package-manager'\n\nimport {resolveTopicAliasInArgv} from './topicAliases.js'\n\n// Running `oclif readme`, we don't want to apply the `prefixBinName` transformation,\n// as it will include whatever pm was used to spawn the script in the generated readme.\n// argv will contain something like [nodeBinPath, oclifBinPath, 'readme', …] so check\n// for 'readme' with a preceeding argument that includes 'oclif' to be sure.\nconst IS_README_GENERATION = (process.argv[process.argv.indexOf('readme') - 1] ?? '').includes(\n 'oclif',\n)\n\n/**\n * Custom Help class for Sanity CLI that overrides the default help formatting to\n * prefix the bin name (e.g., `npx sanity`, `yarn sanity`, etc.) in the help text,\n * and to replace `sanity init` references with the appropriate `create` command\n * for the detected package manager when needed.\n *\n * @internal\n */\nexport default class SanityHelp extends Help {\n protected formatCommand(command: Command.Loadable): string {\n let help = super.formatCommand(command)\n\n // When `sanity init` is called, but originates from the `create-sanity`\n // package/binary (eg the one used by `npm create sanity@latest` etc), we want to\n // customize the help text to show that command instead of `sanity init`.\n const isFromCreate = process.argv.includes('--from-create') && command.id === 'init'\n if (isFromCreate) {\n help = replaceInitWithCreateCommand(help)\n }\n\n return prefixBinName(help)\n }\n\n formatRoot(): string {\n return prefixBinName(super.formatRoot())\n }\n\n protected formatTopic(topic: Interfaces.Topic): string {\n return prefixBinName(super.formatTopic(topic))\n }\n\n protected override getCommandHelpClass(command: Command.Loadable): CommandHelp {\n const commandHelp = super.getCommandHelpClass(command)\n if (command.id === 'login') {\n commandHelp.opts = {...commandHelp.opts, flagSortOrder: 'none'}\n }\n return commandHelp\n }\n\n async showHelp(argv: string[]): Promise<void> {\n return super.showHelp(resolveTopicAliasInArgv(argv))\n }\n}\n\n/**\n * @internal\n */\nexport function prefixBinName(help: string): string {\n if (IS_README_GENERATION) return help\n const binCommand = getBinCommand()\n if (binCommand === 'sanity') return help\n return help.replaceAll('$ sanity', `$ ${binCommand}`)\n}\n\n/**\n * Replace `sanity init` references in help text with the equivalent `create` command\n * for the detected package manager. Lines ending in just `sanity init\\n` (no flags)\n * are replaced without a flag separator, while lines with flags get the separator\n * (eg `--` for npm) so the flags are forwarded correctly.\n *\n * @internal\n */\nexport function replaceInitWithCreateCommand(help: string): string {\n const createCmd = guessCreateCommand()\n const flagSeparator = needsFlagSeparator() ? ' --' : ''\n\n // First replace all `sanity init` references that ends with a newline with the\n // create variant that does not include any flag separator (eg `--`). Then replace\n // the other references that do. Most package managers do not require the `--`\n // separator, but npm does. Only include it if we need to, as the commands look\n // cleaner without it.\n return help\n .replaceAll(/(\\s+)sanity\\s+init\\s*\\n/g, `$1${createCmd}\\n`)\n .replaceAll(/(\\s+)sanity(\\s+)init/g, `$1${createCmd}${flagSeparator}`)\n}\n\nfunction guessCreateCommand() {\n const pm = getRunningPackageManager()\n if (pm === 'yarn') return `yarn create sanity`\n if (pm === 'bun') return `bun create sanity@latest`\n if (pm === 'pnpm') return `pnpm create sanity@latest`\n return `npm create sanity@latest`\n}\n\nfunction needsFlagSeparator() {\n const pm = getRunningPackageManager()\n return pm === 'npm' || !pm\n}\n"],"names":["Help","getBinCommand","getRunningPackageManager","resolveTopicAliasInArgv","IS_README_GENERATION","process","argv","indexOf","includes","SanityHelp","formatCommand","command","help","isFromCreate","id","replaceInitWithCreateCommand","prefixBinName","formatRoot","formatTopic","topic","getCommandHelpClass","commandHelp","opts","flagSortOrder","showHelp","binCommand","replaceAll","createCmd","guessCreateCommand","flagSeparator","needsFlagSeparator","pm"],"mappings":"AAAA,SAA8BA,IAAI,QAAmB,cAAa;AAClE,SAAQC,aAAa,EAAEC,wBAAwB,QAAO,mCAAkC;AAExF,SAAQC,uBAAuB,QAAO,oBAAmB;AAEzD,qFAAqF;AACrF,uFAAuF;AACvF,qFAAqF;AACrF,4EAA4E;AAC5E,MAAMC,uBAAuB,AAACC,CAAAA,QAAQC,IAAI,CAACD,QAAQC,IAAI,CAACC,OAAO,CAAC,YAAY,EAAE,IAAI,EAAC,EAAGC,QAAQ,CAC5F;AAGF;;;;;;;CAOC,GACD,eAAe,MAAMC,mBAAmBT;IAC5BU,cAAcC,OAAyB,EAAU;QACzD,IAAIC,OAAO,KAAK,CAACF,cAAcC;QAE/B,wEAAwE;QACxE,iFAAiF;QACjF,yEAAyE;QACzE,MAAME,eAAeR,QAAQC,IAAI,CAACE,QAAQ,CAAC,oBAAoBG,QAAQG,EAAE,KAAK;QAC9E,IAAID,cAAc;YAChBD,OAAOG,6BAA6BH;QACtC;QAEA,OAAOI,cAAcJ;IACvB;IAEAK,aAAqB;QACnB,OAAOD,cAAc,KAAK,CAACC;IAC7B;IAEUC,YAAYC,KAAuB,EAAU;QACrD,OAAOH,cAAc,KAAK,CAACE,YAAYC;IACzC;IAEmBC,oBAAoBT,OAAyB,EAAe;QAC7E,MAAMU,cAAc,KAAK,CAACD,oBAAoBT;QAC9C,IAAIA,QAAQG,EAAE,KAAK,SAAS;YAC1BO,YAAYC,IAAI,GAAG;gBAAC,GAAGD,YAAYC,IAAI;gBAAEC,eAAe;YAAM;QAChE;QACA,OAAOF;IACT;IAEA,MAAMG,SAASlB,IAAc,EAAiB;QAC5C,OAAO,KAAK,CAACkB,SAASrB,wBAAwBG;IAChD;AACF;AAEA;;CAEC,GACD,OAAO,SAASU,cAAcJ,IAAY;IACxC,IAAIR,sBAAsB,OAAOQ;IACjC,MAAMa,aAAaxB;IACnB,IAAIwB,eAAe,UAAU,OAAOb;IACpC,OAAOA,KAAKc,UAAU,CAAC,YAAY,CAAC,EAAE,EAAED,YAAY;AACtD;AAEA;;;;;;;CAOC,GACD,OAAO,SAASV,6BAA6BH,IAAY;IACvD,MAAMe,YAAYC;IAClB,MAAMC,gBAAgBC,uBAAuB,QAAQ;IAErD,+EAA+E;IAC/E,kFAAkF;IAClF,8EAA8E;IAC9E,+EAA+E;IAC/E,sBAAsB;IACtB,OAAOlB,KACJc,UAAU,CAAC,4BAA4B,CAAC,EAAE,EAAEC,UAAU,EAAE,CAAC,EACzDD,UAAU,CAAC,yBAAyB,CAAC,EAAE,EAAEC,YAAYE,eAAe;AACzE;AAEA,SAASD;IACP,MAAMG,KAAK7B;IACX,IAAI6B,OAAO,QAAQ,OAAO,CAAC,kBAAkB,CAAC;IAC9C,IAAIA,OAAO,OAAO,OAAO,CAAC,wBAAwB,CAAC;IACnD,IAAIA,OAAO,QAAQ,OAAO,CAAC,yBAAyB,CAAC;IACrD,OAAO,CAAC,wBAAwB,CAAC;AACnC;AAEA,SAASD;IACP,MAAMC,KAAK7B;IACX,OAAO6B,OAAO,SAAS,CAACA;AAC1B"}
@@ -1,3 +1,4 @@
1
+ import { exitCodes } from '@sanity/cli-core';
1
2
  /**
2
3
  * Asserts that a dataset exists in a list of datasets, exits if not found
3
4
  *
@@ -8,7 +9,7 @@
8
9
  const exists = datasets.some((d)=>d.name === datasetName);
9
10
  if (!exists) {
10
11
  output.error(`Dataset '${datasetName}' not found in this project. Available datasets: ${datasets.map((d)=>d.name).join(', ')}`, {
11
- exit: 1
12
+ exit: exitCodes.RUNTIME_ERROR
12
13
  });
13
14
  }
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/backup/assertDatasetExist.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {type DatasetsResponse} from '@sanity/client'\n\n/**\n * Asserts that a dataset exists in a list of datasets, exits if not found\n *\n * @param datasets - The list of datasets to check\n * @param datasetName - The name of the dataset to check for\n * @param output - Output to raise the error through the calling command\n */\nexport function assertDatasetExists(\n datasets: DatasetsResponse,\n datasetName: string,\n output: Output,\n): void {\n const exists = datasets.some((d) => d.name === datasetName)\n if (!exists) {\n output.error(\n `Dataset '${datasetName}' not found in this project. Available datasets: ${datasets.map((d) => d.name).join(', ')}`,\n {exit: 1},\n )\n }\n}\n"],"names":["assertDatasetExists","datasets","datasetName","output","exists","some","d","name","error","map","join","exit"],"mappings":"AAGA;;;;;;CAMC,GACD,OAAO,SAASA,oBACdC,QAA0B,EAC1BC,WAAmB,EACnBC,MAAc;IAEd,MAAMC,SAASH,SAASI,IAAI,CAAC,CAACC,IAAMA,EAAEC,IAAI,KAAKL;IAC/C,IAAI,CAACE,QAAQ;QACXD,OAAOK,KAAK,CACV,CAAC,SAAS,EAAEN,YAAY,iDAAiD,EAAED,SAASQ,GAAG,CAAC,CAACH,IAAMA,EAAEC,IAAI,EAAEG,IAAI,CAAC,OAAO,EACnH;YAACC,MAAM;QAAC;IAEZ;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/backup/assertDatasetExist.ts"],"sourcesContent":["import {exitCodes, type Output} from '@sanity/cli-core'\nimport {type DatasetsResponse} from '@sanity/client'\n\n/**\n * Asserts that a dataset exists in a list of datasets, exits if not found\n *\n * @param datasets - The list of datasets to check\n * @param datasetName - The name of the dataset to check for\n * @param output - Output to raise the error through the calling command\n */\nexport function assertDatasetExists(\n datasets: DatasetsResponse,\n datasetName: string,\n output: Output,\n): void {\n const exists = datasets.some((d) => d.name === datasetName)\n if (!exists) {\n output.error(\n `Dataset '${datasetName}' not found in this project. Available datasets: ${datasets.map((d) => d.name).join(', ')}`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n}\n"],"names":["exitCodes","assertDatasetExists","datasets","datasetName","output","exists","some","d","name","error","map","join","exit","RUNTIME_ERROR"],"mappings":"AAAA,SAAQA,SAAS,QAAoB,mBAAkB;AAGvD;;;;;;CAMC,GACD,OAAO,SAASC,oBACdC,QAA0B,EAC1BC,WAAmB,EACnBC,MAAc;IAEd,MAAMC,SAASH,SAASI,IAAI,CAAC,CAACC,IAAMA,EAAEC,IAAI,KAAKL;IAC/C,IAAI,CAACE,QAAQ;QACXD,OAAOK,KAAK,CACV,CAAC,SAAS,EAAEN,YAAY,iDAAiD,EAAED,SAASQ,GAAG,CAAC,CAACH,IAAMA,EAAEC,IAAI,EAAEG,IAAI,CAAC,OAAO,EACnH;YAACC,MAAMZ,UAAUa,aAAa;QAAA;IAElC;AACF"}
@@ -1,5 +1,6 @@
1
1
  import { styleText } from 'node:util';
2
2
  import { compareDependencyVersions, buildStudio as internalBuildStudio } from '@sanity/cli-build/_internal/build';
3
+ import { exitCodes } from '@sanity/cli-core';
3
4
  import { confirm, logSymbols, select, spinner } from '@sanity/cli-core/ux';
4
5
  import { buildAppId, resolveWorkbenchApp } from '@sanity/workbench-cli/build';
5
6
  import { getAppId } from '../../util/appId.js';
@@ -74,7 +75,7 @@ import { checkDependenciesEventListenerFactory, preReleaseEventListenerFactory }
74
75
  buildSpinner.fail();
75
76
  }
76
77
  output.error(message, {
77
- exit: 1
78
+ exit: exitCodes.RUNTIME_ERROR
78
79
  });
79
80
  },
80
81
  onBuildStart ({ message }) {
@@ -127,7 +128,7 @@ import { checkDependenciesEventListenerFactory, preReleaseEventListenerFactory }
127
128
  });
128
129
  if (choice === 'cancel') {
129
130
  output.error('Declined to continue with build', {
130
- exit: 1
131
+ exit: exitCodes.RUNTIME_ERROR
131
132
  });
132
133
  return {
133
134
  stopBuild: true
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n compareDependencyVersions,\n buildStudio as internalBuildStudio,\n} from '@sanity/cli-build/_internal/build'\nimport {confirm, logSymbols, select, spinner} from '@sanity/cli-core/ux'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {getPackageManagerChoice} from '../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../util/packageManager/upgradePackages.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {\n checkDependenciesEventListenerFactory,\n preReleaseEventListenerFactory,\n} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity Studio.\n *\n * @internal\n */\nexport async function buildStudio(options: BuildOptions): Promise<void> {\n const {calledFromDeploy, cliConfig, flags, outDir, output, workDir} = options\n\n // `views`/`services` live on the branded `unstable_defineApp` result — resolve\n // the workbench capability so it's gated on the brand, like the app build.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench ? {services: workbench.services, views: workbench.views} : undefined\n\n const appId = getAppId(cliConfig)\n\n let cleanOutputDirSpinner: ReturnType<typeof spinner> | undefined\n let buildSpinner: ReturnType<typeof spinner> | undefined\n\n await internalBuildStudio({\n appId,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !calledFromDeploy) {\n warnAboutMissingAppId({appType: 'studio', output, projectId: cliConfig?.api?.projectId})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'studio', output),\n exposes,\n isApp: determineIsApp(cliConfig),\n isWorkbenchApp: !!workbench,\n minify: Boolean(flags.minify),\n outDir,\n output,\n reactCompiler: cliConfig.reactCompiler,\n schemaExtraction: cliConfig.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: Boolean(flags.yes),\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: {\n ...preReleaseEventListenerFactory(output),\n\n ...checkDependenciesEventListenerFactory(output),\n\n onBuildEnd({message}) {\n if (buildSpinner) {\n buildSpinner.text = message\n buildSpinner.succeed()\n }\n },\n onBuildFail({message}) {\n if (buildSpinner) {\n buildSpinner.fail()\n }\n\n output.error(message, {exit: 1})\n },\n onBuildStart({message}) {\n if (!buildSpinner) {\n buildSpinner = spinner(message).start()\n }\n },\n onCleanOutputDirEnd({message}) {\n if (cleanOutputDirSpinner) {\n cleanOutputDirSpinner.text = message\n cleanOutputDirSpinner.succeed()\n }\n },\n onCleanOutputDirStart({message}) {\n if (!cleanOutputDirSpinner) {\n cleanOutputDirSpinner = spinner(message).start()\n }\n },\n async onInteractiveNonDefaultOutputDir({message}: {message: string}) {\n const shouldClean = await confirm({\n default: true,\n message,\n })\n return {shouldClean}\n },\n async onVersionMismatchInInteractiveAutoUpdate({mismatched, versionMismatchWarning}) {\n const choice = await select({\n choices: [\n {\n name: `Upgrade local versions (recommended). You will need to run the build command again`,\n value: 'upgrade',\n },\n {\n name: `Upgrade and proceed with build`,\n value: 'upgrade-and-proceed',\n },\n {\n name: `Continue anyway`,\n value: 'continue',\n },\n {name: 'Cancel', value: 'cancel'},\n ],\n default: 'upgrade',\n message: styleText(\n 'yellow',\n `${logSymbols.warning} ${versionMismatchWarning}\\n\\nDo you want to upgrade local versions before deploying?`,\n ),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: 1})\n return {stopBuild: true}\n }\n\n if (choice === 'upgrade' || choice === 'upgrade-and-proceed') {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n\n return {stopBuild: choice === 'upgrade'}\n }\n\n return {stopBuild: false}\n },\n onVersionMismatchInNonInteractiveAutoUpdate({versionMismatchWarning}) {\n output.warn(versionMismatchWarning)\n },\n },\n })\n}\n"],"names":["styleText","compareDependencyVersions","buildStudio","internalBuildStudio","confirm","logSymbols","select","spinner","buildAppId","resolveWorkbenchApp","getAppId","determineIsApp","getPackageManagerChoice","upgradePackages","warnAboutMissingAppId","determineBasePath","checkDependenciesEventListenerFactory","preReleaseEventListenerFactory","options","calledFromDeploy","cliConfig","flags","outDir","output","workDir","workbench","exposes","services","views","undefined","appId","cleanOutputDirSpinner","buildSpinner","autoUpdatesEnabled","checkAppId","appType","projectId","api","packages","isApp","isWorkbenchApp","minify","Boolean","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener","onBuildEnd","message","text","succeed","onBuildFail","fail","error","exit","onBuildStart","start","onCleanOutputDirEnd","onCleanOutputDirStart","onInteractiveNonDefaultOutputDir","shouldClean","default","onVersionMismatchInInteractiveAutoUpdate","mismatched","versionMismatchWarning","choice","choices","name","value","warning","stopBuild","packageManager","interactive","chosen","map","res","pkg","remote","onVersionMismatchInNonInteractiveAutoUpdate","warn"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n compareDependencyVersions,\n buildStudio as internalBuildStudio,\n} from '@sanity/cli-build/_internal/build'\nimport {exitCodes} from '@sanity/cli-core'\nimport {confirm, logSymbols, select, spinner} from '@sanity/cli-core/ux'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {getPackageManagerChoice} from '../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../util/packageManager/upgradePackages.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {\n checkDependenciesEventListenerFactory,\n preReleaseEventListenerFactory,\n} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity Studio.\n *\n * @internal\n */\nexport async function buildStudio(options: BuildOptions): Promise<void> {\n const {calledFromDeploy, cliConfig, flags, outDir, output, workDir} = options\n\n // `views`/`services` live on the branded `unstable_defineApp` result — resolve\n // the workbench capability so it's gated on the brand, like the app build.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench ? {services: workbench.services, views: workbench.views} : undefined\n\n const appId = getAppId(cliConfig)\n\n let cleanOutputDirSpinner: ReturnType<typeof spinner> | undefined\n let buildSpinner: ReturnType<typeof spinner> | undefined\n\n await internalBuildStudio({\n appId,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !calledFromDeploy) {\n warnAboutMissingAppId({appType: 'studio', output, projectId: cliConfig?.api?.projectId})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'studio', output),\n exposes,\n isApp: determineIsApp(cliConfig),\n isWorkbenchApp: !!workbench,\n minify: Boolean(flags.minify),\n outDir,\n output,\n reactCompiler: cliConfig.reactCompiler,\n schemaExtraction: cliConfig.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: Boolean(flags.yes),\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: {\n ...preReleaseEventListenerFactory(output),\n\n ...checkDependenciesEventListenerFactory(output),\n\n onBuildEnd({message}) {\n if (buildSpinner) {\n buildSpinner.text = message\n buildSpinner.succeed()\n }\n },\n onBuildFail({message}) {\n if (buildSpinner) {\n buildSpinner.fail()\n }\n\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n onBuildStart({message}) {\n if (!buildSpinner) {\n buildSpinner = spinner(message).start()\n }\n },\n onCleanOutputDirEnd({message}) {\n if (cleanOutputDirSpinner) {\n cleanOutputDirSpinner.text = message\n cleanOutputDirSpinner.succeed()\n }\n },\n onCleanOutputDirStart({message}) {\n if (!cleanOutputDirSpinner) {\n cleanOutputDirSpinner = spinner(message).start()\n }\n },\n async onInteractiveNonDefaultOutputDir({message}: {message: string}) {\n const shouldClean = await confirm({\n default: true,\n message,\n })\n return {shouldClean}\n },\n async onVersionMismatchInInteractiveAutoUpdate({mismatched, versionMismatchWarning}) {\n const choice = await select({\n choices: [\n {\n name: `Upgrade local versions (recommended). You will need to run the build command again`,\n value: 'upgrade',\n },\n {\n name: `Upgrade and proceed with build`,\n value: 'upgrade-and-proceed',\n },\n {\n name: `Continue anyway`,\n value: 'continue',\n },\n {name: 'Cancel', value: 'cancel'},\n ],\n default: 'upgrade',\n message: styleText(\n 'yellow',\n `${logSymbols.warning} ${versionMismatchWarning}\\n\\nDo you want to upgrade local versions before deploying?`,\n ),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return {stopBuild: true}\n }\n\n if (choice === 'upgrade' || choice === 'upgrade-and-proceed') {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n\n return {stopBuild: choice === 'upgrade'}\n }\n\n return {stopBuild: false}\n },\n onVersionMismatchInNonInteractiveAutoUpdate({versionMismatchWarning}) {\n output.warn(versionMismatchWarning)\n },\n },\n })\n}\n"],"names":["styleText","compareDependencyVersions","buildStudio","internalBuildStudio","exitCodes","confirm","logSymbols","select","spinner","buildAppId","resolveWorkbenchApp","getAppId","determineIsApp","getPackageManagerChoice","upgradePackages","warnAboutMissingAppId","determineBasePath","checkDependenciesEventListenerFactory","preReleaseEventListenerFactory","options","calledFromDeploy","cliConfig","flags","outDir","output","workDir","workbench","exposes","services","views","undefined","appId","cleanOutputDirSpinner","buildSpinner","autoUpdatesEnabled","checkAppId","appType","projectId","api","packages","isApp","isWorkbenchApp","minify","Boolean","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener","onBuildEnd","message","text","succeed","onBuildFail","fail","error","exit","RUNTIME_ERROR","onBuildStart","start","onCleanOutputDirEnd","onCleanOutputDirStart","onInteractiveNonDefaultOutputDir","shouldClean","default","onVersionMismatchInInteractiveAutoUpdate","mismatched","versionMismatchWarning","choice","choices","name","value","warning","stopBuild","packageManager","interactive","chosen","map","res","pkg","remote","onVersionMismatchInNonInteractiveAutoUpdate","warn"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { styleText } from 'node:util';
2
+ import { exitCodes } from '@sanity/cli-core';
2
3
  import { select } from '@sanity/cli-core/ux';
3
4
  /**
4
5
  * Creates check dependency event handlers that are shared between buildStudio and startStudioDevServer.
@@ -12,22 +13,22 @@ import { select } from '@sanity/cli-core/ux';
12
13
  },
13
14
  onInvalidStyledComponentsVersionRange ({ message }) {
14
15
  output.error(message, {
15
- exit: 1
16
+ exit: exitCodes.RUNTIME_ERROR
16
17
  });
17
18
  },
18
19
  onNoDeclaredStyledComponentsVersion ({ message }) {
19
20
  output.error(message, {
20
- exit: 1
21
+ exit: exitCodes.RUNTIME_ERROR
21
22
  });
22
23
  },
23
24
  onNoInstalledSanityVersion ({ message }) {
24
25
  output.error(message, {
25
- exit: 1
26
+ exit: exitCodes.RUNTIME_ERROR
26
27
  });
27
28
  },
28
29
  onNoInstalledStyledComponentsVersion ({ message }) {
29
30
  output.error(message, {
30
- exit: 1
31
+ exit: exitCodes.RUNTIME_ERROR
31
32
  });
32
33
  }
33
34
  };
@@ -53,7 +54,7 @@ import { select } from '@sanity/cli-core/ux';
53
54
  });
54
55
  if (choice === 'cancel') {
55
56
  output.error('Declined to continue with build', {
56
- exit: 1
57
+ exit: exitCodes.RUNTIME_ERROR
57
58
  });
58
59
  return;
59
60
  }
@@ -61,7 +62,7 @@ import { select } from '@sanity/cli-core/ux';
61
62
  },
62
63
  onPreReleaseInNonInteractiveAutoUpdate ({ message }) {
63
64
  output.error(message, {
64
- exit: 1
65
+ exit: exitCodes.RUNTIME_ERROR
65
66
  });
66
67
  }
67
68
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/eventListenerFactory.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Output} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\n\n/**\n * Creates check dependency event handlers that are shared between buildStudio and startStudioDevServer.\n */\nexport function checkDependenciesEventListenerFactory(output: Output) {\n return {\n onIncompatibleDeclaredStyledComponentsVersionRange({message}: {message: string}) {\n output.warn(message)\n },\n onIncompatibleInstalledStyledComponentsVersionRange({message}: {message: string}) {\n output.warn(message)\n },\n onInvalidStyledComponentsVersionRange({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n onNoDeclaredStyledComponentsVersion({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n onNoInstalledSanityVersion({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n onNoInstalledStyledComponentsVersion({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n }\n}\n\n/**\n * Creates pre-release event handlers that are shared between buildApp and buildStudio.\n */\nexport function preReleaseEventListenerFactory(output: Output) {\n return {\n async onPreReleaseInInteractiveAutoUpdate({prereleaseMessage}: {prereleaseMessage: string}) {\n const choice = await select({\n choices: [\n {\n name: 'Disable auto-updates for this build and continue',\n value: 'disable-auto-updates',\n },\n {name: 'Cancel build', value: 'cancel'},\n ],\n default: 'disable-auto-updates',\n message: styleText('yellow', prereleaseMessage),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: 1})\n return\n }\n\n output.warn('Auto-updates disabled for this build')\n },\n onPreReleaseInNonInteractiveAutoUpdate({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n }\n}\n"],"names":["styleText","select","checkDependenciesEventListenerFactory","output","onIncompatibleDeclaredStyledComponentsVersionRange","message","warn","onIncompatibleInstalledStyledComponentsVersionRange","onInvalidStyledComponentsVersionRange","error","exit","onNoDeclaredStyledComponentsVersion","onNoInstalledSanityVersion","onNoInstalledStyledComponentsVersion","preReleaseEventListenerFactory","onPreReleaseInInteractiveAutoUpdate","prereleaseMessage","choice","choices","name","value","default","onPreReleaseInNonInteractiveAutoUpdate"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAGnC,SAAQC,MAAM,QAAO,sBAAqB;AAE1C;;CAEC,GACD,OAAO,SAASC,sCAAsCC,MAAc;IAClE,OAAO;QACLC,oDAAmD,EAACC,OAAO,EAAoB;YAC7EF,OAAOG,IAAI,CAACD;QACd;QACAE,qDAAoD,EAACF,OAAO,EAAoB;YAC9EF,OAAOG,IAAI,CAACD;QACd;QACAG,uCAAsC,EAACH,OAAO,EAAoB;YAChEF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;QACAC,qCAAoC,EAACN,OAAO,EAAoB;YAC9DF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;QACAE,4BAA2B,EAACP,OAAO,EAAoB;YACrDF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;QACAG,sCAAqC,EAACR,OAAO,EAAoB;YAC/DF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;IACF;AACF;AAEA;;CAEC,GACD,OAAO,SAASI,+BAA+BX,MAAc;IAC3D,OAAO;QACL,MAAMY,qCAAoC,EAACC,iBAAiB,EAA8B;YACxF,MAAMC,SAAS,MAAMhB,OAAO;gBAC1BiB,SAAS;oBACP;wBACEC,MAAM;wBACNC,OAAO;oBACT;oBACA;wBAACD,MAAM;wBAAgBC,OAAO;oBAAQ;iBACvC;gBACDC,SAAS;gBACThB,SAASL,UAAU,UAAUgB;YAC/B;YAEA,IAAIC,WAAW,UAAU;gBACvBd,OAAOM,KAAK,CAAC,mCAAmC;oBAACC,MAAM;gBAAC;gBACxD;YACF;YAEAP,OAAOG,IAAI,CAAC;QACd;QACAgB,wCAAuC,EAACjB,OAAO,EAAoB;YACjEF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/build/eventListenerFactory.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {exitCodes, Output} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\n\n/**\n * Creates check dependency event handlers that are shared between buildStudio and startStudioDevServer.\n */\nexport function checkDependenciesEventListenerFactory(output: Output) {\n return {\n onIncompatibleDeclaredStyledComponentsVersionRange({message}: {message: string}) {\n output.warn(message)\n },\n onIncompatibleInstalledStyledComponentsVersionRange({message}: {message: string}) {\n output.warn(message)\n },\n onInvalidStyledComponentsVersionRange({message}: {message: string}) {\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n onNoDeclaredStyledComponentsVersion({message}: {message: string}) {\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n onNoInstalledSanityVersion({message}: {message: string}) {\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n onNoInstalledStyledComponentsVersion({message}: {message: string}) {\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n }\n}\n\n/**\n * Creates pre-release event handlers that are shared between buildApp and buildStudio.\n */\nexport function preReleaseEventListenerFactory(output: Output) {\n return {\n async onPreReleaseInInteractiveAutoUpdate({prereleaseMessage}: {prereleaseMessage: string}) {\n const choice = await select({\n choices: [\n {\n name: 'Disable auto-updates for this build and continue',\n value: 'disable-auto-updates',\n },\n {name: 'Cancel build', value: 'cancel'},\n ],\n default: 'disable-auto-updates',\n message: styleText('yellow', prereleaseMessage),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: exitCodes.RUNTIME_ERROR})\n return\n }\n\n output.warn('Auto-updates disabled for this build')\n },\n onPreReleaseInNonInteractiveAutoUpdate({message}: {message: string}) {\n output.error(message, {exit: exitCodes.RUNTIME_ERROR})\n },\n }\n}\n"],"names":["styleText","exitCodes","select","checkDependenciesEventListenerFactory","output","onIncompatibleDeclaredStyledComponentsVersionRange","message","warn","onIncompatibleInstalledStyledComponentsVersionRange","onInvalidStyledComponentsVersionRange","error","exit","RUNTIME_ERROR","onNoDeclaredStyledComponentsVersion","onNoInstalledSanityVersion","onNoInstalledStyledComponentsVersion","preReleaseEventListenerFactory","onPreReleaseInInteractiveAutoUpdate","prereleaseMessage","choice","choices","name","value","default","onPreReleaseInNonInteractiveAutoUpdate"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,SAAS,QAAe,mBAAkB;AAClD,SAAQC,MAAM,QAAO,sBAAqB;AAE1C;;CAEC,GACD,OAAO,SAASC,sCAAsCC,MAAc;IAClE,OAAO;QACLC,oDAAmD,EAACC,OAAO,EAAoB;YAC7EF,OAAOG,IAAI,CAACD;QACd;QACAE,qDAAoD,EAACF,OAAO,EAAoB;YAC9EF,OAAOG,IAAI,CAACD;QACd;QACAG,uCAAsC,EAACH,OAAO,EAAoB;YAChEF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAMV,UAAUW,aAAa;YAAA;QACtD;QACAC,qCAAoC,EAACP,OAAO,EAAoB;YAC9DF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAMV,UAAUW,aAAa;YAAA;QACtD;QACAE,4BAA2B,EAACR,OAAO,EAAoB;YACrDF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAMV,UAAUW,aAAa;YAAA;QACtD;QACAG,sCAAqC,EAACT,OAAO,EAAoB;YAC/DF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAMV,UAAUW,aAAa;YAAA;QACtD;IACF;AACF;AAEA;;CAEC,GACD,OAAO,SAASI,+BAA+BZ,MAAc;IAC3D,OAAO;QACL,MAAMa,qCAAoC,EAACC,iBAAiB,EAA8B;YACxF,MAAMC,SAAS,MAAMjB,OAAO;gBAC1BkB,SAAS;oBACP;wBACEC,MAAM;wBACNC,OAAO;oBACT;oBACA;wBAACD,MAAM;wBAAgBC,OAAO;oBAAQ;iBACvC;gBACDC,SAAS;gBACTjB,SAASN,UAAU,UAAUkB;YAC/B;YAEA,IAAIC,WAAW,UAAU;gBACvBf,OAAOM,KAAK,CAAC,mCAAmC;oBAACC,MAAMV,UAAUW,aAAa;gBAAA;gBAC9E;YACF;YAEAR,OAAOG,IAAI,CAAC;QACd;QACAiB,wCAAuC,EAAClB,OAAO,EAAoB;YACjEF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAMV,UAAUW,aAAa;YAAA;QACtD;IACF;AACF"}
@@ -1,4 +1,5 @@
1
1
  import { styleText } from 'node:util';
2
+ import { exitCodes } from '@sanity/cli-core';
2
3
  import { isWorkbenchApp } from '@sanity/workbench-cli';
3
4
  /**
4
5
  * Owns the auto-update rules and returns plain facts, so each surface (build,
@@ -111,7 +112,7 @@ function resolveConfiguredAutoUpdates({ cliConfig, flags }) {
111
112
  case 'conflicting-config':
112
113
  {
113
114
  output.error(getAutoUpdateIssueMessage(issue), {
114
- exit: 1
115
+ exit: exitCodes.RUNTIME_ERROR
115
116
  });
116
117
  break;
117
118
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/build/shouldAutoUpdate.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type CliConfig, type Output} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {type DeployFlags} from '../deploy/types.js'\nimport {type DevFlags} from '../dev/types.js'\nimport {type BuildFlags} from './types.js'\n\ninterface AutoUpdateSources {\n cliConfig: CliConfig\n flags: BuildFlags | DeployFlags | DevFlags\n}\n\n/**\n * The single auto-update configuration problem to surface, if any.\n * Flag usage takes precedence over config problems: when the deprecated flag\n * is passed, config is not consulted, so config issues are not reported.\n */\ntype AutoUpdateIssue =\n | {flag: '--auto-updates' | '--no-auto-updates'; type: 'deprecated-flag'}\n | {type: 'conflicting-config'}\n | {type: 'deprecated-config'}\n | {type: 'unsupported'}\n\nexport interface AutoUpdateSettings {\n enabled: boolean\n issue: AutoUpdateIssue | null\n}\n\n/**\n * Owns the auto-update rules and returns plain facts, so each surface (build,\n * dev, deploy warnings, dry-run checks) decides its own presentation.\n *\n * @internal\n */\nexport function resolveAutoUpdates(sources: AutoUpdateSources): AutoUpdateSettings {\n const settings = resolveConfiguredAutoUpdates(sources)\n\n // A workbench app takes `sanity` from the shell's shared runtime, so it has no\n // version of its own to pin.\n // TODO(SDK-1045): confirm the long-term story with the studio team.\n if (settings.enabled && isWorkbenchApp(sources.cliConfig?.app)) {\n // A config conflict still fails — it's a problem with the config itself.\n return settings.issue?.type === 'conflicting-config'\n ? {enabled: false, issue: settings.issue}\n : {enabled: false, issue: {type: 'unsupported'}}\n }\n\n return settings\n}\n\nfunction resolveConfiguredAutoUpdates({cliConfig, flags}: AutoUpdateSources): AutoUpdateSettings {\n // Flags always take precedence over config\n if ('auto-updates' in flags) {\n const enabled = Boolean(flags['auto-updates'])\n return {\n enabled,\n issue: {flag: enabled ? '--auto-updates' : '--no-auto-updates', type: 'deprecated-flag'},\n }\n }\n\n const hasOldConfig = cliConfig && 'autoUpdates' in cliConfig\n\n const hasNewConfig =\n cliConfig &&\n 'deployment' in cliConfig &&\n cliConfig.deployment &&\n 'autoUpdates' in cliConfig.deployment\n\n if (hasNewConfig) {\n return {\n enabled: Boolean(cliConfig?.deployment?.autoUpdates),\n issue: hasOldConfig ? {type: 'conflicting-config'} : null,\n }\n }\n\n if (hasOldConfig) {\n return {enabled: Boolean(cliConfig?.autoUpdates), issue: {type: 'deprecated-config'}}\n }\n\n return {enabled: false, issue: null}\n}\n\n/**\n * The user-facing message for an auto-update configuration problem.\n * Shared by every surface that reports the issue (deploy warnings, dry-run\n * checks) so the wording has one home.\n *\n * @internal\n */\nexport function getAutoUpdateIssueMessage(issue: AutoUpdateIssue): string {\n switch (issue.type) {\n case 'conflicting-config': {\n return 'Found both `autoUpdates` (deprecated) and `deployment.autoUpdates` in sanity.cli.js/.ts. Please remove the deprecated top level `autoUpdates` config.'\n }\n case 'deprecated-config': {\n return 'The autoUpdates config has moved to deployment.autoUpdates.'\n }\n case 'deprecated-flag': {\n return `The ${issue.flag} flag is deprecated for deploy and build commands. Set the autoUpdates option in the deployment section of sanity.cli.ts or sanity.cli.js instead.`\n }\n case 'unsupported': {\n return \"Auto-updates aren't supported yet — using the installed package versions\"\n }\n }\n}\n\n/**\n * The styled before/after edit that migrates the deprecated top-level\n * `autoUpdates` to `deployment.autoUpdates`. Lives here so every surface that\n * reports the deprecated config (deploy warnings, dry-run checks) shows the\n * same migration hint.\n *\n * @internal\n */\nexport function getAutoUpdateMigrationHint(currentValue: unknown): string {\n return `Please update sanity.cli.ts or sanity.cli.js and make the following change:\n ${styleText('red', `- autoUpdates: ${currentValue},`)}\n ${styleText('green', `+ deployment: {autoUpdates: ${currentValue}}`)}\n`\n}\n\n/**\n * Resolves the auto-update setting and prints any configuration problem.\n * @remarks Throws an error if both the old and new auto update config are used; throws a warning if the old config is used, or if the auto updates flags are used.\n * @internal\n */\nexport function shouldAutoUpdate({\n cliConfig,\n flags,\n output,\n}: AutoUpdateSources & {output: Output}): boolean {\n const {enabled, issue} = resolveAutoUpdates({cliConfig, flags})\n\n switch (issue?.type) {\n case 'conflicting-config': {\n output.error(getAutoUpdateIssueMessage(issue), {exit: 1})\n break\n }\n case 'deprecated-config': {\n output.warn(getAutoUpdateIssueMessage(issue))\n output.warn(getAutoUpdateMigrationHint(cliConfig.autoUpdates))\n break\n }\n case 'deprecated-flag':\n case 'unsupported': {\n output.warn(getAutoUpdateIssueMessage(issue))\n break\n }\n default: {\n break\n }\n }\n\n return enabled\n}\n"],"names":["styleText","isWorkbenchApp","resolveAutoUpdates","sources","settings","resolveConfiguredAutoUpdates","enabled","cliConfig","app","issue","type","flags","Boolean","flag","hasOldConfig","hasNewConfig","deployment","autoUpdates","getAutoUpdateIssueMessage","getAutoUpdateMigrationHint","currentValue","shouldAutoUpdate","output","error","exit","warn"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAGnC,SAAQC,cAAc,QAAO,wBAAuB;AA2BpD;;;;;CAKC,GACD,OAAO,SAASC,mBAAmBC,OAA0B;IAC3D,MAAMC,WAAWC,6BAA6BF;IAE9C,+EAA+E;IAC/E,6BAA6B;IAC7B,oEAAoE;IACpE,IAAIC,SAASE,OAAO,IAAIL,eAAeE,QAAQI,SAAS,EAAEC,MAAM;QAC9D,yEAAyE;QACzE,OAAOJ,SAASK,KAAK,EAAEC,SAAS,uBAC5B;YAACJ,SAAS;YAAOG,OAAOL,SAASK,KAAK;QAAA,IACtC;YAACH,SAAS;YAAOG,OAAO;gBAACC,MAAM;YAAa;QAAC;IACnD;IAEA,OAAON;AACT;AAEA,SAASC,6BAA6B,EAACE,SAAS,EAAEI,KAAK,EAAoB;IACzE,2CAA2C;IAC3C,IAAI,kBAAkBA,OAAO;QAC3B,MAAML,UAAUM,QAAQD,KAAK,CAAC,eAAe;QAC7C,OAAO;YACLL;YACAG,OAAO;gBAACI,MAAMP,UAAU,mBAAmB;gBAAqBI,MAAM;YAAiB;QACzF;IACF;IAEA,MAAMI,eAAeP,aAAa,iBAAiBA;IAEnD,MAAMQ,eACJR,aACA,gBAAgBA,aAChBA,UAAUS,UAAU,IACpB,iBAAiBT,UAAUS,UAAU;IAEvC,IAAID,cAAc;QAChB,OAAO;YACLT,SAASM,QAAQL,WAAWS,YAAYC;YACxCR,OAAOK,eAAe;gBAACJ,MAAM;YAAoB,IAAI;QACvD;IACF;IAEA,IAAII,cAAc;QAChB,OAAO;YAACR,SAASM,QAAQL,WAAWU;YAAcR,OAAO;gBAACC,MAAM;YAAmB;QAAC;IACtF;IAEA,OAAO;QAACJ,SAAS;QAAOG,OAAO;IAAI;AACrC;AAEA;;;;;;CAMC,GACD,OAAO,SAASS,0BAA0BT,KAAsB;IAC9D,OAAQA,MAAMC,IAAI;QAChB,KAAK;YAAsB;gBACzB,OAAO;YACT;QACA,KAAK;YAAqB;gBACxB,OAAO;YACT;QACA,KAAK;YAAmB;gBACtB,OAAO,CAAC,IAAI,EAAED,MAAMI,IAAI,CAAC,kJAAkJ,CAAC;YAC9K;QACA,KAAK;YAAe;gBAClB,OAAO;YACT;IACF;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASM,2BAA2BC,YAAqB;IAC9D,OAAO,CAAC;EACR,EAAEpB,UAAU,OAAO,CAAC,gBAAgB,EAAEoB,aAAa,CAAC,CAAC,EAAE;EACvD,EAAEpB,UAAU,SAAS,CAAC,6BAA6B,EAAEoB,aAAa,CAAC,CAAC,EAAE;AACxE,CAAC;AACD;AAEA;;;;CAIC,GACD,OAAO,SAASC,iBAAiB,EAC/Bd,SAAS,EACTI,KAAK,EACLW,MAAM,EAC+B;IACrC,MAAM,EAAChB,OAAO,EAAEG,KAAK,EAAC,GAAGP,mBAAmB;QAACK;QAAWI;IAAK;IAE7D,OAAQF,OAAOC;QACb,KAAK;YAAsB;gBACzBY,OAAOC,KAAK,CAACL,0BAA0BT,QAAQ;oBAACe,MAAM;gBAAC;gBACvD;YACF;QACA,KAAK;YAAqB;gBACxBF,OAAOG,IAAI,CAACP,0BAA0BT;gBACtCa,OAAOG,IAAI,CAACN,2BAA2BZ,UAAUU,WAAW;gBAC5D;YACF;QACA,KAAK;QACL,KAAK;YAAe;gBAClBK,OAAOG,IAAI,CAACP,0BAA0BT;gBACtC;YACF;QACA;YAAS;gBACP;YACF;IACF;IAEA,OAAOH;AACT"}
1
+ {"version":3,"sources":["../../../src/actions/build/shouldAutoUpdate.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type CliConfig, exitCodes, type Output} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {type DeployFlags} from '../deploy/types.js'\nimport {type DevFlags} from '../dev/types.js'\nimport {type BuildFlags} from './types.js'\n\ninterface AutoUpdateSources {\n cliConfig: CliConfig\n flags: BuildFlags | DeployFlags | DevFlags\n}\n\n/**\n * The single auto-update configuration problem to surface, if any.\n * Flag usage takes precedence over config problems: when the deprecated flag\n * is passed, config is not consulted, so config issues are not reported.\n */\ntype AutoUpdateIssue =\n | {flag: '--auto-updates' | '--no-auto-updates'; type: 'deprecated-flag'}\n | {type: 'conflicting-config'}\n | {type: 'deprecated-config'}\n | {type: 'unsupported'}\n\nexport interface AutoUpdateSettings {\n enabled: boolean\n issue: AutoUpdateIssue | null\n}\n\n/**\n * Owns the auto-update rules and returns plain facts, so each surface (build,\n * dev, deploy warnings, dry-run checks) decides its own presentation.\n *\n * @internal\n */\nexport function resolveAutoUpdates(sources: AutoUpdateSources): AutoUpdateSettings {\n const settings = resolveConfiguredAutoUpdates(sources)\n\n // A workbench app takes `sanity` from the shell's shared runtime, so it has no\n // version of its own to pin.\n // TODO(SDK-1045): confirm the long-term story with the studio team.\n if (settings.enabled && isWorkbenchApp(sources.cliConfig?.app)) {\n // A config conflict still fails — it's a problem with the config itself.\n return settings.issue?.type === 'conflicting-config'\n ? {enabled: false, issue: settings.issue}\n : {enabled: false, issue: {type: 'unsupported'}}\n }\n\n return settings\n}\n\nfunction resolveConfiguredAutoUpdates({cliConfig, flags}: AutoUpdateSources): AutoUpdateSettings {\n // Flags always take precedence over config\n if ('auto-updates' in flags) {\n const enabled = Boolean(flags['auto-updates'])\n return {\n enabled,\n issue: {flag: enabled ? '--auto-updates' : '--no-auto-updates', type: 'deprecated-flag'},\n }\n }\n\n const hasOldConfig = cliConfig && 'autoUpdates' in cliConfig\n\n const hasNewConfig =\n cliConfig &&\n 'deployment' in cliConfig &&\n cliConfig.deployment &&\n 'autoUpdates' in cliConfig.deployment\n\n if (hasNewConfig) {\n return {\n enabled: Boolean(cliConfig?.deployment?.autoUpdates),\n issue: hasOldConfig ? {type: 'conflicting-config'} : null,\n }\n }\n\n if (hasOldConfig) {\n return {enabled: Boolean(cliConfig?.autoUpdates), issue: {type: 'deprecated-config'}}\n }\n\n return {enabled: false, issue: null}\n}\n\n/**\n * The user-facing message for an auto-update configuration problem.\n * Shared by every surface that reports the issue (deploy warnings, dry-run\n * checks) so the wording has one home.\n *\n * @internal\n */\nexport function getAutoUpdateIssueMessage(issue: AutoUpdateIssue): string {\n switch (issue.type) {\n case 'conflicting-config': {\n return 'Found both `autoUpdates` (deprecated) and `deployment.autoUpdates` in sanity.cli.js/.ts. Please remove the deprecated top level `autoUpdates` config.'\n }\n case 'deprecated-config': {\n return 'The autoUpdates config has moved to deployment.autoUpdates.'\n }\n case 'deprecated-flag': {\n return `The ${issue.flag} flag is deprecated for deploy and build commands. Set the autoUpdates option in the deployment section of sanity.cli.ts or sanity.cli.js instead.`\n }\n case 'unsupported': {\n return \"Auto-updates aren't supported yet — using the installed package versions\"\n }\n }\n}\n\n/**\n * The styled before/after edit that migrates the deprecated top-level\n * `autoUpdates` to `deployment.autoUpdates`. Lives here so every surface that\n * reports the deprecated config (deploy warnings, dry-run checks) shows the\n * same migration hint.\n *\n * @internal\n */\nexport function getAutoUpdateMigrationHint(currentValue: unknown): string {\n return `Please update sanity.cli.ts or sanity.cli.js and make the following change:\n ${styleText('red', `- autoUpdates: ${currentValue},`)}\n ${styleText('green', `+ deployment: {autoUpdates: ${currentValue}}`)}\n`\n}\n\n/**\n * Resolves the auto-update setting and prints any configuration problem.\n * @remarks Throws an error if both the old and new auto update config are used; throws a warning if the old config is used, or if the auto updates flags are used.\n * @internal\n */\nexport function shouldAutoUpdate({\n cliConfig,\n flags,\n output,\n}: AutoUpdateSources & {output: Output}): boolean {\n const {enabled, issue} = resolveAutoUpdates({cliConfig, flags})\n\n switch (issue?.type) {\n case 'conflicting-config': {\n output.error(getAutoUpdateIssueMessage(issue), {exit: exitCodes.RUNTIME_ERROR})\n break\n }\n case 'deprecated-config': {\n output.warn(getAutoUpdateIssueMessage(issue))\n output.warn(getAutoUpdateMigrationHint(cliConfig.autoUpdates))\n break\n }\n case 'deprecated-flag':\n case 'unsupported': {\n output.warn(getAutoUpdateIssueMessage(issue))\n break\n }\n default: {\n break\n }\n }\n\n return enabled\n}\n"],"names":["styleText","exitCodes","isWorkbenchApp","resolveAutoUpdates","sources","settings","resolveConfiguredAutoUpdates","enabled","cliConfig","app","issue","type","flags","Boolean","flag","hasOldConfig","hasNewConfig","deployment","autoUpdates","getAutoUpdateIssueMessage","getAutoUpdateMigrationHint","currentValue","shouldAutoUpdate","output","error","exit","RUNTIME_ERROR","warn"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAwBC,SAAS,QAAoB,mBAAkB;AACvE,SAAQC,cAAc,QAAO,wBAAuB;AA2BpD;;;;;CAKC,GACD,OAAO,SAASC,mBAAmBC,OAA0B;IAC3D,MAAMC,WAAWC,6BAA6BF;IAE9C,+EAA+E;IAC/E,6BAA6B;IAC7B,oEAAoE;IACpE,IAAIC,SAASE,OAAO,IAAIL,eAAeE,QAAQI,SAAS,EAAEC,MAAM;QAC9D,yEAAyE;QACzE,OAAOJ,SAASK,KAAK,EAAEC,SAAS,uBAC5B;YAACJ,SAAS;YAAOG,OAAOL,SAASK,KAAK;QAAA,IACtC;YAACH,SAAS;YAAOG,OAAO;gBAACC,MAAM;YAAa;QAAC;IACnD;IAEA,OAAON;AACT;AAEA,SAASC,6BAA6B,EAACE,SAAS,EAAEI,KAAK,EAAoB;IACzE,2CAA2C;IAC3C,IAAI,kBAAkBA,OAAO;QAC3B,MAAML,UAAUM,QAAQD,KAAK,CAAC,eAAe;QAC7C,OAAO;YACLL;YACAG,OAAO;gBAACI,MAAMP,UAAU,mBAAmB;gBAAqBI,MAAM;YAAiB;QACzF;IACF;IAEA,MAAMI,eAAeP,aAAa,iBAAiBA;IAEnD,MAAMQ,eACJR,aACA,gBAAgBA,aAChBA,UAAUS,UAAU,IACpB,iBAAiBT,UAAUS,UAAU;IAEvC,IAAID,cAAc;QAChB,OAAO;YACLT,SAASM,QAAQL,WAAWS,YAAYC;YACxCR,OAAOK,eAAe;gBAACJ,MAAM;YAAoB,IAAI;QACvD;IACF;IAEA,IAAII,cAAc;QAChB,OAAO;YAACR,SAASM,QAAQL,WAAWU;YAAcR,OAAO;gBAACC,MAAM;YAAmB;QAAC;IACtF;IAEA,OAAO;QAACJ,SAAS;QAAOG,OAAO;IAAI;AACrC;AAEA;;;;;;CAMC,GACD,OAAO,SAASS,0BAA0BT,KAAsB;IAC9D,OAAQA,MAAMC,IAAI;QAChB,KAAK;YAAsB;gBACzB,OAAO;YACT;QACA,KAAK;YAAqB;gBACxB,OAAO;YACT;QACA,KAAK;YAAmB;gBACtB,OAAO,CAAC,IAAI,EAAED,MAAMI,IAAI,CAAC,kJAAkJ,CAAC;YAC9K;QACA,KAAK;YAAe;gBAClB,OAAO;YACT;IACF;AACF;AAEA;;;;;;;CAOC,GACD,OAAO,SAASM,2BAA2BC,YAAqB;IAC9D,OAAO,CAAC;EACR,EAAErB,UAAU,OAAO,CAAC,gBAAgB,EAAEqB,aAAa,CAAC,CAAC,EAAE;EACvD,EAAErB,UAAU,SAAS,CAAC,6BAA6B,EAAEqB,aAAa,CAAC,CAAC,EAAE;AACxE,CAAC;AACD;AAEA;;;;CAIC,GACD,OAAO,SAASC,iBAAiB,EAC/Bd,SAAS,EACTI,KAAK,EACLW,MAAM,EAC+B;IACrC,MAAM,EAAChB,OAAO,EAAEG,KAAK,EAAC,GAAGP,mBAAmB;QAACK;QAAWI;IAAK;IAE7D,OAAQF,OAAOC;QACb,KAAK;YAAsB;gBACzBY,OAAOC,KAAK,CAACL,0BAA0BT,QAAQ;oBAACe,MAAMxB,UAAUyB,aAAa;gBAAA;gBAC7E;YACF;QACA,KAAK;YAAqB;gBACxBH,OAAOI,IAAI,CAACR,0BAA0BT;gBACtCa,OAAOI,IAAI,CAACP,2BAA2BZ,UAAUU,WAAW;gBAC5D;YACF;QACA,KAAK;QACL,KAAK;YAAe;gBAClBK,OAAOI,IAAI,CAACR,0BAA0BT;gBACtC;YACF;QACA;YAAS;gBACP;YACF;IACF;IAEA,OAAOH;AACT"}
@@ -1,3 +1,4 @@
1
+ import { exitCodes } from '@sanity/cli-core';
1
2
  const wildcardReplacement = 'a-wild-card-r3pl4c3m3n7-a';
2
3
  const portReplacement = ':7777777';
3
4
  /**
@@ -12,7 +13,7 @@ const portReplacement = ':7777777';
12
13
  // Special validation for file:// protocols
13
14
  if (/^file:\/\//.test(givenOrigin)) {
14
15
  output.error('Only a local file wildcard is currently allowed: file:///*', {
15
- exit: 1
16
+ exit: exitCodes.RUNTIME_ERROR
16
17
  });
17
18
  }
18
19
  try {
@@ -30,7 +31,7 @@ const portReplacement = ':7777777';
30
31
  return `${parsed.protocol}//${host}`;
31
32
  } catch {
32
33
  output.error(`Invalid origin "${givenOrigin}", must include protocol (https://some.host)`, {
33
- exit: 1
34
+ exit: exitCodes.RUNTIME_ERROR
34
35
  });
35
36
  }
36
37
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/cors/filterAndValidateOrigin.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\n\nconst wildcardReplacement = 'a-wild-card-r3pl4c3m3n7-a'\nconst portReplacement = ':7777777'\n\n/**\n * Filter and validate an origin, throwing an error if invalid.\n *\n * @internal\n */\nexport async function filterAndValidateOrigin(\n givenOrigin: string,\n output: Output,\n): Promise<string> {\n // Handle special cases that are always valid\n if (givenOrigin === '*' || givenOrigin === 'file:///*' || givenOrigin === 'null') {\n return givenOrigin\n }\n\n // Special validation for file:// protocols\n if (/^file:\\/\\//.test(givenOrigin)) {\n output.error('Only a local file wildcard is currently allowed: file:///*', {exit: 1})\n }\n\n try {\n const example = givenOrigin\n // Replace wildcards with placeholder values for URL parsing\n .replaceAll(/([^:])\\*/g, `$1${wildcardReplacement}`)\n // Replace port wildcards with placeholder value for URL parsing\n .replace(/:\\*/, portReplacement)\n\n const parsed = new URL(example)\n let host = parsed.host || ''\n\n // Remove default ports for http/https\n if (/^https?:$/.test(parsed.protocol || '')) {\n host = host.replace(/:(80|443)$/, '')\n }\n\n // Restore wildcards\n host = host.replaceAll(portReplacement, ':*').replaceAll(wildcardReplacement, '*')\n\n return `${parsed.protocol}//${host}`\n } catch {\n output.error(`Invalid origin \"${givenOrigin}\", must include protocol (https://some.host)`, {\n exit: 1,\n })\n }\n}\n"],"names":["wildcardReplacement","portReplacement","filterAndValidateOrigin","givenOrigin","output","test","error","exit","example","replaceAll","replace","parsed","URL","host","protocol"],"mappings":"AAEA,MAAMA,sBAAsB;AAC5B,MAAMC,kBAAkB;AAExB;;;;CAIC,GACD,OAAO,eAAeC,wBACpBC,WAAmB,EACnBC,MAAc;IAEd,6CAA6C;IAC7C,IAAID,gBAAgB,OAAOA,gBAAgB,eAAeA,gBAAgB,QAAQ;QAChF,OAAOA;IACT;IAEA,2CAA2C;IAC3C,IAAI,aAAaE,IAAI,CAACF,cAAc;QAClCC,OAAOE,KAAK,CAAC,8DAA8D;YAACC,MAAM;QAAC;IACrF;IAEA,IAAI;QACF,MAAMC,UAAUL,WACd,4DAA4D;SAC3DM,UAAU,CAAC,aAAa,CAAC,EAAE,EAAET,qBAAqB,CACnD,gEAAgE;SAC/DU,OAAO,CAAC,OAAOT;QAElB,MAAMU,SAAS,IAAIC,IAAIJ;QACvB,IAAIK,OAAOF,OAAOE,IAAI,IAAI;QAE1B,sCAAsC;QACtC,IAAI,YAAYR,IAAI,CAACM,OAAOG,QAAQ,IAAI,KAAK;YAC3CD,OAAOA,KAAKH,OAAO,CAAC,cAAc;QACpC;QAEA,oBAAoB;QACpBG,OAAOA,KAAKJ,UAAU,CAACR,iBAAiB,MAAMQ,UAAU,CAACT,qBAAqB;QAE9E,OAAO,GAAGW,OAAOG,QAAQ,CAAC,EAAE,EAAED,MAAM;IACtC,EAAE,OAAM;QACNT,OAAOE,KAAK,CAAC,CAAC,gBAAgB,EAAEH,YAAY,4CAA4C,CAAC,EAAE;YACzFI,MAAM;QACR;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/cors/filterAndValidateOrigin.ts"],"sourcesContent":["import {exitCodes, type Output} from '@sanity/cli-core'\n\nconst wildcardReplacement = 'a-wild-card-r3pl4c3m3n7-a'\nconst portReplacement = ':7777777'\n\n/**\n * Filter and validate an origin, throwing an error if invalid.\n *\n * @internal\n */\nexport async function filterAndValidateOrigin(\n givenOrigin: string,\n output: Output,\n): Promise<string> {\n // Handle special cases that are always valid\n if (givenOrigin === '*' || givenOrigin === 'file:///*' || givenOrigin === 'null') {\n return givenOrigin\n }\n\n // Special validation for file:// protocols\n if (/^file:\\/\\//.test(givenOrigin)) {\n output.error('Only a local file wildcard is currently allowed: file:///*', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n try {\n const example = givenOrigin\n // Replace wildcards with placeholder values for URL parsing\n .replaceAll(/([^:])\\*/g, `$1${wildcardReplacement}`)\n // Replace port wildcards with placeholder value for URL parsing\n .replace(/:\\*/, portReplacement)\n\n const parsed = new URL(example)\n let host = parsed.host || ''\n\n // Remove default ports for http/https\n if (/^https?:$/.test(parsed.protocol || '')) {\n host = host.replace(/:(80|443)$/, '')\n }\n\n // Restore wildcards\n host = host.replaceAll(portReplacement, ':*').replaceAll(wildcardReplacement, '*')\n\n return `${parsed.protocol}//${host}`\n } catch {\n output.error(`Invalid origin \"${givenOrigin}\", must include protocol (https://some.host)`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n}\n"],"names":["exitCodes","wildcardReplacement","portReplacement","filterAndValidateOrigin","givenOrigin","output","test","error","exit","RUNTIME_ERROR","example","replaceAll","replace","parsed","URL","host","protocol"],"mappings":"AAAA,SAAQA,SAAS,QAAoB,mBAAkB;AAEvD,MAAMC,sBAAsB;AAC5B,MAAMC,kBAAkB;AAExB;;;;CAIC,GACD,OAAO,eAAeC,wBACpBC,WAAmB,EACnBC,MAAc;IAEd,6CAA6C;IAC7C,IAAID,gBAAgB,OAAOA,gBAAgB,eAAeA,gBAAgB,QAAQ;QAChF,OAAOA;IACT;IAEA,2CAA2C;IAC3C,IAAI,aAAaE,IAAI,CAACF,cAAc;QAClCC,OAAOE,KAAK,CAAC,8DAA8D;YACzEC,MAAMR,UAAUS,aAAa;QAC/B;IACF;IAEA,IAAI;QACF,MAAMC,UAAUN,WACd,4DAA4D;SAC3DO,UAAU,CAAC,aAAa,CAAC,EAAE,EAAEV,qBAAqB,CACnD,gEAAgE;SAC/DW,OAAO,CAAC,OAAOV;QAElB,MAAMW,SAAS,IAAIC,IAAIJ;QACvB,IAAIK,OAAOF,OAAOE,IAAI,IAAI;QAE1B,sCAAsC;QACtC,IAAI,YAAYT,IAAI,CAACO,OAAOG,QAAQ,IAAI,KAAK;YAC3CD,OAAOA,KAAKH,OAAO,CAAC,cAAc;QACpC;QAEA,oBAAoB;QACpBG,OAAOA,KAAKJ,UAAU,CAACT,iBAAiB,MAAMS,UAAU,CAACV,qBAAqB;QAE9E,OAAO,GAAGY,OAAOG,QAAQ,CAAC,EAAE,EAAED,MAAM;IACtC,EAAE,OAAM;QACNV,OAAOE,KAAK,CAAC,CAAC,gBAAgB,EAAEH,YAAY,4CAA4C,CAAC,EAAE;YACzFI,MAAMR,UAAUS,aAAa;QAC/B;IACF;AACF"}
@@ -1,4 +1,5 @@
1
1
  import { CLIError } from '@oclif/core/errors';
2
+ import { exitCodes } from '@sanity/cli-core';
2
3
  import { input, spinner } from '@sanity/cli-core/ux';
3
4
  import { customAlphabet } from 'nanoid';
4
5
  import { createUserApplication as createUserApplicationRequest } from '../../services/userApplications.js';
@@ -71,7 +72,7 @@ export async function createStudioUserApplication(options) {
71
72
  deployDebug('Error creating user application', e);
72
73
  // otherwise, it's a fatal error
73
74
  throw new CLIError('Error creating user application', {
74
- exit: 1
75
+ exit: exitCodes.RUNTIME_ERROR
75
76
  });
76
77
  }
77
78
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/deploy/createUserApplication.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport {type AppVisibility} from '@sanity/cli-core'\nimport {input, spinner} from '@sanity/cli-core/ux'\nimport {customAlphabet} from 'nanoid'\n\nimport {\n createUserApplication as createUserApplicationRequest,\n type UserApplication,\n type UserApplicationResolved,\n} from '../../services/userApplications.js'\nimport {NO_ORGANIZATION_ID} from '../../util/errorMessages.js'\nimport {deployDebug} from './deployDebug.js'\nimport {normalizeUrl, validateUrl} from './urlUtils.js'\n\nconst LETTERS = 'abcdefghijklmnopqrstuvwxyz'\n\n// appHosts have some restrictions (no uppercase, must start with a letter)\nexport function generateAppSlug(): string {\n const firstChar = customAlphabet(LETTERS, 1)()\n const rest = customAlphabet(`${LETTERS}0123456789`, 11)()\n return `${firstChar}${rest}`\n}\n\n// TODO: replace with `Promise.withResolvers()` once it lands in node 22\nfunction promiseWithResolvers<T>() {\n let resolve!: (t: T) => void\n let reject!: (err: unknown) => void\n const promise = new Promise<T>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {promise, reject, resolve}\n}\n\ninterface CreateStudioUserApplicationOptions {\n projectId: string\n\n title?: string\n urlType?: 'external' | 'internal'\n}\n\nexport async function createStudioUserApplication(options: CreateStudioUserApplicationOptions) {\n const {projectId, title, urlType = 'internal'} = options\n const {promise, resolve} = promiseWithResolvers<UserApplication>()\n\n const isExternal = urlType === 'external'\n\n await input({\n message: isExternal ? 'Studio URL (https://...):' : 'Studio hostname (<value>.sanity.studio):',\n // if a string is returned here, it is relayed to the user and prompt allows\n // the user to try again until this function returns true\n validate: async (inp: string) => {\n let appHost: string\n\n if (isExternal) {\n const normalized = normalizeUrl(inp)\n const validation = validateUrl(normalized)\n if (validation !== true) {\n return validation\n }\n appHost = normalized\n } else {\n appHost = inp.replace(/\\.sanity\\.studio$/i, '')\n }\n\n try {\n const response = await createUserApplicationRequest({\n appType: 'studio',\n body: {appHost, title, type: 'studio', urlType},\n projectId,\n })\n resolve(response)\n return true\n } catch (e) {\n // if the name is taken, it should return a 409 so we relay to the user\n if ([402, 409].includes(e?.statusCode)) {\n return e?.response?.body?.message || 'Bad request' // just in case\n }\n\n deployDebug('Error creating user application', e)\n // otherwise, it's a fatal error\n throw new CLIError('Error creating user application', {exit: 1})\n }\n },\n })\n\n return await promise\n}\n\nexport async function createUserApplication(\n organizationId?: string,\n title?: string,\n visibility?: AppVisibility,\n): Promise<UserApplicationResolved> {\n if (!organizationId) {\n throw new Error(NO_ORGANIZATION_ID)\n }\n\n const resolvedTitle =\n title ??\n (await input({\n message: 'Enter a title for your application:',\n validate: (value: string) => value.length > 0 || 'Title is required',\n }))\n\n return tryCreateApp(resolvedTitle, organizationId, visibility)\n}\n\nconst tryCreateApp = async (title: string, organizationId: string, visibility?: AppVisibility) => {\n // we will likely prepend this with an org ID or other parameter in the future\n const appHost = generateAppSlug()\n\n const spin = spinner('Creating application').start()\n\n try {\n const response = await createUserApplicationRequest({\n appType: 'coreApp',\n body: {\n appHost,\n title,\n type: 'coreApp',\n urlType: 'internal',\n ...(visibility ? {dashboardStatus: visibility} : {}),\n },\n organizationId,\n })\n\n spin.succeed()\n return response\n } catch (e) {\n // if the name is taken, generate a new one and try again\n if ([402, 409].includes(e?.statusCode)) {\n deployDebug('App host taken, retrying with new host')\n return tryCreateApp(title, organizationId, visibility)\n }\n\n spin.fail()\n\n deployDebug('Error creating core application', e)\n throw e\n }\n}\n"],"names":["CLIError","input","spinner","customAlphabet","createUserApplication","createUserApplicationRequest","NO_ORGANIZATION_ID","deployDebug","normalizeUrl","validateUrl","LETTERS","generateAppSlug","firstChar","rest","promiseWithResolvers","resolve","reject","promise","Promise","res","rej","createStudioUserApplication","options","projectId","title","urlType","isExternal","message","validate","inp","appHost","normalized","validation","replace","response","appType","body","type","e","includes","statusCode","exit","organizationId","visibility","Error","resolvedTitle","value","length","tryCreateApp","spin","start","dashboardStatus","succeed","fail"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/deploy/createUserApplication.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport {type AppVisibility, exitCodes} from '@sanity/cli-core'\nimport {input, spinner} from '@sanity/cli-core/ux'\nimport {customAlphabet} from 'nanoid'\n\nimport {\n createUserApplication as createUserApplicationRequest,\n type UserApplication,\n type UserApplicationResolved,\n} from '../../services/userApplications.js'\nimport {NO_ORGANIZATION_ID} from '../../util/errorMessages.js'\nimport {deployDebug} from './deployDebug.js'\nimport {normalizeUrl, validateUrl} from './urlUtils.js'\n\nconst LETTERS = 'abcdefghijklmnopqrstuvwxyz'\n\n// appHosts have some restrictions (no uppercase, must start with a letter)\nexport function generateAppSlug(): string {\n const firstChar = customAlphabet(LETTERS, 1)()\n const rest = customAlphabet(`${LETTERS}0123456789`, 11)()\n return `${firstChar}${rest}`\n}\n\n// TODO: replace with `Promise.withResolvers()` once it lands in node 22\nfunction promiseWithResolvers<T>() {\n let resolve!: (t: T) => void\n let reject!: (err: unknown) => void\n const promise = new Promise<T>((res, rej) => {\n resolve = res\n reject = rej\n })\n return {promise, reject, resolve}\n}\n\ninterface CreateStudioUserApplicationOptions {\n projectId: string\n\n title?: string\n urlType?: 'external' | 'internal'\n}\n\nexport async function createStudioUserApplication(options: CreateStudioUserApplicationOptions) {\n const {projectId, title, urlType = 'internal'} = options\n const {promise, resolve} = promiseWithResolvers<UserApplication>()\n\n const isExternal = urlType === 'external'\n\n await input({\n message: isExternal ? 'Studio URL (https://...):' : 'Studio hostname (<value>.sanity.studio):',\n // if a string is returned here, it is relayed to the user and prompt allows\n // the user to try again until this function returns true\n validate: async (inp: string) => {\n let appHost: string\n\n if (isExternal) {\n const normalized = normalizeUrl(inp)\n const validation = validateUrl(normalized)\n if (validation !== true) {\n return validation\n }\n appHost = normalized\n } else {\n appHost = inp.replace(/\\.sanity\\.studio$/i, '')\n }\n\n try {\n const response = await createUserApplicationRequest({\n appType: 'studio',\n body: {appHost, title, type: 'studio', urlType},\n projectId,\n })\n resolve(response)\n return true\n } catch (e) {\n // if the name is taken, it should return a 409 so we relay to the user\n if ([402, 409].includes(e?.statusCode)) {\n return e?.response?.body?.message || 'Bad request' // just in case\n }\n\n deployDebug('Error creating user application', e)\n // otherwise, it's a fatal error\n throw new CLIError('Error creating user application', {exit: exitCodes.RUNTIME_ERROR})\n }\n },\n })\n\n return await promise\n}\n\nexport async function createUserApplication(\n organizationId?: string,\n title?: string,\n visibility?: AppVisibility,\n): Promise<UserApplicationResolved> {\n if (!organizationId) {\n throw new Error(NO_ORGANIZATION_ID)\n }\n\n const resolvedTitle =\n title ??\n (await input({\n message: 'Enter a title for your application:',\n validate: (value: string) => value.length > 0 || 'Title is required',\n }))\n\n return tryCreateApp(resolvedTitle, organizationId, visibility)\n}\n\nconst tryCreateApp = async (title: string, organizationId: string, visibility?: AppVisibility) => {\n // we will likely prepend this with an org ID or other parameter in the future\n const appHost = generateAppSlug()\n\n const spin = spinner('Creating application').start()\n\n try {\n const response = await createUserApplicationRequest({\n appType: 'coreApp',\n body: {\n appHost,\n title,\n type: 'coreApp',\n urlType: 'internal',\n ...(visibility ? {dashboardStatus: visibility} : {}),\n },\n organizationId,\n })\n\n spin.succeed()\n return response\n } catch (e) {\n // if the name is taken, generate a new one and try again\n if ([402, 409].includes(e?.statusCode)) {\n deployDebug('App host taken, retrying with new host')\n return tryCreateApp(title, organizationId, visibility)\n }\n\n spin.fail()\n\n deployDebug('Error creating core application', e)\n throw e\n }\n}\n"],"names":["CLIError","exitCodes","input","spinner","customAlphabet","createUserApplication","createUserApplicationRequest","NO_ORGANIZATION_ID","deployDebug","normalizeUrl","validateUrl","LETTERS","generateAppSlug","firstChar","rest","promiseWithResolvers","resolve","reject","promise","Promise","res","rej","createStudioUserApplication","options","projectId","title","urlType","isExternal","message","validate","inp","appHost","normalized","validation","replace","response","appType","body","type","e","includes","statusCode","exit","RUNTIME_ERROR","organizationId","visibility","Error","resolvedTitle","value","length","tryCreateApp","spin","start","dashboardStatus","succeed","fail"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { CLIError } from '@oclif/core/errors';
2
+ import { exitCodes } from '@sanity/cli-core';
2
3
  import { getErrorMessage } from '@sanity/cli-core/errors';
3
4
  import { createCollectingReporter, createFailFastReporter } from '../../util/checks.js';
4
5
  import { toStderrOutput } from '../../util/toStderrOutput.js';
@@ -77,7 +78,7 @@ import { deploymentPlanToJson, isDeployable, renderDeploymentPlan } from './depl
77
78
  // Ctrl+C on an interactive prompt isn't a real failure
78
79
  if (error instanceof Error && error.name === 'ExitPromptError') {
79
80
  return {
80
- exit: 1,
81
+ exit: exitCodes.RUNTIME_ERROR,
81
82
  message: 'Deployment cancelled by user'
82
83
  };
83
84
  }
@@ -90,7 +91,7 @@ import { deploymentPlanToJson, isDeployable, renderDeploymentPlan } from './depl
90
91
  }
91
92
  deployDebug(`Error deploying ${type === 'coreApp' ? 'application' : 'studio'}`, error);
92
93
  return {
93
- exit: 1,
94
+ exit: exitCodes.RUNTIME_ERROR,
94
95
  message: `Error deploying ${type === 'coreApp' ? 'application' : 'studio'}: ${getErrorMessage(error)}`
95
96
  };
96
97
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/deploy/deployRunner.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport {type Output} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {type WorkbenchDeployPayload} from '@sanity/workbench-cli/deploy'\n\nimport {createCollectingReporter, createFailFastReporter} from '../../util/checks.js'\nimport {toStderrOutput} from '../../util/toStderrOutput.js'\nimport {type DeployCheck, type DeployCheckReporter, type DeployTarget} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {\n type DeploymentFile,\n type DeploymentPlan,\n deploymentPlanToJson,\n isDeployable,\n renderDeploymentPlan,\n} from './deploymentPlan.js'\nimport {type DeployAppOptions} from './types.js'\n\nexport interface DeployResult {\n application: object | null\n payload: DeployPayload\n\n action?: DeployTarget['action']\n /** Resolved server-side, so it stays out of the local payload. */\n installationId?: string\n url?: string | null\n}\n\n/** Collected locally, so a dry run reports it too. */\nexport interface DeployPayload extends Partial<WorkbenchDeployPayload> {\n /** The configured `deployment.appId`; `null` when the deploy would mint one. */\n appId: string | null\n isAutoUpdating: boolean\n type: 'coreApp' | 'studio'\n version: string | null\n\n organizationId?: string\n projectId?: string\n}\n\n/**\n * The parts of a deploy that differ between core apps and studios. The shared\n * sequence — mode selection, error handling, the dry-run plan, `--json` — lives\n * in `runDeploy`.\n */\nexport interface DeploySpec {\n /** Files a real deploy would upload, listed only for the dry-run plan. */\n listFiles: (options: DeployAppOptions) => Promise<DeploymentFile[]>\n /** The step sequence; every step reports through `reporter`. */\n run: (options: DeployAppOptions, reporter: DeployCheckReporter) => Promise<DeployResult | void>\n type: 'coreApp' | 'studio'\n}\n\n/**\n * Runs a deploy in the mode the flags select: a real deploy fails fast and\n * mutates, `--dry-run` drives the same `run` sequence read-only and renders a\n * plan, and `--json` emits the same information as machine-readable JSON.\n */\nexport async function runDeploy(options: DeployAppOptions, spec: DeploySpec): Promise<void> {\n const {output} = options\n const json = !!options.flags.json\n const emitJson = (payload: unknown) => output.log(JSON.stringify(payload, null, 2))\n\n // The JSON payload owns stdout, so the run's progress logs go to stderr; only\n // the final JSON.stringify writes to stdout.\n const runOptions = json ? {...options, output: toStderrOutput(output)} : options\n\n try {\n if (options.flags['dry-run']) {\n const plan = await collectPlan(runOptions, spec)\n if (json) emitJson(deploymentPlanToJson(plan))\n else renderDeploymentPlan(plan, output)\n exitIfBlocked(plan, output)\n return\n }\n\n const result = await spec.run(runOptions, createFailFastReporter(runOptions.output))\n if (json && result) emitJson({deployed: true, reason: null, ...result})\n } catch (error) {\n const failure = normalizeFailure(error, spec.type)\n // A blocked dry run reaches this catch too (its exit throws) and already\n // printed its plan, so only a real deploy adds the {deployed: false} envelope.\n if (json && !options.flags['dry-run']) {\n emitJson({\n application: null,\n deployed: false,\n error: {message: failure.message},\n payload: null,\n reason: failure.message,\n })\n }\n output.error(failure.message, {exit: failure.exit})\n }\n}\n\n/** Runs the step sequence read-only and gathers the plan a dry run reports. */\nasync function collectPlan(options: DeployAppOptions, spec: DeploySpec): Promise<DeploymentPlan> {\n const reporter = createCollectingReporter<DeployCheck>()\n const result = await spec.run(options, reporter)\n const plan: DeploymentPlan = {\n checks: reporter.results,\n files: [],\n payload: result?.payload ?? null,\n target:\n reporter.results.find((check) => check.target && check.status !== 'fail')?.target ?? null,\n type: spec.type,\n }\n // A blocked deploy uploads nothing, so only enumerate files for a deployable plan.\n if (isDeployable(plan)) plan.files = await spec.listFiles(options)\n return plan\n}\n\n/** Exits like a real (fail-fast) deploy would, on the first failing check's exit code. */\nfunction exitIfBlocked(plan: DeploymentPlan, output: Output): void {\n if (isDeployable(plan)) return\n const failed = plan.checks.find((check) => check.status === 'fail')\n output.error('Deploy blocked by failing checks.', {exit: failed?.exitCode ?? 1})\n}\n\n/** The one failure diagnosis both the stderr message and the `--json` envelope read. */\nfunction normalizeFailure(\n error: unknown,\n type: 'coreApp' | 'studio',\n): {exit: number; message: string} {\n // Ctrl+C on an interactive prompt isn't a real failure\n if (error instanceof Error && error.name === 'ExitPromptError') {\n return {exit: 1, message: 'Deployment cancelled by user'}\n }\n // A failed check already carries its own message and exit code\n if (error instanceof CLIError) {\n return {exit: error.oclif?.exit ?? 1, message: error.message}\n }\n deployDebug(`Error deploying ${type === 'coreApp' ? 'application' : 'studio'}`, error)\n return {\n exit: 1,\n message: `Error deploying ${type === 'coreApp' ? 'application' : 'studio'}: ${getErrorMessage(error)}`,\n }\n}\n"],"names":["CLIError","getErrorMessage","createCollectingReporter","createFailFastReporter","toStderrOutput","deployDebug","deploymentPlanToJson","isDeployable","renderDeploymentPlan","runDeploy","options","spec","output","json","flags","emitJson","payload","log","JSON","stringify","runOptions","plan","collectPlan","exitIfBlocked","result","run","deployed","reason","error","failure","normalizeFailure","type","application","message","exit","reporter","checks","results","files","target","find","check","status","listFiles","failed","exitCode","Error","name","oclif"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/deploy/deployRunner.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport {exitCodes, type Output} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {type WorkbenchDeployPayload} from '@sanity/workbench-cli/deploy'\n\nimport {createCollectingReporter, createFailFastReporter} from '../../util/checks.js'\nimport {toStderrOutput} from '../../util/toStderrOutput.js'\nimport {type DeployCheck, type DeployCheckReporter, type DeployTarget} from './deployChecks.js'\nimport {deployDebug} from './deployDebug.js'\nimport {\n type DeploymentFile,\n type DeploymentPlan,\n deploymentPlanToJson,\n isDeployable,\n renderDeploymentPlan,\n} from './deploymentPlan.js'\nimport {type DeployAppOptions} from './types.js'\n\nexport interface DeployResult {\n application: object | null\n payload: DeployPayload\n\n action?: DeployTarget['action']\n /** Resolved server-side, so it stays out of the local payload. */\n installationId?: string\n url?: string | null\n}\n\n/** Collected locally, so a dry run reports it too. */\nexport interface DeployPayload extends Partial<WorkbenchDeployPayload> {\n /** The configured `deployment.appId`; `null` when the deploy would mint one. */\n appId: string | null\n isAutoUpdating: boolean\n type: 'coreApp' | 'studio'\n version: string | null\n\n organizationId?: string\n projectId?: string\n}\n\n/**\n * The parts of a deploy that differ between core apps and studios. The shared\n * sequence — mode selection, error handling, the dry-run plan, `--json` — lives\n * in `runDeploy`.\n */\nexport interface DeploySpec {\n /** Files a real deploy would upload, listed only for the dry-run plan. */\n listFiles: (options: DeployAppOptions) => Promise<DeploymentFile[]>\n /** The step sequence; every step reports through `reporter`. */\n run: (options: DeployAppOptions, reporter: DeployCheckReporter) => Promise<DeployResult | void>\n type: 'coreApp' | 'studio'\n}\n\n/**\n * Runs a deploy in the mode the flags select: a real deploy fails fast and\n * mutates, `--dry-run` drives the same `run` sequence read-only and renders a\n * plan, and `--json` emits the same information as machine-readable JSON.\n */\nexport async function runDeploy(options: DeployAppOptions, spec: DeploySpec): Promise<void> {\n const {output} = options\n const json = !!options.flags.json\n const emitJson = (payload: unknown) => output.log(JSON.stringify(payload, null, 2))\n\n // The JSON payload owns stdout, so the run's progress logs go to stderr; only\n // the final JSON.stringify writes to stdout.\n const runOptions = json ? {...options, output: toStderrOutput(output)} : options\n\n try {\n if (options.flags['dry-run']) {\n const plan = await collectPlan(runOptions, spec)\n if (json) emitJson(deploymentPlanToJson(plan))\n else renderDeploymentPlan(plan, output)\n exitIfBlocked(plan, output)\n return\n }\n\n const result = await spec.run(runOptions, createFailFastReporter(runOptions.output))\n if (json && result) emitJson({deployed: true, reason: null, ...result})\n } catch (error) {\n const failure = normalizeFailure(error, spec.type)\n // A blocked dry run reaches this catch too (its exit throws) and already\n // printed its plan, so only a real deploy adds the {deployed: false} envelope.\n if (json && !options.flags['dry-run']) {\n emitJson({\n application: null,\n deployed: false,\n error: {message: failure.message},\n payload: null,\n reason: failure.message,\n })\n }\n output.error(failure.message, {exit: failure.exit})\n }\n}\n\n/** Runs the step sequence read-only and gathers the plan a dry run reports. */\nasync function collectPlan(options: DeployAppOptions, spec: DeploySpec): Promise<DeploymentPlan> {\n const reporter = createCollectingReporter<DeployCheck>()\n const result = await spec.run(options, reporter)\n const plan: DeploymentPlan = {\n checks: reporter.results,\n files: [],\n payload: result?.payload ?? null,\n target:\n reporter.results.find((check) => check.target && check.status !== 'fail')?.target ?? null,\n type: spec.type,\n }\n // A blocked deploy uploads nothing, so only enumerate files for a deployable plan.\n if (isDeployable(plan)) plan.files = await spec.listFiles(options)\n return plan\n}\n\n/** Exits like a real (fail-fast) deploy would, on the first failing check's exit code. */\nfunction exitIfBlocked(plan: DeploymentPlan, output: Output): void {\n if (isDeployable(plan)) return\n const failed = plan.checks.find((check) => check.status === 'fail')\n output.error('Deploy blocked by failing checks.', {exit: failed?.exitCode ?? 1})\n}\n\n/** The one failure diagnosis both the stderr message and the `--json` envelope read. */\nfunction normalizeFailure(\n error: unknown,\n type: 'coreApp' | 'studio',\n): {exit: number; message: string} {\n // Ctrl+C on an interactive prompt isn't a real failure\n if (error instanceof Error && error.name === 'ExitPromptError') {\n return {exit: exitCodes.RUNTIME_ERROR, message: 'Deployment cancelled by user'}\n }\n // A failed check already carries its own message and exit code\n if (error instanceof CLIError) {\n return {exit: error.oclif?.exit ?? 1, message: error.message}\n }\n deployDebug(`Error deploying ${type === 'coreApp' ? 'application' : 'studio'}`, error)\n return {\n exit: exitCodes.RUNTIME_ERROR,\n message: `Error deploying ${type === 'coreApp' ? 'application' : 'studio'}: ${getErrorMessage(error)}`,\n }\n}\n"],"names":["CLIError","exitCodes","getErrorMessage","createCollectingReporter","createFailFastReporter","toStderrOutput","deployDebug","deploymentPlanToJson","isDeployable","renderDeploymentPlan","runDeploy","options","spec","output","json","flags","emitJson","payload","log","JSON","stringify","runOptions","plan","collectPlan","exitIfBlocked","result","run","deployed","reason","error","failure","normalizeFailure","type","application","message","exit","reporter","checks","results","files","target","find","check","status","listFiles","failed","exitCode","Error","name","RUNTIME_ERROR","oclif"],"mappings":"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"}
@@ -315,16 +315,16 @@ export function deployStudio(options) {
315
315
  deployDebug('Error deploying studio schemas and manifests', error);
316
316
  if (error instanceof SchemaExtractionError && error.validation?.length) {
317
317
  output.error(formatSchemaValidation(error.validation), {
318
- exit: 1
318
+ exit: exitCodes.RUNTIME_ERROR
319
319
  });
320
320
  }
321
321
  output.error(`Error deploying studio schemas and manifests: ${error}`, {
322
- exit: 1
322
+ exit: exitCodes.RUNTIME_ERROR
323
323
  });
324
324
  }
325
325
  if (!studioManifest) {
326
326
  output.error('Failed to generate studio manifest. Please check your schemas and manifests.', {
327
- exit: 1
327
+ exit: exitCodes.RUNTIME_ERROR
328
328
  });
329
329
  }
330
330
  return studioManifest;