qumra-engine 2.0.32 → 2.0.34

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.
@@ -6,3 +6,4 @@ export { default as footer } from './logic/footer';
6
6
  export { default as content } from './logic/content';
7
7
  export { default as qumra_head } from './logic/qumra-head';
8
8
  export { default as qumra_scripts } from './logic/qumra-scripts';
9
+ export { default as include } from './logic/ui';
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.qumra_scripts = exports.qumra_head = exports.content = exports.footer = exports.header = exports.form = exports.widget = exports.seo = void 0;
6
+ exports.include = exports.qumra_scripts = exports.qumra_head = exports.content = exports.footer = exports.header = exports.form = exports.widget = exports.seo = void 0;
7
7
  var seo_1 = require("./logic/seo");
8
8
  Object.defineProperty(exports, "seo", { enumerable: true, get: function () { return __importDefault(seo_1).default; } });
9
9
  var widget_1 = require("./logic/widget");
@@ -20,3 +20,5 @@ var qumra_head_1 = require("./logic/qumra-head");
20
20
  Object.defineProperty(exports, "qumra_head", { enumerable: true, get: function () { return __importDefault(qumra_head_1).default; } });
21
21
  var qumra_scripts_1 = require("./logic/qumra-scripts");
22
22
  Object.defineProperty(exports, "qumra_scripts", { enumerable: true, get: function () { return __importDefault(qumra_scripts_1).default; } });
23
+ var ui_1 = require("./logic/ui");
24
+ Object.defineProperty(exports, "include", { enumerable: true, get: function () { return __importDefault(ui_1).default; } });
@@ -0,0 +1,10 @@
1
+ import nunjucks from "nunjucks";
2
+ declare const _default: {
3
+ tags: string[];
4
+ parse(parser: any, nodes: any): any;
5
+ run({ ctx, env }: {
6
+ ctx: any;
7
+ env: nunjucks.Environment;
8
+ }, ...args: any): string;
9
+ };
10
+ export default _default;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = new (class WidgetExtension {
4
+ constructor() {
5
+ this.tags = ["include"];
6
+ }
7
+ parse(parser, nodes) {
8
+ const tok = parser.nextToken();
9
+ const args = parser.parseSignature(true, true);
10
+ parser.advanceAfterBlockEnd(tok.value);
11
+ return new nodes.CallExtension(this, "run", args);
12
+ }
13
+ run({ ctx, env }, ...args) {
14
+ console.log("🚀 ~ WidgetExtension ~ args:", args);
15
+ return 'this is a test';
16
+ }
17
+ })();
@@ -0,0 +1,10 @@
1
+ import nunjucks from "nunjucks";
2
+ declare const _default: {
3
+ tags: string[];
4
+ parse(parser: any, nodes: any): any;
5
+ run({ ctx, env }: {
6
+ ctx: any;
7
+ env: nunjucks.Environment;
8
+ }, file: string, ...data: any): nunjucks.runtime.SafeString;
9
+ };
10
+ export default _default;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const nunjucks_1 = __importDefault(require("nunjucks"));
7
+ const normalizeUiPath_1 = require("../../utils/normalizeUiPath");
8
+ const validateUiData_1 = require("../../utils/validateUiData");
9
+ exports.default = new (class WidgetExtension {
10
+ constructor() {
11
+ this.tags = ["ui"];
12
+ }
13
+ parse(parser, nodes) {
14
+ const tok = parser.nextToken();
15
+ const args = parser.parseSignature(true, true);
16
+ parser.advanceAfterBlockEnd(tok.value);
17
+ return new nodes.CallExtension(this, "run", args);
18
+ }
19
+ run({ ctx, env }, file, ...data) {
20
+ if (!file || typeof file !== 'string' || file.trim() === '' || !file.includes('.njk')) {
21
+ throw new Error("Invalid file path provided to ui extension");
22
+ }
23
+ const filePath = (0, normalizeUiPath_1.normalizeUiPath)(file);
24
+ if (!filePath) {
25
+ return new nunjucks_1.default.runtime.SafeString(`
26
+ <div style="padding: 12px; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 4px; margin: 8px 0;">
27
+ ⚠️ <strong>مسار الويجيت غير صالح:</strong> ${filePath}
28
+ </div>
29
+ `);
30
+ }
31
+ const validated = (0, validateUiData_1.validateUiData)(data);
32
+ console.log(validated);
33
+ const rendered = env.render(filePath, {
34
+ context: ctx.context,
35
+ globals: ctx.globals,
36
+ data: validated
37
+ });
38
+ return new nunjucks_1.default.runtime.SafeString(rendered);
39
+ }
40
+ })();
@@ -30,6 +30,7 @@ const prepareDataMiddleware = (req, res, next) => {
30
30
  return engineResponse.json();
31
31
  })
32
32
  .then((data) => {
33
+ console.log("🚀 ~ .then ~ data:", data);
33
34
  // تم تخزين النتيجة داخل res.locals.render
34
35
  res.locals.render = data.data;
35
36
  next();
@@ -0,0 +1 @@
1
+ export declare function normalizeIncludesPath(input: string): string | null;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeIncludesPath = normalizeIncludesPath;
4
+ function normalizeIncludesPath(input) {
5
+ if (!input || typeof input !== 'string') {
6
+ return null;
7
+ }
8
+ const trimmed = input.trim().replace(/^['"]|['"]$/g, '');
9
+ // إزالة أي امتداد .njk لو موجود
10
+ let base = trimmed.replace(/\.njk$/, '');
11
+ // لو بيبدأ بـ includes/ نشيله مؤقتًا
12
+ if (base.startsWith('includes/')) {
13
+ base = base.replace(/^includes\//, '');
14
+ }
15
+ // إزالة /widget لو موجودة في الآخر
16
+ base = base.replace(/\/widget$/, '');
17
+ // الناتج النهائي
18
+ return `includes/${base}/widget.njk`;
19
+ }
@@ -0,0 +1 @@
1
+ export declare function normalizeUiPath(input: string): string | null;
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeUiPath = normalizeUiPath;
4
+ function normalizeUiPath(input) {
5
+ if (!input || typeof input !== 'string') {
6
+ return null;
7
+ }
8
+ const trimmed = input.trim().replace(/^['"]|['"]$/g, '');
9
+ // إزالة أي امتداد .njk لو موجود
10
+ let base = trimmed;
11
+ // لو بيبدأ بـ ui/ نشيله مؤقتًا
12
+ if (base.startsWith('ui/')) {
13
+ base = base.replace(/^ui\//, '');
14
+ }
15
+ // إزالة /widget لو موجودة في الآخر
16
+ base = base.replace(/\/widget$/, '');
17
+ // الناتج النهائي
18
+ return `ui/${base}`;
19
+ }
@@ -0,0 +1 @@
1
+ export declare function validateUiData(data: unknown[]): Record<string, any>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateUiData = validateUiData;
4
+ function validateUiData(data) {
5
+ if (!Array.isArray(data)) {
6
+ throw new Error("❌ البيانات يجب أن تكون مصفوفة.");
7
+ }
8
+ const result = {};
9
+ for (const item of data) {
10
+ if (typeof item === "string") {
11
+ throw new Error(`❌ عنصر غير صحيح: "${item}" يجب أن يكون كائن يحتوي على key/value.`);
12
+ }
13
+ if (typeof item === "object" && item !== null) {
14
+ for (const [key, value] of Object.entries(item)) {
15
+ if (value === true)
16
+ continue; // استبعاد مثل __keywords: true
17
+ result[key] = value;
18
+ }
19
+ }
20
+ else {
21
+ throw new Error(`❌ نوع عنصر غير مدعوم: ${JSON.stringify(item)}`);
22
+ }
23
+ }
24
+ return result;
25
+ }
@@ -0,0 +1 @@
1
+ declare function validateWidgetData(data: unknown[]): Record<string, any>;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ function validateWidgetData(data) {
3
+ if (!Array.isArray(data)) {
4
+ throw new Error("❌ البيانات يجب أن تكون مصفوفة.");
5
+ }
6
+ const result = {};
7
+ for (const item of data) {
8
+ if (typeof item === "string") {
9
+ throw new Error(`❌ عنصر غير صحيح: "${item}" يجب أن يكون كائن يحتوي على key/value.`);
10
+ }
11
+ if (typeof item === "object" && item !== null) {
12
+ for (const [key, value] of Object.entries(item)) {
13
+ if (value === true)
14
+ continue; // استبعاد مثل __keywords: true
15
+ result[key] = value;
16
+ }
17
+ }
18
+ else {
19
+ throw new Error(`❌ نوع عنصر غير مدعوم: ${JSON.stringify(item)}`);
20
+ }
21
+ }
22
+ return result;
23
+ }
package/package.json CHANGED
@@ -1,13 +1,11 @@
1
1
  {
2
2
  "name": "qumra-engine",
3
- "version": "2.0.32",
3
+ "version": "2.0.34",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
7
7
  "build": "tsc -w",
8
- "pub": "tsc && npm version patch && npm publish",
9
- "start:dev": "ts-node test/test-app.ts",
10
- "dev": "nodemon --watch src --watch test --ext ts,njk --exec ts-node test/test-app.ts"
8
+ "pub": "tsc && npm version patch && npm publish"
11
9
  },
12
10
  "dependencies": {
13
11
  "chalk": "^5.4.1",