@codama/renderers-js 1.3.4 → 1.4.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/LICENSE +1 -1
- package/dist/index.browser.cjs +3247 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.mjs +3300 -0
- package/dist/index.browser.mjs.map +1 -0
- package/dist/index.node.cjs +2081 -1718
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +2015 -1657
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.react-native.mjs +3300 -0
- package/dist/index.react-native.mjs.map +1 -0
- package/dist/types/fragments/accountFetchHelpers.d.ts +2 -4
- package/dist/types/fragments/accountFetchHelpers.d.ts.map +1 -1
- package/dist/types/fragments/accountPage.d.ts +8 -0
- package/dist/types/fragments/accountPage.d.ts.map +1 -0
- package/dist/types/fragments/accountPdaHelpers.d.ts +3 -5
- package/dist/types/fragments/accountPdaHelpers.d.ts.map +1 -1
- package/dist/types/fragments/accountSizeHelpers.d.ts +3 -4
- package/dist/types/fragments/accountSizeHelpers.d.ts.map +1 -1
- package/dist/types/fragments/accountType.d.ts +3 -5
- package/dist/types/fragments/accountType.d.ts.map +1 -1
- package/dist/types/fragments/discriminatorCondition.d.ts +2 -3
- package/dist/types/fragments/discriminatorCondition.d.ts.map +1 -1
- package/dist/types/fragments/discriminatorConstants.d.ts +5 -6
- package/dist/types/fragments/discriminatorConstants.d.ts.map +1 -1
- package/dist/types/fragments/errorPage.d.ts +6 -0
- package/dist/types/fragments/errorPage.d.ts.map +1 -0
- package/dist/types/fragments/index.d.ts +11 -4
- package/dist/types/fragments/index.d.ts.map +1 -1
- package/dist/types/fragments/indexPage.d.ts +6 -0
- package/dist/types/fragments/indexPage.d.ts.map +1 -0
- package/dist/types/fragments/instructionAccountMeta.d.ts +1 -1
- package/dist/types/fragments/instructionAccountMeta.d.ts.map +1 -1
- package/dist/types/fragments/instructionAccountTypeParam.d.ts +2 -3
- package/dist/types/fragments/instructionAccountTypeParam.d.ts.map +1 -1
- package/dist/types/fragments/instructionByteDelta.d.ts +3 -4
- package/dist/types/fragments/instructionByteDelta.d.ts.map +1 -1
- package/dist/types/fragments/instructionData.d.ts +3 -5
- package/dist/types/fragments/instructionData.d.ts.map +1 -1
- package/dist/types/fragments/instructionExtraArgs.d.ts +3 -5
- package/dist/types/fragments/instructionExtraArgs.d.ts.map +1 -1
- package/dist/types/fragments/instructionFunction.d.ts +3 -5
- package/dist/types/fragments/instructionFunction.d.ts.map +1 -1
- package/dist/types/fragments/instructionInputDefault.d.ts +2 -3
- package/dist/types/fragments/instructionInputDefault.d.ts.map +1 -1
- package/dist/types/fragments/instructionInputResolved.d.ts +2 -3
- package/dist/types/fragments/instructionInputResolved.d.ts.map +1 -1
- package/dist/types/fragments/instructionInputType.d.ts +2 -4
- package/dist/types/fragments/instructionInputType.d.ts.map +1 -1
- package/dist/types/fragments/instructionPage.d.ts +9 -0
- package/dist/types/fragments/instructionPage.d.ts.map +1 -0
- package/dist/types/fragments/instructionParseFunction.d.ts +2 -4
- package/dist/types/fragments/instructionParseFunction.d.ts.map +1 -1
- package/dist/types/fragments/instructionRemainingAccounts.d.ts +3 -4
- package/dist/types/fragments/instructionRemainingAccounts.d.ts.map +1 -1
- package/dist/types/fragments/instructionType.d.ts +2 -3
- package/dist/types/fragments/instructionType.d.ts.map +1 -1
- package/dist/types/fragments/pdaFunction.d.ts +2 -3
- package/dist/types/fragments/pdaFunction.d.ts.map +1 -1
- package/dist/types/fragments/pdaPage.d.ts +7 -0
- package/dist/types/fragments/pdaPage.d.ts.map +1 -0
- package/dist/types/fragments/programAccounts.d.ts +3 -4
- package/dist/types/fragments/programAccounts.d.ts.map +1 -1
- package/dist/types/fragments/programConstant.d.ts +6 -0
- package/dist/types/fragments/programConstant.d.ts.map +1 -0
- package/dist/types/fragments/programInstructions.d.ts +3 -4
- package/dist/types/fragments/programInstructions.d.ts.map +1 -1
- package/dist/types/fragments/programPage.d.ts +6 -0
- package/dist/types/fragments/programPage.d.ts.map +1 -0
- package/dist/types/fragments/rootIndexPage.d.ts +10 -0
- package/dist/types/fragments/rootIndexPage.d.ts.map +1 -0
- package/dist/types/fragments/sharedPage.d.ts +3 -0
- package/dist/types/fragments/sharedPage.d.ts.map +1 -0
- package/dist/types/fragments/type.d.ts +2 -4
- package/dist/types/fragments/type.d.ts.map +1 -1
- package/dist/types/fragments/typeCodec.d.ts +2 -4
- package/dist/types/fragments/typeCodec.d.ts.map +1 -1
- package/dist/types/fragments/typeDecoder.d.ts +2 -4
- package/dist/types/fragments/typeDecoder.d.ts.map +1 -1
- package/dist/types/fragments/typeDiscriminatedUnionHelpers.d.ts +3 -4
- package/dist/types/fragments/typeDiscriminatedUnionHelpers.d.ts.map +1 -1
- package/dist/types/fragments/typeEncoder.d.ts +2 -4
- package/dist/types/fragments/typeEncoder.d.ts.map +1 -1
- package/dist/types/fragments/typePage.d.ts +7 -0
- package/dist/types/fragments/typePage.d.ts.map +1 -0
- package/dist/types/fragments/typeWithCodec.d.ts +2 -4
- package/dist/types/fragments/typeWithCodec.d.ts.map +1 -1
- package/dist/types/index.d.ts +5 -7
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/utils/fragment.d.ts +24 -0
- package/dist/types/utils/fragment.d.ts.map +1 -0
- package/dist/types/utils/importMap.d.ts +17 -0
- package/dist/types/utils/importMap.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +5 -1
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/nameTransformers.d.ts.map +1 -0
- package/dist/types/utils/options.d.ts +40 -0
- package/dist/types/utils/options.d.ts.map +1 -0
- package/dist/types/{TypeManifest.d.ts → utils/typeManifest.d.ts} +6 -6
- package/dist/types/utils/typeManifest.d.ts.map +1 -0
- package/dist/types/visitors/getRenderMapVisitor.d.ts +3 -0
- package/dist/types/visitors/getRenderMapVisitor.d.ts.map +1 -0
- package/dist/types/visitors/getTypeManifestVisitor.d.ts +21 -0
- package/dist/types/visitors/getTypeManifestVisitor.d.ts.map +1 -0
- package/dist/types/visitors/index.d.ts +4 -0
- package/dist/types/visitors/index.d.ts.map +1 -0
- package/dist/types/visitors/renderVisitor.d.ts +3 -0
- package/dist/types/visitors/renderVisitor.d.ts.map +1 -0
- package/package.json +22 -13
- package/dist/templates/fragments/accountFetchHelpers.njk +0 -43
- package/dist/templates/fragments/accountPdaHelpers.njk +0 -25
- package/dist/templates/fragments/accountSizeHelpers.njk +0 -3
- package/dist/templates/fragments/instructionExtraArgs.njk +0 -4
- package/dist/templates/fragments/instructionFunction.njk +0 -62
- package/dist/templates/fragments/instructionInputType.njk +0 -16
- package/dist/templates/fragments/instructionParseFunction.njk +0 -81
- package/dist/templates/fragments/instructionType.njk +0 -18
- package/dist/templates/fragments/pdaFunction.njk +0 -33
- package/dist/templates/fragments/program.njk +0 -3
- package/dist/templates/fragments/programErrors.njk +0 -36
- package/dist/templates/fragments/type.njk +0 -12
- package/dist/templates/fragments/typeCodec.njk +0 -6
- package/dist/templates/fragments/typeDecoder.njk +0 -6
- package/dist/templates/fragments/typeDiscriminatedUnionHelpers.njk +0 -23
- package/dist/templates/fragments/typeEncoder.njk +0 -6
- package/dist/templates/layout.njk +0 -9
- package/dist/templates/macros.njk +0 -12
- package/dist/templates/pages/accountsIndex.njk +0 -9
- package/dist/templates/pages/accountsPage.njk +0 -12
- package/dist/templates/pages/definedTypesIndex.njk +0 -9
- package/dist/templates/pages/definedTypesPage.njk +0 -9
- package/dist/templates/pages/errorsIndex.njk +0 -9
- package/dist/templates/pages/errorsPage.njk +0 -8
- package/dist/templates/pages/instructionsIndex.njk +0 -9
- package/dist/templates/pages/instructionsPage.njk +0 -14
- package/dist/templates/pages/pdasIndex.njk +0 -9
- package/dist/templates/pages/pdasPage.njk +0 -8
- package/dist/templates/pages/programsIndex.njk +0 -9
- package/dist/templates/pages/programsPage.njk +0 -10
- package/dist/templates/pages/rootIndex.njk +0 -26
- package/dist/templates/pages/sharedPage.njk +0 -106
- package/dist/types/ImportMap.d.ts +0 -15
- package/dist/types/ImportMap.d.ts.map +0 -1
- package/dist/types/TypeManifest.d.ts.map +0 -1
- package/dist/types/fragments/common.d.ts +0 -25
- package/dist/types/fragments/common.d.ts.map +0 -1
- package/dist/types/fragments/program.d.ts +0 -7
- package/dist/types/fragments/program.d.ts.map +0 -1
- package/dist/types/fragments/programErrors.d.ts +0 -7
- package/dist/types/fragments/programErrors.d.ts.map +0 -1
- package/dist/types/getRenderMapVisitor.d.ts +0 -31
- package/dist/types/getRenderMapVisitor.d.ts.map +0 -1
- package/dist/types/getTypeManifestVisitor.d.ts +0 -16
- package/dist/types/getTypeManifestVisitor.d.ts.map +0 -1
- package/dist/types/nameTransformers.d.ts.map +0 -1
- package/dist/types/renderVisitor.d.ts +0 -11
- package/dist/types/renderVisitor.d.ts.map +0 -1
- package/dist/types/utils/render.d.ts +0 -4
- package/dist/types/utils/render.d.ts.map +0 -1
- /package/dist/types/{nameTransformers.d.ts → utils/nameTransformers.d.ts} +0 -0
package/dist/index.node.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// src/
|
|
1
|
+
// src/utils/importMap.ts
|
|
2
2
|
var DEFAULT_EXTERNAL_MODULE_MAP = {
|
|
3
3
|
solanaAccounts: "@solana/kit",
|
|
4
4
|
solanaAddresses: "@solana/kit",
|
|
@@ -40,102 +40,255 @@ var DEFAULT_INTERNAL_MODULE_MAP = {
|
|
|
40
40
|
shared: "../shared",
|
|
41
41
|
types: "../types"
|
|
42
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
|
-
currentAliases[name] = alias;
|
|
86
|
-
this._aliases.set(module, currentAliases);
|
|
87
|
-
return this;
|
|
88
|
-
}
|
|
89
|
-
isEmpty() {
|
|
90
|
-
return this._imports.size === 0;
|
|
91
|
-
}
|
|
92
|
-
resolve(dependencies = {}, useGranularImports = false) {
|
|
93
|
-
const aliasedMap = new Map(
|
|
94
|
-
[...this._imports.entries()].map(([module, imports]) => {
|
|
95
|
-
const aliasMap = this._aliases.get(module) ?? {};
|
|
96
|
-
const joinedImports = [...imports].map((i) => aliasMap[i] ? `${i} as ${aliasMap[i]}` : i);
|
|
97
|
-
return [module, new Set(joinedImports)];
|
|
98
|
-
})
|
|
99
|
-
);
|
|
100
|
-
const dependencyMap = {
|
|
101
|
-
...useGranularImports ? DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP : DEFAULT_EXTERNAL_MODULE_MAP,
|
|
102
|
-
...DEFAULT_INTERNAL_MODULE_MAP,
|
|
103
|
-
...dependencies
|
|
104
|
-
};
|
|
105
|
-
const resolvedMap = /* @__PURE__ */ new Map();
|
|
106
|
-
aliasedMap.forEach((imports, module) => {
|
|
107
|
-
const resolvedModule = dependencyMap[module] ?? module;
|
|
108
|
-
const currentImports = resolvedMap.get(resolvedModule) ?? /* @__PURE__ */ new Set();
|
|
109
|
-
imports.forEach((i) => currentImports.add(i));
|
|
110
|
-
resolvedMap.set(resolvedModule, currentImports);
|
|
111
|
-
});
|
|
112
|
-
return resolvedMap;
|
|
113
|
-
}
|
|
114
|
-
toString(dependencies = {}, useGranularImports = false) {
|
|
115
|
-
return [...this.resolve(dependencies, useGranularImports).entries()].sort(([a], [b]) => {
|
|
116
|
-
const aIsRelative = a.startsWith(".");
|
|
117
|
-
const bIsRelative = b.startsWith(".");
|
|
118
|
-
if (aIsRelative && !bIsRelative) return 1;
|
|
119
|
-
if (!aIsRelative && bIsRelative) return -1;
|
|
120
|
-
return a.localeCompare(b);
|
|
121
|
-
}).map(([module, imports]) => {
|
|
122
|
-
const joinedImports = [...imports].sort().filter((i) => {
|
|
123
|
-
const name = i.split(" ");
|
|
124
|
-
if (name.length > 1) {
|
|
125
|
-
return !imports.has(name[1]);
|
|
43
|
+
function createImportMap() {
|
|
44
|
+
return Object.freeze(/* @__PURE__ */ new Map());
|
|
45
|
+
}
|
|
46
|
+
function parseImportInput(input) {
|
|
47
|
+
const matches = input.match(/^(type )?([^ ]+)(?: as (.+))?$/);
|
|
48
|
+
if (!matches) return Object.freeze({ importedIdentifier: input, isType: false, usedIdentifier: input });
|
|
49
|
+
const [_, isType, name, alias] = matches;
|
|
50
|
+
return Object.freeze({
|
|
51
|
+
importedIdentifier: name,
|
|
52
|
+
isType: !!isType,
|
|
53
|
+
usedIdentifier: alias ?? name
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function addToImportMap(importMap, module, imports) {
|
|
57
|
+
const parsedImports = imports.map(parseImportInput).map((i) => [i.usedIdentifier, i]);
|
|
58
|
+
return mergeImportMaps([importMap, /* @__PURE__ */ new Map([[module, new Map(parsedImports)]])]);
|
|
59
|
+
}
|
|
60
|
+
function removeFromImportMap(importMap, module, usedIdentifiers) {
|
|
61
|
+
const newMap = new Map(importMap);
|
|
62
|
+
const newModuleMap = new Map(newMap.get(module));
|
|
63
|
+
usedIdentifiers.forEach((usedIdentifier) => {
|
|
64
|
+
newModuleMap.delete(usedIdentifier);
|
|
65
|
+
});
|
|
66
|
+
if (newModuleMap.size === 0) {
|
|
67
|
+
newMap.delete(module);
|
|
68
|
+
} else {
|
|
69
|
+
newMap.set(module, newModuleMap);
|
|
70
|
+
}
|
|
71
|
+
return Object.freeze(newMap);
|
|
72
|
+
}
|
|
73
|
+
function mergeImportMaps(importMaps) {
|
|
74
|
+
if (importMaps.length === 0) return createImportMap();
|
|
75
|
+
if (importMaps.length === 1) return importMaps[0];
|
|
76
|
+
const mergedMap = new Map(importMaps[0]);
|
|
77
|
+
for (const map of importMaps.slice(1)) {
|
|
78
|
+
for (const [module, imports] of map) {
|
|
79
|
+
const mergedModuleMap = mergedMap.get(module) ?? /* @__PURE__ */ new Map();
|
|
80
|
+
for (const [usedIdentifier, importInfo] of imports) {
|
|
81
|
+
const existingImportInfo = mergedModuleMap.get(usedIdentifier);
|
|
82
|
+
const shouldOverwriteTypeOnly = existingImportInfo && existingImportInfo.importedIdentifier === importInfo.importedIdentifier && existingImportInfo.isType && !importInfo.isType;
|
|
83
|
+
if (!existingImportInfo || shouldOverwriteTypeOnly) {
|
|
84
|
+
mergedModuleMap.set(usedIdentifier, importInfo);
|
|
126
85
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}).join("\n");
|
|
86
|
+
}
|
|
87
|
+
mergedMap.set(module, mergedModuleMap);
|
|
88
|
+
}
|
|
131
89
|
}
|
|
90
|
+
return Object.freeze(mergedMap);
|
|
91
|
+
}
|
|
92
|
+
function importMapToString(importMap, dependencyMap = {}, useGranularImports = false) {
|
|
93
|
+
const resolvedMap = resolveImportMapModules(importMap, dependencyMap, useGranularImports);
|
|
94
|
+
return [...resolvedMap.entries()].sort(([a], [b]) => {
|
|
95
|
+
const relative = Number(a.startsWith(".")) - Number(b.startsWith("."));
|
|
96
|
+
if (relative !== 0) return relative;
|
|
97
|
+
return a.localeCompare(b);
|
|
98
|
+
}).map(([module, imports]) => {
|
|
99
|
+
const innerImports = [...imports.values()].map(importInfoToString).sort((a, b) => a.localeCompare(b)).join(", ");
|
|
100
|
+
return `import { ${innerImports} } from '${module}';`;
|
|
101
|
+
}).join("\n");
|
|
102
|
+
}
|
|
103
|
+
function resolveImportMapModules(importMap, dependencyMap, useGranularImports) {
|
|
104
|
+
const dependencyMapWithDefaults = {
|
|
105
|
+
...useGranularImports ? DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP : DEFAULT_EXTERNAL_MODULE_MAP,
|
|
106
|
+
...DEFAULT_INTERNAL_MODULE_MAP,
|
|
107
|
+
...dependencyMap
|
|
108
|
+
};
|
|
109
|
+
return mergeImportMaps(
|
|
110
|
+
[...importMap.entries()].map(([module, imports]) => {
|
|
111
|
+
const resolvedModule = dependencyMapWithDefaults[module] ?? module;
|
|
112
|
+
return /* @__PURE__ */ new Map([[resolvedModule, imports]]);
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
function importInfoToString({ importedIdentifier, isType, usedIdentifier }) {
|
|
117
|
+
const alias = importedIdentifier !== usedIdentifier ? ` as ${usedIdentifier}` : "";
|
|
118
|
+
return `${isType ? "type " : ""}${importedIdentifier}${alias}`;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/utils/nameTransformers.ts
|
|
122
|
+
import { camelCase, capitalize, kebabCase, pascalCase, snakeCase, titleCase } from "@codama/nodes";
|
|
123
|
+
function getNameApi(transformers) {
|
|
124
|
+
const helpers = {
|
|
125
|
+
camelCase,
|
|
126
|
+
capitalize,
|
|
127
|
+
kebabCase,
|
|
128
|
+
pascalCase,
|
|
129
|
+
snakeCase,
|
|
130
|
+
titleCase
|
|
131
|
+
};
|
|
132
|
+
return Object.fromEntries(
|
|
133
|
+
Object.entries(transformers).map(([key, transformer]) => [key, (name) => transformer(name, helpers)])
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
var DEFAULT_NAME_TRANSFORMERS = {
|
|
137
|
+
accountDecodeFunction: (name) => `decode${pascalCase(name)}`,
|
|
138
|
+
accountFetchAllFunction: (name) => `fetchAll${pascalCase(name)}`,
|
|
139
|
+
accountFetchAllMaybeFunction: (name) => `fetchAllMaybe${pascalCase(name)}`,
|
|
140
|
+
accountFetchFromSeedsFunction: (name) => `fetch${pascalCase(name)}FromSeeds`,
|
|
141
|
+
accountFetchFunction: (name) => `fetch${pascalCase(name)}`,
|
|
142
|
+
accountFetchMaybeFromSeedsFunction: (name) => `fetchMaybe${pascalCase(name)}FromSeeds`,
|
|
143
|
+
accountFetchMaybeFunction: (name) => `fetchMaybe${pascalCase(name)}`,
|
|
144
|
+
accountGetSizeFunction: (name) => `get${pascalCase(name)}Size`,
|
|
145
|
+
codecFunction: (name) => `get${pascalCase(name)}Codec`,
|
|
146
|
+
constant: (name) => snakeCase(name).toUpperCase(),
|
|
147
|
+
constantFunction: (name) => `get${pascalCase(name)}Bytes`,
|
|
148
|
+
dataArgsType: (name) => `${pascalCase(name)}Args`,
|
|
149
|
+
dataType: (name) => `${pascalCase(name)}`,
|
|
150
|
+
decoderFunction: (name) => `get${pascalCase(name)}Decoder`,
|
|
151
|
+
discriminatedUnionDiscriminator: () => "__kind",
|
|
152
|
+
discriminatedUnionFunction: (name) => `${camelCase(name)}`,
|
|
153
|
+
discriminatedUnionVariant: (name) => `${pascalCase(name)}`,
|
|
154
|
+
encoderFunction: (name) => `get${pascalCase(name)}Encoder`,
|
|
155
|
+
enumVariant: (name) => `${pascalCase(name)}`,
|
|
156
|
+
instructionAsyncFunction: (name) => `get${pascalCase(name)}InstructionAsync`,
|
|
157
|
+
instructionAsyncInputType: (name) => `${pascalCase(name)}AsyncInput`,
|
|
158
|
+
instructionDataType: (name) => `${pascalCase(name)}InstructionData`,
|
|
159
|
+
instructionExtraType: (name) => `${pascalCase(name)}InstructionExtra`,
|
|
160
|
+
instructionParseFunction: (name) => `parse${pascalCase(name)}Instruction`,
|
|
161
|
+
instructionParsedType: (name) => `Parsed${pascalCase(name)}Instruction`,
|
|
162
|
+
instructionSyncFunction: (name) => `get${pascalCase(name)}Instruction`,
|
|
163
|
+
instructionSyncInputType: (name) => `${pascalCase(name)}Input`,
|
|
164
|
+
instructionType: (name) => `${pascalCase(name)}Instruction`,
|
|
165
|
+
isDiscriminatedUnionFunction: (name) => `is${pascalCase(name)}`,
|
|
166
|
+
pdaFindFunction: (name) => `find${pascalCase(name)}Pda`,
|
|
167
|
+
pdaSeedsType: (name) => `${pascalCase(name)}Seeds`,
|
|
168
|
+
programAccountsEnum: (name) => `${pascalCase(name)}Account`,
|
|
169
|
+
programAccountsEnumVariant: (name) => `${pascalCase(name)}`,
|
|
170
|
+
programAccountsIdentifierFunction: (name) => `identify${pascalCase(name)}Account`,
|
|
171
|
+
programAddressConstant: (name) => `${snakeCase(name).toUpperCase()}_PROGRAM_ADDRESS`,
|
|
172
|
+
programErrorConstant: (name) => snakeCase(name).toUpperCase(),
|
|
173
|
+
programErrorConstantPrefix: (name) => `${snakeCase(name).toUpperCase()}_ERROR__`,
|
|
174
|
+
programErrorMessagesMap: (name) => `${camelCase(name)}ErrorMessages`,
|
|
175
|
+
programErrorUnion: (name) => `${pascalCase(name)}Error`,
|
|
176
|
+
programGetErrorMessageFunction: (name) => `get${pascalCase(name)}ErrorMessage`,
|
|
177
|
+
programInstructionsEnum: (name) => `${pascalCase(name)}Instruction`,
|
|
178
|
+
programInstructionsEnumVariant: (name) => `${pascalCase(name)}`,
|
|
179
|
+
programInstructionsIdentifierFunction: (name) => `identify${pascalCase(name)}Instruction`,
|
|
180
|
+
programInstructionsParsedUnionType: (name) => `Parsed${pascalCase(name)}Instruction`,
|
|
181
|
+
programIsErrorFunction: (name) => `is${pascalCase(name)}Error`,
|
|
182
|
+
resolverFunction: (name) => `${camelCase(name)}`
|
|
132
183
|
};
|
|
133
184
|
|
|
134
|
-
// src/
|
|
135
|
-
import {
|
|
185
|
+
// src/utils/fragment.ts
|
|
186
|
+
import { createFragmentTemplate } from "@codama/renderers-core";
|
|
187
|
+
function createFragment(content) {
|
|
188
|
+
return Object.freeze({ content, features: /* @__PURE__ */ new Set(), imports: createImportMap() });
|
|
189
|
+
}
|
|
190
|
+
function isFragment(value) {
|
|
191
|
+
return typeof value === "object" && value !== null && "content" in value;
|
|
192
|
+
}
|
|
193
|
+
function fragment(template, ...items) {
|
|
194
|
+
return createFragmentTemplate(template, items, isFragment, mergeFragments);
|
|
195
|
+
}
|
|
196
|
+
function mergeFragments(fragments, mergeContent) {
|
|
197
|
+
const filteredFragments = fragments.filter((f) => f !== void 0);
|
|
198
|
+
return Object.freeze({
|
|
199
|
+
content: mergeContent(filteredFragments.map((fragment2) => fragment2.content)),
|
|
200
|
+
features: new Set(filteredFragments.flatMap((f) => [...f.features])),
|
|
201
|
+
imports: mergeImportMaps(filteredFragments.map((f) => f.imports))
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function use(importInput, module) {
|
|
205
|
+
const importInfo = parseImportInput(importInput);
|
|
206
|
+
return addFragmentImports(createFragment(importInfo.usedIdentifier), module, [importInput]);
|
|
207
|
+
}
|
|
208
|
+
function mergeFragmentImports(fragment2, importMaps) {
|
|
209
|
+
return Object.freeze({ ...fragment2, imports: mergeImportMaps([fragment2.imports, ...importMaps]) });
|
|
210
|
+
}
|
|
211
|
+
function addFragmentImports(fragment2, module, importInputs) {
|
|
212
|
+
return Object.freeze({ ...fragment2, imports: addToImportMap(fragment2.imports, module, importInputs) });
|
|
213
|
+
}
|
|
214
|
+
function removeFragmentImports(fragment2, module, usedIdentifiers) {
|
|
215
|
+
return Object.freeze({ ...fragment2, imports: removeFromImportMap(fragment2.imports, module, usedIdentifiers) });
|
|
216
|
+
}
|
|
217
|
+
function addFragmentFeatures(fragment2, features) {
|
|
218
|
+
return Object.freeze({ ...fragment2, features: /* @__PURE__ */ new Set([...fragment2.features, ...features]) });
|
|
219
|
+
}
|
|
220
|
+
function getExportAllFragment(module) {
|
|
221
|
+
return fragment`export * from '${module}';`;
|
|
222
|
+
}
|
|
223
|
+
function getDocblockFragment(lines, withLineJump = false) {
|
|
224
|
+
const lineJump = withLineJump ? "\n" : "";
|
|
225
|
+
if (lines.length === 0) return;
|
|
226
|
+
if (lines.length === 1) return fragment`/** ${lines[0]} */${lineJump}`;
|
|
227
|
+
const prefixedLines = lines.map((line) => line ? ` * ${line}` : " *");
|
|
228
|
+
return fragment`/**\n${prefixedLines.join("\n")}\n */${lineJump}`;
|
|
229
|
+
}
|
|
230
|
+
function getPageFragment(page, scope) {
|
|
231
|
+
const header = getDocblockFragment([
|
|
232
|
+
"This code was AUTOGENERATED using the Codama library.",
|
|
233
|
+
"Please DO NOT EDIT THIS FILE, instead use visitors",
|
|
234
|
+
"to add features, then rerun Codama to update it.",
|
|
235
|
+
"",
|
|
236
|
+
"@see https://github.com/codama-idl/codama"
|
|
237
|
+
]);
|
|
238
|
+
const imports = page.imports.size === 0 ? void 0 : fragment`${importMapToString(page.imports, scope.dependencyMap, scope.useGranularImports)}`;
|
|
239
|
+
return mergeFragments([header, imports, page], (cs) => cs.join("\n\n"));
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// src/utils/typeManifest.ts
|
|
243
|
+
function typeManifest(input = {}) {
|
|
244
|
+
return Object.freeze({
|
|
245
|
+
decoder: fragment``,
|
|
246
|
+
encoder: fragment``,
|
|
247
|
+
isEnum: false,
|
|
248
|
+
looseType: fragment``,
|
|
249
|
+
strictType: fragment``,
|
|
250
|
+
value: fragment``,
|
|
251
|
+
...input
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
function mergeTypeManifests(manifests, options = {}) {
|
|
255
|
+
const { mergeTypes, mergeCodecs, mergeValues } = options;
|
|
256
|
+
const merge = (fragmentFn, mergeFn) => mergeFn ? mergeFragments(manifests.map(fragmentFn), mergeFn) : fragment``;
|
|
257
|
+
return Object.freeze({
|
|
258
|
+
decoder: merge((m) => m.decoder, mergeCodecs),
|
|
259
|
+
encoder: merge((m) => m.encoder, mergeCodecs),
|
|
260
|
+
isEnum: false,
|
|
261
|
+
looseType: merge((m) => m.looseType, mergeTypes),
|
|
262
|
+
strictType: merge((m) => m.strictType, mergeTypes),
|
|
263
|
+
value: merge((m) => m.value, mergeValues)
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// src/visitors/getRenderMapVisitor.ts
|
|
268
|
+
import {
|
|
269
|
+
camelCase as camelCase14,
|
|
270
|
+
getAllAccounts,
|
|
271
|
+
getAllDefinedTypes,
|
|
272
|
+
getAllInstructionsWithSubs as getAllInstructionsWithSubs2,
|
|
273
|
+
getAllPdas,
|
|
274
|
+
getAllPrograms
|
|
275
|
+
} from "@codama/nodes";
|
|
276
|
+
import { createRenderMap, mergeRenderMaps } from "@codama/renderers-core";
|
|
277
|
+
import {
|
|
278
|
+
extendVisitor as extendVisitor2,
|
|
279
|
+
getByteSizeVisitor,
|
|
280
|
+
getResolvedInstructionInputsVisitor,
|
|
281
|
+
LinkableDictionary as LinkableDictionary3,
|
|
282
|
+
NodeStack as NodeStack2,
|
|
283
|
+
pipe as pipe16,
|
|
284
|
+
recordLinkablesOnFirstVisitVisitor,
|
|
285
|
+
recordNodeStackVisitor as recordNodeStackVisitor2,
|
|
286
|
+
staticVisitor as staticVisitor2,
|
|
287
|
+
visit as visit9
|
|
288
|
+
} from "@codama/visitors-core";
|
|
136
289
|
|
|
137
|
-
// src/fragments/
|
|
138
|
-
import {
|
|
290
|
+
// src/fragments/accountFetchHelpers.ts
|
|
291
|
+
import { getLastNodeFromPath, pipe } from "@codama/visitors-core";
|
|
139
292
|
|
|
140
293
|
// src/utils/async.ts
|
|
141
294
|
import {
|
|
@@ -232,7 +385,7 @@ function getBytesFromBytesValueNode(node) {
|
|
|
232
385
|
|
|
233
386
|
// src/utils/customData.ts
|
|
234
387
|
import {
|
|
235
|
-
camelCase,
|
|
388
|
+
camelCase as camelCase2,
|
|
236
389
|
definedTypeLinkNode,
|
|
237
390
|
definedTypeNode,
|
|
238
391
|
isNode as isNode2,
|
|
@@ -241,13 +394,13 @@ import {
|
|
|
241
394
|
var parseCustomDataOptions = (customDataOptions, defaultSuffix) => new Map(
|
|
242
395
|
customDataOptions.map((o) => {
|
|
243
396
|
const options = typeof o === "string" ? { name: o } : o;
|
|
244
|
-
const importAs =
|
|
397
|
+
const importAs = camelCase2(options.importAs ?? `${options.name}${defaultSuffix}`);
|
|
245
398
|
const importFrom = options.importFrom ?? "hooked";
|
|
246
399
|
return [
|
|
247
|
-
|
|
400
|
+
camelCase2(options.name),
|
|
248
401
|
{
|
|
249
402
|
extract: options.extract ?? false,
|
|
250
|
-
extractAs: options.extractAs ?
|
|
403
|
+
extractAs: options.extractAs ? camelCase2(options.extractAs) : importAs,
|
|
251
404
|
importAs,
|
|
252
405
|
importFrom,
|
|
253
406
|
linkNode: definedTypeLinkNode(importAs)
|
|
@@ -318,169 +471,128 @@ function getImportFromFactory(overrides, customAccountData, customInstructionDat
|
|
|
318
471
|
};
|
|
319
472
|
}
|
|
320
473
|
|
|
321
|
-
// src/
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
474
|
+
// src/fragments/accountFetchHelpers.ts
|
|
475
|
+
function getAccountFetchHelpersFragment(scope) {
|
|
476
|
+
const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
|
|
477
|
+
const accountNode = getLastNodeFromPath(accountPath);
|
|
478
|
+
const decodeFunction = nameApi.accountDecodeFunction(accountNode.name);
|
|
479
|
+
const fetchAllFunction = nameApi.accountFetchAllFunction(accountNode.name);
|
|
480
|
+
const fetchAllMaybeFunction = nameApi.accountFetchAllMaybeFunction(accountNode.name);
|
|
481
|
+
const fetchFunction = nameApi.accountFetchFunction(accountNode.name);
|
|
482
|
+
const fetchMaybeFunction = nameApi.accountFetchMaybeFunction(accountNode.name);
|
|
483
|
+
const hasCustomData = customAccountData.has(accountNode.name);
|
|
484
|
+
const accountType = hasCustomData ? typeManifest2.strictType : nameApi.dataType(accountNode.name);
|
|
485
|
+
const decoderFunction = hasCustomData ? typeManifest2.decoder : `${nameApi.decoderFunction(accountNode.name)}()`;
|
|
486
|
+
return pipe(
|
|
487
|
+
fragment`export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: EncodedAccount<TAddress>): Account<${accountType}, TAddress>;
|
|
488
|
+
export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: MaybeEncodedAccount<TAddress>): MaybeAccount<${accountType}, TAddress>;
|
|
489
|
+
export function ${decodeFunction}<TAddress extends string = string>(encodedAccount: EncodedAccount<TAddress> | MaybeEncodedAccount<TAddress>): Account<${accountType}, TAddress> | MaybeAccount<${accountType}, TAddress> {
|
|
490
|
+
return decodeAccount(encodedAccount as MaybeEncodedAccount<TAddress>, ${decoderFunction});
|
|
335
491
|
}
|
|
336
|
-
var render = (template, context, options) => {
|
|
337
|
-
const dirname = true ? pathDirname(fileURLToPath(import.meta.url)) : __dirname;
|
|
338
|
-
const templates = false ? join(dirname, "..", "..", "public", "templates") : join(dirname, "templates");
|
|
339
|
-
const env = nunjucks.configure(templates, { autoescape: false, trimBlocks: true, ...options });
|
|
340
|
-
env.addFilter("pascalCase", pascalCase);
|
|
341
|
-
env.addFilter("camelCase", camelCase2);
|
|
342
|
-
env.addFilter("snakeCase", snakeCase);
|
|
343
|
-
env.addFilter("kebabCase", kebabCase);
|
|
344
|
-
env.addFilter("titleCase", titleCase);
|
|
345
|
-
env.addFilter("jsDocblock", jsDocblock);
|
|
346
|
-
return env.render(template, context);
|
|
347
|
-
};
|
|
348
492
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
493
|
+
export async function ${fetchFunction}<TAddress extends string = string>(
|
|
494
|
+
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
495
|
+
address: Address<TAddress>,
|
|
496
|
+
config?: FetchAccountConfig,
|
|
497
|
+
): Promise<Account<${accountType}, TAddress>> {
|
|
498
|
+
const maybeAccount = await ${fetchMaybeFunction}(rpc, address, config);
|
|
499
|
+
assertAccountExists(maybeAccount);
|
|
500
|
+
return maybeAccount;
|
|
352
501
|
}
|
|
353
|
-
|
|
354
|
-
|
|
502
|
+
|
|
503
|
+
export async function ${fetchMaybeFunction}<TAddress extends string = string>(
|
|
504
|
+
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
505
|
+
address: Address<TAddress>,
|
|
506
|
+
config?: FetchAccountConfig,
|
|
507
|
+
): Promise<MaybeAccount<${accountType}, TAddress>> {
|
|
508
|
+
const maybeAccount = await fetchEncodedAccount(rpc, address, config);
|
|
509
|
+
return ${decodeFunction}(maybeAccount);
|
|
355
510
|
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
511
|
+
|
|
512
|
+
export async function ${fetchAllFunction}(
|
|
513
|
+
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
514
|
+
addresses: Array<Address>,
|
|
515
|
+
config?: FetchAccountsConfig,
|
|
516
|
+
): Promise<Account<${accountType}>[]> {
|
|
517
|
+
const maybeAccounts = await ${fetchAllMaybeFunction}(rpc, addresses, config);
|
|
518
|
+
assertAccountsExist(maybeAccounts);
|
|
519
|
+
return maybeAccounts;
|
|
362
520
|
}
|
|
363
|
-
var Fragment = class _Fragment {
|
|
364
|
-
render;
|
|
365
|
-
imports;
|
|
366
|
-
features;
|
|
367
|
-
constructor(render2, imports, features) {
|
|
368
|
-
this.render = render2;
|
|
369
|
-
this.imports = imports ? new ImportMap().mergeWith(imports) : new ImportMap();
|
|
370
|
-
this.features = /* @__PURE__ */ new Set([...features ?? []]);
|
|
371
|
-
}
|
|
372
|
-
setRender(render2) {
|
|
373
|
-
this.render = render2;
|
|
374
|
-
return this;
|
|
375
|
-
}
|
|
376
|
-
mapRender(fn) {
|
|
377
|
-
this.render = fn(this.render);
|
|
378
|
-
return this;
|
|
379
|
-
}
|
|
380
|
-
addImports(module, imports) {
|
|
381
|
-
this.imports.add(module, imports);
|
|
382
|
-
return this;
|
|
383
|
-
}
|
|
384
|
-
removeImports(module, imports) {
|
|
385
|
-
this.imports.remove(module, imports);
|
|
386
|
-
return this;
|
|
387
|
-
}
|
|
388
|
-
mergeImportsWith(...others) {
|
|
389
|
-
this.imports.mergeWith(...others);
|
|
390
|
-
return this;
|
|
391
|
-
}
|
|
392
|
-
addImportAlias(module, name, alias) {
|
|
393
|
-
this.imports.addAlias(module, name, alias);
|
|
394
|
-
return this;
|
|
395
|
-
}
|
|
396
|
-
addFeatures(features) {
|
|
397
|
-
const featureArray = typeof features === "string" ? [features] : features;
|
|
398
|
-
featureArray.forEach((f) => this.features.add(f));
|
|
399
|
-
return this;
|
|
400
|
-
}
|
|
401
|
-
removeFeatures(features) {
|
|
402
|
-
const featureArray = typeof features === "string" ? [features] : features;
|
|
403
|
-
featureArray.forEach((f) => this.features.delete(f));
|
|
404
|
-
return this;
|
|
405
|
-
}
|
|
406
|
-
hasFeatures(features) {
|
|
407
|
-
const featureArray = typeof features === "string" ? [features] : features;
|
|
408
|
-
return featureArray.every((f) => this.features.has(f));
|
|
409
|
-
}
|
|
410
|
-
mergeFeaturesWith(...others) {
|
|
411
|
-
others.forEach((f) => this.addFeatures([...f.features]));
|
|
412
|
-
return this;
|
|
413
|
-
}
|
|
414
|
-
clone() {
|
|
415
|
-
return new _Fragment(this.render).mergeImportsWith(this.imports);
|
|
416
|
-
}
|
|
417
|
-
toString() {
|
|
418
|
-
return this.render;
|
|
419
|
-
}
|
|
420
|
-
};
|
|
421
521
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
const
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
"type FetchAccountConfig",
|
|
446
|
-
"type FetchAccountsConfig",
|
|
447
|
-
"type MaybeAccount",
|
|
448
|
-
"type MaybeEncodedAccount"
|
|
449
|
-
]);
|
|
522
|
+
export async function ${fetchAllMaybeFunction}(
|
|
523
|
+
rpc: Parameters<typeof fetchEncodedAccounts>[0],
|
|
524
|
+
addresses: Array<Address>,
|
|
525
|
+
config?: FetchAccountsConfig,
|
|
526
|
+
): Promise<MaybeAccount<${accountType}>[]> {
|
|
527
|
+
const maybeAccounts = await fetchEncodedAccounts(rpc, addresses, config);
|
|
528
|
+
return maybeAccounts.map((maybeAccount) => ${decodeFunction}(maybeAccount));
|
|
529
|
+
}`,
|
|
530
|
+
(f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
|
|
531
|
+
(f) => addFragmentImports(f, "solanaAccounts", [
|
|
532
|
+
"type Account",
|
|
533
|
+
"assertAccountExists",
|
|
534
|
+
"assertAccountsExist",
|
|
535
|
+
"decodeAccount",
|
|
536
|
+
"type EncodedAccount",
|
|
537
|
+
"fetchEncodedAccount",
|
|
538
|
+
"fetchEncodedAccounts",
|
|
539
|
+
"type FetchAccountConfig",
|
|
540
|
+
"type FetchAccountsConfig",
|
|
541
|
+
"type MaybeAccount",
|
|
542
|
+
"type MaybeEncodedAccount"
|
|
543
|
+
])
|
|
544
|
+
);
|
|
450
545
|
}
|
|
451
546
|
|
|
547
|
+
// src/fragments/accountPage.ts
|
|
548
|
+
import { resolveNestedTypeNode as resolveNestedTypeNode2 } from "@codama/nodes";
|
|
549
|
+
import { findProgramNodeFromPath, getLastNodeFromPath as getLastNodeFromPath5, visit as visit2 } from "@codama/visitors-core";
|
|
550
|
+
|
|
452
551
|
// src/fragments/accountPdaHelpers.ts
|
|
453
552
|
import { isNodeFilter } from "@codama/nodes";
|
|
454
|
-
import {
|
|
553
|
+
import { getLastNodeFromPath as getLastNodeFromPath2, pipe as pipe2 } from "@codama/visitors-core";
|
|
455
554
|
function getAccountPdaHelpersFragment(scope) {
|
|
456
555
|
const { accountPath, nameApi, linkables, customAccountData, typeManifest: typeManifest2 } = scope;
|
|
457
556
|
const accountNode = getLastNodeFromPath2(accountPath);
|
|
458
|
-
const programNode = findProgramNodeFromPath(accountPath);
|
|
459
557
|
const pdaNode = accountNode.pda ? linkables.get([...accountPath, accountNode.pda]) : void 0;
|
|
460
|
-
if (!pdaNode)
|
|
461
|
-
|
|
462
|
-
}
|
|
463
|
-
const accountTypeFragment = customAccountData.has(accountNode.name) ? typeManifest2.strictType.clone() : fragment(nameApi.dataType(accountNode.name));
|
|
558
|
+
if (!pdaNode) return;
|
|
559
|
+
const accountType = customAccountData.has(accountNode.name) ? typeManifest2.strictType : nameApi.dataType(accountNode.name);
|
|
464
560
|
const importFrom = "generatedPdas";
|
|
465
561
|
const pdaSeedsType = nameApi.pdaSeedsType(pdaNode.name);
|
|
466
562
|
const findPdaFunction = nameApi.pdaFindFunction(pdaNode.name);
|
|
467
563
|
const hasVariableSeeds = pdaNode.seeds.filter(isNodeFilter("variablePdaSeedNode")).length > 0;
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
]
|
|
564
|
+
const fetchFromSeedsFunction = nameApi.accountFetchFromSeedsFunction(accountNode.name);
|
|
565
|
+
const fetchMaybeFromSeedsFunction = nameApi.accountFetchMaybeFromSeedsFunction(accountNode.name);
|
|
566
|
+
const fetchMaybeFunction = nameApi.accountFetchMaybeFunction(accountNode.name);
|
|
567
|
+
return pipe2(
|
|
568
|
+
fragment`export async function ${fetchFromSeedsFunction}(
|
|
569
|
+
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
570
|
+
${hasVariableSeeds ? `seeds: ${pdaSeedsType},` : ""}
|
|
571
|
+
config: FetchAccountConfig & { programAddress?: Address } = {},
|
|
572
|
+
): Promise<Account<${accountType}>> {
|
|
573
|
+
const maybeAccount = await ${fetchMaybeFromSeedsFunction}(rpc, ${hasVariableSeeds ? "seeds, " : ""}config);
|
|
574
|
+
assertAccountExists(maybeAccount);
|
|
575
|
+
return maybeAccount;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
export async function ${fetchMaybeFromSeedsFunction}(
|
|
579
|
+
rpc: Parameters<typeof fetchEncodedAccount>[0],
|
|
580
|
+
${hasVariableSeeds ? `seeds: ${pdaSeedsType},` : ""}
|
|
581
|
+
config: FetchAccountConfig & { programAddress?: Address } = {},
|
|
582
|
+
): Promise<MaybeAccount<${accountType}>> {
|
|
583
|
+
const { programAddress, ...fetchConfig } = config;
|
|
584
|
+
const [address] = await ${findPdaFunction}(${hasVariableSeeds ? "seeds, " : ""}{ programAddress });
|
|
585
|
+
return await ${fetchMaybeFunction}(rpc, address, fetchConfig);
|
|
586
|
+
}`,
|
|
587
|
+
(f) => addFragmentImports(f, importFrom, hasVariableSeeds ? [pdaSeedsType, findPdaFunction] : [findPdaFunction]),
|
|
588
|
+
(f) => addFragmentImports(f, "solanaAddresses", ["type Address"]),
|
|
589
|
+
(f) => addFragmentImports(f, "solanaAccounts", [
|
|
590
|
+
"type Account",
|
|
591
|
+
"assertAccountExists",
|
|
592
|
+
"type FetchAccountConfig",
|
|
593
|
+
"type MaybeAccount"
|
|
594
|
+
])
|
|
595
|
+
);
|
|
484
596
|
}
|
|
485
597
|
|
|
486
598
|
// src/fragments/accountSizeHelpers.ts
|
|
@@ -488,13 +600,11 @@ import { getLastNodeFromPath as getLastNodeFromPath3 } from "@codama/visitors-co
|
|
|
488
600
|
function getAccountSizeHelpersFragment(scope) {
|
|
489
601
|
const { accountPath, nameApi } = scope;
|
|
490
602
|
const accountNode = getLastNodeFromPath3(accountPath);
|
|
491
|
-
if (accountNode.size == null)
|
|
492
|
-
|
|
493
|
-
}
|
|
494
|
-
return
|
|
495
|
-
|
|
496
|
-
getSizeFunction: nameApi.accountGetSizeFunction(accountNode.name)
|
|
497
|
-
});
|
|
603
|
+
if (accountNode.size == null) return;
|
|
604
|
+
const getSizeFunction = nameApi.accountGetSizeFunction(accountNode.name);
|
|
605
|
+
return fragment`export function ${getSizeFunction}(): number {
|
|
606
|
+
return ${accountNode.size};
|
|
607
|
+
}`;
|
|
498
608
|
}
|
|
499
609
|
|
|
500
610
|
// src/fragments/accountType.ts
|
|
@@ -504,70 +614,70 @@ import { getLastNodeFromPath as getLastNodeFromPath4 } from "@codama/visitors-co
|
|
|
504
614
|
// src/fragments/type.ts
|
|
505
615
|
function getTypeFragment(scope) {
|
|
506
616
|
const { name, manifest, nameApi, docs = [] } = scope;
|
|
507
|
-
const
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
if (!manifest.isEnum) {
|
|
514
|
-
typeFragment.mergeImportsWith(manifest.strictType, manifest.looseType);
|
|
617
|
+
const docblock = getDocblockFragment(docs, true);
|
|
618
|
+
const strictName = nameApi.dataType(name);
|
|
619
|
+
const looseName = nameApi.dataArgsType(name);
|
|
620
|
+
const aliasedLooseName = `export type ${looseName} = ${strictName};`;
|
|
621
|
+
if (manifest.isEnum) {
|
|
622
|
+
return fragment`${docblock}export enum ${strictName} ${manifest.strictType};\n\n${aliasedLooseName}`;
|
|
515
623
|
}
|
|
516
|
-
|
|
624
|
+
const looseExport = manifest.strictType.content === manifest.looseType.content ? aliasedLooseName : fragment`export type ${looseName} = ${manifest.looseType};`;
|
|
625
|
+
return fragment`${docblock}export type ${strictName} = ${manifest.strictType};\n\n${looseExport}`;
|
|
517
626
|
}
|
|
518
627
|
|
|
519
628
|
// src/fragments/typeDecoder.ts
|
|
520
629
|
import { isDataEnum, isNode as isNode3 } from "@codama/nodes";
|
|
521
630
|
function getTypeDecoderFragment(scope) {
|
|
522
631
|
const { name, node, manifest, nameApi, docs = [] } = scope;
|
|
523
|
-
const
|
|
632
|
+
const decoderFunction = nameApi.decoderFunction(name);
|
|
633
|
+
const strictName = nameApi.dataType(name);
|
|
634
|
+
const docblock = getDocblockFragment(docs, true);
|
|
635
|
+
const decoderType = use(
|
|
636
|
+
typeof scope.size === "number" ? "type FixedSizeDecoder" : "type Decoder",
|
|
637
|
+
"solanaCodecsCore"
|
|
638
|
+
);
|
|
524
639
|
const useTypeCast = isNode3(node, "enumTypeNode") && isDataEnum(node) && typeof scope.size === "number";
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
looseName: nameApi.dataArgsType(name),
|
|
530
|
-
manifest,
|
|
531
|
-
strictName: nameApi.dataType(name),
|
|
532
|
-
useTypeCast
|
|
533
|
-
}).mergeImportsWith(manifest.decoder).addImports("solanaCodecsCore", `type ${decoderType}`);
|
|
640
|
+
const typeCast = useTypeCast ? fragment` as ${decoderType}<${strictName}>` : "";
|
|
641
|
+
return fragment`${docblock}export function ${decoderFunction}(): ${decoderType}<${strictName}> {
|
|
642
|
+
return ${manifest.decoder}${typeCast};
|
|
643
|
+
}`;
|
|
534
644
|
}
|
|
535
645
|
|
|
536
646
|
// src/fragments/typeEncoder.ts
|
|
537
647
|
import { isDataEnum as isDataEnum2, isNode as isNode4 } from "@codama/nodes";
|
|
538
648
|
function getTypeEncoderFragment(scope) {
|
|
539
649
|
const { name, node, manifest, nameApi, docs = [] } = scope;
|
|
540
|
-
const
|
|
650
|
+
const encoderFunction = nameApi.encoderFunction(name);
|
|
651
|
+
const looseName = nameApi.dataArgsType(name);
|
|
652
|
+
const docblock = getDocblockFragment(docs, true);
|
|
653
|
+
const encoderType = use(
|
|
654
|
+
typeof scope.size === "number" ? "type FixedSizeEncoder" : "type Encoder",
|
|
655
|
+
"solanaCodecsCore"
|
|
656
|
+
);
|
|
541
657
|
const useTypeCast = isNode4(node, "enumTypeNode") && isDataEnum2(node) && typeof scope.size === "number";
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
looseName: nameApi.dataArgsType(name),
|
|
547
|
-
manifest,
|
|
548
|
-
strictName: nameApi.dataType(name),
|
|
549
|
-
useTypeCast
|
|
550
|
-
}).mergeImportsWith(manifest.encoder).addImports("solanaCodecsCore", `type ${encoderType}`);
|
|
658
|
+
const typeCast = useTypeCast ? fragment` as ${encoderType}<${looseName}>` : "";
|
|
659
|
+
return fragment`${docblock}export function ${encoderFunction}(): ${encoderType}<${looseName}> {
|
|
660
|
+
return ${manifest.encoder}${typeCast};
|
|
661
|
+
}`;
|
|
551
662
|
}
|
|
552
663
|
|
|
553
664
|
// src/fragments/typeCodec.ts
|
|
554
665
|
function getTypeCodecFragment(scope) {
|
|
555
|
-
const {
|
|
556
|
-
const
|
|
666
|
+
const { codecDocs = [], name, nameApi } = scope;
|
|
667
|
+
const codecFunction = nameApi.codecFunction(name);
|
|
668
|
+
const decoderFunction = nameApi.decoderFunction(name);
|
|
669
|
+
const encoderFunction = nameApi.encoderFunction(name);
|
|
670
|
+
const looseName = nameApi.dataArgsType(name);
|
|
671
|
+
const strictName = nameApi.dataType(name);
|
|
672
|
+
const docblock = getDocblockFragment(codecDocs, true);
|
|
673
|
+
const codecType = use(typeof scope.size === "number" ? "type FixedSizeCodec" : "type Codec", "solanaCodecsCore");
|
|
557
674
|
return mergeFragments(
|
|
558
675
|
[
|
|
559
676
|
getTypeEncoderFragment({ ...scope, docs: scope.encoderDocs }),
|
|
560
677
|
getTypeDecoderFragment({ ...scope, docs: scope.decoderDocs }),
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
decoderFunction: nameApi.decoderFunction(name),
|
|
565
|
-
docs: scope.codecDocs,
|
|
566
|
-
encoderFunction: nameApi.encoderFunction(name),
|
|
567
|
-
looseName: nameApi.dataArgsType(name),
|
|
568
|
-
manifest,
|
|
569
|
-
strictName: nameApi.dataType(name)
|
|
570
|
-
}).addImports("solanaCodecsCore", [`type ${codecType}`, "combineCodec"])
|
|
678
|
+
fragment`${docblock}export function ${codecFunction}(): ${codecType}<${looseName}, ${strictName}> {
|
|
679
|
+
return ${use("combineCodec", "solanaCodecsCore")}(${encoderFunction}(), ${decoderFunction}());
|
|
680
|
+
}`
|
|
571
681
|
],
|
|
572
682
|
(renders) => renders.join("\n\n")
|
|
573
683
|
);
|
|
@@ -585,9 +695,7 @@ function getTypeWithCodecFragment(scope) {
|
|
|
585
695
|
function getAccountTypeFragment(scope) {
|
|
586
696
|
const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
|
|
587
697
|
const accountNode = getLastNodeFromPath4(accountPath);
|
|
588
|
-
if (customAccountData.has(accountNode.name))
|
|
589
|
-
return fragment("");
|
|
590
|
-
}
|
|
698
|
+
if (customAccountData.has(accountNode.name)) return;
|
|
591
699
|
return getTypeWithCodecFragment({
|
|
592
700
|
manifest: typeManifest2,
|
|
593
701
|
name: accountNode.name,
|
|
@@ -597,41 +705,119 @@ function getAccountTypeFragment(scope) {
|
|
|
597
705
|
});
|
|
598
706
|
}
|
|
599
707
|
|
|
708
|
+
// src/fragments/discriminatorConstants.ts
|
|
709
|
+
import {
|
|
710
|
+
camelCase as camelCase3,
|
|
711
|
+
isNode as isNode5,
|
|
712
|
+
isNodeFilter as isNodeFilter2,
|
|
713
|
+
VALUE_NODES
|
|
714
|
+
} from "@codama/nodes";
|
|
715
|
+
import { visit } from "@codama/visitors-core";
|
|
716
|
+
function getDiscriminatorConstantsFragment(scope) {
|
|
717
|
+
const fragments = scope.discriminatorNodes.map((node) => getDiscriminatorConstantFragment(node, scope)).filter(Boolean);
|
|
718
|
+
return mergeFragments(fragments, (c) => c.join("\n\n"));
|
|
719
|
+
}
|
|
720
|
+
function getDiscriminatorConstantFragment(discriminatorNode, scope) {
|
|
721
|
+
switch (discriminatorNode.kind) {
|
|
722
|
+
case "constantDiscriminatorNode":
|
|
723
|
+
return getConstantDiscriminatorConstantFragment(discriminatorNode, scope);
|
|
724
|
+
case "fieldDiscriminatorNode":
|
|
725
|
+
return getFieldDiscriminatorConstantFragment(discriminatorNode, scope);
|
|
726
|
+
default:
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
function getConstantDiscriminatorConstantFragment(discriminatorNode, scope) {
|
|
731
|
+
const { discriminatorNodes, typeManifestVisitor, prefix } = scope;
|
|
732
|
+
const index = discriminatorNodes.filter(isNodeFilter2("constantDiscriminatorNode")).indexOf(discriminatorNode);
|
|
733
|
+
const suffix = index <= 0 ? "" : `_${index + 1}`;
|
|
734
|
+
const name = camelCase3(`${prefix}_discriminator${suffix}`);
|
|
735
|
+
const encoder = visit(discriminatorNode.constant.type, typeManifestVisitor).encoder;
|
|
736
|
+
const value = visit(discriminatorNode.constant.value, typeManifestVisitor).value;
|
|
737
|
+
return getConstantFragment({ ...scope, encoder, name, value });
|
|
738
|
+
}
|
|
739
|
+
function getFieldDiscriminatorConstantFragment(discriminatorNode, scope) {
|
|
740
|
+
const { fields, prefix, typeManifestVisitor } = scope;
|
|
741
|
+
const field = fields.find((f) => f.name === discriminatorNode.name);
|
|
742
|
+
if (!field || !field.defaultValue || !isNode5(field.defaultValue, VALUE_NODES)) {
|
|
743
|
+
return null;
|
|
744
|
+
}
|
|
745
|
+
const name = camelCase3(`${prefix}_${discriminatorNode.name}`);
|
|
746
|
+
const encoder = visit(field.type, typeManifestVisitor).encoder;
|
|
747
|
+
const value = visit(field.defaultValue, typeManifestVisitor).value;
|
|
748
|
+
return getConstantFragment({ ...scope, encoder, name, value });
|
|
749
|
+
}
|
|
750
|
+
function getConstantFragment(scope) {
|
|
751
|
+
const { encoder, name, nameApi, value } = scope;
|
|
752
|
+
const constantName = nameApi.constant(name);
|
|
753
|
+
const constantFunction = nameApi.constantFunction(name);
|
|
754
|
+
return fragment`export const ${constantName} = ${value};\n\nexport function ${constantFunction}() { return ${encoder}.encode(${constantName}); }`;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// src/fragments/accountPage.ts
|
|
758
|
+
function getAccountPageFragment(scope) {
|
|
759
|
+
const node = getLastNodeFromPath5(scope.accountPath);
|
|
760
|
+
if (!findProgramNodeFromPath(scope.accountPath)) {
|
|
761
|
+
throw new Error("Account must be visited inside a program.");
|
|
762
|
+
}
|
|
763
|
+
const typeManifest2 = visit2(node, scope.typeManifestVisitor);
|
|
764
|
+
const fields = resolveNestedTypeNode2(node.data).fields;
|
|
765
|
+
return mergeFragments(
|
|
766
|
+
[
|
|
767
|
+
getDiscriminatorConstantsFragment({
|
|
768
|
+
...scope,
|
|
769
|
+
discriminatorNodes: node.discriminators ?? [],
|
|
770
|
+
fields,
|
|
771
|
+
prefix: node.name
|
|
772
|
+
}),
|
|
773
|
+
getAccountTypeFragment({ ...scope, typeManifest: typeManifest2 }),
|
|
774
|
+
getAccountFetchHelpersFragment({ ...scope, typeManifest: typeManifest2 }),
|
|
775
|
+
getAccountSizeHelpersFragment(scope),
|
|
776
|
+
getAccountPdaHelpersFragment({ ...scope, typeManifest: typeManifest2 })
|
|
777
|
+
],
|
|
778
|
+
(cs) => cs.join("\n\n")
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
|
|
600
782
|
// src/fragments/discriminatorCondition.ts
|
|
601
783
|
import {
|
|
602
784
|
constantDiscriminatorNode,
|
|
603
785
|
constantValueNode,
|
|
604
786
|
constantValueNodeFromBytes,
|
|
605
|
-
isNode as
|
|
606
|
-
isNodeFilter as
|
|
787
|
+
isNode as isNode6,
|
|
788
|
+
isNodeFilter as isNodeFilter3
|
|
607
789
|
} from "@codama/nodes";
|
|
608
|
-
import {
|
|
790
|
+
import { mapFragmentContent } from "@codama/renderers-core";
|
|
791
|
+
import { pipe as pipe3, visit as visit3 } from "@codama/visitors-core";
|
|
609
792
|
import { getBase64Decoder } from "@solana/codecs-strings";
|
|
610
793
|
function getDiscriminatorConditionFragment(scope) {
|
|
611
|
-
return
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
794
|
+
return pipe3(
|
|
795
|
+
mergeFragments(
|
|
796
|
+
scope.discriminators.flatMap((discriminator) => {
|
|
797
|
+
if (isNode6(discriminator, "sizeDiscriminatorNode")) {
|
|
798
|
+
return [getSizeConditionFragment(discriminator, scope)];
|
|
799
|
+
}
|
|
800
|
+
if (isNode6(discriminator, "constantDiscriminatorNode")) {
|
|
801
|
+
return [getByteConditionFragment(discriminator, scope)];
|
|
802
|
+
}
|
|
803
|
+
if (isNode6(discriminator, "fieldDiscriminatorNode")) {
|
|
804
|
+
return [getFieldConditionFragment(discriminator, scope)];
|
|
805
|
+
}
|
|
806
|
+
return [];
|
|
807
|
+
}),
|
|
808
|
+
(c) => c.join(" && ")
|
|
809
|
+
),
|
|
810
|
+
(f) => mapFragmentContent(f, (c) => `if (${c}) { ${scope.ifTrue}; }`)
|
|
811
|
+
);
|
|
626
812
|
}
|
|
627
813
|
function getSizeConditionFragment(discriminator, scope) {
|
|
628
814
|
const { dataName } = scope;
|
|
629
|
-
return fragment
|
|
815
|
+
return fragment`${dataName}.length === ${discriminator.size}`;
|
|
630
816
|
}
|
|
631
817
|
function getByteConditionFragment(discriminator, scope) {
|
|
632
818
|
const { dataName, typeManifestVisitor } = scope;
|
|
633
|
-
const constant =
|
|
634
|
-
return
|
|
819
|
+
const constant = visit3(discriminator.constant, typeManifestVisitor).value;
|
|
820
|
+
return fragment`${use("containsBytes", "solanaCodecsCore")}(${dataName}, ${constant}, ${discriminator.offset})`;
|
|
635
821
|
}
|
|
636
822
|
function getFieldConditionFragment(discriminator, scope) {
|
|
637
823
|
const field = scope.struct.fields.find((f) => f.name === discriminator.name);
|
|
@@ -640,7 +826,7 @@ function getFieldConditionFragment(discriminator, scope) {
|
|
|
640
826
|
`Field discriminator "${discriminator.name}" does not have a matching argument with default value.`
|
|
641
827
|
);
|
|
642
828
|
}
|
|
643
|
-
if (
|
|
829
|
+
if (isNode6(field.type, "arrayTypeNode") && isNode6(field.type.item, "numberTypeNode") && field.type.item.format === "u8" && isNode6(field.type.count, "fixedCountNode") && isNode6(field.defaultValue, "arrayValueNode") && field.defaultValue.items.every(isNodeFilter3("numberValueNode"))) {
|
|
644
830
|
const base64Bytes = getBase64Decoder().decode(
|
|
645
831
|
new Uint8Array(field.defaultValue.items.map((node) => node.number))
|
|
646
832
|
);
|
|
@@ -655,20 +841,103 @@ function getFieldConditionFragment(discriminator, scope) {
|
|
|
655
841
|
);
|
|
656
842
|
}
|
|
657
843
|
|
|
844
|
+
// src/fragments/errorPage.ts
|
|
845
|
+
function getErrorPageFragment(scope) {
|
|
846
|
+
return mergeFragments(
|
|
847
|
+
[
|
|
848
|
+
getConstantsFragment(scope),
|
|
849
|
+
getConstantUnionTypeFragment(scope),
|
|
850
|
+
getErrorMessagesFragment(scope),
|
|
851
|
+
getErrorMessageFunctionFragment(scope),
|
|
852
|
+
getIsErrorFunctionFragment(scope)
|
|
853
|
+
],
|
|
854
|
+
(cs) => cs.join("\n\n")
|
|
855
|
+
);
|
|
856
|
+
}
|
|
857
|
+
function getConstantsFragment(scope) {
|
|
858
|
+
const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
|
|
859
|
+
return mergeFragments(
|
|
860
|
+
[...scope.programNode.errors].sort((a, b) => a.code - b.code).map((error) => {
|
|
861
|
+
const docs = getDocblockFragment(error.docs ?? [], true);
|
|
862
|
+
const name = constantPrefix + scope.nameApi.programErrorConstant(error.name);
|
|
863
|
+
return fragment`${docs}export const ${name} = 0x${error.code.toString(16)}; // ${error.code}`;
|
|
864
|
+
}),
|
|
865
|
+
(cs) => cs.join("\n")
|
|
866
|
+
);
|
|
867
|
+
}
|
|
868
|
+
function getConstantUnionTypeFragment(scope) {
|
|
869
|
+
const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
|
|
870
|
+
const typeName = scope.nameApi.programErrorUnion(scope.programNode.name);
|
|
871
|
+
const errorTypes = mergeFragments(
|
|
872
|
+
[...scope.programNode.errors].sort((a, b) => a.name.localeCompare(b.name)).map((error) => fragment`typeof ${constantPrefix + scope.nameApi.programErrorConstant(error.name)}`),
|
|
873
|
+
(cs) => cs.join(" | ")
|
|
874
|
+
);
|
|
875
|
+
return fragment`export type ${typeName} = ${errorTypes};`;
|
|
876
|
+
}
|
|
877
|
+
function getErrorMessagesFragment(scope) {
|
|
878
|
+
const mapName = scope.nameApi.programErrorMessagesMap(scope.programNode.name);
|
|
879
|
+
const errorUnionType = scope.nameApi.programErrorUnion(scope.programNode.name);
|
|
880
|
+
const constantPrefix = scope.nameApi.programErrorConstantPrefix(scope.programNode.name);
|
|
881
|
+
const messageEntries = mergeFragments(
|
|
882
|
+
[...scope.programNode.errors].sort((a, b) => a.name.localeCompare(b.name)).map((error) => {
|
|
883
|
+
const constantName = constantPrefix + scope.nameApi.programErrorConstant(error.name);
|
|
884
|
+
const escapedMessage = error.message.replace(/`/g, "\\`");
|
|
885
|
+
return fragment`[${constantName}]: \`${escapedMessage}\``;
|
|
886
|
+
}),
|
|
887
|
+
(cs) => cs.join(", ")
|
|
888
|
+
);
|
|
889
|
+
return fragment`let ${mapName}: Record<${errorUnionType}, string> | undefined;
|
|
890
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
891
|
+
${mapName} = { ${messageEntries} };
|
|
892
|
+
}`;
|
|
893
|
+
}
|
|
894
|
+
function getErrorMessageFunctionFragment(scope) {
|
|
895
|
+
const functionName = scope.nameApi.programGetErrorMessageFunction(scope.programNode.name);
|
|
896
|
+
const errorUnionType = scope.nameApi.programErrorUnion(scope.programNode.name);
|
|
897
|
+
const messageMapName = scope.nameApi.programErrorMessagesMap(scope.programNode.name);
|
|
898
|
+
return fragment`export function ${functionName}(code: ${errorUnionType}): string {
|
|
899
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
900
|
+
return (${messageMapName} as Record<${errorUnionType}, string>)[code];
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
return 'Error message not available in production bundles.';
|
|
904
|
+
}`;
|
|
905
|
+
}
|
|
906
|
+
function getIsErrorFunctionFragment(scope) {
|
|
907
|
+
const { programNode, nameApi } = scope;
|
|
908
|
+
const programAddressConstant = use(nameApi.programAddressConstant(programNode.name), "generatedPrograms");
|
|
909
|
+
const functionName = nameApi.programIsErrorFunction(programNode.name);
|
|
910
|
+
const programErrorUnion = nameApi.programErrorUnion(programNode.name);
|
|
911
|
+
return fragment`export function ${functionName}<TProgramErrorCode extends ${programErrorUnion}>(
|
|
912
|
+
error: unknown,
|
|
913
|
+
transactionMessage: { instructions: Record<number, { programAddress: ${use("type Address", "solanaAddresses")} }> },
|
|
914
|
+
code?: TProgramErrorCode,
|
|
915
|
+
): error is ${use("type SolanaError", "solanaErrors")}<typeof ${use("type SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM", "solanaErrors")}> & Readonly<{ context: Readonly<{ code: TProgramErrorCode }> }> {
|
|
916
|
+
return ${use("isProgramError", "solanaPrograms")}<TProgramErrorCode>(error, transactionMessage, ${programAddressConstant}, code);
|
|
917
|
+
}`;
|
|
918
|
+
}
|
|
919
|
+
|
|
920
|
+
// src/fragments/indexPage.ts
|
|
921
|
+
function getIndexPageFragment(items) {
|
|
922
|
+
if (items.length === 0) return;
|
|
923
|
+
const names = items.map((item) => item.name).sort((a, b) => a.localeCompare(b)).map((name) => getExportAllFragment(`./${name}`));
|
|
924
|
+
return mergeFragments(names, (cs) => cs.join("\n"));
|
|
925
|
+
}
|
|
926
|
+
|
|
658
927
|
// src/fragments/instructionAccountMeta.ts
|
|
659
928
|
import { pascalCase as pascalCase2 } from "@codama/nodes";
|
|
660
929
|
function getInstructionAccountMetaFragment(instructionAccountNode) {
|
|
661
930
|
const typeParam = `TAccount${pascalCase2(instructionAccountNode.name)}`;
|
|
662
931
|
if (instructionAccountNode.isSigner === true && instructionAccountNode.isWritable) {
|
|
663
|
-
return fragment(
|
|
932
|
+
return fragment`${use("type WritableSignerAccount", "solanaInstructions")}<${typeParam}> & ${use("type AccountSignerMeta", "solanaSigners")}<${typeParam}>`;
|
|
664
933
|
}
|
|
665
934
|
if (instructionAccountNode.isSigner === true) {
|
|
666
|
-
return fragment(
|
|
935
|
+
return fragment`${use("type ReadonlySignerAccount", "solanaInstructions")}<${typeParam}> & ${use("type AccountSignerMeta", "solanaSigners")}<${typeParam}>`;
|
|
667
936
|
}
|
|
668
937
|
if (instructionAccountNode.isWritable) {
|
|
669
|
-
return fragment
|
|
938
|
+
return fragment`${use("type WritableAccount", "solanaInstructions")}<${typeParam}>`;
|
|
670
939
|
}
|
|
671
|
-
return fragment
|
|
940
|
+
return fragment`${use("type ReadonlyAccount", "solanaInstructions")}<${typeParam}>`;
|
|
672
941
|
}
|
|
673
942
|
|
|
674
943
|
// src/fragments/instructionAccountTypeParam.ts
|
|
@@ -676,24 +945,20 @@ import { pascalCase as pascalCase3 } from "@codama/nodes";
|
|
|
676
945
|
import {
|
|
677
946
|
findInstructionNodeFromPath,
|
|
678
947
|
findProgramNodeFromPath as findProgramNodeFromPath2,
|
|
679
|
-
getLastNodeFromPath as
|
|
948
|
+
getLastNodeFromPath as getLastNodeFromPath6
|
|
680
949
|
} from "@codama/visitors-core";
|
|
681
950
|
function getInstructionAccountTypeParamFragment(scope) {
|
|
682
951
|
const { instructionAccountPath, allowAccountMeta, linkables } = scope;
|
|
683
|
-
const instructionAccountNode =
|
|
952
|
+
const instructionAccountNode = getLastNodeFromPath6(instructionAccountPath);
|
|
684
953
|
const instructionNode = findInstructionNodeFromPath(instructionAccountPath);
|
|
685
954
|
const programNode = findProgramNodeFromPath2(instructionAccountPath);
|
|
686
955
|
const typeParam = `TAccount${pascalCase3(instructionAccountNode.name)}`;
|
|
687
|
-
const accountMeta = allowAccountMeta ?
|
|
688
|
-
const imports = new ImportMap();
|
|
689
|
-
if (allowAccountMeta) {
|
|
690
|
-
imports.add("solanaInstructions", "type AccountMeta");
|
|
691
|
-
}
|
|
956
|
+
const accountMeta = allowAccountMeta ? fragment` | ${use("type AccountMeta", "solanaInstructions")}<string>` : void 0;
|
|
692
957
|
if (instructionNode.optionalAccountStrategy === "omitted" && instructionAccountNode.isOptional) {
|
|
693
|
-
return fragment
|
|
958
|
+
return fragment`${typeParam} extends string${accountMeta} | undefined = undefined`;
|
|
694
959
|
}
|
|
695
960
|
const defaultAddress = getDefaultAddress(instructionAccountNode.defaultValue, programNode.publicKey, linkables);
|
|
696
|
-
return fragment
|
|
961
|
+
return fragment`${typeParam} extends string${accountMeta} = ${defaultAddress}`;
|
|
697
962
|
}
|
|
698
963
|
function getDefaultAddress(defaultValue, programId, linkables) {
|
|
699
964
|
switch (defaultValue?.kind) {
|
|
@@ -710,75 +975,83 @@ function getDefaultAddress(defaultValue, programId, linkables) {
|
|
|
710
975
|
}
|
|
711
976
|
|
|
712
977
|
// src/fragments/instructionByteDelta.ts
|
|
713
|
-
import { assertIsNode, camelCase as
|
|
714
|
-
import {
|
|
978
|
+
import { assertIsNode, camelCase as camelCase4, isNode as isNode7 } from "@codama/nodes";
|
|
979
|
+
import { mapFragmentContent as mapFragmentContent2 } from "@codama/renderers-core";
|
|
980
|
+
import { getLastNodeFromPath as getLastNodeFromPath7, pipe as pipe4 } from "@codama/visitors-core";
|
|
715
981
|
function getInstructionByteDeltaFragment(scope) {
|
|
716
|
-
const { byteDeltas } =
|
|
717
|
-
const fragments = (byteDeltas ?? []).flatMap((
|
|
718
|
-
if (fragments.length === 0) return
|
|
982
|
+
const { byteDeltas } = getLastNodeFromPath7(scope.instructionPath);
|
|
983
|
+
const fragments = (byteDeltas ?? []).flatMap((c) => getByteDeltaFragment(c, scope));
|
|
984
|
+
if (fragments.length === 0) return;
|
|
719
985
|
return mergeFragments(
|
|
720
986
|
fragments,
|
|
721
|
-
(
|
|
722
|
-
const byteDelta: number = [${
|
|
987
|
+
(c) => `// Bytes created or reallocated by the instruction.
|
|
988
|
+
const byteDelta: number = [${c.join(",")}].reduce((a, b) => a + b, 0);`
|
|
723
989
|
);
|
|
724
990
|
}
|
|
725
991
|
function getByteDeltaFragment(byteDelta, scope) {
|
|
726
|
-
|
|
727
|
-
if (
|
|
992
|
+
let bytesFragment = (() => {
|
|
993
|
+
if (isNode7(byteDelta.value, "numberValueNode")) {
|
|
728
994
|
return getNumberValueNodeFragment(byteDelta);
|
|
729
995
|
}
|
|
730
|
-
if (
|
|
996
|
+
if (isNode7(byteDelta.value, "argumentValueNode")) {
|
|
731
997
|
return getArgumentValueNodeFragment(byteDelta);
|
|
732
998
|
}
|
|
733
|
-
if (
|
|
999
|
+
if (isNode7(byteDelta.value, "accountLinkNode")) {
|
|
734
1000
|
return getAccountLinkNodeFragment(byteDelta, scope);
|
|
735
1001
|
}
|
|
736
|
-
if (
|
|
1002
|
+
if (isNode7(byteDelta.value, "resolverValueNode")) {
|
|
737
1003
|
return getResolverValueNodeFragment(byteDelta, scope);
|
|
738
1004
|
}
|
|
739
1005
|
return null;
|
|
740
1006
|
})();
|
|
741
1007
|
if (bytesFragment === null) return [];
|
|
742
1008
|
if (byteDelta.withHeader) {
|
|
743
|
-
bytesFragment
|
|
1009
|
+
bytesFragment = fragment`${bytesFragment} + ${use("BASE_ACCOUNT_SIZE", "solanaAccounts")}`;
|
|
744
1010
|
}
|
|
745
1011
|
if (byteDelta.subtract) {
|
|
746
|
-
bytesFragment
|
|
1012
|
+
bytesFragment = pipe4(bytesFragment, (f) => mapFragmentContent2(f, (c) => `- (${c})`));
|
|
747
1013
|
}
|
|
748
1014
|
return [bytesFragment];
|
|
749
1015
|
}
|
|
750
1016
|
function getNumberValueNodeFragment(byteDelta) {
|
|
751
1017
|
assertIsNode(byteDelta.value, "numberValueNode");
|
|
752
|
-
return fragment
|
|
1018
|
+
return fragment`${byteDelta.value.number}`;
|
|
753
1019
|
}
|
|
754
1020
|
function getArgumentValueNodeFragment(byteDelta) {
|
|
755
1021
|
assertIsNode(byteDelta.value, "argumentValueNode");
|
|
756
|
-
const argumentName =
|
|
757
|
-
return fragment
|
|
1022
|
+
const argumentName = camelCase4(byteDelta.value.name);
|
|
1023
|
+
return fragment`Number(args.${argumentName})`;
|
|
758
1024
|
}
|
|
759
1025
|
function getAccountLinkNodeFragment(byteDelta, scope) {
|
|
760
1026
|
assertIsNode(byteDelta.value, "accountLinkNode");
|
|
761
|
-
const functionName =
|
|
762
|
-
|
|
1027
|
+
const functionName = use(
|
|
1028
|
+
scope.nameApi.accountGetSizeFunction(byteDelta.value.name),
|
|
1029
|
+
scope.getImportFrom(byteDelta.value)
|
|
1030
|
+
);
|
|
1031
|
+
return fragment`${functionName}()`;
|
|
763
1032
|
}
|
|
764
1033
|
function getResolverValueNodeFragment(byteDelta, scope) {
|
|
765
1034
|
assertIsNode(byteDelta.value, "resolverValueNode");
|
|
766
1035
|
const isAsync = scope.asyncResolvers.includes(byteDelta.value.name);
|
|
767
1036
|
if (!scope.useAsync && isAsync) return null;
|
|
768
1037
|
const awaitKeyword = scope.useAsync && isAsync ? "await " : "";
|
|
769
|
-
const functionName =
|
|
770
|
-
|
|
1038
|
+
const functionName = use(
|
|
1039
|
+
scope.nameApi.resolverFunction(byteDelta.value.name),
|
|
1040
|
+
scope.getImportFrom(byteDelta.value)
|
|
1041
|
+
);
|
|
1042
|
+
return pipe4(
|
|
1043
|
+
fragment`${awaitKeyword}${functionName}(resolverScope)`,
|
|
1044
|
+
(f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
|
|
1045
|
+
);
|
|
771
1046
|
}
|
|
772
1047
|
|
|
773
1048
|
// src/fragments/instructionData.ts
|
|
774
1049
|
import { structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes2 } from "@codama/nodes";
|
|
775
|
-
import { getLastNodeFromPath as
|
|
1050
|
+
import { getLastNodeFromPath as getLastNodeFromPath8 } from "@codama/visitors-core";
|
|
776
1051
|
function getInstructionDataFragment(scope) {
|
|
777
1052
|
const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope;
|
|
778
|
-
const instructionNode =
|
|
779
|
-
if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name))
|
|
780
|
-
return fragment("");
|
|
781
|
-
}
|
|
1053
|
+
const instructionNode = getLastNodeFromPath8(instructionPath);
|
|
1054
|
+
if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) return;
|
|
782
1055
|
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
|
|
783
1056
|
return getTypeWithCodecFragment({
|
|
784
1057
|
manifest: dataArgsManifest,
|
|
@@ -789,232 +1062,201 @@ function getInstructionDataFragment(scope) {
|
|
|
789
1062
|
});
|
|
790
1063
|
}
|
|
791
1064
|
|
|
792
|
-
// src/fragments/
|
|
793
|
-
import {
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
return mergeFragments(fragments, (r) => r.join("\n\n"));
|
|
1065
|
+
// src/fragments/instructionExtraArgs.ts
|
|
1066
|
+
import { mapFragmentContent as mapFragmentContent3 } from "@codama/renderers-core";
|
|
1067
|
+
import { getLastNodeFromPath as getLastNodeFromPath9 } from "@codama/visitors-core";
|
|
1068
|
+
function getInstructionExtraArgsFragment(scope) {
|
|
1069
|
+
const { instructionPath, extraArgsManifest, nameApi } = scope;
|
|
1070
|
+
const instructionNode = getLastNodeFromPath9(instructionPath);
|
|
1071
|
+
if ((instructionNode.extraArguments ?? []).length === 0) return;
|
|
1072
|
+
const instructionExtraName = nameApi.instructionExtraType(instructionNode.name);
|
|
1073
|
+
const looseName = nameApi.dataArgsType(instructionExtraName);
|
|
1074
|
+
return mapFragmentContent3(extraArgsManifest.looseType, (c) => `export type ${looseName} = ${c};`);
|
|
803
1075
|
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
}
|
|
823
|
-
function
|
|
824
|
-
const {
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
return null;
|
|
828
|
-
}
|
|
829
|
-
const name = camelCase4(`${prefix}_${discriminatorNode.name}`);
|
|
830
|
-
const encoder = visit2(field.type, typeManifestVisitor).encoder;
|
|
831
|
-
const value = visit2(field.defaultValue, typeManifestVisitor).value;
|
|
832
|
-
return getConstantFragment({ ...scope, encoder, name, value });
|
|
833
|
-
}
|
|
834
|
-
function getConstantFragment(scope) {
|
|
835
|
-
const { encoder, name, nameApi, value } = scope;
|
|
836
|
-
const constantName = nameApi.constant(name);
|
|
837
|
-
const constantFunction = nameApi.constantFunction(name);
|
|
838
|
-
return mergeFragments(
|
|
839
|
-
[
|
|
840
|
-
value.mapRender((r) => `export const ${constantName} = ${r};`),
|
|
841
|
-
encoder.mapRender((r) => `export function ${constantFunction}() { return ${r}.encode(${constantName}); }`)
|
|
842
|
-
],
|
|
843
|
-
(r) => r.join("\n\n")
|
|
844
|
-
);
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
// src/fragments/instructionExtraArgs.ts
|
|
848
|
-
import { getLastNodeFromPath as getLastNodeFromPath8 } from "@codama/visitors-core";
|
|
849
|
-
function getInstructionExtraArgsFragment(scope) {
|
|
850
|
-
const { instructionPath, extraArgsManifest, nameApi } = scope;
|
|
851
|
-
const instructionNode = getLastNodeFromPath8(instructionPath);
|
|
852
|
-
if ((instructionNode.extraArguments ?? []).length === 0) {
|
|
853
|
-
return fragment("");
|
|
854
|
-
}
|
|
855
|
-
const instructionExtraName = nameApi.instructionExtraType(instructionNode.name);
|
|
856
|
-
return fragmentFromTemplate("instructionExtraArgs.njk", {
|
|
857
|
-
looseName: nameApi.dataArgsType(instructionExtraName),
|
|
858
|
-
manifest: extraArgsManifest,
|
|
859
|
-
strictName: nameApi.dataType(instructionExtraName)
|
|
860
|
-
}).mergeImportsWith(extraArgsManifest.looseType);
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
// src/fragments/instructionFunction.ts
|
|
864
|
-
import { camelCase as camelCase9, isNode as isNode12, isNodeFilter as isNodeFilter4, pascalCase as pascalCase5 } from "@codama/nodes";
|
|
865
|
-
import {
|
|
866
|
-
findProgramNodeFromPath as findProgramNodeFromPath3,
|
|
867
|
-
getLastNodeFromPath as getLastNodeFromPath12
|
|
868
|
-
} from "@codama/visitors-core";
|
|
869
|
-
|
|
870
|
-
// src/fragments/instructionInputResolved.ts
|
|
871
|
-
import { camelCase as camelCase6, isNode as isNode9, parseOptionalAccountStrategy } from "@codama/nodes";
|
|
872
|
-
import { getLastNodeFromPath as getLastNodeFromPath9 } from "@codama/visitors-core";
|
|
873
|
-
|
|
874
|
-
// src/fragments/instructionInputDefault.ts
|
|
875
|
-
import { camelCase as camelCase5, isNode as isNode8 } from "@codama/nodes";
|
|
876
|
-
import { visit as visit3 } from "@codama/visitors-core";
|
|
877
|
-
function getInstructionInputDefaultFragment(scope) {
|
|
878
|
-
const { input, optionalAccountStrategy, asyncResolvers, useAsync, nameApi, typeManifestVisitor, getImportFrom } = scope;
|
|
879
|
-
if (!input.defaultValue) {
|
|
880
|
-
return fragment("");
|
|
1076
|
+
|
|
1077
|
+
// src/fragments/instructionFunction.ts
|
|
1078
|
+
import { camelCase as camelCase9, isNode as isNode12, isNodeFilter as isNodeFilter4, pascalCase as pascalCase5 } from "@codama/nodes";
|
|
1079
|
+
import { mapFragmentContent as mapFragmentContent7 } from "@codama/renderers-core";
|
|
1080
|
+
import {
|
|
1081
|
+
findProgramNodeFromPath as findProgramNodeFromPath3,
|
|
1082
|
+
getLastNodeFromPath as getLastNodeFromPath13,
|
|
1083
|
+
pipe as pipe8
|
|
1084
|
+
} from "@codama/visitors-core";
|
|
1085
|
+
|
|
1086
|
+
// src/fragments/instructionInputResolved.ts
|
|
1087
|
+
import { camelCase as camelCase6, isNode as isNode9, parseOptionalAccountStrategy } from "@codama/nodes";
|
|
1088
|
+
import { mapFragmentContent as mapFragmentContent5 } from "@codama/renderers-core";
|
|
1089
|
+
import { getLastNodeFromPath as getLastNodeFromPath10 } from "@codama/visitors-core";
|
|
1090
|
+
|
|
1091
|
+
// src/fragments/instructionInputDefault.ts
|
|
1092
|
+
import { camelCase as camelCase5, isNode as isNode8 } from "@codama/nodes";
|
|
1093
|
+
import { mapFragmentContent as mapFragmentContent4, setFragmentContent } from "@codama/renderers-core";
|
|
1094
|
+
import { pipe as pipe5, visit as visit4 } from "@codama/visitors-core";
|
|
1095
|
+
function getInstructionInputDefaultFragment(scope) {
|
|
1096
|
+
const { input, optionalAccountStrategy, asyncResolvers, useAsync, nameApi, typeManifestVisitor, getImportFrom } = scope;
|
|
1097
|
+
if (!input.defaultValue) {
|
|
1098
|
+
return fragment``;
|
|
881
1099
|
}
|
|
882
1100
|
if (!useAsync && isAsyncDefaultValue(input.defaultValue, asyncResolvers)) {
|
|
883
|
-
return fragment
|
|
1101
|
+
return fragment``;
|
|
884
1102
|
}
|
|
885
1103
|
const { defaultValue } = input;
|
|
886
1104
|
const defaultFragment = (renderedValue, isWritable) => {
|
|
887
1105
|
const inputName = camelCase5(input.name);
|
|
888
1106
|
if (input.kind === "instructionAccountNode" && isNode8(defaultValue, "resolverValueNode")) {
|
|
889
|
-
return fragment
|
|
1107
|
+
return fragment`accounts.${inputName} = { ...accounts.${inputName}, ...${renderedValue} };`;
|
|
890
1108
|
}
|
|
891
1109
|
if (input.kind === "instructionAccountNode" && isWritable === void 0) {
|
|
892
|
-
return fragment
|
|
1110
|
+
return fragment`accounts.${inputName}.value = ${renderedValue};`;
|
|
893
1111
|
}
|
|
894
1112
|
if (input.kind === "instructionAccountNode") {
|
|
895
|
-
return fragment
|
|
896
|
-
`accounts.${inputName}.value = ${renderedValue};
|
|
897
|
-
accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
|
|
898
|
-
);
|
|
1113
|
+
return fragment`accounts.${inputName}.value = ${renderedValue};\naccounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`;
|
|
899
1114
|
}
|
|
900
|
-
return fragment
|
|
1115
|
+
return fragment`args.${inputName} = ${renderedValue};`;
|
|
901
1116
|
};
|
|
902
1117
|
switch (defaultValue.kind) {
|
|
903
1118
|
case "accountValueNode":
|
|
904
1119
|
const name = camelCase5(defaultValue.name);
|
|
905
1120
|
if (input.kind === "instructionAccountNode" && input.resolvedIsSigner && !input.isSigner) {
|
|
906
|
-
return
|
|
907
|
-
|
|
908
|
-
"expectTransactionSigner"
|
|
1121
|
+
return pipe5(
|
|
1122
|
+
defaultFragment(`expectTransactionSigner(accounts.${name}.value).address`),
|
|
1123
|
+
(f) => addFragmentImports(f, "shared", ["expectTransactionSigner"])
|
|
909
1124
|
);
|
|
910
1125
|
}
|
|
911
1126
|
if (input.kind === "instructionAccountNode") {
|
|
912
|
-
return
|
|
1127
|
+
return pipe5(
|
|
1128
|
+
defaultFragment(`expectSome(accounts.${name}.value)`),
|
|
1129
|
+
(f) => addFragmentImports(f, "shared", ["expectSome"])
|
|
1130
|
+
);
|
|
913
1131
|
}
|
|
914
|
-
return
|
|
1132
|
+
return pipe5(
|
|
1133
|
+
defaultFragment(`expectAddress(accounts.${name}.value)`),
|
|
1134
|
+
(f) => addFragmentImports(f, "shared", ["expectAddress"])
|
|
1135
|
+
);
|
|
915
1136
|
case "pdaValueNode":
|
|
916
1137
|
if (isNode8(defaultValue.pda, "pdaNode")) {
|
|
917
|
-
const pdaProgram = defaultValue.pda.programId ?
|
|
918
|
-
`'${defaultValue.pda.programId}' as Address<'${defaultValue.pda.programId}'
|
|
919
|
-
|
|
1138
|
+
const pdaProgram = defaultValue.pda.programId ? pipe5(
|
|
1139
|
+
fragment`'${defaultValue.pda.programId}' as Address<'${defaultValue.pda.programId}'>`,
|
|
1140
|
+
(f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
|
|
1141
|
+
) : fragment`programAddress`;
|
|
920
1142
|
const pdaSeeds2 = defaultValue.pda.seeds.flatMap((seed) => {
|
|
921
1143
|
if (isNode8(seed, "constantPdaSeedNode") && isNode8(seed.value, "programIdValueNode")) {
|
|
922
1144
|
return [
|
|
923
|
-
|
|
1145
|
+
pipe5(
|
|
1146
|
+
fragment`getAddressEncoder().encode(${pdaProgram})`,
|
|
1147
|
+
(f) => addFragmentImports(f, "solanaAddresses", ["getAddressEncoder"])
|
|
1148
|
+
)
|
|
924
1149
|
];
|
|
925
1150
|
}
|
|
926
1151
|
if (isNode8(seed, "constantPdaSeedNode") && !isNode8(seed.value, "programIdValueNode")) {
|
|
927
|
-
const typeManifest2 =
|
|
928
|
-
const valueManifest2 =
|
|
929
|
-
return [
|
|
930
|
-
fragment(
|
|
931
|
-
`${typeManifest2.encoder.render}.encode(${valueManifest2.value.render})`
|
|
932
|
-
).mergeImportsWith(typeManifest2.encoder, valueManifest2.value)
|
|
933
|
-
];
|
|
1152
|
+
const typeManifest2 = visit4(seed.type, typeManifestVisitor);
|
|
1153
|
+
const valueManifest2 = visit4(seed.value, typeManifestVisitor);
|
|
1154
|
+
return [fragment`${typeManifest2.encoder}.encode(${valueManifest2.value})`];
|
|
934
1155
|
}
|
|
935
1156
|
if (isNode8(seed, "variablePdaSeedNode")) {
|
|
936
|
-
const typeManifest2 =
|
|
1157
|
+
const typeManifest2 = visit4(seed.type, typeManifestVisitor);
|
|
937
1158
|
const valueSeed = defaultValue.seeds.find((s) => s.name === seed.name)?.value;
|
|
938
1159
|
if (!valueSeed) return [];
|
|
939
1160
|
if (isNode8(valueSeed, "accountValueNode")) {
|
|
940
1161
|
return [
|
|
941
|
-
|
|
942
|
-
`${typeManifest2.encoder
|
|
943
|
-
|
|
1162
|
+
pipe5(
|
|
1163
|
+
fragment`${typeManifest2.encoder}.encode(expectAddress(accounts.${camelCase5(valueSeed.name)}.value))`,
|
|
1164
|
+
(f) => addFragmentImports(f, "shared", ["expectAddress"])
|
|
1165
|
+
)
|
|
944
1166
|
];
|
|
945
1167
|
}
|
|
946
1168
|
if (isNode8(valueSeed, "argumentValueNode")) {
|
|
947
1169
|
return [
|
|
948
|
-
|
|
949
|
-
`${typeManifest2.encoder
|
|
950
|
-
|
|
1170
|
+
pipe5(
|
|
1171
|
+
fragment`${typeManifest2.encoder}.encode(expectSome(args.${camelCase5(valueSeed.name)}))`,
|
|
1172
|
+
(f) => addFragmentImports(f, "shared", ["expectSome"])
|
|
1173
|
+
)
|
|
951
1174
|
];
|
|
952
1175
|
}
|
|
953
|
-
const valueManifest2 =
|
|
954
|
-
return [
|
|
955
|
-
fragment(
|
|
956
|
-
`${typeManifest2.encoder.render}.encode(${valueManifest2.value.render})`
|
|
957
|
-
).mergeImportsWith(typeManifest2.encoder, valueManifest2.value)
|
|
958
|
-
];
|
|
1176
|
+
const valueManifest2 = visit4(valueSeed, typeManifestVisitor);
|
|
1177
|
+
return [fragment`${typeManifest2.encoder}.encode(${valueManifest2.value})`];
|
|
959
1178
|
}
|
|
960
1179
|
return [];
|
|
961
1180
|
});
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
1181
|
+
return pipe5(
|
|
1182
|
+
mergeFragments([pdaProgram, ...pdaSeeds2], ([p, ...s]) => {
|
|
1183
|
+
const programAddress2 = p === "programAddress" ? p : `programAddress: ${p}`;
|
|
1184
|
+
return `await getProgramDerivedAddress({ ${programAddress2}, seeds: [${s.join(", ")}] })`;
|
|
1185
|
+
}),
|
|
1186
|
+
(f) => addFragmentImports(f, "solanaAddresses", ["getProgramDerivedAddress"]),
|
|
1187
|
+
(f) => mapFragmentContent4(f, (c) => defaultFragment(c).content)
|
|
1188
|
+
);
|
|
967
1189
|
}
|
|
968
1190
|
const pdaFunction = nameApi.pdaFindFunction(defaultValue.pda.name);
|
|
969
1191
|
const pdaArgs = [];
|
|
970
1192
|
const pdaSeeds = defaultValue.seeds.map((seed) => {
|
|
971
1193
|
if (isNode8(seed.value, "accountValueNode")) {
|
|
972
|
-
return
|
|
973
|
-
`${seed.name}: expectAddress(accounts.${camelCase5(seed.value.name)}.value)
|
|
974
|
-
|
|
1194
|
+
return pipe5(
|
|
1195
|
+
fragment`${seed.name}: expectAddress(accounts.${camelCase5(seed.value.name)}.value)`,
|
|
1196
|
+
(f) => addFragmentImports(f, "shared", ["expectAddress"])
|
|
1197
|
+
);
|
|
975
1198
|
}
|
|
976
1199
|
if (isNode8(seed.value, "argumentValueNode")) {
|
|
977
|
-
return
|
|
978
|
-
|
|
979
|
-
"expectSome"
|
|
1200
|
+
return pipe5(
|
|
1201
|
+
fragment`${seed.name}: expectSome(args.${camelCase5(seed.value.name)})`,
|
|
1202
|
+
(f) => addFragmentImports(f, "shared", ["expectSome"])
|
|
980
1203
|
);
|
|
981
1204
|
}
|
|
982
|
-
return
|
|
1205
|
+
return pipe5(
|
|
1206
|
+
visit4(seed.value, typeManifestVisitor).value,
|
|
1207
|
+
(f) => mapFragmentContent4(f, (c) => `${seed.name}: ${c}`)
|
|
1208
|
+
);
|
|
983
1209
|
});
|
|
984
|
-
const pdaSeedsFragment =
|
|
1210
|
+
const pdaSeedsFragment = pipe5(
|
|
1211
|
+
mergeFragments(pdaSeeds, (renders) => renders.join(", ")),
|
|
1212
|
+
(f) => mapFragmentContent4(f, (c) => `{ ${c} }`)
|
|
1213
|
+
);
|
|
985
1214
|
if (pdaSeeds.length > 0) {
|
|
986
|
-
pdaArgs.push(pdaSeedsFragment.
|
|
1215
|
+
pdaArgs.push(pdaSeedsFragment.content);
|
|
987
1216
|
}
|
|
988
|
-
|
|
1217
|
+
const module = getImportFrom(defaultValue.pda);
|
|
1218
|
+
return pipe5(
|
|
1219
|
+
defaultFragment(`await ${pdaFunction}(${pdaArgs.join(", ")})`),
|
|
1220
|
+
(f) => mergeFragmentImports(f, [pdaSeedsFragment.imports]),
|
|
1221
|
+
(f) => addFragmentImports(f, module, [pdaFunction])
|
|
1222
|
+
);
|
|
989
1223
|
case "publicKeyValueNode":
|
|
990
|
-
return
|
|
991
|
-
|
|
992
|
-
"type Address"
|
|
1224
|
+
return pipe5(
|
|
1225
|
+
defaultFragment(`'${defaultValue.publicKey}' as Address<'${defaultValue.publicKey}'>`),
|
|
1226
|
+
(f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
|
|
993
1227
|
);
|
|
994
1228
|
case "programLinkNode":
|
|
995
1229
|
const programAddress = nameApi.programAddressConstant(defaultValue.name);
|
|
996
|
-
return
|
|
1230
|
+
return pipe5(
|
|
1231
|
+
defaultFragment(programAddress, false),
|
|
1232
|
+
(f) => addFragmentImports(f, getImportFrom(defaultValue), [programAddress])
|
|
1233
|
+
);
|
|
997
1234
|
case "programIdValueNode":
|
|
998
1235
|
if (optionalAccountStrategy === "programId" && input.kind === "instructionAccountNode" && input.isOptional) {
|
|
999
|
-
return fragment
|
|
1236
|
+
return fragment``;
|
|
1000
1237
|
}
|
|
1001
1238
|
return defaultFragment("programAddress", false);
|
|
1002
1239
|
case "identityValueNode":
|
|
1003
1240
|
case "payerValueNode":
|
|
1004
|
-
return fragment
|
|
1241
|
+
return fragment``;
|
|
1005
1242
|
case "accountBumpValueNode":
|
|
1006
|
-
return
|
|
1007
|
-
`expectProgramDerivedAddress(accounts.${camelCase5(defaultValue.name)}.value)[1]`
|
|
1008
|
-
|
|
1243
|
+
return pipe5(
|
|
1244
|
+
defaultFragment(`expectProgramDerivedAddress(accounts.${camelCase5(defaultValue.name)}.value)[1]`),
|
|
1245
|
+
(f) => addFragmentImports(f, "shared", ["expectProgramDerivedAddress"])
|
|
1246
|
+
);
|
|
1009
1247
|
case "argumentValueNode":
|
|
1010
|
-
return
|
|
1011
|
-
|
|
1012
|
-
"expectSome"
|
|
1248
|
+
return pipe5(
|
|
1249
|
+
defaultFragment(`expectSome(args.${camelCase5(defaultValue.name)})`),
|
|
1250
|
+
(f) => addFragmentImports(f, "shared", ["expectSome"])
|
|
1013
1251
|
);
|
|
1014
1252
|
case "resolverValueNode":
|
|
1015
1253
|
const resolverFunction = nameApi.resolverFunction(defaultValue.name);
|
|
1016
1254
|
const resolverAwait = useAsync && asyncResolvers.includes(defaultValue.name) ? "await " : "";
|
|
1017
|
-
return
|
|
1255
|
+
return pipe5(
|
|
1256
|
+
defaultFragment(`${resolverAwait}${resolverFunction}(resolverScope)`),
|
|
1257
|
+
(f) => addFragmentImports(f, getImportFrom(defaultValue), [resolverFunction]),
|
|
1258
|
+
(f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
|
|
1259
|
+
);
|
|
1018
1260
|
case "conditionalValueNode":
|
|
1019
1261
|
const ifTrueRenderer = renderNestedInstructionDefault({
|
|
1020
1262
|
...scope,
|
|
@@ -1025,51 +1267,58 @@ accounts.${inputName}.isWritable = ${isWritable ? "true" : "false"}`
|
|
|
1025
1267
|
defaultValue: defaultValue.ifFalse
|
|
1026
1268
|
});
|
|
1027
1269
|
if (!ifTrueRenderer && !ifFalseRenderer) {
|
|
1028
|
-
return fragment
|
|
1270
|
+
return fragment``;
|
|
1029
1271
|
}
|
|
1030
|
-
|
|
1272
|
+
let conditionalFragment = fragment``;
|
|
1031
1273
|
if (ifTrueRenderer) {
|
|
1032
|
-
conditionalFragment
|
|
1274
|
+
conditionalFragment = mergeFragments([conditionalFragment, ifTrueRenderer], (c) => c[0]);
|
|
1033
1275
|
}
|
|
1034
1276
|
if (ifFalseRenderer) {
|
|
1035
|
-
conditionalFragment
|
|
1277
|
+
conditionalFragment = mergeFragments([conditionalFragment, ifFalseRenderer], (c) => c[0]);
|
|
1036
1278
|
}
|
|
1037
1279
|
const negatedCondition = !ifTrueRenderer;
|
|
1038
1280
|
let condition = "true";
|
|
1039
1281
|
if (isNode8(defaultValue.condition, "resolverValueNode")) {
|
|
1040
1282
|
const conditionalResolverFunction = nameApi.resolverFunction(defaultValue.condition.name);
|
|
1041
|
-
|
|
1283
|
+
const module2 = getImportFrom(defaultValue.condition);
|
|
1284
|
+
conditionalFragment = pipe5(
|
|
1285
|
+
conditionalFragment,
|
|
1286
|
+
(f) => addFragmentImports(f, module2, [conditionalResolverFunction]),
|
|
1287
|
+
(f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
|
|
1288
|
+
);
|
|
1042
1289
|
const conditionalResolverAwait = useAsync && asyncResolvers.includes(defaultValue.condition.name) ? "await " : "";
|
|
1043
1290
|
condition = `${conditionalResolverAwait}${conditionalResolverFunction}(resolverScope)`;
|
|
1044
1291
|
condition = negatedCondition ? `!${condition}` : condition;
|
|
1045
1292
|
} else {
|
|
1046
1293
|
const comparedInputName = isNode8(defaultValue.condition, "accountValueNode") ? `accounts.${camelCase5(defaultValue.condition.name)}.value` : `args.${camelCase5(defaultValue.condition.name)}`;
|
|
1047
1294
|
if (defaultValue.value) {
|
|
1048
|
-
const comparedValue =
|
|
1049
|
-
conditionalFragment
|
|
1295
|
+
const comparedValue = visit4(defaultValue.value, typeManifestVisitor).value;
|
|
1296
|
+
conditionalFragment = mergeFragments([conditionalFragment, comparedValue], (c) => c[0]);
|
|
1050
1297
|
const operator = negatedCondition ? "!==" : "===";
|
|
1051
|
-
condition = `${comparedInputName} ${operator} ${comparedValue.
|
|
1298
|
+
condition = `${comparedInputName} ${operator} ${comparedValue.content}`;
|
|
1052
1299
|
} else {
|
|
1053
1300
|
condition = negatedCondition ? `!${comparedInputName}` : comparedInputName;
|
|
1054
1301
|
}
|
|
1055
1302
|
}
|
|
1056
1303
|
if (ifTrueRenderer && ifFalseRenderer) {
|
|
1057
|
-
return
|
|
1304
|
+
return setFragmentContent(
|
|
1305
|
+
conditionalFragment,
|
|
1058
1306
|
`if (${condition}) {
|
|
1059
|
-
${ifTrueRenderer.
|
|
1307
|
+
${ifTrueRenderer.content}
|
|
1060
1308
|
} else {
|
|
1061
|
-
${ifFalseRenderer.
|
|
1309
|
+
${ifFalseRenderer.content}
|
|
1062
1310
|
}`
|
|
1063
1311
|
);
|
|
1064
1312
|
}
|
|
1065
|
-
return
|
|
1313
|
+
return setFragmentContent(
|
|
1314
|
+
conditionalFragment,
|
|
1066
1315
|
`if (${condition}) {
|
|
1067
|
-
${ifTrueRenderer ? ifTrueRenderer.
|
|
1316
|
+
${ifTrueRenderer ? ifTrueRenderer.content : ifFalseRenderer?.content}
|
|
1068
1317
|
}`
|
|
1069
1318
|
);
|
|
1070
1319
|
default:
|
|
1071
|
-
const valueManifest =
|
|
1072
|
-
return
|
|
1320
|
+
const valueManifest = visit4(defaultValue, typeManifestVisitor).value;
|
|
1321
|
+
return pipe5(valueManifest, (f) => mapFragmentContent4(f, (c) => defaultFragment(c).content));
|
|
1073
1322
|
}
|
|
1074
1323
|
}
|
|
1075
1324
|
function renderNestedInstructionDefault(scope) {
|
|
@@ -1083,32 +1332,30 @@ function renderNestedInstructionDefault(scope) {
|
|
|
1083
1332
|
|
|
1084
1333
|
// src/fragments/instructionInputResolved.ts
|
|
1085
1334
|
function getInstructionInputResolvedFragment(scope) {
|
|
1086
|
-
const instructionNode =
|
|
1335
|
+
const instructionNode = getLastNodeFromPath10(scope.instructionPath);
|
|
1087
1336
|
const resolvedInputFragments = scope.resolvedInputs.flatMap((input) => {
|
|
1088
1337
|
const inputFragment = getInstructionInputDefaultFragment({
|
|
1089
1338
|
...scope,
|
|
1090
1339
|
input,
|
|
1091
1340
|
optionalAccountStrategy: parseOptionalAccountStrategy(instructionNode.optionalAccountStrategy)
|
|
1092
1341
|
});
|
|
1093
|
-
if (!inputFragment.
|
|
1342
|
+
if (!inputFragment.content) return [];
|
|
1094
1343
|
const camelName = camelCase6(input.name);
|
|
1095
1344
|
return [
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1345
|
+
mapFragmentContent5(
|
|
1346
|
+
inputFragment,
|
|
1347
|
+
(c) => isNode9(input, "instructionArgumentNode") ? `if (!args.${camelName}) {
|
|
1348
|
+
${c}
|
|
1099
1349
|
}` : `if (!accounts.${camelName}.value) {
|
|
1100
|
-
${
|
|
1350
|
+
${c}
|
|
1101
1351
|
}`
|
|
1102
1352
|
)
|
|
1103
1353
|
];
|
|
1104
1354
|
});
|
|
1105
1355
|
if (resolvedInputFragments.length === 0) {
|
|
1106
|
-
return fragment
|
|
1356
|
+
return fragment``;
|
|
1107
1357
|
}
|
|
1108
|
-
return mergeFragments(
|
|
1109
|
-
[fragment("// Resolve default values."), ...resolvedInputFragments],
|
|
1110
|
-
(renders) => renders.join("\n")
|
|
1111
|
-
);
|
|
1358
|
+
return mergeFragments([fragment`// Resolve default values.`, ...resolvedInputFragments], (c) => c.join("\n"));
|
|
1112
1359
|
}
|
|
1113
1360
|
|
|
1114
1361
|
// src/fragments/instructionInputType.ts
|
|
@@ -1116,99 +1363,94 @@ import {
|
|
|
1116
1363
|
camelCase as camelCase7,
|
|
1117
1364
|
getAllInstructionArguments,
|
|
1118
1365
|
isNode as isNode10,
|
|
1119
|
-
parseDocs,
|
|
1120
1366
|
pascalCase as pascalCase4
|
|
1121
1367
|
} from "@codama/nodes";
|
|
1368
|
+
import { mapFragmentContent as mapFragmentContent6 } from "@codama/renderers-core";
|
|
1122
1369
|
import {
|
|
1123
|
-
getLastNodeFromPath as
|
|
1370
|
+
getLastNodeFromPath as getLastNodeFromPath11,
|
|
1371
|
+
pipe as pipe6
|
|
1124
1372
|
} from "@codama/visitors-core";
|
|
1125
1373
|
function getInstructionInputTypeFragment(scope) {
|
|
1126
1374
|
const { instructionPath, useAsync, nameApi } = scope;
|
|
1127
|
-
const instructionNode =
|
|
1375
|
+
const instructionNode = getLastNodeFromPath11(instructionPath);
|
|
1128
1376
|
const instructionInputType = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) : nameApi.instructionSyncInputType(instructionNode.name);
|
|
1129
|
-
const accountsFragment = getAccountsFragment(scope);
|
|
1130
1377
|
const [dataArgumentsFragment, customDataArgumentsFragment] = getDataArgumentsFragments(scope);
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1378
|
+
let accountTypeParams = "";
|
|
1379
|
+
if (instructionNode.accounts.length > 0) {
|
|
1380
|
+
accountTypeParams = instructionNode.accounts.map((account) => `TAccount${pascalCase4(account.name)} extends string = string`).join(", ");
|
|
1381
|
+
accountTypeParams = `<${accountTypeParams}>`;
|
|
1382
|
+
}
|
|
1383
|
+
const typeBodyFragment = mergeFragments(
|
|
1384
|
+
[
|
|
1385
|
+
getAccountsFragment(scope),
|
|
1386
|
+
dataArgumentsFragment,
|
|
1387
|
+
getExtraArgumentsFragment(scope),
|
|
1388
|
+
getRemainingAccountsFragment(instructionNode)
|
|
1389
|
+
],
|
|
1390
|
+
(c) => c.join("\n")
|
|
1391
|
+
);
|
|
1392
|
+
return fragment`export type ${instructionInputType}${accountTypeParams} = ${customDataArgumentsFragment} {
|
|
1393
|
+
${typeBodyFragment}
|
|
1394
|
+
}`;
|
|
1148
1395
|
}
|
|
1149
1396
|
function getAccountsFragment(scope) {
|
|
1150
1397
|
const { instructionPath, resolvedInputs, useAsync, asyncResolvers } = scope;
|
|
1151
|
-
const instructionNode =
|
|
1398
|
+
const instructionNode = getLastNodeFromPath11(instructionPath);
|
|
1152
1399
|
const fragments = instructionNode.accounts.map((account) => {
|
|
1153
1400
|
const resolvedAccount = resolvedInputs.find(
|
|
1154
1401
|
(input) => input.kind === "instructionAccountNode" && input.name === account.name
|
|
1155
1402
|
);
|
|
1156
1403
|
const hasDefaultValue = !!resolvedAccount.defaultValue && !isNode10(resolvedAccount.defaultValue, ["identityValueNode", "payerValueNode"]) && (useAsync || !isAsyncDefaultValue(resolvedAccount.defaultValue, asyncResolvers));
|
|
1157
|
-
const
|
|
1158
|
-
const docblock = accountDocs.length > 0 ? jsDocblock(accountDocs) : "";
|
|
1404
|
+
const docs = getDocblockFragment(account.docs ?? [], true);
|
|
1159
1405
|
const optionalSign = hasDefaultValue || resolvedAccount.isOptional ? "?" : "";
|
|
1160
|
-
return getAccountTypeFragment2(resolvedAccount)
|
|
1161
|
-
(r) => `${docblock}${camelCase7(account.name)}${optionalSign}: ${r};`
|
|
1162
|
-
);
|
|
1406
|
+
return fragment`${docs}${camelCase7(account.name)}${optionalSign}: ${getAccountTypeFragment2(resolvedAccount)};`;
|
|
1163
1407
|
});
|
|
1164
|
-
return mergeFragments(fragments, (
|
|
1408
|
+
return mergeFragments(fragments, (c) => c.join("\n"));
|
|
1165
1409
|
}
|
|
1166
1410
|
function getAccountTypeFragment2(account) {
|
|
1167
1411
|
const typeParam = `TAccount${pascalCase4(account.name)}`;
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
}
|
|
1173
|
-
if (account.
|
|
1174
|
-
|
|
1175
|
-
}
|
|
1176
|
-
if (account.isSigner === "either") {
|
|
1177
|
-
return fragment(`Address<${typeParam}> | TransactionSigner<${typeParam}>`).addImports("solanaAddresses", ["type Address"]).addImports("solanaSigners", ["type TransactionSigner"]);
|
|
1178
|
-
}
|
|
1179
|
-
if (account.isSigner) {
|
|
1180
|
-
return fragment(`TransactionSigner<${typeParam}>`).addImports("solanaSigners", ["type TransactionSigner"]);
|
|
1181
|
-
}
|
|
1182
|
-
return fragment(`Address<${typeParam}>`).addImports("solanaAddresses", ["type Address"]);
|
|
1412
|
+
const address = use("type Address", "solanaAddresses");
|
|
1413
|
+
const signer = use("type TransactionSigner", "solanaSigners");
|
|
1414
|
+
const pda = use("type ProgramDerivedAddress", "solanaAddresses");
|
|
1415
|
+
if (account.isPda && account.isSigner === false) return fragment`${pda}<${typeParam}>`;
|
|
1416
|
+
if (account.isPda && account.isSigner === "either") return fragment`${pda}<${typeParam}> | ${signer}<${typeParam}>`;
|
|
1417
|
+
if (account.isSigner === "either") return fragment`${address}<${typeParam}> | ${signer}<${typeParam}>`;
|
|
1418
|
+
if (account.isSigner) return fragment`${signer}<${typeParam}>`;
|
|
1419
|
+
return fragment`${address}<${typeParam}>`;
|
|
1183
1420
|
}
|
|
1184
1421
|
function getDataArgumentsFragments(scope) {
|
|
1185
1422
|
const { instructionPath, nameApi } = scope;
|
|
1186
|
-
const instructionNode =
|
|
1423
|
+
const instructionNode = getLastNodeFromPath11(instructionPath);
|
|
1187
1424
|
const customData = scope.customInstructionData.get(instructionNode.name);
|
|
1188
1425
|
if (customData) {
|
|
1189
1426
|
return [
|
|
1190
|
-
|
|
1191
|
-
|
|
1427
|
+
void 0,
|
|
1428
|
+
pipe6(
|
|
1429
|
+
fragment`${nameApi.dataArgsType(customData.importAs)}`,
|
|
1430
|
+
(f) => mergeFragmentImports(f, [scope.dataArgsManifest.looseType.imports]),
|
|
1431
|
+
(f) => mapFragmentContent6(f, (c) => `${c} & `)
|
|
1432
|
+
)
|
|
1192
1433
|
];
|
|
1193
1434
|
}
|
|
1194
1435
|
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
|
|
1195
1436
|
const dataArgsType = nameApi.dataArgsType(instructionDataName);
|
|
1196
1437
|
const fragments = instructionNode.arguments.flatMap((arg) => {
|
|
1197
|
-
const argFragment = getArgumentFragment(arg,
|
|
1438
|
+
const argFragment = getArgumentFragment(arg, dataArgsType, scope.resolvedInputs, scope.renamedArgs);
|
|
1198
1439
|
return argFragment ? [argFragment] : [];
|
|
1199
1440
|
});
|
|
1200
|
-
return [mergeFragments(fragments, (
|
|
1441
|
+
return [fragments.length === 0 ? void 0 : mergeFragments(fragments, (c) => c.join("\n")), fragment``];
|
|
1201
1442
|
}
|
|
1202
1443
|
function getExtraArgumentsFragment(scope) {
|
|
1203
1444
|
const { instructionPath, nameApi } = scope;
|
|
1204
|
-
const instructionNode =
|
|
1445
|
+
const instructionNode = getLastNodeFromPath11(instructionPath);
|
|
1205
1446
|
const instructionExtraName = nameApi.instructionExtraType(instructionNode.name);
|
|
1206
1447
|
const extraArgsType = nameApi.dataArgsType(instructionExtraName);
|
|
1207
1448
|
const fragments = (instructionNode.extraArguments ?? []).flatMap((arg) => {
|
|
1208
|
-
const argFragment = getArgumentFragment(arg,
|
|
1449
|
+
const argFragment = getArgumentFragment(arg, extraArgsType, scope.resolvedInputs, scope.renamedArgs);
|
|
1209
1450
|
return argFragment ? [argFragment] : [];
|
|
1210
1451
|
});
|
|
1211
|
-
|
|
1452
|
+
if (fragments.length === 0) return;
|
|
1453
|
+
return mergeFragments(fragments, (c) => c.join("\n"));
|
|
1212
1454
|
}
|
|
1213
1455
|
function getArgumentFragment(arg, argsType, resolvedInputs, renamedArgs) {
|
|
1214
1456
|
const resolvedArg = resolvedInputs.find(
|
|
@@ -1217,7 +1459,7 @@ function getArgumentFragment(arg, argsType, resolvedInputs, renamedArgs) {
|
|
|
1217
1459
|
if (arg.defaultValue && arg.defaultValueStrategy === "omitted") return null;
|
|
1218
1460
|
const renamedName = renamedArgs.get(arg.name) ?? arg.name;
|
|
1219
1461
|
const optionalSign = arg.defaultValue || resolvedArg?.defaultValue ? "?" : "";
|
|
1220
|
-
return
|
|
1462
|
+
return fragment`${camelCase7(renamedName)}${optionalSign}: ${argsType}["${camelCase7(arg.name)}"];`;
|
|
1221
1463
|
}
|
|
1222
1464
|
function getRemainingAccountsFragment(instructionNode) {
|
|
1223
1465
|
const fragments = (instructionNode.remainingAccounts ?? []).flatMap((remainingAccountsNode) => {
|
|
@@ -1228,16 +1470,16 @@ function getRemainingAccountsFragment(instructionNode) {
|
|
|
1228
1470
|
if (argumentExists) return [];
|
|
1229
1471
|
const isSigner = remainingAccountsNode.isSigner ?? false;
|
|
1230
1472
|
const optionalSign = remainingAccountsNode.isOptional ?? false ? "?" : "";
|
|
1231
|
-
const signerFragment =
|
|
1232
|
-
const addressFragment =
|
|
1233
|
-
|
|
1234
|
-
if (isSigner === "either") {
|
|
1235
|
-
return mergeFragments([signerFragment, addressFragment], (r) => r.join(" | "));
|
|
1236
|
-
}
|
|
1473
|
+
const signerFragment = use("type TransactionSigner", "solanaSigners");
|
|
1474
|
+
const addressFragment = use("type Address", "solanaAddresses");
|
|
1475
|
+
const typeFragment = (() => {
|
|
1476
|
+
if (isSigner === "either") return fragment`${signerFragment} | ${addressFragment}`;
|
|
1237
1477
|
return isSigner ? signerFragment : addressFragment;
|
|
1238
|
-
})()
|
|
1478
|
+
})();
|
|
1479
|
+
return fragment`${camelCase7(name)}${optionalSign}: Array<${typeFragment}>;`;
|
|
1239
1480
|
});
|
|
1240
|
-
|
|
1481
|
+
if (fragments.length === 0) return;
|
|
1482
|
+
return mergeFragments(fragments, (c) => c.join("\n"));
|
|
1241
1483
|
}
|
|
1242
1484
|
|
|
1243
1485
|
// src/fragments/instructionRemainingAccounts.ts
|
|
@@ -1247,16 +1489,19 @@ import {
|
|
|
1247
1489
|
getAllInstructionArguments as getAllInstructionArguments2,
|
|
1248
1490
|
isNode as isNode11
|
|
1249
1491
|
} from "@codama/nodes";
|
|
1250
|
-
import { getLastNodeFromPath as
|
|
1492
|
+
import { getLastNodeFromPath as getLastNodeFromPath12, pipe as pipe7 } from "@codama/visitors-core";
|
|
1251
1493
|
function getInstructionRemainingAccountsFragment(scope) {
|
|
1252
|
-
const { remainingAccounts } =
|
|
1253
|
-
const fragments = (remainingAccounts ?? []).flatMap((
|
|
1254
|
-
if (fragments.length === 0) return
|
|
1255
|
-
return
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1494
|
+
const { remainingAccounts } = getLastNodeFromPath12(scope.instructionPath);
|
|
1495
|
+
const fragments = (remainingAccounts ?? []).flatMap((a) => getRemainingAccountsFragment2(a, scope));
|
|
1496
|
+
if (fragments.length === 0) return;
|
|
1497
|
+
return pipe7(
|
|
1498
|
+
mergeFragments(
|
|
1499
|
+
fragments,
|
|
1500
|
+
(c) => `// Remaining accounts.
|
|
1501
|
+
const remainingAccounts: AccountMeta[] = ${c.length === 1 ? c[0] : `[...${c.join(", ...")}]`}`
|
|
1502
|
+
),
|
|
1503
|
+
(f) => addFragmentImports(f, "solanaInstructions", ["type AccountMeta"])
|
|
1504
|
+
);
|
|
1260
1505
|
}
|
|
1261
1506
|
function getRemainingAccountsFragment2(remainingAccounts, scope) {
|
|
1262
1507
|
const remainingAccountsFragment = (() => {
|
|
@@ -1272,65 +1517,50 @@ function getRemainingAccountsFragment2(remainingAccounts, scope) {
|
|
|
1272
1517
|
return [remainingAccountsFragment];
|
|
1273
1518
|
}
|
|
1274
1519
|
function getArgumentValueNodeFragment2(remainingAccounts, scope) {
|
|
1275
|
-
const instructionNode =
|
|
1520
|
+
const instructionNode = getLastNodeFromPath12(scope.instructionPath);
|
|
1276
1521
|
assertIsNode2(remainingAccounts.value, "argumentValueNode");
|
|
1277
1522
|
const argumentName = camelCase8(remainingAccounts.value.name);
|
|
1278
1523
|
const isOptional = remainingAccounts.isOptional ?? false;
|
|
1279
1524
|
const isSigner = remainingAccounts.isSigner ?? false;
|
|
1280
1525
|
const isWritable = remainingAccounts.isWritable ?? false;
|
|
1281
|
-
const
|
|
1282
|
-
const
|
|
1526
|
+
const accountRole = use("AccountRole", "solanaInstructions");
|
|
1527
|
+
const nonSignerRole = isWritable ? fragment`${accountRole}.WRITABLE` : fragment`${accountRole}.READONLY`;
|
|
1528
|
+
const signerRole = isWritable ? fragment`${accountRole}.WRITABLE_SIGNER` : fragment`${accountRole}.READONLY_SIGNER`;
|
|
1283
1529
|
const role = isSigner === true ? signerRole : nonSignerRole;
|
|
1284
1530
|
const argumentArray = isOptional ? `(args.${argumentName} ?? [])` : `args.${argumentName}`;
|
|
1285
1531
|
const allArguments = getAllInstructionArguments2(instructionNode);
|
|
1286
1532
|
const argumentExists = allArguments.some((arg) => arg.name === remainingAccounts.value.name);
|
|
1287
1533
|
if (argumentExists || isSigner === false) {
|
|
1288
|
-
return fragment
|
|
1289
|
-
"solanaInstructions",
|
|
1290
|
-
["AccountRole"]
|
|
1291
|
-
);
|
|
1534
|
+
return fragment`${argumentArray}.map((address) => ({ address, role: ${role} }))`;
|
|
1292
1535
|
}
|
|
1293
1536
|
if (isSigner === "either") {
|
|
1294
|
-
return fragment(
|
|
1295
|
-
`${argumentArray}.map((addressOrSigner) => (isTransactionSigner(addressOrSigner)
|
|
1296
|
-
? { address: addressOrSigner.address, role: ${role}, signer: addressOrSigner }
|
|
1297
|
-
: { address: addressOrSigner, role: ${role} }
|
|
1298
|
-
))`
|
|
1299
|
-
).addImports("solanaInstructions", ["AccountRole"]).addImports("shared", ["isTransactionSigner"]);
|
|
1537
|
+
return fragment`${argumentArray}.map((addressOrSigner) => (${use("isTransactionSigner", "shared")}(addressOrSigner) ? { address: addressOrSigner.address, role: ${role}, signer: addressOrSigner } : { address: addressOrSigner, role: ${role} }))`;
|
|
1300
1538
|
}
|
|
1301
|
-
return fragment(
|
|
1302
|
-
`${argumentArray}.map((signer) => ({ address: signer.address, role: ${signerRole}, signer }))`
|
|
1303
|
-
).addImports("solanaInstructions", ["AccountRole"]);
|
|
1539
|
+
return fragment`${argumentArray}.map((signer) => ({ address: signer.address, role: ${signerRole}, signer }))`;
|
|
1304
1540
|
}
|
|
1305
1541
|
function getResolverValueNodeFragment2(remainingAccounts, scope) {
|
|
1306
1542
|
assertIsNode2(remainingAccounts.value, "resolverValueNode");
|
|
1307
1543
|
const isAsync = scope.asyncResolvers.includes(remainingAccounts.value.name);
|
|
1308
1544
|
if (!scope.useAsync && isAsync) return null;
|
|
1309
1545
|
const awaitKeyword = scope.useAsync && isAsync ? "await " : "";
|
|
1310
|
-
const functionName =
|
|
1311
|
-
|
|
1546
|
+
const functionName = use(
|
|
1547
|
+
scope.nameApi.resolverFunction(remainingAccounts.value.name),
|
|
1548
|
+
scope.getImportFrom(remainingAccounts.value)
|
|
1549
|
+
);
|
|
1550
|
+
return pipe7(
|
|
1551
|
+
fragment`${awaitKeyword}${functionName}(resolverScope)`,
|
|
1552
|
+
(f) => addFragmentFeatures(f, ["instruction:resolverScopeVariable"])
|
|
1553
|
+
);
|
|
1312
1554
|
}
|
|
1313
1555
|
|
|
1314
1556
|
// src/fragments/instructionFunction.ts
|
|
1315
1557
|
function getInstructionFunctionFragment(scope) {
|
|
1316
|
-
const {
|
|
1317
|
-
|
|
1318
|
-
instructionPath,
|
|
1319
|
-
resolvedInputs,
|
|
1320
|
-
renamedArgs,
|
|
1321
|
-
dataArgsManifest,
|
|
1322
|
-
asyncResolvers,
|
|
1323
|
-
nameApi,
|
|
1324
|
-
customInstructionData
|
|
1325
|
-
} = scope;
|
|
1326
|
-
const instructionNode = getLastNodeFromPath12(instructionPath);
|
|
1558
|
+
const { useAsync, instructionPath, resolvedInputs, renamedArgs, asyncResolvers, nameApi, customInstructionData } = scope;
|
|
1559
|
+
const instructionNode = getLastNodeFromPath13(instructionPath);
|
|
1327
1560
|
const programNode = findProgramNodeFromPath3(instructionPath);
|
|
1328
|
-
if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers))
|
|
1329
|
-
return fragment("");
|
|
1330
|
-
}
|
|
1561
|
+
if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers)) return;
|
|
1331
1562
|
const customData = customInstructionData.get(instructionNode.name);
|
|
1332
1563
|
const hasAccounts = instructionNode.accounts.length > 0;
|
|
1333
|
-
const hasLegacyOptionalAccounts = instructionNode.optionalAccountStrategy === "omitted" && instructionNode.accounts.some((account) => account.isOptional);
|
|
1334
1564
|
const instructionDependencies = getInstructionDependencies(instructionNode, asyncResolvers, useAsync);
|
|
1335
1565
|
const argDependencies = instructionDependencies.filter(isNodeFilter4("argumentValueNode")).map((node) => node.name);
|
|
1336
1566
|
const hasData = !!customData || instructionNode.arguments.length > 0;
|
|
@@ -1348,161 +1578,297 @@ function getInstructionFunctionFragment(scope) {
|
|
|
1348
1578
|
const hasRemainingAccountArgs = (instructionNode.remainingAccounts ?? []).filter(({ value }) => isNode12(value, "argumentValueNode")).length > 0;
|
|
1349
1579
|
const hasAnyArgs = hasDataArgs || hasExtraArgs || hasRemainingAccountArgs;
|
|
1350
1580
|
const hasInput = hasAccounts || hasAnyArgs;
|
|
1351
|
-
const
|
|
1352
|
-
const programAddressConstant = nameApi.programAddressConstant(programNode.name);
|
|
1353
|
-
const encoderFunction = customData ? dataArgsManifest.encoder.render : `${nameApi.encoderFunction(instructionDataName)}()`;
|
|
1354
|
-
const argsTypeFragment = fragment(
|
|
1355
|
-
customData ? dataArgsManifest.looseType.render : nameApi.dataArgsType(instructionDataName)
|
|
1356
|
-
);
|
|
1357
|
-
if (customData) {
|
|
1358
|
-
argsTypeFragment.mergeImportsWith(dataArgsManifest.looseType, dataArgsManifest.encoder);
|
|
1359
|
-
}
|
|
1581
|
+
const programAddressConstant = use(nameApi.programAddressConstant(programNode.name), "generatedPrograms");
|
|
1360
1582
|
const functionName = useAsync ? nameApi.instructionAsyncFunction(instructionNode.name) : nameApi.instructionSyncFunction(instructionNode.name);
|
|
1361
|
-
const typeParamsFragment = getTypeParams(instructionNode, programAddressConstant);
|
|
1362
|
-
const instructionTypeFragment = getInstructionType(scope);
|
|
1363
|
-
const inputTypeFragment = getInstructionInputTypeFragment(scope);
|
|
1364
|
-
const inputTypeCallFragment = getInputTypeCall(scope);
|
|
1365
|
-
const renamedArgsText = [...renamedArgs.entries()].map(([k, v]) => `${k}: input.${v}`).join(", ");
|
|
1366
1583
|
const resolvedInputsFragment = getInstructionInputResolvedFragment(scope);
|
|
1367
1584
|
const remainingAccountsFragment = getInstructionRemainingAccountsFragment(scope);
|
|
1368
1585
|
const byteDeltaFragment = getInstructionByteDeltaFragment(scope);
|
|
1369
|
-
const
|
|
1586
|
+
const resolvedInputFragment = mergeFragments(
|
|
1370
1587
|
[resolvedInputsFragment, remainingAccountsFragment, byteDeltaFragment],
|
|
1371
|
-
(
|
|
1588
|
+
(content) => content.join("\n\n")
|
|
1372
1589
|
);
|
|
1373
|
-
const hasRemainingAccounts = remainingAccountsFragment
|
|
1374
|
-
const hasByteDeltas = byteDeltaFragment
|
|
1375
|
-
const hasResolver =
|
|
1376
|
-
const
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1590
|
+
const hasRemainingAccounts = !!remainingAccountsFragment;
|
|
1591
|
+
const hasByteDeltas = !!byteDeltaFragment;
|
|
1592
|
+
const hasResolver = resolvedInputFragment.features.has("instruction:resolverScopeVariable");
|
|
1593
|
+
const instructionTypeFragment = getInstructionTypeFragment(scope);
|
|
1594
|
+
const typeParams = getTypeParamsFragment(instructionNode, programAddressConstant);
|
|
1595
|
+
const returnType = getReturnTypeFragment(instructionTypeFragment, hasByteDeltas, useAsync);
|
|
1596
|
+
const inputType = getInstructionInputTypeFragment(scope);
|
|
1597
|
+
const inputArg = mapFragmentContent7(getInputTypeCallFragment(scope), (c) => hasInput ? `input: ${c}, ` : "");
|
|
1598
|
+
const functionBody = mergeFragments(
|
|
1599
|
+
[
|
|
1600
|
+
getProgramAddressInitializationFragment(programAddressConstant),
|
|
1601
|
+
getAccountsInitializationFragment(instructionNode),
|
|
1602
|
+
getArgumentsInitializationFragment(hasAnyArgs, renamedArgs),
|
|
1603
|
+
getResolverScopeInitializationFragment(hasResolver, hasAccounts, hasAnyArgs),
|
|
1604
|
+
resolvedInputFragment,
|
|
1605
|
+
getReturnStatementFragment({
|
|
1606
|
+
...scope,
|
|
1607
|
+
hasByteDeltas,
|
|
1608
|
+
hasData,
|
|
1609
|
+
hasDataArgs,
|
|
1610
|
+
hasRemainingAccounts,
|
|
1611
|
+
instructionNode,
|
|
1612
|
+
syncReturnTypeFragment: getReturnTypeFragment(instructionTypeFragment, hasByteDeltas, false)
|
|
1613
|
+
})
|
|
1614
|
+
],
|
|
1615
|
+
(cs) => cs.join("\n\n")
|
|
1616
|
+
);
|
|
1617
|
+
return fragment`${inputType}\n\nexport ${useAsync ? "async " : ""}function ${functionName}${typeParams}(${inputArg}config?: { programAddress?: TProgramAddress } ): ${returnType} {
|
|
1618
|
+
${functionBody}
|
|
1619
|
+
}`;
|
|
1620
|
+
}
|
|
1621
|
+
function getProgramAddressInitializationFragment(programAddressConstant) {
|
|
1622
|
+
return fragment`// Program address.
|
|
1623
|
+
const programAddress = config?.programAddress ?? ${programAddressConstant};`;
|
|
1624
|
+
}
|
|
1625
|
+
function getAccountsInitializationFragment(instructionNode) {
|
|
1626
|
+
if (instructionNode.accounts.length === 0) return;
|
|
1627
|
+
const accounts = mergeFragments(
|
|
1628
|
+
instructionNode.accounts.map((account) => {
|
|
1629
|
+
const name = camelCase9(account.name);
|
|
1630
|
+
const isWritable = account.isWritable ? "true" : "false";
|
|
1631
|
+
return fragment`${name}: { value: input.${name} ?? null, isWritable: ${isWritable} }`;
|
|
1632
|
+
}),
|
|
1633
|
+
(cs) => cs.join(", ")
|
|
1634
|
+
);
|
|
1635
|
+
return fragment` // Original accounts.
|
|
1636
|
+
const originalAccounts = { ${accounts} }
|
|
1637
|
+
const accounts = originalAccounts as Record<keyof typeof originalAccounts, ${use("type ResolvedAccount", "shared")}>;
|
|
1638
|
+
`;
|
|
1639
|
+
}
|
|
1640
|
+
function getArgumentsInitializationFragment(hasAnyArgs, renamedArgs) {
|
|
1641
|
+
if (!hasAnyArgs) return;
|
|
1642
|
+
const renamedArgsText = [...renamedArgs.entries()].map(([k, v]) => `${k}: input.${v}`).join(", ");
|
|
1643
|
+
return fragment`// Original args.
|
|
1644
|
+
const args = { ...input, ${renamedArgsText} };
|
|
1645
|
+
`;
|
|
1646
|
+
}
|
|
1647
|
+
function getResolverScopeInitializationFragment(hasResolver, hasAccounts, hasAnyArgs) {
|
|
1648
|
+
if (!hasResolver) return;
|
|
1649
|
+
const resolverAttributes = [
|
|
1650
|
+
"programAddress",
|
|
1651
|
+
...hasAccounts ? ["accounts"] : [],
|
|
1652
|
+
...hasAnyArgs ? ["args"] : []
|
|
1653
|
+
].join(", ");
|
|
1654
|
+
return fragment`// Resolver scope.
|
|
1655
|
+
const resolverScope = { ${resolverAttributes} };`;
|
|
1656
|
+
}
|
|
1657
|
+
function getReturnStatementFragment(scope) {
|
|
1658
|
+
const { instructionNode, hasByteDeltas, hasData, hasDataArgs, hasRemainingAccounts, nameApi } = scope;
|
|
1659
|
+
const optionalAccountStrategy = instructionNode.optionalAccountStrategy ?? "programId";
|
|
1660
|
+
const hasAccounts = instructionNode.accounts.length > 0;
|
|
1661
|
+
const hasLegacyOptionalAccounts = instructionNode.optionalAccountStrategy === "omitted" && instructionNode.accounts.some((account) => account.isOptional);
|
|
1662
|
+
const getAccountMeta = hasAccounts ? fragment`const getAccountMeta = ${use("getAccountMetaFactory", "shared")}(programAddress, '${optionalAccountStrategy}');` : "";
|
|
1663
|
+
const accountItems = [
|
|
1664
|
+
...instructionNode.accounts.map((account) => `getAccountMeta(accounts.${camelCase9(account.name)})`),
|
|
1665
|
+
...hasRemainingAccounts ? ["...remainingAccounts"] : []
|
|
1666
|
+
].join(", ");
|
|
1667
|
+
let accounts;
|
|
1668
|
+
if (hasAccounts && hasLegacyOptionalAccounts) {
|
|
1669
|
+
accounts = fragment`accounts: [${accountItems}].filter(<T>(x: T | undefined): x is T => x !== undefined)`;
|
|
1670
|
+
} else if (hasAccounts) {
|
|
1671
|
+
accounts = fragment`accounts: [${accountItems}]`;
|
|
1672
|
+
} else if (hasRemainingAccounts) {
|
|
1673
|
+
accounts = fragment`accounts: remainingAccounts`;
|
|
1420
1674
|
}
|
|
1421
|
-
|
|
1675
|
+
const customData = scope.customInstructionData.get(instructionNode.name);
|
|
1676
|
+
const instructionDataName = nameApi.instructionDataType(instructionNode.name);
|
|
1677
|
+
const encoderFunctionFragment = customData ? scope.dataArgsManifest.encoder : `${nameApi.encoderFunction(instructionDataName)}()`;
|
|
1678
|
+
const argsTypeFragment = customData ? scope.dataArgsManifest.looseType : nameApi.dataArgsType(instructionDataName);
|
|
1679
|
+
let data;
|
|
1680
|
+
if (hasDataArgs) {
|
|
1681
|
+
data = fragment`data: ${encoderFunctionFragment}.encode(args as ${argsTypeFragment})`;
|
|
1682
|
+
} else if (hasData) {
|
|
1683
|
+
data = fragment`data: ${encoderFunctionFragment}.encode({})`;
|
|
1684
|
+
}
|
|
1685
|
+
const instructionAttributes = pipe8(
|
|
1686
|
+
[accounts, hasByteDeltas ? fragment`byteDelta` : void 0, data, fragment`programAddress`],
|
|
1687
|
+
(fs) => mergeFragments(fs, (cs) => cs.join(", "))
|
|
1688
|
+
);
|
|
1689
|
+
return fragment`${getAccountMeta}\nreturn Object.freeze({ ${instructionAttributes} } as ${scope.syncReturnTypeFragment});`;
|
|
1690
|
+
}
|
|
1691
|
+
function getReturnTypeFragment(instructionTypeFragment, hasByteDeltas, useAsync) {
|
|
1692
|
+
return pipe8(
|
|
1693
|
+
instructionTypeFragment,
|
|
1694
|
+
(f) => hasByteDeltas ? fragment`${f} & ${use("type InstructionWithByteDelta", "shared")}` : f,
|
|
1695
|
+
(f) => useAsync ? fragment`Promise<${f}>` : f
|
|
1696
|
+
);
|
|
1422
1697
|
}
|
|
1423
|
-
function
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1698
|
+
function getTypeParamsFragment(instructionNode, programAddressConstant) {
|
|
1699
|
+
return mergeFragments(
|
|
1700
|
+
[
|
|
1701
|
+
...instructionNode.accounts.map((account) => fragment`TAccount${pascalCase5(account.name)} extends string`),
|
|
1702
|
+
fragment`TProgramAddress extends ${use("type Address", "solanaAddresses")} = typeof ${programAddressConstant}`
|
|
1703
|
+
],
|
|
1704
|
+
(cs) => `<${cs.join(", ")}>`
|
|
1705
|
+
);
|
|
1427
1706
|
}
|
|
1428
|
-
function
|
|
1707
|
+
function getInstructionTypeFragment(scope) {
|
|
1429
1708
|
const { instructionPath, nameApi } = scope;
|
|
1430
|
-
const instructionNode =
|
|
1709
|
+
const instructionNode = getLastNodeFromPath13(instructionPath);
|
|
1431
1710
|
const instructionTypeName = nameApi.instructionType(instructionNode.name);
|
|
1432
|
-
const programAddressFragment = fragment("TProgramAddress");
|
|
1433
1711
|
const accountTypeParamsFragments = instructionNode.accounts.map((account) => {
|
|
1434
|
-
const typeParam = `TAccount${pascalCase5(account.name)}`;
|
|
1712
|
+
const typeParam = fragment`TAccount${pascalCase5(account.name)}`;
|
|
1435
1713
|
const camelName = camelCase9(account.name);
|
|
1436
1714
|
if (account.isSigner === "either") {
|
|
1437
|
-
const signerRole =
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
)
|
|
1715
|
+
const signerRole = use(
|
|
1716
|
+
account.isWritable ? "type WritableSignerAccount" : "type ReadonlySignerAccount",
|
|
1717
|
+
"solanaInstructions"
|
|
1718
|
+
);
|
|
1719
|
+
return pipe8(
|
|
1720
|
+
fragment`typeof input["${camelName}"] extends TransactionSigner<${typeParam}> ? ${signerRole}<${typeParam}> & AccountSignerMeta<${typeParam}> : ${typeParam}`,
|
|
1721
|
+
(f) => addFragmentImports(f, "solanaSigners", ["type AccountSignerMeta", "type TransactionSigner"])
|
|
1722
|
+
);
|
|
1441
1723
|
}
|
|
1442
|
-
return
|
|
1724
|
+
return typeParam;
|
|
1443
1725
|
});
|
|
1444
|
-
return
|
|
1445
|
-
[
|
|
1446
|
-
(
|
|
1447
|
-
)
|
|
1726
|
+
return pipe8(
|
|
1727
|
+
mergeFragments([fragment`TProgramAddress`, ...accountTypeParamsFragments], (c) => c.join(", ")),
|
|
1728
|
+
(f) => mapFragmentContent7(f, (c) => `${instructionTypeName}<${c}>`)
|
|
1729
|
+
);
|
|
1448
1730
|
}
|
|
1449
|
-
function
|
|
1731
|
+
function getInputTypeCallFragment(scope) {
|
|
1450
1732
|
const { instructionPath, useAsync, nameApi } = scope;
|
|
1451
|
-
const instructionNode =
|
|
1733
|
+
const instructionNode = getLastNodeFromPath13(instructionPath);
|
|
1452
1734
|
const inputTypeName = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) : nameApi.instructionSyncInputType(instructionNode.name);
|
|
1453
|
-
if (instructionNode.accounts.length === 0) return fragment
|
|
1735
|
+
if (instructionNode.accounts.length === 0) return fragment`${inputTypeName}`;
|
|
1454
1736
|
const accountTypeParams = instructionNode.accounts.map((account) => `TAccount${pascalCase5(account.name)}`).join(", ");
|
|
1455
|
-
return fragment
|
|
1737
|
+
return fragment`${inputTypeName}<${accountTypeParams}>`;
|
|
1456
1738
|
}
|
|
1457
1739
|
|
|
1740
|
+
// src/fragments/instructionPage.ts
|
|
1741
|
+
import { logWarn } from "@codama/errors";
|
|
1742
|
+
import { camelCase as camelCase11, definedTypeNode as definedTypeNode2, structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes3 } from "@codama/nodes";
|
|
1743
|
+
import {
|
|
1744
|
+
findProgramNodeFromPath as findProgramNodeFromPath6,
|
|
1745
|
+
getLastNodeFromPath as getLastNodeFromPath16,
|
|
1746
|
+
visit as visit5
|
|
1747
|
+
} from "@codama/visitors-core";
|
|
1748
|
+
|
|
1458
1749
|
// src/fragments/instructionParseFunction.ts
|
|
1459
|
-
import {
|
|
1750
|
+
import { camelCase as camelCase10 } from "@codama/nodes";
|
|
1751
|
+
import { findProgramNodeFromPath as findProgramNodeFromPath4, getLastNodeFromPath as getLastNodeFromPath14, pipe as pipe9 } from "@codama/visitors-core";
|
|
1460
1752
|
function getInstructionParseFunctionFragment(scope) {
|
|
1461
|
-
const
|
|
1462
|
-
const
|
|
1463
|
-
const
|
|
1464
|
-
const
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
const
|
|
1469
|
-
const
|
|
1470
|
-
const
|
|
1471
|
-
const
|
|
1472
|
-
|
|
1753
|
+
const instructionNode = getLastNodeFromPath14(scope.instructionPath);
|
|
1754
|
+
const programNode = findProgramNodeFromPath4(scope.instructionPath);
|
|
1755
|
+
const programAddressConstant = use(scope.nameApi.programAddressConstant(programNode.name), "generatedPrograms");
|
|
1756
|
+
const childScope = { ...scope, instructionNode, programAddressConstant };
|
|
1757
|
+
return mergeFragments([getTypeFragment2(childScope), getFunctionFragment(childScope)], (cs) => cs.join("\n\n"));
|
|
1758
|
+
}
|
|
1759
|
+
function getTypeFragment2(scope) {
|
|
1760
|
+
const customData = scope.customInstructionData.get(scope.instructionNode.name);
|
|
1761
|
+
const instructionParsedType = scope.nameApi.instructionParsedType(scope.instructionNode.name);
|
|
1762
|
+
const instructionDataName = scope.nameApi.instructionDataType(scope.instructionNode.name);
|
|
1763
|
+
const hasData = !!customData || scope.instructionNode.arguments.length > 0;
|
|
1764
|
+
const hasAccounts = scope.instructionNode.accounts.length > 0;
|
|
1765
|
+
const typeParamDeclarations = mergeFragments(
|
|
1766
|
+
[
|
|
1767
|
+
fragment`TProgram extends string = typeof ${scope.programAddressConstant}`,
|
|
1768
|
+
hasAccounts ? fragment`TAccountMetas extends readonly ${use("type AccountMeta", "solanaInstructions")}[] = readonly AccountMeta[]` : void 0
|
|
1769
|
+
],
|
|
1770
|
+
(cs) => cs.join(", ")
|
|
1473
1771
|
);
|
|
1474
|
-
const
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1772
|
+
const accounts = mergeFragments(
|
|
1773
|
+
scope.instructionNode.accounts.map((account, i) => {
|
|
1774
|
+
const docs = getDocblockFragment(account.docs ?? [], true);
|
|
1775
|
+
const name = camelCase10(account.name);
|
|
1776
|
+
return fragment`${docs}${name}${account.isOptional ? "?" : ""}: TAccountMetas[${i}]${account.isOptional ? " | undefined" : ""};`;
|
|
1777
|
+
}),
|
|
1778
|
+
(cs) => hasAccounts ? `
|
|
1779
|
+
accounts: {
|
|
1780
|
+
${cs.join("\n")}
|
|
1781
|
+
};` : ""
|
|
1782
|
+
);
|
|
1783
|
+
const dataTypeFragment = customData ? scope.dataArgsManifest.strictType : fragment`${scope.nameApi.dataType(instructionDataName)}`;
|
|
1784
|
+
const data = hasData ? fragment`\ndata: ${dataTypeFragment};` : fragment``;
|
|
1785
|
+
return fragment`export type ${instructionParsedType}<${typeParamDeclarations}> = { programAddress: ${use("type Address", "solanaAddresses")}<TProgram>;${accounts}${data} };`;
|
|
1786
|
+
}
|
|
1787
|
+
function getFunctionFragment(scope) {
|
|
1788
|
+
const customData = scope.customInstructionData.get(scope.instructionNode.name);
|
|
1789
|
+
const instructionParsedType = scope.nameApi.instructionParsedType(scope.instructionNode.name);
|
|
1790
|
+
const instructionParseFunction = scope.nameApi.instructionParseFunction(scope.instructionNode.name);
|
|
1791
|
+
const instructionDataName = scope.nameApi.instructionDataType(scope.instructionNode.name);
|
|
1792
|
+
const decoderFunction = customData ? scope.dataArgsManifest.decoder : fragment`${scope.nameApi.decoderFunction(instructionDataName)}()`;
|
|
1793
|
+
const hasData = !!customData || scope.instructionNode.arguments.length > 0;
|
|
1794
|
+
const hasAccounts = scope.instructionNode.accounts.length > 0;
|
|
1795
|
+
const hasOptionalAccounts = scope.instructionNode.accounts.some((account) => account.isOptional);
|
|
1796
|
+
const minimumNumberOfAccounts = scope.instructionNode.optionalAccountStrategy === "omitted" ? scope.instructionNode.accounts.filter((account) => !account.isOptional).length : scope.instructionNode.accounts.length;
|
|
1797
|
+
const typeParams = ["TProgram", hasAccounts ? "TAccountMetas" : void 0].filter(Boolean).join(", ");
|
|
1798
|
+
const typeParamDeclarations = mergeFragments(
|
|
1799
|
+
[
|
|
1800
|
+
fragment`TProgram extends string`,
|
|
1801
|
+
hasAccounts ? fragment`TAccountMetas extends readonly ${use("type AccountMeta", "solanaInstructions")}[]` : void 0
|
|
1802
|
+
],
|
|
1803
|
+
(cs) => cs.join(", ")
|
|
1804
|
+
);
|
|
1805
|
+
const instructionType = mergeFragments(
|
|
1806
|
+
[
|
|
1807
|
+
fragment`${use("type Instruction", "solanaInstructions")}<TProgram>`,
|
|
1808
|
+
hasAccounts ? fragment`${use("type InstructionWithAccounts", "solanaInstructions")}<TAccountMetas>` : void 0,
|
|
1809
|
+
hasData ? pipe9(
|
|
1810
|
+
fragment`InstructionWithData<ReadonlyUint8Array>`,
|
|
1811
|
+
(f) => addFragmentImports(f, "solanaInstructions", ["type InstructionWithData"]),
|
|
1812
|
+
(f) => addFragmentImports(f, "solanaCodecsCore", ["type ReadonlyUint8Array"])
|
|
1813
|
+
) : void 0
|
|
1814
|
+
],
|
|
1815
|
+
(cs) => cs.join(" & ")
|
|
1816
|
+
);
|
|
1817
|
+
let accountHelpers;
|
|
1818
|
+
if (hasAccounts) {
|
|
1819
|
+
accountHelpers = fragment`if (instruction.accounts.length < ${minimumNumberOfAccounts}) {
|
|
1820
|
+
// TODO: Coded error.
|
|
1821
|
+
throw new Error('Not enough accounts');
|
|
1822
|
+
}
|
|
1823
|
+
let accountIndex = 0;
|
|
1824
|
+
const getNextAccount = () => {
|
|
1825
|
+
const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;
|
|
1826
|
+
accountIndex += 1;
|
|
1827
|
+
return accountMeta;
|
|
1828
|
+
}`;
|
|
1829
|
+
}
|
|
1830
|
+
if (hasOptionalAccounts && scope.instructionNode.optionalAccountStrategy === "omitted") {
|
|
1831
|
+
accountHelpers = fragment`${accountHelpers}
|
|
1832
|
+
let optionalAccountsRemaining = instruction.accounts.length - ${minimumNumberOfAccounts};
|
|
1833
|
+
const getNextOptionalAccount = () => {
|
|
1834
|
+
if (optionalAccountsRemaining === 0) return undefined;
|
|
1835
|
+
optionalAccountsRemaining -= 1;
|
|
1836
|
+
return getNextAccount();
|
|
1837
|
+
};`;
|
|
1838
|
+
} else if (hasOptionalAccounts) {
|
|
1839
|
+
accountHelpers = fragment`${accountHelpers}
|
|
1840
|
+
const getNextOptionalAccount = () => {
|
|
1841
|
+
const accountMeta = getNextAccount();
|
|
1842
|
+
return accountMeta.address === ${scope.programAddressConstant} ? undefined : accountMeta;
|
|
1843
|
+
};`;
|
|
1844
|
+
}
|
|
1845
|
+
const accounts = mergeFragments(
|
|
1846
|
+
scope.instructionNode.accounts.map(
|
|
1847
|
+
(account) => account.isOptional ? fragment`${camelCase10(account.name)}: getNextOptionalAccount()` : fragment`${camelCase10(account.name)}: getNextAccount()`
|
|
1848
|
+
),
|
|
1849
|
+
(cs) => hasAccounts ? `, accounts: { ${cs.join(", ")} }` : ""
|
|
1850
|
+
);
|
|
1851
|
+
const data = hasData ? fragment`, data: ${decoderFunction}.decode(instruction.data)` : fragment``;
|
|
1852
|
+
return fragment`export function ${instructionParseFunction}<${typeParamDeclarations}>(instruction: ${instructionType}): ${instructionParsedType}<${typeParams}> {
|
|
1853
|
+
${accountHelpers}
|
|
1854
|
+
return { programAddress: instruction.programAddress${accounts}${data} };
|
|
1855
|
+
}`;
|
|
1490
1856
|
}
|
|
1491
1857
|
|
|
1492
1858
|
// src/fragments/instructionType.ts
|
|
1493
1859
|
import { pascalCase as pascalCase6 } from "@codama/nodes";
|
|
1494
|
-
import {
|
|
1495
|
-
|
|
1860
|
+
import { mapFragmentContent as mapFragmentContent8 } from "@codama/renderers-core";
|
|
1861
|
+
import { findProgramNodeFromPath as findProgramNodeFromPath5, getLastNodeFromPath as getLastNodeFromPath15 } from "@codama/visitors-core";
|
|
1862
|
+
function getInstructionTypeFragment2(scope) {
|
|
1496
1863
|
const { instructionPath, nameApi, customInstructionData } = scope;
|
|
1497
|
-
const instructionNode =
|
|
1864
|
+
const instructionNode = getLastNodeFromPath15(instructionPath);
|
|
1498
1865
|
const programNode = findProgramNodeFromPath5(instructionPath);
|
|
1499
1866
|
const hasAccounts = instructionNode.accounts.length > 0;
|
|
1500
1867
|
const customData = customInstructionData.get(instructionNode.name);
|
|
1501
1868
|
const hasData = !!customData || instructionNode.arguments.length > 0;
|
|
1502
|
-
const
|
|
1503
|
-
const programAddressConstant = nameApi.programAddressConstant(programNode.name);
|
|
1504
|
-
const
|
|
1505
|
-
const accountTypeParamsFragment = mergeFragments(
|
|
1869
|
+
const instructionType = nameApi.instructionType(instructionNode.name);
|
|
1870
|
+
const programAddressConstant = use(nameApi.programAddressConstant(programNode.name), "generatedPrograms");
|
|
1871
|
+
const accountTypeParams = mergeFragments(
|
|
1506
1872
|
instructionNode.accounts.map(
|
|
1507
1873
|
(account) => getInstructionAccountTypeParamFragment({
|
|
1508
1874
|
...scope,
|
|
@@ -1510,91 +1876,165 @@ function getInstructionTypeFragment(scope) {
|
|
|
1510
1876
|
instructionAccountPath: [...instructionPath, account]
|
|
1511
1877
|
})
|
|
1512
1878
|
),
|
|
1513
|
-
(
|
|
1879
|
+
(cs) => cs.length > 0 ? `${cs.join(", ")}, ` : ""
|
|
1514
1880
|
);
|
|
1881
|
+
const data = hasData ? fragment` & ${use("type InstructionWithData", "solanaInstructions")}<${use("type ReadonlyUint8Array", "solanaCodecsCore")}>` : void 0;
|
|
1515
1882
|
const usesLegacyOptionalAccounts = instructionNode.optionalAccountStrategy === "omitted";
|
|
1516
1883
|
const accountMetasFragment = mergeFragments(
|
|
1517
1884
|
instructionNode.accounts.map(
|
|
1518
|
-
(account) => getInstructionAccountMetaFragment(account)
|
|
1885
|
+
(account) => mapFragmentContent8(getInstructionAccountMetaFragment(account), (c) => {
|
|
1519
1886
|
const typeParam = `TAccount${pascalCase6(account.name)}`;
|
|
1520
1887
|
const isLegacyOptional = account.isOptional && usesLegacyOptionalAccounts;
|
|
1521
|
-
const type = `${typeParam} extends string ? ${
|
|
1888
|
+
const type = `${typeParam} extends string ? ${c} : ${typeParam}`;
|
|
1522
1889
|
if (!isLegacyOptional) return type;
|
|
1523
1890
|
return `...(${typeParam} extends undefined ? [] : [${type}])`;
|
|
1524
1891
|
})
|
|
1525
1892
|
),
|
|
1526
|
-
(
|
|
1527
|
-
);
|
|
1528
|
-
const
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
"
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
...
|
|
1542
|
-
|
|
1543
|
-
|
|
1893
|
+
(c) => c.join(", ")
|
|
1894
|
+
);
|
|
1895
|
+
const instructionWithAccounts = use("type InstructionWithAccounts", "solanaInstructions");
|
|
1896
|
+
const accounts = hasAccounts ? fragment` & ${instructionWithAccounts}<[${accountMetasFragment}, ...TRemainingAccounts]>` : fragment` & ${instructionWithAccounts}<TRemainingAccounts>`;
|
|
1897
|
+
return fragment`export type ${instructionType}<TProgram extends string = typeof ${programAddressConstant}, ${accountTypeParams}TRemainingAccounts extends readonly ${use("type AccountMeta", "solanaInstructions")}<string>[] = []> =
|
|
1898
|
+
${use("type Instruction", "solanaInstructions")}<TProgram>${data}${accounts};`;
|
|
1899
|
+
}
|
|
1900
|
+
|
|
1901
|
+
// src/fragments/instructionPage.ts
|
|
1902
|
+
function getInstructionPageFragment(scope) {
|
|
1903
|
+
const node = getLastNodeFromPath16(scope.instructionPath);
|
|
1904
|
+
if (!findProgramNodeFromPath6(scope.instructionPath)) {
|
|
1905
|
+
throw new Error("Instruction must be visited inside a program.");
|
|
1906
|
+
}
|
|
1907
|
+
const childScope = {
|
|
1908
|
+
...scope,
|
|
1909
|
+
dataArgsManifest: visit5(node, scope.typeManifestVisitor),
|
|
1910
|
+
extraArgsManifest: visit5(
|
|
1911
|
+
definedTypeNode2({
|
|
1912
|
+
name: scope.nameApi.instructionExtraType(node.name),
|
|
1913
|
+
type: structTypeNodeFromInstructionArgumentNodes3(node.extraArguments ?? [])
|
|
1914
|
+
}),
|
|
1915
|
+
scope.typeManifestVisitor
|
|
1916
|
+
),
|
|
1917
|
+
renamedArgs: getRenamedArgsMap(node)
|
|
1918
|
+
};
|
|
1919
|
+
return mergeFragments(
|
|
1920
|
+
[
|
|
1921
|
+
getDiscriminatorConstantsFragment({
|
|
1922
|
+
...childScope,
|
|
1923
|
+
discriminatorNodes: node.discriminators ?? [],
|
|
1924
|
+
fields: node.arguments,
|
|
1925
|
+
prefix: node.name
|
|
1926
|
+
}),
|
|
1927
|
+
getInstructionTypeFragment2(childScope),
|
|
1928
|
+
getInstructionDataFragment(childScope),
|
|
1929
|
+
getInstructionExtraArgsFragment(childScope),
|
|
1930
|
+
getInstructionFunctionFragment({ ...childScope, useAsync: true }),
|
|
1931
|
+
getInstructionFunctionFragment({ ...childScope, useAsync: false }),
|
|
1932
|
+
getInstructionParseFunctionFragment(childScope)
|
|
1933
|
+
],
|
|
1934
|
+
(cs) => cs.join("\n\n")
|
|
1935
|
+
);
|
|
1936
|
+
}
|
|
1937
|
+
function getRenamedArgsMap(instruction) {
|
|
1938
|
+
const argNames = [
|
|
1939
|
+
...instruction.arguments.map((a) => a.name),
|
|
1940
|
+
...(instruction.extraArguments ?? []).map((a) => a.name)
|
|
1941
|
+
];
|
|
1942
|
+
const duplicateArgs = argNames.filter((e, i, a) => a.indexOf(e) !== i);
|
|
1943
|
+
if (duplicateArgs.length > 0) {
|
|
1944
|
+
throw new Error(`Duplicate args found: [${duplicateArgs.join(", ")}] in instruction [${instruction.name}].`);
|
|
1945
|
+
}
|
|
1946
|
+
const allNames = [...instruction.accounts.map((account) => account.name), ...argNames];
|
|
1947
|
+
const duplicates = allNames.filter((e, i, a) => a.indexOf(e) !== i);
|
|
1948
|
+
if (duplicates.length === 0) return /* @__PURE__ */ new Map();
|
|
1949
|
+
logWarn(
|
|
1950
|
+
`[JavaScript] Accounts and args of instruction [${instruction.name}] have the following conflicting attributes [${duplicates.join(", ")}]. Thus, the arguments have been renamed to avoid conflicts in the input type.`
|
|
1951
|
+
);
|
|
1952
|
+
return new Map(duplicates.map((name) => [camelCase11(name), camelCase11(`${name}Arg`)]));
|
|
1544
1953
|
}
|
|
1545
1954
|
|
|
1546
1955
|
// src/fragments/pdaFunction.ts
|
|
1547
|
-
import { isNode as isNode13, isNodeFilter as isNodeFilter5 } from "@codama/nodes";
|
|
1548
|
-
import { findProgramNodeFromPath as
|
|
1956
|
+
import { camelCase as camelCase12, isNode as isNode13, isNodeFilter as isNodeFilter5 } from "@codama/nodes";
|
|
1957
|
+
import { findProgramNodeFromPath as findProgramNodeFromPath7, getLastNodeFromPath as getLastNodeFromPath17, visit as visit6 } from "@codama/visitors-core";
|
|
1549
1958
|
function getPdaFunctionFragment(scope) {
|
|
1550
|
-
const
|
|
1551
|
-
const
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1959
|
+
const pdaNode = getLastNodeFromPath17(scope.pdaPath);
|
|
1960
|
+
const seeds = parsePdaSeedNodes(pdaNode.seeds, scope);
|
|
1961
|
+
return mergeFragments(
|
|
1962
|
+
[getSeedInputTypeFragment(seeds, scope), getFunctionFragment2(seeds, scope)],
|
|
1963
|
+
(cs) => cs.join("\n\n")
|
|
1964
|
+
);
|
|
1965
|
+
}
|
|
1966
|
+
function getSeedInputTypeFragment(seeds, scope) {
|
|
1967
|
+
const variableSeeds = seeds.filter(isNodeFilter5("variablePdaSeedNode"));
|
|
1968
|
+
if (variableSeeds.length === 0) return;
|
|
1969
|
+
const pdaNode = getLastNodeFromPath17(scope.pdaPath);
|
|
1970
|
+
const seedTypeName = scope.nameApi.pdaSeedsType(pdaNode.name);
|
|
1971
|
+
const seedAttributes = mergeFragments(
|
|
1972
|
+
variableSeeds.map((seed) => seed.inputAttribute),
|
|
1973
|
+
(cs) => cs.join("\n")
|
|
1974
|
+
);
|
|
1975
|
+
return fragment`export type ${seedTypeName} = {\n${seedAttributes}\n};`;
|
|
1976
|
+
}
|
|
1977
|
+
function getFunctionFragment2(seeds, scope) {
|
|
1978
|
+
const pdaNode = getLastNodeFromPath17(scope.pdaPath);
|
|
1979
|
+
const programNode = findProgramNodeFromPath7(scope.pdaPath);
|
|
1980
|
+
const addressType = use("type Address", "solanaAddresses");
|
|
1981
|
+
const pdaType = use("type ProgramDerivedAddress", "solanaAddresses");
|
|
1982
|
+
const getPdaFunction = use("getProgramDerivedAddress", "solanaAddresses");
|
|
1983
|
+
const seedTypeName = scope.nameApi.pdaSeedsType(pdaNode.name);
|
|
1984
|
+
const findPdaFunction = scope.nameApi.pdaFindFunction(pdaNode.name);
|
|
1985
|
+
const docs = getDocblockFragment(pdaNode.docs ?? [], true);
|
|
1986
|
+
const hasVariableSeeds = seeds.filter(isNodeFilter5("variablePdaSeedNode")).length > 0;
|
|
1987
|
+
const seedArgument = hasVariableSeeds ? `seeds: ${seedTypeName}, ` : "";
|
|
1988
|
+
const programAddress = pdaNode.programId ?? programNode.publicKey;
|
|
1989
|
+
const encodedSeeds = mergeFragments(
|
|
1990
|
+
seeds.map((s) => s.encodedValue),
|
|
1991
|
+
(cs) => cs.join(", ")
|
|
1992
|
+
);
|
|
1993
|
+
return fragment`${docs}export async function ${findPdaFunction}(${seedArgument}config: { programAddress?: ${addressType} | undefined } = {}): Promise<${pdaType}> {
|
|
1994
|
+
const { programAddress = '${programAddress}' as ${addressType}<'${programAddress}'> } = config;
|
|
1995
|
+
return await ${getPdaFunction}({ programAddress, seeds: [${encodedSeeds}]});
|
|
1996
|
+
}`;
|
|
1997
|
+
}
|
|
1998
|
+
function parsePdaSeedNodes(seeds, scope) {
|
|
1999
|
+
return seeds.map((seed) => {
|
|
1555
2000
|
if (isNode13(seed, "variablePdaSeedNode")) {
|
|
1556
|
-
const
|
|
1557
|
-
|
|
1558
|
-
|
|
2001
|
+
const name = camelCase12(seed.name);
|
|
2002
|
+
const docs = getDocblockFragment(seed.docs ?? [], true);
|
|
2003
|
+
const { encoder: encoder2, looseType } = visit6(seed.type, scope.typeManifestVisitor);
|
|
2004
|
+
return {
|
|
2005
|
+
...seed,
|
|
2006
|
+
encodedValue: fragment`${encoder2}.encode(seeds.${name})`,
|
|
2007
|
+
inputAttribute: fragment`${docs}${name}: ${looseType};`
|
|
2008
|
+
};
|
|
1559
2009
|
}
|
|
1560
2010
|
if (isNode13(seed.value, "programIdValueNode")) {
|
|
1561
|
-
|
|
1562
|
-
return seed;
|
|
2011
|
+
const addressEncoder = use("getAddressEncoder", "solanaAddresses");
|
|
2012
|
+
return { ...seed, encodedValue: fragment`${addressEncoder}().encode(programAddress)` };
|
|
1563
2013
|
}
|
|
1564
|
-
const
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
imports.mergeWith(valueManifest.imports);
|
|
1568
|
-
return { ...seed, typeManifest: seedManifest, valueManifest };
|
|
2014
|
+
const { encoder } = visit6(seed.type, scope.typeManifestVisitor);
|
|
2015
|
+
const { value } = visit6(seed.value, scope.typeManifestVisitor);
|
|
2016
|
+
return { ...seed, encodedValue: fragment`${encoder}.encode(${value})` };
|
|
1569
2017
|
});
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
// src/fragments/program.ts
|
|
1582
|
-
function getProgramFragment(scope) {
|
|
1583
|
-
const { programNode, nameApi } = scope;
|
|
1584
|
-
return fragmentFromTemplate("program.njk", {
|
|
1585
|
-
program: programNode,
|
|
1586
|
-
programAddressConstant: nameApi.programAddressConstant(programNode.name)
|
|
1587
|
-
}).addImports("solanaAddresses", ["type Address"]);
|
|
2018
|
+
}
|
|
2019
|
+
|
|
2020
|
+
// src/fragments/pdaPage.ts
|
|
2021
|
+
import { findProgramNodeFromPath as findProgramNodeFromPath8 } from "@codama/visitors-core";
|
|
2022
|
+
function getPdaPageFragment(scope) {
|
|
2023
|
+
if (!findProgramNodeFromPath8(scope.pdaPath)) {
|
|
2024
|
+
throw new Error("PDA must be visited inside a program.");
|
|
2025
|
+
}
|
|
2026
|
+
return getPdaFunctionFragment(scope);
|
|
1588
2027
|
}
|
|
1589
2028
|
|
|
1590
2029
|
// src/fragments/programAccounts.ts
|
|
1591
|
-
import { resolveNestedTypeNode as
|
|
2030
|
+
import { resolveNestedTypeNode as resolveNestedTypeNode3 } from "@codama/nodes";
|
|
2031
|
+
import { mapFragmentContent as mapFragmentContent9 } from "@codama/renderers-core";
|
|
2032
|
+
import { pipe as pipe10 } from "@codama/visitors-core";
|
|
1592
2033
|
function getProgramAccountsFragment(scope) {
|
|
1593
|
-
if (scope.programNode.accounts.length === 0) return
|
|
2034
|
+
if (scope.programNode.accounts.length === 0) return;
|
|
1594
2035
|
return mergeFragments(
|
|
1595
2036
|
[getProgramAccountsEnumFragment(scope), getProgramAccountsIdentifierFunctionFragment(scope)],
|
|
1596
|
-
(
|
|
1597
|
-
`
|
|
2037
|
+
(c) => c.join("\n\n")
|
|
1598
2038
|
);
|
|
1599
2039
|
}
|
|
1600
2040
|
function getProgramAccountsEnumFragment(scope) {
|
|
@@ -1603,7 +2043,7 @@ function getProgramAccountsEnumFragment(scope) {
|
|
|
1603
2043
|
const programAccountsEnumVariants = programNode.accounts.map(
|
|
1604
2044
|
(account) => nameApi.programAccountsEnumVariant(account.name)
|
|
1605
2045
|
);
|
|
1606
|
-
return fragment
|
|
2046
|
+
return fragment`export enum ${programAccountsEnum} { ${programAccountsEnumVariants.join(", ")} }`;
|
|
1607
2047
|
}
|
|
1608
2048
|
function getProgramAccountsIdentifierFunctionFragment(scope) {
|
|
1609
2049
|
const { programNode, nameApi } = scope;
|
|
@@ -1611,54 +2051,55 @@ function getProgramAccountsIdentifierFunctionFragment(scope) {
|
|
|
1611
2051
|
(account) => (account.discriminators ?? []).length > 0
|
|
1612
2052
|
);
|
|
1613
2053
|
const hasAccountDiscriminators = accountsWithDiscriminators.length > 0;
|
|
1614
|
-
if (!hasAccountDiscriminators) return
|
|
2054
|
+
if (!hasAccountDiscriminators) return;
|
|
1615
2055
|
const programAccountsEnum = nameApi.programAccountsEnum(programNode.name);
|
|
1616
2056
|
const programAccountsIdentifierFunction = nameApi.programAccountsIdentifierFunction(programNode.name);
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
(
|
|
2057
|
+
return pipe10(
|
|
2058
|
+
mergeFragments(
|
|
2059
|
+
accountsWithDiscriminators.map((account) => {
|
|
2060
|
+
const variant = nameApi.programAccountsEnumVariant(account.name);
|
|
2061
|
+
return getDiscriminatorConditionFragment({
|
|
2062
|
+
...scope,
|
|
2063
|
+
dataName: "data",
|
|
2064
|
+
discriminators: account.discriminators ?? [],
|
|
2065
|
+
ifTrue: `return ${programAccountsEnum}.${variant};`,
|
|
2066
|
+
struct: resolveNestedTypeNode3(account.data)
|
|
2067
|
+
});
|
|
2068
|
+
}),
|
|
2069
|
+
(c) => c.join("\n")
|
|
2070
|
+
),
|
|
2071
|
+
(f) => mapFragmentContent9(
|
|
2072
|
+
f,
|
|
2073
|
+
(discriminators) => `export function ${programAccountsIdentifierFunction}(account: { data: ReadonlyUint8Array } | ReadonlyUint8Array): ${programAccountsEnum} {
|
|
1632
2074
|
const data = 'data' in account ? account.data : account;
|
|
1633
2075
|
${discriminators}
|
|
1634
2076
|
throw new Error("The provided account could not be identified as a ${programNode.name} account.")
|
|
1635
2077
|
}`
|
|
1636
|
-
|
|
2078
|
+
),
|
|
2079
|
+
(f) => addFragmentImports(f, "solanaCodecsCore", ["type ReadonlyUint8Array"])
|
|
2080
|
+
);
|
|
1637
2081
|
}
|
|
1638
2082
|
|
|
1639
|
-
// src/fragments/
|
|
1640
|
-
|
|
2083
|
+
// src/fragments/programConstant.ts
|
|
2084
|
+
import { pipe as pipe11 } from "@codama/visitors-core";
|
|
2085
|
+
function getProgramConstantFragment(scope) {
|
|
1641
2086
|
const { programNode, nameApi } = scope;
|
|
1642
2087
|
const programAddressConstant = nameApi.programAddressConstant(programNode.name);
|
|
1643
|
-
return
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
programAddressConstant,
|
|
1648
|
-
programErrorMessagesMap: nameApi.programErrorMessagesMap(programNode.name),
|
|
1649
|
-
programErrorUnion: nameApi.programErrorUnion(programNode.name),
|
|
1650
|
-
programGetErrorMessageFunction: nameApi.programGetErrorMessageFunction(programNode.name),
|
|
1651
|
-
programIsErrorFunction: nameApi.programIsErrorFunction(programNode.name)
|
|
1652
|
-
}).addImports("generatedPrograms", [programAddressConstant]).addImports("solanaPrograms", ["isProgramError"]).addImports("solanaErrors", ["type SolanaError", "type SOLANA_ERROR__INSTRUCTION_ERROR__CUSTOM"]).addImports("solanaAddresses", ["type Address"]);
|
|
2088
|
+
return pipe11(
|
|
2089
|
+
fragment`export const ${programAddressConstant} = '${programNode.publicKey}' as Address<'${programNode.publicKey}'>;`,
|
|
2090
|
+
(f) => addFragmentImports(f, "solanaAddresses", ["type Address"])
|
|
2091
|
+
);
|
|
1653
2092
|
}
|
|
1654
2093
|
|
|
1655
2094
|
// src/fragments/programInstructions.ts
|
|
1656
2095
|
import {
|
|
1657
2096
|
getAllInstructionsWithSubs,
|
|
1658
|
-
structTypeNodeFromInstructionArgumentNodes as
|
|
2097
|
+
structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes4
|
|
1659
2098
|
} from "@codama/nodes";
|
|
2099
|
+
import { mapFragmentContent as mapFragmentContent10 } from "@codama/renderers-core";
|
|
2100
|
+
import { pipe as pipe12 } from "@codama/visitors-core";
|
|
1660
2101
|
function getProgramInstructionsFragment(scope) {
|
|
1661
|
-
if (scope.programNode.instructions.length === 0) return
|
|
2102
|
+
if (scope.programNode.instructions.length === 0) return;
|
|
1662
2103
|
const allInstructions = getAllInstructionsWithSubs(scope.programNode, {
|
|
1663
2104
|
leavesOnly: !scope.renderParentInstructions,
|
|
1664
2105
|
subInstructionsFirst: true
|
|
@@ -1670,8 +2111,7 @@ function getProgramInstructionsFragment(scope) {
|
|
|
1670
2111
|
getProgramInstructionsIdentifierFunctionFragment(scopeWithInstructions),
|
|
1671
2112
|
getProgramInstructionsParsedUnionTypeFragment(scopeWithInstructions)
|
|
1672
2113
|
],
|
|
1673
|
-
(
|
|
1674
|
-
`
|
|
2114
|
+
(c) => c.join("\n\n")
|
|
1675
2115
|
);
|
|
1676
2116
|
}
|
|
1677
2117
|
function getProgramInstructionsEnumFragment(scope) {
|
|
@@ -1680,9 +2120,7 @@ function getProgramInstructionsEnumFragment(scope) {
|
|
|
1680
2120
|
const programInstructionsEnumVariants = allInstructions.map(
|
|
1681
2121
|
(instruction) => nameApi.programInstructionsEnumVariant(instruction.name)
|
|
1682
2122
|
);
|
|
1683
|
-
return fragment(
|
|
1684
|
-
`export enum ${programInstructionsEnum} { ${programInstructionsEnumVariants.join(", ")} }`
|
|
1685
|
-
);
|
|
2123
|
+
return fragment`export enum ${programInstructionsEnum} { ${programInstructionsEnumVariants.join(", ")} }`;
|
|
1686
2124
|
}
|
|
1687
2125
|
function getProgramInstructionsIdentifierFunctionFragment(scope) {
|
|
1688
2126
|
const { programNode, nameApi, allInstructions } = scope;
|
|
@@ -1690,7 +2128,7 @@ function getProgramInstructionsIdentifierFunctionFragment(scope) {
|
|
|
1690
2128
|
(instruction) => (instruction.discriminators ?? []).length > 0
|
|
1691
2129
|
);
|
|
1692
2130
|
const hasInstructionDiscriminators = instructionsWithDiscriminators.length > 0;
|
|
1693
|
-
if (!hasInstructionDiscriminators) return
|
|
2131
|
+
if (!hasInstructionDiscriminators) return;
|
|
1694
2132
|
const programInstructionsEnum = nameApi.programInstructionsEnum(programNode.name);
|
|
1695
2133
|
const programInstructionsIdentifierFunction = nameApi.programInstructionsIdentifierFunction(programNode.name);
|
|
1696
2134
|
const discriminatorsFragment = mergeFragments(
|
|
@@ -1701,18 +2139,23 @@ function getProgramInstructionsIdentifierFunctionFragment(scope) {
|
|
|
1701
2139
|
dataName: "data",
|
|
1702
2140
|
discriminators: instruction.discriminators ?? [],
|
|
1703
2141
|
ifTrue: `return ${programInstructionsEnum}.${variant};`,
|
|
1704
|
-
struct:
|
|
2142
|
+
struct: structTypeNodeFromInstructionArgumentNodes4(instruction.arguments)
|
|
1705
2143
|
});
|
|
1706
2144
|
}),
|
|
1707
|
-
(
|
|
2145
|
+
(c) => c.join("\n")
|
|
1708
2146
|
);
|
|
1709
|
-
return
|
|
1710
|
-
|
|
2147
|
+
return pipe12(
|
|
2148
|
+
discriminatorsFragment,
|
|
2149
|
+
(f) => mapFragmentContent10(
|
|
2150
|
+
f,
|
|
2151
|
+
(discriminators) => `export function ${programInstructionsIdentifierFunction}(instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array): ${programInstructionsEnum} {
|
|
1711
2152
|
const data = 'data' in instruction ? instruction.data : instruction;
|
|
1712
2153
|
${discriminators}
|
|
1713
2154
|
throw new Error("The provided instruction could not be identified as a ${programNode.name} instruction.")
|
|
1714
2155
|
}`
|
|
1715
|
-
|
|
2156
|
+
),
|
|
2157
|
+
(f) => addFragmentImports(f, "solanaCodecsCore", ["type ReadonlyUint8Array"])
|
|
2158
|
+
);
|
|
1716
2159
|
}
|
|
1717
2160
|
function getProgramInstructionsParsedUnionTypeFragment(scope) {
|
|
1718
2161
|
const { programNode, allInstructions, nameApi } = scope;
|
|
@@ -1721,17 +2164,164 @@ function getProgramInstructionsParsedUnionTypeFragment(scope) {
|
|
|
1721
2164
|
const programInstructionsEnum = nameApi.programInstructionsEnum(programNode.name);
|
|
1722
2165
|
const typeVariants = allInstructions.map((instruction) => {
|
|
1723
2166
|
const instructionEnumVariant = nameApi.programInstructionsEnumVariant(instruction.name);
|
|
1724
|
-
const parsedInstructionType =
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
)
|
|
2167
|
+
const parsedInstructionType = use(
|
|
2168
|
+
`type ${nameApi.instructionParsedType(instruction.name)}`,
|
|
2169
|
+
"generatedInstructions"
|
|
2170
|
+
);
|
|
2171
|
+
return fragment`| { instructionType: ${programInstructionsEnum}.${instructionEnumVariant} } & ${parsedInstructionType}<TProgram>`;
|
|
1728
2172
|
});
|
|
1729
2173
|
return mergeFragments(
|
|
1730
2174
|
[
|
|
1731
|
-
fragment
|
|
2175
|
+
fragment`export type ${programInstructionsType}<TProgram extends string = '${programAddress}'> =`,
|
|
1732
2176
|
...typeVariants
|
|
1733
2177
|
],
|
|
1734
|
-
(
|
|
2178
|
+
(c) => c.join("\n")
|
|
2179
|
+
);
|
|
2180
|
+
}
|
|
2181
|
+
|
|
2182
|
+
// src/fragments/programPage.ts
|
|
2183
|
+
function getProgramPageFragment(scope) {
|
|
2184
|
+
return mergeFragments(
|
|
2185
|
+
[getProgramConstantFragment(scope), getProgramAccountsFragment(scope), getProgramInstructionsFragment(scope)],
|
|
2186
|
+
(cs) => cs.join("\n\n")
|
|
2187
|
+
);
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
// src/fragments/rootIndexPage.ts
|
|
2191
|
+
function getRootIndexPageFragment(scope) {
|
|
2192
|
+
const hasAnythingToExport = scope.programsToExport.length > 0 || scope.accountsToExport.length > 0 || scope.instructionsToExport.length > 0 || scope.definedTypesToExport.length > 0;
|
|
2193
|
+
if (!hasAnythingToExport) {
|
|
2194
|
+
return fragment`export default {};`;
|
|
2195
|
+
}
|
|
2196
|
+
const programsWithErrorsToExport = scope.programsToExport.filter((p) => p.errors.length > 0);
|
|
2197
|
+
return mergeFragments(
|
|
2198
|
+
[
|
|
2199
|
+
scope.accountsToExport.length > 0 ? getExportAllFragment("./accounts") : void 0,
|
|
2200
|
+
programsWithErrorsToExport.length > 0 ? getExportAllFragment("./errors") : void 0,
|
|
2201
|
+
scope.instructionsToExport.length > 0 ? getExportAllFragment("./instructions") : void 0,
|
|
2202
|
+
scope.pdasToExport.length > 0 ? getExportAllFragment("./pdas") : void 0,
|
|
2203
|
+
scope.programsToExport.length > 0 ? getExportAllFragment("./programs") : void 0,
|
|
2204
|
+
scope.definedTypesToExport.length > 0 ? getExportAllFragment("./types") : void 0
|
|
2205
|
+
],
|
|
2206
|
+
(cs) => cs.join("\n")
|
|
2207
|
+
);
|
|
2208
|
+
}
|
|
2209
|
+
|
|
2210
|
+
// src/fragments/sharedPage.ts
|
|
2211
|
+
import { pipe as pipe13 } from "@codama/visitors-core";
|
|
2212
|
+
function getSharedPageFragment() {
|
|
2213
|
+
const sharedPage = fragment`/**
|
|
2214
|
+
* Asserts that the given value is not null or undefined.
|
|
2215
|
+
* @internal
|
|
2216
|
+
*/
|
|
2217
|
+
export function expectSome<T>(value: T | null | undefined): T {
|
|
2218
|
+
if (value === null || value === undefined) {
|
|
2219
|
+
throw new Error('Expected a value but received null or undefined.');
|
|
2220
|
+
}
|
|
2221
|
+
return value;
|
|
2222
|
+
}
|
|
2223
|
+
|
|
2224
|
+
/**
|
|
2225
|
+
* Asserts that the given value is a PublicKey.
|
|
2226
|
+
* @internal
|
|
2227
|
+
*/
|
|
2228
|
+
export function expectAddress<T extends string = string>(
|
|
2229
|
+
value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
|
|
2230
|
+
): Address<T> {
|
|
2231
|
+
if (!value) {
|
|
2232
|
+
throw new Error('Expected a Address.');
|
|
2233
|
+
}
|
|
2234
|
+
if (typeof value === 'object' && "address" in value) {
|
|
2235
|
+
return value.address;
|
|
2236
|
+
}
|
|
2237
|
+
if (Array.isArray(value)) {
|
|
2238
|
+
return value[0] as Address<T>;
|
|
2239
|
+
}
|
|
2240
|
+
return value as Address<T>;
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
/**
|
|
2244
|
+
* Asserts that the given value is a PDA.
|
|
2245
|
+
* @internal
|
|
2246
|
+
*/
|
|
2247
|
+
export function expectProgramDerivedAddress<T extends string = string>(
|
|
2248
|
+
value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
|
|
2249
|
+
): ProgramDerivedAddress<T> {
|
|
2250
|
+
if (!value || !Array.isArray(value) || !isProgramDerivedAddress(value)) {
|
|
2251
|
+
throw new Error('Expected a ProgramDerivedAddress.');
|
|
2252
|
+
}
|
|
2253
|
+
return value;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2256
|
+
/**
|
|
2257
|
+
* Asserts that the given value is a TransactionSigner.
|
|
2258
|
+
* @internal
|
|
2259
|
+
*/
|
|
2260
|
+
export function expectTransactionSigner<T extends string = string>(
|
|
2261
|
+
value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
|
|
2262
|
+
): TransactionSigner<T> {
|
|
2263
|
+
if (!value || !isTransactionSigner(value)) {
|
|
2264
|
+
throw new Error('Expected a TransactionSigner.');
|
|
2265
|
+
}
|
|
2266
|
+
return value;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
/**
|
|
2270
|
+
* Defines an instruction account to resolve.
|
|
2271
|
+
* @internal
|
|
2272
|
+
*/
|
|
2273
|
+
export type ResolvedAccount<T extends string = string, U extends Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null = Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null> = {
|
|
2274
|
+
isWritable: boolean;
|
|
2275
|
+
value: U;
|
|
2276
|
+
};
|
|
2277
|
+
|
|
2278
|
+
/**
|
|
2279
|
+
* Defines an instruction that stores additional bytes on-chain.
|
|
2280
|
+
* @internal
|
|
2281
|
+
*/
|
|
2282
|
+
export type InstructionWithByteDelta = {
|
|
2283
|
+
byteDelta: number;
|
|
2284
|
+
};
|
|
2285
|
+
|
|
2286
|
+
/**
|
|
2287
|
+
* Get account metas and signers from resolved accounts.
|
|
2288
|
+
* @internal
|
|
2289
|
+
*/
|
|
2290
|
+
export function getAccountMetaFactory(
|
|
2291
|
+
programAddress: Address,
|
|
2292
|
+
optionalAccountStrategy: 'omitted' | 'programId',
|
|
2293
|
+
) {
|
|
2294
|
+
return (account: ResolvedAccount): AccountMeta | AccountSignerMeta | undefined => {
|
|
2295
|
+
if (!account.value) {
|
|
2296
|
+
if (optionalAccountStrategy === 'omitted') return;
|
|
2297
|
+
return Object.freeze({ address: programAddress, role: AccountRole.READONLY });
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
const writableRole = account.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;
|
|
2301
|
+
return Object.freeze({
|
|
2302
|
+
address: expectAddress(account.value),
|
|
2303
|
+
role: isTransactionSigner(account.value) ? upgradeRoleToSigner(writableRole) : writableRole,
|
|
2304
|
+
...(isTransactionSigner(account.value) ? { signer: account.value } : {})
|
|
2305
|
+
});
|
|
2306
|
+
};
|
|
2307
|
+
}
|
|
2308
|
+
|
|
2309
|
+
export function isTransactionSigner<TAddress extends string = string>(value: Address<TAddress> | ProgramDerivedAddress<TAddress> | TransactionSigner<TAddress>): value is TransactionSigner<TAddress> {
|
|
2310
|
+
return !!value && typeof value === 'object' && 'address' in value && kitIsTransactionSigner(value);
|
|
2311
|
+
}`;
|
|
2312
|
+
return pipe13(
|
|
2313
|
+
sharedPage,
|
|
2314
|
+
(f) => addFragmentImports(f, "solanaAddresses", [
|
|
2315
|
+
"type Address",
|
|
2316
|
+
"isProgramDerivedAddress",
|
|
2317
|
+
"type ProgramDerivedAddress"
|
|
2318
|
+
]),
|
|
2319
|
+
(f) => addFragmentImports(f, "solanaInstructions", ["AccountRole", "type AccountMeta", "upgradeRoleToSigner"]),
|
|
2320
|
+
(f) => addFragmentImports(f, "solanaSigners", [
|
|
2321
|
+
"type AccountSignerMeta",
|
|
2322
|
+
"isTransactionSigner as kitIsTransactionSigner",
|
|
2323
|
+
"type TransactionSigner"
|
|
2324
|
+
])
|
|
1735
2325
|
);
|
|
1736
2326
|
}
|
|
1737
2327
|
|
|
@@ -1740,124 +2330,100 @@ import { isDataEnum as isDataEnum3, isNode as isNode14 } from "@codama/nodes";
|
|
|
1740
2330
|
function getTypeDiscriminatedUnionHelpersFragment(scope) {
|
|
1741
2331
|
const { name, typeNode, nameApi } = scope;
|
|
1742
2332
|
const isDiscriminatedUnion = isNode14(typeNode, "enumTypeNode") && isDataEnum3(typeNode);
|
|
1743
|
-
if (!isDiscriminatedUnion)
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
2333
|
+
if (!isDiscriminatedUnion) return;
|
|
2334
|
+
const functionName = nameApi.discriminatedUnionFunction(name);
|
|
2335
|
+
const isDiscriminatedUnionFunctionName = nameApi.isDiscriminatedUnionFunction(name);
|
|
2336
|
+
const discriminatorName = nameApi.discriminatedUnionDiscriminator(name);
|
|
2337
|
+
const strictName = nameApi.dataType(name);
|
|
2338
|
+
const looseName = nameApi.dataArgsType(name);
|
|
2339
|
+
const getVariantContentType = use("type GetDiscriminatedUnionVariantContent", "solanaCodecsDataStructures");
|
|
2340
|
+
const getVariantType = use("type GetDiscriminatedUnionVariant", "solanaCodecsDataStructures");
|
|
2341
|
+
const variantSignatures = mergeFragments(
|
|
2342
|
+
typeNode.variants.map((variant) => {
|
|
2343
|
+
const variantName = nameApi.discriminatedUnionVariant(variant.name);
|
|
2344
|
+
if (isNode14(variant, "enumStructVariantTypeNode")) {
|
|
2345
|
+
return fragment`export function ${functionName}(kind: '${variantName}', data: ${getVariantContentType}<${looseName}, '${discriminatorName}', '${variantName}'>): ${getVariantType}<${looseName}, '${discriminatorName}', '${variantName}'>;`;
|
|
2346
|
+
}
|
|
2347
|
+
if (isNode14(variant, "enumTupleVariantTypeNode")) {
|
|
2348
|
+
return fragment`export function ${functionName}(kind: '${variantName}', data: ${getVariantContentType}<${looseName}, '${discriminatorName}', '${variantName}'>['fields']): ${getVariantType}<${looseName}, '${discriminatorName}', '${variantName}'>;`;
|
|
2349
|
+
}
|
|
2350
|
+
return fragment`export function ${functionName}(kind: '${variantName}'): ${getVariantType}<${looseName}, '${discriminatorName}', '${variantName}'>;`;
|
|
2351
|
+
}),
|
|
2352
|
+
(cs) => cs.length > 0 ? `${cs.join("\n")}
|
|
2353
|
+
` : ""
|
|
2354
|
+
);
|
|
2355
|
+
return fragment`// Data Enum Helpers.
|
|
2356
|
+
${variantSignatures}export function ${functionName}<K extends ${looseName}['${discriminatorName}'], Data>(kind: K, data?: Data) {
|
|
2357
|
+
return Array.isArray(data) ? { ${discriminatorName}: kind, fields: data } : { ${discriminatorName}: kind, ...(data ?? {}) };
|
|
1758
2358
|
}
|
|
1759
2359
|
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
encoder: fragment(""),
|
|
1765
|
-
isEnum: false,
|
|
1766
|
-
looseType: fragment(""),
|
|
1767
|
-
strictType: fragment(""),
|
|
1768
|
-
value: fragment("")
|
|
1769
|
-
};
|
|
1770
|
-
}
|
|
1771
|
-
function mergeManifests(manifests, options = {}) {
|
|
1772
|
-
const { mergeTypes, mergeCodecs, mergeValues } = options;
|
|
1773
|
-
const merge = (fragmentFn, mergeFn) => mergeFn ? mergeFragments(manifests.map(fragmentFn), mergeFn) : fragment("");
|
|
1774
|
-
return {
|
|
1775
|
-
decoder: merge((m) => m.decoder, mergeCodecs),
|
|
1776
|
-
encoder: merge((m) => m.encoder, mergeCodecs),
|
|
1777
|
-
isEnum: false,
|
|
1778
|
-
looseType: merge((m) => m.looseType, mergeTypes),
|
|
1779
|
-
strictType: merge((m) => m.strictType, mergeTypes),
|
|
1780
|
-
value: merge((m) => m.value, mergeValues)
|
|
1781
|
-
};
|
|
2360
|
+
export function ${isDiscriminatedUnionFunctionName}<K extends ${strictName}['${discriminatorName}']>(kind: K, value: ${strictName}): value is ${strictName} & { ${discriminatorName}: K } {
|
|
2361
|
+
return value.${discriminatorName} === kind;
|
|
2362
|
+
};
|
|
2363
|
+
`;
|
|
1782
2364
|
}
|
|
1783
2365
|
|
|
1784
|
-
// src/
|
|
1785
|
-
import {
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
pipe as pipe2,
|
|
1807
|
-
recordLinkablesOnFirstVisitVisitor,
|
|
1808
|
-
recordNodeStackVisitor as recordNodeStackVisitor2,
|
|
1809
|
-
staticVisitor as staticVisitor2,
|
|
1810
|
-
visit as visit6
|
|
1811
|
-
} from "@codama/visitors-core";
|
|
2366
|
+
// src/fragments/typePage.ts
|
|
2367
|
+
import { pipe as pipe14, visit as visit7 } from "@codama/visitors-core";
|
|
2368
|
+
function getTypePageFragment(scope) {
|
|
2369
|
+
const node = scope.node;
|
|
2370
|
+
const manifest = visit7(node, scope.typeManifestVisitor);
|
|
2371
|
+
return pipe14(
|
|
2372
|
+
mergeFragments(
|
|
2373
|
+
[
|
|
2374
|
+
getTypeWithCodecFragment({ ...scope, manifest, name: node.name, node: node.type, typeDocs: node.docs }),
|
|
2375
|
+
getTypeDiscriminatedUnionHelpersFragment({ ...scope, name: node.name, typeNode: node.type })
|
|
2376
|
+
],
|
|
2377
|
+
(cs) => cs.join("\n\n")
|
|
2378
|
+
),
|
|
2379
|
+
(f) => removeFragmentImports(f, "generatedTypes", [
|
|
2380
|
+
scope.nameApi.dataType(node.name),
|
|
2381
|
+
scope.nameApi.dataArgsType(node.name),
|
|
2382
|
+
scope.nameApi.encoderFunction(node.name),
|
|
2383
|
+
scope.nameApi.decoderFunction(node.name),
|
|
2384
|
+
scope.nameApi.codecFunction(node.name)
|
|
2385
|
+
])
|
|
2386
|
+
);
|
|
2387
|
+
}
|
|
1812
2388
|
|
|
1813
|
-
// src/getTypeManifestVisitor.ts
|
|
2389
|
+
// src/visitors/getTypeManifestVisitor.ts
|
|
1814
2390
|
import {
|
|
1815
|
-
camelCase as
|
|
2391
|
+
camelCase as camelCase13,
|
|
1816
2392
|
isNode as isNode15,
|
|
1817
2393
|
isNodeFilter as isNodeFilter6,
|
|
1818
2394
|
isScalarEnum,
|
|
1819
|
-
parseDocs as parseDocs2,
|
|
1820
2395
|
REGISTERED_TYPE_NODE_KINDS,
|
|
1821
2396
|
REGISTERED_VALUE_NODE_KINDS,
|
|
1822
|
-
resolveNestedTypeNode as
|
|
2397
|
+
resolveNestedTypeNode as resolveNestedTypeNode4,
|
|
1823
2398
|
structFieldTypeNode,
|
|
1824
2399
|
structTypeNode,
|
|
1825
|
-
structTypeNodeFromInstructionArgumentNodes as
|
|
2400
|
+
structTypeNodeFromInstructionArgumentNodes as structTypeNodeFromInstructionArgumentNodes5
|
|
1826
2401
|
} from "@codama/nodes";
|
|
2402
|
+
import { mapFragmentContent as mapFragmentContent11, setFragmentContent as setFragmentContent2 } from "@codama/renderers-core";
|
|
1827
2403
|
import {
|
|
1828
2404
|
extendVisitor,
|
|
1829
2405
|
findLastNodeFromPath,
|
|
1830
2406
|
NodeStack,
|
|
1831
|
-
pipe,
|
|
2407
|
+
pipe as pipe15,
|
|
1832
2408
|
recordNodeStackVisitor,
|
|
1833
2409
|
staticVisitor,
|
|
1834
|
-
visit as
|
|
2410
|
+
visit as visit8
|
|
1835
2411
|
} from "@codama/visitors-core";
|
|
1836
2412
|
function getTypeManifestVisitor(input) {
|
|
1837
2413
|
const { nameApi, linkables, nonScalarEnums, customAccountData, customInstructionData, getImportFrom } = input;
|
|
1838
2414
|
const stack = input.stack ?? new NodeStack();
|
|
1839
2415
|
let parentName = null;
|
|
1840
|
-
return
|
|
1841
|
-
staticVisitor(
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
keys: [
|
|
1852
|
-
...REGISTERED_TYPE_NODE_KINDS,
|
|
1853
|
-
...REGISTERED_VALUE_NODE_KINDS,
|
|
1854
|
-
"definedTypeLinkNode",
|
|
1855
|
-
"definedTypeNode",
|
|
1856
|
-
"accountNode",
|
|
1857
|
-
"instructionNode"
|
|
1858
|
-
]
|
|
1859
|
-
}
|
|
1860
|
-
),
|
|
2416
|
+
return pipe15(
|
|
2417
|
+
staticVisitor(() => typeManifest(), {
|
|
2418
|
+
keys: [
|
|
2419
|
+
...REGISTERED_TYPE_NODE_KINDS,
|
|
2420
|
+
...REGISTERED_VALUE_NODE_KINDS,
|
|
2421
|
+
"definedTypeLinkNode",
|
|
2422
|
+
"definedTypeNode",
|
|
2423
|
+
"accountNode",
|
|
2424
|
+
"instructionNode"
|
|
2425
|
+
]
|
|
2426
|
+
}),
|
|
1861
2427
|
(visitor) => extendVisitor(visitor, {
|
|
1862
2428
|
visitAccount(account, { self }) {
|
|
1863
2429
|
parentName = {
|
|
@@ -1865,106 +2431,81 @@ function getTypeManifestVisitor(input) {
|
|
|
1865
2431
|
strict: nameApi.dataType(account.name)
|
|
1866
2432
|
};
|
|
1867
2433
|
const link = customAccountData.get(account.name)?.linkNode;
|
|
1868
|
-
const manifest = link ?
|
|
2434
|
+
const manifest = link ? visit8(link, self) : visit8(account.data, self);
|
|
1869
2435
|
parentName = null;
|
|
1870
2436
|
return manifest;
|
|
1871
2437
|
},
|
|
1872
2438
|
visitAmountType(amountType, { self }) {
|
|
1873
|
-
return
|
|
2439
|
+
return visit8(amountType.number, self);
|
|
1874
2440
|
},
|
|
1875
2441
|
visitArrayType(arrayType, { self }) {
|
|
1876
|
-
const childManifest =
|
|
1877
|
-
childManifest.looseType.mapRender((r) => `Array<${r}>`);
|
|
1878
|
-
childManifest.strictType.mapRender((r) => `Array<${r}>`);
|
|
2442
|
+
const childManifest = visit8(arrayType.item, self);
|
|
1879
2443
|
const sizeManifest = getArrayLikeSizeOption(arrayType.count, self);
|
|
1880
|
-
const encoderOptions = sizeManifest.encoder
|
|
1881
|
-
const decoderOptions = sizeManifest.decoder
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
2444
|
+
const encoderOptions = sizeManifest.encoder ? fragment`, { ${sizeManifest.encoder} }` : "";
|
|
2445
|
+
const decoderOptions = sizeManifest.decoder ? fragment`, { ${sizeManifest.decoder} }` : "";
|
|
2446
|
+
return typeManifest({
|
|
2447
|
+
...childManifest,
|
|
2448
|
+
decoder: fragment`${use("getArrayDecoder", "solanaCodecsDataStructures")}(${childManifest.decoder}${decoderOptions})`,
|
|
2449
|
+
encoder: fragment`${use("getArrayEncoder", "solanaCodecsDataStructures")}(${childManifest.encoder}${encoderOptions})`,
|
|
2450
|
+
looseType: fragment`Array<${childManifest.looseType}>`,
|
|
2451
|
+
strictType: fragment`Array<${childManifest.strictType}>`
|
|
2452
|
+
});
|
|
1885
2453
|
},
|
|
1886
2454
|
visitArrayValue(node, { self }) {
|
|
1887
|
-
return
|
|
1888
|
-
node.items.map((v) =>
|
|
2455
|
+
return mergeTypeManifests(
|
|
2456
|
+
node.items.map((v) => visit8(v, self)),
|
|
1889
2457
|
{ mergeValues: (renders) => `[${renders.join(", ")}]` }
|
|
1890
2458
|
);
|
|
1891
2459
|
},
|
|
1892
2460
|
visitBooleanType(booleanType, { self }) {
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
let sizeDecoder = "";
|
|
1897
|
-
const resolvedSize = resolveNestedTypeNode3(booleanType.size);
|
|
2461
|
+
let sizeEncoder = fragment``;
|
|
2462
|
+
let sizeDecoder = fragment``;
|
|
2463
|
+
const resolvedSize = resolveNestedTypeNode4(booleanType.size);
|
|
1898
2464
|
if (resolvedSize.format !== "u8" || resolvedSize.endian !== "le") {
|
|
1899
|
-
const size =
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
sizeEncoder = `{ size: ${size.encoder.render} }`;
|
|
1903
|
-
sizeDecoder = `{ size: ${size.decoder.render} }`;
|
|
2465
|
+
const size = visit8(booleanType.size, self);
|
|
2466
|
+
sizeEncoder = fragment`{ size: ${size.encoder} }`;
|
|
2467
|
+
sizeDecoder = fragment`{ size: ${size.decoder} }`;
|
|
1904
2468
|
}
|
|
1905
|
-
return {
|
|
1906
|
-
decoder: fragment(
|
|
1907
|
-
encoder: fragment(
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
value: fragment("")
|
|
1912
|
-
};
|
|
2469
|
+
return typeManifest({
|
|
2470
|
+
decoder: fragment`${use("getBooleanDecoder", "solanaCodecsDataStructures")}(${sizeDecoder})`,
|
|
2471
|
+
encoder: fragment`${use("getBooleanEncoder", "solanaCodecsDataStructures")}(${sizeEncoder})`,
|
|
2472
|
+
looseType: fragment`boolean`,
|
|
2473
|
+
strictType: fragment`boolean`
|
|
2474
|
+
});
|
|
1913
2475
|
},
|
|
1914
2476
|
visitBooleanValue(node) {
|
|
1915
|
-
|
|
1916
|
-
manifest.value.setRender(JSON.stringify(node.boolean));
|
|
1917
|
-
return manifest;
|
|
2477
|
+
return typeManifest({ value: fragment`${JSON.stringify(node.boolean)}` });
|
|
1918
2478
|
},
|
|
1919
2479
|
visitBytesType() {
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
"getBytesEncoder"
|
|
1928
|
-
),
|
|
1929
|
-
isEnum: false,
|
|
1930
|
-
looseType: fragment("ReadonlyUint8Array").addImports(
|
|
1931
|
-
"solanaCodecsCore",
|
|
1932
|
-
"type ReadonlyUint8Array"
|
|
1933
|
-
),
|
|
1934
|
-
strictType: fragment("ReadonlyUint8Array").addImports(
|
|
1935
|
-
"solanaCodecsCore",
|
|
1936
|
-
"type ReadonlyUint8Array"
|
|
1937
|
-
),
|
|
1938
|
-
value: fragment("")
|
|
1939
|
-
};
|
|
2480
|
+
const readonlyUint8Array = use("type ReadonlyUint8Array", "solanaCodecsCore");
|
|
2481
|
+
return typeManifest({
|
|
2482
|
+
decoder: fragment`${use("getBytesDecoder", "solanaCodecsDataStructures")}()`,
|
|
2483
|
+
encoder: fragment`${use("getBytesEncoder", "solanaCodecsDataStructures")}()`,
|
|
2484
|
+
looseType: readonlyUint8Array,
|
|
2485
|
+
strictType: readonlyUint8Array
|
|
2486
|
+
});
|
|
1940
2487
|
},
|
|
1941
2488
|
visitBytesValue(node) {
|
|
1942
|
-
const manifest = typeManifest();
|
|
1943
2489
|
const bytes = getBytesFromBytesValueNode(node);
|
|
1944
|
-
|
|
1945
|
-
return manifest;
|
|
2490
|
+
return typeManifest({ value: fragment`new Uint8Array([${Array.from(bytes).join(", ")}])` });
|
|
1946
2491
|
},
|
|
1947
2492
|
visitConstantValue(node, { self }) {
|
|
1948
2493
|
if (isNode15(node.type, "bytesTypeNode") && isNode15(node.value, "bytesValueNode")) {
|
|
1949
|
-
return
|
|
2494
|
+
return visit8(node.value, self);
|
|
1950
2495
|
}
|
|
1951
|
-
return {
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
[visit5(node.type, self).encoder, visit5(node.value, self).value],
|
|
1955
|
-
([encoderFunction, value]) => `${encoderFunction}.encode(${value})`
|
|
1956
|
-
)
|
|
1957
|
-
};
|
|
2496
|
+
return typeManifest({
|
|
2497
|
+
value: fragment`${visit8(node.type, self).encoder}.encode(${visit8(node.value, self).value})`
|
|
2498
|
+
});
|
|
1958
2499
|
},
|
|
1959
2500
|
visitDateTimeType(dateTimeType, { self }) {
|
|
1960
|
-
return
|
|
2501
|
+
return visit8(dateTimeType.number, self);
|
|
1961
2502
|
},
|
|
1962
2503
|
visitDefinedType(definedType, { self }) {
|
|
1963
2504
|
parentName = {
|
|
1964
2505
|
loose: nameApi.dataArgsType(definedType.name),
|
|
1965
2506
|
strict: nameApi.dataType(definedType.name)
|
|
1966
2507
|
};
|
|
1967
|
-
const manifest =
|
|
2508
|
+
const manifest = visit8(definedType.type, self);
|
|
1968
2509
|
parentName = null;
|
|
1969
2510
|
return manifest;
|
|
1970
2511
|
},
|
|
@@ -1974,54 +2515,52 @@ function getTypeManifestVisitor(input) {
|
|
|
1974
2515
|
const encoderFunction = nameApi.encoderFunction(node.name);
|
|
1975
2516
|
const decoderFunction = nameApi.decoderFunction(node.name);
|
|
1976
2517
|
const importFrom = getImportFrom(node);
|
|
1977
|
-
return {
|
|
1978
|
-
decoder: fragment
|
|
1979
|
-
encoder: fragment
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
value: fragment("")
|
|
1984
|
-
};
|
|
2518
|
+
return typeManifest({
|
|
2519
|
+
decoder: fragment`${use(decoderFunction, importFrom)}()`,
|
|
2520
|
+
encoder: fragment`${use(encoderFunction, importFrom)}()`,
|
|
2521
|
+
looseType: use(`type ${looseName}`, importFrom),
|
|
2522
|
+
strictType: use(`type ${strictName}`, importFrom)
|
|
2523
|
+
});
|
|
1985
2524
|
},
|
|
1986
2525
|
visitEnumEmptyVariantType(enumEmptyVariantType) {
|
|
1987
|
-
const discriminator = nameApi.discriminatedUnionDiscriminator(
|
|
2526
|
+
const discriminator = nameApi.discriminatedUnionDiscriminator(camelCase13(parentName?.strict ?? ""));
|
|
1988
2527
|
const name = nameApi.discriminatedUnionVariant(enumEmptyVariantType.name);
|
|
1989
2528
|
const kindAttribute = `${discriminator}: "${name}"`;
|
|
1990
|
-
return {
|
|
1991
|
-
decoder: fragment
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
"solanaCodecsDataStructures",
|
|
1997
|
-
"getUnitEncoder"
|
|
1998
|
-
),
|
|
1999
|
-
isEnum: false,
|
|
2000
|
-
looseType: fragment(`{ ${kindAttribute} }`),
|
|
2001
|
-
strictType: fragment(`{ ${kindAttribute} }`),
|
|
2002
|
-
value: fragment("")
|
|
2003
|
-
};
|
|
2529
|
+
return typeManifest({
|
|
2530
|
+
decoder: fragment`['${name}', ${use("getUnitDecoder", "solanaCodecsDataStructures")}()]`,
|
|
2531
|
+
encoder: fragment`['${name}', ${use("getUnitEncoder", "solanaCodecsDataStructures")}()]`,
|
|
2532
|
+
looseType: fragment`{ ${kindAttribute} }`,
|
|
2533
|
+
strictType: fragment`{ ${kindAttribute} }`
|
|
2534
|
+
});
|
|
2004
2535
|
},
|
|
2005
2536
|
visitEnumStructVariantType(enumStructVariantType, { self }) {
|
|
2006
2537
|
const currentParentName = parentName;
|
|
2007
2538
|
const discriminator = nameApi.discriminatedUnionDiscriminator(
|
|
2008
|
-
|
|
2539
|
+
camelCase13(currentParentName?.strict ?? "")
|
|
2009
2540
|
);
|
|
2010
2541
|
const name = nameApi.discriminatedUnionVariant(enumStructVariantType.name);
|
|
2011
2542
|
const kindAttribute = `${discriminator}: "${name}"`;
|
|
2012
2543
|
parentName = null;
|
|
2013
|
-
const structManifest =
|
|
2544
|
+
const structManifest = visit8(enumStructVariantType.struct, self);
|
|
2014
2545
|
parentName = currentParentName;
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2546
|
+
return typeManifest({
|
|
2547
|
+
...structManifest,
|
|
2548
|
+
decoder: fragment`['${name}', ${structManifest.decoder}]`,
|
|
2549
|
+
encoder: fragment`['${name}', ${structManifest.encoder}]`,
|
|
2550
|
+
looseType: pipe15(
|
|
2551
|
+
structManifest.looseType,
|
|
2552
|
+
(f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
|
|
2553
|
+
),
|
|
2554
|
+
strictType: pipe15(
|
|
2555
|
+
structManifest.strictType,
|
|
2556
|
+
(f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
|
|
2557
|
+
)
|
|
2558
|
+
});
|
|
2020
2559
|
},
|
|
2021
2560
|
visitEnumTupleVariantType(enumTupleVariantType, { self }) {
|
|
2022
2561
|
const currentParentName = parentName;
|
|
2023
2562
|
const discriminator = nameApi.discriminatedUnionDiscriminator(
|
|
2024
|
-
|
|
2563
|
+
camelCase13(currentParentName?.strict ?? "")
|
|
2025
2564
|
);
|
|
2026
2565
|
const name = nameApi.discriminatedUnionVariant(enumTupleVariantType.name);
|
|
2027
2566
|
const kindAttribute = `${discriminator}: "${name}"`;
|
|
@@ -2032,37 +2571,47 @@ function getTypeManifestVisitor(input) {
|
|
|
2032
2571
|
})
|
|
2033
2572
|
]);
|
|
2034
2573
|
parentName = null;
|
|
2035
|
-
const structManifest =
|
|
2574
|
+
const structManifest = visit8(struct, self);
|
|
2036
2575
|
parentName = currentParentName;
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2576
|
+
return typeManifest({
|
|
2577
|
+
...structManifest,
|
|
2578
|
+
decoder: fragment`['${name}', ${structManifest.decoder}]`,
|
|
2579
|
+
encoder: fragment`['${name}', ${structManifest.encoder}]`,
|
|
2580
|
+
looseType: pipe15(
|
|
2581
|
+
structManifest.looseType,
|
|
2582
|
+
(f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
|
|
2583
|
+
),
|
|
2584
|
+
strictType: pipe15(
|
|
2585
|
+
structManifest.strictType,
|
|
2586
|
+
(f) => mapFragmentContent11(f, (c) => `{ ${kindAttribute},${c.slice(1, -1)}}`)
|
|
2587
|
+
)
|
|
2588
|
+
});
|
|
2042
2589
|
},
|
|
2043
2590
|
visitEnumType(enumType, { self }) {
|
|
2044
2591
|
const currentParentName = parentName;
|
|
2045
|
-
const encoderImports = new ImportMap();
|
|
2046
|
-
const decoderImports = new ImportMap();
|
|
2047
2592
|
const encoderOptions = [];
|
|
2048
2593
|
const decoderOptions = [];
|
|
2049
|
-
const enumSize =
|
|
2594
|
+
const enumSize = resolveNestedTypeNode4(enumType.size);
|
|
2050
2595
|
if (enumSize.format !== "u8" || enumSize.endian !== "le") {
|
|
2051
|
-
const sizeManifest =
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
encoderOptions.push(`size: ${sizeManifest.encoder.render}`);
|
|
2055
|
-
decoderOptions.push(`size: ${sizeManifest.decoder.render}`);
|
|
2596
|
+
const sizeManifest = visit8(enumType.size, self);
|
|
2597
|
+
encoderOptions.push(fragment`size: ${sizeManifest.encoder}`);
|
|
2598
|
+
decoderOptions.push(fragment`size: ${sizeManifest.decoder}`);
|
|
2056
2599
|
}
|
|
2057
2600
|
const discriminator = nameApi.discriminatedUnionDiscriminator(
|
|
2058
|
-
|
|
2601
|
+
camelCase13(currentParentName?.strict ?? "")
|
|
2059
2602
|
);
|
|
2060
2603
|
if (!isScalarEnum(enumType) && discriminator !== "__kind") {
|
|
2061
|
-
encoderOptions.push(`discriminator: '${discriminator}'`);
|
|
2062
|
-
decoderOptions.push(`discriminator: '${discriminator}'`);
|
|
2604
|
+
encoderOptions.push(fragment`discriminator: '${discriminator}'`);
|
|
2605
|
+
decoderOptions.push(fragment`discriminator: '${discriminator}'`);
|
|
2063
2606
|
}
|
|
2064
|
-
const
|
|
2065
|
-
|
|
2607
|
+
const encoderOptionsFragment = mergeFragments(
|
|
2608
|
+
encoderOptions,
|
|
2609
|
+
(cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
|
|
2610
|
+
);
|
|
2611
|
+
const decoderOptionsFragment = mergeFragments(
|
|
2612
|
+
decoderOptions,
|
|
2613
|
+
(cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
|
|
2614
|
+
);
|
|
2066
2615
|
if (isScalarEnum(enumType)) {
|
|
2067
2616
|
if (currentParentName === null) {
|
|
2068
2617
|
throw new Error(
|
|
@@ -2070,31 +2619,26 @@ function getTypeManifestVisitor(input) {
|
|
|
2070
2619
|
);
|
|
2071
2620
|
}
|
|
2072
2621
|
const variantNames = enumType.variants.map(({ name }) => nameApi.enumVariant(name));
|
|
2073
|
-
return {
|
|
2074
|
-
decoder: fragment(
|
|
2075
|
-
|
|
2076
|
-
decoderImports.add("solanaCodecsDataStructures", "getEnumDecoder")
|
|
2077
|
-
),
|
|
2078
|
-
encoder: fragment(
|
|
2079
|
-
`getEnumEncoder(${currentParentName.strict + encoderOptionsAsString})`,
|
|
2080
|
-
encoderImports.add("solanaCodecsDataStructures", "getEnumEncoder")
|
|
2081
|
-
),
|
|
2622
|
+
return typeManifest({
|
|
2623
|
+
decoder: fragment`${use("getEnumDecoder", "solanaCodecsDataStructures")}(${currentParentName.strict}${decoderOptionsFragment})`,
|
|
2624
|
+
encoder: fragment`${use("getEnumEncoder", "solanaCodecsDataStructures")}(${currentParentName.strict}${encoderOptionsFragment})`,
|
|
2082
2625
|
isEnum: true,
|
|
2083
|
-
looseType: fragment
|
|
2084
|
-
strictType: fragment
|
|
2085
|
-
|
|
2086
|
-
};
|
|
2626
|
+
looseType: fragment`{ ${variantNames.join(", ")} }`,
|
|
2627
|
+
strictType: fragment`{ ${variantNames.join(", ")} }`
|
|
2628
|
+
});
|
|
2087
2629
|
}
|
|
2088
|
-
const mergedManifest =
|
|
2089
|
-
enumType.variants.map((variant) =>
|
|
2630
|
+
const mergedManifest = mergeTypeManifests(
|
|
2631
|
+
enumType.variants.map((variant) => visit8(variant, self)),
|
|
2090
2632
|
{
|
|
2091
2633
|
mergeCodecs: (renders) => renders.join(", "),
|
|
2092
2634
|
mergeTypes: (renders) => renders.join(" | ")
|
|
2093
2635
|
}
|
|
2094
2636
|
);
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2637
|
+
return typeManifest({
|
|
2638
|
+
...mergedManifest,
|
|
2639
|
+
decoder: fragment`${use("getDiscriminatedUnionDecoder", "solanaCodecsDataStructures")}([${mergedManifest.decoder}]${decoderOptionsFragment})`,
|
|
2640
|
+
encoder: fragment`${use("getDiscriminatedUnionEncoder", "solanaCodecsDataStructures")}([${mergedManifest.encoder}]${encoderOptionsFragment})`
|
|
2641
|
+
});
|
|
2098
2642
|
},
|
|
2099
2643
|
visitEnumValue(node, { self }) {
|
|
2100
2644
|
const manifest = typeManifest();
|
|
@@ -2105,40 +2649,76 @@ function getTypeManifestVisitor(input) {
|
|
|
2105
2649
|
const isScalar = enumNode && isNode15(enumNode, "enumTypeNode") ? isScalarEnum(enumNode) : !nonScalarEnums.includes(node.enum.name);
|
|
2106
2650
|
if (!node.value && isScalar) {
|
|
2107
2651
|
const variantName2 = nameApi.enumVariant(node.variant);
|
|
2108
|
-
|
|
2109
|
-
|
|
2652
|
+
return typeManifest({
|
|
2653
|
+
...manifest,
|
|
2654
|
+
value: pipe15(
|
|
2655
|
+
manifest.value,
|
|
2656
|
+
(f) => setFragmentContent2(f, `${enumName}.${variantName2}`),
|
|
2657
|
+
(f) => addFragmentImports(f, importFrom, [enumName])
|
|
2658
|
+
)
|
|
2659
|
+
});
|
|
2110
2660
|
}
|
|
2111
2661
|
const variantName = nameApi.discriminatedUnionVariant(node.variant);
|
|
2112
2662
|
if (!node.value) {
|
|
2113
|
-
|
|
2114
|
-
|
|
2663
|
+
return typeManifest({
|
|
2664
|
+
...manifest,
|
|
2665
|
+
value: pipe15(
|
|
2666
|
+
manifest.value,
|
|
2667
|
+
(f) => setFragmentContent2(f, `${enumFunction}('${variantName}')`),
|
|
2668
|
+
(f) => addFragmentImports(f, importFrom, [enumFunction])
|
|
2669
|
+
)
|
|
2670
|
+
});
|
|
2115
2671
|
}
|
|
2116
|
-
|
|
2117
|
-
|
|
2672
|
+
return typeManifest({
|
|
2673
|
+
...manifest,
|
|
2674
|
+
value: pipe15(
|
|
2675
|
+
visit8(node.value, self).value,
|
|
2676
|
+
(f) => mapFragmentContent11(f, (c) => `${enumFunction}('${variantName}', ${c})`),
|
|
2677
|
+
(f) => addFragmentImports(f, importFrom, [enumFunction])
|
|
2678
|
+
)
|
|
2679
|
+
});
|
|
2118
2680
|
},
|
|
2119
2681
|
visitFixedSizeType(node, { self }) {
|
|
2120
|
-
const manifest =
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2682
|
+
const manifest = visit8(node.type, self);
|
|
2683
|
+
return typeManifest({
|
|
2684
|
+
...manifest,
|
|
2685
|
+
decoder: fragment`${use("fixDecoderSize", "solanaCodecsCore")}(${manifest.decoder}, ${node.size})`,
|
|
2686
|
+
encoder: fragment`${use("fixEncoderSize", "solanaCodecsCore")}(${manifest.encoder}, ${node.size})`
|
|
2687
|
+
});
|
|
2124
2688
|
},
|
|
2125
2689
|
visitHiddenPrefixType(node, { self }) {
|
|
2126
|
-
const manifest =
|
|
2127
|
-
const prefixes = node.prefix.map((c) =>
|
|
2128
|
-
const prefixEncoders =
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2690
|
+
const manifest = visit8(node.type, self);
|
|
2691
|
+
const prefixes = node.prefix.map((c) => visit8(c, self).value);
|
|
2692
|
+
const prefixEncoders = pipe15(
|
|
2693
|
+
mergeFragments(prefixes, (cs) => cs.map((c) => `getConstantEncoder(${c})`).join(", ")),
|
|
2694
|
+
(f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantEncoder"])
|
|
2695
|
+
);
|
|
2696
|
+
const prefixDecoders = pipe15(
|
|
2697
|
+
mergeFragments(prefixes, (cs) => cs.map((c) => `getConstantDecoder(${c})`).join(", ")),
|
|
2698
|
+
(f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantDecoder"])
|
|
2699
|
+
);
|
|
2700
|
+
return typeManifest({
|
|
2701
|
+
...manifest,
|
|
2702
|
+
decoder: fragment`${use("getHiddenPrefixDecoder", "solanaCodecsDataStructures")}(${manifest.decoder}, [${prefixDecoders}])`,
|
|
2703
|
+
encoder: fragment`${use("getHiddenPrefixEncoder", "solanaCodecsDataStructures")}(${manifest.encoder}, [${prefixEncoders}])`
|
|
2704
|
+
});
|
|
2133
2705
|
},
|
|
2134
2706
|
visitHiddenSuffixType(node, { self }) {
|
|
2135
|
-
const manifest =
|
|
2136
|
-
const suffixes = node.suffix.map((c) =>
|
|
2137
|
-
const suffixEncoders =
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2707
|
+
const manifest = visit8(node.type, self);
|
|
2708
|
+
const suffixes = node.suffix.map((c) => visit8(c, self).value);
|
|
2709
|
+
const suffixEncoders = pipe15(
|
|
2710
|
+
mergeFragments(suffixes, (cs) => cs.map((c) => `getConstantEncoder(${c})`).join(", ")),
|
|
2711
|
+
(f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantEncoder"])
|
|
2712
|
+
);
|
|
2713
|
+
const suffixDecoders = pipe15(
|
|
2714
|
+
mergeFragments(suffixes, (cs) => cs.map((c) => `getConstantDecoder(${c})`).join(", ")),
|
|
2715
|
+
(f) => addFragmentImports(f, "solanaCodecsCore", ["getConstantDecoder"])
|
|
2716
|
+
);
|
|
2717
|
+
return typeManifest({
|
|
2718
|
+
...manifest,
|
|
2719
|
+
decoder: fragment`${use("getHiddenSuffixDecoder", "solanaCodecsDataStructures")}(${manifest.decoder}, [${suffixDecoders}])`,
|
|
2720
|
+
encoder: fragment`${use("getHiddenSuffixEncoder", "solanaCodecsDataStructures")}(${manifest.encoder}, [${suffixEncoders}])`
|
|
2721
|
+
});
|
|
2142
2722
|
},
|
|
2143
2723
|
visitInstruction(instruction, { self }) {
|
|
2144
2724
|
const instructionDataName = nameApi.instructionDataType(instruction.name);
|
|
@@ -2147,97 +2727,96 @@ function getTypeManifestVisitor(input) {
|
|
|
2147
2727
|
strict: nameApi.dataType(instructionDataName)
|
|
2148
2728
|
};
|
|
2149
2729
|
const link = customInstructionData.get(instruction.name)?.linkNode;
|
|
2150
|
-
const struct =
|
|
2151
|
-
const manifest = link ?
|
|
2730
|
+
const struct = structTypeNodeFromInstructionArgumentNodes5(instruction.arguments);
|
|
2731
|
+
const manifest = link ? visit8(link, self) : visit8(struct, self);
|
|
2152
2732
|
parentName = null;
|
|
2153
2733
|
return manifest;
|
|
2154
2734
|
},
|
|
2155
2735
|
visitMapEntryValue(node, { self }) {
|
|
2156
|
-
return
|
|
2736
|
+
return mergeTypeManifests([visit8(node.key, self), visit8(node.value, self)], {
|
|
2157
2737
|
mergeValues: (renders) => `[${renders.join(", ")}]`
|
|
2158
2738
|
});
|
|
2159
2739
|
},
|
|
2160
2740
|
visitMapType(mapType, { self }) {
|
|
2161
|
-
const key =
|
|
2162
|
-
const value =
|
|
2163
|
-
const mergedManifest =
|
|
2741
|
+
const key = visit8(mapType.key, self);
|
|
2742
|
+
const value = visit8(mapType.value, self);
|
|
2743
|
+
const mergedManifest = mergeTypeManifests([key, value], {
|
|
2164
2744
|
mergeCodecs: ([k, v]) => `${k}, ${v}`,
|
|
2165
2745
|
mergeTypes: ([k, v]) => `Map<${k}, ${v}>`
|
|
2166
2746
|
});
|
|
2167
2747
|
const sizeManifest = getArrayLikeSizeOption(mapType.count, self);
|
|
2168
|
-
const encoderOptions = sizeManifest.encoder
|
|
2169
|
-
const decoderOptions = sizeManifest.decoder
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2748
|
+
const encoderOptions = sizeManifest.encoder ? fragment`, { ${sizeManifest.encoder} }` : "";
|
|
2749
|
+
const decoderOptions = sizeManifest.decoder ? fragment`, { ${sizeManifest.decoder} }` : "";
|
|
2750
|
+
return typeManifest({
|
|
2751
|
+
...mergedManifest,
|
|
2752
|
+
decoder: fragment`${use("getMapDecoder", "solanaCodecsDataStructures")}(${mergedManifest.decoder}${decoderOptions})`,
|
|
2753
|
+
encoder: fragment`${use("getMapEncoder", "solanaCodecsDataStructures")}(${mergedManifest.encoder}${encoderOptions})`
|
|
2754
|
+
});
|
|
2173
2755
|
},
|
|
2174
2756
|
visitMapValue(node, { self }) {
|
|
2175
|
-
const entryFragments = node.entries.map((entry) =>
|
|
2176
|
-
return
|
|
2757
|
+
const entryFragments = node.entries.map((entry) => visit8(entry, self));
|
|
2758
|
+
return mergeTypeManifests(entryFragments, {
|
|
2177
2759
|
mergeValues: (renders) => `new Map([${renders.join(", ")}])`
|
|
2178
2760
|
});
|
|
2179
2761
|
},
|
|
2180
2762
|
visitNoneValue() {
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2763
|
+
return typeManifest({
|
|
2764
|
+
value: fragment`${use("none", "solanaOptions")}()`
|
|
2765
|
+
});
|
|
2184
2766
|
},
|
|
2185
2767
|
visitNumberType(numberType) {
|
|
2186
|
-
const encoderFunction = nameApi.encoderFunction(numberType.format);
|
|
2187
|
-
const decoderFunction = nameApi.decoderFunction(numberType.format);
|
|
2768
|
+
const encoderFunction = use(nameApi.encoderFunction(numberType.format), "solanaCodecsNumbers");
|
|
2769
|
+
const decoderFunction = use(nameApi.decoderFunction(numberType.format), "solanaCodecsNumbers");
|
|
2188
2770
|
const isBigNumber = ["u64", "u128", "i64", "i128"].includes(numberType.format);
|
|
2189
|
-
const
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
}
|
|
2197
|
-
return {
|
|
2198
|
-
decoder: fragment(`${decoderFunction}(${endianness})`, decoderImports),
|
|
2199
|
-
encoder: fragment(`${encoderFunction}(${endianness})`, encoderImports),
|
|
2200
|
-
isEnum: false,
|
|
2201
|
-
looseType: fragment(isBigNumber ? "number | bigint" : "number"),
|
|
2202
|
-
strictType: fragment(isBigNumber ? "bigint" : "number"),
|
|
2203
|
-
value: fragment("")
|
|
2204
|
-
};
|
|
2771
|
+
const endianness = numberType.endian === "be" ? fragment`{ endian: ${use("Endian", "solanaCodecsNumbers")}.Big }` : "";
|
|
2772
|
+
return typeManifest({
|
|
2773
|
+
decoder: fragment`${decoderFunction}(${endianness})`,
|
|
2774
|
+
encoder: fragment`${encoderFunction}(${endianness})`,
|
|
2775
|
+
looseType: fragment`${isBigNumber ? "number | bigint" : "number"}`,
|
|
2776
|
+
strictType: fragment`${isBigNumber ? "bigint" : "number"}`
|
|
2777
|
+
});
|
|
2205
2778
|
},
|
|
2206
2779
|
visitNumberValue(node) {
|
|
2207
|
-
|
|
2208
|
-
manifest.value.setRender(JSON.stringify(node.number));
|
|
2209
|
-
return manifest;
|
|
2780
|
+
return typeManifest({ value: fragment`${JSON.stringify(node.number)}` });
|
|
2210
2781
|
},
|
|
2211
2782
|
visitOptionType(optionType, { self }) {
|
|
2212
|
-
const childManifest =
|
|
2213
|
-
childManifest.strictType.mapRender((r) => `Option<${r}>`).addImports("solanaOptions", "type Option");
|
|
2214
|
-
childManifest.looseType.mapRender((r) => `OptionOrNullable<${r}>`).addImports("solanaOptions", "type OptionOrNullable");
|
|
2783
|
+
const childManifest = visit8(optionType.item, self);
|
|
2215
2784
|
const encoderOptions = [];
|
|
2216
2785
|
const decoderOptions = [];
|
|
2217
|
-
const optionPrefix =
|
|
2786
|
+
const optionPrefix = resolveNestedTypeNode4(optionType.prefix);
|
|
2218
2787
|
if (optionPrefix.format !== "u8" || optionPrefix.endian !== "le") {
|
|
2219
|
-
const prefixManifest =
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
encoderOptions.push(`prefix: ${prefixManifest.encoder.render}`);
|
|
2223
|
-
decoderOptions.push(`prefix: ${prefixManifest.decoder.render}`);
|
|
2788
|
+
const prefixManifest = visit8(optionType.prefix, self);
|
|
2789
|
+
encoderOptions.push(fragment`prefix: ${prefixManifest.encoder}`);
|
|
2790
|
+
decoderOptions.push(fragment`prefix: ${prefixManifest.decoder}`);
|
|
2224
2791
|
}
|
|
2225
2792
|
if (optionType.fixed) {
|
|
2226
|
-
encoderOptions.push(`noneValue: "zeroes"`);
|
|
2227
|
-
decoderOptions.push(`noneValue: "zeroes"`);
|
|
2793
|
+
encoderOptions.push(fragment`noneValue: "zeroes"`);
|
|
2794
|
+
decoderOptions.push(fragment`noneValue: "zeroes"`);
|
|
2228
2795
|
}
|
|
2229
|
-
const
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2796
|
+
const encoderOptionsFragment = mergeFragments(
|
|
2797
|
+
encoderOptions,
|
|
2798
|
+
(cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
|
|
2799
|
+
);
|
|
2800
|
+
const decoderOptionsFragment = mergeFragments(
|
|
2801
|
+
decoderOptions,
|
|
2802
|
+
(cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
|
|
2803
|
+
);
|
|
2804
|
+
return typeManifest({
|
|
2805
|
+
...childManifest,
|
|
2806
|
+
decoder: fragment`${use("getOptionDecoder", "solanaOptions")}(${childManifest.decoder}${decoderOptionsFragment})`,
|
|
2807
|
+
encoder: fragment`${use("getOptionEncoder", "solanaOptions")}(${childManifest.encoder}${encoderOptionsFragment})`,
|
|
2808
|
+
looseType: fragment`${use("type OptionOrNullable", "solanaOptions")}<${childManifest.looseType}>`,
|
|
2809
|
+
strictType: fragment`${use("type Option", "solanaOptions")}<${childManifest.strictType}>`
|
|
2810
|
+
});
|
|
2234
2811
|
},
|
|
2235
2812
|
visitPostOffsetType(node, { self }) {
|
|
2236
|
-
const manifest =
|
|
2813
|
+
const manifest = visit8(node.type, self);
|
|
2237
2814
|
if (node.strategy === "padded") {
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2815
|
+
return typeManifest({
|
|
2816
|
+
...manifest,
|
|
2817
|
+
decoder: fragment`${use("padRightDecoder", "solanaCodecsCore")}(${manifest.decoder}, ${node.offset})`,
|
|
2818
|
+
encoder: fragment`${use("padRightEncoder", "solanaCodecsCore")}(${manifest.encoder}, ${node.offset})`
|
|
2819
|
+
});
|
|
2241
2820
|
}
|
|
2242
2821
|
const fn = (() => {
|
|
2243
2822
|
switch (node.strategy) {
|
|
@@ -2250,16 +2829,20 @@ function getTypeManifestVisitor(input) {
|
|
|
2250
2829
|
return node.offset < 0 ? `({ postOffset }) => postOffset ${node.offset}` : `({ postOffset }) => postOffset + ${node.offset}`;
|
|
2251
2830
|
}
|
|
2252
2831
|
})();
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2832
|
+
return typeManifest({
|
|
2833
|
+
...manifest,
|
|
2834
|
+
decoder: fragment`${use("offsetDecoder", "solanaCodecsCore")}(${manifest.decoder}, { postOffset: ${fn} })`,
|
|
2835
|
+
encoder: fragment`${use("offsetEncoder", "solanaCodecsCore")}(${manifest.encoder}, { postOffset: ${fn} })`
|
|
2836
|
+
});
|
|
2256
2837
|
},
|
|
2257
2838
|
visitPreOffsetType(node, { self }) {
|
|
2258
|
-
const manifest =
|
|
2839
|
+
const manifest = visit8(node.type, self);
|
|
2259
2840
|
if (node.strategy === "padded") {
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2841
|
+
return typeManifest({
|
|
2842
|
+
...manifest,
|
|
2843
|
+
decoder: fragment`${use("padLeftDecoder", "solanaCodecsCore")}(${manifest.decoder}, ${node.offset})`,
|
|
2844
|
+
encoder: fragment`${use("padLeftEncoder", "solanaCodecsCore")}(${manifest.encoder}, ${node.offset})`
|
|
2845
|
+
});
|
|
2263
2846
|
}
|
|
2264
2847
|
const fn = (() => {
|
|
2265
2848
|
switch (node.strategy) {
|
|
@@ -2270,85 +2853,91 @@ function getTypeManifestVisitor(input) {
|
|
|
2270
2853
|
return node.offset < 0 ? `({ preOffset }) => preOffset ${node.offset}` : `({ preOffset }) => preOffset + ${node.offset}`;
|
|
2271
2854
|
}
|
|
2272
2855
|
})();
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2856
|
+
return typeManifest({
|
|
2857
|
+
...manifest,
|
|
2858
|
+
decoder: fragment`${use("offsetDecoder", "solanaCodecsCore")}(${manifest.decoder}, { preOffset: ${fn} })`,
|
|
2859
|
+
encoder: fragment`${use("offsetEncoder", "solanaCodecsCore")}(${manifest.encoder}, { preOffset: ${fn} })`
|
|
2860
|
+
});
|
|
2276
2861
|
},
|
|
2277
2862
|
visitPublicKeyType() {
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
|
|
2284
|
-
strictType: fragment("Address", imports),
|
|
2285
|
-
value: fragment("")
|
|
2286
|
-
};
|
|
2863
|
+
return typeManifest({
|
|
2864
|
+
decoder: fragment`${use("getAddressDecoder", "solanaAddresses")}()`,
|
|
2865
|
+
encoder: fragment`${use("getAddressEncoder", "solanaAddresses")}()`,
|
|
2866
|
+
looseType: use("type Address", "solanaAddresses"),
|
|
2867
|
+
strictType: use("type Address", "solanaAddresses")
|
|
2868
|
+
});
|
|
2287
2869
|
},
|
|
2288
2870
|
visitPublicKeyValue(node) {
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2871
|
+
return typeManifest({
|
|
2872
|
+
value: fragment`${use("address", "solanaAddresses")}("${node.publicKey}")`
|
|
2873
|
+
});
|
|
2292
2874
|
},
|
|
2293
2875
|
visitRemainderOptionType(node, { self }) {
|
|
2294
|
-
const childManifest =
|
|
2295
|
-
childManifest.strictType.mapRender((r) => `Option<${r}>`).addImports("solanaOptions", "type Option");
|
|
2296
|
-
childManifest.looseType.mapRender((r) => `OptionOrNullable<${r}>`).addImports("solanaOptions", "type OptionOrNullable");
|
|
2876
|
+
const childManifest = visit8(node.item, self);
|
|
2297
2877
|
const encoderOptions = ["prefix: null"];
|
|
2298
2878
|
const decoderOptions = ["prefix: null"];
|
|
2299
2879
|
const encoderOptionsAsString = encoderOptions.length > 0 ? `, { ${encoderOptions.join(", ")} }` : "";
|
|
2300
2880
|
const decoderOptionsAsString = decoderOptions.length > 0 ? `, { ${decoderOptions.join(", ")} }` : "";
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2881
|
+
return typeManifest({
|
|
2882
|
+
...childManifest,
|
|
2883
|
+
decoder: fragment`${use("getOptionDecoder", "solanaOptions")}(${childManifest.decoder}${decoderOptionsAsString})`,
|
|
2884
|
+
encoder: fragment`${use("getOptionEncoder", "solanaOptions")}(${childManifest.encoder}${encoderOptionsAsString})`,
|
|
2885
|
+
looseType: fragment`${use("type OptionOrNullable", "solanaOptions")}<${childManifest.looseType}>`,
|
|
2886
|
+
strictType: fragment`${use("type Option", "solanaOptions")}<${childManifest.strictType}>`
|
|
2887
|
+
});
|
|
2304
2888
|
},
|
|
2305
2889
|
visitSentinelType(node, { self }) {
|
|
2306
|
-
const manifest =
|
|
2307
|
-
const sentinel =
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2890
|
+
const manifest = visit8(node.type, self);
|
|
2891
|
+
const sentinel = visit8(node.sentinel, self).value;
|
|
2892
|
+
return typeManifest({
|
|
2893
|
+
...manifest,
|
|
2894
|
+
decoder: fragment`${use("addDecoderSentinel", "solanaCodecsCore")}(${manifest.decoder}, ${sentinel})`,
|
|
2895
|
+
encoder: fragment`${use("addEncoderSentinel", "solanaCodecsCore")}(${manifest.encoder}, ${sentinel})`
|
|
2896
|
+
});
|
|
2311
2897
|
},
|
|
2312
2898
|
visitSetType(setType, { self }) {
|
|
2313
|
-
const childManifest =
|
|
2314
|
-
childManifest.strictType.mapRender((r) => `Set<${r}>`);
|
|
2315
|
-
childManifest.looseType.mapRender((r) => `Set<${r}>`);
|
|
2899
|
+
const childManifest = visit8(setType.item, self);
|
|
2316
2900
|
const sizeManifest = getArrayLikeSizeOption(setType.count, self);
|
|
2317
|
-
const encoderOptions = sizeManifest.encoder
|
|
2318
|
-
const decoderOptions = sizeManifest.decoder
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2901
|
+
const encoderOptions = sizeManifest.encoder ? fragment`, { ${sizeManifest.encoder} }` : "";
|
|
2902
|
+
const decoderOptions = sizeManifest.decoder ? fragment`, { ${sizeManifest.decoder} }` : "";
|
|
2903
|
+
return typeManifest({
|
|
2904
|
+
...childManifest,
|
|
2905
|
+
decoder: fragment`${use("getSetDecoder", "solanaCodecsDataStructures")}(${childManifest.decoder}${decoderOptions})`,
|
|
2906
|
+
encoder: fragment`${use("getSetEncoder", "solanaCodecsDataStructures")}(${childManifest.encoder}${encoderOptions})`,
|
|
2907
|
+
looseType: fragment`Set<${childManifest.looseType}>`,
|
|
2908
|
+
strictType: fragment`Set<${childManifest.strictType}>`
|
|
2909
|
+
});
|
|
2322
2910
|
},
|
|
2323
2911
|
visitSetValue(node, { self }) {
|
|
2324
|
-
return
|
|
2325
|
-
node.items.map((v) =>
|
|
2912
|
+
return mergeTypeManifests(
|
|
2913
|
+
node.items.map((v) => visit8(v, self)),
|
|
2326
2914
|
{ mergeValues: (renders) => `new Set([${renders.join(", ")}])` }
|
|
2327
2915
|
);
|
|
2328
2916
|
},
|
|
2329
2917
|
visitSizePrefixType(node, { self }) {
|
|
2330
|
-
const manifest =
|
|
2331
|
-
const prefix =
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2918
|
+
const manifest = visit8(node.type, self);
|
|
2919
|
+
const prefix = visit8(node.prefix, self);
|
|
2920
|
+
return typeManifest({
|
|
2921
|
+
...manifest,
|
|
2922
|
+
decoder: fragment`${use("addDecoderSizePrefix", "solanaCodecsCore")}(${manifest.decoder}, ${prefix.decoder})`,
|
|
2923
|
+
encoder: fragment`${use("addEncoderSizePrefix", "solanaCodecsCore")}(${manifest.encoder}, ${prefix.encoder})`
|
|
2924
|
+
});
|
|
2335
2925
|
},
|
|
2336
2926
|
visitSolAmountType({ number }, { self }) {
|
|
2337
|
-
const numberManifest =
|
|
2338
|
-
|
|
2339
|
-
const lamportsImport = new ImportMap().add("solanaRpcTypes", "type Lamports");
|
|
2340
|
-
return {
|
|
2927
|
+
const numberManifest = visit8(number, self);
|
|
2928
|
+
return typeManifest({
|
|
2341
2929
|
...numberManifest,
|
|
2342
|
-
decoder:
|
|
2343
|
-
encoder:
|
|
2344
|
-
looseType:
|
|
2345
|
-
strictType:
|
|
2346
|
-
};
|
|
2930
|
+
decoder: fragment`${use("getLamportsDecoder", "solanaRpcTypes")}(${numberManifest.decoder})`,
|
|
2931
|
+
encoder: fragment`${use("getLamportsEncoder", "solanaRpcTypes")}(${numberManifest.encoder})`,
|
|
2932
|
+
looseType: use("type Lamports", "solanaRpcTypes"),
|
|
2933
|
+
strictType: use("type Lamports", "solanaRpcTypes")
|
|
2934
|
+
});
|
|
2347
2935
|
},
|
|
2348
2936
|
visitSomeValue(node, { self }) {
|
|
2349
|
-
const
|
|
2350
|
-
|
|
2351
|
-
|
|
2937
|
+
const innerValue = visit8(node.value, self).value;
|
|
2938
|
+
return typeManifest({
|
|
2939
|
+
value: fragment`${use("some", "solanaOptions")}(${innerValue})`
|
|
2940
|
+
});
|
|
2352
2941
|
},
|
|
2353
2942
|
visitStringType(stringType) {
|
|
2354
2943
|
const [encoder, decoder] = (() => {
|
|
@@ -2365,57 +2954,63 @@ function getTypeManifestVisitor(input) {
|
|
|
2365
2954
|
throw new Error(`Unsupported string encoding: ${stringType.encoding}`);
|
|
2366
2955
|
}
|
|
2367
2956
|
})();
|
|
2368
|
-
return {
|
|
2369
|
-
decoder: fragment
|
|
2370
|
-
encoder: fragment
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
value: fragment("")
|
|
2375
|
-
};
|
|
2957
|
+
return typeManifest({
|
|
2958
|
+
decoder: fragment`${use(decoder, "solanaCodecsStrings")}()`,
|
|
2959
|
+
encoder: fragment`${use(encoder, "solanaCodecsStrings")}()`,
|
|
2960
|
+
looseType: fragment`string`,
|
|
2961
|
+
strictType: fragment`string`
|
|
2962
|
+
});
|
|
2376
2963
|
},
|
|
2377
2964
|
visitStringValue(node) {
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2965
|
+
return typeManifest({
|
|
2966
|
+
value: fragment`${JSON.stringify(node.string)}`
|
|
2967
|
+
});
|
|
2381
2968
|
},
|
|
2382
2969
|
visitStructFieldType(structFieldType, { self }) {
|
|
2383
|
-
const name =
|
|
2384
|
-
const
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2970
|
+
const name = camelCase13(structFieldType.name);
|
|
2971
|
+
const originalChildManifest = visit8(structFieldType.type, self);
|
|
2972
|
+
let docs = getDocblockFragment(structFieldType.docs ?? [], true);
|
|
2973
|
+
docs = docs ? fragment`\n${docs}` : docs;
|
|
2974
|
+
const childManifest = typeManifest({
|
|
2975
|
+
...originalChildManifest,
|
|
2976
|
+
decoder: fragment`['${name}', ${originalChildManifest.decoder}]`,
|
|
2977
|
+
encoder: fragment`['${name}', ${originalChildManifest.encoder}]`,
|
|
2978
|
+
looseType: fragment`${docs}${name}: ${originalChildManifest.looseType}; `,
|
|
2979
|
+
strictType: fragment`${docs}${name}: ${originalChildManifest.strictType}; `
|
|
2980
|
+
});
|
|
2393
2981
|
if (!structFieldType.defaultValue) {
|
|
2394
2982
|
return childManifest;
|
|
2395
2983
|
}
|
|
2396
2984
|
if (structFieldType.defaultValueStrategy !== "omitted") {
|
|
2397
|
-
|
|
2398
|
-
|
|
2985
|
+
return typeManifest({
|
|
2986
|
+
...childManifest,
|
|
2987
|
+
looseType: fragment`${docs}${name}?: ${originalChildManifest.looseType}; `
|
|
2988
|
+
});
|
|
2399
2989
|
}
|
|
2400
|
-
childManifest
|
|
2401
|
-
return childManifest;
|
|
2990
|
+
return typeManifest({ ...childManifest, looseType: fragment`` });
|
|
2402
2991
|
},
|
|
2403
2992
|
visitStructFieldValue(node, { self }) {
|
|
2404
|
-
const
|
|
2405
|
-
|
|
2406
|
-
|
|
2993
|
+
const innerValue = visit8(node.value, self).value;
|
|
2994
|
+
return typeManifest({
|
|
2995
|
+
value: fragment`${node.name}: ${innerValue}`
|
|
2996
|
+
});
|
|
2407
2997
|
},
|
|
2408
2998
|
visitStructType(structType, { self }) {
|
|
2409
2999
|
const optionalFields = structType.fields.filter((f) => !!f.defaultValue);
|
|
2410
|
-
const mergedManifest =
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
3000
|
+
const mergedManifest = pipe15(
|
|
3001
|
+
mergeTypeManifests(
|
|
3002
|
+
structType.fields.map((field) => visit8(field, self)),
|
|
3003
|
+
{
|
|
3004
|
+
mergeCodecs: (renders) => `([${renders.join(", ")}])`,
|
|
3005
|
+
mergeTypes: (renders) => `{ ${renders.join("")} }`
|
|
3006
|
+
}
|
|
3007
|
+
),
|
|
3008
|
+
(manifest) => typeManifest({
|
|
3009
|
+
...manifest,
|
|
3010
|
+
decoder: fragment`${use("getStructDecoder", "solanaCodecsDataStructures")}${manifest.decoder}`,
|
|
3011
|
+
encoder: fragment`${use("getStructEncoder", "solanaCodecsDataStructures")}${manifest.encoder}`
|
|
3012
|
+
})
|
|
2416
3013
|
);
|
|
2417
|
-
mergedManifest.encoder.mapRender((r) => `getStructEncoder${r}`).addImports("solanaCodecsDataStructures", "getStructEncoder");
|
|
2418
|
-
mergedManifest.decoder.mapRender((r) => `getStructDecoder${r}`).addImports("solanaCodecsDataStructures", "getStructDecoder");
|
|
2419
3014
|
if (optionalFields.length === 0) {
|
|
2420
3015
|
return mergedManifest;
|
|
2421
3016
|
}
|
|
@@ -2425,63 +3020,75 @@ ${jsDocblock(structFieldDocs)}` : "";
|
|
|
2425
3020
|
const discriminatorPrefix = instructionNode ? instructionNode.name : accountNode?.name;
|
|
2426
3021
|
const discriminators = (instructionNode ? instructionNode.discriminators : accountNode?.discriminators) ?? [];
|
|
2427
3022
|
const fieldDiscriminators = discriminators.filter(isNodeFilter6("fieldDiscriminatorNode"));
|
|
2428
|
-
const defaultValues =
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
3023
|
+
const defaultValues = mergeFragments(
|
|
3024
|
+
optionalFields.map((f) => {
|
|
3025
|
+
const key = camelCase13(f.name);
|
|
3026
|
+
if (fieldDiscriminators.some((d) => d.name === f.name)) {
|
|
3027
|
+
const constantName = nameApi.constant(camelCase13(`${discriminatorPrefix}_${f.name}`));
|
|
3028
|
+
return f.defaultValueStrategy === "omitted" ? fragment`${key}: ${constantName}` : fragment`${key}: value.${key} ?? ${constantName}`;
|
|
3029
|
+
}
|
|
3030
|
+
const defaultValue = f.defaultValue;
|
|
3031
|
+
const value = visit8(defaultValue, self).value;
|
|
3032
|
+
return f.defaultValueStrategy === "omitted" ? fragment`${key}: ${value}` : fragment`${key}: value.${key} ?? ${value}`;
|
|
3033
|
+
}),
|
|
3034
|
+
(cs) => cs.join(", ")
|
|
3035
|
+
);
|
|
3036
|
+
return typeManifest({
|
|
3037
|
+
...mergedManifest,
|
|
3038
|
+
encoder: fragment`${use("transformEncoder", "solanaCodecsCore")}(${mergedManifest.encoder}, (value) => ({ ...value, ${defaultValues} }))`
|
|
3039
|
+
});
|
|
2441
3040
|
},
|
|
2442
3041
|
visitStructValue(node, { self }) {
|
|
2443
|
-
return
|
|
2444
|
-
node.fields.map((field) =>
|
|
3042
|
+
return mergeTypeManifests(
|
|
3043
|
+
node.fields.map((field) => visit8(field, self)),
|
|
2445
3044
|
{ mergeValues: (renders) => `{ ${renders.join(", ")} }` }
|
|
2446
3045
|
);
|
|
2447
3046
|
},
|
|
2448
3047
|
visitTupleType(tupleType, { self }) {
|
|
2449
|
-
const items = tupleType.items.map((item) =>
|
|
2450
|
-
const mergedManifest =
|
|
3048
|
+
const items = tupleType.items.map((item) => visit8(item, self));
|
|
3049
|
+
const mergedManifest = mergeTypeManifests(items, {
|
|
2451
3050
|
mergeCodecs: (codecs) => `[${codecs.join(", ")}]`,
|
|
2452
3051
|
mergeTypes: (types) => `readonly [${types.join(", ")}]`
|
|
2453
3052
|
});
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
3053
|
+
return typeManifest({
|
|
3054
|
+
...mergedManifest,
|
|
3055
|
+
decoder: fragment`${use("getTupleDecoder", "solanaCodecsDataStructures")}(${mergedManifest.decoder})`,
|
|
3056
|
+
encoder: fragment`${use("getTupleEncoder", "solanaCodecsDataStructures")}(${mergedManifest.encoder})`
|
|
3057
|
+
});
|
|
2457
3058
|
},
|
|
2458
3059
|
visitTupleValue(node, { self }) {
|
|
2459
|
-
return
|
|
2460
|
-
node.items.map((v) =>
|
|
3060
|
+
return mergeTypeManifests(
|
|
3061
|
+
node.items.map((v) => visit8(v, self)),
|
|
2461
3062
|
{ mergeValues: (renders) => `[${renders.join(", ")}]` }
|
|
2462
3063
|
);
|
|
2463
3064
|
},
|
|
2464
3065
|
visitZeroableOptionType(node, { self }) {
|
|
2465
|
-
const childManifest =
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
const encoderOptions = ["prefix: null"];
|
|
2469
|
-
const decoderOptions = ["prefix: null"];
|
|
3066
|
+
const childManifest = visit8(node.item, self);
|
|
3067
|
+
const encoderOptions = [fragment`prefix: null`];
|
|
3068
|
+
const decoderOptions = [fragment`prefix: null`];
|
|
2470
3069
|
if (node.zeroValue) {
|
|
2471
|
-
const zeroValueManifest =
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
encoderOptions.push(`noneValue: ${zeroValueManifest.value.render}`);
|
|
2475
|
-
decoderOptions.push(`noneValue: ${zeroValueManifest.value.render}`);
|
|
3070
|
+
const zeroValueManifest = visit8(node.zeroValue, self);
|
|
3071
|
+
encoderOptions.push(fragment`noneValue: ${zeroValueManifest.value}`);
|
|
3072
|
+
decoderOptions.push(fragment`noneValue: ${zeroValueManifest.value}`);
|
|
2476
3073
|
} else {
|
|
2477
|
-
encoderOptions.push(`noneValue: "zeroes"`);
|
|
2478
|
-
decoderOptions.push(`noneValue: "zeroes"`);
|
|
3074
|
+
encoderOptions.push(fragment`noneValue: "zeroes"`);
|
|
3075
|
+
decoderOptions.push(fragment`noneValue: "zeroes"`);
|
|
2479
3076
|
}
|
|
2480
|
-
const
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
3077
|
+
const encoderOptionsFragment = mergeFragments(
|
|
3078
|
+
encoderOptions,
|
|
3079
|
+
(cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
|
|
3080
|
+
);
|
|
3081
|
+
const decoderOptionsFragment = mergeFragments(
|
|
3082
|
+
decoderOptions,
|
|
3083
|
+
(cs) => cs.length > 0 ? `, { ${cs.join(", ")} }` : ""
|
|
3084
|
+
);
|
|
3085
|
+
return typeManifest({
|
|
3086
|
+
...childManifest,
|
|
3087
|
+
decoder: fragment`${use("getOptionDecoder", "solanaOptions")}(${childManifest.decoder}${decoderOptionsFragment})`,
|
|
3088
|
+
encoder: fragment`${use("getOptionEncoder", "solanaOptions")}(${childManifest.encoder}${encoderOptionsFragment})`,
|
|
3089
|
+
looseType: fragment`${use("type OptionOrNullable", "solanaOptions")}<${childManifest.looseType}>`,
|
|
3090
|
+
strictType: fragment`${use("type Option", "solanaOptions")}<${childManifest.strictType}>`
|
|
3091
|
+
});
|
|
2485
3092
|
}
|
|
2486
3093
|
}),
|
|
2487
3094
|
(visitor) => recordNodeStackVisitor(visitor, stack)
|
|
@@ -2490,290 +3097,99 @@ ${jsDocblock(structFieldDocs)}` : "";
|
|
|
2490
3097
|
function getArrayLikeSizeOption(count, visitor) {
|
|
2491
3098
|
if (isNode15(count, "fixedCountNode")) {
|
|
2492
3099
|
return {
|
|
2493
|
-
decoder: fragment
|
|
2494
|
-
encoder: fragment
|
|
3100
|
+
decoder: fragment`size: ${count.value}`,
|
|
3101
|
+
encoder: fragment`size: ${count.value}`
|
|
2495
3102
|
};
|
|
2496
3103
|
}
|
|
2497
3104
|
if (isNode15(count, "remainderCountNode")) {
|
|
2498
3105
|
return {
|
|
2499
|
-
decoder: fragment
|
|
2500
|
-
encoder: fragment
|
|
3106
|
+
decoder: fragment`size: 'remainder'`,
|
|
3107
|
+
encoder: fragment`size: 'remainder'`
|
|
2501
3108
|
};
|
|
2502
3109
|
}
|
|
2503
|
-
const prefix =
|
|
3110
|
+
const prefix = resolveNestedTypeNode4(count.prefix);
|
|
2504
3111
|
if (prefix.format === "u32" && prefix.endian === "le") {
|
|
2505
|
-
return { decoder:
|
|
3112
|
+
return { decoder: void 0, encoder: void 0 };
|
|
2506
3113
|
}
|
|
2507
|
-
const prefixManifest =
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
}
|
|
2512
|
-
|
|
2513
|
-
// src/nameTransformers.ts
|
|
2514
|
-
import { camelCase as camelCase11, capitalize, kebabCase as kebabCase2, pascalCase as pascalCase7, snakeCase as snakeCase2, titleCase as titleCase2 } from "@codama/nodes";
|
|
2515
|
-
function getNameApi(transformers) {
|
|
2516
|
-
const helpers = {
|
|
2517
|
-
camelCase: camelCase11,
|
|
2518
|
-
capitalize,
|
|
2519
|
-
kebabCase: kebabCase2,
|
|
2520
|
-
pascalCase: pascalCase7,
|
|
2521
|
-
snakeCase: snakeCase2,
|
|
2522
|
-
titleCase: titleCase2
|
|
3114
|
+
const prefixManifest = visit8(count.prefix, visitor);
|
|
3115
|
+
return {
|
|
3116
|
+
decoder: pipe15(prefixManifest.decoder, (f) => mapFragmentContent11(f, (c) => `size: ${c}`)),
|
|
3117
|
+
encoder: pipe15(prefixManifest.encoder, (f) => mapFragmentContent11(f, (c) => `size: ${c}`))
|
|
2523
3118
|
};
|
|
2524
|
-
return Object.fromEntries(
|
|
2525
|
-
Object.entries(transformers).map(([key, transformer]) => [key, (name) => transformer(name, helpers)])
|
|
2526
|
-
);
|
|
2527
3119
|
}
|
|
2528
|
-
var DEFAULT_NAME_TRANSFORMERS = {
|
|
2529
|
-
accountDecodeFunction: (name) => `decode${pascalCase7(name)}`,
|
|
2530
|
-
accountFetchAllFunction: (name) => `fetchAll${pascalCase7(name)}`,
|
|
2531
|
-
accountFetchAllMaybeFunction: (name) => `fetchAllMaybe${pascalCase7(name)}`,
|
|
2532
|
-
accountFetchFromSeedsFunction: (name) => `fetch${pascalCase7(name)}FromSeeds`,
|
|
2533
|
-
accountFetchFunction: (name) => `fetch${pascalCase7(name)}`,
|
|
2534
|
-
accountFetchMaybeFromSeedsFunction: (name) => `fetchMaybe${pascalCase7(name)}FromSeeds`,
|
|
2535
|
-
accountFetchMaybeFunction: (name) => `fetchMaybe${pascalCase7(name)}`,
|
|
2536
|
-
accountGetSizeFunction: (name) => `get${pascalCase7(name)}Size`,
|
|
2537
|
-
codecFunction: (name) => `get${pascalCase7(name)}Codec`,
|
|
2538
|
-
constant: (name) => snakeCase2(name).toUpperCase(),
|
|
2539
|
-
constantFunction: (name) => `get${pascalCase7(name)}Bytes`,
|
|
2540
|
-
dataArgsType: (name) => `${pascalCase7(name)}Args`,
|
|
2541
|
-
dataType: (name) => `${pascalCase7(name)}`,
|
|
2542
|
-
decoderFunction: (name) => `get${pascalCase7(name)}Decoder`,
|
|
2543
|
-
discriminatedUnionDiscriminator: () => "__kind",
|
|
2544
|
-
discriminatedUnionFunction: (name) => `${camelCase11(name)}`,
|
|
2545
|
-
discriminatedUnionVariant: (name) => `${pascalCase7(name)}`,
|
|
2546
|
-
encoderFunction: (name) => `get${pascalCase7(name)}Encoder`,
|
|
2547
|
-
enumVariant: (name) => `${pascalCase7(name)}`,
|
|
2548
|
-
instructionAsyncFunction: (name) => `get${pascalCase7(name)}InstructionAsync`,
|
|
2549
|
-
instructionAsyncInputType: (name) => `${pascalCase7(name)}AsyncInput`,
|
|
2550
|
-
instructionDataType: (name) => `${pascalCase7(name)}InstructionData`,
|
|
2551
|
-
instructionExtraType: (name) => `${pascalCase7(name)}InstructionExtra`,
|
|
2552
|
-
instructionParseFunction: (name) => `parse${pascalCase7(name)}Instruction`,
|
|
2553
|
-
instructionParsedType: (name) => `Parsed${pascalCase7(name)}Instruction`,
|
|
2554
|
-
instructionSyncFunction: (name) => `get${pascalCase7(name)}Instruction`,
|
|
2555
|
-
instructionSyncInputType: (name) => `${pascalCase7(name)}Input`,
|
|
2556
|
-
instructionType: (name) => `${pascalCase7(name)}Instruction`,
|
|
2557
|
-
isDiscriminatedUnionFunction: (name) => `is${pascalCase7(name)}`,
|
|
2558
|
-
pdaFindFunction: (name) => `find${pascalCase7(name)}Pda`,
|
|
2559
|
-
pdaSeedsType: (name) => `${pascalCase7(name)}Seeds`,
|
|
2560
|
-
programAccountsEnum: (name) => `${pascalCase7(name)}Account`,
|
|
2561
|
-
programAccountsEnumVariant: (name) => `${pascalCase7(name)}`,
|
|
2562
|
-
programAccountsIdentifierFunction: (name) => `identify${pascalCase7(name)}Account`,
|
|
2563
|
-
programAddressConstant: (name) => `${snakeCase2(name).toUpperCase()}_PROGRAM_ADDRESS`,
|
|
2564
|
-
programErrorConstant: (name) => snakeCase2(name).toUpperCase(),
|
|
2565
|
-
programErrorConstantPrefix: (name) => `${snakeCase2(name).toUpperCase()}_ERROR__`,
|
|
2566
|
-
programErrorMessagesMap: (name) => `${camelCase11(name)}ErrorMessages`,
|
|
2567
|
-
programErrorUnion: (name) => `${pascalCase7(name)}Error`,
|
|
2568
|
-
programGetErrorMessageFunction: (name) => `get${pascalCase7(name)}ErrorMessage`,
|
|
2569
|
-
programInstructionsEnum: (name) => `${pascalCase7(name)}Instruction`,
|
|
2570
|
-
programInstructionsEnumVariant: (name) => `${pascalCase7(name)}`,
|
|
2571
|
-
programInstructionsIdentifierFunction: (name) => `identify${pascalCase7(name)}Instruction`,
|
|
2572
|
-
programInstructionsParsedUnionType: (name) => `Parsed${pascalCase7(name)}Instruction`,
|
|
2573
|
-
programIsErrorFunction: (name) => `is${pascalCase7(name)}Error`,
|
|
2574
|
-
resolverFunction: (name) => `${camelCase11(name)}`
|
|
2575
|
-
};
|
|
2576
3120
|
|
|
2577
|
-
// src/getRenderMapVisitor.ts
|
|
3121
|
+
// src/visitors/getRenderMapVisitor.ts
|
|
2578
3122
|
function getRenderMapVisitor(options = {}) {
|
|
2579
3123
|
const linkables = new LinkableDictionary3();
|
|
2580
3124
|
const stack = new NodeStack2();
|
|
2581
|
-
const nameTransformers = {
|
|
2582
|
-
...DEFAULT_NAME_TRANSFORMERS,
|
|
2583
|
-
...options.nameTransformers
|
|
2584
|
-
};
|
|
2585
|
-
const nameApi = getNameApi(nameTransformers);
|
|
2586
|
-
const renderParentInstructions = options.renderParentInstructions ?? false;
|
|
2587
|
-
const dependencyMap = options.dependencyMap ?? {};
|
|
2588
|
-
const useGranularImports = options.useGranularImports ?? false;
|
|
2589
|
-
const asyncResolvers = (options.asyncResolvers ?? []).map(camelCase12);
|
|
2590
|
-
const nonScalarEnums = (options.nonScalarEnums ?? []).map(camelCase12);
|
|
2591
|
-
const internalNodes = (options.internalNodes ?? []).map(camelCase12);
|
|
2592
3125
|
const customAccountData = parseCustomDataOptions(options.customAccountData ?? [], "AccountData");
|
|
2593
3126
|
const customInstructionData = parseCustomDataOptions(options.customInstructionData ?? [], "InstructionData");
|
|
2594
|
-
const
|
|
2595
|
-
|
|
3127
|
+
const renderScopeWithTypeManifestVisitor = {
|
|
3128
|
+
asyncResolvers: (options.asyncResolvers ?? []).map(camelCase14),
|
|
2596
3129
|
customAccountData,
|
|
2597
3130
|
customInstructionData,
|
|
2598
|
-
|
|
3131
|
+
dependencyMap: options.dependencyMap ?? {},
|
|
3132
|
+
getImportFrom: getImportFromFactory(options.linkOverrides ?? {}, customAccountData, customInstructionData),
|
|
2599
3133
|
linkables,
|
|
2600
|
-
nameApi,
|
|
2601
|
-
nonScalarEnums,
|
|
2602
|
-
|
|
2603
|
-
|
|
3134
|
+
nameApi: getNameApi({ ...DEFAULT_NAME_TRANSFORMERS, ...options.nameTransformers }),
|
|
3135
|
+
nonScalarEnums: (options.nonScalarEnums ?? []).map(camelCase14),
|
|
3136
|
+
renderParentInstructions: options.renderParentInstructions ?? false,
|
|
3137
|
+
useGranularImports: options.useGranularImports ?? false
|
|
3138
|
+
};
|
|
3139
|
+
const typeManifestVisitor = getTypeManifestVisitor({ ...renderScopeWithTypeManifestVisitor, stack });
|
|
3140
|
+
const renderScope = { ...renderScopeWithTypeManifestVisitor, typeManifestVisitor };
|
|
3141
|
+
const internalNodes = (options.internalNodes ?? []).map(camelCase14);
|
|
2604
3142
|
const resolvedInstructionInputVisitor = getResolvedInstructionInputsVisitor();
|
|
2605
3143
|
const byteSizeVisitor = getByteSizeVisitor(linkables, { stack });
|
|
2606
|
-
const
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
nameApi,
|
|
2613
|
-
nonScalarEnums,
|
|
2614
|
-
renderParentInstructions,
|
|
2615
|
-
typeManifestVisitor
|
|
2616
|
-
};
|
|
2617
|
-
const render2 = (template, context, renderOptions) => {
|
|
2618
|
-
return render(join3("pages", template), context, renderOptions);
|
|
3144
|
+
const asPage = (fragment2, dependencyMap = {}) => {
|
|
3145
|
+
if (!fragment2) return void 0;
|
|
3146
|
+
return getPageFragment(fragment2, {
|
|
3147
|
+
...renderScope,
|
|
3148
|
+
dependencyMap: { ...renderScope.dependencyMap, ...dependencyMap }
|
|
3149
|
+
});
|
|
2619
3150
|
};
|
|
2620
|
-
return
|
|
2621
|
-
staticVisitor2(() =>
|
|
3151
|
+
return pipe16(
|
|
3152
|
+
staticVisitor2(() => createRenderMap(), {
|
|
2622
3153
|
keys: ["rootNode", "programNode", "pdaNode", "accountNode", "definedTypeNode", "instructionNode"]
|
|
2623
3154
|
}),
|
|
2624
3155
|
(v) => extendVisitor2(v, {
|
|
2625
3156
|
visitAccount(node) {
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
};
|
|
2636
|
-
const fields = resolveNestedTypeNode4(node.data).fields;
|
|
2637
|
-
const accountDiscriminatorConstantsFragment = getDiscriminatorConstantsFragment({
|
|
2638
|
-
...scope,
|
|
2639
|
-
discriminatorNodes: node.discriminators ?? [],
|
|
2640
|
-
fields,
|
|
2641
|
-
prefix: node.name
|
|
2642
|
-
});
|
|
2643
|
-
const accountTypeFragment = getAccountTypeFragment(scope);
|
|
2644
|
-
const accountFetchHelpersFragment = getAccountFetchHelpersFragment(scope);
|
|
2645
|
-
const accountSizeHelpersFragment = getAccountSizeHelpersFragment(scope);
|
|
2646
|
-
const accountPdaHelpersFragment = getAccountPdaHelpersFragment(scope);
|
|
2647
|
-
const imports = new ImportMap().mergeWith(
|
|
2648
|
-
accountDiscriminatorConstantsFragment,
|
|
2649
|
-
accountTypeFragment,
|
|
2650
|
-
accountFetchHelpersFragment,
|
|
2651
|
-
accountSizeHelpersFragment,
|
|
2652
|
-
accountPdaHelpersFragment
|
|
2653
|
-
);
|
|
2654
|
-
return new RenderMap().add(
|
|
2655
|
-
`accounts/${camelCase12(node.name)}.ts`,
|
|
2656
|
-
render2("accountsPage.njk", {
|
|
2657
|
-
accountDiscriminatorConstantsFragment,
|
|
2658
|
-
accountFetchHelpersFragment,
|
|
2659
|
-
accountPdaHelpersFragment,
|
|
2660
|
-
accountSizeHelpersFragment,
|
|
2661
|
-
accountTypeFragment,
|
|
2662
|
-
imports: imports.toString(dependencyMap, useGranularImports)
|
|
2663
|
-
})
|
|
3157
|
+
return createRenderMap(
|
|
3158
|
+
`accounts/${camelCase14(node.name)}.ts`,
|
|
3159
|
+
asPage(
|
|
3160
|
+
getAccountPageFragment({
|
|
3161
|
+
...renderScope,
|
|
3162
|
+
accountPath: stack.getPath("accountNode"),
|
|
3163
|
+
size: visit9(node, byteSizeVisitor)
|
|
3164
|
+
})
|
|
3165
|
+
)
|
|
2664
3166
|
);
|
|
2665
3167
|
},
|
|
2666
3168
|
visitDefinedType(node) {
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
encoderDocs: [],
|
|
2672
|
-
manifest: visit6(node, typeManifestVisitor),
|
|
2673
|
-
name: node.name,
|
|
2674
|
-
node: node.type,
|
|
2675
|
-
size: visit6(node, byteSizeVisitor),
|
|
2676
|
-
typeDocs: node.docs,
|
|
2677
|
-
typeNode: node.type
|
|
2678
|
-
};
|
|
2679
|
-
const typeWithCodecFragment = getTypeWithCodecFragment(scope);
|
|
2680
|
-
const typeDiscriminatedUnionHelpersFragment = getTypeDiscriminatedUnionHelpersFragment(scope);
|
|
2681
|
-
const imports = new ImportMap().mergeWith(typeWithCodecFragment, typeDiscriminatedUnionHelpersFragment).remove("generatedTypes", [
|
|
2682
|
-
nameApi.dataType(node.name),
|
|
2683
|
-
nameApi.dataArgsType(node.name),
|
|
2684
|
-
nameApi.encoderFunction(node.name),
|
|
2685
|
-
nameApi.decoderFunction(node.name),
|
|
2686
|
-
nameApi.codecFunction(node.name)
|
|
2687
|
-
]);
|
|
2688
|
-
return new RenderMap().add(
|
|
2689
|
-
`types/${camelCase12(node.name)}.ts`,
|
|
2690
|
-
render2("definedTypesPage.njk", {
|
|
2691
|
-
imports: imports.toString({
|
|
2692
|
-
...dependencyMap,
|
|
2693
|
-
generatedTypes: "."
|
|
2694
|
-
}),
|
|
2695
|
-
typeDiscriminatedUnionHelpersFragment,
|
|
2696
|
-
typeWithCodecFragment
|
|
3169
|
+
return createRenderMap(
|
|
3170
|
+
`types/${camelCase14(node.name)}.ts`,
|
|
3171
|
+
asPage(getTypePageFragment({ ...renderScope, node, size: visit9(node, byteSizeVisitor) }), {
|
|
3172
|
+
generatedTypes: "."
|
|
2697
3173
|
})
|
|
2698
3174
|
);
|
|
2699
3175
|
},
|
|
2700
3176
|
visitInstruction(node) {
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
name: instructionExtraName,
|
|
2712
|
-
type: structTypeNodeFromInstructionArgumentNodes5(node.extraArguments ?? [])
|
|
2713
|
-
}),
|
|
2714
|
-
typeManifestVisitor
|
|
2715
|
-
),
|
|
2716
|
-
instructionPath,
|
|
2717
|
-
renamedArgs: getRenamedArgsMap(node),
|
|
2718
|
-
resolvedInputs: visit6(node, resolvedInstructionInputVisitor),
|
|
2719
|
-
size: visit6(node, byteSizeVisitor)
|
|
2720
|
-
};
|
|
2721
|
-
const instructionDiscriminatorConstantsFragment = getDiscriminatorConstantsFragment({
|
|
2722
|
-
...scope,
|
|
2723
|
-
discriminatorNodes: node.discriminators ?? [],
|
|
2724
|
-
fields: node.arguments,
|
|
2725
|
-
prefix: node.name
|
|
2726
|
-
});
|
|
2727
|
-
const instructionTypeFragment = getInstructionTypeFragment(scope);
|
|
2728
|
-
const instructionDataFragment = getInstructionDataFragment(scope);
|
|
2729
|
-
const instructionExtraArgsFragment = getInstructionExtraArgsFragment(scope);
|
|
2730
|
-
const instructionFunctionAsyncFragment = getInstructionFunctionFragment({
|
|
2731
|
-
...scope,
|
|
2732
|
-
useAsync: true
|
|
2733
|
-
});
|
|
2734
|
-
const instructionFunctionSyncFragment = getInstructionFunctionFragment({
|
|
2735
|
-
...scope,
|
|
2736
|
-
useAsync: false
|
|
2737
|
-
});
|
|
2738
|
-
const instructionParseFunctionFragment = getInstructionParseFunctionFragment(scope);
|
|
2739
|
-
const imports = new ImportMap().mergeWith(
|
|
2740
|
-
instructionDiscriminatorConstantsFragment,
|
|
2741
|
-
instructionTypeFragment,
|
|
2742
|
-
instructionDataFragment,
|
|
2743
|
-
instructionExtraArgsFragment,
|
|
2744
|
-
instructionFunctionAsyncFragment,
|
|
2745
|
-
instructionFunctionSyncFragment,
|
|
2746
|
-
instructionParseFunctionFragment
|
|
2747
|
-
);
|
|
2748
|
-
return new RenderMap().add(
|
|
2749
|
-
`instructions/${camelCase12(node.name)}.ts`,
|
|
2750
|
-
render2("instructionsPage.njk", {
|
|
2751
|
-
imports: imports.toString(dependencyMap, useGranularImports),
|
|
2752
|
-
instruction: node,
|
|
2753
|
-
instructionDataFragment,
|
|
2754
|
-
instructionDiscriminatorConstantsFragment,
|
|
2755
|
-
instructionExtraArgsFragment,
|
|
2756
|
-
instructionFunctionAsyncFragment,
|
|
2757
|
-
instructionFunctionSyncFragment,
|
|
2758
|
-
instructionParseFunctionFragment,
|
|
2759
|
-
instructionTypeFragment
|
|
2760
|
-
})
|
|
3177
|
+
return createRenderMap(
|
|
3178
|
+
`instructions/${camelCase14(node.name)}.ts`,
|
|
3179
|
+
asPage(
|
|
3180
|
+
getInstructionPageFragment({
|
|
3181
|
+
...renderScope,
|
|
3182
|
+
instructionPath: stack.getPath("instructionNode"),
|
|
3183
|
+
resolvedInputs: visit9(node, resolvedInstructionInputVisitor),
|
|
3184
|
+
size: visit9(node, byteSizeVisitor)
|
|
3185
|
+
})
|
|
3186
|
+
)
|
|
2761
3187
|
);
|
|
2762
3188
|
},
|
|
2763
3189
|
visitPda(node) {
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
}
|
|
2768
|
-
const scope = { ...globalScope, pdaPath };
|
|
2769
|
-
const pdaFunctionFragment = getPdaFunctionFragment(scope);
|
|
2770
|
-
const imports = new ImportMap().mergeWith(pdaFunctionFragment);
|
|
2771
|
-
return new RenderMap().add(
|
|
2772
|
-
`pdas/${camelCase12(node.name)}.ts`,
|
|
2773
|
-
render2("pdasPage.njk", {
|
|
2774
|
-
imports: imports.toString(dependencyMap, useGranularImports),
|
|
2775
|
-
pdaFunctionFragment
|
|
2776
|
-
})
|
|
3190
|
+
return createRenderMap(
|
|
3191
|
+
`pdas/${camelCase14(node.name)}.ts`,
|
|
3192
|
+
asPage(getPdaPageFragment({ ...renderScope, pdaPath: stack.getPath("pdaNode") }))
|
|
2777
3193
|
);
|
|
2778
3194
|
},
|
|
2779
3195
|
visitProgram(node, { self }) {
|
|
@@ -2781,36 +3197,20 @@ function getRenderMapVisitor(options = {}) {
|
|
|
2781
3197
|
...getDefinedTypeNodesToExtract(node.accounts, customAccountData),
|
|
2782
3198
|
...getDefinedTypeNodesToExtract(node.instructions, customInstructionData)
|
|
2783
3199
|
];
|
|
2784
|
-
const scope = { ...
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
)
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
const programInstructionsFragment = getProgramInstructionsFragment(scope);
|
|
2799
|
-
renderMap.add(
|
|
2800
|
-
`programs/${camelCase12(node.name)}.ts`,
|
|
2801
|
-
render2("programsPage.njk", {
|
|
2802
|
-
imports: new ImportMap().mergeWith(programFragment, programAccountsFragment, programInstructionsFragment).toString(dependencyMap, useGranularImports),
|
|
2803
|
-
programAccountsFragment,
|
|
2804
|
-
programFragment,
|
|
2805
|
-
programInstructionsFragment
|
|
2806
|
-
})
|
|
2807
|
-
);
|
|
2808
|
-
renderMap.mergeWith(
|
|
2809
|
-
...getAllInstructionsWithSubs2(node, {
|
|
2810
|
-
leavesOnly: !renderParentInstructions
|
|
2811
|
-
}).map((ix) => visit6(ix, self))
|
|
2812
|
-
);
|
|
2813
|
-
return renderMap;
|
|
3200
|
+
const scope = { ...renderScope, programNode: node };
|
|
3201
|
+
return mergeRenderMaps([
|
|
3202
|
+
createRenderMap({
|
|
3203
|
+
[`programs/${camelCase14(node.name)}.ts`]: asPage(getProgramPageFragment(scope)),
|
|
3204
|
+
[`errors/${camelCase14(node.name)}.ts`]: node.errors.length > 0 ? asPage(getErrorPageFragment(scope)) : void 0
|
|
3205
|
+
}),
|
|
3206
|
+
...node.pdas.map((p) => visit9(p, self)),
|
|
3207
|
+
...node.accounts.map((a) => visit9(a, self)),
|
|
3208
|
+
...node.definedTypes.map((t) => visit9(t, self)),
|
|
3209
|
+
...customDataDefinedType.map((t) => visit9(t, self)),
|
|
3210
|
+
...getAllInstructionsWithSubs2(node, { leavesOnly: !renderScope.renderParentInstructions }).map(
|
|
3211
|
+
(i) => visit9(i, self)
|
|
3212
|
+
)
|
|
3213
|
+
]);
|
|
2814
3214
|
},
|
|
2815
3215
|
visitRoot(node, { self }) {
|
|
2816
3216
|
const isNotInternal = (n) => !internalNodes.includes(n.name);
|
|
@@ -2819,88 +3219,41 @@ function getRenderMapVisitor(options = {}) {
|
|
|
2819
3219
|
const pdasToExport = getAllPdas(node);
|
|
2820
3220
|
const accountsToExport = getAllAccounts(node).filter(isNotInternal);
|
|
2821
3221
|
const instructionsToExport = getAllInstructionsWithSubs2(node, {
|
|
2822
|
-
leavesOnly: !renderParentInstructions
|
|
3222
|
+
leavesOnly: !renderScope.renderParentInstructions
|
|
2823
3223
|
}).filter(isNotInternal);
|
|
2824
3224
|
const definedTypesToExport = getAllDefinedTypes(node).filter(isNotInternal);
|
|
2825
3225
|
const hasAnythingToExport = programsToExport.length > 0 || accountsToExport.length > 0 || instructionsToExport.length > 0 || definedTypesToExport.length > 0;
|
|
2826
|
-
const
|
|
3226
|
+
const scope = {
|
|
3227
|
+
...renderScope,
|
|
2827
3228
|
accountsToExport,
|
|
2828
3229
|
definedTypesToExport,
|
|
2829
|
-
hasAnythingToExport,
|
|
2830
3230
|
instructionsToExport,
|
|
2831
3231
|
pdasToExport,
|
|
2832
|
-
programsToExport
|
|
2833
|
-
programsWithErrorsToExport,
|
|
2834
|
-
root: node
|
|
3232
|
+
programsToExport
|
|
2835
3233
|
};
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
"
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
"upgradeRoleToSigner"
|
|
2850
|
-
]).add("solanaSigners", [
|
|
2851
|
-
"type AccountSignerMeta",
|
|
2852
|
-
"isTransactionSigner",
|
|
2853
|
-
"type TransactionSigner"
|
|
2854
|
-
]).addAlias("solanaSigners", "isTransactionSigner", "kitIsTransactionSigner").toString(dependencyMap, useGranularImports)
|
|
2855
|
-
})
|
|
2856
|
-
);
|
|
2857
|
-
}
|
|
2858
|
-
if (programsToExport.length > 0) {
|
|
2859
|
-
map.add("programs/index.ts", render2("programsIndex.njk", ctx));
|
|
2860
|
-
}
|
|
2861
|
-
if (programsWithErrorsToExport.length > 0) {
|
|
2862
|
-
map.add("errors/index.ts", render2("errorsIndex.njk", ctx));
|
|
2863
|
-
}
|
|
2864
|
-
if (accountsToExport.length > 0) {
|
|
2865
|
-
map.add("accounts/index.ts", render2("accountsIndex.njk", ctx));
|
|
2866
|
-
}
|
|
2867
|
-
if (pdasToExport.length > 0) {
|
|
2868
|
-
map.add("pdas/index.ts", render2("pdasIndex.njk", ctx));
|
|
2869
|
-
}
|
|
2870
|
-
if (instructionsToExport.length > 0) {
|
|
2871
|
-
map.add("instructions/index.ts", render2("instructionsIndex.njk", ctx));
|
|
2872
|
-
}
|
|
2873
|
-
if (definedTypesToExport.length > 0) {
|
|
2874
|
-
map.add("types/index.ts", render2("definedTypesIndex.njk", ctx));
|
|
2875
|
-
}
|
|
2876
|
-
return map.add("index.ts", render2("rootIndex.njk", ctx)).mergeWith(...getAllPrograms(node).map((p) => visit6(p, self)));
|
|
3234
|
+
return mergeRenderMaps([
|
|
3235
|
+
createRenderMap({
|
|
3236
|
+
["accounts/index.ts"]: asPage(getIndexPageFragment(accountsToExport)),
|
|
3237
|
+
["errors/index.ts"]: asPage(getIndexPageFragment(programsWithErrorsToExport)),
|
|
3238
|
+
["index.ts"]: asPage(getRootIndexPageFragment(scope)),
|
|
3239
|
+
["instructions/index.ts"]: asPage(getIndexPageFragment(instructionsToExport)),
|
|
3240
|
+
["pdas/index.ts"]: asPage(getIndexPageFragment(pdasToExport)),
|
|
3241
|
+
["programs/index.ts"]: asPage(getIndexPageFragment(programsToExport)),
|
|
3242
|
+
["shared/index.ts"]: hasAnythingToExport ? asPage(getSharedPageFragment()) : void 0,
|
|
3243
|
+
["types/index.ts"]: asPage(getIndexPageFragment(definedTypesToExport))
|
|
3244
|
+
}),
|
|
3245
|
+
...getAllPrograms(node).map((p) => visit9(p, self))
|
|
3246
|
+
]);
|
|
2877
3247
|
}
|
|
2878
3248
|
}),
|
|
2879
3249
|
(v) => recordNodeStackVisitor2(v, stack),
|
|
2880
3250
|
(v) => recordLinkablesOnFirstVisitVisitor(v, linkables)
|
|
2881
3251
|
);
|
|
2882
3252
|
}
|
|
2883
|
-
function getRenamedArgsMap(instruction) {
|
|
2884
|
-
const argNames = [
|
|
2885
|
-
...instruction.arguments.map((a) => a.name),
|
|
2886
|
-
...(instruction.extraArguments ?? []).map((a) => a.name)
|
|
2887
|
-
];
|
|
2888
|
-
const duplicateArgs = argNames.filter((e, i, a) => a.indexOf(e) !== i);
|
|
2889
|
-
if (duplicateArgs.length > 0) {
|
|
2890
|
-
throw new Error(`Duplicate args found: [${duplicateArgs.join(", ")}] in instruction [${instruction.name}].`);
|
|
2891
|
-
}
|
|
2892
|
-
const allNames = [...instruction.accounts.map((account) => account.name), ...argNames];
|
|
2893
|
-
const duplicates = allNames.filter((e, i, a) => a.indexOf(e) !== i);
|
|
2894
|
-
if (duplicates.length === 0) return /* @__PURE__ */ new Map();
|
|
2895
|
-
logWarn(
|
|
2896
|
-
`[JavaScript] Accounts and args of instruction [${instruction.name}] have the following conflicting attributes [${duplicates.join(", ")}]. Thus, the arguments have been renamed to avoid conflicts in the input type.`
|
|
2897
|
-
);
|
|
2898
|
-
return new Map(duplicates.map((name) => [camelCase12(name), camelCase12(`${name}Arg`)]));
|
|
2899
|
-
}
|
|
2900
3253
|
|
|
2901
|
-
// src/renderVisitor.ts
|
|
2902
|
-
import { deleteDirectory } from "@codama/renderers-core";
|
|
2903
|
-
import { rootNodeVisitor, visit as
|
|
3254
|
+
// src/visitors/renderVisitor.ts
|
|
3255
|
+
import { deleteDirectory, mapRenderMapContentAsync, writeRenderMap } from "@codama/renderers-core";
|
|
3256
|
+
import { rootNodeVisitor, visit as visit10 } from "@codama/visitors-core";
|
|
2904
3257
|
import * as estreePlugin from "prettier/plugins/estree";
|
|
2905
3258
|
import * as typeScriptPlugin from "prettier/plugins/typescript";
|
|
2906
3259
|
import { format } from "prettier/standalone";
|
|
@@ -2920,22 +3273,27 @@ function renderVisitor(path, options = {}) {
|
|
|
2920
3273
|
if (options.deleteFolderBeforeRendering ?? true) {
|
|
2921
3274
|
deleteDirectory(path);
|
|
2922
3275
|
}
|
|
2923
|
-
|
|
3276
|
+
let renderMap = visit10(root, getRenderMapVisitor(options));
|
|
2924
3277
|
if (options.formatCode ?? true) {
|
|
2925
3278
|
const prettierOptions = { ...DEFAULT_PRETTIER_OPTIONS, ...options.prettierOptions };
|
|
2926
|
-
await renderMap
|
|
3279
|
+
renderMap = await mapRenderMapContentAsync(renderMap, (code) => format(code, prettierOptions));
|
|
2927
3280
|
}
|
|
2928
|
-
renderMap
|
|
3281
|
+
writeRenderMap(renderMap, path);
|
|
2929
3282
|
});
|
|
2930
3283
|
}
|
|
2931
3284
|
export {
|
|
2932
3285
|
DEFAULT_NAME_TRANSFORMERS,
|
|
2933
|
-
|
|
3286
|
+
addToImportMap,
|
|
3287
|
+
createImportMap,
|
|
2934
3288
|
renderVisitor as default,
|
|
2935
3289
|
getNameApi,
|
|
2936
3290
|
getRenderMapVisitor,
|
|
2937
3291
|
getTypeManifestVisitor,
|
|
2938
|
-
|
|
3292
|
+
importMapToString,
|
|
3293
|
+
mergeImportMaps,
|
|
3294
|
+
mergeTypeManifests,
|
|
3295
|
+
parseImportInput,
|
|
3296
|
+
removeFromImportMap,
|
|
2939
3297
|
renderVisitor,
|
|
2940
3298
|
typeManifest
|
|
2941
3299
|
};
|