Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Return json from extension-api-caller #323

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/core/src/lib/functional-extensions/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface FunctionalFilterOptions {

export type FunctionalFilter = (
options: FunctionalFilterOptions
) => Promise<string>;
) => Promise<any>;

export const createFilterExtension = (
name: string,
Expand Down
28 changes: 28 additions & 0 deletions packages/core/test/functional-extensions/filter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,31 @@ it('The extensions created by createFilter function should work with template en
expect(queries[0]).toBe('SELECT $1');
expect(bindings[0].get('$1')).toBe('QAQ3QQQQ');
});

it('The extensions can return arbitrary value', async () => {
// Arrange
const testFilter: FunctionalFilter = async ({ args, value }) =>
({id: args['aa'], text: `QAQ${args['aa']}${value}`});
const [Builder, Runner] = createFilterExtension('test', testFilter);
const builder = new Builder({}, '');
const runner = new Runner({}, '');
const {
compiler,
loader,
executeTemplate,
getCreatedQueries,
getCreatedBinding,
} = await createTestCompiler({ additionalExtensions: [builder, runner] });
const { compiledData } = await compiler.compile(
`SELECT {{ (context.params.id | test(aa=3)).id }}, {{ (context.params.id | test(aa=3)).text }}`
);
loader.setSource('test', compiledData);
// Act
await executeTemplate('test', { id: 'QQQQ' });
const queries = await getCreatedQueries();
const bindings = await getCreatedBinding();
// Assert
expect(queries[0]).toBe('SELECT $1, $2');
expect(bindings[0].get('$1')).toBe(3);
expect(bindings[0].get('$2')).toBe('QAQ3QQQQ');
});
8 changes: 4 additions & 4 deletions packages/extension-api-caller/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,26 +23,26 @@ To pass the path parameters:

```sql
{% set a_variable_you_can_define = { "path": { "id": 1 } } %}
SELECT {{ a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/:id') }}
SELECT {{ (a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/:id')).id }}
```

To pass the query parameters:

```sql
{% set a_variable_you_can_define = { "query": { "q": "phone" } } %}
SELECT {{ a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/search') }}
SELECT {{ a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/search') | dump }}
```

To issue the POST request:

```sql
{% set a_variable_you_can_define = { "body": { "title": "BMW Pencil" } } %}
SELECT {{ a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/add', method='POST') }}
SELECT {{ a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/add', method='POST') | dump }}
```

To pass the headers and multiple fields:

```sql
{% set a_variable_you_can_define = { "headers": { "Content-Type": "application/json" }, "body": { "title": "BMW Pencil" } } %}
SELECT {{ a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/add', method='POST') }}
SELECT {{ a_variable_you_can_define | rest_api(url='https://dummyjson.com/products/add', method='POST') | dump }}
```
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const RestApiCallerFilter: FunctionalFilter = async ({
logger.info('API request:', options);
const results = await axios(options);
logger.info('API response:', results.data);
return JSON.stringify(results.data);
return results.data;
} catch (error: any) {
const message = error.response
? `response status: ${error.response.status}, response data: ${JSON.stringify(error.response.data)}`
Expand Down
34 changes: 31 additions & 3 deletions packages/extension-api-caller/test/restApiCaller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ describe('Test "rest_api" filter', () => {
extensions: { rest_api: path.join(__dirname, '..', 'src') },
});

const sql = `{% set value = { "path": { "id": 1 } } %}SELECT {{ value | rest_api(url='https://dummyjson.com/products/:id') }}`;
const sql = `{% set value = { "path": { "id": 1 } } %}SELECT {{ value | rest_api(url='https://dummyjson.com/products/:id') | dump }}`;

// Act
await compileAndLoad(sql);
Expand Down Expand Up @@ -155,7 +155,7 @@ describe('Test "rest_api" filter', () => {
extensions: { rest_api: path.join(__dirname, '..', 'src') },
});

const sql = `{% set value = { "query": { "q": "phone" } } %}SELECT {{ value | rest_api(url='https://dummyjson.com/products/search') }}`;
const sql = `{% set value = { "query": { "q": "phone" } } %}SELECT {{ value | rest_api(url='https://dummyjson.com/products/search') | dump }}`;

// Act
await compileAndLoad(sql);
Expand Down Expand Up @@ -183,7 +183,35 @@ describe('Test "rest_api" filter', () => {
extensions: { rest_api: path.join(__dirname, '..', 'src') },
});

const sql = `{% set value = { "body": { "title": "BMW Pencil" }, "headers": { "Content-Type": "application/json" } } %}SELECT {{ value | rest_api(url='https://dummyjson.com/products/add', method='POST') }}`;
const sql = `{% set value = { "body": { "title": "BMW Pencil" }, "headers": { "Content-Type": "application/json" } } %}SELECT {{ value | rest_api(url='https://dummyjson.com/products/add', method='POST') | dump }}`;

// Act
await compileAndLoad(sql);
await execute({});

// Assert
const queries = await getExecutedQueries();
const bindings = await getCreatedBinding();

expect(queries[0]).toBe('SELECT $1');
expect(bindings[0].get('$1')).toEqual(expected);
},
50 * 1000
)

it(
'Should work with template engine with field access',
async () => {
const expected = {
id: 101,
title: 'BMW Pencil'
}.id;

const { compileAndLoad, execute, getExecutedQueries, getCreatedBinding } = await getTestCompiler({
extensions: { rest_api: path.join(__dirname, '..', 'src') },
});

const sql = `{% set value = { "body": { "title": "BMW Pencil" }, "headers": { "Content-Type": "application/json" } } %}SELECT {{ (value | rest_api(url='https://dummyjson.com/products/add', method='POST')).id }}`;

// Act
await compileAndLoad(sql);
Expand Down