glossarist 0.4.37 → 0.4.39

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.
Files changed (37) hide show
  1. package/package.json +1 -1
  2. package/src/models/base.ts +18 -1
  3. package/src/models/bibliography-data.ts +64 -0
  4. package/src/models/{bibliography-entry.js → bibliography-entry.ts} +18 -4
  5. package/src/models/citation.ts +98 -0
  6. package/src/models/{concept-reference.js → concept-reference.ts} +21 -7
  7. package/src/models/designation-relationship.ts +39 -0
  8. package/src/models/detailed-definition.ts +92 -0
  9. package/src/models/figure.ts +110 -0
  10. package/src/models/formula.ts +36 -0
  11. package/src/models/grammar-info.ts +78 -0
  12. package/src/models/{locality.js → locality.ts} +16 -4
  13. package/src/models/localized-string.ts +32 -0
  14. package/src/models/non-verb-rep.ts +48 -0
  15. package/src/models/non-verbal-entity.ts +65 -0
  16. package/src/models/non-verbal-reference.ts +73 -0
  17. package/src/models/non-verbal-references.ts +29 -0
  18. package/src/models/{pronunciation.js → pronunciation.ts} +18 -4
  19. package/src/models/registrable.ts +48 -0
  20. package/src/models/{related-concept.js → related-concept.ts} +49 -25
  21. package/src/models/shared-non-verbal-entity.ts +36 -0
  22. package/src/models/table.ts +36 -0
  23. package/src/models/bibliography-data.js +0 -48
  24. package/src/models/citation.js +0 -68
  25. package/src/models/designation-relationship.js +0 -27
  26. package/src/models/detailed-definition.js +0 -59
  27. package/src/models/figure.js +0 -75
  28. package/src/models/formula.js +0 -25
  29. package/src/models/grammar-info.js +0 -40
  30. package/src/models/localized-string.js +0 -19
  31. package/src/models/non-verb-rep.js +0 -33
  32. package/src/models/non-verbal-entity.js +0 -46
  33. package/src/models/non-verbal-reference.js +0 -35
  34. package/src/models/non-verbal-references.js +0 -16
  35. package/src/models/registrable.js +0 -25
  36. package/src/models/shared-non-verbal-entity.js +0 -28
  37. package/src/models/table.js +0 -25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glossarist",
3
- "version": "0.4.37",
3
+ "version": "0.4.39",
4
4
  "description": "JavaScript SDK for Glossarist GCR packages — read, write, validate, and manage terminology concepts",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -7,9 +7,26 @@
7
7
  * override for performance.
8
8
  */
9
9
 
10
+ /**
11
+ * Any value that can be the output of `JSON.stringify`. Used as the
12
+ * return type of {@link GlossaristModel.toJSON} so subclasses with
13
+ * non-object JSON output (e.g. `NonVerbalReference.toJSON()` returns
14
+ * a bare string for the no-display case) can override without
15
+ * breaking variance. The object case accepts any object to avoid
16
+ * forcing `<Model>Json` interfaces to declare explicit string index
17
+ * signatures (TS interfaces don't have implicit index signatures).
18
+ */
19
+ export type JsonValue =
20
+ | string
21
+ | number
22
+ | boolean
23
+ | null
24
+ | JsonValue[]
25
+ | object;
26
+
10
27
  export abstract class GlossaristModel {
11
28
  /** Wire-shape serialization. Subclasses MUST override. */
12
- toJSON(): object {
29
+ toJSON(): JsonValue {
13
30
  throw new Error(`${this.constructor.name} must implement toJSON()`);
14
31
  }
15
32
 
@@ -0,0 +1,64 @@
1
+ import * as yaml from 'js-yaml';
2
+ import { GlossaristModel } from './base.js';
3
+ import { BibliographyEntry } from './bibliography-entry.js';
4
+ import type { BibliographyEntryJson } from './bibliography-entry.js';
5
+
6
+ export interface BibliographyDataJson {
7
+ bibliography?: ReadonlyArray<BibliographyEntryJson | BibliographyEntry>;
8
+ entries?: ReadonlyArray<BibliographyEntryJson | BibliographyEntry>;
9
+ }
10
+
11
+ export class BibliographyData extends GlossaristModel {
12
+ private readonly _rawEntries: ReadonlyArray<BibliographyEntryJson | BibliographyEntry>;
13
+ private _entries: ReadonlyArray<BibliographyEntry> | null = null;
14
+
15
+ constructor(data: BibliographyDataJson | ReadonlyArray<BibliographyEntryJson | BibliographyEntry> = {}) {
16
+ super();
17
+ let entriesData: ReadonlyArray<BibliographyEntryJson | BibliographyEntry> | undefined;
18
+ if (Array.isArray(data)) {
19
+ entriesData = data;
20
+ } else {
21
+ entriesData = (data as BibliographyDataJson)?.bibliography ?? (data as BibliographyDataJson)?.entries ?? [];
22
+ }
23
+ this._rawEntries = Array.isArray(entriesData) ? entriesData : [];
24
+ }
25
+
26
+ get entries(): ReadonlyArray<BibliographyEntry> {
27
+ return this._lazy<BibliographyEntry>(
28
+ '_entries',
29
+ '_rawEntries',
30
+ (e) => (e instanceof BibliographyEntry ? e : new BibliographyEntry(e as BibliographyEntryJson)),
31
+ );
32
+ }
33
+
34
+ find(id: string): BibliographyEntry | null {
35
+ return this.entries.find((e) => e.id === id) ?? null;
36
+ }
37
+
38
+ get keys(): ReadonlyArray<string | null> {
39
+ return this.entries.map((e) => e.id);
40
+ }
41
+
42
+ override toJSON(): BibliographyDataJson {
43
+ if (this.entries.length === 0) return { bibliography: [] };
44
+ return { bibliography: this.entries.map((e) => e.toJSON()) };
45
+ }
46
+
47
+ toYAML(): string {
48
+ return yaml.dump(this.toJSON());
49
+ }
50
+
51
+ static fromYAML(yamlString: string): BibliographyData {
52
+ const parsed = yaml.load(yamlString) as
53
+ | BibliographyDataJson
54
+ | ReadonlyArray<BibliographyEntryJson>
55
+ | undefined;
56
+ return new BibliographyData(parsed ?? {});
57
+ }
58
+
59
+ static override fromJSON(
60
+ data: BibliographyDataJson | ReadonlyArray<BibliographyEntryJson>,
61
+ ): BibliographyData {
62
+ return new BibliographyData(data);
63
+ }
64
+ }
@@ -1,7 +1,21 @@
1
1
  import { GlossaristModel } from './base.js';
2
2
 
3
+ export interface BibliographyEntryJson {
4
+ id?: string | null;
5
+ reference?: string | null;
6
+ title?: string | null;
7
+ link?: string | null;
8
+ type?: string | null;
9
+ }
10
+
3
11
  export class BibliographyEntry extends GlossaristModel {
4
- constructor(data = {}) {
12
+ readonly id: string | null;
13
+ readonly reference: string | null;
14
+ readonly title: string | null;
15
+ readonly link: string | null;
16
+ readonly type: string | null;
17
+
18
+ constructor(data: BibliographyEntryJson = {}) {
5
19
  super();
6
20
  this.id = data.id ?? null;
7
21
  this.reference = data.reference ?? null;
@@ -10,8 +24,8 @@ export class BibliographyEntry extends GlossaristModel {
10
24
  this.type = data.type ?? null;
11
25
  }
12
26
 
13
- toJSON() {
14
- const obj = {};
27
+ override toJSON(): BibliographyEntryJson {
28
+ const obj: BibliographyEntryJson = {};
15
29
  if (this.id != null) obj.id = this.id;
16
30
  if (this.reference != null) obj.reference = this.reference;
17
31
  if (this.title != null) obj.title = this.title;
@@ -20,7 +34,7 @@ export class BibliographyEntry extends GlossaristModel {
20
34
  return obj;
21
35
  }
22
36
 
23
- static fromJSON(data) {
37
+ static override fromJSON(data: BibliographyEntryJson): BibliographyEntry {
24
38
  return new BibliographyEntry(data);
25
39
  }
26
40
  }
@@ -0,0 +1,98 @@
1
+ import { GlossaristModel } from './base.js';
2
+ import { Locality } from './locality.js';
3
+ import type { LocalityJson } from './locality.js';
4
+
5
+ export interface CitationRefJson {
6
+ source?: string | null;
7
+ id?: string | null;
8
+ version?: string | null;
9
+ }
10
+
11
+ export interface CitationJson {
12
+ ref?: CitationRefJson | CitationRef | null;
13
+ locality?: LocalityJson | Locality | null;
14
+ link?: string | null;
15
+ original?: string | null;
16
+ custom_locality?: string | null;
17
+ customLocality?: string | null;
18
+ }
19
+
20
+ export class CitationRef extends GlossaristModel {
21
+ readonly source: string | null;
22
+ readonly id: string | null;
23
+ readonly version: string | null;
24
+
25
+ constructor(data: CitationRefJson = {}) {
26
+ super();
27
+ this.source = data.source ?? null;
28
+ this.id = data.id ?? null;
29
+ this.version = data.version ?? null;
30
+ }
31
+
32
+ override toString(): string {
33
+ const parts: string[] = [];
34
+ if (this.source) parts.push(this.source);
35
+ if (this.id) parts.push(this.id);
36
+ return parts.join(' ');
37
+ }
38
+
39
+ override toJSON(): CitationRefJson {
40
+ const obj: CitationRefJson = {};
41
+ if (this.source != null) obj.source = this.source;
42
+ if (this.id != null) obj.id = this.id;
43
+ if (this.version != null) obj.version = this.version;
44
+ return obj;
45
+ }
46
+
47
+ static override fromJSON(data: CitationRefJson): CitationRef {
48
+ return new CitationRef(data);
49
+ }
50
+ }
51
+
52
+ export class Citation extends GlossaristModel {
53
+ /** Backward-compat alias for {@link CitationRef}. Original codebase
54
+ * exposed the Ref class via `Citation.Ref`; keep that working. */
55
+ static readonly Ref = CitationRef;
56
+
57
+ readonly ref: CitationRef | null;
58
+ readonly locality: Locality | null;
59
+ readonly link: string | null;
60
+ readonly original: string | null;
61
+ readonly customLocality: string | null;
62
+
63
+ constructor(data: CitationJson | null = {}) {
64
+ super();
65
+ const d = data ?? {};
66
+ this.ref = d.ref
67
+ ? d.ref instanceof CitationRef
68
+ ? d.ref
69
+ : new CitationRef(d.ref)
70
+ : null;
71
+ this.locality = d.locality
72
+ ? d.locality instanceof Locality
73
+ ? d.locality
74
+ : new Locality(d.locality)
75
+ : null;
76
+ this.link = d.link ?? null;
77
+ this.original = d.original ?? null;
78
+ this.customLocality = d.custom_locality ?? d.customLocality ?? null;
79
+ }
80
+
81
+ override toString(): string {
82
+ return this.ref ? this.ref.toString() : '';
83
+ }
84
+
85
+ override toJSON(): CitationJson {
86
+ const obj: CitationJson = {};
87
+ if (this.ref != null) obj.ref = this.ref.toJSON();
88
+ if (this.locality != null) obj.locality = this.locality.toJSON();
89
+ if (this.link != null) obj.link = this.link;
90
+ if (this.original != null) obj.original = this.original;
91
+ if (this.customLocality != null) obj.custom_locality = this.customLocality;
92
+ return obj;
93
+ }
94
+
95
+ static override fromJSON(data: CitationJson): Citation {
96
+ return new Citation(data);
97
+ }
98
+ }
@@ -1,7 +1,21 @@
1
1
  import { GlossaristModel } from './base.js';
2
2
 
3
+ export interface ConceptReferenceJson {
4
+ concept_id?: string | null;
5
+ conceptId?: string | null;
6
+ ref_type?: string | null;
7
+ refType?: string | null;
8
+ source?: string | null;
9
+ urn?: string | null;
10
+ }
11
+
3
12
  export class ConceptReference extends GlossaristModel {
4
- constructor(data = {}) {
13
+ readonly conceptId: string | null;
14
+ readonly refType: string | null;
15
+ readonly source: string | null;
16
+ readonly urn: string | null;
17
+
18
+ constructor(data: ConceptReferenceJson = {}) {
5
19
  super();
6
20
  this.conceptId = data.concept_id ?? data.conceptId ?? null;
7
21
  this.refType = data.ref_type ?? data.refType ?? null;
@@ -9,20 +23,20 @@ export class ConceptReference extends GlossaristModel {
9
23
  this.urn = data.urn ?? null;
10
24
  }
11
25
 
12
- get isLocal() {
26
+ get isLocal(): boolean {
13
27
  return this.urn == null && this.source == null;
14
28
  }
15
29
 
16
- get isExternal() {
30
+ get isExternal(): boolean {
17
31
  return !this.isLocal;
18
32
  }
19
33
 
20
- static domain(conceptId) {
34
+ static domain(conceptId: string): ConceptReference {
21
35
  return new ConceptReference({ concept_id: conceptId, ref_type: 'domain' });
22
36
  }
23
37
 
24
- toJSON() {
25
- const obj = {};
38
+ override toJSON(): ConceptReferenceJson {
39
+ const obj: ConceptReferenceJson = {};
26
40
  if (this.conceptId != null) obj.concept_id = this.conceptId;
27
41
  if (this.refType != null) obj.ref_type = this.refType;
28
42
  if (this.source != null) obj.source = this.source;
@@ -30,7 +44,7 @@ export class ConceptReference extends GlossaristModel {
30
44
  return obj;
31
45
  }
32
46
 
33
- static fromJSON(data) {
47
+ static override fromJSON(data: ConceptReferenceJson): ConceptReference {
34
48
  return new ConceptReference(data);
35
49
  }
36
50
  }
@@ -0,0 +1,39 @@
1
+ import { GlossaristModel } from './base.js';
2
+
3
+ export const DESIGNATION_RELATIONSHIP_TYPES: ReadonlyArray<string> = Object.freeze([
4
+ // TBX (ISO 30042) / ISO 12620 term-level relationships
5
+ 'abbreviated_form_for', 'short_form_for',
6
+ ]);
7
+
8
+ export type DesignationRelationshipType = string;
9
+
10
+ export interface DesignationRelationshipJson {
11
+ type?: DesignationRelationshipType | null;
12
+ content?: string | null;
13
+ target?: string | null;
14
+ }
15
+
16
+ export class DesignationRelationship extends GlossaristModel {
17
+ readonly type: DesignationRelationshipType | null;
18
+ readonly content: string | null;
19
+ readonly target: string | null;
20
+
21
+ constructor(data: DesignationRelationshipJson = {}) {
22
+ super();
23
+ this.type = data.type ?? null;
24
+ this.content = data.content ?? null;
25
+ this.target = data.target ?? null;
26
+ }
27
+
28
+ override toJSON(): DesignationRelationshipJson {
29
+ const obj: DesignationRelationshipJson = {};
30
+ if (this.type != null) obj.type = this.type;
31
+ if (this.content != null) obj.content = this.content;
32
+ if (this.target != null) obj.target = this.target;
33
+ return obj;
34
+ }
35
+
36
+ static override fromJSON(data: DesignationRelationshipJson): DesignationRelationship {
37
+ return new DesignationRelationship(data);
38
+ }
39
+ }
@@ -0,0 +1,92 @@
1
+ import { GlossaristModel } from './base.js';
2
+ import { Citation } from './citation.js';
3
+ import { canonicalJson } from '../diff/canonical-json.js';
4
+
5
+ export interface DetailedDefinitionJson {
6
+ content?: string;
7
+ sources?: ReadonlyArray<unknown>;
8
+ examples?: ReadonlyArray<unknown>;
9
+ }
10
+
11
+ export interface WalkTextEntry {
12
+ text: string;
13
+ source: string;
14
+ }
15
+
16
+ export class DetailedDefinition extends GlossaristModel {
17
+ readonly content: string;
18
+ private readonly _rawSources: ReadonlyArray<unknown>;
19
+ private readonly _rawExamples: ReadonlyArray<unknown>;
20
+ private _sources: ReadonlyArray<Citation> | null = null;
21
+ private _examples: ReadonlyArray<DetailedDefinition> | null = null;
22
+
23
+ constructor(data: DetailedDefinitionJson = {}) {
24
+ super();
25
+ this.content = data.content ?? '';
26
+ this._rawSources = data.sources ?? [];
27
+ this._rawExamples = data.examples ?? [];
28
+ }
29
+
30
+ get sources(): ReadonlyArray<Citation> {
31
+ return this._lazy<Citation>(
32
+ '_sources',
33
+ '_rawSources',
34
+ (s) => (s instanceof Citation ? s : new Citation(s as never)),
35
+ );
36
+ }
37
+
38
+ get examples(): ReadonlyArray<DetailedDefinition> {
39
+ return this._lazy<DetailedDefinition>(
40
+ '_examples',
41
+ '_rawExamples',
42
+ (e) =>
43
+ e instanceof DetailedDefinition
44
+ ? e
45
+ : new DetailedDefinition(e as DetailedDefinitionJson),
46
+ );
47
+ }
48
+
49
+ override toJSON(): DetailedDefinitionJson {
50
+ const obj: DetailedDefinitionJson = { content: this.content };
51
+ this._serialize(obj as Record<string, unknown>, 'sources', '_sources', '_rawSources');
52
+ this._serialize(obj as Record<string, unknown>, 'examples', '_examples', '_rawExamples');
53
+ return obj;
54
+ }
55
+
56
+ /**
57
+ * Yield this definition's content and the content of every nested
58
+ * example (recursively). Each item carries `{ text, source }` where
59
+ * `source` is `<path>.content` rooted at the `path` argument.
60
+ */
61
+ *walkTexts(path: string): Generator<WalkTextEntry> {
62
+ if (typeof this.content === 'string' && this.content.length > 0) {
63
+ yield { text: this.content, source: `${path}.content` };
64
+ }
65
+ const examples = this.examples;
66
+ for (let i = 0; i < examples.length; i++) {
67
+ const example = examples[i];
68
+ if (example) {
69
+ yield* example.walkTexts(`${path}.examples[${i}]`);
70
+ }
71
+ }
72
+ }
73
+
74
+ static identityOf(
75
+ value: { toJSON?: () => unknown } | unknown | null,
76
+ ): string {
77
+ if (value == null) return '';
78
+ if (typeof value === 'object' && value !== null && 'toJSON' in value &&
79
+ typeof (value as { toJSON: unknown }).toJSON === 'function') {
80
+ return canonicalJson((value as { toJSON: () => unknown }).toJSON());
81
+ }
82
+ return canonicalJson(value);
83
+ }
84
+
85
+ override identity(): string {
86
+ return DetailedDefinition.identityOf(this);
87
+ }
88
+
89
+ static override fromJSON(data: DetailedDefinitionJson): DetailedDefinition {
90
+ return new DetailedDefinition(data);
91
+ }
92
+ }
@@ -0,0 +1,110 @@
1
+ import { SharedNonVerbalEntity } from './shared-non-verbal-entity.js';
2
+ import type { SharedNonVerbalEntityJson } from './shared-non-verbal-entity.js';
3
+ import { NonVerbalEntity } from './non-verbal-entity.js';
4
+
5
+ export interface FigureImageJson {
6
+ src?: string | null;
7
+ format?: string | null;
8
+ role?: string | null;
9
+ width?: number | string | null;
10
+ height?: number | string | null;
11
+ scale?: number | string | null;
12
+ }
13
+
14
+ export class FigureImage {
15
+ readonly src: string | null;
16
+ readonly format: string | null;
17
+ readonly role: string | null;
18
+ readonly width: number | string | null;
19
+ readonly height: number | string | null;
20
+ readonly scale: number | string | null;
21
+
22
+ constructor(data: FigureImageJson = {}) {
23
+ this.src = data.src ?? null;
24
+ this.format = data.format ?? null;
25
+ this.role = data.role ?? null;
26
+ this.width = data.width ?? null;
27
+ this.height = data.height ?? null;
28
+ this.scale = data.scale ?? null;
29
+ }
30
+
31
+ toJSON(): FigureImageJson {
32
+ const obj: FigureImageJson = {};
33
+ if (this.src != null) obj.src = this.src;
34
+ if (this.format != null) obj.format = this.format;
35
+ if (this.role != null) obj.role = this.role;
36
+ if (this.width != null) obj.width = this.width;
37
+ if (this.height != null) obj.height = this.height;
38
+ if (this.scale != null) obj.scale = this.scale;
39
+ return obj;
40
+ }
41
+
42
+ static fromJSON(data: FigureImageJson): FigureImage {
43
+ return new FigureImage(data);
44
+ }
45
+ }
46
+
47
+ export interface FigureJson extends SharedNonVerbalEntityJson {
48
+ images?: ReadonlyArray<FigureImageJson>;
49
+ subfigures?: ReadonlyArray<FigureJson | Figure>;
50
+ }
51
+
52
+ export class Figure extends SharedNonVerbalEntity {
53
+ protected readonly _rawImages: ReadonlyArray<FigureImageJson | FigureImage>;
54
+ protected readonly _rawSubfigures: ReadonlyArray<FigureJson | Figure>;
55
+ protected _images: ReadonlyArray<FigureImage> | null = null;
56
+ protected _subfigures: ReadonlyArray<Figure> | null = null;
57
+
58
+ constructor(data: FigureJson = {}) {
59
+ super(data);
60
+ this._rawImages = data.images ?? [];
61
+ this._rawSubfigures = data.subfigures ?? [];
62
+ }
63
+
64
+ override rdfClass(): string {
65
+ return 'Figure';
66
+ }
67
+
68
+ get images(): ReadonlyArray<FigureImage> {
69
+ return this._lazy<FigureImage>(
70
+ '_images',
71
+ '_rawImages',
72
+ (i) => (i instanceof FigureImage ? i : new FigureImage(i as FigureImageJson)),
73
+ );
74
+ }
75
+
76
+ get subfigures(): ReadonlyArray<Figure> {
77
+ return this._lazy<Figure>(
78
+ '_subfigures',
79
+ '_rawSubfigures',
80
+ (s) => (s instanceof Figure ? s : new Figure(s as FigureJson)),
81
+ );
82
+ }
83
+
84
+ override findById(targetId: string): this | null {
85
+ if (this.id === targetId) return this;
86
+ for (const sub of this.subfigures) {
87
+ const found = sub.findById(targetId);
88
+ if (found) return found as this;
89
+ }
90
+ return null;
91
+ }
92
+
93
+ override allIds(): string[] {
94
+ const ids = this.id != null ? [this.id] : [];
95
+ return [...ids, ...this.subfigures.flatMap((s) => s.allIds())];
96
+ }
97
+
98
+ override toJSON(): FigureJson {
99
+ const obj = super.toJSON() as FigureJson;
100
+ this._serialize(obj as unknown as Record<string, unknown>, 'images', '_images', '_rawImages');
101
+ this._serialize(obj as unknown as Record<string, unknown>, 'subfigures', '_subfigures', '_rawSubfigures');
102
+ return obj;
103
+ }
104
+
105
+ static override fromJSON(data: FigureJson): Figure {
106
+ return new Figure(data);
107
+ }
108
+ }
109
+
110
+ NonVerbalEntity.register('figure', Figure);
@@ -0,0 +1,36 @@
1
+ import { SharedNonVerbalEntity } from './shared-non-verbal-entity.js';
2
+ import type { SharedNonVerbalEntityJson } from './shared-non-verbal-entity.js';
3
+ import { NonVerbalEntity } from './non-verbal-entity.js';
4
+
5
+ export interface FormulaJson extends SharedNonVerbalEntityJson {
6
+ expression?: string | null;
7
+ notation?: string | null;
8
+ }
9
+
10
+ export class Formula extends SharedNonVerbalEntity {
11
+ readonly expression: string | null;
12
+ readonly notation: string | null;
13
+
14
+ constructor(data: FormulaJson = {}) {
15
+ super(data);
16
+ this.expression = data.expression ?? null;
17
+ this.notation = data.notation ?? null;
18
+ }
19
+
20
+ override rdfClass(): string {
21
+ return 'Formula';
22
+ }
23
+
24
+ override toJSON(): FormulaJson {
25
+ const obj = super.toJSON() as FormulaJson;
26
+ if (this.expression != null) obj.expression = this.expression;
27
+ if (this.notation != null) obj.notation = this.notation;
28
+ return obj;
29
+ }
30
+
31
+ static override fromJSON(data: FormulaJson): Formula {
32
+ return new Formula(data);
33
+ }
34
+ }
35
+
36
+ NonVerbalEntity.register('formula', Formula);
@@ -0,0 +1,78 @@
1
+ import { GlossaristModel } from './base.js';
2
+
3
+ export type GrammarGender = 'm' | 'f' | 'n' | 'c' | string;
4
+ export type GrammarNumber = 'singular' | 'dual' | 'plural' | string;
5
+ export type GrammarPartOfSpeech =
6
+ | 'noun'
7
+ | 'verb'
8
+ | 'adj'
9
+ | 'adverb'
10
+ | 'preposition'
11
+ | 'participle'
12
+ | string;
13
+
14
+ export const GRAMMAR_GENDERS: ReadonlyArray<string> = Object.freeze([
15
+ 'm', 'f', 'n', 'c',
16
+ ]);
17
+ export const GRAMMAR_NUMBERS: ReadonlyArray<string> = Object.freeze([
18
+ 'singular', 'dual', 'plural',
19
+ ]);
20
+ export const GRAMMAR_PARTS_OF_SPEECH: ReadonlyArray<string> = Object.freeze([
21
+ 'noun', 'verb', 'adj', 'adverb', 'preposition', 'participle',
22
+ ]);
23
+
24
+ export interface GrammarInfoJson {
25
+ gender?: GrammarGender | null;
26
+ number?: GrammarNumber | null;
27
+ part_of_speech?: GrammarPartOfSpeech | null;
28
+ partOfSpeech?: GrammarPartOfSpeech | null;
29
+ noun?: boolean;
30
+ verb?: boolean;
31
+ adj?: boolean;
32
+ adverb?: boolean;
33
+ preposition?: boolean;
34
+ participle?: boolean;
35
+ }
36
+
37
+ export class GrammarInfo extends GlossaristModel {
38
+ readonly gender: GrammarGender | null;
39
+ readonly number: GrammarNumber | null;
40
+ readonly partOfSpeech: GrammarPartOfSpeech | null;
41
+ readonly noun: boolean;
42
+ readonly verb: boolean;
43
+ readonly adj: boolean;
44
+ readonly adverb: boolean;
45
+ readonly preposition: boolean;
46
+ readonly participle: boolean;
47
+
48
+ constructor(data: GrammarInfoJson = {}) {
49
+ super();
50
+ this.gender = data.gender ?? null;
51
+ this.number = data.number ?? null;
52
+ this.partOfSpeech = data.part_of_speech ?? data.partOfSpeech ?? null;
53
+ this.noun = data.noun ?? false;
54
+ this.verb = data.verb ?? false;
55
+ this.adj = data.adj ?? false;
56
+ this.adverb = data.adverb ?? false;
57
+ this.preposition = data.preposition ?? false;
58
+ this.participle = data.participle ?? false;
59
+ }
60
+
61
+ override toJSON(): GrammarInfoJson {
62
+ const obj: GrammarInfoJson = {};
63
+ if (this.gender != null) obj.gender = this.gender;
64
+ if (this.number != null) obj.number = this.number;
65
+ if (this.partOfSpeech != null) obj.part_of_speech = this.partOfSpeech;
66
+ if (this.noun) obj.noun = true;
67
+ if (this.verb) obj.verb = true;
68
+ if (this.adj) obj.adj = true;
69
+ if (this.adverb) obj.adverb = true;
70
+ if (this.preposition) obj.preposition = true;
71
+ if (this.participle) obj.participle = true;
72
+ return obj;
73
+ }
74
+
75
+ static override fromJSON(data: GrammarInfoJson): GrammarInfo {
76
+ return new GrammarInfo(data);
77
+ }
78
+ }