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