@sanity/cli 8.22.0 → 8.23.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/dist/actions/context/watchJob.js +9 -3
- package/dist/actions/context/watchJob.js.map +1 -1
- package/dist/actions/deploy/blueprintManaged.js +59 -0
- package/dist/actions/deploy/blueprintManaged.js.map +1 -0
- package/dist/actions/deploy/deployApp.js +117 -1
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +6 -31
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deployStudioSchemasAndManifestsWorker.js +6 -15
- package/dist/actions/deploy/deployStudioSchemasAndManifestsWorker.js.map +1 -1
- package/dist/actions/exec/runScript.worker.js +6 -2
- package/dist/actions/exec/runScript.worker.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +35 -11
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/createMediaLibraryCliConfig.js +12 -0
- package/dist/actions/init/createMediaLibraryCliConfig.js.map +1 -0
- package/dist/actions/init/determineMediaLibraryTemplate.js +14 -0
- package/dist/actions/init/determineMediaLibraryTemplate.js.map +1 -0
- package/dist/actions/init/initAction.js +35 -6
- package/dist/actions/init/initAction.js.map +1 -1
- package/dist/actions/init/initApp.js +81 -6
- package/dist/actions/init/initApp.js.map +1 -1
- package/dist/actions/init/offerAspectPull.js +81 -0
- package/dist/actions/init/offerAspectPull.js.map +1 -0
- package/dist/actions/init/project/getProjectDetails.js +25 -2
- package/dist/actions/init/project/getProjectDetails.js.map +1 -1
- package/dist/actions/init/templates/index.js +3 -0
- package/dist/actions/init/templates/index.js.map +1 -1
- package/dist/actions/init/templates/mediaLibraryConfig.js +51 -0
- package/dist/actions/init/templates/mediaLibraryConfig.js.map +1 -0
- package/dist/actions/media/aspectName.js +8 -0
- package/dist/actions/media/aspectName.js.map +1 -0
- package/dist/actions/media/aspectSync/contract.js +163 -0
- package/dist/actions/media/aspectSync/contract.js.map +1 -0
- package/dist/actions/media/aspectSync/syncAspects.js +115 -0
- package/dist/actions/media/aspectSync/syncAspects.js.map +1 -0
- package/dist/actions/media/cliConfigFields.js +192 -0
- package/dist/actions/media/cliConfigFields.js.map +1 -0
- package/dist/actions/media/pullAspects.js +225 -0
- package/dist/actions/media/pullAspects.js.map +1 -0
- package/dist/actions/media/resolveMediaLibraryId.js +83 -0
- package/dist/actions/media/resolveMediaLibraryId.js.map +1 -0
- package/dist/actions/schema/deploySchemas.js.map +1 -1
- package/dist/actions/schema/extractSchemaWatcher.js +69 -14
- package/dist/actions/schema/extractSchemaWatcher.js.map +1 -1
- package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -1
- package/dist/commands/context/build.js +2 -2
- package/dist/commands/context/build.js.map +1 -1
- package/dist/commands/context/entries/get.js +83 -0
- package/dist/commands/context/entries/get.js.map +1 -0
- package/dist/commands/context/entries/list.js +82 -0
- package/dist/commands/context/entries/list.js.map +1 -0
- package/dist/commands/context/entries/rebuild.js +95 -0
- package/dist/commands/context/entries/rebuild.js.map +1 -0
- package/dist/commands/context/issues/apply.js +86 -0
- package/dist/commands/context/issues/apply.js.map +1 -0
- package/dist/commands/context/issues/dismiss.js +52 -0
- package/dist/commands/context/issues/dismiss.js.map +1 -0
- package/dist/commands/context/issues/get.js +105 -0
- package/dist/commands/context/issues/get.js.map +1 -0
- package/dist/commands/context/issues/list.js +128 -0
- package/dist/commands/context/issues/list.js.map +1 -0
- package/dist/commands/context/issues/reopen.js +53 -0
- package/dist/commands/context/issues/reopen.js.map +1 -0
- package/dist/commands/context/issues/resolve.js +137 -0
- package/dist/commands/context/issues/resolve.js.map +1 -0
- package/dist/commands/context/jobs/get.js +2 -2
- package/dist/commands/context/jobs/get.js.map +1 -1
- package/dist/commands/context/query.js +92 -0
- package/dist/commands/context/query.js.map +1 -0
- package/dist/commands/deploy.js +13 -0
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/media/prune-aspect-data.js +170 -0
- package/dist/commands/media/prune-aspect-data.js.map +1 -0
- package/dist/commands/media/pull-aspects.js +309 -0
- package/dist/commands/media/pull-aspects.js.map +1 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +17 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
- package/dist/services/context.js +96 -3
- package/dist/services/context.js.map +1 -1
- package/dist/services/mediaLibraries.js +175 -8
- package/dist/services/mediaLibraries.js.map +1 -1
- package/oclif.manifest.json +1050 -361
- package/package.json +6 -5
- package/templates/media-library-config/README.md +52 -0
- package/templates/media-library-config/eslint.config.txt +52 -0
- package/templates/media-library-config/src/fields/caption.tsx +29 -0
- package/templates/media-library-config/src/fields/notes.tsx +54 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
|
+
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
4
|
+
import { isHttpError } from '@sanity/client';
|
|
5
|
+
import { listIssues } from '../../../services/context.js';
|
|
6
|
+
const listIssuesDebug = subdebug('context:issues:list');
|
|
7
|
+
export class ListIssuesCommand extends SanityCommand {
|
|
8
|
+
static args = {
|
|
9
|
+
knowledgeBaseId: Args.string({
|
|
10
|
+
description: 'Knowledge base ID',
|
|
11
|
+
required: true
|
|
12
|
+
})
|
|
13
|
+
};
|
|
14
|
+
static description = 'List issues found by knowledge base builds';
|
|
15
|
+
static enableJsonFlag = true;
|
|
16
|
+
static examples = [
|
|
17
|
+
{
|
|
18
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123',
|
|
19
|
+
description: 'List all issues for a knowledge base'
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 --status open',
|
|
23
|
+
description: 'List issues awaiting triage'
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 --kind conflict --severity critical',
|
|
27
|
+
description: 'List critical conflicts'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 --scope billing',
|
|
31
|
+
description: 'List issues about entries under billing/'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',
|
|
35
|
+
description: 'Output issues as JSON'
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
static flags = {
|
|
39
|
+
kind: Flags.custom({
|
|
40
|
+
description: 'Only list issues of this kind',
|
|
41
|
+
// A Record forces every kind the client knows to be listed, so the options can't drift
|
|
42
|
+
options: Object.keys({
|
|
43
|
+
add_entry: true,
|
|
44
|
+
conflict: true,
|
|
45
|
+
gap: true,
|
|
46
|
+
merge_entry: true,
|
|
47
|
+
remove_entry: true,
|
|
48
|
+
split_entry: true,
|
|
49
|
+
update_required: true
|
|
50
|
+
})
|
|
51
|
+
})(),
|
|
52
|
+
scope: Flags.string({
|
|
53
|
+
description: 'Only list issues about this entry path or anything under it (`*` for knowledge-base-wide issues)',
|
|
54
|
+
helpValue: '<path>',
|
|
55
|
+
parse: async (input)=>{
|
|
56
|
+
const trimmed = input.trim().replace(/\/+$/, '');
|
|
57
|
+
if (trimmed === '') {
|
|
58
|
+
throw new Error('`--scope` cannot be empty if provided');
|
|
59
|
+
}
|
|
60
|
+
return trimmed;
|
|
61
|
+
}
|
|
62
|
+
}),
|
|
63
|
+
severity: Flags.custom({
|
|
64
|
+
description: 'Only list issues of this severity',
|
|
65
|
+
options: [
|
|
66
|
+
'critical',
|
|
67
|
+
'suggestion'
|
|
68
|
+
]
|
|
69
|
+
})(),
|
|
70
|
+
status: Flags.custom({
|
|
71
|
+
description: 'Only list issues with this status (rejected = dismissed, accepted = resolved or applied)',
|
|
72
|
+
options: [
|
|
73
|
+
'open',
|
|
74
|
+
'accepted',
|
|
75
|
+
'rejected'
|
|
76
|
+
]
|
|
77
|
+
})()
|
|
78
|
+
};
|
|
79
|
+
async run() {
|
|
80
|
+
const { knowledgeBaseId } = this.args;
|
|
81
|
+
const { json, kind, scope, severity, status } = this.flags;
|
|
82
|
+
let issues;
|
|
83
|
+
try {
|
|
84
|
+
issues = await listIssues(knowledgeBaseId, status);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
listIssuesDebug('Error listing issues', error);
|
|
87
|
+
if (isHttpError(error) && error.statusCode === 404) {
|
|
88
|
+
this.error(`Knowledge base "${knowledgeBaseId}" not found`, {
|
|
89
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
this.error(`Failed to list issues: ${getErrorMessage(error)}`, {
|
|
93
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
// The client only filters on status; the rest are applied here
|
|
97
|
+
const matches = issues.filter(({ content })=>(kind === undefined || content.kind === kind) && (severity === undefined || content.severity === severity) && (scope === undefined || content.scopePath === scope || content.scopePath.startsWith(`${scope}/`)));
|
|
98
|
+
if (json) {
|
|
99
|
+
this.logJson(matches);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (matches.length === 0) {
|
|
103
|
+
this.log('No issues found');
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// Two lines per issue so long IDs never wrap: ID and metadata, then the summary cut to fit
|
|
107
|
+
const width = Math.max(process.stdout.columns ?? 100, 40);
|
|
108
|
+
const blocks = matches.map(({ _id, content, status: issueStatus })=>{
|
|
109
|
+
const meta = [
|
|
110
|
+
content.kind,
|
|
111
|
+
content.severity,
|
|
112
|
+
issueStatus,
|
|
113
|
+
content.scopePath
|
|
114
|
+
].join(' · ');
|
|
115
|
+
return `${_id} ${meta}\n ${truncate(content.issue, width - 2)}`;
|
|
116
|
+
});
|
|
117
|
+
this.log(blocks.join('\n\n'));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
function truncate(text, maxLength) {
|
|
121
|
+
// Count characters, not UTF-16 units, so an emoji at the cut point isn't split
|
|
122
|
+
const chars = [
|
|
123
|
+
...text.replaceAll(/\s+/g, ' ').trim()
|
|
124
|
+
];
|
|
125
|
+
return chars.length <= maxLength ? chars.join('') : `${chars.slice(0, maxLength - 1).join('')}…`;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/context/issues/list.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {type Context, isHttpError} from '@sanity/client'\n\nimport {listIssues} from '../../../services/context.js'\n\nconst listIssuesDebug = subdebug('context:issues:list')\n\nexport class ListIssuesCommand extends SanityCommand<typeof ListIssuesCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n }\n\n static override description = 'List issues found by knowledge base builds'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123',\n description: 'List all issues for a knowledge base',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --status open',\n description: 'List issues awaiting triage',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --kind conflict --severity critical',\n description: 'List critical conflicts',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --scope billing',\n description: 'List issues about entries under billing/',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 --json',\n description: 'Output issues as JSON',\n },\n ]\n\n static override flags = {\n kind: Flags.custom<IssueKind>({\n description: 'Only list issues of this kind',\n // A Record forces every kind the client knows to be listed, so the options can't drift\n options: Object.keys({\n add_entry: true,\n conflict: true,\n gap: true,\n merge_entry: true,\n remove_entry: true,\n split_entry: true,\n update_required: true,\n } satisfies Record<IssueKind, true>),\n })(),\n scope: Flags.string({\n description:\n 'Only list issues about this entry path or anything under it (`*` for knowledge-base-wide issues)',\n helpValue: '<path>',\n parse: async (input: string) => {\n const trimmed = input.trim().replace(/\\/+$/, '')\n if (trimmed === '') {\n throw new Error('`--scope` cannot be empty if provided')\n }\n return trimmed\n },\n }),\n severity: Flags.custom<Context.IssueDoc['content']['severity']>({\n description: 'Only list issues of this severity',\n options: ['critical', 'suggestion'],\n })(),\n status: Flags.custom<Context.IssueDoc['status']>({\n description:\n 'Only list issues with this status (rejected = dismissed, accepted = resolved or applied)',\n options: ['open', 'accepted', 'rejected'],\n })(),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {knowledgeBaseId} = this.args\n const {json, kind, scope, severity, status} = this.flags\n\n let issues\n try {\n issues = await listIssues(knowledgeBaseId, status)\n } catch (error) {\n listIssuesDebug('Error listing issues', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to list issues: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // The client only filters on status; the rest are applied here\n const matches = issues.filter(\n ({content}) =>\n (kind === undefined || content.kind === kind) &&\n (severity === undefined || content.severity === severity) &&\n (scope === undefined ||\n content.scopePath === scope ||\n content.scopePath.startsWith(`${scope}/`)),\n )\n\n if (json) {\n this.logJson(matches)\n return\n }\n\n if (matches.length === 0) {\n this.log('No issues found')\n return\n }\n\n // Two lines per issue so long IDs never wrap: ID and metadata, then the summary cut to fit\n const width = Math.max(process.stdout.columns ?? 100, 40)\n const blocks = matches.map(({_id, content, status: issueStatus}) => {\n const meta = [content.kind, content.severity, issueStatus, content.scopePath].join(' · ')\n return `${_id} ${meta}\\n ${truncate(content.issue, width - 2)}`\n })\n this.log(blocks.join('\\n\\n'))\n }\n}\n\ntype IssueKind = Context.IssueDoc['content']['kind']\n\nfunction truncate(text: string, maxLength: number): string {\n // Count characters, not UTF-16 units, so an emoji at the cut point isn't split\n const chars = [...text.replaceAll(/\\s+/g, ' ').trim()]\n return chars.length <= maxLength ? chars.join('') : `${chars.slice(0, maxLength - 1).join('')}…`\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","listIssues","listIssuesDebug","ListIssuesCommand","args","knowledgeBaseId","string","description","required","enableJsonFlag","examples","command","flags","kind","custom","options","Object","keys","add_entry","conflict","gap","merge_entry","remove_entry","split_entry","update_required","scope","helpValue","parse","input","trimmed","trim","replace","Error","severity","status","run","json","issues","error","statusCode","exit","RUNTIME_ERROR","matches","filter","content","undefined","scopePath","startsWith","logJson","length","log","width","Math","max","process","stdout","columns","blocks","map","_id","issueStatus","meta","join","truncate","issue","text","maxLength","chars","replaceAll","slice"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Args } from '@oclif/core';
|
|
2
|
+
import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
|
+
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
4
|
+
import { isHttpError } from '@sanity/client';
|
|
5
|
+
import { reopenIssue } from '../../../services/context.js';
|
|
6
|
+
const reopenIssueDebug = subdebug('context:issues:reopen');
|
|
7
|
+
export class ReopenIssueCommand extends SanityCommand {
|
|
8
|
+
static args = {
|
|
9
|
+
knowledgeBaseId: Args.string({
|
|
10
|
+
description: 'Knowledge base ID',
|
|
11
|
+
required: true
|
|
12
|
+
}),
|
|
13
|
+
// eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first
|
|
14
|
+
issueId: Args.string({
|
|
15
|
+
description: 'Issue ID',
|
|
16
|
+
required: true
|
|
17
|
+
})
|
|
18
|
+
};
|
|
19
|
+
static description = 'Reopen a resolved conflict issue';
|
|
20
|
+
static examples = [
|
|
21
|
+
{
|
|
22
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',
|
|
23
|
+
description: 'Return a resolved conflict issue to triage'
|
|
24
|
+
}
|
|
25
|
+
];
|
|
26
|
+
async run() {
|
|
27
|
+
const { issueId, knowledgeBaseId } = this.args;
|
|
28
|
+
let reopened;
|
|
29
|
+
try {
|
|
30
|
+
reopened = await reopenIssue(knowledgeBaseId, issueId);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
reopenIssueDebug('Error reopening issue', error);
|
|
33
|
+
if (isHttpError(error) && error.statusCode === 404) {
|
|
34
|
+
this.error(`Issue "${issueId}" not found on knowledge base "${knowledgeBaseId}"`, {
|
|
35
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
this.error(`Failed to reopen issue: ${getErrorMessage(error)}`, {
|
|
39
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
// The API returns the issue unchanged when it cannot be reopened
|
|
43
|
+
if (reopened.status !== 'open') {
|
|
44
|
+
const status = reopened.status === 'rejected' ? 'rejected (dismissed)' : 'accepted (resolved or applied)';
|
|
45
|
+
this.error(`Issue "${issueId}" is ${status} and cannot be reopened.\nOnly resolved conflict issues can be reopened.`, {
|
|
46
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
this.log('Issue reopened');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//# sourceMappingURL=reopen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/context/issues/reopen.ts"],"sourcesContent":["import {Args} from '@oclif/core'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {reopenIssue} from '../../../services/context.js'\n\nconst reopenIssueDebug = subdebug('context:issues:reopen')\n\nexport class ReopenIssueCommand extends SanityCommand<typeof ReopenIssueCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n issueId: Args.string({\n description: 'Issue ID',\n required: true,\n }),\n }\n\n static override description = 'Reopen a resolved conflict issue'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',\n description: 'Return a resolved conflict issue to triage',\n },\n ]\n\n public async run(): Promise<void> {\n const {issueId, knowledgeBaseId} = this.args\n\n let reopened\n try {\n reopened = await reopenIssue(knowledgeBaseId, issueId)\n } catch (error) {\n reopenIssueDebug('Error reopening issue', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Issue \"${issueId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to reopen issue: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // The API returns the issue unchanged when it cannot be reopened\n if (reopened.status !== 'open') {\n const status =\n reopened.status === 'rejected' ? 'rejected (dismissed)' : 'accepted (resolved or applied)'\n this.error(\n `Issue \"${issueId}\" is ${status} and cannot be reopened.\\nOnly resolved conflict issues can be reopened.`,\n {exit: exitCodes.RUNTIME_ERROR},\n )\n }\n\n this.log('Issue reopened')\n }\n}\n"],"names":["Args","exitCodes","SanityCommand","subdebug","getErrorMessage","isHttpError","reopenIssue","reopenIssueDebug","ReopenIssueCommand","args","knowledgeBaseId","string","description","required","issueId","examples","command","run","reopened","error","statusCode","exit","RUNTIME_ERROR","status","log"],"mappings":"AAAA,SAAQA,IAAI,QAAO,cAAa;AAChC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,WAAW,QAAO,+BAA8B;AAExD,MAAMC,mBAAmBJ,SAAS;AAElC,OAAO,MAAMK,2BAA2BN;IACtC,OAAgBO,OAAO;QACrBC,iBAAiBV,KAAKW,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,SAASd,KAAKW,MAAM,CAAC;YACnBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,mCAAkC;IAEhE,OAAgBG,WAAW;QACzB;YACEC,SAAS;YACTJ,aAAa;QACf;KACD,CAAA;IAED,MAAaK,MAAqB;QAChC,MAAM,EAACH,OAAO,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAE5C,IAAIS;QACJ,IAAI;YACFA,WAAW,MAAMZ,YAAYI,iBAAiBI;QAChD,EAAE,OAAOK,OAAO;YACdZ,iBAAiB,yBAAyBY;YAC1C,IAAId,YAAYc,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,OAAO,EAAEL,QAAQ,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAChFW,MAAMpB,UAAUqB,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,wBAAwB,EAAEf,gBAAgBe,QAAQ,EAAE;gBAC9DE,MAAMpB,UAAUqB,aAAa;YAC/B;QACF;QAEA,iEAAiE;QACjE,IAAIJ,SAASK,MAAM,KAAK,QAAQ;YAC9B,MAAMA,SACJL,SAASK,MAAM,KAAK,aAAa,yBAAyB;YAC5D,IAAI,CAACJ,KAAK,CACR,CAAC,OAAO,EAAEL,QAAQ,KAAK,EAAES,OAAO,wEAAwE,CAAC,EACzG;gBAACF,MAAMpB,UAAUqB,aAAa;YAAA;QAElC;QAEA,IAAI,CAACE,GAAG,CAAC;IACX;AACF"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
|
+
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
4
|
+
import { requiredWhenUnattended } from '@sanity/cli-core/flags';
|
|
5
|
+
import { select } from '@sanity/cli-core/ux';
|
|
6
|
+
import { isHttpError } from '@sanity/client';
|
|
7
|
+
import { formatJobFailure, watchJob } from '../../../actions/context/watchJob.js';
|
|
8
|
+
import { formatKeyValue } from '../../../actions/debug/output.js';
|
|
9
|
+
import { getIssue, resolveIssue } from '../../../services/context.js';
|
|
10
|
+
const resolveIssueDebug = subdebug('context:issues:resolve');
|
|
11
|
+
export class ResolveIssueCommand extends SanityCommand {
|
|
12
|
+
static args = {
|
|
13
|
+
knowledgeBaseId: Args.string({
|
|
14
|
+
description: 'Knowledge base ID',
|
|
15
|
+
required: true
|
|
16
|
+
}),
|
|
17
|
+
// eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first
|
|
18
|
+
issueId: Args.string({
|
|
19
|
+
description: 'Issue ID',
|
|
20
|
+
required: true
|
|
21
|
+
})
|
|
22
|
+
};
|
|
23
|
+
static description = 'Resolve a conflict issue by choosing the correct side\n\nResolving also creates a standing instruction that future builds follow. `sanity context issues reopen` removes it.';
|
|
24
|
+
static examples = [
|
|
25
|
+
{
|
|
26
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',
|
|
27
|
+
description: 'Interactively choose the correct side of a conflict'
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --side 1 --watch',
|
|
31
|
+
description: 'Choose side 1 and wait for the entry to be rewritten'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --side 0',
|
|
35
|
+
description: 'Keep the entry as it is (for a conflict on a single entry)'
|
|
36
|
+
}
|
|
37
|
+
];
|
|
38
|
+
static flags = {
|
|
39
|
+
side: requiredWhenUnattended(Flags.integer({
|
|
40
|
+
description: 'Index of the correct side, as listed by `sanity context issues get`',
|
|
41
|
+
min: 0
|
|
42
|
+
})),
|
|
43
|
+
watch: Flags.boolean({
|
|
44
|
+
default: false,
|
|
45
|
+
description: 'Wait for the entry rewrite to finish, exiting non-zero if it fails'
|
|
46
|
+
})
|
|
47
|
+
};
|
|
48
|
+
async run() {
|
|
49
|
+
const { issueId, knowledgeBaseId } = this.args;
|
|
50
|
+
const { side: sideFlag, watch } = this.flags;
|
|
51
|
+
const side = sideFlag ?? await this.promptForSide(knowledgeBaseId, issueId);
|
|
52
|
+
let resolved;
|
|
53
|
+
try {
|
|
54
|
+
resolved = await resolveIssue(knowledgeBaseId, issueId, side);
|
|
55
|
+
} catch (error) {
|
|
56
|
+
resolveIssueDebug('Error resolving issue', error);
|
|
57
|
+
if (isHttpError(error) && error.statusCode === 404) {
|
|
58
|
+
this.error(`Issue "${issueId}" not found on knowledge base "${knowledgeBaseId}"`, {
|
|
59
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
this.error(`Failed to resolve issue: ${getErrorMessage(error)}`, {
|
|
63
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
this.log('Issue resolved');
|
|
67
|
+
const { jobId } = resolved;
|
|
68
|
+
if (jobId === null) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
this.log(formatKeyValue('Job ID', jobId));
|
|
72
|
+
this.log(`Track it with: sanity context jobs get ${knowledgeBaseId} ${jobId}`);
|
|
73
|
+
if (!watch) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
let job;
|
|
77
|
+
try {
|
|
78
|
+
job = await watchJob(knowledgeBaseId, jobId, {
|
|
79
|
+
label: 'Rewriting entry',
|
|
80
|
+
successText: 'Entry rewritten'
|
|
81
|
+
});
|
|
82
|
+
} catch (error) {
|
|
83
|
+
resolveIssueDebug('Error watching rewrite job', error);
|
|
84
|
+
this.error(`Failed to watch rewrite job: ${getErrorMessage(error)}`, {
|
|
85
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (job.status !== 'succeeded') {
|
|
89
|
+
this.error(formatJobFailure('Rewrite', job), {
|
|
90
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async promptForSide(knowledgeBaseId, issueId) {
|
|
95
|
+
let issue;
|
|
96
|
+
try {
|
|
97
|
+
issue = await getIssue(knowledgeBaseId, issueId);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
resolveIssueDebug('Error getting issue', error);
|
|
100
|
+
if (isHttpError(error) && error.statusCode === 404) {
|
|
101
|
+
this.error(`Knowledge base "${knowledgeBaseId}" not found`, {
|
|
102
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
this.error(`Failed to get issue: ${getErrorMessage(error)}`, {
|
|
106
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (!issue) {
|
|
110
|
+
this.error(`Issue "${issueId}" not found on knowledge base "${knowledgeBaseId}"`, {
|
|
111
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
if (issue.status === 'rejected') {
|
|
115
|
+
this.error(`Issue "${issueId}" is rejected (dismissed) and cannot be resolved`, {
|
|
116
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
const { content } = issue;
|
|
120
|
+
if (content.kind !== 'conflict') {
|
|
121
|
+
this.error(`Only conflict issues can be resolved, "${issueId}" is of kind ${content.kind}`, {
|
|
122
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return select({
|
|
126
|
+
choices: content.sides.map((side, index)=>({
|
|
127
|
+
name: `[${index}] ${side.claim}`,
|
|
128
|
+
value: index
|
|
129
|
+
})),
|
|
130
|
+
// Re-resolving keeps the current choice preselected, so Enter can't flip it
|
|
131
|
+
default: issue.resolution ?? content.suggested,
|
|
132
|
+
message: 'Which side is correct?'
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/context/issues/resolve.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {requiredWhenUnattended} from '@sanity/cli-core/flags'\nimport {select} from '@sanity/cli-core/ux'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatJobFailure, watchJob} from '../../../actions/context/watchJob.js'\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getIssue, resolveIssue} from '../../../services/context.js'\n\nconst resolveIssueDebug = subdebug('context:issues:resolve')\n\nexport class ResolveIssueCommand extends SanityCommand<typeof ResolveIssueCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n issueId: Args.string({\n description: 'Issue ID',\n required: true,\n }),\n }\n\n static override description =\n 'Resolve a conflict issue by choosing the correct side\\n\\nResolving also creates a standing instruction that future builds follow. `sanity context issues reopen` removes it.'\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456',\n description: 'Interactively choose the correct side of a conflict',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --side 1 --watch',\n description: 'Choose side 1 and wait for the entry to be rewritten',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 issue.def456 --side 0',\n description: 'Keep the entry as it is (for a conflict on a single entry)',\n },\n ]\n\n static override flags = {\n side: requiredWhenUnattended(\n Flags.integer({\n description: 'Index of the correct side, as listed by `sanity context issues get`',\n min: 0,\n }),\n ),\n watch: Flags.boolean({\n default: false,\n description: 'Wait for the entry rewrite to finish, exiting non-zero if it fails',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {issueId, knowledgeBaseId} = this.args\n const {side: sideFlag, watch} = this.flags\n\n const side = sideFlag ?? (await this.promptForSide(knowledgeBaseId, issueId))\n\n let resolved\n try {\n resolved = await resolveIssue(knowledgeBaseId, issueId, side)\n } catch (error) {\n resolveIssueDebug('Error resolving issue', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Issue \"${issueId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to resolve issue: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n this.log('Issue resolved')\n\n const {jobId} = resolved\n if (jobId === null) {\n return\n }\n\n this.log(formatKeyValue('Job ID', jobId))\n this.log(`Track it with: sanity context jobs get ${knowledgeBaseId} ${jobId}`)\n\n if (!watch) {\n return\n }\n\n let job\n try {\n job = await watchJob(knowledgeBaseId, jobId, {\n label: 'Rewriting entry',\n successText: 'Entry rewritten',\n })\n } catch (error) {\n resolveIssueDebug('Error watching rewrite job', error)\n this.error(`Failed to watch rewrite job: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (job.status !== 'succeeded') {\n this.error(formatJobFailure('Rewrite', job), {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n\n private async promptForSide(knowledgeBaseId: string, issueId: string): Promise<number> {\n let issue\n try {\n issue = await getIssue(knowledgeBaseId, issueId)\n } catch (error) {\n resolveIssueDebug('Error getting issue', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Knowledge base \"${knowledgeBaseId}\" not found`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get issue: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (!issue) {\n this.error(`Issue \"${issueId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n if (issue.status === 'rejected') {\n this.error(`Issue \"${issueId}\" is rejected (dismissed) and cannot be resolved`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const {content} = issue\n if (content.kind !== 'conflict') {\n this.error(`Only conflict issues can be resolved, \"${issueId}\" is of kind ${content.kind}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n return select({\n choices: content.sides.map((side, index) => ({\n name: `[${index}] ${side.claim}`,\n value: index,\n })),\n // Re-resolving keeps the current choice preselected, so Enter can't flip it\n default: issue.resolution ?? content.suggested,\n message: 'Which side is correct?',\n })\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","requiredWhenUnattended","select","isHttpError","formatJobFailure","watchJob","formatKeyValue","getIssue","resolveIssue","resolveIssueDebug","ResolveIssueCommand","args","knowledgeBaseId","string","description","required","issueId","examples","command","flags","side","integer","min","watch","boolean","default","run","sideFlag","promptForSide","resolved","error","statusCode","exit","RUNTIME_ERROR","log","jobId","job","label","successText","status","issue","content","kind","choices","sides","map","index","name","claim","value","resolution","suggested","message"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { Args, Flags } from '@oclif/core';
|
|
|
2
2
|
import { exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
3
|
import { getErrorMessage, JsonOutputError } from '@sanity/cli-core/errors';
|
|
4
4
|
import { isHttpError } from '@sanity/client';
|
|
5
|
-
import { watchJob } from '../../../actions/context/watchJob.js';
|
|
5
|
+
import { formatJobFailure, watchJob } from '../../../actions/context/watchJob.js';
|
|
6
6
|
import { formatKeyValue } from '../../../actions/debug/output.js';
|
|
7
7
|
import { getJob } from '../../../services/context.js';
|
|
8
8
|
const getJobDebug = subdebug('context:jobs:get');
|
|
@@ -56,7 +56,7 @@ export class GetJobCommand extends SanityCommand {
|
|
|
56
56
|
});
|
|
57
57
|
}
|
|
58
58
|
const jobFailed = watch && job.status !== 'succeeded';
|
|
59
|
-
const failureMessage =
|
|
59
|
+
const failureMessage = formatJobFailure('Job', job);
|
|
60
60
|
if (json) {
|
|
61
61
|
if (jobFailed) throw new JsonOutputError(failureMessage, job, exitCodes.RUNTIME_ERROR);
|
|
62
62
|
this.logJson(job);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/commands/context/jobs/get.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage, JsonOutputError} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {watchJob} from '../../../actions/context/watchJob.js'\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getJob} from '../../../services/context.js'\n\nconst getJobDebug = subdebug('context:jobs:get')\n\nexport class GetJobCommand extends SanityCommand<typeof GetJobCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n jobId: Args.string({\n description: 'Job ID',\n required: true,\n }),\n }\n\n static override description = 'Get the status of a knowledge base job'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456',\n description: 'Get the current status of a job',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456 --watch',\n description: 'Wait for the job to finish (non-zero exit if it does not succeed)',\n },\n ]\n\n static override flags = {\n watch: Flags.boolean({\n default: false,\n description: 'Poll until the job reaches a terminal state',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {jobId, knowledgeBaseId} = this.args\n const {json, watch} = this.flags\n\n let job\n try {\n job = watch\n ? await watchJob(knowledgeBaseId, jobId, {label: 'Waiting for job'})\n : await getJob(knowledgeBaseId, jobId)\n } catch (error) {\n getJobDebug('Error getting job', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Job \"${jobId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get job: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const jobFailed = watch && job.status !== 'succeeded'\n const failureMessage =
|
|
1
|
+
{"version":3,"sources":["../../../../src/commands/context/jobs/get.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage, JsonOutputError} from '@sanity/cli-core/errors'\nimport {isHttpError} from '@sanity/client'\n\nimport {formatJobFailure, watchJob} from '../../../actions/context/watchJob.js'\nimport {formatKeyValue} from '../../../actions/debug/output.js'\nimport {getJob} from '../../../services/context.js'\n\nconst getJobDebug = subdebug('context:jobs:get')\n\nexport class GetJobCommand extends SanityCommand<typeof GetJobCommand> {\n static override args = {\n knowledgeBaseId: Args.string({\n description: 'Knowledge base ID',\n required: true,\n }),\n // eslint-disable-next-line perfectionist/sort-objects -- positional order: knowledge base first\n jobId: Args.string({\n description: 'Job ID',\n required: true,\n }),\n }\n\n static override description = 'Get the status of a knowledge base job'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456',\n description: 'Get the current status of a job',\n },\n {\n command: '<%= config.bin %> <%= command.id %> kb-abc123 job-def456 --watch',\n description: 'Wait for the job to finish (non-zero exit if it does not succeed)',\n },\n ]\n\n static override flags = {\n watch: Flags.boolean({\n default: false,\n description: 'Poll until the job reaches a terminal state',\n }),\n } satisfies FlagInput\n\n public async run(): Promise<void> {\n const {jobId, knowledgeBaseId} = this.args\n const {json, watch} = this.flags\n\n let job\n try {\n job = watch\n ? await watchJob(knowledgeBaseId, jobId, {label: 'Waiting for job'})\n : await getJob(knowledgeBaseId, jobId)\n } catch (error) {\n getJobDebug('Error getting job', error)\n if (isHttpError(error) && error.statusCode === 404) {\n this.error(`Job \"${jobId}\" not found on knowledge base \"${knowledgeBaseId}\"`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n this.error(`Failed to get job: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n const jobFailed = watch && job.status !== 'succeeded'\n const failureMessage = formatJobFailure('Job', job)\n if (json) {\n if (jobFailed) throw new JsonOutputError(failureMessage, job, exitCodes.RUNTIME_ERROR)\n this.logJson(job)\n } else {\n const padTo = 9 // \"Completed\" is the longest key\n this.log(formatKeyValue('ID', job.id, {padTo}))\n this.log(formatKeyValue('Status', job.status, {padTo}))\n this.log(formatKeyValue('Started', job.startedAt ?? '-', {padTo}))\n this.log(formatKeyValue('Completed', job.completedAt ?? '-', {padTo}))\n this.log(formatKeyValue('Error', job.error ?? '-', {padTo}))\n }\n\n if (jobFailed) {\n this.error(failureMessage, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n }\n}\n"],"names":["Args","Flags","exitCodes","SanityCommand","subdebug","getErrorMessage","JsonOutputError","isHttpError","formatJobFailure","watchJob","formatKeyValue","getJob","getJobDebug","GetJobCommand","args","knowledgeBaseId","string","description","required","jobId","enableJsonFlag","examples","command","flags","watch","boolean","default","run","json","job","label","error","statusCode","exit","RUNTIME_ERROR","jobFailed","status","failureMessage","logJson","padTo","log","id","startedAt","completedAt"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACnE,SAAQC,eAAe,EAAEC,eAAe,QAAO,0BAAyB;AACxE,SAAQC,WAAW,QAAO,iBAAgB;AAE1C,SAAQC,gBAAgB,EAAEC,QAAQ,QAAO,uCAAsC;AAC/E,SAAQC,cAAc,QAAO,mCAAkC;AAC/D,SAAQC,MAAM,QAAO,+BAA8B;AAEnD,MAAMC,cAAcR,SAAS;AAE7B,OAAO,MAAMS,sBAAsBV;IACjC,OAAgBW,OAAO;QACrBC,iBAAiBf,KAAKgB,MAAM,CAAC;YAC3BC,aAAa;YACbC,UAAU;QACZ;QACA,gGAAgG;QAChGC,OAAOnB,KAAKgB,MAAM,CAAC;YACjBC,aAAa;YACbC,UAAU;QACZ;IACF,EAAC;IAED,OAAgBD,cAAc,yCAAwC;IAEtE,OAAgBG,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTL,aAAa;QACf;QACA;YACEK,SAAS;YACTL,aAAa;QACf;KACD,CAAA;IAED,OAAgBM,QAAQ;QACtBC,OAAOvB,MAAMwB,OAAO,CAAC;YACnBC,SAAS;YACTT,aAAa;QACf;IACF,EAAqB;IAErB,MAAaU,MAAqB;QAChC,MAAM,EAACR,KAAK,EAAEJ,eAAe,EAAC,GAAG,IAAI,CAACD,IAAI;QAC1C,MAAM,EAACc,IAAI,EAAEJ,KAAK,EAAC,GAAG,IAAI,CAACD,KAAK;QAEhC,IAAIM;QACJ,IAAI;YACFA,MAAML,QACF,MAAMf,SAASM,iBAAiBI,OAAO;gBAACW,OAAO;YAAiB,KAChE,MAAMnB,OAAOI,iBAAiBI;QACpC,EAAE,OAAOY,OAAO;YACdnB,YAAY,qBAAqBmB;YACjC,IAAIxB,YAAYwB,UAAUA,MAAMC,UAAU,KAAK,KAAK;gBAClD,IAAI,CAACD,KAAK,CAAC,CAAC,KAAK,EAAEZ,MAAM,+BAA+B,EAAEJ,gBAAgB,CAAC,CAAC,EAAE;oBAC5EkB,MAAM/B,UAAUgC,aAAa;gBAC/B;YACF;YACA,IAAI,CAACH,KAAK,CAAC,CAAC,mBAAmB,EAAE1B,gBAAgB0B,QAAQ,EAAE;gBACzDE,MAAM/B,UAAUgC,aAAa;YAC/B;QACF;QAEA,MAAMC,YAAYX,SAASK,IAAIO,MAAM,KAAK;QAC1C,MAAMC,iBAAiB7B,iBAAiB,OAAOqB;QAC/C,IAAID,MAAM;YACR,IAAIO,WAAW,MAAM,IAAI7B,gBAAgB+B,gBAAgBR,KAAK3B,UAAUgC,aAAa;YACrF,IAAI,CAACI,OAAO,CAACT;QACf,OAAO;YACL,MAAMU,QAAQ,EAAE,iCAAiC;;YACjD,IAAI,CAACC,GAAG,CAAC9B,eAAe,MAAMmB,IAAIY,EAAE,EAAE;gBAACF;YAAK;YAC5C,IAAI,CAACC,GAAG,CAAC9B,eAAe,UAAUmB,IAAIO,MAAM,EAAE;gBAACG;YAAK;YACpD,IAAI,CAACC,GAAG,CAAC9B,eAAe,WAAWmB,IAAIa,SAAS,IAAI,KAAK;gBAACH;YAAK;YAC/D,IAAI,CAACC,GAAG,CAAC9B,eAAe,aAAamB,IAAIc,WAAW,IAAI,KAAK;gBAACJ;YAAK;YACnE,IAAI,CAACC,GAAG,CAAC9B,eAAe,SAASmB,IAAIE,KAAK,IAAI,KAAK;gBAACQ;YAAK;QAC3D;QAEA,IAAIJ,WAAW;YACb,IAAI,CAACJ,KAAK,CAACM,gBAAgB;gBACzBJ,MAAM/B,UAAUgC,aAAa;YAC/B;QACF;IACF;AACF"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Args, Flags } from '@oclif/core';
|
|
2
|
+
import { colorizeJson, exitCodes, SanityCommand, subdebug } from '@sanity/cli-core';
|
|
3
|
+
import { getErrorMessage } from '@sanity/cli-core/errors';
|
|
4
|
+
import { isRecord } from '@sanity/cli-core/util';
|
|
5
|
+
import { MissingOrganizationError, resolveOrganizationId } from '../../actions/context/resolveOrganizationId.js';
|
|
6
|
+
import { queryContext } from '../../services/context.js';
|
|
7
|
+
import { getOrganizationFlag } from '../../util/sharedFlags.js';
|
|
8
|
+
import { defineCommandTelemetry } from '../../util/telemetry/commandTelemetry.js';
|
|
9
|
+
const queryContextDebug = subdebug('context:query');
|
|
10
|
+
const flags = {
|
|
11
|
+
...getOrganizationFlag({
|
|
12
|
+
description: 'Organization to query',
|
|
13
|
+
semantics: 'override'
|
|
14
|
+
}),
|
|
15
|
+
params: Flags.custom({
|
|
16
|
+
description: 'Query parameters as a JSON object',
|
|
17
|
+
helpValue: '<json>',
|
|
18
|
+
parse: async (input)=>{
|
|
19
|
+
let parsed;
|
|
20
|
+
try {
|
|
21
|
+
parsed = JSON.parse(input);
|
|
22
|
+
} catch {
|
|
23
|
+
throw new Error('`--params` must be valid JSON');
|
|
24
|
+
}
|
|
25
|
+
if (!isRecord(parsed)) {
|
|
26
|
+
throw new Error('`--params` must be a JSON object, like \'{"type": "issue"}\'');
|
|
27
|
+
}
|
|
28
|
+
return parsed;
|
|
29
|
+
}
|
|
30
|
+
})()
|
|
31
|
+
};
|
|
32
|
+
export class QueryContextCommand extends SanityCommand {
|
|
33
|
+
static args = {
|
|
34
|
+
query: Args.string({
|
|
35
|
+
description: "GROQ query to run against the organization's Context documents",
|
|
36
|
+
required: true
|
|
37
|
+
})
|
|
38
|
+
};
|
|
39
|
+
static description = "Query an organization's Context documents with GROQ";
|
|
40
|
+
static enableJsonFlag = true;
|
|
41
|
+
static examples = [
|
|
42
|
+
{
|
|
43
|
+
command: '<%= config.bin %> <%= command.id %> \'*[_type == "sanity.context.issue" && status == "open"]{_id, knowledgeBaseId}\'',
|
|
44
|
+
description: 'List open issues across all knowledge bases'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
command: '<%= config.bin %> <%= command.id %> \'*[_type == "sanity.context.entry" && knowledgeBaseId == $kb].path\' --params \'{"kb": "kb-abc123"}\' --json',
|
|
48
|
+
description: 'List the entry paths of one knowledge base as plain JSON'
|
|
49
|
+
}
|
|
50
|
+
];
|
|
51
|
+
static flags = flags;
|
|
52
|
+
static telemetry = defineCommandTelemetry(flags, {
|
|
53
|
+
redact: [
|
|
54
|
+
'params'
|
|
55
|
+
]
|
|
56
|
+
});
|
|
57
|
+
async run() {
|
|
58
|
+
const { query } = this.args;
|
|
59
|
+
const { json, organization, params } = this.flags;
|
|
60
|
+
let organizationId;
|
|
61
|
+
try {
|
|
62
|
+
organizationId = await resolveOrganizationId({
|
|
63
|
+
configuredOrganizationId: (await this.tryGetCliConfig()).app?.organizationId,
|
|
64
|
+
flagOrganizationId: organization,
|
|
65
|
+
unattended: this.isUnattended()
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
queryContextDebug('Error resolving organization', error);
|
|
69
|
+
this.error(getErrorMessage(error), {
|
|
70
|
+
exit: error instanceof MissingOrganizationError ? exitCodes.USAGE_ERROR : exitCodes.RUNTIME_ERROR
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
let result;
|
|
74
|
+
try {
|
|
75
|
+
result = await queryContext(organizationId, query, params);
|
|
76
|
+
} catch (error) {
|
|
77
|
+
queryContextDebug('Error running query', error);
|
|
78
|
+
this.error(`Failed to run query: ${getErrorMessage(error)}`, {
|
|
79
|
+
exit: exitCodes.RUNTIME_ERROR
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// GROQ returns null for no match; guard undefined, which colorizeJson cannot tokenize
|
|
83
|
+
const output = result ?? null;
|
|
84
|
+
if (json) {
|
|
85
|
+
this.logJson(output);
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
this.log(colorizeJson(output));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//# sourceMappingURL=query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/commands/context/query.ts"],"sourcesContent":["import {Args, Flags} from '@oclif/core'\nimport {type FlagInput} from '@oclif/core/interfaces'\nimport {colorizeJson, exitCodes, SanityCommand, subdebug} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {isRecord} from '@sanity/cli-core/util'\n\nimport {\n MissingOrganizationError,\n resolveOrganizationId,\n} from '../../actions/context/resolveOrganizationId.js'\nimport {queryContext} from '../../services/context.js'\nimport {getOrganizationFlag} from '../../util/sharedFlags.js'\nimport {defineCommandTelemetry} from '../../util/telemetry/commandTelemetry.js'\n\nconst queryContextDebug = subdebug('context:query')\n\nconst flags = {\n ...getOrganizationFlag({\n description: 'Organization to query',\n semantics: 'override',\n }),\n params: Flags.custom<Record<string, unknown>>({\n description: 'Query parameters as a JSON object',\n helpValue: '<json>',\n parse: async (input: string) => {\n let parsed: unknown\n try {\n parsed = JSON.parse(input)\n } catch {\n throw new Error('`--params` must be valid JSON')\n }\n if (!isRecord(parsed)) {\n throw new Error('`--params` must be a JSON object, like \\'{\"type\": \"issue\"}\\'')\n }\n return parsed\n },\n })(),\n} satisfies FlagInput\n\nexport class QueryContextCommand extends SanityCommand<typeof QueryContextCommand> {\n static override args = {\n query: Args.string({\n description: \"GROQ query to run against the organization's Context documents\",\n required: true,\n }),\n }\n\n static override description = \"Query an organization's Context documents with GROQ\"\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"sanity.context.issue\" && status == \"open\"]{_id, knowledgeBaseId}\\'',\n description: 'List open issues across all knowledge bases',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> \\'*[_type == \"sanity.context.entry\" && knowledgeBaseId == $kb].path\\' --params \\'{\"kb\": \"kb-abc123\"}\\' --json',\n description: 'List the entry paths of one knowledge base as plain JSON',\n },\n ]\n\n static override flags = flags\n\n static telemetry = defineCommandTelemetry(flags, {redact: ['params']})\n\n public async run(): Promise<void> {\n const {query} = this.args\n const {json, organization, params} = this.flags\n\n let organizationId: string\n try {\n organizationId = await resolveOrganizationId({\n configuredOrganizationId: (await this.tryGetCliConfig()).app?.organizationId,\n flagOrganizationId: organization,\n unattended: this.isUnattended(),\n })\n } catch (error) {\n queryContextDebug('Error resolving organization', error)\n this.error(getErrorMessage(error), {\n exit:\n error instanceof MissingOrganizationError\n ? exitCodes.USAGE_ERROR\n : exitCodes.RUNTIME_ERROR,\n })\n }\n\n let result\n try {\n result = await queryContext(organizationId, query, params)\n } catch (error) {\n queryContextDebug('Error running query', error)\n this.error(`Failed to run query: ${getErrorMessage(error)}`, {\n exit: exitCodes.RUNTIME_ERROR,\n })\n }\n\n // GROQ returns null for no match; guard undefined, which colorizeJson cannot tokenize\n const output = result ?? null\n if (json) {\n this.logJson(output)\n return\n }\n\n this.log(colorizeJson(output))\n }\n}\n"],"names":["Args","Flags","colorizeJson","exitCodes","SanityCommand","subdebug","getErrorMessage","isRecord","MissingOrganizationError","resolveOrganizationId","queryContext","getOrganizationFlag","defineCommandTelemetry","queryContextDebug","flags","description","semantics","params","custom","helpValue","parse","input","parsed","JSON","Error","QueryContextCommand","args","query","string","required","enableJsonFlag","examples","command","telemetry","redact","run","json","organization","organizationId","configuredOrganizationId","tryGetCliConfig","app","flagOrganizationId","unattended","isUnattended","error","exit","USAGE_ERROR","RUNTIME_ERROR","result","output","logJson","log"],"mappings":"AAAA,SAAQA,IAAI,EAAEC,KAAK,QAAO,cAAa;AAEvC,SAAQC,YAAY,EAAEC,SAAS,EAAEC,aAAa,EAAEC,QAAQ,QAAO,mBAAkB;AACjF,SAAQC,eAAe,QAAO,0BAAyB;AACvD,SAAQC,QAAQ,QAAO,wBAAuB;AAE9C,SACEC,wBAAwB,EACxBC,qBAAqB,QAChB,iDAAgD;AACvD,SAAQC,YAAY,QAAO,4BAA2B;AACtD,SAAQC,mBAAmB,QAAO,4BAA2B;AAC7D,SAAQC,sBAAsB,QAAO,2CAA0C;AAE/E,MAAMC,oBAAoBR,SAAS;AAEnC,MAAMS,QAAQ;IACZ,GAAGH,oBAAoB;QACrBI,aAAa;QACbC,WAAW;IACb,EAAE;IACFC,QAAQhB,MAAMiB,MAAM,CAA0B;QAC5CH,aAAa;QACbI,WAAW;QACXC,OAAO,OAAOC;YACZ,IAAIC;YACJ,IAAI;gBACFA,SAASC,KAAKH,KAAK,CAACC;YACtB,EAAE,OAAM;gBACN,MAAM,IAAIG,MAAM;YAClB;YACA,IAAI,CAACjB,SAASe,SAAS;gBACrB,MAAM,IAAIE,MAAM;YAClB;YACA,OAAOF;QACT;IACF;AACF;AAEA,OAAO,MAAMG,4BAA4BrB;IACvC,OAAgBsB,OAAO;QACrBC,OAAO3B,KAAK4B,MAAM,CAAC;YACjBb,aAAa;YACbc,UAAU;QACZ;IACF,EAAC;IAED,OAAgBd,cAAc,sDAAqD;IAEnF,OAAgBe,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SACE;YACFjB,aAAa;QACf;QACA;YACEiB,SACE;YACFjB,aAAa;QACf;KACD,CAAA;IAED,OAAgBD,QAAQA,MAAK;IAE7B,OAAOmB,YAAYrB,uBAAuBE,OAAO;QAACoB,QAAQ;YAAC;SAAS;IAAA,GAAE;IAEtE,MAAaC,MAAqB;QAChC,MAAM,EAACR,KAAK,EAAC,GAAG,IAAI,CAACD,IAAI;QACzB,MAAM,EAACU,IAAI,EAAEC,YAAY,EAAEpB,MAAM,EAAC,GAAG,IAAI,CAACH,KAAK;QAE/C,IAAIwB;QACJ,IAAI;YACFA,iBAAiB,MAAM7B,sBAAsB;gBAC3C8B,0BAA0B,AAAC,CAAA,MAAM,IAAI,CAACC,eAAe,EAAC,EAAGC,GAAG,EAAEH;gBAC9DI,oBAAoBL;gBACpBM,YAAY,IAAI,CAACC,YAAY;YAC/B;QACF,EAAE,OAAOC,OAAO;YACdhC,kBAAkB,gCAAgCgC;YAClD,IAAI,CAACA,KAAK,CAACvC,gBAAgBuC,QAAQ;gBACjCC,MACED,iBAAiBrC,2BACbL,UAAU4C,WAAW,GACrB5C,UAAU6C,aAAa;YAC/B;QACF;QAEA,IAAIC;QACJ,IAAI;YACFA,SAAS,MAAMvC,aAAa4B,gBAAgBX,OAAOV;QACrD,EAAE,OAAO4B,OAAO;YACdhC,kBAAkB,uBAAuBgC;YACzC,IAAI,CAACA,KAAK,CAAC,CAAC,qBAAqB,EAAEvC,gBAAgBuC,QAAQ,EAAE;gBAC3DC,MAAM3C,UAAU6C,aAAa;YAC/B;QACF;QAEA,sFAAsF;QACtF,MAAME,SAASD,UAAU;QACzB,IAAIb,MAAM;YACR,IAAI,CAACe,OAAO,CAACD;YACb;QACF;QAEA,IAAI,CAACE,GAAG,CAAClD,aAAagD;IACxB;AACF"}
|
package/dist/commands/deploy.js
CHANGED
|
@@ -86,6 +86,12 @@ export class DeployCommand extends SanityCommand {
|
|
|
86
86
|
default: false,
|
|
87
87
|
description: 'Output the result as JSON'
|
|
88
88
|
}),
|
|
89
|
+
'media-library-id': Flags.string({
|
|
90
|
+
description: 'For a Media Library config deploy: the media library to sync the aspect definitions to. Defaults to the single active library of the configured organization; required when the organization has several',
|
|
91
|
+
// Part of the beta config-app flow, like the hidden media commands it
|
|
92
|
+
// pairs with. A help-listed flag is hard to take back — unhide at GA.
|
|
93
|
+
hidden: true
|
|
94
|
+
}),
|
|
89
95
|
minify: Flags.boolean({
|
|
90
96
|
allowNo: true,
|
|
91
97
|
default: true,
|
|
@@ -120,6 +126,13 @@ export class DeployCommand extends SanityCommand {
|
|
|
120
126
|
const cliConfig = await this.getCliConfig();
|
|
121
127
|
const projectRoot = await this.getProjectRoot();
|
|
122
128
|
const isApp = determineIsApp(cliConfig);
|
|
129
|
+
// `--media-library-id` only steers the aspect-document sync of a Media
|
|
130
|
+
// Library config deploy (see deployApp); studio and app deploys never read
|
|
131
|
+
// it. Warned rather than silently dropped (same courtesy init gives
|
|
132
|
+
// --dashboard on the media template).
|
|
133
|
+
if (flags['media-library-id'] && !resolveWorkbenchConfig(cliConfig)) {
|
|
134
|
+
this.output.warn('--media-library-id is ignored — it only applies when deploying a Media Library config');
|
|
135
|
+
}
|
|
123
136
|
if (flags.create) {
|
|
124
137
|
if (!isApp) {
|
|
125
138
|
return this.output.error('--create is only supported for App SDK apps. For a studio, use --url <hostname>.');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {getWorkbench, resolveWorkbenchConfig} from '@sanity/workbench-cli/deploy'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {getAppId} from '../util/appId.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external --url https://apps.example.com',\n description: 'Register an externally hosted studio, served from the provided origin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --yes --json',\n description:\n 'Create and deploy an App SDK app without prompts. Save application.id as deployment.appId, then omit --create on later deploys',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --dry-run --json',\n description: 'Preview a new App SDK deployment without creating or uploading anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --url my-studio --yes',\n description: 'Deploy a studio without prompts using its hostname',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n create: Flags.boolean({\n description: 'Create a new App SDK app, even if the organization has other apps',\n exclusive: ['external', 'url'],\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be deployed without uploading or creating anything',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify'],\n }),\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output the result as JSON',\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n title: Flags.string({\n description:\n 'Title for a newly created application or studio. For apps, use --create to select creation when the organization already has apps',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external deploys, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n if (flags.create) {\n if (!isApp) {\n return this.output.error(\n '--create is only supported for App SDK apps. For a studio, use --url <hostname>.',\n )\n }\n if (getAppId(cliConfig)) {\n return this.output.error(\n '--create cannot be used with a configured app ID. Omit --create to deploy to that app, or remove deployment.appId and app.id to create a new one.',\n )\n }\n if (getWorkbench(cliConfig) || resolveWorkbenchConfig(cliConfig)) {\n return this.output.error(\n '--create is not supported for this app configuration. Omit --create and run sanity deploy.',\n )\n }\n }\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n if (!this.isUnattended() && !flags['dry-run']) {\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // Keep --json's stdout clean for the payload\n if (!flags.json) this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n // Force yes downstream: build/app resolution otherwise prompts for prerelease/version choices\n const deployFlags = this.isUnattended() || flags['dry-run'] ? {...flags, yes: true} : flags\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","exitCodes","SanityCommand","confirm","getWorkbench","resolveWorkbenchConfig","deployApp","deployDebug","deployStudio","getAppId","determineIsApp","dirIsEmptyOrNonExistent","DeployCommand","args","sourceDir","directory","description","enableJsonFlag","examples","command","flags","boolean","allowNo","deprecated","build","default","create","exclusive","external","json","char","minify","title","string","url","verbose","yes","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","output","error","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isUnattended","isEmpty","shouldProceed","message","exit","RUNTIME_ERROR","log","deployFlags"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SAAQC,IAAI,EAAEC,KAAK,QAAO,cAAa;AACvC,SAAQC,SAAS,EAAEC,aAAa,QAAO,mBAAkB;AACzD,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,YAAY,EAAEC,sBAAsB,QAAO,+BAA8B;AAEjF,SAAQC,SAAS,QAAO,iCAAgC;AACxD,SAAQC,WAAW,QAAO,mCAAkC;AAC5D,SAAQC,YAAY,QAAO,oCAAmC;AAC9D,SAAQC,QAAQ,QAAO,mBAAkB;AACzC,SAAQC,cAAc,QAAO,4BAA2B;AACxD,SAAQC,uBAAuB,QAAO,qCAAoC;AAE1E,OAAO,MAAMC,sBAAsBV;IACjC,OAAgBW,OAAO;QACrBC,WAAWf,KAAKgB,SAAS,CAAC;YACxBC,aAAa;QACf;IACF,EAAC;IAED,OAAgBA,cAAc,oEAAmE;IAEjG,OAAgBC,iBAAiB,KAAI;IAErC,OAAgBC,WAAW;QACzB;YACEC,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aACE;QACJ;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aACE;QACJ;QACA;YACEG,SAAS;YACTH,aAAa;QACf;QACA;YACEG,SAAS;YACTH,aAAa;QACf;KACD,CAAA;IAED,OAAgBI,QAAQ;QACtB,gBAAgBpB,MAAMqB,OAAO,CAAC;YAC5BC,SAAS;YACTC,YAAY;YACZP,aAAa;QACf;QACAQ,OAAOxB,MAAMqB,OAAO,CAAC;YACnBC,SAAS;YACTG,SAAS;YACTT,aACE;QACJ;QACAU,QAAQ1B,MAAMqB,OAAO,CAAC;YACpBL,aAAa;YACbW,WAAW;gBAAC;gBAAY;aAAM;QAChC;QACA,WAAW3B,MAAMqB,OAAO,CAAC;YACvBI,SAAS;YACTT,aAAa;QACf;QACAY,UAAU5B,MAAMqB,OAAO,CAAC;YACtBI,SAAS;YACTT,aAAa;YACbW,WAAW;gBAAC;gBAAe;aAAS;QACtC;QACAE,MAAM7B,MAAMqB,OAAO,CAAC;YAClBS,MAAM;YACNL,SAAS;YACTT,aAAa;QACf;QACAe,QAAQ/B,MAAMqB,OAAO,CAAC;YACpBC,SAAS;YACTG,SAAS;YACTT,aAAa;QACf;QACA,mBAAmBhB,MAAMqB,OAAO,CAAC;YAC/BI,SAAS;YACTT,aAAa;QACf;QACA,eAAehB,MAAMqB,OAAO,CAAC;YAC3BI,SAAS;YACTT,aAAa;QACf;QACAgB,OAAOhC,MAAMiC,MAAM,CAAC;YAClBjB,aACE;QACJ;QACAkB,KAAKlC,MAAMiC,MAAM,CAAC;YAChBjB,aACE;QACJ;QACAmB,SAASnC,MAAMqB,OAAO,CAAC;YACrBI,SAAS;YACTT,aAAa;QACf;QACAoB,KAAKpC,MAAMqB,OAAO,CAAC;YACjBS,MAAM;YACNL,SAAS;YACTT,aACE;QACJ;IACF,EAAC;IAED,MAAaqB,MAAqB;QAChC,MAAM,EAACjB,KAAK,EAAC,GAAG,MAAM,IAAI,CAACkB,KAAK,CAAC1B;QAEjC,MAAM2B,YAAY,MAAM,IAAI,CAACC,YAAY;QACzC,MAAMC,cAAc,MAAM,IAAI,CAACC,cAAc;QAE7C,MAAMC,QAAQjC,eAAe6B;QAE7B,IAAInB,MAAMM,MAAM,EAAE;YAChB,IAAI,CAACiB,OAAO;gBACV,OAAO,IAAI,CAACC,MAAM,CAACC,KAAK,CACtB;YAEJ;YACA,IAAIpC,SAAS8B,YAAY;gBACvB,OAAO,IAAI,CAACK,MAAM,CAACC,KAAK,CACtB;YAEJ;YACA,IAAIzC,aAAamC,cAAclC,uBAAuBkC,YAAY;gBAChE,OAAO,IAAI,CAACK,MAAM,CAACC,KAAK,CACtB;YAEJ;QACF;QAEA,MAAMC,mBAAmBhD,KAAKiD,OAAO,CAACjD,KAAKkD,IAAI,CAACP,YAAY1B,SAAS,EAAE;QACvE,MAAMD,YAAYhB,KAAKiD,OAAO,CAACE,QAAQC,GAAG,IAAI,IAAI,CAACrC,IAAI,CAACC,SAAS,IAAIgC;QAErE,8DAA8D;QAC9D,IAAI,IAAI,CAACjC,IAAI,CAACC,SAAS,IAAI,IAAI,CAACD,IAAI,CAACC,SAAS,KAAK,UAAU,CAACM,MAAMQ,QAAQ,EAAE;YAC5E,IAAIuB,iBAAiBrD,KAAKsD,QAAQ,CAACH,QAAQC,GAAG,IAAIpC;YAClD,IAAIqC,cAAc,CAAC,EAAE,KAAK,KAAK;gBAC7BA,iBAAiB,CAAC,EAAE,EAAEA,gBAAgB;YACxC;YAEA,IAAI,CAAC,IAAI,CAACE,YAAY,MAAM,CAACjC,KAAK,CAAC,UAAU,EAAE;gBAC7C,MAAMkC,UAAU,MAAM3C,wBAAwBG;gBAC9C,MAAMyC,gBACJD,WACC,MAAMnD,QAAQ;oBACbsB,SAAS;oBACT+B,SAAS,CAAC,CAAC,EAAEL,eAAe,uCAAuC,CAAC;gBACtE;gBAEF,IAAI,CAACI,eAAe;oBAClB,IAAI,CAACX,MAAM,CAACC,KAAK,CAAC,cAAc;wBAACY,MAAMxD,UAAUyD,aAAa;oBAAA;gBAChE;YACF;YAEA,6CAA6C;YAC7C,IAAI,CAACtC,MAAMS,IAAI,EAAE,IAAI,CAACe,MAAM,CAACe,GAAG,CAAC,CAAC,YAAY,EAAER,eAAe,EAAE,CAAC;QACpE;QAEA,8FAA8F;QAC9F,MAAMS,cAAc,IAAI,CAACP,YAAY,MAAMjC,KAAK,CAAC,UAAU,GAAG;YAAC,GAAGA,KAAK;YAAEgB,KAAK;QAAI,IAAIhB;QAEtF,IAAIuB,OAAO;YACTpC,YAAY;YACZ,MAAMD,UAAU;gBACdiC;gBACAnB,OAAOwC;gBACPhB,QAAQ,IAAI,CAACA,MAAM;gBACnBH;gBACA3B;YACF;QACF,OAAO;YACLP,YAAY;YACZ,MAAMC,aAAa;gBACjB+B;gBACAnB,OAAOwC;gBACPhB,QAAQ,IAAI,CAACA,MAAM;gBACnBH;gBACA3B;YACF;QACF;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {Args, Flags} from '@oclif/core'\nimport {exitCodes, SanityCommand} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {getWorkbench, resolveWorkbenchConfig} from '@sanity/workbench-cli/deploy'\n\nimport {deployApp} from '../actions/deploy/deployApp.js'\nimport {deployDebug} from '../actions/deploy/deployDebug.js'\nimport {deployStudio} from '../actions/deploy/deployStudio.js'\nimport {getAppId} from '../util/appId.js'\nimport {determineIsApp} from '../util/determineIsApp.js'\nimport {dirIsEmptyOrNonExistent} from '../util/dirIsEmptyOrNonExistent.js'\n\nexport class DeployCommand extends SanityCommand<typeof DeployCommand> {\n static override args = {\n sourceDir: Args.directory({\n description: 'Source directory',\n }),\n }\n\n static override description = 'Builds and deploys Sanity Studio or application to Sanity hosting'\n\n static override enableJsonFlag = true\n\n static override examples = [\n {\n command: '<%= config.bin %> <%= command.id %>',\n description: 'Build and deploy the studio to Sanity hosting',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --no-minify --source-maps',\n description: 'Deploys non-minified build with source maps',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --schema-required',\n description:\n 'Fail fast on schema store fails - for when other services rely on the stored schema',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external',\n description: 'Register an externally hosted studio (studioHost contains full URL)',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --external --url https://apps.example.com',\n description: 'Register an externally hosted studio, served from the provided origin',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --yes --json',\n description:\n 'Create and deploy an App SDK app without prompts. Save application.id as deployment.appId, then omit --create on later deploys',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --create --title \"My App\" --dry-run --json',\n description: 'Preview a new App SDK deployment without creating or uploading anything',\n },\n {\n command: '<%= config.bin %> <%= command.id %> --url my-studio --yes',\n description: 'Deploy a studio without prompts using its hostname',\n },\n ]\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n deprecated: true,\n description: 'Automatically update the studio to the latest version',\n }),\n build: Flags.boolean({\n allowNo: true,\n default: true,\n description:\n 'Build the studio before deploying (use --no-build to deploy existing `dist/` output)',\n }),\n create: Flags.boolean({\n description: 'Create a new App SDK app, even if the organization has other apps',\n exclusive: ['external', 'url'],\n }),\n 'dry-run': Flags.boolean({\n default: false,\n description: 'Report what would be deployed without uploading or creating anything',\n }),\n external: Flags.boolean({\n default: false,\n description: 'Register an externally hosted studio',\n exclusive: ['source-maps', 'minify'],\n }),\n json: Flags.boolean({\n char: 'j',\n default: false,\n description: 'Output the result as JSON',\n }),\n 'media-library-id': Flags.string({\n description:\n 'For a Media Library config deploy: the media library to sync the aspect definitions to. Defaults to the single active library of the configured organization; required when the organization has several',\n // Part of the beta config-app flow, like the hidden media commands it\n // pairs with. A help-listed flag is hard to take back — unhide at GA.\n hidden: true,\n }),\n minify: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Minify built JavaScript (use --no-minify to skip for faster builds)',\n }),\n 'schema-required': Flags.boolean({\n default: false,\n description: 'Fail if schema deployment fails',\n }),\n 'source-maps': Flags.boolean({\n default: false,\n description: 'Enable source maps for built bundles (increases size of bundle)',\n }),\n title: Flags.string({\n description:\n 'Title for a newly created application or studio. For apps, use --create to select creation when the organization already has apps',\n }),\n url: Flags.string({\n description:\n 'Studio URL for deployment. For external deploys, the full URL. For hosted studios, the hostname (e.g. \"my-studio\" or \"my-studio.sanity.studio\")',\n }),\n verbose: Flags.boolean({\n default: false,\n description: 'Enable verbose logging',\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n const {flags} = await this.parse(DeployCommand)\n\n const cliConfig = await this.getCliConfig()\n const projectRoot = await this.getProjectRoot()\n\n const isApp = determineIsApp(cliConfig)\n\n // `--media-library-id` only steers the aspect-document sync of a Media\n // Library config deploy (see deployApp); studio and app deploys never read\n // it. Warned rather than silently dropped (same courtesy init gives\n // --dashboard on the media template).\n if (flags['media-library-id'] && !resolveWorkbenchConfig(cliConfig)) {\n this.output.warn(\n '--media-library-id is ignored — it only applies when deploying a Media Library config',\n )\n }\n\n if (flags.create) {\n if (!isApp) {\n return this.output.error(\n '--create is only supported for App SDK apps. For a studio, use --url <hostname>.',\n )\n }\n if (getAppId(cliConfig)) {\n return this.output.error(\n '--create cannot be used with a configured app ID. Omit --create to deploy to that app, or remove deployment.appId and app.id to create a new one.',\n )\n }\n if (getWorkbench(cliConfig) || resolveWorkbenchConfig(cliConfig)) {\n return this.output.error(\n '--create is not supported for this app configuration. Omit --create and run sanity deploy.',\n )\n }\n }\n\n const defaultOutputDir = path.resolve(path.join(projectRoot.directory, 'dist'))\n const sourceDir = path.resolve(process.cwd(), this.args.sourceDir || defaultOutputDir)\n\n // Skip the directory check if the studio is externally hosted\n if (this.args.sourceDir && this.args.sourceDir !== 'dist' && !flags.external) {\n let relativeOutput = path.relative(process.cwd(), sourceDir)\n if (relativeOutput[0] !== '.') {\n relativeOutput = `./${relativeOutput}`\n }\n\n if (!this.isUnattended() && !flags['dry-run']) {\n const isEmpty = await dirIsEmptyOrNonExistent(sourceDir)\n const shouldProceed =\n isEmpty ||\n (await confirm({\n default: false,\n message: `\"${relativeOutput}\" is not empty, do you want to proceed?`,\n }))\n\n if (!shouldProceed) {\n this.output.error('Cancelled.', {exit: exitCodes.RUNTIME_ERROR})\n }\n }\n\n // Keep --json's stdout clean for the payload\n if (!flags.json) this.output.log(`Building to ${relativeOutput}\\n`)\n }\n\n // Force yes downstream: build/app resolution otherwise prompts for prerelease/version choices\n const deployFlags = this.isUnattended() || flags['dry-run'] ? {...flags, yes: true} : flags\n\n if (isApp) {\n deployDebug('Deploying app')\n await deployApp({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n } else {\n deployDebug('Deploying studio')\n await deployStudio({\n cliConfig,\n flags: deployFlags,\n output: this.output,\n projectRoot,\n sourceDir,\n })\n }\n }\n}\n"],"names":["path","Args","Flags","exitCodes","SanityCommand","confirm","getWorkbench","resolveWorkbenchConfig","deployApp","deployDebug","deployStudio","getAppId","determineIsApp","dirIsEmptyOrNonExistent","DeployCommand","args","sourceDir","directory","description","enableJsonFlag","examples","command","flags","boolean","allowNo","deprecated","build","default","create","exclusive","external","json","char","string","hidden","minify","title","url","verbose","yes","run","parse","cliConfig","getCliConfig","projectRoot","getProjectRoot","isApp","output","warn","error","defaultOutputDir","resolve","join","process","cwd","relativeOutput","relative","isUnattended","isEmpty","shouldProceed","message","exit","RUNTIME_ERROR","log","deployFlags"],"mappings":"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"}
|