@syncbridge/common 2.0.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/constants.d.ts +1 -1
- package/constants.js +1 -1
- package/host-link/host-link.d.ts +2 -0
- package/host-link/host-link.js +2 -0
- package/host-link/host-permissions.d.ts +44 -0
- package/host-link/host-permissions.js +66 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/models/metadata/variable-metadata.d.ts +3 -2
- package/models/metadata/variable-metadata.js +6 -4
- package/package.json +1 -1
- package/registry/docs-sidebar.d.ts +2 -1
- package/registry/localized-text.d.ts +28 -0
- package/registry/localized-text.js +49 -0
- package/registry/module-catalog.d.ts +2 -1
package/README.md
CHANGED
|
@@ -117,7 +117,7 @@ property's TypeScript type when not given. Some options:
|
|
|
117
117
|
|
|
118
118
|
| Option | Meaning |
|
|
119
119
|
| --- | --- |
|
|
120
|
-
| `label`, `description` | How it is shown |
|
|
120
|
+
| `label`, `description` | How it is shown: text, or text by language - `{ en: 'Port', tr: 'Bağlantı noktası' }` - shown in the reader's language in the server's UI and the Marketplace, else in English |
|
|
121
121
|
| `type` | `VariableType`: `String`, `Secret` (a password or key, kept encrypted in the profile), `Number`, `BigInt`, `Boolean`, `Enum`, `Nested` |
|
|
122
122
|
| `default`, `required` | Its default value, and whether it must be given |
|
|
123
123
|
| `enumValues` | The values of an enum |
|
package/constants.d.ts
CHANGED
package/constants.js
CHANGED
package/host-link/host-link.d.ts
CHANGED
|
@@ -41,3 +41,5 @@ export type HostLinkMessage = HostStatusMessage;
|
|
|
41
41
|
export declare const CONSOLE_USER_HEADER = "x-sb-console-user";
|
|
42
42
|
export declare const CONSOLE_USER_NAME_HEADER = "x-sb-console-user-name";
|
|
43
43
|
export declare const CONSOLE_ROLE_HEADER = "x-sb-console-role";
|
|
44
|
+
/** What the user may do inside the host: HostPermission values, comma-separated */
|
|
45
|
+
export declare const CONSOLE_PERMISSIONS_HEADER = "x-sb-console-permissions";
|
package/host-link/host-link.js
CHANGED
|
@@ -51,3 +51,5 @@ export function summarizeWorkers(workers) {
|
|
|
51
51
|
export const CONSOLE_USER_HEADER = 'x-sb-console-user';
|
|
52
52
|
export const CONSOLE_USER_NAME_HEADER = 'x-sb-console-user-name';
|
|
53
53
|
export const CONSOLE_ROLE_HEADER = 'x-sb-console-role';
|
|
54
|
+
/** What the user may do inside the host: HostPermission values, comma-separated */
|
|
55
|
+
export const CONSOLE_PERMISSIONS_HEADER = 'x-sb-console-permissions';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a user may do inside a host. Console grants them to an
|
|
3
|
+
* organization's members and passes them on with each request
|
|
4
|
+
* (CONSOLE_PERMISSIONS_HEADER); the host's own users have their role's.
|
|
5
|
+
*/
|
|
6
|
+
export declare enum HostPermission {
|
|
7
|
+
/** Seeing the workers, their logs and configuration, and the settings */
|
|
8
|
+
WorkersView = "host.workers.view",
|
|
9
|
+
/** Starting, stopping and initializing workers */
|
|
10
|
+
WorkersControl = "host.workers.control",
|
|
11
|
+
/** Changing a worker's configuration and its log channels */
|
|
12
|
+
WorkersConfigure = "host.workers.configure",
|
|
13
|
+
/** Adding workers */
|
|
14
|
+
WorkersCreate = "host.workers.create",
|
|
15
|
+
/** Removing workers */
|
|
16
|
+
WorkersDelete = "host.workers.delete",
|
|
17
|
+
/** Changing the host's settings, uploading packages */
|
|
18
|
+
Settings = "host.settings",
|
|
19
|
+
/** Updating SyncBridge */
|
|
20
|
+
Updates = "host.updates",
|
|
21
|
+
/** The host's own users */
|
|
22
|
+
Users = "host.users",
|
|
23
|
+
/** Pairing with Console, restoring, restarting SyncBridge */
|
|
24
|
+
System = "host.system",
|
|
25
|
+
/**
|
|
26
|
+
* Installing packages from the registry: Console's own permission, sent
|
|
27
|
+
* with its installs
|
|
28
|
+
*/
|
|
29
|
+
Install = "hosts.install"
|
|
30
|
+
}
|
|
31
|
+
/** The roles inside a host, each a set of permissions */
|
|
32
|
+
export type HostRole = 'viewer' | 'operator' | 'admin';
|
|
33
|
+
/**
|
|
34
|
+
* The permissions of each role: a host's own users', and a user's whose
|
|
35
|
+
* Console sends a role alone (one older than the permissions)
|
|
36
|
+
*/
|
|
37
|
+
export declare const HOST_ROLE_PERMISSIONS: Readonly<Record<HostRole, readonly HostPermission[]>>;
|
|
38
|
+
/** The permissions of a role; none for a role not known */
|
|
39
|
+
export declare function hostRolePermissions(role: string | undefined | null): HostPermission[];
|
|
40
|
+
/**
|
|
41
|
+
* The permissions a CONSOLE_PERMISSIONS_HEADER value gives: comma-separated,
|
|
42
|
+
* those not known dropped. No header, undefined: the role's to be taken.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseHostPermissions(value: string | undefined | null): HostPermission[] | undefined;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a user may do inside a host. Console grants them to an
|
|
3
|
+
* organization's members and passes them on with each request
|
|
4
|
+
* (CONSOLE_PERMISSIONS_HEADER); the host's own users have their role's.
|
|
5
|
+
*/
|
|
6
|
+
export var HostPermission;
|
|
7
|
+
(function (HostPermission) {
|
|
8
|
+
/** Seeing the workers, their logs and configuration, and the settings */
|
|
9
|
+
HostPermission["WorkersView"] = "host.workers.view";
|
|
10
|
+
/** Starting, stopping and initializing workers */
|
|
11
|
+
HostPermission["WorkersControl"] = "host.workers.control";
|
|
12
|
+
/** Changing a worker's configuration and its log channels */
|
|
13
|
+
HostPermission["WorkersConfigure"] = "host.workers.configure";
|
|
14
|
+
/** Adding workers */
|
|
15
|
+
HostPermission["WorkersCreate"] = "host.workers.create";
|
|
16
|
+
/** Removing workers */
|
|
17
|
+
HostPermission["WorkersDelete"] = "host.workers.delete";
|
|
18
|
+
/** Changing the host's settings, uploading packages */
|
|
19
|
+
HostPermission["Settings"] = "host.settings";
|
|
20
|
+
/** Updating SyncBridge */
|
|
21
|
+
HostPermission["Updates"] = "host.updates";
|
|
22
|
+
/** The host's own users */
|
|
23
|
+
HostPermission["Users"] = "host.users";
|
|
24
|
+
/** Pairing with Console, restoring, restarting SyncBridge */
|
|
25
|
+
HostPermission["System"] = "host.system";
|
|
26
|
+
/**
|
|
27
|
+
* Installing packages from the registry: Console's own permission, sent
|
|
28
|
+
* with its installs
|
|
29
|
+
*/
|
|
30
|
+
HostPermission["Install"] = "hosts.install";
|
|
31
|
+
})(HostPermission || (HostPermission = {}));
|
|
32
|
+
const VIEWER = [HostPermission.WorkersView];
|
|
33
|
+
const OPERATOR = [
|
|
34
|
+
...VIEWER,
|
|
35
|
+
HostPermission.WorkersControl,
|
|
36
|
+
HostPermission.WorkersConfigure,
|
|
37
|
+
HostPermission.WorkersCreate,
|
|
38
|
+
HostPermission.Install,
|
|
39
|
+
];
|
|
40
|
+
/**
|
|
41
|
+
* The permissions of each role: a host's own users', and a user's whose
|
|
42
|
+
* Console sends a role alone (one older than the permissions)
|
|
43
|
+
*/
|
|
44
|
+
export const HOST_ROLE_PERMISSIONS = {
|
|
45
|
+
viewer: VIEWER,
|
|
46
|
+
operator: OPERATOR,
|
|
47
|
+
admin: Object.values(HostPermission),
|
|
48
|
+
};
|
|
49
|
+
const KNOWN = new Set(Object.values(HostPermission));
|
|
50
|
+
/** The permissions of a role; none for a role not known */
|
|
51
|
+
export function hostRolePermissions(role) {
|
|
52
|
+
return [...(HOST_ROLE_PERMISSIONS[role] || [])];
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The permissions a CONSOLE_PERMISSIONS_HEADER value gives: comma-separated,
|
|
56
|
+
* those not known dropped. No header, undefined: the role's to be taken.
|
|
57
|
+
*/
|
|
58
|
+
export function parseHostPermissions(value) {
|
|
59
|
+
if (value == null)
|
|
60
|
+
return;
|
|
61
|
+
const given = value
|
|
62
|
+
.split(',')
|
|
63
|
+
.map(s => s.trim())
|
|
64
|
+
.filter(s => KNOWN.has(s));
|
|
65
|
+
return [...new Set(given)];
|
|
66
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export * from './decorators/log-channel.decorator.js';
|
|
|
16
16
|
export * from './host-link/host-identity.js';
|
|
17
17
|
export * from './host-link/host-link.js';
|
|
18
18
|
export * from './host-link/host-packages.js';
|
|
19
|
+
export * from './host-link/host-permissions.js';
|
|
19
20
|
export * from './host-link/host-workers.js';
|
|
20
21
|
export * from './host-link/multiplexer.js';
|
|
21
22
|
export * from './host-link/sealed-box.js';
|
|
@@ -26,6 +27,7 @@ export * from './models-document.js';
|
|
|
26
27
|
export * from './registry/docs-sidebar.js';
|
|
27
28
|
export * from './registry/extension-package.js';
|
|
28
29
|
export * from './registry/extension-registry.js';
|
|
30
|
+
export * from './registry/localized-text.js';
|
|
29
31
|
export * from './registry/module-catalog.js';
|
|
30
32
|
export * from './registry/package-docs.js';
|
|
31
33
|
export * from './registry/package-manifest.js';
|
package/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export * from './decorators/log-channel.decorator.js';
|
|
|
16
16
|
export * from './host-link/host-identity.js';
|
|
17
17
|
export * from './host-link/host-link.js';
|
|
18
18
|
export * from './host-link/host-packages.js';
|
|
19
|
+
export * from './host-link/host-permissions.js';
|
|
19
20
|
export * from './host-link/host-workers.js';
|
|
20
21
|
export * from './host-link/multiplexer.js';
|
|
21
22
|
export * from './host-link/sealed-box.js';
|
|
@@ -26,6 +27,7 @@ export * from './models-document.js';
|
|
|
26
27
|
export * from './registry/docs-sidebar.js';
|
|
27
28
|
export * from './registry/extension-package.js';
|
|
28
29
|
export * from './registry/extension-registry.js';
|
|
30
|
+
export * from './registry/localized-text.js';
|
|
29
31
|
export * from './registry/module-catalog.js';
|
|
30
32
|
export * from './registry/package-docs.js';
|
|
31
33
|
export * from './registry/package-manifest.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LocalizedText } from '../../registry/localized-text.js';
|
|
1
2
|
import { EnumSource } from '../enums/enum-source.enum.js';
|
|
2
3
|
import { VariableFormat } from '../enums/variable-format.enum.js';
|
|
3
4
|
import { VariableType } from '../enums/variable-type.enum.js';
|
|
@@ -14,8 +15,8 @@ export declare class VariableMetadata {
|
|
|
14
15
|
ignored?: boolean;
|
|
15
16
|
index?: number;
|
|
16
17
|
hotPlug?: boolean;
|
|
17
|
-
label?:
|
|
18
|
-
description?:
|
|
18
|
+
label?: LocalizedText;
|
|
19
|
+
description?: LocalizedText;
|
|
19
20
|
examples?: string[];
|
|
20
21
|
choice?: string[];
|
|
21
22
|
type?: VariableType;
|
|
@@ -36,15 +36,17 @@ __decorate([
|
|
|
36
36
|
], VariableMetadata.prototype, "hotPlug", void 0);
|
|
37
37
|
__decorate([
|
|
38
38
|
ApiField({
|
|
39
|
-
description: '
|
|
39
|
+
description: "Its label: text, or text by language ({ en: '...', tr: '...' }) - shown in the server's UI and the Marketplace in the reader's language",
|
|
40
|
+
type: 'any',
|
|
40
41
|
}),
|
|
41
|
-
__metadata("design:type",
|
|
42
|
+
__metadata("design:type", Object)
|
|
42
43
|
], VariableMetadata.prototype, "label", void 0);
|
|
43
44
|
__decorate([
|
|
44
45
|
ApiField({
|
|
45
|
-
description: '
|
|
46
|
+
description: "What it is for: text, or text by language ({ en: '...', tr: '...' })",
|
|
47
|
+
type: 'any',
|
|
46
48
|
}),
|
|
47
|
-
__metadata("design:type",
|
|
49
|
+
__metadata("design:type", Object)
|
|
48
50
|
], VariableMetadata.prototype, "description", void 0);
|
|
49
51
|
__decorate([
|
|
50
52
|
ApiField({
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { LocalizedText } from './localized-text.js';
|
|
1
2
|
/**
|
|
2
3
|
* How a package's documents are listed, where its author tells it: a
|
|
3
4
|
* sidebar.json in docs/ (the package's own) or in docs/<ClassName>/ (an
|
|
@@ -21,7 +22,7 @@
|
|
|
21
22
|
*/
|
|
22
23
|
export declare const SIDEBAR_FILE = "sidebar.json";
|
|
23
24
|
/** Text, or text by language: { "tr": "Ağ", "en": "Network" } */
|
|
24
|
-
export type SidebarText =
|
|
25
|
+
export type SidebarText = LocalizedText;
|
|
25
26
|
/** An item of a sidebar, as its author writes it */
|
|
26
27
|
export type SidebarItemSource = string | {
|
|
27
28
|
doc: string;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Text, or text by language: { en: 'Port number', tr: 'Port numarası' }.
|
|
3
|
+
* A text alone is in the package's docs language.
|
|
4
|
+
*/
|
|
5
|
+
export type LocalizedText = string | Record<string, string>;
|
|
6
|
+
/**
|
|
7
|
+
* A text in the language asked for: else in its base language ("pt" for
|
|
8
|
+
* "pt-BR"), else in English, else the first told; a text alone as it is
|
|
9
|
+
*/
|
|
10
|
+
export declare function textIn(text: LocalizedText | undefined, language: string): string | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* What is wrong with a text told by language: a key not a language, a
|
|
13
|
+
* text empty; a text alone, or none, is right
|
|
14
|
+
*/
|
|
15
|
+
export declare function localizedTextProblems(text: unknown, what: string): string[];
|
|
16
|
+
/** The settings of a definition: those of a group under it too */
|
|
17
|
+
interface VariableTexts {
|
|
18
|
+
label?: unknown;
|
|
19
|
+
description?: unknown;
|
|
20
|
+
variables?: Record<string, VariableTexts>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* What is wrong with the labels and descriptions of an app's, a
|
|
24
|
+
* component's or a plugin's settings, those in groups too: each by its
|
|
25
|
+
* path ("ClassName's tls.cert label")
|
|
26
|
+
*/
|
|
27
|
+
export declare function variableTextProblems(variables: Record<string, VariableTexts> | undefined, owner: string, at?: string): string[];
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { isDocsLanguage } from './package-docs.js';
|
|
2
|
+
/**
|
|
3
|
+
* A text in the language asked for: else in its base language ("pt" for
|
|
4
|
+
* "pt-BR"), else in English, else the first told; a text alone as it is
|
|
5
|
+
*/
|
|
6
|
+
export function textIn(text, language) {
|
|
7
|
+
if (text === undefined || typeof text === 'string')
|
|
8
|
+
return text;
|
|
9
|
+
return (text[language] ??
|
|
10
|
+
text[language.split('-')[0]] ??
|
|
11
|
+
text.en ??
|
|
12
|
+
Object.values(text)[0]);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* What is wrong with a text told by language: a key not a language, a
|
|
16
|
+
* text empty; a text alone, or none, is right
|
|
17
|
+
*/
|
|
18
|
+
export function localizedTextProblems(text, what) {
|
|
19
|
+
if (text === undefined || (typeof text === 'string' && text.trim()))
|
|
20
|
+
return [];
|
|
21
|
+
if (!text || typeof text !== 'object' || Array.isArray(text))
|
|
22
|
+
return [`${what} is text, or text by language: { en: '...', tr: '...' }`];
|
|
23
|
+
const entries = Object.entries(text);
|
|
24
|
+
if (!entries.length)
|
|
25
|
+
return [`${what} is text, or text by language: { en: '...', tr: '...' }`];
|
|
26
|
+
const problems = [];
|
|
27
|
+
for (const [language, value] of entries) {
|
|
28
|
+
if (!isDocsLanguage(language))
|
|
29
|
+
problems.push(`${what} is told in "${language}", not a language: en, tr, pt-BR...`);
|
|
30
|
+
else if (typeof value !== 'string' || !value.trim())
|
|
31
|
+
problems.push(`${what} in ${language} is empty`);
|
|
32
|
+
}
|
|
33
|
+
return problems;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* What is wrong with the labels and descriptions of an app's, a
|
|
37
|
+
* component's or a plugin's settings, those in groups too: each by its
|
|
38
|
+
* path ("ClassName's tls.cert label")
|
|
39
|
+
*/
|
|
40
|
+
export function variableTextProblems(variables, owner, at = '') {
|
|
41
|
+
const problems = [];
|
|
42
|
+
for (const [key, v] of Object.entries(variables ?? {})) {
|
|
43
|
+
if (!v || typeof v !== 'object')
|
|
44
|
+
continue;
|
|
45
|
+
const path = at + key;
|
|
46
|
+
problems.push(...localizedTextProblems(v.label, `${owner}'s ${path} label`), ...localizedTextProblems(v.description, `${owner}'s ${path} description`), ...variableTextProblems(v.variables, owner, `${path}.`));
|
|
47
|
+
}
|
|
48
|
+
return problems;
|
|
49
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { LocalizedText } from './localized-text.js';
|
|
1
2
|
export declare const SUMMARY_MAX_LENGTH = 160;
|
|
2
3
|
export declare const SCREENSHOTS_MAX = 8;
|
|
3
4
|
/** A summary as told: one in the package's docs language, or one per language */
|
|
4
|
-
export type ModuleSummary =
|
|
5
|
+
export type ModuleSummary = LocalizedText;
|
|
5
6
|
/** What the Marketplace is told of a module, as its makers wrote it */
|
|
6
7
|
export interface ModuleCatalogInput {
|
|
7
8
|
className: string;
|