hazo_auth 4.2.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/hazo_auth.mjs +35 -0
- package/cli-src/assets/images/forgot_password_default.jpg +0 -0
- package/cli-src/assets/images/login_default.jpg +0 -0
- package/cli-src/assets/images/register_default.jpg +0 -0
- package/cli-src/assets/images/reset_password_default.jpg +0 -0
- package/cli-src/assets/images/verify_email_default.jpg +0 -0
- package/cli-src/cli/generate.ts +276 -0
- package/cli-src/cli/index.ts +207 -0
- package/cli-src/cli/init.ts +254 -0
- package/cli-src/cli/init_users.ts +376 -0
- package/cli-src/cli/validate.ts +581 -0
- package/cli-src/lib/already_logged_in_config.server.ts +46 -0
- package/cli-src/lib/app_logger.ts +24 -0
- package/cli-src/lib/auth/auth_cache.ts +220 -0
- package/cli-src/lib/auth/auth_rate_limiter.ts +121 -0
- package/cli-src/lib/auth/auth_types.ts +110 -0
- package/cli-src/lib/auth/auth_utils.server.ts +196 -0
- package/cli-src/lib/auth/hazo_get_auth.server.ts +512 -0
- package/cli-src/lib/auth/index.ts +23 -0
- package/cli-src/lib/auth/nextauth_config.ts +227 -0
- package/cli-src/lib/auth/scope_cache.ts +233 -0
- package/cli-src/lib/auth/server_auth.ts +88 -0
- package/cli-src/lib/auth/session_token_validator.edge.ts +91 -0
- package/cli-src/lib/auth_utility_config.server.ts +136 -0
- package/cli-src/lib/config/config_loader.server.ts +164 -0
- package/cli-src/lib/config/default_config.ts +199 -0
- package/cli-src/lib/email_verification_config.server.ts +63 -0
- package/cli-src/lib/file_types_config.server.ts +25 -0
- package/cli-src/lib/forgot_password_config.server.ts +63 -0
- package/cli-src/lib/hazo_connect_instance.server.ts +101 -0
- package/cli-src/lib/hazo_connect_setup.server.ts +194 -0
- package/cli-src/lib/hazo_connect_setup.ts +54 -0
- package/cli-src/lib/index.ts +46 -0
- package/cli-src/lib/login_config.server.ts +106 -0
- package/cli-src/lib/messages_config.server.ts +45 -0
- package/cli-src/lib/migrations/apply_migration.ts +105 -0
- package/cli-src/lib/my_settings_config.server.ts +135 -0
- package/cli-src/lib/oauth_config.server.ts +87 -0
- package/cli-src/lib/password_requirements_config.server.ts +40 -0
- package/cli-src/lib/profile_pic_menu_config.server.ts +138 -0
- package/cli-src/lib/profile_picture_config.server.ts +56 -0
- package/cli-src/lib/register_config.server.ts +101 -0
- package/cli-src/lib/reset_password_config.server.ts +103 -0
- package/cli-src/lib/scope_hierarchy_config.server.ts +151 -0
- package/cli-src/lib/services/email_service.ts +587 -0
- package/cli-src/lib/services/email_verification_service.ts +270 -0
- package/cli-src/lib/services/index.ts +16 -0
- package/cli-src/lib/services/login_service.ts +150 -0
- package/cli-src/lib/services/oauth_service.ts +494 -0
- package/cli-src/lib/services/password_change_service.ts +154 -0
- package/cli-src/lib/services/password_reset_service.ts +418 -0
- package/cli-src/lib/services/profile_picture_remove_service.ts +120 -0
- package/cli-src/lib/services/profile_picture_service.ts +451 -0
- package/cli-src/lib/services/profile_picture_source_mapper.ts +62 -0
- package/cli-src/lib/services/registration_service.ts +185 -0
- package/cli-src/lib/services/scope_labels_service.ts +348 -0
- package/cli-src/lib/services/scope_service.ts +778 -0
- package/cli-src/lib/services/session_token_service.ts +177 -0
- package/cli-src/lib/services/token_service.ts +240 -0
- package/cli-src/lib/services/user_profiles_cache.ts +189 -0
- package/cli-src/lib/services/user_profiles_service.ts +264 -0
- package/cli-src/lib/services/user_scope_service.ts +554 -0
- package/cli-src/lib/services/user_update_service.ts +141 -0
- package/cli-src/lib/ui_shell_config.server.ts +73 -0
- package/cli-src/lib/ui_sizes_config.server.ts +37 -0
- package/cli-src/lib/user_fields_config.server.ts +31 -0
- package/cli-src/lib/user_management_config.server.ts +39 -0
- package/cli-src/lib/user_profiles_config.server.ts +55 -0
- package/cli-src/lib/utils/api_route_helpers.ts +60 -0
- package/cli-src/lib/utils/error_sanitizer.ts +75 -0
- package/cli-src/lib/utils/password_validator.ts +65 -0
- package/cli-src/lib/utils.ts +11 -0
- package/cli-src/server/logging/logger_service.ts +56 -0
- package/dist/cli/index.js +18 -0
- package/dist/cli/init_users.d.ts +17 -0
- package/dist/cli/init_users.d.ts.map +1 -0
- package/dist/cli/init_users.js +307 -0
- package/dist/components/layouts/shared/config/layout_customization.d.ts +2 -7
- package/dist/components/layouts/shared/config/layout_customization.d.ts.map +1 -1
- package/dist/lib/utils/password_validator.d.ts +7 -1
- package/dist/lib/utils/password_validator.d.ts.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// file_description: CLI entry wrapper that handles ESM module resolution
|
|
3
|
+
// This wrapper ensures the CLI works in consuming projects with proper module resolution
|
|
4
|
+
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { dirname, join } from 'path';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = dirname(__filename);
|
|
11
|
+
|
|
12
|
+
// Get the path to the CLI TypeScript source file (included in the package)
|
|
13
|
+
// Structure: cli-src/cli/index.ts and cli-src/lib/* for relative imports
|
|
14
|
+
const cliPath = join(__dirname, '..', 'cli-src', 'cli', 'index.ts');
|
|
15
|
+
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
|
|
18
|
+
// Use tsx to run the TypeScript source directly
|
|
19
|
+
// This avoids ESM module resolution issues with compiled JS
|
|
20
|
+
// tsx is a dependency of hazo_auth so it should be available
|
|
21
|
+
const child = spawn('npx', ['tsx', cliPath, ...args], {
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
cwd: process.cwd(),
|
|
24
|
+
shell: true
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
child.on('exit', (code) => {
|
|
28
|
+
process.exit(code ?? 0);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
child.on('error', (err) => {
|
|
32
|
+
console.error('Failed to start CLI:', err.message);
|
|
33
|
+
console.error('Make sure tsx is available: npm install -D tsx');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
// file_description: route and page generation logic for hazo_auth
|
|
2
|
+
// This module creates API route files and page files in consuming projects
|
|
3
|
+
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
|
|
7
|
+
// section: types
|
|
8
|
+
type RouteDefinition = {
|
|
9
|
+
name: string;
|
|
10
|
+
path: string;
|
|
11
|
+
method: string;
|
|
12
|
+
export_name: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type PageDefinition = {
|
|
16
|
+
name: string;
|
|
17
|
+
path: string;
|
|
18
|
+
component_name: string;
|
|
19
|
+
import_path: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type GenerateOptions = {
|
|
23
|
+
dir?: string;
|
|
24
|
+
pages?: boolean;
|
|
25
|
+
all?: boolean;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// section: constants
|
|
29
|
+
const ROUTES: RouteDefinition[] = [
|
|
30
|
+
{ name: "login", path: "api/hazo_auth/login", method: "POST", export_name: "loginPOST" },
|
|
31
|
+
{ name: "register", path: "api/hazo_auth/register", method: "POST", export_name: "registerPOST" },
|
|
32
|
+
{ name: "logout", path: "api/hazo_auth/logout", method: "POST", export_name: "logoutPOST" },
|
|
33
|
+
{ name: "me", path: "api/hazo_auth/me", method: "GET", export_name: "meGET" },
|
|
34
|
+
{ name: "forgot_password", path: "api/hazo_auth/forgot_password", method: "POST", export_name: "forgotPasswordPOST" },
|
|
35
|
+
{ name: "reset_password", path: "api/hazo_auth/reset_password", method: "POST", export_name: "resetPasswordPOST" },
|
|
36
|
+
{ name: "verify_email", path: "api/hazo_auth/verify_email", method: "GET", export_name: "verifyEmailGET" },
|
|
37
|
+
{ name: "resend_verification", path: "api/hazo_auth/resend_verification", method: "POST", export_name: "resendVerificationPOST" },
|
|
38
|
+
{ name: "update_user", path: "api/hazo_auth/update_user", method: "PATCH", export_name: "updateUserPATCH" },
|
|
39
|
+
{ name: "change_password", path: "api/hazo_auth/change_password", method: "POST", export_name: "changePasswordPOST" },
|
|
40
|
+
{ name: "upload_profile_picture", path: "api/hazo_auth/upload_profile_picture", method: "POST", export_name: "uploadProfilePicturePOST" },
|
|
41
|
+
{ name: "remove_profile_picture", path: "api/hazo_auth/remove_profile_picture", method: "DELETE", export_name: "removeProfilePictureDELETE" },
|
|
42
|
+
{ name: "library_photos", path: "api/hazo_auth/library_photos", method: "GET", export_name: "libraryPhotosGET" },
|
|
43
|
+
{ name: "library_photo", path: "api/hazo_auth/library_photo/[category]/[filename]", method: "GET", export_name: "libraryPhotoGET" },
|
|
44
|
+
{ name: "get_auth", path: "api/hazo_auth/get_auth", method: "POST", export_name: "getAuthPOST" },
|
|
45
|
+
{ name: "validate_reset_token", path: "api/hazo_auth/validate_reset_token", method: "GET", export_name: "validateResetTokenGET" },
|
|
46
|
+
{ name: "profile_picture_filename", path: "api/hazo_auth/profile_picture/[filename]", method: "GET", export_name: "profilePictureFilenameGET" },
|
|
47
|
+
{ name: "invalidate_cache", path: "api/hazo_auth/invalidate_cache", method: "POST", export_name: "invalidateCachePOST" },
|
|
48
|
+
// User management routes
|
|
49
|
+
{ name: "user_management_users", path: "api/hazo_auth/user_management/users", method: "GET", export_name: "userManagementUsersGET" },
|
|
50
|
+
{ name: "user_management_users_patch", path: "api/hazo_auth/user_management/users", method: "PATCH", export_name: "userManagementUsersPATCH" },
|
|
51
|
+
{ name: "user_management_users_post", path: "api/hazo_auth/user_management/users", method: "POST", export_name: "userManagementUsersPOST" },
|
|
52
|
+
{ name: "user_management_permissions", path: "api/hazo_auth/user_management/permissions", method: "GET", export_name: "userManagementPermissionsGET" },
|
|
53
|
+
{ name: "user_management_permissions_post", path: "api/hazo_auth/user_management/permissions", method: "POST", export_name: "userManagementPermissionsPOST" },
|
|
54
|
+
{ name: "user_management_permissions_put", path: "api/hazo_auth/user_management/permissions", method: "PUT", export_name: "userManagementPermissionsPUT" },
|
|
55
|
+
{ name: "user_management_permissions_delete", path: "api/hazo_auth/user_management/permissions", method: "DELETE", export_name: "userManagementPermissionsDELETE" },
|
|
56
|
+
{ name: "user_management_roles", path: "api/hazo_auth/user_management/roles", method: "GET", export_name: "userManagementRolesGET" },
|
|
57
|
+
{ name: "user_management_roles_post", path: "api/hazo_auth/user_management/roles", method: "POST", export_name: "userManagementRolesPOST" },
|
|
58
|
+
{ name: "user_management_roles_put", path: "api/hazo_auth/user_management/roles", method: "PUT", export_name: "userManagementRolesPUT" },
|
|
59
|
+
{ name: "user_management_users_roles", path: "api/hazo_auth/user_management/users/roles", method: "GET", export_name: "userManagementUsersRolesGET" },
|
|
60
|
+
{ name: "user_management_users_roles_post", path: "api/hazo_auth/user_management/users/roles", method: "POST", export_name: "userManagementUsersRolesPOST" },
|
|
61
|
+
{ name: "user_management_users_roles_put", path: "api/hazo_auth/user_management/users/roles", method: "PUT", export_name: "userManagementUsersRolesPUT" },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const PAGES: PageDefinition[] = [
|
|
65
|
+
{ name: "login", path: "hazo_auth/login", component_name: "LoginPage", import_path: "hazo_auth/pages/login" },
|
|
66
|
+
{ name: "register", path: "hazo_auth/register", component_name: "RegisterPage", import_path: "hazo_auth/pages/register" },
|
|
67
|
+
{ name: "forgot_password", path: "hazo_auth/forgot_password", component_name: "ForgotPasswordPage", import_path: "hazo_auth/pages/forgot_password" },
|
|
68
|
+
{ name: "reset_password", path: "hazo_auth/reset_password", component_name: "ResetPasswordPage", import_path: "hazo_auth/pages/reset_password" },
|
|
69
|
+
{ name: "verify_email", path: "hazo_auth/verify_email", component_name: "VerifyEmailPage", import_path: "hazo_auth/pages/verify_email" },
|
|
70
|
+
{ name: "my_settings", path: "hazo_auth/my_settings", component_name: "MySettingsPage", import_path: "hazo_auth/pages/my_settings" },
|
|
71
|
+
];
|
|
72
|
+
// Note: Using barrel export "hazo_auth/pages" which maps to dist/server_pages/index.js in package.json exports
|
|
73
|
+
|
|
74
|
+
// section: helpers
|
|
75
|
+
function get_project_root(): string {
|
|
76
|
+
return process.cwd();
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function find_app_dir(project_root: string): string | null {
|
|
80
|
+
const possible_dirs = [
|
|
81
|
+
path.join(project_root, "app"),
|
|
82
|
+
path.join(project_root, "src", "app"),
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
for (const dir of possible_dirs) {
|
|
86
|
+
if (fs.existsSync(dir)) {
|
|
87
|
+
return dir;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function ensure_dir(dir_path: string): void {
|
|
95
|
+
if (!fs.existsSync(dir_path)) {
|
|
96
|
+
fs.mkdirSync(dir_path, { recursive: true });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function file_exists(filepath: string): boolean {
|
|
101
|
+
return fs.existsSync(filepath);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function generate_route_content(route: RouteDefinition): string {
|
|
105
|
+
return `// Generated by hazo_auth - do not edit manually
|
|
106
|
+
// Route: /${route.path}
|
|
107
|
+
// Method: ${route.method}
|
|
108
|
+
export { ${route.export_name} as ${route.method} } from "hazo_auth/server/routes";
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function generate_route_content_multi(routes: RouteDefinition[]): string {
|
|
113
|
+
const path = routes[0].path;
|
|
114
|
+
const exports = routes.map(r => `export { ${r.export_name} as ${r.method} } from "hazo_auth/server/routes";`).join("\n");
|
|
115
|
+
const methods = routes.map(r => r.method).join(", ");
|
|
116
|
+
|
|
117
|
+
return `// Generated by hazo_auth - do not edit manually
|
|
118
|
+
// Route: /${path}
|
|
119
|
+
// Methods: ${methods}
|
|
120
|
+
${exports}
|
|
121
|
+
`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function generate_page_content(page: PageDefinition): string {
|
|
125
|
+
return `// Generated by hazo_auth - do not edit manually
|
|
126
|
+
// Page: /${page.path}
|
|
127
|
+
import { ${page.component_name} } from "hazo_auth/pages";
|
|
128
|
+
|
|
129
|
+
export default ${page.component_name};
|
|
130
|
+
`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// section: api_route_generation
|
|
134
|
+
function generate_api_routes(app_dir: string, project_root: string): { created: number; skipped: number; errors: number } {
|
|
135
|
+
let created = 0;
|
|
136
|
+
let skipped = 0;
|
|
137
|
+
let errors = 0;
|
|
138
|
+
|
|
139
|
+
console.log("\x1b[1m📡 Generating API routes...\x1b[0m\n");
|
|
140
|
+
|
|
141
|
+
// Group routes by path to handle multiple methods per path
|
|
142
|
+
const routes_by_path = new Map<string, RouteDefinition[]>();
|
|
143
|
+
for (const route of ROUTES) {
|
|
144
|
+
const existing = routes_by_path.get(route.path) || [];
|
|
145
|
+
existing.push(route);
|
|
146
|
+
routes_by_path.set(route.path, existing);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
for (const [route_path, routes_for_path] of routes_by_path) {
|
|
150
|
+
const route_dir = path.join(app_dir, route_path);
|
|
151
|
+
const route_file = path.join(route_dir, "route.ts");
|
|
152
|
+
|
|
153
|
+
if (file_exists(route_file)) {
|
|
154
|
+
console.log(`\x1b[33m[SKIP]\x1b[0m ${route_path}/route.ts (already exists)`);
|
|
155
|
+
skipped++;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
try {
|
|
160
|
+
ensure_dir(route_dir);
|
|
161
|
+
|
|
162
|
+
// Generate content with all methods for this path
|
|
163
|
+
const content = generate_route_content_multi(routes_for_path);
|
|
164
|
+
fs.writeFileSync(route_file, content, "utf-8");
|
|
165
|
+
|
|
166
|
+
const methods = routes_for_path.map(r => r.method).join(", ");
|
|
167
|
+
console.log(`\x1b[32m[CREATE]\x1b[0m ${route_path}/route.ts (${methods})`);
|
|
168
|
+
created++;
|
|
169
|
+
} catch (err) {
|
|
170
|
+
console.log(`\x1b[31m[ERROR]\x1b[0m ${route_path}/route.ts - ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
171
|
+
errors++;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return { created, skipped, errors };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// section: page_generation
|
|
179
|
+
function generate_page_routes(app_dir: string, project_root: string): { created: number; skipped: number; errors: number } {
|
|
180
|
+
let created = 0;
|
|
181
|
+
let skipped = 0;
|
|
182
|
+
let errors = 0;
|
|
183
|
+
|
|
184
|
+
console.log("\n\x1b[1m📄 Generating page routes...\x1b[0m\n");
|
|
185
|
+
|
|
186
|
+
for (const page of PAGES) {
|
|
187
|
+
const page_dir = path.join(app_dir, page.path);
|
|
188
|
+
const page_file = path.join(page_dir, "page.tsx");
|
|
189
|
+
|
|
190
|
+
if (file_exists(page_file)) {
|
|
191
|
+
console.log(`\x1b[33m[SKIP]\x1b[0m ${page.path}/page.tsx (already exists)`);
|
|
192
|
+
skipped++;
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
ensure_dir(page_dir);
|
|
198
|
+
|
|
199
|
+
const content = generate_page_content(page);
|
|
200
|
+
fs.writeFileSync(page_file, content, "utf-8");
|
|
201
|
+
|
|
202
|
+
console.log(`\x1b[32m[CREATE]\x1b[0m ${page.path}/page.tsx`);
|
|
203
|
+
created++;
|
|
204
|
+
} catch (err) {
|
|
205
|
+
console.log(`\x1b[31m[ERROR]\x1b[0m ${page.path}/page.tsx - ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
206
|
+
errors++;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return { created, skipped, errors };
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// section: main
|
|
214
|
+
export function generate_routes(options: GenerateOptions = {}): void {
|
|
215
|
+
const { dir, pages = false, all = false } = options;
|
|
216
|
+
const project_root = get_project_root();
|
|
217
|
+
const include_pages = pages || all;
|
|
218
|
+
|
|
219
|
+
console.log("\n\x1b[1m🐸 hazo_auth Route Generator\x1b[0m");
|
|
220
|
+
console.log("=".repeat(50));
|
|
221
|
+
console.log(`Project root: ${project_root}`);
|
|
222
|
+
console.log(`Mode: ${include_pages ? "API routes + Pages" : "API routes only"}\n`);
|
|
223
|
+
|
|
224
|
+
const app_dir = dir
|
|
225
|
+
? path.join(project_root, dir)
|
|
226
|
+
: find_app_dir(project_root);
|
|
227
|
+
|
|
228
|
+
if (!app_dir) {
|
|
229
|
+
console.error("\x1b[31mError: Could not find app directory.\x1b[0m");
|
|
230
|
+
console.log("Try specifying it with: npx hazo_auth generate-routes --dir=src/app");
|
|
231
|
+
process.exit(1);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (!fs.existsSync(app_dir)) {
|
|
235
|
+
console.error(`\x1b[31mError: App directory not found: ${app_dir}\x1b[0m`);
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
console.log(`App directory: ${app_dir.replace(project_root, ".")}\n`);
|
|
240
|
+
|
|
241
|
+
// Generate API routes
|
|
242
|
+
const api_result = generate_api_routes(app_dir, project_root);
|
|
243
|
+
|
|
244
|
+
// Generate pages if requested
|
|
245
|
+
let page_result = { created: 0, skipped: 0, errors: 0 };
|
|
246
|
+
if (include_pages) {
|
|
247
|
+
page_result = generate_page_routes(app_dir, project_root);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Summary
|
|
251
|
+
const total_created = api_result.created + page_result.created;
|
|
252
|
+
const total_skipped = api_result.skipped + page_result.skipped;
|
|
253
|
+
const total_errors = api_result.errors + page_result.errors;
|
|
254
|
+
|
|
255
|
+
console.log("\n" + "=".repeat(50));
|
|
256
|
+
console.log("\x1b[1mSummary:\x1b[0m");
|
|
257
|
+
console.log(` \x1b[32m✓ Created: ${total_created}\x1b[0m (${api_result.created} routes, ${page_result.created} pages)`);
|
|
258
|
+
console.log(` \x1b[33m⊘ Skipped: ${total_skipped}\x1b[0m`);
|
|
259
|
+
if (total_errors > 0) {
|
|
260
|
+
console.log(` \x1b[31m✗ Errors: ${total_errors}\x1b[0m`);
|
|
261
|
+
}
|
|
262
|
+
console.log();
|
|
263
|
+
|
|
264
|
+
if (total_created > 0) {
|
|
265
|
+
console.log("\x1b[32m🦊 Generation complete!\x1b[0m");
|
|
266
|
+
console.log("\nNext steps:");
|
|
267
|
+
console.log(" 1. Run `npm run dev` to start your development server");
|
|
268
|
+
console.log(" 2. Test API: `curl http://localhost:3000/api/hazo_auth/me`");
|
|
269
|
+
if (include_pages) {
|
|
270
|
+
console.log(" 3. Visit http://localhost:3000/hazo_auth/login to test pages");
|
|
271
|
+
}
|
|
272
|
+
console.log();
|
|
273
|
+
} else if (total_skipped === ROUTES.length + (include_pages ? PAGES.length : 0)) {
|
|
274
|
+
console.log("\x1b[33m🦊 All files already exist. No changes made.\x1b[0m\n");
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// file_description: main CLI entry point for hazo_auth commands
|
|
3
|
+
// This file is the bin entry for the hazo_auth package
|
|
4
|
+
|
|
5
|
+
// section: imports
|
|
6
|
+
import { run_validation } from "./validate.js";
|
|
7
|
+
import { generate_routes, type GenerateOptions } from "./generate.js";
|
|
8
|
+
import { handle_init } from "./init.js";
|
|
9
|
+
import { handle_init_users, show_init_users_help } from "./init_users.js";
|
|
10
|
+
|
|
11
|
+
// section: constants
|
|
12
|
+
const VERSION = "1.6.0";
|
|
13
|
+
|
|
14
|
+
const HELP_TEXT = `
|
|
15
|
+
\x1b[1m🐸 hazo_auth CLI v${VERSION}\x1b[0m
|
|
16
|
+
|
|
17
|
+
Usage: hazo_auth <command> [options]
|
|
18
|
+
|
|
19
|
+
Commands:
|
|
20
|
+
init Initialize hazo_auth in your project (creates directories, copies config)
|
|
21
|
+
init-users Initialize permissions, roles, and super user from config
|
|
22
|
+
validate Check your hazo_auth setup and configuration
|
|
23
|
+
generate-routes Generate API route files and pages in your project
|
|
24
|
+
|
|
25
|
+
Options:
|
|
26
|
+
--help, -h Show this help message
|
|
27
|
+
--version, -v Show version number
|
|
28
|
+
|
|
29
|
+
Examples:
|
|
30
|
+
npx hazo_auth init
|
|
31
|
+
npx hazo_auth init-users
|
|
32
|
+
npx hazo_auth validate
|
|
33
|
+
npx hazo_auth generate-routes
|
|
34
|
+
npx hazo_auth generate-routes --pages
|
|
35
|
+
npx hazo_auth generate-routes --all --dir=src/app
|
|
36
|
+
|
|
37
|
+
Documentation:
|
|
38
|
+
https://github.com/your-repo/hazo_auth/blob/main/SETUP_CHECKLIST.md
|
|
39
|
+
|
|
40
|
+
🦊
|
|
41
|
+
`;
|
|
42
|
+
|
|
43
|
+
// section: helpers
|
|
44
|
+
function parse_args(): { command?: string; args: string[]; help?: boolean; version?: boolean } {
|
|
45
|
+
const argv = process.argv.slice(2);
|
|
46
|
+
const result: { command?: string; args: string[]; help?: boolean; version?: boolean } = { args: [] };
|
|
47
|
+
|
|
48
|
+
for (const arg of argv) {
|
|
49
|
+
if (arg === "--help" || arg === "-h") {
|
|
50
|
+
result.help = true;
|
|
51
|
+
} else if (arg === "--version" || arg === "-v") {
|
|
52
|
+
result.version = true;
|
|
53
|
+
} else if (!arg.startsWith("-") && !result.command) {
|
|
54
|
+
result.command = arg;
|
|
55
|
+
} else {
|
|
56
|
+
result.args.push(arg);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return result;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function show_help(): void {
|
|
64
|
+
console.log(HELP_TEXT);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function show_version(): void {
|
|
68
|
+
console.log(`hazo_auth v${VERSION}`);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// section: command_handlers
|
|
72
|
+
async function handle_validate(): Promise<void> {
|
|
73
|
+
const summary = run_validation();
|
|
74
|
+
process.exit(summary.failed > 0 ? 1 : 0);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function handle_generate_routes(args: string[]): void {
|
|
78
|
+
const options: GenerateOptions = {};
|
|
79
|
+
|
|
80
|
+
for (const arg of args) {
|
|
81
|
+
if (arg.startsWith("--dir=")) {
|
|
82
|
+
options.dir = arg.replace("--dir=", "");
|
|
83
|
+
} else if (arg === "--pages") {
|
|
84
|
+
options.pages = true;
|
|
85
|
+
} else if (arg === "--all") {
|
|
86
|
+
options.all = true;
|
|
87
|
+
} else if (arg === "--help" || arg === "-h") {
|
|
88
|
+
console.log(`
|
|
89
|
+
hazo_auth generate-routes
|
|
90
|
+
|
|
91
|
+
Generate API route files and page files in your Next.js project.
|
|
92
|
+
|
|
93
|
+
Usage:
|
|
94
|
+
hazo_auth generate-routes [options]
|
|
95
|
+
|
|
96
|
+
Options:
|
|
97
|
+
--dir=<path> Specify the app directory (default: auto-detect)
|
|
98
|
+
--pages Generate page routes in addition to API routes
|
|
99
|
+
--all Generate everything (API routes + pages)
|
|
100
|
+
--help, -h Show this help message
|
|
101
|
+
|
|
102
|
+
Examples:
|
|
103
|
+
hazo_auth generate-routes # API routes only
|
|
104
|
+
hazo_auth generate-routes --pages # API routes + pages
|
|
105
|
+
hazo_auth generate-routes --all # Same as --pages
|
|
106
|
+
hazo_auth generate-routes --dir=src/app # Specify app directory
|
|
107
|
+
`);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
generate_routes(options);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// section: main
|
|
116
|
+
async function main(): Promise<void> {
|
|
117
|
+
const { command, args, help, version } = parse_args();
|
|
118
|
+
|
|
119
|
+
if (version) {
|
|
120
|
+
show_version();
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Show main help only if no command specified
|
|
125
|
+
if (!command) {
|
|
126
|
+
show_help();
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// If help is requested but command exists, pass help to command handler
|
|
131
|
+
// Commands can show their own help
|
|
132
|
+
if (help) {
|
|
133
|
+
args.push("--help");
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
switch (command) {
|
|
137
|
+
case "init":
|
|
138
|
+
if (help) {
|
|
139
|
+
console.log(`
|
|
140
|
+
hazo_auth init
|
|
141
|
+
|
|
142
|
+
Initialize hazo_auth in your project.
|
|
143
|
+
|
|
144
|
+
Actions:
|
|
145
|
+
- Creates public/profile_pictures/library/ directory
|
|
146
|
+
- Creates public/profile_pictures/uploads/ directory
|
|
147
|
+
- Creates data/ directory (for SQLite)
|
|
148
|
+
- Copies hazo_auth_config.ini and hazo_notify_config.ini
|
|
149
|
+
- Copies profile picture library images
|
|
150
|
+
- Creates .env.local.example template
|
|
151
|
+
`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
handle_init();
|
|
155
|
+
break;
|
|
156
|
+
|
|
157
|
+
case "init-users": {
|
|
158
|
+
if (help) {
|
|
159
|
+
show_init_users_help();
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Parse --email option
|
|
163
|
+
let email: string | undefined;
|
|
164
|
+
for (const arg of args) {
|
|
165
|
+
if (arg.startsWith("--email=")) {
|
|
166
|
+
email = arg.replace("--email=", "");
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
await handle_init_users({ email });
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
case "validate":
|
|
174
|
+
if (help) {
|
|
175
|
+
console.log(`
|
|
176
|
+
hazo_auth validate
|
|
177
|
+
|
|
178
|
+
Check your hazo_auth setup and configuration.
|
|
179
|
+
|
|
180
|
+
This command verifies:
|
|
181
|
+
- Config files exist and are readable
|
|
182
|
+
- Required config values are set
|
|
183
|
+
- Environment variables are configured
|
|
184
|
+
- Database connection works
|
|
185
|
+
- Required directories exist
|
|
186
|
+
`);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
await handle_validate();
|
|
190
|
+
break;
|
|
191
|
+
|
|
192
|
+
case "generate-routes":
|
|
193
|
+
handle_generate_routes(args);
|
|
194
|
+
break;
|
|
195
|
+
|
|
196
|
+
default:
|
|
197
|
+
console.error(`\x1b[31mUnknown command: ${command}\x1b[0m\n`);
|
|
198
|
+
console.log("Run 'hazo_auth --help' for usage information.");
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Run main
|
|
204
|
+
main().catch((error) => {
|
|
205
|
+
console.error("\x1b[31mError:\x1b[0m", error.message);
|
|
206
|
+
process.exit(1);
|
|
207
|
+
});
|