dowel-ui 0.12.0 → 0.14.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 +43 -0
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +9 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/codemod.d.ts +22 -0
- package/dist/cli/codemod.d.ts.map +1 -0
- package/dist/cli/codemod.js +69 -0
- package/dist/cli/codemod.js.map +1 -0
- package/dist/cli/diff.d.ts +23 -0
- package/dist/cli/diff.d.ts.map +1 -0
- package/dist/cli/diff.js +122 -0
- package/dist/cli/diff.js.map +1 -0
- package/dist/cli/doctor.d.ts +81 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +185 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.d.ts +8 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +362 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/scan.d.ts +43 -0
- package/dist/cli/scan.d.ts.map +1 -0
- package/dist/cli/scan.js +265 -0
- package/dist/cli/scan.js.map +1 -0
- package/dist/cli/stock.d.ts +29 -0
- package/dist/cli/stock.d.ts.map +1 -0
- package/dist/cli/stock.js +104 -0
- package/dist/cli/stock.js.map +1 -0
- package/dist/registry.json +40 -25
- package/package.json +9 -2
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { relative, resolve, sep } from 'node:path';
|
|
3
|
+
import { collectFiles, scanProject } from './scan.js';
|
|
4
|
+
import { rewriteSource } from './codemod.js';
|
|
5
|
+
import { diagnose, readCatalogue } from './doctor.js';
|
|
6
|
+
import { differs, diffLines, hunks } from './diff.js';
|
|
7
|
+
/*
|
|
8
|
+
* `dowel` - the command a product runs on itself.
|
|
9
|
+
*
|
|
10
|
+
* Four commands, and they divide along one line: `check`, `doctor` and `diff`
|
|
11
|
+
* only read, `codemod` writes and only when asked twice. That division is the
|
|
12
|
+
* design. A migration tool earns its place by being run early and often on a
|
|
13
|
+
* codebase nobody is ready to change yet, and a tool that might edit is a tool
|
|
14
|
+
* that gets run once, at the end, under supervision.
|
|
15
|
+
*
|
|
16
|
+
* Everything works offline. The catalogue a consumer needs is the one that
|
|
17
|
+
* came with the package they installed, so nothing here asks the network for
|
|
18
|
+
* permission to describe a project.
|
|
19
|
+
*/
|
|
20
|
+
/** ANSI, when the output is a terminal that wants it.
|
|
21
|
+
*
|
|
22
|
+
* `NO_COLOR` is honoured because this prints reports people paste into issues,
|
|
23
|
+
* and escape codes in a paste are noise. The check is done once at import: a
|
|
24
|
+
* report that is coloured at the top and plain at the bottom would mean the
|
|
25
|
+
* stream changed underneath, which it does not. */
|
|
26
|
+
const useColor = process.stdout.isTTY === true && !process.env.NO_COLOR && process.env.TERM !== 'dumb';
|
|
27
|
+
/* The escape is written as an escape sequence rather than typed as the byte
|
|
28
|
+
* itself. A literal ESC in a source file works and is invisible - which is
|
|
29
|
+
* the problem: it survives no encoding conversion and no tool that rewrites
|
|
30
|
+
* the file, and when it is lost the output turns into visible garbage rather
|
|
31
|
+
* than failing. */
|
|
32
|
+
const paint = (code) => (text) => (useColor ? `\u001b[${code}m${text}\u001b[0m` : text);
|
|
33
|
+
const bold = paint('1');
|
|
34
|
+
const dim = paint('2');
|
|
35
|
+
const red = paint('31');
|
|
36
|
+
const green = paint('32');
|
|
37
|
+
const yellow = paint('33');
|
|
38
|
+
const cyan = paint('36');
|
|
39
|
+
function parseOptions(argv) {
|
|
40
|
+
const positional = [];
|
|
41
|
+
let root = process.cwd();
|
|
42
|
+
let write = false;
|
|
43
|
+
let json = false;
|
|
44
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
45
|
+
const arg = argv[i];
|
|
46
|
+
if (arg === '--write') {
|
|
47
|
+
write = true;
|
|
48
|
+
}
|
|
49
|
+
else if (arg === '--json') {
|
|
50
|
+
json = true;
|
|
51
|
+
}
|
|
52
|
+
else if (arg === '--cwd') {
|
|
53
|
+
const value = argv[i + 1];
|
|
54
|
+
if (value) {
|
|
55
|
+
root = resolve(value);
|
|
56
|
+
i += 1;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (arg.startsWith('--cwd=')) {
|
|
60
|
+
root = resolve(arg.slice('--cwd='.length));
|
|
61
|
+
}
|
|
62
|
+
else if (!arg.startsWith('-')) {
|
|
63
|
+
positional.push(arg);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return { root, write, json, positional };
|
|
67
|
+
}
|
|
68
|
+
function reportCheck(findings, options) {
|
|
69
|
+
if (options.json) {
|
|
70
|
+
process.stdout.write(`${JSON.stringify({ findings }, null, 2)}\n`);
|
|
71
|
+
return findings.length > 0 ? 1 : 0;
|
|
72
|
+
}
|
|
73
|
+
if (findings.length === 0) {
|
|
74
|
+
process.stdout.write(`${green('Nothing to migrate.')} No stock tokens, no colours written down.\n`);
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
/* Grouped by file, because that is the unit a reader fixes in. Within a
|
|
78
|
+
* file the findings are already in line order from the scanner. */
|
|
79
|
+
const byFile = new Map();
|
|
80
|
+
for (const finding of findings) {
|
|
81
|
+
const list = byFile.get(finding.file);
|
|
82
|
+
if (list)
|
|
83
|
+
list.push(finding);
|
|
84
|
+
else
|
|
85
|
+
byFile.set(finding.file, [finding]);
|
|
86
|
+
}
|
|
87
|
+
for (const [file, list] of byFile) {
|
|
88
|
+
process.stdout.write(`\n${bold(file)}\n`);
|
|
89
|
+
for (const finding of list) {
|
|
90
|
+
/* Three marks, not two. An ambiguous name is not a violation - it is a
|
|
91
|
+
* name this tool cannot judge - and giving it the same mark as a stock
|
|
92
|
+
* token would tell a migrated project it has work to do. */
|
|
93
|
+
const mark = finding.kind === 'color'
|
|
94
|
+
? yellow('color')
|
|
95
|
+
: finding.replacement?.kind === 'ambiguous'
|
|
96
|
+
? dim('both ')
|
|
97
|
+
: cyan('stock');
|
|
98
|
+
process.stdout.write(` ${dim(`${finding.line}:${finding.column}`)} ${mark} ${finding.message}\n`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
const ambiguous = findings.filter((finding) => finding.replacement?.kind === 'ambiguous').length;
|
|
102
|
+
const stock = findings.filter((finding) => finding.kind === 'stock').length - ambiguous;
|
|
103
|
+
const colors = findings.filter((finding) => finding.kind === 'color').length;
|
|
104
|
+
const files = byFile.size;
|
|
105
|
+
const parts = [
|
|
106
|
+
`${stock} stock ${stock === 1 ? 'name' : 'names'}`,
|
|
107
|
+
`${colors} raw ${colors === 1 ? 'colour' : 'colours'}`,
|
|
108
|
+
];
|
|
109
|
+
if (ambiguous > 0)
|
|
110
|
+
parts.push(`${ambiguous} in both vocabularies`);
|
|
111
|
+
process.stdout.write(`\n${bold(String(findings.length))} findings in ${files} file${files === 1 ? '' : 's'}` +
|
|
112
|
+
` - ${parts.join(', ')}.\n`);
|
|
113
|
+
const rewritable = findings.filter((finding) => finding.kind === 'stock' && finding.replacement?.kind === 'token').length;
|
|
114
|
+
if (rewritable > 0) {
|
|
115
|
+
process.stdout.write(`${dim(`${rewritable} of them can be rewritten: dowel codemod --write`)}\n`);
|
|
116
|
+
}
|
|
117
|
+
if (colors > 0) {
|
|
118
|
+
process.stdout.write(`${dim('Colours are not rewritten: which token a colour meant is a decision, not a substitution.')}\n`);
|
|
119
|
+
}
|
|
120
|
+
if (ambiguous > 0) {
|
|
121
|
+
process.stdout.write(`${dim('Names in both vocabularies are never rewritten: on a migrated project they are already right.')}\n`);
|
|
122
|
+
}
|
|
123
|
+
/* Ambiguous names alone are not a reason to fail. A project that has fully
|
|
124
|
+
* migrated still reports them - every use of `--accent` is one - and an exit
|
|
125
|
+
* code that treats "correct" as "findings" cannot be put in a build. */
|
|
126
|
+
return stock + colors > 0 ? 1 : 0;
|
|
127
|
+
}
|
|
128
|
+
function commandCheck(options) {
|
|
129
|
+
if (!existsSync(options.root)) {
|
|
130
|
+
process.stderr.write(`${red('No such directory')}: ${options.root}\n`);
|
|
131
|
+
return 2;
|
|
132
|
+
}
|
|
133
|
+
return reportCheck(scanProject(options.root), options);
|
|
134
|
+
}
|
|
135
|
+
function commandCodemod(options) {
|
|
136
|
+
if (!existsSync(options.root)) {
|
|
137
|
+
process.stderr.write(`${red('No such directory')}: ${options.root}\n`);
|
|
138
|
+
return 2;
|
|
139
|
+
}
|
|
140
|
+
const touched = [];
|
|
141
|
+
const skipped = [];
|
|
142
|
+
let total = 0;
|
|
143
|
+
for (const path of collectFiles(options.root)) {
|
|
144
|
+
let source;
|
|
145
|
+
try {
|
|
146
|
+
source = readFileSync(path, 'utf8');
|
|
147
|
+
}
|
|
148
|
+
catch {
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const name = relative(options.root, path).split(sep).join('/');
|
|
152
|
+
const result = rewriteSource(source);
|
|
153
|
+
for (const entry of result.skipped)
|
|
154
|
+
skipped.push({ file: name, ...entry });
|
|
155
|
+
if (result.changes.length === 0)
|
|
156
|
+
continue;
|
|
157
|
+
total += result.changes.length;
|
|
158
|
+
touched.push({ file: name, changes: result.changes.length });
|
|
159
|
+
if (options.write)
|
|
160
|
+
writeFileSync(path, result.source);
|
|
161
|
+
}
|
|
162
|
+
if (options.json) {
|
|
163
|
+
process.stdout.write(`${JSON.stringify({ written: options.write, touched, skipped }, null, 2)}\n`);
|
|
164
|
+
return 0;
|
|
165
|
+
}
|
|
166
|
+
if (total === 0) {
|
|
167
|
+
process.stdout.write(`${green('Nothing to rewrite.')} No stock token names found.\n`);
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
for (const entry of touched) {
|
|
171
|
+
process.stdout.write(` ${bold(entry.file)} ${dim(`${entry.changes} renamed`)}\n`);
|
|
172
|
+
}
|
|
173
|
+
const verb = options.write ? 'Rewrote' : 'Would rewrite';
|
|
174
|
+
process.stdout.write(`\n${verb} ${bold(String(total))} ${total === 1 ? 'name' : 'names'} in ${touched.length} file${touched.length === 1 ? '' : 's'}.\n`);
|
|
175
|
+
if (!options.write) {
|
|
176
|
+
process.stdout.write(`${dim('Nothing was written. Run again with --write.')}\n`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/* The names deliberately left alone. These are why a run can finish and the
|
|
180
|
+
* migration still not be done, so they are printed even on a clean run.
|
|
181
|
+
*
|
|
182
|
+
* The heading does not say why, because there are two different whys - a
|
|
183
|
+
* name dowel has no equivalent for, and a name that exists in both
|
|
184
|
+
* vocabularies and is probably already right. Each entry carries its own
|
|
185
|
+
* reason; a single heading claiming one of them would be wrong half the
|
|
186
|
+
* time, and it was: it told a migrated project that `--accent` had no
|
|
187
|
+
* equivalent. */
|
|
188
|
+
if (skipped.length > 0) {
|
|
189
|
+
const names = [...new Set(skipped.map((entry) => entry.name))].sort();
|
|
190
|
+
process.stdout.write(`\n${yellow('Left alone')} - each with its reason:\n`);
|
|
191
|
+
for (const name of names) {
|
|
192
|
+
const note = skipped.find((entry) => entry.name === name).note;
|
|
193
|
+
const count = skipped.filter((entry) => entry.name === name).length;
|
|
194
|
+
process.stdout.write(` ${bold(name)} ${dim(`(${count})`)} - ${note}\n`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return 0;
|
|
198
|
+
}
|
|
199
|
+
/** Gather what `doctor` needs from a project on disk. */
|
|
200
|
+
function readProject(root) {
|
|
201
|
+
const readJson = (path) => {
|
|
202
|
+
const full = resolve(root, path);
|
|
203
|
+
if (!existsSync(full))
|
|
204
|
+
return undefined;
|
|
205
|
+
try {
|
|
206
|
+
return JSON.parse(readFileSync(full, 'utf8'));
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
const manifest = readJson('package.json');
|
|
213
|
+
const installedManifest = readJson('node_modules/dowel-ui/package.json');
|
|
214
|
+
const stylesheets = collectFiles(root)
|
|
215
|
+
.filter((path) => path.endsWith('.css'))
|
|
216
|
+
.map((path) => ({
|
|
217
|
+
path: relative(root, path).split(sep).join('/'),
|
|
218
|
+
source: readFileSync(path, 'utf8'),
|
|
219
|
+
}));
|
|
220
|
+
const catalogue = readCatalogue(root);
|
|
221
|
+
/* What has been copied in. A registry component is recognised by the file
|
|
222
|
+
* name matching a catalogue item and the file importing the package - the
|
|
223
|
+
* name alone would claim every `button.tsx` ever written. */
|
|
224
|
+
const installedComponents = [];
|
|
225
|
+
if (catalogue) {
|
|
226
|
+
const componentNames = new Set(catalogue.items.filter((item) => item.type === 'registry:ui').map((item) => item.name));
|
|
227
|
+
for (const path of collectFiles(root)) {
|
|
228
|
+
if (!path.endsWith('.tsx'))
|
|
229
|
+
continue;
|
|
230
|
+
const base = path.slice(path.lastIndexOf(sep) + 1).replace(/\.tsx$/, '');
|
|
231
|
+
if (!componentNames.has(base))
|
|
232
|
+
continue;
|
|
233
|
+
const source = readFileSync(path, 'utf8');
|
|
234
|
+
if (!source.includes('dowel-ui'))
|
|
235
|
+
continue;
|
|
236
|
+
installedComponents.push({ name: base, source });
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
root,
|
|
241
|
+
manifest,
|
|
242
|
+
installedVersion: installedManifest?.version,
|
|
243
|
+
stylesheets,
|
|
244
|
+
componentsConfig: readJson('components.json'),
|
|
245
|
+
catalogue,
|
|
246
|
+
installedComponents,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
function commandDoctor(options) {
|
|
250
|
+
if (!existsSync(options.root)) {
|
|
251
|
+
process.stderr.write(`${red('No such directory')}: ${options.root}\n`);
|
|
252
|
+
return 2;
|
|
253
|
+
}
|
|
254
|
+
const findings = diagnose(readProject(options.root));
|
|
255
|
+
if (options.json) {
|
|
256
|
+
process.stdout.write(`${JSON.stringify({ findings }, null, 2)}\n`);
|
|
257
|
+
return findings.some((finding) => finding.severity === 'problem') ? 1 : 0;
|
|
258
|
+
}
|
|
259
|
+
if (findings.length === 0) {
|
|
260
|
+
process.stdout.write(`${green('The installation is coherent.')}\n`);
|
|
261
|
+
return 0;
|
|
262
|
+
}
|
|
263
|
+
for (const finding of findings) {
|
|
264
|
+
const mark = finding.severity === 'problem' ? red('problem') : yellow('note ');
|
|
265
|
+
process.stdout.write(`${mark} ${bold(finding.check)} ${finding.message}\n`);
|
|
266
|
+
if (finding.fix)
|
|
267
|
+
process.stdout.write(` ${dim(finding.fix)}\n`);
|
|
268
|
+
}
|
|
269
|
+
const problems = findings.filter((finding) => finding.severity === 'problem').length;
|
|
270
|
+
return problems > 0 ? 1 : 0;
|
|
271
|
+
}
|
|
272
|
+
function commandDiff(options) {
|
|
273
|
+
const root = options.root;
|
|
274
|
+
const catalogue = readCatalogue(root);
|
|
275
|
+
if (!catalogue) {
|
|
276
|
+
process.stderr.write(`${red('No catalogue')}: dowel-ui is not installed here, so there is nothing to compare against.\n`);
|
|
277
|
+
return 2;
|
|
278
|
+
}
|
|
279
|
+
const facts = readProject(root);
|
|
280
|
+
const wanted = options.positional[0];
|
|
281
|
+
const targets = wanted
|
|
282
|
+
? facts.installedComponents.filter((component) => component.name === wanted)
|
|
283
|
+
: facts.installedComponents;
|
|
284
|
+
if (wanted && targets.length === 0) {
|
|
285
|
+
process.stderr.write(`${red('Not found')}: no component named ${bold(wanted)} in this project.\n`);
|
|
286
|
+
return 2;
|
|
287
|
+
}
|
|
288
|
+
const changed = [];
|
|
289
|
+
for (const component of targets) {
|
|
290
|
+
const item = catalogue.items.find((candidate) => candidate.name === component.name);
|
|
291
|
+
const file = item?.files?.[0];
|
|
292
|
+
const upstream = file?.content;
|
|
293
|
+
if (typeof upstream !== 'string')
|
|
294
|
+
continue;
|
|
295
|
+
if (!differs(upstream, component.source))
|
|
296
|
+
continue;
|
|
297
|
+
changed.push({ name: component.name, hunks: hunks(diffLines(upstream, component.source)) });
|
|
298
|
+
}
|
|
299
|
+
if (options.json) {
|
|
300
|
+
process.stdout.write(`${JSON.stringify({ changed }, null, 2)}\n`);
|
|
301
|
+
return 0;
|
|
302
|
+
}
|
|
303
|
+
if (changed.length === 0) {
|
|
304
|
+
const scope = wanted ? bold(wanted) : `${targets.length} component${targets.length === 1 ? '' : 's'}`;
|
|
305
|
+
process.stdout.write(`${green('Unchanged')}: ${scope} ${targets.length === 1 ? 'matches' : 'match'} the registry.\n`);
|
|
306
|
+
return 0;
|
|
307
|
+
}
|
|
308
|
+
for (const component of changed) {
|
|
309
|
+
process.stdout.write(`\n${bold(component.name)} ${dim('- registry above, yours below')}\n`);
|
|
310
|
+
for (const hunk of component.hunks) {
|
|
311
|
+
process.stdout.write(dim(` @@ registry ${hunk.fromLine}, yours ${hunk.toLine} @@\n`));
|
|
312
|
+
for (const line of hunk.lines) {
|
|
313
|
+
if (line.kind === 'same')
|
|
314
|
+
process.stdout.write(dim(` ${line.text}\n`));
|
|
315
|
+
else if (line.kind === 'removed')
|
|
316
|
+
process.stdout.write(red(` - ${line.text}\n`));
|
|
317
|
+
else
|
|
318
|
+
process.stdout.write(green(` + ${line.text}\n`));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
process.stdout.write(`\n${bold(String(changed.length))} of ${targets.length} ${targets.length === 1 ? 'component differs' : 'components differ'} from the registry.\n` +
|
|
323
|
+
`${dim('That is allowed - a copied component is yours. Nothing here merges anything.')}\n`);
|
|
324
|
+
return 0;
|
|
325
|
+
}
|
|
326
|
+
const USAGE = `dowel - migration tools for the lacodda design system
|
|
327
|
+
|
|
328
|
+
dowel check What in this project is not on the dowel vocabulary
|
|
329
|
+
dowel codemod [--write] Rewrite stock shadcn token names into dowel's
|
|
330
|
+
dowel doctor Whether this project's dowel installation is coherent
|
|
331
|
+
dowel diff [component] How a copied component differs from the registry's
|
|
332
|
+
|
|
333
|
+
Options
|
|
334
|
+
--cwd <dir> Look at this directory instead of the current one
|
|
335
|
+
--json Machine-readable output
|
|
336
|
+
--write codemod only: actually write the files
|
|
337
|
+
|
|
338
|
+
Everything reads the catalogue inside the installed package; nothing needs the
|
|
339
|
+
network. https://lacodda.github.io/dowel/guides/migration/
|
|
340
|
+
`;
|
|
341
|
+
export function run(argv) {
|
|
342
|
+
const command = argv.find((arg) => !arg.startsWith('-'));
|
|
343
|
+
const options = parseOptions(argv.filter((arg) => arg !== command));
|
|
344
|
+
switch (command) {
|
|
345
|
+
case 'check':
|
|
346
|
+
return commandCheck(options);
|
|
347
|
+
case 'codemod':
|
|
348
|
+
return commandCodemod(options);
|
|
349
|
+
case 'doctor':
|
|
350
|
+
return commandDoctor(options);
|
|
351
|
+
case 'diff':
|
|
352
|
+
return commandDiff(options);
|
|
353
|
+
case 'help':
|
|
354
|
+
case undefined:
|
|
355
|
+
process.stdout.write(USAGE);
|
|
356
|
+
return command === undefined ? 2 : 0;
|
|
357
|
+
default:
|
|
358
|
+
process.stderr.write(`${red('Unknown command')}: ${command}\n\n${USAGE}`);
|
|
359
|
+
return 2;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type Replacement } from './stock.js';
|
|
2
|
+
/** Where a finding is. Line and column are 1-based, as an editor counts. */
|
|
3
|
+
export interface Location {
|
|
4
|
+
readonly file: string;
|
|
5
|
+
readonly line: number;
|
|
6
|
+
readonly column: number;
|
|
7
|
+
}
|
|
8
|
+
/** One thing found in one place. */
|
|
9
|
+
export interface Finding extends Location {
|
|
10
|
+
/** `stock` - a name from the shadcn vocabulary; `color` - a colour written
|
|
11
|
+
* down rather than named. */
|
|
12
|
+
readonly kind: 'stock' | 'color';
|
|
13
|
+
/** The text that was matched, for showing back to the reader. */
|
|
14
|
+
readonly text: string;
|
|
15
|
+
/** What is wrong, in a sentence. */
|
|
16
|
+
readonly message: string;
|
|
17
|
+
/** The token to use instead, when there is an honest one. */
|
|
18
|
+
readonly replacement?: Replacement;
|
|
19
|
+
}
|
|
20
|
+
/** Every file under `root` worth scanning, as absolute paths, in a stable
|
|
21
|
+
* order - a report that reshuffles between runs cannot be diffed. */
|
|
22
|
+
export declare function collectFiles(root: string): string[];
|
|
23
|
+
/** Every string literal in a source file, with where it starts.
|
|
24
|
+
*
|
|
25
|
+
* This is the textual stand-in for the rule's `Literal` and `TemplateElement`
|
|
26
|
+
* visitors, and it exists so that a colour is only reported where a colour
|
|
27
|
+
* could actually be written - in a string - rather than anywhere the
|
|
28
|
+
* characters happen to appear. Without it, a comment explaining the rule would
|
|
29
|
+
* be a finding: it has to write a colour down to say which ones are forbidden.
|
|
30
|
+
*
|
|
31
|
+
* It is a small scanner rather than a regular expression because quotes nest:
|
|
32
|
+
* an apostrophe inside double quotes is one string, not two.
|
|
33
|
+
*/
|
|
34
|
+
export declare function stringLiterals(source: string): {
|
|
35
|
+
text: string;
|
|
36
|
+
index: number;
|
|
37
|
+
}[];
|
|
38
|
+
/** Read one file and say what is wrong with it. */
|
|
39
|
+
export declare function scanSource(source: string, file: string): Finding[];
|
|
40
|
+
/** Scan a whole project. Paths in the findings are relative to `root`, with
|
|
41
|
+
* forward slashes, so a report reads the same on either platform. */
|
|
42
|
+
export declare function scanProject(root: string): Finding[];
|
|
43
|
+
//# sourceMappingURL=scan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../src/cli/scan.ts"],"names":[],"mappings":"AAGA,OAAO,EAA2B,KAAK,WAAW,EAAE,MAAM,YAAY,CAAA;AA6BtE,4EAA4E;AAC5E,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED,oCAAoC;AACpC,MAAM,WAAW,OAAQ,SAAQ,QAAQ;IACvC;iCAC6B;IAC7B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IAChC,iEAAiE;IACjE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,6DAA6D;IAC7D,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,CAAA;CACnC;AAsCD;qEACqE;AACrE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAsCnD;AAoCD;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CA2ChF;AAuBD,mDAAmD;AACnD,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAkFlE;AAED;qEACqE;AACrE,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAanD"}
|