@playaos/api-client 0.11.0 → 0.13.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/README.md CHANGED
@@ -15,7 +15,6 @@ import { createClient } from "@playaos/api-client";
15
15
 
16
16
  const client = createClient({
17
17
  baseUrl: "https://api.playaos.app",
18
- embedBaseUrl: "https://your-camp.playaos.app",
19
18
  apiKey: "pk_live_...",
20
19
  });
21
20
 
@@ -68,11 +67,11 @@ If your deployment serves both route families from the same host, omit `embedBas
68
67
  - `embedBaseUrl` optionally overrides the host for `/api/embed/v1/*` routes.
69
68
  - When `embedBaseUrl` is omitted, embed requests default to `baseUrl`.
70
69
 
71
- This is useful when a deployment splits API-key-authenticated routes onto a dedicated API host (for example `https://api.playaos.app`) but keeps embed routes on a portal host (for example `https://your-camp.playaos.app`).
70
+ This is useful when a deployment splits API-key-authenticated routes and embed routes onto different hosts. PlayaOS production serves both route families from `https://api.playaos.app`, so most integrations can omit `embedBaseUrl`.
72
71
 
73
72
  ## Authentication
74
73
 
75
- Generate an API key in **Admin → Settings → Developer**. Keys use the format `pk_live_*` and are scoped to specific resources.
74
+ Generate an API key in the PlayaOS platform console under your org's **Developer → API Keys** page. Keys use the format `pk_live_*` and are scoped to specific resources.
76
75
 
77
76
  Required scopes per endpoint:
78
77
 
@@ -84,6 +83,25 @@ Required scopes per endpoint:
84
83
  | `shifts.list` | `shifts:read` |
85
84
  | `org.get` | `org:read` |
86
85
 
86
+ ## Member-scoped calls
87
+
88
+ An API key acts as **the camp**, not as a person. Endpoints that return one member's own data — their dues, payments, application, shelter, tickets, onboarding progress, notifications, shift signup — also require the acting member's PlayaOS session JWT, sent as `X-PlayaOS-Member-Token`. Without it those endpoints return `401`; with it, a non-admin member is pinned to their own records (asking for someone else's is `403`, or `404` for a row id), while an `admin`/`super_admin` member may name any member or list the whole camp.
89
+
90
+ Hold one org key server-side and derive a per-member client from it:
91
+
92
+ ```typescript
93
+ const shared = createClient({ baseUrl: "https://api.playaos.app", apiKey: process.env.PLAYAOS_API_KEY! });
94
+
95
+ // `session.access_token` is the signed-in user's Supabase JWT from auth.playaos.app
96
+ const me = shared.withMember(session.access_token);
97
+
98
+ const profile = await me.members.get("me"); // who am I in this camp (profile id, role, contact)
99
+ const myDues = await me.dues.list({ year: 2026 }); // pinned to the signed-in member
100
+ const page = await me.payments.page(); // memberId defaults to the signed-in member
101
+ ```
102
+
103
+ Org-level endpoints (`org.get`, `shifts.list`, `documents.list`, `contacts.list`, …) do not require the member token, so the derived client works for both — but a token that is sent must still verify: an expired or invalid one is a `401` on any `/api/v1` route that installs the member middleware, org-level or not. Refresh the session before deriving the client.
104
+
87
105
  ## Error handling
88
106
 
89
107
  ```typescript
@@ -95,6 +113,8 @@ try {
95
113
  if (err instanceof ApiClientError) {
96
114
  console.error(err.status, err.code, err.message);
97
115
  // 404, "NOT_FOUND", "Member not found"
116
+ // err.retryAfter is the Retry-After header in seconds when the server sends a
117
+ // numeric one (commonly on 429/503); undefined otherwise.
98
118
  }
99
119
  }
100
120
  ```
@@ -1,91 +1,93 @@
1
- import { z } from 'zod';
2
-
1
+ import { z } from "zod";
2
+ //#region src/applications-schema.d.ts
3
3
  declare const step0Schema: z.ZodObject<{
4
- acknowledged_expectations: z.ZodLiteral<true>;
4
+ acknowledged_expectations: z.ZodLiteral<true>;
5
5
  }, z.core.$strip>;
6
6
  declare const step1Schema: z.ZodObject<{
7
- first_name: z.ZodString;
8
- last_name: z.ZodString;
9
- email: z.ZodString;
10
- phone: z.ZodString;
11
- referral_code: z.ZodOptional<z.ZodString>;
12
- socials: z.ZodOptional<z.ZodString>;
13
- birthday: z.ZodString;
14
- hometown: z.ZodString;
7
+ first_name: z.ZodString;
8
+ last_name: z.ZodString;
9
+ email: z.ZodString;
10
+ phone: z.ZodString;
11
+ referral_code: z.ZodOptional<z.ZodString>;
12
+ socials: z.ZodOptional<z.ZodString>;
13
+ birthday: z.ZodString;
14
+ hometown: z.ZodString;
15
15
  }, z.core.$strip>;
16
16
  declare const step2Schema: z.ZodObject<{
17
- how_heard: z.ZodString;
18
- burning_man_before: z.ZodEnum<{
19
- yes: "yes";
20
- no: "no";
21
- }>;
22
- burning_man_years: z.ZodOptional<z.ZodString>;
17
+ how_heard: z.ZodString;
18
+ burning_man_before: z.ZodEnum<{
19
+ no: "no";
20
+ yes: "yes";
21
+ }>;
22
+ burning_man_years: z.ZodOptional<z.ZodString>;
23
23
  }, z.core.$strip>;
24
24
  declare const step3Schema: z.ZodObject<{
25
- shelter_type: z.ZodEnum<{
26
- joining_rv: "joining_rv";
27
- bringing_rv: "bringing_rv";
28
- shiftpod_tent: "shiftpod_tent";
29
- car: "car";
30
- truck: "truck";
31
- van: "van";
32
- unsure: "unsure";
33
- }>;
34
- shelter_mates: z.ZodOptional<z.ZodString>;
35
- ticket_status: z.ZodEnum<{
36
- unsure: "unsure";
37
- looking: "looking";
38
- have_ticket: "have_ticket";
39
- }>;
25
+ shelter_type: z.ZodEnum<{
26
+ bringing_rv: "bringing_rv";
27
+ car: "car";
28
+ joining_rv: "joining_rv";
29
+ shiftpod_tent: "shiftpod_tent";
30
+ truck: "truck";
31
+ unsure: "unsure";
32
+ van: "van";
33
+ }>;
34
+ shelter_mates: z.ZodOptional<z.ZodString>;
35
+ ticket_status: z.ZodEnum<{
36
+ have_ticket: "have_ticket";
37
+ looking: "looking";
38
+ unsure: "unsure";
39
+ }>;
40
40
  }, z.core.$strip>;
41
41
  declare const step4Schema: z.ZodObject<{
42
- build_available: z.ZodBoolean;
43
- build_skills: z.ZodOptional<z.ZodString>;
44
- strike_available: z.ZodBoolean;
45
- strike_help: z.ZodOptional<z.ZodString>;
42
+ build_available: z.ZodBoolean;
43
+ build_skills: z.ZodOptional<z.ZodString>;
44
+ strike_available: z.ZodBoolean;
45
+ strike_help: z.ZodOptional<z.ZodString>;
46
+ commitments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNumber, z.ZodBoolean]>>>;
46
47
  }, z.core.$strip>;
47
48
  declare const step5Schema: z.ZodObject<{
48
- about_yourself: z.ZodString;
49
- agrees_to_principles: z.ZodLiteral<true>;
49
+ about_yourself: z.ZodString;
50
+ agrees_to_principles: z.ZodLiteral<true>;
50
51
  }, z.core.$strip>;
51
52
  declare const applicationSchema: z.ZodObject<{
52
- acknowledged_expectations: z.ZodOptional<z.ZodLiteral<true>>;
53
- first_name: z.ZodString;
54
- last_name: z.ZodString;
55
- email: z.ZodString;
56
- phone: z.ZodOptional<z.ZodString>;
57
- referral_code: z.ZodOptional<z.ZodString>;
58
- socials: z.ZodOptional<z.ZodString>;
59
- birthday: z.ZodOptional<z.ZodString>;
60
- hometown: z.ZodOptional<z.ZodString>;
61
- how_heard: z.ZodOptional<z.ZodString>;
62
- burning_man_before: z.ZodOptional<z.ZodEnum<{
63
- yes: "yes";
64
- no: "no";
65
- }>>;
66
- burning_man_years: z.ZodOptional<z.ZodString>;
67
- shelter_type: z.ZodOptional<z.ZodEnum<{
68
- joining_rv: "joining_rv";
69
- bringing_rv: "bringing_rv";
70
- shiftpod_tent: "shiftpod_tent";
71
- car: "car";
72
- truck: "truck";
73
- van: "van";
74
- unsure: "unsure";
75
- }>>;
76
- shelter_mates: z.ZodOptional<z.ZodString>;
77
- ticket_status: z.ZodOptional<z.ZodEnum<{
78
- unsure: "unsure";
79
- looking: "looking";
80
- have_ticket: "have_ticket";
81
- }>>;
82
- build_available: z.ZodOptional<z.ZodBoolean>;
83
- build_skills: z.ZodOptional<z.ZodString>;
84
- strike_available: z.ZodOptional<z.ZodBoolean>;
85
- strike_help: z.ZodOptional<z.ZodString>;
86
- about_yourself: z.ZodOptional<z.ZodString>;
87
- agrees_to_principles: z.ZodOptional<z.ZodLiteral<true>>;
88
- custom_fields: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
53
+ acknowledged_expectations: z.ZodOptional<z.ZodLiteral<true>>;
54
+ first_name: z.ZodString;
55
+ last_name: z.ZodString;
56
+ email: z.ZodString;
57
+ phone: z.ZodOptional<z.ZodString>;
58
+ referral_code: z.ZodOptional<z.ZodString>;
59
+ socials: z.ZodOptional<z.ZodString>;
60
+ birthday: z.ZodOptional<z.ZodString>;
61
+ hometown: z.ZodOptional<z.ZodString>;
62
+ how_heard: z.ZodOptional<z.ZodString>;
63
+ burning_man_before: z.ZodOptional<z.ZodEnum<{
64
+ no: "no";
65
+ yes: "yes";
66
+ }>>;
67
+ burning_man_years: z.ZodOptional<z.ZodString>;
68
+ shelter_type: z.ZodOptional<z.ZodEnum<{
69
+ bringing_rv: "bringing_rv";
70
+ car: "car";
71
+ joining_rv: "joining_rv";
72
+ shiftpod_tent: "shiftpod_tent";
73
+ truck: "truck";
74
+ unsure: "unsure";
75
+ van: "van";
76
+ }>>;
77
+ shelter_mates: z.ZodOptional<z.ZodString>;
78
+ ticket_status: z.ZodOptional<z.ZodEnum<{
79
+ have_ticket: "have_ticket";
80
+ looking: "looking";
81
+ unsure: "unsure";
82
+ }>>;
83
+ build_available: z.ZodOptional<z.ZodBoolean>;
84
+ build_skills: z.ZodOptional<z.ZodString>;
85
+ strike_available: z.ZodOptional<z.ZodBoolean>;
86
+ strike_help: z.ZodOptional<z.ZodString>;
87
+ about_yourself: z.ZodOptional<z.ZodString>;
88
+ agrees_to_principles: z.ZodOptional<z.ZodLiteral<true>>;
89
+ commitments: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNumber, z.ZodBoolean]>>>;
90
+ custom_fields: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
89
91
  }, z.core.$strip>;
90
92
  type ApplicationFormData = z.infer<typeof applicationSchema>;
91
93
  type Step0Data = z.infer<typeof step0Schema>;
@@ -94,5 +96,6 @@ type Step2Data = z.infer<typeof step2Schema>;
94
96
  type Step3Data = z.infer<typeof step3Schema>;
95
97
  type Step4Data = z.infer<typeof step4Schema>;
96
98
  type Step5Data = z.infer<typeof step5Schema>;
97
-
98
- export { type ApplicationFormData, type Step0Data, type Step1Data, type Step2Data, type Step3Data, type Step4Data, type Step5Data, applicationSchema, step0Schema, step1Schema, step2Schema, step3Schema, step4Schema, step5Schema };
99
+ //#endregion
100
+ export { ApplicationFormData, Step0Data, Step1Data, Step2Data, Step3Data, Step4Data, Step5Data, applicationSchema, step0Schema, step1Schema, step2Schema, step3Schema, step4Schema, step5Schema };
101
+ //# sourceMappingURL=applications-schema.d.ts.map
@@ -1,79 +1,93 @@
1
- // src/applications-schema.ts
2
1
  import { z } from "zod";
3
- var step0Schema = z.object({
4
- acknowledged_expectations: z.literal(true, {
5
- error: "Please acknowledge the expectations to continue"
6
- })
2
+ //#region src/applications-schema.ts
3
+ const step0Schema = z.object({ acknowledged_expectations: z.literal(true, { error: "Please acknowledge the expectations to continue" }) });
4
+ const step1Schema = z.object({
5
+ first_name: z.string().min(1, "First name is required"),
6
+ last_name: z.string().min(1, "Last name is required"),
7
+ email: z.string().email("Invalid email address"),
8
+ phone: z.string().min(10, "Phone number is required"),
9
+ referral_code: z.string().optional(),
10
+ socials: z.string().optional(),
11
+ birthday: z.string().min(1, "Birthday is required"),
12
+ hometown: z.string().min(1, "Location is required")
7
13
  });
8
- var step1Schema = z.object({
9
- first_name: z.string().min(1, "First name is required"),
10
- last_name: z.string().min(1, "Last name is required"),
11
- email: z.string().email("Invalid email address"),
12
- phone: z.string().min(10, "Phone number is required"),
13
- referral_code: z.string().optional(),
14
- socials: z.string().optional(),
15
- birthday: z.string().min(1, "Birthday is required"),
16
- hometown: z.string().min(1, "Location is required")
14
+ const step2Schema = z.object({
15
+ how_heard: z.string().min(1, "Please tell us how you heard about us"),
16
+ burning_man_before: z.enum(["yes", "no"], { error: "Please select an option" }),
17
+ burning_man_years: z.string().optional()
17
18
  });
18
- var step2Schema = z.object({
19
- how_heard: z.string().min(1, "Please tell us how you heard about us"),
20
- burning_man_before: z.enum(["yes", "no"], { error: "Please select an option" }),
21
- burning_man_years: z.string().optional()
19
+ const step3Schema = z.object({
20
+ shelter_type: z.enum([
21
+ "joining_rv",
22
+ "bringing_rv",
23
+ "shiftpod_tent",
24
+ "car",
25
+ "truck",
26
+ "van",
27
+ "unsure"
28
+ ], { error: "Please select a shelter type" }),
29
+ shelter_mates: z.string().optional(),
30
+ ticket_status: z.enum([
31
+ "looking",
32
+ "have_ticket",
33
+ "unsure"
34
+ ], { error: "Please select your ticket status" })
22
35
  });
23
- var step3Schema = z.object({
24
- shelter_type: z.enum(["joining_rv", "bringing_rv", "shiftpod_tent", "car", "truck", "van", "unsure"], {
25
- error: "Please select a shelter type"
26
- }),
27
- shelter_mates: z.string().optional(),
28
- ticket_status: z.enum(["looking", "have_ticket", "unsure"], { error: "Please select your ticket status" })
29
- });
30
- var step4Schema = z.object({
31
- build_available: z.boolean(),
32
- build_skills: z.string().optional(),
33
- strike_available: z.boolean(),
34
- strike_help: z.string().optional()
36
+ const step4Schema = z.object({
37
+ build_available: z.boolean(),
38
+ build_skills: z.string().optional(),
39
+ strike_available: z.boolean(),
40
+ strike_help: z.string().optional(),
41
+ commitments: z.record(z.string(), z.union([z.number().int(), z.boolean()])).optional()
35
42
  }).refine((data) => !data.build_available || data.build_skills, {
36
- message: "Please tell us about your build skills",
37
- path: ["build_skills"]
43
+ message: "Please tell us about your build skills",
44
+ path: ["build_skills"]
38
45
  }).refine((data) => !data.strike_available || data.strike_help, {
39
- message: "Please tell us how you can help with strike",
40
- path: ["strike_help"]
46
+ message: "Please tell us how you can help with strike",
47
+ path: ["strike_help"]
41
48
  });
42
- var step5Schema = z.object({
43
- about_yourself: z.string().min(50, "Please write at least 50 characters about yourself"),
44
- agrees_to_principles: z.literal(true, { error: "You must agree to the 10 Principles" })
49
+ const step5Schema = z.object({
50
+ about_yourself: z.string().min(50, "Please write at least 50 characters about yourself"),
51
+ agrees_to_principles: z.literal(true, { error: "You must agree to the 10 Principles" })
45
52
  });
46
- var applicationSchema = z.object({
47
- acknowledged_expectations: z.literal(true).optional(),
48
- first_name: z.string().min(1),
49
- last_name: z.string().min(1),
50
- email: z.string().email(),
51
- phone: z.string().optional(),
52
- referral_code: z.string().optional(),
53
- socials: z.string().optional(),
54
- birthday: z.string().optional(),
55
- hometown: z.string().optional(),
56
- how_heard: z.string().optional(),
57
- burning_man_before: z.enum(["yes", "no"]).optional(),
58
- burning_man_years: z.string().optional(),
59
- shelter_type: z.enum(["joining_rv", "bringing_rv", "shiftpod_tent", "car", "truck", "van", "unsure"]).optional(),
60
- shelter_mates: z.string().optional(),
61
- ticket_status: z.enum(["looking", "have_ticket", "unsure"]).optional(),
62
- build_available: z.boolean().optional(),
63
- build_skills: z.string().optional(),
64
- strike_available: z.boolean().optional(),
65
- strike_help: z.string().optional(),
66
- about_yourself: z.string().optional(),
67
- agrees_to_principles: z.literal(true).optional(),
68
- custom_fields: z.object({}).passthrough().optional()
53
+ const applicationSchema = z.object({
54
+ acknowledged_expectations: z.literal(true).optional(),
55
+ first_name: z.string().min(1),
56
+ last_name: z.string().min(1),
57
+ email: z.string().email(),
58
+ phone: z.string().optional(),
59
+ referral_code: z.string().optional(),
60
+ socials: z.string().optional(),
61
+ birthday: z.string().optional(),
62
+ hometown: z.string().optional(),
63
+ how_heard: z.string().optional(),
64
+ burning_man_before: z.enum(["yes", "no"]).optional(),
65
+ burning_man_years: z.string().optional(),
66
+ shelter_type: z.enum([
67
+ "joining_rv",
68
+ "bringing_rv",
69
+ "shiftpod_tent",
70
+ "car",
71
+ "truck",
72
+ "van",
73
+ "unsure"
74
+ ]).optional(),
75
+ shelter_mates: z.string().optional(),
76
+ ticket_status: z.enum([
77
+ "looking",
78
+ "have_ticket",
79
+ "unsure"
80
+ ]).optional(),
81
+ build_available: z.boolean().optional(),
82
+ build_skills: z.string().optional(),
83
+ strike_available: z.boolean().optional(),
84
+ strike_help: z.string().optional(),
85
+ about_yourself: z.string().optional(),
86
+ agrees_to_principles: z.literal(true).optional(),
87
+ commitments: z.record(z.string(), z.union([z.number(), z.boolean()])).optional(),
88
+ custom_fields: z.object({}).passthrough().optional()
69
89
  });
70
- export {
71
- applicationSchema,
72
- step0Schema,
73
- step1Schema,
74
- step2Schema,
75
- step3Schema,
76
- step4Schema,
77
- step5Schema
78
- };
90
+ //#endregion
91
+ export { applicationSchema, step0Schema, step1Schema, step2Schema, step3Schema, step4Schema, step5Schema };
92
+
79
93
  //# sourceMappingURL=applications-schema.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/applications-schema.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// Single source of truth for the apply-wizard form shape.\n// The portal apply flow and the @playaos/react <ApplicationForm> SDK both import\n// from here so the validation contract can never drift between them (PLA-483).\n// `ApplicationCreatePayload` in ./types.ts is the zod-free wire mirror; a type\n// equivalence test (applications-schema.test.ts) keeps the two locked together.\n\n// Per-step validation schemas\nexport const step0Schema = z.object({\n acknowledged_expectations: z.literal(true, {\n error: \"Please acknowledge the expectations to continue\",\n }),\n});\n\nexport const step1Schema = z.object({\n first_name: z.string().min(1, \"First name is required\"),\n last_name: z.string().min(1, \"Last name is required\"),\n email: z.string().email(\"Invalid email address\"),\n phone: z.string().min(10, \"Phone number is required\"),\n referral_code: z.string().optional(),\n socials: z.string().optional(),\n birthday: z.string().min(1, \"Birthday is required\"),\n hometown: z.string().min(1, \"Location is required\"),\n});\n\nexport const step2Schema = z.object({\n how_heard: z.string().min(1, \"Please tell us how you heard about us\"),\n burning_man_before: z.enum([\"yes\", \"no\"], { error: \"Please select an option\" }),\n burning_man_years: z.string().optional(),\n});\n\nexport const step3Schema = z.object({\n shelter_type: z.enum([\"joining_rv\", \"bringing_rv\", \"shiftpod_tent\", \"car\", \"truck\", \"van\", \"unsure\"], {\n error: \"Please select a shelter type\",\n }),\n shelter_mates: z.string().optional(),\n ticket_status: z.enum([\"looking\", \"have_ticket\", \"unsure\"], { error: \"Please select your ticket status\" }),\n});\n\nexport const step4Schema = z\n .object({\n build_available: z.boolean(),\n build_skills: z.string().optional(),\n strike_available: z.boolean(),\n strike_help: z.string().optional(),\n })\n .refine((data) => !data.build_available || data.build_skills, {\n message: \"Please tell us about your build skills\",\n path: [\"build_skills\"],\n })\n .refine((data) => !data.strike_available || data.strike_help, {\n message: \"Please tell us how you can help with strike\",\n path: [\"strike_help\"],\n });\n\nexport const step5Schema = z.object({\n about_yourself: z.string().min(50, \"Please write at least 50 characters about yourself\"),\n agrees_to_principles: z.literal(true, { error: \"You must agree to the 10 Principles\" }),\n});\n\n// Combined schema for API-level validation — permissive so external camps\n// can submit applications with only first_name + last_name + email + custom_fields.\n// Step schemas (above) remain strict for the PlayaOS wizard UI.\nexport const applicationSchema = z.object({\n acknowledged_expectations: z.literal(true).optional(),\n first_name: z.string().min(1),\n last_name: z.string().min(1),\n email: z.string().email(),\n phone: z.string().optional(),\n referral_code: z.string().optional(),\n socials: z.string().optional(),\n birthday: z.string().optional(),\n hometown: z.string().optional(),\n how_heard: z.string().optional(),\n burning_man_before: z.enum([\"yes\", \"no\"]).optional(),\n burning_man_years: z.string().optional(),\n shelter_type: z.enum([\"joining_rv\", \"bringing_rv\", \"shiftpod_tent\", \"car\", \"truck\", \"van\", \"unsure\"]).optional(),\n shelter_mates: z.string().optional(),\n ticket_status: z.enum([\"looking\", \"have_ticket\", \"unsure\"]).optional(),\n build_available: z.boolean().optional(),\n build_skills: z.string().optional(),\n strike_available: z.boolean().optional(),\n strike_help: z.string().optional(),\n about_yourself: z.string().optional(),\n agrees_to_principles: z.literal(true).optional(),\n custom_fields: z.object({}).passthrough().optional(),\n});\n\nexport type ApplicationFormData = z.infer<typeof applicationSchema>;\nexport type Step0Data = z.infer<typeof step0Schema>;\nexport type Step1Data = z.infer<typeof step1Schema>;\nexport type Step2Data = z.infer<typeof step2Schema>;\nexport type Step3Data = z.infer<typeof step3Schema>;\nexport type Step4Data = z.infer<typeof step4Schema>;\nexport type Step5Data = z.infer<typeof step5Schema>;\n"],"mappings":"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","names":[]}
1
+ {"version":3,"file":"applications-schema.js","names":[],"sources":["../src/applications-schema.ts"],"sourcesContent":["import { z } from \"zod\";\n\n// Single source of truth for the apply-wizard form shape.\n// The portal apply flow and the @playaos/react <ApplicationForm> SDK both import\n// from here so the validation contract can never drift between them (PLA-483).\n// `ApplicationCreatePayload` in ./types.ts is the zod-free wire mirror; a type\n// equivalence test (applications-schema.test.ts) keeps the two locked together.\n\n// Per-step validation schemas\nexport const step0Schema = z.object({\n acknowledged_expectations: z.literal(true, {\n error: \"Please acknowledge the expectations to continue\",\n }),\n});\n\nexport const step1Schema = z.object({\n first_name: z.string().min(1, \"First name is required\"),\n last_name: z.string().min(1, \"Last name is required\"),\n email: z.string().email(\"Invalid email address\"),\n phone: z.string().min(10, \"Phone number is required\"),\n referral_code: z.string().optional(),\n socials: z.string().optional(),\n birthday: z.string().min(1, \"Birthday is required\"),\n hometown: z.string().min(1, \"Location is required\"),\n});\n\nexport const step2Schema = z.object({\n how_heard: z.string().min(1, \"Please tell us how you heard about us\"),\n burning_man_before: z.enum([\"yes\", \"no\"], { error: \"Please select an option\" }),\n burning_man_years: z.string().optional(),\n});\n\nexport const step3Schema = z.object({\n shelter_type: z.enum([\"joining_rv\", \"bringing_rv\", \"shiftpod_tent\", \"car\", \"truck\", \"van\", \"unsure\"], {\n error: \"Please select a shelter type\",\n }),\n shelter_mates: z.string().optional(),\n ticket_status: z.enum([\"looking\", \"have_ticket\", \"unsure\"], { error: \"Please select your ticket status\" }),\n});\n\nexport const step4Schema = z\n .object({\n build_available: z.boolean(),\n build_skills: z.string().optional(),\n strike_available: z.boolean(),\n strike_help: z.string().optional(),\n // commitmentId → value. Integers only on the number branch (per dataType);\n // per-commitment bounds (min/max) are validated against the live defs at\n // form-render + on the server, not here (PLA-682).\n commitments: z.record(z.string(), z.union([z.number().int(), z.boolean()])).optional(),\n })\n .refine((data) => !data.build_available || data.build_skills, {\n message: \"Please tell us about your build skills\",\n path: [\"build_skills\"],\n })\n .refine((data) => !data.strike_available || data.strike_help, {\n message: \"Please tell us how you can help with strike\",\n path: [\"strike_help\"],\n });\n\nexport const step5Schema = z.object({\n about_yourself: z.string().min(50, \"Please write at least 50 characters about yourself\"),\n agrees_to_principles: z.literal(true, { error: \"You must agree to the 10 Principles\" }),\n});\n\n// Combined schema for API-level validation — permissive so external camps\n// can submit applications with only first_name + last_name + email + custom_fields.\n// Step schemas (above) remain strict for the PlayaOS wizard UI.\nexport const applicationSchema = z.object({\n acknowledged_expectations: z.literal(true).optional(),\n first_name: z.string().min(1),\n last_name: z.string().min(1),\n email: z.string().email(),\n phone: z.string().optional(),\n referral_code: z.string().optional(),\n socials: z.string().optional(),\n birthday: z.string().optional(),\n hometown: z.string().optional(),\n how_heard: z.string().optional(),\n burning_man_before: z.enum([\"yes\", \"no\"]).optional(),\n burning_man_years: z.string().optional(),\n shelter_type: z.enum([\"joining_rv\", \"bringing_rv\", \"shiftpod_tent\", \"car\", \"truck\", \"van\", \"unsure\"]).optional(),\n shelter_mates: z.string().optional(),\n ticket_status: z.enum([\"looking\", \"have_ticket\", \"unsure\"]).optional(),\n build_available: z.boolean().optional(),\n build_skills: z.string().optional(),\n strike_available: z.boolean().optional(),\n strike_help: z.string().optional(),\n about_yourself: z.string().optional(),\n agrees_to_principles: z.literal(true).optional(),\n // Permissive at the API level (no bounds checks) — the server validates each\n // value against the live commitment definition before seeding (PLA-682).\n commitments: z.record(z.string(), z.union([z.number(), z.boolean()])).optional(),\n custom_fields: z.object({}).passthrough().optional(),\n});\n\nexport type ApplicationFormData = z.infer<typeof applicationSchema>;\nexport type Step0Data = z.infer<typeof step0Schema>;\nexport type Step1Data = z.infer<typeof step1Schema>;\nexport type Step2Data = z.infer<typeof step2Schema>;\nexport type Step3Data = z.infer<typeof step3Schema>;\nexport type Step4Data = z.infer<typeof step4Schema>;\nexport type Step5Data = z.infer<typeof step5Schema>;\n"],"mappings":"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"}