@santi020k/lumen 1.4.0 → 1.5.0
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/README.md +17 -2
- package/dist/cli.js +10 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/integration-diagnostics.d.ts.map +1 -1
- package/dist/integration-diagnostics.js +57 -1
- package/dist/native-audit.d.ts +26 -0
- package/dist/native-audit.d.ts.map +1 -0
- package/dist/native-audit.js +198 -0
- package/package.json +3 -1
- package/release-manifest.json +88 -0
package/README.md
CHANGED
|
@@ -43,6 +43,7 @@ lumen add saas-admin --target react
|
|
|
43
43
|
lumen add commerce-dashboard --target elements
|
|
44
44
|
lumen audit-tokens ./src
|
|
45
45
|
lumen doctor --json
|
|
46
|
+
lumen doctor-native --json
|
|
46
47
|
lumen init --framework astro --tailwind
|
|
47
48
|
```
|
|
48
49
|
|
|
@@ -57,8 +58,22 @@ Complete product recipes are also bundled for `analytics-dashboard`, `saas-admin
|
|
|
57
58
|
Run `lumen doctor` to check adapter/style agreement, Tailwind layer order, Astro runtime mounts,
|
|
58
59
|
and fragile internal selector dependencies. In a workspace, diagnostics are scoped to the nearest
|
|
59
60
|
package boundary, generated build trees are ignored, and application-controlled Astro `Toggle`
|
|
60
|
-
instances do not require the shared runtime.
|
|
61
|
-
|
|
61
|
+
instances do not require the shared runtime. It also suggests matching Lumen primitives for likely
|
|
62
|
+
hand-built dropdown, theme, dialog-focus, and keyboard-menu behavior. These suggestions stay
|
|
63
|
+
advisory because product-specific composition can be intentional. Use `--json` for CI and rollout
|
|
64
|
+
automation. `lumen init --framework <astro|react|elements> [--tailwind]` prints the canonical
|
|
65
|
+
non-destructive setup.
|
|
66
|
+
|
|
67
|
+
Run `lumen doctor-native` in an Apple or Android consumer to report the resolved Swift package
|
|
68
|
+
tag/revision or Compose artifact version, compare it with Lumen's bundled cross-platform release
|
|
69
|
+
manifest, and audit public theme placement. Findings are suggestions or warnings: the command does
|
|
70
|
+
not classify application-owned navigation or controls as migration failures. Pass `--manifest`
|
|
71
|
+
to audit against a prerelease manifest and `--json` for CI.
|
|
72
|
+
|
|
73
|
+
The same machine-readable metadata is published as
|
|
74
|
+
`@santi020k/lumen/release-manifest.json`. It records every npm package version and peer range, the
|
|
75
|
+
Swift tag, Maven coordinates, required stylesheet/runtime setup, deprecations, removals, and
|
|
76
|
+
codemod availability.
|
|
62
77
|
|
|
63
78
|
Run `lumen audit-tokens [path]` before incremental adoption when an existing stylesheet may already
|
|
64
79
|
declare names such as `--surface`, `--ink`, or `--line`. The audit reports complete CSS colors that
|
package/dist/cli.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readdir, readFile, stat } from 'node:fs/promises';
|
|
|
2
2
|
import { resolve } from 'node:path';
|
|
3
3
|
import { consumerRolloutSucceeded, formatConsumerRollout, resolveConsumerRolloutTargets, runConsumerRollout } from './consumer-rollout.js';
|
|
4
4
|
import { createLumenSetup, formatLumenDiagnostics, inspectLumenIntegration } from './integration-diagnostics.js';
|
|
5
|
+
import { formatNativeAdoptionAudit, inspectNativeAdoption } from './native-audit.js';
|
|
5
6
|
import { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, lumenRegistry } from './registry.js';
|
|
6
7
|
import { auditLumenTokenCss } from './token-audit.js';
|
|
7
8
|
const args = process.argv.slice(2);
|
|
@@ -24,6 +25,8 @@ const allowDirty = args.includes('--allow-dirty');
|
|
|
24
25
|
const noVerify = args.includes('--no-verify');
|
|
25
26
|
const reportIndex = args.indexOf('--report');
|
|
26
27
|
const reportPath = reportIndex >= 0 ? args[reportIndex + 1] : undefined;
|
|
28
|
+
const manifestIndex = args.indexOf('--manifest');
|
|
29
|
+
const manifestPath = manifestIndex >= 0 ? args[manifestIndex + 1] : undefined;
|
|
27
30
|
const frameworkIndex = args.indexOf('--framework');
|
|
28
31
|
const frameworkValue = frameworkIndex >= 0 ? args[frameworkIndex + 1] : undefined;
|
|
29
32
|
const json = args.includes('--json');
|
|
@@ -160,6 +163,7 @@ const help = [
|
|
|
160
163
|
' lumen install Print install commands',
|
|
161
164
|
' lumen audit-tokens Report incompatible semantic color custom properties',
|
|
162
165
|
' lumen doctor Inspect styles, adapters, runtime mounts, and selector usage',
|
|
166
|
+
' lumen doctor-native Inspect native versions, package pins, and theme placement',
|
|
163
167
|
' lumen init Print canonical framework setup without changing files',
|
|
164
168
|
' lumen rollout [version] [repositories...] Inventory or upgrade pnpm consumers',
|
|
165
169
|
'',
|
|
@@ -175,6 +179,7 @@ const help = [
|
|
|
175
179
|
' --framework <name> Select astro, react, or elements for lumen init',
|
|
176
180
|
' --tailwind Include the verified Tailwind cascade setup in lumen init',
|
|
177
181
|
' --json Print lumen doctor output as JSON',
|
|
182
|
+
' --manifest <path> Use a specific cross-platform release manifest',
|
|
178
183
|
' --apply Apply a rollout (requires a target version)',
|
|
179
184
|
' --allow-dirty Allow rollout after recording an uncommitted baseline',
|
|
180
185
|
' --exclude <path> Exclude a repository (repeatable)',
|
|
@@ -205,6 +210,11 @@ const run = async () => {
|
|
|
205
210
|
process.exitCode = 1;
|
|
206
211
|
break;
|
|
207
212
|
}
|
|
213
|
+
case 'doctor-native': {
|
|
214
|
+
const report = await inspectNativeAdoption(cwd ?? process.cwd(), manifestPath);
|
|
215
|
+
output = json ? JSON.stringify(report, undefined, 2) : formatNativeAdoptionAudit(report);
|
|
216
|
+
break;
|
|
217
|
+
}
|
|
208
218
|
case 'init': {
|
|
209
219
|
output = createLumenSetup(getFramework(frameworkValue), tailwind);
|
|
210
220
|
break;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { type ConsumerInventory, type ConsumerReference, type ConsumerRolloutOptions, type ConsumerRolloutReport, formatConsumerRollout, inspectLumenConsumer, type LumenFramework, runConsumerRollout, updateLumenManifestSource, updateLumenWorkspaceSource } from './consumer-rollout.js';
|
|
2
|
+
export { formatNativeAdoptionAudit, inspectNativeAdoption, type NativeAuditFinding, type NativeAuditPlatform, type NativeAuditReport, type NativeAuditSeverity, type NativeResolvedVersion } from './native-audit.js';
|
|
2
3
|
export { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, type LumenAddOptions, type LumenAddResult, type LumenAddTarget, type LumenMergeConflict, type LumenRegistry, lumenRegistry, type LumenRegistryComponent, type LumenRegistryEntry, type LumenRegistryFile, type LumenRegistryItem, type LumenRegistryLoadOptions } from './registry.js';
|
|
3
4
|
export { alignLumenChartSeries, applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createLumenBarGeometry, createLumenFormFailure, createLumenFormSuccess, createLumenLineGeometry, createLumenPieGeometry, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getLumenChartCategories, getLumenChartDomain, getLumenChartTicks, getLumenChartValueRatio, getLumenFieldErrors, getScheduleConflicts, getVirtualRange, hasLumenPieData, loadDataViewState, loadScheduleEvents, type LumenBarChartLayout, type LumenBarGeometry, type LumenBarGeometryCategory, type LumenBarGeometryMark, type LumenBarGeometryOptions, lumenChart, type LumenChartDatum, type LumenChartDomain, type LumenChartGeometryPoint, type LumenChartOrientation, type LumenChartSeries, type LumenChartTone, lumenChartTones, type LumenCodeToken, lumenCodeTokenClassNames, type LumenCodeTokenKind, lumenColors, type LumenColorScheme, type LumenColorTokenName, lumenColorTokenNames, lumenColorTokens, type LumenComponentName, lumenComponentNames, type LumenContrastScore, lumenCssColorTokens, lumenDarkColors, lumenDarkTheme, type LumenDataRecord, type LumenDataViewServerRequest, type LumenDataViewState, lumenDurations, lumenEasings, lumenElevation, type LumenFieldError, lumenFontFamilies, lumenFontSizes, lumenFontWeights, type LumenFormErrorInput, type LumenFormErrors, type LumenFormFailure, type LumenFormResult, type LumenFormStatus, lumenFormStatuses, type LumenFormSuccess, lumenGlass, type LumenGlassColorTokenName, lumenGlassColorTokenNames, type LumenGlassEffectTokenName, lumenGlassEffectTokenNames, type LumenGlassTokenName, lumenGlassTokenNames, type LumenKeyValueReader, type LumenKeyValueStorage, type LumenKeyValueWriter, lumenLightTheme, type LumenLineGeometry, type LumenLineGeometryOptions, lumenPackages, type LumenPackageTarget, type LumenPieChartVariant, type LumenPieGeometry, type LumenPieGeometryOptions, type LumenPieGeometrySlice, lumenRadii, type LumenScheduleConflict, type LumenScheduleEvent, type LumenScheduleKeyValueReader, type LumenScheduleKeyValueStorage, type LumenScheduleKeyValueWriter, type LumenScheduleResizeEdge, type LumenScheduleResizeOptions, type LumenScheduleResource, type LumenScheduleSlot, type LumenSemanticColor, type LumenSemanticColorTokenName, lumenSemanticColorTokenNames, type LumenSortDirection, lumenSpacing, lumenThemeAttribute, type LumenThemeBuilderExportFormat, type LumenThemeBuilderMode, type LumenThemeBuilderOptions, type LumenThemeBuilderResult, type LumenThemeBuilderScheme, type LumenThemeContrastSuggestion, type LumenThemeTokens, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeLumenFormErrors, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, resolveLumenChartTone, saveDataViewState, saveScheduleEvents, scaleLumenChartValue, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
|
|
4
5
|
export declare const lumen: {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { formatConsumerRollout, inspectLumenConsumer, runConsumerRollout, updateLumenManifestSource, updateLumenWorkspaceSource } from './consumer-rollout.js';
|
|
2
|
+
export { formatNativeAdoptionAudit, inspectNativeAdoption } from './native-audit.js';
|
|
2
3
|
export { addLumenRegistryItem, getLumenRegistryEntries, getLumenRegistryItem, loadLumenRegistry, lumenRegistry } from './registry.js';
|
|
3
4
|
export { alignLumenChartSeries, applyDataViewState, canPlaceScheduleEvent, coerceThemeBuilderExportFormat, coerceThemeBuilderMode, coerceThemeBuilderScheme, composeClassName, createDataViewRequestUrl, createDataViewSearchParams, createDataViewServerRequest, createDataViewState, createDataViewStorageKey, createLumenBarGeometry, createLumenFormFailure, createLumenFormSuccess, createLumenLineGeometry, createLumenPieGeometry, createScheduleSlots, createScheduleStorageKey, createThemeBuilderTokens, createThemePalette, expandRecurringScheduleEvent, exportThemeBuilderCss, exportThemeBuilderValue, exportThemeCss, filterDataRecords, getContrastRatio, getLumenChartCategories, getLumenChartDomain, getLumenChartTicks, getLumenChartValueRatio, getLumenFieldErrors, getScheduleConflicts, getVirtualRange, hasLumenPieData, loadDataViewState, loadScheduleEvents, lumenChart, lumenChartTones, lumenCodeTokenClassNames, lumenColors, lumenColorTokenNames, lumenColorTokens, lumenComponentNames, lumenCssColorTokens, lumenDarkColors, lumenDarkTheme, lumenDurations, lumenEasings, lumenElevation, lumenFontFamilies, lumenFontSizes, lumenFontWeights, lumenFormStatuses, lumenGlass, lumenGlassColorTokenNames, lumenGlassEffectTokenNames, lumenGlassTokenNames, lumenLightTheme, lumenPackages, lumenRadii, lumenSemanticColorTokenNames, lumenSpacing, lumenThemeAttribute, lumenTokenNames, mergeThemeTokens, moveScheduleEvent, normalizeLumenCode, normalizeLumenFormErrors, normalizeThemeBuilderHex, normalizeThemeBuilderHue, paginateDataRecords, parseDataViewState, parseScheduleEvents, parseThemeCss, pinDataViewColumn, renderLumenCodeHtml, resizeScheduleEvent, resizeScheduleEvents, resolveLumenChartTone, saveDataViewState, saveScheduleEvents, scaleLumenChartValue, scheduleEventsOverlap, scoreThemeContrast, serializeDataViewState, serializeScheduleEvents, sortDataRecords, suggestReadableInk, themeBuilderHexToHsl, toggleDataViewSelection, tokenizeLumenCode, tuneThemeContrast, unpinDataViewColumn } from '@santi020k/lumen-core';
|
|
4
5
|
export const lumen = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"integration-diagnostics.d.ts","sourceRoot":"","sources":["../src/integration-diagnostics.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,OAAO,CAAA;AAE1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,uBAAuB,CAAA;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,sBAAsB,EAAE,CAAA;IAClC,UAAU,EAAE,CAAC,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B;
|
|
1
|
+
{"version":3,"file":"integration-diagnostics.d.ts","sourceRoot":"","sources":["../src/integration-diagnostics.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG,OAAO,CAAA;AAE1D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,uBAAuB,CAAA;CAClC;AAED,MAAM,WAAW,qBAAqB;IACpC,kBAAkB,EAAE,MAAM,CAAA;IAC1B,QAAQ,EAAE,sBAAsB,EAAE,CAAA;IAClC,UAAU,EAAE,CAAC,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,OAAO,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,iBAAiB,EAAE,MAAM,EAAE,CAAA;CAC5B;AA+dD,eAAO,MAAM,uBAAuB,GAAU,YAAY,MAAM,KAAG,OAAO,CAAC,qBAAqB,CA8C/F,CAAA;AAED,eAAO,MAAM,sBAAsB,GAAI,QAAQ,qBAAqB,KAAG,MAWtE,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,WAAW,OAAO,GAAG,UAAU,GAAG,OAAO,EAAE,kBAAgB,KAAG,MAsC9F,CAAA"}
|
|
@@ -110,6 +110,62 @@ const collectCompatibilityFindings = (root, sources) => sources.flatMap(item =>
|
|
|
110
110
|
}
|
|
111
111
|
return findings;
|
|
112
112
|
});
|
|
113
|
+
const hasImportedPrimitive = (sources, names) => [
|
|
114
|
+
'@santi020k/lumen-astro',
|
|
115
|
+
'@santi020k/lumen-react'
|
|
116
|
+
].some(packageName => sources.some(item => (importedNames(item.source, packageName).some(name => names.includes(name)))));
|
|
117
|
+
const duplicatedBehaviorRules = [
|
|
118
|
+
{
|
|
119
|
+
detects: (_source, sourceLower) => sourceLower.includes('<details') &&
|
|
120
|
+
(sourceLower.includes('dropdown') || sourceLower.includes('menu')),
|
|
121
|
+
imports: ['Collapsible', 'DropdownMenu'],
|
|
122
|
+
message: 'A details-based dropdown or menu may duplicate Lumen disclosure or menu behavior.',
|
|
123
|
+
remediation: 'Review DropdownMenu or Collapsible before maintaining a separate controller; keep the custom composition when its semantics differ.',
|
|
124
|
+
rule: 'hand-built-dropdown'
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
detects: (source, sourceLower) => source.includes('localStorage') &&
|
|
128
|
+
sourceLower.includes('theme') &&
|
|
129
|
+
(source.includes('classList') || sourceLower.includes('data-theme') || source.includes('dataset')),
|
|
130
|
+
imports: ['ThemeToggle'],
|
|
131
|
+
message: 'Custom theme persistence may duplicate ThemeToggle behavior.',
|
|
132
|
+
remediation: 'Review ThemeToggle before maintaining separate storage and document-theme synchronization.',
|
|
133
|
+
rule: 'hand-built-theme-persistence'
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
detects: (source, sourceLower) => [
|
|
137
|
+
'role="dialog"',
|
|
138
|
+
'role=\'dialog\'',
|
|
139
|
+
'aria-modal'
|
|
140
|
+
].some(value => sourceLower.includes(value)) &&
|
|
141
|
+
source.includes('Tab') &&
|
|
142
|
+
source.includes('focus') &&
|
|
143
|
+
(source.includes('keydown') || source.includes('onKeyDown')),
|
|
144
|
+
imports: ['Dialog'],
|
|
145
|
+
message: 'Custom dialog keyboard and focus management may duplicate Lumen Dialog behavior.',
|
|
146
|
+
remediation: 'Review Dialog before maintaining a separate focus trap; keep product-specific dialog content application-owned.',
|
|
147
|
+
rule: 'hand-built-dialog-focus'
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
detects: (source, sourceLower) => [
|
|
151
|
+
'role="menu"',
|
|
152
|
+
'role=\'menu\''
|
|
153
|
+
].some(value => sourceLower.includes(value)) &&
|
|
154
|
+
['ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowUp'].some(key => source.includes(key)),
|
|
155
|
+
imports: ['DropdownMenu', 'Menubar', 'NavigationMenu'],
|
|
156
|
+
message: 'A raw menu with arrow-key handling may duplicate Lumen menu behavior.',
|
|
157
|
+
remediation: 'Review DropdownMenu, Menubar, or NavigationMenu before maintaining a separate keyboard controller.',
|
|
158
|
+
rule: 'hand-built-menu-keyboard'
|
|
159
|
+
}
|
|
160
|
+
];
|
|
161
|
+
const collectDuplicatedBehaviorFindings = (root, sources) => sources.flatMap(item => {
|
|
162
|
+
const file = relative(root, item.file);
|
|
163
|
+
const source = item.source;
|
|
164
|
+
const sourceLower = source.toLowerCase();
|
|
165
|
+
return duplicatedBehaviorRules.flatMap(rule => (rule.detects(source, sourceLower) && !hasImportedPrimitive(sources, rule.imports) ?
|
|
166
|
+
[finding(file, rule.rule, rule.message, rule.remediation, 'advisory')] :
|
|
167
|
+
[]));
|
|
168
|
+
});
|
|
113
169
|
const getCatalogFingerprint = (sources) => {
|
|
114
170
|
const names = [...new Set(sources.flatMap(item => [
|
|
115
171
|
...importedNames(item.source, '@santi020k/lumen-astro'),
|
|
@@ -255,7 +311,7 @@ export const inspectLumenIntegration = async (repository) => {
|
|
|
255
311
|
const boundaryFrameworks = getFrameworks(boundary.sources);
|
|
256
312
|
const runtime = collectRuntimeFindings(root, boundary);
|
|
257
313
|
runtime.runtimeComponents.forEach(component => runtimeComponents.add(component));
|
|
258
|
-
findings.push(...runtime.findings, ...collectFrameworkStyleFindings(root, boundary, boundaryFrameworks), ...collectAdapterMismatchFindings(root, boundary, boundaryFrameworks));
|
|
314
|
+
findings.push(...collectDuplicatedBehaviorFindings(root, boundary.sources), ...runtime.findings, ...collectFrameworkStyleFindings(root, boundary, boundaryFrameworks), ...collectAdapterMismatchFindings(root, boundary, boundaryFrameworks));
|
|
259
315
|
}
|
|
260
316
|
const deduplicatedFindings = uniqueFindings(findings);
|
|
261
317
|
return {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type NativeAuditPlatform = 'compose' | 'swift';
|
|
2
|
+
export type NativeAuditSeverity = 'suggestion' | 'warning';
|
|
3
|
+
export interface NativeAuditFinding {
|
|
4
|
+
file: string;
|
|
5
|
+
message: string;
|
|
6
|
+
remediation: string;
|
|
7
|
+
rule: string;
|
|
8
|
+
severity: NativeAuditSeverity;
|
|
9
|
+
}
|
|
10
|
+
export interface NativeResolvedVersion {
|
|
11
|
+
platform: NativeAuditPlatform;
|
|
12
|
+
reference: string;
|
|
13
|
+
revision?: string;
|
|
14
|
+
version?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface NativeAuditReport {
|
|
17
|
+
findings: NativeAuditFinding[];
|
|
18
|
+
generatedAt: string;
|
|
19
|
+
platforms: NativeAuditPlatform[];
|
|
20
|
+
releaseVersion: string;
|
|
21
|
+
repository: string;
|
|
22
|
+
resolved: NativeResolvedVersion[];
|
|
23
|
+
}
|
|
24
|
+
export declare const inspectNativeAdoption: (repository: string, manifestPath?: string) => Promise<NativeAuditReport>;
|
|
25
|
+
export declare const formatNativeAdoptionAudit: (report: NativeAuditReport) => string;
|
|
26
|
+
//# sourceMappingURL=native-audit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"native-audit.d.ts","sourceRoot":"","sources":["../src/native-audit.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,mBAAmB,GAAG,SAAS,GAAG,OAAO,CAAA;AACrD,MAAM,MAAM,mBAAmB,GAAG,YAAY,GAAG,SAAS,CAAA;AAE1D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,mBAAmB,CAAA;CAC9B;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,mBAAmB,CAAA;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,kBAAkB,EAAE,CAAA;IAC9B,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,mBAAmB,EAAE,CAAA;IAChC,cAAc,EAAE,MAAM,CAAA;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,qBAAqB,EAAE,CAAA;CAClC;AAiOD,eAAO,MAAM,qBAAqB,GAChC,YAAY,MAAM,EAClB,qBAAkF,KACjF,OAAO,CAAC,iBAAiB,CA+B3B,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAI,QAAQ,iBAAiB,KAAG,MAgBrE,CAAA"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { extname, join, relative, resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const ignoredDirectories = new Set([
|
|
5
|
+
'.build',
|
|
6
|
+
'.git',
|
|
7
|
+
'.gradle',
|
|
8
|
+
'.idea',
|
|
9
|
+
['.', 'swift', 'pm'].join(''),
|
|
10
|
+
'build',
|
|
11
|
+
'DerivedData',
|
|
12
|
+
'node_modules'
|
|
13
|
+
]);
|
|
14
|
+
const nativeExtensions = new Set(['.gradle', '.json', '.kts', '.swift', '.toml']);
|
|
15
|
+
const discoverNativeSources = async (root) => {
|
|
16
|
+
const files = [];
|
|
17
|
+
const visit = async (directory) => {
|
|
18
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) {
|
|
19
|
+
if (ignoredDirectories.has(entry.name))
|
|
20
|
+
continue;
|
|
21
|
+
const path = join(directory, entry.name);
|
|
22
|
+
if (entry.isDirectory()) {
|
|
23
|
+
await visit(path);
|
|
24
|
+
}
|
|
25
|
+
else if (nativeExtensions.has(extname(entry.name)) || entry.name === 'Package.resolved') {
|
|
26
|
+
files.push(path);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
await visit(root);
|
|
31
|
+
return Promise.all(files.map(async (file) => ({ file, source: await readFile(file, 'utf8') })));
|
|
32
|
+
};
|
|
33
|
+
const parseSwiftResolution = (entry) => {
|
|
34
|
+
if (!entry.file.endsWith('Package.resolved'))
|
|
35
|
+
return [];
|
|
36
|
+
try {
|
|
37
|
+
const value = JSON.parse(entry.source);
|
|
38
|
+
const pins = value.pins ?? value.object?.pins ?? [];
|
|
39
|
+
return pins.flatMap(pinValue => {
|
|
40
|
+
const pin = pinValue;
|
|
41
|
+
const reference = pin.location ?? pin.repositoryURL ?? pin.identity ?? pin.package ?? '';
|
|
42
|
+
if (!reference.toLowerCase().includes('lumen'))
|
|
43
|
+
return [];
|
|
44
|
+
return [{
|
|
45
|
+
platform: 'swift',
|
|
46
|
+
reference,
|
|
47
|
+
...(pin.state?.revision ? { revision: pin.state.revision } : {}),
|
|
48
|
+
...(pin.state?.version ? { version: pin.state.version } : {})
|
|
49
|
+
}];
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
const composeCoordinatePattern = /com\.santi020k:lumen-compose(?:-wear)?[:"]([0-9A-Za-z][0-9A-Za-z._-]*)/g;
|
|
57
|
+
const parseComposeCatalog = (entry) => {
|
|
58
|
+
if (!entry.file.endsWith('.toml'))
|
|
59
|
+
return [];
|
|
60
|
+
const versions = new Map();
|
|
61
|
+
const lines = entry.source.split(/\r?\n/u);
|
|
62
|
+
for (const line of lines) {
|
|
63
|
+
const match = /^\s*([A-Za-z0-9_.-]+)\s*=\s*"([^"]+)"\s*$/u.exec(line);
|
|
64
|
+
if (match?.[1] && match[2])
|
|
65
|
+
versions.set(match[1], match[2]);
|
|
66
|
+
}
|
|
67
|
+
return lines.flatMap(line => {
|
|
68
|
+
const module = /module\s*=\s*"(com\.santi020k:lumen-compose(?:-wear)?)"/u.exec(line)?.[1];
|
|
69
|
+
if (!module)
|
|
70
|
+
return [];
|
|
71
|
+
const directVersion = /version\s*=\s*"([^"]+)"/u.exec(line)?.[1];
|
|
72
|
+
const versionReference = /version\.ref\s*=\s*"([^"]+)"/u.exec(line)?.[1];
|
|
73
|
+
const version = directVersion ?? (versionReference ? versions.get(versionReference) : undefined);
|
|
74
|
+
return version ? [{ platform: 'compose', reference: module, version }] : [];
|
|
75
|
+
});
|
|
76
|
+
};
|
|
77
|
+
const parseComposeResolution = (entry) => {
|
|
78
|
+
const resolutions = parseComposeCatalog(entry);
|
|
79
|
+
for (const match of entry.source.matchAll(composeCoordinatePattern)) {
|
|
80
|
+
const version = match[1];
|
|
81
|
+
if (version)
|
|
82
|
+
resolutions.push({ platform: 'compose', reference: match[0], version });
|
|
83
|
+
}
|
|
84
|
+
return resolutions;
|
|
85
|
+
};
|
|
86
|
+
const addThemeFindings = (root, sources, platform, usesLumen) => {
|
|
87
|
+
if (!usesLumen)
|
|
88
|
+
return [];
|
|
89
|
+
const pattern = platform === 'swift' ? /\.lumenTheme\s*\(/g : /\bLumenTheme\s*\(/g;
|
|
90
|
+
const providers = sources.flatMap(entry => {
|
|
91
|
+
const count = [...entry.source.matchAll(pattern)].length;
|
|
92
|
+
return count ? [{ count, file: entry.file }] : [];
|
|
93
|
+
});
|
|
94
|
+
if (providers.length === 0) {
|
|
95
|
+
return [{
|
|
96
|
+
file: '.',
|
|
97
|
+
message: `No ${platform === 'swift' ? '.lumenTheme(...) modifier' : 'LumenTheme(...) provider'} was found.`,
|
|
98
|
+
remediation: platform === 'swift' ?
|
|
99
|
+
'Place the product theme at each application scene and preview that renders Lumen components.' :
|
|
100
|
+
'Place LumenTheme at the application root and pass the existing Material color scheme, typography, and shapes.',
|
|
101
|
+
rule: `${platform}-theme-missing`,
|
|
102
|
+
severity: 'warning'
|
|
103
|
+
}];
|
|
104
|
+
}
|
|
105
|
+
return providers.flatMap(provider => provider.count > 1 ?
|
|
106
|
+
[{
|
|
107
|
+
file: relative(root, provider.file),
|
|
108
|
+
message: `This file mounts ${provider.count} ${platform} theme providers.`,
|
|
109
|
+
remediation: 'Confirm the providers belong to independent scenes or previews; remove accidental nesting around the same surface.',
|
|
110
|
+
rule: `${platform}-theme-repeated`,
|
|
111
|
+
severity: 'suggestion'
|
|
112
|
+
}] :
|
|
113
|
+
[]);
|
|
114
|
+
};
|
|
115
|
+
const unique = (values, key) => [
|
|
116
|
+
...new Map(values.map(value => [key(value), value])).values()
|
|
117
|
+
];
|
|
118
|
+
const usesSwiftPackage = (sources, swiftSources) => (sources.some(entry => entry.file.endsWith('Package.swift') && entry.source.includes('LumenUI')) ||
|
|
119
|
+
swiftSources.some(entry => entry.source.includes('import LumenUI')));
|
|
120
|
+
const usesComposePackage = (sources) => sources.some(entry => (entry.source.includes('com.santi020k.lumen') || entry.source.includes('com.santi020k:lumen-compose')));
|
|
121
|
+
const collectResolutionFindings = (manifest, resolved, usesSwift, usesCompose) => {
|
|
122
|
+
const findings = [];
|
|
123
|
+
if (usesSwift && !resolved.some(item => item.platform === 'swift')) {
|
|
124
|
+
findings.push({
|
|
125
|
+
file: 'Package.resolved',
|
|
126
|
+
message: 'LumenUI is used but no resolved Swift package pin was found.',
|
|
127
|
+
remediation: 'Resolve package dependencies and commit Package.resolved with the intended release tag and revision.',
|
|
128
|
+
rule: 'swift-resolution-missing',
|
|
129
|
+
severity: 'warning'
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
if (usesCompose && !resolved.some(item => item.platform === 'compose')) {
|
|
133
|
+
findings.push({
|
|
134
|
+
file: '.',
|
|
135
|
+
message: 'Compose source uses Lumen but no Maven coordinate with an explicit version was found.',
|
|
136
|
+
remediation: `Declare com.santi020k:lumen-compose:${manifest.release.compose.version} directly or through a version catalog.`,
|
|
137
|
+
rule: 'compose-resolution-missing',
|
|
138
|
+
severity: 'warning'
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
for (const item of resolved) {
|
|
142
|
+
const expected = item.platform === 'compose' ?
|
|
143
|
+
manifest.release.compose.version :
|
|
144
|
+
manifest.release.swift.tag.replace(/^v/u, '');
|
|
145
|
+
if (item.version && item.version !== expected) {
|
|
146
|
+
findings.push({
|
|
147
|
+
file: '.',
|
|
148
|
+
message: `${item.reference} resolves ${item.version}; the release manifest expects ${expected}.`,
|
|
149
|
+
remediation: 'Align the native adapter with the cross-platform release manifest, then refresh the resolver lock file.',
|
|
150
|
+
rule: `${item.platform}-release-mismatch`,
|
|
151
|
+
severity: 'warning'
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return findings;
|
|
156
|
+
};
|
|
157
|
+
export const inspectNativeAdoption = async (repository, manifestPath = fileURLToPath(new URL('../release-manifest.json', import.meta.url))) => {
|
|
158
|
+
const root = resolve(repository);
|
|
159
|
+
if (!(await stat(root)).isDirectory())
|
|
160
|
+
throw new Error(`Not a directory: ${root}`);
|
|
161
|
+
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'));
|
|
162
|
+
const sources = await discoverNativeSources(root);
|
|
163
|
+
const swiftSources = sources.filter(entry => entry.file.endsWith('.swift'));
|
|
164
|
+
const composeSources = sources.filter(entry => ['.gradle', '.kts', '.toml'].includes(extname(entry.file)));
|
|
165
|
+
const usesSwift = usesSwiftPackage(sources, swiftSources);
|
|
166
|
+
const usesCompose = usesComposePackage(composeSources);
|
|
167
|
+
const resolved = unique([
|
|
168
|
+
...sources.flatMap(parseSwiftResolution),
|
|
169
|
+
...composeSources.flatMap(parseComposeResolution)
|
|
170
|
+
], value => `${value.platform}:${value.reference}:${value.version ?? ''}:${value.revision ?? ''}`);
|
|
171
|
+
const findings = [
|
|
172
|
+
...addThemeFindings(root, swiftSources, 'swift', usesSwift),
|
|
173
|
+
...addThemeFindings(root, composeSources, 'compose', usesCompose),
|
|
174
|
+
...collectResolutionFindings(manifest, resolved, usesSwift, usesCompose)
|
|
175
|
+
];
|
|
176
|
+
return {
|
|
177
|
+
findings: unique(findings, item => `${item.file}:${item.rule}:${item.message}`),
|
|
178
|
+
generatedAt: new Date().toISOString(),
|
|
179
|
+
platforms: [usesSwift && 'swift', usesCompose && 'compose'].filter(Boolean),
|
|
180
|
+
releaseVersion: manifest.release.version,
|
|
181
|
+
repository: root,
|
|
182
|
+
resolved
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
export const formatNativeAdoptionAudit = (report) => {
|
|
186
|
+
const heading = report.findings.length === 0 ?
|
|
187
|
+
'Native Lumen adoption matches the release manifest.' :
|
|
188
|
+
`Native Lumen adoption has ${report.findings.length} finding${report.findings.length === 1 ? '' : 's'}.`;
|
|
189
|
+
return [
|
|
190
|
+
heading,
|
|
191
|
+
...report.resolved.map(item => [
|
|
192
|
+
`[resolved] ${item.platform} ${item.reference}`,
|
|
193
|
+
item.version ? `version=${item.version}` : undefined,
|
|
194
|
+
item.revision ? `revision=${item.revision}` : undefined
|
|
195
|
+
].filter(Boolean).join(' ')),
|
|
196
|
+
...report.findings.map(item => (`[${item.severity}] ${item.file} ${item.rule}: ${item.message} ${item.remediation}`))
|
|
197
|
+
].join('\n');
|
|
198
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@santi020k/lumen",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
"types": "./dist/registry.d.ts",
|
|
23
23
|
"import": "./dist/registry.js"
|
|
24
24
|
},
|
|
25
|
+
"./release-manifest.json": "./release-manifest.json",
|
|
25
26
|
"./styles.css": "./styles.css",
|
|
26
27
|
"./layers.css": "./layers.css",
|
|
27
28
|
"./package.json": "./package.json"
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"bin",
|
|
31
32
|
"dist",
|
|
32
33
|
"layers.css",
|
|
34
|
+
"release-manifest.json",
|
|
33
35
|
"styles.css",
|
|
34
36
|
"README.md",
|
|
35
37
|
"LICENSE"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"release": {
|
|
4
|
+
"compose": {
|
|
5
|
+
"artifacts": [
|
|
6
|
+
"com.santi020k:lumen-compose",
|
|
7
|
+
"com.santi020k:lumen-compose-wear"
|
|
8
|
+
],
|
|
9
|
+
"version": "0.4.0"
|
|
10
|
+
},
|
|
11
|
+
"npm": {
|
|
12
|
+
"packages": {
|
|
13
|
+
"@santi020k/lumen-astro": {
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"astro": ">=5"
|
|
16
|
+
},
|
|
17
|
+
"version": "1.4.0"
|
|
18
|
+
},
|
|
19
|
+
"@santi020k/lumen-core": {
|
|
20
|
+
"peerDependencies": {},
|
|
21
|
+
"version": "1.4.0"
|
|
22
|
+
},
|
|
23
|
+
"@santi020k/lumen-elements": {
|
|
24
|
+
"peerDependencies": {},
|
|
25
|
+
"version": "1.4.0"
|
|
26
|
+
},
|
|
27
|
+
"@santi020k/lumen-icons-brand": {
|
|
28
|
+
"peerDependencies": {},
|
|
29
|
+
"version": "1.0.1"
|
|
30
|
+
},
|
|
31
|
+
"@santi020k/lumen": {
|
|
32
|
+
"peerDependencies": {},
|
|
33
|
+
"version": "1.5.0"
|
|
34
|
+
},
|
|
35
|
+
"@santi020k/lumen-mcp": {
|
|
36
|
+
"peerDependencies": {},
|
|
37
|
+
"version": "1.5.0"
|
|
38
|
+
},
|
|
39
|
+
"@santi020k/lumen-react": {
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"react": ">=19"
|
|
42
|
+
},
|
|
43
|
+
"version": "1.4.0"
|
|
44
|
+
},
|
|
45
|
+
"@santi020k/lumen-react-hook-form": {
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"@santi020k/lumen-react": "^1.0.0",
|
|
48
|
+
"react": ">=19",
|
|
49
|
+
"react-hook-form": ">=7.76.0 <8"
|
|
50
|
+
},
|
|
51
|
+
"version": "1.0.1"
|
|
52
|
+
},
|
|
53
|
+
"@santi020k/lumen-react-native": {
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": ">=19.2",
|
|
56
|
+
"react-native": ">=0.86.2"
|
|
57
|
+
},
|
|
58
|
+
"version": "0.4.0"
|
|
59
|
+
},
|
|
60
|
+
"@santi020k/lumen-tokens": {
|
|
61
|
+
"peerDependencies": {},
|
|
62
|
+
"version": "0.1.0"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"swift": {
|
|
67
|
+
"package": "https://github.com/santi020k/lumen.git",
|
|
68
|
+
"revision": null,
|
|
69
|
+
"tag": "v1.5.0"
|
|
70
|
+
},
|
|
71
|
+
"version": "1.5.0"
|
|
72
|
+
},
|
|
73
|
+
"migration": {
|
|
74
|
+
"codemod": null,
|
|
75
|
+
"css": {
|
|
76
|
+
"astro": "@santi020k/lumen-astro/styles.css",
|
|
77
|
+
"elements": "@santi020k/lumen-elements/styles.css",
|
|
78
|
+
"react": "@santi020k/lumen-react/styles.css"
|
|
79
|
+
},
|
|
80
|
+
"deprecatedExports": [],
|
|
81
|
+
"removedExports": [],
|
|
82
|
+
"runtime": {
|
|
83
|
+
"astro": "Mount UIPrimitives once when an imported component declares the ui-primitives runtime.",
|
|
84
|
+
"elements": "Call defineLumenElements once before rendering lumen-* elements.",
|
|
85
|
+
"react": "Use the public React behavior hooks for behavior-heavy primitives."
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|