@sanity/cli 3.74.0 → 3.74.2-canary.67
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/lib/_chunks-cjs/cli.js +146 -82
- package/lib/_chunks-cjs/cli.js.map +1 -1
- package/lib/index.d.mts +10 -0
- package/lib/index.d.ts +10 -0
- package/package.json +9 -9
- package/src/actions/init-project/bootstrapLocalTemplate.ts +35 -20
- package/src/actions/init-project/createCliConfig.ts +5 -47
- package/src/actions/init-project/createCoreAppCliConfig.ts +26 -0
- package/src/actions/init-project/createPackageManifest.ts +1 -1
- package/src/actions/init-project/createStudioConfig.ts +5 -27
- package/src/actions/init-project/determineCoreAppTemplate.ts +13 -0
- package/src/actions/init-project/initProject.ts +41 -13
- package/src/actions/init-project/processTemplate.ts +55 -0
- package/src/actions/init-project/templates/coreApp.ts +31 -0
- package/src/actions/init-project/templates/index.ts +2 -0
- package/src/types.ts +11 -0
- package/templates/core-app/src/App.tsx +26 -0
package/lib/_chunks-cjs/cli.js
CHANGED
@@ -46514,23 +46514,8 @@ var typescriptExports = requireTypescript(), typescript = /* @__PURE__ */ loadEn
|
|
46514
46514
|
__proto__: null,
|
46515
46515
|
default: typescript
|
46516
46516
|
}, [typescriptExports]);
|
46517
|
-
|
46518
|
-
|
46519
|
-
|
46520
|
-
export default defineCliConfig({
|
46521
|
-
api: {
|
46522
|
-
projectId: '%projectId%',
|
46523
|
-
dataset: '%dataset%'
|
46524
|
-
},
|
46525
|
-
/**
|
46526
|
-
* Enable auto-updates for studios.
|
46527
|
-
* Learn more at https://www.sanity.io/docs/cli#auto-updates
|
46528
|
-
*/
|
46529
|
-
autoUpdates: __BOOL__autoUpdates__,
|
46530
|
-
})
|
46531
|
-
`;
|
46532
|
-
function createCliConfig(options2) {
|
46533
|
-
const variables = options2, template = defaultTemplate$1.trimStart(), ast = mainExports.parse(template, { parser });
|
46517
|
+
function processTemplate(options2) {
|
46518
|
+
const { template, variables, includeBooleanTransform = !1 } = options2, ast = mainExports.parse(template.trimStart(), { parser });
|
46534
46519
|
return traverse__default.default(ast, {
|
46535
46520
|
StringLiteral: {
|
46536
46521
|
enter({ node }) {
|
@@ -46544,24 +46529,63 @@ function createCliConfig(options2) {
|
|
46544
46529
|
node.value = typeof newValue == "string" ? newValue : "";
|
46545
46530
|
}
|
46546
46531
|
},
|
46547
|
-
|
46548
|
-
|
46549
|
-
|
46550
|
-
|
46551
|
-
|
46552
|
-
/^__BOOL__(.+?)__$/,
|
46553
|
-
|
46554
|
-
|
46555
|
-
|
46556
|
-
|
46557
|
-
|
46558
|
-
|
46559
|
-
|
46560
|
-
path2.replaceWith({ type: "BooleanLiteral", value });
|
46532
|
+
...includeBooleanTransform && {
|
46533
|
+
Identifier: {
|
46534
|
+
enter(path2) {
|
46535
|
+
if (!path2.node.name.startsWith("__BOOL__"))
|
46536
|
+
return;
|
46537
|
+
const variableName = path2.node.name.replace(/^__BOOL__(.+?)__$/, "$1");
|
46538
|
+
if (!(variableName in variables))
|
46539
|
+
throw new Error(`Template variable '${variableName.toString()}' not defined`);
|
46540
|
+
const value = variables[variableName];
|
46541
|
+
if (typeof value != "boolean")
|
46542
|
+
throw new Error(`Expected boolean value for '${variableName.toString()}'`);
|
46543
|
+
path2.replaceWith({ type: "BooleanLiteral", value });
|
46544
|
+
}
|
46561
46545
|
}
|
46562
46546
|
}
|
46563
46547
|
}), mainExports.print(ast, { quote: "single" }).code;
|
46564
46548
|
}
|
46549
|
+
const defaultTemplate$1 = `
|
46550
|
+
import {defineCliConfig} from 'sanity/cli'
|
46551
|
+
|
46552
|
+
export default defineCliConfig({
|
46553
|
+
api: {
|
46554
|
+
projectId: '%projectId%',
|
46555
|
+
dataset: '%dataset%'
|
46556
|
+
},
|
46557
|
+
/**
|
46558
|
+
* Enable auto-updates for studios.
|
46559
|
+
* Learn more at https://www.sanity.io/docs/cli#auto-updates
|
46560
|
+
*/
|
46561
|
+
autoUpdates: __BOOL__autoUpdates__,
|
46562
|
+
})
|
46563
|
+
`;
|
46564
|
+
function createCliConfig(options2) {
|
46565
|
+
return processTemplate({
|
46566
|
+
template: defaultTemplate$1,
|
46567
|
+
variables: options2,
|
46568
|
+
includeBooleanTransform: !0
|
46569
|
+
});
|
46570
|
+
}
|
46571
|
+
const defaultCoreAppTemplate = `
|
46572
|
+
import {defineCliConfig} from 'sanity/cli'
|
46573
|
+
|
46574
|
+
export default defineCliConfig({
|
46575
|
+
api: {
|
46576
|
+
organizationId: '%organizationId%'
|
46577
|
+
},
|
46578
|
+
__experimental_coreAppConfiguration: {
|
46579
|
+
appLocation: '%appLocation%'
|
46580
|
+
},
|
46581
|
+
})
|
46582
|
+
`;
|
46583
|
+
function createCoreAppCliConfig(options2) {
|
46584
|
+
return processTemplate({
|
46585
|
+
template: defaultCoreAppTemplate,
|
46586
|
+
variables: options2
|
46587
|
+
});
|
46588
|
+
}
|
46565
46589
|
/*!
|
46566
46590
|
* isobject <https://github.com/jonschlinkert/isobject>
|
46567
46591
|
*
|
@@ -46630,7 +46654,7 @@ function createPackageManifest(data) {
|
|
46630
46654
|
...getCommonManifest(data),
|
46631
46655
|
main: "package.json",
|
46632
46656
|
keywords: ["sanity"],
|
46633
|
-
scripts: {
|
46657
|
+
scripts: data.scripts || {
|
46634
46658
|
dev: "sanity dev",
|
46635
46659
|
start: "sanity start",
|
46636
46660
|
build: "sanity build",
|
@@ -46699,25 +46723,42 @@ export default defineConfig({
|
|
46699
46723
|
};
|
46700
46724
|
function createStudioConfig(options2) {
|
46701
46725
|
const variables = { ...defaultVariables, ...options2.variables };
|
46702
|
-
|
46703
|
-
|
46704
|
-
|
46705
|
-
|
46706
|
-
|
46707
|
-
|
46708
|
-
|
46709
|
-
|
46710
|
-
return;
|
46711
|
-
const variableName = value.slice(1, -1);
|
46712
|
-
if (!(variableName in variables))
|
46713
|
-
throw new Error(`Template variable '${value}' not defined`);
|
46714
|
-
const newValue = variables[variableName];
|
46715
|
-
node.value = typeof newValue == "string" ? newValue : "";
|
46716
|
-
}
|
46717
|
-
}
|
46718
|
-
}), mainExports.print(ast, { quote: "single" }).code;
|
46726
|
+
return typeof options2.template == "function" ? options2.template(variables).trimStart() : processTemplate({
|
46727
|
+
template: options2.template || defaultTemplate,
|
46728
|
+
variables
|
46729
|
+
});
|
46730
|
+
}
|
46731
|
+
const coreAppTemplates = ["core-app"];
|
46732
|
+
function determineCoreAppTemplate(templateName) {
|
46733
|
+
return coreAppTemplates.includes(templateName);
|
46719
46734
|
}
|
46720
|
-
const blogTemplate = {}, cleanTemplate = {},
|
46735
|
+
const blogTemplate = {}, cleanTemplate = {}, coreAppTemplate = {
|
46736
|
+
dependencies: {
|
46737
|
+
"@sanity/sdk": "^0.0.0-alpha",
|
46738
|
+
"@sanity/sdk-react": "^0.0.0-alpha",
|
46739
|
+
react: "^19",
|
46740
|
+
"react-dom": "^19"
|
46741
|
+
},
|
46742
|
+
devDependencies: {
|
46743
|
+
/*
|
46744
|
+
* this will be changed to eslint-config sanity,
|
46745
|
+
* eslint.config generation will be a fast follow
|
46746
|
+
*/
|
46747
|
+
"@sanity/eslint-config-studio": "^5.0.1",
|
46748
|
+
"@types/react": "^18.0.25",
|
46749
|
+
eslint: "^9.9.0",
|
46750
|
+
prettier: "^3.0.2",
|
46751
|
+
sanity: "^3",
|
46752
|
+
typescript: "^5.1.6"
|
46753
|
+
},
|
46754
|
+
appLocation: "./src/App.tsx",
|
46755
|
+
scripts: {
|
46756
|
+
// this will eventually run a concurrently process with another in-flight utility
|
46757
|
+
dev: "sanity app dev",
|
46758
|
+
build: "sanity app build",
|
46759
|
+
start: "sanity app start"
|
46760
|
+
}
|
46761
|
+
}, configTemplate$3 = `
|
46721
46762
|
import {defineConfig, isDev} from 'sanity'
|
46722
46763
|
import {visionTool} from '@sanity/vision'
|
46723
46764
|
import {structureTool} from 'sanity/structure'
|
@@ -46895,6 +46936,7 @@ export default defineConfig({
|
|
46895
46936
|
}, templates = {
|
46896
46937
|
blog: blogTemplate,
|
46897
46938
|
clean: cleanTemplate,
|
46939
|
+
"core-app": coreAppTemplate,
|
46898
46940
|
"get-started": getStartedTemplate,
|
46899
46941
|
moviedb: movieTemplate,
|
46900
46942
|
shopify: shopifyTemplate$1,
|
@@ -46915,7 +46957,7 @@ async function updateInitialTemplateMetadata(apiClient, projectId, templateName)
|
|
46915
46957
|
}
|
46916
46958
|
}
|
46917
46959
|
async function bootstrapLocalTemplate(opts, context) {
|
46918
|
-
const { apiClient, cliRoot, output } = context, templatesDir = path__default.default.join(cliRoot, "templates"), { outputPath, templateName, useTypeScript, packageName, variables } = opts, sourceDir = path__default.default.join(templatesDir, templateName), sharedDir = path__default.default.join(templatesDir, "shared"), template = templates[templateName];
|
46960
|
+
const { apiClient, cliRoot, output } = context, templatesDir = path__default.default.join(cliRoot, "templates"), { outputPath, templateName, useTypeScript, packageName, variables } = opts, sourceDir = path__default.default.join(templatesDir, templateName), sharedDir = path__default.default.join(templatesDir, "shared"), isCoreAppTemplate = determineCoreAppTemplate(templateName), template = templates[templateName];
|
46919
46961
|
if (!template)
|
46920
46962
|
throw new Error(`Template "${templateName}" not defined`);
|
46921
46963
|
loadEnv.debug('Copying files from template "%s" to "%s"', templateName, outputPath);
|
@@ -46930,19 +46972,20 @@ async function bootstrapLocalTemplate(opts, context) {
|
|
46930
46972
|
schemaUrl: opts.schemaUrl
|
46931
46973
|
})), spinner.succeed(), spinner = output.spinner("Resolving latest module versions").start();
|
46932
46974
|
const dependencyVersions = await resolveLatestVersions({
|
46933
|
-
...studioDependencies.dependencies,
|
46934
|
-
...studioDependencies.devDependencies,
|
46935
|
-
...template.dependencies || {}
|
46975
|
+
...isCoreAppTemplate ? {} : studioDependencies.dependencies,
|
46976
|
+
...isCoreAppTemplate ? {} : studioDependencies.devDependencies,
|
46977
|
+
...template.dependencies || {},
|
46978
|
+
...template.devDependencies || {}
|
46936
46979
|
});
|
46937
46980
|
spinner.succeed();
|
46938
46981
|
const dependencies = Object.keys({
|
46939
|
-
...studioDependencies.dependencies,
|
46982
|
+
...isCoreAppTemplate ? {} : studioDependencies.dependencies,
|
46940
46983
|
...template.dependencies
|
46941
46984
|
}).reduce(
|
46942
46985
|
(deps, dependency) => (deps[dependency] = dependencyVersions[dependency], deps),
|
46943
46986
|
{}
|
46944
46987
|
), devDependencies = Object.keys({
|
46945
|
-
...studioDependencies.devDependencies,
|
46988
|
+
...isCoreAppTemplate ? {} : studioDependencies.devDependencies,
|
46946
46989
|
...template.devDependencies
|
46947
46990
|
}).reduce(
|
46948
46991
|
(deps, dependency) => (deps[dependency] = dependencyVersions[dependency], deps),
|
@@ -46952,27 +46995,33 @@ async function bootstrapLocalTemplate(opts, context) {
|
|
46952
46995
|
const packageManifest = await createPackageManifest({
|
46953
46996
|
name: packageName,
|
46954
46997
|
dependencies,
|
46955
|
-
devDependencies
|
46956
|
-
|
46998
|
+
devDependencies,
|
46999
|
+
scripts: template.scripts
|
47000
|
+
}), studioConfig = createStudioConfig({
|
46957
47001
|
template: template.configTemplate,
|
46958
47002
|
variables
|
46959
|
-
}), cliConfig =
|
47003
|
+
}), cliConfig = isCoreAppTemplate ? createCoreAppCliConfig({
|
47004
|
+
appLocation: template.appLocation,
|
47005
|
+
organizationId: variables.organizationId
|
47006
|
+
}) : createCliConfig({
|
46960
47007
|
projectId: variables.projectId,
|
46961
47008
|
dataset: variables.dataset,
|
46962
47009
|
autoUpdates: variables.autoUpdates
|
46963
47010
|
}), codeExt = useTypeScript ? "ts" : "js";
|
46964
|
-
return await Promise.all(
|
46965
|
-
|
46966
|
-
|
46967
|
-
|
46968
|
-
|
46969
|
-
|
46970
|
-
|
47011
|
+
return await Promise.all(
|
47012
|
+
[
|
47013
|
+
isCoreAppTemplate ? Promise.resolve(null) : writeFileIfNotExists(`sanity.config.${codeExt}`, studioConfig),
|
47014
|
+
writeFileIfNotExists(`sanity.cli.${codeExt}`, cliConfig),
|
47015
|
+
writeFileIfNotExists("package.json", packageManifest),
|
47016
|
+
writeFileIfNotExists(
|
47017
|
+
"eslint.config.mjs",
|
47018
|
+
`import studio from '@sanity/eslint-config-studio'
|
46971
47019
|
|
46972
47020
|
export default [...studio]
|
46973
47021
|
`
|
46974
|
-
|
46975
|
-
|
47022
|
+
)
|
47023
|
+
].filter(Boolean)
|
47024
|
+
), loadEnv.debug("Updating initial template metadata"), await updateInitialTemplateMetadata(apiClient, variables.projectId, `cli-${templateName}`), spinner.succeed(), template;
|
46976
47025
|
async function writeFileIfNotExists(fileName, content) {
|
46977
47026
|
const filePath = path__default.default.join(outputPath, fileName);
|
46978
47027
|
try {
|
@@ -52591,7 +52640,7 @@ ${err.message}`);
|
|
52591
52640
|
} else unattended || (trace.log({ step: "login" }), await getOrCreateUser());
|
52592
52641
|
let introMessage = "Fetching existing projects";
|
52593
52642
|
cliFlags.quickstart && (introMessage = "Eject your existing project's Sanity configuration"), success(introMessage), print("");
|
52594
|
-
const flags = await prepareFlags(), { projectId, displayName, isFirstProject, datasetName, schemaUrl } = await getProjectDetails(), sluggedName = lodashExports.deburr(displayName.toLowerCase()).replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
52643
|
+
const flags = await prepareFlags(), isCoreAppTemplate = cliFlags.template ? determineCoreAppTemplate(cliFlags.template) : !1, { projectId, displayName, isFirstProject, datasetName, schemaUrl, organizationId } = await getProjectDetails(), sluggedName = lodashExports.deburr(displayName.toLowerCase()).replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, "");
|
52595
52644
|
if (bareOutput) {
|
52596
52645
|
success("Below are your project details"), print(""), print(`Project ID: ${chalk2.cyan(projectId)}`), print(`Dataset: ${chalk2.cyan(datasetName)}`), print(
|
52597
52646
|
`
|
@@ -52781,11 +52830,15 @@ ${chalk2.green("Success!")} Your Sanity configuration files has been added to th
|
|
52781
52830
|
}[pkgManager];
|
52782
52831
|
outputPath === process.cwd() ? (print(`
|
52783
52832
|
${chalk2.green("Success!")} Now, use this command to continue:
|
52784
|
-
`), print(
|
52785
|
-
|
52833
|
+
`), print(
|
52834
|
+
`${chalk2.cyan(devCommand)} - to run ${isCoreAppTemplate ? "your Sanity application" : "Sanity Studio"}
|
52835
|
+
`
|
52836
|
+
)) : (print(`
|
52786
52837
|
${chalk2.green("Success!")} Now, use these commands to continue:
|
52787
|
-
`), print(`First: ${chalk2.cyan(`cd ${outputPath}`)} - to enter project\u2019s directory`), print(
|
52788
|
-
`
|
52838
|
+
`), print(`First: ${chalk2.cyan(`cd ${outputPath}`)} - to enter project\u2019s directory`), print(
|
52839
|
+
`Then: ${chalk2.cyan(devCommand)} -to run ${isCoreAppTemplate ? "your Sanity application" : "Sanity Studio"}
|
52840
|
+
`
|
52841
|
+
)), print("Other helpful commands"), print("npx sanity docs - to open the documentation in a browser"), print("npx sanity manage - to open the project settings in a browser"), print("npx sanity help - to explore the CLI manual");
|
52789
52842
|
const sendInvite = isFirstProject && await prompt2.single({
|
52790
52843
|
type: "confirm",
|
52791
52844
|
message: "We have an excellent developer community, would you like us to send you an invitation to join?",
|
@@ -52812,6 +52865,16 @@ ${chalk2.green("Success!")} Now, use these commands to continue:
|
|
52812
52865
|
isFirstProject: data.isFirstProject
|
52813
52866
|
}), data;
|
52814
52867
|
}
|
52868
|
+
if (isCoreAppTemplate) {
|
52869
|
+
const organizations = await apiClient({ requireUser: !0, requireProject: !1 }).request({ uri: "/organizations" });
|
52870
|
+
return {
|
52871
|
+
projectId: "",
|
52872
|
+
displayName: "",
|
52873
|
+
datasetName: "",
|
52874
|
+
isFirstProject: !1,
|
52875
|
+
organizationId: await getOrganizationId(organizations)
|
52876
|
+
};
|
52877
|
+
}
|
52815
52878
|
loadEnv.debug("Prompting user to select or create a project");
|
52816
52879
|
const project = await getOrCreateProject();
|
52817
52880
|
loadEnv.debug(`Project with name ${project.displayName} selected`), loadEnv.debug("Prompting user to select or create a dataset");
|
@@ -53030,7 +53093,8 @@ The default dataset configuration has a public dataset named "production".`;
|
|
53030
53093
|
autoUpdates,
|
53031
53094
|
dataset: datasetName,
|
53032
53095
|
projectId,
|
53033
|
-
projectName: displayName || answers.projectName
|
53096
|
+
projectName: displayName || answers.projectName,
|
53097
|
+
organizationId
|
53034
53098
|
};
|
53035
53099
|
return remoteTemplateInfo ? bootstrapRemoteTemplate(
|
53036
53100
|
{
|
@@ -53116,10 +53180,10 @@ The default dataset configuration has a public dataset named "production".`;
|
|
53116
53180
|
return cliFlags;
|
53117
53181
|
}
|
53118
53182
|
async function getOrganizationId(organizations) {
|
53119
|
-
let
|
53183
|
+
let orgId = flags.organization;
|
53120
53184
|
if (unattended)
|
53121
|
-
return
|
53122
|
-
if (organizations.length > 0 && !
|
53185
|
+
return orgId || void 0;
|
53186
|
+
if (organizations.length > 0 && !orgId) {
|
53123
53187
|
loadEnv.debug(`User has ${organizations.length} organization(s), checking attach access`);
|
53124
53188
|
const withGrant = await getOrganizationsWithAttachGrant(organizations);
|
53125
53189
|
if (withGrant.length === 0) {
|
@@ -53139,13 +53203,13 @@ The default dataset configuration has a public dataset named "production".`;
|
|
53139
53203
|
type: "list",
|
53140
53204
|
choices: organizationChoices
|
53141
53205
|
});
|
53142
|
-
chosenOrg && chosenOrg !== "none" && (
|
53143
|
-
} else
|
53144
|
-
return
|
53206
|
+
chosenOrg && chosenOrg !== "none" && (orgId = chosenOrg);
|
53207
|
+
} else orgId ? loadEnv.debug("User has defined organization flag explicitly (%s)", orgId) : organizations.length === 0 && loadEnv.debug("User has no organizations, skipping selection prompt");
|
53208
|
+
return orgId || void 0;
|
53145
53209
|
}
|
53146
|
-
async function hasProjectAttachGrant(
|
53210
|
+
async function hasProjectAttachGrant(orgId) {
|
53147
53211
|
const requiredGrantGroup = "sanity.organization.projects", requiredGrant = "attach";
|
53148
|
-
return ((await apiClient({ requireProject: !1, requireUser: !0 }).clone().config({ apiVersion: "v2021-06-07" }).request({ uri: `organizations/${
|
53212
|
+
return ((await apiClient({ requireProject: !1, requireUser: !0 }).clone().config({ apiVersion: "v2021-06-07" }).request({ uri: `organizations/${orgId}/grants` }))[requiredGrantGroup] || []).some(
|
53149
53213
|
(resource) => resource.grants && resource.grants.some((grant) => grant.name === requiredGrant)
|
53150
53214
|
);
|
53151
53215
|
}
|