create-sonamu 0.1.9 → 0.1.11

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/index.js CHANGED
@@ -205,6 +205,9 @@ function init() {
205
205
  if (basename === "gitignore") {
206
206
  destPath = path.join(path.dirname(dest), ".gitignore");
207
207
  }
208
+ if (basename === "env") {
209
+ destPath = path.join(path.dirname(dest), ".env");
210
+ }
208
211
  fs.copyFileSync(src, destPath);
209
212
  // 셸 스크립트는 실행권한 부여
210
213
  if (basename.endsWith(".sh")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sonamu",
3
- "version": "0.1.9",
3
+ "version": "0.1.11",
4
4
  "description": "Create a new Sonamu project",
5
5
  "keywords": [
6
6
  "sonamu",
@@ -59,3 +59,7 @@ Thumbs.db
59
59
 
60
60
  # Slack Confirm
61
61
  .slack-confirm-*
62
+
63
+ # Claude
64
+ .claude/skills/sonamu/
65
+ .claude/CLAUDE.md
@@ -0,0 +1,9 @@
1
+ # Database Configuration
2
+ # DB_HOST=0.0.0.0
3
+ # DB_PORT=
4
+ # DB_USER=postgres
5
+ # DB_PASSWORD=
6
+ # CONTAINER_NAME=
7
+ # DATABASE_NAME=
8
+ # PROJECT_NAME=
9
+ # ANTHROPIC_API_KEY=
@@ -39,7 +39,7 @@
39
39
  "knex": "^3.1.0",
40
40
  "pg": "^8.16.3",
41
41
  "radashi": "^12.2.0",
42
- "sonamu": "^0.8.7",
42
+ "sonamu": "^0.8.8",
43
43
  "zod": "^4.3.6"
44
44
  },
45
45
  "devDependencies": {
@@ -1,8 +1,13 @@
1
- import path from "node:path";
2
- import { defineConfig } from "sonamu";
1
+ import { getConsoleSink } from "@logtape/logtape";
2
+ import { getPrettyFormatter } from "@logtape/pretty";
3
+ import dotenv from "dotenv";
4
+ import path from "path";
5
+ import { CachePresets, defineConfig, passkey, twoFactor } from "sonamu";
3
6
  import { drivers as cacheDrivers, store } from "sonamu/cache";
4
7
  import { drivers } from "sonamu/storage";
5
8
 
9
+ dotenv.config({ path: path.join(import.meta.dirname, "../.env") });
10
+
6
11
  const host = "localhost";
7
12
  const port = 34900;
8
13
 
@@ -35,6 +40,65 @@ export default defineConfig({
35
40
  },
36
41
  },
37
42
 
43
+ slackConfirm:
44
+ process.env.SLACK_BOT_TOKEN && process.env.SLACK_CHANNEL_ID
45
+ ? {
46
+ targets: ["development_master", "production_master"],
47
+ botToken: process.env.SLACK_BOT_TOKEN ?? "",
48
+ channelId: process.env.SLACK_CHANNEL_ID ?? "",
49
+ }
50
+ : undefined,
51
+
52
+ test: {
53
+ parallel: true,
54
+ maxWorkers: 4,
55
+ devRunner: { enabled: true },
56
+ },
57
+
58
+ logging: {
59
+ sinks: {
60
+ console: getConsoleSink({
61
+ formatter: getPrettyFormatter({
62
+ timestamp: "time",
63
+ categoryWidth: 20,
64
+ categoryTruncate: "middle",
65
+ }),
66
+ }),
67
+ },
68
+ loggers: [
69
+ {
70
+ category: ["sonamu"],
71
+ sinks: ["console"],
72
+ lowestLevel: process.env.NODE_ENV === "test" ? "warning" : "debug",
73
+ },
74
+ {
75
+ category: ["sonamu", "internal", "tasks"],
76
+ sinks: ["console"],
77
+ lowestLevel: "error",
78
+ },
79
+ {
80
+ category: ["tasks"],
81
+ sinks: ["console"],
82
+ lowestLevel: "info",
83
+ },
84
+ ],
85
+ },
86
+
87
+ tasks: {
88
+ enableWorker: !["true", "1"].includes(process.env.DISABLE_WORKER ?? "false"),
89
+ workerOptions: {
90
+ concurrency: 1,
91
+ usePubSub: true,
92
+ listenDelay: 500,
93
+ },
94
+ contextProvider: (defaultContext) => {
95
+ return {
96
+ ...defaultContext,
97
+ ip: "127.0.0.1",
98
+ };
99
+ },
100
+ },
101
+
38
102
  server: {
39
103
  listen: { port, host },
40
104
  plugins: {
@@ -51,6 +115,8 @@ export default defineConfig({
51
115
  },
52
116
 
53
117
  auth: {
118
+ appName: "Sonamu Project",
119
+ plugins: [twoFactor(), passkey()],
54
120
  emailAndPassword: { enabled: true },
55
121
  baseURL: process.env.BETTER_AUTH_URL ?? `http://${host}:${port}`,
56
122
  secret: process.env.BETTER_AUTH_SECRET ?? "miomock-secret-key-change-this-in-production",
@@ -58,6 +124,16 @@ export default defineConfig({
58
124
  session: {
59
125
  expiresIn: 60 * 60 * 24 * 365,
60
126
  },
127
+ user: {
128
+ fields: {
129
+ name: "username",
130
+ emailVerified: "is_verified",
131
+ },
132
+ additionalFields: {
133
+ role: { type: "string", sonamuType: "UserRole" },
134
+ created_at: { type: "date" },
135
+ },
136
+ },
61
137
  },
62
138
 
63
139
  apiConfig: {
@@ -72,6 +148,39 @@ export default defineConfig({
72
148
  if (_guard === "user") {
73
149
  console.log("user guard");
74
150
  }
151
+ console.log("NOTHING YET");
152
+ },
153
+ cacheControlHandler: (req) => {
154
+ switch (req.type) {
155
+ case "assets":
156
+ // Hash 포함된 파일: 영구 캐시
157
+ if (req.path.match(/-[a-f0-9]+\./)) {
158
+ return CachePresets.immutable;
159
+ }
160
+ return CachePresets.longLived;
161
+
162
+ case "api":
163
+ // GET 요청만 캐싱 고려
164
+ if (req.method === "GET") {
165
+ // 특정 경로는 짧은 캐시
166
+ if (req.path.startsWith("/api/static-data")) {
167
+ return CachePresets.shortLived;
168
+ }
169
+ if (req.path.startsWith("/api/terms")) {
170
+ return CachePresets.mediumLived;
171
+ }
172
+ }
173
+ // 기본: 캐시 없음
174
+ return CachePresets.noCache;
175
+
176
+ case "ssr":
177
+ // SSR 페이지: 10초 캐시
178
+ return CachePresets.ssr;
179
+
180
+ case "csr":
181
+ // CSR fallback (index.html): 1분 캐시
182
+ return CachePresets.shortLived;
183
+ }
75
184
  },
76
185
  },
77
186