@sanity/cli 6.2.1 → 6.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +111 -120
- package/dist/SanityHelp.js +38 -0
- package/dist/SanityHelp.js.map +1 -1
- package/dist/actions/auth/login/getProvider.js +9 -4
- package/dist/actions/auth/login/getProvider.js.map +1 -1
- package/dist/actions/auth/login/getSSOProvider.js +21 -2
- package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
- package/dist/actions/auth/login/login.js +5 -4
- package/dist/actions/auth/login/login.js.map +1 -1
- package/dist/actions/build/buildApp.js +1 -0
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStaticFiles.js +2 -1
- package/dist/actions/build/buildStaticFiles.js.map +1 -1
- package/dist/actions/build/renderDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +2 -2
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/types.js.map +1 -1
- package/dist/actions/build/writeSanityRuntime.js +3 -2
- package/dist/actions/build/writeSanityRuntime.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +53 -3
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/findUserApplicationForStudio.js +10 -4
- package/dist/actions/deploy/findUserApplicationForStudio.js.map +1 -1
- package/dist/actions/dev/startAppDevServer.js +2 -0
- package/dist/actions/dev/startAppDevServer.js.map +1 -1
- package/dist/actions/init/git.js +5 -2
- package/dist/actions/init/git.js.map +1 -1
- package/dist/actions/init/remoteTemplate.js +3 -1
- package/dist/actions/init/remoteTemplate.js.map +1 -1
- package/dist/actions/init/templates/nextjs/index.js +1 -1
- package/dist/actions/init/templates/nextjs/index.js.map +1 -1
- package/dist/actions/manifest/extractAppManifest.js +3 -1
- package/dist/actions/manifest/extractAppManifest.js.map +1 -1
- package/dist/actions/telemetry/setConsent.js +6 -2
- package/dist/actions/telemetry/setConsent.js.map +1 -1
- package/dist/commands/datasets/alias/create.js +0 -4
- package/dist/commands/datasets/alias/create.js.map +1 -1
- package/dist/commands/datasets/alias/delete.js +1 -5
- package/dist/commands/datasets/alias/delete.js.map +1 -1
- package/dist/commands/datasets/alias/link.js +0 -4
- package/dist/commands/datasets/alias/link.js.map +1 -1
- package/dist/commands/datasets/alias/unlink.js +0 -4
- package/dist/commands/datasets/alias/unlink.js.map +1 -1
- package/dist/commands/datasets/copy.js +1 -1
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/datasets/import.js +34 -5
- package/dist/commands/datasets/import.js.map +1 -1
- package/dist/commands/deploy.js +3 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/init.js +10 -9
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +14 -2
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +6 -8
- package/dist/commands/logout.js.map +1 -1
- package/dist/hooks/prerun/setupTelemetry.js +1 -1
- package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
- package/dist/server/devServer.js +2 -1
- package/dist/server/devServer.js.map +1 -1
- package/dist/util/compareDependencyVersions.js +3 -1
- package/dist/util/compareDependencyVersions.js.map +1 -1
- package/dist/util/createExpiringConfig.js +0 -3
- package/dist/util/createExpiringConfig.js.map +1 -1
- package/dist/util/getCliVersion.js +3 -1
- package/dist/util/getCliVersion.js.map +1 -1
- package/dist/util/telemetry/logger.js +13 -0
- package/dist/util/telemetry/logger.js.map +1 -1
- package/oclif.manifest.json +103 -97
- package/package.json +26 -26
- package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js +0 -540
- package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js.map +0 -1
- package/dist/actions/graphql/__tests__/fixtures/test-studio.js +0 -1143
- package/dist/actions/graphql/__tests__/fixtures/test-studio.js.map +0 -1
- package/dist/actions/graphql/__tests__/fixtures/union-refs.js +0 -591
- package/dist/actions/graphql/__tests__/fixtures/union-refs.js.map +0 -1
- package/dist/actions/graphql/__tests__/helpers.js +0 -23
- package/dist/actions/graphql/__tests__/helpers.js.map +0 -1
- package/dist/actions/manifest/__tests__/resolveSchemaIcon.test.js +0 -157
- package/dist/actions/manifest/__tests__/resolveSchemaIcon.test.js.map +0 -1
- package/dist/actions/manifest/__tests__/testHelpers.js +0 -21
- package/dist/actions/manifest/__tests__/testHelpers.js.map +0 -1
- package/dist/actions/media/__tests__/createMockClient.js +0 -32
- package/dist/actions/media/__tests__/createMockClient.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/telemetry/setConsent.ts"],"sourcesContent":["import {type ConsentInformation, getGlobalCliClient, getUserConfig, isCi} from '@sanity/cli-core'\n\nimport {TELEMETRY_CONSENT_CONFIG_KEY, type ValidApiConsentStatus} from '../../services/telemetry.js'\nimport {isTrueish} from './isTrueish.js'\nimport {resolveConsent} from './resolveConsent.js'\nimport {telemetryDebug} from './telemetryDebug.js'\n\ntype SettableConsentStatus = Extract<ValidApiConsentStatus, 'denied' | 'granted'>\n\n// Type guard for error objects with HTTP properties\nfunction isHttpError(error: unknown): error is {\n message: string\n response?: {body?: {message?: string}}\n statusCode: number\n} {\n return typeof error === 'object' && error !== null && 'statusCode' in error && 'message' in error\n}\n\ninterface SetConsentOptions {\n status: SettableConsentStatus\n}\n\ninterface SetConsentResult {\n changed: boolean\n currentStatus: ConsentInformation\n message: string\n}\n\nexport async function setConsent({status}: SetConsentOptions): Promise<SetConsentResult> {\n telemetryDebug('Setting telemetry consent to \"%s\"', status)\n\n // Check current consent status first\n const currentConsent = await resolveConsent()\n\n // Handle various blocking conditions\n if (isCi()) {\n return {\n changed: false,\n currentStatus: currentConsent,\n message: 'Cannot set telemetry consent in CI environment',\n }\n }\n\n if (isTrueish(process.env.DO_NOT_TRACK) && status === 'granted') {\n return {\n changed: false,\n currentStatus: currentConsent,\n message:\n 'Cannot enable telemetry while DO_NOT_TRACK environment variable is set. Unset DO_NOT_TRACK to enable telemetry.',\n }\n }\n\n // Check if already at desired status\n if (currentConsent.status === status) {\n const message =\n status === 'granted'\n ? \"You've already enabled telemetry data collection to help us improve Sanity.\"\n : currentConsent.reason === 'localOverride'\n ? \"You've already opted out of telemetry data collection.\\nNo data is collected from your machine.\\n\\nUsing DO_NOT_TRACK environment variable.\"\n : \"You've already opted out of telemetry data collection.\\nNo data is collected from your Sanity account.\"\n\n return {\n changed: false,\n currentStatus: currentConsent,\n message,\n }\n }\n\n // User must be logged in to set consent\n if (currentConsent.status === 'undetermined' && currentConsent.reason === 'unauthenticated') {\n return {\n changed: false,\n currentStatus: currentConsent,\n message: 'You need to log in first to set telemetry preferences.',\n }\n }\n\n try {\n const client = await getGlobalCliClient({\n apiVersion: '2023-12-18',\n requireUser: true,\n })\n\n const uri = `/users/me/consents/telemetry/status/${status}`\n telemetryDebug('Sending telemetry consent status to %s', uri)\n\n await client.request({\n method: 'PUT',\n uri,\n })\n\n // Clear cached telemetry consent\n const userConfig = getUserConfig()\n userConfig.delete(TELEMETRY_CONSENT_CONFIG_KEY)\n\n const successMessage =\n status === 'granted'\n ? \"You've now enabled telemetry data collection to help us improve Sanity.\"\n : \"You've opted out of telemetry data collection.\\nNo data will be collected from your Sanity account.\"\n\n const newConsent = await resolveConsent()\n\n return {\n changed: true,\n currentStatus: newConsent,\n message: successMessage,\n }\n } catch (err: unknown) {\n const errorMessage = `Failed to ${status === 'granted' ? 'enable' : 'disable'} telemetry`\n\n if (isHttpError(err) && err.statusCode === 403) {\n // Create a new error without stack trace from original error\n const message = err.response?.body?.message\n ? `${errorMessage}: ${err.response.body.message}`\n : errorMessage\n throw new Error(message)\n }\n\n if (isHttpError(err)) {\n // For other errors, preserve the original error but update the message\n err.message = err.response?.body?.message\n ? `${errorMessage}: ${err.response.body.message}`\n : errorMessage\n throw err\n }\n\n // For non-HTTP errors, wrap in a new error\n throw new Error(errorMessage)\n }\n}\n"],"names":["getGlobalCliClient","getUserConfig","isCi","TELEMETRY_CONSENT_CONFIG_KEY","isTrueish","resolveConsent","telemetryDebug","isHttpError","error","setConsent","status","currentConsent","changed","currentStatus","message","process","env","DO_NOT_TRACK","reason","client","apiVersion","requireUser","uri","request","method","userConfig","delete","successMessage","newConsent","err","errorMessage","statusCode","response","body","Error"],"mappings":"AAAA,SAAiCA,kBAAkB,EAAEC,aAAa,EAAEC,IAAI,QAAO,mBAAkB;AAEjG,SAAQC,4BAA4B,QAAmC,8BAA6B;AACpG,SAAQC,SAAS,QAAO,iBAAgB;AACxC,SAAQC,cAAc,QAAO,sBAAqB;AAClD,SAAQC,cAAc,QAAO,sBAAqB;AAIlD,oDAAoD;AACpD,SAASC,YAAYC,KAAc;IAKjC,OAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,gBAAgBA,SAAS,aAAaA;AAC9F;AAYA,OAAO,eAAeC,WAAW,EAACC,MAAM,EAAoB;IAC1DJ,eAAe,qCAAqCI;IAEpD,qCAAqC;IACrC,MAAMC,iBAAiB,MAAMN;IAE7B,qCAAqC;IACrC,IAAIH,QAAQ;QACV,OAAO;YACLU,SAAS;YACTC,eAAeF;YACfG,SAAS;QACX;IACF;IAEA,IAAIV,UAAUW,QAAQC,GAAG,CAACC,YAAY,KAAKP,WAAW,WAAW;QAC/D,OAAO;YACLE,SAAS;YACTC,eAAeF;YACfG,SACE;QACJ;IACF;IAEA,qCAAqC;IACrC,IAAIH,eAAeD,MAAM,KAAKA,QAAQ;QACpC,MAAMI,UACJJ,WAAW,YACP,gFACAC,eAAeO,MAAM,KAAK,kBACxB,gJACA;QAER,OAAO;YACLN,SAAS;YACTC,eAAeF;YACfG;QACF;IACF;IAEA,wCAAwC;IACxC,IAAIH,eAAeD,MAAM,KAAK,kBAAkBC,eAAeO,MAAM,KAAK,mBAAmB;QAC3F,OAAO;YACLN,SAAS;YACTC,eAAeF;YACfG,SAAS;QACX;IACF;IAEA,IAAI;QACF,MAAMK,SAAS,MAAMnB,mBAAmB;YACtCoB,YAAY;YACZC,aAAa;QACf;QAEA,MAAMC,MAAM,CAAC,oCAAoC,EAAEZ,QAAQ;QAC3DJ,eAAe,0CAA0CgB;QAEzD,MAAMH,OAAOI,OAAO,CAAC;YACnBC,QAAQ;YACRF;QACF;QAEA,iCAAiC;QACjC,MAAMG,aAAaxB;QACnBwB,WAAWC,MAAM,CAACvB;QAElB,MAAMwB,iBACJjB,WAAW,YACP,4EACA;QAEN,MAAMkB,aAAa,MAAMvB;QAEzB,OAAO;YACLO,SAAS;YACTC,eAAee;YACfd,SAASa;QACX;IACF,EAAE,OAAOE,KAAc;QACrB,MAAMC,eAAe,CAAC,UAAU,EAAEpB,WAAW,YAAY,WAAW,UAAU,UAAU,CAAC;QAEzF,IAAIH,YAAYsB,QAAQA,IAAIE,UAAU,KAAK,KAAK;YAC9C,6DAA6D;YAC7D,MAAMjB,UAAUe,IAAIG,QAAQ,EAAEC,MAAMnB,UAChC,GAAGgB,aAAa,EAAE,EAAED,IAAIG,QAAQ,CAACC,IAAI,CAACnB,OAAO,EAAE,GAC/CgB;YACJ,MAAM,IAAII,MAAMpB;
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/telemetry/setConsent.ts"],"sourcesContent":["import {type ConsentInformation, getGlobalCliClient, getUserConfig, isCi} from '@sanity/cli-core'\n\nimport {TELEMETRY_CONSENT_CONFIG_KEY, type ValidApiConsentStatus} from '../../services/telemetry.js'\nimport {isTrueish} from './isTrueish.js'\nimport {resolveConsent} from './resolveConsent.js'\nimport {telemetryDebug} from './telemetryDebug.js'\n\ntype SettableConsentStatus = Extract<ValidApiConsentStatus, 'denied' | 'granted'>\n\n// Type guard for error objects with HTTP properties\nfunction isHttpError(error: unknown): error is {\n message: string\n response?: {body?: {message?: string}}\n statusCode: number\n} {\n return typeof error === 'object' && error !== null && 'statusCode' in error && 'message' in error\n}\n\ninterface SetConsentOptions {\n status: SettableConsentStatus\n}\n\ninterface SetConsentResult {\n changed: boolean\n currentStatus: ConsentInformation\n message: string\n}\n\nexport async function setConsent({status}: SetConsentOptions): Promise<SetConsentResult> {\n telemetryDebug('Setting telemetry consent to \"%s\"', status)\n\n // Check current consent status first\n const currentConsent = await resolveConsent()\n\n // Handle various blocking conditions\n if (isCi()) {\n return {\n changed: false,\n currentStatus: currentConsent,\n message: 'Cannot set telemetry consent in CI environment',\n }\n }\n\n if (isTrueish(process.env.DO_NOT_TRACK) && status === 'granted') {\n return {\n changed: false,\n currentStatus: currentConsent,\n message:\n 'Cannot enable telemetry while DO_NOT_TRACK environment variable is set. Unset DO_NOT_TRACK to enable telemetry.',\n }\n }\n\n // Check if already at desired status\n if (currentConsent.status === status) {\n const message =\n status === 'granted'\n ? \"You've already enabled telemetry data collection to help us improve Sanity.\"\n : currentConsent.reason === 'localOverride'\n ? \"You've already opted out of telemetry data collection.\\nNo data is collected from your machine.\\n\\nUsing DO_NOT_TRACK environment variable.\"\n : \"You've already opted out of telemetry data collection.\\nNo data is collected from your Sanity account.\"\n\n return {\n changed: false,\n currentStatus: currentConsent,\n message,\n }\n }\n\n // User must be logged in to set consent\n if (currentConsent.status === 'undetermined' && currentConsent.reason === 'unauthenticated') {\n return {\n changed: false,\n currentStatus: currentConsent,\n message: 'You need to log in first to set telemetry preferences.',\n }\n }\n\n try {\n const client = await getGlobalCliClient({\n apiVersion: '2023-12-18',\n requireUser: true,\n })\n\n const uri = `/users/me/consents/telemetry/status/${status}`\n telemetryDebug('Sending telemetry consent status to %s', uri)\n\n await client.request({\n method: 'PUT',\n uri,\n })\n\n // Clear cached telemetry consent\n const userConfig = getUserConfig()\n userConfig.delete(TELEMETRY_CONSENT_CONFIG_KEY)\n\n const successMessage =\n status === 'granted'\n ? \"You've now enabled telemetry data collection to help us improve Sanity.\"\n : \"You've opted out of telemetry data collection.\\nNo data will be collected from your Sanity account.\"\n\n const newConsent = await resolveConsent()\n\n return {\n changed: true,\n currentStatus: newConsent,\n message: successMessage,\n }\n } catch (err: unknown) {\n const errorMessage = `Failed to ${status === 'granted' ? 'enable' : 'disable'} telemetry`\n\n if (isHttpError(err) && err.statusCode === 403) {\n // Create a new error without stack trace from original error\n const message = err.response?.body?.message\n ? `${errorMessage}: ${err.response.body.message}`\n : errorMessage\n throw new Error(message, {cause: err})\n }\n\n if (isHttpError(err)) {\n // For other errors, preserve the original error but update the message\n err.message = err.response?.body?.message\n ? `${errorMessage}: ${err.response.body.message}`\n : errorMessage\n throw err\n }\n\n // For non-HTTP errors, wrap in a new error\n throw new Error(errorMessage, {cause: err})\n }\n}\n"],"names":["getGlobalCliClient","getUserConfig","isCi","TELEMETRY_CONSENT_CONFIG_KEY","isTrueish","resolveConsent","telemetryDebug","isHttpError","error","setConsent","status","currentConsent","changed","currentStatus","message","process","env","DO_NOT_TRACK","reason","client","apiVersion","requireUser","uri","request","method","userConfig","delete","successMessage","newConsent","err","errorMessage","statusCode","response","body","Error","cause"],"mappings":"AAAA,SAAiCA,kBAAkB,EAAEC,aAAa,EAAEC,IAAI,QAAO,mBAAkB;AAEjG,SAAQC,4BAA4B,QAAmC,8BAA6B;AACpG,SAAQC,SAAS,QAAO,iBAAgB;AACxC,SAAQC,cAAc,QAAO,sBAAqB;AAClD,SAAQC,cAAc,QAAO,sBAAqB;AAIlD,oDAAoD;AACpD,SAASC,YAAYC,KAAc;IAKjC,OAAO,OAAOA,UAAU,YAAYA,UAAU,QAAQ,gBAAgBA,SAAS,aAAaA;AAC9F;AAYA,OAAO,eAAeC,WAAW,EAACC,MAAM,EAAoB;IAC1DJ,eAAe,qCAAqCI;IAEpD,qCAAqC;IACrC,MAAMC,iBAAiB,MAAMN;IAE7B,qCAAqC;IACrC,IAAIH,QAAQ;QACV,OAAO;YACLU,SAAS;YACTC,eAAeF;YACfG,SAAS;QACX;IACF;IAEA,IAAIV,UAAUW,QAAQC,GAAG,CAACC,YAAY,KAAKP,WAAW,WAAW;QAC/D,OAAO;YACLE,SAAS;YACTC,eAAeF;YACfG,SACE;QACJ;IACF;IAEA,qCAAqC;IACrC,IAAIH,eAAeD,MAAM,KAAKA,QAAQ;QACpC,MAAMI,UACJJ,WAAW,YACP,gFACAC,eAAeO,MAAM,KAAK,kBACxB,gJACA;QAER,OAAO;YACLN,SAAS;YACTC,eAAeF;YACfG;QACF;IACF;IAEA,wCAAwC;IACxC,IAAIH,eAAeD,MAAM,KAAK,kBAAkBC,eAAeO,MAAM,KAAK,mBAAmB;QAC3F,OAAO;YACLN,SAAS;YACTC,eAAeF;YACfG,SAAS;QACX;IACF;IAEA,IAAI;QACF,MAAMK,SAAS,MAAMnB,mBAAmB;YACtCoB,YAAY;YACZC,aAAa;QACf;QAEA,MAAMC,MAAM,CAAC,oCAAoC,EAAEZ,QAAQ;QAC3DJ,eAAe,0CAA0CgB;QAEzD,MAAMH,OAAOI,OAAO,CAAC;YACnBC,QAAQ;YACRF;QACF;QAEA,iCAAiC;QACjC,MAAMG,aAAaxB;QACnBwB,WAAWC,MAAM,CAACvB;QAElB,MAAMwB,iBACJjB,WAAW,YACP,4EACA;QAEN,MAAMkB,aAAa,MAAMvB;QAEzB,OAAO;YACLO,SAAS;YACTC,eAAee;YACfd,SAASa;QACX;IACF,EAAE,OAAOE,KAAc;QACrB,MAAMC,eAAe,CAAC,UAAU,EAAEpB,WAAW,YAAY,WAAW,UAAU,UAAU,CAAC;QAEzF,IAAIH,YAAYsB,QAAQA,IAAIE,UAAU,KAAK,KAAK;YAC9C,6DAA6D;YAC7D,MAAMjB,UAAUe,IAAIG,QAAQ,EAAEC,MAAMnB,UAChC,GAAGgB,aAAa,EAAE,EAAED,IAAIG,QAAQ,CAACC,IAAI,CAACnB,OAAO,EAAE,GAC/CgB;YACJ,MAAM,IAAII,MAAMpB,SAAS;gBAACqB,OAAON;YAAG;QACtC;QAEA,IAAItB,YAAYsB,MAAM;YACpB,uEAAuE;YACvEA,IAAIf,OAAO,GAAGe,IAAIG,QAAQ,EAAEC,MAAMnB,UAC9B,GAAGgB,aAAa,EAAE,EAAED,IAAIG,QAAQ,CAACC,IAAI,CAACnB,OAAO,EAAE,GAC/CgB;YACJ,MAAMD;QACR;QAEA,2CAA2C;QAC3C,MAAM,IAAIK,MAAMJ,cAAc;YAACK,OAAON;QAAG;IAC3C;AACF"}
|
|
@@ -38,10 +38,6 @@ export class CreateAliasCommand extends SanityCommand {
|
|
|
38
38
|
{
|
|
39
39
|
command: '<%= config.bin %> <%= command.id %> conference conf-2025',
|
|
40
40
|
description: 'Create alias "conference" linked to "conf-2025" dataset'
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
command: '<%= config.bin %> <%= command.id %> ~conference conf-2025',
|
|
44
|
-
description: 'Create alias with explicit ~ prefix'
|
|
45
41
|
}
|
|
46
42
|
];
|
|
47
43
|
static flags = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to create dataset alias in',\n semantics: 'override',\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:alias:create']\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","getProjectIdFlag","createAliasDebug","CreateAliasCommand","args","aliasName","string","description","required","targetDataset","examples","command","flags","semantics","hiddenAliases","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":"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"}
|
|
@@ -20,10 +20,6 @@ export class DeleteAliasCommand extends SanityCommand {
|
|
|
20
20
|
command: '<%= config.bin %> <%= command.id %> conference',
|
|
21
21
|
description: 'Delete alias named "conference" with confirmation prompt'
|
|
22
22
|
},
|
|
23
|
-
{
|
|
24
|
-
command: '<%= config.bin %> <%= command.id %> ~conference',
|
|
25
|
-
description: 'Delete alias with explicit ~ prefix'
|
|
26
|
-
},
|
|
27
23
|
{
|
|
28
24
|
command: '<%= config.bin %> <%= command.id %> conference --force',
|
|
29
25
|
description: 'Delete alias named "conference" without confirmation prompt'
|
|
@@ -77,7 +73,7 @@ export class DeleteAliasCommand extends SanityCommand {
|
|
|
77
73
|
if (force) {
|
|
78
74
|
this.warn(`'--force' used: skipping confirmation, deleting alias "${displayName}"`);
|
|
79
75
|
} else {
|
|
80
|
-
await this.confirmDeletion(
|
|
76
|
+
await this.confirmDeletion(apiName, existingAlias.datasetName);
|
|
81
77
|
}
|
|
82
78
|
await removeAlias(projectId, apiName);
|
|
83
79
|
this.log('Dataset alias deleted successfully');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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 %>
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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 --force',\n description: 'Delete alias named \"conference\" without confirmation prompt',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to delete dataset alias from',\n semantics: 'override',\n }),\n force: Flags.boolean({\n description: 'Skip confirmation prompt and delete immediately',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:alias:delete']\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`, {\n exit: 1,\n })\n }\n\n if (force) {\n this.warn(`'--force' used: skipping confirmation, deleting alias \"${displayName}\"`)\n } else {\n await this.confirmDeletion(apiName, 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","getProjectIdFlag","deleteAliasDebug","DeleteAliasCommand","args","aliasName","string","description","required","examples","command","flags","semantics","force","boolean","hiddenAliases","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":"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,gBAAgB,QAAO,uCAAsC;AACrE,SAAQC,WAAW,EAAEC,WAAW,QAAO,sCAAqC;AAC5E,SAAQC,gBAAgB,QAAO,+BAA8B;AAE7D,MAAMC,mBAAmBR,SAAS;AAElC,OAAO,MAAMS,2BAA2BV;IACtC,OAAgBW,OAAO;QACrBC,WAAWd,KAAKe,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;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtB,GAAGV,iBAAiB;YAClBM,aAAa;YACbK,WAAW;QACb,EAAE;QACFC,OAAOrB,MAAMsB,OAAO,CAAC;YACnBP,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBO,gBAA0B;QAAC;KAAuB,CAAA;IAElE,MAAaC,MAAqB;QAChC,MAAM,EAACZ,IAAI,EAAEO,KAAK,EAAC,GAAG,MAAM,IAAI,CAACM,KAAK,CAACd;QACvC,MAAM,EAACU,KAAK,EAAC,GAAGF;QAEhB,MAAMO,YAAY,MAAM,IAAI,CAACC,YAAY,CAAC;YACxCC,UAAU,IACRtB,iBAAiB;oBACfuB,qBAAqB;wBACnB;4BAACC,OAAO;4BAAQC,YAAY;wBAAyB;wBACrD;4BAACD,OAAO;4BAAUC,YAAY;wBAAyB;qBACxD;gBACH;QACJ;QAEA,MAAM,EAACC,OAAO,EAAEC,WAAW,EAAC,GAAG7B,iBAAiBQ,KAAKC,SAAS;QAE9D,MAAMqB,YAAY7B,yBAAyB2B;QAC3C,IAAIE,WAAW;YACb,IAAI,CAACC,KAAK,CAACD,WAAW;gBAACE,MAAM;YAAC;QAChC;QAEA,IAAI;YACF,MAAMC,UAAU,MAAM9B,YAAYmB;YAClC,MAAMY,gBAAgBD,QAAQE,IAAI,CAAC,CAACC,QAAUA,MAAMC,IAAI,KAAKT;YAE7D,IAAI,CAACM,eAAe;gBAClB,IAAI,CAACH,KAAK,CAAC,CAAC,eAAe,EAAEF,YAAY,gBAAgB,CAAC,EAAE;oBAC1DG,MAAM;gBACR;YACF;YAEA,IAAIf,OAAO;gBACT,IAAI,CAACqB,IAAI,CAAC,CAAC,uDAAuD,EAAET,YAAY,CAAC,CAAC;YACpF,OAAO;gBACL,MAAM,IAAI,CAACU,eAAe,CAACX,SAASM,cAAcM,WAAW;YAC/D;YAEA,MAAMpC,YAAYkB,WAAWM;YAE7B,IAAI,CAACa,GAAG,CAAC;QACX,EAAE,OAAOV,OAAO;YACd,MAAMW,eAAeX,iBAAiBY,QAAQZ,MAAMa,OAAO,GAAGC,OAAOd;YAErEzB,iBAAiB,CAAC,6BAA6B,EAAEE,KAAKC,SAAS,EAAE,EAAEsB;YACnE,IAAI,CAACA,KAAK,CAAC,CAAC,+BAA+B,EAAEW,cAAc,EAAE;gBAACV,MAAM;YAAC;QACvE;IACF;IAEA,MAAcO,gBAAgB9B,SAAiB,EAAEqC,aAA6B,EAAiB;QAC7F,MAAMF,UAAUE,gBACZ,CAAC,gCAAgC,EAAEA,cAAc,yHAAyH,CAAC,GAC3K,CAAC,uHAAuH,CAAC;QAE7H,MAAM/C,MAAM;YACV6C;YACAG,UAAU,CAAChD;gBACT,MAAMiD,UAAUjD,MAAMkD,IAAI,GAAGC,OAAO,CAAC,MAAM;gBAC3C,OAAOF,YAAYvC,aAAa;YAClC;QACF;IACF;AACF"}
|
|
@@ -36,10 +36,6 @@ export class LinkAliasCommand extends SanityCommand {
|
|
|
36
36
|
command: '<%= config.bin %> <%= command.id %> conference conf-2025',
|
|
37
37
|
description: 'Link alias "conference" to "conf-2025" dataset'
|
|
38
38
|
},
|
|
39
|
-
{
|
|
40
|
-
command: '<%= config.bin %> <%= command.id %> ~conference conf-2025',
|
|
41
|
-
description: 'Link alias with explicit ~ prefix'
|
|
42
|
-
},
|
|
43
39
|
{
|
|
44
40
|
command: '<%= config.bin %> <%= command.id %> conference conf-2025 --force',
|
|
45
41
|
description: 'Force link without confirmation (skip relink prompt)'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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 ...getProjectIdFlag({\n description: 'Project ID to link dataset alias in',\n semantics: 'override',\n }),\n force: Flags.boolean({\n description: 'Skip confirmation prompt when relinking existing alias',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:alias:link']\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","getProjectIdFlag","linkAliasDebug","LinkAliasCommand","args","aliasName","string","description","required","targetDataset","examples","command","flags","semantics","force","boolean","hiddenAliases","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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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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 --force',\n description: 'Force link without confirmation (skip relink prompt)',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to link dataset alias in',\n semantics: 'override',\n }),\n force: Flags.boolean({\n description: 'Skip confirmation prompt when relinking existing alias',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:alias:link']\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","getProjectIdFlag","linkAliasDebug","LinkAliasCommand","args","aliasName","string","description","required","targetDataset","examples","command","flags","semantics","force","boolean","hiddenAliases","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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"}
|
|
@@ -25,10 +25,6 @@ export class UnlinkAliasCommand extends SanityCommand {
|
|
|
25
25
|
command: '<%= config.bin %> <%= command.id %> conference',
|
|
26
26
|
description: 'Unlink alias "conference" with confirmation prompt'
|
|
27
27
|
},
|
|
28
|
-
{
|
|
29
|
-
command: '<%= config.bin %> <%= command.id %> ~conference',
|
|
30
|
-
description: 'Unlink alias with explicit ~ prefix'
|
|
31
|
-
},
|
|
32
28
|
{
|
|
33
29
|
command: '<%= config.bin %> <%= command.id %> conference --force',
|
|
34
30
|
description: 'Unlink alias "conference" without confirmation prompt'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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 %>
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/datasets/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 {getProjectIdFlag} 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 --force',\n description: 'Unlink alias \"conference\" without confirmation prompt',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to unlink dataset alias in',\n semantics: 'override',\n }),\n force: Flags.boolean({\n description: 'Skip confirmation prompt and unlink immediately',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:alias:unlink']\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","getProjectIdFlag","unlinkAliasDebug","UnlinkAliasCommand","args","aliasName","string","description","required","examples","command","flags","semantics","force","boolean","hiddenAliases","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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"}
|
|
@@ -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 {SanityCommand, subdebug} from '@sanity/cli-core'\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 {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 =\n 'Manages dataset copying, including starting a new copy job, listing copy jobs and following the progress of a running copy job'\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 %> --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-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 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 table.printTable()\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 this.error('Please supply a valid jobId', {exit: 1})\n }\n\n try {\n await this.subscribeToProgress(projectId, jobId)\n this.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 this.error(`Failed to attach to copy job: ${message}`, {exit: 1})\n }\n }\n\n private async handleCopyMode(\n projectId: string,\n args: {source?: string; target?: string},\n flags: {detach?: boolean; 'skip-history'?: boolean},\n ): Promise<void> {\n copyDatasetDebug('Starting copy mode')\n\n const skipHistory = Boolean(flags['skip-history'])\n\n // Get and validate source dataset\n let sourceDataset = args.source\n if (sourceDataset) {\n const nameError = validateDatasetName(sourceDataset)\n if (nameError) {\n this.error(nameError, {exit: 1})\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 this.error(`Failed to fetch datasets: ${message}`, {exit: 1})\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 this.error(`Source dataset \"${sourceDataset}\" doesn't exist`, {exit: 1})\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 this.error(nameError, {exit: 1})\n }\n } else {\n targetDataset = await promptForDatasetName({\n message: 'Target dataset name:',\n })\n }\n\n if (datasetNames.has(targetDataset)) {\n this.error(`Target dataset \"${targetDataset}\" already exists`, {exit: 1})\n }\n\n // Start the copy job\n try {\n this.log(\n `Copying dataset ${styleText('green', sourceDataset)} to ${styleText('green', targetDataset)}...`,\n )\n\n if (!skipHistory) {\n this.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 const response = await copyDataset({\n projectId,\n skipHistory,\n sourceDataset,\n targetDataset,\n })\n\n this.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.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 this.error(`Dataset copying failed: ${message}`, {exit: 1})\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.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 this.error(`Failed to list dataset copy jobs: ${message}`, {exit: 1})\n }\n }\n\n private async subscribeToProgress(projectId: string, jobId: string): Promise<void> {\n let currentProgress = 0\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 currentProgress = event.progress\n }\n spin.text = `Copy in progress: ${currentProgress}%`\n },\n })\n\n process.once('SIGINT', sigintHandler)\n })\n }\n}\n"],"names":["styleText","Args","Flags","exit","SanityCommand","subdebug","spinner","Table","formatDistance","formatDistanceToNow","parseISO","validateDatasetName","promptForDataset","promptForDatasetName","promptForProject","copyDataset","followCopyJobProgress","listDatasetCopyJobs","listDatasets","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","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","printTable","jobId","trim","error","subscribeToProgress","log","message","Error","String","skipHistory","Boolean","nameError","datasetsResponse","datasetNames","Set","map","ds","datasets","has","response","length","currentProgress","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 {SanityCommand, subdebug} from '@sanity/cli-core'\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 {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 =\n 'Manages dataset copying, including starting a new copy job, listing copy jobs and following the progress of a running copy job'\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 %> --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-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 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 table.printTable()\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 this.error('Please supply a valid jobId', {exit: 1})\n }\n\n try {\n await this.subscribeToProgress(projectId, jobId)\n this.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 this.error(`Failed to attach to copy job: ${message}`, {exit: 1})\n }\n }\n\n private async handleCopyMode(\n projectId: string,\n args: {source?: string; target?: string},\n flags: {detach?: boolean; 'skip-history'?: boolean},\n ): Promise<void> {\n copyDatasetDebug('Starting copy mode')\n\n const skipHistory = Boolean(flags['skip-history'])\n\n // Get and validate source dataset\n let sourceDataset = args.source\n if (sourceDataset) {\n const nameError = validateDatasetName(sourceDataset)\n if (nameError) {\n this.error(nameError, {exit: 1})\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 this.error(`Failed to fetch datasets: ${message}`, {exit: 1})\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 this.error(`Source dataset \"${sourceDataset}\" doesn't exist`, {exit: 1})\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 this.error(nameError, {exit: 1})\n }\n } else {\n targetDataset = await promptForDatasetName({\n message: 'Target dataset name:',\n })\n }\n\n if (datasetNames.has(targetDataset)) {\n this.error(`Target dataset \"${targetDataset}\" already exists`, {exit: 1})\n }\n\n // Start the copy job\n try {\n this.log(\n `Copying dataset ${styleText('green', sourceDataset)} to ${styleText('green', targetDataset)}...`,\n )\n\n if (!skipHistory) {\n this.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 const response = await copyDataset({\n projectId,\n skipHistory,\n sourceDataset,\n targetDataset,\n })\n\n this.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.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 this.error(`Dataset copying failed: ${message}`, {exit: 1})\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.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 this.error(`Failed to list dataset copy jobs: ${message}`, {exit: 1})\n }\n }\n\n private async subscribeToProgress(projectId: string, jobId: string): Promise<void> {\n let currentProgress = 0\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 currentProgress = event.progress\n }\n spin.text = `Copy in progress: ${currentProgress}%`\n },\n })\n\n process.once('SIGINT', sigintHandler)\n })\n }\n}\n"],"names":["styleText","Args","Flags","exit","SanityCommand","subdebug","spinner","Table","formatDistance","formatDistanceToNow","parseISO","validateDatasetName","promptForDataset","promptForDatasetName","promptForProject","copyDataset","followCopyJobProgress","listDatasetCopyJobs","listDatasets","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","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","printTable","jobId","trim","error","subscribeToProgress","log","message","Error","String","skipHistory","Boolean","nameError","datasetsResponse","datasetNames","Set","map","ds","datasets","has","response","length","currentProgress","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,13 +1,17 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { Args, Flags } from '@oclif/core';
|
|
4
|
-
import { getProjectCliClient, SanityCommand } from '@sanity/cli-core';
|
|
4
|
+
import { getProjectCliClient, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
5
5
|
import { createRequester } from '@sanity/cli-core/request';
|
|
6
6
|
import { spinner } from '@sanity/cli-core/ux';
|
|
7
7
|
import { sanityImport } from '@sanity/import';
|
|
8
8
|
import prettyMs from 'pretty-ms';
|
|
9
|
+
import { NEW_DATASET_VALUE, promptForDataset } from '../../prompts/promptForDataset.js';
|
|
10
|
+
import { promptForDatasetName } from '../../prompts/promptForDatasetName.js';
|
|
9
11
|
import { promptForProject } from '../../prompts/promptForProject.js';
|
|
12
|
+
import { createDataset, listDatasets } from '../../services/datasets.js';
|
|
10
13
|
import { getDatasetFlag, getProjectIdFlag } from '../../util/sharedFlags.js';
|
|
14
|
+
const importDebug = subdebug('dataset:import');
|
|
11
15
|
function getAssetsBase(source) {
|
|
12
16
|
if (/^https?:\/\//i.test(source) || source === '-') {
|
|
13
17
|
return undefined;
|
|
@@ -35,7 +39,9 @@ async function getUriStream(uri) {
|
|
|
35
39
|
});
|
|
36
40
|
return response.body;
|
|
37
41
|
} catch (err) {
|
|
38
|
-
throw new Error(`Error fetching source:\n${err.message}
|
|
42
|
+
throw new Error(`Error fetching source:\n${err.message}`, {
|
|
43
|
+
cause: err
|
|
44
|
+
});
|
|
39
45
|
}
|
|
40
46
|
}
|
|
41
47
|
function getPercentage(opts) {
|
|
@@ -163,11 +169,34 @@ export class ImportDatasetCommand extends SanityCommand {
|
|
|
163
169
|
if (targetDatasetArg && !datasetFlag) {
|
|
164
170
|
this.warn('Positional dataset argument is deprecated. Use the --dataset flag instead: --dataset <name>');
|
|
165
171
|
}
|
|
166
|
-
|
|
172
|
+
let dataset = datasetFlag ?? targetDatasetArg;
|
|
167
173
|
if (!dataset) {
|
|
168
|
-
this.
|
|
169
|
-
|
|
174
|
+
if (this.isUnattended()) {
|
|
175
|
+
this.error('Missing dataset. Use the --dataset flag to specify a dataset: --dataset <name>', {
|
|
176
|
+
exit: 1
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
const datasets = await listDatasets(projectId);
|
|
180
|
+
dataset = await promptForDataset({
|
|
181
|
+
allowCreation: true,
|
|
182
|
+
datasets
|
|
170
183
|
});
|
|
184
|
+
if (dataset === NEW_DATASET_VALUE) {
|
|
185
|
+
const newDatasetName = await promptForDatasetName();
|
|
186
|
+
try {
|
|
187
|
+
await createDataset({
|
|
188
|
+
datasetName: newDatasetName,
|
|
189
|
+
projectId
|
|
190
|
+
});
|
|
191
|
+
dataset = newDatasetName;
|
|
192
|
+
} catch (error) {
|
|
193
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
194
|
+
importDebug(`Failed to create dataset ${newDatasetName}: ${message}`, error);
|
|
195
|
+
this.error(`Failed to create dataset ${newDatasetName}: ${message}`, {
|
|
196
|
+
exit: 1
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
171
200
|
}
|
|
172
201
|
let operation = 'create';
|
|
173
202
|
let releasesOperation = 'fail';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/datasets/import.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {sanityImport} from '@sanity/import'\nimport prettyMs from 'pretty-ms'\n\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\ninterface ProgressEvent {\n step: string\n\n current?: number\n total?: number\n update?: string\n}\n\nfunction getAssetsBase(source: string): string | undefined {\n if (/^https?:\\/\\//i.test(source) || source === '-') {\n return undefined\n }\n\n try {\n const fileStats = fs.statSync(source)\n const sourceIsFolder = fileStats.isDirectory()\n return sourceIsFolder ? source : path.dirname(source)\n } catch {\n return undefined\n }\n}\n\nasync function getUriStream(uri: string): Promise<NodeJS.ReadableStream> {\n const request = createRequester({\n middleware: {promise: {onlyBody: false}},\n })\n\n try {\n const response = (await request({stream: true, url: uri})) as {body: NodeJS.ReadableStream}\n return response.body\n } catch (err) {\n throw new Error(`Error fetching source:\\n${(err as Error).message}`)\n }\n}\n\nfunction getPercentage(opts: ProgressEvent): string {\n if (!opts.total) {\n return ''\n }\n\n const percent = Math.floor(((opts.current || 0) / opts.total) * 100)\n return `[${percent}%] `\n}\n\nexport class ImportDatasetCommand extends SanityCommand<typeof ImportDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Source file (use \"-\" for stdin)',\n required: true,\n }),\n targetDataset: Args.string({\n description: 'Target dataset (prefer --dataset flag instead)',\n required: false,\n }),\n }\n\n static override description = 'Import documents to a Sanity dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> -d staging my-dataset.ndjson',\n description: 'Import \"./my-dataset.ndjson\" into dataset \"staging\"',\n },\n {\n command: 'cat my-dataset.ndjson | <%= config.bin %> <%= command.id %> -d test -',\n description: 'Import into dataset \"test\" from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> -p projectId -d staging my-dataset.ndjson',\n description: 'Import with explicit project ID (overrides CLI configuration)',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -d staging -t someSecretToken my-dataset.ndjson',\n description: 'Import with an explicit token (e.g. for CI/CD)',\n },\n ]\n\n static override flags = {\n 'allow-assets-in-different-dataset': Flags.boolean({\n default: false,\n description: 'Allow asset documents to reference different project/dataset',\n }),\n 'allow-failing-assets': Flags.boolean({\n default: false,\n description: 'Skip assets that cannot be fetched/uploaded',\n }),\n 'allow-replacement-characters': Flags.boolean({\n default: false,\n description: 'Allow unicode replacement characters in imported documents',\n }),\n 'allow-system-documents': Flags.boolean({\n default: false,\n description: 'Imports system documents',\n }),\n 'asset-concurrency': Flags.integer({\n description: 'Number of parallel asset imports',\n }),\n ...getDatasetFlag({\n description: 'Dataset to import to',\n semantics: 'specify',\n }),\n missing: Flags.boolean({\n default: false,\n description: 'Skip documents that already exist',\n exclusive: ['replace'],\n }),\n ...getProjectIdFlag({\n description: 'Project ID to import to',\n semantics: 'override',\n }),\n project: Flags.string({\n deprecated: {to: 'project-id'},\n description: 'Project ID to import to',\n hidden: true,\n }),\n replace: Flags.boolean({\n default: false,\n description: 'Replace documents with the same IDs',\n exclusive: ['missing'],\n }),\n 'replace-assets': Flags.boolean({\n default: false,\n description: 'Skip reuse of existing assets',\n }),\n 'skip-cross-dataset-references': Flags.boolean({\n default: false,\n description: 'Skips references to other datasets',\n }),\n token: Flags.string({\n char: 't',\n description: 'Token to authenticate with',\n env: 'SANITY_IMPORT_TOKEN',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:import']\n\n private currentProgress?: ReturnType<typeof spinner>\n private currentStep?: string\n private spinInterval?: NodeJS.Timeout | null\n private stepStart?: number\n\n private static async getStream(source: string): Promise<NodeJS.ReadableStream> {\n if (/^https?:\\/\\//i.test(source)) {\n return getUriStream(source)\n }\n\n return source === '-' ? process.stdin : fs.createReadStream(source)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ImportDatasetCommand)\n\n const {\n 'allow-assets-in-different-dataset': allowAssetsInDifferentDataset,\n 'allow-failing-assets': allowFailingAssets,\n 'allow-replacement-characters': allowReplacementCharacters,\n 'allow-system-documents': allowSystemDocuments,\n 'asset-concurrency': assetConcurrency,\n dataset: datasetFlag,\n missing,\n replace,\n 'replace-assets': replaceAssets,\n 'skip-cross-dataset-references': skipCrossDatasetReferences,\n token,\n } = flags\n\n const projectId = await this.getProjectId({\n deprecatedFlagName: 'project',\n fallback: () => promptForProject({}),\n })\n\n const {source, targetDataset: targetDatasetArg} = args\n\n if (targetDatasetArg && !datasetFlag) {\n this.warn(\n 'Positional dataset argument is deprecated. Use the --dataset flag instead: --dataset <name>',\n )\n }\n\n const dataset = datasetFlag ?? targetDatasetArg\n if (!dataset) {\n this.error('Missing dataset. Use the --dataset flag to specify a dataset: --dataset <name>', {\n exit: 1,\n })\n }\n\n let operation: 'create' | 'createIfNotExists' | 'createOrReplace' = 'create'\n let releasesOperation: 'fail' | 'ignore' | 'replace' = 'fail'\n\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n releasesOperation = replace ? 'replace' : 'ignore'\n }\n\n const client = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n projectId,\n requireUser: true,\n ...(token ? {token} : {}),\n })\n\n try {\n const stream = await ImportDatasetCommand.getStream(source)\n const assetsBase = getAssetsBase(source)\n\n const importOptions = {\n allowAssetsInDifferentDataset,\n allowFailingAssets,\n allowReplacementCharacters,\n allowSystemDocuments,\n client,\n onProgress: this.onProgress.bind(this),\n operation,\n releasesOperation,\n replaceAssets,\n skipCrossDatasetReferences,\n tag: 'sanity.import',\n targetDataset: dataset,\n targetProjectId: projectId,\n ...(assetsBase ? {assetsBase} : {}),\n ...(assetConcurrency === undefined ? {} : {assetConcurrency}),\n }\n\n const {numDocs, warnings} = await sanityImport(stream as NodeJS.ReadableStream, importOptions)\n\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n this.currentProgress.text = `[100%] ${this.currentStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n }\n\n this.log('Done! Imported %d documents to dataset \"%s\"\\n', numDocs, dataset)\n this.printWarnings(warnings)\n } catch (err) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress) {\n this.currentProgress.fail()\n }\n\n if ((err as Error).name === 'ReplacementCharError') {\n this.error(\n `Import failed due to unicode replacement characters in the data.\\n${(err as Error).message}\\n\\nIf you are certain you want to proceed with the import despite potentially corrupt data, re-run the import with the \\`--allow-replacement-characters\\` flag set.`,\n {exit: 1},\n )\n } else {\n this.error((err as Error).stack || (err as Error).message, {exit: 1})\n }\n }\n }\n\n private onProgress(opts: ProgressEvent): void {\n const lengthComputable = opts.total\n const sameStep = opts.step === this.currentStep\n const percent = getPercentage(opts)\n\n if (lengthComputable && opts.total === opts.current && this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (sameStep && !lengthComputable) {\n return\n }\n\n if (sameStep) {\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }\n return\n }\n\n // Moved to a new step\n const prevStep = this.currentStep\n const prevStepStart = this.stepStart\n this.stepStart = Date.now()\n this.currentStep = opts.step\n\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress && this.currentProgress.succeed && prevStepStart) {\n const timeSpent = prettyMs(Date.now() - prevStepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `[100%] ${prevStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n\n this.currentProgress = spinner(`[0%] ${opts.step} (0.00s)`).start()\n\n if (!lengthComputable) {\n this.spinInterval = setInterval(() => {\n if (this.stepStart && this.currentProgress) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }, 60)\n }\n }\n\n private printWarnings(warnings: Array<{message: string; type?: string; url?: string}>): void {\n const assetFails = warnings.filter((warn) => warn.type === 'asset')\n\n if (assetFails.length === 0) {\n return\n }\n\n this.warn(`Failed to import the following ${assetFails.length > 1 ? 'assets' : 'asset'}:`)\n\n for (const warning of assetFails) {\n if (warning.url) {\n this.warn(` ${warning.url}`)\n }\n }\n }\n}\n"],"names":["fs","path","Args","Flags","getProjectCliClient","SanityCommand","createRequester","spinner","sanityImport","prettyMs","promptForProject","getDatasetFlag","getProjectIdFlag","getAssetsBase","source","test","undefined","fileStats","statSync","sourceIsFolder","isDirectory","dirname","getUriStream","uri","request","middleware","promise","onlyBody","response","stream","url","body","err","Error","message","getPercentage","opts","total","percent","Math","floor","current","ImportDatasetCommand","args","string","description","required","targetDataset","examples","command","flags","boolean","default","integer","semantics","missing","exclusive","project","deprecated","to","hidden","replace","token","char","env","hiddenAliases","currentProgress","currentStep","spinInterval","stepStart","getStream","process","stdin","createReadStream","run","parse","allowAssetsInDifferentDataset","allowFailingAssets","allowReplacementCharacters","allowSystemDocuments","assetConcurrency","dataset","datasetFlag","replaceAssets","skipCrossDatasetReferences","projectId","getProjectId","deprecatedFlagName","fallback","targetDatasetArg","warn","error","exit","operation","releasesOperation","client","apiVersion","requireUser","assetsBase","importOptions","onProgress","bind","tag","targetProjectId","numDocs","warnings","timeSpent","Date","now","secondsDecimalDigits","clearInterval","text","succeed","log","printWarnings","fail","name","stack","lengthComputable","sameStep","step","render","prevStep","prevStepStart","start","setInterval","assetFails","filter","type","length","warning"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/datasets/import.ts"],"sourcesContent":["import fs from 'node:fs'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {sanityImport} from '@sanity/import'\nimport prettyMs from 'pretty-ms'\n\nimport {NEW_DATASET_VALUE, promptForDataset} from '../../prompts/promptForDataset.js'\nimport {promptForDatasetName} from '../../prompts/promptForDatasetName.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {createDataset, listDatasets} from '../../services/datasets.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nconst importDebug = subdebug('dataset:import')\n\ninterface ProgressEvent {\n step: string\n\n current?: number\n total?: number\n update?: string\n}\n\nfunction getAssetsBase(source: string): string | undefined {\n if (/^https?:\\/\\//i.test(source) || source === '-') {\n return undefined\n }\n\n try {\n const fileStats = fs.statSync(source)\n const sourceIsFolder = fileStats.isDirectory()\n return sourceIsFolder ? source : path.dirname(source)\n } catch {\n return undefined\n }\n}\n\nasync function getUriStream(uri: string): Promise<NodeJS.ReadableStream> {\n const request = createRequester({\n middleware: {promise: {onlyBody: false}},\n })\n\n try {\n const response = (await request({stream: true, url: uri})) as {body: NodeJS.ReadableStream}\n return response.body\n } catch (err) {\n throw new Error(`Error fetching source:\\n${(err as Error).message}`, {cause: err})\n }\n}\n\nfunction getPercentage(opts: ProgressEvent): string {\n if (!opts.total) {\n return ''\n }\n\n const percent = Math.floor(((opts.current || 0) / opts.total) * 100)\n return `[${percent}%] `\n}\n\nexport class ImportDatasetCommand extends SanityCommand<typeof ImportDatasetCommand> {\n static override args = {\n source: Args.string({\n description: 'Source file (use \"-\" for stdin)',\n required: true,\n }),\n targetDataset: Args.string({\n description: 'Target dataset (prefer --dataset flag instead)',\n required: false,\n }),\n }\n\n static override description = 'Import documents to a Sanity dataset'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> -d staging my-dataset.ndjson',\n description: 'Import \"./my-dataset.ndjson\" into dataset \"staging\"',\n },\n {\n command: 'cat my-dataset.ndjson | <%= config.bin %> <%= command.id %> -d test -',\n description: 'Import into dataset \"test\" from stdin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> -p projectId -d staging my-dataset.ndjson',\n description: 'Import with explicit project ID (overrides CLI configuration)',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -d staging -t someSecretToken my-dataset.ndjson',\n description: 'Import with an explicit token (e.g. for CI/CD)',\n },\n ]\n\n static override flags = {\n 'allow-assets-in-different-dataset': Flags.boolean({\n default: false,\n description: 'Allow asset documents to reference different project/dataset',\n }),\n 'allow-failing-assets': Flags.boolean({\n default: false,\n description: 'Skip assets that cannot be fetched/uploaded',\n }),\n 'allow-replacement-characters': Flags.boolean({\n default: false,\n description: 'Allow unicode replacement characters in imported documents',\n }),\n 'allow-system-documents': Flags.boolean({\n default: false,\n description: 'Imports system documents',\n }),\n 'asset-concurrency': Flags.integer({\n description: 'Number of parallel asset imports',\n }),\n ...getDatasetFlag({\n description: 'Dataset to import to',\n semantics: 'specify',\n }),\n missing: Flags.boolean({\n default: false,\n description: 'Skip documents that already exist',\n exclusive: ['replace'],\n }),\n ...getProjectIdFlag({\n description: 'Project ID to import to',\n semantics: 'override',\n }),\n project: Flags.string({\n deprecated: {to: 'project-id'},\n description: 'Project ID to import to',\n hidden: true,\n }),\n replace: Flags.boolean({\n default: false,\n description: 'Replace documents with the same IDs',\n exclusive: ['missing'],\n }),\n 'replace-assets': Flags.boolean({\n default: false,\n description: 'Skip reuse of existing assets',\n }),\n 'skip-cross-dataset-references': Flags.boolean({\n default: false,\n description: 'Skips references to other datasets',\n }),\n token: Flags.string({\n char: 't',\n description: 'Token to authenticate with',\n env: 'SANITY_IMPORT_TOKEN',\n required: false,\n }),\n }\n\n static override hiddenAliases: string[] = ['dataset:import']\n\n private currentProgress?: ReturnType<typeof spinner>\n private currentStep?: string\n private spinInterval?: NodeJS.Timeout | null\n private stepStart?: number\n\n private static async getStream(source: string): Promise<NodeJS.ReadableStream> {\n if (/^https?:\\/\\//i.test(source)) {\n return getUriStream(source)\n }\n\n return source === '-' ? process.stdin : fs.createReadStream(source)\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(ImportDatasetCommand)\n\n const {\n 'allow-assets-in-different-dataset': allowAssetsInDifferentDataset,\n 'allow-failing-assets': allowFailingAssets,\n 'allow-replacement-characters': allowReplacementCharacters,\n 'allow-system-documents': allowSystemDocuments,\n 'asset-concurrency': assetConcurrency,\n dataset: datasetFlag,\n missing,\n replace,\n 'replace-assets': replaceAssets,\n 'skip-cross-dataset-references': skipCrossDatasetReferences,\n token,\n } = flags\n\n const projectId = await this.getProjectId({\n deprecatedFlagName: 'project',\n fallback: () => promptForProject({}),\n })\n\n const {source, targetDataset: targetDatasetArg} = args\n\n if (targetDatasetArg && !datasetFlag) {\n this.warn(\n 'Positional dataset argument is deprecated. Use the --dataset flag instead: --dataset <name>',\n )\n }\n\n let dataset = datasetFlag ?? targetDatasetArg\n if (!dataset) {\n if (this.isUnattended()) {\n this.error(\n 'Missing dataset. Use the --dataset flag to specify a dataset: --dataset <name>',\n {exit: 1},\n )\n }\n\n const datasets = await listDatasets(projectId)\n dataset = await promptForDataset({allowCreation: true, datasets})\n\n if (dataset === NEW_DATASET_VALUE) {\n const newDatasetName = await promptForDatasetName()\n\n try {\n await createDataset({datasetName: newDatasetName, projectId})\n dataset = newDatasetName\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n importDebug(`Failed to create dataset ${newDatasetName}: ${message}`, error)\n this.error(`Failed to create dataset ${newDatasetName}: ${message}`, {exit: 1})\n }\n }\n }\n\n let operation: 'create' | 'createIfNotExists' | 'createOrReplace' = 'create'\n let releasesOperation: 'fail' | 'ignore' | 'replace' = 'fail'\n\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n releasesOperation = replace ? 'replace' : 'ignore'\n }\n\n const client = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n projectId,\n requireUser: true,\n ...(token ? {token} : {}),\n })\n\n try {\n const stream = await ImportDatasetCommand.getStream(source)\n const assetsBase = getAssetsBase(source)\n\n const importOptions = {\n allowAssetsInDifferentDataset,\n allowFailingAssets,\n allowReplacementCharacters,\n allowSystemDocuments,\n client,\n onProgress: this.onProgress.bind(this),\n operation,\n releasesOperation,\n replaceAssets,\n skipCrossDatasetReferences,\n tag: 'sanity.import',\n targetDataset: dataset,\n targetProjectId: projectId,\n ...(assetsBase ? {assetsBase} : {}),\n ...(assetConcurrency === undefined ? {} : {assetConcurrency}),\n }\n\n const {numDocs, warnings} = await sanityImport(stream as NodeJS.ReadableStream, importOptions)\n\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n this.currentProgress.text = `[100%] ${this.currentStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n }\n\n this.log('Done! Imported %d documents to dataset \"%s\"\\n', numDocs, dataset)\n this.printWarnings(warnings)\n } catch (err) {\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress) {\n this.currentProgress.fail()\n }\n\n if ((err as Error).name === 'ReplacementCharError') {\n this.error(\n `Import failed due to unicode replacement characters in the data.\\n${(err as Error).message}\\n\\nIf you are certain you want to proceed with the import despite potentially corrupt data, re-run the import with the \\`--allow-replacement-characters\\` flag set.`,\n {exit: 1},\n )\n } else {\n this.error((err as Error).stack || (err as Error).message, {exit: 1})\n }\n }\n }\n\n private onProgress(opts: ProgressEvent): void {\n const lengthComputable = opts.total\n const sameStep = opts.step === this.currentStep\n const percent = getPercentage(opts)\n\n if (lengthComputable && opts.total === opts.current && this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (sameStep && !lengthComputable) {\n return\n }\n\n if (sameStep) {\n if (this.stepStart) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {secondsDecimalDigits: 2})\n if (this.currentProgress) {\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }\n return\n }\n\n // Moved to a new step\n const prevStep = this.currentStep\n const prevStepStart = this.stepStart\n this.stepStart = Date.now()\n this.currentStep = opts.step\n\n if (this.spinInterval) {\n clearInterval(this.spinInterval)\n this.spinInterval = null\n }\n\n if (this.currentProgress && this.currentProgress.succeed && prevStepStart) {\n const timeSpent = prettyMs(Date.now() - prevStepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `[100%] ${prevStep} (${timeSpent})`\n this.currentProgress.succeed()\n }\n\n this.currentProgress = spinner(`[0%] ${opts.step} (0.00s)`).start()\n\n if (!lengthComputable) {\n this.spinInterval = setInterval(() => {\n if (this.stepStart && this.currentProgress) {\n const timeSpent = prettyMs(Date.now() - this.stepStart, {\n secondsDecimalDigits: 2,\n })\n this.currentProgress.text = `${percent}${opts.step} (${timeSpent})`\n this.currentProgress.render()\n }\n }, 60)\n }\n }\n\n private printWarnings(warnings: Array<{message: string; type?: string; url?: string}>): void {\n const assetFails = warnings.filter((warn) => warn.type === 'asset')\n\n if (assetFails.length === 0) {\n return\n }\n\n this.warn(`Failed to import the following ${assetFails.length > 1 ? 'assets' : 'asset'}:`)\n\n for (const warning of assetFails) {\n if (warning.url) {\n this.warn(` ${warning.url}`)\n }\n }\n }\n}\n"],"names":["fs","path","Args","Flags","getProjectCliClient","SanityCommand","subdebug","createRequester","spinner","sanityImport","prettyMs","NEW_DATASET_VALUE","promptForDataset","promptForDatasetName","promptForProject","createDataset","listDatasets","getDatasetFlag","getProjectIdFlag","importDebug","getAssetsBase","source","test","undefined","fileStats","statSync","sourceIsFolder","isDirectory","dirname","getUriStream","uri","request","middleware","promise","onlyBody","response","stream","url","body","err","Error","message","cause","getPercentage","opts","total","percent","Math","floor","current","ImportDatasetCommand","args","string","description","required","targetDataset","examples","command","flags","boolean","default","integer","semantics","missing","exclusive","project","deprecated","to","hidden","replace","token","char","env","hiddenAliases","currentProgress","currentStep","spinInterval","stepStart","getStream","process","stdin","createReadStream","run","parse","allowAssetsInDifferentDataset","allowFailingAssets","allowReplacementCharacters","allowSystemDocuments","assetConcurrency","dataset","datasetFlag","replaceAssets","skipCrossDatasetReferences","projectId","getProjectId","deprecatedFlagName","fallback","targetDatasetArg","warn","isUnattended","error","exit","datasets","allowCreation","newDatasetName","datasetName","String","operation","releasesOperation","client","apiVersion","requireUser","assetsBase","importOptions","onProgress","bind","tag","targetProjectId","numDocs","warnings","timeSpent","Date","now","secondsDecimalDigits","clearInterval","text","succeed","log","printWarnings","fail","name","stack","lengthComputable","sameStep","step","render","prevStep","prevStepStart","start","setInterval","assetFails","filter","type","length","warning"],"mappings":"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"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -65,6 +65,9 @@ export class DeployCommand extends SanityCommand {
|
|
|
65
65
|
default: false,
|
|
66
66
|
description: 'Enable source maps for built bundles (increases size of bundle)'
|
|
67
67
|
}),
|
|
68
|
+
url: Flags.string({
|
|
69
|
+
description: 'Studio URL for deployment. For external studios, the full URL. For hosted studios, the hostname (e.g. "my-studio" or "my-studio.sanity.studio")'
|
|
70
|
+
}),
|
|
68
71
|
verbose: Flags.boolean({
|
|
69
72
|
default: false,
|
|
70
73
|
description: 'Enable verbose logging'
|