@learncard/helpers 1.2.9 → 1.2.10
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/helpers.cjs.development.js +142 -4
- package/dist/helpers.cjs.development.js.map +3 -3
- package/dist/helpers.cjs.production.min.js +5 -5
- package/dist/helpers.cjs.production.min.js.map +4 -4
- package/dist/helpers.d.ts +61 -0
- package/dist/helpers.esm.js +142 -4
- package/dist/helpers.esm.js.map +3 -3
- package/package.json +2 -2
package/dist/helpers.d.ts
CHANGED
|
@@ -634,6 +634,67 @@ export type DeepPartial<T> = T extends Date ? T : T extends object ? {
|
|
|
634
634
|
} : T;
|
|
635
635
|
export declare const isNotUndefined: <T>(value: T | null | undefined) => value is T;
|
|
636
636
|
export declare const filterUndefined: <T>(arr: (T | null | undefined)[]) => T[];
|
|
637
|
+
/**
|
|
638
|
+
* App installation age restriction logic shared between frontend and backend.
|
|
639
|
+
*
|
|
640
|
+
* This helper evaluates whether a user can install an app based on:
|
|
641
|
+
* - Hard age blocks (min_age) - always blocks, even with guardian approval
|
|
642
|
+
* - Soft age restrictions (age_rating) - can be approved by guardian for child profiles
|
|
643
|
+
* - Contract requirements - require guardian approval for child profiles
|
|
644
|
+
*/
|
|
645
|
+
export type AppInstallCheckResult = {
|
|
646
|
+
action: "proceed";
|
|
647
|
+
} | {
|
|
648
|
+
action: "hard_blocked";
|
|
649
|
+
reason: string;
|
|
650
|
+
} | {
|
|
651
|
+
action: "require_dob";
|
|
652
|
+
reason: string;
|
|
653
|
+
} | {
|
|
654
|
+
action: "require_guardian_approval";
|
|
655
|
+
reason: string;
|
|
656
|
+
};
|
|
657
|
+
export type AppInstallCheckInput = {
|
|
658
|
+
/** Whether the user is a child profile (managed account) */
|
|
659
|
+
isChildProfile: boolean;
|
|
660
|
+
/** User's age calculated from DOB, null if DOB is unknown */
|
|
661
|
+
userAge: number | null;
|
|
662
|
+
/** Hard minimum age requirement (blocks completely, no guardian override) */
|
|
663
|
+
minAge?: number;
|
|
664
|
+
/** Soft age rating string (e.g., '4+', '9+', '12+', '17+') */
|
|
665
|
+
ageRating?: string;
|
|
666
|
+
/** Whether the app has an associated consent contract */
|
|
667
|
+
hasContract: boolean;
|
|
668
|
+
/** Whether guardian approval has already been obtained (for backend validation) */
|
|
669
|
+
hasGuardianApproval?: boolean;
|
|
670
|
+
};
|
|
671
|
+
/**
|
|
672
|
+
* Evaluates whether a user can install an app based on age restrictions and profile type.
|
|
673
|
+
*
|
|
674
|
+
* Cases:
|
|
675
|
+
* 1. Hard block: min_age violation (blocks completely, cannot be overridden)
|
|
676
|
+
* 2. Child profile scenarios:
|
|
677
|
+
* 2a. Child age unknown → require DOB entry (with guardian approval)
|
|
678
|
+
* 2b. No age rating specified → require guardian approval
|
|
679
|
+
* 2c. Child too young for age rating → require guardian approval
|
|
680
|
+
* 2d. App has a contract → require guardian approval
|
|
681
|
+
* 2e. Child old enough, no contract → proceed without guardian
|
|
682
|
+
* 3. Adult user old enough → proceed
|
|
683
|
+
*
|
|
684
|
+
* @param input - The check parameters
|
|
685
|
+
* @returns The action to take and reason if blocked/requires approval
|
|
686
|
+
*/
|
|
687
|
+
export declare const checkAppInstallEligibility: (input: AppInstallCheckInput) => AppInstallCheckResult;
|
|
688
|
+
/**
|
|
689
|
+
* Map age_rating strings to numeric minimum ages.
|
|
690
|
+
*/
|
|
691
|
+
export declare const AGE_RATING_TO_MIN_AGE: Record<string, number>;
|
|
692
|
+
/**
|
|
693
|
+
* Calculate age in years from a date of birth string.
|
|
694
|
+
* @param dob - Date of birth as ISO string or parseable date string
|
|
695
|
+
* @returns Age in years, or null if the date is invalid
|
|
696
|
+
*/
|
|
697
|
+
export declare const calculateAgeFromDob: (dob?: string | null) => number | null;
|
|
637
698
|
/**
|
|
638
699
|
* Determines whether or not a string is a valid hexadecimal string
|
|
639
700
|
*
|
package/dist/helpers.esm.js
CHANGED
|
@@ -75,6 +75,7 @@ var require_types_cjs_development = __commonJS({
|
|
|
75
75
|
AuthGrantQueryValidator: /* @__PURE__ */ __name(() => AuthGrantQueryValidator, "AuthGrantQueryValidator"),
|
|
76
76
|
AuthGrantStatusValidator: /* @__PURE__ */ __name(() => AuthGrantStatusValidator, "AuthGrantStatusValidator"),
|
|
77
77
|
AuthGrantValidator: /* @__PURE__ */ __name(() => AuthGrantValidator, "AuthGrantValidator"),
|
|
78
|
+
AuthSessionError: /* @__PURE__ */ __name(() => AuthSessionError, "AuthSessionError"),
|
|
78
79
|
AutoBoostConfigValidator: /* @__PURE__ */ __name(() => AutoBoostConfigValidator, "AutoBoostConfigValidator"),
|
|
79
80
|
BoostPermissionsQueryValidator: /* @__PURE__ */ __name(() => BoostPermissionsQueryValidator, "BoostPermissionsQueryValidator"),
|
|
80
81
|
BoostPermissionsValidator: /* @__PURE__ */ __name(() => BoostPermissionsValidator, "BoostPermissionsValidator"),
|
|
@@ -82,6 +83,8 @@ var require_types_cjs_development = __commonJS({
|
|
|
82
83
|
BoostRecipientValidator: /* @__PURE__ */ __name(() => BoostRecipientValidator, "BoostRecipientValidator"),
|
|
83
84
|
BoostRecipientWithChildrenValidator: /* @__PURE__ */ __name(() => BoostRecipientWithChildrenValidator, "BoostRecipientWithChildrenValidator"),
|
|
84
85
|
BoostValidator: /* @__PURE__ */ __name(() => BoostValidator, "BoostValidator"),
|
|
86
|
+
CheckCredentialEventValidator: /* @__PURE__ */ __name(() => CheckCredentialEventValidator, "CheckCredentialEventValidator"),
|
|
87
|
+
CheckIssuanceStatusEventValidator: /* @__PURE__ */ __name(() => CheckIssuanceStatusEventValidator, "CheckIssuanceStatusEventValidator"),
|
|
85
88
|
ClaimHookQueryValidator: /* @__PURE__ */ __name(() => ClaimHookQueryValidator, "ClaimHookQueryValidator"),
|
|
86
89
|
ClaimHookTypeValidator: /* @__PURE__ */ __name(() => ClaimHookTypeValidator, "ClaimHookTypeValidator"),
|
|
87
90
|
ClaimHookValidator: /* @__PURE__ */ __name(() => ClaimHookValidator, "ClaimHookValidator"),
|
|
@@ -123,6 +126,7 @@ var require_types_cjs_development = __commonJS({
|
|
|
123
126
|
CredentialActivityValidator: /* @__PURE__ */ __name(() => CredentialActivityValidator, "CredentialActivityValidator"),
|
|
124
127
|
CredentialActivityWithDetailsValidator: /* @__PURE__ */ __name(() => CredentialActivityWithDetailsValidator, "CredentialActivityWithDetailsValidator"),
|
|
125
128
|
CredentialInfoValidator: /* @__PURE__ */ __name(() => CredentialInfoValidator, "CredentialInfoValidator"),
|
|
129
|
+
CredentialNameRefValidator: /* @__PURE__ */ __name(() => CredentialNameRefValidator, "CredentialNameRefValidator"),
|
|
126
130
|
CredentialRecordValidator: /* @__PURE__ */ __name(() => CredentialRecordValidator, "CredentialRecordValidator"),
|
|
127
131
|
CredentialSchemaValidator: /* @__PURE__ */ __name(() => CredentialSchemaValidator, "CredentialSchemaValidator"),
|
|
128
132
|
CredentialStatusValidator: /* @__PURE__ */ __name(() => CredentialStatusValidator, "CredentialStatusValidator"),
|
|
@@ -144,6 +148,7 @@ var require_types_cjs_development = __commonJS({
|
|
|
144
148
|
GetFullSkillTreeResultValidator: /* @__PURE__ */ __name(() => GetFullSkillTreeResultValidator, "GetFullSkillTreeResultValidator"),
|
|
145
149
|
GetSkillPathInputValidator: /* @__PURE__ */ __name(() => GetSkillPathInputValidator, "GetSkillPathInputValidator"),
|
|
146
150
|
GetSkillPathResultValidator: /* @__PURE__ */ __name(() => GetSkillPathResultValidator, "GetSkillPathResultValidator"),
|
|
151
|
+
GetTemplateRecipientsEventValidator: /* @__PURE__ */ __name(() => GetTemplateRecipientsEventValidator, "GetTemplateRecipientsEventValidator"),
|
|
147
152
|
IdentifierEntryValidator: /* @__PURE__ */ __name(() => IdentifierEntryValidator, "IdentifierEntryValidator"),
|
|
148
153
|
IdentifierTypeValidator: /* @__PURE__ */ __name(() => IdentifierTypeValidator, "IdentifierTypeValidator"),
|
|
149
154
|
IdentityObjectValidator: /* @__PURE__ */ __name(() => IdentityObjectValidator, "IdentityObjectValidator"),
|
|
@@ -14591,7 +14596,8 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14591
14596
|
"PROFILE_PARENT_APPROVED",
|
|
14592
14597
|
"APP_LISTING_SUBMITTED",
|
|
14593
14598
|
"APP_LISTING_APPROVED",
|
|
14594
|
-
"APP_LISTING_REJECTED"
|
|
14599
|
+
"APP_LISTING_REJECTED",
|
|
14600
|
+
"DEVICE_LINK_REQUEST"
|
|
14595
14601
|
]);
|
|
14596
14602
|
var LCNNotificationMessageValidator = external_exports.object({
|
|
14597
14603
|
title: external_exports.string().optional(),
|
|
@@ -14730,6 +14736,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14730
14736
|
webhookUrl: external_exports.string().optional(),
|
|
14731
14737
|
boostUri: external_exports.string().optional(),
|
|
14732
14738
|
activityId: external_exports.string().optional(),
|
|
14739
|
+
integrationId: external_exports.string().optional(),
|
|
14733
14740
|
signingAuthority: external_exports.object({
|
|
14734
14741
|
endpoint: external_exports.string().optional(),
|
|
14735
14742
|
name: external_exports.string().optional()
|
|
@@ -14831,8 +14838,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14831
14838
|
claimUrl: external_exports.string().url().optional(),
|
|
14832
14839
|
recipientDid: external_exports.string().optional()
|
|
14833
14840
|
});
|
|
14841
|
+
var CredentialNameRefValidator = external_exports.object({ name: external_exports.string() }).passthrough();
|
|
14834
14842
|
var ClaimInboxCredentialValidator = external_exports.object({
|
|
14835
|
-
credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).describe("The credential to issue."),
|
|
14843
|
+
credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).or(CredentialNameRefValidator).describe("The credential to issue, or a { name } reference to resolve a boost template."),
|
|
14836
14844
|
configuration: external_exports.object({
|
|
14837
14845
|
publishableKey: external_exports.string(),
|
|
14838
14846
|
signingAuthorityName: external_exports.string().optional(),
|
|
@@ -15165,9 +15173,39 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15165
15173
|
var SendCredentialEventValidator = external_exports.object({
|
|
15166
15174
|
type: external_exports.literal("send-credential"),
|
|
15167
15175
|
templateAlias: external_exports.string(),
|
|
15168
|
-
templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
15176
|
+
templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
15177
|
+
preventDuplicateClaim: external_exports.boolean().optional()
|
|
15178
|
+
});
|
|
15179
|
+
var CheckCredentialEventValidator = external_exports.object({
|
|
15180
|
+
type: external_exports.literal("check-credential"),
|
|
15181
|
+
templateAlias: external_exports.string().optional(),
|
|
15182
|
+
boostUri: external_exports.string().optional()
|
|
15183
|
+
}).refine((input) => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
15184
|
+
message: "Exactly one of templateAlias or boostUri is required"
|
|
15185
|
+
});
|
|
15186
|
+
var CheckIssuanceStatusEventValidator = external_exports.object({
|
|
15187
|
+
type: external_exports.literal("check-issuance-status"),
|
|
15188
|
+
templateAlias: external_exports.string().optional(),
|
|
15189
|
+
boostUri: external_exports.string().optional(),
|
|
15190
|
+
recipient: external_exports.string()
|
|
15191
|
+
}).refine((input) => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
15192
|
+
message: "Exactly one of templateAlias or boostUri is required"
|
|
15169
15193
|
});
|
|
15170
|
-
var
|
|
15194
|
+
var GetTemplateRecipientsEventValidator = external_exports.object({
|
|
15195
|
+
type: external_exports.literal("get-template-recipients"),
|
|
15196
|
+
templateAlias: external_exports.string().optional(),
|
|
15197
|
+
boostUri: external_exports.string().optional(),
|
|
15198
|
+
limit: external_exports.number().optional(),
|
|
15199
|
+
cursor: external_exports.string().optional()
|
|
15200
|
+
}).refine((input) => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
15201
|
+
message: "Exactly one of templateAlias or boostUri is required"
|
|
15202
|
+
});
|
|
15203
|
+
var AppEventValidator = external_exports.discriminatedUnion("type", [
|
|
15204
|
+
SendCredentialEventValidator,
|
|
15205
|
+
CheckCredentialEventValidator,
|
|
15206
|
+
CheckIssuanceStatusEventValidator,
|
|
15207
|
+
GetTemplateRecipientsEventValidator
|
|
15208
|
+
]);
|
|
15171
15209
|
var AppEventInputValidator = external_exports.object({
|
|
15172
15210
|
listingId: external_exports.string(),
|
|
15173
15211
|
event: AppEventValidator
|
|
@@ -15230,6 +15268,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15230
15268
|
failed: external_exports.number(),
|
|
15231
15269
|
claimRate: external_exports.number()
|
|
15232
15270
|
});
|
|
15271
|
+
var AuthSessionError = class extends Error {
|
|
15272
|
+
static {
|
|
15273
|
+
__name(this, "AuthSessionError");
|
|
15274
|
+
}
|
|
15275
|
+
constructor(message, reason) {
|
|
15276
|
+
super(message);
|
|
15277
|
+
this.reason = reason;
|
|
15278
|
+
this.name = "AuthSessionError";
|
|
15279
|
+
}
|
|
15280
|
+
static {
|
|
15281
|
+
__name2(this, "AuthSessionError");
|
|
15282
|
+
}
|
|
15283
|
+
};
|
|
15233
15284
|
}
|
|
15234
15285
|
});
|
|
15235
15286
|
|
|
@@ -16060,6 +16111,90 @@ var ImageWithLoadingStateValdator = z.object({
|
|
|
16060
16111
|
var isNotUndefined = /* @__PURE__ */ __name((value) => Boolean(value), "isNotUndefined");
|
|
16061
16112
|
var filterUndefined = /* @__PURE__ */ __name((arr) => arr.filter(isNotUndefined), "filterUndefined");
|
|
16062
16113
|
|
|
16114
|
+
// src/app-install/index.ts
|
|
16115
|
+
var checkAppInstallEligibility = /* @__PURE__ */ __name((input) => {
|
|
16116
|
+
const {
|
|
16117
|
+
isChildProfile,
|
|
16118
|
+
userAge,
|
|
16119
|
+
minAge,
|
|
16120
|
+
ageRating,
|
|
16121
|
+
hasContract,
|
|
16122
|
+
hasGuardianApproval = false
|
|
16123
|
+
} = input;
|
|
16124
|
+
const ageRatingMinAge = getAgeRatingMinAge(ageRating);
|
|
16125
|
+
const isHardBlocked = userAge !== null && minAge !== void 0 && minAge > 0 && userAge < minAge;
|
|
16126
|
+
if (isHardBlocked) {
|
|
16127
|
+
return {
|
|
16128
|
+
action: "hard_blocked",
|
|
16129
|
+
reason: `User does not meet the minimum age requirement of ${minAge}`
|
|
16130
|
+
};
|
|
16131
|
+
}
|
|
16132
|
+
if (isChildProfile) {
|
|
16133
|
+
const noAgeRating = ageRatingMinAge === 0;
|
|
16134
|
+
const childAgeUnknown = userAge === null;
|
|
16135
|
+
const childTooYoung = userAge !== null && userAge < ageRatingMinAge;
|
|
16136
|
+
if (childAgeUnknown) {
|
|
16137
|
+
if (hasGuardianApproval) {
|
|
16138
|
+
return { action: "proceed" };
|
|
16139
|
+
}
|
|
16140
|
+
return {
|
|
16141
|
+
action: "require_dob",
|
|
16142
|
+
reason: "Child profile age is unknown and must be verified by guardian"
|
|
16143
|
+
};
|
|
16144
|
+
}
|
|
16145
|
+
if (noAgeRating) {
|
|
16146
|
+
if (hasGuardianApproval) {
|
|
16147
|
+
return { action: "proceed" };
|
|
16148
|
+
}
|
|
16149
|
+
return {
|
|
16150
|
+
action: "require_guardian_approval",
|
|
16151
|
+
reason: "App has no age rating; guardian approval required for child profiles"
|
|
16152
|
+
};
|
|
16153
|
+
}
|
|
16154
|
+
if (childTooYoung) {
|
|
16155
|
+
if (hasGuardianApproval) {
|
|
16156
|
+
return { action: "proceed" };
|
|
16157
|
+
}
|
|
16158
|
+
return {
|
|
16159
|
+
action: "require_guardian_approval",
|
|
16160
|
+
reason: `Child is under the age rating of ${ageRatingMinAge}+; guardian approval required`
|
|
16161
|
+
};
|
|
16162
|
+
}
|
|
16163
|
+
if (hasContract) {
|
|
16164
|
+
if (hasGuardianApproval) {
|
|
16165
|
+
return { action: "proceed" };
|
|
16166
|
+
}
|
|
16167
|
+
return {
|
|
16168
|
+
action: "require_guardian_approval",
|
|
16169
|
+
reason: "App requires consent to a contract; guardian approval required for child profiles"
|
|
16170
|
+
};
|
|
16171
|
+
}
|
|
16172
|
+
}
|
|
16173
|
+
return { action: "proceed" };
|
|
16174
|
+
}, "checkAppInstallEligibility");
|
|
16175
|
+
var AGE_RATING_TO_MIN_AGE = {
|
|
16176
|
+
"4+": 4,
|
|
16177
|
+
"9+": 9,
|
|
16178
|
+
"12+": 12,
|
|
16179
|
+
"17+": 17
|
|
16180
|
+
};
|
|
16181
|
+
var getAgeRatingMinAge = /* @__PURE__ */ __name((ageRating) => {
|
|
16182
|
+
if (!ageRating) return 0;
|
|
16183
|
+
return AGE_RATING_TO_MIN_AGE[ageRating] ?? 0;
|
|
16184
|
+
}, "getAgeRatingMinAge");
|
|
16185
|
+
var calculateAgeFromDob = /* @__PURE__ */ __name((dob) => {
|
|
16186
|
+
if (!dob) return null;
|
|
16187
|
+
const birthDate = new Date(dob);
|
|
16188
|
+
if (isNaN(birthDate.getTime())) return null;
|
|
16189
|
+
const today = /* @__PURE__ */ new Date();
|
|
16190
|
+
let age = today.getFullYear() - birthDate.getFullYear();
|
|
16191
|
+
const monthDiff = today.getMonth() - birthDate.getMonth();
|
|
16192
|
+
if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birthDate.getDate()) {
|
|
16193
|
+
age--;
|
|
16194
|
+
}
|
|
16195
|
+
return age;
|
|
16196
|
+
}, "calculateAgeFromDob");
|
|
16197
|
+
|
|
16063
16198
|
// src/index.ts
|
|
16064
16199
|
var isHex = /* @__PURE__ */ __name((str) => /^[0-9a-f]+$/i.test(str), "isHex");
|
|
16065
16200
|
var isEncrypted = /* @__PURE__ */ __name((item) => {
|
|
@@ -16109,13 +16244,16 @@ var isAppDidWeb = /* @__PURE__ */ __name((did) => {
|
|
|
16109
16244
|
return LCN_APP_DID_WEB_REGEX.test(did);
|
|
16110
16245
|
}, "isAppDidWeb");
|
|
16111
16246
|
export {
|
|
16247
|
+
AGE_RATING_TO_MIN_AGE,
|
|
16112
16248
|
DEFAULT_RESOLUTIONS,
|
|
16113
16249
|
ImageResizingValidator,
|
|
16114
16250
|
ImageUploadingValidator,
|
|
16115
16251
|
ImageWithLoadingStateValdator,
|
|
16116
16252
|
RegExpTransformer,
|
|
16253
|
+
calculateAgeFromDob,
|
|
16117
16254
|
capitalizeFirstLetter,
|
|
16118
16255
|
changeQuality4 as changeQuality,
|
|
16256
|
+
checkAppInstallEligibility,
|
|
16119
16257
|
curriedArraySlice,
|
|
16120
16258
|
curriedInnerImmerOuterImmer,
|
|
16121
16259
|
curriedInnerImmerOuterReact,
|