@ethlete/cli 3.0.0-next.25 → 3.0.0-next.26
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 +89 -0
- package/design/define-call.ts +29 -3
- package/design/define-part.ts +15 -1
- package/design/logo-sheet.ts +52 -0
- package/design/motion-drive.ts +215 -0
- package/design/motion-runtime.ts +14 -2
- package/design/motion-tokens.ts +177 -0
- package/design/web/frame-fill.ts +4 -0
- package/design/web/frame-scheme.ts +44 -0
- package/design/web/frame.ts +122 -29
- package/package.json +1 -1
- package/src/lib/design/calls-tsconfig.d.ts +2 -0
- package/src/lib/design/calls-tsconfig.js +10 -3
- package/src/lib/design/calls-tsconfig.js.map +1 -1
- package/src/lib/design/check.d.ts +1 -0
- package/src/lib/design/check.js +62 -6
- package/src/lib/design/check.js.map +1 -1
- package/src/lib/design/contact-sheet.d.ts +9 -0
- package/src/lib/design/contact-sheet.js +38 -4
- package/src/lib/design/contact-sheet.js.map +1 -1
- package/src/lib/design/design-command.js +27 -8
- package/src/lib/design/design-command.js.map +1 -1
- package/src/lib/design/draw-ledger.d.ts +36 -0
- package/src/lib/design/draw-ledger.js +52 -0
- package/src/lib/design/draw-ledger.js.map +1 -0
- package/src/lib/design/mcp-command.d.ts +23 -2
- package/src/lib/design/mcp-command.js +105 -10
- package/src/lib/design/mcp-command.js.map +1 -1
- package/src/lib/design/motion-command.js +9 -15
- package/src/lib/design/motion-command.js.map +1 -1
- package/src/lib/design/paths.d.ts +14 -0
- package/src/lib/design/paths.js +50 -1
- package/src/lib/design/paths.js.map +1 -1
- package/src/lib/design/render-packages.d.ts +5 -0
- package/src/lib/design/render-packages.js +6 -1
- package/src/lib/design/render-packages.js.map +1 -1
- package/src/lib/design/render-worker.js +1 -0
- package/src/lib/design/render-worker.js.map +1 -1
- package/src/lib/design/serve.d.ts +2 -2
- package/src/lib/design/serve.js +158 -19
- package/src/lib/design/serve.js.map +1 -1
- package/src/lib/design/shot-command.d.ts +5 -2
- package/src/lib/design/shot-command.js +18 -16
- package/src/lib/design/shot-command.js.map +1 -1
- package/src/lib/design/shot-store.d.ts +24 -0
- package/src/lib/design/shot-store.js +120 -0
- package/src/lib/design/shot-store.js.map +1 -0
- package/src/lib/design/shot.d.ts +21 -1
- package/src/lib/design/shot.js +118 -31
- package/src/lib/design/shot.js.map +1 -1
- package/src/lib/design/sketch-command.js +121 -37
- package/src/lib/design/sketch-command.js.map +1 -1
- package/src/lib/design/ssr-shims.d.ts +2 -0
- package/src/lib/design/ssr-shims.js +12 -1
- package/src/lib/design/ssr-shims.js.map +1 -1
- package/src/lib/design/studio-api.d.ts +12 -0
- package/src/lib/design/studio-api.js +68 -2
- package/src/lib/design/studio-api.js.map +1 -1
- package/src/lib/design/system/check-system.d.ts +6 -2
- package/src/lib/design/system/check-system.js +102 -20
- package/src/lib/design/system/check-system.js.map +1 -1
- package/src/lib/design/system/colour.d.ts +4 -1
- package/src/lib/design/system/colour.js +54 -2
- package/src/lib/design/system/colour.js.map +1 -1
- package/src/lib/design/system/complete-command.js +6 -2
- package/src/lib/design/system/complete-command.js.map +1 -1
- package/src/lib/design/system/complete.d.ts +67 -2
- package/src/lib/design/system/complete.js +227 -53
- package/src/lib/design/system/complete.js.map +1 -1
- package/src/lib/design/system/contrast-check.d.ts +6 -1
- package/src/lib/design/system/contrast-check.js +167 -12
- package/src/lib/design/system/contrast-check.js.map +1 -1
- package/src/lib/design/system/drawn-open-points.d.ts +16 -0
- package/src/lib/design/system/drawn-open-points.js +43 -0
- package/src/lib/design/system/drawn-open-points.js.map +1 -0
- package/src/lib/design/system/list-system.d.ts +4 -1
- package/src/lib/design/system/list-system.js +2 -1
- package/src/lib/design/system/list-system.js.map +1 -1
- package/src/lib/design/system/open-points.d.ts +101 -0
- package/src/lib/design/system/open-points.js +156 -0
- package/src/lib/design/system/open-points.js.map +1 -0
- package/src/lib/design/system/part-ready.d.ts +52 -0
- package/src/lib/design/system/part-ready.js +101 -0
- package/src/lib/design/system/part-ready.js.map +1 -0
- package/src/lib/design/system/read-open-points.d.ts +27 -0
- package/src/lib/design/system/read-open-points.js +81 -0
- package/src/lib/design/system/read-open-points.js.map +1 -0
- package/src/lib/design/system/ready-command.d.ts +7 -0
- package/src/lib/design/system/ready-command.js +65 -0
- package/src/lib/design/system/ready-command.js.map +1 -0
- package/src/lib/design/system/render-check.d.ts +2 -0
- package/src/lib/design/system/render-check.js +197 -31
- package/src/lib/design/system/render-check.js.map +1 -1
- package/src/lib/design/system/resolve-product.d.ts +2 -1
- package/src/lib/design/system/resolve-product.js +20 -3
- package/src/lib/design/system/resolve-product.js.map +1 -1
- package/src/lib/design/system/rules/implements.d.ts +7 -0
- package/src/lib/design/system/rules/implements.js +43 -0
- package/src/lib/design/system/rules/implements.js.map +1 -0
- package/src/lib/design/system/rules/motion.d.ts +2 -0
- package/src/lib/design/system/rules/motion.js +26 -1
- package/src/lib/design/system/rules/motion.js.map +1 -1
- package/src/lib/design/system/rules/option-values.d.ts +15 -0
- package/src/lib/design/system/rules/option-values.js +145 -0
- package/src/lib/design/system/rules/option-values.js.map +1 -0
- package/src/lib/design/system/rules/stale-replace.js +41 -3
- package/src/lib/design/system/rules/stale-replace.js.map +1 -1
- package/src/lib/design/system/sketch/baseline.d.ts +11 -2
- package/src/lib/design/system/sketch/baseline.js +4 -2
- package/src/lib/design/system/sketch/baseline.js.map +1 -1
- package/src/lib/design/system/sketch/check-sketches.d.ts +1 -0
- package/src/lib/design/system/sketch/check-sketches.js +4 -2
- package/src/lib/design/system/sketch/check-sketches.js.map +1 -1
- package/src/lib/design/system/sketch/merge.js +32 -0
- package/src/lib/design/system/sketch/merge.js.map +1 -1
- package/src/lib/design/system/sketch/merged-parts.d.ts +1 -1
- package/src/lib/design/system/sketch/merged-parts.js +1 -1
- package/src/lib/design/system/sketch/merged-parts.js.map +1 -1
- package/src/lib/design/system/sketch/part-definition.d.ts +36 -0
- package/src/lib/design/system/sketch/part-definition.js +56 -2
- package/src/lib/design/system/sketch/part-definition.js.map +1 -1
- package/src/lib/design/system/sketch/sketch.d.ts +15 -0
- package/src/lib/design/system/sketch/sketch.js +65 -27
- package/src/lib/design/system/sketch/sketch.js.map +1 -1
- package/src/lib/design/system/sketch/unchanged-states.d.ts +4 -1
- package/src/lib/design/system/sketch/unchanged-states.js +9 -5
- package/src/lib/design/system/sketch/unchanged-states.js.map +1 -1
- package/src/lib/design/system/sketch/unused-closure.js +12 -2
- package/src/lib/design/system/sketch/unused-closure.js.map +1 -1
- package/src/lib/design/system/sketch/unused-files.d.ts +1 -1
- package/src/lib/design/system/sketch/unused-files.js +6 -3
- package/src/lib/design/system/sketch/unused-files.js.map +1 -1
- package/src/lib/design/system/system-tsconfig.js +2 -2
- package/src/lib/design/system/system-tsconfig.js.map +1 -1
- package/src/lib/design/system/ts-source.d.ts +3 -0
- package/src/lib/design/system/ts-source.js +21 -4
- package/src/lib/design/system/ts-source.js.map +1 -1
- package/src/lib/design/thumb.d.ts +31 -4
- package/src/lib/design/thumb.js +105 -40
- package/src/lib/design/thumb.js.map +1 -1
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { MotionTrack } from './motion-runtime';
|
|
2
|
+
|
|
3
|
+
/** A CSS custom property declared on `:root`, with its computed value. */
|
|
4
|
+
export type MotionToken = { name: string; value: string };
|
|
5
|
+
|
|
6
|
+
/** A track with the names of the tokens whose value equals its duration or easing, in declaration order. */
|
|
7
|
+
export type NamedMotionTrack = MotionTrack & { durationTokens?: string[]; easingTokens?: string[] };
|
|
8
|
+
|
|
9
|
+
const KEYWORD_EASINGS: Record<string, string> = {
|
|
10
|
+
ease: 'cubic-bezier(0.25,0.1,0.25,1)',
|
|
11
|
+
'ease-in': 'cubic-bezier(0.42,0,1,1)',
|
|
12
|
+
'ease-out': 'cubic-bezier(0,0,0.58,1)',
|
|
13
|
+
'ease-in-out': 'cubic-bezier(0.42,0,0.58,1)',
|
|
14
|
+
'step-start': 'steps(1,jump-start)',
|
|
15
|
+
'step-end': 'steps(1,jump-end)',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const TIME = /^(-?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?)(ms|s)$/u;
|
|
19
|
+
const EASING_FUNCTION = /^(cubic-bezier|linear|steps)\((.*)\)$/u;
|
|
20
|
+
|
|
21
|
+
const roundedOf = (value: number) => String(Math.round(value * 10000) / 10000);
|
|
22
|
+
|
|
23
|
+
const msOf = (value: string) => {
|
|
24
|
+
const match = TIME.exec(value.trim().toLowerCase());
|
|
25
|
+
|
|
26
|
+
return match ? Number(match[1]) * (match[2] === 's' ? 1000 : 1) : null;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const linearOf = (body: string) => {
|
|
30
|
+
const points: { output: number; input: number | null }[] = [];
|
|
31
|
+
|
|
32
|
+
for (const stop of body.split(',')) {
|
|
33
|
+
const [output = '', ...inputs] = stop.trim().split(/\s+/u);
|
|
34
|
+
const value = Number(output);
|
|
35
|
+
|
|
36
|
+
if (output === '' || !Number.isFinite(value) || inputs.length > 2) return null;
|
|
37
|
+
|
|
38
|
+
const percents = inputs.map((input) => (input.endsWith('%') ? Number(input.slice(0, -1)) : Number.NaN));
|
|
39
|
+
|
|
40
|
+
if (percents.some((percent) => !Number.isFinite(percent))) return null;
|
|
41
|
+
|
|
42
|
+
if (percents.length === 0) points.push({ output: value, input: null });
|
|
43
|
+
for (const percent of percents) points.push({ output: value, input: percent });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (points.length < 2) return null;
|
|
47
|
+
|
|
48
|
+
const first = points[0];
|
|
49
|
+
const last = points[points.length - 1];
|
|
50
|
+
|
|
51
|
+
if (first && first.input === null) first.input = 0;
|
|
52
|
+
if (last && last.input === null) last.input = Math.max(100, ...points.map((point) => point.input ?? 0));
|
|
53
|
+
|
|
54
|
+
let highest = 0;
|
|
55
|
+
|
|
56
|
+
for (const point of points) {
|
|
57
|
+
if (point.input !== null) point.input = Math.max(point.input, highest);
|
|
58
|
+
highest = point.input ?? highest;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
for (let index = 1; index < points.length; index++) {
|
|
62
|
+
if (points[index]?.input !== null) continue;
|
|
63
|
+
|
|
64
|
+
const before = index - 1;
|
|
65
|
+
let after = index;
|
|
66
|
+
|
|
67
|
+
while (points[after]?.input === null) after++;
|
|
68
|
+
|
|
69
|
+
const from = points[before]?.input ?? 0;
|
|
70
|
+
const to = points[after]?.input ?? 100;
|
|
71
|
+
|
|
72
|
+
for (let gap = index; gap < after; gap++) {
|
|
73
|
+
const point = points[gap];
|
|
74
|
+
|
|
75
|
+
if (point) point.input = from + ((to - from) * (gap - before)) / (after - before);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return `linear(${points.map((point) => `${roundedOf(point.output)} ${roundedOf(point.input ?? 0)}%`).join(',')})`;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
/** An easing in one spelling, so `ease` equals `cubic-bezier(.25, .1, .25, 1)`; `null` when it is not an easing. */
|
|
83
|
+
export const normalisedEasingOf = (value: string): string | null => {
|
|
84
|
+
const easing = value.trim().toLowerCase().replace(/\s+/gu, ' ');
|
|
85
|
+
|
|
86
|
+
if (easing === 'linear') return 'linear';
|
|
87
|
+
if (KEYWORD_EASINGS[easing]) return KEYWORD_EASINGS[easing];
|
|
88
|
+
|
|
89
|
+
const match = EASING_FUNCTION.exec(easing);
|
|
90
|
+
|
|
91
|
+
if (!match) return null;
|
|
92
|
+
|
|
93
|
+
const [, kind = '', body = ''] = match;
|
|
94
|
+
|
|
95
|
+
if (kind === 'linear') return linearOf(body);
|
|
96
|
+
|
|
97
|
+
const args = body.split(',').map((arg) => arg.trim());
|
|
98
|
+
|
|
99
|
+
if (kind === 'steps') return args.length === 1 || args.length === 2 ? `steps(${args[0]},${args[1] ?? 'end'})` : null;
|
|
100
|
+
|
|
101
|
+
const numbers = args.map(Number);
|
|
102
|
+
|
|
103
|
+
return numbers.length === 4 && numbers.every(Number.isFinite)
|
|
104
|
+
? `cubic-bezier(${numbers.map(roundedOf).join(',')})`
|
|
105
|
+
: null;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/** What a token stands for: a time, an easing, or both as a `spring()` token stores them (`<duration>ms linear(...)`). */
|
|
109
|
+
const meaningOf = (value: string) => {
|
|
110
|
+
const trimmed = value.trim();
|
|
111
|
+
const ms = msOf(trimmed);
|
|
112
|
+
|
|
113
|
+
if (ms !== null) return { ms, easing: null };
|
|
114
|
+
|
|
115
|
+
const [head = '', ...rest] = trimmed.split(/\s+/u);
|
|
116
|
+
const leading = msOf(head);
|
|
117
|
+
|
|
118
|
+
if (leading !== null) {
|
|
119
|
+
const easing = normalisedEasingOf(rest.join(' '));
|
|
120
|
+
|
|
121
|
+
return easing ? { ms: leading, easing } : null;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const easing = normalisedEasingOf(trimmed);
|
|
125
|
+
|
|
126
|
+
return easing ? { ms: null, easing } : null;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Adds the names of the `tokens` whose value equals a track's duration (`durationTokens`) or easing (`easingTokens`),
|
|
131
|
+
* in the order of `tokens`; a field without a match is left out.
|
|
132
|
+
*/
|
|
133
|
+
export const withTokenNames = (track: MotionTrack, tokens: readonly MotionToken[]): NamedMotionTrack => {
|
|
134
|
+
const easing = normalisedEasingOf(track.easing);
|
|
135
|
+
const durationTokens: string[] = [];
|
|
136
|
+
const easingTokens: string[] = [];
|
|
137
|
+
|
|
138
|
+
for (const token of tokens) {
|
|
139
|
+
const meaning = meaningOf(token.value);
|
|
140
|
+
|
|
141
|
+
if (!meaning) continue;
|
|
142
|
+
if (meaning.ms !== null && Math.abs(meaning.ms - track.duration) < 0.001) durationTokens.push(token.name);
|
|
143
|
+
if (meaning.easing !== null && easing !== null && meaning.easing === easing) easingTokens.push(token.name);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
...track,
|
|
148
|
+
...(durationTokens.length ? { durationTokens } : {}),
|
|
149
|
+
...(easingTokens.length ? { easingTokens } : {}),
|
|
150
|
+
};
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const rootNamesOf = (rules: CSSRuleList, names: Set<string>) => {
|
|
154
|
+
for (const rule of [...rules]) {
|
|
155
|
+
if (rule instanceof CSSStyleRule && /^(:root|html)$/u.test(rule.selectorText.trim()))
|
|
156
|
+
for (const property of [...rule.style]) if (property.startsWith('--')) names.add(property);
|
|
157
|
+
|
|
158
|
+
if ('cssRules' in rule && rule.cssRules instanceof CSSRuleList) rootNamesOf(rule.cssRules, names);
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
/** The custom properties declared on `:root` in the stylesheets of `document`, in declaration order, as computed there. */
|
|
163
|
+
export const rootTokensOf = (document: Document): MotionToken[] => {
|
|
164
|
+
const names = new Set<string>();
|
|
165
|
+
|
|
166
|
+
for (const sheet of [...document.styleSheets]) {
|
|
167
|
+
try {
|
|
168
|
+
rootNamesOf(sheet.cssRules, names);
|
|
169
|
+
} catch {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const computed = getComputedStyle(document.documentElement);
|
|
175
|
+
|
|
176
|
+
return [...names].map((name) => ({ name, value: computed.getPropertyValue(name).trim() }));
|
|
177
|
+
};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Paints `body` with the token `--<fill>` over the product's page colour, which shows when the product has no such token. */
|
|
2
|
+
export const paintFill = (body: HTMLElement, fill: string) => {
|
|
3
|
+
body.style.backgroundImage = `linear-gradient(var(--${fill}), var(--${fill}))`;
|
|
4
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export type ColorScheme = 'light' | 'dark';
|
|
2
|
+
|
|
3
|
+
const SCHEME_FEATURE = /\(\s*prefers-color-scheme\s*:\s*(light|dark)\s*\)/giu;
|
|
4
|
+
|
|
5
|
+
/** `media` with each `prefers-color-scheme` feature replaced by one that always or never matches, as `scheme` decides. */
|
|
6
|
+
export const pinnedMediaText = (media: string, scheme: ColorScheme) =>
|
|
7
|
+
media.replace(SCHEME_FEATURE, (_, wanted: string) =>
|
|
8
|
+
wanted.toLowerCase() === scheme ? '(width >= 0)' : '(width < 0)',
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const pinRules = (rules: CSSRuleList, scheme: ColorScheme) => {
|
|
12
|
+
for (const rule of Array.from(rules)) {
|
|
13
|
+
if (rule instanceof CSSMediaRule) {
|
|
14
|
+
const pinned = pinnedMediaText(rule.media.mediaText, scheme);
|
|
15
|
+
|
|
16
|
+
if (pinned !== rule.media.mediaText) rule.media.mediaText = pinned;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if ('cssRules' in rule) pinRules((rule as CSSGroupingRule).cssRules, scheme);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const pinSheets = (document: Document, scheme: ColorScheme) => {
|
|
24
|
+
for (const sheet of Array.from(document.styleSheets)) {
|
|
25
|
+
try {
|
|
26
|
+
pinRules(sheet.cssRules, scheme);
|
|
27
|
+
} catch {
|
|
28
|
+
// A cross-origin sheet hides its rules.
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export const pinScheme = (document: Document, scheme: ColorScheme) => {
|
|
34
|
+
document.documentElement.style.colorScheme = scheme;
|
|
35
|
+
pinSheets(document, scheme);
|
|
36
|
+
|
|
37
|
+
new MutationObserver((records) => {
|
|
38
|
+
pinSheets(document, scheme);
|
|
39
|
+
|
|
40
|
+
for (const record of records)
|
|
41
|
+
for (const node of Array.from(record.addedNodes))
|
|
42
|
+
if (node instanceof HTMLLinkElement) node.addEventListener('load', () => pinSheets(document, scheme));
|
|
43
|
+
}).observe(document.head, { childList: true, subtree: true, characterData: true });
|
|
44
|
+
};
|
package/design/web/frame.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { CallVariant, Drawing, fitOutOfFlow, mountDrawing, placeOverlays } from '../define-call';
|
|
2
|
-
import { Part } from '../define-part';
|
|
2
|
+
import { Motion, Part } from '../define-part';
|
|
3
3
|
import { applyEmbed, fitEmbed } from '../embed-page';
|
|
4
|
+
import { paintFill } from './frame-fill';
|
|
5
|
+
import { pinScheme } from './frame-scheme';
|
|
6
|
+
import { createMotionDriver, emulateReducedMotion, motionDriveMessageOf } from '../motion-drive';
|
|
4
7
|
import { runRules, stepMotion, SteppedMotion } from '../motion-runtime';
|
|
8
|
+
import { rootTokensOf, withTokenNames } from '../motion-tokens';
|
|
5
9
|
import { calls } from 'virtual:design-explore';
|
|
6
10
|
import { loadEnv, loadProductEnv } from 'virtual:design-explore/env';
|
|
7
11
|
import { parts, sketchParts, sketchTokens, tokens } from 'virtual:design-explore/system';
|
|
@@ -40,7 +44,11 @@ const fill = params.get('fill');
|
|
|
40
44
|
// On <html> a theme class ties with the `:root` defaults of the theme CSS, which come later and win.
|
|
41
45
|
if (surface) root.classList.add(`et-surface--${surface}`);
|
|
42
46
|
if (color) root.classList.add(`et-color--${color}`);
|
|
43
|
-
if (fill) document.body
|
|
47
|
+
if (fill) paintFill(document.body, fill);
|
|
48
|
+
|
|
49
|
+
const scheme = params.get('scheme');
|
|
50
|
+
|
|
51
|
+
if (scheme === 'light' || scheme === 'dark') pinScheme(document, scheme);
|
|
44
52
|
if (fit) {
|
|
45
53
|
document.documentElement.style.overflow = 'hidden';
|
|
46
54
|
root.style.width = 'max-content';
|
|
@@ -66,6 +74,12 @@ const fail = (message: string) => {
|
|
|
66
74
|
return null;
|
|
67
75
|
};
|
|
68
76
|
|
|
77
|
+
const failMissing = (message: string) => {
|
|
78
|
+
document.documentElement.setAttribute('data-et-missing', '');
|
|
79
|
+
|
|
80
|
+
return fail(message);
|
|
81
|
+
};
|
|
82
|
+
|
|
69
83
|
const showSetupError = (message: string) => {
|
|
70
84
|
markFailed(message);
|
|
71
85
|
|
|
@@ -96,10 +110,10 @@ let drawnPart: { part: Part<unknown>; states: Record<string, unknown> } | null =
|
|
|
96
110
|
|
|
97
111
|
const drawCall = async (): Promise<Drawing | null> => {
|
|
98
112
|
const call = calls[slug];
|
|
99
|
-
if (!call) return
|
|
113
|
+
if (!call) return failMissing(`design-explore: no call "${slug}"`);
|
|
100
114
|
|
|
101
115
|
const variant: CallVariant | undefined = (await call()).default.variants.find((o) => o.key === key);
|
|
102
|
-
if (!variant) return
|
|
116
|
+
if (!variant) return failMissing(`design-explore: call "${slug}" has no variant "${key}"`);
|
|
103
117
|
|
|
104
118
|
return variant.load().then(
|
|
105
119
|
(module) => module.default,
|
|
@@ -110,7 +124,7 @@ const drawCall = async (): Promise<Drawing | null> => {
|
|
|
110
124
|
const drawPart = async (name: string): Promise<Drawing | null> => {
|
|
111
125
|
const load = sketch ? sketchParts[name]?.[sketch]?.[sketchVariant]?.[partKey] : parts[name]?.[partKey];
|
|
112
126
|
if (!load)
|
|
113
|
-
return
|
|
127
|
+
return failMissing(
|
|
114
128
|
sketch
|
|
115
129
|
? `design-explore: variant "${sketchVariant}" of the sketch on ${sketch} in product "${name}" has no part "${partKey}"`
|
|
116
130
|
: `design-explore: product "${name}" has no part "${partKey}"`,
|
|
@@ -118,14 +132,14 @@ const drawPart = async (name: string): Promise<Drawing | null> => {
|
|
|
118
132
|
|
|
119
133
|
const loadProps = propsSketch ? sketchParts[name]?.[propsSketch]?.[propsVariant]?.[partKey] : load;
|
|
120
134
|
if (!loadProps)
|
|
121
|
-
return
|
|
135
|
+
return failMissing(
|
|
122
136
|
`design-explore: variant "${propsVariant}" of the sketch on ${propsSketch} in product "${name}" has no part "${partKey}"`,
|
|
123
137
|
);
|
|
124
138
|
|
|
125
139
|
try {
|
|
126
140
|
const [{ default: part }, { default: holder }] = await Promise.all([retried(load), retried(loadProps)]);
|
|
127
141
|
|
|
128
|
-
if (!(key in holder.states)) return
|
|
142
|
+
if (!(key in holder.states)) return failMissing(`design-explore: part "${partKey}" has no state "${key}"`);
|
|
129
143
|
|
|
130
144
|
drawnPart = { part: part as Part<unknown>, states: holder.states };
|
|
131
145
|
|
|
@@ -181,6 +195,11 @@ const report = () => {
|
|
|
181
195
|
);
|
|
182
196
|
};
|
|
183
197
|
|
|
198
|
+
const reportPainted = () =>
|
|
199
|
+
requestAnimationFrame(() =>
|
|
200
|
+
requestAnimationFrame(() => parent.postMessage({ type: 'design-explore:painted', variant: key }, '*')),
|
|
201
|
+
);
|
|
202
|
+
|
|
184
203
|
const stateMarkupOf = ({ part, states }: NonNullable<typeof drawnPart>, styles: string) => {
|
|
185
204
|
const sheets = new Set([styles]);
|
|
186
205
|
|
|
@@ -218,11 +237,53 @@ const exposeStepped = (options: { start: () => Promise<SteppedMotion>; interrupt
|
|
|
218
237
|
}),
|
|
219
238
|
seek: (ms: number) => steppedOf().seek(ms),
|
|
220
239
|
bounds: () => steppedOf().bounds(),
|
|
221
|
-
timeline: () =>
|
|
240
|
+
timeline: () => {
|
|
241
|
+
const tokens = rootTokensOf(document);
|
|
242
|
+
|
|
243
|
+
return {
|
|
244
|
+
end: steppedOf().end(),
|
|
245
|
+
tracks: steppedOf()
|
|
246
|
+
.tracks()
|
|
247
|
+
.map((track) => withTokenNames(track, tokens)),
|
|
248
|
+
interrupt: options.interrupt,
|
|
249
|
+
};
|
|
250
|
+
},
|
|
222
251
|
},
|
|
223
252
|
});
|
|
224
253
|
};
|
|
225
254
|
|
|
255
|
+
const motionStartOf = (options: {
|
|
256
|
+
drawn: NonNullable<typeof drawnPart>;
|
|
257
|
+
motion: Motion;
|
|
258
|
+
markupOf: (state: string) => Promise<string>;
|
|
259
|
+
switching?: () => void;
|
|
260
|
+
}) => {
|
|
261
|
+
const { drawn, motion, markupOf } = options;
|
|
262
|
+
|
|
263
|
+
return () =>
|
|
264
|
+
Promise.all([markupOf(motion.to), motion.interrupt === undefined ? null : markupOf(motion.from)]).then(
|
|
265
|
+
([markup, back]) => {
|
|
266
|
+
options.switching?.();
|
|
267
|
+
|
|
268
|
+
return stepMotion({
|
|
269
|
+
root,
|
|
270
|
+
markup,
|
|
271
|
+
motion,
|
|
272
|
+
...(back === null
|
|
273
|
+
? {}
|
|
274
|
+
: {
|
|
275
|
+
reverse: {
|
|
276
|
+
markup: back,
|
|
277
|
+
motion: Object.values(drawn.part.motions ?? {}).find(
|
|
278
|
+
(other) => other.from === motion.to && other.to === motion.from,
|
|
279
|
+
),
|
|
280
|
+
},
|
|
281
|
+
}),
|
|
282
|
+
});
|
|
283
|
+
},
|
|
284
|
+
);
|
|
285
|
+
};
|
|
286
|
+
|
|
226
287
|
const exposeMotion = (options: { drawn: NonNullable<typeof drawnPart>; name: string; styles: string }) => {
|
|
227
288
|
const { drawn, name, styles } = options;
|
|
228
289
|
const motion = drawn.part.motions?.[name];
|
|
@@ -235,29 +296,57 @@ const exposeMotion = (options: { drawn: NonNullable<typeof drawnPart>; name: str
|
|
|
235
296
|
return;
|
|
236
297
|
}
|
|
237
298
|
|
|
238
|
-
const markupOf = stateMarkupOf(drawn, styles);
|
|
239
|
-
|
|
240
299
|
exposeStepped({
|
|
241
300
|
interrupt: motion.interrupt ?? null,
|
|
242
|
-
start: ()
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
301
|
+
start: motionStartOf({ drawn, motion, markupOf: stateMarkupOf(drawn, styles) }),
|
|
302
|
+
});
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const settleAnimations = () => {
|
|
306
|
+
for (const animation of document.getAnimations()) {
|
|
307
|
+
if (Number.isFinite(animation.effect?.getComputedTiming().endTime)) animation.finish();
|
|
308
|
+
else animation.cancel();
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const listenForDrive = (drawn: NonNullable<typeof drawnPart>, styles: string) => {
|
|
313
|
+
const markupOf = stateMarkupOf(drawn, styles);
|
|
314
|
+
const drawnMarkup = root.innerHTML;
|
|
315
|
+
let restore: () => void = () => undefined;
|
|
316
|
+
|
|
317
|
+
const driver = createMotionDriver({
|
|
318
|
+
document,
|
|
319
|
+
reply: (answer) => parent.postMessage({ ...answer, variant: key }, '*'),
|
|
320
|
+
released: () => {
|
|
321
|
+
restore();
|
|
322
|
+
restore = () => undefined;
|
|
323
|
+
},
|
|
324
|
+
start: (name, reduced) => {
|
|
325
|
+
const motion = drawn.part.motions?.[name];
|
|
326
|
+
|
|
327
|
+
if (!motion) return Promise.reject(new Error(`design-explore: part "${partKey}" has no motion "${name}"`));
|
|
328
|
+
if (motion.from !== key)
|
|
329
|
+
return Promise.reject(new Error(`design-explore: motion "${name}" starts at "${motion.from}", not "${key}"`));
|
|
330
|
+
|
|
331
|
+
settleAnimations();
|
|
332
|
+
restore();
|
|
333
|
+
root.innerHTML = drawnMarkup;
|
|
334
|
+
|
|
335
|
+
return motionStartOf({
|
|
336
|
+
drawn,
|
|
337
|
+
motion,
|
|
338
|
+
markupOf,
|
|
339
|
+
switching: () => {
|
|
340
|
+
restore = emulateReducedMotion(document, reduced);
|
|
341
|
+
},
|
|
342
|
+
})();
|
|
343
|
+
},
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
addEventListener('message', (event) => {
|
|
347
|
+
const message = event.source === parent ? motionDriveMessageOf(event.data) : null;
|
|
348
|
+
|
|
349
|
+
if (message) void driver.handle(message);
|
|
261
350
|
});
|
|
262
351
|
};
|
|
263
352
|
|
|
@@ -337,6 +426,8 @@ const drawFrame = async () => {
|
|
|
337
426
|
if (flowTo && product) exposeFlowLine({ product, to: flowTo, styles: loaded.styles ?? '' });
|
|
338
427
|
else if (motionName && drawnPart) exposeMotion({ drawn: drawnPart, name: motionName, styles: loaded.styles ?? '' });
|
|
339
428
|
else if (drawnPart?.part.rules?.length) runPartRules(drawnPart, loaded.styles ?? '');
|
|
429
|
+
|
|
430
|
+
if (!flowTo && !motionName && drawnPart) listenForDrive(drawnPart, loaded.styles ?? '');
|
|
340
431
|
}
|
|
341
432
|
|
|
342
433
|
const place = () => {
|
|
@@ -355,6 +446,7 @@ const drawFrame = async () => {
|
|
|
355
446
|
if (fit) reported.observe(root);
|
|
356
447
|
reporting = true;
|
|
357
448
|
report();
|
|
449
|
+
reportPainted();
|
|
358
450
|
|
|
359
451
|
addEventListener('keydown', (event) => {
|
|
360
452
|
if (event.key === 'Escape') parent.postMessage({ type: 'design-explore:escape', variant: key }, '*');
|
|
@@ -371,4 +463,5 @@ void drawFrame().catch((error: unknown) => {
|
|
|
371
463
|
fail(`design-explore: frame failed\n${messageOf(error)}`);
|
|
372
464
|
reporting = true;
|
|
373
465
|
report();
|
|
466
|
+
reportPainted();
|
|
374
467
|
});
|
package/package.json
CHANGED
|
@@ -16,4 +16,6 @@ export declare const DRAWING_COMPILER_OPTIONS: {
|
|
|
16
16
|
* this config for itself. The same config goes to `.ethlete/design/tsconfig.json`, the nearest
|
|
17
17
|
* tsconfig an editor finds for a call file.
|
|
18
18
|
*/
|
|
19
|
+
/** Writes `text` unless the file already holds it: Vite reloads every frame on any write to a tsconfig it watches. */
|
|
20
|
+
export declare const writeTsconfigText: (path: string, text: string) => void;
|
|
19
21
|
export declare const writeCallsTsconfig: (target: string) => string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.writeCallsTsconfig = exports.DRAWING_COMPILER_OPTIONS = void 0;
|
|
3
|
+
exports.writeCallsTsconfig = exports.writeTsconfigText = exports.DRAWING_COMPILER_OPTIONS = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
6
|
const paths_1 = require("./paths");
|
|
@@ -23,6 +23,13 @@ exports.DRAWING_COMPILER_OPTIONS = {
|
|
|
23
23
|
* this config for itself. The same config goes to `.ethlete/design/tsconfig.json`, the nearest
|
|
24
24
|
* tsconfig an editor finds for a call file.
|
|
25
25
|
*/
|
|
26
|
+
/** Writes `text` unless the file already holds it: Vite reloads every frame on any write to a tsconfig it watches. */
|
|
27
|
+
const writeTsconfigText = (path, text) => {
|
|
28
|
+
if ((0, fs_1.existsSync)(path) && (0, fs_1.readFileSync)(path, 'utf8') === text)
|
|
29
|
+
return;
|
|
30
|
+
(0, fs_1.writeFileSync)(path, text);
|
|
31
|
+
};
|
|
32
|
+
exports.writeTsconfigText = writeTsconfigText;
|
|
26
33
|
const writeCallsTsconfig = (target) => {
|
|
27
34
|
const work = (0, paths_1.workRootOf)(target);
|
|
28
35
|
const path = (0, path_1.resolve)(work, 'tsconfig.json');
|
|
@@ -36,9 +43,9 @@ const writeCallsTsconfig = (target) => {
|
|
|
36
43
|
const text = `${JSON.stringify(config, null, 2)}\n`;
|
|
37
44
|
const editorPath = (0, path_1.resolve)(target, paths_1.DESIGN_DIR, 'tsconfig.json');
|
|
38
45
|
(0, fs_1.mkdirSync)(work, { recursive: true });
|
|
39
|
-
(0,
|
|
46
|
+
(0, exports.writeTsconfigText)(path, text);
|
|
40
47
|
(0, fs_1.mkdirSync)((0, path_1.dirname)(editorPath), { recursive: true });
|
|
41
|
-
(0,
|
|
48
|
+
(0, exports.writeTsconfigText)(editorPath, text);
|
|
42
49
|
return path;
|
|
43
50
|
};
|
|
44
51
|
exports.writeCallsTsconfig = writeCallsTsconfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calls-tsconfig.js","sourceRoot":"","sources":["../../../../../libs/cli/src/lib/design/calls-tsconfig.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"calls-tsconfig.js","sourceRoot":"","sources":["../../../../../libs/cli/src/lib/design/calls-tsconfig.ts"],"names":[],"mappings":";;;AAAA,2BAAwE;AACxE,+BAAwC;AACxC,mCAA8F;AAC9F,uDAAkE;AAErD,QAAA,wBAAwB,GAAG;IACtC,KAAK,EAAE,EAAE;IACT,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,UAAU;IAClB,gBAAgB,EAAE,SAAS;IAC3B,GAAG,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC;IACtB,MAAM,EAAE,IAAI;IACZ,wBAAwB,EAAE,IAAI;IAC9B,eAAe,EAAE,IAAI;IACrB,YAAY,EAAE,IAAI;IAClB,MAAM,EAAE,IAAI;CACb,CAAC;AAEF;;;;;GAKG;AACH,sHAAsH;AAC/G,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE;IAC9D,IAAI,IAAA,eAAU,EAAC,IAAI,CAAC,IAAI,IAAA,iBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,KAAK,IAAI;QAAE,OAAO;IAEpE,IAAA,kBAAa,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC5B,CAAC,CAAC;AAJW,QAAA,iBAAiB,qBAI5B;AAEK,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAE,EAAE;IACnD,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,MAAM,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAA,cAAO,EAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAA,cAAO,EAAC,IAAA,0BAAkB,GAAE,EAAE,gBAAgB,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,IAAA,cAAO,EAAC,IAAA,0BAAkB,GAAE,EAAE,iBAAiB,CAAC,CAAC;IACnE,MAAM,SAAS,GAAG,IAAA,6BAAW,EAAC,EAAE,QAAQ,EAAE,IAAA,kCAAgB,EAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAA,kBAAU,EAAC,MAAM,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;IAE9G,MAAM,MAAM,GAAG;QACb,eAAe,kCACV,gCAAwB,KAC3B,KAAK,kCAAO,SAAS,KAAE,iBAAiB,EAAE,CAAC,UAAU,CAAC,MACvD;QACD,OAAO,EAAE,CAAC,GAAG,IAAA,mBAAW,EAAC,MAAM,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC;KACnE,CAAC;IAEF,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IACpD,MAAM,UAAU,GAAG,IAAA,cAAO,EAAC,MAAM,EAAE,kBAAU,EAAE,eAAe,CAAC,CAAC;IAEhE,IAAA,cAAS,EAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,IAAA,yBAAiB,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC9B,IAAA,cAAS,EAAC,IAAA,cAAO,EAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,IAAA,yBAAiB,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAEpC,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAxBW,QAAA,kBAAkB,sBAwB7B"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* error draws an overlay on top of the drawing, so a screenshot of one looks like a design -
|
|
5
5
|
* never screenshot before this says `ok`. With `--call`, the call's status follows the check, but
|
|
6
6
|
* a check that cannot run (no browser, no server, a stale server) leaves the status it found.
|
|
7
|
+
* `--receipt <path>` also writes what the check said and whether it passed to that file.
|
|
7
8
|
*/
|
|
8
9
|
export declare const checkDesign: (options: {
|
|
9
10
|
target: string;
|
package/src/lib/design/check.js
CHANGED
|
@@ -11,6 +11,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.checkDesign = void 0;
|
|
13
13
|
const child_process_1 = require("child_process");
|
|
14
|
+
const fs_1 = require("fs");
|
|
15
|
+
const path_1 = require("path");
|
|
14
16
|
const browser_1 = require("./browser");
|
|
15
17
|
const calls_tsconfig_1 = require("./calls-tsconfig");
|
|
16
18
|
const paths_1 = require("./paths");
|
|
@@ -186,7 +188,7 @@ const runChecks = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
186
188
|
const wanted = (_c = flags['--variant']) === null || _c === void 0 ? void 0 : _c[0];
|
|
187
189
|
const tsconfig = '--tsconfig' in flags ? ((_e = (_d = flags['--tsconfig']) === null || _d === void 0 ? void 0 : _d[0]) !== null && _e !== void 0 ? _e : (0, calls_tsconfig_1.writeCallsTsconfig)(target)) : null;
|
|
188
190
|
if (lintFiles.length === 0 && !tsconfig && !slug) {
|
|
189
|
-
console.error(`usage: ${invocation} check [--lint <file>…] [--tsconfig [path]] [--call <slug> [--variant <key>]]`);
|
|
191
|
+
console.error(`usage: ${invocation} check [--lint <file>…] [--tsconfig [path]] [--call <slug> [--variant <key>]] [--receipt <path>]`);
|
|
190
192
|
return 2;
|
|
191
193
|
}
|
|
192
194
|
if (lintFiles.length > 0) {
|
|
@@ -218,28 +220,83 @@ const runChecks = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
218
220
|
const base = (_f = process.env['DE_URL']) !== null && _f !== void 0 ? _f : `http://localhost:${config ? (0, paths_1.portOf)(config) : paths_1.DEFAULT_PORT}`;
|
|
219
221
|
return runBrowser({ target, base, slug, wanted, fails });
|
|
220
222
|
});
|
|
223
|
+
const receiptArgvOf = (argv) => {
|
|
224
|
+
var _a;
|
|
225
|
+
const index = argv.indexOf('--receipt');
|
|
226
|
+
if (index === -1)
|
|
227
|
+
return { receipt: null, rest: argv };
|
|
228
|
+
return { receipt: (_a = argv[index + 1]) !== null && _a !== void 0 ? _a : null, rest: [...argv.slice(0, index), ...argv.slice(index + 2)] };
|
|
229
|
+
};
|
|
230
|
+
const writeReceipt = (options) => {
|
|
231
|
+
var _a, _b, _c, _d;
|
|
232
|
+
const flags = parse(options.argv, ['--lint', '--tsconfig', '--call', '--variant', '--product']);
|
|
233
|
+
(0, fs_1.mkdirSync)((0, path_1.dirname)(options.path), { recursive: true });
|
|
234
|
+
(0, fs_1.writeFileSync)(options.path, JSON.stringify({
|
|
235
|
+
call: (_b = (_a = flags['--call']) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : null,
|
|
236
|
+
variant: (_d = (_c = flags['--variant']) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : null,
|
|
237
|
+
ok: options.ok,
|
|
238
|
+
at: Math.floor(Date.now() / 1000),
|
|
239
|
+
said: options.said.trim(),
|
|
240
|
+
}));
|
|
241
|
+
};
|
|
221
242
|
/**
|
|
222
243
|
* Finds out why a call does not render, in the cheapest order: eslint on the named files, then
|
|
223
244
|
* `tsc --noEmit` over the checkout's calls, then the live page in a headless browser. A compile
|
|
224
245
|
* error draws an overlay on top of the drawing, so a screenshot of one looks like a design -
|
|
225
246
|
* never screenshot before this says `ok`. With `--call`, the call's status follows the check, but
|
|
226
247
|
* a check that cannot run (no browser, no server, a stale server) leaves the status it found.
|
|
248
|
+
* `--receipt <path>` also writes what the check said and whether it passed to that file.
|
|
227
249
|
*/
|
|
228
250
|
const checkDesign = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
251
|
+
const { receipt, rest } = receiptArgvOf(options.argv);
|
|
252
|
+
if (!receipt)
|
|
253
|
+
return checkWithStatus(options);
|
|
254
|
+
const said = [];
|
|
255
|
+
const log = console.log;
|
|
256
|
+
const error = console.error;
|
|
257
|
+
const tee = (write) => (...lines) => {
|
|
258
|
+
said.push(lines.map(String).join(' '));
|
|
259
|
+
write(...lines);
|
|
260
|
+
};
|
|
261
|
+
console.log = tee(log);
|
|
262
|
+
console.error = tee(error);
|
|
263
|
+
try {
|
|
264
|
+
const code = yield checkWithStatus(Object.assign(Object.assign({}, options), { argv: rest }));
|
|
265
|
+
writeReceipt({ path: receipt, argv: rest, ok: code === 0, said: said.join('\n') });
|
|
266
|
+
return code;
|
|
267
|
+
}
|
|
268
|
+
catch (thrown) {
|
|
269
|
+
said.push(thrown instanceof Error ? thrown.message : String(thrown));
|
|
270
|
+
writeReceipt({ path: receipt, argv: rest, ok: false, said: said.join('\n') });
|
|
271
|
+
throw thrown;
|
|
272
|
+
}
|
|
273
|
+
finally {
|
|
274
|
+
console.log = log;
|
|
275
|
+
console.error = error;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
exports.checkDesign = checkDesign;
|
|
279
|
+
const checkWithStatus = (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
229
280
|
var _a, _b;
|
|
230
|
-
const { target,
|
|
281
|
+
const { target, invocation } = options;
|
|
282
|
+
const complete = options.argv.includes('--complete');
|
|
283
|
+
const argv = options.argv.filter((argument) => argument !== '--complete');
|
|
231
284
|
const flags = parse(argv, ['--lint', '--tsconfig', '--call', '--variant', '--product']);
|
|
232
285
|
const products = flags['--product'];
|
|
233
286
|
if (products) {
|
|
234
287
|
if (products.length === 0) {
|
|
235
|
-
console.error(`usage: ${invocation} check --product <name
|
|
288
|
+
console.error(`usage: ${invocation} check --product <name>… [--complete]`);
|
|
236
289
|
return 2;
|
|
237
290
|
}
|
|
238
|
-
return (0, check_system_1.checkSystemRendered)({ target, config: (_a = (0, paths_1.readConfig)(target)) !== null && _a !== void 0 ? _a : {}, products });
|
|
291
|
+
return (0, check_system_1.checkSystemRendered)({ target, config: (_a = (0, paths_1.readConfig)(target)) !== null && _a !== void 0 ? _a : {}, products, complete });
|
|
239
292
|
}
|
|
240
293
|
const config = argv.length === 0 ? (0, paths_1.readConfig)(target) : null;
|
|
241
294
|
if ((config === null || config === void 0 ? void 0 : config.products) && Object.keys(config.products).length > 0)
|
|
242
|
-
return (0, check_system_1.checkSystemRendered)({ target, config, products: Object.keys(config.products) });
|
|
295
|
+
return (0, check_system_1.checkSystemRendered)({ target, config, products: Object.keys(config.products), complete });
|
|
296
|
+
if (complete) {
|
|
297
|
+
console.error(`usage: ${invocation} check [--product <name>…] --complete - --complete checks products only`);
|
|
298
|
+
return 2;
|
|
299
|
+
}
|
|
243
300
|
const slug = (_b = flags['--call']) === null || _b === void 0 ? void 0 : _b[0];
|
|
244
301
|
let failure = '';
|
|
245
302
|
let blocked = false;
|
|
@@ -280,5 +337,4 @@ const checkDesign = (options) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
280
337
|
throw error;
|
|
281
338
|
}
|
|
282
339
|
});
|
|
283
|
-
exports.checkDesign = checkDesign;
|
|
284
340
|
//# sourceMappingURL=check.js.map
|