@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
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/server/vite/plugin-schema-extraction.ts"],"sourcesContent":["import path, {isAbsolute} from 'node:path'\n\nimport {type CLITelemetryStore} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport debounce from 'lodash-es/debounce.js'\nimport mean from 'lodash-es/mean.js'\nimport once from 'lodash-es/once.js'\nimport {type Plugin} from 'vite'\n\nimport {formatSchemaValidation} from '../../actions/schema/formatSchemaValidation.js'\nimport {createSchemaPatternMatcher} from '../../actions/schema/matchSchemaPattern.js'\nimport {runSchemaExtraction} from '../../actions/schema/runSchemaExtraction.js'\nimport {SchemaExtractionError} from '../../actions/schema/utils/SchemaExtractionError.js'\nimport {\n SchemaExtractedTrace,\n SchemaExtractionWatchModeTrace,\n} from '../../telemetry/extractSchema.telemetry.js'\n\n/**\n * Default glob patterns to watch for schema changes.\n * Covers the sanity config file and common schema directory naming conventions.\n */\nconst DEFAULT_SCHEMA_PATTERNS = [\n 'sanity.config.{js,jsx,ts,tsx,mjs}',\n 'schema*/**/*.{js,jsx,ts,tsx,mjs}',\n]\n\n/** Default debounce delay in milliseconds */\nconst DEFAULT_DEBOUNCE_MS = 1000\n\n/**\n * Delay before initial extraction to allow Vite to finish startup\n * and avoid race conditions with module resolution.\n */\nconst INITIAL_EXTRACTION_DELAY_MS = 1000\n\n/**\n * Options for the Sanity schema extraction Vite plugin.\n *\n * @public\n */\ninterface SchemaExtractionPluginOptions {\n /**\n * Name of sanity config file\n * @example sanity.config.ts\n */\n configPath: string\n\n /**\n * Additional glob patterns to watch for schema changes.\n * These are merged with the default patterns.\n * @example `['lib/custom-types/**\\/*.ts', 'shared/schemas/**\\/*.ts']`\n */\n additionalPatterns?: string[]\n\n /**\n * Debounce delay in milliseconds before triggering extraction\n * after a file change. Helps prevent excessive extractions\n * during rapid file saves.\n * @defaultValue 1000\n */\n debounceMs?: number\n\n /**\n * When true, marks all fields as required in the extracted schema\n * unless they are explicitly marked as optional.\n * @defaultValue false\n */\n enforceRequiredFields?: boolean\n\n /**\n * Format of schema export. groq-type-nodes is the only avilable format at the moment\n */\n format?: string\n\n /**\n * Logger for output messages. Must implement `log`, `info`, and `error` methods.\n * @defaultValue `console`\n */\n output?: Pick<Console, 'error' | 'info' | 'log'>\n\n /**\n * Path where the extracted schema JSON will be written.\n * Can be absolute or relative to the working directory.\n * @defaultValue `path.join(workDir, 'schema.json')`\n */\n outputPath?: string\n\n /**\n * Telemetry logger for the Sanity CLI tooling. If no logger is provided no telemetry\n * is sent. Also, no telemetry will be sent if telemetry is disabled in the sanity CLI.\n */\n telemetryLogger?: CLITelemetryStore\n\n /**\n * Working directory containing the Sanity configuration.\n * This should be the root of your Sanity Studio project where\n * `sanity.config.ts` is located.\n * @defaultValue Vite's project root (`config.root`)\n */\n workDir?: string\n\n /**\n * Workspace name for multi-workspace Sanity configurations.\n * Required when your `sanity.config.ts` exports multiple workspaces\n * and you want to extract schema from a specific one.\n */\n workspaceName?: string\n}\n\n/**\n * Creates a Vite plugin that automatically extracts Sanity schema during development and build.\n *\n * **During development:**\n * The plugin performs an initial extraction when the dev server starts, then watches\n * for file changes and re-extracts the schema when relevant files are modified.\n *\n * **During build:**\n * The plugin extracts the schema once at the end of the build process, ensuring\n * the schema is always up-to-date when deploying.\n *\n * **How it works in dev mode:**\n * 1. Registers watch patterns with Vite's built-in file watcher\n * 2. Performs initial schema extraction when the server starts\n * 3. On file changes matching the patterns, triggers a debounced extraction\n * 4. Uses concurrency control to prevent overlapping extractions\n *\n * @param options - Configuration options for the plugin\n * @returns A Vite plugin configured for schema extraction\n *\n * @internal\n */\nexport function sanitySchemaExtractionPlugin(options: SchemaExtractionPluginOptions) {\n const {\n additionalPatterns = [],\n configPath,\n debounceMs = DEFAULT_DEBOUNCE_MS,\n enforceRequiredFields = false,\n format = 'groq-type-nodes',\n output = console,\n outputPath: outputPathOption = 'schema.json',\n telemetryLogger,\n workDir: workDirOption,\n workspaceName,\n } = options\n\n const watchPatterns = [...DEFAULT_SCHEMA_PATTERNS, ...additionalPatterns]\n\n // Resolved after Vite config is available\n let resolvedWorkDir: string\n let resolvedOutputPath: string\n\n // State for concurrency control\n let isExtracting = false\n let pendingExtraction = false\n\n // Stats for telemetry\n const startTime = Date.now()\n const stats: {failedCount: number; successfulDurations: number[]} = {\n failedCount: 0,\n successfulDurations: [],\n }\n\n const extractSchema = () =>\n runSchemaExtraction({\n configPath,\n enforceRequiredFields,\n format,\n outputPath: resolvedOutputPath,\n workspace: workspaceName,\n })\n\n /**\n * Runs extraction with concurrency control.\n * If extraction is already running, queues one more extraction to run after completion.\n */\n async function runExtraction(isBuilding = false): Promise<void> {\n if (isExtracting) {\n pendingExtraction = true\n return\n }\n\n isExtracting = true\n pendingExtraction = false\n\n const extractionStartTime = Date.now()\n try {\n await extractSchema()\n if (isBuilding) {\n // TODO: Remove when we have better control over progress reporting in build\n output.log('')\n }\n output.log(logSymbols.success, `Extracted schema to ${outputPathOption}`)\n\n // add stats for the successful extraction run to use later for telemetry\n stats.successfulDurations.push(Date.now() - extractionStartTime)\n } catch (err) {\n output.error(\n logSymbols.error,\n `Extraction failed: ${err instanceof Error ? err.message : String(err)}`,\n )\n if (err instanceof SchemaExtractionError && err.validation && err.validation.length > 0) {\n output.error(logSymbols.error, formatSchemaValidation(err.validation))\n }\n\n // track the failed extraction\n stats.failedCount++\n } finally {\n isExtracting = false\n\n // If a change came in during extraction, run again\n if (pendingExtraction) {\n pendingExtraction = false\n await runExtraction()\n }\n }\n }\n\n const debouncedExtract = debounce(() => {\n void runExtraction()\n }, debounceMs)\n\n const {isMatch} = createSchemaPatternMatcher(watchPatterns)\n\n const handleChange = (filePath: string) => {\n if (isMatch(filePath, resolvedWorkDir)) {\n debouncedExtract()\n }\n }\n\n return {\n name: 'sanity/schema-extraction',\n\n configResolved(config) {\n // Resolve workDir from option or Vite's project root\n resolvedWorkDir = workDirOption ?? config.root\n\n resolvedOutputPath = isAbsolute(outputPathOption)\n ? outputPathOption\n : path.join(resolvedWorkDir, outputPathOption)\n },\n\n configureServer(server) {\n const trace = telemetryLogger?.trace(SchemaExtractionWatchModeTrace)\n trace?.start()\n\n trace?.log({enforceRequiredFields, schemaFormat: format, step: 'started'})\n\n // Add schema patterns to Vite's watcher\n const absolutePatterns = watchPatterns.map((pattern) => path.join(resolvedWorkDir, pattern))\n server.watcher.add(absolutePatterns)\n\n // Prepare function to log \"stopped\" event to trace and complete the trace\n const onClose = once(() => {\n // Cancel any pending debounced extractions\n debouncedExtract.cancel()\n\n // Log telemetry if available\n if (trace) {\n trace.log({\n averageExtractionDuration: mean(stats.successfulDurations) || 0,\n extractionFailedCount: stats.failedCount,\n extractionSuccessfulCount: stats.successfulDurations.length,\n step: 'stopped',\n watcherDuration: Date.now() - startTime,\n })\n trace.complete()\n }\n\n // Clean up process listeners (must always run, not just when trace exists)\n process.off('SIGTERM', onClose)\n process.off('SIGINT', onClose)\n })\n\n server.watcher.on('change', handleChange)\n server.watcher.on('add', handleChange)\n server.watcher.on('unlink', handleChange)\n\n // call the watcherClosed method when watcher is closed or when process is stopped/killed\n server.watcher.on('close', onClose)\n process.on('SIGTERM', onClose)\n process.on('SIGINT', onClose)\n\n // Run initial extraction after server is ready\n const startExtraction = () => {\n setTimeout(() => {\n // Notify about schema extraction enabled\n output.info(logSymbols.info, 'Schema extraction enabled. Watching:')\n for (const pattern of watchPatterns) {\n output.info(` - ${pattern}`)\n }\n\n // Perform first extraction\n void runExtraction()\n }, INITIAL_EXTRACTION_DELAY_MS)\n }\n\n if (server.httpServer) {\n server.httpServer.once('listening', startExtraction)\n } else {\n // Middleware mode - no HTTP server, run extraction immediately\n startExtraction()\n }\n },\n\n async buildEnd() {\n const trace = telemetryLogger?.trace(SchemaExtractedTrace)\n trace?.start()\n\n try {\n const start = Date.now()\n const schema = await extractSchema()\n output.log(\n logSymbols.success,\n `Extracted schema to ${outputPathOption} (${Date.now() - start}ms)`,\n )\n\n trace?.log({\n enforceRequiredFields,\n schemaAllTypesCount: schema.length,\n schemaDocumentTypesCount: schema.filter((type) => type.type === 'document').length,\n schemaFormat: format,\n schemaTypesCount: schema.filter((type) => type.type === 'type').length,\n })\n } catch (err) {\n trace?.error(err)\n throw err\n } finally {\n trace?.complete()\n }\n },\n } satisfies Plugin\n}\n"],"names":["path","isAbsolute","logSymbols","debounce","mean","once","formatSchemaValidation","createSchemaPatternMatcher","runSchemaExtraction","SchemaExtractionError","SchemaExtractedTrace","SchemaExtractionWatchModeTrace","DEFAULT_SCHEMA_PATTERNS","DEFAULT_DEBOUNCE_MS","INITIAL_EXTRACTION_DELAY_MS","sanitySchemaExtractionPlugin","options","additionalPatterns","configPath","debounceMs","enforceRequiredFields","format","output","console","outputPath","outputPathOption","telemetryLogger","workDir","workDirOption","workspaceName","watchPatterns","resolvedWorkDir","resolvedOutputPath","isExtracting","pendingExtraction","startTime","Date","now","stats","failedCount","successfulDurations","extractSchema","workspace","runExtraction","isBuilding","extractionStartTime","log","success","push","err","error","Error","message","String","validation","length","debouncedExtract","isMatch","handleChange","filePath","name","configResolved","config","root","join","configureServer","server","trace","start","schemaFormat","step","absolutePatterns","map","pattern","watcher","add","onClose","cancel","averageExtractionDuration","extractionFailedCount","extractionSuccessfulCount","watcherDuration","complete","process","off","on","startExtraction","setTimeout","info","httpServer","buildEnd","schema","schemaAllTypesCount","schemaDocumentTypesCount","filter","type","schemaTypesCount"],"mappings":"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"}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { logSymbols } from '@sanity/cli-core/ux';
|
|
4
|
+
import { runTypegenGenerate, TypegenWatchModeTrace, TypesGeneratedTrace } from '@sanity/codegen';
|
|
5
|
+
import debounce from 'lodash-es/debounce.js';
|
|
6
|
+
import mean from 'lodash-es/mean.js';
|
|
7
|
+
import once from 'lodash-es/once.js';
|
|
8
|
+
import picomatch from 'picomatch';
|
|
9
|
+
import { toForwardSlashes } from '../../util/toForwardSlashes.js';
|
|
10
|
+
/**
|
|
11
|
+
* Default glob patterns to watch for query file changes.
|
|
12
|
+
* Covers common source directory naming conventions.
|
|
13
|
+
*/ const DEFAULT_QUERY_PATTERNS = [
|
|
14
|
+
'./src/**/*.{ts,tsx,js,jsx}',
|
|
15
|
+
'./app/**/*.{ts,tsx,js,jsx}'
|
|
16
|
+
];
|
|
17
|
+
/** Default debounce delay in milliseconds */ const DEFAULT_DEBOUNCE_MS = 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Delay before initial generation to allow Vite to finish startup
|
|
20
|
+
* and avoid race conditions with module resolution.
|
|
21
|
+
*/ const INITIAL_GENERATION_DELAY_MS = 1000;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a Vite plugin that automatically generates TypeScript types during development and build.
|
|
24
|
+
*
|
|
25
|
+
* **During development:**
|
|
26
|
+
* The plugin performs an initial generation when the dev server starts, then watches
|
|
27
|
+
* for file changes and re-generates types when relevant files are modified.
|
|
28
|
+
*
|
|
29
|
+
* **During build:**
|
|
30
|
+
* The plugin generates types once at the end of the build process.
|
|
31
|
+
*
|
|
32
|
+
* **Prerequisites:**
|
|
33
|
+
* The schema.json file must exist before typegen can run. Run `sanity schema extract`
|
|
34
|
+
* first to generate the schema file.
|
|
35
|
+
*
|
|
36
|
+
* @param options - Configuration options for the plugin
|
|
37
|
+
* @returns A Vite plugin configured for typegen
|
|
38
|
+
*
|
|
39
|
+
* @internal
|
|
40
|
+
*/ export function sanityTypegenPlugin(options) {
|
|
41
|
+
const { config: inputConfig, output = console, telemetryLogger, workDir } = options;
|
|
42
|
+
// Apply defaults to config
|
|
43
|
+
const config = {
|
|
44
|
+
formatGeneratedCode: inputConfig.formatGeneratedCode ?? false,
|
|
45
|
+
generates: inputConfig.generates ?? 'sanity.types.ts',
|
|
46
|
+
overloadClientMethods: inputConfig.overloadClientMethods ?? false,
|
|
47
|
+
path: inputConfig.path ?? DEFAULT_QUERY_PATTERNS,
|
|
48
|
+
schema: inputConfig.schema ?? 'schema.json'
|
|
49
|
+
};
|
|
50
|
+
// Build query patterns from config
|
|
51
|
+
const queryPatterns = Array.isArray(config.path) ? config.path : [
|
|
52
|
+
config.path
|
|
53
|
+
];
|
|
54
|
+
// Resolved after Vite config is available
|
|
55
|
+
let resolvedSchemaPath;
|
|
56
|
+
// State for concurrency control
|
|
57
|
+
let isGenerating = false;
|
|
58
|
+
let pendingGeneration = false;
|
|
59
|
+
// Stats for telemetry
|
|
60
|
+
const startTime = Date.now();
|
|
61
|
+
const stats = {
|
|
62
|
+
failedCount: 0,
|
|
63
|
+
successfulDurations: []
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Runs type generation with concurrency control.
|
|
67
|
+
* If generation is already running, queues one more generation to run after completion.
|
|
68
|
+
* Returns the generation result, or null if generation was skipped or failed.
|
|
69
|
+
*/ async function runGeneration(isBuilding = false) {
|
|
70
|
+
if (isGenerating) {
|
|
71
|
+
pendingGeneration = true;
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
isGenerating = true;
|
|
75
|
+
pendingGeneration = false;
|
|
76
|
+
const generationStartTime = Date.now();
|
|
77
|
+
try {
|
|
78
|
+
// Validate schema.json exists
|
|
79
|
+
if (!existsSync(resolvedSchemaPath)) {
|
|
80
|
+
output.error(`${logSymbols.error} Schema file not found: ${config.schema}\n` + `Run "sanity schema extract" first to generate the schema file.`);
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
const result = await runTypegenGenerate({
|
|
84
|
+
config,
|
|
85
|
+
workDir
|
|
86
|
+
});
|
|
87
|
+
if (isBuilding) {
|
|
88
|
+
// Add newline for better formatting in build output
|
|
89
|
+
output.log('');
|
|
90
|
+
}
|
|
91
|
+
if (result.filesWithErrors > 0) {
|
|
92
|
+
output.log(logSymbols.warning, `Generated types to ${config.generates} (with errors in ${result.filesWithErrors} file${result.filesWithErrors === 1 ? '' : 's'})`);
|
|
93
|
+
} else {
|
|
94
|
+
output.log(logSymbols.success, `Generated types to ${config.generates}`);
|
|
95
|
+
}
|
|
96
|
+
// Track stats for telemetry (all completed generations count as successful)
|
|
97
|
+
stats.successfulDurations.push(Date.now() - generationStartTime);
|
|
98
|
+
return result;
|
|
99
|
+
} catch (err) {
|
|
100
|
+
output.error(`${logSymbols.error} Generation failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
101
|
+
stats.failedCount++;
|
|
102
|
+
return null;
|
|
103
|
+
} finally{
|
|
104
|
+
isGenerating = false;
|
|
105
|
+
// If a change came in during generation, run again
|
|
106
|
+
if (pendingGeneration) {
|
|
107
|
+
pendingGeneration = false;
|
|
108
|
+
void runGeneration();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const debouncedGenerate = debounce(()=>{
|
|
113
|
+
void runGeneration();
|
|
114
|
+
}, DEFAULT_DEBOUNCE_MS);
|
|
115
|
+
// Create a matcher function from query patterns
|
|
116
|
+
const isQueryMatch = picomatch(queryPatterns);
|
|
117
|
+
return {
|
|
118
|
+
name: 'sanity/typegen',
|
|
119
|
+
configResolved () {
|
|
120
|
+
const rootDir = workDir;
|
|
121
|
+
resolvedSchemaPath = path.isAbsolute(config.schema) ? config.schema : path.join(rootDir, config.schema);
|
|
122
|
+
},
|
|
123
|
+
configureServer (server) {
|
|
124
|
+
const trace = telemetryLogger?.trace(TypegenWatchModeTrace);
|
|
125
|
+
trace?.start();
|
|
126
|
+
trace?.log({
|
|
127
|
+
step: 'started'
|
|
128
|
+
});
|
|
129
|
+
// Build absolute patterns for query files
|
|
130
|
+
const absoluteQueryPatterns = queryPatterns.map((pattern)=>path.isAbsolute(pattern) ? pattern : path.join(workDir, pattern));
|
|
131
|
+
// Add query patterns AND schema.json to Vite's watcher
|
|
132
|
+
server.watcher.add([
|
|
133
|
+
...absoluteQueryPatterns,
|
|
134
|
+
resolvedSchemaPath
|
|
135
|
+
]);
|
|
136
|
+
// Listen for file changes
|
|
137
|
+
const handleChange = (filePath)=>{
|
|
138
|
+
const relativePath = path.isAbsolute(filePath) ? path.relative(workDir, filePath) : filePath;
|
|
139
|
+
// Normalize to forward slashes for cross-platform picomatch compatibility
|
|
140
|
+
const normalizedPath = toForwardSlashes(relativePath);
|
|
141
|
+
// Trigger on schema.json change OR matching query file
|
|
142
|
+
if (filePath === resolvedSchemaPath || isQueryMatch(normalizedPath)) {
|
|
143
|
+
debouncedGenerate();
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
// Prepare function to log "stopped" event to trace and complete the trace
|
|
147
|
+
const onClose = once(()=>{
|
|
148
|
+
// Cancel any pending debounced extractions
|
|
149
|
+
debouncedGenerate.cancel();
|
|
150
|
+
if (trace) {
|
|
151
|
+
trace.log({
|
|
152
|
+
averageGenerationDuration: mean(stats.successfulDurations) || 0,
|
|
153
|
+
generationFailedCount: stats.failedCount,
|
|
154
|
+
generationSuccessfulCount: stats.successfulDurations.length,
|
|
155
|
+
step: 'stopped',
|
|
156
|
+
watcherDuration: Date.now() - startTime
|
|
157
|
+
});
|
|
158
|
+
trace.complete();
|
|
159
|
+
}
|
|
160
|
+
// Clean up process listeners (must always run, not just when trace exists)
|
|
161
|
+
process.off('SIGTERM', onClose);
|
|
162
|
+
process.off('SIGINT', onClose);
|
|
163
|
+
});
|
|
164
|
+
server.watcher.on('change', handleChange);
|
|
165
|
+
server.watcher.on('add', handleChange);
|
|
166
|
+
server.watcher.on('unlink', handleChange);
|
|
167
|
+
// Call the onClose method when watcher is closed or when process is stopped/killed
|
|
168
|
+
server.watcher.on('close', onClose);
|
|
169
|
+
process.on('SIGTERM', onClose);
|
|
170
|
+
process.on('SIGINT', onClose);
|
|
171
|
+
// Run initial generation after server is ready
|
|
172
|
+
const startGeneration = ()=>{
|
|
173
|
+
setTimeout(()=>{
|
|
174
|
+
// Notify about typegen enabled
|
|
175
|
+
output.info(logSymbols.info, 'Typegen enabled. Watching:');
|
|
176
|
+
for (const pattern of queryPatterns){
|
|
177
|
+
output.info(` - ${pattern}`);
|
|
178
|
+
}
|
|
179
|
+
output.info(` - ${config.schema} (schema)`);
|
|
180
|
+
// Perform first generation
|
|
181
|
+
void runGeneration();
|
|
182
|
+
}, INITIAL_GENERATION_DELAY_MS);
|
|
183
|
+
};
|
|
184
|
+
if (server.httpServer) {
|
|
185
|
+
server.httpServer.once('listening', startGeneration);
|
|
186
|
+
} else {
|
|
187
|
+
// Middleware mode - no HTTP server, run generation immediately
|
|
188
|
+
startGeneration();
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
async buildEnd () {
|
|
192
|
+
// Build mode: One-time generation with telemetry tracking
|
|
193
|
+
const result = await runGeneration(true);
|
|
194
|
+
// Only log telemetry if generation completed successfully
|
|
195
|
+
if (result && telemetryLogger) {
|
|
196
|
+
const trace = telemetryLogger.trace(TypesGeneratedTrace);
|
|
197
|
+
trace.start();
|
|
198
|
+
trace.log({
|
|
199
|
+
configMethod: 'cli',
|
|
200
|
+
configOverloadClientMethods: config.overloadClientMethods ?? false,
|
|
201
|
+
emptyUnionTypeNodesGenerated: result.emptyUnionTypeNodesGenerated,
|
|
202
|
+
filesWithErrors: result.filesWithErrors,
|
|
203
|
+
outputSize: result.code.length,
|
|
204
|
+
queriesCount: result.queriesCount,
|
|
205
|
+
queryFilesCount: result.queryFilesCount,
|
|
206
|
+
schemaTypesCount: result.schemaTypesCount,
|
|
207
|
+
typeNodesGenerated: result.typeNodesGenerated,
|
|
208
|
+
unknownTypeNodesGenerated: result.unknownTypeNodesGenerated,
|
|
209
|
+
unknownTypeNodesRatio: result.typeNodesGenerated > 0 ? result.unknownTypeNodesGenerated / result.typeNodesGenerated : 0
|
|
210
|
+
});
|
|
211
|
+
trace.complete();
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
//# sourceMappingURL=plugin-typegen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/server/vite/plugin-typegen.ts"],"sourcesContent":["import {existsSync} from 'node:fs'\nimport path from 'node:path'\n\nimport {CLITelemetryStore} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {\n type GenerationResult,\n runTypegenGenerate,\n type TypeGenConfig,\n TypegenWatchModeTrace,\n TypesGeneratedTrace,\n} from '@sanity/codegen'\nimport debounce from 'lodash-es/debounce.js'\nimport mean from 'lodash-es/mean.js'\nimport once from 'lodash-es/once.js'\nimport picomatch from 'picomatch'\nimport {type Plugin} from 'vite'\n\nimport {toForwardSlashes} from '../../util/toForwardSlashes.js'\n\n/**\n * Default glob patterns to watch for query file changes.\n * Covers common source directory naming conventions.\n */\nconst DEFAULT_QUERY_PATTERNS = ['./src/**/*.{ts,tsx,js,jsx}', './app/**/*.{ts,tsx,js,jsx}']\n\n/** Default debounce delay in milliseconds */\nconst DEFAULT_DEBOUNCE_MS = 1000\n\n/**\n * Delay before initial generation to allow Vite to finish startup\n * and avoid race conditions with module resolution.\n */\nconst INITIAL_GENERATION_DELAY_MS = 1000\n\n/**\n * Options for the Sanity typegen Vite plugin.\n *\n * @internal\n */\ninterface TypegenPluginOptions {\n /**\n * Typegen configuration from sanity.cli.ts.\n * All fields are optional and will use sensible defaults.\n */\n config: Partial<TypeGenConfig>\n\n /**\n * Working directory containing the Sanity configuration.\n * This should be the root of your Sanity Studio project.\n */\n workDir: string\n\n /**\n * Logger for output messages. Must implement `log`, `info`, and `error` methods.\n * @defaultValue `console`\n */\n output?: Pick<Console, 'error' | 'info' | 'log'>\n\n /**\n * Telemetry logger for the Sanity CLI tooling.\n */\n telemetryLogger?: CLITelemetryStore\n}\n\n/**\n * Creates a Vite plugin that automatically generates TypeScript types during development and build.\n *\n * **During development:**\n * The plugin performs an initial generation when the dev server starts, then watches\n * for file changes and re-generates types when relevant files are modified.\n *\n * **During build:**\n * The plugin generates types once at the end of the build process.\n *\n * **Prerequisites:**\n * The schema.json file must exist before typegen can run. Run `sanity schema extract`\n * first to generate the schema file.\n *\n * @param options - Configuration options for the plugin\n * @returns A Vite plugin configured for typegen\n *\n * @internal\n */\nexport function sanityTypegenPlugin(options: TypegenPluginOptions): Plugin {\n const {config: inputConfig, output = console, telemetryLogger, workDir} = options\n\n // Apply defaults to config\n const config: TypeGenConfig = {\n formatGeneratedCode: inputConfig.formatGeneratedCode ?? false,\n generates: inputConfig.generates ?? 'sanity.types.ts',\n overloadClientMethods: inputConfig.overloadClientMethods ?? false,\n path: inputConfig.path ?? DEFAULT_QUERY_PATTERNS,\n schema: inputConfig.schema ?? 'schema.json',\n }\n\n // Build query patterns from config\n const queryPatterns = Array.isArray(config.path) ? config.path : [config.path]\n\n // Resolved after Vite config is available\n let resolvedSchemaPath: string\n\n // State for concurrency control\n let isGenerating = false\n let pendingGeneration = false\n\n // Stats for telemetry\n const startTime = Date.now()\n const stats: {failedCount: number; successfulDurations: number[]} = {\n failedCount: 0,\n successfulDurations: [],\n }\n\n /**\n * Runs type generation with concurrency control.\n * If generation is already running, queues one more generation to run after completion.\n * Returns the generation result, or null if generation was skipped or failed.\n */\n async function runGeneration(isBuilding = false): Promise<GenerationResult | null> {\n if (isGenerating) {\n pendingGeneration = true\n return null\n }\n\n isGenerating = true\n pendingGeneration = false\n\n const generationStartTime = Date.now()\n\n try {\n // Validate schema.json exists\n if (!existsSync(resolvedSchemaPath)) {\n output.error(\n `${logSymbols.error} Schema file not found: ${config.schema}\\n` +\n `Run \"sanity schema extract\" first to generate the schema file.`,\n )\n return null\n }\n\n const result = await runTypegenGenerate({\n config,\n workDir,\n })\n\n if (isBuilding) {\n // Add newline for better formatting in build output\n output.log('')\n }\n\n if (result.filesWithErrors > 0) {\n output.log(\n logSymbols.warning,\n `Generated types to ${config.generates} (with errors in ${result.filesWithErrors} file${result.filesWithErrors === 1 ? '' : 's'})`,\n )\n } else {\n output.log(logSymbols.success, `Generated types to ${config.generates}`)\n }\n\n // Track stats for telemetry (all completed generations count as successful)\n stats.successfulDurations.push(Date.now() - generationStartTime)\n\n return result\n } catch (err) {\n output.error(\n `${logSymbols.error} Generation failed: ${err instanceof Error ? err.message : String(err)}`,\n )\n stats.failedCount++\n return null\n } finally {\n isGenerating = false\n\n // If a change came in during generation, run again\n if (pendingGeneration) {\n pendingGeneration = false\n void runGeneration()\n }\n }\n }\n\n const debouncedGenerate = debounce(() => {\n void runGeneration()\n }, DEFAULT_DEBOUNCE_MS)\n\n // Create a matcher function from query patterns\n const isQueryMatch = picomatch(queryPatterns)\n\n return {\n name: 'sanity/typegen',\n\n configResolved() {\n const rootDir = workDir\n\n resolvedSchemaPath = path.isAbsolute(config.schema)\n ? config.schema\n : path.join(rootDir, config.schema)\n },\n\n configureServer(server) {\n const trace = telemetryLogger?.trace(TypegenWatchModeTrace)\n trace?.start()\n trace?.log({step: 'started'})\n\n // Build absolute patterns for query files\n const absoluteQueryPatterns = queryPatterns.map((pattern) =>\n path.isAbsolute(pattern) ? pattern : path.join(workDir, pattern),\n )\n\n // Add query patterns AND schema.json to Vite's watcher\n server.watcher.add([...absoluteQueryPatterns, resolvedSchemaPath])\n\n // Listen for file changes\n const handleChange = (filePath: string) => {\n const relativePath = path.isAbsolute(filePath) ? path.relative(workDir, filePath) : filePath\n // Normalize to forward slashes for cross-platform picomatch compatibility\n const normalizedPath = toForwardSlashes(relativePath)\n\n // Trigger on schema.json change OR matching query file\n if (filePath === resolvedSchemaPath || isQueryMatch(normalizedPath)) {\n debouncedGenerate()\n }\n }\n\n // Prepare function to log \"stopped\" event to trace and complete the trace\n const onClose = once(() => {\n // Cancel any pending debounced extractions\n debouncedGenerate.cancel()\n\n if (trace) {\n trace.log({\n averageGenerationDuration: mean(stats.successfulDurations) || 0,\n generationFailedCount: stats.failedCount,\n generationSuccessfulCount: stats.successfulDurations.length,\n step: 'stopped',\n watcherDuration: Date.now() - startTime,\n })\n trace.complete()\n }\n\n // Clean up process listeners (must always run, not just when trace exists)\n process.off('SIGTERM', onClose)\n process.off('SIGINT', onClose)\n })\n\n server.watcher.on('change', handleChange)\n server.watcher.on('add', handleChange)\n server.watcher.on('unlink', handleChange)\n\n // Call the onClose method when watcher is closed or when process is stopped/killed\n server.watcher.on('close', onClose)\n process.on('SIGTERM', onClose)\n process.on('SIGINT', onClose)\n\n // Run initial generation after server is ready\n const startGeneration = () => {\n setTimeout(() => {\n // Notify about typegen enabled\n output.info(logSymbols.info, 'Typegen enabled. Watching:')\n for (const pattern of queryPatterns) {\n output.info(` - ${pattern}`)\n }\n output.info(` - ${config.schema} (schema)`)\n\n // Perform first generation\n void runGeneration()\n }, INITIAL_GENERATION_DELAY_MS)\n }\n\n if (server.httpServer) {\n server.httpServer.once('listening', startGeneration)\n } else {\n // Middleware mode - no HTTP server, run generation immediately\n startGeneration()\n }\n },\n\n async buildEnd() {\n // Build mode: One-time generation with telemetry tracking\n const result = await runGeneration(true)\n\n // Only log telemetry if generation completed successfully\n if (result && telemetryLogger) {\n const trace = telemetryLogger.trace(TypesGeneratedTrace)\n trace.start()\n trace.log({\n configMethod: 'cli',\n configOverloadClientMethods: config.overloadClientMethods ?? false,\n emptyUnionTypeNodesGenerated: result.emptyUnionTypeNodesGenerated,\n filesWithErrors: result.filesWithErrors,\n outputSize: result.code.length,\n queriesCount: result.queriesCount,\n queryFilesCount: result.queryFilesCount,\n schemaTypesCount: result.schemaTypesCount,\n typeNodesGenerated: result.typeNodesGenerated,\n unknownTypeNodesGenerated: result.unknownTypeNodesGenerated,\n unknownTypeNodesRatio:\n result.typeNodesGenerated > 0\n ? result.unknownTypeNodesGenerated / result.typeNodesGenerated\n : 0,\n })\n trace.complete()\n }\n },\n } satisfies Plugin\n}\n"],"names":["existsSync","path","logSymbols","runTypegenGenerate","TypegenWatchModeTrace","TypesGeneratedTrace","debounce","mean","once","picomatch","toForwardSlashes","DEFAULT_QUERY_PATTERNS","DEFAULT_DEBOUNCE_MS","INITIAL_GENERATION_DELAY_MS","sanityTypegenPlugin","options","config","inputConfig","output","console","telemetryLogger","workDir","formatGeneratedCode","generates","overloadClientMethods","schema","queryPatterns","Array","isArray","resolvedSchemaPath","isGenerating","pendingGeneration","startTime","Date","now","stats","failedCount","successfulDurations","runGeneration","isBuilding","generationStartTime","error","result","log","filesWithErrors","warning","success","push","err","Error","message","String","debouncedGenerate","isQueryMatch","name","configResolved","rootDir","isAbsolute","join","configureServer","server","trace","start","step","absoluteQueryPatterns","map","pattern","watcher","add","handleChange","filePath","relativePath","relative","normalizedPath","onClose","cancel","averageGenerationDuration","generationFailedCount","generationSuccessfulCount","length","watcherDuration","complete","process","off","on","startGeneration","setTimeout","info","httpServer","buildEnd","configMethod","configOverloadClientMethods","emptyUnionTypeNodesGenerated","outputSize","code","queriesCount","queryFilesCount","schemaTypesCount","typeNodesGenerated","unknownTypeNodesGenerated","unknownTypeNodesRatio"],"mappings":"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"}
|
|
@@ -29,14 +29,16 @@ export async function editDatasetAcl({ aclMode, datasetName, projectId }) {
|
|
|
29
29
|
aclMode
|
|
30
30
|
});
|
|
31
31
|
}
|
|
32
|
-
export async function createDataset({ aclMode, datasetName, projectId }) {
|
|
32
|
+
export async function createDataset({ aclMode, datasetName, embeddings, projectId }) {
|
|
33
33
|
const client = await getDatasetClient(projectId);
|
|
34
|
+
const options = {};
|
|
34
35
|
if (aclMode) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
options.aclMode = aclMode;
|
|
37
|
+
}
|
|
38
|
+
if (embeddings) {
|
|
39
|
+
options.embeddings = embeddings;
|
|
38
40
|
}
|
|
39
|
-
return client.datasets.create(datasetName);
|
|
41
|
+
return client.datasets.create(datasetName, options);
|
|
40
42
|
}
|
|
41
43
|
export async function copyDataset({ projectId, skipHistory, sourceDataset, targetDataset }) {
|
|
42
44
|
const client = await getDatasetClient(projectId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/datasets.ts"],"sourcesContent":["import {getProjectCliClient} from '@sanity/cli-core'\nimport {type DatasetAclMode} from '@sanity/client'\nimport {EventSource} from 'eventsource'\nimport {Observable} from 'rxjs'\n\nexport const DATASET_API_VERSION = 'v2025-09-16'\n\nfunction getDatasetClient(projectId: string) {\n return getProjectCliClient({\n apiVersion: DATASET_API_VERSION,\n projectId,\n requireUser: true,\n })\n}\n\nexport async function listDatasets(projectId: string) {\n const client = await getDatasetClient(projectId)\n return client.datasets.list()\n}\n\nexport interface DatasetAliasDefinition {\n datasetName: string | null\n name: string\n}\n\nexport async function listDatasetAliases(projectId: string): Promise<DatasetAliasDefinition[]> {\n const client = await getDatasetClient(projectId)\n return client.request<DatasetAliasDefinition[]>({uri: '/aliases'})\n}\n\ninterface DeleteDatasetOptions {\n datasetName: string\n projectId: string\n}\n\nexport async function deleteDataset({datasetName, projectId}: DeleteDatasetOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.delete(datasetName)\n}\n\ninterface EditDatasetAclOptions {\n aclMode: 'private' | 'public'\n datasetName: string\n projectId: string\n}\n\nexport async function editDatasetAcl({aclMode, datasetName, projectId}: EditDatasetAclOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.edit(datasetName, {aclMode})\n}\n\ninterface CreateDatasetOptions {\n datasetName: string\n projectId: string\n\n aclMode?: DatasetAclMode\n}\n\nexport async function createDataset({aclMode, datasetName, projectId}: CreateDatasetOptions) {\n const client = await getDatasetClient(projectId)\n\n if (aclMode) {\n return client.datasets.create(datasetName, {aclMode})\n }\n\n return client.datasets.create(datasetName)\n}\n\ninterface CopyDatasetOptions {\n projectId: string\n skipHistory: boolean\n sourceDataset: string\n targetDataset: string\n}\n\ninterface CopyDatasetResponse {\n jobId: string\n}\n\nexport async function copyDataset({\n projectId,\n skipHistory,\n sourceDataset,\n targetDataset,\n}: CopyDatasetOptions): Promise<CopyDatasetResponse> {\n const client = await getDatasetClient(projectId)\n return client.request<CopyDatasetResponse>({\n body: {\n skipHistory,\n targetDataset,\n },\n method: 'PUT',\n uri: `/datasets/${sourceDataset}/copy`,\n })\n}\n\ninterface ListDatasetCopyJobsOptions {\n projectId: string\n\n limit?: number\n offset?: number\n}\n\nexport interface DatasetCopyJob {\n createdAt: string\n id: string\n sourceDataset: string\n state: string\n targetDataset: string\n updatedAt: string\n withHistory: boolean\n}\n\nexport async function listDatasetCopyJobs({\n limit,\n offset,\n projectId,\n}: ListDatasetCopyJobsOptions): Promise<DatasetCopyJob[]> {\n const client = await getDatasetClient(projectId)\n const query: {limit?: string; offset?: string} = {}\n\n if (offset !== undefined && offset >= 0) {\n query.offset = `${offset}`\n }\n if (limit !== undefined && limit > 0) {\n query.limit = `${limit}`\n }\n\n return client.request<DatasetCopyJob[]>({\n method: 'GET',\n query,\n uri: `/projects/${projectId}/datasets/copy`,\n })\n}\n\nexport interface CopyJobProgressEvent {\n type: 'reconnect' | string\n\n progress?: number\n state?: 'completed' | 'failed' | 'pending' | 'processing'\n}\n\ninterface FollowCopyJobProgressOptions {\n jobId: string\n projectId: string\n}\n\nasync function getJobListenUrl(projectId: string, jobId: string): Promise<string> {\n const client = await getDatasetClient(projectId)\n const baseUrl = client.config().url || 'https://api.sanity.io'\n return `${baseUrl}/jobs/${jobId}/listen`\n}\n\nexport function followCopyJobProgress({\n jobId,\n projectId,\n}: FollowCopyJobProgressOptions): Observable<CopyJobProgressEvent> {\n return new Observable<CopyJobProgressEvent>((observer) => {\n let progressSource: InstanceType<typeof EventSource> | null = null\n let stopped = false\n\n getJobListenUrl(projectId, jobId)\n .then((url) => {\n progressSource = new EventSource(url)\n\n function onError() {\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n\n if (stopped) {\n return\n }\n\n observer.next({type: 'reconnect'})\n progressSource = new EventSource(url)\n attachListeners()\n }\n\n function onChannelError(error: MessageEvent) {\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n const errorMessage = error.data\n ? `Copy job failed: ${error.data}`\n : 'Copy job failed: Connection to server lost. Please check the job status using --list and retry if needed.'\n observer.error(new Error(errorMessage))\n }\n\n function onMessage(event: MessageEvent) {\n let data\n try {\n data = JSON.parse(event.data)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n observer.error(new Error(`Invalid JSON received from server: ${message}`))\n return\n }\n\n if (data.state === 'failed') {\n const failureReason = data.message || data.error || 'Unknown reason'\n observer.error(new Error(`Copy job failed: ${failureReason}`))\n } else if (data.state === 'completed') {\n onComplete()\n } else {\n observer.next(data)\n }\n }\n\n function onComplete() {\n if (progressSource) {\n progressSource.removeEventListener('error', onError)\n progressSource.removeEventListener('channel_error', onChannelError)\n progressSource.removeEventListener('job', onMessage)\n progressSource.removeEventListener('done', onComplete)\n progressSource.close()\n progressSource = null\n }\n observer.complete()\n }\n\n function attachListeners() {\n if (progressSource) {\n progressSource.addEventListener('error', onError)\n progressSource.addEventListener('channel_error', onChannelError)\n progressSource.addEventListener('job', onMessage)\n progressSource.addEventListener('done', onComplete)\n }\n }\n\n attachListeners()\n })\n .catch((error) => {\n observer.error(error)\n })\n\n return () => {\n if (stopped) return\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n }\n })\n}\n"],"names":["getProjectCliClient","EventSource","Observable","DATASET_API_VERSION","getDatasetClient","projectId","apiVersion","requireUser","listDatasets","client","datasets","list","listDatasetAliases","request","uri","deleteDataset","datasetName","delete","editDatasetAcl","aclMode","edit","createDataset","create","copyDataset","skipHistory","sourceDataset","targetDataset","body","method","listDatasetCopyJobs","limit","offset","query","undefined","getJobListenUrl","jobId","baseUrl","config","url","followCopyJobProgress","observer","progressSource","stopped","then","onError","close","next","type","attachListeners","onChannelError","error","errorMessage","data","Error","onMessage","event","JSON","parse","message","state","failureReason","onComplete","removeEventListener","complete","addEventListener","catch"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,mBAAkB;AAEpD,SAAQC,WAAW,QAAO,cAAa;AACvC,SAAQC,UAAU,QAAO,OAAM;AAE/B,OAAO,MAAMC,sBAAsB,cAAa;AAEhD,SAASC,iBAAiBC,SAAiB;IACzC,OAAOL,oBAAoB;QACzBM,YAAYH;QACZE;QACAE,aAAa;IACf;AACF;AAEA,OAAO,eAAeC,aAAaH,SAAiB;IAClD,MAAMI,SAAS,MAAML,iBAAiBC;IACtC,OAAOI,OAAOC,QAAQ,CAACC,IAAI;AAC7B;AAOA,OAAO,eAAeC,mBAAmBP,SAAiB;IACxD,MAAMI,SAAS,MAAML,iBAAiBC;IACtC,OAAOI,OAAOI,OAAO,CAA2B;QAACC,KAAK;IAAU;AAClE;AAOA,OAAO,eAAeC,cAAc,EAACC,WAAW,EAAEX,SAAS,EAAuB;IAChF,MAAMI,SAAS,MAAML,iBAAiBC;IACtC,OAAOI,OAAOC,QAAQ,CAACO,MAAM,CAACD;AAChC;AAQA,OAAO,eAAeE,eAAe,EAACC,OAAO,EAAEH,WAAW,EAAEX,SAAS,EAAwB;IAC3F,MAAMI,SAAS,MAAML,iBAAiBC;IACtC,OAAOI,OAAOC,QAAQ,CAACU,IAAI,CAACJ,aAAa;QAACG;IAAO;AACnD;AASA,OAAO,eAAeE,cAAc,EAACF,OAAO,EAAEH,WAAW,EAAEX,SAAS,EAAuB;IACzF,MAAMI,SAAS,MAAML,iBAAiBC;IAEtC,IAAIc,SAAS;QACX,OAAOV,OAAOC,QAAQ,CAACY,MAAM,CAACN,aAAa;YAACG;QAAO;IACrD;IAEA,OAAOV,OAAOC,QAAQ,CAACY,MAAM,CAACN;AAChC;AAaA,OAAO,eAAeO,YAAY,EAChClB,SAAS,EACTmB,WAAW,EACXC,aAAa,EACbC,aAAa,EACM;IACnB,MAAMjB,SAAS,MAAML,iBAAiBC;IACtC,OAAOI,OAAOI,OAAO,CAAsB;QACzCc,MAAM;YACJH;YACAE;QACF;QACAE,QAAQ;QACRd,KAAK,CAAC,UAAU,EAAEW,cAAc,KAAK,CAAC;IACxC;AACF;AAmBA,OAAO,eAAeI,oBAAoB,EACxCC,KAAK,EACLC,MAAM,EACN1B,SAAS,EACkB;IAC3B,MAAMI,SAAS,MAAML,iBAAiBC;IACtC,MAAM2B,QAA2C,CAAC;IAElD,IAAID,WAAWE,aAAaF,UAAU,GAAG;QACvCC,MAAMD,MAAM,GAAG,GAAGA,QAAQ;IAC5B;IACA,IAAID,UAAUG,aAAaH,QAAQ,GAAG;QACpCE,MAAMF,KAAK,GAAG,GAAGA,OAAO;IAC1B;IAEA,OAAOrB,OAAOI,OAAO,CAAmB;QACtCe,QAAQ;QACRI;QACAlB,KAAK,CAAC,UAAU,EAAET,UAAU,cAAc,CAAC;IAC7C;AACF;AAcA,eAAe6B,gBAAgB7B,SAAiB,EAAE8B,KAAa;IAC7D,MAAM1B,SAAS,MAAML,iBAAiBC;IACtC,MAAM+B,UAAU3B,OAAO4B,MAAM,GAAGC,GAAG,IAAI;IACvC,OAAO,GAAGF,QAAQ,MAAM,EAAED,MAAM,OAAO,CAAC;AAC1C;AAEA,OAAO,SAASI,sBAAsB,EACpCJ,KAAK,EACL9B,SAAS,EACoB;IAC7B,OAAO,IAAIH,WAAiC,CAACsC;QAC3C,IAAIC,iBAA0D;QAC9D,IAAIC,UAAU;QAEdR,gBAAgB7B,WAAW8B,OACxBQ,IAAI,CAAC,CAACL;YACLG,iBAAiB,IAAIxC,YAAYqC;YAEjC,SAASM;gBACP,IAAIH,gBAAgB;oBAClBA,eAAeI,KAAK;oBACpBJ,iBAAiB;gBACnB;gBAEA,IAAIC,SAAS;oBACX;gBACF;gBAEAF,SAASM,IAAI,CAAC;oBAACC,MAAM;gBAAW;gBAChCN,iBAAiB,IAAIxC,YAAYqC;gBACjCU;YACF;YAEA,SAASC,eAAeC,KAAmB;gBACzCR,UAAU;gBACV,IAAID,gBAAgB;oBAClBA,eAAeI,KAAK;oBACpBJ,iBAAiB;gBACnB;gBACA,MAAMU,eAAeD,MAAME,IAAI,GAC3B,CAAC,iBAAiB,EAAEF,MAAME,IAAI,EAAE,GAChC;gBACJZ,SAASU,KAAK,CAAC,IAAIG,MAAMF;YAC3B;YAEA,SAASG,UAAUC,KAAmB;gBACpC,IAAIH;gBACJ,IAAI;oBACFA,OAAOI,KAAKC,KAAK,CAACF,MAAMH,IAAI;gBAC9B,EAAE,OAAOF,OAAO;oBACd,MAAMQ,UAAUR,iBAAiBG,QAAQH,MAAMQ,OAAO,GAAG;oBACzDlB,SAASU,KAAK,CAAC,IAAIG,MAAM,CAAC,mCAAmC,EAAEK,SAAS;oBACxE;gBACF;gBAEA,IAAIN,KAAKO,KAAK,KAAK,UAAU;oBAC3B,MAAMC,gBAAgBR,KAAKM,OAAO,IAAIN,KAAKF,KAAK,IAAI;oBACpDV,SAASU,KAAK,CAAC,IAAIG,MAAM,CAAC,iBAAiB,EAAEO,eAAe;gBAC9D,OAAO,IAAIR,KAAKO,KAAK,KAAK,aAAa;oBACrCE;gBACF,OAAO;oBACLrB,SAASM,IAAI,CAACM;gBAChB;YACF;YAEA,SAASS;gBACP,IAAIpB,gBAAgB;oBAClBA,eAAeqB,mBAAmB,CAAC,SAASlB;oBAC5CH,eAAeqB,mBAAmB,CAAC,iBAAiBb;oBACpDR,eAAeqB,mBAAmB,CAAC,OAAOR;oBAC1Cb,eAAeqB,mBAAmB,CAAC,QAAQD;oBAC3CpB,eAAeI,KAAK;oBACpBJ,iBAAiB;gBACnB;gBACAD,SAASuB,QAAQ;YACnB;YAEA,SAASf;gBACP,IAAIP,gBAAgB;oBAClBA,eAAeuB,gBAAgB,CAAC,SAASpB;oBACzCH,eAAeuB,gBAAgB,CAAC,iBAAiBf;oBACjDR,eAAeuB,gBAAgB,CAAC,OAAOV;oBACvCb,eAAeuB,gBAAgB,CAAC,QAAQH;gBAC1C;YACF;YAEAb;QACF,GACCiB,KAAK,CAAC,CAACf;YACNV,SAASU,KAAK,CAACA;QACjB;QAEF,OAAO;YACL,IAAIR,SAAS;YACbA,UAAU;YACV,IAAID,gBAAgB;gBAClBA,eAAeI,KAAK;gBACpBJ,iBAAiB;YACnB;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/services/datasets.ts"],"sourcesContent":["import {getProjectCliClient} from '@sanity/cli-core'\nimport {\n type DatasetCreateOptions as ClientCreateOptions,\n type DatasetAclMode,\n type EmbeddingsSettingsBody,\n} from '@sanity/client'\nimport {EventSource} from 'eventsource'\nimport {Observable} from 'rxjs'\n\nexport const DATASET_API_VERSION = 'v2025-09-16'\n\nfunction getDatasetClient(projectId: string) {\n return getProjectCliClient({\n apiVersion: DATASET_API_VERSION,\n projectId,\n requireUser: true,\n })\n}\n\nexport async function listDatasets(projectId: string) {\n const client = await getDatasetClient(projectId)\n return client.datasets.list()\n}\n\nexport interface DatasetAliasDefinition {\n datasetName: string | null\n name: string\n}\n\nexport async function listDatasetAliases(projectId: string): Promise<DatasetAliasDefinition[]> {\n const client = await getDatasetClient(projectId)\n return client.request<DatasetAliasDefinition[]>({uri: '/aliases'})\n}\n\ninterface DeleteDatasetOptions {\n datasetName: string\n projectId: string\n}\n\nexport async function deleteDataset({datasetName, projectId}: DeleteDatasetOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.delete(datasetName)\n}\n\ninterface EditDatasetAclOptions {\n aclMode: 'private' | 'public'\n datasetName: string\n projectId: string\n}\n\nexport async function editDatasetAcl({aclMode, datasetName, projectId}: EditDatasetAclOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.edit(datasetName, {aclMode})\n}\n\ninterface CreateDatasetOptions {\n datasetName: string\n projectId: string\n\n aclMode?: DatasetAclMode\n embeddings?: EmbeddingsSettingsBody\n}\n\nexport async function createDataset({\n aclMode,\n datasetName,\n embeddings,\n projectId,\n}: CreateDatasetOptions) {\n const client = await getDatasetClient(projectId)\n const options: ClientCreateOptions = {}\n\n if (aclMode) {\n options.aclMode = aclMode\n }\n if (embeddings) {\n options.embeddings = embeddings\n }\n\n return client.datasets.create(datasetName, options)\n}\n\ninterface CopyDatasetOptions {\n projectId: string\n skipHistory: boolean\n sourceDataset: string\n targetDataset: string\n}\n\ninterface CopyDatasetResponse {\n jobId: string\n}\n\nexport async function copyDataset({\n projectId,\n skipHistory,\n sourceDataset,\n targetDataset,\n}: CopyDatasetOptions): Promise<CopyDatasetResponse> {\n const client = await getDatasetClient(projectId)\n return client.request<CopyDatasetResponse>({\n body: {\n skipHistory,\n targetDataset,\n },\n method: 'PUT',\n uri: `/datasets/${sourceDataset}/copy`,\n })\n}\n\ninterface ListDatasetCopyJobsOptions {\n projectId: string\n\n limit?: number\n offset?: number\n}\n\nexport interface DatasetCopyJob {\n createdAt: string\n id: string\n sourceDataset: string\n state: string\n targetDataset: string\n updatedAt: string\n withHistory: boolean\n}\n\nexport async function listDatasetCopyJobs({\n limit,\n offset,\n projectId,\n}: ListDatasetCopyJobsOptions): Promise<DatasetCopyJob[]> {\n const client = await getDatasetClient(projectId)\n const query: {limit?: string; offset?: string} = {}\n\n if (offset !== undefined && offset >= 0) {\n query.offset = `${offset}`\n }\n if (limit !== undefined && limit > 0) {\n query.limit = `${limit}`\n }\n\n return client.request<DatasetCopyJob[]>({\n method: 'GET',\n query,\n uri: `/projects/${projectId}/datasets/copy`,\n })\n}\n\nexport interface CopyJobProgressEvent {\n type: 'reconnect' | string\n\n progress?: number\n state?: 'completed' | 'failed' | 'pending' | 'processing'\n}\n\ninterface FollowCopyJobProgressOptions {\n jobId: string\n projectId: string\n}\n\nasync function getJobListenUrl(projectId: string, jobId: string): Promise<string> {\n const client = await getDatasetClient(projectId)\n const baseUrl = client.config().url || 'https://api.sanity.io'\n return `${baseUrl}/jobs/${jobId}/listen`\n}\n\nexport function followCopyJobProgress({\n jobId,\n projectId,\n}: FollowCopyJobProgressOptions): Observable<CopyJobProgressEvent> {\n return new Observable<CopyJobProgressEvent>((observer) => {\n let progressSource: InstanceType<typeof EventSource> | null = null\n let stopped = false\n\n getJobListenUrl(projectId, jobId)\n .then((url) => {\n progressSource = new EventSource(url)\n\n function onError() {\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n\n if (stopped) {\n return\n }\n\n observer.next({type: 'reconnect'})\n progressSource = new EventSource(url)\n attachListeners()\n }\n\n function onChannelError(error: MessageEvent) {\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n const errorMessage = error.data\n ? `Copy job failed: ${error.data}`\n : 'Copy job failed: Connection to server lost. Please check the job status using --list and retry if needed.'\n observer.error(new Error(errorMessage))\n }\n\n function onMessage(event: MessageEvent) {\n let data\n try {\n data = JSON.parse(event.data)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n observer.error(new Error(`Invalid JSON received from server: ${message}`))\n return\n }\n\n if (data.state === 'failed') {\n const failureReason = data.message || data.error || 'Unknown reason'\n observer.error(new Error(`Copy job failed: ${failureReason}`))\n } else if (data.state === 'completed') {\n onComplete()\n } else {\n observer.next(data)\n }\n }\n\n function onComplete() {\n if (progressSource) {\n progressSource.removeEventListener('error', onError)\n progressSource.removeEventListener('channel_error', onChannelError)\n progressSource.removeEventListener('job', onMessage)\n progressSource.removeEventListener('done', onComplete)\n progressSource.close()\n progressSource = null\n }\n observer.complete()\n }\n\n function attachListeners() {\n if (progressSource) {\n progressSource.addEventListener('error', onError)\n progressSource.addEventListener('channel_error', onChannelError)\n progressSource.addEventListener('job', onMessage)\n progressSource.addEventListener('done', onComplete)\n }\n }\n\n attachListeners()\n })\n .catch((error) => {\n observer.error(error)\n })\n\n return () => {\n if (stopped) return\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n }\n })\n}\n"],"names":["getProjectCliClient","EventSource","Observable","DATASET_API_VERSION","getDatasetClient","projectId","apiVersion","requireUser","listDatasets","client","datasets","list","listDatasetAliases","request","uri","deleteDataset","datasetName","delete","editDatasetAcl","aclMode","edit","createDataset","embeddings","options","create","copyDataset","skipHistory","sourceDataset","targetDataset","body","method","listDatasetCopyJobs","limit","offset","query","undefined","getJobListenUrl","jobId","baseUrl","config","url","followCopyJobProgress","observer","progressSource","stopped","then","onError","close","next","type","attachListeners","onChannelError","error","errorMessage","data","Error","onMessage","event","JSON","parse","message","state","failureReason","onComplete","removeEventListener","complete","addEventListener","catch"],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getProjectCliClient } from '@sanity/cli-core';
|
|
2
|
+
import { DATASET_API_VERSION } from './datasets.js';
|
|
3
|
+
function getEmbeddingsClient(projectId) {
|
|
4
|
+
return getProjectCliClient({
|
|
5
|
+
apiVersion: DATASET_API_VERSION,
|
|
6
|
+
projectId,
|
|
7
|
+
requireUser: true
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
export async function getEmbeddingsSettings(projectId, dataset) {
|
|
11
|
+
const client = await getEmbeddingsClient(projectId);
|
|
12
|
+
return client.datasets.getEmbeddingsSettings(dataset);
|
|
13
|
+
}
|
|
14
|
+
export async function setEmbeddingsSettings({ dataset, enabled, projectId, projection }) {
|
|
15
|
+
const client = await getEmbeddingsClient(projectId);
|
|
16
|
+
const body = {
|
|
17
|
+
enabled,
|
|
18
|
+
...projection ? {
|
|
19
|
+
projection
|
|
20
|
+
} : {}
|
|
21
|
+
};
|
|
22
|
+
await client.datasets.editEmbeddingsSettings(dataset, body);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
//# sourceMappingURL=embeddings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/embeddings.ts"],"sourcesContent":["import {getProjectCliClient} from '@sanity/cli-core'\nimport {type EmbeddingsSettings, type EmbeddingsSettingsBody} from '@sanity/client'\n\nimport {DATASET_API_VERSION} from './datasets.js'\n\nfunction getEmbeddingsClient(projectId: string) {\n return getProjectCliClient({\n apiVersion: DATASET_API_VERSION,\n projectId,\n requireUser: true,\n })\n}\n\nexport async function getEmbeddingsSettings(\n projectId: string,\n dataset: string,\n): Promise<EmbeddingsSettings> {\n const client = await getEmbeddingsClient(projectId)\n return client.datasets.getEmbeddingsSettings(dataset)\n}\n\ninterface SetEmbeddingsOptions {\n dataset: string\n enabled: boolean\n projectId: string\n\n projection?: string\n}\n\nexport async function setEmbeddingsSettings({\n dataset,\n enabled,\n projectId,\n projection,\n}: SetEmbeddingsOptions): Promise<void> {\n const client = await getEmbeddingsClient(projectId)\n const body: EmbeddingsSettingsBody = {enabled, ...(projection ? {projection} : {})}\n await client.datasets.editEmbeddingsSettings(dataset, body)\n}\n"],"names":["getProjectCliClient","DATASET_API_VERSION","getEmbeddingsClient","projectId","apiVersion","requireUser","getEmbeddingsSettings","dataset","client","datasets","setEmbeddingsSettings","enabled","projection","body","editEmbeddingsSettings"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,mBAAkB;AAGpD,SAAQC,mBAAmB,QAAO,gBAAe;AAEjD,SAASC,oBAAoBC,SAAiB;IAC5C,OAAOH,oBAAoB;QACzBI,YAAYH;QACZE;QACAE,aAAa;IACf;AACF;AAEA,OAAO,eAAeC,sBACpBH,SAAiB,EACjBI,OAAe;IAEf,MAAMC,SAAS,MAAMN,oBAAoBC;IACzC,OAAOK,OAAOC,QAAQ,CAACH,qBAAqB,CAACC;AAC/C;AAUA,OAAO,eAAeG,sBAAsB,EAC1CH,OAAO,EACPI,OAAO,EACPR,SAAS,EACTS,UAAU,EACW;IACrB,MAAMJ,SAAS,MAAMN,oBAAoBC;IACzC,MAAMU,OAA+B;QAACF;QAAS,GAAIC,aAAa;YAACA;QAAU,IAAI,CAAC,CAAC;IAAC;IAClF,MAAMJ,OAAOC,QAAQ,CAACK,sBAAsB,CAACP,SAASM;AACxD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getGlobalCliClient } from '@sanity/cli-core';
|
|
2
|
+
export const GRANTS_API_VERSION = '2025-01-01';
|
|
3
|
+
export async function getUserGrants() {
|
|
4
|
+
const client = await getGlobalCliClient({
|
|
5
|
+
apiVersion: GRANTS_API_VERSION,
|
|
6
|
+
requireUser: true
|
|
7
|
+
});
|
|
8
|
+
return client.request({
|
|
9
|
+
uri: '/users/me/grants'
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//# sourceMappingURL=grants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/services/grants.ts"],"sourcesContent":["import {getGlobalCliClient} from '@sanity/cli-core'\n\nimport {type UserGrantsResponse} from '../types/grants.js'\n\nexport const GRANTS_API_VERSION = '2025-01-01'\n\nexport async function getUserGrants(): Promise<UserGrantsResponse> {\n const client = await getGlobalCliClient({\n apiVersion: GRANTS_API_VERSION,\n requireUser: true,\n })\n\n return client.request<UserGrantsResponse>({uri: '/users/me/grants'})\n}\n"],"names":["getGlobalCliClient","GRANTS_API_VERSION","getUserGrants","client","apiVersion","requireUser","request","uri"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,mBAAkB;AAInD,OAAO,MAAMC,qBAAqB,aAAY;AAE9C,OAAO,eAAeC;IACpB,MAAMC,SAAS,MAAMH,mBAAmB;QACtCI,YAAYH;QACZI,aAAa;IACf;IAEA,OAAOF,OAAOG,OAAO,CAAqB;QAACC,KAAK;IAAkB;AACpE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/graphql.ts"],"sourcesContent":["import {getProjectCliClient} from '@sanity/cli-core'\n\nimport {\n type DeployResponse,\n type GeneratedApiSpecification,\n type ValidationResponse,\n} from '../actions/graphql/types.js'\nimport {getUrlHeaders} from './getUrlHeaders.js'\n\nexport const GRAPHQL_API_VERSION = 'v2025-09-19'\n\nexport interface GraphQLEndpoint {\n dataset: string\n generation: string\n playgroundEnabled: boolean\n projectId: string\n tag: string\n}\n\n/**\n * List all GraphQL endpoints for a project\n * @param client - The API client to use for the request\n * @returns A promise that resolves to an array of GraphQL endpoints\n *\n * @internal\n */\nexport async function listGraphQLEndpoints(projectId: string): Promise<GraphQLEndpoint[]> {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request<GraphQLEndpoint[]>({\n method: 'GET',\n uri: '/apis/graphql',\n })\n}\n\ninterface DeleteGraphQLAPIOptions {\n dataset: string\n projectId: string\n tag: string\n}\n\nexport async function deleteGraphQLAPI({dataset, projectId, tag}: DeleteGraphQLAPIOptions) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request({\n method: 'DELETE',\n uri: `/apis/graphql/${dataset}/${tag}`,\n })\n}\n\nexport async function validateGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema,\n tag,\n}: {\n dataset: string\n enablePlayground: boolean\n projectId: string\n schema: GeneratedApiSpecification\n tag: string\n}) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request<ValidationResponse>({\n body: {enablePlayground, schema},\n maxRedirects: 0,\n method: 'POST',\n url: `/apis/graphql/${dataset}/${tag}/validate`,\n })\n}\n\ninterface DeployGraphQLAPIOptions {\n dataset: string\n enablePlayground: boolean\n projectId: string\n schema: GeneratedApiSpecification\n tag: string\n}\n\nexport async function deployGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema,\n tag,\n}: DeployGraphQLAPIOptions) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request<DeployResponse>({\n body: {enablePlayground, schema},\n maxRedirects: 0,\n method: 'PUT',\n url: `/apis/graphql/${dataset}/${tag}`,\n })\n}\n\nexport async function getClientUrl(projectId: string, uri: string) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return `${client.config().url}/${uri.replace(/^\\//, '')}`\n}\n\nexport async function getCurrentSchemaProps(\n projectId: string,\n dataset: string,\n tag: string,\n): Promise<{\n currentGeneration?: string\n playgroundEnabled?: boolean\n}> {\n try {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n })\n\n const uri = `/apis/graphql/${dataset}/${tag}`\n const config = client.config()\n const apiUrl = `${config.url}/${uri.replace(/^\\//, '')}`\n\n const res = await getUrlHeaders(apiUrl, {\n Authorization: `Bearer ${config.token}`,\n })\n\n return {\n currentGeneration: res['x-sanity-graphql-generation'],\n playgroundEnabled: res['x-sanity-graphql-playground'] === 'true',\n }\n } catch (err) {\n if (err instanceof Error
|
|
1
|
+
{"version":3,"sources":["../../src/services/graphql.ts"],"sourcesContent":["import {getProjectCliClient} from '@sanity/cli-core'\n\nimport {\n type DeployResponse,\n type GeneratedApiSpecification,\n type ValidationResponse,\n} from '../actions/graphql/types.js'\nimport {getUrlHeaders} from './getUrlHeaders.js'\n\nexport const GRAPHQL_API_VERSION = 'v2025-09-19'\n\nexport interface GraphQLEndpoint {\n dataset: string\n generation: string\n playgroundEnabled: boolean\n projectId: string\n tag: string\n}\n\n/**\n * List all GraphQL endpoints for a project\n * @param client - The API client to use for the request\n * @returns A promise that resolves to an array of GraphQL endpoints\n *\n * @internal\n */\nexport async function listGraphQLEndpoints(projectId: string): Promise<GraphQLEndpoint[]> {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request<GraphQLEndpoint[]>({\n method: 'GET',\n uri: '/apis/graphql',\n })\n}\n\ninterface DeleteGraphQLAPIOptions {\n dataset: string\n projectId: string\n tag: string\n}\n\nexport async function deleteGraphQLAPI({dataset, projectId, tag}: DeleteGraphQLAPIOptions) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request({\n method: 'DELETE',\n uri: `/apis/graphql/${dataset}/${tag}`,\n })\n}\n\nexport async function validateGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema,\n tag,\n}: {\n dataset: string\n enablePlayground: boolean\n projectId: string\n schema: GeneratedApiSpecification\n tag: string\n}) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request<ValidationResponse>({\n body: {enablePlayground, schema},\n maxRedirects: 0,\n method: 'POST',\n url: `/apis/graphql/${dataset}/${tag}/validate`,\n })\n}\n\ninterface DeployGraphQLAPIOptions {\n dataset: string\n enablePlayground: boolean\n projectId: string\n schema: GeneratedApiSpecification\n tag: string\n}\n\nexport async function deployGraphQLAPI({\n dataset,\n enablePlayground,\n projectId,\n schema,\n tag,\n}: DeployGraphQLAPIOptions) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return client.request<DeployResponse>({\n body: {enablePlayground, schema},\n maxRedirects: 0,\n method: 'PUT',\n url: `/apis/graphql/${dataset}/${tag}`,\n })\n}\n\nexport async function getClientUrl(projectId: string, uri: string) {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n requireUser: true,\n })\n\n return `${client.config().url}/${uri.replace(/^\\//, '')}`\n}\n\nexport async function getCurrentSchemaProps(\n projectId: string,\n dataset: string,\n tag: string,\n): Promise<{\n currentGeneration?: string\n playgroundEnabled?: boolean\n}> {\n try {\n const client = await getProjectCliClient({\n apiVersion: GRAPHQL_API_VERSION,\n projectId,\n })\n\n const uri = `/apis/graphql/${dataset}/${tag}`\n const config = client.config()\n const apiUrl = `${config.url}/${uri.replace(/^\\//, '')}`\n\n const res = await getUrlHeaders(apiUrl, {\n Authorization: `Bearer ${config.token}`,\n })\n\n return {\n currentGeneration: res['x-sanity-graphql-generation'],\n playgroundEnabled: res['x-sanity-graphql-playground'] === 'true',\n }\n } catch (err) {\n if (\n err instanceof Error &&\n 'response' in err &&\n typeof err.response === 'object' &&\n err.response !== null &&\n 'statusCode' in err.response &&\n err.response.statusCode === 404\n ) {\n return {}\n }\n\n throw err\n }\n}\n"],"names":["getProjectCliClient","getUrlHeaders","GRAPHQL_API_VERSION","listGraphQLEndpoints","projectId","client","apiVersion","requireUser","request","method","uri","deleteGraphQLAPI","dataset","tag","validateGraphQLAPI","enablePlayground","schema","body","maxRedirects","url","deployGraphQLAPI","getClientUrl","config","replace","getCurrentSchemaProps","apiUrl","res","Authorization","token","currentGeneration","playgroundEnabled","err","Error","response","statusCode"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,mBAAkB;AAOpD,SAAQC,aAAa,QAAO,qBAAoB;AAEhD,OAAO,MAAMC,sBAAsB,cAAa;AAUhD;;;;;;CAMC,GACD,OAAO,eAAeC,qBAAqBC,SAAiB;IAC1D,MAAMC,SAAS,MAAML,oBAAoB;QACvCM,YAAYJ;QACZE;QACAG,aAAa;IACf;IAEA,OAAOF,OAAOG,OAAO,CAAoB;QACvCC,QAAQ;QACRC,KAAK;IACP;AACF;AAQA,OAAO,eAAeC,iBAAiB,EAACC,OAAO,EAAER,SAAS,EAAES,GAAG,EAA0B;IACvF,MAAMR,SAAS,MAAML,oBAAoB;QACvCM,YAAYJ;QACZE;QACAG,aAAa;IACf;IAEA,OAAOF,OAAOG,OAAO,CAAC;QACpBC,QAAQ;QACRC,KAAK,CAAC,cAAc,EAAEE,QAAQ,CAAC,EAAEC,KAAK;IACxC;AACF;AAEA,OAAO,eAAeC,mBAAmB,EACvCF,OAAO,EACPG,gBAAgB,EAChBX,SAAS,EACTY,MAAM,EACNH,GAAG,EAOJ;IACC,MAAMR,SAAS,MAAML,oBAAoB;QACvCM,YAAYJ;QACZE;QACAG,aAAa;IACf;IAEA,OAAOF,OAAOG,OAAO,CAAqB;QACxCS,MAAM;YAACF;YAAkBC;QAAM;QAC/BE,cAAc;QACdT,QAAQ;QACRU,KAAK,CAAC,cAAc,EAAEP,QAAQ,CAAC,EAAEC,IAAI,SAAS,CAAC;IACjD;AACF;AAUA,OAAO,eAAeO,iBAAiB,EACrCR,OAAO,EACPG,gBAAgB,EAChBX,SAAS,EACTY,MAAM,EACNH,GAAG,EACqB;IACxB,MAAMR,SAAS,MAAML,oBAAoB;QACvCM,YAAYJ;QACZE;QACAG,aAAa;IACf;IAEA,OAAOF,OAAOG,OAAO,CAAiB;QACpCS,MAAM;YAACF;YAAkBC;QAAM;QAC/BE,cAAc;QACdT,QAAQ;QACRU,KAAK,CAAC,cAAc,EAAEP,QAAQ,CAAC,EAAEC,KAAK;IACxC;AACF;AAEA,OAAO,eAAeQ,aAAajB,SAAiB,EAAEM,GAAW;IAC/D,MAAML,SAAS,MAAML,oBAAoB;QACvCM,YAAYJ;QACZE;QACAG,aAAa;IACf;IAEA,OAAO,GAAGF,OAAOiB,MAAM,GAAGH,GAAG,CAAC,CAAC,EAAET,IAAIa,OAAO,CAAC,OAAO,KAAK;AAC3D;AAEA,OAAO,eAAeC,sBACpBpB,SAAiB,EACjBQ,OAAe,EACfC,GAAW;IAKX,IAAI;QACF,MAAMR,SAAS,MAAML,oBAAoB;YACvCM,YAAYJ;YACZE;QACF;QAEA,MAAMM,MAAM,CAAC,cAAc,EAAEE,QAAQ,CAAC,EAAEC,KAAK;QAC7C,MAAMS,SAASjB,OAAOiB,MAAM;QAC5B,MAAMG,SAAS,GAAGH,OAAOH,GAAG,CAAC,CAAC,EAAET,IAAIa,OAAO,CAAC,OAAO,KAAK;QAExD,MAAMG,MAAM,MAAMzB,cAAcwB,QAAQ;YACtCE,eAAe,CAAC,OAAO,EAAEL,OAAOM,KAAK,EAAE;QACzC;QAEA,OAAO;YACLC,mBAAmBH,GAAG,CAAC,8BAA8B;YACrDI,mBAAmBJ,GAAG,CAAC,8BAA8B,KAAK;QAC5D;IACF,EAAE,OAAOK,KAAK;QACZ,IACEA,eAAeC,SACf,cAAcD,OACd,OAAOA,IAAIE,QAAQ,KAAK,YACxBF,IAAIE,QAAQ,KAAK,QACjB,gBAAgBF,IAAIE,QAAQ,IAC5BF,IAAIE,QAAQ,CAACC,UAAU,KAAK,KAC5B;YACA,OAAO,CAAC;QACV;QAEA,MAAMH;IACR;AACF"}
|
package/dist/services/schemas.js
CHANGED
|
@@ -30,7 +30,7 @@ export async function updateSchemas(dataset, projectId, schemas) {
|
|
|
30
30
|
const client = await getSchemaClient();
|
|
31
31
|
return client.request({
|
|
32
32
|
body: {
|
|
33
|
-
schemas
|
|
33
|
+
schemas
|
|
34
34
|
},
|
|
35
35
|
method: 'PUT',
|
|
36
36
|
url: `/projects/${projectId}/datasets/${dataset}/schemas`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/services/schemas.ts"],"sourcesContent":["import {getGlobalCliClient} from '@sanity/cli-core'\n\nimport {type StoredWorkspaceSchema} from '../actions/manifest/types.js'\n\nexport const SCHEMA_API_VERSION = 'v2025-03-01'\n\nasync function getSchemaClient() {\n return await getGlobalCliClient({\n apiVersion: SCHEMA_API_VERSION,\n requireUser: true,\n })\n}\n\nexport async function getSchemas(dataset: string, projectId: string, id?: string) {\n const client = await getSchemaClient()\n\n return client.request<StoredWorkspaceSchema[]>({\n method: 'GET',\n uri: `/projects/${projectId}/datasets/${dataset}/schemas${id ? `/${id}` : ''}`,\n })\n}\n\nexport async function deleteSchema(dataset: string, projectId: string, id: string) {\n const exists = await getSchemas(dataset, projectId, id)\n\n if (exists?.length === 0) {\n return {\n deleted: false,\n }\n }\n\n const client = await getSchemaClient()\n\n return client.request({\n method: 'DELETE',\n uri: `/projects/${projectId}/datasets/${dataset}/schemas/${id}`,\n })\n}\n\nexport async function updateSchemas<T>(dataset: string, projectId: string, schemas: T) {\n const client = await getSchemaClient()\n\n return client.request({\n body: {\n schemas
|
|
1
|
+
{"version":3,"sources":["../../src/services/schemas.ts"],"sourcesContent":["import {getGlobalCliClient} from '@sanity/cli-core'\n\nimport {type StoredWorkspaceSchema} from '../actions/manifest/types.js'\n\nexport const SCHEMA_API_VERSION = 'v2025-03-01'\n\nasync function getSchemaClient() {\n return await getGlobalCliClient({\n apiVersion: SCHEMA_API_VERSION,\n requireUser: true,\n })\n}\n\nexport async function getSchemas(dataset: string, projectId: string, id?: string) {\n const client = await getSchemaClient()\n\n return client.request<StoredWorkspaceSchema[]>({\n method: 'GET',\n uri: `/projects/${projectId}/datasets/${dataset}/schemas${id ? `/${id}` : ''}`,\n })\n}\n\nexport async function deleteSchema(dataset: string, projectId: string, id: string) {\n const exists = await getSchemas(dataset, projectId, id)\n\n if (exists?.length === 0) {\n return {\n deleted: false,\n }\n }\n\n const client = await getSchemaClient()\n\n return client.request({\n method: 'DELETE',\n uri: `/projects/${projectId}/datasets/${dataset}/schemas/${id}`,\n })\n}\n\nexport async function updateSchemas<T>(dataset: string, projectId: string, schemas: T) {\n const client = await getSchemaClient()\n\n return client.request({\n body: {\n schemas,\n },\n method: 'PUT',\n url: `/projects/${projectId}/datasets/${dataset}/schemas`,\n })\n}\n"],"names":["getGlobalCliClient","SCHEMA_API_VERSION","getSchemaClient","apiVersion","requireUser","getSchemas","dataset","projectId","id","client","request","method","uri","deleteSchema","exists","length","deleted","updateSchemas","schemas","body","url"],"mappings":"AAAA,SAAQA,kBAAkB,QAAO,mBAAkB;AAInD,OAAO,MAAMC,qBAAqB,cAAa;AAE/C,eAAeC;IACb,OAAO,MAAMF,mBAAmB;QAC9BG,YAAYF;QACZG,aAAa;IACf;AACF;AAEA,OAAO,eAAeC,WAAWC,OAAe,EAAEC,SAAiB,EAAEC,EAAW;IAC9E,MAAMC,SAAS,MAAMP;IAErB,OAAOO,OAAOC,OAAO,CAA0B;QAC7CC,QAAQ;QACRC,KAAK,CAAC,UAAU,EAAEL,UAAU,UAAU,EAAED,QAAQ,QAAQ,EAAEE,KAAK,CAAC,CAAC,EAAEA,IAAI,GAAG,IAAI;IAChF;AACF;AAEA,OAAO,eAAeK,aAAaP,OAAe,EAAEC,SAAiB,EAAEC,EAAU;IAC/E,MAAMM,SAAS,MAAMT,WAAWC,SAASC,WAAWC;IAEpD,IAAIM,QAAQC,WAAW,GAAG;QACxB,OAAO;YACLC,SAAS;QACX;IACF;IAEA,MAAMP,SAAS,MAAMP;IAErB,OAAOO,OAAOC,OAAO,CAAC;QACpBC,QAAQ;QACRC,KAAK,CAAC,UAAU,EAAEL,UAAU,UAAU,EAAED,QAAQ,SAAS,EAAEE,IAAI;IACjE;AACF;AAEA,OAAO,eAAeS,cAAiBX,OAAe,EAAEC,SAAiB,EAAEW,OAAU;IACnF,MAAMT,SAAS,MAAMP;IAErB,OAAOO,OAAOC,OAAO,CAAC;QACpBS,MAAM;YACJD;QACF;QACAP,QAAQ;QACRS,KAAK,CAAC,UAAU,EAAEb,UAAU,UAAU,EAAED,QAAQ,QAAQ,CAAC;IAC3D;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/types/grants.ts"],"sourcesContent":["export interface RequiredPermission {\n /** The grant type, e.g. 'read', 'create', 'update', 'delete' */\n grant: string\n /** The permission scope, e.g. 'sanity.project.datasets' */\n permission: string\n}\n\ninterface GrantResource {\n grants: Array<{name: string; params: Record<string, unknown>}>\n}\n\nexport interface UserGrantsResponse {\n organizations: Record<string, Record<string, GrantResource[]>>\n projects: Record<string, Record<string, GrantResource[]>>\n}\n"],"names":[],"mappings":"AAWA,WAGC"}
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * PackageJson type is now consolidated in readPackageJson.ts\n * Re-exported here for backward compatibility.\n *\n * @public\n */\nexport type {PackageJson, ReadPackageJsonOptions} from '@sanity/cli-core'\n\nexport interface CliApiConfig {\n dataset?: string\n projectId?: string\n}\n\nexport interface SanityJson {\n __experimental_spaces?: {\n api: {\n dataset?: string\n projectId?: string\n }\n default?: true\n name: string\n title: string\n }[]\n api?: CliApiConfig\n env?: {\n development?: SanityJson\n production?: SanityJson\n staging?: SanityJson\n }\n parts?: {\n description?: string\n implements?: string\n name?: string\n path?: string\n }[]\n plugins?: string[]\n project?: {\n basePath?: string\n name?: string\n }\n root?: boolean\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * PackageJson type is now consolidated in readPackageJson.ts\n * Re-exported here for backward compatibility.\n *\n * @public\n */\nexport type {PackageJson, ReadPackageJsonOptions} from '@sanity/cli-core'\n\n/**\n * @public\n */\nexport interface CliApiConfig {\n dataset?: string\n projectId?: string\n}\n\nexport interface SanityJson {\n __experimental_spaces?: {\n api: {\n dataset?: string\n projectId?: string\n }\n default?: true\n name: string\n title: string\n }[]\n api?: CliApiConfig\n env?: {\n development?: SanityJson\n production?: SanityJson\n staging?: SanityJson\n }\n parts?: {\n description?: string\n implements?: string\n name?: string\n path?: string\n }[]\n plugins?: string[]\n project?: {\n basePath?: string\n name?: string\n }\n root?: boolean\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAWD,WA4BC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns the set of project IDs that have ALL of the required permissions.
|
|
3
|
+
*
|
|
4
|
+
* Iterates through `grants.projects` and checks that each project has every
|
|
5
|
+
* required `{permission, grant}` combination present in its grant resources.
|
|
6
|
+
*/ export function getProjectsWithPermissions(grants, requiredPermissions) {
|
|
7
|
+
const permitted = new Set();
|
|
8
|
+
for (const [projectId, permissionMap] of Object.entries(grants.projects)){
|
|
9
|
+
const hasAll = requiredPermissions.every(({ grant, permission })=>{
|
|
10
|
+
const resources = permissionMap[permission];
|
|
11
|
+
if (!resources) return false;
|
|
12
|
+
return resources.some((resource)=>resource.grants.some((g)=>g.name === grant));
|
|
13
|
+
});
|
|
14
|
+
if (hasAll) {
|
|
15
|
+
permitted.add(projectId);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
return permitted;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=checkProjectPermissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/util/checkProjectPermissions.ts"],"sourcesContent":["import {type RequiredPermission, type UserGrantsResponse} from '../types/grants.js'\n\n/**\n * Returns the set of project IDs that have ALL of the required permissions.\n *\n * Iterates through `grants.projects` and checks that each project has every\n * required `{permission, grant}` combination present in its grant resources.\n */\nexport function getProjectsWithPermissions(\n grants: UserGrantsResponse,\n requiredPermissions: RequiredPermission[],\n): Set<string> {\n const permitted = new Set<string>()\n\n for (const [projectId, permissionMap] of Object.entries(grants.projects)) {\n const hasAll = requiredPermissions.every(({grant, permission}) => {\n const resources = permissionMap[permission]\n if (!resources) return false\n return resources.some((resource) => resource.grants.some((g) => g.name === grant))\n })\n\n if (hasAll) {\n permitted.add(projectId)\n }\n }\n\n return permitted\n}\n"],"names":["getProjectsWithPermissions","grants","requiredPermissions","permitted","Set","projectId","permissionMap","Object","entries","projects","hasAll","every","grant","permission","resources","some","resource","g","name","add"],"mappings":"AAEA;;;;;CAKC,GACD,OAAO,SAASA,2BACdC,MAA0B,EAC1BC,mBAAyC;IAEzC,MAAMC,YAAY,IAAIC;IAEtB,KAAK,MAAM,CAACC,WAAWC,cAAc,IAAIC,OAAOC,OAAO,CAACP,OAAOQ,QAAQ,EAAG;QACxE,MAAMC,SAASR,oBAAoBS,KAAK,CAAC,CAAC,EAACC,KAAK,EAAEC,UAAU,EAAC;YAC3D,MAAMC,YAAYR,aAAa,CAACO,WAAW;YAC3C,IAAI,CAACC,WAAW,OAAO;YACvB,OAAOA,UAAUC,IAAI,CAAC,CAACC,WAAaA,SAASf,MAAM,CAACc,IAAI,CAAC,CAACE,IAAMA,EAAEC,IAAI,KAAKN;QAC7E;QAEA,IAAIF,QAAQ;YACVP,UAAUgB,GAAG,CAACd;QAChB;IACF;IAEA,OAAOF;AACT"}
|
|
@@ -28,11 +28,11 @@ const defaultRequester = createRequester({
|
|
|
28
28
|
* @param workDir - The path to the working directory containing the package.json file.
|
|
29
29
|
* @param options - Optional configuration for version comparison.
|
|
30
30
|
*
|
|
31
|
-
* @returns A promise that resolves to an
|
|
32
|
-
*
|
|
31
|
+
* @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)
|
|
32
|
+
* and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).
|
|
33
33
|
*
|
|
34
|
-
* @throws Throws an error if the remote version of a package cannot be fetched, or if the local version
|
|
35
|
-
* cannot be parsed.
|
|
34
|
+
* @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version
|
|
35
|
+
* of a package cannot be parsed.
|
|
36
36
|
*/ export async function compareDependencyVersions(packages, workDir, { appId, requester = defaultRequester } = {}) {
|
|
37
37
|
const manifest = await readPackageJson(path.join(workDir, 'package.json'), {
|
|
38
38
|
skipSchemaValidation: true
|
|
@@ -41,11 +41,26 @@ const defaultRequester = createRequester({
|
|
|
41
41
|
...manifest?.dependencies,
|
|
42
42
|
...manifest?.devDependencies
|
|
43
43
|
};
|
|
44
|
-
const
|
|
44
|
+
const mismatched = [];
|
|
45
|
+
const unresolvedPrerelease = [];
|
|
45
46
|
for (const pkg of packages){
|
|
47
|
+
// Skip packages that are not declared in the local package.json
|
|
48
|
+
if (!dependencies[pkg.name]) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
46
51
|
const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {
|
|
47
52
|
appId
|
|
48
53
|
}), requester);
|
|
54
|
+
if (resolvedVersion === null) {
|
|
55
|
+
if (semver.prerelease(pkg.version)) {
|
|
56
|
+
unresolvedPrerelease.push({
|
|
57
|
+
pkg: pkg.name,
|
|
58
|
+
version: pkg.version
|
|
59
|
+
});
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
throw new Error(`Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`);
|
|
63
|
+
}
|
|
49
64
|
const packageVersion = await getLocalPackageVersion(pkg.name, workDir);
|
|
50
65
|
const manifestVersion = dependencies[pkg.name];
|
|
51
66
|
const installed = semver.coerce(packageVersion ? semver.parse(packageVersion) : semver.coerce(manifestVersion));
|
|
@@ -53,14 +68,17 @@ const defaultRequester = createRequester({
|
|
|
53
68
|
throw new Error(`Failed to parse installed version for ${pkg.name}`);
|
|
54
69
|
}
|
|
55
70
|
if (!semver.eq(resolvedVersion, installed.version)) {
|
|
56
|
-
|
|
71
|
+
mismatched.push({
|
|
57
72
|
installed: installed.version,
|
|
58
73
|
pkg: pkg.name,
|
|
59
74
|
remote: resolvedVersion
|
|
60
75
|
});
|
|
61
76
|
}
|
|
62
77
|
}
|
|
63
|
-
return
|
|
78
|
+
return {
|
|
79
|
+
mismatched,
|
|
80
|
+
unresolvedPrerelease
|
|
81
|
+
};
|
|
64
82
|
}
|
|
65
83
|
async function getRemoteResolvedVersion(url, request) {
|
|
66
84
|
let response;
|
|
@@ -82,6 +100,9 @@ async function getRemoteResolvedVersion(url, request) {
|
|
|
82
100
|
}
|
|
83
101
|
return resolved;
|
|
84
102
|
}
|
|
103
|
+
if (response.statusCode === 404) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
85
106
|
throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`);
|
|
86
107
|
}
|
|
87
108
|
|