-
Notifications
You must be signed in to change notification settings - Fork 22
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(pactjs-generator): parse exec code (#1794)
* feat(pactjs-generator): parse exec code * feat(pactjs-generator): export execCodeParser * fix: types * doc: update api docs
- Loading branch information
Showing
14 changed files
with
447 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@kadena/pactjs-generator': minor | ||
--- | ||
|
||
export execCodeParser in order to parse code peroperty of transactions |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
61 changes: 61 additions & 0 deletions
61
packages/libs/pactjs-generator/src/contract/parsing/execCodeParser.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { unwrapData } from './utils/dataWrapper'; | ||
import { functionCallParser } from './utils/functionCallParser'; | ||
import { getPointer } from './utils/getPointer'; | ||
import { FAILED } from './utils/parser-utilities'; | ||
|
||
/** | ||
* @alpha | ||
*/ | ||
export interface IParsedCode { | ||
function: { | ||
module?: string; | ||
namespace?: string; | ||
name: string; | ||
}; | ||
args: Array< | ||
| { string: string } | ||
| { int: number } | ||
| { decimal: number } | ||
| { | ||
object: Array<{ property: string; value: IParsedCode['args'][number] }>; | ||
} | ||
| { list: Array<IParsedCode['args']> } | ||
>; | ||
} | ||
/** | ||
* Parse the regular transaction code; | ||
* | ||
* this does not include deploy contract code; for that use {@link pactParser } | ||
* @example | ||
* const code = '(coin.transfer "alice" "bob" 100)(free.my-contract.my-function "alice" "bob" [100.1 2] \{ "extra" : "some-data" \} )'; | ||
* const parsed = execCodeParser(code); | ||
* // const parsed = [ | ||
* // \{ | ||
* // function: \{ module: 'coin', name: 'transfer' \}, | ||
* // args: [\{ string: 'alice' \}, \{ string: 'bob' \}, \{ int: 100 \}], | ||
* // \}, | ||
* // \{ | ||
* // function: \{ | ||
* // namespace: 'free', | ||
* // module: 'my-contract', | ||
* // name: 'my-function', | ||
* // \}, | ||
* // args: [ | ||
* // \{ string: 'alice' \}, | ||
* // \{ string: 'bob' \}, | ||
* // \{ list: [\{ decimal: 100.1 \}, \{ int: 2 \}] \}, | ||
* // \{ object: [\{ property: 'extra', value: [\{ string: 'some-data' \}] \}] \}, | ||
* // ], | ||
* // \}, | ||
* // ]; | ||
* @alpha | ||
*/ | ||
export function execCodeParser(code: string): undefined | IParsedCode[] { | ||
const pointer = getPointer(code); | ||
const result = functionCallParser(pointer); | ||
const data = unwrapData(result); | ||
if (data === FAILED) { | ||
return undefined; | ||
} | ||
return data?.codes as undefined | IParsedCode[]; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
packages/libs/pactjs-generator/src/contract/parsing/tests/execCodeParser.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { describe, expect, it } from 'vitest'; | ||
import { execCodeParser } from '../execCodeParser'; | ||
|
||
describe('execCodeParser', () => { | ||
it('parses pact code', () => { | ||
const code = | ||
'(coin.transfer "alice" "bob" 100)(free.my-contract.my-function "alice" "bob" [100.1 2] { "extra" : "some-data" } )'; | ||
const parsed = execCodeParser(code); | ||
expect(parsed).toEqual([ | ||
{ | ||
function: { module: 'coin', name: 'transfer' }, | ||
args: [{ string: 'alice' }, { string: 'bob' }, { int: '100' }], | ||
}, | ||
{ | ||
function: { | ||
namespace: 'free', | ||
module: 'my-contract', | ||
name: 'my-function', | ||
}, | ||
args: [ | ||
{ string: 'alice' }, | ||
{ string: 'bob' }, | ||
{ list: [{ decimal: '100.1' }, { int: '2' }] }, | ||
{ object: [{ property: 'extra', value: { string: 'some-data' } }] }, | ||
], | ||
}, | ||
]); | ||
}); | ||
|
||
it('returns undefined if code is not parsable - mismatch parenthesis', () => { | ||
// missing closing parenthesis | ||
const code = '(coin.transfer "alice" "bob" 100'; | ||
const parsed = execCodeParser(code); | ||
expect(parsed).toEqual(undefined); | ||
}); | ||
|
||
it('returns undefined if code is not parsable - invalid arg', () => { | ||
// atom as argument | ||
const code = '(coin.transfer alice "bob" 100'; | ||
const parsed = execCodeParser(code); | ||
expect(parsed).toEqual(undefined); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
92 changes: 92 additions & 0 deletions
92
packages/libs/pactjs-generator/src/contract/parsing/utils/functionCallParser.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
/* eslint-disable @kadena-dev/no-eslint-disable */ | ||
/* eslint-disable @typescript-eslint/explicit-function-return-type */ | ||
/* eslint-disable @rushstack/typedef-var */ | ||
// In this module, we generate new functions by composing other functions. In order to allow TypeScript to automatically infer the types, | ||
// I had to disable these rules. | ||
import type { IPointer } from './getPointer'; | ||
import type { IParser, RuleReturn } from './parser-utilities'; | ||
import { | ||
$, | ||
FAILED, | ||
atom, | ||
id, | ||
maybe, | ||
oneOf, | ||
repeat, | ||
restrictedBlock, | ||
seq, | ||
str, | ||
type, | ||
} from './parser-utilities'; | ||
|
||
export const functionCall = oneOf( | ||
// namespace.module.function | ||
seq( | ||
$('namespace', atom), | ||
id('.'), | ||
$('module', atom), | ||
id('.'), | ||
$('name', atom), | ||
), | ||
// module.function | ||
seq($('module', atom), id('.'), $('name', atom)), | ||
seq($('name', atom)), | ||
); | ||
|
||
const object = (rule: IParser) => | ||
seq( | ||
id('{'), | ||
repeat( | ||
$( | ||
'object', | ||
seq($('property', str), id(':'), $('value', rule), maybe(id(','))), | ||
), | ||
), | ||
id('}'), | ||
); | ||
|
||
const list = (rule: IParser) => seq(id('['), repeat($('list', rule)), id(']')); | ||
|
||
const code = (rule: IParser) => | ||
restrictedBlock( | ||
// function | ||
$('function', functionCall), | ||
repeat($('args', rule)), | ||
); | ||
|
||
// initiate parser on demand | ||
const lazyParser = <T extends IParser>(parser: () => T): T => | ||
((pointer: IPointer) => parser()(pointer)) as T; | ||
|
||
type ArgParser = IParser< | ||
| RuleReturn<string, 'string' | 'decimal' | 'int'> | ||
| RuleReturn<unknown, 'list'> | ||
| RuleReturn<Record<string, unknown>, 'object'> | ||
| RuleReturn<unknown, 'code'> | ||
>; | ||
|
||
const arg: ArgParser = lazyParser( | ||
() => | ||
oneOf( | ||
// valid args | ||
$('string', str), | ||
$('decimal', type('decimal')), | ||
$('int', type('int')), | ||
// object($('worked', arg)), | ||
// $('list', list(arg)), | ||
object(arg), | ||
list(arg), | ||
// $('object', object(arg)), | ||
$('code', code(arg)), | ||
) as ArgParser, | ||
); | ||
|
||
export const functionCallParser = (pointer: IPointer) => { | ||
const rule = repeat($('codes', code(arg))); | ||
const result = rule(pointer); | ||
if (pointer.done()) { | ||
// return the result if all tokens are consumed | ||
return result; | ||
} | ||
return FAILED; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.