@sanity/cli 7.3.0 → 7.4.1

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 (61) hide show
  1. package/README.md +25 -1
  2. package/dist/actions/build/buildApp.js +19 -14
  3. package/dist/actions/build/buildApp.js.map +1 -1
  4. package/dist/actions/build/buildStaticFiles.js +1 -1
  5. package/dist/actions/build/buildStaticFiles.js.map +1 -1
  6. package/dist/actions/build/buildStudio.js +22 -18
  7. package/dist/actions/build/buildStudio.js.map +1 -1
  8. package/dist/actions/dev/devAction.js +46 -197
  9. package/dist/actions/dev/devAction.js.map +1 -1
  10. package/dist/actions/dev/servers/getDevServerConfig.js +1 -1
  11. package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
  12. package/dist/actions/dev/servers/startAppDevServer.js +18 -9
  13. package/dist/actions/dev/servers/startAppDevServer.js.map +1 -1
  14. package/dist/actions/dev/servers/startStudioDevServer.js +2 -2
  15. package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
  16. package/dist/actions/dev/types.js.map +1 -1
  17. package/dist/actions/init/scaffoldTemplate.js +3 -12
  18. package/dist/actions/init/scaffoldTemplate.js.map +1 -1
  19. package/dist/actions/init/templates/pageBuilder.js +1 -1
  20. package/dist/actions/init/templates/pageBuilder.js.map +1 -1
  21. package/dist/actions/{dev/registration/extractDevServerManifest.js → manifest/extractStudioManifest.js} +3 -3
  22. package/dist/actions/manifest/extractStudioManifest.js.map +1 -0
  23. package/dist/actions/mcp/editorConfigs.js +8 -4
  24. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  25. package/dist/commands/datasets/copy.js +17 -19
  26. package/dist/commands/datasets/copy.js.map +1 -1
  27. package/dist/commands/datasets/import.js +11 -15
  28. package/dist/commands/datasets/import.js.map +1 -1
  29. package/dist/commands/doctor.js +9 -9
  30. package/dist/commands/doctor.js.map +1 -1
  31. package/dist/commands/telemetry/disable.js +3 -3
  32. package/dist/commands/telemetry/disable.js.map +1 -1
  33. package/dist/commands/telemetry/enable.js +3 -3
  34. package/dist/commands/telemetry/enable.js.map +1 -1
  35. package/dist/commands/telemetry/status.js +2 -2
  36. package/dist/commands/telemetry/status.js.map +1 -1
  37. package/dist/exports/_internal.d.ts +4 -47
  38. package/dist/exports/_internal.js +1 -1
  39. package/dist/exports/_internal.js.map +1 -1
  40. package/dist/server/devServer.js +1 -1
  41. package/dist/server/devServer.js.map +1 -1
  42. package/dist/util/compareDependencyVersions.js.map +1 -1
  43. package/dist/util/resolveLatestVersions.js +20 -2
  44. package/dist/util/resolveLatestVersions.js.map +1 -1
  45. package/oclif.manifest.json +1 -1
  46. package/package.json +14 -16
  47. package/dist/actions/build/getEnvironmentVariables.js +0 -54
  48. package/dist/actions/build/getEnvironmentVariables.js.map +0 -1
  49. package/dist/actions/dev/registration/deriveInterfaces.js +0 -46
  50. package/dist/actions/dev/registration/deriveInterfaces.js.map +0 -1
  51. package/dist/actions/dev/registration/extractDevServerManifest.js.map +0 -1
  52. package/dist/actions/dev/registration/interfaceSetId.js +0 -41
  53. package/dist/actions/dev/registration/interfaceSetId.js.map +0 -1
  54. package/dist/actions/dev/registration/startDevManifestWatcher.js +0 -104
  55. package/dist/actions/dev/registration/startDevManifestWatcher.js.map +0 -1
  56. package/dist/actions/dev/registration/startDevServerRegistration.js +0 -121
  57. package/dist/actions/dev/registration/startDevServerRegistration.js.map +0 -1
  58. package/dist/actions/dev/workbench/startWorkbenchDevServer.js +0 -276
  59. package/dist/actions/dev/workbench/startWorkbenchDevServer.js.map +0 -1
  60. package/dist/actions/dev/workbench/writeWorkbenchRuntime.js +0 -66
  61. package/dist/actions/dev/workbench/writeWorkbenchRuntime.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/datasets/import.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {sanityImport} from '@sanity/import'\nimport prettyMs from 'pretty-ms'\n\nimport {NEW_DATASET_VALUE, promptForDataset} from '../../prompts/promptForDataset.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {createDataset, listDatasets} from '../../services/datasets.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst importDebug = subdebug('dataset:import')\n\ninterface ProgressEvent {\n step: string\n\n current?: number\n total?: number\n update?: string\n}\n\nfunction getAssetsBase(source: string): string | undefined {\n if (/^https?:\\/\\//i.test(source) || source === '-') {\n return undefined\n }\n\n try {\n const fileStats = fs.statSync(source)\n const sourceIsFolder = fileStats.isDirectory()\n return sourceIsFolder ? source : path.dirname(source)\n } catch {\n return undefined\n }\n}\n\nasync function getUriStream(uri: string): Promise<NodeJS.ReadableStream> {\n const request = createRequester({\n middleware: {promise: {onlyBody: false}},\n })\n\n try {\n const response = (await request({stream: true, url: uri})) as {body: NodeJS.ReadableStream}\n return response.body\n } catch (err) {\n throw new Error(`Error fetching source:\\n${(err as Error).message}`, {cause: err})\n }\n}\n\nfunction getPercentage(opts: ProgressEvent): string {\n if (!opts.total) {\n return ''\n }\n\n const percent = Math.floor(((opts.current || 0) / opts.total) * 100)\n return `[${percent}%] `\n}\n\nexport class ImportDatasetCommand extends SanityCommand<typeof ImportDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Source file (use \"-\" for stdin)',\n required: true,\n }),\n targetDataset: Args.string({\n description: 'Target dataset (prefer --dataset flag instead)',\n required: false,\n }),\n }\n\n static override description = 'Import documents to a Sanity dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> -d staging my-dataset.ndjson',\n description: 'Import \"./my-dataset.ndjson\" into dataset \"staging\"',\n },\n {\n command: 'cat my-dataset.ndjson | <%= config.bin %> <%= command.id %> -d test -',\n description: 'Import into dataset \"test\" from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> -p projectId -d staging my-dataset.ndjson',\n description: 'Import with explicit project ID (overrides CLI configuration)',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -d staging -t someSecretToken my-dataset.ndjson',\n description: 'Import with an explicit token (e.g. for CI/CD)',\n },\n ]\n\n static override flags = {\n 'allow-assets-in-different-dataset': Flags.boolean({\n default: false,\n description: 'Allow asset documents to reference different project/dataset',\n }),\n 'allow-failing-assets': Flags.boolean({\n default: false,\n description: 'Skip assets that cannot be fetched/uploaded',\n }),\n 'allow-replacement-characters': Flags.boolean({\n default: false,\n description: 'Allow unicode replacement characters in imported documents',\n }),\n 'allow-system-documents': Flags.boolean({\n default: false,\n description: 'Imports system documents',\n }),\n 'asset-concurrency': Flags.integer({\n description: 'Number of parallel asset imports',\n }),\n ...getDatasetFlag({\n description: 'Dataset to import to',\n semantics: 'specify',\n }),\n missing: Flags.boolean({\n default: false,\n description: 'Skip documents that already exist',\n exclusive: ['replace'],\n }),\n ...getProjectIdFlag({\n description: 'Project ID to import to',\n semantics: 'override',\n }),\n project: Flags.string({\n deprecated: {to: 'project-id'},\n description: 'Project ID to import to',\n hidden: true,\n }),\n replace: Flags.boolean({\n default: false,\n description: 'Replace documents with the same IDs',\n exclusive: ['missing'],\n }),\n 'replace-assets': Flags.boolean({\n default: false,\n description: 'Skip reuse of existing assets',\n }),\n 'skip-cross-dataset-references': Flags.boolean({\n default: false,\n description: 'Skips references to other datasets',\n }),\n token: Flags.string({\n char: 't',\n description: 'Token to authenticate with',\n env: 'SANITY_IMPORT_TOKEN',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:import']\n\n private currentProgress?: ReturnType<typeof spinner>\n private currentStep?: string\n private spinInterval?: NodeJS.Timeout | null\n private stepStart?: number\n\n private static async getStream(source: string): Promise<NodeJS.ReadableStream> {\n if (/^https?:\\/\\//i.test(source)) {\n return getUriStream(source)\n }\n\n return source === '-' ? process.stdin : fs.createReadStream(source)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ImportDatasetCommand)\n\n const {\n 'allow-assets-in-different-dataset': allowAssetsInDifferentDataset,\n 'allow-failing-assets': allowFailingAssets,\n 'allow-replacement-characters': allowReplacementCharacters,\n 'allow-system-documents': allowSystemDocuments,\n 'asset-concurrency': assetConcurrency,\n dataset: datasetFlag,\n missing,\n replace,\n 'replace-assets': replaceAssets,\n 'skip-cross-dataset-references': skipCrossDatasetReferences,\n token,\n } = flags\n\n const projectId = await this.getProjectId({\n deprecatedFlagName: 'project',\n fallback: () => promptForProject({}),\n })\n\n const {source, targetDataset: targetDatasetArg} = args\n\n if (targetDatasetArg && !datasetFlag) {\n this.warn(\n 'Positional dataset argument is deprecated. Use the --dataset flag instead: --dataset <name>',\n )\n }\n\n let dataset = datasetFlag ?? targetDatasetArg\n if (!dataset) {\n if (this.isUnattended()) {\n this.error(\n 'Missing dataset. Use the --dataset flag to specify a dataset: --dataset <name>',\n {exit: 1},\n )\n }\n\n const datasets = await listDatasets(projectId)\n dataset = await promptForDataset({allowCreation: true, datasets})\n\n if (dataset === NEW_DATASET_VALUE) {\n const newDatasetName = await promptForDatasetName()\n\n try {\n await createDataset({datasetName: newDatasetName, projectId})\n dataset = newDatasetName\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n importDebug(`Failed to create dataset ${newDatasetName}: ${message}`, error)\n this.error(`Failed to create dataset ${newDatasetName}: ${message}`, {exit: 1})\n }\n }\n }\n\n let operation: 'create' | 'createIfNotExists' | 'createOrReplace' = 'create'\n let releasesOperation: 'fail' | 'ignore' | 'replace' = 'fail'\n\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n releasesOperation = replace ? 'replace' : 'ignore'\n }\n\n const client = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n projectId,\n requireUser: true,\n ...(token ? {token} : {}),\n })\n\n try {\n const stream = await ImportDatasetCommand.getStream(source)\n const assetsBase = getAssetsBase(source)\n\n const importOptions = {\n allowAssetsInDifferentDataset,\n allowFailingAssets,\n allowReplacementCharacters,\n allowSystemDocuments,\n client,\n onProgress: this.onProgress.bind(this),\n operation,\n releasesOperation,\n replaceAssets,\n skipCrossDatasetReferences,\n tag: 'sanity.import',\n targetDataset: dataset,\n targetProjectId: projectId,\n ...(assetsBase ? {assetsBase} : {}),\n ...(assetConcurrency === undefined ? {} : {assetConcurrency}),\n }\n\n const {numDocs, warnings} = await sanityImport(stream as NodeJS.ReadableStream, importOptions)\n\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n this.currentProgress.text = `[100%] ${this.currentStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n }\n\n this.log('Done! Imported %d documents to dataset \"%s\"\\n', numDocs, dataset)\n this.printWarnings(warnings)\n } catch (err) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress) {\n this.currentProgress.fail()\n }\n\n if ((err as Error).name === 'ReplacementCharError') {\n this.error(\n `Import failed due to unicode replacement characters in the data.\\n${(err as Error).message}\\n\\nIf you are certain you want to proceed with the import despite potentially corrupt data, re-run the import with the \\`--allow-replacement-characters\\` flag set.`,\n {exit: 1},\n )\n } else {\n this.error((err as Error).stack || (err as Error).message, {exit: 1})\n }\n }\n }\n\n private onProgress(opts: ProgressEvent): void {\n const lengthComputable = opts.total\n const sameStep = opts.step === this.currentStep\n const percent = getPercentage(opts)\n\n if (lengthComputable && opts.total === opts.current && this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (sameStep && !lengthComputable) {\n return\n }\n\n if (sameStep) {\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }\n return\n }\n\n // Moved to a new step\n const prevStep = this.currentStep\n const prevStepStart = this.stepStart\n this.stepStart = Date.now()\n this.currentStep = opts.step\n\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress && this.currentProgress.succeed && prevStepStart) {\n const timeSpent = prettyMs(Date.now() - prevStepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `[100%] ${prevStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n\n this.currentProgress = spinner(`[0%] ${opts.step} (0.00s)`).start()\n\n if (!lengthComputable) {\n this.spinInterval = setInterval(() => {\n if (this.stepStart && this.currentProgress) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }, 60)\n }\n }\n\n private printWarnings(warnings: Array<{message: string; type?: string; url?: string}>): void {\n const assetFails = warnings.filter((warn) => warn.type === 'asset')\n\n if (assetFails.length === 0) {\n return\n }\n\n this.warn(`Failed to import the following ${assetFails.length > 1 ? 'assets' : 'asset'}:`)\n\n for (const warning of assetFails) {\n if (warning.url) {\n this.warn(` ${warning.url}`)\n }\n }\n }\n}\n"],"names":["fs","path","Args","Flags","getProjectCliClient","SanityCommand","subdebug","createRequester","spinner","sanityImport","prettyMs","NEW_DATASET_VALUE","promptForDataset","promptForDatasetName","promptForProject","createDataset","listDatasets","getDatasetFlag","getProjectIdFlag","importDebug","getAssetsBase","source","test","undefined","fileStats","statSync","sourceIsFolder","isDirectory","dirname","getUriStream","uri","request","middleware","promise","onlyBody","response","stream","url","body","err","Error","message","cause","getPercentage","opts","total","percent","Math","floor","current","ImportDatasetCommand","args","string","description","required","targetDataset","examples","command","flags","boolean","default","integer","semantics","missing","exclusive","project","deprecated","to","hidden","replace","token","char","env","hiddenAliases","currentProgress","currentStep","spinInterval","stepStart","getStream","process","stdin","createReadStream","run","parse","allowAssetsInDifferentDataset","allowFailingAssets","allowReplacementCharacters","allowSystemDocuments","assetConcurrency","dataset","datasetFlag","replaceAssets","skipCrossDatasetReferences","projectId","getProjectId","deprecatedFlagName","fallback","targetDatasetArg","warn","isUnattended","error","exit","datasets","allowCreation","newDatasetName","datasetName","String","operation","releasesOperation","client","apiVersion","requireUser","assetsBase","importOptions","onProgress","bind","tag","targetProjectId","numDocs","warnings","timeSpent","Date","now","secondsDecimalDigits","clearInterval","text","succeed","log","printWarnings","fail","name","stack","lengthComputable","sameStep","step","render","prevStep","prevStepStart","start","setInterval","assetFails","filter","type","length","warning"],"mappings":"AAAA,OAAOA,QAAQ,UAAS;AACxB,OAAOC,UAAU,YAAW;AAE5B,SAAQC,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,mBAAmB,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAC7E,SAAQC,eAAe,QAAO,2BAA0B;AACxD,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,YAAY,QAAO,iBAAgB;AAC3C,OAAOC,cAAc,YAAW;AAEhC,SAAQC,iBAAiB,EAAEC,gBAAgB,QAAO,oCAAmC;AACrF,SAAQC,oBAAoB,QAAO,wCAAuC;AAC1E,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,aAAa,EAAEC,YAAY,QAAO,6BAA4B;AACtE,SAAQC,cAAc,EAAEC,gBAAgB,QAAO,4BAA2B;AAE1E,MAAMC,cAAcb,SAAS;AAU7B,SAASc,cAAcC,MAAc;IACnC,IAAI,gBAAgBC,IAAI,CAACD,WAAWA,WAAW,KAAK;QAClD,OAAOE;IACT;IAEA,IAAI;QACF,MAAMC,YAAYxB,GAAGyB,QAAQ,CAACJ;QAC9B,MAAMK,iBAAiBF,UAAUG,WAAW;QAC5C,OAAOD,iBAAiBL,SAASpB,KAAK2B,OAAO,CAACP;IAChD,EAAE,OAAM;QACN,OAAOE;IACT;AACF;AAEA,eAAeM,aAAaC,GAAW;IACrC,MAAMC,UAAUxB,gBAAgB;QAC9ByB,YAAY;YAACC,SAAS;gBAACC,UAAU;YAAK;QAAC;IACzC;IAEA,IAAI;QACF,MAAMC,WAAY,MAAMJ,QAAQ;YAACK,QAAQ;YAAMC,KAAKP;QAAG;QACvD,OAAOK,SAASG,IAAI;IACtB,EAAE,OAAOC,KAAK;QACZ,MAAM,IAAIC,MAAM,CAAC,wBAAwB,EAAE,AAACD,IAAcE,OAAO,EAAE,EAAE;YAACC,OAAOH;QAAG;IAClF;AACF;AAEA,SAASI,cAAcC,IAAmB;IACxC,IAAI,CAACA,KAAKC,KAAK,EAAE;QACf,OAAO;IACT;IAEA,MAAMC,UAAUC,KAAKC,KAAK,CAAC,AAAEJ,CAAAA,KAAKK,OAAO,IAAI,CAAA,IAAKL,KAAKC,KAAK,GAAI;IAChE,OAAO,CAAC,CAAC,EAAEC,QAAQ,GAAG,CAAC;AACzB;AAEA,OAAO,MAAMI,6BAA6B7C;IACxC,OAAgB8C,OAAO;QACrB9B,QAAQnB,KAAKkD,MAAM,CAAC;YAClBC,aAAa;YACbC,UAAU;QACZ;QACAC,eAAerD,KAAKkD,MAAM,CAAC;YACzBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,uCAAsC;IAEpE,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SACE;YACFJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtB,qCAAqCvD,MAAMwD,OAAO,CAAC;YACjDC,SAAS;YACTP,aAAa;QACf;QACA,wBAAwBlD,MAAMwD,OAAO,CAAC;YACpCC,SAAS;YACTP,aAAa;QACf;QACA,gCAAgClD,MAAMwD,OAAO,CAAC;YAC5CC,SAAS;YACTP,aAAa;QACf;QACA,0BAA0BlD,MAAMwD,OAAO,CAAC;YACtCC,SAAS;YACTP,aAAa;QACf;QACA,qBAAqBlD,MAAM0D,OAAO,CAAC;YACjCR,aAAa;QACf;QACA,GAAGpC,eAAe;YAChBoC,aAAa;YACbS,WAAW;QACb,EAAE;QACFC,SAAS5D,MAAMwD,OAAO,CAAC;YACrBC,SAAS;YACTP,aAAa;YACbW,WAAW;gBAAC;aAAU;QACxB;QACA,GAAG9C,iBAAiB;YAClBmC,aAAa;YACbS,WAAW;QACb,EAAE;QACFG,SAAS9D,MAAMiD,MAAM,CAAC;YACpBc,YAAY;gBAACC,IAAI;YAAY;YAC7Bd,aAAa;YACbe,QAAQ;QACV;QACAC,SAASlE,MAAMwD,OAAO,CAAC;YACrBC,SAAS;YACTP,aAAa;YACbW,WAAW;gBAAC;aAAU;QACxB;QACA,kBAAkB7D,MAAMwD,OAAO,CAAC;YAC9BC,SAAS;YACTP,aAAa;QACf;QACA,iCAAiClD,MAAMwD,OAAO,CAAC;YAC7CC,SAAS;YACTP,aAAa;QACf;QACAiB,OAAOnE,MAAMiD,MAAM,CAAC;YAClBmB,MAAM;YACNlB,aAAa;YACbmB,KAAK;YACLlB,UAAU;QACZ;IACF,EAAC;IAED,OAAgBmB,gBAA0B;QAAC;KAAiB,CAAA;IAEpDC,gBAA4C;IAC5CC,YAAoB;IACpBC,aAAoC;IACpCC,UAAkB;IAE1B,aAAqBC,UAAUzD,MAAc,EAAkC;QAC7E,IAAI,gBAAgBC,IAAI,CAACD,SAAS;YAChC,OAAOQ,aAAaR;QACtB;QAEA,OAAOA,WAAW,MAAM0D,QAAQC,KAAK,GAAGhF,GAAGiF,gBAAgB,CAAC5D;IAC9D;IAEA,MAAa6D,MAAqB;QAChC,MAAM,EAAC/B,IAAI,EAAEO,KAAK,EAAC,GAAG,MAAM,IAAI,CAACyB,KAAK,CAACjC;QAEvC,MAAM,EACJ,qCAAqCkC,6BAA6B,EAClE,wBAAwBC,kBAAkB,EAC1C,gCAAgCC,0BAA0B,EAC1D,0BAA0BC,oBAAoB,EAC9C,qBAAqBC,gBAAgB,EACrCC,SAASC,WAAW,EACpB3B,OAAO,EACPM,OAAO,EACP,kBAAkBsB,aAAa,EAC/B,iCAAiCC,0BAA0B,EAC3DtB,KAAK,EACN,GAAGZ;QAEJ,MAAMmC,YAAY,MAAM,IAAI,CAACC,YAAY,CAAC;YACxCC,oBAAoB;YACpBC,UAAU,IAAMlF,iBAAiB,CAAC;QACpC;QAEA,MAAM,EAACO,MAAM,EAAEkC,eAAe0C,gBAAgB,EAAC,GAAG9C;QAElD,IAAI8C,oBAAoB,CAACP,aAAa;YACpC,IAAI,CAACQ,IAAI,CACP;QAEJ;QAEA,IAAIT,UAAUC,eAAeO;QAC7B,IAAI,CAACR,SAAS;YACZ,IAAI,IAAI,CAACU,YAAY,IAAI;gBACvB,IAAI,CAACC,KAAK,CACR,kFACA;oBAACC,MAAM;gBAAC;YAEZ;YAEA,MAAMC,WAAW,MAAMtF,aAAa6E;YACpCJ,UAAU,MAAM7E,iBAAiB;gBAAC2F,eAAe;gBAAMD;YAAQ;YAE/D,IAAIb,YAAY9E,mBAAmB;gBACjC,MAAM6F,iBAAiB,MAAM3F;gBAE7B,IAAI;oBACF,MAAME,cAAc;wBAAC0F,aAAaD;wBAAgBX;oBAAS;oBAC3DJ,UAAUe;gBACZ,EAAE,OAAOJ,OAAO;oBACd,MAAM3D,UAAU2D,iBAAiB5D,QAAQ4D,MAAM3D,OAAO,GAAGiE,OAAON;oBAChEjF,YAAY,CAAC,yBAAyB,EAAEqF,eAAe,EAAE,EAAE/D,SAAS,EAAE2D;oBACtE,IAAI,CAACA,KAAK,CAAC,CAAC,yBAAyB,EAAEI,eAAe,EAAE,EAAE/D,SAAS,EAAE;wBAAC4D,MAAM;oBAAC;gBAC/E;YACF;QACF;QAEA,IAAIM,YAAgE;QACpE,IAAIC,oBAAmD;QAEvD,IAAIvC,WAAWN,SAAS;YACtB4C,YAAYtC,UAAU,oBAAoB;YAC1CuC,oBAAoBvC,UAAU,YAAY;QAC5C;QAEA,MAAMwC,SAAS,MAAMzG,oBAAoB;YACvC0G,YAAY;YACZrB;YACAI;YACAkB,aAAa;YACb,GAAIzC,QAAQ;gBAACA;YAAK,IAAI,CAAC,CAAC;QAC1B;QAEA,IAAI;YACF,MAAMlC,SAAS,MAAMc,qBAAqB4B,SAAS,CAACzD;YACpD,MAAM2F,aAAa5F,cAAcC;YAEjC,MAAM4F,gBAAgB;gBACpB7B;gBACAC;gBACAC;gBACAC;gBACAsB;gBACAK,YAAY,IAAI,CAACA,UAAU,CAACC,IAAI,CAAC,IAAI;gBACrCR;gBACAC;gBACAjB;gBACAC;gBACAwB,KAAK;gBACL7D,eAAekC;gBACf4B,iBAAiBxB;gBACjB,GAAImB,aAAa;oBAACA;gBAAU,IAAI,CAAC,CAAC;gBAClC,GAAIxB,qBAAqBjE,YAAY,CAAC,IAAI;oBAACiE;gBAAgB,CAAC;YAC9D;YAEA,MAAM,EAAC8B,OAAO,EAAEC,QAAQ,EAAC,GAAG,MAAM9G,aAAa2B,QAAiC6E;YAEhF,IAAI,IAAI,CAACpC,SAAS,EAAE;gBAClB,MAAM2C,YAAY9G,SAAS+G,KAAKC,GAAG,KAAK,IAAI,CAAC7C,SAAS,EAAE;oBAAC8C,sBAAsB;gBAAC;gBAChF,IAAI,IAAI,CAACjD,eAAe,EAAE;oBACxB,IAAI,IAAI,CAACE,YAAY,EAAE;wBACrBgD,cAAc,IAAI,CAAChD,YAAY;wBAC/B,IAAI,CAACA,YAAY,GAAG;oBACtB;oBACA,IAAI,CAACF,eAAe,CAACmD,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,CAAClD,WAAW,CAAC,EAAE,EAAE6C,UAAU,CAAC,CAAC;oBACvE,IAAI,CAAC9C,eAAe,CAACoD,OAAO;gBAC9B;YACF;YAEA,IAAI,CAACC,GAAG,CAAC,iDAAiDT,SAAS7B;YACnE,IAAI,CAACuC,aAAa,CAACT;QACrB,EAAE,OAAOhF,KAAK;YACZ,IAAI,IAAI,CAACqC,YAAY,EAAE;gBACrBgD,cAAc,IAAI,CAAChD,YAAY;gBAC/B,IAAI,CAACA,YAAY,GAAG;YACtB;YAEA,IAAI,IAAI,CAACF,eAAe,EAAE;gBACxB,IAAI,CAACA,eAAe,CAACuD,IAAI;YAC3B;YAEA,IAAI,AAAC1F,IAAc2F,IAAI,KAAK,wBAAwB;gBAClD,IAAI,CAAC9B,KAAK,CACR,CAAC,kEAAkE,EAAE,AAAC7D,IAAcE,OAAO,CAAC,oKAAoK,CAAC,EACjQ;oBAAC4D,MAAM;gBAAC;YAEZ,OAAO;gBACL,IAAI,CAACD,KAAK,CAAC,AAAC7D,IAAc4F,KAAK,IAAI,AAAC5F,IAAcE,OAAO,EAAE;oBAAC4D,MAAM;gBAAC;YACrE;QACF;IACF;IAEQa,WAAWtE,IAAmB,EAAQ;QAC5C,MAAMwF,mBAAmBxF,KAAKC,KAAK;QACnC,MAAMwF,WAAWzF,KAAK0F,IAAI,KAAK,IAAI,CAAC3D,WAAW;QAC/C,MAAM7B,UAAUH,cAAcC;QAE9B,IAAIwF,oBAAoBxF,KAAKC,KAAK,KAAKD,KAAKK,OAAO,IAAI,IAAI,CAAC2B,YAAY,EAAE;YACxEgD,cAAc,IAAI,CAAChD,YAAY;YAC/B,IAAI,CAACA,YAAY,GAAG;QACtB;QAEA,IAAIyD,YAAY,CAACD,kBAAkB;YACjC;QACF;QAEA,IAAIC,UAAU;YACZ,IAAI,IAAI,CAACxD,SAAS,EAAE;gBAClB,MAAM2C,YAAY9G,SAAS+G,KAAKC,GAAG,KAAK,IAAI,CAAC7C,SAAS,EAAE;oBAAC8C,sBAAsB;gBAAC;gBAChF,IAAI,IAAI,CAACjD,eAAe,EAAE;oBACxB,IAAI,CAACA,eAAe,CAACmD,IAAI,GAAG,GAAG/E,UAAUF,KAAK0F,IAAI,CAAC,EAAE,EAAEd,UAAU,CAAC,CAAC;oBACnE,IAAI,CAAC9C,eAAe,CAAC6D,MAAM;gBAC7B;YACF;YACA;QACF;QAEA,sBAAsB;QACtB,MAAMC,WAAW,IAAI,CAAC7D,WAAW;QACjC,MAAM8D,gBAAgB,IAAI,CAAC5D,SAAS;QACpC,IAAI,CAACA,SAAS,GAAG4C,KAAKC,GAAG;QACzB,IAAI,CAAC/C,WAAW,GAAG/B,KAAK0F,IAAI;QAE5B,IAAI,IAAI,CAAC1D,YAAY,EAAE;YACrBgD,cAAc,IAAI,CAAChD,YAAY;YAC/B,IAAI,CAACA,YAAY,GAAG;QACtB;QAEA,IAAI,IAAI,CAACF,eAAe,IAAI,IAAI,CAACA,eAAe,CAACoD,OAAO,IAAIW,eAAe;YACzE,MAAMjB,YAAY9G,SAAS+G,KAAKC,GAAG,KAAKe,eAAe;gBACrDd,sBAAsB;YACxB;YACA,IAAI,CAACjD,eAAe,CAACmD,IAAI,GAAG,CAAC,OAAO,EAAEW,SAAS,EAAE,EAAEhB,UAAU,CAAC,CAAC;YAC/D,IAAI,CAAC9C,eAAe,CAACoD,OAAO;QAC9B;QAEA,IAAI,CAACpD,eAAe,GAAGlE,QAAQ,CAAC,KAAK,EAAEoC,KAAK0F,IAAI,CAAC,QAAQ,CAAC,EAAEI,KAAK;QAEjE,IAAI,CAACN,kBAAkB;YACrB,IAAI,CAACxD,YAAY,GAAG+D,YAAY;gBAC9B,IAAI,IAAI,CAAC9D,SAAS,IAAI,IAAI,CAACH,eAAe,EAAE;oBAC1C,MAAM8C,YAAY9G,SAAS+G,KAAKC,GAAG,KAAK,IAAI,CAAC7C,SAAS,EAAE;wBACtD8C,sBAAsB;oBACxB;oBACA,IAAI,CAACjD,eAAe,CAACmD,IAAI,GAAG,GAAG/E,UAAUF,KAAK0F,IAAI,CAAC,EAAE,EAAEd,UAAU,CAAC,CAAC;oBACnE,IAAI,CAAC9C,eAAe,CAAC6D,MAAM;gBAC7B;YACF,GAAG;QACL;IACF;IAEQP,cAAcT,QAA+D,EAAQ;QAC3F,MAAMqB,aAAarB,SAASsB,MAAM,CAAC,CAAC3C,OAASA,KAAK4C,IAAI,KAAK;QAE3D,IAAIF,WAAWG,MAAM,KAAK,GAAG;YAC3B;QACF;QAEA,IAAI,CAAC7C,IAAI,CAAC,CAAC,+BAA+B,EAAE0C,WAAWG,MAAM,GAAG,IAAI,WAAW,QAAQ,CAAC,CAAC;QAEzF,KAAK,MAAMC,WAAWJ,WAAY;YAChC,IAAII,QAAQ3G,GAAG,EAAE;gBACf,IAAI,CAAC6D,IAAI,CAAC,CAAC,EAAE,EAAE8C,QAAQ3G,GAAG,EAAE;YAC9B;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/datasets/import.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {sanityImport} from '@sanity/import'\nimport prettyMs from 'pretty-ms'\n\nimport {NEW_DATASET_VALUE, promptForDataset} from '../../prompts/promptForDataset.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {createDataset, listDatasets} from '../../services/datasets.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst importDebug = subdebug('dataset:import')\n\ninterface ProgressEvent {\n step: string\n\n current?: number\n total?: number\n update?: string\n}\n\nfunction getAssetsBase(source: string): string | undefined {\n if (/^https?:\\/\\//i.test(source) || source === '-') {\n return undefined\n }\n\n try {\n const fileStats = fs.statSync(source)\n const sourceIsFolder = fileStats.isDirectory()\n return sourceIsFolder ? source : path.dirname(source)\n } catch {\n return undefined\n }\n}\n\nasync function getUriStream(uri: string): Promise<NodeJS.ReadableStream> {\n const request = createRequester({\n middleware: {promise: {onlyBody: false}},\n })\n\n try {\n const response = (await request({stream: true, url: uri})) as {body: NodeJS.ReadableStream}\n return response.body\n } catch (err) {\n throw new Error(`Error fetching source:\\n${(err as Error).message}`, {cause: err})\n }\n}\n\nfunction getPercentage(opts: ProgressEvent): string {\n if (!opts.total) {\n return ''\n }\n\n const percent = Math.floor(((opts.current || 0) / opts.total) * 100)\n return `[${percent}%] `\n}\n\nexport class ImportDatasetCommand extends SanityCommand<typeof ImportDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Source file (use \"-\" for stdin)',\n required: true,\n }),\n targetDataset: Args.string({\n description: 'Target dataset (prefer --dataset flag instead)',\n required: false,\n }),\n }\n\n static override description = 'Import documents to a Sanity dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> -d staging my-dataset.ndjson',\n description: 'Import \"./my-dataset.ndjson\" into dataset \"staging\"',\n },\n {\n command: 'cat my-dataset.ndjson | <%= config.bin %> <%= command.id %> -d test -',\n description: 'Import into dataset \"test\" from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> -p projectId -d staging my-dataset.ndjson',\n description: 'Import with explicit project ID (overrides CLI configuration)',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -d staging -t someSecretToken my-dataset.ndjson',\n description: 'Import with an explicit token (e.g. for CI/CD)',\n },\n ]\n\n static override flags = {\n 'allow-assets-in-different-dataset': Flags.boolean({\n default: false,\n description: 'Allow asset documents to reference different project/dataset',\n }),\n 'allow-failing-assets': Flags.boolean({\n default: false,\n description: 'Skip assets that cannot be fetched/uploaded',\n }),\n 'allow-replacement-characters': Flags.boolean({\n default: false,\n description: 'Allow unicode replacement characters in imported documents',\n }),\n 'allow-system-documents': Flags.boolean({\n default: false,\n description: 'Imports system documents',\n }),\n 'asset-concurrency': Flags.integer({\n description: 'Number of parallel asset imports',\n }),\n ...getDatasetFlag({\n description: 'Dataset to import to',\n semantics: 'specify',\n }),\n missing: Flags.boolean({\n default: false,\n description: 'Skip documents that already exist',\n exclusive: ['replace'],\n }),\n ...getProjectIdFlag({\n description: 'Project ID to import to',\n semantics: 'override',\n }),\n project: Flags.string({\n deprecated: {to: 'project-id'},\n description: 'Project ID to import to',\n hidden: true,\n }),\n replace: Flags.boolean({\n default: false,\n description: 'Replace documents with the same IDs',\n exclusive: ['missing'],\n }),\n 'replace-assets': Flags.boolean({\n default: false,\n description: 'Skip reuse of existing assets',\n }),\n 'skip-cross-dataset-references': Flags.boolean({\n default: false,\n description: 'Skips references to other datasets',\n }),\n token: Flags.string({\n char: 't',\n description: 'Token to authenticate with',\n env: 'SANITY_IMPORT_TOKEN',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:import']\n\n private currentProgress?: ReturnType<typeof spinner>\n private currentStep?: string\n private spinInterval?: NodeJS.Timeout | null\n private stepStart?: number\n\n private static async getStream(source: string): Promise<NodeJS.ReadableStream> {\n if (/^https?:\\/\\//i.test(source)) {\n return getUriStream(source)\n }\n\n return source === '-' ? process.stdin : fs.createReadStream(source)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ImportDatasetCommand)\n\n const {\n 'allow-assets-in-different-dataset': allowAssetsInDifferentDataset,\n 'allow-failing-assets': allowFailingAssets,\n 'allow-replacement-characters': allowReplacementCharacters,\n 'allow-system-documents': allowSystemDocuments,\n 'asset-concurrency': assetConcurrency,\n dataset: datasetFlag,\n missing,\n replace,\n 'replace-assets': replaceAssets,\n 'skip-cross-dataset-references': skipCrossDatasetReferences,\n token,\n } = flags\n\n const projectId = await this.getProjectId({\n deprecatedFlagName: 'project',\n fallback: () => promptForProject({}),\n })\n\n const {source, targetDataset: targetDatasetArg} = args\n\n if (targetDatasetArg && !datasetFlag) {\n this.output.warn(\n 'Positional dataset argument is deprecated. Use the --dataset flag instead: --dataset <name>',\n )\n }\n\n let dataset = datasetFlag ?? targetDatasetArg\n if (!dataset) {\n if (this.isUnattended()) {\n return this.output.error(\n 'Missing dataset. Use the --dataset flag to specify a dataset: --dataset <name>',\n {exit: 1},\n )\n }\n\n const datasets = await listDatasets(projectId)\n dataset = await promptForDataset({allowCreation: true, datasets})\n\n if (dataset === NEW_DATASET_VALUE) {\n const newDatasetName = await promptForDatasetName()\n\n try {\n await createDataset({datasetName: newDatasetName, projectId})\n dataset = newDatasetName\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n importDebug(`Failed to create dataset ${newDatasetName}: ${message}`, error)\n return this.output.error(`Failed to create dataset ${newDatasetName}: ${message}`, {\n exit: 1,\n })\n }\n }\n }\n\n let operation: 'create' | 'createIfNotExists' | 'createOrReplace' = 'create'\n let releasesOperation: 'fail' | 'ignore' | 'replace' = 'fail'\n\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n releasesOperation = replace ? 'replace' : 'ignore'\n }\n\n const client = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n projectId,\n requireUser: true,\n ...(token ? {token} : {}),\n })\n\n try {\n const stream = await ImportDatasetCommand.getStream(source)\n const assetsBase = getAssetsBase(source)\n\n const importOptions = {\n allowAssetsInDifferentDataset,\n allowFailingAssets,\n allowReplacementCharacters,\n allowSystemDocuments,\n client,\n onProgress: this.onProgress.bind(this),\n operation,\n releasesOperation,\n replaceAssets,\n skipCrossDatasetReferences,\n tag: 'sanity.import',\n targetDataset: dataset,\n targetProjectId: projectId,\n ...(assetsBase ? {assetsBase} : {}),\n ...(assetConcurrency === undefined ? {} : {assetConcurrency}),\n }\n\n const {numDocs, warnings} = await sanityImport(stream, importOptions)\n\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n this.currentProgress.text = `[100%] ${this.currentStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n }\n\n this.output.log('Done! Imported %d documents to dataset \"%s\"\\n', numDocs, dataset)\n this.printWarnings(warnings)\n } catch (err) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress) {\n this.currentProgress.fail()\n }\n\n return (err as Error).name === 'ReplacementCharError'\n ? this.output.error(\n `Import failed due to unicode replacement characters in the data.\\n${(err as Error).message}\\n\\nIf you are certain you want to proceed with the import despite potentially corrupt data, re-run the import with the \\`--allow-replacement-characters\\` flag set.`,\n {exit: 1},\n )\n : this.output.error((err as Error).stack || (err as Error).message, {exit: 1})\n }\n }\n\n private onProgress(opts: ProgressEvent): void {\n const lengthComputable = opts.total\n const sameStep = opts.step === this.currentStep\n const percent = getPercentage(opts)\n\n if (lengthComputable && opts.total === opts.current && this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (sameStep && !lengthComputable) {\n return\n }\n\n if (sameStep) {\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }\n return\n }\n\n // Moved to a new step\n const prevStep = this.currentStep\n const prevStepStart = this.stepStart\n this.stepStart = Date.now()\n this.currentStep = opts.step\n\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress && this.currentProgress.succeed && prevStepStart) {\n const timeSpent = prettyMs(Date.now() - prevStepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `[100%] ${prevStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n\n this.currentProgress = spinner(`[0%] ${opts.step} (0.00s)`).start()\n\n if (!lengthComputable) {\n this.spinInterval = setInterval(() => {\n if (this.stepStart && this.currentProgress) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }, 60)\n }\n }\n\n private printWarnings(warnings: Array<{message: string; type?: string; url?: string}>): void {\n const assetFails = warnings.filter((warn) => warn.type === 'asset')\n\n if (assetFails.length === 0) {\n return\n }\n\n this.output.warn(\n `Failed to import the following ${assetFails.length > 1 ? 'assets' : 'asset'}:`,\n )\n\n for (const warning of assetFails) {\n if (warning.url) {\n this.output.warn(` ${warning.url}`)\n }\n }\n }\n}\n"],"names":["fs","path","Args","Flags","getProjectCliClient","SanityCommand","subdebug","createRequester","spinner","sanityImport","prettyMs","NEW_DATASET_VALUE","promptForDataset","promptForDatasetName","promptForProject","createDataset","listDatasets","getDatasetFlag","getProjectIdFlag","importDebug","getAssetsBase","source","test","undefined","fileStats","statSync","sourceIsFolder","isDirectory","dirname","getUriStream","uri","request","middleware","promise","onlyBody","response","stream","url","body","err","Error","message","cause","getPercentage","opts","total","percent","Math","floor","current","ImportDatasetCommand","args","string","description","required","targetDataset","examples","command","flags","boolean","default","integer","semantics","missing","exclusive","project","deprecated","to","hidden","replace","token","char","env","hiddenAliases","currentProgress","currentStep","spinInterval","stepStart","getStream","process","stdin","createReadStream","run","parse","allowAssetsInDifferentDataset","allowFailingAssets","allowReplacementCharacters","allowSystemDocuments","assetConcurrency","dataset","datasetFlag","replaceAssets","skipCrossDatasetReferences","projectId","getProjectId","deprecatedFlagName","fallback","targetDatasetArg","output","warn","isUnattended","error","exit","datasets","allowCreation","newDatasetName","datasetName","String","operation","releasesOperation","client","apiVersion","requireUser","assetsBase","importOptions","onProgress","bind","tag","targetProjectId","numDocs","warnings","timeSpent","Date","now","secondsDecimalDigits","clearInterval","text","succeed","log","printWarnings","fail","name","stack","lengthComputable","sameStep","step","render","prevStep","prevStepStart","start","setInterval","assetFails","filter","type","length","warning"],"mappings":"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"}
@@ -53,19 +53,19 @@ export class DoctorCommand extends SanityCommand {
53
53
  try {
54
54
  checks = getChecks(argv);
55
55
  } catch (err) {
56
- this.error(err instanceof Error ? err.message : String(err), {
56
+ return this.output.error(err instanceof Error ? err.message : String(err), {
57
57
  exit: 2
58
58
  });
59
59
  }
60
60
  const cwd = process.cwd();
61
61
  if (!flags.json) {
62
- this.log('Running diagnostics...\n');
62
+ this.output.log('Running diagnostics...\n');
63
63
  }
64
64
  const results = await runDoctorChecks({
65
65
  cwd
66
66
  }, checks);
67
67
  if (flags.json) {
68
- this.log(JSON.stringify(results, null, 2));
68
+ this.output.log(JSON.stringify(results, null, 2));
69
69
  } else {
70
70
  for (const check of results.checks){
71
71
  this.printCheck(check);
@@ -74,25 +74,25 @@ export class DoctorCommand extends SanityCommand {
74
74
  }
75
75
  // Exit with error code if any checks failed
76
76
  if (results.summary.errors > 0) {
77
- this.exit(1);
77
+ return this.exit(1);
78
78
  }
79
79
  }
80
80
  printCheck(check) {
81
81
  const symbol = STATUS_SYMBOLS[check.status];
82
82
  const title = check.status === 'passed' ? check.title : styleText(check.status === 'error' ? 'red' : 'yellow', check.title);
83
- this.log(`${symbol} ${title}`);
83
+ this.output.log(`${symbol} ${title}`);
84
84
  for (const message of check.messages){
85
85
  this.printMessage(message);
86
86
  }
87
- this.log(''); // Empty line between checks
87
+ this.output.log(''); // Empty line between checks
88
88
  }
89
89
  printMessage(message) {
90
90
  const symbol = MESSAGE_SYMBOLS[message.type];
91
91
  const text = message.type === 'error' ? styleText('red', message.text) : message.type === 'warning' ? styleText('yellow', message.text) : message.text;
92
- this.log(` ${symbol} ${text}`);
92
+ this.output.log(` ${symbol} ${text}`);
93
93
  if (message.suggestions?.length) {
94
94
  for (const suggestion of message.suggestions){
95
- this.log(` ${styleText('dim', '→')} ${suggestion}`);
95
+ this.output.log(` ${styleText('dim', '→')} ${suggestion}`);
96
96
  }
97
97
  }
98
98
  }
@@ -107,7 +107,7 @@ export class DoctorCommand extends SanityCommand {
107
107
  if (summary.errors > 0) {
108
108
  parts.push(styleText('red', `${summary.errors} error${summary.errors === 1 ? '' : 's'}`));
109
109
  }
110
- this.log(`Summary: ${parts.join(', ')}`);
110
+ this.output.log(`Summary: ${parts.join(', ')}`);
111
111
  }
112
112
  }
113
113
  function getChecks(argv) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/doctor.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\n\nimport {type DoctorCheckName, doctorChecks, KNOWN_CHECKS} from '../actions/doctor/checks/index.js'\nimport {runDoctorChecks} from '../actions/doctor/runDoctorChecks.js'\nimport {\n type CheckMessage,\n type CheckResultStatus,\n type CheckResultWithMeta,\n type DoctorCheck,\n type DoctorResults,\n type MessageType,\n} from '../actions/doctor/types.js'\n\nconst STATUS_SYMBOLS: Record<CheckResultStatus, string> = {\n error: logSymbols.error,\n passed: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nconst MESSAGE_SYMBOLS: Record<MessageType, string> = {\n error: logSymbols.error,\n info: logSymbols.info,\n success: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nexport class DoctorCommand extends SanityCommand<typeof DoctorCommand> {\n // strict=false allows variadic args — validation is handled by getChecks().\n // options is omitted here because oclif's help formatter uses it for display,\n // but actual validation is done explicitly in getChecks() for clear error messages.\n static override args = {\n checks: Args.string({\n description: `Checks to enable (defaults to all). Valid: ${KNOWN_CHECKS.join(', ')}`,\n multiple: true,\n required: false,\n }),\n }\n\n static override description = 'Run diagnostics on your Sanity project'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {command: '<%= config.bin %> <%= command.id %> --json', description: 'Output results as JSON'},\n {\n command: '<%= config.bin %> <%= command.id %> cli',\n description: 'Only run CLI-related diagnostics',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output results as JSON',\n }),\n }\n\n // Needed for variable argument count\n static override strict = false\n\n public async run(): Promise<void> {\n const {argv, flags} = await this.parse(DoctorCommand)\n\n let checks: Array<DoctorCheck>\n try {\n checks = getChecks(argv)\n } catch (err) {\n this.error(err instanceof Error ? err.message : String(err), {exit: 2})\n }\n const cwd = process.cwd()\n\n if (!flags.json) {\n this.log('Running diagnostics...\\n')\n }\n\n const results = await runDoctorChecks({cwd}, checks)\n\n if (flags.json) {\n this.log(JSON.stringify(results, null, 2))\n } else {\n for (const check of results.checks) {\n this.printCheck(check)\n }\n\n this.printSummary(results.summary)\n }\n\n // Exit with error code if any checks failed\n if (results.summary.errors > 0) {\n this.exit(1)\n }\n }\n\n private printCheck(check: CheckResultWithMeta): void {\n const symbol = STATUS_SYMBOLS[check.status]\n const title =\n check.status === 'passed'\n ? check.title\n : styleText(check.status === 'error' ? 'red' : 'yellow', check.title)\n\n this.log(`${symbol} ${title}`)\n\n for (const message of check.messages) {\n this.printMessage(message)\n }\n\n this.log('') // Empty line between checks\n }\n\n private printMessage(message: CheckMessage): void {\n const symbol = MESSAGE_SYMBOLS[message.type]\n const text =\n message.type === 'error'\n ? styleText('red', message.text)\n : message.type === 'warning'\n ? styleText('yellow', message.text)\n : message.text\n\n this.log(` ${symbol} ${text}`)\n\n if (message.suggestions?.length) {\n for (const suggestion of message.suggestions) {\n this.log(` ${styleText('dim', '→')} ${suggestion}`)\n }\n }\n }\n\n private printSummary(summary: DoctorResults['summary']): void {\n const parts: string[] = []\n\n if (summary.passed > 0) {\n parts.push(styleText('green', `${summary.passed} passed`))\n }\n if (summary.warnings > 0) {\n parts.push(\n styleText('yellow', `${summary.warnings} warning${summary.warnings === 1 ? '' : 's'}`),\n )\n }\n if (summary.errors > 0) {\n parts.push(styleText('red', `${summary.errors} error${summary.errors === 1 ? '' : 's'}`))\n }\n\n this.log(`Summary: ${parts.join(', ')}`)\n }\n}\n\nfunction getChecks(argv: unknown[]): Array<DoctorCheck> {\n // strict=false means oclif does NOT validate Args.string({ options }) — we must\n // validate explicitly. Filter to string args that aren't flags.\n const stringArgs = argv.filter(\n (item): item is string => typeof item === 'string' && !item.startsWith('-'),\n )\n\n const unknownChecks = stringArgs.filter(\n (item) => !(KNOWN_CHECKS as readonly string[]).includes(item),\n )\n if (unknownChecks.length > 0) {\n throw new Error(\n `Unknown check${unknownChecks.length === 1 ? '' : 's'}: ${unknownChecks.join(', ')}. Valid checks: ${KNOWN_CHECKS.join(', ')}`,\n )\n }\n\n const checkNames = stringArgs as DoctorCheckName[]\n return checkNames.length > 0\n ? checkNames.map((check) => doctorChecks[check])\n : Object.values(doctorChecks)\n}\n"],"names":["styleText","Args","Flags","SanityCommand","logSymbols","doctorChecks","KNOWN_CHECKS","runDoctorChecks","STATUS_SYMBOLS","error","passed","success","warning","MESSAGE_SYMBOLS","info","DoctorCommand","args","checks","string","description","join","multiple","required","examples","command","flags","json","boolean","char","default","strict","run","argv","parse","getChecks","err","Error","message","String","exit","cwd","process","log","results","JSON","stringify","check","printCheck","printSummary","summary","errors","symbol","status","title","messages","printMessage","type","text","suggestions","length","suggestion","parts","push","warnings","stringArgs","filter","item","startsWith","unknownChecks","includes","checkNames","map","Object","values"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/doctor.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\n\nimport {type DoctorCheckName, doctorChecks, KNOWN_CHECKS} from '../actions/doctor/checks/index.js'\nimport {runDoctorChecks} from '../actions/doctor/runDoctorChecks.js'\nimport {\n type CheckMessage,\n type CheckResultStatus,\n type CheckResultWithMeta,\n type DoctorCheck,\n type DoctorResults,\n type MessageType,\n} from '../actions/doctor/types.js'\n\nconst STATUS_SYMBOLS: Record<CheckResultStatus, string> = {\n error: logSymbols.error,\n passed: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nconst MESSAGE_SYMBOLS: Record<MessageType, string> = {\n error: logSymbols.error,\n info: logSymbols.info,\n success: logSymbols.success,\n warning: logSymbols.warning,\n}\n\nexport class DoctorCommand extends SanityCommand<typeof DoctorCommand> {\n // strict=false allows variadic args — validation is handled by getChecks().\n // options is omitted here because oclif's help formatter uses it for display,\n // but actual validation is done explicitly in getChecks() for clear error messages.\n static override args = {\n checks: Args.string({\n description: `Checks to enable (defaults to all). Valid: ${KNOWN_CHECKS.join(', ')}`,\n multiple: true,\n required: false,\n }),\n }\n\n static override description = 'Run diagnostics on your Sanity project'\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {command: '<%= config.bin %> <%= command.id %> --json', description: 'Output results as JSON'},\n {\n command: '<%= config.bin %> <%= command.id %> cli',\n description: 'Only run CLI-related diagnostics',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output results as JSON',\n }),\n }\n\n // Needed for variable argument count\n static override strict = false\n\n public async run(): Promise<void> {\n const {argv, flags} = await this.parse(DoctorCommand)\n\n let checks: Array<DoctorCheck>\n try {\n checks = getChecks(argv)\n } catch (err) {\n return this.output.error(err instanceof Error ? err.message : String(err), {exit: 2})\n }\n const cwd = process.cwd()\n\n if (!flags.json) {\n this.output.log('Running diagnostics...\\n')\n }\n\n const results = await runDoctorChecks({cwd}, checks)\n\n if (flags.json) {\n this.output.log(JSON.stringify(results, null, 2))\n } else {\n for (const check of results.checks) {\n this.printCheck(check)\n }\n\n this.printSummary(results.summary)\n }\n\n // Exit with error code if any checks failed\n if (results.summary.errors > 0) {\n return this.exit(1)\n }\n }\n\n private printCheck(check: CheckResultWithMeta): void {\n const symbol = STATUS_SYMBOLS[check.status]\n const title =\n check.status === 'passed'\n ? check.title\n : styleText(check.status === 'error' ? 'red' : 'yellow', check.title)\n\n this.output.log(`${symbol} ${title}`)\n\n for (const message of check.messages) {\n this.printMessage(message)\n }\n\n this.output.log('') // Empty line between checks\n }\n\n private printMessage(message: CheckMessage): void {\n const symbol = MESSAGE_SYMBOLS[message.type]\n const text =\n message.type === 'error'\n ? styleText('red', message.text)\n : message.type === 'warning'\n ? styleText('yellow', message.text)\n : message.text\n\n this.output.log(` ${symbol} ${text}`)\n\n if (message.suggestions?.length) {\n for (const suggestion of message.suggestions) {\n this.output.log(` ${styleText('dim', '→')} ${suggestion}`)\n }\n }\n }\n\n private printSummary(summary: DoctorResults['summary']): void {\n const parts: string[] = []\n\n if (summary.passed > 0) {\n parts.push(styleText('green', `${summary.passed} passed`))\n }\n if (summary.warnings > 0) {\n parts.push(\n styleText('yellow', `${summary.warnings} warning${summary.warnings === 1 ? '' : 's'}`),\n )\n }\n if (summary.errors > 0) {\n parts.push(styleText('red', `${summary.errors} error${summary.errors === 1 ? '' : 's'}`))\n }\n\n this.output.log(`Summary: ${parts.join(', ')}`)\n }\n}\n\nfunction getChecks(argv: unknown[]): Array<DoctorCheck> {\n // strict=false means oclif does NOT validate Args.string({ options }) — we must\n // validate explicitly. Filter to string args that aren't flags.\n const stringArgs = argv.filter(\n (item): item is string => typeof item === 'string' && !item.startsWith('-'),\n )\n\n const unknownChecks = stringArgs.filter(\n (item) => !(KNOWN_CHECKS as readonly string[]).includes(item),\n )\n if (unknownChecks.length > 0) {\n throw new Error(\n `Unknown check${unknownChecks.length === 1 ? '' : 's'}: ${unknownChecks.join(', ')}. Valid checks: ${KNOWN_CHECKS.join(', ')}`,\n )\n }\n\n const checkNames = stringArgs as DoctorCheckName[]\n return checkNames.length > 0\n ? checkNames.map((check) => doctorChecks[check])\n : Object.values(doctorChecks)\n}\n"],"names":["styleText","Args","Flags","SanityCommand","logSymbols","doctorChecks","KNOWN_CHECKS","runDoctorChecks","STATUS_SYMBOLS","error","passed","success","warning","MESSAGE_SYMBOLS","info","DoctorCommand","args","checks","string","description","join","multiple","required","examples","command","flags","json","boolean","char","default","strict","run","argv","parse","getChecks","err","output","Error","message","String","exit","cwd","process","log","results","JSON","stringify","check","printCheck","printSummary","summary","errors","symbol","status","title","messages","printMessage","type","text","suggestions","length","suggestion","parts","push","warnings","stringArgs","filter","item","startsWith","unknownChecks","includes","checkNames","map","Object","values"],"mappings":"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"}
@@ -17,13 +17,13 @@ export class Disable extends SanityCommand {
17
17
  const result = await setConsent({
18
18
  status: 'denied'
19
19
  });
20
- this.log(result.message);
20
+ this.output.log(result.message);
21
21
  if (result.changed) {
22
- this.log(`\n${telemetryLearnMoreMessage('denied')}`);
22
+ this.output.log(`\n${telemetryLearnMoreMessage('denied')}`);
23
23
  }
24
24
  } catch (err) {
25
25
  const message = err instanceof Error ? err.message : 'An unknown error occurred';
26
- this.error(message, {
26
+ this.output.error(message, {
27
27
  exit: 1
28
28
  });
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/telemetry/disable.ts"],"sourcesContent":["import {Command} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {setConsent} from '../../actions/telemetry/setConsent.js'\nimport {telemetryLearnMoreMessage} from '../../actions/telemetry/telemetryLearnMoreMessage.js'\n\nexport class Disable extends SanityCommand<typeof Disable> {\n static override description = 'Disable telemetry for your account'\n\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> telemetry <%= command.id %>',\n description: 'Disable telemetry for your account',\n },\n ]\n\n static override flags = {} satisfies FlagInput\n\n public async run(): Promise<void> {\n // Parse to ensure no invalid flags are passed\n await this.parse(Disable)\n\n try {\n const result = await setConsent({\n status: 'denied',\n })\n\n this.log(result.message)\n\n if (result.changed) {\n this.log(`\\n${telemetryLearnMoreMessage('denied')}`)\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'An unknown error occurred'\n this.error(message, {exit: 1})\n }\n }\n}\n"],"names":["SanityCommand","setConsent","telemetryLearnMoreMessage","Disable","description","examples","command","flags","run","parse","result","status","log","message","changed","err","Error","error","exit"],"mappings":"AAEA,SAAQA,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,UAAU,QAAO,wCAAuC;AAChE,SAAQC,yBAAyB,QAAO,uDAAsD;AAE9F,OAAO,MAAMC,gBAAgBH;IAC3B,OAAgBI,cAAc,qCAAoC;IAElE,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ,CAAC,EAAqB;IAE9C,MAAaC,MAAqB;QAChC,8CAA8C;QAC9C,MAAM,IAAI,CAACC,KAAK,CAACN;QAEjB,IAAI;YACF,MAAMO,SAAS,MAAMT,WAAW;gBAC9BU,QAAQ;YACV;YAEA,IAAI,CAACC,GAAG,CAACF,OAAOG,OAAO;YAEvB,IAAIH,OAAOI,OAAO,EAAE;gBAClB,IAAI,CAACF,GAAG,CAAC,CAAC,EAAE,EAAEV,0BAA0B,WAAW;YACrD;QACF,EAAE,OAAOa,KAAc;YACrB,MAAMF,UAAUE,eAAeC,QAAQD,IAAIF,OAAO,GAAG;YACrD,IAAI,CAACI,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAC9B;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/telemetry/disable.ts"],"sourcesContent":["import {Command} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {setConsent} from '../../actions/telemetry/setConsent.js'\nimport {telemetryLearnMoreMessage} from '../../actions/telemetry/telemetryLearnMoreMessage.js'\n\nexport class Disable extends SanityCommand<typeof Disable> {\n static override description = 'Disable telemetry for your account'\n\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> telemetry <%= command.id %>',\n description: 'Disable telemetry for your account',\n },\n ]\n\n static override flags = {} satisfies FlagInput\n\n public async run(): Promise<void> {\n // Parse to ensure no invalid flags are passed\n await this.parse(Disable)\n\n try {\n const result = await setConsent({\n status: 'denied',\n })\n\n this.output.log(result.message)\n\n if (result.changed) {\n this.output.log(`\\n${telemetryLearnMoreMessage('denied')}`)\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'An unknown error occurred'\n this.output.error(message, {exit: 1})\n }\n }\n}\n"],"names":["SanityCommand","setConsent","telemetryLearnMoreMessage","Disable","description","examples","command","flags","run","parse","result","status","output","log","message","changed","err","Error","error","exit"],"mappings":"AAEA,SAAQA,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,UAAU,QAAO,wCAAuC;AAChE,SAAQC,yBAAyB,QAAO,uDAAsD;AAE9F,OAAO,MAAMC,gBAAgBH;IAC3B,OAAgBI,cAAc,qCAAoC;IAElE,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ,CAAC,EAAqB;IAE9C,MAAaC,MAAqB;QAChC,8CAA8C;QAC9C,MAAM,IAAI,CAACC,KAAK,CAACN;QAEjB,IAAI;YACF,MAAMO,SAAS,MAAMT,WAAW;gBAC9BU,QAAQ;YACV;YAEA,IAAI,CAACC,MAAM,CAACC,GAAG,CAACH,OAAOI,OAAO;YAE9B,IAAIJ,OAAOK,OAAO,EAAE;gBAClB,IAAI,CAACH,MAAM,CAACC,GAAG,CAAC,CAAC,EAAE,EAAEX,0BAA0B,WAAW;YAC5D;QACF,EAAE,OAAOc,KAAc;YACrB,MAAMF,UAAUE,eAAeC,QAAQD,IAAIF,OAAO,GAAG;YACrD,IAAI,CAACF,MAAM,CAACM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QACrC;IACF;AACF"}
@@ -17,13 +17,13 @@ export class Enable extends SanityCommand {
17
17
  const result = await setConsent({
18
18
  status: 'granted'
19
19
  });
20
- this.log(result.message);
20
+ this.output.log(result.message);
21
21
  if (result.changed) {
22
- this.log(`\n${telemetryLearnMoreMessage('granted')}`);
22
+ this.output.log(`\n${telemetryLearnMoreMessage('granted')}`);
23
23
  }
24
24
  } catch (err) {
25
25
  const message = err instanceof Error ? err.message : 'An unknown error occurred';
26
- this.error(message, {
26
+ return this.output.error(message, {
27
27
  exit: 1
28
28
  });
29
29
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/telemetry/enable.ts"],"sourcesContent":["import {Command} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {setConsent} from '../../actions/telemetry/setConsent.js'\nimport {telemetryLearnMoreMessage} from '../../actions/telemetry/telemetryLearnMoreMessage.js'\n\nexport class Enable extends SanityCommand<typeof Enable> {\n static override description = 'Enable telemetry for your account'\n\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> telemetry <%= command.id %>',\n description: 'Enable telemetry for your account',\n },\n ]\n\n static override flags = {} satisfies FlagInput\n\n public async run(): Promise<void> {\n // Parse to ensure no invalid flags are passed\n await this.parse(Enable)\n\n try {\n const result = await setConsent({\n status: 'granted',\n })\n\n this.log(result.message)\n\n if (result.changed) {\n this.log(`\\n${telemetryLearnMoreMessage('granted')}`)\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'An unknown error occurred'\n this.error(message, {exit: 1})\n }\n }\n}\n"],"names":["SanityCommand","setConsent","telemetryLearnMoreMessage","Enable","description","examples","command","flags","run","parse","result","status","log","message","changed","err","Error","error","exit"],"mappings":"AAEA,SAAQA,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,UAAU,QAAO,wCAAuC;AAChE,SAAQC,yBAAyB,QAAO,uDAAsD;AAE9F,OAAO,MAAMC,eAAeH;IAC1B,OAAgBI,cAAc,oCAAmC;IAEjE,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ,CAAC,EAAqB;IAE9C,MAAaC,MAAqB;QAChC,8CAA8C;QAC9C,MAAM,IAAI,CAACC,KAAK,CAACN;QAEjB,IAAI;YACF,MAAMO,SAAS,MAAMT,WAAW;gBAC9BU,QAAQ;YACV;YAEA,IAAI,CAACC,GAAG,CAACF,OAAOG,OAAO;YAEvB,IAAIH,OAAOI,OAAO,EAAE;gBAClB,IAAI,CAACF,GAAG,CAAC,CAAC,EAAE,EAAEV,0BAA0B,YAAY;YACtD;QACF,EAAE,OAAOa,KAAc;YACrB,MAAMF,UAAUE,eAAeC,QAAQD,IAAIF,OAAO,GAAG;YACrD,IAAI,CAACI,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAC9B;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/telemetry/enable.ts"],"sourcesContent":["import {Command} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {setConsent} from '../../actions/telemetry/setConsent.js'\nimport {telemetryLearnMoreMessage} from '../../actions/telemetry/telemetryLearnMoreMessage.js'\n\nexport class Enable extends SanityCommand<typeof Enable> {\n static override description = 'Enable telemetry for your account'\n\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> telemetry <%= command.id %>',\n description: 'Enable telemetry for your account',\n },\n ]\n\n static override flags = {} satisfies FlagInput\n\n public async run(): Promise<void> {\n // Parse to ensure no invalid flags are passed\n await this.parse(Enable)\n\n try {\n const result = await setConsent({\n status: 'granted',\n })\n\n this.output.log(result.message)\n\n if (result.changed) {\n this.output.log(`\\n${telemetryLearnMoreMessage('granted')}`)\n }\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : 'An unknown error occurred'\n return this.output.error(message, {exit: 1})\n }\n }\n}\n"],"names":["SanityCommand","setConsent","telemetryLearnMoreMessage","Enable","description","examples","command","flags","run","parse","result","status","output","log","message","changed","err","Error","error","exit"],"mappings":"AAEA,SAAQA,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,UAAU,QAAO,wCAAuC;AAChE,SAAQC,yBAAyB,QAAO,uDAAsD;AAE9F,OAAO,MAAMC,eAAeH;IAC1B,OAAgBI,cAAc,oCAAmC;IAEjE,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ,CAAC,EAAqB;IAE9C,MAAaC,MAAqB;QAChC,8CAA8C;QAC9C,MAAM,IAAI,CAACC,KAAK,CAACN;QAEjB,IAAI;YACF,MAAMO,SAAS,MAAMT,WAAW;gBAC9BU,QAAQ;YACV;YAEA,IAAI,CAACC,MAAM,CAACC,GAAG,CAACH,OAAOI,OAAO;YAE9B,IAAIJ,OAAOK,OAAO,EAAE;gBAClB,IAAI,CAACH,MAAM,CAACC,GAAG,CAAC,CAAC,EAAE,EAAEX,0BAA0B,YAAY;YAC7D;QACF,EAAE,OAAOc,KAAc;YACrB,MAAMF,UAAUE,eAAeC,QAAQD,IAAIF,OAAO,GAAG;YACrD,OAAO,IAAI,CAACF,MAAM,CAACM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAC5C;IACF;AACF"}
@@ -17,8 +17,8 @@ export class Status extends SanityCommand {
17
17
  const consentInfo = await resolveConsent();
18
18
  const statusMessage = getStatusMessage(consentInfo);
19
19
  const learnMoreMessage = getLearnMoreMessage(consentInfo.status);
20
- this.log(statusMessage);
21
- this.log(`\n${learnMoreMessage}`);
20
+ this.output.log(statusMessage);
21
+ this.output.log(`\n${learnMoreMessage}`);
22
22
  }
23
23
  }
24
24
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/telemetry/status.ts"],"sourcesContent":["import {Command} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {getLearnMoreMessage} from '../../actions/telemetry/getLearnMoreMessage.js'\nimport {getStatusMessage} from '../../actions/telemetry/getStatusMessage.js'\nimport {resolveConsent} from '../../actions/telemetry/resolveConsent.js'\n\nexport class Status extends SanityCommand<typeof Status> {\n static override description = 'Check telemetry status for your account'\n\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> telemetry <%= command.id %>',\n description: 'Check telemetry status for your account',\n },\n ]\n\n static override flags = {} satisfies FlagInput\n\n public async run(): Promise<void> {\n // Parse to ensure no invalid flags are passed\n await this.parse(Status)\n\n const consentInfo = await resolveConsent()\n\n const statusMessage = getStatusMessage(consentInfo)\n const learnMoreMessage = getLearnMoreMessage(consentInfo.status)\n\n this.log(statusMessage)\n this.log(`\\n${learnMoreMessage}`)\n }\n}\n"],"names":["SanityCommand","getLearnMoreMessage","getStatusMessage","resolveConsent","Status","description","examples","command","flags","run","parse","consentInfo","statusMessage","learnMoreMessage","status","log"],"mappings":"AAEA,SAAQA,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,mBAAmB,QAAO,iDAAgD;AAClF,SAAQC,gBAAgB,QAAO,8CAA6C;AAC5E,SAAQC,cAAc,QAAO,4CAA2C;AAExE,OAAO,MAAMC,eAAeJ;IAC1B,OAAgBK,cAAc,0CAAyC;IAEvE,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ,CAAC,EAAqB;IAE9C,MAAaC,MAAqB;QAChC,8CAA8C;QAC9C,MAAM,IAAI,CAACC,KAAK,CAACN;QAEjB,MAAMO,cAAc,MAAMR;QAE1B,MAAMS,gBAAgBV,iBAAiBS;QACvC,MAAME,mBAAmBZ,oBAAoBU,YAAYG,MAAM;QAE/D,IAAI,CAACC,GAAG,CAACH;QACT,IAAI,CAACG,GAAG,CAAC,CAAC,EAAE,EAAEF,kBAAkB;IAClC;AACF"}
1
+ {"version":3,"sources":["../../../src/commands/telemetry/status.ts"],"sourcesContent":["import {Command} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {getLearnMoreMessage} from '../../actions/telemetry/getLearnMoreMessage.js'\nimport {getStatusMessage} from '../../actions/telemetry/getStatusMessage.js'\nimport {resolveConsent} from '../../actions/telemetry/resolveConsent.js'\n\nexport class Status extends SanityCommand<typeof Status> {\n static override description = 'Check telemetry status for your account'\n\n static override examples: Array<Command.Example> = [\n {\n command: '<%= config.bin %> telemetry <%= command.id %>',\n description: 'Check telemetry status for your account',\n },\n ]\n\n static override flags = {} satisfies FlagInput\n\n public async run(): Promise<void> {\n // Parse to ensure no invalid flags are passed\n await this.parse(Status)\n\n const consentInfo = await resolveConsent()\n\n const statusMessage = getStatusMessage(consentInfo)\n const learnMoreMessage = getLearnMoreMessage(consentInfo.status)\n\n this.output.log(statusMessage)\n this.output.log(`\\n${learnMoreMessage}`)\n }\n}\n"],"names":["SanityCommand","getLearnMoreMessage","getStatusMessage","resolveConsent","Status","description","examples","command","flags","run","parse","consentInfo","statusMessage","learnMoreMessage","status","output","log"],"mappings":"AAEA,SAAQA,aAAa,QAAO,mBAAkB;AAE9C,SAAQC,mBAAmB,QAAO,iDAAgD;AAClF,SAAQC,gBAAgB,QAAO,8CAA6C;AAC5E,SAAQC,cAAc,QAAO,4CAA2C;AAExE,OAAO,MAAMC,eAAeJ;IAC1B,OAAgBK,cAAc,0CAAyC;IAEvE,OAAgBC,WAAmC;QACjD;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ,CAAC,EAAqB;IAE9C,MAAaC,MAAqB;QAChC,8CAA8C;QAC9C,MAAM,IAAI,CAACC,KAAK,CAACN;QAEjB,MAAMO,cAAc,MAAMR;QAE1B,MAAMS,gBAAgBV,iBAAiBS;QACvC,MAAME,mBAAmBZ,oBAAoBU,YAAYG,MAAM;QAE/D,IAAI,CAACC,MAAM,CAACC,GAAG,CAACJ;QAChB,IAAI,CAACG,MAAM,CAACC,GAAG,CAAC,CAAC,EAAE,EAAEH,kBAAkB;IACzC;AACF"}
@@ -1,4 +1,6 @@
1
+ import { getStudioEnvironmentVariables } from "@sanity/cli-build/_internal/env";
1
2
  import { Schema } from "@sanity/types";
3
+ import { StudioEnvVariablesOptions } from "@sanity/cli-build/_internal/env";
2
4
 
3
5
  /**
4
6
  * Extracts all serializable properties from userland schema types,
@@ -11,23 +13,7 @@ export declare function extractManifestSchemaTypes(
11
13
  workDir: string,
12
14
  ): Promise<ManifestSchemaType[]>;
13
15
 
14
- /**
15
- * Get environment variables prefixed with SANITY_STUDIO_, as an object.
16
- *
17
- * @param options - Options for the environment variable loading
18
- * {@link StudioEnvVariablesOptions}
19
- * @returns Object of studio environment variables
20
- *
21
- * @example
22
- * ```tsx
23
- * getStudioEnvironmentVariables({prefix: 'process.env.', jsonEncode: true})
24
- * ```
25
- *
26
- * @public
27
- */
28
- export declare function getStudioEnvironmentVariables(
29
- options?: StudioEnvVariablesOptions,
30
- ): Record<string, string>;
16
+ export { getStudioEnvironmentVariables };
31
17
 
32
18
  declare type ManifestArrayMember = Omit<ManifestSchemaType, "name"> & {
33
19
  name?: string;
@@ -99,35 +85,6 @@ declare type ManifestValidationRule = {
99
85
  flag: string;
100
86
  };
101
87
 
102
- /**
103
- * The params for the `getStudioEnvironmentVariables` and `getAppEnvironmentVariables` function
104
- * that gets Studio/App-focused environment variables.
105
- *
106
- * @public
107
- */
108
- export declare interface StudioEnvVariablesOptions {
109
- /**
110
- * When specified includes environment variables from dotenv files (`.env`), in the same way the studio does.
111
- * A `mode` must be specified, usually `development`
112
- * or `production`, which will load the corresponding `.env.development` or `.env.production`.
113
- * To specify where to look for the dotenv files, specify `options.envFile.envDir`.
114
- */
115
- envFile?:
116
- | false
117
- | {
118
- envDir?: string;
119
- mode: string;
120
- };
121
- /**
122
- * When specified, JSON-encodes the values, which is handy if you want to pass
123
- * this to a bundlers hardcoded defines, such as Vite's `define` or Webpack's `DefinePlugin`.
124
- */
125
- jsonEncode?: boolean;
126
- /**
127
- * When specified adds a prefix to the environment variable keys,
128
- * eg: `getStudioEnvironmentVariables({prefix: 'process.env.'})`
129
- */
130
- prefix?: string;
131
- }
88
+ export { StudioEnvVariablesOptions };
132
89
 
133
90
  export {};
@@ -1,4 +1,4 @@
1
- export { getStudioEnvironmentVariables } from '../actions/build/getEnvironmentVariables.js';
2
1
  export { extractManifestSchemaTypes } from '../actions/manifest/extractWorkspaceManifest.js';
2
+ export { getStudioEnvironmentVariables } from '@sanity/cli-build/_internal/env';
3
3
 
4
4
  //# sourceMappingURL=_internal.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/exports/_internal.ts"],"sourcesContent":["export {getStudioEnvironmentVariables} from '../actions/build/getEnvironmentVariables.js'\nexport type {StudioEnvVariablesOptions} from '../actions/build/getEnvironmentVariables.js'\nexport {extractManifestSchemaTypes} from '../actions/manifest/extractWorkspaceManifest.js'\n"],"names":["getStudioEnvironmentVariables","extractManifestSchemaTypes"],"mappings":"AAAA,SAAQA,6BAA6B,QAAO,8CAA6C;AAEzF,SAAQC,0BAA0B,QAAO,kDAAiD"}
1
+ {"version":3,"sources":["../../src/exports/_internal.ts"],"sourcesContent":["export {extractManifestSchemaTypes} from '../actions/manifest/extractWorkspaceManifest.js'\nexport {\n getStudioEnvironmentVariables,\n type StudioEnvVariablesOptions,\n} from '@sanity/cli-build/_internal/env'\n"],"names":["extractManifestSchemaTypes","getStudioEnvironmentVariables"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,kDAAiD;AAC1F,SACEC,6BAA6B,QAExB,kCAAiC"}
@@ -1,7 +1,7 @@
1
1
  import { extendViteConfigWithUserConfig, getViteConfig, writeSanityRuntime } from '@sanity/cli-build/_internal/build';
2
+ import { getAppEnvironmentVariables, getStudioEnvironmentVariables } from '@sanity/cli-build/_internal/env';
2
3
  import { getCliTelemetry } from '@sanity/cli-core';
3
4
  import { createServer } from 'vite';
4
- import { getAppEnvironmentVariables, getStudioEnvironmentVariables } from '../actions/build/getEnvironmentVariables.js';
5
5
  import { serverDebug } from './serverDebug.js';
6
6
  import { sanityTypegenPlugin } from './vite/plugin-typegen.js';
7
7
  const debug = serverDebug.extend('dev');
@@ -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 DefineAppInput} from '@sanity/workbench-cli'\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 isWorkbenchApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n services?: DefineAppInput['services']\n typegen?: CliConfig['typegen']\n views?: DefineAppInput['views']\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 isWorkbenchApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n services,\n typegen,\n views,\n vite: extendViteConfig,\n } = options\n\n debug('Writing Sanity runtime files')\n const {entries, watcher} = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isWorkbenchApp,\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 entries,\n getEnvironmentVariables,\n isApp,\n isWorkbenchApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n services,\n views,\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","isWorkbenchApp","reactCompiler","reactStrictMode","schemaExtraction","services","typegen","views","vite","extendViteConfig","entries","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;AAIhF,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;AAgCjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,GAAG,EACHC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,QAAQ,EACRC,OAAO,EACPC,KAAK,EACLC,MAAMC,gBAAgB,EACvB,GAAGhB;IAEJH,MAAM;IACN,MAAM,EAACoB,OAAO,EAAEC,OAAO,EAAC,GAAG,MAAM5B,mBAAmB;QAClDW;QACAC;QACAC;QACAC;QACAG;QACAC;QACAE;QACAS,OAAO;IACT;IAEAtB,MAAM;IACN,MAAMuB,OAAO;IAEb,SAASC;QACP,OAAOd,QACHd,2BAA2B;YAAC6B,YAAY;YAAMC,QAAQ;QAAc,KACpE7B,8BAA8B;YAAC4B,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAMnC,cAAc;QACjDoC,mBAAmB;YACjB,2BAA2B;eACvBZ,SAASa,UACT;gBACE9B,oBAAoB;oBAClB+B,QAAQd;oBACRe,iBAAiBrC;oBACjBsC,SAAS1B;gBACX;aACD,GACD,EAAE;SACP;QACDD;QACAC;QACAc;QACAI;QACAd;QACAC;QACAY,MAAM;QACNX;QACAE;QACAmB,QAAQ;YAACC,MAAM1B;YAAU2B,MAAM1B;QAAQ;QACvCM;QACAE;IACF;IAEA,sDAAsD;IACtD,IAAIE,kBAAkB;QACpBQ,aAAa,MAAMpC,+BACjB;YAAC6C,SAAS;YAASb;QAAI,GACvBI,YACAR;IAEJ;IAEAnB,MAAM;IACN,MAAMiC,SAAS,MAAMtC,aAAagC;IAElC3B,MAAM;IACN,MAAMiC,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 {\n getAppEnvironmentVariables,\n getStudioEnvironmentVariables,\n} from '@sanity/cli-build/_internal/env'\nimport {CliConfig, getCliTelemetry, type UserViteConfig} from '@sanity/cli-core'\nimport {type DefineAppInput} from '@sanity/workbench-cli'\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 {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 isWorkbenchApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n services?: DefineAppInput['services']\n typegen?: CliConfig['typegen']\n views?: DefineAppInput['views']\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 isWorkbenchApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n services,\n typegen,\n views,\n vite: extendViteConfig,\n } = options\n\n debug('Writing Sanity runtime files')\n const {entries, watcher} = await writeSanityRuntime({\n appTitle,\n basePath,\n cwd,\n entry,\n isApp,\n isWorkbenchApp,\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 entries,\n getEnvironmentVariables,\n isApp,\n isWorkbenchApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n services,\n views,\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","getAppEnvironmentVariables","getStudioEnvironmentVariables","getCliTelemetry","createServer","serverDebug","sanityTypegenPlugin","debug","extend","startDevServer","options","appTitle","basePath","cwd","entry","httpHost","httpPort","isApp","isWorkbenchApp","reactCompiler","reactStrictMode","schemaExtraction","services","typegen","views","vite","extendViteConfig","entries","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,SACEC,0BAA0B,EAC1BC,6BAA6B,QACxB,kCAAiC;AACxC,SAAmBC,eAAe,QAA4B,mBAAkB;AAIhF,SAAQC,YAAY,QAA8C,OAAM;AAExE,SAAQC,WAAW,QAAO,mBAAkB;AAC5C,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,MAAMC,QAAQF,YAAYG,MAAM,CAAC;AAgCjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,QAAQ,EACRC,GAAG,EACHC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,cAAc,EACdC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,QAAQ,EACRC,OAAO,EACPC,KAAK,EACLC,MAAMC,gBAAgB,EACvB,GAAGhB;IAEJH,MAAM;IACN,MAAM,EAACoB,OAAO,EAAEC,OAAO,EAAC,GAAG,MAAM5B,mBAAmB;QAClDW;QACAC;QACAC;QACAC;QACAG;QACAC;QACAE;QACAS,OAAO;IACT;IAEAtB,MAAM;IACN,MAAMuB,OAAO;IAEb,SAASC;QACP,OAAOd,QACHhB,2BAA2B;YAAC+B,YAAY;YAAMC,QAAQ;QAAc,KACpE/B,8BAA8B;YAAC8B,YAAY;YAAMC,QAAQ;QAAc;IAC7E;IAEA,IAAIC,aAA2B,MAAMnC,cAAc;QACjDoC,mBAAmB;YACjB,2BAA2B;eACvBZ,SAASa,UACT;gBACE9B,oBAAoB;oBAClB+B,QAAQd;oBACRe,iBAAiBnC;oBACjBoC,SAAS1B;gBACX;aACD,GACD,EAAE;SACP;QACDD;QACAC;QACAc;QACAI;QACAd;QACAC;QACAY,MAAM;QACNX;QACAE;QACAmB,QAAQ;YAACC,MAAM1B;YAAU2B,MAAM1B;QAAQ;QACvCM;QACAE;IACF;IAEA,sDAAsD;IACtD,IAAIE,kBAAkB;QACpBQ,aAAa,MAAMpC,+BACjB;YAAC6C,SAAS;YAASb;QAAI,GACvBI,YACAR;IAEJ;IAEAnB,MAAM;IACN,MAAMiC,SAAS,MAAMpC,aAAa8B;IAElC3B,MAAM;IACN,MAAMiC,OAAOI,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAIjB,SAAS;gBACX,MAAMA,QAAQiB,KAAK;YACrB;YACA,MAAML,OAAOK,KAAK;QACpB;QACAL;QACAZ;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {getModuleUrl} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, readPackageJson} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {coerce, eq, prerelease, parse as semverParse} from 'semver'\n\nconst defaultRequester = createRequester({\n middleware: {httpErrors: false, promise: {onlyBody: false}},\n})\n\ninterface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\nexport interface UnresolvedPrerelease {\n pkg: string\n version: string\n}\n\ninterface CompareDependencyVersionsResult {\n mismatched: Array<CompareDependencyVersions>\n unresolvedPrerelease: Array<UnresolvedPrerelease>\n}\n\ninterface CompareDependencyVersionsOptions {\n /** When provided, uses the app-specific module endpoint instead of the default endpoint. */\n appId?: string\n /** Optional requester for dependency injection (primarily for testing). */\n requester?: typeof defaultRequester\n}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param packages - An array of packages with their name and version to compare against remote.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param options - Optional configuration for version comparison.\n *\n * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)\n * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).\n *\n * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version\n * of a package cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {appId, requester = defaultRequester}: CompareDependencyVersionsOptions = {},\n): Promise<CompareDependencyVersionsResult> {\n const manifest = await readPackageJson(path.join(workDir, 'package.json'), {\n skipSchemaValidation: true,\n })\n const dependencies = {...manifest?.dependencies, ...manifest?.devDependencies}\n\n const mismatched: Array<CompareDependencyVersions> = []\n const unresolvedPrerelease: Array<UnresolvedPrerelease> = []\n\n for (const pkg of packages) {\n // Skip packages that are not declared in the local package.json\n if (!dependencies[pkg.name]) {\n continue\n }\n\n const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {appId}), requester)\n\n if (resolvedVersion === null) {\n if (prerelease(pkg.version)) {\n unresolvedPrerelease.push({pkg: pkg.name, version: pkg.version})\n continue\n }\n throw new Error(\n `Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`,\n )\n }\n\n const packageVersion = await getLocalPackageVersion(pkg.name, workDir)\n\n const manifestVersion = dependencies[pkg.name]\n\n const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion))\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg.name}`)\n }\n\n if (!eq(resolvedVersion, installed.version)) {\n mismatched.push({\n installed: installed.version,\n pkg: pkg.name,\n remote: resolvedVersion,\n })\n }\n }\n\n return {mismatched, unresolvedPrerelease}\n}\n\nasync function getRemoteResolvedVersion(\n url: string,\n request: typeof defaultRequester,\n): Promise<string | null> {\n let response\n try {\n response = await request({\n maxRedirects: 0,\n method: 'HEAD',\n url,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(`Failed to fetch remote version for ${url}: ${message}`, {cause: err})\n }\n\n // 302 is expected, but lets also handle 2xx\n if (response.statusCode < 400) {\n const resolved = response.headers['x-resolved-version']\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return resolved\n }\n\n if (response.statusCode === 404) {\n return null\n }\n\n throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`)\n}\n"],"names":["path","getModuleUrl","getLocalPackageVersion","readPackageJson","createRequester","coerce","eq","prerelease","parse","semverParse","defaultRequester","middleware","httpErrors","promise","onlyBody","compareDependencyVersions","packages","workDir","appId","requester","manifest","join","skipSchemaValidation","dependencies","devDependencies","mismatched","unresolvedPrerelease","pkg","name","resolvedVersion","getRemoteResolvedVersion","version","push","Error","packageVersion","manifestVersion","installed","remote","url","request","response","maxRedirects","method","err","message","String","cause","statusCode","resolved","headers","statusMessage"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {getModuleUrl} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, readPackageJson} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {coerce, eq, prerelease, parse as semverParse} from 'semver'\n\nconst defaultRequester = createRequester({\n middleware: {httpErrors: false, promise: {onlyBody: false}},\n})\n\ninterface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\nexport interface UnresolvedPrerelease {\n pkg: string\n version: string\n}\n\nexport interface CompareDependencyVersionsResult {\n mismatched: Array<CompareDependencyVersions>\n unresolvedPrerelease: Array<UnresolvedPrerelease>\n}\n\ninterface CompareDependencyVersionsOptions {\n /** When provided, uses the app-specific module endpoint instead of the default endpoint. */\n appId?: string\n /** Optional requester for dependency injection (primarily for testing). */\n requester?: typeof defaultRequester\n}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param packages - An array of packages with their name and version to compare against remote.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param options - Optional configuration for version comparison.\n *\n * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)\n * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).\n *\n * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version\n * of a package cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {appId, requester = defaultRequester}: CompareDependencyVersionsOptions = {},\n): Promise<CompareDependencyVersionsResult> {\n const manifest = await readPackageJson(path.join(workDir, 'package.json'), {\n skipSchemaValidation: true,\n })\n const dependencies = {...manifest?.dependencies, ...manifest?.devDependencies}\n\n const mismatched: Array<CompareDependencyVersions> = []\n const unresolvedPrerelease: Array<UnresolvedPrerelease> = []\n\n for (const pkg of packages) {\n // Skip packages that are not declared in the local package.json\n if (!dependencies[pkg.name]) {\n continue\n }\n\n const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {appId}), requester)\n\n if (resolvedVersion === null) {\n if (prerelease(pkg.version)) {\n unresolvedPrerelease.push({pkg: pkg.name, version: pkg.version})\n continue\n }\n throw new Error(\n `Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`,\n )\n }\n\n const packageVersion = await getLocalPackageVersion(pkg.name, workDir)\n\n const manifestVersion = dependencies[pkg.name]\n\n const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion))\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg.name}`)\n }\n\n if (!eq(resolvedVersion, installed.version)) {\n mismatched.push({\n installed: installed.version,\n pkg: pkg.name,\n remote: resolvedVersion,\n })\n }\n }\n\n return {mismatched, unresolvedPrerelease}\n}\n\nasync function getRemoteResolvedVersion(\n url: string,\n request: typeof defaultRequester,\n): Promise<string | null> {\n let response\n try {\n response = await request({\n maxRedirects: 0,\n method: 'HEAD',\n url,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(`Failed to fetch remote version for ${url}: ${message}`, {cause: err})\n }\n\n // 302 is expected, but lets also handle 2xx\n if (response.statusCode < 400) {\n const resolved = response.headers['x-resolved-version']\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return resolved\n }\n\n if (response.statusCode === 404) {\n return null\n }\n\n throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`)\n}\n"],"names":["path","getModuleUrl","getLocalPackageVersion","readPackageJson","createRequester","coerce","eq","prerelease","parse","semverParse","defaultRequester","middleware","httpErrors","promise","onlyBody","compareDependencyVersions","packages","workDir","appId","requester","manifest","join","skipSchemaValidation","dependencies","devDependencies","mismatched","unresolvedPrerelease","pkg","name","resolvedVersion","getRemoteResolvedVersion","version","push","Error","packageVersion","manifestVersion","installed","remote","url","request","response","maxRedirects","method","err","message","String","cause","statusCode","resolved","headers","statusMessage"],"mappings":"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"}
@@ -1,5 +1,8 @@
1
1
  import { getLatestVersion } from 'get-latest-version';
2
2
  import promiseProps from 'promise-props-recursive';
3
+ // Cap each lookup so a stuck npm request can't hang `init` (or crash it with Node's
4
+ // "unsettled top-level await" exit, code 13). On timeout, fall back to the `latest` tag.
5
+ const LOOKUP_TIMEOUT_MS = 30_000;
3
6
  /**
4
7
  * Resolve the latest versions of given packages within their defined ranges
5
8
  *
@@ -8,14 +11,29 @@ import promiseProps from 'promise-props-recursive';
8
11
  */ export function resolveLatestVersions(pkgs) {
9
12
  const lookups = {};
10
13
  for (const [packageName, range] of Object.entries(pkgs)){
11
- lookups[packageName] = range === 'latest' ? getLatestVersion(packageName, {
14
+ lookups[packageName] = range === 'latest' ? withTimeout(getLatestVersion(packageName, {
12
15
  range
13
- }).then(caretify) : range;
16
+ }).then(caretify), 'latest') : range;
14
17
  }
15
18
  return promiseProps(lookups);
16
19
  }
17
20
  function caretify(version) {
18
21
  return version ? `^${version}` : 'latest';
19
22
  }
23
+ /**
24
+ * Resolve `fallback` if `promise` stalls past the timeout. The timer is deliberately not
25
+ * `unref`'d — keeping the event loop alive is what prevents the exit-13.
26
+ */ function withTimeout(promise, fallback) {
27
+ let timer;
28
+ const timeout = new Promise((resolve)=>{
29
+ timer = setTimeout(()=>resolve(fallback), LOOKUP_TIMEOUT_MS);
30
+ });
31
+ return Promise.race([
32
+ promise,
33
+ timeout
34
+ ]).finally(()=>{
35
+ if (timer) clearTimeout(timer);
36
+ });
37
+ }
20
38
 
21
39
  //# sourceMappingURL=resolveLatestVersions.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/resolveLatestVersions.ts"],"sourcesContent":["import {getLatestVersion} from 'get-latest-version'\nimport promiseProps from 'promise-props-recursive'\n\n/**\n * Resolve the latest versions of given packages within their defined ranges\n *\n * @param pkgs - `{packageName: rangeOrTag}`\n * @returns Object of resolved version numbers\n */\nexport function resolveLatestVersions(\n pkgs: Record<string, string>,\n): Promise<Record<string, string>> {\n const lookups: Record<string, Promise<string> | string> = {}\n for (const [packageName, range] of Object.entries(pkgs)) {\n lookups[packageName] =\n range === 'latest' ? getLatestVersion(packageName, {range}).then(caretify) : range\n }\n\n return promiseProps(lookups)\n}\n\nfunction caretify(version: string | undefined) {\n return version ? `^${version}` : 'latest'\n}\n"],"names":["getLatestVersion","promiseProps","resolveLatestVersions","pkgs","lookups","packageName","range","Object","entries","then","caretify","version"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,qBAAoB;AACnD,OAAOC,kBAAkB,0BAAyB;AAElD;;;;;CAKC,GACD,OAAO,SAASC,sBACdC,IAA4B;IAE5B,MAAMC,UAAoD,CAAC;IAC3D,KAAK,MAAM,CAACC,aAAaC,MAAM,IAAIC,OAAOC,OAAO,CAACL,MAAO;QACvDC,OAAO,CAACC,YAAY,GAClBC,UAAU,WAAWN,iBAAiBK,aAAa;YAACC;QAAK,GAAGG,IAAI,CAACC,YAAYJ;IACjF;IAEA,OAAOL,aAAaG;AACtB;AAEA,SAASM,SAASC,OAA2B;IAC3C,OAAOA,UAAU,CAAC,CAAC,EAAEA,SAAS,GAAG;AACnC"}
1
+ {"version":3,"sources":["../../src/util/resolveLatestVersions.ts"],"sourcesContent":["import {getLatestVersion} from 'get-latest-version'\nimport promiseProps from 'promise-props-recursive'\n\n// Cap each lookup so a stuck npm request can't hang `init` (or crash it with Node's\n// \"unsettled top-level await\" exit, code 13). On timeout, fall back to the `latest` tag.\nconst LOOKUP_TIMEOUT_MS = 30_000\n\n/**\n * Resolve the latest versions of given packages within their defined ranges\n *\n * @param pkgs - `{packageName: rangeOrTag}`\n * @returns Object of resolved version numbers\n */\nexport function resolveLatestVersions(\n pkgs: Record<string, string>,\n): Promise<Record<string, string>> {\n const lookups: Record<string, Promise<string> | string> = {}\n for (const [packageName, range] of Object.entries(pkgs)) {\n lookups[packageName] =\n range === 'latest'\n ? withTimeout(getLatestVersion(packageName, {range}).then(caretify), 'latest')\n : range\n }\n\n return promiseProps(lookups)\n}\n\nfunction caretify(version: string | undefined) {\n return version ? `^${version}` : 'latest'\n}\n\n/**\n * Resolve `fallback` if `promise` stalls past the timeout. The timer is deliberately not\n * `unref`'d — keeping the event loop alive is what prevents the exit-13.\n */\nfunction withTimeout(promise: Promise<string>, fallback: string): Promise<string> {\n let timer: ReturnType<typeof setTimeout> | undefined\n const timeout = new Promise<string>((resolve) => {\n timer = setTimeout(() => resolve(fallback), LOOKUP_TIMEOUT_MS)\n })\n\n return Promise.race([promise, timeout]).finally(() => {\n if (timer) clearTimeout(timer)\n })\n}\n"],"names":["getLatestVersion","promiseProps","LOOKUP_TIMEOUT_MS","resolveLatestVersions","pkgs","lookups","packageName","range","Object","entries","withTimeout","then","caretify","version","promise","fallback","timer","timeout","Promise","resolve","setTimeout","race","finally","clearTimeout"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,qBAAoB;AACnD,OAAOC,kBAAkB,0BAAyB;AAElD,oFAAoF;AACpF,yFAAyF;AACzF,MAAMC,oBAAoB;AAE1B;;;;;CAKC,GACD,OAAO,SAASC,sBACdC,IAA4B;IAE5B,MAAMC,UAAoD,CAAC;IAC3D,KAAK,MAAM,CAACC,aAAaC,MAAM,IAAIC,OAAOC,OAAO,CAACL,MAAO;QACvDC,OAAO,CAACC,YAAY,GAClBC,UAAU,WACNG,YAAYV,iBAAiBM,aAAa;YAACC;QAAK,GAAGI,IAAI,CAACC,WAAW,YACnEL;IACR;IAEA,OAAON,aAAaI;AACtB;AAEA,SAASO,SAASC,OAA2B;IAC3C,OAAOA,UAAU,CAAC,CAAC,EAAEA,SAAS,GAAG;AACnC;AAEA;;;CAGC,GACD,SAASH,YAAYI,OAAwB,EAAEC,QAAgB;IAC7D,IAAIC;IACJ,MAAMC,UAAU,IAAIC,QAAgB,CAACC;QACnCH,QAAQI,WAAW,IAAMD,QAAQJ,WAAWb;IAC9C;IAEA,OAAOgB,QAAQG,IAAI,CAAC;QAACP;QAASG;KAAQ,EAAEK,OAAO,CAAC;QAC9C,IAAIN,OAAOO,aAAaP;IAC1B;AACF"}
@@ -5149,5 +5149,5 @@
5149
5149
  ]
5150
5150
  }
5151
5151
  },
5152
- "version": "7.3.0"
5152
+ "version": "7.4.1"
5153
5153
  }