@sanity/runtime-cli 11.1.1 → 11.1.2
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 +18 -18
- package/dist/cores/blueprints/init.d.ts +35 -0
- package/dist/cores/blueprints/init.js +204 -144
- package/oclif.manifest.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ $ npm install -g @sanity/runtime-cli
|
|
|
20
20
|
$ sanity-run COMMAND
|
|
21
21
|
running command...
|
|
22
22
|
$ sanity-run (--version)
|
|
23
|
-
@sanity/runtime-cli/11.1.
|
|
23
|
+
@sanity/runtime-cli/11.1.2 linux-x64 node-v24.11.0
|
|
24
24
|
$ sanity-run --help [COMMAND]
|
|
25
25
|
USAGE
|
|
26
26
|
$ sanity-run COMMAND
|
|
@@ -92,7 +92,7 @@ EXAMPLES
|
|
|
92
92
|
$ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
95
|
+
_See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/add.ts)_
|
|
96
96
|
|
|
97
97
|
## `sanity-run blueprints config`
|
|
98
98
|
|
|
@@ -124,7 +124,7 @@ EXAMPLES
|
|
|
124
124
|
$ sanity-run blueprints config --edit --project-id <projectId> --stack-id <stackId>
|
|
125
125
|
```
|
|
126
126
|
|
|
127
|
-
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
127
|
+
_See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/config.ts)_
|
|
128
128
|
|
|
129
129
|
## `sanity-run blueprints deploy`
|
|
130
130
|
|
|
@@ -146,7 +146,7 @@ EXAMPLES
|
|
|
146
146
|
$ sanity-run blueprints deploy --no-wait
|
|
147
147
|
```
|
|
148
148
|
|
|
149
|
-
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
149
|
+
_See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/deploy.ts)_
|
|
150
150
|
|
|
151
151
|
## `sanity-run blueprints destroy`
|
|
152
152
|
|
|
@@ -173,7 +173,7 @@ EXAMPLES
|
|
|
173
173
|
$ sanity-run blueprints destroy --stack-id <stackId> --project-id <projectId> --force --no-wait
|
|
174
174
|
```
|
|
175
175
|
|
|
176
|
-
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
176
|
+
_See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/destroy.ts)_
|
|
177
177
|
|
|
178
178
|
## `sanity-run blueprints doctor`
|
|
179
179
|
|
|
@@ -191,7 +191,7 @@ DESCRIPTION
|
|
|
191
191
|
Diagnose potential issues with Blueprint configuration
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
-
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
194
|
+
_See code: [src/commands/blueprints/doctor.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/doctor.ts)_
|
|
195
195
|
|
|
196
196
|
## `sanity-run blueprints info`
|
|
197
197
|
|
|
@@ -213,7 +213,7 @@ EXAMPLES
|
|
|
213
213
|
$ sanity-run blueprints info --stack-id <stackId>
|
|
214
214
|
```
|
|
215
215
|
|
|
216
|
-
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
216
|
+
_See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/info.ts)_
|
|
217
217
|
|
|
218
218
|
## `sanity-run blueprints init [DIR]`
|
|
219
219
|
|
|
@@ -252,7 +252,7 @@ EXAMPLES
|
|
|
252
252
|
$ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
|
|
253
253
|
```
|
|
254
254
|
|
|
255
|
-
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
255
|
+
_See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/init.ts)_
|
|
256
256
|
|
|
257
257
|
## `sanity-run blueprints logs`
|
|
258
258
|
|
|
@@ -274,7 +274,7 @@ EXAMPLES
|
|
|
274
274
|
$ sanity-run blueprints logs --watch
|
|
275
275
|
```
|
|
276
276
|
|
|
277
|
-
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
277
|
+
_See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/logs.ts)_
|
|
278
278
|
|
|
279
279
|
## `sanity-run blueprints plan`
|
|
280
280
|
|
|
@@ -291,7 +291,7 @@ EXAMPLES
|
|
|
291
291
|
$ sanity-run blueprints plan
|
|
292
292
|
```
|
|
293
293
|
|
|
294
|
-
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
294
|
+
_See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/plan.ts)_
|
|
295
295
|
|
|
296
296
|
## `sanity-run blueprints stacks`
|
|
297
297
|
|
|
@@ -316,7 +316,7 @@ EXAMPLES
|
|
|
316
316
|
$ sanity-run blueprints stacks --organization-id <organizationId>
|
|
317
317
|
```
|
|
318
318
|
|
|
319
|
-
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
319
|
+
_See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/blueprints/stacks.ts)_
|
|
320
320
|
|
|
321
321
|
## `sanity-run functions add`
|
|
322
322
|
|
|
@@ -358,7 +358,7 @@ EXAMPLES
|
|
|
358
358
|
$ sanity-run functions add --name my-function --type document-create --type document-update --lang js
|
|
359
359
|
```
|
|
360
360
|
|
|
361
|
-
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
361
|
+
_See code: [src/commands/functions/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/functions/add.ts)_
|
|
362
362
|
|
|
363
363
|
## `sanity-run functions dev`
|
|
364
364
|
|
|
@@ -380,7 +380,7 @@ EXAMPLES
|
|
|
380
380
|
$ sanity-run functions dev --port 8974
|
|
381
381
|
```
|
|
382
382
|
|
|
383
|
-
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
383
|
+
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/functions/dev.ts)_
|
|
384
384
|
|
|
385
385
|
## `sanity-run functions env add NAME KEY VALUE`
|
|
386
386
|
|
|
@@ -402,7 +402,7 @@ EXAMPLES
|
|
|
402
402
|
$ sanity-run functions env add MyFunction API_URL https://api.example.com/
|
|
403
403
|
```
|
|
404
404
|
|
|
405
|
-
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
405
|
+
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/functions/env/add.ts)_
|
|
406
406
|
|
|
407
407
|
## `sanity-run functions env list NAME`
|
|
408
408
|
|
|
@@ -422,7 +422,7 @@ EXAMPLES
|
|
|
422
422
|
$ sanity-run functions env list MyFunction
|
|
423
423
|
```
|
|
424
424
|
|
|
425
|
-
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
425
|
+
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/functions/env/list.ts)_
|
|
426
426
|
|
|
427
427
|
## `sanity-run functions env remove NAME KEY`
|
|
428
428
|
|
|
@@ -443,7 +443,7 @@ EXAMPLES
|
|
|
443
443
|
$ sanity-run functions env remove MyFunction API_URL
|
|
444
444
|
```
|
|
445
445
|
|
|
446
|
-
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
446
|
+
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/functions/env/remove.ts)_
|
|
447
447
|
|
|
448
448
|
## `sanity-run functions logs NAME`
|
|
449
449
|
|
|
@@ -477,7 +477,7 @@ EXAMPLES
|
|
|
477
477
|
$ sanity-run functions logs <name> --delete
|
|
478
478
|
```
|
|
479
479
|
|
|
480
|
-
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
480
|
+
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/functions/logs.ts)_
|
|
481
481
|
|
|
482
482
|
## `sanity-run functions test NAME`
|
|
483
483
|
|
|
@@ -526,7 +526,7 @@ EXAMPLES
|
|
|
526
526
|
$ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
|
|
527
527
|
```
|
|
528
528
|
|
|
529
|
-
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
529
|
+
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.2/src/commands/functions/test.ts)_
|
|
530
530
|
|
|
531
531
|
## `sanity-run help [COMMAND]`
|
|
532
532
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ScopeType } from '../../utils/types.js';
|
|
1
2
|
import type { CoreConfig, CoreResult } from '../index.js';
|
|
2
3
|
export interface BlueprintInitOptions extends CoreConfig {
|
|
3
4
|
token: string;
|
|
@@ -15,3 +16,37 @@ export interface BlueprintInitOptions extends CoreConfig {
|
|
|
15
16
|
};
|
|
16
17
|
}
|
|
17
18
|
export declare function blueprintInitCore(options: BlueprintInitOptions): Promise<CoreResult>;
|
|
19
|
+
export declare function validateFlags(flags: {
|
|
20
|
+
stackId?: string;
|
|
21
|
+
stackName?: string;
|
|
22
|
+
organizationId?: string;
|
|
23
|
+
projectId?: string;
|
|
24
|
+
}): CoreResult | null;
|
|
25
|
+
interface ResolvedScope {
|
|
26
|
+
scopeType: ScopeType;
|
|
27
|
+
scopeId: string;
|
|
28
|
+
stackId: string | undefined;
|
|
29
|
+
}
|
|
30
|
+
export declare function resolveScopeAndStack(params: {
|
|
31
|
+
projectId: string | undefined;
|
|
32
|
+
organizationId: string | undefined;
|
|
33
|
+
stackId: string | undefined;
|
|
34
|
+
stackName: string | undefined;
|
|
35
|
+
token: string;
|
|
36
|
+
log: (message: string) => void;
|
|
37
|
+
}): Promise<ResolvedScope>;
|
|
38
|
+
export declare function determineBlueprintExtension(params: {
|
|
39
|
+
requestedType: string | undefined;
|
|
40
|
+
blueprintDir: string;
|
|
41
|
+
}): Promise<string>;
|
|
42
|
+
export declare function createBlueprintFiles(params: {
|
|
43
|
+
blueprintDir: string;
|
|
44
|
+
userProvidedDirName: string | undefined;
|
|
45
|
+
blueprintExtension: string;
|
|
46
|
+
scopeType: ScopeType;
|
|
47
|
+
scopeId: string;
|
|
48
|
+
stackId: string | undefined;
|
|
49
|
+
bin: string;
|
|
50
|
+
log: (message: string) => void;
|
|
51
|
+
}): Promise<CoreResult>;
|
|
52
|
+
export {};
|
|
@@ -11,149 +11,60 @@ import { verifyExampleExists, writeExample } from '../../actions/sanity/examples
|
|
|
11
11
|
import { getProject } from '../../actions/sanity/projects.js';
|
|
12
12
|
import { BLUEPRINT_CONFIG_FILE, BLUEPRINT_DIR } from '../../config.js';
|
|
13
13
|
import { check, warn } from '../../utils/display/presenters.js';
|
|
14
|
-
import { promptForProject
|
|
15
|
-
const
|
|
14
|
+
import { promptForProject } from '../../utils/display/prompt.js';
|
|
15
|
+
const SCOPE_PROJECT = 'project';
|
|
16
|
+
const SCOPE_ORGANIZATION = 'organization';
|
|
16
17
|
export async function blueprintInitCore(options) {
|
|
17
18
|
const { bin = 'sanity', log, token, args, flags } = options;
|
|
18
19
|
try {
|
|
19
|
-
const { dir: flagDir, example: flagExample, 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId,
|
|
20
|
-
// 'organization-id': flagOrganizationId,
|
|
21
|
-
'stack-id': flagStackId, 'stack-name': flagStackName, } = flags;
|
|
20
|
+
const { dir: flagDir, example: flagExample, 'blueprint-type': flagBlueprintType, 'project-id': flagProjectId, 'organization-id': flagOrganizationId, 'stack-id': flagStackId, 'stack-name': flagStackName, } = flags;
|
|
22
21
|
const { dir: argDir } = args;
|
|
23
|
-
const
|
|
24
|
-
const blueprintDir =
|
|
22
|
+
const userProvidedDirName = argDir || flagDir;
|
|
23
|
+
const blueprintDir = userProvidedDirName || '.';
|
|
25
24
|
const existingBlueprint = findBlueprintFile(blueprintDir);
|
|
26
25
|
if (existingBlueprint) {
|
|
27
26
|
return { success: false, error: 'Existing Blueprint found.' };
|
|
28
27
|
}
|
|
28
|
+
const validationError = validateFlags({
|
|
29
|
+
stackId: flagStackId,
|
|
30
|
+
stackName: flagStackName,
|
|
31
|
+
organizationId: flagOrganizationId,
|
|
32
|
+
projectId: flagProjectId,
|
|
33
|
+
});
|
|
34
|
+
if (validationError)
|
|
35
|
+
return validationError;
|
|
29
36
|
if (flagExample) {
|
|
30
|
-
|
|
31
|
-
log(warn(`Example feature is experimental. Setting up "${flagExample}"...`));
|
|
32
|
-
// we need to...
|
|
33
|
-
// * 1. verify example exists in the recipes repo
|
|
34
|
-
const exampleExists = await verifyExampleExists({ type: 'blueprint', name: flagExample });
|
|
35
|
-
if (!exampleExists) {
|
|
36
|
-
return { success: false, error: `Blueprint example "${flagExample}" does not exist.` };
|
|
37
|
-
}
|
|
38
|
-
// * 2. get a projectId from the user
|
|
39
|
-
const projectId = flagProjectId || (await promptForProject({ token })).projectId;
|
|
40
|
-
// * 3. create empty stack with name from example name
|
|
41
|
-
const stack = await createEmptyStack({
|
|
42
|
-
token,
|
|
43
|
-
scopeType: 'project',
|
|
44
|
-
scopeId: projectId,
|
|
45
|
-
name: `example-${flagExample}`,
|
|
46
|
-
projectBased: false,
|
|
47
|
-
});
|
|
48
|
-
// * 4. download and write example to disk
|
|
49
|
-
// take into account optional providedDir
|
|
50
|
-
const exampleDir = join(blueprintDir, providedDir ? '' : flagExample);
|
|
51
|
-
if (existsSync(exampleDir)) {
|
|
52
|
-
return { success: false, error: `Example directory "${exampleDir}" already exists.` };
|
|
53
|
-
}
|
|
54
|
-
const addedExample = await writeExample({
|
|
55
|
-
exampleType: 'blueprint',
|
|
37
|
+
return handleExampleInitialization({
|
|
56
38
|
exampleName: flagExample,
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
return { success: false, error: `Unable to download example "${flagExample}"` };
|
|
61
|
-
}
|
|
62
|
-
const { files, dir: newDir, instructions } = addedExample;
|
|
63
|
-
for (const filePath of Object.keys(files)) {
|
|
64
|
-
log(check(`${chalk.bold('Created:')} ${newDir}/${filePath}`));
|
|
65
|
-
}
|
|
66
|
-
const discoveredBlueprint = findBlueprintFile(exampleDir);
|
|
67
|
-
if (!discoveredBlueprint) {
|
|
68
|
-
return { success: false, error: 'Failed to find blueprint file.' };
|
|
69
|
-
}
|
|
70
|
-
const { blueprintFilePath } = discoveredBlueprint;
|
|
71
|
-
// * 5. write config file
|
|
72
|
-
writeConfigFile({ blueprintFilePath, projectId, stackId: stack.id });
|
|
73
|
-
log(check(`${chalk.bold('Configured:')} ${exampleDir}/${BLUEPRINT_DIR}/${BLUEPRINT_CONFIG_FILE}`));
|
|
74
|
-
// * 6. print next step
|
|
75
|
-
log(`\n Run "${chalk.bold.magenta(`cd ${exampleDir} && npm i`)}" and check out the README`);
|
|
76
|
-
if (instructions) {
|
|
77
|
-
log('');
|
|
78
|
-
log(instructions);
|
|
79
|
-
}
|
|
80
|
-
return { success: true };
|
|
81
|
-
}
|
|
82
|
-
let blueprintExtension = flagBlueprintType || (await promptForBlueprintType());
|
|
83
|
-
if (!blueprintExtension) {
|
|
84
|
-
return { success: false, error: 'Blueprint type is required.' };
|
|
85
|
-
}
|
|
86
|
-
if (blueprintExtension === 'js') {
|
|
87
|
-
const packageJsonPath = join(blueprintDir, 'package.json');
|
|
88
|
-
const packageExists = existsSync(packageJsonPath);
|
|
89
|
-
if (packageExists) {
|
|
90
|
-
// if package.json#type is not module, set blueprintExtension to mjs
|
|
91
|
-
try {
|
|
92
|
-
const packageJson = readFileSync(packageJsonPath, 'utf8');
|
|
93
|
-
const packageJsonObject = JSON.parse(packageJson);
|
|
94
|
-
if (packageJsonObject.type !== 'module') {
|
|
95
|
-
blueprintExtension = 'mjs';
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
catch { } // not our concern
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
let projectId = flagProjectId;
|
|
102
|
-
let stackId = flagStackId;
|
|
103
|
-
if (!projectId) {
|
|
104
|
-
const pickedProject = await promptForProject({ token });
|
|
105
|
-
projectId = pickedProject.projectId;
|
|
106
|
-
}
|
|
107
|
-
log('');
|
|
108
|
-
if (flagStackName) {
|
|
109
|
-
// using --stack-name gets around "LAUNCH LIMIT: 1 Stack per Project"
|
|
110
|
-
const stack = await createEmptyStack({
|
|
39
|
+
projectId: flagProjectId,
|
|
40
|
+
blueprintDir,
|
|
41
|
+
userProvidedDirName,
|
|
111
42
|
token,
|
|
112
|
-
|
|
113
|
-
scopeId: projectId,
|
|
114
|
-
name: flagStackName,
|
|
115
|
-
projectBased: false,
|
|
43
|
+
log,
|
|
116
44
|
});
|
|
117
|
-
stackId = stack.id;
|
|
118
|
-
}
|
|
119
|
-
if (!stackId) {
|
|
120
|
-
// LAUNCH LIMIT: 1 Stack per Project - do not prompt for Stack, just create one
|
|
121
|
-
if (LAUNCH_LIMIT_STACK_PER_PROJECT) {
|
|
122
|
-
await createProjectBasedStack({ token, scopeType: 'project', scopeId: projectId }, log);
|
|
123
|
-
// do not set stackId, to avoid saving it to the config file
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
stackId = await promptForStackId({ projectId, token });
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
const blueprintFileName = `sanity.blueprint.${blueprintExtension}`;
|
|
130
|
-
const blueprintFilePath = join(blueprintDir, blueprintFileName);
|
|
131
|
-
writeBlueprintToDisk({ blueprintFilePath });
|
|
132
|
-
if (providedDir)
|
|
133
|
-
log(check(`${chalk.bold('New folder created:')} ${providedDir}/`));
|
|
134
|
-
log(check(`${chalk.bold('Created Blueprint:')} ${providedDir ?? '.'}/${blueprintFileName}`));
|
|
135
|
-
writeConfigFile({ blueprintFilePath, projectId, stackId });
|
|
136
|
-
log(check(`${chalk.bold('Added configuration:')} ${providedDir ?? '.'}/${BLUEPRINT_DIR}/${BLUEPRINT_CONFIG_FILE}`));
|
|
137
|
-
writeGitignoreFile(blueprintFilePath);
|
|
138
|
-
log(check(`${chalk.bold('Added .gitignore:')} ${providedDir ?? '.'}/.gitignore`));
|
|
139
|
-
if (blueprintExtension !== 'json') {
|
|
140
|
-
try {
|
|
141
|
-
// check for || create package.json and add @sanity/blueprints to dependencies
|
|
142
|
-
await writeOrUpdateNodeDependency(blueprintFilePath, '@sanity/blueprints');
|
|
143
|
-
log(check(`${chalk.bold('Added dependency:')} @sanity/blueprints`));
|
|
144
|
-
}
|
|
145
|
-
catch {
|
|
146
|
-
log(warn('Unable to add @sanity/blueprints to your project.'));
|
|
147
|
-
}
|
|
148
45
|
}
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
46
|
+
const { scopeType, scopeId, stackId } = await resolveScopeAndStack({
|
|
47
|
+
projectId: flagProjectId,
|
|
48
|
+
organizationId: flagOrganizationId,
|
|
49
|
+
stackId: flagStackId,
|
|
50
|
+
stackName: flagStackName,
|
|
51
|
+
token,
|
|
52
|
+
log,
|
|
53
|
+
});
|
|
54
|
+
const blueprintExtension = await determineBlueprintExtension({
|
|
55
|
+
requestedType: flagBlueprintType,
|
|
56
|
+
blueprintDir,
|
|
57
|
+
});
|
|
58
|
+
return createBlueprintFiles({
|
|
59
|
+
blueprintDir,
|
|
60
|
+
userProvidedDirName,
|
|
61
|
+
blueprintExtension,
|
|
62
|
+
scopeType,
|
|
63
|
+
scopeId,
|
|
64
|
+
stackId,
|
|
65
|
+
bin,
|
|
66
|
+
log,
|
|
67
|
+
});
|
|
157
68
|
}
|
|
158
69
|
catch (error) {
|
|
159
70
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
@@ -161,6 +72,158 @@ export async function blueprintInitCore(options) {
|
|
|
161
72
|
return { success: false, error: errorMessage };
|
|
162
73
|
}
|
|
163
74
|
}
|
|
75
|
+
export function validateFlags(flags) {
|
|
76
|
+
const { stackId, stackName, organizationId, projectId } = flags;
|
|
77
|
+
if (stackId && stackName) {
|
|
78
|
+
return { success: false, error: 'Cannot specify both --stack-id and --stack-name' };
|
|
79
|
+
}
|
|
80
|
+
if (organizationId && projectId) {
|
|
81
|
+
return { success: false, error: 'Cannot specify both --organization-id and --project-id' };
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
async function handleExampleInitialization(options) {
|
|
86
|
+
const { exampleName, blueprintDir, userProvidedDirName, projectId, token, log } = options;
|
|
87
|
+
log(warn(`Example feature is experimental. Setting up "${exampleName}"...`));
|
|
88
|
+
const exampleExists = await verifyExampleExists({ type: 'blueprint', name: exampleName });
|
|
89
|
+
if (!exampleExists) {
|
|
90
|
+
return { success: false, error: `Blueprint example "${exampleName}" does not exist.` };
|
|
91
|
+
}
|
|
92
|
+
const resolvedProjectId = projectId || (await promptForProject({ token })).projectId;
|
|
93
|
+
const stack = await createEmptyStack({
|
|
94
|
+
token,
|
|
95
|
+
scopeType: SCOPE_PROJECT,
|
|
96
|
+
scopeId: resolvedProjectId,
|
|
97
|
+
name: `example-${exampleName}`,
|
|
98
|
+
projectBased: false,
|
|
99
|
+
});
|
|
100
|
+
const exampleDir = userProvidedDirName || join(blueprintDir, exampleName);
|
|
101
|
+
if (existsSync(exampleDir)) {
|
|
102
|
+
return { success: false, error: `Example directory "${exampleDir}" already exists.` };
|
|
103
|
+
}
|
|
104
|
+
const addedExample = await writeExample({
|
|
105
|
+
exampleType: 'blueprint',
|
|
106
|
+
exampleName,
|
|
107
|
+
dir: exampleDir,
|
|
108
|
+
});
|
|
109
|
+
if (!addedExample) {
|
|
110
|
+
return { success: false, error: `Unable to download example "${exampleName}"` };
|
|
111
|
+
}
|
|
112
|
+
const { files, dir: newDir, instructions } = addedExample;
|
|
113
|
+
for (const filePath of Object.keys(files)) {
|
|
114
|
+
log(check(`${chalk.bold('Created:')} ${newDir}/${filePath}`));
|
|
115
|
+
}
|
|
116
|
+
const discoveredBlueprint = findBlueprintFile(exampleDir);
|
|
117
|
+
if (!discoveredBlueprint) {
|
|
118
|
+
return { success: false, error: 'Failed to find blueprint file.' };
|
|
119
|
+
}
|
|
120
|
+
const { blueprintFilePath } = discoveredBlueprint;
|
|
121
|
+
writeConfigFile({ blueprintFilePath, projectId: resolvedProjectId, stackId: stack.id });
|
|
122
|
+
log(check(`${chalk.bold('Configured:')} ${exampleDir}/${BLUEPRINT_DIR}/${BLUEPRINT_CONFIG_FILE}`));
|
|
123
|
+
log(`\n Run "${chalk.bold.magenta(`cd ${exampleDir} && npm i`)}" and check out the README`);
|
|
124
|
+
if (instructions) {
|
|
125
|
+
log('');
|
|
126
|
+
log(instructions);
|
|
127
|
+
}
|
|
128
|
+
return { success: true };
|
|
129
|
+
}
|
|
130
|
+
export async function resolveScopeAndStack(params) {
|
|
131
|
+
const { projectId, organizationId, stackId, stackName, token, log } = params;
|
|
132
|
+
let scopeType = SCOPE_PROJECT;
|
|
133
|
+
let scopeId;
|
|
134
|
+
if (projectId) {
|
|
135
|
+
scopeType = SCOPE_PROJECT;
|
|
136
|
+
scopeId = projectId;
|
|
137
|
+
}
|
|
138
|
+
else if (organizationId) {
|
|
139
|
+
scopeType = SCOPE_ORGANIZATION;
|
|
140
|
+
scopeId = organizationId;
|
|
141
|
+
}
|
|
142
|
+
let resolvedStackId = stackId;
|
|
143
|
+
if (!resolvedStackId && stackName && scopeType && scopeId) {
|
|
144
|
+
// essentially the only way to create an org-scoped stack
|
|
145
|
+
const stack = await createEmptyStack({
|
|
146
|
+
token,
|
|
147
|
+
scopeType,
|
|
148
|
+
scopeId,
|
|
149
|
+
name: stackName,
|
|
150
|
+
projectBased: false,
|
|
151
|
+
});
|
|
152
|
+
resolvedStackId = stack.id;
|
|
153
|
+
}
|
|
154
|
+
if (!scopeId) {
|
|
155
|
+
const pickedProject = await promptForProject({ token });
|
|
156
|
+
scopeType = SCOPE_PROJECT;
|
|
157
|
+
scopeId = pickedProject.projectId;
|
|
158
|
+
}
|
|
159
|
+
if (!resolvedStackId) {
|
|
160
|
+
await getOrCreateProjectBasedStack({ token, projectId: scopeId, log });
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
scopeType,
|
|
164
|
+
scopeId,
|
|
165
|
+
stackId: resolvedStackId,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
export async function determineBlueprintExtension(params) {
|
|
169
|
+
const { requestedType, blueprintDir } = params;
|
|
170
|
+
const extension = requestedType || (await promptForBlueprintType());
|
|
171
|
+
if (extension === 'js') {
|
|
172
|
+
const packageJsonPath = join(blueprintDir, 'package.json');
|
|
173
|
+
const packageExists = existsSync(packageJsonPath);
|
|
174
|
+
if (packageExists) {
|
|
175
|
+
try {
|
|
176
|
+
const packageJson = readFileSync(packageJsonPath, 'utf8');
|
|
177
|
+
const packageJsonObject = JSON.parse(packageJson);
|
|
178
|
+
if (packageJsonObject.type !== 'module') {
|
|
179
|
+
return 'mjs';
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
catch { }
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return extension;
|
|
186
|
+
}
|
|
187
|
+
export async function createBlueprintFiles(params) {
|
|
188
|
+
const { blueprintDir, userProvidedDirName, blueprintExtension, scopeType, scopeId, stackId, bin, log, } = params;
|
|
189
|
+
if (!blueprintExtension) {
|
|
190
|
+
return { success: false, error: 'Blueprint type is required.' };
|
|
191
|
+
}
|
|
192
|
+
const blueprintFileName = `sanity.blueprint.${blueprintExtension}`;
|
|
193
|
+
const blueprintFilePath = join(blueprintDir, blueprintFileName);
|
|
194
|
+
writeBlueprintToDisk({ blueprintFilePath });
|
|
195
|
+
if (userProvidedDirName) {
|
|
196
|
+
log(check(`${chalk.bold('New folder created:')} ${userProvidedDirName}/`));
|
|
197
|
+
}
|
|
198
|
+
const displayPath = userProvidedDirName || '.';
|
|
199
|
+
log(check(`${chalk.bold('Created Blueprint:')} ${displayPath}/${blueprintFileName}`));
|
|
200
|
+
writeConfigFile({
|
|
201
|
+
blueprintFilePath,
|
|
202
|
+
stackId,
|
|
203
|
+
...(scopeType === SCOPE_ORGANIZATION ? { organizationId: scopeId } : { projectId: scopeId }),
|
|
204
|
+
});
|
|
205
|
+
log(check(`${chalk.bold('Added configuration:')} ${displayPath}/${BLUEPRINT_DIR}/${BLUEPRINT_CONFIG_FILE}`));
|
|
206
|
+
writeGitignoreFile(blueprintFilePath);
|
|
207
|
+
log(check(`${chalk.bold('Added .gitignore:')} ${displayPath}/.gitignore`));
|
|
208
|
+
if (blueprintExtension !== 'json') {
|
|
209
|
+
const blueprintsPackage = '@sanity/blueprints';
|
|
210
|
+
try {
|
|
211
|
+
await writeOrUpdateNodeDependency(blueprintFilePath, blueprintsPackage);
|
|
212
|
+
log(check(`${chalk.bold('Added dependency:')} ${blueprintsPackage}`));
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
log(warn(`Unable to add ${blueprintsPackage} to your project.`));
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
const nextStepParts = [];
|
|
219
|
+
if (userProvidedDirName)
|
|
220
|
+
nextStepParts.push(`cd ${userProvidedDirName}`);
|
|
221
|
+
if (blueprintExtension !== 'json')
|
|
222
|
+
nextStepParts.push('npm install');
|
|
223
|
+
nextStepParts.push(`${bin} blueprints --help`);
|
|
224
|
+
log(`\n Run "${chalk.bold.magenta(nextStepParts.join(' && '))}" to get started`);
|
|
225
|
+
return { success: true };
|
|
226
|
+
}
|
|
164
227
|
async function promptForBlueprintType() {
|
|
165
228
|
const { pickedBlueprintsType } = await inquirer.prompt([
|
|
166
229
|
{
|
|
@@ -178,27 +241,24 @@ async function promptForBlueprintType() {
|
|
|
178
241
|
return pickedBlueprintsType;
|
|
179
242
|
}
|
|
180
243
|
// LAUNCH LIMIT: 1 Stack per Project - create exclusive stack for project
|
|
181
|
-
async function
|
|
182
|
-
|
|
183
|
-
throw new Error('Auth must be for a project');
|
|
184
|
-
}
|
|
185
|
-
const { scopeId: projectId, token } = auth;
|
|
186
|
-
// get project
|
|
244
|
+
async function getOrCreateProjectBasedStack(params) {
|
|
245
|
+
const { projectId, token, log } = params;
|
|
187
246
|
const { ok: projectOk, project } = await getProject({
|
|
188
|
-
token
|
|
189
|
-
scopeType:
|
|
247
|
+
token,
|
|
248
|
+
scopeType: SCOPE_PROJECT,
|
|
190
249
|
scopeId: projectId,
|
|
191
250
|
});
|
|
192
251
|
if (!projectOk) {
|
|
193
252
|
throw new Error('Failed to find Project while creating Stack');
|
|
194
253
|
}
|
|
195
|
-
const projectDisplayName = project.displayName;
|
|
196
254
|
// check if project has a stack
|
|
197
|
-
const
|
|
198
|
-
|
|
255
|
+
const { stack: existingStack, ok: stackOk } = await getStack({
|
|
256
|
+
auth: { token, scopeType: SCOPE_PROJECT, scopeId: projectId },
|
|
257
|
+
stackId: `ST-${projectId}`,
|
|
258
|
+
});
|
|
199
259
|
// if existing stack, return stack
|
|
200
260
|
if (stackOk && existingStack) {
|
|
201
|
-
log(warn(`"${
|
|
261
|
+
log(warn(`"${project.displayName}" has an existing deployment.`));
|
|
202
262
|
log(warn(`Deploying an empty Blueprint ${chalk.bold.red('will override the existing deployment!')}`));
|
|
203
263
|
log('');
|
|
204
264
|
return existingStack;
|
|
@@ -206,9 +266,9 @@ async function createProjectBasedStack(auth, log) {
|
|
|
206
266
|
// if not, create a stack
|
|
207
267
|
const stack = await createEmptyStack({
|
|
208
268
|
token,
|
|
209
|
-
scopeType:
|
|
269
|
+
scopeType: SCOPE_PROJECT,
|
|
210
270
|
scopeId: projectId,
|
|
211
|
-
name:
|
|
271
|
+
name: project.displayName,
|
|
212
272
|
});
|
|
213
273
|
return stack;
|
|
214
274
|
}
|
package/oclif.manifest.json
CHANGED