Skip to content
This repository was archived by the owner on Jul 10, 2025. It is now read-only.

Commit 7fff3b1

Browse files
author
Akim
authored
feat(aqua-compiler)!: JS-client aqua wrapper [fixes DXJ-461] (#347)
* Implement wrapper compiler * Small formatting fixes * Add simple test * Package rename * Add new package to release-please * Misc fixes * Fix object type * Update package name * Revert "Fix object type" This reverts commit 572f1e1. * Set string type * Make generator func async * Cleanup * Code refactoring * Fix PR comments * Fix file path * Refactor generate module * Change header text * Rename package * Move some deps to devDeps * Add a comment * New index file * Move aqua-api to devDeps * Add desc * Fix header * Change return type * Fix all tests * Fix func * Fix index file * Add file entry * Change package name (again) * Snapshot testing * Add func name * Fix return type * Fix nox images * Update aurora image * Conditional services * Use function instead classes * Refactor header * Import same type * Make named export * Type generator array
1 parent 580aff0 commit 7fff3b1

File tree

22 files changed

+2604
-42
lines changed

22 files changed

+2604
-42
lines changed

.github/e2e/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ networks:
77

88
services:
99
aurora:
10-
image: docker.fluence.dev/aurora:main-9e7523f-4-1
10+
image: docker.fluence.dev/aurora:0.2.11
1111
ports:
1212
- 8545:8545
1313
networks:

.github/release-please/config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
],
1010
"packages": {
1111
"packages/core/js-client": {},
12-
"packages/core/marine-worker": {}
12+
"packages/core/marine-worker": {},
13+
"packages/core/aqua-to-js": {}
1314
}
1415
}
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
22
"packages/core/js-client": "0.1.6",
3-
"packages/core/marine-worker": "0.3.2"
3+
"packages/core/marine-worker": "0.3.2",
4+
"packages/core/aqua-to-js": "0.0.0"
45
}

.github/workflows/e2e.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ jobs:
4343
uses: fluencelabs/aqua/.github/workflows/tests.yml@main
4444
with:
4545
js-client-snapshots: "${{ needs.js-client.outputs.js-client-snapshots }}"
46-
nox-image: "docker.fluence.dev/nox:ipfs_renovate-air-interpreter-wasm-0-x_3158_2"
46+
nox-image: "fluencelabs/nox:unstable_minimal"
4747
flox:
4848
needs:
4949
- js-client
5050

5151
uses: fluencelabs/flox/.github/workflows/tests.yml@main
5252
with:
5353
js-client-snapshots: "${{ needs.js-client.outputs.js-client-snapshots }}"
54-
nox-image: "docker.fluence.dev/nox:ipfs_renovate-air-interpreter-wasm-0-x_3158_2"
54+
nox-image: "fluencelabs/nox:unstable_minimal"

.github/workflows/run-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,4 @@ jobs:
2828
uses: ./.github/workflows/tests.yml
2929
with:
3030
ref: ${{ github.ref }}
31-
nox-image: "docker.fluence.dev/nox:ipfs_renovate-air-interpreter-wasm-0-x_3135_1"
31+
nox-image: "fluencelabs/nox:unstable_minimal"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "@fluencelabs/aqua-to-js",
3+
"type": "module",
4+
"version": "0.0.0",
5+
"description": "Tool for generating aqua wrapper",
6+
"main": "dist/index.js",
7+
"files": ["dist"],
8+
"scripts": {
9+
"test": "vitest run",
10+
"build": "tsc"
11+
},
12+
"keywords": [],
13+
"author": "Fluence Labs",
14+
"license": "Apache-2.0",
15+
"dependencies": {
16+
"ts-pattern": "5.0.5"
17+
},
18+
"devDependencies": {
19+
"@fluencelabs/aqua-api": "0.12.0",
20+
"@fluencelabs/aqua-lib": "0.7.3",
21+
"@fluencelabs/interfaces": "workspace:*",
22+
"@fluencelabs/js-client": "workspace:*",
23+
"@fluencelabs/registry": "0.8.7",
24+
"@fluencelabs/spell": "0.5.20",
25+
"@fluencelabs/trust-graph": "0.4.7",
26+
"typescript": "5.1.6",
27+
"vitest": "0.29.7"
28+
}
29+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright 2023 Fluence Labs Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { ArrowType, ArrowWithoutCallbacks, NonArrowType, ProductType } from '@fluencelabs/interfaces';
18+
import { match, P } from 'ts-pattern';
19+
import { getFuncArgs } from './utils.js';
20+
21+
export function genTypeName(t: NonArrowType | ProductType<NonArrowType> | ArrowWithoutCallbacks, name: string): readonly [string | undefined, string] {
22+
const genType = typeToTs(t);
23+
return match(t)
24+
.with(
25+
{ tag: 'nil' },
26+
() => [undefined, 'void'] as const
27+
).with(
28+
{ tag: 'struct' },
29+
() => [`export type ${name} = ${genType}`, name] as const
30+
).with(
31+
{ tag: P.union('labeledProduct', 'unlabeledProduct') },
32+
(item) => {
33+
const args = item.tag === 'labeledProduct'
34+
? Object.values(item.fields)
35+
: item.items;
36+
37+
if (args.length === 1) {
38+
return genTypeName(args[0], name);
39+
}
40+
41+
return [`export type ${name} = ${genType}`, name] as const;
42+
},
43+
).otherwise(() => [undefined, genType] as const);
44+
}
45+
46+
export function typeToTs(t: NonArrowType | ArrowWithoutCallbacks | ProductType<NonArrowType>): string {
47+
return match(t)
48+
.with(
49+
{ tag: 'nil' },
50+
() => 'null'
51+
).with(
52+
{ tag: 'option' },
53+
({ type }) => typeToTs(type) + ' | null'
54+
).with(
55+
{ tag: 'scalar' },
56+
({ name }) => match(name)
57+
.with(P.union('u8', 'u16', 'u32', 'u64', 'i8', 'i16', 'i32', 'i64', 'f32', 'f64'), () => 'number')
58+
.with('bool', () => 'boolean')
59+
.with('string', () => 'string')
60+
.with(P._, () => 'any').exhaustive()
61+
).with(
62+
{ tag: 'array' },
63+
({ type }) => typeToTs(type) + '[]'
64+
).with(
65+
{ tag: 'struct' },
66+
({ fields }) => `{ ${Object.entries(fields).map(([field, type]) => `${field}: ${typeToTs(type)};`).join(' ')} }`
67+
).with(
68+
{ tag: 'labeledProduct' },
69+
({ fields }) => `{ ${Object.entries(fields).map(([field, type]) => `${field}: ${typeToTs(type)};`).join(' ')} }`
70+
).with(
71+
{ tag: 'unlabeledProduct' },
72+
({ items }) => `[${items.map(item => typeToTs(item)).join(', ')}]`
73+
).with(
74+
{ tag: 'arrow' },
75+
({ tag, domain, codomain }) => {
76+
const retType = codomain.tag === 'nil'
77+
? 'void'
78+
: codomain.items.length === 1
79+
? typeToTs(codomain.items[0])
80+
: typeToTs(codomain);
81+
82+
const args = getFuncArgs(domain).map(([name, type]) => ([name, typeToTs(type)]));
83+
84+
const generic = args.length === 0 ? 'null' : args.map(([name]) => `'${name}'`).join(' | ');
85+
args.push(['callParams', `CallParams$$<${generic}>`]);
86+
87+
const funcArgs = args.map(([name, type]) => `${name}: ${type}`).join(', ');
88+
89+
return `(${funcArgs}) => ${retType} | Promise<${retType}>`;
90+
}
91+
).with(
92+
{ tag: 'topType' },
93+
() => 'unknown'
94+
).with(
95+
{ tag: 'bottomType' },
96+
() => 'never'
97+
).exhaustive();
98+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/*
2+
* Copyright 2023 Fluence Labs Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
export const CLIENT = 'IFluenceClient$$';
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2023 Fluence Labs Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import {
18+
ArrayType,
19+
BottomType, LabeledProductType,
20+
NilType,
21+
NonArrowType,
22+
OptionType,
23+
ScalarType,
24+
StructType,
25+
TopType, UnlabeledProductType
26+
} from '@fluencelabs/interfaces';
27+
28+
// Type definitions for inferring ts types from air json definition
29+
// In the future we may remove string type declaration and move to type inference.
30+
31+
type GetTsTypeFromScalar<T extends ScalarType> = T['name'] extends 'u8' | 'u16' | 'u32' | 'u64' | 'i8' | 'i16' | 'i32' | 'i64' | 'f32' | 'f64'
32+
? number
33+
: T['name'] extends 'bool'
34+
? boolean
35+
: T['name'] extends 'string'
36+
? string
37+
: never;
38+
39+
type MapTuple<T> = { [K in keyof T]: T[K] extends NonArrowType ? GetTsType<T[K]> : never }
40+
41+
type GetTsType<T extends NonArrowType> = T extends NilType
42+
? null
43+
: T extends ArrayType
44+
? GetTsType<T['type']>[]
45+
: T extends StructType
46+
? { [K in keyof T]: GetTsType<T> }
47+
: T extends OptionType
48+
? GetTsType<T['type']> | null
49+
: T extends ScalarType
50+
? GetTsTypeFromScalar<T>
51+
: T extends TopType
52+
? unknown
53+
: T extends BottomType
54+
? never
55+
: T extends Exclude<UnlabeledProductType<infer H>, NilType>
56+
? MapTuple<H>
57+
: T extends Exclude<LabeledProductType<infer H>, NilType>
58+
? H extends NonArrowType
59+
? { [K in keyof T['fields']]: GetTsType<H> }
60+
: never
61+
: never;

0 commit comments

Comments
 (0)