@sanity/cli-test 0.2.6 → 0.3.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/dist/test/mockSanityCommand.js +7 -10
- package/dist/test/mockSanityCommand.js.map +1 -1
- package/dist/test/setupFixtures.js +3 -1
- package/dist/test/setupFixtures.js.map +1 -1
- package/fixtures/basic-app/package.json +1 -2
- package/fixtures/basic-functions/package.json +1 -1
- package/fixtures/basic-studio/package.json +2 -2
- package/fixtures/graphql-studio/package.json +2 -2
- package/fixtures/multi-workspace-studio/package.json +2 -2
- package/fixtures/prebuilt-app/package.json +1 -2
- package/fixtures/prebuilt-studio/package.json +1 -1
- package/fixtures/worst-case-studio/package.json +2 -2
- package/package.json +12 -12
|
@@ -30,14 +30,11 @@ import { createTestToken } from './createTestToken.js';
|
|
|
30
30
|
createTestToken(options.token);
|
|
31
31
|
}
|
|
32
32
|
// Auto-convert paths in projectRoot to platform-appropriate format
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
projectRoot
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
path: convertToSystemPath(projectRoot.path)
|
|
39
|
-
};
|
|
40
|
-
}
|
|
33
|
+
const projectRoot = options.projectRoot ? {
|
|
34
|
+
...options.projectRoot,
|
|
35
|
+
directory: convertToSystemPath(options.projectRoot.directory),
|
|
36
|
+
path: convertToSystemPath(options.projectRoot.path)
|
|
37
|
+
} : undefined;
|
|
41
38
|
// Create a subclass that overrides methods when mocks are provided
|
|
42
39
|
// Note: we use @ts-expect-error because TypeScript can't properly infer
|
|
43
40
|
// the relationship between the generic CommandClass and SanityCommand
|
|
@@ -56,8 +53,8 @@ import { createTestToken } from './createTestToken.js';
|
|
|
56
53
|
if (options.cliConfigError && 'name' in options.cliConfigError && options.cliConfigError.name === 'ProjectRootNotFoundError') {
|
|
57
54
|
return Promise.reject(options.cliConfigError);
|
|
58
55
|
}
|
|
59
|
-
if (
|
|
60
|
-
return Promise.resolve(
|
|
56
|
+
if (projectRoot) {
|
|
57
|
+
return Promise.resolve(projectRoot);
|
|
61
58
|
}
|
|
62
59
|
return super.getProjectRoot();
|
|
63
60
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/mockSanityCommand.ts"],"sourcesContent":["import {type Command} from '@oclif/core'\nimport {type CliConfig, type ProjectRootResult, SanityCommand} from '@sanity/cli-core'\n\nimport {convertToSystemPath} from '../utils/paths.js'\nimport {createTestToken} from './createTestToken.js'\n\n/**\n * @public\n */\nexport interface MockSanityCommandOptions {\n /**\n * Mock CLI config (required if command uses getCliConfig or getProjectId)\n */\n cliConfig?: CliConfig\n /**\n * When provided, getCliConfig() will throw this error instead of returning a config.\n * Useful for simulating running outside a project directory.\n */\n cliConfigError?: Error\n /**\n * Mock whether the terminal is interactive (used by isUnattended)\n */\n isInteractive?: boolean\n /**\n * Mock project root result (required if command uses getProjectRoot)\n */\n projectRoot?: ProjectRootResult\n /**\n * Mock authentication token (passed to API clients, bypasses getCliToken)\n */\n token?: string\n}\n\n/**\n * Creates a testable subclass of a command with mocked SanityCommand dependencies.\n *\n * @public\n *\n * @example\n * ```ts\n * // Basic config mocking\n * const TestAdd = mockSanityCommand(Add, {\n * cliConfig: { api: { projectId: 'test-project' } }\n * })\n *\n * // With mock API client\n * const mockClient = {\n * getDocument: vi.fn().mockResolvedValue({ _id: 'doc1', title: 'Test' }),\n * fetch: vi.fn().mockResolvedValue([]),\n * }\n * const TestGet = mockSanityCommand(GetDocumentCommand, {\n * cliConfig: { api: { projectId: 'test-project', dataset: 'production' } },\n * projectApiClient: mockClient,\n * })\n *\n * const {stdout} = await testCommand(TestGet, ['doc1'])\n * expect(mockClient.getDocument).toHaveBeenCalledWith('doc1')\n * ```\n */\nexport function mockSanityCommand<T extends typeof SanityCommand<typeof Command>>(\n CommandClass: T,\n options: MockSanityCommandOptions = {},\n): T {\n if (options.token) {\n createTestToken(options.token)\n }\n\n // Auto-convert paths in projectRoot to platform-appropriate format\n
|
|
1
|
+
{"version":3,"sources":["../../src/test/mockSanityCommand.ts"],"sourcesContent":["import {type Command} from '@oclif/core'\nimport {type CliConfig, type ProjectRootResult, SanityCommand} from '@sanity/cli-core'\n\nimport {convertToSystemPath} from '../utils/paths.js'\nimport {createTestToken} from './createTestToken.js'\n\n/**\n * @public\n */\nexport interface MockSanityCommandOptions {\n /**\n * Mock CLI config (required if command uses getCliConfig or getProjectId)\n */\n cliConfig?: CliConfig\n /**\n * When provided, getCliConfig() will throw this error instead of returning a config.\n * Useful for simulating running outside a project directory.\n */\n cliConfigError?: Error\n /**\n * Mock whether the terminal is interactive (used by isUnattended)\n */\n isInteractive?: boolean\n /**\n * Mock project root result (required if command uses getProjectRoot)\n */\n projectRoot?: ProjectRootResult\n /**\n * Mock authentication token (passed to API clients, bypasses getCliToken)\n */\n token?: string\n}\n\n/**\n * Creates a testable subclass of a command with mocked SanityCommand dependencies.\n *\n * @public\n *\n * @example\n * ```ts\n * // Basic config mocking\n * const TestAdd = mockSanityCommand(Add, {\n * cliConfig: { api: { projectId: 'test-project' } }\n * })\n *\n * // With mock API client\n * const mockClient = {\n * getDocument: vi.fn().mockResolvedValue({ _id: 'doc1', title: 'Test' }),\n * fetch: vi.fn().mockResolvedValue([]),\n * }\n * const TestGet = mockSanityCommand(GetDocumentCommand, {\n * cliConfig: { api: { projectId: 'test-project', dataset: 'production' } },\n * projectApiClient: mockClient,\n * })\n *\n * const {stdout} = await testCommand(TestGet, ['doc1'])\n * expect(mockClient.getDocument).toHaveBeenCalledWith('doc1')\n * ```\n */\nexport function mockSanityCommand<T extends typeof SanityCommand<typeof Command>>(\n CommandClass: T,\n options: MockSanityCommandOptions = {},\n): T {\n if (options.token) {\n createTestToken(options.token)\n }\n\n // Auto-convert paths in projectRoot to platform-appropriate format\n const projectRoot = options.projectRoot\n ? {\n ...options.projectRoot,\n directory: convertToSystemPath(options.projectRoot.directory),\n path: convertToSystemPath(options.projectRoot.path),\n }\n : undefined\n\n // Create a subclass that overrides methods when mocks are provided\n // Note: we use @ts-expect-error because TypeScript can't properly infer\n // the relationship between the generic CommandClass and SanityCommand\n // @ts-expect-error - TypeScript struggles with abstract class subclassing\n class MockedCommand extends CommandClass {\n protected getCliConfig(): Promise<CliConfig> {\n if (options.cliConfigError) {\n return Promise.reject(options.cliConfigError)\n }\n if (options.cliConfig) {\n return Promise.resolve(options.cliConfig)\n }\n return super.getCliConfig()\n }\n\n protected getProjectRoot(): Promise<ProjectRootResult> {\n if (\n options.cliConfigError &&\n 'name' in options.cliConfigError &&\n options.cliConfigError.name === 'ProjectRootNotFoundError'\n ) {\n return Promise.reject(options.cliConfigError)\n }\n if (projectRoot) {\n return Promise.resolve(projectRoot)\n }\n return super.getProjectRoot()\n }\n\n protected resolveIsInteractive(): boolean {\n if (options.isInteractive !== undefined) {\n return options.isInteractive\n }\n return super.resolveIsInteractive()\n }\n }\n\n return MockedCommand as T\n}\n"],"names":["convertToSystemPath","createTestToken","mockSanityCommand","CommandClass","options","token","projectRoot","directory","path","undefined","MockedCommand","getCliConfig","cliConfigError","Promise","reject","cliConfig","resolve","getProjectRoot","name","resolveIsInteractive","isInteractive"],"mappings":"AAGA,SAAQA,mBAAmB,QAAO,oBAAmB;AACrD,SAAQC,eAAe,QAAO,uBAAsB;AA6BpD;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,OAAO,SAASC,kBACdC,YAAe,EACfC,UAAoC,CAAC,CAAC;IAEtC,IAAIA,QAAQC,KAAK,EAAE;QACjBJ,gBAAgBG,QAAQC,KAAK;IAC/B;IAEA,mEAAmE;IACnE,MAAMC,cAAcF,QAAQE,WAAW,GACnC;QACE,GAAGF,QAAQE,WAAW;QACtBC,WAAWP,oBAAoBI,QAAQE,WAAW,CAACC,SAAS;QAC5DC,MAAMR,oBAAoBI,QAAQE,WAAW,CAACE,IAAI;IACpD,IACAC;IAEJ,mEAAmE;IACnE,wEAAwE;IACxE,sEAAsE;IACtE,0EAA0E;IAC1E,MAAMC,sBAAsBP;QAChBQ,eAAmC;YAC3C,IAAIP,QAAQQ,cAAc,EAAE;gBAC1B,OAAOC,QAAQC,MAAM,CAACV,QAAQQ,cAAc;YAC9C;YACA,IAAIR,QAAQW,SAAS,EAAE;gBACrB,OAAOF,QAAQG,OAAO,CAACZ,QAAQW,SAAS;YAC1C;YACA,OAAO,KAAK,CAACJ;QACf;QAEUM,iBAA6C;YACrD,IACEb,QAAQQ,cAAc,IACtB,UAAUR,QAAQQ,cAAc,IAChCR,QAAQQ,cAAc,CAACM,IAAI,KAAK,4BAChC;gBACA,OAAOL,QAAQC,MAAM,CAACV,QAAQQ,cAAc;YAC9C;YACA,IAAIN,aAAa;gBACf,OAAOO,QAAQG,OAAO,CAACV;YACzB;YACA,OAAO,KAAK,CAACW;QACf;QAEUE,uBAAgC;YACxC,IAAIf,QAAQgB,aAAa,KAAKX,WAAW;gBACvC,OAAOL,QAAQgB,aAAa;YAC9B;YACA,OAAO,KAAK,CAACD;QACf;IACF;IAEA,OAAOT;AACT"}
|
|
@@ -105,7 +105,9 @@ async function getAdditionalFixturePaths(fixtures) {
|
|
|
105
105
|
const execError = error;
|
|
106
106
|
spinner.fail('Failed to install dependencies');
|
|
107
107
|
console.error(execError.stderr || execError.stdout || execError.message);
|
|
108
|
-
throw new Error(`Error installing dependencies in ${toPath}: ${execError.stderr || execError.stdout || execError.message}
|
|
108
|
+
throw new Error(`Error installing dependencies in ${toPath}: ${execError.stderr || execError.stdout || execError.message}`, {
|
|
109
|
+
cause: error
|
|
110
|
+
});
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
spinner.succeed('Test environment initialized');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/test/setupFixtures.ts"],"sourcesContent":["import {exec as execNode} from 'node:child_process'\nimport {readFile, rm, writeFile} from 'node:fs/promises'\nimport {basename, join} from 'node:path'\nimport {promisify} from 'node:util'\n\nimport ora from 'ora'\nimport {glob} from 'tinyglobby'\nimport {type TestProject} from 'vitest/node'\n\nimport {fileExists} from '../utils/fileExists.js'\nimport {getFixturesPath, getTempPath} from '../utils/paths.js'\nimport {DEFAULT_FIXTURES} from './constants.js'\nimport {testCopyDirectory} from './testFixture.js'\n\nconst exec = promisify(execNode)\n\n/**\n * Options for setupTestFixtures\n *\n * @public\n */\nexport interface SetupTestFixturesOptions {\n /**\n * Glob patterns for additional fixture directories to set up.\n *\n * Each pattern is matched against directories in the current working directory.\n * Only directories containing a `package.json` file are included.\n *\n * @example\n * ```typescript\n * ['fixtures/*', 'dev/*']\n * ```\n */\n additionalFixtures?: string[]\n\n /**\n * Custom temp directory path. Defaults to process.cwd()/tmp\n */\n tempDir?: string\n}\n\nasync function getAdditionalFixturePaths(fixtures: string[]): Promise<FixtureDetails[]> {\n const paths = await glob(fixtures, {\n absolute: true,\n ignore: ['**/node_modules/**', '**/dist/**'],\n onlyDirectories: true,\n })\n\n const additionalFixtures: FixtureDetails[] = []\n\n for (const path of paths) {\n if (await fileExists(join(`${path}/package.json`))) {\n additionalFixtures.push({\n fixture: basename(path),\n fromPath: path,\n includeDist: false,\n })\n }\n }\n\n return additionalFixtures\n}\n\ninterface FixtureDetails {\n fixture: string\n fromPath: string\n includeDist: boolean\n}\n\n/**\n * Global setup function for initializing test fixtures.\n *\n * Copies fixtures from the bundled location to a temp directory\n * and installs dependencies.\n *\n * Note: Fixtures are NOT built during setup. Tests that need built\n * fixtures should build them as part of the test.\n *\n * This function is designed to be used with vitest globalSetup.\n *\n * @public\n *\n * @param options - Configuration options\n * @example\n * ```typescript\n * // In vitest.config.ts\n * export default defineConfig({\n * test: {\n * globalSetup: ['@sanity/cli-test/vitest']\n * }\n * })\n * ```\n */\nexport async function setup(_: TestProject, options: SetupTestFixturesOptions = {}): Promise<void> {\n const {additionalFixtures, tempDir} = options\n\n const spinner = ora({\n // Without this, the watch mode input is discarded\n discardStdin: false,\n text: 'Initializing test environment...',\n }).start()\n\n try {\n const fixturesDir = getFixturesPath()\n const tempDirectory = getTempPath(tempDir)\n\n const allFixturePaths: FixtureDetails[] = []\n\n // Add the default fixtures\n for (const [fixture, options] of Object.entries(DEFAULT_FIXTURES)) {\n allFixturePaths.push({\n fixture,\n fromPath: join(fixturesDir, fixture),\n includeDist: 'includeDist' in options && options.includeDist ? options.includeDist : false,\n })\n }\n\n // Add the additional fixtures\n if (additionalFixtures && additionalFixtures.length > 0) {\n const additionalFixturePaths = await getAdditionalFixturePaths(additionalFixtures)\n\n if (additionalFixturePaths.length > 0) {\n allFixturePaths.push(...additionalFixturePaths)\n } else {\n spinner.warn(\n `No additional fixtures found, check the glob pattern: ${additionalFixtures.join(', ')}`,\n )\n }\n }\n\n for (const {fixture, fromPath, includeDist} of allFixturePaths) {\n const toPath = join(tempDirectory, `fixture-${fixture}`)\n // Copy the fixture, excluding node_modules and dist\n await testCopyDirectory(fromPath, toPath, ['node_modules', ...(includeDist ? [] : ['dist'])])\n\n // Replace the package.json name with a temp name\n const packageJsonPath = join(toPath, 'package.json')\n const packageJson = await readFile(packageJsonPath, 'utf8')\n const packageJsonData = JSON.parse(packageJson)\n packageJsonData.name = `${packageJsonData.name}-test`\n await writeFile(packageJsonPath, JSON.stringify(packageJsonData, null, 2))\n\n // Run pnpm install --no-lockfile in the temp directory\n try {\n await exec(`pnpm install --prefer-offline --no-lockfile`, {\n cwd: toPath,\n })\n } catch (error) {\n const execError = error as {message: string; stderr?: string; stdout?: string}\n spinner.fail('Failed to install dependencies')\n console.error(execError.stderr || execError.stdout || execError.message)\n throw new Error(\n `Error installing dependencies in ${toPath}: ${execError.stderr || execError.stdout || execError.message}`,\n )\n }\n }\n\n spinner.succeed('Test environment initialized')\n } catch (error) {\n spinner.fail('Failed to initialize test environment')\n throw error\n }\n}\n\n/**\n * Options for teardownTestFixtures\n *\n * @public\n */\nexport interface TeardownTestFixturesOptions {\n /**\n * Custom temp directory path. Defaults to process.cwd()/tmp\n */\n tempDir?: string\n}\n\n/**\n * Teardown function to clean up test fixtures.\n *\n * Removes the temp directory created by setupTestFixtures.\n *\n * This function is designed to be used with vitest globalSetup.\n *\n * @public\n *\n * @param options - Configuration options\n */\nexport async function teardown(options: TeardownTestFixturesOptions = {}): Promise<void> {\n const {tempDir} = options\n const tempDirectory = getTempPath(tempDir)\n\n // Remove the tmp directory\n await rm(tempDirectory, {force: true, maxRetries: 3, recursive: true}).catch(() => {})\n}\n"],"names":["exec","execNode","readFile","rm","writeFile","basename","join","promisify","ora","glob","fileExists","getFixturesPath","getTempPath","DEFAULT_FIXTURES","testCopyDirectory","getAdditionalFixturePaths","fixtures","paths","absolute","ignore","onlyDirectories","additionalFixtures","path","push","fixture","fromPath","includeDist","setup","_","options","tempDir","spinner","discardStdin","text","start","fixturesDir","tempDirectory","allFixturePaths","Object","entries","length","additionalFixturePaths","warn","toPath","packageJsonPath","packageJson","packageJsonData","JSON","parse","name","stringify","cwd","error","execError","fail","console","stderr","stdout","message","Error","succeed","teardown","force","maxRetries","recursive","catch"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["../../src/test/setupFixtures.ts"],"sourcesContent":["import {exec as execNode} from 'node:child_process'\nimport {readFile, rm, writeFile} from 'node:fs/promises'\nimport {basename, join} from 'node:path'\nimport {promisify} from 'node:util'\n\nimport ora from 'ora'\nimport {glob} from 'tinyglobby'\nimport {type TestProject} from 'vitest/node'\n\nimport {fileExists} from '../utils/fileExists.js'\nimport {getFixturesPath, getTempPath} from '../utils/paths.js'\nimport {DEFAULT_FIXTURES} from './constants.js'\nimport {testCopyDirectory} from './testFixture.js'\n\nconst exec = promisify(execNode)\n\n/**\n * Options for setupTestFixtures\n *\n * @public\n */\nexport interface SetupTestFixturesOptions {\n /**\n * Glob patterns for additional fixture directories to set up.\n *\n * Each pattern is matched against directories in the current working directory.\n * Only directories containing a `package.json` file are included.\n *\n * @example\n * ```typescript\n * ['fixtures/*', 'dev/*']\n * ```\n */\n additionalFixtures?: string[]\n\n /**\n * Custom temp directory path. Defaults to process.cwd()/tmp\n */\n tempDir?: string\n}\n\nasync function getAdditionalFixturePaths(fixtures: string[]): Promise<FixtureDetails[]> {\n const paths = await glob(fixtures, {\n absolute: true,\n ignore: ['**/node_modules/**', '**/dist/**'],\n onlyDirectories: true,\n })\n\n const additionalFixtures: FixtureDetails[] = []\n\n for (const path of paths) {\n if (await fileExists(join(`${path}/package.json`))) {\n additionalFixtures.push({\n fixture: basename(path),\n fromPath: path,\n includeDist: false,\n })\n }\n }\n\n return additionalFixtures\n}\n\ninterface FixtureDetails {\n fixture: string\n fromPath: string\n includeDist: boolean\n}\n\n/**\n * Global setup function for initializing test fixtures.\n *\n * Copies fixtures from the bundled location to a temp directory\n * and installs dependencies.\n *\n * Note: Fixtures are NOT built during setup. Tests that need built\n * fixtures should build them as part of the test.\n *\n * This function is designed to be used with vitest globalSetup.\n *\n * @public\n *\n * @param options - Configuration options\n * @example\n * ```typescript\n * // In vitest.config.ts\n * export default defineConfig({\n * test: {\n * globalSetup: ['@sanity/cli-test/vitest']\n * }\n * })\n * ```\n */\nexport async function setup(_: TestProject, options: SetupTestFixturesOptions = {}): Promise<void> {\n const {additionalFixtures, tempDir} = options\n\n const spinner = ora({\n // Without this, the watch mode input is discarded\n discardStdin: false,\n text: 'Initializing test environment...',\n }).start()\n\n try {\n const fixturesDir = getFixturesPath()\n const tempDirectory = getTempPath(tempDir)\n\n const allFixturePaths: FixtureDetails[] = []\n\n // Add the default fixtures\n for (const [fixture, options] of Object.entries(DEFAULT_FIXTURES)) {\n allFixturePaths.push({\n fixture,\n fromPath: join(fixturesDir, fixture),\n includeDist: 'includeDist' in options && options.includeDist ? options.includeDist : false,\n })\n }\n\n // Add the additional fixtures\n if (additionalFixtures && additionalFixtures.length > 0) {\n const additionalFixturePaths = await getAdditionalFixturePaths(additionalFixtures)\n\n if (additionalFixturePaths.length > 0) {\n allFixturePaths.push(...additionalFixturePaths)\n } else {\n spinner.warn(\n `No additional fixtures found, check the glob pattern: ${additionalFixtures.join(', ')}`,\n )\n }\n }\n\n for (const {fixture, fromPath, includeDist} of allFixturePaths) {\n const toPath = join(tempDirectory, `fixture-${fixture}`)\n // Copy the fixture, excluding node_modules and dist\n await testCopyDirectory(fromPath, toPath, ['node_modules', ...(includeDist ? [] : ['dist'])])\n\n // Replace the package.json name with a temp name\n const packageJsonPath = join(toPath, 'package.json')\n const packageJson = await readFile(packageJsonPath, 'utf8')\n const packageJsonData = JSON.parse(packageJson)\n packageJsonData.name = `${packageJsonData.name}-test`\n await writeFile(packageJsonPath, JSON.stringify(packageJsonData, null, 2))\n\n // Run pnpm install --no-lockfile in the temp directory\n try {\n await exec(`pnpm install --prefer-offline --no-lockfile`, {\n cwd: toPath,\n })\n } catch (error) {\n const execError = error as {message: string; stderr?: string; stdout?: string}\n spinner.fail('Failed to install dependencies')\n console.error(execError.stderr || execError.stdout || execError.message)\n throw new Error(\n `Error installing dependencies in ${toPath}: ${execError.stderr || execError.stdout || execError.message}`,\n {cause: error},\n )\n }\n }\n\n spinner.succeed('Test environment initialized')\n } catch (error) {\n spinner.fail('Failed to initialize test environment')\n throw error\n }\n}\n\n/**\n * Options for teardownTestFixtures\n *\n * @public\n */\nexport interface TeardownTestFixturesOptions {\n /**\n * Custom temp directory path. Defaults to process.cwd()/tmp\n */\n tempDir?: string\n}\n\n/**\n * Teardown function to clean up test fixtures.\n *\n * Removes the temp directory created by setupTestFixtures.\n *\n * This function is designed to be used with vitest globalSetup.\n *\n * @public\n *\n * @param options - Configuration options\n */\nexport async function teardown(options: TeardownTestFixturesOptions = {}): Promise<void> {\n const {tempDir} = options\n const tempDirectory = getTempPath(tempDir)\n\n // Remove the tmp directory\n await rm(tempDirectory, {force: true, maxRetries: 3, recursive: true}).catch(() => {})\n}\n"],"names":["exec","execNode","readFile","rm","writeFile","basename","join","promisify","ora","glob","fileExists","getFixturesPath","getTempPath","DEFAULT_FIXTURES","testCopyDirectory","getAdditionalFixturePaths","fixtures","paths","absolute","ignore","onlyDirectories","additionalFixtures","path","push","fixture","fromPath","includeDist","setup","_","options","tempDir","spinner","discardStdin","text","start","fixturesDir","tempDirectory","allFixturePaths","Object","entries","length","additionalFixturePaths","warn","toPath","packageJsonPath","packageJson","packageJsonData","JSON","parse","name","stringify","cwd","error","execError","fail","console","stderr","stdout","message","Error","cause","succeed","teardown","force","maxRetries","recursive","catch"],"mappings":"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"}
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
"@sanity/sdk-react": "^2.6.0",
|
|
17
17
|
"react": "^19.2.3",
|
|
18
18
|
"react-dom": "^19.2.3",
|
|
19
|
-
"sanity": "^5.
|
|
19
|
+
"sanity": "^5.18.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/react": "^19.2.9",
|
|
23
|
-
"sanity": "^5.17.1",
|
|
24
23
|
"typescript": "^5.9.3"
|
|
25
24
|
}
|
|
26
25
|
}
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"start": "sanity start"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@sanity/vision": "^5.
|
|
18
|
+
"@sanity/vision": "^5.18.0",
|
|
19
19
|
"react": "^19.2.3",
|
|
20
20
|
"react-dom": "^19.2.3",
|
|
21
|
-
"sanity": "^5.
|
|
21
|
+
"sanity": "^5.18.0",
|
|
22
22
|
"styled-components": "^6.3.8"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"deploy-graphql": "sanity graphql deploy"
|
|
13
13
|
},
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"@sanity/vision": "^5.
|
|
15
|
+
"@sanity/vision": "^5.18.0",
|
|
16
16
|
"react": "^19.2.3",
|
|
17
17
|
"react-dom": "^19.2.3",
|
|
18
|
-
"sanity": "^5.
|
|
18
|
+
"sanity": "^5.18.0",
|
|
19
19
|
"styled-components": "^6.3.8"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
"start": "sanity start"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@sanity/vision": "^5.
|
|
18
|
+
"@sanity/vision": "^5.18.0",
|
|
19
19
|
"react": "^19.2.3",
|
|
20
20
|
"react-dom": "^19.2.3",
|
|
21
|
-
"sanity": "^5.
|
|
21
|
+
"sanity": "^5.18.0",
|
|
22
22
|
"styled-components": "^6.3.8"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
@@ -16,11 +16,10 @@
|
|
|
16
16
|
"@sanity/sdk-react": "^2.6.0",
|
|
17
17
|
"react": "^19.2.3",
|
|
18
18
|
"react-dom": "^19.2.3",
|
|
19
|
-
"sanity": "^5.
|
|
19
|
+
"sanity": "^5.18.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/react": "^19.2.9",
|
|
23
|
-
"sanity": "^5.17.1",
|
|
24
23
|
"typescript": "^5.9.3"
|
|
25
24
|
}
|
|
26
25
|
}
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@sanity/code-input": "^7.0.6",
|
|
19
|
-
"@sanity/vision": "^5.
|
|
19
|
+
"@sanity/vision": "^5.18.0",
|
|
20
20
|
"react": "^19.2.3",
|
|
21
21
|
"react-dom": "^19.2.3",
|
|
22
|
-
"sanity": "^5.
|
|
22
|
+
"sanity": "^5.18.0",
|
|
23
23
|
"sanity-plugin-media": "^4.1.1",
|
|
24
24
|
"styled-components": "^6.3.8",
|
|
25
25
|
"vite-tsconfig-paths": "^6.0.5"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/cli-test",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Sanity CLI test helpers and utilities",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"access": "public"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@swc/core": "^1.15.
|
|
46
|
+
"@swc/core": "^1.15.21",
|
|
47
47
|
"ansis": "^4.2.0",
|
|
48
48
|
"esbuild": "^0.27.4",
|
|
49
49
|
"nock": "^14.0.11",
|
|
@@ -52,28 +52,28 @@
|
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@eslint/compat": "^2.0.3",
|
|
55
|
-
"@oclif/core": "^4.
|
|
56
|
-
"@sanity/client": "^7.
|
|
57
|
-
"@sanity/pkg-utils": "^10.4.
|
|
55
|
+
"@oclif/core": "^4.10.2",
|
|
56
|
+
"@sanity/client": "^7.20.0",
|
|
57
|
+
"@sanity/pkg-utils": "^10.4.13",
|
|
58
58
|
"@swc/cli": "^0.8.0",
|
|
59
59
|
"@types/node": "^20.19.37",
|
|
60
|
-
"eslint": "^
|
|
60
|
+
"eslint": "^10.1.0",
|
|
61
61
|
"publint": "^0.3.18",
|
|
62
62
|
"rimraf": "^6.0.1",
|
|
63
63
|
"tsx": "^4.21.0",
|
|
64
64
|
"typescript": "^5.9.3",
|
|
65
|
-
"vitest": "^4.1.
|
|
66
|
-
"yaml": "^2.8.
|
|
65
|
+
"vitest": "^4.1.2",
|
|
66
|
+
"yaml": "^2.8.3",
|
|
67
67
|
"@repo/package.config": "0.0.1",
|
|
68
|
-
"@
|
|
69
|
-
"@sanity/
|
|
70
|
-
"@
|
|
68
|
+
"@repo/tsconfig": "3.70.0",
|
|
69
|
+
"@sanity/cli-core": "1.3.0",
|
|
70
|
+
"@sanity/eslint-config-cli": "1.1.0"
|
|
71
71
|
},
|
|
72
72
|
"peerDependencies": {
|
|
73
73
|
"@oclif/core": "^4.0.0",
|
|
74
74
|
"@sanity/client": "^7.0.0",
|
|
75
75
|
"vitest": ">=3.0.0 <5.0.0",
|
|
76
|
-
"@sanity/cli-core": "1.
|
|
76
|
+
"@sanity/cli-core": "1.3.0"
|
|
77
77
|
},
|
|
78
78
|
"engines": {
|
|
79
79
|
"node": ">=20.19.1 <22 || >=22.12"
|