@starci/eslint-canon-be 1.8.0 → 2.0.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +95 -5
  2. package/README.md +41 -52
  3. package/async-discipline.mjs +2 -2
  4. package/authorization.mjs +38 -88
  5. package/builders.mjs +305 -0
  6. package/comments.mjs +19 -34
  7. package/config-owner.mjs +127 -125
  8. package/connections.mjs +254 -0
  9. package/cqrs.mjs +426 -135
  10. package/data-access.mjs +320 -391
  11. package/default-deny.mjs +14 -10
  12. package/e2e-flow.mjs +208 -180
  13. package/error-handling.mjs +254 -128
  14. package/idempotency.mjs +98 -67
  15. package/index.mjs +32 -9
  16. package/infra-owner.mjs +96 -0
  17. package/injection.mjs +602 -0
  18. package/input-bounds.mjs +166 -66
  19. package/lib/config.mjs +70 -33
  20. package/lib/db-writes.mjs +58 -0
  21. package/lib/declared.mjs +154 -0
  22. package/lib/hfs.mjs +61 -0
  23. package/lib/import-source.mjs +104 -0
  24. package/lib/persistence.mjs +160 -0
  25. package/lib/ports.mjs +138 -0
  26. package/lib/transport-slots.mjs +14 -0
  27. package/lib/types.mjs +133 -0
  28. package/lib/unit-spec.mjs +33 -0
  29. package/log-safety.mjs +94 -26
  30. package/module-layering.mjs +180 -297
  31. package/module-shape.mjs +296 -59
  32. package/naming.mjs +44 -12
  33. package/observability.mjs +57 -91
  34. package/operations.mjs +201 -0
  35. package/package.json +10 -7
  36. package/query-safety.mjs +189 -223
  37. package/resilience.mjs +126 -31
  38. package/runtime/engine/plain-object.mjs +5 -0
  39. package/runtime/engine/runtime-root.mjs +32 -0
  40. package/runtime/engine/yaml.mjs +161 -0
  41. package/runtime/knowledge/hfs/slots.yaml +1111 -0
  42. package/runtime/scripts/lib/git.mjs +53 -0
  43. package/runtime/scripts/lib/glob.mjs +23 -0
  44. package/runtime/scripts/lib/hfs-allows.mjs +57 -0
  45. package/runtime/scripts/lib/hfs-slots.mjs +729 -0
  46. package/runtime/scripts/lib/hfs-view.mjs +68 -0
  47. package/runtime/scripts/lib/language.mjs +107 -0
  48. package/runtime/scripts/lib/path-key.mjs +17 -0
  49. package/runtime/scripts/lib/recorded-lines.mjs +27 -0
  50. package/schema-authority.mjs +273 -91
  51. package/size-budget.mjs +19 -61
  52. package/spec-no-skip.mjs +84 -0
  53. package/spec-quality.mjs +76 -35
  54. package/suppression.mjs +34 -16
  55. package/temporal.mjs +101 -36
  56. package/test-world.mjs +204 -0
  57. package/testing.mjs +99 -251
  58. package/transport.mjs +433 -142
  59. package/type-safety.mjs +50 -278
  60. package/unit-spec.mjs +452 -0
  61. package/user-copy.mjs +56 -37
  62. package/lib/slots.mjs +0 -83
package/lib/slots.mjs DELETED
@@ -1,83 +0,0 @@
1
- /**
2
- * The adapter between the HFS slot manifest (`knowledge/hfs/slots.yaml`) and the lint rules that need a
3
- * number or a list the manifest owns: which platform capabilities may be `@Global()`, how long a source
4
- * file may be, how many names a public `index.ts` may export.
5
- *
6
- * The manifest states these in `ruleParams.be` (the same block `ruleParams(manifest, "be")` of
7
- * `scripts/lib/hfs-slots.mjs` returns) and in the `budget.indexExports` of a `be.*` slot. This file reads only those
8
- * keys, and there is no other source: a manifest that does not state them, or that cannot be read, stops the lint
9
- * run with an error naming the file, because the slot check owns the finding and a rule must not guess a number.
10
- *
11
- * - `ruleParams.be.globalModules` directories `src/modules/platform/<capability>/` allowed to declare `@Global()`;
12
- * the rule compares the capability `platform/<capability>`
13
- * - `ruleParams.be.fileLines` `{ soft, hardGrowth }`: `soft` is the line budget; with `hardGrowth: true` a file
14
- * over it may not be born or grow (`file-size-growth`)
15
- * - the `budget.indexExports` of the first `be.*` slot that states one, the public-surface width
16
- *
17
- * The manifest and the YAML reader come from the installed `@starci/hfs` package, which carries a runtime copy
18
- * (`runtime/knowledge/hfs/slots.yaml`, `runtime/engine/yaml.mjs`) and is a dependency of this package. They are
19
- * resolved as `@starci/hfs/runtime/...` with `import.meta.resolve`, never from the product repository's filesystem
20
- * and never from a link path. `STARCI_HFS_SLOTS` overrides the manifest file (tests, experiments). Inside the runtime
21
- * repository itself, where `@starci/hfs` is not installed, the sibling `packages/hfs` workspace stands in.
22
- */
23
- import { existsSync, readFileSync } from "node:fs"
24
- import { dirname, join } from "node:path"
25
- import { fileURLToPath, pathToFileURL } from "node:url"
26
-
27
- const HERE = dirname(fileURLToPath(import.meta.url))
28
- const SIBLING_HFS = join(HERE, "..", "..", "..", "hfs")
29
-
30
- const HFS_SLOTS = "@starci/hfs/runtime/knowledge/hfs/slots.yaml"
31
- const HFS_YAML = "@starci/hfs/runtime/engine/yaml.mjs"
32
-
33
- /**
34
- * Resolves a file of the installed `@starci/hfs` package.
35
- *
36
- * @param {string} specifier - The `@starci/hfs/...` specifier.
37
- * @returns {string} The `file:` URL of the file.
38
- */
39
- const hfsFile = (specifier) => {
40
- try {
41
- return import.meta.resolve(specifier)
42
- } catch (error) {
43
- const sibling = join(SIBLING_HFS, specifier.slice("@starci/hfs/".length))
44
- if (existsSync(join(SIBLING_HFS, "package.json")) && existsSync(sibling)) return pathToFileURL(sibling).href
45
- throw new Error(`@starci/hfs is not installed (${specifier} does not resolve): add it to dependencies and reinstall. ${error.message}`)
46
- }
47
- }
48
-
49
- const manifestFile = () => process.env.STARCI_HFS_SLOTS || fileURLToPath(hfsFile(HFS_SLOTS))
50
-
51
- const toCapability = (dir) => String(dir).replace(/^src\/modules\//, "").replace(/\/+$/, "")
52
-
53
- /**
54
- * Reads the rule parameters out of a parsed manifest.
55
- *
56
- * @param {object} manifest - The parsed `slots.yaml`.
57
- * @returns {{ globalModules: readonly string[], fileLines: { soft: number, hardGrowth: number }, indexExports: number }} The parameters; `fileLines.hardGrowth` is the line count above which a file may not grow.
58
- */
59
- export const paramsFromManifest = (manifest) => {
60
- const be = manifest?.ruleParams?.be
61
- if (!Array.isArray(be?.globalModules) || !be.globalModules.every((name) => typeof name === "string")) throw new Error("slots.yaml states no ruleParams.be.globalModules")
62
- if (!Number.isInteger(be.fileLines?.soft) || typeof be.fileLines?.hardGrowth !== "boolean") throw new Error("slots.yaml states no ruleParams.be.fileLines {soft, hardGrowth}")
63
- const indexSlot = Array.isArray(manifest.slots)
64
- ? manifest.slots.find((slot) => String(slot?.id ?? "").startsWith("be.") && Number.isInteger(slot?.budget?.indexExports))
65
- : undefined
66
- if (indexSlot === undefined) throw new Error("slots.yaml states no budget.indexExports on a be.* slot")
67
- const { soft, hardGrowth } = be.fileLines
68
- return {
69
- globalModules: be.globalModules.map(toCapability),
70
- fileLines: { soft, hardGrowth: hardGrowth ? soft : Number.POSITIVE_INFINITY },
71
- indexExports: indexSlot.budget.indexExports,
72
- }
73
- }
74
-
75
- const load = async () => {
76
- const file = manifestFile()
77
- if (!existsSync(file)) throw new Error(`HFS slot manifest not found at ${file}`)
78
- const { parseYaml } = await import(hfsFile(HFS_YAML))
79
- return paramsFromManifest(parseYaml(readFileSync(file, "utf8")))
80
- }
81
-
82
- /** The parameters, resolved once per process. */
83
- export const hfsParams = await load()