@shivaedev/quality 0.7.3 → 0.8.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +103 -9
  3. package/biome/plugins/constant-names.grit +17 -0
  4. package/biome/plugins/effect-fn-spans.grit +13 -3
  5. package/biome/plugins/handler-names.grit +10 -0
  6. package/biome/plugins/schema-names.grit +13 -0
  7. package/biome/plugins/schema-struct-keys.grit +7 -0
  8. package/biome/plugins/service-layers.grit +13 -0
  9. package/biome/plugins/type-re-exports.grit +8 -0
  10. package/biome/preset.json +48 -1
  11. package/dist/imports/graph.d.ts.map +1 -1
  12. package/dist/imports/graph.js +9 -6
  13. package/dist/imports/graph.js.map +1 -1
  14. package/dist/imports/resolve.d.ts +1 -0
  15. package/dist/imports/resolve.d.ts.map +1 -1
  16. package/dist/imports/resolve.js +14 -0
  17. package/dist/imports/resolve.js.map +1 -1
  18. package/dist/naming/exportFits.d.ts +2 -0
  19. package/dist/naming/exportFits.d.ts.map +1 -0
  20. package/dist/naming/exportFits.js +20 -0
  21. package/dist/naming/exportFits.js.map +1 -0
  22. package/dist/naming/mainExport.d.ts +3 -0
  23. package/dist/naming/mainExport.d.ts.map +1 -0
  24. package/dist/naming/mainExport.js +10 -0
  25. package/dist/naming/mainExport.js.map +1 -0
  26. package/dist/naming/ownExports.d.ts +8 -0
  27. package/dist/naming/ownExports.d.ts.map +1 -0
  28. package/dist/naming/ownExports.js +78 -0
  29. package/dist/naming/ownExports.js.map +1 -0
  30. package/dist/naming/packageLayout.d.ts +8 -0
  31. package/dist/naming/packageLayout.d.ts.map +1 -0
  32. package/dist/naming/packageLayout.js +57 -0
  33. package/dist/naming/packageLayout.js.map +1 -0
  34. package/dist/naming/testName.d.ts +11 -0
  35. package/dist/naming/testName.d.ts.map +1 -0
  36. package/dist/naming/testName.js +13 -0
  37. package/dist/naming/testName.js.map +1 -0
  38. package/dist/naming/words.d.ts +8 -0
  39. package/dist/naming/words.d.ts.map +1 -0
  40. package/dist/naming/words.js +21 -0
  41. package/dist/naming/words.js.map +1 -0
  42. package/dist/rules/built-in.d.ts +13 -1
  43. package/dist/rules/built-in.d.ts.map +1 -1
  44. package/dist/rules/built-in.js +10 -0
  45. package/dist/rules/built-in.js.map +1 -1
  46. package/dist/rules/files/folderNames.d.ts +5 -0
  47. package/dist/rules/files/folderNames.d.ts.map +1 -0
  48. package/dist/rules/files/folderNames.js +74 -0
  49. package/dist/rules/files/folderNames.js.map +1 -0
  50. package/dist/rules/files/namedAfterExport.d.ts +4 -0
  51. package/dist/rules/files/namedAfterExport.d.ts.map +1 -0
  52. package/dist/rules/files/namedAfterExport.js +76 -0
  53. package/dist/rules/files/namedAfterExport.js.map +1 -0
  54. package/dist/rules/files/otherNames.d.ts +5 -0
  55. package/dist/rules/files/otherNames.d.ts.map +1 -0
  56. package/dist/rules/files/otherNames.js +99 -0
  57. package/dist/rules/files/otherNames.js.map +1 -0
  58. package/dist/rules/test-names/colocated.d.ts +4 -0
  59. package/dist/rules/test-names/colocated.d.ts.map +1 -0
  60. package/dist/rules/test-names/colocated.js +31 -0
  61. package/dist/rules/test-names/colocated.js.map +1 -0
  62. package/dist/rules/test-names/follow.d.ts +4 -0
  63. package/dist/rules/test-names/follow.d.ts.map +1 -0
  64. package/dist/rules/test-names/follow.js +66 -0
  65. package/dist/rules/test-names/follow.js.map +1 -0
  66. package/dist/rules/test-names/usesDom.d.ts +3 -0
  67. package/dist/rules/test-names/usesDom.d.ts.map +1 -0
  68. package/dist/rules/test-names/usesDom.js +18 -0
  69. package/dist/rules/test-names/usesDom.js.map +1 -0
  70. package/dist/vitest.d.ts +3 -1
  71. package/dist/vitest.d.ts.map +1 -1
  72. package/dist/vitest.js +11 -11
  73. package/dist/vitest.js.map +1 -1
  74. package/package.json +1 -1
  75. package/src/imports/graph.ts +11 -7
  76. package/src/imports/resolve.ts +18 -0
  77. package/src/naming/exportFits.ts +21 -0
  78. package/src/naming/mainExport.ts +11 -0
  79. package/src/naming/ownExports.ts +95 -0
  80. package/src/naming/packageLayout.ts +75 -0
  81. package/src/naming/testName.ts +25 -0
  82. package/src/naming/words.ts +28 -0
  83. package/src/rules/built-in.ts +10 -0
  84. package/src/rules/files/folderNames.ts +92 -0
  85. package/src/rules/files/namedAfterExport.ts +87 -0
  86. package/src/rules/files/otherNames.ts +118 -0
  87. package/src/rules/test-names/colocated.ts +34 -0
  88. package/src/rules/test-names/follow.ts +78 -0
  89. package/src/rules/test-names/usesDom.ts +22 -0
  90. package/src/vitest.ts +14 -11
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.1 - 2026-10-04
4
+
5
+ ### Changed
6
+
7
+ - `imports/resolvable` takes a `#` package import of a missing file as resolved when its `imports` entry in `package.json` points into a folder that `generated` names, as it already did for a relative import. A test can then import a generated client through its alias before the generator runs, and fences see the import as an edge to that path.
8
+
9
+ ## 0.8.0 - 2026-10-04
10
+
11
+ ### Added
12
+
13
+ - The Biome preset checks identifier names, every rule an error without an autofix: nothing renames code, and the message names the valid shapes. `useNamingConvention` asks for camelCase values and PascalCase types without an `I` prefix, spells acronyms as words (`HttpClient`, `userId`) through `strictCase`, allows type parameters `T`, `T` plus a PascalCase name (`TItem`) and Effect's `A`, `E` and `R`, and allows object keys and type properties in camelCase or PascalCase only, so a snake_case or CONSTANT_CASE key is a finding everywhere, also in a `Record`. `useConsistentMemberAccessibility` bans `private`, `protected` and `public` in favor of `#field`, and the preset adds `useReactNamingConvention` and `useComponentExportOnlyModules`. The README's new Naming section lists every shape.
14
+ - New GritQL plugins in the preset: `constant-names` (a module-level string or number constant is CONSTANT_CASE), `schema-names` (a schema is PascalCase), `schema-struct-keys` (a snake_case `Schema.Struct` field points to `Schema.encodeKeys`), `service-layers` (no exported `XLive` or `XLayer` Layer constant; the Layer is the service's static `layer`), `handler-names` (an `onX` prop gets a `handleX` function or a forwarded `onX` prop) and `type-re-exports` (no `export type … from`). `effect-fn-spans` also asks that the operation of an `Effect.fn` span equals the name the function is bound to, as in `const loadItem = Effect.fn("ItemStore.loadItem")`.
15
+ - The preset turns on `noExportedImports`, so no module re-exports anything, package entry files included. A repository that upgrades records its existing naming and re-export findings with `quality baseline write --rule biome`.
16
+ - `files/named-after-export` names a code file after its main export, with its folders as the prefix: `listItems` lives in `items/list.ts`, and `items/listItems.ts` is a finding. A file of several exports is a camelCase topic file, a file with a single constant is a finding, and a file a script runs is kebab-case.
17
+ - `files/folder-names` names a package folder after its package, a module folder after its main file and every other folder in kebab-case, or snake_case for the folders the `content` option lists. A PascalCase folder without its main file is a finding.
18
+ - `files/other-names` names documents, data, assets and GritQL files in kebab-case, a stylesheet that one component imports after that component, a Prisma schema in camelCase and content in snake_case. A repository that upgrades records its existing file and folder findings with `quality baseline write --rule files/named-after-export --rule files/folder-names --rule files/other-names`.
19
+ - `tests/follow` names a test after what it covers: `<file>[.<environment>].test.ts` beside its file, or `<behaviour>[.<environment>].spec.ts` in camelCase for a test of its folder as a whole. The environment is at most one of `dom`, `slow` and `typecheck`; any other suffix, `.postgres` and `.integration` included, is a finding, and a test that uses the DOM without `.dom` is one too.
20
+ - `tests/colocated` reports a test in a `test`, `tests`, `__tests__` or `spec` folder: a test sits beside the code it covers. Both test rules skip the folders their `suites` option lists. A repository that upgrades records its existing test findings with `quality baseline write --rule tests/follow --rule tests/colocated`.
21
+
22
+ ### Changed
23
+
24
+ - `testProjects()` runs `.spec` files beside `.test` files, `<behaviour>.dom.spec.tsx` in the DOM project and `<behaviour>.slow.spec.ts` in the slow project, and leaves out `.typecheck.spec` files. Its new `exclude` option keeps a folder that another runner owns, such as a Playwright suite, out of every project.
25
+
3
26
  ## 0.7.3 - 2026-10-04
4
27
 
5
28
  ### Changed
package/README.md CHANGED
@@ -210,7 +210,7 @@ Each import resolves the way the compiler resolves it, with the options of the n
210
210
  - An import of a stylesheet, an image or JSON resolves to the file, and only when the file exists, whatever declaration describes it. A Node builtin resolves.
211
211
  - A runtime import must resolve to code: a declaration file (`.d.ts`, `.d.mts`, `.d.cts`, or an asset declaration such as `.d.css.ts`) satisfies only `import type` and `export type`, however the import reaches it, so a package that has only its `@types` package installed, or an `exports` entry that points at a declaration, is reported.
212
212
  - A bare import resolves when a declaration file of the importer's tsconfig project declares the module in a script (`declare module "virtual:*"`). A relative import always needs a real file, `declare module "*"` and patterns with more than one `*` never count, and a `declare module` inside a module is an augmentation, which declares nothing new.
213
- - A relative import of a missing file resolves only inside a folder that `generated` names, such as a client a generator writes before the tests run. Each folder must be ignored by git, or at least every file an import names in it must be, hold no file git tracks but a `.gitkeep` or `.keep` placeholder, lie outside `node_modules` and hold a file that an import names. The import stays an edge to its path, so fences apply to it before the file exists.
213
+ - A relative import or a `#` package import of a missing file resolves only inside a folder that `generated` names, such as a client a generator writes before the tests run. A `#` import lands where its `imports` entry in `package.json` points once the file exists. Each folder must be ignored by git, or at least every file an import names in it must be, hold no file git tracks but a `.gitkeep` or `.keep` placeholder, lie outside `node_modules` and hold a file that an import names. The import stays an edge to its path, so fences apply to it before the file exists.
214
214
  - A module that resolves into `node_modules` or outside the root is external, and its package is the one it resolves into, whatever alias the import uses. A `@types` package counts as the package it describes: `@types/hast` is `hast`, `@types/scope__name` is `@scope/name`.
215
215
 
216
216
  ```ts
@@ -384,20 +384,112 @@ quality baseline migrate [--config <file>] [--from <file>]
384
384
  The preset sets:
385
385
 
386
386
  - **Formatting:** tabs, a line width of 150, double quotes, semicolons, trailing commas and operators at the start of a wrapped line.
387
- - **Lint:** every rule Biome recommends, at `error`, and a list of stricter rules on top, among them `noUnsafeTypeAssertion`, `useBlockStatements`, `useNumericSeparators`, `useUnicodeRegex`, `useLiteralKeys`, `noFloatingPromises`, `useExhaustiveDependencies`, `it` for every test, function declarations over function expressions, interfaces for object types, a cognitive complexity limit of 15, no nested ternaries, no barrel files and no `export *`.
387
+ - **Lint:** every rule Biome recommends, at `error`, and a list of stricter rules on top, among them `noUnsafeTypeAssertion`, `useBlockStatements`, `useNumericSeparators`, `useUnicodeRegex`, `useLiteralKeys`, `noFloatingPromises`, `useExhaustiveDependencies`, `it` for every test, function declarations over function expressions, interfaces for object types, a cognitive complexity limit of 15, no nested ternaries, and the naming rules under [Naming](#naming).
388
388
  - **Imports:** organized in five groups: Node and Bun builtins, packages, `@shivaedev/*` packages, aliases and relative paths. Biome counts as an alias a specifier that starts with `#`, `@/`, `~`, `$` or `%`; a tsconfig path such as `@app/*` sorts with the packages, and Biome's `noUndeclaredDependencies` takes it for one, so name aliases in a form Biome recognizes.
389
389
  - **Assist:** organized imports and sorted keys, attributes, enum members, interface members and properties. Keys are sorted in JSON and in object literals alike, but only reported: `quality fix` leaves the order to the author. `package.json` is left out, because `manifests/sorted` gives it the order npm users expect.
390
- - **Plugins:** GritQL rules that ban ambient time, randomness, `console` and `process.env` for Effect's services, and that ask `Effect.fn` for a literal span name shaped `Owner.operation`. They load from `./node_modules/@shivaedev/quality/biome/plugins`, so the package must be installed at the repository root.
390
+ - **Plugins:** GritQL rules that ban ambient time, randomness, `console` and `process.env` for Effect's services, and the naming plugins under [Naming](#naming). They load from `./node_modules/@shivaedev/quality/biome/plugins`, so the package must be installed at the repository root.
391
391
  - Files ignored by git are skipped.
392
392
 
393
393
  The preset turns off `noUnusedVariables` and `noUnusedFunctionParameters`, because the tsconfig presets report them through TypeScript, and allows default exports in `*.config.*` files, which tools load through the default export. It also turns off `noProcessGlobal`, `useJsonImportAttributes`, `noMisusedPromises`, `useExhaustiveSwitchCases`, `useSortedClasses`, `noDelete`, `useConsistentArrayType`, `useConsistentCurlyBraces`, `noEqualsToNull` and `noSkippedTests`, because `quality fix` applies every lint fix and their fixes changed behavior or did not terminate on real code. It declares these weakenings in its `declarations.json`, so `suppressions/biome-overrides` takes them as declared. Every other weakening a repository adds is an override it declares with a reason.
394
394
 
395
- An autofix applies only a change that removes no decision; a fix that can change behavior or delete something written on purpose reports only, and the author decides. The preset keeps `noAccessKey`, `noAriaHiddenOnFocusable`, `noAutofocus`, `noInteractiveElementToNoninteractiveRole`, `noNoninteractiveElementToInteractiveRole`, `noNoninteractiveTabindex`, `noRedundantRoles`, `useValidAriaProps`, `useValidAriaRole`, `noImportantStyles`, `noConstAssign`, `noUnusedPrivateClassMembers`, `useExhaustiveDependencies`, `noFloatingPromises`, `useRegexpTest`, `useUnicodeRegex`, `noNonNullAssertion`, `useAtIndex` and `noParametersOnlyUsedInRecursion` at `error` with their fixes off, and `quality fix` skips `noDuplicateObjectKeys` and `useSortedKeys`, whose fixes Biome's config cannot turn off.
395
+ An autofix applies only a change that removes no decision; a fix that can change behavior or delete something written on purpose reports only, and the author decides. The preset keeps `noAccessKey`, `noAriaHiddenOnFocusable`, `noAutofocus`, `noInteractiveElementToNoninteractiveRole`, `noNoninteractiveElementToInteractiveRole`, `noNoninteractiveTabindex`, `noRedundantRoles`, `useValidAriaProps`, `useValidAriaRole`, `noImportantStyles`, `noConstAssign`, `noUnusedPrivateClassMembers`, `useExhaustiveDependencies`, `noFloatingPromises`, `useRegexpTest`, `useUnicodeRegex`, `noNonNullAssertion`, `useAtIndex`, `noParametersOnlyUsedInRecursion` and `useNamingConvention` at `error` with their fixes off, and `quality fix` skips `noDuplicateObjectKeys` and `useSortedKeys`, whose fixes Biome's config cannot turn off.
396
396
 
397
397
  The `biome` rule runs `biome check` with the repository's config and reports each finding as `biome/<category>`, such as `biome/lint/style/useBlockStatements`, `biome/assist/source/useSortedKeys`, `biome/format` or `biome/plugin`, so Biome's findings go through the baseline like any other rule's. `quality baseline write --rule biome` takes in every Biome category at once. A finding below `error`, such as a rule a repository declared at `warn`, is not reported. The rule also asks for a root `biome.json` or `biome.jsonc` that extends the preset, and it takes no registry exceptions. A Biome config that Biome cannot load stops the run with Biome's message.
398
398
 
399
399
  `quality fix` sorts every `package.json`, then runs `biome check --write --unsafe`, which applies Biome's lint fixes, unsafe ones included, its assist actions, such as organized imports, and its formatting, except the fixes that report only. It then runs Biome's formatter once more, because a lint fix can leave code unformatted. One fix can make room for another, so it repeats both passes until a round rewrites nothing, at most 5 rounds; when files still change in the fifth round, it names them and exits 2. An unsafe fix can change behavior, such as `==` becoming `===`, so review what it changed. An editor that runs Biome on save uses the same version when it resolves Biome from the root `node_modules`, so a repository that wants that installs `@biomejs/biome` at the version this package pins.
400
400
 
401
+ ## Naming
402
+
403
+ A name says what a thing is, and the same kind of thing is named the same way everywhere. Every naming rule is an error without an autofix: nothing renames code or adds a `_` prefix. The message says what is wrong and which shapes are valid, and the author picks the name. Unused variables and parameters stay TypeScript errors; remove them instead of prefixing them.
404
+
405
+ ### Identifiers
406
+
407
+ | What | Valid shape | Checked by |
408
+ | --- | --- | --- |
409
+ | Variables, functions and parameters | camelCase: `itemCount`, `loadItem`. A component or a class is PascalCase. | `useNamingConvention` |
410
+ | Acronyms | Spelled as a word: `HttpClient`, `userId`, `parseUrl`. Never `HTTPClient`, `userID` or `parseURL`. | `useNamingConvention` with `strictCase` |
411
+ | Types, interfaces, classes and enums | PascalCase, without an `I` prefix: `Item`, not `IItem`. | `useNamingConvention` |
412
+ | Type parameters | `T`, or `T` followed by a PascalCase name: `TItem`, `TResult`. Effect's positional `A`, `E` and `R` are valid as they are. | `useNamingConvention` |
413
+ | Module-level constants | A string or number literal at module level is CONSTANT_CASE: `const MAX_ITEMS = 50`. A constant inside a function is camelCase. | `constant-names` plugin, `useNamingConvention` |
414
+ | Object keys and type properties | camelCase or PascalCase, after any leading `_` or `$` (`_tag`, `$transaction`). snake_case and CONSTANT_CASE keys are never valid, also for outside data and in a `Record`. | `useNamingConvention` |
415
+ | Schemas | PascalCase and named like their type: `const Item = Schema.Struct(...)` with `type Item = typeof Item.Type`. | `schema-names` plugin |
416
+ | `Schema.Struct` fields | camelCase. Outside data keeps its keys only at the edge: `Schema.Struct({ createdAt: Schema.String }).pipe(Schema.encodeKeys({ createdAt: "created_at" }))`. | `schema-struct-keys` plugin, `useNamingConvention` |
417
+ | `Effect.fn` spans | `"Owner.operation"`, where the owner is the service or module and the operation is the name the function is bound to: `const loadItem = Effect.fn("ItemStore.loadItem")`, and `loadItem: Effect.fn("ItemStore.loadItem")` in an object. | `effect-fn-spans` plugin |
418
+ | Service Layers | A static `layer` on the service, read as `ItemStore.layer`. No exported `ItemStoreLive` or `ItemStoreLayer` constant. A Layer that wires an application together stays unexported. | `service-layers` plugin |
419
+ | Private members | A `#field`. No `private`, `protected` or `public` modifier. | `useConsistentMemberAccessibility` |
420
+ | React | A function passed to an `onX` prop is `handleX`, or an `onX` prop forwarded as it is. A context is `ThemeContext`, a ref `inputRef`, an id `fieldId`. A module that exports a component exports only components. | `handler-names` plugin, `useReactNamingConvention`, `useComponentExportOnlyModules` |
421
+ | Booleans | A question: `isOpen`, `hasSave`, `canRetry`, `shouldFlush`. A name the DOM or React gives, such as `open` or `disabled`, stays. This is a convention only; no rule checks it. | Review |
422
+
423
+ ### Re-exports
424
+
425
+ No file re-exports, package entry files included: every module is imported from the file that defines it. `noBarrelFile` reports `export { … } from`, `noReExportAll` reports `export *`, the `type-re-exports` plugin reports `export type … from`, and `noExportedImports` reports an import that is exported again. Its message suggests `export … from`, which is a re-export as well: import the name where it is used instead.
426
+
427
+ The plugins report under the one Biome category `plugin`, so their findings share the baseline rule `biome/plugin`.
428
+
429
+ ### Files
430
+
431
+ `files/named-after-export` names a code file after its main export, and the folders above it are the prefix. The export takes the words of the file name, in order, and may add words of its folders around them, in any order and in singular or plural. Folders count from the package root, without a leading `src`; the package name does not count. The file's first letter follows the export's case.
432
+
433
+ | File | Exports | Valid |
434
+ | --- | --- | --- |
435
+ | `routers/items/list.ts` | `listItems` or `itemList` | Yes |
436
+ | `routers/items/Create.ts` | `CreateItemRouter` | Yes |
437
+ | `item/Panel.tsx` or `ItemPanel.tsx` | `ItemPanel`, with `ItemPanelProps` beside it | Yes |
438
+ | `Panel/Panel.tsx` | `Panel`: the main file of a module folder repeats the folder | Yes |
439
+ | `limits.ts` | `MAX_ITEMS` and `MAX_DEPTH`: a topic file of several exports is camelCase | Yes |
440
+ | `setupTests.ts` | Nothing, so it is camelCase | Yes |
441
+ | `script/build-docs.ts` | Run by a `package.json` script or `bin`, or starts with `#!`, so it is kebab-case | Yes |
442
+ | `order.ts` | `type Order` | No: the file's case follows the export, so it is `Order.ts` |
443
+ | `maxItems.ts` | `MAX_ITEMS` alone | No: constants live in a topic file with related constants |
444
+ | `items/listItems.ts` | `listItems` | No: the folder is the prefix, so it is `items/list.ts` |
445
+
446
+ Test files are left to the test rules. The `toolOwned` option lists `.gitignore` patterns of files whose names a tool fixes, `*.config.*` and declaration files by default.
447
+
448
+ ### Folders
449
+
450
+ `files/folder-names` checks every folder above a checked file.
451
+
452
+ - A module folder takes the name of its main file, inside it or beside it: `Panel/` with `Panel/Panel.tsx`, or `Dialog/` beside `Dialog.tsx`. A PascalCase folder without that file is a finding.
453
+ - A package folder is its package name without the scope, so `@acme/ui-kit` lives in `ui-kit/`.
454
+ - A folder that only groups files is kebab-case: `test-support/`, `.github/`.
455
+ - A folder the `content` option lists is snake_case: `forest_path/`.
456
+
457
+ The `toolOwned` option lists folders a tool names, `generated/` and `migrations/` by default.
458
+
459
+ ### Other files
460
+
461
+ `files/other-names` names the files that are not code.
462
+
463
+ - Markdown, JSON, GritQL, images, fonts and SVG are kebab-case, with optional dotted parts: `release-notes.md`, `icons.sprite.svg`. Conventional upper-case names stay: `README.md`, `CHANGELOG.md`, `LICENSE`, `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md`, `SECURITY.md` and `SKILL.md`.
464
+ - A stylesheet that one component imports is named after it: `ItemPanel.css` beside `ItemPanel.tsx`. A shared stylesheet is kebab-case: `form-controls.css`.
465
+ - A Prisma schema is camelCase: `schema.prisma`.
466
+ - A file the `content` option lists is snake_case: `forest_path.json`.
467
+
468
+ The `toolOwned` option lists files a tool names: dotfiles, `package.json`, `tsconfig*.json`, `biome.json`, `*.config.*`, `migrations/` and `generated/` by default.
469
+
470
+ ### Tests
471
+
472
+ A test sits beside the code it covers, and its name says what it covers and where it runs.
473
+
474
+ | File | Covers | Valid |
475
+ | --- | --- | --- |
476
+ | `cart/cart.test.ts` | `cart/cart.ts` | Yes |
477
+ | `cart/cart.typecheck.test.ts` | The types of `cart/cart.ts`, checked by the compiler | Yes |
478
+ | `cart/Basket.dom.test.tsx` | `cart/Basket.tsx`, in a DOM | Yes |
479
+ | `cart/checkoutFlow.spec.ts` | A behaviour of the `cart/` folder as a whole, such as a flow across several files | Yes |
480
+ | `cart/checkoutFlow.dom.spec.tsx` | The same, in a DOM | Yes |
481
+ | `cart/totals.test.ts` | No `cart/totals.ts` beside it | No: a `.test` follows a file, and a test of the folder is a `.spec` |
482
+ | `cart/cart.spec.ts` | | No: a `.spec` names a behaviour, so it may not share a stem with a file beside it |
483
+ | `cart/cart.hydration.test.ts` | | No: an aspect gets its own file in the module's folder, or a `.spec` |
484
+ | `cart/cart.postgres.test.ts` | | No: a database or a running app comes from the app's test fixture, not a file name |
485
+ | `test/cart.test.ts` | | No: a test folder mirrors the source tree; the test sits beside `cart.ts` |
486
+
487
+ `tests/follow` checks the name: `<file>[.<environment>].test.ts` beside its file, or `<behaviour>[.<environment>].spec.ts` in camelCase in the folder it covers. The environment is at most one of `dom`, `slow` and `typecheck`, the ones the [Vitest projects](#vitest-projects) run, and a test that imports `@testing-library/*` or reads `document` or `window` is a `.dom` test.
488
+
489
+ `tests/colocated` checks the place: a test in a `test`, `tests`, `__tests__` or `spec` folder is a finding.
490
+
491
+ Both rules take a `suites` option, `.gitignore` patterns of folders that hold tests with their own layout, such as tests across several packages or a Playwright suite, whose `.spec.ts` files mean something else. The rules skip those folders.
492
+
401
493
  ## Vitest projects
402
494
 
403
495
  `@shivaedev/quality/vitest` sets up the tests of a package by file name, so no test file sets its environment with a pragma. It needs `vitest`, and `happy-dom` for DOM tests.
@@ -412,11 +504,13 @@ export default defineConfig({ test: testProjects() });
412
504
 
413
505
  | Project | Files | Environment | Runs |
414
506
  | --- | --- | --- | --- |
415
- | `unit` | `*.test.ts` and the other test files | Node | By default |
416
- | `dom` | `*.dom.test.ts`, `*.dom.test.tsx` | happy-dom | By default |
417
- | `slow` | `*.slow.test.ts`, `*.slow.test.tsx` | Node | Only with `vitest run --project slow` |
507
+ | `unit` | `*.test.ts`, `*.spec.ts` and the other test and spec files | Node | By default |
508
+ | `dom` | `*.dom.test.tsx`, `*.dom.spec.tsx` and the other `.dom` files | happy-dom | By default |
509
+ | `slow` | `*.slow.test.ts`, `*.slow.spec.ts` and the other `.slow` files | Node | Only with `vitest run --project slow` |
510
+
511
+ Type tests (`*.typecheck.test.ts`, `*.typecheck.spec.ts` and `typecheck.test.ts`) are in no project: the compiler checks them. A test that is too slow for every run goes into the slow project instead of being skipped.
418
512
 
419
- Type tests (`*.typecheck.test.ts` and `typecheck.test.ts`) are in no project: the compiler checks them. A test that is too slow for every run goes into the slow project instead of being skipped.
513
+ A folder that another runner owns, such as a Playwright suite of `.spec.ts` files, is left out with `testProjects({ exclude: ["e2e/**"] })`; the globs are added to every project's `exclude`.
420
514
 
421
515
  ## tsconfig presets
422
516
 
@@ -461,4 +555,4 @@ A package that type-checks its tests with one config and builds `src` with anoth
461
555
 
462
556
  ## Validation
463
557
 
464
- `pnpm ready` checks formatting, TypeScript 7, the rules, the import graph against seeded repositories and the fence policy against its examples, config, discovery, registry, baseline and report behavior, the command line against seeded repositories and git histories, the Biome preset against every rule Biome recommends and against its declarations, the `biome` and `manifests/sorted` rules and `quality fix` against seeded repositories, the Vitest projects against a seeded repository that Vitest runs, an installed tarball consumer that type-checks a config and runs the `quality` bin through a baseline that takes in the preset's lint and plugin findings, and installed consumers that extend each tsconfig preset, type-check a fixture with an expected error for each check the base turns on, and run the package preset's build output.
558
+ `pnpm ready` checks formatting, TypeScript 7, the rules, the import graph against seeded repositories and the fence policy against its examples, config, discovery, registry, baseline and report behavior, the command line against seeded repositories and git histories, the Biome preset against every rule Biome recommends and against its declarations, its naming rules and plugins against seeded files that break and keep each one, the file, folder, other-file and test naming rules against seeded trees, the `biome` and `manifests/sorted` rules and `quality fix` against seeded repositories, the Vitest projects against a seeded repository that Vitest runs, an installed tarball consumer that type-checks a config and runs the `quality` bin through a baseline that takes in the preset's lint and plugin findings, and installed consumers that extend each tsconfig preset, type-check a fixture with an expected error for each check the base turns on, and run the package preset's build output.
@@ -0,0 +1,17 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ `const $name = $value` as $declaration where {
5
+ $value <: or {
6
+ JsNumberLiteralExpression(),
7
+ JsStringLiteralExpression()
8
+ },
9
+ ! $declaration <: within or {
10
+ JsFunctionBody(),
11
+ JsArrowFunctionExpression(),
12
+ JsClassDeclaration(),
13
+ JsClassExpression()
14
+ } ,
15
+ ! $name <: r"[A-Z][A-Z0-9_]*",
16
+ register_diagnostic(span=$name, message="A module-level constant holding a string or number literal is CONSTANT_CASE, such as MAX_ITEMS or DEFAULT_PORT.")
17
+ }
@@ -1,7 +1,17 @@
1
1
  engine biome(1.0)
2
2
  language js(typescript, jsx)
3
3
 
4
- `Effect.fn($name)` as $match where {
5
- ! $name <: r"^[\"'][A-Z][A-Za-z0-9]*\.[a-z][A-Za-z0-9]*[\"']$",
6
- register_diagnostic(span=$match, message="Effect.fn takes a literal span name shaped PascalCaseOwner.lowerCamelCaseOperation, such as \"Transact.invalidateOnCommit\".")
4
+ or {
5
+ `Effect.fn($name)` as $match where {
6
+ ! $name <: r"^[\"'][A-Z][A-Za-z0-9]*\.[a-z][A-Za-z0-9]*[\"']$",
7
+ register_diagnostic(span=$match, message="Effect.fn takes a literal span name shaped PascalCaseOwner.lowerCamelCaseOperation, such as 'Transact.invalidateOnCommit'.")
8
+ },
9
+ or {
10
+ `const $binding = Effect.fn($span)($...)`,
11
+ JsPropertyObjectMember(name=$binding, value=`Effect.fn($span)($...)`)
12
+ } where {
13
+ $span <: r"[\"']([A-Z][A-Za-z0-9]*)\.([a-z][A-Za-z0-9]*)[\"']"($owner, $operation),
14
+ ! $operation <: $binding,
15
+ register_diagnostic(span=$span, message="The operation in an Effect.fn span is the name the function is bound to: const loadItem = Effect.fn('ItemStore.loadItem'). Rename the operation or the binding so they match.")
16
+ }
7
17
  }
@@ -0,0 +1,10 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ JsxAttribute(name=$attribute, initializer=JsxAttributeInitializerClause(value=JsxExpressionAttributeValue(expression=$handler))) where {
5
+ $attribute <: r"on[A-Z][A-Za-z0-9]*",
6
+ $handler <: JsIdentifierExpression(),
7
+ ! $handler <: r"handle[A-Z][A-Za-z0-9]*",
8
+ ! $handler <: r"on[A-Z][A-Za-z0-9]*",
9
+ register_diagnostic(span=$handler, message="A function passed to an onX prop is named handleX, such as onClick={handleClick}, or is an onX prop forwarded as it is.")
10
+ }
@@ -0,0 +1,13 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ `const $name = $init` where {
5
+ $init <: or {
6
+ `Schema.$member($...)`,
7
+ `Schema.$member($...).pipe($...)`,
8
+ `Schema.$member`
9
+ },
10
+ ! $member <: r"decode[A-Za-z]*|encode[A-Za-z]*|is|asserts|validate[A-Za-z]*|to[A-Z][A-Za-z]*|make[A-Za-z]*|format[A-Za-z]*",
11
+ ! $name <: r"[A-Z][A-Za-z0-9]*",
12
+ register_diagnostic(span=$name, message="A schema is PascalCase and shares its name with its type: const Item = Schema.Struct(...), type Item = typeof Item.Type.")
13
+ }
@@ -0,0 +1,7 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ `Schema.Struct($fields)` where {
5
+ $fields <: contains JsPropertyObjectMember(name=$key) where { $key <: r"[\"']?[_$]*[A-Za-z0-9]+_[A-Za-z0-9_]*[\"']?" },
6
+ register_diagnostic(span=$key, message="A Schema.Struct field is camelCase even when the outside data is not: name it createdAt and map the outside key with Schema.encodeKeys({ createdAt: 'created_at' }).")
7
+ }
@@ -0,0 +1,13 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ `export const $name = $init` where {
5
+ $init <: or {
6
+ `Layer.$member`,
7
+ `Layer.$member($...)`,
8
+ `Layer.$member.pipe($...)`,
9
+ `Layer.$member($...).pipe($...)`
10
+ },
11
+ $name <: r"[A-Za-z0-9]*Live|[A-Za-z0-9]*Layer",
12
+ register_diagnostic(span=$name, message="A service's Layer is a static member of the service, read as ItemStore.layer, not an exported ItemStoreLive or ItemStoreLayer constant.")
13
+ }
@@ -0,0 +1,8 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ or {
5
+ `export type { $names } from $source` as $match,
6
+ `export type * from $source` as $match,
7
+ `export type * as $namespace from $source` as $match
8
+ } where { register_diagnostic(span=$match, message="A module never re-exports, types included. Import the type from the module that defines it.") }
package/biome/preset.json CHANGED
@@ -351,6 +351,7 @@
351
351
  "useNamedCaptureGroup": "error",
352
352
  "useNamedLayer": "error",
353
353
  "useReactAsyncServerFunction": "error",
354
+ "useReactNamingConvention": "error",
354
355
  "useReduceTypeParameter": "error",
355
356
  "useRegexpExec": "error",
356
357
  "useRegexpTest": { "fix": "none", "level": "error" },
@@ -389,6 +390,7 @@
389
390
  "noDefaultExport": "error",
390
391
  "noDescendingSpecificity": "error",
391
392
  "noDoneCallback": "error",
393
+ "noExportedImports": "error",
392
394
  "noIncrementDecrement": "error",
393
395
  "noInferrableTypes": "error",
394
396
  "noMultiAssign": "error",
@@ -409,6 +411,7 @@
409
411
  "useBlockStatements": "error",
410
412
  "useCollapsedElseIf": "error",
411
413
  "useCollapsedIf": "error",
414
+ "useComponentExportOnlyModules": "error",
412
415
  "useConsistentArrayType": {
413
416
  "level": "off",
414
417
  "options": {
@@ -419,7 +422,12 @@
419
422
  "useConsistentBuiltinInstantiation": "error",
420
423
  "useConsistentCurlyBraces": "off",
421
424
  "useConsistentEnumValueType": "error",
422
- "useConsistentMemberAccessibility": "error",
425
+ "useConsistentMemberAccessibility": {
426
+ "level": "error",
427
+ "options": {
428
+ "accessibility": "none"
429
+ }
430
+ },
423
431
  "useConsistentMethodSignatures": {
424
432
  "level": "error",
425
433
  "options": {
@@ -446,6 +454,21 @@
446
454
  "useGroupedAccessorPairs": "error",
447
455
  "useImportType": "error",
448
456
  "useLiteralEnumMembers": "error",
457
+ "useNamingConvention": {
458
+ "fix": "none",
459
+ "level": "error",
460
+ "options": {
461
+ "conventions": [
462
+ { "formats": ["PascalCase"], "match": "(T|A|E|R)|T([A-Z][A-Za-z0-9]*)", "selector": { "kind": "typeParameter" } },
463
+ { "formats": ["PascalCase"], "match": "([A-HJ-Z][A-Za-z0-9]*|I[a-z0-9][A-Za-z0-9]*|I)", "selector": { "kind": "typeLike" } },
464
+ { "formats": ["camelCase", "PascalCase"], "selector": { "kind": "function" } },
465
+ { "formats": ["camelCase", "PascalCase"], "match": "[_$]*(.+)", "selector": { "kind": "objectLiteralProperty" } },
466
+ { "formats": ["camelCase", "PascalCase"], "match": "[_$]*(.+)", "selector": { "kind": "typeProperty" } }
467
+ ],
468
+ "requireAscii": true,
469
+ "strictCase": true
470
+ }
471
+ },
449
472
  "useNodeAssertStrict": "error",
450
473
  "useNodejsImportProtocol": "error",
451
474
  "useNumberNamespace": "error",
@@ -609,6 +632,30 @@
609
632
  {
610
633
  "includes": ["**/*.ts", "**/*.tsx", "!**/*.d.ts"],
611
634
  "path": "./node_modules/@shivaedev/quality/biome/plugins/effect-fn-spans.grit"
635
+ },
636
+ {
637
+ "includes": ["**/*.ts", "**/*.tsx", "!**/*.d.ts"],
638
+ "path": "./node_modules/@shivaedev/quality/biome/plugins/constant-names.grit"
639
+ },
640
+ {
641
+ "includes": ["**/*.ts", "**/*.tsx", "!**/*.d.ts"],
642
+ "path": "./node_modules/@shivaedev/quality/biome/plugins/handler-names.grit"
643
+ },
644
+ {
645
+ "includes": ["**/*.ts", "**/*.tsx", "!**/*.d.ts"],
646
+ "path": "./node_modules/@shivaedev/quality/biome/plugins/schema-names.grit"
647
+ },
648
+ {
649
+ "includes": ["**/*.ts", "**/*.tsx", "!**/*.d.ts"],
650
+ "path": "./node_modules/@shivaedev/quality/biome/plugins/schema-struct-keys.grit"
651
+ },
652
+ {
653
+ "includes": ["**/*.ts", "**/*.tsx", "!**/*.d.ts"],
654
+ "path": "./node_modules/@shivaedev/quality/biome/plugins/service-layers.grit"
655
+ },
656
+ {
657
+ "includes": ["**/*.ts", "**/*.tsx", "!**/*.d.ts"],
658
+ "path": "./node_modules/@shivaedev/quality/biome/plugins/type-re-exports.grit"
612
659
  }
613
660
  ],
614
661
  "vcs": {
@@ -1 +1 @@
1
- {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/imports/graph.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,UAAU,CAAC;AAGvD,OAAO,EAAE,KAAK,UAAU,EAAiC,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAE,KAAK,QAAQ,EAAoC,MAAM,cAAc,CAAC;AAC/E,OAAO,EAAE,KAAK,gBAAgB,EAAqB,MAAM,gBAAgB,CAAC;AAE1E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjG,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACjD;AAkDD,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAIpE"}
1
+ {"version":3,"file":"graph.d.ts","sourceRoot":"","sources":["../../src/imports/graph.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAc,MAAM,UAAU,CAAC;AAGvD,OAAO,EAAE,KAAK,UAAU,EAAiC,MAAM,cAAc,CAAC;AAE9E,OAAO,EAAE,KAAK,QAAQ,EAAoD,MAAM,cAAc,CAAC;AAC/F,OAAO,EAAE,KAAK,gBAAgB,EAAqB,MAAM,gBAAgB,CAAC;AAE1E,MAAM,WAAW,UAAU;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjG,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IACtC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAC/C,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACjD;AAsDD,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAIpE"}
@@ -4,15 +4,18 @@ import { parse } from "#rules/syntax.ts";
4
4
  import { ambientModules } from "./ambient.js";
5
5
  import { importsOf } from "./extract.js";
6
6
  import { projectsFor } from "./projects.js";
7
- import { isDeclarationFile, resolveImport } from "./resolve.js";
7
+ import { isDeclarationFile, presumedTarget, resolveImport } from "./resolve.js";
8
8
  import { workspacePackages } from "./workspace.js";
9
9
  const QUERY = /\?.*$/u;
10
10
  const NO_MODULES = "the import graph covers no modules: the sources hold no TypeScript or JavaScript module. Point `sources` at the code, or turn the imports rules off.";
11
- // A relative import of a missing file still names a path, so fences see it before its generator writes it.
12
- function missingTarget(from, request) {
11
+ function relativeTarget(from, request) {
13
12
  const relative = request.kind === "path-reference" || request.specifier.startsWith("./") || request.specifier.startsWith("../");
14
- const target = posix.join(posix.dirname(from), request.specifier.replace(QUERY, ""));
15
- return relative && !target.startsWith("../") ? target : undefined;
13
+ return relative ? posix.join(posix.dirname(from), request.specifier.replace(QUERY, "")) : undefined;
14
+ }
15
+ // A relative import or a package import of a missing file still names a path, so fences see it before its generator writes it.
16
+ function missingTarget(root, from, request, project) {
17
+ const target = presumedTarget(root, request, join(root, from), project) ?? relativeTarget(from, request);
18
+ return target === undefined || target.startsWith("../") ? undefined : target;
16
19
  }
17
20
  function walk(inputs, root) {
18
21
  const projectOf = projectsFor(root);
@@ -28,7 +31,7 @@ function walk(inputs, root) {
28
31
  for (const request of importsOf(syntax, isDeclarationFile(file.path))) {
29
32
  const to = resolveImport(root, ambient, request, path, project);
30
33
  if (to === undefined) {
31
- const missing = missingTarget(file.path, request);
34
+ const missing = missingTarget(root, file.path, request, project);
32
35
  unresolved.push({ ...request, from: file.path, missing });
33
36
  edges.push(...(missing === undefined ? [] : [{ ...request, from: file.path, to: { kind: "file", path: missing } }]));
34
37
  }
@@ -1 +1 @@
1
- {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/imports/graph.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"graph.js","sourceRoot":"","sources":["../../src/imports/graph.ts"],"names":[],"mappings":"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"}
@@ -12,5 +12,6 @@ export type Endpoint = {
12
12
  export declare function builtinName(specifier: string): string | undefined;
13
13
  export declare function packageNameOf(specifier: string): string;
14
14
  export declare function isDeclarationFile(path: string): boolean;
15
+ export declare function presumedTarget(root: string, request: ImportRequest, from: string, project: Project): string | undefined;
15
16
  export declare function resolveImport(root: string, ambient: Ambient, request: ImportRequest, from: string, project: Project): Endpoint | undefined;
16
17
  //# sourceMappingURL=resolve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/imports/resolve.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,QAAQ,GACjB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAYvF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKjE;AAmBD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAYD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAuCD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAY1I"}
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/imports/resolve.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,MAAM,QAAQ,GACjB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC;AAsBvF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKjE;AAmBD,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAYD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AA6BD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMvH;AAYD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,CAY1I"}
@@ -8,6 +8,13 @@ const NODE_MODULES = "/node_modules/";
8
8
  const ASSET_DECLARATION = /\.d(?<extension>\.[^./]+)\.ts$/u;
9
9
  const DECLARATION = /\.d\.[cm]?ts$/u;
10
10
  const QUERY = /\?.*$/u;
11
+ const PACKAGE_IMPORT = "#";
12
+ const PACKAGE_JSON = "package.json";
13
+ const presumingHost = {
14
+ ...ts.sys,
15
+ directoryExists: () => true,
16
+ fileExists: (path) => !path.endsWith(`/${PACKAGE_JSON}`) || ts.sys.fileExists(path),
17
+ };
11
18
  export function builtinName(specifier) {
12
19
  if (!isBuiltin(specifier)) {
13
20
  return undefined;
@@ -63,6 +70,13 @@ function resolvedPath(request, from, project) {
63
70
  const path = located(request, from, project);
64
71
  return path === undefined ? undefined : fitting(path, request.type);
65
72
  }
73
+ export function presumedTarget(root, request, from, project) {
74
+ if (request.kind !== "import" || !request.specifier.startsWith(PACKAGE_IMPORT)) {
75
+ return undefined;
76
+ }
77
+ const path = ts.resolveModuleName(request.specifier.replace(QUERY, ""), from, project.options, presumingHost).resolvedModule?.resolvedFileName;
78
+ return path === undefined ? undefined : posix(relative(root, path));
79
+ }
66
80
  function endpointAt(root, specifier, path) {
67
81
  const real = posix(realpathSync(path));
68
82
  const installed = real.lastIndexOf(NODE_MODULES);
@@ -1 +1 @@
1
- {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/imports/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AASnD,MAAM,WAAW,GAAG,OAAO,CAAC;AAE5B,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAEtC,MAAM,iBAAiB,GAAG,iCAAiC,CAAC;AAE5D,MAAM,WAAW,GAAG,gBAAgB,CAAC;AAErC,MAAM,KAAK,GAAG,QAAQ,CAAC;AAEvB,MAAM,UAAU,WAAW,CAAC,SAAiB;IAC5C,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC;QAC3B,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,SAAS,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,WAAW,GAAG,SAAS,EAAE,CAAC;AACrF,CAAC;AAED,MAAM,WAAW,GAAG,QAAQ,CAAC;AAE7B,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAEnC,SAAS,SAAS,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACrG,CAAC;AAED,SAAS,MAAM,CAAC,IAAY;IAC3B,MAAM,CAAC,KAAK,GAAG,EAAE,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,MAAM,EAAE,CAAC;AACzE,CAAC;AAED,oIAAoI;AACpI,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC9C,OAAO,WAAW,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,OAAO,CAAC,WAAmB;IACnC,OAAO,WAAW,CAAC,OAAO,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;AAC/D,CAAC;AAED,gJAAgJ;AAChJ,MAAM,SAAS,GAA4B;IAC1C,GAAG,EAAE,CAAC,GAAG;IACT,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;CACnH,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC7C,OAAO,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,OAAO,CAAC,QAAgB,EAAE,IAAa;IAC/C,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAC9E,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AACpE,CAAC;AAED,SAAS,OAAO,CAAC,OAAsB,EAAE,IAAY,EAAE,OAAgB;IACtE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACvD,IAAI,OAAO,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACvC,OAAO,EAAE,CAAC,6BAA6B,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,8BAA8B,EAAE,gBAAgB,CAAC;IACzI,CAAC;IACD,IAAI,OAAO,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;QAC5C,OAAO,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACnD,CAAC;IACD,OAAO,CACN,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,cAAc,EAAE,gBAAgB;WAC3G,EAAE,CAAC,iBAAiB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,cAAc,EAAE,gBAAgB,CAC9H,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,OAAsB,EAAE,IAAY,EAAE,OAAgB;IAC3E,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7C,OAAO,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,SAAiB,EAAE,IAAY;IAChE,MAAM,IAAI,GAAG,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACjD,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;IACtG,CAAC;IACD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AACvI,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,OAAgB,EAAE,OAAsB,EAAE,IAAY,EAAE,OAAgB;IACnH,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC;IACnE,CAAC;IACD,MAAM,IAAI,GAAG,YAAY,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAClD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC;QAC/C,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE;QAC/F,CAAC,CAAC,SAAS,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/imports/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function exportFits(name: string, stem: string, folders: readonly string[]): boolean;
2
+ //# sourceMappingURL=exportFits.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exportFits.d.ts","sourceRoot":"","sources":["../../src/naming/exportFits.ts"],"names":[],"mappings":"AAOA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAa1F"}
@@ -0,0 +1,20 @@
1
+ import { CAMEL, isUpper, PASCAL, sameWord, wordsOf } from "#naming/words.ts";
2
+ function restIsFolders(rest, folders) {
3
+ const folderWords = folders.flatMap(wordsOf);
4
+ return rest.every((word) => folderWords.some((folder) => sameWord(word, folder)));
5
+ }
6
+ export function exportFits(name, stem, folders) {
7
+ if (!(CAMEL.test(stem) || PASCAL.test(stem)) || isUpper(stem) !== isUpper(name)) {
8
+ return false;
9
+ }
10
+ const named = wordsOf(name);
11
+ const filed = wordsOf(stem);
12
+ for (let start = 0; start + filed.length <= named.length; start += 1) {
13
+ const matches = filed.every((word, offset) => word === named[start + offset]);
14
+ if (matches && restIsFolders([...named.slice(0, start), ...named.slice(start + filed.length)], folders)) {
15
+ return true;
16
+ }
17
+ }
18
+ return false;
19
+ }
20
+ //# sourceMappingURL=exportFits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exportFits.js","sourceRoot":"","sources":["../../src/naming/exportFits.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE7E,SAAS,aAAa,CAAC,IAAuB,EAAE,OAA0B;IACzE,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,IAAY,EAAE,OAA0B;IAChF,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACjF,OAAO,KAAK,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACtE,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,KAAK,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC;QAC9E,IAAI,OAAO,IAAI,aAAa,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC;YACzG,OAAO,IAAI,CAAC;QACb,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { OwnExport } from "#naming/ownExports.ts";
2
+ export declare function mainExport(exports: readonly OwnExport[]): OwnExport | undefined;
3
+ //# sourceMappingURL=mainExport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mainExport.d.ts","sourceRoot":"","sources":["../../src/naming/mainExport.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,GAAG,SAAS,GAAG,SAAS,CAQ/E"}
@@ -0,0 +1,10 @@
1
+ export function mainExport(exports) {
2
+ const values = exports.filter((entry) => entry.kind === "value");
3
+ const types = exports.filter((entry) => entry.kind === "type");
4
+ const [value] = values;
5
+ if (values.length === 1 && value !== undefined && types.every((type) => type.name.startsWith(value.name))) {
6
+ return value;
7
+ }
8
+ return values.length === 0 && types.length === 1 ? types[0] : undefined;
9
+ }
10
+ //# sourceMappingURL=mainExport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mainExport.js","sourceRoot":"","sources":["../../src/naming/mainExport.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,OAA6B;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAC/D,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;IACvB,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC3G,OAAO,KAAK,CAAC;IACd,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACzE,CAAC"}
@@ -0,0 +1,8 @@
1
+ import ts from "typescript";
2
+ export interface OwnExport {
3
+ readonly constant: boolean;
4
+ readonly kind: "type" | "value";
5
+ readonly name: string;
6
+ }
7
+ export declare function ownExports(source: ts.SourceFile): readonly OwnExport[];
8
+ //# sourceMappingURL=ownExports.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ownExports.d.ts","sourceRoot":"","sources":["../../src/naming/ownExports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,WAAW,SAAS;IACzB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACtB;AAgFD,wBAAgB,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC,UAAU,GAAG,SAAS,SAAS,EAAE,CAQtE"}