create-fuzionx 0.1.32 → 0.1.34
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 +6 -0
- package/package.json +1 -1
- package/templates/common/.env.example.tpl +16 -0
- package/templates/common/.gitignore.tpl +7 -0
- package/templates/common/fuzionx.yaml.tpl +15 -7
- package/templates/common/package.json.tpl +2 -2
- package/templates/spa/meta.json +1 -1
- package/templates/ssr/public/js/fx-client.js +107 -0
package/index.js
CHANGED
|
@@ -66,6 +66,7 @@ async function createApp(name, targetDir, type = 'spa') {
|
|
|
66
66
|
const appName = type; // 앱 디렉토리명은 타입과 동일
|
|
67
67
|
const vars = {
|
|
68
68
|
name,
|
|
69
|
+
appName: type,
|
|
69
70
|
dbName: name.replace(/-/g, '_'),
|
|
70
71
|
};
|
|
71
72
|
|
|
@@ -107,6 +108,11 @@ async function createApp(name, targetDir, type = 'spa') {
|
|
|
107
108
|
const rendered = render(content, vars);
|
|
108
109
|
const destName = entry.name.replace(/\.tpl$/, '');
|
|
109
110
|
await fs.writeFile(path.join(dir, destName), rendered);
|
|
111
|
+
|
|
112
|
+
// .env.example → .env 도 함께 생성
|
|
113
|
+
if (destName === '.env.example') {
|
|
114
|
+
await fs.writeFile(path.join(dir, '.env'), rendered);
|
|
115
|
+
}
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# .env — FuzionX App 환경 변수
|
|
2
|
+
|
|
3
|
+
# ASP 암호화 (Bridge + WASM 공유)
|
|
4
|
+
ASP_SECRET=change-me-in-production
|
|
5
|
+
|
|
6
|
+
# Auth (JWT/세션)
|
|
7
|
+
JWT_SECRET=change-me-in-production
|
|
8
|
+
|
|
9
|
+
# Client Secret (설정값 암호화 → SPA 주입)
|
|
10
|
+
CLIENT_SECRET=change-me-in-production
|
|
11
|
+
|
|
12
|
+
# Database
|
|
13
|
+
DB_NAME={{dbName}}
|
|
14
|
+
|
|
15
|
+
# Redis (세션/큐 — 미사용 시 빈 값)
|
|
16
|
+
REDIS_URL=
|
|
@@ -38,25 +38,25 @@ bridge:
|
|
|
38
38
|
|
|
39
39
|
# ── 세션 ──
|
|
40
40
|
session:
|
|
41
|
-
enabled:
|
|
42
|
-
store:
|
|
41
|
+
enabled: true
|
|
42
|
+
store: file # file | memory | redis
|
|
43
43
|
ttl: 3600 # 세션 TTL (초)
|
|
44
44
|
cookie_name: fuzionx.sid
|
|
45
45
|
# redis_url: "redis://localhost:6379"
|
|
46
46
|
|
|
47
47
|
# ── 국제화 (i18n) ──
|
|
48
48
|
i18n:
|
|
49
|
-
enabled:
|
|
49
|
+
enabled: true
|
|
50
50
|
default_locale: ko
|
|
51
51
|
locale_dir: ./locales
|
|
52
|
-
auto_complete:
|
|
52
|
+
auto_complete: true
|
|
53
53
|
locales:
|
|
54
54
|
- ko
|
|
55
55
|
- en
|
|
56
56
|
|
|
57
57
|
# ── WebSocket ──
|
|
58
58
|
websocket:
|
|
59
|
-
enabled:
|
|
59
|
+
enabled: true
|
|
60
60
|
path: /ws
|
|
61
61
|
check_interval: 60 # 헬스체크 간격 (초)
|
|
62
62
|
timeout: 60 # 타임아웃 (초)
|
|
@@ -79,6 +79,9 @@ bridge:
|
|
|
79
79
|
- image/gif
|
|
80
80
|
- video/mp4
|
|
81
81
|
- video/webm
|
|
82
|
+
- video/quicktime
|
|
83
|
+
- video/matroska
|
|
84
|
+
- video/x-matroska
|
|
82
85
|
- application/pdf
|
|
83
86
|
# watermark: ./assets/watermark.png
|
|
84
87
|
# watermark_opacity: 50
|
|
@@ -89,6 +92,8 @@ bridge:
|
|
|
89
92
|
path: ./public
|
|
90
93
|
- url: /wasm
|
|
91
94
|
path: ./node_modules/@fuzionx/client
|
|
95
|
+
- url: /storage
|
|
96
|
+
path: ./storage
|
|
92
97
|
|
|
93
98
|
# ── 로깅 ──
|
|
94
99
|
logging:
|
|
@@ -162,6 +167,9 @@ app:
|
|
|
162
167
|
# refreshTtl: '7d'
|
|
163
168
|
# bcrypt_rounds: 12
|
|
164
169
|
|
|
170
|
+
# Client Secret (SPA 설정값 암호화)
|
|
171
|
+
client_secret: '${CLIENT_SECRET:change-me-in-production}'
|
|
172
|
+
|
|
165
173
|
# 국제화 (프레임워크 편의 설정)
|
|
166
174
|
i18n:
|
|
167
175
|
default_locale: 'ko'
|
|
@@ -198,7 +206,7 @@ app:
|
|
|
198
206
|
# prefix: "myapp:queue"
|
|
199
207
|
|
|
200
208
|
# ── Multi-App (도메인 → 앱 라우팅) ────────────────
|
|
201
|
-
# tester를 실행하려면
|
|
209
|
+
# tester를 실행하려면 {{appName}}를 주석 처리하고 tester 주석을 해제하세요.
|
|
202
210
|
apps:
|
|
203
|
-
"127.0.0.1:49080":
|
|
211
|
+
"127.0.0.1:49080": {{appName}}
|
|
204
212
|
# "127.0.0.1:49080": tester
|
package/templates/spa/meta.json
CHANGED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FuzionX SSR Client — WASM ASP HTTP + WebSocket 통합 클라이언트
|
|
3
|
+
*
|
|
4
|
+
* create-fuzionx tester 레이아웃 패턴 기반.
|
|
5
|
+
* WASM 로드 → FuzionXClient, FuzionXSocket, aspFetch 글로벌 노출.
|
|
6
|
+
*
|
|
7
|
+
* 사용법 (인증 유저):
|
|
8
|
+
* FxClient.init(clientSecret, encSecret, headerSignal)
|
|
9
|
+
*
|
|
10
|
+
* 사용법 (공개 페이지):
|
|
11
|
+
* FxClient.initPublic(masterSecret, headerSignal)
|
|
12
|
+
*/
|
|
13
|
+
(function () {
|
|
14
|
+
'use strict';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* 인증 유저용 — 암호화된 masterSecret 복호화 후 ASP 클라이언트 생성
|
|
18
|
+
*/
|
|
19
|
+
function init(clientSecret, encSecret, headerSignal) {
|
|
20
|
+
if (!clientSecret || !encSecret) return;
|
|
21
|
+
|
|
22
|
+
window.aspEnabled = true;
|
|
23
|
+
window._aspReady = (async () => {
|
|
24
|
+
try {
|
|
25
|
+
const _v = Date.now();
|
|
26
|
+
const mod = await import(`/wasm/fuzionx_client_wasm.js?v=${_v}`);
|
|
27
|
+
await mod.default({ module_or_path: `/wasm/fuzionx_client_wasm_bg.wasm?v=${_v}` });
|
|
28
|
+
const { FuzionXClient, FuzionXSocket } = mod;
|
|
29
|
+
window.FuzionXSocket = FuzionXSocket;
|
|
30
|
+
|
|
31
|
+
// 임시 클라이언트로 masterSecret 복호화
|
|
32
|
+
const tmp = new FuzionXClient('_init_');
|
|
33
|
+
const masterSecret = tmp.decrypt_custom(clientSecret, encSecret);
|
|
34
|
+
window._aspMasterSecret = masterSecret;
|
|
35
|
+
|
|
36
|
+
// ASP 활성 클라이언트 생성
|
|
37
|
+
window._aspClient = FuzionXClient.new_with_options(
|
|
38
|
+
masterSecret,
|
|
39
|
+
headerSignal || 'Ruxy-Enc-Mode',
|
|
40
|
+
);
|
|
41
|
+
console.log('[FxClient] WASM ASP client ready');
|
|
42
|
+
} catch (e) {
|
|
43
|
+
console.warn('[FxClient] WASM init failed:', e);
|
|
44
|
+
}
|
|
45
|
+
})();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* 공개 페이지용 — masterSecret 직접 사용
|
|
50
|
+
*/
|
|
51
|
+
function initPublic(masterSecret, headerSignal) {
|
|
52
|
+
window.aspEnabled = !!masterSecret;
|
|
53
|
+
if (masterSecret) window._aspMasterSecret = masterSecret;
|
|
54
|
+
|
|
55
|
+
window._aspReady = (async () => {
|
|
56
|
+
try {
|
|
57
|
+
const _v = Date.now();
|
|
58
|
+
const mod = await import(`/wasm/fuzionx_client_wasm.js?v=${_v}`);
|
|
59
|
+
await mod.default({ module_or_path: `/wasm/fuzionx_client_wasm_bg.wasm?v=${_v}` });
|
|
60
|
+
const { FuzionXClient, FuzionXSocket } = mod;
|
|
61
|
+
window.FuzionXSocket = FuzionXSocket;
|
|
62
|
+
|
|
63
|
+
if (masterSecret) {
|
|
64
|
+
window._aspClient = FuzionXClient.new_with_options(
|
|
65
|
+
masterSecret,
|
|
66
|
+
headerSignal || 'Ruxy-Enc-Mode',
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
console.log('[FxClient] WASM client ready (public)');
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.warn('[FxClient] WASM init failed:', e);
|
|
72
|
+
}
|
|
73
|
+
})();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* ASP 암호화 fetch — create-fuzionx tester aspFetch 동일 패턴
|
|
78
|
+
*/
|
|
79
|
+
window.aspFetch = async function (url, opts = {}) {
|
|
80
|
+
if (window._aspReady) await window._aspReady;
|
|
81
|
+
const method = (opts.method || 'GET').toUpperCase();
|
|
82
|
+
if (!url.startsWith('/api') || !window._aspClient) return fetch(url, opts);
|
|
83
|
+
|
|
84
|
+
if (opts.body instanceof FormData) {
|
|
85
|
+
return window._aspClient.upload(url, opts.body);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
let bodyObj = undefined;
|
|
89
|
+
if (opts.body) {
|
|
90
|
+
bodyObj = typeof opts.body === 'string' ? JSON.parse(opts.body) : opts.body;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
switch (method) {
|
|
94
|
+
case 'GET': return window._aspClient.get(url);
|
|
95
|
+
case 'POST': return window._aspClient.post(url, bodyObj);
|
|
96
|
+
case 'PUT': return window._aspClient.put(url, bodyObj);
|
|
97
|
+
case 'PATCH': return window._aspClient.patch(url, bodyObj);
|
|
98
|
+
case 'DELETE': return window._aspClient.delete(url);
|
|
99
|
+
default: return window._aspClient.get(url);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
// 글로벌 노출
|
|
104
|
+
window.FxClient = { init, initPublic };
|
|
105
|
+
window.aspEnabled = false;
|
|
106
|
+
window._aspReady = Promise.resolve();
|
|
107
|
+
})();
|