@aklry/elpis-cli 0.1.0 → 0.1.1

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 (35) hide show
  1. package/dist/create.d.ts +3 -0
  2. package/dist/create.d.ts.map +1 -1
  3. package/dist/create.js +44 -3
  4. package/dist/create.js.map +1 -1
  5. package/dist/templates.js +2 -2
  6. package/dist/templates.js.map +1 -1
  7. package/package.json +5 -5
  8. package/templates/server/app/client.ts +26 -0
  9. package/templates/server/app/controller/user.ts +68 -0
  10. package/templates/server/app/database/schema.ts +11 -0
  11. package/templates/server/app/extend/database.ts +16 -0
  12. package/templates/server/app/middleware/auth.ts +11 -0
  13. package/templates/server/app/middleware/request-tag.ts +8 -0
  14. package/templates/server/app/pages/AboutPage.vue +58 -0
  15. package/templates/server/app/public/docs.html +25 -0
  16. package/templates/server/app/router/user.ts +13 -0
  17. package/templates/server/app/router-schema/user.ts +72 -0
  18. package/templates/server/app/service/user.ts +71 -0
  19. package/templates/server/app/widgets/StatusTag.vue +112 -0
  20. package/templates/server/drizzle.config.ts +9 -0
  21. package/templates/server/elpis.config.ts +19 -0
  22. package/templates/server/env.d.ts +5 -0
  23. package/templates/server/model/admin/model.ts +199 -0
  24. package/templates/server/model/admin/project/demo.ts +15 -0
  25. package/templates/{basic → server}/package.json.template +9 -5
  26. package/templates/server/tsconfig.client.json +8 -0
  27. package/templates/server/tsconfig.server.json +9 -0
  28. package/templates/basic/app/App.vue +0 -27
  29. package/templates/basic/app/client.ts +0 -4
  30. package/templates/basic/app/public/robots.txt +0 -2
  31. package/templates/basic/app/server.ts +0 -13
  32. package/templates/basic/elpis.config.ts +0 -9
  33. package/templates/basic/env.d.ts +0 -5
  34. package/templates/basic/tsconfig.client.json +0 -13
  35. package/templates/basic/tsconfig.server.json +0 -14
package/dist/create.d.ts CHANGED
@@ -10,6 +10,8 @@ export interface CreateProjectOptions {
10
10
  stdinIsTTY?: boolean;
11
11
  env?: NodeJS.ProcessEnv;
12
12
  runner?: InstallRunner;
13
+ input?: NodeJS.ReadableStream;
14
+ output?: NodeJS.WritableStream;
13
15
  }
14
16
  export interface CreateProjectResult {
15
17
  rootDir: string;
@@ -22,5 +24,6 @@ export declare function installDependencies(rootDir: string, manager: PackageMan
22
24
  export declare function installCommand(manager: PackageManager): string;
23
25
  export declare function devCommand(manager: PackageManager): string;
24
26
  export declare function confirmInstall(input: NodeJS.ReadableStream, output: NodeJS.WritableStream): Promise<boolean>;
27
+ export declare function selectPackageManager(input: NodeJS.ReadableStream, output: NodeJS.WritableStream, suggested: PackageManager): Promise<PackageManager>;
25
28
  export declare function createProject(options: CreateProjectOptions): Promise<CreateProjectResult>;
26
29
  //# sourceMappingURL=create.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AACrD,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtG,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;CACpB;AAwBD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAazH;AAkBD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAE,aAAoC,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/I;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAE9D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAE1D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ5G;AA4CD,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA6B/F"}
1
+ {"version":3,"file":"create.d.ts","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AACrD,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEtG,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,cAAc,CAAC;IAC/B,SAAS,EAAE,OAAO,CAAC;CACpB;AAwBD,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAazH;AAyBD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,GAAE,aAAoC,GAAG,OAAO,CAAC,IAAI,CAAC,CAM/I;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAE9D;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAE1D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAQ5G;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,SAAS,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CASpJ;AA8DD,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAkC/F"}
package/dist/create.js CHANGED
@@ -41,6 +41,7 @@ exports.installDependencies = installDependencies;
41
41
  exports.installCommand = installCommand;
42
42
  exports.devCommand = devCommand;
43
43
  exports.confirmInstall = confirmInstall;
44
+ exports.selectPackageManager = selectPackageManager;
44
45
  exports.createProject = createProject;
45
46
  const node_child_process_1 = require("node:child_process");
46
47
  const promises_1 = require("node:fs/promises");
@@ -96,7 +97,14 @@ function commandFor(manager) {
96
97
  }
97
98
  function defaultInstallRunner(file, args, options) {
98
99
  return new Promise((resolve, reject) => {
99
- const child = (0, node_child_process_1.spawn)(file, args, { cwd: options.cwd, stdio: "inherit", shell: false });
100
+ const command = process.platform === "win32"
101
+ ? { file: process.env.ComSpec ?? "cmd.exe", args: ["/d", "/s", "/c", file, ...args] }
102
+ : { file, args };
103
+ const child = (0, node_child_process_1.spawn)(command.file, command.args, {
104
+ cwd: options.cwd,
105
+ stdio: "inherit",
106
+ shell: false,
107
+ });
100
108
  child.once("error", reject);
101
109
  child.once("exit", (code, signal) => {
102
110
  if (code === 0)
@@ -130,6 +138,33 @@ function confirmInstall(input, output) {
130
138
  });
131
139
  });
132
140
  }
141
+ function selectPackageManager(input, output, suggested) {
142
+ const rl = readline.createInterface({ input, output });
143
+ return new Promise(resolve => {
144
+ rl.question(`Package manager [1] pnpm [2] npm [3] yarn (default: ${suggested}): `, answer => {
145
+ rl.close();
146
+ const value = answer.trim().toLowerCase();
147
+ resolve(value === "1" || value === "pnpm" ? "pnpm" : value === "3" || value === "yarn" ? "yarn" : value === "2" || value === "npm" ? "npm" : suggested);
148
+ });
149
+ });
150
+ }
151
+ function askInstall(input, output, suggested) {
152
+ const rl = readline.createInterface({ input, output });
153
+ return new Promise(resolve => {
154
+ rl.question("Install dependencies now? [Y/n] ", answer => {
155
+ if (!/^(?:y|yes)?$/i.test(answer.trim())) {
156
+ rl.close();
157
+ resolve(undefined);
158
+ return;
159
+ }
160
+ rl.question(`Package manager [1] pnpm [2] npm [3] yarn (default: ${suggested}): `, managerAnswer => {
161
+ rl.close();
162
+ const value = managerAnswer.trim().toLowerCase();
163
+ resolve(value === "1" || value === "pnpm" ? "pnpm" : value === "3" || value === "yarn" ? "yarn" : value === "2" || value === "npm" ? "npm" : suggested);
164
+ });
165
+ });
166
+ });
167
+ }
133
168
  function normalizeProjectName(directory) {
134
169
  const base = node_path_1.default.basename(directory);
135
170
  const projectName = base.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -178,7 +213,7 @@ async function createProject(options) {
178
213
  const cwd = node_path_1.default.resolve(options.cwd ?? process.cwd());
179
214
  const rootDir = node_path_1.default.resolve(cwd, options.directory);
180
215
  const projectName = normalizeProjectName(rootDir);
181
- const manager = await detectPackageManager(rootDir, options.env ?? process.env);
216
+ let manager = await detectPackageManager(rootDir, options.env ?? process.env);
182
217
  const state = await targetState(rootDir);
183
218
  const files = await (0, templates_1.renderTemplate)({ projectName, frameworkVersion: options.frameworkVersion });
184
219
  const parent = node_path_1.default.dirname(rootDir);
@@ -199,7 +234,13 @@ async function createProject(options) {
199
234
  let installed = false;
200
235
  if (options.install) {
201
236
  const interactive = options.stdinIsTTY ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
202
- if (interactive && await confirmInstall(process.stdin, process.stdout)) {
237
+ const input = options.input ?? process.stdin;
238
+ const output = options.output ?? process.stdout;
239
+ if (interactive) {
240
+ const selectedManager = await askInstall(input, output, manager);
241
+ if (selectedManager === undefined)
242
+ return { rootDir, projectName, packageManager: manager, installed };
243
+ manager = selectedManager;
203
244
  await installDependencies(rootDir, manager, options.runner);
204
245
  installed = true;
205
246
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create.js","sourceRoot":"","sources":["../src/create.ts"],"names":[],"mappings":"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"}
package/dist/templates.js CHANGED
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.renderTemplate = renderTemplate;
7
7
  const promises_1 = require("node:fs/promises");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
- const TEMPLATE_ROOT = node_path_1.default.resolve(__dirname, "../templates/basic");
9
+ const TEMPLATE_ROOT = node_path_1.default.resolve(__dirname, "../templates/server");
10
10
  function assertSafeRelative(relativePath) {
11
11
  if (!relativePath || node_path_1.default.isAbsolute(relativePath))
12
12
  throw new Error("Template contains an invalid file path.");
@@ -36,7 +36,7 @@ async function collectFiles(directory, relative = "") {
36
36
  async function renderTemplate(options) {
37
37
  const rootStat = await (0, promises_1.lstat)(TEMPLATE_ROOT).catch(() => undefined);
38
38
  if (!rootStat?.isDirectory())
39
- throw new Error("The bundled basic project template is missing.");
39
+ throw new Error("The bundled server project template is missing.");
40
40
  const relativeFiles = await collectFiles(TEMPLATE_ROOT);
41
41
  const rendered = [];
42
42
  for (const relativePath of relativeFiles) {
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../src/templates.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aklry/elpis-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Elpis 命令行入口",
5
5
  "license": "ISC",
6
6
  "type": "commonjs",
@@ -22,17 +22,17 @@
22
22
  "node": ">=22.14.0"
23
23
  },
24
24
  "dependencies": {
25
- "@aklry/elpis-core": "0.1.0",
26
- "@aklry/elpis-schema": "0.1.0"
25
+ "@aklry/elpis-core": "0.1.1",
26
+ "@aklry/elpis-schema": "0.1.1"
27
27
  },
28
28
  "bin": {
29
29
  "elpis": "./dist/index.js"
30
30
  },
31
31
  "devDependencies": {
32
- "@aklry/elpis-builder": "0.1.0"
32
+ "@aklry/elpis-builder": "0.1.1"
33
33
  },
34
34
  "peerDependencies": {
35
- "@aklry/elpis-builder": "^0.1.0"
35
+ "@aklry/elpis-builder": "^0.1.1"
36
36
  },
37
37
  "peerDependenciesMeta": {
38
38
  "@aklry/elpis-builder": {
@@ -0,0 +1,26 @@
1
+ import { createDashboardApp, defineClient, setCurlDefaults } from '@aklry/elpis-client';
2
+ import '@aklry/elpis-client/style.css';
3
+ import AboutPage from './pages/AboutPage.vue';
4
+ import StatusTag from './widgets/StatusTag.vue';
5
+
6
+ setCurlDefaults({
7
+ headers: {
8
+ 'x-demo-token': 'local-demo',
9
+ },
10
+ });
11
+
12
+ void createDashboardApp(defineClient({
13
+ routes({ routes, siderRoutes }) {
14
+ routes.push({
15
+ path: '/view/dashboard/about',
16
+ component: AboutPage,
17
+ });
18
+ siderRoutes.push({
19
+ path: 'about',
20
+ component: AboutPage,
21
+ });
22
+ },
23
+ formItems: {
24
+ statusTag: StatusTag,
25
+ },
26
+ }));
@@ -0,0 +1,68 @@
1
+ import { BaseController, type RequestContext } from '@aklry/elpis-core';
2
+ import type { AppRegistry } from '../../.elpis/types/registry';
3
+
4
+ function queryString(value: unknown): string | undefined {
5
+ if (typeof value === 'string' && value.trim()) return value;
6
+ if (Array.isArray(value) && typeof value[0] === 'string' && value[0].trim()) return value[0];
7
+ return undefined;
8
+ }
9
+
10
+ function queryNumber(value: unknown): number | undefined {
11
+ const text = queryString(value);
12
+ if (text === undefined) return undefined;
13
+ const number = Number(text);
14
+ return Number.isFinite(number) ? number : undefined;
15
+ }
16
+
17
+ export default class UserController extends BaseController<AppRegistry> {
18
+ async list(ctx: RequestContext) {
19
+ const result = await this.service.user.list({
20
+ page: queryNumber(ctx.query.page),
21
+ size: queryNumber(ctx.query.size),
22
+ name: queryString(ctx.query.name),
23
+ role: queryString(ctx.query.role),
24
+ status: queryString(ctx.query.status),
25
+ });
26
+ this.success(ctx, result.data, result.metadata);
27
+ }
28
+
29
+ async get(ctx: RequestContext) {
30
+ const id = queryString(ctx.query.id) ?? ctx.params.id;
31
+ if (!id) {
32
+ this.fail(ctx, '缺少用户 id', 'BAD_REQUEST', 400);
33
+ return;
34
+ }
35
+ const user = await this.service.user.get(id);
36
+ if (!user) {
37
+ this.fail(ctx, '用户不存在', 'NOT_FOUND', 404);
38
+ return;
39
+ }
40
+ this.success(ctx, { ...user, greeting: this.config.private?.greeting });
41
+ }
42
+
43
+ async create(ctx: RequestContext) {
44
+ const input = ctx.request.body as { name: string; role?: string; status?: string };
45
+ this.success(ctx, await this.service.user.create(input));
46
+ ctx.status = 201;
47
+ }
48
+
49
+ async update(ctx: RequestContext) {
50
+ const body = ctx.request.body as { id: string; name?: string; role?: string; status?: string };
51
+ const user = await this.service.user.update(body.id, body);
52
+ if (!user) {
53
+ this.fail(ctx, '用户不存在', 'NOT_FOUND', 404);
54
+ return;
55
+ }
56
+ this.success(ctx, user);
57
+ }
58
+
59
+ async remove(ctx: RequestContext) {
60
+ const body = ctx.request.body as { id: string };
61
+ const user = await this.service.user.remove(body.id);
62
+ if (!user) {
63
+ this.fail(ctx, '用户不存在', 'NOT_FOUND', 404);
64
+ return;
65
+ }
66
+ this.success(ctx, user);
67
+ }
68
+ }
@@ -0,0 +1,11 @@
1
+ import { integer, pgTable, text } from 'drizzle-orm/pg-core';
2
+
3
+ export const users = pgTable('users', {
4
+ id: integer('id').primaryKey().generatedAlwaysAsIdentity(),
5
+ name: text('name').notNull(),
6
+ role: text('role').notNull(),
7
+ status: text('status').notNull(),
8
+ });
9
+
10
+ export type User = typeof users.$inferSelect;
11
+ export type NewUser = typeof users.$inferInsert;
@@ -0,0 +1,16 @@
1
+ import path from 'node:path';
2
+ import { config as loadEnv } from 'dotenv';
3
+ import { createPostgresExtension } from '@aklry/elpis-postgres';
4
+ import * as schema from '../database/schema';
5
+
6
+ const extension = createPostgresExtension({ schema });
7
+
8
+ export default {
9
+ validate(options: Record<string, unknown>) {
10
+ extension.validate?.(options);
11
+ },
12
+ async setup(context: Parameters<NonNullable<typeof extension.setup>>[0], options: Record<string, unknown>) {
13
+ loadEnv({ path: path.join(context.rootDir, '.env') });
14
+ return extension.setup(context, options);
15
+ },
16
+ };
@@ -0,0 +1,11 @@
1
+ import type { MiddlewareFactory } from '@aklry/elpis-core';
2
+
3
+ const auth: MiddlewareFactory = context => async (ctx, next) => {
4
+ if (ctx.get('x-demo-token') !== context.config.private?.demoToken) {
5
+ ctx.status = 401;
6
+ ctx.body = { success: false, code: 'UNAUTHORIZED', message: '需要示例令牌' };
7
+ return;
8
+ }
9
+ await next();
10
+ };
11
+ export default auth;
@@ -0,0 +1,8 @@
1
+ import type { MiddlewareFactory } from '@aklry/elpis-core';
2
+
3
+ const requestTag: MiddlewareFactory = (_context, options) => {
4
+ if (typeof options.label !== 'string') throw new TypeError('requestTag.label must be a string');
5
+ const label = options.label;
6
+ return async (ctx, next) => { ctx.set('X-Elpis-Example', label); await next(); };
7
+ };
8
+ export default requestTag;
@@ -0,0 +1,58 @@
1
+ <script setup lang="ts">
2
+ import { getPublicConfig } from '@aklry/elpis-client';
3
+
4
+ const publicConfig = getPublicConfig();
5
+ </script>
6
+
7
+ <template>
8
+ <section class="about-page">
9
+ <h1>关于页面</h1>
10
+ <p>这是通过 <code>app/client.ts</code> 显式注册的自定义页面,对应菜单 <code>moduleType: custom</code>。</p>
11
+ <dl>
12
+ <div>
13
+ <dt>应用标题</dt>
14
+ <dd>{{ publicConfig.title ?? 'Elpis' }}</dd>
15
+ </div>
16
+ <div>
17
+ <dt>运行环境</dt>
18
+ <dd>{{ publicConfig.environment ?? 'local' }}</dd>
19
+ </div>
20
+ </dl>
21
+ </section>
22
+ </template>
23
+
24
+ <style scoped>
25
+ .about-page {
26
+ height: 100%;
27
+ padding: 24px;
28
+ box-sizing: border-box;
29
+ background: #f8fafc;
30
+ }
31
+ h1 {
32
+ margin: 0 0 12px;
33
+ font-size: 24px;
34
+ }
35
+ p {
36
+ color: #4b5563;
37
+ line-height: 1.6;
38
+ }
39
+ dl {
40
+ margin-top: 24px;
41
+ display: grid;
42
+ gap: 12px;
43
+ }
44
+ dt {
45
+ font-size: 12px;
46
+ color: #6b7280;
47
+ }
48
+ dd {
49
+ margin: 4px 0 0;
50
+ font-size: 16px;
51
+ font-weight: 600;
52
+ }
53
+ code {
54
+ background: #e5e7eb;
55
+ padding: 1px 6px;
56
+ border-radius: 4px;
57
+ }
58
+ </style>
@@ -0,0 +1,25 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Elpis 帮助文档</title>
7
+ <style>
8
+ body { margin: 0; font-family: system-ui, sans-serif; background: #f7f9fb; color: #1f2937; }
9
+ main { max-width: 720px; margin: 48px auto; padding: 24px; background: white; border-radius: 12px; border: 1px solid #e5e7eb; }
10
+ h1 { margin-top: 0; }
11
+ code { background: #f3f4f6; padding: 2px 6px; border-radius: 4px; }
12
+ </style>
13
+ </head>
14
+ <body>
15
+ <main>
16
+ <h1>帮助文档</h1>
17
+ <p>这是 P3 示例中的 iframe 页面,用于验证 <code>moduleType: iframe</code>。</p>
18
+ <ul>
19
+ <li>Schema 页面:成员管理</li>
20
+ <li>Custom 页面:关于</li>
21
+ <li>Sider 页面:工作台侧栏</li>
22
+ </ul>
23
+ </main>
24
+ </body>
25
+ </html>
@@ -0,0 +1,13 @@
1
+ import type { RouterModule } from '@aklry/elpis-core';
2
+ import type { AppRegistry } from '../../.elpis/types/registry';
3
+
4
+ const routes: RouterModule<AppRegistry> = ({ controller }, router) => {
5
+ router.get('/api/users/list', controller.user.list);
6
+ router.get('/api/users/:id', controller.user.get);
7
+ router.get('/api/users', controller.user.get);
8
+ router.post('/api/users', controller.user.create, { middleware: ['auth'] });
9
+ router.put('/api/users', controller.user.update, { middleware: ['auth'] });
10
+ router.delete('/api/users', controller.user.remove, { middleware: ['auth'] });
11
+ };
12
+
13
+ export default routes;
@@ -0,0 +1,72 @@
1
+ import type { RouterSchema } from '@aklry/elpis-core';
2
+
3
+ const userFields = {
4
+ name: { type: 'string', minLength: 1 },
5
+ role: { type: 'string', enum: ['admin', 'editor', 'viewer'] },
6
+ status: { type: 'string', enum: ['active', 'disabled'] },
7
+ };
8
+
9
+ export default {
10
+ '/api/users/list': {
11
+ get: {
12
+ query: {
13
+ type: 'object',
14
+ properties: {
15
+ page: { type: 'string', pattern: '^[0-9]+$' },
16
+ size: { type: 'string', pattern: '^[0-9]+$' },
17
+ name: { type: 'string' },
18
+ role: { type: 'string' },
19
+ status: { type: 'string' },
20
+ },
21
+ additionalProperties: false,
22
+ },
23
+ },
24
+ },
25
+ '/api/users/:id': {
26
+ get: {
27
+ params: {
28
+ type: 'object',
29
+ required: ['id'],
30
+ properties: { id: { type: 'string', pattern: '^[0-9]+$' } },
31
+ additionalProperties: false,
32
+ },
33
+ },
34
+ },
35
+ '/api/users': {
36
+ get: {
37
+ query: {
38
+ type: 'object',
39
+ required: ['id'],
40
+ properties: { id: { type: 'string', pattern: '^[0-9]+$' } },
41
+ additionalProperties: false,
42
+ },
43
+ },
44
+ post: {
45
+ body: {
46
+ type: 'object',
47
+ required: ['name'],
48
+ properties: userFields,
49
+ additionalProperties: false,
50
+ },
51
+ },
52
+ put: {
53
+ body: {
54
+ type: 'object',
55
+ required: ['id'],
56
+ properties: {
57
+ id: { type: 'string', pattern: '^[0-9]+$' },
58
+ ...userFields,
59
+ },
60
+ additionalProperties: false,
61
+ },
62
+ },
63
+ delete: {
64
+ body: {
65
+ type: 'object',
66
+ required: ['id'],
67
+ properties: { id: { type: 'string', pattern: '^[0-9]+$' } },
68
+ additionalProperties: false,
69
+ },
70
+ },
71
+ },
72
+ } satisfies RouterSchema;
@@ -0,0 +1,71 @@
1
+ import { and, asc, count, eq, ilike } from 'drizzle-orm';
2
+ import { BaseService } from '@aklry/elpis-core';
3
+ import type { AppRegistry } from '../../.elpis/types/registry';
4
+ import { users } from '../database/schema';
5
+
6
+ export interface User {
7
+ id: string;
8
+ name: string;
9
+ role: string;
10
+ status: string;
11
+ }
12
+
13
+ function condition(query: { name?: string; role?: string; status?: string }) {
14
+ const filters = [];
15
+ if (query.name) filters.push(ilike(users.name, `%${query.name}%`));
16
+ if (query.role) filters.push(eq(users.role, query.role));
17
+ if (query.status) filters.push(eq(users.status, query.status));
18
+ return filters.length ? and(...filters) : undefined;
19
+ }
20
+
21
+ export default class UserService extends BaseService<AppRegistry> {
22
+ private get db() {
23
+ return this.extend.database.db;
24
+ }
25
+
26
+ async get(id: string) {
27
+ const rows = await this.db.select().from(users).where(eq(users.id, Number(id))).limit(1);
28
+ const user = rows[0];
29
+ return user ? { ...user, id: String(user.id) } : undefined;
30
+ }
31
+
32
+ async list(query: { page?: number; size?: number; name?: string; role?: string; status?: string } = {}) {
33
+ const page = Math.max(1, Number(query.page) || 1);
34
+ const size = Math.max(1, Math.min(100, Number(query.size) || 10));
35
+ const where = condition(query);
36
+ const [rows, totals] = await Promise.all([
37
+ this.db.select().from(users).where(where).orderBy(asc(users.id)).limit(size).offset((page - 1) * size),
38
+ this.db.select({ count: count() }).from(users).where(where),
39
+ ]);
40
+ return {
41
+ data: rows.map(user => ({ ...user, id: String(user.id) })),
42
+ metadata: { total: Number(totals[0]?.count ?? 0), page, size },
43
+ };
44
+ }
45
+
46
+ async create(input: { name: string; role?: string; status?: string }): Promise<User> {
47
+ const rows = await this.db.insert(users).values({
48
+ name: input.name,
49
+ role: input.role ?? 'viewer',
50
+ status: input.status ?? 'active',
51
+ }).returning();
52
+ const user = rows[0]!;
53
+ return { ...user, id: String(user.id) };
54
+ }
55
+
56
+ async update(id: string, input: { name?: string; role?: string; status?: string }): Promise<User | undefined> {
57
+ const rows = await this.db.update(users).set({
58
+ ...(input.name === undefined ? {} : { name: input.name }),
59
+ ...(input.role === undefined ? {} : { role: input.role }),
60
+ ...(input.status === undefined ? {} : { status: input.status }),
61
+ }).where(eq(users.id, Number(id))).returning();
62
+ const user = rows[0];
63
+ return user ? { ...user, id: String(user.id) } : undefined;
64
+ }
65
+
66
+ async remove(id: string): Promise<User | undefined> {
67
+ const rows = await this.db.delete(users).where(eq(users.id, Number(id))).returning();
68
+ const user = rows[0];
69
+ return user ? { ...user, id: String(user.id) } : undefined;
70
+ }
71
+ }
@@ -0,0 +1,112 @@
1
+ <script setup lang="ts">
2
+ import { computed, onMounted, ref, toRefs, watch } from 'vue';
3
+
4
+ const props = defineProps<{
5
+ schemaKey: string;
6
+ schema: {
7
+ label?: string;
8
+ option?: {
9
+ required?: boolean;
10
+ default?: string;
11
+ disabled?: boolean;
12
+ enumList?: Array<{ label: string; value: string }>;
13
+ };
14
+ };
15
+ model?: string;
16
+ }>();
17
+
18
+ const { model, schema, schemaKey } = toRefs(props);
19
+ const dtoValue = ref<string | undefined>();
20
+ const errorMessage = ref('');
21
+
22
+ const options = computed(() => schema.value.option?.enumList ?? [
23
+ { label: '启用', value: 'active' },
24
+ { label: '停用', value: 'disabled' },
25
+ ]);
26
+
27
+ function initData(): void {
28
+ dtoValue.value = model.value ?? schema.value.option?.default ?? options.value[0]?.value;
29
+ errorMessage.value = '';
30
+ }
31
+
32
+ function validate(): boolean {
33
+ errorMessage.value = '';
34
+ if (schema.value.option?.required && !dtoValue.value) {
35
+ errorMessage.value = '不能为空';
36
+ return false;
37
+ }
38
+ return true;
39
+ }
40
+
41
+ function getValue(): Record<string, string> {
42
+ return dtoValue.value !== undefined ? { [schemaKey.value]: dtoValue.value } : {};
43
+ }
44
+
45
+ onMounted(initData);
46
+ watch([model, schema], initData, { deep: true });
47
+
48
+ defineExpose({ validate, getValue, name: 'statusTag' });
49
+ </script>
50
+
51
+ <template>
52
+ <div class="status-tag-field">
53
+ <label class="label">
54
+ <span v-if="schema.option?.required" class="required">*</span>
55
+ {{ schema.label ?? schemaKey }}
56
+ </label>
57
+ <div class="value">
58
+ <button
59
+ v-for="item in options"
60
+ :key="item.value"
61
+ type="button"
62
+ class="chip"
63
+ :class="{ active: dtoValue === item.value }"
64
+ :disabled="schema.option?.disabled === true"
65
+ @click="dtoValue = item.value"
66
+ >
67
+ {{ item.label }}
68
+ </button>
69
+ </div>
70
+ <p v-if="errorMessage" class="error">{{ errorMessage }}</p>
71
+ </div>
72
+ </template>
73
+
74
+ <style scoped>
75
+ .status-tag-field {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: 12px;
79
+ min-width: 450px;
80
+ margin-bottom: 20px;
81
+ }
82
+ .label {
83
+ min-width: 70px;
84
+ text-align: right;
85
+ font-size: 14px;
86
+ }
87
+ .required {
88
+ color: #f56c6c;
89
+ margin-right: 4px;
90
+ }
91
+ .value {
92
+ display: flex;
93
+ gap: 8px;
94
+ }
95
+ .chip {
96
+ border: 1px solid #d1d5db;
97
+ background: white;
98
+ border-radius: 999px;
99
+ padding: 6px 14px;
100
+ cursor: pointer;
101
+ }
102
+ .chip.active {
103
+ border-color: #2563eb;
104
+ background: #eff6ff;
105
+ color: #1d4ed8;
106
+ }
107
+ .error {
108
+ margin: 0;
109
+ color: #f56c6c;
110
+ font-size: 12px;
111
+ }
112
+ </style>
@@ -0,0 +1,9 @@
1
+ import 'dotenv/config';
2
+ import { defineConfig } from 'drizzle-kit';
3
+
4
+ export default defineConfig({
5
+ schema: './app/database/schema.ts',
6
+ out: './drizzle',
7
+ dialect: 'postgresql',
8
+ dbCredentials: { url: process.env.DATABASE_URL! },
9
+ });
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from '@aklry/elpis-core';
2
+
3
+ export default defineConfig(({ env }) => ({
4
+ name: 'P3 前端示例',
5
+ server: { host: '127.0.0.1', port: 3100 },
6
+ public: { title: 'Elpis Schema 控制台', environment: env },
7
+ private: { greeting: '你好', demoToken: 'local-demo' },
8
+ privateSchema: {
9
+ type: 'object', required: ['greeting', 'demoToken'], additionalProperties: false,
10
+ properties: { greeting: { type: 'string' }, demoToken: { type: 'string' } },
11
+ },
12
+ modules: {
13
+ projectApi: true,
14
+ middleware: [{ name: 'requestTag', options: { label: 'p2-example' } }],
15
+ extensions: {
16
+ database: {},
17
+ },
18
+ },
19
+ }));
@@ -0,0 +1,5 @@
1
+ declare module '*.vue' {
2
+ import type { DefineComponent } from 'vue';
3
+ const component: DefineComponent;
4
+ export default component;
5
+ }
@@ -0,0 +1,199 @@
1
+ import type { FieldObjectSchema, ModelConfig } from '@aklry/elpis-core';
2
+
3
+ const userSchema = {
4
+ type: 'object',
5
+ required: ['name'],
6
+ properties: {
7
+ id: {
8
+ type: 'string',
9
+ label: 'ID',
10
+ tableOption: { visible: true, width: 80 },
11
+ detailPanelOption: { visible: true },
12
+ },
13
+ name: {
14
+ type: 'string',
15
+ label: '姓名',
16
+ minLength: 1,
17
+ maxLength: 32,
18
+ tableOption: { visible: true, minWidth: 120 },
19
+ searchOption: {
20
+ comType: 'input',
21
+ placeholder: '按姓名搜索',
22
+ clearable: true,
23
+ size: 'small',
24
+ },
25
+ createFormOption: { comType: 'input', required: true, placeholder: '请输入姓名' },
26
+ editFormOption: { comType: 'input', required: true },
27
+ detailPanelOption: { visible: true },
28
+ },
29
+ role: {
30
+ type: 'string',
31
+ label: '角色',
32
+ tableOption: { visible: true, minWidth: 100 },
33
+ searchOption: {
34
+ comType: 'select',
35
+ clearable: true,
36
+ filterable: true,
37
+ placeholder: '请选择角色',
38
+ enumList: [
39
+ { label: '管理员', value: 'admin' },
40
+ { label: '编辑', value: 'editor' },
41
+ { label: '访客', value: 'viewer' },
42
+ ],
43
+ },
44
+ createFormOption: {
45
+ comType: 'select',
46
+ required: true,
47
+ default: 'viewer',
48
+ enumList: [
49
+ { label: '管理员', value: 'admin' },
50
+ { label: '编辑', value: 'editor' },
51
+ { label: '访客', value: 'viewer' },
52
+ ],
53
+ },
54
+ editFormOption: {
55
+ comType: 'select',
56
+ required: true,
57
+ enumList: [
58
+ { label: '管理员', value: 'admin' },
59
+ { label: '编辑', value: 'editor' },
60
+ { label: '访客', value: 'viewer' },
61
+ ],
62
+ },
63
+ detailPanelOption: { visible: true },
64
+ },
65
+ status: {
66
+ type: 'string',
67
+ label: '状态',
68
+ tableOption: { visible: true, minWidth: 100 },
69
+ searchOption: {
70
+ comType: 'select',
71
+ clearable: false,
72
+ enumList: [
73
+ { label: '启用', value: 'active' },
74
+ { label: '停用', value: 'disabled' },
75
+ ],
76
+ },
77
+ createFormOption: {
78
+ comType: 'statusTag',
79
+ default: 'active',
80
+ enumList: [
81
+ { label: '启用', value: 'active' },
82
+ { label: '停用', value: 'disabled' },
83
+ ],
84
+ },
85
+ editFormOption: {
86
+ comType: 'select',
87
+ enumList: [
88
+ { label: '启用', value: 'active' },
89
+ { label: '停用', value: 'disabled' },
90
+ ],
91
+ },
92
+ detailPanelOption: { visible: true },
93
+ },
94
+ },
95
+ } satisfies FieldObjectSchema;
96
+
97
+ export default {
98
+ name: '管理系统',
99
+ desc: '共享项目配置',
100
+ homePage: '/view/dashboard/schema?key=users&proj_key=demo',
101
+ menu: [
102
+ {
103
+ key: 'users',
104
+ name: '用户',
105
+ menuType: 'module',
106
+ moduleType: 'schema',
107
+ schemaConfig: {
108
+ api: '/api/users',
109
+ schema: userSchema,
110
+ tableConfig: {
111
+ headerButtons: [
112
+ {
113
+ label: '新建',
114
+ eventKey: 'showComponent',
115
+ eventOption: { comName: 'createForm' },
116
+ type: 'primary',
117
+ },
118
+ ],
119
+ rowButtons: [
120
+ {
121
+ label: '详情',
122
+ eventKey: 'showComponent',
123
+ eventOption: { comName: 'detailPanel' },
124
+ },
125
+ {
126
+ label: '编辑',
127
+ eventKey: 'showComponent',
128
+ eventOption: { comName: 'editForm' },
129
+ },
130
+ {
131
+ label: '删除',
132
+ eventKey: 'remove',
133
+ eventOption: { params: { id: 'schema::id' } },
134
+ type: 'danger',
135
+ },
136
+ ],
137
+ },
138
+ componentConfig: {
139
+ createForm: { title: '新建用户', saveBtnText: '创建' },
140
+ editForm: { title: '编辑用户', saveBtnText: '保存', mainKey: 'id' },
141
+ detailPanel: { title: '用户详情', mainKey: 'id' },
142
+ },
143
+ },
144
+ },
145
+ {
146
+ key: 'workspace',
147
+ name: '工作台',
148
+ menuType: 'module',
149
+ moduleType: 'sider',
150
+ siderConfig: {
151
+ menu: [
152
+ {
153
+ key: 'workspace-users',
154
+ name: '成员',
155
+ menuType: 'module',
156
+ moduleType: 'schema',
157
+ schemaConfig: {
158
+ api: '/api/users',
159
+ schema: userSchema,
160
+ tableConfig: {
161
+ rowButtons: [
162
+ {
163
+ label: '详情',
164
+ eventKey: 'showComponent',
165
+ eventOption: { comName: 'detailPanel' },
166
+ },
167
+ ],
168
+ },
169
+ componentConfig: {
170
+ detailPanel: { title: '用户详情', mainKey: 'id' },
171
+ },
172
+ },
173
+ },
174
+ {
175
+ key: 'workspace-docs',
176
+ name: '文档',
177
+ menuType: 'module',
178
+ moduleType: 'iframe',
179
+ iframeConfig: { path: '/docs.html' },
180
+ },
181
+ {
182
+ key: 'workspace-about',
183
+ name: '关于',
184
+ menuType: 'module',
185
+ moduleType: 'custom',
186
+ customConfig: { path: '/about' },
187
+ },
188
+ ],
189
+ },
190
+ },
191
+ {
192
+ key: 'help',
193
+ name: '帮助',
194
+ menuType: 'module',
195
+ moduleType: 'iframe',
196
+ iframeConfig: { path: '/docs.html' },
197
+ },
198
+ ],
199
+ } satisfies ModelConfig;
@@ -0,0 +1,15 @@
1
+ import type { ProjectConfig } from '@aklry/elpis-core';
2
+
3
+ export default {
4
+ name: '演示项目',
5
+ menu: [
6
+ { key: 'users', name: '成员管理' },
7
+ {
8
+ key: 'about',
9
+ name: '关于',
10
+ menuType: 'module',
11
+ moduleType: 'custom',
12
+ customConfig: { path: '/about' },
13
+ },
14
+ ],
15
+ } satisfies ProjectConfig;
@@ -9,16 +9,20 @@
9
9
  "start": "elpis start"
10
10
  },
11
11
  "dependencies": {
12
+ "@aklry/elpis-cli": "__ELPIS_VERSION__",
12
13
  "@aklry/elpis-core": "__ELPIS_VERSION__",
13
- "@aklry/elpis-cli": "__ELPIS_VERSION__"
14
+ "@aklry/elpis-postgres": "__ELPIS_VERSION__",
15
+ "dotenv": "^18.0.4",
16
+ "drizzle-orm": "^0.44.7"
14
17
  },
15
18
  "devDependencies": {
16
19
  "@aklry/elpis-builder": "__ELPIS_VERSION__",
17
20
  "@aklry/elpis-client": "__ELPIS_VERSION__",
21
+ "@types/node": "^22.15.3",
22
+ "drizzle-kit": "^0.31.11",
23
+ "element-plus": "^2.11.2",
24
+ "pinia": "^3.0.3",
18
25
  "vue": "^3.5.21",
19
- "vue-router": "^4.5.0",
20
- "pinia": "^3.0.0",
21
- "element-plus": "^2.10.0",
22
- "@types/node": "^22.15.3"
26
+ "vue-router": "^4.5.1"
23
27
  }
24
28
  }
@@ -0,0 +1,8 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022", "module": "ESNext", "moduleResolution": "Bundler",
4
+ "strict": true, "skipLibCheck": true, "lib": ["ES2022", "DOM", "DOM.Iterable"],
5
+ "types": [], "noEmit": true
6
+ },
7
+ "include": ["app/client.ts", "app/**/*.vue", "env.d.ts"]
8
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022", "module": "Node16", "moduleResolution": "Node16",
4
+ "strict": true, "esModuleInterop": true, "skipLibCheck": true,
5
+ "types": ["node"], "rootDir": ".", "outDir": "dist/server"
6
+ },
7
+ "include": ["elpis.config.ts", "app/**/*.ts", "model/**/*.ts", ".elpis/types/**/*.d.ts", "drizzle.config.ts"],
8
+ "exclude": ["app/client.ts", "dist", "node_modules"]
9
+ }
@@ -1,27 +0,0 @@
1
- <script setup lang="ts">
2
- import { ref } from "vue";
3
-
4
- const message = ref("Loading...");
5
- const count = ref(0);
6
-
7
- async function loadMessage(): Promise<void> {
8
- const response = await fetch("/api/hello");
9
- const body = await response.json() as { message?: string };
10
- message.value = body.message ?? "No message";
11
- }
12
-
13
- void loadMessage();
14
- </script>
15
-
16
- <template>
17
- <main>
18
- <h1>{{ message }}</h1>
19
- <button type="button" @click="count++">Clicked {{ count }} times</button>
20
- <button type="button" @click="loadMessage">Refresh API</button>
21
- </main>
22
- </template>
23
-
24
- <style scoped>
25
- main { max-width: 720px; margin: 4rem auto; padding: 0 1rem; font-family: sans-serif; }
26
- button { margin-right: 0.5rem; padding: 0.5rem 0.75rem; }
27
- </style>
@@ -1,4 +0,0 @@
1
- import { createClientApp } from "@aklry/elpis-client";
2
- import App from "./App.vue";
3
-
4
- createClientApp(App);
@@ -1,2 +0,0 @@
1
- User-agent: *
2
- Disallow:
@@ -1,13 +0,0 @@
1
- import type { ServerModule } from "@aklry/elpis-core";
2
-
3
- const setup: ServerModule = ({ app, config }) => {
4
- app.use(async (ctx, next) => {
5
- if (ctx.method === "GET" && ctx.path === "/api/hello") {
6
- ctx.body = { message: "Hello from " + config.name };
7
- return;
8
- }
9
- await next();
10
- });
11
- };
12
-
13
- export default setup;
@@ -1,9 +0,0 @@
1
- import { defineConfig } from "@aklry/elpis-core";
2
-
3
- export default defineConfig(({ env }) => ({
4
- name: "Elpis App",
5
- server: { entry: "app/server.ts", host: "127.0.0.1", port: 3000 },
6
- client: { entry: "app/client.ts" },
7
- publicDir: "app/public",
8
- public: { title: "Elpis App", environment: env },
9
- }));
@@ -1,5 +0,0 @@
1
- declare module "*.vue" {
2
- import type { DefineComponent } from "vue";
3
- const component: DefineComponent;
4
- export default component;
5
- }
@@ -1,13 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "ESNext",
5
- "moduleResolution": "Bundler",
6
- "strict": true,
7
- "skipLibCheck": true,
8
- "lib": ["ES2022", "DOM", "DOM.Iterable"],
9
- "types": [],
10
- "noEmit": true
11
- },
12
- "include": ["app/client.ts", "app/**/*.vue", "env.d.ts"]
13
- }
@@ -1,14 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "Node16",
5
- "moduleResolution": "Node16",
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "skipLibCheck": true,
9
- "types": ["node"],
10
- "rootDir": ".",
11
- "outDir": "dist/server"
12
- },
13
- "include": ["elpis.config.ts", "app/server.ts"]
14
- }