@phis/contracts 0.4.0 → 0.6.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 +23 -5
- package/dist/addon-index.d.ts +1 -0
- package/dist/addon-index.js +1 -0
- package/dist/addon.d.ts +3 -1
- package/dist/capabilities.d.ts +30 -13
- package/dist/catalog.d.ts +14 -0
- package/dist/catalog.js +14 -2
- package/dist/cms.d.ts +34 -1
- package/dist/cms.js +52 -1
- package/dist/conditions.d.ts +96 -0
- package/dist/conditions.js +163 -0
- package/dist/controls.d.ts +91 -0
- package/dist/controls.js +134 -0
- package/dist/core.d.ts +17 -1
- package/dist/core.js +17 -0
- package/dist/forms.d.ts +496 -0
- package/dist/forms.js +508 -0
- package/dist/http.d.ts +10 -1
- package/dist/http.js +10 -1
- package/dist/layout.d.ts +22 -0
- package/dist/layout.js +30 -0
- package/dist/payments.d.ts +274 -0
- package/dist/payments.js +8 -0
- package/dist/record.d.ts +8 -0
- package/dist/record.js +24 -0
- package/dist/references.d.ts +139 -0
- package/dist/references.js +241 -0
- package/dist/resource-links.d.ts +13 -7
- package/dist/schema.d.ts +9 -0
- package/dist/signals.d.ts +1 -0
- package/dist/signals.js +3 -0
- package/dist/support.d.ts +184 -0
- package/dist/support.js +11 -0
- package/dist/threads.d.ts +29 -0
- package/dist/timeline.d.ts +39 -0
- package/dist/timeline.js +53 -0
- package/package.json +37 -2
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a choice control offers, and where it asks for its choices when they are not written out.
|
|
3
|
+
*
|
|
4
|
+
* Here because stored descriptors carry both: a Form field lists its options or names the provider
|
|
5
|
+
* that answers for them, and phis-server reads that field as it is stored.
|
|
6
|
+
*/
|
|
7
|
+
export type PhiRuntimeDataProviderKey = `${string}/${string}`;
|
|
8
|
+
/**
|
|
9
|
+
* `<namespace>/<name>`: an identifier that says whose it is.
|
|
10
|
+
*
|
|
11
|
+
* Provider keys, item renderer keys and everything else a Module may contribute to a shared registry
|
|
12
|
+
* share this shape, so they share one check. A second spelling of it is the one that drifts.
|
|
13
|
+
*/
|
|
14
|
+
export declare function isPhiNamespacedRuntimeKey(value: unknown): value is `${string}/${string}`;
|
|
15
|
+
export declare function isPhiRuntimeDataProviderKey(value: unknown): value is PhiRuntimeDataProviderKey;
|
|
16
|
+
export type PhiControlOption<TValue extends string | number = string> = {
|
|
17
|
+
value: TValue;
|
|
18
|
+
label: string;
|
|
19
|
+
disabled?: boolean;
|
|
20
|
+
description?: string;
|
|
21
|
+
icon?: string;
|
|
22
|
+
preview?: PhiControlOptionPreview;
|
|
23
|
+
/**
|
|
24
|
+
* The heading this option is listed under, where the Control can group -- a Select shows consecutive
|
|
25
|
+
* options with the same group under one heading. A Control that cannot group lists the options as they
|
|
26
|
+
* come, so the order has to make sense without the headings.
|
|
27
|
+
*/
|
|
28
|
+
group?: string;
|
|
29
|
+
/**
|
|
30
|
+
* A line drawn between this option and the one before or after it, where the Control can draw one --
|
|
31
|
+
* a Select does, in its menu. It sets an option apart from the rest without a heading to name it: the
|
|
32
|
+
* Button's "Custom" above the actions it is not one of. A Control that cannot draw it lists the
|
|
33
|
+
* options as they come.
|
|
34
|
+
*/
|
|
35
|
+
separator?: PhiControlOptionSeparator;
|
|
36
|
+
};
|
|
37
|
+
export type PhiControlOptionSeparator = "before" | "after";
|
|
38
|
+
export type PhiControlOptionPreview = PhiControlOptionBackgroundPreview | PhiControlOptionFontPreview;
|
|
39
|
+
/**
|
|
40
|
+
* The option's label set in the typeface it names, so a list of fonts shows the fonts.
|
|
41
|
+
*
|
|
42
|
+
* `fontFamily` is a complete `font-family` value -- a family, its fallback, a generic -- because the
|
|
43
|
+
* option is drawn in a popup outside the page's root, where a variable that names a font is not in
|
|
44
|
+
* scope. Whoever builds the option resolves the variable first.
|
|
45
|
+
*/
|
|
46
|
+
export type PhiControlOptionFontPreview = {
|
|
47
|
+
kind: "font";
|
|
48
|
+
fontFamily: string;
|
|
49
|
+
};
|
|
50
|
+
export type PhiControlOptionBackgroundPreview = {
|
|
51
|
+
kind: "background";
|
|
52
|
+
backgroundColor?: string;
|
|
53
|
+
backgroundImage?: string;
|
|
54
|
+
backgroundSize?: string;
|
|
55
|
+
backgroundPosition?: string;
|
|
56
|
+
backgroundRepeat?: string;
|
|
57
|
+
};
|
|
58
|
+
export type PhiControlOptionsProviderLoadMode = "client" | "server" | "hybrid";
|
|
59
|
+
export type PhiControlOptionsProviderSearchConfig = {
|
|
60
|
+
enabled?: boolean;
|
|
61
|
+
minChars?: number;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* A value this provider needs that another field holds.
|
|
65
|
+
*
|
|
66
|
+
* `source` and `valuePath` are the vocabulary conditions already use, so "the value of a sibling field"
|
|
67
|
+
* is said the same way everywhere. `form` reads the live form values; `config` reads the field or Widget
|
|
68
|
+
* configuration the control was built from, which is what an Inspector has instead of a form.
|
|
69
|
+
*
|
|
70
|
+
* `required` is the difference between narrowing a list and having no list: a provider whose answer is
|
|
71
|
+
* meaningless without the parent value is not asked at all until it has one, rather than answering with
|
|
72
|
+
* everything and looking as if the dependency were ignored.
|
|
73
|
+
*/
|
|
74
|
+
export type PhiControlOptionsProviderDependency = {
|
|
75
|
+
/** The name the provider reads this value under. */
|
|
76
|
+
param: string;
|
|
77
|
+
source: "form" | "config";
|
|
78
|
+
valuePath: string;
|
|
79
|
+
required?: boolean;
|
|
80
|
+
};
|
|
81
|
+
export type PhiControlOptionsProviderConfig = {
|
|
82
|
+
providerKey: PhiRuntimeDataProviderKey;
|
|
83
|
+
scopeKey?: string;
|
|
84
|
+
area?: string;
|
|
85
|
+
params?: Record<string, unknown>;
|
|
86
|
+
loadMode?: PhiControlOptionsProviderLoadMode;
|
|
87
|
+
search?: PhiControlOptionsProviderSearchConfig;
|
|
88
|
+
dependencies?: readonly PhiControlOptionsProviderDependency[];
|
|
89
|
+
};
|
|
90
|
+
export declare function parsePhiControlOptionsProviderConfig(value: unknown): PhiControlOptionsProviderConfig | null;
|
|
91
|
+
export declare function readPhiControlOptions(value: unknown): PhiControlOption[];
|
package/dist/controls.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a choice control offers, and where it asks for its choices when they are not written out.
|
|
3
|
+
*
|
|
4
|
+
* Here because stored descriptors carry both: a Form field lists its options or names the provider
|
|
5
|
+
* that answers for them, and phis-server reads that field as it is stored.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* `<namespace>/<name>`: an identifier that says whose it is.
|
|
9
|
+
*
|
|
10
|
+
* Provider keys, item renderer keys and everything else a Module may contribute to a shared registry
|
|
11
|
+
* share this shape, so they share one check. A second spelling of it is the one that drifts.
|
|
12
|
+
*/
|
|
13
|
+
export function isPhiNamespacedRuntimeKey(value) {
|
|
14
|
+
if (typeof value !== "string") {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const separatorIndex = value.lastIndexOf("/");
|
|
18
|
+
return separatorIndex > 0 && separatorIndex < value.length - 1;
|
|
19
|
+
}
|
|
20
|
+
export function isPhiRuntimeDataProviderKey(value) {
|
|
21
|
+
return isPhiNamespacedRuntimeKey(value);
|
|
22
|
+
}
|
|
23
|
+
function readString(value) {
|
|
24
|
+
return typeof value === "string" && value.trim().length > 0
|
|
25
|
+
? value.trim()
|
|
26
|
+
: undefined;
|
|
27
|
+
}
|
|
28
|
+
function readRecord(value) {
|
|
29
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
30
|
+
}
|
|
31
|
+
function readLoadMode(value) {
|
|
32
|
+
return value === "client" || value === "server" || value === "hybrid" ? value : undefined;
|
|
33
|
+
}
|
|
34
|
+
function readSearchConfig(value) {
|
|
35
|
+
const record = readRecord(value);
|
|
36
|
+
if (!record) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const enabled = typeof record.enabled === "boolean" ? record.enabled : undefined;
|
|
40
|
+
const minChars = typeof record.minChars === "number" && Number.isFinite(record.minChars)
|
|
41
|
+
? Math.max(0, Math.trunc(record.minChars))
|
|
42
|
+
: undefined;
|
|
43
|
+
if (enabled === undefined && minChars === undefined) {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
enabled,
|
|
48
|
+
minChars,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function readDependencies(value) {
|
|
52
|
+
if (!Array.isArray(value)) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const dependencies = value.flatMap((entry) => {
|
|
56
|
+
const record = readRecord(entry);
|
|
57
|
+
const param = readString(record?.param);
|
|
58
|
+
const valuePath = readString(record?.valuePath);
|
|
59
|
+
const source = record?.source === "form" || record?.source === "config" ? record.source : undefined;
|
|
60
|
+
if (!param || !valuePath || !source) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
return [{
|
|
64
|
+
param,
|
|
65
|
+
source,
|
|
66
|
+
valuePath,
|
|
67
|
+
required: record?.required === true ? true : undefined,
|
|
68
|
+
}];
|
|
69
|
+
});
|
|
70
|
+
return dependencies.length > 0 ? dependencies : undefined;
|
|
71
|
+
}
|
|
72
|
+
function readOptionPreview(value) {
|
|
73
|
+
const record = readRecord(value);
|
|
74
|
+
if (record?.kind === "font") {
|
|
75
|
+
const fontFamily = readString(record.fontFamily);
|
|
76
|
+
return fontFamily ? { kind: "font", fontFamily } : undefined;
|
|
77
|
+
}
|
|
78
|
+
if (record?.kind !== "background")
|
|
79
|
+
return undefined;
|
|
80
|
+
return {
|
|
81
|
+
kind: "background",
|
|
82
|
+
backgroundColor: readString(record.backgroundColor),
|
|
83
|
+
backgroundImage: readString(record.backgroundImage),
|
|
84
|
+
backgroundSize: readString(record.backgroundSize),
|
|
85
|
+
backgroundPosition: readString(record.backgroundPosition),
|
|
86
|
+
backgroundRepeat: readString(record.backgroundRepeat),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
export function parsePhiControlOptionsProviderConfig(value) {
|
|
90
|
+
const record = readRecord(value);
|
|
91
|
+
if (!record) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const providerKey = readString(record.providerKey);
|
|
95
|
+
if (!isPhiRuntimeDataProviderKey(providerKey)) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
providerKey,
|
|
100
|
+
scopeKey: readString(record.scopeKey),
|
|
101
|
+
area: readString(record.area),
|
|
102
|
+
params: readRecord(record.params),
|
|
103
|
+
loadMode: readLoadMode(record.loadMode),
|
|
104
|
+
search: readSearchConfig(record.search),
|
|
105
|
+
dependencies: readDependencies(record.dependencies),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
export function readPhiControlOptions(value) {
|
|
109
|
+
if (Array.isArray(value)) {
|
|
110
|
+
return value
|
|
111
|
+
.map((item) => {
|
|
112
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
const record = item;
|
|
116
|
+
const optionValue = readString(record.value);
|
|
117
|
+
if (!optionValue) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
value: optionValue,
|
|
122
|
+
label: readString(record.label) ?? optionValue,
|
|
123
|
+
disabled: typeof record.disabled === "boolean" ? record.disabled : undefined,
|
|
124
|
+
description: readString(record.description),
|
|
125
|
+
icon: readString(record.icon),
|
|
126
|
+
preview: readOptionPreview(record.preview),
|
|
127
|
+
group: readString(record.group),
|
|
128
|
+
separator: record.separator === "before" || record.separator === "after" ? record.separator : undefined,
|
|
129
|
+
};
|
|
130
|
+
})
|
|
131
|
+
.filter((item) => item != null);
|
|
132
|
+
}
|
|
133
|
+
return [];
|
|
134
|
+
}
|
package/dist/core.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { PhisPaymentChangedEventFacts } from "./payments.js";
|
|
1
2
|
/**
|
|
2
3
|
* What Core offers, named once so both sides can spell it the same way.
|
|
3
4
|
*
|
|
@@ -45,6 +46,8 @@ export declare const PHIS_CORE_CAPABILITIES: {
|
|
|
45
46
|
readonly settings: "@phis/server/settings:v1";
|
|
46
47
|
/** Whether the acting user holds one of this Add-on's own declared roles. */
|
|
47
48
|
readonly roles: "@phis/server/roles:v1";
|
|
49
|
+
readonly payments: "@phis/server/payments:v1";
|
|
50
|
+
readonly paymentNotifications: "@phis/server/payment-notifications:v1";
|
|
48
51
|
};
|
|
49
52
|
export type PhisCoreCapabilityId = (typeof PHIS_CORE_CAPABILITIES)[keyof typeof PHIS_CORE_CAPABILITIES];
|
|
50
53
|
/**
|
|
@@ -67,8 +70,11 @@ export declare const PHIS_ADDON_EVENTS: {
|
|
|
67
70
|
readonly threadStatusChanged: "thread.status.changed";
|
|
68
71
|
/** The link itself is gone; what follows from that is the Add-on's own business. */
|
|
69
72
|
readonly threadLinkRemoved: "thread.link.removed";
|
|
73
|
+
readonly paymentChanged: "payment.changed";
|
|
70
74
|
};
|
|
71
|
-
export type
|
|
75
|
+
export type PhisAddonThreadEventId = Exclude<(typeof PHIS_ADDON_EVENTS)[keyof typeof PHIS_ADDON_EVENTS], "payment.changed">;
|
|
76
|
+
/** Delivered v1 event vocabulary, discriminated by its owned subject. */
|
|
77
|
+
export type PhisAddonEventId = PhisAddonThreadEventId | PhisPaymentChangedEventFacts["event"];
|
|
72
78
|
/**
|
|
73
79
|
* The Core-owned service kinds an Add-on may implement.
|
|
74
80
|
*
|
|
@@ -78,6 +84,7 @@ export type PhisAddonEventId = (typeof PHIS_ADDON_EVENTS)[keyof typeof PHIS_ADDO
|
|
|
78
84
|
*/
|
|
79
85
|
export declare const PHIS_SERVICE_KINDS: {
|
|
80
86
|
readonly mediaStorage: "@phis/server/service/media-storage";
|
|
87
|
+
readonly payments: "@phis/server/service/payments";
|
|
81
88
|
readonly directory: "@phis/server/service/directory";
|
|
82
89
|
/**
|
|
83
90
|
* Turning text in one language into text in another.
|
|
@@ -88,6 +95,15 @@ export declare const PHIS_SERVICE_KINDS: {
|
|
|
88
95
|
* operator selects which one an installation uses.
|
|
89
96
|
*/
|
|
90
97
|
readonly translation: "@phis/server/service/translation";
|
|
98
|
+
/**
|
|
99
|
+
* Handing a Support ticket's work to a system outside the Site -- an issue tracker, a ticket desk.
|
|
100
|
+
*
|
|
101
|
+
* A kind because Core owns the question: which ticket, which task, what may leave and what comes back.
|
|
102
|
+
* What the implementation talks to is its own business, and several may be installed at once; a
|
|
103
|
+
* Supporter chooses one per forward. The interface is `PhisSupportForwardingAdapterV1` in
|
|
104
|
+
* `@phis/contracts/support`.
|
|
105
|
+
*/
|
|
106
|
+
readonly supportForwarding: "@phis/server/service/support-forwarding";
|
|
91
107
|
};
|
|
92
108
|
export type PhisServiceKind = (typeof PHIS_SERVICE_KINDS)[keyof typeof PHIS_SERVICE_KINDS];
|
|
93
109
|
/**
|
package/dist/core.js
CHANGED
|
@@ -45,6 +45,8 @@ export const PHIS_CORE_CAPABILITIES = {
|
|
|
45
45
|
settings: "@phis/server/settings:v1",
|
|
46
46
|
/** Whether the acting user holds one of this Add-on's own declared roles. */
|
|
47
47
|
roles: "@phis/server/roles:v1",
|
|
48
|
+
payments: "@phis/server/payments:v1",
|
|
49
|
+
paymentNotifications: "@phis/server/payment-notifications:v1",
|
|
48
50
|
};
|
|
49
51
|
/**
|
|
50
52
|
* What Core tells an Add-on about after the fact.
|
|
@@ -66,6 +68,7 @@ export const PHIS_ADDON_EVENTS = {
|
|
|
66
68
|
threadStatusChanged: "thread.status.changed",
|
|
67
69
|
/** The link itself is gone; what follows from that is the Add-on's own business. */
|
|
68
70
|
threadLinkRemoved: "thread.link.removed",
|
|
71
|
+
paymentChanged: "payment.changed",
|
|
69
72
|
};
|
|
70
73
|
/**
|
|
71
74
|
* The Core-owned service kinds an Add-on may implement.
|
|
@@ -76,6 +79,7 @@ export const PHIS_ADDON_EVENTS = {
|
|
|
76
79
|
*/
|
|
77
80
|
export const PHIS_SERVICE_KINDS = {
|
|
78
81
|
mediaStorage: "@phis/server/service/media-storage",
|
|
82
|
+
payments: "@phis/server/service/payments",
|
|
79
83
|
directory: "@phis/server/service/directory",
|
|
80
84
|
/**
|
|
81
85
|
* Turning text in one language into text in another.
|
|
@@ -86,6 +90,15 @@ export const PHIS_SERVICE_KINDS = {
|
|
|
86
90
|
* operator selects which one an installation uses.
|
|
87
91
|
*/
|
|
88
92
|
translation: "@phis/server/service/translation",
|
|
93
|
+
/**
|
|
94
|
+
* Handing a Support ticket's work to a system outside the Site -- an issue tracker, a ticket desk.
|
|
95
|
+
*
|
|
96
|
+
* A kind because Core owns the question: which ticket, which task, what may leave and what comes back.
|
|
97
|
+
* What the implementation talks to is its own business, and several may be installed at once; a
|
|
98
|
+
* Supporter chooses one per forward. The interface is `PhisSupportForwardingAdapterV1` in
|
|
99
|
+
* `@phis/contracts/support`.
|
|
100
|
+
*/
|
|
101
|
+
supportForwarding: "@phis/server/service/support-forwarding",
|
|
89
102
|
};
|
|
90
103
|
/**
|
|
91
104
|
* The digest of the interface each service kind currently has.
|
|
@@ -107,11 +120,15 @@ export const PHIS_SERVICE_KINDS = {
|
|
|
107
120
|
*/
|
|
108
121
|
export const PHIS_SERVICE_INTERFACE_VERSIONS = {
|
|
109
122
|
[PHIS_SERVICE_KINDS.mediaStorage]: 1,
|
|
123
|
+
[PHIS_SERVICE_KINDS.payments]: 1,
|
|
110
124
|
[PHIS_SERVICE_KINDS.directory]: 1,
|
|
111
125
|
[PHIS_SERVICE_KINDS.translation]: 1,
|
|
126
|
+
[PHIS_SERVICE_KINDS.supportForwarding]: 1,
|
|
112
127
|
};
|
|
113
128
|
export const PHIS_SERVICE_INTERFACE_DIGESTS = {
|
|
129
|
+
[PHIS_SERVICE_KINDS.payments]: "6b106818d5edbfeddd484e9f571509695a1a8dbb5b82435338a094216410fcf7",
|
|
114
130
|
[PHIS_SERVICE_KINDS.mediaStorage]: "45a871522511f7d77841ca8dd0113b423b3cfd4cb921f143cd1d3d116cab6952",
|
|
115
131
|
[PHIS_SERVICE_KINDS.directory]: "2cac7397c7beb1b8e71fc67f5cae3be89182dddf096895570a15deafa1adbfc9",
|
|
116
132
|
[PHIS_SERVICE_KINDS.translation]: "9bae2e7b92ded5cdde9321939a3bb8cd589f6e1ef8bca7bc5f65608313b3207d",
|
|
133
|
+
[PHIS_SERVICE_KINDS.supportForwarding]: "e9d01711a5ebdfa37ea4c6828952c87935b6e755b98ab8e69cc397933dfbed6f",
|
|
117
134
|
};
|