@sanity/cli 6.0.0-alpha.17 → 6.0.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +833 -912
- package/dist/SanityHelp.js +74 -21
- package/dist/SanityHelp.js.map +1 -1
- package/dist/actions/build/buildApp.js +42 -15
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +21 -9
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/build/buildVendorDependencies.js +3 -16
- package/dist/actions/build/buildVendorDependencies.js.map +1 -1
- package/dist/actions/build/checkStudioDependencyVersions.js +7 -7
- package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
- package/dist/actions/build/createExternalFromImportMap.js +1 -1
- package/dist/actions/build/createExternalFromImportMap.js.map +1 -1
- package/dist/actions/build/determineBasePath.js +5 -2
- package/dist/actions/build/determineBasePath.js.map +1 -1
- package/dist/actions/build/getViteConfig.js +47 -4
- package/dist/actions/build/getViteConfig.js.map +1 -1
- package/dist/actions/build/handlePrereleaseVersions.js +44 -0
- package/dist/actions/build/handlePrereleaseVersions.js.map +1 -0
- package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +1 -0
- package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -1
- package/dist/actions/build/types.js.map +1 -1
- package/dist/actions/build/writeSanityRuntime.js +4 -3
- package/dist/actions/build/writeSanityRuntime.js.map +1 -1
- package/dist/actions/dataset/create.js +7 -1
- package/dist/actions/dataset/create.js.map +1 -1
- package/dist/actions/dataset/resolveDataset.js +26 -0
- package/dist/actions/dataset/resolveDataset.js.map +1 -0
- package/dist/actions/deploy/deployApp.js +1 -8
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +1 -0
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/dev/getDashboardAppUrl.js +48 -0
- package/dist/actions/dev/getDashboardAppUrl.js.map +1 -0
- package/dist/actions/dev/getDevServerConfig.js +7 -3
- package/dist/actions/dev/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/startAppDevServer.js +3 -3
- package/dist/actions/dev/startAppDevServer.js.map +1 -1
- package/dist/actions/dev/startStudioDevServer.js +12 -12
- package/dist/actions/dev/startStudioDevServer.js.map +1 -1
- package/dist/actions/documents/types.js.map +1 -1
- package/dist/actions/documents/validate.js +11 -2
- package/dist/actions/documents/validate.js.map +1 -1
- package/dist/actions/documents/validateDocuments.worker.js +2 -2
- package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
- package/dist/actions/documents/validation/reporters/jsonReporter.js +1 -1
- package/dist/actions/documents/validation/reporters/jsonReporter.js.map +1 -1
- package/dist/actions/documents/validation/reporters/ndjsonReporter.js +1 -1
- package/dist/actions/documents/validation/reporters/ndjsonReporter.js.map +1 -1
- package/dist/actions/graphql/SchemaError.js +1 -1
- package/dist/actions/graphql/SchemaError.js.map +1 -1
- package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js +540 -0
- package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js.map +1 -0
- package/dist/actions/graphql/__tests__/fixtures/test-studio.js +1143 -0
- package/dist/actions/graphql/__tests__/fixtures/test-studio.js.map +1 -0
- package/dist/actions/graphql/__tests__/fixtures/union-refs.js +591 -0
- package/dist/actions/graphql/__tests__/fixtures/union-refs.js.map +1 -0
- package/dist/actions/graphql/__tests__/helpers.js +23 -0
- package/dist/actions/graphql/__tests__/helpers.js.map +1 -0
- package/dist/actions/graphql/extractFromSanitySchema.js +2 -1
- package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
- package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -1
- package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
- package/dist/actions/graphql/gen1/generateTypeQueries.js +2 -1
- package/dist/actions/graphql/gen1/generateTypeQueries.js.map +1 -1
- package/dist/actions/graphql/gen2/generateTypeQueries.js +1 -1
- package/dist/actions/graphql/gen2/generateTypeQueries.js.map +1 -1
- package/dist/actions/graphql/gen3/generateTypeQueries.js +1 -1
- package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
- package/dist/actions/graphql/getGraphQLAPIs.js +2 -10
- package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
- package/dist/actions/graphql/getGraphQLAPIs.worker.js +1 -1
- package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
- package/dist/actions/graphql/types.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/manifest/extractAppManifest.js.map +1 -1
- package/dist/actions/manifest/extractManifest.js +1 -22
- package/dist/actions/manifest/extractManifest.js.map +1 -1
- package/dist/actions/manifest/types.js.map +1 -1
- package/dist/actions/schema/deploySchemas.js +57 -80
- package/dist/actions/schema/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js +24 -0
- package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -0
- package/dist/actions/schema/extractSchemaWatcher.js +9 -7
- package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
- package/dist/actions/schema/matchSchemaPattern.js +22 -0
- package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
- package/dist/actions/schema/runSchemaExtraction.js.map +1 -1
- package/dist/actions/schema/types.js +4 -0
- package/dist/actions/schema/types.js.map +1 -1
- package/dist/actions/schema/utils/schemaStoreValidation.js +1 -7
- package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
- package/dist/actions/schema/utils/uniqByProjectIdDataset.js +1 -1
- package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -1
- package/dist/actions/schema/watchExtractSchema.js +2 -1
- package/dist/actions/schema/watchExtractSchema.js.map +1 -1
- package/dist/actions/versions/getFormatters.js +1 -1
- package/dist/actions/versions/getFormatters.js.map +1 -1
- package/dist/commands/backup/disable.js +0 -6
- package/dist/commands/backup/disable.js.map +1 -1
- package/dist/commands/backup/download.js +0 -6
- package/dist/commands/backup/download.js.map +1 -1
- package/dist/commands/backup/enable.js +0 -6
- package/dist/commands/backup/enable.js.map +1 -1
- package/dist/commands/backup/list.js +4 -7
- package/dist/commands/backup/list.js.map +1 -1
- package/dist/commands/cors/add.js +0 -6
- package/dist/commands/cors/add.js.map +1 -1
- package/dist/commands/cors/delete.js +0 -6
- package/dist/commands/cors/delete.js.map +1 -1
- package/dist/commands/cors/list.js +0 -6
- package/dist/commands/cors/list.js.map +1 -1
- package/dist/commands/dataset/alias/create.js +23 -7
- package/dist/commands/dataset/alias/create.js.map +1 -1
- package/dist/commands/dataset/alias/delete.js +17 -7
- package/dist/commands/dataset/alias/delete.js.map +1 -1
- package/dist/commands/dataset/alias/link.js +17 -7
- package/dist/commands/dataset/alias/link.js.map +1 -1
- package/dist/commands/dataset/alias/unlink.js +17 -7
- package/dist/commands/dataset/alias/unlink.js.map +1 -1
- package/dist/commands/dataset/copy.js +42 -30
- package/dist/commands/dataset/copy.js.map +1 -1
- package/dist/commands/dataset/create.js +29 -7
- package/dist/commands/dataset/create.js.map +1 -1
- package/dist/commands/dataset/delete.js +13 -7
- package/dist/commands/dataset/delete.js.map +1 -1
- package/dist/commands/dataset/embeddings/disable.js +74 -0
- package/dist/commands/dataset/embeddings/disable.js.map +1 -0
- package/dist/commands/dataset/embeddings/enable.js +138 -0
- package/dist/commands/dataset/embeddings/enable.js.map +1 -0
- package/dist/commands/dataset/embeddings/status.js +69 -0
- package/dist/commands/dataset/embeddings/status.js.map +1 -0
- package/dist/commands/dataset/export.js +30 -18
- package/dist/commands/dataset/export.js.map +1 -1
- package/dist/commands/dataset/list.js +19 -7
- package/dist/commands/dataset/list.js.map +1 -1
- package/dist/commands/dataset/visibility/get.js +15 -7
- package/dist/commands/dataset/visibility/get.js.map +1 -1
- package/dist/commands/dataset/visibility/set.js +19 -7
- package/dist/commands/dataset/visibility/set.js.map +1 -1
- package/dist/commands/debug.js +2 -1
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/documents/create.js +2 -7
- package/dist/commands/documents/create.js.map +1 -1
- package/dist/commands/documents/delete.js +0 -6
- package/dist/commands/documents/delete.js.map +1 -1
- package/dist/commands/documents/get.js +0 -6
- package/dist/commands/documents/get.js.map +1 -1
- package/dist/commands/documents/query.js +0 -6
- package/dist/commands/documents/query.js.map +1 -1
- package/dist/commands/graphql/deploy.js +1 -1
- package/dist/commands/graphql/deploy.js.map +1 -1
- package/dist/commands/graphql/list.js +0 -6
- package/dist/commands/graphql/list.js.map +1 -1
- package/dist/commands/graphql/undeploy.js +0 -6
- package/dist/commands/graphql/undeploy.js.map +1 -1
- package/dist/commands/hook/attempt.js +0 -6
- package/dist/commands/hook/attempt.js.map +1 -1
- package/dist/commands/hook/create.js +0 -6
- package/dist/commands/hook/create.js.map +1 -1
- package/dist/commands/hook/delete.js +0 -6
- package/dist/commands/hook/delete.js.map +1 -1
- package/dist/commands/hook/list.js +0 -6
- package/dist/commands/hook/list.js.map +1 -1
- package/dist/commands/hook/logs.js +1 -7
- package/dist/commands/hook/logs.js.map +1 -1
- package/dist/commands/init.js +13 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/manage.js +0 -1
- package/dist/commands/manage.js.map +1 -1
- package/dist/commands/media/create-aspect.js +1 -1
- package/dist/commands/media/create-aspect.js.map +1 -1
- package/dist/commands/media/delete-aspect.js +0 -6
- package/dist/commands/media/delete-aspect.js.map +1 -1
- package/dist/commands/media/deploy-aspect.js +1 -6
- package/dist/commands/media/deploy-aspect.js.map +1 -1
- package/dist/commands/media/export.js +0 -6
- package/dist/commands/media/export.js.map +1 -1
- package/dist/commands/media/import.js +0 -6
- package/dist/commands/media/import.js.map +1 -1
- package/dist/commands/projects/list.js +2 -1
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/schema/delete.js +0 -6
- package/dist/commands/schema/delete.js.map +1 -1
- package/dist/commands/schema/deploy.js +11 -27
- package/dist/commands/schema/deploy.js.map +1 -1
- package/dist/commands/tokens/add.js +0 -6
- package/dist/commands/tokens/add.js.map +1 -1
- package/dist/commands/tokens/delete.js +0 -6
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +0 -6
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/users/invite.js +0 -6
- package/dist/commands/users/invite.js.map +1 -1
- package/dist/commands/users/list.js +1 -7
- package/dist/commands/users/list.js.map +1 -1
- package/dist/commands/versions.js +1 -1
- package/dist/commands/versions.js.map +1 -1
- package/dist/exports/index.d.ts +62 -2
- package/dist/exports/index.js.map +1 -1
- package/dist/prompts/promptForProject.js +64 -0
- package/dist/prompts/promptForProject.js.map +1 -0
- package/dist/prompts/selectMediaLibrary.js +1 -1
- package/dist/prompts/selectMediaLibrary.js.map +1 -1
- package/dist/server/devServer.js +4 -2
- package/dist/server/devServer.js.map +1 -1
- package/dist/server/vite/plugin-schema-extraction.js +201 -0
- package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
- package/dist/server/vite/plugin-typegen.js +217 -0
- package/dist/server/vite/plugin-typegen.js.map +1 -0
- package/dist/services/datasets.js +7 -5
- package/dist/services/datasets.js.map +1 -1
- package/dist/services/embeddings.js +25 -0
- package/dist/services/embeddings.js.map +1 -0
- package/dist/services/grants.js +13 -0
- package/dist/services/grants.js.map +1 -0
- package/dist/services/graphql.js.map +1 -1
- package/dist/services/schemas.js +1 -1
- package/dist/services/schemas.js.map +1 -1
- package/dist/types/grants.js +3 -0
- package/dist/types/grants.js.map +1 -0
- package/dist/types.js.map +1 -1
- package/dist/util/checkProjectPermissions.js +21 -0
- package/dist/util/checkProjectPermissions.js.map +1 -0
- package/dist/util/compareDependencyVersions.js +28 -7
- package/dist/util/compareDependencyVersions.js.map +1 -1
- package/dist/util/errorMessages.js +0 -1
- package/dist/util/errorMessages.js.map +1 -1
- package/dist/util/getSharedServerConfig.js +1 -0
- package/dist/util/getSharedServerConfig.js.map +1 -1
- package/dist/util/packageManager/getPeerDependencies.js +44 -0
- package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
- package/dist/util/sharedFlags.js +19 -0
- package/dist/util/sharedFlags.js.map +1 -0
- package/dist/util/toForwardSlashes.js +8 -0
- package/dist/util/toForwardSlashes.js.map +1 -0
- package/oclif.manifest.json +639 -379
- package/package.json +23 -22
- package/dist/actions/dev/getCoreAppUrl.js +0 -10
- package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
- package/dist/actions/schema/schemaStoreTypes.js +0 -19
- package/dist/actions/schema/schemaStoreTypes.js.map +0 -1
- package/dist/actions/schema/utils/manifestExtractor.js +0 -29
- package/dist/actions/schema/utils/manifestExtractor.js.map +0 -1
- package/dist/actions/schema/utils/manifestReader.js +0 -71
- package/dist/actions/schema/utils/manifestReader.js.map +0 -1
- package/dist/util/workerChannels.js +0 -172
- package/dist/util/workerChannels.js.map +0 -1
|
@@ -7,7 +7,7 @@ import { getMediaLibraryConfig } from '../../actions/media/getMediaLibraryConfig
|
|
|
7
7
|
import { importAspects } from '../../actions/media/importAspects.js';
|
|
8
8
|
import { selectMediaLibrary } from '../../prompts/selectMediaLibrary.js';
|
|
9
9
|
import { deployAspects } from '../../services/mediaLibraries.js';
|
|
10
|
-
import { NO_MEDIA_LIBRARY_ASPECTS_PATH
|
|
10
|
+
import { NO_MEDIA_LIBRARY_ASPECTS_PATH } from '../../util/errorMessages.js';
|
|
11
11
|
import { pluralize } from '../../util/pluralize.js';
|
|
12
12
|
const deployAspectDebug = subdebug('media:deploy-aspect');
|
|
13
13
|
export class MediaDeployAspectCommand extends SanityCommand {
|
|
@@ -61,11 +61,6 @@ export class MediaDeployAspectCommand extends SanityCommand {
|
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
const projectId = await this.getProjectId();
|
|
64
|
-
if (!projectId) {
|
|
65
|
-
this.error(NO_PROJECT_ID, {
|
|
66
|
-
exit: 1
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
64
|
try {
|
|
70
65
|
// Determine target media library
|
|
71
66
|
let mediaLibraryId = mediaLibraryIdFlag;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/media/deploy-aspect.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isAssetAspect, type SchemaValidationProblem} from '@sanity/types'\n\nimport {getMediaLibraryConfig} from '../../actions/media/getMediaLibraryConfig.js'\nimport {importAspects} from '../../actions/media/importAspects.js'\nimport {selectMediaLibrary} from '../../prompts/selectMediaLibrary.js'\nimport {deployAspects} from '../../services/mediaLibraries.js'\nimport {NO_MEDIA_LIBRARY_ASPECTS_PATH, NO_PROJECT_ID} from '../../util/errorMessages.js'\nimport {pluralize} from '../../util/pluralize.js'\n\nconst deployAspectDebug = subdebug('media:deploy-aspect')\n\nexport class MediaDeployAspectCommand extends SanityCommand<typeof MediaDeployAspectCommand> {\n static override args = {\n aspectName: Args.string({\n description: 'Name of the aspect to deploy',\n required: false,\n }),\n }\n\n static override description = 'Deploy an aspect'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> someAspect',\n description: 'Deploy the aspect named \"someAspect\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --all',\n description: 'Deploy all aspects',\n },\n ]\n\n static override flags = {\n all: Flags.boolean({\n description: 'Deploy all aspects',\n required: false,\n }),\n 'media-library-id': Flags.string({\n description: 'The id of the target media library',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {aspectName} = this.args\n const {all, 'media-library-id': mediaLibraryIdFlag} = this.flags\n\n // Validation: must provide either aspect name or --all flag\n if (!all && !aspectName) {\n this.error(\n 'Specify an aspect name, or use the `--all` option to deploy all aspect definitions.',\n {exit: 1},\n )\n }\n\n // Validation: cannot provide both aspect name and --all flag\n if (all && aspectName) {\n this.error('Specified both an aspect name and `--all`.', {exit: 1})\n }\n\n const cliConfig = await this.getCliConfig()\n const mediaLibrary = getMediaLibraryConfig(cliConfig)\n\n if (!mediaLibrary?.aspectsPath) {\n this.error(NO_MEDIA_LIBRARY_ASPECTS_PATH, {exit: 1})\n }\n\n const projectId = await this.getProjectId()\n if (!projectId) {\n this.error(NO_PROJECT_ID, {exit: 1})\n }\n\n try {\n // Determine target media library\n let mediaLibraryId = mediaLibraryIdFlag\n if (!mediaLibraryId) {\n mediaLibraryId = await selectMediaLibrary(projectId)\n }\n\n // Import and validate aspects\n const spin = spinner('Loading aspect definitions').start()\n const result = await importAspects({\n aspectsPath: mediaLibrary.aspectsPath,\n filterAspects: (aspect) => {\n if (all) {\n return true\n }\n\n if (typeof aspect === 'object' && aspect !== null && '_id' in aspect) {\n return aspect._id === aspectName\n }\n\n return false\n },\n })\n spin.stop()\n\n // Handle invalid aspects\n if (result.invalid.length > 0) {\n this.logToStderr('')\n this.warn(\n styleText(\n 'bold',\n `Skipped ${result.invalid.length} invalid ${pluralize('aspect', result.invalid.length)}`,\n ),\n )\n this.logToStderr(this.formatAspectList(result.invalid))\n }\n\n // Check if we found the requested aspect (when not using --all)\n if (!all && result.valid.length === 0 && result.invalid.length === 0) {\n this.log()\n this.error(`Could not find aspect: ${styleText('bold', aspectName ?? '')}`, {exit: 1})\n }\n\n // Deploy valid aspects\n if (result.valid.length === 0) {\n this.logToStderr('')\n this.warn('No valid aspects to deploy')\n return\n }\n\n const deploySpin = spinner(\n `Deploying ${result.valid.length} ${pluralize('aspect', result.valid.length)}`,\n ).start()\n\n const deployResponse = await deployAspects({\n aspects: result.valid.map((a) => a.aspect),\n mediaLibraryId,\n })\n\n deploySpin.succeed()\n\n // Display success message\n this.log()\n this.log(\n `${styleText('green', '✓')} ${styleText('bold', `Deployed ${result.valid.length} ${pluralize('aspect', result.valid.length)}`)}`,\n )\n this.log(this.formatAspectList(result.valid))\n\n deployAspectDebug('Deployed aspects', {\n count: result.valid.length,\n results: deployResponse.results,\n })\n } catch (error) {\n const err = error as Error\n deployAspectDebug('Failed to deploy aspects', {\n all,\n aspectName,\n error: err,\n mediaLibraryId: mediaLibraryIdFlag,\n })\n this.error(\n styleText('bold', 'Failed to deploy aspects') + `\\n\\n${styleText('red', err.message)}`,\n {\n exit: 1,\n },\n )\n }\n }\n\n /**\n * Format a list of aspects for display\n */\n private formatAspectList(\n aspects: Array<{\n aspect: unknown\n filename: string\n validationErrors?: SchemaValidationProblem[][]\n }>,\n ): string {\n return aspects\n .map(({aspect, filename, validationErrors = []}) => {\n const label = isAssetAspect(aspect) ? aspect._id : 'Unnamed aspect'\n\n // Flatten the nested validation errors and extract messages\n const simplifiedErrors = validationErrors.flatMap((group) =>\n group.map(({message}) => message),\n )\n\n const errorLabel =\n simplifiedErrors.length > 0 ? ` ${styleText('bgRed', simplifiedErrors[0])}` : ''\n\n const remainingErrorsCount = simplifiedErrors.length - 1\n const remainingErrorsLabel =\n remainingErrorsCount > 0\n ? styleText(\n 'italic',\n ` and ${remainingErrorsCount} other ${pluralize('error', remainingErrorsCount)}`,\n )\n : ''\n\n return ` - ${label} ${styleText('dim', filename)}${errorLabel}${remainingErrorsLabel}`\n })\n .join('\\n')\n }\n}\n"],"names":["styleText","Args","Flags","SanityCommand","subdebug","spinner","isAssetAspect","getMediaLibraryConfig","importAspects","selectMediaLibrary","deployAspects","NO_MEDIA_LIBRARY_ASPECTS_PATH","NO_PROJECT_ID","pluralize","deployAspectDebug","MediaDeployAspectCommand","args","aspectName","string","description","required","examples","command","flags","all","boolean","run","mediaLibraryIdFlag","error","exit","cliConfig","getCliConfig","mediaLibrary","aspectsPath","projectId","getProjectId","mediaLibraryId","spin","start","result","filterAspects","aspect","_id","stop","invalid","length","logToStderr","warn","formatAspectList","valid","log","deploySpin","deployResponse","aspects","map","a","succeed","count","results","err","message","filename","validationErrors","label","simplifiedErrors","flatMap","group","errorLabel","remainingErrorsCount","remainingErrorsLabel","join"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/media/deploy-aspect.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isAssetAspect, type SchemaValidationProblem} from '@sanity/types'\n\nimport {getMediaLibraryConfig} from '../../actions/media/getMediaLibraryConfig.js'\nimport {importAspects} from '../../actions/media/importAspects.js'\nimport {selectMediaLibrary} from '../../prompts/selectMediaLibrary.js'\nimport {deployAspects} from '../../services/mediaLibraries.js'\nimport {NO_MEDIA_LIBRARY_ASPECTS_PATH} from '../../util/errorMessages.js'\nimport {pluralize} from '../../util/pluralize.js'\n\nconst deployAspectDebug = subdebug('media:deploy-aspect')\n\nexport class MediaDeployAspectCommand extends SanityCommand<typeof MediaDeployAspectCommand> {\n static override args = {\n aspectName: Args.string({\n description: 'Name of the aspect to deploy',\n required: false,\n }),\n }\n\n static override description = 'Deploy an aspect'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> someAspect',\n description: 'Deploy the aspect named \"someAspect\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --all',\n description: 'Deploy all aspects',\n },\n ]\n\n static override flags = {\n all: Flags.boolean({\n description: 'Deploy all aspects',\n required: false,\n }),\n 'media-library-id': Flags.string({\n description: 'The id of the target media library',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {aspectName} = this.args\n const {all, 'media-library-id': mediaLibraryIdFlag} = this.flags\n\n // Validation: must provide either aspect name or --all flag\n if (!all && !aspectName) {\n this.error(\n 'Specify an aspect name, or use the `--all` option to deploy all aspect definitions.',\n {exit: 1},\n )\n }\n\n // Validation: cannot provide both aspect name and --all flag\n if (all && aspectName) {\n this.error('Specified both an aspect name and `--all`.', {exit: 1})\n }\n\n const cliConfig = await this.getCliConfig()\n const mediaLibrary = getMediaLibraryConfig(cliConfig)\n\n if (!mediaLibrary?.aspectsPath) {\n this.error(NO_MEDIA_LIBRARY_ASPECTS_PATH, {exit: 1})\n }\n\n const projectId = await this.getProjectId()\n\n try {\n // Determine target media library\n let mediaLibraryId = mediaLibraryIdFlag\n if (!mediaLibraryId) {\n mediaLibraryId = await selectMediaLibrary(projectId)\n }\n\n // Import and validate aspects\n const spin = spinner('Loading aspect definitions').start()\n const result = await importAspects({\n aspectsPath: mediaLibrary.aspectsPath,\n filterAspects: (aspect) => {\n if (all) {\n return true\n }\n\n if (typeof aspect === 'object' && aspect !== null && '_id' in aspect) {\n return aspect._id === aspectName\n }\n\n return false\n },\n })\n spin.stop()\n\n // Handle invalid aspects\n if (result.invalid.length > 0) {\n this.logToStderr('')\n this.warn(\n styleText(\n 'bold',\n `Skipped ${result.invalid.length} invalid ${pluralize('aspect', result.invalid.length)}`,\n ),\n )\n this.logToStderr(this.formatAspectList(result.invalid))\n }\n\n // Check if we found the requested aspect (when not using --all)\n if (!all && result.valid.length === 0 && result.invalid.length === 0) {\n this.log()\n this.error(`Could not find aspect: ${styleText('bold', aspectName ?? '')}`, {exit: 1})\n }\n\n // Deploy valid aspects\n if (result.valid.length === 0) {\n this.logToStderr('')\n this.warn('No valid aspects to deploy')\n return\n }\n\n const deploySpin = spinner(\n `Deploying ${result.valid.length} ${pluralize('aspect', result.valid.length)}`,\n ).start()\n\n const deployResponse = await deployAspects({\n aspects: result.valid.map((a) => a.aspect),\n mediaLibraryId,\n })\n\n deploySpin.succeed()\n\n // Display success message\n this.log()\n this.log(\n `${styleText('green', '✓')} ${styleText('bold', `Deployed ${result.valid.length} ${pluralize('aspect', result.valid.length)}`)}`,\n )\n this.log(this.formatAspectList(result.valid))\n\n deployAspectDebug('Deployed aspects', {\n count: result.valid.length,\n results: deployResponse.results,\n })\n } catch (error) {\n const err = error as Error\n deployAspectDebug('Failed to deploy aspects', {\n all,\n aspectName,\n error: err,\n mediaLibraryId: mediaLibraryIdFlag,\n })\n this.error(\n styleText('bold', 'Failed to deploy aspects') + `\\n\\n${styleText('red', err.message)}`,\n {\n exit: 1,\n },\n )\n }\n }\n\n /**\n * Format a list of aspects for display\n */\n private formatAspectList(\n aspects: Array<{\n aspect: unknown\n filename: string\n validationErrors?: SchemaValidationProblem[][]\n }>,\n ): string {\n return aspects\n .map(({aspect, filename, validationErrors = []}) => {\n const label = isAssetAspect(aspect) ? aspect._id : 'Unnamed aspect'\n\n // Flatten the nested validation errors and extract messages\n const simplifiedErrors = validationErrors.flatMap((group) =>\n group.map(({message}) => message),\n )\n\n const errorLabel =\n simplifiedErrors.length > 0 ? ` ${styleText('bgRed', simplifiedErrors[0])}` : ''\n\n const remainingErrorsCount = simplifiedErrors.length - 1\n const remainingErrorsLabel =\n remainingErrorsCount > 0\n ? styleText(\n 'italic',\n ` and ${remainingErrorsCount} other ${pluralize('error', remainingErrorsCount)}`,\n )\n : ''\n\n return ` - ${label} ${styleText('dim', filename)}${errorLabel}${remainingErrorsLabel}`\n })\n .join('\\n')\n }\n}\n"],"names":["styleText","Args","Flags","SanityCommand","subdebug","spinner","isAssetAspect","getMediaLibraryConfig","importAspects","selectMediaLibrary","deployAspects","NO_MEDIA_LIBRARY_ASPECTS_PATH","pluralize","deployAspectDebug","MediaDeployAspectCommand","args","aspectName","string","description","required","examples","command","flags","all","boolean","run","mediaLibraryIdFlag","error","exit","cliConfig","getCliConfig","mediaLibrary","aspectsPath","projectId","getProjectId","mediaLibraryId","spin","start","result","filterAspects","aspect","_id","stop","invalid","length","logToStderr","warn","formatAspectList","valid","log","deploySpin","deployResponse","aspects","map","a","succeed","count","results","err","message","filename","validationErrors","label","simplifiedErrors","flatMap","group","errorLabel","remainingErrorsCount","remainingErrorsLabel","join"],"mappings":"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"}
|
|
@@ -8,7 +8,6 @@ import prettyMs from 'pretty-ms';
|
|
|
8
8
|
import { promptForMediaLibrary } from '../../prompts/promptForMediaLibrary.js';
|
|
9
9
|
import { getMediaLibraries } from '../../services/mediaLibraries.js';
|
|
10
10
|
import { absolutify } from '../../util/absolutify.js';
|
|
11
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
12
11
|
const noop = ()=>null;
|
|
13
12
|
const exportDebug = subdebug('media:export');
|
|
14
13
|
export class MediaExportCommand extends SanityCommand {
|
|
@@ -53,11 +52,6 @@ export class MediaExportCommand extends SanityCommand {
|
|
|
53
52
|
const { args, flags } = await this.parse(MediaExportCommand);
|
|
54
53
|
const { destination: targetDestination } = args;
|
|
55
54
|
const projectId = await this.getProjectId();
|
|
56
|
-
if (!projectId) {
|
|
57
|
-
this.error(NO_PROJECT_ID, {
|
|
58
|
-
exit: 1
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
55
|
const projectClient = await getProjectCliClient({
|
|
62
56
|
apiVersion: 'v2025-02-19',
|
|
63
57
|
projectId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/media/export.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {type Writable} from 'node:stream'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {boxen, input, spinner} from '@sanity/cli-core/ux'\nimport {exportDataset, type ExportOptions, type ExportProgress} from '@sanity/export'\nimport prettyMs from 'pretty-ms'\n\nimport {promptForMediaLibrary} from '../../prompts/promptForMediaLibrary.js'\nimport {getMediaLibraries} from '../../services/mediaLibraries.js'\nimport {absolutify} from '../../util/absolutify.js'\nimport {NO_PROJECT_ID} from '../../util/errorMessages.js'\n\nconst noop = () => null\nconst exportDebug = subdebug('media:export')\n\nexport class MediaExportCommand extends SanityCommand<typeof MediaExportCommand> {\n static override args = {\n destination: Args.string({\n description: 'Output destination file path',\n }),\n }\n\n static override description =\n 'Export an archive of all file and image assets including their aspect data from the target media library. Video assets are excluded from the export.'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Export media library interactively',\n },\n {\n command: '<%= config.bin %> <%= command.id %> output.tar.gz',\n description: 'Export media library to output.tar.gz',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --media-library-id my-library-id',\n description: 'Export specific media library',\n },\n ]\n\n static override flags = {\n 'asset-concurrency': Flags.integer({\n default: 8,\n description: 'Concurrent number of asset downloads',\n }),\n 'media-library-id': Flags.string({\n description: 'The id of the target media library',\n }),\n 'no-compress': Flags.boolean({\n default: false,\n description: 'Skips compressing tarball entries (still generates a gzip file)',\n }),\n overwrite: Flags.boolean({\n default: false,\n description: 'Overwrite any file with the same name',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(MediaExportCommand)\n const {destination: targetDestination} = args\n\n const projectId = await this.getProjectId()\n\n if (!projectId) {\n this.error(NO_PROJECT_ID, {\n exit: 1,\n })\n }\n\n const projectClient = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n projectId,\n requireUser: true,\n })\n\n let mediaLibraries\n try {\n mediaLibraries = await getMediaLibraries(projectId)\n } catch (error) {\n exportDebug('Error listing media libraries', error)\n this.error(\n `Failed to list media libraries:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n\n if (mediaLibraries.length === 0) {\n this.error('No active media libraries found in this project', {exit: 1})\n }\n\n let mediaLibraryId = flags['media-library-id']\n if (!mediaLibraryId) {\n try {\n mediaLibraryId = await promptForMediaLibrary({mediaLibraries})\n } catch (error) {\n exportDebug('Error selecting media library', error)\n this.error(\n `Failed to select media library:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n }\n\n if (!mediaLibraries.some((library) => library.id === mediaLibraryId)) {\n this.error(`Media library with id \"${mediaLibraryId}\" not found`, {exit: 1})\n }\n\n this.log(\n boxen(\n `Exporting from:\nprojectId: ${projectId.padEnd(44)}\nmediaLibraryId: ${mediaLibraryId.padEnd(37)}`,\n {\n borderColor: 'yellow',\n borderStyle: 'round',\n },\n ),\n )\n\n let destinationPath = targetDestination\n if (!destinationPath) {\n destinationPath = await this.promptForDestination({mediaLibraryId})\n }\n\n const outputPath = await this.getOutputPath(destinationPath, mediaLibraryId, flags)\n if (!outputPath) {\n this.error('Cancelled', {exit: 1})\n }\n\n const {fail, onProgress, succeed} = this.createProgressHandler()\n const exportOptions: ExportOptions = {\n assetConcurrency: flags['asset-concurrency'],\n client: projectClient,\n compress: !flags['no-compress'],\n mediaLibraryId,\n onProgress,\n outputPath,\n }\n\n const start = Date.now()\n try {\n await exportDataset(exportOptions)\n succeed()\n this.log(`Export finished (${prettyMs(Date.now() - start)})`)\n } catch (error) {\n fail()\n const err = error instanceof Error ? error : new Error(String(error))\n exportDebug('Export failed', err)\n this.error(`Export failed: ${err.message}`, {exit: 1})\n }\n }\n\n private createProgressHandler() {\n let currentSpinner: ReturnType<typeof spinner> | null = null\n let currentStep = ''\n\n const onProgress = (progress: ExportProgress) => {\n if (progress.step !== currentStep) {\n succeed()\n\n currentStep = progress.step\n currentSpinner = spinner(progress.step).start()\n } else if (progress.step === currentStep && progress.update && currentSpinner) {\n currentSpinner.text = `${progress.step} (${progress.current}/${progress.total})`\n }\n }\n\n const succeed = () => {\n currentSpinner?.succeed()\n }\n\n const fail = () => {\n currentSpinner?.fail()\n }\n\n return {fail, onProgress, succeed}\n }\n\n private async getOutputPath(\n destination: string,\n mediaLibraryId: string,\n flags: {overwrite?: boolean},\n ): Promise<string | Writable> {\n if (destination === '-') {\n return process.stdout\n }\n\n const dstPath = path.isAbsolute(destination)\n ? destination\n : path.resolve(process.cwd(), destination)\n\n const dstStats = await fs.stat(dstPath).catch(noop)\n const looksLikeFile = dstStats ? dstStats.isFile() : path.basename(dstPath).includes('.')\n\n if (!dstStats) {\n const createPath = looksLikeFile ? path.dirname(dstPath) : dstPath\n try {\n await fs.mkdir(createPath, {recursive: true})\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n this.error(`Failed to create directory \"${createPath}\": ${err.message}`, {\n exit: 1,\n })\n }\n }\n\n const finalPath = looksLikeFile\n ? dstPath\n : path.join(dstPath, `${mediaLibraryId}-export.tar.gz`)\n const finalPathStats = await fs.stat(finalPath).catch(noop)\n\n if (!flags.overwrite && finalPathStats && finalPathStats.isFile()) {\n this.error(`File \"${finalPath}\" already exists. Use --overwrite flag to overwrite it.`, {\n exit: 1,\n })\n }\n\n return finalPath\n }\n\n private promptForDestination(options: {\n mediaLibraryId: string\n workDir?: string\n }): Promise<string> {\n const {mediaLibraryId, workDir = process.cwd()} = options\n\n const defaultPath = path.join(workDir, `${mediaLibraryId}-export.tar.gz`)\n\n return input({\n default: defaultPath,\n message: 'Output path:',\n transformer: (value: string) => absolutify(value.trim()),\n validate: (value: string) => {\n const trimmed = value.trim()\n if (!trimmed) {\n return 'Please provide a valid output path'\n }\n return true\n },\n })\n }\n}\n"],"names":["fs","path","Args","Flags","getProjectCliClient","SanityCommand","subdebug","boxen","input","spinner","exportDataset","prettyMs","promptForMediaLibrary","getMediaLibraries","absolutify","NO_PROJECT_ID","noop","exportDebug","MediaExportCommand","args","destination","string","description","examples","command","flags","integer","default","boolean","overwrite","run","parse","targetDestination","projectId","getProjectId","error","exit","projectClient","apiVersion","requireUser","mediaLibraries","Error","message","length","mediaLibraryId","some","library","id","log","padEnd","borderColor","borderStyle","destinationPath","promptForDestination","outputPath","getOutputPath","fail","onProgress","succeed","createProgressHandler","exportOptions","assetConcurrency","client","compress","start","Date","now","err","String","currentSpinner","currentStep","progress","step","update","text","current","total","process","stdout","dstPath","isAbsolute","resolve","cwd","dstStats","stat","catch","looksLikeFile","isFile","basename","includes","createPath","dirname","mkdir","recursive","finalPath","join","finalPathStats","options","workDir","defaultPath","transformer","value","trim","validate","trimmed"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAG5B,SAAQC,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,mBAAmB,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAC7E,SAAQC,KAAK,EAAEC,KAAK,EAAEC,OAAO,QAAO,sBAAqB;AACzD,SAAQC,aAAa,QAAgD,iBAAgB;AACrF,OAAOC,cAAc,YAAW;AAEhC,SAAQC,qBAAqB,QAAO,yCAAwC;AAC5E,SAAQC,iBAAiB,QAAO,mCAAkC;AAClE,SAAQC,UAAU,QAAO,2BAA0B;AACnD,SAAQC,aAAa,QAAO,8BAA6B;AAEzD,MAAMC,OAAO,IAAM;AACnB,MAAMC,cAAcX,SAAS;AAE7B,OAAO,MAAMY,2BAA2Bb;IACtC,OAAgBc,OAAO;QACrBC,aAAalB,KAAKmB,MAAM,CAAC;YACvBC,aAAa;QACf;IACF,EAAC;IAED,OAAgBA,cACd,uJAAsJ;IAExJ,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ;QACtB,qBAAqBtB,MAAMuB,OAAO,CAAC;YACjCC,SAAS;YACTL,aAAa;QACf;QACA,oBAAoBnB,MAAMkB,MAAM,CAAC;YAC/BC,aAAa;QACf;QACA,eAAenB,MAAMyB,OAAO,CAAC;YAC3BD,SAAS;YACTL,aAAa;QACf;QACAO,WAAW1B,MAAMyB,OAAO,CAAC;YACvBD,SAAS;YACTL,aAAa;QACf;IACF,EAAC;IAED,MAAaQ,MAAqB;QAChC,MAAM,EAACX,IAAI,EAAEM,KAAK,EAAC,GAAG,MAAM,IAAI,CAACM,KAAK,CAACb;QACvC,MAAM,EAACE,aAAaY,iBAAiB,EAAC,GAAGb;QAEzC,MAAMc,YAAY,MAAM,IAAI,CAACC,YAAY;QAEzC,IAAI,CAACD,WAAW;YACd,IAAI,CAACE,KAAK,CAACpB,eAAe;gBACxBqB,MAAM;YACR;QACF;QAEA,MAAMC,gBAAgB,MAAMjC,oBAAoB;YAC9CkC,YAAY;YACZL;YACAM,aAAa;QACf;QAEA,IAAIC;QACJ,IAAI;YACFA,iBAAiB,MAAM3B,kBAAkBoB;QAC3C,EAAE,OAAOE,OAAO;YACdlB,YAAY,iCAAiCkB;YAC7C,IAAI,CAACA,KAAK,CACR,CAAC,iCAAiC,EAAEA,iBAAiBM,QAAQN,MAAMO,OAAO,GAAGP,OAAO,EACpF;gBACEC,MAAM;YACR;QAEJ;QAEA,IAAII,eAAeG,MAAM,KAAK,GAAG;YAC/B,IAAI,CAACR,KAAK,CAAC,mDAAmD;gBAACC,MAAM;YAAC;QACxE;QAEA,IAAIQ,iBAAiBnB,KAAK,CAAC,mBAAmB;QAC9C,IAAI,CAACmB,gBAAgB;YACnB,IAAI;gBACFA,iBAAiB,MAAMhC,sBAAsB;oBAAC4B;gBAAc;YAC9D,EAAE,OAAOL,OAAO;gBACdlB,YAAY,iCAAiCkB;gBAC7C,IAAI,CAACA,KAAK,CACR,CAAC,iCAAiC,EAAEA,iBAAiBM,QAAQN,MAAMO,OAAO,GAAGP,OAAO,EACpF;oBACEC,MAAM;gBACR;YAEJ;QACF;QAEA,IAAI,CAACI,eAAeK,IAAI,CAAC,CAACC,UAAYA,QAAQC,EAAE,KAAKH,iBAAiB;YACpE,IAAI,CAACT,KAAK,CAAC,CAAC,uBAAuB,EAAES,eAAe,WAAW,CAAC,EAAE;gBAACR,MAAM;YAAC;QAC5E;QAEA,IAAI,CAACY,GAAG,CACNzC,MACE,CAAC;WACE,EAAE0B,UAAUgB,MAAM,CAAC,IAAI;gBAClB,EAAEL,eAAeK,MAAM,CAAC,KAAK,EACrC;YACEC,aAAa;YACbC,aAAa;QACf;QAIJ,IAAIC,kBAAkBpB;QACtB,IAAI,CAACoB,iBAAiB;YACpBA,kBAAkB,MAAM,IAAI,CAACC,oBAAoB,CAAC;gBAACT;YAAc;QACnE;QAEA,MAAMU,aAAa,MAAM,IAAI,CAACC,aAAa,CAACH,iBAAiBR,gBAAgBnB;QAC7E,IAAI,CAAC6B,YAAY;YACf,IAAI,CAACnB,KAAK,CAAC,aAAa;gBAACC,MAAM;YAAC;QAClC;QAEA,MAAM,EAACoB,IAAI,EAAEC,UAAU,EAAEC,OAAO,EAAC,GAAG,IAAI,CAACC,qBAAqB;QAC9D,MAAMC,gBAA+B;YACnCC,kBAAkBpC,KAAK,CAAC,oBAAoB;YAC5CqC,QAAQzB;YACR0B,UAAU,CAACtC,KAAK,CAAC,cAAc;YAC/BmB;YACAa;YACAH;QACF;QAEA,MAAMU,QAAQC,KAAKC,GAAG;QACtB,IAAI;YACF,MAAMxD,cAAckD;YACpBF;YACA,IAAI,CAACV,GAAG,CAAC,CAAC,iBAAiB,EAAErC,SAASsD,KAAKC,GAAG,KAAKF,OAAO,CAAC,CAAC;QAC9D,EAAE,OAAO7B,OAAO;YACdqB;YACA,MAAMW,MAAMhC,iBAAiBM,QAAQN,QAAQ,IAAIM,MAAM2B,OAAOjC;YAC9DlB,YAAY,iBAAiBkD;YAC7B,IAAI,CAAChC,KAAK,CAAC,CAAC,eAAe,EAAEgC,IAAIzB,OAAO,EAAE,EAAE;gBAACN,MAAM;YAAC;QACtD;IACF;IAEQuB,wBAAwB;QAC9B,IAAIU,iBAAoD;QACxD,IAAIC,cAAc;QAElB,MAAMb,aAAa,CAACc;YAClB,IAAIA,SAASC,IAAI,KAAKF,aAAa;gBACjCZ;gBAEAY,cAAcC,SAASC,IAAI;gBAC3BH,iBAAiB5D,QAAQ8D,SAASC,IAAI,EAAER,KAAK;YAC/C,OAAO,IAAIO,SAASC,IAAI,KAAKF,eAAeC,SAASE,MAAM,IAAIJ,gBAAgB;gBAC7EA,eAAeK,IAAI,GAAG,GAAGH,SAASC,IAAI,CAAC,EAAE,EAAED,SAASI,OAAO,CAAC,CAAC,EAAEJ,SAASK,KAAK,CAAC,CAAC,CAAC;YAClF;QACF;QAEA,MAAMlB,UAAU;YACdW,gBAAgBX;QAClB;QAEA,MAAMF,OAAO;YACXa,gBAAgBb;QAClB;QAEA,OAAO;YAACA;YAAMC;YAAYC;QAAO;IACnC;IAEA,MAAcH,cACZnC,WAAmB,EACnBwB,cAAsB,EACtBnB,KAA4B,EACA;QAC5B,IAAIL,gBAAgB,KAAK;YACvB,OAAOyD,QAAQC,MAAM;QACvB;QAEA,MAAMC,UAAU9E,KAAK+E,UAAU,CAAC5D,eAC5BA,cACAnB,KAAKgF,OAAO,CAACJ,QAAQK,GAAG,IAAI9D;QAEhC,MAAM+D,WAAW,MAAMnF,GAAGoF,IAAI,CAACL,SAASM,KAAK,CAACrE;QAC9C,MAAMsE,gBAAgBH,WAAWA,SAASI,MAAM,KAAKtF,KAAKuF,QAAQ,CAACT,SAASU,QAAQ,CAAC;QAErF,IAAI,CAACN,UAAU;YACb,MAAMO,aAAaJ,gBAAgBrF,KAAK0F,OAAO,CAACZ,WAAWA;YAC3D,IAAI;gBACF,MAAM/E,GAAG4F,KAAK,CAACF,YAAY;oBAACG,WAAW;gBAAI;YAC7C,EAAE,OAAO1D,OAAO;gBACd,MAAMgC,MAAMhC,iBAAiBM,QAAQN,QAAQ,IAAIM,MAAM2B,OAAOjC;gBAC9D,IAAI,CAACA,KAAK,CAAC,CAAC,4BAA4B,EAAEuD,WAAW,GAAG,EAAEvB,IAAIzB,OAAO,EAAE,EAAE;oBACvEN,MAAM;gBACR;YACF;QACF;QAEA,MAAM0D,YAAYR,gBACdP,UACA9E,KAAK8F,IAAI,CAAChB,SAAS,GAAGnC,eAAe,cAAc,CAAC;QACxD,MAAMoD,iBAAiB,MAAMhG,GAAGoF,IAAI,CAACU,WAAWT,KAAK,CAACrE;QAEtD,IAAI,CAACS,MAAMI,SAAS,IAAImE,kBAAkBA,eAAeT,MAAM,IAAI;YACjE,IAAI,CAACpD,KAAK,CAAC,CAAC,MAAM,EAAE2D,UAAU,uDAAuD,CAAC,EAAE;gBACtF1D,MAAM;YACR;QACF;QAEA,OAAO0D;IACT;IAEQzC,qBAAqB4C,OAG5B,EAAmB;QAClB,MAAM,EAACrD,cAAc,EAAEsD,UAAUrB,QAAQK,GAAG,EAAE,EAAC,GAAGe;QAElD,MAAME,cAAclG,KAAK8F,IAAI,CAACG,SAAS,GAAGtD,eAAe,cAAc,CAAC;QAExE,OAAOpC,MAAM;YACXmB,SAASwE;YACTzD,SAAS;YACT0D,aAAa,CAACC,QAAkBvF,WAAWuF,MAAMC,IAAI;YACrDC,UAAU,CAACF;gBACT,MAAMG,UAAUH,MAAMC,IAAI;gBAC1B,IAAI,CAACE,SAAS;oBACZ,OAAO;gBACT;gBACA,OAAO;YACT;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/media/export.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {type Writable} from 'node:stream'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {boxen, input, spinner} from '@sanity/cli-core/ux'\nimport {exportDataset, type ExportOptions, type ExportProgress} from '@sanity/export'\nimport prettyMs from 'pretty-ms'\n\nimport {promptForMediaLibrary} from '../../prompts/promptForMediaLibrary.js'\nimport {getMediaLibraries} from '../../services/mediaLibraries.js'\nimport {absolutify} from '../../util/absolutify.js'\n\nconst noop = () => null\nconst exportDebug = subdebug('media:export')\n\nexport class MediaExportCommand extends SanityCommand<typeof MediaExportCommand> {\n static override args = {\n destination: Args.string({\n description: 'Output destination file path',\n }),\n }\n\n static override description =\n 'Export an archive of all file and image assets including their aspect data from the target media library. Video assets are excluded from the export.'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Export media library interactively',\n },\n {\n command: '<%= config.bin %> <%= command.id %> output.tar.gz',\n description: 'Export media library to output.tar.gz',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --media-library-id my-library-id',\n description: 'Export specific media library',\n },\n ]\n\n static override flags = {\n 'asset-concurrency': Flags.integer({\n default: 8,\n description: 'Concurrent number of asset downloads',\n }),\n 'media-library-id': Flags.string({\n description: 'The id of the target media library',\n }),\n 'no-compress': Flags.boolean({\n default: false,\n description: 'Skips compressing tarball entries (still generates a gzip file)',\n }),\n overwrite: Flags.boolean({\n default: false,\n description: 'Overwrite any file with the same name',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(MediaExportCommand)\n const {destination: targetDestination} = args\n\n const projectId = await this.getProjectId()\n\n\n const projectClient = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n projectId,\n requireUser: true,\n })\n\n let mediaLibraries\n try {\n mediaLibraries = await getMediaLibraries(projectId)\n } catch (error) {\n exportDebug('Error listing media libraries', error)\n this.error(\n `Failed to list media libraries:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n\n if (mediaLibraries.length === 0) {\n this.error('No active media libraries found in this project', {exit: 1})\n }\n\n let mediaLibraryId = flags['media-library-id']\n if (!mediaLibraryId) {\n try {\n mediaLibraryId = await promptForMediaLibrary({mediaLibraries})\n } catch (error) {\n exportDebug('Error selecting media library', error)\n this.error(\n `Failed to select media library:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n }\n\n if (!mediaLibraries.some((library) => library.id === mediaLibraryId)) {\n this.error(`Media library with id \"${mediaLibraryId}\" not found`, {exit: 1})\n }\n\n this.log(\n boxen(\n `Exporting from:\nprojectId: ${projectId.padEnd(44)}\nmediaLibraryId: ${mediaLibraryId.padEnd(37)}`,\n {\n borderColor: 'yellow',\n borderStyle: 'round',\n },\n ),\n )\n\n let destinationPath = targetDestination\n if (!destinationPath) {\n destinationPath = await this.promptForDestination({mediaLibraryId})\n }\n\n const outputPath = await this.getOutputPath(destinationPath, mediaLibraryId, flags)\n if (!outputPath) {\n this.error('Cancelled', {exit: 1})\n }\n\n const {fail, onProgress, succeed} = this.createProgressHandler()\n const exportOptions: ExportOptions = {\n assetConcurrency: flags['asset-concurrency'],\n client: projectClient,\n compress: !flags['no-compress'],\n mediaLibraryId,\n onProgress,\n outputPath,\n }\n\n const start = Date.now()\n try {\n await exportDataset(exportOptions)\n succeed()\n this.log(`Export finished (${prettyMs(Date.now() - start)})`)\n } catch (error) {\n fail()\n const err = error instanceof Error ? error : new Error(String(error))\n exportDebug('Export failed', err)\n this.error(`Export failed: ${err.message}`, {exit: 1})\n }\n }\n\n private createProgressHandler() {\n let currentSpinner: ReturnType<typeof spinner> | null = null\n let currentStep = ''\n\n const onProgress = (progress: ExportProgress) => {\n if (progress.step !== currentStep) {\n succeed()\n\n currentStep = progress.step\n currentSpinner = spinner(progress.step).start()\n } else if (progress.step === currentStep && progress.update && currentSpinner) {\n currentSpinner.text = `${progress.step} (${progress.current}/${progress.total})`\n }\n }\n\n const succeed = () => {\n currentSpinner?.succeed()\n }\n\n const fail = () => {\n currentSpinner?.fail()\n }\n\n return {fail, onProgress, succeed}\n }\n\n private async getOutputPath(\n destination: string,\n mediaLibraryId: string,\n flags: {overwrite?: boolean},\n ): Promise<string | Writable> {\n if (destination === '-') {\n return process.stdout\n }\n\n const dstPath = path.isAbsolute(destination)\n ? destination\n : path.resolve(process.cwd(), destination)\n\n const dstStats = await fs.stat(dstPath).catch(noop)\n const looksLikeFile = dstStats ? dstStats.isFile() : path.basename(dstPath).includes('.')\n\n if (!dstStats) {\n const createPath = looksLikeFile ? path.dirname(dstPath) : dstPath\n try {\n await fs.mkdir(createPath, {recursive: true})\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n this.error(`Failed to create directory \"${createPath}\": ${err.message}`, {\n exit: 1,\n })\n }\n }\n\n const finalPath = looksLikeFile\n ? dstPath\n : path.join(dstPath, `${mediaLibraryId}-export.tar.gz`)\n const finalPathStats = await fs.stat(finalPath).catch(noop)\n\n if (!flags.overwrite && finalPathStats && finalPathStats.isFile()) {\n this.error(`File \"${finalPath}\" already exists. Use --overwrite flag to overwrite it.`, {\n exit: 1,\n })\n }\n\n return finalPath\n }\n\n private promptForDestination(options: {\n mediaLibraryId: string\n workDir?: string\n }): Promise<string> {\n const {mediaLibraryId, workDir = process.cwd()} = options\n\n const defaultPath = path.join(workDir, `${mediaLibraryId}-export.tar.gz`)\n\n return input({\n default: defaultPath,\n message: 'Output path:',\n transformer: (value: string) => absolutify(value.trim()),\n validate: (value: string) => {\n const trimmed = value.trim()\n if (!trimmed) {\n return 'Please provide a valid output path'\n }\n return true\n },\n })\n }\n}\n"],"names":["fs","path","Args","Flags","getProjectCliClient","SanityCommand","subdebug","boxen","input","spinner","exportDataset","prettyMs","promptForMediaLibrary","getMediaLibraries","absolutify","noop","exportDebug","MediaExportCommand","args","destination","string","description","examples","command","flags","integer","default","boolean","overwrite","run","parse","targetDestination","projectId","getProjectId","projectClient","apiVersion","requireUser","mediaLibraries","error","Error","message","exit","length","mediaLibraryId","some","library","id","log","padEnd","borderColor","borderStyle","destinationPath","promptForDestination","outputPath","getOutputPath","fail","onProgress","succeed","createProgressHandler","exportOptions","assetConcurrency","client","compress","start","Date","now","err","String","currentSpinner","currentStep","progress","step","update","text","current","total","process","stdout","dstPath","isAbsolute","resolve","cwd","dstStats","stat","catch","looksLikeFile","isFile","basename","includes","createPath","dirname","mkdir","recursive","finalPath","join","finalPathStats","options","workDir","defaultPath","transformer","value","trim","validate","trimmed"],"mappings":"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"}
|
|
@@ -7,7 +7,6 @@ import { importer } from '../../actions/media/importMedia.js';
|
|
|
7
7
|
import { importMediaDebug } from '../../actions/media/importMediaDebug.js';
|
|
8
8
|
import { promptForMediaLibrary } from '../../prompts/promptForMediaLibrary.js';
|
|
9
9
|
import { getMediaLibraries } from '../../services/mediaLibraries.js';
|
|
10
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
11
10
|
export class MediaImportCommand extends SanityCommand {
|
|
12
11
|
static args = {
|
|
13
12
|
source: Args.string({
|
|
@@ -45,11 +44,6 @@ export class MediaImportCommand extends SanityCommand {
|
|
|
45
44
|
const projectId = await this.getProjectId();
|
|
46
45
|
const cliConfig = await this.getCliConfig();
|
|
47
46
|
const dataset = cliConfig.api?.dataset;
|
|
48
|
-
if (!projectId) {
|
|
49
|
-
this.error(NO_PROJECT_ID, {
|
|
50
|
-
exit: 1
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
47
|
let mediaLibraries;
|
|
54
48
|
try {
|
|
55
49
|
mediaLibraries = await getMediaLibraries(projectId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/media/import.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand} from '@sanity/cli-core'\nimport {boxen, spinner} from '@sanity/cli-core/ux'\nimport {SanityClient} from '@sanity/client'\nimport {type OperatorFunction, pipe, scan, tap} from 'rxjs'\n\nimport {importer, type State} from '../../actions/media/importMedia.js'\nimport {importMediaDebug} from '../../actions/media/importMediaDebug.js'\nimport {promptForMediaLibrary} from '../../prompts/promptForMediaLibrary.js'\nimport {getMediaLibraries} from '../../services/mediaLibraries.js'\nimport {NO_PROJECT_ID} from '../../util/errorMessages.js'\n\nexport class MediaImportCommand extends SanityCommand<typeof MediaImportCommand> {\n static override args = {\n source: Args.string({\n description: 'Image file or folder to import from',\n required: true,\n }),\n }\n\n static override description = 'Import a set of assets to the target media library.'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> products',\n description: 'Import all assets from the \"products\" directory',\n },\n {\n command: '<%= config.bin %> <%= command.id %> gallery.tar.gz',\n description: 'Import all assets from \"gallery\" archive',\n },\n {\n command: '<%= config.bin %> <%= command.id %> products --replace-aspects',\n description: 'Import all assets from the \"products\" directory and replace aspects',\n },\n ]\n\n static override flags = {\n 'media-library-id': Flags.string({\n description: 'The id of the target media library',\n }),\n 'replace-aspects': Flags.boolean({\n description:\n 'Replace existing aspect data. All versions will be replaced (e.g. published and draft aspect data)',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(MediaImportCommand)\n const {source} = args\n const replaceAspects = flags['replace-aspects']\n\n const projectId = await this.getProjectId()\n const cliConfig = await this.getCliConfig()\n const dataset = cliConfig.api?.dataset\n\n if (!projectId) {\n this.error(NO_PROJECT_ID, {\n exit: 1,\n })\n }\n\n let mediaLibraries\n try {\n mediaLibraries = await getMediaLibraries(projectId)\n } catch (error) {\n importMediaDebug('Error listing media libraries', error)\n this.error(\n `Failed to list media libraries:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n\n if (mediaLibraries.length === 0) {\n this.error('No active media libraries found in this project', {exit: 1})\n }\n\n let mediaLibraryId = flags['media-library-id']\n if (!mediaLibraryId) {\n try {\n mediaLibraryId = await promptForMediaLibrary({mediaLibraries})\n } catch (error) {\n importMediaDebug('Error selecting media library', error)\n this.error(\n `Failed to select media library:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n }\n\n if (!mediaLibraries.some((library) => library.id === mediaLibraryId)) {\n this.error(`Media library with id \"${mediaLibraryId}\" not found`, {exit: 1})\n }\n\n const projectClient = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n perspective: 'drafts',\n projectId,\n requestTagPrefix: 'sanity.mediaLibraryCli.import',\n requireUser: true,\n '~experimental_resource': {\n id: mediaLibraryId,\n type: 'media-library',\n },\n })\n\n this.log(\n boxen(\n `\n Importing to media library: ${mediaLibraryId.padEnd(37)}\n Importing from path: ${source}\n `,\n {\n borderColor: 'yellow',\n borderStyle: 'round',\n },\n ),\n )\n\n const spin = spinner('Beginning import…').start()\n\n await this.importAssets({projectClient, replaceAspects, source, spin})\n }\n\n private async importAssets(options: {\n projectClient: SanityClient\n replaceAspects: boolean\n source: string\n spin: ReturnType<typeof spinner>\n }): Promise<void> {\n const {projectClient, replaceAspects, source, spin} = options\n\n return new Promise<void>((resolve, reject) => {\n const subscription = importer({\n client: projectClient,\n replaceAspects,\n sourcePath: source,\n spinner: spin,\n })\n .pipe(this.reportResult(spin))\n .subscribe({\n complete: () => {\n resolve()\n },\n error: (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error)\n spin.stop()\n reject(new Error(message))\n },\n })\n\n // Cleanup on Ctrl+C\n process.once('SIGINT', () => {\n subscription.unsubscribe()\n spin.fail('Import interrupted.')\n process.exit(130)\n })\n }).catch((error) => {\n this.error(styleText('red', error.message), {exit: 1})\n })\n }\n\n private reportResult(\n spin: ReturnType<typeof spinner>,\n ): OperatorFunction<State, [number, State | undefined]> {\n let previousState: State | undefined\n\n return pipe(\n scan<State, [number, State | undefined]>(\n (processedAssetsCount, state) => [processedAssetsCount[0] + 1, state],\n [0, undefined],\n ),\n tap({\n complete: () => spin.succeed(`Imported ${previousState?.fileCount} assets`),\n next: ([processedAssetsCount, state]) => {\n previousState = state\n spin.text = `${processedAssetsCount} of ${state?.fileCount} assets imported ${styleText('dim', state?.asset.originalFilename ?? '')}`\n },\n }),\n )\n }\n}\n"],"names":["styleText","Args","Flags","getProjectCliClient","SanityCommand","boxen","spinner","pipe","scan","tap","importer","importMediaDebug","promptForMediaLibrary","getMediaLibraries","NO_PROJECT_ID","MediaImportCommand","args","source","string","description","required","examples","command","flags","boolean","run","parse","replaceAspects","projectId","getProjectId","cliConfig","getCliConfig","dataset","api","error","exit","mediaLibraries","Error","message","length","mediaLibraryId","some","library","id","projectClient","apiVersion","perspective","requestTagPrefix","requireUser","type","log","padEnd","borderColor","borderStyle","spin","start","importAssets","options","Promise","resolve","reject","subscription","client","sourcePath","reportResult","subscribe","complete","String","stop","process","once","unsubscribe","fail","catch","previousState","processedAssetsCount","state","undefined","succeed","fileCount","next","text","asset","originalFilename"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/media/import.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {getProjectCliClient, SanityCommand} from '@sanity/cli-core'\nimport {boxen, spinner} from '@sanity/cli-core/ux'\nimport {SanityClient} from '@sanity/client'\nimport {type OperatorFunction, pipe, scan, tap} from 'rxjs'\n\nimport {importer, type State} from '../../actions/media/importMedia.js'\nimport {importMediaDebug} from '../../actions/media/importMediaDebug.js'\nimport {promptForMediaLibrary} from '../../prompts/promptForMediaLibrary.js'\nimport {getMediaLibraries} from '../../services/mediaLibraries.js'\n\nexport class MediaImportCommand extends SanityCommand<typeof MediaImportCommand> {\n static override args = {\n source: Args.string({\n description: 'Image file or folder to import from',\n required: true,\n }),\n }\n\n static override description = 'Import a set of assets to the target media library.'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> products',\n description: 'Import all assets from the \"products\" directory',\n },\n {\n command: '<%= config.bin %> <%= command.id %> gallery.tar.gz',\n description: 'Import all assets from \"gallery\" archive',\n },\n {\n command: '<%= config.bin %> <%= command.id %> products --replace-aspects',\n description: 'Import all assets from the \"products\" directory and replace aspects',\n },\n ]\n\n static override flags = {\n 'media-library-id': Flags.string({\n description: 'The id of the target media library',\n }),\n 'replace-aspects': Flags.boolean({\n description:\n 'Replace existing aspect data. All versions will be replaced (e.g. published and draft aspect data)',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(MediaImportCommand)\n const {source} = args\n const replaceAspects = flags['replace-aspects']\n\n const projectId = await this.getProjectId()\n const cliConfig = await this.getCliConfig()\n const dataset = cliConfig.api?.dataset\n\n\n let mediaLibraries\n try {\n mediaLibraries = await getMediaLibraries(projectId)\n } catch (error) {\n importMediaDebug('Error listing media libraries', error)\n this.error(\n `Failed to list media libraries:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n\n if (mediaLibraries.length === 0) {\n this.error('No active media libraries found in this project', {exit: 1})\n }\n\n let mediaLibraryId = flags['media-library-id']\n if (!mediaLibraryId) {\n try {\n mediaLibraryId = await promptForMediaLibrary({mediaLibraries})\n } catch (error) {\n importMediaDebug('Error selecting media library', error)\n this.error(\n `Failed to select media library:\\n${error instanceof Error ? error.message : error}`,\n {\n exit: 1,\n },\n )\n }\n }\n\n if (!mediaLibraries.some((library) => library.id === mediaLibraryId)) {\n this.error(`Media library with id \"${mediaLibraryId}\" not found`, {exit: 1})\n }\n\n const projectClient = await getProjectCliClient({\n apiVersion: 'v2025-02-19',\n dataset,\n perspective: 'drafts',\n projectId,\n requestTagPrefix: 'sanity.mediaLibraryCli.import',\n requireUser: true,\n '~experimental_resource': {\n id: mediaLibraryId,\n type: 'media-library',\n },\n })\n\n this.log(\n boxen(\n `\n Importing to media library: ${mediaLibraryId.padEnd(37)}\n Importing from path: ${source}\n `,\n {\n borderColor: 'yellow',\n borderStyle: 'round',\n },\n ),\n )\n\n const spin = spinner('Beginning import…').start()\n\n await this.importAssets({projectClient, replaceAspects, source, spin})\n }\n\n private async importAssets(options: {\n projectClient: SanityClient\n replaceAspects: boolean\n source: string\n spin: ReturnType<typeof spinner>\n }): Promise<void> {\n const {projectClient, replaceAspects, source, spin} = options\n\n return new Promise<void>((resolve, reject) => {\n const subscription = importer({\n client: projectClient,\n replaceAspects,\n sourcePath: source,\n spinner: spin,\n })\n .pipe(this.reportResult(spin))\n .subscribe({\n complete: () => {\n resolve()\n },\n error: (error: unknown) => {\n const message = error instanceof Error ? error.message : String(error)\n spin.stop()\n reject(new Error(message))\n },\n })\n\n // Cleanup on Ctrl+C\n process.once('SIGINT', () => {\n subscription.unsubscribe()\n spin.fail('Import interrupted.')\n process.exit(130)\n })\n }).catch((error) => {\n this.error(styleText('red', error.message), {exit: 1})\n })\n }\n\n private reportResult(\n spin: ReturnType<typeof spinner>,\n ): OperatorFunction<State, [number, State | undefined]> {\n let previousState: State | undefined\n\n return pipe(\n scan<State, [number, State | undefined]>(\n (processedAssetsCount, state) => [processedAssetsCount[0] + 1, state],\n [0, undefined],\n ),\n tap({\n complete: () => spin.succeed(`Imported ${previousState?.fileCount} assets`),\n next: ([processedAssetsCount, state]) => {\n previousState = state\n spin.text = `${processedAssetsCount} of ${state?.fileCount} assets imported ${styleText('dim', state?.asset.originalFilename ?? '')}`\n },\n }),\n )\n }\n}\n"],"names":["styleText","Args","Flags","getProjectCliClient","SanityCommand","boxen","spinner","pipe","scan","tap","importer","importMediaDebug","promptForMediaLibrary","getMediaLibraries","MediaImportCommand","args","source","string","description","required","examples","command","flags","boolean","run","parse","replaceAspects","projectId","getProjectId","cliConfig","getCliConfig","dataset","api","mediaLibraries","error","Error","message","exit","length","mediaLibraryId","some","library","id","projectClient","apiVersion","perspective","requestTagPrefix","requireUser","type","log","padEnd","borderColor","borderStyle","spin","start","importAssets","options","Promise","resolve","reject","subscription","client","sourcePath","reportResult","subscribe","complete","String","stop","process","once","unsubscribe","fail","catch","previousState","processedAssetsCount","state","undefined","succeed","fileCount","next","text","asset","originalFilename"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
3
|
import { SanityCommand, subdebug } from '@sanity/cli-core';
|
|
4
|
-
import
|
|
4
|
+
import size from 'lodash-es/size.js';
|
|
5
|
+
import sortBy from 'lodash-es/sortBy.js';
|
|
5
6
|
import { listProjects } from '../../services/projects.js';
|
|
6
7
|
const sortFields = [
|
|
7
8
|
'id',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/projects/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/projects/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport size from 'lodash-es/size.js'\nimport sortBy from 'lodash-es/sortBy.js'\n\nimport {listProjects} from '../../services/projects.js'\n\nconst sortFields = ['id', 'members', 'name', 'url', 'created']\n\nconst projectsDebug = subdebug('projects')\n\nexport class List extends SanityCommand<typeof List> {\n static override description = 'Lists projects connected to your user'\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List projects',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --sort=members --order=asc',\n description: 'List all users of the project, but exclude pending invitations and robots',\n },\n ]\n\n static override flags = {\n order: Flags.string({\n default: 'desc',\n options: ['asc', 'desc'],\n }),\n sort: Flags.string({\n default: 'created',\n options: sortFields,\n }),\n }\n\n public async run() {\n const {order, sort} = this.flags\n\n try {\n const projects = await listProjects()\n const ordered = sortBy(\n projects.map(({createdAt, displayName, id, members = []}) => {\n const manage = `https://www.sanity.io/manage/project/${id}`\n return [id, members.length, displayName, manage, createdAt].map(String)\n }),\n [sortFields.indexOf(sort)],\n )\n\n const rows = order === 'asc' ? ordered : ordered.toReversed()\n\n // Initialize maxWidths with the width of each header\n const maxWidths = sortFields.map((str) => size(str))\n\n // Calculate maximum width for each column\n for (const row of rows) {\n for (const [i, element] of row.entries()) {\n maxWidths[i] = Math.max(size(element), maxWidths[i])\n }\n }\n\n const printRow = (row: string[]) =>\n row.map((col, i) => `${col}`.padEnd(maxWidths[i])).join(' ')\n\n this.log(styleText('cyan', printRow(sortFields)))\n for (const row of rows) this.log(printRow(row))\n } catch (error) {\n projectsDebug('Error listing projects', error)\n this.error('Failed to list projects', {exit: 1})\n }\n }\n}\n"],"names":["styleText","Flags","SanityCommand","subdebug","size","sortBy","listProjects","sortFields","projectsDebug","List","description","examples","command","flags","order","string","default","options","sort","run","projects","ordered","map","createdAt","displayName","id","members","manage","length","String","indexOf","rows","toReversed","maxWidths","str","row","i","element","entries","Math","max","printRow","col","padEnd","join","log","error","exit"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,KAAK,QAAO,cAAa;AACjC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,OAAOC,UAAU,oBAAmB;AACpC,OAAOC,YAAY,sBAAqB;AAExC,SAAQC,YAAY,QAAO,6BAA4B;AAEvD,MAAMC,aAAa;IAAC;IAAM;IAAW;IAAQ;IAAO;CAAU;AAE9D,MAAMC,gBAAgBL,SAAS;AAE/B,OAAO,MAAMM,aAAaP;IACxB,OAAgBQ,cAAc,wCAAuC;IACrE,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ;QACtBC,OAAOb,MAAMc,MAAM,CAAC;YAClBC,SAAS;YACTC,SAAS;gBAAC;gBAAO;aAAO;QAC1B;QACAC,MAAMjB,MAAMc,MAAM,CAAC;YACjBC,SAAS;YACTC,SAASV;QACX;IACF,EAAC;IAED,MAAaY,MAAM;QACjB,MAAM,EAACL,KAAK,EAAEI,IAAI,EAAC,GAAG,IAAI,CAACL,KAAK;QAEhC,IAAI;YACF,MAAMO,WAAW,MAAMd;YACvB,MAAMe,UAAUhB,OACde,SAASE,GAAG,CAAC,CAAC,EAACC,SAAS,EAAEC,WAAW,EAAEC,EAAE,EAAEC,UAAU,EAAE,EAAC;gBACtD,MAAMC,SAAS,CAAC,qCAAqC,EAAEF,IAAI;gBAC3D,OAAO;oBAACA;oBAAIC,QAAQE,MAAM;oBAAEJ;oBAAaG;oBAAQJ;iBAAU,CAACD,GAAG,CAACO;YAClE,IACA;gBAACtB,WAAWuB,OAAO,CAACZ;aAAM;YAG5B,MAAMa,OAAOjB,UAAU,QAAQO,UAAUA,QAAQW,UAAU;YAE3D,qDAAqD;YACrD,MAAMC,YAAY1B,WAAWe,GAAG,CAAC,CAACY,MAAQ9B,KAAK8B;YAE/C,0CAA0C;YAC1C,KAAK,MAAMC,OAAOJ,KAAM;gBACtB,KAAK,MAAM,CAACK,GAAGC,QAAQ,IAAIF,IAAIG,OAAO,GAAI;oBACxCL,SAAS,CAACG,EAAE,GAAGG,KAAKC,GAAG,CAACpC,KAAKiC,UAAUJ,SAAS,CAACG,EAAE;gBACrD;YACF;YAEA,MAAMK,WAAW,CAACN,MAChBA,IAAIb,GAAG,CAAC,CAACoB,KAAKN,IAAM,GAAGM,KAAK,CAACC,MAAM,CAACV,SAAS,CAACG,EAAE,GAAGQ,IAAI,CAAC;YAE1D,IAAI,CAACC,GAAG,CAAC7C,UAAU,QAAQyC,SAASlC;YACpC,KAAK,MAAM4B,OAAOJ,KAAM,IAAI,CAACc,GAAG,CAACJ,SAASN;QAC5C,EAAE,OAAOW,OAAO;YACdtC,cAAc,0BAA0BsC;YACxC,IAAI,CAACA,KAAK,CAAC,2BAA2B;gBAACC,MAAM;YAAC;QAChD;IACF;AACF"}
|
|
@@ -3,7 +3,6 @@ import { CLIError } from '@oclif/core/errors';
|
|
|
3
3
|
import { parseStringFlag, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
4
4
|
import { deleteSchemaAction } from '../../actions/schema/deleteSchemaAction.js';
|
|
5
5
|
import { parseIds } from '../../actions/schema/utils/schemaStoreValidation.js';
|
|
6
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
7
6
|
const deleteSchemaDebug = subdebug('schema:delete');
|
|
8
7
|
export class DeleteSchemaCommand extends SanityCommand {
|
|
9
8
|
static description = 'Delete schema documents by id';
|
|
@@ -50,11 +49,6 @@ export class DeleteSchemaCommand extends SanityCommand {
|
|
|
50
49
|
try {
|
|
51
50
|
const workDir = await this.getProjectRoot();
|
|
52
51
|
const projectId = await this.getProjectId();
|
|
53
|
-
if (!projectId) {
|
|
54
|
-
this.error(NO_PROJECT_ID, {
|
|
55
|
-
exit: 1
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
52
|
await deleteSchemaAction({
|
|
59
53
|
configPath: workDir.path,
|
|
60
54
|
dataset,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/schema/delete.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {parseStringFlag, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {deleteSchemaAction} from '../../actions/schema/deleteSchemaAction.js'\nimport {parseIds} from '../../actions/schema/utils/schemaStoreValidation.js'\
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/schema/delete.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {parseStringFlag, SanityCommand, subdebug} from '@sanity/cli-core'\n\nimport {deleteSchemaAction} from '../../actions/schema/deleteSchemaAction.js'\nimport {parseIds} from '../../actions/schema/utils/schemaStoreValidation.js'\n\nconst deleteSchemaDebug = subdebug('schema:delete')\n\nexport class DeleteSchemaCommand extends SanityCommand<typeof DeleteSchemaCommand> {\n static override description = 'Delete schema documents by id'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> --ids sanity.workspace.schema.workspaceName',\n description: 'Delete a single schema',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> --ids sanity.workspace.schema.workspaceName,prefix.sanity.workspace.schema.otherWorkspace',\n description: 'Delete multiple schemas',\n },\n ]\n\n static override flags = {\n dataset: Flags.string({\n description: 'Delete schemas from a specific dataset',\n parse: async (input) => parseStringFlag('dataset', input),\n }),\n 'extract-manifest': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Generate manifest file (disable with --no-extract-manifest)',\n hidden: true,\n }),\n ids: Flags.string({\n description: 'Comma-separated list of schema ids to delete',\n required: true,\n }),\n 'manifest-dir': Flags.directory({\n default: './dist/static',\n description: 'Directory containing manifest file',\n hidden: true,\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeleteSchemaCommand)\n const {dataset} = flags\n\n deleteSchemaDebug('Running schema delete with flags: %O', flags)\n\n const ids = parseIds(flags.ids)\n\n try {\n const workDir = await this.getProjectRoot()\n const projectId = await this.getProjectId()\n\n\n await deleteSchemaAction({\n configPath: workDir.path,\n dataset,\n ids,\n output: this.output,\n projectId,\n verbose: flags['verbose'],\n workDir: workDir.directory,\n })\n } catch (error) {\n if (error instanceof CLIError) {\n this.error(error.message, {exit: 1})\n }\n\n deleteSchemaDebug('Error deleting schemas', error)\n this.error(`Failed to delete schemas: ${error.message}`, {exit: 1})\n }\n }\n}\n"],"names":["Flags","CLIError","parseStringFlag","SanityCommand","subdebug","deleteSchemaAction","parseIds","deleteSchemaDebug","DeleteSchemaCommand","description","examples","command","flags","dataset","string","parse","input","boolean","allowNo","default","hidden","ids","required","directory","verbose","run","workDir","getProjectRoot","projectId","getProjectId","configPath","path","output","error","message","exit"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,QAAQ,QAAO,qBAAoB;AAC3C,SAAQC,eAAe,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AAEzE,SAAQC,kBAAkB,QAAO,6CAA4C;AAC7E,SAAQC,QAAQ,QAAO,sDAAqD;AAE5E,MAAMC,oBAAoBH,SAAS;AAEnC,OAAO,MAAMI,4BAA4BL;IACvC,OAAgBM,cAAc,gCAA+B;IAE7D,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SACE;YACFF,aAAa;QACf;KACD,CAAA;IAED,OAAgBG,QAAQ;QACtBC,SAASb,MAAMc,MAAM,CAAC;YACpBL,aAAa;YACbM,OAAO,OAAOC,QAAUd,gBAAgB,WAAWc;QACrD;QACA,oBAAoBhB,MAAMiB,OAAO,CAAC;YAChCC,SAAS;YACTC,SAAS;YACTV,aAAa;YACbW,QAAQ;QACV;QACAC,KAAKrB,MAAMc,MAAM,CAAC;YAChBL,aAAa;YACba,UAAU;QACZ;QACA,gBAAgBtB,MAAMuB,SAAS,CAAC;YAC9BJ,SAAS;YACTV,aAAa;YACbW,QAAQ;QACV;QACAI,SAASxB,MAAMiB,OAAO,CAAC;YACrBE,SAAS;YACTV,aAAa;QACf;IACF,EAAC;IAED,MAAagB,MAAqB;QAChC,MAAM,EAACb,KAAK,EAAC,GAAG,MAAM,IAAI,CAACG,KAAK,CAACP;QACjC,MAAM,EAACK,OAAO,EAAC,GAAGD;QAElBL,kBAAkB,wCAAwCK;QAE1D,MAAMS,MAAMf,SAASM,MAAMS,GAAG;QAE9B,IAAI;YACF,MAAMK,UAAU,MAAM,IAAI,CAACC,cAAc;YACzC,MAAMC,YAAY,MAAM,IAAI,CAACC,YAAY;YAGzC,MAAMxB,mBAAmB;gBACvByB,YAAYJ,QAAQK,IAAI;gBACxBlB;gBACAQ;gBACAW,QAAQ,IAAI,CAACA,MAAM;gBACnBJ;gBACAJ,SAASZ,KAAK,CAAC,UAAU;gBACzBc,SAASA,QAAQH,SAAS;YAC5B;QACF,EAAE,OAAOU,OAAO;YACd,IAAIA,iBAAiBhC,UAAU;gBAC7B,IAAI,CAACgC,KAAK,CAACA,MAAMC,OAAO,EAAE;oBAACC,MAAM;gBAAC;YACpC;YAEA5B,kBAAkB,0BAA0B0B;YAC5C,IAAI,CAACA,KAAK,CAAC,CAAC,0BAA0B,EAAEA,MAAMC,OAAO,EAAE,EAAE;gBAACC,MAAM;YAAC;QACnE;IACF;AACF"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { styleText } from 'node:util';
|
|
1
2
|
import { Flags } from '@oclif/core';
|
|
2
3
|
import { parseStringFlag, SanityCommand } from '@sanity/cli-core';
|
|
3
4
|
import { deploySchemas } from '../../actions/schema/deploySchemas.js';
|
|
5
|
+
import { formatSchemaValidation } from '../../actions/schema/formatSchemaValidation.js';
|
|
4
6
|
import { schemasDeployDebug } from '../../actions/schema/utils/debug.js';
|
|
7
|
+
import { SchemaExtractionError } from '../../actions/schema/utils/SchemaExtractionError.js';
|
|
5
8
|
import { parseTag } from '../../actions/schema/utils/schemaStoreValidation.js';
|
|
6
|
-
import { NO_DATASET_ID, NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
7
9
|
const description = `
|
|
8
10
|
Deploy schema documents into workspace datasets.
|
|
9
11
|
|
|
@@ -22,10 +24,6 @@ export class DeploySchemaCommand extends SanityCommand {
|
|
|
22
24
|
{
|
|
23
25
|
command: '<%= config.bin %> <%= command.id %> --workspace default',
|
|
24
26
|
description: 'Deploy the schema for only the workspace "default"'
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
command: '<%= config.bin %> <%= command.id %> --no-extract-manifest',
|
|
28
|
-
description: 'Runs using a pre-existing manifest file. Config changes in sanity.config will not be picked up in this case.'
|
|
29
27
|
}
|
|
30
28
|
];
|
|
31
29
|
static flags = {
|
|
@@ -59,36 +57,22 @@ export class DeploySchemaCommand extends SanityCommand {
|
|
|
59
57
|
const { tag, workspace } = flags;
|
|
60
58
|
try {
|
|
61
59
|
const workDir = (await this.getProjectRoot()).directory;
|
|
62
|
-
|
|
63
|
-
const projectId = await this.getProjectId();
|
|
64
|
-
const dataset = cliConfig.api?.dataset;
|
|
65
|
-
if (!projectId) {
|
|
66
|
-
this.error(NO_PROJECT_ID, {
|
|
67
|
-
exit: 1
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
if (!dataset) {
|
|
71
|
-
this.error(NO_DATASET_ID, {
|
|
72
|
-
exit: 1
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
const result = await deploySchemas({
|
|
76
|
-
extractManifest: flags['extract-manifest'],
|
|
77
|
-
manifestDir: flags['manifest-dir'],
|
|
60
|
+
await deploySchemas({
|
|
78
61
|
output: this.output,
|
|
79
62
|
tag,
|
|
80
63
|
verbose: flags['verbose'],
|
|
81
64
|
workDir,
|
|
82
65
|
workspaceName: workspace
|
|
83
66
|
});
|
|
84
|
-
|
|
85
|
-
this.error('Failed to deploy schemas', {
|
|
86
|
-
exit: 1
|
|
87
|
-
});
|
|
88
|
-
}
|
|
67
|
+
this.log(`${styleText('gray', '↳ List deployed schemas with:')} ${styleText('cyan', 'sanity schema list')}`);
|
|
89
68
|
} catch (error) {
|
|
69
|
+
if (error instanceof SchemaExtractionError && error.validation && error.validation.length > 0) {
|
|
70
|
+
this.output.log(formatSchemaValidation(error.validation));
|
|
71
|
+
this.exit(1);
|
|
72
|
+
}
|
|
90
73
|
schemasDeployDebug('Failed to deploy schemas', error);
|
|
91
|
-
|
|
74
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
75
|
+
this.error(`Failed to deploy schemas:\n${errorMessage}`, {
|
|
92
76
|
exit: 1
|
|
93
77
|
});
|
|
94
78
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/schema/deploy.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {parseStringFlag, SanityCommand} from '@sanity/cli-core'\n\nimport {deploySchemas} from '../../actions/schema/deploySchemas.js'\nimport {schemasDeployDebug} from '../../actions/schema/utils/debug.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/schema/deploy.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {parseStringFlag, SanityCommand} from '@sanity/cli-core'\n\nimport {deploySchemas} from '../../actions/schema/deploySchemas.js'\nimport {formatSchemaValidation} from '../../actions/schema/formatSchemaValidation.js'\nimport {schemasDeployDebug} from '../../actions/schema/utils/debug.js'\nimport {SchemaExtractionError} from '../../actions/schema/utils/SchemaExtractionError.js'\nimport {parseTag} from '../../actions/schema/utils/schemaStoreValidation.js'\n\nconst description = `\nDeploy schema documents into workspace datasets.\n\n**Note**: This command is experimental and subject to change.\n\nThis operation (re-)generates a manifest file describing the sanity config workspace by default.\nTo re-use an existing manifest file, use --no-extract-manifest.\n`.trim()\n\nexport class DeploySchemaCommand extends SanityCommand<typeof DeploySchemaCommand> {\n static override description = description\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Deploy all workspace schemas',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --workspace default',\n description: 'Deploy the schema for only the workspace \"default\"',\n },\n ]\n\n static override flags = {\n 'extract-manifest': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Disables manifest generation - the command will fail if no manifest exists',\n }),\n 'manifest-dir': Flags.directory({\n default: './dist/static',\n description: 'Directory containing manifest file',\n helpValue: '<directory>',\n }),\n tag: Flags.string({\n description: 'Add a tag suffix to the schema id',\n helpValue: '<tag>',\n parse: parseTag,\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Print detailed information during deployment',\n }),\n workspace: Flags.string({\n description: 'The name of the workspace to deploy a schema for',\n helpValue: '<name>',\n parse: async (input) => parseStringFlag('workspace', input),\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeploySchemaCommand)\n const {tag, workspace} = flags\n\n try {\n const workDir = (await this.getProjectRoot()).directory\n\n await deploySchemas({\n output: this.output,\n tag,\n verbose: flags['verbose'],\n workDir,\n workspaceName: workspace,\n })\n\n this.log(\n `${styleText('gray', '↳ List deployed schemas with:')} ${styleText('cyan', 'sanity schema list')}`,\n )\n } catch (error) {\n if (\n error instanceof SchemaExtractionError &&\n error.validation &&\n error.validation.length > 0\n ) {\n this.output.log(formatSchemaValidation(error.validation))\n this.exit(1)\n }\n\n schemasDeployDebug('Failed to deploy schemas', error)\n const errorMessage = error instanceof Error ? error.message : String(error)\n this.error(`Failed to deploy schemas:\\n${errorMessage}`, {exit: 1})\n }\n }\n}\n"],"names":["styleText","Flags","parseStringFlag","SanityCommand","deploySchemas","formatSchemaValidation","schemasDeployDebug","SchemaExtractionError","parseTag","description","trim","DeploySchemaCommand","examples","command","flags","boolean","allowNo","default","directory","helpValue","tag","string","parse","verbose","workspace","input","run","workDir","getProjectRoot","output","workspaceName","log","error","validation","length","exit","errorMessage","Error","message","String"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,KAAK,QAAO,cAAa;AACjC,SAAQC,eAAe,EAAEC,aAAa,QAAO,mBAAkB;AAE/D,SAAQC,aAAa,QAAO,wCAAuC;AACnE,SAAQC,sBAAsB,QAAO,iDAAgD;AACrF,SAAQC,kBAAkB,QAAO,sCAAqC;AACtE,SAAQC,qBAAqB,QAAO,sDAAqD;AACzF,SAAQC,QAAQ,QAAO,sDAAqD;AAE5E,MAAMC,cAAc,CAAC;;;;;;;AAOrB,CAAC,CAACC,IAAI;AAEN,OAAO,MAAMC,4BAA4BR;IACvC,OAAgBM,cAAcA,YAAW;IAEzC,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;QACA;YACEI,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,OAAgBK,QAAQ;QACtB,oBAAoBb,MAAMc,OAAO,CAAC;YAChCC,SAAS;YACTC,SAAS;YACTR,aAAa;QACf;QACA,gBAAgBR,MAAMiB,SAAS,CAAC;YAC9BD,SAAS;YACTR,aAAa;YACbU,WAAW;QACb;QACAC,KAAKnB,MAAMoB,MAAM,CAAC;YAChBZ,aAAa;YACbU,WAAW;YACXG,OAAOd;QACT;QACAe,SAAStB,MAAMc,OAAO,CAAC;YACrBE,SAAS;YACTR,aAAa;QACf;QACAe,WAAWvB,MAAMoB,MAAM,CAAC;YACtBZ,aAAa;YACbU,WAAW;YACXG,OAAO,OAAOG,QAAUvB,gBAAgB,aAAauB;QACvD;IACF,EAAC;IAED,MAAaC,MAAqB;QAChC,MAAM,EAACZ,KAAK,EAAC,GAAG,MAAM,IAAI,CAACQ,KAAK,CAACX;QACjC,MAAM,EAACS,GAAG,EAAEI,SAAS,EAAC,GAAGV;QAEzB,IAAI;YACF,MAAMa,UAAU,AAAC,CAAA,MAAM,IAAI,CAACC,cAAc,EAAC,EAAGV,SAAS;YAEvD,MAAMd,cAAc;gBAClByB,QAAQ,IAAI,CAACA,MAAM;gBACnBT;gBACAG,SAAST,KAAK,CAAC,UAAU;gBACzBa;gBACAG,eAAeN;YACjB;YAEA,IAAI,CAACO,GAAG,CACN,GAAG/B,UAAU,QAAQ,iCAAiC,CAAC,EAAEA,UAAU,QAAQ,uBAAuB;QAEtG,EAAE,OAAOgC,OAAO;YACd,IACEA,iBAAiBzB,yBACjByB,MAAMC,UAAU,IAChBD,MAAMC,UAAU,CAACC,MAAM,GAAG,GAC1B;gBACA,IAAI,CAACL,MAAM,CAACE,GAAG,CAAC1B,uBAAuB2B,MAAMC,UAAU;gBACvD,IAAI,CAACE,IAAI,CAAC;YACZ;YAEA7B,mBAAmB,4BAA4B0B;YAC/C,MAAMI,eAAeJ,iBAAiBK,QAAQL,MAAMM,OAAO,GAAGC,OAAOP;YACrE,IAAI,CAACA,KAAK,CAAC,CAAC,2BAA2B,EAAEI,cAAc,EAAE;gBAACD,MAAM;YAAC;QACnE;IACF;AACF"}
|
|
@@ -3,7 +3,6 @@ import { SanityCommand, subdebug } from '@sanity/cli-core';
|
|
|
3
3
|
import { input, select } from '@sanity/cli-core/ux';
|
|
4
4
|
import { validateRole } from '../../actions/tokens/validateRole.js';
|
|
5
5
|
import { createToken, getTokenRoles } from '../../services/tokens.js';
|
|
6
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
7
6
|
const tokensAddDebug = subdebug('tokens:add');
|
|
8
7
|
export class AddTokenCommand extends SanityCommand {
|
|
9
8
|
static args = {
|
|
@@ -51,11 +50,6 @@ export class AddTokenCommand extends SanityCommand {
|
|
|
51
50
|
const { label: givenLabel } = args;
|
|
52
51
|
const { json, role } = flags;
|
|
53
52
|
const projectId = await this.getProjectId();
|
|
54
|
-
if (!projectId) {
|
|
55
|
-
this.error(NO_PROJECT_ID, {
|
|
56
|
-
exit: 1
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
53
|
try {
|
|
60
54
|
const label = givenLabel || await this.promptForLabel();
|
|
61
55
|
const roleName = await (role ? validateRole(role, projectId) : this.promptForRole(projectId));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/add.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input, select} from '@sanity/cli-core/ux'\n\nimport {validateRole} from '../../actions/tokens/validateRole.js'\nimport {createToken, getTokenRoles} from '../../services/tokens.js'\
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/add.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input, select} from '@sanity/cli-core/ux'\n\nimport {validateRole} from '../../actions/tokens/validateRole.js'\nimport {createToken, getTokenRoles} from '../../services/tokens.js'\n\nconst tokensAddDebug = subdebug('tokens:add')\n\nexport class AddTokenCommand extends SanityCommand<typeof AddTokenCommand> {\n static override args = {\n label: Args.string({\n description: 'Label for the new token',\n required: false,\n }),\n }\n\n static override description = 'Create a new API token for this project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\"',\n description: 'Create a token with a label',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"My API Token\" --role=editor',\n description: 'Create a token with editor role',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"CI Token\" --role=editor --yes',\n description: 'Create a token in unattended mode',\n },\n {\n command: '<%= config.bin %> <%= command.id %> \"API Token\" --json',\n description: 'Output token information as JSON',\n },\n ]\n\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output as JSON',\n }),\n role: Flags.string({\n description: 'Role to assign to the token',\n helpValue: 'viewer',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description: 'Skip prompts and use defaults (unattended mode)',\n }),\n }\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(AddTokenCommand)\n const {label: givenLabel} = args\n const {json, role} = flags\n\n const projectId = await this.getProjectId()\n\n try {\n const label = givenLabel || (await this.promptForLabel())\n const roleName = await (role ? validateRole(role, projectId) : this.promptForRole(projectId))\n\n tokensAddDebug(`Creating token for project ${projectId}`, {label, roleName})\n const token = await createToken({\n label,\n projectId,\n roleName,\n })\n\n if (json) {\n this.log(JSON.stringify(token, null, 2))\n return\n }\n\n this.log('Token created successfully!')\n this.log(`Label: ${token.label}`)\n this.log(`ID: ${token.id}`)\n this.log(`Role: ${token.roles.map((r) => r.title).join(', ')}`)\n this.log(`Token: ${token.key}`)\n this.log('')\n this.log('Copy the token above – this is your only chance to do so!')\n } catch (error) {\n const err = error as Error\n\n tokensAddDebug(`Error creating token for project ${projectId}`, err)\n this.error(`Token creation failed:\\n${err.message}`, {exit: 1})\n }\n }\n\n private async promptForLabel(): Promise<string> {\n if (this.isUnattended()) {\n this.error(\n 'Token label is required in non-interactive mode. Provide a label as an argument.',\n {\n exit: 1,\n },\n )\n }\n\n const label = await input({\n message: 'Token label:',\n validate: (value) => {\n if (!value || !value.trim()) {\n return 'Label cannot be empty'\n }\n return true\n },\n })\n\n return label\n }\n\n private async promptForRole(projectId: string): Promise<string> {\n if (this.isUnattended()) {\n return 'viewer' // Default role for unattended mode\n }\n\n const roles = await getTokenRoles(projectId)\n const robotRoles = roles.filter((role) => role.appliesToRobots)\n\n tokensAddDebug('Robot roles', {robotRoles})\n\n if (robotRoles.length === 0) {\n this.error('No roles available for tokens', {exit: 1})\n }\n\n const selectedRoleName = await select({\n choices: robotRoles.map((role) => ({\n name: `${role.title} (${role.name})`,\n short: role.title,\n value: role.name,\n })),\n default: 'viewer',\n message: 'Select role for the token:',\n })\n\n return selectedRoleName\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","select","validateRole","createToken","getTokenRoles","tokensAddDebug","AddTokenCommand","args","label","string","description","required","examples","command","flags","json","boolean","default","role","helpValue","yes","char","run","parse","givenLabel","projectId","getProjectId","promptForLabel","roleName","promptForRole","token","log","JSON","stringify","id","roles","map","r","title","join","key","error","err","message","exit","isUnattended","validate","value","trim","robotRoles","filter","appliesToRobots","length","selectedRoleName","choices","name","short"],"mappings":"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"}
|
|
@@ -3,7 +3,6 @@ import { SanityCommand, subdebug } from '@sanity/cli-core';
|
|
|
3
3
|
import { confirm, select } from '@sanity/cli-core/ux';
|
|
4
4
|
import { ClientError } from '@sanity/client';
|
|
5
5
|
import { deleteToken, getTokens } from '../../services/tokens.js';
|
|
6
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
7
6
|
const deleteTokenDebug = subdebug('tokens:delete');
|
|
8
7
|
export class DeleteTokensCommand extends SanityCommand {
|
|
9
8
|
static args = {
|
|
@@ -48,11 +47,6 @@ export class DeleteTokensCommand extends SanityCommand {
|
|
|
48
47
|
}
|
|
49
48
|
// Ensure we have project context
|
|
50
49
|
const projectId = await this.getProjectId();
|
|
51
|
-
if (!projectId) {
|
|
52
|
-
this.error(NO_PROJECT_ID, {
|
|
53
|
-
exit: 1
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
50
|
this.projectId = projectId;
|
|
57
51
|
let tokenId;
|
|
58
52
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/delete.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {confirm, select} from '@sanity/cli-core/ux'\nimport {ClientError} from '@sanity/client'\n\nimport {deleteToken, getTokens} from '../../services/tokens.js'\
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/delete.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {confirm, select} from '@sanity/cli-core/ux'\nimport {ClientError} from '@sanity/client'\n\nimport {deleteToken, getTokens} from '../../services/tokens.js'\n\nconst deleteTokenDebug = subdebug('tokens:delete')\n\nexport class DeleteTokensCommand extends SanityCommand<typeof DeleteTokensCommand> {\n static override args = {\n tokenId: Args.string({\n description: 'Token ID to delete (will prompt if not provided)',\n required: false,\n }),\n }\n\n static override description = 'Delete an API token from this project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Interactively select and delete a token',\n },\n {\n command: '<%= config.bin %> <%= command.id %> silJ2lFmK6dONB',\n description: 'Delete a specific token by ID',\n },\n {\n command: '<%= config.bin %> <%= command.id %> silJ2lFmK6dONB --yes',\n description: 'Delete a specific token without confirmation prompt',\n },\n ]\n\n static override flags = {\n yes: Flags.boolean({\n aliases: ['y'],\n description: 'Skip confirmation prompt (unattended mode)',\n required: false,\n }),\n }\n\n private projectId!: string\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(DeleteTokensCommand)\n\n const unattended = flags.yes\n const {tokenId: givenTokenId} = args\n\n if (unattended && !givenTokenId) {\n this.error(\n 'Token ID is required in non-interactive mode. Provide a token ID as an argument.',\n {exit: 1},\n )\n }\n\n // Ensure we have project context\n const projectId = await this.getProjectId()\n\n this.projectId = projectId\n\n let tokenId: string | undefined\n\n try {\n tokenId = givenTokenId || (await this.getTokenIdFromList())\n\n if (!unattended) {\n const confirmed = await confirm({\n default: false,\n message: `Are you sure you want to delete the token with ID \"${tokenId}\"?`,\n })\n\n if (!confirmed) {\n this.error('Operation cancelled', {exit: 1})\n }\n }\n\n await deleteToken({\n projectId: this.projectId,\n tokenId,\n })\n\n this.log('Token deleted successfully')\n } catch (error) {\n if (error instanceof ClientError && error.response.statusCode === 404) {\n this.error(`Token with ID \"${tokenId}\" not found`, {exit: 1})\n }\n\n const err = error as Error\n deleteTokenDebug(`Error deleting token`, err)\n this.error(`Token deletion failed:\\n${err.message}`, {exit: 1})\n }\n }\n\n private async getTokenIdFromList() {\n const tokens = await getTokens(this.projectId)\n\n if (tokens.length === 0) {\n this.error('No tokens found', {exit: 1})\n }\n\n const choices = tokens.map((token) => ({\n name: `${token.label} (${(token.roles || []).map((r) => r.title).join(', ')})`,\n value: token.id,\n }))\n\n return select({\n choices,\n message: 'Select token to delete:',\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","confirm","select","ClientError","deleteToken","getTokens","deleteTokenDebug","DeleteTokensCommand","args","tokenId","string","description","required","examples","command","flags","yes","boolean","aliases","projectId","run","parse","unattended","givenTokenId","error","exit","getProjectId","getTokenIdFromList","confirmed","default","message","log","response","statusCode","err","tokens","length","choices","map","token","name","label","roles","r","title","join","value","id"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,OAAO,EAAEC,MAAM,QAAO,sBAAqB;AACnD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,WAAW,EAAEC,SAAS,QAAO,2BAA0B;AAE/D,MAAMC,mBAAmBN,SAAS;AAElC,OAAO,MAAMO,4BAA4BR;IACvC,OAAgBS,OAAO;QACrBC,SAASZ,KAAKa,MAAM,CAAC;YACnBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,wCAAuC;IAErE,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtBC,KAAKlB,MAAMmB,OAAO,CAAC;YACjBC,SAAS;gBAAC;aAAI;YACdP,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAEOO,UAAkB;IAE1B,MAAaC,MAAqB;QAChC,MAAM,EAACZ,IAAI,EAAEO,KAAK,EAAC,GAAG,MAAM,IAAI,CAACM,KAAK,CAACd;QAEvC,MAAMe,aAAaP,MAAMC,GAAG;QAC5B,MAAM,EAACP,SAASc,YAAY,EAAC,GAAGf;QAEhC,IAAIc,cAAc,CAACC,cAAc;YAC/B,IAAI,CAACC,KAAK,CACR,oFACA;gBAACC,MAAM;YAAC;QAEZ;QAEA,iCAAiC;QACjC,MAAMN,YAAY,MAAM,IAAI,CAACO,YAAY;QAEzC,IAAI,CAACP,SAAS,GAAGA;QAEjB,IAAIV;QAEJ,IAAI;YACFA,UAAUc,gBAAiB,MAAM,IAAI,CAACI,kBAAkB;YAExD,IAAI,CAACL,YAAY;gBACf,MAAMM,YAAY,MAAM3B,QAAQ;oBAC9B4B,SAAS;oBACTC,SAAS,CAAC,mDAAmD,EAAErB,QAAQ,EAAE,CAAC;gBAC5E;gBAEA,IAAI,CAACmB,WAAW;oBACd,IAAI,CAACJ,KAAK,CAAC,uBAAuB;wBAACC,MAAM;oBAAC;gBAC5C;YACF;YAEA,MAAMrB,YAAY;gBAChBe,WAAW,IAAI,CAACA,SAAS;gBACzBV;YACF;YAEA,IAAI,CAACsB,GAAG,CAAC;QACX,EAAE,OAAOP,OAAO;YACd,IAAIA,iBAAiBrB,eAAeqB,MAAMQ,QAAQ,CAACC,UAAU,KAAK,KAAK;gBACrE,IAAI,CAACT,KAAK,CAAC,CAAC,eAAe,EAAEf,QAAQ,WAAW,CAAC,EAAE;oBAACgB,MAAM;gBAAC;YAC7D;YAEA,MAAMS,MAAMV;YACZlB,iBAAiB,CAAC,oBAAoB,CAAC,EAAE4B;YACzC,IAAI,CAACV,KAAK,CAAC,CAAC,wBAAwB,EAAEU,IAAIJ,OAAO,EAAE,EAAE;gBAACL,MAAM;YAAC;QAC/D;IACF;IAEA,MAAcE,qBAAqB;QACjC,MAAMQ,SAAS,MAAM9B,UAAU,IAAI,CAACc,SAAS;QAE7C,IAAIgB,OAAOC,MAAM,KAAK,GAAG;YACvB,IAAI,CAACZ,KAAK,CAAC,mBAAmB;gBAACC,MAAM;YAAC;QACxC;QAEA,MAAMY,UAAUF,OAAOG,GAAG,CAAC,CAACC,QAAW,CAAA;gBACrCC,MAAM,GAAGD,MAAME,KAAK,CAAC,EAAE,EAAE,AAACF,CAAAA,MAAMG,KAAK,IAAI,EAAE,AAAD,EAAGJ,GAAG,CAAC,CAACK,IAAMA,EAAEC,KAAK,EAAEC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC9EC,OAAOP,MAAMQ,EAAE;YACjB,CAAA;QAEA,OAAO7C,OAAO;YACZmC;YACAP,SAAS;QACX;IACF;AACF"}
|
|
@@ -2,7 +2,6 @@ import { Flags } from '@oclif/core';
|
|
|
2
2
|
import { SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
3
|
import { Table } from 'console-table-printer';
|
|
4
4
|
import { getTokens } from '../../services/tokens.js';
|
|
5
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
6
5
|
import { getErrorMessage } from '../../util/getErrorMessage.js';
|
|
7
6
|
const listTokenDebug = subdebug('tokens:list');
|
|
8
7
|
export class TokensListCommand extends SanityCommand {
|
|
@@ -29,11 +28,6 @@ export class TokensListCommand extends SanityCommand {
|
|
|
29
28
|
const outputJson = json ?? false;
|
|
30
29
|
// Ensure we have project context
|
|
31
30
|
const projectId = await this.getProjectId();
|
|
32
|
-
if (!projectId) {
|
|
33
|
-
this.error(NO_PROJECT_ID, {
|
|
34
|
-
exit: 1
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
31
|
let tokens;
|
|
38
32
|
try {
|
|
39
33
|
tokens = await getTokens(projectId);
|