@codama/renderers-rust 1.2.9 → 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 +15 -13
- package/dist/index.node.cjs +288 -34
- package/dist/index.node.cjs.map +1 -1
- package/dist/index.node.mjs +290 -37
- package/dist/index.node.mjs.map +1 -1
- package/dist/templates/accountsPage.njk +3 -3
- package/dist/types/ImportMap.d.ts +4 -1
- package/dist/types/ImportMap.d.ts.map +1 -1
- package/dist/types/getRenderMapVisitor.d.ts +3 -4
- package/dist/types/getRenderMapVisitor.d.ts.map +1 -1
- package/dist/types/renderVisitor.d.ts +3 -2
- package/dist/types/renderVisitor.d.ts.map +1 -1
- package/dist/types/utils/cargoToml.d.ts +51 -0
- package/dist/types/utils/cargoToml.d.ts.map +1 -0
- package/dist/types/utils/fragment.d.ts +6 -0
- package/dist/types/utils/fragment.d.ts.map +1 -0
- package/dist/types/utils/index.d.ts +2 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/package.json +12 -9
package/README.md
CHANGED
|
@@ -17,14 +17,14 @@ pnpm install @codama/renderers-rust
|
|
|
17
17
|
|
|
18
18
|
## Usage
|
|
19
19
|
|
|
20
|
-
Add the following script to your Codama configuration file.
|
|
20
|
+
Add the following script to your Codama configuration file. The first argument is the crate folder (where `Cargo.toml` lives) and the generated code will be output to `src/generated` within that folder by default.
|
|
21
21
|
|
|
22
22
|
```json
|
|
23
23
|
{
|
|
24
24
|
"scripts": {
|
|
25
25
|
"rust": {
|
|
26
26
|
"from": "@codama/renderers-rust",
|
|
27
|
-
"args": ["clients/rust
|
|
27
|
+
"args": ["clients/rust"]
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -36,17 +36,19 @@ An object can be passed as a second argument to further configure the renderer.
|
|
|
36
36
|
|
|
37
37
|
The `renderVisitor` accepts the following options.
|
|
38
38
|
|
|
39
|
-
| Name | Type | Default | Description
|
|
40
|
-
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------- |
|
|
41
|
-
| `deleteFolderBeforeRendering` | `boolean` | `true` | Whether the base directory should be cleaned before generating new files.
|
|
42
|
-
| `formatCode` | `boolean` | `false` | Whether we should use `cargo fmt` to format the generated code.
|
|
43
|
-
| `
|
|
44
|
-
| `
|
|
45
|
-
| `linkOverrides` | `Record<'accounts' \| 'definedTypes' \| 'instructions' \| 'pdas' \| 'programs' \| 'resolvers', Record<string, string>>` | `{}` | A object that overrides the import path of link nodes. For instance, `{ definedTypes: { counter: 'hooked' } }` uses the `hooked` folder to import any link node referring to the `counter` type.
|
|
46
|
-
| `dependencyMap` | `Record<string, string>` | `{}` | A mapping between import aliases and their actual crate name or path in Rust.
|
|
47
|
-
| `
|
|
48
|
-
| `
|
|
49
|
-
| `
|
|
39
|
+
| Name | Type | Default | Description |
|
|
40
|
+
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
41
|
+
| `deleteFolderBeforeRendering` | `boolean` | `true` | Whether the base directory should be cleaned before generating new files. |
|
|
42
|
+
| `formatCode` | `boolean` | `false` | Whether we should use `cargo fmt` to format the generated code. |
|
|
43
|
+
| `generatedFolder` | `string` | `'src/generated'` | The path to the generated folder, relative to the crate folder provided as the first argument. |
|
|
44
|
+
| `toolchain` | `string` | `"+stable"` | The toolchain to use when formatting the generated code. |
|
|
45
|
+
| `linkOverrides` | `Record<'accounts' \| 'definedTypes' \| 'instructions' \| 'pdas' \| 'programs' \| 'resolvers', Record<string, string>>` | `{}` | A object that overrides the import path of link nodes. For instance, `{ definedTypes: { counter: 'hooked' } }` uses the `hooked` folder to import any link node referring to the `counter` type. |
|
|
46
|
+
| `dependencyMap` | `Record<string, string>` | `{}` | A mapping between import aliases and their actual crate name or path in Rust. |
|
|
47
|
+
| `dependencyVersions` | `Record<string, CargoDependency>` | `{}` | A mapping between external crates — e.g. `solana-pubkey` — and the version range we should use for them — e.g. `^3.0` or the equivalent dependency object — e.g. `{ version: "^3.0" }`. The renderer offers default values for all external dependencies it relies on but this option may be used to override some of these values or add new ones. |
|
|
48
|
+
| `renderParentInstructions` | `boolean` | `false` | When using nested instructions, whether the parent instructions should also be rendered. When set to `false` (default), only the instruction leaves are being rendered. |
|
|
49
|
+
| `traitOptions` | [`TraitOptions`](#trait-options) | `DEFAULT_TRAIT_OPTIONS` | A set of options that can be used to configure how traits are rendered for every Rust types. See [documentation below](#trait-options) for more information. |
|
|
50
|
+
| `anchorTraits` | `boolean` | `true` | Whether to generate Anchor traits `impl` for account types. |
|
|
51
|
+
| `syncCargoToml` | `boolean` | `false` | Whether to update the dependencies of the existing `Cargo.toml` — or create a new `Cargo.toml` when missing — at the crate folder provided as the first argument. |
|
|
50
52
|
|
|
51
53
|
## Trait Options
|
|
52
54
|
|
package/dist/index.node.cjs
CHANGED
|
@@ -6,6 +6,8 @@ var errors = require('@codama/errors');
|
|
|
6
6
|
var nodes = require('@codama/nodes');
|
|
7
7
|
var renderersCore = require('@codama/renderers-core');
|
|
8
8
|
var visitorsCore = require('@codama/visitors-core');
|
|
9
|
+
var toml = require('@iarna/toml');
|
|
10
|
+
var semver = require('semver');
|
|
9
11
|
var codecsStrings = require('@solana/codecs-strings');
|
|
10
12
|
var path = require('path');
|
|
11
13
|
require('url');
|
|
@@ -17,6 +19,7 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
17
19
|
var nunjucks__default = /*#__PURE__*/_interopDefault(nunjucks);
|
|
18
20
|
|
|
19
21
|
// src/ImportMap.ts
|
|
22
|
+
var RUST_CORE_IMPORTS = /* @__PURE__ */ new Set(["std", "crate", "super", "self", "core", "alloc", "clippy"]);
|
|
20
23
|
var DEFAULT_MODULE_MAP = {
|
|
21
24
|
generated: "crate::generated",
|
|
22
25
|
generatedAccounts: "crate::generated::accounts",
|
|
@@ -76,6 +79,10 @@ var ImportMap = class _ImportMap {
|
|
|
76
79
|
this._aliases.forEach((alias, i) => newImportMap.addAlias(resolveDependency(i), alias));
|
|
77
80
|
return newImportMap;
|
|
78
81
|
}
|
|
82
|
+
getExternalDependencies(dependencyMap) {
|
|
83
|
+
const resolvedMap = this.resolveDependencyMap(dependencyMap);
|
|
84
|
+
return new Set([...resolvedMap._imports].map((i) => i.split("::")[0]).filter((i) => !RUST_CORE_IMPORTS.has(i)));
|
|
85
|
+
}
|
|
79
86
|
toString(dependencies) {
|
|
80
87
|
const resolvedMap = this.resolveDependencyMap(dependencies);
|
|
81
88
|
const importStatements = [...resolvedMap.imports].map((i) => {
|
|
@@ -86,6 +93,254 @@ var ImportMap = class _ImportMap {
|
|
|
86
93
|
return importStatements.join("\n");
|
|
87
94
|
}
|
|
88
95
|
};
|
|
96
|
+
var DEFAULT_DEPENDENCY_VERSIONS = {
|
|
97
|
+
"anchor-lang": { optional: true, version: "~0.31" },
|
|
98
|
+
borsh: "^0.10",
|
|
99
|
+
kaigan: { features: ["serde"], version: "^0.3" },
|
|
100
|
+
"num-derive": "^0.4",
|
|
101
|
+
"num-traits": "^0.2",
|
|
102
|
+
serde: { features: ["derive"], optional: true, version: "^1.0" },
|
|
103
|
+
"serde-big-array": "^0.5",
|
|
104
|
+
serde_with: { optional: true, version: "^3.0" },
|
|
105
|
+
"solana-account": "~2.2",
|
|
106
|
+
"solana-account-info": "~2.3",
|
|
107
|
+
"solana-client": { optional: true, version: "^2.2" },
|
|
108
|
+
"solana-cpi": "~2.2",
|
|
109
|
+
"solana-decode-error": "~2.3",
|
|
110
|
+
"solana-instruction": "~2.3",
|
|
111
|
+
"solana-program-error": "~2.2",
|
|
112
|
+
"solana-pubkey": { features: ["curve25519", "borsh"], version: "~2.3" },
|
|
113
|
+
"solana-sdk": { optional: true, version: "^2.3" },
|
|
114
|
+
thiserror: "^1.0"
|
|
115
|
+
};
|
|
116
|
+
function syncCargoToml(renderMap, crateFolder, options) {
|
|
117
|
+
const shouldSyncCargoToml = options.syncCargoToml ?? false;
|
|
118
|
+
const cargoTomlPath = renderersCore.joinPath(crateFolder, "Cargo.toml");
|
|
119
|
+
const usedDependencies = getUsedDependencyVersions(
|
|
120
|
+
renderMap,
|
|
121
|
+
options.dependencyMap ?? {},
|
|
122
|
+
options.dependencyVersions ?? {}
|
|
123
|
+
);
|
|
124
|
+
if (!shouldSyncCargoToml) {
|
|
125
|
+
if (renderersCore.fileExists(cargoTomlPath)) {
|
|
126
|
+
checkExistingCargoToml(readCargoToml(cargoTomlPath), usedDependencies);
|
|
127
|
+
}
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
if (renderersCore.fileExists(cargoTomlPath)) {
|
|
131
|
+
const cargoToml = updateExistingCargoToml(readCargoToml(cargoTomlPath), usedDependencies);
|
|
132
|
+
renderersCore.writeFile(cargoTomlPath, toml.stringify(cargoToml) + "\n");
|
|
133
|
+
} else {
|
|
134
|
+
const cargoToml = createNewCargoToml(usedDependencies);
|
|
135
|
+
renderersCore.writeFile(cargoTomlPath, toml.stringify(cargoToml) + "\n");
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
function createNewCargoToml(usedDependencies) {
|
|
139
|
+
return updateExistingCargoToml(
|
|
140
|
+
{
|
|
141
|
+
name: "rust-client",
|
|
142
|
+
// eslint-disable-next-line sort-keys-fix/sort-keys-fix
|
|
143
|
+
description: "",
|
|
144
|
+
version: "1.0.0",
|
|
145
|
+
// eslint-disable-next-line sort-keys-fix/sort-keys-fix
|
|
146
|
+
repository: { workspace: true },
|
|
147
|
+
// eslint-disable-next-line sort-keys-fix/sort-keys-fix
|
|
148
|
+
edition: { workspace: true },
|
|
149
|
+
license: { workspace: true },
|
|
150
|
+
// eslint-disable-next-line sort-keys-fix/sort-keys-fix
|
|
151
|
+
features: {
|
|
152
|
+
anchor: ["dep:anchor-lang"],
|
|
153
|
+
"anchor-idl-build": ["anchor", "anchor-lang?/idl-build"],
|
|
154
|
+
fetch: ["dep:solana-client", "dep:solana-sdk"],
|
|
155
|
+
serde: ["dep:serde", "dep:serde_with"]
|
|
156
|
+
},
|
|
157
|
+
// eslint-disable-next-line sort-keys-fix/sort-keys-fix
|
|
158
|
+
dependencies: {}
|
|
159
|
+
},
|
|
160
|
+
usedDependencies
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
function updateExistingCargoToml(cargoToml, usedDependencies) {
|
|
164
|
+
const foundUsedDependencies = /* @__PURE__ */ new Set();
|
|
165
|
+
const updatedCargoToml = updateCargoDependencies(cargoToml, (dependencyGroup) => {
|
|
166
|
+
return Object.fromEntries(
|
|
167
|
+
Object.entries(dependencyGroup).map(([dependencyKey, dependency]) => {
|
|
168
|
+
const foundUsedDependency = findCargoDependencyByImportName(
|
|
169
|
+
usedDependencies,
|
|
170
|
+
getCargoDependencyImportName(dependencyKey)
|
|
171
|
+
);
|
|
172
|
+
if (!foundUsedDependency) {
|
|
173
|
+
return [dependencyKey, dependency];
|
|
174
|
+
}
|
|
175
|
+
const [usedDependencyKey, usedDependency] = foundUsedDependency;
|
|
176
|
+
foundUsedDependencies.add(usedDependencyKey);
|
|
177
|
+
const usedDependencyCrateName = getCargoDependencyCrateName(usedDependencyKey, usedDependency);
|
|
178
|
+
if (!shouldUpdateDependency(usedDependencyCrateName, dependency, usedDependency)) {
|
|
179
|
+
return [dependencyKey, dependency];
|
|
180
|
+
}
|
|
181
|
+
const newVersion = getCargoDependencyVersion(usedDependency);
|
|
182
|
+
return [
|
|
183
|
+
dependencyKey,
|
|
184
|
+
typeof dependency === "string" ? newVersion : { ...dependency, version: newVersion }
|
|
185
|
+
];
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
});
|
|
189
|
+
const usedDependenciesToAdd = Object.entries(usedDependencies).filter(
|
|
190
|
+
([usedDependencyKey]) => !foundUsedDependencies.has(usedDependencyKey)
|
|
191
|
+
);
|
|
192
|
+
for (const [usedDependencyKey, usedDependency] of usedDependenciesToAdd) {
|
|
193
|
+
updatedCargoToml.dependencies = updatedCargoToml.dependencies ?? {};
|
|
194
|
+
updatedCargoToml.dependencies[usedDependencyKey] = usedDependency;
|
|
195
|
+
}
|
|
196
|
+
return updatedCargoToml;
|
|
197
|
+
}
|
|
198
|
+
function checkExistingCargoToml(cargoToml, usedDependencies) {
|
|
199
|
+
const missingDependencies = [];
|
|
200
|
+
const dependenciesToUpdate = [];
|
|
201
|
+
const existingDependencies = {
|
|
202
|
+
...cargoToml["build-dependencies"],
|
|
203
|
+
...cargoToml["dev-dependencies"],
|
|
204
|
+
...cargoToml.dependencies,
|
|
205
|
+
...cargoToml.workspace?.dependencies,
|
|
206
|
+
...Object.values(cargoToml.target ?? {}).reduce((acc, target) => {
|
|
207
|
+
return {
|
|
208
|
+
...acc,
|
|
209
|
+
...target["build-dependencies"],
|
|
210
|
+
...target["dev-dependencies"],
|
|
211
|
+
...target.dependencies
|
|
212
|
+
};
|
|
213
|
+
}, {})
|
|
214
|
+
};
|
|
215
|
+
for (const [usedDependencyKey, usedDependency] of Object.entries(usedDependencies)) {
|
|
216
|
+
const foundExistingDependency = findCargoDependencyByImportName(
|
|
217
|
+
existingDependencies,
|
|
218
|
+
getCargoDependencyImportName(usedDependencyKey)
|
|
219
|
+
);
|
|
220
|
+
if (!foundExistingDependency) {
|
|
221
|
+
missingDependencies.push(usedDependencyKey);
|
|
222
|
+
} else if (shouldUpdateDependency(foundExistingDependency[0], foundExistingDependency[1], usedDependency)) {
|
|
223
|
+
dependenciesToUpdate.push(usedDependencyKey);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (missingDependencies.length === 0 && dependenciesToUpdate.length === 0) return;
|
|
227
|
+
const missingList = missingDependencies.map((d) => `- ${d} missing: ${getCargoDependencyVersion(usedDependencies[d])}
|
|
228
|
+
`).join("");
|
|
229
|
+
const outdatedList = dependenciesToUpdate.map(
|
|
230
|
+
(d) => `- ${d} outdated: ${getCargoDependencyVersion(existingDependencies[d])} -> ${getCargoDependencyVersion(usedDependencies[d])}
|
|
231
|
+
`
|
|
232
|
+
).join("");
|
|
233
|
+
errors.logWarn(
|
|
234
|
+
`The following dependencies in your \`Cargo.toml\` are out-of-date or missing:
|
|
235
|
+
${missingList}${outdatedList}`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
function getUsedDependencyVersions(renderMap, dependencyMap, dependencyVersions) {
|
|
239
|
+
const usedImportNames = getUsedImportNames(renderMap, dependencyMap);
|
|
240
|
+
const dependencyVersionsWithDefaults = {
|
|
241
|
+
...DEFAULT_DEPENDENCY_VERSIONS,
|
|
242
|
+
...dependencyVersions
|
|
243
|
+
};
|
|
244
|
+
const [usedDependencyVersion, missingDependencies] = [...usedImportNames].reduce(
|
|
245
|
+
([acc, missingDependencies2], usedImportName) => {
|
|
246
|
+
const usedDependency = findCargoDependencyByImportName(dependencyVersionsWithDefaults, usedImportName);
|
|
247
|
+
if (usedDependency) {
|
|
248
|
+
acc[usedDependency[0]] = usedDependency[1];
|
|
249
|
+
} else {
|
|
250
|
+
missingDependencies2.add(usedImportName);
|
|
251
|
+
}
|
|
252
|
+
return [acc, missingDependencies2];
|
|
253
|
+
},
|
|
254
|
+
[{}, /* @__PURE__ */ new Set()]
|
|
255
|
+
);
|
|
256
|
+
if (missingDependencies.size > 0) {
|
|
257
|
+
throw new errors.CodamaError(errors.CODAMA_ERROR__RENDERERS__MISSING_DEPENDENCY_VERSIONS, {
|
|
258
|
+
dependencies: [...missingDependencies],
|
|
259
|
+
message: "Please add these dependencies to the `dependencyVersions` option."
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
return usedDependencyVersion;
|
|
263
|
+
}
|
|
264
|
+
function getUsedImportNames(renderMap, dependencyMap) {
|
|
265
|
+
const fragments = [...renderMap.values()];
|
|
266
|
+
const fromImportMap = new ImportMap().mergeWith(...fragments.map(({ imports }) => imports)).getExternalDependencies(dependencyMap);
|
|
267
|
+
const PATH_REGEX = /\b(?:::)?([a-z_][a-z0-9_]*)(?:::[a-zA-Z0-9_]+)+/g;
|
|
268
|
+
const fromContent = fragments.flatMap(({ content }) => {
|
|
269
|
+
return [...content.matchAll(PATH_REGEX)].map((match) => match[1]).filter((crateName) => !RUST_CORE_IMPORTS.has(crateName));
|
|
270
|
+
});
|
|
271
|
+
return /* @__PURE__ */ new Set([...fromImportMap, ...fromContent]);
|
|
272
|
+
}
|
|
273
|
+
function shouldUpdateDependency(dependency, currentDependency, requiredDependency) {
|
|
274
|
+
const currentRange = getCargoDependencyVersion(currentDependency);
|
|
275
|
+
const requiredRange = getCargoDependencyVersion(requiredDependency);
|
|
276
|
+
return !!currentRange && !!requiredRange && shouldUpdateRange(dependency, currentRange, requiredRange);
|
|
277
|
+
}
|
|
278
|
+
function shouldUpdateRange(dependency, currentRange, requiredRange) {
|
|
279
|
+
currentRange = cargoToNpmSemver(currentRange);
|
|
280
|
+
requiredRange = cargoToNpmSemver(requiredRange);
|
|
281
|
+
try {
|
|
282
|
+
if (semver.subset(currentRange, requiredRange)) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
const minRequiredVersion = semver.minVersion(requiredRange);
|
|
286
|
+
const minCurrentVersion = semver.minVersion(currentRange);
|
|
287
|
+
if (!minCurrentVersion || !minRequiredVersion) {
|
|
288
|
+
throw new Error("Could not determine minimum versions.");
|
|
289
|
+
}
|
|
290
|
+
if (semver.lt(minCurrentVersion, minRequiredVersion)) {
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
return false;
|
|
294
|
+
} catch (error) {
|
|
295
|
+
console.warn(
|
|
296
|
+
`Could not parse the following ranges for dependency "${dependency}": [${currentRange}] and/or [${requiredRange}]. Caused by: ${error.message}`
|
|
297
|
+
);
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
function updateCargoDependencies(cargoToml, updateFn) {
|
|
302
|
+
const updatedCargoToml = JSON.parse(JSON.stringify(cargoToml));
|
|
303
|
+
const standardSections = ["dependencies", "dev-dependencies", "build-dependencies"];
|
|
304
|
+
for (const section of standardSections) {
|
|
305
|
+
if (updatedCargoToml[section]) {
|
|
306
|
+
updatedCargoToml[section] = updateFn(updatedCargoToml[section]);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (updatedCargoToml.target) {
|
|
310
|
+
for (const targetKey of Object.keys(updatedCargoToml.target)) {
|
|
311
|
+
for (const section of standardSections) {
|
|
312
|
+
if (updatedCargoToml.target[targetKey][section]) {
|
|
313
|
+
updatedCargoToml.target[targetKey][section] = updateFn(updatedCargoToml.target[targetKey][section]);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (updatedCargoToml.workspace?.dependencies) {
|
|
319
|
+
updatedCargoToml.workspace.dependencies = updateFn(updatedCargoToml.workspace.dependencies);
|
|
320
|
+
}
|
|
321
|
+
return updatedCargoToml;
|
|
322
|
+
}
|
|
323
|
+
function cargoToNpmSemver(cargoVersion) {
|
|
324
|
+
const version = cargoVersion.trim();
|
|
325
|
+
return /^\d+(\.\d+)?(\.\d+)?/.test(version) ? `^${version}` : version;
|
|
326
|
+
}
|
|
327
|
+
function getCargoDependencyVersion(dependency) {
|
|
328
|
+
return typeof dependency === "string" ? dependency : dependency.version;
|
|
329
|
+
}
|
|
330
|
+
function getCargoDependencyCrateName(key, dependency) {
|
|
331
|
+
return typeof dependency !== "string" && dependency.package ? dependency.package : key;
|
|
332
|
+
}
|
|
333
|
+
function getCargoDependencyImportName(key) {
|
|
334
|
+
return key.replace(/-/g, "_");
|
|
335
|
+
}
|
|
336
|
+
function findCargoDependencyByImportName(dependencies, importName) {
|
|
337
|
+
return Object.entries(dependencies).find(([key]) => {
|
|
338
|
+
return getCargoDependencyImportName(key) === importName;
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
function readCargoToml(path) {
|
|
342
|
+
return toml.parse(renderersCore.readFile(path));
|
|
343
|
+
}
|
|
89
344
|
function getBytesFromBytesValueNode(node) {
|
|
90
345
|
switch (node.encoding) {
|
|
91
346
|
case "utf8":
|
|
@@ -921,10 +1176,7 @@ function getRenderMapVisitor(options = {}) {
|
|
|
921
1176
|
});
|
|
922
1177
|
const hasVariableSeeds = pdaSeeds.filter(nodes.isNodeFilter("variablePdaSeedNode")).length > 0;
|
|
923
1178
|
const constantSeeds = seeds.filter(nodes.isNodeFilter("constantPdaSeedNode")).filter((seed) => !nodes.isNode(seed.value, "programIdValueNode"));
|
|
924
|
-
const
|
|
925
|
-
if (hasVariableSeeds) {
|
|
926
|
-
imports.mergeWith(seedsImports);
|
|
927
|
-
}
|
|
1179
|
+
const imports = typeManifest.imports.mergeWith(...hasVariableSeeds ? [seedsImports] : []).mergeWith(discriminatorConstants.imports).remove(`generatedAccounts::${nodes.pascalCase(node.name)}`);
|
|
928
1180
|
return renderersCore.createRenderMap(`accounts/${nodes.snakeCase(node.name)}.rs`, {
|
|
929
1181
|
content: render("accountsPage.njk", {
|
|
930
1182
|
account: node,
|
|
@@ -932,23 +1184,25 @@ function getRenderMapVisitor(options = {}) {
|
|
|
932
1184
|
constantSeeds,
|
|
933
1185
|
discriminatorConstants: discriminatorConstants.render,
|
|
934
1186
|
hasVariableSeeds,
|
|
935
|
-
imports: imports.
|
|
1187
|
+
imports: imports.toString(dependencyMap),
|
|
936
1188
|
pda,
|
|
937
1189
|
program,
|
|
938
1190
|
seeds,
|
|
939
1191
|
typeManifest
|
|
940
|
-
})
|
|
1192
|
+
}),
|
|
1193
|
+
imports
|
|
941
1194
|
});
|
|
942
1195
|
},
|
|
943
1196
|
visitDefinedType(node) {
|
|
944
1197
|
const typeManifest = visitorsCore.visit(node, typeManifestVisitor);
|
|
945
|
-
const imports = new ImportMap().mergeWithManifest(typeManifest);
|
|
1198
|
+
const imports = new ImportMap().mergeWithManifest(typeManifest).remove(`generatedTypes::${nodes.pascalCase(node.name)}`);
|
|
946
1199
|
return renderersCore.createRenderMap(`types/${nodes.snakeCase(node.name)}.rs`, {
|
|
947
1200
|
content: render("definedTypesPage.njk", {
|
|
948
1201
|
definedType: node,
|
|
949
|
-
imports: imports.
|
|
1202
|
+
imports: imports.toString(dependencyMap),
|
|
950
1203
|
typeManifest
|
|
951
|
-
})
|
|
1204
|
+
}),
|
|
1205
|
+
imports
|
|
952
1206
|
});
|
|
953
1207
|
},
|
|
954
1208
|
visitInstruction(node) {
|
|
@@ -1009,19 +1263,20 @@ function getRenderMapVisitor(options = {}) {
|
|
|
1009
1263
|
});
|
|
1010
1264
|
const typeManifest = visitorsCore.visit(struct, structVisitor);
|
|
1011
1265
|
const dataTraits = getTraitsFromNode2(node);
|
|
1012
|
-
imports.mergeWith(dataTraits.imports);
|
|
1266
|
+
imports.mergeWith(dataTraits.imports).mergeWith(discriminatorConstants.imports).remove(`generatedInstructions::${nodes.pascalCase(node.name)}`);
|
|
1013
1267
|
return renderersCore.createRenderMap(`instructions/${nodes.snakeCase(node.name)}.rs`, {
|
|
1014
1268
|
content: render("instructionsPage.njk", {
|
|
1015
1269
|
dataTraits: dataTraits.render,
|
|
1016
1270
|
discriminatorConstants: discriminatorConstants.render,
|
|
1017
1271
|
hasArgs,
|
|
1018
1272
|
hasOptional,
|
|
1019
|
-
imports: imports.
|
|
1273
|
+
imports: imports.toString(dependencyMap),
|
|
1020
1274
|
instruction: node,
|
|
1021
1275
|
instructionArgs,
|
|
1022
1276
|
program,
|
|
1023
1277
|
typeManifest
|
|
1024
|
-
})
|
|
1278
|
+
}),
|
|
1279
|
+
imports
|
|
1025
1280
|
});
|
|
1026
1281
|
},
|
|
1027
1282
|
visitProgram(node, { self }) {
|
|
@@ -1039,7 +1294,8 @@ function getRenderMapVisitor(options = {}) {
|
|
|
1039
1294
|
errors: node.errors,
|
|
1040
1295
|
imports: new ImportMap().toString(dependencyMap),
|
|
1041
1296
|
program: node
|
|
1042
|
-
})
|
|
1297
|
+
}),
|
|
1298
|
+
imports: new ImportMap()
|
|
1043
1299
|
});
|
|
1044
1300
|
}
|
|
1045
1301
|
program = null;
|
|
@@ -1063,13 +1319,13 @@ function getRenderMapVisitor(options = {}) {
|
|
|
1063
1319
|
};
|
|
1064
1320
|
return renderersCore.mergeRenderMaps([
|
|
1065
1321
|
renderersCore.createRenderMap({
|
|
1066
|
-
["accounts/mod.rs"]: accountsToExport.length > 0 ? { content: render("accountsMod.njk", ctx) } : void 0,
|
|
1067
|
-
["errors/mod.rs"]: programsToExport.length > 0 ? { content: render("errorsMod.njk", ctx) } : void 0,
|
|
1068
|
-
["instructions/mod.rs"]: instructionsToExport.length > 0 ? { content: render("instructionsMod.njk", ctx) } : void 0,
|
|
1069
|
-
["mod.rs"]: { content: render("rootMod.njk", ctx) },
|
|
1070
|
-
["programs.rs"]: programsToExport.length > 0 ? { content: render("programsMod.njk", ctx) } : void 0,
|
|
1071
|
-
["shared.rs"]: accountsToExport.length > 0 ? { content: render("sharedPage.njk", ctx) } : void 0,
|
|
1072
|
-
["types/mod.rs"]: definedTypesToExport.length > 0 ? { content: render("definedTypesMod.njk", ctx) } : void 0
|
|
1322
|
+
["accounts/mod.rs"]: accountsToExport.length > 0 ? { content: render("accountsMod.njk", ctx), imports: new ImportMap() } : void 0,
|
|
1323
|
+
["errors/mod.rs"]: programsToExport.length > 0 ? { content: render("errorsMod.njk", ctx), imports: new ImportMap() } : void 0,
|
|
1324
|
+
["instructions/mod.rs"]: instructionsToExport.length > 0 ? { content: render("instructionsMod.njk", ctx), imports: new ImportMap() } : void 0,
|
|
1325
|
+
["mod.rs"]: { content: render("rootMod.njk", ctx), imports: new ImportMap() },
|
|
1326
|
+
["programs.rs"]: programsToExport.length > 0 ? { content: render("programsMod.njk", ctx), imports: new ImportMap() } : void 0,
|
|
1327
|
+
["shared.rs"]: accountsToExport.length > 0 ? { content: render("sharedPage.njk", ctx), imports: new ImportMap() } : void 0,
|
|
1328
|
+
["types/mod.rs"]: definedTypesToExport.length > 0 ? { content: render("definedTypesMod.njk", ctx), imports: new ImportMap() } : void 0
|
|
1073
1329
|
}),
|
|
1074
1330
|
...nodes.getAllPrograms(node).map((p) => visitorsCore.visit(p, self))
|
|
1075
1331
|
]);
|
|
@@ -1087,24 +1343,21 @@ function getConflictsForInstructionAccountsAndArgs(instruction) {
|
|
|
1087
1343
|
const duplicates = allNames.filter((e, i, a) => a.indexOf(e) !== i);
|
|
1088
1344
|
return [...new Set(duplicates)];
|
|
1089
1345
|
}
|
|
1090
|
-
function renderVisitor(
|
|
1346
|
+
function renderVisitor(crateFolder, options = {}) {
|
|
1091
1347
|
return visitorsCore.rootNodeVisitor((root) => {
|
|
1348
|
+
const generatedFolder = renderersCore.joinPath(crateFolder, options.generatedFolder ?? "src/generated");
|
|
1092
1349
|
if (options.deleteFolderBeforeRendering ?? true) {
|
|
1093
|
-
renderersCore.deleteDirectory(
|
|
1350
|
+
renderersCore.deleteDirectory(generatedFolder);
|
|
1094
1351
|
}
|
|
1095
|
-
visitorsCore.visit(root,
|
|
1352
|
+
const renderMap = visitorsCore.visit(root, getRenderMapVisitor(options));
|
|
1353
|
+
renderersCore.writeRenderMap(renderMap, generatedFolder);
|
|
1354
|
+
syncCargoToml(renderMap, crateFolder, options);
|
|
1096
1355
|
if (options.formatCode) {
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
removeFalsy
|
|
1103
|
-
)
|
|
1104
|
-
);
|
|
1105
|
-
} else {
|
|
1106
|
-
errors.logWarn("No crate folder specified, skipping formatting.");
|
|
1107
|
-
}
|
|
1356
|
+
const removeFalsy = (arg) => Boolean(arg);
|
|
1357
|
+
runFormatter(
|
|
1358
|
+
"cargo",
|
|
1359
|
+
[options.toolchain, "fmt", "--manifest-path", `${crateFolder}/Cargo.toml`].filter(removeFalsy)
|
|
1360
|
+
);
|
|
1108
1361
|
}
|
|
1109
1362
|
});
|
|
1110
1363
|
}
|
|
@@ -1123,6 +1376,7 @@ function runFormatter(cmd, args) {
|
|
|
1123
1376
|
}
|
|
1124
1377
|
|
|
1125
1378
|
exports.ImportMap = ImportMap;
|
|
1379
|
+
exports.RUST_CORE_IMPORTS = RUST_CORE_IMPORTS;
|
|
1126
1380
|
exports.default = renderVisitor;
|
|
1127
1381
|
exports.getRenderMapVisitor = getRenderMapVisitor;
|
|
1128
1382
|
exports.getTypeManifestVisitor = getTypeManifestVisitor;
|