@syncbridge/common 0.4.7 → 0.5.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.
@@ -0,0 +1,234 @@
1
+ import { deepClone } from '@jsopen/objects';
2
+ import semver from 'semver';
3
+ import { COMPONENT_OPTIONS } from '../constants.js';
4
+ import { resolvePromisesDeep } from '../utils/resolve-promises.js';
5
+ import { ExtensionPackage, ExtensionPackageComponent, ExtensionPackageProcessor, } from './extension-package.js';
6
+ export var ExtensionRegistry;
7
+ (function (ExtensionRegistry) {
8
+ let _resolver = import.meta.resolve;
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 || '*'));
19
+ }
20
+ ExtensionRegistry.findComponent = findComponent;
21
+ /**
22
+ *
23
+ */
24
+ function getComponent(className, version = '*') {
25
+ const cmp = findComponent(className, version);
26
+ if (cmp)
27
+ return cmp;
28
+ throw new Error(`Component "${className}" version "${version}" not found in registry`);
29
+ }
30
+ ExtensionRegistry.getComponent = getComponent;
31
+ /**
32
+ *
33
+ */
34
+ function findProcessor(className, version = '*') {
35
+ return ExtensionRegistry.processors
36
+ .get(className)
37
+ ?.find(v => semver.satisfies(v.version, version || '*'));
38
+ }
39
+ ExtensionRegistry.findProcessor = findProcessor;
40
+ /**
41
+ *
42
+ */
43
+ function getProcessor(className, version = '*') {
44
+ const cmp = findProcessor(className, version);
45
+ if (!cmp) {
46
+ throw new Error(`Processor "${className}" version "${version}" not found in registry`);
47
+ }
48
+ return cmp;
49
+ }
50
+ ExtensionRegistry.getProcessor = getProcessor;
51
+ /**
52
+ *
53
+ * @param resolver
54
+ */
55
+ function setResolver(resolver) {
56
+ _resolver = resolver;
57
+ }
58
+ ExtensionRegistry.setResolver = setResolver;
59
+ /**
60
+ *
61
+ */
62
+ async function registerExtensionPackage(directory) {
63
+ const pkg = await ExtensionPackage.fromDirectory(directory);
64
+ storePackage(pkg);
65
+ return pkg;
66
+ }
67
+ ExtensionRegistry.registerExtensionPackage = registerExtensionPackage;
68
+ /**
69
+ *
70
+ */
71
+ async function registerNodePackage(specifier) {
72
+ const pkg = await ExtensionPackage.fromNodePackage(specifier, _resolver);
73
+ storePackage(pkg);
74
+ return pkg;
75
+ }
76
+ ExtensionRegistry.registerNodePackage = registerNodePackage;
77
+ async function registerComponent(ctor) {
78
+ const _metadata = Reflect.getMetadata(COMPONENT_OPTIONS, ctor);
79
+ if (!_metadata)
80
+ throw new TypeError(`Class "${ctor.name}" has no component metadata.`);
81
+ if (_metadata.abstract)
82
+ return;
83
+ let metadata = await resolvePromisesDeep(_metadata);
84
+ metadata = deepClone({
85
+ className: metadata.className,
86
+ displayName: metadata.displayName,
87
+ description: metadata.description,
88
+ iconUrl: metadata.iconUrl,
89
+ author: metadata.author,
90
+ interfaces: metadata.interfaces,
91
+ tags: metadata.tags,
92
+ abstract: metadata.abstract,
93
+ variables: metadata.variables,
94
+ components: metadata.components,
95
+ ...metadata,
96
+ });
97
+ if (metadata.variables) {
98
+ /** Convert object enumValues to arrays */
99
+ for (const v of Object.values(metadata.variables)) {
100
+ if (v.enumValues &&
101
+ typeof v.enumValues === 'object' &&
102
+ !Array.isArray(v.enumValues)) {
103
+ let values = v.enumValues;
104
+ const keys = Object.keys(values).filter(k => !/^\d+$/.test(k));
105
+ values = keys.reduce((a, k) => {
106
+ if (values[k] != null)
107
+ a.push(values[k]);
108
+ return a;
109
+ // v => !(typeof v === 'number' && !keys.includes(String(v))),
110
+ }, []);
111
+ v.enumValues = values;
112
+ }
113
+ }
114
+ }
115
+ let versions = ExtensionRegistry.packages.get('internal');
116
+ if (!versions) {
117
+ versions = [];
118
+ ExtensionRegistry.packages.set('internal', versions);
119
+ }
120
+ let pkg = versions[0];
121
+ if (!pkg) {
122
+ pkg = new ExtensionPackage();
123
+ pkg.name = 'internal';
124
+ pkg.version = '0.0.0';
125
+ pkg.description = 'Internal extensions';
126
+ }
127
+ const cmp = new ExtensionPackageComponent(pkg, ctor.name, metadata, ctor);
128
+ pkg.components.push(cmp);
129
+ storePackage(pkg);
130
+ return cmp;
131
+ }
132
+ ExtensionRegistry.registerComponent = registerComponent;
133
+ async function registerProcessor(ctor) {
134
+ const _metadata = Reflect.getMetadata(COMPONENT_OPTIONS, ctor);
135
+ if (!_metadata)
136
+ throw new TypeError(`Class "${ctor.name}" has no processor metadata.`);
137
+ if (_metadata.abstract)
138
+ return;
139
+ let metadata = await resolvePromisesDeep(_metadata);
140
+ metadata = deepClone({
141
+ className: metadata.className,
142
+ displayName: metadata.displayName,
143
+ description: metadata.description,
144
+ iconUrl: metadata.iconUrl,
145
+ author: metadata.author,
146
+ tags: metadata.tags,
147
+ abstract: metadata.abstract,
148
+ variables: metadata.variables,
149
+ components: metadata.components,
150
+ ...metadata,
151
+ });
152
+ if (metadata.variables) {
153
+ /** Convert object enumValues to arrays */
154
+ for (const v of Object.values(metadata.variables)) {
155
+ if (v.enumValues &&
156
+ typeof v.enumValues === 'object' &&
157
+ !Array.isArray(v.enumValues)) {
158
+ let values = v.enumValues;
159
+ const keys = Object.keys(values).filter(k => !/^\d+$/.test(k));
160
+ values = keys.reduce((a, k) => {
161
+ if (values[k] != null)
162
+ a.push(values[k]);
163
+ return a;
164
+ // v => !(typeof v === 'number' && !keys.includes(String(v))),
165
+ }, []);
166
+ v.enumValues = values;
167
+ }
168
+ }
169
+ }
170
+ let versions = ExtensionRegistry.packages.get('internal');
171
+ if (!versions) {
172
+ versions = [];
173
+ ExtensionRegistry.packages.set('internal', versions);
174
+ }
175
+ let pkg = versions[0];
176
+ if (!pkg) {
177
+ pkg = new ExtensionPackage();
178
+ pkg.name = 'internal';
179
+ pkg.version = '0.0.0';
180
+ pkg.description = 'Internal extensions';
181
+ }
182
+ const prc = new ExtensionPackageProcessor(pkg, ctor.name, metadata, ctor);
183
+ pkg.processors.push(prc);
184
+ storePackage(pkg);
185
+ return prc;
186
+ }
187
+ ExtensionRegistry.registerProcessor = registerProcessor;
188
+ /**
189
+ *
190
+ * @private
191
+ */
192
+ function storePackage(pkg) {
193
+ pkg.sortVersions();
194
+ let pkgVersions = ExtensionRegistry.packages.get(pkg.name);
195
+ if (!pkgVersions) {
196
+ pkgVersions = [];
197
+ ExtensionRegistry.packages.set(pkg.name, pkgVersions);
198
+ }
199
+ let i = pkgVersions.findIndex(v => v.version === pkg.version);
200
+ if (i >= 0)
201
+ pkgVersions[i] = pkg;
202
+ else
203
+ pkgVersions.push(pkg);
204
+ pkgVersions.sort((a, b) => a.version.localeCompare(b.version));
205
+ if (pkg.components?.length) {
206
+ for (const cmp of pkg.components) {
207
+ let versions = ExtensionRegistry.components.get(cmp.className);
208
+ if (!versions) {
209
+ versions = [];
210
+ ExtensionRegistry.components.set(cmp.className, versions);
211
+ }
212
+ i = versions.findIndex(v => v.version === cmp.version);
213
+ if (i >= 0)
214
+ versions[i] = cmp;
215
+ else
216
+ versions.push(cmp);
217
+ }
218
+ }
219
+ if (pkg.processors?.length) {
220
+ for (const prc of pkg.processors) {
221
+ let versions = ExtensionRegistry.processors.get(prc.className);
222
+ if (!versions) {
223
+ versions = [];
224
+ ExtensionRegistry.processors.set(prc.className, versions);
225
+ }
226
+ i = versions.findIndex(v => v.version === prc.version);
227
+ if (i >= 0)
228
+ versions[i] = prc;
229
+ else
230
+ versions.push(prc);
231
+ }
232
+ }
233
+ }
234
+ })(ExtensionRegistry || (ExtensionRegistry = {}));
File without changes
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+ // import * as 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 { deepClone, isPlainObject } from '@jsopen/objects';
7
+ // import { Type } from 'ts-gems';
8
+ // import type { ComponentBase } from '../classes/component-base.js';
9
+ // import type { ProcessorBase } from '../classes/processor-base.js';
10
+ // import { COMPONENT_OPTIONS, PROCESSOR_OPTIONS } from '../constants.js';
11
+ // import { ComponentMetadata, ProcessorMetadata } from '../models/index.js';
12
+ // import { isExtensionPackage } from '../utils/make-extension-package.js';
13
+ //
14
+ // export namespace ExtensionRegistry {
15
+ // let _resolver = import.meta.resolve;
16
+ //
17
+ // export const packages = new Map<
18
+ // string,
19
+ // ExtensionRegistry.ExtensionPackageRecord
20
+ // >();
21
+ // export const components = new Map<
22
+ // string,
23
+ // ExtensionRegistry.ComponentRecord
24
+ // >();
25
+ // export const processors = new Map<
26
+ // string,
27
+ // ExtensionRegistry.ProcessorRecord
28
+ // >();
29
+ //
30
+ // export function setResolver(resolver: (name: string) => string) {
31
+ // _resolver = resolver;
32
+ // }
33
+ //
34
+ // export function getProcessor(
35
+ // className: string,
36
+ // ): ExtensionRegistry.ProcessorRecord {
37
+ // const rec = ExtensionRegistry.processors.get(className);
38
+ // if (!rec) {
39
+ // throw new Error(`Processor "${className}" not found in registry`);
40
+ // }
41
+ // return rec;
42
+ // }
43
+ //
44
+ // export function getComponent(
45
+ // className: string,
46
+ // ): ExtensionRegistry.ComponentRecord {
47
+ // const rec = ExtensionRegistry.components.get(className);
48
+ // if (!rec) {
49
+ // throw new Error(`Component "${className}" not found in registry`);
50
+ // }
51
+ // return rec;
52
+ // }
53
+ //
54
+ // export async function registerPackage(
55
+ // ...specifiers: string[]
56
+ // ): Promise<void> {
57
+ // const errors: string[] = [];
58
+ // await Promise.all(
59
+ // specifiers.map(specifier =>
60
+ // _registerPackage(specifier).catch(err => {
61
+ // errors.push(`\n ${specifier}: ${err.message}`);
62
+ // }),
63
+ // ),
64
+ // );
65
+ // if (errors.length) {
66
+ // console.error(`Failed to register extensions:${errors}`);
67
+ // }
68
+ // }
69
+ //
70
+ // async function _registerPackage(
71
+ // specifier: string,
72
+ // options?: {
73
+ // ignoreInvalid?: boolean;
74
+ // },
75
+ // ): Promise<void> {
76
+ // let packagePath = fileURLToPath(_resolver(specifier));
77
+ // const json = locatePkgJson(path.dirname(packagePath));
78
+ // if (!json) {
79
+ // if (options?.ignoreInvalid) return;
80
+ // throw new TypeError(`Can't locate package.json file for "${specifier}"`);
81
+ // }
82
+ //
83
+ // if (path.isAbsolute(packagePath) && process.platform === 'win32') {
84
+ // packagePath = pathToFileURL(packagePath).href;
85
+ // }
86
+ //
87
+ // const pkg = (await import(packagePath)).default;
88
+ // if (!isExtensionPackage(pkg)) {
89
+ // if (options?.ignoreInvalid) return;
90
+ // throw new TypeError(
91
+ // `"${specifier}" do not export ExtensionPackage interface`,
92
+ // );
93
+ // }
94
+ // // ignore if already registered
95
+ // if (packages.get(json.name)) return;
96
+ //
97
+ // // Register dependencies
98
+ // if (pkg.dependencies) {
99
+ // for (const dep of pkg.dependencies)
100
+ // await _registerPackage(dep, { ignoreInvalid: true });
101
+ // }
102
+ //
103
+ // const packageRec: ExtensionRegistry.ExtensionPackageRecord = Object.freeze({
104
+ // name: json.name,
105
+ // version: json.version,
106
+ // description: json.description,
107
+ // });
108
+ // packages.set(packageRec.name, packageRec);
109
+ //
110
+ // if (Array.isArray(pkg.components)) {
111
+ // for (const ctor of pkg.components) {
112
+ // await registerComponent(ctor, packageRec.name);
113
+ // }
114
+ // }
115
+ //
116
+ // if (Array.isArray(pkg.processors)) {
117
+ // for (const ctor of pkg.processors) {
118
+ // await registerProcessor(ctor, packageRec.name);
119
+ // }
120
+ // }
121
+ // }
122
+ //
123
+ // export async function registerComponent(ctor: Type, packageName: string) {
124
+ // const _metadata: ComponentMetadata = Reflect.getMetadata(
125
+ // COMPONENT_OPTIONS,
126
+ // ctor,
127
+ // );
128
+ // if (!_metadata)
129
+ // throw new TypeError(`Class "${ctor.name}" has no component metadata.`);
130
+ // if (_metadata.abstract) return;
131
+ // let componentRec = components.get(_metadata.className);
132
+ // if (componentRec)
133
+ // throw new TypeError(
134
+ // `Component "${_metadata.className}" already registered by "${componentRec.package}" package`,
135
+ // );
136
+ //
137
+ // let metadata: ComponentMetadata = await resolvePromisesDeep(_metadata);
138
+ // metadata = deepClone({
139
+ // className: metadata.className,
140
+ // displayName: metadata.displayName,
141
+ // description: metadata.description,
142
+ // iconUrl: metadata.iconUrl,
143
+ // author: metadata.author,
144
+ // interfaces: metadata.interfaces,
145
+ // tags: metadata.tags,
146
+ // abstract: metadata.abstract,
147
+ // variables: metadata.variables,
148
+ // components: metadata.components,
149
+ // ...(metadata as any),
150
+ // });
151
+ // if (metadata.variables) {
152
+ // /** Convert object enumValues to arrays */
153
+ // for (const v of Object.values(metadata.variables)) {
154
+ // if (
155
+ // v.enumValues &&
156
+ // typeof v.enumValues === 'object' &&
157
+ // !Array.isArray(v.enumValues)
158
+ // ) {
159
+ // let values: any = v.enumValues;
160
+ // const keys = Object.keys(values).filter(k => !/^\d+$/.test(k));
161
+ // values = keys.reduce((a, k) => {
162
+ // if (values[k] != null) a.push(values[k]);
163
+ // return a;
164
+ // // v => !(typeof v === 'number' && !keys.includes(String(v))),
165
+ // }, [] as any[]);
166
+ // v.enumValues = values;
167
+ // }
168
+ // }
169
+ // }
170
+ //
171
+ // componentRec = {
172
+ // package: packageName,
173
+ // ctor,
174
+ // metadata,
175
+ // };
176
+ // components.set(metadata.className, componentRec);
177
+ // }
178
+ //
179
+ // export async function registerProcessor(ctor: Type, packageName: string) {
180
+ // const _metadata: ProcessorMetadata = Reflect.getMetadata(
181
+ // PROCESSOR_OPTIONS,
182
+ // ctor,
183
+ // );
184
+ // if (!_metadata)
185
+ // throw new TypeError(`Class "${ctor.name}" has no processor metadata.`);
186
+ // if (_metadata.abstract) return;
187
+ // let processorRec = processors.get(_metadata.className);
188
+ // if (processorRec)
189
+ // throw new TypeError(
190
+ // `Processor "${_metadata.className}" already registered by "${processorRec.package}" package`,
191
+ // );
192
+ // let metadata: ComponentMetadata = await resolvePromisesDeep(_metadata);
193
+ // metadata = deepClone({
194
+ // className: metadata.className,
195
+ // displayName: metadata.displayName,
196
+ // description: metadata.description,
197
+ // iconUrl: metadata.iconUrl,
198
+ // author: metadata.author,
199
+ // tags: metadata.tags,
200
+ // abstract: metadata.abstract,
201
+ // variables: metadata.variables,
202
+ // components: metadata.components,
203
+ // ...(metadata as any),
204
+ // });
205
+ // if (metadata.variables) {
206
+ // /** Convert object enumValues to arrays */
207
+ // for (const v of Object.values(metadata.variables)) {
208
+ // if (
209
+ // v.enumValues &&
210
+ // typeof v.enumValues === 'object' &&
211
+ // !Array.isArray(v.enumValues)
212
+ // ) {
213
+ // let values: any = v.enumValues;
214
+ // const keys = Object.keys(values).filter(k => !/^\d+$/.test(k));
215
+ // values = keys.reduce((a, k) => {
216
+ // if (values[k] != null) a.push(values[k]);
217
+ // return a;
218
+ // // v => !(typeof v === 'number' && !keys.includes(String(v))),
219
+ // }, [] as any[]);
220
+ // v.enumValues = values;
221
+ // }
222
+ // }
223
+ // }
224
+ // processorRec = {
225
+ // package: packageName,
226
+ // ctor,
227
+ // metadata,
228
+ // };
229
+ // processors.set(metadata.className, processorRec);
230
+ // }
231
+ // }
232
+ //
233
+ // function locatePkgJson(directory: string): Record<string, any> | undefined {
234
+ // if (directory.startsWith('file:')) 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) return json;
240
+ // }
241
+ // directory = path.dirname(directory);
242
+ // }
243
+ // }
244
+ //
245
+ // async function resolvePromisesDeep(obj: any) {
246
+ // obj = await obj;
247
+ // if (obj && isPlainObject(obj)) {
248
+ // for (const k of Object.keys(obj)) {
249
+ // obj[k] = await resolvePromisesDeep(obj[k]);
250
+ // }
251
+ // }
252
+ // return obj;
253
+ // }
254
+ //
255
+ // export namespace ExtensionRegistry {
256
+ // export interface ExtensionPackageRecord {
257
+ // name: string;
258
+ // description?: string;
259
+ // version: string;
260
+ // }
261
+ //
262
+ // export interface ComponentRecord {
263
+ // package: string;
264
+ // ctor: Type<ComponentBase>;
265
+ // metadata: ComponentMetadata;
266
+ // }
267
+ //
268
+ // export interface ProcessorRecord {
269
+ // package: string;
270
+ // ctor: Type<ProcessorBase>;
271
+ // metadata: ProcessorMetadata;
272
+ // }
273
+ // }
@@ -1,7 +1,7 @@
1
1
  import { clone, merge, omitUndefined } from '@jsopen/objects';
2
2
  import { SbError } from '../classes/sb-error.js';
3
3
  import { StackExecutor } from '../classes/stack-executor.js';
4
- import { ExtensionRegistry } from '../registry.js';
4
+ import { ExtensionRegistry } from '../registry/extension-registry.js';
5
5
  export function materializeMetadata(profile) {
6
6
  const { metadata, issues } = materializeMetadataSilent(profile);
7
7
  if (issues?.length) {
@@ -0,0 +1 @@
1
+ export declare function resolvePromisesDeep(obj: any): Promise<any>;
@@ -0,0 +1,10 @@
1
+ import { isPlainObject } from '@jsopen/objects';
2
+ export async function resolvePromisesDeep(obj) {
3
+ obj = await obj;
4
+ if (obj && isPlainObject(obj)) {
5
+ for (const k of Object.keys(obj)) {
6
+ obj[k] = await resolvePromisesDeep(obj[k]);
7
+ }
8
+ }
9
+ return obj;
10
+ }
@@ -1,6 +0,0 @@
1
- import type { Type } from 'ts-gems';
2
- export interface IExtensionPackage {
3
- components: Type[];
4
- processors: Type[];
5
- dependencies?: string[];
6
- }
@@ -1 +0,0 @@
1
- export {};
package/registry.d.ts DELETED
@@ -1,32 +0,0 @@
1
- import { Type } from 'ts-gems';
2
- import type { ComponentBase } from './classes/component-base.js';
3
- import type { ProcessorBase } from './classes/processor-base.js';
4
- import type { ComponentMetadata, ProcessorMetadata } from './models/index.js';
5
- export declare namespace ExtensionRegistry {
6
- const packages: Map<string, ExtensionPackageRecord>;
7
- const components: Map<string, ComponentRecord>;
8
- const processors: Map<string, ProcessorRecord>;
9
- function setResolver(resolver: (name: string) => string): void;
10
- function getProcessor(className: string): ExtensionRegistry.ProcessorRecord;
11
- function getComponent(className: string): ExtensionRegistry.ComponentRecord;
12
- function registerPackage(...specifiers: string[]): Promise<void>;
13
- function registerComponent(ctor: Type, packageName: string): Promise<void>;
14
- function registerProcessor(ctor: Type, packageName: string): Promise<void>;
15
- }
16
- export declare namespace ExtensionRegistry {
17
- interface ExtensionPackageRecord {
18
- name: string;
19
- description?: string;
20
- version: string;
21
- }
22
- interface ComponentRecord {
23
- package: string;
24
- ctor: Type<ComponentBase>;
25
- metadata: ComponentMetadata;
26
- }
27
- interface ProcessorRecord {
28
- package: string;
29
- ctor: Type<ProcessorBase>;
30
- metadata: ProcessorMetadata;
31
- }
32
- }