@sanity/cli 6.0.0-alpha.9 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +602 -291
- package/bin/run.js +2 -0
- package/dist/SanityHelp.js +51 -23
- package/dist/SanityHelp.js.map +1 -1
- package/dist/actions/auth/authServer.js +28 -22
- package/dist/actions/auth/authServer.js.map +1 -1
- package/dist/actions/auth/login/getProvider.js +49 -38
- package/dist/actions/auth/login/getProvider.js.map +1 -1
- package/dist/actions/auth/login/getSSOProvider.js +25 -19
- package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
- package/dist/actions/auth/login/login.js +12 -33
- package/dist/actions/auth/login/login.js.map +1 -1
- package/dist/actions/auth/types.js.map +1 -1
- package/dist/actions/backup/downloadAsset.js +9 -9
- package/dist/actions/backup/downloadAsset.js.map +1 -1
- package/dist/actions/backup/downloadDocument.js +8 -8
- package/dist/actions/backup/downloadDocument.js.map +1 -1
- package/dist/actions/build/buildApp.js +55 -18
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStaticFiles.js +3 -2
- package/dist/actions/build/buildStaticFiles.js.map +1 -1
- package/dist/actions/build/buildStudio.js +72 -44
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/build/buildVendorDependencies.js +18 -52
- package/dist/actions/build/buildVendorDependencies.js.map +1 -1
- package/dist/actions/build/checkRequiredDependencies.js +13 -8
- package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
- package/dist/actions/build/checkStudioDependencyVersions.js +19 -17
- 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/renderDocument.js +6 -10
- package/dist/actions/build/renderDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +4 -4
- package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +3 -3
- package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +1 -1
- 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/renderDocumentWorker/getDocumentComponent.js +2 -2
- package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +1 -1
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
- package/dist/actions/build/shouldAutoUpdate.js +2 -0
- package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
- package/dist/actions/build/types.js.map +1 -1
- package/dist/actions/build/writeFavicons.js +3 -5
- package/dist/actions/build/writeFavicons.js.map +1 -1
- package/dist/actions/build/writeSanityRuntime.js +4 -3
- package/dist/actions/build/writeSanityRuntime.js.map +1 -1
- package/dist/actions/codemods/reactIconsV3.js +2 -2
- package/dist/actions/codemods/reactIconsV3.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/determineDatasetAclMode.js.map +1 -1
- package/dist/actions/dataset/resolveDataset.js +26 -0
- package/dist/actions/dataset/resolveDataset.js.map +1 -0
- package/dist/actions/debug/formatters.js +22 -0
- package/dist/actions/debug/formatters.js.map +1 -0
- package/dist/actions/deploy/createStudioUserApplication.js +17 -4
- package/dist/actions/deploy/createStudioUserApplication.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +41 -15
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +92 -44
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deployStudioSchemasAndManifests.js +55 -0
- package/dist/actions/deploy/deployStudioSchemasAndManifests.js.map +1 -0
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +120 -0
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -0
- package/dist/actions/deploy/findUserApplicationForStudio.js +35 -12
- package/dist/actions/deploy/findUserApplicationForStudio.js.map +1 -1
- package/dist/actions/deploy/types.js +10 -1
- package/dist/actions/deploy/types.js.map +1 -1
- package/dist/actions/deploy/urlUtils.js +21 -0
- package/dist/actions/deploy/urlUtils.js.map +1 -0
- 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 +14 -14
- package/dist/actions/dev/startStudioDevServer.js.map +1 -1
- package/dist/actions/doctor/checks/cliInstallation.js +56 -0
- package/dist/actions/doctor/checks/cliInstallation.js.map +1 -0
- package/dist/actions/doctor/checks/index.js +16 -0
- package/dist/actions/doctor/checks/index.js.map +1 -0
- package/dist/actions/doctor/runDoctorChecks.js +56 -0
- package/dist/actions/doctor/runDoctorChecks.js.map +1 -0
- package/dist/actions/doctor/types.js +3 -0
- package/dist/actions/doctor/types.js.map +1 -0
- 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 +4 -4
- 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/documents/validation/reporters/prettyReporter/formatDocumentValidation.js +1 -1
- package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js.map +1 -1
- package/dist/actions/documents/validation/reporters/prettyReporter/tree.js +108 -0
- package/dist/actions/documents/validation/reporters/prettyReporter/tree.js.map +1 -0
- package/dist/actions/graphql/SchemaError.js +4 -26
- 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 +5 -5
- package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
- package/dist/actions/graphql/extractGraphQLAPIs.js +150 -0
- package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -0
- package/dist/actions/graphql/extractGraphQLAPIs.worker.js +12 -0
- package/dist/actions/graphql/extractGraphQLAPIs.worker.js.map +1 -0
- 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/gen1/index.js +5 -5
- package/dist/actions/graphql/gen1/index.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/gen2/index.js +6 -6
- package/dist/actions/graphql/gen2/index.js.map +1 -1
- package/dist/actions/graphql/gen3/generateTypeQueries.js +3 -4
- package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
- package/dist/actions/graphql/gen3/index.js +6 -7
- package/dist/actions/graphql/gen3/index.js.map +1 -1
- package/dist/actions/graphql/getGraphQLAPIs.js +15 -57
- package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
- package/dist/actions/graphql/getGraphQLAPIs.worker.js +75 -106
- package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
- package/dist/actions/graphql/helpers.js +13 -0
- package/dist/actions/graphql/helpers.js.map +1 -1
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +187 -0
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -0
- package/dist/actions/graphql/types.js +1 -1
- package/dist/actions/graphql/types.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +10 -8
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/bootstrapRemoteTemplate.js +6 -5
- package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
- package/dist/actions/init/bootstrapTemplate.js.map +1 -1
- package/dist/actions/init/checkNextJsReactCompatibility.js +1 -1
- package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
- package/dist/actions/init/createAppCliConfig.js.map +1 -1
- package/dist/actions/init/createCliConfig.js.map +1 -1
- package/dist/actions/init/createPackageManifest.js +21 -9
- package/dist/actions/init/createPackageManifest.js.map +1 -1
- package/dist/actions/init/remoteTemplate.js +1 -2
- package/dist/actions/init/remoteTemplate.js.map +1 -1
- package/dist/actions/init/sdkAppDependencies.js +19 -0
- package/dist/actions/init/sdkAppDependencies.js.map +1 -0
- package/dist/actions/init/studioDependencies.js.map +1 -0
- package/dist/actions/init/templates/appQuickstart.js +1 -22
- package/dist/actions/init/templates/appQuickstart.js.map +1 -1
- package/dist/actions/init/templates/appSanityUi.js +3 -22
- package/dist/actions/init/templates/appSanityUi.js.map +1 -1
- package/dist/actions/init/types.js.map +1 -1
- package/dist/actions/manifest/SchemaIcon.js +6 -4
- package/dist/actions/manifest/SchemaIcon.js.map +1 -1
- package/dist/actions/manifest/blockTypeTransformer.js +67 -0
- package/dist/actions/manifest/blockTypeTransformer.js.map +1 -0
- package/dist/actions/manifest/debug.js +4 -0
- package/dist/actions/manifest/debug.js.map +1 -0
- package/dist/actions/manifest/extractAppManifest.js +39 -22
- package/dist/actions/manifest/extractAppManifest.js.map +1 -1
- package/dist/actions/manifest/extractManifest.js +27 -78
- package/dist/actions/manifest/extractManifest.js.map +1 -1
- package/dist/actions/manifest/extractManifest.worker.js +30 -0
- package/dist/actions/manifest/extractManifest.worker.js.map +1 -0
- package/dist/actions/manifest/extractWorkspaceManifest.js +31 -372
- package/dist/actions/manifest/extractWorkspaceManifest.js.map +1 -1
- package/dist/actions/manifest/iconResolver.js +30 -0
- package/dist/actions/manifest/iconResolver.js.map +1 -0
- package/dist/actions/manifest/referenceTransformer.js +51 -0
- package/dist/actions/manifest/referenceTransformer.js.map +1 -0
- package/dist/actions/manifest/schemaTypeHelpers.js +2 -2
- package/dist/actions/manifest/schemaTypeHelpers.js.map +1 -1
- package/dist/actions/manifest/schemaTypeTransformer.js +168 -0
- package/dist/actions/manifest/schemaTypeTransformer.js.map +1 -0
- package/dist/actions/manifest/transformerUtils.js +40 -0
- package/dist/actions/manifest/transformerUtils.js.map +1 -0
- package/dist/actions/manifest/types.js +5 -0
- package/dist/actions/manifest/types.js.map +1 -1
- package/dist/actions/manifest/validationTransformer.js +84 -0
- package/dist/actions/manifest/validationTransformer.js.map +1 -0
- package/dist/actions/manifest/writeManifestFile.js +30 -0
- package/dist/actions/manifest/writeManifestFile.js.map +1 -0
- package/dist/actions/manifest/writeWorkspaceFiles.js +30 -0
- package/dist/actions/manifest/writeWorkspaceFiles.js.map +1 -0
- package/dist/actions/mcp/detectAvailableEditors.js +34 -13
- package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
- package/dist/actions/mcp/editorConfigs.js +231 -109
- package/dist/actions/mcp/editorConfigs.js.map +1 -1
- package/dist/actions/mcp/promptForMCPSetup.js +16 -7
- package/dist/actions/mcp/promptForMCPSetup.js.map +1 -1
- package/dist/actions/mcp/setupMCP.js +62 -23
- package/dist/actions/mcp/setupMCP.js.map +1 -1
- package/dist/actions/mcp/types.js.map +1 -1
- package/dist/actions/mcp/validateEditorTokens.js +56 -0
- package/dist/actions/mcp/validateEditorTokens.js.map +1 -0
- package/dist/actions/mcp/writeMCPConfig.js +27 -15
- package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
- package/dist/actions/media/buildNdjsonIndex.js +32 -0
- package/dist/actions/media/buildNdjsonIndex.js.map +1 -0
- package/dist/actions/media/importAspects.js +2 -11
- package/dist/actions/media/importAspects.js.map +1 -1
- package/dist/actions/media/importMedia.js +22 -18
- package/dist/actions/media/importMedia.js.map +1 -1
- package/dist/actions/organizations/findOrganizationByUserName.js +5 -0
- package/dist/actions/organizations/findOrganizationByUserName.js.map +1 -0
- package/dist/actions/organizations/getOrganization.js +3 -2
- package/dist/actions/organizations/getOrganization.js.map +1 -1
- package/dist/actions/organizations/getOrganizationChoices.js +27 -19
- package/dist/actions/organizations/getOrganizationChoices.js.map +1 -1
- package/dist/actions/organizations/types.js +3 -0
- package/dist/actions/organizations/types.js.map +1 -0
- package/dist/actions/projects/getManageUrl.js +1 -2
- package/dist/actions/projects/getManageUrl.js.map +1 -1
- package/dist/actions/schema/deleteSchemaAction.js +14 -30
- package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
- package/dist/actions/schema/deploySchemas.js +22 -91
- package/dist/actions/schema/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSanitySchema.worker.js +0 -5
- package/dist/actions/schema/extractSanitySchema.worker.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/extractSchema.js +8 -40
- package/dist/actions/schema/extractSchema.js.map +1 -1
- package/dist/actions/schema/extractSchemaWatcher.js +128 -0
- package/dist/actions/schema/extractSchemaWatcher.js.map +1 -0
- package/dist/actions/schema/formatSchemaValidation.js +5 -1
- package/dist/actions/schema/formatSchemaValidation.js.map +1 -1
- package/dist/actions/schema/getExtractOptions.js +16 -0
- package/dist/actions/schema/getExtractOptions.js.map +1 -0
- package/dist/actions/schema/listSchemas.js +53 -56
- package/dist/actions/schema/listSchemas.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 +39 -0
- package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
- package/dist/actions/schema/types.js +8 -0
- package/dist/actions/schema/types.js.map +1 -1
- package/dist/actions/schema/uniqueWorkspaces.worker.js +24 -0
- package/dist/actions/schema/uniqueWorkspaces.worker.js.map +1 -0
- package/dist/actions/schema/updateWorkspaceSchema.js +63 -0
- package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -0
- package/dist/actions/schema/uploadSchemaToLexicon.js +87 -0
- package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -0
- package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
- package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
- package/dist/actions/schema/utils/schemaStoreValidation.js +1 -15
- 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/validateSchema.worker.js +1 -8
- package/dist/actions/schema/validateSchema.worker.js.map +1 -1
- package/dist/actions/schema/watchExtractSchema.js +72 -0
- package/dist/actions/schema/watchExtractSchema.js.map +1 -0
- package/dist/actions/telemetry/isTrueish.js +10 -0
- package/dist/actions/telemetry/isTrueish.js.map +1 -0
- package/dist/actions/telemetry/resolveConsent.js +2 -1
- package/dist/actions/telemetry/resolveConsent.js.map +1 -1
- package/dist/actions/telemetry/setConsent.js +2 -1
- package/dist/actions/telemetry/setConsent.js.map +1 -1
- package/dist/actions/telemetry/telemetryDebug.js +2 -2
- package/dist/actions/telemetry/telemetryDebug.js.map +1 -1
- package/dist/actions/users/getMembersForProject.js.map +1 -1
- package/dist/actions/users/getPendingInvitations.js +1 -1
- package/dist/actions/users/getPendingInvitations.js.map +1 -1
- package/dist/actions/users/types.js.map +1 -1
- package/dist/actions/versions/filterSanityModules.js.map +1 -1
- package/dist/actions/versions/findSanityModulesVersions.js +2 -3
- package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
- package/dist/actions/versions/getFormatters.js +1 -1
- package/dist/actions/versions/getFormatters.js.map +1 -1
- package/dist/actions/versions/tryFindLatestVersion.js +1 -1
- package/dist/actions/versions/tryFindLatestVersion.js.map +1 -1
- package/dist/commands/backup/disable.js +22 -7
- package/dist/commands/backup/disable.js.map +1 -1
- package/dist/commands/backup/download.js +19 -10
- package/dist/commands/backup/download.js.map +1 -1
- package/dist/commands/backup/enable.js +22 -7
- package/dist/commands/backup/enable.js.map +1 -1
- package/dist/commands/backup/list.js +20 -8
- package/dist/commands/backup/list.js.map +1 -1
- package/dist/commands/build.js +2 -5
- package/dist/commands/build.js.map +1 -1
- package/dist/commands/cors/add.js +20 -7
- package/dist/commands/cors/add.js.map +1 -1
- package/dist/commands/cors/delete.js +22 -7
- package/dist/commands/cors/delete.js.map +1 -1
- package/dist/commands/cors/list.js +22 -7
- package/dist/commands/cors/list.js.map +1 -1
- package/dist/commands/dataset/alias/create.js +26 -7
- package/dist/commands/dataset/alias/create.js.map +1 -1
- package/dist/commands/dataset/alias/delete.js +20 -7
- package/dist/commands/dataset/alias/delete.js.map +1 -1
- package/dist/commands/dataset/alias/link.js +20 -7
- package/dist/commands/dataset/alias/link.js.map +1 -1
- package/dist/commands/dataset/alias/unlink.js +20 -7
- package/dist/commands/dataset/alias/unlink.js.map +1 -1
- package/dist/commands/dataset/copy.js +45 -30
- package/dist/commands/dataset/copy.js.map +1 -1
- package/dist/commands/dataset/create.js +32 -7
- package/dist/commands/dataset/create.js.map +1 -1
- package/dist/commands/dataset/delete.js +16 -7
- package/dist/commands/dataset/delete.js.map +1 -1
- package/dist/commands/dataset/embeddings/disable.js +77 -0
- package/dist/commands/dataset/embeddings/disable.js.map +1 -0
- package/dist/commands/dataset/embeddings/enable.js +141 -0
- package/dist/commands/dataset/embeddings/enable.js.map +1 -0
- package/dist/commands/dataset/embeddings/status.js +72 -0
- package/dist/commands/dataset/embeddings/status.js.map +1 -0
- package/dist/commands/dataset/export.js +25 -16
- package/dist/commands/dataset/export.js.map +1 -1
- package/dist/commands/dataset/import.js +306 -1
- package/dist/commands/dataset/import.js.map +1 -1
- package/dist/commands/dataset/list.js +22 -7
- package/dist/commands/dataset/list.js.map +1 -1
- package/dist/commands/dataset/visibility/get.js +18 -7
- package/dist/commands/dataset/visibility/get.js.map +1 -1
- package/dist/commands/dataset/visibility/set.js +22 -7
- package/dist/commands/dataset/visibility/set.js.map +1 -1
- package/dist/commands/debug.js +4 -2
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/deploy.js +22 -11
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.js +2 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.js +125 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/documents/create.js +19 -12
- package/dist/commands/documents/create.js.map +1 -1
- package/dist/commands/documents/delete.js +19 -12
- package/dist/commands/documents/delete.js.map +1 -1
- package/dist/commands/documents/get.js +17 -12
- package/dist/commands/documents/get.js.map +1 -1
- package/dist/commands/documents/query.js +26 -18
- package/dist/commands/documents/query.js.map +1 -1
- package/dist/commands/documents/validate.js +32 -10
- package/dist/commands/documents/validate.js.map +1 -1
- package/dist/commands/graphql/deploy.js +58 -30
- package/dist/commands/graphql/deploy.js.map +1 -1
- package/dist/commands/graphql/list.js +15 -7
- package/dist/commands/graphql/list.js.map +1 -1
- package/dist/commands/graphql/undeploy.js +37 -19
- package/dist/commands/graphql/undeploy.js.map +1 -1
- package/dist/commands/hook/attempt.js +22 -7
- package/dist/commands/hook/attempt.js.map +1 -1
- package/dist/commands/hook/create.js +23 -8
- package/dist/commands/hook/create.js.map +1 -1
- package/dist/commands/hook/delete.js +22 -7
- package/dist/commands/hook/delete.js.map +1 -1
- package/dist/commands/hook/list.js +22 -7
- package/dist/commands/hook/list.js.map +1 -1
- package/dist/commands/hook/logs.js +21 -8
- package/dist/commands/hook/logs.js.map +1 -1
- package/dist/commands/init.js +55 -32
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +19 -6
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +8 -6
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/manage.js +0 -1
- package/dist/commands/manage.js.map +1 -1
- package/dist/commands/manifest/extract.js +14 -10
- package/dist/commands/manifest/extract.js.map +1 -1
- package/dist/commands/mcp/configure.js +4 -2
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/commands/media/create-aspect.js +4 -4
- package/dist/commands/media/create-aspect.js.map +1 -1
- package/dist/commands/media/delete-aspect.js +9 -7
- package/dist/commands/media/delete-aspect.js.map +1 -1
- package/dist/commands/media/deploy-aspect.js +22 -9
- package/dist/commands/media/deploy-aspect.js.map +1 -1
- package/dist/commands/media/export.js +9 -7
- package/dist/commands/media/export.js.map +1 -1
- package/dist/commands/media/import.js +10 -8
- package/dist/commands/media/import.js.map +1 -1
- package/dist/commands/preview.js +5 -8
- package/dist/commands/preview.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 +33 -34
- package/dist/commands/schema/delete.js.map +1 -1
- package/dist/commands/schema/deploy.js +19 -30
- package/dist/commands/schema/deploy.js.map +1 -1
- package/dist/commands/schema/extract.js +32 -4
- package/dist/commands/schema/extract.js.map +1 -1
- package/dist/commands/schema/list.js +10 -31
- package/dist/commands/schema/list.js.map +1 -1
- package/dist/commands/tokens/add.js +24 -7
- package/dist/commands/tokens/add.js.map +1 -1
- package/dist/commands/tokens/delete.js +20 -7
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +20 -7
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/users/invite.js +24 -7
- package/dist/commands/users/invite.js.map +1 -1
- package/dist/commands/users/list.js +76 -33
- 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/config/createCliConfig.js +1 -2
- package/dist/config/createCliConfig.js.map +1 -1
- package/dist/exports/_internal.d.ts +132 -0
- package/dist/exports/_internal.js +4 -0
- package/dist/exports/_internal.js.map +1 -0
- package/dist/exports/index.d.ts +113 -0
- package/dist/exports/index.js +6 -0
- package/dist/exports/index.js.map +1 -0
- package/dist/hooks/init/checkForUpdates.js +14 -0
- package/dist/hooks/init/checkForUpdates.js.map +1 -0
- package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
- package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
- package/dist/hooks/prerun/injectEnvVariables.js +9 -1
- package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
- package/dist/hooks/prerun/setupTelemetry.js +16 -10
- package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
- package/dist/prompts/promptForProject.js +64 -0
- package/dist/prompts/promptForProject.js.map +1 -0
- package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
- package/dist/prompts/promptForProviders.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/previewServer.js +2 -2
- package/dist/server/previewServer.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/auth.js +42 -3
- package/dist/services/auth.js.map +1 -1
- package/dist/services/datasets.js +7 -5
- package/dist/services/datasets.js.map +1 -1
- package/dist/services/docs.js +2 -2
- package/dist/services/docs.js.map +1 -1
- package/dist/services/embeddings.js +25 -0
- package/dist/services/embeddings.js.map +1 -0
- package/dist/services/getUrlHeaders.js +7 -18
- package/dist/services/getUrlHeaders.js.map +1 -1
- package/dist/services/grants.js +13 -0
- package/dist/services/grants.js.map +1 -0
- package/dist/services/graphql.js +1 -1
- package/dist/services/graphql.js.map +1 -1
- package/dist/services/mcp.js +55 -1
- package/dist/services/mcp.js.map +1 -1
- package/dist/services/projects.js +4 -2
- package/dist/services/projects.js.map +1 -1
- package/dist/services/schemas.js +1 -1
- package/dist/services/schemas.js.map +1 -1
- package/dist/services/telemetry.js +2 -1
- package/dist/services/telemetry.js.map +1 -1
- package/dist/services/userApplications.js +21 -6
- package/dist/services/userApplications.js.map +1 -1
- package/dist/telemetry/extractSchema.telemetry.js +10 -0
- package/dist/telemetry/extractSchema.telemetry.js.map +1 -1
- package/dist/types/grants.js +3 -0
- package/dist/types/grants.js.map +1 -0
- package/dist/types.js +3 -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/cliClient.js +5 -3
- package/dist/util/cliClient.js.map +1 -1
- package/dist/util/compareDependencyVersions.js +74 -38
- package/dist/util/compareDependencyVersions.js.map +1 -1
- package/dist/util/createExpiringConfig.js +64 -0
- package/dist/util/createExpiringConfig.js.map +1 -0
- package/dist/util/detectFramework.js +135 -0
- package/dist/util/detectFramework.js.map +1 -0
- package/dist/util/errorMessages.js +0 -1
- package/dist/util/errorMessages.js.map +1 -1
- package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
- package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
- package/dist/util/getCliVersion.js +1 -1
- package/dist/util/getCliVersion.js.map +1 -1
- package/dist/util/getLocalPackageVersion.js +33 -23
- package/dist/util/getLocalPackageVersion.js.map +1 -1
- package/dist/util/getProjectDefaults.js +22 -28
- package/dist/util/getProjectDefaults.js.map +1 -1
- package/dist/util/getSharedServerConfig.js +1 -0
- package/dist/util/getSharedServerConfig.js.map +1 -1
- package/dist/util/getWorkspace.js +1 -1
- package/dist/util/getWorkspace.js.map +1 -1
- package/dist/util/gitConfig.js +45 -0
- package/dist/util/gitConfig.js.map +1 -0
- package/dist/util/isSchemaError.js +11 -0
- package/dist/util/isSchemaError.js.map +1 -0
- package/dist/util/isTar.js +8 -0
- package/dist/util/isTar.js.map +1 -0
- package/dist/util/packageManager/getPeerDependencies.js +44 -0
- package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
- package/dist/util/packageManager/installationInfo/analyzeIssues.js +225 -0
- package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -0
- package/dist/util/packageManager/installationInfo/commands.js +73 -0
- package/dist/util/packageManager/installationInfo/commands.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectCliInstallation.js +66 -0
- package/dist/util/packageManager/installationInfo/detectCliInstallation.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectGlobals.js +295 -0
- package/dist/util/packageManager/installationInfo/detectGlobals.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectPackages.js +190 -0
- package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -0
- package/dist/util/packageManager/installationInfo/detectWorkspace.js +192 -0
- package/dist/util/packageManager/installationInfo/detectWorkspace.js.map +1 -0
- package/dist/util/packageManager/installationInfo/index.js +4 -0
- package/dist/util/packageManager/installationInfo/index.js.map +1 -0
- package/dist/util/packageManager/installationInfo/readJsonFile.js +14 -0
- package/dist/util/packageManager/installationInfo/readJsonFile.js.map +1 -0
- package/dist/util/packageManager/installationInfo/resolveVersionRange.js +42 -0
- package/dist/util/packageManager/installationInfo/resolveVersionRange.js.map +1 -0
- package/dist/util/packageManager/installationInfo/types.js +3 -0
- package/dist/util/packageManager/installationInfo/types.js.map +1 -0
- package/dist/util/packageManager/packageManagerChoice.js +1 -20
- package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
- package/dist/util/packageManager/upgradePackages.js +4 -1
- package/dist/util/packageManager/upgradePackages.js.map +1 -1
- package/dist/util/promiseRaceWithTimeout.js +28 -0
- package/dist/util/promiseRaceWithTimeout.js.map +1 -0
- package/dist/util/readdirRecursive.js.map +1 -1
- package/dist/util/resolveLatestVersions.js +2 -2
- package/dist/util/resolveLatestVersions.js.map +1 -1
- package/dist/util/sharedFlags.js +54 -0
- package/dist/util/sharedFlags.js.map +1 -0
- package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
- package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
- package/dist/util/telemetry/createTelemetryStore.js +95 -0
- package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
- package/dist/util/telemetry/createTraceId.js +10 -0
- package/dist/util/telemetry/createTraceId.js.map +1 -0
- package/dist/util/telemetry/findTelemetryFiles.js +35 -0
- package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
- package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
- package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
- package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
- package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
- package/dist/util/telemetry/logger.js +59 -0
- package/dist/util/telemetry/logger.js.map +1 -0
- package/dist/util/telemetry/readNDJSON.js +28 -0
- package/dist/util/telemetry/readNDJSON.js.map +1 -0
- package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
- package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
- package/dist/util/telemetry/trace.js +150 -0
- package/dist/util/telemetry/trace.js.map +1 -0
- package/dist/util/toForwardSlashes.js +8 -0
- package/dist/util/toForwardSlashes.js.map +1 -0
- package/dist/util/update/fetchLatestVersion.js +21 -0
- package/dist/util/update/fetchLatestVersion.js.map +1 -0
- package/dist/util/update/getUpdateCommand.js +20 -0
- package/dist/util/update/getUpdateCommand.js.map +1 -0
- package/dist/util/update/isInstalledUsingYarn.js +17 -0
- package/dist/util/update/isInstalledUsingYarn.js.map +1 -0
- package/dist/util/update/showNotificationUpdate.js +31 -0
- package/dist/util/update/showNotificationUpdate.js.map +1 -0
- package/dist/util/update/updateChecker.js +60 -0
- package/dist/util/update/updateChecker.js.map +1 -0
- package/dist/util/update/updateCheckerDebug.js +4 -0
- package/dist/util/update/updateCheckerDebug.js.map +1 -0
- package/oclif.config.js +1 -0
- package/oclif.manifest.json +1285 -492
- package/package.json +72 -73
- package/static/favicons/apple-touch-icon.png +0 -0
- package/static/favicons/favicon-192.png +0 -0
- package/static/favicons/favicon-512.png +0 -0
- package/static/favicons/favicon-96.png +0 -0
- package/static/favicons/favicon.ico +0 -0
- package/static/favicons/favicon.svg +12 -0
- package/dist/actions/auth/login/promptProviders.js.map +0 -1
- 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 -33
- 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/index.d.ts +0 -2326
- package/dist/index.js +0 -6
- package/dist/index.js.map +0 -1
- package/dist/studioDependencies.js.map +0 -1
- package/dist/typings/deepSortObject.d.js +0 -2
- package/dist/typings/deepSortObject.d.js.map +0 -1
- package/dist/util/findNdjsonEntry.js +0 -21
- package/dist/util/findNdjsonEntry.js.map +0 -1
- package/dist/util/importStudioConfig.js +0 -40
- package/dist/util/importStudioConfig.js.map +0 -1
- package/dist/util/readModuleVersion.js +0 -15
- package/dist/util/readModuleVersion.js.map +0 -1
- package/dist/util/readPackageJson.js +0 -44
- package/dist/util/readPackageJson.js.map +0 -1
- package/dist/util/readPackageManifest.js +0 -46
- package/dist/util/readPackageManifest.js.map +0 -1
- package/dist/util/uniqBy.js +0 -14
- package/dist/util/uniqBy.js.map +0 -1
- package/dist/util/workerChannels.js +0 -172
- package/dist/util/workerChannels.js.map +0 -1
- /package/dist/{studioDependencies.js → actions/init/studioDependencies.js} +0 -0
|
@@ -1,19 +1,28 @@
|
|
|
1
1
|
import { checkbox } from '@sanity/cli-core/ux';
|
|
2
|
+
function getEditorLabel(editor) {
|
|
3
|
+
if (editor.configured && editor.authStatus === 'unauthorized') {
|
|
4
|
+
return `${editor.name} (auth expired)`;
|
|
5
|
+
}
|
|
6
|
+
if (editor.configured && !editor.existingToken) {
|
|
7
|
+
return `${editor.name} (missing credentials)`;
|
|
8
|
+
}
|
|
9
|
+
return editor.name;
|
|
10
|
+
}
|
|
2
11
|
/**
|
|
3
|
-
* Prompt user to select which editors to configure
|
|
4
|
-
*
|
|
5
|
-
*
|
|
12
|
+
* Prompt user to select which editors to configure.
|
|
13
|
+
*
|
|
14
|
+
* Expects only actionable editors (unconfigured, or configured with
|
|
15
|
+
* invalid/missing credentials). Annotates entries with auth status.
|
|
6
16
|
*/ export async function promptForMCPSetup(editors) {
|
|
7
17
|
const editorChoices = editors.map((e)=>({
|
|
8
|
-
checked:
|
|
9
|
-
name: e
|
|
18
|
+
checked: true,
|
|
19
|
+
name: getEditorLabel(e),
|
|
10
20
|
value: e.name
|
|
11
21
|
}));
|
|
12
|
-
const
|
|
22
|
+
const selectedNames = await checkbox({
|
|
13
23
|
choices: editorChoices,
|
|
14
24
|
message: 'Configure Sanity MCP server?'
|
|
15
25
|
});
|
|
16
|
-
const selectedNames = result;
|
|
17
26
|
// User can deselect all to skip
|
|
18
27
|
if (!selectedNames || selectedNames.length === 0) {
|
|
19
28
|
return null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/mcp/promptForMCPSetup.ts"],"sourcesContent":["import {checkbox} from '@sanity/cli-core/ux'\n\nimport {type Editor} from './types.js'\n\n/**\n * Prompt user to select which editors to configure
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/mcp/promptForMCPSetup.ts"],"sourcesContent":["import {checkbox} from '@sanity/cli-core/ux'\n\nimport {type Editor} from './types.js'\n\nfunction getEditorLabel(editor: Editor): string {\n if (editor.configured && editor.authStatus === 'unauthorized') {\n return `${editor.name} (auth expired)`\n }\n if (editor.configured && !editor.existingToken) {\n return `${editor.name} (missing credentials)`\n }\n return editor.name\n}\n\n/**\n * Prompt user to select which editors to configure.\n *\n * Expects only actionable editors (unconfigured, or configured with\n * invalid/missing credentials). Annotates entries with auth status.\n */\nexport async function promptForMCPSetup(editors: Editor[]): Promise<Editor[] | null> {\n const editorChoices = editors.map((e) => ({\n checked: true, // Pre-select all actionable editors\n name: getEditorLabel(e),\n value: e.name,\n }))\n\n const selectedNames = await checkbox({\n choices: editorChoices,\n message: 'Configure Sanity MCP server?',\n })\n\n // User can deselect all to skip\n if (!selectedNames || selectedNames.length === 0) {\n return null\n }\n\n return editors.filter((e) => selectedNames.includes(e.name))\n}\n"],"names":["checkbox","getEditorLabel","editor","configured","authStatus","name","existingToken","promptForMCPSetup","editors","editorChoices","map","e","checked","value","selectedNames","choices","message","length","filter","includes"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,sBAAqB;AAI5C,SAASC,eAAeC,MAAc;IACpC,IAAIA,OAAOC,UAAU,IAAID,OAAOE,UAAU,KAAK,gBAAgB;QAC7D,OAAO,GAAGF,OAAOG,IAAI,CAAC,eAAe,CAAC;IACxC;IACA,IAAIH,OAAOC,UAAU,IAAI,CAACD,OAAOI,aAAa,EAAE;QAC9C,OAAO,GAAGJ,OAAOG,IAAI,CAAC,sBAAsB,CAAC;IAC/C;IACA,OAAOH,OAAOG,IAAI;AACpB;AAEA;;;;;CAKC,GACD,OAAO,eAAeE,kBAAkBC,OAAiB;IACvD,MAAMC,gBAAgBD,QAAQE,GAAG,CAAC,CAACC,IAAO,CAAA;YACxCC,SAAS;YACTP,MAAMJ,eAAeU;YACrBE,OAAOF,EAAEN,IAAI;QACf,CAAA;IAEA,MAAMS,gBAAgB,MAAMd,SAAS;QACnCe,SAASN;QACTO,SAAS;IACX;IAEA,gCAAgC;IAChC,IAAI,CAACF,iBAAiBA,cAAcG,MAAM,KAAK,GAAG;QAChD,OAAO;IACT;IAEA,OAAOT,QAAQU,MAAM,CAAC,CAACP,IAAMG,cAAcK,QAAQ,CAACR,EAAEN,IAAI;AAC5D"}
|
|
@@ -4,17 +4,20 @@ import { logSymbols } from '@sanity/cli-core/ux';
|
|
|
4
4
|
import { createMCPToken, MCP_SERVER_URL } from '../../services/mcp.js';
|
|
5
5
|
import { detectAvailableEditors } from './detectAvailableEditors.js';
|
|
6
6
|
import { promptForMCPSetup } from './promptForMCPSetup.js';
|
|
7
|
+
import { validateEditorTokens } from './validateEditorTokens.js';
|
|
7
8
|
import { writeMCPConfig } from './writeMCPConfig.js';
|
|
8
9
|
const mcpDebug = subdebug('mcp:setup');
|
|
9
10
|
const NO_EDITORS_DETECTED_MESSAGE = `Couldn't auto-configure Sanity MCP server for your editor. Visit ${MCP_SERVER_URL} for setup instructions.`;
|
|
10
11
|
/**
|
|
11
12
|
* Main MCP setup orchestration
|
|
12
|
-
* Opt-out by default: runs automatically unless
|
|
13
|
-
*/ export async function setupMCP(
|
|
13
|
+
* Opt-out by default: runs automatically unless skip option is set
|
|
14
|
+
*/ export async function setupMCP(options) {
|
|
15
|
+
const { explicit = false, skip = false } = options ?? {};
|
|
14
16
|
// 1. Check for explicit opt-out
|
|
15
|
-
if (
|
|
17
|
+
if (skip) {
|
|
16
18
|
ux.warn('Skipping MCP configuration due to --no-mcp flag');
|
|
17
19
|
return {
|
|
20
|
+
alreadyConfiguredEditors: [],
|
|
18
21
|
configuredEditors: [],
|
|
19
22
|
detectedEditors: [],
|
|
20
23
|
skipped: true
|
|
@@ -25,44 +28,79 @@ const NO_EDITORS_DETECTED_MESSAGE = `Couldn't auto-configure Sanity MCP server f
|
|
|
25
28
|
const detectedEditors = editors.map((e)=>e.name);
|
|
26
29
|
mcpDebug('Detected %d editors: %s', detectedEditors.length, detectedEditors);
|
|
27
30
|
if (editors.length === 0) {
|
|
28
|
-
|
|
31
|
+
if (explicit) {
|
|
32
|
+
ux.warn(NO_EDITORS_DETECTED_MESSAGE);
|
|
33
|
+
}
|
|
29
34
|
return {
|
|
35
|
+
alreadyConfiguredEditors: [],
|
|
30
36
|
configuredEditors: [],
|
|
31
37
|
detectedEditors,
|
|
32
38
|
skipped: true
|
|
33
39
|
};
|
|
34
40
|
}
|
|
35
|
-
// 3.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
// 3. Validate existing tokens against the Sanity API
|
|
42
|
+
await validateEditorTokens(editors);
|
|
43
|
+
// 4. Check if there's anything actionable
|
|
44
|
+
const actionable = editors.filter((e)=>!e.configured || e.authStatus !== 'valid');
|
|
45
|
+
if (actionable.length === 0) {
|
|
46
|
+
mcpDebug('All editors configured with valid credentials');
|
|
47
|
+
const alreadyConfiguredEditors = editors.filter((e)=>e.configured && e.authStatus === 'valid').map((e)=>e.name);
|
|
48
|
+
if (explicit) {
|
|
49
|
+
ux.stdout(`${logSymbols.success} All detected editors are already configured`);
|
|
50
|
+
}
|
|
40
51
|
return {
|
|
52
|
+
alreadyConfiguredEditors,
|
|
41
53
|
configuredEditors: [],
|
|
42
54
|
detectedEditors,
|
|
43
55
|
skipped: true
|
|
44
56
|
};
|
|
45
57
|
}
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
ux.warn(`Could not configure MCP: ${err.message}`);
|
|
54
|
-
ux.warn('You can set up MCP manually later using https://mcp.sanity.io');
|
|
58
|
+
// Non-actionable editors are already configured with valid credentials
|
|
59
|
+
const alreadyConfiguredEditors = editors.filter((e)=>!actionable.includes(e)).map((e)=>e.name);
|
|
60
|
+
// 5. Prompt user (shows only actionable editors, annotates auth issues)
|
|
61
|
+
const selected = await promptForMCPSetup(actionable);
|
|
62
|
+
if (!selected || selected.length === 0) {
|
|
63
|
+
// User deselected all editors
|
|
64
|
+
ux.stdout('MCP configuration skipped');
|
|
55
65
|
return {
|
|
66
|
+
alreadyConfiguredEditors,
|
|
56
67
|
configuredEditors: [],
|
|
57
68
|
detectedEditors,
|
|
58
|
-
|
|
59
|
-
skipped: false
|
|
69
|
+
skipped: true
|
|
60
70
|
};
|
|
61
71
|
}
|
|
62
|
-
//
|
|
72
|
+
// 6. Get a token — reuse a valid existing one or create a new one
|
|
73
|
+
let token;
|
|
74
|
+
// Look for an existing valid token we can reuse
|
|
75
|
+
const validEditor = editors.find((e)=>e.authStatus === 'valid' && e.existingToken);
|
|
76
|
+
if (validEditor?.existingToken) {
|
|
77
|
+
mcpDebug('Reusing valid token from %s', validEditor.name);
|
|
78
|
+
token = validEditor.existingToken;
|
|
79
|
+
}
|
|
80
|
+
// Fall back to creating a new token
|
|
81
|
+
if (!token) {
|
|
82
|
+
try {
|
|
83
|
+
token = await createMCPToken();
|
|
84
|
+
} catch (error) {
|
|
85
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
86
|
+
mcpDebug('Error creating MCP token', error);
|
|
87
|
+
ux.warn(`Could not configure MCP: ${err.message}`);
|
|
88
|
+
ux.warn('You can set up MCP manually later using https://mcp.sanity.io');
|
|
89
|
+
return {
|
|
90
|
+
alreadyConfiguredEditors,
|
|
91
|
+
configuredEditors: [],
|
|
92
|
+
detectedEditors,
|
|
93
|
+
error: err,
|
|
94
|
+
skipped: false
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// 7. Write configs for each selected editor
|
|
99
|
+
const configuredEditors = [];
|
|
63
100
|
try {
|
|
64
101
|
for (const editor of selected){
|
|
65
102
|
await writeMCPConfig(editor, token);
|
|
103
|
+
configuredEditors.push(editor.name);
|
|
66
104
|
}
|
|
67
105
|
} catch (error) {
|
|
68
106
|
const err = error instanceof Error ? error : new Error(String(error));
|
|
@@ -70,15 +108,16 @@ const NO_EDITORS_DETECTED_MESSAGE = `Couldn't auto-configure Sanity MCP server f
|
|
|
70
108
|
ux.warn(`Could not configure MCP: ${err.message}`);
|
|
71
109
|
ux.warn('You can set up MCP manually later using https://mcp.sanity.io');
|
|
72
110
|
return {
|
|
73
|
-
|
|
111
|
+
alreadyConfiguredEditors,
|
|
112
|
+
configuredEditors,
|
|
74
113
|
detectedEditors,
|
|
75
114
|
error: err,
|
|
76
115
|
skipped: false
|
|
77
116
|
};
|
|
78
117
|
}
|
|
79
|
-
const configuredEditors = selected.map((e)=>e.name);
|
|
80
118
|
ux.stdout(`${logSymbols.success} MCP configured for ${configuredEditors.join(', ')}`);
|
|
81
119
|
return {
|
|
120
|
+
alreadyConfiguredEditors,
|
|
82
121
|
configuredEditors,
|
|
83
122
|
detectedEditors,
|
|
84
123
|
skipped: false
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/mcp/setupMCP.ts"],"sourcesContent":["import {ux} from '@oclif/core'\nimport {subdebug} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\n\nimport {createMCPToken, MCP_SERVER_URL} from '../../services/mcp.js'\nimport {detectAvailableEditors} from './detectAvailableEditors.js'\nimport {type EditorName} from './editorConfigs.js'\nimport {promptForMCPSetup} from './promptForMCPSetup.js'\nimport {writeMCPConfig} from './writeMCPConfig.js'\n\nconst mcpDebug = subdebug('mcp:setup')\n\nconst NO_EDITORS_DETECTED_MESSAGE = `Couldn't auto-configure Sanity MCP server for your editor. Visit ${MCP_SERVER_URL} for setup instructions.`\n\
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/mcp/setupMCP.ts"],"sourcesContent":["import {ux} from '@oclif/core'\nimport {subdebug} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\n\nimport {createMCPToken, MCP_SERVER_URL} from '../../services/mcp.js'\nimport {detectAvailableEditors} from './detectAvailableEditors.js'\nimport {type EditorName} from './editorConfigs.js'\nimport {promptForMCPSetup} from './promptForMCPSetup.js'\nimport {validateEditorTokens} from './validateEditorTokens.js'\nimport {writeMCPConfig} from './writeMCPConfig.js'\n\nconst mcpDebug = subdebug('mcp:setup')\n\nconst NO_EDITORS_DETECTED_MESSAGE = `Couldn't auto-configure Sanity MCP server for your editor. Visit ${MCP_SERVER_URL} for setup instructions.`\n\ninterface MCPSetupOptions {\n /**\n * Whether the user explicitly requested MCP configuration (e.g. `sanity mcp configure`).\n * When true, shows status messages even when there's nothing to do.\n * When false/undefined (e.g. called from `sanity init`), stays quiet.\n */\n explicit?: boolean\n\n /**\n * If true, skip MCP configuration entirely (e.g. --no-mcp flag).\n */\n skip?: boolean\n}\n\ninterface MCPSetupResult {\n /** Editors that were already configured with valid credentials (nothing to do) */\n alreadyConfiguredEditors: EditorName[]\n configuredEditors: EditorName[]\n detectedEditors: EditorName[]\n skipped: boolean\n\n error?: Error\n}\n\n/**\n * Main MCP setup orchestration\n * Opt-out by default: runs automatically unless skip option is set\n */\nexport async function setupMCP(options?: MCPSetupOptions): Promise<MCPSetupResult> {\n const {explicit = false, skip = false} = options ?? {}\n\n // 1. Check for explicit opt-out\n if (skip) {\n ux.warn('Skipping MCP configuration due to --no-mcp flag')\n return {\n alreadyConfiguredEditors: [],\n configuredEditors: [],\n detectedEditors: [],\n skipped: true,\n }\n }\n\n // 2. Detect available editors (filters out unparseable configs)\n const editors = await detectAvailableEditors()\n const detectedEditors = editors.map((e) => e.name)\n\n mcpDebug('Detected %d editors: %s', detectedEditors.length, detectedEditors)\n\n if (editors.length === 0) {\n if (explicit) {\n ux.warn(NO_EDITORS_DETECTED_MESSAGE)\n }\n return {\n alreadyConfiguredEditors: [],\n configuredEditors: [],\n detectedEditors,\n skipped: true,\n }\n }\n\n // 3. Validate existing tokens against the Sanity API\n await validateEditorTokens(editors)\n\n // 4. Check if there's anything actionable\n const actionable = editors.filter((e) => !e.configured || e.authStatus !== 'valid')\n\n if (actionable.length === 0) {\n mcpDebug('All editors configured with valid credentials')\n const alreadyConfiguredEditors = editors\n .filter((e) => e.configured && e.authStatus === 'valid')\n .map((e) => e.name)\n if (explicit) {\n ux.stdout(`${logSymbols.success} All detected editors are already configured`)\n }\n return {\n alreadyConfiguredEditors,\n configuredEditors: [],\n detectedEditors,\n skipped: true,\n }\n }\n\n // Non-actionable editors are already configured with valid credentials\n const alreadyConfiguredEditors = editors.filter((e) => !actionable.includes(e)).map((e) => e.name)\n\n // 5. Prompt user (shows only actionable editors, annotates auth issues)\n const selected = await promptForMCPSetup(actionable)\n\n if (!selected || selected.length === 0) {\n // User deselected all editors\n ux.stdout('MCP configuration skipped')\n return {\n alreadyConfiguredEditors,\n configuredEditors: [],\n detectedEditors,\n skipped: true,\n }\n }\n\n // 6. Get a token — reuse a valid existing one or create a new one\n let token: string | undefined\n\n // Look for an existing valid token we can reuse\n const validEditor = editors.find((e) => e.authStatus === 'valid' && e.existingToken)\n if (validEditor?.existingToken) {\n mcpDebug('Reusing valid token from %s', validEditor.name)\n token = validEditor.existingToken\n }\n\n // Fall back to creating a new token\n if (!token) {\n try {\n token = await createMCPToken()\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n mcpDebug('Error creating MCP token', error)\n ux.warn(`Could not configure MCP: ${err.message}`)\n ux.warn('You can set up MCP manually later using https://mcp.sanity.io')\n return {\n alreadyConfiguredEditors,\n configuredEditors: [],\n detectedEditors,\n error: err,\n skipped: false,\n }\n }\n }\n\n // 7. Write configs for each selected editor\n const configuredEditors: EditorName[] = []\n try {\n for (const editor of selected) {\n await writeMCPConfig(editor, token)\n configuredEditors.push(editor.name)\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n mcpDebug('Error writing MCP config', error)\n ux.warn(`Could not configure MCP: ${err.message}`)\n ux.warn('You can set up MCP manually later using https://mcp.sanity.io')\n return {\n alreadyConfiguredEditors,\n configuredEditors,\n detectedEditors,\n error: err,\n skipped: false,\n }\n }\n\n ux.stdout(`${logSymbols.success} MCP configured for ${configuredEditors.join(', ')}`)\n\n return {\n alreadyConfiguredEditors,\n configuredEditors,\n detectedEditors,\n skipped: false,\n }\n}\n"],"names":["ux","subdebug","logSymbols","createMCPToken","MCP_SERVER_URL","detectAvailableEditors","promptForMCPSetup","validateEditorTokens","writeMCPConfig","mcpDebug","NO_EDITORS_DETECTED_MESSAGE","setupMCP","options","explicit","skip","warn","alreadyConfiguredEditors","configuredEditors","detectedEditors","skipped","editors","map","e","name","length","actionable","filter","configured","authStatus","stdout","success","includes","selected","token","validEditor","find","existingToken","error","err","Error","String","message","editor","push","join"],"mappings":"AAAA,SAAQA,EAAE,QAAO,cAAa;AAC9B,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,UAAU,QAAO,sBAAqB;AAE9C,SAAQC,cAAc,EAAEC,cAAc,QAAO,wBAAuB;AACpE,SAAQC,sBAAsB,QAAO,8BAA6B;AAElE,SAAQC,iBAAiB,QAAO,yBAAwB;AACxD,SAAQC,oBAAoB,QAAO,4BAA2B;AAC9D,SAAQC,cAAc,QAAO,sBAAqB;AAElD,MAAMC,WAAWR,SAAS;AAE1B,MAAMS,8BAA8B,CAAC,iEAAiE,EAAEN,eAAe,wBAAwB,CAAC;AA0BhJ;;;CAGC,GACD,OAAO,eAAeO,SAASC,OAAyB;IACtD,MAAM,EAACC,WAAW,KAAK,EAAEC,OAAO,KAAK,EAAC,GAAGF,WAAW,CAAC;IAErD,gCAAgC;IAChC,IAAIE,MAAM;QACRd,GAAGe,IAAI,CAAC;QACR,OAAO;YACLC,0BAA0B,EAAE;YAC5BC,mBAAmB,EAAE;YACrBC,iBAAiB,EAAE;YACnBC,SAAS;QACX;IACF;IAEA,gEAAgE;IAChE,MAAMC,UAAU,MAAMf;IACtB,MAAMa,kBAAkBE,QAAQC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI;IAEjDd,SAAS,2BAA2BS,gBAAgBM,MAAM,EAAEN;IAE5D,IAAIE,QAAQI,MAAM,KAAK,GAAG;QACxB,IAAIX,UAAU;YACZb,GAAGe,IAAI,CAACL;QACV;QACA,OAAO;YACLM,0BAA0B,EAAE;YAC5BC,mBAAmB,EAAE;YACrBC;YACAC,SAAS;QACX;IACF;IAEA,qDAAqD;IACrD,MAAMZ,qBAAqBa;IAE3B,0CAA0C;IAC1C,MAAMK,aAAaL,QAAQM,MAAM,CAAC,CAACJ,IAAM,CAACA,EAAEK,UAAU,IAAIL,EAAEM,UAAU,KAAK;IAE3E,IAAIH,WAAWD,MAAM,KAAK,GAAG;QAC3Bf,SAAS;QACT,MAAMO,2BAA2BI,QAC9BM,MAAM,CAAC,CAACJ,IAAMA,EAAEK,UAAU,IAAIL,EAAEM,UAAU,KAAK,SAC/CP,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI;QACpB,IAAIV,UAAU;YACZb,GAAG6B,MAAM,CAAC,GAAG3B,WAAW4B,OAAO,CAAC,4CAA4C,CAAC;QAC/E;QACA,OAAO;YACLd;YACAC,mBAAmB,EAAE;YACrBC;YACAC,SAAS;QACX;IACF;IAEA,uEAAuE;IACvE,MAAMH,2BAA2BI,QAAQM,MAAM,CAAC,CAACJ,IAAM,CAACG,WAAWM,QAAQ,CAACT,IAAID,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI;IAEjG,wEAAwE;IACxE,MAAMS,WAAW,MAAM1B,kBAAkBmB;IAEzC,IAAI,CAACO,YAAYA,SAASR,MAAM,KAAK,GAAG;QACtC,8BAA8B;QAC9BxB,GAAG6B,MAAM,CAAC;QACV,OAAO;YACLb;YACAC,mBAAmB,EAAE;YACrBC;YACAC,SAAS;QACX;IACF;IAEA,kEAAkE;IAClE,IAAIc;IAEJ,gDAAgD;IAChD,MAAMC,cAAcd,QAAQe,IAAI,CAAC,CAACb,IAAMA,EAAEM,UAAU,KAAK,WAAWN,EAAEc,aAAa;IACnF,IAAIF,aAAaE,eAAe;QAC9B3B,SAAS,+BAA+ByB,YAAYX,IAAI;QACxDU,QAAQC,YAAYE,aAAa;IACnC;IAEA,oCAAoC;IACpC,IAAI,CAACH,OAAO;QACV,IAAI;YACFA,QAAQ,MAAM9B;QAChB,EAAE,OAAOkC,OAAO;YACd,MAAMC,MAAMD,iBAAiBE,QAAQF,QAAQ,IAAIE,MAAMC,OAAOH;YAC9D5B,SAAS,4BAA4B4B;YACrCrC,GAAGe,IAAI,CAAC,CAAC,yBAAyB,EAAEuB,IAAIG,OAAO,EAAE;YACjDzC,GAAGe,IAAI,CAAC;YACR,OAAO;gBACLC;gBACAC,mBAAmB,EAAE;gBACrBC;gBACAmB,OAAOC;gBACPnB,SAAS;YACX;QACF;IACF;IAEA,4CAA4C;IAC5C,MAAMF,oBAAkC,EAAE;IAC1C,IAAI;QACF,KAAK,MAAMyB,UAAUV,SAAU;YAC7B,MAAMxB,eAAekC,QAAQT;YAC7BhB,kBAAkB0B,IAAI,CAACD,OAAOnB,IAAI;QACpC;IACF,EAAE,OAAOc,OAAO;QACd,MAAMC,MAAMD,iBAAiBE,QAAQF,QAAQ,IAAIE,MAAMC,OAAOH;QAC9D5B,SAAS,4BAA4B4B;QACrCrC,GAAGe,IAAI,CAAC,CAAC,yBAAyB,EAAEuB,IAAIG,OAAO,EAAE;QACjDzC,GAAGe,IAAI,CAAC;QACR,OAAO;YACLC;YACAC;YACAC;YACAmB,OAAOC;YACPnB,SAAS;QACX;IACF;IAEAnB,GAAG6B,MAAM,CAAC,GAAG3B,WAAW4B,OAAO,CAAC,oBAAoB,EAAEb,kBAAkB2B,IAAI,CAAC,OAAO;IAEpF,OAAO;QACL5B;QACAC;QACAC;QACAC,SAAS;IACX;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/mcp/types.ts"],"sourcesContent":["import {type EditorName} from './editorConfigs.js'\n\nexport interface Editor {\n configPath: string\n /** Whether Sanity MCP is already configured for this editor */\n configured: boolean\n name: EditorName\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/mcp/types.ts"],"sourcesContent":["import {type EditorName} from './editorConfigs.js'\n\n/** Auth credential status for a configured editor */\nexport type AuthStatus = 'unauthorized' | 'valid'\n\nexport interface Editor {\n configPath: string\n /** Whether Sanity MCP is already configured for this editor */\n configured: boolean\n name: EditorName\n\n /**\n * Auth status of the existing token. Only set for editors that have\n * a Sanity MCP config with a token that has been validated against the API.\n */\n authStatus?: AuthStatus\n /** The existing auth token found in the editor config, if any */\n existingToken?: string\n}\n"],"names":[],"mappings":"AAKA,WAaC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { subdebug } from '@sanity/cli-core';
|
|
2
|
+
import { validateMCPToken } from '../../services/mcp.js';
|
|
3
|
+
const debug = subdebug('mcp:validateEditorTokens');
|
|
4
|
+
/**
|
|
5
|
+
* Validate existing MCP tokens for all configured editors.
|
|
6
|
+
*
|
|
7
|
+
* Collects unique tokens, validates each once against the Sanity API,
|
|
8
|
+
* and sets `authStatus` on each editor that has a token.
|
|
9
|
+
* Editors without a config or token are left unchanged.
|
|
10
|
+
*/ export async function validateEditorTokens(editors) {
|
|
11
|
+
// Collect unique tokens and map them to their editors
|
|
12
|
+
const tokenToEditors = new Map();
|
|
13
|
+
for (const editor of editors){
|
|
14
|
+
if (editor.existingToken) {
|
|
15
|
+
const existing = tokenToEditors.get(editor.existingToken);
|
|
16
|
+
if (existing) {
|
|
17
|
+
existing.push(editor);
|
|
18
|
+
} else {
|
|
19
|
+
tokenToEditors.set(editor.existingToken, [
|
|
20
|
+
editor
|
|
21
|
+
]);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (tokenToEditors.size === 0) {
|
|
26
|
+
debug('No existing tokens to validate');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const editorCount = [
|
|
30
|
+
...tokenToEditors.values()
|
|
31
|
+
].reduce((sum, eds)=>sum + eds.length, 0);
|
|
32
|
+
debug('Validating %d unique token(s) across %d editor(s)', tokenToEditors.size, editorCount);
|
|
33
|
+
// Validate all unique tokens in parallel to avoid stacking timeouts
|
|
34
|
+
await Promise.all([
|
|
35
|
+
...tokenToEditors.entries()
|
|
36
|
+
].map(async ([token, tokenEditors])=>{
|
|
37
|
+
let status;
|
|
38
|
+
try {
|
|
39
|
+
const valid = await validateMCPToken(token);
|
|
40
|
+
status = valid ? 'valid' : 'unauthorized';
|
|
41
|
+
} catch (err) {
|
|
42
|
+
// Network errors, timeouts, or unexpected failures — assume the token
|
|
43
|
+
// is valid rather than falsely marking it as expired. We only mark
|
|
44
|
+
// tokens as unauthorized when the server explicitly says so (401/403).
|
|
45
|
+
debug('Token validation error (assuming valid): %s', err);
|
|
46
|
+
status = 'valid';
|
|
47
|
+
}
|
|
48
|
+
debug('Token ending ...%s is %s (used by %s)', token.slice(-4), status, tokenEditors.map((e)=>e.name).join(', '));
|
|
49
|
+
// Apply status to all editors sharing this token
|
|
50
|
+
for (const editor of tokenEditors){
|
|
51
|
+
editor.authStatus = status;
|
|
52
|
+
}
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//# sourceMappingURL=validateEditorTokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/mcp/validateEditorTokens.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\n\nimport {validateMCPToken} from '../../services/mcp.js'\nimport {type AuthStatus, type Editor} from './types.js'\n\nconst debug = subdebug('mcp:validateEditorTokens')\n\n/**\n * Validate existing MCP tokens for all configured editors.\n *\n * Collects unique tokens, validates each once against the Sanity API,\n * and sets `authStatus` on each editor that has a token.\n * Editors without a config or token are left unchanged.\n */\nexport async function validateEditorTokens(editors: Editor[]): Promise<void> {\n // Collect unique tokens and map them to their editors\n const tokenToEditors = new Map<string, Editor[]>()\n for (const editor of editors) {\n if (editor.existingToken) {\n const existing = tokenToEditors.get(editor.existingToken)\n if (existing) {\n existing.push(editor)\n } else {\n tokenToEditors.set(editor.existingToken, [editor])\n }\n }\n }\n\n if (tokenToEditors.size === 0) {\n debug('No existing tokens to validate')\n return\n }\n\n const editorCount = [...tokenToEditors.values()].reduce((sum, eds) => sum + eds.length, 0)\n debug('Validating %d unique token(s) across %d editor(s)', tokenToEditors.size, editorCount)\n\n // Validate all unique tokens in parallel to avoid stacking timeouts\n await Promise.all(\n [...tokenToEditors.entries()].map(async ([token, tokenEditors]) => {\n let status: AuthStatus\n try {\n const valid = await validateMCPToken(token)\n status = valid ? 'valid' : 'unauthorized'\n } catch (err) {\n // Network errors, timeouts, or unexpected failures — assume the token\n // is valid rather than falsely marking it as expired. We only mark\n // tokens as unauthorized when the server explicitly says so (401/403).\n debug('Token validation error (assuming valid): %s', err)\n status = 'valid'\n }\n\n debug(\n 'Token ending ...%s is %s (used by %s)',\n token.slice(-4),\n status,\n tokenEditors.map((e) => e.name).join(', '),\n )\n\n // Apply status to all editors sharing this token\n for (const editor of tokenEditors) {\n editor.authStatus = status\n }\n }),\n )\n}\n"],"names":["subdebug","validateMCPToken","debug","validateEditorTokens","editors","tokenToEditors","Map","editor","existingToken","existing","get","push","set","size","editorCount","values","reduce","sum","eds","length","Promise","all","entries","map","token","tokenEditors","status","valid","err","slice","e","name","join","authStatus"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAEzC,SAAQC,gBAAgB,QAAO,wBAAuB;AAGtD,MAAMC,QAAQF,SAAS;AAEvB;;;;;;CAMC,GACD,OAAO,eAAeG,qBAAqBC,OAAiB;IAC1D,sDAAsD;IACtD,MAAMC,iBAAiB,IAAIC;IAC3B,KAAK,MAAMC,UAAUH,QAAS;QAC5B,IAAIG,OAAOC,aAAa,EAAE;YACxB,MAAMC,WAAWJ,eAAeK,GAAG,CAACH,OAAOC,aAAa;YACxD,IAAIC,UAAU;gBACZA,SAASE,IAAI,CAACJ;YAChB,OAAO;gBACLF,eAAeO,GAAG,CAACL,OAAOC,aAAa,EAAE;oBAACD;iBAAO;YACnD;QACF;IACF;IAEA,IAAIF,eAAeQ,IAAI,KAAK,GAAG;QAC7BX,MAAM;QACN;IACF;IAEA,MAAMY,cAAc;WAAIT,eAAeU,MAAM;KAAG,CAACC,MAAM,CAAC,CAACC,KAAKC,MAAQD,MAAMC,IAAIC,MAAM,EAAE;IACxFjB,MAAM,qDAAqDG,eAAeQ,IAAI,EAAEC;IAEhF,oEAAoE;IACpE,MAAMM,QAAQC,GAAG,CACf;WAAIhB,eAAeiB,OAAO;KAAG,CAACC,GAAG,CAAC,OAAO,CAACC,OAAOC,aAAa;QAC5D,IAAIC;QACJ,IAAI;YACF,MAAMC,QAAQ,MAAM1B,iBAAiBuB;YACrCE,SAASC,QAAQ,UAAU;QAC7B,EAAE,OAAOC,KAAK;YACZ,sEAAsE;YACtE,mEAAmE;YACnE,uEAAuE;YACvE1B,MAAM,+CAA+C0B;YACrDF,SAAS;QACX;QAEAxB,MACE,yCACAsB,MAAMK,KAAK,CAAC,CAAC,IACbH,QACAD,aAAaF,GAAG,CAAC,CAACO,IAAMA,EAAEC,IAAI,EAAEC,IAAI,CAAC;QAGvC,iDAAiD;QACjD,KAAK,MAAMzB,UAAUkB,aAAc;YACjClB,OAAO0B,UAAU,GAAGP;QACtB;IACF;AAEJ"}
|
|
@@ -2,6 +2,7 @@ import { existsSync } from 'node:fs';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { applyEdits, modify } from 'jsonc-parser';
|
|
5
|
+
import { parse as parseToml, stringify as stringifyToml } from 'smol-toml';
|
|
5
6
|
import { EDITOR_CONFIGS } from './editorConfigs.js';
|
|
6
7
|
/**
|
|
7
8
|
* Write MCP configuration to editor config file
|
|
@@ -10,27 +11,38 @@ import { EDITOR_CONFIGS } from './editorConfigs.js';
|
|
|
10
11
|
* Note: Config parseability is already validated in detectAvailableEditors()
|
|
11
12
|
*/ export async function writeMCPConfig(editor, token) {
|
|
12
13
|
const configPath = editor.configPath;
|
|
13
|
-
const { buildServerConfig, configKey } = EDITOR_CONFIGS[editor.name];
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
const { buildServerConfig, configKey, format } = EDITOR_CONFIGS[editor.name];
|
|
15
|
+
const serverConfig = buildServerConfig(token);
|
|
16
|
+
// Read existing content or start with empty object/document
|
|
17
|
+
let content = format === 'toml' ? '' : '{}';
|
|
16
18
|
if (existsSync(configPath)) {
|
|
17
19
|
const fileContent = await fs.readFile(configPath, 'utf8');
|
|
18
20
|
if (fileContent.trim()) {
|
|
19
21
|
content = fileContent;
|
|
20
22
|
}
|
|
21
23
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
configKey
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
if (format === 'toml') {
|
|
25
|
+
const tomlConfig = content.trim() ? parseToml(content) : {};
|
|
26
|
+
const existingServers = tomlConfig[configKey];
|
|
27
|
+
tomlConfig[configKey] = {
|
|
28
|
+
...existingServers && typeof existingServers === 'object' ? existingServers : {},
|
|
29
|
+
Sanity: serverConfig
|
|
30
|
+
};
|
|
31
|
+
content = stringifyToml(tomlConfig);
|
|
32
|
+
} else {
|
|
33
|
+
// Modify using jsonc-parser - preserves comments
|
|
34
|
+
// Setting a nested path automatically creates intermediate objects
|
|
35
|
+
const edits = modify(content, [
|
|
36
|
+
configKey,
|
|
37
|
+
'Sanity'
|
|
38
|
+
], serverConfig, {
|
|
39
|
+
formattingOptions: {
|
|
40
|
+
insertSpaces: true,
|
|
41
|
+
tabSize: 2
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
content = applyEdits(content, edits);
|
|
45
|
+
}
|
|
34
46
|
// Ensure parent directory exists and write
|
|
35
47
|
await fs.mkdir(path.dirname(configPath), {
|
|
36
48
|
recursive: true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/mcp/writeMCPConfig.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {applyEdits, modify} from 'jsonc-parser'\n\nimport {EDITOR_CONFIGS} from './editorConfigs.js'\nimport {Editor} from './types.js'\n\n/**\n * Write MCP configuration to editor config file\n * Uses jsonc-parser's modify/applyEdits to preserve comments\n *\n * Note: Config parseability is already validated in detectAvailableEditors()\n */\nexport async function writeMCPConfig(editor: Editor, token: string): Promise<void> {\n const configPath = editor.configPath\n const {buildServerConfig, configKey} = EDITOR_CONFIGS[editor.name]\n\n // Read existing content or start with empty object\n let content = '{}'\n if (existsSync(configPath)) {\n const fileContent = await fs.readFile(configPath, 'utf8')\n if (fileContent.trim()) {\n content = fileContent\n }\n }\n\n // Modify using jsonc-parser - preserves comments\n
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/mcp/writeMCPConfig.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {applyEdits, modify} from 'jsonc-parser'\nimport {parse as parseToml, stringify as stringifyToml} from 'smol-toml'\n\nimport {EDITOR_CONFIGS} from './editorConfigs.js'\nimport {Editor} from './types.js'\n\ninterface TomlConfig {\n [key: string]: Record<string, unknown> | undefined\n}\n\n/**\n * Write MCP configuration to editor config file\n * Uses jsonc-parser's modify/applyEdits to preserve comments\n *\n * Note: Config parseability is already validated in detectAvailableEditors()\n */\nexport async function writeMCPConfig(editor: Editor, token: string): Promise<void> {\n const configPath = editor.configPath\n const {buildServerConfig, configKey, format} = EDITOR_CONFIGS[editor.name]\n const serverConfig = buildServerConfig(token)\n\n // Read existing content or start with empty object/document\n let content = format === 'toml' ? '' : '{}'\n if (existsSync(configPath)) {\n const fileContent = await fs.readFile(configPath, 'utf8')\n if (fileContent.trim()) {\n content = fileContent\n }\n }\n\n if (format === 'toml') {\n const tomlConfig = content.trim() ? (parseToml(content) as TomlConfig) : {}\n const existingServers = tomlConfig[configKey]\n\n tomlConfig[configKey] = {\n ...(existingServers && typeof existingServers === 'object' ? existingServers : {}),\n Sanity: serverConfig,\n }\n\n content = stringifyToml(tomlConfig)\n } else {\n // Modify using jsonc-parser - preserves comments\n // Setting a nested path automatically creates intermediate objects\n const edits = modify(content, [configKey, 'Sanity'], serverConfig, {\n formattingOptions: {insertSpaces: true, tabSize: 2},\n })\n content = applyEdits(content, edits)\n }\n\n // Ensure parent directory exists and write\n await fs.mkdir(path.dirname(configPath), {recursive: true})\n await fs.writeFile(configPath, content, 'utf8')\n}\n"],"names":["existsSync","fs","path","applyEdits","modify","parse","parseToml","stringify","stringifyToml","EDITOR_CONFIGS","writeMCPConfig","editor","token","configPath","buildServerConfig","configKey","format","name","serverConfig","content","fileContent","readFile","trim","tomlConfig","existingServers","Sanity","edits","formattingOptions","insertSpaces","tabSize","mkdir","dirname","recursive","writeFile"],"mappings":"AAAA,SAAQA,UAAU,QAAO,UAAS;AAClC,OAAOC,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAE5B,SAAQC,UAAU,EAAEC,MAAM,QAAO,eAAc;AAC/C,SAAQC,SAASC,SAAS,EAAEC,aAAaC,aAAa,QAAO,YAAW;AAExE,SAAQC,cAAc,QAAO,qBAAoB;AAOjD;;;;;CAKC,GACD,OAAO,eAAeC,eAAeC,MAAc,EAAEC,KAAa;IAChE,MAAMC,aAAaF,OAAOE,UAAU;IACpC,MAAM,EAACC,iBAAiB,EAAEC,SAAS,EAAEC,MAAM,EAAC,GAAGP,cAAc,CAACE,OAAOM,IAAI,CAAC;IAC1E,MAAMC,eAAeJ,kBAAkBF;IAEvC,4DAA4D;IAC5D,IAAIO,UAAUH,WAAW,SAAS,KAAK;IACvC,IAAIhB,WAAWa,aAAa;QAC1B,MAAMO,cAAc,MAAMnB,GAAGoB,QAAQ,CAACR,YAAY;QAClD,IAAIO,YAAYE,IAAI,IAAI;YACtBH,UAAUC;QACZ;IACF;IAEA,IAAIJ,WAAW,QAAQ;QACrB,MAAMO,aAAaJ,QAAQG,IAAI,KAAMhB,UAAUa,WAA0B,CAAC;QAC1E,MAAMK,kBAAkBD,UAAU,CAACR,UAAU;QAE7CQ,UAAU,CAACR,UAAU,GAAG;YACtB,GAAIS,mBAAmB,OAAOA,oBAAoB,WAAWA,kBAAkB,CAAC,CAAC;YACjFC,QAAQP;QACV;QAEAC,UAAUX,cAAce;IAC1B,OAAO;QACL,iDAAiD;QACjD,mEAAmE;QACnE,MAAMG,QAAQtB,OAAOe,SAAS;YAACJ;YAAW;SAAS,EAAEG,cAAc;YACjES,mBAAmB;gBAACC,cAAc;gBAAMC,SAAS;YAAC;QACpD;QACAV,UAAUhB,WAAWgB,SAASO;IAChC;IAEA,2CAA2C;IAC3C,MAAMzB,GAAG6B,KAAK,CAAC5B,KAAK6B,OAAO,CAAClB,aAAa;QAACmB,WAAW;IAAI;IACzD,MAAM/B,GAAGgC,SAAS,CAACpB,YAAYM,SAAS;AAC1C"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import readline from 'node:readline';
|
|
2
|
+
/**
|
|
3
|
+
* Stream an NDJSON file and build a Map from a key field to a value field.
|
|
4
|
+
*
|
|
5
|
+
* Only entries that contain the key field are indexed. If duplicate keys exist,
|
|
6
|
+
* the last entry wins.
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/ export async function buildNdjsonIndex(ndjson, keyField, valueField) {
|
|
10
|
+
const lines = readline.createInterface({
|
|
11
|
+
input: ndjson
|
|
12
|
+
});
|
|
13
|
+
const index = new Map();
|
|
14
|
+
try {
|
|
15
|
+
for await (const line of lines){
|
|
16
|
+
const trimmed = line.trim();
|
|
17
|
+
if (trimmed) {
|
|
18
|
+
const entry = JSON.parse(trimmed);
|
|
19
|
+
if (entry[keyField] != null) {
|
|
20
|
+
index.set(entry[keyField], entry[valueField]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
} finally{
|
|
25
|
+
lines.close();
|
|
26
|
+
// Explicitly destroy the underlying stream to prevent file descriptor leaks
|
|
27
|
+
ndjson.destroy();
|
|
28
|
+
}
|
|
29
|
+
return index;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=buildNdjsonIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/media/buildNdjsonIndex.ts"],"sourcesContent":["import readline from 'node:readline'\nimport {Readable} from 'node:stream'\n\n/**\n * Stream an NDJSON file and build a Map from a key field to a value field.\n *\n * Only entries that contain the key field are indexed. If duplicate keys exist,\n * the last entry wins.\n *\n * @internal\n */\nexport async function buildNdjsonIndex<Value = unknown>(\n ndjson: Readable,\n keyField: string,\n valueField: string,\n): Promise<Map<string, Value>> {\n const lines = readline.createInterface({\n input: ndjson,\n })\n\n const index = new Map<string, Value>()\n\n try {\n for await (const line of lines) {\n const trimmed = line.trim()\n if (trimmed) {\n const entry = JSON.parse(trimmed)\n if (entry[keyField] != null) {\n index.set(entry[keyField], entry[valueField])\n }\n }\n }\n } finally {\n lines.close()\n // Explicitly destroy the underlying stream to prevent file descriptor leaks\n ndjson.destroy()\n }\n\n return index\n}\n"],"names":["readline","buildNdjsonIndex","ndjson","keyField","valueField","lines","createInterface","input","index","Map","line","trimmed","trim","entry","JSON","parse","set","close","destroy"],"mappings":"AAAA,OAAOA,cAAc,gBAAe;AAGpC;;;;;;;CAOC,GACD,OAAO,eAAeC,iBACpBC,MAAgB,EAChBC,QAAgB,EAChBC,UAAkB;IAElB,MAAMC,QAAQL,SAASM,eAAe,CAAC;QACrCC,OAAOL;IACT;IAEA,MAAMM,QAAQ,IAAIC;IAElB,IAAI;QACF,WAAW,MAAMC,QAAQL,MAAO;YAC9B,MAAMM,UAAUD,KAAKE,IAAI;YACzB,IAAID,SAAS;gBACX,MAAME,QAAQC,KAAKC,KAAK,CAACJ;gBACzB,IAAIE,KAAK,CAACV,SAAS,IAAI,MAAM;oBAC3BK,MAAMQ,GAAG,CAACH,KAAK,CAACV,SAAS,EAAEU,KAAK,CAACT,WAAW;gBAC9C;YACF;QACF;IACF,SAAU;QACRC,MAAMY,KAAK;QACX,4EAA4E;QAC5Ef,OAAOgB,OAAO;IAChB;IAEA,OAAOV;AACT"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { access, readdir } from 'node:fs/promises';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import { importModule } from '@sanity/cli-core';
|
|
4
4
|
import { validateMediaLibraryAssetAspect } from '@sanity/schema/_internal';
|
|
5
5
|
import { isAssetAspect } from '@sanity/types';
|
|
6
|
-
import { getTsconfig } from 'get-tsconfig';
|
|
7
|
-
import { tsImport } from 'tsx/esm/api';
|
|
8
6
|
/**
|
|
9
7
|
* File extensions that are considered valid aspect definition files
|
|
10
8
|
*/ const ASPECT_FILE_EXTENSIONS = new Set([
|
|
@@ -39,8 +37,6 @@ import { tsImport } from 'tsx/esm/api';
|
|
|
39
37
|
});
|
|
40
38
|
// Filter for valid aspect files
|
|
41
39
|
const aspectFiles = entries.filter((entry)=>entry.isFile() && ASPECT_FILE_EXTENSIONS.has(path.extname(entry.name)));
|
|
42
|
-
// Get tsconfig for TypeScript compilation
|
|
43
|
-
const tsconfig = getTsconfig(aspectsPath);
|
|
44
40
|
// Import and validate all aspect files
|
|
45
41
|
const aspects = [];
|
|
46
42
|
for (const file of aspectFiles){
|
|
@@ -48,12 +44,7 @@ import { tsImport } from 'tsx/esm/api';
|
|
|
48
44
|
const filePath = path.resolve(aspectsPath, filename);
|
|
49
45
|
try {
|
|
50
46
|
// Dynamically import the aspect file with TypeScript support
|
|
51
|
-
const
|
|
52
|
-
parentURL: import.meta.url,
|
|
53
|
-
tsconfig: tsconfig?.path
|
|
54
|
-
});
|
|
55
|
-
// Get the default export
|
|
56
|
-
const maybeAspect = tryGetDefaultExport(aspectModule);
|
|
47
|
+
const maybeAspect = await importModule(filePath);
|
|
57
48
|
// Check if user wants to filter this aspect
|
|
58
49
|
if (!filterAspects(maybeAspect)) {
|
|
59
50
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/media/importAspects.ts"],"sourcesContent":["import {access, readdir} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/media/importAspects.ts"],"sourcesContent":["import {access, readdir} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {importModule} from '@sanity/cli-core'\nimport {validateMediaLibraryAssetAspect} from '@sanity/schema/_internal'\nimport {\n isAssetAspect,\n type MediaLibraryAssetAspectDocument,\n type SchemaValidationProblem,\n} from '@sanity/types'\n\n/**\n * File extensions that are considered valid aspect definition files\n */\nconst ASPECT_FILE_EXTENSIONS = new Set(['.js', '.jsx', '.mjs', '.mts', '.ts', '.tsx'])\n\n/**\n * Type for an aspect that has been validated\n */\ninterface ValidAspect {\n aspect: MediaLibraryAssetAspectDocument\n filename: string\n status: 'valid'\n validationErrors: never[]\n}\n\n/**\n * Type for an aspect that failed validation\n */\ninterface InvalidAspect {\n aspect: unknown\n filename: string\n status: 'invalid'\n validationErrors: SchemaValidationProblem[][]\n}\n\n/**\n * Union type for aspect containers\n */\ntype AspectContainer = InvalidAspect | ValidAspect\n\n/**\n * Options for importing aspects\n */\ninterface ImportAspectsOptions {\n /**\n * Path to the directory containing aspect definition files\n */\n aspectsPath: string\n\n /**\n * Optional filter function to determine which aspects to include\n */\n filterAspects?: (aspect: unknown) => boolean\n}\n\n/**\n * Result of importing aspects, grouped by validation status\n */\ninterface ImportAspectsResult {\n invalid: InvalidAspect[]\n valid: ValidAspect[]\n}\n\n/**\n * Import and validate aspect definition files from a directory\n *\n * This function reads all TypeScript/JavaScript files from the specified directory,\n * dynamically imports them using tsx for TypeScript support, validates them,\n * and returns them grouped by validation status.\n *\n * @param options - Options for importing aspects\n * @returns Promise resolving to valid and invalid aspects\n * @internal\n */\nexport async function importAspects(options: ImportAspectsOptions): Promise<ImportAspectsResult> {\n const {aspectsPath, filterAspects = () => true} = options\n\n // Check if directory exists\n try {\n await access(aspectsPath)\n } catch {\n throw new Error(`Aspects directory does not exist: ${aspectsPath}`)\n }\n\n // Read directory entries\n const entries = await readdir(aspectsPath, {withFileTypes: true})\n\n // Filter for valid aspect files\n const aspectFiles = entries.filter(\n (entry) => entry.isFile() && ASPECT_FILE_EXTENSIONS.has(path.extname(entry.name)),\n )\n\n // Import and validate all aspect files\n const aspects: AspectContainer[] = []\n\n for (const file of aspectFiles) {\n const filename = file.name\n const filePath = path.resolve(aspectsPath, filename)\n\n try {\n // Dynamically import the aspect file with TypeScript support\n const maybeAspect = await importModule(filePath)\n\n // Check if user wants to filter this aspect\n if (!filterAspects(maybeAspect)) {\n continue\n }\n\n // Validate that it's an asset aspect\n if (!isAssetAspect(maybeAspect)) {\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'invalid',\n validationErrors: [],\n })\n continue\n }\n\n // Validate the aspect schema\n const [valid, errors] = validateMediaLibraryAssetAspect(maybeAspect.definition)\n\n if (!valid) {\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'invalid',\n validationErrors: errors,\n })\n continue\n }\n\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'valid',\n validationErrors: [],\n })\n } catch (error) {\n aspects.push({\n aspect: null,\n filename,\n status: 'invalid',\n validationErrors: [\n [\n {\n message: `Failed to import file: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n },\n ],\n ],\n })\n }\n }\n\n // Group by validation status\n const result: ImportAspectsResult = {\n invalid: aspects.filter((a): a is InvalidAspect => a.status === 'invalid'),\n valid: aspects.filter((a): a is ValidAspect => a.status === 'valid'),\n }\n\n return result\n}\n"],"names":["access","readdir","path","importModule","validateMediaLibraryAssetAspect","isAssetAspect","ASPECT_FILE_EXTENSIONS","Set","importAspects","options","aspectsPath","filterAspects","Error","entries","withFileTypes","aspectFiles","filter","entry","isFile","has","extname","name","aspects","file","filename","filePath","resolve","maybeAspect","push","aspect","status","validationErrors","valid","errors","definition","error","message","severity","result","invalid","a"],"mappings":"AAAA,SAAQA,MAAM,EAAEC,OAAO,QAAO,mBAAkB;AAChD,OAAOC,UAAU,YAAW;AAE5B,SAAQC,YAAY,QAAO,mBAAkB;AAC7C,SAAQC,+BAA+B,QAAO,2BAA0B;AACxE,SACEC,aAAa,QAGR,gBAAe;AAEtB;;CAEC,GACD,MAAMC,yBAAyB,IAAIC,IAAI;IAAC;IAAO;IAAQ;IAAQ;IAAQ;IAAO;CAAO;AAkDrF;;;;;;;;;;CAUC,GACD,OAAO,eAAeC,cAAcC,OAA6B;IAC/D,MAAM,EAACC,WAAW,EAAEC,gBAAgB,IAAM,IAAI,EAAC,GAAGF;IAElD,4BAA4B;IAC5B,IAAI;QACF,MAAMT,OAAOU;IACf,EAAE,OAAM;QACN,MAAM,IAAIE,MAAM,CAAC,kCAAkC,EAAEF,aAAa;IACpE;IAEA,yBAAyB;IACzB,MAAMG,UAAU,MAAMZ,QAAQS,aAAa;QAACI,eAAe;IAAI;IAE/D,gCAAgC;IAChC,MAAMC,cAAcF,QAAQG,MAAM,CAChC,CAACC,QAAUA,MAAMC,MAAM,MAAMZ,uBAAuBa,GAAG,CAACjB,KAAKkB,OAAO,CAACH,MAAMI,IAAI;IAGjF,uCAAuC;IACvC,MAAMC,UAA6B,EAAE;IAErC,KAAK,MAAMC,QAAQR,YAAa;QAC9B,MAAMS,WAAWD,KAAKF,IAAI;QAC1B,MAAMI,WAAWvB,KAAKwB,OAAO,CAAChB,aAAac;QAE3C,IAAI;YACF,6DAA6D;YAC7D,MAAMG,cAAc,MAAMxB,aAAasB;YAEvC,4CAA4C;YAC5C,IAAI,CAACd,cAAcgB,cAAc;gBAC/B;YACF;YAEA,qCAAqC;YACrC,IAAI,CAACtB,cAAcsB,cAAc;gBAC/BL,QAAQM,IAAI,CAAC;oBACXC,QAAQF;oBACRH;oBACAM,QAAQ;oBACRC,kBAAkB,EAAE;gBACtB;gBACA;YACF;YAEA,6BAA6B;YAC7B,MAAM,CAACC,OAAOC,OAAO,GAAG7B,gCAAgCuB,YAAYO,UAAU;YAE9E,IAAI,CAACF,OAAO;gBACVV,QAAQM,IAAI,CAAC;oBACXC,QAAQF;oBACRH;oBACAM,QAAQ;oBACRC,kBAAkBE;gBACpB;gBACA;YACF;YAEAX,QAAQM,IAAI,CAAC;gBACXC,QAAQF;gBACRH;gBACAM,QAAQ;gBACRC,kBAAkB,EAAE;YACtB;QACF,EAAE,OAAOI,OAAO;YACdb,QAAQM,IAAI,CAAC;gBACXC,QAAQ;gBACRL;gBACAM,QAAQ;gBACRC,kBAAkB;oBAChB;wBACE;4BACEK,SAAS,CAAC,uBAAuB,EAAED,iBAAiBvB,QAAQuB,MAAMC,OAAO,GAAG,iBAAiB;4BAC7FC,UAAU;wBACZ;qBACD;iBACF;YACH;QACF;IACF;IAEA,6BAA6B;IAC7B,MAAMC,SAA8B;QAClCC,SAASjB,QAAQN,MAAM,CAAC,CAACwB,IAA0BA,EAAEV,MAAM,KAAK;QAChEE,OAAOV,QAAQN,MAAM,CAAC,CAACwB,IAAwBA,EAAEV,MAAM,KAAK;IAC9D;IAEA,OAAOQ;AACT"}
|
|
@@ -8,13 +8,12 @@ import { pipeline } from 'node:stream/promises';
|
|
|
8
8
|
import { styleText } from 'node:util';
|
|
9
9
|
import gunzipMaybe from 'gunzip-maybe';
|
|
10
10
|
// @ts-expect-error `peek-stream` module currently untyped
|
|
11
|
-
import isTar from 'is-tar';
|
|
12
|
-
// @ts-expect-error `peek-stream` module currently untyped
|
|
13
11
|
import peek from 'peek-stream';
|
|
14
12
|
import { catchError, EMPTY, filter, from, map, mergeMap, mergeWith, of, switchMap, tap, zip } from 'rxjs';
|
|
15
13
|
import tar from 'tar-fs';
|
|
16
14
|
import { glob } from 'tinyglobby';
|
|
17
|
-
import {
|
|
15
|
+
import { isTar } from '../../util/isTar.js';
|
|
16
|
+
import { buildNdjsonIndex } from './buildNdjsonIndex.js';
|
|
18
17
|
import { importMediaDebug } from './importMediaDebug.js';
|
|
19
18
|
const DEFAULT_CONCURRENCY = 6;
|
|
20
19
|
export function importer(options) {
|
|
@@ -23,15 +22,20 @@ export function importer(options) {
|
|
|
23
22
|
if (fileCount === 0) {
|
|
24
23
|
throw new Error('No assets to import');
|
|
25
24
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
25
|
+
// Stream the ndjson file once and build an index to avoid creating
|
|
26
|
+
// multiple read streams (which causes file descriptor leaks)
|
|
27
|
+
const aspectsIndexPromise = buildNdjsonIndex(createReadStream(aspectsNdjsonPath), 'filename', 'aspects');
|
|
28
|
+
return from(aspectsIndexPromise).pipe(mergeMap((aspectsIndex)=>{
|
|
29
|
+
const context = {
|
|
30
|
+
...options,
|
|
31
|
+
aspectsIndex,
|
|
32
|
+
workingPath
|
|
33
|
+
};
|
|
34
|
+
return from(files).pipe(switchMap((file)=>zip(of('file'), of(file))), mergeWith(from(images).pipe(switchMap((file)=>zip(of('image'), of(file))))), fetchExistingAssets(context), uploadAsset(context), resolveAspectData(context), setAspects(context), map((asset)=>({
|
|
35
|
+
asset,
|
|
36
|
+
fileCount
|
|
37
|
+
})));
|
|
38
|
+
}));
|
|
35
39
|
}));
|
|
36
40
|
}
|
|
37
41
|
/**
|
|
@@ -141,14 +145,14 @@ function fetchExistingAssets({ client, workingPath }) {
|
|
|
141
145
|
});
|
|
142
146
|
}
|
|
143
147
|
/**
|
|
144
|
-
* Find the first matching entry in the
|
|
148
|
+
* Find the first matching entry in the cached aspect data and attach it to the asset object.
|
|
145
149
|
*
|
|
146
150
|
* @internal
|
|
147
|
-
*/ function resolveAspectData({
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
*/ function resolveAspectData({ aspectsIndex }) {
|
|
152
|
+
return map((resolvedAsset)=>({
|
|
153
|
+
...resolvedAsset,
|
|
154
|
+
aspects: aspectsIndex.get(resolvedAsset.originalFilename)
|
|
155
|
+
}));
|
|
152
156
|
}
|
|
153
157
|
// TODO: Batch mutations to reduce HTTP request count.
|
|
154
158
|
export function setAspects({ client, replaceAspects }) {
|