@caatinga/core 2.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{browser-djYObNl8.d.cts → browser-Cq4ZofIq.d.cts} +10 -1
- package/dist/{browser-djYObNl8.d.ts → browser-Cq4ZofIq.d.ts} +10 -1
- package/dist/browser.cjs +35 -0
- package/dist/browser.d.cts +1 -1
- package/dist/browser.d.ts +1 -1
- package/dist/browser.js +34 -0
- package/dist/index.cjs +328 -78
- package/dist/index.d.cts +95 -4
- package/dist/index.d.ts +95 -4
- package/dist/index.js +305 -64
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -27,6 +27,7 @@ var CaatingaErrorCode = {
|
|
|
27
27
|
DEPLOY_ARG_PLACEHOLDER_UNRESOLVED: "CAATINGA_DEPLOY_ARG_PLACEHOLDER_UNRESOLVED",
|
|
28
28
|
BINDING_CLIENT_NOT_FOUND: "CAATINGA_BINDING_CLIENT_NOT_FOUND",
|
|
29
29
|
BINDING_METHOD_NOT_FOUND: "CAATINGA_BINDING_METHOD_NOT_FOUND",
|
|
30
|
+
PLACEHOLDER_BINDING: "CAATINGA_PLACEHOLDER_BINDING",
|
|
30
31
|
XDR_BUILD_FAILED: "CAATINGA_XDR_BUILD_FAILED",
|
|
31
32
|
XDR_PREPARE_FAILED: "CAATINGA_XDR_PREPARE_FAILED",
|
|
32
33
|
XDR_SIGN_FAILED: "CAATINGA_XDR_SIGN_FAILED",
|
|
@@ -71,8 +72,40 @@ function toCaatingaError(error) {
|
|
|
71
72
|
return new CaatingaError("An unexpected error occurred.", CaatingaErrorCode.UNEXPECTED_ERROR);
|
|
72
73
|
}
|
|
73
74
|
|
|
75
|
+
// src/errors/format-caatinga-error.ts
|
|
76
|
+
function formatCaatingaError(error) {
|
|
77
|
+
if (error instanceof CaatingaError) {
|
|
78
|
+
const lines = [`[${error.code}] ${error.message}`];
|
|
79
|
+
if (error.hint) {
|
|
80
|
+
lines.push("", error.hint);
|
|
81
|
+
}
|
|
82
|
+
const detail = formatCause(error.cause);
|
|
83
|
+
if (detail) {
|
|
84
|
+
lines.push("", `Details: ${detail}`);
|
|
85
|
+
}
|
|
86
|
+
return lines.join("\n");
|
|
87
|
+
}
|
|
88
|
+
return error instanceof Error ? error.message : String(error);
|
|
89
|
+
}
|
|
90
|
+
function formatCause(cause) {
|
|
91
|
+
if (cause === void 0 || cause === null) {
|
|
92
|
+
return "";
|
|
93
|
+
}
|
|
94
|
+
if (cause instanceof Error) {
|
|
95
|
+
return cause.message;
|
|
96
|
+
}
|
|
97
|
+
if (typeof cause === "string") {
|
|
98
|
+
return cause;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
return JSON.stringify(cause);
|
|
102
|
+
} catch {
|
|
103
|
+
return String(cause);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
74
107
|
// src/version.ts
|
|
75
|
-
var CAATINGA_CORE_VERSION = "2.0
|
|
108
|
+
var CAATINGA_CORE_VERSION = "2.2.0";
|
|
76
109
|
|
|
77
110
|
// src/config/config.schema.ts
|
|
78
111
|
import { z } from "zod";
|
|
@@ -237,18 +270,6 @@ function updateArtifact(artifacts, networkName, contractName, contractArtifact,
|
|
|
237
270
|
};
|
|
238
271
|
}
|
|
239
272
|
|
|
240
|
-
// src/networks/networks.ts
|
|
241
|
-
var WELL_KNOWN_NETWORKS = {
|
|
242
|
-
testnet: {
|
|
243
|
-
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
244
|
-
networkPassphrase: "Test SDF Network ; September 2015"
|
|
245
|
-
},
|
|
246
|
-
mainnet: {
|
|
247
|
-
rpcUrl: "https://mainnet.sorobanrpc.com",
|
|
248
|
-
networkPassphrase: "Public Global Stellar Network ; September 2015"
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
|
|
252
273
|
// src/networks/resolve-network.ts
|
|
253
274
|
function resolveNetwork(config, networkName) {
|
|
254
275
|
const name = networkName ?? config.defaultNetwork;
|
|
@@ -263,6 +284,174 @@ function resolveNetwork(config, networkName) {
|
|
|
263
284
|
return { name, config: network };
|
|
264
285
|
}
|
|
265
286
|
|
|
287
|
+
// src/bindings/binding-freshness.ts
|
|
288
|
+
import { readdir } from "fs/promises";
|
|
289
|
+
import path5 from "path";
|
|
290
|
+
|
|
291
|
+
// src/bindings/binding-marker.ts
|
|
292
|
+
import { readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
|
|
293
|
+
import path4 from "path";
|
|
294
|
+
import { z as z5 } from "zod";
|
|
295
|
+
var BINDING_MARKER_FILENAME = ".caatinga-bindings.json";
|
|
296
|
+
var BindingMarkerSchema = z5.object({
|
|
297
|
+
version: z5.literal(1),
|
|
298
|
+
contractId: z5.string().min(1),
|
|
299
|
+
wasmHash: z5.string().min(1),
|
|
300
|
+
network: z5.string().min(1),
|
|
301
|
+
generatedAt: z5.string().datetime()
|
|
302
|
+
});
|
|
303
|
+
async function writeBindingMarker(outputDir, marker) {
|
|
304
|
+
const markerPath = path4.join(outputDir, BINDING_MARKER_FILENAME);
|
|
305
|
+
await writeFile2(markerPath, `${JSON.stringify(marker, null, 2)}
|
|
306
|
+
`, "utf8");
|
|
307
|
+
}
|
|
308
|
+
async function readBindingMarker(outputDir) {
|
|
309
|
+
const markerPath = path4.join(outputDir, BINDING_MARKER_FILENAME);
|
|
310
|
+
let raw;
|
|
311
|
+
try {
|
|
312
|
+
raw = await readFile2(markerPath, "utf8");
|
|
313
|
+
} catch {
|
|
314
|
+
return null;
|
|
315
|
+
}
|
|
316
|
+
try {
|
|
317
|
+
return BindingMarkerSchema.parse(JSON.parse(raw));
|
|
318
|
+
} catch {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// src/bindings/binding-freshness.ts
|
|
324
|
+
async function listGeneratedEntries(outputDir) {
|
|
325
|
+
try {
|
|
326
|
+
const entries = await readdir(outputDir);
|
|
327
|
+
return entries.filter((entry) => entry !== BINDING_MARKER_FILENAME);
|
|
328
|
+
} catch {
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
async function evaluateBindingFreshness(options) {
|
|
333
|
+
const cwd = options.cwd ?? process.cwd();
|
|
334
|
+
const outputDir = path5.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
335
|
+
const contractArtifact = options.artifacts.networks[options.networkName]?.contracts[options.contractName];
|
|
336
|
+
if (!contractArtifact) {
|
|
337
|
+
return {
|
|
338
|
+
contractName: options.contractName,
|
|
339
|
+
status: "missing",
|
|
340
|
+
outputDir,
|
|
341
|
+
marker: null,
|
|
342
|
+
reason: `not deployed on "${options.networkName}"`
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
const generatedEntries = await listGeneratedEntries(outputDir);
|
|
346
|
+
if (generatedEntries === null || generatedEntries.length === 0) {
|
|
347
|
+
return {
|
|
348
|
+
contractName: options.contractName,
|
|
349
|
+
status: "missing",
|
|
350
|
+
outputDir,
|
|
351
|
+
marker: null,
|
|
352
|
+
reason: "no generated bindings found"
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
const marker = await readBindingMarker(outputDir);
|
|
356
|
+
if (!marker) {
|
|
357
|
+
return {
|
|
358
|
+
contractName: options.contractName,
|
|
359
|
+
status: "unknown",
|
|
360
|
+
outputDir,
|
|
361
|
+
marker: null,
|
|
362
|
+
reason: "bindings exist but have no provenance marker \u2014 rerun caatinga generate to record it"
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
if (marker.contractId !== contractArtifact.contractId) {
|
|
366
|
+
return {
|
|
367
|
+
contractName: options.contractName,
|
|
368
|
+
status: "stale",
|
|
369
|
+
outputDir,
|
|
370
|
+
marker,
|
|
371
|
+
reason: "contractId changed since last generate"
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
if (marker.wasmHash !== contractArtifact.wasmHash) {
|
|
375
|
+
return {
|
|
376
|
+
contractName: options.contractName,
|
|
377
|
+
status: "stale",
|
|
378
|
+
outputDir,
|
|
379
|
+
marker,
|
|
380
|
+
reason: "wasmHash changed since last generate"
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
return {
|
|
384
|
+
contractName: options.contractName,
|
|
385
|
+
status: "fresh",
|
|
386
|
+
outputDir,
|
|
387
|
+
marker
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
async function evaluateBindingsFreshness(options) {
|
|
391
|
+
const contractNames = Object.keys(
|
|
392
|
+
options.artifacts.networks[options.networkName]?.contracts ?? {}
|
|
393
|
+
);
|
|
394
|
+
const results = [];
|
|
395
|
+
for (const contractName of contractNames) {
|
|
396
|
+
results.push(await evaluateBindingFreshness({ ...options, contractName }));
|
|
397
|
+
}
|
|
398
|
+
return results;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// src/artifacts/project-status.ts
|
|
402
|
+
async function collectProjectStatus(options) {
|
|
403
|
+
const cwd = options.cwd ?? process.cwd();
|
|
404
|
+
const artifacts = await readArtifacts(cwd);
|
|
405
|
+
let networkNames;
|
|
406
|
+
if (options.networkName) {
|
|
407
|
+
networkNames = [resolveNetwork(options.config, options.networkName).name];
|
|
408
|
+
} else {
|
|
409
|
+
const fromArtifacts = Object.keys(artifacts.networks);
|
|
410
|
+
const fallback = options.config.defaultNetwork ?? "testnet";
|
|
411
|
+
networkNames = fromArtifacts.length > 0 ? fromArtifacts : [fallback];
|
|
412
|
+
if (!networkNames.includes(fallback) && options.config.networks[fallback]) {
|
|
413
|
+
networkNames.push(fallback);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
const networks = [];
|
|
417
|
+
for (const networkName of networkNames) {
|
|
418
|
+
const contracts = [];
|
|
419
|
+
for (const name of Object.keys(options.config.contracts)) {
|
|
420
|
+
const artifact = artifacts.networks[networkName]?.contracts[name];
|
|
421
|
+
const bindings = await evaluateBindingFreshness({
|
|
422
|
+
config: options.config,
|
|
423
|
+
artifacts,
|
|
424
|
+
networkName,
|
|
425
|
+
contractName: name,
|
|
426
|
+
cwd
|
|
427
|
+
});
|
|
428
|
+
contracts.push({
|
|
429
|
+
name,
|
|
430
|
+
deployed: Boolean(artifact),
|
|
431
|
+
contractId: artifact?.contractId,
|
|
432
|
+
wasmHash: artifact?.wasmHash,
|
|
433
|
+
deployedAt: artifact?.deployedAt,
|
|
434
|
+
dependencies: artifact?.dependencies ?? options.config.contracts[name].dependsOn ?? [],
|
|
435
|
+
bindings
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
networks.push({ network: networkName, contracts });
|
|
439
|
+
}
|
|
440
|
+
return { project: options.config.project, networks };
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/networks/networks.ts
|
|
444
|
+
var WELL_KNOWN_NETWORKS = {
|
|
445
|
+
testnet: {
|
|
446
|
+
rpcUrl: "https://soroban-testnet.stellar.org",
|
|
447
|
+
networkPassphrase: "Test SDF Network ; September 2015"
|
|
448
|
+
},
|
|
449
|
+
mainnet: {
|
|
450
|
+
rpcUrl: "https://mainnet.sorobanrpc.com",
|
|
451
|
+
networkPassphrase: "Public Global Stellar Network ; September 2015"
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
|
|
266
455
|
// src/shell/run-command.ts
|
|
267
456
|
import { execa } from "execa";
|
|
268
457
|
|
|
@@ -584,7 +773,7 @@ function validateSourceShape(source) {
|
|
|
584
773
|
}
|
|
585
774
|
|
|
586
775
|
// src/contracts/resolve-contract.ts
|
|
587
|
-
import
|
|
776
|
+
import path6 from "path";
|
|
588
777
|
function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
589
778
|
const contract = config.contracts[contractName];
|
|
590
779
|
if (!contract) {
|
|
@@ -597,15 +786,15 @@ function resolveContract(config, contractName, cwd = process.cwd()) {
|
|
|
597
786
|
return {
|
|
598
787
|
name: contractName,
|
|
599
788
|
config: contract,
|
|
600
|
-
sourcePath:
|
|
601
|
-
wasmPath:
|
|
789
|
+
sourcePath: path6.resolve(cwd, contract.path),
|
|
790
|
+
wasmPath: path6.resolve(cwd, contract.wasm)
|
|
602
791
|
};
|
|
603
792
|
}
|
|
604
793
|
|
|
605
794
|
// src/contracts/wasm.ts
|
|
606
795
|
import { createHash } from "crypto";
|
|
607
|
-
import { access as access2, readdir, readFile as
|
|
608
|
-
import
|
|
796
|
+
import { access as access2, readdir as readdir2, readFile as readFile3, stat } from "fs/promises";
|
|
797
|
+
import path7 from "path";
|
|
609
798
|
var LEGACY_RUST_WASM_TARGET = "wasm32-unknown-unknown";
|
|
610
799
|
var CURRENT_RUST_WASM_TARGET = "wasm32v1-none";
|
|
611
800
|
function toCurrentWasmTargetPath(wasmPath) {
|
|
@@ -628,8 +817,8 @@ function wasmNotFoundError(configuredWasmPath, options) {
|
|
|
628
817
|
);
|
|
629
818
|
}
|
|
630
819
|
function toConfigRelativeWasmPath(absoluteWasmPath) {
|
|
631
|
-
const relative =
|
|
632
|
-
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(
|
|
820
|
+
const relative = path7.relative(process.cwd(), absoluteWasmPath);
|
|
821
|
+
return relative.startsWith("..") ? absoluteWasmPath : `./${relative.split(path7.sep).join("/")}`;
|
|
633
822
|
}
|
|
634
823
|
async function resolveWasmArtifactPath(configuredWasmPath) {
|
|
635
824
|
try {
|
|
@@ -649,7 +838,7 @@ async function resolveWasmArtifactPath(configuredWasmPath) {
|
|
|
649
838
|
}
|
|
650
839
|
}
|
|
651
840
|
async function hashWasm(wasmPath) {
|
|
652
|
-
const bytes = await
|
|
841
|
+
const bytes = await readFile3(wasmPath);
|
|
653
842
|
return createHash("sha256").update(bytes).digest("hex");
|
|
654
843
|
}
|
|
655
844
|
async function getNewestMtimeInDirectory(directory) {
|
|
@@ -660,9 +849,9 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
660
849
|
}
|
|
661
850
|
let newest = 0;
|
|
662
851
|
async function walk(dir) {
|
|
663
|
-
const entries = await
|
|
852
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
664
853
|
for (const entry of entries) {
|
|
665
|
-
const entryPath =
|
|
854
|
+
const entryPath = path7.join(dir, entry.name);
|
|
666
855
|
if (entry.isDirectory()) {
|
|
667
856
|
await walk(entryPath);
|
|
668
857
|
continue;
|
|
@@ -678,7 +867,7 @@ async function getNewestMtimeInDirectory(directory) {
|
|
|
678
867
|
return newest > 0 ? newest : void 0;
|
|
679
868
|
}
|
|
680
869
|
async function isWasmOlderThanSources(input) {
|
|
681
|
-
const srcDir =
|
|
870
|
+
const srcDir = path7.join(input.contractPath, "src");
|
|
682
871
|
const newestSourceMtime = await getNewestMtimeInDirectory(srcDir);
|
|
683
872
|
if (newestSourceMtime === void 0) {
|
|
684
873
|
return false;
|
|
@@ -751,7 +940,7 @@ async function buildContract(options) {
|
|
|
751
940
|
}
|
|
752
941
|
|
|
753
942
|
// src/contracts/deploy-contract.ts
|
|
754
|
-
import
|
|
943
|
+
import path8 from "path";
|
|
755
944
|
|
|
756
945
|
// src/contracts/dependency-graph.ts
|
|
757
946
|
function buildDependencyGraph(contracts) {
|
|
@@ -852,7 +1041,7 @@ async function deployContract(options) {
|
|
|
852
1041
|
contract: contractWithWasm,
|
|
853
1042
|
network,
|
|
854
1043
|
contractId: existing.contractId,
|
|
855
|
-
artifactsPath:
|
|
1044
|
+
artifactsPath: path8.resolve(cwd, "caatinga.artifacts.json"),
|
|
856
1045
|
output: "",
|
|
857
1046
|
skipped: true,
|
|
858
1047
|
staleWasmWarning
|
|
@@ -1129,13 +1318,13 @@ async function deployContractGraph(options) {
|
|
|
1129
1318
|
|
|
1130
1319
|
// src/contracts/generate-bindings.ts
|
|
1131
1320
|
import { access as access3, mkdir as mkdir2, unlink } from "fs/promises";
|
|
1132
|
-
import
|
|
1321
|
+
import path9 from "path";
|
|
1133
1322
|
function toBindingImportPath(bindingsOutput, contractName) {
|
|
1134
|
-
const normalized = bindingsOutput.replace(/^\.\//, "").split(
|
|
1135
|
-
return `./${
|
|
1323
|
+
const normalized = bindingsOutput.replace(/^\.\//, "").split(path9.sep).join("/");
|
|
1324
|
+
return `./${path9.posix.join(normalized, contractName, "src", "index.js")}`;
|
|
1136
1325
|
}
|
|
1137
1326
|
async function removeLegacyBindingStub(cwd, bindingsOutput, contractName) {
|
|
1138
|
-
const legacyPath =
|
|
1327
|
+
const legacyPath = path9.resolve(cwd, bindingsOutput, `${contractName}.ts`);
|
|
1139
1328
|
try {
|
|
1140
1329
|
await access3(legacyPath);
|
|
1141
1330
|
await unlink(legacyPath);
|
|
@@ -1157,7 +1346,7 @@ async function generateBindings(options) {
|
|
|
1157
1346
|
);
|
|
1158
1347
|
}
|
|
1159
1348
|
await checkBinary("stellar", "Install Stellar CLI before running caatinga generate.");
|
|
1160
|
-
const outputDir =
|
|
1349
|
+
const outputDir = path9.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
|
|
1161
1350
|
await mkdir2(outputDir, { recursive: true });
|
|
1162
1351
|
const result = await runCommand("stellar", [
|
|
1163
1352
|
"contract",
|
|
@@ -1178,16 +1367,59 @@ async function generateBindings(options) {
|
|
|
1178
1367
|
options.config.frontend.bindingsOutput,
|
|
1179
1368
|
options.contractName
|
|
1180
1369
|
);
|
|
1370
|
+
const marker = {
|
|
1371
|
+
version: 1,
|
|
1372
|
+
contractId: contractArtifact.contractId,
|
|
1373
|
+
wasmHash: contractArtifact.wasmHash,
|
|
1374
|
+
network: network.name,
|
|
1375
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1376
|
+
};
|
|
1377
|
+
await writeBindingMarker(outputDir, marker);
|
|
1181
1378
|
return {
|
|
1182
1379
|
contractName: options.contractName,
|
|
1183
1380
|
network,
|
|
1184
1381
|
outputDir,
|
|
1185
1382
|
importPath: toBindingImportPath(options.config.frontend.bindingsOutput, options.contractName),
|
|
1186
1383
|
legacyStubRemoved,
|
|
1384
|
+
marker,
|
|
1187
1385
|
output: result.all || result.stdout
|
|
1188
1386
|
};
|
|
1189
1387
|
}
|
|
1190
1388
|
|
|
1389
|
+
// src/contracts/generate-bindings-graph.ts
|
|
1390
|
+
async function generateBindingsGraph(options) {
|
|
1391
|
+
const cwd = options.cwd ?? process.cwd();
|
|
1392
|
+
const network = resolveNetwork(options.config, options.networkName);
|
|
1393
|
+
let targets;
|
|
1394
|
+
if (options.contractName) {
|
|
1395
|
+
targets = [options.contractName];
|
|
1396
|
+
} else if (options.contractNames && options.contractNames.length > 0) {
|
|
1397
|
+
targets = options.contractNames;
|
|
1398
|
+
} else {
|
|
1399
|
+
const artifacts = await readArtifacts(cwd);
|
|
1400
|
+
targets = Object.keys(artifacts.networks[network.name]?.contracts ?? {});
|
|
1401
|
+
if (targets.length === 0) {
|
|
1402
|
+
throw new CaatingaError(
|
|
1403
|
+
`No deployed contracts found on "${network.name}".`,
|
|
1404
|
+
CaatingaErrorCode.ARTIFACT_NOT_FOUND,
|
|
1405
|
+
"Run caatinga deploy before generating bindings, or pass a contract name."
|
|
1406
|
+
);
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
const results = [];
|
|
1410
|
+
for (const contractName of targets) {
|
|
1411
|
+
results.push(
|
|
1412
|
+
await generateBindings({
|
|
1413
|
+
config: options.config,
|
|
1414
|
+
contractName,
|
|
1415
|
+
networkName: network.name,
|
|
1416
|
+
cwd
|
|
1417
|
+
})
|
|
1418
|
+
);
|
|
1419
|
+
}
|
|
1420
|
+
return { network, results };
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1191
1423
|
// src/contracts/invoke-contract.ts
|
|
1192
1424
|
var INVOKE_SIGNING_FAILURE_REGEX = /xdr processing error: xdr value invalid/i;
|
|
1193
1425
|
function parseInvokeTarget(target) {
|
|
@@ -1260,33 +1492,33 @@ ${error.hint ?? ""}`)) {
|
|
|
1260
1492
|
}
|
|
1261
1493
|
|
|
1262
1494
|
// src/templates/create-project-from-template.ts
|
|
1263
|
-
import { cp, mkdir as mkdir3, readFile as
|
|
1264
|
-
import
|
|
1265
|
-
import { z as
|
|
1495
|
+
import { cp, mkdir as mkdir3, readFile as readFile4, readdir as readdir3, stat as stat2, writeFile as writeFile3 } from "fs/promises";
|
|
1496
|
+
import path10 from "path";
|
|
1497
|
+
import { z as z7 } from "zod";
|
|
1266
1498
|
|
|
1267
1499
|
// src/templates/template-manifest.schema.ts
|
|
1268
|
-
import { z as
|
|
1500
|
+
import { z as z6 } from "zod";
|
|
1269
1501
|
import semver3 from "semver";
|
|
1270
1502
|
var CURRENT_TEMPLATE_VERSION = 1;
|
|
1271
|
-
var TemplateManifestSchema =
|
|
1272
|
-
name:
|
|
1273
|
-
version:
|
|
1274
|
-
description:
|
|
1275
|
-
caatinga:
|
|
1276
|
-
compatibleCore:
|
|
1277
|
-
templateVersion:
|
|
1503
|
+
var TemplateManifestSchema = z6.object({
|
|
1504
|
+
name: z6.string().min(1),
|
|
1505
|
+
version: z6.string().min(1),
|
|
1506
|
+
description: z6.string().optional(),
|
|
1507
|
+
caatinga: z6.object({
|
|
1508
|
+
compatibleCore: z6.string().min(1),
|
|
1509
|
+
templateVersion: z6.number().int().positive()
|
|
1278
1510
|
}),
|
|
1279
|
-
frontend:
|
|
1280
|
-
framework:
|
|
1281
|
-
packageManager:
|
|
1511
|
+
frontend: z6.object({
|
|
1512
|
+
framework: z6.enum(["vite-react", "next", "astro"]),
|
|
1513
|
+
packageManager: z6.enum(["npm", "pnpm", "yarn", "bun"]).default("npm")
|
|
1282
1514
|
}),
|
|
1283
|
-
contracts:
|
|
1284
|
-
path:
|
|
1285
|
-
default:
|
|
1515
|
+
contracts: z6.object({
|
|
1516
|
+
path: z6.string(),
|
|
1517
|
+
default: z6.string().optional()
|
|
1286
1518
|
}),
|
|
1287
|
-
files:
|
|
1288
|
-
config:
|
|
1289
|
-
artifacts:
|
|
1519
|
+
files: z6.object({
|
|
1520
|
+
config: z6.string().default("caatinga.config.ts"),
|
|
1521
|
+
artifacts: z6.string().default("caatinga.artifacts.json")
|
|
1290
1522
|
})
|
|
1291
1523
|
});
|
|
1292
1524
|
function defaultCompatibleCoreRange(coreVersion = CAATINGA_CORE_VERSION) {
|
|
@@ -1337,8 +1569,8 @@ var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set([
|
|
|
1337
1569
|
".git"
|
|
1338
1570
|
]);
|
|
1339
1571
|
async function createProjectFromTemplate(options) {
|
|
1340
|
-
const targetDir =
|
|
1341
|
-
const templateDir =
|
|
1572
|
+
const targetDir = path10.resolve(options.targetDir);
|
|
1573
|
+
const templateDir = path10.resolve(options.templateDir);
|
|
1342
1574
|
try {
|
|
1343
1575
|
await stat2(templateDir);
|
|
1344
1576
|
} catch {
|
|
@@ -1373,9 +1605,9 @@ async function ensureArtifacts(targetDir, projectName) {
|
|
|
1373
1605
|
}
|
|
1374
1606
|
}
|
|
1375
1607
|
async function readTemplateManifest(templateDir) {
|
|
1376
|
-
const manifestPath =
|
|
1608
|
+
const manifestPath = path10.join(templateDir, "caatinga.template.json");
|
|
1377
1609
|
try {
|
|
1378
|
-
const rawManifest = await
|
|
1610
|
+
const rawManifest = await readFile4(manifestPath, "utf8");
|
|
1379
1611
|
const manifest = TemplateManifestSchema.parse(JSON.parse(rawManifest));
|
|
1380
1612
|
const compatibilityIssue = getTemplateCompatibilityIssue(manifest);
|
|
1381
1613
|
if (compatibilityIssue) {
|
|
@@ -1397,7 +1629,7 @@ async function readTemplateManifest(templateDir) {
|
|
|
1397
1629
|
if (error instanceof CaatingaError) {
|
|
1398
1630
|
throw error;
|
|
1399
1631
|
}
|
|
1400
|
-
if (error instanceof SyntaxError || error instanceof
|
|
1632
|
+
if (error instanceof SyntaxError || error instanceof z7.ZodError) {
|
|
1401
1633
|
throw new CaatingaError(
|
|
1402
1634
|
"Template manifest is invalid.",
|
|
1403
1635
|
CaatingaErrorCode.INVALID_TEMPLATE_MANIFEST,
|
|
@@ -1408,9 +1640,9 @@ async function readTemplateManifest(templateDir) {
|
|
|
1408
1640
|
}
|
|
1409
1641
|
}
|
|
1410
1642
|
async function replaceTemplateVariables(dir, projectName) {
|
|
1411
|
-
const entries = await
|
|
1643
|
+
const entries = await readdir3(dir);
|
|
1412
1644
|
await Promise.all(entries.map(async (entry) => {
|
|
1413
|
-
const entryPath =
|
|
1645
|
+
const entryPath = path10.join(dir, entry);
|
|
1414
1646
|
const entryStat = await stat2(entryPath);
|
|
1415
1647
|
if (entryStat.isDirectory()) {
|
|
1416
1648
|
await replaceTemplateVariables(entryPath, projectName);
|
|
@@ -1419,16 +1651,16 @@ async function replaceTemplateVariables(dir, projectName) {
|
|
|
1419
1651
|
if (!isTextTemplateFile(entryPath)) {
|
|
1420
1652
|
return;
|
|
1421
1653
|
}
|
|
1422
|
-
const content = await
|
|
1423
|
-
await
|
|
1654
|
+
const content = await readFile4(entryPath, "utf8");
|
|
1655
|
+
await writeFile3(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
|
|
1424
1656
|
}));
|
|
1425
1657
|
}
|
|
1426
1658
|
function shouldCopyTemplateEntry(templateDir, source) {
|
|
1427
|
-
const relativePath =
|
|
1659
|
+
const relativePath = path10.relative(templateDir, source);
|
|
1428
1660
|
if (!relativePath || relativePath === ".") {
|
|
1429
1661
|
return true;
|
|
1430
1662
|
}
|
|
1431
|
-
return !relativePath.split(
|
|
1663
|
+
return !relativePath.split(path10.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
|
|
1432
1664
|
}
|
|
1433
1665
|
function isTextTemplateFile(filePath) {
|
|
1434
1666
|
return [
|
|
@@ -1440,7 +1672,7 @@ function isTextTemplateFile(filePath) {
|
|
|
1440
1672
|
".tsx",
|
|
1441
1673
|
".css",
|
|
1442
1674
|
".html"
|
|
1443
|
-
].includes(
|
|
1675
|
+
].includes(path10.extname(filePath));
|
|
1444
1676
|
}
|
|
1445
1677
|
|
|
1446
1678
|
// src/ci/is-transient-testnet-smoke-failure.ts
|
|
@@ -1464,6 +1696,8 @@ function isTransientTestnetSmokeFailure(logText) {
|
|
|
1464
1696
|
return TRANSIENT_PATTERN.test(logText);
|
|
1465
1697
|
}
|
|
1466
1698
|
export {
|
|
1699
|
+
BINDING_MARKER_FILENAME,
|
|
1700
|
+
BindingMarkerSchema,
|
|
1467
1701
|
CAATINGA_CORE_VERSION,
|
|
1468
1702
|
CaatingaArtifactsSchema,
|
|
1469
1703
|
CaatingaConfigSchema,
|
|
@@ -1477,13 +1711,18 @@ export {
|
|
|
1477
1711
|
buildDependencyGraph,
|
|
1478
1712
|
checkBinary,
|
|
1479
1713
|
checkStellarCliVersion,
|
|
1714
|
+
collectProjectStatus,
|
|
1480
1715
|
createInitialArtifacts,
|
|
1481
1716
|
createProjectFromTemplate,
|
|
1482
1717
|
defineConfig,
|
|
1483
1718
|
deployContract,
|
|
1484
1719
|
deployContractGraph,
|
|
1720
|
+
evaluateBindingFreshness,
|
|
1721
|
+
evaluateBindingsFreshness,
|
|
1485
1722
|
evaluateStellarCliCompatibility,
|
|
1723
|
+
formatCaatingaError,
|
|
1486
1724
|
generateBindings,
|
|
1725
|
+
generateBindingsGraph,
|
|
1487
1726
|
invokeContract,
|
|
1488
1727
|
isTransientTestnetSmokeFailure,
|
|
1489
1728
|
loadConfig,
|
|
@@ -1491,6 +1730,7 @@ export {
|
|
|
1491
1730
|
parseInvokeTarget,
|
|
1492
1731
|
parseStellarCliVersion,
|
|
1493
1732
|
readArtifacts,
|
|
1733
|
+
readBindingMarker,
|
|
1494
1734
|
resolveContract,
|
|
1495
1735
|
resolveDeployArgs,
|
|
1496
1736
|
resolveDeployOrder,
|
|
@@ -1499,5 +1739,6 @@ export {
|
|
|
1499
1739
|
toCaatingaError,
|
|
1500
1740
|
updateArtifact,
|
|
1501
1741
|
validateSourceShape,
|
|
1502
|
-
writeArtifacts
|
|
1742
|
+
writeArtifacts,
|
|
1743
|
+
writeBindingMarker
|
|
1503
1744
|
};
|