From 809890b0a55cbd9e815589e5686821a8d5a0ef02 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 07:54:53 +0700 Subject: [PATCH 01/35] fix: enable bundling and refine included files in vercel.json --- vercel.json | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/vercel.json b/vercel.json index 8cc328b..7641170 100644 --- a/vercel.json +++ b/vercel.json @@ -5,25 +5,11 @@ "src": "apps/web/index.js", "use": "@vercel/node", "config": { - "bundle": false, + "bundle": true, "includeFiles": [ - "apps/web/**", - "apps/api/**", - "packages/**", - "context/**", - "public/**", "resources/**", - "node_modules/@repo/**", - "node_modules/openai/**", - "node_modules/consola/**", - "node_modules/dotenv/**", - "node_modules/express/**", - "node_modules/ejs/**", - "node_modules/docx/**", - "node_modules/@dqbd/**", - "node_modules/express-rate-limit/**", - "node_modules/helmet/**", - "node_modules/sweetalert2/**" + "public/**", + "context/**" ] } } From 41410286d48f6ea6ee11a429a5cdfc6f92a09b6f Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:08:23 +0700 Subject: [PATCH 02/35] fix: update includeFiles in vercel.json for improved bundling --- vercel.json | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/vercel.json b/vercel.json index 7641170..7bed6a1 100644 --- a/vercel.json +++ b/vercel.json @@ -7,9 +7,23 @@ "config": { "bundle": true, "includeFiles": [ - "resources/**", + "apps/web/**", + "apps/api/**", + "packages/**", + "context/**", "public/**", - "context/**" + "resources/**", + "node_modules/@repo/**", + "node_modules/openai/**", + "node_modules/consola/**", + "node_modules/dotenv/**", + "node_modules/express/**", + "node_modules/ejs/**", + "node_modules/docx/**", + "node_modules/@dqbd/**", + "node_modules/express-rate-limit/**", + "node_modules/helmet/**", + "node_modules/sweetalert2/**" ] } } From 18ed85e6ad6398331b7b05b0c699941d618ba56d Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:10:58 +0700 Subject: [PATCH 03/35] feat: add initial vercel.json configuration for deployment --- apps/web/vercel.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 apps/web/vercel.json diff --git a/apps/web/vercel.json b/apps/web/vercel.json new file mode 100644 index 0000000..ebf9b13 --- /dev/null +++ b/apps/web/vercel.json @@ -0,0 +1,15 @@ +{ + "version": 2, + "builds": [ + { + "src": "index.js", + "use": "@vercel/node" + } + ], + "rewrites": [ + { + "source": "/(.*)", + "destination": "index.js" + } + ] +} \ No newline at end of file From 6790e7bfcd5229783edf5a6917b9e70bbc5ac373 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:19:43 +0700 Subject: [PATCH 04/35] fix: remove duplicate dependencies in package.json --- apps/web/package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/web/package.json b/apps/web/package.json index 2aafd69..741904c 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -12,6 +12,9 @@ "license": "Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)", "type": "module", "dependencies": { + "@repo/api": "^1.0.0", + "@repo/handlers": "^1.0.0", + "@repo/utils": "^1.0.0", "consola": "^3.4.2", "dotenv": "^17.4.2", "ejs": "^5.0.2", From 04215be1cdd1cc6f60376e9c7a7b059459686cf2 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:19:49 +0700 Subject: [PATCH 05/35] feat: add config section with includeFiles for Vercel deployment --- apps/web/vercel.json | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/apps/web/vercel.json b/apps/web/vercel.json index ebf9b13..b3912de 100644 --- a/apps/web/vercel.json +++ b/apps/web/vercel.json @@ -3,7 +3,28 @@ "builds": [ { "src": "index.js", - "use": "@vercel/node" + "use": "@vercel/node", + "config": { + "bundle": true, + "includeFiles": [ + "../api/**", + "../../packages/**", + "../../context/**", + "../../public/**", + "../../resources/**", + "node_modules/@repo/**", + "node_modules/openai/**", + "node_modules/consola/**", + "node_modules/dotenv/**", + "node_modules/express/**", + "node_modules/ejs/**", + "node_modules/docx/**", + "node_modules/@dqbd/**", + "node_modules/express-rate-limit/**", + "node_modules/helmet/**", + "node_modules/sweetalert2/**" + ] + } } ], "rewrites": [ From e211362a3982c6c403a9bf149e077f9b2d9707a2 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:24:21 +0700 Subject: [PATCH 06/35] fix: update dependencies in package.json for core and handlers packages --- apps/api/package.json | 2 ++ packages/core/package.json | 7 ++++++- packages/handlers/package.json | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/api/package.json b/apps/api/package.json index 18efb18..e738366 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -12,6 +12,8 @@ "license": "Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)", "type": "module", "dependencies": { + "@repo/handlers": "^1.0.0", + "@repo/utils": "^1.0.0", "consola": "^3.4.2", "dotenv": "^17.4.2", "express": "^5.2.1", diff --git a/packages/core/package.json b/packages/core/package.json index b18b391..ccd57f1 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -6,11 +6,16 @@ "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, - "keywords": ["modul-ajar", "generator", "core"], + "keywords": [ + "modul-ajar", + "generator", + "core" + ], "author": "NgodingCik", "license": "Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)", "type": "module", "dependencies": { + "@repo/utils": "^1.0.0", "consola": "^3.4.2", "openai": "^6.35.0" } diff --git a/packages/handlers/package.json b/packages/handlers/package.json index 5389229..01db726 100644 --- a/packages/handlers/package.json +++ b/packages/handlers/package.json @@ -15,6 +15,8 @@ "license": "Attribution-NonCommercial 4.0 International (CC BY-NC 4.0)", "type": "module", "dependencies": { + "@repo/core": "^1.0.0", + "@repo/utils": "^1.0.0", "consola": "^3.4.2", "docx": "^9.6.1" } From 6d46b6f29538eb8f6d40ffe72a1b8094dcb350c3 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:26:25 +0700 Subject: [PATCH 07/35] chore: remove vercel.json configuration file --- vercel.json | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100644 vercel.json diff --git a/vercel.json b/vercel.json deleted file mode 100644 index 7bed6a1..0000000 --- a/vercel.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "version": 2, - "builds": [ - { - "src": "apps/web/index.js", - "use": "@vercel/node", - "config": { - "bundle": true, - "includeFiles": [ - "apps/web/**", - "apps/api/**", - "packages/**", - "context/**", - "public/**", - "resources/**", - "node_modules/@repo/**", - "node_modules/openai/**", - "node_modules/consola/**", - "node_modules/dotenv/**", - "node_modules/express/**", - "node_modules/ejs/**", - "node_modules/docx/**", - "node_modules/@dqbd/**", - "node_modules/express-rate-limit/**", - "node_modules/helmet/**", - "node_modules/sweetalert2/**" - ] - } - } - ], - "rewrites": [ - { - "source": "/(.*)", - "destination": "/apps/web/index.js" - } - ] -} \ No newline at end of file From 2cb1b0ca154eafdbbc5a063ce70360e46df28263 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:36:54 +0700 Subject: [PATCH 08/35] feat: add initial vercel.json configuration for deployment --- apps/web/vercel.json => vercel.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) rename apps/web/vercel.json => vercel.json (75%) diff --git a/apps/web/vercel.json b/vercel.json similarity index 75% rename from apps/web/vercel.json rename to vercel.json index b3912de..a0af485 100644 --- a/apps/web/vercel.json +++ b/vercel.json @@ -2,16 +2,16 @@ "version": 2, "builds": [ { - "src": "index.js", + "src": "apps/web/index.js", "use": "@vercel/node", "config": { "bundle": true, "includeFiles": [ - "../api/**", - "../../packages/**", - "../../context/**", - "../../public/**", - "../../resources/**", + "apps/api/**", + "packages/**", + "context/**", + "public/**", + "resources/**", "node_modules/@repo/**", "node_modules/openai/**", "node_modules/consola/**", @@ -30,7 +30,7 @@ "rewrites": [ { "source": "/(.*)", - "destination": "index.js" + "destination": "/apps/web/index.js" } ] } \ No newline at end of file From b0e56220571897acdc28ae67f2f3cbb221bf0b61 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:48:39 +0700 Subject: [PATCH 09/35] fix: set bundle to false in Vercel configuration --- vercel.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index a0af485..8cc328b 100644 --- a/vercel.json +++ b/vercel.json @@ -5,8 +5,9 @@ "src": "apps/web/index.js", "use": "@vercel/node", "config": { - "bundle": true, + "bundle": false, "includeFiles": [ + "apps/web/**", "apps/api/**", "packages/**", "context/**", From b7a6ac10e5025e996af3d10c7a77ed4d67d9fd91 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:59:03 +0700 Subject: [PATCH 10/35] fix: update environment variable names for OpenAI configuration --- .env.example | 4 ++-- .env.schema | 4 ++-- apps/web/.env.example | 4 ++-- apps/web/.env.schema | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.env.example b/.env.example index b52578a..5359dcb 100644 --- a/.env.example +++ b/.env.example @@ -5,7 +5,7 @@ APP_PORT=3000 APP_HOST="0.0.0.0" # Base URL for API requests APP_API_BASE_URL=http://localhost:3000/api -# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by OPENAI_API_BASE_URL and not use the built-in API routes) +# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by APP_API_BASE_URL and not use the built-in API routes) APP_USE_BUILTIN_API=true # --- CORS configuration --- @@ -17,4 +17,4 @@ CORS_TRUSTED_CDN_HOSTS="cdn.example.com" # --- OpenAI configuration --- OPENAI_API_KEY="your-openai-api-key-here" OPENAI_MODEL="gpt-3.5-turbo" -OPENAI_API_BASE_URL="https://api.openai.com/v1" \ No newline at end of file +OPENAI_BASE_URL="https://api.openai.com/v1" \ No newline at end of file diff --git a/.env.schema b/.env.schema index 8d25681..af0d3f9 100644 --- a/.env.schema +++ b/.env.schema @@ -5,7 +5,7 @@ APP_PORT= APP_HOST= # Base URL for API requests APP_API_BASE_URL= -# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by OPENAI_API_BASE_URL and not use the built-in API routes) +# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by APP_API_BASE_URL and not use the built-in API routes) APP_USE_BUILTIN_API= # --- CORS configuration --- @@ -17,4 +17,4 @@ CORS_TRUSTED_CDN_HOSTS= # --- OpenAI configuration --- OPENAI_API_KEY= OPENAI_MODEL= -OPENAI_API_BASE_URL= \ No newline at end of file +OPENAI_BASE_URL= \ No newline at end of file diff --git a/apps/web/.env.example b/apps/web/.env.example index b52578a..5359dcb 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -5,7 +5,7 @@ APP_PORT=3000 APP_HOST="0.0.0.0" # Base URL for API requests APP_API_BASE_URL=http://localhost:3000/api -# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by OPENAI_API_BASE_URL and not use the built-in API routes) +# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by APP_API_BASE_URL and not use the built-in API routes) APP_USE_BUILTIN_API=true # --- CORS configuration --- @@ -17,4 +17,4 @@ CORS_TRUSTED_CDN_HOSTS="cdn.example.com" # --- OpenAI configuration --- OPENAI_API_KEY="your-openai-api-key-here" OPENAI_MODEL="gpt-3.5-turbo" -OPENAI_API_BASE_URL="https://api.openai.com/v1" \ No newline at end of file +OPENAI_BASE_URL="https://api.openai.com/v1" \ No newline at end of file diff --git a/apps/web/.env.schema b/apps/web/.env.schema index 8d25681..af0d3f9 100644 --- a/apps/web/.env.schema +++ b/apps/web/.env.schema @@ -5,7 +5,7 @@ APP_PORT= APP_HOST= # Base URL for API requests APP_API_BASE_URL= -# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by OPENAI_API_BASE_URL and not use the built-in API routes) +# Flag to determine whether to use the built-in API or an external API (if true, it will use the built-in API; if false, it will use the external API defined by APP_API_BASE_URL and not use the built-in API routes) APP_USE_BUILTIN_API= # --- CORS configuration --- @@ -17,4 +17,4 @@ CORS_TRUSTED_CDN_HOSTS= # --- OpenAI configuration --- OPENAI_API_KEY= OPENAI_MODEL= -OPENAI_API_BASE_URL= \ No newline at end of file +OPENAI_BASE_URL= \ No newline at end of file From 5f3f985d71d3e0ba4ea6c3ae5e5413753c16b7ca Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:59:15 +0700 Subject: [PATCH 11/35] fix: correct environment variable name for OpenAI base URL in deployment documentation --- docs/deploy/vercel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deploy/vercel.md b/docs/deploy/vercel.md index fed8e48..4ad9b2e 100644 --- a/docs/deploy/vercel.md +++ b/docs/deploy/vercel.md @@ -6,7 +6,7 @@ As you can see, this project includes a `vercel.json` file containing the configuration for Vercel deployment. Follow the steps below to deploy: > [!NOTE] -> To change the OpenAI base URL, you can update the `OPENAI_API_BASE_URL` environment variable in Vercel according to your needs. +> To change the OpenAI base URL, you can update the `OPENAI_BASE_URL` environment variable in Vercel according to your needs. ## Quick Start with Deploy Button From d3fde18e3f1eeec5eab8a3d2c133639bfbcd246d Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 08:59:24 +0700 Subject: [PATCH 12/35] fix: ensure OpenAI API key is properly handled as a string --- packages/handlers/handle-autofill-ai.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/handlers/handle-autofill-ai.js b/packages/handlers/handle-autofill-ai.js index 5509567..7bbf21e 100644 --- a/packages/handlers/handle-autofill-ai.js +++ b/packages/handlers/handle-autofill-ai.js @@ -14,7 +14,7 @@ import OpenAIWrapper from '@repo/core/ai/openai-wrapper.js' const __dirname = import.meta.dirname -const openai = new OpenAIWrapper(String(process.env.OPENAI_API_KEY), String(process.env.OPENAI_MODEL) || 'gpt-4.1-2025-04-14', String(process.env.OPENAI_BASE_URL) || null) +const openai = new OpenAIWrapper(process.env.OPENAI_API_KEY || '', process.env.OPENAI_MODEL || 'gpt-4.1-2025-04-14', process.env.OPENAI_BASE_URL || null) /** @type {Message[]} */ openai.context = [ From 7a737f760dd9b8c0dc1f44e570b6d1ceb720c9bc Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 09:00:19 +0700 Subject: [PATCH 13/35] fix: ensure OpenAI API key is handled as a string --- packages/handlers/handle-generate-docx.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/handlers/handle-generate-docx.js b/packages/handlers/handle-generate-docx.js index c5ae662..81af8c1 100644 --- a/packages/handlers/handle-generate-docx.js +++ b/packages/handlers/handle-generate-docx.js @@ -12,7 +12,7 @@ import * as docxCoverPage from '../scripts/docx/docx-cover-page.js' const __dirname = import.meta.dirname -const openai = new OpenAIWrapper(String(process.env.OPENAI_API_KEY), String(process.env.OPENAI_MODEL) || 'gpt-4.1-2025-04-14', String(process.env.OPENAI_BASE_URL) || null) +const openai = new OpenAIWrapper(process.env.OPENAI_API_KEY || '', process.env.OPENAI_MODEL || 'gpt-4.1-2025-04-14', process.env.OPENAI_BASE_URL || null) openai.loadContextsFromDir(path.join(__dirname, '../../context')) From 13de81a9fe1f85421bba0ea33434278e2cc9e3d4 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 09:07:36 +0700 Subject: [PATCH 14/35] fix: add Cloudflare Insights URL to script-src in helmet middleware --- apps/api/middleware/helmet.js | 2 +- apps/web/middleware/helmet.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api/middleware/helmet.js b/apps/api/middleware/helmet.js index 435a40d..ac13aaf 100644 --- a/apps/api/middleware/helmet.js +++ b/apps/api/middleware/helmet.js @@ -13,7 +13,7 @@ const helmetMiddleware = helmet({ 'upgrade-insecure-requests': isDevelopment ? null : [], 'frame-ancestors': ["'self'", ...CORS_TRUSTED_HOSTS], - 'script-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], + 'script-src': ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com', ...CORS_TRUSTED_CDN_HOSTS], 'style-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], 'img-src': ["'self'", 'data:', 'https://contrib.rocks', ...CORS_TRUSTED_CDN_HOSTS], 'font-src': ["'self'", ...CORS_TRUSTED_CDN_HOSTS] diff --git a/apps/web/middleware/helmet.js b/apps/web/middleware/helmet.js index 435a40d..ac13aaf 100644 --- a/apps/web/middleware/helmet.js +++ b/apps/web/middleware/helmet.js @@ -13,7 +13,7 @@ const helmetMiddleware = helmet({ 'upgrade-insecure-requests': isDevelopment ? null : [], 'frame-ancestors': ["'self'", ...CORS_TRUSTED_HOSTS], - 'script-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], + 'script-src': ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com', ...CORS_TRUSTED_CDN_HOSTS], 'style-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], 'img-src': ["'self'", 'data:', 'https://contrib.rocks', ...CORS_TRUSTED_CDN_HOSTS], 'font-src': ["'self'", ...CORS_TRUSTED_CDN_HOSTS] From 13c8902dce1bd99ccdca5971278d7b92ebf65ed2 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 09:16:33 +0700 Subject: [PATCH 15/35] fix: include assets directory in Vercel configuration --- vercel.json | 1 + 1 file changed, 1 insertion(+) diff --git a/vercel.json b/vercel.json index 8cc328b..b23d3af 100644 --- a/vercel.json +++ b/vercel.json @@ -12,6 +12,7 @@ "packages/**", "context/**", "public/**", + "assets/**", "resources/**", "node_modules/@repo/**", "node_modules/openai/**", From 72c7f63a6af2f1120885ca18b4188fa6354d16b2 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 09:38:58 +0700 Subject: [PATCH 16/35] feat: add Vercel configuration for deployment --- apps/web/vercel.json | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 apps/web/vercel.json diff --git a/apps/web/vercel.json b/apps/web/vercel.json new file mode 100644 index 0000000..78cc0e6 --- /dev/null +++ b/apps/web/vercel.json @@ -0,0 +1,38 @@ +{ + "version": 2, + "builds": [ + { + "src": "index.js", + "use": "@vercel/node", + "config": { + "bundle": false, + "includeFiles": [ + "**", + "../api/**", + "../../packages/**", + "../../context/**", + "../../public/**", + "../../assets/**", + "../../resources/**", + "../../node_modules/@repo/**", + "../../node_modules/openai/**", + "../../node_modules/consola/**", + "../../node_modules/dotenv/**", + "../../node_modules/express/**", + "../../node_modules/ejs/**", + "../../node_modules/docx/**", + "../../node_modules/@dqbd/**", + "../../node_modules/express-rate-limit/**", + "../../node_modules/helmet/**", + "../../node_modules/sweetalert2/**" + ] + } + } + ], + "rewrites": [ + { + "source": "/(.*)", + "destination": "/index.js" + } + ] +} \ No newline at end of file From a94d16196f834e79cc55966efd0b1a9b88498057 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 09:40:15 +0700 Subject: [PATCH 17/35] feat: add Vercel configuration for deployment --- apps/api/vercel.json | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 apps/api/vercel.json diff --git a/apps/api/vercel.json b/apps/api/vercel.json new file mode 100644 index 0000000..efe138a --- /dev/null +++ b/apps/api/vercel.json @@ -0,0 +1,35 @@ +{ + "version": 2, + "builds": [ + { + "src": "index.js", + "use": "@vercel/node", + "config": { + "bundle": false, + "includeFiles": [ + "**", + "../../packages/**", + "../../context/**", + "../../public/**", + "../../assets/**", + "../../resources/**", + "../../node_modules/@repo/**", + "../../node_modules/openai/**", + "../../node_modules/consola/**", + "../../node_modules/dotenv/**", + "../../node_modules/express/**", + "../../node_modules/docx/**", + "../../node_modules/@dqbd/**", + "../../node_modules/express-rate-limit/**", + "../../node_modules/helmet/**" + ] + } + } + ], + "rewrites": [ + { + "source": "/(.*)", + "destination": "/index.js" + } + ] +} \ No newline at end of file From b19d8d307afe7c57074a4de22f9829b5f96cef5b Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 10:04:48 +0700 Subject: [PATCH 18/35] fix: update helmet middleware to include APP_API_BASE_URL and adjust script-src directives --- apps/web/middleware/helmet.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/web/middleware/helmet.js b/apps/web/middleware/helmet.js index ac13aaf..65f4eda 100644 --- a/apps/web/middleware/helmet.js +++ b/apps/web/middleware/helmet.js @@ -4,6 +4,7 @@ const CORS_TRUSTED_HOSTS = process.env.CORS_TRUSTED_HOSTS ? process.env.CORS_TRU const CORS_TRUSTED_CDN_HOSTS = process.env.CORS_TRUSTED_CDN_HOSTS ? process.env.CORS_TRUSTED_CDN_HOSTS.split(',').map(host => host.trim()) : [] +const APP_API_BASE_URL = process.env.APP_API_BASE_URL || null const isDevelopment = process.env.NODE_ENV !== 'production' const helmetMiddleware = helmet({ @@ -13,10 +14,11 @@ const helmetMiddleware = helmet({ 'upgrade-insecure-requests': isDevelopment ? null : [], 'frame-ancestors': ["'self'", ...CORS_TRUSTED_HOSTS], - 'script-src': ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com', ...CORS_TRUSTED_CDN_HOSTS], + 'script-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], 'style-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], 'img-src': ["'self'", 'data:', 'https://contrib.rocks', ...CORS_TRUSTED_CDN_HOSTS], - 'font-src': ["'self'", ...CORS_TRUSTED_CDN_HOSTS] + 'font-src': ["'self'", ...CORS_TRUSTED_CDN_HOSTS], + 'connect-src': ["'self'", ...(APP_API_BASE_URL ? [APP_API_BASE_URL] : [])] } }, frameguard: false, From 71f36b3c0cd702b1d5f3de656bf96925f63de2eb Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 10:06:24 +0700 Subject: [PATCH 19/35] fix: update script-src directive in helmet middleware to include Cloudflare Insights URL --- apps/web/middleware/helmet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/middleware/helmet.js b/apps/web/middleware/helmet.js index 65f4eda..82d4100 100644 --- a/apps/web/middleware/helmet.js +++ b/apps/web/middleware/helmet.js @@ -14,7 +14,7 @@ const helmetMiddleware = helmet({ 'upgrade-insecure-requests': isDevelopment ? null : [], 'frame-ancestors': ["'self'", ...CORS_TRUSTED_HOSTS], - 'script-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], + 'script-src': ["'self'", "'unsafe-inline'", 'https://static.cloudflareinsights.com', ...CORS_TRUSTED_CDN_HOSTS], 'style-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], 'img-src': ["'self'", 'data:', 'https://contrib.rocks', ...CORS_TRUSTED_CDN_HOSTS], 'font-src': ["'self'", ...CORS_TRUSTED_CDN_HOSTS], From 99e0be96f892f92046bc22fd78bc0db7873dc8bf Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 10:12:45 +0700 Subject: [PATCH 20/35] fix: simplify CORS origin handling and remove unnecessary host checks --- apps/api/middleware/cors.js | 42 +++++++++++++------------------------ apps/web/middleware/cors.js | 42 +++++++++++++------------------------ 2 files changed, 30 insertions(+), 54 deletions(-) diff --git a/apps/api/middleware/cors.js b/apps/api/middleware/cors.js index f2f1684..f639dda 100644 --- a/apps/api/middleware/cors.js +++ b/apps/api/middleware/cors.js @@ -1,37 +1,23 @@ import consola from 'consola' const APP_ORIGIN_URL = process.env.APP_ORIGIN_URL || 'http://localhost:3000' -const APP_ORIGIN_HOST = new URL(APP_ORIGIN_URL).host const isDevelopment = process.env.NODE_ENV !== 'production' -if (!APP_ORIGIN_URL) { - throw new Error('APP_ORIGIN_URL environment variable is required') -} - -/** - * Helper function to check if the request host is allowed based on the configured APP_ORIGIN_URL. - * @param {string | undefined} host - The host from the request headers (e.g., 'localhost:3000') - * @returns {boolean} - */ -const isHostAllowed = (host) => { - if (!host) { - return isDevelopment - } - - return host === APP_ORIGIN_HOST -} +// Support wildcard '*' or comma-separated list of full origin URLs +// e.g. APP_ORIGIN_URL="https://modul-ajar.web.id,https://test.modul-ajar.web.id" +const ALLOWED_ORIGINS = APP_ORIGIN_URL === '*' + ? '*' + : APP_ORIGIN_URL.split(',').map(o => o.trim()) /** - * Helper function to check if the request origin is allowed based on the configured APP_ORIGIN_URL. - * @param {string} origin - The origin from the request headers (e.g., 'http://localhost:3000') + * Helper function to check if the request origin is allowed. + * @param {string | undefined} origin - The origin from the request headers (e.g., 'https://modul-ajar.web.id') * @returns {boolean} */ const isOriginAllowed = (origin) => { - if (!origin) { - return isDevelopment - } - - return origin === APP_ORIGIN_HOST + if (!origin) return isDevelopment + if (ALLOWED_ORIGINS === '*') return true + return ALLOWED_ORIGINS.includes(origin) } /** @@ -42,12 +28,14 @@ const isOriginAllowed = (origin) => { * @returns {import('express').Response | void} */ const cors = (req, res, next) => { - const origin = req.headers.origin || req.headers.host || '' + const origin = req.headers.origin || '' consola.debug(`CORS check - Origin: ${origin}, Host: ${req.headers.host}`) res.header('Vary', 'Origin') - if (isOriginAllowed(origin)) { + if (ALLOWED_ORIGINS === '*') { + res.header('Access-Control-Allow-Origin', '*') + } else if (isOriginAllowed(origin)) { res.header('Access-Control-Allow-Origin', origin) } @@ -64,7 +52,7 @@ const cors = (req, res, next) => { return res.sendStatus(204) } - if (!isOriginAllowed(origin) && !isHostAllowed(req.headers.host)) { + if (!isOriginAllowed(origin)) { consola.warn(`CORS blocked - origin not allowed: ${origin}`) return res.status(403).json({ status: false, message: '403 Forbidden', error: null }) } diff --git a/apps/web/middleware/cors.js b/apps/web/middleware/cors.js index f2f1684..f639dda 100644 --- a/apps/web/middleware/cors.js +++ b/apps/web/middleware/cors.js @@ -1,37 +1,23 @@ import consola from 'consola' const APP_ORIGIN_URL = process.env.APP_ORIGIN_URL || 'http://localhost:3000' -const APP_ORIGIN_HOST = new URL(APP_ORIGIN_URL).host const isDevelopment = process.env.NODE_ENV !== 'production' -if (!APP_ORIGIN_URL) { - throw new Error('APP_ORIGIN_URL environment variable is required') -} - -/** - * Helper function to check if the request host is allowed based on the configured APP_ORIGIN_URL. - * @param {string | undefined} host - The host from the request headers (e.g., 'localhost:3000') - * @returns {boolean} - */ -const isHostAllowed = (host) => { - if (!host) { - return isDevelopment - } - - return host === APP_ORIGIN_HOST -} +// Support wildcard '*' or comma-separated list of full origin URLs +// e.g. APP_ORIGIN_URL="https://modul-ajar.web.id,https://test.modul-ajar.web.id" +const ALLOWED_ORIGINS = APP_ORIGIN_URL === '*' + ? '*' + : APP_ORIGIN_URL.split(',').map(o => o.trim()) /** - * Helper function to check if the request origin is allowed based on the configured APP_ORIGIN_URL. - * @param {string} origin - The origin from the request headers (e.g., 'http://localhost:3000') + * Helper function to check if the request origin is allowed. + * @param {string | undefined} origin - The origin from the request headers (e.g., 'https://modul-ajar.web.id') * @returns {boolean} */ const isOriginAllowed = (origin) => { - if (!origin) { - return isDevelopment - } - - return origin === APP_ORIGIN_HOST + if (!origin) return isDevelopment + if (ALLOWED_ORIGINS === '*') return true + return ALLOWED_ORIGINS.includes(origin) } /** @@ -42,12 +28,14 @@ const isOriginAllowed = (origin) => { * @returns {import('express').Response | void} */ const cors = (req, res, next) => { - const origin = req.headers.origin || req.headers.host || '' + const origin = req.headers.origin || '' consola.debug(`CORS check - Origin: ${origin}, Host: ${req.headers.host}`) res.header('Vary', 'Origin') - if (isOriginAllowed(origin)) { + if (ALLOWED_ORIGINS === '*') { + res.header('Access-Control-Allow-Origin', '*') + } else if (isOriginAllowed(origin)) { res.header('Access-Control-Allow-Origin', origin) } @@ -64,7 +52,7 @@ const cors = (req, res, next) => { return res.sendStatus(204) } - if (!isOriginAllowed(origin) && !isHostAllowed(req.headers.host)) { + if (!isOriginAllowed(origin)) { consola.warn(`CORS blocked - origin not allowed: ${origin}`) return res.status(403).json({ status: false, message: '403 Forbidden', error: null }) } From 00c6d2a10686bbc5b65b5deb9c9c8b2cf57d7af0 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:18:13 +0700 Subject: [PATCH 21/35] fix: rename APP_ORIGIN_URL to APP_ORIGIN_HOST in environment configuration files --- .env.example | 3 ++- .env.schema | 3 ++- apps/web/.env.example | 3 ++- apps/web/.env.schema | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 5359dcb..4fb4ddb 100644 --- a/.env.example +++ b/.env.example @@ -1,6 +1,7 @@ # --- App configuration --- APP_NAME="My App" -APP_ORIGIN_URL="*" +# Comma-separated list of allowed CORS +APP_ORIGIN_HOST="*" APP_PORT=3000 APP_HOST="0.0.0.0" # Base URL for API requests diff --git a/.env.schema b/.env.schema index af0d3f9..fb0eedf 100644 --- a/.env.schema +++ b/.env.schema @@ -1,6 +1,7 @@ # --- App configuration --- APP_NAME= -APP_ORIGIN_URL= +# Comma-separated list of allowed CORS +APP_ORIGIN_HOST= APP_PORT= APP_HOST= # Base URL for API requests diff --git a/apps/web/.env.example b/apps/web/.env.example index 5359dcb..4fb4ddb 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -1,6 +1,7 @@ # --- App configuration --- APP_NAME="My App" -APP_ORIGIN_URL="*" +# Comma-separated list of allowed CORS +APP_ORIGIN_HOST="*" APP_PORT=3000 APP_HOST="0.0.0.0" # Base URL for API requests diff --git a/apps/web/.env.schema b/apps/web/.env.schema index af0d3f9..fb0eedf 100644 --- a/apps/web/.env.schema +++ b/apps/web/.env.schema @@ -1,6 +1,7 @@ # --- App configuration --- APP_NAME= -APP_ORIGIN_URL= +# Comma-separated list of allowed CORS +APP_ORIGIN_HOST= APP_PORT= APP_HOST= # Base URL for API requests From b8206d685fca994d91a34b2e54a27863da9eea7f Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:19:49 +0700 Subject: [PATCH 22/35] fix: rename APP_ORIGIN_URL to APP_ORIGIN_HOST and update CORS origin handling --- apps/api/middleware/cors.js | 10 +++++----- apps/web/middleware/cors.js | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/api/middleware/cors.js b/apps/api/middleware/cors.js index f639dda..06723f9 100644 --- a/apps/api/middleware/cors.js +++ b/apps/api/middleware/cors.js @@ -1,13 +1,13 @@ import consola from 'consola' -const APP_ORIGIN_URL = process.env.APP_ORIGIN_URL || 'http://localhost:3000' +const APP_ORIGIN_HOST = process.env.APP_ORIGIN_HOST || 'localhost' const isDevelopment = process.env.NODE_ENV !== 'production' // Support wildcard '*' or comma-separated list of full origin URLs -// e.g. APP_ORIGIN_URL="https://modul-ajar.web.id,https://test.modul-ajar.web.id" -const ALLOWED_ORIGINS = APP_ORIGIN_URL === '*' +// e.g. APP_ORIGIN_HOST="modul-ajar.web.id,test.modul-ajar.web.id" +const ALLOWED_ORIGINS = APP_ORIGIN_HOST === '*' ? '*' - : APP_ORIGIN_URL.split(',').map(o => o.trim()) + : APP_ORIGIN_HOST.split(',').map(o => o.trim()) /** * Helper function to check if the request origin is allowed. @@ -28,7 +28,7 @@ const isOriginAllowed = (origin) => { * @returns {import('express').Response | void} */ const cors = (req, res, next) => { - const origin = req.headers.origin || '' + const origin = (req.get('host') || req.get('origin') || req.headers.origin || '').split(':')[0] // Extract hostname without port consola.debug(`CORS check - Origin: ${origin}, Host: ${req.headers.host}`) res.header('Vary', 'Origin') diff --git a/apps/web/middleware/cors.js b/apps/web/middleware/cors.js index f639dda..06723f9 100644 --- a/apps/web/middleware/cors.js +++ b/apps/web/middleware/cors.js @@ -1,13 +1,13 @@ import consola from 'consola' -const APP_ORIGIN_URL = process.env.APP_ORIGIN_URL || 'http://localhost:3000' +const APP_ORIGIN_HOST = process.env.APP_ORIGIN_HOST || 'localhost' const isDevelopment = process.env.NODE_ENV !== 'production' // Support wildcard '*' or comma-separated list of full origin URLs -// e.g. APP_ORIGIN_URL="https://modul-ajar.web.id,https://test.modul-ajar.web.id" -const ALLOWED_ORIGINS = APP_ORIGIN_URL === '*' +// e.g. APP_ORIGIN_HOST="modul-ajar.web.id,test.modul-ajar.web.id" +const ALLOWED_ORIGINS = APP_ORIGIN_HOST === '*' ? '*' - : APP_ORIGIN_URL.split(',').map(o => o.trim()) + : APP_ORIGIN_HOST.split(',').map(o => o.trim()) /** * Helper function to check if the request origin is allowed. @@ -28,7 +28,7 @@ const isOriginAllowed = (origin) => { * @returns {import('express').Response | void} */ const cors = (req, res, next) => { - const origin = req.headers.origin || '' + const origin = (req.get('host') || req.get('origin') || req.headers.origin || '').split(':')[0] // Extract hostname without port consola.debug(`CORS check - Origin: ${origin}, Host: ${req.headers.host}`) res.header('Vary', 'Origin') From 41fafc03a8ded2b80ad745efa8fd8b9665c2394d Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:24:02 +0700 Subject: [PATCH 23/35] fix: rename APP_ORIGIN_HOST to APP_ORIGIN_HOSTS in configuration files --- .env.example | 2 +- .env.schema | 2 +- apps/web/.env.example | 2 +- apps/web/.env.schema | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index 4fb4ddb..ff8056f 100644 --- a/.env.example +++ b/.env.example @@ -1,7 +1,7 @@ # --- App configuration --- APP_NAME="My App" # Comma-separated list of allowed CORS -APP_ORIGIN_HOST="*" +APP_ORIGIN_HOSTS="*" APP_PORT=3000 APP_HOST="0.0.0.0" # Base URL for API requests diff --git a/.env.schema b/.env.schema index fb0eedf..476fbc7 100644 --- a/.env.schema +++ b/.env.schema @@ -1,7 +1,7 @@ # --- App configuration --- APP_NAME= # Comma-separated list of allowed CORS -APP_ORIGIN_HOST= +APP_ORIGIN_HOSTS= APP_PORT= APP_HOST= # Base URL for API requests diff --git a/apps/web/.env.example b/apps/web/.env.example index 4fb4ddb..ff8056f 100644 --- a/apps/web/.env.example +++ b/apps/web/.env.example @@ -1,7 +1,7 @@ # --- App configuration --- APP_NAME="My App" # Comma-separated list of allowed CORS -APP_ORIGIN_HOST="*" +APP_ORIGIN_HOSTS="*" APP_PORT=3000 APP_HOST="0.0.0.0" # Base URL for API requests diff --git a/apps/web/.env.schema b/apps/web/.env.schema index fb0eedf..476fbc7 100644 --- a/apps/web/.env.schema +++ b/apps/web/.env.schema @@ -1,7 +1,7 @@ # --- App configuration --- APP_NAME= # Comma-separated list of allowed CORS -APP_ORIGIN_HOST= +APP_ORIGIN_HOSTS= APP_PORT= APP_HOST= # Base URL for API requests From 6975aa9317987521517a9d9fe113d22521248286 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:25:04 +0700 Subject: [PATCH 24/35] fix: rename APP_ORIGIN_URL to APP_ORIGIN_HOSTS in configuration files --- apps/api/.env.example | 2 +- apps/api/.env.schema | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/api/.env.example b/apps/api/.env.example index b2758ad..da1f307 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -1,5 +1,5 @@ # --- App configuration --- -APP_ORIGIN_URL="*" +APP_ORIGIN_HOSTS="*" APP_PORT=3000 APP_HOST="0.0.0.0" diff --git a/apps/api/.env.schema b/apps/api/.env.schema index a57ef99..1d72f72 100644 --- a/apps/api/.env.schema +++ b/apps/api/.env.schema @@ -1,5 +1,5 @@ # --- App configuration --- -APP_ORIGIN_URL= +APP_ORIGIN_HOSTS= APP_PORT= APP_HOST= From c84a432c277ab2571d0276f30c0c7ad99108bb94 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:25:21 +0700 Subject: [PATCH 25/35] feat: add boot.js files for API and web with dotenv configuration --- apps/api/boot.js | 7 +++++++ apps/web/boot.js | 7 +++++++ 2 files changed, 14 insertions(+) create mode 100644 apps/api/boot.js create mode 100644 apps/web/boot.js diff --git a/apps/api/boot.js b/apps/api/boot.js new file mode 100644 index 0000000..36e50f3 --- /dev/null +++ b/apps/api/boot.js @@ -0,0 +1,7 @@ +import { config } from 'dotenv' +import { getEnvPath } from '@repo/utils/utils.js' + +const envPath = getEnvPath() +config({ path: envPath || undefined, override: true }) + +import('./index.js') diff --git a/apps/web/boot.js b/apps/web/boot.js new file mode 100644 index 0000000..36e50f3 --- /dev/null +++ b/apps/web/boot.js @@ -0,0 +1,7 @@ +import { config } from 'dotenv' +import { getEnvPath } from '@repo/utils/utils.js' + +const envPath = getEnvPath() +config({ path: envPath || undefined, override: true }) + +import('./index.js') From 846ebefd4dfbfb12a5c08e70e7cfc7e410bd5951 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:26:17 +0700 Subject: [PATCH 26/35] fix: update start and dev scripts to use boot.js for API and web applications --- apps/api/package.json | 4 ++-- apps/web/package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/api/package.json b/apps/api/package.json index e738366..cd3ec7d 100644 --- a/apps/api/package.json +++ b/apps/api/package.json @@ -4,8 +4,8 @@ "description": "API for the Modul Ajar Generator", "main": "index.js", "scripts": { - "start": "node index.js", - "dev": "npx nodemon index.js" + "start": "cross-env NODE_ENV=production node boot.js", + "dev": "cross-env NODE_ENV=development npx nodemon boot.js" }, "keywords": [], "author": "NgodingCik", diff --git a/apps/web/package.json b/apps/web/package.json index 741904c..5347925 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,8 +4,8 @@ "description": "Web application for the Modul Ajar Generator", "main": "index.js", "scripts": { - "start": "node index.js", - "dev": "npx nodemon index.js" + "start": "cross-env NODE_ENV=production node boot.js", + "dev": "cross-env NODE_ENV=development npx nodemon boot.js" }, "keywords": [], "author": "NgodingCik", From 6b00c358a12cc8171fc177f12ce8991ff0e41414 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:26:46 +0700 Subject: [PATCH 27/35] fix: rename APP_ORIGIN_HOST to APP_ORIGIN_HOSTS in CORS middleware for consistency --- apps/api/middleware/cors.js | 8 ++++---- apps/web/middleware/cors.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/apps/api/middleware/cors.js b/apps/api/middleware/cors.js index 06723f9..caa377c 100644 --- a/apps/api/middleware/cors.js +++ b/apps/api/middleware/cors.js @@ -1,13 +1,13 @@ import consola from 'consola' -const APP_ORIGIN_HOST = process.env.APP_ORIGIN_HOST || 'localhost' +const APP_ORIGIN_HOSTS = process.env.APP_ORIGIN_HOSTS || 'localhost' const isDevelopment = process.env.NODE_ENV !== 'production' // Support wildcard '*' or comma-separated list of full origin URLs -// e.g. APP_ORIGIN_HOST="modul-ajar.web.id,test.modul-ajar.web.id" -const ALLOWED_ORIGINS = APP_ORIGIN_HOST === '*' +// e.g. APP_ORIGIN_HOSTS="modul-ajar.web.id,test.modul-ajar.web.id" +const ALLOWED_ORIGINS = APP_ORIGIN_HOSTS === '*' ? '*' - : APP_ORIGIN_HOST.split(',').map(o => o.trim()) + : APP_ORIGIN_HOSTS.split(',').map(o => o.trim()) /** * Helper function to check if the request origin is allowed. diff --git a/apps/web/middleware/cors.js b/apps/web/middleware/cors.js index 06723f9..caa377c 100644 --- a/apps/web/middleware/cors.js +++ b/apps/web/middleware/cors.js @@ -1,13 +1,13 @@ import consola from 'consola' -const APP_ORIGIN_HOST = process.env.APP_ORIGIN_HOST || 'localhost' +const APP_ORIGIN_HOSTS = process.env.APP_ORIGIN_HOSTS || 'localhost' const isDevelopment = process.env.NODE_ENV !== 'production' // Support wildcard '*' or comma-separated list of full origin URLs -// e.g. APP_ORIGIN_HOST="modul-ajar.web.id,test.modul-ajar.web.id" -const ALLOWED_ORIGINS = APP_ORIGIN_HOST === '*' +// e.g. APP_ORIGIN_HOSTS="modul-ajar.web.id,test.modul-ajar.web.id" +const ALLOWED_ORIGINS = APP_ORIGIN_HOSTS === '*' ? '*' - : APP_ORIGIN_HOST.split(',').map(o => o.trim()) + : APP_ORIGIN_HOSTS.split(',').map(o => o.trim()) /** * Helper function to check if the request origin is allowed. From 9db625383fe8ae8db846d4419c7c2eb1c653406a Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:28:18 +0700 Subject: [PATCH 28/35] fix: update deploy button environment variable from APP_ORIGIN_URL to APP_ORIGIN_HOSTS for consistency --- docs/deploy/vercel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/deploy/vercel.md b/docs/deploy/vercel.md index 4ad9b2e..6d3ba31 100644 --- a/docs/deploy/vercel.md +++ b/docs/deploy/vercel.md @@ -10,7 +10,7 @@ As you can see, this project includes a `vercel.json` file containing the config ## Quick Start with Deploy Button -[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FNgodingCik%2Fmodul-ajar-generator&env=APP_NAME,APP_ORIGIN_URL,APP_PORT,APP_HOST,APP_API_BASE_URL,APP_USE_BUILTIN_API,CORS_TRUSTED_HOSTS,CORS_TRUSTED_CDN_HOSTS,OPENAI_API_KEY,OPENAI_MODEL&envDefaults=%7B%22APP_NAME%22%3A%22My%20App%22%2C%22APP_ORIGIN_URL%22%3A%22*%22%2C%22APP_PORT%22%3A%223000%22%2C%22APP_HOST%22%3A%220.0.0.0%22%2C%22APP_API_BASE_URL%22%3A%22http%3A%2F%2Flocalhost%3A3000%2Fapi%22%2C%22APP_USE_BUILTIN_API%22%3A%22true%22%2C%22CORS_TRUSTED_HOSTS%22%3A%22localhost%2Cexample.com%22%2C%22CORS_TRUSTED_CDN_HOSTS%22%3A%22cdn.example.com%22%7D&project-name=my-modul-ajar-generator&repository-name=my-modul-ajar-generator) +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FNgodingCik%2Fmodul-ajar-generator&env=APP_NAME,APP_ORIGIN_HOSTS,APP_PORT,APP_HOST,APP_API_BASE_URL,APP_USE_BUILTIN_API,CORS_TRUSTED_HOSTS,CORS_TRUSTED_CDN_HOSTS,OPENAI_API_KEY,OPENAI_MODEL&envDefaults=%7B%22APP_NAME%22%3A%22My%20App%22%2C%APP_ORIGIN_HOSTS%22%3A%22*%22%2C%22APP_PORT%22%3A%223000%22%2C%22APP_HOST%22%3A%220.0.0.0%22%2C%22APP_API_BASE_URL%22%3A%22http%3A%2F%2Flocalhost%3A3000%2Fapi%22%2C%22APP_USE_BUILTIN_API%22%3A%22true%22%2C%22CORS_TRUSTED_HOSTS%22%3A%22localhost%2Cexample.com%22%2C%22CORS_TRUSTED_CDN_HOSTS%22%3A%22cdn.example.com%22%7D&project-name=my-modul-ajar-generator&repository-name=my-modul-ajar-generator) ## Manual Deployment From 9b199a2b2e6bcbb63b2284d0db7fe4cb5b72defa Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Mon, 4 May 2026 11:30:31 +0700 Subject: [PATCH 29/35] docs: regenerate api-reference --- .../core/ai/openai-wrapper/classes/default.md | 24 +++++++++---------- .../ai/openai-wrapper/interfaces/Message.md | 10 ++++---- .../core/engine/vm-runner/classes/default.md | 16 ++++++------- .../vm-runner/type-aliases/ContextObject.md | 2 +- .../vm-runner/type-aliases/VMCallback.md | 2 +- .../handle-autofill-ai/functions/default.md | 2 +- .../handle-autofill-ai/interfaces/Message.md | 10 ++++---- .../handle-generate-docx/functions/default.md | 2 +- .../utils/functions/convertNumToRoman.md | 2 +- .../functions/extractCodeFromMarkdownFence.md | 2 +- .../utils/utils/functions/getEnvPath.md | 2 +- .../utils/utils/functions/loadContexts.md | 2 +- .../utils/functions/numTokensFromString.md | 2 +- .../functions/removeCodeBlocksFromMarkdown.md | 2 +- .../utils/functions/removeImportRequire.md | 2 +- .../utils/functions/validateBodyParams.md | 2 +- 16 files changed, 42 insertions(+), 42 deletions(-) diff --git a/docs/api-reference/packages/core/ai/openai-wrapper/classes/default.md b/docs/api-reference/packages/core/ai/openai-wrapper/classes/default.md index afed6c3..02b5e68 100644 --- a/docs/api-reference/packages/core/ai/openai-wrapper/classes/default.md +++ b/docs/api-reference/packages/core/ai/openai-wrapper/classes/default.md @@ -6,7 +6,7 @@ # Class: default -Defined in: [packages/core/ai/openai-wrapper.js:26](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L26) +Defined in: [packages/core/ai/openai-wrapper.js:26](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L26) OpenAIWrapper is a simple wrapper around the OpenAI API to manage contexts and generate responses. @@ -29,7 +29,7 @@ Make sure to set the OPENAI_API_KEY and OPENAI_MODEL environment variables befor > **new default**(`apiKey`, `model?`, `baseURL?`): `OpenAIWrapper` -Defined in: [packages/core/ai/openai-wrapper.js:43](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L43) +Defined in: [packages/core/ai/openai-wrapper.js:43](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L43) Creates an instance of OpenAIWrapper. @@ -65,7 +65,7 @@ The base URL for the OpenAI API > **get** **baseURL**(): `string` \| `null` -Defined in: [packages/core/ai/openai-wrapper.js:63](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L63) +Defined in: [packages/core/ai/openai-wrapper.js:63](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L63) Gets the base URL for the OpenAI API. @@ -81,7 +81,7 @@ Gets the base URL for the OpenAI API. > **get** **client**(): `OpenAI` -Defined in: [packages/core/ai/openai-wrapper.js:88](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L88) +Defined in: [packages/core/ai/openai-wrapper.js:88](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L88) Gets the OpenAI client instance. @@ -97,7 +97,7 @@ Gets the OpenAI client instance. > **get** **context**(): [`Message`](../interfaces/Message.md)[] -Defined in: [packages/core/ai/openai-wrapper.js:96](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L96) +Defined in: [packages/core/ai/openai-wrapper.js:96](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L96) Gets the default context. @@ -109,7 +109,7 @@ Gets the default context. > **set** **context**(`context`): `void` -Defined in: [packages/core/ai/openai-wrapper.js:104](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L104) +Defined in: [packages/core/ai/openai-wrapper.js:104](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L104) Sets the default context. @@ -131,7 +131,7 @@ Sets the default context. > **get** **model**(): `string` -Defined in: [packages/core/ai/openai-wrapper.js:71](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L71) +Defined in: [packages/core/ai/openai-wrapper.js:71](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L71) Gets the model. @@ -143,7 +143,7 @@ Gets the model. > **set** **model**(`model`): `void` -Defined in: [packages/core/ai/openai-wrapper.js:79](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L79) +Defined in: [packages/core/ai/openai-wrapper.js:79](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L79) Sets the model. @@ -163,7 +163,7 @@ Sets the model. > **addContext**(...`contexts`): `void` -Defined in: [packages/core/ai/openai-wrapper.js:115](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L115) +Defined in: [packages/core/ai/openai-wrapper.js:115](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L115) Adds one or more context objects to the existing default context. @@ -183,7 +183,7 @@ Adds one or more context objects to the existing default context. > **chat**(`messages`): `Promise`\<`string`\> -Defined in: [packages/core/ai/openai-wrapper.js:173](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L173) +Defined in: [packages/core/ai/openai-wrapper.js:173](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L173) Send a chat message to the OpenAI model with the loaded contexts. @@ -205,7 +205,7 @@ Send a chat message to the OpenAI model with the loaded contexts. > **loadContext**(`filePath`): `void` -Defined in: [packages/core/ai/openai-wrapper.js:151](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L151) +Defined in: [packages/core/ai/openai-wrapper.js:151](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L151) Loads a context from a file and adds it to the default context as a system message. @@ -225,7 +225,7 @@ Loads a context from a file and adds it to the default context as a system messa > **loadContextsFromDir**(`pathDir`): `void` -Defined in: [packages/core/ai/openai-wrapper.js:126](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L126) +Defined in: [packages/core/ai/openai-wrapper.js:126](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L126) Load context(s) from a directory. diff --git a/docs/api-reference/packages/core/ai/openai-wrapper/interfaces/Message.md b/docs/api-reference/packages/core/ai/openai-wrapper/interfaces/Message.md index 3325f9e..9271dcf 100644 --- a/docs/api-reference/packages/core/ai/openai-wrapper/interfaces/Message.md +++ b/docs/api-reference/packages/core/ai/openai-wrapper/interfaces/Message.md @@ -6,7 +6,7 @@ # Interface: Message -Defined in: [packages/core/ai/openai-wrapper.js:8](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L8) +Defined in: [packages/core/ai/openai-wrapper.js:8](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L8) ## Properties @@ -14,7 +14,7 @@ Defined in: [packages/core/ai/openai-wrapper.js:8](https://github.com/GTPSHAX/mo > **content**: `string` -Defined in: [packages/core/ai/openai-wrapper.js:10](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L10) +Defined in: [packages/core/ai/openai-wrapper.js:10](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L10) The content of the message @@ -24,7 +24,7 @@ The content of the message > `optional` **name?**: `string` -Defined in: [packages/core/ai/openai-wrapper.js:11](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L11) +Defined in: [packages/core/ai/openai-wrapper.js:11](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L11) Optional name for tool/function messages @@ -34,7 +34,7 @@ Optional name for tool/function messages > **role**: `"system"` \| `"user"` \| `"assistant"` \| `"tool"` -Defined in: [packages/core/ai/openai-wrapper.js:9](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L9) +Defined in: [packages/core/ai/openai-wrapper.js:9](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L9) The role of the message sender (excluding 'function' to avoid name requirement) @@ -44,6 +44,6 @@ The role of the message sender (excluding 'function' to avoid name requirement) > `optional` **tool\_call\_id?**: `string` -Defined in: [packages/core/ai/openai-wrapper.js:12](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/ai/openai-wrapper.js#L12) +Defined in: [packages/core/ai/openai-wrapper.js:12](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/ai/openai-wrapper.js#L12) Optional tool_call_id for tool messages diff --git a/docs/api-reference/packages/core/engine/vm-runner/classes/default.md b/docs/api-reference/packages/core/engine/vm-runner/classes/default.md index b74dafc..6907a24 100644 --- a/docs/api-reference/packages/core/engine/vm-runner/classes/default.md +++ b/docs/api-reference/packages/core/engine/vm-runner/classes/default.md @@ -6,7 +6,7 @@ # Class: default -Defined in: [packages/core/engine/vm-runner.js:28](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L28) +Defined in: [packages/core/engine/vm-runner.js:28](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L28) Runs JavaScript code safely inside a sandboxed VM context. @@ -30,7 +30,7 @@ const runner = new VMRunner( > **new default**(`code`, `shared?`, `callback?`): `VMRunner` -Defined in: [packages/core/engine/vm-runner.js:45](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L45) +Defined in: [packages/core/engine/vm-runner.js:45](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L45) Creates a new VMRunner instance. @@ -64,7 +64,7 @@ Error-first callback for results > **callback**: [`VMCallback`](../type-aliases/VMCallback.md) \| `null` = `null` -Defined in: [packages/core/engine/vm-runner.js:34](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L34) +Defined in: [packages/core/engine/vm-runner.js:34](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L34) *** @@ -72,7 +72,7 @@ Defined in: [packages/core/engine/vm-runner.js:34](https://github.com/GTPSHAX/mo > **code**: `string` \| `null` = `null` -Defined in: [packages/core/engine/vm-runner.js:30](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L30) +Defined in: [packages/core/engine/vm-runner.js:30](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L30) *** @@ -80,7 +80,7 @@ Defined in: [packages/core/engine/vm-runner.js:30](https://github.com/GTPSHAX/mo > **context**: [`ContextObject`](../type-aliases/ContextObject.md) \| `null` = `null` -Defined in: [packages/core/engine/vm-runner.js:36](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L36) +Defined in: [packages/core/engine/vm-runner.js:36](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L36) *** @@ -88,7 +88,7 @@ Defined in: [packages/core/engine/vm-runner.js:36](https://github.com/GTPSHAX/mo > **shared**: [`ContextObject`](../type-aliases/ContextObject.md) \| `null` = `null` -Defined in: [packages/core/engine/vm-runner.js:32](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L32) +Defined in: [packages/core/engine/vm-runner.js:32](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L32) ## Methods @@ -96,7 +96,7 @@ Defined in: [packages/core/engine/vm-runner.js:32](https://github.com/GTPSHAX/mo > **addContext**(...`contexts`): `void` -Defined in: [packages/core/engine/vm-runner.js:144](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L144) +Defined in: [packages/core/engine/vm-runner.js:144](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L144) Adds extra variables into the VM context before running. @@ -118,7 +118,7 @@ Objects to merge into the VM context > **run**(): `void` -Defined in: [packages/core/engine/vm-runner.js:76](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L76) +Defined in: [packages/core/engine/vm-runner.js:76](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L76) Runs the code inside the VM and calls the callback with the result. diff --git a/docs/api-reference/packages/core/engine/vm-runner/type-aliases/ContextObject.md b/docs/api-reference/packages/core/engine/vm-runner/type-aliases/ContextObject.md index aa443ec..f4ef4f3 100644 --- a/docs/api-reference/packages/core/engine/vm-runner/type-aliases/ContextObject.md +++ b/docs/api-reference/packages/core/engine/vm-runner/type-aliases/ContextObject.md @@ -8,6 +8,6 @@ > **ContextObject** = `Record`\<`string`, `any`\> -Defined in: [packages/core/engine/vm-runner.js:11](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L11) +Defined in: [packages/core/engine/vm-runner.js:11](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L11) ## Type Parameters diff --git a/docs/api-reference/packages/core/engine/vm-runner/type-aliases/VMCallback.md b/docs/api-reference/packages/core/engine/vm-runner/type-aliases/VMCallback.md index 976e3a9..b0b0d42 100644 --- a/docs/api-reference/packages/core/engine/vm-runner/type-aliases/VMCallback.md +++ b/docs/api-reference/packages/core/engine/vm-runner/type-aliases/VMCallback.md @@ -8,7 +8,7 @@ > **VMCallback** = (`err`, `result?`) => `void` -Defined in: [packages/core/engine/vm-runner.js:10](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/core/engine/vm-runner.js#L10) +Defined in: [packages/core/engine/vm-runner.js:10](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/core/engine/vm-runner.js#L10) ## Type Parameters diff --git a/docs/api-reference/packages/handlers/handle-autofill-ai/functions/default.md b/docs/api-reference/packages/handlers/handle-autofill-ai/functions/default.md index ba5a722..d7d66cd 100644 --- a/docs/api-reference/packages/handlers/handle-autofill-ai/functions/default.md +++ b/docs/api-reference/packages/handlers/handle-autofill-ai/functions/default.md @@ -8,7 +8,7 @@ > **default**(`body`): `Promise`\<\{ `data?`: `string`; `message?`: `string`; `status`: `number`; \}\> -Defined in: [packages/handlers/handle-autofill-ai.js:61](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/handlers/handle-autofill-ai.js#L61) +Defined in: [packages/handlers/handle-autofill-ai.js:61](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/handlers/handle-autofill-ai.js#L61) Handles auto-filling AI functionality. diff --git a/docs/api-reference/packages/handlers/handle-autofill-ai/interfaces/Message.md b/docs/api-reference/packages/handlers/handle-autofill-ai/interfaces/Message.md index fceee0c..f1c02ad 100644 --- a/docs/api-reference/packages/handlers/handle-autofill-ai/interfaces/Message.md +++ b/docs/api-reference/packages/handlers/handle-autofill-ai/interfaces/Message.md @@ -6,7 +6,7 @@ # Interface: Message -Defined in: [packages/handlers/handle-autofill-ai.js:8](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/handlers/handle-autofill-ai.js#L8) +Defined in: [packages/handlers/handle-autofill-ai.js:8](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/handlers/handle-autofill-ai.js#L8) ## Properties @@ -14,7 +14,7 @@ Defined in: [packages/handlers/handle-autofill-ai.js:8](https://github.com/GTPSH > **content**: `string` -Defined in: [packages/handlers/handle-autofill-ai.js:10](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/handlers/handle-autofill-ai.js#L10) +Defined in: [packages/handlers/handle-autofill-ai.js:10](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/handlers/handle-autofill-ai.js#L10) The content of the message @@ -24,7 +24,7 @@ The content of the message > `optional` **name?**: `string` -Defined in: [packages/handlers/handle-autofill-ai.js:11](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/handlers/handle-autofill-ai.js#L11) +Defined in: [packages/handlers/handle-autofill-ai.js:11](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/handlers/handle-autofill-ai.js#L11) Optional name for tool/function messages @@ -34,7 +34,7 @@ Optional name for tool/function messages > **role**: `"system"` \| `"user"` \| `"assistant"` \| `"tool"` -Defined in: [packages/handlers/handle-autofill-ai.js:9](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/handlers/handle-autofill-ai.js#L9) +Defined in: [packages/handlers/handle-autofill-ai.js:9](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/handlers/handle-autofill-ai.js#L9) The role of the message sender (excluding 'function' to avoid name requirement) @@ -44,6 +44,6 @@ The role of the message sender (excluding 'function' to avoid name requirement) > `optional` **tool\_call\_id?**: `string` -Defined in: [packages/handlers/handle-autofill-ai.js:12](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/handlers/handle-autofill-ai.js#L12) +Defined in: [packages/handlers/handle-autofill-ai.js:12](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/handlers/handle-autofill-ai.js#L12) Optional tool_call_id for tool messages diff --git a/docs/api-reference/packages/handlers/handle-generate-docx/functions/default.md b/docs/api-reference/packages/handlers/handle-generate-docx/functions/default.md index 2796009..99dc663 100644 --- a/docs/api-reference/packages/handlers/handle-generate-docx/functions/default.md +++ b/docs/api-reference/packages/handlers/handle-generate-docx/functions/default.md @@ -8,7 +8,7 @@ > **default**(`body`): `Promise`\<\{ `data?`: `any`; `message?`: `string`; `status`: `number`; \}\> -Defined in: [packages/handlers/handle-generate-docx.js:126](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/handlers/handle-generate-docx.js#L126) +Defined in: [packages/handlers/handle-generate-docx.js:126](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/handlers/handle-generate-docx.js#L126) Handles the generation of a DOCX document based on the provided body data. diff --git a/docs/api-reference/packages/utils/utils/functions/convertNumToRoman.md b/docs/api-reference/packages/utils/utils/functions/convertNumToRoman.md index 088a122..575ecbd 100644 --- a/docs/api-reference/packages/utils/utils/functions/convertNumToRoman.md +++ b/docs/api-reference/packages/utils/utils/functions/convertNumToRoman.md @@ -8,7 +8,7 @@ > **convertNumToRoman**(`num`): `string` -Defined in: [packages/utils/utils.js:92](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L92) +Defined in: [packages/utils/utils.js:92](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L92) Converts a number to its Roman numeral representation. diff --git a/docs/api-reference/packages/utils/utils/functions/extractCodeFromMarkdownFence.md b/docs/api-reference/packages/utils/utils/functions/extractCodeFromMarkdownFence.md index c584790..9f40326 100644 --- a/docs/api-reference/packages/utils/utils/functions/extractCodeFromMarkdownFence.md +++ b/docs/api-reference/packages/utils/utils/functions/extractCodeFromMarkdownFence.md @@ -8,7 +8,7 @@ > **extractCodeFromMarkdownFence**(`code`): `string` -Defined in: [packages/utils/utils.js:79](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L79) +Defined in: [packages/utils/utils.js:79](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L79) Cleans code extracted from markdown code blocks. Removes the enclosing backticks while preserving inner content. diff --git a/docs/api-reference/packages/utils/utils/functions/getEnvPath.md b/docs/api-reference/packages/utils/utils/functions/getEnvPath.md index 80bd83e..1c7be2d 100644 --- a/docs/api-reference/packages/utils/utils/functions/getEnvPath.md +++ b/docs/api-reference/packages/utils/utils/functions/getEnvPath.md @@ -8,7 +8,7 @@ > **getEnvPath**(`filename?`): `string` \| `null` -Defined in: [packages/utils/utils.js:167](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L167) +Defined in: [packages/utils/utils.js:167](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L167) Gets the path to the .env file, checking both the current working directory and the project root. This allows for flexibility in where the .env file can be located, accommodating different deployment and development setups. diff --git a/docs/api-reference/packages/utils/utils/functions/loadContexts.md b/docs/api-reference/packages/utils/utils/functions/loadContexts.md index 36d16d4..afa04ee 100644 --- a/docs/api-reference/packages/utils/utils/functions/loadContexts.md +++ b/docs/api-reference/packages/utils/utils/functions/loadContexts.md @@ -8,7 +8,7 @@ > **loadContexts**(`dir`): `object` -Defined in: [packages/utils/utils.js:37](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L37) +Defined in: [packages/utils/utils.js:37](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L37) This function loads all Markdown files from a specified directory, reads their content, and constructs an object where each key is derived from the filename (converted to uppercase and underscores) and the value is the file's content. This allows for easy access to the content of multiple Markdown files in a structured format. diff --git a/docs/api-reference/packages/utils/utils/functions/numTokensFromString.md b/docs/api-reference/packages/utils/utils/functions/numTokensFromString.md index 2914996..b763e93 100644 --- a/docs/api-reference/packages/utils/utils/functions/numTokensFromString.md +++ b/docs/api-reference/packages/utils/utils/functions/numTokensFromString.md @@ -8,7 +8,7 @@ > **numTokensFromString**(`message`, `model?`): `number` -Defined in: [packages/utils/utils.js:110](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L110) +Defined in: [packages/utils/utils.js:110](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L110) Counts the number of tokens in a string using the specified model's tokenizer. diff --git a/docs/api-reference/packages/utils/utils/functions/removeCodeBlocksFromMarkdown.md b/docs/api-reference/packages/utils/utils/functions/removeCodeBlocksFromMarkdown.md index 392805f..0cec0ba 100644 --- a/docs/api-reference/packages/utils/utils/functions/removeCodeBlocksFromMarkdown.md +++ b/docs/api-reference/packages/utils/utils/functions/removeCodeBlocksFromMarkdown.md @@ -8,7 +8,7 @@ > **removeCodeBlocksFromMarkdown**(`markdown`): `string` -Defined in: [packages/utils/utils.js:63](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L63) +Defined in: [packages/utils/utils.js:63](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L63) Removes markdown code blocks and inline code from a markdown string. Note: This removes MARKDOWN code blocks (e.g., from markdown with embedded code), diff --git a/docs/api-reference/packages/utils/utils/functions/removeImportRequire.md b/docs/api-reference/packages/utils/utils/functions/removeImportRequire.md index e96ace4..662ec6a 100644 --- a/docs/api-reference/packages/utils/utils/functions/removeImportRequire.md +++ b/docs/api-reference/packages/utils/utils/functions/removeImportRequire.md @@ -8,7 +8,7 @@ > **removeImportRequire**(`content`): `string` -Defined in: [packages/utils/utils.js:16](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L16) +Defined in: [packages/utils/utils.js:16](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L16) Removes import require, and export statements from a string. diff --git a/docs/api-reference/packages/utils/utils/functions/validateBodyParams.md b/docs/api-reference/packages/utils/utils/functions/validateBodyParams.md index bf81ebf..dc1c375 100644 --- a/docs/api-reference/packages/utils/utils/functions/validateBodyParams.md +++ b/docs/api-reference/packages/utils/utils/functions/validateBodyParams.md @@ -8,7 +8,7 @@ > **validateBodyParams**(`body`, ...`requiredParams`): `object` -Defined in: [packages/utils/utils.js:125](https://github.com/GTPSHAX/modul-ajar-generator/blob/4297ff4935987b650cede1000047210790531bd4/packages/utils/utils.js#L125) +Defined in: [packages/utils/utils.js:125](https://github.com/GTPSHAX/modul-ajar-generator/blob/9db625383fe8ae8db846d4419c7c2eb1c653406a/packages/utils/utils.js#L125) Validates that all required parameters are present in the request body. From badf9fb6fb0ec9e76a331927bf2112fbb76f7769 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Tue, 5 May 2026 00:28:03 +0700 Subject: [PATCH 30/35] feat: add OpenAI configuration to .env and .env.schema files --- apps/api/.env.example | 7 ++++++- apps/api/.env.schema | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/apps/api/.env.example b/apps/api/.env.example index da1f307..dfbfb27 100644 --- a/apps/api/.env.example +++ b/apps/api/.env.example @@ -7,4 +7,9 @@ APP_HOST="0.0.0.0" # Comma-separated list of trusted hosts for CORS validation CORS_TRUSTED_HOSTS="localhost,example.com" # Comma-separated list of trusted CDN hosts for CORS validation -CORS_TRUSTED_CDN_HOSTS="cdn.example.com" \ No newline at end of file +CORS_TRUSTED_CDN_HOSTS="cdn.example.com" + +# --- OpenAI configuration --- +OPENAI_API_KEY="your-openai-api-key-here" +OPENAI_MODEL="gpt-3.5-turbo" +OPENAI_BASE_URL="https://api.openai.com/v1" \ No newline at end of file diff --git a/apps/api/.env.schema b/apps/api/.env.schema index 1d72f72..85643b8 100644 --- a/apps/api/.env.schema +++ b/apps/api/.env.schema @@ -7,4 +7,9 @@ APP_HOST= # Comma-separated list of trusted hosts for CORS validation CORS_TRUSTED_HOSTS= # Comma-separated list of trusted CDN hosts for CORS validation -CORS_TRUSTED_CDN_HOSTS= \ No newline at end of file +CORS_TRUSTED_CDN_HOSTS= + +# --- OpenAI configuration --- +OPENAI_API_KEY= +OPENAI_MODEL= +OPENAI_BASE_URL= \ No newline at end of file From c8996dbf7e6635ec59867c7a7db93a195d378fd1 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Tue, 5 May 2026 00:28:22 +0700 Subject: [PATCH 31/35] fix: improve CORS middleware to correctly extract origin from request headers --- apps/api/middleware/cors.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/apps/api/middleware/cors.js b/apps/api/middleware/cors.js index caa377c..f8b6b12 100644 --- a/apps/api/middleware/cors.js +++ b/apps/api/middleware/cors.js @@ -28,15 +28,38 @@ const isOriginAllowed = (origin) => { * @returns {import('express').Response | void} */ const cors = (req, res, next) => { - const origin = (req.get('host') || req.get('origin') || req.headers.origin || '').split(':')[0] // Extract hostname without port - consola.debug(`CORS check - Origin: ${origin}, Host: ${req.headers.host}`) + const originHeader = req.headers.origin || req.get('origin') || '' + + let origin = '' + let fullUrl = '' + + if (originHeader) { + try { + const urlObj = new URL(originHeader) + origin = urlObj.hostname + fullUrl = originHeader + } catch (e) { + origin = originHeader + fullUrl = originHeader + } + } else { + // Fallback if no origin is provided (e.g., direct API calls) + const hostHeader = String(req.get('host') || '') + origin = hostHeader.split(':')[0] + fullUrl = req.protocol + '://' + hostHeader + } + + consola.debug(`CORS check - Origin Header: ${originHeader}, Extracted Origin: ${origin}, URL: ${fullUrl}`) res.header('Vary', 'Origin') + const IS_ALLOWED = isOriginAllowed(origin) + consola.debug(`CORS allowed: ${IS_ALLOWED} for origin: ${origin}`) + if (ALLOWED_ORIGINS === '*') { res.header('Access-Control-Allow-Origin', '*') - } else if (isOriginAllowed(origin)) { - res.header('Access-Control-Allow-Origin', origin) + } else if (origin && IS_ALLOWED) { + res.header('Access-Control-Allow-Origin', fullUrl) } if (req.url.startsWith('/api/')) { From 29d0059dee29ec6e552d7375d6e4aa75b258332d Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Tue, 5 May 2026 00:30:44 +0700 Subject: [PATCH 32/35] fix: enhance CORS middleware to correctly extract origin from request headers --- apps/web/middleware/cors.js | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/apps/web/middleware/cors.js b/apps/web/middleware/cors.js index caa377c..f8b6b12 100644 --- a/apps/web/middleware/cors.js +++ b/apps/web/middleware/cors.js @@ -28,15 +28,38 @@ const isOriginAllowed = (origin) => { * @returns {import('express').Response | void} */ const cors = (req, res, next) => { - const origin = (req.get('host') || req.get('origin') || req.headers.origin || '').split(':')[0] // Extract hostname without port - consola.debug(`CORS check - Origin: ${origin}, Host: ${req.headers.host}`) + const originHeader = req.headers.origin || req.get('origin') || '' + + let origin = '' + let fullUrl = '' + + if (originHeader) { + try { + const urlObj = new URL(originHeader) + origin = urlObj.hostname + fullUrl = originHeader + } catch (e) { + origin = originHeader + fullUrl = originHeader + } + } else { + // Fallback if no origin is provided (e.g., direct API calls) + const hostHeader = String(req.get('host') || '') + origin = hostHeader.split(':')[0] + fullUrl = req.protocol + '://' + hostHeader + } + + consola.debug(`CORS check - Origin Header: ${originHeader}, Extracted Origin: ${origin}, URL: ${fullUrl}`) res.header('Vary', 'Origin') + const IS_ALLOWED = isOriginAllowed(origin) + consola.debug(`CORS allowed: ${IS_ALLOWED} for origin: ${origin}`) + if (ALLOWED_ORIGINS === '*') { res.header('Access-Control-Allow-Origin', '*') - } else if (isOriginAllowed(origin)) { - res.header('Access-Control-Allow-Origin', origin) + } else if (origin && IS_ALLOWED) { + res.header('Access-Control-Allow-Origin', fullUrl) } if (req.url.startsWith('/api/')) { From 4f58da43a817326e00640b261ae8327353390170 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Tue, 5 May 2026 00:31:09 +0700 Subject: [PATCH 33/35] fix: update connect-src directive to use removePathFromUrl helper function --- apps/web/middleware/helmet.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/web/middleware/helmet.js b/apps/web/middleware/helmet.js index 82d4100..0e6a99d 100644 --- a/apps/web/middleware/helmet.js +++ b/apps/web/middleware/helmet.js @@ -7,6 +7,22 @@ const CORS_TRUSTED_CDN_HOSTS = process.env.CORS_TRUSTED_CDN_HOSTS const APP_API_BASE_URL = process.env.APP_API_BASE_URL || null const isDevelopment = process.env.NODE_ENV !== 'production' +/** + * Helper function to remove path from a URL, leaving only the origin (scheme + host + port). + * @param {string} url + * @returns {string} + */ +const removePathFromUrl = (url) => { + try { + const parsedUrl = new URL(url) + parsedUrl.pathname = '' + return parsedUrl.toString().replace(/\/+$/, '') // Remove trailing slash if any + } catch (error) { + console.warn(`Invalid URL provided: ${url}`) + return url + } +} + const helmetMiddleware = helmet({ contentSecurityPolicy: { directives: { @@ -18,7 +34,7 @@ const helmetMiddleware = helmet({ 'style-src': ["'self'", "'unsafe-inline'", ...CORS_TRUSTED_CDN_HOSTS], 'img-src': ["'self'", 'data:', 'https://contrib.rocks', ...CORS_TRUSTED_CDN_HOSTS], 'font-src': ["'self'", ...CORS_TRUSTED_CDN_HOSTS], - 'connect-src': ["'self'", ...(APP_API_BASE_URL ? [APP_API_BASE_URL] : [])] + 'connect-src': ["'self'", ...(APP_API_BASE_URL ? [removePathFromUrl(APP_API_BASE_URL)] : [])] } }, frameguard: false, From d7106f3ed99a04a0bd8b973f2118e68549da87f6 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Tue, 5 May 2026 00:31:32 +0700 Subject: [PATCH 34/35] fix: update target file path in stripConsoleMiddleware to use __dirname --- apps/web/middleware/stripconsole.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/web/middleware/stripconsole.js b/apps/web/middleware/stripconsole.js index 9dad29c..b101a44 100644 --- a/apps/web/middleware/stripconsole.js +++ b/apps/web/middleware/stripconsole.js @@ -1,6 +1,8 @@ import fs from 'node:fs' import path from 'node:path' +const __dirname = import.meta.dirname + const IS_PRODUCTION = (process.env.NODE_ENV || '').toUpperCase() === 'PRODUCTION' const JS_PUBLIC_PATH_PATTERN = /^\/js\/[^/]+\.js$/ @@ -42,7 +44,7 @@ const stripConsoleMiddleware = (req, res, next) => { } const publicRelativePath = req.path.replace(/^\/+/, '') - const targetFile = path.join(process.cwd(), 'public', publicRelativePath) + const targetFile = path.join(__dirname, '../../../public', publicRelativePath) try { const source = fs.readFileSync(targetFile, 'utf8') From b9091757d30738e909a194c28a5855dcc6b469a1 Mon Sep 17 00:00:00 2001 From: GTPSHAX Date: Tue, 5 May 2026 00:43:37 +0700 Subject: [PATCH 35/35] feat: add initial package.json for scripts module --- packages/scripts/package.json | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/scripts/package.json diff --git a/packages/scripts/package.json b/packages/scripts/package.json new file mode 100644 index 0000000..b010f36 --- /dev/null +++ b/packages/scripts/package.json @@ -0,0 +1,5 @@ +{ + "name": "@repo/scripts", + "version": "1.0.0", + "type": "module" +}