@sanity/runtime-cli 17.7.1 → 17.8.0-blueprinit.g0993fa5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -21
- package/dist/actions/blueprinit/manifest.d.ts +34 -0
- package/dist/actions/blueprinit/manifest.js +107 -0
- package/dist/actions/blueprinit/studio.d.ts +6 -0
- package/dist/actions/blueprinit/studio.js +43 -0
- package/dist/actions/blueprinit/templates.d.ts +73 -0
- package/dist/actions/blueprinit/templates.js +138 -0
- package/dist/actions/blueprinit/workspace.d.ts +24 -0
- package/dist/actions/blueprinit/workspace.js +146 -0
- package/dist/actions/blueprints/stacks.d.ts +2 -0
- package/dist/actions/blueprints/stacks.js +1 -0
- package/dist/actions/sanity/datasets.d.ts +15 -0
- package/dist/actions/sanity/datasets.js +26 -0
- package/dist/actions/sanity/projects.d.ts +11 -0
- package/dist/actions/sanity/projects.js +48 -22
- package/dist/baseCommands.d.ts +6 -0
- package/dist/baseCommands.js +9 -1
- package/dist/commands/blueprints/stacks.d.ts +2 -1
- package/dist/commands/blueprints/stacks.js +14 -6
- package/dist/commands/init.d.ts +20 -0
- package/dist/commands/init.js +72 -0
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +5 -0
- package/dist/cores/blueprinit/adopt.d.ts +6 -0
- package/dist/cores/blueprinit/adopt.js +154 -0
- package/dist/cores/blueprinit/finish.d.ts +15 -0
- package/dist/cores/blueprinit/finish.js +73 -0
- package/dist/cores/blueprinit/fresh.d.ts +3 -0
- package/dist/cores/blueprinit/fresh.js +173 -0
- package/dist/cores/blueprinit/preview.d.ts +24 -0
- package/dist/cores/blueprinit/preview.js +97 -0
- package/dist/cores/blueprinit/prompts.d.ts +15 -0
- package/dist/cores/blueprinit/prompts.js +43 -0
- package/dist/cores/blueprinit/selection.d.ts +15 -0
- package/dist/cores/blueprinit/selection.js +90 -0
- package/dist/cores/blueprinit/stack-name.d.ts +39 -0
- package/dist/cores/blueprinit/stack-name.js +56 -0
- package/dist/cores/blueprinit/target.d.ts +33 -0
- package/dist/cores/blueprinit/target.js +80 -0
- package/dist/cores/blueprinit/types.d.ts +18 -0
- package/dist/cores/blueprinit/types.js +1 -0
- package/dist/cores/blueprinit.d.ts +7 -0
- package/dist/cores/blueprinit.js +55 -0
- package/dist/cores/blueprints/stacks.d.ts +8 -3
- package/dist/cores/blueprints/stacks.js +282 -85
- package/dist/cores/functions/test.d.ts +2 -19
- package/dist/cores/functions/test.js +55 -111
- package/dist/server/app.js +4 -6
- package/dist/server/static/components/payload-panel.js +1 -1
- package/dist/utils/display/intro.d.ts +6 -0
- package/dist/utils/display/intro.js +63 -0
- package/dist/utils/display/prompt.d.ts +4 -1
- package/dist/utils/display/prompt.js +16 -2
- package/dist/utils/external/npmjs.d.ts +7 -0
- package/dist/utils/external/npmjs.js +10 -0
- package/dist/utils/functions/child-process-wrapper.js +18 -6
- package/dist/utils/functions/child-runtime/durable.d.ts +18 -0
- package/dist/utils/functions/child-runtime/durable.js +46 -0
- package/dist/utils/functions/invoke/local.js +26 -9
- package/dist/utils/functions/invoke/resolve-invoke-type.d.ts +51 -0
- package/dist/utils/functions/invoke/resolve-invoke-type.js +131 -0
- package/dist/utils/progress.js +6 -3
- package/dist/utils/types.d.ts +46 -2
- package/oclif.manifest.json +155 -5
- package/package.json +1 -1
- package/skills/blueprints-stacks.md +14 -2
- package/skills/init.md +170 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join, posix } from 'node:path';
|
|
3
|
+
import { renderBlueprint, STARTER_FUNCTION_NAME } from './manifest.js';
|
|
4
|
+
import { FUNCTION_SET_SLUG, functionPackageJson, renderStudioCliConfig, renderStudioConfig, STUDIO_POST_TYPE, STUDIO_SCHEMA_TYPES, STUDIO_TSCONFIG, studioPackageJson, } from './templates.js';
|
|
5
|
+
const GITIGNORE_ENTRY = '# Sanity Blueprints\n.sanity/';
|
|
6
|
+
const DEFAULT_GITIGNORE = `node_modules
|
|
7
|
+
.env
|
|
8
|
+
|
|
9
|
+
${GITIGNORE_ENTRY}
|
|
10
|
+
`;
|
|
11
|
+
export function scaffoldWorkspace(options) {
|
|
12
|
+
const { dir, studioName, studioVersions } = options;
|
|
13
|
+
assertTargetsAvailable(dir, [
|
|
14
|
+
posix.join('studios', studioName),
|
|
15
|
+
posix.join('functions', STARTER_FUNCTION_NAME),
|
|
16
|
+
]);
|
|
17
|
+
const packageJson = preparePackageJson(options, ['studios/*', 'functions/*']);
|
|
18
|
+
const files = [];
|
|
19
|
+
const write = createWriter(dir, files);
|
|
20
|
+
const blueprintFilePath = write('sanity.blueprint.ts', renderBlueprint({
|
|
21
|
+
...manifestOptions(options),
|
|
22
|
+
studioSrc: `./studios/${studioName}`,
|
|
23
|
+
withFunction: true,
|
|
24
|
+
}));
|
|
25
|
+
write(posix.join('studios', studioName, 'package.json'), formatJson(studioPackageJson(studioName, studioVersions)));
|
|
26
|
+
write(posix.join('studios', studioName, 'tsconfig.json'), formatJson(STUDIO_TSCONFIG));
|
|
27
|
+
write(posix.join('studios', studioName, 'sanity.config.ts'), renderStudioConfig(options));
|
|
28
|
+
write(posix.join('studios', studioName, 'sanity.cli.ts'), renderStudioCliConfig(options));
|
|
29
|
+
write(posix.join('studios', studioName, 'schemaTypes', 'index.ts'), STUDIO_SCHEMA_TYPES);
|
|
30
|
+
write(posix.join('studios', studioName, 'schemaTypes', 'post.ts'), STUDIO_POST_TYPE);
|
|
31
|
+
write(posix.join('studios', studioName, 'static', '.gitkeep'), '');
|
|
32
|
+
write(posix.join('functions', STARTER_FUNCTION_NAME, 'package.json'), formatJson(functionPackageJson(STARTER_FUNCTION_NAME)));
|
|
33
|
+
write(posix.join('functions', STARTER_FUNCTION_NAME, 'index.ts'), FUNCTION_SET_SLUG);
|
|
34
|
+
writePreparedRootFiles(dir, packageJson, files);
|
|
35
|
+
return { blueprintFilePath, files };
|
|
36
|
+
}
|
|
37
|
+
export function adoptWorkspace(options) {
|
|
38
|
+
const { dir } = options;
|
|
39
|
+
const packageJson = preparePackageJson(options, []);
|
|
40
|
+
const files = [];
|
|
41
|
+
const write = createWriter(dir, files);
|
|
42
|
+
const blueprintFilePath = write('sanity.blueprint.ts', renderBlueprint({ ...manifestOptions(options), studioSrc: '.', withFunction: false }));
|
|
43
|
+
writePreparedRootFiles(dir, packageJson, files);
|
|
44
|
+
return { blueprintFilePath, files };
|
|
45
|
+
}
|
|
46
|
+
function manifestOptions(options) {
|
|
47
|
+
return {
|
|
48
|
+
projectName: options.projectName,
|
|
49
|
+
displayName: options.displayName,
|
|
50
|
+
projectId: options.projectId,
|
|
51
|
+
datasetName: options.datasetName,
|
|
52
|
+
studioName: options.studioName,
|
|
53
|
+
studioSlug: options.studioSlug,
|
|
54
|
+
studioOrigin: options.studioOrigin,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function assertTargetsAvailable(dir, paths) {
|
|
58
|
+
const conflicts = paths.filter((path) => existsSync(join(dir, path)));
|
|
59
|
+
if (conflicts.length > 0) {
|
|
60
|
+
throw new Error(`Refusing to overwrite existing paths: ${conflicts.join(', ')}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function createWriter(dir, files) {
|
|
64
|
+
return (relativePath, content) => {
|
|
65
|
+
const filePath = join(dir, relativePath);
|
|
66
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
67
|
+
writeFileSync(filePath, content);
|
|
68
|
+
files.push(relativePath);
|
|
69
|
+
return filePath;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function writePreparedRootFiles(dir, packageJson, files) {
|
|
73
|
+
if (writeGitignore(dir))
|
|
74
|
+
files.push('.gitignore');
|
|
75
|
+
writeFileSync(join(dir, 'package.json'), formatJson(packageJson));
|
|
76
|
+
files.push('package.json');
|
|
77
|
+
}
|
|
78
|
+
function writeGitignore(dir) {
|
|
79
|
+
const filePath = join(dir, '.gitignore');
|
|
80
|
+
if (!existsSync(filePath)) {
|
|
81
|
+
writeFileSync(filePath, DEFAULT_GITIGNORE);
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
const existing = readFileSync(filePath, 'utf8');
|
|
85
|
+
if (existing.split(/\r?\n/).some((line) => line.trim() === '.sanity/'))
|
|
86
|
+
return false;
|
|
87
|
+
writeFileSync(filePath, `${existing.trimEnd()}\n\n${GITIGNORE_ENTRY}\n`);
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
function preparePackageJson(options, requiredWorkspaces) {
|
|
91
|
+
const filePath = join(options.dir, 'package.json');
|
|
92
|
+
const parsed = existsSync(filePath)
|
|
93
|
+
? JSON.parse(readFileSync(filePath, 'utf8'))
|
|
94
|
+
: {
|
|
95
|
+
name: options.stackName,
|
|
96
|
+
version: '0.1.0',
|
|
97
|
+
private: true,
|
|
98
|
+
type: 'module',
|
|
99
|
+
};
|
|
100
|
+
if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
|
|
101
|
+
throw new Error('The existing package.json must contain a JSON object.');
|
|
102
|
+
}
|
|
103
|
+
const packageJson = parsed;
|
|
104
|
+
addWorkspaces(packageJson, requiredWorkspaces);
|
|
105
|
+
addBlueprintsDependency(packageJson, options.blueprintsVersion);
|
|
106
|
+
return packageJson;
|
|
107
|
+
}
|
|
108
|
+
function addWorkspaces(packageJson, required) {
|
|
109
|
+
if (required.length === 0)
|
|
110
|
+
return;
|
|
111
|
+
if (!packageJson.workspaces) {
|
|
112
|
+
packageJson.workspaces = required;
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(packageJson.workspaces)) {
|
|
116
|
+
packageJson.workspaces = [...new Set([...packageJson.workspaces, ...required])];
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
if (!packageJson.workspaces || typeof packageJson.workspaces !== 'object') {
|
|
120
|
+
throw new Error('Cannot add generated packages to the existing package.json workspaces.');
|
|
121
|
+
}
|
|
122
|
+
const workspaces = packageJson.workspaces;
|
|
123
|
+
if (Array.isArray(workspaces.packages)) {
|
|
124
|
+
workspaces.packages = [...new Set([...workspaces.packages, ...required])];
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
throw new Error('Cannot add generated packages to the existing package.json workspaces.');
|
|
128
|
+
}
|
|
129
|
+
function addBlueprintsDependency(packageJson, blueprintsVersion) {
|
|
130
|
+
const dependencies = recordOrEmpty(packageJson.dependencies);
|
|
131
|
+
const devDependencies = recordOrEmpty(packageJson.devDependencies);
|
|
132
|
+
if (dependencies['@sanity/blueprints'] || devDependencies['@sanity/blueprints'])
|
|
133
|
+
return;
|
|
134
|
+
packageJson.devDependencies = {
|
|
135
|
+
...devDependencies,
|
|
136
|
+
'@sanity/blueprints': blueprintsVersion,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function recordOrEmpty(value) {
|
|
140
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
141
|
+
? value
|
|
142
|
+
: {};
|
|
143
|
+
}
|
|
144
|
+
function formatJson(value) {
|
|
145
|
+
return `${JSON.stringify(value, null, 2)}\n`;
|
|
146
|
+
}
|
|
@@ -6,10 +6,12 @@ type ListStacksResponse = {
|
|
|
6
6
|
ok: true;
|
|
7
7
|
error: null;
|
|
8
8
|
stacks: StackSummary[];
|
|
9
|
+
response?: Response;
|
|
9
10
|
} | {
|
|
10
11
|
ok: false;
|
|
11
12
|
error: string;
|
|
12
13
|
stacks?: unknown;
|
|
14
|
+
response?: Response;
|
|
13
15
|
};
|
|
14
16
|
export declare function listStacks(auth: AuthParams, logger: Logger): Promise<ListStacksResponse>;
|
|
15
17
|
type GetStackResponse = {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Logger } from '../../utils/logger.js';
|
|
2
|
+
import type { ActionResponse } from '../../utils/types.js';
|
|
3
|
+
export interface Dataset {
|
|
4
|
+
name: string;
|
|
5
|
+
aclMode: string;
|
|
6
|
+
}
|
|
7
|
+
interface ListDatasetsResponse extends ActionResponse {
|
|
8
|
+
datasets: Dataset[];
|
|
9
|
+
}
|
|
10
|
+
export declare function listDatasets({ token, projectId, logger, }: {
|
|
11
|
+
token: string;
|
|
12
|
+
projectId: string;
|
|
13
|
+
logger: Logger;
|
|
14
|
+
}): Promise<ListDatasetsResponse>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createTracedFetch } from '../../utils/traced-fetch.js';
|
|
2
|
+
import { projectsApiPath } from './projects.js';
|
|
3
|
+
export async function listDatasets({ token, projectId, logger, }) {
|
|
4
|
+
const fetchFn = createTracedFetch(logger);
|
|
5
|
+
const url = `${projectsApiPath}/${encodeURIComponent(projectId)}/datasets`;
|
|
6
|
+
const response = await fetchFn(url, {
|
|
7
|
+
method: 'GET',
|
|
8
|
+
headers: {
|
|
9
|
+
Authorization: `Bearer ${token}`,
|
|
10
|
+
'Content-Type': 'application/json',
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
const body = await response.json();
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
return {
|
|
16
|
+
ok: false,
|
|
17
|
+
error: body.error?.message ?? response.statusText,
|
|
18
|
+
datasets: [],
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
ok: true,
|
|
23
|
+
error: null,
|
|
24
|
+
datasets: body,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
@@ -22,6 +22,17 @@ export declare function listProjects({ token, organizationId, logger, }: {
|
|
|
22
22
|
organizationId?: string;
|
|
23
23
|
logger: Logger;
|
|
24
24
|
}): Promise<ListProjectsResponse>;
|
|
25
|
+
export interface Organization {
|
|
26
|
+
id: string;
|
|
27
|
+
name: string;
|
|
28
|
+
}
|
|
29
|
+
interface ListOrganizationsResponse extends ActionResponse {
|
|
30
|
+
organizations: Organization[];
|
|
31
|
+
}
|
|
32
|
+
export declare function listOrganizations({ token, logger, }: {
|
|
33
|
+
token: string;
|
|
34
|
+
logger: Logger;
|
|
35
|
+
}): Promise<ListOrganizationsResponse>;
|
|
25
36
|
interface GroupedProjectsByOrganizationResponse extends ActionResponse {
|
|
26
37
|
organizations: GroupedProjects[];
|
|
27
38
|
}
|
|
@@ -8,22 +8,52 @@ export async function listProjects({ token, organizationId, logger, }) {
|
|
|
8
8
|
const url = organizationId
|
|
9
9
|
? `${projectsApiPath}?organizationId=${encodeURIComponent(organizationId)}`
|
|
10
10
|
: projectsApiPath;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
11
|
+
try {
|
|
12
|
+
const projectsFetch = await fetchFn(url, {
|
|
13
|
+
method: 'GET',
|
|
14
|
+
headers: {
|
|
15
|
+
Authorization: `Bearer ${token}`,
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
const projects = await projectsFetch.json();
|
|
20
|
+
return {
|
|
21
|
+
ok: projectsFetch.ok,
|
|
22
|
+
error: projectsFetch.ok ? null : projects.error?.message,
|
|
23
|
+
projects,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
catch (error) {
|
|
27
|
+
return {
|
|
28
|
+
ok: false,
|
|
29
|
+
error: error instanceof Error ? error.message : String(error),
|
|
30
|
+
projects: [],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
24
33
|
}
|
|
25
|
-
export async function
|
|
34
|
+
export async function listOrganizations({ token, logger, }) {
|
|
26
35
|
const fetchFn = createTracedFetch(logger);
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetchFn(orgsApiPath, {
|
|
38
|
+
method: 'GET',
|
|
39
|
+
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
40
|
+
});
|
|
41
|
+
const organizations = await response.json();
|
|
42
|
+
return {
|
|
43
|
+
ok: response.ok,
|
|
44
|
+
error: response.ok ? null : organizations.error?.message,
|
|
45
|
+
organizations,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
error: error instanceof Error ? error.message : String(error),
|
|
52
|
+
organizations: [],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function groupProjectsByOrganization({ token, logger, }) {
|
|
27
57
|
const projectsResponse = await listProjects({ token, logger });
|
|
28
58
|
if (!projectsResponse.ok) {
|
|
29
59
|
return {
|
|
@@ -32,19 +62,15 @@ export async function groupProjectsByOrganization({ token, logger, }) {
|
|
|
32
62
|
organizations: [],
|
|
33
63
|
};
|
|
34
64
|
}
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
headers: { Authorization: `Bearer ${token}`, 'Content-Type': 'application/json' },
|
|
38
|
-
});
|
|
39
|
-
if (!orgsFetch.ok) {
|
|
65
|
+
const orgsResponse = await listOrganizations({ token, logger });
|
|
66
|
+
if (!orgsResponse.ok) {
|
|
40
67
|
return {
|
|
41
68
|
ok: false,
|
|
42
|
-
error:
|
|
69
|
+
error: orgsResponse.error,
|
|
43
70
|
organizations: [],
|
|
44
71
|
};
|
|
45
72
|
}
|
|
46
|
-
const
|
|
47
|
-
const orgsWithProjects = organizations.map(({ name, id }) => {
|
|
73
|
+
const orgsWithProjects = orgsResponse.organizations.map(({ name, id }) => {
|
|
48
74
|
const projects = projectsResponse.projects.filter((project) => project.organizationId === id);
|
|
49
75
|
return { organization: { name, id }, projects };
|
|
50
76
|
});
|
package/dist/baseCommands.d.ts
CHANGED
|
@@ -131,6 +131,12 @@ export declare abstract class ResolvedCommand<T extends typeof Command> extends
|
|
|
131
131
|
* populated regardless of `needs` and is never required
|
|
132
132
|
*/
|
|
133
133
|
protected resolvedStackId?: string;
|
|
134
|
+
/**
|
|
135
|
+
* locally-resolved scope (flags > env > module > config)
|
|
136
|
+
* populated regardless of `needs` and is never required
|
|
137
|
+
*/
|
|
138
|
+
protected resolvedScopeType?: ScopeType;
|
|
139
|
+
protected resolvedScopeId?: string;
|
|
134
140
|
/**
|
|
135
141
|
* the located `.sanity/blueprint.config.json` (if any), populated regardless of
|
|
136
142
|
* `needs`. Lets commands read/update local config without requiring a manifest.
|
package/dist/baseCommands.js
CHANGED
|
@@ -213,6 +213,12 @@ export class ResolvedCommand extends RuntimeCommand {
|
|
|
213
213
|
* populated regardless of `needs` and is never required
|
|
214
214
|
*/
|
|
215
215
|
resolvedStackId;
|
|
216
|
+
/**
|
|
217
|
+
* locally-resolved scope (flags > env > module > config)
|
|
218
|
+
* populated regardless of `needs` and is never required
|
|
219
|
+
*/
|
|
220
|
+
resolvedScopeType;
|
|
221
|
+
resolvedScopeId;
|
|
216
222
|
/**
|
|
217
223
|
* the located `.sanity/blueprint.config.json` (if any), populated regardless of
|
|
218
224
|
* `needs`. Lets commands read/update local config without requiring a manifest.
|
|
@@ -308,8 +314,10 @@ export class ResolvedCommand extends RuntimeCommand {
|
|
|
308
314
|
// assumption was wrong; leave stackId undefined
|
|
309
315
|
}
|
|
310
316
|
}
|
|
311
|
-
// Expose the resolved Stack ID regardless of `needs` (optional, for listings/highlighting)
|
|
317
|
+
// Expose the resolved Stack ID and scope regardless of `needs` (optional, for listings/highlighting)
|
|
312
318
|
this.resolvedStackId = resolved.stackId;
|
|
319
|
+
this.resolvedScopeType = resolved.scopeType;
|
|
320
|
+
this.resolvedScopeId = resolved.scopeId;
|
|
313
321
|
// Backfill resolved IDs onto the blueprint result if it was loaded
|
|
314
322
|
if (this.blueprint) {
|
|
315
323
|
Object.assign(this.blueprint, {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ResolvedCommand } from '../../baseCommands.js';
|
|
2
2
|
export default class StacksCommand extends ResolvedCommand<typeof StacksCommand> {
|
|
3
|
-
static needs: readonly ['
|
|
3
|
+
static needs: readonly ['token'];
|
|
4
4
|
static summary: string;
|
|
5
5
|
static description: string;
|
|
6
6
|
static examples: string[];
|
|
@@ -8,6 +8,7 @@ export default class StacksCommand extends ResolvedCommand<typeof StacksCommand>
|
|
|
8
8
|
'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
9
9
|
'organization-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
10
10
|
'include-projects': import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
all: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
12
|
};
|
|
12
13
|
run(): Promise<Record<string, unknown> | undefined>;
|
|
13
14
|
}
|
|
@@ -3,15 +3,16 @@ import { organizationIdFlagConfig, projectIdFlagConfig, ResolvedCommand } from '
|
|
|
3
3
|
import { blueprintStacksCore } from '../../cores/blueprints/stacks.js';
|
|
4
4
|
import { Logger } from '../../utils/logger.js';
|
|
5
5
|
export default class StacksCommand extends ResolvedCommand {
|
|
6
|
-
static needs = ['
|
|
6
|
+
static needs = ['token'];
|
|
7
7
|
static summary = 'List remote Stack deployments for your project or organization';
|
|
8
8
|
static description = `Shows all Stacks associated with a project or organization. By default, lists Stacks scoped to the local Blueprint.
|
|
9
9
|
|
|
10
10
|
Use this to discover existing Stacks you can scope a local Blueprint to (using 'blueprints config --edit'), or to audit what's deployed across your project.
|
|
11
11
|
|
|
12
|
-
Use --include-projects with --organization-id
|
|
12
|
+
Without a scope, prompts for an organization or project. Use --all to list Stacks across every organization and project you can access, or --include-projects with --organization-id for one organization and its projects.`;
|
|
13
13
|
static examples = [
|
|
14
14
|
'<%= config.bin %> <%= command.id %>',
|
|
15
|
+
'<%= config.bin %> <%= command.id %> --all',
|
|
15
16
|
'<%= config.bin %> <%= command.id %> --project-id <projectId>',
|
|
16
17
|
'<%= config.bin %> <%= command.id %> --organization-id <organizationId>',
|
|
17
18
|
'<%= config.bin %> <%= command.id %> --organization-id <organizationId> --include-projects',
|
|
@@ -19,21 +20,28 @@ Use --include-projects with --organization-id to also list Stacks from all proje
|
|
|
19
20
|
static flags = {
|
|
20
21
|
'project-id': Flags.string({
|
|
21
22
|
...projectIdFlagConfig,
|
|
22
|
-
exclusive: ['organization-id', 'include-projects'],
|
|
23
|
+
exclusive: ['organization-id', 'include-projects', 'all'],
|
|
24
|
+
}),
|
|
25
|
+
'organization-id': Flags.string({
|
|
26
|
+
...organizationIdFlagConfig,
|
|
27
|
+
exclusive: ['project-id', 'all'],
|
|
23
28
|
}),
|
|
24
|
-
'organization-id': Flags.string({ ...organizationIdFlagConfig }),
|
|
25
29
|
'include-projects': Flags.boolean({
|
|
26
30
|
description: 'Include Stacks from all projects within the organization. Requires --organization-id.',
|
|
27
31
|
dependsOn: ['organization-id'],
|
|
28
32
|
}),
|
|
33
|
+
all: Flags.boolean({
|
|
34
|
+
description: 'List Stacks from every organization and project you have access to',
|
|
35
|
+
exclusive: ['project-id', 'organization-id', 'include-projects'],
|
|
36
|
+
}),
|
|
29
37
|
};
|
|
30
38
|
async run() {
|
|
31
39
|
const result = await blueprintStacksCore({
|
|
32
40
|
bin: this.config.bin,
|
|
33
41
|
log: Logger(this.log.bind(this), this.flags),
|
|
34
42
|
token: this.sanityToken,
|
|
35
|
-
scopeType: this.
|
|
36
|
-
scopeId: this.
|
|
43
|
+
scopeType: this.resolvedScopeType,
|
|
44
|
+
scopeId: this.resolvedScopeId,
|
|
37
45
|
localStackId: this.resolvedStackId,
|
|
38
46
|
flags: this.flags,
|
|
39
47
|
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RuntimeCommand } from '../baseCommands.js';
|
|
2
|
+
export default class InitCommand extends RuntimeCommand<typeof InitCommand> {
|
|
3
|
+
static hidden: boolean;
|
|
4
|
+
static summary: string;
|
|
5
|
+
static description: string;
|
|
6
|
+
static examples: string[];
|
|
7
|
+
static args: {
|
|
8
|
+
directory: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
|
|
9
|
+
};
|
|
10
|
+
static flags: {
|
|
11
|
+
llms: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
13
|
+
'organization-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
15
|
+
dataset: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
16
|
+
'stack-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
17
|
+
'studio-name': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
18
|
+
};
|
|
19
|
+
run(): Promise<Record<string, unknown> | undefined>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { Args, Flags } from '@oclif/core';
|
|
3
|
+
import { llmsFlagConfig } from '@sanity-labs/oclif-plugin-skills-flag';
|
|
4
|
+
import { RuntimeCommand } from '../baseCommands.js';
|
|
5
|
+
import { blueprinitCore } from '../cores/blueprinit.js';
|
|
6
|
+
import { playIntro } from '../utils/display/intro.js';
|
|
7
|
+
import { Logger } from '../utils/logger.js';
|
|
8
|
+
export default class InitCommand extends RuntimeCommand {
|
|
9
|
+
static hidden = true;
|
|
10
|
+
static summary = 'Experimental blueprints-first project init';
|
|
11
|
+
static description = `Scaffolds a Blueprint, Studio, and starter function around an existing Sanity project.
|
|
12
|
+
|
|
13
|
+
Pass a directory to scaffold into it. Without one, an interactive run asks where the files go.
|
|
14
|
+
|
|
15
|
+
This hidden command is an experiment; its interface and generated files are not stable.`;
|
|
16
|
+
static examples = [
|
|
17
|
+
'<%= config.bin %> <%= command.id %>',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> ./my-workspace',
|
|
19
|
+
'<%= config.bin %> <%= command.id %> --yes',
|
|
20
|
+
'<%= config.bin %> <%= command.id %> --project-id <id> --dataset <name> --yes',
|
|
21
|
+
];
|
|
22
|
+
static args = {
|
|
23
|
+
directory: Args.string({
|
|
24
|
+
description: 'Directory to initialize. Interactive runs are asked for one instead.',
|
|
25
|
+
required: false,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
static flags = {
|
|
29
|
+
llms: Flags.boolean(llmsFlagConfig),
|
|
30
|
+
yes: Flags.boolean({
|
|
31
|
+
char: 'y',
|
|
32
|
+
description: 'Skip confirmation prompts',
|
|
33
|
+
default: false,
|
|
34
|
+
}),
|
|
35
|
+
'organization-id': Flags.string({
|
|
36
|
+
description: 'Organization to use when the account has several',
|
|
37
|
+
aliases: ['organization', 'organizationId', 'org'],
|
|
38
|
+
}),
|
|
39
|
+
'project-id': Flags.string({
|
|
40
|
+
description: 'Project to use when the organization has several',
|
|
41
|
+
aliases: ['project', 'projectId'],
|
|
42
|
+
}),
|
|
43
|
+
dataset: Flags.string({
|
|
44
|
+
description: 'Dataset to attach',
|
|
45
|
+
}),
|
|
46
|
+
'stack-name': Flags.string({
|
|
47
|
+
description: 'Name for the new organization-scoped Stack, and the hosted Studio slug',
|
|
48
|
+
}),
|
|
49
|
+
'studio-name': Flags.string({
|
|
50
|
+
description: 'Blueprint-local name for the Studio resource and its directory',
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
async run() {
|
|
54
|
+
await playIntro({ json: this.jsonEnabled() });
|
|
55
|
+
const result = await blueprinitCore({
|
|
56
|
+
bin: this.config.bin,
|
|
57
|
+
dir: this.args.directory ? resolve(this.args.directory) : undefined,
|
|
58
|
+
log: Logger(this.log.bind(this), this.flags),
|
|
59
|
+
flags: {
|
|
60
|
+
yes: this.flags.yes,
|
|
61
|
+
organizationId: this.flags['organization-id'],
|
|
62
|
+
projectId: this.flags['project-id'],
|
|
63
|
+
datasetName: this.flags.dataset,
|
|
64
|
+
stackName: this.flags['stack-name'],
|
|
65
|
+
studioName: this.flags['studio-name'],
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
if (!result.success)
|
|
69
|
+
this.coreError(result);
|
|
70
|
+
return result.json;
|
|
71
|
+
}
|
|
72
|
+
}
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { DurableStepPhase } from './utils/types.js';
|
|
1
2
|
export declare const SANITY_ACCESS_ROLE = "sanity.access.role";
|
|
2
3
|
export declare const SANITY_ACCESS_ROBOT = "sanity.access.robot";
|
|
3
4
|
export declare const SANITY_FUNCTION_PREFIX = "sanity.function.";
|
|
@@ -50,3 +51,4 @@ export declare const LABEL_PUBSUB = "PubSub";
|
|
|
50
51
|
export declare const LABEL_SCHEDULED = "Scheduled";
|
|
51
52
|
export declare const LABEL_SYNC_TAG_INVALIDATE = "Sync Tag Invalidate";
|
|
52
53
|
export declare const CI_SETUP_DOCS_URL = "https://www.sanity.io/docs/blueprints/deploy-blueprints-from-ci";
|
|
54
|
+
export declare const STEP_PHASE_GLYPH: Record<DurableStepPhase, string>;
|
package/dist/constants.js
CHANGED
|
@@ -56,3 +56,8 @@ export const LABEL_PUBSUB = 'PubSub';
|
|
|
56
56
|
export const LABEL_SCHEDULED = 'Scheduled';
|
|
57
57
|
export const LABEL_SYNC_TAG_INVALIDATE = 'Sync Tag Invalidate';
|
|
58
58
|
export const CI_SETUP_DOCS_URL = 'https://www.sanity.io/docs/blueprints/deploy-blueprints-from-ci';
|
|
59
|
+
export const STEP_PHASE_GLYPH = {
|
|
60
|
+
start: '▶',
|
|
61
|
+
complete: '✔',
|
|
62
|
+
error: '✖',
|
|
63
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { DetectedStudio } from '../../actions/blueprinit/studio.js';
|
|
2
|
+
import type { CoreResult } from '../index.js';
|
|
3
|
+
import type { BlueprinitFlowOptions } from './types.js';
|
|
4
|
+
export declare function adoptFlow(options: BlueprinitFlowOptions & {
|
|
5
|
+
studio: DetectedStudio;
|
|
6
|
+
}): Promise<CoreResult>;
|