@devbie/style-guide 1.1.3 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,27 +5,44 @@ Single source of truth for code style across the devbie ecosystem
5
5
 
6
6
  ## Exports
7
7
 
8
- | Entry | Contents |
9
- | ------------------------------------ | -------------------------------------------------------------- |
10
- | `@devbie/style-guide/prettier` | Canonical prettier config (all repos) |
11
- | `@devbie/style-guide/eslint/backend` | eslint flat standard for Nest/Node TypeScript backends |
12
- | `@devbie/style-guide/eslint/frontend`| eslint flat standard for frontend repos (TS + React + a11y) |
13
- | `@devbie/style-guide/eslint/next` | Frontend standard + canonical Next.js rules (overlay) |
14
-
15
- ## Which entry each repo uses
16
-
17
- | Repo | eslint entry |
18
- | --------------------------------------------------------------------------------- | ------------ |
19
- | newbie, newbie-starter, nightwatch-backend, newbie-modules, apits | `backend` |
20
- | fewbie | `frontend` |
21
- | fewbie-starter, nightwatch-frontend | `next` |
22
-
23
- `next` is the shared `core` baseline plus `eslint-config-next` (which already
24
- bundles the React / react-hooks / jsx-a11y layers), so every repo shares the
25
- same language-level rules while Next.js applications add only the canonical
26
- framework layer. `eslint-config-next` requires the `next` package at load
27
- time, which is why repos without a Next runtime (fewbie) use `frontend`
28
- instead.
8
+ | Entry | Contents |
9
+ | --------------------------------- | ----------------------------------------------- |
10
+ | `@devbie/style-guide/prettier` | Canonical prettier config (all repos) |
11
+ | `@devbie/style-guide/eslint/base` | Baseline eslint flat config for Node TypeScript |
12
+ | `@devbie/style-guide/eslint/nest` | Nest.js layer (Nest-specific rules, type-aware) |
13
+ | `@devbie/style-guide/eslint/next` | Next.js layer (canonical Next.js rules) |
14
+
15
+ `nest` and `next` are **layers, not standalone standards**: every consumer
16
+ composes `[...base, ...nest]` or `[...base, ...next]`. The baseline carries
17
+ the shared language-level rules and prettier; a layer adds only its
18
+ framework's rules. `base` alone covers CLIs, code generators, registries, and
19
+ SDKs.
20
+
21
+ ## Coverage: which entry each repo uses
22
+
23
+ | Repo | Composition |
24
+ | ----------------------------------- | ----------------------------------------- |
25
+ | newbie-monorepo root | `base` + `nest` scoped to `packages/core` |
26
+ | newbie-starter, nightwatch-backend | `base` + `nest` |
27
+ | fewbie-starter, nightwatch-frontend | `base` + `next` |
28
+ | newbie-modules | `base` only |
29
+
30
+ Two structural facts drive this table:
31
+
32
+ - `newbie-modules` installs no dependencies at all (modules are copied into a
33
+ consumer, not built in place), so it can only use `base`, which is purely
34
+ syntactic.
35
+ - The newbie monorepo root lints heterogeneous packages in one config: only
36
+ `packages/core` is Nest framework code, while the CLIs, the generator and
37
+ the SDKs are plain Node. ESLint flat config does not read `package.json` and
38
+ nested `eslint.config.mjs` files are not inherited, so per-package
39
+ differentiation must be expressed in the root config with `files` scoping —
40
+ never with per-package config files or `package.json` entry fields.
41
+
42
+ `next` (and `nest`) must be loaded where the framework's packages are
43
+ installed; `eslint-config-next` requires `next` at load time, and the Nest
44
+ layer requires `class-validator` plus a TypeScript project for its four
45
+ type-aware rules.
29
46
 
30
47
  ## Usage
31
48
 
@@ -48,13 +65,13 @@ not style decisions.
48
65
  `eslint.config.mjs` in the consumer repo:
49
66
 
50
67
  ```js
51
- import backend from "@devbie/style-guide/eslint/backend";
52
- // frontend repos: import frontend from "@devbie/style-guide/eslint/frontend";
68
+ import base from "@devbie/style-guide/eslint/base";
69
+ // Nest apps: import nest from "@devbie/style-guide/eslint/nest";
53
70
  // Next.js apps: import next from "@devbie/style-guide/eslint/next";
54
71
 
55
72
  export default [
56
- ...backend,
57
- // Repo-specific rules and ignores go here.
73
+ ...base,
74
+ // ...nest or ...next, then repo-specific rules and ignores.
58
75
  ];
59
76
  ```
60
77
 
@@ -70,6 +87,18 @@ default, only as a deliberate milestone.
70
87
 
71
88
  ## Changelog
72
89
 
90
+ - 1.3.0 — new `nest` layer backed by `@darraghor/eslint-plugin-nestjs-typed`
91
+ (recommended flat config, four type-aware rules), and `next` reshaped into a
92
+ layer. Consumers now compose `[...base, ...nest]` / `[...base, ...next]`;
93
+ this also lets the newbie monorepo scope the Nest layer to `packages/core`
94
+ via `files` instead of giving a Nest framework standard to its CLIs.
95
+ - 1.2.0 — `backend` renamed to `base` and `frontend` removed. After apits and
96
+ fewbie-cli joined the newbie monorepo (ADR-012/ADR-015), `frontend` had no
97
+ consumer left, and `backend` no longer described its consumers (CLIs, code
98
+ generators, registries — none of them backends). The pair is now named for
99
+ what it is: `base` (the default) and `next` (the Next.js specialization).
100
+ The react/react-hooks/jsx-a11y plugin dependencies are dropped; `next`
101
+ gets those layers from `eslint-config-next`.
73
102
  - 1.1.3 — `frontend` pins the React version for rule evaluation (19.0) instead
74
103
  of detecting it: fewbie lints React template sources without a `react`
75
104
  package installed, where detection only emits a warning.
package/eslint/base.js ADDED
@@ -0,0 +1,16 @@
1
+ import core from "./core.js";
2
+ import prettierConfig from "eslint-config-prettier";
3
+
4
+ /**
5
+ * Baseline standard for the devbie ecosystem.
6
+ *
7
+ * Consumers: every repo composes this and optionally adds a framework layer —
8
+ * `[...base, ...nest]` for Nest applications, `[...base, ...next]` for Next.js
9
+ * applications. Repos without a framework (newbie-modules, a dependency-free
10
+ * source registry) use `base` alone: every rule here is syntactic, so it runs
11
+ * without installing module dependencies.
12
+ *
13
+ * Repo-specific rules and ignores belong in the consumer's own
14
+ * eslint.config.mjs, spread after this entry.
15
+ */
16
+ export default [...core, prettierConfig];
package/eslint/core.js CHANGED
@@ -8,23 +8,30 @@ import tseslint from "typescript-eslint";
8
8
  * eslint-config-prettier last so no plugin can re-enable eslint formatting
9
9
  * rules afterwards.
10
10
  *
11
- * Internal entry: consumers import `backend`, `frontend` or `next`, never
12
- * this file.
11
+ * Internal entry: consumers import `base` (or compose a layer such as
12
+ * `nest` / `next` on top of it), never this file.
13
13
  */
14
- export default [...tseslint.configs.recommended, {
15
- rules: {
16
- "@typescript-eslint/no-explicit-any": "off",
17
- "@typescript-eslint/no-unused-vars": [
18
- "error",
19
- { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" },
20
- ],
14
+ export default [
15
+ ...tseslint.configs.recommended,
16
+ {
17
+ rules: {
18
+ "@typescript-eslint/no-explicit-any": "off",
19
+ "@typescript-eslint/no-unused-vars": [
20
+ "error",
21
+ { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" },
22
+ ],
21
23
 
22
- // Code-quality rules carried over from the legacy gts-derived config.
23
- "block-scoped-var": "error",
24
- eqeqeq: ["error", "always", { null: "ignore" }],
25
- "no-var": "error",
26
- "prefer-const": "error",
27
- "prefer-arrow-callback": "error",
28
- "no-restricted-properties": ["error", { object: "describe", property: "only" }, { object: "it", property: "only" }],
24
+ // Code-quality rules carried over from the legacy gts-derived config.
25
+ "block-scoped-var": "error",
26
+ eqeqeq: ["error", "always", { null: "ignore" }],
27
+ "no-var": "error",
28
+ "prefer-const": "error",
29
+ "prefer-arrow-callback": "error",
30
+ "no-restricted-properties": [
31
+ "error",
32
+ { object: "describe", property: "only" },
33
+ { object: "it", property: "only" },
34
+ ],
35
+ },
29
36
  },
30
- }];
37
+ ];
package/eslint/nest.js ADDED
@@ -0,0 +1,29 @@
1
+ import nestjsTyped from "@darraghor/eslint-plugin-nestjs-typed";
2
+ import prettierConfig from "eslint-config-prettier";
3
+
4
+ /**
5
+ * Nest.js layer for the devbie ecosystem.
6
+ *
7
+ * This is a layer, not a standalone standard: compose it after `base`
8
+ * (`export default [...base, ...nest]`). Keeping it separable lets a
9
+ * monorepo scope the Nest rules to the packages that actually contain Nest
10
+ * code, instead of applying a framework standard to its plain Node packages.
11
+ *
12
+ * The rule set is the plugin's recommended flat config. Four of those rules
13
+ * are type-aware, so every file covered by this layer must belong to a
14
+ * TypeScript project (projectService resolves the nearest tsconfig.json), and
15
+ * the plugin's peers (`class-validator`, `@typescript-eslint/parser`) must be
16
+ * installed by the consumer.
17
+ *
18
+ * `prettierConfig` is repeated here so that composing `[...base, ...nest]`
19
+ * still ends on the formatting-rule shutdown.
20
+ */
21
+ export default [
22
+ ...nestjsTyped.configs.flatRecommended,
23
+ {
24
+ languageOptions: {
25
+ parserOptions: { projectService: true },
26
+ },
27
+ },
28
+ prettierConfig,
29
+ ];
package/eslint/next.js CHANGED
@@ -1,26 +1,30 @@
1
- import { defineConfig, globalIgnores } from "eslint/config";
2
- import core from "./core.js";
1
+ import { globalIgnores } from "eslint/config";
3
2
  import nextVitals from "eslint-config-next/core-web-vitals";
4
3
  import nextTs from "eslint-config-next/typescript";
5
4
  import prettierConfig from "eslint-config-prettier";
6
5
 
7
6
  /**
8
- * Next.js standard for Next.js applications
9
- * (nightwatch-frontend, fewbie-starter).
7
+ * Next.js layer for the devbie ecosystem.
8
+ *
9
+ * This is a layer, not a standalone standard: compose it after `base`
10
+ * (`export default [...base, ...next]`), so every repo shares the same
11
+ * language-level rules while Next.js applications add only the canonical
12
+ * framework rule set.
10
13
  *
11
- * Extends the shared `core` baseline with the canonical Next rule set.
12
14
  * `eslint-config-next` already bundles the React / react-hooks / jsx-a11y
13
- * layers, so the `frontend` React layer is not repeated here: spreading both
15
+ * layers, so nothing else is layered on top: spreading another React layer
14
16
  * would redefine the same plugin and flat config rejects that.
15
17
  *
16
- * This entry can only be loaded where the `next` package is installed, which
17
- * is why frontend repos without a Next runtime use `frontend` instead.
18
+ * This entry can only be loaded where the `next` package is installed; Node
19
+ * repos without a Next runtime compose `base` with `nest` or nothing at all.
20
+ *
21
+ * `prettierConfig` is repeated here so that composing `[...base, ...next]`
22
+ * still ends on the formatting-rule shutdown.
18
23
  */
19
- export default defineConfig([
20
- ...core,
24
+ export default [
21
25
  ...nextVitals,
22
26
  ...nextTs,
23
27
  prettierConfig,
24
28
  // Framework-generated artifacts; consumers append their own ignores.
25
29
  globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
26
- ]);
30
+ ];
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@devbie/style-guide",
3
- "version": "1.1.3",
4
- "description": "Single source of truth for devbie ecosystem code style: shared prettier config and eslint flat standards (backend, frontend, next)",
3
+ "version": "1.3.0",
4
+ "description": "Single source of truth for devbie ecosystem code style: shared prettier config and composable eslint flat layers (base, nest, next)",
5
5
  "license": "MIT",
6
6
  "author": "worldzhy",
7
7
  "type": "module",
8
8
  "exports": {
9
9
  "./prettier": "./prettier.js",
10
- "./eslint/backend": "./eslint/backend.js",
11
- "./eslint/frontend": "./eslint/frontend.js",
10
+ "./eslint/base": "./eslint/base.js",
11
+ "./eslint/nest": "./eslint/nest.js",
12
12
  "./eslint/next": "./eslint/next.js",
13
13
  "./package.json": "./package.json"
14
14
  },
@@ -20,11 +20,9 @@
20
20
  "access": "public"
21
21
  },
22
22
  "dependencies": {
23
+ "@darraghor/eslint-plugin-nestjs-typed": "^7.5.8",
23
24
  "eslint-config-next": "^16.4.2",
24
25
  "eslint-config-prettier": "^10.1.8",
25
- "eslint-plugin-jsx-a11y": "^6.10.0",
26
- "eslint-plugin-react": "^7.37.0",
27
- "eslint-plugin-react-hooks": "^7.1.0",
28
26
  "typescript-eslint": "^8.71.2"
29
27
  },
30
28
  "peerDependencies": {
package/eslint/backend.js DELETED
@@ -1,15 +0,0 @@
1
- import core from "./core.js";
2
- import prettierConfig from "eslint-config-prettier";
3
-
4
- /**
5
- * Backend standard for the devbie ecosystem.
6
- *
7
- * Consumers: newbie, newbie-starter, nightwatch-backend, newbie-modules,
8
- * apits. All of them are Nest/Node TypeScript codebases; the language-level
9
- * rules live in `core` so the backend and frontend standards never drift on
10
- * the shared part.
11
- *
12
- * Repo-specific rules and ignores belong in the consumer's own
13
- * eslint.config.mjs, spread after this entry.
14
- */
15
- export default [...core, prettierConfig];
@@ -1,34 +0,0 @@
1
- import core from "./core.js";
2
- import prettierConfig from "eslint-config-prettier";
3
- import react from "eslint-plugin-react";
4
- import reactHooks from "eslint-plugin-react-hooks";
5
- import jsxA11y from "eslint-plugin-jsx-a11y";
6
-
7
- /**
8
- * Frontend standard for the devbie ecosystem.
9
- *
10
- * Consumers: fewbie, fewbie-starter, nightwatch-frontend.
11
- *
12
- * Deliberately independent of `eslint-config-next`: that package requires the
13
- * `next` package to be installed (its parser is `next/dist/compiled/babel
14
- * /eslint-parser`), while fewbie ships a Node CLI and has no Next runtime.
15
- * Next.js applications layer `@devbie/style-guide/eslint/next` on top instead.
16
- *
17
- * The JSX/React layer is scoped to JSX/TSX files, so Node code in a frontend
18
- * group repo (fewbie-cli) is never evaluated against React rules, while its
19
- * React template sources are.
20
- */
21
- const jsxFiles = ["**/*.jsx", "**/*.tsx"];
22
- const jsxOnly = (config) => ({ ...config, files: jsxFiles });
23
-
24
- export default [
25
- ...core,
26
- jsxOnly(react.configs.flat.recommended),
27
- jsxOnly(react.configs.flat["jsx-runtime"]),
28
- jsxOnly(reactHooks.configs.flat["recommended-latest"]),
29
- jsxOnly(jsxA11y.flatConfigs.recommended),
30
- // Pinned instead of `detect`: fewbie lints React 19 template sources without
31
- // a `react` package installed, where detection only produces a warning.
32
- { settings: { react: { version: "19.0" } } },
33
- prettierConfig,
34
- ];