@sanity/cli 8.23.0 → 8.25.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 +401 -87
- package/bin/run.js +7 -1
- package/dist/actions/codemods/dashboard.js +136 -8
- package/dist/actions/codemods/dashboard.js.map +1 -1
- package/dist/actions/codemods/types.js.map +1 -1
- package/dist/actions/dev/devAction.js +48 -44
- package/dist/actions/dev/devAction.js.map +1 -1
- package/dist/actions/init/initHelpers.js +1 -1
- package/dist/actions/init/initHelpers.js.map +1 -1
- package/dist/actions/init/initStudio.js +1 -1
- package/dist/actions/init/initStudio.js.map +1 -1
- package/dist/actions/init/project/getOrCreateDataset.js +10 -12
- package/dist/actions/init/project/getOrCreateDataset.js.map +1 -1
- package/dist/actions/init/project/getOrCreateProject.js +7 -5
- package/dist/actions/init/project/getOrCreateProject.js.map +1 -1
- package/dist/actions/init/project/promptUserForOrganization.js +6 -4
- package/dist/actions/init/project/promptUserForOrganization.js.map +1 -1
- package/dist/commands/api.js +1 -1
- package/dist/commands/api.js.map +1 -1
- package/dist/commands/assets/upload.js +1 -1
- package/dist/commands/assets/upload.js.map +1 -1
- package/dist/commands/codemod.js +1 -0
- package/dist/commands/codemod.js.map +1 -1
- package/dist/commands/cors/add.js +1 -1
- package/dist/commands/cors/add.js.map +1 -1
- package/dist/commands/cors/delete.js +1 -1
- package/dist/commands/cors/delete.js.map +1 -1
- package/dist/commands/cors/list.js +1 -1
- package/dist/commands/cors/list.js.map +1 -1
- package/dist/commands/datasets/alias/create.js +1 -1
- package/dist/commands/datasets/alias/create.js.map +1 -1
- package/dist/commands/datasets/import.js +0 -8
- package/dist/commands/datasets/import.js.map +1 -1
- package/dist/commands/datasets/list.js +1 -1
- package/dist/commands/datasets/list.js.map +1 -1
- package/dist/commands/documents/create.js +1 -1
- package/dist/commands/documents/create.js.map +1 -1
- package/dist/commands/documents/delete.js +1 -1
- package/dist/commands/documents/delete.js.map +1 -1
- package/dist/commands/documents/get.js +1 -1
- package/dist/commands/documents/get.js.map +1 -1
- package/dist/commands/documents/query.js +1 -9
- package/dist/commands/documents/query.js.map +1 -1
- package/dist/commands/documents/validate.js +2 -2
- package/dist/commands/documents/validate.js.map +1 -1
- package/dist/commands/graphql/list.js +1 -1
- package/dist/commands/graphql/list.js.map +1 -1
- package/dist/commands/graphql/undeploy.js +1 -11
- package/dist/commands/graphql/undeploy.js.map +1 -1
- package/dist/commands/hooks/attempt.js +1 -1
- package/dist/commands/hooks/attempt.js.map +1 -1
- package/dist/commands/hooks/create.js +1 -1
- package/dist/commands/hooks/create.js.map +1 -1
- package/dist/commands/hooks/delete.js +1 -1
- package/dist/commands/hooks/delete.js.map +1 -1
- package/dist/commands/hooks/list.js +1 -1
- package/dist/commands/hooks/list.js.map +1 -1
- package/dist/commands/hooks/logs.js +1 -1
- package/dist/commands/hooks/logs.js.map +1 -1
- package/dist/commands/init.js +3 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/migrations/run.js +5 -5
- package/dist/commands/migrations/run.js.map +1 -1
- package/dist/commands/projects/unclaimed.js +6 -5
- package/dist/commands/projects/unclaimed.js.map +1 -1
- package/dist/commands/tokens/create.js +4 -4
- package/dist/commands/tokens/create.js.map +1 -1
- package/dist/commands/tokens/delete.js +2 -2
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +2 -2
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/users/invite.js +1 -1
- package/dist/commands/users/invite.js.map +1 -1
- package/dist/commands/users/list.js +1 -1
- package/dist/commands/users/list.js.map +1 -1
- package/dist/exports/invokeSanityCli/index.js +1 -1
- package/dist/exports/invokeSanityCli/index.js.map +1 -1
- package/dist/hooks/prerun/injectEnvVariables.js +1 -1
- package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
- package/dist/util/searchChoices.js +52 -0
- package/dist/util/searchChoices.js.map +1 -0
- package/dist/util/sharedFlags.js +8 -4
- package/dist/util/sharedFlags.js.map +1 -1
- package/dist/util/warnOnNonProductionEnvironment.js +4 -3
- package/dist/util/warnOnNonProductionEnvironment.js.map +1 -1
- package/oclif.manifest.json +515 -351
- package/package.json +8 -8
- package/dist/util/getSanityEnv.js +0 -8
- package/dist/util/getSanityEnv.js.map +0 -1
- package/templates/shopify/.gitignore +0 -26
package/bin/run.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
2
|
+
/* eslint-disable n/no-unsupported-features/node-builtins -- Supported by the Node version guard. */
|
|
3
|
+
import module from 'node:module'
|
|
3
4
|
|
|
4
5
|
var err = '\u001B[31m\u001B[1mERROR:\u001B[22m\u001B[39m '
|
|
5
6
|
var nodeVersionParts = process.version.replace(/^v/i, '').split('.').map(Number)
|
|
@@ -21,6 +22,11 @@ if (!isSupportedNodeVersion(majorVersion, minorVersion)) {
|
|
|
21
22
|
process.exit(1)
|
|
22
23
|
}
|
|
23
24
|
|
|
25
|
+
module.enableCompileCache()
|
|
26
|
+
setTimeout(() => module.flushCompileCache(), 10 * 1000).unref()
|
|
27
|
+
|
|
28
|
+
const {execute, settings} = module.createRequire(import.meta.url)('@oclif/core')
|
|
29
|
+
|
|
24
30
|
settings.enableAutoTranspile = false
|
|
25
31
|
|
|
26
32
|
await execute({dir: import.meta.url})
|
|
@@ -1,17 +1,47 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import { findPathForFiles, getCliConfig, getLocalPackageVersion, getStudioConfig, isWorkbenchApp, tryFindStudioConfigPath } from '@sanity/cli-core';
|
|
2
|
-
import {
|
|
4
|
+
import { getYarnMajorVersion, readPackageJson } from '@sanity/cli-core/package-manager';
|
|
5
|
+
import { confirm, input, select } from '@sanity/cli-core/ux';
|
|
3
6
|
import { toAppSlug } from '@sanity/workbench-cli/init';
|
|
7
|
+
import { execa } from 'execa';
|
|
4
8
|
import { lt } from 'semver';
|
|
9
|
+
import yaml from 'yaml';
|
|
5
10
|
import { getOrganizationGrants, listOrganizations } from '../../services/organizations.js';
|
|
6
11
|
import { getProjectById } from '../../services/projects.js';
|
|
12
|
+
import { determineIsApp } from '../../util/determineIsApp.js';
|
|
13
|
+
import { detectWorkspace } from '../../util/packageManager/installationInfo/detectWorkspace.js';
|
|
14
|
+
import { getPackageManagerChoice, getPartialEnvWithNpmPath } from '../../util/packageManager/packageManagerChoice.js';
|
|
7
15
|
import { getManageUrl } from '../projects/getManageUrl.js';
|
|
8
|
-
//
|
|
9
|
-
const MIN_SANITY_VERSION = '6.
|
|
16
|
+
// `defineApplication` landed in 6.12.0; the Dashboard also needs the CLI fixes released since
|
|
17
|
+
const MIN_SANITY_VERSION = '6.20.0';
|
|
18
|
+
const MIN_SDK_VERSION = '3.9.1';
|
|
19
|
+
async function findOutdated(packages, workDir) {
|
|
20
|
+
const installed = await Promise.all(packages.map(({ name })=>getLocalPackageVersion(name, workDir)));
|
|
21
|
+
return packages.flatMap((pkg, index)=>{
|
|
22
|
+
const version = installed[index];
|
|
23
|
+
return version && lt(version, pkg.min) ? [
|
|
24
|
+
{
|
|
25
|
+
...pkg,
|
|
26
|
+
version
|
|
27
|
+
}
|
|
28
|
+
] : [];
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
// corepack's `packageManager: "yarn@4.9.1"` names the major even without a .yarnrc.yml
|
|
32
|
+
function declaredYarnMajor(field) {
|
|
33
|
+
const match = typeof field === 'string' ? /^yarn@(\d+)/.exec(field) : null;
|
|
34
|
+
return match ? Number.parseInt(match[1], 10) : undefined;
|
|
35
|
+
}
|
|
36
|
+
function listOutdated(packages) {
|
|
37
|
+
return packages.map(({ min, name, neededBy, version })=>` - ${name} ${version} (${neededBy} ${min} or later)`).join('\n');
|
|
38
|
+
}
|
|
10
39
|
const purpose = 'Move an existing Studio or SDK app onto the Dashboard';
|
|
11
40
|
const description = `
|
|
12
41
|
Rewrites sanity.cli.ts (or .js) so the next \`sanity dev\` and \`sanity deploy\` run the project
|
|
13
42
|
as a new Dashboard application. Asks for the application's title and slug, and looks up the
|
|
14
|
-
organization from the project.
|
|
43
|
+
organization from the project. Offers to upgrade sanity (older than ${MIN_SANITY_VERSION}) and, in
|
|
44
|
+
SDK apps, @sanity/sdk and @sanity/sdk-react (older than ${MIN_SDK_VERSION}) to their latest versions.
|
|
15
45
|
|
|
16
46
|
from: app: {organizationId: 'oAbc', entry: './src/App.tsx'}
|
|
17
47
|
to: app: defineApplication({title: 'Acme', slug: 'acme', organizationId: 'oAbc', entry: './src/App.tsx'})
|
|
@@ -22,7 +52,7 @@ Dashboard build replaces the existing application.
|
|
|
22
52
|
export const dashboard = {
|
|
23
53
|
description,
|
|
24
54
|
filename: 'dashboard.js',
|
|
25
|
-
prepare: async ({ output, workDir })=>{
|
|
55
|
+
prepare: async ({ dry, output, workDir })=>{
|
|
26
56
|
const config = await getCliConfig(workDir);
|
|
27
57
|
if (isWorkbenchApp(config.app)) {
|
|
28
58
|
throw new Error('This project is already a Dashboard application.');
|
|
@@ -88,9 +118,107 @@ export const dashboard = {
|
|
|
88
118
|
if (appIdKey) {
|
|
89
119
|
output.warn(`Remove \`${appIdKey}\` from your CLI config before you deploy. It points at your existing application, and deploying with it in place replaces that application with the Dashboard build.`);
|
|
90
120
|
}
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
121
|
+
const required = [
|
|
122
|
+
{
|
|
123
|
+
min: MIN_SANITY_VERSION,
|
|
124
|
+
name: 'sanity',
|
|
125
|
+
neededBy: 'the Dashboard needs'
|
|
126
|
+
},
|
|
127
|
+
...determineIsApp(config) ? [
|
|
128
|
+
'@sanity/sdk',
|
|
129
|
+
'@sanity/sdk-react'
|
|
130
|
+
].map((name)=>({
|
|
131
|
+
min: MIN_SDK_VERSION,
|
|
132
|
+
name,
|
|
133
|
+
neededBy: 'SDK apps need'
|
|
134
|
+
})) : []
|
|
135
|
+
];
|
|
136
|
+
const outdated = await findOutdated(required, workDir);
|
|
137
|
+
if (outdated.length > 0) {
|
|
138
|
+
output.warn(`\`sanity dev\` and \`sanity deploy\` will fail until you upgrade:\n${listOutdated(outdated)}`);
|
|
139
|
+
const { chosen: packageManager } = await getPackageManagerChoice(workDir, {
|
|
140
|
+
interactive: false
|
|
141
|
+
});
|
|
142
|
+
const { root, yarnBerry } = await detectWorkspace(workDir);
|
|
143
|
+
const [{ dependencies, devDependencies }, rootManifest] = await Promise.all([
|
|
144
|
+
readPackageJson(path.join(workDir, 'package.json'), {
|
|
145
|
+
skipSchemaValidation: true
|
|
146
|
+
}),
|
|
147
|
+
readFile(path.join(root, 'package.json'), 'utf8').then(JSON.parse, ()=>null)
|
|
148
|
+
]);
|
|
149
|
+
let pnpmOverrides = [];
|
|
150
|
+
if (packageManager === 'pnpm') {
|
|
151
|
+
const workspacePath = path.join(root, 'pnpm-workspace.yaml');
|
|
152
|
+
const workspaceConfig = await readFile(workspacePath, 'utf8').then(yaml.parse, ()=>null);
|
|
153
|
+
pnpmOverrides = Object.keys({
|
|
154
|
+
...rootManifest?.pnpm?.overrides,
|
|
155
|
+
...workspaceConfig?.overrides
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// bun's upgrade leaves a catalog untouched, yarn's swaps `catalog:` for a plain range, and
|
|
159
|
+
// pnpm's does the same when `overrides` pins the package
|
|
160
|
+
const isUnupgradableCatalog = (name)=>(dependencies?.[name] ?? devDependencies?.[name] ?? '').startsWith('catalog:') && (packageManager === 'bun' || packageManager === 'yarn' || pnpmOverrides.some((key)=>key === name || key.startsWith(`${name}@`)));
|
|
161
|
+
const catalogued = outdated.filter(({ name })=>isUnupgradableCatalog(name));
|
|
162
|
+
const upgradable = outdated.filter(({ name })=>!isUnupgradableCatalog(name));
|
|
163
|
+
if (catalogued.length > 0) {
|
|
164
|
+
const targets = catalogued.map(({ min, name })=>`${name} to ^${min} or later`).join(', ');
|
|
165
|
+
const install = `then run \`${packageManager} install\``;
|
|
166
|
+
output.log(packageManager === 'pnpm' ? `pnpm can't upgrade catalog packages that \`overrides\` pin, so update them yourself: set ${targets} in the catalog and in \`overrides\`, ${install}.` : `${packageManager} can't upgrade catalog packages, so update them yourself: set ${targets} in the catalog in ${packageManager === 'bun' ? 'the root package.json' : '.yarnrc.yml'}, ${install}.`);
|
|
167
|
+
}
|
|
168
|
+
if (upgradable.length > 0) {
|
|
169
|
+
const names = upgradable.map(({ name })=>name);
|
|
170
|
+
const latest = names.map((name)=>`${name}@latest`);
|
|
171
|
+
// Berry dropped `yarn upgrade`, and the user agent only names yarn when the CLI itself was
|
|
172
|
+
// run through yarn, so take the project's own signals first
|
|
173
|
+
const isYarnBerry = yarnBerry || (declaredYarnMajor(rootManifest?.packageManager) ?? getYarnMajorVersion() ?? 1) >= 2;
|
|
174
|
+
// pnpm keeps `catalog:` and bumps the catalog entry only with `update --latest`
|
|
175
|
+
const command = {
|
|
176
|
+
bun: [
|
|
177
|
+
'bun',
|
|
178
|
+
'update',
|
|
179
|
+
...latest
|
|
180
|
+
],
|
|
181
|
+
manual: undefined,
|
|
182
|
+
npm: [
|
|
183
|
+
'npm',
|
|
184
|
+
'install',
|
|
185
|
+
'--legacy-peer-deps',
|
|
186
|
+
...latest
|
|
187
|
+
],
|
|
188
|
+
pnpm: [
|
|
189
|
+
'pnpm',
|
|
190
|
+
'update',
|
|
191
|
+
...names,
|
|
192
|
+
'--latest'
|
|
193
|
+
],
|
|
194
|
+
yarn: [
|
|
195
|
+
'yarn',
|
|
196
|
+
isYarnBerry ? 'up' : 'upgrade',
|
|
197
|
+
...latest
|
|
198
|
+
]
|
|
199
|
+
}[packageManager];
|
|
200
|
+
if (!command) {
|
|
201
|
+
output.log(`Upgrade ${names.join(', ')} to the latest version with your package manager.`);
|
|
202
|
+
} else if (dry || !await confirm({
|
|
203
|
+
default: true,
|
|
204
|
+
message: `Upgrade ${names.join(', ')} to the latest version now?`
|
|
205
|
+
})) {
|
|
206
|
+
output.log(`Run \`${command.join(' ')}\` to upgrade.`);
|
|
207
|
+
} else {
|
|
208
|
+
output.log(`Running \`${command.join(' ')}\``);
|
|
209
|
+
// The version check below reports a failed upgrade, so the exit code isn't needed
|
|
210
|
+
await execa(command[0], command.slice(1), {
|
|
211
|
+
cwd: workDir,
|
|
212
|
+
env: getPartialEnvWithNpmPath(workDir),
|
|
213
|
+
reject: false,
|
|
214
|
+
stdio: 'inherit'
|
|
215
|
+
});
|
|
216
|
+
const stillOutdated = await findOutdated(upgradable, workDir);
|
|
217
|
+
if (stillOutdated.length > 0) {
|
|
218
|
+
output.warn(`These are still too old after the upgrade. Upgrade them before you run \`sanity dev\` or \`sanity deploy\`:\n${listOutdated(stillOutdated)}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
94
222
|
}
|
|
95
223
|
// getCliConfig has already checked there is exactly one
|
|
96
224
|
const cliConfigPaths = await findPathForFiles(workDir, [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/codemods/dashboard.ts"],"sourcesContent":["import {\n findPathForFiles,\n getCliConfig,\n getLocalPackageVersion,\n getStudioConfig,\n isWorkbenchApp,\n tryFindStudioConfigPath,\n} from '@sanity/cli-core'\nimport {input, select} from '@sanity/cli-core/ux'\nimport {toAppSlug} from '@sanity/workbench-cli/init'\nimport {lt} from 'semver'\n\nimport {getOrganizationGrants, listOrganizations} from '../../services/organizations.js'\nimport {getProjectById} from '../../services/projects.js'\nimport {getManageUrl} from '../projects/getManageUrl.js'\nimport {type CodeMod} from './types.js'\n\n// The first `sanity` release whose `sanity/cli` exports `defineApplication`\nconst MIN_SANITY_VERSION = '6.12.0'\n\nconst purpose = 'Move an existing Studio or SDK app onto the Dashboard'\nconst description = `\nRewrites sanity.cli.ts (or .js) so the next \\`sanity dev\\` and \\`sanity deploy\\` run the project\nas a new Dashboard application. Asks for the application's title and slug, and looks up the\norganization from the project.\n\nfrom: app: {organizationId: 'oAbc', entry: './src/App.tsx'}\n to: app: defineApplication({title: 'Acme', slug: 'acme', organizationId: 'oAbc', entry: './src/App.tsx'})\n\nThe existing deployment is left alone. Remove \\`deployment.appId\\` before deploying, or the\nDashboard build replaces the existing application.\n`.trim()\n\nexport const dashboard: CodeMod = {\n description,\n filename: 'dashboard.js',\n prepare: async ({output, workDir}) => {\n const config = await getCliConfig(workDir)\n if (isWorkbenchApp(config.app)) {\n throw new Error('This project is already a Dashboard application.')\n }\n\n const projectId = config.api?.projectId\n let organizationId = config.app?.organizationId\n // Deploy creates the application with both IDs, and the API rejects a project outside the\n // organization, so a project's organization is the only valid choice\n if (!organizationId && projectId) {\n organizationId = (await getProjectById(projectId)).organizationId ?? undefined\n if (!organizationId) {\n throw new Error(\n `Project ${projectId} isn't in an organization, and a Dashboard application needs one. Move the project into an organization at ${getManageUrl(projectId)}, then run this again.`,\n )\n }\n }\n if (!organizationId) {\n const choices = await Promise.all(\n (await listOrganizations()).map(async ({id, name}) => {\n // Grants can 401 for implicit memberships; treat any failure as no access\n const grants = await getOrganizationGrants(id).catch(() => null)\n const canDeploy = (grants?.['sanity.sdk.applications'] ?? []).some((resource) =>\n resource.grants.some((grant) => grant.name === 'deploy'),\n )\n return {\n disabled: canDeploy ? false : 'Insufficient permissions',\n name: `${name} [${id}]`,\n value: id,\n }\n }),\n )\n if (!choices.some((choice) => choice.disabled === false)) {\n throw new Error(\n \"You can't deploy applications in any of your organizations. Ask an organization administrator for access, then run this again.\",\n )\n }\n organizationId = await select({choices, message: 'Organization that owns the application:'})\n }\n\n let suggestedTitle = config.app?.title\n if (!suggestedTitle && (await tryFindStudioConfigPath(workDir))) {\n const studioConfig = await getStudioConfig(workDir, {resolvePlugins: false})\n suggestedTitle = Array.isArray(studioConfig) ? undefined : studioConfig.title\n }\n\n const title = await input({\n default: suggestedTitle,\n message: 'Application title:',\n validate: (value) => (value.trim() ? true : 'Enter a title for the application.'),\n })\n\n // A studio titled after its host would otherwise suggest the one slug that's rejected\n const suggestedSlug = toAppSlug(title) ?? undefined\n const slug = await input({\n default: suggestedSlug === config.studioHost ? undefined : suggestedSlug,\n message: 'Application slug (the hostname it deploys to):',\n validate: (value) => {\n if (toAppSlug(value) !== value) {\n return 'Use lowercase letters, numbers and hyphens, starting with a letter.'\n }\n if (value === config.studioHost) {\n return `\"${value}\" is your Studio's hostname (studioHost), so the deploy would fail. Choose a different slug.`\n }\n return true\n },\n })\n\n // `app.id` is the deprecated spelling and deploy still honours it\n const appIdKey = config.deployment?.appId ? 'deployment.appId' : config.app?.id && 'app.id'\n if (appIdKey) {\n output.warn(\n `Remove \\`${appIdKey}\\` from your CLI config before you deploy. It points at your existing application, and deploying with it in place replaces that application with the Dashboard build.`,\n )\n }\n\n const sanityVersion = await getLocalPackageVersion('sanity', workDir)\n if (sanityVersion && lt(sanityVersion, MIN_SANITY_VERSION)) {\n output.warn(\n `This project uses sanity ${sanityVersion}, and \\`defineApplication\\` needs ${MIN_SANITY_VERSION} or later. Upgrade sanity before you run \\`sanity dev\\` or \\`sanity deploy\\`.`,\n )\n }\n\n // getCliConfig has already checked there is exactly one\n const cliConfigPaths = await findPathForFiles(workDir, ['sanity.cli.ts', 'sanity.cli.js'])\n const paths = cliConfigPaths.filter((path) => path.exists).map((path) => path.path)\n\n return {options: {organizationId, slug, title: title.trim()}, paths}\n },\n purpose,\n}\n"],"names":["findPathForFiles","getCliConfig","getLocalPackageVersion","getStudioConfig","isWorkbenchApp","tryFindStudioConfigPath","input","select","toAppSlug","lt","getOrganizationGrants","listOrganizations","getProjectById","getManageUrl","MIN_SANITY_VERSION","purpose","description","trim","dashboard","filename","prepare","output","workDir","config","app","Error","projectId","api","organizationId","undefined","choices","Promise","all","map","id","name","grants","catch","canDeploy","some","resource","grant","disabled","value","choice","message","suggestedTitle","title","studioConfig","resolvePlugins","Array","isArray","default","validate","suggestedSlug","slug","studioHost","appIdKey","deployment","appId","warn","sanityVersion","cliConfigPaths","paths","filter","path","exists","options"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/codemods/dashboard.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {\n findPathForFiles,\n getCliConfig,\n getLocalPackageVersion,\n getStudioConfig,\n isWorkbenchApp,\n tryFindStudioConfigPath,\n} from '@sanity/cli-core'\nimport {getYarnMajorVersion, readPackageJson} from '@sanity/cli-core/package-manager'\nimport {confirm, input, select} from '@sanity/cli-core/ux'\nimport {toAppSlug} from '@sanity/workbench-cli/init'\nimport {execa} from 'execa'\nimport {lt} from 'semver'\nimport yaml from 'yaml'\n\nimport {getOrganizationGrants, listOrganizations} from '../../services/organizations.js'\nimport {getProjectById} from '../../services/projects.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {detectWorkspace} from '../../util/packageManager/installationInfo/detectWorkspace.js'\nimport {\n getPackageManagerChoice,\n getPartialEnvWithNpmPath,\n} from '../../util/packageManager/packageManagerChoice.js'\nimport {getManageUrl} from '../projects/getManageUrl.js'\nimport {type CodeMod} from './types.js'\n\n// `defineApplication` landed in 6.12.0; the Dashboard also needs the CLI fixes released since\nconst MIN_SANITY_VERSION = '6.20.0'\nconst MIN_SDK_VERSION = '3.9.1'\n\ninterface RequiredPackage {\n min: string\n name: string\n neededBy: string\n}\n\nasync function findOutdated(packages: RequiredPackage[], workDir: string) {\n const installed = await Promise.all(\n packages.map(({name}) => getLocalPackageVersion(name, workDir)),\n )\n return packages.flatMap((pkg, index) => {\n const version = installed[index]\n return version && lt(version, pkg.min) ? [{...pkg, version}] : []\n })\n}\n\n// corepack's `packageManager: \"yarn@4.9.1\"` names the major even without a .yarnrc.yml\nfunction declaredYarnMajor(field: unknown) {\n const match = typeof field === 'string' ? /^yarn@(\\d+)/.exec(field) : null\n return match ? Number.parseInt(match[1], 10) : undefined\n}\n\nfunction listOutdated(packages: Awaited<ReturnType<typeof findOutdated>>) {\n return packages\n .map(({min, name, neededBy, version}) => ` - ${name} ${version} (${neededBy} ${min} or later)`)\n .join('\\n')\n}\n\nconst purpose = 'Move an existing Studio or SDK app onto the Dashboard'\nconst description = `\nRewrites sanity.cli.ts (or .js) so the next \\`sanity dev\\` and \\`sanity deploy\\` run the project\nas a new Dashboard application. Asks for the application's title and slug, and looks up the\norganization from the project. Offers to upgrade sanity (older than ${MIN_SANITY_VERSION}) and, in\nSDK apps, @sanity/sdk and @sanity/sdk-react (older than ${MIN_SDK_VERSION}) to their latest versions.\n\nfrom: app: {organizationId: 'oAbc', entry: './src/App.tsx'}\n to: app: defineApplication({title: 'Acme', slug: 'acme', organizationId: 'oAbc', entry: './src/App.tsx'})\n\nThe existing deployment is left alone. Remove \\`deployment.appId\\` before deploying, or the\nDashboard build replaces the existing application.\n`.trim()\n\nexport const dashboard: CodeMod = {\n description,\n filename: 'dashboard.js',\n prepare: async ({dry, output, workDir}) => {\n const config = await getCliConfig(workDir)\n if (isWorkbenchApp(config.app)) {\n throw new Error('This project is already a Dashboard application.')\n }\n\n const projectId = config.api?.projectId\n let organizationId = config.app?.organizationId\n // Deploy creates the application with both IDs, and the API rejects a project outside the\n // organization, so a project's organization is the only valid choice\n if (!organizationId && projectId) {\n organizationId = (await getProjectById(projectId)).organizationId ?? undefined\n if (!organizationId) {\n throw new Error(\n `Project ${projectId} isn't in an organization, and a Dashboard application needs one. Move the project into an organization at ${getManageUrl(projectId)}, then run this again.`,\n )\n }\n }\n if (!organizationId) {\n const choices = await Promise.all(\n (await listOrganizations()).map(async ({id, name}) => {\n // Grants can 401 for implicit memberships; treat any failure as no access\n const grants = await getOrganizationGrants(id).catch(() => null)\n const canDeploy = (grants?.['sanity.sdk.applications'] ?? []).some((resource) =>\n resource.grants.some((grant) => grant.name === 'deploy'),\n )\n return {\n disabled: canDeploy ? false : 'Insufficient permissions',\n name: `${name} [${id}]`,\n value: id,\n }\n }),\n )\n if (!choices.some((choice) => choice.disabled === false)) {\n throw new Error(\n \"You can't deploy applications in any of your organizations. Ask an organization administrator for access, then run this again.\",\n )\n }\n organizationId = await select({choices, message: 'Organization that owns the application:'})\n }\n\n let suggestedTitle = config.app?.title\n if (!suggestedTitle && (await tryFindStudioConfigPath(workDir))) {\n const studioConfig = await getStudioConfig(workDir, {resolvePlugins: false})\n suggestedTitle = Array.isArray(studioConfig) ? undefined : studioConfig.title\n }\n\n const title = await input({\n default: suggestedTitle,\n message: 'Application title:',\n validate: (value) => (value.trim() ? true : 'Enter a title for the application.'),\n })\n\n // A studio titled after its host would otherwise suggest the one slug that's rejected\n const suggestedSlug = toAppSlug(title) ?? undefined\n const slug = await input({\n default: suggestedSlug === config.studioHost ? undefined : suggestedSlug,\n message: 'Application slug (the hostname it deploys to):',\n validate: (value) => {\n if (toAppSlug(value) !== value) {\n return 'Use lowercase letters, numbers and hyphens, starting with a letter.'\n }\n if (value === config.studioHost) {\n return `\"${value}\" is your Studio's hostname (studioHost), so the deploy would fail. Choose a different slug.`\n }\n return true\n },\n })\n\n // `app.id` is the deprecated spelling and deploy still honours it\n const appIdKey = config.deployment?.appId ? 'deployment.appId' : config.app?.id && 'app.id'\n if (appIdKey) {\n output.warn(\n `Remove \\`${appIdKey}\\` from your CLI config before you deploy. It points at your existing application, and deploying with it in place replaces that application with the Dashboard build.`,\n )\n }\n\n const required: RequiredPackage[] = [\n {min: MIN_SANITY_VERSION, name: 'sanity', neededBy: 'the Dashboard needs'},\n ...(determineIsApp(config)\n ? ['@sanity/sdk', '@sanity/sdk-react'].map((name) => ({\n min: MIN_SDK_VERSION,\n name,\n neededBy: 'SDK apps need',\n }))\n : []),\n ]\n const outdated = await findOutdated(required, workDir)\n if (outdated.length > 0) {\n output.warn(\n `\\`sanity dev\\` and \\`sanity deploy\\` will fail until you upgrade:\\n${listOutdated(outdated)}`,\n )\n\n const {chosen: packageManager} = await getPackageManagerChoice(workDir, {interactive: false})\n const {root, yarnBerry} = await detectWorkspace(workDir)\n const [{dependencies, devDependencies}, rootManifest] = await Promise.all([\n readPackageJson(path.join(workDir, 'package.json'), {skipSchemaValidation: true}),\n readFile(path.join(root, 'package.json'), 'utf8').then(JSON.parse, () => null),\n ])\n let pnpmOverrides: string[] = []\n if (packageManager === 'pnpm') {\n const workspacePath = path.join(root, 'pnpm-workspace.yaml')\n const workspaceConfig = await readFile(workspacePath, 'utf8').then(yaml.parse, () => null)\n pnpmOverrides = Object.keys({\n ...rootManifest?.pnpm?.overrides,\n ...workspaceConfig?.overrides,\n })\n }\n\n // bun's upgrade leaves a catalog untouched, yarn's swaps `catalog:` for a plain range, and\n // pnpm's does the same when `overrides` pins the package\n const isUnupgradableCatalog = (name: string) =>\n (dependencies?.[name] ?? devDependencies?.[name] ?? '').startsWith('catalog:') &&\n (packageManager === 'bun' ||\n packageManager === 'yarn' ||\n pnpmOverrides.some((key) => key === name || key.startsWith(`${name}@`)))\n const catalogued = outdated.filter(({name}) => isUnupgradableCatalog(name))\n const upgradable = outdated.filter(({name}) => !isUnupgradableCatalog(name))\n\n if (catalogued.length > 0) {\n const targets = catalogued.map(({min, name}) => `${name} to ^${min} or later`).join(', ')\n const install = `then run \\`${packageManager} install\\``\n output.log(\n packageManager === 'pnpm'\n ? `pnpm can't upgrade catalog packages that \\`overrides\\` pin, so update them yourself: set ${targets} in the catalog and in \\`overrides\\`, ${install}.`\n : `${packageManager} can't upgrade catalog packages, so update them yourself: set ${targets} in the catalog in ${packageManager === 'bun' ? 'the root package.json' : '.yarnrc.yml'}, ${install}.`,\n )\n }\n\n if (upgradable.length > 0) {\n const names = upgradable.map(({name}) => name)\n const latest = names.map((name) => `${name}@latest`)\n // Berry dropped `yarn upgrade`, and the user agent only names yarn when the CLI itself was\n // run through yarn, so take the project's own signals first\n const isYarnBerry =\n yarnBerry ||\n (declaredYarnMajor(rootManifest?.packageManager) ?? getYarnMajorVersion() ?? 1) >= 2\n // pnpm keeps `catalog:` and bumps the catalog entry only with `update --latest`\n const command = {\n bun: ['bun', 'update', ...latest],\n manual: undefined,\n npm: ['npm', 'install', '--legacy-peer-deps', ...latest],\n pnpm: ['pnpm', 'update', ...names, '--latest'],\n yarn: ['yarn', isYarnBerry ? 'up' : 'upgrade', ...latest],\n }[packageManager]\n\n if (!command) {\n output.log(`Upgrade ${names.join(', ')} to the latest version with your package manager.`)\n } else if (\n dry ||\n !(await confirm({\n default: true,\n message: `Upgrade ${names.join(', ')} to the latest version now?`,\n }))\n ) {\n output.log(`Run \\`${command.join(' ')}\\` to upgrade.`)\n } else {\n output.log(`Running \\`${command.join(' ')}\\``)\n // The version check below reports a failed upgrade, so the exit code isn't needed\n await execa(command[0], command.slice(1), {\n cwd: workDir,\n env: getPartialEnvWithNpmPath(workDir),\n reject: false,\n stdio: 'inherit',\n })\n const stillOutdated = await findOutdated(upgradable, workDir)\n if (stillOutdated.length > 0) {\n output.warn(\n `These are still too old after the upgrade. Upgrade them before you run \\`sanity dev\\` or \\`sanity deploy\\`:\\n${listOutdated(stillOutdated)}`,\n )\n }\n }\n }\n }\n\n // getCliConfig has already checked there is exactly one\n const cliConfigPaths = await findPathForFiles(workDir, ['sanity.cli.ts', 'sanity.cli.js'])\n const paths = cliConfigPaths.filter((path) => path.exists).map((path) => path.path)\n\n return {options: {organizationId, slug, title: title.trim()}, paths}\n },\n purpose,\n}\n"],"names":["readFile","path","findPathForFiles","getCliConfig","getLocalPackageVersion","getStudioConfig","isWorkbenchApp","tryFindStudioConfigPath","getYarnMajorVersion","readPackageJson","confirm","input","select","toAppSlug","execa","lt","yaml","getOrganizationGrants","listOrganizations","getProjectById","determineIsApp","detectWorkspace","getPackageManagerChoice","getPartialEnvWithNpmPath","getManageUrl","MIN_SANITY_VERSION","MIN_SDK_VERSION","findOutdated","packages","workDir","installed","Promise","all","map","name","flatMap","pkg","index","version","min","declaredYarnMajor","field","match","exec","Number","parseInt","undefined","listOutdated","neededBy","join","purpose","description","trim","dashboard","filename","prepare","dry","output","config","app","Error","projectId","api","organizationId","choices","id","grants","catch","canDeploy","some","resource","grant","disabled","value","choice","message","suggestedTitle","title","studioConfig","resolvePlugins","Array","isArray","default","validate","suggestedSlug","slug","studioHost","appIdKey","deployment","appId","warn","required","outdated","length","chosen","packageManager","interactive","root","yarnBerry","dependencies","devDependencies","rootManifest","skipSchemaValidation","then","JSON","parse","pnpmOverrides","workspacePath","workspaceConfig","Object","keys","pnpm","overrides","isUnupgradableCatalog","startsWith","key","catalogued","filter","upgradable","targets","install","log","names","latest","isYarnBerry","command","bun","manual","npm","yarn","slice","cwd","env","reject","stdio","stillOutdated","cliConfigPaths","paths","exists","options"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/codemods/types.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\n\nexport interface CodeMod {\n description: string\n // Must match filename in `cli/codemods/`\n filename: string\n purpose: string\n\n /**\n * Runs in the CLI process before the transform (prompts, API lookups). `options` reach the\n * transform's `options` argument; `paths` replace the default target of the whole directory.\n */\n prepare?: (context: {output: Output; workDir: string}) => Promise<{\n options: Record<string, string>\n paths: string[]\n }>\n verify?: (context: {workDir: string}) => Promise<void>\n}\n"],"names":[],"mappings":"AAEA,WAeC"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/codemods/types.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\n\nexport interface CodeMod {\n description: string\n // Must match filename in `cli/codemods/`\n filename: string\n purpose: string\n\n /**\n * Runs in the CLI process before the transform (prompts, API lookups). `options` reach the\n * transform's `options` argument; `paths` replace the default target of the whole directory.\n */\n prepare?: (context: {dry: boolean; output: Output; workDir: string}) => Promise<{\n options: Record<string, string>\n paths: string[]\n }>\n verify?: (context: {workDir: string}) => Promise<void>\n}\n"],"names":[],"mappings":"AAEA,WAeC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { SANITY_CACHE_DIR } from '@sanity/cli-build/_internal/build';
|
|
2
2
|
import { extractCoreAppManifest } from '@sanity/cli-build/_internal/manifest';
|
|
3
3
|
import { isWorkbenchApp, isWorkbenchConfig } from '@sanity/workbench-cli';
|
|
4
|
+
import { startWorkbenchDev, watchForWorkbenchOptIn } from '@sanity/workbench-cli/dev';
|
|
4
5
|
import { checkForDeprecatedAppId } from '../../util/appId.js';
|
|
6
|
+
import { determineIsApp } from '../../util/determineIsApp.js';
|
|
5
7
|
import { getSharedServerConfig } from '../../util/getSharedServerConfig.js';
|
|
6
8
|
import { resolveReactStrictMode } from '../../util/resolveReactStrictMode.js';
|
|
7
9
|
import { extractStudioManifest } from '../manifest/extractStudioManifest.js';
|
|
@@ -10,10 +12,34 @@ import { startStudioDevServer } from './servers/startStudioDevServer.js';
|
|
|
10
12
|
const noop = async ()=>{};
|
|
11
13
|
/**
|
|
12
14
|
* Entry point for `sanity dev`. A plain studio/app starts a single dev server, as
|
|
13
|
-
* before workbench existed
|
|
15
|
+
* before workbench existed, and switches to the workbench if `sanity.cli.*` opts
|
|
16
|
+
* in while it runs. A workbench app (via `defineApplication`) delegates to
|
|
14
17
|
* `@sanity/workbench-cli`, injecting the CLI-domain pieces (app server, manifest
|
|
15
|
-
* extraction, app id)
|
|
18
|
+
* extraction, app id).
|
|
16
19
|
*/ export async function devAction(options) {
|
|
20
|
+
const { cliConfig, output, workDir } = options;
|
|
21
|
+
// A workbench app (an app to render) or a workbench config (config-only, like
|
|
22
|
+
// the media library, which needs the workbench to render it) both delegate.
|
|
23
|
+
if (isWorkbenchApp(cliConfig?.app) || isWorkbenchConfig(cliConfig?.app)) {
|
|
24
|
+
return startWorkbench(options);
|
|
25
|
+
}
|
|
26
|
+
// Plain non-workbench studio/app: one dev server announcing its own URL.
|
|
27
|
+
const result = await (options.isApp ? startAppDevServer : startStudioDevServer)(options);
|
|
28
|
+
if (!result.started) return {
|
|
29
|
+
close: noop
|
|
30
|
+
};
|
|
31
|
+
return watchForWorkbenchOptIn({
|
|
32
|
+
closePlainServer: result.close,
|
|
33
|
+
output,
|
|
34
|
+
startWorkbench: (freshConfig)=>startWorkbench({
|
|
35
|
+
...options,
|
|
36
|
+
cliConfig: freshConfig,
|
|
37
|
+
isApp: determineIsApp(freshConfig)
|
|
38
|
+
}),
|
|
39
|
+
workDir
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
function startWorkbench(options) {
|
|
17
43
|
const { cliConfig, flags, isApp, output, workDir } = options;
|
|
18
44
|
const { httpHost, httpPort } = getSharedServerConfig({
|
|
19
45
|
cliConfig,
|
|
@@ -23,50 +49,28 @@ const noop = async ()=>{};
|
|
|
23
49
|
},
|
|
24
50
|
workDir
|
|
25
51
|
});
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
httpPort: params.httpPort
|
|
33
|
-
});
|
|
34
|
-
// A workbench app (an app to render) or a workbench config (config-only, like
|
|
35
|
-
// the media library, which needs the workbench to render it) both delegate.
|
|
36
|
-
if (isWorkbenchApp(cliConfig?.app) || isWorkbenchConfig(cliConfig?.app)) {
|
|
37
|
-
// Lazy so a non-workbench `sanity dev` never loads the package. `doImport`
|
|
38
|
-
// is path-based and doesn't apply to a bare specifier.
|
|
39
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
40
|
-
const { startWorkbenchDev } = await import('@sanity/workbench-cli/dev');
|
|
41
|
-
return startWorkbenchDev({
|
|
42
|
-
cacheDir: `${SANITY_CACHE_DIR}/vite`,
|
|
43
|
-
checkForDeprecatedAppId: ()=>checkForDeprecatedAppId({
|
|
44
|
-
cliConfig,
|
|
45
|
-
output
|
|
46
|
-
}),
|
|
47
|
-
cliConfig,
|
|
48
|
-
extractManifest: isApp ? ({ workDir: wd })=>extractCoreAppManifest({
|
|
49
|
-
workDir: wd
|
|
50
|
-
}) : (params)=>extractStudioManifest(params),
|
|
51
|
-
httpHost,
|
|
52
|
-
httpPort,
|
|
53
|
-
isApp,
|
|
54
|
-
output,
|
|
55
|
-
// Runtime template needs a concrete boolean; collapse an unset config to off.
|
|
56
|
-
reactStrictMode: resolveReactStrictMode(cliConfig) ?? false,
|
|
57
|
-
startAppServer,
|
|
58
|
-
workDir
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
// Plain non-workbench studio/app: one dev server announcing its own URL.
|
|
62
|
-
const result = await startAppServer({
|
|
63
|
-
announceUrl: true,
|
|
52
|
+
return startWorkbenchDev({
|
|
53
|
+
cacheDir: `${SANITY_CACHE_DIR}/vite`,
|
|
54
|
+
checkForDeprecatedAppId: ()=>checkForDeprecatedAppId({
|
|
55
|
+
cliConfig,
|
|
56
|
+
output
|
|
57
|
+
}),
|
|
64
58
|
cliConfig,
|
|
65
|
-
|
|
59
|
+
extractManifest: isApp ? ({ workDir: wd })=>extractCoreAppManifest({
|
|
60
|
+
workDir: wd
|
|
61
|
+
}) : (params)=>extractStudioManifest(params),
|
|
62
|
+
httpHost,
|
|
63
|
+
httpPort,
|
|
64
|
+
isApp,
|
|
65
|
+
output,
|
|
66
|
+
// Runtime template needs a concrete boolean; collapse an unset config to off.
|
|
67
|
+
reactStrictMode: resolveReactStrictMode(cliConfig) ?? false,
|
|
68
|
+
startAppServer: (params)=>(isApp ? startAppDevServer : startStudioDevServer)({
|
|
69
|
+
...options,
|
|
70
|
+
...params
|
|
71
|
+
}),
|
|
72
|
+
workDir
|
|
66
73
|
});
|
|
67
|
-
return {
|
|
68
|
-
close: result.started ? result.close : noop
|
|
69
|
-
};
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
//# sourceMappingURL=devAction.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/devAction.ts"],"sourcesContent":["import {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {extractCoreAppManifest} from '@sanity/cli-build/_internal/manifest'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/devAction.ts"],"sourcesContent":["import {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {extractCoreAppManifest} from '@sanity/cli-build/_internal/manifest'\nimport {isWorkbenchApp, isWorkbenchConfig} from '@sanity/workbench-cli'\nimport {startWorkbenchDev, watchForWorkbenchOptIn} from '@sanity/workbench-cli/dev'\n\nimport {checkForDeprecatedAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {getSharedServerConfig} from '../../util/getSharedServerConfig.js'\nimport {resolveReactStrictMode} from '../../util/resolveReactStrictMode.js'\nimport {extractStudioManifest} from '../manifest/extractStudioManifest.js'\nimport {startAppDevServer} from './servers/startAppDevServer.js'\nimport {startStudioDevServer} from './servers/startStudioDevServer.js'\nimport {type DevActionOptions} from './types.js'\n\nconst noop = async () => {}\n\n/**\n * Entry point for `sanity dev`. A plain studio/app starts a single dev server, as\n * before workbench existed, and switches to the workbench if `sanity.cli.*` opts\n * in while it runs. A workbench app (via `defineApplication`) delegates to\n * `@sanity/workbench-cli`, injecting the CLI-domain pieces (app server, manifest\n * extraction, app id).\n */\nexport async function devAction(options: DevActionOptions): Promise<{close: () => Promise<void>}> {\n const {cliConfig, output, workDir} = options\n\n // A workbench app (an app to render) or a workbench config (config-only, like\n // the media library, which needs the workbench to render it) both delegate.\n if (isWorkbenchApp(cliConfig?.app) || isWorkbenchConfig(cliConfig?.app)) {\n return startWorkbench(options)\n }\n\n // Plain non-workbench studio/app: one dev server announcing its own URL.\n const result = await (options.isApp ? startAppDevServer : startStudioDevServer)(options)\n if (!result.started) return {close: noop}\n\n return watchForWorkbenchOptIn({\n closePlainServer: result.close,\n output,\n startWorkbench: (freshConfig) =>\n startWorkbench({...options, cliConfig: freshConfig, isApp: determineIsApp(freshConfig)}),\n workDir,\n })\n}\n\nfunction startWorkbench(options: DevActionOptions): Promise<{close: () => Promise<void>}> {\n const {cliConfig, flags, isApp, output, workDir} = options\n const {httpHost, httpPort} = getSharedServerConfig({\n cliConfig,\n flags: {host: flags.host, port: flags.port},\n workDir,\n })\n\n return startWorkbenchDev({\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,\n httpPort,\n isApp,\n output,\n // Runtime template needs a concrete boolean; collapse an unset config to off.\n reactStrictMode: resolveReactStrictMode(cliConfig) ?? false,\n startAppServer: (params) =>\n (isApp ? startAppDevServer : startStudioDevServer)({...options, ...params}),\n workDir,\n })\n}\n"],"names":["SANITY_CACHE_DIR","extractCoreAppManifest","isWorkbenchApp","isWorkbenchConfig","startWorkbenchDev","watchForWorkbenchOptIn","checkForDeprecatedAppId","determineIsApp","getSharedServerConfig","resolveReactStrictMode","extractStudioManifest","startAppDevServer","startStudioDevServer","noop","devAction","options","cliConfig","output","workDir","app","startWorkbench","result","isApp","started","close","closePlainServer","freshConfig","flags","httpHost","httpPort","host","port","cacheDir","extractManifest","wd","params","reactStrictMode","startAppServer"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,oCAAmC;AAClE,SAAQC,sBAAsB,QAAO,uCAAsC;AAC3E,SAAQC,cAAc,EAAEC,iBAAiB,QAAO,wBAAuB;AACvE,SAAQC,iBAAiB,EAAEC,sBAAsB,QAAO,4BAA2B;AAEnF,SAAQC,uBAAuB,QAAO,sBAAqB;AAC3D,SAAQC,cAAc,QAAO,+BAA8B;AAC3D,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,sBAAsB,QAAO,uCAAsC;AAC3E,SAAQC,qBAAqB,QAAO,uCAAsC;AAC1E,SAAQC,iBAAiB,QAAO,iCAAgC;AAChE,SAAQC,oBAAoB,QAAO,oCAAmC;AAGtE,MAAMC,OAAO,WAAa;AAE1B;;;;;;CAMC,GACD,OAAO,eAAeC,UAAUC,OAAyB;IACvD,MAAM,EAACC,SAAS,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGH;IAErC,8EAA8E;IAC9E,4EAA4E;IAC5E,IAAIb,eAAec,WAAWG,QAAQhB,kBAAkBa,WAAWG,MAAM;QACvE,OAAOC,eAAeL;IACxB;IAEA,yEAAyE;IACzE,MAAMM,SAAS,MAAM,AAACN,CAAAA,QAAQO,KAAK,GAAGX,oBAAoBC,oBAAmB,EAAGG;IAChF,IAAI,CAACM,OAAOE,OAAO,EAAE,OAAO;QAACC,OAAOX;IAAI;IAExC,OAAOR,uBAAuB;QAC5BoB,kBAAkBJ,OAAOG,KAAK;QAC9BP;QACAG,gBAAgB,CAACM,cACfN,eAAe;gBAAC,GAAGL,OAAO;gBAAEC,WAAWU;gBAAaJ,OAAOf,eAAemB;YAAY;QACxFR;IACF;AACF;AAEA,SAASE,eAAeL,OAAyB;IAC/C,MAAM,EAACC,SAAS,EAAEW,KAAK,EAAEL,KAAK,EAAEL,MAAM,EAAEC,OAAO,EAAC,GAAGH;IACnD,MAAM,EAACa,QAAQ,EAAEC,QAAQ,EAAC,GAAGrB,sBAAsB;QACjDQ;QACAW,OAAO;YAACG,MAAMH,MAAMG,IAAI;YAAEC,MAAMJ,MAAMI,IAAI;QAAA;QAC1Cb;IACF;IAEA,OAAOd,kBAAkB;QACvB4B,UAAU,GAAGhC,iBAAiB,KAAK,CAAC;QACpCM,yBAAyB,IAAMA,wBAAwB;gBAACU;gBAAWC;YAAM;QACzED;QACAiB,iBAAiBX,QACb,CAAC,EAACJ,SAASgB,EAAE,EAAC,GAAKjC,uBAAuB;gBAACiB,SAASgB;YAAE,KACtD,CAACC,SAAWzB,sBAAsByB;QACtCP;QACAC;QACAP;QACAL;QACA,8EAA8E;QAC9EmB,iBAAiB3B,uBAAuBO,cAAc;QACtDqB,gBAAgB,CAACF,SACf,AAACb,CAAAA,QAAQX,oBAAoBC,oBAAmB,EAAG;gBAAC,GAAGG,OAAO;gBAAE,GAAGoB,MAAM;YAAA;QAC3EjB;IACF;AACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getSanityEnv } from '
|
|
1
|
+
import { getSanityEnv } from '@sanity/cli-core/util';
|
|
2
2
|
import { createOrAppendEnvVars } from './env/createOrAppendEnvVars.js';
|
|
3
3
|
import { fetchPostInitPrompt } from './fetchPostInitPrompt.js';
|
|
4
4
|
export function shouldPrompt(unattended, flagValue) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/initHelpers.ts"],"sourcesContent":["import {getSanityEnv} from '
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/initHelpers.ts"],"sourcesContent":["import {getSanityEnv} from '@sanity/cli-core/util'\n\nimport {type EditorName} from '../mcp/editorConfigs.js'\nimport {createOrAppendEnvVars} from './env/createOrAppendEnvVars.js'\nimport {fetchPostInitPrompt} from './fetchPostInitPrompt.js'\nimport {type InitContext} from './types.js'\n\nexport function shouldPrompt(unattended: boolean, flagValue: unknown): boolean {\n return !unattended && flagValue === undefined\n}\n\nexport function flagOrDefault(flagValue: boolean | undefined, defaultValue: boolean): boolean {\n return typeof flagValue === 'boolean' ? flagValue : defaultValue\n}\n\nexport async function getPostInitMCPPrompt(editorsNames: EditorName[]): Promise<string> {\n return fetchPostInitPrompt(new Intl.ListFormat('en').format(editorsNames))\n}\n\nexport async function writeStagingEnvIfNeeded(\n output: InitContext['output'],\n outputPath: string,\n): Promise<void> {\n const sanityEnv = getSanityEnv()\n if (sanityEnv === 'production') return\n\n await createOrAppendEnvVars({\n envVars: {INTERNAL_ENV: sanityEnv},\n filename: '.env',\n framework: null,\n log: false,\n output,\n outputPath,\n })\n}\n"],"names":["getSanityEnv","createOrAppendEnvVars","fetchPostInitPrompt","shouldPrompt","unattended","flagValue","undefined","flagOrDefault","defaultValue","getPostInitMCPPrompt","editorsNames","Intl","ListFormat","format","writeStagingEnvIfNeeded","output","outputPath","sanityEnv","envVars","INTERNAL_ENV","filename","framework","log"],"mappings":"AAAA,SAAQA,YAAY,QAAO,wBAAuB;AAGlD,SAAQC,qBAAqB,QAAO,iCAAgC;AACpE,SAAQC,mBAAmB,QAAO,2BAA0B;AAG5D,OAAO,SAASC,aAAaC,UAAmB,EAAEC,SAAkB;IAClE,OAAO,CAACD,cAAcC,cAAcC;AACtC;AAEA,OAAO,SAASC,cAAcF,SAA8B,EAAEG,YAAqB;IACjF,OAAO,OAAOH,cAAc,YAAYA,YAAYG;AACtD;AAEA,OAAO,eAAeC,qBAAqBC,YAA0B;IACnE,OAAOR,oBAAoB,IAAIS,KAAKC,UAAU,CAAC,MAAMC,MAAM,CAACH;AAC9D;AAEA,OAAO,eAAeI,wBACpBC,MAA6B,EAC7BC,UAAkB;IAElB,MAAMC,YAAYjB;IAClB,IAAIiB,cAAc,cAAc;IAEhC,MAAMhB,sBAAsB;QAC1BiB,SAAS;YAACC,cAAcF;QAAS;QACjCG,UAAU;QACVC,WAAW;QACXC,KAAK;QACLP;QACAC;IACF;AACF"}
|
|
@@ -64,7 +64,7 @@ export async function initStudio({ datasetName, defaults, displayName, isFirstPr
|
|
|
64
64
|
const { ImportDatasetCommand } = await import('../../commands/datasets/import.js');
|
|
65
65
|
await ImportDatasetCommand.run([
|
|
66
66
|
resolvedTemplate.datasetUrl,
|
|
67
|
-
'--project
|
|
67
|
+
'--project',
|
|
68
68
|
projectId,
|
|
69
69
|
'--dataset',
|
|
70
70
|
datasetName,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/initStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {getCliToken, type Output, subdebug, type TelemetryUserProperties} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\n\nimport {updateProjectInitializedAt} from '../../services/projects.js'\nimport {type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {getInstallCommand} from '../../util/packageManager/installPackages.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {type EditorName} from '../mcp/editorConfigs.js'\nimport {InitError} from './initError.js'\nimport {getPostInitMCPPrompt} from './initHelpers.js'\nimport {type RepoInfo} from './remoteTemplate.js'\nimport {scaffoldAndInstall, selectTemplate} from './scaffoldTemplate.js'\nimport {type InitOptions} from './types.js'\n\nconst debug = subdebug('init')\n\nasync function promptForDatasetImport(message?: string): Promise<boolean> {\n return confirm({\n default: true,\n message: message || 'This template includes a sample dataset, would you like to use it?',\n })\n}\n\nexport async function initStudio({\n datasetName,\n defaults,\n displayName,\n isFirstProject,\n mcpConfigured,\n options,\n organizationId,\n output,\n outputPath,\n preclaim = false,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n trace,\n workbench,\n workDir,\n}: {\n datasetName: string\n defaults: {projectName: string}\n displayName: string\n isFirstProject: boolean\n mcpConfigured: EditorName[]\n options: InitOptions\n organizationId: string | undefined\n output: Output\n outputPath: string\n preclaim?: boolean\n projectId: string\n remoteTemplateInfo: RepoInfo | undefined\n sluggedName: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n workbench: boolean\n workDir: string\n}): Promise<void> {\n const {importDataset, install, unattended} = options\n const {\n template: resolvedTemplate,\n templateName,\n useTypeScript,\n } = await selectTemplate({\n options,\n remoteTemplateInfo,\n trace,\n })\n\n if (!remoteTemplateInfo && !resolvedTemplate) {\n throw new InitError(`Template \"${templateName}\" not found`, 1)\n }\n\n // If the template has a sample dataset, prompt the user whether or not we should import it\n const shouldImport =\n resolvedTemplate?.datasetUrl &&\n (importDataset ??\n (!unattended && (await promptForDatasetImport(resolvedTemplate.importPrompt))))\n\n trace.log({\n selectedOption: shouldImport ? 'yes' : 'no',\n step: 'importTemplateDataset',\n })\n\n if (!preclaim) {\n try {\n await updateProjectInitializedAt(projectId)\n } catch (err) {\n // Non-critical update\n debug('Failed to update cliInitializedAt metadata', err)\n }\n }\n\n const {pkgManager} = await scaffoldAndInstall({\n datasetName,\n defaults,\n displayName,\n options,\n organizationId,\n output,\n outputPath,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n templateName,\n trace,\n useTypeScript,\n workbench,\n workDir,\n })\n\n // Prompt for dataset import (if a dataset is defined)\n if (shouldImport && resolvedTemplate?.datasetUrl) {\n const token = await getCliToken()\n if (!token) {\n throw new InitError('Authentication required to import dataset', 1)\n }\n // eslint-disable-next-line no-restricted-syntax\n const {ImportDatasetCommand} = await import('../../commands/datasets/import.js')\n await ImportDatasetCommand.run(\n [\n resolvedTemplate.datasetUrl,\n '--project-id',\n projectId,\n '--dataset',\n datasetName,\n '--token',\n token,\n '--missing',\n ],\n {\n root: outputPath,\n },\n )\n\n output.log('')\n output.log('If you want to delete the imported data, use')\n output.log(` ${styleText('cyan', `npx sanity dataset delete ${datasetName}`)}`)\n output.log('and create a new clean dataset with')\n output.log(` ${styleText('cyan', `npx sanity dataset create <name>`)}\\n`)\n }\n\n // `sanity new` owns the combined Studio/frontend outro.\n if (preclaim) return\n\n const devCommandMap: Record<PackageManager, string> = {\n bun: 'bun dev',\n manual: 'npm run dev',\n npm: 'npm run dev',\n pnpm: 'pnpm dev',\n yarn: 'yarn dev',\n }\n const devCommand = devCommandMap[pkgManager]\n\n const isCurrentDir = outputPath === workDir\n const goToProjectDir = `\\n(${styleText('cyan', `cd ${outputPath}`)} to navigate to your new project directory)`\n\n //output for Studios here\n output.log(`\\u2705 ${styleText(['green', 'bold'], 'Success!')} Your Studio has been created.`)\n if (!isCurrentDir) output.log(goToProjectDir)\n const startupCommands = install\n ? styleText('cyan', devCommand)\n : `${styleText('cyan', getInstallCommand(pkgManager))}, then ${styleText('cyan', devCommand)}`\n output.log(\n `\\nGet started by running ${startupCommands} to launch your Studio's development server`,\n )\n if (mcpConfigured && mcpConfigured.length > 0) {\n const message = await getPostInitMCPPrompt(mcpConfigured)\n output.log(`\\n${message}`)\n output.log(`\\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`)\n output.log(\n `\\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`,\n )\n }\n output.log('\\n')\n output.log(`Other helpful commands:`)\n output.log(`npx sanity docs browse to open the documentation in a browser`)\n output.log(`npx sanity manage to open the project settings in a browser`)\n output.log(`npx sanity help to explore the CLI manual`)\n\n if (isFirstProject) {\n trace.log({selectedOption: 'yes', step: 'sendCommunityInvite'})\n\n const DISCORD_INVITE_LINK = 'https://www.sanity.io/community/join'\n\n output.log(`\\nJoin the Sanity community: ${styleText('cyan', DISCORD_INVITE_LINK)}`)\n output.log('We look forward to seeing you there!\\n')\n }\n}\n"],"names":["styleText","getCliToken","subdebug","confirm","updateProjectInitializedAt","getInstallCommand","InitError","getPostInitMCPPrompt","scaffoldAndInstall","selectTemplate","debug","promptForDatasetImport","message","default","initStudio","datasetName","defaults","displayName","isFirstProject","mcpConfigured","options","organizationId","output","outputPath","preclaim","projectId","remoteTemplateInfo","sluggedName","trace","workbench","workDir","importDataset","install","unattended","template","resolvedTemplate","templateName","useTypeScript","shouldImport","datasetUrl","importPrompt","log","selectedOption","step","err","pkgManager","token","ImportDatasetCommand","run","root","devCommandMap","bun","manual","npm","pnpm","yarn","devCommand","isCurrentDir","goToProjectDir","startupCommands","length","DISCORD_INVITE_LINK"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/initStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {getCliToken, type Output, subdebug, type TelemetryUserProperties} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\n\nimport {updateProjectInitializedAt} from '../../services/projects.js'\nimport {type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {getInstallCommand} from '../../util/packageManager/installPackages.js'\nimport {type PackageManager} from '../../util/packageManager/packageManagerChoice.js'\nimport {type EditorName} from '../mcp/editorConfigs.js'\nimport {InitError} from './initError.js'\nimport {getPostInitMCPPrompt} from './initHelpers.js'\nimport {type RepoInfo} from './remoteTemplate.js'\nimport {scaffoldAndInstall, selectTemplate} from './scaffoldTemplate.js'\nimport {type InitOptions} from './types.js'\n\nconst debug = subdebug('init')\n\nasync function promptForDatasetImport(message?: string): Promise<boolean> {\n return confirm({\n default: true,\n message: message || 'This template includes a sample dataset, would you like to use it?',\n })\n}\n\nexport async function initStudio({\n datasetName,\n defaults,\n displayName,\n isFirstProject,\n mcpConfigured,\n options,\n organizationId,\n output,\n outputPath,\n preclaim = false,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n trace,\n workbench,\n workDir,\n}: {\n datasetName: string\n defaults: {projectName: string}\n displayName: string\n isFirstProject: boolean\n mcpConfigured: EditorName[]\n options: InitOptions\n organizationId: string | undefined\n output: Output\n outputPath: string\n preclaim?: boolean\n projectId: string\n remoteTemplateInfo: RepoInfo | undefined\n sluggedName: string\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n workbench: boolean\n workDir: string\n}): Promise<void> {\n const {importDataset, install, unattended} = options\n const {\n template: resolvedTemplate,\n templateName,\n useTypeScript,\n } = await selectTemplate({\n options,\n remoteTemplateInfo,\n trace,\n })\n\n if (!remoteTemplateInfo && !resolvedTemplate) {\n throw new InitError(`Template \"${templateName}\" not found`, 1)\n }\n\n // If the template has a sample dataset, prompt the user whether or not we should import it\n const shouldImport =\n resolvedTemplate?.datasetUrl &&\n (importDataset ??\n (!unattended && (await promptForDatasetImport(resolvedTemplate.importPrompt))))\n\n trace.log({\n selectedOption: shouldImport ? 'yes' : 'no',\n step: 'importTemplateDataset',\n })\n\n if (!preclaim) {\n try {\n await updateProjectInitializedAt(projectId)\n } catch (err) {\n // Non-critical update\n debug('Failed to update cliInitializedAt metadata', err)\n }\n }\n\n const {pkgManager} = await scaffoldAndInstall({\n datasetName,\n defaults,\n displayName,\n options,\n organizationId,\n output,\n outputPath,\n projectId,\n remoteTemplateInfo,\n sluggedName,\n templateName,\n trace,\n useTypeScript,\n workbench,\n workDir,\n })\n\n // Prompt for dataset import (if a dataset is defined)\n if (shouldImport && resolvedTemplate?.datasetUrl) {\n const token = await getCliToken()\n if (!token) {\n throw new InitError('Authentication required to import dataset', 1)\n }\n // eslint-disable-next-line no-restricted-syntax\n const {ImportDatasetCommand} = await import('../../commands/datasets/import.js')\n await ImportDatasetCommand.run(\n [\n resolvedTemplate.datasetUrl,\n '--project',\n projectId,\n '--dataset',\n datasetName,\n '--token',\n token,\n '--missing',\n ],\n {\n root: outputPath,\n },\n )\n\n output.log('')\n output.log('If you want to delete the imported data, use')\n output.log(` ${styleText('cyan', `npx sanity dataset delete ${datasetName}`)}`)\n output.log('and create a new clean dataset with')\n output.log(` ${styleText('cyan', `npx sanity dataset create <name>`)}\\n`)\n }\n\n // `sanity new` owns the combined Studio/frontend outro.\n if (preclaim) return\n\n const devCommandMap: Record<PackageManager, string> = {\n bun: 'bun dev',\n manual: 'npm run dev',\n npm: 'npm run dev',\n pnpm: 'pnpm dev',\n yarn: 'yarn dev',\n }\n const devCommand = devCommandMap[pkgManager]\n\n const isCurrentDir = outputPath === workDir\n const goToProjectDir = `\\n(${styleText('cyan', `cd ${outputPath}`)} to navigate to your new project directory)`\n\n //output for Studios here\n output.log(`\\u2705 ${styleText(['green', 'bold'], 'Success!')} Your Studio has been created.`)\n if (!isCurrentDir) output.log(goToProjectDir)\n const startupCommands = install\n ? styleText('cyan', devCommand)\n : `${styleText('cyan', getInstallCommand(pkgManager))}, then ${styleText('cyan', devCommand)}`\n output.log(\n `\\nGet started by running ${startupCommands} to launch your Studio's development server`,\n )\n if (mcpConfigured && mcpConfigured.length > 0) {\n const message = await getPostInitMCPPrompt(mcpConfigured)\n output.log(`\\n${message}`)\n output.log(`\\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`)\n output.log(\n `\\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`,\n )\n }\n output.log('\\n')\n output.log(`Other helpful commands:`)\n output.log(`npx sanity docs browse to open the documentation in a browser`)\n output.log(`npx sanity manage to open the project settings in a browser`)\n output.log(`npx sanity help to explore the CLI manual`)\n\n if (isFirstProject) {\n trace.log({selectedOption: 'yes', step: 'sendCommunityInvite'})\n\n const DISCORD_INVITE_LINK = 'https://www.sanity.io/community/join'\n\n output.log(`\\nJoin the Sanity community: ${styleText('cyan', DISCORD_INVITE_LINK)}`)\n output.log('We look forward to seeing you there!\\n')\n }\n}\n"],"names":["styleText","getCliToken","subdebug","confirm","updateProjectInitializedAt","getInstallCommand","InitError","getPostInitMCPPrompt","scaffoldAndInstall","selectTemplate","debug","promptForDatasetImport","message","default","initStudio","datasetName","defaults","displayName","isFirstProject","mcpConfigured","options","organizationId","output","outputPath","preclaim","projectId","remoteTemplateInfo","sluggedName","trace","workbench","workDir","importDataset","install","unattended","template","resolvedTemplate","templateName","useTypeScript","shouldImport","datasetUrl","importPrompt","log","selectedOption","step","err","pkgManager","token","ImportDatasetCommand","run","root","devCommandMap","bun","manual","npm","pnpm","yarn","devCommand","isCurrentDir","goToProjectDir","startupCommands","length","DISCORD_INVITE_LINK"],"mappings":"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"}
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
import { subdebug } from '@sanity/cli-core';
|
|
2
|
-
import {
|
|
2
|
+
import { search, Separator } from '@sanity/cli-core/ux';
|
|
3
3
|
import { promptForDatasetName } from '../../../prompts/promptForDatasetName.js';
|
|
4
4
|
import { promptForDefaultConfig } from '../../../prompts/promptForDefaultConfig.js';
|
|
5
5
|
import { listDatasets } from '../../../services/datasets.js';
|
|
6
6
|
import { getProjectFeatures } from '../../../services/getProjectFeatures.js';
|
|
7
|
+
import { searchChoices, searchTheme } from '../../../util/searchChoices.js';
|
|
7
8
|
import { createDataset } from '../../dataset/create.js';
|
|
8
9
|
const debug = subdebug('init');
|
|
9
10
|
export async function getOrCreateDataset(opts) {
|
|
10
11
|
const { dataset, visibility } = opts;
|
|
11
12
|
let { defaultConfig } = opts;
|
|
12
|
-
if (dataset && opts.unattended) {
|
|
13
|
-
return {
|
|
14
|
-
datasetName: dataset,
|
|
15
|
-
userAction: 'none'
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
13
|
const [datasets, projectFeatures] = await Promise.all([
|
|
19
14
|
listDatasets(opts.projectId),
|
|
20
15
|
getProjectFeatures(opts.projectId)
|
|
@@ -27,6 +22,7 @@ export async function getOrCreateDataset(opts) {
|
|
|
27
22
|
await createDataset({
|
|
28
23
|
datasetName: dataset,
|
|
29
24
|
forcePublic: defaultConfig,
|
|
25
|
+
isUnattended: opts.unattended,
|
|
30
26
|
output: opts.output,
|
|
31
27
|
projectFeatures,
|
|
32
28
|
projectId: opts.projectId,
|
|
@@ -35,7 +31,7 @@ export async function getOrCreateDataset(opts) {
|
|
|
35
31
|
}
|
|
36
32
|
return {
|
|
37
33
|
datasetName: dataset,
|
|
38
|
-
userAction: 'none'
|
|
34
|
+
userAction: existing ? 'none' : 'create'
|
|
39
35
|
};
|
|
40
36
|
}
|
|
41
37
|
if (opts.unattended) {
|
|
@@ -81,18 +77,20 @@ export async function getOrCreateDataset(opts) {
|
|
|
81
77
|
}
|
|
82
78
|
debug(`User has ${datasets.length} dataset(s) already, showing list of choices`);
|
|
83
79
|
const datasetChoices = datasets.map((dataset)=>({
|
|
80
|
+
name: dataset.name,
|
|
84
81
|
value: dataset.name
|
|
85
82
|
}));
|
|
86
|
-
const selected = await
|
|
87
|
-
|
|
83
|
+
const selected = await search({
|
|
84
|
+
message: 'Select dataset to use',
|
|
85
|
+
source: searchChoices([
|
|
88
86
|
{
|
|
89
87
|
name: 'Create new dataset',
|
|
90
88
|
value: 'new'
|
|
91
89
|
},
|
|
92
90
|
new Separator(),
|
|
93
91
|
...datasetChoices
|
|
94
|
-
],
|
|
95
|
-
|
|
92
|
+
]),
|
|
93
|
+
theme: searchTheme
|
|
96
94
|
});
|
|
97
95
|
if (selected === 'new') {
|
|
98
96
|
const existingDatasetNames = datasets.map((ds)=>ds.name);
|