@sanity/cli 3.85.2-media-library.14 → 3.86.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/lib/_chunks-cjs/cli.js +530 -28
- package/lib/_chunks-cjs/cli.js.map +1 -1
- package/package.json +6 -6
- package/src/commands/blueprints/addBlueprintsCommand.ts +81 -0
- package/src/commands/blueprints/blueprintsGroup.ts +11 -0
- package/src/commands/blueprints/configBlueprintsCommand.ts +112 -0
- package/src/commands/blueprints/deployBlueprintsCommand.ts +164 -0
- package/src/commands/blueprints/infoBlueprintsCommand.ts +84 -0
- package/src/commands/blueprints/initBlueprintsCommand.ts +96 -0
- package/src/commands/blueprints/logsBlueprintsCommand.ts +111 -0
- package/src/commands/blueprints/planBlueprintsCommand.ts +63 -0
- package/src/commands/blueprints/stacksBlueprintsCommand.ts +76 -0
- package/src/commands/functions/devFunctionsCommand.ts +2 -2
- package/src/commands/functions/envFunctionsCommand.ts +14 -15
- package/src/commands/functions/logsFunctionsCommand.ts +10 -7
- package/src/commands/functions/testFunctionsCommand.ts +14 -8
- package/src/commands/index.ts +18 -0
- package/bin/xdg-open +0 -1066
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@sanity/cli",
|
3
|
-
"version": "3.
|
3
|
+
"version": "3.86.0",
|
4
4
|
"description": "Sanity CLI tool for managing Sanity installations, managing plugins, schemas and datasets",
|
5
5
|
"keywords": [
|
6
6
|
"sanity",
|
@@ -59,11 +59,11 @@
|
|
59
59
|
"dependencies": {
|
60
60
|
"@babel/traverse": "^7.23.5",
|
61
61
|
"@sanity/client": "^6.29.0",
|
62
|
-
"@sanity/codegen": "3.
|
63
|
-
"@sanity/runtime-cli": "^
|
62
|
+
"@sanity/codegen": "3.86.0",
|
63
|
+
"@sanity/runtime-cli": "^3.0.0",
|
64
64
|
"@sanity/telemetry": "^0.8.0",
|
65
65
|
"@sanity/template-validator": "^2.4.3",
|
66
|
-
"@sanity/util": "3.
|
66
|
+
"@sanity/util": "3.86.0",
|
67
67
|
"chalk": "^4.1.2",
|
68
68
|
"debug": "^4.3.4",
|
69
69
|
"decompress": "^4.2.0",
|
@@ -83,7 +83,7 @@
|
|
83
83
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
84
84
|
"@sanity/eslint-config-studio": "^4.0.0",
|
85
85
|
"@sanity/generate-help-url": "^3.0.0",
|
86
|
-
"@sanity/types": "3.
|
86
|
+
"@sanity/types": "3.86.0",
|
87
87
|
"@types/babel__traverse": "^7.20.5",
|
88
88
|
"@types/configstore": "^5.0.1",
|
89
89
|
"@types/cpx": "^1.5.2",
|
@@ -135,5 +135,5 @@
|
|
135
135
|
"engines": {
|
136
136
|
"node": ">=18"
|
137
137
|
},
|
138
|
-
"gitHead": "
|
138
|
+
"gitHead": "29b5941dceac3ece48124c4ad586aa7431f33043"
|
139
139
|
}
|
@@ -0,0 +1,81 @@
|
|
1
|
+
import {type CliCommandDefinition} from '../../types'
|
2
|
+
|
3
|
+
const helpText = `
|
4
|
+
Arguments
|
5
|
+
[type] Type of Resource to add (currently only 'function' is supported)
|
6
|
+
|
7
|
+
Examples
|
8
|
+
# Add a Function Resource
|
9
|
+
sanity blueprints add function
|
10
|
+
`
|
11
|
+
|
12
|
+
const addBlueprintsCommand: CliCommandDefinition = {
|
13
|
+
name: 'add',
|
14
|
+
group: 'blueprints',
|
15
|
+
helpText,
|
16
|
+
signature: '<type>',
|
17
|
+
description: 'Add a Resource to a Blueprint',
|
18
|
+
hideFromHelp: true,
|
19
|
+
async action(args, context) {
|
20
|
+
const {output, prompt} = context
|
21
|
+
const {print} = output
|
22
|
+
|
23
|
+
const [resourceType] = args.argsWithoutOptions
|
24
|
+
|
25
|
+
if (!resourceType) {
|
26
|
+
print('Resource type is required. Available types: function')
|
27
|
+
return
|
28
|
+
}
|
29
|
+
|
30
|
+
const {blueprint: blueprintAction, resources: resourcesAction} = await import(
|
31
|
+
'@sanity/runtime-cli/actions/blueprints'
|
32
|
+
)
|
33
|
+
|
34
|
+
const existingBlueprint = blueprintAction.findBlueprintFile()
|
35
|
+
if (!existingBlueprint) {
|
36
|
+
print('No blueprint file found. Run `sanity blueprints init` first.')
|
37
|
+
return
|
38
|
+
}
|
39
|
+
|
40
|
+
if (resourceType === 'function') {
|
41
|
+
const functionName = await prompt.single({
|
42
|
+
type: 'input',
|
43
|
+
message: 'Enter function name:',
|
44
|
+
validate: (input: string) => input.length > 0 || 'Function name is required',
|
45
|
+
})
|
46
|
+
|
47
|
+
const functionType = await prompt.single({
|
48
|
+
type: 'list',
|
49
|
+
message: 'Choose function type:',
|
50
|
+
choices: [
|
51
|
+
{value: 'document-publish', name: 'Document Publish'},
|
52
|
+
{value: 'document-create', name: 'Document Create (Available soon)', disabled: true},
|
53
|
+
{value: 'document-delete', name: 'Document Delete (Available soon)', disabled: true},
|
54
|
+
],
|
55
|
+
})
|
56
|
+
|
57
|
+
const {filePath, resourceAdded, resource} = resourcesAction.createFunctionResource({
|
58
|
+
name: functionName,
|
59
|
+
type: functionType,
|
60
|
+
displayName: functionName,
|
61
|
+
})
|
62
|
+
|
63
|
+
print(`\nCreated function: ${filePath}`)
|
64
|
+
|
65
|
+
if (resourceAdded) {
|
66
|
+
// added to blueprint.json
|
67
|
+
print('Function Resource added to Blueprint')
|
68
|
+
} else {
|
69
|
+
// print the resource JSON for manual addition
|
70
|
+
print('\nAdd this Function Resource to your Blueprint:')
|
71
|
+
print(JSON.stringify(resource, null, 2))
|
72
|
+
}
|
73
|
+
|
74
|
+
return
|
75
|
+
}
|
76
|
+
|
77
|
+
print(`Unsupported resource type: ${resourceType}. Available types: function`)
|
78
|
+
},
|
79
|
+
}
|
80
|
+
|
81
|
+
export default addBlueprintsCommand
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import {type CliCommandGroupDefinition} from '../../types'
|
2
|
+
|
3
|
+
const blueprintsGroup: CliCommandGroupDefinition = {
|
4
|
+
name: 'blueprints',
|
5
|
+
signature: '[COMMAND]',
|
6
|
+
isGroupRoot: true,
|
7
|
+
description: 'Deploy and manage Sanity Blueprints and Stacks (IaC)',
|
8
|
+
hideFromHelp: true,
|
9
|
+
}
|
10
|
+
|
11
|
+
export default blueprintsGroup
|
@@ -0,0 +1,112 @@
|
|
1
|
+
import {type CliCommandDefinition} from '../../types'
|
2
|
+
|
3
|
+
const helpText = `
|
4
|
+
Options
|
5
|
+
--edit Edit the configuration
|
6
|
+
|
7
|
+
Examples
|
8
|
+
# View current configuration
|
9
|
+
sanity blueprints config
|
10
|
+
|
11
|
+
# Edit configuration
|
12
|
+
sanity blueprints config --edit
|
13
|
+
`
|
14
|
+
|
15
|
+
const defaultFlags = {
|
16
|
+
edit: false,
|
17
|
+
}
|
18
|
+
|
19
|
+
const configBlueprintsCommand: CliCommandDefinition = {
|
20
|
+
name: 'config',
|
21
|
+
group: 'blueprints',
|
22
|
+
helpText,
|
23
|
+
signature: '[--edit]',
|
24
|
+
description: 'View or edit local Blueprints configuration',
|
25
|
+
hideFromHelp: true,
|
26
|
+
async action(args, context) {
|
27
|
+
const {apiClient, output, prompt} = context
|
28
|
+
const {print} = output
|
29
|
+
const flags = {...defaultFlags, ...args.extOptions}
|
30
|
+
|
31
|
+
const client = apiClient({
|
32
|
+
requireUser: true,
|
33
|
+
requireProject: false,
|
34
|
+
})
|
35
|
+
const {token} = client.config()
|
36
|
+
const {
|
37
|
+
blueprint: blueprintAction,
|
38
|
+
projects: projectsAction,
|
39
|
+
stacks: stacksAction,
|
40
|
+
} = await import('@sanity/runtime-cli/actions/blueprints')
|
41
|
+
|
42
|
+
const config = blueprintAction.readConfigFile()
|
43
|
+
if (!config) {
|
44
|
+
print('No configuration found. Run `sanity blueprints init` first.')
|
45
|
+
return
|
46
|
+
}
|
47
|
+
|
48
|
+
print('\nCurrent configuration:')
|
49
|
+
print(JSON.stringify(config, null, 2))
|
50
|
+
|
51
|
+
if (!flags.edit) {
|
52
|
+
return
|
53
|
+
}
|
54
|
+
|
55
|
+
if (!token) {
|
56
|
+
print('No API token found. Please run `sanity login` first.')
|
57
|
+
return
|
58
|
+
}
|
59
|
+
|
60
|
+
const {ok, projects, error} = await projectsAction.listProjects({token})
|
61
|
+
if (!ok) {
|
62
|
+
print(error)
|
63
|
+
return
|
64
|
+
}
|
65
|
+
|
66
|
+
if (!projects || projects.length === 0) {
|
67
|
+
print('No Projects found. Please create a Project in Sanity.io first.')
|
68
|
+
return
|
69
|
+
}
|
70
|
+
|
71
|
+
const projectChoices = projects.map(({displayName, id}) => ({
|
72
|
+
value: id,
|
73
|
+
name: `${displayName} <${id}>`,
|
74
|
+
}))
|
75
|
+
|
76
|
+
const projectId = await prompt.single({
|
77
|
+
type: 'list',
|
78
|
+
message: 'Select your Sanity Project:',
|
79
|
+
choices: projectChoices,
|
80
|
+
default: config.projectId,
|
81
|
+
})
|
82
|
+
|
83
|
+
const auth = {token, projectId}
|
84
|
+
|
85
|
+
// get stacks for selected project
|
86
|
+
const {ok: stacksOk, stacks, error: stacksError} = await stacksAction.listStacks(auth)
|
87
|
+
if (!stacksOk) {
|
88
|
+
print(stacksError)
|
89
|
+
return
|
90
|
+
}
|
91
|
+
|
92
|
+
let stackId
|
93
|
+
if (stacks && stacks.length > 0) {
|
94
|
+
const stackChoices = stacks.map(({name, id}) => ({
|
95
|
+
value: id,
|
96
|
+
name: `${name} <${id}>`,
|
97
|
+
}))
|
98
|
+
|
99
|
+
stackId = await prompt.single({
|
100
|
+
type: 'list',
|
101
|
+
message: 'Select a Stack:',
|
102
|
+
choices: stackChoices,
|
103
|
+
default: config.stackId,
|
104
|
+
})
|
105
|
+
}
|
106
|
+
|
107
|
+
blueprintAction.writeConfigFile({projectId, stackId})
|
108
|
+
print('\nConfiguration updated successfully.')
|
109
|
+
},
|
110
|
+
}
|
111
|
+
|
112
|
+
export default configBlueprintsCommand
|
@@ -0,0 +1,164 @@
|
|
1
|
+
import {type CliCommandDefinition} from '../../types'
|
2
|
+
|
3
|
+
const helpText = `
|
4
|
+
Examples
|
5
|
+
# Deploy the current blueprint
|
6
|
+
sanity blueprints deploy
|
7
|
+
`
|
8
|
+
|
9
|
+
const deployBlueprintsCommand: CliCommandDefinition = {
|
10
|
+
name: 'deploy',
|
11
|
+
group: 'blueprints',
|
12
|
+
helpText,
|
13
|
+
signature: '',
|
14
|
+
description: 'Deploy a Blueprint to create or update a Stack',
|
15
|
+
hideFromHelp: true,
|
16
|
+
/* eslint-disable-next-line complexity, max-statements */
|
17
|
+
async action(args, context) {
|
18
|
+
const {apiClient, output, prompt} = context
|
19
|
+
const {print} = output
|
20
|
+
|
21
|
+
const client = apiClient({
|
22
|
+
requireUser: true,
|
23
|
+
requireProject: false,
|
24
|
+
})
|
25
|
+
const {token} = client.config()
|
26
|
+
const {
|
27
|
+
blueprint: blueprintAction,
|
28
|
+
stacks: stacksAction,
|
29
|
+
assets: assetsAction,
|
30
|
+
} = await import('@sanity/runtime-cli/actions/blueprints')
|
31
|
+
const {display} = await import('@sanity/runtime-cli/utils')
|
32
|
+
|
33
|
+
if (!token) {
|
34
|
+
print('No API token found. Please run `sanity login` first.')
|
35
|
+
return
|
36
|
+
}
|
37
|
+
|
38
|
+
let blueprint = null
|
39
|
+
try {
|
40
|
+
blueprint = await blueprintAction.readBlueprintOnDisk({getStack: true, token})
|
41
|
+
} catch (error) {
|
42
|
+
print('Unable to read Blueprint manifest file. Run `sanity blueprints init`')
|
43
|
+
return
|
44
|
+
}
|
45
|
+
|
46
|
+
if (!blueprint) {
|
47
|
+
print('Unable to read Blueprint manifest file. Run `sanity blueprints init`')
|
48
|
+
return
|
49
|
+
}
|
50
|
+
|
51
|
+
const {
|
52
|
+
errors,
|
53
|
+
projectId: configuredProjectId,
|
54
|
+
stackId,
|
55
|
+
parsedBlueprint,
|
56
|
+
deployedStack,
|
57
|
+
} = blueprint
|
58
|
+
|
59
|
+
if (errors && errors.length > 0) {
|
60
|
+
print(errors)
|
61
|
+
return
|
62
|
+
}
|
63
|
+
|
64
|
+
if (stackId && !deployedStack) {
|
65
|
+
print('Stack specified in config, but deployed Stack not found.')
|
66
|
+
return
|
67
|
+
}
|
68
|
+
|
69
|
+
const resources = parsedBlueprint.resources || []
|
70
|
+
|
71
|
+
let projectId = configuredProjectId
|
72
|
+
if (!projectId) {
|
73
|
+
print('No Sanity Project context found in Blueprint configuration.')
|
74
|
+
|
75
|
+
const maybeProjectId = await prompt.single({
|
76
|
+
type: 'input',
|
77
|
+
message: 'Enter Sanity Project ID:',
|
78
|
+
})
|
79
|
+
|
80
|
+
projectId = maybeProjectId
|
81
|
+
}
|
82
|
+
|
83
|
+
if (!projectId) {
|
84
|
+
print('Sanity Project context is required')
|
85
|
+
print('To configure this Blueprint, run `sanity blueprints config`')
|
86
|
+
return
|
87
|
+
}
|
88
|
+
|
89
|
+
const auth = {token, projectId}
|
90
|
+
|
91
|
+
let name = deployedStack?.name
|
92
|
+
if (!name) {
|
93
|
+
const stackName = await prompt.single({
|
94
|
+
type: 'input',
|
95
|
+
message: 'Enter stack name:',
|
96
|
+
validate: (input) => input.length > 0 || 'Stack name is required',
|
97
|
+
})
|
98
|
+
|
99
|
+
name = stackName
|
100
|
+
}
|
101
|
+
|
102
|
+
if (!name) {
|
103
|
+
print('Stack name is required')
|
104
|
+
return
|
105
|
+
}
|
106
|
+
|
107
|
+
const validResources = resources?.filter((r) => r.type)
|
108
|
+
const functionResources = validResources?.filter((r) => r.type.startsWith('sanity.function.'))
|
109
|
+
|
110
|
+
if (functionResources?.length) {
|
111
|
+
for (const resource of functionResources) {
|
112
|
+
print(`Processing ${resource.name}...`)
|
113
|
+
const result = await assetsAction.stashAsset({resource, auth})
|
114
|
+
|
115
|
+
if (result.success && result.assetId) {
|
116
|
+
const src = resource.src
|
117
|
+
resource.src = result.assetId // ! this will change! for now, the API expects the assetId
|
118
|
+
const {yellow} = display.colors
|
119
|
+
print(`${resource.name} <${yellow(result.assetId)}>`)
|
120
|
+
print(` Source: ${src}`)
|
121
|
+
} else {
|
122
|
+
print(` Error: ${result.error}`)
|
123
|
+
throw new Error(`Failed to process ${resource.name}`)
|
124
|
+
}
|
125
|
+
}
|
126
|
+
}
|
127
|
+
|
128
|
+
const stackPayload = {
|
129
|
+
name,
|
130
|
+
projectId,
|
131
|
+
document: {resources: validResources},
|
132
|
+
}
|
133
|
+
|
134
|
+
print('Deploying stack...')
|
135
|
+
|
136
|
+
const {
|
137
|
+
ok: deployOk,
|
138
|
+
stack,
|
139
|
+
error: deployError,
|
140
|
+
} = deployedStack
|
141
|
+
? await stacksAction.updateStack({stackId: deployedStack.id, stackPayload, auth})
|
142
|
+
: await stacksAction.createStack({stackPayload, auth})
|
143
|
+
|
144
|
+
if (deployOk) {
|
145
|
+
const {green, bold, yellow} = display.colors
|
146
|
+
print(
|
147
|
+
`${green('Success!')} Stack "${bold(stack.name)}" ${deployedStack ? 'updated' : 'created'} <${yellow(stack.id)}>`,
|
148
|
+
)
|
149
|
+
|
150
|
+
blueprintAction.writeConfigFile({
|
151
|
+
projectId,
|
152
|
+
stackId: stack.id,
|
153
|
+
})
|
154
|
+
|
155
|
+
print('\nUse `sanity blueprints info` to check deployment status')
|
156
|
+
} else {
|
157
|
+
const {red} = display.colors
|
158
|
+
print(`${red('Failed')} to ${deployedStack ? 'update' : 'create'} stack`)
|
159
|
+
print(`Error: ${deployError || JSON.stringify(stack, null, 2) || 'Unknown error'}`)
|
160
|
+
}
|
161
|
+
},
|
162
|
+
}
|
163
|
+
|
164
|
+
export default deployBlueprintsCommand
|
@@ -0,0 +1,84 @@
|
|
1
|
+
import {type CliCommandDefinition} from '../../types'
|
2
|
+
|
3
|
+
const helpText = `
|
4
|
+
Options
|
5
|
+
--id, -i Stack ID
|
6
|
+
|
7
|
+
Examples
|
8
|
+
# Retrieve information about the current Stack
|
9
|
+
sanity blueprints info
|
10
|
+
|
11
|
+
# Retrieve information about a specific Stack
|
12
|
+
sanity blueprints info --id <stack-id>
|
13
|
+
`
|
14
|
+
|
15
|
+
const defaultFlags = {id: undefined}
|
16
|
+
|
17
|
+
const infoBlueprintsCommand: CliCommandDefinition = {
|
18
|
+
name: 'info',
|
19
|
+
group: 'blueprints',
|
20
|
+
helpText,
|
21
|
+
signature: '',
|
22
|
+
description: 'Retrieve information about a Blueprint Stack',
|
23
|
+
hideFromHelp: true,
|
24
|
+
async action(args, context) {
|
25
|
+
const {apiClient, output} = context
|
26
|
+
const {print} = output
|
27
|
+
const flags = {...defaultFlags, ...args.extOptions}
|
28
|
+
|
29
|
+
const client = apiClient({
|
30
|
+
requireUser: true,
|
31
|
+
requireProject: false,
|
32
|
+
})
|
33
|
+
const {token} = client.config()
|
34
|
+
const {blueprint: blueprintAction, stacks: stacksAction} = await import(
|
35
|
+
'@sanity/runtime-cli/actions/blueprints'
|
36
|
+
)
|
37
|
+
const {display} = await import('@sanity/runtime-cli/utils')
|
38
|
+
|
39
|
+
let blueprint = null
|
40
|
+
try {
|
41
|
+
blueprint = await blueprintAction.readBlueprintOnDisk({token})
|
42
|
+
} catch (error) {
|
43
|
+
print('Unable to read Blueprint manifest file. Run `sanity blueprints init`')
|
44
|
+
return
|
45
|
+
}
|
46
|
+
|
47
|
+
if (!blueprint) {
|
48
|
+
print('Unable to read Blueprint manifest file. Run `sanity blueprints init`')
|
49
|
+
return
|
50
|
+
}
|
51
|
+
|
52
|
+
const {errors, deployedStack, projectId} = blueprint
|
53
|
+
|
54
|
+
if (errors && errors.length > 0) {
|
55
|
+
print(errors)
|
56
|
+
return
|
57
|
+
}
|
58
|
+
|
59
|
+
if (token && projectId) {
|
60
|
+
const auth = {token, projectId}
|
61
|
+
let result
|
62
|
+
if (flags.id) {
|
63
|
+
const {stack, error, ok} = await stacksAction.getStack({stackId: flags.id, auth})
|
64
|
+
if (ok) {
|
65
|
+
result = stack
|
66
|
+
} else {
|
67
|
+
print(error)
|
68
|
+
}
|
69
|
+
} else {
|
70
|
+
result = deployedStack
|
71
|
+
}
|
72
|
+
|
73
|
+
if (result) {
|
74
|
+
print(display.blueprintsFormatting.formatStackInfo(result))
|
75
|
+
} else {
|
76
|
+
print('No Stack found')
|
77
|
+
}
|
78
|
+
} else {
|
79
|
+
print('Cannot retrieve information for Blueprint: missing API token or Project ID')
|
80
|
+
}
|
81
|
+
},
|
82
|
+
}
|
83
|
+
|
84
|
+
export default infoBlueprintsCommand
|
@@ -0,0 +1,96 @@
|
|
1
|
+
import {join} from 'node:path'
|
2
|
+
import {cwd} from 'node:process'
|
3
|
+
|
4
|
+
import {type CliCommandDefinition} from '../../types'
|
5
|
+
|
6
|
+
const helpText = `
|
7
|
+
Examples
|
8
|
+
# Create a new Blueprint manifest file
|
9
|
+
sanity blueprints init
|
10
|
+
`
|
11
|
+
|
12
|
+
const initBlueprintsCommand: CliCommandDefinition = {
|
13
|
+
name: 'init',
|
14
|
+
group: 'blueprints',
|
15
|
+
helpText,
|
16
|
+
signature: '',
|
17
|
+
description: 'Initialize a new Blueprint manifest file',
|
18
|
+
hideFromHelp: true,
|
19
|
+
async action(args, context) {
|
20
|
+
const {apiClient, output, prompt} = context
|
21
|
+
const {print} = output
|
22
|
+
|
23
|
+
const client = apiClient({
|
24
|
+
requireUser: true,
|
25
|
+
requireProject: false,
|
26
|
+
})
|
27
|
+
const {token} = client.config()
|
28
|
+
|
29
|
+
if (!token) {
|
30
|
+
print('No API token found. Please run `sanity login` first.')
|
31
|
+
return
|
32
|
+
}
|
33
|
+
|
34
|
+
const {blueprint: blueprintAction, projects: projectsAction} = await import(
|
35
|
+
'@sanity/runtime-cli/actions/blueprints'
|
36
|
+
)
|
37
|
+
|
38
|
+
const existingBlueprint = blueprintAction.findBlueprintFile()
|
39
|
+
|
40
|
+
if (existingBlueprint) {
|
41
|
+
print(`A blueprint file already exists: ${existingBlueprint.fileName}`)
|
42
|
+
return
|
43
|
+
}
|
44
|
+
|
45
|
+
const blueprintExtension = await prompt.single({
|
46
|
+
type: 'list',
|
47
|
+
message: 'Choose a Blueprint manifest file type:',
|
48
|
+
choices: [
|
49
|
+
{value: 'json', name: 'JSON (Recommended)'},
|
50
|
+
{value: 'js', name: 'JavaScript (Available soon)', disabled: true},
|
51
|
+
{value: 'ts', name: 'TypeScript (Available soon)', disabled: true},
|
52
|
+
],
|
53
|
+
})
|
54
|
+
|
55
|
+
const {ok, projects, error} = await projectsAction.listProjects({token})
|
56
|
+
|
57
|
+
if (!ok) {
|
58
|
+
print(error)
|
59
|
+
return
|
60
|
+
}
|
61
|
+
|
62
|
+
if (!projects || projects.length === 0) {
|
63
|
+
print('No Projects found. Please create a Project in Sanity.io first.')
|
64
|
+
return
|
65
|
+
}
|
66
|
+
|
67
|
+
const projectChoices = projects.map(({displayName, id}) => ({
|
68
|
+
value: id,
|
69
|
+
name: `${displayName} <${id}>`,
|
70
|
+
}))
|
71
|
+
|
72
|
+
const projectId = await prompt.single({
|
73
|
+
type: 'list',
|
74
|
+
message: 'Select your Sanity Project:',
|
75
|
+
choices: projectChoices,
|
76
|
+
})
|
77
|
+
|
78
|
+
const fileName = `blueprint.${blueprintExtension}`
|
79
|
+
const filePath = join(cwd(), fileName)
|
80
|
+
|
81
|
+
blueprintAction.writeBlueprintToDisk({
|
82
|
+
path: filePath,
|
83
|
+
fileType: blueprintExtension as 'json' | 'js' | 'ts',
|
84
|
+
})
|
85
|
+
|
86
|
+
blueprintAction.writeConfigFile({projectId})
|
87
|
+
|
88
|
+
print(`Created new blueprint: ./${fileName}`)
|
89
|
+
|
90
|
+
if (blueprintExtension === 'ts') {
|
91
|
+
print('\nNote: TypeScript support requires "tsx" to be installed. Run: npm install -D tsx')
|
92
|
+
}
|
93
|
+
},
|
94
|
+
}
|
95
|
+
|
96
|
+
export default initBlueprintsCommand
|
@@ -0,0 +1,111 @@
|
|
1
|
+
import {type CliCommandDefinition} from '../../types'
|
2
|
+
|
3
|
+
const helpText = `
|
4
|
+
${
|
5
|
+
/*Options
|
6
|
+
--watch, -w Watch for new logs (streaming mode)
|
7
|
+
*/ ''
|
8
|
+
}
|
9
|
+
Examples
|
10
|
+
# Show logs for the current Stack
|
11
|
+
sanity blueprints logs
|
12
|
+
${
|
13
|
+
/*
|
14
|
+
# Watch for new logs
|
15
|
+
sanity blueprints logs --watch
|
16
|
+
*/ ''
|
17
|
+
}
|
18
|
+
`
|
19
|
+
|
20
|
+
// const defaultFlags = {watch: false}
|
21
|
+
|
22
|
+
const logsBlueprintsCommand: CliCommandDefinition = {
|
23
|
+
name: 'logs',
|
24
|
+
group: 'blueprints',
|
25
|
+
helpText,
|
26
|
+
signature: '[--watch]',
|
27
|
+
description: 'Display logs for the current Blueprint Stack',
|
28
|
+
hideFromHelp: true,
|
29
|
+
async action(args, context) {
|
30
|
+
const {apiClient, output} = context
|
31
|
+
const {print} = output
|
32
|
+
// const flags = {...defaultFlags, ...args.extOptions}
|
33
|
+
// const watchMode = Boolean(flags.watch)
|
34
|
+
|
35
|
+
const client = apiClient({requireUser: true, requireProject: false})
|
36
|
+
const {token} = client.config()
|
37
|
+
|
38
|
+
if (!token) {
|
39
|
+
print('No API token found. Please run `sanity login` first.')
|
40
|
+
return
|
41
|
+
}
|
42
|
+
|
43
|
+
const {blueprint: blueprintAction, logs: logsAction} = await import(
|
44
|
+
'@sanity/runtime-cli/actions/blueprints'
|
45
|
+
)
|
46
|
+
const {display} = await import('@sanity/runtime-cli/utils')
|
47
|
+
|
48
|
+
let blueprint = null
|
49
|
+
try {
|
50
|
+
blueprint = await blueprintAction.readBlueprintOnDisk({token})
|
51
|
+
} catch (error) {
|
52
|
+
print('Unable to read Blueprint manifest file. Run `sanity blueprints init`')
|
53
|
+
return
|
54
|
+
}
|
55
|
+
|
56
|
+
if (!blueprint) {
|
57
|
+
print('Unable to read Blueprint manifest file. Run `sanity blueprints init`')
|
58
|
+
return
|
59
|
+
}
|
60
|
+
|
61
|
+
const {errors, deployedStack} = blueprint
|
62
|
+
|
63
|
+
if (errors && errors.length > 0) {
|
64
|
+
print(errors)
|
65
|
+
return
|
66
|
+
}
|
67
|
+
|
68
|
+
if (!deployedStack) {
|
69
|
+
print('Stack not found')
|
70
|
+
return
|
71
|
+
}
|
72
|
+
|
73
|
+
const {id: stackId, projectId, name} = deployedStack
|
74
|
+
const auth = {token, projectId}
|
75
|
+
|
76
|
+
print(`Fetching logs for stack ${display.colors.yellow(`<${stackId}>`)}`)
|
77
|
+
|
78
|
+
// enable watch mode here
|
79
|
+
|
80
|
+
try {
|
81
|
+
const {ok, logs, error} = await logsAction.getLogs(stackId, auth)
|
82
|
+
|
83
|
+
if (!ok) {
|
84
|
+
print(`${display.colors.red('Failed')} to retrieve logs`)
|
85
|
+
print(`Error: ${error || 'Unknown error'}`)
|
86
|
+
return
|
87
|
+
}
|
88
|
+
|
89
|
+
if (logs.length === 0) {
|
90
|
+
print(`No logs found for Stack ${stackId}`)
|
91
|
+
return
|
92
|
+
}
|
93
|
+
|
94
|
+
print(`${display.blueprintsFormatting.formatTitle('Blueprint', name)} Logs`)
|
95
|
+
print(
|
96
|
+
`Found ${display.colors.bold(logs.length.toString())} log entries for stack ${display.colors.yellow(stackId)}\n`,
|
97
|
+
)
|
98
|
+
|
99
|
+
// Organize and format logs by day
|
100
|
+
const logsByDay = display.logsFormatting.organizeLogsByDay(logs)
|
101
|
+
print(display.logsFormatting.formatLogsByDay(logsByDay))
|
102
|
+
} catch (err) {
|
103
|
+
print('Failed to retrieve logs')
|
104
|
+
if (err instanceof Error) {
|
105
|
+
print(`Error: ${err.message}`)
|
106
|
+
}
|
107
|
+
}
|
108
|
+
},
|
109
|
+
}
|
110
|
+
|
111
|
+
export default logsBlueprintsCommand
|