@playaos/api-client 0.12.0 → 0.14.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 +19 -0
- package/dist/applications-schema.d.ts +80 -79
- package/dist/applications-schema.js +83 -76
- package/dist/applications-schema.js.map +1 -1
- package/dist/index.d.ts +1091 -629
- package/dist/index.js +514 -510
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -83,6 +83,25 @@ Required scopes per endpoint:
|
|
|
83
83
|
| `shifts.list` | `shifts:read` |
|
|
84
84
|
| `org.get` | `org:read` |
|
|
85
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
|
+
|
|
86
105
|
## Error handling
|
|
87
106
|
|
|
88
107
|
```typescript
|
|
@@ -1,93 +1,93 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
//#region src/applications-schema.d.ts
|
|
3
3
|
declare const step0Schema: z.ZodObject<{
|
|
4
|
-
|
|
4
|
+
acknowledged_expectations: z.ZodLiteral<true>;
|
|
5
5
|
}, z.core.$strip>;
|
|
6
6
|
declare const step1Schema: z.ZodObject<{
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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]>>>;
|
|
47
47
|
}, z.core.$strip>;
|
|
48
48
|
declare const step5Schema: z.ZodObject<{
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
about_yourself: z.ZodString;
|
|
50
|
+
agrees_to_principles: z.ZodLiteral<true>;
|
|
51
51
|
}, z.core.$strip>;
|
|
52
52
|
declare const applicationSchema: z.ZodObject<{
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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>>;
|
|
91
91
|
}, z.core.$strip>;
|
|
92
92
|
type ApplicationFormData = z.infer<typeof applicationSchema>;
|
|
93
93
|
type Step0Data = z.infer<typeof step0Schema>;
|
|
@@ -96,5 +96,6 @@ type Step2Data = z.infer<typeof step2Schema>;
|
|
|
96
96
|
type Step3Data = z.infer<typeof step3Schema>;
|
|
97
97
|
type Step4Data = z.infer<typeof step4Schema>;
|
|
98
98
|
type Step5Data = z.infer<typeof step5Schema>;
|
|
99
|
-
|
|
100
|
-
export {
|
|
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,86 +1,93 @@
|
|
|
1
|
-
// src/applications-schema.ts
|
|
2
1
|
import { z } from "zod";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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(),
|
|
35
|
-
// commitmentId → value. Integers only on the number branch (per dataType);
|
|
36
|
-
// per-commitment bounds (min/max) are validated against the live defs at
|
|
37
|
-
// form-render + on the server, not here (PLA-682).
|
|
38
|
-
commitments: z.record(z.string(), z.union([z.number().int(), z.boolean()])).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()
|
|
39
42
|
}).refine((data) => !data.build_available || data.build_skills, {
|
|
40
|
-
|
|
41
|
-
|
|
43
|
+
message: "Please tell us about your build skills",
|
|
44
|
+
path: ["build_skills"]
|
|
42
45
|
}).refine((data) => !data.strike_available || data.strike_help, {
|
|
43
|
-
|
|
44
|
-
|
|
46
|
+
message: "Please tell us how you can help with strike",
|
|
47
|
+
path: ["strike_help"]
|
|
45
48
|
});
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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" })
|
|
49
52
|
});
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
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()
|
|
76
89
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
step1Schema,
|
|
81
|
-
step2Schema,
|
|
82
|
-
step3Schema,
|
|
83
|
-
step4Schema,
|
|
84
|
-
step5Schema
|
|
85
|
-
};
|
|
90
|
+
//#endregion
|
|
91
|
+
export { applicationSchema, step0Schema, step1Schema, step2Schema, step3Schema, step4Schema, step5Schema };
|
|
92
|
+
|
|
86
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 // 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":"
|
|
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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"}
|