v-transform 2.1.1 → 2.2.0

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/src/parser.js CHANGED
@@ -1,157 +1,140 @@
1
- import yaml from 'js-yaml';
1
+ import yaml from 'js-yaml'
2
2
 
3
- function parseStruct(head) {
4
- const layer = [];
5
- const subs = {};
6
- const json = [];
7
-
8
- for(const col in head) {
9
- let key = head[col].trim();
10
- if(key[0] == '#') continue;
11
- if(key[0] == '@') {
12
- json.push(col);
13
- key = key.substr(1);
14
- }
15
- let [first, ...last] = key.split(/[\.:]/);
16
- first = first.trim();
17
- if(!subs[first]) {
18
- layer.push(first);
19
- }
20
- if(last.length > 0) {
21
- if(!subs[first]) subs[first] = {};
22
- subs[first][col] = last.join('.');
23
- } else {
24
- if(first.substr(-2) == '[]') {
25
- if(!subs[first]) subs[first] = [];
26
- subs[first].push(col);
27
- } else {
28
- subs[first] = col;
29
- }
30
- }
3
+ function isCommentKey(key) {
4
+ return key.startsWith('#')
5
+ }
31
6
 
7
+ function isJsonKey(key) {
8
+ return key.startsWith('@')
9
+ }
10
+
11
+ function processHeaderColumn(col, head, layer, subs, json) {
12
+ let key = head[col].trim()
13
+ if (isCommentKey(key)) return
14
+ if (isJsonKey(key)) {
15
+ json.push(col)
16
+ key = key.substr(1)
17
+ }
18
+ const [first, ...parts] = key.split(/[.:]/).map(p => p.trim())
19
+ if (!subs[first]) layer.push(first)
20
+ if (parts.length > 0) {
21
+ if (!subs[first]) subs[first] = {}
22
+ subs[first][col] = parts.join('.')
23
+ } else if (first.endsWith('[]')) {
24
+ if (!subs[first]) subs[first] = []
25
+ subs[first].push(col)
26
+ } else {
27
+ subs[first] = col
32
28
  }
29
+ }
33
30
 
34
- const struct = {
35
- type: 'object',
36
- subs: [],
37
- json
38
- };
31
+ function createObjectSub(key, subs) {
32
+ subs = [parseStruct(subs[key])]
33
+ key = key.substr(0, key.length - 2)
34
+ return { type: 'object', key, subs }
35
+ }
39
36
 
40
- for(const key of layer) {
41
- if(key[0] == '$') {
42
- struct.key = `#${subs[key]}`;
43
- }
44
- switch(key.substr(-2)) {
45
- case '{}':
46
- struct.subs.push({
47
- type: 'object',
48
- key: key.substr(0, key.length -2),
49
- subs: [ parseStruct(subs[key]) ]
50
- });
51
- break;
52
- case '[]':
53
- struct.subs.push({
54
- type: 'array',
55
- key: key.substr(0, key.length -2),
56
- subs: Array.isArray(subs[key])
57
- ? subs[key].map(col => ({
58
- type: 'value',
59
- source: col
60
- }))
61
- : [parseStruct(subs[key])]
62
- });
63
- break;
64
- default:
65
- struct.subs.push(
66
- typeof subs[key] == 'string'
67
- ? ({
68
- type: 'value',
69
- key: key[0] == '$'
70
- ? key.substr(1)
71
- : key,
72
- source: subs[key]
73
- })
74
- : {
75
- key,
76
- type: 'object',
77
- subs: parseStruct(subs[key]).subs
78
- }
79
- );
80
- }
81
- }
37
+ function createArraySub(key, subs) {
38
+ if (Array.isArray(subs[key]))
39
+ subs = subs[key].map(source => ({ type: 'value', source }))
40
+ else subs = [parseStruct(subs[key])]
41
+ key = key.substr(0, key.length - 2)
42
+ return { type: 'array', key, subs }
43
+ }
44
+
45
+ function createValueSub(key, subs) {
46
+ const source = subs[key]
47
+ if (key.startsWith('$')) key = key.substr(1)
48
+ return { type: 'value', key, source }
49
+ }
82
50
 
83
- return struct;
51
+ function createNestedObjectSub(key, subs) {
52
+ return { type: 'object', key, subs: parseStruct(subs[key]).subs }
84
53
  }
85
54
 
86
- function formatRow({type, key, source, subs}, row, original, json) {
87
- if(row[0] == '#' || (''+row[0])[0] == '#') return null;
88
- if(key && key[0] == '#') key = row[key.substr(1)];
89
- switch(type) {
55
+ function createSubFromKey(key, subs) {
56
+ if (key.endsWith('{}')) return createObjectSub(key, subs)
57
+ if (key.endsWith('[]')) return createArraySub(key, subs)
58
+ if (typeof subs[key] === 'string') return createValueSub(key, subs)
59
+ return createNestedObjectSub(key, subs)
60
+ }
61
+
62
+ function parseStruct(head) {
63
+ const layer = []
64
+ const subs = {}
65
+ const json = []
66
+ for (const col in head) processHeaderColumn(col, head, layer, subs, json)
67
+ const struct = { type: 'object', subs: [], json }
68
+ for (const key of layer) {
69
+ if (key.startsWith('$')) struct.key = `#${subs[key]}`
70
+ const sub = createSubFromKey(key, subs)
71
+ struct.subs.push(sub)
72
+ }
73
+ return struct
74
+ }
75
+
76
+ function formatRow({ type, key, source, subs }, row, original, json) {
77
+ if (('' + row[0]).startsWith('#')) return null
78
+ if (key?.startsWith('#')) key = row[key.substr(1)]
79
+ switch (type) {
90
80
  case 'value':
91
- const value = row[source];
92
- if(value != void 0) {
93
- try {
94
- return {
95
- key,
96
- value: json.includes(source)
97
- ? yaml.load(value)
98
- : value
99
- };
100
- } catch(e) {
101
- return null;
102
- }
103
- }
104
- return null;
81
+ return formatValue(key, source, row[source], json)
105
82
  case 'array':
106
- const arr = original?.[key] || [];
107
- for(const sub of subs) {
108
- const data = formatRow(sub, row, arr, json);
109
- if(data) {
110
- arr.push(data.value);
111
- }
112
- }
113
- if(arr.length) {
114
- return { key, value: arr };
115
- }
116
- return null;
83
+ return formatArray(key, subs, row, original, json)
117
84
  case 'object':
118
- const obj = original?.[key] || {};
119
- let r = false;
120
- for(const sub of subs) {
121
- const data = formatRow(sub, row, obj, json);
122
- if(data) {
123
- r = true;
124
- obj[data.key] = data.value;
125
- }
126
- }
127
- if(r) {
128
- return { key, value: obj };
129
- }
130
- return null;
85
+ return formatObject(key, subs, row, original, json)
86
+ }
87
+ }
88
+
89
+ function formatValue(key, source, value, json) {
90
+ if (value == null) return null
91
+ if (json.includes(source)) value = yaml.load(value)
92
+ return { key, value }
93
+ }
94
+
95
+ function formatArray(key, subs, row, original, json) {
96
+ const arr = original?.[key] || []
97
+ for (const sub of subs) {
98
+ const data = formatRow(sub, row, arr, json)
99
+ if (data) arr.push(data.value)
100
+ }
101
+ return arr.length ? { key, value: arr } : null
102
+ }
103
+
104
+ function formatObject(key, subs, row, original, json) {
105
+ const obj = original?.[key] || {}
106
+ let hasData = false
107
+ for (const sub of subs) {
108
+ const data = formatRow(sub, row, obj, json)
109
+ if (data) {
110
+ hasData = true
111
+ obj[data.key] = data.value
112
+ }
131
113
  }
114
+ return hasData ? { key, value: obj } : null
132
115
  }
133
116
 
134
117
  function formatSheet(struct, rawSheet, json) {
135
- let data;
136
- if(struct.key == void 0) {
137
- data = [];
138
- for(const row of rawSheet) {
139
- const temp = formatRow(struct, row, null, json);
140
- if(temp) data.push(temp.value);
118
+ let data
119
+ if (struct.key == void 0) {
120
+ data = []
121
+ for (const row of rawSheet) {
122
+ const temp = formatRow(struct, row, null, json)
123
+ if (temp) data.push(temp.value)
141
124
  }
142
125
  } else {
143
- data = {};
144
- for(const row of rawSheet) {
145
- const temp = formatRow(struct, row, data, json);
146
- if(temp) data[temp.key] = temp.value;
126
+ data = {}
127
+ for (const row of rawSheet) {
128
+ const temp = formatRow(struct, row, data, json)
129
+ if (temp) data[temp.key] = temp.value
147
130
  }
148
131
  }
149
132
 
150
- return data;
133
+ return data
151
134
  }
152
135
 
153
136
  export function parser(rawSheet) {
154
- const struct = parseStruct(rawSheet.shift());
155
- rawSheet.shift();
156
- return formatSheet(struct, rawSheet, struct.json);
157
- }
137
+ const struct = parseStruct(rawSheet.shift())
138
+ rawSheet.shift()
139
+ return formatSheet(struct, rawSheet, struct.json)
140
+ }
package/src/prepare.js CHANGED
@@ -1,26 +1,23 @@
1
- import path from 'path';
2
- import { readFile } from 'fs/promises';
3
- import * as XLSX from 'xlsx';
1
+ import path from 'node:path'
2
+ import { readFile } from 'node:fs/promises'
3
+ import { read, utils } from 'xlsx'
4
4
 
5
5
  export async function prepare(xlsxPath) {
6
- switch(path.extname(xlsxPath)) {
6
+ switch (path.extname(xlsxPath)) {
7
7
  case '.xls':
8
8
  case '.xlsx':
9
- break;
9
+ break
10
10
  default:
11
- return [];
11
+ return []
12
12
  }
13
- const xlsxFileBuffer = await readFile(xlsxPath);
14
- const xlsx = XLSX.read(xlsxFileBuffer, {type: 'buffer'});
15
- const sheets = xlsx.Sheets;
16
- const data = [];
17
- for(const sheetName in sheets) {
18
- const sheetRawData = sheets[sheetName];
19
- if(!sheetRawData['!ref']) break;
20
- data.push({
21
- name: sheetName,
22
- data: XLSX.utils.sheet_to_json(sheetRawData, { header: 1 })
23
- });
13
+ const xlsxFileBuffer = await readFile(xlsxPath)
14
+ const xlsx = read(xlsxFileBuffer, { type: 'buffer' })
15
+ const datas = []
16
+ for (const name in xlsx.Sheets) {
17
+ const sheetRawData = xlsx.Sheets[name]
18
+ if (!sheetRawData['!ref']) break
19
+ const data = utils.sheet_to_json(sheetRawData, { header: 1 })
20
+ datas.push({ name, data })
24
21
  }
25
- return data;
26
- }
22
+ return datas
23
+ }
package/src/transform.js CHANGED
@@ -1,91 +1,93 @@
1
- import path from 'path';
2
- import { load } from './loader.js';
3
- import { prepare } from './prepare.js';
4
- import { parser } from './parser.js';
5
- import { dump } from './dump.js';
1
+ import path from 'node:path'
2
+ import { load } from './loader.js'
3
+ import { prepare } from './prepare.js'
4
+ import { parser } from './parser.js'
5
+ import { dump } from './dump.js'
6
6
 
7
7
  export async function transform(options) {
8
- const now = Date.now();
9
- const configurations = await load(options);
10
- for (const config of configurations)
11
- await task(config);
12
- console.info(`Transformed in ${Date.now() - now}ms`);
8
+ const now = Date.now()
9
+ const configurations = await load(options)
10
+ for (const config of configurations) await task(config)
11
+ console.info(`Transformed in ${Date.now() - now}ms`)
13
12
  }
14
13
 
15
14
  async function task({ files, dest, cwd, type, space, addition }) {
16
- console.info('Transform task config:', { files, dest, cwd, type, space });
17
- const m = new Map();
15
+ console.info('Transform task config:', { files, dest, cwd, type, space })
16
+ const m = new Map()
18
17
  for (const file of files) {
19
- const dir = path.resolve(dest, path.dirname(file));
20
- for (const { name, data } of (await prepare(path.resolve(cwd, file)))) {
21
- if (name[0] === "#") continue;
22
- let sheet = name.split('#')[0];
23
- sheet = sheet.replace('<arr>', '');
24
- if (sheet[0] === '>') sheet = sheet.substring(1);
25
- const keys = sheet.split('.');
26
- sheet = path.resolve(dir, keys.shift());
27
- if (!m.has(sheet))
28
- m.set(sheet, new JobData());
29
- m.get(sheet).append({
30
- keys, data: parser(data)
31
- });
32
- }
18
+ const dir = path.resolve(dest, path.dirname(file))
19
+ const prepared = await prepare(path.resolve(cwd, file))
20
+ processPrepared(prepared, dir, m)
33
21
  }
34
22
  for (const [sheet, job] of m) {
35
- const data = job.result();
36
- if (addition)
37
- await dump(sheet, { data, ...addition }, type, space);
38
- else
39
- await dump(sheet, data, type, space);
23
+ const data = job.result()
24
+ if (addition) await dump(sheet, { data, ...addition }, type, space)
25
+ else await dump(sheet, data, type, space)
26
+ }
27
+ }
28
+
29
+ function processPrepared(prepared, dir, m) {
30
+ for (const { name, data } of prepared) {
31
+ if (name.startsWith('#')) continue
32
+ const { sheet, keys } = parseSheetAndKeys(name, dir)
33
+ if (!m.has(sheet)) m.set(sheet, new JobData())
34
+ m.get(sheet).append({ keys, data: parser(data) })
40
35
  }
41
36
  }
42
37
 
38
+ function parseSheetAndKeys(name, dir) {
39
+ let sheet = name.split('#')[0]
40
+ sheet = sheet.replace('<arr>', '')
41
+ if (sheet.startsWith('>')) sheet = sheet.substring(1)
42
+ const keys = sheet.split('.')
43
+ sheet = path.resolve(dir, keys.shift())
44
+ return { sheet, keys }
45
+ }
46
+
43
47
  class JobData {
44
48
  constructor(data) {
45
- if (data) this.append(data);
49
+ if (data) this.append(data)
46
50
  }
47
51
 
48
- #data = [];
52
+ #data = []
49
53
 
50
54
  append(data) {
51
- this.#data.push(data);
55
+ this.#data.push(data)
52
56
  }
53
57
 
54
58
  result() {
55
- if (!this.#data.length) return {};
56
- let result;
59
+ if (!this.#data.length) return {}
60
+ let result
57
61
  for (const { keys, data } of this.#data) {
58
62
  if (!keys.length) {
59
- result = this.#combine(result, data);
60
- continue;
63
+ result = this.#combine(result, data)
64
+ continue
61
65
  }
62
- if (!result) result = {};
63
- let r = result;
64
- let last = keys.pop();
66
+ if (!result) result = {}
67
+ let r = result
68
+ let last = keys.pop()
65
69
  for (const key of keys) {
66
- if (!r[key]) r[key] = {};
67
- r = r[key];
70
+ if (!r[key]) r[key] = {}
71
+ r = r[key]
68
72
  }
69
- r[last] = this.#combine(r[last], data);
73
+ r[last] = this.#combine(r[last], data)
70
74
  }
71
- return result;
75
+ return result
72
76
  }
73
77
 
74
78
  #combine(a, b) {
75
- if (a == null) return b;
76
- if (b == null) return a;
79
+ if (a == null) return b
80
+ if (b == null) return a
77
81
  if (Array.isArray(a) && Array.isArray(b)) {
78
- if (Array.isArray(b)) return a.concat(b);
79
- a.push(b);
80
- return a;
82
+ if (Array.isArray(b)) return a.concat(b)
83
+ a.push(b)
84
+ return a
81
85
  }
82
- if (Array.isArray(a))
83
- return this.#combine(a, Object.values(b));
84
- if (Array.isArray(b))
85
- return this.#combine(Object.values(a), b);
86
- const result = {};
87
- for (const key in a) result[key] = this.#combine(a[key], b[key]);
88
- for (const key in b) if (!result[key]) result[key] = b[key];
89
- return result;
86
+ if (Array.isArray(a)) return this.#combine(a, Object.values(b))
87
+ if (Array.isArray(b)) return this.#combine(Object.values(a), b)
88
+ const result = {}
89
+ for (const key in a) result[key] = this.#combine(a[key], b[key])
90
+ for (const key in b) if (!result[key]) result[key] = b[key]
91
+ return result
90
92
  }
91
- }
93
+ }