@sanity/cli 3.96.1-next.5.6494f59c50 → 3.96.1-next.7.fd2aa4c9d2
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 +286 -49
- package/lib/_chunks-cjs/cli.js.map +1 -1
- package/package.json +6 -6
package/lib/_chunks-cjs/cli.js
CHANGED
|
@@ -3767,7 +3767,7 @@ function print() { __p += __j.call(arguments, '') }
|
|
|
3767
3767
|
}(lodash$1, lodash$1.exports)), lodash$1.exports;
|
|
3768
3768
|
}
|
|
3769
3769
|
var lodashExports = requireLodash();
|
|
3770
|
-
const helpText$
|
|
3770
|
+
const helpText$n = `
|
|
3771
3771
|
Arguments
|
|
3772
3772
|
<type> Type of Resource to add (currently only 'function' is supported)
|
|
3773
3773
|
|
|
@@ -3809,7 +3809,7 @@ Examples:
|
|
|
3809
3809
|
}, addBlueprintsCommand = {
|
|
3810
3810
|
name: "add",
|
|
3811
3811
|
group: "blueprints",
|
|
3812
|
-
helpText: helpText$
|
|
3812
|
+
helpText: helpText$n,
|
|
3813
3813
|
signature: "<type> [--name <name>] [--fn-type <document-publish>] [--fn-lang <ts|js>] [--javascript]",
|
|
3814
3814
|
description: "Add a Resource to a Blueprint",
|
|
3815
3815
|
async action(args, context) {
|
|
@@ -3870,7 +3870,7 @@ Examples:
|
|
|
3870
3870
|
signature: "[COMMAND]",
|
|
3871
3871
|
isGroupRoot: !0,
|
|
3872
3872
|
description: "Deploy and manage Sanity Blueprints and Stacks (IaC)"
|
|
3873
|
-
}, helpText$
|
|
3873
|
+
}, helpText$m = `
|
|
3874
3874
|
Options
|
|
3875
3875
|
--edit, -e Edit the configuration
|
|
3876
3876
|
--test, -t Test the configuration
|
|
@@ -3893,7 +3893,7 @@ Examples:
|
|
|
3893
3893
|
}, configBlueprintsCommand = {
|
|
3894
3894
|
name: "config",
|
|
3895
3895
|
group: "blueprints",
|
|
3896
|
-
helpText: helpText$
|
|
3896
|
+
helpText: helpText$m,
|
|
3897
3897
|
signature: "[--edit] [-e] [--test] [-t] [--project-id <id>]",
|
|
3898
3898
|
description: "View or edit local Blueprints configuration",
|
|
3899
3899
|
async action(args, context) {
|
|
@@ -3920,7 +3920,7 @@ Examples:
|
|
|
3920
3920
|
});
|
|
3921
3921
|
if (!success) throw new Error(error2);
|
|
3922
3922
|
}
|
|
3923
|
-
}, helpText$
|
|
3923
|
+
}, helpText$l = `
|
|
3924
3924
|
Options
|
|
3925
3925
|
--no-wait Do not wait for deployment to complete
|
|
3926
3926
|
|
|
@@ -3935,7 +3935,7 @@ Examples:
|
|
|
3935
3935
|
}, deployBlueprintsCommand = {
|
|
3936
3936
|
name: "deploy",
|
|
3937
3937
|
group: "blueprints",
|
|
3938
|
-
helpText: helpText$
|
|
3938
|
+
helpText: helpText$l,
|
|
3939
3939
|
signature: "[--no-wait]",
|
|
3940
3940
|
description: "Deploy a Blueprint to create or update a Stack",
|
|
3941
3941
|
async action(args, context) {
|
|
@@ -3958,7 +3958,7 @@ Examples:
|
|
|
3958
3958
|
});
|
|
3959
3959
|
if (!success) throw new Error(error2);
|
|
3960
3960
|
}
|
|
3961
|
-
}, helpText$
|
|
3961
|
+
}, helpText$k = `
|
|
3962
3962
|
Options
|
|
3963
3963
|
--force, -f Force destroy without confirmation
|
|
3964
3964
|
--no-wait Do not wait for destroy to complete
|
|
@@ -3977,7 +3977,7 @@ Examples:
|
|
|
3977
3977
|
}, destroyBlueprintsCommand = {
|
|
3978
3978
|
name: "destroy",
|
|
3979
3979
|
group: "blueprints",
|
|
3980
|
-
helpText: helpText$
|
|
3980
|
+
helpText: helpText$k,
|
|
3981
3981
|
signature: "[--force] [-f] [--no-wait]",
|
|
3982
3982
|
description: "Destroy a Blueprint deployment",
|
|
3983
3983
|
async action(args, context) {
|
|
@@ -4003,7 +4003,7 @@ Examples:
|
|
|
4003
4003
|
});
|
|
4004
4004
|
if (!success) throw new Error(error2);
|
|
4005
4005
|
}
|
|
4006
|
-
}, helpText$
|
|
4006
|
+
}, helpText$j = `
|
|
4007
4007
|
Examples:
|
|
4008
4008
|
# Retrieve information about the current Stack
|
|
4009
4009
|
sanity blueprints info
|
|
@@ -4012,7 +4012,7 @@ Examples:
|
|
|
4012
4012
|
}, infoBlueprintsCommand = {
|
|
4013
4013
|
name: "info",
|
|
4014
4014
|
group: "blueprints",
|
|
4015
|
-
helpText: helpText$
|
|
4015
|
+
helpText: helpText$j,
|
|
4016
4016
|
signature: "",
|
|
4017
4017
|
description: "Retrieve information about a Blueprint Stack",
|
|
4018
4018
|
async action(args, context) {
|
|
@@ -4033,7 +4033,7 @@ Examples:
|
|
|
4033
4033
|
});
|
|
4034
4034
|
if (!success) throw new Error(error2);
|
|
4035
4035
|
}
|
|
4036
|
-
}, helpText$
|
|
4036
|
+
}, helpText$i = `
|
|
4037
4037
|
Arguments
|
|
4038
4038
|
[dir] Path to initialize the Blueprint in
|
|
4039
4039
|
|
|
@@ -4055,7 +4055,7 @@ Examples:
|
|
|
4055
4055
|
}, initBlueprintsCommand = {
|
|
4056
4056
|
name: "init",
|
|
4057
4057
|
group: "blueprints",
|
|
4058
|
-
helpText: helpText$
|
|
4058
|
+
helpText: helpText$i,
|
|
4059
4059
|
signature: "[dir] [--blueprint-type <type>] [--project-id <id>]",
|
|
4060
4060
|
description: "Initialize a new Blueprint manifest file",
|
|
4061
4061
|
async action(args, context) {
|
|
@@ -4095,7 +4095,7 @@ Examples:
|
|
|
4095
4095
|
});
|
|
4096
4096
|
if (!success) throw new Error(error2);
|
|
4097
4097
|
}
|
|
4098
|
-
}, helpText$
|
|
4098
|
+
}, helpText$h = `
|
|
4099
4099
|
Options
|
|
4100
4100
|
--watch, -w Watch for new logs (streaming mode)
|
|
4101
4101
|
|
|
@@ -4110,7 +4110,7 @@ Examples:
|
|
|
4110
4110
|
}, logsBlueprintsCommand = {
|
|
4111
4111
|
name: "logs",
|
|
4112
4112
|
group: "blueprints",
|
|
4113
|
-
helpText: helpText$
|
|
4113
|
+
helpText: helpText$h,
|
|
4114
4114
|
signature: "[--watch] [-w]",
|
|
4115
4115
|
description: "Display logs for the current Blueprint Stack",
|
|
4116
4116
|
async action(args, context) {
|
|
@@ -4133,7 +4133,7 @@ Examples:
|
|
|
4133
4133
|
});
|
|
4134
4134
|
if (streaming && await streaming, !success) throw new Error(error2);
|
|
4135
4135
|
}
|
|
4136
|
-
}, helpText$
|
|
4136
|
+
}, helpText$g = `
|
|
4137
4137
|
Safe to run at any time. Will not modify any Resources.
|
|
4138
4138
|
|
|
4139
4139
|
Examples:
|
|
@@ -4142,7 +4142,7 @@ Examples:
|
|
|
4142
4142
|
`, planBlueprintsCommand = {
|
|
4143
4143
|
name: "plan",
|
|
4144
4144
|
group: "blueprints",
|
|
4145
|
-
helpText: helpText$
|
|
4145
|
+
helpText: helpText$g,
|
|
4146
4146
|
signature: "",
|
|
4147
4147
|
description: "Enumerate Resources to be deployed",
|
|
4148
4148
|
async action(args, context) {
|
|
@@ -4162,7 +4162,7 @@ Examples:
|
|
|
4162
4162
|
});
|
|
4163
4163
|
if (!success) throw new Error(error2);
|
|
4164
4164
|
}
|
|
4165
|
-
}, helpText$
|
|
4165
|
+
}, helpText$f = `
|
|
4166
4166
|
Options
|
|
4167
4167
|
--project-id <id> Project ID to use
|
|
4168
4168
|
|
|
@@ -4177,7 +4177,7 @@ Examples:
|
|
|
4177
4177
|
}, stacksBlueprintsCommand = {
|
|
4178
4178
|
name: "stacks",
|
|
4179
4179
|
group: "blueprints",
|
|
4180
|
-
helpText: helpText$
|
|
4180
|
+
helpText: helpText$f,
|
|
4181
4181
|
signature: "[--project-id <id>]",
|
|
4182
4182
|
description: "List all Blueprint Stacks for the current Project",
|
|
4183
4183
|
hideFromHelp: !0,
|
|
@@ -4345,7 +4345,7 @@ function ensureNpx() {
|
|
|
4345
4345
|
);
|
|
4346
4346
|
}
|
|
4347
4347
|
}
|
|
4348
|
-
const helpText$
|
|
4348
|
+
const helpText$e = `
|
|
4349
4349
|
Runs a given code modification script on the current studio folder.
|
|
4350
4350
|
Running the command without a specified codemod name will list available transformations.
|
|
4351
4351
|
|
|
@@ -4367,7 +4367,7 @@ Examples
|
|
|
4367
4367
|
name: "codemod",
|
|
4368
4368
|
signature: "[CODEMOD_NAME]",
|
|
4369
4369
|
description: "Updates Sanity Studio codebase with a code modification script",
|
|
4370
|
-
helpText: helpText$
|
|
4370
|
+
helpText: helpText$e,
|
|
4371
4371
|
action: codemodAction
|
|
4372
4372
|
};
|
|
4373
4373
|
var lodash_isplainobject, hasRequiredLodash_isplainobject;
|
|
@@ -7905,7 +7905,7 @@ const docsCommand = {
|
|
|
7905
7905
|
const { output } = context, { print } = output, url = "https://www.sanity.io/docs";
|
|
7906
7906
|
print(`Opening ${url}`), await open(url);
|
|
7907
7907
|
}
|
|
7908
|
-
}, helpText$
|
|
7908
|
+
}, helpText$d = `
|
|
7909
7909
|
Options
|
|
7910
7910
|
--port <port> Port to start emulator on
|
|
7911
7911
|
--open Open dev server in a new browser tab
|
|
@@ -7925,7 +7925,7 @@ Examples
|
|
|
7925
7925
|
}, devFunctionsCommand = {
|
|
7926
7926
|
name: "dev",
|
|
7927
7927
|
group: "functions",
|
|
7928
|
-
helpText: helpText$
|
|
7928
|
+
helpText: helpText$d,
|
|
7929
7929
|
signature: "[--port <port> --open]",
|
|
7930
7930
|
description: "Start the Sanity Function emulator",
|
|
7931
7931
|
async action(args, context) {
|
|
@@ -7946,7 +7946,7 @@ Examples
|
|
|
7946
7946
|
if (!success) throw new Error(error2);
|
|
7947
7947
|
shouldOpen && open(`http://localhost:${flags.port}`);
|
|
7948
7948
|
}
|
|
7949
|
-
}, helpText$
|
|
7949
|
+
}, helpText$c = `
|
|
7950
7950
|
Commands
|
|
7951
7951
|
add Add or update an environment variable
|
|
7952
7952
|
list List the environment variables
|
|
@@ -7969,7 +7969,7 @@ Examples
|
|
|
7969
7969
|
`, envFunctionsCommand = {
|
|
7970
7970
|
name: "env",
|
|
7971
7971
|
group: "functions",
|
|
7972
|
-
helpText: helpText$
|
|
7972
|
+
helpText: helpText$c,
|
|
7973
7973
|
signature: "<add|list|remove> <name> [key] [value]",
|
|
7974
7974
|
description: "Add or remove an environment variable or list environment variables for a Sanity function",
|
|
7975
7975
|
async action(args, context) {
|
|
@@ -8025,7 +8025,7 @@ Examples
|
|
|
8025
8025
|
signature: "[COMMAND]",
|
|
8026
8026
|
isGroupRoot: !0,
|
|
8027
8027
|
description: "Manage, test, and observe Sanity Functions"
|
|
8028
|
-
}, helpText$
|
|
8028
|
+
}, helpText$b = `
|
|
8029
8029
|
Arguments
|
|
8030
8030
|
<name> The name of the Function to retrieve logs for
|
|
8031
8031
|
|
|
@@ -8062,7 +8062,7 @@ Examples
|
|
|
8062
8062
|
}, logsFunctionsCommand = {
|
|
8063
8063
|
name: "logs",
|
|
8064
8064
|
group: "functions",
|
|
8065
|
-
helpText: helpText$
|
|
8065
|
+
helpText: helpText$b,
|
|
8066
8066
|
signature: "<name> [--limit <number>] [--json] [--utc] [--delete [--force]] [--watch]",
|
|
8067
8067
|
description: "Retrieve or delete logs for a Sanity Function",
|
|
8068
8068
|
async action(args, context) {
|
|
@@ -8087,7 +8087,7 @@ Examples
|
|
|
8087
8087
|
});
|
|
8088
8088
|
if (!success) throw new Error(error2);
|
|
8089
8089
|
}
|
|
8090
|
-
}, helpText$
|
|
8090
|
+
}, helpText$a = `
|
|
8091
8091
|
Arguments
|
|
8092
8092
|
<name> The name of the Sanity Function
|
|
8093
8093
|
|
|
@@ -8098,6 +8098,7 @@ Options
|
|
|
8098
8098
|
--api <version> Sanity API Version to use
|
|
8099
8099
|
--dataset <dataset> The Sanity dataset to use
|
|
8100
8100
|
--project-id <id> Sanity Project ID to use
|
|
8101
|
+
--with-user-token Prime access token from CLI config into getCliClient()
|
|
8101
8102
|
|
|
8102
8103
|
|
|
8103
8104
|
Examples
|
|
@@ -8110,13 +8111,14 @@ Examples
|
|
|
8110
8111
|
# Test function passing event data on command line and cap execution time to 60 seconds
|
|
8111
8112
|
sanity functions test echo --data '{ "id": 1 }' --timeout 60
|
|
8112
8113
|
`, defaultFlags$1 = {
|
|
8113
|
-
timeout: 10
|
|
8114
|
+
timeout: 10,
|
|
8114
8115
|
// seconds
|
|
8116
|
+
"with-user-token": !1
|
|
8115
8117
|
}, testFunctionsCommand = {
|
|
8116
8118
|
name: "test",
|
|
8117
8119
|
group: "functions",
|
|
8118
|
-
helpText: helpText$
|
|
8119
|
-
signature: "<name> [--data <json>] [--file <filename>] [--timeout <seconds>] [--api <version>] [--dataset <name>] [--project-id] <id>]",
|
|
8120
|
+
helpText: helpText$a,
|
|
8121
|
+
signature: "<name> [--data <json>] [--file <filename>] [--timeout <seconds>] [--api <version>] [--dataset <name>] [--project-id] <id>] [--with-user-token]",
|
|
8120
8122
|
description: "Invoke a local Sanity Function",
|
|
8121
8123
|
async action(args, context) {
|
|
8122
8124
|
const { apiClient, output } = context, [name] = args.argsWithoutOptions, flags = { ...defaultFlags$1, ...args.extOptions }, client2 = apiClient({
|
|
@@ -8141,7 +8143,8 @@ Examples
|
|
|
8141
8143
|
timeout: flags.timeout,
|
|
8142
8144
|
api: flags.api,
|
|
8143
8145
|
dataset: flags.dataset || actualDataset,
|
|
8144
|
-
"project-id": flags["project-id"] || projectId
|
|
8146
|
+
"project-id": flags["project-id"] || projectId,
|
|
8147
|
+
"with-user-token": flags["with-user-token"]
|
|
8145
8148
|
}
|
|
8146
8149
|
});
|
|
8147
8150
|
if (!success) throw new Error(error2);
|
|
@@ -8195,11 +8198,11 @@ const commonMistakes = { get: "list" }, levenThreshold = 3, coreCommands = [
|
|
|
8195
8198
|
"undeploy",
|
|
8196
8199
|
"uninstall",
|
|
8197
8200
|
"users"
|
|
8198
|
-
], discouragedCommands = ["upgrade", "check", "configcheck", "uninstall"], helpText$
|
|
8201
|
+
], discouragedCommands = ["upgrade", "check", "configcheck", "uninstall"], helpText$9 = `
|
|
8199
8202
|
Run the command again within a Sanity project directory, where "sanity"
|
|
8200
8203
|
is installed as a dependency.`;
|
|
8201
8204
|
function getNoSuchCommandText(cmdName, parentGroupName, groups) {
|
|
8202
|
-
return parentGroupName && groups && groups[parentGroupName] ? suggestCommand(cmdName, groups[parentGroupName], parentGroupName) : coreCommands.includes(cmdName) ? `Command "${cmdName}" is not available outside of a Sanity project context.${helpText$
|
|
8205
|
+
return parentGroupName && groups && groups[parentGroupName] ? suggestCommand(cmdName, groups[parentGroupName], parentGroupName) : coreCommands.includes(cmdName) ? `Command "${cmdName}" is not available outside of a Sanity project context.${helpText$9}` : suggestCommand(cmdName, groups ? groups.default : []);
|
|
8203
8206
|
}
|
|
8204
8207
|
function suggestCommand(cmdName, group, parentGroupName = null) {
|
|
8205
8208
|
const closest = group.filter((command2) => !discouragedCommands.includes(command2.name)).map((command2) => leven(command2.name, cmdName)).reduce(
|
|
@@ -53905,7 +53908,7 @@ ${err.message}`);
|
|
|
53905
53908
|
throw new Error(
|
|
53906
53909
|
`Given organization ID (${flags.organization}) not found, or you do not have access to it`
|
|
53907
53910
|
);
|
|
53908
|
-
if (!await
|
|
53911
|
+
if (!await hasProjectAttachGrant2(flags.organization))
|
|
53909
53912
|
throw new Error(
|
|
53910
53913
|
"You lack the necessary permissions to attach a project to this organization"
|
|
53911
53914
|
);
|
|
@@ -54170,7 +54173,7 @@ The default dataset configuration has a public dataset named "production".`;
|
|
|
54170
54173
|
}
|
|
54171
54174
|
return cliFlags;
|
|
54172
54175
|
}
|
|
54173
|
-
async function
|
|
54176
|
+
async function createOrganization2(props = {}) {
|
|
54174
54177
|
const name = props.name || await prompt2.single({
|
|
54175
54178
|
type: "input",
|
|
54176
54179
|
message: "Organization name:",
|
|
@@ -54200,13 +54203,13 @@ The default dataset configuration has a public dataset named "production".`;
|
|
|
54200
54203
|
default: defaultOrganizationId || void 0,
|
|
54201
54204
|
choices: organizationChoices
|
|
54202
54205
|
});
|
|
54203
|
-
return chosenOrg === "-new-" ?
|
|
54206
|
+
return chosenOrg === "-new-" ? createOrganization2().then((org) => org.id) : chosenOrg || void 0;
|
|
54204
54207
|
}
|
|
54205
54208
|
async function getOrganizationId(organizations) {
|
|
54206
54209
|
if (organizations.length === 0)
|
|
54207
|
-
return
|
|
54210
|
+
return createOrganization2().then((org) => org.id);
|
|
54208
54211
|
loadEnv.debug(`User has ${organizations.length} organization(s), checking attach access`);
|
|
54209
|
-
const withGrantInfo = await
|
|
54212
|
+
const withGrantInfo = await getOrganizationsWithAttachGrantInfo2(organizations), withAttach = withGrantInfo.filter(({ hasAttachGrant }) => hasAttachGrant);
|
|
54210
54213
|
loadEnv.debug("User has attach access to %d organizations.", withAttach.length);
|
|
54211
54214
|
const organizationChoices = [
|
|
54212
54215
|
...withGrantInfo.map(({ organization, hasAttachGrant }) => ({
|
|
@@ -54223,9 +54226,9 @@ The default dataset configuration has a public dataset named "production".`;
|
|
|
54223
54226
|
default: defaultOrganizationId || void 0,
|
|
54224
54227
|
choices: organizationChoices
|
|
54225
54228
|
});
|
|
54226
|
-
return chosenOrg === "-new-" ?
|
|
54229
|
+
return chosenOrg === "-new-" ? createOrganization2().then((org) => org.id) : chosenOrg || void 0;
|
|
54227
54230
|
}
|
|
54228
|
-
async function
|
|
54231
|
+
async function hasProjectAttachGrant2(orgId) {
|
|
54229
54232
|
const requiredGrantGroup = "sanity.organization.projects", requiredGrant = "attach", client2 = apiClient({ requireProject: !1, requireUser: !0 }).clone().config({ apiVersion: "v2021-06-07" });
|
|
54230
54233
|
try {
|
|
54231
54234
|
return ((await client2.request({ uri: `organizations/${orgId}/grants` }))[requiredGrantGroup] || []).some(
|
|
@@ -54235,11 +54238,11 @@ The default dataset configuration has a public dataset named "production".`;
|
|
|
54235
54238
|
return err.statusCode === 401 ? (loadEnv.debug("No access to organization %s (401)", orgId), !1) : (loadEnv.debug("Error checking grants for organization %s: %s", orgId, err.message), !1);
|
|
54236
54239
|
}
|
|
54237
54240
|
}
|
|
54238
|
-
function
|
|
54241
|
+
function getOrganizationsWithAttachGrantInfo2(organizations) {
|
|
54239
54242
|
return pMap(
|
|
54240
54243
|
organizations,
|
|
54241
54244
|
async (organization) => ({
|
|
54242
|
-
hasAttachGrant: await
|
|
54245
|
+
hasAttachGrant: await hasProjectAttachGrant2(organization.id),
|
|
54243
54246
|
organization
|
|
54244
54247
|
}),
|
|
54245
54248
|
{ concurrency: 3 }
|
|
@@ -54379,7 +54382,7 @@ function getImportCommand(outputPath, studioVersion) {
|
|
|
54379
54382
|
);
|
|
54380
54383
|
}
|
|
54381
54384
|
}
|
|
54382
|
-
const helpText$
|
|
54385
|
+
const helpText$8 = `
|
|
54383
54386
|
Options
|
|
54384
54387
|
-y, --yes Use unattended mode, accepting defaults and using only flags for choices
|
|
54385
54388
|
--project, --project-id <projectId> Project ID to use for the studio
|
|
@@ -54432,7 +54435,7 @@ Examples
|
|
|
54432
54435
|
name: "init",
|
|
54433
54436
|
signature: "",
|
|
54434
54437
|
description: "Initializes a new Sanity Studio and/or project",
|
|
54435
|
-
helpText: helpText$
|
|
54438
|
+
helpText: helpText$8,
|
|
54436
54439
|
action: async (args, context) => {
|
|
54437
54440
|
const [type2] = args.argsWithoutOptions;
|
|
54438
54441
|
if (type2)
|
|
@@ -54470,7 +54473,7 @@ Examples
|
|
|
54470
54473
|
const { output } = context, { print } = output, url = "https://www.sanity.io/learn";
|
|
54471
54474
|
print(`Opening ${url}`), await open(url);
|
|
54472
54475
|
}
|
|
54473
|
-
}, helpText$
|
|
54476
|
+
}, helpText$7 = `
|
|
54474
54477
|
Options
|
|
54475
54478
|
--sso <slug> Log in using Single Sign On, using the given slug
|
|
54476
54479
|
--provider <providerId> Authenticate against a specific provider
|
|
@@ -54488,16 +54491,16 @@ Examples
|
|
|
54488
54491
|
`, loginCommand = {
|
|
54489
54492
|
name: "login",
|
|
54490
54493
|
signature: "[--sso <slug>] [--provider <providerId>] [--no-open]",
|
|
54491
|
-
helpText: helpText$
|
|
54494
|
+
helpText: helpText$7,
|
|
54492
54495
|
description: "Authenticates the CLI for access to Sanity projects",
|
|
54493
54496
|
action: login
|
|
54494
|
-
}, helpText$
|
|
54497
|
+
}, helpText$6 = `
|
|
54495
54498
|
Examples
|
|
54496
54499
|
# Log out of the CLI
|
|
54497
54500
|
sanity logout
|
|
54498
54501
|
`, logoutCommand = {
|
|
54499
54502
|
name: "logout",
|
|
54500
|
-
helpText: helpText$
|
|
54503
|
+
helpText: helpText$6,
|
|
54501
54504
|
signature: "logout",
|
|
54502
54505
|
description: "Logs out the CLI from the current user session",
|
|
54503
54506
|
async action(args, { output, apiClient }) {
|
|
@@ -54527,6 +54530,239 @@ ${err.message}`));
|
|
|
54527
54530
|
const { output, cliConfig } = context, { print } = output, projectId = cliConfig?.api?.projectId, url = projectId ? `https://www.sanity.io/manage/project/${projectId}` : "https://www.sanity.io/manage/";
|
|
54528
54531
|
print(`Opening ${url}`), await open(url);
|
|
54529
54532
|
}
|
|
54533
|
+
};
|
|
54534
|
+
async function hasProjectAttachGrant(orgId, context) {
|
|
54535
|
+
const requiredGrantGroup = "sanity.organization.projects", requiredGrant = "attach", client2 = context.apiClient({ requireProject: !1, requireUser: !0 }).withConfig({ apiVersion: "v2021-06-07" });
|
|
54536
|
+
try {
|
|
54537
|
+
return ((await client2.request({ uri: `organizations/${orgId}/grants` }))[requiredGrantGroup] || []).some(
|
|
54538
|
+
(resource) => resource.grants && resource.grants.some((grant) => grant.name === requiredGrant)
|
|
54539
|
+
);
|
|
54540
|
+
} catch {
|
|
54541
|
+
return !1;
|
|
54542
|
+
}
|
|
54543
|
+
}
|
|
54544
|
+
function getOrganizationsWithAttachGrantInfo(organizations, context) {
|
|
54545
|
+
return pMap(
|
|
54546
|
+
organizations,
|
|
54547
|
+
async (organization) => ({
|
|
54548
|
+
hasAttachGrant: await hasProjectAttachGrant(organization.id, context),
|
|
54549
|
+
organization
|
|
54550
|
+
}),
|
|
54551
|
+
{ concurrency: 3 }
|
|
54552
|
+
);
|
|
54553
|
+
}
|
|
54554
|
+
function getOrganizationChoices(withGrantInfo, prompt2) {
|
|
54555
|
+
const choices2 = withGrantInfo.map(({ organization, hasAttachGrant }) => ({
|
|
54556
|
+
value: organization.id,
|
|
54557
|
+
name: `${organization.name} [${organization.id}]`,
|
|
54558
|
+
disabled: hasAttachGrant ? !1 : "Insufficient permissions"
|
|
54559
|
+
}));
|
|
54560
|
+
return prompt2 && choices2.push(
|
|
54561
|
+
new prompt2.Separator(),
|
|
54562
|
+
{ value: "-new-", name: "Create new organization", disabled: !1 },
|
|
54563
|
+
new prompt2.Separator()
|
|
54564
|
+
), choices2;
|
|
54565
|
+
}
|
|
54566
|
+
async function createOrganization(context, user, props = {}) {
|
|
54567
|
+
const { prompt: prompt2, apiClient } = context, name = props.name || await prompt2.single({
|
|
54568
|
+
type: "input",
|
|
54569
|
+
message: "Organization name:",
|
|
54570
|
+
default: void 0,
|
|
54571
|
+
validate(input2) {
|
|
54572
|
+
return input2.length === 0 ? "Organization name cannot be empty" : input2.length > 100 ? "Organization name cannot be longer than 100 characters" : !0;
|
|
54573
|
+
}
|
|
54574
|
+
}), spinner = context.output.spinner("Creating organization").start(), organization = await apiClient({ requireProject: !1, requireUser: !0 }).request({
|
|
54575
|
+
uri: "/organizations",
|
|
54576
|
+
method: "POST",
|
|
54577
|
+
body: { name }
|
|
54578
|
+
});
|
|
54579
|
+
return spinner.succeed(), organization;
|
|
54580
|
+
}
|
|
54581
|
+
async function promptForOrganizationSelection(choices2, defaultChoice, context) {
|
|
54582
|
+
return context.prompt.single({
|
|
54583
|
+
message: "Select organization:",
|
|
54584
|
+
type: "list",
|
|
54585
|
+
choices: choices2,
|
|
54586
|
+
default: defaultChoice
|
|
54587
|
+
});
|
|
54588
|
+
}
|
|
54589
|
+
async function getOrganization(context, user, unattended, specifiedOrgId) {
|
|
54590
|
+
const { apiClient, output } = context, client2 = apiClient({ requireUser: !0, requireProject: !1 }), spinner = output.spinner("Loading organizations").start();
|
|
54591
|
+
let organizations;
|
|
54592
|
+
try {
|
|
54593
|
+
organizations = await client2.request({ uri: "/organizations" });
|
|
54594
|
+
} catch (error2) {
|
|
54595
|
+
throw spinner.fail(), error2;
|
|
54596
|
+
}
|
|
54597
|
+
if (specifiedOrgId) {
|
|
54598
|
+
const org = organizations.find((o) => o.id === specifiedOrgId || o.slug === specifiedOrgId);
|
|
54599
|
+
if (!org)
|
|
54600
|
+
throw spinner.fail(), new Error(`Organization "${specifiedOrgId}" not found or you don't have access to it`);
|
|
54601
|
+
return spinner.succeed(), org;
|
|
54602
|
+
}
|
|
54603
|
+
if (organizations.length === 0)
|
|
54604
|
+
return spinner.succeed(), output.print("You need to create an organization to create projects."), createOrganization(context).then((org) => ({
|
|
54605
|
+
id: org.id,
|
|
54606
|
+
name: org.name,
|
|
54607
|
+
slug: org.slug || org.id
|
|
54608
|
+
}));
|
|
54609
|
+
const withGrantInfo = await getOrganizationsWithAttachGrantInfo(organizations, context);
|
|
54610
|
+
spinner.succeed();
|
|
54611
|
+
const withAttach = withGrantInfo.filter(({ hasAttachGrant }) => hasAttachGrant);
|
|
54612
|
+
if (unattended || !isInteractive$1)
|
|
54613
|
+
return withAttach.length > 0 ? withAttach[0].organization : void 0;
|
|
54614
|
+
const organizationChoices = getOrganizationChoices(withGrantInfo, context.prompt), defaultOrganizationId = withAttach.length === 1 ? withAttach[0].organization.id : organizations.find((org) => org.name === user?.name)?.id, chosenOrg = await promptForOrganizationSelection(
|
|
54615
|
+
organizationChoices,
|
|
54616
|
+
defaultOrganizationId,
|
|
54617
|
+
context
|
|
54618
|
+
);
|
|
54619
|
+
return chosenOrg === "-new-" ? createOrganization(context).then((org) => ({
|
|
54620
|
+
id: org.id,
|
|
54621
|
+
name: org.name,
|
|
54622
|
+
slug: org.slug || org.id
|
|
54623
|
+
})) : organizations.find((org) => org.id === chosenOrg) || void 0;
|
|
54624
|
+
}
|
|
54625
|
+
function validateProjectName(input2) {
|
|
54626
|
+
return !input2 || input2.trim() === "" ? "Project name cannot be empty" : input2.length > 80 ? "Project name cannot be longer than 80 characters" : !0;
|
|
54627
|
+
}
|
|
54628
|
+
async function promptForProjectName(prompt2) {
|
|
54629
|
+
return prompt2.single({
|
|
54630
|
+
type: "input",
|
|
54631
|
+
message: "Project name:",
|
|
54632
|
+
default: "My Sanity Project",
|
|
54633
|
+
validate: validateProjectName
|
|
54634
|
+
});
|
|
54635
|
+
}
|
|
54636
|
+
const DATASET_INFO_TEXT = `Your content will be stored in a dataset that can be public or private, depending on
|
|
54637
|
+
whether you want to query your content with or without authentication.
|
|
54638
|
+
The default dataset configuration has a public dataset named "production".`;
|
|
54639
|
+
async function promptAndCreateDataset(options2) {
|
|
54640
|
+
const { context, datasetName, datasetVisibility, unattended } = options2, { prompt: prompt2, output } = context;
|
|
54641
|
+
let finalDatasetName, finalVisibility, useDefaultConfig = !1;
|
|
54642
|
+
return datasetName ? finalDatasetName = datasetName : unattended ? (finalDatasetName = "production", useDefaultConfig = !0) : (output.print(DATASET_INFO_TEXT), useDefaultConfig = await promptForDefaultConfig(prompt2), useDefaultConfig ? finalDatasetName = "production" : finalDatasetName = await promptForDatasetName(prompt2, {
|
|
54643
|
+
message: "Name of your first dataset:"
|
|
54644
|
+
})), datasetVisibility ? finalVisibility = datasetVisibility : unattended || useDefaultConfig ? finalVisibility = "public" : finalVisibility = await promptForAclMode(prompt2, output), { name: finalDatasetName, visibility: finalVisibility };
|
|
54645
|
+
}
|
|
54646
|
+
async function createDatasetForProject(context, projectId, datasetName, visibility) {
|
|
54647
|
+
const { apiClient, output } = context, spinner = output.spinner("Creating dataset").start();
|
|
54648
|
+
try {
|
|
54649
|
+
return await apiClient({ api: { projectId } }).datasets.create(datasetName, { aclMode: visibility }), spinner.succeed(), { name: datasetName, visibility };
|
|
54650
|
+
} catch (err) {
|
|
54651
|
+
throw spinner.fail(), err;
|
|
54652
|
+
}
|
|
54653
|
+
}
|
|
54654
|
+
async function createProjectWithMetadata(apiClient, displayName, organizationId, context, extraMetadata = {}) {
|
|
54655
|
+
const { output } = context, spinner = output.spinner("Creating project").start();
|
|
54656
|
+
try {
|
|
54657
|
+
const createOptions = {
|
|
54658
|
+
displayName,
|
|
54659
|
+
organizationId,
|
|
54660
|
+
metadata: {
|
|
54661
|
+
integration: "cli",
|
|
54662
|
+
...extraMetadata
|
|
54663
|
+
}
|
|
54664
|
+
}, result = await createProject(apiClient, createOptions);
|
|
54665
|
+
return spinner.succeed(), result;
|
|
54666
|
+
} catch (error2) {
|
|
54667
|
+
throw spinner.fail(), error2;
|
|
54668
|
+
}
|
|
54669
|
+
}
|
|
54670
|
+
function formatProjectUrl(projectId, apiHost) {
|
|
54671
|
+
return `https://www.${new URL(apiHost).hostname.split(".").slice(-2).join(".")}/manage/project/${projectId}`;
|
|
54672
|
+
}
|
|
54673
|
+
function printProjectCreationSuccess(result, format, context) {
|
|
54674
|
+
const { output, apiClient } = context;
|
|
54675
|
+
if (format === "json") {
|
|
54676
|
+
output.print(JSON.stringify(result, null, 2));
|
|
54677
|
+
return;
|
|
54678
|
+
}
|
|
54679
|
+
output.print("Project created successfully!"), output.print(`ID: ${result.projectId}`), output.print(`Name: ${result.displayName}`), output.print(`Organization: ${result.organization?.name || "Personal"}`), result.dataset && output.print(`Dataset: ${result.dataset.name} (${result.dataset.visibility})`);
|
|
54680
|
+
const { apiHost } = apiClient({
|
|
54681
|
+
requireProject: !1,
|
|
54682
|
+
requireUser: !1
|
|
54683
|
+
}).config();
|
|
54684
|
+
output.print(""), output.print(`Manage your project: ${formatProjectUrl(result.projectId, apiHost)}`);
|
|
54685
|
+
}
|
|
54686
|
+
async function createProjectAction(options2, context) {
|
|
54687
|
+
const { apiClient, prompt: prompt2 } = context;
|
|
54688
|
+
apiClient({ requireUser: !0, requireProject: !1 });
|
|
54689
|
+
const projectName = options2.projectName || (options2.unattended || !isInteractive$1 ? "My Sanity Project" : await promptForProjectName(prompt2)), organization = await getOrganization(
|
|
54690
|
+
context,
|
|
54691
|
+
void 0,
|
|
54692
|
+
// user - not needed for projects create
|
|
54693
|
+
options2.unattended,
|
|
54694
|
+
options2.organizationId
|
|
54695
|
+
), project = await createProjectWithMetadata(apiClient, projectName, organization?.id, context), result = {
|
|
54696
|
+
projectId: project.projectId,
|
|
54697
|
+
displayName: project.displayName,
|
|
54698
|
+
organization
|
|
54699
|
+
};
|
|
54700
|
+
if (options2.createDataset) {
|
|
54701
|
+
const { name: datasetName, visibility } = await promptAndCreateDataset({
|
|
54702
|
+
context,
|
|
54703
|
+
datasetName: options2.datasetName,
|
|
54704
|
+
datasetVisibility: options2.datasetVisibility,
|
|
54705
|
+
unattended: options2.unattended || !isInteractive$1
|
|
54706
|
+
});
|
|
54707
|
+
try {
|
|
54708
|
+
const dataset = await createDatasetForProject(
|
|
54709
|
+
context,
|
|
54710
|
+
project.projectId,
|
|
54711
|
+
datasetName,
|
|
54712
|
+
visibility
|
|
54713
|
+
);
|
|
54714
|
+
result.dataset = dataset;
|
|
54715
|
+
} catch (err) {
|
|
54716
|
+
context.output.warn(`Project created but dataset creation failed: ${err.message}`);
|
|
54717
|
+
}
|
|
54718
|
+
}
|
|
54719
|
+
return result;
|
|
54720
|
+
}
|
|
54721
|
+
const helpText$5 = `
|
|
54722
|
+
Examples
|
|
54723
|
+
sanity projects create
|
|
54724
|
+
sanity projects create "My New Project"
|
|
54725
|
+
sanity projects create "My Project" --organization=my-org
|
|
54726
|
+
sanity projects create "My Project" --dataset
|
|
54727
|
+
sanity projects create "My Project" --dataset=staging --dataset-visibility=private
|
|
54728
|
+
sanity projects create "CI Project" --yes --json
|
|
54729
|
+
|
|
54730
|
+
Options
|
|
54731
|
+
--organization <slug|id> Organization to create the project in
|
|
54732
|
+
--dataset [name] Create a dataset. Prompts for name/visibility unless specified or --yes used
|
|
54733
|
+
--dataset-visibility <mode> Dataset visibility: public or private
|
|
54734
|
+
--json JSON output format
|
|
54735
|
+
-y, --yes Skip prompts and use defaults (project: "My Sanity Project", dataset: production, visibility: public)
|
|
54736
|
+
`, createProjectCommand = {
|
|
54737
|
+
name: "create",
|
|
54738
|
+
group: "projects",
|
|
54739
|
+
signature: "[PROJECT_NAME]",
|
|
54740
|
+
helpText: helpText$5,
|
|
54741
|
+
description: "Create a new Sanity project",
|
|
54742
|
+
action: async (args, context) => {
|
|
54743
|
+
const [projectName] = args.argsWithoutOptions, {
|
|
54744
|
+
organization,
|
|
54745
|
+
dataset,
|
|
54746
|
+
"dataset-visibility": datasetVisibility,
|
|
54747
|
+
json: json2,
|
|
54748
|
+
yes,
|
|
54749
|
+
y
|
|
54750
|
+
} = args.extOptions;
|
|
54751
|
+
let datasetName, createDataset = !1;
|
|
54752
|
+
dataset === !0 ? (createDataset = !0, datasetName = void 0) : typeof dataset == "string" && (createDataset = !0, datasetName = dataset);
|
|
54753
|
+
const result = await createProjectAction(
|
|
54754
|
+
{
|
|
54755
|
+
projectName,
|
|
54756
|
+
organizationId: organization,
|
|
54757
|
+
createDataset,
|
|
54758
|
+
datasetName,
|
|
54759
|
+
datasetVisibility,
|
|
54760
|
+
unattended: y || yes
|
|
54761
|
+
},
|
|
54762
|
+
context
|
|
54763
|
+
);
|
|
54764
|
+
printProjectCreationSuccess(result, json2 ? "json" : "text", context);
|
|
54765
|
+
}
|
|
54530
54766
|
}, headings = ["id", "members", "name", "url", "created"], helpText$4 = `
|
|
54531
54767
|
Options
|
|
54532
54768
|
--sort <field> Sort output by specified column
|
|
@@ -54567,7 +54803,7 @@ Examples
|
|
|
54567
54803
|
name: "projects",
|
|
54568
54804
|
signature: "[COMMAND]",
|
|
54569
54805
|
isGroupRoot: !0,
|
|
54570
|
-
description: "
|
|
54806
|
+
description: "Manage Sanity projects - list, create"
|
|
54571
54807
|
}, helpText$3 = `
|
|
54572
54808
|
Examples
|
|
54573
54809
|
# Check telemetry consent status for your logged in user
|
|
@@ -54788,6 +55024,7 @@ const baseCommands = [
|
|
|
54788
55024
|
projectGroup,
|
|
54789
55025
|
learnCommand,
|
|
54790
55026
|
listProjectsCommand,
|
|
55027
|
+
createProjectCommand,
|
|
54791
55028
|
codemodCommand,
|
|
54792
55029
|
telemetryGroup,
|
|
54793
55030
|
disableTelemetryCommand,
|