@devbie/style-guide 1.3.0 → 1.4.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
@@ -1,7 +1,7 @@
1
1
  # @devbie/style-guide
2
2
 
3
3
  Single source of truth for code style across the devbie ecosystem
4
- (newbie / fewbie / nightwatch / apits). See ADR-010 in `worldzhy/newbie`.
4
+ (newbie / fewbie / nightwatch / apits). See ADR-010 in `worldzhy/devbie`.
5
5
 
6
6
  ## Exports
7
7
 
@@ -9,7 +9,7 @@ Single source of truth for code style across the devbie ecosystem
9
9
  | --------------------------------- | ----------------------------------------------- |
10
10
  | `@devbie/style-guide/prettier` | Canonical prettier config (all repos) |
11
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) |
12
+ | `@devbie/style-guide/eslint/nest` | Nest layer (Nest-specific rules, type-aware) |
13
13
  | `@devbie/style-guide/eslint/next` | Next.js layer (canonical Next.js rules) |
14
14
 
15
15
  `nest` and `next` are **layers, not standalone standards**: every consumer
@@ -20,29 +20,34 @@ SDKs.
20
20
 
21
21
  ## Coverage: which entry each repo uses
22
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 |
23
+ | Repo | Composition |
24
+ | ----------------------------------- | ------------------------------------------- |
25
+ | devbie monorepo root | `base` + `nest` scoped to `packages/newbie` |
26
+ | newbie-starter, nightwatch-backend | `base` + `nest` |
27
+ | fewbie-starter, nightwatch-frontend | `base` + `next` |
28
+ | newbie-modules | `base` + `nest` |
29
29
 
30
30
  Two structural facts drive this table:
31
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
32
+ - `newbie-modules` is a pure source registry — module sources are copied into
33
+ a consumer rather than built in place — but those sources are Nest code, so
34
+ it composes `[...base, ...nest]` with `injectable-should-be-provided`
35
+ scoped off: there is no host module graph in the registry for the rule to
36
+ resolve providers against, and the host keeps the rule enabled where that
37
+ graph exists.
38
+ - The devbie monorepo root lints heterogeneous packages in one config: only
39
+ `packages/newbie` is Nest framework code, while the CLIs, the generator and
37
40
  the SDKs are plain Node. ESLint flat config does not read `package.json` and
38
41
  nested `eslint.config.mjs` files are not inherited, so per-package
39
42
  differentiation must be expressed in the root config with `files` scoping —
40
43
  never with per-package config files or `package.json` entry fields.
41
44
 
42
45
  `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.
46
+ installed: `eslint-config-next` requires `next` at load time (declared as an
47
+ optional peer, so base/nest consumers are never forced to install Next.js),
48
+ and the Nest layer requires a TypeScript project for its four type-aware
49
+ rules. The Nest plugin's own peer declarations carry the rest — nothing
50
+ imports `class-validator` at lint runtime.
46
51
 
47
52
  ## Usage
48
53
 
@@ -87,10 +92,14 @@ default, only as a deliberate milestone.
87
92
 
88
93
  ## Changelog
89
94
 
95
+ - 1.3.1 — the internal `core` entry is inlined into `base` and removed. Nothing
96
+ imported it directly (`base` was its only consumer), and keeping two files
97
+ for one entry set made the loading order harder to read: `nest` and `next`
98
+ each also end on `prettierConfig`, so there is no shared tail to factor out.
90
99
  - 1.3.0 — new `nest` layer backed by `@darraghor/eslint-plugin-nestjs-typed`
91
100
  (recommended flat config, four type-aware rules), and `next` reshaped into a
92
101
  layer. Consumers now compose `[...base, ...nest]` / `[...base, ...next]`;
93
- this also lets the newbie monorepo scope the Nest layer to `packages/core`
102
+ this also lets the devbie monorepo scope the Nest layer to `packages/newbie`
94
103
  via `files` instead of giving a Nest framework standard to its CLIs.
95
104
  - 1.2.0 — `backend` renamed to `base` and `frontend` removed. After apits and
96
105
  fewbie-cli joined the newbie monorepo (ADR-012/ADR-015), `frontend` had no
@@ -0,0 +1,5 @@
1
+ import type { Linter } from "eslint";
2
+
3
+ // Baseline flat-config layer; compose first ([...base, ...nest] / [...base, ...next]).
4
+ declare const config: Linter.Config[];
5
+ export default config;
package/eslint/base.js CHANGED
@@ -1,4 +1,4 @@
1
- import core from "./core.js";
1
+ import tseslint from "typescript-eslint";
2
2
  import prettierConfig from "eslint-config-prettier";
3
3
 
4
4
  /**
@@ -6,11 +6,39 @@ import prettierConfig from "eslint-config-prettier";
6
6
  *
7
7
  * Consumers: every repo composes this and optionally adds a framework layer —
8
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.
9
+ * applications. Plain Node packages (CLIs, code generators, SDKs) use `base`
10
+ * alone: every rule here is syntactic, so it runs without installing module
11
+ * dependencies.
12
+ *
13
+ * Formatting rules (quotes, eol-last, trailing spaces, ...) are deliberately
14
+ * absent: prettier owns formatting. `prettierConfig` is appended last so that
15
+ * composing a layer on top still ends on the formatting-rule shutdown.
12
16
  *
13
17
  * Repo-specific rules and ignores belong in the consumer's own
14
18
  * eslint.config.mjs, spread after this entry.
15
19
  */
16
- export default [...core, prettierConfig];
20
+ export default [
21
+ ...tseslint.configs.recommended,
22
+ {
23
+ rules: {
24
+ "@typescript-eslint/no-explicit-any": "off",
25
+ "@typescript-eslint/no-unused-vars": [
26
+ "error",
27
+ { argsIgnorePattern: "^_", varsIgnorePattern: "^_", caughtErrorsIgnorePattern: "^_" },
28
+ ],
29
+
30
+ // Code-quality rules carried over from the legacy gts-derived config.
31
+ "block-scoped-var": "error",
32
+ eqeqeq: ["error", "always", { null: "ignore" }],
33
+ "no-var": "error",
34
+ "prefer-const": "error",
35
+ "prefer-arrow-callback": "error",
36
+ "no-restricted-properties": [
37
+ "error",
38
+ { object: "describe", property: "only" },
39
+ { object: "it", property: "only" },
40
+ ],
41
+ },
42
+ },
43
+ prettierConfig,
44
+ ];
@@ -0,0 +1,5 @@
1
+ import type { Linter } from "eslint";
2
+
3
+ // Nest framework layer; compose after base ([...base, ...nest]).
4
+ declare const config: Linter.Config[];
5
+ export default config;
package/eslint/nest.js CHANGED
@@ -2,7 +2,7 @@ import nestjsTyped from "@darraghor/eslint-plugin-nestjs-typed";
2
2
  import prettierConfig from "eslint-config-prettier";
3
3
 
4
4
  /**
5
- * Nest.js layer for the devbie ecosystem.
5
+ * Nest layer for the devbie ecosystem.
6
6
  *
7
7
  * This is a layer, not a standalone standard: compose it after `base`
8
8
  * (`export default [...base, ...nest]`). Keeping it separable lets a
@@ -11,9 +11,10 @@ import prettierConfig from "eslint-config-prettier";
11
11
  *
12
12
  * The rule set is the plugin's recommended flat config. Four of those rules
13
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.
14
+ * TypeScript project (projectService resolves the nearest tsconfig.json). The
15
+ * plugin's own peer declarations bring what its rules expect (`class-validator`
16
+ * is referenced by name only — the rules never import it at lint runtime), and
17
+ * npm/pnpm auto-install those peers, so no extra install step is required.
17
18
  *
18
19
  * `prettierConfig` is repeated here so that composing `[...base, ...nest]`
19
20
  * still ends on the formatting-rule shutdown.
@@ -0,0 +1,5 @@
1
+ import type { Linter } from "eslint";
2
+
3
+ // Next.js framework layer; compose after base ([...base, ...next]).
4
+ declare const config: Linter.Config[];
5
+ export default config;
package/eslint/next.js CHANGED
@@ -24,6 +24,16 @@ import prettierConfig from "eslint-config-prettier";
24
24
  export default [
25
25
  ...nextVitals,
26
26
  ...nextTs,
27
+ {
28
+ files: ["**/eslint.config.*"],
29
+ rules: {
30
+ // eslint-config-next bundles eslint-plugin-import, whose
31
+ // no-anonymous-default-export warns on `export default [...]` — the
32
+ // canonical flat-config idiom. Switch it off for config files so
33
+ // consumers need no `const config = [...]; export default config;` shim.
34
+ "import/no-anonymous-default-export": "off",
35
+ },
36
+ },
27
37
  prettierConfig,
28
38
  // Framework-generated artifacts; consumers append their own ignores.
29
39
  globalIgnores([".next/**", "out/**", "build/**", "next-env.d.ts"]),
package/package.json CHANGED
@@ -1,15 +1,24 @@
1
1
  {
2
2
  "name": "@devbie/style-guide",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
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/base": "./eslint/base.js",
11
- "./eslint/nest": "./eslint/nest.js",
12
- "./eslint/next": "./eslint/next.js",
10
+ "./eslint/base": {
11
+ "types": "./eslint/base.d.ts",
12
+ "default": "./eslint/base.js"
13
+ },
14
+ "./eslint/nest": {
15
+ "types": "./eslint/nest.d.ts",
16
+ "default": "./eslint/nest.js"
17
+ },
18
+ "./eslint/next": {
19
+ "types": "./eslint/next.d.ts",
20
+ "default": "./eslint/next.js"
21
+ },
13
22
  "./package.json": "./package.json"
14
23
  },
15
24
  "files": [
@@ -27,7 +36,19 @@
27
36
  },
28
37
  "peerDependencies": {
29
38
  "eslint": "^9.0.0 || ^10.0.0",
39
+ "next": "^16.4.2",
30
40
  "prettier": "^3.9.9",
31
41
  "typescript": ">=5.0.0"
42
+ },
43
+ "peerDependenciesMeta": {
44
+ "next": {
45
+ "optional": true
46
+ }
47
+ },
48
+ "scripts": {
49
+ "test": "node --test"
50
+ },
51
+ "devDependencies": {
52
+ "next": "^16.4.2"
32
53
  }
33
54
  }
package/eslint/core.js DELETED
@@ -1,37 +0,0 @@
1
- import tseslint from "typescript-eslint";
2
-
3
- /**
4
- * Language-level baseline shared by every devbie codebase.
5
- *
6
- * Formatting rules (quotes, eol-last, trailing spaces, ...) are deliberately
7
- * absent: prettier owns formatting. Every public entry appends
8
- * eslint-config-prettier last so no plugin can re-enable eslint formatting
9
- * rules afterwards.
10
- *
11
- * Internal entry: consumers import `base` (or compose a layer such as
12
- * `nest` / `next` on top of it), never this file.
13
- */
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
- ],
23
-
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
- },
36
- },
37
- ];