Exemplo em Javascript de Meta-Schema (v1)

Um exemplo em Javascript para validar payloads com instâncias do Meta-Schema de definição de tipo de produto da Amazon.

Exemplo de implementação do validador para Javascript

Para aplicativos JavaScript, a biblioteca Hyperjump - JSON Schema Validator é compatível com JSON Schema Draft 2019-09 e vocabulários personalizados. O exemplo a seguir usa Node.js para demonstrar como utilizar a biblioteca Hyperjump - JSON Schema Validator para validar cargas com instâncias do Meta-Schema de definição de tipo de produto da Amazon. O código de exemplo a seguir não funcionará em um navegador da Web, no entanto, a biblioteca não tem dependências do Node.js e pode ser usada em um navegador da Web. Não há necessidade de usar essa biblioteca específica ou a implementação de exemplo. A Amazon não fornece suporte técnico para bibliotecas de esquema JSON de terceiros, isso é fornecido apenas como exemplo.

Configuração do schema

Ao usar o Hyperjump - JSON Schema Validator para validar instâncias do Meta-Schema de definição de tipo de produto da Amazon com vocabulário personalizado, o Meta-Schema é configurado como uma instância JsonSchema com validação de palavra-chave de vocabulário personalizada registrada no Hyperjump - JSON Schema Core.

Constantes:

// $id of the Amazon Product Type Definition Meta-Schema.
const schemaId = "https://schemas.amazon.com/selling-partners/definitions/product-types/meta-schema/v1";
// $id of the Amazon Product Type Definition Luggage-Schema.
const luggageSchemaId = "https://schemas.amazon.com/selling-partners/definitions/product-types/schema/v1/LUGGAGE";

// Local copy of the Amazon Product Type Definition Meta-Schema.
const metaSchemaPath = "./amazon-product-type-definition-meta-schema-v1.json";

// Local copy of an instance of the Amazon Product Type Definition Meta-Schema.
const luggageSchemaPath = "./luggage.json";

Configurar Meta-Schema:

// Add custom vocabulary and keywords
const { Core, Schema } = require("@hyperjump/json-schema-core");
const maxUniqueItemsKeyword = require("./keywords/MaxUniqueItemsKeyword.js");
const maxUtf8ByteLengthKeyword = require("./keywords/MaxUtf8ByteLengthKeyword.js");
const minUtf8ByteLengthKeyword = require("./keywords/MinUtf8ByteLengthKeyword.js");
const customVocabularyId = "https://schemas.amazon.com/selling-partners/definitions/product-types/vocabulary/v1";

// Configure $vocabulary defined in the schema JSON as vocabularyToken
Schema.setConfig(schemaId, "vocabularyToken", "$vocabulary");

// Add custom vocabulary and keywords
Core.defineVocabulary(customVocabularyId, {
    maxUniqueItems : maxUniqueItemsKeyword,
    minUtf8ByteLength : minUtf8ByteLengthKeyword,
    maxUtf8ByteLength : maxUtf8ByteLengthKeyword
});

// Add local schema JSON in JsonSchema.add() to use local copies of schemas rather than retrieving them from the web.
const JsonSchema = require("@hyperjump/json-schema");

// Add meta schema
const metaSchemaJSON = JSON.parse(fs.readFileSync(metaSchemaPath), "utf8");
JsonSchema.add(metaSchemaJSON, schemaId);

// Add luggage schema
const luggageSchemaJSON = JSON.parse(fs.readFileSync(luggageSchemaPath), "utf8");
JsonSchema.add(luggageSchemaJSON, luggageSchemaId, schemaId);

Carregar instância de Meta-Schema:

// Retrieve previously added luggage schema from JsonSchema instance
var luggageSchema = await JsonSchema.get(luggageSchemaId);

Validação do Payload

Com uma instância do Meta-Schema de definição de tipo de produto da Amazon carregada como uma instância JsonSchema, as cargas úteis podem ser validadas usando a instância.

// Load JSON for the payload (this can be constructed in code, read from a file, etc.).
const payload = JSON.parse(fs.readFileSync("./payload.json"), "utf8");

// Validate the payload and get validation result.
const result = await JsonSchema.validate(luggageSchema, payload, JsonSchema.BASIC);
const isValid = result.valid;

Se a carga útil for válida, isValid retornará true com uma lista vazia de palavras-chave de erro. Caso contrário, isValid retornará false com uma lista de palavras-chave de erro.

Exemplo de mensagem de validação:

{
    keyword: 'https://schemas.amazon.com/selling-partners/definitions/product-types/meta-schema/v1#minUtf8ByteLength',
    absoluteKeywordLocation: 'https://schemas.amazon.com/selling-partners/definitions/product-types/schema/v1/LUGGAGE#/properties/contribution_sku/items/properties/value/minUtf8ByteLength',
    instanceLocation: '#/contribution_sku/0/value',
    valid: false
}

Validação de palavra-chave

O Hyperjump - JSON Schema Core fornece uma estrutura que pode ser usada para validar vocabulário personalizado, palavras-chave e outras ferramentas.

Os exemplos a seguir ilustram as implementações do JsonSchema que validam o vocabulário personalizado em instâncias do Meta-Schema de definição de tipo de produto da Amazon.

Script MaxUniqueItemsKeyword

const { Schema, Instance} = require("@hyperjump/json-schema-core");

const compile = (schema, ast, parentSchema) =>
{
    const maxUniqueItems = Schema.value(schema);
    // Retrieve the selectors defined in meta-schema
    const selectors = parentSchema.value.selectors;
    return [maxUniqueItems, selectors];
}

const interpret = ([maxUniqueItems, selectors], instance, ast) => {
    if (!Instance.typeOf(instance, "array")) {
        return false;
    }

    let uniqueItems = new Array();
    // For each instance in the example schema retrieve selectors combinations
    instance.value.forEach(inst => {
        let selectorCombination = {};
        Object.entries(inst).forEach(([key,value]) => {
            if(selectors != undefined && selectors.includes(key)) {
                selectorCombination[key] = value;
            }});
        uniqueItems.push(JSON.stringify(selectorCombination));
    });

    let countMap = new Map();
    // Add count of each unique selector combination in countMap
    uniqueItems.forEach(item => {
        countMap.get(item) != undefined ? countMap.set(item, countMap.get(item)+ 1): countMap.set(item, 1);
    });
    // Filter the countMap for values greater than maxUniqueItems
    let filteredItems = Array.from(countMap.entries()).filter(item => {
        return item[1] > maxUniqueItems;
    });
    // If filteredItems found then validation fails, else succeeds
    return filteredItems.length > 0 ? false : true;
};

module.exports = { compile, interpret };

Script MaxUtf8ByteLengthKeyword

const { Schema, Instance} = require("@hyperjump/json-schema-core");

const compile = (schema, ast) => Schema.value(schema);

const interpret = (maxUtf8ByteLength, instance, ast) =>  Instance.typeOf(instance, "string") &&
    Buffer.byteLength(Instance.value(instance)) <= maxUtf8ByteLength;

module.exports = { compile, interpret };

Script MinUtf8ByteLengthKeyword

const { Schema, Instance} = require("@hyperjump/json-schema-core");

const compile = (schema, ast) => Schema.value(schema);

const interpret = (minUtf8ByteLength, instance, ast) =>
    Instance.typeOf(instance, "string") && Buffer.byteLength(Instance.value(instance)) >= minUtf8ByteLength;

module.exports = { compile, interpret };