@optolith/entity-descriptions 0.4.22 → 0.4.24
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/CHANGELOG.md +16 -0
- package/lib/creator.d.ts +4 -1
- package/lib/creator.js +6 -4
- package/lib/entities/activatable.d.ts +1 -1
- package/lib/entities/liturgicalChant.js +9 -5
- package/lib/entities/partial/enhancements.d.ts +1 -1
- package/lib/entities/partial/enhancements.js +4 -1
- package/lib/entities/partial/rated/activatable/cost.d.ts +1 -1
- package/lib/entities/partial/reader.d.ts +3 -0
- package/lib/entities/partial/responsiveText.d.ts +1 -1
- package/lib/entities/partial/units/timeSpan.d.ts +1 -1
- package/lib/entities/partial/units/timeSpan.js +1 -0
- package/lib/entities/spell.js +4 -2
- package/lib/index.d.ts +55 -54
- package/lib/index.js +2 -2
- package/lib/references/index.d.ts +2 -1
- package/lib/references/index.js +5 -2
- package/lib/references/publicationOptions.d.ts +70 -0
- package/lib/references/publicationOptions.js +122 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
package/lib/index.js
CHANGED
|
@@ -172,7 +172,7 @@ export const supportedEntities = Object.keys(registeredEntityDescriptionCreators
|
|
|
172
172
|
* Get a JSON representation of the rules text for an entry in the database.
|
|
173
173
|
*/
|
|
174
174
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- false positive
|
|
175
|
-
export const getEntityDescription = (database, localeEnv, idMap, getResolvedSelectOptionById, getAllResolvedSelectOptions, getAllResolvedNewSkillApplications, getAllResolvedSkillUses, entityName, instanceId) => {
|
|
175
|
+
export const getEntityDescription = (database, localeEnv, idMap, getResolvedSelectOptionById, getAllResolvedSelectOptions, getAllResolvedNewSkillApplications, getAllResolvedSkillUses, entityName, instanceId, publicationOptions) => {
|
|
176
176
|
const creator = registeredEntityDescriptionCreators[entityName];
|
|
177
177
|
const instance = database.getInstanceOfEntityById(entityName, instanceId);
|
|
178
178
|
if (!instance) {
|
|
@@ -188,5 +188,5 @@ export const getEntityDescription = (database, localeEnv, idMap, getResolvedSele
|
|
|
188
188
|
getAllResolvedNewSkillApplications,
|
|
189
189
|
getAllResolvedSkillUses,
|
|
190
190
|
idMap,
|
|
191
|
-
}, localeEnv, { entity: entityName, content: instance, id: instanceId });
|
|
191
|
+
}, localeEnv, { entity: entityName, content: instance, id: instanceId }, { publications: publicationOptions });
|
|
192
192
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import type { PublicationRefs } from "@optolith/database-schema/gen";
|
|
2
2
|
import type { GetInstanceById } from "../helpers/getTypes.js";
|
|
3
3
|
import type { LocaleEnvironment } from "../helpers/locale.js";
|
|
4
|
+
import { type PublicationOptions } from "./publicationOptions.js";
|
|
4
5
|
/**
|
|
5
6
|
* Returns the translation of the references.
|
|
6
7
|
*/
|
|
7
|
-
export declare const getReferencesTranslation: (getInstanceById: GetInstanceById<"Publication">, locale: LocaleEnvironment, references: PublicationRefs) => string;
|
|
8
|
+
export declare const getReferencesTranslation: (getInstanceById: GetInstanceById<"Publication">, publicationOptions: PublicationOptions, locale: LocaleEnvironment, references: PublicationRefs) => string;
|
package/lib/references/index.js
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import { isNotNullish } from "@optolith/helpers/nullable";
|
|
2
2
|
import { assertExhaustive } from "@optolith/helpers/typeSafety";
|
|
3
3
|
import { fromRawPageRange, normalizePageRanges, printPageRanges } from "./pageRange.js";
|
|
4
|
+
import { isPublicationIncluded } from "./publicationOptions.js";
|
|
4
5
|
/**
|
|
5
6
|
* Returns the translation of the references.
|
|
6
7
|
*/
|
|
7
|
-
export const getReferencesTranslation = (getInstanceById, locale, references) => references
|
|
8
|
+
export const getReferencesTranslation = (getInstanceById, publicationOptions, locale, references) => references
|
|
8
9
|
.map(ref => {
|
|
9
10
|
const publication = getInstanceById("Publication", ref.id);
|
|
10
11
|
const publicationTranslations = locale.translateMap(publication?.translations);
|
|
11
12
|
const occurrences = locale.translateMap(ref.occurrences);
|
|
12
13
|
if (publication === undefined ||
|
|
13
14
|
publicationTranslations === undefined ||
|
|
14
|
-
occurrences === undefined
|
|
15
|
+
occurrences === undefined ||
|
|
16
|
+
(publicationOptions.onlyShowReferencesToIncludedPublications &&
|
|
17
|
+
!isPublicationIncluded(publicationOptions, ref.id, publication))) {
|
|
15
18
|
return undefined;
|
|
16
19
|
}
|
|
17
20
|
const initialPageRanges = normalizePageRanges(occurrences.initial.pages.map(fromRawPageRange));
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import type { Publication, Publication_ID, PublicationRefs } from "@optolith/database-schema/gen";
|
|
2
|
+
import type { StdReader } from "../entities/partial/reader.js";
|
|
3
|
+
import type { GetInstanceById } from "../helpers/getTypes.js";
|
|
4
|
+
import type { TranslateMap } from "../helpers/translate.js";
|
|
5
|
+
/**
|
|
6
|
+
* Options for how to render information from different publications in entity descriptions.
|
|
7
|
+
*/
|
|
8
|
+
export type PublicationOptions = {
|
|
9
|
+
/**
|
|
10
|
+
* A list of publications to include, identified by their ID. These will always be included no matter the settings in `showPublicationGroups`.
|
|
11
|
+
*/
|
|
12
|
+
publications: Publication_ID[];
|
|
13
|
+
/**
|
|
14
|
+
* Which publication groups to include, no matter if they are explicitly referenced or not.
|
|
15
|
+
*
|
|
16
|
+
* - `"none"`: No groups, only explicitly referenced publications
|
|
17
|
+
* - `"core"`: Core rules
|
|
18
|
+
* - `"playerOriented"`: Core rules and player-oriented supplements, excluding books with adult content and adventure books.
|
|
19
|
+
* - `"playerOrientedWithAdult"`: Core rules and player-oriented supplements, excluding adventure books but including books with adult content.
|
|
20
|
+
* - `"playerOrientedWithAdventures"`: Core rules and player-oriented supplements, including adventure books but excluding books with adult content.
|
|
21
|
+
* - `"all"`: All groups, including books with adult content and adventure books. Any explicit publication references will have no effect as all publications are included anyway.
|
|
22
|
+
*/
|
|
23
|
+
showPublicationGroups: "none" | "core" | "playerOriented" | "playerOrientedWithAdult" | "playerOrientedWithAdventures" | "all";
|
|
24
|
+
/**
|
|
25
|
+
* How to handle added and removed entries for publications.
|
|
26
|
+
*
|
|
27
|
+
* - `"none"`: No handling, new and deprecated/removed entries are displayed.
|
|
28
|
+
* - `"latestOnly"`: Consider only the latest printings of publications. Inclusion and exclusion of entries is determined based on the initial occurrence and all revisions, if any.
|
|
29
|
+
* - `Record<Publication_ID, number>`: A custom handling for each publication, where the number indicates up until which point to include. If an entry is not present in this record, it is treated as if the latest printing should be included.
|
|
30
|
+
*/
|
|
31
|
+
changeHandling: "none" | "latestOnly" | Record<Publication_ID, number>;
|
|
32
|
+
/**
|
|
33
|
+
* If true, only publication references to publications included via `publications` and `showPublicationGroups` will be shown.
|
|
34
|
+
*/
|
|
35
|
+
onlyShowReferencesToIncludedPublications: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* If true, only include publications that have been fully implemented.
|
|
38
|
+
*/
|
|
39
|
+
onlyCompletePublications: boolean;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Checks if a publication is included based on the publication options.
|
|
43
|
+
*/
|
|
44
|
+
export declare const isPublicationIncluded: (publicationOptions: PublicationOptions, publicationId: Publication_ID, publication: Publication) => boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Checks if a publication is included based on the publication options.
|
|
47
|
+
*/
|
|
48
|
+
export declare const isPublicationIncludedById: (getInstanceById: GetInstanceById<"Publication">, publicationOptions: PublicationOptions, publicationId: Publication_ID) => boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Checks if an entry is from a publication that should be included based on the publication options. If the entry has no publication references, it is included by default, as it is assumed that its parent entry has sources that determine whether to include it or not.
|
|
51
|
+
*/
|
|
52
|
+
export declare const isEntryFromIncludedPublication: (entry: {
|
|
53
|
+
src?: PublicationRefs;
|
|
54
|
+
}, getInstanceById: GetInstanceById<"Publication">, translateMap: TranslateMap, publicationOptions: PublicationOptions) => boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Filters a list of entries to only include those that are from publications that should be included based on the publication options. If an entry has no publication references, it is included by default, as it is assumed that its parent entry has sources that determine whether to include it or not.
|
|
57
|
+
*
|
|
58
|
+
* Provided instances can have an indirect `src` property. Use the second parameter to specify how to access the object with publication references for each entry.
|
|
59
|
+
*/
|
|
60
|
+
export declare const filterIncludedPublicationEntriesMapR: <T>(instances: T[], accessorFn: (entry: T) => {
|
|
61
|
+
src?: PublicationRefs;
|
|
62
|
+
}) => StdReader<T[], "tm" | "ibi" | "po", "Publication">;
|
|
63
|
+
/**
|
|
64
|
+
* Filters a list of entries to only include those that are from publications that should be included based on the publication options. If an entry has no publication references, it is included by default, as it is assumed that its parent entry has sources that determine whether to include it or not.
|
|
65
|
+
*
|
|
66
|
+
* Provided instances must have a direct `src` property.
|
|
67
|
+
*/
|
|
68
|
+
export declare const filterIncludedPublicationEntriesR: <T extends {
|
|
69
|
+
src?: PublicationRefs;
|
|
70
|
+
}>(instances: T[]) => StdReader<T[], "tm" | "ibi" | "po", "Publication">;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { identity } from "@elyukai/utils/function";
|
|
2
|
+
import { Reader } from "@elyukai/utils/reader";
|
|
3
|
+
import { assertExhaustive } from "@elyukai/utils/typeSafety";
|
|
4
|
+
const isPublicationIncludedInGroup = (publication, publicationOptions) => {
|
|
5
|
+
switch (publicationOptions.showPublicationGroups) {
|
|
6
|
+
case "none":
|
|
7
|
+
return false;
|
|
8
|
+
case "core":
|
|
9
|
+
switch (publication.category.kind) {
|
|
10
|
+
case "CoreRules":
|
|
11
|
+
return true;
|
|
12
|
+
case "ExpansionRules":
|
|
13
|
+
case "Sourcebook":
|
|
14
|
+
case "RegionalSourcebook":
|
|
15
|
+
case "Adventure":
|
|
16
|
+
return false;
|
|
17
|
+
default:
|
|
18
|
+
return assertExhaustive(publication.category);
|
|
19
|
+
}
|
|
20
|
+
case "playerOriented":
|
|
21
|
+
switch (publication.category.kind) {
|
|
22
|
+
case "CoreRules":
|
|
23
|
+
case "ExpansionRules":
|
|
24
|
+
case "Sourcebook":
|
|
25
|
+
case "RegionalSourcebook":
|
|
26
|
+
return !publication.containsAdultContent;
|
|
27
|
+
case "Adventure":
|
|
28
|
+
return false;
|
|
29
|
+
default:
|
|
30
|
+
return assertExhaustive(publication.category);
|
|
31
|
+
}
|
|
32
|
+
case "playerOrientedWithAdult":
|
|
33
|
+
switch (publication.category.kind) {
|
|
34
|
+
case "CoreRules":
|
|
35
|
+
case "ExpansionRules":
|
|
36
|
+
case "Sourcebook":
|
|
37
|
+
case "RegionalSourcebook":
|
|
38
|
+
return true;
|
|
39
|
+
case "Adventure":
|
|
40
|
+
return false;
|
|
41
|
+
default:
|
|
42
|
+
return assertExhaustive(publication.category);
|
|
43
|
+
}
|
|
44
|
+
case "playerOrientedWithAdventures":
|
|
45
|
+
return !publication.containsAdultContent;
|
|
46
|
+
case "all":
|
|
47
|
+
return true;
|
|
48
|
+
default:
|
|
49
|
+
return assertExhaustive(publicationOptions.showPublicationGroups);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Checks if a publication is included based on the publication options.
|
|
54
|
+
*/
|
|
55
|
+
export const isPublicationIncluded = (publicationOptions, publicationId, publication) => publicationOptions.publications.includes(publicationId) ||
|
|
56
|
+
isPublicationIncludedInGroup(publication, publicationOptions);
|
|
57
|
+
/**
|
|
58
|
+
* Checks if a publication is included based on the publication options.
|
|
59
|
+
*/
|
|
60
|
+
export const isPublicationIncludedById = (getInstanceById, publicationOptions, publicationId) => {
|
|
61
|
+
const publication = getInstanceById("Publication", publicationId);
|
|
62
|
+
if (publication === undefined) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
return isPublicationIncluded(publicationOptions, publicationId, publication);
|
|
66
|
+
};
|
|
67
|
+
const isEntryRemovedInInitialPublicationOccurrence = (printingToConsider, occurrence) => (occurrence.initial.isRemoved === true &&
|
|
68
|
+
occurrence.revisions === undefined &&
|
|
69
|
+
(occurrence.initial.printing === undefined ||
|
|
70
|
+
occurrence.initial.printing <= printingToConsider)) ||
|
|
71
|
+
// also "removed" if the entry is only added in a later printing of the publication that should not be considered at this point.
|
|
72
|
+
(occurrence.initial.isRemoved !== true &&
|
|
73
|
+
occurrence.initial.printing !== undefined &&
|
|
74
|
+
occurrence.initial.printing > printingToConsider);
|
|
75
|
+
const isEntryRemovedInPublicationRevision = (printingToConsider, occurrence) => occurrence.revisions?.some((rev, revIdx, revs) => rev.kind === "Deprecated" &&
|
|
76
|
+
rev.Deprecated.printing <= printingToConsider &&
|
|
77
|
+
!revs.some((otherRev, otherRevIdx) => revIdx !== otherRevIdx &&
|
|
78
|
+
otherRev.kind === "Since" &&
|
|
79
|
+
otherRev.Since.printing <= printingToConsider &&
|
|
80
|
+
otherRev.Since.printing > rev.Deprecated.printing)) === true;
|
|
81
|
+
const isEntryRemovedInPublication = (publicationOptions, publicationId, occurrence) => {
|
|
82
|
+
if (publicationOptions.changeHandling === "none") {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
const printingToConsider = publicationOptions.changeHandling === "latestOnly"
|
|
86
|
+
? Infinity
|
|
87
|
+
: (publicationOptions.changeHandling[publicationId] ?? Infinity);
|
|
88
|
+
return (isEntryRemovedInInitialPublicationOccurrence(printingToConsider, occurrence) ||
|
|
89
|
+
isEntryRemovedInPublicationRevision(printingToConsider, occurrence));
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Checks if an entry is from a publication that should be included based on the publication options. If the entry has no publication references, it is included by default, as it is assumed that its parent entry has sources that determine whether to include it or not.
|
|
93
|
+
*/
|
|
94
|
+
export const isEntryFromIncludedPublication = (entry, getInstanceById, translateMap, publicationOptions) => {
|
|
95
|
+
if (entry.src === undefined) {
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
// if any publication explicity removes the entry, it is not included in any case
|
|
99
|
+
if (entry.src.some(ref => {
|
|
100
|
+
const localeOccurrences = translateMap(ref.occurrences);
|
|
101
|
+
return localeOccurrences === undefined
|
|
102
|
+
? false
|
|
103
|
+
: isPublicationIncludedById(getInstanceById, publicationOptions, ref.id) &&
|
|
104
|
+
isEntryRemovedInPublication(publicationOptions, ref.id, localeOccurrences);
|
|
105
|
+
})) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
// otherwise, it is included if at least one publication includes it
|
|
109
|
+
return entry.src.some(ref => isPublicationIncludedById(getInstanceById, publicationOptions, ref.id));
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Filters a list of entries to only include those that are from publications that should be included based on the publication options. If an entry has no publication references, it is included by default, as it is assumed that its parent entry has sources that determine whether to include it or not.
|
|
113
|
+
*
|
|
114
|
+
* Provided instances can have an indirect `src` property. Use the second parameter to specify how to access the object with publication references for each entry.
|
|
115
|
+
*/
|
|
116
|
+
export const filterIncludedPublicationEntriesMapR = (instances, accessorFn) => Reader.asks(({ getInstanceById, translateMap, publicationOptions }) => instances.filter(instance => isEntryFromIncludedPublication(accessorFn(instance), getInstanceById, translateMap, publicationOptions)));
|
|
117
|
+
/**
|
|
118
|
+
* Filters a list of entries to only include those that are from publications that should be included based on the publication options. If an entry has no publication references, it is included by default, as it is assumed that its parent entry has sources that determine whether to include it or not.
|
|
119
|
+
*
|
|
120
|
+
* Provided instances must have a direct `src` property.
|
|
121
|
+
*/
|
|
122
|
+
export const filterIncludedPublicationEntriesR = (instances) => filterIncludedPublicationEntriesMapR(instances, identity);
|