@sanity/runtime-cli 11.1.1 → 11.1.3
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 +22 -21
- package/dist/actions/functions/dev.d.ts +1 -1
- package/dist/actions/functions/dev.js +2 -2
- package/dist/commands/functions/dev.d.ts +1 -0
- package/dist/commands/functions/dev.js +11 -2
- package/dist/cores/blueprints/init.d.ts +35 -0
- package/dist/cores/blueprints/init.js +204 -144
- package/dist/cores/functions/dev.d.ts +1 -0
- package/dist/cores/functions/dev.js +3 -3
- package/dist/server/app.d.ts +1 -1
- package/dist/server/app.js +1 -2
- package/oclif.manifest.json +12 -3
- 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.3 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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/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.3/src/commands/functions/add.ts)_
|
|
362
362
|
|
|
363
363
|
## `sanity-run functions dev`
|
|
364
364
|
|
|
@@ -366,10 +366,11 @@ Start the Sanity Function emulator
|
|
|
366
366
|
|
|
367
367
|
```
|
|
368
368
|
USAGE
|
|
369
|
-
$ sanity-run functions dev [-p <value>] [-t <value>]
|
|
369
|
+
$ sanity-run functions dev [-h <value>] [-p <value>] [-t <value>]
|
|
370
370
|
|
|
371
371
|
FLAGS
|
|
372
|
-
-
|
|
372
|
+
-h, --host=<value> The local network interface at which to listen. [default: "localhost"]
|
|
373
|
+
-p, --port=<value> TCP port to start emulator on. [default: 8080]
|
|
373
374
|
-t, --timeout=<value> Maximum execution time for all functions, in seconds. Takes precedence over function-specific
|
|
374
375
|
`timeout`
|
|
375
376
|
|
|
@@ -377,10 +378,10 @@ DESCRIPTION
|
|
|
377
378
|
Start the Sanity Function emulator
|
|
378
379
|
|
|
379
380
|
EXAMPLES
|
|
380
|
-
$ sanity-run functions dev --port 8974
|
|
381
|
+
$ sanity-run functions dev --host 127.0.0.1 --port 8974
|
|
381
382
|
```
|
|
382
383
|
|
|
383
|
-
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
384
|
+
_See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.3/src/commands/functions/dev.ts)_
|
|
384
385
|
|
|
385
386
|
## `sanity-run functions env add NAME KEY VALUE`
|
|
386
387
|
|
|
@@ -402,7 +403,7 @@ EXAMPLES
|
|
|
402
403
|
$ sanity-run functions env add MyFunction API_URL https://api.example.com/
|
|
403
404
|
```
|
|
404
405
|
|
|
405
|
-
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
406
|
+
_See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.3/src/commands/functions/env/add.ts)_
|
|
406
407
|
|
|
407
408
|
## `sanity-run functions env list NAME`
|
|
408
409
|
|
|
@@ -422,7 +423,7 @@ EXAMPLES
|
|
|
422
423
|
$ sanity-run functions env list MyFunction
|
|
423
424
|
```
|
|
424
425
|
|
|
425
|
-
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
426
|
+
_See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.3/src/commands/functions/env/list.ts)_
|
|
426
427
|
|
|
427
428
|
## `sanity-run functions env remove NAME KEY`
|
|
428
429
|
|
|
@@ -443,7 +444,7 @@ EXAMPLES
|
|
|
443
444
|
$ sanity-run functions env remove MyFunction API_URL
|
|
444
445
|
```
|
|
445
446
|
|
|
446
|
-
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
447
|
+
_See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.3/src/commands/functions/env/remove.ts)_
|
|
447
448
|
|
|
448
449
|
## `sanity-run functions logs NAME`
|
|
449
450
|
|
|
@@ -477,7 +478,7 @@ EXAMPLES
|
|
|
477
478
|
$ sanity-run functions logs <name> --delete
|
|
478
479
|
```
|
|
479
480
|
|
|
480
|
-
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
481
|
+
_See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.3/src/commands/functions/logs.ts)_
|
|
481
482
|
|
|
482
483
|
## `sanity-run functions test NAME`
|
|
483
484
|
|
|
@@ -526,7 +527,7 @@ EXAMPLES
|
|
|
526
527
|
$ sanity-run functions test <name> --event update --data-before '{ "title": "before" }' --data-after '{ "title": "after" }'
|
|
527
528
|
```
|
|
528
529
|
|
|
529
|
-
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.
|
|
530
|
+
_See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v11.1.3/src/commands/functions/test.ts)_
|
|
530
531
|
|
|
531
532
|
## `sanity-run help [COMMAND]`
|
|
532
533
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { InvokeExecutionOptions } from '../../utils/types.js';
|
|
2
|
-
export declare function dev(port: number, executionOptions?: Partial<InvokeExecutionOptions>): Promise<void>;
|
|
2
|
+
export declare function dev(host: string, port: number, executionOptions?: Partial<InvokeExecutionOptions>): Promise<void>;
|
|
@@ -3,6 +3,7 @@ export default class DevCommand extends Command {
|
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
6
|
+
host: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
6
7
|
port: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
7
8
|
timeout: import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
8
9
|
};
|
|
@@ -2,9 +2,18 @@ import { Command, Flags } from '@oclif/core';
|
|
|
2
2
|
import { functionDevCore } from '../../cores/functions/dev.js';
|
|
3
3
|
export default class DevCommand extends Command {
|
|
4
4
|
static description = 'Start the Sanity Function emulator';
|
|
5
|
-
static examples = ['<%= config.bin %> <%= command.id %> --port 8974'];
|
|
5
|
+
static examples = ['<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port 8974'];
|
|
6
6
|
static flags = {
|
|
7
|
-
|
|
7
|
+
host: Flags.string({
|
|
8
|
+
char: 'h',
|
|
9
|
+
description: 'The local network interface at which to listen. [default: "localhost"]',
|
|
10
|
+
required: false,
|
|
11
|
+
}),
|
|
12
|
+
port: Flags.integer({
|
|
13
|
+
char: 'p',
|
|
14
|
+
description: 'TCP port to start emulator on. [default: 8080]',
|
|
15
|
+
required: false,
|
|
16
|
+
}),
|
|
8
17
|
timeout: Flags.integer({
|
|
9
18
|
char: 't',
|
|
10
19
|
description: 'Maximum execution time for all functions, in seconds. Takes precedence over function-specific `timeout`',
|
|
@@ -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
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { dev } from '../../actions/functions/dev.js';
|
|
2
2
|
export async function functionDevCore(options) {
|
|
3
3
|
const { log, flags } = options;
|
|
4
|
-
const { port = 8080, timeout } = flags;
|
|
4
|
+
const { host = 'localhost', port = 8080, timeout } = flags;
|
|
5
5
|
// Construct execution options only if timeout is provided
|
|
6
6
|
const executionOptions = timeout
|
|
7
7
|
? { timeout }
|
|
8
8
|
: undefined;
|
|
9
9
|
try {
|
|
10
|
-
await dev(Number(port), executionOptions);
|
|
11
|
-
log(`Server is running on http
|
|
10
|
+
await dev(host, Number(port), executionOptions);
|
|
11
|
+
log(`Server is running on http://${host}:${port}\n`);
|
|
12
12
|
return {
|
|
13
13
|
success: true,
|
|
14
14
|
// hold the line...
|
package/dist/server/app.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type InvokeExecutionOptions } from '../utils/types.js';
|
|
2
|
-
declare const app: (port: number, executionOptions?: Partial<InvokeExecutionOptions>) => void;
|
|
2
|
+
declare const app: (host: string, port: number, executionOptions?: Partial<InvokeExecutionOptions>) => void;
|
|
3
3
|
declare function parseDocumentUrl(url: string): {
|
|
4
4
|
projectId: string;
|
|
5
5
|
dataset: string;
|
package/dist/server/app.js
CHANGED
|
@@ -7,8 +7,7 @@ import config from '../config.js';
|
|
|
7
7
|
import { isRecord } from '../utils/is-record.js';
|
|
8
8
|
import { isEventType, } from '../utils/types.js';
|
|
9
9
|
import { handleInvokeRequest } from './handlers/invoke.js';
|
|
10
|
-
const
|
|
11
|
-
const app = (port, executionOptions) => {
|
|
10
|
+
const app = (host, port, executionOptions) => {
|
|
12
11
|
const requestListener = async (req, res) => {
|
|
13
12
|
res.setHeader('Content-Type', 'application/json');
|
|
14
13
|
switch (true) {
|
package/oclif.manifest.json
CHANGED
|
@@ -866,12 +866,21 @@
|
|
|
866
866
|
"args": {},
|
|
867
867
|
"description": "Start the Sanity Function emulator",
|
|
868
868
|
"examples": [
|
|
869
|
-
"<%= config.bin %> <%= command.id %> --port 8974"
|
|
869
|
+
"<%= config.bin %> <%= command.id %> --host 127.0.0.1 --port 8974"
|
|
870
870
|
],
|
|
871
871
|
"flags": {
|
|
872
|
+
"host": {
|
|
873
|
+
"char": "h",
|
|
874
|
+
"description": "The local network interface at which to listen. [default: \"localhost\"]",
|
|
875
|
+
"name": "host",
|
|
876
|
+
"required": false,
|
|
877
|
+
"hasDynamicHelp": false,
|
|
878
|
+
"multiple": false,
|
|
879
|
+
"type": "option"
|
|
880
|
+
},
|
|
872
881
|
"port": {
|
|
873
882
|
"char": "p",
|
|
874
|
-
"description": "
|
|
883
|
+
"description": "TCP port to start emulator on. [default: 8080]",
|
|
875
884
|
"name": "port",
|
|
876
885
|
"required": false,
|
|
877
886
|
"hasDynamicHelp": false,
|
|
@@ -1408,5 +1417,5 @@
|
|
|
1408
1417
|
]
|
|
1409
1418
|
}
|
|
1410
1419
|
},
|
|
1411
|
-
"version": "11.1.
|
|
1420
|
+
"version": "11.1.3"
|
|
1412
1421
|
}
|