webspresso 0.0.73 → 0.0.75
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 +44 -4
- package/bin/commands/orm-map.js +139 -0
- package/bin/commands/skill.js +22 -8
- package/bin/commands/upgrade.js +146 -0
- package/bin/utils/orm-map-html.js +689 -0
- package/bin/utils/orm-map-load.js +85 -0
- package/bin/utils/orm-map-snapshot.js +179 -0
- package/bin/utils/resolve-webspresso-orm.js +23 -0
- package/bin/webspresso.js +4 -0
- package/core/auth/manager.js +14 -1
- package/core/kernel/app.js +96 -0
- package/core/kernel/base-repository.js +143 -0
- package/core/kernel/events.js +101 -0
- package/core/kernel/flow.js +22 -0
- package/core/kernel/index.js +17 -0
- package/core/kernel/plugin.js +23 -0
- package/core/kernel/plugins/sample-seo.js +26 -0
- package/core/kernel/run-demo.js +58 -0
- package/core/kernel/view.js +167 -0
- package/core/openapi/build-from-api-routes.js +8 -2
- package/core/orm/model.js +3 -1
- package/core/url-path-normalize.js +30 -0
- package/index.d.ts +168 -1
- package/index.js +20 -2
- package/package.json +11 -1
- package/plugins/admin-panel/api.js +43 -15
- package/plugins/admin-panel/app.js +109 -0
- package/plugins/admin-panel/client/README.md +39 -0
- package/plugins/admin-panel/client/load-parts.js +74 -0
- package/plugins/admin-panel/client/manifest.parts.json +12 -0
- package/plugins/admin-panel/client/parts/01-state-api-breadcrumb.js +150 -0
- package/plugins/admin-panel/client/parts/02-filter-components.js +554 -0
- package/plugins/admin-panel/client/parts/03-pagination-intro.js +70 -0
- package/plugins/admin-panel/client/parts/04-field-renderers.js +287 -0
- package/plugins/admin-panel/client/parts/05-rich-text-file-helpers.js +335 -0
- package/plugins/admin-panel/client/parts/06-login-setup-forms.js +125 -0
- package/plugins/admin-panel/client/parts/07-model-list.js +596 -0
- package/plugins/admin-panel/client/parts/08-record-list.js +536 -0
- package/plugins/admin-panel/client/parts/09-record-form.js +170 -0
- package/plugins/admin-panel/client/parts/10-export-registry.js +11 -0
- package/plugins/admin-panel/client/verify-spa-parts.js +32 -0
- package/plugins/admin-panel/client/vite.config.example.mjs +22 -0
- package/plugins/admin-panel/components.js +4 -2640
- package/plugins/admin-panel/core/api-extensions.js +100 -10
- package/plugins/admin-panel/index.js +3 -0
- package/plugins/admin-panel/lib/is-rich-text-empty.js +23 -0
- package/plugins/admin-panel/lib/sanitize-rich-html.js +106 -0
- package/plugins/admin-panel/modules/dashboard.js +17 -13
- package/plugins/admin-panel/modules/user-management.js +118 -27
- package/plugins/data-exchange/export-xlsx.js +3 -0
- package/plugins/data-exchange/record-selection.js +21 -5
- package/plugins/index.js +4 -0
- package/plugins/rate-limit/index.js +178 -0
- package/plugins/redirect/index.js +204 -0
- package/plugins/rest-resources/index.js +2 -1
- package/plugins/site-analytics/admin-component.js +88 -78
- package/plugins/swagger.js +2 -1
- package/plugins/upload/local-file-provider.js +6 -2
- package/src/file-router.js +270 -53
- package/src/njk-frontmatter.js +156 -0
- package/src/plugin-manager.js +4 -2
- package/src/server.js +28 -9
- package/templates/skills/webspresso-usage/REFERENCE-framework.md +276 -0
- package/templates/skills/webspresso-usage/REFERENCE-kernel.md +93 -0
- package/templates/skills/webspresso-usage/SKILL.md +29 -275
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// Login Form Component
|
|
2
|
+
const LoginForm = {
|
|
3
|
+
view: () => m('.min-h-screen.flex.items-center.justify-center.p-4.sm:p-6.bg-gradient-to-br.from-blue-600.via-indigo-600.to-purple-700', [
|
|
4
|
+
m('.w-full.max-w-md', [
|
|
5
|
+
m('.bg-white dark:bg-slate-800.rounded-2xl.shadow-2xl.p-6.sm:p-8', [
|
|
6
|
+
m('div.text-center.mb-6', [
|
|
7
|
+
m('h1.text-2xl.sm:text-3xl.font-bold.text-gray-900.dark:text-slate-50', 'Admin Login'),
|
|
8
|
+
m('p.text-gray-500.dark:text-slate-400.text-sm.mt-1', 'Sign in to your account'),
|
|
9
|
+
]),
|
|
10
|
+
m('form', {
|
|
11
|
+
onsubmit: async (e) => {
|
|
12
|
+
e.preventDefault();
|
|
13
|
+
state.loading = true;
|
|
14
|
+
state.error = null;
|
|
15
|
+
try {
|
|
16
|
+
const data = new FormData(e.target);
|
|
17
|
+
const result = await api.post('/auth/login', {
|
|
18
|
+
email: data.get('email'),
|
|
19
|
+
password: data.get('password'),
|
|
20
|
+
});
|
|
21
|
+
state.user = result.user;
|
|
22
|
+
m.route.set('/');
|
|
23
|
+
} catch (err) {
|
|
24
|
+
state.error = err.message;
|
|
25
|
+
} finally {
|
|
26
|
+
state.loading = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}, [
|
|
30
|
+
state.error ? m('.bg-red-50.border.border-red-200.text-red-700.dark:bg-red-950/50.dark:border-red-800/80.dark:text-red-200.px-4.py-3.rounded-lg.mb-4.text-sm', state.error) : null,
|
|
31
|
+
m('.mb-4', [
|
|
32
|
+
m('label.block.text-sm.font-medium.text-gray-700.dark:text-slate-300.mb-2', { for: 'email' }, 'Email'),
|
|
33
|
+
m('input#email.w-full.px-3.py-2.5.bg-white.text-gray-900.border.border-gray-300.rounded-lg.placeholder-gray-400.focus:ring-2.focus:ring-blue-500.focus:border-blue-500.transition-colors.dark:bg-slate-900/80.dark:border-slate-500.dark:text-slate-100.dark:placeholder-slate-500', {
|
|
34
|
+
type: 'email',
|
|
35
|
+
name: 'email',
|
|
36
|
+
required: true,
|
|
37
|
+
placeholder: 'admin@example.com',
|
|
38
|
+
}),
|
|
39
|
+
]),
|
|
40
|
+
m('.mb-6', [
|
|
41
|
+
m('label.block.text-sm.font-medium.text-gray-700.dark:text-slate-300.mb-2', { for: 'password' }, 'Password'),
|
|
42
|
+
m('input#password.w-full.px-3.py-2.5.bg-white.text-gray-900.border.border-gray-300.rounded-lg.focus:ring-2.focus:ring-blue-500.focus:border-blue-500.transition-colors.dark:bg-slate-900/80.dark:border-slate-500.dark:text-slate-100', {
|
|
43
|
+
type: 'password',
|
|
44
|
+
name: 'password',
|
|
45
|
+
required: true,
|
|
46
|
+
}),
|
|
47
|
+
]),
|
|
48
|
+
m('button.w-full.bg-blue-600.text-white.py-2.5.px-4.rounded-lg.font-medium.hover:bg-blue-700.focus:ring-2.focus:ring-blue-500.focus:ring-offset-2.dark:focus:ring-offset-slate-800.disabled:opacity-50.transition-colors', {
|
|
49
|
+
type: 'submit',
|
|
50
|
+
disabled: state.loading,
|
|
51
|
+
}, state.loading ? 'Logging in...' : 'Sign in'),
|
|
52
|
+
]),
|
|
53
|
+
]),
|
|
54
|
+
]),
|
|
55
|
+
]),
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Setup Form Component
|
|
59
|
+
const SetupForm = {
|
|
60
|
+
view: () => m('.min-h-screen.flex.items-center.justify-center.p-4.sm:p-6.bg-gradient-to-br.from-blue-600.via-indigo-600.to-purple-700', [
|
|
61
|
+
m('.w-full.max-w-md', [
|
|
62
|
+
m('.bg-white dark:bg-slate-800.rounded-2xl.shadow-2xl.p-6.sm:p-8', [
|
|
63
|
+
m('div.text-center.mb-6', [
|
|
64
|
+
m('h1.text-2xl.sm:text-3xl.font-bold.text-gray-900.dark:text-slate-50', 'Setup Admin Account'),
|
|
65
|
+
m('p.text-gray-500.dark:text-slate-400.text-sm.mt-1', 'Create the first admin user account.'),
|
|
66
|
+
]),
|
|
67
|
+
m('form', {
|
|
68
|
+
onsubmit: async (e) => {
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
state.loading = true;
|
|
71
|
+
state.error = null;
|
|
72
|
+
try {
|
|
73
|
+
const data = new FormData(e.target);
|
|
74
|
+
const result = await api.post('/auth/setup', {
|
|
75
|
+
email: data.get('email'),
|
|
76
|
+
password: data.get('password'),
|
|
77
|
+
name: data.get('name'),
|
|
78
|
+
});
|
|
79
|
+
state.user = result.user;
|
|
80
|
+
state.needsSetup = false;
|
|
81
|
+
m.route.set('/');
|
|
82
|
+
} catch (err) {
|
|
83
|
+
state.error = err.message;
|
|
84
|
+
} finally {
|
|
85
|
+
state.loading = false;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}, [
|
|
89
|
+
state.error ? m('.bg-red-50.border.border-red-200.text-red-700.dark:bg-red-950/50.dark:border-red-800/80.dark:text-red-200.px-4.py-3.rounded-lg.mb-4.text-sm', state.error) : null,
|
|
90
|
+
m('.mb-4', [
|
|
91
|
+
m('label.block.text-sm.font-medium.text-gray-700.dark:text-slate-300.mb-2', { for: 'name' }, 'Name'),
|
|
92
|
+
m('input#name.w-full.px-3.py-2.5.bg-white.text-gray-900.border.border-gray-300.rounded-lg.focus:ring-2.focus:ring-blue-500.focus:border-blue-500.transition-colors.dark:bg-slate-900/80.dark:border-slate-500.dark:text-slate-100', {
|
|
93
|
+
type: 'text',
|
|
94
|
+
name: 'name',
|
|
95
|
+
required: true,
|
|
96
|
+
}),
|
|
97
|
+
]),
|
|
98
|
+
m('.mb-4', [
|
|
99
|
+
m('label.block.text-sm.font-medium.text-gray-700.dark:text-slate-300.mb-2', { for: 'email' }, 'Email'),
|
|
100
|
+
m('input#email.w-full.px-3.py-2.5.bg-white.text-gray-900.border.border-gray-300.rounded-lg.placeholder-gray-400.focus:ring-2.focus:ring-blue-500.focus:border-blue-500.transition-colors.dark:bg-slate-900/80.dark:border-slate-500.dark:text-slate-100.dark:placeholder-slate-500', {
|
|
101
|
+
type: 'email',
|
|
102
|
+
name: 'email',
|
|
103
|
+
required: true,
|
|
104
|
+
placeholder: 'admin@example.com',
|
|
105
|
+
}),
|
|
106
|
+
]),
|
|
107
|
+
m('.mb-6', [
|
|
108
|
+
m('label.block.text-sm.font-medium.text-gray-700.dark:text-slate-300.mb-2', { for: 'password' }, 'Password'),
|
|
109
|
+
m('input#password.w-full.px-3.py-2.5.bg-white.text-gray-900.border.border-gray-300.rounded-lg.focus:ring-2.focus:ring-blue-500.focus:border-blue-500.transition-colors.dark:bg-slate-900/80.dark:border-slate-500.dark:text-slate-100', {
|
|
110
|
+
type: 'password',
|
|
111
|
+
name: 'password',
|
|
112
|
+
required: true,
|
|
113
|
+
}),
|
|
114
|
+
]),
|
|
115
|
+
m('button.w-full.bg-blue-600.text-white.py-2.5.px-4.rounded-lg.font-medium.hover:bg-blue-700.focus:ring-2.focus:ring-blue-500.focus:ring-offset-2.dark:focus:ring-offset-slate-800.disabled:opacity-50.transition-colors', {
|
|
116
|
+
type: 'submit',
|
|
117
|
+
disabled: state.loading,
|
|
118
|
+
}, state.loading ? 'Creating...' : 'Create Admin Account'),
|
|
119
|
+
]),
|
|
120
|
+
]),
|
|
121
|
+
]),
|
|
122
|
+
]),
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
// Layout Component is defined in menu.js module (uses Sidebar)
|