@stag-build/phonebook 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +10 -1
  2. package/dist/cli.js +22 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/init.d.ts +21 -2
  5. package/dist/commands/init.js +33 -4
  6. package/dist/commands/init.js.map +1 -1
  7. package/dist/engines/android.d.ts +54 -0
  8. package/dist/engines/android.js +152 -6
  9. package/dist/engines/android.js.map +1 -1
  10. package/dist/engines/ios.d.ts +53 -4
  11. package/dist/engines/ios.js +142 -27
  12. package/dist/engines/ios.js.map +1 -1
  13. package/dist/errors.js +12 -1
  14. package/dist/errors.js.map +1 -1
  15. package/dist/ios/snapshotTestClass.d.ts +44 -0
  16. package/dist/ios/snapshotTestClass.js +115 -0
  17. package/dist/ios/snapshotTestClass.js.map +1 -1
  18. package/dist/ios/unrendered.d.ts +38 -0
  19. package/dist/ios/unrendered.js +92 -0
  20. package/dist/ios/unrendered.js.map +1 -0
  21. package/dist/manifest.d.ts +23 -2
  22. package/dist/manifest.js +58 -0
  23. package/dist/manifest.js.map +1 -1
  24. package/dist/mcp/server.d.ts +28 -0
  25. package/dist/mcp/server.js +232 -11
  26. package/dist/mcp/server.js.map +1 -1
  27. package/dist/png.d.ts +18 -0
  28. package/dist/png.js +44 -0
  29. package/dist/png.js.map +1 -0
  30. package/dist/scan/android.js +142 -16
  31. package/dist/scan/android.js.map +1 -1
  32. package/dist/scan/gaps.d.ts +52 -0
  33. package/dist/scan/gaps.js +169 -0
  34. package/dist/scan/gaps.js.map +1 -0
  35. package/dist/scan/ios.d.ts +44 -0
  36. package/dist/scan/ios.js +445 -41
  37. package/dist/scan/ios.js.map +1 -1
  38. package/dist/scan/scope.d.ts +30 -0
  39. package/dist/scan/scope.js +208 -0
  40. package/dist/scan/scope.js.map +1 -0
  41. package/dist/scan/stats.d.ts +12 -0
  42. package/dist/scan/stats.js +24 -0
  43. package/dist/scan/stats.js.map +1 -0
  44. package/dist/scan/types.d.ts +87 -1
  45. package/dist/site/build.js +0 -0
  46. package/dist/site/build.js.map +1 -1
  47. package/package.json +1 -1
@@ -1,6 +1,8 @@
1
1
  import { readdir, readFile } from 'node:fs/promises';
2
2
  import { join, relative } from 'node:path';
3
3
  import { previewHints } from './hints.js';
4
+ import { componentGaps } from './gaps.js';
5
+ import { computeStats } from './stats.js';
4
6
  /**
5
7
  * Regex-based heuristic scanner for Jetpack Compose `@Composable` / `@Preview`
6
8
  * functions. Walks each module's `src/main` tree and matches previews to
@@ -9,6 +11,8 @@ import { previewHints } from './hints.js';
9
11
  export async function scanAndroid(projectDir, modules) {
10
12
  const components = [];
11
13
  const orphanPreviews = [];
14
+ const extraLocales = await detectLocales(projectDir, modules);
15
+ const enumTypes = new Set();
12
16
  for (const module of modules) {
13
17
  const moduleDir = join(projectDir, ...module.split(':').filter(Boolean));
14
18
  const srcRoot = join(moduleDir, 'src', 'main');
@@ -16,6 +20,8 @@ export async function scanAndroid(projectDir, modules) {
16
20
  for (const file of files) {
17
21
  const relFile = relative(projectDir, file);
18
22
  const content = await readFile(file, 'utf8');
23
+ for (const enumName of findEnums(content))
24
+ enumTypes.add(enumName);
19
25
  const { fileComponents, filePreviews } = scanKotlinFile(content, relFile);
20
26
  for (const comp of fileComponents)
21
27
  components.push(comp);
@@ -24,10 +30,25 @@ export async function scanAndroid(projectDir, modules) {
24
30
  }
25
31
  components.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
26
32
  orphanPreviews.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);
33
+ for (const component of components) {
34
+ const gaps = componentGaps({
35
+ platform: 'android',
36
+ component: component.name,
37
+ properties: component.properties ?? [],
38
+ previewNames: component.previews.map((p) => p.displayName ?? p.name),
39
+ hasDarkPreview: component.previews.some((p) => p.dark),
40
+ previewText: component.previews.map((p) => p.annotationText ?? '').join('\n'),
41
+ extraLocales,
42
+ enumTypes: [...enumTypes],
43
+ });
44
+ if (gaps.length > 0)
45
+ component.gaps = gaps;
46
+ }
27
47
  return {
28
48
  platform: 'android',
29
49
  components,
30
50
  orphanPreviews,
51
+ extraLocales,
31
52
  stats: computeStats(components, orphanPreviews),
32
53
  };
33
54
  }
@@ -82,11 +103,13 @@ function scanKotlinFile(content, relFile) {
82
103
  });
83
104
  }
84
105
  else {
106
+ const properties = findParameters(content, fn.funIndex);
85
107
  fileComponents.push({
86
108
  name: fn.name,
87
109
  file: relFile,
88
110
  line: fn.line,
89
111
  previews: [],
112
+ ...(properties.length > 0 ? { properties } : {}),
90
113
  });
91
114
  }
92
115
  }
@@ -100,11 +123,13 @@ function scanKotlinFile(content, relFile) {
100
123
  filePreviews.push(preview);
101
124
  }
102
125
  else {
126
+ const properties = findParameters(content, fn.funIndex);
103
127
  fileComponents.push({
104
128
  name: fn.name,
105
129
  file: relFile,
106
130
  line: fn.line,
107
131
  previews: [preview],
132
+ ...(properties.length > 0 ? { properties } : {}),
108
133
  });
109
134
  }
110
135
  }
@@ -126,6 +151,123 @@ function bestPrefixMatch(name, components) {
126
151
  * the block of annotations (e.g. `@Composable`, `@Preview(...)`) found within
127
152
  * roughly 5 lines above the `fun` keyword.
128
153
  */
154
+ /**
155
+ * Parameters of the composable whose `fun` keyword starts at `funIndex`.
156
+ *
157
+ * A composable's parameters are its states: a `Boolean` has two values, a
158
+ * nullable can be absent, a `List` can be empty. `Modifier` is excluded because
159
+ * it configures placement rather than describing a state.
160
+ */
161
+ function findParameters(content, funIndex) {
162
+ const open = content.indexOf('(', funIndex);
163
+ if (open === -1)
164
+ return [];
165
+ let depth = 0;
166
+ let close = -1;
167
+ const cap = Math.min(content.length, open + 4000);
168
+ for (let i = open; i < cap; i++) {
169
+ if (content[i] === '(')
170
+ depth++;
171
+ else if (content[i] === ')') {
172
+ depth--;
173
+ if (depth === 0) {
174
+ close = i;
175
+ break;
176
+ }
177
+ }
178
+ }
179
+ if (close === -1)
180
+ return [];
181
+ const properties = [];
182
+ for (const raw of splitTopLevel(content.slice(open + 1, close))) {
183
+ const match = raw.match(/^\s*(?:@\w+(?:\([^)]*\))?\s+)*(\w+)\s*:\s*([^=]+)/);
184
+ if (!match)
185
+ continue;
186
+ const name = match[1];
187
+ const type = match[2].trim();
188
+ if (type.startsWith('Modifier'))
189
+ continue;
190
+ properties.push({ name, type, kind: classifyKotlinType(type) });
191
+ }
192
+ return properties;
193
+ }
194
+ /** Enum type names declared in this file. */
195
+ function findEnums(content) {
196
+ const results = [];
197
+ const regex = /\benum\s+class\s+([A-Z]\w*)/g;
198
+ let match;
199
+ while ((match = regex.exec(content)) !== null)
200
+ results.push(match[1]);
201
+ return results;
202
+ }
203
+ /** Splits a parameter list on commas that are not inside brackets. */
204
+ function splitTopLevel(text) {
205
+ const parts = [];
206
+ let depth = 0;
207
+ let current = '';
208
+ for (const char of text) {
209
+ if (char === '<' || char === '(' || char === '[')
210
+ depth++;
211
+ else if (char === '>' || char === ')' || char === ']')
212
+ depth--;
213
+ if (char === ',' && depth === 0) {
214
+ parts.push(current);
215
+ current = '';
216
+ continue;
217
+ }
218
+ current += char;
219
+ }
220
+ if (current.trim())
221
+ parts.push(current);
222
+ return parts;
223
+ }
224
+ /** Types whose values are a spectrum rather than a set of states worth previewing. */
225
+ const SCALAR_TYPES = new Set([
226
+ 'String', 'Int', 'Long', 'Float', 'Double', 'Char', 'Dp', 'TextUnit', 'Color',
227
+ 'Any', 'Unit',
228
+ ]);
229
+ function classifyKotlinType(type) {
230
+ const bare = type.replace(/\s+/g, '');
231
+ if (bare.endsWith('?'))
232
+ return 'optional';
233
+ if (/^(List|Set|Array|Collection|Iterable|Map)</.test(bare))
234
+ return 'collection';
235
+ if (bare === 'Boolean')
236
+ return 'bool';
237
+ if (bare.includes('->'))
238
+ return 'other';
239
+ if (SCALAR_TYPES.has(bare))
240
+ return 'other';
241
+ if (/^[A-Z]\w*$/.test(bare))
242
+ return 'enum-like';
243
+ return 'other';
244
+ }
245
+ /**
246
+ * Locales the project ships, from `res/values-<code>` resource directories.
247
+ * The unqualified `values` directory is the default language, not a locale.
248
+ */
249
+ async function detectLocales(projectDir, modules) {
250
+ const found = new Set();
251
+ for (const module of modules) {
252
+ const moduleDir = join(projectDir, ...module.split(':').filter(Boolean));
253
+ const resDir = join(moduleDir, 'src', 'main', 'res');
254
+ let entries;
255
+ try {
256
+ entries = await readdir(resDir, { withFileTypes: true });
257
+ }
258
+ catch {
259
+ continue;
260
+ }
261
+ for (const entry of entries) {
262
+ if (!entry.isDirectory())
263
+ continue;
264
+ const match = entry.name.match(/^values-([a-z]{2}(?:-r[A-Z]{2})?)$/);
265
+ if (match)
266
+ found.add(match[1].replace('-r', '-'));
267
+ }
268
+ }
269
+ return [...found].sort();
270
+ }
129
271
  function findAnnotatedFunctions(content) {
130
272
  const results = [];
131
273
  const funRegex = /\bfun\s+([A-Z]\w*)\s*\(/g;
@@ -182,22 +324,6 @@ function matchPreviewsToComponents(previews, components, orphanPreviews) {
182
324
  }
183
325
  }
184
326
  }
185
- function computeStats(components, orphanPreviews) {
186
- const withPreview = components.filter((c) => c.previews.length > 0).length;
187
- const withDarkPreview = components.filter((c) => c.previews.some((p) => p.dark)).length;
188
- const totalPreviews = components.reduce((sum, c) => sum + c.previews.length, 0) + orphanPreviews.length;
189
- const allPreviews = [...components.flatMap((c) => c.previews), ...orphanPreviews];
190
- const hintCount = allPreviews.reduce((sum, p) => sum + (p.hints?.length ?? 0), 0);
191
- const selfPreviewed = components.filter((c) => c.previews.some((p) => p.name === c.name && p.line === c.line)).length;
192
- return {
193
- components: components.length,
194
- withPreview,
195
- withDarkPreview,
196
- totalPreviews,
197
- hintCount,
198
- selfPreviewed,
199
- };
200
- }
201
327
  async function walkKotlinFiles(dir) {
202
328
  const results = [];
203
329
  let entries;
@@ -1 +1 @@
1
- {"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/scan/android.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/scan/android.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Coverage gaps: what a component is *missing*, as opposed to what an existing
3
+ * preview got wrong.
4
+ *
5
+ * `hints.ts` answers "this preview's name promises something its annotation
6
+ * doesn't declare". That only ever fires on a preview that already exists, so a
7
+ * component with no previews at all — or one preview standing in for four
8
+ * states — produces no hints and reads as fine.
9
+ *
10
+ * This module answers the other half: given what a component actually is (its
11
+ * stored properties or parameters) and what the project supports (its locales),
12
+ * which previews *should* exist and don't. The output is guidance for an agent
13
+ * to act on, not a verdict — Phonebook renders previews, it never writes them,
14
+ * and whether a state is worth covering is a judgment the agent makes with the
15
+ * component's source in front of it.
16
+ */
17
+ export type PropertyKind = 'bool' | 'optional' | 'collection' | 'enum-like' | 'other';
18
+ export interface ComponentProperty {
19
+ name: string;
20
+ /** Type as written in source, e.g. "Bool", "[Status]", "Status?". */
21
+ type: string;
22
+ kind: PropertyKind;
23
+ }
24
+ export interface CoverageGap {
25
+ rule: string;
26
+ severity: 'warning' | 'info';
27
+ message: string;
28
+ suggestion: string;
29
+ }
30
+ export interface CoverageGapInput {
31
+ platform: 'android' | 'ios';
32
+ component: string;
33
+ properties: ComponentProperty[];
34
+ /** Display names of the previews already covering this component. */
35
+ previewNames: string[];
36
+ /** True when at least one existing preview declares a dark configuration. */
37
+ hasDarkPreview: boolean;
38
+ /** Raw text of every existing preview for this component, for "already declares it" checks. */
39
+ previewText: string;
40
+ /** Locales the project ships, beyond its development language. Empty when unlocalized. */
41
+ extraLocales: string[];
42
+ /** Enum types declared anywhere in the project. A property of one of these
43
+ * has a known, finite set of states; a property of any other named type is
44
+ * left alone rather than guessed at. */
45
+ enumTypes?: string[];
46
+ /** Types the component reads via `@Environment(X.self)` (iOS only). */
47
+ environmentTypes?: string[];
48
+ /** Everything the previews pass to `.environment(...)`, including through any
49
+ * project helper they call. A type named anywhere in here is supplied. */
50
+ environmentProvided?: string;
51
+ }
52
+ export declare function componentGaps(input: CoverageGapInput): CoverageGap[];
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Coverage gaps: what a component is *missing*, as opposed to what an existing
3
+ * preview got wrong.
4
+ *
5
+ * `hints.ts` answers "this preview's name promises something its annotation
6
+ * doesn't declare". That only ever fires on a preview that already exists, so a
7
+ * component with no previews at all — or one preview standing in for four
8
+ * states — produces no hints and reads as fine.
9
+ *
10
+ * This module answers the other half: given what a component actually is (its
11
+ * stored properties or parameters) and what the project supports (its locales),
12
+ * which previews *should* exist and don't. The output is guidance for an agent
13
+ * to act on, not a verdict — Phonebook renders previews, it never writes them,
14
+ * and whether a state is worth covering is a judgment the agent makes with the
15
+ * component's source in front of it.
16
+ */
17
+ /** A state name the previews already mention, however it is spelled. */
18
+ function covers(input, ...words) {
19
+ const haystack = [...input.previewNames, input.previewText].join(' ').toLowerCase();
20
+ return words.some((w) => haystack.includes(w.toLowerCase()));
21
+ }
22
+ /**
23
+ * True when some preview passes *this* property in its absent or empty form.
24
+ *
25
+ * Checked against the property by name rather than by looking for "nil"
26
+ * anywhere: a preview that passes `author: nil` covers the absent author, and
27
+ * says nothing about an empty `replies` in the same call.
28
+ */
29
+ function coversPropertyAs(input, property, forms) {
30
+ const pattern = new RegExp(`\\b${property}\\s*[:=]\\s*(?:${forms.source})`, 'i');
31
+ return pattern.test(input.previewText);
32
+ }
33
+ const ABSENT_FORMS = /nil|null|\.none|None/;
34
+ const EMPTY_FORMS = /\[\s*\]|emptyList\(\)|emptySet\(\)|\.init\(\)|listOf\(\)|setOf\(\)/;
35
+ function stateCount(input) {
36
+ // A component with one preview has one state covered no matter what that
37
+ // preview is called; "Default" is not two states.
38
+ return new Set(input.previewNames.map((n) => n.toLowerCase())).size;
39
+ }
40
+ const IOS_ENV = {
41
+ dark: '.preferredColorScheme(.dark)',
42
+ dynamicType: '.dynamicTypeSize(.accessibility3)',
43
+ locale: (code) => `.environment(\\.locale, .init(identifier: "${code}"))`,
44
+ };
45
+ const ANDROID_ENV = {
46
+ dark: '@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)',
47
+ dynamicType: '@Preview(fontScale = 1.5f)',
48
+ locale: (code) => `@Preview(locale = "${code}")`,
49
+ };
50
+ export function componentGaps(input) {
51
+ const gaps = [];
52
+ const env = input.platform === 'ios' ? IOS_ENV : ANDROID_ENV;
53
+ const previewCount = input.previewNames.length;
54
+ if (previewCount === 0) {
55
+ gaps.push({
56
+ rule: 'no-preview',
57
+ severity: 'warning',
58
+ message: `"${input.component}" has no preview, so it never reaches the gallery.`,
59
+ suggestion: 'add one preview per meaningful state; call get_preview_guidance for the template',
60
+ });
61
+ }
62
+ for (const prop of input.properties) {
63
+ if (prop.kind === 'bool') {
64
+ const both = stateCount(input) >= 2;
65
+ if (!both) {
66
+ gaps.push({
67
+ rule: 'state-bool',
68
+ severity: 'warning',
69
+ message: `"${input.component}" takes ${prop.name}: ${prop.type}, which has two states, but ${previewCount === 0 ? 'no preview covers either' : 'only one preview exists'}.`,
70
+ suggestion: `one preview per value of ${prop.name}, named "${input.component}/<State>"`,
71
+ });
72
+ }
73
+ continue;
74
+ }
75
+ if (prop.kind === 'optional') {
76
+ const covered = coversPropertyAs(input, prop.name, ABSENT_FORMS) ||
77
+ covers(input, 'empty', 'none', 'missing', 'placeholder');
78
+ if (!covered) {
79
+ gaps.push({
80
+ rule: 'state-optional',
81
+ severity: 'warning',
82
+ message: `"${input.component}" takes ${prop.name}: ${prop.type}, which can be absent, and no preview covers the absent case.`,
83
+ suggestion: `a preview with ${prop.name} set to nil, named "${input.component}/Empty"`,
84
+ });
85
+ }
86
+ continue;
87
+ }
88
+ if (prop.kind === 'collection') {
89
+ const covered = coversPropertyAs(input, prop.name, EMPTY_FORMS) || covers(input, 'empty', 'none', 'zero');
90
+ if (!covered) {
91
+ gaps.push({
92
+ rule: 'state-collection',
93
+ severity: 'warning',
94
+ message: `"${input.component}" takes ${prop.name}: ${prop.type}, which can be empty, and no preview covers the empty case.`,
95
+ suggestion: `a preview with ${prop.name} empty, named "${input.component}/Empty"`,
96
+ });
97
+ }
98
+ continue;
99
+ }
100
+ if (prop.kind === 'enum-like') {
101
+ // Only when the project actually declares it as an enum. Every other
102
+ // named type — a class, a struct, a protocol — has no finite set of
103
+ // states to enumerate, and guessing at one would fill the report with
104
+ // work that does not exist.
105
+ const declared = (input.enumTypes ?? []).includes(prop.type.replace(/\s+/g, ''));
106
+ if (declared && stateCount(input) < 2) {
107
+ gaps.push({
108
+ rule: 'state-enum',
109
+ severity: 'warning',
110
+ message: `"${input.component}" takes ${prop.name}: ${prop.type}, an enum, and ${previewCount === 0 ? 'no preview covers any case' : 'only one preview exists'}.`,
111
+ suggestion: `one preview per case of ${prop.type}, named "${input.component}/<Case>"`,
112
+ });
113
+ }
114
+ }
115
+ }
116
+ // Before every configuration rule below, because those describe a preview
117
+ // that renders the wrong thing and this one describes a preview that does not
118
+ // render at all. SwiftUI has no default for an @Observable read out of the
119
+ // environment: the property's getter traps the moment the body reads it, so a
120
+ // preview missing one is not thin coverage, it is a crash with a name.
121
+ //
122
+ // Direct reads only. A view that renders a subview with environment needs of
123
+ // its own still traps, and finding that needs the call graph rather than the
124
+ // one struct — worth doing, not done here, and a rule that catches the direct
125
+ // case is already the difference between a preview that runs and one that
126
+ // does not.
127
+ if (input.platform === 'ios' && previewCount > 0) {
128
+ const provided = input.environmentProvided ?? '';
129
+ for (const type of input.environmentTypes ?? []) {
130
+ if (provided.includes(type))
131
+ continue;
132
+ gaps.push({
133
+ rule: 'env-missing',
134
+ severity: 'warning',
135
+ message: `"${input.component}" reads @Environment(${type}.self) and no preview supplies one, so every preview of it traps at render.`,
136
+ suggestion: `pass ${type} to .environment(...) in each preview — an unsatisfied @Environment traps rather than defaulting`,
137
+ });
138
+ }
139
+ }
140
+ if (previewCount > 0 && !input.hasDarkPreview) {
141
+ gaps.push({
142
+ rule: 'theme-dark',
143
+ severity: 'warning',
144
+ message: `"${input.component}" has no dark-theme preview, so a dark-mode regression cannot show up in the gallery.`,
145
+ suggestion: env.dark,
146
+ });
147
+ }
148
+ if (previewCount > 0 && !covers(input, 'dynamictypesize', 'fontscale', 'sizecategory', 'accessibility')) {
149
+ gaps.push({
150
+ rule: 'dynamic-type',
151
+ severity: 'info',
152
+ message: `"${input.component}" has no large-text preview, the configuration that most often breaks a layout.`,
153
+ suggestion: env.dynamicType,
154
+ });
155
+ }
156
+ // Silent on an unlocalized project: telling every repository to cover locales
157
+ // it does not ship would make the report noise rather than a to-do list.
158
+ if (previewCount > 0 && input.extraLocales.length > 0 && !covers(input, 'locale', 'environment(\\.locale', 'rtl')) {
159
+ const sample = input.extraLocales[0];
160
+ gaps.push({
161
+ rule: 'localization',
162
+ severity: 'info',
163
+ message: `The project ships ${input.extraLocales.length} localization${input.extraLocales.length === 1 ? '' : 's'} (${input.extraLocales.slice(0, 4).join(', ')}${input.extraLocales.length > 4 ? ', …' : ''}) and "${input.component}" is previewed in the development language only.`,
164
+ suggestion: env.locale(sample),
165
+ });
166
+ }
167
+ return gaps;
168
+ }
169
+ //# sourceMappingURL=gaps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gaps.js","sourceRoot":"","sources":["../../src/scan/gaps.ts"],"names":[],"mappings":"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"}
@@ -5,3 +5,47 @@ import type { CoverageReport } from './types.js';
5
5
  * matches previews to components by file + name heuristics.
6
6
  */
7
7
  export declare function scanIos(projectDir: string): Promise<CoverageReport>;
8
+ /**
9
+ * True when `source` renders `component` — the name followed by an opening
10
+ * parenthesis, which is how a SwiftUI view is instantiated.
11
+ *
12
+ * A bare mention is not a render: `StatusRowView.Context` names the type
13
+ * without showing anything, and a comment saying "like AvatarView" shows even
14
+ * less. Requiring the parenthesis costs the zero-argument spelling nothing —
15
+ * `RowList()` still matches — and keeps the answer to something a reader
16
+ * would agree with.
17
+ */
18
+ export declare function rendersComponent(source: string, component: string): boolean;
19
+ /**
20
+ * Where `source` renders `component` behind a condition, when every place it
21
+ * does is behind one — so whether it appears depends on state the caller sets.
22
+ *
23
+ * This is what separates a parent that shows a child from a parent that might.
24
+ * IceCubes' StatusRowView renders StatusRowDetailView only `if isFocused`, and
25
+ * its one preview builds a timeline row, where nothing is focused: the preview
26
+ * exists, and the detail view is not in it. Treating that as coverage is how a
27
+ * redesigned view reaches no screenshot and no one is told.
28
+ *
29
+ * The brace stack is the whole trick — a frame remembers the text that opened
30
+ * it, and that text is the condition when it reads as one. No Swift is
31
+ * evaluated and none needs to be: the question is whether a render is guarded
32
+ * and behind what, not which way the guard goes.
33
+ *
34
+ * Returns the innermost condition around the first guarded render. A component
35
+ * that renders the same child behind two different conditions is rare, and the
36
+ * answer to the first is the answer to both: nothing shows it.
37
+ */
38
+ export declare function onlyRendersConditionally(source: string, component: string): {
39
+ guard: string;
40
+ line: number;
41
+ } | undefined;
42
+ /**
43
+ * Which of `known` this source renders — the same rule as `rendersComponent`,
44
+ * asked once for the whole set.
45
+ *
46
+ * Reading the names out of the source and intersecting beats testing every
47
+ * known component against it: a project has hundreds of components and a scan
48
+ * asks this of every preview body, and the regex-per-name version is that
49
+ * product.
50
+ */
51
+ export declare function componentsNamedIn(source: string, known: ReadonlySet<string>): string[];