qumra-engine 2.0.149 → 2.0.151

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.
Files changed (63) hide show
  1. package/dist/controllers/localize/currency.controller.d.ts +1 -0
  2. package/dist/controllers/localize/currency.controller.js +34 -1
  3. package/dist/controllers/localize/lang.controller.js +0 -1
  4. package/dist/extensions/logic/all_products.js +0 -2
  5. package/dist/extensions/logic/content.d.ts +1 -1
  6. package/dist/extensions/logic/content.js +88 -69
  7. package/dist/extensions/logic/seo.js +0 -3
  8. package/dist/extensions/logic/template copy.d.ts +10 -0
  9. package/dist/extensions/logic/template copy.js +70 -0
  10. package/dist/extensions/logic/template.d.ts +5 -4
  11. package/dist/extensions/logic/template.js +61 -54
  12. package/dist/extensions/logic/ui.d.ts +5 -4
  13. package/dist/extensions/logic/ui.js +42 -17
  14. package/dist/extensions/logic/widget.d.ts +5 -4
  15. package/dist/extensions/logic/widget.js +47 -22
  16. package/dist/extensions/registerAllExtensions.js +0 -2
  17. package/dist/filters/index.d.ts +136 -22
  18. package/dist/filters/index.js +186 -49
  19. package/dist/filters/logic/array/index.d.ts +0 -19
  20. package/dist/filters/logic/array/index.js +0 -43
  21. package/dist/filters/logic/cart/index.d.ts +0 -2
  22. package/dist/filters/logic/cart/index.js +0 -9
  23. package/dist/filters/logic/colors/index.d.ts +0 -16
  24. package/dist/filters/logic/colors/index.js +0 -37
  25. package/dist/filters/logic/customer/index.d.ts +0 -4
  26. package/dist/filters/logic/customer/index.js +0 -13
  27. package/dist/filters/logic/default/index.d.ts +0 -1
  28. package/dist/filters/logic/default/index.js +0 -7
  29. package/dist/filters/logic/format/index.d.ts +0 -4
  30. package/dist/filters/logic/format/index.js +0 -13
  31. package/dist/filters/logic/format/unit_price_with_measurement.js +1 -1
  32. package/dist/filters/logic/format/weight_with_unit.d.ts +1 -1
  33. package/dist/filters/logic/format/weight_with_unit.js +1 -1
  34. package/dist/filters/logic/html/index.d.ts +0 -7
  35. package/dist/filters/logic/html/index.js +0 -19
  36. package/dist/filters/logic/localization/currency_selector.d.ts +1 -7
  37. package/dist/filters/logic/localization/currency_selector.js +10 -36
  38. package/dist/filters/logic/localization/index.d.ts +0 -2
  39. package/dist/filters/logic/localization/index.js +0 -9
  40. package/dist/filters/logic/math/index.d.ts +0 -11
  41. package/dist/filters/logic/math/index.js +0 -27
  42. package/dist/filters/logic/media/external_video_tag.d.ts +1 -1
  43. package/dist/filters/logic/media/external_video_tag.js +21 -1
  44. package/dist/filters/logic/media/image_url.d.ts +1 -1
  45. package/dist/filters/logic/media/image_url.js +30 -2
  46. package/dist/filters/logic/media/index.d.ts +0 -8
  47. package/dist/filters/logic/media/index.js +0 -21
  48. package/dist/filters/registerAllFilters.js +3 -36
  49. package/dist/functions/render-handler.js +29 -7
  50. package/dist/globals/logic/all_products.js +0 -1
  51. package/dist/graphql/query/findAllCountries.d.ts +2 -0
  52. package/dist/graphql/query/findAllCountries.js +41 -0
  53. package/dist/graphql/query/index.d.ts +2 -1
  54. package/dist/graphql/query/index.js +3 -1
  55. package/dist/middleware/init.middleware.js +0 -3
  56. package/dist/middleware/nunjucks.middleware.js +1 -1
  57. package/dist/middleware/prepareData.middleware.js +1 -1
  58. package/dist/middleware/render.middleware.js +14 -5
  59. package/dist/middleware.js +0 -1
  60. package/dist/nunjucksEnv.d.ts +1 -1
  61. package/dist/nunjucksEnv.js +2 -1
  62. package/dist/utils/client.js +1 -1
  63. package/package.json +1 -1
@@ -1,2 +1,3 @@
1
1
  import { Request, Response } from "express";
2
2
  export declare const currencyController: (req: Request, res: Response) => Promise<Response<any, Record<string, any>> | undefined>;
3
+ export declare const getAllCurrency: () => Promise<unknown>;
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.currencyController = void 0;
3
+ exports.getAllCurrency = exports.currencyController = void 0;
4
+ const client_1 = require("../../utils/client");
5
+ const graphql_1 = require("../../graphql");
4
6
  const currencyController = async (req, res) => {
5
7
  const { currency } = req.body;
6
8
  if (!currency) {
@@ -15,3 +17,34 @@ const currencyController = async (req, res) => {
15
17
  res.redirect(redirectUrl);
16
18
  };
17
19
  exports.currencyController = currencyController;
20
+ const currencies = [
21
+ { value: "AED", label: "AED د.إ" },
22
+ { value: "AFN", label: "AFN ؋" },
23
+ { value: "AUD", label: "AUD $" },
24
+ { value: "CAD", label: "CAD $", selected: true },
25
+ { value: "CHF", label: "CHF CHF" },
26
+ { value: "CZK", label: "CZK Kč" },
27
+ { value: "DKK", label: "DKK kr." },
28
+ { value: "EUR", label: "EUR €" },
29
+ { value: "GBP", label: "GBP £" },
30
+ { value: "HKD", label: "HKD $" },
31
+ { value: "ILS", label: "ILS ₪" },
32
+ { value: "JPY", label: "JPY ¥" },
33
+ { value: "KRW", label: "KRW ₩" },
34
+ { value: "MYR", label: "MYR RM" },
35
+ { value: "NZD", label: "NZD $" },
36
+ { value: "PLN", label: "PLN zł" },
37
+ { value: "SEK", label: "SEK kr" },
38
+ { value: "SGD", label: "SGD $" },
39
+ { value: "USD", label: "USD $" },
40
+ ];
41
+ const getAllCurrency = () => {
42
+ // const client = getGqlClient();
43
+ // const Currency = await client.request(query.findAllCountries)
44
+ // return Currency.countries
45
+ return new Promise(resolve => {
46
+ const client = (0, client_1.getGqlClient)();
47
+ client.request(graphql_1.query.findAllCountries).then((data) => resolve(data.countries));
48
+ });
49
+ };
50
+ exports.getAllCurrency = getAllCurrency;
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.langController = void 0;
4
4
  const langController = async (req, res) => {
5
5
  const { lang } = req.body;
6
- console.log("🚀 ~ langController ~ req.body:", req.body);
7
6
  if (!lang) {
8
7
  return res.status(400).send("Missing redirect_url");
9
8
  }
@@ -25,7 +25,6 @@ exports.default = new (class AllProductsExtension {
25
25
  }
26
26
  async run(_context, args = {}, callback) {
27
27
  try {
28
- console.log("🚀 ~ run ~ khalidstest:");
29
28
  if (typeof args !== "object" || Array.isArray(args))
30
29
  args = {};
31
30
  const client = (0, client_js_1.getGqlClient)();
@@ -42,7 +41,6 @@ exports.default = new (class AllProductsExtension {
42
41
  const input = { ...args };
43
42
  const cleanedInput = cleanInput(input);
44
43
  const data = await client.request(index_js_1.query.findAllProducts, { input: cleanedInput });
45
- console.log("🚀 ~ run ~ datfindAllProductsa:", data?.findAllProducts?.data, cleanedInput);
46
44
  const products = data?.findAllProducts?.data || [];
47
45
  const json = JSON.stringify(products, null, 2);
48
46
  callback(null, new nunjucks_1.default.runtime.SafeString(json));
@@ -5,6 +5,6 @@ declare const _default: {
5
5
  run({ ctx, env }: {
6
6
  ctx: any;
7
7
  env: nunjucks.Environment;
8
- }): nunjucks.runtime.SafeString;
8
+ }, templateKey: string, callback: any): void;
9
9
  };
10
10
  export default _default;
@@ -5,86 +5,105 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const nunjucks_1 = __importDefault(require("nunjucks"));
7
7
  const normalizeWidgetPath_1 = require("../../utils/normalizeWidgetPath");
8
+ function renderAsync(env, templatePath, data) {
9
+ return new Promise((resolve, reject) => {
10
+ env.render(templatePath, data, (err, res) => {
11
+ if (err)
12
+ reject(err);
13
+ else
14
+ resolve(res);
15
+ });
16
+ });
17
+ }
8
18
  exports.default = new (class WidgetExtension {
9
19
  constructor() {
10
20
  this.tags = ["content"];
11
21
  }
12
22
  parse(parser, nodes) {
23
+ console.log("🚀 ~ parse ~ parser:", parser);
13
24
  const tok = parser.nextToken();
14
- const args = parser.parseSignature(true, true);
25
+ const args = parser.parseSignature(null, true);
15
26
  parser.advanceAfterBlockEnd(tok.value);
16
- return new nodes.CallExtension(this, "run", args);
27
+ return new nodes.CallExtensionAsync(this, "run", args);
17
28
  }
18
- run({ ctx, env }) {
19
- let widgetPreview = null;
20
- if (env.getGlobal("widget")) {
21
- widgetPreview = env.getGlobal("widget");
22
- }
23
- let widgets = [];
24
- let template = {};
25
- if (!widgetPreview) {
26
- const templates = env.getGlobal("templates");
27
- template = templates.find((t) => t.key === "main");
28
- widgets = template?.widgets || [];
29
- }
30
- else {
31
- widgets = [
32
- {
33
- ...widgetPreview,
34
- widget: widgetPreview.widgetKey,
35
- },
36
- ];
37
- }
38
- const renderedWidgets = [];
39
- for (const widget of widgets) {
40
- const widgetTemplatePath = (0, normalizeWidgetPath_1.normalizeWidgetPath)(widget.widget);
41
- if (!widgetTemplatePath) {
42
- return new nunjucks_1.default.runtime.SafeString(`
43
- <div style="padding: 12px; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 4px; margin: 8px 0;">
44
- ⚠️ <strong>مسار الويجيت غير صالح:</strong> ${widget.widget}
45
- </div>
46
- `);
29
+ run({ ctx, env }, templateKey, callback) {
30
+ console.log("🚀 ~ run ~ templateKey:", templateKey);
31
+ try {
32
+ let widgetPreview = env.getGlobal("widget") || null;
33
+ let widgets = [];
34
+ let template = {};
35
+ if (!widgetPreview) {
36
+ const templates = env.getGlobal("templates");
37
+ template = templates.find((t) => t.key === "main");
38
+ widgets = template?.widgets || [];
47
39
  }
48
- try {
49
- const html = env.render(widgetTemplatePath, {
50
- context: ctx.context,
51
- globals: ctx.globals,
52
- lang: ctx.lang,
53
- currency: ctx.currency,
54
- market: ctx.market,
55
- widget: {
56
- id: widget._id,
57
- type: widget.widget,
58
- data: widget.data,
59
- blocks: widget.blocks ?? [],
40
+ else {
41
+ widgets = [
42
+ {
43
+ ...widgetPreview,
44
+ widget: widgetPreview.widgetKey,
60
45
  },
61
- });
62
- let showDevTools = false;
63
- if (env.getGlobal("isIframe")) {
64
- showDevTools = env.getGlobal("isIframe");
65
- }
66
- if (env.getGlobal("showDevTools")) {
67
- showDevTools = env.getGlobal("showDevTools");
68
- }
69
- if (showDevTools) {
70
- renderedWidgets.push(`
71
- <section content-type="widget" widget-id="${widget._id}" id="qumra-widget-id-${widget._id}" template-key="main" template-id="${template._id}">
72
- ${html}
73
- </section>
74
- `);
75
- }
76
- else {
77
- renderedWidgets.push(html);
78
- }
79
- }
80
- catch (err) {
81
- renderedWidgets.push(`
82
- <div style="padding:10px;background:#ffe;border:1px solid #fc0;color:#aa0">
83
- ⚠️ Error rendering widget '${widget.widget}': ${err.message}
84
- </div>
85
- `);
46
+ ];
86
47
  }
48
+ const showDevTools = env.getGlobal("isIframe") || env.getGlobal("showDevTools") || false;
49
+ widgets
50
+ .reduce((chain, widget) => {
51
+ return chain.then((renderedWidgets) => {
52
+ const widgetTemplatePath = (0, normalizeWidgetPath_1.normalizeWidgetPath)(widget.widget);
53
+ if (!widgetTemplatePath) {
54
+ renderedWidgets.push(`
55
+ <div style="padding: 12px; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 4px; margin: 8px 0;">
56
+ ⚠️ <strong>مسار الويجيت غير صالح:</strong> ${widget.widget}
57
+ </div>
58
+ `);
59
+ return renderedWidgets;
60
+ }
61
+ return renderAsync(env, widgetTemplatePath, {
62
+ context: ctx.context,
63
+ globals: ctx.globals,
64
+ lang: ctx.lang,
65
+ currency: ctx.currency,
66
+ market: ctx.market,
67
+ widget: {
68
+ id: widget._id,
69
+ type: widget.widget,
70
+ data: widget.data,
71
+ blocks: widget.blocks ?? [],
72
+ },
73
+ })
74
+ .then((html) => {
75
+ if (showDevTools) {
76
+ renderedWidgets.push(`
77
+ <section content-type="widget" widget-id="${widget._id}" id="qumra-widget-id-${widget._id}" template-key="main" template-id="${template._id}">
78
+ ${html}
79
+ </section>
80
+ `);
81
+ }
82
+ else {
83
+ renderedWidgets.push(html);
84
+ }
85
+ return renderedWidgets;
86
+ })
87
+ .catch((err) => {
88
+ renderedWidgets.push(`
89
+ <div style="padding:10px;background:#ffe;border:1px solid #fc0;color:#aa0">
90
+ ⚠️ Error rendering widget '${widget.widget}': ${err.message}
91
+ </div>
92
+ `);
93
+ return renderedWidgets;
94
+ });
95
+ });
96
+ }, Promise.resolve([]))
97
+ .then((renderedWidgets) => {
98
+ const output = new nunjucks_1.default.runtime.SafeString(renderedWidgets.join("\n"));
99
+ callback(null, output);
100
+ })
101
+ .catch((err) => {
102
+ callback(err);
103
+ });
104
+ }
105
+ catch (err) {
106
+ callback(err);
87
107
  }
88
- return new nunjucks_1.default.runtime.SafeString(renderedWidgets.join("\n"));
89
108
  }
90
109
  })();
@@ -24,12 +24,9 @@ exports.default = new (class SeoExtension {
24
24
  const product = page.product || c.product || {};
25
25
  // أساسيات
26
26
  const siteName = (0, textOnly_1.textOnly)(store?.name || "Store", 70);
27
- console.log("🚀 ~ run ~ seo.title:", seo.title);
28
27
  const titleRaw = seo.title || page.title || siteName;
29
- console.log("🚀 ~ run ~ titleRaw:", titleRaw);
30
28
  const descRaw = seo.description || page.description || "";
31
29
  const pageTitle = (0, textOnly_1.textOnly)(titleRaw, 70);
32
- console.log("🚀 ~ run ~ pageTitle:", pageTitle);
33
30
  const pageDesc = (0, textOnly_1.textOnly)(descRaw, 160);
34
31
  // روابط وصور
35
32
  const canonical = (0, safeUrl_1.safeUrl)(seo.canonical || page.canonical || page.url || "");
@@ -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
+ }, templateKey: string, callback: any): any;
9
+ };
10
+ export default _default;
@@ -0,0 +1,70 @@
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 normalizeWidgetPath_1 = require("../../utils/normalizeWidgetPath");
8
+ exports.default = new (class WidgetExtension {
9
+ constructor() {
10
+ this.tags = ["template"];
11
+ }
12
+ parse(parser, nodes) {
13
+ const tok = parser.nextToken();
14
+ const args = parser.parseSignature(true, true);
15
+ parser.advanceAfterBlockEnd(tok.value);
16
+ console.log("CallExtension", nodes);
17
+ return new nodes.CallExtensionAsync(this, "run", args);
18
+ }
19
+ run({ ctx, env }, templateKey, callback) {
20
+ const widgetPreview = env.getGlobal("widget");
21
+ if (widgetPreview) {
22
+ return callback(null, "");
23
+ }
24
+ const templates = env.getGlobal("templates");
25
+ const template = templates.find((t) => t.key === templateKey);
26
+ const widgets = template?.widgets || [];
27
+ const renderedWidgets = [];
28
+ for (const widget of widgets) {
29
+ const widgetTemplatePath = (0, normalizeWidgetPath_1.normalizeWidgetPath)(widget.widget);
30
+ if (!widgetTemplatePath) {
31
+ return callback(null, new nunjucks_1.default.runtime.SafeString(`
32
+ <div style="padding:12px;background:#f8d7da;color:#721c24;border:1px solid #f5c6cb;border-radius:4px;">
33
+ ⚠️ <strong>مسار الويجيت غير صالح:</strong> ${widget.widget}
34
+ </div>
35
+ `));
36
+ }
37
+ try {
38
+ const html = env.render(widgetTemplatePath, {
39
+ ...ctx,
40
+ widget: {
41
+ id: widget._id,
42
+ type: widget.widget,
43
+ data: widget.data,
44
+ blocks: widget.blocks ?? [],
45
+ },
46
+ });
47
+ let showDevTools = env.getGlobal("isIframe") || env.getGlobal("showDevTools") || false;
48
+ if (showDevTools) {
49
+ renderedWidgets.push(`
50
+ <section widget-id="${widget._id}" id="qumra-widget-id-${widget._id}" template-key="${templateKey}" template-id="${template._id}">
51
+ ${html}
52
+ </section>
53
+ `);
54
+ }
55
+ else {
56
+ renderedWidgets.push(html);
57
+ }
58
+ }
59
+ catch (err) {
60
+ renderedWidgets.push(`
61
+ <div style="padding:10px;background:#ffe;border:1px solid #fc0;color:#aa0">
62
+ ⚠️ Error rendering widget '${widget.widget}': ${err.message}
63
+ </div>
64
+ `);
65
+ }
66
+ }
67
+ const htmlOutput = new nunjucks_1.default.runtime.SafeString(renderedWidgets.join("\n"));
68
+ return callback(null, htmlOutput);
69
+ }
70
+ })();
@@ -1,10 +1,11 @@
1
1
  import nunjucks from "nunjucks";
2
+ interface RunContext {
3
+ ctx: any;
4
+ env: nunjucks.Environment;
5
+ }
2
6
  declare const _default: {
3
7
  tags: string[];
4
8
  parse(parser: any, nodes: any): any;
5
- run({ ctx, env }: {
6
- ctx: any;
7
- env: nunjucks.Environment;
8
- }, templateKey: string): "" | nunjucks.runtime.SafeString;
9
+ run({ ctx, env }: RunContext, templateKey: string, callback: any): any;
9
10
  };
10
11
  export default _default;
@@ -5,6 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const nunjucks_1 = __importDefault(require("nunjucks"));
7
7
  const normalizeWidgetPath_1 = require("../../utils/normalizeWidgetPath");
8
+ function renderAsync(env, templatePath, data) {
9
+ return new Promise((resolve, reject) => {
10
+ env.render(templatePath, data, (err, res) => {
11
+ if (err)
12
+ reject(err);
13
+ else
14
+ resolve(res);
15
+ });
16
+ });
17
+ }
8
18
  exports.default = new (class WidgetExtension {
9
19
  constructor() {
10
20
  this.tags = ["template"];
@@ -13,36 +23,35 @@ exports.default = new (class WidgetExtension {
13
23
  const tok = parser.nextToken();
14
24
  const args = parser.parseSignature(true, true);
15
25
  parser.advanceAfterBlockEnd(tok.value);
16
- return new nodes.CallExtension(this, "run", args);
26
+ return new nodes.CallExtensionAsync(this, "run", args);
17
27
  }
18
- run({ ctx, env }, templateKey) {
19
- const widgetPreview = env.getGlobal("widget");
20
- if (widgetPreview) {
21
- return "";
22
- }
23
- // if (templateKey === "main") {
24
- // return new nunjucks.runtime.SafeString(`
25
- // <div style="padding: 12px; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 4px; margin: 8px 0;">
26
- // ⚠️ <strong>لا يمكن تضمين قالب "{% template "main" %}" بشكل مباشر:</strong>
27
- // <p>يمكنك استخدام "{% content %}" لعرض المحتوى الرئيسي للصفحة</p>
28
- // </div>
29
- // `);
30
- // }
31
- const templates = env.getGlobal("templates");
32
- const template = templates.find((t) => t.key === templateKey);
33
- const widgets = template?.widgets || [];
34
- const renderedWidgets = [];
35
- for (const widget of widgets) {
36
- const widgetTemplatePath = (0, normalizeWidgetPath_1.normalizeWidgetPath)(widget.widget);
37
- if (!widgetTemplatePath) {
38
- return new nunjucks_1.default.runtime.SafeString(`
39
- <div style="padding: 12px; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 4px; margin: 8px 0;">
40
- ⚠️ <strong>مسار الويجيت غير صالح:</strong> ${widget.widget}
41
- </div>
42
- `);
28
+ run({ ctx, env }, templateKey, callback) {
29
+ try {
30
+ const widgetPreview = env.getGlobal("widget");
31
+ if (widgetPreview)
32
+ return callback(null, "");
33
+ const templates = env.getGlobal("templates") || [];
34
+ const template = templates.find((t) => t.key === templateKey);
35
+ if (!template) {
36
+ return callback(null, new nunjucks_1.default.runtime.SafeString(`<div style="padding:12px;background:#fdecea;color:#b71c1c;">
37
+ ⚠️ Template not found: ${templateKey}
38
+ </div>`));
43
39
  }
44
- try {
45
- const html = env.render(widgetTemplatePath, {
40
+ const widgets = template.widgets || [];
41
+ const showDevTools = env.getGlobal("isIframe") || env.getGlobal("showDevTools") || false;
42
+ widgets
43
+ .reduce((chain, widget) => chain.then((results) => {
44
+ const widgetTemplatePath = (0, normalizeWidgetPath_1.normalizeWidgetPath)(widget.widget);
45
+ if (!widgetTemplatePath) {
46
+ results.push(`
47
+ <div style="padding:12px;background:#f8d7da;color:#721c24;
48
+ border:1px solid #f5c6cb;border-radius:4px;">
49
+ ⚠️ مسار الويجيت غير صالح: ${widget.widget}
50
+ </div>
51
+ `);
52
+ return results;
53
+ }
54
+ return renderAsync(env, widgetTemplatePath, {
46
55
  ...ctx,
47
56
  widget: {
48
57
  id: widget._id,
@@ -50,33 +59,31 @@ exports.default = new (class WidgetExtension {
50
59
  data: widget.data,
51
60
  blocks: widget.blocks ?? [],
52
61
  },
62
+ }).then((html) => {
63
+ if (showDevTools) {
64
+ results.push(`
65
+ <section widget-id="${widget._id}"
66
+ id="qumra-widget-id-${widget._id}"
67
+ template-key="${templateKey}"
68
+ template-id="${template._id}">
69
+ ${html}
70
+ </section>
71
+ `);
72
+ }
73
+ else {
74
+ results.push(html);
75
+ }
76
+ return results;
53
77
  });
54
- let showDevTools = false;
55
- if (env.getGlobal("isIframe")) {
56
- showDevTools = env.getGlobal("isIframe");
57
- }
58
- if (env.getGlobal("showDevTools")) {
59
- showDevTools = env.getGlobal("showDevTools");
60
- }
61
- if (showDevTools) {
62
- renderedWidgets.push(`
63
- <section widget-id="${widget._id}" id="qumra-widget-id-${widget._id}" template-key="${templateKey}" template-id="${template._id}">
64
- ${html}
65
- </section>
66
- `);
67
- }
68
- else {
69
- renderedWidgets.push(html);
70
- }
71
- }
72
- catch (err) {
73
- renderedWidgets.push(`
74
- <div style="padding:10px;background:#ffe;border:1px solid #fc0;color:#aa0">
75
- ⚠️ Error rendering widget '${widget.widget}': ${err.message}
76
- </div>
77
- `);
78
- }
78
+ }), Promise.resolve([]))
79
+ .then((renderedHtml) => {
80
+ const output = new nunjucks_1.default.runtime.SafeString(renderedHtml.join("\n"));
81
+ callback(null, output);
82
+ })
83
+ .catch((err) => callback(err));
84
+ }
85
+ catch (err) {
86
+ callback(err);
79
87
  }
80
- return new nunjucks_1.default.runtime.SafeString(renderedWidgets.join("\n"));
81
88
  }
82
89
  })();
@@ -1,10 +1,11 @@
1
1
  import nunjucks from "nunjucks";
2
+ interface RunContext {
3
+ ctx: any;
4
+ env: nunjucks.Environment;
5
+ }
2
6
  declare const _default: {
3
7
  tags: string[];
4
8
  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
+ run({ ctx, env }: RunContext, file: string, ...args: any[]): any;
9
10
  };
10
11
  export default _default;
@@ -6,7 +6,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const nunjucks_1 = __importDefault(require("nunjucks"));
7
7
  const normalizeUiPath_1 = require("../../utils/normalizeUiPath");
8
8
  const validateUiData_1 = require("../../utils/validateUiData");
9
- exports.default = new (class WidgetExtension {
9
+ function renderAsync(env, templatePath, data) {
10
+ return new Promise((resolve, reject) => {
11
+ env.render(templatePath, data, (err, res) => {
12
+ if (err)
13
+ reject(err);
14
+ else
15
+ resolve(res);
16
+ });
17
+ });
18
+ }
19
+ exports.default = new (class UiExtension {
10
20
  constructor() {
11
21
  this.tags = ["ui"];
12
22
  }
@@ -14,25 +24,40 @@ exports.default = new (class WidgetExtension {
14
24
  const tok = parser.nextToken();
15
25
  const args = parser.parseSignature(true, true);
16
26
  parser.advanceAfterBlockEnd(tok.value);
17
- return new nodes.CallExtension(this, "run", args);
27
+ return new nodes.CallExtensionAsync(this, "run", args);
18
28
  }
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(`
29
+ run({ ctx, env }, file, ...args) {
30
+ // الـ callback دائماً آخر parameter
31
+ const callback = args[args.length - 1];
32
+ // ⭐ الـ data هي كل شيء ما عدا الـ callback
33
+ const data = args.slice(0, -1);
34
+ try {
35
+ // التحقق من صحة المسار
36
+ if (!file || typeof file !== 'string' || file.trim() === '' || !file.includes('.njk')) {
37
+ return callback(new Error("Invalid file path provided to ui extension"));
38
+ }
39
+ const filePath = (0, normalizeUiPath_1.normalizeUiPath)(file);
40
+ if (!filePath) {
41
+ return callback(null, new nunjucks_1.default.runtime.SafeString(`
26
42
  <div style="padding: 12px; background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; border-radius: 4px; margin: 8px 0;">
27
- ⚠️ <strong>مسار الويجيت غير صالح:</strong> ${filePath}
43
+ ⚠️ <strong>مسار الويجيت غير صالح:</strong> ${file}
28
44
  </div>
29
- `);
45
+ `));
46
+ }
47
+ const validated = (0, validateUiData_1.validateUiData)(data);
48
+ // استخدام renderAsync بدلاً من render المباشر
49
+ renderAsync(env, filePath, {
50
+ ...ctx,
51
+ data: validated,
52
+ })
53
+ .then((rendered) => {
54
+ const output = new nunjucks_1.default.runtime.SafeString(rendered);
55
+ callback(null, output);
56
+ })
57
+ .catch((err) => callback(err));
58
+ }
59
+ catch (err) {
60
+ callback(err);
30
61
  }
31
- const validated = (0, validateUiData_1.validateUiData)(data);
32
- const rendered = env.render(filePath, {
33
- ...ctx,
34
- data: validated,
35
- });
36
- return new nunjucks_1.default.runtime.SafeString(rendered);
37
62
  }
38
63
  })();
@@ -1,10 +1,11 @@
1
1
  import nunjucks from "nunjucks";
2
+ interface RunContext {
3
+ ctx: any;
4
+ env: nunjucks.Environment;
5
+ }
2
6
  declare const _default: {
3
7
  tags: string[];
4
8
  parse(parser: any, nodes: any): any;
5
- run({ ctx, env }: {
6
- ctx: any;
7
- env: nunjucks.Environment;
8
- }, widgetPath: string): nunjucks.runtime.SafeString;
9
+ run({ ctx, env }: RunContext, widgetPath: string, ...args: any[]): any;
9
10
  };
10
11
  export default _default;