@farcaster/snap 1.3.3 → 1.4.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.
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { POST_GRID_TAP_KEY, PAGE_ROOT_TYPE, ELEMENT_TYPE, MEDIA_TYPE, DEFAULT_THEME_ACCENT, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, PALETTE_COLOR, PALETTE_COLOR_VALUES, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, type PaletteColor, } from "./constants.js";
2
- export { rootSchema, firstPageRootSchema, payloadSchema, type SnapAction, type SnapContext, type SnapResponse, type SnapResponseInput, type SnapFunction, type SnapPayload, } from "./schemas.js";
3
- export { validatePage, validateFirstPage, type ValidationResult, } from "./validator.js";
2
+ export { snapResponseSchema, firstPageResponseSchema, payloadSchema, type SnapAction, type SnapContext, type SnapResponse, type SnapHandlerResult, type SnapFunction, type SnapPayload, } from "./schemas.js";
3
+ export { validateSnapResponse, validateFirstPageResponse, type ValidationResult, } from "./validator.js";
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { POST_GRID_TAP_KEY, PAGE_ROOT_TYPE, ELEMENT_TYPE, MEDIA_TYPE, DEFAULT_THEME_ACCENT, DEFAULT_LIST_STYLE, DEFAULT_SLIDER_STEP, PALETTE_COLOR, PALETTE_COLOR_VALUES, PALETTE_LIGHT_HEX, PALETTE_DARK_HEX, } from "./constants.js";
2
- export { rootSchema, firstPageRootSchema, payloadSchema, } from "./schemas.js";
3
- export { validatePage, validateFirstPage, } from "./validator.js";
2
+ export { snapResponseSchema, firstPageResponseSchema, payloadSchema, } from "./schemas.js";
3
+ export { validateSnapResponse, validateFirstPageResponse, } from "./validator.js";
package/dist/schemas.d.ts CHANGED
@@ -13,6 +13,7 @@ declare const buttonSchema: z.ZodObject<{
13
13
  secondary: "secondary";
14
14
  }>>;
15
15
  }, z.core.$strip>;
16
+ export type Button = z.infer<typeof buttonSchema>;
16
17
  /** Any single page element, including media and `group` */
17
18
  declare const elementSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
18
19
  type: z.ZodLiteral<"text">;
@@ -326,6 +327,7 @@ declare const elementSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
326
327
  accent: "accent";
327
328
  }>>;
328
329
  }, z.core.$strip>], "type">;
330
+ export type Element = z.infer<typeof elementSchema>;
329
331
  declare const elementsSchema: z.ZodObject<{
330
332
  type: z.ZodLiteral<"stack">;
331
333
  children: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -641,10 +643,8 @@ declare const elementsSchema: z.ZodObject<{
641
643
  }>>;
642
644
  }, z.core.$strip>], "type">>;
643
645
  }, z.core.$strict>;
644
- export type Button = z.infer<typeof buttonSchema>;
645
- export type Element = z.infer<typeof elementSchema>;
646
646
  export type Elements = z.infer<typeof elementsSchema>;
647
- export declare const rootSchema: z.ZodObject<{
647
+ export declare const snapResponseSchema: z.ZodObject<{
648
648
  version: z.ZodLiteral<"1.0">;
649
649
  page: z.ZodObject<{
650
650
  theme: z.ZodDefault<z.ZodOptional<z.ZodObject<{
@@ -998,7 +998,9 @@ export declare const rootSchema: z.ZodObject<{
998
998
  }, z.core.$strip>>>;
999
999
  }, z.core.$strict>;
1000
1000
  }, z.core.$strict>;
1001
- export declare const firstPageRootSchema: z.ZodObject<{
1001
+ export type SnapResponse = z.infer<typeof snapResponseSchema>;
1002
+ export type SnapHandlerResult = z.input<typeof snapResponseSchema>;
1003
+ export declare const firstPageResponseSchema: z.ZodObject<{
1002
1004
  version: z.ZodLiteral<"1.0">;
1003
1005
  page: z.ZodObject<{
1004
1006
  theme: z.ZodDefault<z.ZodOptional<z.ZodObject<{
@@ -1352,6 +1354,7 @@ export declare const firstPageRootSchema: z.ZodObject<{
1352
1354
  }, z.core.$strip>>>;
1353
1355
  }, z.core.$strict>;
1354
1356
  }, z.core.$strict>;
1357
+ export type FirstPageResponse = z.infer<typeof firstPageResponseSchema>;
1355
1358
  export declare const payloadSchema: z.ZodObject<{
1356
1359
  fid: z.ZodNumber;
1357
1360
  inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodObject<{
@@ -1361,27 +1364,40 @@ export declare const payloadSchema: z.ZodObject<{
1361
1364
  button_index: z.ZodNumber;
1362
1365
  timestamp: z.ZodNumber;
1363
1366
  }, z.core.$strict>;
1364
- export type SnapResponse = z.infer<typeof rootSchema>;
1365
- export type SnapResponseInput = z.input<typeof rootSchema>;
1366
- export type SnapPage = SnapResponse["page"];
1367
1367
  export type SnapPayload = z.infer<typeof payloadSchema>;
1368
+ export declare const ACTION_TYPE_GET: "get";
1369
+ export declare const ACTION_TYPE_POST: "post";
1370
+ declare const snapGetActionSchema: z.ZodObject<{
1371
+ type: z.ZodLiteral<"get">;
1372
+ }, z.core.$strip>;
1373
+ export type SnapGetAction = z.infer<typeof snapGetActionSchema>;
1368
1374
  declare const snapPostActionSchema: z.ZodObject<{
1369
1375
  fid: z.ZodNumber;
1370
1376
  inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodObject<{
1371
1377
  row: z.ZodNumber;
1372
1378
  col: z.ZodNumber;
1373
1379
  }, z.core.$strict>]>>>;
1380
+ button_index: z.ZodNumber;
1374
1381
  timestamp: z.ZodNumber;
1375
1382
  type: z.ZodLiteral<"post">;
1376
- buttonIndex: z.ZodNumber;
1377
1383
  }, z.core.$strict>;
1378
1384
  export type SnapPostAction = z.infer<typeof snapPostActionSchema>;
1379
- export type SnapAction = {
1380
- type: "get";
1381
- } | SnapPostAction;
1385
+ export declare const snapActionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
1386
+ type: z.ZodLiteral<"get">;
1387
+ }, z.core.$strip>, z.ZodObject<{
1388
+ fid: z.ZodNumber;
1389
+ inputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodObject<{
1390
+ row: z.ZodNumber;
1391
+ col: z.ZodNumber;
1392
+ }, z.core.$strict>]>>>;
1393
+ button_index: z.ZodNumber;
1394
+ timestamp: z.ZodNumber;
1395
+ type: z.ZodLiteral<"post">;
1396
+ }, z.core.$strict>], "type">;
1397
+ export type SnapAction = z.infer<typeof snapActionSchema>;
1382
1398
  export type SnapContext = {
1383
1399
  action: SnapAction;
1384
1400
  request: Request;
1385
1401
  };
1386
- export type SnapFunction = (ctx: SnapContext) => Promise<SnapResponseInput>;
1402
+ export type SnapFunction = (ctx: SnapContext) => Promise<SnapHandlerResult>;
1387
1403
  export {};
package/dist/schemas.js CHANGED
@@ -368,7 +368,7 @@ const elementsSchema = z
368
368
  }),
369
369
  })
370
370
  .strict();
371
- export const rootSchema = z
371
+ export const snapResponseSchema = z
372
372
  .object({
373
373
  version: z.literal(SPEC_VERSION),
374
374
  page: z
@@ -402,9 +402,9 @@ export const rootSchema = z
402
402
  })
403
403
  .strict();
404
404
  // extra constraints for the first page to make it look nicer
405
- export const firstPageRootSchema = rootSchema.superRefine((root, ctx) => {
406
- const body = root.page.elements.children;
407
- const hasTextTitleOrBody = body.some((el) => el.type === ELEMENT_TYPE.text &&
405
+ export const firstPageResponseSchema = snapResponseSchema.superRefine((response, ctx) => {
406
+ const elements = response.page.elements.children;
407
+ const hasTextTitleOrBody = elements.some((el) => el.type === ELEMENT_TYPE.text &&
408
408
  (el.style === TEXT_STYLE.title || el.style === TEXT_STYLE.body));
409
409
  if (!hasTextTitleOrBody) {
410
410
  ctx.addIssue({
@@ -413,8 +413,8 @@ export const firstPageRootSchema = rootSchema.superRefine((root, ctx) => {
413
413
  path: ["page", "elements", "children"],
414
414
  });
415
415
  }
416
- const hasInteractive = body.some((el) => INTERACTIVE_ELEMENT_TYPES.includes(el.type));
417
- const hasMedia = body.some((el) => MEDIA_ELEMENT_TYPES.includes(el.type));
416
+ const hasInteractive = elements.some((el) => INTERACTIVE_ELEMENT_TYPES.includes(el.type));
417
+ const hasMedia = elements.some((el) => MEDIA_ELEMENT_TYPES.includes(el.type));
418
418
  if (!hasInteractive && !hasMedia) {
419
419
  ctx.addIssue({
420
420
  code: "custom",
@@ -443,10 +443,17 @@ export const payloadSchema = z
443
443
  timestamp: z.number().int(),
444
444
  })
445
445
  .strict();
446
+ export const ACTION_TYPE_GET = "get";
447
+ export const ACTION_TYPE_POST = "post";
448
+ const snapGetActionSchema = z.object({
449
+ type: z.literal(ACTION_TYPE_GET),
450
+ });
446
451
  const snapPostActionSchema = payloadSchema
447
- .omit({ button_index: true })
448
452
  .extend({
449
- type: z.literal("post"),
450
- buttonIndex: payloadSchema.shape.button_index,
453
+ type: z.literal(ACTION_TYPE_POST),
451
454
  })
452
455
  .strict();
456
+ export const snapActionSchema = z.discriminatedUnion("type", [
457
+ snapGetActionSchema,
458
+ snapPostActionSchema,
459
+ ]);
@@ -1,4 +1,4 @@
1
- import { payloadSchema } from "../schemas.js";
1
+ import { ACTION_TYPE_GET, ACTION_TYPE_POST, payloadSchema, } from "../schemas.js";
2
2
  import { decodePayload, verifyJFSRequestBody } from "./verify.js";
3
3
  import { z } from "zod";
4
4
  /** Default replay window per SPEC.md § Replay Protection (5 minutes). */
@@ -26,7 +26,7 @@ export async function parseRequest(request, options = {}) {
26
26
  if (request.method === "GET") {
27
27
  return {
28
28
  success: true,
29
- action: { type: "get" },
29
+ action: { type: ACTION_TYPE_GET },
30
30
  };
31
31
  }
32
32
  const maxSkew = DEFAULT_SNAP_POST_MAX_SKEW_SECONDS;
@@ -81,11 +81,8 @@ export async function parseRequest(request, options = {}) {
81
81
  return {
82
82
  success: true,
83
83
  action: {
84
- type: "post",
85
- fid: body.fid,
86
- inputs: body.inputs,
87
- buttonIndex: body.button_index,
88
- timestamp: body.timestamp,
84
+ type: ACTION_TYPE_POST,
85
+ ...body,
89
86
  },
90
87
  };
91
88
  }
@@ -240,7 +240,7 @@ export declare const snapJsonRenderCatalog: import("@json-render/core").Catalog<
240
240
  snap_post: {
241
241
  description: string;
242
242
  params: z.ZodObject<{
243
- buttonIndex: z.ZodNumber;
243
+ button_index: z.ZodNumber;
244
244
  target: z.ZodString;
245
245
  label: z.ZodOptional<z.ZodString>;
246
246
  style: z.ZodOptional<z.ZodEnum<{
@@ -18,7 +18,7 @@ import { groupProps } from "./group.js";
18
18
  import { stackProps } from "./stack.js";
19
19
  import { actionButtonProps } from "./button.js";
20
20
  const snapPostParams = z.object({
21
- buttonIndex: z.number().int().nonnegative(),
21
+ button_index: z.number().int().nonnegative(),
22
22
  target: z.string(),
23
23
  label: z.string().optional(),
24
24
  style: z.enum(BUTTON_STYLE_VALUES).optional(),
@@ -3,5 +3,5 @@ export type ValidationResult = {
3
3
  valid: boolean;
4
4
  issues: z.core.$ZodIssue[];
5
5
  };
6
- export declare function validatePage(json: unknown): ValidationResult;
7
- export declare function validateFirstPage(json: unknown): ValidationResult;
6
+ export declare function validateSnapResponse(json: unknown): ValidationResult;
7
+ export declare function validateFirstPageResponse(json: unknown): ValidationResult;
package/dist/validator.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { BUTTON_GROUP_STYLE, DEFAULT_BUTTON_LAYOUT, ELEMENT_TYPE, LIMITS, SPACER_SIZE, TEXT_STYLE, } from "./constants.js";
2
- import { firstPageRootSchema, rootSchema, } from "./schemas.js";
2
+ import { firstPageResponseSchema, snapResponseSchema, } from "./schemas.js";
3
3
  /** Not in SPEC — rough px used only for {@link measureHeightBudget}. */
4
4
  const PAGE_HEIGHT_HEURISTIC = {
5
5
  baseChromePx: 32,
@@ -116,8 +116,8 @@ function heightBudgetValidationErrorForRoot(root) {
116
116
  : DEFAULT_BUTTON_LAYOUT;
117
117
  return heightBudgetValidationError(root.page.elements.children, root.page.buttons ?? [], layout);
118
118
  }
119
- export function validatePage(json) {
120
- const parsed = rootSchema.safeParse(json);
119
+ export function validateSnapResponse(json) {
120
+ const parsed = snapResponseSchema.safeParse(json);
121
121
  if (!parsed.success) {
122
122
  return {
123
123
  valid: false,
@@ -130,8 +130,8 @@ export function validatePage(json) {
130
130
  }
131
131
  return { valid: true, issues: [] };
132
132
  }
133
- export function validateFirstPage(json) {
134
- const parsed = firstPageRootSchema.safeParse(json);
133
+ export function validateFirstPageResponse(json) {
134
+ const parsed = firstPageResponseSchema.safeParse(json);
135
135
  if (!parsed.success) {
136
136
  return {
137
137
  valid: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farcaster/snap",
3
- "version": "1.3.3",
3
+ "version": "1.4.0",
4
4
  "description": "Farcaster Snaps 🫰",
5
5
  "repository": {
6
6
  "type": "git",
package/src/index.ts CHANGED
@@ -13,18 +13,18 @@ export {
13
13
  type PaletteColor,
14
14
  } from "./constants";
15
15
  export {
16
- rootSchema,
17
- firstPageRootSchema,
16
+ snapResponseSchema,
17
+ firstPageResponseSchema,
18
18
  payloadSchema,
19
19
  type SnapAction,
20
20
  type SnapContext,
21
21
  type SnapResponse,
22
- type SnapResponseInput,
22
+ type SnapHandlerResult,
23
23
  type SnapFunction,
24
24
  type SnapPayload,
25
25
  } from "./schemas";
26
26
  export {
27
- validatePage,
28
- validateFirstPage,
27
+ validateSnapResponse,
28
+ validateFirstPageResponse,
29
29
  type ValidationResult,
30
30
  } from "./validator";
package/src/schemas.ts CHANGED
@@ -391,6 +391,8 @@ const buttonSchema = z
391
391
  }
392
392
  });
393
393
 
394
+ export type Button = z.infer<typeof buttonSchema>;
395
+
394
396
  /** Child elements allowed inside `group` (no media, no nested group) */
395
397
  const groupChildElementSchema = z.discriminatedUnion("type", [
396
398
  textElementSchema,
@@ -431,6 +433,8 @@ const elementSchema = z.discriminatedUnion("type", [
431
433
  barChartElementSchema,
432
434
  ]);
433
435
 
436
+ export type Element = z.infer<typeof elementSchema>;
437
+
434
438
  const elementsSchema = z
435
439
  .object({
436
440
  type: z.literal(PAGE_ROOT_TYPE.stack),
@@ -443,11 +447,9 @@ const elementsSchema = z
443
447
  })
444
448
  .strict();
445
449
 
446
- export type Button = z.infer<typeof buttonSchema>;
447
- export type Element = z.infer<typeof elementSchema>;
448
450
  export type Elements = z.infer<typeof elementsSchema>;
449
451
 
450
- export const rootSchema = z
452
+ export const snapResponseSchema = z
451
453
  .object({
452
454
  version: z.literal(SPEC_VERSION),
453
455
  page: z
@@ -481,37 +483,48 @@ export const rootSchema = z
481
483
  })
482
484
  .strict();
483
485
 
486
+ // canonical snap response type
487
+ export type SnapResponse = z.infer<typeof snapResponseSchema>;
488
+ // what snap handlers may return (keeps optional fields optional)
489
+ export type SnapHandlerResult = z.input<typeof snapResponseSchema>;
490
+
484
491
  // extra constraints for the first page to make it look nicer
485
- export const firstPageRootSchema = rootSchema.superRefine((root, ctx) => {
486
- const body = root.page.elements.children;
487
-
488
- const hasTextTitleOrBody = body.some(
489
- (el) =>
490
- el.type === ELEMENT_TYPE.text &&
491
- (el.style === TEXT_STYLE.title || el.style === TEXT_STYLE.body),
492
- );
493
- if (!hasTextTitleOrBody) {
494
- ctx.addIssue({
495
- code: "custom",
496
- message:
497
- 'first page must have at least one text element with style "title" or "body"',
498
- path: ["page", "elements", "children"],
499
- });
500
- }
492
+ export const firstPageResponseSchema = snapResponseSchema.superRefine(
493
+ (response, ctx) => {
494
+ const elements = response.page.elements.children;
495
+
496
+ const hasTextTitleOrBody = elements.some(
497
+ (el) =>
498
+ el.type === ELEMENT_TYPE.text &&
499
+ (el.style === TEXT_STYLE.title || el.style === TEXT_STYLE.body),
500
+ );
501
+ if (!hasTextTitleOrBody) {
502
+ ctx.addIssue({
503
+ code: "custom",
504
+ message:
505
+ 'first page must have at least one text element with style "title" or "body"',
506
+ path: ["page", "elements", "children"],
507
+ });
508
+ }
501
509
 
502
- const hasInteractive = body.some((el) =>
503
- INTERACTIVE_ELEMENT_TYPES.includes(el.type),
504
- );
505
- const hasMedia = body.some((el) => MEDIA_ELEMENT_TYPES.includes(el.type));
506
- if (!hasInteractive && !hasMedia) {
507
- ctx.addIssue({
508
- code: "custom",
509
- message:
510
- "first page must have at least one interactive element (button_group, slider, text_input, toggle) or media element (image, grid)",
511
- path: ["page", "elements", "children"],
512
- });
513
- }
514
- });
510
+ const hasInteractive = elements.some((el) =>
511
+ INTERACTIVE_ELEMENT_TYPES.includes(el.type),
512
+ );
513
+ const hasMedia = elements.some((el) =>
514
+ MEDIA_ELEMENT_TYPES.includes(el.type),
515
+ );
516
+ if (!hasInteractive && !hasMedia) {
517
+ ctx.addIssue({
518
+ code: "custom",
519
+ message:
520
+ "first page must have at least one interactive element (button_group, slider, text_input, toggle) or media element (image, grid)",
521
+ path: ["page", "elements", "children"],
522
+ });
523
+ }
524
+ },
525
+ );
526
+
527
+ export type FirstPageResponse = z.infer<typeof firstPageResponseSchema>;
515
528
 
516
529
  const postInputValueSchema = z.union([
517
530
  z.string(),
@@ -535,30 +548,35 @@ export const payloadSchema = z
535
548
  })
536
549
  .strict();
537
550
 
538
- export type SnapResponse = z.infer<typeof rootSchema>;
539
- export type SnapResponseInput = z.input<typeof rootSchema>;
540
- export type SnapPage = SnapResponse["page"];
541
551
  export type SnapPayload = z.infer<typeof payloadSchema>;
542
552
 
553
+ export const ACTION_TYPE_GET = "get" as const;
554
+ export const ACTION_TYPE_POST = "post" as const;
555
+
556
+ const snapGetActionSchema = z.object({
557
+ type: z.literal(ACTION_TYPE_GET),
558
+ });
559
+
560
+ export type SnapGetAction = z.infer<typeof snapGetActionSchema>;
561
+
543
562
  const snapPostActionSchema = payloadSchema
544
- .omit({ button_index: true })
545
563
  .extend({
546
- type: z.literal("post"),
547
- buttonIndex: payloadSchema.shape.button_index,
564
+ type: z.literal(ACTION_TYPE_POST),
548
565
  })
549
566
  .strict();
550
567
 
551
568
  export type SnapPostAction = z.infer<typeof snapPostActionSchema>;
552
569
 
553
- export type SnapAction =
554
- | {
555
- type: "get";
556
- }
557
- | SnapPostAction;
570
+ export const snapActionSchema = z.discriminatedUnion("type", [
571
+ snapGetActionSchema,
572
+ snapPostActionSchema,
573
+ ]);
574
+
575
+ export type SnapAction = z.infer<typeof snapActionSchema>;
558
576
 
559
577
  export type SnapContext = {
560
578
  action: SnapAction;
561
579
  request: Request;
562
580
  };
563
581
 
564
- export type SnapFunction = (ctx: SnapContext) => Promise<SnapResponseInput>;
582
+ export type SnapFunction = (ctx: SnapContext) => Promise<SnapHandlerResult>;
@@ -1,4 +1,9 @@
1
- import { payloadSchema, type SnapAction } from "../schemas";
1
+ import {
2
+ ACTION_TYPE_GET,
3
+ ACTION_TYPE_POST,
4
+ payloadSchema,
5
+ type SnapAction,
6
+ } from "../schemas";
2
7
  import { decodePayload, verifyJFSRequestBody } from "./verify";
3
8
  import { z } from "zod";
4
9
 
@@ -66,7 +71,7 @@ export async function parseRequest(
66
71
  if (request.method === "GET") {
67
72
  return {
68
73
  success: true,
69
- action: { type: "get" },
74
+ action: { type: ACTION_TYPE_GET },
70
75
  };
71
76
  }
72
77
 
@@ -129,11 +134,8 @@ export async function parseRequest(
129
134
  return {
130
135
  success: true,
131
136
  action: {
132
- type: "post",
133
- fid: body.fid,
134
- inputs: body.inputs,
135
- buttonIndex: body.button_index,
136
- timestamp: body.timestamp,
137
+ type: ACTION_TYPE_POST,
138
+ ...body,
137
139
  },
138
140
  };
139
141
  }
package/src/ui/catalog.ts CHANGED
@@ -19,7 +19,7 @@ import { stackProps } from "./stack.js";
19
19
  import { actionButtonProps } from "./button.js";
20
20
 
21
21
  const snapPostParams = z.object({
22
- buttonIndex: z.number().int().nonnegative(),
22
+ button_index: z.number().int().nonnegative(),
23
23
  target: z.string(),
24
24
  label: z.string().optional(),
25
25
  style: z.enum(BUTTON_STYLE_VALUES).optional(),
package/src/validator.ts CHANGED
@@ -8,13 +8,13 @@ import {
8
8
  TEXT_STYLE,
9
9
  } from "./constants";
10
10
  import {
11
- firstPageRootSchema,
12
- rootSchema,
11
+ firstPageResponseSchema,
12
+ snapResponseSchema,
13
13
  type Button,
14
14
  type Element,
15
15
  } from "./schemas";
16
16
 
17
- type SnapRoot = z.infer<typeof rootSchema>;
17
+ type SnapRoot = z.infer<typeof snapResponseSchema>;
18
18
 
19
19
  export type ValidationResult = {
20
20
  valid: boolean;
@@ -158,8 +158,8 @@ function heightBudgetValidationErrorForRoot(
158
158
  );
159
159
  }
160
160
 
161
- export function validatePage(json: unknown): ValidationResult {
162
- const parsed = rootSchema.safeParse(json);
161
+ export function validateSnapResponse(json: unknown): ValidationResult {
162
+ const parsed = snapResponseSchema.safeParse(json);
163
163
  if (!parsed.success) {
164
164
  return {
165
165
  valid: false,
@@ -175,8 +175,8 @@ export function validatePage(json: unknown): ValidationResult {
175
175
  return { valid: true, issues: [] };
176
176
  }
177
177
 
178
- export function validateFirstPage(json: unknown): ValidationResult {
179
- const parsed = firstPageRootSchema.safeParse(json);
178
+ export function validateFirstPageResponse(json: unknown): ValidationResult {
179
+ const parsed = firstPageResponseSchema.safeParse(json);
180
180
  if (!parsed.success) {
181
181
  return {
182
182
  valid: false,