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

feat(packages): add crypto-frontmatter mirror to copy raw assets #26

Merged
merged 5 commits into from
Nov 14, 2023
Merged
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
3 changes: 3 additions & 0 deletions packages/crypto-frontmatter/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#! /usr/bin/env node
/* eslint-disable */
require('./dist/cli.js');
28 changes: 17 additions & 11 deletions packages/crypto-frontmatter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
]
}
},
"bin": {
"crypto-frontmatter": "./cli.js"
},
"files": [
"dist"
],
Expand All @@ -40,23 +43,26 @@
"jest": {
"preset": "@workspace/jest-preset"
},
"dependencies": {
"clipanion": "3.2.1"
},
"devDependencies": {
"@crypto-frontmatter/eip155-1-erc20": "workspace:*",
"@workspace/jest-preset": "workspace:*",
"@workspace/tsconfig": "workspace:*"
},
"peerDependencies": {
"@crypto-frontmatter/eip155-1-erc20": "*",
"@crypto-frontmatter/eip155-10-erc20": "*",
"@crypto-frontmatter/eip155-1313161554-erc20": "*",
"@crypto-frontmatter/eip155-137-erc20": "*",
"@crypto-frontmatter/eip155-42161-erc20": "*",
"@crypto-frontmatter/eip155-42220-erc20": "*",
"@crypto-frontmatter/eip155-43114-erc20": "*",
"@crypto-frontmatter/eip155-56-erc20": "*",
"@crypto-frontmatter/eip155-8453-erc20": "*",
"@crypto-frontmatter/tip474-728126428-trc10": "*",
"@crypto-frontmatter/tip474-728126428-trc20": "*"
"@crypto-frontmatter/eip155-1-erc20": "workspace:*",
"@crypto-frontmatter/eip155-10-erc20": "workspace:*",
"@crypto-frontmatter/eip155-1313161554-erc20": "workspace:*",
"@crypto-frontmatter/eip155-137-erc20": "workspace:*",
"@crypto-frontmatter/eip155-42161-erc20": "workspace:*",
"@crypto-frontmatter/eip155-42220-erc20": "workspace:*",
"@crypto-frontmatter/eip155-43114-erc20": "workspace:*",
"@crypto-frontmatter/eip155-56-erc20": "workspace:*",
"@crypto-frontmatter/eip155-8453-erc20": "workspace:*",
"@crypto-frontmatter/tip474-728126428-trc10": "workspace:*",
"@crypto-frontmatter/tip474-728126428-trc20": "workspace:*"
},
"peerDependenciesMeta": {
"@crypto-frontmatter/eip155-1-erc20": {
Expand Down
34 changes: 34 additions & 0 deletions packages/crypto-frontmatter/src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { copyFile, mkdir } from 'node:fs/promises';
import { join } from 'node:path';

import { Command, Option, runExit } from 'clipanion';

import { getFrontmatterIndexArray, getInstalledFrontmatterCollection, getNodeModulesPath } from './index';

export class MirrorCommand extends Command {
static override paths = [[`mirror`]];
private target = Option.String();

async execute(): Promise<number | void> {
await mkdir(this.target, { recursive: true });

const collections = await getInstalledFrontmatterCollection();
for (const collection of collections) {
let count = 0;
const indexArray = await getFrontmatterIndexArray(collection.caip2, collection.namespace);
for (const frontmatterIndex of indexArray) {
for (const frontmatterImage of frontmatterIndex.fields.images) {
const from = getNodeModulesPath(collection.caip2, collection.namespace, frontmatterImage.path);
const to = join(this.target, frontmatterImage.path);
count++;
await copyFile(from, to);
}
}

this.context.stdout.write(`Mirrored ${count} files for "${collection.caip2}/${collection.namespace}"\n`);
}
}
}

// noinspection JSIgnoredPromiseFromCall
void runExit([MirrorCommand]);
71 changes: 47 additions & 24 deletions packages/crypto-frontmatter/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { createHash } from 'node:crypto';
import { readFile } from 'node:fs/promises';
import { readdir, readFile, stat } from 'node:fs/promises';
import { join } from 'node:path';

export interface FrontmatterLink {
Expand Down Expand Up @@ -39,19 +39,10 @@ export interface FrontmatterContent extends FrontmatterIndex {
html: string;
}

export const SupportedCollections = [
['eip155:1', 'erc20'],
['eip155:10', 'erc20'],
['eip155:56', 'erc20'],
['eip155:137', 'erc20'],
['eip155:8453', 'erc20'],
['eip155:42161', 'erc20'],
['eip155:42220', 'erc20'],
['eip155:43114', 'erc20'],
['eip155:1313161554', 'erc20'],
['tip474:728126428', 'trc10'],
['tip474:728126428', 'trc20'],
];
export interface FrontmatterCollection {
caip2: string;
namespace: string;
}

/**
* Decode CAIP-19 into CAIP-2, Asset NAMESPACE, and Asset REFERENCE
Expand All @@ -68,6 +59,13 @@ function sha256(input: string): string {
return createHash('sha256').update(input).digest('hex');
}

function hasFile(filepath: string): Promise<boolean> {
return stat(filepath).then(
() => true,
() => false,
);
}

/**
* Encode CAIP-19 into fileId
* If Namespace is ERC20, the address field will be converted to lowercase.
Expand All @@ -82,30 +80,47 @@ export function computeFileId(caip19: string): string {
return sha256(caip19);
}

export async function readCryptoFrontmatterFile(caip2: string, namespace: string, file: string): Promise<any> {
export function getNodeModulesPath(caip2: string, namespace: string, file: string) {
const [caip2Type, caip2Reference] = caip2.split(':');
const path = join(
return join(
'node_modules',
'@crypto-frontmatter',
`${caip2Type}-${caip2Reference}-${namespace}`,
'dist',
'Frontmatter',
file,
);
const contents = await readFile(path, {
encoding: 'utf-8',
});
return JSON.parse(contents);
}

export async function getInstalledFrontmatterCollection(): Promise<FrontmatterCollection[]> {
const scopePath = join('node_modules', '@crypto-frontmatter');
const collections: FrontmatterCollection[] = [];

for (const dir of await readdir(scopePath)) {
const packagePath = join(scopePath, dir, 'package.json');
if (!(await hasFile(packagePath))) {
continue;
}
const contents = await readFile(packagePath, {
encoding: 'utf-8',
});
collections.push(JSON.parse(contents).config);
}
return collections;
}

/**
* Get FrontmatterIndex collection of CAIP-2 and Asset TYPE
* Get the collection FrontmatterIndex with CAIP-2 and Asset TYPE
* @param caip2 {string}
* @param namespace {string}
* @return {FrontmatterIndex[]}
*/
export async function getFrontmatterCollection(caip2: string, namespace: string): Promise<FrontmatterIndex[]> {
return readCryptoFrontmatterFile(caip2, namespace, 'index.json');
export async function getFrontmatterIndexArray(caip2: string, namespace: string): Promise<FrontmatterIndex[]> {
const path = getNodeModulesPath(caip2, namespace, 'index.json');
const contents = await readFile(path, {
encoding: 'utf-8',
});
return JSON.parse(contents);
}

/**
Expand All @@ -120,5 +135,13 @@ export async function getFrontmatterContent(caip19: string): Promise<Frontmatter
const fileId = computeFileId(caip19);
const [caip2, asset] = caip19.split('/');
const [namespace] = asset.split(':');
return readCryptoFrontmatterFile(caip2, namespace, `${fileId}.json`);

const path = getNodeModulesPath(caip2, namespace, `${fileId}.json`);
if (!(await hasFile(path))) {
return undefined;
}
const contents = await readFile(path, {
encoding: 'utf-8',
});
return JSON.parse(contents);
}
28 changes: 25 additions & 3 deletions packages/crypto-frontmatter/src/index.unit.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { expect, it } from '@jest/globals';

import { getFrontmatterCollection, getFrontmatterContent } from './index';
import { getFrontmatterContent, getFrontmatterIndexArray, getInstalledFrontmatterCollection } from './index';

it('should getFrontmatterCollection of eip155:1/erc20', async () => {
const collection = await getFrontmatterCollection('eip155:1', 'erc20');
const collection = await getFrontmatterIndexArray('eip155:1', 'erc20');
expect(collection).toStrictEqual(
expect.arrayContaining([
expect.objectContaining({
Expand Down Expand Up @@ -42,10 +42,32 @@ it('should getFrontmatterContent of eip155:1/erc20:0x00000000008943c65cAf789FFFC
width: 512,
height: 512,
},
path: expect.stringMatching(/[0-f]{64}\.logo\.png/),
path: expect.stringMatching(/[0-9a-f]{64}\.png/),
},
],
},
html: '<h1>Dharma USD Coin</h1>',
});
});

it('should getFrontmatterContent of eip155:1/erc20:0', async () => {
const frontmatterContent = await getFrontmatterContent('eip155:1/erc20:0');
expect(frontmatterContent).toBeUndefined();
});

it('should getInstalledFrontmatterCollection', async () => {
const collections = await getInstalledFrontmatterCollection();
expect(collections).toStrictEqual([
{ caip2: 'eip155:1', namespace: 'erc20' },
{ caip2: 'eip155:10', namespace: 'erc20' },
{ caip2: 'eip155:1313161554', namespace: 'erc20' },
{ caip2: 'eip155:137', namespace: 'erc20' },
{ caip2: 'eip155:42161', namespace: 'erc20' },
{ caip2: 'eip155:42220', namespace: 'erc20' },
{ caip2: 'eip155:43114', namespace: 'erc20' },
{ caip2: 'eip155:56', namespace: 'erc20' },
{ caip2: 'eip155:8453', namespace: 'erc20' },
{ caip2: 'tip474:728126428', namespace: 'trc10' },
{ caip2: 'tip474:728126428', namespace: 'trc20' },
]);
});
4 changes: 4 additions & 0 deletions packages/eip155-1-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:1",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-10-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:10",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-1313161554-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:1313161554",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-137-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:137",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-42161-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:42161",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-42220-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:42220",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-43114-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:43114",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-56-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:56",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/eip155-8453-erc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "eip155:8453",
"namespace": "erc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/tip474-728126428-trc10/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "tip474:728126428",
"namespace": "trc10"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
4 changes: 4 additions & 0 deletions packages/tip474-728126428-trc20/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
"build": "contented build",
"clean": "rm -rf dist"
},
"config": {
"caip2": "tip474:728126428",
"namespace": "trc20"
},
"devDependencies": {
"@contentedjs/contented": "^7.1.0",
"@workspace/contented-config": "workspace:*"
Expand Down
Loading