Skip to content

Commit e56c6a7

Browse files
committed
Merge branch 'next' of github.com:devforth/adminforth into feature/AdminForth/1439/add-global-plugins
AdminForth/1439/add-global-plugins
2 parents 27b093d + e3e43f3 commit e56c6a7

296 files changed

Lines changed: 15404 additions & 17184 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: Deploy Documentation
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- 'adminforth/documentation/**'
9+
- '.github/workflows/deploy_documentation.yaml'
10+
11+
jobs:
12+
deploy:
13+
runs-on: ubuntu-latest
14+
defaults:
15+
run:
16+
working-directory: adminforth
17+
steps:
18+
- name: Checkout repository
19+
uses: actions/checkout@v4
20+
- name: Install pnpm
21+
uses: pnpm/action-setup@v4
22+
with:
23+
version: 9
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '20'
28+
cache: 'pnpm'
29+
cache-dependency-path: adminforth/pnpm-lock.yaml
30+
31+
- name: Configure Git
32+
run: |
33+
git config --global user.name "${{ github.actor }}"
34+
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
35+
36+
- name: Install dependencies
37+
run: |
38+
pnpm i
39+
cd documentation
40+
npm ci
41+
42+
- name: Build and deploy docs
43+
run: GIT_USER=${{ github.actor }} GIT_PASS=${{ secrets.DOCUSAURUS_DEPLOY_KEY }} pnpm rollout-doc

README.md

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# AdminForth - free powerfull Node.js admin panel framework on Vue & Tailwind
1+
# AdminForth - powerfull Agent-first Typescript admin panel framework
22

33

44
<a href="https://adminforth.dev"><img src="https://img.shields.io/badge/website-adminforth.dev-blue" style="height:24px"/></a> <a href="https://adminforth.dev"><img src="https://img.shields.io/npm/dw/adminforth" style="height:24px"/></a> <a href="https://devforth.io"><img src="https://raw.githubusercontent.com/devforth/OnLogs/e97944fffc24fec0ce2347b205c9bda3be8de5c5/.assets/df_powered_by.svg" style="height:28px"/></a>
@@ -7,17 +7,20 @@
77

88
* [Try live demo](https://demo.adminforth.dev/)
99

10+
* [YouTube video: build agentic admin panel in a minutes](https://www.youtube.com/watch?v=4tB8uzY__uk)
11+
1012
* [Hello world in 5 minutes](https://adminforth.dev/docs/tutorial/gettingStarted) with AdminForth
1113

1214
* [Tutorial](https://adminforth.dev/docs/tutorial/Customization/branding/)
1315

1416
<br/>
1517

1618
<div align="center">
17-
<img src="https://github.com/user-attachments/assets/e643caad-1daa-4085-b125-cc940557a2ec"
18-
alt="AdminForth Dashboard" width="90%">
19+
<img src="https://github.com/user-attachments/assets/775c527d-65c3-4d9c-bb0c-3692462f2818"
20+
alt="AdminForth Agent" width="90%">
1921
</div>
2022

23+
2124
<br/>
2225

2326
Why AdminForth:
@@ -34,32 +37,43 @@ Why AdminForth:
3437

3538
## Project initialisation
3639

37-
```
38-
mkdir myadmin && cd myadmin
40+
To create an AdminForth project, run:
41+
42+
```bash
3943
npx adminforth create-app
4044
```
4145

42-
## Previews
46+
During the interactive initialization process, AdminForth will ask you to provide a local database URL.
4347

44-
<a href="https://adminforth.dev/docs/tutorial/Customization/customPages">Custom Dashboard</a>
45-
<br/>
46-
<img src="https://github.com/user-attachments/assets/aa899196-f7f3-4582-839c-2267f2e9e197" alt="AdminForth Dashboard demo" width="80%" />
48+
### Integrating AdminForth into your existing application
4749

48-
<a href="https://adminforth.dev/docs/tutorial/Plugins/chat-gpt">Text completion plugin (Copilot-style) using LLMs</a>
49-
<br/>
50+
If you want to build an admin panel for an existing project that already has a database with tables, you can provide the connection URL to your existing development database, such as a local or deployed one.
5051

51-
<img src="https://github.com/user-attachments/assets/cfa17cbd-3a53-4725-ab46-53c7c7666028" alt="AdminForth ChatGPT demo" width="80%" />
52+
After that, you may want to generate AdminForth resource files from your existing database tables:
5253

53-
<a href="https://adminforth.dev/docs/tutorial/Plugins/upload/#image-generation">Image Generation using image generation models</a>
54-
<br/>
55-
<img src="https://github.com/user-attachments/assets/b923e044-7e29-46ff-ab91-eeca5eee2b0a" alt="AdminForth DALE-E image generator demo" width="80%">
54+
```bash
55+
npx adminforth resource
56+
```
57+
58+
Resource files are needed for AdminForth to “know” about your tables and define how to work with them.
59+
60+
Use the command above every time you add new tables or change their schema.
61+
62+
### Starting from scratch
63+
64+
If you do not have a database yet, start an empty local database, for example PostgreSQL in Docker, and provide its URL to the AdminForth CLI.
65+
66+
If the adminforth CLI does not detect any tables, it will suggest adding Prisma as a migration tool. Prisma is not related to AdminForth, but it is one of the most convenient migration tools.
67+
68+
Please follow [getting started](https://adminforth.dev/docs/tutorial/gettingStarted/).
5669

70+
# For AdminForth developers
5771

58-
# For developers
72+
> Follow this section only if you want to make changes to the AdminForth framework or develop a plugin.
5973
60-
The most convenient way to add new features or fixes is using `dev-demo`. It imports the source code of the repository and plugins so you can edit them and see changes on the fly.
74+
The most convenient way to add new features or fixes is to use `dev-demo`. It imports the repository source code and plugins, so you can edit them and see changes on the fly.
6175

62-
# Requirements
76+
## Requirements
6377

6478
- **Node.js 20**
6579
- **Docker**

adminforth/commands/callTsProxy.js

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,27 @@ import dotenv from "dotenv";
88
const currentFilePath = import.meta.url;
99
const currentFileFolder = path.dirname(currentFilePath).replace("file:", "");
1010

11+
function getLocalBinPath(currentDirectory) {
12+
return path.join(currentDirectory, "node_modules", ".bin");
13+
}
14+
15+
function getLocalBinExecutable(currentDirectory, command) {
16+
const extension = process.platform === "win32" ? ".cmd" : "";
17+
const executablePath = path.join(getLocalBinPath(currentDirectory), `${command}${extension}`);
18+
return fs.existsSync(executablePath) ? executablePath : command;
19+
}
20+
21+
function getEnvWithLocalBin(currentDirectory) {
22+
const pathKey = process.platform === "win32" ? "Path" : "PATH";
23+
const localBinPath = getLocalBinPath(currentDirectory);
24+
const currentPath = process.env[pathKey] || "";
25+
26+
return {
27+
...process.env,
28+
[pathKey]: [localBinPath, currentPath].filter(Boolean).join(path.delimiter),
29+
};
30+
}
31+
1132
export function callTsProxy(tsCode, silent=false) {
1233

1334
const currentDirectory = process.cwd();
@@ -22,28 +43,37 @@ export function callTsProxy(tsCode, silent=false) {
2243

2344
process.env.HEAVY_DEBUG && console.log("🌐 Calling tsproxy with code:", path.join(currentFileFolder, "proxy.ts"));
2445
return new Promise((resolve, reject) => {
25-
const child = spawn("tsx", [path.join(currentFileFolder, "proxy.ts")], {
26-
env: process.env,
46+
const child = spawn(getLocalBinExecutable(currentDirectory, "tsx"), [path.join(currentFileFolder, "proxy.ts")], {
47+
env: getEnvWithLocalBin(currentDirectory),
2748
});
2849
let stderr = "";
29-
let stdoutLogs = [];
50+
let stdout = "";
3051

3152
child.stdout.on("data", (data) => {
32-
stdoutLogs.push(data.toString());
53+
stdout += data.toString();
3354
});
3455

3556
child.stderr.on("data", (data) => {
3657
stderr += data;
3758
});
3859

60+
child.on("error", (error) => {
61+
reject(error);
62+
});
63+
3964
child.on("close", (code) => {
40-
const tsProxyResult = stdoutLogs.find(log => log.includes('>>>>>>>'));
41-
const preparedStdout = tsProxyResult.slice(tsProxyResult.indexOf('>>>>>>>') + 7, tsProxyResult.lastIndexOf('<<<<<<<'));
42-
const preparedStdoutLogs = stdoutLogs.filter(log => !log.includes('>>>>>>>'));
65+
const resultStart = stdout.indexOf('>>>>>>>');
66+
const resultEnd = stdout.lastIndexOf('<<<<<<<');
67+
if (resultStart === -1 || resultEnd === -1 || resultEnd < resultStart) {
68+
reject(new Error(`Invalid JSON from tsproxy. stdout: ${stdout}, stderr: ${stderr}`));
69+
return;
70+
}
71+
const preparedStdout = stdout.slice(resultStart + 7, resultEnd);
72+
const preparedStdoutLogs = stdout.slice(0, resultStart);
4373
if (code === 0) {
4474
try {
45-
for (const log of preparedStdoutLogs) {
46-
console.log(log);
75+
if (preparedStdoutLogs) {
76+
process.stdout.write(preparedStdoutLogs);
4777
}
4878
const parsed = JSON.parse(preparedStdout);
4979
if (!silent) {

0 commit comments

Comments
 (0)