@tokenoftrust/cli 6.7.0 → 6.8.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tokenoftrust/cli",
3
- "version": "6.7.0",
3
+ "version": "6.8.0",
4
4
  "description": "Token of Trust developer CLI — clone a tenant store, run it locally with save→reload, and submit it for preview. Installs the `tot` command.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Token of Trust",
@@ -24,7 +24,7 @@ export const TOT_CONFIG_KEYS = [
24
24
  // Keys other tooling has written that the platform does NOT read, with the key it does.
25
25
  const RENAMED_CONFIG_KEYS = { appDomain: "scope", tenantId: "tenant" };
26
26
  export const COMPLIANCE_KEYS = [
27
- "ruleProfile", "minAge", "nicotineWarning", "shippingRestriction", "pactAct",
27
+ "ruleProfile", "minAge", "ageVerificationRequired", "nicotineWarning", "shippingRestriction", "pactAct",
28
28
  "adultSignature", "prop65", "purchaseLimit", "stateEligibility", "exciseTax",
29
29
  ];
30
30
  export const FEATURE_KEYS = [
@@ -352,6 +352,7 @@ function shippingProblemMessage(problems) {
352
352
  export const COMPLIANCE_NOTICES = {
353
353
  ruleProfile: "checkout compliance rules",
354
354
  minAge: "age gate",
355
+ ageVerificationRequired: "age verification",
355
356
  nicotineWarning: "FDA nicotine warning",
356
357
  shippingRestriction: "shipping-restriction notice",
357
358
  pactAct: "PACT Act notice",
@@ -395,6 +396,16 @@ export const COMPLIANCE_OBLIGATIONS = Object.freeze([
395
396
  { id: "jurisdiction", surface: "commerce", keys: ["stateEligibility", "shippingRestriction"] },
396
397
  ]);
397
398
 
399
+ /**
400
+ * Does the declared block require age/identity verification? Mirrors
401
+ * `ageVerificationRequired` in compliance-obligations.ts: required unless
402
+ * `ageVerificationRequired: false`, and always for a store that sells nicotine.
403
+ * @param {Record<string, any> | null | undefined} compliance
404
+ */
405
+ export function declaresAgeVerificationRequired(compliance) {
406
+ return compliance?.ageVerificationRequired !== false || !!compliance?.nicotineWarning;
407
+ }
408
+
398
409
  /**
399
410
  * The obligations a declared compliance block switches on, as `resolveObligations` returns
400
411
  * them (id + surface), in registry order.
@@ -404,6 +415,7 @@ export const COMPLIANCE_OBLIGATIONS = Object.freeze([
404
415
  export function declaredObligations(compliance) {
405
416
  return COMPLIANCE_OBLIGATIONS
406
417
  .filter((o) => o.keys.some((key) => !!compliance?.[key]))
418
+ .filter((o) => o.id !== "age_gate" || declaresAgeVerificationRequired(compliance))
407
419
  .map(({ id, surface }) => ({ id, surface }));
408
420
  }
409
421
 
@@ -572,6 +584,13 @@ export function complianceFindings(config, file = ".tot/config.json") {
572
584
  "`capabilities.exciseTax` cannot be disabled for a store with `compliance.nicotineWarning` or `compliance.exciseTax` — the hosted preview refuses this revision.",
573
585
  "Remove `capabilities.exciseTax.enabled: false` from .tot/config.json."));
574
586
  }
587
+ if (compliance?.ageVerificationRequired === false && compliance?.nicotineWarning) {
588
+ out.push(mk(WARN, "compliance-age-verification-policy", `${file} compliance`,
589
+ "`compliance.ageVerificationRequired: false` has no effect on a store that sells nicotine " +
590
+ "(`compliance.nicotineWarning`): platform policy keeps age/ID verification required at checkout.",
591
+ "Remove `compliance.ageVerificationRequired` from .tot/config.json, or turn only the arrival popup off " +
592
+ "with `features.ageGate: false`."));
593
+ }
575
594
  if (isRegulatedObligationSet(obligations) && !compliance?.ruleProfile) {
576
595
  out.push(mk(WARN, "compliance-rule-profile", `${file} compliance`,
577
596
  `This store is regulated (${regulatedBy(compliance, obligations)}) but declares no ` +