@paneljs/paneljs 0.1.0 → 0.2.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 (55) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/dist/adapter.d.ts +10 -6
  3. package/dist/adminService.d.ts +49 -0
  4. package/dist/adminService.js +307 -0
  5. package/dist/adminService.js.map +1 -0
  6. package/dist/authStore.d.ts +31 -0
  7. package/dist/authStore.js +3 -0
  8. package/dist/authStore.js.map +1 -0
  9. package/dist/builtInAuth.d.ts +49 -0
  10. package/dist/builtInAuth.js +117 -0
  11. package/dist/builtInAuth.js.map +1 -0
  12. package/dist/cli/args.d.ts +2 -0
  13. package/dist/cli/args.js +16 -0
  14. package/dist/cli/args.js.map +1 -0
  15. package/dist/cli/auth.d.ts +7 -0
  16. package/dist/cli/auth.js +95 -0
  17. package/dist/cli/auth.js.map +1 -0
  18. package/dist/cli/init.d.ts +37 -0
  19. package/dist/cli/init.js +137 -0
  20. package/dist/cli/init.js.map +1 -0
  21. package/dist/cli/project.d.ts +31 -0
  22. package/dist/cli/project.js +150 -0
  23. package/dist/cli/project.js.map +1 -0
  24. package/dist/cli/prompt.d.ts +10 -0
  25. package/dist/cli/prompt.js +129 -0
  26. package/dist/cli/prompt.js.map +1 -0
  27. package/dist/cli/stack.d.ts +18 -0
  28. package/dist/cli/stack.js +129 -0
  29. package/dist/cli/stack.js.map +1 -0
  30. package/dist/cli.d.ts +2 -0
  31. package/dist/cli.js +53 -0
  32. package/dist/cli.js.map +1 -0
  33. package/dist/deleteRelations.d.ts +17 -0
  34. package/dist/deleteRelations.js +100 -0
  35. package/dist/deleteRelations.js.map +1 -0
  36. package/dist/index.d.ts +21 -7
  37. package/dist/index.js +25 -7
  38. package/dist/index.js.map +1 -1
  39. package/dist/listQuery.d.ts +6 -12
  40. package/dist/listQuery.js +10 -17
  41. package/dist/listQuery.js.map +1 -1
  42. package/dist/query.d.ts +65 -0
  43. package/dist/query.js +12 -0
  44. package/dist/query.js.map +1 -0
  45. package/dist/recordSelection.d.ts +3 -6
  46. package/dist/recordSelection.js +26 -20
  47. package/dist/recordSelection.js.map +1 -1
  48. package/dist/scope.d.ts +1 -1
  49. package/dist/types.d.ts +6 -1
  50. package/package.json +19 -10
  51. package/ui/dist/assets/index-BFz2MB0D.js +11 -0
  52. package/ui/dist/assets/index-B_bCMkti.css +1 -0
  53. package/ui/dist/index.html +2 -2
  54. package/ui/dist/assets/index-ChtweaBk.js +0 -11
  55. package/ui/dist/assets/index-eXfQCDXx.css +0 -1
@@ -0,0 +1,117 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { verifyLoginPassword } from "./passwords.js";
3
+ export const SESSION_COOKIE_NAME = "paneljs_session";
4
+ export const DEFAULT_SESSION_TTL_SECONDS = 60 * 60 * 24 * 7;
5
+ export function hashSessionToken(token) {
6
+ return createHash("sha256").update(token).digest("hex");
7
+ }
8
+ export function readSessionToken(req) {
9
+ const header = req.headers.cookie;
10
+ if (typeof header !== "string")
11
+ return null;
12
+ for (const part of header.split(";")) {
13
+ const [key, ...value] = part.trim().split("=");
14
+ if (key === SESSION_COOKIE_NAME) {
15
+ try {
16
+ return decodeURIComponent(value.join("="));
17
+ }
18
+ catch {
19
+ return null;
20
+ }
21
+ }
22
+ }
23
+ return null;
24
+ }
25
+ function cookieSecure(config) {
26
+ return config.secureCookies ?? process.env.NODE_ENV === "production";
27
+ }
28
+ export function sessionCookie(token, config, basePath, expires) {
29
+ return {
30
+ name: SESSION_COOKIE_NAME,
31
+ value: token,
32
+ path: basePath,
33
+ httpOnly: true,
34
+ sameSite: "Lax",
35
+ maxAge: Math.max(0, Math.floor((expires.getTime() - Date.now()) / 1000)),
36
+ expires,
37
+ secure: cookieSecure(config),
38
+ };
39
+ }
40
+ export function clearedSessionCookie(config, basePath) {
41
+ return {
42
+ name: SESSION_COOKIE_NAME,
43
+ value: "",
44
+ path: basePath,
45
+ httpOnly: true,
46
+ sameSite: "Lax",
47
+ maxAge: 0,
48
+ expires: new Date(0),
49
+ secure: cookieSecure(config),
50
+ };
51
+ }
52
+ export function builtInUserToAdminUser(user) {
53
+ if (!user.isActive || !["ADMIN", "SUPER_ADMIN"].includes(user.role))
54
+ return null;
55
+ return {
56
+ id: user.id,
57
+ email: user.email ?? user.username ?? user.id,
58
+ ...(user.username ? { username: user.username } : {}),
59
+ ...(user.tenantId ? { tenantId: user.tenantId } : {}),
60
+ role: user.role,
61
+ isSuperAdmin: user.role === "SUPER_ADMIN",
62
+ };
63
+ }
64
+ export function resolveAuthStore(adapter, auth) {
65
+ if (auth.store)
66
+ return auth.store;
67
+ if (adapter.createAuthStore)
68
+ return adapter.createAuthStore(auth);
69
+ throw new Error("[paneljs] Built-in auth requires auth.store or an adapter that implements createAuthStore().");
70
+ }
71
+ export async function authenticateSession(store, token) {
72
+ if (!token)
73
+ return null;
74
+ const session = await store.findSessionWithUser(hashSessionToken(token));
75
+ if (!session)
76
+ return null;
77
+ if (session.expiresAt.getTime() <= Date.now())
78
+ return null;
79
+ return builtInUserToAdminUser(session.user);
80
+ }
81
+ export async function authenticateBuiltInRequest(req, store) {
82
+ return authenticateSession(store, readSessionToken(req));
83
+ }
84
+ const invalidCredentials = {
85
+ ok: false,
86
+ status: 401,
87
+ body: { error: "Invalid credentials.", code: "INVALID_CREDENTIALS" },
88
+ };
89
+ export async function loginWithPassword(store, config, credentials, basePath) {
90
+ const identifier = credentials.identifier.trim();
91
+ const password = credentials.password;
92
+ if (!identifier || !password || identifier.length > 254 || password.length > 1_024) {
93
+ return invalidCredentials;
94
+ }
95
+ const user = await store.findUserByIdentifier(identifier);
96
+ const passwordMatches = await verifyLoginPassword(password, user?.passwordHash);
97
+ const adminUser = user && passwordMatches ? builtInUserToAdminUser(user) : null;
98
+ if (!user || !adminUser)
99
+ return invalidCredentials;
100
+ const token = randomBytes(32).toString("base64url");
101
+ const ttlSeconds = config.sessionTtlSeconds ?? DEFAULT_SESSION_TTL_SECONDS;
102
+ const expiresAt = new Date(Date.now() + ttlSeconds * 1_000);
103
+ await store.createSession({ tokenHash: hashSessionToken(token), userId: user.id, expiresAt });
104
+ return {
105
+ ok: true,
106
+ status: 200,
107
+ body: { ok: true },
108
+ cookie: sessionCookie(token, config, basePath, expiresAt),
109
+ };
110
+ }
111
+ export async function logoutBuiltIn(store, req, config, basePath) {
112
+ const token = readSessionToken(req);
113
+ if (token)
114
+ await store.deleteSessionByTokenHash(hashSessionToken(token));
115
+ return { status: 204, cookie: clearedSessionCookie(config, basePath) };
116
+ }
117
+ //# sourceMappingURL=builtInAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builtInAuth.js","sourceRoot":"","sources":["../src/builtInAuth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function argument(argv: string[], name: string): string | undefined;
2
+ export declare function hasFlag(argv: string[], name: string): boolean;
@@ -0,0 +1,16 @@
1
+ export function argument(argv, name) {
2
+ const equals = argv.find((item) => item.startsWith(`${name}=`));
3
+ if (equals)
4
+ return equals.slice(name.length + 1) || undefined;
5
+ const index = argv.indexOf(name);
6
+ if (index < 0)
7
+ return undefined;
8
+ const value = argv[index + 1];
9
+ if (!value || value.startsWith("-"))
10
+ return undefined;
11
+ return value;
12
+ }
13
+ export function hasFlag(argv, name) {
14
+ return argv.includes(name);
15
+ }
16
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,QAAQ,CACtB,IAAc,EACd,IAAY;IAEZ,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC;IAChE,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,SAAS,CAAC;IAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAc,EAAE,IAAY;IAClD,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { BuiltInAuthConfig } from "../types.js";
2
+ export interface PaneljsCliConfig {
3
+ prisma: object;
4
+ auth: BuiltInAuthConfig;
5
+ }
6
+ export declare function authSchema(identifier: string): string;
7
+ export declare const createSuperuser: (argv: string[]) => Promise<void>;
@@ -0,0 +1,95 @@
1
+ import { resolve } from "node:path";
2
+ import { pathToFileURL } from "node:url";
3
+ import { hashAdminPassword } from "../passwords.js";
4
+ import { argument } from "./args.js";
5
+ import { confirm, hiddenQuestion, question } from "./prompt.js";
6
+ const emailSchema = `enum ExpressAdminRole {
7
+ ADMIN
8
+ SUPER_ADMIN
9
+ }
10
+
11
+ model ExpressAdminUser {
12
+ id String @id @default(cuid())
13
+ email String @unique
14
+ passwordHash String
15
+ role ExpressAdminRole @default(ADMIN)
16
+ isActive Boolean @default(true)
17
+ createdAt DateTime @default(now())
18
+ updatedAt DateTime @updatedAt
19
+ sessions ExpressAdminSession[]
20
+ }
21
+
22
+ model ExpressAdminSession {
23
+ id String @id @default(cuid())
24
+ tokenHash String @unique
25
+ userId String
26
+ user ExpressAdminUser @relation(fields: [userId], references: [id], onDelete: Cascade)
27
+ expiresAt DateTime
28
+ createdAt DateTime @default(now())
29
+
30
+ @@index([userId])
31
+ @@index([expiresAt])
32
+ }`;
33
+ const usernameSchema = emailSchema.replace("email String @unique", "username String @unique");
34
+ export function authSchema(identifier) {
35
+ if (identifier !== "email" && identifier !== "username") {
36
+ throw new Error("auth:schema requires --identifier email or --identifier username");
37
+ }
38
+ return identifier === "email" ? emailSchema : usernameSchema;
39
+ }
40
+ const modelKey = (modelName) => modelName.charAt(0).toLowerCase() + modelName.slice(1);
41
+ const loadConfig = async (configPath) => {
42
+ const module = await import(pathToFileURL(resolve(configPath)).href);
43
+ const config = module.default;
44
+ if (!config?.prisma || config.auth?.mode !== "built-in")
45
+ throw new Error('The config must default-export { prisma, auth: { mode: "built-in", ... } }. TypeORM apps should insert the first operator with hashAdminPassword instead.');
46
+ return config;
47
+ };
48
+ export const createSuperuser = async (argv) => {
49
+ const configPath = argument(argv, "--config");
50
+ if (!configPath)
51
+ throw new Error("createsuperuser requires --config ./paneljs.config.mjs");
52
+ const config = await loadConfig(configPath);
53
+ try {
54
+ const identifierName = config.auth.identifier;
55
+ const identifier = argument(argv, `--${identifierName}`) ??
56
+ (await question(`${identifierName === "email" ? "Email" : "Username"}: `));
57
+ const suppliedPassword = argument(argv, "--password") ?? process.env.EXPRESS_ADMIN_PASSWORD;
58
+ const password = suppliedPassword ?? (await hiddenQuestion("Password: "));
59
+ if (!suppliedPassword) {
60
+ const confirmation = await hiddenQuestion("Confirm password: ");
61
+ if (password !== confirmation)
62
+ throw new Error("Passwords do not match.");
63
+ }
64
+ if (!identifier || identifier.length > 254)
65
+ throw new Error(`A valid ${identifierName} is required.`);
66
+ if (!password)
67
+ throw new Error("Password cannot be empty.");
68
+ if (password.length < 12) {
69
+ const warning = "This password is shorter than the recommended 12 characters. Continue anyway?";
70
+ if (suppliedPassword)
71
+ console.warn(`Warning: ${warning}`);
72
+ else if (!(await confirm(warning, false)))
73
+ throw new Error("Superuser creation cancelled.");
74
+ }
75
+ const delegate = config.prisma[modelKey(config.auth.userModel ?? "ExpressAdminUser")];
76
+ if (!delegate)
77
+ throw new Error(`Prisma client has no delegate for ${config.auth.userModel ?? "ExpressAdminUser"}. Generate your Prisma client after adding the auth schema.`);
78
+ await delegate.create({
79
+ data: {
80
+ [identifierName]: identifier,
81
+ passwordHash: await hashAdminPassword(password),
82
+ role: "SUPER_ADMIN",
83
+ isActive: true,
84
+ },
85
+ });
86
+ console.log(`Superuser created. Sign in at /admin/login with your ${identifierName}.`);
87
+ }
88
+ finally {
89
+ const disconnect = config.prisma
90
+ .$disconnect;
91
+ if (disconnect)
92
+ await disconnect.call(config.prisma);
93
+ }
94
+ };
95
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/cli/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOhE,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BlB,CAAC;AAEH,MAAM,cAAc,GAAG,WAAW,CAAC,OAAO,CACxC,uCAAuC,EACvC,uCAAuC,CACxC,CAAC;AAEF,MAAM,UAAU,UAAU,CAAC,UAAkB;IAC3C,IAAI,UAAU,KAAK,OAAO,IAAI,UAAU,KAAK,UAAU,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CACb,kEAAkE,CACnE,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC;AAC/D,CAAC;AAED,MAAM,QAAQ,GAAG,CAAC,SAAiB,EAAE,EAAE,CACrC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEzD,MAAM,UAAU,GAAG,KAAK,EAAE,UAAkB,EAA6B,EAAE;IACzE,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACrE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAuC,CAAC;IAC9D,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,KAAK,UAAU;QACrD,MAAM,IAAI,KAAK,CACb,2JAA2J,CAC5J,CAAC;IACJ,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,IAAc,EAAiB,EAAE;IACrE,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU;QACb,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QAC9C,MAAM,UAAU,GACd,QAAQ,CAAC,IAAI,EAAE,KAAK,cAAc,EAAE,CAAC;YACrC,CAAC,MAAM,QAAQ,CACb,GAAG,cAAc,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,IAAI,CACzD,CAAC,CAAC;QACL,MAAM,gBAAgB,GACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;QACrE,MAAM,QAAQ,GAAG,gBAAgB,IAAI,CAAC,MAAM,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACtB,MAAM,YAAY,GAAG,MAAM,cAAc,CAAC,oBAAoB,CAAC,CAAC;YAChE,IAAI,QAAQ,KAAK,YAAY;gBAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG;YACxC,MAAM,IAAI,KAAK,CAAC,WAAW,cAAc,eAAe,CAAC,CAAC;QAC5D,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC5D,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACzB,MAAM,OAAO,GACX,+EAA+E,CAAC;YAClF,IAAI,gBAAgB;gBAAE,OAAO,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;iBACrD,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBACvC,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,QAAQ,GAAI,MAAM,CAAC,MAAkC,CACzD,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,kBAAkB,CAAC,CACK,CAAC;QAC7D,IAAI,CAAC,QAAQ;YACX,MAAM,IAAI,KAAK,CACb,qCAAqC,MAAM,CAAC,IAAI,CAAC,SAAS,IAAI,kBAAkB,6DAA6D,CAC9I,CAAC;QACJ,MAAM,QAAQ,CAAC,MAAM,CAAC;YACpB,IAAI,EAAE;gBACJ,CAAC,cAAc,CAAC,EAAE,UAAU;gBAC5B,YAAY,EAAE,MAAM,iBAAiB,CAAC,QAAQ,CAAC;gBAC/C,IAAI,EAAE,aAAa;gBACnB,QAAQ,EAAE,IAAI;aACf;SACF,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CACT,wDAAwD,cAAc,GAAG,CAC1E,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,MAAM,UAAU,GAAI,MAAM,CAAC,MAAgD;aACxE,WAAW,CAAC;QACf,IAAI,UAAU;YAAE,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACvD,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { type InstallPlan, type PackageManifest } from "./project.js";
2
+ import type { SelectItem } from "./prompt.js";
3
+ import { type FrameworkId, type OrmId, type PackageManager } from "./stack.js";
4
+ export interface InitFlags {
5
+ framework?: string;
6
+ orm?: string;
7
+ pm?: string;
8
+ yes?: boolean;
9
+ dryRun?: boolean;
10
+ help?: boolean;
11
+ }
12
+ export interface InitIo {
13
+ stdout: {
14
+ write(chunk: string): void;
15
+ };
16
+ isTTY: boolean;
17
+ env: NodeJS.ProcessEnv;
18
+ select(label: string, items: SelectItem[]): Promise<string>;
19
+ confirm(label: string): Promise<boolean>;
20
+ install(pm: PackageManager, cwd: string, dependencies: string[], devDependencies: string[]): Promise<void>;
21
+ }
22
+ export declare function parseInitArgs(argv: string[]): InitFlags;
23
+ export declare const INIT_USAGE = "Usage:\n paneljs init [--framework express] [--orm prisma|typeorm] [--pm npm|pnpm|yarn|bun] [--yes] [--dry-run]\n\nAdds PanelJS packages to the app in this directory. Does not rewrite source files.\nFastify, Nest.js, and Drizzle are listed in the prompt but are not selectable yet.";
24
+ export interface ResolvedInit {
25
+ framework: FrameworkId;
26
+ orm: OrmId;
27
+ pm: PackageManager;
28
+ plan: InstallPlan;
29
+ packages: string[];
30
+ }
31
+ export declare function resolveInitPlan(cwd: string, flags: InitFlags, manifest: PackageManifest, env: NodeJS.ProcessEnv, framework: FrameworkId, orm: OrmId): ResolvedInit;
32
+ export declare function runInit(input: {
33
+ cwd: string;
34
+ argv: string[];
35
+ io: InitIo;
36
+ }): Promise<void>;
37
+ export declare function createDefaultInstall(): InitIo["install"];
@@ -0,0 +1,137 @@
1
+ import { spawn } from "node:child_process";
2
+ import { argument, hasFlag } from "./args.js";
3
+ import { detectPackageManager, installArgs, peersFor, planInstall, readManifest, } from "./project.js";
4
+ import { docsUrl, FRAMEWORKS, ORMS, paneljsPackages, parseFramework, parseOrm, resolveFramework, resolveOrm, setupSnippet, } from "./stack.js";
5
+ export function parseInitArgs(argv) {
6
+ const unknown = argv.filter((item) => item.startsWith("-") &&
7
+ item !== "--framework" &&
8
+ item !== "--orm" &&
9
+ item !== "--pm" &&
10
+ item !== "--yes" &&
11
+ item !== "-y" &&
12
+ item !== "--dry-run" &&
13
+ item !== "--help" &&
14
+ item !== "-h" &&
15
+ !item.startsWith("--framework=") &&
16
+ !item.startsWith("--orm=") &&
17
+ !item.startsWith("--pm="));
18
+ if (unknown.length > 0) {
19
+ throw new Error(`Unknown init flag: ${unknown[0]}`);
20
+ }
21
+ return {
22
+ framework: argument(argv, "--framework"),
23
+ orm: argument(argv, "--orm"),
24
+ pm: argument(argv, "--pm"),
25
+ yes: hasFlag(argv, "--yes") || hasFlag(argv, "-y"),
26
+ dryRun: hasFlag(argv, "--dry-run"),
27
+ help: hasFlag(argv, "--help") || hasFlag(argv, "-h"),
28
+ };
29
+ }
30
+ export const INIT_USAGE = `Usage:
31
+ paneljs init [--framework express] [--orm prisma|typeorm] [--pm npm|pnpm|yarn|bun] [--yes] [--dry-run]
32
+
33
+ Adds PanelJS packages to the app in this directory. Does not rewrite source files.
34
+ Fastify, Nest.js, and Drizzle are listed in the prompt but are not selectable yet.`;
35
+ export function resolveInitPlan(cwd, flags, manifest, env, framework, orm) {
36
+ const frameworkChoice = resolveFramework(framework);
37
+ const ormChoice = resolveOrm(orm);
38
+ const packages = paneljsPackages(frameworkChoice.id, ormChoice.id);
39
+ const plan = planInstall(manifest, packages, peersFor(ormChoice.id));
40
+ if (plan.incompatible.length > 0) {
41
+ throw new Error(plan.incompatible.join("\n"));
42
+ }
43
+ const pm = detectPackageManager(cwd, manifest, env, flags.pm);
44
+ return { framework: frameworkChoice.id, orm: ormChoice.id, pm, plan, packages };
45
+ }
46
+ export async function runInit(input) {
47
+ const flags = parseInitArgs(input.argv);
48
+ if (flags.help === true) {
49
+ input.io.stdout.write(`${INIT_USAGE}\n`);
50
+ return;
51
+ }
52
+ const manifest = readManifest(input.cwd);
53
+ const framework = await pick("Which Node framework are you using?", flags.framework, FRAMEWORKS.map((item) => ({
54
+ value: item.id,
55
+ label: item.label,
56
+ disabled: !item.available,
57
+ })), flags, input.io, (value) => parseFramework(value));
58
+ const orm = await pick("Which ORM are you using?", flags.orm, ORMS.map((item) => ({
59
+ value: item.id,
60
+ label: item.label,
61
+ disabled: !item.available,
62
+ })), flags, input.io, (value) => parseOrm(value));
63
+ const resolved = resolveInitPlan(input.cwd, flags, manifest, input.io.env, framework, orm);
64
+ const { plan } = resolved;
65
+ const adding = [...plan.dependencies, ...plan.devDependencies];
66
+ input.io.stdout.write("\n");
67
+ if (adding.length === 0) {
68
+ input.io.stdout.write("PanelJS packages for this stack are already listed.\n");
69
+ }
70
+ else {
71
+ input.io.stdout.write(`Using ${resolved.pm}. Will add:\n`);
72
+ for (const name of plan.dependencies)
73
+ input.io.stdout.write(` ${name}\n`);
74
+ for (const name of plan.devDependencies)
75
+ input.io.stdout.write(` ${name} (dev)\n`);
76
+ }
77
+ if (plan.alreadyPresent.length > 0) {
78
+ input.io.stdout.write(`Already present: ${plan.alreadyPresent.join(", ")}\n`);
79
+ }
80
+ input.io.stdout.write("No source files will be changed.\n");
81
+ if (flags.dryRun === true) {
82
+ input.io.stdout.write("\nDry run. Nothing was installed.\n");
83
+ writeSnippet(input.io, resolved.framework, resolved.orm);
84
+ return;
85
+ }
86
+ if (adding.length > 0 && flags.yes !== true) {
87
+ if (!input.io.isTTY) {
88
+ throw new Error("Non-interactive install requires --yes.");
89
+ }
90
+ const ok = await input.io.confirm("Install these packages?");
91
+ if (!ok)
92
+ throw new Error("Init cancelled.");
93
+ }
94
+ if (adding.length > 0) {
95
+ await input.io.install(resolved.pm, input.cwd, plan.dependencies, plan.devDependencies);
96
+ }
97
+ input.io.stdout.write("\nInstalled. Wire this into your existing server:\n\n");
98
+ writeSnippet(input.io, resolved.framework, resolved.orm);
99
+ }
100
+ function writeSnippet(io, framework, orm) {
101
+ io.stdout.write(`${setupSnippet(framework, orm)}\n\n`);
102
+ io.stdout.write(`Docs: ${docsUrl(framework, orm)}\n`);
103
+ io.stdout.write("Auth: https://www.paneljs.com/docs/guide/auth\n");
104
+ }
105
+ async function pick(label, flagged, items, flags, io, parse) {
106
+ if (flagged)
107
+ return parse(flagged);
108
+ if (flags.yes === true || !io.isTTY) {
109
+ throw new Error(`${label} Pass the matching flag with --yes, or run in a terminal.`);
110
+ }
111
+ return parse(await io.select(label, items));
112
+ }
113
+ export function createDefaultInstall() {
114
+ return async (pm, cwd, dependencies, devDependencies) => {
115
+ if (dependencies.length > 0)
116
+ await runCommand(pm, installArgs(pm, dependencies, false), cwd);
117
+ if (devDependencies.length > 0)
118
+ await runCommand(pm, installArgs(pm, devDependencies, true), cwd);
119
+ };
120
+ }
121
+ function runCommand(command, args, cwd) {
122
+ return new Promise((resolve, reject) => {
123
+ const child = spawn(command, args, {
124
+ cwd,
125
+ stdio: "inherit",
126
+ shell: process.platform === "win32",
127
+ });
128
+ child.on("error", reject);
129
+ child.on("exit", (code) => {
130
+ if (code === 0)
131
+ resolve();
132
+ else
133
+ reject(new Error(`${command} ${args.join(" ")} exited with code ${code}.`));
134
+ });
135
+ });
136
+ }
137
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { OrmId, PackageManager } from "./stack.js";
2
+ export interface PackageManifest {
3
+ dependencies?: Record<string, string>;
4
+ devDependencies?: Record<string, string>;
5
+ optionalDependencies?: Record<string, string>;
6
+ packageManager?: string;
7
+ }
8
+ export interface PeerNeed {
9
+ name: string;
10
+ installAs: "dep" | "dev";
11
+ spec?: string;
12
+ }
13
+ export declare function readManifest(cwd: string): PackageManifest;
14
+ export declare function declaredSpec(manifest: PackageManifest, name: string): string | undefined;
15
+ export declare function detectPackageManager(cwd: string, manifest: PackageManifest, env: NodeJS.ProcessEnv, override?: string): PackageManager;
16
+ export declare function packageManagerFromUserAgent(userAgent: string | undefined): PackageManager | undefined;
17
+ export declare function peersFor(orm: OrmId): PeerNeed[];
18
+ export declare function incompatiblePeer(name: string, spec: string): string | undefined;
19
+ export declare function parseLeadingVersion(spec: string): {
20
+ major: number;
21
+ minor: number;
22
+ patch: number;
23
+ } | undefined;
24
+ export interface InstallPlan {
25
+ dependencies: string[];
26
+ devDependencies: string[];
27
+ alreadyPresent: string[];
28
+ incompatible: string[];
29
+ }
30
+ export declare function planInstall(manifest: PackageManifest, panelPackages: string[], peers: PeerNeed[]): InstallPlan;
31
+ export declare function installArgs(pm: PackageManager, packages: string[], dev: boolean): string[];
@@ -0,0 +1,150 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ const PRISMA_PEERS = [
4
+ { name: "express", installAs: "dep" },
5
+ { name: "@prisma/client", installAs: "dep", spec: "~7.5.0" },
6
+ { name: "prisma", installAs: "dev", spec: "~7.5.0" },
7
+ ];
8
+ const TYPEORM_PEERS = [
9
+ { name: "express", installAs: "dep" },
10
+ { name: "typeorm", installAs: "dep", spec: "^0.3.20" },
11
+ ];
12
+ export function readManifest(cwd) {
13
+ const path = join(cwd, "package.json");
14
+ if (!existsSync(path)) {
15
+ throw new Error("No package.json in this directory. Run paneljs init inside your app.");
16
+ }
17
+ try {
18
+ return JSON.parse(readFileSync(path, "utf8"));
19
+ }
20
+ catch {
21
+ throw new Error(`Could not parse ${path}.`);
22
+ }
23
+ }
24
+ export function declaredSpec(manifest, name) {
25
+ return (manifest.dependencies?.[name] ??
26
+ manifest.devDependencies?.[name] ??
27
+ manifest.optionalDependencies?.[name]);
28
+ }
29
+ export function detectPackageManager(cwd, manifest, env, override) {
30
+ if (override) {
31
+ const allowed = ["npm", "pnpm", "yarn", "bun"];
32
+ if (!allowed.includes(override)) {
33
+ throw new Error(`Unknown package manager "${override}". Use npm, pnpm, yarn, or bun.`);
34
+ }
35
+ return override;
36
+ }
37
+ const fromAgent = packageManagerFromUserAgent(env.npm_config_user_agent);
38
+ if (fromAgent)
39
+ return fromAgent;
40
+ const field = manifest.packageManager?.split("@")[0];
41
+ if (field === "npm" || field === "pnpm" || field === "yarn" || field === "bun") {
42
+ return field;
43
+ }
44
+ if (existsSync(join(cwd, "pnpm-lock.yaml")))
45
+ return "pnpm";
46
+ if (existsSync(join(cwd, "yarn.lock")))
47
+ return "yarn";
48
+ if (existsSync(join(cwd, "bun.lock")) || existsSync(join(cwd, "bun.lockb")))
49
+ return "bun";
50
+ if (existsSync(join(cwd, "package-lock.json")))
51
+ return "npm";
52
+ return "npm";
53
+ }
54
+ export function packageManagerFromUserAgent(userAgent) {
55
+ if (!userAgent)
56
+ return undefined;
57
+ const name = userAgent.split("/")[0];
58
+ if (name === "npm" || name === "pnpm" || name === "yarn" || name === "bun") {
59
+ return name;
60
+ }
61
+ return undefined;
62
+ }
63
+ export function peersFor(orm) {
64
+ if (orm === "prisma")
65
+ return PRISMA_PEERS;
66
+ if (orm === "typeorm")
67
+ return TYPEORM_PEERS;
68
+ return [{ name: "express", installAs: "dep" }];
69
+ }
70
+ export function incompatiblePeer(name, spec) {
71
+ if (spec.startsWith("workspace:") ||
72
+ spec.startsWith("catalog:") ||
73
+ spec === "*" ||
74
+ spec === "latest") {
75
+ return undefined;
76
+ }
77
+ const version = parseLeadingVersion(spec);
78
+ if (!version)
79
+ return undefined;
80
+ if (name === "prisma" || name === "@prisma/client") {
81
+ if (version.major !== 7 || version.minor !== 5) {
82
+ return `${name}@${spec} is not Prisma 7.5.x. @paneljs/prisma requires ~7.5.0.`;
83
+ }
84
+ return undefined;
85
+ }
86
+ if (name === "typeorm") {
87
+ if (version.major !== 0 ||
88
+ version.minor < 3 ||
89
+ (version.minor === 3 && version.patch < 20)) {
90
+ return `${name}@${spec} is below ^0.3.20.`;
91
+ }
92
+ return undefined;
93
+ }
94
+ if (name === "express") {
95
+ if (version.major < 4 || (version.major === 4 && version.minor < 18)) {
96
+ return `${name}@${spec} is below ^4.18 or ^5.`;
97
+ }
98
+ return undefined;
99
+ }
100
+ return undefined;
101
+ }
102
+ export function parseLeadingVersion(spec) {
103
+ const match = spec
104
+ .replace(/^[~^>=<\s]+/, "")
105
+ .match(/^(\d+)\.(\d+)(?:\.(\d+))?/);
106
+ if (!match)
107
+ return undefined;
108
+ return {
109
+ major: Number(match[1]),
110
+ minor: Number(match[2]),
111
+ patch: Number(match[3] ?? 0),
112
+ };
113
+ }
114
+ export function planInstall(manifest, panelPackages, peers) {
115
+ const incompatible = [];
116
+ const alreadyPresent = [];
117
+ const dependencies = [];
118
+ const devDependencies = [];
119
+ const consider = (name, installAs, spec) => {
120
+ const declared = declaredSpec(manifest, name);
121
+ if (declared) {
122
+ const problem = incompatiblePeer(name, declared);
123
+ if (problem)
124
+ incompatible.push(problem);
125
+ else
126
+ alreadyPresent.push(name);
127
+ return;
128
+ }
129
+ const token = spec ? `${name}@${spec}` : name;
130
+ if (installAs === "dev")
131
+ devDependencies.push(token);
132
+ else
133
+ dependencies.push(token);
134
+ };
135
+ for (const name of panelPackages)
136
+ consider(name, "dep");
137
+ for (const peer of peers)
138
+ consider(peer.name, peer.installAs, peer.spec);
139
+ return { dependencies, devDependencies, alreadyPresent, incompatible };
140
+ }
141
+ export function installArgs(pm, packages, dev) {
142
+ if (packages.length === 0)
143
+ return [];
144
+ if (pm === "npm")
145
+ return ["install", ...(dev ? ["-D"] : []), ...packages];
146
+ if (pm === "bun")
147
+ return ["add", ...(dev ? ["-d"] : []), ...packages];
148
+ return ["add", ...(dev ? ["-D"] : []), ...packages];
149
+ }
150
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/cli/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface SelectItem {
2
+ value: string;
3
+ label: string;
4
+ disabled?: boolean;
5
+ hint?: string;
6
+ }
7
+ export declare function question(label: string): Promise<string>;
8
+ export declare function confirm(label: string, defaultYes?: boolean): Promise<boolean>;
9
+ export declare function hiddenQuestion(label: string): Promise<string>;
10
+ export declare function select(label: string, items: SelectItem[]): Promise<string>;