@syncbridge/common 0.11.0 → 0.12.1

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.
@@ -3,8 +3,8 @@ type NotPromise<T> = T extends Promise<any> ? never : T;
3
3
  export declare class StackExecutor {
4
4
  stack: string[];
5
5
  issues: StackExecutor.Issue[];
6
- executeAsync(stack: string, fn: () => Promise<any>): Promise<void>;
7
- execute<T>(stack: string, fn: () => NotPromise<T>): void;
6
+ executeAsync(stack: string, fn: () => Promise<any>): Promise<boolean>;
7
+ execute<T>(stack: string, fn: () => NotPromise<T>): boolean;
8
8
  handleError(e: any): void;
9
9
  }
10
10
  export declare namespace StackExecutor {
@@ -14,6 +14,7 @@ export class StackExecutor {
14
14
  finally {
15
15
  this.stack.pop();
16
16
  }
17
+ return !this.issues.find(i => !(i.severity === 'warning' || i.severity === 'info'));
17
18
  }
18
19
  execute(stack, fn) {
19
20
  this.stack.push(stack);
@@ -26,6 +27,7 @@ export class StackExecutor {
26
27
  finally {
27
28
  this.stack.pop();
28
29
  }
30
+ return !this.issues.find(i => !(i.severity === 'warning' || i.severity === 'info'));
29
31
  }
30
32
  handleError(e) {
31
33
  const location = this.stack.join('/');
package/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export const version = '0.11.0';
1
+ export const version = '0.12.1';
2
2
  export const CLASS_METADATA = Symbol.for('CLASS_METADATA');
3
3
  export const CLASS_TYPE = Symbol.for('CLASS_TYPE');
4
4
  export const VARIABLE_CONTAINER = Symbol.for('VARIABLE_CONTAINER');
@@ -9,7 +9,7 @@ import { resolvePackageJson } from '../utils/locate-package-json.js';
9
9
  import { defineOwnMetadata, parseNpmAuthor } from './decorator-helpers.js';
10
10
  import { UseComponent as _UseComponent } from './use-component.decorator.js';
11
11
  import { UseVariables as _UseVariables } from './use-variables.decorator.js';
12
- const NAME_PATTERN = /^(.*?)(Component)?$/;
12
+ const NAME_PATTERN = /^([A-Z][A-Za-z0-9_]*?)(Component)?$/;
13
13
  export function Component(options) {
14
14
  const callerFile = callerCallsite()?.getFileName();
15
15
  const pkgjson = callerFile && resolvePackageJson(path.dirname(callerFile));
@@ -1,7 +1,7 @@
1
1
  import 'reflect-metadata';
2
2
  import type { DeepPartial, StrictOmit, Type } from 'ts-gems';
3
3
  import { VariableMetadata, VariableMetadataRecord } from '../models/index.js';
4
- export declare function DefineVariable(options: DefineVariable.Options): (target: Object, propertyKey: string | symbol) => void;
4
+ export declare function DefineVariable(options?: DefineVariable.Options): (target: Object, propertyKey: string | symbol) => void;
5
5
  type TEnumValue = (string | number)[] | Record<string, string | number>;
6
6
  type TVariable = DeepPartial<VariableMetadataRecord> | Type;
7
7
  export declare namespace DefineVariable {
@@ -2,7 +2,7 @@ import 'reflect-metadata';
2
2
  import { deepClone, merge, omitUndefined } from '@jsopen/objects';
3
3
  import { VARIABLE_CONTAINER } from '../constants.js';
4
4
  import { VariableMetadata, VariableMetadataRecord, VariableType, } from '../models/index.js';
5
- export function DefineVariable(options) {
5
+ export function DefineVariable(options = {}) {
6
6
  return function (target, propertyKey) {
7
7
  /** c8 ignore next */
8
8
  if (typeof propertyKey !== 'string')
@@ -36,6 +36,8 @@ export function DefineVariable(options) {
36
36
  metadata.type = VariableType.Boolean;
37
37
  else if (designType === Number)
38
38
  metadata.type = VariableType.Number;
39
+ else if (designType === BigInt)
40
+ metadata.type = VariableType.BigInt;
39
41
  else if (typeof designType === 'function' &&
40
42
  Reflect.hasMetadata(VARIABLE_CONTAINER, designType.prototype)) {
41
43
  metadata.type = VariableType.Nested;
@@ -3,7 +3,7 @@ import type { DeepPartial, StrictOmit, Type } from 'ts-gems';
3
3
  import type { ProcessorBase } from '../classes/processor-base.js';
4
4
  import { ProcessorMetadata } from '../models/index.js';
5
5
  import { UseComponent as _UseComponent } from './use-component.decorator.js';
6
- export declare function Processor<T extends ProcessorBase>(options: Processor.Options): (target: Type<T>) => void;
6
+ export declare function Processor<T extends ProcessorBase>(options?: Processor.Options): (target: Type<T>) => void;
7
7
  export declare namespace Processor {
8
8
  /**
9
9
  *
@@ -9,7 +9,7 @@ import { defineOwnMetadata } from './decorator-helpers.js';
9
9
  import { OnCreateProfile as _OnCreateProfile, OnUpdateProfile as _OnUpdateProfile, } from './processor-events.decorator.js';
10
10
  import { UseComponent as _UseComponent } from './use-component.decorator.js';
11
11
  import { UseVariables as _UseVariables } from './use-variables.decorator.js';
12
- const NAME_PATTERN = /^(.*?)(Processor)?$/;
12
+ const NAME_PATTERN = /^([A-Z][A-Za-z0-9_]*)(Processor)?$/;
13
13
  export function Processor(options) {
14
14
  const callerFile = callerCallsite()?.getFileName();
15
15
  const pkgjson = callerFile && resolvePackageJson(path.dirname(callerFile));
@@ -20,7 +20,7 @@ export function Processor(options) {
20
20
  if (classType && classType !== 'processor')
21
21
  throw new TypeError(`${target.name} already decorated as "${classType}"`);
22
22
  /** Determine class name */
23
- let className = options.className;
23
+ let className = options?.className;
24
24
  if (!className) {
25
25
  const m = NAME_PATTERN.exec(target.name);
26
26
  if (!m)
@@ -39,7 +39,7 @@ export function Processor(options) {
39
39
  uri,
40
40
  displayName: className,
41
41
  version: pkgjson.version,
42
- abstract: !!options.abstract,
42
+ abstract: !!options?.abstract,
43
43
  ...omit(options, ['uri', 'components', 'variables', 'version']),
44
44
  });
45
45
  target.uri = uri;
package/index.d.ts CHANGED
@@ -20,5 +20,5 @@ export * from './registry/extension-registry.js';
20
20
  export * from './utils/decode-profile.js';
21
21
  export * from './utils/materialize-metadata.js';
22
22
  export * from './utils/normalize-metadata.js';
23
- export * from './utils/type-guartds.js';
23
+ export * from './utils/type-guards.js';
24
24
  export * from './utils/uri-to-id.js';
package/index.js CHANGED
@@ -20,5 +20,5 @@ export * from './registry/extension-registry.js';
20
20
  export * from './utils/decode-profile.js';
21
21
  export * from './utils/materialize-metadata.js';
22
22
  export * from './utils/normalize-metadata.js';
23
- export * from './utils/type-guartds.js';
23
+ export * from './utils/type-guards.js';
24
24
  export * from './utils/uri-to-id.js';
@@ -55,7 +55,6 @@ __decorate([
55
55
  ApiField({
56
56
  label: 'Required',
57
57
  description: 'Determine if the component is required or not',
58
- default: true,
59
58
  }),
60
59
  __metadata("design:type", Boolean)
61
60
  ], ElementComponentMetadata.prototype, "required", void 0);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncbridge/common",
3
- "version": "0.11.0",
3
+ "version": "0.12.1",
4
4
  "description": "SyncBridge Common utilities",
5
5
  "author": "Panates Inc",
6
6
  "license": "MIT",
@@ -11,10 +11,16 @@ export declare namespace ProcessorFactory {
11
11
  }
12
12
  function createProcessor<T extends ProcessorBase>(profile: Profile, options?: ProcessorOptions): Promise<T>;
13
13
  function createProcessorSilent<T extends ProcessorBase>(profile: Profile, options?: ProcessorOptions): Promise<{
14
+ result: true;
14
15
  processor: T;
15
16
  issues: StackExecutor.Issue[];
17
+ } | {
18
+ result: false;
19
+ issues: StackExecutor.Issue[];
16
20
  }>;
17
- function updateProcessor(processor: ProcessorBase, profile: Profile, options?: ProcessorOptions): Promise<{
21
+ function updateProcessor(processor: ProcessorBase, profile: Profile, options?: ProcessorOptions): Promise<void>;
22
+ function updateProcessorSilent(processor: ProcessorBase, profile: Profile, options?: ProcessorOptions): Promise<{
23
+ result: boolean;
18
24
  issues: StackExecutor.Issue[];
19
25
  }>;
20
26
  }
@@ -1,59 +1,91 @@
1
+ import { clone } from '@jsopen/objects';
1
2
  import equal from 'fast-deep-equal';
2
3
  import { ComponentBase } from './classes/component-base.js';
3
4
  import { ProcessorBase } from './classes/processor-base.js';
4
5
  import { SbError, SbValidationError } from './classes/sb-error.js';
5
6
  import { StackExecutor } from './classes/stack-executor.js';
6
- import { ElementComponentMetadataRecord, Profile, ProfileComponentRecord, VariableMetadataRecord, } from './models/index.js';
7
+ import { ElementComponentMetadataRecord, ProcessorMetadata, Profile, ProfileComponentRecord, VariableMetadataRecord, } from './models/index.js';
7
8
  import { initializeModelsDocument } from './models-document.js';
8
9
  import { ExtensionRegistry } from './registry/extension-registry.js';
9
- import { materializeMetadata } from './utils/materialize-metadata.js';
10
+ import { decodeProfile } from './utils/decode-profile.js';
11
+ import { materializeMetadataSilent } from './utils/materialize-metadata.js';
10
12
  export var ProcessorFactory;
11
13
  (function (ProcessorFactory) {
12
14
  ProcessorFactory.METADATA_KEY = Symbol('METADATA');
13
15
  ProcessorFactory.PROFILE_KEY = Symbol('PROFILE');
14
16
  async function createProcessor(profile, options) {
15
- const { processor: out, issues } = await createProcessorSilent(profile, options);
16
- if (issues?.length) {
17
+ const r1 = await createProcessorSilent(profile, options);
18
+ if (!r1.result) {
17
19
  const msg = 'Error while creating processor.\n ' +
18
- issues
20
+ r1.issues
19
21
  .map(issue => `- ${issue.message}. Location: /${issue.location}`)
20
22
  .join('\n ');
21
- issues.forEach(issue => {
23
+ r1.issues.forEach(issue => {
22
24
  if (issue instanceof SbValidationError)
23
25
  delete issue.stack;
24
26
  });
25
27
  throw new SbValidationError(msg, {
26
- issues,
28
+ issues: r1.issues,
27
29
  });
28
30
  }
29
- return out;
31
+ return r1.processor;
30
32
  }
31
33
  ProcessorFactory.createProcessor = createProcessor;
32
34
  async function createProcessorSilent(profile, options) {
33
- await initializeModelsDocument();
34
- const reg = ExtensionRegistry.getProcessor(profile.processorUri, profile.processorVersion);
35
- const processorClass = await reg.getClass();
36
- const processor = new processorClass({
37
- name: profile.displayName,
38
- logger: options?.logger,
39
- values: profile.values || {},
40
- dataDirectory: options?.dataDirectory,
41
- });
42
35
  const ctx = {
43
36
  stackExecutor: new StackExecutor(),
44
- processor,
37
+ processor: undefined,
45
38
  profile,
46
39
  options,
47
- valueUpdates: new Map(),
48
- };
49
- await _configureProcessor(ctx);
50
- return {
51
- processor: processor,
52
- issues: ctx.stackExecutor.issues,
53
40
  };
41
+ try {
42
+ await initializeModelsDocument();
43
+ if (!(await _configureProcessor(ctx))) {
44
+ return {
45
+ result: false,
46
+ issues: ctx.stackExecutor.issues,
47
+ };
48
+ }
49
+ return {
50
+ result: true,
51
+ processor: ctx.processor,
52
+ issues: ctx.stackExecutor.issues,
53
+ };
54
+ }
55
+ catch (error) {
56
+ return {
57
+ result: false,
58
+ issues: [
59
+ ...ctx.stackExecutor.issues,
60
+ {
61
+ message: error.message,
62
+ type: 'error',
63
+ severity: 'error',
64
+ stack: error.stack,
65
+ },
66
+ ],
67
+ };
68
+ }
54
69
  }
55
70
  ProcessorFactory.createProcessorSilent = createProcessorSilent;
56
71
  async function updateProcessor(processor, profile, options) {
72
+ const r1 = await updateProcessorSilent(processor, profile, options);
73
+ if (!r1.result) {
74
+ const msg = 'Error while updating processor.\n ' +
75
+ r1.issues
76
+ .map(issue => `- ${issue.message}. Location: /${issue.location}`)
77
+ .join('\n ');
78
+ r1.issues.forEach(issue => {
79
+ if (issue instanceof SbValidationError)
80
+ delete issue.stack;
81
+ });
82
+ throw new SbValidationError(msg, {
83
+ issues: r1.issues,
84
+ });
85
+ }
86
+ }
87
+ ProcessorFactory.updateProcessor = updateProcessor;
88
+ async function updateProcessorSilent(processor, profile, options) {
57
89
  if (options?.logger)
58
90
  processor.logger = options.logger;
59
91
  if (options?.dataDirectory)
@@ -65,47 +97,82 @@ export var ProcessorFactory;
65
97
  options,
66
98
  valueUpdates: new Map(),
67
99
  };
68
- await _configureProcessor(ctx);
100
+ if (!(await _configureProcessor(ctx))) {
101
+ return {
102
+ result: false,
103
+ issues: ctx.stackExecutor.issues,
104
+ };
105
+ }
69
106
  const signalUpdates = async (obj) => {
70
107
  if (obj.components) {
71
108
  for (const component of Object.values(obj.components)) {
72
109
  await signalUpdates(component);
73
110
  }
74
111
  }
75
- const properties = ctx.valueUpdates.get(obj);
112
+ const properties = ctx.valueUpdates?.get(obj);
76
113
  if (properties?.length) {
77
114
  await obj.emitAsyncSafe('values-updated', properties);
78
115
  }
79
116
  };
80
117
  await signalUpdates(processor);
81
118
  return {
119
+ result: true,
82
120
  issues: ctx.stackExecutor.issues,
83
121
  };
84
122
  }
85
- ProcessorFactory.updateProcessor = updateProcessor;
123
+ ProcessorFactory.updateProcessorSilent = updateProcessorSilent;
86
124
  async function _configureProcessor(ctx) {
87
- const { processor, profile } = ctx;
88
- const newMetadata = materializeMetadata(profile);
125
+ const r1 = materializeMetadataSilent(ctx.profile);
126
+ if (!r1.result) {
127
+ ctx.stackExecutor.issues.push(...r1.issues);
128
+ return false;
129
+ }
130
+ /* Decode profile */
131
+ const profile = decodeProfile(r1.metadata, ctx.profile);
132
+ ctx.profile = profile;
133
+ const oldMetadata = ctx.processor?.[ProcessorFactory.METADATA_KEY];
134
+ const oldProfile = ctx.processor?.[ProcessorFactory.PROFILE_KEY];
135
+ if (!ctx.processor) {
136
+ /* Create new processor instance */
137
+ const reg = ExtensionRegistry.getProcessor(profile.processorUri, profile.processorVersion);
138
+ const processorClass = await reg.getClass();
139
+ /* Create processor instance */
140
+ ctx.processor = new processorClass({
141
+ name: profile.displayName,
142
+ logger: ctx.options?.logger,
143
+ values: profile.values ? clone(profile.values) : {},
144
+ dataDirectory: ctx.options?.dataDirectory,
145
+ });
146
+ }
147
+ else {
148
+ /* Update values */
149
+ if (!ctx.stackExecutor.execute('values', () => {
150
+ _patchValues(ctx, ctx.processor, ctx.processor.values, '', profile.values, r1.metadata.variables || {}, oldProfile?.values, oldMetadata.variables);
151
+ })) {
152
+ return false;
153
+ }
154
+ }
89
155
  const cmpCtx = {
90
156
  ...ctx,
91
- owner: processor,
157
+ owner: ctx.processor,
92
158
  curPath: '',
93
- newMetadataComponents: newMetadata.components,
159
+ newMetadataComponents: r1.metadata.components,
94
160
  newProfileComponents: profile.components,
95
- oldMetadataComponents: processor[ProcessorFactory.METADATA_KEY]?.components,
96
- oldProfileComponents: processor[ProcessorFactory.PROFILE_KEY]?.components,
161
+ oldMetadataComponents: oldMetadata?.components,
162
+ oldProfileComponents: oldProfile?.components,
97
163
  };
98
- _validateComponents(cmpCtx);
99
- await _configureComponents(cmpCtx);
100
- processor[ProcessorFactory.METADATA_KEY] = newMetadata;
101
- processor[ProcessorFactory.PROFILE_KEY] = profile;
164
+ if (!(_validateComponents(cmpCtx) && (await _configureComponents(cmpCtx)))) {
165
+ return false;
166
+ }
167
+ ctx.processor[ProcessorFactory.METADATA_KEY] = r1.metadata;
168
+ ctx.processor[ProcessorFactory.PROFILE_KEY] = profile;
169
+ return true;
102
170
  }
103
171
  function _validateComponents(ctx) {
104
- const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, processor, } = ctx;
172
+ const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, } = ctx;
105
173
  if (!newMetadataComponents)
106
- return;
107
- // Stack: components
108
- stackExecutor.execute('components', () => {
174
+ return true;
175
+ return stackExecutor.execute('components', () => {
109
176
  for (const [key, newChildMetadata] of Object.entries(newMetadataComponents)) {
110
177
  // Stack: components/componentName
111
178
  stackExecutor.execute(key, () => {
@@ -114,10 +181,9 @@ export var ProcessorFactory;
114
181
  const newChildProfile = newProfileComponents[key];
115
182
  const componentPath = curPath ? curPath + '/' + key : key;
116
183
  const componentInstance = owner.components?.[key];
117
- if (processor.stopped &&
118
- oldChildProfile?.uri &&
184
+ if (oldChildProfile?.uri &&
119
185
  oldChildProfile?.uri !== newChildProfile.uri)
120
- throw new SbError('Cannot change component class while processor running. You should stop it first.');
186
+ throw new SbError(`You should not change uri of the component (${componentPath})`);
121
187
  /** Validate sub-components */
122
188
  if (newChildMetadata.components && componentInstance) {
123
189
  _validateComponents({
@@ -137,10 +203,10 @@ export var ProcessorFactory;
137
203
  async function _configureComponents(ctx) {
138
204
  const { newMetadataComponents, newProfileComponents, oldMetadataComponents, oldProfileComponents, curPath, owner, stackExecutor, processor, } = ctx;
139
205
  if (!newMetadataComponents)
140
- return;
206
+ return true;
141
207
  owner.components = owner.components || {};
142
208
  // Stack: components
143
- await stackExecutor.executeAsync('components', async () => {
209
+ return await stackExecutor.executeAsync('components', async () => {
144
210
  for (const [key, newChildMetadata] of Object.entries(newMetadataComponents)) {
145
211
  // Stack: components/componentName
146
212
  await stackExecutor.executeAsync(key, async () => {
@@ -153,17 +219,18 @@ export var ProcessorFactory;
153
219
  const newChildProfile = newProfileComponents[key];
154
220
  const componentPath = curPath ? curPath + '/' + key : key;
155
221
  let componentInstance = owner.components[key];
156
- /** Create the component only if the owner stopped */ // todo implement hotplug components
157
- if (owner.stopped) {
222
+ /** Create the component */
223
+ if (!componentInstance) {
158
224
  const compReg = ExtensionRegistry.getComponent(newChildMetadata.classUri);
159
225
  /** Create the component instance */
160
226
  const compClass = await compReg.getClass();
227
+ const values = { ...newChildProfile.values };
161
228
  componentInstance = new compClass({
162
229
  processor: processor,
163
230
  parent: owner,
164
231
  name: key,
165
232
  path: componentPath,
166
- values: newChildProfile.values || {},
233
+ values,
167
234
  });
168
235
  owner.components[key] = componentInstance;
169
236
  if (newChildMetadata.propertyKey)
@@ -171,30 +238,7 @@ export var ProcessorFactory;
171
238
  }
172
239
  else {
173
240
  componentInstance.values = {};
174
- const patchValues = (target, valPath, newValues, newVariables, oldValues, oldVariables) => {
175
- if (oldValues)
176
- Object.assign(target, oldValues);
177
- const updatedValues = ctx.valueUpdates.get(componentInstance) || [];
178
- ctx.valueUpdates.set(componentInstance, updatedValues);
179
- if (newVariables) {
180
- for (const [varKey, varMeta] of Object.entries(newVariables)) {
181
- const keyPath = valPath ? valPath + '.' + varKey : varKey;
182
- /** Update only hotplug variables */
183
- if (varMeta?.hotPlug !== true)
184
- continue;
185
- if (varMeta.type === 'nested') {
186
- target[varKey] = {};
187
- patchValues(target[varKey], keyPath, newValues[varKey], newVariables[varKey]?.variables || {}, oldValues?.[varKey], oldVariables?.[varKey]?.variables);
188
- continue;
189
- }
190
- if (!equal(target[varKey], newValues[varKey])) {
191
- updatedValues.push(keyPath);
192
- target[varKey] = newValues[varKey];
193
- }
194
- }
195
- }
196
- };
197
- patchValues(componentInstance.values, '', newChildProfile.values || {}, newChildMetadata.variables || {}, oldChildProfile?.values, oldChildMetadata?.variables);
241
+ _patchValues(ctx, componentInstance, componentInstance.values, '', newChildProfile.values || {}, newChildMetadata.variables || {}, oldChildProfile?.values, oldChildMetadata?.variables);
198
242
  }
199
243
  /** Create the child logger */
200
244
  componentInstance.logger = owner.logger?.child({
@@ -204,7 +248,7 @@ export var ProcessorFactory;
204
248
  componentInstance.logger.level =
205
249
  newChildProfile.settings?.logs?.level;
206
250
  }
207
- /** Initialize sub components */
251
+ /** Initialize sub-components */
208
252
  if (newChildMetadata.components) {
209
253
  await _configureComponents({
210
254
  ...ctx,
@@ -221,4 +265,27 @@ export var ProcessorFactory;
221
265
  }
222
266
  });
223
267
  }
268
+ function _patchValues(ctx, instance, target, valPath, newValues, newVariables, oldValues, oldVariables) {
269
+ if (oldValues)
270
+ Object.assign(target, oldValues);
271
+ const updatedValues = ctx.valueUpdates?.get(instance) || [];
272
+ ctx.valueUpdates?.set(instance, updatedValues);
273
+ if (newVariables) {
274
+ for (const [varKey, varMeta] of Object.entries(newVariables)) {
275
+ const keyPath = valPath ? valPath + '.' + varKey : varKey;
276
+ /** Update only hotplug variables */
277
+ if (varMeta?.hotPlug !== true)
278
+ continue;
279
+ if (varMeta.type === 'nested') {
280
+ target[varKey] = {};
281
+ _patchValues(ctx, instance, target[varKey], keyPath, newValues[varKey], newVariables[varKey]?.variables || {}, oldValues?.[varKey], oldVariables?.[varKey]?.variables);
282
+ continue;
283
+ }
284
+ if (!equal(target[varKey], newValues[varKey])) {
285
+ updatedValues.push(keyPath);
286
+ target[varKey] = newValues[varKey];
287
+ }
288
+ }
289
+ }
290
+ }
224
291
  })(ProcessorFactory || (ProcessorFactory = {}));
@@ -4,7 +4,7 @@ import { ComponentBase } from '../classes/component-base.js';
4
4
  import { ProcessorBase } from '../classes/processor-base.js';
5
5
  import { SbError } from '../classes/sb-error.js';
6
6
  import { ComponentMetadata, ElementMetadata, ProcessorMetadata, } from '../models/index.js';
7
- import { isComponentBase, isProcessorBase } from '../utils/type-guartds.js';
7
+ import { isComponentBase, isProcessorBase } from '../utils/type-guards.js';
8
8
  /**
9
9
  *
10
10
  */
@@ -8,6 +8,10 @@ export declare function materializeMetadata(profile: Profile, returnUndefinedCom
8
8
  *
9
9
  */
10
10
  export declare function materializeMetadataSilent(profile: Profile, returnUndefinedComponentsAsAbstract?: boolean): {
11
+ result: true;
11
12
  metadata: ProcessorMetadata;
12
- issues?: StackExecutor.Issue[];
13
+ issues: StackExecutor.Issue[];
14
+ } | {
15
+ result: false;
16
+ issues: StackExecutor.Issue[];
13
17
  };
@@ -7,22 +7,22 @@ import { ExtensionRegistry } from '../registry/extension-registry.js';
7
7
  * Materializes metadata from profile.
8
8
  */
9
9
  export function materializeMetadata(profile, returnUndefinedComponentsAsAbstract) {
10
- const { metadata, issues } = materializeMetadataSilent(profile, returnUndefinedComponentsAsAbstract);
11
- if (issues?.length) {
10
+ const r = materializeMetadataSilent(profile, returnUndefinedComponentsAsAbstract);
11
+ if (!r.result) {
12
12
  const msg = 'Worker profile validation error.\n ' +
13
- issues
13
+ r.issues
14
14
  .map(issue => `- ${issue.message}. Location: /${issue.location}`)
15
15
  .join('\n ');
16
- issues.forEach(issue => {
16
+ r.issues.forEach(issue => {
17
17
  if (issue instanceof SbValidationError)
18
18
  delete issue.stack;
19
19
  });
20
20
  throw new SbValidationError(msg, {
21
21
  workerId: profile.id,
22
- issues,
22
+ issues: r.issues,
23
23
  });
24
24
  }
25
- return metadata;
25
+ return r.metadata;
26
26
  }
27
27
  /**
28
28
  *
@@ -48,8 +48,8 @@ export function materializeMetadataSilent(profile, returnUndefinedComponentsAsAb
48
48
  });
49
49
  }
50
50
  if (stackExecutor.issues?.length)
51
- return { metadata, issues: stackExecutor.issues };
52
- return { metadata };
51
+ return { result: false, issues: stackExecutor.issues };
52
+ return { result: true, metadata, issues: stackExecutor.issues };
53
53
  }
54
54
  /**
55
55
  *
@@ -39,7 +39,8 @@ export async function normalizeProcessorMetadataSilent(metadata) {
39
39
  cloned.variables = normalizeVariables(cloned.variables);
40
40
  cloned.components = normalizeComponents(cloned.components);
41
41
  const { value, errors } = decoder.silent(cloned);
42
- merge(value, metadata, { keepExisting: true, deep: 'full' });
42
+ if (value)
43
+ merge(value, metadata, { keepExisting: true, deep: 'full' });
43
44
  return {
44
45
  metadata: value || cloned,
45
46
  issues: errors?.map(x => ({
@@ -84,7 +85,8 @@ export async function normalizeComponentMetadataSilent(metadata) {
84
85
  cloned.variables = normalizeVariables(cloned.variables);
85
86
  cloned.components = normalizeComponents(cloned.components);
86
87
  const { value, errors } = decoder.silent(cloned);
87
- merge(value, metadata, { keepExisting: true, deep: 'full' });
88
+ if (value)
89
+ merge(value, metadata, { keepExisting: true, deep: 'full' });
88
90
  return {
89
91
  metadata: value || cloned,
90
92
  issues: errors?.map(x => ({
File without changes
File without changes