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

Custom keyword modifying data doesn't run during parsing #1952

Open
bohdyone opened this issue Apr 7, 2022 · 6 comments
Open

Custom keyword modifying data doesn't run during parsing #1952

bohdyone opened this issue Apr 7, 2022 · 6 comments
Labels

Comments

@bohdyone
Copy link

bohdyone commented Apr 7, 2022

Hi, I'm trying to parse to a custom type, but running into some issues.

What version of Ajv are you using? Does the issue happen if you use the latest version?
"ajv": "^8.11.0"

Ajv options object

const parseDecimalKeyword: KeywordDefinition = {
  keyword: "parseDecimal",
  compile: () => (data, dataCtx: DataValidationCxt) => {
    const parsedDecimal = new BigNumber(data, 10);
    dataCtx.parentData[dataCtx.parentDataProperty] = parsedDecimal;

    return !parsedDecimal.isNaN();
  },
};

const ajv = new Ajv({
  keywords: [parseDecimalKeyword],
});

JSON Schema

{
  elements: {
    properties: {
      amount: <any>{
        type: "string",
        metadata: {
          parseDecimal: true,
        },
      },
    },
    additionalProperties: true,
  },
};

Sample data

const test = [
      {
        id: 'DeQtD(X%t}',
        creationTime: '2072-12-24T10:35:22.962Z',
        description: '*N)`v1;#M8',
        assetName: 'g+}rw`6zi)',
        amount: '57136.58',
        balance: '81053.34',
        type: 'Withdraw',
        recordType: 'Trade',
        referenceId: '}AEcK*GK*P'
      }
]
const result = parseBtcMarketsTxsRspData(JSON.stringify(test))!;
  expect(parseBtcMarketsTxsRspData.message).toBeUndefined();
  expect(result).not.toBeUndefined();

  expect(result).toHaveLength(1);
  expect(result[0].amount).toBeInstanceOf(BigNumber);

What results did you expect?

Based on the examples in #141 I expect to have the value of amount parsed to a BigNumber object if successful, but it seems like it's still a string.

Btw, it seems like I also have to cast the property object in schema to to satisfy the type checking even though I will be coercing the value from string to BigNumber. Is there a plan to address this limitation / support this use case?

Are you going to resolve the issue?

If there is a more appropriate way to do this, I'm happy to. Right now I have to work around it by using validate() instead of parse() directly.

@semiaddict
Copy link

I believe your schema should be as follows (without the metadata key):

{
  elements: {
    properties: {
      amount: <any>{
        type: "string",
        parseDecimal: true,
      },
    },
    additionalProperties: true,
  },
};

@bohdyone
Copy link
Author

Forgot to say, this is a JTD schema not a JSON Schema, so extra keywords are only allowed under the metadata prop...

@bohdyone
Copy link
Author

Hi, Is there any update on this one?

Regards.

@epoberezkin
Copy link
Member

Sorry for the delay.

Keywords that modify data have to be explicitly marked as such (modifying: true), otherwise they won't update the object with the data, they would simply update the local variable.

See this doc: https://ajv.js.org/api.html#ajv-addkeyword-definition-object-ajv

@epoberezkin
Copy link
Member

although, you are explicitly updating parent data...

@bohdyone
Copy link
Author

bohdyone commented Aug 7, 2022

Hi,

Thanks for the reply.

although, you are explicitly updating parent data...

I'm only doing that in this case because I want to replace the value of data. Is there a more idiomatic way of doing that?

Regards,
Bogdan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants