@sanity/runtime-cli 17.1.0 → 17.2.0-blueprinit.gd1553d6

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.
Files changed (104) hide show
  1. package/README.md +38 -28
  2. package/dist/actions/blueprinit/manifest.d.ts +13 -0
  3. package/dist/actions/blueprinit/manifest.js +57 -0
  4. package/dist/actions/blueprinit/studio.d.ts +6 -0
  5. package/dist/actions/blueprinit/studio.js +43 -0
  6. package/dist/actions/blueprinit/templates.d.ts +34 -0
  7. package/dist/actions/blueprinit/templates.js +83 -0
  8. package/dist/actions/blueprinit/workspace.d.ts +15 -0
  9. package/dist/actions/blueprinit/workspace.js +142 -0
  10. package/dist/actions/blueprints/assets.d.ts +2 -1
  11. package/dist/actions/blueprints/assets.js +17 -26
  12. package/dist/actions/blueprints/blueprint.d.ts +1 -1
  13. package/dist/actions/blueprints/pre-deploy.d.ts +29 -0
  14. package/dist/actions/blueprints/pre-deploy.js +164 -0
  15. package/dist/actions/blueprints/wait-for-operation.js +4 -0
  16. package/dist/actions/sanity/datasets.d.ts +15 -0
  17. package/dist/actions/sanity/datasets.js +26 -0
  18. package/dist/actions/sanity/examples.d.ts +4 -4
  19. package/dist/baseCommands.d.ts +4 -4
  20. package/dist/commands/blueprinit.d.ts +13 -0
  21. package/dist/commands/blueprinit.js +44 -0
  22. package/dist/commands/blueprints/add.d.ts +1 -1
  23. package/dist/commands/blueprints/config.d.ts +1 -1
  24. package/dist/commands/blueprints/deploy.d.ts +1 -1
  25. package/dist/commands/blueprints/destroy.d.ts +1 -1
  26. package/dist/commands/blueprints/doctor.d.ts +0 -1
  27. package/dist/commands/blueprints/doctor.js +3 -7
  28. package/dist/commands/blueprints/info.d.ts +1 -1
  29. package/dist/commands/blueprints/logs.d.ts +1 -1
  30. package/dist/commands/blueprints/mint-deploy-token.d.ts +1 -1
  31. package/dist/commands/blueprints/plan.d.ts +1 -1
  32. package/dist/commands/blueprints/promote.d.ts +1 -1
  33. package/dist/commands/blueprints/stacks.d.ts +1 -1
  34. package/dist/commands/functions/add.d.ts +1 -1
  35. package/dist/commands/functions/build.d.ts +1 -1
  36. package/dist/commands/functions/dev.d.ts +1 -1
  37. package/dist/commands/functions/env/add.d.ts +4 -1
  38. package/dist/commands/functions/env/add.js +6 -2
  39. package/dist/commands/functions/env/list.d.ts +4 -1
  40. package/dist/commands/functions/env/list.js +9 -3
  41. package/dist/commands/functions/env/remove.d.ts +4 -1
  42. package/dist/commands/functions/env/remove.js +9 -3
  43. package/dist/commands/functions/logs.d.ts +1 -1
  44. package/dist/commands/functions/test.d.ts +1 -1
  45. package/dist/constants.d.ts +1 -0
  46. package/dist/constants.js +1 -0
  47. package/dist/cores/blueprinit/adopt.d.ts +6 -0
  48. package/dist/cores/blueprinit/adopt.js +90 -0
  49. package/dist/cores/blueprinit/finish.d.ts +14 -0
  50. package/dist/cores/blueprinit/finish.js +36 -0
  51. package/dist/cores/blueprinit/fresh.d.ts +3 -0
  52. package/dist/cores/blueprinit/fresh.js +88 -0
  53. package/dist/cores/blueprinit/prompts.d.ts +4 -0
  54. package/dist/cores/blueprinit/prompts.js +14 -0
  55. package/dist/cores/blueprinit/selection.d.ts +15 -0
  56. package/dist/cores/blueprinit/selection.js +63 -0
  57. package/dist/cores/blueprinit/types.d.ts +13 -0
  58. package/dist/cores/blueprinit/types.js +1 -0
  59. package/dist/cores/blueprinit.d.ts +7 -0
  60. package/dist/cores/blueprinit.js +39 -0
  61. package/dist/cores/blueprints/deploy.js +18 -65
  62. package/dist/cores/blueprints/doctor.js +15 -12
  63. package/dist/cores/functions/build.js +3 -2
  64. package/dist/cores/functions/test.js +4 -2
  65. package/dist/server/app.js +8 -2
  66. package/dist/server/static/favicon-dark.svg +1 -0
  67. package/dist/server/static/favicon.svg +1 -0
  68. package/dist/server/static/index.html +1 -1
  69. package/dist/server/static/vendor/vendor.bundle.js +5 -0
  70. package/dist/utils/functions/child-process-wrapper.js +13 -171
  71. package/dist/utils/functions/child-runtime/console.d.ts +1 -0
  72. package/dist/utils/functions/child-runtime/console.js +50 -0
  73. package/dist/utils/functions/child-runtime/invoke.d.ts +4 -0
  74. package/dist/utils/functions/child-runtime/invoke.js +47 -0
  75. package/dist/utils/functions/child-runtime/resources.d.ts +4 -0
  76. package/dist/utils/functions/child-runtime/resources.js +59 -0
  77. package/dist/utils/functions/find-entry-point.d.ts +1 -1
  78. package/dist/utils/functions/find-entry-point.js +10 -12
  79. package/dist/utils/functions/invoke/local.js +1 -1
  80. package/dist/utils/functions/invoke/prepare.d.ts +1 -1
  81. package/dist/utils/functions/invoke/prepare.js +19 -8
  82. package/dist/utils/functions/package-json.d.ts +1 -2
  83. package/dist/utils/functions/package-json.js +4 -6
  84. package/dist/utils/functions/prepare-asset.d.ts +2 -2
  85. package/dist/utils/functions/prepare-asset.js +18 -7
  86. package/dist/utils/functions/resolve-dependencies.d.ts +4 -1
  87. package/dist/utils/functions/resolve-dependencies.js +5 -6
  88. package/dist/utils/functions/resource-to-arc.d.ts +1 -1
  89. package/dist/utils/functions/resource-to-arc.js +4 -5
  90. package/dist/utils/functions/should-transpile.d.ts +7 -1
  91. package/dist/utils/functions/should-transpile.js +10 -10
  92. package/dist/utils/functions/transpile/function.d.ts +4 -1
  93. package/dist/utils/functions/transpile/function.js +9 -14
  94. package/dist/utils/functions/transpile/verify-handler.js +1 -1
  95. package/dist/utils/logger.d.ts +7 -5
  96. package/dist/utils/logger.js +33 -1
  97. package/dist/utils/progress.d.ts +5 -0
  98. package/dist/utils/progress.js +40 -0
  99. package/dist/utils/studios/prepare-asset.d.ts +6 -0
  100. package/dist/utils/studios/prepare-asset.js +139 -0
  101. package/dist/utils/types.d.ts +9 -8
  102. package/dist/utils/types.js +2 -3
  103. package/oclif.manifest.json +1049 -951
  104. package/package.json +30 -23
@@ -3,9 +3,10 @@ import type { Logger } from '../../utils/logger.js';
3
3
  import type { AssetResource, AuthParams, InstallerType } from '../../utils/types.js';
4
4
  export declare const assetCheckUrl: string;
5
5
  export declare const assetStashUrl: string;
6
- export declare function stashAsset({ resource, auth, logger, installer, }: {
6
+ export declare function stashAsset({ resource, auth, blueprintFileDir, logger, installer, }: {
7
7
  resource: AssetResource;
8
8
  auth: AuthParams;
9
+ blueprintFileDir: string;
9
10
  logger: Logger;
10
11
  installer?: InstallerType;
11
12
  }): Promise<{
@@ -1,48 +1,52 @@
1
1
  import crypto from 'node:crypto';
2
2
  import fs from 'node:fs';
3
+ import { readFile } from 'node:fs/promises';
3
4
  import AdmZip from 'adm-zip';
4
5
  import { blueprintsUrl } from '../../config.js';
5
6
  import { CONVERT_BYTES_TO_MB, MAX_ASSET_SIZE } from '../../constants.js';
6
7
  import { prepareAsset as prepareFunctionAsset } from '../../utils/functions/prepare-asset.js';
7
8
  import getHeaders from '../../utils/get-headers.js';
9
+ import { prepareStudioAsset } from '../../utils/studios/prepare-asset.js';
8
10
  import { createTracedFetch } from '../../utils/traced-fetch.js';
9
11
  import { isLocalFunctionResource, isStudioResource } from '../../utils/types.js';
10
12
  const assetsUrl = blueprintsUrl('assets');
11
13
  export const assetCheckUrl = `${assetsUrl}/check`;
12
14
  export const assetStashUrl = `${assetsUrl}/stash`;
13
- export async function stashAsset({ resource, auth, logger, installer, }) {
15
+ export async function stashAsset({ resource, auth, blueprintFileDir, logger, installer, }) {
16
+ let cleanup = async () => { };
14
17
  try {
15
18
  let b64;
16
19
  let hash;
17
20
  let extension;
18
- let cleanup;
19
21
  if (isLocalFunctionResource(resource)) {
20
- const prepResult = await prepareFunctionAsset({ resource }, { installer });
22
+ const prepResult = await prepareFunctionAsset({ resource, blueprintFileDir, installer });
21
23
  if (prepResult.success === false) {
24
+ await prepResult.cleanup();
22
25
  return {
23
26
  success: false,
24
27
  error: prepResult.error,
25
28
  };
26
29
  }
30
+ cleanup = prepResult.cleanup;
27
31
  const zipResult = await pathToB64ZipHash(prepResult.outputPath);
28
32
  b64 = zipResult.b64;
29
33
  hash = zipResult.hash;
30
34
  extension = 'zip';
31
- cleanup = prepResult.cleanup;
32
35
  }
33
36
  else if (isStudioResource(resource)) {
34
- const prepResult = await prepareStudioAsset({ resource });
37
+ const prepResult = await prepareStudioAsset({ resource, blueprintFileDir });
35
38
  if (prepResult.success === false) {
39
+ await prepResult.cleanup();
36
40
  return {
37
41
  success: false,
38
42
  error: prepResult.error,
39
43
  };
40
44
  }
41
- const buffer = await fs.promises.readFile(prepResult.outputPath);
45
+ cleanup = prepResult.cleanup;
46
+ const buffer = await readFile(prepResult.outputPath);
42
47
  b64 = buffer.toString('base64');
43
48
  hash = hashBuffer(buffer);
44
49
  extension = 'tar.gz';
45
- cleanup = prepResult.cleanup;
46
50
  }
47
51
  else {
48
52
  return {
@@ -61,28 +65,15 @@ export async function stashAsset({ resource, auth, logger, installer, }) {
61
65
  });
62
66
  }
63
67
  catch (err) {
68
+ try {
69
+ await cleanup();
70
+ }
71
+ catch {
72
+ // ignore clean up errors
73
+ }
64
74
  return { success: false, error: err instanceof Error ? err.message : `${err}` };
65
75
  }
66
76
  }
67
- async function prepareStudioAsset({ resource, }) {
68
- if (!fs.existsSync(resource.src)) {
69
- return {
70
- success: false,
71
- async cleanup() {
72
- // no op
73
- },
74
- error: `Property 'src' on resource with type '${resource.type}' must be a directory`,
75
- };
76
- }
77
- return {
78
- success: true,
79
- async cleanup() {
80
- // no op
81
- },
82
- // studio must be pre built (e.g. with `npm run build`) and tarred/gzipped
83
- outputPath: resource.src,
84
- };
85
- }
86
77
  async function stashSingleAsset({ b64, hash, cleanup, resource, auth, logger, extension = 'zip', }) {
87
78
  const fetchFn = createTracedFetch(logger);
88
79
  try {
@@ -4,7 +4,7 @@ import type { Logger } from '../../utils/logger.js';
4
4
  import type { BlueprintParserError, ScopeType } from '../../utils/types.js';
5
5
  import { type LocatedBlueprintsConfig } from './config.js';
6
6
  import { type ConfigSource } from './resolve.js';
7
- declare const SUPPORTED_FILE_EXTENSIONS: readonly [".json", ".js", ".mjs", ".ts"];
7
+ declare const SUPPORTED_FILE_EXTENSIONS: readonly ['.json', '.js', '.mjs', '.ts'];
8
8
  type BlueprintFileExtension = (typeof SUPPORTED_FILE_EXTENSIONS)[number];
9
9
  export declare const JSON_BLUEPRINT_CONTENT: {
10
10
  blueprintVersion: string;
@@ -0,0 +1,29 @@
1
+ import type { BlueprintResource } from '@sanity/blueprints';
2
+ import type { Logger } from '../../utils/logger.js';
3
+ import { type AuthParams, type InstallerType, type ScopeType } from '../../utils/types.js';
4
+ type PreDeployResult = {
5
+ success: false;
6
+ error: string;
7
+ code?: string;
8
+ exitCode?: number;
9
+ suggestions?: string[];
10
+ } | {
11
+ success: true;
12
+ };
13
+ type PreDeployResourceOptions = {
14
+ auth: AuthParams;
15
+ blueprintFileDir: string;
16
+ installer: InstallerType;
17
+ log: Logger;
18
+ };
19
+ type PreDeployOptions = {
20
+ scopeType: ScopeType;
21
+ scopeId: string;
22
+ resources: BlueprintResource[];
23
+ stackId: string;
24
+ stackName: string;
25
+ bin: string;
26
+ verbose: boolean | undefined;
27
+ } & PreDeployResourceOptions;
28
+ export declare function preDeploy(options: PreDeployOptions): Promise<PreDeployResult>;
29
+ export {};
@@ -0,0 +1,164 @@
1
+ import { env } from 'node:process';
2
+ import { resolveDeployedResources } from '../../utils/blueprints/resolve-deployed-resources.js';
3
+ import { niceId } from '../../utils/display/presenters.js';
4
+ import { CODE_OPERATION_UNCONFIRMED, EXIT_OPERATION_UNCONFIRMED } from '../../utils/exit-codes.js';
5
+ import { styleText } from '../../utils/style-text.js';
6
+ import { isAssetResource, } from '../../utils/types.js';
7
+ import { stashAsset } from './assets.js';
8
+ import { updateStack } from './stacks.js';
9
+ import { waitForOperation } from './wait-for-operation.js';
10
+ const DEFAULT_ASSET_TIMEOUT = 180;
11
+ const assetTimeoutS = Number(process.env.SANITY_ASSET_TIMEOUT) || DEFAULT_ASSET_TIMEOUT;
12
+ const assetTimeoutMs = assetTimeoutS * 1000;
13
+ const warnTimeoutMs = assetTimeoutMs / 3;
14
+ export async function preDeploy(options) {
15
+ const { resources, stackId, auth, blueprintFileDir, installer, log } = options;
16
+ const hasAssetResources = resources.some(isAssetResource);
17
+ if (hasAssetResources) {
18
+ let assetResources;
19
+ if (env.SANITY_BLUEPRINTS_PRE_DEPLOY_ENABLED === 'true') {
20
+ const preDeployStackResult = await preDeployStack(options);
21
+ if (!preDeployStackResult.success) {
22
+ return preDeployStackResult;
23
+ }
24
+ /** Look up resources from the back-end and attach the externalId if possible */
25
+ const resolvedResources = await resolveDeployedResources({
26
+ resources,
27
+ stackId,
28
+ auth,
29
+ logger: log,
30
+ });
31
+ assetResources = resolvedResources.filter(isAssetResource);
32
+ }
33
+ else {
34
+ assetResources = resources.filter(isAssetResource);
35
+ }
36
+ log('Processing assets...');
37
+ for (const resource of assetResources) {
38
+ const preDeployResult = await preDeployResource(resource, {
39
+ auth,
40
+ blueprintFileDir,
41
+ installer,
42
+ log,
43
+ });
44
+ if (!preDeployResult.success)
45
+ return preDeployResult;
46
+ const idx = resources.findIndex((r) => r.name === resource.name);
47
+ if (idx === -1)
48
+ throw new Error('Unable to update resource asset');
49
+ resources[idx] = preDeployResult.resource;
50
+ }
51
+ }
52
+ return { success: true };
53
+ }
54
+ async function preDeployStack(options) {
55
+ const { scopeType, scopeId, stackId, stackName, resources, auth, log, bin, verbose } = options;
56
+ const spinner = log.ora('Starting pre-deploy...').start();
57
+ const stackMutation = {
58
+ scopeType,
59
+ scopeId,
60
+ name: stackName,
61
+ preDeploy: true,
62
+ document: { resources },
63
+ };
64
+ const { ok: deployOk, stack, error: deployError, } = await updateStack({ stackId, stackMutation, auth, logger: log });
65
+ if (!deployOk) {
66
+ spinner.fail(`${styleText('red', 'Failed')} to complete Stack pre-deployment`);
67
+ return {
68
+ success: false,
69
+ error: deployError || 'Failed to complete Stack pre-deployment',
70
+ suggestions: [
71
+ `Run \`npx ${bin} blueprints plan\` to preview changes before deploying.`,
72
+ `Run \`npx ${bin} blueprints doctor\` to check your configuration.`,
73
+ ],
74
+ };
75
+ }
76
+ spinner.stop().clear();
77
+ log(styleText('dim', 'Stack deployment progress:'));
78
+ log('');
79
+ const outcome = await waitForOperation({
80
+ stackId,
81
+ operationId: stack.operationId,
82
+ auth,
83
+ log,
84
+ bin,
85
+ verbose,
86
+ progressNoun: 'pre-deployment',
87
+ });
88
+ if (outcome.type === 'completed') {
89
+ log(styleText(['bold', 'green'], 'Stack pre-deployment completed!'));
90
+ }
91
+ else if (outcome.type === 'unconfirmed') {
92
+ return {
93
+ success: false,
94
+ error: `Stack pre-deployment was accepted but completion could not be confirmed${outcome.error ? ` (${outcome.error})` : ''}.`,
95
+ code: CODE_OPERATION_UNCONFIRMED,
96
+ exitCode: EXIT_OPERATION_UNCONFIRMED,
97
+ suggestions: [
98
+ 'The pre-deployment may or may not have finished on Sanity servers.',
99
+ `Run \`npx ${bin} blueprints info\` to check status.`,
100
+ `Run \`npx ${bin} blueprints logs --watch\` to keep streaming logs.`,
101
+ ],
102
+ };
103
+ }
104
+ else {
105
+ return {
106
+ success: false,
107
+ error: 'Stack pre-deployment failed',
108
+ suggestions: [
109
+ ...outcome.logHints,
110
+ 'Review the pre-deployment output above for error details.',
111
+ `Run \`npx ${bin} blueprints logs --verbose\` for more context.`,
112
+ `Run \`npx ${bin} blueprints plan\` to identify issues with your Blueprint.`,
113
+ ],
114
+ };
115
+ }
116
+ return { success: true };
117
+ }
118
+ async function preDeployResource(resource, options) {
119
+ const { auth, blueprintFileDir, installer, log } = options;
120
+ const fnSpinner = log.ora({ text: `Processing ${resource.name}...`, prefixText: ' ' }).start();
121
+ const warnTimer = setTimeout(() => {
122
+ fnSpinner.text = `Still processing ${resource.name}, this can take a moment...`;
123
+ }, warnTimeoutMs);
124
+ let assetTimeoutTimer;
125
+ let result;
126
+ try {
127
+ result = await Promise.race([
128
+ stashAsset({ resource, blueprintFileDir, auth, logger: log, installer }),
129
+ new Promise((_, reject) => {
130
+ assetTimeoutTimer = setTimeout(() => {
131
+ reject(new Error(`Processing ${resource.name} timed out after ${assetTimeoutS}s`));
132
+ }, assetTimeoutMs);
133
+ }),
134
+ ]);
135
+ }
136
+ catch (err) {
137
+ const msg = err instanceof Error ? err.message : String(err);
138
+ fnSpinner.fail(msg);
139
+ return { success: false, error: msg };
140
+ }
141
+ finally {
142
+ clearTimeout(warnTimer);
143
+ clearTimeout(assetTimeoutTimer);
144
+ }
145
+ if (result.success && result.assetId) {
146
+ const updatedResource = { ...resource, src: result.assetId };
147
+ fnSpinner.succeed(`${updatedResource.name} ${niceId(result.assetId)}`);
148
+ log(` Source: ${updatedResource.src}`);
149
+ if (result.hash) {
150
+ if (result.hash.length > 24) {
151
+ log.verbose(` Hash: ${result.hash.slice(0, 8)}...${result.hash.slice(-12)}`);
152
+ }
153
+ else {
154
+ log.verbose(` Hash: ${result.hash}`);
155
+ }
156
+ }
157
+ if (result.exists)
158
+ log.verbose(' Asset unchanged');
159
+ return { success: true, resource: updatedResource };
160
+ }
161
+ const errorMsg = `Failed uploading ${resource.name} asset, deploy has stopped`;
162
+ fnSpinner.fail(errorMsg);
163
+ return { success: false, error: result.error || 'Failed to process asset' };
164
+ }
@@ -12,6 +12,7 @@ export async function waitForOperation(options) {
12
12
  const logHints = createHintCollector(bin);
13
13
  let logStreamCleanup = null;
14
14
  try {
15
+ log.showProgress();
15
16
  let lastLogAt = Date.now();
16
17
  let idleMessageShown = false;
17
18
  let consecutiveErrors = 0;
@@ -85,4 +86,7 @@ export async function waitForOperation(options) {
85
86
  logStreamCleanup();
86
87
  throw error;
87
88
  }
89
+ finally {
90
+ log.clearProgress();
91
+ }
88
92
  }
@@ -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
+ }
@@ -2,12 +2,12 @@ import type { Logger } from '../../utils/logger.js';
2
2
  export declare const EXAMPLES_CACHE_DIR: string;
3
3
  declare const EXAMPLE_TYPES: {
4
4
  readonly blueprint: {
5
- readonly repo: "sanity-io/sanity";
6
- readonly dir: "examples/blueprints";
5
+ readonly repo: 'sanity-io/sanity';
6
+ readonly dir: 'examples/blueprints';
7
7
  };
8
8
  readonly function: {
9
- readonly repo: "sanity-labs/function-recipes";
10
- readonly dir: "";
9
+ readonly repo: 'sanity-labs/function-recipes';
10
+ readonly dir: '';
11
11
  };
12
12
  };
13
13
  export declare function verifyExampleExists({ type, name, logger, }: {
@@ -10,7 +10,7 @@ export declare const pathFlagConfig: {
10
10
  description: string;
11
11
  env: string;
12
12
  aliases: string[];
13
- char: "p";
13
+ char: 'p';
14
14
  };
15
15
  export declare const baseFlags: {
16
16
  json: Interfaces.BooleanFlag<boolean>;
@@ -112,14 +112,14 @@ export type Need = 'token' | 'blueprint' | 'scope' | 'stackId' | 'deployedStack'
112
112
  export declare abstract class ResolvedCommand<T extends typeof Command> extends RuntimeCommand<T> {
113
113
  static needs: readonly Need[];
114
114
  static baseFlags: {
115
- stack: Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
116
- 'project-id': Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
117
- 'organization-id': Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
118
115
  json: Interfaces.BooleanFlag<boolean>;
119
116
  path: Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
120
117
  trace: Interfaces.BooleanFlag<boolean>;
121
118
  'validate-resources': Interfaces.BooleanFlag<boolean>;
122
119
  verbose: Interfaces.BooleanFlag<boolean>;
120
+ stack: Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
121
+ 'project-id': Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
122
+ 'organization-id': Interfaces.OptionFlag<string | undefined, Interfaces.CustomOptions>;
123
123
  };
124
124
  protected sanityToken: string;
125
125
  protected blueprint: ReadBlueprintResult;
@@ -0,0 +1,13 @@
1
+ import { RuntimeCommand } from '../baseCommands.js';
2
+ export default class BlueprinitCommand extends RuntimeCommand<typeof BlueprinitCommand> {
3
+ static hidden: boolean;
4
+ static summary: string;
5
+ static description: string;
6
+ static examples: string[];
7
+ static flags: {
8
+ yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
+ 'organization-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ 'project-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<Record<string, unknown> | undefined>;
13
+ }
@@ -0,0 +1,44 @@
1
+ import { Flags } from '@oclif/core';
2
+ import { RuntimeCommand } from '../baseCommands.js';
3
+ import { blueprinitCore } from '../cores/blueprinit.js';
4
+ import { Logger } from '../utils/logger.js';
5
+ export default class BlueprinitCommand extends RuntimeCommand {
6
+ static hidden = true;
7
+ static summary = 'Experimental blueprints-first project init';
8
+ static description = `Scaffolds a Blueprint, Studio, and starter function around an existing Sanity project.
9
+
10
+ This hidden command is an experiment; its interface and generated files are not stable.`;
11
+ static examples = [
12
+ '<%= config.bin %> <%= command.id %>',
13
+ '<%= config.bin %> <%= command.id %> --yes',
14
+ ];
15
+ static flags = {
16
+ yes: Flags.boolean({
17
+ char: 'y',
18
+ description: 'Skip confirmation prompts',
19
+ default: false,
20
+ }),
21
+ 'organization-id': Flags.string({
22
+ description: 'Organization to use when the account has several',
23
+ aliases: ['organization', 'organizationId', 'org'],
24
+ }),
25
+ 'project-id': Flags.string({
26
+ description: 'Project to use when the organization has several',
27
+ aliases: ['project', 'projectId'],
28
+ }),
29
+ };
30
+ async run() {
31
+ const result = await blueprinitCore({
32
+ bin: this.config.bin,
33
+ log: Logger(this.log.bind(this), this.flags),
34
+ flags: {
35
+ yes: this.flags.yes,
36
+ organizationId: this.flags['organization-id'],
37
+ projectId: this.flags['project-id'],
38
+ },
39
+ });
40
+ if (!result.success)
41
+ this.coreError(result);
42
+ return result.json;
43
+ }
44
+ }
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { ResolvedCommand } from '../../baseCommands.js';
6
6
  export default class AddCommand extends ResolvedCommand<typeof AddCommand> {
7
- static needs: readonly ["blueprint"];
7
+ static needs: readonly ['blueprint'];
8
8
  static state: string;
9
9
  static deprecationOptions: {
10
10
  to: string;
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class ConfigCommand extends ResolvedCommand<typeof ConfigCommand> {
3
- static needs: readonly ["token", "blueprint"];
3
+ static needs: readonly ['token', 'blueprint'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class DeployCommand extends ResolvedCommand<typeof DeployCommand> {
3
- static needs: readonly ["deployedStack", "blueprint"];
3
+ static needs: readonly ['deployedStack', 'blueprint'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class DestroyCommand extends ResolvedCommand<typeof DestroyCommand> {
3
- static needs: readonly ["scope"];
3
+ static needs: readonly ['scope'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -6,7 +6,6 @@ export default class DoctorCommand extends RuntimeCommand<typeof DoctorCommand>
6
6
  static flags: {
7
7
  path: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
8
  fix: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
9
  };
11
10
  run(): Promise<Record<string, unknown> | undefined>;
12
11
  }
@@ -7,8 +7,9 @@ export default class DoctorCommand extends RuntimeCommand {
7
7
  static summary = 'Diagnose potential issues with local Blueprint and remote Stack configuration';
8
8
  static description = `Analyzes your local Blueprint and remote Stack configuration for common issues, such as missing authentication, invalid project references, or misconfigured resources.
9
9
 
10
- Run this command when encountering errors with other Blueprint commands. Use --fix to interactively resolve detected issues.`;
11
- // TODO: add "Supports --json for programmatic consumption of diagnostic results." to help text
10
+ Run this command when encountering errors with other Blueprint commands. Use --fix to interactively resolve detected issues.
11
+
12
+ Supports --json for programmatic consumption of diagnostic results.`;
12
13
  static examples = [
13
14
  '<%= config.bin %> <%= command.id %>',
14
15
  '<%= config.bin %> <%= command.id %> --fix',
@@ -19,11 +20,6 @@ Run this command when encountering errors with other Blueprint commands. Use --f
19
20
  description: 'Interactively fix configuration issues',
20
21
  default: false,
21
22
  }),
22
- verbose: Flags.boolean({
23
- description: 'Verbose output; defaults to true',
24
- default: true,
25
- allowNo: true,
26
- }),
27
23
  };
28
24
  async run() {
29
25
  const { token } = config;
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class InfoCommand extends ResolvedCommand<typeof InfoCommand> {
3
- static needs: readonly ["deployedStack"];
3
+ static needs: readonly ['deployedStack'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class LogsCommand extends ResolvedCommand<typeof LogsCommand> {
3
- static needs: readonly ["deployedStack"];
3
+ static needs: readonly ['deployedStack'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class MintDeployTokenCommand extends ResolvedCommand<typeof MintDeployTokenCommand> {
3
- static needs: readonly ["scope"];
3
+ static needs: readonly ['scope'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class PlanCommand extends ResolvedCommand<typeof PlanCommand> {
3
- static needs: readonly ["token", "blueprint"];
3
+ static needs: readonly ['token', 'blueprint'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class PromoteCommand extends ResolvedCommand<typeof PromoteCommand> {
3
- static needs: readonly ["deployedStack", "blueprint"];
3
+ static needs: readonly ['deployedStack', 'blueprint'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -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 ["scope"];
3
+ static needs: readonly ['scope'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class AddCommand extends ResolvedCommand<typeof AddCommand> {
3
- static needs: readonly ["blueprint"];
3
+ static needs: readonly ['blueprint'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class BuildCommand extends ResolvedCommand<typeof BuildCommand> {
3
- static needs: readonly ["blueprint"];
3
+ static needs: readonly ['blueprint'];
4
4
  static summary: string;
5
5
  static hidden: boolean;
6
6
  static args: {
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../baseCommands.js';
2
2
  export default class DevCommand extends ResolvedCommand<typeof DevCommand> {
3
- static needs: readonly ["blueprint"];
3
+ static needs: readonly ['blueprint'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static examples: string[];
@@ -1,6 +1,6 @@
1
1
  import { ResolvedCommand } from '../../../baseCommands.js';
2
2
  export default class EnvAddCommand extends ResolvedCommand<typeof EnvAddCommand> {
3
- static needs: readonly ["deployedStack", "blueprint"];
3
+ static needs: readonly ['deployedStack', 'blueprint'];
4
4
  static summary: string;
5
5
  static description: string;
6
6
  static args: {
@@ -8,6 +8,9 @@ export default class EnvAddCommand extends ResolvedCommand<typeof EnvAddCommand>
8
8
  key: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
9
9
  value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
10
10
  };
11
+ static flags: {
12
+ stack: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ };
11
14
  static examples: string[];
12
15
  run(): Promise<Record<string, unknown> | undefined>;
13
16
  }