@plasius/schema 1.2.17 → 1.3.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/dist/index.d.cts CHANGED
@@ -339,8 +339,11 @@ declare function getComponentSchema(type: string): Schema<SchemaShape> | undefin
339
339
  declare function getAllComponentSchemas(): [string, Schema<SchemaShape>][];
340
340
 
341
341
  /**
342
- * Validates an email string using a simplified RFC 5322-compliant regex.
343
- * Returns true if the input is a string in the format `name@domain.tld`.
342
+ * Validates the package's pragmatic dot-domain mailbox subset.
343
+ *
344
+ * This intentionally does not claim full RFC 5322 mailbox support (for
345
+ * example, quoted local parts and address literals are outside the product
346
+ * contract). The legacy filename is retained for import compatibility.
344
347
  */
345
348
  declare const validateEmail: (value: unknown) => boolean;
346
349
 
@@ -358,8 +361,8 @@ declare const validatePhone: (value: unknown) => boolean;
358
361
  declare const validateUrl: (value: unknown) => boolean;
359
362
 
360
363
  /**
361
- * Validates a string against the RFC 4122 format for UUIDs.
362
- * Matches UUIDs of versions 1 to 5, e.g., "123e4567-e89b-12d3-a456-426614174000".
364
+ * Validates the RFC 9562 UUID text format, including versions 1-8 plus Nil and
365
+ * Max UUIDs. The legacy filename is retained for import compatibility.
363
366
  */
364
367
  declare const validateUUID: (value: unknown) => boolean;
365
368
 
@@ -652,4 +655,112 @@ declare function isPrivateUseSubtag(value: string): boolean;
652
655
  */
653
656
  declare function validateLanguage(value: unknown): boolean;
654
657
 
655
- export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type FieldValidator, type FieldValidatorResult, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationIssue, type ValidationIssueInput, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
658
+ /** Event classes that can be observed by a player. */
659
+ declare const PLAYER_SYSTEM_EVENT_KINDS: readonly ["combat", "social", "mission", "crafting", "world"];
660
+ type PlayerSystemEventKind = (typeof PLAYER_SYSTEM_EVENT_KINDS)[number];
661
+ /** Achievement tiers exposed by the curated player projection. */
662
+ declare const PLAYER_SYSTEM_ACHIEVEMENT_TIERS: readonly ["bronze", "silver", "gold"];
663
+ type PlayerSystemAchievementTier = (typeof PLAYER_SYSTEM_ACHIEVEMENT_TIERS)[number];
664
+ /** Projection states for an achievement progress track. */
665
+ declare const PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES: readonly ["tracking", "earned"];
666
+ type PlayerSystemAchievementTrackStatus = (typeof PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES)[number];
667
+ /** A player-observable event accepted at the ingestion boundary. */
668
+ interface PlayerSystemObservedEvent {
669
+ id: string;
670
+ playerId: string;
671
+ occurredAt: string;
672
+ kind: PlayerSystemEventKind;
673
+ title: string;
674
+ summary: string;
675
+ highlighted: boolean;
676
+ }
677
+ /** A raw event batch written to the blob-backed ingestion zone. */
678
+ interface PlayerSystemObservedEventBatch {
679
+ source: string;
680
+ emittedAt: string;
681
+ events: readonly PlayerSystemObservedEvent[];
682
+ }
683
+ /** A normalized event enriched with its deterministic deduplication key. */
684
+ interface PlayerSystemNormalizedObservedEvent extends PlayerSystemObservedEvent {
685
+ deterministicKey: string;
686
+ }
687
+ /** A normalized event batch written by the projection processor. */
688
+ interface PlayerSystemNormalizedEventBatch {
689
+ sourceBlobName: string;
690
+ processedAt: string;
691
+ events: readonly PlayerSystemNormalizedObservedEvent[];
692
+ }
693
+ /** A highlighted event shown in the curated player Event Log. */
694
+ interface PlayerSystemEventHighlight {
695
+ id: string;
696
+ title: string;
697
+ summary: string;
698
+ occurredAt: string;
699
+ kind: PlayerSystemEventKind;
700
+ }
701
+ /** A recent event shown in the curated player Event Log. */
702
+ interface PlayerSystemEventEntry extends PlayerSystemEventHighlight {
703
+ highlighted: boolean;
704
+ }
705
+ /** An earned or explainable achievement projected from observed events. */
706
+ interface PlayerSystemAchievementEntry {
707
+ id: string;
708
+ title: string;
709
+ tier: PlayerSystemAchievementTier;
710
+ progressLabel: string;
711
+ earnedAt?: string;
712
+ }
713
+ /** Progress toward an achievement projected from observed events. */
714
+ interface PlayerSystemAchievementTrack {
715
+ id: string;
716
+ title: string;
717
+ current: number;
718
+ target: number;
719
+ status: PlayerSystemAchievementTrackStatus;
720
+ }
721
+ /** Curated per-player Event Log and Achievement read model. */
722
+ interface PlayerSystemCuratedSnapshot {
723
+ playerId: string;
724
+ projectedAt: string;
725
+ lastObservedAt: string;
726
+ highlights: readonly PlayerSystemEventHighlight[];
727
+ events: readonly PlayerSystemEventEntry[];
728
+ achievements: readonly PlayerSystemAchievementEntry[];
729
+ tracks: readonly PlayerSystemAchievementTrack[];
730
+ }
731
+ /** Schema for raw player-observable event batches. */
732
+ declare const PlayerSystemObservedEventBatchSchema: Schema<{
733
+ source: FieldBuilder<string, string>;
734
+ emittedAt: FieldBuilder<string, string>;
735
+ events: FieldBuilder<unknown, unknown>;
736
+ }>;
737
+ /** Schema for normalized event batches used by projections and gossip sourcing. */
738
+ declare const PlayerSystemNormalizedEventBatchSchema: Schema<{
739
+ sourceBlobName: FieldBuilder<string, string>;
740
+ processedAt: FieldBuilder<string, string>;
741
+ events: FieldBuilder<unknown, unknown>;
742
+ }>;
743
+ /** Schema for curated per-player Event Log and Achievement read models. */
744
+ declare const PlayerSystemCuratedSnapshotSchema: Schema<{
745
+ playerId: FieldBuilder<string, string>;
746
+ projectedAt: FieldBuilder<string, string>;
747
+ lastObservedAt: FieldBuilder<string, string>;
748
+ highlights: FieldBuilder<unknown, unknown>;
749
+ events: FieldBuilder<unknown, unknown>;
750
+ achievements: FieldBuilder<unknown, unknown>;
751
+ tracks: FieldBuilder<unknown, unknown>;
752
+ }>;
753
+ type PlayerSystemObservedEventBatchEntity = PlayerSystemObservedEventBatch & {
754
+ type: "player-system-observed-event-batch";
755
+ version: "1.0.0";
756
+ };
757
+ type PlayerSystemNormalizedEventBatchEntity = PlayerSystemNormalizedEventBatch & {
758
+ type: "player-system-normalized-event-batch";
759
+ version: "1.0.0";
760
+ };
761
+ type PlayerSystemCuratedSnapshotEntity = PlayerSystemCuratedSnapshot & {
762
+ type: "player-system-curated-snapshot";
763
+ version: "1.0.0";
764
+ };
765
+
766
+ export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type FieldValidator, type FieldValidatorResult, type Infer, IsoLanguageCode, type PIIEnforcement, PLAYER_SYSTEM_ACHIEVEMENT_TIERS, PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES, PLAYER_SYSTEM_EVENT_KINDS, type PlayerSystemAchievementEntry, type PlayerSystemAchievementTier, type PlayerSystemAchievementTrack, type PlayerSystemAchievementTrackStatus, type PlayerSystemCuratedSnapshot, type PlayerSystemCuratedSnapshotEntity, PlayerSystemCuratedSnapshotSchema, type PlayerSystemEventEntry, type PlayerSystemEventHighlight, type PlayerSystemEventKind, type PlayerSystemNormalizedEventBatch, type PlayerSystemNormalizedEventBatchEntity, PlayerSystemNormalizedEventBatchSchema, type PlayerSystemNormalizedObservedEvent, type PlayerSystemObservedEvent, type PlayerSystemObservedEventBatch, type PlayerSystemObservedEventBatchEntity, PlayerSystemObservedEventBatchSchema, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationIssue, type ValidationIssueInput, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
package/dist/index.d.ts CHANGED
@@ -339,8 +339,11 @@ declare function getComponentSchema(type: string): Schema<SchemaShape> | undefin
339
339
  declare function getAllComponentSchemas(): [string, Schema<SchemaShape>][];
340
340
 
341
341
  /**
342
- * Validates an email string using a simplified RFC 5322-compliant regex.
343
- * Returns true if the input is a string in the format `name@domain.tld`.
342
+ * Validates the package's pragmatic dot-domain mailbox subset.
343
+ *
344
+ * This intentionally does not claim full RFC 5322 mailbox support (for
345
+ * example, quoted local parts and address literals are outside the product
346
+ * contract). The legacy filename is retained for import compatibility.
344
347
  */
345
348
  declare const validateEmail: (value: unknown) => boolean;
346
349
 
@@ -358,8 +361,8 @@ declare const validatePhone: (value: unknown) => boolean;
358
361
  declare const validateUrl: (value: unknown) => boolean;
359
362
 
360
363
  /**
361
- * Validates a string against the RFC 4122 format for UUIDs.
362
- * Matches UUIDs of versions 1 to 5, e.g., "123e4567-e89b-12d3-a456-426614174000".
364
+ * Validates the RFC 9562 UUID text format, including versions 1-8 plus Nil and
365
+ * Max UUIDs. The legacy filename is retained for import compatibility.
363
366
  */
364
367
  declare const validateUUID: (value: unknown) => boolean;
365
368
 
@@ -652,4 +655,112 @@ declare function isPrivateUseSubtag(value: string): boolean;
652
655
  */
653
656
  declare function validateLanguage(value: unknown): boolean;
654
657
 
655
- export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type FieldValidator, type FieldValidatorResult, type Infer, IsoLanguageCode, type PIIEnforcement, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationIssue, type ValidationIssueInput, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
658
+ /** Event classes that can be observed by a player. */
659
+ declare const PLAYER_SYSTEM_EVENT_KINDS: readonly ["combat", "social", "mission", "crafting", "world"];
660
+ type PlayerSystemEventKind = (typeof PLAYER_SYSTEM_EVENT_KINDS)[number];
661
+ /** Achievement tiers exposed by the curated player projection. */
662
+ declare const PLAYER_SYSTEM_ACHIEVEMENT_TIERS: readonly ["bronze", "silver", "gold"];
663
+ type PlayerSystemAchievementTier = (typeof PLAYER_SYSTEM_ACHIEVEMENT_TIERS)[number];
664
+ /** Projection states for an achievement progress track. */
665
+ declare const PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES: readonly ["tracking", "earned"];
666
+ type PlayerSystemAchievementTrackStatus = (typeof PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES)[number];
667
+ /** A player-observable event accepted at the ingestion boundary. */
668
+ interface PlayerSystemObservedEvent {
669
+ id: string;
670
+ playerId: string;
671
+ occurredAt: string;
672
+ kind: PlayerSystemEventKind;
673
+ title: string;
674
+ summary: string;
675
+ highlighted: boolean;
676
+ }
677
+ /** A raw event batch written to the blob-backed ingestion zone. */
678
+ interface PlayerSystemObservedEventBatch {
679
+ source: string;
680
+ emittedAt: string;
681
+ events: readonly PlayerSystemObservedEvent[];
682
+ }
683
+ /** A normalized event enriched with its deterministic deduplication key. */
684
+ interface PlayerSystemNormalizedObservedEvent extends PlayerSystemObservedEvent {
685
+ deterministicKey: string;
686
+ }
687
+ /** A normalized event batch written by the projection processor. */
688
+ interface PlayerSystemNormalizedEventBatch {
689
+ sourceBlobName: string;
690
+ processedAt: string;
691
+ events: readonly PlayerSystemNormalizedObservedEvent[];
692
+ }
693
+ /** A highlighted event shown in the curated player Event Log. */
694
+ interface PlayerSystemEventHighlight {
695
+ id: string;
696
+ title: string;
697
+ summary: string;
698
+ occurredAt: string;
699
+ kind: PlayerSystemEventKind;
700
+ }
701
+ /** A recent event shown in the curated player Event Log. */
702
+ interface PlayerSystemEventEntry extends PlayerSystemEventHighlight {
703
+ highlighted: boolean;
704
+ }
705
+ /** An earned or explainable achievement projected from observed events. */
706
+ interface PlayerSystemAchievementEntry {
707
+ id: string;
708
+ title: string;
709
+ tier: PlayerSystemAchievementTier;
710
+ progressLabel: string;
711
+ earnedAt?: string;
712
+ }
713
+ /** Progress toward an achievement projected from observed events. */
714
+ interface PlayerSystemAchievementTrack {
715
+ id: string;
716
+ title: string;
717
+ current: number;
718
+ target: number;
719
+ status: PlayerSystemAchievementTrackStatus;
720
+ }
721
+ /** Curated per-player Event Log and Achievement read model. */
722
+ interface PlayerSystemCuratedSnapshot {
723
+ playerId: string;
724
+ projectedAt: string;
725
+ lastObservedAt: string;
726
+ highlights: readonly PlayerSystemEventHighlight[];
727
+ events: readonly PlayerSystemEventEntry[];
728
+ achievements: readonly PlayerSystemAchievementEntry[];
729
+ tracks: readonly PlayerSystemAchievementTrack[];
730
+ }
731
+ /** Schema for raw player-observable event batches. */
732
+ declare const PlayerSystemObservedEventBatchSchema: Schema<{
733
+ source: FieldBuilder<string, string>;
734
+ emittedAt: FieldBuilder<string, string>;
735
+ events: FieldBuilder<unknown, unknown>;
736
+ }>;
737
+ /** Schema for normalized event batches used by projections and gossip sourcing. */
738
+ declare const PlayerSystemNormalizedEventBatchSchema: Schema<{
739
+ sourceBlobName: FieldBuilder<string, string>;
740
+ processedAt: FieldBuilder<string, string>;
741
+ events: FieldBuilder<unknown, unknown>;
742
+ }>;
743
+ /** Schema for curated per-player Event Log and Achievement read models. */
744
+ declare const PlayerSystemCuratedSnapshotSchema: Schema<{
745
+ playerId: FieldBuilder<string, string>;
746
+ projectedAt: FieldBuilder<string, string>;
747
+ lastObservedAt: FieldBuilder<string, string>;
748
+ highlights: FieldBuilder<unknown, unknown>;
749
+ events: FieldBuilder<unknown, unknown>;
750
+ achievements: FieldBuilder<unknown, unknown>;
751
+ tracks: FieldBuilder<unknown, unknown>;
752
+ }>;
753
+ type PlayerSystemObservedEventBatchEntity = PlayerSystemObservedEventBatch & {
754
+ type: "player-system-observed-event-batch";
755
+ version: "1.0.0";
756
+ };
757
+ type PlayerSystemNormalizedEventBatchEntity = PlayerSystemNormalizedEventBatch & {
758
+ type: "player-system-normalized-event-batch";
759
+ version: "1.0.0";
760
+ };
761
+ type PlayerSystemCuratedSnapshotEntity = PlayerSystemCuratedSnapshot & {
762
+ type: "player-system-curated-snapshot";
763
+ version: "1.0.0";
764
+ };
765
+
766
+ export { type DeepReadonly, FieldBuilder, type FieldDefinition, type FieldExposure, type FieldType, type FieldTypeMap, type FieldValidator, type FieldValidatorResult, type Infer, IsoLanguageCode, type PIIEnforcement, PLAYER_SYSTEM_ACHIEVEMENT_TIERS, PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES, PLAYER_SYSTEM_EVENT_KINDS, type PlayerSystemAchievementEntry, type PlayerSystemAchievementTier, type PlayerSystemAchievementTrack, type PlayerSystemAchievementTrackStatus, type PlayerSystemCuratedSnapshot, type PlayerSystemCuratedSnapshotEntity, PlayerSystemCuratedSnapshotSchema, type PlayerSystemEventEntry, type PlayerSystemEventHighlight, type PlayerSystemEventKind, type PlayerSystemNormalizedEventBatch, type PlayerSystemNormalizedEventBatchEntity, PlayerSystemNormalizedEventBatchSchema, type PlayerSystemNormalizedObservedEvent, type PlayerSystemObservedEvent, type PlayerSystemObservedEventBatch, type PlayerSystemObservedEventBatchEntity, PlayerSystemObservedEventBatchSchema, type RefEntityId, type Schema, type SchemaOptions, type SchemaShape, type SchemaUpgradeFunction, type SchemaUpgradeResult, type SchemaUpgradeSpec, type SchemaUpgradeStep, type SerializeOptions, type ValidateCompositionOptions, type ValidationIssue, type ValidationIssueInput, type ValidationResult, createComponentSchema, createSchema, field, getAllComponentSchemas, getAllSchemas, getComponentSchema, getSchemaForType, isExtensionSingleton, isExtensionSubtag, isIsoLanguageCode, isPrivateUseSingleton, isPrivateUseSubtag, isRegionSubtag, isScriptSubtag, isVariantSubtag, isoCountryCodes, isoCurrencyCodes, registerComponentSchema, renderSchemaDescription, validateCountryCode, validateCurrencyCode, validateDateTimeISO, validateEmail, validateLanguage, validateName, validatePercentage, validatePhone, validateRichText, validateSafeText, validateSemVer, validateUUID, validateUrl, validateUserId, validateUserIdArray };
package/dist/index.js CHANGED
@@ -223,8 +223,8 @@ var validateUrl = (value) => {
223
223
  // src/validation/uuid.RFC4122.ts
224
224
  var validateUUID = (value) => {
225
225
  if (typeof value !== "string") return false;
226
- const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
227
- return uuidRegex.test(value);
226
+ const standard = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
227
+ return standard.test(value) || value.toLowerCase() === "00000000-0000-0000-0000-000000000000" || value.toLowerCase() === "ffffffff-ffff-ffff-ffff-ffffffffffff";
228
228
  };
229
229
 
230
230
  // src/validation/dateTime.ISO8601.ts
@@ -971,10 +971,10 @@ function isIsoLanguageCode(value) {
971
971
  return typeof value === "string" && ISO_LANGUAGE_SET.has(value.toLowerCase());
972
972
  }
973
973
  function isRegionSubtag(value) {
974
- return /^[A-Z]{2}$/.test(value) || /^\d{3}$/.test(value);
974
+ return /^[A-Za-z]{2}$/.test(value) || /^\d{3}$/.test(value);
975
975
  }
976
976
  function isScriptSubtag(value) {
977
- return /^[A-Z][a-z]{3}$/.test(value);
977
+ return /^[A-Za-z]{4}$/.test(value);
978
978
  }
979
979
  function isVariantSubtag(value) {
980
980
  return /^([0-9][A-Za-z0-9]{3}|[A-Za-z0-9]{5,8})$/.test(value);
@@ -994,20 +994,42 @@ function isPrivateUseSubtag(value) {
994
994
  function validateLanguage(value) {
995
995
  if (typeof value !== "string" || value.length === 0) return false;
996
996
  const parts = value.split("-");
997
+ if (parts.some((part) => part.length === 0)) return false;
998
+ const lowerTag = value.toLowerCase();
999
+ if (GRANDFATHERED_TAGS.has(lowerTag)) return true;
1000
+ if (parts[0]?.toLowerCase() === "x") {
1001
+ return parts.length > 1 && parts.slice(1).every(isPrivateUseSubtag);
1002
+ }
997
1003
  let i = 0;
998
1004
  const lang = parts[i];
999
- if (!lang || !isIsoLanguageCode(lang)) return false;
1005
+ if (!lang || !/^[A-Za-z]{2,3}$/.test(lang)) return false;
1006
+ if (lang.length === 2 && !isIsoLanguageCode(lang)) return false;
1000
1007
  i += 1;
1008
+ if (lang.length <= 3) {
1009
+ let extlangCount = 0;
1010
+ while (i < parts.length && extlangCount < 3 && /^[A-Za-z]{3}$/.test(parts[i])) {
1011
+ i += 1;
1012
+ extlangCount += 1;
1013
+ }
1014
+ }
1001
1015
  if (i < parts.length && isScriptSubtag(parts[i])) {
1002
1016
  i += 1;
1003
1017
  }
1004
1018
  if (i < parts.length && isRegionSubtag(parts[i].toUpperCase())) {
1005
1019
  i += 1;
1006
1020
  }
1021
+ const variants = /* @__PURE__ */ new Set();
1007
1022
  while (i < parts.length && isVariantSubtag(parts[i])) {
1023
+ const variant = parts[i].toLowerCase();
1024
+ if (variants.has(variant)) return false;
1025
+ variants.add(variant);
1008
1026
  i += 1;
1009
1027
  }
1028
+ const extensionSingletons = /* @__PURE__ */ new Set();
1010
1029
  while (i < parts.length && isExtensionSingleton(parts[i])) {
1030
+ const singleton = parts[i].toLowerCase();
1031
+ if (extensionSingletons.has(singleton)) return false;
1032
+ extensionSingletons.add(singleton);
1011
1033
  i += 1;
1012
1034
  if (!(i < parts.length && isExtensionSubtag(parts[i]))) return false;
1013
1035
  while (i < parts.length && isExtensionSubtag(parts[i])) {
@@ -1023,6 +1045,34 @@ function validateLanguage(value) {
1023
1045
  }
1024
1046
  return i === parts.length;
1025
1047
  }
1048
+ var GRANDFATHERED_TAGS = /* @__PURE__ */ new Set([
1049
+ "art-lojban",
1050
+ "cel-gaulish",
1051
+ "en-gb-oed",
1052
+ "i-ami",
1053
+ "i-bnn",
1054
+ "i-default",
1055
+ "i-enochian",
1056
+ "i-hak",
1057
+ "i-klingon",
1058
+ "i-lux",
1059
+ "i-mingo",
1060
+ "i-navajo",
1061
+ "i-pwn",
1062
+ "i-tao",
1063
+ "i-tay",
1064
+ "i-tsu",
1065
+ "no-bok",
1066
+ "no-nyn",
1067
+ "sgn-be-fr",
1068
+ "sgn-be-nl",
1069
+ "sgn-ch-de",
1070
+ "zh-guoyu",
1071
+ "zh-hakka",
1072
+ "zh-min",
1073
+ "zh-min-nan",
1074
+ "zh-xiang"
1075
+ ]);
1026
1076
 
1027
1077
  // src/field.ts
1028
1078
  var field = {
@@ -2448,9 +2498,128 @@ function getComponentSchema(type) {
2448
2498
  function getAllComponentSchemas() {
2449
2499
  return Array.from(componentSchemaRegistry.entries());
2450
2500
  }
2501
+
2502
+ // src/player-system-events.ts
2503
+ var PLAYER_SYSTEM_EVENT_KINDS = [
2504
+ "combat",
2505
+ "social",
2506
+ "mission",
2507
+ "crafting",
2508
+ "world"
2509
+ ];
2510
+ var PLAYER_SYSTEM_ACHIEVEMENT_TIERS = [
2511
+ "bronze",
2512
+ "silver",
2513
+ "gold"
2514
+ ];
2515
+ var PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES = [
2516
+ "tracking",
2517
+ "earned"
2518
+ ];
2519
+ var playerIdField = () => field.string().min(1).max(128).PID({
2520
+ classification: "low",
2521
+ action: "none",
2522
+ logHandling: "pseudonym",
2523
+ purpose: "a stable player-scoped storage identifier"
2524
+ }).description(
2525
+ "Stable player identifier; the only personal identifier retained in event projections"
2526
+ );
2527
+ var eventIdField = () => field.string().min(1).max(128);
2528
+ var eventKindField = () => field.string().enum(PLAYER_SYSTEM_EVENT_KINDS);
2529
+ var eventTitleField = () => field.generalText().min(1).max(120).description("Player-visible event title");
2530
+ var eventSummaryField = () => field.generalText().min(1).max(320).description("Player-visible event summary");
2531
+ var observedEventFields = (defaultHighlighted = true) => ({
2532
+ id: eventIdField(),
2533
+ playerId: playerIdField(),
2534
+ occurredAt: field.dateTimeISO(),
2535
+ kind: eventKindField(),
2536
+ title: eventTitleField(),
2537
+ summary: eventSummaryField(),
2538
+ highlighted: defaultHighlighted ? field.boolean().default(false) : field.boolean()
2539
+ });
2540
+ var eventHighlightFields = () => ({
2541
+ id: eventIdField(),
2542
+ title: eventTitleField(),
2543
+ summary: eventSummaryField(),
2544
+ occurredAt: field.dateTimeISO(),
2545
+ kind: eventKindField()
2546
+ });
2547
+ var eventEntryFields = () => ({
2548
+ id: eventIdField(),
2549
+ title: eventTitleField(),
2550
+ summary: eventSummaryField(),
2551
+ occurredAt: field.dateTimeISO(),
2552
+ kind: eventKindField(),
2553
+ highlighted: field.boolean()
2554
+ });
2555
+ var achievementFields = () => ({
2556
+ id: eventIdField(),
2557
+ title: eventTitleField(),
2558
+ tier: field.string().enum(PLAYER_SYSTEM_ACHIEVEMENT_TIERS),
2559
+ progressLabel: eventSummaryField(),
2560
+ earnedAt: field.dateTimeISO().optional()
2561
+ });
2562
+ var achievementTrackFields = () => ({
2563
+ id: eventIdField(),
2564
+ title: eventTitleField(),
2565
+ current: field.number().min(0).max(1e3),
2566
+ target: field.number().min(1).max(1e3),
2567
+ status: field.string().enum(PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES)
2568
+ });
2569
+ var PlayerSystemObservedEventBatchSchema = createSchema(
2570
+ {
2571
+ source: field.string().min(1).max(120),
2572
+ emittedAt: field.dateTimeISO(),
2573
+ events: field.array(field.object(observedEventFields()))
2574
+ },
2575
+ "player-system-observed-event-batch",
2576
+ {
2577
+ version: "1.0.0",
2578
+ piiEnforcement: "strict"
2579
+ }
2580
+ );
2581
+ var PlayerSystemNormalizedEventBatchSchema = createSchema(
2582
+ {
2583
+ sourceBlobName: field.string().min(1).max(512),
2584
+ processedAt: field.dateTimeISO(),
2585
+ events: field.array(
2586
+ field.object({
2587
+ ...observedEventFields(false),
2588
+ deterministicKey: field.string().min(1).max(256)
2589
+ })
2590
+ )
2591
+ },
2592
+ "player-system-normalized-event-batch",
2593
+ {
2594
+ version: "1.0.0",
2595
+ piiEnforcement: "strict"
2596
+ }
2597
+ );
2598
+ var PlayerSystemCuratedSnapshotSchema = createSchema(
2599
+ {
2600
+ playerId: playerIdField(),
2601
+ projectedAt: field.dateTimeISO(),
2602
+ lastObservedAt: field.dateTimeISO(),
2603
+ highlights: field.array(field.object(eventHighlightFields())),
2604
+ events: field.array(field.object(eventEntryFields())),
2605
+ achievements: field.array(field.object(achievementFields())),
2606
+ tracks: field.array(field.object(achievementTrackFields()))
2607
+ },
2608
+ "player-system-curated-snapshot",
2609
+ {
2610
+ version: "1.0.0",
2611
+ piiEnforcement: "strict"
2612
+ }
2613
+ );
2451
2614
  export {
2452
2615
  FieldBuilder,
2453
2616
  IsoLanguageCode,
2617
+ PLAYER_SYSTEM_ACHIEVEMENT_TIERS,
2618
+ PLAYER_SYSTEM_ACHIEVEMENT_TRACK_STATUSES,
2619
+ PLAYER_SYSTEM_EVENT_KINDS,
2620
+ PlayerSystemCuratedSnapshotSchema,
2621
+ PlayerSystemNormalizedEventBatchSchema,
2622
+ PlayerSystemObservedEventBatchSchema,
2454
2623
  createComponentSchema,
2455
2624
  createSchema,
2456
2625
  field,