diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..d66c017a --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,30 @@ +name: Test + +on: + push: + branches: + - main # Set a branch to deploy + pull_request: + +jobs: + deploy: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - uses: denoland/setup-deno@v1 + with: + deno-version: v1.x + + - uses: szenius/set-timezone@v1.0 + with: + timezoneLinux: "Europe/Prague" + + - name: Test + run: make test \ No newline at end of file diff --git a/dist/bundle.json b/dist/bundle.json index 4c0e9415..8ad9c46b 100644 --- a/dist/bundle.json +++ b/dist/bundle.json @@ -409,7 +409,122 @@ "id": "pollen-mobile" }, { - "id": "secret-network" + "id": "secret-network", + "name": "Secret Network", + "categories": [ + "infrastructure" + ], + "ecosystem": "Secret", + "token": [ + { + "name": "Secret", + "symbol": "SCRT" + } + ], + "description": "Chain for private computations", + "project_type": "Infrastructure", + "product_launch_day": "Feb 13, 2020", + "technology": { + "type": "TEE", + "name": "Trusted execution environment", + "features": "privacy, DeFi, NFTs, PaaS" + }, + "links": { + "web": "https://scrt.network/", + "twitter": "https://twitter.com/SecretNetwork", + "telegram": "https://t.me/scrtCommunity", + "discord": "https://discord.com/invite/secret-network-360051864110235648", + "blog": "https://scrt.network/blog", + "facebook": null, + "block_explorer": "https://www.mintscan.io/secret", + "whitepaper": "https://scrt.network/graypaper/", + "github": "https://github.com/scrtlabs/SecretNetwork", + "docs": "https://docs.scrt.network/secret-network-documentation/", + "forum": "https://forum.scrt.network/" + }, + "blockchain_features": { + "p2p": false, + "encryption": "TEE", + "upgradability": { + "enabled": true, + "type": "governance/fork" + }, + "opensource": true, + "viewing_key": true, + "dissapearing_tx": false, + "connected_tx": true, + "reversability_condition": "viewing key, hack", + "data_masking": "Secret Contracts", + "asset_custody_type": "non-custody" + }, + "licences": "MIT License", + "privacy_policy": { + "defined": false + }, + "team": { + "anonymous": false, + "teammembers": [ + { + "name": "Alex Zaidelson", + "role": "SLabs CEO", + "link": "https://twitter.com/azaidelson" + } + ], + "company": [ + { + "name": "Secret Labs", + "link": "https://www.scrtlabs.com/", + "contacts": "info@scrtlabs.com" + } + ] + }, + "storage": { + "decentralized": true + }, + "tracebility": { + "tracked_data": "user SCRT adress", + "kyc": false, + "sign_in_type_requirments": "wallet" + }, + "third_party_dependency": false, + "compliance": false, + "social_trust": "Slabs ( MRSINGER )", + "technical_spof": "Can decrypt", + "history": [ + { + "title": "Mainnet", + "event_type": "launch", + "description": "Mainnet", + "time": "Feb 13, 2020", + "link": "https://shadeprotocol.io/blog/shade-protocol-claim-tutorial" + } + ], + "client_diversability": [ + { + "name": "Keplr", + "link": "https://www.keplr.app/" + }, + { + "name": "Starshell", + "link": "https://starshell.net/" + } + ], + "default_privacy": false, + "funding": [ + { + "name": "Private investors", + "type": "ICO", + "link": "https://icodrops.com/secret-network/", + "value": "236.500.000 $", + "time": "Jul 23, 2020" + } + ], + "project_status": { + "live_status": true, + "version": "Mainnet", + "testnet": true, + "mainnet": true + } }, { "id": "mysterium" @@ -478,7 +593,101 @@ "id": "litecash" }, { - "id": "zcash" + "id": "zcash", + "name": "Zcash", + "categories": [ + "currency" + ], + "ecosystem": "Zcash", + "token": [ + { + "name": "Zcash", + "symbol": "ZEC" + } + ], + "security": "PoW", + "description": "A simple, secure digital currency that protects your privacy.", + "project_type": "Currency", + "product_launch_day": "Oct 28, 2016", + "technology": { + "type": "zkSNARKs", + "name": "Zero-knowlindge", + "features": "private, currency, payments" + }, + "links": { + "web": "https://z.cash/", + "coingecko": "https://www.coingecko.com/en/coins/zcash", + "twitter": "https://twitter.com/zcash", + "telegram": "https://t.me/zcash_community", + "discord": null, + "blog": null, + "facebook": null, + "block_explorer": "https://zcashblockexplorer.com/", + "whitepaper": "https://whitepaper.io/document/645/zcash-whitepaper", + "github": "https://github.com/zcash/zcash", + "docs": "https://zcash.readthedocs.io/en/latest/", + "forum": "https://forum.zcashcommunity.com/" + }, + "blockchain_features": { + "p2p": false, + "encryption": "zk-SNARKs", + "upgradability": { + "enabled": true, + "type": "fork" + }, + "opensource": true, + "viewing_key": true, + "dissapearing_tx": false, + "frontend_anonymity": "options", + "identity_integration": null, + "connected_tx": false, + "revealed_recipient": false, + "revealed_sender": false, + "revealed_ammount": false, + "reversability_condition": "viewing key, hack", + "data_masking": "Shielded pools", + "asset_custody_type": "non-custody" + }, + "licences": null, + "third_party_dependency": false, + "compliance": false, + "social_trust": null, + "technical_spof": null, + "history": [ + { + "title": "Mainet", + "event_type": "launch", + "description": "Airdrop", + "time": "Oct 28, 2016", + "link": null + } + ], + "wallets": [ + { + "name": "Ywallet", + "link": "https://ywallet.app/" + }, + { + "name": "Edge Wallet", + "link": "https://z.cash/ecosystem/edge-wallet/" + } + ], + "default_privacy": false, + "funding": [ + { + "name": null, + "type": null, + "link": null, + "value": null, + "time": null + } + ], + "project_status": { + "live_status": true, + "version": "Mainnet", + "testnet": true, + "mainnet": true + } }, { "id": "cog" @@ -764,7 +973,7 @@ "categories": [ "defi" ], - "ecosystem": "Ethereum", + "ecosystem": "Ethereum, Elrond, Polkadot, Avalanche, Near, Flare", "description": "is a decentralized privacy metaprotocol enabling confidential, trusted transactions and interoperability with DeFi", "technology": { "type": "zk" diff --git a/schema/categories.yaml b/schema/categories.yaml deleted file mode 100644 index e08a0a7b..00000000 --- a/schema/categories.yaml +++ /dev/null @@ -1,13 +0,0 @@ -type: array -required: - - id - - name -additionalProperties: false -items: - type: object - properties: - id: - type: string - pattern: '^[a-z0-9-]+$' - name: - type: string diff --git a/schema/category.yaml b/schema/category.yaml new file mode 100644 index 00000000..aa85db5d --- /dev/null +++ b/schema/category.yaml @@ -0,0 +1,11 @@ +type: object +additionalProperties: false +required: + - id + - name +properties: + id: + type: string + pattern: '^[a-z0-9-]+$' + name: + type: string diff --git a/schema/project.yaml b/schema/project.yaml index 780c700e..64447586 100644 --- a/schema/project.yaml +++ b/schema/project.yaml @@ -1,15 +1,18 @@ type: object additionalProperties: false required: + - id - name - categories - ecosystem - - token - description - project_type - technology - links properties: + id: + type: string + pattern: '^[a-z0-9-]+$' name: type: string categories: @@ -27,7 +30,7 @@ properties: symbol: type: string network: - type: + type: string contract_address: type: string required: @@ -115,7 +118,7 @@ properties: encryption: type: string network: - type: + type: string upgradability: type: object properties: @@ -190,7 +193,7 @@ properties: type: object properties: decentralized: - type: boolean + type: boolean tracebility: type: object properties: @@ -221,7 +224,7 @@ properties: social_trust: type: string technical_spof: - type: striing + type: string history: type: object properties: diff --git a/utils/build.js b/utils/build.js index 8ec03e1e..6634cbd6 100644 --- a/utils/build.js +++ b/utils/build.js @@ -1,14 +1,14 @@ import { W3PData } from "./w3pdata.js"; -const w3pd = new W3PData() -await w3pd.init() +const w3pd = new W3PData(); +await w3pd.init(); -const outputDir = "./dist" +const outputDir = "./dist"; try { - await Deno.mkdir(outputDir) + await Deno.mkdir(outputDir); } catch {} -const bundleFn = `${outputDir}/bundle.json` -await Deno.writeTextFile(bundleFn, JSON.stringify(w3pd.data, null, 2)) -console.log(`Bundle writed: ${bundleFn}`) +const bundleFn = `${outputDir}/bundle.json`; +await Deno.writeTextFile(bundleFn, JSON.stringify(w3pd.data, null, 2)); +console.log(`Bundle writed: ${bundleFn}`); diff --git a/utils/gen.js b/utils/gen.js index a19d7bce..20f75819 100644 --- a/utils/gen.js +++ b/utils/gen.js @@ -1,56 +1,57 @@ -import yaml from 'npm:js-yaml' +import yaml from "npm:js-yaml"; function slugify(input) { - if (!input) - return ''; + if (!input) { + return ""; + } - // make lower case and trim - var slug = input.toLowerCase().trim(); + // make lower case and trim + var slug = input.toLowerCase().trim(); - // remove accents from charaters - slug = slug.normalize('NFD').replace(/[\u0300-\u036f]/g, '') + // remove accents from charaters + slug = slug.normalize("NFD").replace(/[\u0300-\u036f]/g, ""); - // replace invalid chars with spaces - slug = slug.replace(/[^a-z0-9\s-]/g, ' ').trim(); + // replace invalid chars with spaces + slug = slug.replace(/[^a-z0-9\s-]/g, " ").trim(); - // replace multiple spaces or hyphens with a single hyphen - slug = slug.replace(/[\s-]+/g, '-'); + // replace multiple spaces or hyphens with a single hyphen + slug = slug.replace(/[\s-]+/g, "-"); - return slug; + return slug; } -const projectDir = "src/projects" +const projectDir = "src/projects"; -async function genCat (cat) { - const catDir = `${projectDir}/${cat}` - const f = await Deno.readTextFile(`${catDir}/src.json`) - const src = JSON.parse(f) +async function genCat(cat) { + const catDir = `${projectDir}/${cat}`; + const f = await Deno.readTextFile(`${catDir}/src.json`); + const src = JSON.parse(f); - for (const p of src.data.Projects) { - const id = slugify(p.Project) - const pDir = `${catDir}/${id}` - console.log(`${id}:\n -> ${pDir}`) + for (const p of src.data.Projects) { + const id = slugify(p.Project); + const pDir = `${catDir}/${id}`; + console.log(`${id}:\n -> ${pDir}`); - try { - await Deno.mkdir(pDir) - } catch {} + try { + await Deno.mkdir(pDir); + } catch {} - const out = { - name: p.Project, - description: p.Description, - ecosystem: p.Ecosystem, - links: { - github: p.GitHub, - linkedin: p.TeamLink, - }, - team: { - anonymous: p.Team !== "Public" - } - } - const yml = yaml.dump(out) - await Deno.writeTextFile(`${pDir}/index.yaml`, yml) - //console.log(id, yml) - } + const out = { + name: p.Project, + description: p.Description, + ecosystem: p.Ecosystem, + links: { + github: p.GitHub, + linkedin: p.TeamLink, + }, + team: { + anonymous: p.Team !== "Public", + }, + }; + const yml = yaml.dump(out); + await Deno.writeTextFile(`${pDir}/index.yaml`, yml); + //console.log(id, yml) + } } -genCat(Deno.args[0]) +genCat(Deno.args[0]); diff --git a/utils/test.js b/utils/test.js index b0e61683..051ed8e3 100644 --- a/utils/test.js +++ b/utils/test.js @@ -1,6 +1,40 @@ +import Ajv from "https://esm.sh/ajv@8.8.1?pin=v58"; +import addFormats from "https://esm.sh/ajv-formats@2.1.1"; +import yaml from "npm:js-yaml"; + import { W3PData } from "./w3pdata.js"; -const w3pd = new W3PData() -await w3pd.init() +const w3pd = new W3PData(); +await w3pd.init(); -console.log(w3pd.data) \ No newline at end of file +const ajv = new Ajv({ strict: false }); +addFormats(ajv); + +async function loadSchemas() { + const out = {}; + for await (const f of Deno.readDir(schemaDir)) { + const col = f.name.split(".")[0]; + out[col] = yaml.load(await Deno.readTextFile(`${schemaDir}/${f.name}`)); + } + return out; +} + +const matrix = { + categories: "category", + projects: "project", +}; + +const schemaDir = "./schema"; +const schemas = await loadSchemas(); + +for (const col of Object.keys(w3pd.data)) { + const validator = ajv.compile(schemas[matrix[col]]); + + for (const item of w3pd.data[col]) { + Deno.test(`${col}/${item.id}`, () => { + if (!validator(item)) { + throw validator.errors; + } + }); + } +} diff --git a/utils/w3pdata.js b/utils/w3pdata.js index 2425f595..4e9377b4 100644 --- a/utils/w3pdata.js +++ b/utils/w3pdata.js @@ -1,42 +1,43 @@ -import yaml from 'npm:js-yaml' +import yaml from "npm:js-yaml"; export class W3PData { + constructor() { + } - constructor () { - } + async init() { + this.data = await this.load("./src"); + } - async init () { - this.data = await this.load("./src") - } - - async load (dataDir) { - const out = {} - for await (const f of Deno.readDir(dataDir)) { - if (f.isFile && f.name.match(/\.yaml$/)) { - const name = f.name.split('.')[0] - out[name] = await this.loadYaml(`${dataDir}/${f.name}`) - } - if (f.isDirectory && f.name === 'projects') { - out.projects = [] - const projectsDir = `${dataDir}/${f.name}` - for await (const pcd of Deno.readDir(projectsDir)) { - const catName = pcd.name - const catDir = `${projectsDir}/${pcd.name}` - for await (const pd of Deno.readDir(catDir)) { - if (!pd.isDirectory) { - continue - } - const pDir = `${catDir}/${pd.name}` - const index = yaml.load(await Deno.readTextFile(`${pDir}/index.yaml`)) - out.projects.push(Object.assign({ id: pd.name }, index)) - } - } + async load(dataDir) { + const out = {}; + for await (const f of Deno.readDir(dataDir)) { + if (f.isFile && f.name.match(/\.yaml$/)) { + const name = f.name.split(".")[0]; + out[name] = await this.loadYaml(`${dataDir}/${f.name}`); + } + if (f.isDirectory && f.name === "projects") { + out.projects = []; + const projectsDir = `${dataDir}/${f.name}`; + for await (const pcd of Deno.readDir(projectsDir)) { + const catName = pcd.name; + const catDir = `${projectsDir}/${pcd.name}`; + for await (const pd of Deno.readDir(catDir)) { + if (!pd.isDirectory) { + continue; } + const pDir = `${catDir}/${pd.name}`; + const index = yaml.load( + await Deno.readTextFile(`${pDir}/index.yaml`), + ); + out.projects.push(Object.assign({ id: pd.name }, index)); + } } - return out + } } - - async loadYaml (f) { - return yaml.load(await Deno.readTextFile(f)) - } -} \ No newline at end of file + return out; + } + + async loadYaml(f) { + return yaml.load(await Deno.readTextFile(f)); + } +}