Skip to content

Commit c08ae0b

Browse files
committed
Merge branch 'next' of https://github.com/devforth/adminforth into create-cli
2 parents f34741c + 9cfc2a8 commit c08ae0b

File tree

79 files changed

+1555
-836
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+1555
-836
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ npx adminforth create-app
5454

5555

5656

57-
5857
# For developers
5958

6059
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.
@@ -66,20 +65,21 @@ Fork repo, pull it and do next:
6665
cd adminforth
6766
npm ci
6867
npm run build
68+
```
69+
70+
To run dev demo:
71+
```sh
72+
cd dev-demo
73+
cp .env.sample .env
6974

7075
# this will install all official plugins and link adminforth package, if plugin installed it will git pull and npm ci
7176
npm run install-plugins
7277

7378
# same for official adapters
7479
npm run install-adapters
75-
```
7680

77-
To run dev demo:
78-
```sh
79-
cd dev-demo
80-
cp .env.sample .env
8181
npm ci
82-
npm run migrate
82+
npm run migrate:local
8383
npm start
8484
```
8585

adapters/install-adapters.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#!/usr/bin/env bash
2-
ADAPTERS="adminforth-completion-adapter-open-ai-chat-gpt adminforth-email-adapter-aws-ses adminforth-google-oauth-adapter adminforth-github-oauth-adapter adminforth-facebook-oauth-adapter adminforth-keycloak-oauth-adapter adminforth-microsoft-oauth-adapter"
2+
ADAPTERS="adminforth-completion-adapter-open-ai-chat-gpt adminforth-email-adapter-aws-ses adminforth-google-oauth-adapter adminforth-github-oauth-adapter adminforth-facebook-oauth-adapter adminforth-keycloak-oauth-adapter adminforth-microsoft-oauth-adapter adminforth-image-generation-adapter-openai adminforth-storage-adapter-amazon-s3 adminforth-storage-adapter-local"
33

44
# for each
55
install_adapter() {

adminforth/commands/callTsProxy.js

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

10-
export function callTsProxy(tsCode) {
10+
export function callTsProxy(tsCode, silent=false) {
1111

1212
process.env.HEAVY_DEBUG && console.log("🌐 Calling tsproxy with code:", path.join(currentFileFolder, "proxy.ts"));
1313
return new Promise((resolve, reject) => {
@@ -30,9 +30,11 @@ export function callTsProxy(tsCode) {
3030
if (code === 0) {
3131
try {
3232
const parsed = JSON.parse(stdout);
33-
parsed.capturedLogs.forEach((log) => {
34-
console.log(...log);
35-
});
33+
if (!silent) {
34+
parsed.capturedLogs.forEach((log) => {
35+
console.log(...log);
36+
});
37+
}
3638

3739
if (parsed.error) {
3840
reject(new Error(`${parsed.error}\n${parsed.stack}`));
@@ -73,13 +75,13 @@ export async function findAdminInstance() {
7375
const fileNoTs = file.replace(/\.ts$/, "");
7476
process.env.HEAVY_DEBUG && console.log(`🪲 Trying bundleing ${file}...`);
7577
try {
76-
res = await callTsProxy(`
78+
const res = await callTsProxy(`
7779
import { admin } from './${fileNoTs}.js';
7880
7981
export async function exec() {
8082
return admin.formatAdminForth();
8183
}
82-
`);
84+
`, true);
8385
instanceFound.file = fileNoTs;
8486
instanceFound.version = res;
8587
break;

adminforth/commands/createApp/main.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ export default async function createApp(args) {
2222
await tasks.run();
2323
} catch (err) {
2424
console.error(chalk.red(`\n❌ ${err.message}\n`));
25+
console.error(err.stack);
2526
process.exit(1);
2627
}
2728
}
Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
NODE_ENV=production
2-
DATABASE_URL=sqlite://.db.sqlite
3-
DATABASE_URL={{dbUrl}}
4-
{{#if prismaDbUrl}}
5-
PRISMA_DATABASE_URL={{prismaDbUrl}}
2+
DATABASE_URL={{dbUrlProd}}
3+
{{#if prismaDbUrlProd}}
4+
PRISMA_DATABASE_URL={{prismaDbUrlProd}}
65
{{/if}}

adminforth/commands/createApp/templates/adminuser.ts.hbs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import AdminForth, { AdminForthDataTypes, AdminForthResourceInput, AdminForthResource, AdminUser } from 'adminforth';
2-
3-
import type { AdminUser } from 'adminforth';
1+
import AdminForth, { AdminForthDataTypes } from 'adminforth';
2+
import type { AdminForthResourceInput, AdminForthResource, AdminUser } from 'adminforth';
3+
import { randomUUID } from 'crypto';
44

55
async function canModifyUsers({ adminUser }: { adminUser: AdminUser }): Promise<boolean> {
66
return adminUser.dbUser.role === 'superadmin';
@@ -23,7 +23,7 @@ export default {
2323
name: 'id',
2424
primaryKey: true,
2525
type: AdminForthDataTypes.STRING,
26-
fillOnCreate: ({ initialRecord, adminUser }) => Math.random().toString(36).substring(7),
26+
fillOnCreate: ({ initialRecord, adminUser }) => randomUUID(),
2727
showIn: {
2828
edit: false,
2929
create: false,

adminforth/commands/createApp/templates/index.ts.hbs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import express from 'express';
2-
import AdminForth, { Filters } from 'adminforth';
2+
import AdminForth from 'adminforth';
33
import usersResource from "./resources/adminuser.js";
44

55
const ADMIN_BASE_URL = '';
@@ -61,13 +61,14 @@ if (import.meta.url === `file://${process.argv[1]}`) {
6161

6262
const port = 3500;
6363

64-
await admin.bundleNow({ hotReload: process.env.NODE_ENV === 'development' });
65-
console.log('Bundling AdminForth SPA done.');
64+
admin.bundleNow({ hotReload: process.env.NODE_ENV === 'development' }).then(() => {
65+
console.log('Bundling AdminForth SPA done.');
66+
});
6667

67-
admin.express.serve(app)
68+
admin.express.serve(app);
6869

6970
admin.discoverDatabases().then(async () => {
70-
if (!await admin.resource('adminuser').get([Filters.EQ('email', 'adminforth')])) {
71+
if (await admin.resource('adminuser').count() === 0) {
7172
await admin.resource('adminuser').create({
7273
email: 'adminforth',
7374
password_hash: await AdminForth.Utils.generatePasswordHash('adminforth'),

adminforth/commands/createApp/templates/readme.md.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ You have Dockerfile ready for production deployment. You can test the build with
3838

3939
```bash
4040
docker build -t {{appName}}-image .
41-
docker run -p 3500:3500 {{appName}}-image
41+
docker run -p 3500:3500 -e ADMINFORTH_SECRET=123 {{#if sqliteFile}}-v $(pwd)/db:/code/db {{/if}}{{appName}}-image
4242
```
4343

4444
To set non-sensitive environment variables in production, use `.env.prod` file.

adminforth/commands/createApp/utils.js

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,20 @@ function generateDbUrlForPrisma(connectionString) {
100100
return connectionString.toString();
101101
}
102102

103+
function generateDbUrlForPrismaProd(connectionString) {
104+
if (connectionString.protocol.startsWith('sqlite'))
105+
return `file:/code/db/${connectionString.host}`;
106+
if (connectionString.protocol.startsWith('mongodb'))
107+
return null;
108+
return connectionString.toString();
109+
}
110+
111+
function generateDbUrlForAfProd(connectionString) {
112+
if (connectionString.protocol.startsWith('sqlite'))
113+
return `sqlite:////code/db/${connectionString.host}`;
114+
return connectionString.toString();
115+
}
116+
103117
function initialChecks(options) {
104118
return [
105119
{
@@ -128,8 +142,12 @@ async function scaffoldProject(ctx, options, cwd) {
128142
await fse.ensureDir(projectDir);
129143

130144
const connectionString = parseConnectionString(options.db);
145+
const connectionStringProd = generateDbUrlForAfProd(connectionString);
146+
131147
const provider = detectDbProvider(connectionString.protocol);
132148
const prismaDbUrl = generateDbUrlForPrisma(connectionString);
149+
const prismaDbUrlProd = generateDbUrlForPrismaProd(connectionString);
150+
133151

134152
ctx.skipPrismaSetup = !prismaDbUrl;
135153
const appName = options.appName;
@@ -151,17 +169,23 @@ async function scaffoldProject(ctx, options, cwd) {
151169
// Write templated files
152170
await writeTemplateFiles(dirname, projectDir, {
153171
dbUrl: connectionString.toString(),
172+
dbUrlProd: connectionStringProd,
154173
prismaDbUrl,
174+
prismaDbUrlProd,
155175
appName,
156176
provider,
157177
nodeMajor: parseInt(process.versions.node.split('.')[0], 10),
178+
sqliteFile: connectionString.protocol.startsWith('sqlite') ? connectionString.host : null,
158179
});
159180

160181
return projectDir; // Return the new directory path
161182
}
162183

163184
async function writeTemplateFiles(dirname, cwd, options) {
164-
const { dbUrl, prismaDbUrl, appName, provider, nodeMajor } = options;
185+
const {
186+
dbUrl, prismaDbUrl, appName, provider, nodeMajor,
187+
dbUrlProd, prismaDbUrlProd, sqliteFile
188+
} = options;
165189

166190
// Build a list of files to generate
167191
const templateTasks = [
@@ -199,12 +223,12 @@ async function writeTemplateFiles(dirname, cwd, options) {
199223
{
200224
src: '.env.prod.hbs',
201225
dest: '.env.prod',
202-
data: { dbUrl, prismaDbUrl },
226+
data: { prismaDbUrlProd, dbUrlProd },
203227
},
204228
{
205229
src: 'readme.md.hbs',
206230
dest: 'README.md',
207-
data: { dbUrl, prismaDbUrl, appName },
231+
data: { dbUrl, prismaDbUrl, appName, sqliteFile },
208232
},
209233
{
210234
// We'll write .env using the same content as .env.sample
@@ -237,7 +261,7 @@ async function writeTemplateFiles(dirname, cwd, options) {
237261
src: '.dockerignore.hbs',
238262
dest: '.dockerignore',
239263
data: {
240-
sqliteFile: detectDbProvider(options.db).startsWith('sqlite') ? options.db.split('://')[1] : null,
264+
sqliteFile,
241265
},
242266
}
243267
];

adminforth/commands/utils.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ export const mapToTypeScriptType = (adminType) => {
1313
switch (adminType) {
1414
case "string":
1515
case "text":
16-
case "richtext":
1716
case "datetime":
1817
case "date":
1918
case "time":

0 commit comments

Comments
 (0)