mega-framework 0.1.3 → 0.1.5
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/package.json +1 -1
- package/sample/crud/yarn.lock +1 -1
- package/src/adapters/file-adapter.js +5 -0
- package/src/adapters/mega-cache-adapter.js +6 -2
- package/src/adapters/nats-adapter.js +6 -1
- package/src/cli/commands/console-cmd.js +4 -2
- package/src/cli/commands/new.js +115 -67
- package/src/cli/commands/scaffold.js +6 -12
- package/src/cli/index.js +1 -1
- package/src/core/mega-app.js +11 -3
- package/src/core/mega-cluster.js +27 -17
- package/src/core/ws-upgrade.js +19 -1
- package/src/lib/asp/nonce-cache.js +12 -0
- package/src/lib/logger/telegram-core.js +33 -5
- package/src/lib/logger/telegram-transport.js +22 -2
- package/src/lib/mega-job-queue.js +22 -1
- package/src/lib/mega-logger.js +41 -2
- package/src/lib/mega-shutdown.js +46 -2
- package/sample/crud/test/apps/main/auth-flow.integration.test.js +0 -177
- package/sample/crud/test/apps/main/auth-service.test.js +0 -93
- package/sample/crud/test/apps/main/chat-channel.test.js +0 -149
- package/sample/crud/test/apps/main/cron-demo-service.test.js +0 -93
- package/sample/crud/test/apps/main/demo-flow.integration.test.js +0 -386
- package/sample/crud/test/apps/main/email-job.test.js +0 -76
- package/sample/crud/test/apps/main/guide-service.test.js +0 -68
- package/sample/crud/test/apps/main/hash-task.test.js +0 -30
- package/sample/crud/test/apps/main/jobs-demo-service.test.js +0 -88
- package/sample/crud/test/apps/main/logs-demo-service.test.js +0 -85
- package/sample/crud/test/apps/main/metrics-demo-service.test.js +0 -90
- package/sample/crud/test/apps/main/note-service.test.js +0 -68
- package/sample/crud/test/apps/main/perf-service.test.js +0 -121
- package/sample/crud/test/apps/main/perf.integration.test.js +0 -202
- package/sample/crud/test/apps/main/redis-demo-service.test.js +0 -98
- package/sample/crud/test/apps/main/tracing-demo-service.test.js +0 -90
- package/sample/crud/test/apps/main/upload-demo-service.test.js +0 -61
- package/sample/crud/test/apps/main/user-service.test.js +0 -65
- package/sample/crud/test/apps/main/ws-chat.integration.test.js +0 -233
- package/templates/project/app.config.tpl +0 -8
- package/templates/project/app.config.views.tpl +0 -37
- package/templates/project/ecosystem.config.tpl +0 -10
- package/templates/project/env.tpl +0 -12
- package/templates/project/gitignore.tpl +0 -8
- package/templates/project/locales/client/en.json.tpl +0 -3
- package/templates/project/locales/client/ko.json.tpl +0 -3
- package/templates/project/locales/server/en.json.tpl +0 -17
- package/templates/project/locales/server/ko.json.tpl +0 -17
- package/templates/project/mega.config.tpl +0 -11
- package/templates/project/package.tpl +0 -25
- package/templates/project/public/css/app.css +0 -101
- package/templates/project/public/js/app.js +0 -54
- package/templates/project/public/js/theme-init.js +0 -12
- package/templates/project/public/vendor/bootstrap/bootstrap.bundle.min.js +0 -7
- package/templates/project/public/vendor/bootstrap/bootstrap.min.css +0 -6
- package/templates/project/readme.tpl +0 -48
- package/templates/project/route.test.tpl +0 -13
- package/templates/project/route.test.views.tpl +0 -15
- package/templates/project/route.tpl +0 -10
- package/templates/project/route.views.tpl +0 -10
- package/templates/project/views/index.ejs.tpl +0 -58
- package/templates/project/views/layout.ejs.tpl +0 -73
- package/templates/project/vitest.config.tpl +0 -8
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import { describe, test, expect } from 'vitest'
|
|
3
|
-
import routes from '../../../apps/main/routes/index.js'
|
|
4
|
-
|
|
5
|
-
describe('main app index route', () => {
|
|
6
|
-
test('GET / 등록 + hello world 반환', async () => {
|
|
7
|
-
/** @type {Function|undefined} */
|
|
8
|
-
let handler
|
|
9
|
-
routes({ http: { get: (/** @type {string} */ _p, /** @type {Function} */ h) => void (handler = h) } })
|
|
10
|
-
expect(typeof handler).toBe('function')
|
|
11
|
-
expect(await /** @type {any} */ (handler)({}, {}, {})).toEqual({ message: 'Hello from {{name}}!' })
|
|
12
|
-
})
|
|
13
|
-
})
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
import { describe, test, expect, vi } from 'vitest'
|
|
3
|
-
import routes from '../../../apps/main/routes/index.js'
|
|
4
|
-
|
|
5
|
-
describe('main app index route (views)', () => {
|
|
6
|
-
test('GET / 가 index 뷰를 렌더', async () => {
|
|
7
|
-
/** @type {Function|undefined} */
|
|
8
|
-
let handler
|
|
9
|
-
routes({ http: { get: (/** @type {string} */ _p, /** @type {Function} */ h) => void (handler = h) } })
|
|
10
|
-
expect(typeof handler).toBe('function')
|
|
11
|
-
const ctx = { t: (/** @type {string} */ k) => k, render: vi.fn(() => 'html') }
|
|
12
|
-
await /** @type {any} */ (handler)({}, {}, ctx)
|
|
13
|
-
expect(ctx.render).toHaveBeenCalledWith('index', { title: 'welcome' })
|
|
14
|
-
})
|
|
15
|
-
})
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/**
|
|
3
|
-
* apps/main 기본 라우트 — 자동 로딩(loadRoutes). `mega start` 후 GET / 로 hello world.
|
|
4
|
-
*/
|
|
5
|
-
export default (/** @type {any} */ router) => {
|
|
6
|
-
router.http.get('/', async (/** @type {any} */ _req, /** @type {any} */ _res, /** @type {any} */ _ctx) => {
|
|
7
|
-
// 핸들러는 raw data 만 반환한다 — 프레임워크가 `{ ok, data, meta }` envelope 로 자동 wrap(ADR-018).
|
|
8
|
-
return { message: 'Hello from {{name}}!' }
|
|
9
|
-
})
|
|
10
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
/**
|
|
3
|
-
* apps/main 기본 라우트 — 자동 로딩(loadRoutes). `mega start` 후 GET / 로 Bootstrap 5 뷰를 렌더한다.
|
|
4
|
-
*/
|
|
5
|
-
export default (/** @type {any} */ router) => {
|
|
6
|
-
router.http.get('/', async (/** @type {any} */ _req, /** @type {any} */ _reply, /** @type {any} */ ctx) => {
|
|
7
|
-
// ctx.render 가 EJS + ejs-mate 로 index.ejs 를 렌더한다(req.t/req.lang 자동 병합 → 다국어 뷰).
|
|
8
|
-
return ctx.render('index', { title: ctx.t('welcome') })
|
|
9
|
-
})
|
|
10
|
-
}
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
<% layout('layouts/main') %>
|
|
2
|
-
|
|
3
|
-
<section class="hero p-4 p-md-5 mb-5">
|
|
4
|
-
<div class="row align-items-center g-4">
|
|
5
|
-
<div class="col-lg-7">
|
|
6
|
-
<span class="badge text-bg-light border mb-3">{{name}}</span>
|
|
7
|
-
<h1 class="display-5 fw-bold mb-3"><%= t('hero_title') %></h1>
|
|
8
|
-
<p class="fs-5 text-body-secondary mb-4"><%= t('hero_subtitle') %></p>
|
|
9
|
-
<div class="d-flex flex-wrap gap-2">
|
|
10
|
-
<a href="https://www.npmjs.com/package/mega-framework" class="btn btn-primary btn-lg" target="_blank" rel="noopener"
|
|
11
|
-
><%= t('hero_cta_primary') %></a
|
|
12
|
-
>
|
|
13
|
-
<a href="https://getbootstrap.com/" class="btn btn-outline-secondary btn-lg" target="_blank" rel="noopener"
|
|
14
|
-
><%= t('hero_cta_secondary') %></a
|
|
15
|
-
>
|
|
16
|
-
</div>
|
|
17
|
-
</div>
|
|
18
|
-
<div class="col-lg-5 text-center d-none d-lg-block">
|
|
19
|
-
<div class="display-1">🚀</div>
|
|
20
|
-
</div>
|
|
21
|
-
</div>
|
|
22
|
-
</section>
|
|
23
|
-
|
|
24
|
-
<section>
|
|
25
|
-
<h2 class="h4 mb-4"><%= t('features_heading') %></h2>
|
|
26
|
-
<div class="row g-4">
|
|
27
|
-
<div class="col-md-4">
|
|
28
|
-
<div class="card h-100 feature-card border-0 shadow-sm">
|
|
29
|
-
<div class="card-body">
|
|
30
|
-
<div class="feature-icon mb-3">🎨</div>
|
|
31
|
-
<h3 class="h5 card-title"><%= t('feature1_title') %></h3>
|
|
32
|
-
<p class="card-text text-body-secondary mb-0"><%= t('feature1_desc') %></p>
|
|
33
|
-
</div>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
<div class="col-md-4">
|
|
37
|
-
<div class="card h-100 feature-card border-0 shadow-sm">
|
|
38
|
-
<div class="card-body">
|
|
39
|
-
<div class="feature-icon mb-3">🌐</div>
|
|
40
|
-
<h3 class="h5 card-title"><%= t('feature2_title') %></h3>
|
|
41
|
-
<p class="card-text text-body-secondary mb-0"><%= t('feature2_desc') %></p>
|
|
42
|
-
</div>
|
|
43
|
-
</div>
|
|
44
|
-
</div>
|
|
45
|
-
<div class="col-md-4">
|
|
46
|
-
<div class="card h-100 feature-card border-0 shadow-sm">
|
|
47
|
-
<div class="card-body">
|
|
48
|
-
<div class="feature-icon mb-3">🌓</div>
|
|
49
|
-
<h3 class="h5 card-title"><%= t('feature3_title') %></h3>
|
|
50
|
-
<p class="card-text text-body-secondary mb-0"><%= t('feature3_desc') %></p>
|
|
51
|
-
</div>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
<p class="text-body-secondary small mt-4 mb-0">
|
|
56
|
-
<code>apps/main/views/index.ejs</code> · <code>lang=<%= lang %></code>
|
|
57
|
-
</p>
|
|
58
|
-
</section>
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
<!doctype html>
|
|
2
|
-
<html lang="<%= lang %>" data-bs-theme="light">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="utf-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
-
<title><%= typeof title !== 'undefined' ? title : '{{name}}' %></title>
|
|
7
|
-
<%# FOUC 방지 — 저장된 테마를 페인트 전에 적용. CSP(script-src 'self')라 인라인 불가 → 외부 파일. %>
|
|
8
|
-
<script src="/static/js/theme-init.js"></script>
|
|
9
|
-
<link rel="stylesheet" href="/static/vendor/bootstrap/bootstrap.min.css" />
|
|
10
|
-
<link rel="stylesheet" href="/static/css/app.css" />
|
|
11
|
-
</head>
|
|
12
|
-
<body class="d-flex flex-column min-vh-100">
|
|
13
|
-
<nav class="navbar navbar-expand-md border-bottom">
|
|
14
|
-
<div class="container">
|
|
15
|
-
<a class="navbar-brand" href="/">{{name}}</a>
|
|
16
|
-
<button
|
|
17
|
-
class="navbar-toggler"
|
|
18
|
-
type="button"
|
|
19
|
-
data-bs-toggle="collapse"
|
|
20
|
-
data-bs-target="#navmenu"
|
|
21
|
-
aria-controls="navmenu"
|
|
22
|
-
aria-expanded="false"
|
|
23
|
-
aria-label="menu"
|
|
24
|
-
>
|
|
25
|
-
<span class="navbar-toggler-icon"></span>
|
|
26
|
-
</button>
|
|
27
|
-
<div class="collapse navbar-collapse" id="navmenu">
|
|
28
|
-
<ul class="navbar-nav me-auto">
|
|
29
|
-
<li class="nav-item"><a class="nav-link" href="/"><%= t('nav_home') %></a></li>
|
|
30
|
-
</ul>
|
|
31
|
-
<div class="d-flex align-items-center gap-2">
|
|
32
|
-
<button
|
|
33
|
-
type="button"
|
|
34
|
-
class="btn btn-outline-secondary btn-sm"
|
|
35
|
-
data-theme-toggle
|
|
36
|
-
aria-label="<%= t('theme_toggle') %>"
|
|
37
|
-
title="<%= t('theme_toggle') %>"
|
|
38
|
-
>
|
|
39
|
-
<span class="theme-icon-light">☀️</span><span class="theme-icon-dark">🌙</span>
|
|
40
|
-
</button>
|
|
41
|
-
<div class="dropdown">
|
|
42
|
-
<button
|
|
43
|
-
class="btn btn-outline-secondary btn-sm dropdown-toggle"
|
|
44
|
-
type="button"
|
|
45
|
-
data-bs-toggle="dropdown"
|
|
46
|
-
aria-expanded="false"
|
|
47
|
-
>
|
|
48
|
-
<%= lang === 'ko' ? '한국어' : 'English' %>
|
|
49
|
-
</button>
|
|
50
|
-
<ul class="dropdown-menu dropdown-menu-end">
|
|
51
|
-
<li><a class="dropdown-item" href="#" data-lang="ko">한국어</a></li>
|
|
52
|
-
<li><a class="dropdown-item" href="#" data-lang="en">English</a></li>
|
|
53
|
-
</ul>
|
|
54
|
-
</div>
|
|
55
|
-
</div>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
</nav>
|
|
59
|
-
|
|
60
|
-
<main class="container py-4 py-md-5 flex-grow-1">
|
|
61
|
-
<%- body %>
|
|
62
|
-
</main>
|
|
63
|
-
|
|
64
|
-
<footer class="site-footer py-4 mt-auto">
|
|
65
|
-
<div class="container text-center text-body-secondary small">
|
|
66
|
-
<%= t('footer_built') %>
|
|
67
|
-
</div>
|
|
68
|
-
</footer>
|
|
69
|
-
|
|
70
|
-
<script src="/static/vendor/bootstrap/bootstrap.bundle.min.js"></script>
|
|
71
|
-
<script src="/static/js/app.js"></script>
|
|
72
|
-
</body>
|
|
73
|
-
</html>
|