@ethlete/cli 2.1.0-next.8 → 3.0.0-next.16
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 +93 -0
- package/README.md +22 -7
- package/design/define-call.ts +92 -0
- package/design/web/env.d.ts +11 -0
- package/design/web/frame.html +17 -0
- package/design/web/frame.ts +44 -0
- package/design/web/host.css +494 -0
- package/design/web/host.ts +445 -0
- package/design/web/index.html +11 -0
- package/package.json +13 -2
- package/src/index.d.ts +1 -0
- package/src/index.js +32 -4
- package/src/index.js.map +1 -1
- package/src/lib/api/clear.js +13 -3
- package/src/lib/api/clear.js.map +1 -1
- package/src/lib/api/compose.js +5 -1
- package/src/lib/api/compose.js.map +1 -1
- package/src/lib/api/git.d.ts +11 -4
- package/src/lib/api/git.js +35 -8
- package/src/lib/api/git.js.map +1 -1
- package/src/lib/api/load-definitions.js +10 -1
- package/src/lib/api/load-definitions.js.map +1 -1
- package/src/lib/api/ports.js +12 -3
- package/src/lib/api/ports.js.map +1 -1
- package/src/lib/api/run.js +8 -3
- package/src/lib/api/run.js.map +1 -1
- package/src/lib/api/setup.js +1 -1
- package/src/lib/api/setup.js.map +1 -1
- package/src/lib/api/state.js +7 -5
- package/src/lib/api/state.js.map +1 -1
- package/src/lib/auth/composer-auth.js +3 -2
- package/src/lib/auth/composer-auth.js.map +1 -1
- package/src/lib/auth/gitlab-token.js +1 -1
- package/src/lib/auth/gitlab-token.js.map +1 -1
- package/src/lib/config/diagnose.js +15 -9
- package/src/lib/config/diagnose.js.map +1 -1
- package/src/lib/config/local-config.d.ts +1 -1
- package/src/lib/design/calls-tsconfig.d.ts +6 -0
- package/src/lib/design/calls-tsconfig.js +37 -0
- package/src/lib/design/calls-tsconfig.js.map +1 -0
- package/src/lib/design/check.d.ts +11 -0
- package/src/lib/design/check.js +203 -0
- package/src/lib/design/check.js.map +1 -0
- package/src/lib/design/design-command.d.ts +10 -0
- package/src/lib/design/design-command.js +32 -0
- package/src/lib/design/design-command.js.map +1 -0
- package/src/lib/design/index.d.ts +5 -0
- package/src/lib/design/index.js +9 -0
- package/src/lib/design/index.js.map +1 -0
- package/src/lib/design/paths.d.ts +24 -0
- package/src/lib/design/paths.js +31 -0
- package/src/lib/design/paths.js.map +1 -0
- package/src/lib/design/serve.d.ts +7 -0
- package/src/lib/design/serve.js +144 -0
- package/src/lib/design/serve.js.map +1 -0
- package/src/lib/design/vite-paths.d.ts +7 -0
- package/src/lib/design/vite-paths.js +15 -0
- package/src/lib/design/vite-paths.js.map +1 -0
- package/src/lib/doctor/doctor-command.js +18 -4
- package/src/lib/doctor/doctor-command.js.map +1 -1
- package/src/lib/index.d.ts +1 -0
- package/src/lib/index.js +1 -0
- package/src/lib/index.js.map +1 -1
- package/src/lib/release.d.ts +38 -1
- package/src/lib/release.js +153 -28
- package/src/lib/release.js.map +1 -1
- package/src/lib/update/agent-rules-sync.d.ts +37 -0
- package/src/lib/update/agent-rules-sync.js +40 -0
- package/src/lib/update/agent-rules-sync.js.map +1 -0
- package/src/lib/update/agent-setup.d.ts +33 -0
- package/src/lib/update/agent-setup.js +124 -0
- package/src/lib/update/agent-setup.js.map +1 -0
- package/src/lib/update/ai.d.ts +37 -8
- package/src/lib/update/ai.js +193 -24
- package/src/lib/update/ai.js.map +1 -1
- package/src/lib/update/args.d.ts +2 -0
- package/src/lib/update/args.js +22 -2
- package/src/lib/update/args.js.map +1 -1
- package/src/lib/update/available-migrations.d.ts +10 -0
- package/src/lib/update/available-migrations.js +23 -0
- package/src/lib/update/available-migrations.js.map +1 -0
- package/src/lib/update/commits.d.ts +63 -0
- package/src/lib/update/commits.js +146 -0
- package/src/lib/update/commits.js.map +1 -0
- package/src/lib/update/gitignore.d.ts +8 -0
- package/src/lib/update/gitignore.js +22 -0
- package/src/lib/update/gitignore.js.map +1 -0
- package/src/lib/update/index.d.ts +6 -0
- package/src/lib/update/index.js +6 -0
- package/src/lib/update/index.js.map +1 -1
- package/src/lib/update/migration-manifest.d.ts +10 -0
- package/src/lib/update/migration-manifest.js +15 -3
- package/src/lib/update/migration-manifest.js.map +1 -1
- package/src/lib/update/migration-record.d.ts +24 -0
- package/src/lib/update/migration-record.js +48 -0
- package/src/lib/update/migration-record.js.map +1 -0
- package/src/lib/update/migrations-command.d.ts +14 -0
- package/src/lib/update/migrations-command.js +212 -0
- package/src/lib/update/migrations-command.js.map +1 -0
- package/src/lib/update/package-manager.d.ts +20 -1
- package/src/lib/update/package-manager.js +34 -15
- package/src/lib/update/package-manager.js.map +1 -1
- package/src/lib/update/packages.d.ts +28 -8
- package/src/lib/update/packages.js +117 -36
- package/src/lib/update/packages.js.map +1 -1
- package/src/lib/update/pending.d.ts +16 -0
- package/src/lib/update/pending.js +21 -5
- package/src/lib/update/pending.js.map +1 -1
- package/src/lib/update/plan.d.ts +33 -8
- package/src/lib/update/plan.js +76 -7
- package/src/lib/update/plan.js.map +1 -1
- package/src/lib/update/registry.d.ts +32 -4
- package/src/lib/update/registry.js +145 -8
- package/src/lib/update/registry.js.map +1 -1
- package/src/lib/update/run-migrations.d.ts +2 -0
- package/src/lib/update/run-migrations.js +20 -15
- package/src/lib/update/run-migrations.js.map +1 -1
- package/src/lib/update/scan.d.ts +14 -0
- package/src/lib/update/scan.js +57 -0
- package/src/lib/update/scan.js.map +1 -0
- package/src/lib/update/semver.js +2 -1
- package/src/lib/update/semver.js.map +1 -1
- package/src/lib/update/tasks.d.ts +18 -1
- package/src/lib/update/tasks.js +114 -43
- package/src/lib/update/tasks.js.map +1 -1
- package/src/lib/update/update-command.d.ts +7 -0
- package/src/lib/update/update-command.js +300 -73
- package/src/lib/update/update-command.js.map +1 -1
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
import type { Call, CallVariant, CallRound } from '@design-explore';
|
|
2
|
+
import { calls, defaultCall } from 'virtual:design-explore';
|
|
3
|
+
import './host.css';
|
|
4
|
+
|
|
5
|
+
/** The contact sheet draws about five 1100px frames per screen at this scale. */
|
|
6
|
+
const SHEET_SCALE = 0.32;
|
|
7
|
+
|
|
8
|
+
const params = new URLSearchParams(location.search);
|
|
9
|
+
const slugs = Object.keys(calls);
|
|
10
|
+
const asked = params.get('call') ?? '';
|
|
11
|
+
const landing = defaultCall && slugs.includes(defaultCall) ? defaultCall : (slugs.at(-1) ?? '');
|
|
12
|
+
const slug = slugs.includes(asked) ? asked : landing;
|
|
13
|
+
const view = params.get('view') === 'sheet' ? 'sheet' : 'rounds';
|
|
14
|
+
const opened = new Set((params.get('open') ?? '').split(',').filter(Boolean));
|
|
15
|
+
const picked = (params.get('pick') ?? '').split(',').filter(Boolean);
|
|
16
|
+
|
|
17
|
+
const esc = (text: string) => text.replace(/[&<>]/g, (c) => ({ '&': '&', '<': '<', '>': '>' })[c] ?? c);
|
|
18
|
+
|
|
19
|
+
const link = (next: Record<string, string | null>) => {
|
|
20
|
+
const url = new URLSearchParams(params);
|
|
21
|
+
for (const [name, value] of Object.entries(next)) {
|
|
22
|
+
if (value === null) url.delete(name);
|
|
23
|
+
else url.set(name, value);
|
|
24
|
+
}
|
|
25
|
+
return `?${url}`;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const listLink = (name: string, list: string[], key: string) => {
|
|
29
|
+
const next = list.includes(key) ? list.filter((entry) => entry !== key) : [...list, key];
|
|
30
|
+
return link({ [name]: next.length > 0 ? next.join(',') : null });
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const toggleOpen = (key: string) => listLink('open', [...opened], key);
|
|
34
|
+
const togglePick = (key: string) => listLink('pick', picked, key);
|
|
35
|
+
|
|
36
|
+
type Band = { key: string | null; number: number; round: CallRound | null; variants: CallVariant[] };
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The variants are the call. A band exists because a variant names it, never because `rounds`
|
|
40
|
+
* declares it, so a variant added without its round entry still gets a band, a heading and a
|
|
41
|
+
* menu row - all three say the bare key until somebody writes the prose.
|
|
42
|
+
*/
|
|
43
|
+
const bandsOf = (call: Call): Band[] => {
|
|
44
|
+
const declared = new Map((call.rounds ?? []).map((round) => [round.key, round]));
|
|
45
|
+
const bands = new Map<string, Band>();
|
|
46
|
+
|
|
47
|
+
for (const variant of call.variants) {
|
|
48
|
+
const key = variant.round ?? '';
|
|
49
|
+
const band = bands.get(key) ?? { key: key || null, number: 0, round: declared.get(key) ?? null, variants: [] };
|
|
50
|
+
band.variants.push(variant);
|
|
51
|
+
bands.set(key, band);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let number = 0;
|
|
55
|
+
for (const band of bands.values()) if (band.key) band.number = ++number;
|
|
56
|
+
|
|
57
|
+
return [...bands.values()];
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/** Prose that no variant claims is stale prose, and it is the one thing the variants cannot show. */
|
|
61
|
+
const problemsOf = (call: Call, bands: Band[]) => {
|
|
62
|
+
const keys = (call.rounds ?? []).map((round) => round.key);
|
|
63
|
+
const drawn = new Set(bands.map((band) => band.key));
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
...[...new Set(keys.filter((key, index) => keys.indexOf(key) !== index))].map(
|
|
67
|
+
(key) => `two rounds share the key "${key}"`,
|
|
68
|
+
),
|
|
69
|
+
...keys.filter((key) => !drawn.has(key)).map((key) => `round "${key}" has no variants`),
|
|
70
|
+
];
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A call is resolved once every round has ruled and at least one round has a winner. Its rounds
|
|
75
|
+
* then draw nothing, because each winner is the one before it plus a change, so the last of them
|
|
76
|
+
* already holds all the others.
|
|
77
|
+
*/
|
|
78
|
+
const chainOf = (bands: Band[]) => {
|
|
79
|
+
const named = bands.filter((band) => band.key);
|
|
80
|
+
const ruled = named.length > 1 && named.every((band) => band.variants.every((variant) => variant.verdict));
|
|
81
|
+
const chain = named
|
|
82
|
+
.map((band) => band.variants.find((variant) => variant.verdict === 'chosen'))
|
|
83
|
+
.filter((variant): variant is CallVariant => !!variant);
|
|
84
|
+
|
|
85
|
+
return ruled && chain.length > 0 ? chain : [];
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/** A call's folder path is its place in the tree, so the sidebar nests on the path segments. */
|
|
89
|
+
const tree = (bands: Band[]) => {
|
|
90
|
+
const groups = new Map<string, string[]>();
|
|
91
|
+
for (const s of slugs) {
|
|
92
|
+
const parts = s.split('/');
|
|
93
|
+
const group = parts.slice(0, -1).join(' / ');
|
|
94
|
+
groups.set(group, [...(groups.get(group) ?? []), s]);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const named = bands.filter((band) => band.key);
|
|
98
|
+
|
|
99
|
+
const rounds = (s: string) =>
|
|
100
|
+
s !== slug || view === 'sheet' || named.length < 2
|
|
101
|
+
? ''
|
|
102
|
+
: `<div class="nav-rounds">${named
|
|
103
|
+
.map(
|
|
104
|
+
(band) =>
|
|
105
|
+
`<a href="#round-${esc(band.key ?? '')}">${band.number} · ${esc(band.round?.title ?? band.key ?? '')}</a>`,
|
|
106
|
+
)
|
|
107
|
+
.join('')}</div>`;
|
|
108
|
+
|
|
109
|
+
return [...groups]
|
|
110
|
+
.map(
|
|
111
|
+
([group, members]) => `
|
|
112
|
+
<section>
|
|
113
|
+
${group ? `<h3>${esc(group)}</h3>` : ''}
|
|
114
|
+
${members
|
|
115
|
+
.map(
|
|
116
|
+
(s) =>
|
|
117
|
+
`<a href="${link({ call: s, open: null, pick: null })}" ${s === slug ? 'aria-current="page"' : ''}>${esc(
|
|
118
|
+
s.split('/').at(-1) ?? s,
|
|
119
|
+
)}</a>${rounds(s)}`,
|
|
120
|
+
)
|
|
121
|
+
.join('')}
|
|
122
|
+
</section>`,
|
|
123
|
+
)
|
|
124
|
+
.join('');
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const load = slug ? calls[slug] : undefined;
|
|
128
|
+
|
|
129
|
+
if (!load) {
|
|
130
|
+
document.body.innerHTML = `<p class="empty">No call under .ethlete/design/calls.</p>`;
|
|
131
|
+
} else {
|
|
132
|
+
const call: Call = (await load()).default;
|
|
133
|
+
const bands = bandsOf(call);
|
|
134
|
+
const chain = chainOf(bands);
|
|
135
|
+
const result = chain.at(-1);
|
|
136
|
+
const isView = call.variants.length === 1 && !call.variants[0]?.claim;
|
|
137
|
+
const geometry = `--frame-width:${call.frameWidth}px`;
|
|
138
|
+
|
|
139
|
+
const frame = (variant: CallVariant) => `
|
|
140
|
+
<iframe
|
|
141
|
+
src="frame.html?call=${encodeURIComponent(slug)}&variant=${encodeURIComponent(variant.key)}"
|
|
142
|
+
data-variant="${esc(variant.key)}"
|
|
143
|
+
title="${esc(variant.name)}"
|
|
144
|
+
style="width:${call.frameWidth}px"
|
|
145
|
+
></iframe>`;
|
|
146
|
+
|
|
147
|
+
const column = (variant: CallVariant) => `
|
|
148
|
+
<div class="column" data-verdict="${variant.verdict ?? 'open'}" ${picked.includes(variant.key) ? 'data-picked' : ''}>
|
|
149
|
+
${
|
|
150
|
+
isView
|
|
151
|
+
? ''
|
|
152
|
+
: `<h3>
|
|
153
|
+
<a href="${togglePick(variant.key)}">${esc(variant.name)}</a>
|
|
154
|
+
<span class="tag">${variant.verdict ?? 'open'}</span>
|
|
155
|
+
</h3>`
|
|
156
|
+
}
|
|
157
|
+
<div class="stage">${frame(variant)}</div>
|
|
158
|
+
${variant.claim ? `<p class="claim">${esc(variant.claim)}</p>` : ''}
|
|
159
|
+
${variant.cost ? `<p class="cost">${esc(variant.cost)}</p>` : ''}
|
|
160
|
+
</div>`;
|
|
161
|
+
|
|
162
|
+
const grid = (variants: CallVariant[]) =>
|
|
163
|
+
variants.length === 0
|
|
164
|
+
? ''
|
|
165
|
+
: `<div class="grid" style="${geometry}" ${isView ? 'data-view' : ''}>${variants.map(column).join('')}</div>`;
|
|
166
|
+
|
|
167
|
+
const rows = (variants: CallVariant[]) =>
|
|
168
|
+
variants.length === 0
|
|
169
|
+
? ''
|
|
170
|
+
: `<ul class="folded">${variants
|
|
171
|
+
.map(
|
|
172
|
+
(variant) =>
|
|
173
|
+
`<li data-verdict="${variant.verdict ?? 'open'}"><a href="${togglePick(variant.key)}">${esc(
|
|
174
|
+
variant.name,
|
|
175
|
+
)}</a><span class="tag">${variant.verdict ?? 'open'}</span></li>`,
|
|
176
|
+
)
|
|
177
|
+
.join('')}</ul>`;
|
|
178
|
+
|
|
179
|
+
const band = ({ key, number, round, variants }: Band) => {
|
|
180
|
+
const settled = variants.every((variant) => variant.verdict);
|
|
181
|
+
const open = !key || !settled || opened.has(key);
|
|
182
|
+
const drawn = open ? variants : chain.length > 0 ? [] : variants.filter((variant) => variant.verdict === 'chosen');
|
|
183
|
+
const folded = variants.filter((variant) => !drawn.includes(variant));
|
|
184
|
+
|
|
185
|
+
const head = !key
|
|
186
|
+
? ''
|
|
187
|
+
: `<div class="round-head">
|
|
188
|
+
<span class="eyebrow">Round ${number}${settled ? ' · settled' : ''}</span>
|
|
189
|
+
<h2>${esc(round?.title ?? key)}</h2>
|
|
190
|
+
${round?.note ? `<p>${esc(round.note)}</p>` : ''}
|
|
191
|
+
${
|
|
192
|
+
settled
|
|
193
|
+
? `<a class="fold" href="${toggleOpen(key)}">${
|
|
194
|
+
open ? `Fold ${variants.length} variants away` : `Show all ${variants.length} variants`
|
|
195
|
+
}</a>`
|
|
196
|
+
: ''
|
|
197
|
+
}
|
|
198
|
+
</div>`;
|
|
199
|
+
|
|
200
|
+
return `
|
|
201
|
+
<section class="round" ${key ? `id="round-${esc(key)}"` : ''}>
|
|
202
|
+
${head}
|
|
203
|
+
${grid(drawn)}
|
|
204
|
+
${rows(folded)}
|
|
205
|
+
</section>`;
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
/** Each step is the one before it plus a change, so the arrow is the order they were drawn in. */
|
|
209
|
+
const trail = () =>
|
|
210
|
+
chain
|
|
211
|
+
.map((variant) => {
|
|
212
|
+
const band = bands.find((entry) => entry.variants.includes(variant));
|
|
213
|
+
const target = band?.key ? `${toggleOpen(band.key)}#round-${band.key}` : togglePick(variant.key);
|
|
214
|
+
return `<a href="${esc(target)}" ${variant === result ? 'aria-current="step"' : ''}>${esc(
|
|
215
|
+
variant.key.toUpperCase(),
|
|
216
|
+
)}</a>`;
|
|
217
|
+
})
|
|
218
|
+
.join('<span class="arrow">→</span>');
|
|
219
|
+
|
|
220
|
+
const resultBand = () =>
|
|
221
|
+
!result
|
|
222
|
+
? ''
|
|
223
|
+
: `<section class="round result">
|
|
224
|
+
<div class="round-head">
|
|
225
|
+
<span class="eyebrow">Result</span>
|
|
226
|
+
<h2>${esc(result.name)}</h2>
|
|
227
|
+
${result.claim ? `<p>${esc(result.claim)}</p>` : ''}
|
|
228
|
+
<div class="trail">${trail()}</div>
|
|
229
|
+
</div>
|
|
230
|
+
<div class="grid" style="${geometry}">
|
|
231
|
+
<div class="column" data-verdict="chosen">
|
|
232
|
+
<div class="stage">${frame(result)}</div>
|
|
233
|
+
${result.cost ? `<p class="cost">${esc(result.cost)}</p>` : ''}
|
|
234
|
+
</div>
|
|
235
|
+
</div>
|
|
236
|
+
</section>`;
|
|
237
|
+
|
|
238
|
+
const tray = () => {
|
|
239
|
+
const variants = picked
|
|
240
|
+
.map((key) => call.variants.find((variant) => variant.key === key))
|
|
241
|
+
.filter((variant): variant is CallVariant => !!variant);
|
|
242
|
+
if (variants.length === 0) return '';
|
|
243
|
+
|
|
244
|
+
const two = variants.length === 2;
|
|
245
|
+
|
|
246
|
+
return `
|
|
247
|
+
<section class="round tray">
|
|
248
|
+
<div class="round-head">
|
|
249
|
+
<span class="eyebrow">Compare · ${variants.length}</span>
|
|
250
|
+
<h2>${variants.map((variant) => esc(variant.name)).join(' · ')}</h2>
|
|
251
|
+
<div class="switch">
|
|
252
|
+
${variants
|
|
253
|
+
.map((variant, index) => `<button data-step="${index}">${esc(variant.key.toUpperCase())}</button>`)
|
|
254
|
+
.join('')}
|
|
255
|
+
<span class="hint">${
|
|
256
|
+
two ? 'click or space to blink · arrows to wipe' : 'click or space for the next one'
|
|
257
|
+
}</span>
|
|
258
|
+
</div>
|
|
259
|
+
<a class="fold" href="${link({ pick: null })}">Clear the comparison</a>
|
|
260
|
+
</div>
|
|
261
|
+
<div class="overlay" data-two="${two}" style="width:${call.frameWidth}px">
|
|
262
|
+
${variants.map(frame).join('')}
|
|
263
|
+
<div class="seam"></div>
|
|
264
|
+
</div>
|
|
265
|
+
</section>`;
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const sheet = () => `
|
|
269
|
+
<div class="grid sheet" style="${geometry};--de-scale:${SHEET_SCALE}">
|
|
270
|
+
${call.variants
|
|
271
|
+
.map(
|
|
272
|
+
(variant) => `
|
|
273
|
+
<a class="thumb" href="${togglePick(variant.key)}" data-verdict="${variant.verdict ?? 'open'}" ${
|
|
274
|
+
picked.includes(variant.key) ? 'data-picked' : ''
|
|
275
|
+
}>
|
|
276
|
+
<div class="thumb-frame">${frame(variant)}</div>
|
|
277
|
+
<span class="thumb-name">${esc(variant.name)}</span>
|
|
278
|
+
</a>`,
|
|
279
|
+
)
|
|
280
|
+
.join('')}
|
|
281
|
+
</div>`;
|
|
282
|
+
|
|
283
|
+
const views = () =>
|
|
284
|
+
isView
|
|
285
|
+
? ''
|
|
286
|
+
: `<div class="views">
|
|
287
|
+
<a href="${link({ view: null })}" ${view === 'rounds' ? 'aria-current="page"' : ''}>rounds</a>
|
|
288
|
+
<a href="${link({ view: 'sheet' })}" ${view === 'sheet' ? 'aria-current="page"' : ''}>all ${
|
|
289
|
+
call.variants.length
|
|
290
|
+
}</a>
|
|
291
|
+
</div>`;
|
|
292
|
+
|
|
293
|
+
document.body.innerHTML = `
|
|
294
|
+
<nav>${tree(bands)}</nav>
|
|
295
|
+
<main>
|
|
296
|
+
<header>
|
|
297
|
+
<span class="eyebrow">${esc(call.eyebrow)}</span>
|
|
298
|
+
<h1>${esc(call.headline)}</h1>
|
|
299
|
+
<p>${esc(call.intro)}</p>
|
|
300
|
+
${views()}
|
|
301
|
+
</header>
|
|
302
|
+
${problemsOf(call, bands)
|
|
303
|
+
.map((problem) => `<p class="problem">design-explore: ${esc(problem)}</p>`)
|
|
304
|
+
.join('')}
|
|
305
|
+
${tray()}
|
|
306
|
+
${view === 'sheet' ? sheet() : `${resultBand()}${bands.map(band).join('')}`}
|
|
307
|
+
</main>`;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* A frame reports its height late, so the page grows under the reader for a second or two after
|
|
312
|
+
* load. The scroll is put back on every one of those reports, until the reader scrolls or the
|
|
313
|
+
* frames go quiet, because a single restore lands on a page that is still the wrong height.
|
|
314
|
+
*/
|
|
315
|
+
const scrollKey = `design-explore:scroll:${slug}:${view}`;
|
|
316
|
+
|
|
317
|
+
history.scrollRestoration = 'manual';
|
|
318
|
+
|
|
319
|
+
let restoring = true;
|
|
320
|
+
const target = Number(sessionStorage.getItem(scrollKey) ?? 0);
|
|
321
|
+
|
|
322
|
+
const stopRestore = () => {
|
|
323
|
+
restoring = false;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
if (target > 0 && !location.hash) {
|
|
327
|
+
for (const event of ['wheel', 'touchstart', 'keydown', 'pointerdown'] as const) {
|
|
328
|
+
addEventListener(event, stopRestore, { once: true, passive: true });
|
|
329
|
+
}
|
|
330
|
+
setTimeout(stopRestore, 3000);
|
|
331
|
+
scrollTo(0, target);
|
|
332
|
+
} else {
|
|
333
|
+
restoring = false;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
addEventListener(
|
|
337
|
+
'scroll',
|
|
338
|
+
() => {
|
|
339
|
+
if (!restoring) sessionStorage.setItem(scrollKey, String(Math.round(scrollY)));
|
|
340
|
+
},
|
|
341
|
+
{ passive: true },
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
const heights = new Map<string, number>();
|
|
345
|
+
|
|
346
|
+
/** The overlay is as tall as its tallest pick, so no frame is cut and none of them move. */
|
|
347
|
+
const size = () => {
|
|
348
|
+
for (const frame of document.querySelectorAll<HTMLIFrameElement>('iframe[data-variant]')) {
|
|
349
|
+
const height = heights.get(frame.dataset.variant ?? '');
|
|
350
|
+
if (!height) continue;
|
|
351
|
+
|
|
352
|
+
frame.style.height = `${height}px`;
|
|
353
|
+
|
|
354
|
+
const box = frame.parentElement;
|
|
355
|
+
if (box?.classList.contains('thumb-frame')) box.style.height = `${Math.ceil(height * SHEET_SCALE)}px`;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const overlay = document.querySelector<HTMLElement>('.overlay');
|
|
359
|
+
if (!overlay) return;
|
|
360
|
+
|
|
361
|
+
const tallest = [...overlay.querySelectorAll<HTMLIFrameElement>('iframe')]
|
|
362
|
+
.map((frame) => heights.get(frame.dataset.variant ?? '') ?? 0)
|
|
363
|
+
.reduce((a, b) => Math.max(a, b), 0);
|
|
364
|
+
|
|
365
|
+
if (tallest > 0) overlay.style.height = `${tallest}px`;
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
addEventListener('message', (event) => {
|
|
369
|
+
const data = event.data as { type?: string; variant?: string; height?: number };
|
|
370
|
+
if (data?.type !== 'design-explore:height' || !data.height || !data.variant) return;
|
|
371
|
+
|
|
372
|
+
heights.set(data.variant, data.height);
|
|
373
|
+
size();
|
|
374
|
+
|
|
375
|
+
if (restoring) scrollTo(0, target);
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Two drawings that differ by a few pixels can only be told apart in one place, so the picks are
|
|
380
|
+
* stacked at full size and the reader switches between them. Two picks also get a wipe: the
|
|
381
|
+
* second one is clipped from the left, so dragging the seam turns one into the other.
|
|
382
|
+
*/
|
|
383
|
+
const overlay = document.querySelector<HTMLElement>('.overlay');
|
|
384
|
+
|
|
385
|
+
if (overlay) {
|
|
386
|
+
const frames = [...overlay.querySelectorAll<HTMLIFrameElement>('iframe')];
|
|
387
|
+
const steps = [...document.querySelectorAll<HTMLButtonElement>('.switch button')];
|
|
388
|
+
const seam = overlay.querySelector<HTMLElement>('.seam');
|
|
389
|
+
const two = overlay.dataset.two === 'true';
|
|
390
|
+
|
|
391
|
+
let wipe = 50;
|
|
392
|
+
let active = 0;
|
|
393
|
+
|
|
394
|
+
const paint = () => {
|
|
395
|
+
frames.forEach((frame, index) => {
|
|
396
|
+
if (two && index === 1) {
|
|
397
|
+
frame.style.clipPath = `inset(0 0 0 ${wipe}%)`;
|
|
398
|
+
frame.style.opacity = '1';
|
|
399
|
+
} else if (two) {
|
|
400
|
+
frame.style.opacity = '1';
|
|
401
|
+
} else {
|
|
402
|
+
frame.style.opacity = index === active ? '1' : '0';
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
if (seam) {
|
|
407
|
+
seam.style.left = `${wipe}%`;
|
|
408
|
+
seam.hidden = !two || wipe === 0 || wipe === 100;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
const shown = two ? (wipe > 50 ? 0 : 1) : active;
|
|
412
|
+
steps.forEach((step, index) => step.toggleAttribute('aria-current', index === shown));
|
|
413
|
+
};
|
|
414
|
+
|
|
415
|
+
const next = () => {
|
|
416
|
+
if (two) wipe = wipe > 50 ? 0 : 100;
|
|
417
|
+
else active = (active + 1) % frames.length;
|
|
418
|
+
paint();
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
const go = (index: number) => {
|
|
422
|
+
if (two) wipe = index === 0 ? 100 : 0;
|
|
423
|
+
else active = index;
|
|
424
|
+
paint();
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
steps.forEach((step, index) => step.addEventListener('click', () => go(index)));
|
|
428
|
+
overlay.addEventListener('click', next);
|
|
429
|
+
|
|
430
|
+
addEventListener('keydown', (event) => {
|
|
431
|
+
if (event.target !== document.body) return;
|
|
432
|
+
|
|
433
|
+
if (event.key === ' ') next();
|
|
434
|
+
else if (two && event.key === 'ArrowLeft') wipe = Math.max(0, wipe - 5);
|
|
435
|
+
else if (two && event.key === 'ArrowRight') wipe = Math.min(100, wipe + 5);
|
|
436
|
+
else if (!two && event.key === 'ArrowLeft') active = (active - 1 + frames.length) % frames.length;
|
|
437
|
+
else if (!two && event.key === 'ArrowRight') active = (active + 1) % frames.length;
|
|
438
|
+
else return;
|
|
439
|
+
|
|
440
|
+
event.preventDefault();
|
|
441
|
+
paint();
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
paint();
|
|
445
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Design explore</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<script type="module" src="./host.ts"></script>
|
|
10
|
+
</body>
|
|
11
|
+
</html>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ethlete/cli",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-next.16",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"main": "./src/index.js",
|
|
@@ -8,8 +8,19 @@
|
|
|
8
8
|
"bin": {
|
|
9
9
|
"et": "./src/index.js"
|
|
10
10
|
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@tailwindcss/postcss": "4.3.3",
|
|
13
|
+
"typescript": "6.0.3",
|
|
14
|
+
"vite": "8.1.5"
|
|
15
|
+
},
|
|
11
16
|
"peerDependencies": {
|
|
12
|
-
"
|
|
17
|
+
"playwright": "^1.50.0",
|
|
18
|
+
"tslib": "^2.3.0"
|
|
19
|
+
},
|
|
20
|
+
"peerDependenciesMeta": {
|
|
21
|
+
"playwright": {
|
|
22
|
+
"optional": true
|
|
23
|
+
}
|
|
13
24
|
},
|
|
14
25
|
"types": "./src/index.d.ts"
|
|
15
26
|
}
|
package/src/index.d.ts
CHANGED
package/src/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
1
2
|
"use strict";
|
|
2
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
4
|
const tslib_1 = require("tslib");
|
|
@@ -25,11 +26,24 @@ const USAGE_ROWS = [
|
|
|
25
26
|
args: '',
|
|
26
27
|
lines: ["Check this machine's ethlete.config.local.json, container engine", 'and every API checkout'],
|
|
27
28
|
},
|
|
29
|
+
{
|
|
30
|
+
subcommand: 'design',
|
|
31
|
+
args: ' [checkout]',
|
|
32
|
+
lines: [
|
|
33
|
+
"Serve the design page of a checkout's .ethlete/design folder,",
|
|
34
|
+
'or run `design check` to find out why a call does not render',
|
|
35
|
+
],
|
|
36
|
+
},
|
|
28
37
|
{
|
|
29
38
|
subcommand: 'update',
|
|
30
39
|
args: ' [packages...]',
|
|
31
40
|
lines: ['Move the @ethlete/* packages to a newer version and run the', 'migrations those versions ship'],
|
|
32
41
|
},
|
|
42
|
+
{
|
|
43
|
+
subcommand: 'migrations',
|
|
44
|
+
args: ' [run <package>:<name>]',
|
|
45
|
+
lines: ['List the recommended and optional migrations this repo has', 'not run yet, or run one of them'],
|
|
46
|
+
},
|
|
33
47
|
];
|
|
34
48
|
const usage = (root) => {
|
|
35
49
|
const rows = USAGE_ROWS.map((row) => (Object.assign(Object.assign({}, row), { command: `${(0, lib_1.repoInvocation)({ root, subcommand: row.subcommand })}${row.args}` })));
|
|
@@ -44,10 +58,11 @@ const usage = (root) => {
|
|
|
44
58
|
const cli = (args) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
45
59
|
switch (args[0]) {
|
|
46
60
|
case 'release':
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
61
|
+
return (0, lib_1.release)({
|
|
62
|
+
root: process.cwd(),
|
|
63
|
+
args: args.slice(1),
|
|
64
|
+
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'release' }),
|
|
65
|
+
});
|
|
51
66
|
case 'api':
|
|
52
67
|
return (0, lib_1.apiCommand)({
|
|
53
68
|
root: process.cwd(),
|
|
@@ -60,12 +75,25 @@ const cli = (args) => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
|
|
|
60
75
|
argv: args.slice(1),
|
|
61
76
|
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'auth' }),
|
|
62
77
|
});
|
|
78
|
+
case 'design':
|
|
79
|
+
return (0, lib_1.designCommand)({
|
|
80
|
+
root: process.cwd(),
|
|
81
|
+
argv: args.slice(1),
|
|
82
|
+
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'design' }),
|
|
83
|
+
});
|
|
63
84
|
case 'update':
|
|
64
85
|
return (0, lib_1.updateCommand)({
|
|
65
86
|
root: process.cwd(),
|
|
66
87
|
argv: args.slice(1),
|
|
67
88
|
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'update' }),
|
|
68
89
|
});
|
|
90
|
+
case 'migrations':
|
|
91
|
+
return (0, lib_1.migrationsCommand)({
|
|
92
|
+
root: process.cwd(),
|
|
93
|
+
argv: args.slice(1),
|
|
94
|
+
invocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'migrations' }),
|
|
95
|
+
updateInvocation: (0, lib_1.repoInvocation)({ root: process.cwd(), subcommand: 'update' }),
|
|
96
|
+
});
|
|
69
97
|
case 'doctor':
|
|
70
98
|
// Every fix it names is an `et api` command, so it needs that script rather than its own.
|
|
71
99
|
return (0, lib_1.doctorCommand)({
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/cli/src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/cli/src/index.ts"],"names":[],"mappings":"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"}
|
package/src/lib/api/clear.js
CHANGED
|
@@ -19,7 +19,7 @@ const listed = (lines) => [
|
|
|
19
19
|
const planApiClear = (options) => {
|
|
20
20
|
const { apis, names, root, invocation, force, hasContainers } = options;
|
|
21
21
|
return names.flatMap((name) => {
|
|
22
|
-
const api = apis[name];
|
|
22
|
+
const api = Object.prototype.hasOwnProperty.call(apis, name) ? apis[name] : undefined;
|
|
23
23
|
if (!api)
|
|
24
24
|
return [];
|
|
25
25
|
const checkout = (0, resolve_checkout_1.resolveApiCheckout)({ root, name, api, needs: 'repo' });
|
|
@@ -43,6 +43,7 @@ const planApiClear = (options) => {
|
|
|
43
43
|
}
|
|
44
44
|
const changes = (0, git_1.uncommittedChanges)(repoPath);
|
|
45
45
|
const unpushed = (0, git_1.unpushedCommits)(repoPath);
|
|
46
|
+
const stashes = (0, git_1.stashEntries)(repoPath);
|
|
46
47
|
return [
|
|
47
48
|
{
|
|
48
49
|
name,
|
|
@@ -50,18 +51,27 @@ const planApiClear = (options) => {
|
|
|
50
51
|
composePath,
|
|
51
52
|
hasContainers: hasContainers(composePath),
|
|
52
53
|
blockers: [
|
|
53
|
-
...(!force && changes
|
|
54
|
+
...(!force && (changes === undefined || unpushed === undefined || stashes === undefined)
|
|
55
|
+
? [`git could not read ${repoPath}, so its changes are unknown. Pass --force to remove it anyway.`]
|
|
56
|
+
: []),
|
|
57
|
+
...(!force && changes !== undefined && changes.length > 0
|
|
54
58
|
? [
|
|
55
59
|
`${repoPath} has uncommitted changes:\n\n${listed(changes)}\n\n` +
|
|
56
60
|
'Commit them, or pass --force to lose them.',
|
|
57
61
|
]
|
|
58
62
|
: []),
|
|
59
|
-
...(!force && unpushed.length > 0
|
|
63
|
+
...(!force && unpushed !== undefined && unpushed.length > 0
|
|
60
64
|
? [
|
|
61
65
|
`${repoPath} has commits no remote holds:\n\n${listed(unpushed)}\n\n` +
|
|
62
66
|
'Push them, or pass --force to lose them.',
|
|
63
67
|
]
|
|
64
68
|
: []),
|
|
69
|
+
...(!force && stashes !== undefined && stashes.length > 0
|
|
70
|
+
? [
|
|
71
|
+
`${repoPath} has stashed changes:\n\n${listed(stashes)}\n\n` +
|
|
72
|
+
'Apply or drop them, or pass --force to lose them.',
|
|
73
|
+
]
|
|
74
|
+
: []),
|
|
65
75
|
],
|
|
66
76
|
},
|
|
67
77
|
];
|
package/src/lib/api/clear.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/clear.ts"],"names":[],"mappings":";;;;AAAA,2BAA4B;AAC5B,oCAAmC;AAEnC,+
|
|
1
|
+
{"version":3,"file":"clear.js","sourceRoot":"","sources":["../../../../../../libs/cli/src/lib/api/clear.ts"],"names":[],"mappings":"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"}
|
package/src/lib/api/compose.js
CHANGED
|
@@ -25,7 +25,11 @@ const COMPOSE_TOOLS = [
|
|
|
25
25
|
const PODMAN_REGISTRIES_CONF = `unqualified-search-registries = ["docker.io"]\nshort-name-mode = "disabled"\n`;
|
|
26
26
|
let podmanRegistriesConfPath;
|
|
27
27
|
const writePodmanRegistriesConf = () => {
|
|
28
|
-
|
|
28
|
+
if (podmanRegistriesConfPath === undefined) {
|
|
29
|
+
const directory = (0, fs_1.mkdtempSync)((0, path_1.join)((0, os_1.tmpdir)(), 'ethlete-api-'));
|
|
30
|
+
process.once('exit', () => (0, fs_1.rmSync)(directory, { recursive: true, force: true }));
|
|
31
|
+
podmanRegistriesConfPath = (0, path_1.join)(directory, 'registries.conf');
|
|
32
|
+
}
|
|
29
33
|
(0, fs_1.writeFileSync)(podmanRegistriesConfPath, PODMAN_REGISTRIES_CONF, 'utf8');
|
|
30
34
|
return podmanRegistriesConfPath;
|
|
31
35
|
};
|