ilse-design 0.3.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.
- package/README.md +187 -0
- package/dist/agent/executor.d.ts +20 -0
- package/dist/agent/executor.d.ts.map +1 -0
- package/dist/agent/executor.js +130 -0
- package/dist/agent/executor.js.map +1 -0
- package/dist/ai/provider.d.ts +45 -0
- package/dist/ai/provider.d.ts.map +1 -0
- package/dist/ai/provider.js +374 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/analysis/classify-element.d.ts +23 -0
- package/dist/analysis/classify-element.d.ts.map +1 -0
- package/dist/analysis/classify-element.js +79 -0
- package/dist/analysis/classify-element.js.map +1 -0
- package/dist/analysis/compare-family.d.ts +22 -0
- package/dist/analysis/compare-family.d.ts.map +1 -0
- package/dist/analysis/compare-family.js +82 -0
- package/dist/analysis/compare-family.js.map +1 -0
- package/dist/analysis/profile-component.d.ts +32 -0
- package/dist/analysis/profile-component.d.ts.map +1 -0
- package/dist/analysis/profile-component.js +119 -0
- package/dist/analysis/profile-component.js.map +1 -0
- package/dist/bridge/augment.d.ts +20 -0
- package/dist/bridge/augment.d.ts.map +1 -0
- package/dist/bridge/augment.js +110 -0
- package/dist/bridge/augment.js.map +1 -0
- package/dist/bridge/store.d.ts +17 -0
- package/dist/bridge/store.d.ts.map +1 -0
- package/dist/bridge/store.js +70 -0
- package/dist/bridge/store.js.map +1 -0
- package/dist/bridge/ws-server.d.ts +12 -0
- package/dist/bridge/ws-server.d.ts.map +1 -0
- package/dist/bridge/ws-server.js +136 -0
- package/dist/bridge/ws-server.js.map +1 -0
- package/dist/cli/check.d.ts +8 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +303 -0
- package/dist/cli/check.js.map +1 -0
- package/dist/cli/default.d.ts +2 -0
- package/dist/cli/default.d.ts.map +1 -0
- package/dist/cli/default.js +166 -0
- package/dist/cli/default.js.map +1 -0
- package/dist/cli/extract.d.ts +5 -0
- package/dist/cli/extract.d.ts.map +1 -0
- package/dist/cli/extract.js +62 -0
- package/dist/cli/extract.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +111 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +5 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +190 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/insight.d.ts +5 -0
- package/dist/cli/insight.d.ts.map +1 -0
- package/dist/cli/insight.js +141 -0
- package/dist/cli/insight.js.map +1 -0
- package/dist/cli/listen.d.ts +10 -0
- package/dist/cli/listen.d.ts.map +1 -0
- package/dist/cli/listen.js +94 -0
- package/dist/cli/listen.js.map +1 -0
- package/dist/cli/login.d.ts +15 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +302 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/config/limits.d.ts +13 -0
- package/dist/config/limits.d.ts.map +1 -0
- package/dist/config/limits.js +26 -0
- package/dist/config/limits.js.map +1 -0
- package/dist/config/mcp-register.d.ts +5 -0
- package/dist/config/mcp-register.d.ts.map +1 -0
- package/dist/config/mcp-register.js +50 -0
- package/dist/config/mcp-register.js.map +1 -0
- package/dist/config/preferences.d.ts +22 -0
- package/dist/config/preferences.d.ts.map +1 -0
- package/dist/config/preferences.js +159 -0
- package/dist/config/preferences.js.map +1 -0
- package/dist/config/user-config.d.ts +10 -0
- package/dist/config/user-config.d.ts.map +1 -0
- package/dist/config/user-config.js +32 -0
- package/dist/config/user-config.js.map +1 -0
- package/dist/constants.d.ts +11 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +49 -0
- package/dist/constants.js.map +1 -0
- package/dist/extraction/find-inconsistencies.d.ts +17 -0
- package/dist/extraction/find-inconsistencies.d.ts.map +1 -0
- package/dist/extraction/find-inconsistencies.js +93 -0
- package/dist/extraction/find-inconsistencies.js.map +1 -0
- package/dist/extraction/find-patterns.d.ts +20 -0
- package/dist/extraction/find-patterns.d.ts.map +1 -0
- package/dist/extraction/find-patterns.js +179 -0
- package/dist/extraction/find-patterns.js.map +1 -0
- package/dist/extraction/index-tokens.d.ts +16 -0
- package/dist/extraction/index-tokens.d.ts.map +1 -0
- package/dist/extraction/index-tokens.js +103 -0
- package/dist/extraction/index-tokens.js.map +1 -0
- package/dist/fixer/autofix.d.ts +11 -0
- package/dist/fixer/autofix.d.ts.map +1 -0
- package/dist/fixer/autofix.js +202 -0
- package/dist/fixer/autofix.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +271 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/parsers/repo.d.ts +22 -0
- package/dist/parsers/repo.d.ts.map +1 -0
- package/dist/parsers/repo.js +165 -0
- package/dist/parsers/repo.js.map +1 -0
- package/dist/parsers/snapshot.d.ts +15 -0
- package/dist/parsers/snapshot.d.ts.map +1 -0
- package/dist/parsers/snapshot.js +136 -0
- package/dist/parsers/snapshot.js.map +1 -0
- package/dist/parsers/tokens.d.ts +10 -0
- package/dist/parsers/tokens.d.ts.map +1 -0
- package/dist/parsers/tokens.js +119 -0
- package/dist/parsers/tokens.js.map +1 -0
- package/dist/react/annotator.d.ts +64 -0
- package/dist/react/annotator.d.ts.map +1 -0
- package/dist/react/annotator.js +279 -0
- package/dist/react/annotator.js.map +1 -0
- package/dist/react/area-selector.d.ts +14 -0
- package/dist/react/area-selector.d.ts.map +1 -0
- package/dist/react/area-selector.js +76 -0
- package/dist/react/area-selector.js.map +1 -0
- package/dist/react/freeze.d.ts +5 -0
- package/dist/react/freeze.d.ts.map +1 -0
- package/dist/react/freeze.js +109 -0
- package/dist/react/freeze.js.map +1 -0
- package/dist/react/image-input.d.ts +14 -0
- package/dist/react/image-input.d.ts.map +1 -0
- package/dist/react/image-input.js +100 -0
- package/dist/react/image-input.js.map +1 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +13 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/toolbar.d.ts +2 -0
- package/dist/react/toolbar.d.ts.map +1 -0
- package/dist/react/toolbar.js +755 -0
- package/dist/react/toolbar.js.map +1 -0
- package/dist/react/ws-client.d.ts +8 -0
- package/dist/react/ws-client.d.ts.map +1 -0
- package/dist/react/ws-client.js +71 -0
- package/dist/react/ws-client.js.map +1 -0
- package/dist/reporters/coverage.d.ts +6 -0
- package/dist/reporters/coverage.d.ts.map +1 -0
- package/dist/reporters/coverage.js +74 -0
- package/dist/reporters/coverage.js.map +1 -0
- package/dist/reporters/ds-report.d.ts +8 -0
- package/dist/reporters/ds-report.d.ts.map +1 -0
- package/dist/reporters/ds-report.js +66 -0
- package/dist/reporters/ds-report.js.map +1 -0
- package/dist/reporters/terminal.d.ts +43 -0
- package/dist/reporters/terminal.d.ts.map +1 -0
- package/dist/reporters/terminal.js +361 -0
- package/dist/reporters/terminal.js.map +1 -0
- package/dist/setup/framework-detect.d.ts +8 -0
- package/dist/setup/framework-detect.d.ts.map +1 -0
- package/dist/setup/framework-detect.js +109 -0
- package/dist/setup/framework-detect.js.map +1 -0
- package/dist/setup/inject-component.d.ts +12 -0
- package/dist/setup/inject-component.d.ts.map +1 -0
- package/dist/setup/inject-component.js +98 -0
- package/dist/setup/inject-component.js.map +1 -0
- package/dist/types.d.ts +170 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/ast.d.ts +18 -0
- package/dist/utils/ast.d.ts.map +1 -0
- package/dist/utils/ast.js +57 -0
- package/dist/utils/ast.js.map +1 -0
- package/dist/utils/files.d.ts +6 -0
- package/dist/utils/files.d.ts.map +1 -0
- package/dist/utils/files.js +25 -0
- package/dist/utils/files.js.map +1 -0
- package/dist/utils/suggest.d.ts +37 -0
- package/dist/utils/suggest.d.ts.map +1 -0
- package/dist/utils/suggest.js +158 -0
- package/dist/utils/suggest.js.map +1 -0
- package/dist/validators/coverage.d.ts +24 -0
- package/dist/validators/coverage.d.ts.map +1 -0
- package/dist/validators/coverage.js +156 -0
- package/dist/validators/coverage.js.map +1 -0
- package/dist/validators/static.d.ts +14 -0
- package/dist/validators/static.d.ts.map +1 -0
- package/dist/validators/static.js +398 -0
- package/dist/validators/static.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { mkdtempSync, rmSync, existsSync, readdirSync, statSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { parseTokens } from './tokens.js';
|
|
6
|
+
// File patterns to look for in a design system repo
|
|
7
|
+
const TOKEN_FILE_PATTERNS = [
|
|
8
|
+
'tokens.json',
|
|
9
|
+
'design-tokens.json',
|
|
10
|
+
'**/tokens/**/*.json',
|
|
11
|
+
'**/design-tokens/**/*.json',
|
|
12
|
+
'tokens.ts',
|
|
13
|
+
'tokens.js',
|
|
14
|
+
];
|
|
15
|
+
const THEME_FILE_PATTERNS = [
|
|
16
|
+
'tailwind.config.ts',
|
|
17
|
+
'tailwind.config.js',
|
|
18
|
+
'tailwind.config.mjs',
|
|
19
|
+
'theme.json',
|
|
20
|
+
'theme.ts',
|
|
21
|
+
'theme.js',
|
|
22
|
+
];
|
|
23
|
+
/**
|
|
24
|
+
* Normalize a GitHub URL for cloning.
|
|
25
|
+
* Accepts: github.com/org/repo, https://github.com/org/repo, etc.
|
|
26
|
+
*/
|
|
27
|
+
function normalizeGitUrl(url) {
|
|
28
|
+
let cleaned = url.trim();
|
|
29
|
+
// Remove trailing slashes and .git
|
|
30
|
+
cleaned = cleaned.replace(/\/+$/, '').replace(/\.git$/, '');
|
|
31
|
+
// If no protocol, add https://
|
|
32
|
+
if (!cleaned.startsWith('http://') && !cleaned.startsWith('https://') && !cleaned.startsWith('git@')) {
|
|
33
|
+
cleaned = `https://${cleaned}`;
|
|
34
|
+
}
|
|
35
|
+
return `${cleaned}.git`;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Find JSON token files in a directory recursively.
|
|
39
|
+
*/
|
|
40
|
+
function findTokenFiles(dir, depth = 3) {
|
|
41
|
+
const results = [];
|
|
42
|
+
function walk(currentDir, currentDepth) {
|
|
43
|
+
if (currentDepth > depth)
|
|
44
|
+
return;
|
|
45
|
+
let entries;
|
|
46
|
+
try {
|
|
47
|
+
entries = readdirSync(currentDir);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
for (const entry of entries) {
|
|
53
|
+
if (entry.startsWith('.') || entry === 'node_modules' || entry === 'dist')
|
|
54
|
+
continue;
|
|
55
|
+
const fullPath = join(currentDir, entry);
|
|
56
|
+
let stat;
|
|
57
|
+
try {
|
|
58
|
+
stat = statSync(fullPath);
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (stat.isDirectory()) {
|
|
64
|
+
walk(fullPath, currentDepth + 1);
|
|
65
|
+
}
|
|
66
|
+
else if (entry.endsWith('.json')) {
|
|
67
|
+
// Try to parse as tokens
|
|
68
|
+
const parseResult = parseTokens(fullPath);
|
|
69
|
+
if (parseResult.ok) {
|
|
70
|
+
results.push(fullPath);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
walk(dir, 0);
|
|
76
|
+
return results;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Clone a GitHub repository and scan for design token files.
|
|
80
|
+
*/
|
|
81
|
+
export function cloneAndScan(repoUrl) {
|
|
82
|
+
const gitUrl = normalizeGitUrl(repoUrl);
|
|
83
|
+
const tempDir = mkdtempSync(join(tmpdir(), 'ilse-'));
|
|
84
|
+
try {
|
|
85
|
+
// Shallow clone for speed
|
|
86
|
+
execSync(`git clone --depth 1 ${gitUrl} ${tempDir}`, {
|
|
87
|
+
stdio: 'pipe',
|
|
88
|
+
timeout: 30000,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
catch (err) {
|
|
92
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
93
|
+
return {
|
|
94
|
+
ok: false,
|
|
95
|
+
error: `Falha ao clonar repositório: ${err.message.split('\n')[0]}`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Find token files
|
|
99
|
+
const tokenFiles = findTokenFiles(tempDir);
|
|
100
|
+
if (tokenFiles.length === 0) {
|
|
101
|
+
// Don't clean up yet — caller might want to inspect
|
|
102
|
+
return {
|
|
103
|
+
ok: false,
|
|
104
|
+
error: 'Nenhum arquivo de tokens encontrado no repositório.',
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Parse all token files and merge
|
|
108
|
+
const allTokens = [];
|
|
109
|
+
const fileResults = [];
|
|
110
|
+
for (const file of tokenFiles) {
|
|
111
|
+
const result = parseTokens(file);
|
|
112
|
+
if (result.ok) {
|
|
113
|
+
allTokens.push(...result.value);
|
|
114
|
+
// Make path relative to temp dir for display
|
|
115
|
+
const relativePath = file.replace(tempDir + '/', '');
|
|
116
|
+
fileResults.push({ path: relativePath, tokenCount: result.value.length });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (allTokens.length === 0) {
|
|
120
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
121
|
+
return { ok: false, error: 'Arquivos encontrados mas nenhum token válido extraído.' };
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
ok: true,
|
|
125
|
+
value: { tokens: allTokens, files: fileResults, tempDir },
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Scan a local directory for token files.
|
|
130
|
+
*/
|
|
131
|
+
export function scanDirectory(dirPath) {
|
|
132
|
+
if (!existsSync(dirPath)) {
|
|
133
|
+
return { ok: false, error: `Diretório não encontrado: ${dirPath}` };
|
|
134
|
+
}
|
|
135
|
+
const tokenFiles = findTokenFiles(dirPath);
|
|
136
|
+
if (tokenFiles.length === 0) {
|
|
137
|
+
return { ok: false, error: 'Nenhum arquivo de tokens encontrado no diretório.' };
|
|
138
|
+
}
|
|
139
|
+
const allTokens = [];
|
|
140
|
+
const fileResults = [];
|
|
141
|
+
for (const file of tokenFiles) {
|
|
142
|
+
const result = parseTokens(file);
|
|
143
|
+
if (result.ok) {
|
|
144
|
+
allTokens.push(...result.value);
|
|
145
|
+
const relativePath = file.replace(dirPath + '/', '');
|
|
146
|
+
fileResults.push({ path: relativePath, tokenCount: result.value.length });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (allTokens.length === 0) {
|
|
150
|
+
return { ok: false, error: 'Arquivos encontrados mas nenhum token válido extraído.' };
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
ok: true,
|
|
154
|
+
value: { tokens: allTokens, files: fileResults, tempDir: dirPath },
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Clean up a temporary directory created by cloneAndScan.
|
|
159
|
+
*/
|
|
160
|
+
export function cleanupTemp(tempDir) {
|
|
161
|
+
if (tempDir.startsWith(join(tmpdir(), 'ilse-'))) {
|
|
162
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/parsers/repo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAG1C,oDAAoD;AACpD,MAAM,mBAAmB,GAAG;IAC1B,aAAa;IACb,oBAAoB;IACpB,qBAAqB;IACrB,4BAA4B;IAC5B,WAAW;IACX,WAAW;CACZ,CAAC;AAEF,MAAM,mBAAmB,GAAG;IAC1B,oBAAoB;IACpB,oBAAoB;IACpB,qBAAqB;IACrB,YAAY;IACZ,UAAU;IACV,UAAU;CACX,CAAC;AAEF;;;GAGG;AACH,SAAS,eAAe,CAAC,GAAW;IAClC,IAAI,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAEzB,mCAAmC;IACnC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IAE5D,+BAA+B;IAC/B,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACrG,OAAO,GAAG,WAAW,OAAO,EAAE,CAAC;IACjC,CAAC;IAED,OAAO,GAAG,OAAO,MAAM,CAAC;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,GAAW,EAAE,QAAgB,CAAC;IACpD,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,SAAS,IAAI,CAAC,UAAkB,EAAE,YAAoB;QACpD,IAAI,YAAY,GAAG,KAAK;YAAE,OAAO;QAEjC,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,cAAc,IAAI,KAAK,KAAK,MAAM;gBAAE,SAAS;YAEpF,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YACzC,IAAI,IAAI,CAAC;YACT,IAAI,CAAC;gBACH,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,CAAC,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnC,yBAAyB;gBACzB,MAAM,WAAW,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,WAAW,CAAC,EAAE,EAAE,CAAC;oBACnB,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACb,OAAO,OAAO,CAAC;AACjB,CAAC;AAQD;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC;IAErD,IAAI,CAAC;QACH,0BAA0B;QAC1B,QAAQ,CAAC,uBAAuB,MAAM,IAAI,OAAO,EAAE,EAAE;YACnD,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,gCAAiC,GAAa,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE;SAC/E,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAE3C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,oDAAoD;QACpD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,qDAAqD;SAC7D,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,MAAM,SAAS,GAAY,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAgD,EAAE,CAAC;IAEpE,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAChC,6CAA6C;YAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;YACrD,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wDAAwD,EAAE,CAAC;IACxF,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE;KAC1D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,6BAA6B,OAAO,EAAE,EAAE,CAAC;IACtE,CAAC;IAED,MAAM,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IAE3C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,mDAAmD,EAAE,CAAC;IACnF,CAAC;IAED,MAAM,SAAS,GAAY,EAAE,CAAC;IAC9B,MAAM,WAAW,GAAgD,EAAE,CAAC;IAEpE,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC;YACrD,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wDAAwD,EAAE,CAAC;IACxF,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE;KACnE,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;QAChD,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Token, TokenSnapshot, DSDiffReport, Result } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Save current tokens as a snapshot.
|
|
4
|
+
*/
|
|
5
|
+
export declare function saveSnapshot(tokens: Token[], dir?: string): Result<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Load the previous token snapshot.
|
|
8
|
+
* Returns null if no snapshot exists (first run).
|
|
9
|
+
*/
|
|
10
|
+
export declare function loadSnapshot(dir?: string): Result<TokenSnapshot | null>;
|
|
11
|
+
/**
|
|
12
|
+
* Compare previous and current tokens to detect changes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function diffTokens(previous: Token[], current: Token[]): DSDiffReport;
|
|
15
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/parsers/snapshot.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAe,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI3F;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAcxE;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,CAcvE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,CAmG5E"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { hexToRgb, colorDistance } from '../utils/suggest.js';
|
|
4
|
+
const SNAPSHOT_FILENAME = '.ilse-snapshot.json';
|
|
5
|
+
/**
|
|
6
|
+
* Save current tokens as a snapshot.
|
|
7
|
+
*/
|
|
8
|
+
export function saveSnapshot(tokens, dir) {
|
|
9
|
+
const filePath = resolve(dir || process.cwd(), SNAPSHOT_FILENAME);
|
|
10
|
+
const snapshot = {
|
|
11
|
+
version: '0.2.0',
|
|
12
|
+
timestamp: new Date().toISOString(),
|
|
13
|
+
tokens,
|
|
14
|
+
};
|
|
15
|
+
try {
|
|
16
|
+
writeFileSync(filePath, JSON.stringify(snapshot, null, 2), 'utf-8');
|
|
17
|
+
return { ok: true, value: undefined };
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
return { ok: false, error: `Falha ao salvar snapshot: ${err.message}` };
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Load the previous token snapshot.
|
|
25
|
+
* Returns null if no snapshot exists (first run).
|
|
26
|
+
*/
|
|
27
|
+
export function loadSnapshot(dir) {
|
|
28
|
+
const filePath = resolve(dir || process.cwd(), SNAPSHOT_FILENAME);
|
|
29
|
+
if (!existsSync(filePath)) {
|
|
30
|
+
return { ok: true, value: null };
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const raw = readFileSync(filePath, 'utf-8');
|
|
34
|
+
const snapshot = JSON.parse(raw);
|
|
35
|
+
return { ok: true, value: snapshot };
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return { ok: false, error: `Falha ao ler snapshot: ${err.message}` };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Compare previous and current tokens to detect changes.
|
|
43
|
+
*/
|
|
44
|
+
export function diffTokens(previous, current) {
|
|
45
|
+
const changes = [];
|
|
46
|
+
const prevMap = new Map();
|
|
47
|
+
for (const t of previous)
|
|
48
|
+
prevMap.set(t.name, t);
|
|
49
|
+
const currMap = new Map();
|
|
50
|
+
for (const t of current)
|
|
51
|
+
currMap.set(t.name, t);
|
|
52
|
+
// Detect removed and changed
|
|
53
|
+
const removed = [];
|
|
54
|
+
for (const [name, prevToken] of prevMap) {
|
|
55
|
+
const currToken = currMap.get(name);
|
|
56
|
+
if (!currToken) {
|
|
57
|
+
removed.push(prevToken);
|
|
58
|
+
}
|
|
59
|
+
else if (currToken.value !== prevToken.value) {
|
|
60
|
+
changes.push({
|
|
61
|
+
type: 'changed',
|
|
62
|
+
tokenName: name,
|
|
63
|
+
oldValue: prevToken.value,
|
|
64
|
+
newValue: currToken.value,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Detect added
|
|
69
|
+
const added = [];
|
|
70
|
+
for (const [name] of currMap) {
|
|
71
|
+
if (!prevMap.has(name)) {
|
|
72
|
+
added.push(currMap.get(name));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Rename detection: removed + added with same value and type
|
|
76
|
+
const matchedRemoved = new Set();
|
|
77
|
+
const matchedAdded = new Set();
|
|
78
|
+
for (const rem of removed) {
|
|
79
|
+
for (const add of added) {
|
|
80
|
+
if (matchedAdded.has(add.name))
|
|
81
|
+
continue;
|
|
82
|
+
if (rem.type !== add.type)
|
|
83
|
+
continue;
|
|
84
|
+
let isMatch = false;
|
|
85
|
+
if (rem.type === 'color') {
|
|
86
|
+
// Tight color distance for rename detection
|
|
87
|
+
const rgbA = hexToRgb(rem.value);
|
|
88
|
+
const rgbB = hexToRgb(add.value);
|
|
89
|
+
if (rgbA && rgbB) {
|
|
90
|
+
isMatch = colorDistance(rgbA, rgbB) < 5;
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
isMatch = rem.value === add.value;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
isMatch = rem.value === add.value;
|
|
98
|
+
}
|
|
99
|
+
if (isMatch) {
|
|
100
|
+
changes.push({
|
|
101
|
+
type: 'renamed',
|
|
102
|
+
tokenName: rem.name,
|
|
103
|
+
newName: add.name,
|
|
104
|
+
oldValue: rem.value,
|
|
105
|
+
newValue: add.value,
|
|
106
|
+
});
|
|
107
|
+
matchedRemoved.add(rem.name);
|
|
108
|
+
matchedAdded.add(add.name);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// Remaining removed (not renamed)
|
|
114
|
+
for (const rem of removed) {
|
|
115
|
+
if (!matchedRemoved.has(rem.name)) {
|
|
116
|
+
changes.push({
|
|
117
|
+
type: 'removed',
|
|
118
|
+
tokenName: rem.name,
|
|
119
|
+
oldValue: rem.value,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Remaining added (not renamed)
|
|
124
|
+
for (const add of added) {
|
|
125
|
+
if (!matchedAdded.has(add.name)) {
|
|
126
|
+
changes.push({
|
|
127
|
+
type: 'added',
|
|
128
|
+
tokenName: add.name,
|
|
129
|
+
newValue: add.value,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const hasBreakingChanges = changes.some((c) => c.type === 'removed' || c.type === 'changed');
|
|
134
|
+
return { changes, hasBreakingChanges };
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/parsers/snapshot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Token, Result } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse W3C Design Tokens JSON file into a flat Token array.
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseTokens(filePath: string): Result<Token[]>;
|
|
6
|
+
/**
|
|
7
|
+
* Get tokens filtered by type.
|
|
8
|
+
*/
|
|
9
|
+
export declare function getTokensByType(tokens: Token[], type: Token['type']): Token[];
|
|
10
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../../src/parsers/tokens.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AA+GjD;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CA8B7D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,KAAK,EAAE,CAE7E"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
2
|
+
/**
|
|
3
|
+
* Check if an object is a W3C Design Token (has $value).
|
|
4
|
+
*/
|
|
5
|
+
function isTokenValue(obj) {
|
|
6
|
+
return (typeof obj === 'object' &&
|
|
7
|
+
obj !== null &&
|
|
8
|
+
'$value' in obj &&
|
|
9
|
+
typeof obj.$value === 'string');
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Infer token type from the value if $type is not provided.
|
|
13
|
+
*/
|
|
14
|
+
function inferType(value) {
|
|
15
|
+
// Color patterns: #hex, rgb(), rgba(), hsl(), hsla()
|
|
16
|
+
if (value.startsWith('#') ||
|
|
17
|
+
value.startsWith('rgb') ||
|
|
18
|
+
value.startsWith('hsl')) {
|
|
19
|
+
return 'color';
|
|
20
|
+
}
|
|
21
|
+
// Spacing patterns: px, rem, em, %
|
|
22
|
+
if (/^-?\d+(\.\d+)?(px|rem|em|%)$/.test(value)) {
|
|
23
|
+
return 'spacing';
|
|
24
|
+
}
|
|
25
|
+
// Typography patterns: font sizes, weights, families
|
|
26
|
+
if (/^\d+(px|rem|em)$/.test(value) || // font sizes
|
|
27
|
+
/^\d{3}$/.test(value) || // font weights (100-900)
|
|
28
|
+
/^[a-zA-Z]/.test(value) // font families
|
|
29
|
+
) {
|
|
30
|
+
return 'typography';
|
|
31
|
+
}
|
|
32
|
+
// Default to spacing for numeric values
|
|
33
|
+
if (/^-?\d+(\.\d+)?$/.test(value)) {
|
|
34
|
+
return 'spacing';
|
|
35
|
+
}
|
|
36
|
+
return 'color'; // fallback
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Map W3C $type to our Token type.
|
|
40
|
+
*/
|
|
41
|
+
function mapW3CType(w3cType) {
|
|
42
|
+
const typeMap = {
|
|
43
|
+
color: 'color',
|
|
44
|
+
dimension: 'spacing',
|
|
45
|
+
spacing: 'spacing',
|
|
46
|
+
sizing: 'spacing',
|
|
47
|
+
fontFamily: 'typography',
|
|
48
|
+
fontWeight: 'typography',
|
|
49
|
+
fontSize: 'typography',
|
|
50
|
+
lineHeight: 'typography',
|
|
51
|
+
letterSpacing: 'typography',
|
|
52
|
+
typography: 'typography',
|
|
53
|
+
};
|
|
54
|
+
return typeMap[w3cType] || 'color';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Recursively flatten W3C Design Tokens into a flat Token array.
|
|
58
|
+
*/
|
|
59
|
+
function flattenTokens(obj, path = []) {
|
|
60
|
+
const tokens = [];
|
|
61
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
62
|
+
// Skip $-prefixed metadata keys at group level
|
|
63
|
+
if (key.startsWith('$')) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const currentPath = [...path, key];
|
|
67
|
+
if (isTokenValue(value)) {
|
|
68
|
+
const type = value.$type ? mapW3CType(value.$type) : inferType(value.$value);
|
|
69
|
+
tokens.push({
|
|
70
|
+
name: currentPath.join('.'),
|
|
71
|
+
value: value.$value,
|
|
72
|
+
type,
|
|
73
|
+
path: currentPath,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
else if (typeof value === 'object' && value !== null) {
|
|
77
|
+
// Recurse into nested groups
|
|
78
|
+
tokens.push(...flattenTokens(value, currentPath));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return tokens;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Parse W3C Design Tokens JSON file into a flat Token array.
|
|
85
|
+
*/
|
|
86
|
+
export function parseTokens(filePath) {
|
|
87
|
+
if (!existsSync(filePath)) {
|
|
88
|
+
return { ok: false, error: `Token file not found: ${filePath}` };
|
|
89
|
+
}
|
|
90
|
+
let content;
|
|
91
|
+
try {
|
|
92
|
+
content = readFileSync(filePath, 'utf-8');
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
return { ok: false, error: `Failed to read token file: ${err.message}` };
|
|
96
|
+
}
|
|
97
|
+
let parsed;
|
|
98
|
+
try {
|
|
99
|
+
parsed = JSON.parse(content);
|
|
100
|
+
}
|
|
101
|
+
catch (err) {
|
|
102
|
+
return { ok: false, error: `Invalid JSON in token file: ${err.message}` };
|
|
103
|
+
}
|
|
104
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
105
|
+
return { ok: false, error: 'Token file must be a JSON object' };
|
|
106
|
+
}
|
|
107
|
+
const tokens = flattenTokens(parsed);
|
|
108
|
+
if (tokens.length === 0) {
|
|
109
|
+
return { ok: false, error: 'No tokens found in file' };
|
|
110
|
+
}
|
|
111
|
+
return { ok: true, value: tokens };
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get tokens filtered by type.
|
|
115
|
+
*/
|
|
116
|
+
export function getTokensByType(tokens, type) {
|
|
117
|
+
return tokens.filter((t) => t.type === type);
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=tokens.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../../src/parsers/tokens.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface ElementCapture {
|
|
2
|
+
element: string;
|
|
3
|
+
component?: string;
|
|
4
|
+
styles: Record<string, string>;
|
|
5
|
+
parent?: string;
|
|
6
|
+
rect: {
|
|
7
|
+
top: number;
|
|
8
|
+
left: number;
|
|
9
|
+
width: number;
|
|
10
|
+
height: number;
|
|
11
|
+
};
|
|
12
|
+
grepPattern?: string;
|
|
13
|
+
componentStack?: string[];
|
|
14
|
+
_scrollX?: number;
|
|
15
|
+
_scrollY?: number;
|
|
16
|
+
domPath?: string;
|
|
17
|
+
nearbyElements?: string[];
|
|
18
|
+
}
|
|
19
|
+
export interface PageEnvironment {
|
|
20
|
+
viewport: string;
|
|
21
|
+
url: string;
|
|
22
|
+
userAgent: string;
|
|
23
|
+
devicePixelRatio: number;
|
|
24
|
+
timestamp: string;
|
|
25
|
+
}
|
|
26
|
+
export declare function captureEnvironment(): PageEnvironment;
|
|
27
|
+
export type CaptureMode = 'click' | 'text' | 'area';
|
|
28
|
+
export declare function getComponentStack(el: Element): string[];
|
|
29
|
+
export interface TextCapture {
|
|
30
|
+
text: string;
|
|
31
|
+
element: string;
|
|
32
|
+
component?: string;
|
|
33
|
+
styles: Record<string, string>;
|
|
34
|
+
rect: {
|
|
35
|
+
top: number;
|
|
36
|
+
left: number;
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
};
|
|
40
|
+
grepPattern?: string;
|
|
41
|
+
componentStack?: string[];
|
|
42
|
+
}
|
|
43
|
+
export interface AreaCapture {
|
|
44
|
+
elements: Array<{
|
|
45
|
+
selector: string;
|
|
46
|
+
tag: string;
|
|
47
|
+
}>;
|
|
48
|
+
region: {
|
|
49
|
+
top: number;
|
|
50
|
+
left: number;
|
|
51
|
+
width: number;
|
|
52
|
+
height: number;
|
|
53
|
+
};
|
|
54
|
+
elementCount: number;
|
|
55
|
+
}
|
|
56
|
+
export declare function captureTextSelection(): TextCapture | null;
|
|
57
|
+
export declare function captureArea(region: {
|
|
58
|
+
top: number;
|
|
59
|
+
left: number;
|
|
60
|
+
width: number;
|
|
61
|
+
height: number;
|
|
62
|
+
}): AreaCapture;
|
|
63
|
+
export declare function captureElement(el: Element): ElementCapture;
|
|
64
|
+
//# sourceMappingURL=annotator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"annotator.d.ts","sourceRoot":"","sources":["../../src/react/annotator.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAQpD;AAiGD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAIpD,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,OAAO,GAAG,MAAM,EAAE,CAuBvD;AAyDD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACnD,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACrE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,oBAAoB,IAAI,WAAW,GAAG,IAAI,CAgCzD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,WAAW,CAoC7G;AA4BD,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,cAAc,CAsB1D"}
|