@m1kapp/kit 0.0.31 → 0.0.32
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 +16 -12
- package/bin/stats.mjs +12 -5
- package/dist/index.d.mts +16 -1
- package/dist/index.d.ts +16 -1
- package/dist/index.js +3 -3
- package/dist/index.mjs +3 -3
- package/dist/meta.json +4 -4
- package/dist/pwa.js +1 -1
- package/dist/pwa.mjs +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,21 +17,25 @@ npm install @m1kapp/kit
|
|
|
17
17
|
|
|
18
18
|
```tsx
|
|
19
19
|
// CSS 자동 주입 — 별도 import 불필요
|
|
20
|
-
import { AppShell, AppShellHeader, AppShellContent, TabBar, Tab } from "@m1kapp/kit";
|
|
20
|
+
import { Watermark, AppShell, AppShellHeader, AppShellContent, Section, TabBar, Tab } from "@m1kapp/kit";
|
|
21
21
|
|
|
22
22
|
export default function App() {
|
|
23
23
|
return (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
// Watermark가 뷰포트 전체 높이/중앙정렬/하단 크레딧을 같이 줍니다.
|
|
25
|
+
// AppShell만 단독으로 쓰면 콘텐츠 높이만큼 쪼그라들어요.
|
|
26
|
+
<Watermark color="#e2603f" text="myapp">
|
|
27
|
+
<AppShell>
|
|
28
|
+
<AppShellHeader>
|
|
29
|
+
<h1>My App</h1>
|
|
30
|
+
</AppShellHeader>
|
|
31
|
+
<AppShellContent>
|
|
32
|
+
<Section className="pt-4">{/* 콘텐츠 — Divider로 섹션 구분 */}</Section>
|
|
33
|
+
</AppShellContent>
|
|
34
|
+
<TabBar>
|
|
35
|
+
<Tab href="/" icon={<HomeIcon />} label="홈" />
|
|
36
|
+
</TabBar>
|
|
37
|
+
</AppShell>
|
|
38
|
+
</Watermark>
|
|
35
39
|
);
|
|
36
40
|
}
|
|
37
41
|
```
|
package/bin/stats.mjs
CHANGED
|
@@ -390,6 +390,7 @@ let totalBranches = 0;
|
|
|
390
390
|
let totalFunctions = 0;
|
|
391
391
|
let maxFile = { path: "", lines: 0 };
|
|
392
392
|
let longFiles = 0; // 200줄 초과 파일 수
|
|
393
|
+
let longFileSeverity = 0; // 200→400줄 0→1, 400→600줄 1→2로 완만하게 누적 (600줄+ 파일당 최대 2)
|
|
393
394
|
const allImports = new Set();
|
|
394
395
|
const ts = loadTypescript();
|
|
395
396
|
const allFns = []; // AST 모드: {name, cc, cog, line, file}
|
|
@@ -417,7 +418,10 @@ for (const file of files) {
|
|
|
417
418
|
fileContents.push({ file: rel, content });
|
|
418
419
|
}
|
|
419
420
|
if (counts.code > maxFile.lines) maxFile = { path: path.relative(process.cwd(), file), lines: counts.code };
|
|
420
|
-
if (counts.code > 200)
|
|
421
|
+
if (counts.code > 200) {
|
|
422
|
+
longFiles++;
|
|
423
|
+
longFileSeverity += Math.min(2, (counts.code - 200) / 200);
|
|
424
|
+
}
|
|
421
425
|
const imports = detectKitImports(content);
|
|
422
426
|
for (const imp of imports) allImports.add(imp);
|
|
423
427
|
}
|
|
@@ -431,7 +435,10 @@ const avgFileLines = files.length > 0 ? Math.round(codeLines / files.length) : 0
|
|
|
431
435
|
// - cog>15 함수 비율 ×3 (최대 25), cog>25 함수 비율 ×5 (최대 15)
|
|
432
436
|
// - 최악 함수: cog 20 초과분 ×1 (최대 15)
|
|
433
437
|
// - 중복 밀도: 3% 초과분 ×2.5 (최대 25) ← 새 축
|
|
434
|
-
// - 200줄 초과
|
|
438
|
+
// - 200줄 초과 파일: 초과분에 비례한 심각도(200→400줄 0→1, 400→600줄 1→2, 600줄+ 캡) 비율 ×1.5 (최대 10)
|
|
439
|
+
// ※ 파일 개수 기준 이진 카운트(200줄 넘으면 무조건 1) 대신 심각도 가중 — 살짝 넘는 파일과
|
|
440
|
+
// 터무니없이 큰 파일을 구분하고, 파일 수 적은 프로젝트가 파일 1개만으로 즉시 만점 감점 맞는 절벽 방지.
|
|
441
|
+
// / 평균 파일 길이 80줄 초과분 /5 (최대 10)
|
|
435
442
|
let qualityScore;
|
|
436
443
|
let cc = null;
|
|
437
444
|
let cognitive = null;
|
|
@@ -465,14 +472,14 @@ if (ts && allFns.length > 0) {
|
|
|
465
472
|
|
|
466
473
|
const over15Pct = (cogOver15.length / allFns.length) * 100;
|
|
467
474
|
const over25Pct = (cogOver25.length / allFns.length) * 100;
|
|
468
|
-
const
|
|
475
|
+
const longFileSeverityPct = (longFileSeverity / files.length) * 100;
|
|
469
476
|
qualityScore = Math.max(0, Math.round(
|
|
470
477
|
100
|
|
471
478
|
- Math.min(25, over15Pct * 3)
|
|
472
479
|
- Math.min(15, over25Pct * 5)
|
|
473
480
|
- Math.min(15, Math.max(0, maxCog - 20))
|
|
474
481
|
- Math.min(25, Math.max(0, duplication.percent - 3) * 2.5)
|
|
475
|
-
- Math.min(10,
|
|
482
|
+
- Math.min(10, longFileSeverityPct * 1.5)
|
|
476
483
|
- Math.min(10, Math.max(0, avgFileLines - 80) / 5)
|
|
477
484
|
));
|
|
478
485
|
} else {
|
|
@@ -480,7 +487,7 @@ if (ts && allFns.length > 0) {
|
|
|
480
487
|
qualityScore = Math.max(0, Math.round(
|
|
481
488
|
100
|
|
482
489
|
- Math.min(40, Math.max(0, branchDensity - 10) * 2)
|
|
483
|
-
- Math.min(30,
|
|
490
|
+
- Math.min(30, longFileSeverity * 2.5)
|
|
484
491
|
- Math.min(30, Math.max(0, avgFileLines - 80) / 4)
|
|
485
492
|
));
|
|
486
493
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -65,6 +65,19 @@ interface AppShellProps {
|
|
|
65
65
|
/**
|
|
66
66
|
* Mobile app-like container with rounded corners, shadow, and ring.
|
|
67
67
|
* Centers content and constrains width for a phone-like viewport.
|
|
68
|
+
*
|
|
69
|
+
* `AppShell` fills `h-full` of its parent — it does not size itself. Wrap it
|
|
70
|
+
* in `<Watermark>` (gives `h-dvh` + centering + the `PoweredByKit` credit
|
|
71
|
+
* strip) rather than a hand-rolled height/centering div; without a sized
|
|
72
|
+
* parent the shell just collapses to content height.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* <Watermark color="#e2603f" text="myapp">
|
|
76
|
+
* <AppShell>
|
|
77
|
+
* <AppShellHeader>...</AppShellHeader>
|
|
78
|
+
* <AppShellContent><Section>...</Section></AppShellContent>
|
|
79
|
+
* </AppShell>
|
|
80
|
+
* </Watermark>
|
|
68
81
|
*/
|
|
69
82
|
declare function AppShell({ children, className, maxWidth, maxHeight, accent, accentFg, style, }: AppShellProps): react_jsx_runtime.JSX.Element;
|
|
70
83
|
interface AppShellHeaderProps {
|
|
@@ -80,7 +93,9 @@ interface AppShellContentProps {
|
|
|
80
93
|
className?: string;
|
|
81
94
|
}
|
|
82
95
|
/**
|
|
83
|
-
* Scrollable main content area.
|
|
96
|
+
* Scrollable main content area. Carries no padding of its own — build
|
|
97
|
+
* children from `<Section>` (px-4) blocks separated by `<Divider spacing="sm" />`,
|
|
98
|
+
* not a hand-rolled `<div className="p-4 flex flex-col gap-4">`.
|
|
84
99
|
*/
|
|
85
100
|
declare function AppShellContent({ children, className }: AppShellContentProps): react_jsx_runtime.JSX.Element;
|
|
86
101
|
|
package/dist/index.d.ts
CHANGED
|
@@ -65,6 +65,19 @@ interface AppShellProps {
|
|
|
65
65
|
/**
|
|
66
66
|
* Mobile app-like container with rounded corners, shadow, and ring.
|
|
67
67
|
* Centers content and constrains width for a phone-like viewport.
|
|
68
|
+
*
|
|
69
|
+
* `AppShell` fills `h-full` of its parent — it does not size itself. Wrap it
|
|
70
|
+
* in `<Watermark>` (gives `h-dvh` + centering + the `PoweredByKit` credit
|
|
71
|
+
* strip) rather than a hand-rolled height/centering div; without a sized
|
|
72
|
+
* parent the shell just collapses to content height.
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* <Watermark color="#e2603f" text="myapp">
|
|
76
|
+
* <AppShell>
|
|
77
|
+
* <AppShellHeader>...</AppShellHeader>
|
|
78
|
+
* <AppShellContent><Section>...</Section></AppShellContent>
|
|
79
|
+
* </AppShell>
|
|
80
|
+
* </Watermark>
|
|
68
81
|
*/
|
|
69
82
|
declare function AppShell({ children, className, maxWidth, maxHeight, accent, accentFg, style, }: AppShellProps): react_jsx_runtime.JSX.Element;
|
|
70
83
|
interface AppShellHeaderProps {
|
|
@@ -80,7 +93,9 @@ interface AppShellContentProps {
|
|
|
80
93
|
className?: string;
|
|
81
94
|
}
|
|
82
95
|
/**
|
|
83
|
-
* Scrollable main content area.
|
|
96
|
+
* Scrollable main content area. Carries no padding of its own — build
|
|
97
|
+
* children from `<Section>` (px-4) blocks separated by `<Divider spacing="sm" />`,
|
|
98
|
+
* not a hand-rolled `<div className="p-4 flex flex-col gap-4">`.
|
|
84
99
|
*/
|
|
85
100
|
declare function AppShellContent({ children, className }: AppShellContentProps): react_jsx_runtime.JSX.Element;
|
|
86
101
|
|