@santi020k/lumen 0.3.0 → 1.0.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 +28 -2
- package/dist/cli.js +35 -9
- package/dist/consumer-rollout.d.ts +2 -0
- package/dist/consumer-rollout.d.ts.map +1 -1
- package/dist/consumer-rollout.js +33 -28
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +26 -8
- package/dist/integration-diagnostics.d.ts +21 -0
- package/dist/integration-diagnostics.d.ts.map +1 -0
- package/dist/integration-diagnostics.js +180 -0
- package/dist/registry-data.d.ts +224 -2
- package/dist/registry-data.d.ts.map +1 -1
- package/dist/registry-data.js +1761 -1246
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +18 -14
- package/dist/token-audit.d.ts.map +1 -1
- package/dist/token-audit.js +64 -9
- package/package.json +6 -4
- package/styles.css +958 -42
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,CAAA;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EACV,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,aAAa,EAAE,CAAA;AAExB,YAAY,EACV,aAAa,EACb,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,iBAAiB,EACjB,wBAAwB,EACzB,CAAA;AASD,eAAO,MAAM,uBAAuB,GAAI,WAAU,aAA6B,KAAG,kBAAkB,EAGnG,CAAA;AAED,eAAO,MAAM,oBAAoB,GAC/B,MAAM,MAAM,EACZ,WAAU,aAA6B,KACtC,kBAAkB,GAAG,SAQvB,CAAA;AAmFD,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,MAAM,GAAG,GAAG,EACpB,UAAS,wBAA6B,KACrC,OAAO,CAAC,aAAa,CAevB,CAAA;AAED,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACxB,MAAM,gBAAgB,CAAA"}
|
package/dist/registry.js
CHANGED
|
@@ -3,7 +3,10 @@ import { readFile } from 'node:fs/promises';
|
|
|
3
3
|
import { lumenRegistry } from './registry-data.js';
|
|
4
4
|
export { lumenRegistry };
|
|
5
5
|
const defaultRegistryTimeoutMs = 30_000;
|
|
6
|
-
const normalizeRegistryEntryName = (name) => name
|
|
6
|
+
const normalizeRegistryEntryName = (name) => name
|
|
7
|
+
.replaceAll(/([a-z0-9])([A-Z])/g, '$1-$2')
|
|
8
|
+
.replaceAll(/[\s_]+/g, '-')
|
|
9
|
+
.toLowerCase();
|
|
7
10
|
export const getLumenRegistryEntries = (registry = lumenRegistry) => [
|
|
8
11
|
...(registry.components ?? []),
|
|
9
12
|
...registry.items
|
|
@@ -11,8 +14,8 @@ export const getLumenRegistryEntries = (registry = lumenRegistry) => [
|
|
|
11
14
|
export const getLumenRegistryItem = (name, registry = lumenRegistry) => {
|
|
12
15
|
const normalizedName = normalizeRegistryEntryName(name);
|
|
13
16
|
const entries = getLumenRegistryEntries(registry);
|
|
14
|
-
return entries.find(item => item.name === name) ??
|
|
15
|
-
entries.find(item => normalizeRegistryEntryName(item.name) === normalizedName);
|
|
17
|
+
return (entries.find(item => item.name === name) ??
|
|
18
|
+
entries.find(item => normalizeRegistryEntryName(item.name) === normalizedName));
|
|
16
19
|
};
|
|
17
20
|
const isRegistryFile = (value) => {
|
|
18
21
|
if (typeof value === 'string')
|
|
@@ -22,42 +25,43 @@ const isRegistryFile = (value) => {
|
|
|
22
25
|
const file = value;
|
|
23
26
|
return typeof file.path === 'string' && typeof file.source === 'string';
|
|
24
27
|
};
|
|
25
|
-
const
|
|
26
|
-
const
|
|
28
|
+
const isString = (entry) => typeof entry === 'string';
|
|
29
|
+
const isStringArray = (value) => Array.isArray(value) && value.every(isString);
|
|
30
|
+
const isRegistryFileArray = (value) => Array.isArray(value) && value.every(isRegistryFile);
|
|
27
31
|
const registryItemTypes = new Set(['component-set', 'documentation', 'recipe']);
|
|
28
32
|
const isRegistryItem = (value) => {
|
|
29
33
|
if (!value || typeof value !== 'object')
|
|
30
34
|
return false;
|
|
31
35
|
const item = value;
|
|
32
|
-
return typeof item.name === 'string' &&
|
|
36
|
+
return (typeof item.name === 'string' &&
|
|
33
37
|
typeof item.type === 'string' &&
|
|
34
38
|
registryItemTypes.has(item.type) &&
|
|
35
39
|
(item.components === undefined || isStringArray(item.components)) &&
|
|
36
|
-
(item.files === undefined || isRegistryFileArray(item.files));
|
|
40
|
+
(item.files === undefined || isRegistryFileArray(item.files)));
|
|
37
41
|
};
|
|
38
42
|
const isRegistryComponent = (value) => {
|
|
39
43
|
if (!value || typeof value !== 'object')
|
|
40
44
|
return false;
|
|
41
45
|
const component = value;
|
|
42
|
-
return typeof component.name === 'string' &&
|
|
46
|
+
return (typeof component.name === 'string' &&
|
|
43
47
|
component.type === 'component' &&
|
|
44
48
|
typeof component.description === 'string' &&
|
|
45
49
|
typeof component.category === 'string' &&
|
|
46
50
|
isRegistryFileArray(component.files) &&
|
|
47
|
-
(component.dependencies === undefined || isStringArray(component.dependencies));
|
|
51
|
+
(component.dependencies === undefined || isStringArray(component.dependencies)));
|
|
48
52
|
};
|
|
49
53
|
const isLumenRegistry = (value) => {
|
|
50
54
|
if (!value || typeof value !== 'object')
|
|
51
55
|
return false;
|
|
52
56
|
const registry = value;
|
|
53
|
-
return typeof registry.name === 'string' &&
|
|
57
|
+
return (typeof registry.name === 'string' &&
|
|
54
58
|
typeof registry.version === 'number' &&
|
|
55
59
|
typeof registry.description === 'string' &&
|
|
56
60
|
isStringArray(registry.packages) &&
|
|
57
61
|
Array.isArray(registry.items) &&
|
|
58
62
|
registry.items.every(item => isRegistryItem(item)) &&
|
|
59
63
|
(registry.components === undefined ||
|
|
60
|
-
(Array.isArray(registry.components) && registry.components.every(component => isRegistryComponent(component))));
|
|
64
|
+
(Array.isArray(registry.components) && registry.components.every(component => isRegistryComponent(component)))));
|
|
61
65
|
};
|
|
62
66
|
const fetchRegistrySource = async (source, options) => {
|
|
63
67
|
if (options.token && source.startsWith('http://')) {
|
|
@@ -77,9 +81,9 @@ const fetchRegistrySource = async (source, options) => {
|
|
|
77
81
|
};
|
|
78
82
|
export const loadLumenRegistry = async (source, options = {}) => {
|
|
79
83
|
const sourceValue = String(source);
|
|
80
|
-
const raw = sourceValue.startsWith('http://') || sourceValue.startsWith('https://')
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
const raw = sourceValue.startsWith('http://') || sourceValue.startsWith('https://') ?
|
|
85
|
+
await fetchRegistrySource(sourceValue, options) :
|
|
86
|
+
await readFile(source, 'utf8');
|
|
83
87
|
const parsed = JSON.parse(raw);
|
|
84
88
|
if (!isLumenRegistry(parsed)) {
|
|
85
89
|
throw new Error('Invalid Lumen registry manifest');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"token-audit.d.ts","sourceRoot":"","sources":["../src/token-audit.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;
|
|
1
|
+
{"version":3,"file":"token-audit.d.ts","sourceRoot":"","sources":["../src/token-audit.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAkFD,eAAO,MAAM,kBAAkB,GAAI,QAAQ,MAAM,EAAE,aAAgB,KAAG,sBAAsB,EA+B3F,CAAA"}
|
package/dist/token-audit.js
CHANGED
|
@@ -1,18 +1,73 @@
|
|
|
1
1
|
import { lumenSemanticColorTokenNames } from '@santi020k/lumen-core';
|
|
2
|
-
const
|
|
3
|
-
|
|
2
|
+
const channelPattern = new RegExp([
|
|
3
|
+
String.raw `^(?:var\(.+\)|-?(?:\d+(?:\.\d+)?|\.\d+)`,
|
|
4
|
+
String.raw `(?:deg|grad|rad|turn)?\s+-?(?:\d+(?:\.\d+)?|\.\d+)%`,
|
|
5
|
+
String.raw `\s+-?(?:\d+(?:\.\d+)?|\.\d+)%`,
|
|
6
|
+
String.raw `(?:\s*\/\s*(?:\d+(?:\.\d+)?|\.\d+)%?)?)$`
|
|
7
|
+
].join(''), 'iu');
|
|
4
8
|
const semanticTokens = new Set(lumenSemanticColorTokenNames);
|
|
9
|
+
const isAsciiLetter = (character) => character !== undefined && /[a-z]/iu.test(character);
|
|
10
|
+
const isTokenCharacter = (character) => character !== undefined && /[\w-]/u.test(character);
|
|
11
|
+
const isWhitespace = (character) => character !== undefined && /\s/u.test(character);
|
|
12
|
+
const scanTokenDeclaration = (source, index) => {
|
|
13
|
+
let tokenEnd = index + 2;
|
|
14
|
+
if (!isAsciiLetter(source[tokenEnd]))
|
|
15
|
+
return { cursor: index + 1 };
|
|
16
|
+
tokenEnd += 1;
|
|
17
|
+
while (isTokenCharacter(source[tokenEnd]))
|
|
18
|
+
tokenEnd += 1;
|
|
19
|
+
const token = source.slice(index + 2, tokenEnd);
|
|
20
|
+
let colon = tokenEnd;
|
|
21
|
+
while (isWhitespace(source[colon]))
|
|
22
|
+
colon += 1;
|
|
23
|
+
if (source[colon] !== ':')
|
|
24
|
+
return { cursor: colon };
|
|
25
|
+
const valueStart = colon + 1;
|
|
26
|
+
let valueEnd = valueStart;
|
|
27
|
+
while (valueEnd < source.length &&
|
|
28
|
+
source[valueEnd] !== ';' &&
|
|
29
|
+
source[valueEnd] !== '}' &&
|
|
30
|
+
source[valueEnd] !== '\n') {
|
|
31
|
+
valueEnd += 1;
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
cursor: valueEnd,
|
|
35
|
+
declaration: {
|
|
36
|
+
index,
|
|
37
|
+
token,
|
|
38
|
+
value: source.slice(valueStart, valueEnd).trim()
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
const findTokenDeclarations = (source) => {
|
|
43
|
+
const declarations = [];
|
|
44
|
+
let cursor = 0;
|
|
45
|
+
while (cursor < source.length) {
|
|
46
|
+
const index = source.indexOf('--', cursor);
|
|
47
|
+
if (index === -1)
|
|
48
|
+
break;
|
|
49
|
+
const scan = scanTokenDeclaration(source, index);
|
|
50
|
+
cursor = scan.cursor;
|
|
51
|
+
if (scan.declaration)
|
|
52
|
+
declarations.push(scan.declaration);
|
|
53
|
+
}
|
|
54
|
+
return declarations;
|
|
55
|
+
};
|
|
5
56
|
export const auditLumenTokenCss = (source, file = '<input>') => {
|
|
6
57
|
const findings = [];
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
58
|
+
let line = 1;
|
|
59
|
+
let lineCursor = 0;
|
|
60
|
+
let lineStart = 0;
|
|
61
|
+
for (const { index, token, value } of findTokenDeclarations(source)) {
|
|
10
62
|
if (!token || !value || !semanticTokens.has(token) || channelPattern.test(value))
|
|
11
63
|
continue;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
64
|
+
let newline = source.indexOf('\n', lineCursor);
|
|
65
|
+
while (newline !== -1 && newline < index) {
|
|
66
|
+
line += 1;
|
|
67
|
+
lineStart = newline + 1;
|
|
68
|
+
lineCursor = lineStart;
|
|
69
|
+
newline = source.indexOf('\n', lineCursor);
|
|
70
|
+
}
|
|
16
71
|
findings.push({
|
|
17
72
|
column: index - lineStart + 1,
|
|
18
73
|
file,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@santi020k/lumen",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -39,12 +39,14 @@
|
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"semver": "^7.8.0",
|
|
42
|
-
"@santi020k/lumen-core": "^0.
|
|
42
|
+
"@santi020k/lumen-core": "^1.0.0"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/node": "^26.1.1",
|
|
46
|
+
"@types/react": "^19.2.17",
|
|
46
47
|
"@types/semver": "^7.7.1",
|
|
47
48
|
"@vitest/coverage-v8": "^4.1.10",
|
|
49
|
+
"react": "^19.2.8",
|
|
48
50
|
"typescript": "^6.0.3",
|
|
49
51
|
"tailwindcss": "^4.3.3",
|
|
50
52
|
"vitest": "^4.1.10"
|
|
@@ -72,8 +74,8 @@
|
|
|
72
74
|
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
73
75
|
"test": "vitest run --config ../../vitest.config.ts --project lumen",
|
|
74
76
|
"test:coverage": "vitest run --config ../../vitest.config.ts --project lumen --coverage",
|
|
75
|
-
"lint": "eslint . --no-warn-ignored",
|
|
76
|
-
"lint:fix": "eslint . --fix --no-warn-ignored",
|
|
77
|
+
"lint": "eslint . --no-warn-ignored --max-warnings=0",
|
|
78
|
+
"lint:fix": "eslint . --fix --no-warn-ignored --max-warnings=0",
|
|
77
79
|
"clean": "rm -rf dist coverage"
|
|
78
80
|
}
|
|
79
81
|
}
|