@phis/contracts 0.2.0 → 0.4.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/NOTICE +1 -1
- package/README.md +175 -67
- package/dist/access.d.ts +63 -0
- package/dist/access.js +78 -0
- package/dist/addon-index.d.ts +5 -0
- package/dist/addon-index.js +5 -0
- package/dist/addon.d.ts +181 -57
- package/dist/addon.js +2 -2
- package/dist/assets.d.ts +165 -0
- package/dist/assets.js +1 -0
- package/dist/capabilities.d.ts +175 -33
- package/dist/capabilities.js +2 -2
- package/dist/catalog.d.ts +104 -0
- package/dist/catalog.js +116 -0
- package/dist/cms.d.ts +120 -0
- package/dist/cms.js +270 -0
- package/dist/core.d.ts +52 -6
- package/dist/core.js +55 -8
- package/dist/http.d.ts +33 -0
- package/dist/http.js +33 -0
- package/dist/locale.d.ts +14 -0
- package/dist/locale.js +14 -0
- package/dist/logging.d.ts +49 -0
- package/dist/logging.js +17 -0
- package/dist/media-storage.d.ts +371 -0
- package/dist/media-storage.js +84 -0
- package/dist/media.d.ts +272 -0
- package/dist/media.js +421 -0
- package/dist/queries.d.ts +280 -48
- package/dist/queries.js +10 -1
- package/dist/resource-links.d.ts +94 -0
- package/dist/resource-links.js +27 -0
- package/dist/schema.d.ts +160 -26
- package/dist/schema.js +11 -2
- package/dist/server-capabilities.d.ts +37 -0
- package/dist/server-capabilities.js +17 -0
- package/dist/signals.d.ts +58 -0
- package/dist/signals.js +118 -0
- package/dist/site-groups.d.ts +53 -0
- package/dist/site-groups.js +54 -0
- package/dist/support.d.ts +390 -0
- package/dist/support.js +148 -0
- package/dist/threads.d.ts +363 -0
- package/dist/threads.js +146 -0
- package/dist/translation.d.ts +125 -0
- package/dist/translation.js +15 -0
- package/dist/user-state.d.ts +132 -0
- package/dist/user-state.js +92 -0
- package/package.json +64 -4
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -6
package/dist/media.d.ts
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How a Media Space names its kind on the wire.
|
|
3
|
+
*
|
|
4
|
+
* Only the name is shared. phis stores the kind as a smallint and that number is its own business --
|
|
5
|
+
* the site UI never sees it, so putting it here would place a storage detail in a contract.
|
|
6
|
+
*
|
|
7
|
+
* What made this worth writing down is that the translation between the two was incomplete: phis knew
|
|
8
|
+
* four kinds and mapped three, falling back to `"site"` for the rest, while the UI declared its own
|
|
9
|
+
* union of the same three. An Add-on Space therefore reached the administration surface calling itself
|
|
10
|
+
* a Site Space, in the one view that shows Add-on Spaces at all. With the names here, the map on the
|
|
11
|
+
* server side is a total function from its own enum onto this one, and a kind that is added and not
|
|
12
|
+
* mapped stops compiling.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PHI_MEDIA_SPACE_KINDS: readonly ["site", "user", "group", "addon"];
|
|
15
|
+
export type PhiMediaSpaceKind = (typeof PHI_MEDIA_SPACE_KINDS)[number];
|
|
16
|
+
/**
|
|
17
|
+
* The kinds a Module may declare a need for.
|
|
18
|
+
*
|
|
19
|
+
* The Site Space always exists and is governed by the Core Media role matrix, so declaring it could
|
|
20
|
+
* only repeat what is already true. An Add-on Space belongs to its Add-on and comes with installing
|
|
21
|
+
* it, rather than being asked for by a Module.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PHI_DECLARABLE_MEDIA_SPACE_KINDS: readonly ["user", "group"];
|
|
24
|
+
export type PhiDeclarableMediaSpaceKind = (typeof PHI_DECLARABLE_MEDIA_SPACE_KINDS)[number];
|
|
25
|
+
export declare function isPhiDeclarableMediaSpaceKind(value: unknown): value is PhiDeclarableMediaSpaceKind;
|
|
26
|
+
/**
|
|
27
|
+
* The display properties an Asset may carry, as bits of `media_assets.presentation_flags`.
|
|
28
|
+
*
|
|
29
|
+
* Shared because the number itself travels: the site UI sends a mask as a list filter and an array of
|
|
30
|
+
* these values when metadata is saved, and phis both answers the filter with `flags & mask <> 0` and
|
|
31
|
+
* refuses a value it does not know. Two sides that must agree on a number is what this package is for,
|
|
32
|
+
* and the copy that lived on each side had already drifted -- phis still carried `Private`, `Archived`
|
|
33
|
+
* and `Restricted` long after lifecycle and delivery had become columns of their own.
|
|
34
|
+
*
|
|
35
|
+
* Display only. Access is `delivery_policy` and `lifecycle_status`, never a bit in here.
|
|
36
|
+
*
|
|
37
|
+
* Bits 1 and 2 are free, and before v1 a bit may be given a new meaning rather than kept vacant.
|
|
38
|
+
*/
|
|
39
|
+
export declare const PhiMediaAssetFlags: {
|
|
40
|
+
/** Offered as a background. What an Asset is for; where it came from is `meta.source`. */
|
|
41
|
+
readonly Background: number;
|
|
42
|
+
readonly Featured: number;
|
|
43
|
+
readonly Locked: number;
|
|
44
|
+
readonly Mask: number;
|
|
45
|
+
};
|
|
46
|
+
export type PhiMediaAssetFlag = (typeof PhiMediaAssetFlags)[keyof typeof PhiMediaAssetFlags];
|
|
47
|
+
/**
|
|
48
|
+
* The rest of the Media vocabulary both sides speak.
|
|
49
|
+
*
|
|
50
|
+
* Kind names travel as `kind` in the list contract and are stored on the Asset; Folder flags travel in
|
|
51
|
+
* the Folder payload; a variant key is a number in a delivery URL and the name phis generates the
|
|
52
|
+
* rendition under. None of it is one side's private business, and all of it stood twice -- once here in
|
|
53
|
+
* spirit, once in each repository in fact -- until a bit value drifted and showed what that costs.
|
|
54
|
+
*
|
|
55
|
+
* The two resolvers come along because a vocabulary without its total function is only half a contract:
|
|
56
|
+
* a content type must land on the same kind in the browser and on the server, or an upload is filed as
|
|
57
|
+
* one thing and listed as another.
|
|
58
|
+
*/
|
|
59
|
+
export declare const PhiMediaFolderFlags: {
|
|
60
|
+
readonly Collapsed: number;
|
|
61
|
+
readonly Hidden: number;
|
|
62
|
+
readonly Locked: number;
|
|
63
|
+
};
|
|
64
|
+
export declare const PhiMediaKind: {
|
|
65
|
+
readonly Image: "image";
|
|
66
|
+
readonly Video: "video";
|
|
67
|
+
readonly Audio: "audio";
|
|
68
|
+
readonly Pdf: "pdf";
|
|
69
|
+
readonly Markdown: "markdown";
|
|
70
|
+
readonly Document: "document";
|
|
71
|
+
readonly Archive: "archive";
|
|
72
|
+
readonly Font: "font";
|
|
73
|
+
readonly Binary: "binary";
|
|
74
|
+
readonly Other: "other";
|
|
75
|
+
};
|
|
76
|
+
export declare const PhiImageAssetVariantKey: {
|
|
77
|
+
readonly Thumbnail: 0;
|
|
78
|
+
readonly Preview: 1;
|
|
79
|
+
readonly Banner: 2;
|
|
80
|
+
readonly Header: 3;
|
|
81
|
+
readonly Card: 4;
|
|
82
|
+
readonly Hero: 5;
|
|
83
|
+
readonly Avatar: 6;
|
|
84
|
+
readonly Logo: 7;
|
|
85
|
+
readonly Landscape: 8;
|
|
86
|
+
readonly Portrait: 9;
|
|
87
|
+
};
|
|
88
|
+
export declare const PhiImageAssetVariantKeyName: {
|
|
89
|
+
readonly 0: "thumbnail";
|
|
90
|
+
readonly 1: "preview";
|
|
91
|
+
readonly 2: "banner";
|
|
92
|
+
readonly 3: "header";
|
|
93
|
+
readonly 4: "card";
|
|
94
|
+
readonly 5: "hero";
|
|
95
|
+
readonly 6: "avatar";
|
|
96
|
+
readonly 7: "logo";
|
|
97
|
+
readonly 8: "landscape";
|
|
98
|
+
readonly 9: "portrait";
|
|
99
|
+
};
|
|
100
|
+
export type PhiImageAssetVariantSpec = {
|
|
101
|
+
width: number;
|
|
102
|
+
height: number;
|
|
103
|
+
fit: "cover" | "contain";
|
|
104
|
+
quality: number;
|
|
105
|
+
format: "webp";
|
|
106
|
+
};
|
|
107
|
+
export declare function normalizePhiMediaKind(kind: string | null | undefined): "image" | "video" | "audio" | "pdf" | "markdown" | "document" | "archive" | "font" | "binary" | "other";
|
|
108
|
+
export declare function resolvePhiMediaKindFromContentType(contentType: string | null | undefined): "image" | "video" | "audio" | "pdf" | "markdown" | "document" | "archive" | "font" | "binary" | "other";
|
|
109
|
+
export declare function normalizePhiImageAssetVariantKey(key: unknown): 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 8 | null;
|
|
110
|
+
export declare function resolvePhiImageAssetVariantKeyName(key: number | null | undefined): string | null;
|
|
111
|
+
export declare function resolvePhiImageAssetVariantSpec(key: number | null | undefined): PhiImageAssetVariantSpec | null;
|
|
112
|
+
/**
|
|
113
|
+
* The two closed vocabularies that decide whether an Asset may be delivered at all.
|
|
114
|
+
*
|
|
115
|
+
* The numbers themselves reach the site UI: an Asset's detail payload carries `lifecycleStatus` and
|
|
116
|
+
* `deliveryPolicy` as they stand in the row, and the UI decides from them whether `next/image` may be
|
|
117
|
+
* pointed at the original. phis evaluates `delivery_policy` before any physical lookup, so a value that
|
|
118
|
+
* means one thing on one side and another on the other would be a visibility bug, not a display bug.
|
|
119
|
+
*
|
|
120
|
+
* Unlike the Space kind next to them in phis, which stays a storage detail because the wire carries its
|
|
121
|
+
* name instead of its number.
|
|
122
|
+
*/
|
|
123
|
+
export declare const PhiMediaLifecycleStatus: {
|
|
124
|
+
readonly Pending: 1;
|
|
125
|
+
readonly Ready: 2;
|
|
126
|
+
readonly Archived: 3;
|
|
127
|
+
readonly Quarantined: 4;
|
|
128
|
+
readonly Failed: 5;
|
|
129
|
+
};
|
|
130
|
+
export declare const PhiMediaDeliveryPolicy: {
|
|
131
|
+
readonly Public: 1;
|
|
132
|
+
readonly Authenticated: 2;
|
|
133
|
+
readonly User: 3;
|
|
134
|
+
readonly Group: 4;
|
|
135
|
+
readonly Internal: 5;
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* What a typeface says about its own proportions.
|
|
139
|
+
*
|
|
140
|
+
* Shared because the numbers cross: phis reads them out of the uploaded file once and keeps them on the
|
|
141
|
+
* Asset, and the site UI turns them into the `size-adjust` and `*-override` descriptors of a fallback
|
|
142
|
+
* `@font-face`. Without that face a browser sets the page in a local substitute and reflows when the
|
|
143
|
+
* real file lands, which is the one thing a viewer actually sees.
|
|
144
|
+
*
|
|
145
|
+
* Everything is in font units on the `unitsPerEm` grid, so a reader divides rather than assumes 1000.
|
|
146
|
+
*/
|
|
147
|
+
export type PhiFontMetrics = {
|
|
148
|
+
/** The container the numbers were read from. */
|
|
149
|
+
format: "sfnt" | "woff" | "woff2";
|
|
150
|
+
familyName: string | null;
|
|
151
|
+
unitsPerEm: number;
|
|
152
|
+
ascent: number;
|
|
153
|
+
descent: number;
|
|
154
|
+
lineGap: number;
|
|
155
|
+
capHeight: number | null;
|
|
156
|
+
xHeight: number | null;
|
|
157
|
+
/**
|
|
158
|
+
* How wide running text sets, as an advance width.
|
|
159
|
+
*
|
|
160
|
+
* `glyphs` is the frequency-weighted advance of the characters prose is made of. `os2` is the font's
|
|
161
|
+
* own `xAvgCharWidth`, which averages every glyph in the file and is therefore wrong for a Latin page
|
|
162
|
+
* in a family that also carries Greek -- the source travels so a reader can tell the two apart.
|
|
163
|
+
*/
|
|
164
|
+
xWidthAvg: number | null;
|
|
165
|
+
xWidthAvgSource: "glyphs" | "os2" | null;
|
|
166
|
+
/**
|
|
167
|
+
* What the file classifies itself as, and `null` where it classifies itself as nothing.
|
|
168
|
+
*
|
|
169
|
+
* Plenty of good fonts leave both PANOSE and the `OS/2` family class empty, so the absence is a fact
|
|
170
|
+
* about the file rather than a reason to guess: whoever picks the local substitute decides instead.
|
|
171
|
+
*/
|
|
172
|
+
category: "serif" | "sans-serif" | "monospace" | null;
|
|
173
|
+
/**
|
|
174
|
+
* Which unicode cuts the typeface has characters in, read out of its `cmap` at upload.
|
|
175
|
+
*
|
|
176
|
+
* Absent on a font uploaded before cuts existed; such a font is delivered whole.
|
|
177
|
+
*/
|
|
178
|
+
coverage?: PhiFontCoverage | null;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* The cuts a typeface can be delivered in.
|
|
182
|
+
*
|
|
183
|
+
* The number stands in a delivery URL, so it is shared; the named cuts follow the unicode ranges Google
|
|
184
|
+
* Fonts divides its families along, so a face declared here splits where fonts are commonly split.
|
|
185
|
+
* `Rest` is not a range but everything a typeface has outside all of them -- its own characters, listed
|
|
186
|
+
* per font in `PhiFontCoverage.restRanges`, so a page never loses a glyph and never fetches a cut for a
|
|
187
|
+
* character the font does not have.
|
|
188
|
+
*/
|
|
189
|
+
export declare const PhiFontSubsetKey: {
|
|
190
|
+
readonly Latin: 0;
|
|
191
|
+
readonly LatinExt: 1;
|
|
192
|
+
readonly Cyrillic: 2;
|
|
193
|
+
readonly CyrillicExt: 3;
|
|
194
|
+
readonly Greek: 4;
|
|
195
|
+
readonly GreekExt: 5;
|
|
196
|
+
readonly Vietnamese: 6;
|
|
197
|
+
readonly Math: 7;
|
|
198
|
+
readonly Symbols: 8;
|
|
199
|
+
readonly Rest: 15;
|
|
200
|
+
};
|
|
201
|
+
export type PhiFontSubsetKeyValue = (typeof PhiFontSubsetKey)[keyof typeof PhiFontSubsetKey];
|
|
202
|
+
/** An inclusive codepoint range. */
|
|
203
|
+
export type PhiUnicodeRange = readonly [start: number, end: number];
|
|
204
|
+
/**
|
|
205
|
+
* Raised whenever the ranges below or the way a cut is produced changes, so every stored cut is made
|
|
206
|
+
* again rather than served under a rule that no longer describes it.
|
|
207
|
+
*/
|
|
208
|
+
export declare const PHI_FONT_SUBSET_VERSION = 1;
|
|
209
|
+
/** The named cuts, as Google Fonts' CSS2 API states them for a Latin, Cyrillic and Greek family. */
|
|
210
|
+
export declare const PHI_FONT_SUBSET_RANGES: Readonly<Record<Exclude<PhiFontSubsetKeyValue, 15>, readonly PhiUnicodeRange[]>>;
|
|
211
|
+
/** What a typeface has characters in: the named cuts, and its own characters outside all of them. */
|
|
212
|
+
export type PhiFontCoverage = {
|
|
213
|
+
subsets: PhiFontSubsetKeyValue[];
|
|
214
|
+
restRanges: PhiUnicodeRange[];
|
|
215
|
+
};
|
|
216
|
+
export declare function isPhiCodepointInRanges(codepoint: number, ranges: readonly PhiUnicodeRange[]): boolean;
|
|
217
|
+
/** A `unicode-range` descriptor value. */
|
|
218
|
+
export declare function formatPhiUnicodeRange(ranges: readonly PhiUnicodeRange[]): string;
|
|
219
|
+
/** The ranges a cut covers for one typeface: the shared list for a named cut, the font's own for `Rest`. */
|
|
220
|
+
export declare function resolvePhiFontSubsetRanges(key: PhiFontSubsetKeyValue, coverage: PhiFontCoverage): readonly PhiUnicodeRange[];
|
|
221
|
+
export declare function isPhiFontSubsetKey(value: unknown): value is PhiFontSubsetKeyValue;
|
|
222
|
+
/**
|
|
223
|
+
* The cuts to preload for a page in `locale`, `Latin` first, restricted to what the font covers.
|
|
224
|
+
*
|
|
225
|
+
* `locale` is a BCP 47 tag; its script subtag overrides the language's usual one, so `sr-Latn` preloads
|
|
226
|
+
* `LatinExt` where `sr` preloads `Cyrillic`.
|
|
227
|
+
*/
|
|
228
|
+
export declare function resolvePhiFontPreloadSubsetKeys(locale: string | null | undefined, coverage: PhiFontCoverage): PhiFontSubsetKeyValue[];
|
|
229
|
+
/**
|
|
230
|
+
* How a body above one part is divided, as a rule rather than as a Provider's private arithmetic.
|
|
231
|
+
*
|
|
232
|
+
* It lives here because two parties have to agree on it and neither can be told by the other in time. The
|
|
233
|
+
* Provider needs the part size to sign one request per part; the Client needs it *before* the plan exists,
|
|
234
|
+
* because a digest can only be signed into a request if it is known when the request is signed -- so the
|
|
235
|
+
* Client has to hash the same divisions the Provider is about to address. A rule both compute from the
|
|
236
|
+
* byte size is the only arrangement where that holds without an extra round trip.
|
|
237
|
+
*
|
|
238
|
+
* **Frozen once objects exist under it.** A `sha256-composite` value is a digest of part digests, so it
|
|
239
|
+
* answers "the same bytes divided the same way". Change the division and the same file yields a different
|
|
240
|
+
* value, which splits duplicate detection into cohorts that can never match across the change. The value
|
|
241
|
+
* carries the part size for exactly this reason: a changed rule produces non-matches, never false matches.
|
|
242
|
+
* Changing it is therefore a decision about the whole corpus, not a tuning knob.
|
|
243
|
+
*
|
|
244
|
+
* `PHIS_MEDIA_UPLOAD_MAX_PART_COUNT` is well under S3's ten thousand on purpose. Every part is signed up
|
|
245
|
+
* front, so the count is also the size of the plan a Client receives and Core holds in memory.
|
|
246
|
+
*/
|
|
247
|
+
export declare const PHIS_MEDIA_UPLOAD_PART_SIZE_BYTES: number;
|
|
248
|
+
export declare const PHIS_MEDIA_UPLOAD_MAX_PART_COUNT = 1000;
|
|
249
|
+
/**
|
|
250
|
+
* The part size for one body, and the same answer wherever it is asked.
|
|
251
|
+
*
|
|
252
|
+
* Sixteen mebibytes until that would need more parts than are allowed, and from there the smallest whole
|
|
253
|
+
* mebibyte that fits the body into the allowance. Whole mebibytes keep the number short where it is
|
|
254
|
+
* recorded and keep the arithmetic exact in a browser, where sizes are doubles.
|
|
255
|
+
*/
|
|
256
|
+
export declare function resolvePhiMediaUploadPartSizeBytes(sizeBytes: number): number;
|
|
257
|
+
/** How many parts one body is divided into under `resolvePhiMediaUploadPartSizeBytes`. */
|
|
258
|
+
export declare function resolvePhiMediaUploadPartCount(sizeBytes: number): number;
|
|
259
|
+
/**
|
|
260
|
+
* The recorded form of a `sha256-composite` digest: the digest, the part count, the part size.
|
|
261
|
+
*
|
|
262
|
+
* Duplicate detection compares these values as strings, so everything that decides whether two of them
|
|
263
|
+
* mean the same thing has to be inside the string. The digest alone would not: the same bytes divided
|
|
264
|
+
* differently hash differently, and a value that did not say how it was divided would look like a plain
|
|
265
|
+
* SHA-256 that simply failed to match. Naming the division makes a mismatch legible instead of puzzling.
|
|
266
|
+
*/
|
|
267
|
+
export declare function formatPhiMediaCompositeChecksum(digestHex: string, partCount: number, partSizeBytes: number): string;
|
|
268
|
+
export declare function parsePhiMediaCompositeChecksum(value: string): {
|
|
269
|
+
digest: string;
|
|
270
|
+
partCount: number;
|
|
271
|
+
partSizeBytes: number;
|
|
272
|
+
} | null;
|