hazo_auth 1.6.0 → 1.6.2
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/README.md +191 -19
- package/SETUP_CHECKLIST.md +190 -65
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts +9 -0
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.d.ts.map +1 -0
- package/dist/app/api/hazo_auth/library_photo/[category]/[filename]/route.js +82 -0
- package/dist/app/api/hazo_auth/library_photos/route.d.ts +9 -0
- package/dist/app/api/hazo_auth/library_photos/route.d.ts.map +1 -1
- package/dist/app/api/hazo_auth/library_photos/route.js +31 -6
- package/dist/cli/generate.d.ts +6 -1
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +101 -34
- package/dist/cli/index.js +64 -11
- package/dist/cli/init.d.ts +2 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +206 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +25 -0
- package/dist/components/layouts/email_verification/index.d.ts +2 -1
- package/dist/components/layouts/email_verification/index.d.ts.map +1 -1
- package/dist/components/layouts/email_verification/index.js +3 -2
- package/dist/components/layouts/forgot_password/index.d.ts +3 -1
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
- package/dist/components/layouts/forgot_password/index.js +3 -2
- package/dist/components/layouts/my_settings/components/editable_field.js +1 -1
- package/dist/components/layouts/my_settings/components/password_change_dialog.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_display.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_gravatar_tab.js +1 -1
- package/dist/components/layouts/my_settings/components/profile_picture_library_tab.js +4 -4
- package/dist/components/layouts/my_settings/components/profile_picture_upload_tab.js +4 -4
- package/dist/components/layouts/my_settings/index.js +1 -1
- package/dist/components/layouts/shared/components/profile_pic_menu.js +2 -2
- package/dist/lib/auth_utility_config.server.js +2 -2
- package/dist/lib/services/profile_picture_service.d.ts +34 -2
- package/dist/lib/services/profile_picture_service.d.ts.map +1 -1
- package/dist/lib/services/profile_picture_service.js +157 -15
- package/dist/lib/services/user_profiles_cache.d.ts +76 -0
- package/dist/lib/services/user_profiles_cache.d.ts.map +1 -0
- package/dist/lib/services/user_profiles_cache.js +141 -0
- package/dist/lib/services/user_profiles_service.d.ts +17 -0
- package/dist/lib/services/user_profiles_service.d.ts.map +1 -1
- package/dist/lib/services/user_profiles_service.js +136 -44
- package/dist/lib/user_profiles_config.server.d.ts +15 -0
- package/dist/lib/user_profiles_config.server.d.ts.map +1 -0
- package/dist/lib/user_profiles_config.server.js +23 -0
- package/dist/page_components/forgot_password.d.ts +19 -0
- package/dist/page_components/forgot_password.d.ts.map +1 -0
- package/dist/page_components/forgot_password.js +36 -0
- package/dist/page_components/index.d.ts +7 -0
- package/dist/page_components/index.d.ts.map +1 -0
- package/dist/page_components/index.js +9 -0
- package/dist/page_components/login.d.ts +26 -0
- package/dist/page_components/login.d.ts.map +1 -0
- package/dist/page_components/login.js +40 -0
- package/dist/page_components/my_settings.d.ts +64 -0
- package/dist/page_components/my_settings.d.ts.map +1 -0
- package/dist/page_components/my_settings.js +67 -0
- package/dist/page_components/register.d.ts +25 -0
- package/dist/page_components/register.d.ts.map +1 -0
- package/dist/page_components/register.js +43 -0
- package/dist/page_components/reset_password.d.ts +25 -0
- package/dist/page_components/reset_password.d.ts.map +1 -0
- package/dist/page_components/reset_password.js +43 -0
- package/dist/page_components/verify_email.d.ts +21 -0
- package/dist/page_components/verify_email.d.ts.map +1 -0
- package/dist/page_components/verify_email.js +36 -0
- package/dist/server/routes/index.d.ts +1 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +1 -0
- package/dist/server/routes/library_photo.d.ts +2 -0
- package/dist/server/routes/library_photo.d.ts.map +1 -0
- package/dist/server/routes/library_photo.js +3 -0
- package/hazo_auth_config.example.ini +25 -5
- package/package.json +33 -1
|
@@ -4,9 +4,18 @@ export declare function GET(request: NextRequest): Promise<NextResponse<{
|
|
|
4
4
|
success: boolean;
|
|
5
5
|
category: string;
|
|
6
6
|
photos: string[];
|
|
7
|
+
pagination: {
|
|
8
|
+
page: number;
|
|
9
|
+
page_size: number;
|
|
10
|
+
total: number;
|
|
11
|
+
has_more: boolean;
|
|
12
|
+
total_pages: number;
|
|
13
|
+
};
|
|
14
|
+
source: "project" | "node_modules";
|
|
7
15
|
}> | NextResponse<{
|
|
8
16
|
success: boolean;
|
|
9
17
|
categories: string[];
|
|
18
|
+
source: "project" | "node_modules" | null;
|
|
10
19
|
}> | NextResponse<{
|
|
11
20
|
error: string;
|
|
12
21
|
}>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/app/api/hazo_auth/library_photos/route.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/app/api/hazo_auth/library_photos/route.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAUxD,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAOvC,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW;;;;;;;;;;;;;;;;;;IAmF7C"}
|
|
@@ -1,43 +1,68 @@
|
|
|
1
|
-
// file_description: API route for listing library photo categories and photos in categories
|
|
1
|
+
// file_description: API route for listing library photo categories and photos in categories with pagination support
|
|
2
2
|
// section: imports
|
|
3
3
|
import { NextResponse } from "next/server";
|
|
4
|
-
import { get_library_categories,
|
|
4
|
+
import { get_library_categories, get_library_photos_paginated, get_library_source } from "../../../../lib/services/profile_picture_service";
|
|
5
5
|
import { create_app_logger } from "../../../../lib/app_logger";
|
|
6
6
|
import { get_filename, get_line_number } from "../../../../lib/utils/api_route_helpers";
|
|
7
7
|
// section: route_config
|
|
8
8
|
export const dynamic = 'force-dynamic';
|
|
9
|
+
// section: constants
|
|
10
|
+
const DEFAULT_PAGE_SIZE = 20;
|
|
11
|
+
const MAX_PAGE_SIZE = 100;
|
|
9
12
|
// section: api_handler
|
|
10
13
|
export async function GET(request) {
|
|
11
14
|
const logger = create_app_logger();
|
|
12
15
|
try {
|
|
13
16
|
const { searchParams } = new URL(request.url);
|
|
14
17
|
const category = searchParams.get("category");
|
|
18
|
+
const page_param = searchParams.get("page");
|
|
19
|
+
const page_size_param = searchParams.get("page_size");
|
|
20
|
+
// Parse pagination parameters
|
|
21
|
+
const page = page_param ? Math.max(1, parseInt(page_param, 10) || 1) : 1;
|
|
22
|
+
const page_size = page_size_param
|
|
23
|
+
? Math.min(MAX_PAGE_SIZE, Math.max(1, parseInt(page_size_param, 10) || DEFAULT_PAGE_SIZE))
|
|
24
|
+
: DEFAULT_PAGE_SIZE;
|
|
15
25
|
if (category) {
|
|
16
|
-
// Return photos in the specified category
|
|
17
|
-
const
|
|
26
|
+
// Return photos in the specified category with pagination
|
|
27
|
+
const result = get_library_photos_paginated(category, page, page_size);
|
|
18
28
|
logger.info("library_photos_category_requested", {
|
|
19
29
|
filename: get_filename(),
|
|
20
30
|
line_number: get_line_number(),
|
|
21
31
|
category,
|
|
22
|
-
|
|
32
|
+
page,
|
|
33
|
+
page_size,
|
|
34
|
+
total: result.total,
|
|
35
|
+
returned: result.photos.length,
|
|
36
|
+
source: result.source,
|
|
23
37
|
});
|
|
24
38
|
return NextResponse.json({
|
|
25
39
|
success: true,
|
|
26
40
|
category,
|
|
27
|
-
photos,
|
|
41
|
+
photos: result.photos,
|
|
42
|
+
pagination: {
|
|
43
|
+
page: result.page,
|
|
44
|
+
page_size: result.page_size,
|
|
45
|
+
total: result.total,
|
|
46
|
+
has_more: result.has_more,
|
|
47
|
+
total_pages: Math.ceil(result.total / result.page_size),
|
|
48
|
+
},
|
|
49
|
+
source: result.source,
|
|
28
50
|
}, { status: 200 });
|
|
29
51
|
}
|
|
30
52
|
else {
|
|
31
53
|
// Return list of categories
|
|
32
54
|
const categories = get_library_categories();
|
|
55
|
+
const source = get_library_source();
|
|
33
56
|
logger.info("library_categories_requested", {
|
|
34
57
|
filename: get_filename(),
|
|
35
58
|
line_number: get_line_number(),
|
|
36
59
|
categoryCount: categories.length,
|
|
60
|
+
source,
|
|
37
61
|
});
|
|
38
62
|
return NextResponse.json({
|
|
39
63
|
success: true,
|
|
40
64
|
categories,
|
|
65
|
+
source,
|
|
41
66
|
}, { status: 200 });
|
|
42
67
|
}
|
|
43
68
|
}
|
package/dist/cli/generate.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export
|
|
1
|
+
export type GenerateOptions = {
|
|
2
|
+
dir?: string;
|
|
3
|
+
pages?: boolean;
|
|
4
|
+
all?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export declare function generate_routes(options?: GenerateOptions): void;
|
|
2
7
|
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/cli/generate.ts"],"names":[],"mappings":"AAqBA,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAwJF,wBAAgB,eAAe,CAAC,OAAO,GAAE,eAAoB,GAAG,IAAI,CA8DnE"}
|
package/dist/cli/generate.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// file_description: route generation logic for hazo_auth
|
|
2
|
-
// This module creates API route files in consuming projects
|
|
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
3
|
import * as fs from "fs";
|
|
4
4
|
import * as path from "path";
|
|
5
5
|
// section: constants
|
|
@@ -17,11 +17,21 @@ const ROUTES = [
|
|
|
17
17
|
{ name: "upload_profile_picture", path: "api/hazo_auth/upload_profile_picture", method: "POST", export_name: "uploadProfilePicturePOST" },
|
|
18
18
|
{ name: "remove_profile_picture", path: "api/hazo_auth/remove_profile_picture", method: "DELETE", export_name: "removeProfilePictureDELETE" },
|
|
19
19
|
{ name: "library_photos", path: "api/hazo_auth/library_photos", method: "GET", export_name: "libraryPhotosGET" },
|
|
20
|
+
{ name: "library_photo", path: "api/hazo_auth/library_photo/[category]/[filename]", method: "GET", export_name: "libraryPhotoGET" },
|
|
20
21
|
{ name: "get_auth", path: "api/hazo_auth/get_auth", method: "POST", export_name: "getAuthPOST" },
|
|
21
22
|
{ name: "validate_reset_token", path: "api/hazo_auth/validate_reset_token", method: "GET", export_name: "validateResetTokenGET" },
|
|
22
23
|
{ name: "profile_picture_filename", path: "api/hazo_auth/profile_picture/[filename]", method: "GET", export_name: "profilePictureFilenameGET" },
|
|
23
24
|
{ name: "invalidate_cache", path: "api/hazo_auth/invalidate_cache", method: "POST", export_name: "invalidateCachePOST" },
|
|
24
25
|
];
|
|
26
|
+
const PAGES = [
|
|
27
|
+
{ name: "login", path: "hazo_auth/login", component_name: "LoginPage", import_path: "hazo_auth/pages/login" },
|
|
28
|
+
{ name: "register", path: "hazo_auth/register", component_name: "RegisterPage", import_path: "hazo_auth/pages/register" },
|
|
29
|
+
{ name: "forgot_password", path: "hazo_auth/forgot_password", component_name: "ForgotPasswordPage", import_path: "hazo_auth/pages/forgot_password" },
|
|
30
|
+
{ name: "reset_password", path: "hazo_auth/reset_password", component_name: "ResetPasswordPage", import_path: "hazo_auth/pages/reset_password" },
|
|
31
|
+
{ name: "verify_email", path: "hazo_auth/verify_email", component_name: "VerifyEmailPage", import_path: "hazo_auth/pages/verify_email" },
|
|
32
|
+
{ name: "my_settings", path: "hazo_auth/my_settings", component_name: "MySettingsPage", import_path: "hazo_auth/pages/my_settings" },
|
|
33
|
+
];
|
|
34
|
+
// Note: The import_path uses "hazo_auth/pages/*" which maps to dist/page_components/* in package.json exports
|
|
25
35
|
// section: helpers
|
|
26
36
|
function get_project_root() {
|
|
27
37
|
return process.cwd();
|
|
@@ -43,6 +53,9 @@ function ensure_dir(dir_path) {
|
|
|
43
53
|
fs.mkdirSync(dir_path, { recursive: true });
|
|
44
54
|
}
|
|
45
55
|
}
|
|
56
|
+
function file_exists(filepath) {
|
|
57
|
+
return fs.existsSync(filepath);
|
|
58
|
+
}
|
|
46
59
|
function generate_route_content(route) {
|
|
47
60
|
return `// Generated by hazo_auth - do not edit manually
|
|
48
61
|
// Route: /${route.path}
|
|
@@ -50,32 +63,20 @@ function generate_route_content(route) {
|
|
|
50
63
|
export { ${route.export_name} as ${route.method} } from "hazo_auth/server/routes";
|
|
51
64
|
`;
|
|
52
65
|
}
|
|
53
|
-
function
|
|
54
|
-
return
|
|
66
|
+
function generate_page_content(page) {
|
|
67
|
+
return `// Generated by hazo_auth - do not edit manually
|
|
68
|
+
// Page: /${page.path}
|
|
69
|
+
import { ${page.component_name} } from "${page.import_path}";
|
|
70
|
+
|
|
71
|
+
export default ${page.component_name};
|
|
72
|
+
`;
|
|
55
73
|
}
|
|
56
|
-
// section:
|
|
57
|
-
|
|
58
|
-
const project_root = get_project_root();
|
|
59
|
-
console.log("\n\x1b[1m🐸 hazo_auth Route Generator\x1b[0m");
|
|
60
|
-
console.log("=".repeat(50));
|
|
61
|
-
console.log(`Project root: ${project_root}\n`);
|
|
62
|
-
let app_dir = custom_app_dir
|
|
63
|
-
? path.join(project_root, custom_app_dir)
|
|
64
|
-
: find_app_dir(project_root);
|
|
65
|
-
if (!app_dir) {
|
|
66
|
-
console.error("\x1b[31mError: Could not find app directory.\x1b[0m");
|
|
67
|
-
console.log("Try specifying it with: npx hazo_auth generate-routes --dir=src/app");
|
|
68
|
-
process.exit(1);
|
|
69
|
-
}
|
|
70
|
-
if (!fs.existsSync(app_dir)) {
|
|
71
|
-
console.error(`\x1b[31mError: App directory not found: ${app_dir}\x1b[0m`);
|
|
72
|
-
process.exit(1);
|
|
73
|
-
}
|
|
74
|
-
console.log(`App directory: ${app_dir.replace(project_root, ".")}\n`);
|
|
74
|
+
// section: api_route_generation
|
|
75
|
+
function generate_api_routes(app_dir, project_root) {
|
|
75
76
|
let created = 0;
|
|
76
77
|
let skipped = 0;
|
|
77
78
|
let errors = 0;
|
|
78
|
-
console.log("\x1b[
|
|
79
|
+
console.log("\x1b[1m📡 Generating API routes...\x1b[0m\n");
|
|
79
80
|
for (const route of ROUTES) {
|
|
80
81
|
const route_dir = path.join(app_dir, route.path);
|
|
81
82
|
const route_file = path.join(route_dir, "route.ts");
|
|
@@ -96,22 +97,88 @@ export function generate_routes(custom_app_dir) {
|
|
|
96
97
|
errors++;
|
|
97
98
|
}
|
|
98
99
|
}
|
|
100
|
+
return { created, skipped, errors };
|
|
101
|
+
}
|
|
102
|
+
// section: page_generation
|
|
103
|
+
function generate_page_routes(app_dir, project_root) {
|
|
104
|
+
let created = 0;
|
|
105
|
+
let skipped = 0;
|
|
106
|
+
let errors = 0;
|
|
107
|
+
console.log("\n\x1b[1m📄 Generating page routes...\x1b[0m\n");
|
|
108
|
+
for (const page of PAGES) {
|
|
109
|
+
const page_dir = path.join(app_dir, page.path);
|
|
110
|
+
const page_file = path.join(page_dir, "page.tsx");
|
|
111
|
+
if (file_exists(page_file)) {
|
|
112
|
+
console.log(`\x1b[33m[SKIP]\x1b[0m ${page.path}/page.tsx (already exists)`);
|
|
113
|
+
skipped++;
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
ensure_dir(page_dir);
|
|
118
|
+
const content = generate_page_content(page);
|
|
119
|
+
fs.writeFileSync(page_file, content, "utf-8");
|
|
120
|
+
console.log(`\x1b[32m[CREATE]\x1b[0m ${page.path}/page.tsx`);
|
|
121
|
+
created++;
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
console.log(`\x1b[31m[ERROR]\x1b[0m ${page.path}/page.tsx - ${err instanceof Error ? err.message : "Unknown error"}`);
|
|
125
|
+
errors++;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return { created, skipped, errors };
|
|
129
|
+
}
|
|
130
|
+
// section: main
|
|
131
|
+
export function generate_routes(options = {}) {
|
|
132
|
+
const { dir, pages = false, all = false } = options;
|
|
133
|
+
const project_root = get_project_root();
|
|
134
|
+
const include_pages = pages || all;
|
|
135
|
+
console.log("\n\x1b[1m🐸 hazo_auth Route Generator\x1b[0m");
|
|
136
|
+
console.log("=".repeat(50));
|
|
137
|
+
console.log(`Project root: ${project_root}`);
|
|
138
|
+
console.log(`Mode: ${include_pages ? "API routes + Pages" : "API routes only"}\n`);
|
|
139
|
+
const app_dir = dir
|
|
140
|
+
? path.join(project_root, dir)
|
|
141
|
+
: find_app_dir(project_root);
|
|
142
|
+
if (!app_dir) {
|
|
143
|
+
console.error("\x1b[31mError: Could not find app directory.\x1b[0m");
|
|
144
|
+
console.log("Try specifying it with: npx hazo_auth generate-routes --dir=src/app");
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
if (!fs.existsSync(app_dir)) {
|
|
148
|
+
console.error(`\x1b[31mError: App directory not found: ${app_dir}\x1b[0m`);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
console.log(`App directory: ${app_dir.replace(project_root, ".")}\n`);
|
|
152
|
+
// Generate API routes
|
|
153
|
+
const api_result = generate_api_routes(app_dir, project_root);
|
|
154
|
+
// Generate pages if requested
|
|
155
|
+
let page_result = { created: 0, skipped: 0, errors: 0 };
|
|
156
|
+
if (include_pages) {
|
|
157
|
+
page_result = generate_page_routes(app_dir, project_root);
|
|
158
|
+
}
|
|
159
|
+
// Summary
|
|
160
|
+
const total_created = api_result.created + page_result.created;
|
|
161
|
+
const total_skipped = api_result.skipped + page_result.skipped;
|
|
162
|
+
const total_errors = api_result.errors + page_result.errors;
|
|
99
163
|
console.log("\n" + "=".repeat(50));
|
|
100
164
|
console.log("\x1b[1mSummary:\x1b[0m");
|
|
101
|
-
console.log(` \x1b[32m✓ Created: ${
|
|
102
|
-
console.log(` \x1b[33m⊘ Skipped: ${
|
|
103
|
-
if (
|
|
104
|
-
console.log(` \x1b[31m✗ Errors: ${
|
|
165
|
+
console.log(` \x1b[32m✓ Created: ${total_created}\x1b[0m (${api_result.created} routes, ${page_result.created} pages)`);
|
|
166
|
+
console.log(` \x1b[33m⊘ Skipped: ${total_skipped}\x1b[0m`);
|
|
167
|
+
if (total_errors > 0) {
|
|
168
|
+
console.log(` \x1b[31m✗ Errors: ${total_errors}\x1b[0m`);
|
|
105
169
|
}
|
|
106
170
|
console.log();
|
|
107
|
-
if (
|
|
108
|
-
console.log("\x1b[32m🦊
|
|
171
|
+
if (total_created > 0) {
|
|
172
|
+
console.log("\x1b[32m🦊 Generation complete!\x1b[0m");
|
|
109
173
|
console.log("\nNext steps:");
|
|
110
174
|
console.log(" 1. Run `npm run dev` to start your development server");
|
|
111
|
-
console.log(" 2. Test
|
|
112
|
-
|
|
175
|
+
console.log(" 2. Test API: `curl http://localhost:3000/api/hazo_auth/me`");
|
|
176
|
+
if (include_pages) {
|
|
177
|
+
console.log(" 3. Visit http://localhost:3000/hazo_auth/login to test pages");
|
|
178
|
+
}
|
|
179
|
+
console.log();
|
|
113
180
|
}
|
|
114
|
-
else if (
|
|
115
|
-
console.log("\x1b[33m🦊 All
|
|
181
|
+
else if (total_skipped === ROUTES.length + (include_pages ? PAGES.length : 0)) {
|
|
182
|
+
console.log("\x1b[33m🦊 All files already exist. No changes made.\x1b[0m\n");
|
|
116
183
|
}
|
|
117
184
|
}
|
package/dist/cli/index.js
CHANGED
|
@@ -4,25 +4,29 @@
|
|
|
4
4
|
// section: imports
|
|
5
5
|
import { run_validation } from "./validate.js";
|
|
6
6
|
import { generate_routes } from "./generate.js";
|
|
7
|
+
import { handle_init } from "./init.js";
|
|
7
8
|
// section: constants
|
|
8
|
-
const VERSION = "1.
|
|
9
|
+
const VERSION = "1.6.0";
|
|
9
10
|
const HELP_TEXT = `
|
|
10
11
|
\x1b[1m🐸 hazo_auth CLI v${VERSION}\x1b[0m
|
|
11
12
|
|
|
12
13
|
Usage: hazo_auth <command> [options]
|
|
13
14
|
|
|
14
15
|
Commands:
|
|
16
|
+
init Initialize hazo_auth in your project (creates directories, copies config)
|
|
15
17
|
validate Check your hazo_auth setup and configuration
|
|
16
|
-
generate-routes Generate API route files in your project
|
|
18
|
+
generate-routes Generate API route files and pages in your project
|
|
17
19
|
|
|
18
20
|
Options:
|
|
19
21
|
--help, -h Show this help message
|
|
20
22
|
--version, -v Show version number
|
|
21
23
|
|
|
22
24
|
Examples:
|
|
25
|
+
npx hazo_auth init
|
|
23
26
|
npx hazo_auth validate
|
|
24
27
|
npx hazo_auth generate-routes
|
|
25
|
-
npx hazo_auth generate-routes --
|
|
28
|
+
npx hazo_auth generate-routes --pages
|
|
29
|
+
npx hazo_auth generate-routes --all --dir=src/app
|
|
26
30
|
|
|
27
31
|
Documentation:
|
|
28
32
|
https://github.com/your-repo/hazo_auth/blob/main/SETUP_CHECKLIST.md
|
|
@@ -61,33 +65,42 @@ async function handle_validate() {
|
|
|
61
65
|
process.exit(summary.failed > 0 ? 1 : 0);
|
|
62
66
|
}
|
|
63
67
|
function handle_generate_routes(args) {
|
|
64
|
-
|
|
65
|
-
let dir;
|
|
68
|
+
const options = {};
|
|
66
69
|
for (const arg of args) {
|
|
67
70
|
if (arg.startsWith("--dir=")) {
|
|
68
|
-
dir = arg.replace("--dir=", "");
|
|
71
|
+
options.dir = arg.replace("--dir=", "");
|
|
72
|
+
}
|
|
73
|
+
else if (arg === "--pages") {
|
|
74
|
+
options.pages = true;
|
|
75
|
+
}
|
|
76
|
+
else if (arg === "--all") {
|
|
77
|
+
options.all = true;
|
|
69
78
|
}
|
|
70
79
|
else if (arg === "--help" || arg === "-h") {
|
|
71
80
|
console.log(`
|
|
72
81
|
hazo_auth generate-routes
|
|
73
82
|
|
|
74
|
-
Generate API route files in your Next.js project.
|
|
83
|
+
Generate API route files and page files in your Next.js project.
|
|
75
84
|
|
|
76
85
|
Usage:
|
|
77
86
|
hazo_auth generate-routes [options]
|
|
78
87
|
|
|
79
88
|
Options:
|
|
80
89
|
--dir=<path> Specify the app directory (default: auto-detect)
|
|
90
|
+
--pages Generate page routes in addition to API routes
|
|
91
|
+
--all Generate everything (API routes + pages)
|
|
81
92
|
--help, -h Show this help message
|
|
82
93
|
|
|
83
94
|
Examples:
|
|
84
|
-
hazo_auth generate-routes
|
|
85
|
-
hazo_auth generate-routes --
|
|
95
|
+
hazo_auth generate-routes # API routes only
|
|
96
|
+
hazo_auth generate-routes --pages # API routes + pages
|
|
97
|
+
hazo_auth generate-routes --all # Same as --pages
|
|
98
|
+
hazo_auth generate-routes --dir=src/app # Specify app directory
|
|
86
99
|
`);
|
|
87
100
|
return;
|
|
88
101
|
}
|
|
89
102
|
}
|
|
90
|
-
generate_routes(
|
|
103
|
+
generate_routes(options);
|
|
91
104
|
}
|
|
92
105
|
// section: main
|
|
93
106
|
async function main() {
|
|
@@ -96,12 +109,52 @@ async function main() {
|
|
|
96
109
|
show_version();
|
|
97
110
|
return;
|
|
98
111
|
}
|
|
99
|
-
|
|
112
|
+
// Show main help only if no command specified
|
|
113
|
+
if (!command) {
|
|
100
114
|
show_help();
|
|
101
115
|
return;
|
|
102
116
|
}
|
|
117
|
+
// If help is requested but command exists, pass help to command handler
|
|
118
|
+
// Commands can show their own help
|
|
119
|
+
if (help) {
|
|
120
|
+
args.push("--help");
|
|
121
|
+
}
|
|
103
122
|
switch (command) {
|
|
123
|
+
case "init":
|
|
124
|
+
if (help) {
|
|
125
|
+
console.log(`
|
|
126
|
+
hazo_auth init
|
|
127
|
+
|
|
128
|
+
Initialize hazo_auth in your project.
|
|
129
|
+
|
|
130
|
+
Actions:
|
|
131
|
+
- Creates public/profile_pictures/library/ directory
|
|
132
|
+
- Creates public/profile_pictures/uploads/ directory
|
|
133
|
+
- Creates data/ directory (for SQLite)
|
|
134
|
+
- Copies hazo_auth_config.ini and hazo_notify_config.ini
|
|
135
|
+
- Copies profile picture library images
|
|
136
|
+
- Creates .env.local.example template
|
|
137
|
+
`);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
handle_init();
|
|
141
|
+
break;
|
|
104
142
|
case "validate":
|
|
143
|
+
if (help) {
|
|
144
|
+
console.log(`
|
|
145
|
+
hazo_auth validate
|
|
146
|
+
|
|
147
|
+
Check your hazo_auth setup and configuration.
|
|
148
|
+
|
|
149
|
+
This command verifies:
|
|
150
|
+
- Config files exist and are readable
|
|
151
|
+
- Required config values are set
|
|
152
|
+
- Environment variables are configured
|
|
153
|
+
- Database connection works
|
|
154
|
+
- Required directories exist
|
|
155
|
+
`);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
105
158
|
await handle_validate();
|
|
106
159
|
break;
|
|
107
160
|
case "generate-routes":
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AA2IA,wBAAgB,WAAW,IAAI,IAAI,CAkHlC"}
|
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
// file_description: init command for hazo_auth
|
|
2
|
+
// Creates directories and copies config files to consuming projects
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
// section: esm_shim
|
|
7
|
+
// ESM-compatible __dirname shim
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
// section: constants
|
|
11
|
+
const REQUIRED_DIRECTORIES = [
|
|
12
|
+
"public/profile_pictures/library",
|
|
13
|
+
"public/profile_pictures/uploads",
|
|
14
|
+
"data",
|
|
15
|
+
];
|
|
16
|
+
const CONFIG_FILES = [
|
|
17
|
+
{ source: "hazo_auth_config.example.ini", target: "hazo_auth_config.ini" },
|
|
18
|
+
{ source: "hazo_notify_config.example.ini", target: "hazo_notify_config.ini" },
|
|
19
|
+
];
|
|
20
|
+
// section: helpers
|
|
21
|
+
function get_project_root() {
|
|
22
|
+
return process.cwd();
|
|
23
|
+
}
|
|
24
|
+
function get_package_root() {
|
|
25
|
+
// When running from node_modules, we need to find the hazo_auth package root
|
|
26
|
+
// When running in development, use the current directory
|
|
27
|
+
// Check if we're in node_modules
|
|
28
|
+
const parts = __dirname.split(path.sep);
|
|
29
|
+
const node_modules_index = parts.lastIndexOf("node_modules");
|
|
30
|
+
if (node_modules_index !== -1) {
|
|
31
|
+
// We're in node_modules/hazo_auth/dist/cli
|
|
32
|
+
return parts.slice(0, node_modules_index + 2).join(path.sep);
|
|
33
|
+
}
|
|
34
|
+
// Development mode - go up from src/cli or dist/cli
|
|
35
|
+
return path.resolve(__dirname, "..", "..");
|
|
36
|
+
}
|
|
37
|
+
function ensure_dir(dir_path) {
|
|
38
|
+
if (!fs.existsSync(dir_path)) {
|
|
39
|
+
fs.mkdirSync(dir_path, { recursive: true });
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
function copy_file_if_not_exists(source, target) {
|
|
45
|
+
if (fs.existsSync(target)) {
|
|
46
|
+
return "skipped";
|
|
47
|
+
}
|
|
48
|
+
if (!fs.existsSync(source)) {
|
|
49
|
+
return "error";
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
fs.copyFileSync(source, target);
|
|
53
|
+
return "created";
|
|
54
|
+
}
|
|
55
|
+
catch (_a) {
|
|
56
|
+
return "error";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function copy_directory(source, target) {
|
|
60
|
+
let copied = 0;
|
|
61
|
+
if (!fs.existsSync(source)) {
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
ensure_dir(target);
|
|
65
|
+
const items = fs.readdirSync(source);
|
|
66
|
+
for (const item of items) {
|
|
67
|
+
const source_path = path.join(source, item);
|
|
68
|
+
const target_path = path.join(target, item);
|
|
69
|
+
const stat = fs.statSync(source_path);
|
|
70
|
+
if (stat.isDirectory()) {
|
|
71
|
+
copied += copy_directory(source_path, target_path);
|
|
72
|
+
}
|
|
73
|
+
else if (!fs.existsSync(target_path)) {
|
|
74
|
+
fs.copyFileSync(source_path, target_path);
|
|
75
|
+
copied++;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return copied;
|
|
79
|
+
}
|
|
80
|
+
function create_gitkeep(dir_path) {
|
|
81
|
+
const gitkeep_path = path.join(dir_path, ".gitkeep");
|
|
82
|
+
if (!fs.existsSync(gitkeep_path)) {
|
|
83
|
+
const files = fs.readdirSync(dir_path);
|
|
84
|
+
if (files.length === 0) {
|
|
85
|
+
fs.writeFileSync(gitkeep_path, "# This file keeps the empty directory in git\n");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function create_env_template(project_root) {
|
|
90
|
+
const env_example_path = path.join(project_root, ".env.local.example");
|
|
91
|
+
if (fs.existsSync(env_example_path)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
const content = `# hazo_auth environment variables
|
|
95
|
+
# Copy this file to .env.local and fill in the values
|
|
96
|
+
|
|
97
|
+
# Required for email functionality (email verification, password reset)
|
|
98
|
+
ZEPTOMAIL_API_KEY=your_zeptomail_api_key_here
|
|
99
|
+
|
|
100
|
+
# Optional: Database path (defaults to data/hazo_auth.sqlite)
|
|
101
|
+
# HAZO_AUTH_DB_PATH=./data/hazo_auth.sqlite
|
|
102
|
+
`;
|
|
103
|
+
fs.writeFileSync(env_example_path, content);
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
// section: main
|
|
107
|
+
export function handle_init() {
|
|
108
|
+
const project_root = get_project_root();
|
|
109
|
+
const package_root = get_package_root();
|
|
110
|
+
console.log("\n\x1b[1m🐸 hazo_auth Initialization\x1b[0m");
|
|
111
|
+
console.log("=".repeat(50));
|
|
112
|
+
console.log(`Project root: ${project_root}`);
|
|
113
|
+
console.log(`Package root: ${package_root}\n`);
|
|
114
|
+
const result = {
|
|
115
|
+
directories_created: [],
|
|
116
|
+
files_copied: [],
|
|
117
|
+
skipped: [],
|
|
118
|
+
errors: [],
|
|
119
|
+
};
|
|
120
|
+
// Step 1: Create directories
|
|
121
|
+
console.log("\x1b[1m📁 Creating directories...\x1b[0m\n");
|
|
122
|
+
for (const dir of REQUIRED_DIRECTORIES) {
|
|
123
|
+
const full_path = path.join(project_root, dir);
|
|
124
|
+
if (ensure_dir(full_path)) {
|
|
125
|
+
console.log(`\x1b[32m[CREATE]\x1b[0m ${dir}/`);
|
|
126
|
+
result.directories_created.push(dir);
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
console.log(`\x1b[33m[EXISTS]\x1b[0m ${dir}/`);
|
|
130
|
+
result.skipped.push(dir);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
// Step 2: Copy config files
|
|
134
|
+
console.log("\n\x1b[1m📄 Copying config files...\x1b[0m\n");
|
|
135
|
+
for (const config of CONFIG_FILES) {
|
|
136
|
+
const source_path = path.join(package_root, config.source);
|
|
137
|
+
const target_path = path.join(project_root, config.target);
|
|
138
|
+
const status = copy_file_if_not_exists(source_path, target_path);
|
|
139
|
+
if (status === "created") {
|
|
140
|
+
console.log(`\x1b[32m[CREATE]\x1b[0m ${config.target}`);
|
|
141
|
+
result.files_copied.push(config.target);
|
|
142
|
+
}
|
|
143
|
+
else if (status === "skipped") {
|
|
144
|
+
console.log(`\x1b[33m[EXISTS]\x1b[0m ${config.target}`);
|
|
145
|
+
result.skipped.push(config.target);
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
console.log(`\x1b[31m[ERROR]\x1b[0m ${config.target} - source not found: ${source_path}`);
|
|
149
|
+
result.errors.push(config.target);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// Step 3: Copy profile picture library
|
|
153
|
+
console.log("\n\x1b[1m🖼️ Copying profile picture library...\x1b[0m\n");
|
|
154
|
+
const library_source = path.join(package_root, "public", "profile_pictures", "library");
|
|
155
|
+
const library_target = path.join(project_root, "public", "profile_pictures", "library");
|
|
156
|
+
if (fs.existsSync(library_source)) {
|
|
157
|
+
const copied_count = copy_directory(library_source, library_target);
|
|
158
|
+
if (copied_count > 0) {
|
|
159
|
+
console.log(`\x1b[32m[COPY]\x1b[0m ${copied_count} library images`);
|
|
160
|
+
result.files_copied.push(`${copied_count} library images`);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.log(`\x1b[33m[EXISTS]\x1b[0m Library images already present`);
|
|
164
|
+
result.skipped.push("library images");
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
console.log(`\x1b[33m[SKIP]\x1b[0m Library not found at: ${library_source}`);
|
|
169
|
+
result.skipped.push("library images (source not found)");
|
|
170
|
+
}
|
|
171
|
+
// Step 4: Create .gitkeep files for empty directories
|
|
172
|
+
console.log("\n\x1b[1m📌 Creating .gitkeep files...\x1b[0m\n");
|
|
173
|
+
const empty_dirs = ["public/profile_pictures/uploads", "data"];
|
|
174
|
+
for (const dir of empty_dirs) {
|
|
175
|
+
const full_path = path.join(project_root, dir);
|
|
176
|
+
if (fs.existsSync(full_path)) {
|
|
177
|
+
create_gitkeep(full_path);
|
|
178
|
+
console.log(`\x1b[32m[CREATE]\x1b[0m ${dir}/.gitkeep`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
// Step 5: Create .env.local.example template
|
|
182
|
+
console.log("\n\x1b[1m🔑 Creating environment template...\x1b[0m\n");
|
|
183
|
+
if (create_env_template(project_root)) {
|
|
184
|
+
console.log(`\x1b[32m[CREATE]\x1b[0m .env.local.example`);
|
|
185
|
+
result.files_copied.push(".env.local.example");
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
console.log(`\x1b[33m[EXISTS]\x1b[0m .env.local.example`);
|
|
189
|
+
result.skipped.push(".env.local.example");
|
|
190
|
+
}
|
|
191
|
+
// Summary
|
|
192
|
+
console.log("\n" + "=".repeat(50));
|
|
193
|
+
console.log("\x1b[1mSummary:\x1b[0m");
|
|
194
|
+
console.log(` \x1b[32m✓ Created:\x1b[0m ${result.directories_created.length} directories, ${result.files_copied.length} files`);
|
|
195
|
+
console.log(` \x1b[33m⊘ Skipped:\x1b[0m ${result.skipped.length} items`);
|
|
196
|
+
if (result.errors.length > 0) {
|
|
197
|
+
console.log(` \x1b[31m✗ Errors:\x1b[0m ${result.errors.length}`);
|
|
198
|
+
}
|
|
199
|
+
console.log("\n\x1b[32m🦊 Initialization complete!\x1b[0m");
|
|
200
|
+
console.log("\nNext steps:");
|
|
201
|
+
console.log(" 1. Edit \x1b[36mhazo_auth_config.ini\x1b[0m with your settings");
|
|
202
|
+
console.log(" 2. Copy \x1b[36m.env.local.example\x1b[0m to \x1b[36m.env.local\x1b[0m and add your API keys");
|
|
203
|
+
console.log(" 3. Run \x1b[36mnpx hazo_auth generate-routes --pages\x1b[0m to generate routes and pages");
|
|
204
|
+
console.log(" 4. Run \x1b[36mnpx hazo_auth validate\x1b[0m to check your setup");
|
|
205
|
+
console.log();
|
|
206
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export * from "./components/index";
|
|
2
|
+
export { cn, merge_class_names } from "./lib/utils";
|
|
3
|
+
export * from "./lib/auth/auth_types";
|
|
4
|
+
export { use_auth_status, trigger_auth_status_refresh } from "./components/layouts/shared/hooks/use_auth_status";
|
|
5
|
+
export { use_hazo_auth, trigger_hazo_auth_refresh } from "./components/layouts/shared/hooks/use_hazo_auth";
|
|
6
|
+
export type { UseHazoAuthOptions, UseHazoAuthResult } from "./components/layouts/shared/hooks/use_hazo_auth";
|
|
7
|
+
export * from "./components/layouts/shared/utils/validation";
|
|
8
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAYA,cAAc,oBAAoB,CAAC;AAInC,OAAO,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAIpD,cAAc,uBAAuB,CAAC;AAItC,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,mDAAmD,CAAC;AACjH,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,MAAM,iDAAiD,CAAC;AAC3G,YAAY,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,iDAAiD,CAAC;AAI7G,cAAc,8CAA8C,CAAC"}
|