@codama/renderers-js 1.7.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -19
- package/dist/index.browser.cjs +565 -465
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.mjs +565 -465
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.node.cjs +565 -465
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +565 -465
- package/dist/index.node.mjs.map +1 -1
- package/dist/index.react-native.mjs +565 -465
- package/dist/index.react-native.mjs.map +1 -1
- package/dist/types/fragments/index.d.ts +1 -1
- package/dist/types/fragments/index.d.ts.map +1 -1
- package/dist/types/fragments/instructionInputDefault.d.ts.map +1 -1
- package/dist/types/fragments/instructionPage.d.ts +1 -0
- package/dist/types/fragments/instructionPage.d.ts.map +1 -1
- package/dist/types/fragments/programAccounts.d.ts.map +1 -1
- package/dist/types/fragments/programInstructions.d.ts.map +1 -1
- package/dist/types/fragments/programPage.d.ts +1 -1
- package/dist/types/fragments/programPage.d.ts.map +1 -1
- package/dist/types/fragments/programPlugin.d.ts +6 -0
- package/dist/types/fragments/programPlugin.d.ts.map +1 -0
- package/dist/types/utils/formatCode.d.ts +1 -1
- package/dist/types/utils/formatCode.d.ts.map +1 -1
- package/dist/types/utils/fragment.d.ts +1 -1
- package/dist/types/utils/fragment.d.ts.map +1 -1
- package/dist/types/utils/importMap.d.ts +3 -2
- package/dist/types/utils/importMap.d.ts.map +1 -1
- package/dist/types/utils/nameTransformers.d.ts +1 -1
- package/dist/types/utils/nameTransformers.d.ts.map +1 -1
- package/dist/types/utils/options.d.ts +28 -3
- package/dist/types/utils/options.d.ts.map +1 -1
- package/dist/types/utils/packageJson.d.ts +3 -3
- package/dist/types/utils/packageJson.d.ts.map +1 -1
- package/dist/types/visitors/getRenderMapVisitor.d.ts.map +1 -1
- package/dist/types/visitors/renderVisitor.d.ts +1 -1
- package/dist/types/visitors/renderVisitor.d.ts.map +1 -1
- package/package.json +1 -1
- package/dist/types/fragments/sharedPage.d.ts +0 -3
- package/dist/types/fragments/sharedPage.d.ts.map +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { camelCase, pascalCase, snakeCase, titleCase, kebabCase, capitalize, REGISTERED_TYPE_NODE_KINDS, REGISTERED_VALUE_NODE_KINDS, isNodeFilter, resolveNestedTypeNode, structTypeNodeFromInstructionArgumentNodes, isNode, isScalarEnum, structTypeNode, structFieldTypeNode, getAllPrograms, getAllPdas, getAllAccounts, getAllInstructionsWithSubs, getAllDefinedTypes, definedTypeLinkNode, definedTypeNode, isDataEnum, accountValueNode, argumentValueNode, parseOptionalAccountStrategy, VALUE_NODES, getAllInstructionArguments, constantDiscriminatorNode, constantValueNodeFromBytes, constantValueNode, assertIsNode } from '@codama/nodes';
|
|
2
|
-
import { setFragmentContent, mapFragmentContent, createRenderMap, mergeRenderMaps, deleteDirectory, mapRenderMapContentAsync, writeRenderMap, createFragmentTemplate, joinPath, fileExists, readJson, writeFile } from '@codama/renderers-core';
|
|
3
2
|
import { NodeStack, pipe, staticVisitor, extendVisitor, visit, findLastNodeFromPath, recordNodeStackVisitor, LinkableDictionary, getResolvedInstructionInputsVisitor, getByteSizeVisitor, recordLinkablesOnFirstVisitVisitor, rootNodeVisitor, findProgramNodeFromPath, getLastNodeFromPath, findInstructionNodeFromPath, deduplicateInstructionDependencies } from '@codama/visitors-core';
|
|
4
3
|
import { getBase64Encoder, getBase58Encoder, getBase16Encoder, getUtf8Encoder, getBase64Decoder } from '@solana/codecs-strings';
|
|
4
|
+
import { setFragmentContent, mapFragmentContent, createRenderMap, mergeRenderMaps, joinPath, deleteDirectory, mapRenderMapContentAsync, writeRenderMap, createFragmentTemplate, fileExists, readJson, writeFile } from '@codama/renderers-core';
|
|
5
5
|
import 'prettier';
|
|
6
6
|
import * as babelPlugin from 'prettier/plugins/babel';
|
|
7
7
|
import * as estreePlugin from 'prettier/plugins/estree';
|
|
@@ -10,270 +10,7 @@ import { format } from 'prettier/standalone';
|
|
|
10
10
|
import { CodamaError, CODAMA_ERROR__UNEXPECTED_NODE_KIND, logWarn, CODAMA_ERROR__RENDERERS__MISSING_DEPENDENCY_VERSIONS } from '@codama/errors';
|
|
11
11
|
import { subset, minVersion, lt } from 'semver';
|
|
12
12
|
|
|
13
|
-
// src/utils/
|
|
14
|
-
var DEFAULT_EXTERNAL_MODULE_MAP = {
|
|
15
|
-
solanaAccounts: "@solana/kit",
|
|
16
|
-
solanaAddresses: "@solana/kit",
|
|
17
|
-
solanaCodecsCore: "@solana/kit",
|
|
18
|
-
solanaCodecsDataStructures: "@solana/kit",
|
|
19
|
-
solanaCodecsNumbers: "@solana/kit",
|
|
20
|
-
solanaCodecsStrings: "@solana/kit",
|
|
21
|
-
solanaErrors: "@solana/kit",
|
|
22
|
-
solanaInstructions: "@solana/kit",
|
|
23
|
-
solanaOptions: "@solana/kit",
|
|
24
|
-
solanaPrograms: "@solana/kit",
|
|
25
|
-
solanaRpcTypes: "@solana/kit",
|
|
26
|
-
solanaSigners: "@solana/kit"
|
|
27
|
-
};
|
|
28
|
-
var DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP = {
|
|
29
|
-
solanaAccounts: "@solana/accounts",
|
|
30
|
-
solanaAddresses: "@solana/addresses",
|
|
31
|
-
solanaCodecsCore: "@solana/codecs",
|
|
32
|
-
solanaCodecsDataStructures: "@solana/codecs",
|
|
33
|
-
solanaCodecsNumbers: "@solana/codecs",
|
|
34
|
-
solanaCodecsStrings: "@solana/codecs",
|
|
35
|
-
solanaErrors: "@solana/errors",
|
|
36
|
-
solanaInstructions: "@solana/instructions",
|
|
37
|
-
solanaOptions: "@solana/codecs",
|
|
38
|
-
solanaPrograms: "@solana/programs",
|
|
39
|
-
solanaRpcTypes: "@solana/rpc-types",
|
|
40
|
-
solanaSigners: "@solana/signers"
|
|
41
|
-
};
|
|
42
|
-
var DEFAULT_INTERNAL_MODULE_MAP = {
|
|
43
|
-
errors: "../errors",
|
|
44
|
-
generated: "..",
|
|
45
|
-
generatedAccounts: "../accounts",
|
|
46
|
-
generatedErrors: "../errors",
|
|
47
|
-
generatedInstructions: "../instructions",
|
|
48
|
-
generatedPdas: "../pdas",
|
|
49
|
-
generatedPrograms: "../programs",
|
|
50
|
-
generatedTypes: "../types",
|
|
51
|
-
hooked: "../../hooked",
|
|
52
|
-
shared: "../shared",
|
|
53
|
-
types: "../types"
|
|
54
|
-
};
|
|
55
|
-
function createImportMap() {
|
|
56
|
-
return Object.freeze(/* @__PURE__ */ new Map());
|
|
57
|
-
}
|
|
58
|
-
function parseImportInput(input) {
|
|
59
|
-
const matches = input.match(/^(type )?([^ ]+)(?: as (.+))?$/);
|
|
60
|
-
if (!matches) return Object.freeze({ importedIdentifier: input, isType: false, usedIdentifier: input });
|
|
61
|
-
const [_, isType, name, alias] = matches;
|
|
62
|
-
return Object.freeze({
|
|
63
|
-
importedIdentifier: name,
|
|
64
|
-
isType: !!isType,
|
|
65
|
-
usedIdentifier: alias ?? name
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function addToImportMap(importMap, module, imports) {
|
|
69
|
-
const parsedImports = imports.map(parseImportInput).map((i) => [i.usedIdentifier, i]);
|
|
70
|
-
return mergeImportMaps([importMap, /* @__PURE__ */ new Map([[module, new Map(parsedImports)]])]);
|
|
71
|
-
}
|
|
72
|
-
function removeFromImportMap(importMap, module, usedIdentifiers) {
|
|
73
|
-
const newMap = new Map(importMap);
|
|
74
|
-
const newModuleMap = new Map(newMap.get(module));
|
|
75
|
-
usedIdentifiers.forEach((usedIdentifier) => {
|
|
76
|
-
newModuleMap.delete(usedIdentifier);
|
|
77
|
-
});
|
|
78
|
-
if (newModuleMap.size === 0) {
|
|
79
|
-
newMap.delete(module);
|
|
80
|
-
} else {
|
|
81
|
-
newMap.set(module, newModuleMap);
|
|
82
|
-
}
|
|
83
|
-
return Object.freeze(newMap);
|
|
84
|
-
}
|
|
85
|
-
function mergeImportMaps(importMaps) {
|
|
86
|
-
if (importMaps.length === 0) return createImportMap();
|
|
87
|
-
if (importMaps.length === 1) return importMaps[0];
|
|
88
|
-
const mergedMap = new Map(importMaps[0]);
|
|
89
|
-
for (const map of importMaps.slice(1)) {
|
|
90
|
-
for (const [module, imports] of map) {
|
|
91
|
-
const mergedModuleMap = mergedMap.get(module) ?? /* @__PURE__ */ new Map();
|
|
92
|
-
for (const [usedIdentifier, importInfo] of imports) {
|
|
93
|
-
const existingImportInfo = mergedModuleMap.get(usedIdentifier);
|
|
94
|
-
const shouldOverwriteTypeOnly = existingImportInfo && existingImportInfo.importedIdentifier === importInfo.importedIdentifier && existingImportInfo.isType && !importInfo.isType;
|
|
95
|
-
if (!existingImportInfo || shouldOverwriteTypeOnly) {
|
|
96
|
-
mergedModuleMap.set(usedIdentifier, importInfo);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
mergedMap.set(module, mergedModuleMap);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return Object.freeze(mergedMap);
|
|
103
|
-
}
|
|
104
|
-
function importMapToString(importMap, dependencyMap = {}, useGranularImports = false) {
|
|
105
|
-
const resolvedMap = resolveImportMapModules(importMap, dependencyMap, useGranularImports);
|
|
106
|
-
return [...resolvedMap.entries()].sort(([a], [b]) => {
|
|
107
|
-
const relative = Number(a.startsWith(".")) - Number(b.startsWith("."));
|
|
108
|
-
if (relative !== 0) return relative;
|
|
109
|
-
return a.localeCompare(b);
|
|
110
|
-
}).map(([module, imports]) => {
|
|
111
|
-
const innerImports = [...imports.values()].map(importInfoToString).sort((a, b) => a.localeCompare(b)).join(", ");
|
|
112
|
-
return `import { ${innerImports} } from '${module}';`;
|
|
113
|
-
}).join("\n");
|
|
114
|
-
}
|
|
115
|
-
function getExternalDependencies(importMap, dependencyMap, useGranularImports) {
|
|
116
|
-
const resolvedImports = resolveImportMapModules(importMap, dependencyMap, useGranularImports);
|
|
117
|
-
return new Set([...resolvedImports.keys()].filter((module) => !module.startsWith(".")));
|
|
118
|
-
}
|
|
119
|
-
function resolveImportMapModules(importMap, dependencyMap, useGranularImports) {
|
|
120
|
-
const dependencyMapWithDefaults = {
|
|
121
|
-
...useGranularImports ? DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP : DEFAULT_EXTERNAL_MODULE_MAP,
|
|
122
|
-
...DEFAULT_INTERNAL_MODULE_MAP,
|
|
123
|
-
...dependencyMap
|
|
124
|
-
};
|
|
125
|
-
return mergeImportMaps(
|
|
126
|
-
[...importMap.entries()].map(([module, imports]) => {
|
|
127
|
-
const resolvedModule = dependencyMapWithDefaults[module] ?? module;
|
|
128
|
-
return /* @__PURE__ */ new Map([[resolvedModule, imports]]);
|
|
129
|
-
})
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
function importInfoToString({ importedIdentifier, isType, usedIdentifier }) {
|
|
133
|
-
const alias = importedIdentifier !== usedIdentifier ? ` as ${usedIdentifier}` : "";
|
|
134
|
-
return `${isType ? "type " : ""}${importedIdentifier}${alias}`;
|
|
135
|
-
}
|
|
136
|
-
function getNameApi(transformers) {
|
|
137
|
-
const helpers = {
|
|
138
|
-
camelCase,
|
|
139
|
-
capitalize,
|
|
140
|
-
kebabCase,
|
|
141
|
-
pascalCase,
|
|
142
|
-
snakeCase,
|
|
143
|
-
titleCase
|
|
144
|
-
};
|
|
145
|
-
return Object.fromEntries(
|
|
146
|
-
Object.entries(transformers).map(([key, transformer]) => [key, (name) => transformer(name, helpers)])
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
var DEFAULT_NAME_TRANSFORMERS = {
|
|
150
|
-
accountDecodeFunction: (name) => `decode${pascalCase(name)}`,
|
|
151
|
-
accountFetchAllFunction: (name) => `fetchAll${pascalCase(name)}`,
|
|
152
|
-
accountFetchAllMaybeFunction: (name) => `fetchAllMaybe${pascalCase(name)}`,
|
|
153
|
-
accountFetchFromSeedsFunction: (name) => `fetch${pascalCase(name)}FromSeeds`,
|
|
154
|
-
accountFetchFunction: (name) => `fetch${pascalCase(name)}`,
|
|
155
|
-
accountFetchMaybeFromSeedsFunction: (name) => `fetchMaybe${pascalCase(name)}FromSeeds`,
|
|
156
|
-
accountFetchMaybeFunction: (name) => `fetchMaybe${pascalCase(name)}`,
|
|
157
|
-
accountGetSizeFunction: (name) => `get${pascalCase(name)}Size`,
|
|
158
|
-
codecFunction: (name) => `get${pascalCase(name)}Codec`,
|
|
159
|
-
constant: (name) => snakeCase(name).toUpperCase(),
|
|
160
|
-
constantFunction: (name) => `get${pascalCase(name)}Bytes`,
|
|
161
|
-
dataArgsType: (name) => `${pascalCase(name)}Args`,
|
|
162
|
-
dataType: (name) => `${pascalCase(name)}`,
|
|
163
|
-
decoderFunction: (name) => `get${pascalCase(name)}Decoder`,
|
|
164
|
-
discriminatedUnionDiscriminator: () => "__kind",
|
|
165
|
-
discriminatedUnionFunction: (name) => `${camelCase(name)}`,
|
|
166
|
-
discriminatedUnionVariant: (name) => `${pascalCase(name)}`,
|
|
167
|
-
encoderFunction: (name) => `get${pascalCase(name)}Encoder`,
|
|
168
|
-
enumVariant: (name) => `${pascalCase(name)}`,
|
|
169
|
-
instructionAsyncFunction: (name) => `get${pascalCase(name)}InstructionAsync`,
|
|
170
|
-
instructionAsyncInputType: (name) => `${pascalCase(name)}AsyncInput`,
|
|
171
|
-
instructionDataType: (name) => `${pascalCase(name)}InstructionData`,
|
|
172
|
-
instructionExtraType: (name) => `${pascalCase(name)}InstructionExtra`,
|
|
173
|
-
instructionParseFunction: (name) => `parse${pascalCase(name)}Instruction`,
|
|
174
|
-
instructionParsedType: (name) => `Parsed${pascalCase(name)}Instruction`,
|
|
175
|
-
instructionSyncFunction: (name) => `get${pascalCase(name)}Instruction`,
|
|
176
|
-
instructionSyncInputType: (name) => `${pascalCase(name)}Input`,
|
|
177
|
-
instructionType: (name) => `${pascalCase(name)}Instruction`,
|
|
178
|
-
isDiscriminatedUnionFunction: (name) => `is${pascalCase(name)}`,
|
|
179
|
-
pdaFindFunction: (name) => `find${pascalCase(name)}Pda`,
|
|
180
|
-
pdaSeedsType: (name) => `${pascalCase(name)}Seeds`,
|
|
181
|
-
programAccountsEnum: (name) => `${pascalCase(name)}Account`,
|
|
182
|
-
programAccountsEnumVariant: (name) => `${pascalCase(name)}`,
|
|
183
|
-
programAccountsIdentifierFunction: (name) => `identify${pascalCase(name)}Account`,
|
|
184
|
-
programAddressConstant: (name) => `${snakeCase(name).toUpperCase()}_PROGRAM_ADDRESS`,
|
|
185
|
-
programErrorConstant: (name) => snakeCase(name).toUpperCase(),
|
|
186
|
-
programErrorConstantPrefix: (name) => `${snakeCase(name).toUpperCase()}_ERROR__`,
|
|
187
|
-
programErrorMessagesMap: (name) => `${camelCase(name)}ErrorMessages`,
|
|
188
|
-
programErrorUnion: (name) => `${pascalCase(name)}Error`,
|
|
189
|
-
programGetErrorMessageFunction: (name) => `get${pascalCase(name)}ErrorMessage`,
|
|
190
|
-
programInstructionsEnum: (name) => `${pascalCase(name)}Instruction`,
|
|
191
|
-
programInstructionsEnumVariant: (name) => `${pascalCase(name)}`,
|
|
192
|
-
programInstructionsIdentifierFunction: (name) => `identify${pascalCase(name)}Instruction`,
|
|
193
|
-
programInstructionsParseFunction: (name) => `parse${pascalCase(name)}Instruction`,
|
|
194
|
-
programInstructionsParsedUnionType: (name) => `Parsed${pascalCase(name)}Instruction`,
|
|
195
|
-
programIsErrorFunction: (name) => `is${pascalCase(name)}Error`,
|
|
196
|
-
resolverFunction: (name) => `${camelCase(name)}`
|
|
197
|
-
};
|
|
198
|
-
function createFragment(content) {
|
|
199
|
-
return Object.freeze({ content, features: /* @__PURE__ */ new Set(), imports: createImportMap() });
|
|
200
|
-
}
|
|
201
|
-
function isFragment(value) {
|
|
202
|
-
return typeof value === "object" && value !== null && "content" in value;
|
|
203
|
-
}
|
|
204
|
-
function fragment(template, ...items) {
|
|
205
|
-
return createFragmentTemplate(template, items, isFragment, mergeFragments);
|
|
206
|
-
}
|
|
207
|
-
function mergeFragments(fragments, mergeContent) {
|
|
208
|
-
const filteredFragments = fragments.filter((f) => f !== void 0);
|
|
209
|
-
return Object.freeze({
|
|
210
|
-
content: mergeContent(filteredFragments.map((fragment2) => fragment2.content)),
|
|
211
|
-
features: new Set(filteredFragments.flatMap((f) => [...f.features])),
|
|
212
|
-
imports: mergeImportMaps(filteredFragments.map((f) => f.imports))
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
function use(importInput, module) {
|
|
216
|
-
const importInfo = parseImportInput(importInput);
|
|
217
|
-
return addFragmentImports(createFragment(importInfo.usedIdentifier), module, [importInput]);
|
|
218
|
-
}
|
|
219
|
-
function mergeFragmentImports(fragment2, importMaps) {
|
|
220
|
-
return Object.freeze({ ...fragment2, imports: mergeImportMaps([fragment2.imports, ...importMaps]) });
|
|
221
|
-
}
|
|
222
|
-
function addFragmentImports(fragment2, module, importInputs) {
|
|
223
|
-
return Object.freeze({ ...fragment2, imports: addToImportMap(fragment2.imports, module, importInputs) });
|
|
224
|
-
}
|
|
225
|
-
function removeFragmentImports(fragment2, module, usedIdentifiers) {
|
|
226
|
-
return Object.freeze({ ...fragment2, imports: removeFromImportMap(fragment2.imports, module, usedIdentifiers) });
|
|
227
|
-
}
|
|
228
|
-
function addFragmentFeatures(fragment2, features) {
|
|
229
|
-
return Object.freeze({ ...fragment2, features: /* @__PURE__ */ new Set([...fragment2.features, ...features]) });
|
|
230
|
-
}
|
|
231
|
-
function getExportAllFragment(module) {
|
|
232
|
-
return fragment`export * from '${module}';`;
|
|
233
|
-
}
|
|
234
|
-
function getDocblockFragment(lines, withLineJump = false) {
|
|
235
|
-
const lineJump = withLineJump ? "\n" : "";
|
|
236
|
-
if (lines.length === 0) return;
|
|
237
|
-
if (lines.length === 1) return fragment`/** ${lines[0]} */${lineJump}`;
|
|
238
|
-
const prefixedLines = lines.map((line) => line ? ` * ${line}` : " *");
|
|
239
|
-
return fragment`/**\n${prefixedLines.join("\n")}\n */${lineJump}`;
|
|
240
|
-
}
|
|
241
|
-
function getPageFragment(page, scope) {
|
|
242
|
-
const header = getDocblockFragment([
|
|
243
|
-
"This code was AUTOGENERATED using the Codama library.",
|
|
244
|
-
"Please DO NOT EDIT THIS FILE, instead use visitors",
|
|
245
|
-
"to add features, then rerun Codama to update it.",
|
|
246
|
-
"",
|
|
247
|
-
"@see https://github.com/codama-idl/codama"
|
|
248
|
-
]);
|
|
249
|
-
const imports = page.imports.size === 0 ? void 0 : fragment`${importMapToString(page.imports, scope.dependencyMap, scope.useGranularImports)}`;
|
|
250
|
-
return mergeFragments([header, imports, page], (cs) => cs.join("\n\n"));
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// src/utils/typeManifest.ts
|
|
254
|
-
function typeManifest(input = {}) {
|
|
255
|
-
return Object.freeze({
|
|
256
|
-
decoder: fragment``,
|
|
257
|
-
encoder: fragment``,
|
|
258
|
-
isEnum: false,
|
|
259
|
-
looseType: fragment``,
|
|
260
|
-
strictType: fragment``,
|
|
261
|
-
value: fragment``,
|
|
262
|
-
...input
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
function mergeTypeManifests(manifests, options = {}) {
|
|
266
|
-
const { mergeTypes, mergeCodecs, mergeValues } = options;
|
|
267
|
-
const merge = (fragmentFn, mergeFn) => mergeFn ? mergeFragments(manifests.map(fragmentFn), mergeFn) : fragment``;
|
|
268
|
-
return Object.freeze({
|
|
269
|
-
decoder: merge((m) => m.decoder, mergeCodecs),
|
|
270
|
-
encoder: merge((m) => m.encoder, mergeCodecs),
|
|
271
|
-
isEnum: false,
|
|
272
|
-
looseType: merge((m) => m.looseType, mergeTypes),
|
|
273
|
-
strictType: merge((m) => m.strictType, mergeTypes),
|
|
274
|
-
value: merge((m) => m.value, mergeValues)
|
|
275
|
-
});
|
|
276
|
-
}
|
|
13
|
+
// src/utils/async.ts
|
|
277
14
|
function hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers) {
|
|
278
15
|
const hasByteDeltasAsync = (instructionNode.byteDeltas ?? []).some(
|
|
279
16
|
({ value }) => isNode(value, "resolverValueNode") && asyncResolvers.includes(value.name)
|
|
@@ -389,12 +126,12 @@ var getDefinedTypeNodesToExtract = (nodes, parsedCustomDataOptions) => nodes.fla
|
|
|
389
126
|
var DEFAULT_PRETTIER_OPTIONS = {
|
|
390
127
|
plugins: [estreePlugin, typeScriptPlugin, babelPlugin]
|
|
391
128
|
};
|
|
392
|
-
async function getCodeFormatter(options) {
|
|
129
|
+
async function getCodeFormatter(packageFolder, options) {
|
|
393
130
|
const shouldFormatCode = options.formatCode ?? true;
|
|
394
131
|
if (!shouldFormatCode) return (code) => Promise.resolve(code);
|
|
395
132
|
const prettierOptions = {
|
|
396
133
|
...DEFAULT_PRETTIER_OPTIONS,
|
|
397
|
-
...await resolvePrettierOptions(
|
|
134
|
+
...await resolvePrettierOptions(),
|
|
398
135
|
...options.prettierOptions
|
|
399
136
|
};
|
|
400
137
|
return (code, filepath) => format(code, { ...prettierOptions, filepath });
|
|
@@ -404,6 +141,60 @@ async function resolvePrettierOptions(packageFolder) {
|
|
|
404
141
|
return null;
|
|
405
142
|
}
|
|
406
143
|
}
|
|
144
|
+
function createFragment(content) {
|
|
145
|
+
return Object.freeze({ content, features: /* @__PURE__ */ new Set(), imports: createImportMap() });
|
|
146
|
+
}
|
|
147
|
+
function isFragment(value) {
|
|
148
|
+
return typeof value === "object" && value !== null && "content" in value;
|
|
149
|
+
}
|
|
150
|
+
function fragment(template, ...items) {
|
|
151
|
+
return createFragmentTemplate(template, items, isFragment, mergeFragments);
|
|
152
|
+
}
|
|
153
|
+
function mergeFragments(fragments, mergeContent) {
|
|
154
|
+
const filteredFragments = fragments.filter((f) => f !== void 0);
|
|
155
|
+
return Object.freeze({
|
|
156
|
+
content: mergeContent(filteredFragments.map((fragment2) => fragment2.content)),
|
|
157
|
+
features: new Set(filteredFragments.flatMap((f) => [...f.features])),
|
|
158
|
+
imports: mergeImportMaps(filteredFragments.map((f) => f.imports))
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function use(importInput, module) {
|
|
162
|
+
const importInfo = parseImportInput(importInput);
|
|
163
|
+
return addFragmentImports(createFragment(importInfo.usedIdentifier), module, [importInput]);
|
|
164
|
+
}
|
|
165
|
+
function mergeFragmentImports(fragment2, importMaps) {
|
|
166
|
+
return Object.freeze({ ...fragment2, imports: mergeImportMaps([fragment2.imports, ...importMaps]) });
|
|
167
|
+
}
|
|
168
|
+
function addFragmentImports(fragment2, module, importInputs) {
|
|
169
|
+
return Object.freeze({ ...fragment2, imports: addToImportMap(fragment2.imports, module, importInputs) });
|
|
170
|
+
}
|
|
171
|
+
function removeFragmentImports(fragment2, module, usedIdentifiers) {
|
|
172
|
+
return Object.freeze({ ...fragment2, imports: removeFromImportMap(fragment2.imports, module, usedIdentifiers) });
|
|
173
|
+
}
|
|
174
|
+
function addFragmentFeatures(fragment2, features) {
|
|
175
|
+
return Object.freeze({ ...fragment2, features: /* @__PURE__ */ new Set([...fragment2.features, ...features]) });
|
|
176
|
+
}
|
|
177
|
+
function getExportAllFragment(module) {
|
|
178
|
+
return fragment`export * from '${module}';`;
|
|
179
|
+
}
|
|
180
|
+
function getDocblockFragment(lines, withLineJump = false) {
|
|
181
|
+
const lineJump = withLineJump ? "\n" : "";
|
|
182
|
+
if (lines.length === 0) return;
|
|
183
|
+
if (lines.length === 1) return fragment`/** ${lines[0]} */${lineJump}`;
|
|
184
|
+
const prefixedLines = lines.map((line) => line ? ` * ${line}` : " *");
|
|
185
|
+
return fragment`/**\n${prefixedLines.join("\n")}\n */${lineJump}`;
|
|
186
|
+
}
|
|
187
|
+
function getPageFragment(page, scope) {
|
|
188
|
+
const header = getDocblockFragment([
|
|
189
|
+
"This code was AUTOGENERATED using the Codama library.",
|
|
190
|
+
"Please DO NOT EDIT THIS FILE, instead use visitors",
|
|
191
|
+
"to add features, then rerun Codama to update it.",
|
|
192
|
+
"",
|
|
193
|
+
"@see https://github.com/codama-idl/codama"
|
|
194
|
+
]);
|
|
195
|
+
const imports = page.imports.size === 0 ? void 0 : fragment`${importMapToString(page.imports, scope.dependencyMap, scope.kitImportStrategy)}`;
|
|
196
|
+
return mergeFragments([header, imports, page], (cs) => cs.join("\n\n"));
|
|
197
|
+
}
|
|
407
198
|
function getImportFromFactory(overrides, customAccountData, customInstructionData) {
|
|
408
199
|
const customDataOverrides = Object.fromEntries(
|
|
409
200
|
[...customAccountData.values(), ...customInstructionData.values()].map(({ importFrom, importAs }) => [
|
|
@@ -450,6 +241,79 @@ function getImportFromFactory(overrides, customAccountData, customInstructionDat
|
|
|
450
241
|
}
|
|
451
242
|
};
|
|
452
243
|
}
|
|
244
|
+
function getNameApi(transformers) {
|
|
245
|
+
const helpers = {
|
|
246
|
+
camelCase: camelCase,
|
|
247
|
+
capitalize,
|
|
248
|
+
kebabCase,
|
|
249
|
+
pascalCase,
|
|
250
|
+
snakeCase,
|
|
251
|
+
titleCase
|
|
252
|
+
};
|
|
253
|
+
return Object.fromEntries(
|
|
254
|
+
Object.entries(transformers).map(([key, transformer]) => [key, (name) => transformer(name, helpers)])
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
var DEFAULT_NAME_TRANSFORMERS = {
|
|
258
|
+
accountDecodeFunction: (name) => `decode${pascalCase(name)}`,
|
|
259
|
+
accountFetchAllFunction: (name) => `fetchAll${pascalCase(name)}`,
|
|
260
|
+
accountFetchAllMaybeFunction: (name) => `fetchAllMaybe${pascalCase(name)}`,
|
|
261
|
+
accountFetchFromSeedsFunction: (name) => `fetch${pascalCase(name)}FromSeeds`,
|
|
262
|
+
accountFetchFunction: (name) => `fetch${pascalCase(name)}`,
|
|
263
|
+
accountFetchMaybeFromSeedsFunction: (name) => `fetchMaybe${pascalCase(name)}FromSeeds`,
|
|
264
|
+
accountFetchMaybeFunction: (name) => `fetchMaybe${pascalCase(name)}`,
|
|
265
|
+
accountGetSizeFunction: (name) => `get${pascalCase(name)}Size`,
|
|
266
|
+
codecFunction: (name) => `get${pascalCase(name)}Codec`,
|
|
267
|
+
constant: (name) => snakeCase(name).toUpperCase(),
|
|
268
|
+
constantFunction: (name) => `get${pascalCase(name)}Bytes`,
|
|
269
|
+
dataArgsType: (name) => `${pascalCase(name)}Args`,
|
|
270
|
+
dataType: (name) => `${pascalCase(name)}`,
|
|
271
|
+
decoderFunction: (name) => `get${pascalCase(name)}Decoder`,
|
|
272
|
+
discriminatedUnionDiscriminator: () => "__kind",
|
|
273
|
+
discriminatedUnionFunction: (name) => `${camelCase(name)}`,
|
|
274
|
+
discriminatedUnionVariant: (name) => `${pascalCase(name)}`,
|
|
275
|
+
encoderFunction: (name) => `get${pascalCase(name)}Encoder`,
|
|
276
|
+
enumVariant: (name) => `${pascalCase(name)}`,
|
|
277
|
+
instructionAsyncFunction: (name) => `get${pascalCase(name)}InstructionAsync`,
|
|
278
|
+
instructionAsyncInputType: (name) => `${pascalCase(name)}AsyncInput`,
|
|
279
|
+
instructionDataType: (name) => `${pascalCase(name)}InstructionData`,
|
|
280
|
+
instructionExtraType: (name) => `${pascalCase(name)}InstructionExtra`,
|
|
281
|
+
instructionParseFunction: (name) => `parse${pascalCase(name)}Instruction`,
|
|
282
|
+
instructionParsedType: (name) => `Parsed${pascalCase(name)}Instruction`,
|
|
283
|
+
instructionSyncFunction: (name) => `get${pascalCase(name)}Instruction`,
|
|
284
|
+
instructionSyncInputType: (name) => `${pascalCase(name)}Input`,
|
|
285
|
+
instructionType: (name) => `${pascalCase(name)}Instruction`,
|
|
286
|
+
isDiscriminatedUnionFunction: (name) => `is${pascalCase(name)}`,
|
|
287
|
+
pdaFindFunction: (name) => `find${pascalCase(name)}Pda`,
|
|
288
|
+
pdaSeedsType: (name) => `${pascalCase(name)}Seeds`,
|
|
289
|
+
programAccountsEnum: (name) => `${pascalCase(name)}Account`,
|
|
290
|
+
programAccountsEnumVariant: (name) => `${pascalCase(name)}`,
|
|
291
|
+
programAccountsIdentifierFunction: (name) => `identify${pascalCase(name)}Account`,
|
|
292
|
+
programAddressConstant: (name) => `${snakeCase(name).toUpperCase()}_PROGRAM_ADDRESS`,
|
|
293
|
+
programErrorConstant: (name) => snakeCase(name).toUpperCase(),
|
|
294
|
+
programErrorConstantPrefix: (name) => `${snakeCase(name).toUpperCase()}_ERROR__`,
|
|
295
|
+
programErrorMessagesMap: (name) => `${camelCase(name)}ErrorMessages`,
|
|
296
|
+
programErrorUnion: (name) => `${pascalCase(name)}Error`,
|
|
297
|
+
programGetErrorMessageFunction: (name) => `get${pascalCase(name)}ErrorMessage`,
|
|
298
|
+
programInstructionsEnum: (name) => `${pascalCase(name)}Instruction`,
|
|
299
|
+
programInstructionsEnumVariant: (name) => `${pascalCase(name)}`,
|
|
300
|
+
programInstructionsIdentifierFunction: (name) => `identify${pascalCase(name)}Instruction`,
|
|
301
|
+
programInstructionsParseFunction: (name) => `parse${pascalCase(name)}Instruction`,
|
|
302
|
+
programInstructionsParsedUnionType: (name) => `Parsed${pascalCase(name)}Instruction`,
|
|
303
|
+
programIsErrorFunction: (name) => `is${pascalCase(name)}Error`,
|
|
304
|
+
programPluginAccountKey: (name) => `${camelCase(name)}`,
|
|
305
|
+
programPluginAccountsType: (name) => `${pascalCase(name)}PluginAccounts`,
|
|
306
|
+
programPluginFunction: (name) => `${camelCase(name)}Program`,
|
|
307
|
+
programPluginInstructionKey: (name) => `${camelCase(name)}`,
|
|
308
|
+
programPluginInstructionsType: (name) => `${pascalCase(name)}PluginInstructions`,
|
|
309
|
+
programPluginKey: (name) => `${camelCase(name)}`,
|
|
310
|
+
programPluginRequirementsType: (name) => `${pascalCase(name)}PluginRequirements`,
|
|
311
|
+
programPluginType: (name) => `${pascalCase(name)}Plugin`,
|
|
312
|
+
resolverFunction: (name) => `${camelCase(name)}`
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// src/utils/options.ts
|
|
316
|
+
var DEFAULT_KIT_IMPORT_STRATEGY = "preferRoot";
|
|
453
317
|
var DEFAULT_DEPENDENCY_VERSIONS = {
|
|
454
318
|
"@solana/accounts": "^6.0.0",
|
|
455
319
|
"@solana/addresses": "^6.0.0",
|
|
@@ -459,23 +323,16 @@ var DEFAULT_DEPENDENCY_VERSIONS = {
|
|
|
459
323
|
"@solana/kit": "^6.0.0",
|
|
460
324
|
"@solana/programs": "^6.0.0",
|
|
461
325
|
"@solana/rpc-types": "^6.0.0",
|
|
462
|
-
"@solana/signers": "^6.0.0"
|
|
463
|
-
};
|
|
464
|
-
async function syncPackageJson(renderMap, formatCode, options) {
|
|
465
|
-
const shouldSyncPackageJson = options.syncPackageJson ??
|
|
466
|
-
const packageFolder = options.packageFolder;
|
|
467
|
-
if (!packageFolder) {
|
|
468
|
-
if (shouldSyncPackageJson) {
|
|
469
|
-
logWarn("Cannot sync package.json. Please provide the 'packageFolder' option.");
|
|
470
|
-
}
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
326
|
+
"@solana/signers": "^6.0.0"
|
|
327
|
+
};
|
|
328
|
+
async function syncPackageJson(renderMap, formatCode, packageFolder, options) {
|
|
329
|
+
const shouldSyncPackageJson = options.syncPackageJson ?? true;
|
|
473
330
|
const packageJsonPath = joinPath(packageFolder, "package.json");
|
|
474
331
|
const usedDependencies = getUsedDependencyVersions(
|
|
475
332
|
renderMap,
|
|
476
333
|
options.dependencyMap ?? {},
|
|
477
334
|
options.dependencyVersions ?? {},
|
|
478
|
-
options.
|
|
335
|
+
options.kitImportStrategy ?? DEFAULT_KIT_IMPORT_STRATEGY
|
|
479
336
|
);
|
|
480
337
|
if (!shouldSyncPackageJson) {
|
|
481
338
|
if (fileExists(packageJsonPath)) {
|
|
@@ -563,13 +420,13 @@ function checkExistingPackageJson(packageJson, dependencyVersions) {
|
|
|
563
420
|
${missingList}${outdatedList}`
|
|
564
421
|
);
|
|
565
422
|
}
|
|
566
|
-
function getUsedDependencyVersions(renderMap, dependencyMap, dependencyVersions,
|
|
423
|
+
function getUsedDependencyVersions(renderMap, dependencyMap, dependencyVersions, kitImportStrategy) {
|
|
567
424
|
const dependencyVersionsWithDefaults = {
|
|
568
425
|
...DEFAULT_DEPENDENCY_VERSIONS,
|
|
569
426
|
...dependencyVersions
|
|
570
427
|
};
|
|
571
428
|
const fragment2 = mergeFragments([...renderMap.values()], () => "");
|
|
572
|
-
const usedDependencies = getExternalDependencies(fragment2.imports, dependencyMap,
|
|
429
|
+
const usedDependencies = getExternalDependencies(fragment2.imports, dependencyMap, kitImportStrategy);
|
|
573
430
|
const [usedDependencyVersion, missingDependencies] = [...usedDependencies].reduce(
|
|
574
431
|
([acc, missingDependencies2], dependency) => {
|
|
575
432
|
const version = dependencyVersionsWithDefaults[dependency];
|
|
@@ -622,7 +479,173 @@ async function writePackageJson(packageJson, packageJsonPath, formatCode) {
|
|
|
622
479
|
writeFile(packageJsonPath, formattedContent);
|
|
623
480
|
}
|
|
624
481
|
|
|
625
|
-
// src/
|
|
482
|
+
// src/utils/typeManifest.ts
|
|
483
|
+
function typeManifest(input = {}) {
|
|
484
|
+
return Object.freeze({
|
|
485
|
+
decoder: fragment``,
|
|
486
|
+
encoder: fragment``,
|
|
487
|
+
isEnum: false,
|
|
488
|
+
looseType: fragment``,
|
|
489
|
+
strictType: fragment``,
|
|
490
|
+
value: fragment``,
|
|
491
|
+
...input
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
function mergeTypeManifests(manifests, options = {}) {
|
|
495
|
+
const { mergeTypes, mergeCodecs, mergeValues } = options;
|
|
496
|
+
const merge = (fragmentFn, mergeFn) => mergeFn ? mergeFragments(manifests.map(fragmentFn), mergeFn) : fragment``;
|
|
497
|
+
return Object.freeze({
|
|
498
|
+
decoder: merge((m) => m.decoder, mergeCodecs),
|
|
499
|
+
encoder: merge((m) => m.encoder, mergeCodecs),
|
|
500
|
+
isEnum: false,
|
|
501
|
+
looseType: merge((m) => m.looseType, mergeTypes),
|
|
502
|
+
strictType: merge((m) => m.strictType, mergeTypes),
|
|
503
|
+
value: merge((m) => m.value, mergeValues)
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// src/utils/importMap.ts
|
|
508
|
+
var DEFAULT_EXTERNAL_MODULE_MAP = {
|
|
509
|
+
solanaAccounts: "@solana/kit",
|
|
510
|
+
solanaAddresses: "@solana/kit",
|
|
511
|
+
solanaCodecsCore: "@solana/kit",
|
|
512
|
+
solanaCodecsDataStructures: "@solana/kit",
|
|
513
|
+
solanaCodecsNumbers: "@solana/kit",
|
|
514
|
+
solanaCodecsStrings: "@solana/kit",
|
|
515
|
+
solanaErrors: "@solana/kit",
|
|
516
|
+
solanaInstructionPlans: "@solana/kit",
|
|
517
|
+
solanaInstructions: "@solana/kit",
|
|
518
|
+
solanaOptions: "@solana/kit",
|
|
519
|
+
solanaPluginCore: "@solana/kit",
|
|
520
|
+
solanaPluginInterfaces: "@solana/kit",
|
|
521
|
+
solanaProgramClientCore: "@solana/kit/program-client-core",
|
|
522
|
+
solanaPrograms: "@solana/kit",
|
|
523
|
+
solanaRpcApi: "@solana/kit",
|
|
524
|
+
solanaRpcTypes: "@solana/kit",
|
|
525
|
+
solanaSigners: "@solana/kit"
|
|
526
|
+
};
|
|
527
|
+
var DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP = {
|
|
528
|
+
solanaAccounts: "@solana/accounts",
|
|
529
|
+
solanaAddresses: "@solana/addresses",
|
|
530
|
+
solanaCodecsCore: "@solana/codecs",
|
|
531
|
+
solanaCodecsDataStructures: "@solana/codecs",
|
|
532
|
+
solanaCodecsNumbers: "@solana/codecs",
|
|
533
|
+
solanaCodecsStrings: "@solana/codecs",
|
|
534
|
+
solanaErrors: "@solana/errors",
|
|
535
|
+
solanaInstructionPlans: "@solana/instruction-plans",
|
|
536
|
+
solanaInstructions: "@solana/instructions",
|
|
537
|
+
solanaOptions: "@solana/codecs",
|
|
538
|
+
solanaPluginCore: "@solana/plugin-core",
|
|
539
|
+
solanaPluginInterfaces: "@solana/plugin-interfaces",
|
|
540
|
+
solanaProgramClientCore: "@solana/program-client-core",
|
|
541
|
+
solanaPrograms: "@solana/programs",
|
|
542
|
+
solanaRpcApi: "@solana/rpc-api",
|
|
543
|
+
solanaRpcTypes: "@solana/rpc-types",
|
|
544
|
+
solanaSigners: "@solana/signers"
|
|
545
|
+
};
|
|
546
|
+
var DEFAULT_INTERNAL_MODULE_MAP = {
|
|
547
|
+
errors: "../errors",
|
|
548
|
+
generated: "..",
|
|
549
|
+
generatedAccounts: "../accounts",
|
|
550
|
+
generatedErrors: "../errors",
|
|
551
|
+
generatedInstructions: "../instructions",
|
|
552
|
+
generatedPdas: "../pdas",
|
|
553
|
+
generatedPrograms: "../programs",
|
|
554
|
+
generatedTypes: "../types",
|
|
555
|
+
hooked: "../../hooked",
|
|
556
|
+
shared: "../shared",
|
|
557
|
+
types: "../types"
|
|
558
|
+
};
|
|
559
|
+
function createImportMap() {
|
|
560
|
+
return Object.freeze(/* @__PURE__ */ new Map());
|
|
561
|
+
}
|
|
562
|
+
function parseImportInput(input) {
|
|
563
|
+
const matches = input.match(/^(type )?([^ ]+)(?: as (.+))?$/);
|
|
564
|
+
if (!matches) return Object.freeze({ importedIdentifier: input, isType: false, usedIdentifier: input });
|
|
565
|
+
const [_, isType, name, alias] = matches;
|
|
566
|
+
return Object.freeze({
|
|
567
|
+
importedIdentifier: name,
|
|
568
|
+
isType: !!isType,
|
|
569
|
+
usedIdentifier: alias ?? name
|
|
570
|
+
});
|
|
571
|
+
}
|
|
572
|
+
function addToImportMap(importMap, module, imports) {
|
|
573
|
+
const parsedImports = imports.map(parseImportInput).map((i) => [i.usedIdentifier, i]);
|
|
574
|
+
return mergeImportMaps([importMap, /* @__PURE__ */ new Map([[module, new Map(parsedImports)]])]);
|
|
575
|
+
}
|
|
576
|
+
function removeFromImportMap(importMap, module, usedIdentifiers) {
|
|
577
|
+
const newMap = new Map(importMap);
|
|
578
|
+
const newModuleMap = new Map(newMap.get(module));
|
|
579
|
+
usedIdentifiers.forEach((usedIdentifier) => {
|
|
580
|
+
newModuleMap.delete(usedIdentifier);
|
|
581
|
+
});
|
|
582
|
+
if (newModuleMap.size === 0) {
|
|
583
|
+
newMap.delete(module);
|
|
584
|
+
} else {
|
|
585
|
+
newMap.set(module, newModuleMap);
|
|
586
|
+
}
|
|
587
|
+
return Object.freeze(newMap);
|
|
588
|
+
}
|
|
589
|
+
function mergeImportMaps(importMaps) {
|
|
590
|
+
if (importMaps.length === 0) return createImportMap();
|
|
591
|
+
if (importMaps.length === 1) return importMaps[0];
|
|
592
|
+
const mergedMap = new Map(importMaps[0]);
|
|
593
|
+
for (const map of importMaps.slice(1)) {
|
|
594
|
+
for (const [module, imports] of map) {
|
|
595
|
+
const mergedModuleMap = mergedMap.get(module) ?? /* @__PURE__ */ new Map();
|
|
596
|
+
for (const [usedIdentifier, importInfo] of imports) {
|
|
597
|
+
const existingImportInfo = mergedModuleMap.get(usedIdentifier);
|
|
598
|
+
const shouldOverwriteTypeOnly = existingImportInfo && existingImportInfo.importedIdentifier === importInfo.importedIdentifier && existingImportInfo.isType && !importInfo.isType;
|
|
599
|
+
if (!existingImportInfo || shouldOverwriteTypeOnly) {
|
|
600
|
+
mergedModuleMap.set(usedIdentifier, importInfo);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
mergedMap.set(module, mergedModuleMap);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
return Object.freeze(mergedMap);
|
|
607
|
+
}
|
|
608
|
+
function importMapToString(importMap, dependencyMap = {}, kitImportStrategy = DEFAULT_KIT_IMPORT_STRATEGY) {
|
|
609
|
+
const resolvedMap = resolveImportMapModules(importMap, dependencyMap, kitImportStrategy);
|
|
610
|
+
return [...resolvedMap.entries()].sort(([a], [b]) => {
|
|
611
|
+
const relative = Number(a.startsWith(".")) - Number(b.startsWith("."));
|
|
612
|
+
if (relative !== 0) return relative;
|
|
613
|
+
return a.localeCompare(b);
|
|
614
|
+
}).map(([module, imports]) => {
|
|
615
|
+
const innerImports = [...imports.values()].map(importInfoToString).sort((a, b) => a.localeCompare(b)).join(", ");
|
|
616
|
+
return `import { ${innerImports} } from '${module}';`;
|
|
617
|
+
}).join("\n");
|
|
618
|
+
}
|
|
619
|
+
function getExternalDependencies(importMap, dependencyMap, kitImportStrategy) {
|
|
620
|
+
const resolvedImports = resolveImportMapModules(importMap, dependencyMap, kitImportStrategy);
|
|
621
|
+
return new Set(
|
|
622
|
+
[...resolvedImports.keys()].filter((module) => !module.startsWith(".")).map((module) => {
|
|
623
|
+
const subPathExportIndex = module.startsWith("@") ? 2 : 1;
|
|
624
|
+
return module.split("/").slice(0, subPathExportIndex).join("/");
|
|
625
|
+
})
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
function resolveImportMapModules(importMap, dependencyMap, kitImportStrategy) {
|
|
629
|
+
const defaultExternalModuleMap = kitImportStrategy === "granular" ? DEFAULT_GRANULAR_EXTERNAL_MODULE_MAP : DEFAULT_EXTERNAL_MODULE_MAP;
|
|
630
|
+
if (kitImportStrategy === "preferRoot") {
|
|
631
|
+
defaultExternalModuleMap["solanaProgramClientCore"] = "@solana/program-client-core";
|
|
632
|
+
}
|
|
633
|
+
const dependencyMapWithDefaults = {
|
|
634
|
+
...defaultExternalModuleMap,
|
|
635
|
+
...DEFAULT_INTERNAL_MODULE_MAP,
|
|
636
|
+
...dependencyMap
|
|
637
|
+
};
|
|
638
|
+
return mergeImportMaps(
|
|
639
|
+
[...importMap.entries()].map(([module, imports]) => {
|
|
640
|
+
const resolvedModule = dependencyMapWithDefaults[module] ?? module;
|
|
641
|
+
return /* @__PURE__ */ new Map([[resolvedModule, imports]]);
|
|
642
|
+
})
|
|
643
|
+
);
|
|
644
|
+
}
|
|
645
|
+
function importInfoToString({ importedIdentifier, isType, usedIdentifier }) {
|
|
646
|
+
const alias = importedIdentifier !== usedIdentifier ? ` as ${usedIdentifier}` : "";
|
|
647
|
+
return `${isType ? "type " : ""}${importedIdentifier}${alias}`;
|
|
648
|
+
}
|
|
626
649
|
function getAccountFetchHelpersFragment(scope) {
|
|
627
650
|
const { accountPath, typeManifest: typeManifest2, nameApi, customAccountData } = scope;
|
|
628
651
|
const accountNode = getLastNodeFromPath(accountPath);
|
|
@@ -1182,28 +1205,45 @@ function getInstructionInputDefaultFragment(scope) {
|
|
|
1182
1205
|
}
|
|
1183
1206
|
return fragment`args.${inputName} = ${renderedValue};`;
|
|
1184
1207
|
};
|
|
1185
|
-
const
|
|
1186
|
-
const
|
|
1187
|
-
|
|
1188
|
-
|
|
1208
|
+
const getNonNullResolvedInstructionInput = use("getNonNullResolvedInstructionInput", "solanaProgramClientCore");
|
|
1209
|
+
const getResolvedInstructionAccountAsTransactionSigner = use(
|
|
1210
|
+
"getResolvedInstructionAccountAsTransactionSigner",
|
|
1211
|
+
"solanaProgramClientCore"
|
|
1212
|
+
);
|
|
1213
|
+
const getAddressFromResolvedInstructionAccount = use(
|
|
1214
|
+
"getAddressFromResolvedInstructionAccount",
|
|
1215
|
+
"solanaProgramClientCore"
|
|
1216
|
+
);
|
|
1217
|
+
const getResolvedInstructionAccountAsProgramDerivedAddress = use(
|
|
1218
|
+
"getResolvedInstructionAccountAsProgramDerivedAddress",
|
|
1219
|
+
"solanaProgramClientCore"
|
|
1220
|
+
);
|
|
1189
1221
|
const addressType = use("type Address", "solanaAddresses");
|
|
1190
1222
|
switch (defaultValue.kind) {
|
|
1191
1223
|
case "accountValueNode":
|
|
1192
1224
|
const name = camelCase(defaultValue.name);
|
|
1193
1225
|
if (input.kind === "instructionAccountNode" && input.resolvedIsSigner && !input.isSigner) {
|
|
1194
|
-
return defaultFragment(
|
|
1226
|
+
return defaultFragment(
|
|
1227
|
+
fragment`${getResolvedInstructionAccountAsTransactionSigner}("${name}", accounts.${name}.value).address`
|
|
1228
|
+
);
|
|
1195
1229
|
}
|
|
1196
1230
|
if (input.kind === "instructionAccountNode") {
|
|
1197
|
-
return defaultFragment(
|
|
1231
|
+
return defaultFragment(
|
|
1232
|
+
fragment`${getNonNullResolvedInstructionInput}("${name}", accounts.${name}.value)`
|
|
1233
|
+
);
|
|
1198
1234
|
}
|
|
1199
|
-
return defaultFragment(
|
|
1235
|
+
return defaultFragment(
|
|
1236
|
+
fragment`${getAddressFromResolvedInstructionAccount}("${name}", accounts.${name}.value)`
|
|
1237
|
+
);
|
|
1200
1238
|
case "pdaValueNode":
|
|
1201
1239
|
let pdaProgramValue;
|
|
1202
1240
|
if (isNode(defaultValue.programId, "accountValueNode")) {
|
|
1203
|
-
|
|
1241
|
+
const name2 = camelCase(defaultValue.programId.name);
|
|
1242
|
+
pdaProgramValue = fragment`${getAddressFromResolvedInstructionAccount}("${name2}", accounts.${name2}.value)`;
|
|
1204
1243
|
}
|
|
1205
1244
|
if (isNode(defaultValue.programId, "argumentValueNode")) {
|
|
1206
|
-
|
|
1245
|
+
const name2 = camelCase(defaultValue.programId.name);
|
|
1246
|
+
pdaProgramValue = fragment`${getAddressFromResolvedInstructionAccount}("${name2}", args.${name2})`;
|
|
1207
1247
|
}
|
|
1208
1248
|
if (isNode(defaultValue.pda, "pdaNode")) {
|
|
1209
1249
|
let pdaProgram = fragment`programAddress`;
|
|
@@ -1226,13 +1266,15 @@ function getInstructionInputDefaultFragment(scope) {
|
|
|
1226
1266
|
const valueSeed = defaultValue.seeds.find((s) => s.name === seed.name)?.value;
|
|
1227
1267
|
if (!valueSeed) return [];
|
|
1228
1268
|
if (isNode(valueSeed, "accountValueNode")) {
|
|
1269
|
+
const name2 = camelCase(valueSeed.name);
|
|
1229
1270
|
return [
|
|
1230
|
-
fragment`${typeManifest2.encoder}.encode(${
|
|
1271
|
+
fragment`${typeManifest2.encoder}.encode(${getAddressFromResolvedInstructionAccount}("${name2}", accounts.${name2}.value))`
|
|
1231
1272
|
];
|
|
1232
1273
|
}
|
|
1233
1274
|
if (isNode(valueSeed, "argumentValueNode")) {
|
|
1275
|
+
const name2 = camelCase(valueSeed.name);
|
|
1234
1276
|
return [
|
|
1235
|
-
fragment`${typeManifest2.encoder}.encode(${
|
|
1277
|
+
fragment`${typeManifest2.encoder}.encode(${getNonNullResolvedInstructionInput}("${name2}", args.${name2}))`
|
|
1236
1278
|
];
|
|
1237
1279
|
}
|
|
1238
1280
|
const valueManifest2 = visit(valueSeed, typeManifestVisitor);
|
|
@@ -1251,10 +1293,12 @@ function getInstructionInputDefaultFragment(scope) {
|
|
|
1251
1293
|
const pdaArgs = [];
|
|
1252
1294
|
const pdaSeeds = defaultValue.seeds.map((seed) => {
|
|
1253
1295
|
if (isNode(seed.value, "accountValueNode")) {
|
|
1254
|
-
|
|
1296
|
+
const name2 = camelCase(seed.value.name);
|
|
1297
|
+
return fragment`${seed.name}: ${getAddressFromResolvedInstructionAccount}("${name2}", accounts.${name2}.value)`;
|
|
1255
1298
|
}
|
|
1256
1299
|
if (isNode(seed.value, "argumentValueNode")) {
|
|
1257
|
-
|
|
1300
|
+
const name2 = camelCase(seed.value.name);
|
|
1301
|
+
return fragment`${seed.name}: ${getNonNullResolvedInstructionInput}("${name2}", args.${name2})`;
|
|
1258
1302
|
}
|
|
1259
1303
|
return pipe(
|
|
1260
1304
|
visit(seed.value, typeManifestVisitor).value,
|
|
@@ -1289,10 +1333,12 @@ function getInstructionInputDefaultFragment(scope) {
|
|
|
1289
1333
|
return fragment``;
|
|
1290
1334
|
case "accountBumpValueNode":
|
|
1291
1335
|
return defaultFragment(
|
|
1292
|
-
fragment`${
|
|
1336
|
+
fragment`${getResolvedInstructionAccountAsProgramDerivedAddress}("${camelCase(defaultValue.name)}", accounts.${camelCase(defaultValue.name)}.value)[1]`
|
|
1293
1337
|
);
|
|
1294
1338
|
case "argumentValueNode":
|
|
1295
|
-
return defaultFragment(
|
|
1339
|
+
return defaultFragment(
|
|
1340
|
+
fragment`${getNonNullResolvedInstructionInput}("${camelCase(defaultValue.name)}", args.${camelCase(defaultValue.name)})`
|
|
1341
|
+
);
|
|
1296
1342
|
case "resolverValueNode":
|
|
1297
1343
|
const resolverFunction = use(nameApi.resolverFunction(defaultValue.name), getImportFrom(defaultValue));
|
|
1298
1344
|
const resolverAwait = useAsync && asyncResolvers.includes(defaultValue.name) ? "await " : "";
|
|
@@ -1555,7 +1601,7 @@ function getArgumentValueNodeFragment2(remainingAccounts, scope) {
|
|
|
1555
1601
|
return fragment`${argumentArray}.map((address) => ({ address, role: ${role} }))`;
|
|
1556
1602
|
}
|
|
1557
1603
|
if (isSigner === "either") {
|
|
1558
|
-
return fragment`${argumentArray}.map((addressOrSigner) => (
|
|
1604
|
+
return fragment`${argumentArray}.map((addressOrSigner) => (typeof addressOrSigner === "string" ? { address: addressOrSigner, role: ${role} } : { address: addressOrSigner.address, role: ${role}, signer: addressOrSigner }))`;
|
|
1559
1605
|
}
|
|
1560
1606
|
return fragment`${argumentArray}.map((signer) => ({ address: signer.address, role: ${signerRole}, signer }))`;
|
|
1561
1607
|
}
|
|
@@ -1655,7 +1701,7 @@ function getAccountsInitializationFragment(instructionNode) {
|
|
|
1655
1701
|
);
|
|
1656
1702
|
return fragment` // Original accounts.
|
|
1657
1703
|
const originalAccounts = { ${accounts} }
|
|
1658
|
-
const accounts = originalAccounts as Record<keyof typeof originalAccounts, ${use("type
|
|
1704
|
+
const accounts = originalAccounts as Record<keyof typeof originalAccounts, ${use("type ResolvedInstructionAccount", "solanaProgramClientCore")}>;
|
|
1659
1705
|
`;
|
|
1660
1706
|
}
|
|
1661
1707
|
function getArgumentsInitializationFragment(hasAnyArgs, renamedArgs) {
|
|
@@ -1680,9 +1726,11 @@ function getReturnStatementFragment(scope) {
|
|
|
1680
1726
|
const optionalAccountStrategy = instructionNode.optionalAccountStrategy ?? "programId";
|
|
1681
1727
|
const hasAccounts = instructionNode.accounts.length > 0;
|
|
1682
1728
|
const hasLegacyOptionalAccounts = instructionNode.optionalAccountStrategy === "omitted" && instructionNode.accounts.some((account) => account.isOptional);
|
|
1683
|
-
const getAccountMeta = hasAccounts ? fragment`const getAccountMeta = ${use("getAccountMetaFactory", "
|
|
1729
|
+
const getAccountMeta = hasAccounts ? fragment`const getAccountMeta = ${use("getAccountMetaFactory", "solanaProgramClientCore")}(programAddress, '${optionalAccountStrategy}');` : "";
|
|
1684
1730
|
const accountItems = [
|
|
1685
|
-
...instructionNode.accounts.map(
|
|
1731
|
+
...instructionNode.accounts.map(
|
|
1732
|
+
(account) => `getAccountMeta("${camelCase(account.name)}", accounts.${camelCase(account.name)})`
|
|
1733
|
+
),
|
|
1686
1734
|
...hasRemainingAccounts ? ["...remainingAccounts"] : []
|
|
1687
1735
|
].join(", ");
|
|
1688
1736
|
let accounts;
|
|
@@ -1712,7 +1760,7 @@ function getReturnStatementFragment(scope) {
|
|
|
1712
1760
|
function getReturnTypeFragment(instructionTypeFragment, hasByteDeltas, useAsync) {
|
|
1713
1761
|
return pipe(
|
|
1714
1762
|
instructionTypeFragment,
|
|
1715
|
-
(f) => hasByteDeltas ? fragment`${f} & ${use("type InstructionWithByteDelta", "
|
|
1763
|
+
(f) => hasByteDeltas ? fragment`${f} & ${use("type InstructionWithByteDelta", "solanaProgramClientCore")}` : f,
|
|
1716
1764
|
(f) => useAsync ? fragment`Promise<${f}>` : f
|
|
1717
1765
|
);
|
|
1718
1766
|
}
|
|
@@ -1824,9 +1872,10 @@ function getFunctionFragment(scope) {
|
|
|
1824
1872
|
);
|
|
1825
1873
|
let accountHelpers;
|
|
1826
1874
|
if (hasAccounts) {
|
|
1875
|
+
const solanaError = use("SolanaError", "solanaErrors");
|
|
1876
|
+
const solanaErrorCode = use("SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS", "solanaErrors");
|
|
1827
1877
|
accountHelpers = fragment`if (instruction.accounts.length < ${minimumNumberOfAccounts}) {
|
|
1828
|
-
|
|
1829
|
-
throw new Error('Not enough accounts');
|
|
1878
|
+
throw new ${solanaError}(${solanaErrorCode}, { actualAccountMetas: instruction.accounts.length, expectedAccountMetas: ${minimumNumberOfAccounts} });
|
|
1830
1879
|
}
|
|
1831
1880
|
let accountIndex = 0;
|
|
1832
1881
|
const getNextAccount = () => {
|
|
@@ -2044,30 +2093,27 @@ function getProgramAccountsIdentifierFunctionFragment(scope) {
|
|
|
2044
2093
|
if (!hasAccountDiscriminators) return;
|
|
2045
2094
|
const programAccountsEnum = nameApi.programAccountsEnum(programNode.name);
|
|
2046
2095
|
const programAccountsIdentifierFunction = nameApi.programAccountsIdentifierFunction(programNode.name);
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
(c) => c.join("\n")
|
|
2060
|
-
),
|
|
2061
|
-
(f) => mapFragmentContent(
|
|
2062
|
-
f,
|
|
2063
|
-
(discriminators) => `export function ${programAccountsIdentifierFunction}(account: { data: ReadonlyUint8Array } | ReadonlyUint8Array): ${programAccountsEnum} {
|
|
2064
|
-
const data = 'data' in account ? account.data : account;
|
|
2065
|
-
${discriminators}
|
|
2066
|
-
throw new Error("The provided account could not be identified as a ${programNode.name} account.")
|
|
2067
|
-
}`
|
|
2068
|
-
),
|
|
2069
|
-
(f) => addFragmentImports(f, "solanaCodecsCore", ["type ReadonlyUint8Array"])
|
|
2096
|
+
const discriminatorsFragment = mergeFragments(
|
|
2097
|
+
accountsWithDiscriminators.map((account) => {
|
|
2098
|
+
const variant = nameApi.programAccountsEnumVariant(account.name);
|
|
2099
|
+
return getDiscriminatorConditionFragment({
|
|
2100
|
+
...scope,
|
|
2101
|
+
dataName: "data",
|
|
2102
|
+
discriminators: account.discriminators ?? [],
|
|
2103
|
+
ifTrue: `return ${programAccountsEnum}.${variant};`,
|
|
2104
|
+
struct: resolveNestedTypeNode(account.data)
|
|
2105
|
+
});
|
|
2106
|
+
}),
|
|
2107
|
+
(c) => c.join("\n")
|
|
2070
2108
|
);
|
|
2109
|
+
const readonlyUint8Array = use("type ReadonlyUint8Array", "solanaCodecsCore");
|
|
2110
|
+
const solanaError = use("SolanaError", "solanaErrors");
|
|
2111
|
+
const solanaErrorCode = use("SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT", "solanaErrors");
|
|
2112
|
+
return fragment`export function ${programAccountsIdentifierFunction}(account: { data: ${readonlyUint8Array} } | ${readonlyUint8Array}): ${programAccountsEnum} {
|
|
2113
|
+
const data = 'data' in account ? account.data : account;
|
|
2114
|
+
${discriminatorsFragment}
|
|
2115
|
+
throw new ${solanaError}(${solanaErrorCode}, { accountData: data, programName: "${programNode.name}" });
|
|
2116
|
+
}`;
|
|
2071
2117
|
}
|
|
2072
2118
|
function getProgramConstantFragment(scope) {
|
|
2073
2119
|
const { programNode, nameApi } = scope;
|
|
@@ -2124,18 +2170,14 @@ function getProgramInstructionsIdentifierFunctionFragment(scope) {
|
|
|
2124
2170
|
}),
|
|
2125
2171
|
(c) => c.join("\n")
|
|
2126
2172
|
);
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
${
|
|
2134
|
-
|
|
2135
|
-
}`
|
|
2136
|
-
),
|
|
2137
|
-
(f) => addFragmentImports(f, "solanaCodecsCore", ["type ReadonlyUint8Array"])
|
|
2138
|
-
);
|
|
2173
|
+
const readonlyUint8Array = use("type ReadonlyUint8Array", "solanaCodecsCore");
|
|
2174
|
+
const solanaError = use("SolanaError", "solanaErrors");
|
|
2175
|
+
const solanaErrorCode = use("SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION", "solanaErrors");
|
|
2176
|
+
return fragment`export function ${programInstructionsIdentifierFunction}(instruction: { data: ${readonlyUint8Array} } | ${readonlyUint8Array}): ${programInstructionsEnum} {
|
|
2177
|
+
const data = 'data' in instruction ? instruction.data : instruction;
|
|
2178
|
+
${discriminatorsFragment}
|
|
2179
|
+
throw new ${solanaError}(${solanaErrorCode}, { instructionData: data, programName: "${programNode.name}" });
|
|
2180
|
+
}`;
|
|
2139
2181
|
}
|
|
2140
2182
|
function getProgramInstructionsParsedUnionTypeFragment(scope) {
|
|
2141
2183
|
const { programNode, allInstructions, nameApi } = scope;
|
|
@@ -2179,6 +2221,8 @@ function getProgramInstructionsParseFunctionFragment(scope) {
|
|
|
2179
2221
|
}),
|
|
2180
2222
|
(c) => c.join("\n")
|
|
2181
2223
|
);
|
|
2224
|
+
const solanaError = use("SolanaError", "solanaErrors");
|
|
2225
|
+
const solanaErrorCode = use("SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE", "solanaErrors");
|
|
2182
2226
|
return fragment`
|
|
2183
2227
|
export function ${parseFunction}<TProgram extends string>(
|
|
2184
2228
|
instruction: ${use("type Instruction", "solanaInstructions")}<TProgram>
|
|
@@ -2187,15 +2231,187 @@ function getProgramInstructionsParseFunctionFragment(scope) {
|
|
|
2187
2231
|
const instructionType = ${programInstructionsIdentifierFunction}(instruction);
|
|
2188
2232
|
switch (instructionType) {
|
|
2189
2233
|
${switchCases}
|
|
2190
|
-
default: throw new
|
|
2234
|
+
default: throw new ${solanaError}(${solanaErrorCode}, { instructionType: instructionType as string, programName: "${programNode.name}" });
|
|
2191
2235
|
}
|
|
2192
2236
|
}`;
|
|
2193
2237
|
}
|
|
2238
|
+
function getProgramPluginFragment(scope) {
|
|
2239
|
+
if (scope.programNode.accounts.length === 0 && scope.programNode.instructions.length === 0) return;
|
|
2240
|
+
const resolvedInstructionInputVisitor = getResolvedInstructionInputsVisitor();
|
|
2241
|
+
const asyncInstructions = scope.programNode.instructions.filter(
|
|
2242
|
+
(instruction) => hasAsyncFunction(instruction, visit(instruction, resolvedInstructionInputVisitor), scope.asyncResolvers)
|
|
2243
|
+
).map((i) => i.name);
|
|
2244
|
+
return mergeFragments(
|
|
2245
|
+
[
|
|
2246
|
+
getProgramPluginTypeFragment(scope),
|
|
2247
|
+
getProgramPluginAccountsTypeFragment(scope),
|
|
2248
|
+
getProgramPluginInstructionsTypeFragment({ ...scope, asyncInstructions }),
|
|
2249
|
+
getProgramPluginRequirementsTypeFragment(scope),
|
|
2250
|
+
getProgramPluginFunctionFragment({ ...scope, asyncInstructions }),
|
|
2251
|
+
getMakeOptionalHelperTypeFragment(scope)
|
|
2252
|
+
],
|
|
2253
|
+
(c) => c.join("\n\n")
|
|
2254
|
+
);
|
|
2255
|
+
}
|
|
2256
|
+
function getProgramPluginTypeFragment(scope) {
|
|
2257
|
+
const { programNode, nameApi } = scope;
|
|
2258
|
+
const programPluginType = nameApi.programPluginType(programNode.name);
|
|
2259
|
+
const programPluginAccountsType = nameApi.programPluginAccountsType(programNode.name);
|
|
2260
|
+
const programPluginInstructionsType = nameApi.programPluginInstructionsType(programNode.name);
|
|
2261
|
+
const fields = mergeFragments(
|
|
2262
|
+
[
|
|
2263
|
+
programNode.accounts.length > 0 ? fragment`accounts: ${programPluginAccountsType};` : void 0,
|
|
2264
|
+
programNode.instructions.length > 0 ? fragment`instructions: ${programPluginInstructionsType};` : void 0
|
|
2265
|
+
],
|
|
2266
|
+
(c) => c.join(" ")
|
|
2267
|
+
);
|
|
2268
|
+
return fragment`export type ${programPluginType} = { ${fields} }`;
|
|
2269
|
+
}
|
|
2270
|
+
function getProgramPluginAccountsTypeFragment(scope) {
|
|
2271
|
+
const { programNode, nameApi } = scope;
|
|
2272
|
+
if (programNode.accounts.length === 0) return;
|
|
2273
|
+
const programPluginAccountsType = nameApi.programPluginAccountsType(programNode.name);
|
|
2274
|
+
const selfFetchFunctions = use("type SelfFetchFunctions", "solanaProgramClientCore");
|
|
2275
|
+
const fields = mergeFragments(
|
|
2276
|
+
programNode.accounts.map((account) => {
|
|
2277
|
+
const name = nameApi.programPluginAccountKey(account.name);
|
|
2278
|
+
const codecFunction = use("type " + nameApi.codecFunction(account.name), "generatedAccounts");
|
|
2279
|
+
const fromType = use("type " + nameApi.dataArgsType(account.name), "generatedAccounts");
|
|
2280
|
+
const toType = use("type " + nameApi.dataType(account.name), "generatedAccounts");
|
|
2281
|
+
return fragment`${name}: ReturnType<typeof ${codecFunction}> & ${selfFetchFunctions}<${fromType}, ${toType}>;`;
|
|
2282
|
+
}),
|
|
2283
|
+
(c) => c.join(" ")
|
|
2284
|
+
);
|
|
2285
|
+
return fragment`export type ${programPluginAccountsType} = { ${fields} }`;
|
|
2286
|
+
}
|
|
2287
|
+
function getProgramPluginInstructionsTypeFragment(scope) {
|
|
2288
|
+
const { programNode, asyncInstructions, nameApi } = scope;
|
|
2289
|
+
if (programNode.instructions.length === 0) return;
|
|
2290
|
+
const programPluginInstructionsType = nameApi.programPluginInstructionsType(programNode.name);
|
|
2291
|
+
const selfPlanAndSendFunctions = use("type SelfPlanAndSendFunctions", "solanaProgramClientCore");
|
|
2292
|
+
const fields = mergeFragments(
|
|
2293
|
+
programNode.instructions.map((instruction) => {
|
|
2294
|
+
const name = nameApi.programPluginInstructionKey(instruction.name);
|
|
2295
|
+
const isAsync = asyncInstructions.includes(instruction.name);
|
|
2296
|
+
let instructionInputType = isAsync ? use("type " + nameApi.instructionAsyncInputType(instruction.name), "generatedInstructions") : use("type " + nameApi.instructionSyncInputType(instruction.name), "generatedInstructions");
|
|
2297
|
+
const instructionFunction = isAsync ? use("type " + nameApi.instructionAsyncFunction(instruction.name), "generatedInstructions") : use("type " + nameApi.instructionSyncFunction(instruction.name), "generatedInstructions");
|
|
2298
|
+
const payerDefaultValues = getPayerDefaultValues(instruction);
|
|
2299
|
+
if (payerDefaultValues.length > 0) {
|
|
2300
|
+
const fieldStringUnion = payerDefaultValues.map(({ name: name2 }) => `"${name2}"`).join(" | ");
|
|
2301
|
+
instructionInputType = fragment`MakeOptional<${instructionInputType}, ${fieldStringUnion}>`;
|
|
2302
|
+
}
|
|
2303
|
+
return fragment`${name}: (input: ${instructionInputType}) => ReturnType<typeof ${instructionFunction}> & ${selfPlanAndSendFunctions};`;
|
|
2304
|
+
}),
|
|
2305
|
+
(c) => c.join(" ")
|
|
2306
|
+
);
|
|
2307
|
+
return fragment`export type ${programPluginInstructionsType} = { ${fields} }`;
|
|
2308
|
+
}
|
|
2309
|
+
function getProgramPluginRequirementsTypeFragment(scope) {
|
|
2310
|
+
const { programNode, nameApi } = scope;
|
|
2311
|
+
const programRequirementsType = nameApi.programPluginRequirementsType(programNode.name);
|
|
2312
|
+
const clientWithRpc = fragment`${use("type ClientWithRpc", "solanaPluginInterfaces")}<${use("type GetAccountInfoApi", "solanaRpcApi")} & ${use("type GetMultipleAccountsApi", "solanaRpcApi")}>`;
|
|
2313
|
+
const clientWithPayer = use("type ClientWithPayer", "solanaPluginInterfaces");
|
|
2314
|
+
const clientWithTransactionPlanning = use("type ClientWithTransactionPlanning", "solanaPluginInterfaces");
|
|
2315
|
+
const clientWithTransactionSending = use("type ClientWithTransactionSending", "solanaPluginInterfaces");
|
|
2316
|
+
const hasAccounts = programNode.accounts.length > 0;
|
|
2317
|
+
const hasInstructions = programNode.instructions.length > 0;
|
|
2318
|
+
const requirements = mergeFragments(
|
|
2319
|
+
[
|
|
2320
|
+
hasAccounts ? clientWithRpc : void 0,
|
|
2321
|
+
hasPayerDefaultValues(programNode) ? clientWithPayer : void 0,
|
|
2322
|
+
hasInstructions ? clientWithTransactionPlanning : void 0,
|
|
2323
|
+
hasInstructions ? clientWithTransactionSending : void 0
|
|
2324
|
+
],
|
|
2325
|
+
(c) => c.join(" & ")
|
|
2326
|
+
);
|
|
2327
|
+
return fragment`export type ${programRequirementsType} = ${requirements}`;
|
|
2328
|
+
}
|
|
2329
|
+
function getProgramPluginFunctionFragment(scope) {
|
|
2330
|
+
const { programNode, nameApi } = scope;
|
|
2331
|
+
const programPluginFunction = nameApi.programPluginFunction(programNode.name);
|
|
2332
|
+
const programPluginType = nameApi.programPluginType(programNode.name);
|
|
2333
|
+
const programPluginRequirementsType = nameApi.programPluginRequirementsType(programNode.name);
|
|
2334
|
+
const programPluginKey = nameApi.programPluginKey(programNode.name);
|
|
2335
|
+
const fields = mergeFragments(
|
|
2336
|
+
[getProgramPluginAccountsObjectFragment(scope), getProgramPluginInstructionsObjectFragment(scope)],
|
|
2337
|
+
(c) => c.join(", ")
|
|
2338
|
+
);
|
|
2339
|
+
return fragment`export function ${programPluginFunction}() {
|
|
2340
|
+
return <T extends ${programPluginRequirementsType}>(client: T) => {
|
|
2341
|
+
return { ...client, ${programPluginKey}: <${programPluginType}>{ ${fields} } };
|
|
2342
|
+
};
|
|
2343
|
+
}`;
|
|
2344
|
+
}
|
|
2345
|
+
function getProgramPluginAccountsObjectFragment(scope) {
|
|
2346
|
+
const { programNode, nameApi } = scope;
|
|
2347
|
+
if (programNode.accounts.length === 0) return;
|
|
2348
|
+
const fields = mergeFragments(
|
|
2349
|
+
programNode.accounts.map((account) => {
|
|
2350
|
+
const name = nameApi.programPluginAccountKey(account.name);
|
|
2351
|
+
const addSelfFetchFunctions = use("addSelfFetchFunctions", "solanaProgramClientCore");
|
|
2352
|
+
const codecFunction = use(nameApi.codecFunction(account.name), "generatedAccounts");
|
|
2353
|
+
return fragment`${name}: ${addSelfFetchFunctions}(client, ${codecFunction}())`;
|
|
2354
|
+
}),
|
|
2355
|
+
(c) => c.join(", ")
|
|
2356
|
+
);
|
|
2357
|
+
return fragment`accounts: { ${fields} }`;
|
|
2358
|
+
}
|
|
2359
|
+
function getProgramPluginInstructionsObjectFragment(scope) {
|
|
2360
|
+
const { programNode, nameApi, asyncInstructions } = scope;
|
|
2361
|
+
if (programNode.instructions.length === 0) return;
|
|
2362
|
+
const fields = mergeFragments(
|
|
2363
|
+
programNode.instructions.map((instruction) => {
|
|
2364
|
+
const name = nameApi.programPluginInstructionKey(instruction.name);
|
|
2365
|
+
const isAsync = asyncInstructions.includes(instruction.name);
|
|
2366
|
+
const instructionFunction = isAsync ? use(nameApi.instructionAsyncFunction(instruction.name), "generatedInstructions") : use(nameApi.instructionSyncFunction(instruction.name), "generatedInstructions");
|
|
2367
|
+
const addSelfPlanAndSendFunctions = use("addSelfPlanAndSendFunctions", "solanaProgramClientCore");
|
|
2368
|
+
const payerDefaultValues = getPayerDefaultValues(instruction);
|
|
2369
|
+
let input = fragment`input`;
|
|
2370
|
+
if (payerDefaultValues.length > 0) {
|
|
2371
|
+
const fieldOverrides = mergeFragments(
|
|
2372
|
+
payerDefaultValues.map(({ name: name2, signer }) => {
|
|
2373
|
+
const signerDefault = signer ? "client.payer" : "client.payer.address";
|
|
2374
|
+
return fragment`${name2}: input.${name2} ?? ${signerDefault}`;
|
|
2375
|
+
}),
|
|
2376
|
+
(c) => c.join(", ")
|
|
2377
|
+
);
|
|
2378
|
+
input = fragment`{ ...input, ${fieldOverrides} }`;
|
|
2379
|
+
}
|
|
2380
|
+
return fragment`${name}: input => ${addSelfPlanAndSendFunctions}(client, ${instructionFunction}(${input}))`;
|
|
2381
|
+
}),
|
|
2382
|
+
(c) => c.join(", ")
|
|
2383
|
+
);
|
|
2384
|
+
return fragment`instructions: { ${fields} }`;
|
|
2385
|
+
}
|
|
2386
|
+
function getMakeOptionalHelperTypeFragment(scope) {
|
|
2387
|
+
if (!hasPayerDefaultValues(scope.programNode)) return;
|
|
2388
|
+
return fragment`type MakeOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;`;
|
|
2389
|
+
}
|
|
2390
|
+
function hasPayerDefaultValues(programNode) {
|
|
2391
|
+
return programNode.instructions.some((instruction) => getPayerDefaultValueNodes(instruction).length > 0);
|
|
2392
|
+
}
|
|
2393
|
+
function getPayerDefaultValues(instructionNode) {
|
|
2394
|
+
const renamedArgs = getRenamedArgsMap(instructionNode);
|
|
2395
|
+
return getPayerDefaultValueNodes(instructionNode).map((inputNode) => {
|
|
2396
|
+
return isNode(inputNode, "instructionAccountNode") ? { name: inputNode.name, signer: inputNode.isSigner !== false } : { name: renamedArgs.get(inputNode.name) ?? inputNode.name, signer: false };
|
|
2397
|
+
});
|
|
2398
|
+
}
|
|
2399
|
+
function getPayerDefaultValueNodes(instructionNode) {
|
|
2400
|
+
return [
|
|
2401
|
+
...instructionNode.accounts.filter((a) => !a.isOptional && isNode(a.defaultValue, "payerValueNode")),
|
|
2402
|
+
...instructionNode.arguments.filter((a) => isNode(a.defaultValue, "payerValueNode"))
|
|
2403
|
+
];
|
|
2404
|
+
}
|
|
2194
2405
|
|
|
2195
2406
|
// src/fragments/programPage.ts
|
|
2196
2407
|
function getProgramPageFragment(scope) {
|
|
2197
2408
|
return mergeFragments(
|
|
2198
|
-
[
|
|
2409
|
+
[
|
|
2410
|
+
getProgramConstantFragment(scope),
|
|
2411
|
+
getProgramAccountsFragment(scope),
|
|
2412
|
+
getProgramInstructionsFragment(scope),
|
|
2413
|
+
getProgramPluginFragment(scope)
|
|
2414
|
+
],
|
|
2199
2415
|
(cs) => cs.join("\n\n")
|
|
2200
2416
|
);
|
|
2201
2417
|
}
|
|
@@ -2219,121 +2435,6 @@ function getRootIndexPageFragment(scope) {
|
|
|
2219
2435
|
(cs) => cs.join("\n")
|
|
2220
2436
|
);
|
|
2221
2437
|
}
|
|
2222
|
-
function getSharedPageFragment() {
|
|
2223
|
-
const sharedPage = fragment`/**
|
|
2224
|
-
* Asserts that the given value is not null or undefined.
|
|
2225
|
-
* @internal
|
|
2226
|
-
*/
|
|
2227
|
-
export function expectSome<T>(value: T | null | undefined): T {
|
|
2228
|
-
if (value === null || value === undefined) {
|
|
2229
|
-
throw new Error('Expected a value but received null or undefined.');
|
|
2230
|
-
}
|
|
2231
|
-
return value;
|
|
2232
|
-
}
|
|
2233
|
-
|
|
2234
|
-
/**
|
|
2235
|
-
* Asserts that the given value is a PublicKey.
|
|
2236
|
-
* @internal
|
|
2237
|
-
*/
|
|
2238
|
-
export function expectAddress<T extends string = string>(
|
|
2239
|
-
value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
|
|
2240
|
-
): Address<T> {
|
|
2241
|
-
if (!value) {
|
|
2242
|
-
throw new Error('Expected a Address.');
|
|
2243
|
-
}
|
|
2244
|
-
if (typeof value === 'object' && "address" in value) {
|
|
2245
|
-
return value.address;
|
|
2246
|
-
}
|
|
2247
|
-
if (Array.isArray(value)) {
|
|
2248
|
-
return value[0] as Address<T>;
|
|
2249
|
-
}
|
|
2250
|
-
return value as Address<T>;
|
|
2251
|
-
}
|
|
2252
|
-
|
|
2253
|
-
/**
|
|
2254
|
-
* Asserts that the given value is a PDA.
|
|
2255
|
-
* @internal
|
|
2256
|
-
*/
|
|
2257
|
-
export function expectProgramDerivedAddress<T extends string = string>(
|
|
2258
|
-
value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
|
|
2259
|
-
): ProgramDerivedAddress<T> {
|
|
2260
|
-
if (!value || !Array.isArray(value) || !isProgramDerivedAddress(value)) {
|
|
2261
|
-
throw new Error('Expected a ProgramDerivedAddress.');
|
|
2262
|
-
}
|
|
2263
|
-
return value;
|
|
2264
|
-
}
|
|
2265
|
-
|
|
2266
|
-
/**
|
|
2267
|
-
* Asserts that the given value is a TransactionSigner.
|
|
2268
|
-
* @internal
|
|
2269
|
-
*/
|
|
2270
|
-
export function expectTransactionSigner<T extends string = string>(
|
|
2271
|
-
value: Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null | undefined
|
|
2272
|
-
): TransactionSigner<T> {
|
|
2273
|
-
if (!value || !isTransactionSigner(value)) {
|
|
2274
|
-
throw new Error('Expected a TransactionSigner.');
|
|
2275
|
-
}
|
|
2276
|
-
return value;
|
|
2277
|
-
}
|
|
2278
|
-
|
|
2279
|
-
/**
|
|
2280
|
-
* Defines an instruction account to resolve.
|
|
2281
|
-
* @internal
|
|
2282
|
-
*/
|
|
2283
|
-
export type ResolvedAccount<T extends string = string, U extends Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null = Address<T> | ProgramDerivedAddress<T> | TransactionSigner<T> | null> = {
|
|
2284
|
-
isWritable: boolean;
|
|
2285
|
-
value: U;
|
|
2286
|
-
};
|
|
2287
|
-
|
|
2288
|
-
/**
|
|
2289
|
-
* Defines an instruction that stores additional bytes on-chain.
|
|
2290
|
-
* @internal
|
|
2291
|
-
*/
|
|
2292
|
-
export type InstructionWithByteDelta = {
|
|
2293
|
-
byteDelta: number;
|
|
2294
|
-
};
|
|
2295
|
-
|
|
2296
|
-
/**
|
|
2297
|
-
* Get account metas and signers from resolved accounts.
|
|
2298
|
-
* @internal
|
|
2299
|
-
*/
|
|
2300
|
-
export function getAccountMetaFactory(
|
|
2301
|
-
programAddress: Address,
|
|
2302
|
-
optionalAccountStrategy: 'omitted' | 'programId',
|
|
2303
|
-
) {
|
|
2304
|
-
return (account: ResolvedAccount): AccountMeta | AccountSignerMeta | undefined => {
|
|
2305
|
-
if (!account.value) {
|
|
2306
|
-
if (optionalAccountStrategy === 'omitted') return;
|
|
2307
|
-
return Object.freeze({ address: programAddress, role: AccountRole.READONLY });
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
const writableRole = account.isWritable ? AccountRole.WRITABLE : AccountRole.READONLY;
|
|
2311
|
-
return Object.freeze({
|
|
2312
|
-
address: expectAddress(account.value),
|
|
2313
|
-
role: isTransactionSigner(account.value) ? upgradeRoleToSigner(writableRole) : writableRole,
|
|
2314
|
-
...(isTransactionSigner(account.value) ? { signer: account.value } : {})
|
|
2315
|
-
});
|
|
2316
|
-
};
|
|
2317
|
-
}
|
|
2318
|
-
|
|
2319
|
-
export function isTransactionSigner<TAddress extends string = string>(value: Address<TAddress> | ProgramDerivedAddress<TAddress> | TransactionSigner<TAddress>): value is TransactionSigner<TAddress> {
|
|
2320
|
-
return !!value && typeof value === 'object' && 'address' in value && kitIsTransactionSigner(value);
|
|
2321
|
-
}`;
|
|
2322
|
-
return pipe(
|
|
2323
|
-
sharedPage,
|
|
2324
|
-
(f) => addFragmentImports(f, "solanaAddresses", [
|
|
2325
|
-
"type Address",
|
|
2326
|
-
"isProgramDerivedAddress",
|
|
2327
|
-
"type ProgramDerivedAddress"
|
|
2328
|
-
]),
|
|
2329
|
-
(f) => addFragmentImports(f, "solanaInstructions", ["AccountRole", "type AccountMeta", "upgradeRoleToSigner"]),
|
|
2330
|
-
(f) => addFragmentImports(f, "solanaSigners", [
|
|
2331
|
-
"type AccountSignerMeta",
|
|
2332
|
-
"isTransactionSigner as kitIsTransactionSigner",
|
|
2333
|
-
"type TransactionSigner"
|
|
2334
|
-
])
|
|
2335
|
-
);
|
|
2336
|
-
}
|
|
2337
2438
|
function getTypeDiscriminatedUnionHelpersFragment(scope) {
|
|
2338
2439
|
const { name, typeNode, nameApi } = scope;
|
|
2339
2440
|
const isDiscriminatedUnion = isNode(typeNode, "enumTypeNode") && isDataEnum(typeNode);
|
|
@@ -3111,11 +3212,11 @@ function getRenderMapVisitor(options = {}) {
|
|
|
3111
3212
|
dependencyMap: options.dependencyMap ?? {},
|
|
3112
3213
|
dependencyVersions: options.dependencyVersions ?? {},
|
|
3113
3214
|
getImportFrom: getImportFromFactory(options.linkOverrides ?? {}, customAccountData, customInstructionData),
|
|
3215
|
+
kitImportStrategy: options.kitImportStrategy ?? DEFAULT_KIT_IMPORT_STRATEGY,
|
|
3114
3216
|
linkables,
|
|
3115
3217
|
nameApi: getNameApi({ ...DEFAULT_NAME_TRANSFORMERS, ...options.nameTransformers }),
|
|
3116
3218
|
nonScalarEnums: (options.nonScalarEnums ?? []).map(camelCase),
|
|
3117
|
-
renderParentInstructions: options.renderParentInstructions ?? false
|
|
3118
|
-
useGranularImports: options.useGranularImports ?? false
|
|
3219
|
+
renderParentInstructions: options.renderParentInstructions ?? false
|
|
3119
3220
|
};
|
|
3120
3221
|
const typeManifestVisitor = getTypeManifestVisitor({ ...renderScopeWithTypeManifestVisitor, stack });
|
|
3121
3222
|
const renderScope = { ...renderScopeWithTypeManifestVisitor, typeManifestVisitor };
|
|
@@ -3203,7 +3304,6 @@ function getRenderMapVisitor(options = {}) {
|
|
|
3203
3304
|
leavesOnly: !renderScope.renderParentInstructions
|
|
3204
3305
|
}).filter(isNotInternal);
|
|
3205
3306
|
const definedTypesToExport = getAllDefinedTypes(node).filter(isNotInternal);
|
|
3206
|
-
const hasAnythingToExport = programsToExport.length > 0 || accountsToExport.length > 0 || instructionsToExport.length > 0 || definedTypesToExport.length > 0;
|
|
3207
3307
|
const scope = {
|
|
3208
3308
|
accountsToExport,
|
|
3209
3309
|
definedTypesToExport,
|
|
@@ -3219,7 +3319,6 @@ function getRenderMapVisitor(options = {}) {
|
|
|
3219
3319
|
["instructions/index.ts"]: asPage(getIndexPageFragment(instructionsToExport)),
|
|
3220
3320
|
["pdas/index.ts"]: asPage(getIndexPageFragment(pdasToExport)),
|
|
3221
3321
|
["programs/index.ts"]: asPage(getIndexPageFragment(programsToExport)),
|
|
3222
|
-
["shared/index.ts"]: hasAnythingToExport ? asPage(getSharedPageFragment()) : void 0,
|
|
3223
3322
|
["types/index.ts"]: asPage(getIndexPageFragment(definedTypesToExport))
|
|
3224
3323
|
}),
|
|
3225
3324
|
...getAllPrograms(node).map((p) => visit(p, self))
|
|
@@ -3230,16 +3329,17 @@ function getRenderMapVisitor(options = {}) {
|
|
|
3230
3329
|
(v) => recordLinkablesOnFirstVisitVisitor(v, linkables)
|
|
3231
3330
|
);
|
|
3232
3331
|
}
|
|
3233
|
-
function renderVisitor(
|
|
3332
|
+
function renderVisitor(packageFolder, options = {}) {
|
|
3234
3333
|
return rootNodeVisitor(async (root) => {
|
|
3334
|
+
const generatedFolder = joinPath(packageFolder, options.generatedFolder ?? "src/generated");
|
|
3235
3335
|
if (options.deleteFolderBeforeRendering ?? true) {
|
|
3236
|
-
deleteDirectory(
|
|
3336
|
+
deleteDirectory(generatedFolder);
|
|
3237
3337
|
}
|
|
3238
3338
|
let renderMap = visit(root, getRenderMapVisitor(options));
|
|
3239
|
-
const formatCode = await getCodeFormatter(options);
|
|
3339
|
+
const formatCode = await getCodeFormatter(packageFolder, options);
|
|
3240
3340
|
renderMap = await mapRenderMapContentAsync(renderMap, formatCode);
|
|
3241
|
-
await syncPackageJson(renderMap, formatCode, options);
|
|
3242
|
-
writeRenderMap(renderMap,
|
|
3341
|
+
await syncPackageJson(renderMap, formatCode, packageFolder, options);
|
|
3342
|
+
writeRenderMap(renderMap, generatedFolder);
|
|
3243
3343
|
});
|
|
3244
3344
|
}
|
|
3245
3345
|
|