@chain-registry/workflows 1.26.3 β†’ 1.28.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,11 +9,86 @@
9
9
  <img height="20" src="https://github.com/cosmology-tech/chain-registry/actions/workflows/run-tests.yml/badge.svg" />
10
10
  </a>
11
11
  <a href="https://github.com/cosmology-tech/chain-registry/blob/main/LICENSE"><img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
12
- <a href="https://www.npmjs.com/package/@chain-registry/workflows"><img height="20" src="https://img.shields.io/github/package-json/v/cosmology-tech/chain-registry?filename=packages%2Fworkflows%2Fpackage.json"></a>
12
+ <a href="https://www.npmjs.com/package/@chain-registry/workflows"><img height="20" src="https://img.shields.io/github/package-json/v/cosmology-tech/chain-registry?filename=workflows%2Fworkflows%2Fpackage.json"></a>
13
13
  </p>
14
14
 
15
- TODO
15
+ The `@chain-registry/workflows` is a powerful library that powers our command-line interface ([`@chain-registry/cli`](https://github.com/cosmology-tech/chain-registry/tree/main/workflows/cli)) designed to interact with the Chain Registry, allowing users to fetch information, validate data, and generate TypeScript interfaces directly from JSON schemas.
16
16
 
17
+ ## Features
18
+
19
+ πŸ” **Info**: Retrieve detailed information about chains, assets, and asset lists.
20
+
21
+ βœ… **Validate**: Check the integrity and validity of the registry data against its schemas.
22
+
23
+ πŸ› οΈ **Codegen**: Generate TypeScript definitions for use in development, ensuring type safety and adherence to the schema definitions.
24
+
25
+
26
+ ## Installation
27
+
28
+ We recommend using the CLI to use workflows. To get started with `@chain-registry/cli`, install it via npm or yarn:
29
+
30
+ ```js
31
+ npm install @chain-registry/cli
32
+ # or
33
+ yarn add @chain-registry/cli
34
+ ```
35
+
36
+ ## Table of Contents
37
+
38
+ - [Features](#features)
39
+ - [Installation](#installation)
40
+ - [Command Details](#command-details)
41
+ - [Info](#info)
42
+ - [Validate](#validate)
43
+ - [Codegen](#codegen)
44
+ - [Related Projects](#related)
45
+ - [Credits](#credits)
46
+ - [Disclaimer](#disclaimer)
47
+
48
+ ## Command Details
49
+
50
+ ### Info
51
+
52
+ Fetch and display information about entities in the chain registry:
53
+
54
+ ```sh
55
+ chain-registry info
56
+ ```
57
+
58
+ Options:
59
+
60
+ - `chain`: Fetch information specific to a chain.
61
+ - `asset-list`: Fetch asset lists associated with a specific chain.
62
+ - `asset`: Fetch detailed information about a specific asset.
63
+ - `--registryDir`: Path to the chain registry directory.
64
+
65
+ ### Validate
66
+
67
+ Validate the data in the registry against the provided JSON schemas:
68
+
69
+ ```sh
70
+ chain-registry validate
71
+ ```
72
+
73
+ Options:
74
+
75
+ - `--outputDir`: Directory to output the generated TypeScript files.
76
+ - `--registryDir`: Path to the chain registry directory.
77
+
78
+ ### Codegen
79
+
80
+ Generate TypeScript interfaces for the registry:
81
+
82
+ ```sh
83
+ chain-registry codegen --outputDir ./src --registryDir /path/to/registry
84
+ ```
85
+
86
+ Options:
87
+
88
+ - `--outputDir`: Directory to output the generated TypeScript files.
89
+ - `--registryDir`: Path to the chain registry directory.
90
+ - `--strictTypeSafety`: Enables strict TypeScript type definitions.
91
+ - `--useCamelCase`: Converts JSON schema properties to camelCase in the generated TypeScript files.
17
92
 
18
93
  ## Related
19
94
 
package/esm/index.js CHANGED
@@ -1,2 +1,3 @@
1
- export * from './fixtures';
1
+ export * from './registry';
2
2
  export * from './schema-typescript';
3
+ export * from './validator';
@@ -0,0 +1,165 @@
1
+ import { readFileSync } from 'fs';
2
+ import { sync as glob } from 'glob';
3
+ import { basename } from 'path';
4
+ const SCHEMATA_MAPPING = {
5
+ AssetList: 'assetLists',
6
+ Chain: 'chains',
7
+ IBCData: 'ibcData',
8
+ MemoKeys: 'memoKeys',
9
+ Versions: 'versions'
10
+ };
11
+ const SCHEMA_WHITELIST = [
12
+ 'assetlist.schema.json',
13
+ 'chain.schema.json',
14
+ 'ibc_data.schema.json',
15
+ 'memo_keys.schema.json',
16
+ 'versions.schema.json'
17
+ ];
18
+ const IGNORE_ROOT_DIRS = [
19
+ `_template`,
20
+ `.github`,
21
+ `.git`,
22
+ `node_modules`
23
+ ];
24
+ export class Registry {
25
+ definitions;
26
+ basePath;
27
+ schemaMappings = {
28
+ AssetList: null,
29
+ IBCData: null,
30
+ Chain: null,
31
+ MemoKeys: null,
32
+ Versions: null
33
+ };
34
+ dataMappings = {
35
+ AssetList: [],
36
+ IBCData: [],
37
+ Chain: [],
38
+ MemoKeys: [],
39
+ Versions: []
40
+ };
41
+ constructor(basePath) {
42
+ this.basePath = basePath;
43
+ this.initializeData();
44
+ }
45
+ isJsonSchema(schema) {
46
+ const $schema = schema.$schema;
47
+ if (!$schema)
48
+ return false;
49
+ return true;
50
+ }
51
+ startsWithUrl(schema) {
52
+ return (/^http/.test(schema.$schema));
53
+ }
54
+ isSchema(schema) {
55
+ if (!this.isJsonSchema(schema))
56
+ return false;
57
+ if (!this.startsWithUrl(schema))
58
+ return false;
59
+ const url = new URL(schema.$schema);
60
+ const def = url.pathname;
61
+ if (def.match(/\/draft-0[47]\/schema$/)) {
62
+ return true;
63
+ }
64
+ return false;
65
+ }
66
+ getSchemaFrom$Schema(data) {
67
+ const schema = this.definitions.find(defn => {
68
+ const pred = basename(defn.path) === data.$schemaFile;
69
+ return pred;
70
+ });
71
+ if (!schema) {
72
+ console.warn('missing schema definition: ' + data.$schemaFile);
73
+ }
74
+ return schema.content;
75
+ }
76
+ isData(schema) {
77
+ if (!this.isJsonSchema(schema))
78
+ return false;
79
+ if (this.startsWithUrl(schema))
80
+ return false;
81
+ if (SCHEMA_WHITELIST.includes(basename(schema.$schema)))
82
+ return true;
83
+ return false;
84
+ }
85
+ loadData(schema) {
86
+ if (this.isData(schema.content)) {
87
+ const defn = this.getSchemaFrom$Schema(schema);
88
+ this.dataMappings[defn.title].push(schema);
89
+ }
90
+ }
91
+ initStoreForSchema(schema) {
92
+ // if it exists return
93
+ if (this.schemaMappings[schema.content.title])
94
+ return;
95
+ // initialize
96
+ this.schemaMappings[schema.content.title] = schema;
97
+ }
98
+ initializeData() {
99
+ let types = {};
100
+ // parse every JSON file
101
+ this.definitions = glob(`${this.basePath}/**/*.json`, {
102
+ // ignore certain root directories
103
+ ignore: IGNORE_ROOT_DIRS.map(dir => `${this.basePath}/${dir}/**/*`)
104
+ })
105
+ .map(path => {
106
+ const content = JSON.parse(readFileSync(path, 'utf-8'));
107
+ if (!this.isJsonSchema(content))
108
+ return;
109
+ // https://stackoverflow.com/questions/69133771/ajv-no-schema-with-key-or-ref-https-json-schema-org-draft-07-schema
110
+ content.$schema = content.$schema.replace(/https/, 'http');
111
+ types[basename(content.$schema)] = true;
112
+ return {
113
+ $schemaFile: basename(content.$schema),
114
+ path,
115
+ content
116
+ };
117
+ }).filter(Boolean);
118
+ // filter out schemas (e.g. draft-04/schema )
119
+ const schemas = this.definitions.filter(schema => this.isSchema(schema.content)).filter(Boolean);
120
+ // validate
121
+ schemas.forEach(schema => {
122
+ if (!(schema.content.title in SCHEMATA_MAPPING))
123
+ throw new Error('MISSING SCHEMA: ' + schema.content.title);
124
+ });
125
+ // create schemaMappings and data
126
+ schemas.forEach(schema => {
127
+ this.initStoreForSchema(schema);
128
+ });
129
+ // load data
130
+ this.definitions
131
+ .filter(d => SCHEMA_WHITELIST.includes(d.$schemaFile))
132
+ .forEach(schema => {
133
+ this.loadData(schema);
134
+ });
135
+ }
136
+ get chains() {
137
+ return this.dataMappings.Chain.map(c => c.content);
138
+ }
139
+ get assetLists() {
140
+ return this.dataMappings.AssetList.map(c => c.content);
141
+ }
142
+ get ibcData() {
143
+ return this.dataMappings.IBCData.map(c => c.content);
144
+ }
145
+ get memoKeys() {
146
+ return this.dataMappings.MemoKeys.map(c => c.content);
147
+ }
148
+ get versions() {
149
+ return this.dataMappings.Versions.map(c => c.content);
150
+ }
151
+ get schemas() {
152
+ return Object.entries(this.schemaMappings).map(([_str, obj]) => {
153
+ return obj;
154
+ });
155
+ }
156
+ get count() {
157
+ return {
158
+ chains: this.chains.length,
159
+ assetLists: this.assetLists.length,
160
+ ibcData: this.ibcData.length,
161
+ memoKeys: this.memoKeys.length,
162
+ versions: this.versions.length,
163
+ };
164
+ }
165
+ }
@@ -1,3 +1,4 @@
1
+ import * as fs from 'fs';
1
2
  import { basename, dirname, join } from 'path';
2
3
  import { generateTypeScript } from 'schema-typescript';
3
4
  // Default titles for certain schemas
@@ -11,16 +12,13 @@ const DEFAULT_TITLES = {
11
12
  };
12
13
  export class SchemaTypeGenerator {
13
14
  outputDir;
14
- writeFs;
15
- readFs;
16
- schemas;
15
+ registry;
17
16
  schemaTSOptions;
18
17
  supportedSchemas;
19
18
  constructor(options) {
20
19
  this.outputDir = options.outputDir;
21
- this.writeFs = options.writeFs;
22
- this.readFs = options.readFs;
23
- this.schemas = options.schemas;
20
+ this.registry = options.registry;
21
+ this.schemaTSOptions = options.schemaTSOptions;
24
22
  this.supportedSchemas = new Set(options.supportedSchemas || []);
25
23
  }
26
24
  updateSchemaTitle(schema, schemaFile) {
@@ -36,12 +34,13 @@ export class SchemaTypeGenerator {
36
34
  return this.supportedSchemas.has(filename);
37
35
  }
38
36
  generateTypes() {
39
- this.schemas.forEach(schemaFile => {
37
+ this.registry.schemas.forEach(fileInfo => {
38
+ const schemaFile = fileInfo.path;
40
39
  if (this.isSchemaSupported(schemaFile)) {
41
40
  try {
42
- const schema = this.readJsonFile(schemaFile);
41
+ const schema = fileInfo.content;
43
42
  this.updateSchemaTitle(schema, schemaFile);
44
- const result = this.generateTypeScript(schema);
43
+ const result = generateTypeScript(schema, this.schemaTSOptions);
45
44
  const filename = this.getOutputFilename(schemaFile);
46
45
  this.ensureDirExists(filename);
47
46
  this.writeFile(filename, result);
@@ -52,20 +51,20 @@ export class SchemaTypeGenerator {
52
51
  }
53
52
  });
54
53
  }
55
- readJsonFile(filePath) {
56
- return JSON.parse(this.readFs.readFileSync(filePath, 'utf-8'));
57
- }
58
- generateTypeScript(schema) {
59
- return generateTypeScript(schema, this.schemaTSOptions);
60
- }
61
54
  getOutputFilename(schemaFile) {
62
55
  const filename = basename(schemaFile);
63
56
  return join(this.outputDir, filename.replace(/.json$/, '.ts'));
64
57
  }
65
58
  ensureDirExists(filePath) {
66
- this.writeFs.mkdirpSync(dirname(filePath));
59
+ this.mkdirpSync(dirname(filePath));
60
+ }
61
+ mkdirpSync(p) {
62
+ if (!fs.existsSync(p)) {
63
+ this.mkdirpSync(dirname(p));
64
+ fs.mkdirSync(p);
65
+ }
67
66
  }
68
67
  writeFile(filePath, content) {
69
- this.writeFs.writeFileSync(filePath, content);
68
+ fs.writeFileSync(filePath, content);
70
69
  }
71
70
  }
package/esm/utils.js ADDED
@@ -0,0 +1,10 @@
1
+ import { toCamelCase, toPascalCase } from "schema-typescript";
2
+ export const camelCase = (str) => {
3
+ if (str === 'IBCData') {
4
+ return 'ibcData';
5
+ }
6
+ return toCamelCase(str);
7
+ };
8
+ export const pascalCase = (str) => {
9
+ return toPascalCase(str);
10
+ };
@@ -0,0 +1,43 @@
1
+ import Ajv from 'ajv/dist/2019';
2
+ import addFormats from 'ajv-formats';
3
+ import chalk from 'chalk';
4
+ export class SchemaValidator {
5
+ ajv;
6
+ registry;
7
+ constructor(registry, options) {
8
+ const { useStrict = false, allErrors = true, useDefaults = true } = options ?? {};
9
+ this.ajv = new Ajv({
10
+ strict: useStrict,
11
+ allErrors,
12
+ useDefaults
13
+ });
14
+ this.registry = registry;
15
+ addFormats(this.ajv);
16
+ }
17
+ validateAllData(verbose = false) {
18
+ // Compile and validate each schema, then validate corresponding data
19
+ Object.entries(this.registry.schemaMappings).forEach(([title, schema]) => {
20
+ schema.content.$schema = 'https://json-schema.org/draft/2019-09/schema';
21
+ const validate = this.ajv.compile(schema.content);
22
+ const dataMap = this.registry.dataMappings[title];
23
+ if (!dataMap) {
24
+ console.error(chalk.yellow(`⚠️ No data found for schema titled ${chalk.bold(title)}`));
25
+ return;
26
+ }
27
+ dataMap.forEach(data => {
28
+ this.validateJsonSchema(data, title, validate, verbose);
29
+ });
30
+ });
31
+ }
32
+ validateJsonSchema(data, title, validate, verbose) {
33
+ if (!validate(data.content)) {
34
+ console.error(chalk.red(`❌ Validation errors for ${chalk.bold(title)} in file ${chalk.magenta(data.path)}:`));
35
+ validate.errors?.forEach(error => {
36
+ console.error(chalk.red(` ➑️ ${error.instancePath} ${error.message}`));
37
+ });
38
+ }
39
+ else if (verbose) {
40
+ console.log(chalk.green(`βœ… Validation passed for ${chalk.bold(title)} in file ${chalk.magenta(data.path)}`));
41
+ }
42
+ }
43
+ }
package/index.d.ts CHANGED
@@ -1,2 +1,4 @@
1
- export * from './fixtures';
1
+ export * from './registry';
2
2
  export * from './schema-typescript';
3
+ export * from './validator';
4
+ export { JSONSchema } from 'schema-typescript';
package/index.js CHANGED
@@ -14,5 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./fixtures"), exports);
17
+ __exportStar(require("./registry"), exports);
18
18
  __exportStar(require("./schema-typescript"), exports);
19
+ __exportStar(require("./validator"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chain-registry/workflows",
3
- "version": "1.26.3",
3
+ "version": "1.28.0",
4
4
  "description": "Chain Registry Workflows",
5
5
  "author": "Dan Lynch <pyramation@gmail.com>",
6
6
  "homepage": "https://github.com/cosmology-tech/chain-registry",
@@ -32,18 +32,23 @@
32
32
  "strfy-js": "^2.2.2"
33
33
  },
34
34
  "dependencies": {
35
- "@chain-registry/types": "^0.25.3",
35
+ "@chain-registry/interfaces": "^0.27.0",
36
+ "ajv": "^8.12.0",
37
+ "ajv-formats": "^3.0.1",
36
38
  "bignumber.js": "9.1.1",
39
+ "chalk": "^4.1.0",
37
40
  "file-ts": "^0.7.15",
41
+ "glob": "^7.1.4",
38
42
  "minimatch": "^9.0.4",
39
- "schema-typescript": "^0.2.4",
40
- "sha.js": "^2.4.11",
41
- "strfy-js": "^2.2.2"
43
+ "mkdirp": "3.0.1",
44
+ "schema-typescript": "^0.2.5",
45
+ "sha.js": "^2.4.11"
42
46
  },
43
47
  "keywords": [
44
48
  "chain-registry",
45
49
  "web3",
46
50
  "cosmos",
47
51
  "interchain"
48
- ]
52
+ ],
53
+ "gitHead": "7478b00e390b053976e2a5f502d9b407e861c69d"
49
54
  }
package/registry.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { AssetList, Chain, IBCData, MemoKeys, Versions } from '@chain-registry/interfaces';
2
+ import { JSONSchema } from "schema-typescript";
3
+ export interface JSONSchemaContent<T> {
4
+ $schemaFile: string;
5
+ path: string;
6
+ content: T;
7
+ }
8
+ export interface DataMapping {
9
+ AssetList: JSONSchemaContent<AssetList>[];
10
+ IBCData: JSONSchemaContent<IBCData>[];
11
+ Chain: JSONSchemaContent<Chain>[];
12
+ MemoKeys: JSONSchemaContent<MemoKeys>[];
13
+ Versions: JSONSchemaContent<Versions>[];
14
+ }
15
+ export interface SchemaMapping {
16
+ AssetList: JSONSchemaContent<JSONSchema>;
17
+ IBCData: JSONSchemaContent<JSONSchema>;
18
+ Chain: JSONSchemaContent<JSONSchema>;
19
+ MemoKeys: JSONSchemaContent<JSONSchema>;
20
+ Versions: JSONSchemaContent<JSONSchema>;
21
+ }
22
+ export declare class Registry {
23
+ private definitions;
24
+ basePath: string;
25
+ schemaMappings: SchemaMapping;
26
+ dataMappings: DataMapping;
27
+ constructor(basePath: string);
28
+ private isJsonSchema;
29
+ private startsWithUrl;
30
+ private isSchema;
31
+ private getSchemaFrom$Schema;
32
+ private isData;
33
+ private loadData;
34
+ private initStoreForSchema;
35
+ private initializeData;
36
+ get chains(): Chain[];
37
+ get assetLists(): AssetList[];
38
+ get ibcData(): IBCData[];
39
+ get memoKeys(): MemoKeys[];
40
+ get versions(): Versions[];
41
+ get schemas(): JSONSchemaContent<JSONSchema>[];
42
+ get count(): {
43
+ chains: number;
44
+ assetLists: number;
45
+ ibcData: number;
46
+ memoKeys: number;
47
+ versions: number;
48
+ };
49
+ }
package/registry.js ADDED
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Registry = void 0;
4
+ const fs_1 = require("fs");
5
+ const glob_1 = require("glob");
6
+ const path_1 = require("path");
7
+ const SCHEMATA_MAPPING = {
8
+ AssetList: 'assetLists',
9
+ Chain: 'chains',
10
+ IBCData: 'ibcData',
11
+ MemoKeys: 'memoKeys',
12
+ Versions: 'versions'
13
+ };
14
+ const SCHEMA_WHITELIST = [
15
+ 'assetlist.schema.json',
16
+ 'chain.schema.json',
17
+ 'ibc_data.schema.json',
18
+ 'memo_keys.schema.json',
19
+ 'versions.schema.json'
20
+ ];
21
+ const IGNORE_ROOT_DIRS = [
22
+ `_template`,
23
+ `.github`,
24
+ `.git`,
25
+ `node_modules`
26
+ ];
27
+ class Registry {
28
+ definitions;
29
+ basePath;
30
+ schemaMappings = {
31
+ AssetList: null,
32
+ IBCData: null,
33
+ Chain: null,
34
+ MemoKeys: null,
35
+ Versions: null
36
+ };
37
+ dataMappings = {
38
+ AssetList: [],
39
+ IBCData: [],
40
+ Chain: [],
41
+ MemoKeys: [],
42
+ Versions: []
43
+ };
44
+ constructor(basePath) {
45
+ this.basePath = basePath;
46
+ this.initializeData();
47
+ }
48
+ isJsonSchema(schema) {
49
+ const $schema = schema.$schema;
50
+ if (!$schema)
51
+ return false;
52
+ return true;
53
+ }
54
+ startsWithUrl(schema) {
55
+ return (/^http/.test(schema.$schema));
56
+ }
57
+ isSchema(schema) {
58
+ if (!this.isJsonSchema(schema))
59
+ return false;
60
+ if (!this.startsWithUrl(schema))
61
+ return false;
62
+ const url = new URL(schema.$schema);
63
+ const def = url.pathname;
64
+ if (def.match(/\/draft-0[47]\/schema$/)) {
65
+ return true;
66
+ }
67
+ return false;
68
+ }
69
+ getSchemaFrom$Schema(data) {
70
+ const schema = this.definitions.find(defn => {
71
+ const pred = (0, path_1.basename)(defn.path) === data.$schemaFile;
72
+ return pred;
73
+ });
74
+ if (!schema) {
75
+ console.warn('missing schema definition: ' + data.$schemaFile);
76
+ }
77
+ return schema.content;
78
+ }
79
+ isData(schema) {
80
+ if (!this.isJsonSchema(schema))
81
+ return false;
82
+ if (this.startsWithUrl(schema))
83
+ return false;
84
+ if (SCHEMA_WHITELIST.includes((0, path_1.basename)(schema.$schema)))
85
+ return true;
86
+ return false;
87
+ }
88
+ loadData(schema) {
89
+ if (this.isData(schema.content)) {
90
+ const defn = this.getSchemaFrom$Schema(schema);
91
+ this.dataMappings[defn.title].push(schema);
92
+ }
93
+ }
94
+ initStoreForSchema(schema) {
95
+ // if it exists return
96
+ if (this.schemaMappings[schema.content.title])
97
+ return;
98
+ // initialize
99
+ this.schemaMappings[schema.content.title] = schema;
100
+ }
101
+ initializeData() {
102
+ let types = {};
103
+ // parse every JSON file
104
+ this.definitions = (0, glob_1.sync)(`${this.basePath}/**/*.json`, {
105
+ // ignore certain root directories
106
+ ignore: IGNORE_ROOT_DIRS.map(dir => `${this.basePath}/${dir}/**/*`)
107
+ })
108
+ .map(path => {
109
+ const content = JSON.parse((0, fs_1.readFileSync)(path, 'utf-8'));
110
+ if (!this.isJsonSchema(content))
111
+ return;
112
+ // https://stackoverflow.com/questions/69133771/ajv-no-schema-with-key-or-ref-https-json-schema-org-draft-07-schema
113
+ content.$schema = content.$schema.replace(/https/, 'http');
114
+ types[(0, path_1.basename)(content.$schema)] = true;
115
+ return {
116
+ $schemaFile: (0, path_1.basename)(content.$schema),
117
+ path,
118
+ content
119
+ };
120
+ }).filter(Boolean);
121
+ // filter out schemas (e.g. draft-04/schema )
122
+ const schemas = this.definitions.filter(schema => this.isSchema(schema.content)).filter(Boolean);
123
+ // validate
124
+ schemas.forEach(schema => {
125
+ if (!(schema.content.title in SCHEMATA_MAPPING))
126
+ throw new Error('MISSING SCHEMA: ' + schema.content.title);
127
+ });
128
+ // create schemaMappings and data
129
+ schemas.forEach(schema => {
130
+ this.initStoreForSchema(schema);
131
+ });
132
+ // load data
133
+ this.definitions
134
+ .filter(d => SCHEMA_WHITELIST.includes(d.$schemaFile))
135
+ .forEach(schema => {
136
+ this.loadData(schema);
137
+ });
138
+ }
139
+ get chains() {
140
+ return this.dataMappings.Chain.map(c => c.content);
141
+ }
142
+ get assetLists() {
143
+ return this.dataMappings.AssetList.map(c => c.content);
144
+ }
145
+ get ibcData() {
146
+ return this.dataMappings.IBCData.map(c => c.content);
147
+ }
148
+ get memoKeys() {
149
+ return this.dataMappings.MemoKeys.map(c => c.content);
150
+ }
151
+ get versions() {
152
+ return this.dataMappings.Versions.map(c => c.content);
153
+ }
154
+ get schemas() {
155
+ return Object.entries(this.schemaMappings).map(([_str, obj]) => {
156
+ return obj;
157
+ });
158
+ }
159
+ get count() {
160
+ return {
161
+ chains: this.chains.length,
162
+ assetLists: this.assetLists.length,
163
+ ibcData: this.ibcData.length,
164
+ memoKeys: this.memoKeys.length,
165
+ versions: this.versions.length,
166
+ };
167
+ }
168
+ }
169
+ exports.Registry = Registry;
@@ -1,31 +1,22 @@
1
1
  import { SchemaTSOptions } from 'schema-typescript';
2
- export interface FileSystem {
3
- readFileSync(path: string, encoding: string): string;
4
- writeFileSync(path: string, data: string): void;
5
- mkdirpSync(path: string): void;
6
- }
2
+ import { Registry } from './registry';
7
3
  export interface SchemaTypeGeneratorOptions {
8
4
  outputDir: string;
9
5
  schemaTSOptions: Partial<SchemaTSOptions>;
10
- readFs: FileSystem;
11
- writeFs: FileSystem;
12
- schemas: string[];
13
6
  supportedSchemas?: string[];
7
+ registry: Registry;
14
8
  }
15
9
  export declare class SchemaTypeGenerator {
16
10
  private outputDir;
17
- private writeFs;
18
- private readFs;
19
- private schemas;
11
+ private registry;
20
12
  private schemaTSOptions;
21
13
  private supportedSchemas;
22
14
  constructor(options: SchemaTypeGeneratorOptions);
23
15
  private updateSchemaTitle;
24
16
  private isSchemaSupported;
25
17
  generateTypes(): void;
26
- private readJsonFile;
27
- private generateTypeScript;
28
18
  private getOutputFilename;
29
19
  private ensureDirExists;
20
+ private mkdirpSync;
30
21
  private writeFile;
31
22
  }
@@ -1,6 +1,30 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
2
25
  Object.defineProperty(exports, "__esModule", { value: true });
3
26
  exports.SchemaTypeGenerator = void 0;
27
+ const fs = __importStar(require("fs"));
4
28
  const path_1 = require("path");
5
29
  const schema_typescript_1 = require("schema-typescript");
6
30
  // Default titles for certain schemas
@@ -14,16 +38,13 @@ const DEFAULT_TITLES = {
14
38
  };
15
39
  class SchemaTypeGenerator {
16
40
  outputDir;
17
- writeFs;
18
- readFs;
19
- schemas;
41
+ registry;
20
42
  schemaTSOptions;
21
43
  supportedSchemas;
22
44
  constructor(options) {
23
45
  this.outputDir = options.outputDir;
24
- this.writeFs = options.writeFs;
25
- this.readFs = options.readFs;
26
- this.schemas = options.schemas;
46
+ this.registry = options.registry;
47
+ this.schemaTSOptions = options.schemaTSOptions;
27
48
  this.supportedSchemas = new Set(options.supportedSchemas || []);
28
49
  }
29
50
  updateSchemaTitle(schema, schemaFile) {
@@ -39,12 +60,13 @@ class SchemaTypeGenerator {
39
60
  return this.supportedSchemas.has(filename);
40
61
  }
41
62
  generateTypes() {
42
- this.schemas.forEach(schemaFile => {
63
+ this.registry.schemas.forEach(fileInfo => {
64
+ const schemaFile = fileInfo.path;
43
65
  if (this.isSchemaSupported(schemaFile)) {
44
66
  try {
45
- const schema = this.readJsonFile(schemaFile);
67
+ const schema = fileInfo.content;
46
68
  this.updateSchemaTitle(schema, schemaFile);
47
- const result = this.generateTypeScript(schema);
69
+ const result = (0, schema_typescript_1.generateTypeScript)(schema, this.schemaTSOptions);
48
70
  const filename = this.getOutputFilename(schemaFile);
49
71
  this.ensureDirExists(filename);
50
72
  this.writeFile(filename, result);
@@ -55,21 +77,21 @@ class SchemaTypeGenerator {
55
77
  }
56
78
  });
57
79
  }
58
- readJsonFile(filePath) {
59
- return JSON.parse(this.readFs.readFileSync(filePath, 'utf-8'));
60
- }
61
- generateTypeScript(schema) {
62
- return (0, schema_typescript_1.generateTypeScript)(schema, this.schemaTSOptions);
63
- }
64
80
  getOutputFilename(schemaFile) {
65
81
  const filename = (0, path_1.basename)(schemaFile);
66
82
  return (0, path_1.join)(this.outputDir, filename.replace(/.json$/, '.ts'));
67
83
  }
68
84
  ensureDirExists(filePath) {
69
- this.writeFs.mkdirpSync((0, path_1.dirname)(filePath));
85
+ this.mkdirpSync((0, path_1.dirname)(filePath));
86
+ }
87
+ mkdirpSync(p) {
88
+ if (!fs.existsSync(p)) {
89
+ this.mkdirpSync((0, path_1.dirname)(p));
90
+ fs.mkdirSync(p);
91
+ }
70
92
  }
71
93
  writeFile(filePath, content) {
72
- this.writeFs.writeFileSync(filePath, content);
94
+ fs.writeFileSync(filePath, content);
73
95
  }
74
96
  }
75
97
  exports.SchemaTypeGenerator = SchemaTypeGenerator;
package/utils.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare const camelCase: (str: string) => string;
2
+ export declare const pascalCase: (str: string) => string;
package/utils.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.pascalCase = exports.camelCase = void 0;
4
+ const schema_typescript_1 = require("schema-typescript");
5
+ const camelCase = (str) => {
6
+ if (str === 'IBCData') {
7
+ return 'ibcData';
8
+ }
9
+ return (0, schema_typescript_1.toCamelCase)(str);
10
+ };
11
+ exports.camelCase = camelCase;
12
+ const pascalCase = (str) => {
13
+ return (0, schema_typescript_1.toPascalCase)(str);
14
+ };
15
+ exports.pascalCase = pascalCase;
package/validator.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { Registry } from './registry';
2
+ export interface SchemaValidatorOptions {
3
+ useStrict?: boolean;
4
+ allErrors?: boolean;
5
+ useDefaults?: boolean;
6
+ }
7
+ export declare class SchemaValidator {
8
+ private ajv;
9
+ private registry;
10
+ constructor(registry: Registry, options?: SchemaValidatorOptions);
11
+ validateAllData(verbose?: boolean): void;
12
+ private validateJsonSchema;
13
+ }
package/validator.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SchemaValidator = void 0;
7
+ const _2019_1 = __importDefault(require("ajv/dist/2019"));
8
+ const ajv_formats_1 = __importDefault(require("ajv-formats"));
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ class SchemaValidator {
11
+ ajv;
12
+ registry;
13
+ constructor(registry, options) {
14
+ const { useStrict = false, allErrors = true, useDefaults = true } = options ?? {};
15
+ this.ajv = new _2019_1.default({
16
+ strict: useStrict,
17
+ allErrors,
18
+ useDefaults
19
+ });
20
+ this.registry = registry;
21
+ (0, ajv_formats_1.default)(this.ajv);
22
+ }
23
+ validateAllData(verbose = false) {
24
+ // Compile and validate each schema, then validate corresponding data
25
+ Object.entries(this.registry.schemaMappings).forEach(([title, schema]) => {
26
+ schema.content.$schema = 'https://json-schema.org/draft/2019-09/schema';
27
+ const validate = this.ajv.compile(schema.content);
28
+ const dataMap = this.registry.dataMappings[title];
29
+ if (!dataMap) {
30
+ console.error(chalk_1.default.yellow(`⚠️ No data found for schema titled ${chalk_1.default.bold(title)}`));
31
+ return;
32
+ }
33
+ dataMap.forEach(data => {
34
+ this.validateJsonSchema(data, title, validate, verbose);
35
+ });
36
+ });
37
+ }
38
+ validateJsonSchema(data, title, validate, verbose) {
39
+ if (!validate(data.content)) {
40
+ console.error(chalk_1.default.red(`❌ Validation errors for ${chalk_1.default.bold(title)} in file ${chalk_1.default.magenta(data.path)}:`));
41
+ validate.errors?.forEach(error => {
42
+ console.error(chalk_1.default.red(` ➑️ ${error.instancePath} ${error.message}`));
43
+ });
44
+ }
45
+ else if (verbose) {
46
+ console.log(chalk_1.default.green(`βœ… Validation passed for ${chalk_1.default.bold(title)} in file ${chalk_1.default.magenta(data.path)}`));
47
+ }
48
+ }
49
+ }
50
+ exports.SchemaValidator = SchemaValidator;
package/dist/LICENSE DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2024 Dan Lynch <pyramation@gmail.com>
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
package/dist/README.md DELETED
@@ -1,39 +0,0 @@
1
- # @chain-registry/workflows
2
-
3
- <p align="center" width="100%">
4
- <img height="90" src="https://user-images.githubusercontent.com/545047/190171475-b416f99e-2831-4786-9ba3-a7ff4d95b0d3.svg" />
5
- </p>
6
-
7
- <p align="center" width="100%">
8
- <a href="https://github.com/cosmology-tech/chain-registry/actions/workflows/run-tests.yml">
9
- <img height="20" src="https://github.com/cosmology-tech/chain-registry/actions/workflows/run-tests.yml/badge.svg" />
10
- </a>
11
- <a href="https://github.com/cosmology-tech/chain-registry/blob/main/LICENSE"><img height="20" src="https://img.shields.io/badge/license-MIT-blue.svg"></a>
12
- <a href="https://www.npmjs.com/package/@chain-registry/workflows"><img height="20" src="https://img.shields.io/github/package-json/v/cosmology-tech/chain-registry?filename=packages%2Fworkflows%2Fpackage.json"></a>
13
- </p>
14
-
15
- TODO
16
-
17
-
18
- ## Related
19
-
20
- Checkout these related projects:
21
-
22
- * [@cosmology/telescope](https://github.com/cosmology-tech/telescope) Your Frontend Companion for Building with TypeScript with Cosmos SDK Modules.
23
- * [@cosmwasm/ts-codegen](https://github.com/CosmWasm/ts-codegen) Convert your CosmWasm smart contracts into dev-friendly TypeScript classes.
24
- * [chain-registry](https://github.com/cosmology-tech/chain-registry) Everything from token symbols, logos, and IBC denominations for all assets you want to support in your application.
25
- * [cosmos-kit](https://github.com/cosmology-tech/cosmos-kit) Experience the convenience of connecting with a variety of web3 wallets through a single, streamlined interface.
26
- * [create-cosmos-app](https://github.com/cosmology-tech/create-cosmos-app) Set up a modern Cosmos app by running one command.
27
- * [interchain-ui](https://github.com/cosmology-tech/interchain-ui) The Interchain Design System, empowering developers with a flexible, easy-to-use UI kit.
28
- * [starship](https://github.com/cosmology-tech/starship) Unified Testing and Development for the Interchain.
29
-
30
- ## Credits
31
-
32
- πŸ›  Built by Cosmology β€”Β if you like our tools, please consider delegating to [our validator βš›οΈ](https://cosmology.zone/validator)
33
-
34
-
35
- ## Disclaimer
36
-
37
- AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED β€œAS IS”, AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
38
-
39
- No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
package/dist/package.json DELETED
@@ -1,49 +0,0 @@
1
- {
2
- "name": "@chain-registry/workflows",
3
- "version": "1.26.3",
4
- "description": "Chain Registry Workflows",
5
- "author": "Dan Lynch <pyramation@gmail.com>",
6
- "homepage": "https://github.com/cosmology-tech/chain-registry",
7
- "license": "SEE LICENSE IN LICENSE",
8
- "main": "index.js",
9
- "module": "esm/index.js",
10
- "types": "index.d.ts",
11
- "publishConfig": {
12
- "access": "public",
13
- "directory": "dist"
14
- },
15
- "repository": {
16
- "type": "git",
17
- "url": "https://github.com/cosmology-tech/chain-registry"
18
- },
19
- "bugs": {
20
- "url": "https://github.com/cosmology-tech/chain-registry/issues"
21
- },
22
- "scripts": {
23
- "copy": "copyfiles -f LICENSE README.md package.json dist",
24
- "clean": "del dist/**",
25
- "prepare": "npm run build",
26
- "build": "npm run clean; tsc; tsc -p tsconfig.esm.json; npm run copy",
27
- "test": "jest",
28
- "test:watch": "jest --watch"
29
- },
30
- "devDependencies": {
31
- "@types/sha.js": "^2.4.0",
32
- "strfy-js": "^2.2.2"
33
- },
34
- "dependencies": {
35
- "@chain-registry/types": "^0.25.3",
36
- "bignumber.js": "9.1.1",
37
- "file-ts": "^0.7.15",
38
- "minimatch": "^9.0.4",
39
- "schema-typescript": "^0.2.4",
40
- "sha.js": "^2.4.11",
41
- "strfy-js": "^2.2.2"
42
- },
43
- "keywords": [
44
- "chain-registry",
45
- "web3",
46
- "cosmos",
47
- "interchain"
48
- ]
49
- }
package/esm/fixtures.js DELETED
@@ -1,36 +0,0 @@
1
- import { sync as glob } from "glob";
2
- import { basename, dirname, join, relative } from "path";
3
- export const NON_INFO_DIRS = [
4
- '_memo_keys',
5
- '_scripts',
6
- '_template',
7
- '.github'
8
- ];
9
- const REG_DIR = 'chain-registry/chain-registry';
10
- export const registryDir = join(__dirname, `/../../../packages/${REG_DIR}`);
11
- // Helper function to filter and map file paths
12
- function filterAndMapFiles(paths) {
13
- return paths.filter(path => {
14
- const relativePath = path.split(REG_DIR)[1];
15
- const dir = basename(dirname(relativePath));
16
- return !NON_INFO_DIRS.includes(dir);
17
- }).map(path => {
18
- const relativePath = path.split(REG_DIR)[1];
19
- return {
20
- filepath: relativePath,
21
- origpath: relative(process.cwd(), path)
22
- };
23
- });
24
- }
25
- // Glob patterns for different JSON files
26
- const globPatterns = {
27
- chains: `${registryDir}/**/chain.json`,
28
- assetLists: `${registryDir}/**/assetlist.json`,
29
- ibcInfo: `${registryDir}/**/_IBC/*-*.json`,
30
- schemas: `${registryDir}/*.schema.json`
31
- };
32
- // Using the helper function to process files
33
- export const chains = filterAndMapFiles(glob(globPatterns.chains));
34
- export const assetLists = filterAndMapFiles(glob(globPatterns.assetLists));
35
- export const ibcInfo = filterAndMapFiles(glob(globPatterns.ibcInfo));
36
- export const schemas = glob(globPatterns.schemas);
package/fixtures.d.ts DELETED
@@ -1,11 +0,0 @@
1
- export declare const NON_INFO_DIRS: string[];
2
- export declare const registryDir: string;
3
- interface FilePathInfo {
4
- filepath: string;
5
- origpath: string;
6
- }
7
- export declare const chains: FilePathInfo[];
8
- export declare const assetLists: FilePathInfo[];
9
- export declare const ibcInfo: FilePathInfo[];
10
- export declare const schemas: string[];
11
- export {};
package/fixtures.js DELETED
@@ -1,39 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.schemas = exports.ibcInfo = exports.assetLists = exports.chains = exports.registryDir = exports.NON_INFO_DIRS = void 0;
4
- const glob_1 = require("glob");
5
- const path_1 = require("path");
6
- exports.NON_INFO_DIRS = [
7
- '_memo_keys',
8
- '_scripts',
9
- '_template',
10
- '.github'
11
- ];
12
- const REG_DIR = 'chain-registry/chain-registry';
13
- exports.registryDir = (0, path_1.join)(__dirname, `/../../../packages/${REG_DIR}`);
14
- // Helper function to filter and map file paths
15
- function filterAndMapFiles(paths) {
16
- return paths.filter(path => {
17
- const relativePath = path.split(REG_DIR)[1];
18
- const dir = (0, path_1.basename)((0, path_1.dirname)(relativePath));
19
- return !exports.NON_INFO_DIRS.includes(dir);
20
- }).map(path => {
21
- const relativePath = path.split(REG_DIR)[1];
22
- return {
23
- filepath: relativePath,
24
- origpath: (0, path_1.relative)(process.cwd(), path)
25
- };
26
- });
27
- }
28
- // Glob patterns for different JSON files
29
- const globPatterns = {
30
- chains: `${exports.registryDir}/**/chain.json`,
31
- assetLists: `${exports.registryDir}/**/assetlist.json`,
32
- ibcInfo: `${exports.registryDir}/**/_IBC/*-*.json`,
33
- schemas: `${exports.registryDir}/*.schema.json`
34
- };
35
- // Using the helper function to process files
36
- exports.chains = filterAndMapFiles((0, glob_1.sync)(globPatterns.chains));
37
- exports.assetLists = filterAndMapFiles((0, glob_1.sync)(globPatterns.assetLists));
38
- exports.ibcInfo = filterAndMapFiles((0, glob_1.sync)(globPatterns.ibcInfo));
39
- exports.schemas = (0, glob_1.sync)(globPatterns.schemas);