@travetto/schema 7.0.0-rc.0 → 7.0.0-rc.2

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/data.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { isNumberObject as isNum, isBooleanObject as isBool, isStringObject as isStr } from 'node:util/types';
1
+ import { isNumberObject, isBooleanObject, isStringObject } from 'node:util/types';
2
2
 
3
3
  import { asConstructable, castTo, Class, asFull, TypedObject } from '@travetto/runtime';
4
4
  import { UnknownType } from './types.ts';
@@ -12,24 +12,26 @@ export class DataUtil {
12
12
 
13
13
  /**
14
14
  * Is a value a plain JS object, created using {}
15
- * @param obj Object to check
15
+ * @param value Object to check
16
16
  */
17
- static isPlainObject(obj: unknown): obj is Record<string, unknown> {
18
- return typeof obj === 'object' // separate from primitives
19
- && obj !== undefined
20
- && obj !== null // is obvious
21
- && obj.constructor === Object // separate instances (Array, DOM, ...)
22
- && Object.prototype.toString.call(obj) === '[object Object]'; // separate build-in like Math
17
+ static isPlainObject(value: unknown): value is Record<string, unknown> {
18
+ return typeof value === 'object' // separate from primitives
19
+ && value !== undefined
20
+ && value !== null // is obvious
21
+ && value.constructor === Object // separate instances (Array, DOM, ...)
22
+ && Object.prototype.toString.call(value) === '[object Object]'; // separate build-in like Math
23
23
  }
24
24
 
25
25
  /**
26
26
  * Is a value of primitive type
27
- * @param el Value to check
27
+ * @param value Value to check
28
28
  */
29
- static isPrimitive(el: unknown): el is (string | boolean | number | RegExp) {
30
- switch (typeof el) {
29
+ static isPrimitive(value: unknown): value is (string | boolean | number | RegExp) {
30
+ switch (typeof value) {
31
31
  case 'string': case 'boolean': case 'number': case 'bigint': return true;
32
- case 'object': return !!el && (el instanceof RegExp || el instanceof Date || isStr(el) || isNum(el) || isBool(el));
32
+ case 'object': return !!value && (
33
+ value instanceof RegExp || value instanceof Date || isStringObject(value) || isNumberObject(value) || isBooleanObject(value)
34
+ );
33
35
  default: return false;
34
36
  }
35
37
  }
@@ -37,8 +39,8 @@ export class DataUtil {
37
39
  /**
38
40
  * Is simple, as a primitive, function or class
39
41
  */
40
- static isSimpleValue(a: unknown): a is Function | Class | string | number | RegExp | Date {
41
- return this.isPrimitive(a) || typeof a === 'function';
42
+ static isSimpleValue(value: unknown): value is Function | Class | string | number | RegExp | Date {
43
+ return this.isPrimitive(value) || typeof value === 'function';
42
44
  }
43
45
 
44
46
  static #deepAssignRaw(a: unknown, b: unknown, mode: 'replace' | 'loose' | 'strict' | 'coerce' = 'loose'): unknown {
@@ -68,10 +70,10 @@ export class DataUtil {
68
70
  if (mode === 'replace') {
69
71
  value = b;
70
72
  } else {
71
- const retArr: unknown[] = castTo(value);
72
- const bArr = b;
73
- for (let i = 0; i < bArr.length; i++) {
74
- retArr[i] = this.#deepAssignRaw(retArr[i], bArr[i], mode);
73
+ const valueArray: unknown[] = castTo(value);
74
+ const bArray = b;
75
+ for (let i = 0; i < bArray.length; i++) {
76
+ valueArray[i] = this.#deepAssignRaw(valueArray[i], bArray[i], mode);
75
77
  }
76
78
  }
77
79
  } else if (isSimpB) { // Scalars
@@ -87,14 +89,14 @@ export class DataUtil {
87
89
  }
88
90
  } else { // Object merge
89
91
  value = a;
90
- const bObj: Record<string, unknown> = castTo(b);
91
- const retObj: Record<string, unknown> = castTo(value);
92
+ const bObject: Record<string, unknown> = castTo(b);
93
+ const valueObject: Record<string, unknown> = castTo(value);
92
94
 
93
- for (const key of Object.keys(bObj)) {
95
+ for (const key of Object.keys(bObject)) {
94
96
  if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
95
97
  continue;
96
98
  }
97
- retObj[key] = this.#deepAssignRaw(retObj[key], bObj[key], mode);
99
+ valueObject[key] = this.#deepAssignRaw(valueObject[key], bObject[key], mode);
98
100
  }
99
101
  }
100
102
  }
@@ -119,7 +121,7 @@ export class DataUtil {
119
121
  /**
120
122
  * Coerce an input of any type to the class provided
121
123
  * @param input Input value
122
- * @param type Class to coerce to (String, Boolean, Number, Date, RegEx, Object)
124
+ * @param type Class to coerce to (String, Boolean, Number, Date, RegExp, Object)
123
125
  * @param strict Should a failure to coerce throw an error?
124
126
  */
125
127
  static coerceType(input: unknown, type: typeof String, strict?: boolean): string;
@@ -226,10 +228,10 @@ export class DataUtil {
226
228
 
227
229
  /**
228
230
  * Clone top level properties to a new object
229
- * @param o Object to clone
231
+ * @param value Object to clone
230
232
  */
231
- static shallowClone<T>(a: T): T {
232
- return castTo(Array.isArray(a) ? a.slice(0) : (this.isSimpleValue(a) ? a : { ...castTo<object>(a) }));
233
+ static shallowClone<T>(value: T): T {
234
+ return castTo(Array.isArray(value) ? value.slice(0) : (this.isSimpleValue(value) ? value : { ...castTo<object>(value) }));
233
235
  }
234
236
 
235
237
  /**
@@ -247,29 +249,28 @@ export class DataUtil {
247
249
 
248
250
  /**
249
251
  * Filter object by excluding specific keys
250
- * @param obj A value to filter, primitives will be untouched
252
+ * @param input A value to filter, primitives will be untouched
251
253
  * @param exclude Strings or patterns to exclude against
252
254
  * @returns
253
255
  */
254
- static filterByKeys<T>(obj: T, exclude: (string | RegExp)[]): T {
255
- if (Array.isArray(obj)) {
256
- return castTo(obj.map(x => this.filterByKeys(x, exclude)));
257
- } else if (obj !== null && obj !== undefined && typeof obj === 'object') {
256
+ static filterByKeys<T>(input: T, exclude: (string | RegExp)[]): T {
257
+ if (Array.isArray(input)) {
258
+ return castTo(input.map(value => this.filterByKeys(value, exclude)));
259
+ } else if (input !== null && input !== undefined && typeof input === 'object') {
258
260
  const out: Partial<T> = {};
259
- for (const key of TypedObject.keys(obj)) {
260
- if (!exclude.some(r => typeof key === 'string' && (typeof r === 'string' ? r === key : r.test(key)))) {
261
- const val = obj[key];
262
- if (typeof val === 'object') {
263
- out[key] = this.filterByKeys(val, exclude);
261
+ for (const key of TypedObject.keys(input)) {
262
+ if (!exclude.some(toMatch => typeof key === 'string' && (typeof toMatch === 'string' ? toMatch === key : toMatch.test(key)))) {
263
+ const value = input[key];
264
+ if (typeof value === 'object') {
265
+ out[key] = this.filterByKeys(value, exclude);
264
266
  } else {
265
- out[key] = val;
267
+ out[key] = value;
266
268
  }
267
269
  }
268
270
  }
269
271
  return asFull(out);
270
272
  } else {
271
- return obj;
273
+ return input;
272
274
  }
273
275
  }
274
-
275
276
  }
@@ -10,14 +10,14 @@ import { SchemaRegistryIndex } from '../service/registry-index.ts';
10
10
  * @kind decorator
11
11
  */
12
12
  export function Describe(config: Partial<Omit<SchemaCoreConfig, 'metadata'>>) {
13
- return (instanceOrCls: Class | ClassInstance, property?: string | symbol, descOrIdx?: PropertyDescriptor | number): void => {
13
+ return (instanceOrCls: Class | ClassInstance, property?: string, descriptorOrIdx?: PropertyDescriptor | number): void => {
14
14
  const adapter = SchemaRegistryIndex.getForRegister(getClass(instanceOrCls));
15
15
  if (!property) {
16
16
  adapter.register(config);
17
17
  } else {
18
- if (descOrIdx !== undefined && typeof descOrIdx === 'number') {
19
- adapter.registerParameter(property, descOrIdx, config);
20
- } else if (typeof descOrIdx === 'object' && typeof descOrIdx.value === 'function') {
18
+ if (descriptorOrIdx !== undefined && typeof descriptorOrIdx === 'number') {
19
+ adapter.registerParameter(property, descriptorOrIdx, config);
20
+ } else if (typeof descriptorOrIdx === 'object' && typeof descriptorOrIdx.value === 'function') {
21
21
  adapter.registerMethod(property, config);
22
22
  } else {
23
23
  adapter.registerField(property, config);
@@ -31,7 +31,7 @@ export function Describe(config: Partial<Omit<SchemaCoreConfig, 'metadata'>>) {
31
31
  * @augments `@travetto/schema:Input`
32
32
  * @kind decorator
33
33
  */
34
- export const IsPrivate = (): (instanceOrCls: Class | ClassInstance, property?: string | symbol) => void => Describe({ private: true });
34
+ export const IsPrivate = (): (instanceOrCls: Class | ClassInstance, property?: string) => void => Describe({ private: true });
35
35
 
36
36
  /**
37
37
  * Mark a field/method as ignored
@@ -3,23 +3,25 @@ import { Any, ClassInstance, getClass } from '@travetto/runtime';
3
3
  import { SchemaFieldConfig } from '../service/types.ts';
4
4
  import { SchemaRegistryIndex } from '../service/registry-index.ts';
5
5
 
6
- type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(t: T, k: K, idx?: TypedPropertyDescriptor<Any> | number) => void);
6
+ type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(
7
+ instance: T, property: K, idx?: TypedPropertyDescriptor<Any> | number
8
+ ) => void);
7
9
 
8
- function field<V>(...obj: Partial<SchemaFieldConfig>[]): PropType<V> {
9
- return (instance: ClassInstance, property: string | symbol): void => {
10
- SchemaRegistryIndex.getForRegister(getClass(instance)).registerField(property, ...obj);
10
+ function field<V>(...configs: Partial<SchemaFieldConfig>[]): PropType<V> {
11
+ return (instance: ClassInstance, property: string): void => {
12
+ SchemaRegistryIndex.getForRegister(getClass(instance)).registerField(property, ...configs);
11
13
  };
12
14
  }
13
15
 
14
16
  /**
15
17
  * Registering a field
16
18
  * @param type The type for the field
17
- * @param config The field configuration
19
+ * @param configs The field configuration
18
20
  * @augments `@travetto/schema:Input`
19
21
  * @kind decorator
20
22
  */
21
- export function Field(type: Pick<SchemaFieldConfig, 'type' | 'array'>, ...config: Partial<SchemaFieldConfig>[]): PropType<unknown> {
22
- return field(type, ...config);
23
+ export function Field(type: Pick<SchemaFieldConfig, 'type' | 'array'>, ...configs: Partial<SchemaFieldConfig>[]): PropType<unknown> {
24
+ return field(type, ...configs);
23
25
  }
24
26
 
25
27
  /**
@@ -4,16 +4,18 @@ import { CommonRegExp } from '../validate/regexp.ts';
4
4
  import { CONSTRUCTOR_PROPERTY, SchemaInputConfig } from '../service/types.ts';
5
5
  import { SchemaRegistryIndex } from '../service/registry-index.ts';
6
6
 
7
- type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(t: T, k: K, idx?: TypedPropertyDescriptor<Any> | number) => void);
7
+ type PropType<V> = (<T extends Partial<Record<K, V | Function>>, K extends string>(
8
+ instance: T, property: K, idx?: TypedPropertyDescriptor<Any> | number
9
+ ) => void);
8
10
 
9
- function input<V>(...obj: Partial<SchemaInputConfig>[]): PropType<V> {
10
- return (instanceOrCls: ClassInstance | Class, property: string | symbol, idx?: number | TypedPropertyDescriptor<Any>): void => {
11
+ function input<V>(...configs: Partial<SchemaInputConfig>[]): PropType<V> {
12
+ return (instanceOrCls: ClassInstance | Class, property: string, idx?: number | TypedPropertyDescriptor<Any>): void => {
11
13
  const adapter = SchemaRegistryIndex.getForRegister(getClass(instanceOrCls));
12
14
  const propertyKey = property ?? CONSTRUCTOR_PROPERTY;
13
15
  if (typeof idx === 'number') {
14
- adapter.registerParameter(propertyKey, idx, ...obj);
16
+ adapter.registerParameter(propertyKey, idx, ...configs);
15
17
  } else {
16
- adapter.registerField(propertyKey, ...obj);
18
+ adapter.registerField(propertyKey, ...configs);
17
19
  }
18
20
  };
19
21
  }
@@ -21,12 +23,12 @@ function input<V>(...obj: Partial<SchemaInputConfig>[]): PropType<V> {
21
23
  /**
22
24
  * Registering an input
23
25
  * @param type The type for the input
24
- * @param config The input configuration
26
+ * @param configs The input configuration
25
27
  * @augments `@travetto/schema:Input`
26
28
  * @kind decorator
27
29
  */
28
- export function Input(type: Pick<SchemaInputConfig, 'type' | 'array'>, ...config: Partial<SchemaInputConfig>[]): PropType<unknown> {
29
- return input(type, ...config);
30
+ export function Input(type: Pick<SchemaInputConfig, 'type' | 'array'>, ...configs: Partial<SchemaInputConfig>[]): PropType<unknown> {
31
+ return input(type, ...configs);
30
32
  }
31
33
 
32
34
  /**
@@ -197,7 +199,7 @@ export function Specifier(...specifiers: string[]): PropType<unknown> { return i
197
199
  * @augments `@travetto/schema:Input`
198
200
  * @kind decorator
199
201
  */
200
- export function DiscriminatorField(): ((t: ClassInstance, k: string) => void) {
202
+ export function DiscriminatorField(): ((instance: ClassInstance, property: string) => void) {
201
203
  return (instance: ClassInstance, property: string): void => {
202
204
  SchemaRegistryIndex.getForRegister(getClass(instance)).register({
203
205
  discriminatedBase: true,
@@ -4,6 +4,8 @@ import { SchemaMethodConfig } from '../service/types';
4
4
  import { SchemaRegistryIndex } from '../service/registry-index';
5
5
  import { MethodValidatorFn } from '../validate/types';
6
6
 
7
+ type MethodDecorator = (instance: ClassInstance, property: string, descriptor: PropertyDescriptor) => PropertyDescriptor | void;
8
+
7
9
  /**
8
10
  * Registering a method
9
11
  * @param config The method configuration
@@ -11,7 +13,7 @@ import { MethodValidatorFn } from '../validate/types';
11
13
  * @kind decorator
12
14
  */
13
15
  export function Method(...config: Partial<SchemaMethodConfig>[]) {
14
- return (instanceOrCls: ClassInstance, property: string | symbol): void => {
16
+ return (instanceOrCls: ClassInstance, property: string): void => {
15
17
  SchemaRegistryIndex.getForRegister(getClass(instanceOrCls)).registerMethod(property, ...config);
16
18
  };
17
19
  }
@@ -16,12 +16,12 @@ type ValidStringField<T> = { [K in Extract<keyof T, string>]: T[K] extends strin
16
16
  * @augments `@travetto/schema:Schema`
17
17
  * @kind decorator
18
18
  */
19
- export function Schema(cfg?: Partial<Pick<SchemaClassConfig, 'validators' | 'methods'>>) {
19
+ export function Schema(config?: Partial<Pick<SchemaClassConfig, 'validators' | 'methods'>>) {
20
20
  return <T, U extends Class<T>>(cls: U): void => {
21
21
  cls.from ??= function <V>(this: Class<V>, data: DeepPartial<V>, view?: string): V {
22
22
  return BindUtil.bindSchema(this, data, { view });
23
23
  };
24
- SchemaRegistryIndex.getForRegister(cls).registerClass(cfg);
24
+ SchemaRegistryIndex.getForRegister(cls).registerClass(config);
25
25
  };
26
26
  }
27
27
 
@@ -5,7 +5,7 @@ const InvalidSymbol = Symbol();
5
5
  /**
6
6
  * Point Implementation
7
7
  */
8
- export class PointImpl {
8
+ export class PointImplementation {
9
9
 
10
10
  /**
11
11
  * Validate we have an actual point
@@ -20,7 +20,7 @@ export class PointImpl {
20
20
  */
21
21
  static bindSchema(input: unknown): [number, number] | typeof InvalidSymbol | undefined {
22
22
  if (Array.isArray(input) && input.length === 2) {
23
- const [a, b] = input.map(x => DataUtil.coerceType(x, Number, false));
23
+ const [a, b] = input.map(value => DataUtil.coerceType(value, Number, false));
24
24
  return [a, b];
25
25
  } else {
26
26
  return InvalidSymbol;
@@ -28,4 +28,4 @@ export class PointImpl {
28
28
  }
29
29
  }
30
30
 
31
- Object.defineProperty(PointImpl, 'name', { value: 'Point' });
31
+ Object.defineProperty(PointImplementation, 'name', { value: 'Point' });
package/src/name.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { SchemaClassConfig } from './service/types.ts';
2
2
 
3
- const ID_RE = /(\d{1,100})Δ$/;
3
+ const ID_REGEX = /(\d{1,100})Δ$/;
4
4
 
5
5
  /**
6
6
  * Name resolver, specifically for synthetic types
@@ -17,9 +17,9 @@ export class SchemaNameResolver {
17
17
  getName(schema: SchemaClassConfig): string {
18
18
  const cls = schema.class;
19
19
  const id = cls.Ⲑid;
20
- if (ID_RE.test(cls.name)) {
20
+ if (ID_REGEX.test(cls.name)) {
21
21
  if (!this.#schemaIdToName.has(id)) {
22
- const name = cls.name.replace(ID_RE, (_, uid) => uid.slice(-this.#digits));
22
+ const name = cls.name.replace(ID_REGEX, (_, uniqueId) => uniqueId.slice(-this.#digits));
23
23
  this.#schemaIdToName.set(id, name);
24
24
  }
25
25
  return this.#schemaIdToName.get(id)!;
@@ -40,17 +40,17 @@ class $SchemaChangeListener {
40
40
 
41
41
  /**
42
42
  * On schema change, emit the change event for the whole schema
43
- * @param cb The function to call on schema change
43
+ * @param handler The function to call on schema change
44
44
  */
45
- onSchemaChange(handler: (e: SchemaChangeEvent) => void): void {
45
+ onSchemaChange(handler: (event: SchemaChangeEvent) => void): void {
46
46
  this.#emitter.on('schema', handler);
47
47
  }
48
48
 
49
49
  /**
50
50
  * On schema field change, emit the change event for the whole schema
51
- * @param cb The function to call on schema field change
51
+ * @param handler The function to call on schema field change
52
52
  */
53
- onFieldChange(handler: (e: FieldChangeEvent) => void): void {
53
+ onFieldChange(handler: (event: FieldChangeEvent) => void): void {
54
54
  this.#emitter.on('field', handler);
55
55
  }
56
56
 
@@ -63,13 +63,13 @@ class $SchemaChangeListener {
63
63
 
64
64
  /**
65
65
  * Track a specific class for dependencies
66
- * @param src The target class
66
+ * @param cls The target class
67
67
  * @param parent The parent class
68
68
  * @param path The path within the object hierarchy to arrive at the class
69
69
  * @param config The configuration or the class
70
70
  */
71
- trackSchemaDependency(src: Class, parent: Class, path: SchemaFieldConfig[], config: SchemaClassConfig): void {
72
- const idValue = src.Ⲑid;
71
+ trackSchemaDependency(cls: Class, parent: Class, path: SchemaFieldConfig[], config: SchemaClassConfig): void {
72
+ const idValue = cls.Ⲑid;
73
73
  if (!this.#mapping.has(idValue)) {
74
74
  this.#mapping.set(idValue, new Map());
75
75
  }
@@ -86,13 +86,13 @@ class $SchemaChangeListener {
86
86
  const clsId = cls.Ⲑid;
87
87
 
88
88
  if (this.#mapping.has(clsId)) {
89
- const deps = this.#mapping.get(clsId)!;
90
- for (const depClsId of deps.keys()) {
91
- if (!updates.has(depClsId)) {
92
- updates.set(depClsId, { config: deps.get(depClsId)!.config, subs: [] });
89
+ const dependencies = this.#mapping.get(clsId)!;
90
+ for (const dependencyClsId of dependencies.keys()) {
91
+ if (!updates.has(dependencyClsId)) {
92
+ updates.set(dependencyClsId, { config: dependencies.get(dependencyClsId)!.config, subs: [] });
93
93
  }
94
- const c = deps.get(depClsId)!;
95
- updates.get(depClsId)!.subs.push({ path: [...c.path], fields: changes });
94
+ const childDependency = dependencies.get(dependencyClsId)!;
95
+ updates.get(dependencyClsId)!.subs.push({ path: [...childDependency.path], fields: changes });
96
96
  }
97
97
  }
98
98
 
@@ -103,49 +103,49 @@ class $SchemaChangeListener {
103
103
 
104
104
  /**
105
105
  * Emit field level changes in the schema
106
- * @param prev The previous class config
107
- * @param curr The current class config
106
+ * @param previous The previous class config
107
+ * @param current The current class config
108
108
  */
109
- emitFieldChanges(ev: ChangeEvent<SchemaClassConfig>): void {
110
- const prev = 'prev' in ev ? ev.prev : undefined;
111
- const curr = 'curr' in ev ? ev.curr : undefined;
109
+ emitFieldChanges(event: ChangeEvent<SchemaClassConfig>): void {
110
+ const previous = 'previous' in event ? event.previous : undefined;
111
+ const current = 'current' in event ? event.current : undefined;
112
112
 
113
- const prevFields = new Set(Object.keys(prev?.fields ?? {}));
114
- const currFields = new Set(Object.keys(curr?.fields ?? {}));
113
+ const previousFields = new Set(Object.keys(previous?.fields ?? {}));
114
+ const currentFields = new Set(Object.keys(current?.fields ?? {}));
115
115
 
116
116
  const changes: ChangeEvent<SchemaFieldConfig>[] = [];
117
117
 
118
- for (const c of currFields) {
119
- if (!prevFields.has(c) && curr) {
120
- changes.push({ curr: curr.fields[c], type: 'added' });
118
+ for (const field of currentFields) {
119
+ if (!previousFields.has(field) && current) {
120
+ changes.push({ current: current.fields[field], type: 'added' });
121
121
  }
122
122
  }
123
123
 
124
- for (const c of prevFields) {
125
- if (!currFields.has(c) && prev) {
126
- changes.push({ prev: prev.fields[c], type: 'removing' });
124
+ for (const field of previousFields) {
125
+ if (!currentFields.has(field) && previous) {
126
+ changes.push({ previous: previous.fields[field], type: 'removing' });
127
127
  }
128
128
  }
129
129
 
130
130
  // Handle class references changing, but keeping same id
131
131
  const compareTypes = (a: Class, b: Class): boolean => a.Ⲑid ? a.Ⲑid === b.Ⲑid : a === b;
132
132
 
133
- for (const c of currFields) {
134
- if (prevFields.has(c) && prev && curr) {
135
- const prevSchema = prev.fields[c];
136
- const currSchema = curr.fields[c];
133
+ for (const field of currentFields) {
134
+ if (previousFields.has(field) && previous && current) {
135
+ const prevSchema = previous.fields[field];
136
+ const currSchema = current.fields[field];
137
137
  if (
138
138
  JSON.stringify(prevSchema) !== JSON.stringify(currSchema) ||
139
139
  !compareTypes(prevSchema.type, currSchema.type)
140
140
  ) {
141
- changes.push({ prev: prev.fields[c], curr: curr.fields[c], type: 'changed' });
141
+ changes.push({ previous: previous.fields[field], current: current.fields[field], type: 'changed' });
142
142
  }
143
143
  }
144
144
  }
145
145
 
146
146
  // Send field changes
147
- this.#emitter.emit('field', { cls: curr!.class, changes });
148
- this.emitSchemaChanges({ cls: curr!.class, changes });
147
+ this.#emitter.emit('field', { cls: current!.class, changes });
148
+ this.emitSchemaChanges({ cls: current!.class, changes });
149
149
  }
150
150
  }
151
151