@aravinthan_p/appnest-engine 1.0.20 → 1.0.22
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 +73 -62
- package/appnest-command-line/appnest-command.js +41 -28
- package/appnest-command-line/frameworkDocsUtils.js +73 -0
- package/appnest-command-line/precheckUtils.js +7 -20
- package/appnest-command-line/setupAppUtils.js +15 -0
- package/appnest-command-line/validateUtils/index.js +2 -8
- package/appnest-command-line/validateUtils/lint/lint-backend.js +4 -3
- package/appnest-command-line/validateUtils/lint/lint-frontend.js +4 -4
- package/appnest-command-line/validateUtils/lint/lint-utils.js +67 -56
- package/appnest-command-line/validateUtils/lint/lint.js +5 -5
- package/appnest-command-line/validateUtils/manifestUtils.js +359 -120
- package/appnest-command-line/zipUtils.js +1 -1
- package/appnest-engine-commands.md +46 -0
- package/appnest-install-frontend/package.json +1 -1
- package/appnest-install-frontend/vite.config.js +4 -4
- package/appnest-proxy/server.js +20 -14
- package/cli.js +6 -4
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
# Appnest Engine
|
|
2
2
|
|
|
3
|
-
Development CLI and runtime for Appnest apps. It wires your **app-backend**, **app-frontend**, and optional **app-
|
|
3
|
+
Development CLI and runtime for Appnest apps. It wires your **app-backend**, **app-frontend**, and optional **app-install-frontend** behind a single proxy, runs checks, and helps you bundle and zip the app for distribution.
|
|
4
|
+
|
|
5
|
+
**Package:** `@aravinthan_p/appnest-engine` · **CLI binary:** `appnest-engine`
|
|
6
|
+
|
|
7
|
+
For a focused list of commands, see **[appnest-engine-commands.md](./appnest-engine-commands.md)**.
|
|
4
8
|
|
|
5
9
|
---
|
|
6
10
|
|
|
7
11
|
## Overview
|
|
8
12
|
|
|
9
|
-
Appnest Engine runs
|
|
13
|
+
Appnest Engine runs from the **developer’s project directory** (where `app-backend`, `app-frontend`, etc. live). It provides:
|
|
10
14
|
|
|
11
|
-
- **CLI** – Commands for
|
|
12
|
-
- **Proxy** – One server on port **3000** that routes traffic to your app’s backend and frontends.
|
|
13
|
-
- **Engine packages** – Shared runtime
|
|
15
|
+
- **CLI** – Commands for init, precheck, install, start, validate, bundle, and pack (see [appnest-engine-commands.md](./appnest-engine-commands.md)).
|
|
16
|
+
- **Proxy** – One server on port **3000** (default) that routes traffic to your app’s backend and frontends.
|
|
17
|
+
- **Engine packages** – Shared runtime (proxy, backend layer, Vite dev servers) that load your app code from the current directory via `ORIGINAL_CWD`.
|
|
14
18
|
|
|
15
19
|
---
|
|
16
20
|
|
|
@@ -18,14 +22,14 @@ Appnest Engine runs in the **developer’s project directory** (where `app-backe
|
|
|
18
22
|
|
|
19
23
|
```
|
|
20
24
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
21
|
-
│ Developer runs: appnest-engine
|
|
25
|
+
│ Developer runs: appnest-engine app start │
|
|
22
26
|
│ (from their app project directory: app-backend, app-frontend, etc.) │
|
|
23
27
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
24
28
|
│
|
|
25
29
|
▼
|
|
26
30
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
27
31
|
│ CLI (cli.js) │
|
|
28
|
-
│ • Parses "
|
|
32
|
+
│ • Parses "app start" → appnestAction("start") │
|
|
29
33
|
│ • runtimeUtils.runApp() starts only: appnest-proxy │
|
|
30
34
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
31
35
|
│
|
|
@@ -33,31 +37,31 @@ Appnest Engine runs in the **developer’s project directory** (where `app-backe
|
|
|
33
37
|
┌─────────────────────────────────────────────────────────────────────────┐
|
|
34
38
|
│ appnest-proxy (port 3000) │
|
|
35
39
|
│ • Reads .env from ORIGINAL_CWD (developer’s project) │
|
|
36
|
-
│ • Allocates ports for app-backend, app-frontend, app-
|
|
37
|
-
│ • Starts appnest-backend (loads user’s app-backend/server.js)
|
|
40
|
+
│ • Allocates ports for app-backend, app-frontend, app-install-frontend │
|
|
41
|
+
│ • Starts appnest-backend (loads user’s app-backend/server.js) │
|
|
38
42
|
│ • Starts appnest-frontend (Vite dev server for app-frontend) │
|
|
39
|
-
│ • Starts appnest-install-frontend if
|
|
43
|
+
│ • Starts appnest-install-frontend if app-install-frontend exists │
|
|
40
44
|
│ • Proxies: │
|
|
41
|
-
│ /app-backend/* → app-backend
|
|
42
|
-
│ /app-frontend/* → app-frontend
|
|
43
|
-
│ /app-
|
|
44
|
-
│ • Watches app-backend / app-frontend and restarts on change (backend)
|
|
45
|
-
│ or on config change (frontends); HMR for normal frontend edits
|
|
45
|
+
│ /app-backend/* → app-backend │
|
|
46
|
+
│ /app-frontend/* → app-frontend │
|
|
47
|
+
│ /app-install-frontend/* → installation UI │
|
|
48
|
+
│ • Watches app-backend / app-frontend and restarts on change (backend) │
|
|
49
|
+
│ or on config change (frontends); HMR for normal frontend edits │
|
|
46
50
|
└─────────────────────────────────────────────────────────────────────────┘
|
|
47
51
|
│
|
|
48
52
|
┌───────────────────────────┼───────────────────────────┐
|
|
49
53
|
▼ ▼ ▼
|
|
50
54
|
┌──────────────────┐ ┌────────────────────┐ ┌────────────────────────────┐
|
|
51
|
-
│ appnest-backend
|
|
52
|
-
│ (Express layer)
|
|
53
|
-
│ Loads user’s
|
|
54
|
-
│ app-backend/
|
|
55
|
-
│ server.js
|
|
55
|
+
│ appnest-backend │ │ appnest-frontend │ │ appnest-install-frontend │
|
|
56
|
+
│ (Express layer) │ │ (Vite dev server) │ │ (Vite dev server) │
|
|
57
|
+
│ Loads user’s │ │ Serves user’s │ │ Serves user’s │
|
|
58
|
+
│ app-backend/ │ │ app-frontend/ │ │ app-install-frontend/ │
|
|
59
|
+
│ server.js │ │ │ │ (optional) │
|
|
56
60
|
└──────────────────┘ └────────────────────┘ └────────────────────────────┘
|
|
57
61
|
```
|
|
58
62
|
|
|
59
63
|
- **User directory** = where the developer runs the CLI (`process.cwd()` → `ORIGINAL_CWD` for child processes).
|
|
60
|
-
- **Engine packages** = `appnest-backend`, `appnest-frontend`, `appnest-install-frontend`, `appnest-proxy
|
|
64
|
+
- **Engine packages** (in this repo) = `appnest-backend`, `appnest-frontend`, `appnest-install-frontend`, `appnest-proxy`. They load and serve the **app** folders from the user directory.
|
|
61
65
|
|
|
62
66
|
---
|
|
63
67
|
|
|
@@ -65,78 +69,85 @@ Appnest Engine runs in the **developer’s project directory** (where `app-backe
|
|
|
65
69
|
|
|
66
70
|
| Path | Role |
|
|
67
71
|
|------|------|
|
|
68
|
-
| `cli.js` | Entry point for `appnest-engine
|
|
72
|
+
| `cli.js` | Entry point for `appnest-engine`; Commander; delegates to `appnest-command-line`. |
|
|
69
73
|
| `index.js` | Exports `appnestAction` for programmatic use. |
|
|
70
|
-
| `package.json` | Root package; `bin.appnest-engine` → `cli.js`; version
|
|
71
|
-
| **appnest-command-line/** |
|
|
72
|
-
| **appnest-proxy/** | Express
|
|
73
|
-
| **appnest-backend/** | Express app that loads the user’s `app-backend/server.js`
|
|
74
|
-
| **appnest-frontend/** | Vite dev server for the user’s `app-frontend`. |
|
|
75
|
-
| **appnest-install-frontend/** | Vite dev server for the user’s `app-
|
|
74
|
+
| `package.json` | Root package; `bin.appnest-engine` → `cli.js`; version used by CLI. |
|
|
75
|
+
| **appnest-command-line/** | CLI actions: init, precheck, install, start, validate, bundle, pack. |
|
|
76
|
+
| **appnest-proxy/** | Express on port 3000; reads user `.env`; starts backend + frontends; proxies and file watching. |
|
|
77
|
+
| **appnest-backend/** | Express app that loads the user’s `app-backend/server.js` under `/app-backend`. |
|
|
78
|
+
| **appnest-frontend/** | Vite dev server / build tooling for the user’s `app-frontend`. |
|
|
79
|
+
| **appnest-install-frontend/** | Vite dev server / build for the user’s optional `app-install-frontend`. |
|
|
76
80
|
|
|
77
|
-
|
|
81
|
+
**Developer project** (user directory) typically includes:
|
|
78
82
|
|
|
79
83
|
- `app-backend/` (e.g. `server.js`)
|
|
80
84
|
- `app-frontend/` (e.g. Vite/React app)
|
|
81
|
-
- Optional: `app-
|
|
82
|
-
- `.env`
|
|
85
|
+
- Optional: `app-install-frontend/`
|
|
86
|
+
- `.env` — proxy reads this for ports, `CLIENT_SCRIPT_URL`, `PROXY_DEBUG_LOGS`, etc.
|
|
83
87
|
|
|
84
88
|
---
|
|
85
89
|
|
|
86
90
|
## Installation
|
|
87
91
|
|
|
92
|
+
From the **engine** repo root:
|
|
93
|
+
|
|
88
94
|
```bash
|
|
89
|
-
cd appnest-engine
|
|
90
95
|
npm install
|
|
91
96
|
```
|
|
92
97
|
|
|
93
|
-
|
|
98
|
+
That installs **root** dependencies only (`commander`, `eslint`, `stylelint`, …). To install dependencies inside each engine package (`appnest-backend`, `appnest-frontend`, `appnest-install-frontend`, `appnest-proxy`), run:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
appnest-engine app install-packages
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
(Run from anywhere with the CLI on your `PATH`, or use `node path/to/cli.js app install-packages` from the engine repo.)
|
|
94
105
|
|
|
95
106
|
---
|
|
96
107
|
|
|
97
108
|
## CLI usage
|
|
98
109
|
|
|
99
|
-
From the **appnest-engine** directory, or with the `appnest-engine` binary on `PATH`:
|
|
100
|
-
|
|
101
110
|
| Command | Description |
|
|
102
111
|
|---------|-------------|
|
|
103
|
-
| `appnest-engine --version` | Print version (
|
|
104
|
-
| `appnest-engine
|
|
105
|
-
| `appnest-engine
|
|
106
|
-
| `appnest-engine
|
|
107
|
-
| `appnest-engine
|
|
108
|
-
| `appnest-engine
|
|
109
|
-
| `appnest-engine
|
|
110
|
-
| `appnest-engine
|
|
111
|
-
| `appnest-engine
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
112
|
+
| `appnest-engine --version` | Print engine version (root `package.json`). |
|
|
113
|
+
| `appnest-engine app init` | Download Appnest base code from GitHub into the current directory. |
|
|
114
|
+
| `appnest-engine app precheck` | Node.js (≥22) and existence of all configured engine + app paths. |
|
|
115
|
+
| `appnest-engine app install-packages` | `npm install` in `appnest-backend`, `appnest-frontend`, `appnest-install-frontend`, `appnest-proxy`. |
|
|
116
|
+
| `appnest-engine app start` | Start **appnest-proxy**; proxy starts backend + frontends and proxies traffic. |
|
|
117
|
+
| `appnest-engine app bundle-frontend` | Run `npm run build` in `appnest-frontend` and `appnest-install-frontend` (builds into the **user’s** app folders via `ORIGINAL_CWD`). |
|
|
118
|
+
| `appnest-engine app pack` | Runs **bundle-frontend**, then packages `app-frontend`, `app-backend`, `app-install-frontend` (+ `manifest.json`) into `appnest-app-pack/` and a timestamped zip under `app-pack-zip/`. |
|
|
119
|
+
| `appnest-engine app validate` | ESLint (and related checks) on `app-backend` / `app-frontend`; validates `manifest.json`. |
|
|
120
|
+
| `appnest-engine app ai-context` | Download AI context into `appnest-ai-context/` at project root. Replaces existing folder if present. |
|
|
121
|
+
| `appnest-engine help` | Print short help for available `app` actions. |
|
|
122
|
+
|
|
123
|
+
**Typical developer flow**
|
|
124
|
+
|
|
125
|
+
1. In the **app project** directory: `appnest-engine app init` (if needed).
|
|
126
|
+
2. `appnest-engine app precheck` (optional).
|
|
127
|
+
3. `appnest-engine app install-packages` (after cloning or updating the engine).
|
|
128
|
+
4. From the **app project** directory: `appnest-engine app start` → proxy on port **3000**, e.g. `http://localhost:3000/app-frontend/`, API at `http://localhost:3000/app-backend/`.
|
|
119
129
|
|
|
120
130
|
---
|
|
121
131
|
|
|
122
|
-
## Runtime flow (
|
|
132
|
+
## Runtime flow (`start`)
|
|
123
133
|
|
|
124
|
-
1. **CLI**
|
|
125
|
-
2. **Proxy** reads `.env
|
|
126
|
-
- Starts **appnest-backend** (
|
|
134
|
+
1. **CLI** starts **appnest-proxy** with `ORIGINAL_CWD` = current working directory.
|
|
135
|
+
2. **Proxy** reads `.env`, allocates ports, then:
|
|
136
|
+
- Starts **appnest-backend** (user’s `app-backend/server.js`).
|
|
127
137
|
- Starts **appnest-frontend** (Vite for `app-frontend`).
|
|
128
|
-
- If `app-
|
|
129
|
-
3.
|
|
130
|
-
- `/app-backend` →
|
|
131
|
-
- `/app-frontend` →
|
|
132
|
-
- `/app-
|
|
133
|
-
4. **
|
|
138
|
+
- If `app-install-frontend` exists, starts **appnest-install-frontend**.
|
|
139
|
+
3. Routes (defaults; ports from `.env` where applicable):
|
|
140
|
+
- `/app-backend` → backend
|
|
141
|
+
- `/app-frontend` → main frontend
|
|
142
|
+
- `/app-install-frontend` → installation UI
|
|
143
|
+
4. **Watching**: `app-backend` changes restart the backend; `vite.config.js` / `.env` changes can restart frontends; ordinary source edits use Vite HMR.
|
|
134
144
|
|
|
135
145
|
---
|
|
136
146
|
|
|
137
147
|
## Zip / bundle flow
|
|
138
148
|
|
|
139
|
-
- **`
|
|
149
|
+
- **`bundle-frontend`** builds both engine frontends so output lands in the user’s `app-frontend/dist` and `app-install-frontend/dist` (when those trees exist).
|
|
150
|
+
- **`pack`** runs **bundle-frontend**, may rewrite paths in `app-frontend/dist/index.html`, copies `app-frontend`, `app-backend`, `app-install-frontend`, and `manifest.json` into **`appnest-app-pack/`**, then creates **`app-pack-zip/app-pack-<timestamp>.zip`**.
|
|
140
151
|
|
|
141
152
|
---
|
|
142
153
|
|
|
@@ -7,7 +7,8 @@ const { precheck } = require('./precheckUtils');
|
|
|
7
7
|
const { bundleFrontend } = require('./bundleUtils');
|
|
8
8
|
const { zipAppProject } = require('./zipUtils');
|
|
9
9
|
const { setupApp } = require('./setupAppUtils');
|
|
10
|
-
const { validateApp
|
|
10
|
+
const { validateApp } = require('./validateUtils');
|
|
11
|
+
const { downloadFrameworkDocs } = require('./frameworkDocsUtils');
|
|
11
12
|
|
|
12
13
|
// Folders setup
|
|
13
14
|
const projects = {
|
|
@@ -16,30 +17,41 @@ const projects = {
|
|
|
16
17
|
'appnest-install-frontend': path.join(__dirname, '../appnest-install-frontend'),
|
|
17
18
|
'appnest-proxy': path.join(__dirname, '../appnest-proxy'),
|
|
18
19
|
'app-frontend': path.join(userDir, './app-frontend'),
|
|
19
|
-
'app-
|
|
20
|
+
'app-install-frontend': path.join(userDir, './app-install-frontend'),
|
|
20
21
|
'app-backend': path.join(userDir, './app-backend'),
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
// --- CLI Controller ---
|
|
24
25
|
|
|
26
|
+
const HELP_TEXT = `
|
|
27
|
+
Available actions:
|
|
28
|
+
|
|
29
|
+
appnest-engine app init Setup the app project
|
|
30
|
+
appnest-engine app precheck Check Node.js (>=22) and paths
|
|
31
|
+
appnest-engine app install-packages Install npm packages in all engine packages
|
|
32
|
+
appnest-engine app start Start proxy (backend + frontends)
|
|
33
|
+
appnest-engine app bundle-frontend Build app-frontend and app-installation-frontend dist via engine Vite
|
|
34
|
+
appnest-engine app pack Bundle frontends, then zip app folders into appnest-app-pack
|
|
35
|
+
appnest-engine app validate Validate app-backend, app-frontend, and manifest
|
|
36
|
+
appnest-engine app ai-context Download AI context to appnest-ai-context/
|
|
37
|
+
|
|
38
|
+
Show this list: appnest-engine app | appnest-engine app help | appnest-engine app -h
|
|
39
|
+
`;
|
|
40
|
+
|
|
25
41
|
const helpAction = () => {
|
|
26
|
-
console.log(
|
|
27
|
-
Appnest Command Line Interface, Available actions:
|
|
28
|
-
appnest-engine run setup-app Setup the app project
|
|
29
|
-
appnest-engine run precheck Check Node.js (>=22) and ngrok installation
|
|
30
|
-
appnest-engine run install-packages Install npm packages for both projects
|
|
31
|
-
appnest-engine run run-all Run "npm run dev" in both projects
|
|
32
|
-
appnest-engine run zip-app Zip the frontend and backend app projects
|
|
33
|
-
appnest-engine run lint Lint app-backend and app-frontend JavaScript
|
|
34
|
-
appnest-engine run lint-fix Lint and auto-fix where possible
|
|
35
|
-
`);
|
|
42
|
+
console.log('\n Appnest Command Line Interface —' + HELP_TEXT);
|
|
36
43
|
}
|
|
37
44
|
|
|
38
45
|
async function appnestAction(action) {
|
|
39
46
|
const userDir = process.cwd();
|
|
47
|
+
const normalizedAction = (action || '').trim().toLowerCase();
|
|
48
|
+
if (!normalizedAction || normalizedAction === 'help' || normalizedAction === '-h' || normalizedAction === '--help') {
|
|
49
|
+
helpAction();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
40
52
|
console.log('📂 User Directory from appnest-command.js', userDir);
|
|
41
|
-
switch (
|
|
42
|
-
case '
|
|
53
|
+
switch (normalizedAction) {
|
|
54
|
+
case 'init':
|
|
43
55
|
setupApp();
|
|
44
56
|
break;
|
|
45
57
|
case 'precheck':
|
|
@@ -48,35 +60,36 @@ async function appnestAction(action) {
|
|
|
48
60
|
case 'install-packages':
|
|
49
61
|
installPackages({ projects });
|
|
50
62
|
break;
|
|
51
|
-
case '
|
|
63
|
+
case 'start':
|
|
52
64
|
runApp({ projects });
|
|
53
65
|
break;
|
|
54
|
-
case '
|
|
66
|
+
case 'pack':
|
|
55
67
|
zipAppProject({ projects });
|
|
56
68
|
break;
|
|
57
69
|
case 'bundle-frontend':
|
|
58
70
|
bundleFrontend({ projects });
|
|
59
71
|
break;
|
|
60
|
-
case '
|
|
72
|
+
case 'validate':
|
|
61
73
|
await validateApp({ projects });
|
|
62
74
|
break;
|
|
63
|
-
case '
|
|
64
|
-
|
|
75
|
+
case 'ai-context':
|
|
76
|
+
downloadFrameworkDocs();
|
|
65
77
|
break;
|
|
66
78
|
default:
|
|
67
79
|
console.log(`
|
|
68
|
-
❓ Unknown action: "${
|
|
80
|
+
❓ Unknown action: "${normalizedAction}"
|
|
69
81
|
Available actions:
|
|
70
82
|
|
|
71
|
-
appnest-engine
|
|
72
|
-
appnest-engine
|
|
73
|
-
appnest-engine
|
|
74
|
-
appnest-engine
|
|
75
|
-
appnest-engine
|
|
76
|
-
appnest-engine
|
|
77
|
-
appnest-engine
|
|
83
|
+
appnest-engine app init Setup the app project
|
|
84
|
+
appnest-engine app precheck Check Node.js (>=22) and paths
|
|
85
|
+
appnest-engine app install-packages Install npm packages in all engine packages
|
|
86
|
+
appnest-engine app start Start proxy (backend + frontends)
|
|
87
|
+
appnest-engine app bundle-frontend Build user app-frontend and app-install-frontend dist
|
|
88
|
+
appnest-engine app pack Bundle frontends, then zip app folders
|
|
89
|
+
appnest-engine app validate Validate app-backend, app-frontend, and manifest
|
|
90
|
+
appnest-engine app ai-context Download AI context to appnest-ai-context/
|
|
78
91
|
`);
|
|
79
92
|
}
|
|
80
93
|
}
|
|
81
94
|
|
|
82
|
-
module.exports = { appnestAction, helpAction };
|
|
95
|
+
module.exports = { appnestAction, helpAction, HELP_TEXT };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
|
|
5
|
+
const frameworkDocsUrl =
|
|
6
|
+
'https://github.com/AravinthanPraba007/appnest-sample-tools/archive/refs/heads/main.zip';
|
|
7
|
+
|
|
8
|
+
const downloadFrameworkDocs = () => {
|
|
9
|
+
const userDir = process.cwd();
|
|
10
|
+
const targetDir = path.join(userDir, 'appnest-ai-context');
|
|
11
|
+
const zipFileName = 'appnest-sample-tools-main.zip';
|
|
12
|
+
const zipFilePath = path.join(userDir, zipFileName);
|
|
13
|
+
const tempExtractDir = path.join(userDir, '.appnest-ai-context-tmp');
|
|
14
|
+
|
|
15
|
+
console.log('📥 Downloading AI context...\n');
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
// Delete appnest-ai-context if it exists
|
|
19
|
+
if (fs.existsSync(targetDir)) {
|
|
20
|
+
console.log('🗑️ Removing existing appnest-ai-context folder...');
|
|
21
|
+
fs.rmSync(targetDir, { recursive: true, force: true });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (fs.existsSync(zipFilePath)) {
|
|
25
|
+
fs.rmSync(zipFilePath, { force: true });
|
|
26
|
+
}
|
|
27
|
+
if (fs.existsSync(tempExtractDir)) {
|
|
28
|
+
fs.rmSync(tempExtractDir, { recursive: true, force: true });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
console.log('⬇️ Downloading AI context zip...');
|
|
32
|
+
execSync(`curl -L -o "${zipFilePath}" "${frameworkDocsUrl}"`, {
|
|
33
|
+
stdio: 'inherit',
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
console.log('📦 Extracting...');
|
|
37
|
+
fs.mkdirSync(tempExtractDir, { recursive: true });
|
|
38
|
+
execSync(`unzip -q "${zipFilePath}" -d "${tempExtractDir}"`, {
|
|
39
|
+
stdio: 'inherit',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const extractedItems = fs.readdirSync(tempExtractDir);
|
|
43
|
+
if (extractedItems.length === 0) {
|
|
44
|
+
throw new Error('Zip extraction produced no files.');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const rootExtractedPath = path.join(tempExtractDir, extractedItems[0]);
|
|
48
|
+
if (!fs.existsSync(rootExtractedPath)) {
|
|
49
|
+
throw new Error('Extracted folder not found.');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.log('📂 Copying to appnest-ai-context/...');
|
|
53
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
54
|
+
const entries = fs.readdirSync(rootExtractedPath);
|
|
55
|
+
for (const entry of entries) {
|
|
56
|
+
const fromPath = path.join(rootExtractedPath, entry);
|
|
57
|
+
const toPath = path.join(targetDir, entry);
|
|
58
|
+
fs.cpSync(fromPath, toPath, { recursive: true, force: true });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
fs.rmSync(tempExtractDir, { recursive: true, force: true });
|
|
62
|
+
fs.rmSync(zipFilePath, { force: true });
|
|
63
|
+
|
|
64
|
+
console.log('✅ AI context downloaded to appnest-ai-context/\n');
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('❌ Failed to download AI context:', error.message);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
module.exports = {
|
|
72
|
+
downloadFrameworkDocs,
|
|
73
|
+
};
|
|
@@ -4,7 +4,6 @@ const { runCommand } = require('./runCommandUtils');
|
|
|
4
4
|
const precheck = ({ projects }) => {
|
|
5
5
|
console.log('🔍 Running system precheck...\n');
|
|
6
6
|
let nodeCheckPassed = false;
|
|
7
|
-
let ngrokCheckPassed = false;
|
|
8
7
|
let allPathsExist = true;
|
|
9
8
|
|
|
10
9
|
// Check Node.js version
|
|
@@ -23,27 +22,20 @@ const precheck = ({ projects }) => {
|
|
|
23
22
|
}
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
// Check ngrok
|
|
27
|
-
const ngrokVersion = runCommand('ngrok --version');
|
|
28
|
-
if (ngrokVersion) {
|
|
29
|
-
console.log(`✅ ngrok is installed (${ngrokVersion}).`);
|
|
30
|
-
ngrokCheckPassed = true;
|
|
31
|
-
} else {
|
|
32
|
-
console.log(
|
|
33
|
-
'❌ ngrok not found. Please install it globally using "npm install -g ngrok".'
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
25
|
for (const [key, project] of Object.entries(projects)) {
|
|
38
26
|
console.log(`Checking path for Folder "${key}": ${project}`);
|
|
39
27
|
if (fs.existsSync(project)) {
|
|
40
28
|
console.log(`✅ Path exists for Folder "${key}": ${project}`);
|
|
41
29
|
} else {
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
if(key !== 'app-install-frontend') {
|
|
31
|
+
console.log(`❌ Path does not exist for Folder "${key}": ${project}`);
|
|
32
|
+
allPathsExist = false;
|
|
33
|
+
} else {
|
|
34
|
+
console.log(`❗️ Path does not exist for Folder "${key}": ${project} (currently not required)`);
|
|
35
|
+
}
|
|
44
36
|
}
|
|
45
37
|
}
|
|
46
|
-
if (nodeCheckPassed &&
|
|
38
|
+
if (nodeCheckPassed && allPathsExist) {
|
|
47
39
|
console.log('\n🎉 All precheck items passed successfully!');
|
|
48
40
|
} else {
|
|
49
41
|
console.log('\n❌ Precheck failed. Please address the following issues.');
|
|
@@ -52,11 +44,6 @@ const precheck = ({ projects }) => {
|
|
|
52
44
|
'- Please install or upgrade Node.js to version 22 or higher.'
|
|
53
45
|
);
|
|
54
46
|
}
|
|
55
|
-
if (!ngrokCheckPassed) {
|
|
56
|
-
console.log(
|
|
57
|
-
'- Please install ngrok globally using "npm install -g ngrok".'
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
47
|
if (!allPathsExist) {
|
|
61
48
|
console.log('- Please ensure all Folder paths exist as specified.');
|
|
62
49
|
}
|
|
@@ -7,6 +7,21 @@ const setupApp = () => {
|
|
|
7
7
|
const userDir = process.cwd();
|
|
8
8
|
console.log('🔍 Setting up the app project...\n');
|
|
9
9
|
|
|
10
|
+
// Check if project folder is empty (only .cursor allowed)
|
|
11
|
+
const allowedItems = ['.cursor'];
|
|
12
|
+
const existingItems = fs.readdirSync(userDir, { withFileTypes: true });
|
|
13
|
+
const disallowedItems = existingItems.filter(
|
|
14
|
+
(item) => !allowedItems.includes(item.name)
|
|
15
|
+
);
|
|
16
|
+
if (disallowedItems.length > 0) {
|
|
17
|
+
console.error(
|
|
18
|
+
`❌ Project folder is not empty. Cannot setup the app. Please run setup in an empty directory (only ${allowedItems.join(', ')} folder is allowed).`
|
|
19
|
+
);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
} else {
|
|
22
|
+
console.log('✅ Project folder is empty. Proceeding with setup...');
|
|
23
|
+
}
|
|
24
|
+
|
|
10
25
|
const zipUrl =
|
|
11
26
|
'https://github.com/AravinthanPraba007/appnest-basecode/archive/refs/heads/main.zip';
|
|
12
27
|
const zipFileName = 'appnest-basecode-main.zip';
|
|
@@ -5,16 +5,10 @@ const { validateManifestFile } = require('./manifestUtils');
|
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
const validateApp = async ({ projects }) => {
|
|
8
|
-
await validate({ projects, fix: false });
|
|
9
|
-
validateManifestFile();
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const validateAppFix = async ({ projects }) => {
|
|
13
|
-
await validate({ projects, fix: true });
|
|
14
8
|
validateManifestFile();
|
|
9
|
+
await validate({ projects, fix: false });
|
|
15
10
|
}
|
|
16
11
|
|
|
17
12
|
module.exports = {
|
|
18
|
-
validateApp
|
|
19
|
-
validateAppFix
|
|
13
|
+
validateApp
|
|
20
14
|
};
|
|
@@ -8,11 +8,12 @@ const {
|
|
|
8
8
|
BACKEND_EXTENSIONS,
|
|
9
9
|
spider,
|
|
10
10
|
constructLintMessage,
|
|
11
|
-
|
|
11
|
+
getEslintBackendConfig,
|
|
12
12
|
} = require('./lint-utils');
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
|
-
* Lint app-backend: all
|
|
15
|
+
* Lint app-backend: all `.js` files. Policy is **CommonJS only** (require / module.exports);
|
|
16
|
+
* ESM syntax is rejected by ESLint (see getEslintBackendConfig in lint-utils).
|
|
16
17
|
* @param {string} backendPath - Absolute path to app-backend
|
|
17
18
|
* @param {boolean} fix - Apply ESLint --fix
|
|
18
19
|
* @returns {Array<{ severity: number, value: string }>}
|
|
@@ -37,7 +38,7 @@ function lintBackend(backendPath, fix) {
|
|
|
37
38
|
continue;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
const config =
|
|
41
|
+
const config = getEslintBackendConfig();
|
|
41
42
|
const options = { filename, allowInlineConfig: false };
|
|
42
43
|
const result = linter[toCall](fileContent, config, options);
|
|
43
44
|
|
|
@@ -9,7 +9,7 @@ const {
|
|
|
9
9
|
FRONTEND_EXTENSIONS,
|
|
10
10
|
spider,
|
|
11
11
|
constructLintMessage,
|
|
12
|
-
|
|
12
|
+
getEslintFrontendConfig,
|
|
13
13
|
} = require('./lint-utils');
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -27,14 +27,14 @@ async function lintFrontend(frontendPath, fix) {
|
|
|
27
27
|
);
|
|
28
28
|
const cssFiles = files.filter((f) => path.extname(f).toLowerCase() === '.css');
|
|
29
29
|
|
|
30
|
-
const lints = lintJsJsx(jsJsxFiles, fix
|
|
30
|
+
const lints = lintJsJsx(jsJsxFiles, fix);
|
|
31
31
|
const cssLints = await lintCss(cssFiles, fix);
|
|
32
32
|
lints.push(...cssLints);
|
|
33
33
|
|
|
34
34
|
return lints;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
function lintJsJsx(files, fix
|
|
37
|
+
function lintJsJsx(files, fix) {
|
|
38
38
|
const linter = new Linter();
|
|
39
39
|
const lints = [];
|
|
40
40
|
const toCall = fix ? 'verifyAndFix' : 'verify';
|
|
@@ -51,7 +51,7 @@ function lintJsJsx(files, fix, frontendPath) {
|
|
|
51
51
|
continue;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
-
const config =
|
|
54
|
+
const config = getEslintFrontendConfig(filename);
|
|
55
55
|
const options = { filename, allowInlineConfig: false };
|
|
56
56
|
const result = linter[toCall](fileContent, config, options);
|
|
57
57
|
|