arcanajs 2.2.1 → 2.3.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/framework/cli/templates.js +2 -0
- package/framework/cli/webpack.config.js +51 -2
- package/framework/lib/client/index.d.ts +32 -0
- package/framework/lib/client/index.js +34 -0
- package/framework/lib/config/index.d.ts +46 -0
- package/framework/lib/config/index.js +115 -0
- package/framework/lib/global.d.ts +60 -0
- package/framework/lib/index.d.ts +1 -0
- package/framework/lib/index.js +19 -1
- package/framework/lib/server/ArcanaJSServer.js +3 -3
- package/framework/lib/server.d.ts +19 -3
- package/framework/lib/server.js +31 -3
- package/framework/lib/types.d.ts +174 -0
- package/framework/lib/types.js +8 -0
- package/framework/templates/HomePage.tsx +2 -2
- package/framework/templates/arcanajs.config.js +41 -0
- package/framework/templates/arcanajs.d.ts +10 -0
- package/framework/templates/package.json +1 -1
- package/framework/templates/server-index.ts +3 -2
- package/framework/templates/tsconfig.json +27 -0
- package/package.json +12 -3
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.requiredDirs = exports.errorPages = exports.configFiles = void 0;
|
|
4
4
|
exports.configFiles = [
|
|
5
5
|
{ src: "package.json", dest: "package.json" },
|
|
6
|
+
{ src: "tsconfig.json", dest: "tsconfig.json" },
|
|
7
|
+
{ src: "arcanajs.d.ts", dest: "src/arcanajs.d.ts" },
|
|
6
8
|
{ src: "postcss.config.js", dest: "postcss.config.js" },
|
|
7
9
|
{ src: "globals.css", dest: "src/client/globals.css" },
|
|
8
10
|
{ src: "client-index.tsx", dest: "src/client/index.tsx" },
|
|
@@ -108,8 +108,39 @@ const createClientConfig = () => {
|
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
110
|
},
|
|
111
|
+
// CSS Modules rule for .module.css files
|
|
112
|
+
{
|
|
113
|
+
test: /\.module\.css$/,
|
|
114
|
+
use: [
|
|
115
|
+
isProduction
|
|
116
|
+
? mini_css_extract_plugin_1.default.loader
|
|
117
|
+
: resolveLoader("style-loader"),
|
|
118
|
+
{
|
|
119
|
+
loader: resolveLoader("css-loader"),
|
|
120
|
+
options: {
|
|
121
|
+
importLoaders: 1,
|
|
122
|
+
modules: {
|
|
123
|
+
localIdentName: isProduction
|
|
124
|
+
? "[hash:base64:8]"
|
|
125
|
+
: "[path][name]__[local]--[hash:base64:5]",
|
|
126
|
+
exportLocalsConvention: "camelCaseOnly",
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
loader: resolveLoader("postcss-loader"),
|
|
132
|
+
options: {
|
|
133
|
+
postcssOptions: {
|
|
134
|
+
config: path_1.default.resolve(cwd, "postcss.config.js"),
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
],
|
|
139
|
+
},
|
|
140
|
+
// Global CSS rule for regular .css files
|
|
111
141
|
{
|
|
112
142
|
test: /\.css$/,
|
|
143
|
+
exclude: /\.module\.css$/,
|
|
113
144
|
use: [
|
|
114
145
|
isProduction
|
|
115
146
|
? mini_css_extract_plugin_1.default.loader
|
|
@@ -242,9 +273,27 @@ const createServerConfig = () => {
|
|
|
242
273
|
},
|
|
243
274
|
},
|
|
244
275
|
},
|
|
276
|
+
// CSS Modules rule for .module.css files on server (for SSR)
|
|
277
|
+
{
|
|
278
|
+
test: /\.module\.css$/,
|
|
279
|
+
use: {
|
|
280
|
+
loader: resolveLoader("css-loader"),
|
|
281
|
+
options: {
|
|
282
|
+
modules: {
|
|
283
|
+
localIdentName: isProduction
|
|
284
|
+
? "[hash:base64:8]"
|
|
285
|
+
: "[path][name]__[local]--[hash:base64:5]",
|
|
286
|
+
exportLocalsConvention: "camelCaseOnly",
|
|
287
|
+
exportOnlyLocals: true, // Only export class names, not CSS
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
// Regular CSS files - ignore on server side
|
|
245
293
|
{
|
|
246
294
|
test: /\.css$/,
|
|
247
|
-
|
|
295
|
+
exclude: /\.module\.css$/,
|
|
296
|
+
use: resolveLoader("null-loader"),
|
|
248
297
|
},
|
|
249
298
|
{
|
|
250
299
|
test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|eot|ttf|otf)$/i,
|
|
@@ -255,7 +304,7 @@ const createServerConfig = () => {
|
|
|
255
304
|
},
|
|
256
305
|
],
|
|
257
306
|
},
|
|
258
|
-
|
|
307
|
+
devtool: isProduction ? "source-map" : "eval-source-map",
|
|
259
308
|
};
|
|
260
309
|
};
|
|
261
310
|
exports.createServerConfig = createServerConfig;
|
|
@@ -1,2 +1,34 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
export type { LayoutComponent, ViewsRegistry } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Hydrate the ArcanaJS application on the client side
|
|
5
|
+
*
|
|
6
|
+
* This function initializes the React application on the client,
|
|
7
|
+
* hydrating the server-rendered HTML with client-side interactivity.
|
|
8
|
+
*
|
|
9
|
+
* @param viewsOrContext - Either a views registry object or a webpack require.context
|
|
10
|
+
* @param layout - Optional layout component to wrap all pages
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Using webpack require.context (recommended)
|
|
15
|
+
* import { hydrateArcanaJS } from 'arcanajs/client';
|
|
16
|
+
*
|
|
17
|
+
* const views = require.context('./views', false, /\.tsx$/);
|
|
18
|
+
* hydrateArcanaJS(views);
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Using manual views registry
|
|
24
|
+
* import { hydrateArcanaJS } from 'arcanajs/client';
|
|
25
|
+
* import HomePage from './views/HomePage';
|
|
26
|
+
* import AboutPage from './views/AboutPage';
|
|
27
|
+
*
|
|
28
|
+
* hydrateArcanaJS({
|
|
29
|
+
* HomePage,
|
|
30
|
+
* AboutPage,
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
2
34
|
export declare const hydrateArcanaJS: (viewsOrContext: Record<string, React.FC<any>> | any, layout?: React.FC<any>) => void;
|
|
@@ -10,6 +10,40 @@ const HeadContext_1 = require("../shared/context/HeadContext");
|
|
|
10
10
|
const ArcanaJSApp_1 = require("../shared/core/ArcanaJSApp");
|
|
11
11
|
const ErrorPage_1 = __importDefault(require("../shared/views/ErrorPage"));
|
|
12
12
|
const NotFoundPage_1 = __importDefault(require("../shared/views/NotFoundPage"));
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Client Hydration Function
|
|
15
|
+
// ============================================================================
|
|
16
|
+
/**
|
|
17
|
+
* Hydrate the ArcanaJS application on the client side
|
|
18
|
+
*
|
|
19
|
+
* This function initializes the React application on the client,
|
|
20
|
+
* hydrating the server-rendered HTML with client-side interactivity.
|
|
21
|
+
*
|
|
22
|
+
* @param viewsOrContext - Either a views registry object or a webpack require.context
|
|
23
|
+
* @param layout - Optional layout component to wrap all pages
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* // Using webpack require.context (recommended)
|
|
28
|
+
* import { hydrateArcanaJS } from 'arcanajs/client';
|
|
29
|
+
*
|
|
30
|
+
* const views = require.context('./views', false, /\.tsx$/);
|
|
31
|
+
* hydrateArcanaJS(views);
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```typescript
|
|
36
|
+
* // Using manual views registry
|
|
37
|
+
* import { hydrateArcanaJS } from 'arcanajs/client';
|
|
38
|
+
* import HomePage from './views/HomePage';
|
|
39
|
+
* import AboutPage from './views/AboutPage';
|
|
40
|
+
*
|
|
41
|
+
* hydrateArcanaJS({
|
|
42
|
+
* HomePage,
|
|
43
|
+
* AboutPage,
|
|
44
|
+
* });
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
13
47
|
const hydrateArcanaJS = (viewsOrContext, layout) => {
|
|
14
48
|
let views = {};
|
|
15
49
|
if (viewsOrContext.keys && typeof viewsOrContext.keys === "function") {
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArcanaJS Configuration System
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for loading and validating ArcanaJS configuration files.
|
|
5
|
+
*/
|
|
6
|
+
import type { ArcanaJSUserConfig, ResolvedArcanaJSConfig } from "../types";
|
|
7
|
+
/**
|
|
8
|
+
* Define a configuration object with type safety
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* export default defineConfig({
|
|
13
|
+
* server: {
|
|
14
|
+
* port: 3000,
|
|
15
|
+
* },
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare function defineConfig(config: ArcanaJSUserConfig): ArcanaJSUserConfig;
|
|
20
|
+
/**
|
|
21
|
+
* Load ArcanaJS configuration from project root
|
|
22
|
+
*
|
|
23
|
+
* Searches for:
|
|
24
|
+
* - arcanajs.config.js
|
|
25
|
+
* - arcanajs.config.ts
|
|
26
|
+
* - arcanajs.config.mjs
|
|
27
|
+
*
|
|
28
|
+
* @param root - Project root directory (defaults to process.cwd())
|
|
29
|
+
* @returns User configuration object or empty object if not found
|
|
30
|
+
*/
|
|
31
|
+
export declare function loadConfig(root?: string): Promise<ArcanaJSUserConfig>;
|
|
32
|
+
/**
|
|
33
|
+
* Resolve user configuration with defaults
|
|
34
|
+
*
|
|
35
|
+
* @param userConfig - User-provided configuration
|
|
36
|
+
* @param root - Project root directory
|
|
37
|
+
* @returns Fully resolved configuration with all defaults applied
|
|
38
|
+
*/
|
|
39
|
+
export declare function resolveConfig(userConfig: ArcanaJSUserConfig, root?: string): ResolvedArcanaJSConfig;
|
|
40
|
+
/**
|
|
41
|
+
* Load and resolve configuration in one step
|
|
42
|
+
*
|
|
43
|
+
* @param root - Project root directory
|
|
44
|
+
* @returns Fully resolved configuration
|
|
45
|
+
*/
|
|
46
|
+
export declare function loadAndResolveConfig(root?: string): Promise<ResolvedArcanaJSConfig>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* ArcanaJS Configuration System
|
|
4
|
+
*
|
|
5
|
+
* Provides utilities for loading and validating ArcanaJS configuration files.
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.defineConfig = defineConfig;
|
|
12
|
+
exports.loadConfig = loadConfig;
|
|
13
|
+
exports.resolveConfig = resolveConfig;
|
|
14
|
+
exports.loadAndResolveConfig = loadAndResolveConfig;
|
|
15
|
+
const fs_1 = __importDefault(require("fs"));
|
|
16
|
+
const path_1 = __importDefault(require("path"));
|
|
17
|
+
/**
|
|
18
|
+
* Define a configuration object with type safety
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* export default defineConfig({
|
|
23
|
+
* server: {
|
|
24
|
+
* port: 3000,
|
|
25
|
+
* },
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
function defineConfig(config) {
|
|
30
|
+
return config;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Load ArcanaJS configuration from project root
|
|
34
|
+
*
|
|
35
|
+
* Searches for:
|
|
36
|
+
* - arcanajs.config.js
|
|
37
|
+
* - arcanajs.config.ts
|
|
38
|
+
* - arcanajs.config.mjs
|
|
39
|
+
*
|
|
40
|
+
* @param root - Project root directory (defaults to process.cwd())
|
|
41
|
+
* @returns User configuration object or empty object if not found
|
|
42
|
+
*/
|
|
43
|
+
async function loadConfig(root = process.cwd()) {
|
|
44
|
+
const configFiles = [
|
|
45
|
+
"arcanajs.config.js",
|
|
46
|
+
"arcanajs.config.ts",
|
|
47
|
+
"arcanajs.config.mjs",
|
|
48
|
+
];
|
|
49
|
+
for (const configFile of configFiles) {
|
|
50
|
+
const configPath = path_1.default.resolve(root, configFile);
|
|
51
|
+
if (fs_1.default.existsSync(configPath)) {
|
|
52
|
+
try {
|
|
53
|
+
// For TypeScript files, we need ts-node or tsx
|
|
54
|
+
if (configFile.endsWith(".ts")) {
|
|
55
|
+
try {
|
|
56
|
+
require("tsx/cjs");
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
try {
|
|
60
|
+
require("ts-node/register");
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
console.warn(`Found ${configFile} but ts-node/tsx is not available. Skipping.`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const config = require(configPath);
|
|
69
|
+
return config.default || config;
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
console.error(`Error loading config from ${configPath}:`, error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Resolve user configuration with defaults
|
|
80
|
+
*
|
|
81
|
+
* @param userConfig - User-provided configuration
|
|
82
|
+
* @param root - Project root directory
|
|
83
|
+
* @returns Fully resolved configuration with all defaults applied
|
|
84
|
+
*/
|
|
85
|
+
function resolveConfig(userConfig, root = process.cwd()) {
|
|
86
|
+
const mode = process.env.NODE_ENV || "development";
|
|
87
|
+
return {
|
|
88
|
+
root,
|
|
89
|
+
mode,
|
|
90
|
+
server: {
|
|
91
|
+
port: userConfig.server?.port || process.env.PORT || 3000,
|
|
92
|
+
staticDir: userConfig.server?.staticDir || "public",
|
|
93
|
+
distDir: userConfig.server?.distDir || "dist/public",
|
|
94
|
+
},
|
|
95
|
+
build: {
|
|
96
|
+
outDir: userConfig.build?.outDir || "dist",
|
|
97
|
+
sourcemap: userConfig.build?.sourcemap ?? mode === "development",
|
|
98
|
+
minify: userConfig.build?.minify ?? mode === "production",
|
|
99
|
+
},
|
|
100
|
+
views: {
|
|
101
|
+
dir: userConfig.views?.dir || "src/views",
|
|
102
|
+
layout: userConfig.views?.layout,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Load and resolve configuration in one step
|
|
108
|
+
*
|
|
109
|
+
* @param root - Project root directory
|
|
110
|
+
* @returns Fully resolved configuration
|
|
111
|
+
*/
|
|
112
|
+
async function loadAndResolveConfig(root = process.cwd()) {
|
|
113
|
+
const userConfig = await loadConfig(root);
|
|
114
|
+
return resolveConfig(userConfig, root);
|
|
115
|
+
}
|
|
@@ -1,3 +1,63 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Webpack Global Variables
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
1
5
|
declare var __non_webpack_require__: NodeRequire;
|
|
2
6
|
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// CSS Module Declarations
|
|
9
|
+
// ============================================================================
|
|
10
|
+
|
|
11
|
+
// Global CSS files
|
|
3
12
|
declare module "*.css";
|
|
13
|
+
|
|
14
|
+
// CSS Modules
|
|
15
|
+
declare module "*.module.css" {
|
|
16
|
+
const classes: { readonly [key: string]: string };
|
|
17
|
+
export default classes;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// Express Augmentation
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
declare global {
|
|
25
|
+
namespace Express {
|
|
26
|
+
interface Response {
|
|
27
|
+
/**
|
|
28
|
+
* Render a page component with data
|
|
29
|
+
* @param page - Name of the page component to render
|
|
30
|
+
* @param data - Data to pass to the page component
|
|
31
|
+
*/
|
|
32
|
+
renderPage(page: string, data?: any): void;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Send a success JSON response
|
|
36
|
+
* @param data - Data to send in the response
|
|
37
|
+
* @param message - Optional success message
|
|
38
|
+
* @param status - HTTP status code (default: 200)
|
|
39
|
+
*/
|
|
40
|
+
success(
|
|
41
|
+
data?: string | object | null,
|
|
42
|
+
message?: string,
|
|
43
|
+
status?: number
|
|
44
|
+
): Response;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Send an error JSON response
|
|
48
|
+
* @param message - Error message
|
|
49
|
+
* @param status - HTTP status code (default: 500)
|
|
50
|
+
* @param error - Error details
|
|
51
|
+
* @param data - Additional error data
|
|
52
|
+
*/
|
|
53
|
+
error(
|
|
54
|
+
message?: string,
|
|
55
|
+
status?: number,
|
|
56
|
+
error?: string | object | null,
|
|
57
|
+
data?: string | object | null
|
|
58
|
+
): Response;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export {};
|
package/framework/lib/index.d.ts
CHANGED
package/framework/lib/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
// ============================================================================
|
|
3
|
+
// Component Exports
|
|
4
|
+
// ============================================================================
|
|
2
5
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
6
|
if (k2 === undefined) k2 = k;
|
|
4
7
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -23,18 +26,33 @@ __exportStar(require("./shared/components/Head"), exports);
|
|
|
23
26
|
__exportStar(require("./shared/components/Link"), exports);
|
|
24
27
|
__exportStar(require("./shared/components/NavLink"), exports);
|
|
25
28
|
__exportStar(require("./shared/components/Page"), exports);
|
|
29
|
+
// ============================================================================
|
|
30
|
+
// Context Exports
|
|
31
|
+
// ============================================================================
|
|
26
32
|
__exportStar(require("./shared/context/HeadContext"), exports);
|
|
27
33
|
__exportStar(require("./shared/context/PageContext"), exports);
|
|
28
34
|
__exportStar(require("./shared/context/RouterContext"), exports);
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// Core Exports
|
|
37
|
+
// ============================================================================
|
|
29
38
|
__exportStar(require("./shared/core/ArcanaJSApp"), exports);
|
|
39
|
+
// ============================================================================
|
|
40
|
+
// Hook Exports
|
|
41
|
+
// ============================================================================
|
|
30
42
|
__exportStar(require("./shared/hooks/useHead"), exports);
|
|
31
43
|
__exportStar(require("./shared/hooks/useLocation"), exports);
|
|
32
44
|
__exportStar(require("./shared/hooks/usePage"), exports);
|
|
33
45
|
__exportStar(require("./shared/hooks/useParams"), exports);
|
|
34
46
|
__exportStar(require("./shared/hooks/useQuery"), exports);
|
|
35
47
|
__exportStar(require("./shared/hooks/useRouter"), exports);
|
|
36
|
-
//
|
|
48
|
+
// ============================================================================
|
|
49
|
+
// Default Error Views
|
|
50
|
+
// ============================================================================
|
|
37
51
|
var ErrorPage_1 = require("./shared/views/ErrorPage");
|
|
38
52
|
Object.defineProperty(exports, "ErrorPage", { enumerable: true, get: function () { return __importDefault(ErrorPage_1).default; } });
|
|
39
53
|
var NotFoundPage_1 = require("./shared/views/NotFoundPage");
|
|
40
54
|
Object.defineProperty(exports, "NotFoundPage", { enumerable: true, get: function () { return __importDefault(NotFoundPage_1).default; } });
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// Type Exports
|
|
57
|
+
// ============================================================================
|
|
58
|
+
__exportStar(require("./types"), exports);
|
|
@@ -131,9 +131,9 @@ class ArcanaJSServer {
|
|
|
131
131
|
try {
|
|
132
132
|
// Use __non_webpack_require__ if available to avoid Webpack bundling issues
|
|
133
133
|
// or standard require if running in Node directly
|
|
134
|
-
const requireFunc = typeof __non_webpack_require__ !== "undefined"
|
|
135
|
-
? __non_webpack_require__
|
|
136
|
-
:
|
|
134
|
+
const requireFunc = typeof globalThis.__non_webpack_require__ !== "undefined"
|
|
135
|
+
? globalThis.__non_webpack_require__
|
|
136
|
+
: require;
|
|
137
137
|
// Register ts-node if needed
|
|
138
138
|
if (file.endsWith(".tsx") || file.endsWith(".ts")) {
|
|
139
139
|
try {
|
|
@@ -4,13 +4,29 @@ export * from "./server/ArcanaJSMiddleware";
|
|
|
4
4
|
export * from "./server/ArcanaJSServer";
|
|
5
5
|
export { default as ControllerBinder } from "./server/ControllerBinder";
|
|
6
6
|
export * from "./server/DynamicRouter";
|
|
7
|
-
export * from "./server/ResponseHandlerMiddleware";
|
|
8
7
|
export * from "./server/Router";
|
|
9
8
|
export { default as Route } from "./server/Router";
|
|
9
|
+
export * from "./server/CsrfMiddleware";
|
|
10
|
+
export * from "./server/ResponseHandlerMiddleware";
|
|
10
11
|
/**
|
|
11
12
|
* Create an ArcanaJS server with the given Express app
|
|
12
|
-
*
|
|
13
|
-
* @param
|
|
13
|
+
*
|
|
14
|
+
* @param app - Express application instance
|
|
15
|
+
* @param config - Optional ArcanaJS configuration
|
|
14
16
|
* @returns ArcanaJSServer instance
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import express from 'express';
|
|
21
|
+
* import { createArcanaServer } from 'arcanajs/server';
|
|
22
|
+
*
|
|
23
|
+
* const app = express();
|
|
24
|
+
* const server = createArcanaServer(app, {
|
|
25
|
+
* port: 3000,
|
|
26
|
+
* viewsDir: 'src/views',
|
|
27
|
+
* });
|
|
28
|
+
*
|
|
29
|
+
* server.start();
|
|
30
|
+
* ```
|
|
15
31
|
*/
|
|
16
32
|
export declare function createArcanaServer(app: Express, config?: Partial<ArcanaJSConfig>): ArcanaJSServer;
|
package/framework/lib/server.js
CHANGED
|
@@ -20,20 +20,48 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
20
20
|
exports.Route = exports.ControllerBinder = void 0;
|
|
21
21
|
exports.createArcanaServer = createArcanaServer;
|
|
22
22
|
const ArcanaJSServer_1 = require("./server/ArcanaJSServer");
|
|
23
|
+
// ============================================================================
|
|
24
|
+
// Server Core Exports
|
|
25
|
+
// ============================================================================
|
|
23
26
|
__exportStar(require("./server/ArcanaJSMiddleware"), exports);
|
|
24
27
|
__exportStar(require("./server/ArcanaJSServer"), exports);
|
|
25
28
|
var ControllerBinder_1 = require("./server/ControllerBinder");
|
|
26
29
|
Object.defineProperty(exports, "ControllerBinder", { enumerable: true, get: function () { return __importDefault(ControllerBinder_1).default; } });
|
|
30
|
+
// ============================================================================
|
|
31
|
+
// Routing Exports
|
|
32
|
+
// ============================================================================
|
|
27
33
|
__exportStar(require("./server/DynamicRouter"), exports);
|
|
28
|
-
__exportStar(require("./server/ResponseHandlerMiddleware"), exports);
|
|
29
34
|
__exportStar(require("./server/Router"), exports);
|
|
30
35
|
var Router_1 = require("./server/Router");
|
|
31
36
|
Object.defineProperty(exports, "Route", { enumerable: true, get: function () { return __importDefault(Router_1).default; } });
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Middleware Exports
|
|
39
|
+
// ============================================================================
|
|
40
|
+
__exportStar(require("./server/CsrfMiddleware"), exports);
|
|
41
|
+
__exportStar(require("./server/ResponseHandlerMiddleware"), exports);
|
|
42
|
+
// ============================================================================
|
|
43
|
+
// Server Factory Function
|
|
44
|
+
// ============================================================================
|
|
32
45
|
/**
|
|
33
46
|
* Create an ArcanaJS server with the given Express app
|
|
34
|
-
*
|
|
35
|
-
* @param
|
|
47
|
+
*
|
|
48
|
+
* @param app - Express application instance
|
|
49
|
+
* @param config - Optional ArcanaJS configuration
|
|
36
50
|
* @returns ArcanaJSServer instance
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import express from 'express';
|
|
55
|
+
* import { createArcanaServer } from 'arcanajs/server';
|
|
56
|
+
*
|
|
57
|
+
* const app = express();
|
|
58
|
+
* const server = createArcanaServer(app, {
|
|
59
|
+
* port: 3000,
|
|
60
|
+
* viewsDir: 'src/views',
|
|
61
|
+
* });
|
|
62
|
+
*
|
|
63
|
+
* server.start();
|
|
64
|
+
* ```
|
|
37
65
|
*/
|
|
38
66
|
function createArcanaServer(app, config) {
|
|
39
67
|
const server = new ArcanaJSServer_1.ArcanaJSServer({ ...config });
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArcanaJS Framework - Centralized Type Definitions
|
|
3
|
+
*
|
|
4
|
+
* This file exports all public TypeScript types and interfaces
|
|
5
|
+
* for the ArcanaJS framework.
|
|
6
|
+
*/
|
|
7
|
+
export type { ArcanaJSConfig } from "./server/ArcanaJSServer";
|
|
8
|
+
export type { ArcanaJSAppProps } from "./shared/core/ArcanaJSApp";
|
|
9
|
+
export type { HeadManager } from "./shared/context/HeadContext";
|
|
10
|
+
export type { RouterContextType } from "./shared/context/RouterContext";
|
|
11
|
+
import type React from "react";
|
|
12
|
+
/**
|
|
13
|
+
* Props for the Page component
|
|
14
|
+
*/
|
|
15
|
+
export interface PageProps {
|
|
16
|
+
data?: any;
|
|
17
|
+
children?: React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Props for the Head component
|
|
21
|
+
*/
|
|
22
|
+
export interface HeadProps {
|
|
23
|
+
children?: React.ReactNode;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Props for the Body component
|
|
27
|
+
*/
|
|
28
|
+
export interface BodyProps {
|
|
29
|
+
children?: React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Props for the Link component
|
|
33
|
+
*/
|
|
34
|
+
export interface LinkProps {
|
|
35
|
+
to: string;
|
|
36
|
+
children?: React.ReactNode;
|
|
37
|
+
className?: string;
|
|
38
|
+
[key: string]: any;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Props for the NavLink component
|
|
42
|
+
*/
|
|
43
|
+
export interface NavLinkProps extends LinkProps {
|
|
44
|
+
activeClassName?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Return type for useRouter hook
|
|
48
|
+
*/
|
|
49
|
+
export interface UseRouterReturn {
|
|
50
|
+
navigateTo: (url: string) => void;
|
|
51
|
+
currentPage: string;
|
|
52
|
+
currentUrl: string;
|
|
53
|
+
params: Record<string, string>;
|
|
54
|
+
csrfToken?: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Return type for useParams hook
|
|
58
|
+
*/
|
|
59
|
+
export type UseParamsReturn = Record<string, string>;
|
|
60
|
+
/**
|
|
61
|
+
* Return type for useLocation hook
|
|
62
|
+
*/
|
|
63
|
+
export interface UseLocationReturn {
|
|
64
|
+
pathname: string;
|
|
65
|
+
search: string;
|
|
66
|
+
hash: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Return type for useQuery hook
|
|
70
|
+
*/
|
|
71
|
+
export type UseQueryReturn = URLSearchParams;
|
|
72
|
+
/**
|
|
73
|
+
* Return type for usePage hook
|
|
74
|
+
*/
|
|
75
|
+
export type UsePageReturn = any;
|
|
76
|
+
/**
|
|
77
|
+
* Return type for useHead hook
|
|
78
|
+
*/
|
|
79
|
+
export interface UseHeadReturn {
|
|
80
|
+
push: (tags: React.ReactNode) => void;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* View component type - a React functional component that can receive data and params
|
|
84
|
+
*/
|
|
85
|
+
export type ViewComponent<T = any> = React.FC<{
|
|
86
|
+
data?: T;
|
|
87
|
+
params?: Record<string, string>;
|
|
88
|
+
navigateTo?: (url: string) => void;
|
|
89
|
+
}>;
|
|
90
|
+
/**
|
|
91
|
+
* Views registry - maps view names to view components
|
|
92
|
+
*/
|
|
93
|
+
export type ViewsRegistry = Record<string, React.FC<any>>;
|
|
94
|
+
/**
|
|
95
|
+
* Layout component type
|
|
96
|
+
*/
|
|
97
|
+
export type LayoutComponent = React.FC<{
|
|
98
|
+
children: React.ReactNode;
|
|
99
|
+
}>;
|
|
100
|
+
import type { RequestHandler } from "express";
|
|
101
|
+
/**
|
|
102
|
+
* Controller class type
|
|
103
|
+
*/
|
|
104
|
+
export type ControllerClass = new (...args: any[]) => any;
|
|
105
|
+
/**
|
|
106
|
+
* Route action - can be a handler function or a controller/method pair
|
|
107
|
+
*/
|
|
108
|
+
export type RouteAction = RequestHandler | [ControllerClass, string];
|
|
109
|
+
/**
|
|
110
|
+
* User-facing configuration for ArcanaJS
|
|
111
|
+
*/
|
|
112
|
+
export interface ArcanaJSUserConfig {
|
|
113
|
+
/**
|
|
114
|
+
* Server configuration
|
|
115
|
+
*/
|
|
116
|
+
server?: {
|
|
117
|
+
/**
|
|
118
|
+
* Port to run the server on
|
|
119
|
+
* @default 3000
|
|
120
|
+
*/
|
|
121
|
+
port?: number | string;
|
|
122
|
+
/**
|
|
123
|
+
* Static files directory
|
|
124
|
+
* @default "public"
|
|
125
|
+
*/
|
|
126
|
+
staticDir?: string;
|
|
127
|
+
/**
|
|
128
|
+
* Distribution directory for built assets
|
|
129
|
+
* @default "dist/public"
|
|
130
|
+
*/
|
|
131
|
+
distDir?: string;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Build configuration
|
|
135
|
+
*/
|
|
136
|
+
build?: {
|
|
137
|
+
/**
|
|
138
|
+
* Output directory for build
|
|
139
|
+
* @default "dist"
|
|
140
|
+
*/
|
|
141
|
+
outDir?: string;
|
|
142
|
+
/**
|
|
143
|
+
* Enable source maps
|
|
144
|
+
* @default true in development, false in production
|
|
145
|
+
*/
|
|
146
|
+
sourcemap?: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* Enable minification
|
|
149
|
+
* @default true in production, false in development
|
|
150
|
+
*/
|
|
151
|
+
minify?: boolean;
|
|
152
|
+
};
|
|
153
|
+
/**
|
|
154
|
+
* Views configuration
|
|
155
|
+
*/
|
|
156
|
+
views?: {
|
|
157
|
+
/**
|
|
158
|
+
* Directory containing view files
|
|
159
|
+
* @default "src/views"
|
|
160
|
+
*/
|
|
161
|
+
dir?: string;
|
|
162
|
+
/**
|
|
163
|
+
* Custom layout component
|
|
164
|
+
*/
|
|
165
|
+
layout?: LayoutComponent;
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Resolved internal configuration
|
|
170
|
+
*/
|
|
171
|
+
export interface ResolvedArcanaJSConfig extends Required<ArcanaJSUserConfig> {
|
|
172
|
+
root: string;
|
|
173
|
+
mode: "development" | "production";
|
|
174
|
+
}
|
|
@@ -298,13 +298,13 @@ export default function HomePage() {
|
|
|
298
298
|
</div>
|
|
299
299
|
<div className="text-white">npm run dev</div>
|
|
300
300
|
</div>
|
|
301
|
-
<div>
|
|
301
|
+
<div className="mb-4">
|
|
302
302
|
<div className="text-gray-500 mb-1">
|
|
303
303
|
# Build for production
|
|
304
304
|
</div>
|
|
305
305
|
<div className="text-white">npm run build</div>
|
|
306
306
|
</div>
|
|
307
|
-
<div>
|
|
307
|
+
<div className="mb-4">
|
|
308
308
|
<div className="text-gray-500 mb-1">
|
|
309
309
|
# Start production server
|
|
310
310
|
</div>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ArcanaJS Configuration Template
|
|
3
|
+
*
|
|
4
|
+
* This file defines the configuration for your ArcanaJS application.
|
|
5
|
+
*
|
|
6
|
+
* @type {import('arcanajs').ArcanaJSUserConfig}
|
|
7
|
+
*/
|
|
8
|
+
export default {
|
|
9
|
+
// Server configuration
|
|
10
|
+
server: {
|
|
11
|
+
// Port to run the server on
|
|
12
|
+
port: 3000,
|
|
13
|
+
|
|
14
|
+
// Static files directory
|
|
15
|
+
staticDir: "public",
|
|
16
|
+
|
|
17
|
+
// Distribution directory for built assets
|
|
18
|
+
distDir: "dist/public",
|
|
19
|
+
},
|
|
20
|
+
|
|
21
|
+
// Build configuration
|
|
22
|
+
build: {
|
|
23
|
+
// Output directory for build
|
|
24
|
+
outDir: "dist",
|
|
25
|
+
|
|
26
|
+
// Enable source maps (automatically set based on NODE_ENV)
|
|
27
|
+
// sourcemap: true,
|
|
28
|
+
|
|
29
|
+
// Enable minification (automatically set based on NODE_ENV)
|
|
30
|
+
// minify: true,
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
// Views configuration
|
|
34
|
+
views: {
|
|
35
|
+
// Directory containing view files
|
|
36
|
+
dir: "src/views",
|
|
37
|
+
|
|
38
|
+
// Custom layout component (optional)
|
|
39
|
+
// layout: undefined,
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ArcanaJSServer } from "arcanajs/server";
|
|
2
2
|
import webRoutes from "./routes/web";
|
|
3
3
|
|
|
4
|
+
const PORT = process.env.PORT || 3000;
|
|
5
|
+
|
|
4
6
|
const server = new ArcanaJSServer({
|
|
7
|
+
port: PORT,
|
|
5
8
|
routes: webRoutes,
|
|
6
9
|
});
|
|
7
10
|
|
|
8
|
-
const PORT = process.env.PORT || 3000;
|
|
9
|
-
|
|
10
11
|
server.start();
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"module": "ESNext",
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"esModuleInterop": true,
|
|
9
|
+
"allowSyntheticDefaultImports": true,
|
|
10
|
+
|
|
11
|
+
/* Bundler mode */
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"jsx": "react-jsx",
|
|
18
|
+
|
|
19
|
+
/* Linting */
|
|
20
|
+
"strict": true,
|
|
21
|
+
"noUnusedLocals": true,
|
|
22
|
+
"noUnusedParameters": true,
|
|
23
|
+
"noFallthroughCasesInSwitch": true
|
|
24
|
+
},
|
|
25
|
+
"include": ["src/**/*"],
|
|
26
|
+
"exclude": ["node_modules", "dist"]
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcanajs",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.0",
|
|
4
4
|
"description": "ArcanaJS Framework",
|
|
5
5
|
"main": "framework/lib/index.js",
|
|
6
6
|
"types": "framework/lib/index.d.ts",
|
|
@@ -16,7 +16,16 @@
|
|
|
16
16
|
"./client": {
|
|
17
17
|
"types": "./framework/lib/client/index.d.ts",
|
|
18
18
|
"default": "./framework/lib/client/index.js"
|
|
19
|
-
}
|
|
19
|
+
},
|
|
20
|
+
"./types": {
|
|
21
|
+
"types": "./framework/lib/types.d.ts",
|
|
22
|
+
"default": "./framework/lib/types.js"
|
|
23
|
+
},
|
|
24
|
+
"./config": {
|
|
25
|
+
"types": "./framework/lib/config/index.d.ts",
|
|
26
|
+
"default": "./framework/lib/config/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
20
29
|
},
|
|
21
30
|
"bin": {
|
|
22
31
|
"arcanajs": "./bin/arcanajs.js"
|
|
@@ -26,7 +35,7 @@
|
|
|
26
35
|
"bin"
|
|
27
36
|
],
|
|
28
37
|
"scripts": {
|
|
29
|
-
"build": "tsc -p tsconfig.json && cp src/lib/server/default-index.html framework/lib/server/ && cp src/lib/global.d.ts framework/lib/ && cp -r src/templates framework/"
|
|
38
|
+
"build": "tsc -p tsconfig.json && cp src/lib/server/default-index.html framework/lib/server/ && cp src/lib/global.d.ts framework/lib/ && cp -r src/templates framework/ && cp src/templates/arcanajs.config.js framework/templates/"
|
|
30
39
|
},
|
|
31
40
|
"dependencies": {
|
|
32
41
|
"@babel/core": "^7.23.0",
|