@sanity/runtime-cli 10.4.0 → 10.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +16 -16
  2. package/dist/actions/blueprints/blueprint.d.ts +14 -24
  3. package/dist/actions/blueprints/blueprint.js +19 -43
  4. package/dist/actions/blueprints/index.d.ts +3 -4
  5. package/dist/actions/blueprints/index.js +0 -1
  6. package/dist/actions/blueprints/logs-streaming.d.ts +24 -0
  7. package/dist/actions/blueprints/logs-streaming.js +96 -0
  8. package/dist/actions/blueprints/logs.d.ts +0 -11
  9. package/dist/actions/blueprints/logs.js +0 -75
  10. package/dist/baseCommands.d.ts +2 -2
  11. package/dist/commands/blueprints/init.js +4 -4
  12. package/dist/cores/blueprints/add.js +1 -1
  13. package/dist/cores/blueprints/deploy.js +1 -1
  14. package/dist/cores/blueprints/destroy.js +1 -1
  15. package/dist/cores/blueprints/logs.js +1 -1
  16. package/dist/cores/index.js +2 -2
  17. package/dist/utils/display/blueprints-formatting.d.ts +4 -3
  18. package/dist/utils/display/index.d.ts +0 -1
  19. package/dist/utils/display/index.js +0 -1
  20. package/dist/utils/display/logs-formatting.d.ts +0 -1
  21. package/dist/utils/display/logs-formatting.js +0 -10
  22. package/dist/utils/find-function.d.ts +3 -3
  23. package/dist/utils/find-function.js +0 -18
  24. package/dist/utils/index.d.ts +0 -1
  25. package/dist/utils/index.js +0 -1
  26. package/dist/utils/types.d.ts +5 -42
  27. package/dist/utils/validated-token.d.ts +5 -10
  28. package/dist/utils/validated-token.js +6 -3
  29. package/oclif.manifest.json +1 -1
  30. package/package.json +2 -1
  31. package/dist/actions/blueprints/operations.d.ts +0 -19
  32. package/dist/actions/blueprints/operations.js +0 -46
  33. package/dist/utils/display/blueprints-logs-streaming.d.ts +0 -14
  34. package/dist/utils/display/blueprints-logs-streaming.js +0 -33
  35. package/dist/utils/display/colors.d.ts +0 -15
  36. package/dist/utils/display/colors.js +0 -30
  37. package/dist/utils/vendor/index.d.ts +0 -1
  38. package/dist/utils/vendor/index.js +0 -1
  39. package/dist/utils/vendor/parser-validator.d.ts +0 -7
  40. package/dist/utils/vendor/parser-validator.js +0 -514
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/10.4.0 linux-x64 node-v22.18.0
23
+ @sanity/runtime-cli/10.5.0 linux-x64 node-v22.19.0
24
24
  $ sanity-run --help [COMMAND]
25
25
  USAGE
26
26
  $ sanity-run COMMAND
@@ -88,7 +88,7 @@ EXAMPLES
88
88
  $ sanity-run blueprints add function --name my-function --fn-type document-create --fn-type document-update --lang js
89
89
  ```
90
90
 
91
- _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/add.ts)_
91
+ _See code: [src/commands/blueprints/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/add.ts)_
92
92
 
93
93
  ## `sanity-run blueprints config`
94
94
 
@@ -119,7 +119,7 @@ EXAMPLES
119
119
  $ sanity-run blueprints config --edit --project-id <projectId> --stack-id <stackId>
120
120
  ```
121
121
 
122
- _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/config.ts)_
122
+ _See code: [src/commands/blueprints/config.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/config.ts)_
123
123
 
124
124
  ## `sanity-run blueprints deploy`
125
125
 
@@ -141,7 +141,7 @@ EXAMPLES
141
141
  $ sanity-run blueprints deploy --no-wait
142
142
  ```
143
143
 
144
- _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/deploy.ts)_
144
+ _See code: [src/commands/blueprints/deploy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/deploy.ts)_
145
145
 
146
146
  ## `sanity-run blueprints destroy`
147
147
 
@@ -166,7 +166,7 @@ EXAMPLES
166
166
  $ sanity-run blueprints destroy --stack-id <stackId> --project-id <projectId> --force --no-wait
167
167
  ```
168
168
 
169
- _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/destroy.ts)_
169
+ _See code: [src/commands/blueprints/destroy.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/destroy.ts)_
170
170
 
171
171
  ## `sanity-run blueprints info`
172
172
 
@@ -188,7 +188,7 @@ EXAMPLES
188
188
  $ sanity-run blueprints info --stack-id <stackId>
189
189
  ```
190
190
 
191
- _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/info.ts)_
191
+ _See code: [src/commands/blueprints/info.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/info.ts)_
192
192
 
193
193
  ## `sanity-run blueprints init [DIR]`
194
194
 
@@ -226,7 +226,7 @@ EXAMPLES
226
226
  $ sanity-run blueprints init --blueprint-type <json|js|ts> --stack-name <stackName>
227
227
  ```
228
228
 
229
- _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/init.ts)_
229
+ _See code: [src/commands/blueprints/init.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/init.ts)_
230
230
 
231
231
  ## `sanity-run blueprints logs`
232
232
 
@@ -248,7 +248,7 @@ EXAMPLES
248
248
  $ sanity-run blueprints logs --watch
249
249
  ```
250
250
 
251
- _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/logs.ts)_
251
+ _See code: [src/commands/blueprints/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/logs.ts)_
252
252
 
253
253
  ## `sanity-run blueprints plan`
254
254
 
@@ -265,7 +265,7 @@ EXAMPLES
265
265
  $ sanity-run blueprints plan
266
266
  ```
267
267
 
268
- _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/plan.ts)_
268
+ _See code: [src/commands/blueprints/plan.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/plan.ts)_
269
269
 
270
270
  ## `sanity-run blueprints stacks`
271
271
 
@@ -287,7 +287,7 @@ EXAMPLES
287
287
  $ sanity-run blueprints stacks --project-id <projectId>
288
288
  ```
289
289
 
290
- _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/blueprints/stacks.ts)_
290
+ _See code: [src/commands/blueprints/stacks.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/blueprints/stacks.ts)_
291
291
 
292
292
  ## `sanity-run functions dev`
293
293
 
@@ -307,7 +307,7 @@ EXAMPLES
307
307
  $ sanity-run functions dev --port 8974
308
308
  ```
309
309
 
310
- _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/functions/dev.ts)_
310
+ _See code: [src/commands/functions/dev.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/functions/dev.ts)_
311
311
 
312
312
  ## `sanity-run functions env add NAME KEY VALUE`
313
313
 
@@ -329,7 +329,7 @@ EXAMPLES
329
329
  $ sanity-run functions env add MyFunction API_URL https://api.example.com/
330
330
  ```
331
331
 
332
- _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/functions/env/add.ts)_
332
+ _See code: [src/commands/functions/env/add.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/functions/env/add.ts)_
333
333
 
334
334
  ## `sanity-run functions env list NAME`
335
335
 
@@ -349,7 +349,7 @@ EXAMPLES
349
349
  $ sanity-run functions env list MyFunction
350
350
  ```
351
351
 
352
- _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/functions/env/list.ts)_
352
+ _See code: [src/commands/functions/env/list.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/functions/env/list.ts)_
353
353
 
354
354
  ## `sanity-run functions env remove NAME KEY`
355
355
 
@@ -370,7 +370,7 @@ EXAMPLES
370
370
  $ sanity-run functions env remove MyFunction API_URL
371
371
  ```
372
372
 
373
- _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/functions/env/remove.ts)_
373
+ _See code: [src/commands/functions/env/remove.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/functions/env/remove.ts)_
374
374
 
375
375
  ## `sanity-run functions logs NAME`
376
376
 
@@ -404,7 +404,7 @@ EXAMPLES
404
404
  $ sanity-run functions logs <name> --delete
405
405
  ```
406
406
 
407
- _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/functions/logs.ts)_
407
+ _See code: [src/commands/functions/logs.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/functions/logs.ts)_
408
408
 
409
409
  ## `sanity-run functions test NAME`
410
410
 
@@ -439,7 +439,7 @@ EXAMPLES
439
439
  $ sanity-run functions test <name> --data '{ "id": 1 }' --timeout 60
440
440
  ```
441
441
 
442
- _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v10.4.0/src/commands/functions/test.ts)_
442
+ _See code: [src/commands/functions/test.ts](https://github.com/sanity-io/runtime-cli/blob/v10.5.0/src/commands/functions/test.ts)_
443
443
 
444
444
  ## `sanity-run help [COMMAND]`
445
445
 
@@ -1,4 +1,5 @@
1
- import type { BlueprintParserError, LocalBlueprint, Resource } from '../../utils/types.js';
1
+ import { type Blueprint } from '@sanity/blueprints-parser';
2
+ import type { BlueprintParserError, Resource } from '../../utils/types.js';
2
3
  export { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR } from '../../config.js';
3
4
  declare const SUPPORTED_FILE_EXTENSIONS: readonly [".json", ".js", ".mjs", ".ts"];
4
5
  type BlueprintFileExtension = (typeof SUPPORTED_FILE_EXTENSIONS)[number];
@@ -14,27 +15,24 @@ export type BlueprintModule = ((args?: unknown) => Record<string, unknown>) & {
14
15
  projectId?: string;
15
16
  stackId?: string;
16
17
  };
18
+ type FileInfo = {
19
+ blueprintFilePath: string;
20
+ fileName: string;
21
+ extension: BlueprintFileExtension;
22
+ };
17
23
  /**
18
24
  * Finds the blueprint file in the given path or current working directory
19
25
  * @param blueprintPath - The path of the blueprint file or directory
20
26
  * @returns The path, file name, and extension of the blueprint file
21
27
  */
22
- export declare function findBlueprintFile(blueprintPath?: string): {
23
- blueprintFilePath: string;
24
- fileName: string;
25
- extension: BlueprintFileExtension;
26
- } | null;
28
+ export declare function findBlueprintFile(blueprintPath?: string): FileInfo | null;
27
29
  /**
28
30
  * Result of the blueprint read operation
29
31
  */
30
32
  export interface ReadBlueprintResult {
31
- fileInfo: {
32
- blueprintFilePath: string;
33
- fileName: string;
34
- extension: string;
35
- };
36
- rawBlueprint: LocalBlueprint;
37
- parsedBlueprint: LocalBlueprint;
33
+ fileInfo: FileInfo;
34
+ rawBlueprint: Record<string, unknown>;
35
+ parsedBlueprint: Blueprint;
38
36
  errors: BlueprintParserError[];
39
37
  configPath?: string;
40
38
  projectId?: string;
@@ -48,14 +46,14 @@ export interface ReadBlueprintResult {
48
46
  export declare function readLocalBlueprint(blueprintPath?: string): Promise<ReadBlueprintResult>;
49
47
  export declare function writeBlueprintToDisk({ blueprintFilePath, jsonContent, }: {
50
48
  blueprintFilePath: string;
51
- jsonContent?: LocalBlueprint;
49
+ jsonContent?: Blueprint;
52
50
  }): string;
53
51
  export declare function writeOrUpdateNodeDependency({ blueprintFilePath, dependency, }: {
54
52
  blueprintFilePath: string;
55
53
  dependency: string;
56
54
  }): Promise<void>;
57
- export declare function readConfigFile(blueprintFilePath?: string | undefined): {
58
- configPath?: string;
55
+ export declare function readConfigFile(blueprintFilePath: string): {
56
+ configPath: string;
59
57
  projectId?: string;
60
58
  stackId?: string;
61
59
  } | null;
@@ -71,11 +69,3 @@ export declare function addResourceToBlueprint({ blueprintFilePath, resource, }:
71
69
  blueprintFilePath?: string;
72
70
  resource: Resource;
73
71
  }): Resource | undefined;
74
- export declare function updateBlueprintMetadata({ blueprintFilePath, metadata, }: {
75
- blueprintFilePath?: string;
76
- metadata: LocalBlueprint['metadata'];
77
- }): void;
78
- export declare function updateBlueprintValues({ blueprintFilePath, values, }: {
79
- blueprintFilePath: string;
80
- values: LocalBlueprint['values'];
81
- }): void;
@@ -1,13 +1,13 @@
1
1
  import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
2
2
  import { basename, dirname, extname, join } from 'node:path';
3
3
  import { cwd, env } from 'node:process';
4
+ import blueprintParserValidator from '@sanity/blueprints-parser';
4
5
  import { findUpSync } from 'find-up';
5
6
  import { createJiti } from 'jiti';
6
7
  import { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR } from '../../config.js';
7
8
  import { getLatestNpmVersion } from '../../utils/other/npmjs.js';
8
9
  import { isLocalFunctionResource } from '../../utils/types.js';
9
10
  import { validateFunctionResource } from '../../utils/validate/resource.js';
10
- import { blueprintParserValidator } from '../../utils/vendor/parser-validator.js';
11
11
  export { BLUEPRINT_CONFIG_FILE, BLUEPRINT_CONFIG_VERSION, BLUEPRINT_DIR } from '../../config.js';
12
12
  const SUPPORTED_FILE_EXTENSIONS = ['.json', '.js', '.mjs', '.ts'];
13
13
  let SUPPORTED_FILE_NAMES = SUPPORTED_FILE_EXTENSIONS.map((ext) => `blueprint${ext}`);
@@ -128,11 +128,14 @@ export async function readLocalBlueprint(blueprintPath) {
128
128
  throw Error(`Blueprint ${fileName} must export a default function`);
129
129
  }
130
130
  }
131
+ if (typeof rawBlueprint === 'undefined') {
132
+ throw Error('Unable to read Blueprint');
133
+ }
131
134
  const parserResult = blueprintParserValidator(rawBlueprint);
132
- const parsedBlueprint = parserResult.blueprint;
133
- const errors = parserResult.errors || [];
135
+ const parsedBlueprint = parserResult.result === 'valid' ? parserResult.blueprint : undefined;
136
+ const errors = parserResult.result !== 'valid' ? parserResult.errors : [];
134
137
  // further validation - remove once validator is updated
135
- if (parsedBlueprint.resources) {
138
+ if (parsedBlueprint?.resources) {
136
139
  // validate function resources
137
140
  const functionResources = parsedBlueprint.resources.filter(isLocalFunctionResource);
138
141
  const fnErrors = functionResources.map((r) => validateFunctionResource(r));
@@ -160,12 +163,13 @@ export async function readLocalBlueprint(blueprintPath) {
160
163
  stackId = `ST-${projectId}`;
161
164
  return {
162
165
  fileInfo: { blueprintFilePath: foundFilePath, fileName, extension },
163
- rawBlueprint: rawBlueprint,
166
+ rawBlueprint,
164
167
  errors,
165
168
  projectId,
166
169
  stackId,
167
170
  configPath,
168
- parsedBlueprint,
171
+ // fallback to the raw blueprint if the parser found errors
172
+ parsedBlueprint: parsedBlueprint || rawBlueprint,
169
173
  };
170
174
  }
171
175
  export function writeBlueprintToDisk({ blueprintFilePath, jsonContent = JSON_BLUEPRINT_CONTENT, }) {
@@ -219,17 +223,15 @@ export async function writeOrUpdateNodeDependency({ blueprintFilePath, dependenc
219
223
  writeFileSync(packageJsonPath, JSON.stringify(packageJsonObject, null, 2));
220
224
  }
221
225
  export function readConfigFile(blueprintFilePath) {
222
- if (blueprintFilePath) {
223
- const blueprintDir = dirname(blueprintFilePath);
224
- const configPath = join(blueprintDir, BLUEPRINT_DIR, BLUEPRINT_CONFIG_FILE);
225
- if (existsSync(configPath)) {
226
- try {
227
- const config = JSON.parse(readFileSync(configPath, 'utf8'));
228
- return { configPath, ...config };
229
- }
230
- catch {
231
- return null;
232
- }
226
+ const blueprintDir = dirname(blueprintFilePath);
227
+ const configPath = join(blueprintDir, BLUEPRINT_DIR, BLUEPRINT_CONFIG_FILE);
228
+ if (existsSync(configPath)) {
229
+ try {
230
+ const config = JSON.parse(readFileSync(configPath, 'utf8'));
231
+ return { configPath, ...config };
232
+ }
233
+ catch {
234
+ return null;
233
235
  }
234
236
  }
235
237
  const configFilePath = join(cwd(), BLUEPRINT_DIR, BLUEPRINT_CONFIG_FILE);
@@ -296,29 +298,3 @@ export function addResourceToBlueprint({ blueprintFilePath, resource, }) {
296
298
  }
297
299
  return resource;
298
300
  }
299
- export function updateBlueprintMetadata({ blueprintFilePath, metadata, }) {
300
- const blueprintFile = findBlueprintFile(blueprintFilePath);
301
- if (!blueprintFile)
302
- throw Error('Could not find Blueprint file');
303
- const { blueprintFilePath: foundPath, extension } = blueprintFile;
304
- if (extension === '.json') {
305
- const blueprintString = readFileSync(foundPath, 'utf8').toString();
306
- const blueprint = JSON.parse(blueprintString);
307
- blueprint.metadata = blueprint.metadata || {};
308
- blueprint.metadata = { ...blueprint.metadata, ...metadata };
309
- writeFileSync(foundPath, JSON.stringify(blueprint, null, 2));
310
- }
311
- }
312
- export function updateBlueprintValues({ blueprintFilePath, values, }) {
313
- const blueprintFile = findBlueprintFile(blueprintFilePath);
314
- if (!blueprintFile)
315
- throw Error('Could not find Blueprint file');
316
- const { blueprintFilePath: foundPath, extension } = blueprintFile;
317
- if (extension === '.json') {
318
- const blueprintString = readFileSync(foundPath, 'utf8').toString();
319
- const blueprint = JSON.parse(blueprintString);
320
- blueprint.values = blueprint.values || {};
321
- blueprint.values = { ...blueprint.values, ...values };
322
- writeFileSync(foundPath, JSON.stringify(blueprint, null, 2));
323
- }
324
- }
@@ -5,17 +5,16 @@ export * as projects from '../sanity/projects.js';
5
5
  export * as assets from './assets.js';
6
6
  export * as blueprint from './blueprint.js';
7
7
  export * as logs from './logs.js';
8
- export * as operations from './operations.js';
9
8
  export * as resources from './resources.js';
10
9
  export * as stacks from './stacks.js';
11
10
  import type { BlueprintParserError, Stack } from '../../utils/types.js';
12
- import { readLocalBlueprint } from './blueprint.js';
11
+ import { type ReadBlueprintResult } from './blueprint.js';
13
12
  export type BlueprintIssue = {
14
13
  code: 'NO_STACK_ID' | 'NO_PROJECT_ID' | 'NO_STACK' | 'PARSE_ERROR';
15
14
  message: string;
16
15
  errors?: BlueprintParserError[];
17
16
  };
18
- type LocalBlueprintWithIds = Awaited<ReturnType<typeof readLocalBlueprint>> & {
17
+ type LocalBlueprintWithIds = ReadBlueprintResult & {
19
18
  projectId: string;
20
19
  stackId: string;
21
20
  };
@@ -25,7 +24,7 @@ type BlueprintSuccess = {
25
24
  issues?: never;
26
25
  };
27
26
  type BlueprintFailure = {
28
- localBlueprint: Awaited<ReturnType<typeof readLocalBlueprint>>;
27
+ localBlueprint: ReadBlueprintResult;
29
28
  issues: BlueprintIssue[];
30
29
  deployedStack?: never;
31
30
  };
@@ -5,7 +5,6 @@ export * as projects from '../sanity/projects.js';
5
5
  export * as assets from './assets.js';
6
6
  export * as blueprint from './blueprint.js';
7
7
  export * as logs from './logs.js';
8
- export * as operations from './operations.js';
9
8
  export * as resources from './resources.js';
10
9
  export * as stacks from './stacks.js';
11
10
  import { readLocalBlueprint } from './blueprint.js';
@@ -0,0 +1,24 @@
1
+ import type { AuthParams, BlueprintLog } from '../../utils/types.js';
2
+ export interface LogStreamingConfig {
3
+ stackId: string;
4
+ after?: string;
5
+ auth: AuthParams;
6
+ showBanner?: boolean;
7
+ log: (message: string) => void;
8
+ }
9
+ export interface StreamLogsOptions {
10
+ stackId: string;
11
+ after?: string;
12
+ auth: AuthParams;
13
+ onLog: (log: BlueprintLog) => void;
14
+ onOpen: () => void;
15
+ onError: (error: string) => void;
16
+ }
17
+ export declare function streamLogs({ stackId, after, auth, onLog, onOpen, onError, }: StreamLogsOptions): () => void;
18
+ export declare function isNewerLog(log: BlueprintLog, timestamp: number): boolean;
19
+ /**
20
+ * Sets up log streaming for operations like deploy or destroy with spinner integration
21
+ * @param config Configuration for log streaming
22
+ * @returns A cleanup function for closing the log stream
23
+ */
24
+ export declare function setupLogStreaming(config: LogStreamingConfig): Promise<() => void>;
@@ -0,0 +1,96 @@
1
+ import chalk from 'chalk';
2
+ import { EventSource } from 'eventsource';
3
+ import { formatLogEntry } from '../../utils/display/logs-formatting.js';
4
+ import getHeaders from '../../utils/get-headers.js';
5
+ import { logsUrl } from './logs.js';
6
+ export function streamLogs({ stackId, after, auth, onLog, onOpen, onError, }) {
7
+ const url = new URL(`${logsUrl}/stream`);
8
+ url.searchParams.append('stackId', stackId);
9
+ if (after)
10
+ url.searchParams.append('after', after);
11
+ const headers = getHeaders(auth);
12
+ const eventSource = new EventSource(url.toString(), {
13
+ fetch: (input, init) => fetch(input, {
14
+ ...init,
15
+ headers: {
16
+ ...init?.headers,
17
+ ...headers,
18
+ },
19
+ }),
20
+ });
21
+ eventSource.onopen = onOpen;
22
+ eventSource.onmessage = (event) => {
23
+ try {
24
+ const log = JSON.parse(event.data);
25
+ onLog(log);
26
+ }
27
+ catch (err) {
28
+ onError(`Failed to parse log data: ${err instanceof Error ? err.message : String(err)}`);
29
+ }
30
+ };
31
+ eventSource.addEventListener('logs', (event) => {
32
+ try {
33
+ const logData = JSON.parse(event.data);
34
+ // usually an array
35
+ if (Array.isArray(logData)) {
36
+ for (const log of logData)
37
+ onLog(log);
38
+ }
39
+ else {
40
+ onLog(logData);
41
+ }
42
+ }
43
+ catch (err) {
44
+ console.error('Error parsing logs event:', err);
45
+ }
46
+ });
47
+ eventSource.onerror = () => {
48
+ onError('Connection to log stream failed or was closed');
49
+ if (eventSource.readyState === eventSource.CLOSED) {
50
+ console.log('Connection is CLOSED');
51
+ }
52
+ else if (eventSource.readyState === eventSource.CONNECTING) {
53
+ console.log('Connection is attempting to reconnect...');
54
+ return; // Don't close if trying to reconnect
55
+ }
56
+ eventSource.close();
57
+ };
58
+ return () => {
59
+ eventSource.close();
60
+ };
61
+ }
62
+ // Check if a log is newer than a given timestamp
63
+ export function isNewerLog(log, timestamp) {
64
+ const logTimestamp = new Date(log.timestamp).getTime();
65
+ return logTimestamp > timestamp;
66
+ }
67
+ /**
68
+ * Sets up log streaming for operations like deploy or destroy with spinner integration
69
+ * @param config Configuration for log streaming
70
+ * @returns A cleanup function for closing the log stream
71
+ */
72
+ export async function setupLogStreaming(config) {
73
+ const { stackId, auth, log, showBanner, after } = config;
74
+ let newestTimestamp = Date.now();
75
+ const onLogReceived = (logEntry) => {
76
+ if (!isNewerLog(logEntry, newestTimestamp))
77
+ return;
78
+ newestTimestamp = new Date(logEntry.timestamp).getTime();
79
+ log(formatLogEntry(logEntry, true));
80
+ };
81
+ const onStreamOpen = () => {
82
+ if (showBanner)
83
+ log(`Streaming logs... ${chalk.bold('ctrl+c')} to cancel`);
84
+ };
85
+ const onStreamError = (error) => {
86
+ log(`${chalk.yellow('Stream error:')} ${error}`);
87
+ };
88
+ return streamLogs({
89
+ stackId,
90
+ after,
91
+ auth,
92
+ onLog: onLogReceived,
93
+ onOpen: onStreamOpen,
94
+ onError: onStreamError,
95
+ });
96
+ }
@@ -5,15 +5,4 @@ export declare function getLogs(stackId: string, auth: AuthParams): Promise<{
5
5
  ok: boolean;
6
6
  error: string | null;
7
7
  }>;
8
- export declare function findNewestLogTimestamp(logs: BlueprintLog[]): number;
9
- export declare function isNewerLog(log: BlueprintLog, timestamp: number): boolean;
10
8
  export declare function getRecentLogs(logs: BlueprintLog[], limit?: number): BlueprintLog[];
11
- export interface StreamLogsOptions {
12
- stackId: string;
13
- after?: string;
14
- auth: AuthParams;
15
- onLog: (log: BlueprintLog) => void;
16
- onOpen: () => void;
17
- onError: (error: string) => void;
18
- }
19
- export declare function streamLogs({ stackId, after, auth, onLog, onOpen, onError, }: StreamLogsOptions): () => void;
@@ -1,4 +1,3 @@
1
- import { EventSource } from 'eventsource';
2
1
  import config from '../../config.js';
3
2
  import getHeaders from '../../utils/get-headers.js';
4
3
  const { apiUrl } = config;
@@ -17,82 +16,8 @@ export async function getLogs(stackId, auth) {
17
16
  logs: response.ok ? result : [],
18
17
  };
19
18
  }
20
- // Process logs to find the newest timestamp
21
- export function findNewestLogTimestamp(logs) {
22
- let newestTimestamp = 0;
23
- if (logs.length > 0) {
24
- for (const log of logs) {
25
- const timestamp = new Date(log.timestamp).getTime();
26
- if (timestamp > newestTimestamp) {
27
- newestTimestamp = timestamp;
28
- }
29
- }
30
- }
31
- return newestTimestamp;
32
- }
33
- // Check if a log is newer than a given timestamp
34
- export function isNewerLog(log, timestamp) {
35
- const logTimestamp = new Date(log.timestamp).getTime();
36
- return logTimestamp > timestamp;
37
- }
38
19
  // Get most recent logs, up to a limit
39
20
  export function getRecentLogs(logs, limit = 10) {
40
21
  const sortedLogs = [...logs].sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
41
22
  return sortedLogs.slice(-limit);
42
23
  }
43
- export function streamLogs({ stackId, after, auth, onLog, onOpen, onError, }) {
44
- const url = new URL(`${logsUrl}/stream`);
45
- url.searchParams.append('stackId', stackId);
46
- if (after)
47
- url.searchParams.append('after', after);
48
- const headers = getHeaders(auth);
49
- const eventSource = new EventSource(url.toString(), {
50
- fetch: (input, init) => fetch(input, {
51
- ...init,
52
- headers: {
53
- ...init?.headers,
54
- ...headers,
55
- },
56
- }),
57
- });
58
- eventSource.onopen = onOpen;
59
- eventSource.onmessage = (event) => {
60
- try {
61
- const log = JSON.parse(event.data);
62
- onLog(log);
63
- }
64
- catch (err) {
65
- onError(`Failed to parse log data: ${err instanceof Error ? err.message : String(err)}`);
66
- }
67
- };
68
- eventSource.addEventListener('logs', (event) => {
69
- try {
70
- const logData = JSON.parse(event.data);
71
- // usually an array
72
- if (Array.isArray(logData)) {
73
- for (const log of logData)
74
- onLog(log);
75
- }
76
- else {
77
- onLog(logData);
78
- }
79
- }
80
- catch (err) {
81
- console.error('Error parsing logs event:', err);
82
- }
83
- });
84
- eventSource.onerror = () => {
85
- onError('Connection to log stream failed or was closed');
86
- if (eventSource.readyState === eventSource.CLOSED) {
87
- console.log('Connection is CLOSED');
88
- }
89
- else if (eventSource.readyState === eventSource.CONNECTING) {
90
- console.log('Connection is attempting to reconnect...');
91
- return; // Don't close if trying to reconnect
92
- }
93
- eventSource.close();
94
- };
95
- return () => {
96
- eventSource.close();
97
- };
98
- }
@@ -1,6 +1,6 @@
1
1
  import type { Interfaces } from '@oclif/core';
2
2
  import { Command } from '@oclif/core';
3
- import type { readLocalBlueprint } from './actions/blueprints/blueprint.js';
3
+ import type { ReadBlueprintResult } from './actions/blueprints/blueprint.js';
4
4
  import type { AuthParams, Stack } from './utils/types.js';
5
5
  export type Flags<T extends typeof Command> = Interfaces.InferredFlags<(typeof BlueprintCommand)['baseFlags'] & T['flags']>;
6
6
  export type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
@@ -11,7 +11,7 @@ export type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
11
11
  */
12
12
  export declare abstract class BlueprintCommand<T extends typeof Command> extends Command {
13
13
  protected sanityToken: string;
14
- protected blueprint: Awaited<ReturnType<typeof readLocalBlueprint>>;
14
+ protected blueprint: ReadBlueprintResult;
15
15
  protected flags: Flags<T>;
16
16
  protected args: Args<T>;
17
17
  init(): Promise<void>;
@@ -47,13 +47,13 @@ export default class InitCommand extends Command {
47
47
  };
48
48
  async run() {
49
49
  const { args, flags } = await this.parse(InitCommand);
50
- const { token, error: tokenErr } = await validTokenOrErrorMessage();
51
- if (tokenErr)
52
- this.error(tokenErr.message);
50
+ const result = await validTokenOrErrorMessage();
51
+ if (!result.ok)
52
+ this.error(result.error.message);
53
53
  const { success, error } = await blueprintInitCore({
54
54
  bin: this.config.bin,
55
55
  log: (message) => this.log(message),
56
- token,
56
+ token: result.value,
57
57
  args,
58
58
  flags,
59
59
  });
@@ -12,7 +12,7 @@ const generateFunctionBlueprintResourceTemplate = (fnName, eventNames) => `
12
12
  export default defineBlueprint({
13
13
  resources: [
14
14
  // ...
15
- defineDocumentFunction({name: '${fnName}', event: {on: [${eventNames.map((e) => `'${e}'`).join(', ')}]}}), // ← add this line
15
+ defineDocumentFunction({name: '${fnName}', event: {on: [${eventNames.map((e) => `'${e.replace('document-', '')}'`).join(', ')}]}}), // ← add this line
16
16
  ],
17
17
  })
18
18
  `;
@@ -2,8 +2,8 @@ import { setTimeout } from 'node:timers/promises';
2
2
  import chalk from 'chalk';
3
3
  import ora from 'ora';
4
4
  import { stashAsset } from '../../actions/blueprints/assets.js';
5
+ import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
5
6
  import { getStack, updateStack } from '../../actions/blueprints/stacks.js';
6
- import { setupLogStreaming } from '../../utils/display/blueprints-logs-streaming.js';
7
7
  import { niceId } from '../../utils/display/presenters.js';
8
8
  import { isLocalFunctionResource } from '../../utils/types.js';
9
9
  export async function blueprintDeployCore(options) {
@@ -2,8 +2,8 @@ import { setTimeout } from 'node:timers/promises';
2
2
  import chalk from 'chalk';
3
3
  import inquirer from 'inquirer';
4
4
  import ora from 'ora';
5
+ import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
5
6
  import { destroyStack, getStack } from '../../actions/blueprints/stacks.js';
6
- import { setupLogStreaming } from '../../utils/display/blueprints-logs-streaming.js';
7
7
  import { niceId } from '../../utils/display/presenters.js';
8
8
  export async function blueprintDestroyCore(options) {
9
9
  const { log, token, blueprint, flags } = options;
@@ -1,8 +1,8 @@
1
1
  import chalk from 'chalk';
2
2
  import ora from 'ora';
3
3
  import { getLogs, getRecentLogs } from '../../actions/blueprints/logs.js';
4
+ import { setupLogStreaming } from '../../actions/blueprints/logs-streaming.js';
4
5
  import { formatTitle } from '../../utils/display/blueprints-formatting.js';
5
- import { setupLogStreaming } from '../../utils/display/blueprints-logs-streaming.js';
6
6
  import { formatLogEntry, formatLogsByDay, organizeLogsByDay, } from '../../utils/display/logs-formatting.js';
7
7
  import { niceId } from '../../utils/display/presenters.js';
8
8
  export async function blueprintLogsCore(options) {