@oddkin/analyzer 0.0.0-stage → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +40 -2
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +65 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/contracts.d.ts +29 -0
  8. package/dist/contracts.d.ts.map +1 -0
  9. package/dist/contracts.js +57 -0
  10. package/dist/contracts.js.map +1 -0
  11. package/dist/docs.d.ts +34 -0
  12. package/dist/docs.d.ts.map +1 -0
  13. package/dist/docs.js +63 -0
  14. package/dist/docs.js.map +1 -0
  15. package/dist/emit.d.ts +38 -0
  16. package/dist/emit.d.ts.map +1 -0
  17. package/dist/emit.js +406 -0
  18. package/dist/emit.js.map +1 -0
  19. package/dist/examples.d.ts +35 -0
  20. package/dist/examples.d.ts.map +1 -0
  21. package/dist/examples.js +345 -0
  22. package/dist/examples.js.map +1 -0
  23. package/dist/extract.d.ts +208 -0
  24. package/dist/extract.d.ts.map +1 -0
  25. package/dist/extract.js +1570 -0
  26. package/dist/extract.js.map +1 -0
  27. package/dist/foundations.d.ts +36 -0
  28. package/dist/foundations.d.ts.map +1 -0
  29. package/dist/foundations.js +108 -0
  30. package/dist/foundations.js.map +1 -0
  31. package/dist/history.d.ts +10 -0
  32. package/dist/history.d.ts.map +1 -0
  33. package/dist/history.js +62 -0
  34. package/dist/history.js.map +1 -0
  35. package/dist/impact-bin.d.ts +3 -0
  36. package/dist/impact-bin.d.ts.map +1 -0
  37. package/dist/impact-bin.js +7 -0
  38. package/dist/impact-bin.js.map +1 -0
  39. package/dist/impact-cli.d.ts +8 -0
  40. package/dist/impact-cli.d.ts.map +1 -0
  41. package/dist/impact-cli.js +121 -0
  42. package/dist/impact-cli.js.map +1 -0
  43. package/dist/impact.d.ts +282 -0
  44. package/dist/impact.d.ts.map +1 -0
  45. package/dist/impact.js +744 -0
  46. package/dist/impact.js.map +1 -0
  47. package/dist/index.d.ts +82 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +228 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/kit/agents-md.d.ts +10 -0
  52. package/dist/kit/agents-md.d.ts.map +1 -0
  53. package/dist/kit/agents-md.js +64 -0
  54. package/dist/kit/agents-md.js.map +1 -0
  55. package/dist/kit/cli.d.ts +8 -0
  56. package/dist/kit/cli.d.ts.map +1 -0
  57. package/dist/kit/cli.js +214 -0
  58. package/dist/kit/cli.js.map +1 -0
  59. package/dist/kit/context.d.ts +104 -0
  60. package/dist/kit/context.d.ts.map +1 -0
  61. package/dist/kit/context.js +323 -0
  62. package/dist/kit/context.js.map +1 -0
  63. package/dist/kit/index.d.ts +12 -0
  64. package/dist/kit/index.d.ts.map +1 -0
  65. package/dist/kit/index.js +12 -0
  66. package/dist/kit/index.js.map +1 -0
  67. package/dist/kit/kit.d.ts +62 -0
  68. package/dist/kit/kit.d.ts.map +1 -0
  69. package/dist/kit/kit.js +626 -0
  70. package/dist/kit/kit.js.map +1 -0
  71. package/dist/kit/llms.d.ts +22 -0
  72. package/dist/kit/llms.d.ts.map +1 -0
  73. package/dist/kit/llms.js +58 -0
  74. package/dist/kit/llms.js.map +1 -0
  75. package/dist/kit/package-kit.d.ts +18 -0
  76. package/dist/kit/package-kit.d.ts.map +1 -0
  77. package/dist/kit/package-kit.js +224 -0
  78. package/dist/kit/package-kit.js.map +1 -0
  79. package/dist/kit-bin.d.ts +3 -0
  80. package/dist/kit-bin.d.ts.map +1 -0
  81. package/dist/kit-bin.js +7 -0
  82. package/dist/kit-bin.js.map +1 -0
  83. package/dist/published.d.ts +43 -0
  84. package/dist/published.d.ts.map +1 -0
  85. package/dist/published.js +62 -0
  86. package/dist/published.js.map +1 -0
  87. package/dist/references.d.ts +70 -0
  88. package/dist/references.d.ts.map +1 -0
  89. package/dist/references.js +255 -0
  90. package/dist/references.js.map +1 -0
  91. package/dist/style-mappings.d.ts +46 -0
  92. package/dist/style-mappings.d.ts.map +1 -0
  93. package/dist/style-mappings.js +246 -0
  94. package/dist/style-mappings.js.map +1 -0
  95. package/dist/stylesheets.d.ts +56 -0
  96. package/dist/stylesheets.d.ts.map +1 -0
  97. package/dist/stylesheets.js +83 -0
  98. package/dist/stylesheets.js.map +1 -0
  99. package/dist/verification.d.ts +62 -0
  100. package/dist/verification.d.ts.map +1 -0
  101. package/dist/verification.js +115 -0
  102. package/dist/verification.js.map +1 -0
  103. package/package.json +45 -4
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Authored references (metadata-and-analyzer.md §5): names that descriptions, guidance, and
3
+ * examples cite in code spans must exist in the published contracts. Only Oddkin-shaped spans are
4
+ * checked; other code spans (HTML, ARIA, DOM APIs, values) are prose. Node-free and DOM-free.
5
+ */
6
+ import type { AnalyzerDiagnostic, SourceLocation } from './extract.js';
7
+ export declare const UNKNOWN_REFERENCE = "agent.guidance.unknownReference";
8
+ /** A piece of authored text and what its member-shaped references resolve against. */
9
+ export interface AuthoredText {
10
+ readonly text: string;
11
+ /** Tag of the element the text describes; `.prop`, `name()`, `attr="v"`, … resolve against it. */
12
+ readonly subject?: string;
13
+ /** Where the text lives, e.g. `odd-card --odd-card-shadow` or `example:odd-card/default guidance`. */
14
+ readonly at: string;
15
+ readonly source?: SourceLocation;
16
+ }
17
+ interface ElementNames {
18
+ readonly members: Set<string>;
19
+ readonly methods: Set<string>;
20
+ /** Attribute name → allowed values when its type is a union of string literals. */
21
+ readonly attributes: Map<string, readonly string[] | undefined>;
22
+ readonly events: Set<string>;
23
+ readonly slots: Set<string>;
24
+ readonly parts: Set<string>;
25
+ readonly cssProperties: Set<string>;
26
+ readonly cssStates: Set<string>;
27
+ }
28
+ export interface ReferenceIndex {
29
+ readonly elements: ReadonlyMap<string, ElementNames>;
30
+ /** Tag prefixes of the indexed elements (`odd-`): only tag-shaped spans with them are checked. */
31
+ readonly prefixes: ReadonlySet<string>;
32
+ /** Package scopes (`@oddkin`): only import specifiers in them are checked. */
33
+ readonly scopes: ReadonlySet<string>;
34
+ readonly imports: (specifier: string) => boolean;
35
+ readonly tokens: ReadonlySet<string>;
36
+ readonly variables: ReadonlySet<string>;
37
+ readonly recipes: ReadonlySet<string>;
38
+ /** Classes the published document stylesheets define (`odd-box`), without the dot. */
39
+ readonly classes: ReadonlySet<string>;
40
+ /** Published contract ids (`contract:core/scope`). */
41
+ readonly contracts: ReadonlySet<string>;
42
+ }
43
+ export interface ReferenceSources {
44
+ /** Published `custom-elements.json` manifests. */
45
+ readonly manifests: readonly unknown[];
46
+ /** Published `oddkin.metadata.json` documents (layout recipes, document stylesheet variables). */
47
+ readonly metadata?: readonly unknown[];
48
+ /** Packages whose `exports` define the public import specifiers. */
49
+ readonly packages?: readonly {
50
+ readonly name: string;
51
+ readonly exports?: unknown;
52
+ }[];
53
+ /** Token ids (`color.focus.ring`) and the CSS custom properties a theme declares. */
54
+ readonly tokens?: readonly string[];
55
+ readonly variables?: readonly string[];
56
+ /** Contract ids from the installed packages' `contracts.json`. */
57
+ readonly contracts?: readonly string[];
58
+ }
59
+ export declare function referenceIndex(sources: ReferenceSources): ReferenceIndex;
60
+ /**
61
+ * Authored text of a package: element and member descriptions and deprecation reasons from its
62
+ * CEM, authored facts (`provenance: 'authored'`) from its metadata, and example texts.
63
+ */
64
+ export declare function authoredTexts(manifest: unknown, metadata?: unknown, examples?: readonly {
65
+ readonly texts?: readonly AuthoredText[];
66
+ }[]): AuthoredText[];
67
+ /** Every code span in `texts` that names an Oddkin contract must resolve in `index`. */
68
+ export declare function checkReferences(texts: readonly AuthoredText[], index: ReferenceIndex): AnalyzerDiagnostic[];
69
+ export {};
70
+ //# sourceMappingURL=references.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,255 @@
1
+ export const UNKNOWN_REFERENCE = 'agent.guidance.unknownReference';
2
+ const list = (value) => Array.isArray(value) ? value.filter((v) => !!v && typeof v === 'object') : [];
3
+ const names = (value) => new Set(list(value).flatMap((v) => (typeof v['name'] === 'string' ? [v['name']] : [])));
4
+ /** `"a" | "b"` → ['a', 'b']; anything else (boolean, string, number, mixed) → undefined. */
5
+ function literalUnion(type) {
6
+ const text = type?.text;
7
+ if (typeof text !== 'string')
8
+ return undefined;
9
+ const parts = text.split('|').map((p) => p.trim());
10
+ const values = parts.map((p) => /^"([^"]*)"$/.exec(p)?.[1]);
11
+ return values.every((v) => v !== undefined) ? values : undefined;
12
+ }
13
+ const declarations = (manifest) => list(manifest?.modules).flatMap((m) => list(m['declarations']));
14
+ /** The document stylesheet records of the published metadata. */
15
+ const sheets = (sources) => (sources.metadata ?? []).flatMap((m) => Object.values((m
16
+ ?.stylesheets ?? {})));
17
+ export function referenceIndex(sources) {
18
+ const elements = new Map();
19
+ for (const manifest of sources.manifests)
20
+ for (const d of declarations(manifest)) {
21
+ if (typeof d['tagName'] !== 'string')
22
+ continue;
23
+ const members = list(d['members']).filter((m) => !m['static'] && m['privacy'] !== 'private');
24
+ elements.set(d['tagName'], {
25
+ members: names(members),
26
+ methods: names(members.filter((m) => m['kind'] === 'method')),
27
+ attributes: new Map(list(d['attributes']).flatMap((a) => typeof a['name'] === 'string' ? [[a['name'], literalUnion(a['type'])]] : [])),
28
+ events: names(d['events']),
29
+ slots: names(d['slots']),
30
+ parts: names(d['cssParts']),
31
+ cssProperties: names(d['cssProperties']),
32
+ cssStates: names(d['cssStates']),
33
+ });
34
+ }
35
+ const packages = sources.packages ?? [];
36
+ const entries = new Map(packages.map((p) => [
37
+ p.name,
38
+ typeof p.exports === 'string'
39
+ ? ['.']
40
+ : Object.keys((p.exports ?? { '.': '' })),
41
+ ]));
42
+ return {
43
+ elements,
44
+ prefixes: new Set([...elements.keys()].map((tag) => tag.slice(0, tag.indexOf('-') + 1))),
45
+ scopes: new Set(packages.map((p) => p.name.split('/')[0] ?? '')),
46
+ imports: (specifier) => {
47
+ const name = specifier.split('/').slice(0, 2).join('/');
48
+ const subpath = `.${specifier.slice(name.length)}`;
49
+ return (entries.get(name) ?? []).some((key) => {
50
+ const star = key.indexOf('*');
51
+ return star < 0
52
+ ? key === subpath
53
+ : subpath.startsWith(key.slice(0, star)) && subpath.endsWith(key.slice(star + 1));
54
+ });
55
+ },
56
+ tokens: new Set(sources.tokens ?? []),
57
+ variables: new Set([
58
+ ...(sources.variables ?? []),
59
+ ...sheets(sources).flatMap((sheet) => Array.isArray(sheet.variables)
60
+ ? sheet.variables.filter((v) => typeof v === 'string')
61
+ : []),
62
+ ]),
63
+ contracts: new Set(sources.contracts ?? []),
64
+ classes: new Set(sheets(sources).flatMap((sheet) => Array.isArray(sheet.classes)
65
+ ? sheet.classes.filter((c) => typeof c === 'string')
66
+ : [])),
67
+ recipes: new Set((sources.metadata ?? []).flatMap((m) => Object.values((m?.recipes ?? {})).flatMap((r) => (typeof r.name === 'string' ? [r.name] : [])))),
68
+ };
69
+ }
70
+ const DESCRIBED = [
71
+ ['members', 'name'],
72
+ ['attributes', 'name'],
73
+ ['events', 'name'],
74
+ ['slots', 'name'],
75
+ ['cssParts', 'name'],
76
+ ['cssProperties', 'name'],
77
+ ['cssStates', 'name'],
78
+ ];
79
+ /**
80
+ * Authored text of a package: element and member descriptions and deprecation reasons from its
81
+ * CEM, authored facts (`provenance: 'authored'`) from its metadata, and example texts.
82
+ */
83
+ export function authoredTexts(manifest, metadata, examples = []) {
84
+ const out = [];
85
+ const add = (text, at, subject) => {
86
+ if (typeof text === 'string' && text.includes('`'))
87
+ out.push({ text, at, ...(subject ? { subject } : {}) });
88
+ };
89
+ for (const d of declarations(manifest)) {
90
+ const tag = typeof d['tagName'] === 'string' ? d['tagName'] : undefined;
91
+ const owner = tag ?? String(d['name']);
92
+ add(d['description'], owner, tag);
93
+ add(d['deprecated'], `${owner} deprecated`, tag);
94
+ for (const [key] of DESCRIBED)
95
+ for (const item of list(d[key])) {
96
+ add(item['description'], `${owner} ${String(item['name'])}`, tag);
97
+ add(item['deprecated'], `${owner} ${String(item['name'])} deprecated`, tag);
98
+ }
99
+ }
100
+ const components = metadata?.components;
101
+ for (const [id, component] of Object.entries(components ?? {})) {
102
+ const tag = id.replace(/^component:/, '');
103
+ const visit = (value, path) => {
104
+ if (Array.isArray(value))
105
+ value.forEach((v, i) => visit(v, `${path}/${i}`));
106
+ else if (value && typeof value === 'object') {
107
+ const fact = value;
108
+ if (fact['provenance'] === 'authored' && typeof fact['value'] === 'string') {
109
+ if (fact['value'].includes('`'))
110
+ out.push({
111
+ text: fact['value'],
112
+ at: `${tag} ${path.slice(1)}`,
113
+ subject: tag,
114
+ ...(fact['source'] ? { source: fact['source'] } : {}),
115
+ });
116
+ }
117
+ else
118
+ for (const [key, v] of Object.entries(fact))
119
+ visit(v, `${path}/${key}`);
120
+ }
121
+ };
122
+ visit(component, '');
123
+ }
124
+ for (const example of examples)
125
+ out.push(...(example.texts ?? []));
126
+ return out;
127
+ }
128
+ const GLOBAL_ATTRIBUTE = /^(aria-[a-z]+|data-[\w-]+|role|id|class|style|slot|part|exportparts|title|lang|dir|hidden|inert|tabindex|autofocus|popover)$/;
129
+ /** Every code span in `texts` that names an Oddkin contract must resolve in `index`. */
130
+ export function checkReferences(texts, index) {
131
+ const out = [];
132
+ for (const { text, subject, at, source } of texts) {
133
+ const self = subject ? index.elements.get(subject) : undefined;
134
+ const report = (span, problem) => out.push({
135
+ code: UNKNOWN_REFERENCE,
136
+ severity: 'warning',
137
+ message: `${at}: \`${span}\` ${problem}.`,
138
+ ...(source ? { source } : {}),
139
+ suggestion: 'Cite only names the published contracts declare, or drop the code span.',
140
+ });
141
+ const anyElement = (has) => [...index.elements.values()].some(has);
142
+ const checkOn = (element, tag, span, rest) => {
143
+ const state = /^:state\(([\w-]+)\)$/.exec(rest)?.[1];
144
+ if (state !== undefined && !element.cssStates.has(state))
145
+ report(span, `names a custom state ${tag} does not declare`);
146
+ const part = /^::part\(([\w-]+)\)$/.exec(rest)?.[1];
147
+ if (part !== undefined && !element.parts.has(part))
148
+ report(span, `names a part ${tag} does not declare`);
149
+ for (const [, name = '', value] of rest.matchAll(/\s([a-z][\w-]*)(?:="([^"]*)")?/g))
150
+ checkAttribute(element, tag, span, name, value);
151
+ };
152
+ const checkAttribute = (element, tag, span, name, value) => {
153
+ if (element.attributes.has(name)) {
154
+ const allowed = element.attributes.get(name);
155
+ if (value !== undefined && allowed && !allowed.includes(value))
156
+ report(span, `gives ${tag} [${name}] a value outside ${allowed.join(', ')}`);
157
+ }
158
+ else if (name === 'slot') {
159
+ // Placement on a child, resolved against the element that hosts it.
160
+ if (value !== undefined && !element.slots.has(value))
161
+ report(span, `names a slot ${tag} does not declare`);
162
+ }
163
+ else if (!GLOBAL_ATTRIBUTE.test(name))
164
+ report(span, `names an attribute ${tag} does not declare`);
165
+ };
166
+ for (const match of text.matchAll(/`([^`]+)`/g)) {
167
+ const span = (match[1] ?? '').trim();
168
+ const after = text.slice((match.index ?? 0) + (match[0] ?? '').length);
169
+ // Contextual: "`side-nav` layout recipe", "`odd-model-change` event". Native events have no
170
+ // hyphen (`submit`, `input`), Oddkin events always do.
171
+ if (/^\s+(layout\s+)?recipe\b/.test(after) && /^[a-z]+(-[a-z0-9]+)*$/.test(span)) {
172
+ if (!index.recipes.has(span))
173
+ report(span, 'is not a known layout recipe');
174
+ continue;
175
+ }
176
+ if (/^\s+events?\b/.test(after) && /^[a-z]+(-[a-z0-9]+)+$/.test(span)) {
177
+ if (!(self?.events.has(span) ?? anyElement((e) => e.events.has(span))))
178
+ report(span, subject ? `is not an event of ${subject}` : 'is not a known event');
179
+ continue;
180
+ }
181
+ const scope = /^(@[a-z0-9-]+)\/[a-z0-9-]+/.exec(span)?.[1];
182
+ if (/^contract:[a-z][a-z0-9-]*\/[a-z0-9-]+$/.test(span)) {
183
+ if (!index.contracts.has(span))
184
+ report(span, 'is not a published contract');
185
+ continue;
186
+ }
187
+ if (scope && index.scopes.has(scope)) {
188
+ if (!/\s/.test(span) && !index.imports(span))
189
+ report(span, 'is not a public entry point');
190
+ continue;
191
+ }
192
+ if (/^--[a-z0-9-]+$/.test(span)) {
193
+ if (!index.variables.has(span) && !anyElement((e) => e.cssProperties.has(span)))
194
+ report(span, 'is neither a token variable nor a declared CSS property');
195
+ continue;
196
+ }
197
+ const tagged = /^<?([a-z][a-z0-9]*-[a-z0-9-]*)(.*?)>?$/s.exec(span);
198
+ const tag = tagged?.[1];
199
+ if (tag && index.prefixes.has(tag.slice(0, tag.indexOf('-') + 1))) {
200
+ const element = index.elements.get(tag);
201
+ if (element)
202
+ checkOn(element, tag, span, tagged[2] ?? '');
203
+ else if (!(tagged[2] ?? '') &&
204
+ !(self?.events.has(tag) || anyElement((e) => e.events.has(tag))))
205
+ report(span, 'is not a known element or event');
206
+ else if (!element && (tagged[2] ?? ''))
207
+ report(span, 'is not a known element');
208
+ continue;
209
+ }
210
+ if (!self || !subject) {
211
+ if (/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/.test(span) && isTokenPath(span, index))
212
+ if (!index.tokens.has(span))
213
+ report(span, 'is not a token');
214
+ continue;
215
+ }
216
+ // A class of a published stylesheet (`.odd-box`), not a member.
217
+ if (/^\.[a-z][\w-]*$/.test(span) && index.classes.has(span.slice(1)))
218
+ continue;
219
+ const member = /^\.([A-Za-z_$][\w$]*)/.exec(span)?.[1];
220
+ if (member !== undefined) {
221
+ if (!self.members.has(member))
222
+ report(span, `is not a property or method of ${subject}`);
223
+ continue;
224
+ }
225
+ const method = /^([A-Za-z_$][\w$]*)\([^()]*\)$/.exec(span)?.[1];
226
+ if (method !== undefined) {
227
+ if (!self.methods.has(method))
228
+ report(span, `is not a method of ${subject}`);
229
+ continue;
230
+ }
231
+ const attribute = /^([a-z][a-z0-9-]*)="([^"]*)"$/.exec(span);
232
+ if (attribute) {
233
+ checkAttribute(self, subject, span, attribute[1] ?? '', attribute[2]);
234
+ continue;
235
+ }
236
+ const state = /^:state\(([\w-]+)\)$/.test(span) || /^::part\(([\w-]+)\)$/.test(span);
237
+ if (state) {
238
+ checkOn(self, subject, span, span);
239
+ continue;
240
+ }
241
+ if (/^[a-z][a-z0-9-]*(\.[a-z0-9-]+)+$/.test(span) &&
242
+ !self.members.has(span.split('.')[0] ?? '') &&
243
+ isTokenPath(span, index) &&
244
+ !index.tokens.has(span))
245
+ report(span, 'is not a token');
246
+ }
247
+ }
248
+ return out;
249
+ }
250
+ /** A dotted span whose first segment starts some token id (`elevation.md`, not `detail.action`). */
251
+ const isTokenPath = (span, index) => {
252
+ const group = `${span.split('.')[0]}.`;
253
+ return [...index.tokens].some((token) => token.startsWith(group));
254
+ };
255
+ //# sourceMappingURL=references.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"references.js","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Style mappings: which public option or state sets which CSS property of which part to which
3
+ * token, read from a component's CSS text. A mapping is the declaration that wins the cascade
4
+ * (`!important`, layer, specificity, order) for a part, a stated condition, and a property. A
5
+ * part's property is left unmapped when any rule that may set it states a condition outside the
6
+ * grammar below: unknown, never guessed. Contract: metadata-and-analyzer.md §3 ("Style mappings").
7
+ */
8
+ /** CSS text with each token reference written as `token(<name>)`, other substitutions as `unknown()`. */
9
+ export type TokenCss = string;
10
+ export interface StyleMapping {
11
+ /** `default`, `appearance="primary"`, `appearance="primary" (enabled, hover)`, `(disabled)`, … */
12
+ readonly when: string;
13
+ /** The part the declaration styles; absent for the host. */
14
+ readonly part?: string;
15
+ readonly cssProperty: string;
16
+ readonly token: string;
17
+ readonly provenance: 'extracted';
18
+ }
19
+ /** Which of a component's parts each tag and class selects in its template. */
20
+ export interface PartSelectors {
21
+ readonly tags: ReadonlyMap<string, readonly string[]>;
22
+ readonly classes: ReadonlyMap<string, readonly string[]>;
23
+ /** Every part the template renders. */
24
+ readonly all: readonly string[];
25
+ /** Parts on elements whose class list is computed: any class selector may match them. */
26
+ readonly computedClass: readonly string[];
27
+ }
28
+ /** What one selector styles; the part `undefined` is the host. */
29
+ export interface Selection {
30
+ /** Parts styled when `when` holds. */
31
+ readonly matches: readonly (string | undefined)[];
32
+ readonly when: string;
33
+ /** `b * 100 + c`; the grammar has no id selectors. */
34
+ readonly specificity: number;
35
+ /** Parts the selector may style under a condition this grammar does not read. */
36
+ readonly unread: readonly (string | undefined)[];
37
+ }
38
+ /**
39
+ * What a selector styles and when: `:host` with at most one attribute, or a part's tag or class
40
+ * (optionally after `:host…` and a space) followed by the states above. Any other combinator,
41
+ * pseudo-class, or attribute leaves the condition unread. Pseudo-elements style no part.
42
+ */
43
+ export declare function selectionOf(selector: string, parts: PartSelectors): Selection;
44
+ /** The tokens read by each declaration that wins for a part, a condition, and a property. */
45
+ export declare function styleMappingsOf(css: TokenCss, parts: PartSelectors): StyleMapping[];
46
+ //# sourceMappingURL=style-mappings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style-mappings.d.ts","sourceRoot":"","sources":["../src/style-mappings.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yGAAyG;AACzG,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC;AAE9B,MAAM,WAAW,YAAY;IAC3B,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;CAClC;AAED,+EAA+E;AAC/E,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IACtD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IACzD,uCAAuC;IACvC,QAAQ,CAAC,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,yFAAyF;IACzF,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;CAC3C;AAED,kEAAkE;AAClE,MAAM,WAAW,SAAS;IACxB,sCAAsC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;IAClD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,iFAAiF;IACjF,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC;CAClD;AAmED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,SAAS,CAuC7E;AAkED,6FAA6F;AAC7F,wBAAgB,eAAe,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,GAAG,YAAY,EAAE,CA6DnF"}
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Style mappings: which public option or state sets which CSS property of which part to which
3
+ * token, read from a component's CSS text. A mapping is the declaration that wins the cascade
4
+ * (`!important`, layer, specificity, order) for a part, a stated condition, and a property. A
5
+ * part's property is left unmapped when any rule that may set it states a condition outside the
6
+ * grammar below: unknown, never guessed. Contract: metadata-and-analyzer.md §3 ("Style mappings").
7
+ */
8
+ // States a compound may add after its element; each is one pseudo-class or attribute selector.
9
+ const STATES = [
10
+ [":not([aria-disabled='true'])", 'enabled'],
11
+ [':enabled', 'enabled'],
12
+ [':disabled', 'disabled'],
13
+ [':hover', 'hover'],
14
+ [':active', 'active'],
15
+ [':focus-visible', 'focus-visible'],
16
+ ];
17
+ const ARIA = /^\[aria-([\w-]+)=(?:'([^']*)'|"([^"]*)")\]/;
18
+ const HOST = /^:host(?:\(\[([\w-]+)(?:=(?:'([^']*)'|"([^"]*)"))?\]\))?$/;
19
+ const ELEMENT = /^(?:[a-zA-Z][\w-]*|\.[\w-]+|\*)/;
20
+ const CONDITION = /^@(?:media|supports|container)\b/;
21
+ // At-rules whose contents are not an element's steady-state styles.
22
+ const IGNORED = /^@(?:keyframes|font-face|property|counter-style|font-feature-values|page|starting-style)\b/;
23
+ const NONE = { matches: [], when: 'default', specificity: 0, unread: [] };
24
+ /** Split at top-level separator characters (outside parentheses, brackets, and strings). */
25
+ function splitTop(text, separators) {
26
+ const pieces = [];
27
+ let current = '';
28
+ let depth = 0;
29
+ let quote = '';
30
+ for (const c of text) {
31
+ if (quote) {
32
+ if (c === quote)
33
+ quote = '';
34
+ }
35
+ else if (c === '"' || c === "'")
36
+ quote = c;
37
+ else if (c === '(' || c === '[')
38
+ depth++;
39
+ else if (c === ')' || c === ']')
40
+ depth--;
41
+ else if (!depth && separators.includes(c)) {
42
+ pieces.push(current);
43
+ current = '';
44
+ continue;
45
+ }
46
+ current += c;
47
+ }
48
+ pieces.push(current);
49
+ return pieces;
50
+ }
51
+ /** `appearance="primary"` for `:host([appearance='primary'])`, `full-width` for `:host([full-width])`. */
52
+ function hostWhen(host) {
53
+ const value = host[2] ?? host[3];
54
+ return !host[1] ? '' : value === undefined ? host[1] : `${host[1]}="${value}"`;
55
+ }
56
+ /** The states after a compound's element; `undefined` when one is outside the grammar. */
57
+ function statesOf(text) {
58
+ const states = [];
59
+ while (text) {
60
+ const known = STATES.find(([key]) => text.startsWith(key));
61
+ const aria = ARIA.exec(text);
62
+ if (known) {
63
+ states.push(known[1]);
64
+ text = text.slice(known[0].length);
65
+ }
66
+ else if (aria) {
67
+ const value = aria[2] ?? aria[3];
68
+ states.push(value === 'true' ? aria[1] : `${aria[1]}="${value}"`);
69
+ text = text.slice(aria[0].length);
70
+ }
71
+ else
72
+ return undefined;
73
+ }
74
+ return states;
75
+ }
76
+ /**
77
+ * What a selector styles and when: `:host` with at most one attribute, or a part's tag or class
78
+ * (optionally after `:host…` and a space) followed by the states above. Any other combinator,
79
+ * pseudo-class, or attribute leaves the condition unread. Pseudo-elements style no part.
80
+ */
81
+ export function selectionOf(selector, parts) {
82
+ const compounds = splitTop(selector.trim(), ' \t\r\n>+~').filter(Boolean);
83
+ const last = compounds.at(-1);
84
+ if (!last || last.includes('::'))
85
+ return NONE;
86
+ if (compounds.length === 1 && last.startsWith(':host')) {
87
+ const host = HOST.exec(last);
88
+ return host
89
+ ? {
90
+ ...NONE,
91
+ matches: [undefined],
92
+ when: hostWhen(host) || 'default',
93
+ specificity: host[1] ? 200 : 100,
94
+ }
95
+ : { ...NONE, unread: [undefined] };
96
+ }
97
+ const element = ELEMENT.exec(last)?.[0];
98
+ const isClass = !!element?.startsWith('.');
99
+ const universal = !element || element === '*';
100
+ const named = universal
101
+ ? []
102
+ : ((isClass ? parts.classes.get(element.slice(1)) : parts.tags.get(element.toLowerCase())) ??
103
+ []);
104
+ const maybe = universal ? parts.all : isClass ? parts.computedClass : [];
105
+ const host = compounds.length === 2 && splitTop(selector, '>+~').length === 1
106
+ ? HOST.exec(compounds[0])
107
+ : null;
108
+ const states = universal ? undefined : statesOf(last.slice(element.length));
109
+ if (!states || (compounds.length > 1 && !host))
110
+ return { ...NONE, unread: [...named, ...maybe] };
111
+ const stated = [...new Set(states)].sort();
112
+ const when = [host ? hostWhen(host) : '', stated.length ? `(${stated.join(', ')})` : '']
113
+ .filter(Boolean)
114
+ .join(' ');
115
+ return {
116
+ matches: named,
117
+ when: when || 'default',
118
+ specificity: (host ? (host[1] ? 200 : 100) : 0) + (isClass ? 100 : 1) + states.length * 100,
119
+ unread: maybe,
120
+ };
121
+ }
122
+ /** Innermost blocks with their at-rule context; `undefined` when style rules nest (not read). */
123
+ function rulesOf(text) {
124
+ const rules = [];
125
+ const open = [];
126
+ let boundary = 0;
127
+ let quote = '';
128
+ for (let i = 0; i < text.length; i++) {
129
+ const c = text[i];
130
+ if (quote) {
131
+ if (c === '\\')
132
+ i++;
133
+ else if (c === quote)
134
+ quote = '';
135
+ }
136
+ else if (c === '"' || c === "'")
137
+ quote = c;
138
+ else if (c === '{') {
139
+ const parent = open.at(-1);
140
+ if (parent && !parent.prelude.startsWith('@'))
141
+ return undefined;
142
+ if (parent)
143
+ parent.nested = true;
144
+ open.push({ prelude: text.slice(boundary, i).trim(), start: i + 1, nested: false });
145
+ boundary = i + 1;
146
+ }
147
+ else if (c === '}') {
148
+ const block = open.pop();
149
+ if (block && !block.nested)
150
+ rules.push({
151
+ prelude: block.prelude,
152
+ body: text.slice(block.start, i),
153
+ context: open.map((b) => b.prelude),
154
+ });
155
+ boundary = i + 1;
156
+ }
157
+ else if (c === ';')
158
+ boundary = i + 1;
159
+ }
160
+ return rules;
161
+ }
162
+ /** Layer names in order of first appearance, from `@layer` statements and blocks. */
163
+ function layerOrder(text) {
164
+ const names = [];
165
+ for (const [, list] of text.matchAll(/@layer\s+([^{;]+)/g))
166
+ for (const name of list.split(',').map((n) => n.trim()))
167
+ if (name && !names.includes(name))
168
+ names.push(name);
169
+ return names;
170
+ }
171
+ /** A rule's media, support, and container conditions and its layer; `undefined` when unread. */
172
+ function contextOf(context) {
173
+ const conditions = [];
174
+ let layer;
175
+ for (const prelude of context) {
176
+ if (IGNORED.test(prelude))
177
+ return 'ignored';
178
+ if (CONDITION.test(prelude))
179
+ conditions.push(prelude.replace(/\s+/g, ' '));
180
+ else if (/^@layer\s+[\w.-]+$/.test(prelude) && layer === undefined)
181
+ layer = prelude.slice('@layer'.length).trim();
182
+ else
183
+ return undefined;
184
+ }
185
+ return { conditions, ...(layer === undefined ? {} : { layer }) };
186
+ }
187
+ /** The tokens read by each declaration that wins for a part, a condition, and a property. */
188
+ export function styleMappingsOf(css, parts) {
189
+ const text = css.replace(/\/\*[\s\S]*?\*\//g, '');
190
+ const rules = rulesOf(text);
191
+ if (!rules)
192
+ return [];
193
+ const layers = layerOrder(text);
194
+ // Normal declarations: unlayered over later layers over earlier ones; `!important` reverses.
195
+ const precedence = (important, layer, specificity) => {
196
+ const index = layer === undefined ? layers.length : layers.indexOf(layer);
197
+ return (important ? 2e9 + (layers.length - index) * 1e6 : index * 1e6) + specificity;
198
+ };
199
+ const winners = new Map();
200
+ const unread = new Set();
201
+ for (const rule of rules) {
202
+ // A computed selector or condition could style anything.
203
+ if ([rule.prelude, ...rule.context].some((p) => p.includes('unknown()')))
204
+ return [];
205
+ const context = contextOf(rule.context);
206
+ if (context === 'ignored' || rule.prelude.startsWith('@'))
207
+ continue;
208
+ const selections = splitTop(rule.prelude, ',').map((s) => selectionOf(s, parts));
209
+ for (const declaration of splitTop(rule.body, ';')) {
210
+ const colon = declaration.indexOf(':');
211
+ const cssProperty = declaration.slice(0, Math.max(colon, 0)).trim();
212
+ if (!/^-{0,2}[a-z][a-z-]*$/.test(cssProperty))
213
+ continue;
214
+ const value = declaration.slice(colon + 1);
215
+ const important = /!\s*important\s*$/i.test(value);
216
+ const tokens = [...new Set(Array.from(value.matchAll(/token\(([\w.-]+)\)/g), (m) => m[1]))];
217
+ for (const selection of selections) {
218
+ const notRead = context ? selection.unread : [...selection.matches, ...selection.unread];
219
+ for (const part of notRead)
220
+ unread.add(`${part ?? ''}|${cssProperty}`);
221
+ if (!context)
222
+ continue;
223
+ const when = [selection.when === 'default' ? '' : selection.when, ...context.conditions]
224
+ .filter(Boolean)
225
+ .join(' ') || 'default';
226
+ const rank = precedence(important, context.layer, selection.specificity);
227
+ for (const part of selection.matches) {
228
+ const key = `${part ?? ''}|${when}|${cssProperty}`;
229
+ const current = winners.get(key);
230
+ if (!current || rank >= current.rank)
231
+ winners.set(key, { ...(part ? { part } : {}), when, cssProperty, rank, tokens });
232
+ }
233
+ }
234
+ }
235
+ }
236
+ return [...winners.values()]
237
+ .filter((w) => !unread.has(`${w.part ?? ''}|${w.cssProperty}`))
238
+ .flatMap(({ part, when, cssProperty, tokens }) => tokens.map((token) => ({
239
+ when,
240
+ ...(part ? { part } : {}),
241
+ cssProperty,
242
+ token,
243
+ provenance: 'extracted',
244
+ })));
245
+ }
246
+ //# sourceMappingURL=style-mappings.js.map