@tallyrelease/core 0.5.0-beta.21 → 0.5.0-beta.31
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/dist/affected.d.ts +1 -42
- package/dist/branches.d.ts +5 -53
- package/dist/bump.d.ts +27 -0
- package/dist/bump.js +48 -0
- package/dist/changelog.d.ts +1 -1
- package/dist/explain.d.ts +1 -1
- package/dist/facts.d.ts +2 -83
- package/dist/index.d.ts +4 -3
- package/dist/model/affected-types.d.ts +42 -0
- package/dist/model/affected-types.js +1 -0
- package/dist/model/branch-types.d.ts +57 -0
- package/dist/model/branch-types.js +1 -0
- package/dist/model/facts-types.d.ts +83 -0
- package/dist/model/facts-types.js +1 -0
- package/dist/model/plan-types.d.ts +106 -0
- package/dist/model/plan-types.js +1 -0
- package/dist/plan.d.ts +3 -107
- package/dist/plan.js +3 -1
- package/dist/release-as.d.ts +33 -0
- package/dist/release-as.js +101 -0
- package/dist/release-items.d.ts +1 -1
- package/dist/release-settings.d.ts +30 -0
- package/dist/release-settings.js +38 -0
- package/dist/release.d.ts +5 -72
- package/dist/release.js +3 -243
- package/dist/released.d.ts +1 -1
- package/dist/version-files.d.ts +1 -1
- package/dist/version-math.d.ts +36 -0
- package/dist/version-math.js +55 -0
- package/dist/workspace.d.ts +1 -1
- package/dist/workspace.js +1 -1
- package/package.json +1 -1
package/dist/release.js
CHANGED
|
@@ -1,246 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { ownBump, unitChanges } from "./bump.js";
|
|
2
|
+
import { appliedValue, commitValues, pickReleaseAs } from "./release-as.js";
|
|
3
3
|
import { compare, maxLevel, uniqueSorted } from "./util.js";
|
|
4
|
-
|
|
5
|
-
feat: "minor",
|
|
6
|
-
fix: "patch",
|
|
7
|
-
perf: "patch",
|
|
8
|
-
revert: "patch",
|
|
9
|
-
};
|
|
10
|
-
/** Release-As values per commit for one unit, in range order. */
|
|
11
|
-
const commitValues = (id, changes) => {
|
|
12
|
-
const commits = new Map();
|
|
13
|
-
changes.forEach(({ change, units }, i) => {
|
|
14
|
-
const key = change.sha ?? `#${String(i)}`;
|
|
15
|
-
const entry = commits.get(key) ?? {
|
|
16
|
-
...(change.sha === undefined ? {} : { sha: change.sha }),
|
|
17
|
-
qualified: [],
|
|
18
|
-
plain: [],
|
|
19
|
-
};
|
|
20
|
-
commits.set(key, entry);
|
|
21
|
-
for (const r of change.releaseAs ?? []) {
|
|
22
|
-
if (r.unit === id) {
|
|
23
|
-
entry.qualified.push(r.version);
|
|
24
|
-
}
|
|
25
|
-
else if (r.unit === undefined && units.includes(id)) {
|
|
26
|
-
entry.plain.push(r.version);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
return [...commits.values()].map(({ qualified, plain, ...rest }) => ({
|
|
31
|
-
...rest,
|
|
32
|
-
values: qualified.length > 0 ? qualified : plain,
|
|
33
|
-
}));
|
|
34
|
-
};
|
|
35
|
-
const at = (sha) => (sha === undefined ? "" : ` in ${sha}`);
|
|
36
|
-
/** A Release-As value without a single leading `v`, parsed by the scheme. */
|
|
37
|
-
const parseReleaseAs = (scheme, raw) => scheme.parse(raw.startsWith("v") ? raw.slice(1) : raw);
|
|
38
|
-
/** Why a parsed Release-As value is ignored, else undefined. */
|
|
39
|
-
const releaseAsProblem = (scheme, version, from) => {
|
|
40
|
-
if (scheme.isPrerelease(version)) {
|
|
41
|
-
return "is a prerelease";
|
|
42
|
-
}
|
|
43
|
-
return from && scheme.compare(version, from.version) <= 0
|
|
44
|
-
? `does not exceed ${from.label}`
|
|
45
|
-
: undefined;
|
|
46
|
-
};
|
|
47
|
-
/** Newest valid value wins; invalid values and other values warn. */
|
|
48
|
-
const pickReleaseAs = (input, warnings) => {
|
|
49
|
-
const { unit, scheme, from, commits } = input;
|
|
50
|
-
let winner;
|
|
51
|
-
for (const { sha, values } of commits) {
|
|
52
|
-
for (const raw of values) {
|
|
53
|
-
const version = parseReleaseAs(scheme, raw);
|
|
54
|
-
const problem = version === undefined
|
|
55
|
-
? `is not a ${unit.scheme} version`
|
|
56
|
-
: releaseAsProblem(scheme, version, from);
|
|
57
|
-
if (problem !== undefined || version === undefined) {
|
|
58
|
-
warnings.push(coreCodes.warning("W_RELEASE_AS_INVALID", `unit "${unit.id}": Release-As "${raw}"${at(sha)} ${problem ?? ""}; ignored`, { unit: unit.id }));
|
|
59
|
-
}
|
|
60
|
-
else if (!winner) {
|
|
61
|
-
winner = { ...(sha === undefined ? {} : { sha }), raw, version };
|
|
62
|
-
}
|
|
63
|
-
else if (scheme.compare(version, winner.version) !== 0) {
|
|
64
|
-
warnings.push(coreCodes.warning("W_RELEASE_AS_CONFLICT", `unit "${unit.id}": Release-As "${winner.raw}"${at(winner.sha)} wins over "${raw}"${at(sha)}`, { unit: unit.id }));
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
return winner;
|
|
69
|
-
};
|
|
70
|
-
/**
|
|
71
|
-
* Level of one change. While the major is 0, breaking changes use
|
|
72
|
-
* `preMajor.breaking` and changes whose type level is minor `preMajor.feat`.
|
|
73
|
-
* An absorbed change contributes `bumps.absorbed` when its own level is set
|
|
74
|
-
* (`minor` caps it at minor).
|
|
75
|
-
*/
|
|
76
|
-
const changeLevel = ({ change, via }, settings, preMajor) => {
|
|
77
|
-
const typed = settings.bumps.get(change.type) ?? null;
|
|
78
|
-
const level = change.breaking
|
|
79
|
-
? preMajor
|
|
80
|
-
? settings.preMajor.breaking
|
|
81
|
-
: "major"
|
|
82
|
-
: preMajor && typed === "minor"
|
|
83
|
-
? settings.preMajor.feat
|
|
84
|
-
: typed;
|
|
85
|
-
if (via === undefined || level === null) {
|
|
86
|
-
return level;
|
|
87
|
-
}
|
|
88
|
-
return settings.absorbed === "minor" && level !== "patch" ? "minor" : "patch";
|
|
89
|
-
};
|
|
90
|
-
/** Max level over the changes. */
|
|
91
|
-
const ownBump = (changes, settings, preMajor) => changes.reduce((bump, change) => maxLevel(bump, changeLevel(change, settings, preMajor)), null);
|
|
92
|
-
/** Changes of the range attributed to the unit or to an absorbed unit. */
|
|
93
|
-
const unitChanges = (id, range, absorbed) => range.changes.flatMap(({ change, units }) => {
|
|
94
|
-
if (units.includes(id)) {
|
|
95
|
-
return [{ change }];
|
|
96
|
-
}
|
|
97
|
-
const via = units.find((u) => absorbed.has(u));
|
|
98
|
-
return via === undefined ? [] : [{ change, via }];
|
|
99
|
-
});
|
|
100
|
-
/** Warns when a first release's initial version is not above the unit's highest prerelease tag. */
|
|
101
|
-
const initialBelowPrerelease = (scheme, initial, facts) => {
|
|
102
|
-
const highest = facts.tags
|
|
103
|
-
.filter((t) => {
|
|
104
|
-
const v = scheme.parse(t.version);
|
|
105
|
-
return v !== undefined && scheme.isPrerelease(v);
|
|
106
|
-
})
|
|
107
|
-
.at(-1);
|
|
108
|
-
const version = highest && scheme.parse(highest.version);
|
|
109
|
-
if (!highest || version === undefined) {
|
|
110
|
-
return [];
|
|
111
|
-
}
|
|
112
|
-
return scheme.compare(initial, version) > 0
|
|
113
|
-
? []
|
|
114
|
-
: [
|
|
115
|
-
coreCodes.warning("W_INITIAL_BELOW_PRERELEASE", `unit "${facts.id}": initial version ${scheme.format(initial)} does not exceed prerelease tag "${highest.name}"`, { unit: facts.id }),
|
|
116
|
-
];
|
|
117
|
-
};
|
|
118
|
-
/** Normalized value of the first valid Release-As of a commit. */
|
|
119
|
-
const appliedValue = (scheme, values) => {
|
|
120
|
-
for (const raw of values) {
|
|
121
|
-
const version = parseReleaseAs(scheme, raw);
|
|
122
|
-
if (version !== undefined && !scheme.isPrerelease(version)) {
|
|
123
|
-
return scheme.format(version);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return undefined;
|
|
127
|
-
};
|
|
128
|
-
/** The `from` version of a unit, from `facts.fromTag`. */
|
|
129
|
-
const fromOf = (scheme, facts) => {
|
|
130
|
-
const tag = facts.fromTag;
|
|
131
|
-
const version = tag === null ? undefined : scheme.parse(tag.version);
|
|
132
|
-
return tag === null || version === undefined
|
|
133
|
-
? undefined
|
|
134
|
-
: {
|
|
135
|
-
version,
|
|
136
|
-
label: facts.group === null
|
|
137
|
-
? tag.version
|
|
138
|
-
: `${tag.version} (group ${facts.group})`,
|
|
139
|
-
};
|
|
140
|
-
};
|
|
141
|
-
/** `from` bumped by `bump`; the initial version on a first release. */
|
|
142
|
-
const bumpedOf = (scheme, bump, { from, initial }) => bump === null
|
|
143
|
-
? undefined
|
|
144
|
-
: from === undefined
|
|
145
|
-
? initial
|
|
146
|
-
: scheme.bump(from.version, bump);
|
|
147
|
-
const ctxOf = (unit, head, at) => ({
|
|
148
|
-
unit,
|
|
149
|
-
head,
|
|
150
|
-
baseTag: at.baseTag?.name ?? null,
|
|
151
|
-
tags: at.tags,
|
|
152
|
-
firstParent: { sinceLineBase: at.sinceLineBase, total: at.total },
|
|
153
|
-
});
|
|
154
|
-
const initialOf = (unit, scheme) => (unit.initialVersion === null
|
|
155
|
-
? undefined
|
|
156
|
-
: scheme.parse(unit.initialVersion)) ?? scheme.initial();
|
|
157
|
-
/** `next` and prerelease of `raw` under `ctx`. */
|
|
158
|
-
const render = ({ scheme, raw, ctx, channel, }) => ({
|
|
159
|
-
next: raw === undefined ? null : scheme.format(scheme.release(raw, ctx)),
|
|
160
|
-
prerelease: raw === undefined || channel === null
|
|
161
|
-
? null
|
|
162
|
-
: scheme.format(scheme.prerelease(raw, { ...ctx, channel })),
|
|
163
|
-
});
|
|
164
|
-
/**
|
|
165
|
-
* Unreleased units reachable over `id`'s dependencies, never stepping into or
|
|
166
|
-
* through a released unit.
|
|
167
|
-
*/
|
|
168
|
-
export const reach = (id, dependencies, released) => {
|
|
169
|
-
const found = new Set();
|
|
170
|
-
const queue = [id];
|
|
171
|
-
for (const v of queue) {
|
|
172
|
-
for (const w of dependencies.get(v) ?? []) {
|
|
173
|
-
if (!released.has(w) && !found.has(w)) {
|
|
174
|
-
found.add(w);
|
|
175
|
-
queue.push(w);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
return found;
|
|
180
|
-
};
|
|
181
|
-
/** Applies the defaults to `bumps` and `branches`. */
|
|
182
|
-
export const releaseSettings = (config, units) => ({
|
|
183
|
-
bumps: new Map(Object.entries({ ...DEFAULT_TYPES, ...config.bumps?.types })),
|
|
184
|
-
absorbed: config.bumps?.absorbed ?? "patch",
|
|
185
|
-
preMajor: {
|
|
186
|
-
breaking: config.bumps?.preMajor?.breaking ?? "minor",
|
|
187
|
-
feat: config.bumps?.preMajor?.feat ?? "minor",
|
|
188
|
-
},
|
|
189
|
-
branches: (config.branches ?? []).map((b) => ({
|
|
190
|
-
name: b.name,
|
|
191
|
-
line: b.line,
|
|
192
|
-
channel: b.channel ?? null,
|
|
193
|
-
unit: b.unit ?? null,
|
|
194
|
-
group: b.group ?? null,
|
|
195
|
-
})),
|
|
196
|
-
releasePr: {
|
|
197
|
-
default: config.defaults?.releasePr ?? "shared",
|
|
198
|
-
units: new Map(Object.entries(config.units ?? {}).flatMap(([root, overlay]) => {
|
|
199
|
-
const unit = units.find((u) => u.root === normalizeRoot(root));
|
|
200
|
-
return unit && overlay.releasePr
|
|
201
|
-
? [[unit.id, overlay.releasePr]]
|
|
202
|
-
: [];
|
|
203
|
-
})),
|
|
204
|
-
groups: new Map(Object.entries(config.groups ?? {}).flatMap(([name, group]) => group.releasePr ? [[name, group.releasePr]] : [])),
|
|
205
|
-
},
|
|
206
|
-
floating: config.tags?.floating ?? [],
|
|
207
|
-
templates: new Map(Object.entries(config.units ?? {}).flatMap(([root, overlay]) => {
|
|
208
|
-
const unit = units.find((u) => u.root === normalizeRoot(root));
|
|
209
|
-
return unit && overlay.versionFiles
|
|
210
|
-
? [[unit.id, overlay.versionFiles]]
|
|
211
|
-
: [];
|
|
212
|
-
})),
|
|
213
|
-
});
|
|
214
|
-
/**
|
|
215
|
-
* Warns for qualified Release-As values naming unknown or unreleased units and
|
|
216
|
-
* for plain values on commits attributed to no released unit.
|
|
217
|
-
*/
|
|
218
|
-
export const releaseAsWarnings = (units, ranges) => {
|
|
219
|
-
const known = new Set(units.map((u) => u.id));
|
|
220
|
-
const released = new Set(units.filter((u) => u.version !== "none").map((u) => u.id));
|
|
221
|
-
const warnings = new Map();
|
|
222
|
-
const warn = (code, message, unit) => {
|
|
223
|
-
warnings.set(`${code}\0${message}`, coreCodes.warning(code, message, unit === undefined ? {} : { unit }));
|
|
224
|
-
};
|
|
225
|
-
for (const { changes } of ranges) {
|
|
226
|
-
for (const { change, units: owners } of changes) {
|
|
227
|
-
for (const { unit, version } of change.releaseAs ?? []) {
|
|
228
|
-
if (unit === undefined) {
|
|
229
|
-
if (!owners.some((id) => released.has(id))) {
|
|
230
|
-
warn("W_RELEASE_AS_IGNORED", `Release-As "${version}"${at(change.sha)} is not attributed to a released unit`);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
else if (!known.has(unit)) {
|
|
234
|
-
warn("W_RELEASE_AS_UNKNOWN", `Release-As "${unit}@${version}"${at(change.sha)} names unknown unit "${unit}"`);
|
|
235
|
-
}
|
|
236
|
-
else if (!released.has(unit)) {
|
|
237
|
-
warn("W_RELEASE_AS_IGNORED", `Release-As "${unit}@${version}"${at(change.sha)} names unreleased unit "${unit}"`, unit);
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
242
|
-
return [...warnings.values()];
|
|
243
|
-
};
|
|
4
|
+
import { bumpedOf, ctxOf, fromOf, initialBelowPrerelease, initialOf, render, } from "./version-math.js";
|
|
244
5
|
/**
|
|
245
6
|
* Own and absorbed bump and Release-As of a released unit. Release-As values
|
|
246
7
|
* are read newest first (core commit order); a single leading `v` is
|
|
@@ -368,4 +129,3 @@ export const releaseGroup = (group, members, warnings) => {
|
|
|
368
129
|
}),
|
|
369
130
|
};
|
|
370
131
|
};
|
|
371
|
-
export { changeLevel };
|
package/dist/released.d.ts
CHANGED
package/dist/version-files.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Warning } from "./errors.js";
|
|
2
|
-
import type { Plan } from "./plan.js";
|
|
2
|
+
import type { Plan } from "./model/plan-types.js";
|
|
3
3
|
import type { ReadonlyFs, VersionFile } from "./plugin.js";
|
|
4
4
|
import type { ReleaseItem } from "./release-items.js";
|
|
5
5
|
import type { Workspace } from "./workspace.js";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Warning } from "./errors.js";
|
|
2
|
+
import type { UnitFacts } from "./model/facts-types.js";
|
|
3
|
+
import type { BumpLevel, PreCtx, Unit, VersionScheme } from "./plugin.js";
|
|
4
|
+
/** A parsed `from` version; `label` names it in warnings. */
|
|
5
|
+
export interface From<V> {
|
|
6
|
+
readonly version: V;
|
|
7
|
+
readonly label: string;
|
|
8
|
+
}
|
|
9
|
+
/** The `from` version of a unit, from `facts.fromTag`. */
|
|
10
|
+
export declare const fromOf: <V>(scheme: VersionScheme<V>, facts: UnitFacts) => From<V> | undefined;
|
|
11
|
+
export declare const initialOf: <V>(unit: Unit, scheme: VersionScheme<V>) => V;
|
|
12
|
+
/** `from` bumped by `bump`; the initial version on a first release. */
|
|
13
|
+
export declare const bumpedOf: <V>(scheme: VersionScheme<V>, bump: BumpLevel | null, { from, initial }: {
|
|
14
|
+
from: From<V> | undefined;
|
|
15
|
+
initial: V;
|
|
16
|
+
}) => V | undefined;
|
|
17
|
+
export declare const ctxOf: (unit: Unit, head: string, at: {
|
|
18
|
+
baseTag: {
|
|
19
|
+
name: string;
|
|
20
|
+
} | null;
|
|
21
|
+
tags: readonly string[];
|
|
22
|
+
sinceLineBase: number;
|
|
23
|
+
total: number;
|
|
24
|
+
}) => PreCtx;
|
|
25
|
+
/** `next` and prerelease of `raw` under `ctx`. */
|
|
26
|
+
export declare const render: <V>({ scheme, raw, ctx, channel, }: {
|
|
27
|
+
scheme: VersionScheme<V>;
|
|
28
|
+
raw: V | undefined;
|
|
29
|
+
ctx: PreCtx;
|
|
30
|
+
channel: string | null;
|
|
31
|
+
}) => {
|
|
32
|
+
readonly next: string | null;
|
|
33
|
+
readonly prerelease: string | null;
|
|
34
|
+
};
|
|
35
|
+
/** Warns when a first release's initial version is not above the unit's highest prerelease tag. */
|
|
36
|
+
export declare const initialBelowPrerelease: <V>(scheme: VersionScheme<V>, initial: V, facts: UnitFacts) => Warning[];
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { coreCodes } from "./codes.js";
|
|
2
|
+
/** The `from` version of a unit, from `facts.fromTag`. */
|
|
3
|
+
export const fromOf = (scheme, facts) => {
|
|
4
|
+
const tag = facts.fromTag;
|
|
5
|
+
const version = tag === null ? undefined : scheme.parse(tag.version);
|
|
6
|
+
return tag === null || version === undefined
|
|
7
|
+
? undefined
|
|
8
|
+
: {
|
|
9
|
+
version,
|
|
10
|
+
label: facts.group === null
|
|
11
|
+
? tag.version
|
|
12
|
+
: `${tag.version} (group ${facts.group})`,
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export const initialOf = (unit, scheme) => (unit.initialVersion === null
|
|
16
|
+
? undefined
|
|
17
|
+
: scheme.parse(unit.initialVersion)) ?? scheme.initial();
|
|
18
|
+
/** `from` bumped by `bump`; the initial version on a first release. */
|
|
19
|
+
export const bumpedOf = (scheme, bump, { from, initial }) => bump === null
|
|
20
|
+
? undefined
|
|
21
|
+
: from === undefined
|
|
22
|
+
? initial
|
|
23
|
+
: scheme.bump(from.version, bump);
|
|
24
|
+
export const ctxOf = (unit, head, at) => ({
|
|
25
|
+
unit,
|
|
26
|
+
head,
|
|
27
|
+
baseTag: at.baseTag?.name ?? null,
|
|
28
|
+
tags: at.tags,
|
|
29
|
+
firstParent: { sinceLineBase: at.sinceLineBase, total: at.total },
|
|
30
|
+
});
|
|
31
|
+
/** `next` and prerelease of `raw` under `ctx`. */
|
|
32
|
+
export const render = ({ scheme, raw, ctx, channel, }) => ({
|
|
33
|
+
next: raw === undefined ? null : scheme.format(scheme.release(raw, ctx)),
|
|
34
|
+
prerelease: raw === undefined || channel === null
|
|
35
|
+
? null
|
|
36
|
+
: scheme.format(scheme.prerelease(raw, { ...ctx, channel })),
|
|
37
|
+
});
|
|
38
|
+
/** Warns when a first release's initial version is not above the unit's highest prerelease tag. */
|
|
39
|
+
export const initialBelowPrerelease = (scheme, initial, facts) => {
|
|
40
|
+
const highest = facts.tags
|
|
41
|
+
.filter((t) => {
|
|
42
|
+
const v = scheme.parse(t.version);
|
|
43
|
+
return v !== undefined && scheme.isPrerelease(v);
|
|
44
|
+
})
|
|
45
|
+
.at(-1);
|
|
46
|
+
const version = highest && scheme.parse(highest.version);
|
|
47
|
+
if (!highest || version === undefined) {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
return scheme.compare(initial, version) > 0
|
|
51
|
+
? []
|
|
52
|
+
: [
|
|
53
|
+
coreCodes.warning("W_INITIAL_BELOW_PRERELEASE", `unit "${facts.id}": initial version ${scheme.format(initial)} does not exceed prerelease tag "${highest.name}"`, { unit: facts.id }),
|
|
54
|
+
];
|
|
55
|
+
};
|
package/dist/workspace.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { Graph } from "./graph.js";
|
|
|
3
3
|
import type { Group } from "./groups.js";
|
|
4
4
|
import type { IntentSource, Unit, VersionFile } from "./plugin.js";
|
|
5
5
|
import type { PluginEnv } from "./plugins.js";
|
|
6
|
-
import type { ReleaseSettings } from "./release.js";
|
|
6
|
+
import type { ReleaseSettings } from "./release-settings.js";
|
|
7
7
|
import type { SchemeEntry } from "./schemes.js";
|
|
8
8
|
/** An intent source with its plugin's validated options; callers build the `Ctx`. */
|
|
9
9
|
export interface IntentEntry {
|
package/dist/workspace.js
CHANGED
|
@@ -4,7 +4,7 @@ import { discoverUnits } from "./discover.js";
|
|
|
4
4
|
import { buildGraph } from "./graph.js";
|
|
5
5
|
import { resolveGroups } from "./groups.js";
|
|
6
6
|
import { activatePlugins, runHook } from "./plugins.js";
|
|
7
|
-
import { releaseSettings } from "./release.js";
|
|
7
|
+
import { releaseSettings } from "./release-settings.js";
|
|
8
8
|
import { collectSchemes } from "./schemes.js";
|
|
9
9
|
import { uniqueSorted } from "./util.js";
|
|
10
10
|
const collectEdges = async (active, config, units) => {
|