linked-rolls 0.0.1 → 0.1.1
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 +48 -1
- package/lib/Assumption.d.ts +124 -0
- package/lib/Assumption.js +34 -0
- package/lib/Collation.d.ts +11 -0
- package/lib/ConditionState.d.ts +8 -3
- package/lib/ConditionState.js +0 -5
- package/lib/Edit.d.ts +44 -14
- package/lib/Edit.js +2 -95
- package/lib/Edition.d.ts +144 -4
- package/lib/EditionView.d.ts +51 -0
- package/lib/EditionView.js +294 -0
- package/lib/Emulation.d.ts +21 -68
- package/lib/Emulation.js +94 -386
- package/lib/Feature.d.ts +137 -16
- package/lib/Feature.js +9 -1
- package/lib/Plan.d.ts +190 -0
- package/lib/Plan.js +555 -0
- package/lib/ReproducingSystem.d.ts +80 -0
- package/lib/RollCopy.d.ts +265 -24
- package/lib/RollCopy.js +276 -215
- package/lib/Symbol.d.ts +70 -37
- package/lib/Symbol.js +2 -27
- package/lib/TrackCalibration.d.ts +33 -0
- package/lib/TrackCalibration.js +14 -0
- package/lib/TrackerBar.d.ts +52 -5
- package/lib/TrackerBar.js +70 -49
- package/lib/Version.d.ts +32 -33
- package/lib/Version.js +3 -209
- package/lib/alignFeatures.d.ts +3 -2
- package/lib/alignFeatures.js +5 -4
- package/lib/asJsonLd.d.ts +1 -1
- package/lib/asJsonLd.js +13 -26
- package/lib/importJsonLd.d.ts +0 -1
- package/lib/importJsonLd.js +9 -72
- package/lib/index.d.ts +7 -3
- package/lib/index.js +7 -3
- package/lib/schema.json +1739 -0
- package/lib/spec/context.json +125 -144
- package/lib/systems/welteT100.d.ts +55 -0
- package/lib/systems/welteT100.js +191 -0
- package/lib/utils.d.ts +29 -0
- package/lib/validate.d.ts +3 -0
- package/lib/validate.js +10 -0
- package/package.json +41 -8
- package/lib/Condition.d.ts +0 -10
- package/lib/EditorialAssumption.d.ts +0 -67
- package/lib/EditorialAssumption.js +0 -26
- package/lib/Measurement.d.ts +0 -9
- package/lib/PlaceTimeConversion.d.ts +0 -65
- package/lib/PlaceTimeConversion.js +0 -175
- package/lib/RollEvent.d.ts +0 -76
- package/lib/RollEvent.js +0 -3
- package/lib/Stage.d.ts +0 -37
- package/lib/Stage.js +0 -165
- package/lib/Transcription.d.ts +0 -7
- package/lib/Transcription.js +0 -9
- package/lib/WithId.d.ts +0 -3
- package/lib/WithId.js +0 -1
- package/lib/alignRolls.d.ts +0 -7
- package/lib/alignRolls.js +0 -49
- package/lib/alignSymbols.d.ts +0 -7
- package/lib/alignSymbols.js +0 -49
- package/lib/aton/AtonParser.test.d.ts +0 -1
- package/lib/aton/AtonParser.test.js +0 -16
- package/lib/build-schema.cjs +0 -113
- /package/lib/{Condition.js → ReproducingSystem.js} +0 -0
- /package/lib/{Measurement.js → utils.js} +0 -0
package/lib/Stage.js
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { v4 } from "uuid";
|
|
2
|
-
import { flat } from "./EditorialAssumption";
|
|
3
|
-
import { dimensionOf } from "./Symbol";
|
|
4
|
-
const versionType = [
|
|
5
|
-
/**
|
|
6
|
-
* The roll is in a state where it is used as
|
|
7
|
-
* the master roll for several new reproductions.
|
|
8
|
-
*/
|
|
9
|
-
'edition',
|
|
10
|
-
/**
|
|
11
|
-
* This denotes a stage which is specific to (early)
|
|
12
|
-
* Welte-Mignon piano rolls, where rolls inteded to
|
|
13
|
-
* be pulished are revised by a controller first. These
|
|
14
|
-
* rolls typically carry a "controlliert" stamp. The
|
|
15
|
-
* revision is done on the same date as the perforation
|
|
16
|
-
* and the date is written on the roll towards its end.
|
|
17
|
-
*/
|
|
18
|
-
'authorised-revision',
|
|
19
|
-
/**
|
|
20
|
-
* Unauthorised revisions are those, which cannot be linked
|
|
21
|
-
* to a specific controller and are likely done by
|
|
22
|
-
* a later, anonymous hand.
|
|
23
|
-
*/
|
|
24
|
-
'unauthorised-revision',
|
|
25
|
-
/**
|
|
26
|
-
* In the case of Welte Mignon rolls, glosses are
|
|
27
|
-
* typically comments about the roll's condition, added
|
|
28
|
-
* e.g. by the collector.
|
|
29
|
-
*/
|
|
30
|
-
'gloss'
|
|
31
|
-
];
|
|
32
|
-
export const traverseStages = (stage, callback) => {
|
|
33
|
-
callback(stage);
|
|
34
|
-
if (stage.basedOn) {
|
|
35
|
-
traverseStages(flat(stage.basedOn), callback);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
export const getSnapshot = (stage) => {
|
|
39
|
-
const snapshot = [];
|
|
40
|
-
const toDelete = [];
|
|
41
|
-
traverseStages(stage, s => {
|
|
42
|
-
snapshot.push(...s.edits.flatMap(edit => edit.insert || []));
|
|
43
|
-
// as we travel further up, remove symbols that are
|
|
44
|
-
// deleted in the stages further down
|
|
45
|
-
const deleted = [];
|
|
46
|
-
for (const toRemove of toDelete) {
|
|
47
|
-
const index = snapshot.findIndex(s => s === toRemove);
|
|
48
|
-
if (index !== -1) {
|
|
49
|
-
snapshot.splice(index, 1);
|
|
50
|
-
deleted.push(toRemove);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
for (const del of deleted) {
|
|
54
|
-
toDelete.splice(toDelete.indexOf(del), 1);
|
|
55
|
-
}
|
|
56
|
-
// collect symbols that are deleted in the current stage
|
|
57
|
-
toDelete.push(...s.edits.flatMap(edit => edit.delete || []));
|
|
58
|
-
});
|
|
59
|
-
return snapshot.sort((a, b) => {
|
|
60
|
-
const aDimension = dimensionOf(a);
|
|
61
|
-
const bDimension = dimensionOf(b);
|
|
62
|
-
return aDimension.horizontal.from - bDimension.horizontal.from;
|
|
63
|
-
});
|
|
64
|
-
};
|
|
65
|
-
const isCollatable = (symbolA, symbolB) => {
|
|
66
|
-
// two symbols are collatible if they share the same
|
|
67
|
-
// symbol characteristics (pitch, expression type etc.)
|
|
68
|
-
// and occur in the same horizontal position.
|
|
69
|
-
if (symbolA.type === 'note' && symbolB.type === 'note') {
|
|
70
|
-
if (symbolA.pitch !== symbolB.pitch)
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
else if (symbolA.type === 'expression' && symbolB.type === 'expression') {
|
|
74
|
-
if (symbolA.expressionType !== symbolB.expressionType)
|
|
75
|
-
return false;
|
|
76
|
-
if (symbolA.scope !== symbolB.scope)
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
const dimensionA = dimensionOf(symbolA);
|
|
80
|
-
const dimensionB = dimensionOf(symbolB);
|
|
81
|
-
const distanceStart = Math.abs(dimensionA.horizontal.from - dimensionB.horizontal.from);
|
|
82
|
-
const distanceEnd = Math.abs(dimensionA.horizontal.to - dimensionB.horizontal.to);
|
|
83
|
-
if (distanceStart > 5 || distanceEnd > 5) {
|
|
84
|
-
// the symbols are too far apart to be collated
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
return true;
|
|
88
|
-
};
|
|
89
|
-
const overlaps = (a, b) => {
|
|
90
|
-
const overlapsDimension = (a, b) => (a.from ?? 0) < (b.to ?? Infinity) && (b.from ?? 0) < (a.to ?? Infinity);
|
|
91
|
-
return overlapsDimension(a.horizontal, b.horizontal) && overlapsDimension(a.vertical, b.vertical);
|
|
92
|
-
};
|
|
93
|
-
/**
|
|
94
|
-
* Walks through the stages. If it finds a symbol that is still
|
|
95
|
-
* part of the tradition (i.e. it is included in the current snapshot)
|
|
96
|
-
* and is equivalent with the given symbol, it will add the feature
|
|
97
|
-
* carrying the symbol to the collated symbol. Otherwise, the
|
|
98
|
-
* given symbol will be added to the current stage's insertions.
|
|
99
|
-
*
|
|
100
|
-
* All symbols of the tradition that are not included in the given
|
|
101
|
-
* symbols are considered to be deleted.
|
|
102
|
-
*
|
|
103
|
-
* @param creation
|
|
104
|
-
* @param symbols
|
|
105
|
-
* @returns
|
|
106
|
-
*/
|
|
107
|
-
export function fillEdits(currentStage, symbols) {
|
|
108
|
-
const snapshot = getSnapshot(currentStage);
|
|
109
|
-
const treatedSymbols = [];
|
|
110
|
-
// can it be collated with any of the symbols of
|
|
111
|
-
// included in the current snapshot?
|
|
112
|
-
const insertions = [...symbols];
|
|
113
|
-
for (const symbol of symbols) {
|
|
114
|
-
snapshot
|
|
115
|
-
.filter(toCompare => isCollatable(symbol, toCompare))
|
|
116
|
-
.forEach(corresp => {
|
|
117
|
-
corresp.carriers.push(...symbol.carriers);
|
|
118
|
-
insertions.splice(insertions.indexOf(symbol), 1);
|
|
119
|
-
treatedSymbols.push(corresp);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
// special treatment for covers
|
|
123
|
-
const covers = insertions.filter(symbol => symbol.type === 'cover');
|
|
124
|
-
for (const cover of covers) {
|
|
125
|
-
// find perforations in the snapshot that
|
|
126
|
-
// overlap with the cover
|
|
127
|
-
snapshot
|
|
128
|
-
.filter(symbol => symbol.type === 'note' || symbol.type === 'expression')
|
|
129
|
-
.map(dimensionOf)
|
|
130
|
-
.filter(dimension => overlaps(dimension, dimensionOf(cover)))
|
|
131
|
-
.forEach(dimension => {
|
|
132
|
-
const coverDimension = dimensionOf(cover);
|
|
133
|
-
// check if the cover partially covers the beginning
|
|
134
|
-
if (dimension.horizontal.from >= coverDimension.horizontal.from &&
|
|
135
|
-
dimension.horizontal.from <= coverDimension.horizontal.to) {
|
|
136
|
-
// the note starts where the cover ends
|
|
137
|
-
dimension.horizontal.from = coverDimension.horizontal.to;
|
|
138
|
-
}
|
|
139
|
-
// check if the cover partially covers the ending
|
|
140
|
-
if (dimension.horizontal.to >= coverDimension.horizontal.from &&
|
|
141
|
-
dimension.horizontal.to <= coverDimension.horizontal.to) {
|
|
142
|
-
// the note ends where the cover starts
|
|
143
|
-
dimension.horizontal.to = coverDimension.horizontal.from;
|
|
144
|
-
}
|
|
145
|
-
});
|
|
146
|
-
insertions.splice(insertions.indexOf(cover), 1);
|
|
147
|
-
}
|
|
148
|
-
currentStage.edits.push(...insertions.map((symbol) => {
|
|
149
|
-
return {
|
|
150
|
-
insert: [symbol],
|
|
151
|
-
delete: [],
|
|
152
|
-
id: v4(),
|
|
153
|
-
};
|
|
154
|
-
}));
|
|
155
|
-
const deletions = snapshot.filter(sym => {
|
|
156
|
-
return !treatedSymbols.includes(sym);
|
|
157
|
-
});
|
|
158
|
-
for (const symbol of deletions) {
|
|
159
|
-
currentStage.edits.push({
|
|
160
|
-
insert: [],
|
|
161
|
-
delete: [symbol],
|
|
162
|
-
id: v4(),
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
}
|
package/lib/Transcription.d.ts
DELETED
package/lib/Transcription.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
// Example:
|
|
3
|
-
// Edit -> carried out by -> "Anonym"
|
|
4
|
-
// Edit -> concluded by -> Observation: der äußeren Erscheinung nach eine spätere Hinzufügung von unbekanntere Hand
|
|
5
|
-
// Edit -> insert -> Symbol
|
|
6
|
-
// Symbol -> is carried by -> Roll Feature -> condition -> damaged
|
|
7
|
-
// Symbol -> concludedBy -> Transcription -> Die Perforationen wurden nicht präzise an die richtige Stelle gesetzt.
|
|
8
|
-
// Wir gehen davon aus, dass sie jeweils auf der darüberliegenden Linie
|
|
9
|
-
// platziert werden sollten.
|
package/lib/WithId.d.ts
DELETED
package/lib/WithId.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/lib/alignRolls.d.ts
DELETED
package/lib/alignRolls.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { dimensionOf } from "./Symbol";
|
|
2
|
-
export function alignSymbols(rollA, rollB) {
|
|
3
|
-
// 1. Only musical-note anchors
|
|
4
|
-
const XA = rollA.filter(e => e.type === 'note').map(e => dimensionOf(e).horizontal.from);
|
|
5
|
-
const YB = rollB.filter(e => e.type === 'note').map(e => dimensionOf(e).horizontal.from);
|
|
6
|
-
// 2. Initial LSQ fit for x2 = A*x + B
|
|
7
|
-
let { A, B } = fitAffine(XA, YB);
|
|
8
|
-
let stretch = A, shift = B / A;
|
|
9
|
-
// 3. Refinement
|
|
10
|
-
for (let i = 0; i < 10; i++) {
|
|
11
|
-
const transformed = XA.map(x => stretch * (x + shift));
|
|
12
|
-
const pairs = [];
|
|
13
|
-
for (let tx of transformed) {
|
|
14
|
-
const nearest = findClosest(tx, YB);
|
|
15
|
-
if (Math.abs(tx - nearest) <= 3) {
|
|
16
|
-
pairs.push([(tx / stretch) - shift, nearest]);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
if (pairs.length < 2)
|
|
20
|
-
break;
|
|
21
|
-
const [Xin, Yin] = unzip(pairs);
|
|
22
|
-
const { A: A2, B: B2 } = fitAffine(Xin, Yin);
|
|
23
|
-
const b2 = B2 / A2;
|
|
24
|
-
if (Math.abs(A2 - A) < 1e-6 && Math.abs(b2 - shift) < 1e-3)
|
|
25
|
-
break;
|
|
26
|
-
A = A2;
|
|
27
|
-
B = B2;
|
|
28
|
-
stretch = A;
|
|
29
|
-
shift = b2;
|
|
30
|
-
}
|
|
31
|
-
return { stretch: stretch, shift: shift };
|
|
32
|
-
}
|
|
33
|
-
const mean = (arr) => arr.reduce((acc, val) => acc + val, 0) / arr.length;
|
|
34
|
-
function fitAffine(X, Y) {
|
|
35
|
-
const mx = mean(X), my = mean(Y);
|
|
36
|
-
let num = 0, den = 0;
|
|
37
|
-
X.forEach((x, i) => { num += (x - mx) * (Y[i] - my); den += (x - mx) ** 2; });
|
|
38
|
-
const A = den === 0 ? 1 : num / den;
|
|
39
|
-
const B = my - A * mx;
|
|
40
|
-
return { A, B };
|
|
41
|
-
}
|
|
42
|
-
function findClosest(val, arr) {
|
|
43
|
-
return arr.reduce((best, curr) => Math.abs(curr - val) < Math.abs(best - val) ? curr : best);
|
|
44
|
-
}
|
|
45
|
-
function unzip(p) {
|
|
46
|
-
const X = [], Y = [];
|
|
47
|
-
p.forEach(([x, y]) => { X.push(x); Y.push(y); });
|
|
48
|
-
return [X, Y];
|
|
49
|
-
}
|
package/lib/alignSymbols.d.ts
DELETED
package/lib/alignSymbols.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { dimensionOf } from "./Symbol";
|
|
2
|
-
export function alignSymbols(rollA, rollB) {
|
|
3
|
-
// 1. Only musical-note anchors
|
|
4
|
-
const XA = rollA.filter(e => e.type === 'note').map(e => dimensionOf(e).horizontal.from);
|
|
5
|
-
const YB = rollB.filter(e => e.type === 'note').map(e => dimensionOf(e).horizontal.from);
|
|
6
|
-
// 2. Initial LSQ fit for x2 = A*x + B
|
|
7
|
-
let { A, B } = fitAffine(XA, YB);
|
|
8
|
-
let stretch = A, shift = B / A;
|
|
9
|
-
// 3. Refinement
|
|
10
|
-
for (let i = 0; i < 10; i++) {
|
|
11
|
-
const transformed = XA.map(x => stretch * (x + shift));
|
|
12
|
-
const pairs = [];
|
|
13
|
-
for (let tx of transformed) {
|
|
14
|
-
const nearest = findClosest(tx, YB);
|
|
15
|
-
if (Math.abs(tx - nearest) <= 3) {
|
|
16
|
-
pairs.push([(tx / stretch) - shift, nearest]);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
if (pairs.length < 2)
|
|
20
|
-
break;
|
|
21
|
-
const [Xin, Yin] = unzip(pairs);
|
|
22
|
-
const { A: A2, B: B2 } = fitAffine(Xin, Yin);
|
|
23
|
-
const b2 = B2 / A2;
|
|
24
|
-
if (Math.abs(A2 - A) < 1e-6 && Math.abs(b2 - shift) < 1e-3)
|
|
25
|
-
break;
|
|
26
|
-
A = A2;
|
|
27
|
-
B = B2;
|
|
28
|
-
stretch = A;
|
|
29
|
-
shift = b2;
|
|
30
|
-
}
|
|
31
|
-
return { stretch: stretch, shift: shift };
|
|
32
|
-
}
|
|
33
|
-
const mean = (arr) => arr.reduce((acc, val) => acc + val, 0) / arr.length;
|
|
34
|
-
function fitAffine(X, Y) {
|
|
35
|
-
const mx = mean(X), my = mean(Y);
|
|
36
|
-
let num = 0, den = 0;
|
|
37
|
-
X.forEach((x, i) => { num += (x - mx) * (Y[i] - my); den += (x - mx) ** 2; });
|
|
38
|
-
const A = den === 0 ? 1 : num / den;
|
|
39
|
-
const B = my - A * mx;
|
|
40
|
-
return { A, B };
|
|
41
|
-
}
|
|
42
|
-
function findClosest(val, arr) {
|
|
43
|
-
return arr.reduce((best, curr) => Math.abs(curr - val) < Math.abs(best - val) ? curr : best);
|
|
44
|
-
}
|
|
45
|
-
function unzip(p) {
|
|
46
|
-
const X = [], Y = [];
|
|
47
|
-
p.forEach(([x, y]) => { X.push(x); Y.push(y); });
|
|
48
|
-
return [X, Y];
|
|
49
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { expect, test } from 'vitest';
|
|
2
|
-
import { AtonParser } from './AtonParser';
|
|
3
|
-
test('it import ATON files correctly', () => {
|
|
4
|
-
const parser = new AtonParser();
|
|
5
|
-
const result = parser.parse(`
|
|
6
|
-
@key1: value1
|
|
7
|
-
@@START: key2
|
|
8
|
-
@key2a: value2a
|
|
9
|
-
@key2b: value2b
|
|
10
|
-
@key2c: value2c
|
|
11
|
-
@@END: key2
|
|
12
|
-
@key3: value3`);
|
|
13
|
-
expect(result.key1).toBe('value1');
|
|
14
|
-
expect(result.key2.key2a).toBe('value2a');
|
|
15
|
-
expect(result.key3).toBe('value3');
|
|
16
|
-
});
|
package/lib/build-schema.cjs
DELETED
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
16
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
17
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
18
|
-
}
|
|
19
|
-
Object.defineProperty(o, k2, desc);
|
|
20
|
-
}) : (function(o, m, k, k2) {
|
|
21
|
-
if (k2 === undefined) k2 = k;
|
|
22
|
-
o[k2] = m[k];
|
|
23
|
-
}));
|
|
24
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
25
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
26
|
-
}) : function(o, v) {
|
|
27
|
-
o["default"] = v;
|
|
28
|
-
});
|
|
29
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
30
|
-
var ownKeys = function(o) {
|
|
31
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
32
|
-
var ar = [];
|
|
33
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
34
|
-
return ar;
|
|
35
|
-
};
|
|
36
|
-
return ownKeys(o);
|
|
37
|
-
};
|
|
38
|
-
return function (mod) {
|
|
39
|
-
if (mod && mod.__esModule) return mod;
|
|
40
|
-
var result = {};
|
|
41
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
42
|
-
__setModuleDefault(result, mod);
|
|
43
|
-
return result;
|
|
44
|
-
};
|
|
45
|
-
})();
|
|
46
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
47
|
-
// build-schema.ts
|
|
48
|
-
var ts_json_schema_generator_1 = require("ts-json-schema-generator");
|
|
49
|
-
var fs = __importStar(require("fs"));
|
|
50
|
-
/** Safely check if a referenced type is an ObjectType with a string `id` property. */
|
|
51
|
-
function refTargetsRefableObject(ref, fmt) {
|
|
52
|
-
var _a;
|
|
53
|
-
var target = ref.getType();
|
|
54
|
-
// console.log('target', target, target instanceof ObjectType)
|
|
55
|
-
// if (!(target instanceof ObjectType)) return false;
|
|
56
|
-
// Ask the default formatter for the *object's* definition and inspect its properties.
|
|
57
|
-
// This is safe because 'target' isn't a ReferenceType, so the built-ins will produce
|
|
58
|
-
// the object schema (possibly via $ref creation behind the scenes).
|
|
59
|
-
var def = fmt.getDefinition(target);
|
|
60
|
-
console.log('def=', def);
|
|
61
|
-
var idSchema = (_a = def === null || def === void 0 ? void 0 : def.properties) === null || _a === void 0 ? void 0 : _a.id;
|
|
62
|
-
if (!idSchema)
|
|
63
|
-
return false;
|
|
64
|
-
// Accept plain string or unions that contain string
|
|
65
|
-
return idSchema.type === "string" ||
|
|
66
|
-
(Array.isArray(idSchema.anyOf) && idSchema.anyOf.some(function (s) { return (s === null || s === void 0 ? void 0 : s.type) === "string"; }));
|
|
67
|
-
}
|
|
68
|
-
/** Wrap only ReferenceType occurrences to ref-able objects as oneOf($ref, "#id"). */
|
|
69
|
-
var RefableReferenceWrapper = /** @class */ (function () {
|
|
70
|
-
function RefableReferenceWrapper(child) {
|
|
71
|
-
this.child = child;
|
|
72
|
-
}
|
|
73
|
-
// Only intercept ReferenceType; let built-ins handle everything else.
|
|
74
|
-
RefableReferenceWrapper.prototype.supportsType = function (type) {
|
|
75
|
-
return type instanceof ts_json_schema_generator_1.ReferenceType;
|
|
76
|
-
};
|
|
77
|
-
RefableReferenceWrapper.prototype.getDefinition = function (type) {
|
|
78
|
-
console.log('ref type', type);
|
|
79
|
-
var isRefable = type.getType().type.type.properties.findIndex(function (p) { return p.name === 'id'; }) !== -1;
|
|
80
|
-
// Let the built-in ReferenceTypeFormatter do its thing first ($ref, etc.)
|
|
81
|
-
var original = this.child.getDefinition(type);
|
|
82
|
-
// If the reference points to an object with string `id`, allow "#id" as alternative.
|
|
83
|
-
if (isRefable) {
|
|
84
|
-
console.log('is refable', type);
|
|
85
|
-
// Avoid double-wrapping if something upstream already produced oneOf.
|
|
86
|
-
if (original && original.oneOf)
|
|
87
|
-
return original;
|
|
88
|
-
return original;
|
|
89
|
-
//return {
|
|
90
|
-
// oneOf: [
|
|
91
|
-
// original, // usually { "$ref": "#/definitions/..." }
|
|
92
|
-
// { type: "string", pattern: "^#.+$" }, // your "#<id>" form; tighten regex if needed
|
|
93
|
-
// ],
|
|
94
|
-
// };
|
|
95
|
-
}
|
|
96
|
-
return original;
|
|
97
|
-
};
|
|
98
|
-
RefableReferenceWrapper.prototype.getChildren = function (type) {
|
|
99
|
-
// Always delegate. Do NOT call .getType() here—let the chain manage traversal.
|
|
100
|
-
return this.child.getChildren(type);
|
|
101
|
-
};
|
|
102
|
-
return RefableReferenceWrapper;
|
|
103
|
-
}());
|
|
104
|
-
// ——— Wire up the generator ———
|
|
105
|
-
var config = __assign(__assign({}, ts_json_schema_generator_1.DEFAULT_CONFIG), { path: "../src/**/*.ts", tsconfig: "tsconfig.json", type: "Edition" });
|
|
106
|
-
var formatter = (0, ts_json_schema_generator_1.createFormatter)(config, function (fmt, circular) {
|
|
107
|
-
fmt.addTypeFormatter(new RefableReferenceWrapper(circular));
|
|
108
|
-
});
|
|
109
|
-
var program = (0, ts_json_schema_generator_1.createProgram)(config);
|
|
110
|
-
var parser = (0, ts_json_schema_generator_1.createParser)(program, config);
|
|
111
|
-
var generator = new ts_json_schema_generator_1.SchemaGenerator(program, parser, formatter, config);
|
|
112
|
-
var schema = generator.createSchema(config.type);
|
|
113
|
-
fs.writeFileSync("./context.json", JSON.stringify(schema, null, 2));
|
|
File without changes
|
|
File without changes
|