@sanity/cli 6.3.1 → 6.4.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 +311 -452
- package/dist/actions/build/decorateIndexWithStagingScript.js +16 -0
- package/dist/actions/build/decorateIndexWithStagingScript.js.map +1 -0
- package/dist/actions/build/writeSanityRuntime.js +3 -2
- package/dist/actions/build/writeSanityRuntime.js.map +1 -1
- package/dist/actions/dataset/create.js +4 -0
- package/dist/actions/dataset/create.js.map +1 -1
- package/dist/actions/deploy/findUserApplicationForApp.js +1 -0
- package/dist/actions/deploy/findUserApplicationForApp.js.map +1 -1
- package/dist/actions/deploy/types.js +1 -1
- package/dist/actions/deploy/types.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/initApp.js +72 -0
- package/dist/actions/init/initApp.js.map +1 -0
- package/dist/actions/init/initHelpers.js +37 -0
- package/dist/actions/init/initHelpers.js.map +1 -0
- package/dist/actions/init/initNextJs.js +246 -0
- package/dist/actions/init/initNextJs.js.map +1 -0
- package/dist/actions/init/initStudio.js +127 -0
- package/dist/actions/init/initStudio.js.map +1 -0
- package/dist/actions/init/scaffoldTemplate.js +114 -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/nextjs/index.js +1 -2
- package/dist/actions/init/templates/nextjs/index.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/manifest/types.js +1 -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/schema/types.js +3 -3
- package/dist/actions/schema/types.js.map +1 -1
- package/dist/actions/users/validateEmail.js +2 -2
- package/dist/actions/users/validateEmail.js.map +1 -1
- package/dist/commands/backups/disable.js +1 -1
- package/dist/commands/backups/disable.js.map +1 -1
- package/dist/commands/backups/download.js +1 -1
- package/dist/commands/backups/download.js.map +1 -1
- package/dist/commands/backups/enable.js +1 -1
- package/dist/commands/backups/enable.js.map +1 -1
- package/dist/commands/backups/list.js +1 -1
- package/dist/commands/backups/list.js.map +1 -1
- package/dist/commands/build.js +1 -1
- package/dist/commands/build.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 +2 -2
- 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/alias/delete.js +1 -1
- package/dist/commands/datasets/alias/delete.js.map +1 -1
- package/dist/commands/datasets/alias/link.js +1 -1
- package/dist/commands/datasets/alias/link.js.map +1 -1
- package/dist/commands/datasets/alias/unlink.js +1 -1
- package/dist/commands/datasets/alias/unlink.js.map +1 -1
- package/dist/commands/datasets/copy.js +15 -1
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/datasets/create.js +1 -1
- package/dist/commands/datasets/create.js.map +1 -1
- package/dist/commands/datasets/delete.js +1 -1
- package/dist/commands/datasets/delete.js.map +1 -1
- package/dist/commands/datasets/embeddings/enable.js +11 -0
- package/dist/commands/datasets/embeddings/enable.js.map +1 -1
- package/dist/commands/datasets/export.js +2 -2
- package/dist/commands/datasets/export.js.map +1 -1
- package/dist/commands/datasets/list.js +2 -2
- package/dist/commands/datasets/list.js.map +1 -1
- package/dist/commands/debug.js +1 -1
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/deploy.js +3 -3
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/dev.js +5 -5
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/docs/browse.js +1 -1
- package/dist/commands/docs/browse.js.map +1 -1
- package/dist/commands/documents/delete.js +1 -1
- package/dist/commands/documents/delete.js.map +1 -1
- package/dist/commands/exec.js +2 -2
- package/dist/commands/exec.js.map +1 -1
- package/dist/commands/graphql/deploy.js +2 -2
- package/dist/commands/graphql/deploy.js.map +1 -1
- package/dist/commands/graphql/list.js +2 -2
- package/dist/commands/graphql/list.js.map +1 -1
- package/dist/commands/hooks/create.js +2 -2
- package/dist/commands/hooks/create.js.map +1 -1
- package/dist/commands/hooks/delete.js +5 -5
- package/dist/commands/hooks/delete.js.map +1 -1
- package/dist/commands/hooks/list.js +3 -3
- package/dist/commands/hooks/list.js.map +1 -1
- package/dist/commands/hooks/logs.js +5 -5
- package/dist/commands/hooks/logs.js.map +1 -1
- package/dist/commands/init.js +175 -490
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.js +1 -1
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/learn.js +1 -1
- package/dist/commands/learn.js.map +1 -1
- package/dist/commands/login.js +1 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/logout.js.map +1 -1
- package/dist/commands/manage.js +1 -1
- package/dist/commands/manage.js.map +1 -1
- package/dist/commands/manifest/extract.js +2 -2
- package/dist/commands/manifest/extract.js.map +1 -1
- package/dist/commands/mcp/configure.js +1 -1
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/commands/media/delete-aspect.js +1 -1
- package/dist/commands/media/delete-aspect.js.map +1 -1
- package/dist/commands/media/export.js +1 -1
- package/dist/commands/media/export.js.map +1 -1
- package/dist/commands/preview.js +3 -3
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/projects/list.js +4 -2
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/schemas/deploy.js +3 -4
- package/dist/commands/schemas/deploy.js.map +1 -1
- package/dist/commands/schemas/extract.js +3 -3
- package/dist/commands/schemas/extract.js.map +1 -1
- package/dist/commands/schemas/list.js +4 -5
- package/dist/commands/schemas/list.js.map +1 -1
- package/dist/commands/telemetry/disable.js +2 -2
- package/dist/commands/telemetry/disable.js.map +1 -1
- package/dist/commands/telemetry/enable.js +2 -2
- package/dist/commands/telemetry/enable.js.map +1 -1
- package/dist/commands/telemetry/status.js +2 -2
- package/dist/commands/telemetry/status.js.map +1 -1
- package/dist/commands/tokens/add.js +1 -1
- package/dist/commands/tokens/add.js.map +1 -1
- package/dist/commands/tokens/delete.js +1 -1
- 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/list.js +1 -1
- package/dist/commands/users/list.js.map +1 -1
- package/dist/commands/versions.js +1 -1
- package/dist/commands/versions.js.map +1 -1
- package/dist/hooks/prerun/injectEnvVariables.js +3 -5
- package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
- package/dist/server/vite/plugin-sanity-build-entries.js +3 -2
- 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/packageManager/installationInfo/detectPackages.js +13 -7
- package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -1
- package/dist/util/telemetry/createTelemetryStore.js +27 -12
- package/dist/util/telemetry/createTelemetryStore.js.map +1 -1
- 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/dist/util/validateProjection.js +121 -0
- package/dist/util/validateProjection.js.map +1 -0
- package/oclif.manifest.json +698 -681
- package/package.json +24 -23
- 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
package/dist/commands/init.js
CHANGED
|
@@ -1,56 +1,44 @@
|
|
|
1
|
-
import { existsSync } from 'node:fs';
|
|
2
|
-
import { mkdir, writeFile } from 'node:fs/promises';
|
|
3
1
|
import path from 'node:path';
|
|
4
2
|
import { styleText } from 'node:util';
|
|
5
3
|
import { Args, Flags } from '@oclif/core';
|
|
6
4
|
import { CLIError } from '@oclif/core/errors';
|
|
7
|
-
import {
|
|
5
|
+
import { SanityCommand, subdebug } from '@sanity/cli-core';
|
|
8
6
|
import { confirm, input, logSymbols, select, Separator, spinner } from '@sanity/cli-core/ux';
|
|
9
7
|
import { isHttpError } from '@sanity/client';
|
|
10
8
|
import { frameworks } from '@vercel/frameworks';
|
|
11
|
-
import { execa } from 'execa';
|
|
12
9
|
import deburr from 'lodash-es/deburr.js';
|
|
13
10
|
import { validateSession } from '../actions/auth/ensureAuthenticated.js';
|
|
14
11
|
import { getProviderName } from '../actions/auth/getProviderName.js';
|
|
15
12
|
import { login } from '../actions/auth/login/login.js';
|
|
16
13
|
import { createDataset } from '../actions/dataset/create.js';
|
|
17
|
-
import { bootstrapTemplate } from '../actions/init/bootstrapTemplate.js';
|
|
18
14
|
import { checkNextJsReactCompatibility } from '../actions/init/checkNextJsReactCompatibility.js';
|
|
19
|
-
import { countNestedFolders } from '../actions/init/countNestedFolders.js';
|
|
20
15
|
import { determineAppTemplate } from '../actions/init/determineAppTemplate.js';
|
|
21
16
|
import { createOrAppendEnvVars } from '../actions/init/env/createOrAppendEnvVars.js';
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
17
|
+
import { initApp } from '../actions/init/initApp.js';
|
|
18
|
+
import { flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded } from '../actions/init/initHelpers.js';
|
|
19
|
+
import { initNextJs } from '../actions/init/initNextJs.js';
|
|
20
|
+
import { initStudio } from '../actions/init/initStudio.js';
|
|
24
21
|
import { checkIsRemoteTemplate, getGitHubRepoInfo } from '../actions/init/remoteTemplate.js';
|
|
25
|
-
import { resolvePackageManager } from '../actions/init/resolvePackageManager.js';
|
|
26
|
-
import templates from '../actions/init/templates/index.js';
|
|
27
|
-
import { sanityCliTemplate, sanityConfigTemplate, sanityFolder, sanityStudioTemplate } from '../actions/init/templates/nextjs/index.js';
|
|
28
22
|
import { setupMCP } from '../actions/mcp/setupMCP.js';
|
|
29
23
|
import { findOrganizationByUserName } from '../actions/organizations/findOrganizationByUserName.js';
|
|
30
24
|
import { getOrganizationChoices } from '../actions/organizations/getOrganizationChoices.js';
|
|
31
25
|
import { getOrganizationsWithAttachGrantInfo } from '../actions/organizations/getOrganizationsWithAttachGrantInfo.js';
|
|
32
26
|
import { hasProjectAttachGrant } from '../actions/organizations/hasProjectAttachGrant.js';
|
|
33
|
-
import {
|
|
34
|
-
import { promptForTypeScript } from '../prompts/init/promptForTypescript.js';
|
|
27
|
+
import { promptForConfigFiles } from '../prompts/init/nextjs.js';
|
|
35
28
|
import { promptForDatasetName } from '../prompts/promptForDatasetName.js';
|
|
36
29
|
import { promptForDefaultConfig } from '../prompts/promptForDefaultConfig.js';
|
|
37
30
|
import { promptForOrganizationName } from '../prompts/promptForOrganizationName.js';
|
|
38
|
-
import { createCorsOrigin, listCorsOrigins } from '../services/cors.js';
|
|
39
31
|
import { createDataset as createDatasetService, listDatasets } from '../services/datasets.js';
|
|
40
32
|
import { getProjectFeatures } from '../services/getProjectFeatures.js';
|
|
41
33
|
import { createOrganization, listOrganizations } from '../services/organizations.js';
|
|
42
34
|
import { getPlanId, getPlanIdFromCoupon } from '../services/plans.js';
|
|
43
|
-
import { createProject, listProjects
|
|
35
|
+
import { createProject, listProjects } from '../services/projects.js';
|
|
44
36
|
import { getCliUser } from '../services/user.js';
|
|
45
37
|
import { CLIInitStepCompleted } from '../telemetry/init.telemetry.js';
|
|
46
38
|
import { detectFrameworkRecord } from '../util/detectFramework.js';
|
|
47
39
|
import { absolutify, validateEmptyPath } from '../util/fsUtils.js';
|
|
48
40
|
import { getProjectDefaults } from '../util/getProjectDefaults.js';
|
|
49
41
|
import { getSanityEnv } from '../util/getSanityEnv.js';
|
|
50
|
-
import { getPeerDependencies } from '../util/packageManager/getPeerDependencies.js';
|
|
51
|
-
import { installDeclaredPackages, installNewPackages } from '../util/packageManager/installPackages.js';
|
|
52
|
-
import { getPartialEnvWithNpmPath } from '../util/packageManager/packageManagerChoice.js';
|
|
53
|
-
import { ImportDatasetCommand } from './datasets/import.js';
|
|
54
42
|
const debug = subdebug('init');
|
|
55
43
|
export class InitCommand extends SanityCommand {
|
|
56
44
|
static args = {
|
|
@@ -395,8 +383,8 @@ export class InitCommand extends SanityCommand {
|
|
|
395
383
|
this.log(`\nYou can find your project on Sanity Manage — https://www.sanity.io/manage/project/${projectId}\n`);
|
|
396
384
|
return;
|
|
397
385
|
}
|
|
398
|
-
let initNext = this.
|
|
399
|
-
if (isNextJs && this.
|
|
386
|
+
let initNext = flagOrDefault(this.flags['nextjs-add-config-files'], false);
|
|
387
|
+
if (isNextJs && shouldPrompt(this.isUnattended(), this.flags['nextjs-add-config-files'])) {
|
|
400
388
|
initNext = await promptForConfigFiles();
|
|
401
389
|
}
|
|
402
390
|
this._trace.log({
|
|
@@ -419,9 +407,9 @@ export class InitCommand extends SanityCommand {
|
|
|
419
407
|
sluggedName,
|
|
420
408
|
workDir
|
|
421
409
|
});
|
|
422
|
-
// Set up MCP integration
|
|
410
|
+
// Set up MCP integration (skip in non-production environments)
|
|
423
411
|
let mcpMode = 'prompt';
|
|
424
|
-
if (!this.flags.mcp || !this.resolveIsInteractive()) {
|
|
412
|
+
if (!this.flags.mcp || !this.resolveIsInteractive() || getSanityEnv() !== 'production') {
|
|
425
413
|
mcpMode = 'skip';
|
|
426
414
|
} else if (this.flags.yes) {
|
|
427
415
|
mcpMode = 'auto';
|
|
@@ -453,14 +441,25 @@ export class InitCommand extends SanityCommand {
|
|
|
453
441
|
});
|
|
454
442
|
}
|
|
455
443
|
if (initNext) {
|
|
456
|
-
await
|
|
444
|
+
await initNextJs({
|
|
457
445
|
datasetName,
|
|
458
446
|
detectedFramework,
|
|
459
447
|
envFilename,
|
|
460
448
|
mcpConfigured,
|
|
449
|
+
nextjsAppendEnv: this.flags['nextjs-append-env'],
|
|
450
|
+
nextjsEmbedStudio: this.flags['nextjs-embed-studio'],
|
|
451
|
+
output: this.output,
|
|
452
|
+
overwriteFiles: this.flags['overwrite-files'],
|
|
453
|
+
packageManager: this.flags['package-manager'],
|
|
461
454
|
projectId,
|
|
455
|
+
template: this.flags.template,
|
|
456
|
+
trace: this._trace,
|
|
457
|
+
typescript: this.flags.typescript,
|
|
458
|
+
unattended: this.isUnattended(),
|
|
462
459
|
workDir
|
|
463
460
|
});
|
|
461
|
+
this._trace.complete();
|
|
462
|
+
return;
|
|
464
463
|
}
|
|
465
464
|
// user wants to write environment variables to file
|
|
466
465
|
if (this.flags.env) {
|
|
@@ -475,178 +474,42 @@ export class InitCommand extends SanityCommand {
|
|
|
475
474
|
output: this.output,
|
|
476
475
|
outputPath
|
|
477
476
|
});
|
|
478
|
-
await this.
|
|
477
|
+
await writeStagingEnvIfNeeded(this.output, outputPath);
|
|
479
478
|
this.exit(0);
|
|
480
479
|
}
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
this.error(`Template "${templateName}" not found`, {
|
|
490
|
-
exit: 1
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
let useTypeScript = this.flags.typescript;
|
|
494
|
-
if (!remoteTemplateInfo && template && template.typescriptOnly === true) {
|
|
495
|
-
useTypeScript = true;
|
|
496
|
-
} else if (this.promptForUndefinedFlag(this.flags.typescript)) {
|
|
497
|
-
useTypeScript = await promptForTypeScript();
|
|
498
|
-
this._trace.log({
|
|
499
|
-
selectedOption: useTypeScript ? 'yes' : 'no',
|
|
500
|
-
step: 'useTypeScript'
|
|
501
|
-
});
|
|
502
|
-
}
|
|
503
|
-
// If the template has a sample dataset, prompt the user whether or not we should import it
|
|
504
|
-
const importDatasetFlag = this.flags['import-dataset'];
|
|
505
|
-
const shouldImport = template?.datasetUrl && (importDatasetFlag ?? (!this.isUnattended() && await this.promptForDatasetImport(template.importPrompt)));
|
|
506
|
-
this._trace.log({
|
|
507
|
-
selectedOption: shouldImport ? 'yes' : 'no',
|
|
508
|
-
step: 'importTemplateDataset'
|
|
509
|
-
});
|
|
510
|
-
try {
|
|
511
|
-
await updateProjectInitializedAt(projectId);
|
|
512
|
-
} catch (err) {
|
|
513
|
-
// Non-critical update
|
|
514
|
-
debug('Failed to update cliInitializedAt metadata', err);
|
|
515
|
-
}
|
|
516
|
-
try {
|
|
517
|
-
await bootstrapTemplate({
|
|
518
|
-
autoUpdates: this.flags['auto-updates'],
|
|
519
|
-
bearerToken: this.flags['template-token'],
|
|
520
|
-
dataset: datasetName,
|
|
521
|
-
organizationId,
|
|
522
|
-
output: this.output,
|
|
523
|
-
outputPath,
|
|
524
|
-
overwriteFiles: this.flags['overwrite-files'],
|
|
525
|
-
packageName: sluggedName,
|
|
526
|
-
projectId,
|
|
527
|
-
projectName: displayName || defaults.projectName,
|
|
528
|
-
remoteTemplateInfo,
|
|
529
|
-
templateName,
|
|
530
|
-
useTypeScript
|
|
531
|
-
});
|
|
532
|
-
} catch (error) {
|
|
533
|
-
if (error instanceof Error) {
|
|
534
|
-
throw error;
|
|
535
|
-
}
|
|
536
|
-
throw new Error(String(error), {
|
|
537
|
-
cause: error
|
|
538
|
-
});
|
|
539
|
-
}
|
|
540
|
-
const pkgManager = await resolvePackageManager({
|
|
541
|
-
interactive: !this.isUnattended(),
|
|
480
|
+
const sharedParams = {
|
|
481
|
+
autoUpdates: this.flags['auto-updates'],
|
|
482
|
+
defaults,
|
|
483
|
+
error: this.error.bind(this),
|
|
484
|
+
git: this.flags.git,
|
|
485
|
+
mcpConfigured,
|
|
486
|
+
noGit: this.flags['no-git'],
|
|
487
|
+
organizationId,
|
|
542
488
|
output: this.output,
|
|
489
|
+
outputPath,
|
|
490
|
+
overwriteFiles: this.flags['overwrite-files'],
|
|
543
491
|
packageManager: this.flags['package-manager'],
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
await installDeclaredPackages(outputPath, pkgManager, {
|
|
552
|
-
output: this.output,
|
|
492
|
+
remoteTemplateInfo,
|
|
493
|
+
sluggedName,
|
|
494
|
+
template: this.flags.template,
|
|
495
|
+
templateToken: this.flags['template-token'],
|
|
496
|
+
trace: this._trace,
|
|
497
|
+
typescript: this.flags.typescript,
|
|
498
|
+
unattended: this.isUnattended(),
|
|
553
499
|
workDir
|
|
554
|
-
});
|
|
555
|
-
const useGit = this.flags.git === undefined || Boolean(this.flags.git);
|
|
556
|
-
const commitMessage = this.flags.git;
|
|
557
|
-
await this.writeStagingEnvIfNeeded(outputPath);
|
|
558
|
-
// Try initializing a git repository
|
|
559
|
-
if (useGit) {
|
|
560
|
-
tryGitInit(outputPath, typeof commitMessage === 'string' ? commitMessage : undefined);
|
|
561
|
-
}
|
|
562
|
-
// Prompt for dataset import (if a dataset is defined)
|
|
563
|
-
if (shouldImport && template?.datasetUrl) {
|
|
564
|
-
const token = await getCliToken();
|
|
565
|
-
if (!token) {
|
|
566
|
-
this.error('Authentication required to import dataset', {
|
|
567
|
-
exit: 1
|
|
568
|
-
});
|
|
569
|
-
}
|
|
570
|
-
await ImportDatasetCommand.run([
|
|
571
|
-
template.datasetUrl,
|
|
572
|
-
'--project-id',
|
|
573
|
-
projectId,
|
|
574
|
-
'--dataset',
|
|
575
|
-
datasetName,
|
|
576
|
-
'--token',
|
|
577
|
-
token
|
|
578
|
-
], {
|
|
579
|
-
root: outputPath
|
|
580
|
-
});
|
|
581
|
-
this.log('');
|
|
582
|
-
this.log('If you want to delete the imported data, use');
|
|
583
|
-
this.log(` ${styleText('cyan', `npx sanity dataset delete ${datasetName}`)}`);
|
|
584
|
-
this.log('and create a new clean dataset with');
|
|
585
|
-
this.log(` ${styleText('cyan', `npx sanity dataset create <name>`)}\n`);
|
|
586
|
-
}
|
|
587
|
-
const devCommandMap = {
|
|
588
|
-
bun: 'bun dev',
|
|
589
|
-
manual: 'npm run dev',
|
|
590
|
-
npm: 'npm run dev',
|
|
591
|
-
pnpm: 'pnpm dev',
|
|
592
|
-
yarn: 'yarn dev'
|
|
593
500
|
};
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
this.log(styleText([
|
|
607
|
-
'blue',
|
|
608
|
-
'underline'
|
|
609
|
-
], 'https://www.sanity.io/docs/app-sdk/sdk-configuration'));
|
|
610
|
-
if (mcpConfigured && mcpConfigured.length > 0) {
|
|
611
|
-
const message = await this.getPostInitMCPPrompt(mcpConfigured);
|
|
612
|
-
this.log(`\n${message}`);
|
|
613
|
-
this.log(`\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`);
|
|
614
|
-
this.log(`\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`);
|
|
615
|
-
}
|
|
616
|
-
this.log('\n');
|
|
617
|
-
this.log(`Other helpful commands:`);
|
|
618
|
-
this.log(`npx sanity docs browse to open the documentation in a browser`);
|
|
619
|
-
this.log(`npx sanity dev to start the development server for your app`);
|
|
620
|
-
this.log(`npx sanity deploy to deploy your app`);
|
|
621
|
-
} else {
|
|
622
|
-
//output for Studios here
|
|
623
|
-
this.log(`✅ ${styleText([
|
|
624
|
-
'green',
|
|
625
|
-
'bold'
|
|
626
|
-
], 'Success!')} Your Studio has been created.`);
|
|
627
|
-
if (!isCurrentDir) this.log(goToProjectDir);
|
|
628
|
-
this.log(`\nGet started by running ${styleText('cyan', devCommand)} to launch your Studio's development server`);
|
|
629
|
-
if (mcpConfigured && mcpConfigured.length > 0) {
|
|
630
|
-
const message = await this.getPostInitMCPPrompt(mcpConfigured);
|
|
631
|
-
this.log(`\n${message}`);
|
|
632
|
-
this.log(`\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`);
|
|
633
|
-
this.log(`\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`);
|
|
634
|
-
}
|
|
635
|
-
this.log('\n');
|
|
636
|
-
this.log(`Other helpful commands:`);
|
|
637
|
-
this.log(`npx sanity docs browse to open the documentation in a browser`);
|
|
638
|
-
this.log(`npx sanity manage to open the project settings in a browser`);
|
|
639
|
-
this.log(`npx sanity help to explore the CLI manual`);
|
|
640
|
-
}
|
|
641
|
-
if (isFirstProject) {
|
|
642
|
-
this._trace.log({
|
|
643
|
-
selectedOption: 'yes',
|
|
644
|
-
step: 'sendCommunityInvite'
|
|
645
|
-
});
|
|
646
|
-
const DISCORD_INVITE_LINK = 'https://www.sanity.io/community/join';
|
|
647
|
-
this.log(`\nJoin the Sanity community: ${styleText('cyan', DISCORD_INVITE_LINK)}`);
|
|
648
|
-
this.log('We look forward to seeing you there!\n');
|
|
649
|
-
}
|
|
501
|
+
await (isAppTemplate ? initApp({
|
|
502
|
+
...sharedParams,
|
|
503
|
+
datasetName,
|
|
504
|
+
projectId
|
|
505
|
+
}) : initStudio({
|
|
506
|
+
...sharedParams,
|
|
507
|
+
datasetName,
|
|
508
|
+
displayName,
|
|
509
|
+
importDataset: this.flags['import-dataset'],
|
|
510
|
+
isFirstProject,
|
|
511
|
+
projectId
|
|
512
|
+
}));
|
|
650
513
|
this._trace.complete();
|
|
651
514
|
}
|
|
652
515
|
checkFlagsInUnattendedMode({ createProjectName, isAppTemplate, isNextJs }) {
|
|
@@ -665,13 +528,8 @@ export class InitCommand extends SanityCommand {
|
|
|
665
528
|
}
|
|
666
529
|
return;
|
|
667
530
|
}
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
exit: 1
|
|
671
|
-
});
|
|
672
|
-
}
|
|
673
|
-
// output-path is required in unattended mode when not using nextjs
|
|
674
|
-
if (!isNextJs && !this.flags['output-path']) {
|
|
531
|
+
// output-path is required in unattended mode when not using nextjs or bare
|
|
532
|
+
if (!isNextJs && !this.flags.bare && !this.flags['output-path']) {
|
|
675
533
|
this.error(`\`--output-path\` must be specified in unattended mode`, {
|
|
676
534
|
exit: 1
|
|
677
535
|
});
|
|
@@ -760,9 +618,6 @@ export class InitCommand extends SanityCommand {
|
|
|
760
618
|
user: loggedInUser
|
|
761
619
|
};
|
|
762
620
|
}
|
|
763
|
-
flagOrDefault(flag, defaultValue) {
|
|
764
|
-
return typeof this.flags[flag] === 'boolean' ? this.flags[flag] : defaultValue;
|
|
765
|
-
}
|
|
766
621
|
async getOrCreateDataset(opts) {
|
|
767
622
|
const visibility = this.flags.visibility;
|
|
768
623
|
const dataset = this.flags.dataset;
|
|
@@ -796,6 +651,28 @@ export class InitCommand extends SanityCommand {
|
|
|
796
651
|
userAction: 'none'
|
|
797
652
|
};
|
|
798
653
|
}
|
|
654
|
+
// In unattended mode without --dataset, default to "production" with public visibility
|
|
655
|
+
// (same behavior as --dataset-default)
|
|
656
|
+
if (this.isUnattended()) {
|
|
657
|
+
debug('Unattended mode without --dataset, defaulting to "production" dataset');
|
|
658
|
+
const datasetName = 'production';
|
|
659
|
+
const existing = datasets.find((ds)=>ds.name === datasetName);
|
|
660
|
+
if (!existing) {
|
|
661
|
+
await createDataset({
|
|
662
|
+
datasetName,
|
|
663
|
+
forcePublic: visibility === undefined,
|
|
664
|
+
isUnattended: true,
|
|
665
|
+
output: this.output,
|
|
666
|
+
projectFeatures,
|
|
667
|
+
projectId: opts.projectId,
|
|
668
|
+
visibility
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
return {
|
|
672
|
+
datasetName,
|
|
673
|
+
userAction: existing ? 'none' : 'create'
|
|
674
|
+
};
|
|
675
|
+
}
|
|
799
676
|
if (datasets.length === 0) {
|
|
800
677
|
debug('No datasets found for project, prompting for name');
|
|
801
678
|
if (opts.showDefaultConfigPrompt) {
|
|
@@ -985,38 +862,36 @@ export class InitCommand extends SanityCommand {
|
|
|
985
862
|
return undefined;
|
|
986
863
|
}
|
|
987
864
|
}
|
|
988
|
-
async getPostInitMCPPrompt(editorsNames) {
|
|
989
|
-
return fetchPostInitPrompt(new Intl.ListFormat('en').format(editorsNames));
|
|
990
|
-
}
|
|
991
865
|
async getProjectDetails({ isAppTemplate, newProject, planId, showDefaultConfigPrompt, user }) {
|
|
992
866
|
if (isAppTemplate) {
|
|
993
|
-
|
|
994
|
-
if (
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
867
|
+
let organizationId = this.flags.organization;
|
|
868
|
+
if (!organizationId) {
|
|
869
|
+
let organizations;
|
|
870
|
+
try {
|
|
871
|
+
organizations = await listOrganizations();
|
|
872
|
+
} catch (err) {
|
|
873
|
+
this.error(`Failed to communicate with the Sanity API:\n${err.message}`, {
|
|
874
|
+
exit: 1
|
|
875
|
+
});
|
|
876
|
+
}
|
|
877
|
+
organizationId = await this.promptUserForOrganization({
|
|
878
|
+
isAppTemplate: true,
|
|
879
|
+
organizations,
|
|
880
|
+
user
|
|
881
|
+
});
|
|
1002
882
|
}
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
includeMembers: 'true'
|
|
1008
|
-
});
|
|
1009
|
-
const appOrganizationId = await this.promptUserForOrganization({
|
|
1010
|
-
isAppTemplate: true,
|
|
1011
|
-
organizations,
|
|
883
|
+
const { datasetName, displayName, projectId } = await this.promptForAppTemplateSetup({
|
|
884
|
+
newProject,
|
|
885
|
+
organizationId,
|
|
886
|
+
planId,
|
|
1012
887
|
user
|
|
1013
888
|
});
|
|
1014
889
|
return {
|
|
1015
|
-
datasetName
|
|
1016
|
-
displayName
|
|
890
|
+
datasetName,
|
|
891
|
+
displayName,
|
|
1017
892
|
isFirstProject: false,
|
|
1018
|
-
organizationId
|
|
1019
|
-
projectId
|
|
893
|
+
organizationId,
|
|
894
|
+
projectId
|
|
1020
895
|
};
|
|
1021
896
|
}
|
|
1022
897
|
debug('Prompting user to select or create a project');
|
|
@@ -1060,183 +935,90 @@ export class InitCommand extends SanityCommand {
|
|
|
1060
935
|
});
|
|
1061
936
|
return absolutify(inputPath);
|
|
1062
937
|
}
|
|
1063
|
-
async
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
});
|
|
1072
|
-
const fileExtension = useTypeScript ? 'ts' : 'js';
|
|
1073
|
-
let embeddedStudio = this.flagOrDefault('nextjs-embed-studio', true);
|
|
1074
|
-
if (this.promptForUndefinedFlag(this.flags['nextjs-embed-studio'])) {
|
|
1075
|
-
embeddedStudio = await promptForEmbeddedStudio();
|
|
1076
|
-
}
|
|
1077
|
-
let hasSrcFolder = false;
|
|
1078
|
-
if (embeddedStudio) {
|
|
1079
|
-
// find source path (app or src/app)
|
|
1080
|
-
const appDir = 'app';
|
|
1081
|
-
let srcPath = path.join(workDir, appDir);
|
|
1082
|
-
if (!existsSync(srcPath)) {
|
|
1083
|
-
srcPath = path.join(workDir, 'src', appDir);
|
|
1084
|
-
hasSrcFolder = true;
|
|
1085
|
-
if (!existsSync(srcPath)) {
|
|
1086
|
-
try {
|
|
1087
|
-
await mkdir(srcPath, {
|
|
1088
|
-
recursive: true
|
|
1089
|
-
});
|
|
1090
|
-
} catch {
|
|
1091
|
-
debug('Error creating folder %s', srcPath);
|
|
1092
|
-
}
|
|
1093
|
-
}
|
|
938
|
+
async promptForAppTemplateSetup({ newProject, organizationId, planId, user }) {
|
|
939
|
+
if (this.isUnattended()) {
|
|
940
|
+
if (!this.flags.project && !newProject) {
|
|
941
|
+
return {
|
|
942
|
+
datasetName: '',
|
|
943
|
+
displayName: '',
|
|
944
|
+
projectId: ''
|
|
945
|
+
};
|
|
1094
946
|
}
|
|
1095
|
-
const
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
}
|
|
1111
|
-
await this.writeSourceFiles({
|
|
1112
|
-
fileExtension,
|
|
1113
|
-
files: sanityFolder(useTypeScript, templateToUse),
|
|
1114
|
-
folderPath: undefined,
|
|
1115
|
-
srcFolderPrefix: hasSrcFolder,
|
|
1116
|
-
workDir
|
|
1117
|
-
});
|
|
1118
|
-
let appendEnv = this.flagOrDefault('nextjs-append-env', true);
|
|
1119
|
-
if (this.promptForUndefinedFlag(this.flags['nextjs-append-env'])) {
|
|
1120
|
-
appendEnv = await promptForAppendEnv(envFilename);
|
|
947
|
+
const project = await this.getOrCreateProject({
|
|
948
|
+
newProject,
|
|
949
|
+
planId,
|
|
950
|
+
user
|
|
951
|
+
});
|
|
952
|
+
const dataset = await this.getOrCreateDataset({
|
|
953
|
+
displayName: project.displayName,
|
|
954
|
+
projectId: project.projectId,
|
|
955
|
+
showDefaultConfigPrompt: false
|
|
956
|
+
});
|
|
957
|
+
return {
|
|
958
|
+
datasetName: dataset.datasetName,
|
|
959
|
+
displayName: project.displayName,
|
|
960
|
+
projectId: project.projectId
|
|
961
|
+
};
|
|
1121
962
|
}
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
963
|
+
const projects = (await listProjects()).toSorted((a, b)=>b.createdAt.localeCompare(a.createdAt));
|
|
964
|
+
const projectChoices = projects.map((project)=>({
|
|
965
|
+
name: `${project.displayName} (${project.id})`,
|
|
966
|
+
value: project.id
|
|
967
|
+
}));
|
|
968
|
+
const SKIP_PROJECT = '__skip__';
|
|
969
|
+
const NEW_PROJECT = '__new__';
|
|
970
|
+
const selected = await select({
|
|
971
|
+
choices: [
|
|
972
|
+
{
|
|
973
|
+
name: "Skip — I'll configure later",
|
|
974
|
+
value: SKIP_PROJECT
|
|
1127
975
|
},
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
976
|
+
{
|
|
977
|
+
name: 'Create new project',
|
|
978
|
+
value: NEW_PROJECT
|
|
979
|
+
},
|
|
980
|
+
...projectChoices.length > 0 ? [
|
|
981
|
+
new Separator(),
|
|
982
|
+
...projectChoices
|
|
983
|
+
] : []
|
|
984
|
+
],
|
|
985
|
+
message: 'Configure a project for this app?'
|
|
986
|
+
});
|
|
987
|
+
if (selected === SKIP_PROJECT) {
|
|
988
|
+
this._trace.log({
|
|
989
|
+
selectedOption: 'skip',
|
|
990
|
+
step: 'configureAppProject'
|
|
1133
991
|
});
|
|
992
|
+
return {
|
|
993
|
+
datasetName: '',
|
|
994
|
+
displayName: '',
|
|
995
|
+
projectId: ''
|
|
996
|
+
};
|
|
1134
997
|
}
|
|
1135
|
-
if (embeddedStudio) {
|
|
1136
|
-
const nextjsLocalDevOrigin = 'http://localhost:3000';
|
|
1137
|
-
const existingCorsOrigins = await listCorsOrigins(projectId);
|
|
1138
|
-
const hasExistingCorsOrigin = existingCorsOrigins.some((item)=>item.origin === nextjsLocalDevOrigin);
|
|
1139
|
-
if (!hasExistingCorsOrigin) {
|
|
1140
|
-
try {
|
|
1141
|
-
const createCorsRes = await createCorsOrigin({
|
|
1142
|
-
allowCredentials: true,
|
|
1143
|
-
origin: nextjsLocalDevOrigin,
|
|
1144
|
-
projectId
|
|
1145
|
-
});
|
|
1146
|
-
this.log(createCorsRes.id ? `Added ${nextjsLocalDevOrigin} to CORS origins` : `Failed to add ${nextjsLocalDevOrigin} to CORS origins`);
|
|
1147
|
-
} catch (error) {
|
|
1148
|
-
debug(`Error creating new CORS Origin ${nextjsLocalDevOrigin}: ${error}`);
|
|
1149
|
-
this.error(`Failed to add ${nextjsLocalDevOrigin} to CORS origins: ${error}`, {
|
|
1150
|
-
exit: 1
|
|
1151
|
-
});
|
|
1152
|
-
}
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
const chosen = await resolvePackageManager({
|
|
1156
|
-
interactive: !this.isUnattended(),
|
|
1157
|
-
output: this.output,
|
|
1158
|
-
packageManager: this.flags['package-manager'],
|
|
1159
|
-
targetDir: workDir
|
|
1160
|
-
});
|
|
1161
998
|
this._trace.log({
|
|
1162
|
-
selectedOption:
|
|
1163
|
-
step: '
|
|
1164
|
-
});
|
|
1165
|
-
const packages = [
|
|
1166
|
-
'@sanity/vision@5',
|
|
1167
|
-
'sanity@5',
|
|
1168
|
-
'@sanity/image-url@2',
|
|
1169
|
-
'styled-components@6'
|
|
1170
|
-
];
|
|
1171
|
-
if (templateToUse === 'blog') {
|
|
1172
|
-
packages.push('@sanity/icons');
|
|
1173
|
-
}
|
|
1174
|
-
await installNewPackages({
|
|
1175
|
-
packageManager: chosen,
|
|
1176
|
-
packages
|
|
1177
|
-
}, {
|
|
1178
|
-
output: this.output,
|
|
1179
|
-
workDir
|
|
999
|
+
selectedOption: selected === NEW_PROJECT ? 'create' : 'existing',
|
|
1000
|
+
step: 'configureAppProject'
|
|
1180
1001
|
});
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1002
|
+
const project = selected === NEW_PROJECT ? await this.promptForProjectCreation({
|
|
1003
|
+
isUsersFirstProject: projects.length === 0,
|
|
1004
|
+
organizationId,
|
|
1005
|
+
organizations: [],
|
|
1006
|
+
planId,
|
|
1007
|
+
user
|
|
1008
|
+
}) : {
|
|
1009
|
+
displayName: projects.find((p)=>p.id === selected)?.displayName ?? '',
|
|
1010
|
+
projectId: selected
|
|
1187
1011
|
};
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
'install',
|
|
1193
|
-
'next-sanity@12'
|
|
1194
|
-
], execOptions);
|
|
1195
|
-
break;
|
|
1196
|
-
}
|
|
1197
|
-
case 'pnpm':
|
|
1198
|
-
{
|
|
1199
|
-
await execa('pnpm', [
|
|
1200
|
-
'install',
|
|
1201
|
-
'next-sanity@12'
|
|
1202
|
-
], execOptions);
|
|
1203
|
-
break;
|
|
1204
|
-
}
|
|
1205
|
-
case 'yarn':
|
|
1206
|
-
{
|
|
1207
|
-
const peerDeps = await getPeerDependencies('next-sanity@12', workDir);
|
|
1208
|
-
await installNewPackages({
|
|
1209
|
-
packageManager: 'yarn',
|
|
1210
|
-
packages: [
|
|
1211
|
-
'next-sanity@12',
|
|
1212
|
-
...peerDeps
|
|
1213
|
-
]
|
|
1214
|
-
}, {
|
|
1215
|
-
output: this.output,
|
|
1216
|
-
workDir
|
|
1217
|
-
});
|
|
1218
|
-
break;
|
|
1219
|
-
}
|
|
1220
|
-
default:
|
|
1221
|
-
{
|
|
1222
|
-
break;
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
this.log(`\n${styleText('green', 'Success!')} Your Sanity configuration files has been added to this project`);
|
|
1226
|
-
if (mcpConfigured && mcpConfigured.length > 0) {
|
|
1227
|
-
const message = await this.getPostInitMCPPrompt(mcpConfigured);
|
|
1228
|
-
this.log(`\n${message}`);
|
|
1229
|
-
this.log(`\nLearn more: ${styleText('cyan', 'https://mcp.sanity.io')}`);
|
|
1230
|
-
this.log(`\nHave feedback? Tell us in the community: ${styleText('cyan', 'https://www.sanity.io/community/join')}`);
|
|
1231
|
-
}
|
|
1232
|
-
await this.writeStagingEnvIfNeeded(workDir);
|
|
1233
|
-
this.exit(0);
|
|
1234
|
-
}
|
|
1235
|
-
async promptForDatasetImport(message) {
|
|
1236
|
-
return confirm({
|
|
1237
|
-
default: true,
|
|
1238
|
-
message: message || 'This template includes a sample dataset, would you like to use it?'
|
|
1012
|
+
const dataset = await this.getOrCreateDataset({
|
|
1013
|
+
displayName: project.displayName,
|
|
1014
|
+
projectId: project.projectId,
|
|
1015
|
+
showDefaultConfigPrompt: false
|
|
1239
1016
|
});
|
|
1017
|
+
return {
|
|
1018
|
+
datasetName: dataset.datasetName,
|
|
1019
|
+
displayName: project.displayName,
|
|
1020
|
+
projectId: project.projectId
|
|
1021
|
+
};
|
|
1240
1022
|
}
|
|
1241
1023
|
async promptForProjectCreation({ isUsersFirstProject, organizationId, organizations, planId, user }) {
|
|
1242
1024
|
const projectName = await input({
|
|
@@ -1272,37 +1054,6 @@ export class InitCommand extends SanityCommand {
|
|
|
1272
1054
|
userAction: 'create'
|
|
1273
1055
|
};
|
|
1274
1056
|
}
|
|
1275
|
-
async promptForTemplate() {
|
|
1276
|
-
const template = this.flags.template;
|
|
1277
|
-
const defaultTemplate = this.isUnattended() || template ? template || 'clean' : null;
|
|
1278
|
-
if (defaultTemplate) {
|
|
1279
|
-
return defaultTemplate;
|
|
1280
|
-
}
|
|
1281
|
-
return select({
|
|
1282
|
-
choices: [
|
|
1283
|
-
{
|
|
1284
|
-
name: 'Clean project with no predefined schema types',
|
|
1285
|
-
value: 'clean'
|
|
1286
|
-
},
|
|
1287
|
-
{
|
|
1288
|
-
name: 'Blog (schema)',
|
|
1289
|
-
value: 'blog'
|
|
1290
|
-
},
|
|
1291
|
-
{
|
|
1292
|
-
name: 'E-commerce (Shopify)',
|
|
1293
|
-
value: 'shopify'
|
|
1294
|
-
},
|
|
1295
|
-
{
|
|
1296
|
-
name: 'Movie project (schema + sample data)',
|
|
1297
|
-
value: 'moviedb'
|
|
1298
|
-
}
|
|
1299
|
-
],
|
|
1300
|
-
message: 'Select project template'
|
|
1301
|
-
});
|
|
1302
|
-
}
|
|
1303
|
-
promptForUndefinedFlag(flag) {
|
|
1304
|
-
return !this.isUnattended() && flag === undefined;
|
|
1305
|
-
}
|
|
1306
1057
|
async promptUserForNewOrganization(user) {
|
|
1307
1058
|
const name = await promptForOrganizationName(user);
|
|
1308
1059
|
const spin = spinner('Creating organization').start();
|
|
@@ -1408,72 +1159,6 @@ export class InitCommand extends SanityCommand {
|
|
|
1408
1159
|
}
|
|
1409
1160
|
}
|
|
1410
1161
|
}
|
|
1411
|
-
async writeOrOverwrite(filePath, content, workDir) {
|
|
1412
|
-
if (existsSync(filePath)) {
|
|
1413
|
-
let overwrite = this.flagOrDefault('overwrite-files', false);
|
|
1414
|
-
if (this.promptForUndefinedFlag(this.flags['overwrite-files'])) {
|
|
1415
|
-
overwrite = await confirm({
|
|
1416
|
-
default: false,
|
|
1417
|
-
message: `File ${styleText('yellow', filePath.replace(workDir, ''))} already exists. Do you want to overwrite it?`
|
|
1418
|
-
});
|
|
1419
|
-
}
|
|
1420
|
-
if (!overwrite) {
|
|
1421
|
-
return;
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
// make folder if not exists
|
|
1425
|
-
const folderPath = path.dirname(filePath);
|
|
1426
|
-
try {
|
|
1427
|
-
await mkdir(folderPath, {
|
|
1428
|
-
recursive: true
|
|
1429
|
-
});
|
|
1430
|
-
} catch {
|
|
1431
|
-
debug('Error creating folder %s', folderPath);
|
|
1432
|
-
}
|
|
1433
|
-
await writeFile(filePath, content, {
|
|
1434
|
-
encoding: 'utf8'
|
|
1435
|
-
});
|
|
1436
|
-
}
|
|
1437
|
-
// write sanity folder files
|
|
1438
|
-
async writeSourceFiles({ fileExtension, files, folderPath, srcFolderPrefix, workDir }) {
|
|
1439
|
-
for (const [filePath, content] of Object.entries(files)){
|
|
1440
|
-
// check if file ends with full stop to indicate it's file and not directory (this only works with our template tree structure)
|
|
1441
|
-
if (filePath.includes('.') && typeof content === 'string') {
|
|
1442
|
-
await this.writeOrOverwrite(path.join(workDir, srcFolderPrefix ? 'src' : '', 'sanity', folderPath || '', `${filePath}${fileExtension}`), content, workDir);
|
|
1443
|
-
} else {
|
|
1444
|
-
await mkdir(path.join(workDir, srcFolderPrefix ? 'src' : '', 'sanity', filePath), {
|
|
1445
|
-
recursive: true
|
|
1446
|
-
});
|
|
1447
|
-
if (typeof content === 'object') {
|
|
1448
|
-
await this.writeSourceFiles({
|
|
1449
|
-
fileExtension,
|
|
1450
|
-
files: content,
|
|
1451
|
-
folderPath: filePath,
|
|
1452
|
-
srcFolderPrefix,
|
|
1453
|
-
workDir
|
|
1454
|
-
});
|
|
1455
|
-
}
|
|
1456
|
-
}
|
|
1457
|
-
}
|
|
1458
|
-
}
|
|
1459
|
-
/**
|
|
1460
|
-
* When running in a non-production Sanity environment (e.g. staging), write the
|
|
1461
|
-
* `SANITY_INTERNAL_ENV` variable to a `.env` file in the output directory so that
|
|
1462
|
-
* the bootstrapped project continues to target the same environment.
|
|
1463
|
-
*/ async writeStagingEnvIfNeeded(outputPath) {
|
|
1464
|
-
const sanityEnv = getSanityEnv();
|
|
1465
|
-
if (sanityEnv === 'production') return;
|
|
1466
|
-
await createOrAppendEnvVars({
|
|
1467
|
-
envVars: {
|
|
1468
|
-
INTERNAL_ENV: sanityEnv
|
|
1469
|
-
},
|
|
1470
|
-
filename: '.env',
|
|
1471
|
-
framework: null,
|
|
1472
|
-
log: false,
|
|
1473
|
-
output: this.output,
|
|
1474
|
-
outputPath
|
|
1475
|
-
});
|
|
1476
|
-
}
|
|
1477
1162
|
}
|
|
1478
1163
|
|
|
1479
1164
|
//# sourceMappingURL=init.js.map
|