oxlint-plugin-arch 0.12.0 → 0.12.2

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.
@@ -3,9 +3,14 @@ import type { OxlintOverride } from 'oxlint';
3
3
  export declare class PresetError extends Error {
4
4
  }
5
5
  export declare function presetScopes(roots: string[], suffix?: string): string[];
6
+ export declare function presetServiceScopes(folders: Record<string, string>, sources: string[], suffix?: string): string[];
6
7
  export declare function presetOverride(files: string[], rules: PresetTypes.PresetRules, excludeFiles?: string[]): OxlintOverride;
7
8
  export declare function presetSeverity(rules: PresetTypes.PresetRules, level: PresetTypes.PresetLevel): PresetTypes.PresetRules;
8
9
  export declare function presetPackageName(root: string, directory: string): string | undefined;
9
10
  export declare function presetIntersect(glob: string, scope: string): string[];
10
11
  export declare function presetAliases(root: string, aliases: Record<string, string> | undefined): Record<string, string>;
11
12
  export declare function presetRuntime(project: PresetTypes.PresetProject, settings: Required<PresetTypes.PresetFrameworkOptions>, framework: PresetTypes.PresetFramework, rule: string): OxlintOverride[];
13
+ export declare function presetManifest(root: string, directory: string): PresetTypes.PresetManifest;
14
+ export declare function presetIsDirectory(path: string): boolean;
15
+ export declare function presetServicesFolder(root: string, source: string, configured?: string, fallback?: boolean): string;
16
+ export declare function presetIsFile(path: string): boolean;
@@ -4,6 +4,7 @@ export interface BoundariesOptions {
4
4
  backend: string[];
5
5
  packages: string | string[];
6
6
  roles?: string[];
7
+ services?: string[];
7
8
  portable?: boolean;
8
9
  backendPackages: string[];
9
10
  appPackages: string[];
@@ -153,6 +153,7 @@ export type PresetGroupName = keyof PresetGroups;
153
153
  export interface PresetFolder extends PresetGroups {
154
154
  severity?: PresetLevel;
155
155
  source?: string;
156
+ services?: string;
156
157
  rules?: PresetRules;
157
158
  }
158
159
  export type PresetFolders = Record<string, boolean | PresetFolder>;
@@ -224,6 +225,7 @@ export interface PresetUnit {
224
225
  kind: PresetKind;
225
226
  framework?: PresetFramework;
226
227
  source: string;
228
+ services: string;
227
229
  layout: Record<string, PresetLayoutMode>;
228
230
  }
229
231
  export interface PresetLayoutScope {
@@ -245,18 +247,23 @@ export interface PresetImportRestriction {
245
247
  group: string[];
246
248
  message: string;
247
249
  }
250
+ export type PresetImportTarget = string | null | PresetImportTarget[] | {
251
+ [condition: string]: PresetImportTarget;
252
+ };
248
253
  export interface PresetManifest {
249
254
  name?: string;
250
255
  dependencies?: Record<string, string>;
251
256
  devDependencies?: Record<string, string>;
257
+ peerDependencies?: Record<string, string>;
252
258
  workspaces?: string[] | {
253
259
  packages?: string[];
254
260
  };
255
- imports?: Record<string, unknown>;
261
+ imports?: Record<string, PresetImportTarget>;
256
262
  exports?: unknown;
257
263
  }
258
264
  export interface PresetProject {
259
265
  root: string;
266
+ serviceFolders: Record<string, string>;
260
267
  scopes: PresetScope[];
261
268
  units: PresetUnit[];
262
269
  suffixes: string[];
@@ -294,7 +301,9 @@ export interface PresetProject {
294
301
  publicEntrypoints: string[];
295
302
  baseImports: PresetImportRestriction[];
296
303
  css: Record<string, string>;
304
+ registries: string[];
297
305
  ignores: string[];
306
+ outputs: string[];
298
307
  }
299
308
  export type PresetBuilder<K extends PresetGroupName> = (project: PresetProject, settings: PresetGroupSettings<K>, scope: PresetScope) => OxlintOverride[];
300
309
  export type PresetBuilders = {
@@ -7,6 +7,7 @@ export interface SchemasElementOptions {
7
7
  export interface SchemasLocalOptions {
8
8
  packages: string[];
9
9
  namespaces: string[];
10
+ calls?: string[];
10
11
  allow?: string[];
11
12
  patterns?: string[];
12
13
  message?: string;
@@ -134,8 +134,12 @@ function optionsPatternsTest(patterns, value) {
134
134
  });
135
135
  }
136
136
  function optionsGlob(pattern) {
137
- const source = pattern.replaceAll(/[.+^$()|[\]\\]/g, "\\$&").replaceAll("?", "[^/]").replaceAll("**/", "\x00").replaceAll("**", "\x01").replaceAll("*", "[^/]*").replaceAll("\x00", "(?:.*/)?").replaceAll("\x01", ".*").replaceAll(/\{([^}]*)\}/g, (_, options) => `(?:${options.split(",").join("|")})`);
138
- return new RegExp(`^${source}$`);
137
+ const negated = [];
138
+ const source = pattern.replaceAll(/!\(([^()]*)\)/g, (_, options) => {
139
+ negated.push(options.split("|").map((option) => option.replaceAll(/[.+^$()|[\]\\*?{}]/g, "\\$&")).join("|"));
140
+ return `\x02${negated.length - 1}\x03`;
141
+ }).replaceAll(/[.+^$()|[\]\\]/g, "\\$&").replaceAll("?", "[^/]").replaceAll("**/", "\x00").replaceAll("**", "\x01").replaceAll("*", "[^/]*").replaceAll("\x00", "(?:.*/)?").replaceAll("\x01", ".*").replaceAll(/\{([^}]*)\}/g, (_, options) => `(?:${options.split(",").join("|")})`);
142
+ return new RegExp(`^${negated.reduce((text, names, index) => text.replace(`\x02${index}\x03`, `(?!(?:${names})(?:/|$))[^/]*`), source)}$`);
139
143
  }
140
144
  function optionsPatternLabel(pattern) {
141
145
  return pattern === undefined ? "" : [pattern].flat().filter((source) => source !== "").join(" | ");
@@ -1208,6 +1212,31 @@ var noRuntimeTypeofRule = defineRule8({
1208
1212
  // src/vendor/dillon-anti-slop/rules/no-shape-in-symbol-names.ts
1209
1213
  import { defineRule as defineRule9 } from "@oxlint/plugins";
1210
1214
  var FORBIDDEN_SYMBOL_NAME = "shape";
1215
+ function namesForeignApi(node) {
1216
+ const parent = node.parent;
1217
+ if (!parent) {
1218
+ return false;
1219
+ }
1220
+ if (parent.type === "MemberExpression") {
1221
+ return parent.property === node && !parent.computed;
1222
+ }
1223
+ if (parent.type === "TSQualifiedName") {
1224
+ return parent.right === node;
1225
+ }
1226
+ if (parent.type === "ImportSpecifier") {
1227
+ return parent.imported === node && parent.local !== node && "name" in node && parent.local.name !== node.name;
1228
+ }
1229
+ if (parent.type === "ExportSpecifier") {
1230
+ return parent.local === node && parent.exported !== node && parent.parent.type === "ExportNamedDeclaration" && parent.parent.source !== null;
1231
+ }
1232
+ if (parent.type === "JSXMemberExpression") {
1233
+ return parent.property === node;
1234
+ }
1235
+ if (parent.type === "JSXAttribute") {
1236
+ return parent.name === node;
1237
+ }
1238
+ return parent.type === "Property" && parent.key === node && !parent.computed && (parent.shorthand || parent.parent.type === "ObjectPattern");
1239
+ }
1211
1240
  var noForbiddenTermInSymbolNamesRule = defineRule9({
1212
1241
  meta: {
1213
1242
  type: "problem",
@@ -1220,7 +1249,7 @@ var noForbiddenTermInSymbolNamesRule = defineRule9({
1220
1249
  },
1221
1250
  createOnce(context) {
1222
1251
  const reportForbiddenSymbolName = (node) => {
1223
- if (!node.name.toLowerCase().includes(FORBIDDEN_SYMBOL_NAME)) {
1252
+ if (!node.name.toLowerCase().includes(FORBIDDEN_SYMBOL_NAME) || namesForeignApi(node)) {
1224
1253
  return;
1225
1254
  }
1226
1255
  context.report({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-arch",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "Configurable architecture rules for Oxlint JavaScript plugins.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,12 +26,12 @@
26
26
  ],
27
27
  "scripts": {
28
28
  "build": "rm -rf dist && bun build src/index.ts src/preset/preset.ts src/vendor/dillon-anti-slop/index.ts --root src --outdir dist --target node --format esm --packages external && tsc --project tsconfig.build.json",
29
- "test": "vitest run src",
29
+ "test": "vitest run tests",
30
30
  "check": "bun run build && bun run lint && bun run typecheck && bun run test && bun run lint:dead && bun run lint:dupes && bun run docs:check",
31
31
  "docs": "bun scripts/docs.ts",
32
32
  "docs:check": "bun scripts/docs.ts --check",
33
33
  "bench": "bun scripts/bench.ts",
34
- "lint": "oxlint -c oxlint.config.ts --disable-nested-config src examples scripts",
34
+ "lint": "oxlint -c oxlint.config.ts --disable-nested-config src tests examples scripts",
35
35
  "lint:dead": "fallow dead-code",
36
36
  "lint:dupes": "fallow dupes",
37
37
  "lint:slop": "scanr slop",
@@ -18,6 +18,11 @@ Local behavior fixes recognize `SAFETY:` comments on exported declarations and
18
18
  export-default assertions, while retaining statement boundaries for other
19
19
  assertions.
20
20
 
21
+ `no-shape-in-symbol-names` skips names that belong to another API: the
22
+ property of a non-computed member access (`schema.shape`), a renamed
23
+ destructured property or import, the right side of a qualified type name, and
24
+ the key of a shorthand property (its variable is still reported).
25
+
21
26
  Local option changes let `no-module-mocking` take `deny` and `allow` API
22
27
  patterns and `checkDestructured`, so the preset can also ban stubs such as
23
28
  `vi.spyOn`. With no options it reports the same calls as before.