Skip to content

Commit 230673a

Browse files
authored
Version 0.2.9
2 parents 87590c3 + d49fd35 commit 230673a

4 files changed

Lines changed: 44 additions & 22 deletions

File tree

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "advanced-export",
3-
"version": "0.2.8",
3+
"version": "0.2.9",
44
"private": true,
55
"dependencies": {
66
"@devexpress/dx-react-core": "1.4.0",
@@ -11,6 +11,7 @@
1111
"@material-ui/core": "^3.9.2",
1212
"@material-ui/icons": "^3.0.2",
1313
"axios": "^0.18.0",
14+
"axios-retry": "^3.1.2",
1415
"babel-preset-es2015": "^6.24.1",
1516
"babel-preset-stage-2": "^6.24.1",
1617
"btoa": "^1.2.1",
@@ -48,7 +49,7 @@
4849
"manifest.webapp": {
4950
"name": "Advanced Export",
5051
"description": "Export App with recursive metadata fetching",
51-
"version": "0.2.8",
52+
"version": "0.2.9",
5253
"developer": {
5354
"name": "Alexis Rico",
5455
"url": "https://github.com/SferaDev"

src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function parseMetadataTypes(d2) {
6868
if (result.pager.hasNextPage()) result.pager.getNextPage().then(result => insertMetadata(model, result));
6969
};
7070
metadataTypes.forEach((model) => {
71-
d2.models[model].list({paging: false, fields: ['id', 'displayName']}).then(result => {
71+
d2.models[model].list({paging: false, fields: ['id', 'displayName', 'code']}).then(result => {
7272
insertMetadata(model, result);
7373
if (--parsedElements === 1) store.dispatch({type: actionTypes.LOADING, loading: false});
7474
}).catch(() => {

src/logic/extractor.js

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import _ from 'lodash';
22
import axios from "axios";
3+
import axiosRetry from 'axios-retry';
34
import * as traverse from "traverse";
45
import * as FileSaver from "file-saver";
56
import moment from "moment";
@@ -9,7 +10,10 @@ import * as actionTypes from "../actions/actionTypes";
910
import * as settingsAction from "../actions/settingsAction";
1011
import * as configuration from "./configuration";
1112

13+
axiosRetry(axios, { retries: 10 });
14+
1215
const timeout = ms => new Promise(res => setTimeout(res, ms));
16+
const mergeCustomizer = (obj, src) => _.isArray(obj) ? obj.concat(src) : src;
1317

1418
export let Extractor = (function () {
1519
let instance;
@@ -50,29 +54,32 @@ ExtractorClass.prototype.initialFetchAndRetrieve = async function (elements) {
5054
};
5155

5256
ExtractorClass.prototype.fetchAndRetrieve = async function (json) {
53-
for (const type in json) {
54-
if (Array.isArray(json[type])) {
55-
let elements = json[type].filter(e => e.id !== undefined && e.code !== 'default');
56-
for (const element of elements) {
57-
// Insert on the metadata map
58-
this.metadataMap.set(element.id, {...element, type} );
59-
60-
if (this.debug) console.log('fetchAndRetrieve: Parsing ' + element.id);
61-
62-
// Traverse references and call recursion
63-
let references = await this.recursiveParse(element, this.d2.models[type].name);
64-
let newJson = await this.parseElements(references);
65-
await this.fetchAndRetrieve(newJson);
66-
}
57+
const metadataTypes = _.keys(json).filter(type => _.isArray(json[type]));
58+
for (const metadataType of metadataTypes) {
59+
let references = [];
60+
let elements = json[metadataType].filter(e => e.id !== undefined);
61+
if (this.debug) console.log('fetchAndRetrieve: Parsing ' + elements.map(e => e.id));
62+
63+
for (const element of elements) {
64+
// Insert on the metadata map
65+
this.metadataMap.set(element.id, {metadataType, ...element} );
66+
67+
// Traverse and store references
68+
const innerReferences = await this.recursiveParse(element, this.d2.models[metadataType].name);
69+
references.push(...innerReferences);
6770
}
71+
72+
// Call recursion
73+
const newJson = await this.parseElements(references);
74+
await this.fetchAndRetrieve(newJson);
6875
}
6976
};
7077

7178
ExtractorClass.prototype.recursiveParse = async function (element, type) {
7279
let context = this;
7380
let references = [];
7481
traverse(element).forEach(function (item) {
75-
if (this.isLeaf && this.key === 'id' && item !== '') {
82+
if (this.isLeaf && this.key === 'id' && isValidUid(item)) {
7683
let parent = this.parent;
7784
while (parent.level > 1 && context.d2.models[parent.key] === undefined) parent = parent.parent;
7885
if (parent.key !== undefined) {
@@ -92,12 +99,13 @@ ExtractorClass.prototype.parseElements = async function (elementsArray) {
9299
let promises = [];
93100
for (let i = 0; i < elements.length; i += 100) {
94101
let requestUrl = this.d2.Api.getApi().baseUrl +
95-
'/metadata.json?fields=:all&filter=id:in:[' + elements.slice(i, i + 100).toString() + ']';
102+
'/metadata.json?fields=:all&defaults=EXCLUDE&filter=id:in:[' + elements.slice(i, i + 100).toString() + ']';
96103
if (this.debug) console.log('parseElements: ' + requestUrl);
97104
promises.push(axios.get(requestUrl));
98105
}
99106
let result = await Promise.all(promises);
100-
return _.merge({}, ...result.map(result => result.data));
107+
const data = result.map(result => result.data);
108+
return _.mergeWith({}, ...data, mergeCustomizer);
101109
};
102110

103111
ExtractorClass.prototype.handleCreatePackage = async function (elements, dependencies) {
@@ -121,7 +129,7 @@ ExtractorClass.prototype.createPackage = async function (elements, dependencies)
121129
for (const id of elementSet) {
122130
if (this.metadataMap.has(id)) {
123131
let element = this.metadataMap.get(id);
124-
let elementType = this.d2.models[element.type].plural;
132+
let elementType = this.d2.models[element.metadataType].plural;
125133
if (resultObject[elementType] === undefined) resultObject[elementType] = [];
126134
resultObject[elementType].push(cleanJson(element));
127135
} else if(this.debug) {
@@ -168,6 +176,7 @@ function cleanJson(json) {
168176
if (store.getState().settings[actionTypes.SETTINGS_USER_CLEAN_UP] === settingsAction.USER_CLEAN_UP_REMOVE_OPTION) {
169177
traverse(result).forEach(function (item) {
170178
if (this.key === 'user') this.update({});
179+
if (this.key === 'users') this.update([]);
171180
if (this.key === 'userGroupAccesses') this.update([]);
172181
if (this.key === 'userAccesses') this.update([]);
173182
if (this.key === 'lastUpdatedBy') this.update({});
@@ -179,4 +188,9 @@ function cleanJson(json) {
179188
});
180189
}
181190
return result;
191+
}
192+
193+
function isValidUid(code) {
194+
const CODE_PATTERN = /^[a-zA-Z][a-zA-Z0-9]{10}$/;
195+
return code !== null && CODE_PATTERN.test(code);
182196
}

yarn.lock

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,13 @@ aws4@^1.8.0:
617617
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
618618
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
619619

620+
axios-retry@^3.1.2:
621+
version "3.1.2"
622+
resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.1.2.tgz#4f4dcbefb0b434e22b72bd5e28a027d77b8a3458"
623+
integrity sha512-+X0mtJ3S0mmia1kTVi1eA3DAC+oWnT2A29g3CpkzcBPMT6vJm+hn/WiV9wPt/KXLHVmg5zev9mWqkPx7bHMovg==
624+
dependencies:
625+
is-retry-allowed "^1.1.0"
626+
620627
axios@^0.18.0:
621628
version "0.18.0"
622629
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
@@ -4756,7 +4763,7 @@ is-resolvable@^1.0.0:
47564763
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
47574764
integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==
47584765

4759-
is-retry-allowed@^1.0.0:
4766+
is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
47604767
version "1.1.0"
47614768
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34"
47624769
integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=

0 commit comments

Comments
 (0)