@trebired/code-discipline 0.1.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 (100) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/LICENSE +661 -0
  3. package/README.md +241 -0
  4. package/dist/checks/index.d.ts +4 -0
  5. package/dist/checks/index.d.ts.map +1 -0
  6. package/dist/checks/index.js +22 -0
  7. package/dist/checks/index.js.map +1 -0
  8. package/dist/checks/rules/folderize-compound-files.d.ts +5 -0
  9. package/dist/checks/rules/folderize-compound-files.d.ts.map +1 -0
  10. package/dist/checks/rules/folderize-compound-files.js +37 -0
  11. package/dist/checks/rules/folderize-compound-files.js.map +1 -0
  12. package/dist/checks/rules/max-file-lines.d.ts +5 -0
  13. package/dist/checks/rules/max-file-lines.d.ts.map +1 -0
  14. package/dist/checks/rules/max-file-lines.js +30 -0
  15. package/dist/checks/rules/max-file-lines.js.map +1 -0
  16. package/dist/checks/types.d.ts +64 -0
  17. package/dist/checks/types.d.ts.map +1 -0
  18. package/dist/checks/types.js +2 -0
  19. package/dist/checks/types.js.map +1 -0
  20. package/dist/cli/run-cli.d.ts +13 -0
  21. package/dist/cli/run-cli.d.ts.map +1 -0
  22. package/dist/cli/run-cli.js +104 -0
  23. package/dist/cli/run-cli.js.map +1 -0
  24. package/dist/cli.d.ts +5 -0
  25. package/dist/cli.d.ts.map +1 -0
  26. package/dist/cli.js +10 -0
  27. package/dist/cli.js.map +1 -0
  28. package/dist/config/index.d.ts +9 -0
  29. package/dist/config/index.d.ts.map +1 -0
  30. package/dist/config/index.js +49 -0
  31. package/dist/config/index.js.map +1 -0
  32. package/dist/config/normalize-check-options.d.ts +4 -0
  33. package/dist/config/normalize-check-options.d.ts.map +1 -0
  34. package/dist/config/normalize-check-options.js +14 -0
  35. package/dist/config/normalize-check-options.js.map +1 -0
  36. package/dist/config/normalize-rule-options.d.ts +14 -0
  37. package/dist/config/normalize-rule-options.d.ts.map +1 -0
  38. package/dist/config/normalize-rule-options.js +51 -0
  39. package/dist/config/normalize-rule-options.js.map +1 -0
  40. package/dist/config/normalize-source-options.d.ts +16 -0
  41. package/dist/config/normalize-source-options.d.ts.map +1 -0
  42. package/dist/config/normalize-source-options.js +24 -0
  43. package/dist/config/normalize-source-options.js.map +1 -0
  44. package/dist/config/normalize-sync-imports-options.d.ts +4 -0
  45. package/dist/config/normalize-sync-imports-options.d.ts.map +1 -0
  46. package/dist/config/normalize-sync-imports-options.js +34 -0
  47. package/dist/config/normalize-sync-imports-options.js.map +1 -0
  48. package/dist/imports/aliases.d.ts +9 -0
  49. package/dist/imports/aliases.d.ts.map +1 -0
  50. package/dist/imports/aliases.js +150 -0
  51. package/dist/imports/aliases.js.map +1 -0
  52. package/dist/imports/resolve.d.ts +7 -0
  53. package/dist/imports/resolve.d.ts.map +1 -0
  54. package/dist/imports/resolve.js +49 -0
  55. package/dist/imports/resolve.js.map +1 -0
  56. package/dist/imports/rewrite.d.ts +5 -0
  57. package/dist/imports/rewrite.d.ts.map +1 -0
  58. package/dist/imports/rewrite.js +139 -0
  59. package/dist/imports/rewrite.js.map +1 -0
  60. package/dist/imports/scan.d.ts +4 -0
  61. package/dist/imports/scan.d.ts.map +1 -0
  62. package/dist/imports/scan.js +44 -0
  63. package/dist/imports/scan.js.map +1 -0
  64. package/dist/imports/strategies.d.ts +7 -0
  65. package/dist/imports/strategies.d.ts.map +1 -0
  66. package/dist/imports/strategies.js +55 -0
  67. package/dist/imports/strategies.js.map +1 -0
  68. package/dist/imports/sync-imports.d.ts +4 -0
  69. package/dist/imports/sync-imports.d.ts.map +1 -0
  70. package/dist/imports/sync-imports.js +41 -0
  71. package/dist/imports/sync-imports.js.map +1 -0
  72. package/dist/imports/types.d.ts +104 -0
  73. package/dist/imports/types.d.ts.map +1 -0
  74. package/dist/imports/types.js +2 -0
  75. package/dist/imports/types.js.map +1 -0
  76. package/dist/index.d.ts +16 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +13 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/shared/constants.d.ts +18 -0
  81. package/dist/shared/constants.d.ts.map +1 -0
  82. package/dist/shared/constants.js +18 -0
  83. package/dist/shared/constants.js.map +1 -0
  84. package/dist/shared/errors.d.ts +34 -0
  85. package/dist/shared/errors.d.ts.map +1 -0
  86. package/dist/shared/errors.js +64 -0
  87. package/dist/shared/errors.js.map +1 -0
  88. package/dist/shared/logging-types.d.ts +18 -0
  89. package/dist/shared/logging-types.d.ts.map +1 -0
  90. package/dist/shared/logging-types.js +2 -0
  91. package/dist/shared/logging-types.js.map +1 -0
  92. package/dist/shared/logging.d.ts +5 -0
  93. package/dist/shared/logging.d.ts.map +1 -0
  94. package/dist/shared/logging.js +99 -0
  95. package/dist/shared/logging.js.map +1 -0
  96. package/dist/shared/utils.d.ts +24 -0
  97. package/dist/shared/utils.d.ts.map +1 -0
  98. package/dist/shared/utils.js +127 -0
  99. package/dist/shared/utils.js.map +1 -0
  100. package/package.json +54 -0
package/README.md ADDED
@@ -0,0 +1,241 @@
1
+ # @trebired/code-discipline
2
+
3
+ Configurable codebase discipline checks and import syncing for Bun and Node.js projects.
4
+
5
+ `@trebired/code-discipline` scans a configured source tree, runs project-level discipline rules, and can also keep TypeScript path aliases plus source imports aligned in one package.
6
+
7
+ The package is intentionally focused. It helps with repository structure rules, file-shape rules, and import hygiene. It does not try to be a full linter, formatter, or build system.
8
+
9
+ ## Install
10
+
11
+ Runtime support: Bun 1+ and Node.js 18+.
12
+
13
+ ```sh
14
+ npm install @trebired/code-discipline
15
+ ```
16
+
17
+ ## Quick Start
18
+
19
+ ```ts
20
+ import { checkCodeDiscipline } from "@trebired/code-discipline";
21
+
22
+ const result = await checkCodeDiscipline({
23
+ projectRoot: "/repo",
24
+ sourceRoot: "src",
25
+ rules: {
26
+ maxFileLines: {
27
+ enabled: true,
28
+ max: 500,
29
+ },
30
+ folderizeCompoundFiles: {
31
+ enabled: true,
32
+ suffixes: ["start", "service"],
33
+ separators: ["_", "-"],
34
+ },
35
+ },
36
+ });
37
+
38
+ if (!result.ok) {
39
+ console.error(result.violations);
40
+ process.exit(1);
41
+ }
42
+ ```
43
+
44
+ The first public slice is intentionally small:
45
+
46
+ - `checkCodeDiscipline()`
47
+ - `syncImports()`
48
+ - `defineCodeDisciplineConfig()`
49
+ - `loadCodeDisciplineConfig()`
50
+
51
+ If you want repo-driven usage instead of embedding the API directly, use the CLI with a top-level config file:
52
+
53
+ ```sh
54
+ code-discipline check
55
+ code-discipline sync
56
+ ```
57
+
58
+ ## What This Package Checks
59
+
60
+ The first discipline layer is intentionally narrow:
61
+
62
+ - `maxFileLines`
63
+ - `folderizeCompoundFiles`
64
+
65
+ `maxFileLines` reports files whose physical line count exceeds a configured threshold.
66
+
67
+ `folderizeCompoundFiles` reports names such as `user_start.ts` or `user-start.ts` that could be grouped into a more structured path such as `user/start.ts`.
68
+
69
+ Example:
70
+
71
+ ```ts
72
+ import { checkCodeDiscipline } from "@trebired/code-discipline";
73
+
74
+ const result = await checkCodeDiscipline({
75
+ projectRoot: "/repo",
76
+ rules: {
77
+ maxFileLines: {
78
+ enabled: true,
79
+ max: 500,
80
+ severity: "error",
81
+ },
82
+ folderizeCompoundFiles: {
83
+ enabled: true,
84
+ suffixes: ["start"],
85
+ separators: ["_", "-"],
86
+ severity: "warn",
87
+ },
88
+ },
89
+ });
90
+ ```
91
+
92
+ The result shape stays simple:
93
+
94
+ ```ts
95
+ {
96
+ ok: boolean;
97
+ warnings: number;
98
+ errors: number;
99
+ violations: Array<{
100
+ rule: "max-file-lines" | "folderize-compound-files";
101
+ severity: "warn" | "error";
102
+ filePath: string;
103
+ message: string;
104
+ details: Record<string, unknown>;
105
+ suggestedPath?: string;
106
+ }>;
107
+ }
108
+ ```
109
+
110
+ Checks are read-only. They report problems and let the caller decide whether to fail startup, fail CI, or only warn.
111
+
112
+ ## CLI And Config
113
+
114
+ The CLI is meant for repository-owned discipline rules:
115
+
116
+ ```sh
117
+ code-discipline check
118
+ code-discipline sync
119
+ ```
120
+
121
+ Both commands accept `--config <path>`. When that flag is omitted, the CLI looks for `code-discipline.config.json` in the current working directory.
122
+
123
+ Example config:
124
+
125
+ ```json
126
+ {
127
+ "sourceRoot": "src",
128
+ "rules": {
129
+ "maxFileLines": {
130
+ "enabled": true,
131
+ "max": 500
132
+ },
133
+ "folderizeCompoundFiles": {
134
+ "enabled": true,
135
+ "suffixes": ["start", "service"],
136
+ "separators": ["_", "-"]
137
+ },
138
+ "syncImports": {
139
+ "alias": {
140
+ "strategy": "relative-path-slug"
141
+ }
142
+ }
143
+ }
144
+ }
145
+ ```
146
+
147
+ `check` is read-only. It reports violations and exits non-zero when any error-severity rule fails.
148
+
149
+ `sync` is the mutating import-alignment command. It updates `compilerOptions.paths` and rewrites eligible source imports.
150
+
151
+ In practice:
152
+
153
+ - use JSON config plus the CLI when the rules belong to the repo
154
+ - use the API when another tool wants to control configuration or reporting dynamically
155
+
156
+ ## Import Sync
157
+
158
+ `syncImports()` remains a first-class part of the package. It scans source files, generates aliases, preserves still-valid alias ids, writes stable `compilerOptions.paths` output, and rewrites eligible relative imports to those aliases.
159
+
160
+ ```ts
161
+ import { syncImports } from "@trebired/code-discipline";
162
+
163
+ const result = await syncImports({
164
+ projectRoot: "/repo",
165
+ sourceRoot: "src",
166
+ tsconfigPath: "/repo/tsconfig.json",
167
+ });
168
+ ```
169
+
170
+ Default behavior:
171
+
172
+ - `sourceRoot: "src"`
173
+ - `tsconfigPath: "<projectRoot>/tsconfig.json"`
174
+ - `sourceExtensions: [".ts", ".tsx", ".js", ".jsx"]`
175
+ - `excludeDirs: ["node_modules", "dist", ".vite"]`
176
+ - `imports.rewrite: true`
177
+ - `imports.keepRelative: ["./"]`
178
+ - `alias.prefix: "#"`
179
+ - `alias.strategy: "random"`
180
+ - `alias.randomLength: 12`
181
+
182
+ By default, same-directory imports such as `./local` stay relative. Imports that walk upward, such as `../shared/util`, are eligible for rewrite when they resolve to a file under the configured source root.
183
+
184
+ Alias strategies:
185
+
186
+ - `"random"`
187
+ - `"relative-path-slug"`
188
+ - `"relative-path-hash"`
189
+ - custom function
190
+
191
+ Example custom strategy:
192
+
193
+ ```ts
194
+ await syncImports({
195
+ projectRoot: "/repo",
196
+ alias: {
197
+ strategy(input) {
198
+ return `@${input.relativeFromSourceRoot.replace(/\//g, "__")}`;
199
+ },
200
+ },
201
+ });
202
+ ```
203
+
204
+ If a custom strategy returns an invalid id or a duplicate id, the package fails clearly instead of guessing a fallback.
205
+
206
+ ## Why This Package
207
+
208
+ Many repository rules are awkward in a single-file linter pass because they are really about the shape of a source tree, not only one file at a time.
209
+
210
+ This package is a better fit when you want checks such as:
211
+
212
+ - file-size limits across a configured source root
213
+ - filename patterns that imply a cleaner folder layout
214
+ - path alias synchronization across many files
215
+ - startup, CI, or pre-build gates based on repository conventions
216
+
217
+ It is intentionally repo-oriented. The package does one lane of work: codebase discipline plus import alignment.
218
+
219
+ ## Current API
220
+
221
+ - `checkCodeDiscipline()`
222
+ - `defineCodeDisciplineConfig()`
223
+ - `loadCodeDisciplineConfig()`
224
+ - `syncImports()`
225
+ - `scanSourceFiles()`
226
+ - `syncTsconfigAliases()`
227
+ - `rewriteSourceImports()`
228
+ - `resolveRelativeImport()`
229
+ - `createRandomAlias()`
230
+ - `createRelativePathHashAlias()`
231
+ - `createRelativePathSlugAlias()`
232
+
233
+ The package also exports the public TypeScript types for options, results, violations, alias strategies, keep-relative callbacks, log events, and source scan rows.
234
+
235
+ ## What This Package Does Not Do
236
+
237
+ - it does not build or compile TypeScript
238
+ - it does not move files automatically for folderization violations
239
+ - it does not rewrite emitted build output
240
+ - it does not depend on ESLint
241
+ - it does not assume a framework-specific runtime layout
@@ -0,0 +1,4 @@
1
+ import type { CheckCodeDisciplineOptions, CheckCodeDisciplineResult } from "./types.js";
2
+ declare function checkCodeDiscipline(options: CheckCodeDisciplineOptions): Promise<CheckCodeDisciplineResult>;
3
+ export { checkCodeDiscipline };
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,0BAA0B,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAIxF,iBAAe,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAiB1G;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { normalizeCheckCodeDisciplineOptions } from "../config/normalize-check-options.js";
2
+ import { scanSourceFiles } from "../imports/scan.js";
3
+ import { runFolderizeCompoundFilesRule } from "./rules/folderize-compound-files.js";
4
+ import { runMaxFileLinesRule } from "./rules/max-file-lines.js";
5
+ async function checkCodeDiscipline(options) {
6
+ const normalized = await normalizeCheckCodeDisciplineOptions(options);
7
+ const sourceFiles = await scanSourceFiles(normalized);
8
+ const maxFileViolations = await runMaxFileLinesRule(sourceFiles, normalized);
9
+ const folderizeViolations = runFolderizeCompoundFilesRule(sourceFiles, normalized);
10
+ const violations = [...maxFileViolations, ...folderizeViolations]
11
+ .sort((left, right) => left.filePath.localeCompare(right.filePath) || left.rule.localeCompare(right.rule));
12
+ const warnings = violations.filter((violation) => violation.severity === "warn").length;
13
+ const errors = violations.length - warnings;
14
+ return {
15
+ ok: errors === 0,
16
+ warnings,
17
+ errors,
18
+ violations,
19
+ };
20
+ }
21
+ export { checkCodeDiscipline };
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/checks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mCAAmC,EAAE,MAAM,sCAAsC,CAAC;AAC3F,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,EAAE,6BAA6B,EAAE,MAAM,qCAAqC,CAAC;AACpF,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAEhE,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IACpE,MAAM,UAAU,GAAG,MAAM,mCAAmC,CAAC,OAAO,CAAC,CAAC;IACtE,MAAM,WAAW,GAAG,MAAM,eAAe,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,iBAAiB,GAAG,MAAM,mBAAmB,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAC7E,MAAM,mBAAmB,GAAG,6BAA6B,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAEnF,MAAM,UAAU,GAAG,CAAC,GAAG,iBAAiB,EAAE,GAAG,mBAAmB,CAAC;SAC9D,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7G,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACxF,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,QAAQ,CAAC;IAE5C,OAAO;QACL,EAAE,EAAE,MAAM,KAAK,CAAC;QAChB,QAAQ;QACR,MAAM;QACN,UAAU;KACX,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { CodeDisciplineViolation, NormalizedCheckCodeDisciplineOptions } from "../types.js";
2
+ import type { ScannedSourceFile } from "../../imports/types.js";
3
+ declare function runFolderizeCompoundFilesRule(sourceFiles: ScannedSourceFile[], options: NormalizedCheckCodeDisciplineOptions): CodeDisciplineViolation[];
4
+ export { runFolderizeCompoundFilesRule };
5
+ //# sourceMappingURL=folderize-compound-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folderize-compound-files.d.ts","sourceRoot":"","sources":["../../../src/checks/rules/folderize-compound-files.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,oCAAoC,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AA0ChE,iBAAS,6BAA6B,CACpC,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,oCAAoC,GAC5C,uBAAuB,EAAE,CAI3B;AAED,OAAO,EAAE,6BAA6B,EAAE,CAAC"}
@@ -0,0 +1,37 @@
1
+ import path from "node:path";
2
+ function matchFolderizedFile(file, options) {
3
+ if (!options.rules.folderizeCompoundFiles.enabled)
4
+ return null;
5
+ const basename = path.basename(file.relativeFromSourceRoot, file.extension);
6
+ for (const separator of options.rules.folderizeCompoundFiles.separators) {
7
+ for (const suffix of options.rules.folderizeCompoundFiles.suffixes) {
8
+ const token = `${separator}${suffix}`;
9
+ if (!basename.endsWith(token))
10
+ continue;
11
+ const stem = basename.slice(0, basename.length - token.length);
12
+ if (!stem)
13
+ continue;
14
+ const suggestedPath = path.posix.join(path.posix.dirname(file.relativeFromProjectRoot), stem, `${suffix}${file.extension}`);
15
+ return {
16
+ rule: "folderize-compound-files",
17
+ severity: options.rules.folderizeCompoundFiles.severity,
18
+ filePath: file.relativeFromProjectRoot,
19
+ message: `file can be grouped under ${suggestedPath}`,
20
+ suggestedPath,
21
+ details: {
22
+ separator,
23
+ suffix,
24
+ stem,
25
+ },
26
+ };
27
+ }
28
+ }
29
+ return null;
30
+ }
31
+ function runFolderizeCompoundFilesRule(sourceFiles, options) {
32
+ return sourceFiles
33
+ .map((file) => matchFolderizedFile(file, options))
34
+ .filter(Boolean);
35
+ }
36
+ export { runFolderizeCompoundFilesRule };
37
+ //# sourceMappingURL=folderize-compound-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folderize-compound-files.js","sourceRoot":"","sources":["../../../src/checks/rules/folderize-compound-files.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,SAAS,mBAAmB,CAC1B,IAAuB,EACvB,OAA6C;IAE7C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAE/D,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAE5E,KAAK,MAAM,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,UAAU,EAAE,CAAC;QACxE,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,QAAQ,EAAE,CAAC;YACnE,MAAM,KAAK,GAAG,GAAG,SAAS,GAAG,MAAM,EAAE,CAAC;YACtC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,SAAS;YAExC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;YAC/D,IAAI,CAAC,IAAI;gBAAE,SAAS;YAEpB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CACnC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,EAChD,IAAI,EACJ,GAAG,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAC7B,CAAC;YAEF,OAAO;gBACL,IAAI,EAAE,0BAA0B;gBAChC,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,QAAQ;gBACvD,QAAQ,EAAE,IAAI,CAAC,uBAAuB;gBACtC,OAAO,EAAE,6BAA6B,aAAa,EAAE;gBACrD,aAAa;gBACb,OAAO,EAAE;oBACP,SAAS;oBACT,MAAM;oBACN,IAAI;iBACL;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,6BAA6B,CACpC,WAAgC,EAChC,OAA6C;IAE7C,OAAO,WAAW;SACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;SACjD,MAAM,CAAC,OAAO,CAA8B,CAAC;AAClD,CAAC;AAED,OAAO,EAAE,6BAA6B,EAAE,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { CodeDisciplineViolation, NormalizedCheckCodeDisciplineOptions } from "../types.js";
2
+ import type { ScannedSourceFile } from "../../imports/types.js";
3
+ declare function runMaxFileLinesRule(sourceFiles: ScannedSourceFile[], options: NormalizedCheckCodeDisciplineOptions): Promise<CodeDisciplineViolation[]>;
4
+ export { runMaxFileLinesRule };
5
+ //# sourceMappingURL=max-file-lines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"max-file-lines.d.ts","sourceRoot":"","sources":["../../../src/checks/rules/max-file-lines.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,oCAAoC,EAAE,MAAM,aAAa,CAAC;AACjG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAOhE,iBAAe,mBAAmB,CAChC,WAAW,EAAE,iBAAiB,EAAE,EAChC,OAAO,EAAE,oCAAoC,GAC5C,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAwBpC;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,30 @@
1
+ import fs from "node:fs/promises";
2
+ function countLines(text) {
3
+ if (text.length === 0)
4
+ return 0;
5
+ return text.split(/\r?\n/).length;
6
+ }
7
+ async function runMaxFileLinesRule(sourceFiles, options) {
8
+ if (!options.rules.maxFileLines.enabled)
9
+ return [];
10
+ const violations = [];
11
+ for (const file of sourceFiles) {
12
+ const text = await fs.readFile(file.absolutePath, "utf8");
13
+ const lineCount = countLines(text);
14
+ if (lineCount <= options.rules.maxFileLines.max)
15
+ continue;
16
+ violations.push({
17
+ rule: "max-file-lines",
18
+ severity: options.rules.maxFileLines.severity,
19
+ filePath: file.relativeFromProjectRoot,
20
+ message: `file has ${lineCount} lines and exceeds the limit of ${options.rules.maxFileLines.max}`,
21
+ details: {
22
+ lineCount,
23
+ max: options.rules.maxFileLines.max,
24
+ },
25
+ });
26
+ }
27
+ return violations;
28
+ }
29
+ export { runMaxFileLinesRule };
30
+ //# sourceMappingURL=max-file-lines.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"max-file-lines.js","sourceRoot":"","sources":["../../../src/checks/rules/max-file-lines.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAKlC,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IAChC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;AACpC,CAAC;AAED,KAAK,UAAU,mBAAmB,CAChC,WAAgC,EAChC,OAA6C;IAE7C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAEnD,MAAM,UAAU,GAA8B,EAAE,CAAC;IAEjD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC1D,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;QAEnC,IAAI,SAAS,IAAI,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG;YAAE,SAAS;QAE1D,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,gBAAgB;YACtB,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ;YAC7C,QAAQ,EAAE,IAAI,CAAC,uBAAuB;YACtC,OAAO,EAAE,YAAY,SAAS,mCAAmC,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;YACjG,OAAO,EAAE;gBACP,SAAS;gBACT,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG;aACpC;SACF,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,OAAO,EAAE,mBAAmB,EAAE,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type { SourceScanOptions, SyncImportsOptions } from "../imports/types.js";
2
+ type CodeDisciplineRuleSeverity = "warn" | "error";
3
+ type SyncImportsRuleOptions = Omit<SyncImportsOptions, "projectRoot"> & {
4
+ enabled?: boolean;
5
+ };
6
+ type MaxFileLinesRuleOptions = {
7
+ enabled?: boolean;
8
+ max?: number;
9
+ severity?: CodeDisciplineRuleSeverity;
10
+ };
11
+ type FolderizeCompoundFilesRuleOptions = {
12
+ enabled?: boolean;
13
+ separators?: string[];
14
+ suffixes?: string[];
15
+ severity?: CodeDisciplineRuleSeverity;
16
+ };
17
+ type CodeDisciplineRules = {
18
+ maxFileLines?: MaxFileLinesRuleOptions;
19
+ folderizeCompoundFiles?: FolderizeCompoundFilesRuleOptions;
20
+ syncImports?: SyncImportsRuleOptions;
21
+ };
22
+ type CheckCodeDisciplineOptions = {
23
+ projectRoot: string;
24
+ sourceRoot?: string;
25
+ sourceExtensions?: string[];
26
+ excludeDirs?: string[];
27
+ rules?: CodeDisciplineRules;
28
+ };
29
+ type CodeDisciplineConfig = Omit<CheckCodeDisciplineOptions, "projectRoot">;
30
+ type NormalizedMaxFileLinesRule = {
31
+ enabled: boolean;
32
+ max: number;
33
+ severity: CodeDisciplineRuleSeverity;
34
+ };
35
+ type NormalizedFolderizeCompoundFilesRule = {
36
+ enabled: boolean;
37
+ separators: string[];
38
+ suffixes: string[];
39
+ severity: CodeDisciplineRuleSeverity;
40
+ };
41
+ type NormalizedCheckCodeDisciplineOptions = SourceScanOptions & {
42
+ sourceRootRelative: string;
43
+ rules: {
44
+ maxFileLines: NormalizedMaxFileLinesRule;
45
+ folderizeCompoundFiles: NormalizedFolderizeCompoundFilesRule;
46
+ };
47
+ };
48
+ type CodeDisciplineRuleName = "max-file-lines" | "folderize-compound-files";
49
+ type CodeDisciplineViolation = {
50
+ rule: CodeDisciplineRuleName;
51
+ severity: CodeDisciplineRuleSeverity;
52
+ filePath: string;
53
+ message: string;
54
+ details: Record<string, unknown>;
55
+ suggestedPath?: string;
56
+ };
57
+ type CheckCodeDisciplineResult = {
58
+ ok: boolean;
59
+ warnings: number;
60
+ errors: number;
61
+ violations: CodeDisciplineViolation[];
62
+ };
63
+ export type { CheckCodeDisciplineOptions, CheckCodeDisciplineResult, CodeDisciplineConfig, CodeDisciplineRuleName, CodeDisciplineRuleSeverity, CodeDisciplineRules, CodeDisciplineViolation, FolderizeCompoundFilesRuleOptions, MaxFileLinesRuleOptions, NormalizedCheckCodeDisciplineOptions, NormalizedFolderizeCompoundFilesRule, NormalizedMaxFileLinesRule, SyncImportsRuleOptions, };
64
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/checks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEjF,KAAK,0BAA0B,GAAG,MAAM,GAAG,OAAO,CAAC;AAEnD,KAAK,sBAAsB,GAAG,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,GAAG;IACtE,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,0BAA0B,CAAC;CACvC,CAAC;AAEF,KAAK,iCAAiC,GAAG;IACvC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,CAAC,EAAE,0BAA0B,CAAC;CACvC,CAAC;AAEF,KAAK,mBAAmB,GAAG;IACzB,YAAY,CAAC,EAAE,uBAAuB,CAAC;IACvC,sBAAsB,CAAC,EAAE,iCAAiC,CAAC;IAC3D,WAAW,CAAC,EAAE,sBAAsB,CAAC;CACtC,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF,KAAK,oBAAoB,GAAG,IAAI,CAAC,0BAA0B,EAAE,aAAa,CAAC,CAAC;AAE5E,KAAK,0BAA0B,GAAG;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,0BAA0B,CAAC;CACtC,CAAC;AAEF,KAAK,oCAAoC,GAAG;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,0BAA0B,CAAC;CACtC,CAAC;AAEF,KAAK,oCAAoC,GAAG,iBAAiB,GAAG;IAC9D,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,EAAE;QACL,YAAY,EAAE,0BAA0B,CAAC;QACzC,sBAAsB,EAAE,oCAAoC,CAAC;KAC9D,CAAC;CACH,CAAC;AAEF,KAAK,sBAAsB,GAAG,gBAAgB,GAAG,0BAA0B,CAAC;AAE5E,KAAK,uBAAuB,GAAG;IAC7B,IAAI,EAAE,sBAAsB,CAAC;IAC7B,QAAQ,EAAE,0BAA0B,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,uBAAuB,EAAE,CAAC;CACvC,CAAC;AAEF,YAAY,EACV,0BAA0B,EAC1B,yBAAyB,EACzB,oBAAoB,EACpB,sBAAsB,EACtB,0BAA0B,EAC1B,mBAAmB,EACnB,uBAAuB,EACvB,iCAAiC,EACjC,uBAAuB,EACvB,oCAAoC,EACpC,oCAAoC,EACpC,0BAA0B,EAC1B,sBAAsB,GACvB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/checks/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ type CliRunOptions = {
3
+ cwd?: string;
4
+ stdout?: (text: string) => void;
5
+ stderr?: (text: string) => void;
6
+ };
7
+ type CliRunResult = {
8
+ exitCode: number;
9
+ };
10
+ declare function runCli(argv: string[], options?: CliRunOptions): Promise<CliRunResult>;
11
+ export { runCli };
12
+ export type { CliRunOptions, CliRunResult };
13
+ //# sourceMappingURL=run-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-cli.d.ts","sourceRoot":"","sources":["../../src/cli/run-cli.ts"],"names":[],"mappings":";AAUA,KAAK,aAAa,GAAG;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAyDF,iBAAe,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAuDxF;AAQD,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC"}
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ import { pathToFileURL } from "node:url";
3
+ import { checkCodeDiscipline } from "../checks/index.js";
4
+ import { loadCodeDisciplineConfig } from "../config/index.js";
5
+ import { syncImports } from "../imports/sync-imports.js";
6
+ function renderHelp() {
7
+ return [
8
+ "Usage: code-discipline <command> [--config <path>]",
9
+ "",
10
+ "Commands:",
11
+ " check run configured discipline checks",
12
+ " sync sync tsconfig aliases and rewrite imports",
13
+ "",
14
+ ].join("\n");
15
+ }
16
+ function parseArgs(args) {
17
+ let configPath;
18
+ const extra = [];
19
+ for (let index = 0; index < args.length; index += 1) {
20
+ const arg = args[index];
21
+ if (arg === "--config") {
22
+ const value = args[index + 1];
23
+ if (!value) {
24
+ throw new Error("Missing value for --config");
25
+ }
26
+ configPath = value;
27
+ index += 1;
28
+ continue;
29
+ }
30
+ extra.push(arg);
31
+ }
32
+ return { configPath, extra };
33
+ }
34
+ function buildSyncImportsOptions(projectRoot, config) {
35
+ const { enabled: _enabled, ...syncRule } = config.rules?.syncImports ?? {};
36
+ return {
37
+ projectRoot,
38
+ sourceRoot: syncRule.sourceRoot ?? config.sourceRoot,
39
+ tsconfigPath: syncRule.tsconfigPath,
40
+ sourceExtensions: syncRule.sourceExtensions ?? config.sourceExtensions,
41
+ excludeDirs: syncRule.excludeDirs ?? config.excludeDirs,
42
+ alias: syncRule.alias,
43
+ imports: syncRule.imports,
44
+ logging: syncRule.logging,
45
+ };
46
+ }
47
+ function formatViolation(violation) {
48
+ const suggested = violation.suggestedPath ? ` suggested=${violation.suggestedPath}` : "";
49
+ return `${violation.severity.toUpperCase()} ${violation.rule} ${violation.filePath} ${violation.message}${suggested}`;
50
+ }
51
+ async function runCli(argv, options = {}) {
52
+ const cwd = options.cwd ?? process.cwd();
53
+ const stdout = options.stdout ?? ((text) => process.stdout.write(text));
54
+ const stderr = options.stderr ?? ((text) => process.stderr.write(text));
55
+ const [command, ...rest] = argv;
56
+ if (!command || command === "help" || command === "--help" || command === "-h") {
57
+ stdout(renderHelp());
58
+ return { exitCode: 0 };
59
+ }
60
+ try {
61
+ const parsed = parseArgs(rest);
62
+ if (parsed.extra.length > 0) {
63
+ throw new Error(`Unexpected arguments: ${parsed.extra.join(" ")}`);
64
+ }
65
+ const { config } = await loadCodeDisciplineConfig(cwd, parsed.configPath);
66
+ if (command === "check") {
67
+ const result = await checkCodeDiscipline({
68
+ projectRoot: cwd,
69
+ sourceRoot: config.sourceRoot,
70
+ sourceExtensions: config.sourceExtensions,
71
+ excludeDirs: config.excludeDirs,
72
+ rules: config.rules,
73
+ });
74
+ if (result.violations.length === 0) {
75
+ stdout("No discipline violations found.\n");
76
+ return { exitCode: 0 };
77
+ }
78
+ for (const violation of result.violations) {
79
+ stdout(`${formatViolation(violation)}\n`);
80
+ }
81
+ stdout(`Summary: ${result.errors} errors, ${result.warnings} warnings.\n`);
82
+ return { exitCode: result.ok ? 0 : 1 };
83
+ }
84
+ if (command === "sync") {
85
+ const result = await syncImports(buildSyncImportsOptions(cwd, config));
86
+ stdout(`${JSON.stringify(result)}\n`);
87
+ return { exitCode: 0 };
88
+ }
89
+ stderr(`Unknown command: ${command}\n`);
90
+ stderr(renderHelp());
91
+ return { exitCode: 1 };
92
+ }
93
+ catch (error) {
94
+ stderr(`${error instanceof Error ? error.message : String(error)}\n`);
95
+ return { exitCode: 1 };
96
+ }
97
+ }
98
+ const entryPath = process.argv[1] ? pathToFileURL(process.argv[1]).href : null;
99
+ if (entryPath && import.meta.url === entryPath) {
100
+ const result = await runCli(process.argv.slice(2));
101
+ process.exitCode = result.exitCode;
102
+ }
103
+ export { runCli };
104
+ //# sourceMappingURL=run-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-cli.js","sourceRoot":"","sources":["../../src/cli/run-cli.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "./cli/run-cli.js";
3
+ export { runCli };
4
+ export type { CliRunOptions, CliRunResult } from "./cli/run-cli.js";
5
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAQ1C,OAAO,EAAE,MAAM,EAAE,CAAC;AAClB,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/cli.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { pathToFileURL } from "node:url";
3
+ import { runCli } from "./cli/run-cli.js";
4
+ const entryPath = process.argv[1] ? pathToFileURL(process.argv[1]).href : null;
5
+ if (entryPath && import.meta.url === entryPath) {
6
+ const result = await runCli(process.argv.slice(2));
7
+ process.exitCode = result.exitCode;
8
+ }
9
+ export { runCli };
10
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/E,IAAI,SAAS,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;IAC/C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;AACrC,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { CodeDisciplineConfig } from "../checks/types.js";
2
+ type LoadedCodeDisciplineConfig = {
3
+ config: CodeDisciplineConfig;
4
+ configPath: string | null;
5
+ };
6
+ declare function defineCodeDisciplineConfig(config: CodeDisciplineConfig): CodeDisciplineConfig;
7
+ declare function loadCodeDisciplineConfig(projectRoot: string, configPath?: string): Promise<LoadedCodeDisciplineConfig>;
8
+ export { defineCodeDisciplineConfig, loadCodeDisciplineConfig };
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAK/D,KAAK,0BAA0B,GAAG;IAChC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,iBAAS,0BAA0B,CAAC,MAAM,EAAE,oBAAoB,GAAG,oBAAoB,CAEtF;AAsBD,iBAAe,wBAAwB,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAwBrH;AAED,OAAO,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,CAAC"}