@opengis/fastify-table 1.3.64 → 1.3.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengis/fastify-table",
3
- "version": "1.3.64",
3
+ "version": "1.3.65",
4
4
  "type": "module",
5
5
  "description": "core-plugins",
6
6
  "keywords": [
@@ -9,15 +9,16 @@ export default async function runCron({
9
9
  const unique = await verifyUnique(name);
10
10
  if (!unique) return;
11
11
 
12
- const db = pg.options.database;
12
+ const db = pg?.options?.database;
13
+ if (!db) return;
13
14
 
14
15
  try {
15
16
  const data = await func({ pg });
16
- const subdir = !!data ? 'cron' : 'cron/null';
17
+ const subdir = data ? 'cron' : 'cron/null';
17
18
  logger.file(subdir, { db, name, result: data });
18
19
  }
19
20
  catch (err) {
20
21
  logger.file('cron', { db, name, error: err.toString() });
21
22
  logger.error(err);
22
23
  }
23
- }
24
+ }
@@ -13,7 +13,7 @@ const rclient = getRedis();
13
13
  async function runCron({
14
14
  pg = pgClients.client, query, name,
15
15
  }) {
16
- const db = pg.options.database;
16
+ const db = pg?.options?.database;
17
17
 
18
18
  // verifyUnique
19
19
  const key = `cron:unique:${name}`;
@@ -16,7 +16,7 @@ export default async function dataDelete({
16
16
  const pg = pg1 || getPG({ name: 'client' });
17
17
 
18
18
  // pg client single transaction support
19
- if (!pg.pk) {
19
+ if (!pg?.pk && config.pg) {
20
20
  pg.options = pgClients.client?.options;
21
21
  pg.tlist = pgClients.client?.tlist;
22
22
  pg.pgType = pgClients.client?.pgType;
@@ -16,7 +16,7 @@ export default async function dataInsert({
16
16
  const pg = pg1 || getPG({ name: 'client' });
17
17
 
18
18
  // pg client single transaction support
19
- if (!pg.pk) {
19
+ if (!pg?.pk && config.pg) {
20
20
  pg.options = pgClients.client?.options;
21
21
  pg.tlist = pgClients.client?.tlist;
22
22
  pg.pgType = pgClients.client?.pgType;
@@ -29,7 +29,7 @@ export default async function dataUpdate({
29
29
  const pg = pg1 || getPG({ name: 'client' });
30
30
 
31
31
  // pg client single transaction support
32
- if (!pg.pk) {
32
+ if (!pg?.pk && config.pg) {
33
33
  pg.options = pgClients.client?.options;
34
34
  pg.tlist = pgClients.client?.tlist;
35
35
  pg.pgType = pgClients.client?.pgType;
@@ -23,7 +23,7 @@ const sqlQuery = `select datname as dbname, application_name as app, client_addr
23
23
 
24
24
  export default async function loggerSystem(req) {
25
25
  const { pg = pgClients.client } = req;
26
- const dbName = pg.options?.database;
26
+ const dbName = pg?.options?.database;
27
27
 
28
28
  const dbsize = config.redis ? await rclient.get(`${dbName}:content:dbsize:${redisKey}`) : null;
29
29
 
@@ -82,8 +82,8 @@ export default async function loggerSystem(req) {
82
82
  root: process.cwd(),
83
83
  processFolder,
84
84
  saveDirectory: filesFolder,
85
- dbhost: pg.options?.host,
86
- dbport: pg.options?.port,
85
+ dbhost: pg?.options?.host,
86
+ dbport: pg?.options?.port,
87
87
  dbname: dbName,
88
88
  },
89
89
 
@@ -9,7 +9,7 @@ const rclient2 = getRedis({ db: 2 });
9
9
 
10
10
  export default async function systemMetricsFifthly({ pg = pgClients.client }) {
11
11
  const system = await loggerSystem({ pg });
12
- const dbName = pg.options?.database;
12
+ const dbName = pg?.options?.database;
13
13
 
14
14
  if (config.redis) { await rclient2.del(`${dbName}:system_metrics`); }
15
15
 
@@ -31,7 +31,7 @@ export default async function execSql(filepath, pg = pgClients.client) {
31
31
  const sql = readFileSync(filepath, 'utf-8');
32
32
 
33
33
  const hash = createHash('md5').update(sql).digest('hex');
34
- const hashes = config.redis ? await rclient.hgetall(`${pg.options?.database}:migration-hashes`).then(obj => Object.keys(obj)) : {};
34
+ const hashes = config.redis ? await rclient.hgetall(`${pg?.options?.database}:migration-hashes`).then(obj => Object.keys(obj)) : [];
35
35
 
36
36
  if (hashes.includes(hash) && !config.disableCache) {
37
37
  console.log(filename, 'skip equal hash', Date.now() - start);
@@ -41,7 +41,7 @@ export default async function execSql(filepath, pg = pgClients.client) {
41
41
  try {
42
42
  console.log(filename, 'start', Date.now() - start);
43
43
  await pg.query(sql);
44
- if (!config.disableCache && config.redis) await rclient.hset(`${pg.options?.database}:migration-hashes`, hash, 1);
44
+ if (!config.disableCache && config.redis) await rclient.hset(`${pg?.options?.database}:migration-hashes`, hash, 1);
45
45
  console.log(filename, 'finish', Date.now() - start);
46
46
  logger.file('migration/success', {
47
47
  filepath,
@@ -5,6 +5,7 @@ const data = {};
5
5
  // decorator
6
6
  export default async function getMeta(opt, nocache) {
7
7
  const pg = opt?.pg || getPG({ name: 'client' });
8
+ if (!pg) return { error: 'pg connection not established', status: 400 };
8
9
  const table = opt?.table || opt;
9
10
 
10
11
  if (pg?.options?.database && data[pg.options.database]?.[table] && !nocache) return data[pg.options.database][table];
@@ -20,8 +20,8 @@ function getPG(param) {
20
20
  if (pgClients[name]) return pgClients[name];
21
21
 
22
22
  const dbConfig = {
23
- user: user || config.pg?.user,
24
- password: password || config.pg?.password,
23
+ user: user || config.pg?.user || 'postgres',
24
+ password: password || config.pg?.password || 'postgres',
25
25
  host: host || config.pg?.host,
26
26
  port: port || config.pg?.port,
27
27
  database: db || database || config.pg?.db || config.pg?.database,
@@ -21,8 +21,8 @@ async function getPGAsync(param) {
21
21
  if (pgClients[name]?.tlist) return pgClients[name];
22
22
 
23
23
  const dbConfig = {
24
- user: user || config.pg?.user,
25
- password: password || config.pg?.password,
24
+ user: user || config.pg?.user || 'postgres',
25
+ password: password || config.pg?.password || 'postgres',
26
26
  host: host || config.pg?.host,
27
27
  port: port || config.pg?.port,
28
28
  database: db || database || config.pg?.db || config.pg?.database,
@@ -7,7 +7,7 @@ import logger from '../../logger/getLogger.js';
7
7
  const rclient = getRedis({ db: 0 });
8
8
 
9
9
  async function init(client) {
10
- if (!client.options?.database) {
10
+ if (!client?.options?.database) {
11
11
  return;
12
12
  }
13
13
  const textQuery = `select
@@ -23,7 +23,7 @@ async function init(client) {
23
23
  from pg_class where relkind in ('r','v')`);
24
24
  const relkinds = rows.reduce((acc, curr) => Object.assign(acc, { [curr.tname]: curr.relkind }), {});
25
25
 
26
- async function query(q, args = [], isstream) {
26
+ async function query(q, args = [], isstream = false) {
27
27
  try {
28
28
  if (isstream) {
29
29
  await client.query('set statement_timeout to 100000000');
@@ -75,12 +75,12 @@ export default function checkPolicy(req, reply) {
75
75
  }
76
76
 
77
77
  /* === policy: public === */
78
- if (policy.includes('public') || skipCheckPolicy(path)) {
78
+ if (policy.includes('public') || skipCheckPolicy(path) || !config.pg || config.auth?.disable || config.local || config.debug || unittest) {
79
79
  return null;
80
80
  }
81
81
 
82
82
  /* === 0. policy: unauthorized access from admin URL === */
83
- if (!validToken && !user?.uid && !config.auth?.disable && isAdmin && !policy.includes('public')) {
83
+ if (!validToken && !user?.uid && isAdmin && !policy.includes('public')) {
84
84
  logger.file('policy/unauthorized', {
85
85
  path, method, params, query, body, token: headers?.token, userId: headers?.uid, ip: req.ip, headers, message: 'unauthorized',
86
86
  });
@@ -88,7 +88,7 @@ export default function checkPolicy(req, reply) {
88
88
  }
89
89
 
90
90
  /* === 3. policy: user === */
91
- if (!validToken && !user && policy.includes('user') && config.pg && !config.auth?.disable && !skipCheckPolicy(path)) {
91
+ if (!validToken && !user && policy.includes('user') && !skipCheckPolicy(path)) {
92
92
  logger.file('policy/user', {
93
93
  path, method, params, query, body, message: 'access restricted: 3',
94
94
  });
@@ -96,7 +96,7 @@ export default function checkPolicy(req, reply) {
96
96
  }
97
97
 
98
98
  /* === 4. policy: referer === */
99
- if (!validToken && !headers?.referer?.includes?.(hostname) && policy.includes('referer') && !config.local && !config.debug) {
99
+ if (!validToken && !headers?.referer?.includes?.(hostname) && policy.includes('referer')) {
100
100
  logger.file('policy/referer', {
101
101
  path, method, params, query, body, message: 'access restricted: 4', uid: user?.uid,
102
102
  });
@@ -104,7 +104,7 @@ export default function checkPolicy(req, reply) {
104
104
  }
105
105
 
106
106
  /* === 5. policy: site auth === */
107
- if (!validToken && !policy.includes('site') && !isAdmin && !config.local && !config.debug && !unittest) {
107
+ if (!validToken && !policy.includes('site') && !isAdmin) {
108
108
  logger.file('policy/site', {
109
109
  path, method, params, query, body, message: 'access restricted: 5', uid: user?.uid,
110
110
  });
@@ -112,7 +112,7 @@ export default function checkPolicy(req, reply) {
112
112
  }
113
113
 
114
114
  /* === 6. base policy: block non-public api w/ out authorization === */
115
- if (!validToken && isAdmin && !isUser && isServer && !config.local && !config.debug) {
115
+ if (!validToken && isAdmin && !isUser && isServer) {
116
116
  logger.file('policy/api', {
117
117
  path, method, params, query, body, message: 'access restricted: 6', uid: user?.uid,
118
118
  });
@@ -1,13 +1,14 @@
1
1
  import getSelect from '../getSelect.js';
2
2
  import pgClients from '../../../pg/pgClients.js';
3
- import redis from '../../../redis/client.js';
3
+ import rclient from '../../../redis/client.js';
4
+ import config from '../../../../../config.js';
4
5
 
5
6
  const selectIds = {};
6
7
  export default async function getSelectVal({
7
8
  pg = pgClients.client, name, values: valuesOrigin, ar = false,
8
9
  }) {
9
10
  if (!valuesOrigin?.length) return null;
10
- const values = valuesOrigin.filter(el => typeof el === 'boolean' ? true : el).map(el => el.toString());
11
+ const values = valuesOrigin.filter(el => (typeof el === 'boolean' ? true : el)).map(el => el.toString());
11
12
  const cls = await getSelect(name, pg);
12
13
 
13
14
  // === array ===
@@ -26,7 +27,7 @@ export default async function getSelectVal({
26
27
 
27
28
  // cache
28
29
  const key = `select:${name}`;
29
- const cache = values?.length ? (await redis.hmget(key, values)).reduce((p, el, i) => ({ ...p, [values[i]]: el }), {}) : {};
30
+ const cache = values?.length && config.redis ? (await rclient.hmget(key, values)).reduce((p, el, i) => ({ ...p, [values[i]]: el }), {}) : {};
30
31
  const filteredValues = values.filter(el => !cache[el]);
31
32
 
32
33
  // query select
@@ -37,8 +38,8 @@ export default async function getSelectVal({
37
38
 
38
39
  const clsObj = { ...cache, ...data.reduce((p, el) => ({ ...p, [el.id.toString()]: el.color ? el : el.text }), {}) };
39
40
 
40
- if (data?.length) {
41
- redis.hmset(key, clsObj);
41
+ if (data?.length && config.redis) {
42
+ rclient.hmset(key, clsObj);
42
43
  }
43
44
 
44
45
  if (ar) {
@@ -75,7 +75,7 @@ export default async function tableAPI(req) {
75
75
  if (!data) return { message: 'not found', status: 404 };
76
76
 
77
77
  Object.keys(schema).filter(key => schema[key]?.type === 'DataTable').forEach(key => {
78
- if (data[key] && !Array.isArray(data[key])) { data[key] = null };
78
+ if (data[key] && !Array.isArray(data[key])) { data[key] = null; }
79
79
  });
80
80
 
81
81
  if (extraKeys?.length) {
@@ -93,7 +93,7 @@ export default async function tableAPI(req) {
93
93
  ids: [JSON.stringify({ id, table: tableName, form: loadTable.form })],
94
94
  uid: user.uid,
95
95
  array: 1,
96
- })[0];
96
+ })?.[0];
97
97
  }
98
98
 
99
99
  await extraDataGet({ rows: [data], table: tableName, form: hookData?.form || tokenData?.form || loadTable.form }, pg);
@@ -9,8 +9,8 @@ import locales from './utils/locales.js';
9
9
  import conditions from './utils/conditions.js';
10
10
 
11
11
  const components = {
12
- 'vs-widget-file': `select 'vs-widget-file' as component, count(*) from crm.files where entity_id=$1 and file_status<>3`,
13
- 'vs-widget-comments': `select 'vs-widget-comments' as component, count(*) from crm.communications where entity_id=$1`
12
+ 'vs-widget-file': 'select \'vs-widget-file\' as component, count(*) from crm.files where entity_id=$1 and file_status<>3',
13
+ 'vs-widget-comments': 'select \'vs-widget-comments\' as component, count(*) from crm.communications where entity_id=$1',
14
14
  };
15
15
 
16
16
  const checkInline = {};
@@ -42,40 +42,38 @@ export default async function dataAPI(req, reply, called) {
42
42
  if (!checkInline[params?.table] && loadTable?.sql?.length && loadTable.table) {
43
43
  const filterSql = loadTable.sql.filter(el => !el?.disabled && (el.inline ?? true));
44
44
  const sqlTable = filterSql.map((el, i) => ` left join lateral (${el.sql}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
45
- const d = await Promise.all(filterSql.map((el, i) => pg.query(`select ${el.name || `t${i}`}.* from(select * from ${loadTable.table})t ${sqlTable} limit 0`).then(el => el.fields)))
45
+ const d = await Promise.all(filterSql.map((el, i) => pg.query(`select ${el.name || `t${i}`}.* from(select * from ${loadTable.table})t ${sqlTable} limit 0`).then(item => item.fields)));
46
46
  d.forEach((el, i) => {
47
- filterSql[i].inline = el.length == 1 ? true : false;
47
+ filterSql[i].inline = el.length === 1;
48
48
  filterSql[i].fields = el.map(f => f.name);
49
49
  });
50
50
  checkInline[params?.table] = loadTable.sql;
51
- } else if (checkInline[params?.table]) {
52
- loadTable.sql = checkInline[params?.table]
51
+ }
52
+ else if (checkInline[params?.table]) {
53
+ loadTable.sql = checkInline[params?.table];
53
54
  }
54
55
 
55
56
  if (query.sql === '0') return loadTable;
56
57
 
58
+ if (!config.pg) { return reply.status(500).send('empty pg'); }
59
+
57
60
  if (!loadTable && !(tokenData?.table && pg.pk?.[tokenData?.table]) && !(called && pg.pk?.[params?.table])) {
58
- return { message: 'template not found', status: 404 };
61
+ return reply.status(404).send('template not found');
59
62
  }
60
63
 
61
64
  const id = tokenData?.id || hookData?.id || params?.id;
62
65
  const { actions = [], query: accessQuery } = await getAccess({ table: tokenData?.table || hookData?.table || params.table, id, user }, pg) || {};
63
66
 
64
67
  if (!actions.includes('view') && !config?.local && !called) {
65
- return { message: 'access restricted', status: 403 };
68
+ return reply.status(403).send('access restricted');
66
69
  }
67
70
 
68
71
  const {
69
72
  table, columns = [], sql, cardSql, filters, form, meta, sqlColumns, public: ispublic, editable = false,
70
73
  } = loadTable || tokenData || params;
71
74
 
72
- const columns1 = columns || dbColumns.map(({ name, title, dataTypeID }) => ({ name, title, type: pg.pgType[dataTypeID] }));
73
- columns1.forEach(col => {
74
- Object.assign(col, locales[`${table || params.table}.${col.name}`] || {});
75
- });
76
-
77
75
  const tableMeta = await getMeta({ pg, table });
78
- timeArr.push(Date.now())
76
+ timeArr.push(Date.now());
79
77
  if (tableMeta?.view) {
80
78
  if (!loadTable?.key && !tokenData?.key) return { message: `key not found: ${table}`, status: 404 };
81
79
  Object.assign(tableMeta, { pk: loadTable?.key || tokenData?.key });
@@ -83,7 +81,14 @@ export default async function dataAPI(req, reply, called) {
83
81
 
84
82
  const { pk, columns: dbColumns = [] } = tableMeta || {};
85
83
 
86
- if (!pk) return { message: `table not found: ${table}`, status: 404 };
84
+ const columns1 = columns || dbColumns.map(({ name, title, dataTypeID }) => ({ name, title, type: pg.pgType[dataTypeID] }));
85
+ columns1.forEach(col => {
86
+ Object.assign(col, locales[`${table || params.table}.${col.name}`] || {});
87
+ });
88
+
89
+ if (!pk) {
90
+ return reply.status(404).send(`table not found: ${table}`);
91
+ }
87
92
 
88
93
  const columnList = dbColumns.map((el) => el.name || el).join(',');
89
94
  const sqlTable = sql?.filter?.((el) => !el?.disabled && !el.inline && el?.sql?.replace && (!el.sql.includes('{{uid}}') || uid)).map((el, i) => ` left join lateral (${el.sql.replace('{{uid}}', uid)}) ${el.name || `t${i}`} on 1=1 `)?.join('') || '';
@@ -179,7 +184,7 @@ export default async function dataAPI(req, reply, called) {
179
184
  throw new Error(err.toString());
180
185
  });
181
186
 
182
- timeArr.push(Date.now())
187
+ timeArr.push(Date.now());
183
188
 
184
189
  if (uid && rows.length && editable) {
185
190
  rows.forEach(row => {
@@ -187,7 +192,7 @@ export default async function dataAPI(req, reply, called) {
187
192
  ids: [JSON.stringify({ id: row.id, table: tokenData?.table || hookData?.table || params.table, form: loadTable?.form })],
188
193
  uid,
189
194
  array: 1,
190
- })[0];
195
+ })?.[0];
191
196
  });
192
197
  }
193
198
 
@@ -209,14 +214,14 @@ export default async function dataAPI(req, reply, called) {
209
214
  ? { total: rows.length, filtered: rows.length }
210
215
  : await pg.queryCache?.(qCount, { table: loadTable?.table || tokenData?.table, time: 5 }).then(el => el?.rows[0] || {});
211
216
 
212
- timeArr.push(Date.now())
217
+ timeArr.push(Date.now());
213
218
  const { total, filtered } = counts || {};
214
219
  const agg = Object.keys(counts).filter(el => !['total', 'filtered'].includes(el)).reduce((acc, el) => ({ ...acc, [el]: counts[el] }), {});
215
220
 
216
221
  await extraDataGet({ rows, table: loadTable?.table, form }, pg);
217
222
 
218
223
  await metaFormat({ rows, table: tokenData?.table || hookData?.table || params.table, sufix }, pg);
219
- timeArr.push(Date.now())
224
+ timeArr.push(Date.now());
220
225
  const status = [];
221
226
  if (loadTable?.meta?.status) {
222
227
  const statusColumn = loadTable.meta?.cls?.[loadTable.meta?.status]
@@ -237,19 +242,19 @@ export default async function dataAPI(req, reply, called) {
237
242
 
238
243
  const tokens = {};
239
244
  if (template && objectId) {
240
-
241
245
  // tokens result
242
246
  if (index?.tokens && typeof index?.tokens === 'object' && !Array.isArray(index?.tokens)) {
243
247
  Object.keys(index.tokens || {})
244
248
  .filter(key => index?.tokens[key]?.public
245
249
  || actions?.includes?.('edit')
246
250
  || actions?.includes?.('add')
247
- || !index?.tokens[key]?.table
248
- )
251
+ || !index?.tokens[key]?.table)
249
252
  .forEach(key => {
250
253
  const item = index?.tokens[key];
251
254
  Object.keys(item).filter(el => item[el]?.includes?.('{{')).forEach(el => {
252
- item[el] = handlebarsSync.compile(item[el])({ user, uid: user?.uid, id, data: rows[0] });
255
+ item[el] = handlebarsSync.compile(item[el])({
256
+ user, uid: user?.uid, id, data: rows[0],
257
+ });
253
258
  });
254
259
 
255
260
  const token = item.form && item.table ? setToken({
@@ -261,43 +266,47 @@ export default async function dataAPI(req, reply, called) {
261
266
  });
262
267
  }
263
268
 
264
- // conditions
269
+ // conditions
265
270
  panels?.filter(el => el.items).forEach(el => {
266
- el.items = el.items?.filter(el => conditions(el.conditions, rows[0]));
271
+ el.items = el.items?.filter(item => conditions(item.conditions, rows[0]));
267
272
  });
268
273
 
269
274
  // title, count
270
275
  panels?.filter(el => el.items).forEach(async el => {
271
- const filtered = el.items.filter(el => el.count?.toLowerCase?.().includes('select'));
272
- const data = await Promise.all(filtered.map(el => pg.query(el.count).then(el => el.rows[0] || {})))
273
- filtered.forEach((el, i) => {
274
- Object.assign(el, data[i] || {}, data[i].count ? {} : { count: undefined })
276
+ const filtered1 = el.items.filter(item => item.count?.toLowerCase?.().includes('select'));
277
+ const data = await Promise.all(filtered1.map(item => pg.query(item.count).then(item1 => item1.rows[0] || {})));
278
+ filtered1.forEach((el1, i) => {
279
+ Object.assign(el1, data[i] || {}, data[i].count ? {} : { count: undefined });
275
280
  });
276
- const q = el.items.map((el) => el.component ? components[el.component] : null).filter(el => el).join(' union all ');
277
- const counts = q && id
281
+ const q1 = el.items.map((item) => (item.component ? components[item.component] : null)).filter(item => item).join(' union all ');
282
+ const counts1 = q1 && id
278
283
  ? await pg.query(q, [id])
279
284
  .then(e => e.rows.reduce((acc, curr) => Object.assign(acc, { [curr.component]: curr.count }), {}))
280
285
  : {};
281
- el.items?.filter?.(item => item.component)?.forEach(item => Object.assign(item, { count: counts?.[item.component] }));
286
+ el.items?.filter?.(item => item.component)?.forEach(item => Object.assign(item, { count: counts1?.[item.component] }));
282
287
  });
283
288
 
284
289
  // data result
285
290
  const data = {};
286
- const route = pg.pk?.['admin.routes'] ? await pg.query(`select route_id as path, title from admin.routes where enabled and alias=$1 limit 1`, [table])
291
+ const route = pg.pk?.['admin.routes'] ? await pg.query('select route_id as path, title from admin.routes where enabled and alias=$1 limit 1', [table])
287
292
  .then(el => el.rows?.[0] || {}) : {};
288
293
  Object.assign(route, { tableTitle: loadTable?.title });
289
294
  if (index?.data && index?.data?.[0]?.name) {
290
295
  await Promise.all(index.data.filter((el) => el?.name && el?.sql).map(async (el) => {
291
- const q = handlebarsSync.compile(el.sql)({ data: rows[0], user, uid: user?.uid, id });
292
- const { rows: sqlData } = await pg.query(q);
296
+ const q2 = handlebarsSync.compile(el.sql)({
297
+ data: rows[0], user, uid: user?.uid, id,
298
+ });
299
+ const { rows: sqlData } = await pg.query(q2);
293
300
  data[el.name] = sqlData;
294
301
  }));
295
302
  }
296
303
 
297
304
  // html
298
305
  await Promise.all(template.filter(el => el[0].includes('.hbs')).map(async (el) => {
299
- const htmlContent = await handlebars.compile(el[1])({ ...rows[0], user, data, tokens });
300
- const name = el[0].substring(0, el[0].lastIndexOf('.'))
306
+ const htmlContent = await handlebars.compile(el[1])({
307
+ ...rows[0], user, data, tokens,
308
+ });
309
+ const name = el[0].substring(0, el[0].lastIndexOf('.'));
301
310
  html[name] = htmlContent;
302
311
  }));
303
312
  }
@@ -338,7 +347,11 @@ export default async function dataAPI(req, reply, called) {
338
347
  // console.log({ add: loadTable.table, form: loadTable.form });
339
348
  if (uid && actions.includes('add')) {
340
349
  const addTokens = setToken({
341
- ids: [JSON.stringify({ table: tokenData?.table || hookData?.table || params.table, form: loadTable?.form })],
350
+ ids: [
351
+ JSON.stringify({
352
+ table: tokenData?.table || hookData?.table || params.table,
353
+ form: loadTable?.form,
354
+ })],
342
355
  uid,
343
356
  array: 1,
344
357
  });
@@ -346,7 +359,12 @@ export default async function dataAPI(req, reply, called) {
346
359
  }
347
360
 
348
361
  const result = await applyHook('afterData', {
349
- pg, table: loadTable?.table || tokenData?.table, id: tokenData?.id || hookData?.id || params.id, template: tokenData?.table || hookData?.table || params.table, payload: res, user,
362
+ pg,
363
+ table: loadTable?.table || tokenData?.table,
364
+ id: tokenData?.id || hookData?.id || params.id,
365
+ template: tokenData?.table || hookData?.table || params.table,
366
+ payload: res,
367
+ user,
350
368
  });
351
369
 
352
370
  return result || res;