@learncard/helpers 1.2.9 → 1.2.11
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 +143 -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 +143 -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,9 @@ 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
|
+
"APP_LISTING_WITHDRAWN",
|
|
14601
|
+
"DEVICE_LINK_REQUEST"
|
|
14595
14602
|
]);
|
|
14596
14603
|
var LCNNotificationMessageValidator = external_exports.object({
|
|
14597
14604
|
title: external_exports.string().optional(),
|
|
@@ -14730,6 +14737,7 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14730
14737
|
webhookUrl: external_exports.string().optional(),
|
|
14731
14738
|
boostUri: external_exports.string().optional(),
|
|
14732
14739
|
activityId: external_exports.string().optional(),
|
|
14740
|
+
integrationId: external_exports.string().optional(),
|
|
14733
14741
|
signingAuthority: external_exports.object({
|
|
14734
14742
|
endpoint: external_exports.string().optional(),
|
|
14735
14743
|
name: external_exports.string().optional()
|
|
@@ -14831,8 +14839,9 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
14831
14839
|
claimUrl: external_exports.string().url().optional(),
|
|
14832
14840
|
recipientDid: external_exports.string().optional()
|
|
14833
14841
|
});
|
|
14842
|
+
var CredentialNameRefValidator = external_exports.object({ name: external_exports.string() }).passthrough();
|
|
14834
14843
|
var ClaimInboxCredentialValidator = external_exports.object({
|
|
14835
|
-
credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).describe("The credential to issue."),
|
|
14844
|
+
credential: VCValidator.or(VPValidator).or(UnsignedVCValidator).or(CredentialNameRefValidator).describe("The credential to issue, or a { name } reference to resolve a boost template."),
|
|
14836
14845
|
configuration: external_exports.object({
|
|
14837
14846
|
publishableKey: external_exports.string(),
|
|
14838
14847
|
signingAuthorityName: external_exports.string().optional(),
|
|
@@ -15165,9 +15174,39 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15165
15174
|
var SendCredentialEventValidator = external_exports.object({
|
|
15166
15175
|
type: external_exports.literal("send-credential"),
|
|
15167
15176
|
templateAlias: external_exports.string(),
|
|
15168
|
-
templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
|
|
15177
|
+
templateData: external_exports.record(external_exports.string(), external_exports.unknown()).optional(),
|
|
15178
|
+
preventDuplicateClaim: external_exports.boolean().optional()
|
|
15179
|
+
});
|
|
15180
|
+
var CheckCredentialEventValidator = external_exports.object({
|
|
15181
|
+
type: external_exports.literal("check-credential"),
|
|
15182
|
+
templateAlias: external_exports.string().optional(),
|
|
15183
|
+
boostUri: external_exports.string().optional()
|
|
15184
|
+
}).refine((input) => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
15185
|
+
message: "Exactly one of templateAlias or boostUri is required"
|
|
15186
|
+
});
|
|
15187
|
+
var CheckIssuanceStatusEventValidator = external_exports.object({
|
|
15188
|
+
type: external_exports.literal("check-issuance-status"),
|
|
15189
|
+
templateAlias: external_exports.string().optional(),
|
|
15190
|
+
boostUri: external_exports.string().optional(),
|
|
15191
|
+
recipient: external_exports.string()
|
|
15192
|
+
}).refine((input) => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
15193
|
+
message: "Exactly one of templateAlias or boostUri is required"
|
|
15169
15194
|
});
|
|
15170
|
-
var
|
|
15195
|
+
var GetTemplateRecipientsEventValidator = external_exports.object({
|
|
15196
|
+
type: external_exports.literal("get-template-recipients"),
|
|
15197
|
+
templateAlias: external_exports.string().optional(),
|
|
15198
|
+
boostUri: external_exports.string().optional(),
|
|
15199
|
+
limit: external_exports.number().optional(),
|
|
15200
|
+
cursor: external_exports.string().optional()
|
|
15201
|
+
}).refine((input) => Boolean(input.templateAlias) !== Boolean(input.boostUri), {
|
|
15202
|
+
message: "Exactly one of templateAlias or boostUri is required"
|
|
15203
|
+
});
|
|
15204
|
+
var AppEventValidator = external_exports.discriminatedUnion("type", [
|
|
15205
|
+
SendCredentialEventValidator,
|
|
15206
|
+
CheckCredentialEventValidator,
|
|
15207
|
+
CheckIssuanceStatusEventValidator,
|
|
15208
|
+
GetTemplateRecipientsEventValidator
|
|
15209
|
+
]);
|
|
15171
15210
|
var AppEventInputValidator = external_exports.object({
|
|
15172
15211
|
listingId: external_exports.string(),
|
|
15173
15212
|
event: AppEventValidator
|
|
@@ -15230,6 +15269,19 @@ Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.
|
|
|
15230
15269
|
failed: external_exports.number(),
|
|
15231
15270
|
claimRate: external_exports.number()
|
|
15232
15271
|
});
|
|
15272
|
+
var AuthSessionError = class extends Error {
|
|
15273
|
+
static {
|
|
15274
|
+
__name(this, "AuthSessionError");
|
|
15275
|
+
}
|
|
15276
|
+
constructor(message, reason) {
|
|
15277
|
+
super(message);
|
|
15278
|
+
this.reason = reason;
|
|
15279
|
+
this.name = "AuthSessionError";
|
|
15280
|
+
}
|
|
15281
|
+
static {
|
|
15282
|
+
__name2(this, "AuthSessionError");
|
|
15283
|
+
}
|
|
15284
|
+
};
|
|
15233
15285
|
}
|
|
15234
15286
|
});
|
|
15235
15287
|
|
|
@@ -16060,6 +16112,90 @@ var ImageWithLoadingStateValdator = z.object({
|
|
|
16060
16112
|
var isNotUndefined = /* @__PURE__ */ __name((value) => Boolean(value), "isNotUndefined");
|
|
16061
16113
|
var filterUndefined = /* @__PURE__ */ __name((arr) => arr.filter(isNotUndefined), "filterUndefined");
|
|
16062
16114
|
|
|
16115
|
+
// src/app-install/index.ts
|
|
16116
|
+
var checkAppInstallEligibility = /* @__PURE__ */ __name((input) => {
|
|
16117
|
+
const {
|
|
16118
|
+
isChildProfile,
|
|
16119
|
+
userAge,
|
|
16120
|
+
minAge,
|
|
16121
|
+
ageRating,
|
|
16122
|
+
hasContract,
|
|
16123
|
+
hasGuardianApproval = false
|
|
16124
|
+
} = input;
|
|
16125
|
+
const ageRatingMinAge = getAgeRatingMinAge(ageRating);
|
|
16126
|
+
const isHardBlocked = userAge !== null && minAge !== void 0 && minAge > 0 && userAge < minAge;
|
|
16127
|
+
if (isHardBlocked) {
|
|
16128
|
+
return {
|
|
16129
|
+
action: "hard_blocked",
|
|
16130
|
+
reason: `User does not meet the minimum age requirement of ${minAge}`
|
|
16131
|
+
};
|
|
16132
|
+
}
|
|
16133
|
+
if (isChildProfile) {
|
|
16134
|
+
const noAgeRating = ageRatingMinAge === 0;
|
|
16135
|
+
const childAgeUnknown = userAge === null;
|
|
16136
|
+
const childTooYoung = userAge !== null && userAge < ageRatingMinAge;
|
|
16137
|
+
if (childAgeUnknown) {
|
|
16138
|
+
if (hasGuardianApproval) {
|
|
16139
|
+
return { action: "proceed" };
|
|
16140
|
+
}
|
|
16141
|
+
return {
|
|
16142
|
+
action: "require_dob",
|
|
16143
|
+
reason: "Child profile age is unknown and must be verified by guardian"
|
|
16144
|
+
};
|
|
16145
|
+
}
|
|
16146
|
+
if (noAgeRating) {
|
|
16147
|
+
if (hasGuardianApproval) {
|
|
16148
|
+
return { action: "proceed" };
|
|
16149
|
+
}
|
|
16150
|
+
return {
|
|
16151
|
+
action: "require_guardian_approval",
|
|
16152
|
+
reason: "App has no age rating; guardian approval required for child profiles"
|
|
16153
|
+
};
|
|
16154
|
+
}
|
|
16155
|
+
if (childTooYoung) {
|
|
16156
|
+
if (hasGuardianApproval) {
|
|
16157
|
+
return { action: "proceed" };
|
|
16158
|
+
}
|
|
16159
|
+
return {
|
|
16160
|
+
action: "require_guardian_approval",
|
|
16161
|
+
reason: `Child is under the age rating of ${ageRatingMinAge}+; guardian approval required`
|
|
16162
|
+
};
|
|
16163
|
+
}
|
|
16164
|
+
if (hasContract) {
|
|
16165
|
+
if (hasGuardianApproval) {
|
|
16166
|
+
return { action: "proceed" };
|
|
16167
|
+
}
|
|
16168
|
+
return {
|
|
16169
|
+
action: "require_guardian_approval",
|
|
16170
|
+
reason: "App requires consent to a contract; guardian approval required for child profiles"
|
|
16171
|
+
};
|
|
16172
|
+
}
|
|
16173
|
+
}
|
|
16174
|
+
return { action: "proceed" };
|
|
16175
|
+
}, "checkAppInstallEligibility");
|
|
16176
|
+
var AGE_RATING_TO_MIN_AGE = {
|
|
16177
|
+
"4+": 4,
|
|
16178
|
+
"9+": 9,
|
|
16179
|
+
"12+": 12,
|
|
16180
|
+
"17+": 17
|
|
16181
|
+
};
|
|
16182
|
+
var getAgeRatingMinAge = /* @__PURE__ */ __name((ageRating) => {
|
|
16183
|
+
if (!ageRating) return 0;
|
|
16184
|
+
return AGE_RATING_TO_MIN_AGE[ageRating] ?? 0;
|
|
16185
|
+
}, "getAgeRatingMinAge");
|
|
16186
|
+
var calculateAgeFromDob = /* @__PURE__ */ __name((dob) => {
|
|
16187
|
+
if (!dob) return null;
|
|
16188
|
+
const birthDate = new Date(dob);
|
|
16189
|
+
if (isNaN(birthDate.getTime())) return null;
|
|
16190
|
+
const today = /* @__PURE__ */ new Date();
|
|
16191
|
+
let age = today.getFullYear() - birthDate.getFullYear();
|
|
16192
|
+
const monthDiff = today.getMonth() - birthDate.getMonth();
|
|
16193
|
+
if (monthDiff < 0 || monthDiff === 0 && today.getDate() < birthDate.getDate()) {
|
|
16194
|
+
age--;
|
|
16195
|
+
}
|
|
16196
|
+
return age;
|
|
16197
|
+
}, "calculateAgeFromDob");
|
|
16198
|
+
|
|
16063
16199
|
// src/index.ts
|
|
16064
16200
|
var isHex = /* @__PURE__ */ __name((str) => /^[0-9a-f]+$/i.test(str), "isHex");
|
|
16065
16201
|
var isEncrypted = /* @__PURE__ */ __name((item) => {
|
|
@@ -16109,13 +16245,16 @@ var isAppDidWeb = /* @__PURE__ */ __name((did) => {
|
|
|
16109
16245
|
return LCN_APP_DID_WEB_REGEX.test(did);
|
|
16110
16246
|
}, "isAppDidWeb");
|
|
16111
16247
|
export {
|
|
16248
|
+
AGE_RATING_TO_MIN_AGE,
|
|
16112
16249
|
DEFAULT_RESOLUTIONS,
|
|
16113
16250
|
ImageResizingValidator,
|
|
16114
16251
|
ImageUploadingValidator,
|
|
16115
16252
|
ImageWithLoadingStateValdator,
|
|
16116
16253
|
RegExpTransformer,
|
|
16254
|
+
calculateAgeFromDob,
|
|
16117
16255
|
capitalizeFirstLetter,
|
|
16118
16256
|
changeQuality4 as changeQuality,
|
|
16257
|
+
checkAppInstallEligibility,
|
|
16119
16258
|
curriedArraySlice,
|
|
16120
16259
|
curriedInnerImmerOuterImmer,
|
|
16121
16260
|
curriedInnerImmerOuterReact,
|