@spectrabrain/eds 0.3.0 → 0.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.
@@ -16,10 +16,20 @@ export const conventionsFileName = "FRONTEND_CONVENTIONS.md";
16
16
  export const layerOrder = ["app", "pages", "widgets", "features", "entities", "shared"];
17
17
  // Layers whose second path segment is a slice (pages/<domain>, widgets/<name>, features/<domain>, entities/<domain>).
18
18
  export const slicedLayers = new Set(["pages", "widgets", "features", "entities"]);
19
- // src/ entries allowed besides the layers: MSW handlers, global declaration files and the file eds sync generates.
20
- export const auxiliarySourceDirectories = ["mocks", "types", "styles"];
19
+ // Existing auxiliary source directories accepted alongside the FSD layers.
20
+ export const auxiliarySourceDirectories = ["types", "styles"];
21
21
  export const allowedSourceRootFiles = ["vite-env.d.ts"];
22
22
  export const generatedStylesFileName = "eds-tokens.css";
23
+ export const maximumSupportedViteMajor = 8;
24
+ export const preservedResourceDirectoryNames = [
25
+ "i18n", "i18next", "intl", "locale", "locales", "lang", "language", "languages", "localization", "localizations",
26
+ "translation", "translations",
27
+ ];
28
+ export const preservedResourceDirectoryPattern = /^(?:i18n(?:ext)?|intl|locales?|languages?|lang|localizations?|translations?)(?:[A-Z][A-Za-z0-9]*|[-_.][^/]+)?$/i;
29
+ export const preservedResourceFilePattern = /^(?:i18n(?:ext)?|intl|locales?|languages?|lang|localizations?|translations?)(?:[A-Z][A-Za-z0-9]*|[-_.][^/]+)?\.(?:[^./]+(?:\.[^./]+)*)$/i;
30
+ export const preservedResourceHookPattern = /^use(?:translation|i18n|locale|language)[A-Za-z0-9_-]*\.[cm]?[jt]sx?$/i;
31
+ export const preservedMockPathPattern = /(?:^|\/)(?:__mocks__|mocks?)(?:\/|$)|(?:^|[._-])mocks?(?:[._-]|$)/i;
32
+ export const preservedMockCamelCaseFilePattern = /(?:^|[a-z0-9])Mocks?(?:[A-Z][A-Za-z0-9_-]*)?(?:\.[^./]+)+$|^[Mm]ock[A-Z][A-Za-z0-9_-]*(?:\.[^./]+)+$/;
23
33
 
24
34
  export const appEntries = ["main.tsx", "App.tsx", "providers", "router", "styles"];
25
35
  export const entitySegments = ["components", "hooks", "services", "stores", "types", "lib"];
@@ -78,9 +88,43 @@ export const requiredDevDependencies = [
78
88
  // Vite 8 moved Babel out of @vitejs/plugin-react; the React Compiler then runs through this plugin.
79
89
  export const rolldownBabelPackage = "@rolldown/plugin-babel";
80
90
  export const minimumMajors = { react: 19, "@tanstack/react-query": 5, tailwindcss: 4 };
91
+ export const minimumVersions = {
92
+ vite: "5.2.0",
93
+ nodeForVite8: "22.12.0",
94
+ pluginReactForVite5: "4.2.1",
95
+ pluginReactForVite6: "4.4.0",
96
+ pluginReactForVite7: "4.7.0",
97
+ pluginReactForVite8: "6.0.1",
98
+ tailwindViteForVite7: "4.2.0",
99
+ tailwindViteForVite8: "4.3.2",
100
+ babelCoreForVite8: "7.29.0",
101
+ rolldownPluginForVite8: "0.1.7",
102
+ reactCompilerForVite8: "1.0.0",
103
+ };
104
+
105
+ export function minimumPluginReactVersion(viteMajor) {
106
+ if (viteMajor === 8) {
107
+ return minimumVersions.pluginReactForVite8;
108
+ }
109
+ if (viteMajor !== null && viteMajor > maximumSupportedViteMajor) {
110
+ return null;
111
+ }
112
+ if (viteMajor === 7) return minimumVersions.pluginReactForVite7;
113
+ if (viteMajor === 6) return minimumVersions.pluginReactForVite6;
114
+ return minimumVersions.pluginReactForVite5;
115
+ }
116
+
117
+ export function minimumTailwindViteVersion(viteMajor) {
118
+ if (viteMajor === 7) return minimumVersions.tailwindViteForVite7;
119
+ if (viteMajor === 8) {
120
+ return minimumVersions.tailwindViteForVite8;
121
+ }
122
+ return null;
123
+ }
81
124
 
82
125
  // Install ranges the templates are written against. Packages without a range install at their latest version.
83
126
  export const installRanges = {
127
+ vite: "^5.2.0",
84
128
  eslint: "^9.22",
85
129
  "@eslint/js": "^9.22",
86
130
  "typescript-eslint": "^8",
@@ -90,6 +134,8 @@ export const installRanges = {
90
134
  "babel-plugin-react-compiler": "^1",
91
135
  tailwindcss: "^4",
92
136
  "@tailwindcss/vite": "^4",
137
+ "@babel/core": "^7.29.0",
138
+ "@rolldown/plugin-babel": "^0.2.0",
93
139
  "@types/react": "^19",
94
140
  "@types/react-dom": "^19",
95
141
  "@tanstack/react-query": "^5",
@@ -106,20 +152,20 @@ export const templateToolMinimums = {
106
152
  "eslint-plugin-react-refresh": "0.4.20",
107
153
  };
108
154
  // Installed with the tooling step although no check requires them: the templates reference them.
109
- export const templateDevDependencies = ["vite-plugin-svgr", "terser", "tw-animate-css", "msw"];
155
+ export const templateDevDependencies = ["vite-plugin-svgr", "terser", "tw-animate-css"];
110
156
  // The lucide-react version EDS depends on: a consumer that imports lucide-react directly declares the same one, so the
111
157
  // icon code is bundled once.
112
158
  export const edsLucideVersion = JSON.parse(fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), "..", "package.json"), "utf8")).dependencies?.["lucide-react"] ?? null;
113
- // Installed in step 6 only when the app calls a REST API that gets MSW handlers.
114
- export const mockDevDependencies = ["@faker-js/faker"];
115
-
116
- // Tests are outside the conventions: a prototype's test policy may change at any time. eds align neither requires,
117
- // replaces nor lists test tooling, and leaves test files, test directories and test setup files where they are.
118
- export const testDirectoryNames = ["test", "tests", "__tests__", "__mocks__"];
119
- export const testFilePattern = /\.(?:test|spec)\.[cm]?[jt]sx?$/;
120
- export const testSetupFilePattern = /^(?:setupTests|setup-tests|testSetup|test-setup|vitest\.setup|jest\.setup)\.[cm]?[jt]sx?$/;
159
+ // Recognize these paths only to keep existing test files and settings unchanged.
160
+ export const testDirectoryNames = ["test", "tests", "testing", "test-utils", "testutils", "test-helpers", "testhelpers", "spec", "specs", "__tests__", "__mocks__", "__snapshots__", "__fixtures__", "cypress", "e2e", "e2e-tests", "playwright"];
161
+ export const testFilePattern = /\.(?:test|spec|cy|e2e)\.[cm]?[jt]sx?$/i;
162
+ export const testSupportFilePattern = /^(?:test[-_.][^/]+|[^/]+[-_.](?:test|tests|spec|specs|cy|e2e))\.[cm]?[jt]sx?$/i;
163
+ export const testHelperFilePattern = /^(?:[Tt]est[A-Z][A-Za-z0-9_-]*|testutils|testhelpers|testsetup)\.[cm]?[jt]sx?$/;
164
+ export const testSetupFilePattern = /^(?:setupTests|setup-tests|testSetup|test-setup|vitest\.setup|jest\.setup)\.[cm]?[jt]sx?$/i;
165
+ export const testConfigFilePattern = /^(?:(?:vitest|jest|cypress|playwright|mocha|karma)(?:-[^/]+)?\.config\.[cm]?[jt]sx?|tsconfig(?:[-.](?:test|tests|spec|specs|e2e|cypress|playwright|vitest|jest))\.json)$/i;
121
166
  export const testToolingPattern =
122
- /^(?:jest|jest-.+|@jest\/.+|ts-jest|babel-jest|vitest|@vitest\/.+|@testing-library\/.+|cypress|@cypress\/.+|playwright|@playwright\/.+|happy-dom|jsdom|enzyme|enzyme-.+|identity-obj-proxy|mocha|chai|sinon|nock|supertest)$/;
167
+ /^(?:jest|jest-.+|@jest\/.+|ts-jest|babel-jest|vitest|vitest-.+|@vitest\/.+|@testing-library\/.+|cypress|@cypress\/.+|playwright|playwright-.+|@playwright\/.+|@storybook\/(?:test|test-runner|testing-library|addon-test|addon-vitest)|@axe-core\/.+|jest-axe|happy-dom|jsdom|enzyme|enzyme-.+|identity-obj-proxy|react-test-renderer|mocha|chai|sinon|nock|supertest|karma|karma-.+|jasmine|jasmine-core)$/;
168
+ export const preservedResourceDependencyPattern = /i18n|i18next|localization|translation|intl|formatjs|lingui|messageformat|msw|mock|mirage|faker/i;
123
169
 
124
170
  // Libraries a prototype often brings and the EVA standard that replaces each category.
125
171
  export const replacementRules = [
@@ -241,7 +287,6 @@ export const replacementRules = [
241
287
  { category: "toast", target: "sonner", packages: ["react-toastify", "react-hot-toast", "notistack"] },
242
288
  { category: "date", target: "date-fns", packages: ["moment", "moment-timezone", "dayjs", "luxon"] },
243
289
  { category: "virtual-list", target: "react-virtuoso", packages: ["react-window", "react-virtualized", "@tanstack/react-virtual"] },
244
- { category: "api-mock", target: "msw", packages: ["miragejs"] },
245
290
  {
246
291
  category: "lint-format",
247
292
  target: "ESLint flat config + Prettier",
@@ -402,7 +447,7 @@ export const backendScriptPattern =
402
447
  // Lockfiles at the repository root change when a workspace package installs dependencies.
403
448
  export const rootLockfiles = ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"];
404
449
 
405
- export const testSupportHint = "테스트 코드는 정렬 대상이 아니므로 그대로 둡니다";
450
+ export const preservedSourceHint = "기존 파일과 설정을 그대로 둡니다";
406
451
 
407
452
  // Where the usual prototype directories go. Keys are src/ top-level names (lower case).
408
453
  export const structureHints = {
@@ -449,20 +494,11 @@ export const structureHints = {
449
494
  config: "shared/lib/ · entities/<domain>/types/enums.ts",
450
495
  constants: "shared/lib/ · entities/<domain>/types/enums.ts",
451
496
  consts: "shared/lib/ · entities/<domain>/types/enums.ts",
452
- i18n: "shared/lib/ (기존 i18n 설정은 지우지 않고 옮깁니다. 새 문구는 「UI 문구」를 따릅니다)",
453
- locales: "shared/lib/ (기존 번역 파일은 지우지 않고 옮깁니다)",
454
- lang: "shared/lib/ (기존 번역 파일은 지우지 않고 옮깁니다)",
455
- translations: "shared/lib/ (기존 번역 파일은 지우지 않고 옮깁니다)",
456
- mocks: "mocks/<domain>/index.ts",
457
497
  integrations: "shared/api/ (backend client SDK)",
458
498
  "app.tsx": "app/App.tsx",
459
499
  "app.jsx": "app/App.tsx",
460
500
  "main.tsx": "app/main.tsx",
461
501
  "main.jsx": "app/main.tsx",
462
- "i18n.ts": "shared/lib/i18n.ts (기존 i18n 설정은 지우지 않고 옮깁니다)",
463
- "i18n.tsx": "shared/lib/i18n.ts (기존 i18n 설정은 지우지 않고 옮깁니다)",
464
- "i18n.js": "shared/lib/i18n.ts (기존 i18n 설정은 지우지 않고 옮깁니다)",
465
- "i18n.jsx": "shared/lib/i18n.ts (기존 i18n 설정은 지우지 않고 옮깁니다)",
466
502
  "index.tsx": "app/main.tsx",
467
503
  "index.jsx": "app/main.tsx",
468
504
  "index.css": "app/styles/index.css",