@sanity/cli 7.15.0 → 7.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -1
- package/dist/actions/build/shouldAutoUpdate.js +28 -5
- package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +4 -8
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +49 -31
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js +1 -1
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +12 -10
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deploymentPlan.js +2 -2
- package/dist/actions/deploy/deploymentPlan.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +13 -13
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +2 -3
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/createAppCliConfig.js.map +1 -1
- package/dist/actions/init/createCliConfig.js.map +1 -1
- package/dist/actions/init/initNextJs.js +1 -1
- package/dist/actions/init/initNextJs.js.map +1 -1
- package/dist/actions/init/initStudio.js +10 -6
- package/dist/actions/init/initStudio.js.map +1 -1
- package/dist/actions/init/templates/appSanityUi.js +1 -1
- package/dist/actions/init/templates/appSanityUi.js.map +1 -1
- package/dist/actions/init/templates/getStarted.js +2 -2
- package/dist/actions/init/templates/getStarted.js.map +1 -1
- package/dist/actions/init/templates/nextjs/schemaTypes/blog.js +4 -4
- package/dist/actions/init/templates/nextjs/schemaTypes/blog.js.map +1 -1
- package/dist/actions/init/templates/shopify.js +2 -2
- package/dist/actions/init/templates/shopify.js.map +1 -1
- package/dist/actions/init/templates/shopifyOnline.js +2 -2
- package/dist/actions/init/templates/shopifyOnline.js.map +1 -1
- package/dist/actions/manifest/extractCoreAppManifest.js +7 -7
- package/dist/actions/manifest/extractCoreAppManifest.js.map +1 -1
- package/dist/actions/scaffold/createFrontend.js +107 -0
- package/dist/actions/scaffold/createFrontend.js.map +1 -0
- package/dist/actions/scaffold/scaffoldProject.js +202 -0
- package/dist/actions/scaffold/scaffoldProject.js.map +1 -0
- package/dist/actions/telemetry/resolveConsent.js +4 -2
- package/dist/actions/telemetry/resolveConsent.js.map +1 -1
- package/dist/commands/backups/list.js +1 -1
- package/dist/commands/backups/list.js.map +1 -1
- package/dist/commands/datasets/copy.js +5 -3
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/documents/query.js +5 -4
- package/dist/commands/documents/query.js.map +1 -1
- package/dist/commands/migrations/list.js +1 -1
- package/dist/commands/migrations/list.js.map +1 -1
- package/dist/commands/migrations/run.js +1 -1
- package/dist/commands/migrations/run.js.map +1 -1
- package/dist/commands/new.js +309 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/organizations/list.js +1 -1
- package/dist/commands/organizations/list.js.map +1 -1
- package/dist/commands/projects/unclaimed.js +205 -0
- package/dist/commands/projects/unclaimed.js.map +1 -0
- package/dist/commands/tokens/list.js +1 -1
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/users/list.js +5 -1
- package/dist/commands/users/list.js.map +1 -1
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +4 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
- package/dist/exports/invokeSanityCli/index.d.ts +5 -9
- package/dist/exports/invokeSanityCli/index.js +47 -20
- package/dist/exports/invokeSanityCli/index.js.map +1 -1
- package/dist/exports/runtime.d.ts +12 -0
- package/dist/exports/runtime.js.map +1 -1
- package/dist/services/mintProject.js +91 -0
- package/dist/services/mintProject.js.map +1 -0
- package/dist/services/projects.js +19 -0
- package/dist/services/projects.js.map +1 -1
- package/dist/services/telemetry.js +4 -0
- package/dist/services/telemetry.js.map +1 -1
- package/dist/util/formatClaimDeadline.js +15 -0
- package/dist/util/formatClaimDeadline.js.map +1 -0
- package/dist/util/mintProjectConstants.js +6 -0
- package/dist/util/mintProjectConstants.js.map +1 -0
- package/dist/util/newCommandSplash.js +27 -0
- package/dist/util/newCommandSplash.js.map +1 -0
- package/dist/util/packageManager/installPackages.js +57 -28
- package/dist/util/packageManager/installPackages.js.map +1 -1
- package/dist/util/unclaimedProjects.js +105 -0
- package/dist/util/unclaimedProjects.js.map +1 -0
- package/oclif.manifest.json +150 -41
- package/package.json +7 -7
- package/templates/get-started/plugins/sanity-plugin-tutorial/GetStartedTutorial.tsx +1 -1
- package/templates/shopify/components/inputs/CollectionHidden.tsx +1 -1
- package/templates/shopify/components/inputs/ProductHidden.tsx +1 -1
- package/templates/shopify/components/inputs/ProductVariantHidden.tsx +1 -1
- package/templates/shopify/components/inputs/ProxyString.tsx +1 -1
- package/templates/shopify/components/media/ShopifyDocumentStatus.tsx +3 -1
- package/templates/shopify/constants.ts +3 -1
- package/templates/shopify/plugins/customDocumentActions/shopifyDelete.tsx +1 -1
- package/templates/shopify/plugins/customDocumentActions/shopifyLink.ts +1 -1
- package/templates/shopify/schemaTypes/documents/collection.tsx +1 -1
- package/templates/shopify/schemaTypes/documents/colorTheme.tsx +1 -1
- package/templates/shopify/schemaTypes/documents/page.ts +1 -1
- package/templates/shopify/schemaTypes/documents/product.tsx +1 -1
- package/templates/shopify/schemaTypes/documents/productVariant.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/collection/collectionGroupType.ts +1 -1
- package/templates/shopify/schemaTypes/objects/hotspot/imageWithProductHotspotsType.ts +1 -1
- package/templates/shopify/schemaTypes/objects/link/linkEmailType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/link/linkExternalType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/link/linkInternalType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/link/linkProductType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/module/accordionType.ts +1 -1
- package/templates/shopify/schemaTypes/objects/module/callToActionType.tsx +2 -1
- package/templates/shopify/schemaTypes/objects/module/calloutType.ts +1 -1
- package/templates/shopify/schemaTypes/objects/module/collectionReferenceType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/module/gridType.ts +1 -1
- package/templates/shopify/schemaTypes/objects/module/imageFeatureType.ts +1 -1
- package/templates/shopify/schemaTypes/objects/module/imageFeaturesType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/module/instagramType.ts +1 -1
- package/templates/shopify/schemaTypes/objects/module/productFeaturesType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/module/productReferenceType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/shopify/collectionRuleType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/shopify/optionType.tsx +1 -1
- package/templates/shopify/schemaTypes/objects/shopify/productWithVariantType.tsx +1 -1
- package/templates/shopify/schemaTypes/singletons/homeType.ts +1 -1
- package/templates/shopify/schemaTypes/singletons/settingsType.ts +5 -1
- package/templates/shopify/structure/pageStructure.ts +1 -1
- package/templates/shopify/structure/productStructure.ts +1 -1
- package/templates/shopify-online-storefront/components/inputs/CollectionHidden.tsx +1 -1
- package/templates/shopify-online-storefront/components/inputs/ProductHidden.tsx +1 -1
- package/templates/shopify-online-storefront/components/inputs/ProductVariantHidden.tsx +1 -1
- package/templates/shopify-online-storefront/components/inputs/ProxyString.tsx +1 -1
- package/templates/shopify-online-storefront/components/media/ShopifyDocumentStatus.tsx +3 -1
- package/templates/shopify-online-storefront/plugins/shopifyDocumentActions/shopifyDelete.tsx +1 -1
- package/templates/shopify-online-storefront/plugins/shopifyDocumentActions/shopifyLink.ts +1 -1
- package/templates/shopify-online-storefront/schemaTypes/documents/collection.tsx +1 -1
- package/templates/shopify-online-storefront/schemaTypes/documents/product.tsx +1 -1
- package/templates/shopify-online-storefront/schemaTypes/documents/productVariant.tsx +1 -1
- package/templates/shopify-online-storefront/schemaTypes/objects/accordion.ts +1 -1
- package/templates/shopify-online-storefront/schemaTypes/objects/callout.ts +1 -1
- package/templates/shopify-online-storefront/schemaTypes/objects/option.ts +1 -1
- package/templates/shopify-online-storefront/schemaTypes/objects/shopifyCollectionRule.tsx +1 -1
- package/templates/shopify-online-storefront/structure/productStructure.ts +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/datasets/copy.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exit} from '@oclif/core/errors'\nimport {exitCodes} from '@sanity/cli-core'\nimport {subdebug} from '@sanity/cli-core/debug'\nimport {SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {Table} from 'console-table-printer'\nimport {formatDistance} from 'date-fns/formatDistance'\nimport {formatDistanceToNow} from 'date-fns/formatDistanceToNow'\nimport {parseISO} from 'date-fns/parseISO'\n\nimport {validateDatasetName} from '../../actions/dataset/validateDatasetName.js'\nimport {promptForDataset} from '../../prompts/promptForDataset.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {\n copyDataset,\n type CopyJobProgressEvent,\n type DatasetCopyJob,\n followCopyJobProgress,\n listDatasetCopyJobs,\n listDatasets,\n} from '../../services/datasets.js'\nimport {formatCliErrorMessages} from '../../util/formatCliErrorMessages.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst copyDatasetDebug = subdebug('dataset:copy')\n\nexport class CopyDatasetCommand extends SanityCommand<typeof CopyDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Name of the dataset to copy from',\n required: false,\n }),\n target: Args.string({\n description: 'Name of the dataset to copy to',\n required: false,\n }),\n }\n\n static override description = 'Copy a dataset or manage copy jobs'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively copy a dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> source-dataset',\n description: 'Copy from source-dataset (prompts for target)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> source-dataset target-dataset',\n description: 'Copy from source-dataset to target-dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --skip-history source target',\n description: 'Copy without preserving document history (faster for large datasets)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --skip-content-releases source target',\n description: 'Copy without content release documents',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --detach source target',\n description: 'Start copy job without waiting for completion',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --attach <job-id>',\n description: 'Attach to a running copy job to follow progress',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --list',\n description: 'List all dataset copy jobs',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --list --offset 2 --limit 10',\n description: 'List copy jobs with pagination',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to copy dataset in',\n semantics: 'override',\n }),\n attach: Flags.string({\n description: 'Attach to the running copy process to show progress',\n exclusive: ['list', 'detach', 'skip-history'],\n required: false,\n }),\n detach: Flags.boolean({\n description: 'Start the copy without waiting for it to finish',\n exclusive: ['list', 'attach'],\n required: false,\n }),\n limit: Flags.integer({\n dependsOn: ['list'],\n description: 'Maximum number of jobs returned (default 10, max 1000)',\n max: 1000,\n required: false,\n }),\n list: Flags.boolean({\n description: 'Lists all dataset copy jobs',\n exclusive: ['attach', 'detach', 'skip-history'],\n required: false,\n }),\n offset: Flags.integer({\n dependsOn: ['list'],\n description: 'Start position in the list of jobs (default 0)',\n required: false,\n }),\n 'skip-content-releases': Flags.boolean({\n description: \"Don't copy content release documents to the target dataset\",\n exclusive: ['list', 'attach'],\n required: false,\n }),\n 'skip-history': Flags.boolean({\n description: \"Don't preserve document history on copy\",\n exclusive: ['list', 'attach'],\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:copy']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CopyDatasetCommand)\n\n if (!flags.list && !flags.attach && this.isUnattended()) {\n const errors: string[] = []\n\n if (!args.source) {\n errors.push('Source dataset is required. Pass it as the `<source>` argument.')\n }\n if (!args.target) {\n errors.push('Target dataset is required. Pass it as the `<target>` argument.')\n }\n\n if (errors.length > 0) {\n this.output.error(formatCliErrorMessages(errors), {exit: exitCodes.USAGE_ERROR})\n }\n }\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'create', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n // Route to appropriate mode\n if (flags.list) {\n return this.handleListMode(projectId, flags)\n }\n\n if (flags.attach) {\n return this.handleAttachMode(projectId, flags.attach)\n }\n\n return this.handleCopyMode(projectId, args, flags)\n }\n\n private displayCopyJobsTable(jobs: DatasetCopyJob[]): void {\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'Job ID'},\n {alignment: 'left', name: 'sourceDataset', title: 'Source Dataset'},\n {alignment: 'left', name: 'targetDataset', title: 'Target Dataset'},\n {alignment: 'left', name: 'state', title: 'State'},\n {alignment: 'left', name: 'withHistory', title: 'With history'},\n {alignment: 'left', name: 'timeStarted', title: 'Time started'},\n {alignment: 'left', name: 'timeTaken', title: 'Time taken'},\n ],\n title: 'Dataset copy jobs for this project in descending order',\n })\n\n for (const job of jobs) {\n const {createdAt, id, sourceDataset, state, targetDataset, updatedAt, withHistory} = job\n\n let timeStarted = ''\n if (createdAt !== '') {\n timeStarted = formatDistanceToNow(parseISO(createdAt))\n }\n\n let timeTaken = ''\n if (updatedAt !== '') {\n timeTaken = formatDistance(parseISO(updatedAt), parseISO(createdAt))\n }\n\n let color: '' | 'green' | 'red' | 'yellow'\n switch (state) {\n case 'completed': {\n color = 'green'\n break\n }\n case 'failed': {\n color = 'red'\n break\n }\n case 'pending': {\n color = 'yellow'\n break\n }\n default: {\n color = ''\n }\n }\n\n table.addRow(\n {\n id,\n sourceDataset,\n state,\n targetDataset,\n timeStarted: `${timeStarted} ago`,\n timeTaken,\n withHistory,\n },\n {color},\n )\n }\n\n this.output.log(table.render())\n }\n\n private async handleAttachMode(projectId: string, jobId: string): Promise<void> {\n copyDatasetDebug('Attaching to copy job %s', jobId)\n\n if (jobId.trim() === '') {\n return this.output.error('Please supply a valid jobId', {exit: exitCodes.RUNTIME_ERROR})\n }\n\n try {\n await this.subscribeToProgress(projectId, jobId)\n this.output.log(`Job ${styleText('green', jobId)} completed`)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Failed to attach to copy job: %s', message, error)\n return this.output.error(`Failed to attach to copy job: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async handleCopyMode(\n projectId: string,\n args: {source?: string; target?: string},\n flags: {detach?: boolean; 'skip-content-releases'?: boolean; 'skip-history'?: boolean},\n ): Promise<void> {\n copyDatasetDebug('Starting copy mode')\n\n const skipHistory = Boolean(flags['skip-history'])\n const skipContentReleases = Boolean(flags['skip-content-releases'])\n\n // Surfaced before any prompting so the flag is still actionable: a copy job\n // can't be canceled once started, so mentioning it after the job kicks off\n // leaves nothing to decide.\n if (!skipHistory) {\n this.output.log(\n `Note: You can run this command with flag '--skip-history'. The flag will reduce copy time in larger datasets.`,\n )\n }\n\n // Get and validate source dataset\n let sourceDataset = args.source\n if (sourceDataset) {\n const nameError = validateDatasetName(sourceDataset)\n if (nameError) {\n return this.output.error(nameError, {exit: exitCodes.USAGE_ERROR})\n }\n }\n\n let datasetsResponse\n try {\n datasetsResponse = await listDatasets(projectId)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Failed to fetch datasets: %s', message, error)\n return this.output.error(`Failed to fetch datasets: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const datasetNames = new Set(datasetsResponse.map((ds) => ds.name))\n\n // Prompt for source if not provided\n if (!sourceDataset) {\n sourceDataset = await promptForDataset({\n datasets: datasetsResponse,\n })\n }\n\n if (!datasetNames.has(sourceDataset)) {\n return this.output.error(`Source dataset \"${sourceDataset}\" doesn't exist`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // Get and validate target dataset\n let targetDataset = args.target\n if (targetDataset) {\n const nameError = validateDatasetName(targetDataset)\n if (nameError) {\n return this.output.error(nameError, {exit: exitCodes.USAGE_ERROR})\n }\n } else {\n targetDataset = await promptForDatasetName({\n message: 'Target dataset name:',\n })\n }\n\n if (datasetNames.has(targetDataset)) {\n return this.output.error(`Target dataset \"${targetDataset}\" already exists`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // Start the copy job\n try {\n this.output.log(\n `Copying dataset ${styleText('green', sourceDataset)} to ${styleText('green', targetDataset)}...`,\n )\n\n const response = await copyDataset({\n projectId,\n skipContentReleases,\n skipHistory,\n sourceDataset,\n targetDataset,\n })\n\n this.output.log(`Job ${styleText('green', response.jobId)} started`)\n\n if (flags.detach) {\n return\n }\n\n await this.subscribeToProgress(projectId, response.jobId)\n this.output.log(`Job ${styleText('green', response.jobId)} completed`)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Dataset copying failed: %s', message, error)\n return this.output.error(`Dataset copying failed: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async handleListMode(\n projectId: string,\n flags: {limit?: number; offset?: number},\n ): Promise<void> {\n copyDatasetDebug('Listing dataset copy jobs')\n\n try {\n const jobs = await listDatasetCopyJobs({\n limit: flags.limit,\n offset: flags.offset,\n projectId,\n })\n\n if (jobs.length === 0) {\n this.output.log(\"This project doesn't have any dataset copy jobs\")\n return\n }\n\n this.displayCopyJobsTable(jobs)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Failed to list dataset copy jobs: %s', message, error)\n return this.output.error(`Failed to list dataset copy jobs: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async subscribeToProgress(projectId: string, jobId: string): Promise<void> {\n const spin = spinner('').start()\n\n return new Promise<void>((resolve, reject) => {\n const sigintHandler = () => {\n subscription.unsubscribe()\n spin.fail('Copy interrupted.')\n exit(130)\n }\n\n const subscription = followCopyJobProgress({jobId, projectId}).subscribe({\n complete: () => {\n process.off('SIGINT', sigintHandler)\n spin.succeed('Copy finished.')\n resolve()\n },\n error: (err) => {\n process.off('SIGINT', sigintHandler)\n spin.fail('Copy failed.')\n reject(err)\n },\n next: (event: CopyJobProgressEvent) => {\n if (typeof event.progress === 'number') {\n spin.text = `Copy in progress: ${event.progress}%`\n }\n },\n })\n\n process.once('SIGINT', sigintHandler)\n })\n }\n}\n"],"names":["styleText","Args","Flags","exit","exitCodes","subdebug","SanityCommand","spinner","Table","formatDistance","formatDistanceToNow","parseISO","validateDatasetName","promptForDataset","promptForDatasetName","promptForProject","copyDataset","followCopyJobProgress","listDatasetCopyJobs","listDatasets","formatCliErrorMessages","getProjectIdFlag","copyDatasetDebug","CopyDatasetCommand","args","source","string","description","required","target","examples","command","flags","semantics","attach","exclusive","detach","boolean","limit","integer","dependsOn","max","list","offset","hiddenAliases","run","parse","isUnattended","errors","push","length","output","error","USAGE_ERROR","projectId","getProjectId","fallback","requiredPermissions","grant","permission","handleListMode","handleAttachMode","handleCopyMode","displayCopyJobsTable","jobs","table","columns","alignment","name","title","job","createdAt","id","sourceDataset","state","targetDataset","updatedAt","withHistory","timeStarted","timeTaken","color","addRow","log","render","jobId","trim","RUNTIME_ERROR","subscribeToProgress","message","Error","String","skipHistory","Boolean","skipContentReleases","nameError","datasetsResponse","datasetNames","Set","map","ds","datasets","has","response","spin","start","Promise","resolve","reject","sigintHandler","subscription","unsubscribe","fail","subscribe","complete","process","off","succeed","err","next","event","progress","text","once"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/datasets/copy.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exit} from '@oclif/core/errors'\nimport {exitCodes} from '@sanity/cli-core'\nimport {subdebug} from '@sanity/cli-core/debug'\nimport {getCliExecutionContext} from '@sanity/cli-core/executionContext'\nimport {SanityCommand} from '@sanity/cli-core/SanityCommand'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {Table} from 'console-table-printer'\nimport {formatDistance} from 'date-fns/formatDistance'\nimport {formatDistanceToNow} from 'date-fns/formatDistanceToNow'\nimport {parseISO} from 'date-fns/parseISO'\n\nimport {validateDatasetName} from '../../actions/dataset/validateDatasetName.js'\nimport {promptForDataset} from '../../prompts/promptForDataset.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {\n copyDataset,\n type CopyJobProgressEvent,\n type DatasetCopyJob,\n followCopyJobProgress,\n listDatasetCopyJobs,\n listDatasets,\n} from '../../services/datasets.js'\nimport {formatCliErrorMessages} from '../../util/formatCliErrorMessages.js'\nimport {getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst copyDatasetDebug = subdebug('dataset:copy')\n\nexport class CopyDatasetCommand extends SanityCommand<typeof CopyDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Name of the dataset to copy from',\n required: false,\n }),\n target: Args.string({\n description: 'Name of the dataset to copy to',\n required: false,\n }),\n }\n\n static override description = 'Copy a dataset or manage copy jobs'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively copy a dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> source-dataset',\n description: 'Copy from source-dataset (prompts for target)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> source-dataset target-dataset',\n description: 'Copy from source-dataset to target-dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --skip-history source target',\n description: 'Copy without preserving document history (faster for large datasets)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --skip-content-releases source target',\n description: 'Copy without content release documents',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --detach source target',\n description: 'Start copy job without waiting for completion',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --attach <job-id>',\n description: 'Attach to a running copy job to follow progress',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --list',\n description: 'List all dataset copy jobs',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --list --offset 2 --limit 10',\n description: 'List copy jobs with pagination',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to copy dataset in',\n semantics: 'override',\n }),\n attach: Flags.string({\n description: 'Attach to the running copy process to show progress',\n exclusive: ['list', 'detach', 'skip-history'],\n required: false,\n }),\n detach: Flags.boolean({\n description: 'Start the copy without waiting for it to finish',\n exclusive: ['list', 'attach'],\n required: false,\n }),\n limit: Flags.integer({\n dependsOn: ['list'],\n description: 'Maximum number of jobs returned (default 10, max 1000)',\n max: 1000,\n required: false,\n }),\n list: Flags.boolean({\n description: 'Lists all dataset copy jobs',\n exclusive: ['attach', 'detach', 'skip-history'],\n required: false,\n }),\n offset: Flags.integer({\n dependsOn: ['list'],\n description: 'Start position in the list of jobs (default 0)',\n required: false,\n }),\n 'skip-content-releases': Flags.boolean({\n description: \"Don't copy content release documents to the target dataset\",\n exclusive: ['list', 'attach'],\n required: false,\n }),\n 'skip-history': Flags.boolean({\n description: \"Don't preserve document history on copy\",\n exclusive: ['list', 'attach'],\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:copy']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CopyDatasetCommand)\n\n if (!flags.list && !flags.attach && this.isUnattended()) {\n const errors: string[] = []\n\n if (!args.source) {\n errors.push('Source dataset is required. Pass it as the `<source>` argument.')\n }\n if (!args.target) {\n errors.push('Target dataset is required. Pass it as the `<target>` argument.')\n }\n\n if (errors.length > 0) {\n this.output.error(formatCliErrorMessages(errors), {exit: exitCodes.USAGE_ERROR})\n }\n }\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'create', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n // Route to appropriate mode\n if (flags.list) {\n return this.handleListMode(projectId, flags)\n }\n\n if (flags.attach) {\n return this.handleAttachMode(projectId, flags.attach)\n }\n\n return this.handleCopyMode(projectId, args, flags)\n }\n\n private displayCopyJobsTable(jobs: DatasetCopyJob[]): void {\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'Job ID'},\n {alignment: 'left', name: 'sourceDataset', title: 'Source Dataset'},\n {alignment: 'left', name: 'targetDataset', title: 'Target Dataset'},\n {alignment: 'left', name: 'state', title: 'State'},\n {alignment: 'left', name: 'withHistory', title: 'With history'},\n {alignment: 'left', name: 'timeStarted', title: 'Time started'},\n {alignment: 'left', name: 'timeTaken', title: 'Time taken'},\n ],\n title: 'Dataset copy jobs for this project in descending order',\n })\n\n for (const job of jobs) {\n const {createdAt, id, sourceDataset, state, targetDataset, updatedAt, withHistory} = job\n\n let timeStarted = ''\n if (createdAt !== '') {\n timeStarted = formatDistanceToNow(parseISO(createdAt))\n }\n\n let timeTaken = ''\n if (updatedAt !== '') {\n timeTaken = formatDistance(parseISO(updatedAt), parseISO(createdAt))\n }\n\n let color: '' | 'green' | 'red' | 'yellow'\n switch (state) {\n case 'completed': {\n color = 'green'\n break\n }\n case 'failed': {\n color = 'red'\n break\n }\n case 'pending': {\n color = 'yellow'\n break\n }\n default: {\n color = ''\n }\n }\n\n table.addRow(\n {\n id,\n sourceDataset,\n state,\n targetDataset,\n timeStarted: `${timeStarted} ago`,\n timeTaken,\n withHistory,\n },\n {color},\n )\n }\n\n this.output.log(table.render())\n }\n\n private async handleAttachMode(projectId: string, jobId: string): Promise<void> {\n copyDatasetDebug('Attaching to copy job %s', jobId)\n\n if (jobId.trim() === '') {\n return this.output.error('Please supply a valid jobId', {exit: exitCodes.RUNTIME_ERROR})\n }\n\n try {\n await this.subscribeToProgress(projectId, jobId)\n this.output.log(`Job ${styleText('green', jobId)} completed`)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Failed to attach to copy job: %s', message, error)\n return this.output.error(`Failed to attach to copy job: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async handleCopyMode(\n projectId: string,\n args: {source?: string; target?: string},\n flags: {detach?: boolean; 'skip-content-releases'?: boolean; 'skip-history'?: boolean},\n ): Promise<void> {\n copyDatasetDebug('Starting copy mode')\n\n const skipHistory = Boolean(flags['skip-history'])\n const skipContentReleases = Boolean(flags['skip-content-releases'])\n\n // Surfaced before any prompting so the flag is still actionable: a copy job\n // can't be canceled once started, so mentioning it after the job kicks off\n // leaves nothing to decide.\n if (!skipHistory) {\n this.output.log(\n `Note: You can run this command with flag '--skip-history'. The flag will reduce copy time in larger datasets.`,\n )\n }\n\n // Get and validate source dataset\n let sourceDataset = args.source\n if (sourceDataset) {\n const nameError = validateDatasetName(sourceDataset)\n if (nameError) {\n return this.output.error(nameError, {exit: exitCodes.USAGE_ERROR})\n }\n }\n\n let datasetsResponse\n try {\n datasetsResponse = await listDatasets(projectId)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Failed to fetch datasets: %s', message, error)\n return this.output.error(`Failed to fetch datasets: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const datasetNames = new Set(datasetsResponse.map((ds) => ds.name))\n\n // Prompt for source if not provided\n if (!sourceDataset) {\n sourceDataset = await promptForDataset({\n datasets: datasetsResponse,\n })\n }\n\n if (!datasetNames.has(sourceDataset)) {\n return this.output.error(`Source dataset \"${sourceDataset}\" doesn't exist`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // Get and validate target dataset\n let targetDataset = args.target\n if (targetDataset) {\n const nameError = validateDatasetName(targetDataset)\n if (nameError) {\n return this.output.error(nameError, {exit: exitCodes.USAGE_ERROR})\n }\n } else {\n targetDataset = await promptForDatasetName({\n message: 'Target dataset name:',\n })\n }\n\n if (datasetNames.has(targetDataset)) {\n return this.output.error(`Target dataset \"${targetDataset}\" already exists`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // Start the copy job\n try {\n this.output.log(\n `Copying dataset ${styleText('green', sourceDataset)} to ${styleText('green', targetDataset)}...`,\n )\n\n const response = await copyDataset({\n projectId,\n skipContentReleases,\n skipHistory,\n sourceDataset,\n targetDataset,\n })\n\n this.output.log(`Job ${styleText('green', response.jobId)} started`)\n\n if (flags.detach) {\n return\n }\n\n await this.subscribeToProgress(projectId, response.jobId)\n this.output.log(`Job ${styleText('green', response.jobId)} completed`)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Dataset copying failed: %s', message, error)\n return this.output.error(`Dataset copying failed: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async handleListMode(\n projectId: string,\n flags: {limit?: number; offset?: number},\n ): Promise<void> {\n copyDatasetDebug('Listing dataset copy jobs')\n\n try {\n const jobs = await listDatasetCopyJobs({\n limit: flags.limit,\n offset: flags.offset,\n projectId,\n })\n\n if (jobs.length === 0) {\n this.output.log(\"This project doesn't have any dataset copy jobs\")\n return\n }\n\n this.displayCopyJobsTable(jobs)\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n copyDatasetDebug('Failed to list dataset copy jobs: %s', message, error)\n return this.output.error(`Failed to list dataset copy jobs: ${message}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async subscribeToProgress(projectId: string, jobId: string): Promise<void> {\n const spin = spinner('').start()\n const hasCliExecutionContext = Boolean(getCliExecutionContext())\n\n return new Promise<void>((resolve, reject) => {\n const sigintHandler = () => {\n subscription.unsubscribe()\n spin.fail('Copy interrupted.')\n exit(130)\n }\n\n const subscription = followCopyJobProgress({jobId, projectId}).subscribe({\n complete: () => {\n if (!hasCliExecutionContext) process.off('SIGINT', sigintHandler)\n spin.succeed('Copy finished.')\n resolve()\n },\n error: (err) => {\n if (!hasCliExecutionContext) process.off('SIGINT', sigintHandler)\n spin.fail('Copy failed.')\n reject(err)\n },\n next: (event: CopyJobProgressEvent) => {\n if (typeof event.progress === 'number') {\n spin.text = `Copy in progress: ${event.progress}%`\n }\n },\n })\n\n if (!hasCliExecutionContext) process.once('SIGINT', sigintHandler)\n })\n }\n}\n"],"names":["styleText","Args","Flags","exit","exitCodes","subdebug","getCliExecutionContext","SanityCommand","spinner","Table","formatDistance","formatDistanceToNow","parseISO","validateDatasetName","promptForDataset","promptForDatasetName","promptForProject","copyDataset","followCopyJobProgress","listDatasetCopyJobs","listDatasets","formatCliErrorMessages","getProjectIdFlag","copyDatasetDebug","CopyDatasetCommand","args","source","string","description","required","target","examples","command","flags","semantics","attach","exclusive","detach","boolean","limit","integer","dependsOn","max","list","offset","hiddenAliases","run","parse","isUnattended","errors","push","length","output","error","USAGE_ERROR","projectId","getProjectId","fallback","requiredPermissions","grant","permission","handleListMode","handleAttachMode","handleCopyMode","displayCopyJobsTable","jobs","table","columns","alignment","name","title","job","createdAt","id","sourceDataset","state","targetDataset","updatedAt","withHistory","timeStarted","timeTaken","color","addRow","log","render","jobId","trim","RUNTIME_ERROR","subscribeToProgress","message","Error","String","skipHistory","Boolean","skipContentReleases","nameError","datasetsResponse","datasetNames","Set","map","ds","datasets","has","response","spin","start","hasCliExecutionContext","Promise","resolve","reject","sigintHandler","subscription","unsubscribe","fail","subscribe","complete","process","off","succeed","err","next","event","progress","text","once"],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Args, Flags } from '@oclif/core';
|
|
2
2
|
import { colorizeJson, exitCodes, getProjectCliClient, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
|
+
import { getCliExecutionContext } from '@sanity/cli-core/executionContext';
|
|
3
4
|
import { DOCUMENTS_API_VERSION } from '../../actions/documents/constants.js';
|
|
4
5
|
import { promptForProject } from '../../prompts/promptForProject.js';
|
|
5
6
|
import { getDatasetFlag, getProjectIdFlag } from '../../util/sharedFlags.js';
|
|
@@ -44,8 +45,7 @@ export class QueryDocumentCommand extends SanityCommand {
|
|
|
44
45
|
description: 'Send the query without any authorization token'
|
|
45
46
|
}),
|
|
46
47
|
'api-version': Flags.string({
|
|
47
|
-
description: `API version to use (defaults to ${DOCUMENTS_API_VERSION})
|
|
48
|
-
env: 'SANITY_CLI_QUERY_API_VERSION'
|
|
48
|
+
description: `API version to use (defaults to ${DOCUMENTS_API_VERSION})`
|
|
49
49
|
}),
|
|
50
50
|
pretty: Flags.boolean({
|
|
51
51
|
default: false,
|
|
@@ -78,8 +78,9 @@ export class QueryDocumentCommand extends SanityCommand {
|
|
|
78
78
|
});
|
|
79
79
|
}
|
|
80
80
|
const targetDataset = dataset || cliConfig.api?.dataset;
|
|
81
|
-
const
|
|
82
|
-
|
|
81
|
+
const configuredApiVersion = apiVersion ?? (getCliExecutionContext() ? undefined : process.env.SANITY_CLI_QUERY_API_VERSION);
|
|
82
|
+
const targetApiVersion = configuredApiVersion || DOCUMENTS_API_VERSION;
|
|
83
|
+
if (!configuredApiVersion) {
|
|
83
84
|
this.warn(`--api-version not specified, using \`${DOCUMENTS_API_VERSION}\``);
|
|
84
85
|
}
|
|
85
86
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/documents/query.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {\n colorizeJson,\n exitCodes,\n getProjectCliClient,\n SanityCommand,\n subdebug,\n} from '@sanity/cli-core'\n\nimport {DOCUMENTS_API_VERSION} from '../../actions/documents/constants.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst queryDocumentDebug = subdebug('documents:query')\n\nexport class QueryDocumentCommand extends SanityCommand<typeof QueryDocumentCommand> {\n static override args = {\n query: Args.string({\n description: 'GROQ query to run against the dataset',\n required: true,\n }),\n }\n\n static override description = 'Query for documents'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> \\'*[_type == \"movie\"][0..4]\\'',\n description: 'Fetch 5 documents of type \"movie\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"movie\"]|order(releaseDate asc)[0]{title}\\' --dataset staging',\n description: 'Fetch title of the oldest movie in the dataset named \"staging\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_id == \"header\"] { \"headerText\": pt::text(body) }\\' --api-version v2021-06-07',\n description: 'Use API version v2021-06-07 and do a query',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"post\"]\\' --project-id abc123 --dataset production',\n description: 'Query documents in a specific project and dataset',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({description: 'Project ID to query', semantics: 'override'}),\n ...getDatasetFlag({description: 'Dataset to query', semantics: 'override'}),\n anonymous: Flags.boolean({\n default: false,\n description: 'Send the query without any authorization token',\n }),\n 'api-version': Flags.string({\n description: `API version to use (defaults to ${DOCUMENTS_API_VERSION})`,\n
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/documents/query.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {\n colorizeJson,\n exitCodes,\n getProjectCliClient,\n SanityCommand,\n subdebug,\n} from '@sanity/cli-core'\nimport {getCliExecutionContext} from '@sanity/cli-core/executionContext'\n\nimport {DOCUMENTS_API_VERSION} from '../../actions/documents/constants.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst queryDocumentDebug = subdebug('documents:query')\n\nexport class QueryDocumentCommand extends SanityCommand<typeof QueryDocumentCommand> {\n static override args = {\n query: Args.string({\n description: 'GROQ query to run against the dataset',\n required: true,\n }),\n }\n\n static override description = 'Query for documents'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> \\'*[_type == \"movie\"][0..4]\\'',\n description: 'Fetch 5 documents of type \"movie\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"movie\"]|order(releaseDate asc)[0]{title}\\' --dataset staging',\n description: 'Fetch title of the oldest movie in the dataset named \"staging\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_id == \"header\"] { \"headerText\": pt::text(body) }\\' --api-version v2021-06-07',\n description: 'Use API version v2021-06-07 and do a query',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"post\"]\\' --project-id abc123 --dataset production',\n description: 'Query documents in a specific project and dataset',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({description: 'Project ID to query', semantics: 'override'}),\n ...getDatasetFlag({description: 'Dataset to query', semantics: 'override'}),\n anonymous: Flags.boolean({\n default: false,\n description: 'Send the query without any authorization token',\n }),\n 'api-version': Flags.string({\n description: `API version to use (defaults to ${DOCUMENTS_API_VERSION})`,\n }),\n pretty: Flags.boolean({\n default: false,\n description: 'Colorize JSON output',\n }),\n project: Flags.string({\n deprecated: {to: 'project-id'},\n description: 'Project ID to query',\n hidden: true,\n }),\n }\n\n static override hiddenAliases: string[] = ['document:query']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(QueryDocumentCommand)\n const {query} = args\n const {anonymous, 'api-version': apiVersion, dataset, pretty} = flags\n\n const cliConfig = await this.tryGetCliConfig()\n\n const projectId = await this.getProjectId({\n deprecatedFlagName: 'project',\n fallback: () => promptForProject({}),\n })\n\n const requireUser = !anonymous\n\n if (!cliConfig.api?.dataset && !dataset) {\n this.error(\n 'Dataset is required. Pass it with `--dataset <name>` or configure it in `sanity.cli.ts`.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const targetDataset = dataset || cliConfig.api?.dataset\n const configuredApiVersion =\n apiVersion ??\n (getCliExecutionContext() ? undefined : process.env.SANITY_CLI_QUERY_API_VERSION)\n const targetApiVersion = configuredApiVersion || DOCUMENTS_API_VERSION\n\n if (!configuredApiVersion) {\n this.warn(`--api-version not specified, using \\`${DOCUMENTS_API_VERSION}\\``)\n }\n\n try {\n const projectClient = await getProjectCliClient({\n apiVersion: targetApiVersion,\n dataset: targetDataset,\n projectId,\n requireUser,\n })\n\n const docs = await projectClient.fetch(query)\n\n if (!docs) {\n this.error('Query returned no results', {exit: exitCodes.RUNTIME_ERROR})\n }\n\n // Output the query results\n if (pretty) {\n this.log(colorizeJson(docs))\n } else {\n this.log(JSON.stringify(docs, null, 2))\n }\n } catch (error) {\n const err = error as Error\n\n queryDocumentDebug(`Error running query: ${query}`, err)\n\n // Provide more context in error messages\n const errorMsg = err.message.toLowerCase().includes('syntax')\n ? `Invalid GROQ query syntax: ${err.message}`\n : `Failed to run query: ${err.message}`\n\n this.error(`${errorMsg}\\nQuery: ${query}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n}\n"],"names":["Args","Flags","colorizeJson","exitCodes","getProjectCliClient","SanityCommand","subdebug","getCliExecutionContext","DOCUMENTS_API_VERSION","promptForProject","getDatasetFlag","getProjectIdFlag","queryDocumentDebug","QueryDocumentCommand","args","query","string","description","required","examples","command","flags","semantics","anonymous","boolean","default","pretty","project","deprecated","to","hidden","hiddenAliases","run","parse","apiVersion","dataset","cliConfig","tryGetCliConfig","projectId","getProjectId","deprecatedFlagName","fallback","requireUser","api","error","exit","USAGE_ERROR","targetDataset","configuredApiVersion","undefined","process","env","SANITY_CLI_QUERY_API_VERSION","targetApiVersion","warn","projectClient","docs","fetch","RUNTIME_ERROR","log","JSON","stringify","err","errorMsg","message","toLowerCase","includes"],"mappings":"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"}
|
|
@@ -44,7 +44,7 @@ export class ListMigrationCommand extends SanityCommand {
|
|
|
44
44
|
title: definedMigration.migration.title
|
|
45
45
|
});
|
|
46
46
|
}
|
|
47
|
-
table.
|
|
47
|
+
this.log(table.render());
|
|
48
48
|
this.log('\nRun `sanity migration run <ID>` to run a migration');
|
|
49
49
|
listMigrationDebug(`Successfully listed ${migrations.length} migrations`);
|
|
50
50
|
} catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/migrations/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {Table} from 'console-table-printer'\n\nimport {resolveMigrations} from '../../actions/migration/resolveMigrations.js'\n\nconst listMigrationDebug = subdebug('migration:list')\n\nexport class ListMigrationCommand extends SanityCommand<typeof ListMigrationCommand> {\n static override description = 'List available migrations'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all available migrations in the project',\n },\n ]\n\n static override hiddenAliases = ['migration:list']\n\n public async run(): Promise<void> {\n const {directory: workDir} = await this.getProjectRoot()\n\n try {\n const migrations = await resolveMigrations(workDir)\n\n if (migrations.length === 0) {\n this.log('No migrations found in migrations folder of the project')\n this.log(\n `\\nRun ${styleText('green', '`sanity migration create <NAME>`')} to create a new migration`,\n )\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'title', title: 'Title'},\n ],\n title: `Found ${migrations.length} migrations in project`,\n })\n\n for (const definedMigration of migrations) {\n table.addRow({id: definedMigration.id, title: definedMigration.migration.title})\n }\n table.
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/migrations/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {Table} from 'console-table-printer'\n\nimport {resolveMigrations} from '../../actions/migration/resolveMigrations.js'\n\nconst listMigrationDebug = subdebug('migration:list')\n\nexport class ListMigrationCommand extends SanityCommand<typeof ListMigrationCommand> {\n static override description = 'List available migrations'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all available migrations in the project',\n },\n ]\n\n static override hiddenAliases = ['migration:list']\n\n public async run(): Promise<void> {\n const {directory: workDir} = await this.getProjectRoot()\n\n try {\n const migrations = await resolveMigrations(workDir)\n\n if (migrations.length === 0) {\n this.log('No migrations found in migrations folder of the project')\n this.log(\n `\\nRun ${styleText('green', '`sanity migration create <NAME>`')} to create a new migration`,\n )\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'title', title: 'Title'},\n ],\n title: `Found ${migrations.length} migrations in project`,\n })\n\n for (const definedMigration of migrations) {\n table.addRow({id: definedMigration.id, title: definedMigration.migration.title})\n }\n this.log(table.render())\n this.log('\\nRun `sanity migration run <ID>` to run a migration')\n listMigrationDebug(`Successfully listed ${migrations.length} migrations`)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n this.log('No migrations folder found in the project')\n this.log(\n `\\nRun ${styleText('green', '`sanity migration create <NAME>`')} to create a new migration`,\n )\n return\n }\n listMigrationDebug('Failed to list migrations:', error)\n this.error(\n `List migrations failed: ${error instanceof Error ? error.message : String(error)}`,\n {\n exit: exitCodes.RUNTIME_ERROR,\n },\n )\n }\n }\n}\n"],"names":["styleText","exitCodes","SanityCommand","subdebug","Table","resolveMigrations","listMigrationDebug","ListMigrationCommand","description","examples","command","hiddenAliases","run","directory","workDir","getProjectRoot","migrations","length","log","table","columns","alignment","name","title","definedMigration","addRow","id","migration","render","error","code","Error","message","String","exit","RUNTIME_ERROR"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,KAAK,QAAO,wBAAuB;AAE3C,SAAQC,iBAAiB,QAAO,+CAA8C;AAE9E,MAAMC,qBAAqBH,SAAS;AAEpC,OAAO,MAAMI,6BAA6BL;IACxC,OAAgBM,cAAc,4BAA2B;IAEzD,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,gBAAgB;QAAC;KAAiB,CAAA;IAElD,MAAaC,MAAqB;QAChC,MAAM,EAACC,WAAWC,OAAO,EAAC,GAAG,MAAM,IAAI,CAACC,cAAc;QAEtD,IAAI;YACF,MAAMC,aAAa,MAAMX,kBAAkBS;YAE3C,IAAIE,WAAWC,MAAM,KAAK,GAAG;gBAC3B,IAAI,CAACC,GAAG,CAAC;gBACT,IAAI,CAACA,GAAG,CACN,CAAC,MAAM,EAAElB,UAAU,SAAS,oCAAoC,0BAA0B,CAAC;gBAE7F;YACF;YAEA,MAAMmB,QAAQ,IAAIf,MAAM;gBACtBgB,SAAS;oBACP;wBAACC,WAAW;wBAAQC,MAAM;wBAAMC,OAAO;oBAAI;oBAC3C;wBAACF,WAAW;wBAAQC,MAAM;wBAASC,OAAO;oBAAO;iBAClD;gBACDA,OAAO,CAAC,MAAM,EAAEP,WAAWC,MAAM,CAAC,sBAAsB,CAAC;YAC3D;YAEA,KAAK,MAAMO,oBAAoBR,WAAY;gBACzCG,MAAMM,MAAM,CAAC;oBAACC,IAAIF,iBAAiBE,EAAE;oBAAEH,OAAOC,iBAAiBG,SAAS,CAACJ,KAAK;gBAAA;YAChF;YACA,IAAI,CAACL,GAAG,CAACC,MAAMS,MAAM;YACrB,IAAI,CAACV,GAAG,CAAC;YACTZ,mBAAmB,CAAC,oBAAoB,EAAEU,WAAWC,MAAM,CAAC,WAAW,CAAC;QAC1E,EAAE,OAAOY,OAAO;YACd,IAAI,AAACA,MAAgCC,IAAI,KAAK,UAAU;gBACtD,IAAI,CAACZ,GAAG,CAAC;gBACT,IAAI,CAACA,GAAG,CACN,CAAC,MAAM,EAAElB,UAAU,SAAS,oCAAoC,0BAA0B,CAAC;gBAE7F;YACF;YACAM,mBAAmB,8BAA8BuB;YACjD,IAAI,CAACA,KAAK,CACR,CAAC,wBAAwB,EAAEA,iBAAiBE,QAAQF,MAAMG,OAAO,GAAGC,OAAOJ,QAAQ,EACnF;gBACEK,MAAMjC,UAAUkC,aAAa;YAC/B;QAEJ;IACF;AACF"}
|
|
@@ -116,7 +116,7 @@ export class RunMigrationCommand extends SanityCommand {
|
|
|
116
116
|
title: definedMigration.migration.title
|
|
117
117
|
});
|
|
118
118
|
}
|
|
119
|
-
table.
|
|
119
|
+
this.log(table.render());
|
|
120
120
|
this.log('\nRun `sanity migration run <ID>` to run a migration');
|
|
121
121
|
this.exit(exitCodes.RUNTIME_ERROR);
|
|
122
122
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/migrations/run.ts"],"sourcesContent":["import path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\nimport {\n type APIConfig,\n DEFAULT_MUTATION_CONCURRENCY,\n dryRun,\n MAX_MUTATION_CONCURRENCY,\n type Migration,\n type MigrationProgress,\n run,\n} from '@sanity/migrate'\nimport {Table} from 'console-table-printer'\n\nimport {DEFAULT_API_VERSION, MIGRATIONS_DIRECTORY} from '../../actions/migration/constants.js'\nimport {ensureApiVersionFormat} from '../../actions/migration/ensureApiVersionFormat.js'\nimport {prettyFormat} from '../../actions/migration/prettyMutationFormatter.js'\nimport {resolveMigrations} from '../../actions/migration/resolveMigrations.js'\nimport {\n isLoadableMigrationScript,\n resolveMigrationScript,\n} from '../../actions/migration/resolveMigrationScript.js'\n\nconst runMigrationDebug = subdebug('migration:run')\n\nexport type RunMigrationFlags = RunMigrationCommand['flags']\n\nexport class RunMigrationCommand extends SanityCommand<typeof RunMigrationCommand> {\n static override args = {\n id: Args.string({\n description: 'ID',\n required: false,\n }),\n }\n\n static override description = 'Run a migration against a dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> <id>',\n description: 'dry run the migration',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> <id> --no-dry-run --project xyz --dataset staging',\n description: 'execute the migration against a dataset',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> <id> --from-export=production.tar.gz --no-dry-run --project xyz --dataset staging',\n description: 'execute the migration using a dataset export as the source',\n },\n ]\n\n static override flags = {\n 'api-version': Flags.string({\n description: `API version to use when migrating. Defaults to ${DEFAULT_API_VERSION}.`,\n }),\n concurrency: Flags.integer({\n default: DEFAULT_MUTATION_CONCURRENCY,\n description: `How many mutation requests to run in parallel. Must be between 1 and ${MAX_MUTATION_CONCURRENCY}. Default: ${DEFAULT_MUTATION_CONCURRENCY}.`,\n }),\n confirm: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Prompt for confirmation before running the migration (default: true). Use --no-confirm to skip.',\n }),\n dataset: Flags.string({\n description:\n 'Dataset to migrate. Defaults to the dataset configured in your Sanity CLI config.',\n }),\n 'dry-run': Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'By default the migration runs in dry mode. Use --no-dry-run to migrate dataset.',\n }),\n 'from-export': Flags.string({\n description:\n 'Use a local dataset export as source for migration instead of calling the Sanity API. Note: this is only supported for dry runs.',\n }),\n progress: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Display progress during migration (default: true). Use --no-progress to hide output.',\n }),\n project: Flags.string({\n description:\n 'Project ID of the dataset to migrate. Defaults to the projectId configured in your Sanity CLI config.',\n }),\n }\n\n static override hiddenAliases = ['migration:run']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(RunMigrationCommand)\n const {directory: workDir} = await this.getProjectRoot()\n const id = args.id\n const migrationsDirectoryPath = path.join(workDir, MIGRATIONS_DIRECTORY)\n\n // Listing migrations (no id given) only needs a project root, mirroring\n // `sanity migrations list` — it must not require api.projectId/dataset.\n if (!id) {\n this.warn(styleText('red', 'Error: Migration ID must be provided'))\n\n let migrations: Awaited<ReturnType<typeof resolveMigrations>> = []\n try {\n migrations = await resolveMigrations(workDir)\n } catch (error) {\n // A missing migrations folder is expected for a fresh project; surface\n // any other failure (e.g. a syntax error in a migration file).\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n this.error(\n `Failed to list migrations: ${error instanceof Error ? error.message : String(error)}`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n }\n\n if (migrations.length === 0) {\n this.log('\\nNo migrations found in the project')\n this.log(\n `Run ${styleText('green', '`sanity migration create <NAME>`')} to create a new migration`,\n )\n this.exit(exitCodes.RUNTIME_ERROR)\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'title', title: 'Title'},\n ],\n title: `Migrations found in project`,\n })\n\n for (const definedMigration of migrations) {\n table.addRow({id: definedMigration.id, title: definedMigration.migration.title})\n }\n table.printTable()\n this.log('\\nRun `sanity migration run <ID>` to run a migration')\n\n this.exit(exitCodes.RUNTIME_ERROR)\n }\n\n const cliConfig = await this.getCliConfig()\n const projectId = await this.getProjectId({deprecatedFlagName: 'project'})\n const datasetFromConfig = cliConfig.api?.dataset\n\n const fromExport = flags['from-export']\n const dry = flags['dry-run']\n const dataset = flags.dataset\n const project = flags.project\n const apiVersion = ensureApiVersionFormat(flags['api-version'] ?? DEFAULT_API_VERSION)\n\n if ((dataset && !project) || (project && !dataset)) {\n this.error('If either --dataset or --project is provided, both must be provided', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (!project && !projectId) {\n this.error(\n 'sanity.cli.js does not contain a project identifier (\"api.projectId\") and no --project option was provided.',\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n if (!dataset && !datasetFromConfig) {\n this.error(\n 'sanity.cli.js does not contain a dataset identifier (\"api.dataset\") and no --dataset option was provided.',\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n const candidates = await resolveMigrationScript(workDir, id)\n const resolvedScripts = candidates.filter((candidate) => isLoadableMigrationScript(candidate))\n\n if (resolvedScripts.length > 1) {\n // todo: consider prompt user about which one to run? note: it's likely a mistake if multiple files resolve to the same name\n this.error(\n `Found multiple migrations for \"${id}\" in ${styleText('cyan', migrationsDirectoryPath)}: \\n - ${candidates\n .map((candidate) => path.relative(migrationsDirectoryPath, candidate.absolutePath))\n .join('\\n - ')}`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n const script = resolvedScripts[0]\n if (!script) {\n this.error(\n `No migration found for \"${id}\" in ${styleText('cyan', migrationsDirectoryPath)}. Make sure that the migration file exists and exports a valid migration as its default export.\\n\n Tried the following files:\\n - ${candidates\n .map((candidate) => path.relative(migrationsDirectoryPath, candidate.absolutePath))\n .join('\\n - ')}`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n const mod = script.mod\n if ('up' in mod || 'down' in mod) {\n // todo: consider adding support for up/down as separate named exports\n // For now, make sure we reserve the names for future use\n this.error(\n 'Named \"up\"/\"down\" migration exports are not supported at this time, please export your migration as the default export',\n {\n exit: exitCodes.RUNTIME_ERROR,\n },\n )\n }\n\n const migration: Migration = mod.default\n\n if (fromExport && !dry) {\n this.error('Can only dry run migrations from a dataset export file', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const concurrency = flags.concurrency\n if (concurrency !== undefined) {\n if (concurrency > MAX_MUTATION_CONCURRENCY) {\n this.error(`Concurrency exceeds the maximum allowed value of ${MAX_MUTATION_CONCURRENCY}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (concurrency < 1) {\n this.error(`Concurrency must be a positive number, got ${concurrency}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n const projectClient = await getProjectCliClient({\n apiVersion,\n projectId: (project ?? projectId)!,\n requireUser: true,\n })\n const projectConfig = projectClient.config()\n\n const apiConfig: APIConfig = {\n apiHost: projectConfig.apiHost,\n apiVersion,\n dataset: (dataset ?? datasetFromConfig)!,\n projectId: (project ?? projectId)!,\n token: projectConfig.token!,\n } as const\n if (dry) {\n await this.dryRunHandler(id, migration, apiConfig, fromExport)\n return\n }\n\n this.log(\n `\\n${styleText(['yellow', 'bold'], 'Note: During migrations, your webhooks stay active.')}`,\n )\n this.log(\n `To adjust them, launch the management interface with ${styleText('cyan', 'sanity manage')}, navigate to the API settings, and toggle the webhooks before and after the migration as needed.\\n`,\n )\n\n if (flags.confirm) {\n await this.promptConfirmMigrate(apiConfig)\n }\n\n const spin = spinner(`Running migration \"${id}\"`).start()\n try {\n await run(\n {\n api: apiConfig,\n concurrency,\n onProgress: this.createProgress(spin, flags, id, dry, apiConfig, migration),\n },\n migration,\n )\n } finally {\n spin.stop()\n }\n }\n\n private createProgress(\n progressSpinner: ReturnType<typeof spinner>,\n flags: RunMigrationFlags,\n id: string,\n dry: boolean,\n apiConfig: APIConfig,\n migration: Migration,\n ) {\n return function onProgress(progress: MigrationProgress) {\n if (!flags.progress) {\n progressSpinner.stop()\n return\n }\n if (progress.done) {\n progressSpinner.text = `Migration \"${id}\" completed.\n\n Project id: ${styleText('bold', apiConfig.projectId)}\n Dataset: ${styleText('bold', apiConfig.dataset)}\n\n ${progress.documents} documents processed.\n ${progress.mutations} mutations generated.\n ${styleText('green', String(progress.completedTransactions.length))} transactions committed.`\n progressSpinner.stopAndPersist({symbol: styleText('green', '✔')})\n return\n }\n\n for (const transaction of [null, ...progress.currentTransactions]) {\n progressSpinner.text = `Running migration \"${id}\" ${dry ? 'in dry mode...' : '...'}\n\n Project id: ${styleText('bold', apiConfig.projectId)}\n Dataset: ${styleText('bold', apiConfig.dataset)}\n Document type: ${styleText('bold', migration.documentTypes?.join(',') ?? '')}\n\n ${progress.documents} documents processed…\n ${progress.mutations} mutations generated…\n ${styleText('blue', String(progress.pending))} requests pending…\n ${styleText('green', String(progress.completedTransactions.length))} transactions committed.\n\n ${\n transaction && !progress.done\n ? `» ${prettyFormat({indentSize: 2, migration, subject: transaction})}`\n : ''\n }`\n }\n }\n }\n\n private async dryRunHandler(\n id: string,\n migration: Migration,\n apiConfig: APIConfig,\n fromExport: string | undefined,\n ) {\n this.log(`Running migration \"${id}\" in dry mode`)\n\n if (fromExport) {\n this.log(`Using export ${styleText('cyan', fromExport)}`)\n }\n\n this.log()\n this.log(`Project id: ${styleText('bold', apiConfig.projectId)}`)\n this.log(`Dataset: ${styleText('bold', apiConfig.dataset)}`)\n\n for await (const mutation of dryRun({api: apiConfig, exportPath: fromExport}, migration)) {\n if (!mutation) continue\n this.log()\n this.log(\n prettyFormat({\n migration,\n subject: mutation,\n }),\n )\n }\n }\n\n private async promptConfirmMigrate(apiConfig: APIConfig) {\n const response = await confirm({\n message: `This migration will run on the ${styleText(\n ['yellow', 'bold'],\n apiConfig.dataset,\n )} dataset in ${styleText(['yellow', 'bold'], apiConfig.projectId)} project. Are you sure?`,\n })\n\n if (!response) {\n runMigrationDebug('User aborted migration')\n this.exit(exitCodes.RUNTIME_ERROR)\n }\n }\n}\n"],"names":["path","styleText","Args","Flags","exitCodes","getProjectCliClient","SanityCommand","subdebug","confirm","spinner","DEFAULT_MUTATION_CONCURRENCY","dryRun","MAX_MUTATION_CONCURRENCY","run","Table","DEFAULT_API_VERSION","MIGRATIONS_DIRECTORY","ensureApiVersionFormat","prettyFormat","resolveMigrations","isLoadableMigrationScript","resolveMigrationScript","runMigrationDebug","RunMigrationCommand","args","id","string","description","required","examples","command","flags","concurrency","integer","default","boolean","allowNo","dataset","progress","project","hiddenAliases","parse","directory","workDir","getProjectRoot","migrationsDirectoryPath","join","warn","migrations","error","code","Error","message","String","exit","RUNTIME_ERROR","length","log","table","columns","alignment","name","title","definedMigration","addRow","migration","printTable","cliConfig","getCliConfig","projectId","getProjectId","deprecatedFlagName","datasetFromConfig","api","fromExport","dry","apiVersion","candidates","resolvedScripts","filter","candidate","map","relative","absolutePath","script","mod","undefined","projectClient","requireUser","projectConfig","config","apiConfig","apiHost","token","dryRunHandler","promptConfirmMigrate","spin","start","onProgress","createProgress","stop","progressSpinner","done","text","documents","mutations","completedTransactions","stopAndPersist","symbol","transaction","currentTransactions","documentTypes","pending","indentSize","subject","mutation","exportPath","response"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/migrations/run.ts"],"sourcesContent":["import path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {confirm, spinner} from '@sanity/cli-core/ux'\nimport {\n type APIConfig,\n DEFAULT_MUTATION_CONCURRENCY,\n dryRun,\n MAX_MUTATION_CONCURRENCY,\n type Migration,\n type MigrationProgress,\n run,\n} from '@sanity/migrate'\nimport {Table} from 'console-table-printer'\n\nimport {DEFAULT_API_VERSION, MIGRATIONS_DIRECTORY} from '../../actions/migration/constants.js'\nimport {ensureApiVersionFormat} from '../../actions/migration/ensureApiVersionFormat.js'\nimport {prettyFormat} from '../../actions/migration/prettyMutationFormatter.js'\nimport {resolveMigrations} from '../../actions/migration/resolveMigrations.js'\nimport {\n isLoadableMigrationScript,\n resolveMigrationScript,\n} from '../../actions/migration/resolveMigrationScript.js'\n\nconst runMigrationDebug = subdebug('migration:run')\n\nexport type RunMigrationFlags = RunMigrationCommand['flags']\n\nexport class RunMigrationCommand extends SanityCommand<typeof RunMigrationCommand> {\n static override args = {\n id: Args.string({\n description: 'ID',\n required: false,\n }),\n }\n\n static override description = 'Run a migration against a dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> <id>',\n description: 'dry run the migration',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> <id> --no-dry-run --project xyz --dataset staging',\n description: 'execute the migration against a dataset',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> <id> --from-export=production.tar.gz --no-dry-run --project xyz --dataset staging',\n description: 'execute the migration using a dataset export as the source',\n },\n ]\n\n static override flags = {\n 'api-version': Flags.string({\n description: `API version to use when migrating. Defaults to ${DEFAULT_API_VERSION}.`,\n }),\n concurrency: Flags.integer({\n default: DEFAULT_MUTATION_CONCURRENCY,\n description: `How many mutation requests to run in parallel. Must be between 1 and ${MAX_MUTATION_CONCURRENCY}. Default: ${DEFAULT_MUTATION_CONCURRENCY}.`,\n }),\n confirm: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Prompt for confirmation before running the migration (default: true). Use --no-confirm to skip.',\n }),\n dataset: Flags.string({\n description:\n 'Dataset to migrate. Defaults to the dataset configured in your Sanity CLI config.',\n }),\n 'dry-run': Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'By default the migration runs in dry mode. Use --no-dry-run to migrate dataset.',\n }),\n 'from-export': Flags.string({\n description:\n 'Use a local dataset export as source for migration instead of calling the Sanity API. Note: this is only supported for dry runs.',\n }),\n progress: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Display progress during migration (default: true). Use --no-progress to hide output.',\n }),\n project: Flags.string({\n description:\n 'Project ID of the dataset to migrate. Defaults to the projectId configured in your Sanity CLI config.',\n }),\n }\n\n static override hiddenAliases = ['migration:run']\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(RunMigrationCommand)\n const {directory: workDir} = await this.getProjectRoot()\n const id = args.id\n const migrationsDirectoryPath = path.join(workDir, MIGRATIONS_DIRECTORY)\n\n // Listing migrations (no id given) only needs a project root, mirroring\n // `sanity migrations list` — it must not require api.projectId/dataset.\n if (!id) {\n this.warn(styleText('red', 'Error: Migration ID must be provided'))\n\n let migrations: Awaited<ReturnType<typeof resolveMigrations>> = []\n try {\n migrations = await resolveMigrations(workDir)\n } catch (error) {\n // A missing migrations folder is expected for a fresh project; surface\n // any other failure (e.g. a syntax error in a migration file).\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {\n this.error(\n `Failed to list migrations: ${error instanceof Error ? error.message : String(error)}`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n }\n\n if (migrations.length === 0) {\n this.log('\\nNo migrations found in the project')\n this.log(\n `Run ${styleText('green', '`sanity migration create <NAME>`')} to create a new migration`,\n )\n this.exit(exitCodes.RUNTIME_ERROR)\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'id', title: 'ID'},\n {alignment: 'left', name: 'title', title: 'Title'},\n ],\n title: `Migrations found in project`,\n })\n\n for (const definedMigration of migrations) {\n table.addRow({id: definedMigration.id, title: definedMigration.migration.title})\n }\n this.log(table.render())\n this.log('\\nRun `sanity migration run <ID>` to run a migration')\n\n this.exit(exitCodes.RUNTIME_ERROR)\n }\n\n const cliConfig = await this.getCliConfig()\n const projectId = await this.getProjectId({deprecatedFlagName: 'project'})\n const datasetFromConfig = cliConfig.api?.dataset\n\n const fromExport = flags['from-export']\n const dry = flags['dry-run']\n const dataset = flags.dataset\n const project = flags.project\n const apiVersion = ensureApiVersionFormat(flags['api-version'] ?? DEFAULT_API_VERSION)\n\n if ((dataset && !project) || (project && !dataset)) {\n this.error('If either --dataset or --project is provided, both must be provided', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (!project && !projectId) {\n this.error(\n 'sanity.cli.js does not contain a project identifier (\"api.projectId\") and no --project option was provided.',\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n if (!dataset && !datasetFromConfig) {\n this.error(\n 'sanity.cli.js does not contain a dataset identifier (\"api.dataset\") and no --dataset option was provided.',\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n const candidates = await resolveMigrationScript(workDir, id)\n const resolvedScripts = candidates.filter((candidate) => isLoadableMigrationScript(candidate))\n\n if (resolvedScripts.length > 1) {\n // todo: consider prompt user about which one to run? note: it's likely a mistake if multiple files resolve to the same name\n this.error(\n `Found multiple migrations for \"${id}\" in ${styleText('cyan', migrationsDirectoryPath)}: \\n - ${candidates\n .map((candidate) => path.relative(migrationsDirectoryPath, candidate.absolutePath))\n .join('\\n - ')}`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n const script = resolvedScripts[0]\n if (!script) {\n this.error(\n `No migration found for \"${id}\" in ${styleText('cyan', migrationsDirectoryPath)}. Make sure that the migration file exists and exports a valid migration as its default export.\\n\n Tried the following files:\\n - ${candidates\n .map((candidate) => path.relative(migrationsDirectoryPath, candidate.absolutePath))\n .join('\\n - ')}`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n const mod = script.mod\n if ('up' in mod || 'down' in mod) {\n // todo: consider adding support for up/down as separate named exports\n // For now, make sure we reserve the names for future use\n this.error(\n 'Named \"up\"/\"down\" migration exports are not supported at this time, please export your migration as the default export',\n {\n exit: exitCodes.RUNTIME_ERROR,\n },\n )\n }\n\n const migration: Migration = mod.default\n\n if (fromExport && !dry) {\n this.error('Can only dry run migrations from a dataset export file', {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const concurrency = flags.concurrency\n if (concurrency !== undefined) {\n if (concurrency > MAX_MUTATION_CONCURRENCY) {\n this.error(`Concurrency exceeds the maximum allowed value of ${MAX_MUTATION_CONCURRENCY}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (concurrency < 1) {\n this.error(`Concurrency must be a positive number, got ${concurrency}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n const projectClient = await getProjectCliClient({\n apiVersion,\n projectId: (project ?? projectId)!,\n requireUser: true,\n })\n const projectConfig = projectClient.config()\n\n const apiConfig: APIConfig = {\n apiHost: projectConfig.apiHost,\n apiVersion,\n dataset: (dataset ?? datasetFromConfig)!,\n projectId: (project ?? projectId)!,\n token: projectConfig.token!,\n } as const\n if (dry) {\n await this.dryRunHandler(id, migration, apiConfig, fromExport)\n return\n }\n\n this.log(\n `\\n${styleText(['yellow', 'bold'], 'Note: During migrations, your webhooks stay active.')}`,\n )\n this.log(\n `To adjust them, launch the management interface with ${styleText('cyan', 'sanity manage')}, navigate to the API settings, and toggle the webhooks before and after the migration as needed.\\n`,\n )\n\n if (flags.confirm) {\n await this.promptConfirmMigrate(apiConfig)\n }\n\n const spin = spinner(`Running migration \"${id}\"`).start()\n try {\n await run(\n {\n api: apiConfig,\n concurrency,\n onProgress: this.createProgress(spin, flags, id, dry, apiConfig, migration),\n },\n migration,\n )\n } finally {\n spin.stop()\n }\n }\n\n private createProgress(\n progressSpinner: ReturnType<typeof spinner>,\n flags: RunMigrationFlags,\n id: string,\n dry: boolean,\n apiConfig: APIConfig,\n migration: Migration,\n ) {\n return function onProgress(progress: MigrationProgress) {\n if (!flags.progress) {\n progressSpinner.stop()\n return\n }\n if (progress.done) {\n progressSpinner.text = `Migration \"${id}\" completed.\n\n Project id: ${styleText('bold', apiConfig.projectId)}\n Dataset: ${styleText('bold', apiConfig.dataset)}\n\n ${progress.documents} documents processed.\n ${progress.mutations} mutations generated.\n ${styleText('green', String(progress.completedTransactions.length))} transactions committed.`\n progressSpinner.stopAndPersist({symbol: styleText('green', '✔')})\n return\n }\n\n for (const transaction of [null, ...progress.currentTransactions]) {\n progressSpinner.text = `Running migration \"${id}\" ${dry ? 'in dry mode...' : '...'}\n\n Project id: ${styleText('bold', apiConfig.projectId)}\n Dataset: ${styleText('bold', apiConfig.dataset)}\n Document type: ${styleText('bold', migration.documentTypes?.join(',') ?? '')}\n\n ${progress.documents} documents processed…\n ${progress.mutations} mutations generated…\n ${styleText('blue', String(progress.pending))} requests pending…\n ${styleText('green', String(progress.completedTransactions.length))} transactions committed.\n\n ${\n transaction && !progress.done\n ? `» ${prettyFormat({indentSize: 2, migration, subject: transaction})}`\n : ''\n }`\n }\n }\n }\n\n private async dryRunHandler(\n id: string,\n migration: Migration,\n apiConfig: APIConfig,\n fromExport: string | undefined,\n ) {\n this.log(`Running migration \"${id}\" in dry mode`)\n\n if (fromExport) {\n this.log(`Using export ${styleText('cyan', fromExport)}`)\n }\n\n this.log()\n this.log(`Project id: ${styleText('bold', apiConfig.projectId)}`)\n this.log(`Dataset: ${styleText('bold', apiConfig.dataset)}`)\n\n for await (const mutation of dryRun({api: apiConfig, exportPath: fromExport}, migration)) {\n if (!mutation) continue\n this.log()\n this.log(\n prettyFormat({\n migration,\n subject: mutation,\n }),\n )\n }\n }\n\n private async promptConfirmMigrate(apiConfig: APIConfig) {\n const response = await confirm({\n message: `This migration will run on the ${styleText(\n ['yellow', 'bold'],\n apiConfig.dataset,\n )} dataset in ${styleText(['yellow', 'bold'], apiConfig.projectId)} project. Are you sure?`,\n })\n\n if (!response) {\n runMigrationDebug('User aborted migration')\n this.exit(exitCodes.RUNTIME_ERROR)\n }\n }\n}\n"],"names":["path","styleText","Args","Flags","exitCodes","getProjectCliClient","SanityCommand","subdebug","confirm","spinner","DEFAULT_MUTATION_CONCURRENCY","dryRun","MAX_MUTATION_CONCURRENCY","run","Table","DEFAULT_API_VERSION","MIGRATIONS_DIRECTORY","ensureApiVersionFormat","prettyFormat","resolveMigrations","isLoadableMigrationScript","resolveMigrationScript","runMigrationDebug","RunMigrationCommand","args","id","string","description","required","examples","command","flags","concurrency","integer","default","boolean","allowNo","dataset","progress","project","hiddenAliases","parse","directory","workDir","getProjectRoot","migrationsDirectoryPath","join","warn","migrations","error","code","Error","message","String","exit","RUNTIME_ERROR","length","log","table","columns","alignment","name","title","definedMigration","addRow","migration","render","cliConfig","getCliConfig","projectId","getProjectId","deprecatedFlagName","datasetFromConfig","api","fromExport","dry","apiVersion","candidates","resolvedScripts","filter","candidate","map","relative","absolutePath","script","mod","undefined","projectClient","requireUser","projectConfig","config","apiConfig","apiHost","token","dryRunHandler","promptConfirmMigrate","spin","start","onProgress","createProgress","stop","progressSpinner","done","text","documents","mutations","completedTransactions","stopAndPersist","symbol","transaction","currentTransactions","documentTypes","pending","indentSize","subject","mutation","exportPath","response"],"mappings":"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"}
|