-
Notifications
You must be signed in to change notification settings - Fork 222
/
Copy pathutils.ts
101 lines (85 loc) · 3.56 KB
/
utils.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import yaml from 'js-yaml';
import debug from './debug.js';
const utilsDebug = debug('graph-cli:utils');
export const createIpfsClient = (await import('kubo-rpc-client')).create;
export async function loadSubgraphSchemaFromIPFS(ipfsClient: any, manifest: string) {
try {
const manifestBuffer = ipfsClient.cat(manifest);
let manifestFile = '';
for await (const chunk of manifestBuffer) {
manifestFile += Buffer.from(chunk).toString('utf8'); // Explicitly convert each chunk to UTF-8
}
const manifestYaml: any = yaml.load(manifestFile);
let schema = manifestYaml.schema.file['/'];
if (schema.startsWith('/ipfs/')) {
schema = schema.slice(6);
}
const schemaBuffer = ipfsClient.cat(schema);
let schemaFile = '';
for await (const chunk of schemaBuffer) {
schemaFile += Buffer.from(chunk).toString('utf8'); // Explicitly convert each chunk to UTF-8
}
return schemaFile;
} catch (e) {
utilsDebug.extend('loadSubgraphSchemaFromIPFS')(`Failed to load schema from IPFS ${manifest}`);
utilsDebug.extend('loadSubgraphSchemaFromIPFS')(e);
throw Error(`Failed to load schema from IPFS ${manifest}`);
}
}
export async function loadManifestFromIPFS(ipfsClient: any, manifest: string) {
try {
const manifestBuffer = ipfsClient.cat(manifest);
let manifestFile = '';
for await (const chunk of manifestBuffer) {
manifestFile += Buffer.from(chunk).toString('utf8');
}
return manifestFile;
} catch (e) {
utilsDebug.extend('loadManifestFromIPFS')(`Failed to load manifest from IPFS ${manifest}`);
utilsDebug.extend('loadManifestFromIPFS')(e);
throw Error(`Failed to load manifest from IPFS ${manifest}`);
}
}
export async function loadManifestYaml(ipfsClient: any, manifest: string): Promise<any> {
const manifestFile = await loadManifestFromIPFS(ipfsClient, manifest);
return yaml.load(manifestFile) as any;
}
/**
* Validates that the network of a source subgraph matches the target network
* @param manifestYaml Parsed manifest YAML
* @param targetNetwork Network of the target subgraph being created
* @returns Object containing validation result and error message if any
*/
export function validateSubgraphNetworkMatch(
manifestYaml: any,
targetNetwork: string,
): { valid: boolean; error?: string } {
// Extract network from data sources
const dataSources = manifestYaml.dataSources || [];
const templates = manifestYaml.templates || [];
const allSources = [...dataSources, ...templates];
if (allSources.length === 0) {
return { valid: true }; // No data sources to validate
}
// Get network from first data source
const sourceNetwork = allSources[0].network;
if (sourceNetwork !== targetNetwork) {
return {
valid: false,
error: `Network mismatch: The source subgraph is indexing the '${sourceNetwork}' network, but you're creating a subgraph for '${targetNetwork}' network. When composing subgraphs, they must index the same network.`,
};
}
return { valid: true };
}
/**
* Gets the minimum startBlock from all dataSources in the manifest
* @param manifestYaml Parsed manifest YAML
* @returns The minimum startBlock or undefined if no startBlock is found
*/
export function getMinStartBlock(manifestYaml: any): number | undefined {
const dataSources = manifestYaml.dataSources || [];
const startBlocks = dataSources
.map((ds: { source?: { startBlock?: number } }) => ds.source?.startBlock)
.filter((block: unknown): block is number => typeof block === 'number');
return startBlocks.length > 0 ? Math.min(...startBlocks) : undefined;
}