kreftjs 0.0.17-beta → 0.0.20-beta
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 +20 -0
- package/bin/build.js +13 -2
- package/bin/electron.js +61 -2
- package/bin/kreftjs.js +5 -3
- package/book/ar/01-getting-started.md +169 -0
- package/book/ar/02-language.md +330 -0
- package/book/ar/03-components-and-state.md +258 -0
- package/book/ar/04-router-data-forms.md +333 -0
- package/book/ar/05-arabic-rtl.md +175 -0
- package/book/ar/06-backend.md +247 -0
- package/book/ar/07-auth-and-security.md +157 -0
- package/book/ar/08-background-work.md +250 -0
- package/book/ar/09-testing-and-deploy.md +234 -0
- package/book/ar/10-electron-desktop.md +258 -0
- package/book/ar/11-advanced-blog.md +370 -0
- package/book/ar/12-advanced-shop.md +426 -0
- package/book/ar/13-advanced-ui.md +440 -0
- package/book/ar/14-advanced-ops.md +167 -0
- package/book/ar/15-appendix.md +81 -0
- package/book/ar/README.md +62 -0
- package/book/kreft-book-ar.docx +0 -0
- package/docs/README.md +43 -8
- package/kreftjs.d.ts +1 -1
- package/kreftjs.js +436 -74
- package/package.json +4 -3
- package/templates/app/frontend/errors/ErrorMonitor.kreft +2 -2
- package/templates/app/frontend/kreftjs.d.ts +1 -1
- package/templates/app/frontend/kreftjs.js +436 -74
- package/templates/app/frontend/pages/Dashboard.kreft +1 -1
- package/templates/errors/ErrorMonitor.kreft +1 -1
package/README.md
CHANGED
|
@@ -42,10 +42,30 @@ Open the address in the terminal (normally `http://localhost:8000`). A new proje
|
|
|
42
42
|
| **Authentication** | Cookie sessions with CSRF protection, API tokens with permissions, device list, two-factor codes, email verification, account lockout. |
|
|
43
43
|
| **Tooling** | `kreft dev` with hot reload, DevTools, an error monitor, `kreft build` (CSP-safe), prerendering, TypeScript, Vite and Electron support, a safer `kreft add`, an MCP server for AI agents. |
|
|
44
44
|
|
|
45
|
+
## Desktop apps (Electron)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
kreft new my-app --electron # or: kreft electron:init in an existing app
|
|
49
|
+
npm install
|
|
50
|
+
kreft electron # opens the app in its own window (no browser, no URL)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Make installers (build each system on that system; `.deb` and `.rpm` need Linux):
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm run electron:build:mac # .dmg and .zip
|
|
57
|
+
npm run electron:build:win # NSIS installer and portable .exe
|
|
58
|
+
npm run electron:build:linux # AppImage, .deb and .rpm
|
|
59
|
+
npm run electron:build:all # all three (same as: kreft electron:build --all)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The app icon is `build/icon.png`, and `ELECTRON_MENU=show|auto|hide` controls the window menu. Details: [Desktop apps with Electron](docs/README.md#desktop-apps-with-electron).
|
|
63
|
+
|
|
45
64
|
## Learn more
|
|
46
65
|
|
|
47
66
|
| I want to… | Read |
|
|
48
67
|
|---|---|
|
|
68
|
+
| Learn Kreft in Arabic, from basics to advanced tested examples | [كتاب Kreft بالعربية](book/ar/README.md) |
|
|
49
69
|
| Build my first page | [Your first app](docs/README.md#your-first-app) and [Components](docs/README.md#components-and-the-kreft-file) |
|
|
50
70
|
| Fetch data and handle forms | [Fetching data](docs/README.md#fetching-data), [Forms](docs/README.md#forms-and-validation) |
|
|
51
71
|
| Add an API and a database | [Routing](docs/README.md#routing), [Models](docs/README.md#models-and-the-database), [Migrations](docs/README.md#migrations-seeders-and-factories) |
|
package/bin/build.js
CHANGED
|
@@ -34,12 +34,13 @@ const SERVER_DIRS = new Set();
|
|
|
34
34
|
const SKIP = new Set(['node_modules', 'dist', 'dist-electron', '.git', '.vscode', '.idea', 'package.json', 'package-lock.json', '.DS_Store']);
|
|
35
35
|
|
|
36
36
|
module.exports = function build(args) {
|
|
37
|
-
let folder = null, out = null, base = null, prerender = null, urlsFile = null, htaccess = true;
|
|
37
|
+
let folder = null, out = null, base = null, prerender = null, urlsFile = null, htaccess = true, minify = true;
|
|
38
38
|
const include = [];
|
|
39
39
|
for (let i = 0; i < args.length; i++) {
|
|
40
40
|
if (args[i] === '--out' || args[i] === '-o') out = args[++i];
|
|
41
41
|
else if (args[i] === '--base') base = args[++i];
|
|
42
42
|
else if (args[i] === '--no-htaccess') htaccess = false;
|
|
43
|
+
else if (args[i] === '--no-minify') minify = false; // keep kreftjs.js readable (for debugging)
|
|
43
44
|
else if (args[i] === '--include') include.push(args[++i]); // another folder to copy in, like the docs
|
|
44
45
|
else if (args[i] === '--prerender') prerender = args[i + 1] && !args[i + 1].startsWith('-') && args[i + 1].includes('/') ? args[++i].split(',') : [];
|
|
45
46
|
else if (args[i] === '--urls') urlsFile = args[++i]; // a file with more addresses to prerender (pages from your data)
|
|
@@ -154,7 +155,17 @@ ${indent(components.join('\n\n'))}
|
|
|
154
155
|
}
|
|
155
156
|
}
|
|
156
157
|
}
|
|
157
|
-
|
|
158
|
+
// the framework file is minified when esbuild is installed (about 40% smaller); without it, it is copied as it is
|
|
159
|
+
const runtimeSrc = path.join(__dirname, '..', 'kreftjs.js'), runtimeOut = path.join(dist, 'kreftjs.js');
|
|
160
|
+
const esb = minify ? deps.loadEsbuild(root) : null;
|
|
161
|
+
let minified = false;
|
|
162
|
+
if (esb) {
|
|
163
|
+
try {
|
|
164
|
+
fs.writeFileSync(runtimeOut, esb.transformSync(fs.readFileSync(runtimeSrc, 'utf8'), { minify: true, target: 'es2020', legalComments: 'none' }).code);
|
|
165
|
+
minified = true;
|
|
166
|
+
} catch (_) { /* fall back to the plain copy */ }
|
|
167
|
+
}
|
|
168
|
+
if (!minified) fs.copyFileSync(runtimeSrc, runtimeOut);
|
|
158
169
|
for (const dir of include) {
|
|
159
170
|
const from = path.resolve(dir);
|
|
160
171
|
if (!fs.existsSync(from)) fail(`--include: ${dir} does not exist.`);
|
package/bin/electron.js
CHANGED
|
@@ -54,11 +54,21 @@ function getDevToolsConfig() {
|
|
|
54
54
|
// ELECTRON_MENU=hide no menu at all
|
|
55
55
|
// Change it while running from the page: window.kreftDesktop.setMenu('show' | 'auto' | 'hide')
|
|
56
56
|
let menuMode = String(process.env.ELECTRON_MENU || 'show').toLowerCase();
|
|
57
|
-
|
|
57
|
+
let defaultMenu = null; // Electron's own menu, read once the app is ready
|
|
58
58
|
function applyMenu(mode) {
|
|
59
59
|
menuMode = ['show', 'auto', 'hide'].includes(mode) ? mode : 'show';
|
|
60
|
-
|
|
60
|
+
if (!defaultMenu) defaultMenu = Menu.getApplicationMenu();
|
|
61
|
+
if (menuMode === 'hide') {
|
|
62
|
+
// macOS keeps one app menu (with Quit) because the system needs it; Windows and Linux lose the bar
|
|
63
|
+
Menu.setApplicationMenu(process.platform === 'darwin'
|
|
64
|
+
? Menu.buildFromTemplate([{ role: 'appMenu' }])
|
|
65
|
+
: null);
|
|
66
|
+
} else {
|
|
67
|
+
Menu.setApplicationMenu(defaultMenu);
|
|
68
|
+
}
|
|
61
69
|
if (mainWindow && process.platform !== 'darwin') {
|
|
70
|
+
if (menuMode === 'hide') mainWindow.removeMenu();
|
|
71
|
+
else mainWindow.setMenu(defaultMenu);
|
|
62
72
|
mainWindow.setAutoHideMenuBar(menuMode === 'auto');
|
|
63
73
|
mainWindow.setMenuBarVisibility(menuMode === 'show');
|
|
64
74
|
}
|
|
@@ -235,6 +245,7 @@ ipcMain.handle('kreft:dialog:save', async (_, options) => {
|
|
|
235
245
|
});
|
|
236
246
|
|
|
237
247
|
app.whenReady().then(() => {
|
|
248
|
+
applyMenu(menuMode);
|
|
238
249
|
createWindow();
|
|
239
250
|
|
|
240
251
|
app.on('activate', () => {
|
|
@@ -431,7 +442,52 @@ function freePort(start) {
|
|
|
431
442
|
});
|
|
432
443
|
}
|
|
433
444
|
|
|
445
|
+
function help() {
|
|
446
|
+
console.log(`
|
|
447
|
+
Kreft + Electron: your app as a desktop program (Windows, macOS, Linux)
|
|
448
|
+
|
|
449
|
+
Commands
|
|
450
|
+
kreft new <name> --electron A new app with desktop support
|
|
451
|
+
kreft electron:init Add desktop support to an existing app (alias: kreft make:electron)
|
|
452
|
+
Writes electron/main.js, electron/preload.js, build/icon.png and the build block
|
|
453
|
+
in package.json. Files that exist are never overwritten.
|
|
454
|
+
kreft electron Open the app in its own window: no browser, no URL (alias: kreft electron:dev)
|
|
455
|
+
--devtools[=right|bottom|left|detach] Open DevTools --no-devtools Do not
|
|
456
|
+
--port <number> Private port for the hidden dev server (default: the next free one)
|
|
457
|
+
kreft electron:build Build the app (kreft build --base ./) and make installers in dist-electron/
|
|
458
|
+
--mac --win --linux Choose the systems (more electron-builder flags work: --arm64, --x64, --dir)
|
|
459
|
+
npm run electron:build:mac .dmg and .zip
|
|
460
|
+
npm run electron:build:win NSIS installer and portable .exe
|
|
461
|
+
npm run electron:build:linux AppImage, .deb and .rpm
|
|
462
|
+
npm run electron:build:all All three
|
|
463
|
+
kreft electron:help This text
|
|
464
|
+
|
|
465
|
+
Window menu ELECTRON_MENU=show (default) | auto (Alt shows it) | hide
|
|
466
|
+
From a page: kreftDesktop.setMenu('hide'), kreftDesktop.getMenu()
|
|
467
|
+
(macOS always keeps one app menu with Quit)
|
|
468
|
+
DevTools ELECTRON_DEVTOOLS=right|bottom|left|detach|false, or F12 / Ctrl+Shift+I
|
|
469
|
+
App icon build/icon.png, a square PNG of 512x512 or more (.icns and .ico are made from it)
|
|
470
|
+
App name build.productName and build.appId in package.json
|
|
471
|
+
Installer info description, homepage, author (with e-mail) and build.linux.maintainer in package.json
|
|
472
|
+
(missing ones are filled in from git when you build; check them)
|
|
473
|
+
From a page if (Kreftjs.isElectron) kreftDesktop.getInfo(), minimize(), maximize(), close(),
|
|
474
|
+
showMessageBox(), showOpenDialog(), showSaveDialog(), openDevTools()
|
|
475
|
+
|
|
476
|
+
Good to know
|
|
477
|
+
- Build each system on that system. On a Mac, .deb and .rpm fail: build them on Linux.
|
|
478
|
+
- npm run build makes the website (paths start at /). electron:build makes the desktop build (--base ./).
|
|
479
|
+
- The packaged app has no backend: frontend-only apps work, full-stack ones (login, database) need a server.
|
|
480
|
+
- Unsigned apps show a warning on macOS and Windows: https://www.electron.build/code-signing
|
|
481
|
+
- Errors: "Electron is not installed locally" -> kreft add -D electron
|
|
482
|
+
"electron-builder is not installed" -> kreft add -D electron-builder
|
|
483
|
+
White window in the app -> run electron:build again (it needs --base ./)
|
|
484
|
+
|
|
485
|
+
Full guide: docs/README.md, "Desktop apps with Electron"
|
|
486
|
+
`);
|
|
487
|
+
}
|
|
488
|
+
|
|
434
489
|
function dev(args = []) {
|
|
490
|
+
if (['help', '--help', '-h'].includes(args[0])) return help();
|
|
435
491
|
const asked = args.findIndex((a) => a === '--port' || a === '-p');
|
|
436
492
|
if (asked >= 0 && Number(args[asked + 1])) return startDev(args, Number(args[asked + 1]));
|
|
437
493
|
return freePort(Number(process.env.PORT) || 8000).then((port) => startDev(args, port));
|
|
@@ -521,6 +577,8 @@ function startDev(args, port) {
|
|
|
521
577
|
}
|
|
522
578
|
|
|
523
579
|
function build(args = []) {
|
|
580
|
+
// --all is a Kreft shortcut for --mac --win --linux (electron-builder has no such flag)
|
|
581
|
+
if (args.includes('--all')) args = [...args.filter((a) => a !== '--all'), ...['--mac', '--win', '--linux'].filter((p) => !args.includes(p))];
|
|
524
582
|
const root = getProjectRoot();
|
|
525
583
|
const electronMain = path.join(root, 'electron', 'main.js');
|
|
526
584
|
if (!fs.existsSync(electronMain)) {
|
|
@@ -574,6 +632,7 @@ function build(args = []) {
|
|
|
574
632
|
|
|
575
633
|
module.exports = {
|
|
576
634
|
init,
|
|
635
|
+
help,
|
|
577
636
|
dev,
|
|
578
637
|
run: dev,
|
|
579
638
|
build,
|
package/bin/kreftjs.js
CHANGED
|
@@ -46,6 +46,7 @@ const commands = {
|
|
|
46
46
|
'electron:dev': (a) => require('./electron.js').dev(a),
|
|
47
47
|
'electron:build': (a) => require('./electron.js').build(a),
|
|
48
48
|
'electron:init': (a) => require('./electron.js').init(a),
|
|
49
|
+
'electron:help': () => require('./electron.js').help(),
|
|
49
50
|
'make:electron': (a) => require('./electron.js').init(a),
|
|
50
51
|
vite: (a) => require('./vite.js').dev(a),
|
|
51
52
|
'vite:dev': (a) => require('./vite.js').dev(a),
|
|
@@ -117,10 +118,10 @@ function help() {
|
|
|
117
118
|
kreft vite:init Add Vite configuration to an existing project (alias: kreft make:vite)
|
|
118
119
|
|
|
119
120
|
Desktop (Electron.js):
|
|
120
|
-
kreft electron
|
|
121
|
-
kreft electron:
|
|
122
|
-
kreft electron:build Build static bundle and package desktop app with electron-builder
|
|
121
|
+
kreft electron Open the app in a desktop window only: no browser, no URL (alias: kreft electron:dev)
|
|
122
|
+
kreft electron:build Build and make installers (--mac, --win, --linux; or npm run electron:build:all)
|
|
123
123
|
kreft electron:init Add Electron support to an existing project (alias: kreft make:electron)
|
|
124
|
+
kreft electron:help Everything about desktop apps: menu, icon, installers, errors
|
|
124
125
|
|
|
125
126
|
The backend (kreft list shows every command, yours too):
|
|
126
127
|
kreft key:generate Set the application encryption key in .env (--show: print only)
|
|
@@ -164,6 +165,7 @@ function help() {
|
|
|
164
165
|
--prerender [paths] Also save every page as ready HTML (needs: npm i -D jsdom)
|
|
165
166
|
--include <folder> Also copy this folder into the output (for example docs)
|
|
166
167
|
--no-htaccess Do not write dist/.htaccess (page-address rules for Apache and Hostinger)
|
|
168
|
+
--no-minify Copy kreftjs.js as it is (by default it is minified when esbuild is installed)
|
|
167
169
|
kreft add <packages...> Install npm packages with strict security gatekeeper (alias: kreft install, kreft i)
|
|
168
170
|
-D, --dev Install as devDependency
|
|
169
171
|
-y, --yes Auto-confirm unverified community packages in CI/CD
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# الفصل الأول: البداية
|
|
2
|
+
|
|
3
|
+
## ما هو Kreft؟
|
|
4
|
+
|
|
5
|
+
Kreft (يُكتب `kreftjs`) إطار عمل صغير، تفاعلي (reactive)، له لغة مكوّنات خاصة به: ملفات `.kreft`. تكتب في الملف الواحد حالتك وقيمك المشتقة وأفعالك بكلمات بسيطة، ثم تصف الصفحة في `<view>`. ويأتي مع واجهة خلفية كاملة على Node.js (مسارات، ومتحكمات، ونماذج، وترحيلات، وطوابير، وبريد)، فيغطي المشروع الواحد التطبيق بأكمله.
|
|
6
|
+
|
|
7
|
+
> **ملاحظة:** الإصدار الحالي تجريبي (`0.0.x-beta`). كل ما في هذا الكتاب جُرِّب على الإصدار الذي صدر معه، لكن واجهات الإطار قد تتغير بين الإصدارات التجريبية. راجع `kreft --version` وملف `docs/README.md` (بالإنجليزية) عند الشك.
|
|
8
|
+
|
|
9
|
+
لماذا قد تختاره؟
|
|
10
|
+
|
|
11
|
+
- **لغة واحدة للمكوّن:** HTML ومنطق وتنسيق في ملف واحد، بلا ديكورات ولا وحدات (modules) تتعلمها.
|
|
12
|
+
- **بدون إعداد:** `kreft new` ثم `kreft dev`. لا ملف إعداد لأداة تجميع.
|
|
13
|
+
- **واجهة خلفية جاهزة:** تسجيل دخول، وتحقق من البريد، واستعادة كلمة المرور، ولوحة إدارة، ومصادقة ثنائية.
|
|
14
|
+
- **تطبيقات سطح المكتب:** `kreft new --electron` ثم تبني مثبّتات لـ Windows وmacOS وLinux.
|
|
15
|
+
- **دعم RTL من الأساس:** تبديل اللغة واتجاه الصفحة من دالة واحدة (مهم لنا نحن العرب، وله فصل كامل).
|
|
16
|
+
|
|
17
|
+
## التثبيت
|
|
18
|
+
|
|
19
|
+
المتطلبات: Node.js (يُفضَّل 22 أو أحدث) وnpm.
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g kreftjs
|
|
23
|
+
kreft --version # مثال: 0.0.19-beta
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
للتحقق من أن كل شيء سليم:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
kreft about
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
وللحصول على تلوين الملفات وملفات المقتطفات (snippets) في VS Code أو Cursor:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
kreft vscode
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## أول تطبيق
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
kreft new my-app # يسألك: JavaScript أم TypeScript؟
|
|
42
|
+
cd my-app
|
|
43
|
+
npm run dev
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
افتح العنوان الذي يطبعه الطرفية (عادة `http://localhost:8000`؛ وإن كان المنفذ مشغولًا يُستخدم التالي).
|
|
47
|
+
|
|
48
|
+
خيارات مفيدة عند الإنشاء:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
kreft new shop --db mysql --ts # TypeScript وقاعدة MySQL
|
|
52
|
+
kreft new site --ui tailwind --no-auth # Tailwind بدون صفحات تسجيل الدخول
|
|
53
|
+
kreft new desk --electron # مع دعم تطبيقات سطح المكتب
|
|
54
|
+
kreft new app-name --ui bootstrap --no-auth
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
> **تنبيه:** اكتب قيم الخيارات كما هي بالضبط: `bootstrap` و`tailwind` و`bulma` و`pico`. أي قيمة أخرى توقف الأمر مع رسالة تعرض القيم المسموحة.
|
|
58
|
+
|
|
59
|
+
يأتي المشروع الجديد (إن لم تستعمل `--no-auth`) بصفحات الدخول والتسجيل واستعادة كلمة المرور وتأكيد البريد والملف الشخصي ولوحة الإدارة. وعند تشغيل `npm run dev` تُنشأ الجداول ومستخدم تجريبي:
|
|
60
|
+
|
|
61
|
+
- البريد: `test@example.com`
|
|
62
|
+
- كلمة المرور: `password`
|
|
63
|
+
|
|
64
|
+
> **تحذير:** هذا المستخدم للتطوير المحلي فقط. احذفه أو لا تشغّل `--seed` أبدًا على قاعدة بيانات حقيقية.
|
|
65
|
+
|
|
66
|
+
رسائل البريد (تأكيد، استعادة) تُطبع في الطرفية إلى أن تضبط `MAIL_URL`.
|
|
67
|
+
|
|
68
|
+
## أصغر تطبيق ممكن
|
|
69
|
+
|
|
70
|
+
يمكنك استعمال Kreft بلا مشروع كامل. التطبيق صفحة HTML وملفات `.kreft`:
|
|
71
|
+
|
|
72
|
+
```html
|
|
73
|
+
<!-- index.html -->
|
|
74
|
+
<div id="app"></div>
|
|
75
|
+
<script src="kreftjs.js"></script>
|
|
76
|
+
<script>
|
|
77
|
+
Kreftjs.app('App.kreft').mount('#app')
|
|
78
|
+
</script>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<!-- App.kreft -->
|
|
83
|
+
state name = 'العالم'
|
|
84
|
+
|
|
85
|
+
<view>
|
|
86
|
+
<h1>مرحبًا يا {name}</h1>
|
|
87
|
+
<input k-model="name">
|
|
88
|
+
</view>
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
> **تحذير:** ملفات `.kreft` تحتاج خادمًا. المتصفحات ترفض تحميل الملفات من `file://`، فافتح التطبيق دائمًا عبر `npm run dev` أو أي خادم.
|
|
92
|
+
|
|
93
|
+
## بنية المشروع
|
|
94
|
+
|
|
95
|
+
ينشئ `kreft new` مجلدين لا يختلطان أبدًا: `frontend/` هو ما يصل المتصفح، و`backend/` هو الخادم ولا يمكن الوصول إليه عبر HTTP.
|
|
96
|
+
|
|
97
|
+
```text
|
|
98
|
+
my-app/
|
|
99
|
+
├── frontend/
|
|
100
|
+
│ ├── index.html نقطة الدخول
|
|
101
|
+
│ ├── App.kreft المكوّن الجذر وحاوية الموجِّه
|
|
102
|
+
│ ├── routes/web.kreft مسارات الصفحات
|
|
103
|
+
│ ├── layouts/ app.kreft (بعد الدخول)، guest.kreft (صفحات الدخول)
|
|
104
|
+
│ ├── pages/ ملف .kreft لكل شاشة
|
|
105
|
+
│ ├── components/ مكوّنات قابلة لإعادة الاستخدام
|
|
106
|
+
│ ├── ui.css نظام التصميم
|
|
107
|
+
│ └── tests/ اختبارات المكوّنات
|
|
108
|
+
├── backend/
|
|
109
|
+
│ ├── config/ app.js, auth.js, database.js, redis.js, session.js
|
|
110
|
+
│ ├── app/
|
|
111
|
+
│ │ ├── Http/ Controllers, Middleware, Requests, Resources
|
|
112
|
+
│ │ ├── Models/ User, PersonalAccessToken
|
|
113
|
+
│ │ └── Auth/ مساعدات الجلسات
|
|
114
|
+
│ ├── database/ migrations, seeders, factories
|
|
115
|
+
│ └── routes/ api.js, auth.js, console.js
|
|
116
|
+
├── .env الأسرار والإعدادات (لا ترفعه إلى Git أبدًا)
|
|
117
|
+
├── package.json
|
|
118
|
+
└── kreftjs.config.json خيارات سطر الأوامر
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
لماذا الفصل مهم؟
|
|
122
|
+
|
|
123
|
+
- `kreft dev` و`kreft build` يقدّمان `frontend/` فقط. أما `backend/` وملفات قاعدة البيانات و`.env` فلا عنوان ويب لها.
|
|
124
|
+
- على macOS وLinux يمنح `kreft new` المجلد `backend/` والملف `.env` صلاحيات يقرؤها المالك فقط.
|
|
125
|
+
- ملفات مثل `.env` و`*.db` و`*.pem` و`package.json` مرفوضة حتى لو طُلبت بالاسم.
|
|
126
|
+
|
|
127
|
+
## إضافة مكتبة CSS
|
|
128
|
+
|
|
129
|
+
أي مكتبة تعمل. أضف `<link>` في `index.html`، أو ثبّتها واستورد ملفها من ملف `.kreft`:
|
|
130
|
+
|
|
131
|
+
```html
|
|
132
|
+
import 'bootstrap/dist/css/bootstrap.min.css' // npm i bootstrap
|
|
133
|
+
import './theme.css' // ملفك الخاص بجانب هذا الملف
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## حزم npm في المتصفح
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
kreft add dayjs nanoid lodash
|
|
140
|
+
kreft add -D esbuild # مرة واحدة لكل مشروع: يجهّز الحزم للمتصفح
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```html
|
|
144
|
+
import dayjs from 'dayjs'
|
|
145
|
+
import { nanoid } from 'nanoid'
|
|
146
|
+
|
|
147
|
+
state id = nanoid()
|
|
148
|
+
|
|
149
|
+
<view>
|
|
150
|
+
<p>{dayjs().format('YYYY-MM-DD')}</p>
|
|
151
|
+
</view>
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
الأمر `kreft add` نسخة أكثر أمانًا من `npm install`: يمنع سكربتات التثبيت افتراضيًا، ويتحقق من أخطاء الكتابة المتعمدة في أسماء الحزم (typosquatting)، وينبّه إلى الحزم التي نُشرت قبل أقل من 14 يومًا، ثم يشغّل `npm audit`.
|
|
155
|
+
|
|
156
|
+
## أوامر ستستخدمها كل يوم
|
|
157
|
+
|
|
158
|
+
| الأمر | وظيفته |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `kreft new my-app` | ينشئ مشروعًا |
|
|
161
|
+
| `kreft dev` | خادم التطوير مع إعادة تحميل فورية |
|
|
162
|
+
| `kreft build` | يصرّف التطبيق إلى ملفات عادية في `dist/` |
|
|
163
|
+
| `kreft serve dist` | يشغّل التطبيق المبني للمستخدمين الحقيقيين |
|
|
164
|
+
| `kreft list` | يعرض كل أوامر نسختك |
|
|
165
|
+
| `kreft help` | خيارات الأوامر الرئيسية |
|
|
166
|
+
| `kreft tinker` | طرفية تفاعلية مع نماذجك (`await User.count()`) |
|
|
167
|
+
| `kreft update` | يحدّث الحزم وملف `kreftjs.js` |
|
|
168
|
+
|
|
169
|
+
تدريب سريع: أنشئ مشروعًا، وغيّر كلمة في `frontend/pages/` وراقب الصفحة تتبدل في المتصفح دون إعادة تحميل وبدون ضياع الحالة. هذه هي إعادة التحميل الفورية (hot reload).
|