@globaltypesystem/gts-ts 0.1.1 → 0.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/src/types.ts CHANGED
@@ -14,6 +14,7 @@ export interface GtsIDSegment {
14
14
  verMinor?: number;
15
15
  isType: boolean;
16
16
  isWildcard: boolean;
17
+ isUuidTail: boolean;
17
18
  }
18
19
 
19
20
  export interface GtsID {
package/src/x-gts-ref.ts CHANGED
@@ -81,6 +81,56 @@ export class XGtsRefValidator {
81
81
  });
82
82
  }
83
83
  }
84
+
85
+ // Recurse into combinator subschemas
86
+ if (Array.isArray(schema.allOf)) {
87
+ for (const subSchema of schema.allOf) {
88
+ this.visitInstance(instance, subSchema, path, rootSchema, errors);
89
+ }
90
+ }
91
+
92
+ if (Array.isArray(schema.anyOf)) {
93
+ // Only enforce when all branches have x-gts-ref; mixed branches may be valid via non-x-gts-ref path (Ajv handles that)
94
+ const refBranches = schema.anyOf.filter((s: any) => this.containsXGtsRef(s));
95
+ if (refBranches.length > 0 && refBranches.length === schema.anyOf.length) {
96
+ const branchResults = refBranches.map((subSchema: any) => {
97
+ const branchErrors: XGtsRefValidationError[] = [];
98
+ this.visitInstance(instance, subSchema, path, rootSchema, branchErrors);
99
+ return branchErrors;
100
+ });
101
+ const anyPassed = branchResults.some((errs: XGtsRefValidationError[]) => errs.length === 0);
102
+ if (!anyPassed) {
103
+ for (const branchErrors of branchResults) {
104
+ errors.push(...branchErrors);
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ if (Array.isArray(schema.oneOf)) {
111
+ // Only enforce when all branches have x-gts-ref; mixed branches can't be coordinated with Ajv's branch selection
112
+ const refBranches = schema.oneOf.filter((s: any) => this.containsXGtsRef(s));
113
+ if (refBranches.length > 0 && refBranches.length === schema.oneOf.length) {
114
+ const branchResults = refBranches.map((subSchema: any) => {
115
+ const branchErrors: XGtsRefValidationError[] = [];
116
+ this.visitInstance(instance, subSchema, path, rootSchema, branchErrors);
117
+ return branchErrors;
118
+ });
119
+ const passingCount = branchResults.filter((errs: XGtsRefValidationError[]) => errs.length === 0).length;
120
+ if (passingCount === 0) {
121
+ for (const branchErrors of branchResults) {
122
+ errors.push(...branchErrors);
123
+ }
124
+ } else if (passingCount > 1) {
125
+ errors.push({
126
+ fieldPath: path || '/',
127
+ value: instance,
128
+ refPattern: '',
129
+ reason: `Value matches ${passingCount} oneOf branches but must match exactly one`,
130
+ });
131
+ }
132
+ }
133
+ }
84
134
  }
85
135
 
86
136
  private visitSchema(schema: any, path: string, rootSchema: any, errors: XGtsRefValidationError[]): void {
@@ -300,6 +350,19 @@ export class XGtsRefValidator {
300
350
  return null;
301
351
  }
302
352
 
353
+ private containsXGtsRef(schema: any): boolean {
354
+ if (!schema || typeof schema !== 'object') return false;
355
+ if (schema['x-gts-ref'] !== undefined) return true;
356
+ for (const value of Object.values(schema)) {
357
+ if (Array.isArray(value)) {
358
+ if (value.some((item) => this.containsXGtsRef(item))) return true;
359
+ } else if (value && typeof value === 'object') {
360
+ if (this.containsXGtsRef(value)) return true;
361
+ }
362
+ }
363
+ return false;
364
+ }
365
+
303
366
  /**
304
367
  * Strip the "gts://" prefix from a value if present
305
368
  */
package/tests/gts.test.ts CHANGED
@@ -414,6 +414,8 @@ describe('GTS Store Operations', () => {
414
414
  });
415
415
  });
416
416
 
417
+ // x-gts-ref combinator tests (oneOf/anyOf/allOf) are in the canonical gts-spec test suite
418
+
417
419
  describe('OP#12 - Wildcard Validation (v0.7)', () => {
418
420
  test('validates wildcard patterns', () => {
419
421
  const result = validateGtsID('gts.vendor.pkg.*');