@rafters/veneer 0.0.2 → 0.0.4

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/dist/bin.mjs CHANGED
@@ -1,20 +1,54 @@
1
1
  #!/usr/bin/env node
2
- import { t as check } from "./check-DxTxqBre.mjs";
2
+ import { i as relativeFile } from "./lint-Bqu-nKvP.mjs";
3
+ import { t as check } from "./check-vsAQPYCD.mjs";
4
+ import path from "node:path";
5
+ import { existsSync, realpathSync } from "node:fs";
6
+ import { parseArgs } from "node:util";
7
+ import { text } from "node:stream/consumers";
3
8
  //#region src/bin.ts
4
- const [root, ...rest] = process.argv.slice(2);
5
- if (root?.startsWith("-") || rest.length > 0) {
6
- process.stderr.write("usage: rafters-check [root]\n");
7
- process.exitCode = 1;
8
- } else {
9
- const result = await check(root ?? process.cwd());
10
- if (result.ok) {
11
- process.stdout.write(result.report);
12
- for (const { message } of result.notices) process.stderr.write(`${message}\n`);
13
- process.exitCode = result.diagnostics.some(({ severity }) => severity === "error") ? 1 : 0;
14
- } else {
9
+ const COULD_NOT_RUN = 2;
10
+ function parsedArguments() {
11
+ try {
12
+ const { values, positionals } = parseArgs({
13
+ allowPositionals: true,
14
+ options: { stdin: { type: "string" } }
15
+ });
16
+ const [root, ...rest] = positionals;
17
+ return rest.length > 0 ? void 0 : {
18
+ root,
19
+ stdinPath: values.stdin
20
+ };
21
+ } catch {
22
+ return;
23
+ }
24
+ }
25
+ function resolvedLinks(file) {
26
+ if (existsSync(file)) return realpathSync(file);
27
+ const parent = path.dirname(file);
28
+ return parent === file ? file : path.join(resolvedLinks(parent), path.basename(file));
29
+ }
30
+ async function run(root, stdinPath) {
31
+ const file = stdinPath && relativeFile(resolvedLinks(root), resolvedLinks(path.resolve(stdinPath)));
32
+ const unsaved = file === void 0 ? void 0 : { [file]: await text(process.stdin) };
33
+ const result = await check(root, { unsaved });
34
+ if (!result.ok) {
15
35
  for (const { message } of result.errors) process.stderr.write(`${message}\n`);
16
- process.exitCode = 1;
36
+ return COULD_NOT_RUN;
17
37
  }
38
+ process.stdout.write(result.report);
39
+ for (const { message } of result.notices) process.stderr.write(`${message}\n`);
40
+ return result.diagnostics.some(({ severity }) => severity === "error") ? 1 : 0;
41
+ }
42
+ const parsed = parsedArguments();
43
+ if (parsed) try {
44
+ process.exitCode = await run(parsed.root ?? process.cwd(), parsed.stdinPath);
45
+ } catch (error) {
46
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
47
+ process.exitCode = COULD_NOT_RUN;
48
+ }
49
+ else {
50
+ process.stderr.write("usage: rafters-check [root] [--stdin <path>]\n");
51
+ process.exitCode = COULD_NOT_RUN;
18
52
  }
19
53
  //#endregion
20
54
  export {};
@@ -1,4 +1,4 @@
1
- import { a as ProjectError, i as resolveComponents, n as report, o as openProject, r as compareCodePoints, s as readConfig, t as lint } from "./lint-BabXVYQJ.mjs";
1
+ import { a as resolveComponents, c as readConfig, n as report, o as ProjectError, r as compareCodePoints, s as openProject, t as lint } from "./lint-Bqu-nKvP.mjs";
2
2
  import path from "node:path";
3
3
  import { mkdir, rename, rm, writeFile } from "node:fs/promises";
4
4
  import { lstatSync } from "node:fs";
@@ -139,6 +139,7 @@ async function check(projectRoot, options = {}) {
139
139
  const asked = options.paths ?? (unsavedFiles.length > 0 ? unsavedFiles : void 0);
140
140
  const diagnostics = await lint(project, {
141
141
  componentFolders: config.componentFolders,
142
+ scan: config.scan,
142
143
  files: isSave ? void 0 : asked?.filter((file) => !outside.includes(file))
143
144
  });
144
145
  const written = isSave ? await writeDocsFrom(project, config) : void 0;
package/dist/index.d.mts CHANGED
@@ -1,6 +1,8 @@
1
1
  import { AstroCheck, Diagnostic as Diagnostic$1 } from "@astrojs/language-server";
2
2
  import * as TypeScript from "typescript";
3
3
  //#region src/config.d.ts
4
+ declare const SCANS: readonly ["system", "format", "all"];
5
+ type Scan = (typeof SCANS)[number];
4
6
  interface Notice {
5
7
  code: string;
6
8
  message: string;
@@ -47,6 +49,7 @@ interface LintDiagnostic extends Diagnostic {
47
49
  }
48
50
  export declare function lint(project: Project, options: {
49
51
  componentFolders: string[];
52
+ scan?: Scan;
50
53
  files?: string[];
51
54
  }): Promise<LintDiagnostic[]>;
52
55
  export declare function report(diagnostics: LintDiagnostic[]): string;
package/dist/index.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import { a as ProjectError, n as report, o as openProject, t as lint } from "./lint-BabXVYQJ.mjs";
2
- import { n as writeDocs, t as check } from "./check-DxTxqBre.mjs";
1
+ import { n as report, o as ProjectError, s as openProject, t as lint } from "./lint-Bqu-nKvP.mjs";
2
+ import { n as writeDocs, t as check } from "./check-vsAQPYCD.mjs";
3
3
  export { ProjectError, check, lint, openProject, report, writeDocs };
@@ -6,6 +6,12 @@ import { format } from "node:util";
6
6
  import { AstroCheck } from "@astrojs/language-server";
7
7
  //#region src/config.ts
8
8
  const CONFIG_FILE = ".rafters/config.rafters.json";
9
+ const SCANS = [
10
+ "system",
11
+ "format",
12
+ "all"
13
+ ];
14
+ const isScan = (value) => SCANS.some((scan) => scan === value);
9
15
  function isObject(value) {
10
16
  return typeof value === "object" && value !== null && !Array.isArray(value);
11
17
  }
@@ -98,7 +104,10 @@ async function readConfig(root) {
98
104
  }
99
105
  if (intent !== void 0 && typeof intent !== "string") errors.push(fieldError("intent", "expected a string", intent));
100
106
  if (veneer !== void 0 && !isObject(veneer)) errors.push(fieldError("veneer", "expected an object", veneer));
101
- else if (veneer?.mdxPath !== void 0 && typeof veneer.mdxPath !== "string") errors.push(fieldError("veneer.mdxPath", "expected a string", veneer.mdxPath));
107
+ else {
108
+ if (veneer?.mdxPath !== void 0 && typeof veneer.mdxPath !== "string") errors.push(fieldError("veneer.mdxPath", "expected a string", veneer.mdxPath));
109
+ if (veneer?.scan !== void 0 && !isScan(veneer.scan)) errors.push(fieldError("veneer.scan", `expected one of ${SCANS.join(", ")}`, veneer.scan));
110
+ }
102
111
  if (errors.length > 0) return {
103
112
  ok: false,
104
113
  errors
@@ -107,6 +116,7 @@ async function readConfig(root) {
107
116
  ok: true,
108
117
  intent: typeof intent === "string" ? intent : null,
109
118
  componentFolders,
119
+ scan: isObject(veneer) && isScan(veneer.scan) ? veneer.scan : "format",
110
120
  notices
111
121
  };
112
122
  }
@@ -669,7 +679,15 @@ function ownPropNames(reader, component, sourceFile) {
669
679
  if (!signature) return [];
670
680
  return propsOfSignature(reader, signature, sourceFile, /* @__PURE__ */ new Map()).props.map(({ name }) => name);
671
681
  }
672
- function intelligenceBlock(reader, sourceFile) {
682
+ const INTELLIGENCE_TAGS = [
683
+ "cognitive-load",
684
+ "attention-economics",
685
+ "trust-building",
686
+ "accessibility",
687
+ "semantic-meaning",
688
+ "usage-patterns"
689
+ ];
690
+ function placedBlocks(reader, sourceFile) {
673
691
  const { ts } = reader;
674
692
  const blocks = [];
675
693
  const visit = (node) => {
@@ -684,7 +702,16 @@ function intelligenceBlock(reader, sourceFile) {
684
702
  block,
685
703
  at
686
704
  }];
687
- }).sort((a, b) => a.at - b.at)[0]?.block;
705
+ });
706
+ }
707
+ function intelligenceBlock(reader, sourceFile) {
708
+ return placedBlocks(reader, sourceFile).sort((a, b) => a.at - b.at)[0]?.block;
709
+ }
710
+ function holdsAllIntelligenceTags(reader, sourceFile) {
711
+ return placedBlocks(reader, sourceFile).some(({ block }) => {
712
+ const names = new Set(block.tags?.map((tag) => tag.tagName.text));
713
+ return INTELLIGENCE_TAGS.every((tag) => names.has(tag));
714
+ });
688
715
  }
689
716
  function intelligence(reader, sourceFile) {
690
717
  const { ts } = reader;
@@ -785,6 +812,13 @@ const CLASS_ATTRIBUTES = /* @__PURE__ */ new Set([
785
812
  ]);
786
813
  const MAX_RESOLVE_STEPS = 8;
787
814
  const realPath = (file) => existsSync(file) ? realpathSync(file) : file;
815
+ const isClassesFile = (file) => file.endsWith(".classes.ts");
816
+ function qualifies(reader, sourceFile) {
817
+ const { fileName } = sourceFile;
818
+ const stem = fileName.replace(/\.(tsx|astro)$/, "");
819
+ const { sys } = reader.ts;
820
+ return stem !== fileName && sys.fileExists(`${stem}.behavior.ts`) && sys.fileExists(`${stem}.classes.ts`) && holdsAllIntelligenceTags(reader, sourceFile);
821
+ }
788
822
  function offsetAt(text, line, column) {
789
823
  const breaks = /\r\n|\r|\n/g;
790
824
  let start = 0;
@@ -817,8 +851,8 @@ function elementUsing(ts, node) {
817
851
  const element = tag.parent;
818
852
  return ts.isJsxOpeningLikeElement(element) && element.tagName === tag ? element : void 0;
819
853
  }
820
- function resolveTag({ ts, tc }, { tagName }) {
821
- let symbol = tc.getSymbolAtLocation(ts.isPropertyAccessExpression(tagName) ? tagName.name : tagName);
854
+ function resolveSymbol({ ts, tc }, start) {
855
+ let symbol = start;
822
856
  for (let step = 0; symbol && step < MAX_RESOLVE_STEPS; step += 1) {
823
857
  const declaration = symbol.valueDeclaration;
824
858
  if (symbol.flags & ts.SymbolFlags.Alias) symbol = tc.getAliasedSymbol(symbol);
@@ -826,6 +860,10 @@ function resolveTag({ ts, tc }, { tagName }) {
826
860
  else return symbol;
827
861
  }
828
862
  }
863
+ function resolveTag(reader, { tagName }) {
864
+ const { ts, tc } = reader;
865
+ return resolveSymbol(reader, tc.getSymbolAtLocation(ts.isPropertyAccessExpression(tagName) ? tagName.name : tagName));
866
+ }
829
867
  function deprecatedText({ ts, tc }, element, name) {
830
868
  const parameter = tc.getResolvedSignature(element)?.parameters[0];
831
869
  const tag = (parameter && tc.getTypeOfSymbol(parameter).getProperty(name))?.getJsDocTags(tc).find((found) => found.name === "deprecated");
@@ -842,46 +880,82 @@ function utilityOf(className) {
842
880
  }
843
881
  return className.slice(start);
844
882
  }
845
- function classLiterals(ts, node) {
846
- if (ts.isStringLiteralLike(node)) return [node];
847
- if (ts.isJsxExpression(node) || ts.isParenthesizedExpression(node)) return node.expression ? classLiterals(ts, node.expression) : [];
848
- if (ts.isArrayLiteralExpression(node)) return node.elements.flatMap((element) => classLiterals(ts, element));
849
- if (ts.isObjectLiteralExpression(node)) return node.properties.flatMap((property) => ts.isPropertyAssignment(property) && ts.isStringLiteral(property.name) ? [property.name] : []);
850
- return [];
883
+ function constInitializer(reader, identifier) {
884
+ const { ts, tc } = reader;
885
+ const declaration = resolveSymbol(reader, tc.getSymbolAtLocation(identifier))?.valueDeclaration;
886
+ return declaration && ts.isVariableDeclaration(declaration) && ts.getCombinedNodeFlags(declaration) & ts.NodeFlags.Const ? declaration.initializer : void 0;
887
+ }
888
+ function constString(reader, identifier) {
889
+ const initializer = constInitializer(reader, identifier);
890
+ return initializer && reader.ts.isStringLiteralLike(initializer) ? initializer : void 0;
891
+ }
892
+ function constProperty(reader, { expression, name }) {
893
+ const { ts } = reader;
894
+ let object = ts.isIdentifier(expression) ? constInitializer(reader, expression) : void 0;
895
+ while (object && (ts.isAsExpression(object) || ts.isSatisfiesExpression(object))) object = object.expression;
896
+ if (!object || !ts.isObjectLiteralExpression(object)) return void 0;
897
+ for (const property of object.properties) if (ts.isPropertyAssignment(property) && ts.isIdentifier(property.name) && property.name.text === name.text) return ts.isStringLiteralLike(property.initializer) ? property.initializer : void 0;
898
+ }
899
+ function collectClassStrings(reader, sourceFile, isOwnSource, node, found) {
900
+ const { ts } = reader;
901
+ if (ts.isStringLiteralLike(node)) found.set(node, node);
902
+ else if (ts.isIdentifier(node)) {
903
+ const literal = constString(reader, node);
904
+ const declaredIn = literal?.getSourceFile();
905
+ if (!literal || !declaredIn) return;
906
+ if (declaredIn === sourceFile) found.set(literal, literal);
907
+ else if (isOwnSource(declaredIn.fileName)) found.set(node, literal);
908
+ } else {
909
+ const literal = ts.isPropertyAccessExpression(node) ? constProperty(reader, node) : void 0;
910
+ const declaredIn = literal?.getSourceFile();
911
+ if (literal && declaredIn && (declaredIn === sourceFile || isOwnSource(declaredIn.fileName))) {
912
+ found.set(node, literal);
913
+ return;
914
+ }
915
+ ts.forEachChild(node, (child) => {
916
+ collectClassStrings(reader, sourceFile, isOwnSource, child, found);
917
+ });
918
+ }
851
919
  }
852
- function bracketsInLiteral(reader, file, sourceFile, literal) {
853
- return [...literal.getText(sourceFile).slice(1, -1).matchAll(/\S+/g)].flatMap((match) => {
920
+ function bracketsInLiteral(reader, file, sourceFile, at, literal) {
921
+ return [...literal.getText(literal.getSourceFile()).slice(1, -1).matchAll(/\S+/g)].flatMap((match) => {
854
922
  const [className] = match;
855
923
  if (!utilityOf(className).includes("[")) return [];
856
- const position = positionOf(reader, sourceFile, literal.getStart(sourceFile) + 1 + match.index);
924
+ const inLiteral = at === literal;
925
+ const position = positionOf(reader, sourceFile, at.getStart(sourceFile) + (inLiteral ? 1 + match.index : 0));
857
926
  if (!position) return [];
858
927
  return [{
859
928
  file,
860
929
  line: position.line,
861
930
  column: position.column,
862
931
  endLine: position.line,
863
- endColumn: position.column + className.length,
932
+ endColumn: position.column + (inLiteral ? className.length : at.getWidth(sourceFile)),
864
933
  severity: "error",
865
934
  code: "rafters(arbitrary-value)",
866
935
  message: `${className} is an arbitrary value`
867
936
  }];
868
937
  });
869
938
  }
870
- function bracketValues(reader, file, sourceFile) {
939
+ function bracketValues(reader, file, sourceFile, isOwnSource) {
871
940
  const { ts } = reader;
872
- const found = [];
941
+ const strings = /* @__PURE__ */ new Map();
942
+ const everyLiteral = isClassesFile(sourceFile.fileName);
943
+ if (everyLiteral && !isOwnSource(sourceFile.fileName)) return [];
873
944
  const visit = (node) => {
874
- if (ts.isJsxAttribute(node) && node.initializer) {
945
+ if (everyLiteral) {
946
+ if (ts.isStringLiteralLike(node)) strings.set(node, node);
947
+ } else if (ts.isJsxAttribute(node) && node.initializer) {
875
948
  const { name } = node;
876
949
  const attribute = ts.isJsxNamespacedName(name) ? `${name.namespace.text}:${name.name.text}` : name.text;
877
- if (CLASS_ATTRIBUTES.has(attribute)) for (const literal of classLiterals(ts, node.initializer)) found.push(...bracketsInLiteral(reader, file, sourceFile, literal));
878
- }
950
+ if (CLASS_ATTRIBUTES.has(attribute)) collectClassStrings(reader, sourceFile, isOwnSource, node.initializer, strings);
951
+ } else if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && node.expression.text === "classy") for (const argument of node.arguments) collectClassStrings(reader, sourceFile, isOwnSource, argument, strings);
879
952
  ts.forEachChild(node, visit);
880
953
  };
881
954
  visit(sourceFile);
882
- return found;
955
+ return [...strings].flatMap(([at, literal]) => bracketsInLiteral(reader, file, sourceFile, at, literal));
883
956
  }
884
957
  const FILL_WORD = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
958
+ const FILL_TOKEN = /^bg-fill-[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
885
959
  const FILL_ALPHA = /^(100|[1-9]?[0-9])$/;
886
960
  const AUTHORED_FILL = "a fill the designer authors, fill=\"bg-fill-<name>\"";
887
961
  const isFillStop = (stop) => {
@@ -901,24 +975,24 @@ async function loadSurfaces(root) {
901
975
  return { failure: error instanceof Error ? error.message : String(error) };
902
976
  }
903
977
  }
904
- function fillLiteral(ts, node) {
978
+ function valueLiteral(ts, node) {
905
979
  const { initializer } = node;
906
980
  if (!initializer) return void 0;
907
981
  if (ts.isStringLiteral(initializer)) return initializer;
908
982
  const inner = ts.isJsxExpression(initializer) ? initializer.expression : void 0;
909
983
  return inner && ts.isStringLiteralLike(inner) ? inner : void 0;
910
984
  }
911
- function fillAttributes({ ts }, sourceFile) {
985
+ function valueAttributes({ ts }, sourceFile) {
912
986
  const found = [];
913
987
  const visit = (node) => {
914
- if (ts.isJsxAttribute(node) && ts.isIdentifier(node.name) && node.name.text === "fill") found.push(node);
988
+ if (ts.isJsxAttribute(node) && ts.isIdentifier(node.name) && (node.name.text === "fill" || node.name.text === "surface")) found.push(node);
915
989
  ts.forEachChild(node, visit);
916
990
  };
917
991
  visit(sourceFile);
918
992
  return found;
919
993
  }
920
994
  async function lint(project, options) {
921
- const files = options.files ?? project.checker.getRootFileNames().filter((file) => file.endsWith(".tsx") || file.endsWith(".astro")).map((file) => relativeFile(project.root, file));
995
+ const files = options.files?.filter((file) => !file.endsWith(".ts") || isClassesFile(file)) ?? project.checker.getRootFileNames().filter((file) => file.endsWith(".tsx") || file.endsWith(".astro") || isClassesFile(file)).map((file) => relativeFile(project.root, file));
922
996
  const perFile = [];
923
997
  for (const file of files) perFile.push([file, await project.diagnostics(file)]);
924
998
  const program = project.program();
@@ -933,6 +1007,17 @@ async function lint(project, options) {
933
1007
  const real = realPath(file);
934
1008
  return folders.some((folder) => real.startsWith(folder));
935
1009
  };
1010
+ const scan = options.scan ?? "format";
1011
+ const projectRoot = realPath(project.root);
1012
+ const isOwnSource = (file) => {
1013
+ const [first, ...rest] = path.relative(projectRoot, realPath(file)).split(path.sep);
1014
+ return first !== ".." && first !== "node_modules" && !rest.includes("node_modules");
1015
+ };
1016
+ const isExempt = (sourceFile) => isUnderFolder(sourceFile.fileName) || qualifies(reader, sourceFile);
1017
+ const isCheckedUse = (declaredIn) => {
1018
+ if (scan === "system") return isUnderFolder(declaredIn.fileName);
1019
+ return isExempt(declaredIn) || scan === "all" && isOwnSource(declaredIn.fileName);
1020
+ };
936
1021
  const propsHelp = /* @__PURE__ */ new Map();
937
1022
  const reportedUse = (sourceFile, diagnostic) => {
938
1023
  const offset = programOffset(reader, sourceFile, diagnostic);
@@ -943,7 +1028,7 @@ async function lint(project, options) {
943
1028
  const declaration = component?.valueDeclaration ?? component?.declarations?.[0];
944
1029
  if (!element || !component || !declaration) return void 0;
945
1030
  const declaredIn = declaration.getSourceFile();
946
- if (!isUnderFolder(declaredIn.fileName)) return void 0;
1031
+ if (!isCheckedUse(declaredIn)) return void 0;
947
1032
  let help;
948
1033
  if (diagnostic.code === "ts(6385)") help = deprecatedText(reader, element, node.getText(sourceFile));
949
1034
  else {
@@ -966,15 +1051,44 @@ async function lint(project, options) {
966
1051
  if ("failure" in loaded) return `the project's tokens could not be loaded, so no replacement is named: ${loaded.failure}`;
967
1052
  return loaded.words.has(value) ? `surface="${value}"` : AUTHORED_FILL;
968
1053
  };
969
- const retiredFills = async (file, sourceFile) => {
1054
+ const fillFinding = async (value) => {
1055
+ if (value === "" || FILL_TOKEN.test(value)) return void 0;
1056
+ const form = retiredFillForm(value);
1057
+ if (!form) return {
1058
+ code: "rafters(invalid-fill)",
1059
+ message: `fill="${value}" is not exactly one bg-fill-* token`
1060
+ };
1061
+ return {
1062
+ code: "rafters(retired-fill)",
1063
+ message: `fill="${value}" is a retired fill value`,
1064
+ help: await replacement(value, form)
1065
+ };
1066
+ };
1067
+ const surfaceFinding = async (value) => {
1068
+ if (value === "") return void 0;
1069
+ surfaces ??= loadSurfaces(project.root);
1070
+ const loaded = await surfaces;
1071
+ if ("failure" in loaded) return {
1072
+ code: "rafters(unknown-surface)",
1073
+ message: `surface="${value}" could not be checked`,
1074
+ help: `the project's tokens could not be loaded, so no surface is named: ${loaded.failure}`
1075
+ };
1076
+ if (loaded.words.has(value)) return void 0;
1077
+ return {
1078
+ code: "rafters(unknown-surface)",
1079
+ message: `surface="${value}" is not a surface in the project's tokens`
1080
+ };
1081
+ };
1082
+ const badValues = async (file, sourceFile) => {
970
1083
  const flagged = [];
971
- for (const attribute of fillAttributes(reader, sourceFile)) {
972
- const literal = fillLiteral(ts, attribute);
973
- const form = literal && retiredFillForm(literal.text);
974
- if (!literal || !form) continue;
1084
+ for (const attribute of valueAttributes(reader, sourceFile)) {
1085
+ const literal = valueLiteral(ts, attribute);
1086
+ if (!literal) continue;
975
1087
  const component = resolveTag(reader, attribute.parent.parent);
976
1088
  const declaration = component?.valueDeclaration ?? component?.declarations?.[0];
977
- if (!declaration || !isUnderFolder(declaration.getSourceFile().fileName)) continue;
1089
+ if (!declaration || !isCheckedUse(declaration.getSourceFile())) continue;
1090
+ const finding = await (attribute.name.getText(sourceFile) === "fill" ? fillFinding(literal.text) : surfaceFinding(literal.text));
1091
+ if (!finding) continue;
978
1092
  const start = positionOf(reader, sourceFile, attribute.getStart(sourceFile));
979
1093
  const end = positionOf(reader, sourceFile, attribute.end);
980
1094
  if (!start || !end) continue;
@@ -985,9 +1099,7 @@ async function lint(project, options) {
985
1099
  endLine: end.line,
986
1100
  endColumn: end.column,
987
1101
  severity: "error",
988
- code: "rafters(retired-fill)",
989
- message: `fill="${literal.text}" is a retired fill value`,
990
- help: await replacement(literal.text, form)
1102
+ ...finding
991
1103
  });
992
1104
  }
993
1105
  return flagged;
@@ -1001,9 +1113,9 @@ async function lint(project, options) {
1001
1113
  const reported = reportedUse(sourceFile, diagnostic);
1002
1114
  if (reported) found.push(reported);
1003
1115
  }
1004
- if (!isUnderFolder(absolute)) {
1005
- found.push(...bracketValues(reader, file, sourceFile));
1006
- found.push(...await retiredFills(file, sourceFile));
1116
+ if (!isExempt(sourceFile)) {
1117
+ found.push(...bracketValues(reader, file, sourceFile, isOwnSource));
1118
+ found.push(...await badValues(file, sourceFile));
1007
1119
  }
1008
1120
  }
1009
1121
  return found.sort((a, b) => compareCodePoints(a.file, b.file) || a.line - b.line || a.column - b.column);
@@ -1021,4 +1133,4 @@ function report(diagnostics) {
1021
1133
  return lines.map((line) => `${line}\n`).join("");
1022
1134
  }
1023
1135
  //#endregion
1024
- export { ProjectError as a, resolveComponents as i, report as n, openProject as o, compareCodePoints as r, readConfig as s, lint as t };
1136
+ export { resolveComponents as a, readConfig as c, relativeFile as i, report as n, ProjectError as o, compareCodePoints as r, openProject as s, lint as t };
package/dist/worker.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { o as openProject, s as readConfig, t as lint } from "./lint-BabXVYQJ.mjs";
1
+ import { c as readConfig, s as openProject, t as lint } from "./lint-Bqu-nKvP.mjs";
2
2
  import path from "node:path";
3
3
  import { existsSync } from "node:fs";
4
4
  import { promisify } from "node:util";
@@ -30,7 +30,7 @@ process.stdout.write(JSON.stringify(await check(${JSON.stringify(root)}, { save:
30
30
  async function serve(root) {
31
31
  const config = await readConfig(root);
32
32
  if (!config.ok) throw new Error(messages(config.errors));
33
- const { componentFolders } = config;
33
+ const { componentFolders, scan } = config;
34
34
  let project = await openProject(root);
35
35
  const unsaved = /* @__PURE__ */ new Map();
36
36
  const outside = /* @__PURE__ */ new Set();
@@ -57,6 +57,7 @@ async function serve(root) {
57
57
  }
58
58
  return lint(project, {
59
59
  componentFolders,
60
+ scan,
60
61
  files: [file]
61
62
  });
62
63
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rafters/veneer",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Docs, rafters check and the composite compile for rafters projects",
5
5
  "license": "MIT",
6
6
  "repository": {