@syncbridge/common 0.6.9 → 0.6.12

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/constants.js CHANGED
@@ -1,4 +1,4 @@
1
- export const version = '0.6.9';
1
+ export const version = '0.6.12';
2
2
  export const OWN_ELEMENT_METADATA = Symbol.for('OWN_ELEMENT_METADATA');
3
3
  export const COMPONENT_OPTIONS = Symbol.for('COMPONENT_OPTIONS');
4
4
  export const PROCESSOR_OPTIONS = Symbol.for('PROCESSOR_OPTIONS');
package/index.d.ts CHANGED
@@ -18,3 +18,5 @@ export * from './registry/extension-package.js';
18
18
  export * from './registry/extension-registry.js';
19
19
  export * from './utils/decode-profile.js';
20
20
  export * from './utils/materialize-metadata.js';
21
+ export * from './utils/normalize-metadata.js';
22
+ export * from './utils/type-guartds.js';
package/index.js CHANGED
@@ -18,3 +18,5 @@ export * from './registry/extension-package.js';
18
18
  export * from './registry/extension-registry.js';
19
19
  export * from './utils/decode-profile.js';
20
20
  export * from './utils/materialize-metadata.js';
21
+ export * from './utils/normalize-metadata.js';
22
+ export * from './utils/type-guartds.js';
@@ -1,5 +1,5 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import { ApiField, ComplexType } from '@opra/common';
2
+ import { ApiField, ArrayType, ComplexType } from '@opra/common';
3
3
  import { ElementMetadata } from './element-metadata.js';
4
4
  /**
5
5
  *
@@ -13,8 +13,7 @@ __decorate([
13
13
  ApiField({
14
14
  label: 'Interfaces',
15
15
  description: 'Interfaces which this component implemented',
16
- type: 'string',
17
- isArray: true,
16
+ type: ArrayType('string'),
18
17
  }),
19
18
  __metadata("design:type", Array)
20
19
  ], ComponentMetadata.prototype, "interfaces", void 0);
@@ -1,5 +1,5 @@
1
1
  import { __decorate, __metadata } from "tslib";
2
- import { ApiField, ComplexType } from '@opra/common';
2
+ import { ApiField, ArrayType, ComplexType } from '@opra/common';
3
3
  import { AuthorMetadata } from './author-metadata.js';
4
4
  import { VariableMetadataRecord } from './variable-metadata.js';
5
5
  /**
@@ -69,8 +69,7 @@ __decorate([
69
69
  ApiField({
70
70
  label: 'Tags',
71
71
  description: 'Tags of the component. Tags are used to group components',
72
- type: 'string',
73
- isArray: true,
72
+ type: ArrayType('string'),
74
73
  }),
75
74
  __metadata("design:type", Array)
76
75
  ], ElementMetadata.prototype, "tags", void 0);
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@syncbridge/common",
3
- "version": "0.6.9",
3
+ "version": "0.6.12",
4
4
  "description": "SyncBridge Common utilities",
5
5
  "author": "Panates Inc",
6
6
  "license": "MIT",
7
7
  "dependencies": {
8
8
  "@jsopen/objects": "^2.2.0",
9
9
  "fast-deep-equal": "^3.1.3",
10
- "node-events-async": "^1.5.0",
10
+ "node-events-async": "^1.5.2",
11
11
  "reflect-metadata": "^0.2.2",
12
12
  "semver": "^7.7.4",
13
- "ts-gems": "^3.11.3",
13
+ "ts-gems": "^3.11.5",
14
14
  "valgen": "^5.19.5"
15
15
  },
16
16
  "peerDependencies": {
@@ -3,7 +3,6 @@ import { Type } from 'ts-gems';
3
3
  import { ComponentBase } from '../classes/component-base.js';
4
4
  import { ProcessorBase } from '../classes/processor-base.js';
5
5
  import { ComponentMetadata, ProcessorMetadata } from '../models/index.js';
6
- import type { ExtensionRegistry } from './extension-registry.js';
7
6
  /**
8
7
  *
9
8
  */
@@ -11,18 +10,11 @@ export declare class ExtensionPackage {
11
10
  name: string;
12
11
  version: string;
13
12
  description: string;
13
+ path: string;
14
14
  entryPoint: string;
15
15
  components: ComponentExtension[];
16
16
  processors: ProcessorExtension[];
17
17
  errors: Error[];
18
- sortVersions(): void;
19
- /**
20
- *
21
- * @param directory
22
- * @static
23
- */
24
- static fromDirectory(directory: string): Promise<ExtensionPackage>;
25
- static fromNodePackage(specifier: string, resolver: ExtensionRegistry.Resolver | undefined): Promise<ExtensionPackage>;
26
18
  }
27
19
  /**
28
20
  *
@@ -1,13 +1,6 @@
1
1
  import 'reflect-metadata';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
4
- import process from 'node:process';
5
- import { fileURLToPath, pathToFileURL } from 'node:url';
6
- import { updateErrorMessage } from '@jsopen/objects';
7
2
  import { SbError } from '../classes/sb-error.js';
8
- import { COMPONENT_OPTIONS, PROCESSOR_OPTIONS } from '../constants.js';
9
3
  import { isComponentBase, isProcessorBase } from '../utils/type-guartds.js';
10
- import { normalizeComponentMetadata, normalizeProcessorMetadata, } from './normalize-metadata.js';
11
4
  /**
12
5
  *
13
6
  */
@@ -15,140 +8,6 @@ export class ExtensionPackage {
15
8
  components = [];
16
9
  processors = [];
17
10
  errors = [];
18
- sortVersions() {
19
- this.components.sort((a, b) => a.version.localeCompare(b.version));
20
- this.processors.sort((a, b) => a.version.localeCompare(b.version));
21
- }
22
- /**
23
- *
24
- * @param directory
25
- * @static
26
- */
27
- static async fromDirectory(directory) {
28
- let filename = path.join(directory, 'package.json');
29
- if (!fs.existsSync(filename))
30
- throw new SbError(`Directory "${directory}" does not contain package.json`);
31
- const pkgJson = JSON.parse(fs.readFileSync(filename, 'utf8'));
32
- if (!pkgJson.syncbridge)
33
- throw new SbError(`"${pkgJson.name}" is not a SyncBridge extension package`);
34
- const out = new ExtensionPackage();
35
- out.name = pkgJson.name;
36
- out.version = pkgJson.version;
37
- out.description = pkgJson.description;
38
- out.entryPoint = path.join(directory, pkgJson.module || pkgJson.main);
39
- let metadata;
40
- if (pkgJson.syncbridge.components) {
41
- for (const ctorName of pkgJson.syncbridge.components) {
42
- filename = path.join(directory, 'metadata', ctorName + '.json');
43
- if (!fs.existsSync(filename)) {
44
- out.errors.push(new Error(`Component (${ctorName}) metadata file not found`));
45
- continue;
46
- }
47
- try {
48
- metadata = JSON.parse(fs.readFileSync(filename, 'utf8'));
49
- }
50
- catch {
51
- out.errors.push(new Error(`Component (${ctorName}) metadata file read error`));
52
- continue;
53
- }
54
- try {
55
- metadata = await normalizeComponentMetadata(metadata);
56
- }
57
- catch (e) {
58
- updateErrorMessage(e, `Component (${ctorName}) metadata validation error. ` + e.message);
59
- out.errors.push(e);
60
- continue;
61
- }
62
- if (metadata.abstract)
63
- continue;
64
- out.components = out.components || [];
65
- out.components.push(new ComponentExtension(out, ctorName, metadata));
66
- }
67
- }
68
- if (pkgJson.syncbridge.processors) {
69
- for (const ctorName of pkgJson.syncbridge.processors) {
70
- filename = path.join(directory, 'metadata', ctorName + '.json');
71
- if (!fs.existsSync(filename)) {
72
- out.errors.push(new Error(`Processors (${ctorName}) metadata file not found`));
73
- continue;
74
- }
75
- try {
76
- metadata = JSON.parse(fs.readFileSync(filename, 'utf8'));
77
- }
78
- catch {
79
- out.errors.push(new Error(`Processors (${ctorName}) metadata file read error`));
80
- continue;
81
- }
82
- try {
83
- metadata = await normalizeProcessorMetadata(metadata);
84
- }
85
- catch (e) {
86
- updateErrorMessage(e, `Processor (${ctorName}) metadata validation error. ` + e.message);
87
- out.errors.push(e);
88
- continue;
89
- }
90
- if (metadata.abstract)
91
- continue;
92
- out.processors = out.processors || [];
93
- out.processors.push(new ProcessorExtension(out, ctorName, metadata));
94
- }
95
- }
96
- out.sortVersions();
97
- return out;
98
- }
99
- static async fromNodePackage(specifier, resolver) {
100
- // const resolver = createRequire(parentPath || import.meta.url).resolve;
101
- let entryPoint = (resolver || import.meta.resolve)(specifier);
102
- const pkgJson = locatePkgJson(path.dirname(entryPoint));
103
- if (!pkgJson) {
104
- throw new SbError(`Can't locate package.json file for "${specifier}"`);
105
- }
106
- if (path.isAbsolute(entryPoint) && process.platform === 'win32') {
107
- entryPoint = pathToFileURL(entryPoint).href;
108
- }
109
- const out = new ExtensionPackage();
110
- out.name = pkgJson.name;
111
- out.version = pkgJson.version;
112
- out.description = pkgJson.description;
113
- out.entryPoint = entryPoint;
114
- const module = await import(entryPoint);
115
- for (const [ctorName, v] of Object.entries(module)) {
116
- if (typeof v !== 'function')
117
- continue;
118
- let metadata = Reflect.getMetadata(COMPONENT_OPTIONS, v);
119
- if (metadata) {
120
- try {
121
- metadata = await normalizeComponentMetadata(metadata);
122
- }
123
- catch (e) {
124
- updateErrorMessage(e, `Component (${ctorName}) metadata validation error. ` + e.message);
125
- out.errors.push(e);
126
- continue;
127
- }
128
- if (metadata.abstract)
129
- continue;
130
- out.components = out.components || [];
131
- out.components.push(new ComponentExtension(out, ctorName, metadata));
132
- }
133
- metadata = Reflect.getMetadata(PROCESSOR_OPTIONS, v);
134
- if (metadata) {
135
- try {
136
- metadata = await normalizeProcessorMetadata(metadata);
137
- }
138
- catch (e) {
139
- updateErrorMessage(e, `Processor (${ctorName}) metadata validation error. ` + e.message);
140
- out.errors.push(e);
141
- continue;
142
- }
143
- if (metadata.abstract)
144
- continue;
145
- out.processors = out.processors || [];
146
- out.processors.push(new ProcessorExtension(out, ctorName, metadata));
147
- }
148
- }
149
- out.sortVersions();
150
- return out;
151
- }
152
11
  }
153
12
  /**
154
13
  *
@@ -226,19 +85,3 @@ export class ProcessorExtension {
226
85
  return this._ctor;
227
86
  }
228
87
  }
229
- /**
230
- *
231
- */
232
- function locatePkgJson(directory) {
233
- if (directory.startsWith('file:'))
234
- directory = fileURLToPath(directory);
235
- for (let i = 0; i < 3; i++) {
236
- const f = path.resolve(directory, 'package.json');
237
- if (fs.existsSync(f)) {
238
- const json = JSON.parse(fs.readFileSync(f, 'utf8'));
239
- if (json.name && json.version)
240
- return json;
241
- }
242
- directory = path.dirname(directory);
243
- }
244
- }
@@ -1,39 +1,72 @@
1
- import { URL } from 'node:url';
1
+ import { ResponsiveMap } from '@opra/common';
2
2
  import { Type } from 'ts-gems';
3
3
  import { ComponentExtension, ExtensionPackage, ProcessorExtension } from './extension-package.js';
4
- export declare namespace ExtensionRegistry {
5
- type Resolver = (specifier: string, parent?: string | URL) => string;
6
- const packages: Map<string, ExtensionPackage[]>;
7
- const components: Map<string, ComponentExtension[]>;
8
- const processors: Map<string, ProcessorExtension[]>;
4
+ declare const instanceSymbol: unique symbol;
5
+ /**
6
+ * The `ExtensionRegistry` class is responsible for managing component and processor extensions,
7
+ * as well as handling the registration of extension packages. It provides methods to locate and
8
+ * retrieve extensions by their class name and version, and offers the ability to dynamically register
9
+ * packages, components, and processors at runtime.
10
+ *
11
+ * @class ExtensionRegistry
12
+ */
13
+ export declare class ExtensionRegistry {
14
+ protected static [instanceSymbol]: ExtensionRegistry;
15
+ static get packages(): ResponsiveMap<ExtensionPackage[]>;
16
+ static get components(): ResponsiveMap<ComponentExtension[]>;
17
+ static get processors(): ResponsiveMap<ProcessorExtension[]>;
18
+ static setResolver(fn: ExtensionRegistry.PackageResolver | undefined): void;
19
+ static findComponent(className: string, version?: string): ComponentExtension | undefined;
20
+ static getComponent(className: string, version?: string): ComponentExtension;
21
+ static findProcessor(className: string, version?: string): ProcessorExtension | undefined;
22
+ static getProcessor(className: string, version?: string): ProcessorExtension;
23
+ static registerPackage(specifier: string): Promise<ExtensionPackage>;
24
+ static registerComponent(ctor: Type): Promise<ComponentExtension | undefined>;
25
+ static registerProcessor(ctor: Type): Promise<ProcessorExtension | undefined>;
26
+ static storePackage(pkg: ExtensionPackage): void;
27
+ protected _resolver: ExtensionRegistry.PackageResolver;
28
+ readonly packages: ResponsiveMap<ExtensionPackage[]>;
29
+ readonly components: ResponsiveMap<ComponentExtension[]>;
30
+ readonly processors: ResponsiveMap<ProcessorExtension[]>;
31
+ /**
32
+ *
33
+ */
34
+ setResolver(fn: ExtensionRegistry.PackageResolver | undefined): void;
9
35
  /**
10
36
  *
11
37
  */
12
- function findComponent(className: string, version?: string): ComponentExtension | undefined;
38
+ findComponent(className: string, version?: string): ComponentExtension | undefined;
13
39
  /**
14
40
  *
15
41
  */
16
- function getComponent(className: string, version?: string): ComponentExtension;
42
+ getComponent(className: string, version?: string): ComponentExtension;
17
43
  /**
18
44
  *
19
45
  */
20
- function findProcessor(className: string, version?: string): ProcessorExtension | undefined;
46
+ findProcessor(className: string, version?: string): ProcessorExtension | undefined;
21
47
  /**
22
48
  *
23
49
  */
24
- function getProcessor(className: string, version?: string): ProcessorExtension;
50
+ getProcessor(className: string, version?: string): ProcessorExtension;
25
51
  /**
26
52
  *
27
53
  */
28
- function setResolver(fn: Resolver | undefined): void;
54
+ registerPackage(specifier: string): Promise<ExtensionPackage>;
55
+ registerComponent(ctor: Type): Promise<ComponentExtension | undefined>;
29
56
  /**
30
57
  *
31
58
  */
32
- function registerExtensionPackage(directory: string): Promise<ExtensionPackage>;
59
+ registerProcessor(ctor: Type): Promise<ProcessorExtension | undefined>;
33
60
  /**
34
61
  *
35
62
  */
36
- function registerNodePackage(specifier: string): Promise<ExtensionPackage>;
37
- function registerComponent(ctor: Type): Promise<ComponentExtension | undefined>;
38
- function registerProcessor(ctor: Type): Promise<ProcessorExtension | undefined>;
63
+ storePackage(pkg: ExtensionPackage): void;
64
+ }
65
+ /**
66
+ *
67
+ * @namespace ExtensionRegistry
68
+ */
69
+ export declare namespace ExtensionRegistry {
70
+ type PackageResolver = (specifier: string) => string;
39
71
  }
72
+ export {};
@@ -1,89 +1,175 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { pathToFileURL } from 'node:url';
4
+ import { updateErrorMessage } from '@jsopen/objects';
5
+ import { ResponsiveMap } from '@opra/common';
1
6
  import semver from 'semver';
2
7
  import { SbError } from '../classes/sb-error.js';
3
8
  import { COMPONENT_OPTIONS, PROCESSOR_OPTIONS } from '../constants.js';
9
+ import { normalizeComponentMetadata, normalizeProcessorMetadata, } from '../utils/normalize-metadata.js';
4
10
  import { ComponentExtension, ExtensionPackage, ProcessorExtension, } from './extension-package.js';
5
- import { normalizeComponentMetadata, normalizeProcessorMetadata, } from './normalize-metadata.js';
6
- export var ExtensionRegistry;
7
- (function (ExtensionRegistry) {
8
- let _resolver;
9
- ExtensionRegistry.packages = new Map();
10
- ExtensionRegistry.components = new Map();
11
- ExtensionRegistry.processors = new Map();
12
- /**
13
- *
14
- */
15
- function findComponent(className, version = '*') {
16
- return ExtensionRegistry.components
17
- .get(className)
18
- ?.find(v => semver.satisfies(v.version, version || '*'));
11
+ import { locatePackageJson } from './locate-package-json.js';
12
+ const instanceSymbol = Symbol.for('instance');
13
+ /**
14
+ * The `ExtensionRegistry` class is responsible for managing component and processor extensions,
15
+ * as well as handling the registration of extension packages. It provides methods to locate and
16
+ * retrieve extensions by their class name and version, and offers the ability to dynamically register
17
+ * packages, components, and processors at runtime.
18
+ *
19
+ * @class ExtensionRegistry
20
+ */
21
+ export class ExtensionRegistry {
22
+ static [instanceSymbol] = new ExtensionRegistry();
23
+ static get packages() {
24
+ return this[instanceSymbol].packages;
25
+ }
26
+ static get components() {
27
+ return this[instanceSymbol].components;
28
+ }
29
+ static get processors() {
30
+ return this[instanceSymbol].processors;
31
+ }
32
+ static setResolver(fn) {
33
+ this[instanceSymbol].setResolver(fn);
34
+ }
35
+ static findComponent(className, version = '*') {
36
+ return this[instanceSymbol].findComponent(className, version);
19
37
  }
20
- ExtensionRegistry.findComponent = findComponent;
38
+ static getComponent(className, version = '*') {
39
+ return this[instanceSymbol].getComponent(className, version);
40
+ }
41
+ static findProcessor(className, version = '*') {
42
+ return this[instanceSymbol].findProcessor(className, version);
43
+ }
44
+ static getProcessor(className, version = '*') {
45
+ return this[instanceSymbol].getProcessor(className, version);
46
+ }
47
+ static async registerPackage(specifier) {
48
+ return this[instanceSymbol].registerPackage(specifier);
49
+ }
50
+ static async registerComponent(ctor) {
51
+ return this[instanceSymbol].registerComponent(ctor);
52
+ }
53
+ static async registerProcessor(ctor) {
54
+ return this[instanceSymbol].registerProcessor(ctor);
55
+ }
56
+ static storePackage(pkg) {
57
+ return this[instanceSymbol].storePackage(pkg);
58
+ }
59
+ _resolver = import.meta.resolve;
60
+ packages = new ResponsiveMap();
61
+ components = new ResponsiveMap();
62
+ processors = new ResponsiveMap();
21
63
  /**
22
64
  *
23
65
  */
24
- function getComponent(className, version = '*') {
25
- const cmp = findComponent(className, version);
26
- if (cmp)
27
- return cmp;
28
- throw new SbError(`Component "${className}" version "${version}" not found in registry`);
66
+ setResolver(fn) {
67
+ this._resolver = fn || import.meta.resolve;
29
68
  }
30
- ExtensionRegistry.getComponent = getComponent;
31
69
  /**
32
70
  *
33
71
  */
34
- function findProcessor(className, version = '*') {
35
- return ExtensionRegistry.processors
72
+ findComponent(className, version = '*') {
73
+ return this.components
36
74
  .get(className)
37
75
  ?.find(v => semver.satisfies(v.version, version || '*'));
38
76
  }
39
- ExtensionRegistry.findProcessor = findProcessor;
40
77
  /**
41
78
  *
42
79
  */
43
- function getProcessor(className, version = '*') {
44
- const cmp = findProcessor(className, version);
80
+ getComponent(className, version = '*') {
81
+ const cmp = this.findComponent(className, version);
45
82
  if (!cmp) {
46
- throw new SbError(`Processor "${className}" version "${version}" not found in registry`);
83
+ throw new SbError(`Component "${className}@${version}" not found in registry`);
47
84
  }
48
85
  return cmp;
49
86
  }
50
- ExtensionRegistry.getProcessor = getProcessor;
51
87
  /**
52
88
  *
53
89
  */
54
- function setResolver(fn) {
55
- _resolver = fn;
90
+ findProcessor(className, version = '*') {
91
+ return this.processors
92
+ .get(className)
93
+ ?.find(v => semver.satisfies(v.version, version || '*'));
56
94
  }
57
- ExtensionRegistry.setResolver = setResolver;
58
95
  /**
59
96
  *
60
97
  */
61
- async function registerExtensionPackage(directory) {
62
- const pkg = await ExtensionPackage.fromDirectory(directory);
63
- storePackage(pkg);
64
- return pkg;
98
+ getProcessor(className, version = '*') {
99
+ const cmp = this.findProcessor(className, version);
100
+ if (!cmp) {
101
+ throw new SbError(`Processor "${className}@${version}" not found in registry`);
102
+ }
103
+ return cmp;
65
104
  }
66
- ExtensionRegistry.registerExtensionPackage = registerExtensionPackage;
67
105
  /**
68
106
  *
69
107
  */
70
- async function registerNodePackage(specifier) {
71
- const pkg = await ExtensionPackage.fromNodePackage(specifier, _resolver);
72
- storePackage(pkg);
108
+ async registerPackage(specifier) {
109
+ let entryPoint = this._resolver(specifier);
110
+ const pkgDir = locatePackageJson(path.dirname(entryPoint));
111
+ if (!pkgDir) {
112
+ throw new SbError(`Can't locate package.json file for "${specifier}"`);
113
+ }
114
+ const pkgJson = JSON.parse(fs.readFileSync(path.join(pkgDir, 'package.json'), 'utf8'));
115
+ if (path.isAbsolute(entryPoint) && process.platform === 'win32') {
116
+ entryPoint = pathToFileURL(entryPoint).href;
117
+ }
118
+ const pkg = new ExtensionPackage();
119
+ pkg.name = pkgJson.name;
120
+ pkg.version = pkgJson.version;
121
+ pkg.description = pkgJson.description;
122
+ pkg.path = pkgDir;
123
+ pkg.entryPoint = entryPoint;
124
+ const module = await import(entryPoint);
125
+ for (const [ctorName, v] of Object.entries(module)) {
126
+ if (typeof v !== 'function')
127
+ continue;
128
+ let metadata = Reflect.getMetadata(COMPONENT_OPTIONS, v);
129
+ if (metadata) {
130
+ try {
131
+ metadata = await normalizeComponentMetadata(metadata);
132
+ }
133
+ catch (e) {
134
+ updateErrorMessage(e, `Component (${ctorName}) metadata validation error. ` + e.message);
135
+ pkg.errors.push(e);
136
+ continue;
137
+ }
138
+ if (metadata.abstract)
139
+ continue;
140
+ pkg.components = pkg.components || [];
141
+ pkg.components.push(new ComponentExtension(pkg, ctorName, metadata));
142
+ }
143
+ metadata = Reflect.getMetadata(PROCESSOR_OPTIONS, v);
144
+ if (metadata) {
145
+ try {
146
+ metadata = await normalizeProcessorMetadata(metadata);
147
+ }
148
+ catch (e) {
149
+ updateErrorMessage(e, `Processor (${ctorName}) metadata validation error. ` + e.message);
150
+ pkg.errors.push(e);
151
+ continue;
152
+ }
153
+ if (metadata.abstract)
154
+ continue;
155
+ pkg.processors = pkg.processors || [];
156
+ pkg.processors.push(new ProcessorExtension(pkg, ctorName, metadata));
157
+ }
158
+ }
159
+ this.storePackage(pkg);
73
160
  return pkg;
74
161
  }
75
- ExtensionRegistry.registerNodePackage = registerNodePackage;
76
- async function registerComponent(ctor) {
162
+ async registerComponent(ctor) {
77
163
  const _metadata = Reflect.getMetadata(COMPONENT_OPTIONS, ctor);
78
164
  if (!_metadata)
79
165
  throw new SbError(`Class "${ctor.name}" has no component metadata.`);
80
166
  if (_metadata.abstract)
81
167
  return;
82
168
  const metadata = await normalizeComponentMetadata(_metadata);
83
- let versions = ExtensionRegistry.packages.get('internal');
169
+ let versions = this.packages.get('internal');
84
170
  if (!versions) {
85
171
  versions = [];
86
- ExtensionRegistry.packages.set('internal', versions);
172
+ this.packages.set('internal', versions);
87
173
  }
88
174
  let pkg = versions[0];
89
175
  if (!pkg) {
@@ -94,21 +180,23 @@ export var ExtensionRegistry;
94
180
  }
95
181
  const cmp = new ComponentExtension(pkg, ctor.name, metadata, ctor);
96
182
  pkg.components.push(cmp);
97
- storePackage(pkg);
183
+ this.storePackage(pkg);
98
184
  return cmp;
99
185
  }
100
- ExtensionRegistry.registerComponent = registerComponent;
101
- async function registerProcessor(ctor) {
186
+ /**
187
+ *
188
+ */
189
+ async registerProcessor(ctor) {
102
190
  const _metadata = Reflect.getMetadata(PROCESSOR_OPTIONS, ctor);
103
191
  if (!_metadata)
104
192
  throw new SbError(`Class "${ctor.name}" has no processor metadata.`);
105
193
  if (_metadata.abstract)
106
194
  return;
107
195
  const metadata = await normalizeProcessorMetadata(_metadata);
108
- let versions = ExtensionRegistry.packages.get('internal');
196
+ let versions = this.packages.get('internal');
109
197
  if (!versions) {
110
198
  versions = [];
111
- ExtensionRegistry.packages.set('internal', versions);
199
+ this.packages.set('internal', versions);
112
200
  }
113
201
  let pkg = versions[0];
114
202
  if (!pkg) {
@@ -119,20 +207,17 @@ export var ExtensionRegistry;
119
207
  }
120
208
  const prc = new ProcessorExtension(pkg, ctor.name, metadata, ctor);
121
209
  pkg.processors.push(prc);
122
- storePackage(pkg);
210
+ this.storePackage(pkg);
123
211
  return prc;
124
212
  }
125
- ExtensionRegistry.registerProcessor = registerProcessor;
126
213
  /**
127
214
  *
128
- * @private
129
215
  */
130
- function storePackage(pkg) {
131
- pkg.sortVersions();
132
- let pkgVersions = ExtensionRegistry.packages.get(pkg.name);
216
+ storePackage(pkg) {
217
+ let pkgVersions = this.packages.get(pkg.name);
133
218
  if (!pkgVersions) {
134
219
  pkgVersions = [];
135
- ExtensionRegistry.packages.set(pkg.name, pkgVersions);
220
+ this.packages.set(pkg.name, pkgVersions);
136
221
  }
137
222
  let i = pkgVersions.findIndex(v => v.version === pkg.version);
138
223
  if (i >= 0)
@@ -142,10 +227,10 @@ export var ExtensionRegistry;
142
227
  pkgVersions.sort((a, b) => a.version.localeCompare(b.version));
143
228
  if (pkg.components?.length) {
144
229
  for (const cmp of pkg.components) {
145
- let versions = ExtensionRegistry.components.get(cmp.className);
230
+ let versions = this.components.get(cmp.className);
146
231
  if (!versions) {
147
232
  versions = [];
148
- ExtensionRegistry.components.set(cmp.className, versions);
233
+ this.components.set(cmp.className, versions);
149
234
  }
150
235
  i = versions.findIndex(v => v.version === cmp.version);
151
236
  if (i >= 0)
@@ -156,10 +241,10 @@ export var ExtensionRegistry;
156
241
  }
157
242
  if (pkg.processors?.length) {
158
243
  for (const prc of pkg.processors) {
159
- let versions = ExtensionRegistry.processors.get(prc.className);
244
+ let versions = this.processors.get(prc.className);
160
245
  if (!versions) {
161
246
  versions = [];
162
- ExtensionRegistry.processors.set(prc.className, versions);
247
+ this.processors.set(prc.className, versions);
163
248
  }
164
249
  i = versions.findIndex(v => v.version === prc.version);
165
250
  if (i >= 0)
@@ -169,4 +254,4 @@ export var ExtensionRegistry;
169
254
  }
170
255
  }
171
256
  }
172
- })(ExtensionRegistry || (ExtensionRegistry = {}));
257
+ }
@@ -0,0 +1,4 @@
1
+ /**
2
+ *
3
+ */
4
+ export declare function locatePackageJson(directory: string): string | undefined;
@@ -0,0 +1,17 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ /**
5
+ *
6
+ */
7
+ export function locatePackageJson(directory) {
8
+ if (directory.startsWith('file:'))
9
+ directory = fileURLToPath(directory);
10
+ for (let i = 0; i < 3; i++) {
11
+ const f = path.resolve(directory, 'package.json');
12
+ if (fs.existsSync(f)) {
13
+ return directory;
14
+ }
15
+ directory = path.dirname(directory);
16
+ }
17
+ }
@@ -12,6 +12,10 @@ export declare function decodeProfileSilent(materializedMetadata: ProcessorMetad
12
12
  profile: Profile;
13
13
  issues?: StackExecutor.Issue[];
14
14
  };
15
+ /**
16
+ * Encodes profile
17
+ */
18
+ export declare function encodeProfile(materializedMetadata: ProcessorMetadata, rawProfile: Profile, options?: CodecOptions): Profile;
15
19
  /**
16
20
  * Encodes profile
17
21
  */
@@ -10,7 +10,7 @@ import { secretDecryptor, secretEncryptor } from './encrypt-helpers.js';
10
10
  export function decodeProfile(materializedMetadata, rawProfile, options) {
11
11
  const { profile: out, issues } = decodeProfileSilent(materializedMetadata, rawProfile, options);
12
12
  if (issues?.length) {
13
- const msg = 'Worker profile validation error.\n ' +
13
+ const msg = 'Worker profile decoding error.\n ' +
14
14
  issues
15
15
  .map(issue => `- ${issue.message}. Location: /${issue.location}`)
16
16
  .join('\n ');
@@ -34,6 +34,27 @@ export function decodeProfileSilent(materializedMetadata, rawProfile, options) {
34
34
  _codecProcessElement(stackExecutor, 'decode', materializedMetadata, out, options);
35
35
  return { profile: out, issues: stackExecutor.issues };
36
36
  }
37
+ /**
38
+ * Encodes profile
39
+ */
40
+ export function encodeProfile(materializedMetadata, rawProfile, options) {
41
+ const { profile: out, issues } = encodeProfileSilent(materializedMetadata, rawProfile, options);
42
+ if (issues?.length) {
43
+ const msg = 'Worker profile encoding error.\n ' +
44
+ issues
45
+ .map(issue => `- ${issue.message}. Location: /${issue.location}`)
46
+ .join('\n ');
47
+ issues.forEach(issue => {
48
+ if (issue instanceof SbValidationError)
49
+ delete issue.stack;
50
+ });
51
+ throw new SbValidationError(msg, {
52
+ workerId: rawProfile.id,
53
+ issues,
54
+ });
55
+ }
56
+ return out;
57
+ }
37
58
  /**
38
59
  * Encodes profile
39
60
  */
@@ -0,0 +1,12 @@
1
+ import { StackExecutor } from '../classes/stack-executor.js';
2
+ import { ComponentMetadata, ProcessorMetadata } from '../models/index.js';
3
+ export declare function normalizeProcessorMetadata(metadata: ProcessorMetadata): Promise<ProcessorMetadata>;
4
+ export declare function normalizeProcessorMetadataSilent(metadata: ProcessorMetadata): Promise<{
5
+ metadata: ProcessorMetadata;
6
+ issues?: StackExecutor.Issue[];
7
+ }>;
8
+ export declare function normalizeComponentMetadata(metadata: ComponentMetadata): Promise<ComponentMetadata>;
9
+ export declare function normalizeComponentMetadataSilent(metadata: ComponentMetadata): Promise<{
10
+ metadata: ComponentMetadata;
11
+ issues?: StackExecutor.Issue[];
12
+ }>;
@@ -0,0 +1,149 @@
1
+ import { deepClone, merge } from '@jsopen/objects';
2
+ import { SbValidationError } from '../classes/sb-error.js';
3
+ import { ComponentMetadata, ProcessorMetadata, } from '../models/index.js';
4
+ import { initializeModelsDocument } from '../models-document.js';
5
+ import { resolvePromisesDeep } from './resolve-promises.js';
6
+ export async function normalizeProcessorMetadata(metadata) {
7
+ const { metadata: out, issues } = await normalizeProcessorMetadataSilent(metadata);
8
+ if (issues?.length) {
9
+ const msg = 'Worker profile decoding error.\n ' +
10
+ issues
11
+ .map(issue => `- ${issue.message}. Location: /${issue.location}`)
12
+ .join('\n ');
13
+ issues.forEach(issue => {
14
+ if (issue instanceof SbValidationError)
15
+ delete issue.stack;
16
+ });
17
+ throw new SbValidationError(msg, {
18
+ issues,
19
+ });
20
+ }
21
+ return out;
22
+ }
23
+ export async function normalizeProcessorMetadataSilent(metadata) {
24
+ const decoder = await getProcMetadataTypeDecoder();
25
+ let cloned = deepClone({
26
+ className: metadata.className,
27
+ displayName: metadata.displayName,
28
+ description: metadata.description,
29
+ iconUrl: metadata.iconUrl,
30
+ author: metadata.author,
31
+ tags: metadata.tags,
32
+ abstract: metadata.abstract,
33
+ variables: metadata.variables,
34
+ components: metadata.components,
35
+ ...metadata,
36
+ });
37
+ cloned = await resolvePromisesDeep(cloned);
38
+ cloned.variables = normalizeVariables(cloned.variables);
39
+ cloned.components = normalizeComponents(cloned.components);
40
+ const { value, errors } = decoder.silent(cloned);
41
+ merge(value, metadata, { keepExisting: true, deep: 'full' });
42
+ return {
43
+ metadata: value || cloned,
44
+ issues: errors?.map(x => ({
45
+ ...x.issue,
46
+ severity: 'error',
47
+ })),
48
+ };
49
+ }
50
+ export async function normalizeComponentMetadata(metadata) {
51
+ const { metadata: out, issues } = await normalizeComponentMetadataSilent(metadata);
52
+ if (issues?.length) {
53
+ const msg = 'Worker profile decoding error.\n ' +
54
+ issues
55
+ .map(issue => `- ${issue.message}. Location: /${issue.location}`)
56
+ .join('\n ');
57
+ issues.forEach(issue => {
58
+ if (issue instanceof SbValidationError)
59
+ delete issue.stack;
60
+ });
61
+ throw new SbValidationError(msg, {
62
+ issues,
63
+ });
64
+ }
65
+ return out;
66
+ }
67
+ export async function normalizeComponentMetadataSilent(metadata) {
68
+ const decoder = await getCompMetadataTypeDecoder();
69
+ let cloned = deepClone({
70
+ className: metadata.className,
71
+ displayName: metadata.displayName,
72
+ description: metadata.description,
73
+ iconUrl: metadata.iconUrl,
74
+ author: metadata.author,
75
+ interfaces: metadata.interfaces,
76
+ tags: metadata.tags,
77
+ abstract: metadata.abstract,
78
+ variables: metadata.variables,
79
+ components: metadata.components,
80
+ ...metadata,
81
+ });
82
+ cloned = await resolvePromisesDeep(cloned);
83
+ cloned.variables = normalizeVariables(cloned.variables);
84
+ cloned.components = normalizeComponents(cloned.components);
85
+ const { value, errors } = decoder.silent(cloned);
86
+ merge(value, metadata, { keepExisting: true, deep: 'full' });
87
+ return {
88
+ metadata: value || cloned,
89
+ issues: errors?.map(x => ({
90
+ ...x.issue,
91
+ severity: 'error',
92
+ })),
93
+ };
94
+ }
95
+ function normalizeComponents(components) {
96
+ if (!components)
97
+ return;
98
+ for (const component of Object.values(components)) {
99
+ if (component.variables)
100
+ component.variables = normalizeVariables(component.variables);
101
+ if (component.components)
102
+ component.components = normalizeComponents(component.components);
103
+ }
104
+ return components;
105
+ }
106
+ function normalizeVariables(variables) {
107
+ if (!variables)
108
+ return;
109
+ /** Convert object enumValues to arrays */
110
+ for (const v of Object.values(variables)) {
111
+ if (v.enumValues &&
112
+ typeof v.enumValues === 'object' &&
113
+ !Array.isArray(v.enumValues)) {
114
+ let values = v.enumValues;
115
+ const keys = Object.keys(values).filter(k => !/^\d+$/.test(k));
116
+ values = keys.reduce((a, k) => {
117
+ if (values[k] != null)
118
+ a.push(values[k]);
119
+ return a;
120
+ }, []);
121
+ v.enumValues = values;
122
+ }
123
+ }
124
+ return variables;
125
+ }
126
+ // ************************************************************************
127
+ // ************************************************************************
128
+ let _compMetadataTypeDecoder;
129
+ let _procMetadataTypeDecoder;
130
+ async function getCompMetadataTypeDecoder() {
131
+ if (!_compMetadataTypeDecoder) {
132
+ const apiDoc = await initializeModelsDocument();
133
+ const compMetadataType = apiDoc.node.getComplexType(ComponentMetadata);
134
+ _compMetadataTypeDecoder = compMetadataType.generateCodec('decode', {
135
+ coerce: true,
136
+ });
137
+ }
138
+ return _compMetadataTypeDecoder;
139
+ }
140
+ async function getProcMetadataTypeDecoder() {
141
+ if (!_procMetadataTypeDecoder) {
142
+ const apiDoc = await initializeModelsDocument();
143
+ const procMetadataType = apiDoc.node.getComplexType(ProcessorMetadata);
144
+ _procMetadataTypeDecoder = procMetadataType.generateCodec('decode', {
145
+ coerce: true,
146
+ });
147
+ }
148
+ return _procMetadataTypeDecoder;
149
+ }
@@ -1,3 +0,0 @@
1
- import { ComponentMetadata, ProcessorMetadata } from '../models/index.js';
2
- export declare function normalizeProcessorMetadata(metadata: ProcessorMetadata): Promise<ProcessorMetadata>;
3
- export declare function normalizeComponentMetadata(metadata: ComponentMetadata): Promise<ComponentMetadata>;
@@ -1,98 +0,0 @@
1
- import { deepClone, merge } from '@jsopen/objects';
2
- import { ComponentMetadata, ProcessorMetadata, } from '../models/index.js';
3
- import { initializeModelsDocument } from '../models-document.js';
4
- import { resolvePromisesDeep } from '../utils/resolve-promises.js';
5
- export async function normalizeProcessorMetadata(metadata) {
6
- const decoder = await getProcMetadataTypeDecoder();
7
- let out = await resolvePromisesDeep(metadata);
8
- out = deepClone(out);
9
- out = decoder({
10
- className: out.className,
11
- displayName: out.displayName,
12
- description: out.description,
13
- iconUrl: out.iconUrl,
14
- author: out.author,
15
- tags: out.tags,
16
- abstract: out.abstract,
17
- variables: normalizeVariables(out.variables),
18
- components: normalizeComponents(out.components),
19
- ...out,
20
- });
21
- merge(out, metadata, { keepExisting: true, deep: 'full' });
22
- return out;
23
- }
24
- export async function normalizeComponentMetadata(metadata) {
25
- const decoder = await getCompMetadataTypeDecoder();
26
- let out = await resolvePromisesDeep(metadata);
27
- out = deepClone(out);
28
- out = decoder({
29
- className: out.className,
30
- displayName: out.displayName,
31
- description: out.description,
32
- iconUrl: out.iconUrl,
33
- author: out.author,
34
- interfaces: out.interfaces,
35
- tags: out.tags,
36
- abstract: out.abstract,
37
- variables: normalizeVariables(out.variables),
38
- components: normalizeComponents(out.components),
39
- ...out,
40
- });
41
- merge(out, metadata, { keepExisting: true, deep: 'full' });
42
- return out;
43
- }
44
- function normalizeComponents(components) {
45
- if (!components)
46
- return;
47
- for (const component of Object.values(components)) {
48
- if (component.variables)
49
- component.variables = normalizeVariables(component.variables);
50
- if (component.components)
51
- component.components = normalizeComponents(component.components);
52
- }
53
- return components;
54
- }
55
- function normalizeVariables(variables) {
56
- if (!variables)
57
- return;
58
- /** Convert object enumValues to arrays */
59
- for (const v of Object.values(variables)) {
60
- if (v.enumValues &&
61
- typeof v.enumValues === 'object' &&
62
- !Array.isArray(v.enumValues)) {
63
- let values = v.enumValues;
64
- const keys = Object.keys(values).filter(k => !/^\d+$/.test(k));
65
- values = keys.reduce((a, k) => {
66
- if (values[k] != null)
67
- a.push(values[k]);
68
- return a;
69
- }, []);
70
- v.enumValues = values;
71
- }
72
- }
73
- return variables;
74
- }
75
- // ************************************************************************
76
- // ************************************************************************
77
- let _compMetadataTypeDecoder;
78
- let _procMetadataTypeDecoder;
79
- async function getCompMetadataTypeDecoder() {
80
- if (!_compMetadataTypeDecoder) {
81
- const apiDoc = await initializeModelsDocument();
82
- const compMetadataType = apiDoc.node.getComplexType(ComponentMetadata);
83
- _compMetadataTypeDecoder = compMetadataType.generateCodec('decode', {
84
- coerce: true,
85
- });
86
- }
87
- return _compMetadataTypeDecoder;
88
- }
89
- async function getProcMetadataTypeDecoder() {
90
- if (!_procMetadataTypeDecoder) {
91
- const apiDoc = await initializeModelsDocument();
92
- const procMetadataType = apiDoc.node.getComplexType(ProcessorMetadata);
93
- _procMetadataTypeDecoder = procMetadataType.generateCodec('decode', {
94
- coerce: true,
95
- });
96
- }
97
- return _procMetadataTypeDecoder;
98
- }