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.
Files changed (65) hide show
  1. package/README.md +44 -4
  2. package/bin/commands/orm-map.js +139 -0
  3. package/bin/commands/skill.js +22 -8
  4. package/bin/commands/upgrade.js +146 -0
  5. package/bin/utils/orm-map-html.js +689 -0
  6. package/bin/utils/orm-map-load.js +85 -0
  7. package/bin/utils/orm-map-snapshot.js +179 -0
  8. package/bin/utils/resolve-webspresso-orm.js +23 -0
  9. package/bin/webspresso.js +4 -0
  10. package/core/auth/manager.js +14 -1
  11. package/core/kernel/app.js +96 -0
  12. package/core/kernel/base-repository.js +143 -0
  13. package/core/kernel/events.js +101 -0
  14. package/core/kernel/flow.js +22 -0
  15. package/core/kernel/index.js +17 -0
  16. package/core/kernel/plugin.js +23 -0
  17. package/core/kernel/plugins/sample-seo.js +26 -0
  18. package/core/kernel/run-demo.js +58 -0
  19. package/core/kernel/view.js +167 -0
  20. package/core/openapi/build-from-api-routes.js +8 -2
  21. package/core/orm/model.js +3 -1
  22. package/core/url-path-normalize.js +30 -0
  23. package/index.d.ts +168 -1
  24. package/index.js +20 -2
  25. package/package.json +11 -1
  26. package/plugins/admin-panel/api.js +43 -15
  27. package/plugins/admin-panel/app.js +109 -0
  28. package/plugins/admin-panel/client/README.md +39 -0
  29. package/plugins/admin-panel/client/load-parts.js +74 -0
  30. package/plugins/admin-panel/client/manifest.parts.json +12 -0
  31. package/plugins/admin-panel/client/parts/01-state-api-breadcrumb.js +150 -0
  32. package/plugins/admin-panel/client/parts/02-filter-components.js +554 -0
  33. package/plugins/admin-panel/client/parts/03-pagination-intro.js +70 -0
  34. package/plugins/admin-panel/client/parts/04-field-renderers.js +287 -0
  35. package/plugins/admin-panel/client/parts/05-rich-text-file-helpers.js +335 -0
  36. package/plugins/admin-panel/client/parts/06-login-setup-forms.js +125 -0
  37. package/plugins/admin-panel/client/parts/07-model-list.js +596 -0
  38. package/plugins/admin-panel/client/parts/08-record-list.js +536 -0
  39. package/plugins/admin-panel/client/parts/09-record-form.js +170 -0
  40. package/plugins/admin-panel/client/parts/10-export-registry.js +11 -0
  41. package/plugins/admin-panel/client/verify-spa-parts.js +32 -0
  42. package/plugins/admin-panel/client/vite.config.example.mjs +22 -0
  43. package/plugins/admin-panel/components.js +4 -2640
  44. package/plugins/admin-panel/core/api-extensions.js +100 -10
  45. package/plugins/admin-panel/index.js +3 -0
  46. package/plugins/admin-panel/lib/is-rich-text-empty.js +23 -0
  47. package/plugins/admin-panel/lib/sanitize-rich-html.js +106 -0
  48. package/plugins/admin-panel/modules/dashboard.js +17 -13
  49. package/plugins/admin-panel/modules/user-management.js +118 -27
  50. package/plugins/data-exchange/export-xlsx.js +3 -0
  51. package/plugins/data-exchange/record-selection.js +21 -5
  52. package/plugins/index.js +4 -0
  53. package/plugins/rate-limit/index.js +178 -0
  54. package/plugins/redirect/index.js +204 -0
  55. package/plugins/rest-resources/index.js +2 -1
  56. package/plugins/site-analytics/admin-component.js +88 -78
  57. package/plugins/swagger.js +2 -1
  58. package/plugins/upload/local-file-provider.js +6 -2
  59. package/src/file-router.js +270 -53
  60. package/src/njk-frontmatter.js +156 -0
  61. package/src/plugin-manager.js +4 -2
  62. package/src/server.js +28 -9
  63. package/templates/skills/webspresso-usage/REFERENCE-framework.md +276 -0
  64. package/templates/skills/webspresso-usage/REFERENCE-kernel.md +93 -0
  65. 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)