frontend-hamroun 1.2.16 → 1.2.17
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 +4 -0
- package/bin/cli.js +673 -0
- package/dist/component.d.ts +1 -1
- package/dist/context.d.ts +4 -3
- package/dist/index.client.d.ts +11 -0
- package/dist/index.d.ts +9 -89
- package/dist/index.js +396 -67
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +392 -0
- package/dist/index.mjs.map +1 -0
- package/dist/jsx-runtime/jsx-runtime.d.ts +0 -1
- package/dist/jsx-runtime.d.ts +1 -1
- package/dist/renderer.d.ts +0 -10
- package/dist/server-renderer.d.ts +0 -3
- package/dist/server-types.d.ts +42 -0
- package/package.json +69 -41
- package/templates/basic-app/index.html +6 -6
- package/templates/basic-app/package.json +18 -7
- package/templates/basic-app/postcss.config.js +0 -1
- package/templates/basic-app/src/main.tsx +1 -10
- package/templates/basic-app/tailwind.config.js +2 -23
- package/templates/basic-app/tsconfig.json +4 -17
- package/templates/basic-app/vite.config.ts +3 -54
- package/templates/fullstack-app/api/hello.ts +18 -0
- package/templates/fullstack-app/api/users/[id].ts +73 -0
- package/templates/fullstack-app/api/users/index.ts +32 -0
- package/templates/fullstack-app/package.json +31 -0
- package/templates/fullstack-app/server.ts +46 -0
- package/templates/fullstack-app/src/pages/index.tsx +59 -0
- package/templates/ssr-template/vite.config.ts +1 -11
- package/bin/cli.cjs +0 -16
- package/bin/cli.mjs +0 -237
- package/dist/backend/api-utils.d.ts +0 -38
- package/dist/backend/api-utils.js +0 -135
- package/dist/backend/auth.d.ts +0 -134
- package/dist/backend/auth.js +0 -387
- package/dist/backend/database.d.ts +0 -27
- package/dist/backend/database.js +0 -91
- package/dist/backend/model.d.ts +0 -43
- package/dist/backend/model.js +0 -178
- package/dist/backend/router.d.ts +0 -27
- package/dist/backend/router.js +0 -137
- package/dist/backend/server.d.ts +0 -19
- package/dist/backend/server.js +0 -268
- package/dist/backend/types.d.ts +0 -217
- package/dist/backend/types.js +0 -1
- package/dist/batch.js +0 -22
- package/dist/cli/index.d.ts +0 -2
- package/dist/cli/index.js +0 -215
- package/dist/component.js +0 -84
- package/dist/components/Counter.js +0 -2
- package/dist/context.js +0 -18
- package/dist/frontend-hamroun.es.js +0 -1378
- package/dist/frontend-hamroun.umd.js +0 -66
- package/dist/hooks.js +0 -164
- package/dist/jsx-runtime/index.d.ts +0 -11
- package/dist/jsx-runtime/index.js +0 -19
- package/dist/jsx-runtime/jsx-dev-runtime.js +0 -1
- package/dist/jsx-runtime/jsx-runtime.js +0 -95
- package/dist/jsx-runtime.js +0 -192
- package/dist/renderer.js +0 -51
- package/dist/server-renderer.js +0 -102
- package/dist/types.js +0 -1
- package/dist/vdom.js +0 -27
- package/scripts/build-cli.js +0 -1199
- package/scripts/generate.js +0 -134
- package/src/backend/api-utils.ts +0 -178
- package/src/backend/auth.ts +0 -544
- package/src/backend/database.ts +0 -104
- package/src/backend/model.ts +0 -198
- package/src/backend/router.ts +0 -176
- package/src/backend/server.ts +0 -330
- package/src/backend/types.ts +0 -257
- package/src/batch.ts +0 -24
- package/src/cli/index.js +0 -554
- package/src/cli/index.ts +0 -257
- package/src/component.ts +0 -98
- package/src/components/Counter.tsx +0 -4
- package/src/context.ts +0 -29
- package/src/hooks.ts +0 -211
- package/src/index.ts +0 -144
- package/src/jsx-runtime/index.ts +0 -27
- package/src/jsx-runtime/jsx-dev-runtime.ts +0 -0
- package/src/jsx-runtime/jsx-runtime.ts +0 -104
- package/src/jsx-runtime.ts +0 -226
- package/src/renderer.ts +0 -55
- package/src/server-renderer.ts +0 -114
- package/src/shims.d.ts +0 -20
- package/src/types/bcrypt.d.ts +0 -30
- package/src/types/jsonwebtoken.d.ts +0 -55
- package/src/types.d.ts +0 -26
- package/src/types.ts +0 -21
- package/src/vdom.ts +0 -34
- package/templates/basic/.eslintignore +0 -5
- package/templates/basic/.eslintrc.json +0 -25
- package/templates/basic/docs/rapport_pfe.aux +0 -27
- package/templates/basic/docs/rapport_pfe.log +0 -399
- package/templates/basic/docs/rapport_pfe.out +0 -10
- package/templates/basic/docs/rapport_pfe.pdf +0 -0
- package/templates/basic/docs/rapport_pfe.tex +0 -68
- package/templates/basic/docs/rapport_pfe.toc +0 -14
- package/templates/basic/index.html +0 -12
- package/templates/basic/jsconfig.json +0 -14
- package/templates/basic/package.json +0 -18
- package/templates/basic/postcss.config.js +0 -7
- package/templates/basic/src/App.js +0 -105
- package/templates/basic/src/App.tsx +0 -65
- package/templates/basic/src/api.ts +0 -58
- package/templates/basic/src/components/Counter.tsx +0 -26
- package/templates/basic/src/components/Header.tsx +0 -9
- package/templates/basic/src/components/TodoList.tsx +0 -90
- package/templates/basic/src/main.css +0 -3
- package/templates/basic/src/main.js +0 -11
- package/templates/basic/src/main.ts +0 -20
- package/templates/basic/src/main.tsx +0 -144
- package/templates/basic/src/server.ts +0 -99
- package/templates/basic/tailwind.config.js +0 -32
- package/templates/basic/tsconfig.json +0 -20
- package/templates/basic/tsconfig.node.json +0 -10
- package/templates/basic/vite.config.js +0 -18
- package/templates/basic/vite.config.ts +0 -86
- package/templates/basic-app/src/App.js +0 -105
- package/templates/basic-app/src/App.tsx +0 -143
- package/templates/basic-app/src/api.ts +0 -58
- package/templates/basic-app/src/components/Counter.tsx +0 -26
- package/templates/basic-app/src/components/Header.tsx +0 -9
- package/templates/basic-app/src/components/TodoList.tsx +0 -90
- package/templates/basic-app/src/main.js +0 -10
- package/templates/basic-app/src/main.ts +0 -21
- package/templates/basic-app/src/react/index.ts +0 -35
- package/templates/basic-app/src/react/jsx-dev-runtime.ts +0 -13
- package/templates/basic-app/src/react/jsx-runtime.ts +0 -12
- package/templates/basic-app/src/server.ts +0 -99
- package/templates/basic-app/src/shims.ts +0 -9
- package/templates/basic-app/tsconfig.node.json +0 -10
- package/templates/basic-app/vite.config.js +0 -22
- package/templates/full-stack/.env.example +0 -11
- package/templates/full-stack/README.md +0 -51
- package/templates/full-stack/index.html +0 -12
- package/templates/full-stack/jsconfig.json +0 -14
- package/templates/full-stack/package.json +0 -21
- package/templates/full-stack/src/App.js +0 -105
- package/templates/full-stack/src/client/App.tsx +0 -50
- package/templates/full-stack/src/client/components/Header.tsx +0 -42
- package/templates/full-stack/src/client/components/UserList.tsx +0 -29
- package/templates/full-stack/src/client/main.tsx +0 -5
- package/templates/full-stack/src/main.css +0 -3
- package/templates/full-stack/src/main.js +0 -11
- package/templates/full-stack/src/main.ts +0 -20
- package/templates/full-stack/src/server/index.ts +0 -99
- package/templates/full-stack/src/server/routes/auth.ts +0 -39
- package/templates/full-stack/src/server/routes/users.ts +0 -48
- package/templates/full-stack/src/shims.ts +0 -9
- package/templates/full-stack/tsconfig.json +0 -20
- package/templates/full-stack/tsconfig.node.json +0 -10
- package/templates/full-stack/tsconfig.server.json +0 -15
- package/templates/full-stack/vite.config.js +0 -18
- package/templates/full-stack/vite.config.ts +0 -85
package/dist/backend/types.d.ts
DELETED
@@ -1,217 +0,0 @@
|
|
1
|
-
import { Request, Response, NextFunction, RequestHandler } from 'express';
|
2
|
-
import { DatabaseConnector } from './database';
|
3
|
-
/**
|
4
|
-
* Options for configuring a Hamroun server
|
5
|
-
*/
|
6
|
-
export interface HamrounServerOptions {
|
7
|
-
/**
|
8
|
-
* Port to run the server on (default: 3000)
|
9
|
-
*/
|
10
|
-
port?: number;
|
11
|
-
/**
|
12
|
-
* Directory to serve static files from (default: 'public')
|
13
|
-
*/
|
14
|
-
staticDir?: string;
|
15
|
-
/**
|
16
|
-
* Enable CORS headers (default: true)
|
17
|
-
*/
|
18
|
-
enableCors?: boolean;
|
19
|
-
/**
|
20
|
-
* Prefix for API routes (default: '/api')
|
21
|
-
*/
|
22
|
-
apiPrefix?: string;
|
23
|
-
/**
|
24
|
-
* Enable server-side rendering (default: true)
|
25
|
-
*/
|
26
|
-
ssrEnabled?: boolean;
|
27
|
-
/**
|
28
|
-
* Additional Express middleware to apply
|
29
|
-
*/
|
30
|
-
middlewares?: RequestHandler[];
|
31
|
-
/**
|
32
|
-
* Enable response compression (default: true)
|
33
|
-
*/
|
34
|
-
enableCompression?: boolean;
|
35
|
-
/**
|
36
|
-
* Enable helmet security headers (default: true)
|
37
|
-
*/
|
38
|
-
enableHelmet?: boolean;
|
39
|
-
/**
|
40
|
-
* Disable Content Security Policy (default: false)
|
41
|
-
*/
|
42
|
-
disableCSP?: boolean;
|
43
|
-
/**
|
44
|
-
* Logging format for Morgan (default: 'dev')
|
45
|
-
*/
|
46
|
-
logFormat?: string | null;
|
47
|
-
/**
|
48
|
-
* Trust proxy headers (default: false)
|
49
|
-
*/
|
50
|
-
trustProxy?: boolean | string | number | string[] | number[];
|
51
|
-
/**
|
52
|
-
* Static file cache age (default: '1d')
|
53
|
-
*/
|
54
|
-
staticCacheAge?: string;
|
55
|
-
/**
|
56
|
-
* Show detailed error information in responses (default: false)
|
57
|
-
*/
|
58
|
-
showErrorDetails?: boolean;
|
59
|
-
}
|
60
|
-
/**
|
61
|
-
* Options for router configuration
|
62
|
-
*/
|
63
|
-
export interface RouterOptions {
|
64
|
-
/**
|
65
|
-
* Prefix to apply to all routes (overrides server apiPrefix)
|
66
|
-
*/
|
67
|
-
prefix?: string;
|
68
|
-
/**
|
69
|
-
* Enable authentication for all routes in this router
|
70
|
-
*/
|
71
|
-
requireAuth?: boolean;
|
72
|
-
/**
|
73
|
-
* Required role for all routes in this router
|
74
|
-
*/
|
75
|
-
requiredRole?: string | string[];
|
76
|
-
/**
|
77
|
-
* Enable rate limiting for this router
|
78
|
-
*/
|
79
|
-
rateLimit?: {
|
80
|
-
windowMs: number;
|
81
|
-
max: number;
|
82
|
-
message?: string;
|
83
|
-
};
|
84
|
-
}
|
85
|
-
/**
|
86
|
-
* Context provided to route handlers
|
87
|
-
*/
|
88
|
-
export interface RouteContext {
|
89
|
-
req: Request;
|
90
|
-
res: Response;
|
91
|
-
next: NextFunction;
|
92
|
-
params: any;
|
93
|
-
query: any;
|
94
|
-
body: any;
|
95
|
-
user?: any;
|
96
|
-
}
|
97
|
-
/**
|
98
|
-
* Pagination options
|
99
|
-
*/
|
100
|
-
export interface PaginationOptions {
|
101
|
-
page: number;
|
102
|
-
limit: number;
|
103
|
-
sort?: string;
|
104
|
-
order?: 'asc' | 'desc';
|
105
|
-
}
|
106
|
-
/**
|
107
|
-
* Paginated result
|
108
|
-
*/
|
109
|
-
export interface PaginatedResult<T> {
|
110
|
-
data: T[];
|
111
|
-
pagination: {
|
112
|
-
total: number;
|
113
|
-
totalPages: number;
|
114
|
-
currentPage: number;
|
115
|
-
limit: number;
|
116
|
-
hasNextPage: boolean;
|
117
|
-
hasPrevPage: boolean;
|
118
|
-
};
|
119
|
-
}
|
120
|
-
/**
|
121
|
-
* Database connection options
|
122
|
-
*/
|
123
|
-
export interface DatabaseOptions {
|
124
|
-
/**
|
125
|
-
* URI to connect to the database
|
126
|
-
*/
|
127
|
-
uri: string;
|
128
|
-
/**
|
129
|
-
* Database name
|
130
|
-
*/
|
131
|
-
name: string;
|
132
|
-
/**
|
133
|
-
* Connection options
|
134
|
-
*/
|
135
|
-
options?: Record<string, any>;
|
136
|
-
/**
|
137
|
-
* Number of retry attempts (default: 3)
|
138
|
-
*/
|
139
|
-
retryAttempts?: number;
|
140
|
-
/**
|
141
|
-
* Retry delay in ms (default: 1000)
|
142
|
-
*/
|
143
|
-
retryDelay?: number;
|
144
|
-
/**
|
145
|
-
* Connection timeout in ms (default: 10000)
|
146
|
-
*/
|
147
|
-
connectionTimeout?: number;
|
148
|
-
/**
|
149
|
-
* Auto-index creation (default: true)
|
150
|
-
*/
|
151
|
-
autoIndex?: boolean;
|
152
|
-
}
|
153
|
-
/**
|
154
|
-
* Data model structure
|
155
|
-
*/
|
156
|
-
export interface Model<T> {
|
157
|
-
/**
|
158
|
-
* Get all documents
|
159
|
-
*/
|
160
|
-
getAll: (options?: PaginationOptions) => Promise<PaginatedResult<T>>;
|
161
|
-
/**
|
162
|
-
* Get document by ID
|
163
|
-
*/
|
164
|
-
getById: (id: string) => Promise<T | null>;
|
165
|
-
/**
|
166
|
-
* Create a new document
|
167
|
-
*/
|
168
|
-
create: (data: Partial<T>) => Promise<T>;
|
169
|
-
/**
|
170
|
-
* Create multiple documents
|
171
|
-
*/
|
172
|
-
createMany: (data: Partial<T>[]) => Promise<T[]>;
|
173
|
-
/**
|
174
|
-
* Update a document
|
175
|
-
*/
|
176
|
-
update: (id: string, data: Partial<T>) => Promise<T | null>;
|
177
|
-
/**
|
178
|
-
* Delete a document
|
179
|
-
*/
|
180
|
-
delete: (id: string) => Promise<boolean>;
|
181
|
-
/**
|
182
|
-
* Find documents by custom query
|
183
|
-
*/
|
184
|
-
find: (query: Record<string, any>, options?: PaginationOptions) => Promise<PaginatedResult<T>>;
|
185
|
-
/**
|
186
|
-
* Count documents matching query
|
187
|
-
*/
|
188
|
-
count: (query?: Record<string, any>) => Promise<number>;
|
189
|
-
/**
|
190
|
-
* Find one document
|
191
|
-
*/
|
192
|
-
findOne: (query: Record<string, any>) => Promise<T | null>;
|
193
|
-
}
|
194
|
-
/**
|
195
|
-
* API response format
|
196
|
-
*/
|
197
|
-
export interface ApiResponse<T = any> {
|
198
|
-
success: boolean;
|
199
|
-
data?: T;
|
200
|
-
error?: string;
|
201
|
-
message?: string;
|
202
|
-
meta?: Record<string, any>;
|
203
|
-
}
|
204
|
-
declare global {
|
205
|
-
namespace Express {
|
206
|
-
interface Application {
|
207
|
-
registerApi: (routePath: string, router: any, options?: RouterOptions) => Application;
|
208
|
-
registerSSR: (routePath: string, component: any, options?: any) => Application;
|
209
|
-
start: (callback?: () => void) => any;
|
210
|
-
connectToDatabase: (dbOptions: DatabaseOptions) => Promise<DatabaseConnector>;
|
211
|
-
}
|
212
|
-
interface Request {
|
213
|
-
user?: any;
|
214
|
-
pagination?: PaginationOptions;
|
215
|
-
}
|
216
|
-
}
|
217
|
-
}
|
package/dist/backend/types.js
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
export {};
|
package/dist/batch.js
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
export let isBatching = false;
|
2
|
-
const queue = [];
|
3
|
-
export function batchUpdates(fn) {
|
4
|
-
if (isBatching) {
|
5
|
-
queue.push(fn);
|
6
|
-
return;
|
7
|
-
}
|
8
|
-
isBatching = true;
|
9
|
-
try {
|
10
|
-
fn();
|
11
|
-
while (queue.length > 0) {
|
12
|
-
const nextFn = queue.shift();
|
13
|
-
nextFn?.();
|
14
|
-
}
|
15
|
-
}
|
16
|
-
finally {
|
17
|
-
isBatching = false;
|
18
|
-
}
|
19
|
-
}
|
20
|
-
export function getIsBatching() {
|
21
|
-
return isBatching;
|
22
|
-
}
|
package/dist/cli/index.d.ts
DELETED
package/dist/cli/index.js
DELETED
@@ -1,215 +0,0 @@
|
|
1
|
-
#!/usr/bin/env node
|
2
|
-
import fs from 'fs';
|
3
|
-
import path from 'path';
|
4
|
-
import { fileURLToPath } from 'url';
|
5
|
-
import { execSync } from 'child_process';
|
6
|
-
import readline from 'readline';
|
7
|
-
const __filename = fileURLToPath(import.meta.url);
|
8
|
-
const __dirname = path.dirname(__filename);
|
9
|
-
// Get package.json to read version
|
10
|
-
const packageJsonPath = path.resolve(__dirname, '../../package.json');
|
11
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
12
|
-
// Available templates
|
13
|
-
const TEMPLATES = {
|
14
|
-
'basic': 'Basic frontend only template',
|
15
|
-
'full-stack': 'Complete frontend and backend template',
|
16
|
-
'api-only': 'Backend API only template'
|
17
|
-
};
|
18
|
-
// CLI colors
|
19
|
-
const colors = {
|
20
|
-
reset: '\x1b[0m',
|
21
|
-
bright: '\x1b[1m',
|
22
|
-
green: '\x1b[32m',
|
23
|
-
blue: '\x1b[34m',
|
24
|
-
red: '\x1b[31m',
|
25
|
-
yellow: '\x1b[33m'
|
26
|
-
};
|
27
|
-
// Create readline interface
|
28
|
-
function createInterface() {
|
29
|
-
return readline.createInterface({
|
30
|
-
input: process.stdin,
|
31
|
-
output: process.stdout
|
32
|
-
});
|
33
|
-
}
|
34
|
-
// Print banner
|
35
|
-
function printBanner() {
|
36
|
-
console.log(`
|
37
|
-
${colors.blue}${colors.bright}╔══════════════════════════════════════════════╗
|
38
|
-
║ ║
|
39
|
-
║ Frontend Hamroun v${packageJson.version.padEnd(25)}║
|
40
|
-
║ A lightweight frontend & backend framework ║
|
41
|
-
║ ║
|
42
|
-
╚══════════════════════════════════════════════╝${colors.reset}
|
43
|
-
`);
|
44
|
-
}
|
45
|
-
// Print help
|
46
|
-
function printHelp() {
|
47
|
-
console.log(`
|
48
|
-
${colors.bright}USAGE:${colors.reset}
|
49
|
-
${colors.blue}npx frontend-hamroun${colors.reset} [command] [options]
|
50
|
-
|
51
|
-
${colors.bright}COMMANDS:${colors.reset}
|
52
|
-
${colors.blue}create${colors.reset} <project-name> [options] Create a new project
|
53
|
-
${colors.blue}help${colors.reset} Display this help message
|
54
|
-
${colors.blue}version${colors.reset} Display version information
|
55
|
-
|
56
|
-
${colors.bright}OPTIONS:${colors.reset}
|
57
|
-
${colors.blue}--template${colors.reset}, ${colors.blue}-t${colors.reset} <template> Specify template (default: basic)
|
58
|
-
${colors.blue}--skip-install${colors.reset}, ${colors.blue}-s${colors.reset} Skip package installation
|
59
|
-
|
60
|
-
${colors.bright}AVAILABLE TEMPLATES:${colors.reset}
|
61
|
-
${Object.entries(TEMPLATES).map(([name, desc]) => ` ${colors.blue}${name.padEnd(12)}${colors.reset} ${desc}`).join('\n')}
|
62
|
-
|
63
|
-
${colors.bright}EXAMPLES:${colors.reset}
|
64
|
-
${colors.blue}npx frontend-hamroun create${colors.reset} my-app
|
65
|
-
${colors.blue}npx frontend-hamroun create${colors.reset} my-app --template full-stack
|
66
|
-
${colors.blue}npx frontend-hamroun create${colors.reset} my-api -t api-only --skip-install
|
67
|
-
`);
|
68
|
-
}
|
69
|
-
// Create project from template
|
70
|
-
async function createProject(projectName, options) {
|
71
|
-
const template = options.template || 'basic';
|
72
|
-
// Check if template exists
|
73
|
-
if (!Object.keys(TEMPLATES).includes(template)) {
|
74
|
-
console.error(`${colors.red}error:${colors.reset} Template "${template}" not found.`);
|
75
|
-
console.log(`Available templates: ${Object.keys(TEMPLATES).join(', ')}`);
|
76
|
-
process.exit(1);
|
77
|
-
}
|
78
|
-
// Check if project directory already exists
|
79
|
-
const projectPath = path.resolve(process.cwd(), projectName);
|
80
|
-
if (fs.existsSync(projectPath)) {
|
81
|
-
console.error(`${colors.red}error:${colors.reset} Directory ${projectName} already exists.`);
|
82
|
-
process.exit(1);
|
83
|
-
}
|
84
|
-
console.log(`
|
85
|
-
${colors.bright}Creating a new project with Frontend Hamroun...${colors.reset}
|
86
|
-
${colors.blue}• Project name:${colors.reset} ${projectName}
|
87
|
-
${colors.blue}• Template:${colors.reset} ${template}
|
88
|
-
${colors.blue}• Directory:${colors.reset} ${projectPath}
|
89
|
-
`);
|
90
|
-
try {
|
91
|
-
// Find templates directory
|
92
|
-
const templateDir = path.resolve(__dirname, '../../templates', template);
|
93
|
-
// Create project directory
|
94
|
-
fs.mkdirSync(projectPath, { recursive: true });
|
95
|
-
// Copy template files
|
96
|
-
copyTemplateFiles(templateDir, projectPath);
|
97
|
-
// Update package.json with project name
|
98
|
-
const projectPackageJsonPath = path.join(projectPath, 'package.json');
|
99
|
-
if (fs.existsSync(projectPackageJsonPath)) {
|
100
|
-
const projectPackageJson = JSON.parse(fs.readFileSync(projectPackageJsonPath, 'utf8'));
|
101
|
-
projectPackageJson.name = projectName;
|
102
|
-
fs.writeFileSync(projectPackageJsonPath, JSON.stringify(projectPackageJson, null, 2));
|
103
|
-
}
|
104
|
-
// Install dependencies
|
105
|
-
if (!options.skipInstall) {
|
106
|
-
console.log(`\n${colors.blue}Installing dependencies...${colors.reset}`);
|
107
|
-
const command = getPackageManager() === 'yarn'
|
108
|
-
? 'yarn'
|
109
|
-
: 'npm install';
|
110
|
-
execSync(command, {
|
111
|
-
cwd: projectPath,
|
112
|
-
stdio: 'inherit'
|
113
|
-
});
|
114
|
-
}
|
115
|
-
// Success message
|
116
|
-
console.log(`
|
117
|
-
${colors.green}${colors.bright}Success!${colors.reset} Created ${projectName} at ${projectPath}
|
118
|
-
|
119
|
-
${colors.blue}Inside that directory, you can run several commands:${colors.reset}
|
120
|
-
|
121
|
-
${colors.bright}npm run dev${colors.reset}
|
122
|
-
Starts the development server.
|
123
|
-
|
124
|
-
${colors.bright}npm run build${colors.reset}
|
125
|
-
Builds the app for production.
|
126
|
-
|
127
|
-
${colors.bright}npm start${colors.reset}
|
128
|
-
Runs the built app in production mode.
|
129
|
-
|
130
|
-
${colors.blue}We suggest that you begin by typing:${colors.reset}
|
131
|
-
|
132
|
-
${colors.bright}cd${colors.reset} ${projectName}
|
133
|
-
${colors.bright}npm run dev${colors.reset}
|
134
|
-
|
135
|
-
${colors.green}Happy coding!${colors.reset}
|
136
|
-
`);
|
137
|
-
}
|
138
|
-
catch (error) {
|
139
|
-
console.error(`${colors.red}Failed to create project:${colors.reset}`, error);
|
140
|
-
process.exit(1);
|
141
|
-
}
|
142
|
-
}
|
143
|
-
// Copy template files recursively
|
144
|
-
function copyTemplateFiles(source, destination) {
|
145
|
-
const files = fs.readdirSync(source);
|
146
|
-
for (const file of files) {
|
147
|
-
const sourcePath = path.join(source, file);
|
148
|
-
const destPath = path.join(destination, file);
|
149
|
-
const stats = fs.statSync(sourcePath);
|
150
|
-
if (stats.isDirectory()) {
|
151
|
-
fs.mkdirSync(destPath, { recursive: true });
|
152
|
-
copyTemplateFiles(sourcePath, destPath);
|
153
|
-
}
|
154
|
-
else {
|
155
|
-
fs.copyFileSync(sourcePath, destPath);
|
156
|
-
}
|
157
|
-
}
|
158
|
-
console.log(`${colors.green}•${colors.reset} Copied template files`);
|
159
|
-
}
|
160
|
-
// Detect package manager
|
161
|
-
function getPackageManager() {
|
162
|
-
try {
|
163
|
-
const userAgent = process.env.npm_config_user_agent;
|
164
|
-
if (userAgent && userAgent.startsWith('yarn')) {
|
165
|
-
return 'yarn';
|
166
|
-
}
|
167
|
-
return 'npm';
|
168
|
-
}
|
169
|
-
catch (error) {
|
170
|
-
return 'npm';
|
171
|
-
}
|
172
|
-
}
|
173
|
-
// Parse command line arguments
|
174
|
-
function parseArgs() {
|
175
|
-
const args = process.argv.slice(2);
|
176
|
-
const command = args[0];
|
177
|
-
if (!command || command === 'help') {
|
178
|
-
printBanner();
|
179
|
-
printHelp();
|
180
|
-
process.exit(0);
|
181
|
-
}
|
182
|
-
if (command === 'version') {
|
183
|
-
console.log(`frontend-hamroun v${packageJson.version}`);
|
184
|
-
process.exit(0);
|
185
|
-
}
|
186
|
-
if (command === 'create') {
|
187
|
-
const projectName = args[1];
|
188
|
-
if (!projectName) {
|
189
|
-
console.error(`${colors.red}error:${colors.reset} Project name is required.`);
|
190
|
-
console.log(`Run ${colors.blue}npx frontend-hamroun help${colors.reset} for usage information.`);
|
191
|
-
process.exit(1);
|
192
|
-
}
|
193
|
-
// Parse options
|
194
|
-
const options = {
|
195
|
-
template: 'basic',
|
196
|
-
skipInstall: false
|
197
|
-
};
|
198
|
-
for (let i = 2; i < args.length; i++) {
|
199
|
-
if (args[i] === '--template' || args[i] === '-t') {
|
200
|
-
options.template = args[++i];
|
201
|
-
}
|
202
|
-
else if (args[i] === '--skip-install' || args[i] === '-s') {
|
203
|
-
options.skipInstall = true;
|
204
|
-
}
|
205
|
-
}
|
206
|
-
printBanner();
|
207
|
-
createProject(projectName, options);
|
208
|
-
return;
|
209
|
-
}
|
210
|
-
console.error(`${colors.red}error:${colors.reset} Unknown command: ${command}`);
|
211
|
-
console.log(`Run ${colors.blue}npx frontend-hamroun help${colors.reset} for usage information.`);
|
212
|
-
process.exit(1);
|
213
|
-
}
|
214
|
-
// Run CLI
|
215
|
-
parseArgs();
|
package/dist/component.js
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
import { createElement } from './jsx-runtime';
|
2
|
-
export class Component {
|
3
|
-
constructor(props = {}) {
|
4
|
-
this.state = {};
|
5
|
-
this.element = null;
|
6
|
-
this._mounted = false;
|
7
|
-
this.props = props;
|
8
|
-
}
|
9
|
-
componentDidMount() {
|
10
|
-
// Hook for after component is mounted
|
11
|
-
}
|
12
|
-
async setState(newState) {
|
13
|
-
const prevState = { ...this.state };
|
14
|
-
this.state = { ...prevState, ...newState };
|
15
|
-
console.log(`${this.constructor.name} state updated:`, {
|
16
|
-
prev: prevState,
|
17
|
-
next: this.state
|
18
|
-
});
|
19
|
-
await Promise.resolve(); // Ensure state is updated before re-render
|
20
|
-
if (this._mounted) {
|
21
|
-
await this.update();
|
22
|
-
}
|
23
|
-
else {
|
24
|
-
await this.update();
|
25
|
-
}
|
26
|
-
}
|
27
|
-
_replayEvents(oldElement, newElement) {
|
28
|
-
const oldEvents = oldElement.__events || {};
|
29
|
-
Object.entries(oldEvents).forEach(([event, handler]) => {
|
30
|
-
newElement.addEventListener(event, handler);
|
31
|
-
});
|
32
|
-
newElement.__events = oldEvents;
|
33
|
-
}
|
34
|
-
_deepCloneWithEvents(node) {
|
35
|
-
const clone = node.cloneNode(false);
|
36
|
-
// Copy events from original element
|
37
|
-
const events = node.__events || {};
|
38
|
-
clone.__events = events;
|
39
|
-
Object.entries(events).forEach(([event, handler]) => {
|
40
|
-
clone.addEventListener(event, handler);
|
41
|
-
});
|
42
|
-
// Clone children
|
43
|
-
Array.from(node.childNodes).forEach(child => {
|
44
|
-
if (child instanceof HTMLElement) {
|
45
|
-
clone.appendChild(this._deepCloneWithEvents(child));
|
46
|
-
}
|
47
|
-
else {
|
48
|
-
clone.appendChild(child.cloneNode(true));
|
49
|
-
}
|
50
|
-
});
|
51
|
-
return clone;
|
52
|
-
}
|
53
|
-
async update() {
|
54
|
-
const vdom = this.render();
|
55
|
-
if (!vdom)
|
56
|
-
return document.createTextNode('');
|
57
|
-
const rendered = await createElement(vdom);
|
58
|
-
if (rendered instanceof HTMLElement) {
|
59
|
-
return this._updateElement(rendered);
|
60
|
-
}
|
61
|
-
const wrapper = document.createElement('div');
|
62
|
-
wrapper.appendChild(rendered);
|
63
|
-
return this._updateElement(wrapper);
|
64
|
-
}
|
65
|
-
async _updateElement(rendered) {
|
66
|
-
const newElement = this._deepCloneWithEvents(rendered);
|
67
|
-
newElement.__instance = this;
|
68
|
-
if (!this.element) {
|
69
|
-
this.element = newElement;
|
70
|
-
if (!this._mounted) {
|
71
|
-
this._mounted = true;
|
72
|
-
queueMicrotask(() => this.componentDidMount());
|
73
|
-
}
|
74
|
-
}
|
75
|
-
else if (this.element.parentNode) {
|
76
|
-
this.element.parentNode.replaceChild(newElement, this.element);
|
77
|
-
this.element = newElement;
|
78
|
-
}
|
79
|
-
return this.element;
|
80
|
-
}
|
81
|
-
render() {
|
82
|
-
throw new Error('Component must implement render() method');
|
83
|
-
}
|
84
|
-
}
|
package/dist/context.js
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
const contexts = new Map();
|
2
|
-
let currentRender = null;
|
3
|
-
export function createContext(defaultValue) {
|
4
|
-
const context = {
|
5
|
-
_currentValue: defaultValue,
|
6
|
-
Provider: function Provider({ value, children }) {
|
7
|
-
context._currentValue = value;
|
8
|
-
return children;
|
9
|
-
},
|
10
|
-
Consumer: function Consumer({ children }) {
|
11
|
-
return children(context._currentValue);
|
12
|
-
}
|
13
|
-
};
|
14
|
-
return context;
|
15
|
-
}
|
16
|
-
export function useContext(context) {
|
17
|
-
return context._currentValue;
|
18
|
-
}
|