@sanity/cli 8.3.0 → 8.4.2
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/dist/actions/build/buildApp.js +14 -7
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +3 -3
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +32 -25
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +2 -1
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +2 -4
- package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -1
- package/dist/actions/deploy/deploymentPlan.js.map +1 -1
- package/dist/actions/dev/devAction.js +6 -4
- package/dist/actions/dev/devAction.js.map +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js +13 -6
- package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/servers/startAppDevServer.js +4 -2
- package/dist/actions/dev/servers/startAppDevServer.js.map +1 -1
- package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -2
- package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +5 -2
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -1
- package/dist/actions/init/templates/shopify.js +2 -1
- package/dist/actions/init/templates/shopify.js.map +1 -1
- package/dist/actions/manifest/extractManifest.js +5 -37
- package/dist/actions/manifest/extractManifest.js.map +1 -1
- package/dist/actions/manifest/extractStudioManifest.js +1 -1
- package/dist/actions/manifest/extractStudioManifest.js.map +1 -1
- package/dist/actions/preview/previewAction.js +1 -1
- package/dist/actions/preview/previewAction.js.map +1 -1
- package/dist/actions/schema/deleteSchemaAction.js +1 -1
- package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
- package/dist/actions/schema/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js +1 -1
- package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +1 -1
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/schema/schemaTypeHelpers.js +5 -0
- package/dist/actions/schema/schemaTypeHelpers.js.map +1 -0
- package/dist/actions/schema/updateWorkspaceSchema.js +1 -1
- package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -1
- package/dist/actions/schema/utils/schemaStoreValidation.js +2 -2
- package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
- package/dist/actions/schema/utils/workspaceSchemaId.js +1 -1
- package/dist/actions/schema/utils/workspaceSchemaId.js.map +1 -1
- package/dist/actions/versions/getFormatters.js +1 -2
- package/dist/actions/versions/getFormatters.js.map +1 -1
- package/dist/commands/documents/create.js +4 -4
- package/dist/commands/documents/create.js.map +1 -1
- package/dist/commands/hooks/logs.js +1 -2
- package/dist/commands/hooks/logs.js.map +1 -1
- package/dist/commands/projects/list.js +3 -5
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/undeploy.js +7 -5
- package/dist/commands/undeploy.js.map +1 -1
- package/dist/commands/users/list.js +3 -5
- package/dist/commands/users/list.js.map +1 -1
- package/dist/commands/versions.js +1 -2
- package/dist/commands/versions.js.map +1 -1
- package/dist/exports/_internal.d.ts +1 -67
- package/dist/exports/_internal.js +1 -1
- package/dist/exports/_internal.js.map +1 -1
- package/dist/exports/index.d.ts +2 -2
- package/dist/exports/index.js +2 -1
- package/dist/exports/index.js.map +1 -1
- package/dist/exports/runtime.d.ts +2 -2
- package/dist/exports/runtime.js +1 -1
- package/dist/exports/runtime.js.map +1 -1
- package/dist/generated/apiRoutes.js +4 -0
- package/dist/generated/apiRoutes.js.map +1 -1
- package/dist/prompts/selectMediaLibrary.js +2 -3
- package/dist/prompts/selectMediaLibrary.js.map +1 -1
- package/dist/services/mintProject.js +27 -14
- package/dist/services/mintProject.js.map +1 -1
- package/dist/services/schemas.js.map +1 -1
- package/dist/services/userApplications.js.map +1 -1
- package/dist/util/determineIsApp.js +1 -1
- package/dist/util/determineIsApp.js.map +1 -1
- package/dist/util/sortRowsByColumn.js +23 -0
- package/dist/util/sortRowsByColumn.js.map +1 -0
- package/oclif.manifest.json +353 -353
- package/package.json +7 -10
- package/dist/actions/manifest/blockTypeTransformer.js +0 -67
- package/dist/actions/manifest/blockTypeTransformer.js.map +0 -1
- package/dist/actions/manifest/extractCoreAppManifest.js +0 -111
- package/dist/actions/manifest/extractCoreAppManifest.js.map +0 -1
- package/dist/actions/manifest/extractManifest.worker.js +0 -30
- package/dist/actions/manifest/extractManifest.worker.js.map +0 -1
- package/dist/actions/manifest/extractWorkspaceManifest.js +0 -72
- package/dist/actions/manifest/extractWorkspaceManifest.js.map +0 -1
- package/dist/actions/manifest/iconResolver.js +0 -36
- package/dist/actions/manifest/iconResolver.js.map +0 -1
- package/dist/actions/manifest/purifyConfig.js +0 -307
- package/dist/actions/manifest/purifyConfig.js.map +0 -1
- package/dist/actions/manifest/referenceTransformer.js +0 -51
- package/dist/actions/manifest/referenceTransformer.js.map +0 -1
- package/dist/actions/manifest/resolveSchemaIcon.js +0 -43
- package/dist/actions/manifest/resolveSchemaIcon.js.map +0 -1
- package/dist/actions/manifest/sanitizeIcon.js +0 -13
- package/dist/actions/manifest/sanitizeIcon.js.map +0 -1
- package/dist/actions/manifest/schemaTypeHelpers.js +0 -110
- package/dist/actions/manifest/schemaTypeHelpers.js.map +0 -1
- package/dist/actions/manifest/schemaTypeTransformer.js +0 -169
- package/dist/actions/manifest/schemaTypeTransformer.js.map +0 -1
- package/dist/actions/manifest/transformerUtils.js +0 -40
- package/dist/actions/manifest/transformerUtils.js.map +0 -1
- package/dist/actions/manifest/types.js +0 -13
- package/dist/actions/manifest/types.js.map +0 -1
- package/dist/actions/manifest/validationTransformer.js +0 -84
- package/dist/actions/manifest/validationTransformer.js.map +0 -1
- package/dist/actions/manifest/writeManifestFile.js +0 -29
- package/dist/actions/manifest/writeManifestFile.js.map +0 -1
- package/dist/actions/manifest/writeWorkspaceFiles.js +0 -30
- package/dist/actions/manifest/writeWorkspaceFiles.js.map +0 -1
- package/dist/actions/schema/uploadSchemaToLexicon.js +0 -91
- package/dist/actions/schema/uploadSchemaToLexicon.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/manifest/extractStudioManifest.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport {join, resolve} from 'node:path'\n\nimport {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/manifest/extractStudioManifest.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport {join, resolve} from 'node:path'\n\nimport {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {MANIFEST_FILENAME, type StudioManifest} from '@sanity/cli-build/_internal/manifest'\n\nimport {extractManifest} from './extractManifest.js'\n\n/**\n * Dev-time manifest output directory, relative to the studio working\n * directory. Sibling of Vite's `cacheDir` so it stays out of `dist` and is\n * ignored by default in typical `.gitignore` files.\n */\nconst MANIFEST_DIR = `${SANITY_CACHE_DIR}/manifest`\n\n/**\n * Run the worker-based studio schema extraction, write the resulting manifest\n * to `MANIFEST_DIR`, then read it back so the caller can inline it into the\n * registry.\n *\n * `configPath` must be the resolved `sanity.config.(ts|js)` path — passing it\n * in (e.g. from `findProjectRoot`) avoids re-traversing the filesystem on\n * every call.\n */\nexport async function extractStudioManifest(options: {\n configPath: string\n workDir: string\n}): Promise<StudioManifest | undefined> {\n const outPath = resolve(options.workDir, MANIFEST_DIR)\n await extractManifest({outPath, path: options.configPath, workDir: options.workDir})\n const raw = await readFile(join(outPath, MANIFEST_FILENAME), 'utf8')\n return JSON.parse(raw)\n}\n"],"names":["readFile","join","resolve","SANITY_CACHE_DIR","MANIFEST_FILENAME","extractManifest","MANIFEST_DIR","extractStudioManifest","options","outPath","workDir","path","configPath","raw","JSON","parse"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,IAAI,EAAEC,OAAO,QAAO,YAAW;AAEvC,SAAQC,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,iBAAiB,QAA4B,uCAAsC;AAE3F,SAAQC,eAAe,QAAO,uBAAsB;AAEpD;;;;CAIC,GACD,MAAMC,eAAe,GAAGH,iBAAiB,SAAS,CAAC;AAEnD;;;;;;;;CAQC,GACD,OAAO,eAAeI,sBAAsBC,OAG3C;IACC,MAAMC,UAAUP,QAAQM,QAAQE,OAAO,EAAEJ;IACzC,MAAMD,gBAAgB;QAACI;QAASE,MAAMH,QAAQI,UAAU;QAAEF,SAASF,QAAQE,OAAO;IAAA;IAClF,MAAMG,MAAM,MAAMb,SAASC,KAAKQ,SAASL,oBAAoB;IAC7D,OAAOU,KAAKC,KAAK,CAACF;AACpB"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { SANITY_CACHE_DIR } from '@sanity/cli-build/_internal/build';
|
|
2
|
+
import { extractCoreAppManifest } from '@sanity/cli-build/_internal/manifest';
|
|
2
3
|
import { isWorkbenchApp } from '@sanity/workbench-cli';
|
|
3
4
|
import { gracefulServerDeath } from '../../server/gracefulServerDeath.js';
|
|
4
5
|
import { startPreviewServer } from '../../server/previewServer.js';
|
|
5
6
|
import { checkForDeprecatedAppId } from '../../util/appId.js';
|
|
6
7
|
import { determineIsApp } from '../../util/determineIsApp.js';
|
|
7
8
|
import { resolveReactStrictMode } from '../../util/resolveReactStrictMode.js';
|
|
8
|
-
import { extractCoreAppManifest } from '../manifest/extractCoreAppManifest.js';
|
|
9
9
|
import { extractStudioManifest } from '../manifest/extractStudioManifest.js';
|
|
10
10
|
import { getPreviewServerConfig } from './getPreviewServerConfig.js';
|
|
11
11
|
export async function previewAction(options) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/preview/previewAction.ts"],"sourcesContent":["import {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {type CliConfig, type Output} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {gracefulServerDeath} from '../../server/gracefulServerDeath.js'\nimport {type PreviewServer, startPreviewServer} from '../../server/previewServer.js'\nimport {checkForDeprecatedAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {resolveReactStrictMode} from '../../util/resolveReactStrictMode.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/preview/previewAction.ts"],"sourcesContent":["import {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {extractCoreAppManifest} from '@sanity/cli-build/_internal/manifest'\nimport {type CliConfig, type Output} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {gracefulServerDeath} from '../../server/gracefulServerDeath.js'\nimport {type PreviewServer, startPreviewServer} from '../../server/previewServer.js'\nimport {checkForDeprecatedAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {resolveReactStrictMode} from '../../util/resolveReactStrictMode.js'\nimport {extractStudioManifest} from '../manifest/extractStudioManifest.js'\nimport {getPreviewServerConfig} from './getPreviewServerConfig.js'\nimport {type PreviewFlags} from './types.js'\n\ninterface PreviewActionOptions {\n cliConfig: CliConfig\n flags: PreviewFlags\n outDir: string\n output: Output\n workDir: string\n}\n\nexport async function previewAction(\n options: PreviewActionOptions,\n): Promise<PreviewServer | {close: () => Promise<void>}> {\n const {cliConfig, flags, outDir, output, workDir} = options\n\n const config = getPreviewServerConfig({cliConfig, flags, rootDir: outDir, workDir})\n\n if (isWorkbenchApp(cliConfig?.app)) {\n const isApp = determineIsApp(cliConfig)\n // Lazy so a non-workbench `sanity start` never loads the package. `doImport`\n // is path-based and doesn't apply to a bare specifier.\n // eslint-disable-next-line no-restricted-syntax\n const {startWorkbenchPreview} = await import('@sanity/workbench-cli/preview')\n return startWorkbenchPreview({\n cacheDir: `${SANITY_CACHE_DIR}/vite`,\n checkForDeprecatedAppId: () => checkForDeprecatedAppId({cliConfig, output}),\n cliConfig,\n extractManifest: isApp\n ? ({workDir: wd}) => extractCoreAppManifest({workDir: wd})\n : (params) => extractStudioManifest(params),\n httpHost: config.httpHost,\n httpPort: config.httpPort,\n isApp,\n outDir,\n output,\n reactStrictMode: resolveReactStrictMode(cliConfig) ?? false,\n workDir,\n })\n }\n\n try {\n const server = await startPreviewServer(config)\n return server\n } catch (err) {\n throw gracefulServerDeath('preview', config.httpHost, config.httpPort, err)\n }\n}\n"],"names":["SANITY_CACHE_DIR","extractCoreAppManifest","isWorkbenchApp","gracefulServerDeath","startPreviewServer","checkForDeprecatedAppId","determineIsApp","resolveReactStrictMode","extractStudioManifest","getPreviewServerConfig","previewAction","options","cliConfig","flags","outDir","output","workDir","config","rootDir","app","isApp","startWorkbenchPreview","cacheDir","extractManifest","wd","params","httpHost","httpPort","reactStrictMode","server","err"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,sBAAsB,QAAO,uCAAsC;AAE3E,SAAQC,cAAc,QAAO,wBAAuB;AAEpD,SAAQC,mBAAmB,QAAO,sCAAqC;AACvE,SAA4BC,kBAAkB,QAAO,gCAA+B;AACpF,SAAQC,uBAAuB,QAAO,sBAAqB;AAC3D,SAAQC,cAAc,QAAO,+BAA8B;AAC3D,SAAQC,sBAAsB,QAAO,uCAAsC;AAC3E,SAAQC,qBAAqB,QAAO,uCAAsC;AAC1E,SAAQC,sBAAsB,QAAO,8BAA6B;AAWlE,OAAO,eAAeC,cACpBC,OAA6B;IAE7B,MAAM,EAACC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGL;IAEpD,MAAMM,SAASR,uBAAuB;QAACG;QAAWC;QAAOK,SAASJ;QAAQE;IAAO;IAEjF,IAAId,eAAeU,WAAWO,MAAM;QAClC,MAAMC,QAAQd,eAAeM;QAC7B,6EAA6E;QAC7E,uDAAuD;QACvD,gDAAgD;QAChD,MAAM,EAACS,qBAAqB,EAAC,GAAG,MAAM,MAAM,CAAC;QAC7C,OAAOA,sBAAsB;YAC3BC,UAAU,GAAGtB,iBAAiB,KAAK,CAAC;YACpCK,yBAAyB,IAAMA,wBAAwB;oBAACO;oBAAWG;gBAAM;YACzEH;YACAW,iBAAiBH,QACb,CAAC,EAACJ,SAASQ,EAAE,EAAC,GAAKvB,uBAAuB;oBAACe,SAASQ;gBAAE,KACtD,CAACC,SAAWjB,sBAAsBiB;YACtCC,UAAUT,OAAOS,QAAQ;YACzBC,UAAUV,OAAOU,QAAQ;YACzBP;YACAN;YACAC;YACAa,iBAAiBrB,uBAAuBK,cAAc;YACtDI;QACF;IACF;IAEA,IAAI;QACF,MAAMa,SAAS,MAAMzB,mBAAmBa;QACxC,OAAOY;IACT,EAAE,OAAOC,KAAK;QACZ,MAAM3B,oBAAoB,WAAWc,OAAOS,QAAQ,EAAET,OAAOU,QAAQ,EAAEG;IACzE;AACF"}
|
|
@@ -2,7 +2,7 @@ import { styleText } from 'node:util';
|
|
|
2
2
|
import { CLIError } from '@oclif/core/errors';
|
|
3
3
|
import { studioWorkerTask } from '@sanity/cli-core';
|
|
4
4
|
import { deleteSchema } from '../../services/schemas.js';
|
|
5
|
-
import { isDefined } from '
|
|
5
|
+
import { isDefined } from './schemaTypeHelpers.js';
|
|
6
6
|
import { getDatasetsOutString, getStringList } from './utils/schemaStoreOutStrings.js';
|
|
7
7
|
// Native implementation instead of lodash/uniq
|
|
8
8
|
function uniq(array) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/deleteSchemaAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {CLIError} from '@oclif/core/errors'\nimport {type Output, studioWorkerTask} from '@sanity/cli-core'\nimport {type Workspace} from 'sanity'\n\nimport {deleteSchema} from '../../services/schemas.js'\nimport {isDefined} from '
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/deleteSchemaAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {CLIError} from '@oclif/core/errors'\nimport {type Output, studioWorkerTask} from '@sanity/cli-core'\nimport {type Workspace} from 'sanity'\n\nimport {deleteSchema} from '../../services/schemas.js'\nimport {isDefined} from './schemaTypeHelpers.js'\nimport {type UniqWorkspaceWorkerData} from './types.js'\nimport {getDatasetsOutString, getStringList} from './utils/schemaStoreOutStrings.js'\nimport {type WorkspaceSchemaId} from './utils/schemaStoreValidation.js'\n\n// Native implementation instead of lodash/uniq\nfunction uniq<T>(array: T[]): T[] {\n return [...new Set(array)]\n}\n\ninterface DeleteSchemasOptions {\n configPath: string\n ids: WorkspaceSchemaId[]\n output: Output\n projectId: string\n verbose: boolean\n workDir: string\n\n dataset?: string\n}\n\ninterface DeleteResult {\n dataset: string\n deleted: boolean\n schemaId: string\n}\n\nclass DeleteIdError extends Error {\n public dataset: string\n public id: string\n constructor(id: string, dataset: string, options?: ErrorOptions) {\n super((options?.cause as {message?: string})?.message, options)\n this.name = 'DeleteIdError'\n this.id = id\n this.dataset = dataset\n }\n}\n\nexport async function deleteSchemaAction(options: DeleteSchemasOptions): Promise<void> {\n const {configPath, dataset, ids, output, projectId, verbose, workDir} = options\n\n const projectDatasets = await studioWorkerTask<(Workspace & {key: string})[]>(\n new URL('uniqueWorkspaces.worker.js', import.meta.url),\n {\n name: 'uniqueWorkspaces',\n studioRootPath: workDir,\n workerData: {configPath, dataset} satisfies UniqWorkspaceWorkerData,\n },\n )\n\n const datasets = projectDatasets.map((w) => w.dataset)\n\n const results = await Promise.allSettled(\n datasets.flatMap((targetDataset: string) => {\n return ids.map(async ({schemaId}): Promise<DeleteResult> => {\n try {\n const deletedSchema = await deleteSchema(targetDataset, projectId, schemaId)\n return {dataset: targetDataset, deleted: deletedSchema.deleted, schemaId}\n } catch (err) {\n throw new DeleteIdError(schemaId, targetDataset, {cause: err})\n }\n })\n }),\n )\n\n const deletedIds = results\n .filter((r): r is PromiseFulfilledResult<DeleteResult> => r.status === 'fulfilled')\n .filter((r) => r.value.deleted)\n .map((r) => r.value)\n\n const notFound = uniq(\n results\n .filter((r): r is PromiseFulfilledResult<DeleteResult> => r.status === 'fulfilled')\n .filter((r) => !r.value.deleted)\n .filter((r) => !deletedIds.map(({schemaId}) => schemaId).includes(r.value.schemaId))\n .map((r) => r.value.schemaId),\n )\n\n const deleteFailureIds = uniq(\n results\n .filter((r) => r.status === 'rejected')\n .map((result) => {\n const error = result.reason\n if (error instanceof DeleteIdError) {\n output.warn(\n styleText(\n 'red',\n [\n `Failed to delete schema \"${error.id}\" in dataset \"${error.dataset}\":`,\n error.message,\n ].join('\\n'),\n ),\n )\n if (verbose) output.warn(error)\n return error.id\n }\n //hubris inc: given the try-catch wrapping the full promise \"this should never happen\"\n throw error\n }),\n )\n\n // Compare unique schema IDs deleted vs requested (not total deletions across datasets)\n const uniqueDeletedSchemaIds = uniq(deletedIds.map(({schemaId}) => schemaId))\n const success = uniqueDeletedSchemaIds.length === ids.length\n if (success) {\n output.log(`Successfully deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas`)\n } else {\n throw new CLIError(\n [\n `Deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas.`,\n deletedIds.length > 0\n ? `Successfully deleted ids:\\n${deletedIds\n .map(\n ({dataset: targetDataset, schemaId}) =>\n `- \"${schemaId}\" (in ${getDatasetsOutString([targetDataset])})`,\n )\n .join('\\n')}`\n : undefined,\n notFound.length > 0\n ? `Ids not found in ${getDatasetsOutString(datasets)}:\\n${getStringList(notFound)}`\n : undefined,\n ...(deleteFailureIds.length > 0\n ? [`Failed to delete ids:\\n${getStringList(deleteFailureIds)}`, 'Check logs for errors.']\n : []),\n ]\n .filter((item) => isDefined(item))\n .join('\\n'),\n )\n }\n}\n"],"names":["styleText","CLIError","studioWorkerTask","deleteSchema","isDefined","getDatasetsOutString","getStringList","uniq","array","Set","DeleteIdError","Error","dataset","id","options","cause","message","name","deleteSchemaAction","configPath","ids","output","projectId","verbose","workDir","projectDatasets","URL","url","studioRootPath","workerData","datasets","map","w","results","Promise","allSettled","flatMap","targetDataset","schemaId","deletedSchema","deleted","err","deletedIds","filter","r","status","value","notFound","includes","deleteFailureIds","result","error","reason","warn","join","uniqueDeletedSchemaIds","success","length","log","undefined","item"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/deploySchemas.ts"],"sourcesContent":["import {SchemaExtractionError} from '@sanity/cli-build/_internal/extract'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/deploySchemas.ts"],"sourcesContent":["import {SchemaExtractionError} from '@sanity/cli-build/_internal/extract'\nimport {type ManifestSchemaType} from '@sanity/cli-build/_internal/manifest'\nimport {studioWorkerTask} from '@sanity/cli-core'\nimport {type SchemaValidationProblemGroup} from '@sanity/types'\nimport {type Workspace} from 'sanity'\n\nimport {type ExtractWorkspaceWorkerData} from './types.js'\nimport {updateWorkspacesSchemas, type WorkspaceSchemaInput} from './updateWorkspaceSchema.js'\n\ninterface DeploySchemasOptions {\n verbose: boolean\n workDir: string\n\n tag?: string\n workspaceName?: string\n}\n\ntype WorkspaceWithManifest = Workspace & {manifestSchema: ManifestSchemaType[]}\n\ntype ExtractWorkspaceWorkerMessage =\n | {\n error: string\n type: 'error'\n validation?: SchemaValidationProblemGroup[]\n }\n | {\n type: 'success'\n workspaces: WorkspaceWithManifest[]\n }\n\nexport async function deploySchemas(options: DeploySchemasOptions): Promise<void> {\n const {tag, verbose, workDir, workspaceName} = options\n\n const result = await studioWorkerTask<ExtractWorkspaceWorkerMessage>(\n new URL('extractSanityWorkspace.worker.js', import.meta.url),\n {\n name: 'extractSanityWorkspace',\n studioRootPath: workDir,\n workerData: {\n configPath: workDir,\n workDir,\n } satisfies ExtractWorkspaceWorkerData,\n },\n )\n\n if (result.type === 'error') {\n throw new SchemaExtractionError(result.error, result.validation)\n }\n\n const workspaces: WorkspaceSchemaInput[] = result.workspaces\n .filter((workspace) => !workspaceName || workspace.name === workspaceName)\n .map((workspace) => ({\n dataset: workspace.dataset,\n manifestSchema: workspace.manifestSchema,\n name: workspace.name,\n projectId: workspace.projectId,\n title: workspace.title,\n }))\n\n if (workspaces.length === 0) {\n const error = workspaceName\n ? new Error(`Found no workspaces named \"${workspaceName}\"`)\n : new Error('No workspaces found')\n throw error\n }\n\n await updateWorkspacesSchemas({\n tag,\n verbose,\n workspaces,\n })\n}\n"],"names":["SchemaExtractionError","studioWorkerTask","updateWorkspacesSchemas","deploySchemas","options","tag","verbose","workDir","workspaceName","result","URL","url","name","studioRootPath","workerData","configPath","type","error","validation","workspaces","filter","workspace","map","dataset","manifestSchema","projectId","title","length","Error"],"mappings":"AAAA,SAAQA,qBAAqB,QAAO,sCAAqC;AAEzE,SAAQC,gBAAgB,QAAO,mBAAkB;AAKjD,SAAQC,uBAAuB,QAAkC,6BAA4B;AAuB7F,OAAO,eAAeC,cAAcC,OAA6B;IAC/D,MAAM,EAACC,GAAG,EAAEC,OAAO,EAAEC,OAAO,EAAEC,aAAa,EAAC,GAAGJ;IAE/C,MAAMK,SAAS,MAAMR,iBACnB,IAAIS,IAAI,oCAAoC,YAAYC,GAAG,GAC3D;QACEC,MAAM;QACNC,gBAAgBN;QAChBO,YAAY;YACVC,YAAYR;YACZA;QACF;IACF;IAGF,IAAIE,OAAOO,IAAI,KAAK,SAAS;QAC3B,MAAM,IAAIhB,sBAAsBS,OAAOQ,KAAK,EAAER,OAAOS,UAAU;IACjE;IAEA,MAAMC,aAAqCV,OAAOU,UAAU,CACzDC,MAAM,CAAC,CAACC,YAAc,CAACb,iBAAiBa,UAAUT,IAAI,KAAKJ,eAC3Dc,GAAG,CAAC,CAACD,YAAe,CAAA;YACnBE,SAASF,UAAUE,OAAO;YAC1BC,gBAAgBH,UAAUG,cAAc;YACxCZ,MAAMS,UAAUT,IAAI;YACpBa,WAAWJ,UAAUI,SAAS;YAC9BC,OAAOL,UAAUK,KAAK;QACxB,CAAA;IAEF,IAAIP,WAAWQ,MAAM,KAAK,GAAG;QAC3B,MAAMV,QAAQT,gBACV,IAAIoB,MAAM,CAAC,2BAA2B,EAAEpB,cAAc,CAAC,CAAC,IACxD,IAAIoB,MAAM;QACd,MAAMX;IACR;IAEA,MAAMf,wBAAwB;QAC5BG;QACAC;QACAa;IACF;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
2
2
|
import { extractValidationFromSchemaError } from '@sanity/cli-build/_internal/extract';
|
|
3
|
+
import { extractManifestSchemaTypes } from '@sanity/cli-build/_internal/manifest';
|
|
3
4
|
import { getStudioWorkspaces, safeStructuredClone } from '@sanity/cli-core';
|
|
4
|
-
import { extractManifestSchemaTypes } from '../manifest/extractWorkspaceManifest.js';
|
|
5
5
|
import { extractWorkspaceWorkerData } from './types.js';
|
|
6
6
|
if (isMainThread || !parentPort) {
|
|
7
7
|
throw new Error('Should only be run in a worker!');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/extractSanityWorkspace.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {extractValidationFromSchemaError} from '@sanity/cli-build/_internal/extract'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/extractSanityWorkspace.worker.ts"],"sourcesContent":["import {isMainThread, parentPort, workerData} from 'node:worker_threads'\n\nimport {extractValidationFromSchemaError} from '@sanity/cli-build/_internal/extract'\nimport {extractManifestSchemaTypes} from '@sanity/cli-build/_internal/manifest'\nimport {getStudioWorkspaces, safeStructuredClone} from '@sanity/cli-core'\nimport {type Schema} from '@sanity/types'\n\nimport {extractWorkspaceWorkerData} from './types.js'\n\nif (isMainThread || !parentPort) {\n throw new Error('Should only be run in a worker!')\n}\n\nconst {configPath, workDir} = extractWorkspaceWorkerData.parse(workerData)\n\ntry {\n const workspaces = await getStudioWorkspaces(configPath)\n\n // Extract manifest schemas while Schema objects are still live (before structured clone\n // strips class methods like getTypeNames/get). The API expects ManifestSchemaType[], not\n // the runtime Schema class instance.\n const workspacesWithManifest = await Promise.all(\n workspaces.map(async (workspace) => ({\n ...safeStructuredClone(workspace),\n manifestSchema: await extractManifestSchemaTypes(workspace.schema as Schema, workDir),\n })),\n )\n\n parentPort.postMessage({\n type: 'success',\n workspaces: workspacesWithManifest,\n })\n} catch (error) {\n const validation = await extractValidationFromSchemaError(error, workDir)\n parentPort.postMessage({\n error: error instanceof Error ? error.message : String(error),\n type: 'error',\n validation,\n })\n}\n"],"names":["isMainThread","parentPort","workerData","extractValidationFromSchemaError","extractManifestSchemaTypes","getStudioWorkspaces","safeStructuredClone","extractWorkspaceWorkerData","Error","configPath","workDir","parse","workspaces","workspacesWithManifest","Promise","all","map","workspace","manifestSchema","schema","postMessage","type","error","validation","message","String"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,UAAU,EAAEC,UAAU,QAAO,sBAAqB;AAExE,SAAQC,gCAAgC,QAAO,sCAAqC;AACpF,SAAQC,0BAA0B,QAAO,uCAAsC;AAC/E,SAAQC,mBAAmB,EAAEC,mBAAmB,QAAO,mBAAkB;AAGzE,SAAQC,0BAA0B,QAAO,aAAY;AAErD,IAAIP,gBAAgB,CAACC,YAAY;IAC/B,MAAM,IAAIO,MAAM;AAClB;AAEA,MAAM,EAACC,UAAU,EAAEC,OAAO,EAAC,GAAGH,2BAA2BI,KAAK,CAACT;AAE/D,IAAI;IACF,MAAMU,aAAa,MAAMP,oBAAoBI;IAE7C,wFAAwF;IACxF,yFAAyF;IACzF,qCAAqC;IACrC,MAAMI,yBAAyB,MAAMC,QAAQC,GAAG,CAC9CH,WAAWI,GAAG,CAAC,OAAOC,YAAe,CAAA;YACnC,GAAGX,oBAAoBW,UAAU;YACjCC,gBAAgB,MAAMd,2BAA2Ba,UAAUE,MAAM,EAAYT;QAC/E,CAAA;IAGFT,WAAWmB,WAAW,CAAC;QACrBC,MAAM;QACNT,YAAYC;IACd;AACF,EAAE,OAAOS,OAAO;IACd,MAAMC,aAAa,MAAMpB,iCAAiCmB,OAAOZ;IACjET,WAAWmB,WAAW,CAAC;QACrBE,OAAOA,iBAAiBd,QAAQc,MAAME,OAAO,GAAGC,OAAOH;QACvDD,MAAM;QACNE;IACF;AACF"}
|
|
@@ -3,7 +3,7 @@ import { studioWorkerTask } from '@sanity/cli-core';
|
|
|
3
3
|
import { logSymbols } from '@sanity/cli-core/ux';
|
|
4
4
|
import { getSchemas } from '../../services/schemas.js';
|
|
5
5
|
import { Table } from '../../util/responsiveTable.js';
|
|
6
|
-
import { isDefined } from '
|
|
6
|
+
import { isDefined } from './schemaTypeHelpers.js';
|
|
7
7
|
import { getDatasetsOutString } from './utils/schemaStoreOutStrings.js';
|
|
8
8
|
import { SCHEMA_PERMISSION_HELP_TEXT } from './utils/schemaStoreValidation.js';
|
|
9
9
|
class DatasetError extends Error {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/listSchemas.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type Output, studioWorkerTask} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {type Workspace} from 'sanity'\n\nimport {getSchemas} from '../../services/schemas.js'\nimport {Table} from '../../util/responsiveTable.js'\nimport {isDefined} from '
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/listSchemas.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type StoredWorkspaceSchema} from '@sanity/cli-build/_internal/manifest'\nimport {type Output, studioWorkerTask} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {type Workspace} from 'sanity'\n\nimport {getSchemas} from '../../services/schemas.js'\nimport {Table} from '../../util/responsiveTable.js'\nimport {isDefined} from './schemaTypeHelpers.js'\nimport {type UniqWorkspaceWorkerData} from './types.js'\nimport {getDatasetsOutString} from './utils/schemaStoreOutStrings.js'\nimport {SCHEMA_PERMISSION_HELP_TEXT} from './utils/schemaStoreValidation.js'\n\ninterface ListSchemasOptions {\n configPath: string\n json: boolean\n output: Output\n workDir: string\n\n id?: string\n}\n\nclass DatasetError extends Error {\n public dataset: string\n public projectId: string\n constructor(args: {dataset: string; options?: ErrorOptions; projectId: string}) {\n super((args.options?.cause as {message?: string})?.message, args.options)\n this.projectId = args.projectId\n this.dataset = args.dataset\n this.name = 'DatasetError'\n }\n}\n\nexport async function listSchemas(options: ListSchemasOptions): Promise<void> {\n const {configPath, id, json, output, workDir} = options\n\n const projectDatasets = await studioWorkerTask<(Workspace & {key: string})[]>(\n new URL('uniqueWorkspaces.worker.js', import.meta.url),\n {\n name: 'uniqueWorkspaces',\n studioRootPath: workDir,\n workerData: {configPath} satisfies UniqWorkspaceWorkerData,\n },\n )\n\n const schemas = await getDatasetSchemas(projectDatasets, id)\n const parsedSchemas = parseSchemas(schemas, output, json)\n\n if (parsedSchemas.length === 0) {\n const datasetString = getDatasetsOutString(projectDatasets.map((dataset) => dataset.dataset))\n\n throw new Error(\n id\n ? `Schema for id \"${id}\" not found in ${datasetString}`\n : `No schemas found in ${datasetString}`,\n )\n }\n\n if (json) {\n output.log(JSON.stringify(id ? parsedSchemas[0] : parsedSchemas, null, 2))\n } else {\n printSchemas({output, schemas: parsedSchemas, workspaces: projectDatasets})\n }\n}\n\nasync function getDatasetSchemas(projectDatasets: Workspace[], id?: string) {\n return Promise.allSettled(\n projectDatasets.map(async ({dataset, projectId}) => {\n try {\n return await getSchemas(dataset, projectId, id)\n } catch (error) {\n throw new DatasetError({dataset, options: {cause: error}, projectId})\n }\n }),\n )\n}\n\nfunction parseSchemas(\n schemas: PromiseSettledResult<StoredWorkspaceSchema[]>[],\n output: Output,\n json: boolean,\n) {\n return schemas\n .map((schema) => {\n if (schema.status === 'fulfilled') return schema.value\n\n const error = schema.reason\n\n if (error instanceof DatasetError) {\n if (\n 'cause' in error &&\n error.cause &&\n typeof error.cause === 'object' &&\n 'statusCode' in error.cause &&\n error.cause.statusCode === 401\n ) {\n const logDiagnostic = json ? output.warn.bind(output) : output.log.bind(output)\n logDiagnostic(\n styleText(\n 'yellow',\n `${logSymbols.warning} ↳ No permissions to read schema from \"${error.dataset}\". ${\n SCHEMA_PERMISSION_HELP_TEXT\n }:\\n ${styleText('red', `${error.message}`)}`,\n ),\n )\n return []\n }\n\n const logDiagnostic = json ? output.warn.bind(output) : output.log.bind(output)\n logDiagnostic(\n styleText('red', `↳ Failed to fetch schema from \"${error.dataset}\":\\n ${error.message}`),\n )\n return []\n } else {\n //hubris inc: given the try-catch wrapping all the full promise \"this should never happen\"\n throw error\n }\n })\n .filter((schema) => isDefined(schema))\n .flat()\n}\n\nfunction printSchemas({\n output,\n schemas,\n workspaces,\n}: {\n output: Output\n schemas: StoredWorkspaceSchema[]\n workspaces: Workspace[]\n}) {\n const rows = schemas\n .toSorted((a, b) => -(a._createdAt || '').localeCompare(b._createdAt || ''))\n .map(({_createdAt: createdAt, _id: id, workspace}) => {\n const workspaceData = workspaces.find((w) => w.name === workspace.name)\n if (!workspaceData) return\n\n return {\n CreatedAt: createdAt,\n Dataset: workspaceData.dataset,\n Id: id,\n ProjectId: workspaceData.projectId,\n Workspace: workspace.name,\n }\n })\n .filter((schema) => isDefined(schema))\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'Id'},\n {alignment: 'left', name: 'Workspace'},\n {alignment: 'left', name: 'Dataset'},\n {alignment: 'left', name: 'ProjectId'},\n {alignment: 'left', name: 'CreatedAt'},\n ],\n })\n\n table.addRows(rows)\n output.log(table.render())\n}\n"],"names":["styleText","studioWorkerTask","logSymbols","getSchemas","Table","isDefined","getDatasetsOutString","SCHEMA_PERMISSION_HELP_TEXT","DatasetError","Error","dataset","projectId","args","options","cause","message","name","listSchemas","configPath","id","json","output","workDir","projectDatasets","URL","url","studioRootPath","workerData","schemas","getDatasetSchemas","parsedSchemas","parseSchemas","length","datasetString","map","log","JSON","stringify","printSchemas","workspaces","Promise","allSettled","error","schema","status","value","reason","statusCode","logDiagnostic","warn","bind","warning","filter","flat","rows","toSorted","a","b","_createdAt","localeCompare","createdAt","_id","workspace","workspaceData","find","w","CreatedAt","Dataset","Id","ProjectId","Workspace","table","columns","alignment","addRows","render"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/schemaTypeHelpers.ts"],"sourcesContent":["export function isDefined<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined\n}\n"],"names":["isDefined","value","undefined"],"mappings":"AAAA,OAAO,SAASA,UAAaC,KAA2B;IACtD,OAAOA,UAAU,QAAQA,UAAUC;AACrC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { ux } from '@oclif/core/ux';
|
|
3
|
+
import { CURRENT_WORKSPACE_SCHEMA_VERSION } from '@sanity/cli-build/_internal/manifest';
|
|
3
4
|
import { spinner } from '@sanity/cli-core/ux';
|
|
4
5
|
import partition from 'lodash-es/partition.js';
|
|
5
6
|
import { updateSchemas } from '../../services/schemas.js';
|
|
6
|
-
import { CURRENT_WORKSPACE_SCHEMA_VERSION } from '../manifest/types.js';
|
|
7
7
|
import { SCHEMA_PERMISSION_HELP_TEXT } from './utils/schemaStoreValidation.js';
|
|
8
8
|
import { getWorkspaceSchemaId } from './utils/workspaceSchemaId.js';
|
|
9
9
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/updateWorkspaceSchema.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {ux} from '@oclif/core/ux'\nimport {spinner} from '@sanity/cli-core/ux'\nimport partition from 'lodash-es/partition.js'\n\nimport {updateSchemas} from '../../services/schemas.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/updateWorkspaceSchema.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {ux} from '@oclif/core/ux'\nimport {\n CURRENT_WORKSPACE_SCHEMA_VERSION,\n type ManifestSchemaType,\n type StoredWorkspaceSchema,\n} from '@sanity/cli-build/_internal/manifest'\nimport {spinner} from '@sanity/cli-core/ux'\nimport partition from 'lodash-es/partition.js'\n\nimport {updateSchemas} from '../../services/schemas.js'\nimport {SCHEMA_PERMISSION_HELP_TEXT} from './utils/schemaStoreValidation.js'\nimport {getWorkspaceSchemaId} from './utils/workspaceSchemaId.js'\n\n/**\n * Workspace metadata + pre-extracted manifest schema for deployment.\n * The schema must already be in ManifestSchemaType[] format (extracted from\n * the live Schema object before any structured clone boundary).\n */\nexport interface WorkspaceSchemaInput {\n dataset: string\n manifestSchema: ManifestSchemaType[]\n name: string\n projectId: string\n\n title?: string\n}\n\n/**\n * Updates the schemas for a list of workspaces.\n */\nexport async function updateWorkspacesSchemas(args: {\n tag?: string\n verbose: boolean\n workspaces: WorkspaceSchemaInput[]\n}) {\n const {tag, verbose, workspaces} = args\n\n /* Known caveat: we _don't_ rollback failed operations or partial success */\n const results = await Promise.allSettled(\n workspaces.map(async (workspace): Promise<void> => {\n await updateWorkspaceSchema({\n tag,\n verbose,\n workspace,\n })\n }),\n )\n\n const [fulfilledUpdates, rejectedUpdates] = partition(\n results,\n (result) => result.status === 'fulfilled',\n )\n\n if (rejectedUpdates.length > 0) {\n throw new Error(\n `Failed to deploy ${rejectedUpdates.length}/${workspaces.length} schemas. Successfully deployed ${fulfilledUpdates.length}/${workspaces.length} schemas.`,\n )\n }\n\n spinner(`Deployed ${fulfilledUpdates.length}/${workspaces.length} schemas`).succeed()\n}\n\n/**\n * Updates a workspace schema in the dataset.\n */\nasync function updateWorkspaceSchema(args: {\n tag?: string\n verbose: boolean\n workspace: WorkspaceSchemaInput\n}) {\n const {tag, verbose, workspace} = args\n\n const {dataset, manifestSchema, projectId} = workspace\n\n const {idWarning, safeBaseId: id} = getWorkspaceSchemaId({\n tag,\n workspaceName: workspace.name,\n })\n\n if (idWarning) ux.warn(idWarning)\n\n try {\n await updateSchemas<Omit<StoredWorkspaceSchema, '_id' | '_type'>[]>(dataset, projectId, [\n {\n // the API will stringify the schema – we send as JSON\n schema: manifestSchema,\n tag,\n version: CURRENT_WORKSPACE_SCHEMA_VERSION,\n workspace: {\n name: workspace.name,\n title: workspace.title,\n },\n },\n ])\n\n if (verbose) {\n ux.stdout(\n styleText('gray', `↳ schemaId: ${id}, projectId: ${projectId}, dataset: ${dataset}`),\n )\n }\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n if (\n err instanceof Error &&\n 'statusCode' in err &&\n (err as {statusCode: unknown}).statusCode === 401\n ) {\n ux.warn(\n `↳ No permissions to write schema for workspace \"${workspace.name}\" in dataset \"${workspace.dataset}\". ${\n SCHEMA_PERMISSION_HELP_TEXT\n }:\\n ${styleText('red', message)}`,\n )\n } else {\n ux.stdout(\n styleText(\n 'red',\n `↳ Error deploying schema for workspace \"${workspace.name}\":\\n ${styleText('red', message)}`,\n ),\n )\n }\n\n throw err\n }\n}\n"],"names":["styleText","ux","CURRENT_WORKSPACE_SCHEMA_VERSION","spinner","partition","updateSchemas","SCHEMA_PERMISSION_HELP_TEXT","getWorkspaceSchemaId","updateWorkspacesSchemas","args","tag","verbose","workspaces","results","Promise","allSettled","map","workspace","updateWorkspaceSchema","fulfilledUpdates","rejectedUpdates","result","status","length","Error","succeed","dataset","manifestSchema","projectId","idWarning","safeBaseId","id","workspaceName","name","warn","schema","version","title","stdout","err","message","String","statusCode"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,EAAE,QAAO,iBAAgB;AACjC,SACEC,gCAAgC,QAG3B,uCAAsC;AAC7C,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,OAAOC,eAAe,yBAAwB;AAE9C,SAAQC,aAAa,QAAO,4BAA2B;AACvD,SAAQC,2BAA2B,QAAO,mCAAkC;AAC5E,SAAQC,oBAAoB,QAAO,+BAA8B;AAgBjE;;CAEC,GACD,OAAO,eAAeC,wBAAwBC,IAI7C;IACC,MAAM,EAACC,GAAG,EAAEC,OAAO,EAAEC,UAAU,EAAC,GAAGH;IAEnC,0EAA0E,GAC1E,MAAMI,UAAU,MAAMC,QAAQC,UAAU,CACtCH,WAAWI,GAAG,CAAC,OAAOC;QACpB,MAAMC,sBAAsB;YAC1BR;YACAC;YACAM;QACF;IACF;IAGF,MAAM,CAACE,kBAAkBC,gBAAgB,GAAGhB,UAC1CS,SACA,CAACQ,SAAWA,OAAOC,MAAM,KAAK;IAGhC,IAAIF,gBAAgBG,MAAM,GAAG,GAAG;QAC9B,MAAM,IAAIC,MACR,CAAC,iBAAiB,EAAEJ,gBAAgBG,MAAM,CAAC,CAAC,EAAEX,WAAWW,MAAM,CAAC,gCAAgC,EAAEJ,iBAAiBI,MAAM,CAAC,CAAC,EAAEX,WAAWW,MAAM,CAAC,SAAS,CAAC;IAE7J;IAEApB,QAAQ,CAAC,SAAS,EAAEgB,iBAAiBI,MAAM,CAAC,CAAC,EAAEX,WAAWW,MAAM,CAAC,QAAQ,CAAC,EAAEE,OAAO;AACrF;AAEA;;CAEC,GACD,eAAeP,sBAAsBT,IAIpC;IACC,MAAM,EAACC,GAAG,EAAEC,OAAO,EAAEM,SAAS,EAAC,GAAGR;IAElC,MAAM,EAACiB,OAAO,EAAEC,cAAc,EAAEC,SAAS,EAAC,GAAGX;IAE7C,MAAM,EAACY,SAAS,EAAEC,YAAYC,EAAE,EAAC,GAAGxB,qBAAqB;QACvDG;QACAsB,eAAef,UAAUgB,IAAI;IAC/B;IAEA,IAAIJ,WAAW5B,GAAGiC,IAAI,CAACL;IAEvB,IAAI;QACF,MAAMxB,cAA8DqB,SAASE,WAAW;YACtF;gBACE,sDAAsD;gBACtDO,QAAQR;gBACRjB;gBACA0B,SAASlC;gBACTe,WAAW;oBACTgB,MAAMhB,UAAUgB,IAAI;oBACpBI,OAAOpB,UAAUoB,KAAK;gBACxB;YACF;SACD;QAED,IAAI1B,SAAS;YACXV,GAAGqC,MAAM,CACPtC,UAAU,QAAQ,CAAC,YAAY,EAAE+B,GAAG,aAAa,EAAEH,UAAU,WAAW,EAAEF,SAAS;QAEvF;IACF,EAAE,OAAOa,KAAK;QACZ,MAAMC,UAAUD,eAAef,QAAQe,IAAIC,OAAO,GAAGC,OAAOF;QAC5D,IACEA,eAAef,SACf,gBAAgBe,OAChB,AAACA,IAA8BG,UAAU,KAAK,KAC9C;YACAzC,GAAGiC,IAAI,CACL,CAAC,gDAAgD,EAAEjB,UAAUgB,IAAI,CAAC,cAAc,EAAEhB,UAAUS,OAAO,CAAC,GAAG,EACrGpB,4BACD,KAAK,EAAEN,UAAU,OAAOwC,UAAU;QAEvC,OAAO;YACLvC,GAAGqC,MAAM,CACPtC,UACE,OACA,CAAC,wCAAwC,EAAEiB,UAAUgB,IAAI,CAAC,MAAM,EAAEjC,UAAU,OAAOwC,UAAU;QAGnG;QAEA,MAAMD;IACR;AACF"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { CLIError } from '@oclif/core/errors';
|
|
2
|
+
import { SANITY_WORKSPACE_SCHEMA_ID_PREFIX } from '@sanity/cli-build/_internal/manifest';
|
|
2
3
|
import uniqBy from 'lodash-es/uniqBy.js';
|
|
3
|
-
import { isDefined } from '
|
|
4
|
-
import { SANITY_WORKSPACE_SCHEMA_ID_PREFIX } from '../../manifest/types.js';
|
|
4
|
+
import { isDefined } from '../schemaTypeHelpers.js';
|
|
5
5
|
const validForIdChars = 'a-zA-Z0-9._-';
|
|
6
6
|
const validForIdPattern = new RegExp(`^[${validForIdChars}]+$`);
|
|
7
7
|
//no periods allowed in workspaceName or tag in ids
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/schema/utils/schemaStoreValidation.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/schema/utils/schemaStoreValidation.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport {SANITY_WORKSPACE_SCHEMA_ID_PREFIX} from '@sanity/cli-build/_internal/manifest'\nimport uniqBy from 'lodash-es/uniqBy.js'\n\nimport {isDefined} from '../schemaTypeHelpers.js'\n\nconst validForIdChars = 'a-zA-Z0-9._-'\nconst validForIdPattern = new RegExp(`^[${validForIdChars}]+$`)\n\n//no periods allowed in workspaceName or tag in ids\nexport const validForNamesChars = 'a-zA-Z0-9_-'\nexport const validForNamesPattern = new RegExp(`^[${validForNamesChars}]+$`)\n\nconst requiredInId = SANITY_WORKSPACE_SCHEMA_ID_PREFIX.replaceAll(/[.]/g, String.raw`\\.`)\n\nconst idIdPatternString = String.raw`^${requiredInId}\\.([${validForNamesChars}]+)`\nconst baseIdPattern = new RegExp(`${idIdPatternString}$`)\nconst taggedIdIdPattern = new RegExp(\n String.raw`${idIdPatternString}\\.tag\\.([${validForNamesChars}]+)$`,\n)\n\nexport interface WorkspaceSchemaId {\n schemaId: string\n workspace: string\n}\n\nexport function parseIds(ids?: string): WorkspaceSchemaId[] {\n if (!ids) {\n throw new CLIError('ids argument is empty')\n }\n\n const errors: string[] = []\n\n const parsedIds = ids\n .split(',')\n .map((id) => id.trim())\n .filter((id) => !!id)\n .map((id) => parseWorkspaceSchemaId(errors, id))\n .filter((item) => isDefined(item))\n\n if (errors.length > 0) {\n throw new CLIError(`Invalid arguments:\\n${errors.map((error) => ` - ${error}`).join('\\n')}`)\n }\n\n if (parsedIds.length === 0) {\n throw new CLIError(`ids contains no valid id strings`)\n }\n\n const uniqueIds = uniqBy(parsedIds, 'schemaId' satisfies keyof (typeof parsedIds)[number])\n if (uniqueIds.length < parsedIds.length) {\n throw new CLIError(`ids contains duplicates`)\n }\n\n return uniqueIds\n}\n\nexport function parseWorkspaceSchemaId(errors: string[], id?: string) {\n if (id === undefined) {\n return\n }\n\n if (!id) {\n errors.push('id argument is empty')\n return\n }\n\n const trimmedId = id.trim()\n\n if (!validForIdPattern.test(trimmedId)) {\n errors.push(`id can only contain characters in [${validForIdChars}] but found: \"${trimmedId}\"`)\n return\n }\n\n if (trimmedId.startsWith('-')) {\n errors.push(`id cannot start with - (dash) but found: \"${trimmedId}\"`)\n return\n }\n\n if (/\\.\\./g.test(trimmedId)) {\n errors.push(`id cannot have consecutive . (period) characters, but found: \"${trimmedId}\"`)\n return\n }\n\n const [, workspace] = trimmedId.match(taggedIdIdPattern) ?? trimmedId.match(baseIdPattern) ?? []\n if (!workspace) {\n errors.push(\n [\n `id must either match ${SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.<workspaceName> `,\n `or ${SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.<workspaceName>.tag.<tag> but found: \"${trimmedId}\". `,\n `Note that workspace name characters not in [${validForNamesChars}] has to be replaced with _ for schema id.`,\n ].join(''),\n )\n return\n }\n return {\n schemaId: trimmedId,\n workspace,\n }\n}\n\n/**\n *\n * @param tag - The tag to parse\n * Throws an error if the tag is empty\n * Throws an error if the tag contains a period\n * Throws an error if the tag starts with a dash\n * Returns the parsed tag\n */\nexport async function parseTag(tag?: string) {\n if (tag === undefined) {\n return tag\n }\n\n if (!tag) {\n throw new CLIError('tag argument is empty')\n }\n\n if (tag.includes('.')) {\n throw new CLIError(`tag cannot contain . (period), but was: \"${tag}\"`)\n }\n\n if (!validForNamesPattern.test(tag)) {\n throw new CLIError(\n `tag can only contain characters in [${validForNamesChars}], but was: \"${tag}\"`,\n )\n }\n\n if (tag.startsWith('-')) {\n throw new CLIError(`tag cannot start with - (dash) but was: \"${tag}\"`)\n }\n\n return tag\n}\n\nexport const SCHEMA_PERMISSION_HELP_TEXT =\n 'For multi-project workspaces, set SANITY_AUTH_TOKEN environment variable to a token with access to the workspace projects.'\n"],"names":["CLIError","SANITY_WORKSPACE_SCHEMA_ID_PREFIX","uniqBy","isDefined","validForIdChars","validForIdPattern","RegExp","validForNamesChars","validForNamesPattern","requiredInId","replaceAll","String","raw","idIdPatternString","baseIdPattern","taggedIdIdPattern","parseIds","ids","errors","parsedIds","split","map","id","trim","filter","parseWorkspaceSchemaId","item","length","error","join","uniqueIds","undefined","push","trimmedId","test","startsWith","workspace","match","schemaId","parseTag","tag","includes","SCHEMA_PERMISSION_HELP_TEXT"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SANITY_WORKSPACE_SCHEMA_ID_PREFIX } from '
|
|
1
|
+
import { SANITY_WORKSPACE_SCHEMA_ID_PREFIX } from '@sanity/cli-build/_internal/manifest';
|
|
2
2
|
import { validForNamesChars, validForNamesPattern } from './schemaStoreValidation.js';
|
|
3
3
|
export function getWorkspaceSchemaId(args) {
|
|
4
4
|
const { tag, workspaceName: rawWorkspaceName } = args;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/schema/utils/workspaceSchemaId.ts"],"sourcesContent":["import {\n type DefaultWorkspaceSchemaId,\n SANITY_WORKSPACE_SCHEMA_ID_PREFIX,\n type WorkspaceSchemaId,\n} from '
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/schema/utils/workspaceSchemaId.ts"],"sourcesContent":["import {\n type DefaultWorkspaceSchemaId,\n SANITY_WORKSPACE_SCHEMA_ID_PREFIX,\n type WorkspaceSchemaId,\n} from '@sanity/cli-build/_internal/manifest'\n\nimport {validForNamesChars, validForNamesPattern} from './schemaStoreValidation.js'\n\nexport function getWorkspaceSchemaId(args: {tag?: string; workspaceName: string}) {\n const {tag, workspaceName: rawWorkspaceName} = args\n\n let workspaceName = rawWorkspaceName\n let idWarning: string | undefined\n\n // The HTTP API replaces periods with _ in the workspace name, so the CLI should too\n if (!validForNamesPattern.test(workspaceName)) {\n workspaceName = workspaceName.replaceAll(new RegExp(`[^${validForNamesChars}]`, 'g'), '_')\n idWarning = [\n `Workspace \"${rawWorkspaceName}\" contains characters unsupported by schema _id [${validForNamesChars}], they will be replaced with _.`,\n 'This could lead duplicate schema ids: consider renaming your workspace.',\n ].join('\\n')\n }\n\n const safeBaseId: DefaultWorkspaceSchemaId = `${SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.${workspaceName}`\n return {\n idWarning,\n safeBaseId,\n safeTaggedId: `${safeBaseId}${tag ? `.${tag}` : ''}` satisfies WorkspaceSchemaId,\n }\n}\n"],"names":["SANITY_WORKSPACE_SCHEMA_ID_PREFIX","validForNamesChars","validForNamesPattern","getWorkspaceSchemaId","args","tag","workspaceName","rawWorkspaceName","idWarning","test","replaceAll","RegExp","join","safeBaseId","safeTaggedId"],"mappings":"AAAA,SAEEA,iCAAiC,QAE5B,uCAAsC;AAE7C,SAAQC,kBAAkB,EAAEC,oBAAoB,QAAO,6BAA4B;AAEnF,OAAO,SAASC,qBAAqBC,IAA2C;IAC9E,MAAM,EAACC,GAAG,EAAEC,eAAeC,gBAAgB,EAAC,GAAGH;IAE/C,IAAIE,gBAAgBC;IACpB,IAAIC;IAEJ,oFAAoF;IACpF,IAAI,CAACN,qBAAqBO,IAAI,CAACH,gBAAgB;QAC7CA,gBAAgBA,cAAcI,UAAU,CAAC,IAAIC,OAAO,CAAC,EAAE,EAAEV,mBAAmB,CAAC,CAAC,EAAE,MAAM;QACtFO,YAAY;YACV,CAAC,WAAW,EAAED,iBAAiB,iDAAiD,EAAEN,mBAAmB,gCAAgC,CAAC;YACtI;SACD,CAACW,IAAI,CAAC;IACT;IAEA,MAAMC,aAAuC,GAAGb,kCAAkC,CAAC,EAAEM,eAAe;IACpG,OAAO;QACLE;QACAK;QACAC,cAAc,GAAGD,aAAaR,MAAM,CAAC,CAAC,EAAEA,KAAK,GAAG,IAAI;IACtD;AACF"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
|
-
import padEnd from 'lodash-es/padEnd.js';
|
|
3
2
|
/**
|
|
4
3
|
* Get the display name for a module.
|
|
5
4
|
*
|
|
@@ -19,7 +18,7 @@ import padEnd from 'lodash-es/padEnd.js';
|
|
|
19
18
|
nameLength = Math.max(nameLength, displayName.length);
|
|
20
19
|
versionLength = Math.max(versionLength, (mod.installed || '<missing>').length);
|
|
21
20
|
}
|
|
22
|
-
const formatName = (name)=>padEnd(
|
|
21
|
+
const formatName = (name)=>name.padEnd(nameLength + 1).replace(/^@sanity\/(.*?)(\s|$)/, `${styleText('yellow', '@sanity/')}${styleText('cyan', '$1')}$2`).replace(/^sanity(\s|$)/, `${styleText('yellow', 'sanity')}$1`);
|
|
23
22
|
return {
|
|
24
23
|
formatName,
|
|
25
24
|
nameLength,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/versions/getFormatters.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/versions/getFormatters.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type ModuleVersionResult} from './types.js'\n\n/**\n * Get the display name for a module.\n *\n * @internal\n */\nexport function getDisplayName(mod: ModuleVersionResult): string {\n return mod.isGlobal ? `${mod.name} (global)` : mod.name\n}\n\n/**\n * Get formatters for the package versions.\n *\n * @internal\n */\nexport function getFormatters(versions: ModuleVersionResult[]): {\n formatName: (name: string) => string\n nameLength: number\n versionLength: number\n} {\n let nameLength = 0\n let versionLength = 0\n\n for (const mod of versions) {\n const displayName = getDisplayName(mod)\n nameLength = Math.max(nameLength, displayName.length)\n versionLength = Math.max(versionLength, (mod.installed || '<missing>').length)\n }\n\n const formatName = (name: string): string =>\n name\n .padEnd(nameLength + 1)\n .replace(\n /^@sanity\\/(.*?)(\\s|$)/,\n `${styleText('yellow', '@sanity/')}${styleText('cyan', '$1')}$2`,\n )\n .replace(/^sanity(\\s|$)/, `${styleText('yellow', 'sanity')}$1`)\n\n return {formatName, nameLength, versionLength}\n}\n"],"names":["styleText","getDisplayName","mod","isGlobal","name","getFormatters","versions","nameLength","versionLength","displayName","Math","max","length","installed","formatName","padEnd","replace"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAInC;;;;CAIC,GACD,OAAO,SAASC,eAAeC,GAAwB;IACrD,OAAOA,IAAIC,QAAQ,GAAG,GAAGD,IAAIE,IAAI,CAAC,SAAS,CAAC,GAAGF,IAAIE,IAAI;AACzD;AAEA;;;;CAIC,GACD,OAAO,SAASC,cAAcC,QAA+B;IAK3D,IAAIC,aAAa;IACjB,IAAIC,gBAAgB;IAEpB,KAAK,MAAMN,OAAOI,SAAU;QAC1B,MAAMG,cAAcR,eAAeC;QACnCK,aAAaG,KAAKC,GAAG,CAACJ,YAAYE,YAAYG,MAAM;QACpDJ,gBAAgBE,KAAKC,GAAG,CAACH,eAAe,AAACN,CAAAA,IAAIW,SAAS,IAAI,WAAU,EAAGD,MAAM;IAC/E;IAEA,MAAME,aAAa,CAACV,OAClBA,KACGW,MAAM,CAACR,aAAa,GACpBS,OAAO,CACN,yBACA,GAAGhB,UAAU,UAAU,cAAcA,UAAU,QAAQ,MAAM,EAAE,CAAC,EAEjEgB,OAAO,CAAC,iBAAiB,GAAGhB,UAAU,UAAU,UAAU,EAAE,CAAC;IAElE,OAAO;QAACc;QAAYP;QAAYC;IAAa;AAC/C"}
|
|
@@ -2,13 +2,13 @@ import { randomUUID } from 'node:crypto';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
|
+
import { isDeepStrictEqual } from 'node:util';
|
|
5
6
|
import { Args, Flags } from '@oclif/core';
|
|
6
7
|
import { exitCodes, getProjectCliClient, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
8
|
+
import { isRecord } from '@sanity/cli-core/util';
|
|
7
9
|
import { watch as chokidarWatch } from 'chokidar';
|
|
8
10
|
import { execa, execaSync } from 'execa';
|
|
9
11
|
import json5 from 'json5';
|
|
10
|
-
import isEqual from 'lodash-es/isEqual.js';
|
|
11
|
-
import isPlainObject from 'lodash-es/isPlainObject.js';
|
|
12
12
|
import { DOCUMENTS_API_VERSION } from '../../actions/documents/constants.js';
|
|
13
13
|
import { getEditor, registerUnlinkOnSigInt } from '../../actions/documents/editor.js';
|
|
14
14
|
import { promptForProject } from '../../prompts/promptForProject.js';
|
|
@@ -242,7 +242,7 @@ export class CreateDocumentCommand extends SanityCommand {
|
|
|
242
242
|
this.log(`Failed to read input: ${error.message}`);
|
|
243
243
|
return;
|
|
244
244
|
}
|
|
245
|
-
if (
|
|
245
|
+
if (isDeepStrictEqual(content, defaultValue)) {
|
|
246
246
|
this.log('Value not modified, doing nothing.');
|
|
247
247
|
this.log('Modify document to trigger creation.');
|
|
248
248
|
return;
|
|
@@ -266,7 +266,7 @@ export class CreateDocumentCommand extends SanityCommand {
|
|
|
266
266
|
* Validates a document for Sanity requirements
|
|
267
267
|
*/ validateDocument(doc, index, arr) {
|
|
268
268
|
const isSingle = arr.length === 1;
|
|
269
|
-
if (!
|
|
269
|
+
if (!isRecord(doc)) {
|
|
270
270
|
throw new Error(this.getErrorMessage('must be an object', index, isSingle));
|
|
271
271
|
}
|
|
272
272
|
if (!isSanityDocumentish(doc)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/commands/documents/create.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto'\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {type MultipleMutationResult, type Mutation} from '@sanity/client'\nimport {watch as chokidarWatch} from 'chokidar'\nimport {execa, execaSync} from 'execa'\nimport json5 from 'json5'\nimport isEqual from 'lodash-es/isEqual.js'\nimport isPlainObject from 'lodash-es/isPlainObject.js'\n\nimport {DOCUMENTS_API_VERSION} from '../../actions/documents/constants.js'\nimport {getEditor, registerUnlinkOnSigInt} from '../../actions/documents/editor.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {isIdentifiedSanityDocument, isSanityDocumentish} from '../../util/isSanityDocumentish.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nexport type MutationOperationName = 'create' | 'createIfNotExists' | 'createOrReplace'\n\nconst createDocumentDebug = subdebug('documents:create')\n\nexport class CreateDocumentCommand extends SanityCommand<typeof CreateDocumentCommand> {\n static override args = {\n file: Args.string({\n description: 'JSON file to create document(s) from',\n required: false,\n }),\n }\n\n static override description = 'Create one or more documents'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> myDocument.json',\n description: 'Create the document specified in \"myDocument.json\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Open configured $EDITOR and create the specified document(s)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --id myDocId --replace',\n description:\n 'Fetch document with the ID \"myDocId\" and open configured $EDITOR with the current document content (if any). Replace document with the edited version when the editor closes',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --id myDocId --watch --replace --json5',\n description:\n 'Open configured $EDITOR and replace the document with the given content on each save. Use JSON5 file extension and parser for simplified syntax.',\n },\n {\n command: '<%= config.bin %> <%= command.id %> myDocument.json --project-id abc123',\n description: 'Create documents in a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to create document(s) in',\n semantics: 'override',\n }),\n ...getDatasetFlag({\n description: 'Dataset to create document(s) in',\n semantics: 'override',\n }),\n id: Flags.string({\n description:\n 'Specify a document ID to use. Will fetch remote document ID and populate editor.',\n }),\n json5: Flags.boolean({\n description: 'Use JSON5 file type to allow a \"simplified\" version of JSON',\n }),\n missing: Flags.boolean({\n description: \"On duplicate document IDs, don't modify the target document(s)\",\n }),\n replace: Flags.boolean({\n description:\n 'On duplicate document IDs, replace existing document with specified document(s)',\n }),\n watch: Flags.boolean({\n description: 'Write the documents whenever the target file or buffer changes',\n }),\n }\n\n static override hiddenAliases: string[] = ['document:create']\n\n private client!: Awaited<ReturnType<typeof getProjectCliClient>>\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateDocumentCommand)\n const {file} = args\n const {dataset, id, json5: useJson5, missing, replace, watch} = flags\n\n if (!file && this.isUnattended()) {\n this.error(\n 'Document input is required in unattended mode. Pass it as the `<file>` argument.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n if (replace && missing) {\n this.error(\n 'Cannot use `--replace` and `--missing` together. Remove one flag and try again.',\n {\n exit: exitCodes.USAGE_ERROR,\n },\n )\n }\n\n if (id && file) {\n this.error(\n 'Cannot use `--id` with the `<file>` argument. Remove `--id` or omit `<file>` and try again.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const cliConfig = await this.tryGetCliConfig()\n\n const projectId = await this.getProjectId({fallback: () => promptForProject({})})\n\n if (!cliConfig.api?.dataset && !dataset) {\n this.error(\n 'Dataset is required. Pass it with `--dataset <name>` or configure it in `sanity.cli.ts`.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const targetDataset = dataset || cliConfig.api?.dataset\n\n this.client = await getProjectCliClient({\n apiVersion: DOCUMENTS_API_VERSION,\n dataset: targetDataset,\n projectId,\n requireUser: true,\n })\n\n let operation: MutationOperationName = 'create'\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n }\n\n if (file) {\n try {\n const contentPath = path.resolve(process.cwd(), file)\n const content = json5.parse(await fs.readFile(contentPath, 'utf8'))\n const result = await this.writeDocuments(content, operation)\n this.log(this.getResultMessage(result, operation))\n return\n } catch (error) {\n const err = error as Error\n createDocumentDebug(`Error creating documents from file ${file}`, err)\n this.error(`Failed to create documents: ${err.message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n try {\n // Create a temporary file and use that as source, opening an editor on it\n const docId = id || randomUUID()\n const ext = useJson5 ? 'json5' : 'json'\n // Add UUID prefix to prevent predictable file names and potential conflicts\n const tmpFile = path.join(os.tmpdir(), 'sanity-cli', `${randomUUID()}-${docId}.${ext}`)\n const stringify = useJson5 ? json5.stringify : JSON.stringify\n const defaultValue = (id && (await this.client.getDocument(id))) || {\n _id: docId,\n _type: 'specify-me',\n }\n\n // Create temp directory with restricted permissions (owner only)\n const tempDir = path.join(os.tmpdir(), 'sanity-cli')\n await fs.mkdir(tempDir, {\n mode: 0o700, // rwx------ (owner read/write/execute only)\n recursive: true,\n })\n\n // Write file with restricted permissions (owner read/write only)\n await fs.writeFile(tmpFile, stringify(defaultValue, null, 2), {\n encoding: 'utf8',\n mode: 0o600, // rw------- (owner read/write only)\n })\n\n const editor = getEditor()\n const readAndPerformCreatesFromFile = this.readAndPerformCreatesFromFile.bind(this, operation)\n\n if (watch) {\n // If we're in watch mode, we want to run the creation on each change (if it validates)\n registerUnlinkOnSigInt(tmpFile)\n this.log(`Watch mode: ${tmpFile}`)\n this.log('Watch mode: Will write documents on each save.')\n this.log('Watch mode: Press Ctrl + C to cancel watch mode.')\n\n // Add race condition protection\n let isProcessing = false\n chokidarWatch(tmpFile).on('change', async () => {\n if (isProcessing) {\n return // Skip if already processing\n }\n isProcessing = true\n\n this.log('')\n try {\n await readAndPerformCreatesFromFile(tmpFile, defaultValue)\n } finally {\n isProcessing = false\n }\n })\n execa(editor.bin, [...editor.args, tmpFile], {stdio: 'inherit'})\n } else {\n // While in normal mode, we just want to wait for the editor to close and run the thing once\n execaSync(editor.bin, [...editor.args, tmpFile], {stdio: 'inherit'})\n await readAndPerformCreatesFromFile(tmpFile, defaultValue)\n await fs.unlink(tmpFile).catch(() => {})\n }\n } catch (error) {\n const err = error as Error\n createDocumentDebug('Error in editor workflow', err)\n this.error(`Failed to create documents: ${err.message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n private getErrorMessage(message: string, index: number, isSingle: boolean): string {\n return isSingle ? `Document ${message}` : `Document at index ${index} ${message}`\n }\n\n /**\n * Formats the result message for document operations\n */\n private getResultMessage(\n result: MultipleMutationResult,\n operation: MutationOperationName,\n ): string {\n const joiner = '\\n - '\n if (operation === 'createOrReplace') {\n return `Upserted:\\n - ${result.results.map((res) => res.id).join(joiner)}`\n }\n\n if (operation === 'create') {\n return `Created:\\n - ${result.results.map((res) => res.id).join(joiner)}`\n }\n\n // \"Missing\" (createIfNotExists)\n const created: string[] = []\n const skipped: string[] = []\n for (const res of result.results) {\n if (res.operation === 'update') {\n skipped.push(res.id)\n } else {\n created.push(res.id)\n }\n }\n\n if (created.length > 0 && skipped.length > 0) {\n return [\n `Created:\\n - ${created.join(joiner)}`,\n `Skipped (already exists):${joiner}${skipped.join(joiner)}`,\n ].join('\\n\\n')\n } else if (created.length > 0) {\n return `Created:\\n - ${created.join(joiner)}`\n }\n\n return `Skipped (already exists):\\n - ${skipped.join(joiner)}`\n }\n\n /**\n * Reads and processes documents from a file for creation\n */\n private async readAndPerformCreatesFromFile(\n operation: MutationOperationName,\n filePath: string,\n defaultValue: unknown,\n ): Promise<void> {\n let content\n try {\n content = json5.parse(await fs.readFile(filePath, 'utf8'))\n } catch (err) {\n const error = err as Error\n createDocumentDebug(`Failed to read input file ${filePath}`, error)\n this.log(`Failed to read input: ${error.message}`)\n return\n }\n\n if (isEqual(content, defaultValue)) {\n this.log('Value not modified, doing nothing.')\n this.log('Modify document to trigger creation.')\n return\n }\n\n try {\n const writeResult = await this.writeDocuments(content, operation)\n this.log(this.getResultMessage(writeResult, operation))\n } catch (err) {\n const error = err as Error\n createDocumentDebug(`Failed to write documents`, error)\n let errorMessage = `Failed to write documents: ${error.message}`\n if (error.message.includes('already exists')) {\n errorMessage += '\\nPerhaps you want to use `--replace` or `--missing`?'\n }\n this.error(errorMessage, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n /**\n * Validates a document for Sanity requirements\n */\n private validateDocument(doc: unknown, index: number, arr: unknown[]): void {\n const isSingle = arr.length === 1\n\n if (!isPlainObject(doc)) {\n throw new Error(this.getErrorMessage('must be an object', index, isSingle))\n }\n\n if (!isSanityDocumentish(doc)) {\n throw new Error(\n this.getErrorMessage('must have a `_type` property of type string', index, isSingle),\n )\n }\n\n // Enhanced validations for Sanity document constraints\n const docObj = doc as Record<string, unknown>\n\n // Validate _type is non-empty\n const typeValue = docObj._type?.toString().trim()\n if (!typeValue) {\n throw new Error(this.getErrorMessage('_type cannot be empty', index, isSingle))\n }\n\n // Validate _type format (alphanumeric, underscore, hyphen, dot)\n if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(typeValue)) {\n throw new Error(\n this.getErrorMessage(\n '_type must start with a letter and contain only alphanumeric characters, underscores, hyphens, and dots',\n index,\n isSingle,\n ),\n )\n }\n\n // Validate _id format if present\n if (docObj._id && typeof docObj._id === 'string') {\n const idValue = docObj._id.trim()\n if (!idValue) {\n throw new Error(this.getErrorMessage('_id cannot be empty', index, isSingle))\n }\n\n // Sanity document IDs can contain alphanumeric chars, hyphens, underscores, and dots\n if (!/^[a-zA-Z0-9_.-]+$/.test(idValue)) {\n throw new Error(\n this.getErrorMessage(\n '_id can only contain alphanumeric characters, underscores, hyphens, and dots',\n index,\n isSingle,\n ),\n )\n }\n\n // Check length constraints (Sanity has reasonable limits)\n if (idValue.length > 200) {\n throw new Error(\n this.getErrorMessage('_id cannot be longer than 200 characters', index, isSingle),\n )\n }\n }\n\n // Warn about reserved fields (these are managed by Sanity)\n const reservedFields = ['_rev', '_updatedAt', '_createdAt']\n for (const field of reservedFields) {\n if (field in docObj) {\n // Note: We don't throw an error here as these might be present in fetched documents\n // that are being re-uploaded, but we could add a debug warning\n createDocumentDebug(\n `Warning: Document ${index} contains reserved field '${field}' which will be ignored by Sanity`,\n )\n }\n }\n }\n\n /**\n * Writes documents to Sanity using the specified operation\n */\n private async writeDocuments(\n documents: {_id?: string; _type: string} | {_id?: string; _type: string}[],\n operation: MutationOperationName,\n ): Promise<MultipleMutationResult> {\n const docs = Array.isArray(documents) ? documents : [documents]\n if (docs.length === 0) {\n throw new Error('No documents provided')\n }\n\n const mutations = docs.map((doc, index): Mutation => {\n this.validateDocument(doc, index, docs)\n if (operation === 'create') {\n return {create: doc}\n }\n\n if (operation === 'createIfNotExists') {\n if (isIdentifiedSanityDocument(doc)) {\n return {createIfNotExists: doc}\n }\n\n throw new Error(`Missing required _id attribute for ${operation}`)\n }\n\n if (operation === 'createOrReplace') {\n if (isIdentifiedSanityDocument(doc)) {\n return {createOrReplace: doc}\n }\n\n throw new Error(`Missing required _id attribute for ${operation}`)\n }\n\n throw new Error(`Unsupported operation ${operation}`)\n })\n\n return this.client.transaction(mutations).commit()\n }\n}\n"],"names":["randomUUID","fs","os","path","Args","Flags","exitCodes","getProjectCliClient","SanityCommand","subdebug","watch","chokidarWatch","execa","execaSync","json5","isEqual","isPlainObject","DOCUMENTS_API_VERSION","getEditor","registerUnlinkOnSigInt","promptForProject","isIdentifiedSanityDocument","isSanityDocumentish","getDatasetFlag","getProjectIdFlag","createDocumentDebug","CreateDocumentCommand","args","file","string","description","required","examples","command","flags","semantics","id","boolean","missing","replace","hiddenAliases","client","run","parse","dataset","useJson5","isUnattended","error","exit","USAGE_ERROR","cliConfig","tryGetCliConfig","projectId","getProjectId","fallback","api","targetDataset","apiVersion","requireUser","operation","contentPath","resolve","process","cwd","content","readFile","result","writeDocuments","log","getResultMessage","err","message","RUNTIME_ERROR","docId","ext","tmpFile","join","tmpdir","stringify","JSON","defaultValue","getDocument","_id","_type","tempDir","mkdir","mode","recursive","writeFile","encoding","editor","readAndPerformCreatesFromFile","bind","isProcessing","on","bin","stdio","unlink","catch","getErrorMessage","index","isSingle","joiner","results","map","res","created","skipped","push","length","filePath","writeResult","errorMessage","includes","validateDocument","doc","arr","Error","docObj","typeValue","toString","trim","test","idValue","reservedFields","field","documents","docs","Array","isArray","mutations","create","createIfNotExists","createOrReplace","transaction","commit"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/documents/create.ts"],"sourcesContent":["import {randomUUID} from 'node:crypto'\nimport fs from 'node:fs/promises'\nimport os from 'node:os'\nimport path from 'node:path'\nimport {isDeepStrictEqual} from 'node:util'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, getProjectCliClient, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {isRecord} from '@sanity/cli-core/util'\nimport {type MultipleMutationResult, type Mutation} from '@sanity/client'\nimport {watch as chokidarWatch} from 'chokidar'\nimport {execa, execaSync} from 'execa'\nimport json5 from 'json5'\n\nimport {DOCUMENTS_API_VERSION} from '../../actions/documents/constants.js'\nimport {getEditor, registerUnlinkOnSigInt} from '../../actions/documents/editor.js'\nimport {promptForProject} from '../../prompts/promptForProject.js'\nimport {isIdentifiedSanityDocument, isSanityDocumentish} from '../../util/isSanityDocumentish.js'\nimport {getDatasetFlag, getProjectIdFlag} from '../../util/sharedFlags.js'\n\nexport type MutationOperationName = 'create' | 'createIfNotExists' | 'createOrReplace'\n\nconst createDocumentDebug = subdebug('documents:create')\n\nexport class CreateDocumentCommand extends SanityCommand<typeof CreateDocumentCommand> {\n static override args = {\n file: Args.string({\n description: 'JSON file to create document(s) from',\n required: false,\n }),\n }\n\n static override description = 'Create one or more documents'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> myDocument.json',\n description: 'Create the document specified in \"myDocument.json\"',\n },\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Open configured $EDITOR and create the specified document(s)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --id myDocId --replace',\n description:\n 'Fetch document with the ID \"myDocId\" and open configured $EDITOR with the current document content (if any). Replace document with the edited version when the editor closes',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --id myDocId --watch --replace --json5',\n description:\n 'Open configured $EDITOR and replace the document with the given content on each save. Use JSON5 file extension and parser for simplified syntax.',\n },\n {\n command: '<%= config.bin %> <%= command.id %> myDocument.json --project-id abc123',\n description: 'Create documents in a specific project',\n },\n ]\n\n static override flags = {\n ...getProjectIdFlag({\n description: 'Project ID to create document(s) in',\n semantics: 'override',\n }),\n ...getDatasetFlag({\n description: 'Dataset to create document(s) in',\n semantics: 'override',\n }),\n id: Flags.string({\n description:\n 'Specify a document ID to use. Will fetch remote document ID and populate editor.',\n }),\n json5: Flags.boolean({\n description: 'Use JSON5 file type to allow a \"simplified\" version of JSON',\n }),\n missing: Flags.boolean({\n description: \"On duplicate document IDs, don't modify the target document(s)\",\n }),\n replace: Flags.boolean({\n description:\n 'On duplicate document IDs, replace existing document with specified document(s)',\n }),\n watch: Flags.boolean({\n description: 'Write the documents whenever the target file or buffer changes',\n }),\n }\n\n static override hiddenAliases: string[] = ['document:create']\n\n private client!: Awaited<ReturnType<typeof getProjectCliClient>>\n\n public async run(): Promise<void> {\n const {args, flags} = await this.parse(CreateDocumentCommand)\n const {file} = args\n const {dataset, id, json5: useJson5, missing, replace, watch} = flags\n\n if (!file && this.isUnattended()) {\n this.error(\n 'Document input is required in unattended mode. Pass it as the `<file>` argument.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n if (replace && missing) {\n this.error(\n 'Cannot use `--replace` and `--missing` together. Remove one flag and try again.',\n {\n exit: exitCodes.USAGE_ERROR,\n },\n )\n }\n\n if (id && file) {\n this.error(\n 'Cannot use `--id` with the `<file>` argument. Remove `--id` or omit `<file>` and try again.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const cliConfig = await this.tryGetCliConfig()\n\n const projectId = await this.getProjectId({fallback: () => promptForProject({})})\n\n if (!cliConfig.api?.dataset && !dataset) {\n this.error(\n 'Dataset is required. Pass it with `--dataset <name>` or configure it in `sanity.cli.ts`.',\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n const targetDataset = dataset || cliConfig.api?.dataset\n\n this.client = await getProjectCliClient({\n apiVersion: DOCUMENTS_API_VERSION,\n dataset: targetDataset,\n projectId,\n requireUser: true,\n })\n\n let operation: MutationOperationName = 'create'\n if (replace || missing) {\n operation = replace ? 'createOrReplace' : 'createIfNotExists'\n }\n\n if (file) {\n try {\n const contentPath = path.resolve(process.cwd(), file)\n const content = json5.parse(await fs.readFile(contentPath, 'utf8'))\n const result = await this.writeDocuments(content, operation)\n this.log(this.getResultMessage(result, operation))\n return\n } catch (error) {\n const err = error as Error\n createDocumentDebug(`Error creating documents from file ${file}`, err)\n this.error(`Failed to create documents: ${err.message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n try {\n // Create a temporary file and use that as source, opening an editor on it\n const docId = id || randomUUID()\n const ext = useJson5 ? 'json5' : 'json'\n // Add UUID prefix to prevent predictable file names and potential conflicts\n const tmpFile = path.join(os.tmpdir(), 'sanity-cli', `${randomUUID()}-${docId}.${ext}`)\n const stringify = useJson5 ? json5.stringify : JSON.stringify\n const defaultValue = (id && (await this.client.getDocument(id))) || {\n _id: docId,\n _type: 'specify-me',\n }\n\n // Create temp directory with restricted permissions (owner only)\n const tempDir = path.join(os.tmpdir(), 'sanity-cli')\n await fs.mkdir(tempDir, {\n mode: 0o700, // rwx------ (owner read/write/execute only)\n recursive: true,\n })\n\n // Write file with restricted permissions (owner read/write only)\n await fs.writeFile(tmpFile, stringify(defaultValue, null, 2), {\n encoding: 'utf8',\n mode: 0o600, // rw------- (owner read/write only)\n })\n\n const editor = getEditor()\n const readAndPerformCreatesFromFile = this.readAndPerformCreatesFromFile.bind(this, operation)\n\n if (watch) {\n // If we're in watch mode, we want to run the creation on each change (if it validates)\n registerUnlinkOnSigInt(tmpFile)\n this.log(`Watch mode: ${tmpFile}`)\n this.log('Watch mode: Will write documents on each save.')\n this.log('Watch mode: Press Ctrl + C to cancel watch mode.')\n\n // Add race condition protection\n let isProcessing = false\n chokidarWatch(tmpFile).on('change', async () => {\n if (isProcessing) {\n return // Skip if already processing\n }\n isProcessing = true\n\n this.log('')\n try {\n await readAndPerformCreatesFromFile(tmpFile, defaultValue)\n } finally {\n isProcessing = false\n }\n })\n execa(editor.bin, [...editor.args, tmpFile], {stdio: 'inherit'})\n } else {\n // While in normal mode, we just want to wait for the editor to close and run the thing once\n execaSync(editor.bin, [...editor.args, tmpFile], {stdio: 'inherit'})\n await readAndPerformCreatesFromFile(tmpFile, defaultValue)\n await fs.unlink(tmpFile).catch(() => {})\n }\n } catch (error) {\n const err = error as Error\n createDocumentDebug('Error in editor workflow', err)\n this.error(`Failed to create documents: ${err.message}`, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n private getErrorMessage(message: string, index: number, isSingle: boolean): string {\n return isSingle ? `Document ${message}` : `Document at index ${index} ${message}`\n }\n\n /**\n * Formats the result message for document operations\n */\n private getResultMessage(\n result: MultipleMutationResult,\n operation: MutationOperationName,\n ): string {\n const joiner = '\\n - '\n if (operation === 'createOrReplace') {\n return `Upserted:\\n - ${result.results.map((res) => res.id).join(joiner)}`\n }\n\n if (operation === 'create') {\n return `Created:\\n - ${result.results.map((res) => res.id).join(joiner)}`\n }\n\n // \"Missing\" (createIfNotExists)\n const created: string[] = []\n const skipped: string[] = []\n for (const res of result.results) {\n if (res.operation === 'update') {\n skipped.push(res.id)\n } else {\n created.push(res.id)\n }\n }\n\n if (created.length > 0 && skipped.length > 0) {\n return [\n `Created:\\n - ${created.join(joiner)}`,\n `Skipped (already exists):${joiner}${skipped.join(joiner)}`,\n ].join('\\n\\n')\n } else if (created.length > 0) {\n return `Created:\\n - ${created.join(joiner)}`\n }\n\n return `Skipped (already exists):\\n - ${skipped.join(joiner)}`\n }\n\n /**\n * Reads and processes documents from a file for creation\n */\n private async readAndPerformCreatesFromFile(\n operation: MutationOperationName,\n filePath: string,\n defaultValue: unknown,\n ): Promise<void> {\n let content\n try {\n content = json5.parse(await fs.readFile(filePath, 'utf8'))\n } catch (err) {\n const error = err as Error\n createDocumentDebug(`Failed to read input file ${filePath}`, error)\n this.log(`Failed to read input: ${error.message}`)\n return\n }\n\n if (isDeepStrictEqual(content, defaultValue)) {\n this.log('Value not modified, doing nothing.')\n this.log('Modify document to trigger creation.')\n return\n }\n\n try {\n const writeResult = await this.writeDocuments(content, operation)\n this.log(this.getResultMessage(writeResult, operation))\n } catch (err) {\n const error = err as Error\n createDocumentDebug(`Failed to write documents`, error)\n let errorMessage = `Failed to write documents: ${error.message}`\n if (error.message.includes('already exists')) {\n errorMessage += '\\nPerhaps you want to use `--replace` or `--missing`?'\n }\n this.error(errorMessage, {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n /**\n * Validates a document for Sanity requirements\n */\n private validateDocument(doc: unknown, index: number, arr: unknown[]): void {\n const isSingle = arr.length === 1\n\n if (!isRecord(doc)) {\n throw new Error(this.getErrorMessage('must be an object', index, isSingle))\n }\n\n if (!isSanityDocumentish(doc)) {\n throw new Error(\n this.getErrorMessage('must have a `_type` property of type string', index, isSingle),\n )\n }\n\n // Enhanced validations for Sanity document constraints\n const docObj = doc as Record<string, unknown>\n\n // Validate _type is non-empty\n const typeValue = docObj._type?.toString().trim()\n if (!typeValue) {\n throw new Error(this.getErrorMessage('_type cannot be empty', index, isSingle))\n }\n\n // Validate _type format (alphanumeric, underscore, hyphen, dot)\n if (!/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(typeValue)) {\n throw new Error(\n this.getErrorMessage(\n '_type must start with a letter and contain only alphanumeric characters, underscores, hyphens, and dots',\n index,\n isSingle,\n ),\n )\n }\n\n // Validate _id format if present\n if (docObj._id && typeof docObj._id === 'string') {\n const idValue = docObj._id.trim()\n if (!idValue) {\n throw new Error(this.getErrorMessage('_id cannot be empty', index, isSingle))\n }\n\n // Sanity document IDs can contain alphanumeric chars, hyphens, underscores, and dots\n if (!/^[a-zA-Z0-9_.-]+$/.test(idValue)) {\n throw new Error(\n this.getErrorMessage(\n '_id can only contain alphanumeric characters, underscores, hyphens, and dots',\n index,\n isSingle,\n ),\n )\n }\n\n // Check length constraints (Sanity has reasonable limits)\n if (idValue.length > 200) {\n throw new Error(\n this.getErrorMessage('_id cannot be longer than 200 characters', index, isSingle),\n )\n }\n }\n\n // Warn about reserved fields (these are managed by Sanity)\n const reservedFields = ['_rev', '_updatedAt', '_createdAt']\n for (const field of reservedFields) {\n if (field in docObj) {\n // Note: We don't throw an error here as these might be present in fetched documents\n // that are being re-uploaded, but we could add a debug warning\n createDocumentDebug(\n `Warning: Document ${index} contains reserved field '${field}' which will be ignored by Sanity`,\n )\n }\n }\n }\n\n /**\n * Writes documents to Sanity using the specified operation\n */\n private async writeDocuments(\n documents: {_id?: string; _type: string} | {_id?: string; _type: string}[],\n operation: MutationOperationName,\n ): Promise<MultipleMutationResult> {\n const docs = Array.isArray(documents) ? documents : [documents]\n if (docs.length === 0) {\n throw new Error('No documents provided')\n }\n\n const mutations = docs.map((doc, index): Mutation => {\n this.validateDocument(doc, index, docs)\n if (operation === 'create') {\n return {create: doc}\n }\n\n if (operation === 'createIfNotExists') {\n if (isIdentifiedSanityDocument(doc)) {\n return {createIfNotExists: doc}\n }\n\n throw new Error(`Missing required _id attribute for ${operation}`)\n }\n\n if (operation === 'createOrReplace') {\n if (isIdentifiedSanityDocument(doc)) {\n return {createOrReplace: doc}\n }\n\n throw new Error(`Missing required _id attribute for ${operation}`)\n }\n\n throw new Error(`Unsupported operation ${operation}`)\n })\n\n return this.client.transaction(mutations).commit()\n }\n}\n"],"names":["randomUUID","fs","os","path","isDeepStrictEqual","Args","Flags","exitCodes","getProjectCliClient","SanityCommand","subdebug","isRecord","watch","chokidarWatch","execa","execaSync","json5","DOCUMENTS_API_VERSION","getEditor","registerUnlinkOnSigInt","promptForProject","isIdentifiedSanityDocument","isSanityDocumentish","getDatasetFlag","getProjectIdFlag","createDocumentDebug","CreateDocumentCommand","args","file","string","description","required","examples","command","flags","semantics","id","boolean","missing","replace","hiddenAliases","client","run","parse","dataset","useJson5","isUnattended","error","exit","USAGE_ERROR","cliConfig","tryGetCliConfig","projectId","getProjectId","fallback","api","targetDataset","apiVersion","requireUser","operation","contentPath","resolve","process","cwd","content","readFile","result","writeDocuments","log","getResultMessage","err","message","RUNTIME_ERROR","docId","ext","tmpFile","join","tmpdir","stringify","JSON","defaultValue","getDocument","_id","_type","tempDir","mkdir","mode","recursive","writeFile","encoding","editor","readAndPerformCreatesFromFile","bind","isProcessing","on","bin","stdio","unlink","catch","getErrorMessage","index","isSingle","joiner","results","map","res","created","skipped","push","length","filePath","writeResult","errorMessage","includes","validateDocument","doc","arr","Error","docObj","typeValue","toString","trim","test","idValue","reservedFields","field","documents","docs","Array","isArray","mutations","create","createIfNotExists","createOrReplace","transaction","commit"],"mappings":"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"}
|
|
@@ -2,7 +2,6 @@ import { inspect, styleText } from 'node:util';
|
|
|
2
2
|
import { Args, Flags } from '@oclif/core';
|
|
3
3
|
import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
4
4
|
import { select } from '@sanity/cli-core/ux';
|
|
5
|
-
import groupBy from 'lodash-es/groupBy.js';
|
|
6
5
|
import { formatFailure } from '../../actions/hook/formatFailure.js';
|
|
7
6
|
import { promptForProject } from '../../prompts/promptForProject.js';
|
|
8
7
|
import { getHookAttemptsForProject, getHookMessagesForProject, getHooksForProject } from '../../services/hooks.js';
|
|
@@ -121,7 +120,7 @@ export class LogsHookCommand extends SanityCommand {
|
|
|
121
120
|
});
|
|
122
121
|
}
|
|
123
122
|
// Group attempts by message ID
|
|
124
|
-
const groupedAttempts = groupBy(attempts,
|
|
123
|
+
const groupedAttempts = Object.groupBy(attempts, (attempt)=>attempt.messageId);
|
|
125
124
|
// Populate messages with attempts
|
|
126
125
|
const populated = messages.map((msg)=>({
|
|
127
126
|
...msg,
|