@axis-ds/cli 1.7.4 → 1.7.6
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 +9 -4
- package/dist/{chunk-YYSEFWYD.js → chunk-I3HWV7Y5.js} +48 -1
- package/dist/index.js +224 -63
- package/dist/monet.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ axis list
|
|
|
48
48
|
- `utils.ts` 가 이미 있으면 같은 내용이면 「유지(이미 같은 내용)」(다시 쓰지 않음), 다르면 init 의 utils 로 덮어쓰고 「덮어씀」으로 알립니다(터미널이 아닌 곳에서 `-y` 없이 실행하면 덮어쓰지 않고 rc 1, 아래 「터미널이 아닌 곳에서 실행」). `utils.ts` 쓰기는 `axis add` 와 같은 규칙입니다: 심볼릭 링크면 같은 내용일 때 「유지(이미 같은 내용, 링크)」로 두고, 내용이 다른 링크(프로젝트 안 · 밖) · 깨진 링크 · 디렉터리 · 읽을 수 없는 파일 · 다른 경로와 하드링크로 이어진 파일은 쓰지 않고 그 사실을 알린 뒤 rc 1 입니다. 이 판정은 쓰기 전에 하므로 이때는 `axis.config.json` · `package.json` 도 쓰지 않습니다. 다른 경로와 하드링크로 이어진 `axis.config.json` 을 다시 써야 할 때도 같습니다.
|
|
49
49
|
- 경로 기본값(`-y` 값 · 대화형 초기값)은 실제 프로젝트를 보고 정합니다(1.6.0 부터). `componentsDir` 는 `src/` 가 있으면 `./src/components/ui`, 없으면 `./components/ui` 이고 `src/` 를 새로 만들지 않습니다. `globalCss` 는 `app/globals.css` · `src/app/globals.css` · `styles/globals.css` · `src/styles/globals.css` · `globals.css` 가운데 실제로 있는 첫 파일, `tailwindConfig` 는 있는 `tailwind.config.{ts,js,mjs,cjs}` 가운데 첫 파일입니다. 찾지 못하면 기본값을 기록하고 그 사실을 한 줄 알립니다. Tailwind 4 안내 제목도 이 경로를 씁니다.
|
|
50
50
|
- config 가 이미 있으면 출력이 「생성 완료」가 아니라 사실대로 「유지(이미 같은 내용)」 또는 「갱신」입니다. 갱신은 init 이 다루는 키(`$schema` · `componentsDir` · `tailwindConfig` · `globalCss` · `registry`)만 바꾸고, 그 밖의 키(`brand` · `monetDir` · `template` · `agenticDir` 등)는 값과 순서를 그대로 둡니다(1.6.0 부터, 이전에는 빠졌음). 들여쓰기도 기존 파일을 따릅니다. 기존 `componentsDir` 는 그대로 두고, `globalCss` · `tailwindConfig` 는 가리키는 파일이 있으면 그대로, 없으면 찾은 파일로 바꾸고 알립니다(찾지 못하면 그대로 두고 알림). Tailwind 4 이상이면 `tailwindConfig` 를 지우고 알립니다. `registry` 가 종전 기본값이면 위처럼 새 기본값으로 바꿉니다. `AXIS_REGISTRY_URL` 은 config 에 기록하지 않고 add · list 를 실행할 때만 우선합니다.
|
|
51
|
-
- 애니메이션 플러그인(`tailwindcss-animate` · `tw-animate-css`)이 `package.json` 에 없으면, Dialog · Select 등의 열고 닫는 애니메이션에 필요하다는 안내 한 줄을 냅니다(Tailwind 3 은 plugins, Tailwind 4 는 `@import "tw-animate-css";`).
|
|
51
|
+
- 애니메이션 플러그인(`tailwindcss-animate` · `tw-animate-css`)이 `package.json` 에 없으면, Dialog · Select 등의 열고 닫는 애니메이션에 필요하다는 안내 한 줄을 냅니다(Tailwind 3 은 plugins, Tailwind 4 는 `@import "tw-animate-css";`). 1.7.5 부터 선언은 앱 다음 워크스페이스 루트 `package.json` 까지 보고, 이름은 `axis check` 와 같습니다(Tailwind 3 은 `tailwindcss-animate` 만, Tailwind 4 는 `tw-animate-css` · `tailwindcss-animate` 둘 다). 선언과 설치본이 모두 있으면 안내하지 않고, 선언만 있고 설치본이 없으면 「선언돼 있지만 설치되지 않았습니다」와 설치 명령 · 설정 줄을 냅니다. Yarn PnP 는 루트 선언을 인정하지 않고 앱 선언이 있으면 안내하지 않습니다.
|
|
52
52
|
- `tailwind-merge` 범위와 아래 안내는 프로젝트의 Tailwind 버전(설치본, 없으면 `package.json` 선언)으로 정합니다. 판정하지 못하면 Tailwind 3 으로 봅니다.
|
|
53
53
|
- Tailwind 4 이상이면 전역 CSS 에 넣을 줄을 안내합니다. CSS 파일은 고치지 않습니다.
|
|
54
54
|
|
|
@@ -83,11 +83,14 @@ axis theme info ontology
|
|
|
83
83
|
axis theme add ontology
|
|
84
84
|
```
|
|
85
85
|
|
|
86
|
-
- `axis theme add` 는 `axis.config.json` 의 `globalCss` → `app/globals.css` → `src/app/globals.css` → `styles/globals.css` → `src/styles/globals.css` → 루트 `globals.css` 순으로 찾은 파일의 앞쪽 import 구간 끝(`@tailwind` 등 규칙보다 앞)에 줄을 넣습니다. 1.6.0 부터 브랜드 import 앞에 기본 토큰 CSS 도 넣습니다: Tailwind 3 은 `@axis-ds/tokens/css` · `@axis-ds/tokens/css/shadcn`, Tailwind 4 는 `@axis-ds/tokens/css/tailwind4` 와 `package.json` 에 선언된 `@axis-ds/ui-react` · `@axis-ds/agentic-ui` 의 `tailwind.css` 입니다. 이미 있는 줄은 다시 넣지 않으므로 여러 번 실행해도 같습니다. 규칙 뒤에 있는 기존 `@import` 는 CSS 규칙상 무시될 수 있어 맨 앞으로 옮기라고 알립니다(Next.js 15 는 위치와 관계없이 앞으로 끌어올려 적용함을 측정).
|
|
86
|
+
- `axis theme add` 는 `axis.config.json` 의 `globalCss` → `app/globals.css` → `src/app/globals.css` → `styles/globals.css` → `src/styles/globals.css` → 루트 `globals.css` 순으로 찾은 파일의 앞쪽 import 구간 끝(`@tailwind` 등 규칙보다 앞)에 줄을 넣습니다. 1.6.0 부터 브랜드 import 앞에 기본 토큰 CSS 도 넣습니다: Tailwind 3 은 `@axis-ds/tokens/css` · `@axis-ds/tokens/css/shadcn`, Tailwind 4 는 `@axis-ds/tokens/css/tailwind4` 와 `package.json` 에 선언된 `@axis-ds/ui-react` · `@axis-ds/agentic-ui` 의 `tailwind.css` 입니다. 1.7.5 부터 워크스페이스 루트에만 선언한 패키지는 설치본에 `tailwind.css` 가 실제로 있을 때만 넣고, 없으면(미설치 · 1.4.0 미만) 넣지 않은 이유를 한 줄로 알립니다. 이미 있는 줄은 다시 넣지 않으므로 여러 번 실행해도 같습니다. 규칙 뒤에 있는 기존 `@import` 는 CSS 규칙상 무시될 수 있어 맨 앞으로 옮기라고 알립니다(Next.js 15 는 위치와 관계없이 앞으로 끌어올려 적용함을 측정).
|
|
87
87
|
- `package.json` 에 `@axis-ds/tokens` 가 없으면 `dependencies` 에 `^1.6.0`(1.6.0 부터, 이전에는 `^1.3.0`)을 더하고 설치 명령만 안내합니다. 설치는 실행하지 않습니다. 설치 · 업그레이드 안내 명령은 lockfile 로 고릅니다(`npm install` · `yarn add` · `pnpm add`). lockfile 이 없으면 `package.json` 의 `packageManager`(`npm@…` · `yarn@…` · `pnpm@…`)를 보고, 둘 다 없으면 `pnpm` 입니다(1.7.2 부터 `packageManager` 를 봄).
|
|
88
|
+
- 1.7.5 부터 `@axis-ds/tokens` 가 워크스페이스 루트 `package.json`(`dependencies` · `devDependencies`)에 선언돼 있으면 앱 `package.json` 에 쓰지 않고 「워크스페이스 루트에 선언돼 있어 앱 package.json 은 바꾸지 않음」으로 알립니다. 설치본이 없으면 설치 명령을, 업그레이드 안내 때는 루트 선언을 올리라는 줄을 더합니다. 루트에 `@axis-ds/theme` 가 있으면 ThemeProvider 설치 안내를 내지 않습니다. 앱만 따로 운영 설치 · 배포하면 루트 선언이 따라가지 않으니 앱에 직접 선언합니다. Yarn PnP 와 앱 디렉터리에 자체 lockfile 이 있는 앱은 루트 선언을 보지 않습니다(종전).
|
|
88
89
|
- 브랜드 CSS 는 `[data-brand="<brand>"]` 선택자로 적용되므로 루트 레이아웃의 `<html data-brand>` 나 `ThemeProvider` 의 `setBrand` 가 있어야 화면이 바뀝니다. 코드는 고치지 않고, 레이아웃에서 찾지 못하면 두 방법의 예시를 냅니다(`defaultBrand` 는 `@axis-ds/theme` 1.6.2 이하에서 `setBrand(undefined)` 로 끈 상태가 새로고침 뒤 유지되지 않아 예시에 쓰지 않습니다). 마크업 `data-brand` 와 `ThemeProvider` 를 함께 쓰는 레이아웃이면 theme 1.7.0 이상이 필요하다고 한 줄 더 알립니다(1.6.1 부터). Tailwind 3 이면 preset · content 가 빠졌을 때 넣을 줄도 안내합니다(설정 파일은 고치지 않음). preset 안내는 1.6.1 부터 CommonJS 에서 모든 tokens 버전에 되는 `require("@axis-ds/tokens/tailwind").default` 입니다(1.6.0 의 `.default` 없는 형태는 tokens 1.6.2 이하에서 preset 이 빠짐).
|
|
89
90
|
- 넣은 import 줄의 출력은 1.6.1 부터 실제 위치 · 분류를 따릅니다. 컴포넌트 `tailwind.css` 는 「컴포넌트 스캔 경로, 위치 무관」, 기본 토큰 CSS 는 브랜드 줄보다 앞에 들어갔을 때만 「브랜드 앞」이고 뒤에 들어가면 옮기라고 경고합니다.
|
|
90
91
|
- `@axis-ds/tokens` 가 없거나 1.3.0 미만이면 목록 대신 설치 · 업그레이드 안내를 내고 종료 코드 1 로 끝납니다.
|
|
92
|
+
- 1.7.6 부터 `theme list` · `theme info` 의 안내는 선언 출처를 따릅니다. 앱이나 pnpm · yarn 워크스페이스 루트에 선언돼 있으면 「설치: <pm> install」, npm 워크스페이스 루트에 선언돼 있으면 「설치: 워크스페이스 루트에서 npm install」, 루트 선언이 1.3.0 미만이면 루트 선언을 올리라는 줄, 빌드 전 재설치도 install 입니다. Yarn PnP 에서 앱에 선언이 있으면 설치본을 판정하지 못했다는 한 줄을 냅니다. 선언이 없으면(또는 PnP · 앱 자체 lockfile 이라 루트 선언을 보지 않으면) 종전 추가 명령입니다.
|
|
93
|
+
- 같은 1.7.6 부터 `theme add` 는 앱에 선언된 tokens 가 설치되지 않았으면 「설치: <pm> install」을, 설치본이 빌드 전이면 선언 출처(앱 · 루트)와 상관없이 `theme list` 와 같은 재설치 안내(npm 워크스페이스 루트 선언이면 「워크스페이스 루트에서 npm install」)를 더합니다. Yarn PnP 에서 앱에 선언이 있으면 설치 · 재설치 · 업그레이드 줄 대신 `theme list` 와 같은 판정하지 못했다는 한 줄을 냅니다. 루트 선언 미설치의 「설치: <pm> install」 줄은 npm 이어도 앱 디렉터리 명령 그대로입니다.
|
|
91
94
|
- `axis check` 는 `axis.config.json` 의 `brand` 와 CSS 의 브랜드 import 가 맞는지도 봅니다.
|
|
92
95
|
|
|
93
96
|
## 프로젝트 검증 (`axis check`)
|
|
@@ -105,10 +108,12 @@ axis theme add ontology
|
|
|
105
108
|
- Tailwind 3 CommonJS(1.6.1 부터): 설정이 `.cjs` 이거나 `module.exports` 를 쓰고 `.default` 없는 `require("@axis-ds/tokens/tailwind")` 가 있으면, 설치본(없으면 선언 하한) `@axis-ds/tokens` 가 1.7.0 미만일 때 WARN 입니다. 1.6.2 이하의 이 형태는 preset 이 아니라 `{ default }` 를 받아 색 · keyframes 가 빠집니다(1.1.0 부터). `.ts` · `.mjs` 의 `export default` 안 `require` 와 `import` 형태는 Tailwind 가 `.default` 를 꺼내 줘서 PASS 입니다.
|
|
106
109
|
- globals.css 항목: 같은 후보에서 처음 찾은 CSS 하나를 봅니다. 1.6.1 부터 AXIS 근거가 있을 때만 PASS 입니다: `@axis-ds/tokens/css` · `@axis-ds/tokens/css/shadcn` · `@axis-ds/tokens/css/tailwind4` import(블록 주석 밖, 작은따옴표 · `url()` · `layer()` 표기 포함, 문구 끝에 `(@axis-ds/tokens/css/tailwind4 import)` 처럼 경로), `--axis-*` 변수 정의, 또는 루트 레이아웃(`app/layout.tsx` 등)의 `import "@axis-ds/tokens/css"`. 자체 `--background` · `--primary` 만 있으면 「자체 CSS 변수만 있고 AXIS 토큰이 없습니다」 WARN 입니다(1.6.0 까지는 PASS). Tailwind 3 에서 create-next-app 기본 `body` 의 `font-family: Arial` 이 남아 있으면 PASS 조건을 채워도 WARN 입니다(Tailwind 4 는 tailwind.config 항목의 create-next-app 기본 정의로 냅니다).
|
|
107
110
|
- dependencies 항목(1.6.1 부터): `tailwindcss` 선언이 없으면 FAIL, `clsx` · `tailwind-merge` 선언이 없으면 WARN(종전과 같음). 여기에 선언된 `tailwindcss` · `clsx` · `tailwind-merge` · `@axis-ds/*` 가 `node_modules` 에 없으면 「선언됐지만 설치되지 않은 의존성」 WARN 과 lockfile 에 맞는 설치 명령을 냅니다. 상위 디렉터리의 `node_modules`(모노레포 호이스팅)도 찾고, Plug'n'Play(`.pnp.cjs`)는 설치본을 읽지 않고 선언 기준입니다. 1.6.0 까지는 선언만 보고 「모두 설치되어 있습니다」였습니다.
|
|
111
|
+
- 1.7.6 부터 워크스페이스 루트 `package.json` 에 선언한 `@axis-ds/*`(앱에 없는 것)도 설치 확인 대상이고, 설치되지 않았으면 「워크스페이스 루트에 선언돼 있지만 설치되지 않았습니다」 WARN 입니다(종료 코드는 그대로, 1.7.5 까지는 앱 선언만 봐서 PASS).
|
|
112
|
+
- 1.7.6 부터 Plug'n'Play 는 워크스페이스 루트 선언을 인정하지 않습니다. 앱이 자기 `package.json` 에 없는 패키지를 해석하지 못하기 때문입니다. 루트에만 있는 `tailwindcss` 는 「워크스페이스 루트에만 선언돼 Plug'n'Play 에서 앱이 해석하지 못합니다」 FAIL, `clsx` · `tailwind-merge` · `@axis-ds/*` 는 같은 문구의 WARN 입니다(1.7.5 까지는 PASS). `.pnp.cjs` 는 `.git` 이 있는 층에서 찾기를 멈춥니다. `pnpFallbackMode: all` 설정은 읽지 않습니다.
|
|
108
113
|
- 해당할 때만 더하는 항목(1.6.0 부터, brand 항목 뒤 이 순서):
|
|
109
|
-
- `brand.activation`: `brand` 가 있을 때 루트 레이아웃(`app/layout.tsx` · `src/app/layout.tsx` · `pages/_app` 등, 그 레이아웃이 import 하는 같은 디렉터리의 `./providers` 한 단계 포함)에 `data-brand` · `setBrand(` · `defaultBrand=` 가 없으면 WARN 입니다(휴리스틱, `ThemeProvider` 단독은 켜는 코드가 아님). 1.6.1 부터 마크업 `data-brand` 와 `ThemeProvider` 만 있고 `setBrand(` · `defaultBrand=` 가 없으면 설치본(없으면 선언) `@axis-ds/theme` 가 1.7.0 미만이거나 판정할 수 없을 때 WARN 입니다(1.6.2 이하는 마운트 때 속성을 지움).
|
|
114
|
+
- `brand.activation`: `brand` 가 있을 때 루트 레이아웃(`app/layout.tsx` · `src/app/layout.tsx` · `pages/_app` 등, 그 레이아웃이 import 하는 같은 디렉터리의 `./providers` 한 단계 포함)에 `data-brand` · `setBrand(` · `defaultBrand=` 가 없으면 WARN 입니다(휴리스틱, `ThemeProvider` 단독은 켜는 코드가 아님). 1.6.1 부터 마크업 `data-brand` 와 `ThemeProvider` 만 있고 `setBrand(` · `defaultBrand=` 가 없으면 설치본(없으면 선언) `@axis-ds/theme` 가 1.7.0 미만이거나 판정할 수 없을 때 WARN 입니다(1.6.2 이하는 마운트 때 속성을 지움). 1.7.6 부터 Plug'n'Play 에서 `@axis-ds/theme` 가 워크스페이스 루트에만 선언돼 있으면 「앱이 해석하지 못합니다」 WARN 입니다(Tailwind 3 CommonJS preset 의 `@axis-ds/tokens` 판정도 같음).
|
|
110
115
|
- `tailwind.content`: Tailwind 3 설정 파일이 있고 `componentsDir` 나 선언된 `@axis-ds/ui-react` · `@axis-ds/agentic-ui` 가 있을 때, `content` 의 문자열 glob 이 그 경로를 덮지 않으면 FAIL 입니다(그 경로의 클래스가 생성되지 않음). `content` 를 정적으로 다 읽지 못하면(변수 · 펼침) WARN 입니다. 패키지 경로는 프로젝트 디렉터리부터 상위로 찾은 설치본 위치 기준이라, npm workspaces · pnpm hoisted 처럼 루트에만 설치된 앱은 `../../node_modules/@axis-ds/ui-react/dist/**/*.{js,mjs}` 를 안내합니다(1.7.1 부터, 설치본이 없거나 Plug'n'Play 면 `./node_modules/...`). `**` 는 `../` 를 넘지 않는 것으로, 절대경로 glob 은 실제 위치와 비교해 판정합니다. 1.7.4 부터 pnpm 기본 레이아웃처럼 앱 설치본이 링크이면 실경로가 같은 상위 설치본(`../../node_modules/...`)과 `.pnpm` 스토어 실경로를 상대 경로로 쓴 glob 도 인정하고, 실경로가 다른 상위 설치본을 가리키면 FAIL 문구에 그 이유를 붙입니다. 상위 경로는 Tailwind 3 가 빌드를 실행한 디렉터리 기준으로 풀리므로 모노레포 루트에서 빌드하면 `content: { relative: true, files: [...] }` 를 쓰세요(판정은 프로젝트 디렉터리에서 빌드한다고 보고 함).
|
|
111
|
-
- `animation`: `@axis-ds/ui-react` 선언이나 `componentsDir` 의 `animate-in` 류 클래스가 있을 때 애니메이션 플러그인(Tailwind 3 `tailwindcss-animate` 선언 + 설치본 + `plugins` 배열 참조, Tailwind 4 `@import "tw-animate-css"`)이 없으면 WARN 입니다. 1.6.1 부터 Tailwind 3 은 `plugins` 배열 안의 `require("tailwindcss-animate")` 나 그 패키지를 받은 식별자(`import animate from` · `const animate = require(...)`)만 인정합니다(import 만 있거나 다른 곳의 같은 문자열은 아님). 배열을 정적으로 다 읽지 못하면(펼침 · 단축 속성) 「확인하지 못함」 WARN 입니다.
|
|
116
|
+
- `animation`: `@axis-ds/ui-react` 선언이나 `componentsDir` 의 `animate-in` 류 클래스가 있을 때 애니메이션 플러그인(Tailwind 3 `tailwindcss-animate` 선언 + 설치본 + `plugins` 배열 참조, Tailwind 4 `@import "tw-animate-css"`)이 없으면 WARN 입니다. 1.6.1 부터 Tailwind 3 은 `plugins` 배열 안의 `require("tailwindcss-animate")` 나 그 패키지를 받은 식별자(`import animate from` · `const animate = require(...)`)만 인정합니다(import 만 있거나 다른 곳의 같은 문자열은 아님). 배열을 정적으로 다 읽지 못하면(펼침 · 단축 속성) 「확인하지 못함」 WARN 입니다. 1.7.6 부터 Tailwind 4 는 CSS 의 줄마다 그 줄의 패키지(`tw-animate-css` · `tailwindcss-animate`)가 선언 · 설치돼 있어야 PASS 이고, 줄은 있는데 선언이나 설치본이 없으면 「애니메이션 플러그인을 쓸 수 없습니다」 WARN 입니다(1.7.5 까지는 줄만 보고 PASS, 실제 빌드는 실패). Plug'n'Play 에서는 플러그인 선언을 앱 `package.json` 에서만 봅니다.
|
|
112
117
|
- FAIL 이 하나라도 있으면 종료 코드 1 로 끝납니다. WARN 만 있으면 0 입니다(1.3.0 부터, 이전에는 결과와 관계없이 0).
|
|
113
118
|
- MCP `axis.check_project` 도 같은 항목 · 문구를 냅니다.
|
|
114
119
|
|
|
@@ -109,14 +109,56 @@ function workspaceRootPackage(baseDirInput) {
|
|
|
109
109
|
return void 0;
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
-
function declaredDependency(baseDir, pkg, name, rootPkg) {
|
|
112
|
+
function declaredDependency(baseDir, pkg, name, rootPkg, options = {}) {
|
|
113
113
|
if (pkg === void 0) return void 0;
|
|
114
114
|
const own = hasDependency(pkg, name);
|
|
115
115
|
if (own !== void 0) return { range: own, source: "app" };
|
|
116
|
+
if (options.appOnlyInPnp && isPnpProject(baseDir)) return void 0;
|
|
116
117
|
const root = rootPkg === void 0 ? workspaceRootPackage(baseDir) : rootPkg ?? void 0;
|
|
117
118
|
const fromRoot = root !== void 0 ? hasDependency(root, name) : void 0;
|
|
118
119
|
return fromRoot !== void 0 ? { range: fromRoot, source: "root" } : void 0;
|
|
119
120
|
}
|
|
121
|
+
function pnpRootOnlyDependency(baseDir, pkg, name, rootPkg) {
|
|
122
|
+
if (pkg === void 0 || hasDependency(pkg, name) !== void 0 || !isPnpProject(baseDir)) return void 0;
|
|
123
|
+
const found = declaredDependency(baseDir, pkg, name, rootPkg);
|
|
124
|
+
return found?.source === "root" ? found : void 0;
|
|
125
|
+
}
|
|
126
|
+
var PNP_ROOT_ONLY_NOTE = "\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uB9CC \uC120\uC5B8\uB3FC Plug'n'Play \uC5D0\uC11C \uC571\uC774 \uD574\uC11D\uD558\uC9C0 \uBABB\uD569\uB2C8\uB2E4";
|
|
127
|
+
var APP_LOCKFILES = ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"];
|
|
128
|
+
function hasAppLockfile(baseDirInput) {
|
|
129
|
+
const baseDir = path.resolve(baseDirInput);
|
|
130
|
+
return APP_LOCKFILES.some((f) => existsSync(path.join(baseDir, f)));
|
|
131
|
+
}
|
|
132
|
+
function rootDeclarationsAllowed(baseDir, pkg) {
|
|
133
|
+
return pkg !== void 0 && !isPnpProject(baseDir) && !hasAppLockfile(baseDir);
|
|
134
|
+
}
|
|
135
|
+
function readPackageJsonAt(dir) {
|
|
136
|
+
try {
|
|
137
|
+
const parsed = JSON.parse(readFileSync(path.join(dir, "package.json"), "utf8"));
|
|
138
|
+
return isPlainObject(parsed) ? parsed : void 0;
|
|
139
|
+
} catch {
|
|
140
|
+
return void 0;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function dependencyInstallGuide(baseDirInput, name, range) {
|
|
144
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
145
|
+
const installCommand = detectInstallCommand(baseDir);
|
|
146
|
+
const base = { installCommand, addCommand: addCommandFor(installCommand, { [name]: range }) };
|
|
147
|
+
const pkg = readPackageJsonAt(baseDir);
|
|
148
|
+
if (pkg === void 0) return { kind: "add", ...base };
|
|
149
|
+
const own = hasDependency(pkg, name);
|
|
150
|
+
if (isPnpProject(baseDir)) return own !== void 0 ? { kind: "pnp", source: "app", range: own, ...base } : { kind: "add", ...base };
|
|
151
|
+
if (own !== void 0) return { kind: "install", source: "app", range: own, ...base };
|
|
152
|
+
if (!rootDeclarationsAllowed(baseDir, pkg)) return { kind: "add", ...base };
|
|
153
|
+
const declared = declaredDependency(baseDir, pkg, name);
|
|
154
|
+
if (declared?.source !== "root") return { kind: "add", ...base };
|
|
155
|
+
return {
|
|
156
|
+
kind: packageManagerOf(installCommand) === "npm" ? "install-at-root" : "install",
|
|
157
|
+
source: "root",
|
|
158
|
+
range: declared.range,
|
|
159
|
+
...base
|
|
160
|
+
};
|
|
161
|
+
}
|
|
120
162
|
function isPlainObject(value) {
|
|
121
163
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
122
164
|
}
|
|
@@ -247,6 +289,7 @@ function isPnpProject(baseDirInput) {
|
|
|
247
289
|
let dir = resolveBaseDir(baseDirInput);
|
|
248
290
|
for (; ; ) {
|
|
249
291
|
if (isFile(path.join(dir, ".pnp.cjs")) || isFile(path.join(dir, ".pnp.js"))) return true;
|
|
292
|
+
if (existsSync(path.join(dir, ".git"))) return false;
|
|
250
293
|
const parent = path.dirname(dir);
|
|
251
294
|
if (parent === dir) return false;
|
|
252
295
|
dir = parent;
|
|
@@ -453,6 +496,10 @@ export {
|
|
|
453
496
|
hasDependency,
|
|
454
497
|
workspaceRootPackage,
|
|
455
498
|
declaredDependency,
|
|
499
|
+
pnpRootOnlyDependency,
|
|
500
|
+
PNP_ROOT_ONLY_NOTE,
|
|
501
|
+
rootDeclarationsAllowed,
|
|
502
|
+
dependencyInstallGuide,
|
|
456
503
|
isPlainObject,
|
|
457
504
|
addCommandPrefix,
|
|
458
505
|
addCommandFor,
|
package/dist/index.js
CHANGED
|
@@ -2,23 +2,27 @@
|
|
|
2
2
|
import {
|
|
3
3
|
GLOBAL_CSS_CANDIDATES,
|
|
4
4
|
MonetClient,
|
|
5
|
+
PNP_ROOT_ONLY_NOTE,
|
|
5
6
|
ROOT_LAYOUT_FILES,
|
|
6
7
|
addCommandFor,
|
|
7
8
|
addCommandPrefix,
|
|
8
9
|
compareExactVersions,
|
|
9
10
|
declaredDependency,
|
|
11
|
+
dependencyInstallGuide,
|
|
10
12
|
detectInstallCommand,
|
|
11
13
|
detectProjectPaths,
|
|
12
14
|
findInstalledPackage,
|
|
13
15
|
hasDependency,
|
|
14
16
|
isPlainObject,
|
|
15
17
|
isPnpProject,
|
|
18
|
+
pnpRootOnlyDependency,
|
|
16
19
|
projectFileExists,
|
|
17
20
|
resolveBaseDir,
|
|
21
|
+
rootDeclarationsAllowed,
|
|
18
22
|
runScriptCommand,
|
|
19
23
|
workspaceRootPackage,
|
|
20
24
|
workspaceRunCommand
|
|
21
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-I3HWV7Y5.js";
|
|
22
26
|
import {
|
|
23
27
|
V0Client
|
|
24
28
|
} from "./chunk-2PNCUPCG.js";
|
|
@@ -1929,6 +1933,9 @@ import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep }
|
|
|
1929
1933
|
function declaredRange(baseDir, pkg, name) {
|
|
1930
1934
|
return declaredDependency(baseDir, pkg, name)?.range;
|
|
1931
1935
|
}
|
|
1936
|
+
function declaredRangeForCheck(baseDir, pkg, name) {
|
|
1937
|
+
return declaredDependency(baseDir, pkg, name, void 0, { appOnlyInPnp: true })?.range;
|
|
1938
|
+
}
|
|
1932
1939
|
function isPlainObject2(value) {
|
|
1933
1940
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1934
1941
|
}
|
|
@@ -2306,7 +2313,7 @@ function hasBareCjsPresetRequire(code) {
|
|
|
2306
2313
|
function isCommonJsConfig(file, source) {
|
|
2307
2314
|
return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
|
|
2308
2315
|
}
|
|
2309
|
-
function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
2316
|
+
function packageVersionGate(baseDirInput, pkg, name, min, options = {}) {
|
|
2310
2317
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
2311
2318
|
if (!isPnpProject(baseDir)) {
|
|
2312
2319
|
const installed = findInstalledPackage(baseDir, name)?.version;
|
|
@@ -2315,7 +2322,11 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
|
2315
2322
|
if (cmp !== void 0) return { status: cmp >= 0 ? "ok" : "below", source: "installed", value: installed };
|
|
2316
2323
|
}
|
|
2317
2324
|
}
|
|
2318
|
-
const declared = pkg ?
|
|
2325
|
+
const declared = pkg ? declaredDependency(baseDir, pkg, name, void 0, options)?.range : void 0;
|
|
2326
|
+
if (declared === void 0 && options.appOnlyInPnp) {
|
|
2327
|
+
const rootOnly = pnpRootOnlyDependency(baseDir, pkg, name);
|
|
2328
|
+
if (rootOnly !== void 0) return { status: "unresolved", source: "declared", value: rootOnly.range };
|
|
2329
|
+
}
|
|
2319
2330
|
if (declared !== void 0) {
|
|
2320
2331
|
const atLeast = rangeLowerAtLeast(declared, min);
|
|
2321
2332
|
if (atLeast !== void 0) return { status: atLeast ? "ok" : "below", source: "declared", value: declared };
|
|
@@ -2324,6 +2335,7 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
|
2324
2335
|
return { status: "unknown", source: "none" };
|
|
2325
2336
|
}
|
|
2326
2337
|
function versionGateLabel(gate) {
|
|
2338
|
+
if (gate.status === "unresolved") return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 \uC120\uC5B8 ${gate.value}`;
|
|
2327
2339
|
if (gate.source === "installed") return `\uC124\uCE58\uBCF8 ${gate.value}`;
|
|
2328
2340
|
if (gate.source === "declared") return `\uC120\uC5B8 ${gate.value}`;
|
|
2329
2341
|
return "\uC124\uCE58\uBCF8 \xB7 \uC120\uC5B8 \uC5C6\uC74C";
|
|
@@ -2405,7 +2417,14 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2405
2417
|
if (hasTokensPresetReference(content)) {
|
|
2406
2418
|
const code = stripJsComments(content);
|
|
2407
2419
|
if (isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code)) {
|
|
2408
|
-
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION);
|
|
2420
|
+
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION, { appOnlyInPnp: true });
|
|
2421
|
+
if (gate.status === "unresolved") {
|
|
2422
|
+
return {
|
|
2423
|
+
name: "tailwind.config",
|
|
2424
|
+
severity: "warn",
|
|
2425
|
+
message: `${file}\uC5D0 AXIS preset \uCC38\uC870\uAC00 \uC788\uC9C0\uB9CC @axis-ds/tokens \uAC00 ${PNP_ROOT_ONLY_NOTE}(${versionGateLabel(gate)}) \u2192 \uC571 package.json \uC5D0 @axis-ds/tokens ${TOKENS_CJS_PRESET_FIXED_VERSION} \uC774\uC0C1\uC744 \uC120\uC5B8\uD558\uC138\uC694`
|
|
2426
|
+
};
|
|
2427
|
+
}
|
|
2409
2428
|
if (gate.status !== "ok") {
|
|
2410
2429
|
const why = gate.status === "below" ? `@axis-ds/tokens ${versionGateLabel(gate)} \uC5D0\uC11C\uB294 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uAC00 preset \uC774 \uC544\uB2C8\uB77C { default } \uB97C \uB3CC\uB824\uC918 \uC0C9 \xB7 keyframes \uAC00 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` : `@axis-ds/tokens \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${versionGateLabel(gate)}). ${TOKENS_CJS_PRESET_FIXED_VERSION} \uBBF8\uB9CC\uC774\uBA74 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uB85C\uB294 preset \uC774 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
|
|
2411
2430
|
return {
|
|
@@ -2751,30 +2770,56 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
2751
2770
|
if (!declared && !copied) return null;
|
|
2752
2771
|
const by = declared ? "@axis-ds/ui-react \uC120\uC5B8" : "componentsDir \uC758 animate-in \uB958 \uD074\uB798\uC2A4";
|
|
2753
2772
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
2773
|
+
const pnp = isPnpProject(baseDir);
|
|
2774
|
+
const pluginProblem = (name) => {
|
|
2775
|
+
if (declaredRangeForCheck(baseDir, pkg, name) === void 0) {
|
|
2776
|
+
return pnpRootOnlyDependency(baseDir, pkg, name) !== void 0 ? `${name} \uAC00 ${PNP_ROOT_ONLY_NOTE}` : `${name} \uC120\uC5B8 \uC5C6\uC74C`;
|
|
2777
|
+
}
|
|
2778
|
+
if (!pnp && findInstalledPackage(baseDir, name) === void 0) return `${name} \uBBF8\uC124\uCE58(\uC120\uC5B8\uB9CC \uC788\uC74C)`;
|
|
2779
|
+
return void 0;
|
|
2780
|
+
};
|
|
2754
2781
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
2755
2782
|
const file = TAILWIND_CSS_CANDIDATES.find((c) => existsSync(join(baseDir, c)));
|
|
2756
2783
|
const css = file !== void 0 ? stripCssComments(readFileSync(join(baseDir, file), "utf8")) : "";
|
|
2757
|
-
const
|
|
2758
|
-
|
|
2784
|
+
const lines = [];
|
|
2785
|
+
if (new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`).test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND4);
|
|
2786
|
+
if (new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`).test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND3);
|
|
2787
|
+
if (lines.length === 0) {
|
|
2788
|
+
return {
|
|
2789
|
+
name: "animation",
|
|
2790
|
+
severity: "warn",
|
|
2791
|
+
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND4} \uC124\uCE58 \uB4A4 @import "${ANIMATION_PLUGIN_TAILWIND4}";`
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
const problems = lines.map((name) => ({ name, why: pluginProblem(name) })).filter((x) => x.why !== void 0);
|
|
2795
|
+
if (problems.length === 0) return { name: "animation", severity: "pass", message: `${file}\uC5D0 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
2796
|
+
return {
|
|
2759
2797
|
name: "animation",
|
|
2760
2798
|
severity: "warn",
|
|
2761
|
-
message:
|
|
2799
|
+
message: `${file}\uC758 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC744 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${by}, ${problems.map((x) => x.why).join(" \xB7 ")}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uACE0 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2192 ${problems.map((x) => x.name).join(" \xB7 ")} \uB97C package.json \uC5D0 \uC120\uC5B8 \xB7 \uC124\uCE58\uD558\uC138\uC694`
|
|
2762
2800
|
};
|
|
2763
2801
|
}
|
|
2764
2802
|
const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync(join(baseDir, f)));
|
|
2765
2803
|
const source = configFile !== void 0 ? stripJsComments(readFileSync(join(baseDir, configFile), "utf8")) : "";
|
|
2766
2804
|
const plugins = configFile !== void 0 ? readAnimationPluginUse(source) : "absent";
|
|
2767
|
-
const
|
|
2768
|
-
|
|
2769
|
-
if (plugins === "found" && pluginDeclared && pluginInstalled) {
|
|
2805
|
+
const pluginReason = pluginProblem(ANIMATION_PLUGIN_TAILWIND3);
|
|
2806
|
+
if (plugins === "found" && pluginReason === void 0) {
|
|
2770
2807
|
return { name: "animation", severity: "pass", message: `${configFile}\uC758 plugins \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
2771
2808
|
}
|
|
2772
2809
|
const cfg = configFile ?? "tailwind.config";
|
|
2810
|
+
const configReason = plugins === "dynamic" ? `${cfg} plugins \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD568` : plugins !== "found" ? `${cfg} plugins \uC5D0 \uC5C6\uC74C` : void 0;
|
|
2811
|
+
if (pluginReason !== void 0 && pnpRootOnlyDependency(baseDir, pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0) {
|
|
2812
|
+
const extra = configReason !== void 0 ? `, ${configReason}` : "";
|
|
2813
|
+
const plug = configReason !== void 0 ? ` \xB7 plugins \uC5D0 require("${ANIMATION_PLUGIN_TAILWIND3}")` : "";
|
|
2814
|
+
return {
|
|
2815
|
+
name: "animation",
|
|
2816
|
+
severity: "warn",
|
|
2817
|
+
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 ${PNP_ROOT_ONLY_NOTE}(${by}${extra}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uC571 package.json \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uB97C \uC120\uC5B8\uD558\uC138\uC694${plug}`
|
|
2818
|
+
};
|
|
2819
|
+
}
|
|
2773
2820
|
const reasons = [];
|
|
2774
|
-
if (
|
|
2775
|
-
|
|
2776
|
-
if (plugins === "dynamic") reasons.push(`${cfg} plugins \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD568`);
|
|
2777
|
-
else if (plugins !== "found") reasons.push(`${cfg} plugins \uC5D0 \uC5C6\uC74C`);
|
|
2821
|
+
if (pluginReason !== void 0) reasons.push(pluginReason);
|
|
2822
|
+
if (configReason !== void 0) reasons.push(configReason);
|
|
2778
2823
|
return {
|
|
2779
2824
|
name: "animation",
|
|
2780
2825
|
severity: "warn",
|
|
@@ -3439,7 +3484,11 @@ function inspectBrandActivation(baseDir) {
|
|
|
3439
3484
|
if (typeof brand !== "string" || brand.trim() === "") return null;
|
|
3440
3485
|
const location = findBrandActivation(baseDir);
|
|
3441
3486
|
if (!location.markupWithProvider) return { brand, ...location };
|
|
3442
|
-
return {
|
|
3487
|
+
return {
|
|
3488
|
+
brand,
|
|
3489
|
+
...location,
|
|
3490
|
+
theme: packageVersionGate(baseDir, readProjectPackageJson(baseDir), THEME_PACKAGE, THEME_MARKUP_BRAND_MIN_VERSION, { appOnlyInPnp: true })
|
|
3491
|
+
};
|
|
3443
3492
|
}
|
|
3444
3493
|
var THEME_PACKAGE = "@axis-ds/theme";
|
|
3445
3494
|
function readProjectPackageJson(baseDir) {
|
|
@@ -3512,25 +3561,43 @@ function checkDependencies(baseDirInput) {
|
|
|
3512
3561
|
return { name: "dependencies", severity: "fail", message: "package.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(JSON \uD655\uC778)" };
|
|
3513
3562
|
}
|
|
3514
3563
|
const rootPkg = workspaceRootPackage(baseDir) ?? null;
|
|
3515
|
-
const
|
|
3564
|
+
const pnp = isPnpProject(baseDir);
|
|
3565
|
+
const declared = (d) => declaredDependency(baseDir, pkg, d, rootPkg, { appOnlyInPnp: true });
|
|
3566
|
+
const pnpRootOnly = (d) => pnpRootOnlyDependency(baseDir, pkg, d, rootPkg) !== void 0;
|
|
3516
3567
|
const fromRoot = (d) => declared(d)?.source === "root";
|
|
3517
|
-
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0);
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3568
|
+
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0 && !pnpRootOnly(d));
|
|
3569
|
+
const pnpRootRequired = REQUIRED_DEPENDENCIES.filter((d) => pnpRootOnly(d));
|
|
3570
|
+
if (missingRequired.length > 0 || pnpRootRequired.length > 0) {
|
|
3571
|
+
const fails = [];
|
|
3572
|
+
if (missingRequired.length > 0) fails.push(`\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}`);
|
|
3573
|
+
if (pnpRootRequired.length > 0) fails.push(`\uD544\uC218 \uC758\uC874\uC131 ${pnpRootRequired.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
3574
|
+
return { name: "dependencies", severity: "fail", message: fails.join(" / ") };
|
|
3575
|
+
}
|
|
3576
|
+
const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => declared(d) === void 0 && !pnpRootOnly(d));
|
|
3577
|
+
const pnpRootRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => pnpRootOnly(d));
|
|
3578
|
+
const appAxis = declaredAxisPackages(pkg);
|
|
3579
|
+
const rootOnlyAxis = rootPkg !== null ? declaredAxisPackages(rootPkg).filter((d) => !appAxis.includes(d)) : [];
|
|
3580
|
+
const rootAxis = pnp ? [] : rootOnlyAxis;
|
|
3581
|
+
const pnpRootAxis = pnp ? rootOnlyAxis : [];
|
|
3582
|
+
const rootDeclared = [...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => fromRoot(d)), ...rootAxis];
|
|
3523
3583
|
const rootNote = rootDeclared.length > 0 ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8: ${rootDeclared.join(", ")}` : void 0;
|
|
3524
3584
|
const targets = [
|
|
3525
3585
|
...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => declared(d) !== void 0),
|
|
3526
|
-
...
|
|
3586
|
+
...appAxis,
|
|
3587
|
+
...rootAxis
|
|
3527
3588
|
];
|
|
3528
|
-
const pnp = isPnpProject(baseDir);
|
|
3529
3589
|
const notInstalled = pnp ? [] : targets.filter((d) => findInstalledPackage(baseDir, d) === void 0);
|
|
3590
|
+
const notInstalledRoot = notInstalled.filter((d) => rootAxis.includes(d));
|
|
3591
|
+
const notInstalledOther = notInstalled.filter((d) => !rootAxis.includes(d));
|
|
3530
3592
|
const problems = [];
|
|
3531
3593
|
if (missingRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 \uB204\uB77D: ${missingRecommended.join(", ")}`);
|
|
3532
|
-
if (
|
|
3533
|
-
|
|
3594
|
+
if (pnpRootRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 ${pnpRootRecommended.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
3595
|
+
if (pnpRootAxis.length > 0) problems.push(`${pnpRootAxis.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
3596
|
+
if (notInstalledOther.length > 0) {
|
|
3597
|
+
problems.push(`\uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC740 \uC758\uC874\uC131: ${notInstalledOther.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
|
|
3598
|
+
}
|
|
3599
|
+
if (notInstalledRoot.length > 0) {
|
|
3600
|
+
problems.push(`\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB3FC \uC788\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: ${notInstalledRoot.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
|
|
3534
3601
|
}
|
|
3535
3602
|
if (problems.length > 0) {
|
|
3536
3603
|
return { name: "dependencies", severity: "warn", message: problems.join(" / ") + (rootNote ? ` (${rootNote})` : "") };
|
|
@@ -3669,6 +3736,13 @@ function brandCheckResult(check) {
|
|
|
3669
3736
|
}
|
|
3670
3737
|
}
|
|
3671
3738
|
function brandActivationResult(check) {
|
|
3739
|
+
if (check.found && check.theme?.status === "unresolved") {
|
|
3740
|
+
return {
|
|
3741
|
+
name: "brand.activation",
|
|
3742
|
+
severity: "warn",
|
|
3743
|
+
message: `${check.found}\uC758 <html data-brand> \uB97C ThemeProvider \uC640 \uD568\uAED8 \uC4F0\uB294\uB370 @axis-ds/theme \uAC00 ${PNP_ROOT_ONLY_NOTE}(${versionGateLabel(check.theme)}) \u2192 \uC571 package.json \uC5D0 @axis-ds/theme ${THEME_MARKUP_BRAND_MIN_VERSION} \uC774\uC0C1\uC744 \uC120\uC5B8\uD558\uAC70\uB098 setBrand("${check.brand}")`
|
|
3744
|
+
};
|
|
3745
|
+
}
|
|
3672
3746
|
if (check.found && check.theme && check.theme.status !== "ok") {
|
|
3673
3747
|
const label = versionGateLabel(check.theme);
|
|
3674
3748
|
const why = check.theme.status === "below" ? `@axis-ds/theme ${label} \uC758 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4` : `@axis-ds/theme \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${label}). ${THEME_MARKUP_BRAND_MIN_VERSION} \uBBF8\uB9CC\uC774\uBA74 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4`;
|
|
@@ -3802,11 +3876,12 @@ import chalk9 from "chalk";
|
|
|
3802
3876
|
import path12 from "path";
|
|
3803
3877
|
|
|
3804
3878
|
// src/theme/theme-add.ts
|
|
3805
|
-
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync4, realpathSync as realpathSync2, unlinkSync, writeFileSync } from "fs";
|
|
3879
|
+
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync4, realpathSync as realpathSync2, statSync as statSync2, unlinkSync, writeFileSync } from "fs";
|
|
3806
3880
|
import path11 from "path";
|
|
3807
3881
|
var TOKENS_DEPENDENCY_RANGE = `^${TOKENS_DEPENDENCY_MIN_VERSION}`;
|
|
3808
3882
|
var TAILWIND3_BASE_IMPORTS = [`${TOKENS_PACKAGE}/css`, `${TOKENS_PACKAGE}/css/shadcn`];
|
|
3809
3883
|
var THEME_MIN_VERSION = "1.3.0";
|
|
3884
|
+
var COMPONENT_TAILWIND_CSS_MIN_VERSION = "1.4.0";
|
|
3810
3885
|
function readText(file) {
|
|
3811
3886
|
return existsSync3(file) ? readFileSync4(file, "utf8") : null;
|
|
3812
3887
|
}
|
|
@@ -3905,6 +3980,13 @@ function realPathInside(baseDir, file) {
|
|
|
3905
3980
|
const inside = relPath !== "" && !relPath.startsWith("..") && !path11.isAbsolute(relPath);
|
|
3906
3981
|
return { inside, realPath };
|
|
3907
3982
|
}
|
|
3983
|
+
function isFile2(file) {
|
|
3984
|
+
try {
|
|
3985
|
+
return statSync2(file).isFile();
|
|
3986
|
+
} catch {
|
|
3987
|
+
return false;
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3908
3990
|
function isStylesheet(realPath) {
|
|
3909
3991
|
return path11.extname(realPath).toLowerCase() === ".css";
|
|
3910
3992
|
}
|
|
@@ -3919,6 +4001,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
3919
4001
|
unverifiedBrand: false,
|
|
3920
4002
|
configChanged: false,
|
|
3921
4003
|
installCommand: detectInstallCommand(baseDir),
|
|
4004
|
+
tokensGuide: dependencyInstallGuide(baseDir, TOKENS_PACKAGE, TOKENS_DEPENDENCY_RANGE),
|
|
3922
4005
|
writes: []
|
|
3923
4006
|
};
|
|
3924
4007
|
const configFile = path11.join(baseDir, AXIS_CONFIG_FILE);
|
|
@@ -3972,14 +4055,27 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
3972
4055
|
return plan;
|
|
3973
4056
|
}
|
|
3974
4057
|
}
|
|
4058
|
+
const rootPkg = rootDeclarationsAllowed(baseDir, pkg) ? workspaceRootPackage(baseDir) ?? null : null;
|
|
3975
4059
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
3976
4060
|
const tailwind4 = tailwind.major !== void 0 && tailwind.major >= 4;
|
|
3977
|
-
const
|
|
3978
|
-
|
|
3979
|
-
|
|
3980
|
-
|
|
3981
|
-
|
|
3982
|
-
|
|
4061
|
+
const componentImports = [];
|
|
4062
|
+
const deferredComponentImports = [];
|
|
4063
|
+
if (tailwind4 && pkg !== void 0) {
|
|
4064
|
+
for (const n of TAILWIND4_COMPONENT_PACKAGES) {
|
|
4065
|
+
if (hasDependency(pkg, n) !== void 0) {
|
|
4066
|
+
componentImports.push(n);
|
|
4067
|
+
continue;
|
|
4068
|
+
}
|
|
4069
|
+
if (declaredDependency(baseDir, pkg, n, rootPkg)?.source !== "root") continue;
|
|
4070
|
+
const installed2 = findInstalledPackage(baseDir, n);
|
|
4071
|
+
if (installed2 !== void 0 && isFile2(path11.join(installed2.dir, "tailwind.css"))) {
|
|
4072
|
+
componentImports.push(n);
|
|
4073
|
+
} else {
|
|
4074
|
+
deferredComponentImports.push(installed2 === void 0 ? { name: n } : { name: n, installedVersion: installed2.version ?? "?" });
|
|
4075
|
+
}
|
|
4076
|
+
}
|
|
4077
|
+
}
|
|
4078
|
+
const requiredBaseImports = tailwind4 ? [TOKENS_TAILWIND4_ENTRY, ...componentImports.map((n) => `${n}/tailwind.css`)] : [...TAILWIND3_BASE_IMPORTS];
|
|
3983
4079
|
const location = findGlobalCss(baseDir, config);
|
|
3984
4080
|
if (location.path) {
|
|
3985
4081
|
const where = realPathInside(baseDir, location.path);
|
|
@@ -3998,6 +4094,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
3998
4094
|
const otherBrands = [...new Set(imported.filter((n) => n !== brand))];
|
|
3999
4095
|
const brandAdded = !imported.includes(brand);
|
|
4000
4096
|
const baseImports = requiredBaseImports.filter((spec) => !hasCssImport(before, spec));
|
|
4097
|
+
const deferredHere = deferredComponentImports.filter((d) => !hasCssImport(before, `${d.name}/tailwind.css`));
|
|
4001
4098
|
const lines = [...baseImports.map((spec) => `@import "${spec}";`), ...brandAdded ? [`@import "${plan.importPath}";`] : []];
|
|
4002
4099
|
plan.css = {
|
|
4003
4100
|
file: location.path,
|
|
@@ -4008,7 +4105,8 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4008
4105
|
baseImports,
|
|
4009
4106
|
requiredBaseImports,
|
|
4010
4107
|
lateImports: findLateImports(before),
|
|
4011
|
-
tailwind4
|
|
4108
|
+
tailwind4,
|
|
4109
|
+
...deferredHere.length > 0 ? { deferredComponentImports: deferredHere } : {}
|
|
4012
4110
|
};
|
|
4013
4111
|
if (lines.length > 0) {
|
|
4014
4112
|
plan.writes.push({ file: location.path, before, after: insertImportLines(before, lines) });
|
|
@@ -4022,7 +4120,8 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4022
4120
|
baseImports: requiredBaseImports,
|
|
4023
4121
|
requiredBaseImports,
|
|
4024
4122
|
lateImports: [],
|
|
4025
|
-
tailwind4
|
|
4123
|
+
tailwind4,
|
|
4124
|
+
...deferredComponentImports.length > 0 ? { deferredComponentImports } : {}
|
|
4026
4125
|
};
|
|
4027
4126
|
}
|
|
4028
4127
|
if (!tailwind4) {
|
|
@@ -4043,10 +4142,18 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4043
4142
|
if (pkgText === null || pkg === void 0) {
|
|
4044
4143
|
plan.dependency = { action: "no-package-json", upgrade, themeMissing: false, tokensAddCommand, themeAddCommand };
|
|
4045
4144
|
} else {
|
|
4046
|
-
const themeMissing =
|
|
4047
|
-
const declared =
|
|
4145
|
+
const themeMissing = declaredDependency(baseDir, pkg, THEME_PACKAGE, rootPkg) === void 0;
|
|
4146
|
+
const declared = declaredDependency(baseDir, pkg, TOKENS_PACKAGE, rootPkg);
|
|
4048
4147
|
if (declared !== void 0) {
|
|
4049
|
-
plan.dependency = {
|
|
4148
|
+
plan.dependency = {
|
|
4149
|
+
action: "present",
|
|
4150
|
+
declaredRange: declared.range,
|
|
4151
|
+
declaredSource: declared.source,
|
|
4152
|
+
upgrade,
|
|
4153
|
+
themeMissing,
|
|
4154
|
+
tokensAddCommand,
|
|
4155
|
+
themeAddCommand
|
|
4156
|
+
};
|
|
4050
4157
|
} else {
|
|
4051
4158
|
const deps = isPlainObject(pkg.dependencies) ? { ...pkg.dependencies } : {};
|
|
4052
4159
|
deps[TOKENS_PACKAGE] = TOKENS_DEPENDENCY_RANGE;
|
|
@@ -4152,30 +4259,44 @@ function baseImportLines(after, spec, brandImportPath2, file) {
|
|
|
4152
4259
|
chalk9.yellow(` ! \uC774 \uC904\uC774 \uBE0C\uB79C\uB4DC import \uB4A4\uC5D0 \uB4E4\uC5B4\uAC14\uC2B5\uB2C8\uB2E4. \uBE0C\uB79C\uB4DC \uAC12\uC774 \uAE30\uBCF8 \uD1A0\uD070\uC5D0 \uB36E\uC774\uBBC0\uB85C @import "${brandImportPath2}"; \uC55E\uC73C\uB85C \uC62E\uAE30\uC138\uC694`)
|
|
4153
4260
|
];
|
|
4154
4261
|
}
|
|
4155
|
-
function tokensInstallCommand(baseDir) {
|
|
4156
|
-
return addCommandFor(detectInstallCommand(baseDir), { [TOKENS_PACKAGE]: TOKENS_DEPENDENCY_RANGE });
|
|
4157
|
-
}
|
|
4158
4262
|
var TOKENS_INSTALL_COMMAND = addCommandFor("pnpm install", { [TOKENS_PACKAGE]: TOKENS_DEPENDENCY_RANGE });
|
|
4159
|
-
function
|
|
4263
|
+
function tokensInstallGuide(baseDir) {
|
|
4264
|
+
return dependencyInstallGuide(baseDir, TOKENS_PACKAGE, TOKENS_DEPENDENCY_RANGE);
|
|
4265
|
+
}
|
|
4266
|
+
function asGuide(guide) {
|
|
4267
|
+
return typeof guide === "string" ? { kind: "add", installCommand: guide, addCommand: guide } : guide;
|
|
4268
|
+
}
|
|
4269
|
+
function tokensPnpMessage(range) {
|
|
4270
|
+
return `${TOKENS_PACKAGE}${range ? ` ${range}` : ""} \uAC00 package.json \uC5D0 \uC120\uC5B8\uB3FC \uC788\uC9C0\uB9CC Plug'n'Play \uC124\uCE58\uB77C \uC124\uCE58\uBCF8\uC744 \uD310\uC815\uD558\uC9C0 \uBABB\uD574 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`;
|
|
4271
|
+
}
|
|
4272
|
+
var ROOT_TOKENS_UPGRADE_GUIDE = `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 package.json \uC758 ${TOKENS_PACKAGE} \uC120\uC5B8\uC744 ^${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9AC\uACE0 \uC124\uCE58\uD558\uC138\uC694.`;
|
|
4273
|
+
function installPhrase(g) {
|
|
4274
|
+
if (g.kind === "install-at-root") return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${chalk9.cyan(g.installCommand)}`;
|
|
4275
|
+
return chalk9.cyan(g.kind === "install" ? g.installCommand : g.addCommand);
|
|
4276
|
+
}
|
|
4277
|
+
function rebuildGuide(g) {
|
|
4278
|
+
return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 ${chalk9.cyan(workspaceRunCommand(g.installCommand, TOKENS_PACKAGE, "build"))}, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${installPhrase(g)}`;
|
|
4279
|
+
}
|
|
4280
|
+
function tokensStatusGuide(status, version, guide = TOKENS_INSTALL_COMMAND) {
|
|
4281
|
+
const g = asGuide(guide);
|
|
4282
|
+
if (g.kind === "pnp") return [chalk9.yellow(tokensPnpMessage(g.range))];
|
|
4283
|
+
const install = installPhrase(g);
|
|
4160
4284
|
switch (status) {
|
|
4161
4285
|
case "not-installed":
|
|
4162
|
-
return [
|
|
4163
|
-
chalk9.yellow(`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`),
|
|
4164
|
-
` \uC124\uCE58: ${chalk9.cyan(installCommand)}`
|
|
4165
|
-
];
|
|
4286
|
+
return [chalk9.yellow(`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`), ` \uC124\uCE58: ${install}`];
|
|
4166
4287
|
case "unsupported":
|
|
4167
4288
|
return [
|
|
4168
4289
|
chalk9.yellow(
|
|
4169
4290
|
`${TOKENS_PACKAGE} ${version ?? "(\uBC84\uC804 \uBAA8\uB984)"} \uC740 \uBE0C\uB79C\uB4DC\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1 \uD544\uC694).`
|
|
4170
4291
|
),
|
|
4171
|
-
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(
|
|
4292
|
+
g.source === "root" ? ` ${ROOT_TOKENS_UPGRADE_GUIDE}` : ` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(g.addCommand)}`
|
|
4172
4293
|
];
|
|
4173
4294
|
case "not-built":
|
|
4174
4295
|
return [
|
|
4175
4296
|
chalk9.yellow(
|
|
4176
4297
|
`${TOKENS_PACKAGE}${version ? ` ${version}` : ""} \uB294 \uC788\uC9C0\uB9CC \uBE4C\uB4DC \uC0B0\uCD9C\uBB3C\uC774 \uC5C6\uC5B4 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`
|
|
4177
4298
|
),
|
|
4178
|
-
`
|
|
4299
|
+
` ${rebuildGuide(g)}`
|
|
4179
4300
|
];
|
|
4180
4301
|
}
|
|
4181
4302
|
}
|
|
@@ -4365,6 +4486,15 @@ function renderThemeAdd(plan, written) {
|
|
|
4365
4486
|
)
|
|
4366
4487
|
);
|
|
4367
4488
|
}
|
|
4489
|
+
for (const d of css?.deferredComponentImports ?? []) {
|
|
4490
|
+
const line = `@import "${d.name}/tailwind.css";`;
|
|
4491
|
+
const current = d.installedVersion !== void 0 && d.installedVersion !== "?" && (compareExactVersions(d.installedVersion, COMPONENT_TAILWIND_CSS_MIN_VERSION) ?? -1) >= 0;
|
|
4492
|
+
lines.push(
|
|
4493
|
+
chalk9.yellow(
|
|
4494
|
+
d.installedVersion === void 0 ? ` ! ${d.name} \uAC00 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC544 ${line} \uB97C \uB123\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58(${plan.installCommand}) \uB4A4 theme add \uB97C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uC9C1\uC811 \uB123\uC73C\uC138\uC694.` : current ? ` ! \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB41C ${d.name} \uC758 \uC124\uCE58\uBCF8(${d.installedVersion})\uC5D0 tailwind.css \uAC00 \uC5C6\uC5B4 ${line} \uB97C \uB123\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uAC00 \uC190\uC0C1\uB410\uC744 \uC218 \uC788\uC73C\uB2C8 \uB2E4\uC2DC \uC124\uCE58(${plan.installCommand}) \uB4A4 theme add \uB97C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uC9C1\uC811 \uB123\uC73C\uC138\uC694.` : ` ! \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB41C ${d.name} \uC758 \uC124\uCE58\uBCF8(${d.installedVersion === "?" ? "\uBC84\uC804 \uBAA8\uB984" : d.installedVersion})\uC5D0 tailwind.css \uAC00 \uC5C6\uC5B4(${COMPONENT_TAILWIND_CSS_MIN_VERSION} \uBD80\uD130 \uC81C\uACF5) ${line} \uB97C \uB123\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${COMPONENT_TAILWIND_CSS_MIN_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9B0 \uB4A4 theme add \uB97C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uC9C1\uC811 \uB123\uC73C\uC138\uC694.`
|
|
4495
|
+
)
|
|
4496
|
+
);
|
|
4497
|
+
}
|
|
4368
4498
|
if (css && css.otherBrands.length > 0) {
|
|
4369
4499
|
lines.push(
|
|
4370
4500
|
chalk9.yellow(
|
|
@@ -4373,23 +4503,38 @@ function renderThemeAdd(plan, written) {
|
|
|
4373
4503
|
);
|
|
4374
4504
|
}
|
|
4375
4505
|
const dep = plan.dependency;
|
|
4506
|
+
const tokensGuide = plan.tokensGuide;
|
|
4507
|
+
const pnpTokens = tokensGuide.kind === "pnp" && plan.tokens.status !== "ok";
|
|
4376
4508
|
if (dep?.action === "add") {
|
|
4377
4509
|
lines.push(
|
|
4378
4510
|
` ${chalk9.green("\u2713")} package.json: dependencies \uC5D0 "${TOKENS_PACKAGE}": "${TOKENS_DEPENDENCY_RANGE}" \uCD94\uAC00`,
|
|
4379
4511
|
` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`
|
|
4380
4512
|
);
|
|
4513
|
+
} else if (dep?.action === "present" && dep.declaredSource === "root") {
|
|
4514
|
+
lines.push(
|
|
4515
|
+
` ${chalk9.gray("-")} package.json: ${TOKENS_PACKAGE} ${dep.declaredRange} \uAC00 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB3FC \uC788\uC5B4 \uC571 package.json \uC740 \uBC14\uAFB8\uC9C0 \uC54A\uC74C`
|
|
4516
|
+
);
|
|
4517
|
+
if (plan.tokens.status === "not-installed") lines.push(` \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`);
|
|
4518
|
+
else if (plan.tokens.status === "not-built") lines.push(` ${rebuildGuide(tokensGuide)}`);
|
|
4381
4519
|
} else if (dep?.action === "present") {
|
|
4382
4520
|
lines.push(` ${chalk9.gray("-")} package.json: ${TOKENS_PACKAGE} ${dep.declaredRange} \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uBC94\uC704\uB97C \uBC14\uAFB8\uC9C0 \uC54A\uC74C`);
|
|
4521
|
+
if (pnpTokens) lines.push(` ${chalk9.yellow(tokensPnpMessage(tokensGuide.range))}`);
|
|
4522
|
+
else if (plan.tokens.status === "not-installed") lines.push(` \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`);
|
|
4523
|
+
else if (plan.tokens.status === "not-built") lines.push(` ${rebuildGuide(tokensGuide)}`);
|
|
4383
4524
|
} else if (dep?.action === "no-package-json") {
|
|
4384
4525
|
lines.push(chalk9.yellow(` ! package.json \uC774 \uC5C6\uC5B4 \uC758\uC874\uC131\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${dep.tokensAddCommand}`));
|
|
4385
4526
|
}
|
|
4386
|
-
if (dep?.upgrade) {
|
|
4527
|
+
if (dep?.upgrade && !pnpTokens) {
|
|
4387
4528
|
lines.push(
|
|
4388
4529
|
chalk9.yellow(
|
|
4389
4530
|
` ! \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${plan.tokens.version} \uC740 \uBE0C\uB79C\uB4DC\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1 \uD544\uC694).`
|
|
4390
|
-
)
|
|
4391
|
-
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(dep.tokensAddCommand)}`
|
|
4531
|
+
)
|
|
4392
4532
|
);
|
|
4533
|
+
if (dep.action === "present" && dep.declaredSource === "root") {
|
|
4534
|
+
lines.push(` \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 package.json \uC758 ${TOKENS_PACKAGE} \uC120\uC5B8\uC744 ^${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9AC\uACE0 \uC124\uCE58\uD558\uC138\uC694.`);
|
|
4535
|
+
} else {
|
|
4536
|
+
lines.push(` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(dep.tokensAddCommand)}`);
|
|
4537
|
+
}
|
|
4393
4538
|
}
|
|
4394
4539
|
if (plan.configChanged) {
|
|
4395
4540
|
lines.push(` ${chalk9.green("\u2713")} axis.config.json: "brand": "${plan.brand}" \uAE30\uB85D`);
|
|
@@ -4468,11 +4613,11 @@ function registerThemeCommand(program2) {
|
|
|
4468
4613
|
const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
|
|
4469
4614
|
themeCmd.command("list").alias("ls").description("\uC124\uCE58\uB41C @axis-ds/tokens \uC758 \uBE0C\uB79C\uB4DC \uBAA9\uB85D").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((options) => {
|
|
4470
4615
|
const baseDir = path12.resolve(options.dir || ".");
|
|
4471
|
-
print(renderThemeList(listBrands(baseDir),
|
|
4616
|
+
print(renderThemeList(listBrands(baseDir), tokensInstallGuide(baseDir)));
|
|
4472
4617
|
});
|
|
4473
4618
|
themeCmd.command("info <brand>").description("\uBE0C\uB79C\uB4DC \uC0C1\uC138: import \uACBD\uB85C \xB7 Provider \uC608\uC2DC \xB7 \uC8FC\uC694 \uD1A0\uD070 \xB7 \uBCF4\uC815 \uB0B4\uC5ED").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((name, options) => {
|
|
4474
4619
|
const baseDir = path12.resolve(options.dir || ".");
|
|
4475
|
-
print(renderThemeInfo(getBrand(baseDir, name), name,
|
|
4620
|
+
print(renderThemeInfo(getBrand(baseDir, name), name, tokensInstallGuide(baseDir)));
|
|
4476
4621
|
});
|
|
4477
4622
|
themeCmd.command("add <brand>").description("\uBE0C\uB79C\uB4DC \uC801\uC6A9: CSS import \xB7 package.json \uC758\uC874\uC131 \xB7 axis.config.json brand (\uC124\uCE58\uB294 \uC548\uB0B4\uB9CC)").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((name, options) => {
|
|
4478
4623
|
const baseDir = path12.resolve(options.dir || ".");
|
|
@@ -4794,13 +4939,13 @@ async function fetchRegistryJson(url, options = {}) {
|
|
|
4794
4939
|
}
|
|
4795
4940
|
|
|
4796
4941
|
// src/init/init.ts
|
|
4797
|
-
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync5, lstatSync as lstatSync3, readFileSync as readFileSync5, realpathSync as realpathSync4, statSync as
|
|
4942
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync5, lstatSync as lstatSync3, readFileSync as readFileSync5, realpathSync as realpathSync4, statSync as statSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
4798
4943
|
import path14 from "path";
|
|
4799
4944
|
import chalk10 from "chalk";
|
|
4800
4945
|
import fs12 from "fs-extra";
|
|
4801
4946
|
|
|
4802
4947
|
// ../axis-registry-core/src/add/safe-write.ts
|
|
4803
|
-
import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync2, realpathSync as realpathSync3, statSync as
|
|
4948
|
+
import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync2, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
|
|
4804
4949
|
import path13 from "path";
|
|
4805
4950
|
import fs11 from "fs-extra";
|
|
4806
4951
|
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
@@ -4856,7 +5001,7 @@ function escapeReason(root, target, options = {}) {
|
|
|
4856
5001
|
}
|
|
4857
5002
|
let followed;
|
|
4858
5003
|
try {
|
|
4859
|
-
followed =
|
|
5004
|
+
followed = statSync3(realTarget);
|
|
4860
5005
|
} catch {
|
|
4861
5006
|
return `\uAE30\uC874 \uD30C\uC77C \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${target})`;
|
|
4862
5007
|
}
|
|
@@ -5049,9 +5194,25 @@ async function resolveInitAnswers(baseDirInput, tailwind4) {
|
|
|
5049
5194
|
}
|
|
5050
5195
|
return { answers, notes };
|
|
5051
5196
|
}
|
|
5052
|
-
function animationGuideLine(pkg, tailwind4, installCommand) {
|
|
5197
|
+
function animationGuideLine(pkg, tailwind4, installCommand, baseDir) {
|
|
5053
5198
|
const name = tailwind4 ? ANIMATION_PLUGIN_TAILWIND4 : ANIMATION_PLUGIN_TAILWIND3;
|
|
5054
|
-
if (
|
|
5199
|
+
if (baseDir !== void 0) {
|
|
5200
|
+
const pnp = isPnpProject(baseDir);
|
|
5201
|
+
const candidates = tailwind4 ? [ANIMATION_PLUGIN_TAILWIND4, ANIMATION_PLUGIN_TAILWIND3] : [ANIMATION_PLUGIN_TAILWIND3];
|
|
5202
|
+
const declaredOf = (n) => {
|
|
5203
|
+
if (pkg === void 0) return void 0;
|
|
5204
|
+
if (pnp) return hasDependency(pkg, n) !== void 0 ? { source: "app" } : void 0;
|
|
5205
|
+
return declaredDependency(baseDir, pkg, n);
|
|
5206
|
+
};
|
|
5207
|
+
for (const candidate of candidates) {
|
|
5208
|
+
const declared = declaredOf(candidate);
|
|
5209
|
+
if (declared === void 0) continue;
|
|
5210
|
+
if (pnp || findInstalledPackage(baseDir, candidate) !== void 0) return void 0;
|
|
5211
|
+
const declaredWhere = declared.source === "root" ? "\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 " : "";
|
|
5212
|
+
const setup = !tailwind4 ? `tailwind.config \uC758 plugins \uC5D0 require("${candidate}") \uB97C \uB123\uC73C\uC138\uC694` : candidate === ANIMATION_PLUGIN_TAILWIND4 ? `\uC804\uC5ED CSS \uC5D0 @import "${candidate}"; \uB97C \uB123\uC73C\uC138\uC694` : `\uC804\uC5ED CSS \uC5D0 @plugin "${candidate}"; \uB97C \uB123\uC73C\uC138\uC694`;
|
|
5213
|
+
return `\uC560\uB2C8\uBA54\uC774\uC158: ${candidate} \uB294 ${declaredWhere}\uC120\uC5B8\uB3FC \uC788\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${installCommand} \uB4A4 ${setup}.`;
|
|
5214
|
+
}
|
|
5215
|
+
} else if (pkg !== void 0 && (hasDependency(pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0 || hasDependency(pkg, ANIMATION_PLUGIN_TAILWIND4) !== void 0)) {
|
|
5055
5216
|
return void 0;
|
|
5056
5217
|
}
|
|
5057
5218
|
const add = `${addCommandFor(installCommand, {}).trimEnd()} ${name}`;
|
|
@@ -5315,7 +5476,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
5315
5476
|
}
|
|
5316
5477
|
let target;
|
|
5317
5478
|
try {
|
|
5318
|
-
target =
|
|
5479
|
+
target = statSync4(real);
|
|
5319
5480
|
} catch (e) {
|
|
5320
5481
|
return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC758 \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
5321
5482
|
}
|
|
@@ -5391,7 +5552,7 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
|
|
|
5391
5552
|
}
|
|
5392
5553
|
if (previousText !== null && previousText !== nextText) {
|
|
5393
5554
|
try {
|
|
5394
|
-
const st =
|
|
5555
|
+
const st = statSync4(configPath);
|
|
5395
5556
|
if (st.isFile() && st.nlink >= 2) rejects.push(hardLinkMessage("axis.config.json", st.nlink));
|
|
5396
5557
|
} catch {
|
|
5397
5558
|
}
|
|
@@ -5490,7 +5651,7 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
|
|
|
5490
5651
|
return;
|
|
5491
5652
|
}
|
|
5492
5653
|
reportDependencies(plan, log);
|
|
5493
|
-
const animation = animationGuideLine(readPackageJsonSafe(baseDir), tailwind4, plan.installCommand);
|
|
5654
|
+
const animation = animationGuideLine(readPackageJsonSafe(baseDir), tailwind4, plan.installCommand, baseDir);
|
|
5494
5655
|
if (animation !== void 0) log(chalk10.yellow(` ${animation}`));
|
|
5495
5656
|
if (tailwind4) {
|
|
5496
5657
|
const [head, ...rest] = tailwind4GuideLines(
|
|
@@ -5550,7 +5711,7 @@ function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL, deps
|
|
|
5550
5711
|
import chalk12 from "chalk";
|
|
5551
5712
|
|
|
5552
5713
|
// ../axis-registry-core/src/add/add.ts
|
|
5553
|
-
import { existsSync as existsSync7, readFileSync as readFileSync7, statSync as
|
|
5714
|
+
import { existsSync as existsSync7, readFileSync as readFileSync7, statSync as statSync5 } from "fs";
|
|
5554
5715
|
import path16 from "path";
|
|
5555
5716
|
import fs13 from "fs-extra";
|
|
5556
5717
|
|
|
@@ -6209,7 +6370,7 @@ function relativeSpecifierResolves(fromFile, spec) {
|
|
|
6209
6370
|
const base = path16.resolve(path16.dirname(fromFile), spec);
|
|
6210
6371
|
return RESOLVE_EXTS.some((ext) => {
|
|
6211
6372
|
try {
|
|
6212
|
-
return
|
|
6373
|
+
return statSync5(base + ext).isFile();
|
|
6213
6374
|
} catch {
|
|
6214
6375
|
return false;
|
|
6215
6376
|
}
|
package/dist/monet.js
CHANGED