@rainlanguage/ui-components 0.0.1-alpha.16 → 0.0.1-alpha.18
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/dist/components/deployment/DeploymentSteps.svelte +19 -5
- package/dist/components/deployment/DepositInput.svelte +21 -5
- package/dist/components/deployment/FieldDefinitionInput.svelte +15 -3
- package/dist/services/index.d.ts +1 -1
- package/dist/services/index.js +1 -1
- package/dist/services/registry.d.ts +6 -0
- package/dist/services/registry.js +156 -0
- package/package.json +2 -2
- package/dist/components/deployment/TokenIOSection.svelte +0 -17
- package/dist/components/deployment/TokenIOSection.svelte.d.ts +0 -21
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>import { Alert } from "flowbite-svelte";
|
|
2
|
-
import
|
|
2
|
+
import TokenIOInput from "./TokenIOInput.svelte";
|
|
3
3
|
import DepositsSection from "./DepositsSection.svelte";
|
|
4
4
|
import ComposedRainlangModal from "./ComposedRainlangModal.svelte";
|
|
5
5
|
import FieldDefinitionsSection from "./FieldDefinitionsSection.svelte";
|
|
@@ -47,8 +47,16 @@ onMount(async () => {
|
|
|
47
47
|
});
|
|
48
48
|
function getAllFieldDefinitions() {
|
|
49
49
|
try {
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
const allFieldDefinitionsResult = gui.getAllFieldDefinitions(false);
|
|
51
|
+
if (allFieldDefinitionsResult.error) {
|
|
52
|
+
throw new Error(allFieldDefinitionsResult.error.msg);
|
|
53
|
+
}
|
|
54
|
+
allFieldDefinitionsWithoutDefaults = allFieldDefinitionsResult.value;
|
|
55
|
+
const allFieldDefinitionsWithDefaultsResult = gui.getAllFieldDefinitions(true);
|
|
56
|
+
if (allFieldDefinitionsWithDefaultsResult.error) {
|
|
57
|
+
throw new Error(allFieldDefinitionsWithDefaultsResult.error.msg);
|
|
58
|
+
}
|
|
59
|
+
allFieldDefinitionsWithDefaults = allFieldDefinitionsWithDefaultsResult.value;
|
|
52
60
|
} catch (e) {
|
|
53
61
|
DeploymentStepsError.catch(e, DeploymentStepsErrorCode.NO_FIELD_DEFINITIONS);
|
|
54
62
|
}
|
|
@@ -240,8 +248,14 @@ const areAllTokensSelected = async () => {
|
|
|
240
248
|
<DepositsSection bind:allDepositFields {gui} />
|
|
241
249
|
{/if}
|
|
242
250
|
|
|
243
|
-
{#if
|
|
244
|
-
|
|
251
|
+
{#if showAdvancedOptions}
|
|
252
|
+
{#each allTokenInputs as input, i}
|
|
253
|
+
<TokenIOInput {i} label="Input" vault={input} {gui} />
|
|
254
|
+
{/each}
|
|
255
|
+
|
|
256
|
+
{#each allTokenOutputs as output, i}
|
|
257
|
+
<TokenIOInput {i} label="Output" vault={output} {gui} />
|
|
258
|
+
{/each}
|
|
245
259
|
{/if}
|
|
246
260
|
|
|
247
261
|
{#if $deploymentStepsError}
|
|
@@ -15,12 +15,20 @@ let tokenInfo = null;
|
|
|
15
15
|
onMount(() => {
|
|
16
16
|
setCurrentDeposit();
|
|
17
17
|
});
|
|
18
|
-
const
|
|
18
|
+
const getCurrentDeposit = () => {
|
|
19
|
+
const deposits = gui.getDeposits();
|
|
20
|
+
if (deposits.error) {
|
|
21
|
+
throw new Error(deposits.error.msg);
|
|
22
|
+
}
|
|
23
|
+
return deposits.value.find((d) => d.token === deposit.token?.key);
|
|
24
|
+
};
|
|
25
|
+
const setCurrentDeposit = () => {
|
|
19
26
|
try {
|
|
20
|
-
currentDeposit =
|
|
27
|
+
currentDeposit = getCurrentDeposit();
|
|
21
28
|
inputValue = currentDeposit?.amount || "";
|
|
22
|
-
} catch {
|
|
29
|
+
} catch (e) {
|
|
23
30
|
currentDeposit = void 0;
|
|
31
|
+
error = e.message ? e.message : "Error setting current deposit.";
|
|
24
32
|
}
|
|
25
33
|
};
|
|
26
34
|
const getTokenSymbol = async () => {
|
|
@@ -41,7 +49,11 @@ function handlePresetClick(preset) {
|
|
|
41
49
|
inputValue = preset;
|
|
42
50
|
gui?.saveDeposit(deposit.token?.key, preset);
|
|
43
51
|
gui = gui;
|
|
44
|
-
|
|
52
|
+
try {
|
|
53
|
+
currentDeposit = getCurrentDeposit();
|
|
54
|
+
} catch (e) {
|
|
55
|
+
error = e.message ? e.message : "Error handling preset click.";
|
|
56
|
+
}
|
|
45
57
|
}
|
|
46
58
|
}
|
|
47
59
|
function handleInput(e) {
|
|
@@ -50,7 +62,11 @@ function handleInput(e) {
|
|
|
50
62
|
inputValue = e.currentTarget.value;
|
|
51
63
|
gui?.saveDeposit(deposit.token.key, e.currentTarget.value);
|
|
52
64
|
gui = gui;
|
|
53
|
-
|
|
65
|
+
try {
|
|
66
|
+
currentDeposit = getCurrentDeposit();
|
|
67
|
+
} catch (e2) {
|
|
68
|
+
error = e2.message ? e2.message : "Error handling input.";
|
|
69
|
+
}
|
|
54
70
|
}
|
|
55
71
|
}
|
|
56
72
|
}
|
|
@@ -11,7 +11,11 @@ let currentValue;
|
|
|
11
11
|
let inputValue = currentValue?.value ? currentValue?.value : fieldDefinition.default || null;
|
|
12
12
|
onMount(() => {
|
|
13
13
|
try {
|
|
14
|
-
|
|
14
|
+
const result = gui.getFieldValue(fieldDefinition.binding);
|
|
15
|
+
if (result.error) {
|
|
16
|
+
throw new Error(result.error.msg);
|
|
17
|
+
}
|
|
18
|
+
currentValue = result.value;
|
|
15
19
|
inputValue = currentValue?.value ? currentValue?.value : fieldDefinition.default || null;
|
|
16
20
|
} catch {
|
|
17
21
|
currentValue = void 0;
|
|
@@ -23,7 +27,11 @@ async function handlePresetClick(preset) {
|
|
|
23
27
|
isPreset: true,
|
|
24
28
|
value: preset.id
|
|
25
29
|
});
|
|
26
|
-
|
|
30
|
+
const result = gui.getFieldValue(fieldDefinition.binding);
|
|
31
|
+
if (result.error) {
|
|
32
|
+
throw new Error(result.error.msg);
|
|
33
|
+
}
|
|
34
|
+
currentValue = result.value;
|
|
27
35
|
}
|
|
28
36
|
async function handleCustomInputChange(value) {
|
|
29
37
|
inputValue = value;
|
|
@@ -31,7 +39,11 @@ async function handleCustomInputChange(value) {
|
|
|
31
39
|
isPreset: false,
|
|
32
40
|
value
|
|
33
41
|
});
|
|
34
|
-
|
|
42
|
+
const result = gui.getFieldValue(fieldDefinition.binding);
|
|
43
|
+
if (result.error) {
|
|
44
|
+
throw new Error(result.error.msg);
|
|
45
|
+
}
|
|
46
|
+
currentValue = result.value;
|
|
35
47
|
}
|
|
36
48
|
</script>
|
|
37
49
|
|
package/dist/services/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { fetchParseRegistry, fetchRegistryDotrains } from './registry';
|
|
1
|
+
export { fetchParseRegistry, fetchRegistryDotrains, validateStrategies } from './registry';
|
|
2
2
|
export type { RegistryDotrain, RegistryFile } from './registry';
|
package/dist/services/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { fetchParseRegistry, fetchRegistryDotrains } from './registry';
|
|
1
|
+
export { fetchParseRegistry, fetchRegistryDotrains, validateStrategies } from './registry';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { InvalidStrategyDetail, ValidStrategyDetail } from '../types/strategy';
|
|
1
2
|
export type RegistryFile = {
|
|
2
3
|
name: string;
|
|
3
4
|
url: string;
|
|
@@ -6,6 +7,10 @@ export type RegistryDotrain = {
|
|
|
6
7
|
name: string;
|
|
7
8
|
dotrain: string;
|
|
8
9
|
};
|
|
10
|
+
export interface StrategyValidationResult {
|
|
11
|
+
validStrategies: ValidStrategyDetail[];
|
|
12
|
+
invalidStrategies: InvalidStrategyDetail[];
|
|
13
|
+
}
|
|
9
14
|
/**
|
|
10
15
|
* Fetches and parses a file registry from a given URL.
|
|
11
16
|
* The registry is expected to be a text file where each line contains a file name and URL separated by a space.
|
|
@@ -23,3 +28,4 @@ export declare const fetchParseRegistry: (url: string) => Promise<{
|
|
|
23
28
|
url: string;
|
|
24
29
|
}[]>;
|
|
25
30
|
export declare const fetchRegistryDotrains: (url: string) => Promise<RegistryDotrain[]>;
|
|
31
|
+
export declare function validateStrategies(registryDotrains: RegistryDotrain[]): Promise<StrategyValidationResult>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DotrainOrderGui } from '@rainlanguage/orderbook/js_api';
|
|
1
2
|
/**
|
|
2
3
|
* Fetches and parses a file registry from a given URL.
|
|
3
4
|
* The registry is expected to be a text file where each line contains a file name and URL separated by a space.
|
|
@@ -52,6 +53,40 @@ export const fetchRegistryDotrains = async (url) => {
|
|
|
52
53
|
}));
|
|
53
54
|
return dotrains;
|
|
54
55
|
};
|
|
56
|
+
export async function validateStrategies(registryDotrains) {
|
|
57
|
+
const strategiesPromises = registryDotrains.map(async (registryDotrain) => {
|
|
58
|
+
try {
|
|
59
|
+
const result = await DotrainOrderGui.getStrategyDetails(registryDotrain.dotrain);
|
|
60
|
+
if (result.error) {
|
|
61
|
+
throw new Error(result.error.msg);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
valid: true,
|
|
65
|
+
data: {
|
|
66
|
+
...registryDotrain,
|
|
67
|
+
details: result.value
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
return {
|
|
73
|
+
valid: false,
|
|
74
|
+
data: {
|
|
75
|
+
name: registryDotrain.name,
|
|
76
|
+
error: error instanceof Error ? error.message : String(error)
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
const strategiesResults = await Promise.all(strategiesPromises);
|
|
82
|
+
const validStrategies = strategiesResults
|
|
83
|
+
.filter((result) => result.valid)
|
|
84
|
+
.map((result) => result.data);
|
|
85
|
+
const invalidStrategies = strategiesResults
|
|
86
|
+
.filter((result) => !result.valid)
|
|
87
|
+
.map((result) => result.data);
|
|
88
|
+
return { validStrategies, invalidStrategies };
|
|
89
|
+
}
|
|
55
90
|
if (import.meta.vitest) {
|
|
56
91
|
const { describe, it, expect, vi } = import.meta.vitest;
|
|
57
92
|
describe('getFileRegistry', () => {
|
|
@@ -130,4 +165,125 @@ file2.rain https://example.com/file2.rain`;
|
|
|
130
165
|
await expect(fetchRegistryDotrains('https://example.com/registry')).rejects.toThrow('Error fetching dotrain for file1.rain: Network error');
|
|
131
166
|
});
|
|
132
167
|
});
|
|
168
|
+
describe('validateStrategies', async () => {
|
|
169
|
+
// Mock the DotrainOrderGui dependency
|
|
170
|
+
vi.mock('@rainlanguage/orderbook/js_api', () => ({
|
|
171
|
+
DotrainOrderGui: {
|
|
172
|
+
getStrategyDetails: vi.fn()
|
|
173
|
+
}
|
|
174
|
+
}));
|
|
175
|
+
// Import DotrainOrderGui after mocking
|
|
176
|
+
const { DotrainOrderGui } = await import('@rainlanguage/orderbook/js_api');
|
|
177
|
+
beforeEach(() => {
|
|
178
|
+
vi.resetAllMocks();
|
|
179
|
+
});
|
|
180
|
+
it('should validate strategies and categorize them properly', async () => {
|
|
181
|
+
// Input data
|
|
182
|
+
const registryDotrains = [
|
|
183
|
+
{ name: 'valid.rain', dotrain: 'valid dotrain content' },
|
|
184
|
+
{ name: 'invalid.rain', dotrain: 'invalid dotrain content' },
|
|
185
|
+
{ name: 'another-valid.rain', dotrain: 'another valid content' }
|
|
186
|
+
];
|
|
187
|
+
// Set up mock responses for the DotrainOrderGui
|
|
188
|
+
DotrainOrderGui.getStrategyDetails
|
|
189
|
+
.mockResolvedValueOnce({
|
|
190
|
+
value: { name: 'Valid Strategy', description: 'A valid strategy' },
|
|
191
|
+
error: null
|
|
192
|
+
})
|
|
193
|
+
.mockResolvedValueOnce({
|
|
194
|
+
error: { msg: 'Invalid syntax' },
|
|
195
|
+
value: null
|
|
196
|
+
})
|
|
197
|
+
.mockResolvedValueOnce({
|
|
198
|
+
value: { name: 'Another Valid', description: 'Another valid strategy' },
|
|
199
|
+
error: null
|
|
200
|
+
});
|
|
201
|
+
// Call the function with our test data
|
|
202
|
+
const result = await validateStrategies(registryDotrains);
|
|
203
|
+
// Verify DotrainOrderGui was called correctly
|
|
204
|
+
expect(DotrainOrderGui.getStrategyDetails).toHaveBeenCalledTimes(3);
|
|
205
|
+
expect(DotrainOrderGui.getStrategyDetails).toHaveBeenCalledWith('valid dotrain content');
|
|
206
|
+
expect(DotrainOrderGui.getStrategyDetails).toHaveBeenCalledWith('invalid dotrain content');
|
|
207
|
+
expect(DotrainOrderGui.getStrategyDetails).toHaveBeenCalledWith('another valid content');
|
|
208
|
+
// Verify the valid strategies are processed correctly
|
|
209
|
+
expect(result.validStrategies).toHaveLength(2);
|
|
210
|
+
expect(result.validStrategies[0].name).toBe('valid.rain');
|
|
211
|
+
expect(result.validStrategies[0].dotrain).toBe('valid dotrain content');
|
|
212
|
+
expect(result.validStrategies[0].details).toEqual({
|
|
213
|
+
name: 'Valid Strategy',
|
|
214
|
+
description: 'A valid strategy'
|
|
215
|
+
});
|
|
216
|
+
// Verify the invalid strategies are processed correctly
|
|
217
|
+
expect(result.invalidStrategies).toHaveLength(1);
|
|
218
|
+
expect(result.invalidStrategies[0].name).toBe('invalid.rain');
|
|
219
|
+
expect(result.invalidStrategies[0].error).toBe('Invalid syntax');
|
|
220
|
+
});
|
|
221
|
+
it('should handle exceptions thrown during strategy validation', async () => {
|
|
222
|
+
// Input data
|
|
223
|
+
const registryDotrains = [{ name: 'error.rain', dotrain: 'will throw error' }];
|
|
224
|
+
// Mock the DotrainOrderGui to throw an exception
|
|
225
|
+
DotrainOrderGui.getStrategyDetails.mockRejectedValueOnce(new Error('Unexpected parsing error'));
|
|
226
|
+
// Call the function
|
|
227
|
+
const result = await validateStrategies(registryDotrains);
|
|
228
|
+
// Verify results
|
|
229
|
+
expect(result.validStrategies).toHaveLength(0);
|
|
230
|
+
expect(result.invalidStrategies).toHaveLength(1);
|
|
231
|
+
expect(result.invalidStrategies[0].name).toBe('error.rain');
|
|
232
|
+
expect(result.invalidStrategies[0].error).toBe('Unexpected parsing error');
|
|
233
|
+
});
|
|
234
|
+
it('should handle non-Error objects being thrown', async () => {
|
|
235
|
+
// Input data
|
|
236
|
+
const registryDotrains = [{ name: 'string-error.rain', dotrain: 'will throw string' }];
|
|
237
|
+
// Mock the DotrainOrderGui to throw a string instead of an Error
|
|
238
|
+
DotrainOrderGui.getStrategyDetails.mockRejectedValueOnce('String error message');
|
|
239
|
+
// Call the function
|
|
240
|
+
const result = await validateStrategies(registryDotrains);
|
|
241
|
+
// Verify results
|
|
242
|
+
expect(result.validStrategies).toHaveLength(0);
|
|
243
|
+
expect(result.invalidStrategies).toHaveLength(1);
|
|
244
|
+
expect(result.invalidStrategies[0].name).toBe('string-error.rain');
|
|
245
|
+
expect(result.invalidStrategies[0].error).toBe('String error message');
|
|
246
|
+
});
|
|
247
|
+
it('should process an empty array of strategies', async () => {
|
|
248
|
+
const result = await validateStrategies([]);
|
|
249
|
+
expect(result.validStrategies).toEqual([]);
|
|
250
|
+
expect(result.invalidStrategies).toEqual([]);
|
|
251
|
+
expect(DotrainOrderGui.getStrategyDetails).not.toHaveBeenCalled();
|
|
252
|
+
});
|
|
253
|
+
it('should handle mixed validation results correctly', async () => {
|
|
254
|
+
// Create a mix of scenarios
|
|
255
|
+
const registryDotrains = [
|
|
256
|
+
{ name: 'valid1.rain', dotrain: 'valid content 1' },
|
|
257
|
+
{ name: 'error.rain', dotrain: 'will throw error' },
|
|
258
|
+
{ name: 'valid2.rain', dotrain: 'valid content 2' },
|
|
259
|
+
{ name: 'invalid.rain', dotrain: 'invalid content' }
|
|
260
|
+
];
|
|
261
|
+
// Set up mock responses
|
|
262
|
+
DotrainOrderGui.getStrategyDetails
|
|
263
|
+
.mockResolvedValueOnce({
|
|
264
|
+
value: { strategyName: 'Strategy 1', description: 'Description 1' },
|
|
265
|
+
error: null
|
|
266
|
+
})
|
|
267
|
+
.mockRejectedValueOnce(new Error('Processing error'))
|
|
268
|
+
.mockResolvedValueOnce({
|
|
269
|
+
value: { strategyName: 'Strategy 2', description: 'Description 2' },
|
|
270
|
+
error: null
|
|
271
|
+
})
|
|
272
|
+
.mockResolvedValueOnce({
|
|
273
|
+
error: { msg: 'Validation failed' },
|
|
274
|
+
value: null
|
|
275
|
+
});
|
|
276
|
+
// Call the function
|
|
277
|
+
const result = await validateStrategies(registryDotrains);
|
|
278
|
+
// Verify results
|
|
279
|
+
expect(result.validStrategies).toHaveLength(2);
|
|
280
|
+
expect(result.validStrategies[0].name).toBe('valid1.rain');
|
|
281
|
+
expect(result.validStrategies[1].name).toBe('valid2.rain');
|
|
282
|
+
expect(result.invalidStrategies).toHaveLength(2);
|
|
283
|
+
expect(result.invalidStrategies[0].name).toBe('error.rain');
|
|
284
|
+
expect(result.invalidStrategies[0].error).toBe('Processing error');
|
|
285
|
+
expect(result.invalidStrategies[1].name).toBe('invalid.rain');
|
|
286
|
+
expect(result.invalidStrategies[1].error).toBe('Validation failed');
|
|
287
|
+
});
|
|
288
|
+
});
|
|
133
289
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rainlanguage/ui-components",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.18",
|
|
4
4
|
"description": "A component library for building Svelte applications to be used with Raindex.",
|
|
5
5
|
"license": "LicenseRef-DCL-1.0",
|
|
6
6
|
"author": "Rain Open Source Software Ltd",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@fontsource/dm-sans": "^5.0.18",
|
|
54
54
|
"@imask/svelte": "^7.3.0",
|
|
55
55
|
"@observablehq/plot": "^0.6.13",
|
|
56
|
-
"@rainlanguage/orderbook": "0.0.1-alpha.
|
|
56
|
+
"@rainlanguage/orderbook": "0.0.1-alpha.18",
|
|
57
57
|
"@reown/appkit": "^1.6.4",
|
|
58
58
|
"@reown/appkit-adapter-wagmi": "^1.6.4",
|
|
59
59
|
"@sentry/sveltekit": "^7.107.0",
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
<script>import TokenIOInput from "./TokenIOInput.svelte";
|
|
2
|
-
export let allTokenInputs = [];
|
|
3
|
-
export let allTokenOutputs = [];
|
|
4
|
-
export let gui;
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
{#if allTokenInputs.length > 0}
|
|
8
|
-
{#each allTokenInputs as input, i}
|
|
9
|
-
<TokenIOInput {i} label="Input" vault={input} {gui} />
|
|
10
|
-
{/each}
|
|
11
|
-
{/if}
|
|
12
|
-
|
|
13
|
-
{#if allTokenOutputs.length > 0}
|
|
14
|
-
{#each allTokenOutputs as output, i}
|
|
15
|
-
<TokenIOInput {i} label="Output" vault={output} {gui} />
|
|
16
|
-
{/each}
|
|
17
|
-
{/if}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { SvelteComponent } from "svelte";
|
|
2
|
-
import type { DotrainOrderGui, OrderIOCfg } from '@rainlanguage/orderbook/js_api';
|
|
3
|
-
declare const __propDef: {
|
|
4
|
-
props: {
|
|
5
|
-
allTokenInputs?: OrderIOCfg[];
|
|
6
|
-
allTokenOutputs?: OrderIOCfg[];
|
|
7
|
-
gui: DotrainOrderGui;
|
|
8
|
-
};
|
|
9
|
-
events: {
|
|
10
|
-
[evt: string]: CustomEvent<any>;
|
|
11
|
-
};
|
|
12
|
-
slots: {};
|
|
13
|
-
exports?: {} | undefined;
|
|
14
|
-
bindings?: string | undefined;
|
|
15
|
-
};
|
|
16
|
-
export type TokenIoSectionProps = typeof __propDef.props;
|
|
17
|
-
export type TokenIoSectionEvents = typeof __propDef.events;
|
|
18
|
-
export type TokenIoSectionSlots = typeof __propDef.slots;
|
|
19
|
-
export default class TokenIoSection extends SvelteComponent<TokenIoSectionProps, TokenIoSectionEvents, TokenIoSectionSlots> {
|
|
20
|
-
}
|
|
21
|
-
export {};
|