@nitronjs/framework 0.1.0
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 +429 -0
- package/cli/create.js +260 -0
- package/cli/njs.js +164 -0
- package/lib/Auth/Manager.js +111 -0
- package/lib/Build/Manager.js +1232 -0
- package/lib/Console/Commands/BuildCommand.js +25 -0
- package/lib/Console/Commands/DevCommand.js +385 -0
- package/lib/Console/Commands/MakeCommand.js +110 -0
- package/lib/Console/Commands/MigrateCommand.js +98 -0
- package/lib/Console/Commands/MigrateFreshCommand.js +97 -0
- package/lib/Console/Commands/SeedCommand.js +92 -0
- package/lib/Console/Commands/StorageLinkCommand.js +31 -0
- package/lib/Console/Stubs/controller.js +19 -0
- package/lib/Console/Stubs/middleware.js +9 -0
- package/lib/Console/Stubs/migration.js +23 -0
- package/lib/Console/Stubs/model.js +7 -0
- package/lib/Console/Stubs/page-hydration.tsx +54 -0
- package/lib/Console/Stubs/seeder.js +9 -0
- package/lib/Console/Stubs/vendor.tsx +11 -0
- package/lib/Core/Config.js +86 -0
- package/lib/Core/Environment.js +21 -0
- package/lib/Core/Paths.js +188 -0
- package/lib/Database/Connection.js +61 -0
- package/lib/Database/DB.js +84 -0
- package/lib/Database/Drivers/MySQLDriver.js +234 -0
- package/lib/Database/Manager.js +162 -0
- package/lib/Database/Model.js +161 -0
- package/lib/Database/QueryBuilder.js +714 -0
- package/lib/Database/QueryValidation.js +62 -0
- package/lib/Database/Schema/Blueprint.js +126 -0
- package/lib/Database/Schema/Manager.js +116 -0
- package/lib/Date/DateTime.js +108 -0
- package/lib/Date/Locale.js +68 -0
- package/lib/Encryption/Manager.js +47 -0
- package/lib/Filesystem/Manager.js +49 -0
- package/lib/Hashing/Manager.js +25 -0
- package/lib/Http/Server.js +317 -0
- package/lib/Logging/Manager.js +153 -0
- package/lib/Mail/Manager.js +120 -0
- package/lib/Route/Loader.js +81 -0
- package/lib/Route/Manager.js +265 -0
- package/lib/Runtime/Entry.js +11 -0
- package/lib/Session/File.js +299 -0
- package/lib/Session/Manager.js +259 -0
- package/lib/Session/Memory.js +67 -0
- package/lib/Session/Session.js +196 -0
- package/lib/Support/Str.js +100 -0
- package/lib/Translation/Manager.js +49 -0
- package/lib/Validation/MimeTypes.js +39 -0
- package/lib/Validation/Validator.js +691 -0
- package/lib/View/Manager.js +544 -0
- package/lib/View/Templates/default/Home.tsx +262 -0
- package/lib/View/Templates/default/MainLayout.tsx +44 -0
- package/lib/View/Templates/errors/404.tsx +13 -0
- package/lib/View/Templates/errors/500.tsx +13 -0
- package/lib/View/Templates/errors/ErrorLayout.tsx +112 -0
- package/lib/View/Templates/messages/Maintenance.tsx +17 -0
- package/lib/View/Templates/messages/MessageLayout.tsx +136 -0
- package/lib/index.js +57 -0
- package/package.json +47 -0
- package/skeleton/.env.example +26 -0
- package/skeleton/app/Controllers/HomeController.js +9 -0
- package/skeleton/app/Kernel.js +11 -0
- package/skeleton/app/Middlewares/Authentication.js +9 -0
- package/skeleton/app/Middlewares/Guest.js +9 -0
- package/skeleton/app/Middlewares/VerifyCsrf.js +24 -0
- package/skeleton/app/Models/User.js +7 -0
- package/skeleton/config/app.js +4 -0
- package/skeleton/config/auth.js +16 -0
- package/skeleton/config/database.js +27 -0
- package/skeleton/config/hash.js +3 -0
- package/skeleton/config/server.js +28 -0
- package/skeleton/config/session.js +21 -0
- package/skeleton/database/migrations/2025_01_01_00_00_users.js +20 -0
- package/skeleton/database/seeders/UserSeeder.js +15 -0
- package/skeleton/globals.d.ts +1 -0
- package/skeleton/package.json +24 -0
- package/skeleton/public/.gitkeep +0 -0
- package/skeleton/resources/css/.gitkeep +0 -0
- package/skeleton/resources/langs/.gitkeep +0 -0
- package/skeleton/resources/views/Site/Home.tsx +66 -0
- package/skeleton/routes/web.js +4 -0
- package/skeleton/storage/app/private/.gitkeep +0 -0
- package/skeleton/storage/app/public/.gitkeep +0 -0
- package/skeleton/storage/framework/sessions/.gitkeep +0 -0
- package/skeleton/storage/logs/.gitkeep +0 -0
- package/skeleton/tsconfig.json +33 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
import DB from '../../Database/DB.js';
|
|
5
|
+
import Paths from '../../Core/Paths.js';
|
|
6
|
+
import Config from '../../Core/Config.js';
|
|
7
|
+
|
|
8
|
+
class MigrateFresh {
|
|
9
|
+
#shouldSeed;
|
|
10
|
+
|
|
11
|
+
constructor(shouldSeed = false) {
|
|
12
|
+
this.#shouldSeed = shouldSeed;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async run() {
|
|
16
|
+
dotenv.config({ quiet: true });
|
|
17
|
+
await Config.initialize();
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
await DB.setup();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
console.error('❌ Database setup failed:', error.message);
|
|
24
|
+
console.error('Check your .env file and ensure the database exists and is accessible');
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
await this.#dropAllTables();
|
|
29
|
+
await this.#runMigrations();
|
|
30
|
+
|
|
31
|
+
if (this.#shouldSeed) {
|
|
32
|
+
await this.#runSeeders();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
await DB.close();
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async #dropAllTables() {
|
|
40
|
+
const connection = await DB.connection();
|
|
41
|
+
const currentTables = await connection.query("SHOW TABLES");
|
|
42
|
+
await connection.query("SET FOREIGN_KEY_CHECKS = 0");
|
|
43
|
+
|
|
44
|
+
for (const table of currentTables[0]) {
|
|
45
|
+
const tableName = Object.values(table)[0];
|
|
46
|
+
console.log(`❌ [\x1b[36m${tableName}\x1b[0m] Dropping table...`);
|
|
47
|
+
await connection.query(`DROP TABLE IF EXISTS \`${tableName}\``);
|
|
48
|
+
console.log(`✅ [\x1b[36m${tableName}\x1b[0m] Table dropped\n`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
await connection.query("SET FOREIGN_KEY_CHECKS = 1");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async #runMigrations() {
|
|
55
|
+
const migrationsDir = Paths.migrations;
|
|
56
|
+
const files = fs.readdirSync(migrationsDir);
|
|
57
|
+
|
|
58
|
+
for (const file of files) {
|
|
59
|
+
const filePath = Paths.migrationUrl(file);
|
|
60
|
+
const module = await import(filePath);
|
|
61
|
+
console.log(`📦 [\x1b[36m${module.default.name}\x1b[0m] Creating table...`);
|
|
62
|
+
await module.default.up();
|
|
63
|
+
console.log(`✅ [\x1b[36m${module.default.name}\x1b[0m] Table created successfully\n`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async #runSeeders() {
|
|
68
|
+
const seedersDir = Paths.seeders;
|
|
69
|
+
const seedFiles = fs.readdirSync(seedersDir);
|
|
70
|
+
|
|
71
|
+
for (const file of seedFiles) {
|
|
72
|
+
const filePath = Paths.seederUrl(file);
|
|
73
|
+
const seeder = await import(filePath);
|
|
74
|
+
console.log(`🌱 [\x1b[36m${seeder.default.name}\x1b[0m] Seeding...`);
|
|
75
|
+
await seeder.default.run();
|
|
76
|
+
console.log(`✅ [\x1b[36m${seeder.default.name}\x1b[0m] Seeding completed\n`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export default async function migrateFresh(shouldSeed = false) {
|
|
82
|
+
const instance = new MigrateFresh(shouldSeed);
|
|
83
|
+
return instance.run();
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Auto-run when called directly
|
|
87
|
+
const isMain = process.argv[1]?.endsWith("MigrateFreshCommand.js");
|
|
88
|
+
if (isMain) {
|
|
89
|
+
const args = process.argv.slice(2);
|
|
90
|
+
const shouldSeed = args.includes("--seed");
|
|
91
|
+
migrateFresh(shouldSeed)
|
|
92
|
+
.then(success => process.exit(success ? 0 : 1))
|
|
93
|
+
.catch(err => {
|
|
94
|
+
console.error(err);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
});
|
|
97
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import dotenv from 'dotenv';
|
|
5
|
+
import DB from '../../Database/DB.js';
|
|
6
|
+
import Paths from '../../Core/Paths.js';
|
|
7
|
+
import Config from '../../Core/Config.js';
|
|
8
|
+
|
|
9
|
+
class Seed {
|
|
10
|
+
#seederClass;
|
|
11
|
+
|
|
12
|
+
constructor(seederClass = null) {
|
|
13
|
+
this.#seederClass = seederClass;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async run() {
|
|
17
|
+
dotenv.config({ quiet: true });
|
|
18
|
+
await Config.initialize();
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
await DB.setup();
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error('❌ Database setup failed:', error.message);
|
|
24
|
+
console.error('Check your .env file and ensure the database exists and is accessible');
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (this.#seederClass) {
|
|
29
|
+
await this.#runSeeder(this.#seederClass);
|
|
30
|
+
} else {
|
|
31
|
+
await this.#runAllSeeders();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
await DB.close();
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async #runSeeder(className) {
|
|
39
|
+
const file = className + ".js";
|
|
40
|
+
const filePath = Paths.seederUrl(file);
|
|
41
|
+
|
|
42
|
+
try {
|
|
43
|
+
const seeder = await import(filePath);
|
|
44
|
+
console.log(`🌱 [\x1b[36m${seeder.default.name}\x1b[0m] Seeding...`);
|
|
45
|
+
await seeder.default.run();
|
|
46
|
+
console.log(`✅ [\x1b[36m${seeder.default.name}\x1b[0m] Seeding completed\n`);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error(`❌ Seeder '${className}' not found or failed:`, error.message);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async #runAllSeeders() {
|
|
54
|
+
const seedersDir = Paths.seeders;
|
|
55
|
+
const seedFiles = fs.readdirSync(seedersDir);
|
|
56
|
+
|
|
57
|
+
if (seedFiles.length === 0) {
|
|
58
|
+
console.log("No seeders found in database/seeders");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const file of seedFiles) {
|
|
63
|
+
const filePath = Paths.seederUrl(file);
|
|
64
|
+
const seeder = await import(filePath);
|
|
65
|
+
console.log(`🌱 [\x1b[36m${seeder.default.name}\x1b[0m] Seeding...`);
|
|
66
|
+
await seeder.default.run();
|
|
67
|
+
console.log(`✅ [\x1b[36m${seeder.default.name}\x1b[0m] Seeding completed\n`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default async function seed(seederClass = null) {
|
|
73
|
+
const instance = new Seed(seederClass);
|
|
74
|
+
return instance.run();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Auto-run when called directly
|
|
78
|
+
const isMain = process.argv[1]?.endsWith("SeedCommand.js");
|
|
79
|
+
if (isMain) {
|
|
80
|
+
const args = process.argv.slice(2);
|
|
81
|
+
const classArg = args.find(arg => arg.startsWith('--class='));
|
|
82
|
+
const seederClass = classArg
|
|
83
|
+
? classArg.split('=')[1]
|
|
84
|
+
: (args[0] && !args[0].startsWith('-') ? args[0] : null);
|
|
85
|
+
|
|
86
|
+
seed(seederClass)
|
|
87
|
+
.then(success => process.exit(success ? 0 : 1))
|
|
88
|
+
.catch(err => {
|
|
89
|
+
console.error(err);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import os from "os";
|
|
4
|
+
|
|
5
|
+
export default async function storageLink() {
|
|
6
|
+
const source = path.join(process.cwd(), "storage", "app", "public");
|
|
7
|
+
const target = path.join(process.cwd(), "public", "storage");
|
|
8
|
+
|
|
9
|
+
let linkType = os.platform() === 'win32' ? 'junction' : 'dir';
|
|
10
|
+
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
fs.symlink(source, target, linkType, (err) => {
|
|
13
|
+
if (err) {
|
|
14
|
+
console.error('Error creating symbolic link:', err);
|
|
15
|
+
reject(err);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.log('Symbolic link has been created successfully.');
|
|
19
|
+
resolve(true);
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Auto-run when called directly
|
|
26
|
+
const isMain = process.argv[1]?.endsWith("StorageLinkCommand.js");
|
|
27
|
+
if (isMain) {
|
|
28
|
+
storageLink()
|
|
29
|
+
.then(() => process.exit(0))
|
|
30
|
+
.catch(() => process.exit(1));
|
|
31
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Schema } from "@nitronjs/framework";
|
|
2
|
+
|
|
3
|
+
class __CLASS__ {
|
|
4
|
+
|
|
5
|
+
static async up () {
|
|
6
|
+
await Schema.create("__TABLE__", (table) => {
|
|
7
|
+
table.id();
|
|
8
|
+
//
|
|
9
|
+
table.boolean("status").default(1);
|
|
10
|
+
table.integer("creator");
|
|
11
|
+
table.timestamp("created_at");
|
|
12
|
+
table.integer("editor").nullable();
|
|
13
|
+
table.timestamp("edited_at").nullable();
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
static async down () {
|
|
18
|
+
await Schema.dropIfExists("__TABLE__");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export default __CLASS__;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { hydrateRoot } from "react-dom/client";
|
|
3
|
+
|
|
4
|
+
// __COMPONENT_IMPORTS__
|
|
5
|
+
|
|
6
|
+
declare global {
|
|
7
|
+
interface Window {
|
|
8
|
+
__NITRON_PROPS__?: Record<string, any>;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const componentManifest: Record<string, React.ComponentType<any>> = {};
|
|
13
|
+
|
|
14
|
+
// __COMPONENT_MANIFEST__
|
|
15
|
+
|
|
16
|
+
function hydrate() {
|
|
17
|
+
const props = window.__NITRON_PROPS__ || {};
|
|
18
|
+
|
|
19
|
+
const islands = document.querySelectorAll<HTMLElement>("[data-cid]");
|
|
20
|
+
|
|
21
|
+
islands.forEach(element => {
|
|
22
|
+
const componentName = element.dataset.island;
|
|
23
|
+
const componentId = element.dataset.cid;
|
|
24
|
+
|
|
25
|
+
if (!componentName || !componentId) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const Component = componentManifest[componentName];
|
|
30
|
+
|
|
31
|
+
if (!Component) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const componentProps = props[componentId] || {};
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
hydrateRoot(
|
|
39
|
+
element,
|
|
40
|
+
React.createElement(Component, componentProps),
|
|
41
|
+
{ identifierPrefix: componentId }
|
|
42
|
+
);
|
|
43
|
+
} catch {
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
delete window.__NITRON_PROPS__;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (document.readyState === "loading") {
|
|
51
|
+
document.addEventListener("DOMContentLoaded", hydrate);
|
|
52
|
+
} else {
|
|
53
|
+
hydrate();
|
|
54
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import * as ReactDOM from 'react-dom';
|
|
3
|
+
import * as ReactDOMClient from 'react-dom/client';
|
|
4
|
+
import * as ReactJSXRuntime from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
Object.assign(window, {
|
|
7
|
+
__NITRON_REACT__: React,
|
|
8
|
+
__NITRON_REACT_DOM__: ReactDOM,
|
|
9
|
+
__NITRON_REACT_DOM_CLIENT__: ReactDOMClient,
|
|
10
|
+
__NITRON_JSX_RUNTIME__: ReactJSXRuntime
|
|
11
|
+
});
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import Paths from "./Paths.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Config Manager
|
|
5
|
+
*
|
|
6
|
+
* Loads all config files once at startup and provides synchronous access.
|
|
7
|
+
* Must be initialized before any other module tries to access config.
|
|
8
|
+
*/
|
|
9
|
+
class Config {
|
|
10
|
+
static #configs = {};
|
|
11
|
+
static #initialized = false;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Initialize all configs - called once at server startup
|
|
15
|
+
*/
|
|
16
|
+
static async initialize() {
|
|
17
|
+
if (this.#initialized) return;
|
|
18
|
+
|
|
19
|
+
const configFiles = ['app', 'auth', 'database', 'hash', 'server', 'session'];
|
|
20
|
+
|
|
21
|
+
for (const name of configFiles) {
|
|
22
|
+
try {
|
|
23
|
+
this.#configs[name] = (await import(Paths.configUrl(name))).default;
|
|
24
|
+
} catch (err) {
|
|
25
|
+
// Config file might not exist, that's ok
|
|
26
|
+
this.#configs[name] = {};
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
this.#initialized = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Get a config value synchronously
|
|
35
|
+
* @param {string} key - Config key in dot notation (e.g., 'app.timezone', 'database.default')
|
|
36
|
+
* @param {*} defaultValue - Default value if key not found
|
|
37
|
+
* @returns {*} Config value
|
|
38
|
+
*/
|
|
39
|
+
static get(key, defaultValue = null) {
|
|
40
|
+
if (!this.#initialized) {
|
|
41
|
+
throw new Error('Config not initialized. Call Config.initialize() first.');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const parts = key.split('.');
|
|
45
|
+
const configName = parts[0];
|
|
46
|
+
|
|
47
|
+
if (!this.#configs[configName]) {
|
|
48
|
+
return defaultValue;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (parts.length === 1) {
|
|
52
|
+
return this.#configs[configName];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let value = this.#configs[configName];
|
|
56
|
+
for (let i = 1; i < parts.length; i++) {
|
|
57
|
+
if (value === undefined || value === null) {
|
|
58
|
+
return defaultValue;
|
|
59
|
+
}
|
|
60
|
+
value = value[parts[i]];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return value !== undefined ? value : defaultValue;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get entire config object for a config file
|
|
68
|
+
* @param {string} name - Config file name (e.g., 'app', 'database')
|
|
69
|
+
* @returns {object} Config object
|
|
70
|
+
*/
|
|
71
|
+
static all(name) {
|
|
72
|
+
if (!this.#initialized) {
|
|
73
|
+
throw new Error('Config not initialized. Call Config.initialize() first.');
|
|
74
|
+
}
|
|
75
|
+
return this.#configs[name] || {};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Check if config system is initialized
|
|
80
|
+
*/
|
|
81
|
+
static isInitialized() {
|
|
82
|
+
return this.#initialized;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export default Config;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
|
|
3
|
+
class Environment {
|
|
4
|
+
|
|
5
|
+
static update (key, value) {
|
|
6
|
+
let content = fs.readFileSync(".env", 'utf-8');
|
|
7
|
+
const regex = new RegExp(`^${key}=.*`, 'm');
|
|
8
|
+
|
|
9
|
+
if (content.match(regex)) {
|
|
10
|
+
content = content.replace(regex, `${key}=${value}`);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
content += `\n${key}=${value}`;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
fs.writeFileSync(".env", content.trim() + '\n');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export default Environment;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
import { pathToFileURL } from "url";
|
|
4
|
+
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
|
|
7
|
+
class Paths {
|
|
8
|
+
static #framework = path.resolve(__dirname, "../..");
|
|
9
|
+
static #project = process.cwd();
|
|
10
|
+
|
|
11
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
12
|
+
// Base Directories
|
|
13
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
14
|
+
|
|
15
|
+
static get framework() {
|
|
16
|
+
return this.#framework;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static get project() {
|
|
20
|
+
return this.#project;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
24
|
+
// Framework Paths
|
|
25
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
26
|
+
|
|
27
|
+
static get frameworkLib() {
|
|
28
|
+
return path.join(this.#framework, "lib");
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
static get frameworkViews() {
|
|
32
|
+
return path.join(this.#framework, "lib/View/Templates");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
static get frameworkTemplates() {
|
|
36
|
+
return path.join(this.#framework, "lib/Console/Stubs");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
40
|
+
// Project Paths
|
|
41
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
42
|
+
|
|
43
|
+
static get config() {
|
|
44
|
+
return path.join(this.#project, "config");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
static get app() {
|
|
48
|
+
return path.join(this.#project, "app");
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static get controllers() {
|
|
52
|
+
return path.join(this.#project, "app/Controllers");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static get middlewares() {
|
|
56
|
+
return path.join(this.#project, "app/Middlewares");
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static get models() {
|
|
60
|
+
return path.join(this.#project, "app/Models");
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
static get routes() {
|
|
64
|
+
return path.join(this.#project, "routes");
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static get resources() {
|
|
68
|
+
return path.join(this.#project, "resources");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static get views() {
|
|
72
|
+
return path.join(this.#project, "resources/views");
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
static get css() {
|
|
76
|
+
return path.join(this.#project, "resources/css");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
static get langs() {
|
|
80
|
+
return path.join(this.#project, "resources/langs");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static get database() {
|
|
84
|
+
return path.join(this.#project, "database");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
static get migrations() {
|
|
88
|
+
return path.join(this.#project, "database/migrations");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static get seeders() {
|
|
92
|
+
return path.join(this.#project, "database/seeders");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
static get storage() {
|
|
96
|
+
return path.join(this.#project, "storage");
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
static get storagePublic() {
|
|
100
|
+
return path.join(this.#project, "storage/app/public");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
static get storagePrivate() {
|
|
104
|
+
return path.join(this.#project, "storage/app/private");
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
static get storageSessions() {
|
|
108
|
+
return path.join(this.#project, "storage/framework/sessions");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static get storageLogs() {
|
|
112
|
+
return path.join(this.#project, "storage/logs");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
static get public() {
|
|
116
|
+
return path.join(this.#project, "public");
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
static get publicCss() {
|
|
120
|
+
return path.join(this.#project, "storage/app/public/css");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static get publicJs() {
|
|
124
|
+
return path.join(this.#project, "storage/app/public/js");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
static get build() {
|
|
128
|
+
return path.join(this.#project, "build");
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
static get buildViews() {
|
|
132
|
+
return path.join(this.#project, "build/views");
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static get buildFrameworkViews() {
|
|
136
|
+
return path.join(this.#project, "build/framework/views");
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static get nitronTemp() {
|
|
140
|
+
return path.join(this.#project, ".nitron");
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
static get jsxRuntime() {
|
|
144
|
+
return path.join(this.#project, ".nitron/jsx-runtime.js");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
148
|
+
// Config Files (returns file:// URL for dynamic import)
|
|
149
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
static configUrl(name) {
|
|
152
|
+
return pathToFileURL(path.join(this.#project, `config/${name}.js`)).href;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
static routeUrl(name) {
|
|
156
|
+
return pathToFileURL(path.join(this.#project, `routes/${name}.js`)).href;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static migrationUrl(file) {
|
|
160
|
+
return pathToFileURL(path.join(this.migrations, file)).href;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static seederUrl(file) {
|
|
164
|
+
return pathToFileURL(path.join(this.seeders, file)).href;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
static kernelUrl() {
|
|
168
|
+
return pathToFileURL(path.join(this.#project, "app/Kernel.js")).href;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
172
|
+
// Helper Methods
|
|
173
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
174
|
+
|
|
175
|
+
static join(...segments) {
|
|
176
|
+
return path.join(this.#project, ...segments);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
static frameworkJoin(...segments) {
|
|
180
|
+
return path.join(this.#framework, ...segments);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static resolve(...segments) {
|
|
184
|
+
return path.resolve(this.#project, ...segments);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export default Paths;
|