@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {Table} from 'console-table-printer'\n\nimport {type Token} from '../../actions/tokens/types.js'\nimport {getTokens} from '../../services/tokens.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/tokens/list.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {Table} from 'console-table-printer'\n\nimport {type Token} from '../../actions/tokens/types.js'\nimport {getTokens} from '../../services/tokens.js'\nimport {getErrorMessage} from '../../util/getErrorMessage.js'\n\nconst listTokenDebug = subdebug('tokens:list')\n\nexport class TokensListCommand extends SanityCommand<typeof TokensListCommand> {\n static override description = 'List API tokens for the current project'\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List tokens for the current project',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --json',\n description: 'List tokens in JSON format',\n },\n ]\n static override flags = {\n json: Flags.boolean({\n default: false,\n description: 'Output tokens in JSON format',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(TokensListCommand)\n const {json} = flags\n const outputJson = json ?? false\n\n // Ensure we have project context\n const projectId = await this.getProjectId()\n\n let tokens: Token[]\n try {\n tokens = await getTokens(projectId)\n } catch (error) {\n const message = getErrorMessage(error)\n listTokenDebug(`Error fetching tokens for project ${projectId}`, error)\n this.error(`Token list retrieval failed:\\n${message}`, {exit: 1})\n }\n\n if (outputJson) {\n this.log(JSON.stringify(tokens, null, 2))\n return\n }\n\n if (tokens.length === 0) {\n this.log('No API tokens found for this project.')\n return\n }\n\n const table = new Table({\n columns: [\n {alignment: 'left', maxLen: 40, name: 'label', title: 'Label'},\n {alignment: 'left', maxLen: 20, name: 'id', title: 'Token ID'},\n {alignment: 'left', maxLen: 30, name: 'roles', title: 'Roles'},\n ],\n title: `Found ${tokens.length} API tokens`,\n })\n\n for (const token of tokens) {\n const roles = token.roles?.map((role) => role.title).join(', ') || 'No roles'\n const truncatedLabel =\n token.label.length > 37 ? `${token.label.slice(0, 37)}...` : token.label\n const truncatedRoles = roles.length > 27 ? `${roles.slice(0, 27)}...` : roles\n\n table.addRow({\n id: token.id,\n label: truncatedLabel,\n roles: truncatedRoles,\n })\n }\n\n table.printTable()\n }\n}\n"],"names":["Flags","SanityCommand","subdebug","Table","getTokens","getErrorMessage","listTokenDebug","TokensListCommand","description","examples","command","flags","json","boolean","default","run","parse","outputJson","projectId","getProjectId","tokens","error","message","exit","log","JSON","stringify","length","table","columns","alignment","maxLen","name","title","token","roles","map","role","join","truncatedLabel","label","slice","truncatedRoles","addRow","id","printTable"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AACjC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,KAAK,QAAO,wBAAuB;AAG3C,SAAQC,SAAS,QAAO,2BAA0B;AAClD,SAAQC,eAAe,QAAO,gCAA+B;AAE7D,MAAMC,iBAAiBJ,SAAS;AAEhC,OAAO,MAAMK,0BAA0BN;IACrC,OAAgBO,cAAc,0CAAyC;IACvE,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IACD,OAAgBG,QAAQ;QACtBC,MAAMZ,MAAMa,OAAO,CAAC;YAClBC,SAAS;YACTN,aAAa;QACf;IACF,EAAC;IAED,MAAaO,MAAqB;QAChC,MAAM,EAACJ,KAAK,EAAC,GAAG,MAAM,IAAI,CAACK,KAAK,CAACT;QACjC,MAAM,EAACK,IAAI,EAAC,GAAGD;QACf,MAAMM,aAAaL,QAAQ;QAE3B,iCAAiC;QACjC,MAAMM,YAAY,MAAM,IAAI,CAACC,YAAY;QAEzC,IAAIC;QACJ,IAAI;YACFA,SAAS,MAAMhB,UAAUc;QAC3B,EAAE,OAAOG,OAAO;YACd,MAAMC,UAAUjB,gBAAgBgB;YAChCf,eAAe,CAAC,kCAAkC,EAAEY,WAAW,EAAEG;YACjE,IAAI,CAACA,KAAK,CAAC,CAAC,8BAA8B,EAAEC,SAAS,EAAE;gBAACC,MAAM;YAAC;QACjE;QAEA,IAAIN,YAAY;YACd,IAAI,CAACO,GAAG,CAACC,KAAKC,SAAS,CAACN,QAAQ,MAAM;YACtC;QACF;QAEA,IAAIA,OAAOO,MAAM,KAAK,GAAG;YACvB,IAAI,CAACH,GAAG,CAAC;YACT;QACF;QAEA,MAAMI,QAAQ,IAAIzB,MAAM;YACtB0B,SAAS;gBACP;oBAACC,WAAW;oBAAQC,QAAQ;oBAAIC,MAAM;oBAASC,OAAO;gBAAO;gBAC7D;oBAACH,WAAW;oBAAQC,QAAQ;oBAAIC,MAAM;oBAAMC,OAAO;gBAAU;gBAC7D;oBAACH,WAAW;oBAAQC,QAAQ;oBAAIC,MAAM;oBAASC,OAAO;gBAAO;aAC9D;YACDA,OAAO,CAAC,MAAM,EAAEb,OAAOO,MAAM,CAAC,WAAW,CAAC;QAC5C;QAEA,KAAK,MAAMO,SAASd,OAAQ;YAC1B,MAAMe,QAAQD,MAAMC,KAAK,EAAEC,IAAI,CAACC,OAASA,KAAKJ,KAAK,EAAEK,KAAK,SAAS;YACnE,MAAMC,iBACJL,MAAMM,KAAK,CAACb,MAAM,GAAG,KAAK,GAAGO,MAAMM,KAAK,CAACC,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,GAAGP,MAAMM,KAAK;YAC1E,MAAME,iBAAiBP,MAAMR,MAAM,GAAG,KAAK,GAAGQ,MAAMM,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,GAAGN;YAExEP,MAAMe,MAAM,CAAC;gBACXC,IAAIV,MAAMU,EAAE;gBACZJ,OAAOD;gBACPJ,OAAOO;YACT;QACF;QAEAd,MAAMiB,UAAU;IAClB;AACF"}
|
|
@@ -3,7 +3,6 @@ import { SanityCommand, subdebug } from '@sanity/cli-core';
|
|
|
3
3
|
import { input, select } from '@sanity/cli-core/ux';
|
|
4
4
|
import { validateEmail } from '../../actions/users/validateEmail.js';
|
|
5
5
|
import { getProjectRoles, inviteUser } from '../../services/projects.js';
|
|
6
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
7
6
|
const QUOTA_ERROR_MESSAGE = 'Project is already at user quota, add billing details to the project in order to allow overage charges.';
|
|
8
7
|
const usersInviteDebug = subdebug('users:invite');
|
|
9
8
|
export class UsersInviteCommand extends SanityCommand {
|
|
@@ -38,11 +37,6 @@ export class UsersInviteCommand extends SanityCommand {
|
|
|
38
37
|
const { email: selectedEmail } = this.args;
|
|
39
38
|
const { role: selectedRole } = this.flags;
|
|
40
39
|
const projectId = await this.getProjectId();
|
|
41
|
-
if (!projectId) {
|
|
42
|
-
this.error(NO_PROJECT_ID, {
|
|
43
|
-
exit: 1
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
40
|
let roles;
|
|
47
41
|
try {
|
|
48
42
|
roles = (await getProjectRoles(projectId)).filter((role)=>role.appliesToUsers);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/users/invite.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input, select} from '@sanity/cli-core/ux'\n\nimport {type Role} from '../../actions/users/types.js'\nimport {validateEmail} from '../../actions/users/validateEmail.js'\nimport {getProjectRoles, inviteUser} from '../../services/projects.js'\
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/users/invite.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {SanityCommand, subdebug} from '@sanity/cli-core'\nimport {input, select} from '@sanity/cli-core/ux'\n\nimport {type Role} from '../../actions/users/types.js'\nimport {validateEmail} from '../../actions/users/validateEmail.js'\nimport {getProjectRoles, inviteUser} from '../../services/projects.js'\n\nconst QUOTA_ERROR_MESSAGE =\n 'Project is already at user quota, add billing details to the project in order to allow overage charges.'\n\nconst usersInviteDebug = subdebug('users:invite')\n\nexport class UsersInviteCommand extends SanityCommand<typeof UsersInviteCommand> {\n static override args = {\n email: Args.string({\n description: 'Email address to invite',\n required: false,\n }),\n }\n\n static override description = 'Invite a new user to the project'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Invite a new user to the project (prompt for details)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> pippi@sanity.io',\n description: 'Send a new user invite to the email \"pippi@sanity.io\", prompt for role',\n },\n {\n command: '<%= config.bin %> <%= command.id %> pippi@sanity.io --role administrator',\n description: 'Send a new user invite to the email \"pippi@sanity.io\", as administrator',\n },\n ]\n\n static override flags = {\n role: Flags.string({\n description: 'Role to invite the user as',\n required: false,\n }),\n }\n\n public async run(): Promise<void> {\n const {email: selectedEmail} = this.args\n const {role: selectedRole} = this.flags\n\n const projectId = await this.getProjectId()\n\n\n let roles: Role[]\n try {\n roles = (await getProjectRoles(projectId)).filter((role) => role.appliesToUsers)\n } catch (error) {\n usersInviteDebug('Error fetching roles', error)\n this.error('Error fetching roles', {exit: 1})\n }\n\n const email = selectedEmail || (await this.promptForEmail())\n const roleSelection = selectedRole || (await this.promptForRole(roles))\n const role = roles.find(({name}) => name.toLowerCase() === roleSelection.toLowerCase())\n\n if (!role) {\n this.error(\n `Role name \"${roleSelection}\" not found. Available roles: ${roles.map((r) => r.name).join(', ')}`,\n {exit: 1},\n )\n }\n\n try {\n await inviteUser({email, projectId, role: role.name})\n\n this.log(`Invitation sent to ${email}`)\n } catch (error) {\n usersInviteDebug(`Error inviting user`, error)\n if ((error as Error & {statusCode: number}).statusCode === 402) {\n this.error(QUOTA_ERROR_MESSAGE, {exit: 1})\n }\n\n this.error(`Error inviting user`, {exit: 1})\n }\n }\n\n private async promptForEmail(): Promise<string> {\n return input({\n message: 'Email to invite:',\n transformer: (val: string) => val.trim(),\n validate: validateEmail,\n })\n }\n\n private async promptForRole(roles: Role[]): Promise<string> {\n return select({\n choices: roles.map((role) => ({\n name: `${role.title} (${role.description || 'No description'})`,\n value: role.name,\n })),\n message: 'Which role should the user have?',\n })\n }\n}\n"],"names":["Args","Flags","SanityCommand","subdebug","input","select","validateEmail","getProjectRoles","inviteUser","QUOTA_ERROR_MESSAGE","usersInviteDebug","UsersInviteCommand","args","email","string","description","required","examples","command","flags","role","run","selectedEmail","selectedRole","projectId","getProjectId","roles","filter","appliesToUsers","error","exit","promptForEmail","roleSelection","promptForRole","find","name","toLowerCase","map","r","join","log","statusCode","message","transformer","val","trim","validate","choices","title","value"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACxD,SAAQC,KAAK,EAAEC,MAAM,QAAO,sBAAqB;AAGjD,SAAQC,aAAa,QAAO,uCAAsC;AAClE,SAAQC,eAAe,EAAEC,UAAU,QAAO,6BAA4B;AAEtE,MAAMC,sBACJ;AAEF,MAAMC,mBAAmBP,SAAS;AAElC,OAAO,MAAMQ,2BAA2BT;IACtC,OAAgBU,OAAO;QACrBC,OAAOb,KAAKc,MAAM,CAAC;YACjBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,mCAAkC;IAEhE,OAAgBE,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtBC,MAAMnB,MAAMa,MAAM,CAAC;YACjBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,MAAaK,MAAqB;QAChC,MAAM,EAACR,OAAOS,aAAa,EAAC,GAAG,IAAI,CAACV,IAAI;QACxC,MAAM,EAACQ,MAAMG,YAAY,EAAC,GAAG,IAAI,CAACJ,KAAK;QAEvC,MAAMK,YAAY,MAAM,IAAI,CAACC,YAAY;QAGzC,IAAIC;QACJ,IAAI;YACFA,QAAQ,AAAC,CAAA,MAAMnB,gBAAgBiB,UAAS,EAAGG,MAAM,CAAC,CAACP,OAASA,KAAKQ,cAAc;QACjF,EAAE,OAAOC,OAAO;YACdnB,iBAAiB,wBAAwBmB;YACzC,IAAI,CAACA,KAAK,CAAC,wBAAwB;gBAACC,MAAM;YAAC;QAC7C;QAEA,MAAMjB,QAAQS,iBAAkB,MAAM,IAAI,CAACS,cAAc;QACzD,MAAMC,gBAAgBT,gBAAiB,MAAM,IAAI,CAACU,aAAa,CAACP;QAChE,MAAMN,OAAOM,MAAMQ,IAAI,CAAC,CAAC,EAACC,IAAI,EAAC,GAAKA,KAAKC,WAAW,OAAOJ,cAAcI,WAAW;QAEpF,IAAI,CAAChB,MAAM;YACT,IAAI,CAACS,KAAK,CACR,CAAC,WAAW,EAAEG,cAAc,8BAA8B,EAAEN,MAAMW,GAAG,CAAC,CAACC,IAAMA,EAAEH,IAAI,EAAEI,IAAI,CAAC,OAAO,EACjG;gBAACT,MAAM;YAAC;QAEZ;QAEA,IAAI;YACF,MAAMtB,WAAW;gBAACK;gBAAOW;gBAAWJ,MAAMA,KAAKe,IAAI;YAAA;YAEnD,IAAI,CAACK,GAAG,CAAC,CAAC,mBAAmB,EAAE3B,OAAO;QACxC,EAAE,OAAOgB,OAAO;YACdnB,iBAAiB,CAAC,mBAAmB,CAAC,EAAEmB;YACxC,IAAI,AAACA,MAAuCY,UAAU,KAAK,KAAK;gBAC9D,IAAI,CAACZ,KAAK,CAACpB,qBAAqB;oBAACqB,MAAM;gBAAC;YAC1C;YAEA,IAAI,CAACD,KAAK,CAAC,CAAC,mBAAmB,CAAC,EAAE;gBAACC,MAAM;YAAC;QAC5C;IACF;IAEA,MAAcC,iBAAkC;QAC9C,OAAO3B,MAAM;YACXsC,SAAS;YACTC,aAAa,CAACC,MAAgBA,IAAIC,IAAI;YACtCC,UAAUxC;QACZ;IACF;IAEA,MAAc2B,cAAcP,KAAa,EAAmB;QAC1D,OAAOrB,OAAO;YACZ0C,SAASrB,MAAMW,GAAG,CAAC,CAACjB,OAAU,CAAA;oBAC5Be,MAAM,GAAGf,KAAK4B,KAAK,CAAC,EAAE,EAAE5B,KAAKL,WAAW,IAAI,iBAAiB,CAAC,CAAC;oBAC/DkC,OAAO7B,KAAKe,IAAI;gBAClB,CAAA;YACAO,SAAS;QACX;IACF;AACF"}
|
|
@@ -2,9 +2,8 @@ import { styleText } from 'node:util';
|
|
|
2
2
|
import { Flags } from '@oclif/core';
|
|
3
3
|
import { SanityCommand } from '@sanity/cli-core';
|
|
4
4
|
import { Table } from 'console-table-printer';
|
|
5
|
-
import
|
|
5
|
+
import sortBy from 'lodash-es/sortBy.js';
|
|
6
6
|
import { getMembersForProject } from '../../actions/users/getMembersForProject.js';
|
|
7
|
-
import { NO_PROJECT_ID } from '../../util/errorMessages.js';
|
|
8
7
|
const sortFields = [
|
|
9
8
|
'id',
|
|
10
9
|
'name',
|
|
@@ -63,11 +62,6 @@ export class List extends SanityCommand {
|
|
|
63
62
|
async run() {
|
|
64
63
|
const { invitations, order, robots, sort } = this.flags;
|
|
65
64
|
const projectId = await this.getProjectId();
|
|
66
|
-
if (!projectId) {
|
|
67
|
-
this.error(NO_PROJECT_ID, {
|
|
68
|
-
exit: 1
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
65
|
const members = await getMembersForProject({
|
|
72
66
|
includeInvitations: invitations,
|
|
73
67
|
includeRobots: robots,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/users/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport {Table} from 'console-table-printer'\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/users/list.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Flags} from '@oclif/core'\nimport {SanityCommand} from '@sanity/cli-core'\nimport {Table} from 'console-table-printer'\nimport sortBy from 'lodash-es/sortBy.js'\n\nimport {getMembersForProject} from '../../actions/users/getMembersForProject.js'\n\nconst sortFields = ['id', 'name', 'role', 'date']\n\nfunction dimText(value: string, isDim: boolean): string {\n return isDim ? styleText('dim', value) : value\n}\n\nexport class List extends SanityCommand<typeof List> {\n static override description = 'List all users of the project'\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'List all users of the project',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-invitations --no-robots',\n description: 'List all users of the project, but exclude pending invitations and robots',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --sort role',\n description: 'List all users, sorted by role',\n },\n ]\n static override flags = {\n invitations: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Includes or excludes pending invitations',\n }),\n order: Flags.string({\n default: 'asc',\n description: 'Sort output ascending/descending',\n options: ['asc', 'desc'],\n }),\n robots: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Includes or excludes robots (token users)',\n }),\n sort: Flags.string({\n default: 'date',\n description: 'Sort users by specified column',\n options: ['id', 'name', 'role', 'date'],\n }),\n }\n\n public async run(): Promise<void> {\n const {invitations, order, robots, sort} = this.flags\n\n const projectId = await this.getProjectId()\n\n\n const members = await getMembersForProject({\n includeInvitations: invitations,\n includeRobots: robots,\n projectId,\n })\n\n const ordered = sortBy(\n members.map(({date, id, name, roles}) => [\n id,\n name,\n roles\n ?.map((role) => role.title)\n .join(', ')\n .trim() || '-',\n date,\n ]),\n [sortFields.indexOf(sort)],\n )\n\n const rows = order === 'asc' ? ordered : ordered.toReversed()\n\n const table = new Table({\n columns: [\n {alignment: 'left', maxLen: 30, name: 'id', title: 'ID'},\n {alignment: 'left', maxLen: 40, name: 'name', title: 'Name'},\n {alignment: 'left', maxLen: 30, name: 'roles', title: 'Roles'},\n {alignment: 'left', maxLen: 12, name: 'date', title: 'Date'},\n ],\n rowSeparator: true,\n })\n\n for (const [id, name, roles, date] of rows) {\n const isPending = id === '<pending>'\n table.addRow({\n date: dimText(date, isPending),\n id: dimText(id, isPending),\n name: dimText(name, isPending),\n roles: dimText(roles, isPending),\n })\n }\n\n table.printTable()\n }\n}\n"],"names":["styleText","Flags","SanityCommand","Table","sortBy","getMembersForProject","sortFields","dimText","value","isDim","List","description","examples","command","flags","invitations","boolean","allowNo","default","order","string","options","robots","sort","run","projectId","getProjectId","members","includeInvitations","includeRobots","ordered","map","date","id","name","roles","role","title","join","trim","indexOf","rows","toReversed","table","columns","alignment","maxLen","rowSeparator","isPending","addRow","printTable"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,KAAK,QAAO,cAAa;AACjC,SAAQC,aAAa,QAAO,mBAAkB;AAC9C,SAAQC,KAAK,QAAO,wBAAuB;AAC3C,OAAOC,YAAY,sBAAqB;AAExC,SAAQC,oBAAoB,QAAO,8CAA6C;AAEhF,MAAMC,aAAa;IAAC;IAAM;IAAQ;IAAQ;CAAO;AAEjD,SAASC,QAAQC,KAAa,EAAEC,KAAc;IAC5C,OAAOA,QAAQT,UAAU,OAAOQ,SAASA;AAC3C;AAEA,OAAO,MAAME,aAAaR;IACxB,OAAgBS,cAAc,gCAA+B;IAC7D,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;QACA;YACEE,SAAS;YACTF,aAAa;QACf;KACD,CAAA;IACD,OAAgBG,QAAQ;QACtBC,aAAad,MAAMe,OAAO,CAAC;YACzBC,SAAS;YACTC,SAAS;YACTP,aAAa;QACf;QACAQ,OAAOlB,MAAMmB,MAAM,CAAC;YAClBF,SAAS;YACTP,aAAa;YACbU,SAAS;gBAAC;gBAAO;aAAO;QAC1B;QACAC,QAAQrB,MAAMe,OAAO,CAAC;YACpBC,SAAS;YACTC,SAAS;YACTP,aAAa;QACf;QACAY,MAAMtB,MAAMmB,MAAM,CAAC;YACjBF,SAAS;YACTP,aAAa;YACbU,SAAS;gBAAC;gBAAM;gBAAQ;gBAAQ;aAAO;QACzC;IACF,EAAC;IAED,MAAaG,MAAqB;QAChC,MAAM,EAACT,WAAW,EAAEI,KAAK,EAAEG,MAAM,EAAEC,IAAI,EAAC,GAAG,IAAI,CAACT,KAAK;QAErD,MAAMW,YAAY,MAAM,IAAI,CAACC,YAAY;QAGzC,MAAMC,UAAU,MAAMtB,qBAAqB;YACzCuB,oBAAoBb;YACpBc,eAAeP;YACfG;QACF;QAEA,MAAMK,UAAU1B,OACduB,QAAQI,GAAG,CAAC,CAAC,EAACC,IAAI,EAAEC,EAAE,EAAEC,IAAI,EAAEC,KAAK,EAAC,GAAK;gBACvCF;gBACAC;gBACAC,OACIJ,IAAI,CAACK,OAASA,KAAKC,KAAK,EACzBC,KAAK,MACLC,UAAU;gBACbP;aACD,GACD;YAAC1B,WAAWkC,OAAO,CAACjB;SAAM;QAG5B,MAAMkB,OAAOtB,UAAU,QAAQW,UAAUA,QAAQY,UAAU;QAE3D,MAAMC,QAAQ,IAAIxC,MAAM;YACtByC,SAAS;gBACP;oBAACC,WAAW;oBAAQC,QAAQ;oBAAIZ,MAAM;oBAAMG,OAAO;gBAAI;gBACvD;oBAACQ,WAAW;oBAAQC,QAAQ;oBAAIZ,MAAM;oBAAQG,OAAO;gBAAM;gBAC3D;oBAACQ,WAAW;oBAAQC,QAAQ;oBAAIZ,MAAM;oBAASG,OAAO;gBAAO;gBAC7D;oBAACQ,WAAW;oBAAQC,QAAQ;oBAAIZ,MAAM;oBAAQG,OAAO;gBAAM;aAC5D;YACDU,cAAc;QAChB;QAEA,KAAK,MAAM,CAACd,IAAIC,MAAMC,OAAOH,KAAK,IAAIS,KAAM;YAC1C,MAAMO,YAAYf,OAAO;YACzBU,MAAMM,MAAM,CAAC;gBACXjB,MAAMzB,QAAQyB,MAAMgB;gBACpBf,IAAI1B,QAAQ0B,IAAIe;gBAChBd,MAAM3B,QAAQ2B,MAAMc;gBACpBb,OAAO5B,QAAQ4B,OAAOa;YACxB;QACF;QAEAL,MAAMO,UAAU;IAClB;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { SanityCommand } from '@sanity/cli-core';
|
|
3
|
-
import
|
|
3
|
+
import padStart from 'lodash-es/padStart.js';
|
|
4
4
|
import { findSanityModulesVersions } from '../actions/versions/findSanityModulesVersions.js';
|
|
5
5
|
import { getDisplayName, getFormatters } from '../actions/versions/getFormatters.js';
|
|
6
6
|
import { versionsDebug } from '../actions/versions/versionsDebug.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/versions.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {SanityCommand} from '@sanity/cli-core'\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/commands/versions.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {SanityCommand} from '@sanity/cli-core'\nimport padStart from 'lodash-es/padStart.js'\n\nimport {findSanityModulesVersions} from '../actions/versions/findSanityModulesVersions.js'\nimport {getDisplayName, getFormatters} from '../actions/versions/getFormatters.js'\nimport {versionsDebug} from '../actions/versions/versionsDebug.js'\n\nexport class Versions extends SanityCommand<typeof Versions> {\n static override description = 'Shows installed versions of Sanity Studio and components'\n static override examples = ['<%= config.bin %> <%= command.id %>']\n\n public async run(): Promise<void> {\n const root = (await this.getProjectRoot()).directory\n\n const versions = await findSanityModulesVersions({cwd: root})\n\n versionsDebug('resolved versions:', versions)\n\n const {formatName, versionLength} = getFormatters(versions)\n for (const mod of versions) {\n const version = padStart(mod.installed || '<missing>', versionLength)\n const latest =\n mod.installed === mod.latest\n ? styleText('green', '(up to date)')\n : `(latest: ${styleText('yellow', mod.latest)})`\n\n this.log(`${formatName(getDisplayName(mod))} ${version} ${latest}`)\n }\n }\n}\n"],"names":["styleText","SanityCommand","padStart","findSanityModulesVersions","getDisplayName","getFormatters","versionsDebug","Versions","description","examples","run","root","getProjectRoot","directory","versions","cwd","formatName","versionLength","mod","version","installed","latest","log"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,aAAa,QAAO,mBAAkB;AAC9C,OAAOC,cAAc,wBAAuB;AAE5C,SAAQC,yBAAyB,QAAO,mDAAkD;AAC1F,SAAQC,cAAc,EAAEC,aAAa,QAAO,uCAAsC;AAClF,SAAQC,aAAa,QAAO,uCAAsC;AAElE,OAAO,MAAMC,iBAAiBN;IAC5B,OAAgBO,cAAc,2DAA0D;IACxF,OAAgBC,WAAW;QAAC;KAAsC,CAAA;IAElE,MAAaC,MAAqB;QAChC,MAAMC,OAAO,AAAC,CAAA,MAAM,IAAI,CAACC,cAAc,EAAC,EAAGC,SAAS;QAEpD,MAAMC,WAAW,MAAMX,0BAA0B;YAACY,KAAKJ;QAAI;QAE3DL,cAAc,sBAAsBQ;QAEpC,MAAM,EAACE,UAAU,EAAEC,aAAa,EAAC,GAAGZ,cAAcS;QAClD,KAAK,MAAMI,OAAOJ,SAAU;YAC1B,MAAMK,UAAUjB,SAASgB,IAAIE,SAAS,IAAI,aAAaH;YACvD,MAAMI,SACJH,IAAIE,SAAS,KAAKF,IAAIG,MAAM,GACxBrB,UAAU,SAAS,kBACnB,CAAC,SAAS,EAAEA,UAAU,UAAUkB,IAAIG,MAAM,EAAE,CAAC,CAAC;YAEpD,IAAI,CAACC,GAAG,CAAC,GAAGN,WAAWZ,eAAec,MAAM,CAAC,EAAEC,QAAQ,CAAC,EAAEE,QAAQ;QACpE;IACF;AACF"}
|
package/dist/exports/index.d.ts
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
import {CliConfig} from '@sanity/cli-core'
|
|
2
2
|
import {ClientConfig} from '@sanity/client'
|
|
3
3
|
import {loadEnv} from 'vite'
|
|
4
|
-
import {PackageJson} from '@sanity/cli-core'
|
|
5
4
|
import {SanityClient} from '@sanity/client'
|
|
5
|
+
import {UserViteConfig} from '@sanity/cli-core'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export declare interface CliApiConfig {
|
|
11
|
+
dataset?: string
|
|
12
|
+
projectId?: string
|
|
13
|
+
}
|
|
6
14
|
|
|
7
15
|
declare type CliClientGetter = ((options?: CliClientOptions) => SanityClient) & {
|
|
8
16
|
/**
|
|
@@ -44,8 +52,60 @@ export declare function defineCliConfig(config: CliConfig): CliConfig
|
|
|
44
52
|
*/
|
|
45
53
|
export declare const getCliClient: CliClientGetter
|
|
46
54
|
|
|
55
|
+
/**
|
|
56
|
+
* @public
|
|
57
|
+
*/
|
|
58
|
+
export declare interface GraphQLAPIConfig {
|
|
59
|
+
/**
|
|
60
|
+
* Suffix to use for generated filter types.
|
|
61
|
+
*
|
|
62
|
+
* Optional, Defaults to `Filter`.
|
|
63
|
+
*
|
|
64
|
+
*/
|
|
65
|
+
filterSuffix?: string
|
|
66
|
+
/**
|
|
67
|
+
* Generation of API to deploy
|
|
68
|
+
*
|
|
69
|
+
* Optional, defaults to `gen3` (which is the only option, currently)
|
|
70
|
+
*/
|
|
71
|
+
generation?: 'gen1' | 'gen2' | 'gen3'
|
|
72
|
+
/**
|
|
73
|
+
* ID of GraphQL API. Only (currently) required when using the `--api` flag
|
|
74
|
+
* for `sanity graphql deploy`, in order to only deploy a specific API.
|
|
75
|
+
*/
|
|
76
|
+
id?: string
|
|
77
|
+
/**
|
|
78
|
+
* Whether or not to enable the GraphQL v2021-10-21 query semantics
|
|
79
|
+
*/
|
|
80
|
+
nonNullDocumentFields?: boolean
|
|
81
|
+
/**
|
|
82
|
+
* Whether or not to enable the GraphQL Playground for this API
|
|
83
|
+
*
|
|
84
|
+
* Optional, defaults to `true` in development mode, `false` otherwise
|
|
85
|
+
*/
|
|
86
|
+
playground?: boolean
|
|
87
|
+
/**
|
|
88
|
+
* Name of source containing the schema to deploy, within the configured workspace
|
|
89
|
+
*
|
|
90
|
+
* Optional, defaults to `default` (eg the one used if no `name` is defined)
|
|
91
|
+
*/
|
|
92
|
+
source?: string
|
|
93
|
+
/**
|
|
94
|
+
* API tag for this API - allows deploying multiple different APIs to a single dataset
|
|
95
|
+
*
|
|
96
|
+
* Optional, defaults to `default`
|
|
97
|
+
*/
|
|
98
|
+
tag?: string
|
|
99
|
+
/**
|
|
100
|
+
* Name of workspace containing the schema to deploy
|
|
101
|
+
*
|
|
102
|
+
* Optional, defaults to `default` (eg the one used if no `name` is defined)
|
|
103
|
+
*/
|
|
104
|
+
workspace?: string
|
|
105
|
+
}
|
|
106
|
+
|
|
47
107
|
export {loadEnv}
|
|
48
108
|
|
|
49
|
-
export {
|
|
109
|
+
export {UserViteConfig}
|
|
50
110
|
|
|
51
111
|
export {}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/index.ts"],"sourcesContent":["export {createCliConfig} from '../config/createCliConfig.js'\nexport {defineCliConfig} from '../config/defineCliConfig.js'\nexport type {
|
|
1
|
+
{"version":3,"sources":["../../src/exports/index.ts"],"sourcesContent":["export type {GraphQLAPIConfig} from '../actions/graphql/types.js'\nexport {createCliConfig} from '../config/createCliConfig.js'\nexport {defineCliConfig} from '../config/defineCliConfig.js'\nexport type {CliApiConfig} from '../types.js'\nexport {type CliClientOptions, getCliClient} from '../util/cliClient.js'\nexport {loadEnv} from '../util/loadEnv.js'\nexport type {CliConfig, UserViteConfig} from '@sanity/cli-core'\n"],"names":["createCliConfig","defineCliConfig","getCliClient","loadEnv"],"mappings":"AACA,SAAQA,eAAe,QAAO,+BAA8B;AAC5D,SAAQC,eAAe,QAAO,+BAA8B;AAE5D,SAA+BC,YAAY,QAAO,uBAAsB;AACxE,SAAQC,OAAO,QAAO,qBAAoB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { isInteractive, NonInteractiveError, subdebug } from '@sanity/cli-core';
|
|
2
|
+
import { select, Separator, spinner } from '@sanity/cli-core/ux';
|
|
3
|
+
import { getUserGrants } from '../services/grants.js';
|
|
4
|
+
import { listProjects } from '../services/projects.js';
|
|
5
|
+
import { getProjectsWithPermissions } from '../util/checkProjectPermissions.js';
|
|
6
|
+
const debug = subdebug('prompt:project');
|
|
7
|
+
/**
|
|
8
|
+
* Prompt the user to select a project from their available projects.
|
|
9
|
+
*
|
|
10
|
+
* When `requiredPermissions` is provided, projects are filtered by grants:
|
|
11
|
+
* only permitted projects are shown as selectable, with a single disabled
|
|
12
|
+
* summary item indicating how many projects were hidden due to insufficient permissions.
|
|
13
|
+
*/ export async function promptForProject(options = {}) {
|
|
14
|
+
if (!isInteractive()) {
|
|
15
|
+
throw new NonInteractiveError('select');
|
|
16
|
+
}
|
|
17
|
+
const { requiredPermissions } = options;
|
|
18
|
+
debug('Fetching projects and grants');
|
|
19
|
+
const spin = spinner('Fetching available projects').start();
|
|
20
|
+
const [projects, grants] = await Promise.all([
|
|
21
|
+
listProjects(),
|
|
22
|
+
requiredPermissions ? getUserGrants() : undefined
|
|
23
|
+
]).catch((error)=>{
|
|
24
|
+
spin.fail(requiredPermissions ? 'Failed to fetch projects or permissions' : 'Failed to fetch projects');
|
|
25
|
+
throw error;
|
|
26
|
+
});
|
|
27
|
+
if (projects.length === 0) {
|
|
28
|
+
spin.fail('No projects found');
|
|
29
|
+
throw new Error('No projects found. Create a project at https://www.sanity.io/manage');
|
|
30
|
+
}
|
|
31
|
+
spin.succeed();
|
|
32
|
+
const permittedIds = grants && requiredPermissions ? getProjectsWithPermissions(grants, requiredPermissions) : undefined;
|
|
33
|
+
const sorted = projects.toSorted((a, b)=>b.createdAt.localeCompare(a.createdAt));
|
|
34
|
+
const choices = [];
|
|
35
|
+
let insufficientCount = 0;
|
|
36
|
+
for (const project of sorted){
|
|
37
|
+
const label = `${project.displayName} (${project.id})`;
|
|
38
|
+
if (permittedIds && !permittedIds.has(project.id)) {
|
|
39
|
+
insufficientCount++;
|
|
40
|
+
} else {
|
|
41
|
+
choices.push({
|
|
42
|
+
name: label,
|
|
43
|
+
value: project.id
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (insufficientCount > 0) {
|
|
48
|
+
if (choices.length === 0) {
|
|
49
|
+
throw new Error('None of your projects have sufficient permissions for this operation');
|
|
50
|
+
}
|
|
51
|
+
const suffix = insufficientCount === 1 ? 'project' : 'projects';
|
|
52
|
+
choices.push(new Separator(), {
|
|
53
|
+
disabled: '(insufficient permissions)',
|
|
54
|
+
name: `${insufficientCount} other ${suffix} hidden`,
|
|
55
|
+
value: ''
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
return select({
|
|
59
|
+
choices,
|
|
60
|
+
message: 'Select project'
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=promptForProject.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/prompts/promptForProject.ts"],"sourcesContent":["import {isInteractive, NonInteractiveError, subdebug} from '@sanity/cli-core'\nimport {select, Separator, spinner} from '@sanity/cli-core/ux'\n\nimport {getUserGrants} from '../services/grants.js'\nimport {listProjects} from '../services/projects.js'\nimport {type RequiredPermission} from '../types/grants.js'\nimport {getProjectsWithPermissions} from '../util/checkProjectPermissions.js'\n\nconst debug = subdebug('prompt:project')\n\ninterface PromptForProjectOptions {\n requiredPermissions?: RequiredPermission[]\n}\n\n/**\n * Prompt the user to select a project from their available projects.\n *\n * When `requiredPermissions` is provided, projects are filtered by grants:\n * only permitted projects are shown as selectable, with a single disabled\n * summary item indicating how many projects were hidden due to insufficient permissions.\n */\nexport async function promptForProject(options: PromptForProjectOptions = {}): Promise<string> {\n if (!isInteractive()) {\n throw new NonInteractiveError('select')\n }\n\n const {requiredPermissions} = options\n\n debug('Fetching projects and grants')\n const spin = spinner('Fetching available projects').start()\n\n const [projects, grants] = await Promise.all([\n listProjects(),\n requiredPermissions ? getUserGrants() : undefined,\n ]).catch((error) => {\n spin.fail(requiredPermissions ? 'Failed to fetch projects or permissions' : 'Failed to fetch projects')\n throw error\n })\n\n if (projects.length === 0) {\n spin.fail('No projects found')\n throw new Error('No projects found. Create a project at https://www.sanity.io/manage')\n }\n\n spin.succeed()\n\n const permittedIds =\n grants && requiredPermissions\n ? getProjectsWithPermissions(grants, requiredPermissions)\n : undefined\n\n const sorted = projects.toSorted((a, b) => b.createdAt.localeCompare(a.createdAt))\n\n const choices: Array<\n Separator | {disabled?: string; name: string; value: string}\n > = []\n let insufficientCount = 0\n\n for (const project of sorted) {\n const label = `${project.displayName} (${project.id})`\n if (permittedIds && !permittedIds.has(project.id)) {\n insufficientCount++\n } else {\n choices.push({name: label, value: project.id})\n }\n }\n\n if (insufficientCount > 0) {\n if (choices.length === 0) {\n throw new Error(\n 'None of your projects have sufficient permissions for this operation',\n )\n }\n\n const suffix = insufficientCount === 1 ? 'project' : 'projects'\n choices.push(\n new Separator(),\n {\n disabled: '(insufficient permissions)',\n name: `${insufficientCount} other ${suffix} hidden`,\n value: '',\n },\n )\n }\n\n return select({\n choices,\n message: 'Select project',\n })\n}\n"],"names":["isInteractive","NonInteractiveError","subdebug","select","Separator","spinner","getUserGrants","listProjects","getProjectsWithPermissions","debug","promptForProject","options","requiredPermissions","spin","start","projects","grants","Promise","all","undefined","catch","error","fail","length","Error","succeed","permittedIds","sorted","toSorted","a","b","createdAt","localeCompare","choices","insufficientCount","project","label","displayName","id","has","push","name","value","suffix","disabled","message"],"mappings":"AAAA,SAAQA,aAAa,EAAEC,mBAAmB,EAAEC,QAAQ,QAAO,mBAAkB;AAC7E,SAAQC,MAAM,EAAEC,SAAS,EAAEC,OAAO,QAAO,sBAAqB;AAE9D,SAAQC,aAAa,QAAO,wBAAuB;AACnD,SAAQC,YAAY,QAAO,0BAAyB;AAEpD,SAAQC,0BAA0B,QAAO,qCAAoC;AAE7E,MAAMC,QAAQP,SAAS;AAMvB;;;;;;CAMC,GACD,OAAO,eAAeQ,iBAAiBC,UAAmC,CAAC,CAAC;IAC1E,IAAI,CAACX,iBAAiB;QACpB,MAAM,IAAIC,oBAAoB;IAChC;IAEA,MAAM,EAACW,mBAAmB,EAAC,GAAGD;IAE9BF,MAAM;IACN,MAAMI,OAAOR,QAAQ,+BAA+BS,KAAK;IAEzD,MAAM,CAACC,UAAUC,OAAO,GAAG,MAAMC,QAAQC,GAAG,CAAC;QAC3CX;QACAK,sBAAsBN,kBAAkBa;KACzC,EAAEC,KAAK,CAAC,CAACC;QACRR,KAAKS,IAAI,CAACV,sBAAsB,4CAA4C;QAC5E,MAAMS;IACR;IAEA,IAAIN,SAASQ,MAAM,KAAK,GAAG;QACzBV,KAAKS,IAAI,CAAC;QACV,MAAM,IAAIE,MAAM;IAClB;IAEAX,KAAKY,OAAO;IAEZ,MAAMC,eACJV,UAAUJ,sBACNJ,2BAA2BQ,QAAQJ,uBACnCO;IAEN,MAAMQ,SAASZ,SAASa,QAAQ,CAAC,CAACC,GAAGC,IAAMA,EAAEC,SAAS,CAACC,aAAa,CAACH,EAAEE,SAAS;IAEhF,MAAME,UAEF,EAAE;IACN,IAAIC,oBAAoB;IAExB,KAAK,MAAMC,WAAWR,OAAQ;QAC5B,MAAMS,QAAQ,GAAGD,QAAQE,WAAW,CAAC,EAAE,EAAEF,QAAQG,EAAE,CAAC,CAAC,CAAC;QACtD,IAAIZ,gBAAgB,CAACA,aAAaa,GAAG,CAACJ,QAAQG,EAAE,GAAG;YACjDJ;QACF,OAAO;YACLD,QAAQO,IAAI,CAAC;gBAACC,MAAML;gBAAOM,OAAOP,QAAQG,EAAE;YAAA;QAC9C;IACF;IAEA,IAAIJ,oBAAoB,GAAG;QACzB,IAAID,QAAQV,MAAM,KAAK,GAAG;YACxB,MAAM,IAAIC,MACR;QAEJ;QAEA,MAAMmB,SAAST,sBAAsB,IAAI,YAAY;QACrDD,QAAQO,IAAI,CACV,IAAIpC,aACJ;YACEwC,UAAU;YACVH,MAAM,GAAGP,kBAAkB,OAAO,EAAES,OAAO,OAAO,CAAC;YACnDD,OAAO;QACT;IAEJ;IAEA,OAAOvC,OAAO;QACZ8B;QACAY,SAAS;IACX;AACF"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { subdebug } from '@sanity/cli-core';
|
|
2
2
|
import { select, Separator, spinner } from '@sanity/cli-core/ux';
|
|
3
|
-
import
|
|
3
|
+
import groupBy from 'lodash-es/groupBy.js';
|
|
4
4
|
import { getMediaLibraries } from '../services/mediaLibraries.js';
|
|
5
5
|
const debug = subdebug('media:determine-target-library');
|
|
6
6
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/prompts/selectMediaLibrary.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\nimport {select, Separator, spinner} from '@sanity/cli-core/ux'\nimport
|
|
1
|
+
{"version":3,"sources":["../../src/prompts/selectMediaLibrary.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\nimport {select, Separator, spinner} from '@sanity/cli-core/ux'\nimport groupBy from 'lodash-es/groupBy.js'\n\nimport {getMediaLibraries} from '../services/mediaLibraries.js'\n\nconst debug = subdebug('media:determine-target-library')\n\n/**\n * Fetch a list of available media libraries and present them to the user in a list prompt. The items\n * in the list prompt are grouped by organization id.\n */\nexport async function selectMediaLibrary(projectId: string): Promise<string> {\n debug('Fetching available media libraries')\n const spin = spinner('Fetching available media libraries').start()\n\n try {\n const activeLibraries = await getMediaLibraries(projectId)\n\n const byOrg = groupBy(activeLibraries, 'organizationId')\n\n spin.succeed()\n\n // Create flat choices array with separators\n const choices: Array<Separator | {name: string; value: string}> = []\n for (const [orgId, libs] of Object.entries(byOrg)) {\n choices.push(\n new Separator(`Organization: ${orgId}`),\n ...libs.map((lib) => ({name: lib.id, value: lib.id})),\n )\n }\n\n return select({\n choices,\n message: 'Select media library',\n })\n } catch (error) {\n spin.fail('Failed to fetch media libraries')\n throw error\n }\n}\n"],"names":["subdebug","select","Separator","spinner","groupBy","getMediaLibraries","debug","selectMediaLibrary","projectId","spin","start","activeLibraries","byOrg","succeed","choices","orgId","libs","Object","entries","push","map","lib","name","id","value","message","error","fail"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,MAAM,EAAEC,SAAS,EAAEC,OAAO,QAAO,sBAAqB;AAC9D,OAAOC,aAAa,uBAAsB;AAE1C,SAAQC,iBAAiB,QAAO,gCAA+B;AAE/D,MAAMC,QAAQN,SAAS;AAEvB;;;CAGC,GACD,OAAO,eAAeO,mBAAmBC,SAAiB;IACxDF,MAAM;IACN,MAAMG,OAAON,QAAQ,sCAAsCO,KAAK;IAEhE,IAAI;QACF,MAAMC,kBAAkB,MAAMN,kBAAkBG;QAEhD,MAAMI,QAAQR,QAAQO,iBAAiB;QAEvCF,KAAKI,OAAO;QAEZ,4CAA4C;QAC5C,MAAMC,UAA4D,EAAE;QACpE,KAAK,MAAM,CAACC,OAAOC,KAAK,IAAIC,OAAOC,OAAO,CAACN,OAAQ;YACjDE,QAAQK,IAAI,CACV,IAAIjB,UAAU,CAAC,cAAc,EAAEa,OAAO,MACnCC,KAAKI,GAAG,CAAC,CAACC,MAAS,CAAA;oBAACC,MAAMD,IAAIE,EAAE;oBAAEC,OAAOH,IAAIE,EAAE;gBAAA,CAAA;QAEtD;QAEA,OAAOtB,OAAO;YACZa;YACAW,SAAS;QACX;IACF,EAAE,OAAOC,OAAO;QACdjB,KAAKkB,IAAI,CAAC;QACV,MAAMD;IACR;AACF"}
|
package/dist/server/devServer.js
CHANGED
|
@@ -4,7 +4,7 @@ import { writeSanityRuntime } from '../actions/build/writeSanityRuntime.js';
|
|
|
4
4
|
import { serverDebug } from './serverDebug.js';
|
|
5
5
|
const debug = serverDebug.extend('dev');
|
|
6
6
|
export async function startDevServer(options) {
|
|
7
|
-
const { basePath, cwd, entry, httpHost, httpPort, isApp, reactCompiler, reactStrictMode, vite: extendViteConfig } = options;
|
|
7
|
+
const { basePath, cwd, entry, httpHost, httpPort, isApp, reactCompiler, reactStrictMode, schemaExtraction, typegen, vite: extendViteConfig } = options;
|
|
8
8
|
debug('Writing Sanity runtime files');
|
|
9
9
|
const watcher = await writeSanityRuntime({
|
|
10
10
|
basePath,
|
|
@@ -22,10 +22,12 @@ export async function startDevServer(options) {
|
|
|
22
22
|
isApp,
|
|
23
23
|
mode: 'development',
|
|
24
24
|
reactCompiler,
|
|
25
|
+
schemaExtraction,
|
|
25
26
|
server: {
|
|
26
27
|
host: httpHost,
|
|
27
28
|
port: httpPort
|
|
28
|
-
}
|
|
29
|
+
},
|
|
30
|
+
typegen
|
|
29
31
|
});
|
|
30
32
|
// Extend Vite configuration with user-provided config
|
|
31
33
|
if (extendViteConfig) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import {type UserViteConfig} from '@sanity/cli-core'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {extendViteConfigWithUserConfig, getViteConfig} from '../actions/build/getViteConfig.js'\nimport {writeSanityRuntime} from '../actions/build/writeSanityRuntime.js'\nimport {serverDebug} from './serverDebug.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: ReactCompilerConfig | undefined\n reactStrictMode: boolean\n\n staticPath: string\n\n entry?: string\n httpHost?: string\n isApp?: boolean\n projectName?: string\n vite?: UserViteConfig\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n basePath,\n cwd,\n entry,\n httpHost,\n httpPort,\n isApp,\n reactCompiler,\n reactStrictMode,\n vite: extendViteConfig,\n } = options\n\n debug('Writing Sanity runtime files')\n const watcher = await writeSanityRuntime({\n basePath,\n cwd,\n entry,\n isApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n let viteConfig: InlineConfig = await getViteConfig({\n basePath,\n cwd,\n isApp,\n mode: 'development',\n reactCompiler,\n server: {host: httpHost, port: httpPort},\n })\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["createServer","extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","serverDebug","debug","extend","startDevServer","options","basePath","cwd","entry","httpHost","httpPort","isApp","reactCompiler","reactStrictMode","vite","extendViteConfig","watcher","watch","mode","viteConfig","server","host","port","command","listen","close"],"mappings":"AAGA,SAAQA,YAAY,QAA8C,OAAM;AAExE,SAAQC,8BAA8B,EAAEC,aAAa,QAAO,oCAAmC;AAC/F,SAAQC,kBAAkB,QAAO,yCAAwC;AACzE,SAAQC,WAAW,QAAO,mBAAkB;AAE5C,MAAMC,QAAQD,YAAYE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"sources":["../../src/server/devServer.ts"],"sourcesContent":["import {CliConfig, type UserViteConfig} from '@sanity/cli-core'\nimport {type PluginOptions as ReactCompilerConfig} from 'babel-plugin-react-compiler'\nimport {type FSWatcher} from 'chokidar'\nimport {createServer, type InlineConfig, type ViteDevServer} from 'vite'\n\nimport {extendViteConfigWithUserConfig, getViteConfig} from '../actions/build/getViteConfig.js'\nimport {writeSanityRuntime} from '../actions/build/writeSanityRuntime.js'\nimport {serverDebug} from './serverDebug.js'\n\nconst debug = serverDebug.extend('dev')\n\nexport interface DevServerOptions {\n basePath: string\n cwd: string\n httpPort: number\n\n reactCompiler: ReactCompilerConfig | undefined\n reactStrictMode: boolean\n\n staticPath: string\n\n entry?: string\n httpHost?: string\n isApp?: boolean\n projectName?: string\n schemaExtraction?: CliConfig['schemaExtraction']\n typegen?: CliConfig['typegen']\n vite?: UserViteConfig\n}\n\ninterface DevServer {\n close(): Promise<void>\n server: ViteDevServer\n\n watcher?: FSWatcher\n}\n\nexport async function startDevServer(options: DevServerOptions): Promise<DevServer> {\n const {\n basePath,\n cwd,\n entry,\n httpHost,\n httpPort,\n isApp,\n reactCompiler,\n reactStrictMode,\n schemaExtraction,\n typegen,\n vite: extendViteConfig,\n } = options\n\n debug('Writing Sanity runtime files')\n const watcher = await writeSanityRuntime({\n basePath,\n cwd,\n entry,\n isApp,\n reactStrictMode,\n watch: true,\n })\n\n debug('Resolving vite config')\n const mode = 'development'\n\n let viteConfig: InlineConfig = await getViteConfig({\n basePath,\n cwd,\n isApp,\n mode: 'development',\n reactCompiler,\n schemaExtraction,\n server: {host: httpHost, port: httpPort},\n typegen,\n })\n\n // Extend Vite configuration with user-provided config\n if (extendViteConfig) {\n viteConfig = await extendViteConfigWithUserConfig(\n {command: 'serve', mode},\n viteConfig,\n extendViteConfig,\n )\n }\n\n debug('Creating vite server')\n const server = await createServer(viteConfig)\n\n debug('Listening on specified port')\n await server.listen()\n\n return {\n close: async () => {\n if (watcher) {\n await watcher.close()\n }\n await server.close()\n },\n server,\n watcher,\n }\n}\n"],"names":["createServer","extendViteConfigWithUserConfig","getViteConfig","writeSanityRuntime","serverDebug","debug","extend","startDevServer","options","basePath","cwd","entry","httpHost","httpPort","isApp","reactCompiler","reactStrictMode","schemaExtraction","typegen","vite","extendViteConfig","watcher","watch","mode","viteConfig","server","host","port","command","listen","close"],"mappings":"AAGA,SAAQA,YAAY,QAA8C,OAAM;AAExE,SAAQC,8BAA8B,EAAEC,aAAa,QAAO,oCAAmC;AAC/F,SAAQC,kBAAkB,QAAO,yCAAwC;AACzE,SAAQC,WAAW,QAAO,mBAAkB;AAE5C,MAAMC,QAAQD,YAAYE,MAAM,CAAC;AA4BjC,OAAO,eAAeC,eAAeC,OAAyB;IAC5D,MAAM,EACJC,QAAQ,EACRC,GAAG,EACHC,KAAK,EACLC,QAAQ,EACRC,QAAQ,EACRC,KAAK,EACLC,aAAa,EACbC,eAAe,EACfC,gBAAgB,EAChBC,OAAO,EACPC,MAAMC,gBAAgB,EACvB,GAAGZ;IAEJH,MAAM;IACN,MAAMgB,UAAU,MAAMlB,mBAAmB;QACvCM;QACAC;QACAC;QACAG;QACAE;QACAM,OAAO;IACT;IAEAjB,MAAM;IACN,MAAMkB,OAAO;IAEb,IAAIC,aAA2B,MAAMtB,cAAc;QACjDO;QACAC;QACAI;QACAS,MAAM;QACNR;QACAE;QACAQ,QAAQ;YAACC,MAAMd;YAAUe,MAAMd;QAAQ;QACvCK;IACF;IAEA,sDAAsD;IACtD,IAAIE,kBAAkB;QACpBI,aAAa,MAAMvB,+BACjB;YAAC2B,SAAS;YAASL;QAAI,GACvBC,YACAJ;IAEJ;IAEAf,MAAM;IACN,MAAMoB,SAAS,MAAMzB,aAAawB;IAElCnB,MAAM;IACN,MAAMoB,OAAOI,MAAM;IAEnB,OAAO;QACLC,OAAO;YACL,IAAIT,SAAS;gBACX,MAAMA,QAAQS,KAAK;YACrB;YACA,MAAML,OAAOK,KAAK;QACpB;QACAL;QACAJ;IACF;AACF"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import path, { isAbsolute } from 'node:path';
|
|
2
|
+
import { logSymbols } from '@sanity/cli-core/ux';
|
|
3
|
+
import debounce from 'lodash-es/debounce.js';
|
|
4
|
+
import mean from 'lodash-es/mean.js';
|
|
5
|
+
import once from 'lodash-es/once.js';
|
|
6
|
+
import { formatSchemaValidation } from '../../actions/schema/formatSchemaValidation.js';
|
|
7
|
+
import { createSchemaPatternMatcher } from '../../actions/schema/matchSchemaPattern.js';
|
|
8
|
+
import { runSchemaExtraction } from '../../actions/schema/runSchemaExtraction.js';
|
|
9
|
+
import { SchemaExtractionError } from '../../actions/schema/utils/SchemaExtractionError.js';
|
|
10
|
+
import { SchemaExtractedTrace, SchemaExtractionWatchModeTrace } from '../../telemetry/extractSchema.telemetry.js';
|
|
11
|
+
/**
|
|
12
|
+
* Default glob patterns to watch for schema changes.
|
|
13
|
+
* Covers the sanity config file and common schema directory naming conventions.
|
|
14
|
+
*/ const DEFAULT_SCHEMA_PATTERNS = [
|
|
15
|
+
'sanity.config.{js,jsx,ts,tsx,mjs}',
|
|
16
|
+
'schema*/**/*.{js,jsx,ts,tsx,mjs}'
|
|
17
|
+
];
|
|
18
|
+
/** Default debounce delay in milliseconds */ const DEFAULT_DEBOUNCE_MS = 1000;
|
|
19
|
+
/**
|
|
20
|
+
* Delay before initial extraction to allow Vite to finish startup
|
|
21
|
+
* and avoid race conditions with module resolution.
|
|
22
|
+
*/ const INITIAL_EXTRACTION_DELAY_MS = 1000;
|
|
23
|
+
/**
|
|
24
|
+
* Creates a Vite plugin that automatically extracts Sanity schema during development and build.
|
|
25
|
+
*
|
|
26
|
+
* **During development:**
|
|
27
|
+
* The plugin performs an initial extraction when the dev server starts, then watches
|
|
28
|
+
* for file changes and re-extracts the schema when relevant files are modified.
|
|
29
|
+
*
|
|
30
|
+
* **During build:**
|
|
31
|
+
* The plugin extracts the schema once at the end of the build process, ensuring
|
|
32
|
+
* the schema is always up-to-date when deploying.
|
|
33
|
+
*
|
|
34
|
+
* **How it works in dev mode:**
|
|
35
|
+
* 1. Registers watch patterns with Vite's built-in file watcher
|
|
36
|
+
* 2. Performs initial schema extraction when the server starts
|
|
37
|
+
* 3. On file changes matching the patterns, triggers a debounced extraction
|
|
38
|
+
* 4. Uses concurrency control to prevent overlapping extractions
|
|
39
|
+
*
|
|
40
|
+
* @param options - Configuration options for the plugin
|
|
41
|
+
* @returns A Vite plugin configured for schema extraction
|
|
42
|
+
*
|
|
43
|
+
* @internal
|
|
44
|
+
*/ export function sanitySchemaExtractionPlugin(options) {
|
|
45
|
+
const { additionalPatterns = [], configPath, debounceMs = DEFAULT_DEBOUNCE_MS, enforceRequiredFields = false, format = 'groq-type-nodes', output = console, outputPath: outputPathOption = 'schema.json', telemetryLogger, workDir: workDirOption, workspaceName } = options;
|
|
46
|
+
const watchPatterns = [
|
|
47
|
+
...DEFAULT_SCHEMA_PATTERNS,
|
|
48
|
+
...additionalPatterns
|
|
49
|
+
];
|
|
50
|
+
// Resolved after Vite config is available
|
|
51
|
+
let resolvedWorkDir;
|
|
52
|
+
let resolvedOutputPath;
|
|
53
|
+
// State for concurrency control
|
|
54
|
+
let isExtracting = false;
|
|
55
|
+
let pendingExtraction = false;
|
|
56
|
+
// Stats for telemetry
|
|
57
|
+
const startTime = Date.now();
|
|
58
|
+
const stats = {
|
|
59
|
+
failedCount: 0,
|
|
60
|
+
successfulDurations: []
|
|
61
|
+
};
|
|
62
|
+
const extractSchema = ()=>runSchemaExtraction({
|
|
63
|
+
configPath,
|
|
64
|
+
enforceRequiredFields,
|
|
65
|
+
format,
|
|
66
|
+
outputPath: resolvedOutputPath,
|
|
67
|
+
workspace: workspaceName
|
|
68
|
+
});
|
|
69
|
+
/**
|
|
70
|
+
* Runs extraction with concurrency control.
|
|
71
|
+
* If extraction is already running, queues one more extraction to run after completion.
|
|
72
|
+
*/ async function runExtraction(isBuilding = false) {
|
|
73
|
+
if (isExtracting) {
|
|
74
|
+
pendingExtraction = true;
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
isExtracting = true;
|
|
78
|
+
pendingExtraction = false;
|
|
79
|
+
const extractionStartTime = Date.now();
|
|
80
|
+
try {
|
|
81
|
+
await extractSchema();
|
|
82
|
+
if (isBuilding) {
|
|
83
|
+
// TODO: Remove when we have better control over progress reporting in build
|
|
84
|
+
output.log('');
|
|
85
|
+
}
|
|
86
|
+
output.log(logSymbols.success, `Extracted schema to ${outputPathOption}`);
|
|
87
|
+
// add stats for the successful extraction run to use later for telemetry
|
|
88
|
+
stats.successfulDurations.push(Date.now() - extractionStartTime);
|
|
89
|
+
} catch (err) {
|
|
90
|
+
output.error(logSymbols.error, `Extraction failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
91
|
+
if (err instanceof SchemaExtractionError && err.validation && err.validation.length > 0) {
|
|
92
|
+
output.error(logSymbols.error, formatSchemaValidation(err.validation));
|
|
93
|
+
}
|
|
94
|
+
// track the failed extraction
|
|
95
|
+
stats.failedCount++;
|
|
96
|
+
} finally{
|
|
97
|
+
isExtracting = false;
|
|
98
|
+
// If a change came in during extraction, run again
|
|
99
|
+
if (pendingExtraction) {
|
|
100
|
+
pendingExtraction = false;
|
|
101
|
+
await runExtraction();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const debouncedExtract = debounce(()=>{
|
|
106
|
+
void runExtraction();
|
|
107
|
+
}, debounceMs);
|
|
108
|
+
const { isMatch } = createSchemaPatternMatcher(watchPatterns);
|
|
109
|
+
const handleChange = (filePath)=>{
|
|
110
|
+
if (isMatch(filePath, resolvedWorkDir)) {
|
|
111
|
+
debouncedExtract();
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
return {
|
|
115
|
+
name: 'sanity/schema-extraction',
|
|
116
|
+
configResolved (config) {
|
|
117
|
+
// Resolve workDir from option or Vite's project root
|
|
118
|
+
resolvedWorkDir = workDirOption ?? config.root;
|
|
119
|
+
resolvedOutputPath = isAbsolute(outputPathOption) ? outputPathOption : path.join(resolvedWorkDir, outputPathOption);
|
|
120
|
+
},
|
|
121
|
+
configureServer (server) {
|
|
122
|
+
const trace = telemetryLogger?.trace(SchemaExtractionWatchModeTrace);
|
|
123
|
+
trace?.start();
|
|
124
|
+
trace?.log({
|
|
125
|
+
enforceRequiredFields,
|
|
126
|
+
schemaFormat: format,
|
|
127
|
+
step: 'started'
|
|
128
|
+
});
|
|
129
|
+
// Add schema patterns to Vite's watcher
|
|
130
|
+
const absolutePatterns = watchPatterns.map((pattern)=>path.join(resolvedWorkDir, pattern));
|
|
131
|
+
server.watcher.add(absolutePatterns);
|
|
132
|
+
// Prepare function to log "stopped" event to trace and complete the trace
|
|
133
|
+
const onClose = once(()=>{
|
|
134
|
+
// Cancel any pending debounced extractions
|
|
135
|
+
debouncedExtract.cancel();
|
|
136
|
+
// Log telemetry if available
|
|
137
|
+
if (trace) {
|
|
138
|
+
trace.log({
|
|
139
|
+
averageExtractionDuration: mean(stats.successfulDurations) || 0,
|
|
140
|
+
extractionFailedCount: stats.failedCount,
|
|
141
|
+
extractionSuccessfulCount: stats.successfulDurations.length,
|
|
142
|
+
step: 'stopped',
|
|
143
|
+
watcherDuration: Date.now() - startTime
|
|
144
|
+
});
|
|
145
|
+
trace.complete();
|
|
146
|
+
}
|
|
147
|
+
// Clean up process listeners (must always run, not just when trace exists)
|
|
148
|
+
process.off('SIGTERM', onClose);
|
|
149
|
+
process.off('SIGINT', onClose);
|
|
150
|
+
});
|
|
151
|
+
server.watcher.on('change', handleChange);
|
|
152
|
+
server.watcher.on('add', handleChange);
|
|
153
|
+
server.watcher.on('unlink', handleChange);
|
|
154
|
+
// call the watcherClosed method when watcher is closed or when process is stopped/killed
|
|
155
|
+
server.watcher.on('close', onClose);
|
|
156
|
+
process.on('SIGTERM', onClose);
|
|
157
|
+
process.on('SIGINT', onClose);
|
|
158
|
+
// Run initial extraction after server is ready
|
|
159
|
+
const startExtraction = ()=>{
|
|
160
|
+
setTimeout(()=>{
|
|
161
|
+
// Notify about schema extraction enabled
|
|
162
|
+
output.info(logSymbols.info, 'Schema extraction enabled. Watching:');
|
|
163
|
+
for (const pattern of watchPatterns){
|
|
164
|
+
output.info(` - ${pattern}`);
|
|
165
|
+
}
|
|
166
|
+
// Perform first extraction
|
|
167
|
+
void runExtraction();
|
|
168
|
+
}, INITIAL_EXTRACTION_DELAY_MS);
|
|
169
|
+
};
|
|
170
|
+
if (server.httpServer) {
|
|
171
|
+
server.httpServer.once('listening', startExtraction);
|
|
172
|
+
} else {
|
|
173
|
+
// Middleware mode - no HTTP server, run extraction immediately
|
|
174
|
+
startExtraction();
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
async buildEnd () {
|
|
178
|
+
const trace = telemetryLogger?.trace(SchemaExtractedTrace);
|
|
179
|
+
trace?.start();
|
|
180
|
+
try {
|
|
181
|
+
const start = Date.now();
|
|
182
|
+
const schema = await extractSchema();
|
|
183
|
+
output.log(logSymbols.success, `Extracted schema to ${outputPathOption} (${Date.now() - start}ms)`);
|
|
184
|
+
trace?.log({
|
|
185
|
+
enforceRequiredFields,
|
|
186
|
+
schemaAllTypesCount: schema.length,
|
|
187
|
+
schemaDocumentTypesCount: schema.filter((type)=>type.type === 'document').length,
|
|
188
|
+
schemaFormat: format,
|
|
189
|
+
schemaTypesCount: schema.filter((type)=>type.type === 'type').length
|
|
190
|
+
});
|
|
191
|
+
} catch (err) {
|
|
192
|
+
trace?.error(err);
|
|
193
|
+
throw err;
|
|
194
|
+
} finally{
|
|
195
|
+
trace?.complete();
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
//# sourceMappingURL=plugin-schema-extraction.js.map
|