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.
@@ -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
- use: resolveLoader("null-loader"), // Ignore CSS on server side
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
- // devtool: isProduction ? "source-map" : "eval-source-map",
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 {};
@@ -15,3 +15,4 @@ export * from "./shared/hooks/useQuery";
15
15
  export * from "./shared/hooks/useRouter";
16
16
  export { default as ErrorPage } from "./shared/views/ErrorPage";
17
17
  export { default as NotFoundPage } from "./shared/views/NotFoundPage";
18
+ export * from "./types";
@@ -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
- // Default error views
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
- : module.require;
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
- * @param app Express application instance
13
- * @param config Optional ArcanaJS configuration
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;
@@ -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
- * @param app Express application instance
35
- * @param config Optional ArcanaJS configuration
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
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ /**
3
+ * ArcanaJS Framework - Centralized Type Definitions
4
+ *
5
+ * This file exports all public TypeScript types and interfaces
6
+ * for the ArcanaJS framework.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -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
+ };
@@ -0,0 +1,10 @@
1
+ declare var __non_webpack_require__: NodeRequire;
2
+
3
+ // Global CSS files
4
+ declare module "*.css";
5
+
6
+ // CSS Modules
7
+ declare module "*.module.css" {
8
+ const classes: { readonly [key: string]: string };
9
+ export default classes;
10
+ }
@@ -8,7 +8,7 @@
8
8
  "start": "arcanajs start"
9
9
  },
10
10
  "dependencies": {
11
- "arcanajs": "^2.2.1",
11
+ "arcanajs": "^2.3.0",
12
12
  "react": "^19.2.0",
13
13
  "react-dom": "^19.2.0"
14
14
  }
@@ -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.2.1",
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",