@nocobase/app-template-default 0.0.0-stage → 1.0.0-beta.57

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 (250) hide show
  1. package/.cursor/mcp.json +8 -0
  2. package/.mcp.json +8 -0
  3. package/.prettierignore +20 -0
  4. package/.vscode/mcp.json +8 -0
  5. package/AGENTS.md +432 -0
  6. package/CLAUDE.md +9 -0
  7. package/Dockerfile +132 -0
  8. package/Dockerfile.dockerignore +45 -0
  9. package/README.MD +481 -0
  10. package/cli/plugins.ts +14 -0
  11. package/client/agent-annotations-host.ts +19 -0
  12. package/client/app.ts +38 -0
  13. package/client/components/back-button.tsx +49 -0
  14. package/client/components/breadcrumbs.tsx +167 -0
  15. package/client/components/inbox-badge.ts +49 -0
  16. package/client/components/inbox-button.tsx +132 -0
  17. package/client/components/inbox-header-button.tsx +25 -0
  18. package/client/components/loading.tsx +35 -0
  19. package/client/components/page-container.tsx +24 -0
  20. package/client/components/page-header.tsx +33 -0
  21. package/client/components/route-child-page.tsx +121 -0
  22. package/client/components/route-dialog.tsx +10 -0
  23. package/client/components/route-drawer.tsx +10 -0
  24. package/client/components/route-overlay.tsx +190 -0
  25. package/client/components/ui/alert.tsx +75 -0
  26. package/client/components/ui/badge.tsx +51 -0
  27. package/client/components/ui/breadcrumb.tsx +121 -0
  28. package/client/components/ui/button.tsx +58 -0
  29. package/client/components/ui/collapsible.tsx +19 -0
  30. package/client/components/ui/context-menu.tsx +271 -0
  31. package/client/components/ui/dialog.tsx +160 -0
  32. package/client/components/ui/dropdown-menu.tsx +270 -0
  33. package/client/components/ui/empty.tsx +103 -0
  34. package/client/components/ui/field.tsx +236 -0
  35. package/client/components/ui/input-group.tsx +158 -0
  36. package/client/components/ui/input.tsx +20 -0
  37. package/client/components/ui/kbd.tsx +26 -0
  38. package/client/components/ui/label.tsx +18 -0
  39. package/client/components/ui/popover.tsx +89 -0
  40. package/client/components/ui/select.tsx +200 -0
  41. package/client/components/ui/separator.tsx +22 -0
  42. package/client/components/ui/sheet.tsx +137 -0
  43. package/client/components/ui/sidebar.tsx +723 -0
  44. package/client/components/ui/skeleton.tsx +13 -0
  45. package/client/components/ui/spinner.tsx +20 -0
  46. package/client/components/ui/tabs.tsx +79 -0
  47. package/client/components/ui/textarea.tsx +17 -0
  48. package/client/components/ui/toast.tsx +231 -0
  49. package/client/components/ui/tooltip.tsx +63 -0
  50. package/client/components/use-route-overlay.ts +26 -0
  51. package/client/config/api.ts +13 -0
  52. package/client/config/app.ts +8 -0
  53. package/client/config/auth.ts +18 -0
  54. package/client/config/index.ts +17 -0
  55. package/client/extensions/nocobase-auth-forms/field-props.ts +13 -0
  56. package/client/extensions/nocobase-auth-forms/form-parts.tsx +101 -0
  57. package/client/extensions/nocobase-auth-forms/password-input.tsx +41 -0
  58. package/client/extensions/nocobase-auth-forms/password-login-form.tsx +123 -0
  59. package/client/extensions/nocobase-auth-forms/password-registration-form.tsx +193 -0
  60. package/client/extensions/nocobase-auth-forms/password-reset-form.tsx +132 -0
  61. package/client/extensions/nocobase-auth-forms/password-reset-request-form.tsx +99 -0
  62. package/client/extensions/nocobase-auth-methods/auth-methods.tsx +170 -0
  63. package/client/extensions/nocobase-auth-split-layout/auth-split-layout.tsx +126 -0
  64. package/client/extensions/nocobase-device-approval/device-approval.tsx +277 -0
  65. package/client/extensions/nocobase-device-approval/locales/en-US.ts +55 -0
  66. package/client/extensions/nocobase-device-approval/locales/zh-CN.ts +27 -0
  67. package/client/extensions/nocobase-device-approval/use-device-approval.ts +176 -0
  68. package/client/extensions/nocobase-file-component-ui/README.md +13 -0
  69. package/client/extensions/nocobase-file-component-ui/components/file-list.tsx +147 -0
  70. package/client/extensions/nocobase-file-component-ui/components/file-preview-dialog.tsx +263 -0
  71. package/client/extensions/nocobase-file-component-ui/components/file-preview-field.tsx +68 -0
  72. package/client/extensions/nocobase-file-component-ui/components/file-thumbnail.tsx +73 -0
  73. package/client/extensions/nocobase-file-component-ui/components/file-upload-field.tsx +386 -0
  74. package/client/extensions/nocobase-file-component-ui/components/previewers/file-preview-content.tsx +255 -0
  75. package/client/extensions/nocobase-file-component-ui/components/previewers/office-open-xml-preview.tsx +226 -0
  76. package/client/extensions/nocobase-file-component-ui/index.ts +8 -0
  77. package/client/extensions/nocobase-file-component-ui/lib/file-preview.ts +194 -0
  78. package/client/extensions/nocobase-file-component-ui/lib/file-url.ts +22 -0
  79. package/client/extensions/nocobase-file-component-ui/lib/message-key.ts +18 -0
  80. package/client/extensions/nocobase-file-component-ui/types.ts +69 -0
  81. package/client/extensions/nocobase-inbox/decision-actions-bar.tsx +140 -0
  82. package/client/extensions/nocobase-inbox/frame.ts +31 -0
  83. package/client/extensions/nocobase-inbox/inbox-actions.ts +21 -0
  84. package/client/extensions/nocobase-inbox/inbox-detail.tsx +386 -0
  85. package/client/extensions/nocobase-inbox/inbox-item.tsx +274 -0
  86. package/client/extensions/nocobase-inbox/inbox-list.tsx +433 -0
  87. package/client/extensions/nocobase-inbox/inbox-page.tsx +545 -0
  88. package/client/extensions/nocobase-inbox/locales/en-US.ts +111 -0
  89. package/client/extensions/nocobase-inbox/locales/zh-CN.ts +57 -0
  90. package/client/extensions/nocobase-inbox/model.ts +428 -0
  91. package/client/extensions/nocobase-inbox/registry-scope.tsx +49 -0
  92. package/client/extensions/nocobase-inbox/registry.ts +303 -0
  93. package/client/extensions/nocobase-inbox/source.ts +117 -0
  94. package/client/hooks/use-mobile.ts +21 -0
  95. package/client/index.tsx +60 -0
  96. package/client/layouts/app-layout.tsx +105 -0
  97. package/client/layouts/components/app-brand.tsx +49 -0
  98. package/client/layouts/components/app-sidebar.tsx +196 -0
  99. package/client/layouts/components/header-actions.tsx +50 -0
  100. package/client/layouts/components/language-switcher.tsx +95 -0
  101. package/client/layouts/components/layout-header.tsx +17 -0
  102. package/client/layouts/components/navigation-menu.tsx +411 -0
  103. package/client/layouts/components/sidebar-footer.tsx +107 -0
  104. package/client/layouts/components/surface-empty.tsx +35 -0
  105. package/client/layouts/components/user-menu.tsx +127 -0
  106. package/client/layouts/index.ts +2 -0
  107. package/client/layouts/settings-layout.tsx +172 -0
  108. package/client/layouts/use-sidebar-preference.ts +57 -0
  109. package/client/lib/constants.ts +5 -0
  110. package/client/lib/toaster.ts +56 -0
  111. package/client/lib/utils.ts +1 -0
  112. package/client/locales/en-US.ts +178 -0
  113. package/client/locales/index.ts +9 -0
  114. package/client/locales/zh-CN.ts +161 -0
  115. package/client/pages/auth/device.tsx +41 -0
  116. package/client/pages/auth/forgot-password.tsx +39 -0
  117. package/client/pages/auth/login.tsx +66 -0
  118. package/client/pages/auth/register.tsx +46 -0
  119. package/client/pages/auth/reset-password.tsx +38 -0
  120. package/client/pages/auth/shared.tsx +111 -0
  121. package/client/pages/home.tsx +16 -0
  122. package/client/pages/inbox.tsx +12 -0
  123. package/client/plugins.ts +41 -0
  124. package/client/react-providers.ts +27 -0
  125. package/client/route-overrides.ts +9 -0
  126. package/client/routes.ts +75 -0
  127. package/client/routing/app-router.tsx +127 -0
  128. package/client/routing/client-route.tsx +129 -0
  129. package/client/routing/route-context.tsx +85 -0
  130. package/client/routing/route-navigation.ts +153 -0
  131. package/client/routing/route-tree.tsx +42 -0
  132. package/client/routing/standalone-page-layout.tsx +15 -0
  133. package/client/runtime.ts +26 -0
  134. package/client/service-provider.ts +40 -0
  135. package/client/source-extensions.ts +19 -0
  136. package/client/startup.tsx +22 -0
  137. package/client/styles.css +122 -0
  138. package/client/theme/index.ts +4 -0
  139. package/client/theme/theme-context.ts +12 -0
  140. package/client/theme/theme-preferences.ts +84 -0
  141. package/client/theme/theme-presets.ts +7 -0
  142. package/client/theme/theme-provider.tsx +106 -0
  143. package/client/theme/theme-settings.tsx +176 -0
  144. package/client/theme/themes/compact.css +140 -0
  145. package/client/theme/themes/default.css +117 -0
  146. package/client/vite-env.d.ts +5 -0
  147. package/components.json +27 -0
  148. package/config.example.yml +172 -0
  149. package/database/main/migrations/.gitkeep +0 -0
  150. package/database/main/migrations/202610060001_create_device_code.ts +37 -0
  151. package/database/main/seeds/.gitkeep +0 -0
  152. package/database/tsconfig.json +4 -0
  153. package/ecosystem.config.js +35 -0
  154. package/eslint.config.js +24 -0
  155. package/index.html +100 -0
  156. package/package.json +200 -3
  157. package/playwright.config.ts +10 -0
  158. package/public/assets/favicon.ico +0 -0
  159. package/public/assets/logo-dark.png +0 -0
  160. package/public/assets/logo-mark-dark.png +0 -0
  161. package/public/assets/logo-mark.png +0 -0
  162. package/public/assets/logo.png +0 -0
  163. package/server/app.ts +50 -0
  164. package/server/config/ai.ts +27 -0
  165. package/server/config/api.ts +8 -0
  166. package/server/config/app.ts +40 -0
  167. package/server/config/auth.ts +36 -0
  168. package/server/config/authorization.ts +18 -0
  169. package/server/config/caching.ts +21 -0
  170. package/server/config/database.ts +22 -0
  171. package/server/config/drive.ts +30 -0
  172. package/server/config/i18n.ts +17 -0
  173. package/server/config/index.ts +73 -0
  174. package/server/config/jobs.ts +27 -0
  175. package/server/config/logging.ts +23 -0
  176. package/server/config/notification.ts +11 -0
  177. package/server/config/queue.ts +28 -0
  178. package/server/config/scheduler.ts +23 -0
  179. package/server/config/secrets.ts +10 -0
  180. package/server/config/server.ts +26 -0
  181. package/server/config/session.ts +60 -0
  182. package/server/config/snowflake.ts +21 -0
  183. package/server/config/spa.ts +24 -0
  184. package/server/config/users.ts +11 -0
  185. package/server/config/workflow.ts +24 -0
  186. package/server/config.ts +24 -0
  187. package/server/embedded.ts +23 -0
  188. package/server/locales/en-US.ts +10 -0
  189. package/server/locales/index.ts +10 -0
  190. package/server/locales/zh-CN.ts +5 -0
  191. package/server/plugins.ts +41 -0
  192. package/server/providers/index.ts +5 -0
  193. package/server/routes/index.ts +6 -0
  194. package/server/runtime.ts +24 -0
  195. package/server/standalone.ts +29 -0
  196. package/server/tsconfig.json +4 -0
  197. package/tailwind.config.mjs +59 -0
  198. package/tests/components/app-layout-routes.test.tsx +132 -0
  199. package/tests/components/app-title.test.tsx +57 -0
  200. package/tests/components/auth-i18n.test.tsx +87 -0
  201. package/tests/components/back-button.test.tsx +80 -0
  202. package/tests/components/file-preview.test.tsx +101 -0
  203. package/tests/components/header-hover.test.tsx +87 -0
  204. package/tests/components/inbox.test.tsx +139 -0
  205. package/tests/components/language-switcher.test.tsx +298 -0
  206. package/tests/components/layout-containers.test.tsx +15 -0
  207. package/tests/components/layout-i18n.test.tsx +187 -0
  208. package/tests/components/loading.test.tsx +25 -0
  209. package/tests/components/navigation-menu.test.tsx +355 -0
  210. package/tests/components/page-harness.test.tsx +318 -0
  211. package/tests/components/primitive-labels.test.tsx +80 -0
  212. package/tests/components/sidebar-permissions.test.tsx +110 -0
  213. package/tests/components/sidebar-preference.test.tsx +42 -0
  214. package/tests/fixtures/theme-tokens.html +12 -0
  215. package/tests/fixtures/theme-tokens.tsx +111 -0
  216. package/tests/logic/account-permissions.test.tsx +204 -0
  217. package/tests/logic/app-locale-coverage.test.ts +136 -0
  218. package/tests/logic/app-server.test.ts +1589 -0
  219. package/tests/logic/asset-url-build.test.ts +106 -0
  220. package/tests/logic/client-auth.test.tsx +122 -0
  221. package/tests/logic/client-plugin-registry.test.ts +63 -0
  222. package/tests/logic/client-route-recovery.test.tsx +80 -0
  223. package/tests/logic/client-routes.test.ts +126 -0
  224. package/tests/logic/client-runtime.test.ts +112 -0
  225. package/tests/logic/client-settings.test.tsx +841 -0
  226. package/tests/logic/client-shell.test.tsx +466 -0
  227. package/tests/logic/client-theme.test.tsx +441 -0
  228. package/tests/logic/config.test.ts +197 -0
  229. package/tests/logic/dev-client-watch.test.ts +108 -0
  230. package/tests/logic/dev-routes-production-build.test.ts +168 -0
  231. package/tests/logic/device-code-migration.test.ts +70 -0
  232. package/tests/logic/lifecycle.test.ts +221 -0
  233. package/tests/logic/plugin-commands.test.ts +69 -0
  234. package/tests/logic/plugin-page-authz.test.ts +76 -0
  235. package/tests/logic/route-navigation.test.ts +66 -0
  236. package/tests/logic/route-overlay.test.tsx +353 -0
  237. package/tests/logic/server-imports.test.ts +88 -0
  238. package/tests/logic/tailwind-sources.test.ts +151 -0
  239. package/tests/logic/template-package-name.test.ts +88 -0
  240. package/tests/logic/theme-preferences.test.ts +86 -0
  241. package/tests/logic/theme-tokens.test.ts +248 -0
  242. package/tests/logic/toaster.test.tsx +108 -0
  243. package/tests/logic/user-menu-sign-out.test.tsx +98 -0
  244. package/tests/setup/client-config.ts +27 -0
  245. package/tsconfig.json +11 -0
  246. package/tsconfig.node.json +12 -0
  247. package/tsconfig.server.json +19 -0
  248. package/vite.config.ts +92 -0
  249. package/vitest.config.ts +37 -0
  250. package/README.md +0 -3
@@ -0,0 +1,172 @@
1
+ # Copy this file to config.yml before starting the application.
2
+
3
+ # app:
4
+ # Public origin used for callbacks and redirects in production.
5
+ # publicOrigin: https://apps.example.com
6
+
7
+ # The language the application starts in, for the browser and the server alike. Which languages it offers follows
8
+ # from the files in client/locales and server/locales, not from configuration.
9
+ # i18n:
10
+ # defaultLocale: zh-CN
11
+
12
+ # Limits every /api request meets before its route, each off until set. bodyLimit refuses a larger body with 413
13
+ # BODY_TOO_LARGE; a route may set its own, usually smaller, limit. timeout answers 503 REQUEST_TIMEOUT when a handler
14
+ # has not produced its response in time; a streaming response that has started is not cut off. rateLimit allows max
15
+ # requests per window from each client address and answers 429 RATE_LIMITED with Retry-After; GET /api/healthz is
16
+ # exempt. Counters live in each process, so every instance counts on its own, and behind a reverse proxy the proxy is
17
+ # the client address. API_BODY_LIMIT and API_TIMEOUT set the first two.
18
+ # api:
19
+ # bodyLimit: 10mb
20
+ # timeout: 30s
21
+ # rateLimit:
22
+ # max: 600
23
+ # window: 1m
24
+
25
+ # Values under client are public and embedded in the SPA HTML.
26
+ client:
27
+ app:
28
+ title: NocoBase
29
+ # Defaults apply only when no valid browser-local choice is saved.
30
+ # defaultColorScheme: system # light | dark | system
31
+ # defaultTheme: compact # ID from client/theme/theme-presets.ts
32
+
33
+ users:
34
+ # The first administrator, created only when seeding an empty user table. Changing these values later does not
35
+ # reset an existing account. Replace the password before exposing the application. INITIAL_ADMIN_USERNAME,
36
+ # INITIAL_ADMIN_EMAIL and INITIAL_ADMIN_PASSWORD set them from the environment instead.
37
+ initialAdmin:
38
+ username: nocobase # 3–30 letters, digits, underscores or dots; stored lowercase
39
+ email: admin@nocobase.com # stored lowercase; also signs in
40
+ password: admin123
41
+
42
+ # Master keys for what the application encrypts at rest — stored credentials and API keys, OAuth tokens — and from
43
+ # which the sign-in and session keys are derived. The first key is current; the others only decrypt. To rotate, put a
44
+ # new key first with a higher version, run `pnpm nocobase secrets rotate`, then remove the old key. Changing the current
45
+ # key signs everyone out. Generate a key with: openssl rand -hex 32. SECRETS_KEYS=2:<key>,1:<key> sets the list from
46
+ # the environment instead.
47
+ secrets:
48
+ keys:
49
+ - version: 1
50
+ key: replace-with-a-unique-secret
51
+
52
+ auth:
53
+ emailAndPassword:
54
+ enabled: true
55
+ autoSignIn: false
56
+ session:
57
+ storeSessionInDatabase: true
58
+
59
+ notification:
60
+ channels:
61
+ inbox:
62
+ provider: in-app
63
+
64
+ # Uncomment and configure independent email Channels.
65
+ # Values are read as written: ${NAME} is not expanded. To take a secret from the environment instead, map a
66
+ # variable onto its path in env of server/config/notification.ts, such as SMTP_PASSWORD.
67
+ # system-email:
68
+ # provider: smtp
69
+ # host: smtp.example.com
70
+ # port: 587
71
+ # auth:
72
+ # user: notifications@example.com
73
+ # pass: replace-with-the-smtp-password
74
+ # from: notifications@example.com
75
+ # marketing-email:
76
+ # provider: resend
77
+ # apiKey: replace-with-the-resend-api-key
78
+ # from: marketing@example.com
79
+
80
+ # ops-feishu:
81
+ # provider: feishu-webhook
82
+ # webhookUrl: https://open.feishu.cn/open-apis/bot/v2/hook/replace-with-the-token
83
+ # ops-dingtalk:
84
+ # provider: dingtalk-webhook
85
+ # webhookUrl: https://oapi.dingtalk.com/robot/send?access_token=replace-with-the-token
86
+
87
+ # Declarative LLM services are loaded from application config, keyed by service name.
88
+ # The server reads this when it starts: restart it after editing, which `pnpm dev` does on its own.
89
+ # Keep the key out of this file. Write it into config.yml with
90
+ # `pnpm nocobase config set --from-env ai.llmServices.openai.options.apiKey=OPENAI_API_KEY`,
91
+ # or map an injected environment variable onto that path in server/config/ai.ts.
92
+ # ai:
93
+ # llmServices:
94
+ # openai:
95
+ # title: OpenAI
96
+ # provider: openai
97
+ # enabledModels:
98
+ # - label: GPT-4.1
99
+ # value: gpt-4.1
100
+ # enabled: true
101
+ # sort: 10
102
+
103
+ # DB_DIALECT, DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD, DB_SSL and DB_FILENAME override the main
104
+ # connection's fields from the environment.
105
+ database:
106
+ default: main
107
+ connections:
108
+ main:
109
+ dialect: sqlite
110
+ database: database.sqlite
111
+ debug: false
112
+ # For Oracle, use dialect: oracle and replace database with serviceName: FREEPDB1.
113
+ # For SQL Server, use dialect: mssql and configure encrypt and trustServerCertificate.
114
+ schemaManagement: managed
115
+ migrations:
116
+ autoRun: true
117
+ seeds:
118
+ autoRun: true
119
+ # Additional managed databases use database/<connectionName>/{migrations,seeds}.
120
+ # analytics:
121
+ # dialect: postgres
122
+ # host: localhost
123
+ # database: analytics
124
+ # username: postgres
125
+ # password: replace-with-the-password # or DB_ANALYTICS_PASSWORD, declared with connectionEnvironment('analytics', 'DB_ANALYTICS')
126
+ # schemaManagement: managed
127
+ # migrations:
128
+ # autoRun: false
129
+ # seeds:
130
+ # autoRun: false
131
+ # An existing database another system owns sets schemaManagement: external and runs no tasks. Its titles,
132
+ # descriptions and relations are read from database/<connection>/metadata/<name>.json unless metadataStore says otherwise.
133
+
134
+ snowflake:
135
+ # Assign a unique worker ID to each concurrently running instance.
136
+ workerId: 0
137
+ epoch: 1605024000
138
+
139
+ # Scheduled jobs, such as the Scheduler plugin's. Without jobs.default they run on the built-in memory adapter:
140
+ # state kept in the process, read from storage/jobs at startup and written back when the application stops, so a
141
+ # process that is killed loses what changed since it started. It serves one process: every other process or instance
142
+ # would run its own copy. Set default to memory to keep that without the startup warning, or to redis to run several.
143
+ # Redis must persist its data (AOF or RDB) and use maxmemory-policy noeviction, or schedules can be lost.
144
+ # jobs:
145
+ # default: redis
146
+ # redis:
147
+ # connection:
148
+ # host: 127.0.0.1
149
+ # port: 6379
150
+ # # namespace: my-app # defaults to the application name; set it when deployments share one Redis
151
+
152
+ # The jobs configuration the Scheduler plugin's schedules run on, by name. Left out, they follow jobs.default.
153
+ # scheduler:
154
+ # jobs: redis
155
+
156
+ # File logging is independent of terminal formatting.
157
+ logging:
158
+ level: info
159
+ file:
160
+ enabled: true
161
+ retentionDays: 7
162
+ name: app
163
+ maxFileSizeMB: 10
164
+ maxTotalSizeMB: 500
165
+ loggers:
166
+ request:
167
+ file:
168
+ name: request
169
+ console:
170
+ enabled: true
171
+ # Set true for human-readable terminal output.
172
+ pretty: false
File without changes
@@ -0,0 +1,37 @@
1
+ import { defineMigration, type MigrationDefinition } from '@nocobase/db';
2
+
3
+ /**
4
+ * Creates the `deviceCode` table Better Auth's `deviceAuthorization()` plugin reads and writes: a CLI's sign-in
5
+ * through the browser (RFC 8628). The shape is the plugin's schema in better-auth 1.7.5, spelled out here so a later
6
+ * release cannot change what this migration did; when that schema gains a field, add it in a new migration.
7
+ *
8
+ * `pollingInterval` is milliseconds. A row lives until its code is redeemed, denied or found expired.
9
+ */
10
+ const migration: MigrationDefinition = defineMigration({
11
+ name: '202610060001_create_device_code',
12
+
13
+ async up({ builder }) {
14
+ await builder.createCollection('deviceCode', (collection) => {
15
+ collection.string('id', { length: 64 }).notNull();
16
+ collection.string('deviceCode', { length: 191 }).notNull();
17
+ collection.string('userCode', { length: 191 }).notNull();
18
+ collection.string('userId', { length: 64 }).nullable();
19
+ collection.datetime('expiresAt').notNull();
20
+ collection.string('status', { length: 32 }).notNull();
21
+ collection.datetime('lastPolledAt').nullable();
22
+ collection.integer('pollingInterval').nullable();
23
+ collection.string('clientId', { length: 255 }).nullable();
24
+ collection.text('scope').nullable();
25
+
26
+ collection.primary('id', { name: 'pk_device_code' });
27
+ collection.unique('deviceCode', { name: 'uq_device_code_device_code' });
28
+ collection.unique('userCode', { name: 'uq_device_code_user_code' });
29
+ });
30
+ },
31
+
32
+ async down({ builder }) {
33
+ await builder.dropCollection('deviceCode');
34
+ },
35
+ });
36
+
37
+ export default migration;
File without changes
@@ -0,0 +1,4 @@
1
+ {
2
+ "extends": "../tsconfig.server.json",
3
+ "include": ["**/*.ts"]
4
+ }
@@ -0,0 +1,35 @@
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ // The pm2 process name. `APP_PM2_NAME` chooses it; otherwise it follows the application's package name, read from the
5
+ // project root or, beside an unpacked deployment archive, from `dist/package.json`. Two applications on one machine
6
+ // then get different names: pm2 treats `pm2 start` on a name it already runs as a restart of that process.
7
+ const manifest = ['package.json', 'dist/package.json']
8
+ .map((file) => path.join(import.meta.dirname, file))
9
+ .find((file) => existsSync(file));
10
+ const packageName = manifest
11
+ ? JSON.parse(readFileSync(manifest, 'utf8')).name
12
+ : undefined;
13
+ const name =
14
+ process.env.APP_PM2_NAME ||
15
+ `nocobase-${String(packageName ?? 'app').replace(/^@[^/]+\//, '')}`;
16
+
17
+ export const apps = [
18
+ {
19
+ name,
20
+ // pm2's fork mode loads a script through its own wrapper, so
21
+ // import.meta.main is false there and standalone.js never starts the
22
+ // server. Running node itself keeps standalone.js the main module.
23
+ script: 'node',
24
+ args: './dist/server/standalone.js',
25
+ // Resolve `args` against this file's directory rather than wherever
26
+ // `pm2 start` runs, so the path to this file can be given from anywhere.
27
+ cwd: import.meta.dirname,
28
+ interpreter: 'none',
29
+ env: {
30
+ NODE_ENV: 'production',
31
+ },
32
+ },
33
+ ];
34
+
35
+ export default { apps };
@@ -0,0 +1,24 @@
1
+ import { createApplicationConfig } from '@nocobase/dev-config/eslint';
2
+
3
+ export default createApplicationConfig({
4
+ tsconfigRootDir: import.meta.dirname,
5
+ ignores: [
6
+ '.extension-state/**',
7
+ 'client-old/**',
8
+ 'public/r/**',
9
+ 'storage/**',
10
+ ],
11
+ overrides: [
12
+ {
13
+ // Top-level workflow definitions and handlers use the server project.
14
+ files: ['workflows/**/*.ts'],
15
+ ignores: ['workflows/*/client/**'],
16
+ languageOptions: {
17
+ parserOptions: {
18
+ projectService: false,
19
+ project: './tsconfig.server.json',
20
+ },
21
+ },
22
+ },
23
+ ],
24
+ });
package/index.html ADDED
@@ -0,0 +1,100 @@
1
+ <!doctype html>
2
+ <html lang="en-US">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <link rel="icon" type="image/x-icon" href="/assets/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta name="theme-color" content="#171717" />
8
+ <meta name="description" content="NocoBase administration console" />
9
+ <meta data-rh="true" property="og:image" content="/assets/logo-mark.png" />
10
+ <meta data-rh="true" name="twitter:image" content="/assets/logo-mark.png" />
11
+ <style>
12
+ .app-bootstrap-loading {
13
+ display: flex;
14
+ min-height: 100svh;
15
+ width: 100%;
16
+ align-items: center;
17
+ justify-content: center;
18
+ background: oklch(0.985 0 0);
19
+ color: oklch(0.18 0 0);
20
+ }
21
+
22
+ .app-bootstrap-loading [data-slot='loading-indicator'] {
23
+ width: 1.75rem;
24
+ height: 1.75rem;
25
+ opacity: 0;
26
+ animation:
27
+ app-bootstrap-reveal 0s 200ms forwards,
28
+ app-bootstrap-spin 1s linear 200ms infinite;
29
+ }
30
+
31
+ html,
32
+ body {
33
+ margin: 0;
34
+ }
35
+
36
+ @keyframes app-bootstrap-spin {
37
+ to {
38
+ transform: rotate(360deg);
39
+ }
40
+ }
41
+
42
+ @keyframes app-bootstrap-reveal {
43
+ to {
44
+ opacity: 1;
45
+ }
46
+ }
47
+
48
+ @media (prefers-color-scheme: dark) {
49
+ .app-bootstrap-loading {
50
+ background: oklch(0.145 0 0);
51
+ color: oklch(0.9 0 0);
52
+ }
53
+ }
54
+
55
+ @media (prefers-reduced-motion: reduce) {
56
+ .app-bootstrap-loading [data-slot='loading-indicator'] {
57
+ animation: none;
58
+ opacity: 0.65;
59
+ }
60
+ }
61
+ </style>
62
+ <title>NocoBase</title>
63
+ </head>
64
+ <body>
65
+ <noscript>You need to enable JavaScript to run this app.</noscript>
66
+ <div id="root">
67
+ <div
68
+ class="app-bootstrap-loading"
69
+ role="status"
70
+ aria-label="Loading application"
71
+ >
72
+ <svg
73
+ data-slot="loading-indicator"
74
+ viewBox="0 0 24 24"
75
+ fill="none"
76
+ aria-hidden="true"
77
+ >
78
+ <path
79
+ d="M21 12a9 9 0 1 1-6.219-8.56"
80
+ stroke="currentColor"
81
+ stroke-width="2"
82
+ stroke-linecap="round"
83
+ stroke-linejoin="round"
84
+ />
85
+ </svg>
86
+ </div>
87
+ </div>
88
+ <script type="module" src="/client/index.tsx"></script>
89
+ <!--
90
+ This HTML file is a template.
91
+ If you open it directly in the browser, you will see an empty page.
92
+
93
+ You can add webfonts, meta tags, or analytics to this file.
94
+ The build step will place the bundled scripts into the <body> tag.
95
+
96
+ To begin development, run `pnpm dev`.
97
+ To create a production bundle, run `pnpm build`.
98
+ -->
99
+ </body>
100
+ </html>
package/package.json CHANGED
@@ -1,6 +1,203 @@
1
1
  {
2
2
  "name": "@nocobase/app-template-default",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "displayName": "Default Template",
4
+ "version": "1.0.0-beta.57",
5
+ "type": "module",
6
+ "prettier": "@nocobase/dev-config/prettier",
7
+ "engines": {
8
+ "node": ">=24.0.0"
9
+ },
10
+ "nocobase": {
11
+ "templateKind": "app",
12
+ "defaultTemplateVersion": "1.0.0-beta.57"
13
+ },
14
+ "devDependencies": {
15
+ "@ai-sdk/react": "2.0.0",
16
+ "@base-ui/react": "^1.6.0",
17
+ "@dicebear/core": "^9.4.3",
18
+ "@gchust/agent-annotations": "0.1.9",
19
+ "@hookform/resolvers": "^5.0.1",
20
+ "@nocobase/ai-employee-avatars": "^1.0.2",
21
+ "@playwright/test": "^1.62.1",
22
+ "@refinedev/cli": "^2.16.48",
23
+ "@refinedev/core": "^5.0.8",
24
+ "@refinedev/react-hook-form": "^5.0.0",
25
+ "@refinedev/react-router": "^2.0.0",
26
+ "@refinedev/react-table": "^6.0.0",
27
+ "@silurus/ooxml": "0.85.1",
28
+ "@tailwindcss/postcss": "^4.1.4",
29
+ "@tailwindcss/vite": "^4.1.8",
30
+ "@tanstack/react-query": "^5.81.5",
31
+ "@testing-library/jest-dom": "^7.0.0",
32
+ "@testing-library/react": "^16.3.2",
33
+ "@testing-library/user-event": "^14.6.3",
34
+ "@tiptap/core": "3.30.2",
35
+ "@tiptap/extension-link": "3.30.2",
36
+ "@tiptap/extension-placeholder": "3.30.2",
37
+ "@tiptap/extension-text-style": "3.30.2",
38
+ "@tiptap/pm": "3.30.2",
39
+ "@tiptap/react": "3.30.2",
40
+ "@tiptap/starter-kit": "3.30.2",
41
+ "@types/node": "^24.0.0",
42
+ "@types/react": "^19.2.0",
43
+ "@types/react-dom": "^19.2.0",
44
+ "@vitejs/plugin-react": "^4.4.1",
45
+ "@vitest/coverage-v8": "^4.1.10",
46
+ "ai": "5.0.0",
47
+ "class-variance-authority": "^0.7.1",
48
+ "cn": "^0.4.0",
49
+ "dayjs": "^1.10.7",
50
+ "dingtalk-jsapi": "3.1.1",
51
+ "echarts": "^5.5.0",
52
+ "echarts-for-react": "3.0.2",
53
+ "eslint": "^10.0.0",
54
+ "eventsource-parser": "3.1.0",
55
+ "ignore": "^7.0.6",
56
+ "jsdom": "^30.0.1",
57
+ "knex": "^3.1.0",
58
+ "lucide-react": "^0.487.0",
59
+ "next-themes": "^0.4.6",
60
+ "postcss": "^8.5.3",
61
+ "prettier": "^3.9.6",
62
+ "react": "^19.2.8",
63
+ "react-dom": "^19.2.8",
64
+ "react-error-boundary": "^6.0.0",
65
+ "react-hook-form": "^7.57.0",
66
+ "react-i18next": "^17.0.12",
67
+ "react-markdown": "^10.1.0",
68
+ "react-router": "^7.0.2",
69
+ "remark-gfm": "^4.0.1",
70
+ "shadcn": "^4.13.1",
71
+ "tailwindcss": "^4.1.4",
72
+ "tsc-alias": "^1.9.2",
73
+ "tsx": "^4.21.0",
74
+ "tw-animate-css": "^1.2.5",
75
+ "typescript": "^6.0.3",
76
+ "vite": "^6.3.5",
77
+ "vitest": "^4.1.10",
78
+ "tar": "^7.5.22",
79
+ "@nocobase/app-client": "^2.0.0-beta.2",
80
+ "@nocobase/app-plugin-template-print": "0.0.2-beta.0",
81
+ "@nocobase/app-skills": "0.1.0-beta.25",
82
+ "@nocobase/app-websocket": "^0.0.1",
83
+ "@nocobase/dev-config": "0.1.0-beta.19",
84
+ "@nocobase/drive": "^0.1.0-beta.4",
85
+ "@nocobase/app-testing": "0.1.0-beta.1",
86
+ "@nocobase/hub-cli": "^1.0.0-beta.1",
87
+ "@nocobase/logging": "^0.1.0-beta.6",
88
+ "@nocobase/session": "^0.1.0-beta.2"
89
+ },
90
+ "files": [
91
+ ".prettierignore",
92
+ ".mcp.json",
93
+ ".cursor/mcp.json",
94
+ ".vscode/mcp.json",
95
+ "cli",
96
+ "client",
97
+ "server",
98
+ "workflows",
99
+ "database/tsconfig.json",
100
+ "database/*/migrations/**",
101
+ "database/*/seeds/**",
102
+ "public",
103
+ "tests",
104
+ "index.html",
105
+ "components.json",
106
+ "tailwind.config.mjs",
107
+ "vite.config.ts",
108
+ "vitest.config.ts",
109
+ "eslint.config.js",
110
+ "tsconfig.json",
111
+ "tsconfig.node.json",
112
+ "tsconfig.server.json",
113
+ "ecosystem.config.js",
114
+ "Dockerfile",
115
+ "Dockerfile.dockerignore",
116
+ "config.example.yml",
117
+ "README.MD",
118
+ "AGENTS.md",
119
+ "CLAUDE.md",
120
+ "playwright.config.ts"
121
+ ],
122
+ "publishConfig": {
123
+ "access": "public"
124
+ },
125
+ "repository": {
126
+ "type": "git",
127
+ "url": "git+https://github.com/nocobase/nocobase3.git",
128
+ "directory": "packages/templates/app-template-default"
129
+ },
130
+ "browserslist": {
131
+ "production": [
132
+ ">0.2%",
133
+ "not dead",
134
+ "not op_mini all"
135
+ ],
136
+ "development": [
137
+ "last 1 chrome version",
138
+ "last 1 firefox version",
139
+ "last 1 safari version"
140
+ ]
141
+ },
142
+ "dependencies": {
143
+ "zod": "^4.6.5",
144
+ "@oclif/core": "^4.14.0",
145
+ "better-auth": "1.7.5",
146
+ "hono": "^4.13.2",
147
+ "@nocobase/app-plugin-ai-employee": "^3.0.0-beta.1",
148
+ "@nocobase/app-plugin-api-keys": "^1.0.0-beta.13",
149
+ "@nocobase/app-plugin-authentication": "^2.0.0-beta.2",
150
+ "@nocobase/app-plugin-authorization": "^1.0.0-beta.25",
151
+ "@nocobase/app-plugin-database-explorer": "^1.0.0-beta.11",
152
+ "@nocobase/app-plugin-file": "^1.0.0-beta.20",
153
+ "@nocobase/app-plugin-i18n": "^1.0.0-beta.13",
154
+ "@nocobase/app-plugin-notification": "^1.0.0-beta.24",
155
+ "@nocobase/app-plugin-notification-in-app": "^1.0.0-beta.22",
156
+ "@nocobase/app-plugin-notification-providers": "^0.2.0-beta.10",
157
+ "@nocobase/app-plugin-scheduler": "^1.0.0-beta.14",
158
+ "@nocobase/app-plugin-users": "^2.0.0-beta.1",
159
+ "@nocobase/app-server": "^2.0.0-beta.1",
160
+ "@nocobase/config": "^0.1.0-beta.2",
161
+ "@nocobase/db": "^1.0.0-beta.18",
162
+ "@nocobase/app-plugin-workflow": "^2.0.0-beta.1",
163
+ "@nocobase/db-sqlite": "^0.1.0-beta.4",
164
+ "@nocobase/service-provider": "^0.0.2-beta.1",
165
+ "@nocobase/snowflake": "^1.0.0-beta.3",
166
+ "@nocobase/app-plugin-authz-default-access": "^1.0.0-beta.10",
167
+ "@nocobase/app-plugin-authz-sharing-rules": "^1.0.0-beta.10",
168
+ "@nocobase/app-plugin-authz-restriction-rules": "^1.0.0-beta.9",
169
+ "@nocobase/authorization": "^1.0.0-beta.12",
170
+ "@nocobase/queue": "^0.1.0-beta.8",
171
+ "@nocobase/jobs": "^0.1.0-beta.2",
172
+ "@nocobase/i18n": "^1.0.0-beta.5",
173
+ "@nocobase/caching": "^0.1.0-beta.2",
174
+ "@nocobase/ai-employee": "^0.2.0-beta.8",
175
+ "@nocobase/repository-input": "^0.1.0-beta.2",
176
+ "@nocobase/app-cli": "^1.0.0-beta.14"
177
+ },
178
+ "description": "NocoBase 3 application template with the standard product capabilities.",
179
+ "imports": {
180
+ "#components/*": "./client/components/*.js",
181
+ "#hooks/*": "./client/hooks/*.js",
182
+ "#lib/*": "./client/lib/*.js",
183
+ "#extensions/*": "./client/extensions/*.js",
184
+ "#pages/*": "./client/pages/*.js"
185
+ },
186
+ "scripts": {
187
+ "postinstall": "nocobase skills sync",
188
+ "dev": "nocobase dev",
189
+ "build": "nocobase build",
190
+ "start": "nocobase start",
191
+ "check": "pnpm lint && pnpm format:check && pnpm typecheck && pnpm test && pnpm build",
192
+ "fix": "pnpm lint:fix && pnpm format",
193
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.node.json --noEmit && tsc -p tsconfig.server.json --noEmit",
194
+ "lint": "eslint . --max-warnings 0",
195
+ "lint:fix": "eslint . --fix --max-warnings 0",
196
+ "format": "prettier . --write",
197
+ "format:check": "prettier . --check",
198
+ "test": "vitest run",
199
+ "test:watch": "vitest",
200
+ "test:coverage": "vitest run --coverage",
201
+ "test:e2e": "playwright test --pass-with-no-tests"
202
+ }
6
203
  }
@@ -0,0 +1,10 @@
1
+ import { defineConfig } from '@playwright/test';
2
+
3
+ export default defineConfig({
4
+ testDir: './tests/playwright',
5
+ testMatch: '**/*.test.ts',
6
+ timeout: 120_000,
7
+ workers: 1,
8
+ reporter: 'list',
9
+ use: { trace: 'off' },
10
+ });
Binary file
Binary file
Binary file
Binary file
Binary file
package/server/app.ts ADDED
@@ -0,0 +1,50 @@
1
+ import type { Application } from '@nocobase/app-server/application';
2
+ import { DatabaseProvider } from '@nocobase/app-server/database';
3
+ import { I18nProvider, i18nHttpMiddleware } from '@nocobase/app-server/i18n';
4
+ import { CachingProvider } from '@nocobase/app-server/caching';
5
+ import { DriveProvider } from '@nocobase/app-server/drive';
6
+ import { IdGeneratorProvider } from '@nocobase/app-server/id-generator';
7
+ import {
8
+ LoggingProvider,
9
+ requestLoggingMiddleware,
10
+ } from '@nocobase/app-server/logging';
11
+ import { QueueServiceProvider } from '@nocobase/app-server/queue';
12
+ import { SecretsProvider } from '@nocobase/app-server/secrets';
13
+ import { JobExecutorServiceProvider } from '@nocobase/app-server/jobs';
14
+ import {
15
+ SessionProvider,
16
+ sessionHttpMiddleware,
17
+ } from '@nocobase/app-server/session';
18
+ import { healthCheckApiRoutes } from '@nocobase/app-server/router';
19
+ import {
20
+ createAppFromRuntime,
21
+ type AppRuntimeContext,
22
+ } from '@nocobase/app-server/runtime';
23
+ import { spaRootRoutes } from '@nocobase/app-server/spa';
24
+
25
+ export function createApp(runtime: AppRuntimeContext): Application {
26
+ const app = createAppFromRuntime(runtime);
27
+
28
+ app.addServiceProvider(DatabaseProvider);
29
+ app.addServiceProvider(I18nProvider);
30
+ app.addServiceProvider(LoggingProvider);
31
+ app.addServiceProvider(CachingProvider);
32
+ app.addServiceProvider(IdGeneratorProvider);
33
+ app.addServiceProvider(SecretsProvider);
34
+ app.addServiceProvider(SessionProvider);
35
+ app.addServiceProvider(DriveProvider);
36
+ app.addServiceProvider(QueueServiceProvider, {
37
+ nodeEnv: runtime.env.NODE_ENV,
38
+ });
39
+ app.addServiceProvider(JobExecutorServiceProvider, {
40
+ nodeEnv: runtime.env.NODE_ENV,
41
+ });
42
+ app.addHttpMiddleware(requestLoggingMiddleware);
43
+ app.addHttpMiddleware(sessionHttpMiddleware);
44
+ app.addHttpMiddleware(i18nHttpMiddleware);
45
+ app.addRoutes(healthCheckApiRoutes);
46
+ app.addRuntimeContributions(runtime);
47
+ app.addRoutes(spaRootRoutes);
48
+
49
+ return app;
50
+ }