@polkadot-api/cli 0.19.5-canary.d6be873 → 0.20.1-canary.ccfb151
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/dist/index.d.ts +2 -1
- package/dist/main/package.json.js +4 -0
- package/dist/main/package.json.js.map +1 -0
- package/dist/main/src/cli.js +49 -0
- package/dist/main/src/cli.js.map +1 -0
- package/dist/main/src/commands/add.js +91 -0
- package/dist/main/src/commands/add.js.map +1 -0
- package/dist/main/src/commands/generate.js +459 -0
- package/dist/main/src/commands/generate.js.map +1 -0
- package/dist/main/src/commands/ink.js +53 -0
- package/dist/main/src/commands/ink.js.map +1 -0
- package/dist/main/src/commands/remove.js +21 -0
- package/dist/main/src/commands/remove.js.map +1 -0
- package/dist/main/src/commands/sol.js +51 -0
- package/dist/main/src/commands/sol.js.map +1 -0
- package/dist/main/src/commands/update.js +56 -0
- package/dist/main/src/commands/update.js.map +1 -0
- package/dist/main/src/main.js +12 -0
- package/dist/main/src/main.js.map +1 -0
- package/dist/main/src/metadata.js +175 -0
- package/dist/main/src/metadata.js.map +1 -0
- package/dist/main/src/packageManager.js +70 -0
- package/dist/main/src/packageManager.js.map +1 -0
- package/dist/main/src/papiConfig.js +103 -0
- package/dist/main/src/papiConfig.js.map +1 -0
- package/dist/main/src/version.js +6 -0
- package/dist/main/src/version.js.map +1 -0
- package/dist/package.json.js +4 -0
- package/dist/package.json.js.map +1 -0
- package/dist/src/cli.js +49 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/add.js +91 -0
- package/dist/src/commands/add.js.map +1 -0
- package/dist/src/commands/generate.js +459 -0
- package/dist/src/commands/generate.js.map +1 -0
- package/dist/src/commands/ink.js +53 -0
- package/dist/src/commands/ink.js.map +1 -0
- package/dist/src/commands/remove.js +21 -0
- package/dist/src/commands/remove.js.map +1 -0
- package/dist/src/commands/sol.js +51 -0
- package/dist/src/commands/sol.js.map +1 -0
- package/dist/src/commands/update.js +56 -0
- package/dist/src/commands/update.js.map +1 -0
- package/dist/src/index.js +9 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/metadata.js +175 -0
- package/dist/src/metadata.js.map +1 -0
- package/dist/src/packageManager.js +70 -0
- package/dist/src/packageManager.js.map +1 -0
- package/dist/src/papiConfig.js +103 -0
- package/dist/src/papiConfig.js.map +1 -0
- package/dist/src/version.js +6 -0
- package/dist/src/version.js.map +1 -0
- package/package.json +29 -26
- package/dist/chunk-YWAERR2C.js +0 -1127
- package/dist/chunk-YWAERR2C.js.map +0 -1
- package/dist/index.js +0 -21
- package/dist/index.js.map +0 -1
- package/dist/main.js +0 -15
- package/dist/main.js.map +0 -1
- /package/dist/{main.d.ts → main/main.d.ts} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sources":["../../../../src/commands/generate.ts"],"sourcesContent":["import { getMetadata } from \"@/metadata\"\nimport { readPapiConfig } from \"@/papiConfig\"\nimport { cliVersion } from \"@/version\"\nimport {\n capitalize,\n generateInkTypes,\n generateMultipleDescriptors,\n generateSolTypes,\n type KnownTypes,\n} from \"@polkadot-api/codegen\"\nimport { getInkLookup } from \"@polkadot-api/ink-contracts\"\nimport {\n EntryPointCodec,\n TypedefCodec,\n} from \"@polkadot-api/metadata-compatibility\"\nimport {\n Binary,\n Blake2128,\n h64,\n HexString,\n Tuple,\n UnifiedMetadata,\n Vector,\n} from \"@polkadot-api/substrate-bindings\"\nimport { toHex } from \"@polkadot-api/utils\"\nimport { spawn } from \"child_process\"\nimport { existsSync } from \"fs\"\nimport fsExists from \"fs.promises.exists\"\nimport fs, { mkdtemp, rm } from \"fs/promises\"\nimport { tmpdir } from \"os\"\nimport path, { join } from \"path\"\nimport process from \"process\"\nimport { readPackage } from \"read-pkg\"\nimport { rollup, RollupBuild } from \"rollup\"\nimport esbuild from \"rollup-plugin-esbuild\"\nimport tsc from \"tsc-prog\"\nimport { updatePackage } from \"write-package\"\nimport { detectPackageManager } from \"../packageManager\"\nimport { CommonOptions } from \"./commonOptions\"\n\nexport interface GenerateOptions extends CommonOptions {\n clientLibrary?: string\n}\n\nexport async function generate(opts: GenerateOptions) {\n if (process.env.PAPI_SKIP_GENERATE) {\n return\n }\n if (opts.whitelist) {\n console.error(\n \"The --whitelist option has been removed. The whitelist should be placed at `.papi/whitelist.ts`\",\n )\n process.exit(1)\n }\n\n const config = await readPapiConfig(opts.config)\n if (!config) {\n throw new Error(\"Can't find the Polkadot-API configuration\")\n }\n const sources = config.entries\n\n if (Object.keys(sources).length == 0) {\n console.log(\"No chains defined in config file\")\n }\n\n console.log(`Reading metadata`)\n const chains = await Promise.all(\n Object.entries(sources).map(async ([key, source]) => ({\n key,\n ...(await getMetadata(source))!,\n knownTypes: {},\n })),\n )\n\n const contracts = Object.fromEntries(\n await Promise.all(\n ([\"ink\", \"sol\"] as const).map(async (kind) => [\n kind,\n Object.fromEntries(\n await Promise.all(\n Object.entries(config[kind] ?? {}).map(async ([key, v]) => [\n key,\n toHex(Blake2128(Binary.fromText(await fs.readFile(v, \"utf-8\")))),\n ]),\n ),\n ),\n ]),\n ),\n )\n\n if (chains.length === 0) {\n console.log(\"No entries in polkadot-api.json. Nothing to generate.\")\n return\n }\n\n const whitelist = await readWhitelist(\".papi/whitelist.ts\")\n\n const descriptorsDir = join(process.cwd(), config.descriptorPath)\n if (await alreadyGenerated(descriptorsDir, chains, contracts, whitelist)) {\n console.log(\"Detected previous descriptors with no changes needed.\")\n return\n }\n\n console.log(`Generating descriptors`)\n await cleanDescriptorsPackage(config.descriptorPath)\n if (!config.options?.noDescriptorsPackage) {\n await addDescriptorsToPackageJson(config.descriptorPath)\n }\n\n const clientPath = opts.clientLibrary ?? \"polkadot-api\"\n\n const descriptorSrcDir = join(descriptorsDir, \"src\")\n const hash = await outputCodegen(\n chains,\n descriptorSrcDir,\n clientPath,\n whitelist,\n )\n\n if (config.ink || config.sol) {\n outputContractCodegen(config, descriptorSrcDir)\n }\n\n await replacePackageJson(descriptorsDir, hash)\n const cleanCodegen = await compileCodegen(descriptorsDir)\n if (cleanCodegen) {\n await tagGenerated(descriptorsDir, chains, contracts, whitelist)\n await fs.rm(descriptorSrcDir, { recursive: true })\n }\n if (!config.options?.noDescriptorsPackage) {\n await runInstall()\n await flushBundlerCache()\n }\n}\n\nasync function tagGenerated(\n descriptorsDir: string,\n chains: {\n key: string\n metadataRaw: Uint8Array\n }[],\n contracts: Record<\"ink\" | \"sol\", Record<string, HexString>>,\n whitelist: string[] | null,\n) {\n const filePath = join(descriptorsDir, \"generated.json\")\n\n await fs.writeFile(\n filePath,\n JSON.stringify({\n cliVersion,\n whitelist,\n chains: Object.fromEntries(\n chains.map(({ key, metadataRaw }) => [\n key,\n toHex(Blake2128(metadataRaw)),\n ]),\n ),\n contracts,\n }),\n )\n}\nasync function alreadyGenerated(\n descriptorsDir: string,\n chains: {\n key: string\n metadataRaw: Uint8Array\n }[],\n contracts: Record<\"ink\" | \"sol\", Record<string, HexString>>,\n whitelist: string[] | null,\n) {\n const generatedJsôn = join(descriptorsDir, \"generated.json\")\n if (!existsSync(generatedJsôn)) return false\n\n try {\n const generated = JSON.parse(\n await fs.readFile(generatedJsôn, {\n encoding: \"utf-8\",\n }),\n )\n if (\n (generated.whitelist ?? [\"*\"]).join(\",\") !=\n (whitelist ?? [\"*\"]).join(\",\") ||\n generated.cliVersion !== cliVersion\n )\n return false\n\n return (\n chains.length === Object.entries(generated.chains).length &&\n chains.every(({ key, metadataRaw }) => {\n const hash = toHex(Blake2128(metadataRaw))\n return hash === generated.chains[key]\n }) &&\n ([\"ink\", \"sol\"] as const).every(\n (kind) =>\n Object.entries(contracts[kind]).length ===\n Object.entries(generated.contracts[kind]).length &&\n Object.entries(contracts[kind]).every(\n ([k, hash]) => hash === generated.contracts[kind][k],\n ),\n )\n )\n } catch {\n return false\n }\n}\n\nasync function cleanDescriptorsPackage(path: string) {\n const descriptorsDir = join(process.cwd(), path)\n if (!existsSync(descriptorsDir)) {\n await fs.mkdir(descriptorsDir, { recursive: true })\n\n // We have to keep the package.json in git because otherwise npm install on a fresh repo would fail\n await fs.writeFile(\n join(descriptorsDir, \".gitignore\"),\n \"*\\n!.gitignore\\n!package.json\\n\",\n )\n }\n\n const distDir = join(descriptorsDir, \"dist\")\n if (existsSync(distDir)) {\n await fs.rm(distDir, { recursive: true })\n }\n}\n\nasync function addDescriptorsToPackageJson(path: string) {\n const [packageJson, protocol] = await Promise.all([\n readPackage(),\n getPackageProtocol(),\n ])\n\n const packageSource = `${protocol}:${path}`\n const currentSource = packageJson.dependencies?.[\"@polkadot-api/descriptors\"]\n if (currentSource !== packageSource) {\n await updatePackage({\n dependencies: {\n \"@polkadot-api/descriptors\": packageSource,\n },\n })\n }\n}\n\nasync function getPackageProtocol() {\n const { packageManager, version } = await detectPackageManager()\n\n switch (packageManager) {\n case \"yarn\":\n const yarnMajorVersion = Number(version.split(\".\").at(0))\n\n return yarnMajorVersion >= 2 ? \"portal\" : \"file\"\n default:\n return \"file\"\n }\n}\n\nasync function runInstall() {\n const { executable } = await detectPackageManager()\n console.log(`${executable} install`)\n const child = spawn(executable, [\"install\"], {\n stdio: \"inherit\",\n shell: true,\n env: {\n ...process.env,\n PAPI_SKIP_GENERATE: \"true\",\n },\n })\n await new Promise((resolve) => child.on(\"close\", resolve))\n}\n\nconst generateMetadataExportFile = (input: Uint8Array): string =>\n `const binMeta: string = \"${Buffer.from(input).toString(\"base64\")}\"; export default binMeta;`\n\nasync function outputCodegen(\n chains: Array<{\n key: string\n metadata: UnifiedMetadata\n metadataRaw: Uint8Array\n knownTypes: KnownTypes\n codeHash?: HexString\n genesis?: HexString\n }>,\n outputFolder: string,\n clientPath: string,\n whitelist: string[] | Record<string, string[]> | null,\n) {\n const {\n commonFileContent,\n descriptorsFileContent,\n descriptorTypesFiles,\n metadataTypes,\n typesFileContent,\n publicTypes,\n } = generateMultipleDescriptors(\n chains,\n {\n client: clientPath,\n metadataTypes: \"./metadataTypes\",\n types: \"./common-types\",\n descriptorValues: \"./descriptors\",\n common: \"./common\",\n },\n {\n whitelist: whitelist ?? undefined,\n },\n )\n\n const hash = h64(\n Binary.fromText(Array.from(metadataTypes.checksumToIdx.keys()).join(\"\")),\n )\n\n const EntryPointsCodec = Vector(EntryPointCodec)\n const TypedefsCodec = Vector(TypedefCodec)\n const TypesCodec = Tuple(EntryPointsCodec, TypedefsCodec)\n\n await fs.mkdir(outputFolder, { recursive: true })\n\n await fs.writeFile(path.join(outputFolder, \"common.ts\"), commonFileContent)\n // Going through base64 conversion instead of using binary loader because of esbuild issue\n // https://github.com/evanw/esbuild/issues/3894\n const metadataTypesBase64 = Buffer.from(\n TypesCodec.enc([metadataTypes.entryPoints, metadataTypes.typedefs]),\n ).toString(\"base64\")\n\n await fs.writeFile(\n path.join(outputFolder, \"metadataTypes.ts\"),\n `\nconst content = \"${metadataTypesBase64}\"\nexport default content\n `,\n )\n await fs.writeFile(\n path.join(outputFolder, \"descriptors.ts\"),\n descriptorsFileContent,\n )\n await fs.writeFile(\n path.join(outputFolder, \"common-types.ts\"),\n typesFileContent,\n )\n await Promise.all(\n chains\n .map((chain, i) => [\n fs.writeFile(\n join(outputFolder, `${chain.key}.ts`),\n descriptorTypesFiles[i].content,\n ),\n fs.writeFile(\n join(outputFolder, `${chain.key}_metadata.ts`),\n generateMetadataExportFile(chain.metadataRaw),\n ),\n ])\n .flat(),\n )\n\n await generateIndex(\n outputFolder,\n chains.map((chain) => chain.key),\n publicTypes,\n Object.fromEntries(\n chains.filter((x) => x.codeHash!!).map((x) => [x.codeHash, x.key]),\n ),\n )\n\n return hash\n}\n\nasync function outputContractCodegen(\n contracts: {\n ink?: Record<string, string>\n sol?: Record<string, string>\n },\n outputFolder: string,\n) {\n console.log(\"Generating smart contract types\")\n\n const contractsFolder = join(outputFolder, \"contracts\")\n if (!existsSync(contractsFolder))\n await fs.mkdir(contractsFolder, { recursive: true })\n\n const imports: string[] = []\n for (const [key, metadata] of Object.entries(contracts.ink ?? {})) {\n try {\n const types = generateInkTypes(\n getInkLookup(JSON.parse(await fs.readFile(metadata, \"utf-8\"))),\n )\n await fs.writeFile(join(contractsFolder, `${key}.ts`), types)\n imports.push(`export { descriptor as ${key} } from './${key}'`)\n } catch (ex) {\n console.error(\"Exception when generating descriptors for contract \" + key)\n console.error(ex)\n }\n }\n\n for (const [key, metadata] of Object.entries(contracts.sol ?? {})) {\n try {\n const types = generateSolTypes(\n JSON.parse(await fs.readFile(metadata, \"utf-8\")),\n )\n await fs.writeFile(join(contractsFolder, `${key}.ts`), types)\n imports.push(`export { descriptor as ${key} } from './${key}'`)\n } catch (ex) {\n console.error(\"Exception when generating descriptors for contract \" + key)\n console.error(ex)\n }\n }\n\n await fs.writeFile(\n join(contractsFolder, `index.ts`),\n imports.join(\"\\n\") + \"\\n\",\n )\n\n fs.appendFile(\n join(outputFolder, \"index.ts\"),\n `\n export * as contracts from './contracts';\n `,\n )\n}\n\nasync function compileCodegen(packageDir: string) {\n const srcDir = join(packageDir, \"src\")\n const outDir = join(packageDir, \"dist\")\n\n if (await fsExists(outDir)) {\n await fs.rm(outDir, { recursive: true })\n }\n\n const bundleSuccess = await bundleEsm(path.join(srcDir, \"index.ts\"), {\n dir: outDir,\n })\n\n // We need tsc to actually build the definitions file, and also perform the typecheck\n const program = tsc.createProgramFromConfig({\n basePath: srcDir,\n compilerOptions: {\n skipLibCheck: true,\n declaration: true,\n emitDeclarationOnly: true,\n target: \"esnext\",\n module: \"esnext\",\n resolveJsonModule: true,\n allowSyntheticDefaultImports: true,\n outDir,\n },\n })\n tsc.emit(program)\n\n const errors = [\n program.getGlobalDiagnostics(),\n program.getOptionsDiagnostics(),\n program.getSemanticDiagnostics(),\n program.getSyntacticDiagnostics(),\n program.getDeclarationDiagnostics(),\n program.getConfigFileParsingDiagnostics(),\n ].flat()\n\n return bundleSuccess && errors.length === 0\n}\n\nconst cacheMetadataStr = `\nexport const getMetadata: (codeHash: string) => Promise<Uint8Array | null> = async (\n codeHash: string\n)=> {\n try {\n return await metadatas[codeHash].getMetadata()\n } catch {}\n return null\n}`\n\nconst generateIndex = async (\n path: string,\n keys: string[],\n publicTypes: string[],\n metadatas: Record<string, string>,\n) => {\n const indexTs = [\n ...keys.flatMap((key) => [\n `import { default as ${key}, type ${capitalize(key)}WhitelistEntry } from \"./${key}\";`,\n `export { ${key} }`,\n `export type * from \"./${key}\";`,\n ]),\n `export {`,\n publicTypes.join(\", \"),\n `} from './common-types';`,\n `const metadatas: Record<string, { getMetadata: () => Promise<Uint8Array> }> = {${Object.entries(\n metadatas,\n )\n .map(([codeHash, key]) => `[\"${codeHash}\"]: ${key}`)\n .join(\",\\n\")}}`,\n cacheMetadataStr,\n `export type WhitelistEntry = ${keys.map((key) => `${capitalize(key)}WhitelistEntry`).join(\" | \")};`,\n `export type WhitelistEntriesByChain = Partial<{\"*\": WhitelistEntry[], ${keys.map((key) => `${key}: WhitelistEntry[]`).join(\",\\n\")}}>`,\n ].join(\"\\n\")\n await fs.writeFile(join(path, \"index.ts\"), indexTs)\n}\n\nasync function replacePackageJson(descriptorsDir: string, version: bigint) {\n await fs.writeFile(\n join(descriptorsDir, \"package.json\"),\n `{\n \"version\": \"0.1.0-autogenerated.${version}\",\n \"name\": \"@polkadot-api/descriptors\",\n \"files\": [\n \"dist\"\n ],\n \"type\": \"module\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"module\": \"./dist/index.js\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"main\": \"./dist/index.js\",\n \"module\": \"./dist/index.js\",\n \"browser\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"sideEffects\": false,\n \"peerDependencies\": {\n \"polkadot-api\": \">=2.0.0-rc.1\"\n }\n}\n`,\n )\n}\n\nasync function readWhitelist(filename: string): Promise<string[] | null> {\n if (!(await fsExists(filename))) {\n return null\n }\n\n const tmpDir = await mkdtemp(join(tmpdir(), \"papi-\"))\n try {\n await bundleEsm(filename, { file: join(tmpDir, \"index.js\") })\n const { whitelist } = await import(join(tmpDir, \"index.js\"))\n return whitelist\n } finally {\n await rm(tmpDir, { recursive: true }).catch(console.error)\n }\n}\n\nasync function flushBundlerCache() {\n try {\n const viteMetadata = join(\n process.cwd(),\n \"node_modules\",\n \".vite\",\n \"deps\",\n \"_metadata.json\",\n )\n if (await fsExists(viteMetadata)) {\n await rm(viteMetadata)\n }\n } catch (ex) {\n console.error(ex)\n }\n}\n\nconst isExternal = (id: string) => !id.startsWith(\".\") && !path.isAbsolute(id)\n\nconst scaleBinaryPlugin = () => ({\n name: \"scale-binary\",\n async load(id: string) {\n if (!id.endsWith(\".scale\")) return null\n const data = await fs.readFile(id)\n const base64 = Buffer.from(data).toString(\"base64\")\n return `const base64 = \"${base64}\";\\nexport default base64;`\n },\n})\n\nasync function bundleEsm(\n entry: string,\n output: { dir: string } | { file: string },\n) {\n let bundle: RollupBuild | undefined\n try {\n bundle = await rollup({\n input: entry,\n external: isExternal,\n plugins: [scaleBinaryPlugin(), esbuild({ target: \"es2022\" })],\n logLevel: \"silent\",\n })\n await bundle.write({\n ...output,\n format: \"es\",\n })\n return true\n } catch (ex) {\n console.error(ex)\n return false\n } finally {\n await bundle?.close()\n }\n}\n"],"names":["path"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { readPapiConfig, defaultConfig, writePapiConfig, papiFolder } from '../papiConfig.js';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import * as fs from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { generate } from './generate.js';
|
|
6
|
+
|
|
7
|
+
const ink = {
|
|
8
|
+
async add(file, options) {
|
|
9
|
+
const metadata = JSON.parse(await fs.readFile(file, "utf-8"));
|
|
10
|
+
delete metadata.source?.wasm;
|
|
11
|
+
const key = options.key || metadata.contract.name;
|
|
12
|
+
const config = await readPapiConfig(options.config) ?? defaultConfig;
|
|
13
|
+
const inkConfig = config.ink || (config.ink = {});
|
|
14
|
+
if (key in inkConfig) {
|
|
15
|
+
console.warn(`Replacing existing ${key} config`);
|
|
16
|
+
}
|
|
17
|
+
const contractsFolder = join(papiFolder, "contracts");
|
|
18
|
+
if (!existsSync(contractsFolder)) {
|
|
19
|
+
await fs.mkdir(contractsFolder, { recursive: true });
|
|
20
|
+
}
|
|
21
|
+
const fileName = join(contractsFolder, key + ".json");
|
|
22
|
+
await fs.writeFile(fileName, JSON.stringify(metadata, null, 2));
|
|
23
|
+
inkConfig[key] = fileName;
|
|
24
|
+
await writePapiConfig(options.config, config);
|
|
25
|
+
if (!options.skipCodegen) {
|
|
26
|
+
generate({
|
|
27
|
+
config: options.config
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
async remove(key, options) {
|
|
32
|
+
const config = await readPapiConfig(options.config) ?? defaultConfig;
|
|
33
|
+
const inkConfig = config.ink || (config.ink = {});
|
|
34
|
+
if (!(key in inkConfig)) {
|
|
35
|
+
console.log(`${key} contract not found in config`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const fileName = inkConfig[key];
|
|
39
|
+
delete inkConfig[key];
|
|
40
|
+
if (existsSync(fileName)) {
|
|
41
|
+
await fs.rm(fileName);
|
|
42
|
+
}
|
|
43
|
+
await writePapiConfig(options.config, config);
|
|
44
|
+
if (!options.skipCodegen) {
|
|
45
|
+
generate({
|
|
46
|
+
config: options.config
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export { ink };
|
|
53
|
+
//# sourceMappingURL=ink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ink.js","sources":["../../../../src/commands/ink.ts"],"sourcesContent":["import {\n defaultConfig,\n papiFolder,\n readPapiConfig,\n writePapiConfig,\n} from \"@/papiConfig\"\nimport { existsSync } from \"node:fs\"\nimport * as fs from \"node:fs/promises\"\nimport { join } from \"node:path\"\nimport { CommonOptions } from \"./commonOptions\"\nimport { generate } from \"./generate\"\n\nexport interface InkAddOptions extends CommonOptions {\n key?: string\n}\n\nexport const ink = {\n async add(file: string, options: InkAddOptions) {\n const metadata = JSON.parse(await fs.readFile(file, \"utf-8\"))\n // Remove wasm blob if it's there\n delete metadata.source?.wasm\n\n const key = options.key || metadata.contract.name\n const config = (await readPapiConfig(options.config)) ?? defaultConfig\n const inkConfig = (config.ink ||= {})\n if (key in inkConfig) {\n console.warn(`Replacing existing ${key} config`)\n }\n\n const contractsFolder = join(papiFolder, \"contracts\")\n if (!existsSync(contractsFolder)) {\n await fs.mkdir(contractsFolder, { recursive: true })\n }\n const fileName = join(contractsFolder, key + \".json\")\n await fs.writeFile(fileName, JSON.stringify(metadata, null, 2))\n\n inkConfig[key] = fileName\n await writePapiConfig(options.config, config)\n\n if (!options.skipCodegen) {\n generate({\n config: options.config,\n })\n }\n },\n async remove(key: string, options: CommonOptions) {\n const config = (await readPapiConfig(options.config)) ?? defaultConfig\n const inkConfig = (config.ink ||= {})\n if (!(key in inkConfig)) {\n console.log(`${key} contract not found in config`)\n return\n }\n\n const fileName = inkConfig[key]\n delete inkConfig[key]\n\n if (existsSync(fileName)) {\n await fs.rm(fileName)\n }\n\n await writePapiConfig(options.config, config)\n\n if (!options.skipCodegen) {\n generate({\n config: options.config,\n })\n }\n },\n}\n"],"names":[],"mappings":";;;;;;AAgBO,MAAM,GAAA,GAAM;AAAA,EACjB,MAAM,GAAA,CAAI,IAAA,EAAc,OAAA,EAAwB;AAC9C,IAAA,MAAM,QAAA,GAAW,KAAK,KAAA,CAAM,MAAM,GAAG,QAAA,CAAS,IAAA,EAAM,OAAO,CAAC,CAAA;AAE5D,IAAA,OAAO,SAAS,MAAA,EAAQ,IAAA;AAExB,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,GAAA,IAAO,QAAA,CAAS,QAAA,CAAS,IAAA;AAC7C,IAAA,MAAM,MAAA,GAAU,MAAM,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,IAAM,aAAA;AACzD,IAAA,MAAM,SAAA,GAAa,MAAA,CAAO,GAAA,KAAP,MAAA,CAAO,MAAQ,EAAC,CAAA;AACnC,IAAA,IAAI,OAAO,SAAA,EAAW;AACpB,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,mBAAA,EAAsB,GAAG,CAAA,OAAA,CAAS,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AACpD,IAAA,IAAI,CAAC,UAAA,CAAW,eAAe,CAAA,EAAG;AAChC,MAAA,MAAM,GAAG,KAAA,CAAM,eAAA,EAAiB,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IACrD;AACA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,eAAA,EAAiB,GAAA,GAAM,OAAO,CAAA;AACpD,IAAA,MAAM,EAAA,CAAG,UAAU,QAAA,EAAU,IAAA,CAAK,UAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAC,CAAA;AAE9D,IAAA,SAAA,CAAU,GAAG,CAAA,GAAI,QAAA;AACjB,IAAA,MAAM,eAAA,CAAgB,OAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAE5C,IAAA,IAAI,CAAC,QAAQ,WAAA,EAAa;AACxB,MAAA,QAAA,CAAS;AAAA,QACP,QAAQ,OAAA,CAAQ;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAAA,EACA,MAAM,MAAA,CAAO,GAAA,EAAa,OAAA,EAAwB;AAChD,IAAA,MAAM,MAAA,GAAU,MAAM,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,IAAM,aAAA;AACzD,IAAA,MAAM,SAAA,GAAa,MAAA,CAAO,GAAA,KAAP,MAAA,CAAO,MAAQ,EAAC,CAAA;AACnC,IAAA,IAAI,EAAE,OAAO,SAAA,CAAA,EAAY;AACvB,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,GAAG,CAAA,6BAAA,CAA+B,CAAA;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,UAAU,GAAG,CAAA;AAC9B,IAAA,OAAO,UAAU,GAAG,CAAA;AAEpB,IAAA,IAAI,UAAA,CAAW,QAAQ,CAAA,EAAG;AACxB,MAAA,MAAM,EAAA,CAAG,GAAG,QAAQ,CAAA;AAAA,IACtB;AAEA,IAAA,MAAM,eAAA,CAAgB,OAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAE5C,IAAA,IAAI,CAAC,QAAQ,WAAA,EAAa;AACxB,MAAA,QAAA,CAAS;AAAA,QACP,QAAQ,OAAA,CAAQ;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF;AACF;;;;"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { readPapiConfig, defaultConfig, writePapiConfig } from '../papiConfig.js';
|
|
2
|
+
import { generate } from './generate.js';
|
|
3
|
+
|
|
4
|
+
async function remove(key, options) {
|
|
5
|
+
const config = await readPapiConfig(options.config) ?? defaultConfig;
|
|
6
|
+
const entries = config.entries;
|
|
7
|
+
if (!(key in entries)) {
|
|
8
|
+
throw new Error(`Key ${key} not set in polkadot-api config`);
|
|
9
|
+
}
|
|
10
|
+
delete entries[key];
|
|
11
|
+
await writePapiConfig(options.config, config);
|
|
12
|
+
console.log(`Removed chain "${key}" from config`);
|
|
13
|
+
if (!options.skipCodegen) {
|
|
14
|
+
generate({
|
|
15
|
+
config: options.config
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export { remove };
|
|
21
|
+
//# sourceMappingURL=remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.js","sources":["../../../../src/commands/remove.ts"],"sourcesContent":["import { defaultConfig, readPapiConfig, writePapiConfig } from \"@/papiConfig\"\nimport { CommonOptions } from \"./commonOptions\"\nimport { generate } from \"./generate\"\n\nexport async function remove(key: string, options: CommonOptions) {\n const config = (await readPapiConfig(options.config)) ?? defaultConfig\n const entries = config.entries\n\n if (!(key in entries)) {\n throw new Error(`Key ${key} not set in polkadot-api config`)\n }\n\n delete entries[key]\n\n await writePapiConfig(options.config, config)\n console.log(`Removed chain \"${key}\" from config`)\n\n if (!options.skipCodegen) {\n generate({\n config: options.config,\n })\n }\n}\n"],"names":[],"mappings":";;;AAIA,eAAsB,MAAA,CAAO,KAAa,OAAA,EAAwB;AAChE,EAAA,MAAM,MAAA,GAAU,MAAM,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,IAAM,aAAA;AACzD,EAAA,MAAM,UAAU,MAAA,CAAO,OAAA;AAEvB,EAAA,IAAI,EAAE,OAAO,OAAA,CAAA,EAAU;AACrB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,IAAA,EAAO,GAAG,CAAA,+BAAA,CAAiC,CAAA;AAAA,EAC7D;AAEA,EAAA,OAAO,QAAQ,GAAG,CAAA;AAElB,EAAA,MAAM,eAAA,CAAgB,OAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAC5C,EAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,eAAA,EAAkB,GAAG,CAAA,aAAA,CAAe,CAAA;AAEhD,EAAA,IAAI,CAAC,QAAQ,WAAA,EAAa;AACxB,IAAA,QAAA,CAAS;AAAA,MACP,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAAA,EACH;AACF;;;;"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { readPapiConfig, defaultConfig, writePapiConfig, papiFolder } from '../papiConfig.js';
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
|
+
import * as fs from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { generate } from './generate.js';
|
|
6
|
+
|
|
7
|
+
const sol = {
|
|
8
|
+
async add(file, key, options) {
|
|
9
|
+
const abi = JSON.parse(await fs.readFile(file, "utf-8"));
|
|
10
|
+
const config = await readPapiConfig(options.config) ?? defaultConfig;
|
|
11
|
+
const solConfig = config.sol || (config.sol = {});
|
|
12
|
+
if (key in solConfig) {
|
|
13
|
+
console.warn(`Replacing existing ${key} config`);
|
|
14
|
+
}
|
|
15
|
+
const contractsFolder = join(papiFolder, "contracts");
|
|
16
|
+
if (!existsSync(contractsFolder)) {
|
|
17
|
+
await fs.mkdir(contractsFolder, { recursive: true });
|
|
18
|
+
}
|
|
19
|
+
const fileName = join(contractsFolder, key + ".json");
|
|
20
|
+
await fs.writeFile(fileName, JSON.stringify(abi, null, 2));
|
|
21
|
+
solConfig[key] = fileName;
|
|
22
|
+
await writePapiConfig(options.config, config);
|
|
23
|
+
if (!options.skipCodegen) {
|
|
24
|
+
generate({
|
|
25
|
+
config: options.config
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
async remove(key, options) {
|
|
30
|
+
const config = await readPapiConfig(options.config) ?? defaultConfig;
|
|
31
|
+
const solConfig = config.sol || (config.sol = {});
|
|
32
|
+
if (!(key in solConfig)) {
|
|
33
|
+
console.log(`${key} contract not found in config`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const fileName = solConfig[key];
|
|
37
|
+
delete solConfig[key];
|
|
38
|
+
if (existsSync(fileName)) {
|
|
39
|
+
await fs.rm(fileName);
|
|
40
|
+
}
|
|
41
|
+
await writePapiConfig(options.config, config);
|
|
42
|
+
if (!options.skipCodegen) {
|
|
43
|
+
generate({
|
|
44
|
+
config: options.config
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export { sol };
|
|
51
|
+
//# sourceMappingURL=sol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sol.js","sources":["../../../../src/commands/sol.ts"],"sourcesContent":["import {\n defaultConfig,\n papiFolder,\n readPapiConfig,\n writePapiConfig,\n} from \"@/papiConfig\"\nimport { existsSync } from \"node:fs\"\nimport * as fs from \"node:fs/promises\"\nimport { join } from \"node:path\"\nimport { CommonOptions } from \"./commonOptions\"\nimport { generate } from \"./generate\"\n\nexport const sol = {\n async add(file: string, key: string, options: CommonOptions) {\n const abi = JSON.parse(await fs.readFile(file, \"utf-8\"))\n\n const config = (await readPapiConfig(options.config)) ?? defaultConfig\n const solConfig = (config.sol ||= {})\n if (key in solConfig) {\n console.warn(`Replacing existing ${key} config`)\n }\n\n const contractsFolder = join(papiFolder, \"contracts\")\n if (!existsSync(contractsFolder)) {\n await fs.mkdir(contractsFolder, { recursive: true })\n }\n const fileName = join(contractsFolder, key + \".json\")\n await fs.writeFile(fileName, JSON.stringify(abi, null, 2))\n\n solConfig[key] = fileName\n await writePapiConfig(options.config, config)\n\n if (!options.skipCodegen) {\n generate({\n config: options.config,\n })\n }\n },\n async remove(key: string, options: CommonOptions) {\n const config = (await readPapiConfig(options.config)) ?? defaultConfig\n const solConfig = (config.sol ||= {})\n if (!(key in solConfig)) {\n console.log(`${key} contract not found in config`)\n return\n }\n\n const fileName = solConfig[key]\n delete solConfig[key]\n\n if (existsSync(fileName)) {\n await fs.rm(fileName)\n }\n\n await writePapiConfig(options.config, config)\n\n if (!options.skipCodegen) {\n generate({\n config: options.config,\n })\n }\n },\n}\n"],"names":[],"mappings":";;;;;;AAYO,MAAM,GAAA,GAAM;AAAA,EACjB,MAAM,GAAA,CAAI,IAAA,EAAc,GAAA,EAAa,OAAA,EAAwB;AAC3D,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAM,MAAM,GAAG,QAAA,CAAS,IAAA,EAAM,OAAO,CAAC,CAAA;AAEvD,IAAA,MAAM,MAAA,GAAU,MAAM,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,IAAM,aAAA;AACzD,IAAA,MAAM,SAAA,GAAa,MAAA,CAAO,GAAA,KAAP,MAAA,CAAO,MAAQ,EAAC,CAAA;AACnC,IAAA,IAAI,OAAO,SAAA,EAAW;AACpB,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,mBAAA,EAAsB,GAAG,CAAA,OAAA,CAAS,CAAA;AAAA,IACjD;AAEA,IAAA,MAAM,eAAA,GAAkB,IAAA,CAAK,UAAA,EAAY,WAAW,CAAA;AACpD,IAAA,IAAI,CAAC,UAAA,CAAW,eAAe,CAAA,EAAG;AAChC,MAAA,MAAM,GAAG,KAAA,CAAM,eAAA,EAAiB,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,IACrD;AACA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,eAAA,EAAiB,GAAA,GAAM,OAAO,CAAA;AACpD,IAAA,MAAM,EAAA,CAAG,UAAU,QAAA,EAAU,IAAA,CAAK,UAAU,GAAA,EAAK,IAAA,EAAM,CAAC,CAAC,CAAA;AAEzD,IAAA,SAAA,CAAU,GAAG,CAAA,GAAI,QAAA;AACjB,IAAA,MAAM,eAAA,CAAgB,OAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAE5C,IAAA,IAAI,CAAC,QAAQ,WAAA,EAAa;AACxB,MAAA,QAAA,CAAS;AAAA,QACP,QAAQ,OAAA,CAAQ;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF,CAAA;AAAA,EACA,MAAM,MAAA,CAAO,GAAA,EAAa,OAAA,EAAwB;AAChD,IAAA,MAAM,MAAA,GAAU,MAAM,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,IAAM,aAAA;AACzD,IAAA,MAAM,SAAA,GAAa,MAAA,CAAO,GAAA,KAAP,MAAA,CAAO,MAAQ,EAAC,CAAA;AACnC,IAAA,IAAI,EAAE,OAAO,SAAA,CAAA,EAAY;AACvB,MAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,EAAG,GAAG,CAAA,6BAAA,CAA+B,CAAA;AACjD,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,UAAU,GAAG,CAAA;AAC9B,IAAA,OAAO,UAAU,GAAG,CAAA;AAEpB,IAAA,IAAI,UAAA,CAAW,QAAQ,CAAA,EAAG;AACxB,MAAA,MAAM,EAAA,CAAG,GAAG,QAAQ,CAAA;AAAA,IACtB;AAEA,IAAA,MAAM,eAAA,CAAgB,OAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAE5C,IAAA,IAAI,CAAC,QAAQ,WAAA,EAAa;AACxB,MAAA,QAAA,CAAS;AAAA,QACP,QAAQ,OAAA,CAAQ;AAAA,OACjB,CAAA;AAAA,IACH;AAAA,EACF;AACF;;;;"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getMetadata, writeMetadataToDisk } from '../metadata.js';
|
|
2
|
+
import { readPapiConfig, defaultConfig, writePapiConfig } from '../papiConfig.js';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { generate } from './generate.js';
|
|
5
|
+
|
|
6
|
+
async function update(keysInput, options) {
|
|
7
|
+
const config = await readPapiConfig(options.config) ?? defaultConfig;
|
|
8
|
+
const { entries } = config;
|
|
9
|
+
const keys = keysInput === void 0 ? Object.keys(entries) : keysInput.split(",");
|
|
10
|
+
const updateByKey = async (key) => {
|
|
11
|
+
if (!(key in entries)) {
|
|
12
|
+
throw new Error(`Key ${key} not set in polkadot-api config`);
|
|
13
|
+
}
|
|
14
|
+
const { metadata: filename, ...entry } = entries[key];
|
|
15
|
+
if (!filename) {
|
|
16
|
+
if (keysInput !== void 0) {
|
|
17
|
+
console.warn(`Key ${key} doesn't have a metadata file to update`);
|
|
18
|
+
}
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if ("at" in entry) {
|
|
22
|
+
console.warn(
|
|
23
|
+
`Key ${key} is based on a specific block ${entry.at}, skipping update`
|
|
24
|
+
);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const metadata = await getMetadata(entry);
|
|
28
|
+
if (!metadata) {
|
|
29
|
+
if (keysInput !== void 0) {
|
|
30
|
+
console.warn(
|
|
31
|
+
`Key ${key} doesn't have any external source to update from`
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
entries[key].genesis = metadata.genesis;
|
|
37
|
+
entries[key].codeHash = metadata.codeHash;
|
|
38
|
+
spinner.text = `Writing ${key} metadata`;
|
|
39
|
+
await writeMetadataToDisk(metadata.metadataRaw, filename);
|
|
40
|
+
spinner.succeed(`${key} metadata updated`);
|
|
41
|
+
};
|
|
42
|
+
const spinner = ora(`Updating`).start();
|
|
43
|
+
await Promise.all(keys.map(updateByKey));
|
|
44
|
+
await writePapiConfig(options.config, config);
|
|
45
|
+
if (!options.skipCodegen) {
|
|
46
|
+
console.log(`Updating descriptors`);
|
|
47
|
+
await generate({
|
|
48
|
+
config: options.config
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
spinner.stop();
|
|
52
|
+
console.log(`Updated chain(s) "${keys.join(", ")}"`);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { update };
|
|
56
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sources":["../../../../src/commands/update.ts"],"sourcesContent":["import { getMetadata, writeMetadataToDisk } from \"@/metadata\"\nimport {\n defaultConfig,\n EntryConfig,\n readPapiConfig,\n writePapiConfig,\n} from \"@/papiConfig\"\nimport ora from \"ora\"\nimport { CommonOptions } from \"./commonOptions\"\nimport { generate } from \"./generate\"\n\nexport async function update(\n keysInput: string | undefined,\n options: CommonOptions,\n) {\n const config = (await readPapiConfig(options.config)) ?? defaultConfig\n const { entries } = config\n\n const keys =\n keysInput === undefined ? Object.keys(entries) : keysInput.split(\",\")\n\n const updateByKey = async (key: string) => {\n if (!(key in entries)) {\n throw new Error(`Key ${key} not set in polkadot-api config`)\n }\n\n // Exclude metadata file from the entry, otherwise getMetadata would load from the file\n const { metadata: filename, ...entry } = entries[key]\n if (!filename) {\n if (keysInput !== undefined) {\n console.warn(`Key ${key} doesn't have a metadata file to update`)\n }\n\n return\n }\n\n if (\"at\" in entry) {\n console.warn(\n `Key ${key} is based on a specific block ${entry.at}, skipping update`,\n )\n return\n }\n\n const metadata = await getMetadata(entry as EntryConfig)\n // For those without other sources than metadata file, we get a null.\n if (!metadata) {\n if (keysInput !== undefined) {\n console.warn(\n `Key ${key} doesn't have any external source to update from`,\n )\n }\n return\n }\n entries[key].genesis = metadata.genesis\n entries[key].codeHash = metadata.codeHash\n\n spinner.text = `Writing ${key} metadata`\n await writeMetadataToDisk(metadata.metadataRaw, filename)\n spinner.succeed(`${key} metadata updated`)\n }\n\n const spinner = ora(`Updating`).start()\n await Promise.all(keys.map(updateByKey))\n await writePapiConfig(options.config, config)\n\n if (!options.skipCodegen) {\n console.log(`Updating descriptors`)\n await generate({\n config: options.config,\n })\n }\n\n spinner.stop()\n console.log(`Updated chain(s) \"${keys.join(\", \")}\"`)\n}\n"],"names":[],"mappings":";;;;;AAWA,eAAsB,MAAA,CACpB,WACA,OAAA,EACA;AACA,EAAA,MAAM,MAAA,GAAU,MAAM,cAAA,CAAe,OAAA,CAAQ,MAAM,CAAA,IAAM,aAAA;AACzD,EAAA,MAAM,EAAE,SAAQ,GAAI,MAAA;AAEpB,EAAA,MAAM,IAAA,GACJ,cAAc,MAAA,GAAY,MAAA,CAAO,KAAK,OAAO,CAAA,GAAI,SAAA,CAAU,KAAA,CAAM,GAAG,CAAA;AAEtE,EAAA,MAAM,WAAA,GAAc,OAAO,GAAA,KAAgB;AACzC,IAAA,IAAI,EAAE,OAAO,OAAA,CAAA,EAAU;AACrB,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,IAAA,EAAO,GAAG,CAAA,+BAAA,CAAiC,CAAA;AAAA,IAC7D;AAGA,IAAA,MAAM,EAAE,QAAA,EAAU,QAAA,EAAU,GAAG,KAAA,EAAM,GAAI,QAAQ,GAAG,CAAA;AACpD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,QAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,IAAA,EAAO,GAAG,CAAA,uCAAA,CAAyC,CAAA;AAAA,MAClE;AAEA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,CAAA,IAAA,EAAO,GAAG,CAAA,8BAAA,EAAiC,KAAA,CAAM,EAAE,CAAA,iBAAA;AAAA,OACrD;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,QAAA,GAAW,MAAM,WAAA,CAAY,KAAoB,CAAA;AAEvD,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,IAAI,cAAc,MAAA,EAAW;AAC3B,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,OAAO,GAAG,CAAA,gDAAA;AAAA,SACZ;AAAA,MACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,GAAG,CAAA,CAAE,OAAA,GAAU,QAAA,CAAS,OAAA;AAChC,IAAA,OAAA,CAAQ,GAAG,CAAA,CAAE,QAAA,GAAW,QAAA,CAAS,QAAA;AAEjC,IAAA,OAAA,CAAQ,IAAA,GAAO,WAAW,GAAG,CAAA,SAAA,CAAA;AAC7B,IAAA,MAAM,mBAAA,CAAoB,QAAA,CAAS,WAAA,EAAa,QAAQ,CAAA;AACxD,IAAA,OAAA,CAAQ,OAAA,CAAQ,CAAA,EAAG,GAAG,CAAA,iBAAA,CAAmB,CAAA;AAAA,EAC3C,CAAA;AAEA,EAAA,MAAM,OAAA,GAAU,GAAA,CAAI,CAAA,QAAA,CAAU,CAAA,CAAE,KAAA,EAAM;AACtC,EAAA,MAAM,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,GAAA,CAAI,WAAW,CAAC,CAAA;AACvC,EAAA,MAAM,eAAA,CAAgB,OAAA,CAAQ,MAAA,EAAQ,MAAM,CAAA;AAE5C,EAAA,IAAI,CAAC,QAAQ,WAAA,EAAa;AACxB,IAAA,OAAA,CAAQ,IAAI,CAAA,oBAAA,CAAsB,CAAA;AAClC,IAAA,MAAM,QAAA,CAAS;AAAA,MACb,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAAA,EACH;AAEA,EAAA,OAAA,CAAQ,IAAA,EAAK;AACb,EAAA,OAAA,CAAQ,IAAI,CAAA,kBAAA,EAAqB,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AACrD;;;;"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { getCli } from './cli.js';
|
|
3
|
+
import { add } from './commands/add.js';
|
|
4
|
+
import { generate } from './commands/generate.js';
|
|
5
|
+
import { ink } from './commands/ink.js';
|
|
6
|
+
import { remove } from './commands/remove.js';
|
|
7
|
+
import { update } from './commands/update.js';
|
|
8
|
+
import { version } from '../package.json.js';
|
|
9
|
+
|
|
10
|
+
const program = getCli({ add, generate, remove, update, ink, version });
|
|
11
|
+
program.parse();
|
|
12
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sources":["../../../src/main.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { getCli } from \"./cli\"\nimport { add, generate, ink, remove, update } from \"./commands\"\nimport { version } from \"../package.json\"\n\nconst program = getCli({ add, generate, remove, update, ink, version })\nprogram.parse()\n"],"names":[],"mappings":";;;;;;;;;AAMA,MAAM,OAAA,GAAU,OAAO,EAAE,GAAA,EAAK,UAAU,MAAA,EAAQ,MAAA,EAAQ,GAAA,EAAK,OAAA,EAAS,CAAA;AACtE,OAAA,CAAQ,KAAA,EAAM"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { createClient } from '@polkadot-api/substrate-client';
|
|
2
|
+
import * as fs from 'node:fs/promises';
|
|
3
|
+
import { unifyMetadata, metadata, v15 } from '@polkadot-api/substrate-bindings';
|
|
4
|
+
import { getWsProvider } from '@polkadot-api/ws-provider';
|
|
5
|
+
import { Worker } from 'node:worker_threads';
|
|
6
|
+
import { getObservableClient } from '@polkadot-api/observable-client';
|
|
7
|
+
import { firstValueFrom, Observable, map, combineLatest, take, catchError, of, filter, from, switchMap } from 'rxjs';
|
|
8
|
+
import { dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import * as knownChains from '@polkadot-api/known-chains';
|
|
11
|
+
import { startFromWorker } from '@polkadot-api/smoldot/from-node-worker';
|
|
12
|
+
import { getSmProvider } from '@polkadot-api/sm-provider';
|
|
13
|
+
import { middleware } from '@polkadot-api/ws-middleware';
|
|
14
|
+
|
|
15
|
+
const workerPath = fileURLToPath(
|
|
16
|
+
import.meta.resolve("@polkadot-api/smoldot/node-worker")
|
|
17
|
+
);
|
|
18
|
+
let smoldotWorker;
|
|
19
|
+
let workerRefCount = 0;
|
|
20
|
+
async function getSmoldotWorker() {
|
|
21
|
+
if (!smoldotWorker) {
|
|
22
|
+
const worker = new Worker(workerPath, {
|
|
23
|
+
stdout: true,
|
|
24
|
+
stderr: true
|
|
25
|
+
});
|
|
26
|
+
const client = startFromWorker(worker);
|
|
27
|
+
smoldotWorker = [client, worker];
|
|
28
|
+
}
|
|
29
|
+
return smoldotWorker;
|
|
30
|
+
}
|
|
31
|
+
const getMetadataCall = (provider, at) => new Observable((observer) => {
|
|
32
|
+
const substrateClient = createClient(provider);
|
|
33
|
+
const client = getObservableClient(substrateClient);
|
|
34
|
+
const { runtime$, unfollow, genesis$, getRuntime$ } = client.chainHead$();
|
|
35
|
+
const archive = client.archive(getRuntime$);
|
|
36
|
+
const getRuntimeCtx$ = () => {
|
|
37
|
+
if (!at) return runtime$.pipe(filter(Boolean));
|
|
38
|
+
const hash$ = at.length < 32 && /^\d+$/.test(at) ? from(substrateClient.archive.hashByHeight(Number(at))).pipe(
|
|
39
|
+
map(([hash]) => {
|
|
40
|
+
if (!hash) {
|
|
41
|
+
throw new Error(`Can't find block number "${at}"`);
|
|
42
|
+
}
|
|
43
|
+
return hash;
|
|
44
|
+
})
|
|
45
|
+
) : of(at);
|
|
46
|
+
return hash$.pipe(switchMap(archive.getRuntimeContext$));
|
|
47
|
+
};
|
|
48
|
+
const subscription = combineLatest({
|
|
49
|
+
runtime: getRuntimeCtx$(),
|
|
50
|
+
genesis: genesis$
|
|
51
|
+
}).pipe(
|
|
52
|
+
take(1),
|
|
53
|
+
map(
|
|
54
|
+
({
|
|
55
|
+
runtime: {
|
|
56
|
+
lookup: { metadata: metadata2 },
|
|
57
|
+
metadataRaw,
|
|
58
|
+
codeHash
|
|
59
|
+
},
|
|
60
|
+
genesis
|
|
61
|
+
}) => ({
|
|
62
|
+
metadata: metadata2,
|
|
63
|
+
metadataRaw,
|
|
64
|
+
codeHash,
|
|
65
|
+
genesis
|
|
66
|
+
})
|
|
67
|
+
)
|
|
68
|
+
).subscribe(observer);
|
|
69
|
+
subscription.add(() => {
|
|
70
|
+
try {
|
|
71
|
+
unfollow();
|
|
72
|
+
client.destroy();
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
return subscription;
|
|
77
|
+
});
|
|
78
|
+
const getChainSpecs = (chain) => {
|
|
79
|
+
if (!(chain in knownChains)) {
|
|
80
|
+
const relayChainName2 = JSON.parse(chain).relay_chain;
|
|
81
|
+
return {
|
|
82
|
+
potentialRelayChainSpecs: relayChainName2 in knownChains ? [knownChains[relayChainName2]] : [],
|
|
83
|
+
chainSpec: chain
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const relayChainName = Object.keys(knownChains).find(
|
|
87
|
+
(c) => c !== chain && chain.startsWith(c)
|
|
88
|
+
);
|
|
89
|
+
const potentialRelayChainSpecs = relayChainName ? [knownChains[relayChainName]] : [];
|
|
90
|
+
const chainSpec = knownChains[chain];
|
|
91
|
+
return {
|
|
92
|
+
potentialRelayChainSpecs,
|
|
93
|
+
chainSpec
|
|
94
|
+
};
|
|
95
|
+
};
|
|
96
|
+
const getMetadataFromSmoldot = async (chain) => {
|
|
97
|
+
workerRefCount++;
|
|
98
|
+
try {
|
|
99
|
+
const [smoldot] = await getSmoldotWorker();
|
|
100
|
+
const chainSpecs = getChainSpecs(chain);
|
|
101
|
+
const potentialRelayChains = await Promise.all(
|
|
102
|
+
chainSpecs.potentialRelayChainSpecs.map(
|
|
103
|
+
(chainSpec) => smoldot.addChain({ chainSpec })
|
|
104
|
+
)
|
|
105
|
+
);
|
|
106
|
+
const provider = getSmProvider(
|
|
107
|
+
() => smoldot.addChain({
|
|
108
|
+
chainSpec: chainSpecs.chainSpec,
|
|
109
|
+
potentialRelayChains
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
return await firstValueFrom(getMetadataCall(provider));
|
|
113
|
+
} finally {
|
|
114
|
+
workerRefCount--;
|
|
115
|
+
if (workerRefCount === 0) {
|
|
116
|
+
const [smoldot, worker] = smoldotWorker;
|
|
117
|
+
smoldotWorker = null;
|
|
118
|
+
await smoldot.terminate();
|
|
119
|
+
await worker.terminate();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
const getMetadataCallWithError = (...input) => getMetadataCall(...input).pipe(
|
|
124
|
+
map((value) => ({ success: true, value })),
|
|
125
|
+
catchError((error) => of({ success: false, error }))
|
|
126
|
+
);
|
|
127
|
+
const getMetadataFromWsURL = (wsURL, at) => firstValueFrom(
|
|
128
|
+
getMetadataCallWithError(getWsProvider(wsURL, { middleware }), at).pipe(
|
|
129
|
+
map((x) => {
|
|
130
|
+
if (x.success) return x.value;
|
|
131
|
+
throw x.error;
|
|
132
|
+
})
|
|
133
|
+
)
|
|
134
|
+
);
|
|
135
|
+
async function getMetadata({
|
|
136
|
+
metadata: metadataFile,
|
|
137
|
+
codeHash,
|
|
138
|
+
genesis,
|
|
139
|
+
...entry
|
|
140
|
+
}) {
|
|
141
|
+
if (metadataFile) {
|
|
142
|
+
const data = await fs.readFile(metadataFile);
|
|
143
|
+
const metadataRaw = new Uint8Array(data);
|
|
144
|
+
let meta;
|
|
145
|
+
try {
|
|
146
|
+
meta = unifyMetadata(metadata.dec(metadataRaw));
|
|
147
|
+
} catch (_) {
|
|
148
|
+
meta = unifyMetadata(v15.dec(metadataRaw));
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
metadata: meta,
|
|
152
|
+
metadataRaw,
|
|
153
|
+
codeHash,
|
|
154
|
+
genesis
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
if ("chain" in entry) {
|
|
158
|
+
return getMetadataFromSmoldot(entry.chain);
|
|
159
|
+
}
|
|
160
|
+
if ("chainSpec" in entry) {
|
|
161
|
+
const chainSpec = await fs.readFile(entry.chainSpec, "utf8");
|
|
162
|
+
return getMetadataFromSmoldot(chainSpec);
|
|
163
|
+
}
|
|
164
|
+
if ("wsUrl" in entry) {
|
|
165
|
+
return getMetadataFromWsURL(entry.wsUrl, entry.at);
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
async function writeMetadataToDisk(metadataRaw, outFile) {
|
|
170
|
+
await fs.mkdir(dirname(outFile), { recursive: true });
|
|
171
|
+
await fs.writeFile(outFile, metadataRaw);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export { getMetadata, writeMetadataToDisk };
|
|
175
|
+
//# sourceMappingURL=metadata.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadata.js","sources":["../../../src/metadata.ts"],"sourcesContent":["import { createClient } from \"@polkadot-api/substrate-client\"\nimport type { JsonRpcProvider } from \"@polkadot-api/json-rpc-provider\"\nimport * as fs from \"node:fs/promises\"\nimport {\n HexString,\n metadata,\n UnifiedMetadata,\n unifyMetadata,\n v15,\n} from \"@polkadot-api/substrate-bindings\"\nimport { getWsProvider } from \"@polkadot-api/ws-provider\"\nimport { Worker } from \"node:worker_threads\"\nimport { getObservableClient } from \"@polkadot-api/observable-client\"\nimport {\n catchError,\n combineLatest,\n filter,\n firstValueFrom,\n from,\n map,\n Observable,\n of,\n switchMap,\n take,\n} from \"rxjs\"\nimport { EntryConfig } from \"./papiConfig\"\nimport { dirname } from \"path\"\nimport { fileURLToPath } from \"url\"\nimport * as knownChains from \"@polkadot-api/known-chains\"\nimport { startFromWorker } from \"@polkadot-api/smoldot/from-node-worker\"\nimport { Client as SmoldotClient } from \"@polkadot-api/smoldot\"\nimport { getSmProvider } from \"@polkadot-api/sm-provider\"\nimport { middleware } from \"@polkadot-api/ws-middleware\"\n\nconst workerPath = fileURLToPath(\n import.meta.resolve(\"@polkadot-api/smoldot/node-worker\"),\n)\n\nlet smoldotWorker: [SmoldotClient, Worker] | null\nlet workerRefCount = 0\nasync function getSmoldotWorker() {\n if (!smoldotWorker) {\n const worker = new Worker(workerPath, {\n stdout: true,\n stderr: true,\n })\n const client = startFromWorker(worker)\n smoldotWorker = [client, worker]\n }\n return smoldotWorker\n}\n\ntype GetMetadataPayload = {\n metadata: UnifiedMetadata\n metadataRaw: Uint8Array\n codeHash: string\n genesis: string\n}\nconst getMetadataCall = (provider: JsonRpcProvider, at?: string) =>\n new Observable<GetMetadataPayload>((observer) => {\n const substrateClient = createClient(provider)\n const client = getObservableClient(substrateClient)\n const { runtime$, unfollow, genesis$, getRuntime$ } = client.chainHead$()\n const archive = client.archive(getRuntime$)\n\n const getRuntimeCtx$ = () => {\n if (!at) return runtime$.pipe(filter(Boolean))\n // if it's a number\n const hash$ =\n at.length < 32 && /^\\d+$/.test(at)\n ? from(substrateClient.archive.hashByHeight(Number(at))).pipe(\n map(([hash]) => {\n if (!hash) {\n throw new Error(`Can't find block number \"${at}\"`)\n }\n return hash\n }),\n )\n : of(at)\n return hash$.pipe(switchMap(archive.getRuntimeContext$))\n }\n\n const subscription = combineLatest({\n runtime: getRuntimeCtx$(),\n genesis: genesis$,\n })\n .pipe(\n take(1),\n map(\n ({\n runtime: {\n lookup: { metadata },\n metadataRaw,\n codeHash,\n },\n genesis,\n }) => ({\n metadata,\n metadataRaw,\n codeHash,\n genesis,\n }),\n ),\n )\n .subscribe(observer)\n\n subscription.add(() => {\n try {\n unfollow()\n client.destroy()\n } catch {}\n })\n\n return subscription\n })\n\nconst getChainSpecs = (\n chain: string,\n): { potentialRelayChainSpecs: string[]; chainSpec: string } => {\n if (!(chain in knownChains)) {\n const relayChainName = JSON.parse(chain).relay_chain\n return {\n potentialRelayChainSpecs:\n relayChainName in knownChains\n ? [knownChains[relayChainName as keyof typeof knownChains]]\n : [],\n chainSpec: chain,\n }\n }\n\n const relayChainName = Object.keys(knownChains).find(\n (c) => c !== chain && chain.startsWith(c),\n )\n const potentialRelayChainSpecs = relayChainName\n ? [knownChains[relayChainName as keyof typeof knownChains]]\n : []\n const chainSpec = knownChains[chain as keyof typeof knownChains]\n\n return {\n potentialRelayChainSpecs,\n chainSpec,\n }\n}\n\nconst getMetadataFromSmoldot = async (chain: string) => {\n workerRefCount++\n try {\n const [smoldot] = await getSmoldotWorker()\n const chainSpecs = getChainSpecs(chain)\n const potentialRelayChains = await Promise.all(\n chainSpecs.potentialRelayChainSpecs.map((chainSpec) =>\n smoldot.addChain({ chainSpec }),\n ),\n )\n const provider = getSmProvider(() =>\n smoldot.addChain({\n chainSpec: chainSpecs.chainSpec,\n potentialRelayChains,\n }),\n )\n return await firstValueFrom(getMetadataCall(provider))\n } finally {\n workerRefCount--\n if (workerRefCount === 0) {\n const [smoldot, worker] = smoldotWorker!\n smoldotWorker = null\n await smoldot.terminate()\n await worker.terminate()\n }\n }\n}\n\nconst getMetadataCallWithError = (\n ...input: Parameters<typeof getMetadataCall>\n) =>\n getMetadataCall(...input).pipe(\n map((value) => ({ success: true as const, value })),\n catchError((error) => of({ success: false as const, error })),\n )\n\nconst getMetadataFromWsURL = (wsURL: string, at?: string) =>\n firstValueFrom(\n getMetadataCallWithError(getWsProvider(wsURL, { middleware }), at).pipe(\n map((x) => {\n if (x.success) return x.value\n throw x.error\n }),\n ),\n )\n\nexport async function getMetadata({\n metadata: metadataFile,\n codeHash,\n genesis,\n ...entry\n}: EntryConfig): Promise<{\n metadata: UnifiedMetadata\n metadataRaw: Uint8Array\n codeHash?: HexString\n genesis?: HexString\n} | null> {\n // metadata file always prevails over other entries.\n // cli's update will update the metadata file when the user requests it.\n if (metadataFile) {\n const data = await fs.readFile(metadataFile)\n const metadataRaw = new Uint8Array(data)\n\n let meta: UnifiedMetadata\n try {\n meta = unifyMetadata(metadata.dec(metadataRaw))\n } catch (_) {\n meta = unifyMetadata(v15.dec(metadataRaw))\n }\n\n return {\n metadata: meta,\n metadataRaw,\n codeHash,\n genesis,\n }\n }\n\n if (\"chain\" in entry) {\n return getMetadataFromSmoldot(entry.chain)\n }\n\n if (\"chainSpec\" in entry) {\n const chainSpec = await fs.readFile(entry.chainSpec, \"utf8\")\n return getMetadataFromSmoldot(chainSpec)\n }\n\n if (\"wsUrl\" in entry) {\n return getMetadataFromWsURL(entry.wsUrl, entry.at)\n }\n\n return null\n}\n\nexport async function writeMetadataToDisk(\n metadataRaw: Uint8Array,\n outFile: string,\n) {\n await fs.mkdir(dirname(outFile), { recursive: true })\n await fs.writeFile(outFile, metadataRaw)\n}\n"],"names":["metadata","relayChainName"],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { execa } from 'execa';
|
|
4
|
+
|
|
5
|
+
let detected = null;
|
|
6
|
+
async function detectPackageManager() {
|
|
7
|
+
if (detected) return detected;
|
|
8
|
+
const { packageManager, executable } = await detectByLockFile() ?? detectByEnvironment() ?? getFallback();
|
|
9
|
+
const version = await getVersion(executable);
|
|
10
|
+
return detected = {
|
|
11
|
+
packageManager,
|
|
12
|
+
executable,
|
|
13
|
+
version
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
async function detectByLockFile() {
|
|
17
|
+
try {
|
|
18
|
+
for (let i = 0, dir = "."; i < 5; i++, dir = join(dir, "..")) {
|
|
19
|
+
const packageManager = await getByLockFile(dir);
|
|
20
|
+
if (packageManager) {
|
|
21
|
+
return {
|
|
22
|
+
packageManager,
|
|
23
|
+
executable: packageManager
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
} catch (ex) {
|
|
28
|
+
}
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
const lockFileToPackageManager = {
|
|
32
|
+
"pnpm-lock.yaml": "pnpm",
|
|
33
|
+
"yarn.lock": "yarn",
|
|
34
|
+
"bun.lock": "bun",
|
|
35
|
+
"bun.lockb": "bun",
|
|
36
|
+
"package-lock.json": "npm"
|
|
37
|
+
};
|
|
38
|
+
const lockFiles = new Set(Object.keys(lockFileToPackageManager));
|
|
39
|
+
async function getByLockFile(dir) {
|
|
40
|
+
const files = await readdir(dir);
|
|
41
|
+
const lockFile = files.find((v) => lockFiles.has(v));
|
|
42
|
+
return lockFile ? lockFileToPackageManager[lockFile] : null;
|
|
43
|
+
}
|
|
44
|
+
function detectByEnvironment() {
|
|
45
|
+
const npm_execpath = process.env.npm_execpath;
|
|
46
|
+
if (npm_execpath) {
|
|
47
|
+
const packageManager = Object.values(lockFileToPackageManager).find(
|
|
48
|
+
(manager) => npm_execpath.includes(manager)
|
|
49
|
+
);
|
|
50
|
+
return packageManager ? { packageManager, executable: npm_execpath } : null;
|
|
51
|
+
}
|
|
52
|
+
if (process.env.PNPM_PACKAGE_NAME) {
|
|
53
|
+
return { packageManager: "pnpm", executable: "pnpm" };
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
function getFallback() {
|
|
58
|
+
console.warn("Package manager couldn't be detected, fallback to npm");
|
|
59
|
+
return {
|
|
60
|
+
executable: "npm",
|
|
61
|
+
packageManager: "npm"
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async function getVersion(executable) {
|
|
65
|
+
const res = await execa(executable, ["--version"]);
|
|
66
|
+
return res.stdout;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export { detectPackageManager };
|
|
70
|
+
//# sourceMappingURL=packageManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"packageManager.js","sources":["../../../src/packageManager.ts"],"sourcesContent":["import { readdir } from \"node:fs/promises\"\nimport { join } from \"node:path\"\nimport { execa } from \"execa\"\n\nexport type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\"\nexport interface PackageManagerDetection {\n packageManager: PackageManager\n executable: string\n version: string\n}\nlet detected: PackageManagerDetection | null = null\n\nexport async function detectPackageManager() {\n if (detected) return detected\n\n const { packageManager, executable } =\n (await detectByLockFile()) ?? detectByEnvironment() ?? getFallback()\n const version = await getVersion(executable)\n\n return (detected = {\n packageManager,\n executable,\n version,\n })\n}\n\nasync function detectByLockFile(): Promise<Omit<\n PackageManagerDetection,\n \"version\"\n> | null> {\n try {\n for (let i = 0, dir = \".\"; i < 5; i++, dir = join(dir, \"..\")) {\n const packageManager = await getByLockFile(dir)\n if (packageManager) {\n return {\n packageManager,\n executable: packageManager,\n }\n }\n }\n } catch (ex) {\n // fs access can fail for permission errors\n // We just assume that we have\n }\n return null\n}\n\nconst lockFileToPackageManager: Record<string, PackageManager> = {\n \"pnpm-lock.yaml\": \"pnpm\",\n \"yarn.lock\": \"yarn\",\n \"bun.lock\": \"bun\",\n \"bun.lockb\": \"bun\",\n \"package-lock.json\": \"npm\",\n}\n\nconst lockFiles = new Set(Object.keys(lockFileToPackageManager))\nasync function getByLockFile(dir: string) {\n const files = await readdir(dir)\n const lockFile = files.find((v) => lockFiles.has(v))\n return lockFile ? lockFileToPackageManager[lockFile] : null\n}\n\nfunction detectByEnvironment(): Omit<\n PackageManagerDetection,\n \"version\"\n> | null {\n const npm_execpath = process.env.npm_execpath\n if (npm_execpath) {\n const packageManager = Object.values(lockFileToPackageManager).find(\n (manager) => npm_execpath.includes(manager),\n )\n return packageManager ? { packageManager, executable: npm_execpath } : null\n }\n if (process.env.PNPM_PACKAGE_NAME) {\n return { packageManager: \"pnpm\", executable: \"pnpm\" }\n }\n return null\n}\n\nfunction getFallback(): Omit<PackageManagerDetection, \"version\"> {\n console.warn(\"Package manager couldn't be detected, fallback to npm\")\n return {\n executable: \"npm\",\n packageManager: \"npm\",\n }\n}\n\nasync function getVersion(executable: string) {\n const res = await execa(executable, [\"--version\"])\n return res.stdout\n}\n"],"names":[],"mappings":";;;;AAUA,IAAI,QAAA,GAA2C,IAAA;AAE/C,eAAsB,oBAAA,GAAuB;AAC3C,EAAA,IAAI,UAAU,OAAO,QAAA;AAErB,EAAA,MAAM,EAAE,gBAAgB,UAAA,EAAW,GAChC,MAAM,gBAAA,EAAiB,IAAM,mBAAA,EAAoB,IAAK,WAAA,EAAY;AACrE,EAAA,MAAM,OAAA,GAAU,MAAM,UAAA,CAAW,UAAU,CAAA;AAE3C,EAAA,OAAQ,QAAA,GAAW;AAAA,IACjB,cAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,eAAe,gBAAA,GAGL;AACR,EAAA,IAAI;AACF,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,GAAA,GAAM,GAAA,EAAK,CAAA,GAAI,CAAA,EAAG,CAAA,EAAA,EAAK,GAAA,GAAM,IAAA,CAAK,GAAA,EAAK,IAAI,CAAA,EAAG;AAC5D,MAAA,MAAM,cAAA,GAAiB,MAAM,aAAA,CAAc,GAAG,CAAA;AAC9C,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,OAAO;AAAA,UACL,cAAA;AAAA,UACA,UAAA,EAAY;AAAA,SACd;AAAA,MACF;AAAA,IACF;AAAA,EACF,SAAS,EAAA,EAAI;AAAA,EAGb;AACA,EAAA,OAAO,IAAA;AACT;AAEA,MAAM,wBAAA,GAA2D;AAAA,EAC/D,gBAAA,EAAkB,MAAA;AAAA,EAClB,WAAA,EAAa,MAAA;AAAA,EACb,UAAA,EAAY,KAAA;AAAA,EACZ,WAAA,EAAa,KAAA;AAAA,EACb,mBAAA,EAAqB;AACvB,CAAA;AAEA,MAAM,YAAY,IAAI,GAAA,CAAI,MAAA,CAAO,IAAA,CAAK,wBAAwB,CAAC,CAAA;AAC/D,eAAe,cAAc,GAAA,EAAa;AACxC,EAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,GAAG,CAAA;AAC/B,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,CAAC,MAAM,SAAA,CAAU,GAAA,CAAI,CAAC,CAAC,CAAA;AACnD,EAAA,OAAO,QAAA,GAAW,wBAAA,CAAyB,QAAQ,CAAA,GAAI,IAAA;AACzD;AAEA,SAAS,mBAAA,GAGA;AACP,EAAA,MAAM,YAAA,GAAe,QAAQ,GAAA,CAAI,YAAA;AACjC,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,cAAA,GAAiB,MAAA,CAAO,MAAA,CAAO,wBAAwB,CAAA,CAAE,IAAA;AAAA,MAC7D,CAAC,OAAA,KAAY,YAAA,CAAa,QAAA,CAAS,OAAO;AAAA,KAC5C;AACA,IAAA,OAAO,cAAA,GAAiB,EAAE,cAAA,EAAgB,UAAA,EAAY,cAAa,GAAI,IAAA;AAAA,EACzE;AACA,EAAA,IAAI,OAAA,CAAQ,IAAI,iBAAA,EAAmB;AACjC,IAAA,OAAO,EAAE,cAAA,EAAgB,MAAA,EAAQ,UAAA,EAAY,MAAA,EAAO;AAAA,EACtD;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,WAAA,GAAwD;AAC/D,EAAA,OAAA,CAAQ,KAAK,uDAAuD,CAAA;AACpE,EAAA,OAAO;AAAA,IACL,UAAA,EAAY,KAAA;AAAA,IACZ,cAAA,EAAgB;AAAA,GAClB;AACF;AAEA,eAAe,WAAW,UAAA,EAAoB;AAC5C,EAAA,MAAM,MAAM,MAAM,KAAA,CAAM,UAAA,EAAY,CAAC,WAAW,CAAC,CAAA;AACjD,EAAA,OAAO,GAAA,CAAI,MAAA;AACb;;;;"}
|