@sanity/cli 6.3.2 → 6.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -18
- package/dist/actions/build/buildApp.js +12 -4
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStaticFiles.js +3 -1
- package/dist/actions/build/buildStaticFiles.js.map +1 -1
- package/dist/actions/build/buildStudio.js +29 -7
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/build/buildVendorDependencies.js +7 -7
- package/dist/actions/build/buildVendorDependencies.js.map +1 -1
- package/dist/actions/build/checkRequiredDependencies.js +4 -4
- package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
- package/dist/actions/build/checkStudioDependencyVersions.js +9 -9
- package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
- package/dist/actions/build/getAutoUpdatesImportMap.js +9 -0
- package/dist/actions/build/getAutoUpdatesImportMap.js.map +1 -1
- package/dist/actions/build/getViteConfig.js +2 -1
- package/dist/actions/build/getViteConfig.js.map +1 -1
- package/dist/actions/build/renderDocument.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js +34 -14
- package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js +2 -2
- package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js.map +1 -1
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +2 -2
- package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
- package/dist/actions/codemods/reactIconsV3.js +2 -2
- package/dist/actions/codemods/reactIconsV3.js.map +1 -1
- package/dist/actions/dev/startStudioDevServer.js +2 -2
- package/dist/actions/dev/startStudioDevServer.js.map +1 -1
- package/dist/actions/doctor/types.js.map +1 -1
- package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +16 -1
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/bootstrapTemplate.js.map +1 -1
- package/dist/actions/init/checkNextJsReactCompatibility.js +3 -3
- package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
- package/dist/actions/init/initAction.js +287 -0
- package/dist/actions/init/initAction.js.map +1 -0
- package/dist/actions/init/initApp.js +63 -0
- package/dist/actions/init/initApp.js.map +1 -0
- package/dist/actions/init/initError.js +10 -0
- package/dist/actions/init/initError.js.map +1 -0
- package/dist/actions/init/initHelpers.js +28 -0
- package/dist/actions/init/initHelpers.js.map +1 -0
- package/dist/actions/init/initNextJs.js +243 -0
- package/dist/actions/init/initNextJs.js.map +1 -0
- package/dist/actions/init/initStudio.js +118 -0
- package/dist/actions/init/initStudio.js.map +1 -0
- package/dist/actions/init/plan/getPlan.js +15 -0
- package/dist/actions/init/plan/getPlan.js.map +1 -0
- package/dist/actions/init/plan/verifyCoupon.js +35 -0
- package/dist/actions/init/plan/verifyCoupon.js.map +1 -0
- package/dist/actions/init/plan/verifyPlan.js +34 -0
- package/dist/actions/init/plan/verifyPlan.js.map +1 -0
- package/dist/actions/init/project/createProjectFromName.js +44 -0
- package/dist/actions/init/project/createProjectFromName.js.map +1 -0
- package/dist/actions/init/project/getOrCreateDataset.js +126 -0
- package/dist/actions/init/project/getOrCreateDataset.js.map +1 -0
- package/dist/actions/init/project/getOrCreateProject.js +128 -0
- package/dist/actions/init/project/getOrCreateProject.js.map +1 -0
- package/dist/actions/init/project/getProjectDetails.js +87 -0
- package/dist/actions/init/project/getProjectDetails.js.map +1 -0
- package/dist/actions/init/project/getProjectOutputPath.js +17 -0
- package/dist/actions/init/project/getProjectOutputPath.js.map +1 -0
- package/dist/actions/init/project/promptForAppTemplateSetup.js +112 -0
- package/dist/actions/init/project/promptForAppTemplateSetup.js.map +1 -0
- package/dist/actions/init/project/promptForProjectCreation.js +40 -0
- package/dist/actions/init/project/promptForProjectCreation.js.map +1 -0
- package/dist/actions/init/project/promptUserForNewOrganization.js +12 -0
- package/dist/actions/init/project/promptUserForNewOrganization.js.map +1 -0
- package/dist/actions/init/project/promptUserForOrganization.js +38 -0
- package/dist/actions/init/project/promptUserForOrganization.js.map +1 -0
- package/dist/actions/init/scaffoldTemplate.js +108 -0
- package/dist/actions/init/scaffoldTemplate.js.map +1 -0
- package/dist/actions/init/templates/appQuickstart.js +2 -1
- package/dist/actions/init/templates/appQuickstart.js.map +1 -1
- package/dist/actions/init/templates/appSanityUi.js +2 -1
- package/dist/actions/init/templates/appSanityUi.js.map +1 -1
- package/dist/actions/init/templates/shopify.js +6 -6
- package/dist/actions/init/templates/shopify.js.map +1 -1
- package/dist/actions/init/templates/shopifyOnline.js +2 -2
- package/dist/actions/init/templates/shopifyOnline.js.map +1 -1
- package/dist/actions/init/types.js +47 -1
- package/dist/actions/init/types.js.map +1 -1
- package/dist/actions/manifest/types.js +0 -1
- package/dist/actions/manifest/types.js.map +1 -1
- package/dist/actions/mcp/detectAvailableEditors.js +16 -3
- package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
- package/dist/actions/mcp/editorConfigs.js +192 -132
- package/dist/actions/mcp/editorConfigs.js.map +1 -1
- package/dist/actions/mcp/setupMCP.js +4 -1
- package/dist/actions/mcp/setupMCP.js.map +1 -1
- package/dist/actions/mcp/writeMCPConfig.js +2 -2
- package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
- package/dist/actions/schema/extractSchema.js +5 -7
- package/dist/actions/schema/extractSchema.js.map +1 -1
- package/dist/actions/versions/buildPackageArray.js +2 -2
- package/dist/actions/versions/buildPackageArray.js.map +1 -1
- package/dist/actions/versions/findSanityModulesVersions.js +3 -3
- package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
- package/dist/commands/datasets/copy.js +14 -0
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/init.js +11 -1244
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp/configure.js +1 -1
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/hooks/prerun/injectEnvVariables.js +3 -5
- package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
- package/dist/server/vite/plugin-sanity-build-entries.js +2 -1
- package/dist/server/vite/plugin-sanity-build-entries.js.map +1 -1
- package/dist/services/datasets.js +2 -1
- package/dist/services/datasets.js.map +1 -1
- package/dist/telemetry/init.telemetry.js.map +1 -1
- package/dist/util/compareDependencyVersions.js +4 -4
- package/dist/util/compareDependencyVersions.js.map +1 -1
- package/dist/util/createExpiringConfig.js +1 -1
- package/dist/util/createExpiringConfig.js.map +1 -1
- package/dist/util/packageManager/installationInfo/analyzeIssues.js +7 -7
- package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -1
- package/dist/util/packageManager/installationInfo/detectPackages.js +13 -7
- package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -1
- package/dist/util/packageManager/installationInfo/types.js.map +1 -1
- package/dist/util/packageManager/packageManagerChoice.js +2 -2
- package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
- package/dist/util/packageManager/preferredPm.js +106 -0
- package/dist/util/packageManager/preferredPm.js.map +1 -0
- package/dist/util/update/fetchUpdateInfo.js +40 -0
- package/dist/util/update/fetchUpdateInfo.js.map +1 -0
- package/dist/util/update/fetchUpdateInfo.worker.js +19 -0
- package/dist/util/update/fetchUpdateInfo.worker.js.map +1 -0
- package/dist/util/update/getRunnerUpdateCommand.js +33 -0
- package/dist/util/update/getRunnerUpdateCommand.js.map +1 -0
- package/dist/util/update/getUpdateCommand.js +6 -7
- package/dist/util/update/getUpdateCommand.js.map +1 -1
- package/dist/util/update/packageRunner.js +10 -0
- package/dist/util/update/packageRunner.js.map +1 -0
- package/dist/util/update/resolveRunnerPackage.js +45 -0
- package/dist/util/update/resolveRunnerPackage.js.map +1 -0
- package/dist/util/update/resolveUpdateTarget.js +31 -0
- package/dist/util/update/resolveUpdateTarget.js.map +1 -0
- package/dist/util/update/showNotificationUpdate.js +8 -6
- package/dist/util/update/showNotificationUpdate.js.map +1 -1
- package/dist/util/update/updateChecker.js +73 -38
- package/dist/util/update/updateChecker.js.map +1 -1
- package/oclif.manifest.json +17 -2
- package/package.json +23 -22
- package/templates/app-quickstart/src/App.tsx +2 -2
- package/templates/app-sanity-ui/src/App.tsx +2 -2
- package/templates/shopify/schemaTypes/objects/hotspot/imageWithProductHotspotsType.ts +1 -1
- package/dist/util/update/fetchLatestVersion.js +0 -21
- package/dist/util/update/fetchLatestVersion.js.map +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const BIN_NAMES = {
|
|
2
|
+
'@sanity/cli': 'sanity',
|
|
3
|
+
sanity: 'sanity'
|
|
4
|
+
};
|
|
5
|
+
export function getRunnerUpdateCommand(runner, packageName) {
|
|
6
|
+
const binName = BIN_NAMES[packageName];
|
|
7
|
+
switch(runner){
|
|
8
|
+
case 'bunx':
|
|
9
|
+
{
|
|
10
|
+
return `bunx ${packageName}@latest`;
|
|
11
|
+
}
|
|
12
|
+
case 'npx':
|
|
13
|
+
{
|
|
14
|
+
return `npx --yes ${packageName}@latest`;
|
|
15
|
+
}
|
|
16
|
+
case 'pnpm-dlx':
|
|
17
|
+
{
|
|
18
|
+
return `pnpm dlx ${packageName}@latest`;
|
|
19
|
+
}
|
|
20
|
+
case 'yarn-dlx':
|
|
21
|
+
{
|
|
22
|
+
// yarn dlx only needs `-p` when the package name differs from the bin name
|
|
23
|
+
return binName === packageName ? `yarn dlx ${packageName}@latest` : `yarn dlx -p ${packageName}@latest ${binName}`;
|
|
24
|
+
}
|
|
25
|
+
default:
|
|
26
|
+
{
|
|
27
|
+
const _exhaustive = runner;
|
|
28
|
+
throw new Error(`Unknown runner: ${_exhaustive}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=getRunnerUpdateCommand.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/update/getRunnerUpdateCommand.ts"],"sourcesContent":["import {type SanityPackage} from '../packageManager/installationInfo/types.js'\nimport {type PackageRunner} from './packageRunner.js'\n\nconst BIN_NAMES: Record<SanityPackage, string> = {\n '@sanity/cli': 'sanity',\n sanity: 'sanity',\n}\n\nexport function getRunnerUpdateCommand(runner: PackageRunner, packageName: SanityPackage): string {\n const binName = BIN_NAMES[packageName]\n\n switch (runner) {\n case 'bunx': {\n return `bunx ${packageName}@latest`\n }\n case 'npx': {\n return `npx --yes ${packageName}@latest`\n }\n case 'pnpm-dlx': {\n return `pnpm dlx ${packageName}@latest`\n }\n case 'yarn-dlx': {\n // yarn dlx only needs `-p` when the package name differs from the bin name\n return binName === packageName\n ? `yarn dlx ${packageName}@latest`\n : `yarn dlx -p ${packageName}@latest ${binName}`\n }\n default: {\n const _exhaustive: never = runner\n throw new Error(`Unknown runner: ${_exhaustive as string}`)\n }\n }\n}\n"],"names":["BIN_NAMES","sanity","getRunnerUpdateCommand","runner","packageName","binName","_exhaustive","Error"],"mappings":"AAGA,MAAMA,YAA2C;IAC/C,eAAe;IACfC,QAAQ;AACV;AAEA,OAAO,SAASC,uBAAuBC,MAAqB,EAAEC,WAA0B;IACtF,MAAMC,UAAUL,SAAS,CAACI,YAAY;IAEtC,OAAQD;QACN,KAAK;YAAQ;gBACX,OAAO,CAAC,KAAK,EAAEC,YAAY,OAAO,CAAC;YACrC;QACA,KAAK;YAAO;gBACV,OAAO,CAAC,UAAU,EAAEA,YAAY,OAAO,CAAC;YAC1C;QACA,KAAK;YAAY;gBACf,OAAO,CAAC,SAAS,EAAEA,YAAY,OAAO,CAAC;YACzC;QACA,KAAK;YAAY;gBACf,2EAA2E;gBAC3E,OAAOC,YAAYD,cACf,CAAC,SAAS,EAAEA,YAAY,OAAO,CAAC,GAChC,CAAC,YAAY,EAAEA,YAAY,QAAQ,EAAEC,SAAS;YACpD;QACA;YAAS;gBACP,MAAMC,cAAqBH;gBAC3B,MAAM,IAAII,MAAM,CAAC,gBAAgB,EAAED,aAAuB;YAC5D;IACF;AACF"}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { getYarnMajorVersion } from '@sanity/cli-core/package-manager';
|
|
2
|
-
export const cliPkgName = 'sanity';
|
|
3
2
|
/**
|
|
4
3
|
* Get the appropriate update command for the package manager
|
|
5
|
-
*/ export function getUpdateCommand(pm) {
|
|
4
|
+
*/ export function getUpdateCommand(pm, packageName) {
|
|
6
5
|
if (pm === 'yarn') {
|
|
7
6
|
const yarnMajor = getYarnMajorVersion();
|
|
8
7
|
const cmd = yarnMajor !== undefined && yarnMajor >= 2 ? 'up' : 'upgrade';
|
|
9
|
-
return `yarn ${cmd} ${
|
|
8
|
+
return `yarn ${cmd} ${packageName}`;
|
|
10
9
|
}
|
|
11
10
|
const localCommands = {
|
|
12
|
-
bun: `bun update ${
|
|
13
|
-
manual: `npm update ${
|
|
14
|
-
npm: `npm update ${
|
|
15
|
-
pnpm: `pnpm update ${
|
|
11
|
+
bun: `bun update ${packageName}`,
|
|
12
|
+
manual: `npm update ${packageName}`,
|
|
13
|
+
npm: `npm update ${packageName}`,
|
|
14
|
+
pnpm: `pnpm update ${packageName}`
|
|
16
15
|
};
|
|
17
16
|
return localCommands[pm];
|
|
18
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/util/update/getUpdateCommand.ts"],"sourcesContent":["import {getYarnMajorVersion} from '@sanity/cli-core/package-manager'\n\nimport {type
|
|
1
|
+
{"version":3,"sources":["../../../src/util/update/getUpdateCommand.ts"],"sourcesContent":["import {getYarnMajorVersion} from '@sanity/cli-core/package-manager'\n\nimport {type SanityPackage} from '../packageManager/installationInfo/types.js'\nimport {type PackageManager} from '../packageManager/packageManagerChoice.js'\n\n/**\n * Get the appropriate update command for the package manager\n */\nexport function getUpdateCommand(pm: PackageManager, packageName: SanityPackage): string {\n if (pm === 'yarn') {\n const yarnMajor = getYarnMajorVersion()\n const cmd = yarnMajor !== undefined && yarnMajor >= 2 ? 'up' : 'upgrade'\n return `yarn ${cmd} ${packageName}`\n }\n\n const localCommands: Record<Exclude<PackageManager, 'yarn'>, string> = {\n bun: `bun update ${packageName}`,\n manual: `npm update ${packageName}`,\n npm: `npm update ${packageName}`,\n pnpm: `pnpm update ${packageName}`,\n }\n return localCommands[pm]\n}\n"],"names":["getYarnMajorVersion","getUpdateCommand","pm","packageName","yarnMajor","cmd","undefined","localCommands","bun","manual","npm","pnpm"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,mCAAkC;AAKpE;;CAEC,GACD,OAAO,SAASC,iBAAiBC,EAAkB,EAAEC,WAA0B;IAC7E,IAAID,OAAO,QAAQ;QACjB,MAAME,YAAYJ;QAClB,MAAMK,MAAMD,cAAcE,aAAaF,aAAa,IAAI,OAAO;QAC/D,OAAO,CAAC,KAAK,EAAEC,IAAI,CAAC,EAAEF,aAAa;IACrC;IAEA,MAAMI,gBAAiE;QACrEC,KAAK,CAAC,WAAW,EAAEL,aAAa;QAChCM,QAAQ,CAAC,WAAW,EAAEN,aAAa;QACnCO,KAAK,CAAC,WAAW,EAAEP,aAAa;QAChCQ,MAAM,CAAC,YAAY,EAAER,aAAa;IACpC;IACA,OAAOI,aAAa,CAACL,GAAG;AAC1B"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function detectPackageRunner(binaryPath = process.argv[1] ?? '') {
|
|
2
|
+
const normalized = binaryPath.replaceAll('\\', '/');
|
|
3
|
+
if (normalized.includes('/_npx/')) return 'npx';
|
|
4
|
+
if (normalized.includes('/pnpm/dlx/')) return 'pnpm-dlx';
|
|
5
|
+
if (normalized.includes('/xfs-') && normalized.includes('/dlx-')) return 'yarn-dlx';
|
|
6
|
+
if (/\/bunx-\d+-/.test(normalized)) return 'bunx';
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=packageRunner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/update/packageRunner.ts"],"sourcesContent":["export type PackageRunner = 'bunx' | 'npx' | 'pnpm-dlx' | 'yarn-dlx'\n\nexport function detectPackageRunner(\n binaryPath: string = process.argv[1] ?? '',\n): PackageRunner | null {\n const normalized = binaryPath.replaceAll('\\\\', '/')\n\n if (normalized.includes('/_npx/')) return 'npx'\n if (normalized.includes('/pnpm/dlx/')) return 'pnpm-dlx'\n if (normalized.includes('/xfs-') && normalized.includes('/dlx-')) return 'yarn-dlx'\n if (/\\/bunx-\\d+-/.test(normalized)) return 'bunx'\n\n return null\n}\n"],"names":["detectPackageRunner","binaryPath","process","argv","normalized","replaceAll","includes","test"],"mappings":"AAEA,OAAO,SAASA,oBACdC,aAAqBC,QAAQC,IAAI,CAAC,EAAE,IAAI,EAAE;IAE1C,MAAMC,aAAaH,WAAWI,UAAU,CAAC,MAAM;IAE/C,IAAID,WAAWE,QAAQ,CAAC,WAAW,OAAO;IAC1C,IAAIF,WAAWE,QAAQ,CAAC,eAAe,OAAO;IAC9C,IAAIF,WAAWE,QAAQ,CAAC,YAAYF,WAAWE,QAAQ,CAAC,UAAU,OAAO;IACzE,IAAI,cAAcC,IAAI,CAACH,aAAa,OAAO;IAE3C,OAAO;AACT"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFile, realpath } from 'node:fs/promises';
|
|
2
|
+
import { dirname, resolve } from 'node:path';
|
|
3
|
+
import { subdebug } from '@sanity/cli-core';
|
|
4
|
+
const debug = subdebug('updateChecker');
|
|
5
|
+
const KNOWN_PACKAGES = new Set([
|
|
6
|
+
'@sanity/cli',
|
|
7
|
+
'sanity'
|
|
8
|
+
]);
|
|
9
|
+
const MAX_WALK_ITERATIONS = 25;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the Sanity package name + installed version from a runner install.
|
|
12
|
+
* Falls back to `sanity` + `fallbackVersion` when the walk can't determine them.
|
|
13
|
+
*/ export async function resolveRunnerPackage(binaryPath = process.argv[1] ?? '', fallbackVersion = '') {
|
|
14
|
+
try {
|
|
15
|
+
// Follow the runner's .bin/sanity symlink to the real bin file, then walk
|
|
16
|
+
// up until we hit a package.json for a known Sanity package.
|
|
17
|
+
let dir = dirname(await realpath(binaryPath));
|
|
18
|
+
for(let i = 0; i < MAX_WALK_ITERATIONS && dir !== resolve(dir, '..'); i++){
|
|
19
|
+
try {
|
|
20
|
+
const pkg = JSON.parse(await readFile(resolve(dir, 'package.json'), 'utf8'));
|
|
21
|
+
if (typeof pkg.name === 'string' && typeof pkg.version === 'string' && isKnownSanityPackage(pkg.name)) {
|
|
22
|
+
return {
|
|
23
|
+
installedVersion: pkg.version,
|
|
24
|
+
packageName: pkg.name
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
} catch {
|
|
28
|
+
// ignore missing/malformed package.json and keep walking
|
|
29
|
+
}
|
|
30
|
+
dir = dirname(dir);
|
|
31
|
+
}
|
|
32
|
+
debug('resolveRunnerPackage: walk exhausted without finding a known Sanity package');
|
|
33
|
+
} catch (err) {
|
|
34
|
+
debug('resolveRunnerPackage: realpath failed for %s (%s)', binaryPath, err);
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
installedVersion: fallbackVersion,
|
|
38
|
+
packageName: 'sanity'
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function isKnownSanityPackage(name) {
|
|
42
|
+
return KNOWN_PACKAGES.has(name);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=resolveRunnerPackage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/update/resolveRunnerPackage.ts"],"sourcesContent":["import {readFile, realpath} from 'node:fs/promises'\nimport {dirname, resolve} from 'node:path'\n\nimport {subdebug} from '@sanity/cli-core'\n\nimport {type SanityPackage} from '../packageManager/installationInfo/types.js'\n\nconst debug = subdebug('updateChecker')\n\nconst KNOWN_PACKAGES = new Set<SanityPackage>(['@sanity/cli', 'sanity'])\nconst MAX_WALK_ITERATIONS = 25\n\ninterface RunnerPackage {\n installedVersion: string\n packageName: SanityPackage\n}\n\n/**\n * Resolve the Sanity package name + installed version from a runner install.\n * Falls back to `sanity` + `fallbackVersion` when the walk can't determine them.\n */\nexport async function resolveRunnerPackage(\n binaryPath: string = process.argv[1] ?? '',\n fallbackVersion = '',\n): Promise<RunnerPackage> {\n try {\n // Follow the runner's .bin/sanity symlink to the real bin file, then walk\n // up until we hit a package.json for a known Sanity package.\n let dir = dirname(await realpath(binaryPath))\n for (let i = 0; i < MAX_WALK_ITERATIONS && dir !== resolve(dir, '..'); i++) {\n try {\n const pkg = JSON.parse(await readFile(resolve(dir, 'package.json'), 'utf8'))\n if (\n typeof pkg.name === 'string' &&\n typeof pkg.version === 'string' &&\n isKnownSanityPackage(pkg.name)\n ) {\n return {installedVersion: pkg.version, packageName: pkg.name}\n }\n } catch {\n // ignore missing/malformed package.json and keep walking\n }\n dir = dirname(dir)\n }\n debug('resolveRunnerPackage: walk exhausted without finding a known Sanity package')\n } catch (err) {\n debug('resolveRunnerPackage: realpath failed for %s (%s)', binaryPath, err)\n }\n\n return {installedVersion: fallbackVersion, packageName: 'sanity'}\n}\n\nfunction isKnownSanityPackage(name: string): name is SanityPackage {\n return KNOWN_PACKAGES.has(name as SanityPackage)\n}\n"],"names":["readFile","realpath","dirname","resolve","subdebug","debug","KNOWN_PACKAGES","Set","MAX_WALK_ITERATIONS","resolveRunnerPackage","binaryPath","process","argv","fallbackVersion","dir","i","pkg","JSON","parse","name","version","isKnownSanityPackage","installedVersion","packageName","err","has"],"mappings":"AAAA,SAAQA,QAAQ,EAAEC,QAAQ,QAAO,mBAAkB;AACnD,SAAQC,OAAO,EAAEC,OAAO,QAAO,YAAW;AAE1C,SAAQC,QAAQ,QAAO,mBAAkB;AAIzC,MAAMC,QAAQD,SAAS;AAEvB,MAAME,iBAAiB,IAAIC,IAAmB;IAAC;IAAe;CAAS;AACvE,MAAMC,sBAAsB;AAO5B;;;CAGC,GACD,OAAO,eAAeC,qBACpBC,aAAqBC,QAAQC,IAAI,CAAC,EAAE,IAAI,EAAE,EAC1CC,kBAAkB,EAAE;IAEpB,IAAI;QACF,0EAA0E;QAC1E,6DAA6D;QAC7D,IAAIC,MAAMZ,QAAQ,MAAMD,SAASS;QACjC,IAAK,IAAIK,IAAI,GAAGA,IAAIP,uBAAuBM,QAAQX,QAAQW,KAAK,OAAOC,IAAK;YAC1E,IAAI;gBACF,MAAMC,MAAMC,KAAKC,KAAK,CAAC,MAAMlB,SAASG,QAAQW,KAAK,iBAAiB;gBACpE,IACE,OAAOE,IAAIG,IAAI,KAAK,YACpB,OAAOH,IAAII,OAAO,KAAK,YACvBC,qBAAqBL,IAAIG,IAAI,GAC7B;oBACA,OAAO;wBAACG,kBAAkBN,IAAII,OAAO;wBAAEG,aAAaP,IAAIG,IAAI;oBAAA;gBAC9D;YACF,EAAE,OAAM;YACN,yDAAyD;YAC3D;YACAL,MAAMZ,QAAQY;QAChB;QACAT,MAAM;IACR,EAAE,OAAOmB,KAAK;QACZnB,MAAM,qDAAqDK,YAAYc;IACzE;IAEA,OAAO;QAACF,kBAAkBT;QAAiBU,aAAa;IAAQ;AAClE;AAEA,SAASF,qBAAqBF,IAAY;IACxC,OAAOb,eAAemB,GAAG,CAACN;AAC5B"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { subdebug } from '@sanity/cli-core';
|
|
2
|
+
import { findInstalledPackage, findPackageDeclaration } from '../packageManager/installationInfo/detectPackages.js';
|
|
3
|
+
const debug = subdebug('updateChecker');
|
|
4
|
+
/**
|
|
5
|
+
* Determine which package to check for updates and what version is currently installed.
|
|
6
|
+
*
|
|
7
|
+
* If the user's project declares `sanity` as a dependency and it's installed,
|
|
8
|
+
* we check `sanity` (since that's what the user manages). Otherwise, we fall back
|
|
9
|
+
* to `@sanity/cli` (the currently running CLI binary).
|
|
10
|
+
*/ export async function resolveUpdateTarget(cwd, cliVersion) {
|
|
11
|
+
// Check if `sanity` is a dependency in the local project
|
|
12
|
+
const sanityDeclaration = await findPackageDeclaration('sanity', cwd);
|
|
13
|
+
if (sanityDeclaration) {
|
|
14
|
+
debug('Project declares sanity as a dependency, checking installed version');
|
|
15
|
+
const sanityInstalled = await findInstalledPackage('sanity', cwd);
|
|
16
|
+
if (sanityInstalled) {
|
|
17
|
+
debug('Installed sanity version: %s', sanityInstalled.version);
|
|
18
|
+
return {
|
|
19
|
+
installedVersion: sanityInstalled.version,
|
|
20
|
+
packageName: 'sanity'
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
debug('sanity is declared but not installed, falling back to @sanity/cli');
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
installedVersion: cliVersion,
|
|
27
|
+
packageName: '@sanity/cli'
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//# sourceMappingURL=resolveUpdateTarget.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/util/update/resolveUpdateTarget.ts"],"sourcesContent":["import {subdebug} from '@sanity/cli-core'\n\nimport {\n findInstalledPackage,\n findPackageDeclaration,\n} from '../packageManager/installationInfo/detectPackages.js'\nimport {type SanityPackage} from '../packageManager/installationInfo/types.js'\n\nconst debug = subdebug('updateChecker')\n\ninterface UpdateTarget {\n installedVersion: string\n packageName: SanityPackage\n}\n\n/**\n * Determine which package to check for updates and what version is currently installed.\n *\n * If the user's project declares `sanity` as a dependency and it's installed,\n * we check `sanity` (since that's what the user manages). Otherwise, we fall back\n * to `@sanity/cli` (the currently running CLI binary).\n */\nexport async function resolveUpdateTarget(cwd: string, cliVersion: string): Promise<UpdateTarget> {\n // Check if `sanity` is a dependency in the local project\n const sanityDeclaration = await findPackageDeclaration('sanity', cwd)\n\n if (sanityDeclaration) {\n debug('Project declares sanity as a dependency, checking installed version')\n const sanityInstalled = await findInstalledPackage('sanity', cwd)\n\n if (sanityInstalled) {\n debug('Installed sanity version: %s', sanityInstalled.version)\n return {installedVersion: sanityInstalled.version, packageName: 'sanity'}\n }\n\n debug('sanity is declared but not installed, falling back to @sanity/cli')\n }\n\n return {installedVersion: cliVersion, packageName: '@sanity/cli'}\n}\n"],"names":["subdebug","findInstalledPackage","findPackageDeclaration","debug","resolveUpdateTarget","cwd","cliVersion","sanityDeclaration","sanityInstalled","version","installedVersion","packageName"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,mBAAkB;AAEzC,SACEC,oBAAoB,EACpBC,sBAAsB,QACjB,uDAAsD;AAG7D,MAAMC,QAAQH,SAAS;AAOvB;;;;;;CAMC,GACD,OAAO,eAAeI,oBAAoBC,GAAW,EAAEC,UAAkB;IACvE,yDAAyD;IACzD,MAAMC,oBAAoB,MAAML,uBAAuB,UAAUG;IAEjE,IAAIE,mBAAmB;QACrBJ,MAAM;QACN,MAAMK,kBAAkB,MAAMP,qBAAqB,UAAUI;QAE7D,IAAIG,iBAAiB;YACnBL,MAAM,gCAAgCK,gBAAgBC,OAAO;YAC7D,OAAO;gBAACC,kBAAkBF,gBAAgBC,OAAO;gBAAEE,aAAa;YAAQ;QAC1E;QAEAR,MAAM;IACR;IAEA,OAAO;QAACO,kBAAkBJ;QAAYK,aAAa;IAAa;AAClE"}
|
|
@@ -3,20 +3,22 @@ import { ux } from '@oclif/core';
|
|
|
3
3
|
import { boxen } from '@sanity/cli-core/ux';
|
|
4
4
|
import isInstalledGlobally from 'is-installed-globally';
|
|
5
5
|
import { getPackageManagerChoice } from '../packageManager/packageManagerChoice.js';
|
|
6
|
-
import {
|
|
6
|
+
import { getRunnerUpdateCommand } from './getRunnerUpdateCommand.js';
|
|
7
|
+
import { getUpdateCommand } from './getUpdateCommand.js';
|
|
7
8
|
import { isInstalledUsingYarn } from './isInstalledUsingYarn.js';
|
|
8
9
|
/**
|
|
9
10
|
* Show a boxed notification about the available update
|
|
10
|
-
*/ export async function showUpdateNotification(currentVersion, latestVersion) {
|
|
11
|
+
*/ export async function showUpdateNotification(currentVersion, latestVersion, packageName, runner = null) {
|
|
11
12
|
let command;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
if (runner) {
|
|
14
|
+
command = getRunnerUpdateCommand(runner, packageName);
|
|
15
|
+
} else if (isInstalledGlobally) {
|
|
16
|
+
command = isInstalledUsingYarn() ? `yarn global add ${packageName}` : `npm install -g ${packageName}`;
|
|
15
17
|
} else {
|
|
16
18
|
const { chosen } = await getPackageManagerChoice(process.cwd(), {
|
|
17
19
|
interactive: false
|
|
18
20
|
});
|
|
19
|
-
command = getUpdateCommand(chosen);
|
|
21
|
+
command = getUpdateCommand(chosen, packageName);
|
|
20
22
|
}
|
|
21
23
|
const message = `Update available: ${styleText('dim', currentVersion)} → ${styleText('green', latestVersion)}\n\nRun ${styleText('cyan', command)} to update`;
|
|
22
24
|
const boxed = boxen(message, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/util/update/showNotificationUpdate.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {ux} from '@oclif/core'\nimport {boxen} from '@sanity/cli-core/ux'\nimport isInstalledGlobally from 'is-installed-globally'\n\nimport {getPackageManagerChoice} from '../packageManager/packageManagerChoice.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/util/update/showNotificationUpdate.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {ux} from '@oclif/core'\nimport {boxen} from '@sanity/cli-core/ux'\nimport isInstalledGlobally from 'is-installed-globally'\n\nimport {type SanityPackage} from '../packageManager/installationInfo/types.js'\nimport {getPackageManagerChoice} from '../packageManager/packageManagerChoice.js'\nimport {getRunnerUpdateCommand} from './getRunnerUpdateCommand.js'\nimport {getUpdateCommand} from './getUpdateCommand.js'\nimport {isInstalledUsingYarn} from './isInstalledUsingYarn.js'\nimport {type PackageRunner} from './packageRunner.js'\n\n/**\n * Show a boxed notification about the available update\n */\nexport async function showUpdateNotification(\n currentVersion: string,\n latestVersion: string,\n packageName: SanityPackage,\n runner: PackageRunner | null = null,\n): Promise<void> {\n let command\n\n if (runner) {\n command = getRunnerUpdateCommand(runner, packageName)\n } else if (isInstalledGlobally) {\n command = isInstalledUsingYarn()\n ? `yarn global add ${packageName}`\n : `npm install -g ${packageName}`\n } else {\n const {chosen} = await getPackageManagerChoice(process.cwd(), {interactive: false})\n command = getUpdateCommand(chosen, packageName)\n }\n\n const message = `Update available: ${styleText('dim', currentVersion)} → ${styleText('green', latestVersion)}\\n\\nRun ${styleText('cyan', command)} to update`\n\n const boxed = boxen(message, {\n borderColor: 'yellow',\n borderStyle: 'round',\n margin: 1,\n padding: 1,\n })\n\n ux.stderr('\\n' + boxed + '\\n')\n}\n"],"names":["styleText","ux","boxen","isInstalledGlobally","getPackageManagerChoice","getRunnerUpdateCommand","getUpdateCommand","isInstalledUsingYarn","showUpdateNotification","currentVersion","latestVersion","packageName","runner","command","chosen","process","cwd","interactive","message","boxed","borderColor","borderStyle","margin","padding","stderr"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,EAAE,QAAO,cAAa;AAC9B,SAAQC,KAAK,QAAO,sBAAqB;AACzC,OAAOC,yBAAyB,wBAAuB;AAGvD,SAAQC,uBAAuB,QAAO,4CAA2C;AACjF,SAAQC,sBAAsB,QAAO,8BAA6B;AAClE,SAAQC,gBAAgB,QAAO,wBAAuB;AACtD,SAAQC,oBAAoB,QAAO,4BAA2B;AAG9D;;CAEC,GACD,OAAO,eAAeC,uBACpBC,cAAsB,EACtBC,aAAqB,EACrBC,WAA0B,EAC1BC,SAA+B,IAAI;IAEnC,IAAIC;IAEJ,IAAID,QAAQ;QACVC,UAAUR,uBAAuBO,QAAQD;IAC3C,OAAO,IAAIR,qBAAqB;QAC9BU,UAAUN,yBACN,CAAC,gBAAgB,EAAEI,aAAa,GAChC,CAAC,eAAe,EAAEA,aAAa;IACrC,OAAO;QACL,MAAM,EAACG,MAAM,EAAC,GAAG,MAAMV,wBAAwBW,QAAQC,GAAG,IAAI;YAACC,aAAa;QAAK;QACjFJ,UAAUP,iBAAiBQ,QAAQH;IACrC;IAEA,MAAMO,UAAU,CAAC,kBAAkB,EAAElB,UAAU,OAAOS,gBAAgB,GAAG,EAAET,UAAU,SAASU,eAAe,QAAQ,EAAEV,UAAU,QAAQa,SAAS,UAAU,CAAC;IAE7J,MAAMM,QAAQjB,MAAMgB,SAAS;QAC3BE,aAAa;QACbC,aAAa;QACbC,QAAQ;QACRC,SAAS;IACX;IAEAtB,GAAGuB,MAAM,CAAC,OAAOL,QAAQ;AAC3B"}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
1
3
|
import { getUserConfig, isCi, subdebug } from '@sanity/cli-core';
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { gt as semverGt } from 'semver';
|
|
5
|
+
import { detectPackageRunner } from './packageRunner.js';
|
|
6
|
+
import { resolveRunnerPackage } from './resolveRunnerPackage.js';
|
|
7
|
+
import { resolveUpdateTarget } from './resolveUpdateTarget.js';
|
|
5
8
|
import { showUpdateNotification } from './showNotificationUpdate.js';
|
|
6
9
|
const debug = subdebug('updateChecker');
|
|
7
|
-
const TWELVE_HOURS = 12 * 60 * 60 * 1000
|
|
8
|
-
;
|
|
9
|
-
const CHECK_TIMEOUT = 300;
|
|
10
|
+
const TWELVE_HOURS = 12 * 60 * 60 * 1000;
|
|
10
11
|
/**
|
|
11
12
|
* Check for CLI updates and notify the user if a new version is available.
|
|
12
|
-
* This is designed to be non-blocking and will silently fail if anything goes wrong.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
14
|
+
* The main process resolves the local update target (which package and installed version),
|
|
15
|
+
* then reads the latest version from the config cache. It never makes network requests.
|
|
16
|
+
* If the cache is empty or expired, a detached worker process is spawned to fetch the
|
|
17
|
+
* latest version from npm and write it to the cache. The notification is shown on the
|
|
18
|
+
* next CLI invocation when the cached result is available instantly.
|
|
15
19
|
*/ export async function updateChecker(config) {
|
|
16
20
|
debug(`Installed CLI version is ${config.version}`);
|
|
17
21
|
// Skip in CI or if disabled
|
|
@@ -22,39 +26,70 @@ const CHECK_TIMEOUT = 300;
|
|
|
22
26
|
if (!process.stdout.isTTY) {
|
|
23
27
|
return;
|
|
24
28
|
}
|
|
29
|
+
const runner = detectPackageRunner();
|
|
30
|
+
const { installedVersion, packageName } = runner ? await resolveRunnerPackage(process.argv[1] ?? '', config.version) : await resolveUpdateTarget(process.cwd(), config.version);
|
|
31
|
+
debug('Update target: %s@%s%s', packageName, installedVersion, runner ? ` via ${runner}` : '');
|
|
25
32
|
const store = getUserConfig();
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (comparison === 0) {
|
|
51
|
-
debug('No update found');
|
|
52
|
-
return;
|
|
33
|
+
const cacheKey = `latestVersion:${packageName}`;
|
|
34
|
+
const cached = readCachedLatestVersion(store, cacheKey);
|
|
35
|
+
if (cached) {
|
|
36
|
+
const { expired, latestVersion, updatedAt } = cached;
|
|
37
|
+
debug('Cache %s for %s: installed=%s, latest=%s', expired ? 'expired' : 'hit', packageName, installedVersion, latestVersion);
|
|
38
|
+
if (semverGt(latestVersion, installedVersion)) {
|
|
39
|
+
const notifiedKey = `notifiedAt:${packageName}`;
|
|
40
|
+
if (store.get(notifiedKey) === updatedAt) {
|
|
41
|
+
debug('Update is available (%s), already notified for this cache cycle', latestVersion);
|
|
42
|
+
} else {
|
|
43
|
+
debug('Update is available (%s)', latestVersion);
|
|
44
|
+
await showUpdateNotification(installedVersion, latestVersion, packageName, runner);
|
|
45
|
+
store.set(notifiedKey, updatedAt);
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
debug('No update found');
|
|
49
|
+
}
|
|
50
|
+
if (expired) {
|
|
51
|
+
debug('Cache expired, spawning worker to refresh');
|
|
52
|
+
spawnFetchWorker(config.version, packageName);
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
debug('No cached update info, spawning worker to fetch');
|
|
56
|
+
spawnFetchWorker(config.version, packageName);
|
|
53
57
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Read and validate the cached latest version for a specific package.
|
|
61
|
+
* The cache only stores the latest npm version (globally valid) - the installed
|
|
62
|
+
* version is always resolved locally to avoid cross-project confusion.
|
|
63
|
+
*/ function readCachedLatestVersion(store, cacheKey) {
|
|
64
|
+
const stored = store.get(cacheKey);
|
|
65
|
+
if (!stored || typeof stored !== 'object' || !('updatedAt' in stored) || typeof stored.updatedAt !== 'number' || !('value' in stored) || typeof stored.value !== 'string') {
|
|
66
|
+
return null;
|
|
57
67
|
}
|
|
68
|
+
const expired = Date.now() - stored.updatedAt > TWELVE_HOURS;
|
|
69
|
+
return {
|
|
70
|
+
expired,
|
|
71
|
+
latestVersion: stored.value,
|
|
72
|
+
updatedAt: stored.updatedAt
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Spawn a detached worker process to fetch the latest version and update the cache.
|
|
77
|
+
* The worker is unref'd so the parent CLI can exit immediately.
|
|
78
|
+
*/ function spawnFetchWorker(cliVersion, packageName) {
|
|
79
|
+
const workerPath = fileURLToPath(new URL('fetchUpdateInfo.worker.js', import.meta.url));
|
|
80
|
+
debug(`Spawning update check worker: ${process.execPath} ${workerPath}`);
|
|
81
|
+
spawn(process.execPath, [
|
|
82
|
+
workerPath
|
|
83
|
+
], {
|
|
84
|
+
detached: true,
|
|
85
|
+
env: {
|
|
86
|
+
...process.env,
|
|
87
|
+
SANITY_UPDATE_CHECK_CLI_VERSION: cliVersion,
|
|
88
|
+
SANITY_UPDATE_CHECK_CWD: process.cwd(),
|
|
89
|
+
SANITY_UPDATE_CHECK_PACKAGE: packageName
|
|
90
|
+
},
|
|
91
|
+
stdio: debug.enabled ? 'inherit' : 'ignore'
|
|
92
|
+
}).unref();
|
|
58
93
|
}
|
|
59
94
|
|
|
60
95
|
//# sourceMappingURL=updateChecker.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/util/update/updateChecker.ts"],"sourcesContent":["import {getUserConfig, isCi, subdebug} from '@sanity/cli-core'\nimport
|
|
1
|
+
{"version":3,"sources":["../../../src/util/update/updateChecker.ts"],"sourcesContent":["import {spawn} from 'node:child_process'\nimport {fileURLToPath} from 'node:url'\n\nimport {getUserConfig, isCi, subdebug} from '@sanity/cli-core'\nimport {gt as semverGt} from 'semver'\n\nimport {type SanityPackage} from '../packageManager/installationInfo/types.js'\nimport {detectPackageRunner} from './packageRunner.js'\nimport {resolveRunnerPackage} from './resolveRunnerPackage.js'\nimport {resolveUpdateTarget} from './resolveUpdateTarget.js'\nimport {showUpdateNotification} from './showNotificationUpdate.js'\n\nconst debug = subdebug('updateChecker')\n\nconst TWELVE_HOURS = 12 * 60 * 60 * 1000\n\n/**\n * Check for CLI updates and notify the user if a new version is available.\n *\n * The main process resolves the local update target (which package and installed version),\n * then reads the latest version from the config cache. It never makes network requests.\n * If the cache is empty or expired, a detached worker process is spawned to fetch the\n * latest version from npm and write it to the cache. The notification is shown on the\n * next CLI invocation when the cached result is available instantly.\n */\nexport async function updateChecker(config: {version: string}): Promise<void> {\n debug(`Installed CLI version is ${config.version}`)\n\n // Skip in CI or if disabled\n if (isCi() || process.env.NO_UPDATE_NOTIFIER) {\n debug('Running on CI, or explicitly disabled, skipping update check')\n return\n }\n\n if (!process.stdout.isTTY) {\n return\n }\n\n const runner = detectPackageRunner()\n const {installedVersion, packageName} = runner\n ? await resolveRunnerPackage(process.argv[1] ?? '', config.version)\n : await resolveUpdateTarget(process.cwd(), config.version)\n debug('Update target: %s@%s%s', packageName, installedVersion, runner ? ` via ${runner}` : '')\n\n const store = getUserConfig()\n const cacheKey = `latestVersion:${packageName}`\n const cached = readCachedLatestVersion(store, cacheKey)\n\n if (cached) {\n const {expired, latestVersion, updatedAt} = cached\n\n debug(\n 'Cache %s for %s: installed=%s, latest=%s',\n expired ? 'expired' : 'hit',\n packageName,\n installedVersion,\n latestVersion,\n )\n\n if (semverGt(latestVersion, installedVersion)) {\n const notifiedKey = `notifiedAt:${packageName}`\n if (store.get(notifiedKey) === updatedAt) {\n debug('Update is available (%s), already notified for this cache cycle', latestVersion)\n } else {\n debug('Update is available (%s)', latestVersion)\n await showUpdateNotification(installedVersion, latestVersion, packageName, runner)\n store.set(notifiedKey, updatedAt)\n }\n } else {\n debug('No update found')\n }\n\n if (expired) {\n debug('Cache expired, spawning worker to refresh')\n spawnFetchWorker(config.version, packageName)\n }\n } else {\n debug('No cached update info, spawning worker to fetch')\n spawnFetchWorker(config.version, packageName)\n }\n}\n\n/**\n * Read and validate the cached latest version for a specific package.\n * The cache only stores the latest npm version (globally valid) - the installed\n * version is always resolved locally to avoid cross-project confusion.\n */\nfunction readCachedLatestVersion(\n store: ReturnType<typeof getUserConfig>,\n cacheKey: string,\n): {expired: boolean; latestVersion: string; updatedAt: number} | null {\n const stored: unknown = store.get(cacheKey)\n\n if (\n !stored ||\n typeof stored !== 'object' ||\n !('updatedAt' in stored) ||\n typeof stored.updatedAt !== 'number' ||\n !('value' in stored) ||\n typeof stored.value !== 'string'\n ) {\n return null\n }\n\n const expired = Date.now() - stored.updatedAt > TWELVE_HOURS\n return {expired, latestVersion: stored.value, updatedAt: stored.updatedAt}\n}\n\n/**\n * Spawn a detached worker process to fetch the latest version and update the cache.\n * The worker is unref'd so the parent CLI can exit immediately.\n */\nfunction spawnFetchWorker(cliVersion: string, packageName: SanityPackage): void {\n const workerPath = fileURLToPath(new URL('fetchUpdateInfo.worker.js', import.meta.url))\n debug(`Spawning update check worker: ${process.execPath} ${workerPath}`)\n\n spawn(process.execPath, [workerPath], {\n detached: true,\n env: {\n ...process.env,\n SANITY_UPDATE_CHECK_CLI_VERSION: cliVersion,\n SANITY_UPDATE_CHECK_CWD: process.cwd(),\n SANITY_UPDATE_CHECK_PACKAGE: packageName,\n },\n stdio: debug.enabled ? 'inherit' : 'ignore',\n }).unref()\n}\n"],"names":["spawn","fileURLToPath","getUserConfig","isCi","subdebug","gt","semverGt","detectPackageRunner","resolveRunnerPackage","resolveUpdateTarget","showUpdateNotification","debug","TWELVE_HOURS","updateChecker","config","version","process","env","NO_UPDATE_NOTIFIER","stdout","isTTY","runner","installedVersion","packageName","argv","cwd","store","cacheKey","cached","readCachedLatestVersion","expired","latestVersion","updatedAt","notifiedKey","get","set","spawnFetchWorker","stored","value","Date","now","cliVersion","workerPath","URL","url","execPath","detached","SANITY_UPDATE_CHECK_CLI_VERSION","SANITY_UPDATE_CHECK_CWD","SANITY_UPDATE_CHECK_PACKAGE","stdio","enabled","unref"],"mappings":"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"}
|
package/oclif.manifest.json
CHANGED
|
@@ -1454,6 +1454,10 @@
|
|
|
1454
1454
|
"command": "<%= config.bin %> <%= command.id %> --skip-history source target",
|
|
1455
1455
|
"description": "Copy without preserving document history (faster for large datasets)"
|
|
1456
1456
|
},
|
|
1457
|
+
{
|
|
1458
|
+
"command": "<%= config.bin %> <%= command.id %> --skip-content-releases source target",
|
|
1459
|
+
"description": "Copy without content release documents"
|
|
1460
|
+
},
|
|
1457
1461
|
{
|
|
1458
1462
|
"command": "<%= config.bin %> <%= command.id %> --detach source target",
|
|
1459
1463
|
"description": "Start copy job without waiting for completion"
|
|
@@ -1540,6 +1544,17 @@
|
|
|
1540
1544
|
"multiple": false,
|
|
1541
1545
|
"type": "option"
|
|
1542
1546
|
},
|
|
1547
|
+
"skip-content-releases": {
|
|
1548
|
+
"description": "Don't copy content release documents to the target dataset",
|
|
1549
|
+
"exclusive": [
|
|
1550
|
+
"list",
|
|
1551
|
+
"attach"
|
|
1552
|
+
],
|
|
1553
|
+
"name": "skip-content-releases",
|
|
1554
|
+
"required": false,
|
|
1555
|
+
"allowNo": false,
|
|
1556
|
+
"type": "boolean"
|
|
1557
|
+
},
|
|
1543
1558
|
"skip-history": {
|
|
1544
1559
|
"description": "Don't preserve document history on copy",
|
|
1545
1560
|
"exclusive": [
|
|
@@ -3155,7 +3170,7 @@
|
|
|
3155
3170
|
"mcp:configure": {
|
|
3156
3171
|
"aliases": [],
|
|
3157
3172
|
"args": {},
|
|
3158
|
-
"description": "Configure Sanity MCP server for AI editors (Claude Code, Codex CLI, Cursor, Gemini CLI, GitHub Copilot CLI, VS Code)",
|
|
3173
|
+
"description": "Configure Sanity MCP server for AI editors (Antigravity, Claude Code, Cline, Cline CLI, Codex CLI, Cursor, Gemini CLI, GitHub Copilot CLI, MCPorter, OpenCode, VS Code, VS Code Insiders, Zed)",
|
|
3159
3174
|
"examples": [
|
|
3160
3175
|
{
|
|
3161
3176
|
"command": "<%= config.bin %> <%= command.id %>",
|
|
@@ -5067,5 +5082,5 @@
|
|
|
5067
5082
|
]
|
|
5068
5083
|
}
|
|
5069
5084
|
},
|
|
5070
|
-
"version": "6.
|
|
5085
|
+
"version": "6.5.0"
|
|
5071
5086
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/cli",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.0",
|
|
4
4
|
"description": "Sanity CLI tool for managing Sanity projects and organizations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -52,22 +52,22 @@
|
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@oclif/core": "^4.10.
|
|
56
|
-
"@oclif/plugin-help": "^6.2.
|
|
57
|
-
"@oclif/plugin-not-found": "^3.2.
|
|
58
|
-
"@sanity/client": "^7.
|
|
59
|
-
"@sanity/codegen": "^6.0.
|
|
55
|
+
"@oclif/core": "^4.10.6",
|
|
56
|
+
"@oclif/plugin-help": "^6.2.45",
|
|
57
|
+
"@oclif/plugin-not-found": "^3.2.81",
|
|
58
|
+
"@sanity/client": "^7.22.0",
|
|
59
|
+
"@sanity/codegen": "^6.0.3",
|
|
60
60
|
"@sanity/descriptors": "^1.3.0",
|
|
61
61
|
"@sanity/export": "^6.1.0",
|
|
62
62
|
"@sanity/generate-help-url": "^4.0.0",
|
|
63
63
|
"@sanity/id-utils": "^1.0.0",
|
|
64
64
|
"@sanity/import": "^6.0.1",
|
|
65
|
-
"@sanity/migrate": "^6.1.
|
|
66
|
-
"@sanity/runtime-cli": "^14.
|
|
67
|
-
"@sanity/schema": "^5.
|
|
65
|
+
"@sanity/migrate": "^6.1.2",
|
|
66
|
+
"@sanity/runtime-cli": "^14.13.4",
|
|
67
|
+
"@sanity/schema": "^5.23.0",
|
|
68
68
|
"@sanity/telemetry": "^0.9.0",
|
|
69
69
|
"@sanity/template-validator": "^3.1.0",
|
|
70
|
-
"@sanity/types": "^5.
|
|
70
|
+
"@sanity/types": "^5.23.0",
|
|
71
71
|
"@sanity/ui": "^3.1.14",
|
|
72
72
|
"@sanity/worker-channels": "^2.0.0",
|
|
73
73
|
"@vercel/frameworks": "3.21.1",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"execa": "^9.6.0",
|
|
82
82
|
"form-data": "^4.0.5",
|
|
83
83
|
"get-latest-version": "^6.0.1",
|
|
84
|
-
"groq-js": "^1.
|
|
84
|
+
"groq-js": "^1.30.1",
|
|
85
85
|
"gunzip-maybe": "^1.4.2",
|
|
86
86
|
"import-meta-resolve": "^4.2.0",
|
|
87
87
|
"is-installed-globally": "^1.0.0",
|
|
@@ -99,7 +99,6 @@
|
|
|
99
99
|
"peek-stream": "^1.1.3",
|
|
100
100
|
"picomatch": "^4.0.4",
|
|
101
101
|
"pluralize-esm": "^9.0.5",
|
|
102
|
-
"preferred-pm": "^5.0.0",
|
|
103
102
|
"pretty-ms": "^9.3.0",
|
|
104
103
|
"promise-props-recursive": "^2.0.2",
|
|
105
104
|
"react": "^19.2.4",
|
|
@@ -122,16 +121,17 @@
|
|
|
122
121
|
"@sanity/cli-core": "^1.3.1"
|
|
123
122
|
},
|
|
124
123
|
"devDependencies": {
|
|
125
|
-
"@eslint/compat": "^2.0.
|
|
126
|
-
"@sanity/pkg-utils": "^10.4.
|
|
124
|
+
"@eslint/compat": "^2.0.5",
|
|
125
|
+
"@sanity/pkg-utils": "^10.4.18",
|
|
127
126
|
"@swc/cli": "^0.8.1",
|
|
128
|
-
"@swc/core": "^1.15.
|
|
127
|
+
"@swc/core": "^1.15.30",
|
|
129
128
|
"@types/debug": "^4.1.13",
|
|
130
129
|
"@types/gunzip-maybe": "^1.4.3",
|
|
130
|
+
"@types/jsdom": "^28.0.1",
|
|
131
131
|
"@types/lodash-es": "^4.17.12",
|
|
132
132
|
"@types/minimist": "^1.2.5",
|
|
133
133
|
"@types/node": "^20.19.39",
|
|
134
|
-
"@types/picomatch": "^4.0.
|
|
134
|
+
"@types/picomatch": "^4.0.3",
|
|
135
135
|
"@types/react": "^19.2.14",
|
|
136
136
|
"@types/react-dom": "^19.2.3",
|
|
137
137
|
"@types/react-is": "^19.2.0",
|
|
@@ -139,21 +139,22 @@
|
|
|
139
139
|
"@types/tar-fs": "^2.0.4",
|
|
140
140
|
"@types/tar-stream": "^3.1.4",
|
|
141
141
|
"@types/which": "^3.0.4",
|
|
142
|
-
"@vitest/coverage-istanbul": "^4.1.
|
|
142
|
+
"@vitest/coverage-istanbul": "^4.1.5",
|
|
143
143
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
144
|
-
"eslint": "^10.1
|
|
144
|
+
"eslint": "^10.2.1",
|
|
145
|
+
"jsdom": "^29.0.2",
|
|
145
146
|
"nock": "^14.0.12",
|
|
146
147
|
"oclif": "^4.23.0",
|
|
147
148
|
"publint": "^0.3.18",
|
|
148
149
|
"rimraf": "^6.0.1",
|
|
149
|
-
"sanity": "^5.
|
|
150
|
+
"sanity": "^5.23.0",
|
|
150
151
|
"typescript": "^5.9.3",
|
|
151
152
|
"vite-tsconfig-paths": "^6.1.1",
|
|
152
|
-
"vitest": "^4.1.
|
|
153
|
+
"vitest": "^4.1.5",
|
|
153
154
|
"@repo/package.config": "0.0.1",
|
|
154
155
|
"@repo/tsconfig": "3.70.0",
|
|
155
|
-
"@sanity/cli
|
|
156
|
-
"@sanity/
|
|
156
|
+
"@sanity/eslint-config-cli": "1.1.1",
|
|
157
|
+
"@sanity/cli-test": "0.3.2"
|
|
157
158
|
},
|
|
158
159
|
"engines": {
|
|
159
160
|
"node": ">=20.19.1 <22 || >=22.12"
|
|
@@ -38,7 +38,7 @@ export const imageWithProductHotspotsType = defineField({
|
|
|
38
38
|
return {
|
|
39
39
|
media: image,
|
|
40
40
|
subtitle:
|
|
41
|
-
showHotspots && hotspots.length > 0
|
|
41
|
+
showHotspots && hotspots && hotspots.length > 0
|
|
42
42
|
? `${pluralize('hotspot', hotspots.length, true)}`
|
|
43
43
|
: undefined,
|
|
44
44
|
title: fileName,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { subdebug } from '@sanity/cli-core';
|
|
2
|
-
import { getLatestVersion } from 'get-latest-version';
|
|
3
|
-
import { promiseRaceWithTimeout } from '../promiseRaceWithTimeout.js';
|
|
4
|
-
const debug = subdebug('updateChecker');
|
|
5
|
-
/**
|
|
6
|
-
* Fetch the latest version from npm with a timeout
|
|
7
|
-
*/ export async function fetchLatestVersion(packageName, timeout) {
|
|
8
|
-
try {
|
|
9
|
-
const result = await promiseRaceWithTimeout(getLatestVersion(packageName), timeout);
|
|
10
|
-
if (result === null) {
|
|
11
|
-
debug(`Max time ${timeout} reached waiting for latest version info`);
|
|
12
|
-
}
|
|
13
|
-
debug('Latest remote version is %s', result);
|
|
14
|
-
return result;
|
|
15
|
-
} catch (err) {
|
|
16
|
-
debug(`Failed to fetch latest version of ${packageName} from npm:\n${err instanceof Error ? err.stack : String(err)}`);
|
|
17
|
-
throw err;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
//# sourceMappingURL=fetchLatestVersion.js.map
|