@applitools/eyes-cypress 3.23.9 → 3.24.0-beta.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/CHANGELOG.md +2187 -2185
- package/LICENSE +25 -25
- package/README.md +778 -769
- package/commands.js +2 -2
- package/dist/browser/spec-driver.js +104 -0
- package/dist/plugin/handler.js +55 -0
- package/eyes-index.d.ts +34 -34
- package/index.js +2 -2
- package/package.json +97 -81
- package/src/browser/commands.js +167 -147
- package/src/browser/eyesCheckMapping.js +71 -0
- package/src/browser/eyesOpenMapping.js +34 -0
- package/src/browser/makeSend.js +18 -22
- package/src/browser/refer.js +57 -0
- package/src/browser/sendRequest.js +16 -16
- package/src/browser/socket.js +143 -0
- package/src/browser/socketCommands.js +81 -0
- package/src/browser/spec-driver.ts +109 -0
- package/src/pem/server.cert +22 -22
- package/src/pem/server.key +27 -27
- package/src/plugin/concurrencyMsg.js +8 -8
- package/src/plugin/config.js +54 -53
- package/src/plugin/defaultPort.js +1 -1
- package/src/plugin/errorDigest.js +96 -96
- package/src/plugin/getErrorsAndDiffs.js +34 -34
- package/src/plugin/handleTestResults.js +39 -0
- package/src/plugin/handler.ts +58 -0
- package/src/plugin/hooks.js +49 -42
- package/src/plugin/isGlobalHooksSupported.js +13 -13
- package/src/plugin/pluginExport.js +60 -57
- package/src/plugin/server.js +98 -46
- package/src/plugin/startPlugin.js +13 -34
- package/src/plugin/webSocket.js +130 -0
- package/src/setup/addEyesCommands.js +24 -24
- package/src/setup/addEyesCypressPlugin.js +15 -15
- package/src/setup/getCypressConfig.js +16 -16
- package/src/setup/getFilePath.js +22 -22
- package/src/setup/handleCommands.js +23 -23
- package/src/setup/handlePlugin.js +23 -23
- package/src/setup/handleTypeScript.js +21 -21
- package/src/setup/isCommandsDefined.js +7 -7
- package/src/setup/isPluginDefined.js +7 -7
- package/test/fixtures/testAppCopies/.gitignore +1 -1
- package/bin/eyes-setup.js +0 -21
- package/src/browser/eyesCheckWindow.js +0 -132
- package/src/browser/getAllBlobs.js +0 -14
- package/src/browser/getBrowserInfo.js +0 -39
- package/src/browser/makeHandleCypressViewport.js +0 -22
- package/src/browser/poll.js +0 -25
- package/src/plugin/app.js +0 -42
- package/src/plugin/handlers.js +0 -205
- package/src/plugin/makeHandleBatchResultsFile.js +0 -17
- package/src/plugin/pollingHandler.js +0 -46
- package/src/plugin/processCloseAndAbort.js +0 -33
- package/src/plugin/runningTests.js +0 -27
- package/src/plugin/waitForBatch.js +0 -33
package/src/browser/commands.js
CHANGED
|
@@ -1,147 +1,167 @@
|
|
|
1
|
-
/* global Cypress,cy,
|
|
2
|
-
'use strict';
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
1
|
+
/* global Cypress,cy,after,navigator */
|
|
2
|
+
'use strict';
|
|
3
|
+
const spec = require('../../dist/browser/spec-driver');
|
|
4
|
+
const Refer = require('./refer');
|
|
5
|
+
const Socket = require('./socket');
|
|
6
|
+
const {socketCommands} = require('./socketCommands');
|
|
7
|
+
const {eyesOpenMapValues} = require('./eyesOpenMapping');
|
|
8
|
+
const {eyesCheckMapValues} = require('./eyesCheckMapping');
|
|
9
|
+
|
|
10
|
+
const refer = new Refer(value => {
|
|
11
|
+
if (!value || !value.constructor || !value.constructor.name) return false;
|
|
12
|
+
const name = value.constructor.name;
|
|
13
|
+
return name === 'HTMLDocument' || name === 'Window' || value.ownerDocument;
|
|
14
|
+
});
|
|
15
|
+
const socket = new Socket();
|
|
16
|
+
const throwErr = Cypress.config('failCypressOnDiff');
|
|
17
|
+
socketCommands(socket, refer);
|
|
18
|
+
let connectedToUniversal = false;
|
|
19
|
+
|
|
20
|
+
let manager,
|
|
21
|
+
eyes,
|
|
22
|
+
closePromiseArr = [];
|
|
23
|
+
|
|
24
|
+
function getGlobalConfigProperty(prop) {
|
|
25
|
+
const property = Cypress.config(prop);
|
|
26
|
+
const shouldParse = ['eyesBrowser', 'eyesLayoutBreakpoints'];
|
|
27
|
+
return property ? (shouldParse.includes(prop) ? JSON.parse(property) : property) : undefined;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const shouldUseBrowserHooks =
|
|
31
|
+
!getGlobalConfigProperty('eyesIsDisabled') &&
|
|
32
|
+
(getGlobalConfigProperty('isInteractive') ||
|
|
33
|
+
!getGlobalConfigProperty('eyesIsGlobalHooksSupported'));
|
|
34
|
+
|
|
35
|
+
Cypress.Commands.add('eyesGetAllTestResults', async () => {
|
|
36
|
+
if (isCurrentTestDisabled) {
|
|
37
|
+
isCurrentTestDisabled = false;
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
await Promise.all(closePromiseArr);
|
|
41
|
+
return socket.request('EyesManager.closeAllEyes', {manager, throwErr});
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (shouldUseBrowserHooks) {
|
|
45
|
+
after(() => {
|
|
46
|
+
if (!manager) return;
|
|
47
|
+
return cy.then({timeout: 86400000}, async () => {
|
|
48
|
+
if (isCurrentTestDisabled) {
|
|
49
|
+
isCurrentTestDisabled = false;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const resultConfig = {
|
|
53
|
+
showLogs: Cypress.config('appliConfFile').showLogs,
|
|
54
|
+
eyesFailCypressOnDiff: Cypress.config('eyesFailCypressOnDiff'),
|
|
55
|
+
isTextTerminal: Cypress.config('isTextTerminal'),
|
|
56
|
+
tapDirPath: Cypress.config('appliConfFile').tapDirPath,
|
|
57
|
+
tapFileName: Cypress.config('appliConfFile').tapFileName,
|
|
58
|
+
};
|
|
59
|
+
await Promise.all(closePromiseArr);
|
|
60
|
+
const testResults = await socket.request('EyesManager.closeAllEyes', {manager, throwErr});
|
|
61
|
+
const message = await socket.request('Test.printTestResults', {testResults, resultConfig});
|
|
62
|
+
if (
|
|
63
|
+
!!getGlobalConfigProperty('eyesFailCypressOnDiff') &&
|
|
64
|
+
message &&
|
|
65
|
+
message.includes('Eyes-Cypress detected diffs or errors')
|
|
66
|
+
) {
|
|
67
|
+
throw new Error(message);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let isCurrentTestDisabled;
|
|
74
|
+
|
|
75
|
+
Cypress.Commands.add('eyesOpen', function(args = {}) {
|
|
76
|
+
Cypress.log({name: 'Eyes: open'});
|
|
77
|
+
Cypress.config('eyesOpenArgs', args);
|
|
78
|
+
const {title: testName} = this.currentTest || this.test || Cypress.currentTest;
|
|
79
|
+
|
|
80
|
+
if (Cypress.config('eyesIsDisabled') && args.isDisabled === false) {
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Eyes-Cypress is disabled by an env variable or in the applitools.config.js file, but the "${testName}" test was passed isDisabled:false. A single test cannot be enabled when Eyes.Cypress is disabled through the global configuration. Please remove "isDisabled:false" from cy.eyesOpen() for this test, or enable Eyes.Cypress in the global configuration, either by unsetting the APPLITOOLS_IS_DISABLED env var, or by deleting 'isDisabled' from the applitools.config.js file.`,
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
isCurrentTestDisabled = getGlobalConfigProperty('eyesIsDisabled') || args.isDisabled;
|
|
86
|
+
if (isCurrentTestDisabled) return;
|
|
87
|
+
|
|
88
|
+
return cy.then({timeout: 86400000}, async () => {
|
|
89
|
+
setRootContext();
|
|
90
|
+
const driver = refer.ref(cy.state('window').document);
|
|
91
|
+
|
|
92
|
+
if (!connectedToUniversal) {
|
|
93
|
+
socket.connect(`ws://localhost:${Cypress.config('eyesPort')}/eyes`);
|
|
94
|
+
connectedToUniversal = true;
|
|
95
|
+
socket.emit('Core.makeSDK', {
|
|
96
|
+
name: 'eyes.cypress',
|
|
97
|
+
version: require('../../package.json').version,
|
|
98
|
+
commands: Object.keys(spec).concat(['isSelector', 'isDriver', 'isElement']), // TODO fix spec.isSelector and spec.isDriver and spec.isElement in driver utils
|
|
99
|
+
cwd: process.cwd(),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
manager =
|
|
103
|
+
manager ||
|
|
104
|
+
(await socket.request(
|
|
105
|
+
'Core.makeManager',
|
|
106
|
+
Object.assign(
|
|
107
|
+
{},
|
|
108
|
+
{concurrency: Cypress.config('eyesTestConcurrency')},
|
|
109
|
+
{legacy: false, type: 'vg'},
|
|
110
|
+
),
|
|
111
|
+
));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const appliConfFile = Cypress.config('appliConfFile');
|
|
115
|
+
const config = eyesOpenMapValues({
|
|
116
|
+
args,
|
|
117
|
+
appliConfFile,
|
|
118
|
+
testName,
|
|
119
|
+
shouldUseBrowserHooks,
|
|
120
|
+
defaultBrowser: {
|
|
121
|
+
width: Cypress.config('viewportWidth'),
|
|
122
|
+
height: Cypress.config('viewportHeight'),
|
|
123
|
+
name: 'chrome',
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
eyes = await socket.request('EyesManager.openEyes', {manager, driver, config});
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
Cypress.Commands.add('eyesCheckWindow', args =>
|
|
131
|
+
cy.then({timeout: 86400000}, () => {
|
|
132
|
+
if (isCurrentTestDisabled) return;
|
|
133
|
+
|
|
134
|
+
setRootContext();
|
|
135
|
+
|
|
136
|
+
Cypress.log({name: 'Eyes: check window'});
|
|
137
|
+
|
|
138
|
+
const checkSettings = eyesCheckMapValues({args});
|
|
139
|
+
|
|
140
|
+
return socket.request('Eyes.check', {
|
|
141
|
+
eyes,
|
|
142
|
+
settings: checkSettings,
|
|
143
|
+
});
|
|
144
|
+
}),
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
Cypress.Commands.add('eyesClose', () => {
|
|
148
|
+
return cy.then({timeout: 86400000}, () => {
|
|
149
|
+
if (isCurrentTestDisabled) return;
|
|
150
|
+
|
|
151
|
+
Cypress.log({name: 'Eyes: close'});
|
|
152
|
+
if (isCurrentTestDisabled) {
|
|
153
|
+
isCurrentTestDisabled = false;
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// intentionally not returning the result in order to not wait on the close promise
|
|
158
|
+
const p = socket.request('Eyes.close', {eyes, throwErr: false}).catch(err => {
|
|
159
|
+
console.log('Error in cy.eyesClose', err);
|
|
160
|
+
});
|
|
161
|
+
closePromiseArr.push(p);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
function setRootContext() {
|
|
166
|
+
cy.state('window').document['applitools-marker'] = 'root-context';
|
|
167
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
function eyesCheckMapValues({args}) {
|
|
2
|
+
return toCheckWindowConfiguration(args);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
function toCheckWindowConfiguration(config = {}) {
|
|
6
|
+
const mappedValues = [
|
|
7
|
+
'tag',
|
|
8
|
+
'hooks',
|
|
9
|
+
'ignore',
|
|
10
|
+
'floating',
|
|
11
|
+
'strict',
|
|
12
|
+
'layout',
|
|
13
|
+
'content',
|
|
14
|
+
'accessibility',
|
|
15
|
+
'region',
|
|
16
|
+
'selector',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
let regionSettings = {};
|
|
20
|
+
let shadowDomSettings = {};
|
|
21
|
+
const checkSettings = {
|
|
22
|
+
name: config.tag,
|
|
23
|
+
scriptHooks: config.hooks,
|
|
24
|
+
ignoreRegions: config.ignore,
|
|
25
|
+
floatingRegions: config.floating,
|
|
26
|
+
strictRegions: config.strict,
|
|
27
|
+
layoutRegions: config.layout,
|
|
28
|
+
contentRegions: config.content,
|
|
29
|
+
accessibilityRegions: config.accessibility,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (config.target === 'region') {
|
|
33
|
+
if (!Array.isArray(config.selector)) {
|
|
34
|
+
if (!config.hasOwnProperty('selector')) {
|
|
35
|
+
regionSettings = {
|
|
36
|
+
region: config.region,
|
|
37
|
+
};
|
|
38
|
+
} else {
|
|
39
|
+
regionSettings = {
|
|
40
|
+
region: config.selector,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
const selectors = config.selector;
|
|
45
|
+
for (let i = selectors.length - 1; i > -1; i--) {
|
|
46
|
+
if (i === selectors.length - 1) {
|
|
47
|
+
shadowDomSettings['shadow'] = selectors[i].selector;
|
|
48
|
+
} else {
|
|
49
|
+
const prevSettings = Object.assign({}, shadowDomSettings);
|
|
50
|
+
shadowDomSettings['selector'] = selectors[i].selector;
|
|
51
|
+
if (!prevSettings.hasOwnProperty('selector')) {
|
|
52
|
+
shadowDomSettings['shadow'] = prevSettings.shadow;
|
|
53
|
+
} else {
|
|
54
|
+
shadowDomSettings['shadow'] = prevSettings;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
regionSettings = {region: shadowDomSettings};
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
for (const val of mappedValues) {
|
|
63
|
+
if (config.hasOwnProperty(val)) {
|
|
64
|
+
delete config[val];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return Object.assign({}, checkSettings, regionSettings, config);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
module.exports = {eyesCheckMapValues};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
function eyesOpenMapValues({args, appliConfFile, testName, shouldUseBrowserHooks}) {
|
|
2
|
+
let browsersInfo = args.browser || appliConfFile.browser;
|
|
3
|
+
|
|
4
|
+
if (browsersInfo) {
|
|
5
|
+
if (Array.isArray(browsersInfo)) {
|
|
6
|
+
browsersInfo.forEach(fillDefaultBrowserName);
|
|
7
|
+
} else {
|
|
8
|
+
fillDefaultBrowserName(browsersInfo);
|
|
9
|
+
browsersInfo = [browsersInfo];
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const mappedArgs = {
|
|
14
|
+
...args,
|
|
15
|
+
browsersInfo,
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
delete mappedArgs.browser;
|
|
19
|
+
delete appliConfFile.browser;
|
|
20
|
+
|
|
21
|
+
return Object.assign(
|
|
22
|
+
{testName, dontCloseBatches: !shouldUseBrowserHooks},
|
|
23
|
+
appliConfFile,
|
|
24
|
+
mappedArgs,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function fillDefaultBrowserName(browser) {
|
|
29
|
+
if (!browser.name && !browser.iosDeviceInfo && !browser.chromeEmulationInfo) {
|
|
30
|
+
browser.name = 'chrome';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
module.exports = {eyesOpenMapValues};
|
package/src/browser/makeSend.js
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
return throat(CONCURRENCY_LIMITATION, send);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
module.exports = makeSend;
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function makeSend(port, fetch) {
|
|
4
|
+
return function send({
|
|
5
|
+
command,
|
|
6
|
+
data,
|
|
7
|
+
method = 'POST',
|
|
8
|
+
headers = {'Content-Type': 'application/json'},
|
|
9
|
+
}) {
|
|
10
|
+
return fetch(`https://localhost:${port}/eyes/${command}`, {
|
|
11
|
+
method,
|
|
12
|
+
body: headers['Content-Type'] === 'application/json' ? JSON.stringify(data) : data,
|
|
13
|
+
headers,
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = makeSend;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const uuid = require('uuid');
|
|
2
|
+
|
|
3
|
+
const REF_ID = 'applitools-ref-id';
|
|
4
|
+
class Refer {
|
|
5
|
+
constructor(check) {
|
|
6
|
+
this.store = new Map();
|
|
7
|
+
this.relation = new Map();
|
|
8
|
+
this.check = check;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
isRef(ref) {
|
|
12
|
+
return Boolean(ref && ref[REF_ID]);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
ref(value, parentRef) {
|
|
16
|
+
if (this.check(value)) {
|
|
17
|
+
const ref = uuid.v4();
|
|
18
|
+
this.store.set(ref, value);
|
|
19
|
+
if (parentRef) {
|
|
20
|
+
let childRefs = this.relation.get(parentRef[REF_ID]);
|
|
21
|
+
if (!childRefs) {
|
|
22
|
+
childRefs = new Set();
|
|
23
|
+
this.relation.set(parentRef[REF_ID], childRefs);
|
|
24
|
+
}
|
|
25
|
+
childRefs.add({[REF_ID]: ref});
|
|
26
|
+
}
|
|
27
|
+
return {[REF_ID]: ref};
|
|
28
|
+
} else if (Array.isArray(value)) {
|
|
29
|
+
return value.map(value => this.ref(value, parentRef));
|
|
30
|
+
} else if (typeof value === 'object' && value !== null) {
|
|
31
|
+
return Object.entries(value).reduce((obj, [key, value]) => {
|
|
32
|
+
return Object.assign(obj, {[key]: this.ref(value, parentRef)});
|
|
33
|
+
}, {});
|
|
34
|
+
} else {
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
deref(ref) {
|
|
40
|
+
if (this.isRef(ref)) {
|
|
41
|
+
return this.store.get(ref[REF_ID]);
|
|
42
|
+
} else {
|
|
43
|
+
return ref;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
destroy(ref) {
|
|
48
|
+
if (!this.isRef(ref)) return;
|
|
49
|
+
const childRefs = this.relation.get(ref[REF_ID]);
|
|
50
|
+
if (childRefs) {
|
|
51
|
+
childRefs.forEach(childRef => this.destroy(childRef));
|
|
52
|
+
}
|
|
53
|
+
this.store.delete(ref[REF_ID]);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = Refer;
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
function makeSendRequest(send) {
|
|
4
|
-
return function sendRequest(args) {
|
|
5
|
-
return send(args)
|
|
6
|
-
.then(resp => resp.json())
|
|
7
|
-
.then(body => {
|
|
8
|
-
if (!body.success) {
|
|
9
|
-
throw new Error(body.error);
|
|
10
|
-
}
|
|
11
|
-
return body.result;
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
module.exports = makeSendRequest;
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function makeSendRequest(send) {
|
|
4
|
+
return function sendRequest(args) {
|
|
5
|
+
return send(args)
|
|
6
|
+
.then(resp => resp.json())
|
|
7
|
+
.then(body => {
|
|
8
|
+
if (!body.success) {
|
|
9
|
+
throw new Error(body.error);
|
|
10
|
+
}
|
|
11
|
+
return body.result;
|
|
12
|
+
});
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = makeSendRequest;
|