@mentra/cloud-protocol 3.4.0-dev.1100 → 3.4.0-dev.1101

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mentra/cloud-protocol",
3
- "version": "3.4.0-dev.1100",
3
+ "version": "3.4.0-dev.1101",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "exports": {
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @fileoverview A person's declared age, kept on their Core account: `/api/account/declared-age`.
3
+ *
4
+ * A miniapp that declares an `ageRating` above the host app's own App Store rating installs or opens only for a person
5
+ * whose declared age is old enough (App Store Review Guideline 4.7.5). The first time that comes up, the app asks the
6
+ * person's age once, and Core keeps it on their account with the date they gave it. Their age now is the declared age
7
+ * plus the whole years since that date ({@link currentDeclaredAge}). Core never puts it in a token or sends it to a
8
+ * miniapp.
9
+ *
10
+ * GET /api/account/declared-age {declaredAge, declaredAgeAt}, both null until the person answers
11
+ * PUT /api/account/declared-age {age} {declaredAge, declaredAgeAt}
12
+ *
13
+ * `GET /api/account/me` carries the same two fields.
14
+ */
15
+ import {z} from "zod"
16
+
17
+ /** The ages a person may give: a whole number of years. */
18
+ export const DECLARED_AGE_MIN = 1
19
+ export const DECLARED_AGE_MAX = 120
20
+
21
+ export const DeclaredAgeRequestSchema = z.object({
22
+ age: z.number().int().min(DECLARED_AGE_MIN).max(DECLARED_AGE_MAX),
23
+ })
24
+ export type DeclaredAgeRequest = z.infer<typeof DeclaredAgeRequestSchema>
25
+
26
+ /** What Core keeps. Both fields are null until the person answers, and set together after. */
27
+ export interface DeclaredAge {
28
+ /** The age the person gave. */
29
+ declaredAge: number | null
30
+ /** When they gave it, ISO 8601. */
31
+ declaredAgeAt: string | null
32
+ }
33
+
34
+ export const DeclaredAgeSchema: z.ZodType<DeclaredAge> = z.union([
35
+ z.object({
36
+ declaredAge: z.number().int().min(DECLARED_AGE_MIN).max(DECLARED_AGE_MAX),
37
+ declaredAgeAt: z.string().datetime({offset: true}),
38
+ }),
39
+ z.object({declaredAge: z.null(), declaredAgeAt: z.null()}),
40
+ ])
41
+
42
+ /**
43
+ * The person's age at `now`: the age they gave plus the whole years since they gave it, counted by calendar date in
44
+ * UTC. Never less than the age they gave, even when `now` is earlier.
45
+ */
46
+ export function currentDeclaredAge(declaredAge: number, declaredAgeAt: string | Date, now: Date): number {
47
+ const at = new Date(declaredAgeAt)
48
+ if (Number.isNaN(at.getTime()) || Number.isNaN(now.getTime())) return declaredAge
49
+ let years = now.getUTCFullYear() - at.getUTCFullYear()
50
+ const beforeAnniversary =
51
+ now.getUTCMonth() < at.getUTCMonth() ||
52
+ (now.getUTCMonth() === at.getUTCMonth() && now.getUTCDate() < at.getUTCDate())
53
+ if (beforeAnniversary) years -= 1
54
+ return declaredAge + Math.max(0, years)
55
+ }
package/src/index.ts CHANGED
@@ -20,3 +20,4 @@ export * from "./report-automation";
20
20
  export * from "./fleet";
21
21
  export * from "./miniapp-url";
22
22
  export * from "./miniapp-registry";
23
+ export * from "./declared-age";