lupine.api 1.1.59 → 1.1.61

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": "lupine.api",
3
- "version": "1.1.59",
3
+ "version": "1.1.61",
4
4
  "license": "MIT",
5
5
  "author": "uuware.com",
6
6
  "homepage": "https://github.com/uuware/lupine.js",
@@ -1,44 +1,8 @@
1
1
  import { ServerResponse } from 'http';
2
- import { Logger } from 'lupine.api';
2
+ import { exportCSVData, exportCSVHead, Logger } from 'lupine.api';
3
3
  import { Db } from '../lib/db';
4
4
 
5
5
  const logger = new Logger('admin-csv');
6
- export const exportCSVData = async (db: Db, tableName: string, res: ServerResponse) => {
7
- res.write(`@TABLE,${tableName}\r\n`);
8
-
9
- const result = await db.selectObject(tableName);
10
- if (result && result.length > 0) {
11
- const fields = Object.keys(result[0]).join(',').toLowerCase();
12
- res.write(`@FIELD,${fields}\r\n`);
13
- result.forEach((row: any) => {
14
- res.write(`${JSON.stringify(Object.values(row))}\r\n`);
15
- });
16
- } else {
17
- res.write('#no data\r\n');
18
- }
19
- };
20
-
21
- export const exportCSVHead = (fileName: string, res: ServerResponse) => {
22
- res.writeHead(200, {
23
- 'Content-Type': 'text/csv',
24
- // 'Expires': '0',
25
- // 'Cache-Control': 'no-cache, no-store, must-revalidate',
26
- 'Content-Disposition': 'attachment; filename=' + fileName + '.ljcsv',
27
- // 'Content-Description': 'File Transfer',
28
- });
29
- };
30
-
31
- export const exportCSV = async (db: Db, tableName: string, res: ServerResponse) => {
32
- if (tableName) {
33
- exportCSVHead(tableName + '-' + new Date().toJSON().replace(/:/g, '-'), res);
34
- await exportCSVData(db, tableName, res);
35
- } else {
36
- res.writeHead(200, { 'Content-Type': 'text/html' });
37
- res.write('Need a table name.');
38
- }
39
- res.end();
40
- return true;
41
- };
42
6
 
43
7
  export const exportCSVTables = async (db: Db, tables: string[], res: ServerResponse) => {
44
8
  exportCSVHead('all-tables-' + new Date().toJSON().replace(/:/g, '-'), res);
@@ -49,46 +13,3 @@ export const exportCSVTables = async (db: Db, tables: string[], res: ServerRespo
49
13
  res.end();
50
14
  return true;
51
15
  };
52
-
53
- export const loadCSV = async (db: Db, lines: string[]) => {
54
- let table = '';
55
- let insSql = '';
56
- const result: any = {};
57
- let toFields: string[] = [];
58
- let toFieldsIndex: number[] = [];
59
- for (const i in lines) {
60
- if (!lines[i] || lines[i].startsWith('#')) {
61
- continue;
62
- }
63
- if (lines[i].startsWith('@TABLE,')) {
64
- table = lines[i].substring(7);
65
- result[table] = { succeeded: 0, failed: 0, errorMessage: [] };
66
-
67
- const toTableInfo = await db.getTableInfo(table);
68
- toFields = toTableInfo.map((item: any) => item.name);
69
- } else if (lines[i].startsWith('@FIELD,')) {
70
- const fromFields = lines[i]
71
- .substring(7)
72
- .split(',')
73
- .filter((item: string) => toFields.includes(item));
74
- toFieldsIndex = toFields.map((item: string) => fromFields.indexOf(item));
75
- const values = Array(fromFields.length).fill('?').join(',');
76
- insSql = `INSERT INTO ${table} (${fromFields.join(',')} ) VALUES (${values})`;
77
- } else {
78
- if (toFields.length === 0 || !insSql) {
79
- throw new Error('Invalid CSV format (no @TABLE or @FIELD)');
80
- }
81
- try {
82
- const row = JSON.parse(lines[i]);
83
- const values = toFieldsIndex.map((index: number) => row[index]);
84
- await db.execute(insSql, values);
85
- result[table].succeeded++;
86
- } catch (error: any) {
87
- result[table].failed++;
88
- result[table].errorMessage.push(error.message);
89
- }
90
- }
91
- }
92
-
93
- return result;
94
- };
@@ -1,6 +1,16 @@
1
1
  import { ServerResponse } from 'http';
2
- import { IApiBase, FsUtils, Logger, apiCache, ServerRequest, ApiRouter, ApiHelper } from 'lupine.api';
3
- import { exportCSV, exportCSVTables, loadCSV } from './admin-csv';
2
+ import {
3
+ IApiBase,
4
+ FsUtils,
5
+ Logger,
6
+ apiCache,
7
+ ServerRequest,
8
+ ApiRouter,
9
+ ApiHelper,
10
+ loadCSV,
11
+ exportCSV,
12
+ } from 'lupine.api';
13
+ import { exportCSVTables } from './admin-csv';
4
14
 
5
15
  const logger = new Logger('admin-db');
6
16
  export class AdminDb implements IApiBase {
@@ -115,10 +115,16 @@ export class AdminPerformance implements IApiBase {
115
115
  times: c.times,
116
116
  })),
117
117
  process: {
118
- ...(process as any),
119
- mainModule: undefined,
120
- moduleLoadList: undefined,
121
- config: undefined,
118
+ // ...(process as any), // cause delay
119
+ pid: process.pid,
120
+ ppid: process.ppid,
121
+ title: process.title,
122
+ version: process.version,
123
+ versions: process.versions,
124
+ cwd: process.cwd(),
125
+ execPath: process.execPath,
126
+ argv: process.argv,
127
+ // config: process.config,
122
128
  },
123
129
  },
124
130
  };
@@ -609,9 +609,12 @@ export class AdminRelease implements IApiBase {
609
609
  // } else if (chkOption === 'web') {
610
610
  // saveFile = path.join(appData.apiPath, '..', toList + '_web', 'index.js');
611
611
  } else if (chkOption === 'web-sub' && data.webSub) {
612
- const folder = path.join(appData.apiPath, '..', toList + '_web', path.basename(data.webSub));
613
- if (!(await FsUtils.pathExist(folder))) {
614
- await FsUtils.mkdir(folder);
612
+ const baseName = path.basename(data.webSub);
613
+ if (baseName !== data.webSub) {
614
+ const folder = path.join(appData.apiPath, '..', toList + '_web', baseName);
615
+ if (!(await FsUtils.pathExist(folder))) {
616
+ await FsUtils.mkdir(folder);
617
+ }
615
618
  }
616
619
  saveFile = path.join(appData.apiPath, '..', toList + '_web', data.webSub);
617
620
  } else if ((chkOption as string).startsWith('.env')) {
@@ -1,5 +1,8 @@
1
1
  export const encodeHtml = (str: string): string => {
2
- return str.replace(
2
+ if (!str) {
3
+ return str;
4
+ }
5
+ return str.toString().replace(
3
6
  /[&<>'"]/g,
4
7
  (tag) =>
5
8
  ({
@@ -13,7 +16,10 @@ export const encodeHtml = (str: string): string => {
13
16
  };
14
17
 
15
18
  export const decodeHtml = (str: string): string => {
16
- return str.replace(
19
+ if (!str) {
20
+ return str;
21
+ }
22
+ return str.toString().replace(
17
23
  /&(\D+);/gi,
18
24
  (tag) =>
19
25
  ({
@@ -0,0 +1,89 @@
1
+ import { ServerResponse } from 'http';
2
+ import { Db } from '../db';
3
+
4
+ export const exportCSVData = async (db: Db, tableName: string, res: ServerResponse) => {
5
+ res.write(`@TABLE,${tableName}\r\n`);
6
+
7
+ const result = await db.selectObject(tableName);
8
+ if (result && result.length > 0) {
9
+ const fields = Object.keys(result[0]).join(',').toLowerCase();
10
+ res.write(`@FIELD,${fields}\r\n`);
11
+ result.forEach((row: any) => {
12
+ res.write(`${JSON.stringify(Object.values(row))}\r\n`);
13
+ });
14
+ } else {
15
+ res.write('#no data\r\n');
16
+ }
17
+ };
18
+
19
+ export const exportCSVHead = (fileName: string, res: ServerResponse) => {
20
+ res.writeHead(200, {
21
+ 'Content-Type': 'text/csv',
22
+ // 'Expires': '0',
23
+ // 'Cache-Control': 'no-cache, no-store, must-revalidate',
24
+ 'Content-Disposition': 'attachment; filename=' + fileName + '.ljcsv',
25
+ // 'Content-Description': 'File Transfer',
26
+ });
27
+ };
28
+
29
+ export const exportCSV = async (db: Db, tableName: string, res: ServerResponse) => {
30
+ if (tableName) {
31
+ exportCSVHead(tableName + '-' + new Date().toJSON().replace(/:/g, '-'), res);
32
+ await exportCSVData(db, tableName, res);
33
+ } else {
34
+ res.writeHead(200, { 'Content-Type': 'text/html' });
35
+ res.write('Need a table name.');
36
+ }
37
+ res.end();
38
+ return true;
39
+ };
40
+
41
+ export const loadCSV = async (db: Db, lines: string[]) => {
42
+ let table = '';
43
+ let insSql = '';
44
+ const result: any = {};
45
+ let toFields: string[] = [];
46
+ let toFieldsIndex: number[] = [];
47
+ for (const i in lines) {
48
+ if (!lines[i] || lines[i].startsWith('#')) {
49
+ continue;
50
+ }
51
+ if (lines[i].startsWith('@TABLE,')) {
52
+ table = lines[i].substring(7);
53
+ result[table] = { succeeded: 0, failed: 0, errorMessage: [] };
54
+
55
+ const toTableInfo = await db.getTableInfo(table);
56
+ toFields = toTableInfo.map((item: any) => item.name);
57
+ } else if (lines[i].startsWith('@FIELD,')) {
58
+ const allCsvFields = lines[i].substring(7).split(',');
59
+ const validFields: string[] = [];
60
+ const validIndices: number[] = [];
61
+
62
+ allCsvFields.forEach((field, index) => {
63
+ if (toFields.includes(field)) {
64
+ validFields.push(field);
65
+ validIndices.push(index);
66
+ }
67
+ });
68
+
69
+ toFieldsIndex = validIndices;
70
+ const values = Array(validFields.length).fill('?').join(',');
71
+ insSql = `INSERT INTO ${table} (${validFields.join(',')}) VALUES (${values})`;
72
+ } else {
73
+ if (toFields.length === 0 || !insSql) {
74
+ throw new Error('Invalid CSV format (no @TABLE or @FIELD)');
75
+ }
76
+ try {
77
+ const row = JSON.parse(lines[i]);
78
+ const values = toFieldsIndex.map((index: number) => row[index]);
79
+ await db.execute(insSql, values);
80
+ result[table].succeeded++;
81
+ } catch (error: any) {
82
+ result[table].failed++;
83
+ result[table].errorMessage.push(error.message);
84
+ }
85
+ }
86
+ }
87
+
88
+ return result;
89
+ };
@@ -1,12 +1,13 @@
1
+ export * from './cookie-util';
1
2
  export * from './crypto';
3
+ export * from './csv-util';
2
4
  export * from './date-utils';
3
5
  export * from './deep-merge';
4
6
  export * from './delay';
5
7
  export * from './file-setting';
6
8
  export * from './format-bytes';
9
+ export * from './fs-utils';
7
10
  export * from './get-env';
8
11
  export * from './is-type';
9
12
  export * from './load-env';
10
13
  export * from './pad';
11
- export * from './cookie-util';
12
- export * from './fs-utils';