@sanity/cli 6.0.0-alpha.18 → 6.0.0-alpha.19

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 (127) hide show
  1. package/dist/actions/build/getViteConfig.js +47 -4
  2. package/dist/actions/build/getViteConfig.js.map +1 -1
  3. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +1 -0
  4. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -1
  5. package/dist/actions/build/writeSanityRuntime.js +4 -3
  6. package/dist/actions/build/writeSanityRuntime.js.map +1 -1
  7. package/dist/actions/dev/getDashboardAppUrl.js +48 -0
  8. package/dist/actions/dev/getDashboardAppUrl.js.map +1 -0
  9. package/dist/actions/dev/getDevServerConfig.js +2 -1
  10. package/dist/actions/dev/getDevServerConfig.js.map +1 -1
  11. package/dist/actions/dev/startAppDevServer.js +3 -3
  12. package/dist/actions/dev/startAppDevServer.js.map +1 -1
  13. package/dist/actions/dev/startStudioDevServer.js +5 -10
  14. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  15. package/dist/actions/schema/extractSchemaWatcher.js +8 -6
  16. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
  17. package/dist/actions/schema/matchSchemaPattern.js +22 -0
  18. package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
  19. package/dist/actions/schema/runSchemaExtraction.js.map +1 -1
  20. package/dist/commands/backup/disable.js +0 -6
  21. package/dist/commands/backup/disable.js.map +1 -1
  22. package/dist/commands/backup/download.js +0 -6
  23. package/dist/commands/backup/download.js.map +1 -1
  24. package/dist/commands/backup/enable.js +0 -6
  25. package/dist/commands/backup/enable.js.map +1 -1
  26. package/dist/commands/backup/list.js +0 -6
  27. package/dist/commands/backup/list.js.map +1 -1
  28. package/dist/commands/cors/add.js +0 -6
  29. package/dist/commands/cors/add.js.map +1 -1
  30. package/dist/commands/cors/delete.js +0 -6
  31. package/dist/commands/cors/delete.js.map +1 -1
  32. package/dist/commands/cors/list.js +0 -6
  33. package/dist/commands/cors/list.js.map +1 -1
  34. package/dist/commands/dataset/alias/create.js +23 -7
  35. package/dist/commands/dataset/alias/create.js.map +1 -1
  36. package/dist/commands/dataset/alias/delete.js +17 -7
  37. package/dist/commands/dataset/alias/delete.js.map +1 -1
  38. package/dist/commands/dataset/alias/link.js +17 -7
  39. package/dist/commands/dataset/alias/link.js.map +1 -1
  40. package/dist/commands/dataset/alias/unlink.js +17 -7
  41. package/dist/commands/dataset/alias/unlink.js.map +1 -1
  42. package/dist/commands/dataset/copy.js +39 -29
  43. package/dist/commands/dataset/copy.js.map +1 -1
  44. package/dist/commands/dataset/create.js +17 -7
  45. package/dist/commands/dataset/create.js.map +1 -1
  46. package/dist/commands/dataset/delete.js +13 -7
  47. package/dist/commands/dataset/delete.js.map +1 -1
  48. package/dist/commands/dataset/embeddings/disable.js +19 -7
  49. package/dist/commands/dataset/embeddings/disable.js.map +1 -1
  50. package/dist/commands/dataset/embeddings/enable.js +17 -7
  51. package/dist/commands/dataset/embeddings/enable.js.map +1 -1
  52. package/dist/commands/dataset/embeddings/status.js +15 -7
  53. package/dist/commands/dataset/embeddings/status.js.map +1 -1
  54. package/dist/commands/dataset/export.js +30 -18
  55. package/dist/commands/dataset/export.js.map +1 -1
  56. package/dist/commands/dataset/list.js +19 -7
  57. package/dist/commands/dataset/list.js.map +1 -1
  58. package/dist/commands/dataset/visibility/get.js +15 -7
  59. package/dist/commands/dataset/visibility/get.js.map +1 -1
  60. package/dist/commands/dataset/visibility/set.js +19 -7
  61. package/dist/commands/dataset/visibility/set.js.map +1 -1
  62. package/dist/commands/documents/create.js +0 -6
  63. package/dist/commands/documents/create.js.map +1 -1
  64. package/dist/commands/documents/delete.js +0 -6
  65. package/dist/commands/documents/delete.js.map +1 -1
  66. package/dist/commands/documents/get.js +0 -6
  67. package/dist/commands/documents/get.js.map +1 -1
  68. package/dist/commands/documents/query.js +0 -6
  69. package/dist/commands/documents/query.js.map +1 -1
  70. package/dist/commands/graphql/list.js +0 -6
  71. package/dist/commands/graphql/list.js.map +1 -1
  72. package/dist/commands/graphql/undeploy.js +0 -6
  73. package/dist/commands/graphql/undeploy.js.map +1 -1
  74. package/dist/commands/hook/attempt.js +0 -6
  75. package/dist/commands/hook/attempt.js.map +1 -1
  76. package/dist/commands/hook/create.js +0 -6
  77. package/dist/commands/hook/create.js.map +1 -1
  78. package/dist/commands/hook/delete.js +0 -6
  79. package/dist/commands/hook/delete.js.map +1 -1
  80. package/dist/commands/hook/list.js +0 -6
  81. package/dist/commands/hook/list.js.map +1 -1
  82. package/dist/commands/hook/logs.js +0 -6
  83. package/dist/commands/hook/logs.js.map +1 -1
  84. package/dist/commands/media/delete-aspect.js +0 -6
  85. package/dist/commands/media/delete-aspect.js.map +1 -1
  86. package/dist/commands/media/deploy-aspect.js +1 -6
  87. package/dist/commands/media/deploy-aspect.js.map +1 -1
  88. package/dist/commands/media/export.js +0 -6
  89. package/dist/commands/media/export.js.map +1 -1
  90. package/dist/commands/media/import.js +0 -6
  91. package/dist/commands/media/import.js.map +1 -1
  92. package/dist/commands/schema/delete.js +0 -6
  93. package/dist/commands/schema/delete.js.map +1 -1
  94. package/dist/commands/tokens/add.js +0 -6
  95. package/dist/commands/tokens/add.js.map +1 -1
  96. package/dist/commands/tokens/delete.js +0 -6
  97. package/dist/commands/tokens/delete.js.map +1 -1
  98. package/dist/commands/tokens/list.js +0 -6
  99. package/dist/commands/tokens/list.js.map +1 -1
  100. package/dist/commands/users/invite.js +0 -6
  101. package/dist/commands/users/invite.js.map +1 -1
  102. package/dist/commands/users/list.js +0 -6
  103. package/dist/commands/users/list.js.map +1 -1
  104. package/dist/prompts/promptForProject.js +64 -0
  105. package/dist/prompts/promptForProject.js.map +1 -0
  106. package/dist/server/devServer.js +4 -2
  107. package/dist/server/devServer.js.map +1 -1
  108. package/dist/server/vite/plugin-schema-extraction.js +201 -0
  109. package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
  110. package/dist/server/vite/plugin-typegen.js +217 -0
  111. package/dist/server/vite/plugin-typegen.js.map +1 -0
  112. package/dist/services/grants.js +13 -0
  113. package/dist/services/grants.js.map +1 -0
  114. package/dist/types/grants.js +3 -0
  115. package/dist/types/grants.js.map +1 -0
  116. package/dist/util/checkProjectPermissions.js +21 -0
  117. package/dist/util/checkProjectPermissions.js.map +1 -0
  118. package/dist/util/getSharedServerConfig.js +1 -0
  119. package/dist/util/getSharedServerConfig.js.map +1 -1
  120. package/dist/util/sharedFlags.js +19 -0
  121. package/dist/util/sharedFlags.js.map +1 -0
  122. package/dist/util/toForwardSlashes.js +8 -0
  123. package/dist/util/toForwardSlashes.js.map +1 -0
  124. package/oclif.manifest.json +412 -286
  125. package/package.json +18 -16
  126. package/dist/actions/dev/getCoreAppUrl.js +0 -10
  127. package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
@@ -3,11 +3,12 @@ import { SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { validateDatasetAliasName } from '../../../actions/dataset/validateDatasetAliasName.js';
4
4
  import { validateDatasetName } from '../../../actions/dataset/validateDatasetName.js';
5
5
  import { promptForDatasetAliasName } from '../../../prompts/promptForDatasetAliasName.js';
6
+ import { promptForProject } from '../../../prompts/promptForProject.js';
6
7
  import { selectDataset } from '../../../prompts/selectDataset.js';
7
8
  import { ALIAS_PREFIX, createAlias, listAliases } from '../../../services/datasetAliases.js';
8
9
  import { listDatasets } from '../../../services/datasets.js';
9
10
  import { getProjectFeatures } from '../../../services/getProjectFeatures.js';
10
- import { NO_PROJECT_ID } from '../../../util/errorMessages.js';
11
+ import { projectIdFlag } from '../../../util/sharedFlags.js';
11
12
  const createAliasDebug = subdebug('dataset:alias:create');
12
13
  export class CreateAliasCommand extends SanityCommand {
13
14
  static args = {
@@ -22,6 +23,10 @@ export class CreateAliasCommand extends SanityCommand {
22
23
  };
23
24
  static description = 'Create a dataset alias within your project';
24
25
  static examples = [
26
+ {
27
+ command: '<%= config.bin %> <%= command.id %> --project-id abc123 conference conf-2025',
28
+ description: 'Create alias in a specific project'
29
+ },
25
30
  {
26
31
  command: '<%= config.bin %> <%= command.id %>',
27
32
  description: 'Create an alias with interactive prompts'
@@ -39,14 +44,25 @@ export class CreateAliasCommand extends SanityCommand {
39
44
  description: 'Create alias with explicit ~ prefix'
40
45
  }
41
46
  ];
47
+ static flags = {
48
+ ...projectIdFlag
49
+ };
42
50
  async run() {
43
51
  const { args } = await this.parse(CreateAliasCommand);
44
- const projectId = await this.getProjectId();
45
- if (!projectId) {
46
- this.error(NO_PROJECT_ID, {
47
- exit: 1
48
- });
49
- }
52
+ const projectId = await this.getProjectId({
53
+ fallback: ()=>promptForProject({
54
+ requiredPermissions: [
55
+ {
56
+ grant: 'read',
57
+ permission: 'sanity.project.datasets'
58
+ },
59
+ {
60
+ grant: 'create',
61
+ permission: 'sanity.project.datasets'
62
+ }
63
+ ]
64
+ })
65
+ });
50
66
  let canCreateAlias = false;
51
67
  try {
52
68
  const features = await getProjectFeatures(projectId);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/dataset/alias/create.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {validateDatasetName} from '../../../actions/dataset/validateDatasetName.js'\nimport {promptForDatasetAliasName} from '../../../prompts/promptForDatasetAliasName.js'\nimport {selectDataset} from '../../../prompts/selectDataset.js'\nimport {ALIAS_PREFIX, createAlias, listAliases} from '../../../services/datasetAliases.js'\nimport {listDatasets} from '../../../services/datasets.js'\nimport {getProjectFeatures} from '../../../services/getProjectFeatures.js'\nimport {NO_PROJECT_ID} from '../../../util/errorMessages.js'\n\nconst createAliasDebug = subdebug('dataset:alias:create')\n\nexport class CreateAliasCommand extends SanityCommand<typeof CreateAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to create',\n required: false,\n }),\n targetDataset: Args.string({\n description: 'Target dataset name to link the alias to',\n required: false,\n }),\n }\n\n static override description = 'Create a dataset alias within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Create an alias with interactive prompts',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Create alias named \"conference\" with interactive dataset selection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference conf-2025',\n description: 'Create alias \"conference\" linked to \"conf-2025\" dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference conf-2025',\n description: 'Create alias with explicit ~ prefix',\n },\n ]\n\n public async run(): Promise<void> {\n const {args} = await this.parse(CreateAliasCommand)\n\n const projectId = await this.getProjectId()\n if (!projectId) {\n this.error(NO_PROJECT_ID, {exit: 1})\n }\n\n let canCreateAlias = false\n try {\n const features = await getProjectFeatures(projectId)\n canCreateAlias = features.includes('advancedDatasetManagement')\n } catch (error) {\n createAliasDebug(`Error getting project features`, error)\n this.error('Failed to get project features', {exit: 1})\n }\n if (!canCreateAlias) {\n this.error('This project cannot create a dataset alias - see https://www.sanity.io/pricing', {\n exit: 1,\n })\n }\n\n if (args.aliasName) {\n const nameError = validateDatasetAliasName(args.aliasName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n }\n\n if (args.targetDataset) {\n const datasetErr = validateDatasetName(args.targetDataset)\n if (datasetErr) {\n this.error(datasetErr, {exit: 1})\n }\n }\n\n try {\n const [datasetsResponse, aliases] = await Promise.all([\n listDatasets(projectId),\n listAliases(projectId),\n ])\n\n const datasets = datasetsResponse.map((ds: {name: string}) => ds.name)\n const existingAliases = aliases.map((alias: {name: string}) => alias.name)\n\n let aliasName = args.aliasName || (await promptForDatasetAliasName())\n let aliasOutputName = aliasName\n\n if (aliasName.startsWith(ALIAS_PREFIX)) {\n aliasName = aliasName.slice(1)\n } else {\n aliasOutputName = `${ALIAS_PREFIX}${aliasName}`\n }\n\n if (existingAliases.includes(aliasName)) {\n this.error(`Dataset alias \"${aliasOutputName}\" already exists`, {exit: 1})\n }\n\n const targetDataset =\n args.targetDataset || (datasets.length > 0 ? await selectDataset(datasets) : null)\n\n if (targetDataset && !datasets.includes(targetDataset)) {\n this.error(\n `Dataset \"${targetDataset}\" does not exist. Available datasets: ${datasets.join(', ')}`,\n {exit: 1},\n )\n }\n\n await createAlias(projectId, aliasName, targetDataset)\n\n const linkMessage = targetDataset ? ` and linked to ${targetDataset}` : ''\n this.log(`Dataset alias ${aliasOutputName} created${linkMessage} successfully`)\n } catch (error) {\n createAliasDebug(`Error creating dataset alias`, error)\n this.error(\n `Dataset alias creation failed: ${error instanceof Error ? error.message : String(error)}`,\n {exit: 1},\n )\n }\n }\n}\n"],"names":["Args","SanityCommand","subdebug","validateDatasetAliasName","validateDatasetName","promptForDatasetAliasName","selectDataset","ALIAS_PREFIX","createAlias","listAliases","listDatasets","getProjectFeatures","NO_PROJECT_ID","createAliasDebug","CreateAliasCommand","args","aliasName","string","description","required","targetDataset","examples","command","run","parse","projectId","getProjectId","error","exit","canCreateAlias","features","includes","nameError","datasetErr","datasetsResponse","aliases","Promise","all","datasets","map","ds","name","existingAliases","alias","aliasOutputName","startsWith","slice","length","join","linkMessage","log","Error","message","String"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/commands/dataset/alias/create.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {validateDatasetName} from '../../../actions/dataset/validateDatasetName.js'\nimport {promptForDatasetAliasName} from '../../../prompts/promptForDatasetAliasName.js'\nimport {promptForProject} from '../../../prompts/promptForProject.js'\nimport {selectDataset} from '../../../prompts/selectDataset.js'\nimport {ALIAS_PREFIX, createAlias, listAliases} from '../../../services/datasetAliases.js'\nimport {listDatasets} from '../../../services/datasets.js'\nimport {getProjectFeatures} from '../../../services/getProjectFeatures.js'\nimport {projectIdFlag} from '../../../util/sharedFlags.js'\n\nconst createAliasDebug = subdebug('dataset:alias:create')\n\nexport class CreateAliasCommand extends SanityCommand<typeof CreateAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to create',\n required: false,\n }),\n targetDataset: Args.string({\n description: 'Target dataset name to link the alias to',\n required: false,\n }),\n }\n\n static override description = 'Create a dataset alias within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> --project-id abc123 conference conf-2025',\n description: 'Create alias in a specific project',\n },\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Create an alias with interactive prompts',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Create alias named \"conference\" with interactive dataset selection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference conf-2025',\n description: 'Create alias \"conference\" linked to \"conf-2025\" dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference conf-2025',\n description: 'Create alias with explicit ~ prefix',\n },\n ]\n\n static override flags = {\n ...projectIdFlag,\n }\n\n public async run(): Promise<void> {\n const {args} = await this.parse(CreateAliasCommand)\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 let canCreateAlias = false\n try {\n const features = await getProjectFeatures(projectId)\n canCreateAlias = features.includes('advancedDatasetManagement')\n } catch (error) {\n createAliasDebug(`Error getting project features`, error)\n this.error('Failed to get project features', {exit: 1})\n }\n if (!canCreateAlias) {\n this.error('This project cannot create a dataset alias - see https://www.sanity.io/pricing', {\n exit: 1,\n })\n }\n\n if (args.aliasName) {\n const nameError = validateDatasetAliasName(args.aliasName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n }\n\n if (args.targetDataset) {\n const datasetErr = validateDatasetName(args.targetDataset)\n if (datasetErr) {\n this.error(datasetErr, {exit: 1})\n }\n }\n\n try {\n const [datasetsResponse, aliases] = await Promise.all([\n listDatasets(projectId),\n listAliases(projectId),\n ])\n\n const datasets = datasetsResponse.map((ds: {name: string}) => ds.name)\n const existingAliases = aliases.map((alias: {name: string}) => alias.name)\n\n let aliasName = args.aliasName || (await promptForDatasetAliasName())\n let aliasOutputName = aliasName\n\n if (aliasName.startsWith(ALIAS_PREFIX)) {\n aliasName = aliasName.slice(1)\n } else {\n aliasOutputName = `${ALIAS_PREFIX}${aliasName}`\n }\n\n if (existingAliases.includes(aliasName)) {\n this.error(`Dataset alias \"${aliasOutputName}\" already exists`, {exit: 1})\n }\n\n const targetDataset =\n args.targetDataset || (datasets.length > 0 ? await selectDataset(datasets) : null)\n\n if (targetDataset && !datasets.includes(targetDataset)) {\n this.error(\n `Dataset \"${targetDataset}\" does not exist. Available datasets: ${datasets.join(', ')}`,\n {exit: 1},\n )\n }\n\n await createAlias(projectId, aliasName, targetDataset)\n\n const linkMessage = targetDataset ? ` and linked to ${targetDataset}` : ''\n this.log(`Dataset alias ${aliasOutputName} created${linkMessage} successfully`)\n } catch (error) {\n createAliasDebug(`Error creating dataset alias`, error)\n this.error(\n `Dataset alias creation failed: ${error instanceof Error ? error.message : String(error)}`,\n {exit: 1},\n )\n }\n }\n}\n"],"names":["Args","SanityCommand","subdebug","validateDatasetAliasName","validateDatasetName","promptForDatasetAliasName","promptForProject","selectDataset","ALIAS_PREFIX","createAlias","listAliases","listDatasets","getProjectFeatures","projectIdFlag","createAliasDebug","CreateAliasCommand","args","aliasName","string","description","required","targetDataset","examples","command","flags","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","canCreateAlias","features","includes","error","exit","nameError","datasetErr","datasetsResponse","aliases","Promise","all","datasets","map","ds","name","existingAliases","alias","aliasOutputName","startsWith","slice","length","join","linkMessage","log","Error","message","String"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAExD,SAAQC,wBAAwB,QAAO,uDAAsD;AAC7F,SAAQC,mBAAmB,QAAO,kDAAiD;AACnF,SAAQC,yBAAyB,QAAO,gDAA+C;AACvF,SAAQC,gBAAgB,QAAO,uCAAsC;AACrE,SAAQC,aAAa,QAAO,oCAAmC;AAC/D,SAAQC,YAAY,EAAEC,WAAW,EAAEC,WAAW,QAAO,sCAAqC;AAC1F,SAAQC,YAAY,QAAO,gCAA+B;AAC1D,SAAQC,kBAAkB,QAAO,0CAAyC;AAC1E,SAAQC,aAAa,QAAO,+BAA8B;AAE1D,MAAMC,mBAAmBZ,SAAS;AAElC,OAAO,MAAMa,2BAA2Bd;IACtC,OAAgBe,OAAO;QACrBC,WAAWjB,KAAKkB,MAAM,CAAC;YACrBC,aAAa;YACbC,UAAU;QACZ;QACAC,eAAerB,KAAKkB,MAAM,CAAC;YACzBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,6CAA4C;IAE1E,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtB,GAAGX,aAAa;IAClB,EAAC;IAED,MAAaY,MAAqB;QAChC,MAAM,EAACT,IAAI,EAAC,GAAG,MAAM,IAAI,CAACU,KAAK,CAACX;QAEhC,MAAMY,YAAY,MAAM,IAAI,CAACC,YAAY,CAAC;YACxCC,UAAU,IACRvB,iBAAiB;oBACfwB,qBAAqB;wBACnB;4BAACC,OAAO;4BAAQC,YAAY;wBAAyB;wBACrD;4BAACD,OAAO;4BAAUC,YAAY;wBAAyB;qBACxD;gBACH;QACJ;QAEA,IAAIC,iBAAiB;QACrB,IAAI;YACF,MAAMC,WAAW,MAAMtB,mBAAmBe;YAC1CM,iBAAiBC,SAASC,QAAQ,CAAC;QACrC,EAAE,OAAOC,OAAO;YACdtB,iBAAiB,CAAC,8BAA8B,CAAC,EAAEsB;YACnD,IAAI,CAACA,KAAK,CAAC,kCAAkC;gBAACC,MAAM;YAAC;QACvD;QACA,IAAI,CAACJ,gBAAgB;YACnB,IAAI,CAACG,KAAK,CAAC,kFAAkF;gBAC3FC,MAAM;YACR;QACF;QAEA,IAAIrB,KAAKC,SAAS,EAAE;YAClB,MAAMqB,YAAYnC,yBAAyBa,KAAKC,SAAS;YACzD,IAAIqB,WAAW;gBACb,IAAI,CAACF,KAAK,CAACE,WAAW;oBAACD,MAAM;gBAAC;YAChC;QACF;QAEA,IAAIrB,KAAKK,aAAa,EAAE;YACtB,MAAMkB,aAAanC,oBAAoBY,KAAKK,aAAa;YACzD,IAAIkB,YAAY;gBACd,IAAI,CAACH,KAAK,CAACG,YAAY;oBAACF,MAAM;gBAAC;YACjC;QACF;QAEA,IAAI;YACF,MAAM,CAACG,kBAAkBC,QAAQ,GAAG,MAAMC,QAAQC,GAAG,CAAC;gBACpDhC,aAAagB;gBACbjB,YAAYiB;aACb;YAED,MAAMiB,WAAWJ,iBAAiBK,GAAG,CAAC,CAACC,KAAuBA,GAAGC,IAAI;YACrE,MAAMC,kBAAkBP,QAAQI,GAAG,CAAC,CAACI,QAA0BA,MAAMF,IAAI;YAEzE,IAAI9B,YAAYD,KAAKC,SAAS,IAAK,MAAMZ;YACzC,IAAI6C,kBAAkBjC;YAEtB,IAAIA,UAAUkC,UAAU,CAAC3C,eAAe;gBACtCS,YAAYA,UAAUmC,KAAK,CAAC;YAC9B,OAAO;gBACLF,kBAAkB,GAAG1C,eAAeS,WAAW;YACjD;YAEA,IAAI+B,gBAAgBb,QAAQ,CAAClB,YAAY;gBACvC,IAAI,CAACmB,KAAK,CAAC,CAAC,eAAe,EAAEc,gBAAgB,gBAAgB,CAAC,EAAE;oBAACb,MAAM;gBAAC;YAC1E;YAEA,MAAMhB,gBACJL,KAAKK,aAAa,IAAKuB,CAAAA,SAASS,MAAM,GAAG,IAAI,MAAM9C,cAAcqC,YAAY,IAAG;YAElF,IAAIvB,iBAAiB,CAACuB,SAAST,QAAQ,CAACd,gBAAgB;gBACtD,IAAI,CAACe,KAAK,CACR,CAAC,SAAS,EAAEf,cAAc,sCAAsC,EAAEuB,SAASU,IAAI,CAAC,OAAO,EACvF;oBAACjB,MAAM;gBAAC;YAEZ;YAEA,MAAM5B,YAAYkB,WAAWV,WAAWI;YAExC,MAAMkC,cAAclC,gBAAgB,CAAC,eAAe,EAAEA,eAAe,GAAG;YACxE,IAAI,CAACmC,GAAG,CAAC,CAAC,cAAc,EAAEN,gBAAgB,QAAQ,EAAEK,YAAY,aAAa,CAAC;QAChF,EAAE,OAAOnB,OAAO;YACdtB,iBAAiB,CAAC,4BAA4B,CAAC,EAAEsB;YACjD,IAAI,CAACA,KAAK,CACR,CAAC,+BAA+B,EAAEA,iBAAiBqB,QAAQrB,MAAMsB,OAAO,GAAGC,OAAOvB,QAAQ,EAC1F;gBAACC,MAAM;YAAC;QAEZ;IACF;AACF"}
@@ -3,8 +3,9 @@ import { SanityCommand, subdebug } from '@sanity/cli-core';
3
3
  import { input } from '@sanity/cli-core/ux';
4
4
  import { processAliasName } from '../../../actions/dataset/processAliasName.js';
5
5
  import { validateDatasetAliasName } from '../../../actions/dataset/validateDatasetAliasName.js';
6
+ import { promptForProject } from '../../../prompts/promptForProject.js';
6
7
  import { listAliases, removeAlias } from '../../../services/datasetAliases.js';
7
- import { NO_PROJECT_ID } from '../../../util/errorMessages.js';
8
+ import { projectIdFlag } from '../../../util/sharedFlags.js';
8
9
  const deleteAliasDebug = subdebug('dataset:alias:delete');
9
10
  export class DeleteAliasCommand extends SanityCommand {
10
11
  static args = {
@@ -29,6 +30,7 @@ export class DeleteAliasCommand extends SanityCommand {
29
30
  }
30
31
  ];
31
32
  static flags = {
33
+ ...projectIdFlag,
32
34
  force: Flags.boolean({
33
35
  description: 'Skip confirmation prompt and delete immediately',
34
36
  required: false
@@ -37,12 +39,20 @@ export class DeleteAliasCommand extends SanityCommand {
37
39
  async run() {
38
40
  const { args, flags } = await this.parse(DeleteAliasCommand);
39
41
  const { force } = flags;
40
- const projectId = await this.getProjectId();
41
- if (!projectId) {
42
- this.error(NO_PROJECT_ID, {
43
- exit: 1
44
- });
45
- }
42
+ const projectId = await this.getProjectId({
43
+ fallback: ()=>promptForProject({
44
+ requiredPermissions: [
45
+ {
46
+ grant: 'read',
47
+ permission: 'sanity.project.datasets'
48
+ },
49
+ {
50
+ grant: 'delete',
51
+ permission: 'sanity.project.datasets'
52
+ }
53
+ ]
54
+ })
55
+ });
46
56
  const { apiName, displayName } = processAliasName(args.aliasName);
47
57
  const nameError = validateDatasetAliasName(apiName);
48
58
  if (nameError) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/dataset/alias/delete.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input} from '@sanity/cli-core/ux'\n\nimport {processAliasName} from '../../../actions/dataset/processAliasName.js'\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {listAliases, removeAlias} from '../../../services/datasetAliases.js'\nimport {NO_PROJECT_ID} from '../../../util/errorMessages.js'\n\nconst deleteAliasDebug = subdebug('dataset:alias:delete')\n\nexport class DeleteAliasCommand extends SanityCommand<typeof DeleteAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to delete',\n required: true,\n }),\n }\n\n static override description = 'Delete a dataset alias within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Delete alias named \"conference\" with confirmation prompt',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference',\n description: 'Delete alias with explicit ~ prefix',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference --force',\n description: 'Delete alias named \"conference\" without confirmation prompt',\n },\n ]\n\n static override flags = {\n force: Flags.boolean({\n description: 'Skip confirmation prompt and delete immediately',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(DeleteAliasCommand)\n const {force} = flags\n\n const projectId = await this.getProjectId()\n if (!projectId) {\n this.error(NO_PROJECT_ID, {exit: 1})\n }\n\n const {apiName, displayName} = processAliasName(args.aliasName)\n\n const nameError = validateDatasetAliasName(apiName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n\n try {\n const aliases = await listAliases(projectId)\n const existingAlias = aliases.find((alias) => alias.name === apiName)\n\n if (!existingAlias) {\n this.error(`Dataset alias \"${displayName}\" does not exist`, {exit: 1})\n }\n\n if (force) {\n this.warn(`'--force' used: skipping confirmation, deleting alias \"${displayName}\"`)\n } else {\n await this.confirmDeletion(displayName, existingAlias.datasetName)\n }\n\n await removeAlias(projectId, apiName)\n\n this.log('Dataset alias deleted successfully')\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n\n deleteAliasDebug(`Error deleting dataset alias ${args.aliasName}`, error)\n this.error(`Dataset alias deletion failed: ${errorMessage}`, {exit: 1})\n }\n }\n\n private async confirmDeletion(aliasName: string, linkedDataset?: string | null): Promise<void> {\n const message = linkedDataset\n ? `This dataset alias is linked to ${linkedDataset}. Are you ABSOLUTELY sure you want to delete this dataset alias?\\n Type the name of the dataset alias to confirm delete:`\n : `Are you ABSOLUTELY sure you want to delete this dataset alias?\\n Type the name of the dataset alias to confirm delete:`\n\n await input({\n message,\n validate: (input) => {\n const trimmed = input.trim().replace(/^~/, '')\n return trimmed === aliasName || 'Incorrect dataset alias name. Ctrl + C to cancel delete.'\n },\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","processAliasName","validateDatasetAliasName","listAliases","removeAlias","NO_PROJECT_ID","deleteAliasDebug","DeleteAliasCommand","args","aliasName","string","description","required","examples","command","flags","force","boolean","run","parse","projectId","getProjectId","error","exit","apiName","displayName","nameError","aliases","existingAlias","find","alias","name","warn","confirmDeletion","datasetName","log","errorMessage","Error","message","String","linkedDataset","validate","trimmed","trim","replace"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,KAAK,QAAO,sBAAqB;AAEzC,SAAQC,gBAAgB,QAAO,+CAA8C;AAC7E,SAAQC,wBAAwB,QAAO,uDAAsD;AAC7F,SAAQC,WAAW,EAAEC,WAAW,QAAO,sCAAqC;AAC5E,SAAQC,aAAa,QAAO,iCAAgC;AAE5D,MAAMC,mBAAmBP,SAAS;AAElC,OAAO,MAAMQ,2BAA2BT;IACtC,OAAgBU,OAAO;QACrBC,WAAWb,KAAKc,MAAM,CAAC;YACrBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,6CAA4C;IAE1E,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtBC,OAAOnB,MAAMoB,OAAO,CAAC;YACnBN,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,MAAaM,MAAqB;QAChC,MAAM,EAACV,IAAI,EAAEO,KAAK,EAAC,GAAG,MAAM,IAAI,CAACI,KAAK,CAACZ;QACvC,MAAM,EAACS,KAAK,EAAC,GAAGD;QAEhB,MAAMK,YAAY,MAAM,IAAI,CAACC,YAAY;QACzC,IAAI,CAACD,WAAW;YACd,IAAI,CAACE,KAAK,CAACjB,eAAe;gBAACkB,MAAM;YAAC;QACpC;QAEA,MAAM,EAACC,OAAO,EAAEC,WAAW,EAAC,GAAGxB,iBAAiBO,KAAKC,SAAS;QAE9D,MAAMiB,YAAYxB,yBAAyBsB;QAC3C,IAAIE,WAAW;YACb,IAAI,CAACJ,KAAK,CAACI,WAAW;gBAACH,MAAM;YAAC;QAChC;QAEA,IAAI;YACF,MAAMI,UAAU,MAAMxB,YAAYiB;YAClC,MAAMQ,gBAAgBD,QAAQE,IAAI,CAAC,CAACC,QAAUA,MAAMC,IAAI,KAAKP;YAE7D,IAAI,CAACI,eAAe;gBAClB,IAAI,CAACN,KAAK,CAAC,CAAC,eAAe,EAAEG,YAAY,gBAAgB,CAAC,EAAE;oBAACF,MAAM;gBAAC;YACtE;YAEA,IAAIP,OAAO;gBACT,IAAI,CAACgB,IAAI,CAAC,CAAC,uDAAuD,EAAEP,YAAY,CAAC,CAAC;YACpF,OAAO;gBACL,MAAM,IAAI,CAACQ,eAAe,CAACR,aAAaG,cAAcM,WAAW;YACnE;YAEA,MAAM9B,YAAYgB,WAAWI;YAE7B,IAAI,CAACW,GAAG,CAAC;QACX,EAAE,OAAOb,OAAO;YACd,MAAMc,eAAed,iBAAiBe,QAAQf,MAAMgB,OAAO,GAAGC,OAAOjB;YAErEhB,iBAAiB,CAAC,6BAA6B,EAAEE,KAAKC,SAAS,EAAE,EAAEa;YACnE,IAAI,CAACA,KAAK,CAAC,CAAC,+BAA+B,EAAEc,cAAc,EAAE;gBAACb,MAAM;YAAC;QACvE;IACF;IAEA,MAAcU,gBAAgBxB,SAAiB,EAAE+B,aAA6B,EAAiB;QAC7F,MAAMF,UAAUE,gBACZ,CAAC,gCAAgC,EAAEA,cAAc,yHAAyH,CAAC,GAC3K,CAAC,uHAAuH,CAAC;QAE7H,MAAMxC,MAAM;YACVsC;YACAG,UAAU,CAACzC;gBACT,MAAM0C,UAAU1C,MAAM2C,IAAI,GAAGC,OAAO,CAAC,MAAM;gBAC3C,OAAOF,YAAYjC,aAAa;YAClC;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../../../src/commands/dataset/alias/delete.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input} from '@sanity/cli-core/ux'\n\nimport {processAliasName} from '../../../actions/dataset/processAliasName.js'\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {promptForProject} from '../../../prompts/promptForProject.js'\nimport {listAliases, removeAlias} from '../../../services/datasetAliases.js'\nimport {projectIdFlag} from '../../../util/sharedFlags.js'\n\nconst deleteAliasDebug = subdebug('dataset:alias:delete')\n\nexport class DeleteAliasCommand extends SanityCommand<typeof DeleteAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to delete',\n required: true,\n }),\n }\n\n static override description = 'Delete a dataset alias within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Delete alias named \"conference\" with confirmation prompt',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference',\n description: 'Delete alias with explicit ~ prefix',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference --force',\n description: 'Delete alias named \"conference\" without confirmation prompt',\n },\n ]\n\n static override flags = {\n ...projectIdFlag,\n force: Flags.boolean({\n description: 'Skip confirmation prompt and delete immediately',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(DeleteAliasCommand)\n const {force} = flags\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'delete', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n const {apiName, displayName} = processAliasName(args.aliasName)\n\n const nameError = validateDatasetAliasName(apiName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n\n try {\n const aliases = await listAliases(projectId)\n const existingAlias = aliases.find((alias) => alias.name === apiName)\n\n if (!existingAlias) {\n this.error(`Dataset alias \"${displayName}\" does not exist`, {exit: 1})\n }\n\n if (force) {\n this.warn(`'--force' used: skipping confirmation, deleting alias \"${displayName}\"`)\n } else {\n await this.confirmDeletion(displayName, existingAlias.datasetName)\n }\n\n await removeAlias(projectId, apiName)\n\n this.log('Dataset alias deleted successfully')\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error)\n\n deleteAliasDebug(`Error deleting dataset alias ${args.aliasName}`, error)\n this.error(`Dataset alias deletion failed: ${errorMessage}`, {exit: 1})\n }\n }\n\n private async confirmDeletion(aliasName: string, linkedDataset?: string | null): Promise<void> {\n const message = linkedDataset\n ? `This dataset alias is linked to ${linkedDataset}. Are you ABSOLUTELY sure you want to delete this dataset alias?\\n Type the name of the dataset alias to confirm delete:`\n : `Are you ABSOLUTELY sure you want to delete this dataset alias?\\n Type the name of the dataset alias to confirm delete:`\n\n await input({\n message,\n validate: (input) => {\n const trimmed = input.trim().replace(/^~/, '')\n return trimmed === aliasName || 'Incorrect dataset alias name. Ctrl + C to cancel delete.'\n },\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","processAliasName","validateDatasetAliasName","promptForProject","listAliases","removeAlias","projectIdFlag","deleteAliasDebug","DeleteAliasCommand","args","aliasName","string","description","required","examples","command","flags","force","boolean","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","apiName","displayName","nameError","error","exit","aliases","existingAlias","find","alias","name","warn","confirmDeletion","datasetName","log","errorMessage","Error","message","String","linkedDataset","validate","trimmed","trim","replace"],"mappings":"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"}
@@ -5,10 +5,11 @@ import { processAliasName } from '../../../actions/dataset/processAliasName.js';
5
5
  import { validateDatasetAliasName } from '../../../actions/dataset/validateDatasetAliasName.js';
6
6
  import { validateDatasetName } from '../../../actions/dataset/validateDatasetName.js';
7
7
  import { promptForDatasetAliasName } from '../../../prompts/promptForDatasetAliasName.js';
8
+ import { promptForProject } from '../../../prompts/promptForProject.js';
8
9
  import { selectDataset } from '../../../prompts/selectDataset.js';
9
10
  import { listAliases, updateAlias } from '../../../services/datasetAliases.js';
10
11
  import { listDatasets } from '../../../services/datasets.js';
11
- import { NO_PROJECT_ID } from '../../../util/errorMessages.js';
12
+ import { projectIdFlag } from '../../../util/sharedFlags.js';
12
13
  const linkAliasDebug = subdebug('dataset:alias:link');
13
14
  export class LinkAliasCommand extends SanityCommand {
14
15
  static args = {
@@ -45,6 +46,7 @@ export class LinkAliasCommand extends SanityCommand {
45
46
  }
46
47
  ];
47
48
  static flags = {
49
+ ...projectIdFlag,
48
50
  force: Flags.boolean({
49
51
  description: 'Skip confirmation prompt when relinking existing alias',
50
52
  required: false
@@ -53,12 +55,20 @@ export class LinkAliasCommand extends SanityCommand {
53
55
  async run() {
54
56
  const { args, flags } = await this.parse(LinkAliasCommand);
55
57
  const { force } = flags;
56
- const projectId = await this.getProjectId();
57
- if (!projectId) {
58
- this.error(NO_PROJECT_ID, {
59
- exit: 1
60
- });
61
- }
58
+ const projectId = await this.getProjectId({
59
+ fallback: ()=>promptForProject({
60
+ requiredPermissions: [
61
+ {
62
+ grant: 'read',
63
+ permission: 'sanity.project.datasets'
64
+ },
65
+ {
66
+ grant: 'update',
67
+ permission: 'sanity.project.datasets'
68
+ }
69
+ ]
70
+ })
71
+ });
62
72
  if (args.aliasName) {
63
73
  const { apiName } = processAliasName(args.aliasName);
64
74
  const nameError = validateDatasetAliasName(apiName);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/dataset/alias/link.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input} from '@sanity/cli-core/ux'\n\nimport {processAliasName} from '../../../actions/dataset/processAliasName.js'\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {validateDatasetName} from '../../../actions/dataset/validateDatasetName.js'\nimport {promptForDatasetAliasName} from '../../../prompts/promptForDatasetAliasName.js'\nimport {selectDataset} from '../../../prompts/selectDataset.js'\nimport {listAliases, updateAlias} from '../../../services/datasetAliases.js'\nimport {listDatasets} from '../../../services/datasets.js'\nimport {NO_PROJECT_ID} from '../../../util/errorMessages.js'\n\nconst linkAliasDebug = subdebug('dataset:alias:link')\n\nexport class LinkAliasCommand extends SanityCommand<typeof LinkAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to link',\n required: false,\n }),\n targetDataset: Args.string({\n description: 'Target dataset name to link the alias to',\n required: false,\n }),\n }\n\n static override description = 'Link a dataset alias to a dataset within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Link an alias with interactive prompts',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Link alias named \"conference\" with interactive dataset selection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference conf-2025',\n description: 'Link alias \"conference\" to \"conf-2025\" dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference conf-2025',\n description: 'Link alias with explicit ~ prefix',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference conf-2025 --force',\n description: 'Force link without confirmation (skip relink prompt)',\n },\n ]\n\n static override flags = {\n force: Flags.boolean({\n description: 'Skip confirmation prompt when relinking existing alias',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(LinkAliasCommand)\n const {force} = flags\n\n const projectId = await this.getProjectId()\n if (!projectId) {\n this.error(NO_PROJECT_ID, {exit: 1})\n }\n\n if (args.aliasName) {\n const {apiName} = processAliasName(args.aliasName)\n const nameError = validateDatasetAliasName(apiName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n }\n\n if (args.targetDataset) {\n const datasetErr = validateDatasetName(args.targetDataset)\n if (datasetErr) {\n this.error(datasetErr, {exit: 1})\n }\n }\n\n try {\n const [datasetsResponse, aliases] = await Promise.all([\n listDatasets(projectId),\n listAliases(projectId),\n ])\n\n const datasets = datasetsResponse.map((ds) => ds.name)\n\n const aliasNameInput = args.aliasName || (await promptForDatasetAliasName())\n\n const {apiName, displayName} = processAliasName(aliasNameInput)\n\n const existingAlias = aliases.find((alias) => alias.name === apiName)\n if (!existingAlias) {\n const availableAliases = aliases.map((a) => `~${a.name}`).join(', ')\n this.error(\n `Dataset alias \"${displayName}\" does not exist. Available aliases: ${availableAliases}`,\n {exit: 1},\n )\n }\n\n const targetDataset =\n args.targetDataset ||\n (datasets.length > 0\n ? await selectDataset(datasets, {\n message: 'Select target dataset to link alias to:',\n })\n : null)\n\n if (!targetDataset) {\n this.error('No datasets available to link to', {exit: 1})\n }\n\n if (!datasets.includes(targetDataset)) {\n this.error(\n `Dataset \"${targetDataset}\" does not exist. Available datasets: ${datasets.join(', ')}`,\n {exit: 1},\n )\n }\n\n if (existingAlias.datasetName === targetDataset) {\n this.error(`Dataset alias ${displayName} already linked to ${targetDataset}`, {exit: 1})\n }\n\n if (existingAlias.datasetName && !force) {\n await this.confirmRelink(existingAlias.datasetName, targetDataset)\n } else if (force && existingAlias.datasetName) {\n this.warn(`'--force' used: skipping confirmation, linking alias to ${targetDataset}`)\n }\n\n await updateAlias(projectId, apiName, targetDataset)\n\n this.log(`Dataset alias ${displayName} linked to ${targetDataset} successfully`)\n } catch (error) {\n linkAliasDebug(`Error linking dataset alias`, error)\n this.error(\n `Dataset alias linking failed: ${error instanceof Error ? error.message : String(error)}`,\n {exit: 1},\n )\n }\n }\n\n private async confirmRelink(currentDataset: string, newDataset: string): Promise<void> {\n await input({\n message: `This alias is linked to dataset <${currentDataset}>. Are you ABSOLUTELY sure you want to link this dataset alias to ${newDataset}?\\n Type YES/NO:`,\n validate: (input) => {\n const response = input.toLowerCase().trim()\n return response === 'yes' || 'Type YES to confirm or Ctrl + C to cancel dataset alias link.'\n },\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","processAliasName","validateDatasetAliasName","validateDatasetName","promptForDatasetAliasName","selectDataset","listAliases","updateAlias","listDatasets","NO_PROJECT_ID","linkAliasDebug","LinkAliasCommand","args","aliasName","string","description","required","targetDataset","examples","command","flags","force","boolean","run","parse","projectId","getProjectId","error","exit","apiName","nameError","datasetErr","datasetsResponse","aliases","Promise","all","datasets","map","ds","name","aliasNameInput","displayName","existingAlias","find","alias","availableAliases","a","join","length","message","includes","datasetName","confirmRelink","warn","log","Error","String","currentDataset","newDataset","validate","response","toLowerCase","trim"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/commands/dataset/alias/link.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input} from '@sanity/cli-core/ux'\n\nimport {processAliasName} from '../../../actions/dataset/processAliasName.js'\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {validateDatasetName} from '../../../actions/dataset/validateDatasetName.js'\nimport {promptForDatasetAliasName} from '../../../prompts/promptForDatasetAliasName.js'\nimport {promptForProject} from '../../../prompts/promptForProject.js'\nimport {selectDataset} from '../../../prompts/selectDataset.js'\nimport {listAliases, updateAlias} from '../../../services/datasetAliases.js'\nimport {listDatasets} from '../../../services/datasets.js'\nimport {projectIdFlag} from '../../../util/sharedFlags.js'\n\nconst linkAliasDebug = subdebug('dataset:alias:link')\n\nexport class LinkAliasCommand extends SanityCommand<typeof LinkAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to link',\n required: false,\n }),\n targetDataset: Args.string({\n description: 'Target dataset name to link the alias to',\n required: false,\n }),\n }\n\n static override description = 'Link a dataset alias to a dataset within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Link an alias with interactive prompts',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Link alias named \"conference\" with interactive dataset selection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference conf-2025',\n description: 'Link alias \"conference\" to \"conf-2025\" dataset',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference conf-2025',\n description: 'Link alias with explicit ~ prefix',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference conf-2025 --force',\n description: 'Force link without confirmation (skip relink prompt)',\n },\n ]\n\n static override flags = {\n ...projectIdFlag,\n force: Flags.boolean({\n description: 'Skip confirmation prompt when relinking existing alias',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(LinkAliasCommand)\n const {force} = flags\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'update', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n if (args.aliasName) {\n const {apiName} = processAliasName(args.aliasName)\n const nameError = validateDatasetAliasName(apiName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n }\n\n if (args.targetDataset) {\n const datasetErr = validateDatasetName(args.targetDataset)\n if (datasetErr) {\n this.error(datasetErr, {exit: 1})\n }\n }\n\n try {\n const [datasetsResponse, aliases] = await Promise.all([\n listDatasets(projectId),\n listAliases(projectId),\n ])\n\n const datasets = datasetsResponse.map((ds) => ds.name)\n\n const aliasNameInput = args.aliasName || (await promptForDatasetAliasName())\n\n const {apiName, displayName} = processAliasName(aliasNameInput)\n\n const existingAlias = aliases.find((alias) => alias.name === apiName)\n if (!existingAlias) {\n const availableAliases = aliases.map((a) => `~${a.name}`).join(', ')\n this.error(\n `Dataset alias \"${displayName}\" does not exist. Available aliases: ${availableAliases}`,\n {exit: 1},\n )\n }\n\n const targetDataset =\n args.targetDataset ||\n (datasets.length > 0\n ? await selectDataset(datasets, {\n message: 'Select target dataset to link alias to:',\n })\n : null)\n\n if (!targetDataset) {\n this.error('No datasets available to link to', {exit: 1})\n }\n\n if (!datasets.includes(targetDataset)) {\n this.error(\n `Dataset \"${targetDataset}\" does not exist. Available datasets: ${datasets.join(', ')}`,\n {exit: 1},\n )\n }\n\n if (existingAlias.datasetName === targetDataset) {\n this.error(`Dataset alias ${displayName} already linked to ${targetDataset}`, {exit: 1})\n }\n\n if (existingAlias.datasetName && !force) {\n await this.confirmRelink(existingAlias.datasetName, targetDataset)\n } else if (force && existingAlias.datasetName) {\n this.warn(`'--force' used: skipping confirmation, linking alias to ${targetDataset}`)\n }\n\n await updateAlias(projectId, apiName, targetDataset)\n\n this.log(`Dataset alias ${displayName} linked to ${targetDataset} successfully`)\n } catch (error) {\n linkAliasDebug(`Error linking dataset alias`, error)\n this.error(\n `Dataset alias linking failed: ${error instanceof Error ? error.message : String(error)}`,\n {exit: 1},\n )\n }\n }\n\n private async confirmRelink(currentDataset: string, newDataset: string): Promise<void> {\n await input({\n message: `This alias is linked to dataset <${currentDataset}>. Are you ABSOLUTELY sure you want to link this dataset alias to ${newDataset}?\\n Type YES/NO:`,\n validate: (input) => {\n const response = input.toLowerCase().trim()\n return response === 'yes' || 'Type YES to confirm or Ctrl + C to cancel dataset alias link.'\n },\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","processAliasName","validateDatasetAliasName","validateDatasetName","promptForDatasetAliasName","promptForProject","selectDataset","listAliases","updateAlias","listDatasets","projectIdFlag","linkAliasDebug","LinkAliasCommand","args","aliasName","string","description","required","targetDataset","examples","command","flags","force","boolean","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","apiName","nameError","error","exit","datasetErr","datasetsResponse","aliases","Promise","all","datasets","map","ds","name","aliasNameInput","displayName","existingAlias","find","alias","availableAliases","a","join","length","message","includes","datasetName","confirmRelink","warn","log","Error","String","currentDataset","newDataset","validate","response","toLowerCase","trim"],"mappings":"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"}
@@ -4,8 +4,9 @@ import { input } from '@sanity/cli-core/ux';
4
4
  import { processAliasName } from '../../../actions/dataset/processAliasName.js';
5
5
  import { validateDatasetAliasName } from '../../../actions/dataset/validateDatasetAliasName.js';
6
6
  import { promptForDatasetAliasName } from '../../../prompts/promptForDatasetAliasName.js';
7
+ import { promptForProject } from '../../../prompts/promptForProject.js';
7
8
  import { listAliases, unlinkAlias } from '../../../services/datasetAliases.js';
8
- import { NO_PROJECT_ID } from '../../../util/errorMessages.js';
9
+ import { projectIdFlag } from '../../../util/sharedFlags.js';
9
10
  const unlinkAliasDebug = subdebug('dataset:alias:unlink');
10
11
  export class UnlinkAliasCommand extends SanityCommand {
11
12
  static args = {
@@ -34,6 +35,7 @@ export class UnlinkAliasCommand extends SanityCommand {
34
35
  }
35
36
  ];
36
37
  static flags = {
38
+ ...projectIdFlag,
37
39
  force: Flags.boolean({
38
40
  description: 'Skip confirmation prompt and unlink immediately',
39
41
  required: false
@@ -42,12 +44,20 @@ export class UnlinkAliasCommand extends SanityCommand {
42
44
  async run() {
43
45
  const { args, flags } = await this.parse(UnlinkAliasCommand);
44
46
  const { force } = flags;
45
- const projectId = await this.getProjectId();
46
- if (!projectId) {
47
- this.error(NO_PROJECT_ID, {
48
- exit: 1
49
- });
50
- }
47
+ const projectId = await this.getProjectId({
48
+ fallback: ()=>promptForProject({
49
+ requiredPermissions: [
50
+ {
51
+ grant: 'read',
52
+ permission: 'sanity.project.datasets'
53
+ },
54
+ {
55
+ grant: 'update',
56
+ permission: 'sanity.project.datasets'
57
+ }
58
+ ]
59
+ })
60
+ });
51
61
  try {
52
62
  const aliasNameInput = args.aliasName || await promptForDatasetAliasName();
53
63
  const { apiName, displayName } = processAliasName(aliasNameInput);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/dataset/alias/unlink.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input} from '@sanity/cli-core/ux'\n\nimport {processAliasName} from '../../../actions/dataset/processAliasName.js'\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {promptForDatasetAliasName} from '../../../prompts/promptForDatasetAliasName.js'\nimport {listAliases, unlinkAlias} from '../../../services/datasetAliases.js'\nimport {NO_PROJECT_ID} from '../../../util/errorMessages.js'\n\nconst unlinkAliasDebug = subdebug('dataset:alias:unlink')\n\nexport class UnlinkAliasCommand extends SanityCommand<typeof UnlinkAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to unlink',\n required: false,\n }),\n }\n\n static override description = 'Unlink a dataset alias from its dataset within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Unlink an alias with interactive selection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Unlink alias \"conference\" with confirmation prompt',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference',\n description: 'Unlink alias with explicit ~ prefix',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference --force',\n description: 'Unlink alias \"conference\" without confirmation prompt',\n },\n ]\n\n static override flags = {\n force: Flags.boolean({\n description: 'Skip confirmation prompt and unlink immediately',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(UnlinkAliasCommand)\n const {force} = flags\n\n const projectId = await this.getProjectId()\n if (!projectId) {\n this.error(NO_PROJECT_ID, {exit: 1})\n }\n\n try {\n const aliasNameInput = args.aliasName || (await promptForDatasetAliasName())\n const {apiName, displayName} = processAliasName(aliasNameInput)\n\n const nameError = validateDatasetAliasName(apiName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n\n const aliases = await listAliases(projectId)\n\n // get the current alias from the remote alias list\n const linkedAlias = aliases.find((elem) => elem.name === apiName)\n if (!linkedAlias) {\n this.error(`Dataset alias \"${displayName}\" does not exist`, {exit: 1})\n }\n\n if (!linkedAlias.datasetName) {\n this.error(`Dataset alias \"${displayName}\" is not linked to a dataset`, {exit: 1})\n }\n\n if (force) {\n this.warn(`'--force' used: skipping confirmation, unlinking alias \"${displayName}\"`)\n } else {\n await this.confirmUnlink(linkedAlias.datasetName)\n }\n\n const result = await unlinkAlias(projectId, apiName)\n this.log(`Dataset alias ${displayName} unlinked from ${result.datasetName} successfully`)\n } catch (error) {\n unlinkAliasDebug('Error unlinking dataset alias', error)\n this.error(\n `Dataset alias unlink failed: ${error instanceof Error ? error.message : String(error)}`,\n {exit: 1},\n )\n }\n }\n\n private async confirmUnlink(datasetName: string): Promise<void> {\n await input({\n message: `Are you ABSOLUTELY sure you want to unlink this alias from the \"${datasetName}\" dataset?\\n Type YES/NO:`,\n validate: (input) => {\n const response = input.toLowerCase().trim()\n return (\n response === 'yes' || 'Type YES to confirm or Ctrl + C to cancel dataset alias unlink.'\n )\n },\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","processAliasName","validateDatasetAliasName","promptForDatasetAliasName","listAliases","unlinkAlias","NO_PROJECT_ID","unlinkAliasDebug","UnlinkAliasCommand","args","aliasName","string","description","required","examples","command","flags","force","boolean","run","parse","projectId","getProjectId","error","exit","aliasNameInput","apiName","displayName","nameError","aliases","linkedAlias","find","elem","name","datasetName","warn","confirmUnlink","result","log","Error","message","String","validate","response","toLowerCase","trim"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../src/commands/dataset/alias/unlink.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input} from '@sanity/cli-core/ux'\n\nimport {processAliasName} from '../../../actions/dataset/processAliasName.js'\nimport {validateDatasetAliasName} from '../../../actions/dataset/validateDatasetAliasName.js'\nimport {promptForDatasetAliasName} from '../../../prompts/promptForDatasetAliasName.js'\nimport {promptForProject} from '../../../prompts/promptForProject.js'\nimport {listAliases, unlinkAlias} from '../../../services/datasetAliases.js'\nimport {projectIdFlag} from '../../../util/sharedFlags.js'\n\nconst unlinkAliasDebug = subdebug('dataset:alias:unlink')\n\nexport class UnlinkAliasCommand extends SanityCommand<typeof UnlinkAliasCommand> {\n static override args = {\n aliasName: Args.string({\n description: 'Dataset alias name to unlink',\n required: false,\n }),\n }\n\n static override description = 'Unlink a dataset alias from its dataset within your project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Unlink an alias with interactive selection',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference',\n description: 'Unlink alias \"conference\" with confirmation prompt',\n },\n {\n command: '<%= config.bin %> <%= command.id %> ~conference',\n description: 'Unlink alias with explicit ~ prefix',\n },\n {\n command: '<%= config.bin %> <%= command.id %> conference --force',\n description: 'Unlink alias \"conference\" without confirmation prompt',\n },\n ]\n\n static override flags = {\n ...projectIdFlag,\n force: Flags.boolean({\n description: 'Skip confirmation prompt and unlink immediately',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(UnlinkAliasCommand)\n const {force} = flags\n\n const projectId = await this.getProjectId({\n fallback: () =>\n promptForProject({\n requiredPermissions: [\n {grant: 'read', permission: 'sanity.project.datasets'},\n {grant: 'update', permission: 'sanity.project.datasets'},\n ],\n }),\n })\n\n try {\n const aliasNameInput = args.aliasName || (await promptForDatasetAliasName())\n const {apiName, displayName} = processAliasName(aliasNameInput)\n\n const nameError = validateDatasetAliasName(apiName)\n if (nameError) {\n this.error(nameError, {exit: 1})\n }\n\n const aliases = await listAliases(projectId)\n\n // get the current alias from the remote alias list\n const linkedAlias = aliases.find((elem) => elem.name === apiName)\n if (!linkedAlias) {\n this.error(`Dataset alias \"${displayName}\" does not exist`, {exit: 1})\n }\n\n if (!linkedAlias.datasetName) {\n this.error(`Dataset alias \"${displayName}\" is not linked to a dataset`, {exit: 1})\n }\n\n if (force) {\n this.warn(`'--force' used: skipping confirmation, unlinking alias \"${displayName}\"`)\n } else {\n await this.confirmUnlink(linkedAlias.datasetName)\n }\n\n const result = await unlinkAlias(projectId, apiName)\n this.log(`Dataset alias ${displayName} unlinked from ${result.datasetName} successfully`)\n } catch (error) {\n unlinkAliasDebug('Error unlinking dataset alias', error)\n this.error(\n `Dataset alias unlink failed: ${error instanceof Error ? error.message : String(error)}`,\n {exit: 1},\n )\n }\n }\n\n private async confirmUnlink(datasetName: string): Promise<void> {\n await input({\n message: `Are you ABSOLUTELY sure you want to unlink this alias from the \"${datasetName}\" dataset?\\n Type YES/NO:`,\n validate: (input) => {\n const response = input.toLowerCase().trim()\n return (\n response === 'yes' || 'Type YES to confirm or Ctrl + C to cancel dataset alias unlink.'\n )\n },\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","processAliasName","validateDatasetAliasName","promptForDatasetAliasName","promptForProject","listAliases","unlinkAlias","projectIdFlag","unlinkAliasDebug","UnlinkAliasCommand","args","aliasName","string","description","required","examples","command","flags","force","boolean","run","parse","projectId","getProjectId","fallback","requiredPermissions","grant","permission","aliasNameInput","apiName","displayName","nameError","error","exit","aliases","linkedAlias","find","elem","name","datasetName","warn","confirmUnlink","result","log","Error","message","String","validate","response","toLowerCase","trim"],"mappings":"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"}
@@ -10,8 +10,9 @@ import { parseISO } from 'date-fns/parseISO';
10
10
  import { validateDatasetName } from '../../actions/dataset/validateDatasetName.js';
11
11
  import { promptForDataset } from '../../prompts/promptForDataset.js';
12
12
  import { promptForDatasetName } from '../../prompts/promptForDatasetName.js';
13
+ import { promptForProject } from '../../prompts/promptForProject.js';
13
14
  import { copyDataset, followCopyJobProgress, listDatasetCopyJobs, listDatasets } from '../../services/datasets.js';
14
- import { NO_PROJECT_ID } from '../../util/errorMessages.js';
15
+ import { projectIdFlag } from '../../util/sharedFlags.js';
15
16
  const copyDatasetDebug = subdebug('dataset:copy');
16
17
  export class CopyDatasetCommand extends SanityCommand {
17
18
  static args = {
@@ -60,6 +61,7 @@ export class CopyDatasetCommand extends SanityCommand {
60
61
  }
61
62
  ];
62
63
  static flags = {
64
+ ...projectIdFlag,
63
65
  attach: Flags.string({
64
66
  description: 'Attach to the running copy process to show progress',
65
67
  exclusive: [
@@ -110,24 +112,30 @@ export class CopyDatasetCommand extends SanityCommand {
110
112
  required: false
111
113
  })
112
114
  };
113
- projectId;
114
115
  async run() {
115
116
  const { args, flags } = await this.parse(CopyDatasetCommand);
116
- const projectId = await this.getProjectId();
117
- if (!projectId) {
118
- this.error(NO_PROJECT_ID, {
119
- exit: 1
120
- });
121
- }
122
- this.projectId = projectId;
117
+ const projectId = await this.getProjectId({
118
+ fallback: ()=>promptForProject({
119
+ requiredPermissions: [
120
+ {
121
+ grant: 'read',
122
+ permission: 'sanity.project.datasets'
123
+ },
124
+ {
125
+ grant: 'create',
126
+ permission: 'sanity.project.datasets'
127
+ }
128
+ ]
129
+ })
130
+ });
123
131
  // Route to appropriate mode
124
132
  if (flags.list) {
125
- return this.handleListMode(flags);
133
+ return this.handleListMode(projectId, flags);
126
134
  }
127
135
  if (flags.attach) {
128
- return this.handleAttachMode(flags.attach);
136
+ return this.handleAttachMode(projectId, flags.attach);
129
137
  }
130
- return this.handleCopyMode(args, flags);
138
+ return this.handleCopyMode(projectId, args, flags);
131
139
  }
132
140
  displayCopyJobsTable(jobs) {
133
141
  const table = new Table({
@@ -216,15 +224,15 @@ export class CopyDatasetCommand extends SanityCommand {
216
224
  }
217
225
  table.printTable();
218
226
  }
219
- async handleAttachMode(jobId) {
227
+ async handleAttachMode(projectId, jobId) {
220
228
  copyDatasetDebug('Attaching to copy job %s', jobId);
221
- if (!jobId || typeof jobId !== 'string' || jobId.trim() === '') {
229
+ if (jobId.trim() === '') {
222
230
  this.error('Please supply a valid jobId', {
223
231
  exit: 1
224
232
  });
225
233
  }
226
234
  try {
227
- await this.subscribeToProgress(jobId);
235
+ await this.subscribeToProgress(projectId, jobId);
228
236
  this.log(`Job ${styleText('green', jobId)} completed`);
229
237
  } catch (error) {
230
238
  const message = error instanceof Error ? error.message : String(error);
@@ -234,7 +242,7 @@ export class CopyDatasetCommand extends SanityCommand {
234
242
  });
235
243
  }
236
244
  }
237
- async handleCopyMode(args, flags) {
245
+ async handleCopyMode(projectId, args, flags) {
238
246
  copyDatasetDebug('Starting copy mode');
239
247
  const skipHistory = Boolean(flags['skip-history']);
240
248
  // Get and validate source dataset
@@ -249,7 +257,7 @@ export class CopyDatasetCommand extends SanityCommand {
249
257
  }
250
258
  let datasetsResponse;
251
259
  try {
252
- datasetsResponse = await listDatasets(this.projectId);
260
+ datasetsResponse = await listDatasets(projectId);
253
261
  } catch (error) {
254
262
  const message = error instanceof Error ? error.message : String(error);
255
263
  copyDatasetDebug('Failed to fetch datasets: %s', message, error);
@@ -295,7 +303,7 @@ export class CopyDatasetCommand extends SanityCommand {
295
303
  this.log(`Note: You can run this command with flag '--skip-history'. The flag will reduce copy time in larger datasets.`);
296
304
  }
297
305
  const response = await copyDataset({
298
- projectId: this.projectId,
306
+ projectId,
299
307
  skipHistory,
300
308
  sourceDataset,
301
309
  targetDataset
@@ -304,7 +312,7 @@ export class CopyDatasetCommand extends SanityCommand {
304
312
  if (flags.detach) {
305
313
  return;
306
314
  }
307
- await this.subscribeToProgress(response.jobId);
315
+ await this.subscribeToProgress(projectId, response.jobId);
308
316
  this.log(`Job ${styleText('green', response.jobId)} completed`);
309
317
  } catch (error) {
310
318
  const message = error instanceof Error ? error.message : String(error);
@@ -314,13 +322,13 @@ export class CopyDatasetCommand extends SanityCommand {
314
322
  });
315
323
  }
316
324
  }
317
- async handleListMode(flags) {
325
+ async handleListMode(projectId, flags) {
318
326
  copyDatasetDebug('Listing dataset copy jobs');
319
327
  try {
320
328
  const jobs = await listDatasetCopyJobs({
321
329
  limit: flags.limit,
322
330
  offset: flags.offset,
323
- projectId: this.projectId
331
+ projectId
324
332
  });
325
333
  if (jobs.length === 0) {
326
334
  this.log("This project doesn't have any dataset copy jobs");
@@ -335,19 +343,26 @@ export class CopyDatasetCommand extends SanityCommand {
335
343
  });
336
344
  }
337
345
  }
338
- async subscribeToProgress(jobId) {
346
+ async subscribeToProgress(projectId, jobId) {
339
347
  let currentProgress = 0;
340
348
  const spin = spinner('').start();
341
349
  return new Promise((resolve, reject)=>{
350
+ const sigintHandler = ()=>{
351
+ subscription.unsubscribe();
352
+ spin.fail('Copy interrupted.');
353
+ exit(130);
354
+ };
342
355
  const subscription = followCopyJobProgress({
343
356
  jobId,
344
- projectId: this.projectId
357
+ projectId
345
358
  }).subscribe({
346
359
  complete: ()=>{
360
+ process.off('SIGINT', sigintHandler);
347
361
  spin.succeed('Copy finished.');
348
362
  resolve();
349
363
  },
350
364
  error: (err)=>{
365
+ process.off('SIGINT', sigintHandler);
351
366
  spin.fail('Copy failed.');
352
367
  reject(err);
353
368
  },
@@ -358,12 +373,7 @@ export class CopyDatasetCommand extends SanityCommand {
358
373
  spin.text = `Copy in progress: ${currentProgress}%`;
359
374
  }
360
375
  });
361
- // Cleanup on process termination - use 'once' to prevent memory leaks
362
- process.once('SIGINT', ()=>{
363
- subscription.unsubscribe();
364
- spin.fail('Copy interrupted.');
365
- exit(130);
366
- });
376
+ process.once('SIGINT', sigintHandler);
367
377
  });
368
378
  }
369
379
  }