sh-ui-cli 0.32.0 → 0.32.1
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 +1 -1
- package/data/changelog/versions.json +13 -0
- package/package.json +1 -1
- package/src/create/generator.js +55 -1
- package/src/create/index.mjs +1 -1
- package/src/create/plugins/authJwt.js +1 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ npx sh-ui-cli create
|
|
|
22
22
|
|
|
23
23
|
# 비대화형 (에이전트 / CI)
|
|
24
24
|
npx sh-ui-cli create my-app --platform next --structure standalone --yes
|
|
25
|
-
npx sh-ui-cli create my-app --platform next --structure monorepo --plugins sentry,next-intl --yes
|
|
25
|
+
npx sh-ui-cli create my-app --platform next --structure monorepo --plugins sentry,next-intl,auth-jwt --yes
|
|
26
26
|
npx sh-ui-cli create my-app --platform flutter --yes
|
|
27
27
|
```
|
|
28
28
|
|
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
3
|
"$description": "sh-ui 릴리즈 노트 단일 소스. docs(React)와 showcase(Flutter)가 함께 읽는다. 새 릴리즈마다 맨 앞에 추가.",
|
|
4
4
|
"versions": [
|
|
5
|
+
{
|
|
6
|
+
"version": "0.32.1",
|
|
7
|
+
"date": "2026-04-29",
|
|
8
|
+
"title": "auth-jwt 의 proxy.ts 경로 버그 수정 + next-intl 와 자동 합성",
|
|
9
|
+
"type": "patch",
|
|
10
|
+
"highlights": [
|
|
11
|
+
"auth-jwt 플러그인이 proxy.ts 를 src/proxy.ts 로 잘못 깔아 Next 16 이 인식 못 하던 문제 — 베이스 템플릿이 app/ 을 root 에 두므로 proxy.ts 도 root 로 가야 함. 결과적으로 v0.32.0 의 인증 라우트 가드가 동작하지 않았음, 이번 패치에서 해결",
|
|
12
|
+
"auth-jwt + next-intl 동시 활성화 시 generator 가 proxy.ts 를 자동 합성 — intl 미들웨어 + locale prefix 를 벗긴 경로 기반 인증 가드. 단독 사용 시에는 각 플러그인의 단일 proxy.ts 그대로 적용",
|
|
13
|
+
"/cli 페이지 플러그인 섹션 갱신 — Sentry 의 옛 axios 인터셉터/apiCore 설명 제거, observability 브릿지 정확화, auth-jwt 항목 신설. 기본 스택의 'Axios' 표기를 fetch 기반 isomorphic http() 로 정정",
|
|
14
|
+
"auth-jwt / next-intl 플러그인 페이지의 폴더 트리 + 파일 설명을 실제 manifest 와 동기화"
|
|
15
|
+
],
|
|
16
|
+
"url": "https://github.com/sanghyeonKim0201/sh-ui/releases/tag/v0.32.1"
|
|
17
|
+
},
|
|
5
18
|
{
|
|
6
19
|
"version": "0.32.0",
|
|
7
20
|
"date": "2026-04-29",
|
package/package.json
CHANGED
package/src/create/generator.js
CHANGED
|
@@ -90,7 +90,7 @@ export async function createProject(options = {}) {
|
|
|
90
90
|
});
|
|
91
91
|
|
|
92
92
|
// plugins 는 미지정시 기본 빈 배열 — prompt 띄우지 않는다.
|
|
93
|
-
// (플러그인을 쓰려면 명시적으로 --plugins sentry,next-intl 사용)
|
|
93
|
+
// (플러그인을 쓰려면 명시적으로 --plugins sentry,next-intl,auth-jwt 등 사용)
|
|
94
94
|
const selectedPluginNames = options.plugins ?? [];
|
|
95
95
|
|
|
96
96
|
const plugins = getPluginsByNames(selectedPluginNames);
|
|
@@ -428,6 +428,60 @@ async function writePluginFiles(targetDir, plugins) {
|
|
|
428
428
|
}
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
|
+
|
|
432
|
+
// auth-jwt + next-intl 동시 활성화 시 proxy.ts 병합
|
|
433
|
+
// (각 플러그인이 단독으로 깐 proxy.ts 를 합친 버전으로 덮어쓴다)
|
|
434
|
+
const names = new Set(plugins.map((p) => p.name));
|
|
435
|
+
if (names.has('auth-jwt') && names.has('next-intl')) {
|
|
436
|
+
const mergedProxy = `import createIntlMiddleware from 'next-intl/middleware';
|
|
437
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
438
|
+
|
|
439
|
+
import { routing } from '@/src/shared/config/i18n/routing';
|
|
440
|
+
|
|
441
|
+
const AUTH_ROUTES = ['/sign-in', '/sign-up'];
|
|
442
|
+
|
|
443
|
+
const intl = createIntlMiddleware(routing);
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* 로케일 prefix (/ko, /en) 를 벗겨 인증 라우트 매칭에 사용한다.
|
|
447
|
+
* 예: /ko/sign-in → /sign-in
|
|
448
|
+
*/
|
|
449
|
+
const stripLocalePrefix = (pathname: string): string => {
|
|
450
|
+
const locales = routing.locales as readonly string[];
|
|
451
|
+
const segments = pathname.split('/').filter(Boolean);
|
|
452
|
+
if (segments[0] && locales.includes(segments[0])) {
|
|
453
|
+
const rest = segments.slice(1).join('/');
|
|
454
|
+
return \`/\${rest}\`.replace(/\\/$/, '') || '/';
|
|
455
|
+
}
|
|
456
|
+
return pathname;
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
/**
|
|
460
|
+
* Next 16+ proxy.ts (구 middleware.ts).
|
|
461
|
+
* next-intl 라우팅 + auth-jwt 토큰 존재 체크 합성 버전.
|
|
462
|
+
*
|
|
463
|
+
* - intl 이 먼저 로케일 prefix 처리 + NEXT_LOCALE 쿠키 set
|
|
464
|
+
* - 그 위에 인증 가드 — 토큰 없고 인증 라우트도 아니면 /sign-in 으로 redirect
|
|
465
|
+
* - AT 만료 검사나 refresh 는 하지 않는다 (BFF 가 처리)
|
|
466
|
+
*/
|
|
467
|
+
export default function proxy(req: NextRequest) {
|
|
468
|
+
const intlRes = intl(req);
|
|
469
|
+
const pathname = stripLocalePrefix(req.nextUrl.pathname);
|
|
470
|
+
const hasToken = !!req.cookies.get('accessToken')?.value;
|
|
471
|
+
const isAuthRoute = AUTH_ROUTES.some((r) => pathname.startsWith(r));
|
|
472
|
+
|
|
473
|
+
if (isAuthRoute) return intlRes;
|
|
474
|
+
if (!hasToken) return NextResponse.redirect(new URL('/sign-in', req.url));
|
|
475
|
+
|
|
476
|
+
return intlRes;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export const config = {
|
|
480
|
+
matcher: '/((?!api|_next|_vercel|monitoring|.*\\\\..*).*)',
|
|
481
|
+
};
|
|
482
|
+
`;
|
|
483
|
+
await fs.writeFile(path.join(targetDir, 'proxy.ts'), mergedProxy);
|
|
484
|
+
}
|
|
431
485
|
}
|
|
432
486
|
|
|
433
487
|
async function composeProviders(targetDir, plugins) {
|
package/src/create/index.mjs
CHANGED
|
@@ -23,7 +23,7 @@ export const HELP_TEXT = `sh-ui create — sh-ui 프로젝트 스캐폴드 (Next
|
|
|
23
23
|
|
|
24
24
|
예 (비대화형 / 에이전트 / CI):
|
|
25
25
|
sh-ui create my-app --platform next --structure standalone --yes
|
|
26
|
-
sh-ui create my-app --platform next --structure monorepo --plugins sentry,next-intl --yes
|
|
26
|
+
sh-ui create my-app --platform next --structure monorepo --plugins sentry,next-intl,auth-jwt --yes
|
|
27
27
|
sh-ui create my-app --platform flutter --yes
|
|
28
28
|
|
|
29
29
|
비대화형 환경(TTY 없음)에서는 누락된 필수 인자가 있으면 prompt 대신 에러로 종료한다.
|
|
@@ -25,7 +25,7 @@ export const authJwtPlugin = {
|
|
|
25
25
|
// BFF 와 withAuthRetry 가 자동 활용한다.
|
|
26
26
|
|
|
27
27
|
files: {
|
|
28
|
-
'
|
|
28
|
+
'proxy.ts': `import { NextRequest, NextResponse } from 'next/server';
|
|
29
29
|
|
|
30
30
|
const AUTH_ROUTES = ['/sign-in', '/sign-up'];
|
|
31
31
|
|