Skip to content

Commit

Permalink
Merge pull request #25 from hypercerts-org/feat/geojson_support_metadata
Browse files Browse the repository at this point in the history
Support for geoJSON in metadata
  • Loading branch information
bitbeckers authored Jan 26, 2025
2 parents 76367c7 + f205913 commit 7e16d00
Show file tree
Hide file tree
Showing 20 changed files with 1,077 additions and 136 deletions.
25 changes: 14 additions & 11 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";


export default [
{ files: ["**/*.{js,mjs,cjs,ts}"] },
{ languageOptions: { globals: { ...globals.browser, ...globals.node } } },
pluginJs.configs.recommended,
...tseslint.configs.recommended,
];
export default {
root: true,
env: {
browser: true,
node: true,
},
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:chai-friendly/recommended"],
parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "chai-friendly"],
rules: {
"no-unused-expressions": "off",
"chai-friendly/no-unused-expressions": "error",
},
};
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"esbuild": "^0.19.8",
"eslint": "^9.18.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-chai-friendly": "^1.0.1",
"globals": "^15.14.0",
"husky": "^9.1.7",
"json-schema-to-typescript": "^13.1.1",
Expand Down Expand Up @@ -83,7 +84,7 @@
"commitlint": "commitlint --config commitlintrc.ts --edit"
},
"lint-staged": {
"*.{js, jsx,ts,tsx}": [
"*.{js,jsx,ts,tsx}": [
"eslint --quiet --fix"
],
"*.{json,js,ts,jsx,tsx,html}": [
Expand Down
13 changes: 13 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 18 additions & 6 deletions src/resources/schema/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,26 @@
"type": "array",
"items": {
"type": "object",
"properties": {
"trait_type": {
"type": "string"
"oneOf": [
{
"properties": {
"trait_type": { "type": "string" },
"value": { "type": "string" }
},
"required": ["trait_type", "value"],
"additionalProperties": false
},
"value": {
"type": "string"
{
"properties": {
"trait_type": { "type": "string" },
"type": { "type": "string" },
"src": { "type": "string" },
"name": { "type": "string" }
},
"required": ["trait_type", "type", "src", "name"],
"additionalProperties": false
}
}
]
}
},
"hypercert": {
Expand Down
17 changes: 12 additions & 5 deletions src/types/metadata.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,18 @@ export interface HypercertMetadata {
* A CID pointer to the merke tree proof json on ipfs
*/
allowList?: string;
properties?: {
trait_type?: string;
value?: string;
[k: string]: unknown;
}[];
properties?: (
| {
trait_type: string;
value: string;
}
| {
trait_type: string;
type: string;
src: string;
name: string;
}
)[];
hypercert?: HypercertClaimdata;
}
/**
Expand Down
29 changes: 29 additions & 0 deletions src/validator/ValidatorFactory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { HypercertMetadata, HypercertClaimdata, AllowlistEntry } from "src/types";
import { IValidator } from "./interfaces";
import { MerkleProofData, MerkleProofValidator } from "./validators/MerkleProofValidator";
import { MetadataValidator, ClaimDataValidator } from "./validators/MetadataValidator";
import { AllowlistValidator } from "./validators/AllowListValidator";
import { AllowlistValidationParams } from "./validators/AllowListValidator";
import { PropertyValidator, PropertyValue } from "./validators/PropertyValidator";

export class ValidatorFactory {
static createMetadataValidator(): IValidator<HypercertMetadata> {
return new MetadataValidator();
}

static createClaimDataValidator(): IValidator<HypercertClaimdata> {
return new ClaimDataValidator();
}

static createAllowlistValidator(): IValidator<AllowlistEntry[], AllowlistValidationParams> {
return new AllowlistValidator();
}

static createMerkleProofValidator(): IValidator<MerkleProofData> {
return new MerkleProofValidator();
}

static createPropertyValidator(): IValidator<PropertyValue> {
return new PropertyValidator();
}
}
40 changes: 40 additions & 0 deletions src/validator/base/SchemaValidator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Ajv, { Schema, ErrorObject } from "ajv";
import { IValidator, ValidationError, ValidationResult } from "../interfaces";

export abstract class SchemaValidator<T> implements IValidator<T> {
protected ajv: Ajv;
protected schema: Schema;

constructor(schema: Schema, additionalSchemas: Schema[] = []) {
this.ajv = new Ajv({ allErrors: true });
// Add any additional schemas first
additionalSchemas.forEach((schema) => this.ajv.addSchema(schema));
this.schema = schema;
}

validate(data: unknown): ValidationResult<T> {
const validate = this.ajv.compile(this.schema);

if (!validate(data)) {
return {
isValid: false,
errors: this.formatErrors(validate.errors || []),
};
}

return {
isValid: true,
data: data as T,
errors: [],
};
}

protected formatErrors(errors: ErrorObject[]): ValidationError[] {
return errors.map((error) => ({
code: "SCHEMA_VALIDATION_ERROR",
message: error.message || "Unknown validation error",
field: error.instancePath || (error.params.missingProperty as string) || "",
details: error.params,
}));
}
}
Loading

0 comments on commit 7e16d00

Please sign in to comment.