@caatinga/core 3.1.0 → 3.1.2

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.
Files changed (3) hide show
  1. package/dist/index.cjs +150 -56
  2. package/dist/index.js +140 -46
  3. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1608,8 +1608,101 @@ async function deployContractGraph(options) {
1608
1608
  }
1609
1609
 
1610
1610
  // src/contracts/generate-bindings.ts
1611
+ var import_promises8 = require("fs/promises");
1612
+ var import_node_path11 = __toESM(require("path"), 1);
1613
+
1614
+ // src/bindings/patch-generated-binding-package.ts
1611
1615
  var import_promises7 = require("fs/promises");
1612
1616
  var import_node_path10 = __toESM(require("path"), 1);
1617
+ var BUNDLER_ENTRY = "./src/index.ts";
1618
+ var ROOT_BINDING_INDEX_CONTENT = 'export * from "./src/index.js";\n';
1619
+ function resolveExportEntry(exportsField) {
1620
+ if (!exportsField) {
1621
+ return void 0;
1622
+ }
1623
+ const rootExport = exportsField["."];
1624
+ if (typeof rootExport === "string") {
1625
+ return rootExport;
1626
+ }
1627
+ if (rootExport && typeof rootExport === "object" && !Array.isArray(rootExport)) {
1628
+ const conditions = rootExport;
1629
+ for (const key of ["import", "default", "types"]) {
1630
+ const value = conditions[key];
1631
+ if (typeof value === "string") {
1632
+ return value;
1633
+ }
1634
+ }
1635
+ }
1636
+ return void 0;
1637
+ }
1638
+ function pointsToDist(main) {
1639
+ return typeof main === "string" && main.replace(/^\.\//, "").startsWith("dist/");
1640
+ }
1641
+ function pointsToBundlerSource(entry) {
1642
+ return entry === BUNDLER_ENTRY || entry === "./src/index.js";
1643
+ }
1644
+ function shouldPatchPackageJson(packageJson) {
1645
+ const exportEntry = resolveExportEntry(
1646
+ typeof packageJson.exports === "object" && packageJson.exports !== null && !Array.isArray(packageJson.exports) ? packageJson.exports : void 0
1647
+ );
1648
+ return pointsToDist(packageJson.main) || pointsToDist(packageJson.types) || !pointsToBundlerSource(exportEntry);
1649
+ }
1650
+ async function ensureRootBindingIndex(outputDir) {
1651
+ const rootIndexPath = import_node_path10.default.join(outputDir, "index.ts");
1652
+ try {
1653
+ const existing = await (0, import_promises7.readFile)(rootIndexPath, "utf8");
1654
+ if (existing === ROOT_BINDING_INDEX_CONTENT) {
1655
+ return;
1656
+ }
1657
+ return;
1658
+ } catch {
1659
+ await (0, import_promises7.writeFile)(rootIndexPath, ROOT_BINDING_INDEX_CONTENT, "utf8");
1660
+ }
1661
+ }
1662
+ async function patchGeneratedBindingPackage(outputDir) {
1663
+ const packageJsonPath = import_node_path10.default.join(outputDir, "package.json");
1664
+ const entryPath = import_node_path10.default.join(outputDir, "src", "index.ts");
1665
+ try {
1666
+ await (0, import_promises7.access)(entryPath);
1667
+ } catch {
1668
+ throw new CaatingaError(
1669
+ "Generated binding package is missing src/index.ts.",
1670
+ CaatingaErrorCode.BINDINGS_FAILED,
1671
+ "Re-run caatinga generate or check @stellar/stellar-sdk generate output."
1672
+ );
1673
+ }
1674
+ let raw;
1675
+ try {
1676
+ raw = await (0, import_promises7.readFile)(packageJsonPath, "utf8");
1677
+ } catch {
1678
+ throw new CaatingaError(
1679
+ "Generated binding package is missing package.json.",
1680
+ CaatingaErrorCode.BINDINGS_FAILED,
1681
+ "Re-run caatinga generate or check @stellar/stellar-sdk generate output."
1682
+ );
1683
+ }
1684
+ let packageJson;
1685
+ try {
1686
+ packageJson = JSON.parse(raw);
1687
+ } catch {
1688
+ throw new CaatingaError(
1689
+ "Generated binding package.json is not valid JSON.",
1690
+ CaatingaErrorCode.BINDINGS_FAILED,
1691
+ "Re-run caatinga generate or check @stellar/stellar-sdk generate output."
1692
+ );
1693
+ }
1694
+ if (shouldPatchPackageJson(packageJson)) {
1695
+ packageJson.main = BUNDLER_ENTRY;
1696
+ packageJson.types = BUNDLER_ENTRY;
1697
+ packageJson.exports = {
1698
+ ...typeof packageJson.exports === "object" && packageJson.exports !== null && !Array.isArray(packageJson.exports) ? packageJson.exports : {},
1699
+ ".": BUNDLER_ENTRY
1700
+ };
1701
+ await (0, import_promises7.writeFile)(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
1702
+ `, "utf8");
1703
+ }
1704
+ await ensureRootBindingIndex(outputDir);
1705
+ }
1613
1706
 
1614
1707
  // src/contracts/build-generate-network-args.ts
1615
1708
  function buildGenerateNetworkArgs(network) {
@@ -1621,14 +1714,14 @@ function buildGenerateNetworkArgs(network) {
1621
1714
 
1622
1715
  // src/contracts/generate-bindings.ts
1623
1716
  function toBindingImportPath(bindingsOutput, contractName) {
1624
- const normalized = bindingsOutput.replace(/^\.\//, "").split(import_node_path10.default.sep).join("/");
1625
- return `./${import_node_path10.default.posix.join(normalized, contractName)}`;
1717
+ const normalized = bindingsOutput.replace(/^\.\//, "").split(import_node_path11.default.sep).join("/");
1718
+ return `./${import_node_path11.default.posix.join(normalized, contractName)}`;
1626
1719
  }
1627
1720
  async function removeLegacyBindingStub(cwd, bindingsOutput, contractName) {
1628
- const legacyPath = import_node_path10.default.resolve(cwd, bindingsOutput, `${contractName}.ts`);
1721
+ const legacyPath = import_node_path11.default.resolve(cwd, bindingsOutput, `${contractName}.ts`);
1629
1722
  try {
1630
- await (0, import_promises7.access)(legacyPath);
1631
- await (0, import_promises7.unlink)(legacyPath);
1723
+ await (0, import_promises8.access)(legacyPath);
1724
+ await (0, import_promises8.unlink)(legacyPath);
1632
1725
  return true;
1633
1726
  } catch {
1634
1727
  return false;
@@ -1653,8 +1746,8 @@ async function generateBindings(options) {
1653
1746
  "Run caatinga deploy for this contract and network before generating bindings."
1654
1747
  );
1655
1748
  }
1656
- const outputDir = import_node_path10.default.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
1657
- await (0, import_promises7.mkdir)(outputDir, { recursive: true });
1749
+ const outputDir = import_node_path11.default.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
1750
+ await (0, import_promises8.mkdir)(outputDir, { recursive: true });
1658
1751
  const result = await runCommand(
1659
1752
  "npx",
1660
1753
  [
@@ -1680,6 +1773,7 @@ async function generateBindings(options) {
1680
1773
  options.config.frontend.bindingsOutput,
1681
1774
  options.contractName
1682
1775
  );
1776
+ await patchGeneratedBindingPackage(outputDir);
1683
1777
  const marker = {
1684
1778
  version: 1,
1685
1779
  contractId: contractArtifact.contractId,
@@ -1879,8 +1973,8 @@ async function readContract(options) {
1879
1973
  }
1880
1974
 
1881
1975
  // src/templates/create-project-from-template.ts
1882
- var import_promises8 = require("fs/promises");
1883
- var import_node_path11 = __toESM(require("path"), 1);
1976
+ var import_promises9 = require("fs/promises");
1977
+ var import_node_path12 = __toESM(require("path"), 1);
1884
1978
  var import_zod7 = require("zod");
1885
1979
 
1886
1980
  // src/templates/template-manifest.schema.ts
@@ -1951,10 +2045,10 @@ function formatTemplateCompatibilityHint(issue) {
1951
2045
  // src/templates/create-project-from-template.ts
1952
2046
  var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set(["target", "test_snapshots", "node_modules", ".git"]);
1953
2047
  async function createProjectFromTemplate(options) {
1954
- const targetDir = import_node_path11.default.resolve(options.targetDir);
1955
- const templateDir = import_node_path11.default.resolve(options.templateDir);
2048
+ const targetDir = import_node_path12.default.resolve(options.targetDir);
2049
+ const templateDir = import_node_path12.default.resolve(options.templateDir);
1956
2050
  try {
1957
- await (0, import_promises8.stat)(templateDir);
2051
+ await (0, import_promises9.stat)(templateDir);
1958
2052
  } catch {
1959
2053
  throw new CaatingaError(
1960
2054
  `Template directory was not found: ${templateDir}`,
@@ -1964,8 +2058,8 @@ async function createProjectFromTemplate(options) {
1964
2058
  }
1965
2059
  const manifest = await readTemplateManifest(templateDir);
1966
2060
  const mergeIntoExisting = Boolean(options.filter);
1967
- await (0, import_promises8.mkdir)(targetDir, { recursive: true });
1968
- await (0, import_promises8.cp)(templateDir, targetDir, {
2061
+ await (0, import_promises9.mkdir)(targetDir, { recursive: true });
2062
+ await (0, import_promises9.cp)(templateDir, targetDir, {
1969
2063
  recursive: true,
1970
2064
  force: true,
1971
2065
  errorOnExist: false,
@@ -1993,9 +2087,9 @@ async function ensureArtifacts(targetDir, projectName) {
1993
2087
  }
1994
2088
  }
1995
2089
  async function readTemplateManifest(templateDir) {
1996
- const manifestPath = import_node_path11.default.join(templateDir, "caatinga.template.json");
2090
+ const manifestPath = import_node_path12.default.join(templateDir, "caatinga.template.json");
1997
2091
  try {
1998
- const rawManifest = await (0, import_promises8.readFile)(manifestPath, "utf8");
2092
+ const rawManifest = await (0, import_promises9.readFile)(manifestPath, "utf8");
1999
2093
  const manifest = TemplateManifestSchema.parse(JSON.parse(rawManifest));
2000
2094
  const compatibilityIssue = getTemplateCompatibilityIssue(manifest);
2001
2095
  if (compatibilityIssue) {
@@ -2028,11 +2122,11 @@ async function readTemplateManifest(templateDir) {
2028
2122
  }
2029
2123
  }
2030
2124
  async function replaceTemplateVariables(dir, projectName) {
2031
- const entries = await (0, import_promises8.readdir)(dir);
2125
+ const entries = await (0, import_promises9.readdir)(dir);
2032
2126
  await Promise.all(
2033
2127
  entries.map(async (entry) => {
2034
- const entryPath = import_node_path11.default.join(dir, entry);
2035
- const entryStat = await (0, import_promises8.stat)(entryPath);
2128
+ const entryPath = import_node_path12.default.join(dir, entry);
2129
+ const entryStat = await (0, import_promises9.stat)(entryPath);
2036
2130
  if (entryStat.isDirectory()) {
2037
2131
  await replaceTemplateVariables(entryPath, projectName);
2038
2132
  return;
@@ -2040,39 +2134,39 @@ async function replaceTemplateVariables(dir, projectName) {
2040
2134
  if (!isTextTemplateFile(entryPath)) {
2041
2135
  return;
2042
2136
  }
2043
- const content = await (0, import_promises8.readFile)(entryPath, "utf8");
2044
- await (0, import_promises8.writeFile)(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
2137
+ const content = await (0, import_promises9.readFile)(entryPath, "utf8");
2138
+ await (0, import_promises9.writeFile)(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
2045
2139
  })
2046
2140
  );
2047
2141
  }
2048
2142
  function shouldCopyTemplateEntry(templateDir, source, userFilter) {
2049
- const relativePath = import_node_path11.default.relative(templateDir, source);
2143
+ const relativePath = import_node_path12.default.relative(templateDir, source);
2050
2144
  if (!relativePath || relativePath === ".") {
2051
2145
  return true;
2052
2146
  }
2053
- const normalizedPath = relativePath.split(import_node_path11.default.sep).join("/");
2147
+ const normalizedPath = relativePath.split(import_node_path12.default.sep).join("/");
2054
2148
  if (userFilter && !userFilter(normalizedPath)) {
2055
2149
  return false;
2056
2150
  }
2057
- return !relativePath.split(import_node_path11.default.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
2151
+ return !relativePath.split(import_node_path12.default.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
2058
2152
  }
2059
2153
  function isTextTemplateFile(filePath) {
2060
2154
  return [".json", ".md", ".rs", ".toml", ".ts", ".tsx", ".css", ".html"].includes(
2061
- import_node_path11.default.extname(filePath)
2155
+ import_node_path12.default.extname(filePath)
2062
2156
  );
2063
2157
  }
2064
2158
 
2065
2159
  // src/scaffold/create-zk-project.ts
2066
- var import_promises9 = require("fs/promises");
2160
+ var import_promises10 = require("fs/promises");
2067
2161
  var import_node_fs2 = require("fs");
2068
- var import_node_path12 = __toESM(require("path"), 1);
2162
+ var import_node_path13 = __toESM(require("path"), 1);
2069
2163
  var import_node_url = require("url");
2070
2164
  var import_meta3 = {};
2071
- var moduleDir = typeof __dirname === "string" ? __dirname : import_node_path12.default.dirname((0, import_node_url.fileURLToPath)(import_meta3.url));
2165
+ var moduleDir = typeof __dirname === "string" ? __dirname : import_node_path13.default.dirname((0, import_node_url.fileURLToPath)(import_meta3.url));
2072
2166
  function scaffoldRoot() {
2073
2167
  const candidates = [
2074
- import_node_path12.default.resolve(moduleDir, "../../scaffolds"),
2075
- import_node_path12.default.resolve(moduleDir, "../scaffolds")
2168
+ import_node_path13.default.resolve(moduleDir, "../../scaffolds"),
2169
+ import_node_path13.default.resolve(moduleDir, "../scaffolds")
2076
2170
  ];
2077
2171
  const found = candidates.find((candidate) => (0, import_node_fs2.existsSync)(candidate));
2078
2172
  return found ?? candidates[0];
@@ -2163,39 +2257,39 @@ Replace \`circuits/main.circom\` with your circuit. Keep the entry point named \
2163
2257
  `;
2164
2258
  }
2165
2259
  async function createZkProject(options) {
2166
- const targetDir = import_node_path12.default.resolve(options.targetDir);
2260
+ const targetDir = import_node_path13.default.resolve(options.targetDir);
2167
2261
  const force = options.force ?? false;
2168
2262
  const projectFiles = options.projectFiles ?? true;
2169
- await (0, import_promises9.mkdir)(targetDir, { recursive: true });
2263
+ await (0, import_promises10.mkdir)(targetDir, { recursive: true });
2170
2264
  if (projectFiles) {
2171
2265
  await Promise.all([
2172
- (0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
2266
+ (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
2173
2267
  encoding: "utf8",
2174
2268
  flag: force ? "w" : "wx"
2175
2269
  }),
2176
- (0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
2270
+ (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
2177
2271
  encoding: "utf8",
2178
2272
  flag: force ? "w" : "wx"
2179
2273
  }),
2180
- (0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2274
+ (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2181
2275
  encoding: "utf8",
2182
2276
  flag: force ? "w" : "wx"
2183
2277
  }),
2184
- (0, import_promises9.writeFile)(import_node_path12.default.join(targetDir, "README.md"), readmeSource(options.projectName), {
2278
+ (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "README.md"), readmeSource(options.projectName), {
2185
2279
  encoding: "utf8",
2186
2280
  flag: force ? "w" : "wx"
2187
2281
  })
2188
2282
  ]);
2189
2283
  }
2190
- await (0, import_promises9.mkdir)(import_node_path12.default.join(targetDir, "contracts"), { recursive: true });
2191
- await (0, import_promises9.cp)(import_node_path12.default.join(scaffoldRoot(), "zk-circuit-stub"), import_node_path12.default.join(targetDir, "circuits"), {
2284
+ await (0, import_promises10.mkdir)(import_node_path13.default.join(targetDir, "contracts"), { recursive: true });
2285
+ await (0, import_promises10.cp)(import_node_path13.default.join(scaffoldRoot(), "zk-circuit-stub"), import_node_path13.default.join(targetDir, "circuits"), {
2192
2286
  recursive: true,
2193
2287
  force,
2194
2288
  errorOnExist: !force
2195
2289
  });
2196
- await (0, import_promises9.cp)(
2197
- import_node_path12.default.join(scaffoldRoot(), "zk-verifier"),
2198
- import_node_path12.default.join(targetDir, "contracts", "verifier"),
2290
+ await (0, import_promises10.cp)(
2291
+ import_node_path13.default.join(scaffoldRoot(), "zk-verifier"),
2292
+ import_node_path13.default.join(targetDir, "contracts", "verifier"),
2199
2293
  {
2200
2294
  recursive: true,
2201
2295
  force,
@@ -2212,16 +2306,16 @@ async function createZkProject(options) {
2212
2306
  }
2213
2307
 
2214
2308
  // src/scaffold/create-minimal-project.ts
2215
- var import_promises10 = require("fs/promises");
2309
+ var import_promises11 = require("fs/promises");
2216
2310
  var import_node_fs3 = require("fs");
2217
- var import_node_path13 = __toESM(require("path"), 1);
2311
+ var import_node_path14 = __toESM(require("path"), 1);
2218
2312
  var import_node_url2 = require("url");
2219
2313
  var import_meta4 = {};
2220
- var moduleDir2 = typeof __dirname === "string" ? __dirname : import_node_path13.default.dirname((0, import_node_url2.fileURLToPath)(import_meta4.url));
2314
+ var moduleDir2 = typeof __dirname === "string" ? __dirname : import_node_path14.default.dirname((0, import_node_url2.fileURLToPath)(import_meta4.url));
2221
2315
  function scaffoldRoot2() {
2222
2316
  const candidates = [
2223
- import_node_path13.default.resolve(moduleDir2, "../../scaffolds"),
2224
- import_node_path13.default.resolve(moduleDir2, "../scaffolds")
2317
+ import_node_path14.default.resolve(moduleDir2, "../../scaffolds"),
2318
+ import_node_path14.default.resolve(moduleDir2, "../scaffolds")
2225
2319
  ];
2226
2320
  const found = candidates.find((candidate) => (0, import_node_fs3.existsSync)(candidate));
2227
2321
  return found ?? candidates[0];
@@ -2312,31 +2406,31 @@ Edit \`contracts/app/src/lib.rs\` to customize the contract. Add a frontend late
2312
2406
  `;
2313
2407
  }
2314
2408
  async function createMinimalProject(options) {
2315
- const targetDir = import_node_path13.default.resolve(options.targetDir);
2409
+ const targetDir = import_node_path14.default.resolve(options.targetDir);
2316
2410
  const force = options.force ?? false;
2317
- await (0, import_promises10.mkdir)(targetDir, { recursive: true });
2411
+ await (0, import_promises11.mkdir)(targetDir, { recursive: true });
2318
2412
  await Promise.all([
2319
- (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
2413
+ (0, import_promises11.writeFile)(import_node_path14.default.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
2320
2414
  encoding: "utf8",
2321
2415
  flag: force ? "w" : "wx"
2322
2416
  }),
2323
- (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
2417
+ (0, import_promises11.writeFile)(import_node_path14.default.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
2324
2418
  encoding: "utf8",
2325
2419
  flag: force ? "w" : "wx"
2326
2420
  }),
2327
- (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2421
+ (0, import_promises11.writeFile)(import_node_path14.default.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2328
2422
  encoding: "utf8",
2329
2423
  flag: force ? "w" : "wx"
2330
2424
  }),
2331
- (0, import_promises10.writeFile)(import_node_path13.default.join(targetDir, "README.md"), readmeSource2(options.projectName), {
2425
+ (0, import_promises11.writeFile)(import_node_path14.default.join(targetDir, "README.md"), readmeSource2(options.projectName), {
2332
2426
  encoding: "utf8",
2333
2427
  flag: force ? "w" : "wx"
2334
2428
  })
2335
2429
  ]);
2336
- await (0, import_promises10.mkdir)(import_node_path13.default.join(targetDir, "contracts"), { recursive: true });
2337
- await (0, import_promises10.cp)(
2338
- import_node_path13.default.join(scaffoldRoot2(), "soroban-contract-stub"),
2339
- import_node_path13.default.join(targetDir, "contracts", "app"),
2430
+ await (0, import_promises11.mkdir)(import_node_path14.default.join(targetDir, "contracts"), { recursive: true });
2431
+ await (0, import_promises11.cp)(
2432
+ import_node_path14.default.join(scaffoldRoot2(), "soroban-contract-stub"),
2433
+ import_node_path14.default.join(targetDir, "contracts", "app"),
2340
2434
  {
2341
2435
  recursive: true,
2342
2436
  force,
package/dist/index.js CHANGED
@@ -1517,8 +1517,101 @@ async function deployContractGraph(options) {
1517
1517
  }
1518
1518
 
1519
1519
  // src/contracts/generate-bindings.ts
1520
- import { access as access3, mkdir as mkdir2, unlink } from "fs/promises";
1520
+ import { access as access4, mkdir as mkdir2, unlink } from "fs/promises";
1521
+ import path11 from "path";
1522
+
1523
+ // src/bindings/patch-generated-binding-package.ts
1524
+ import { access as access3, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
1521
1525
  import path10 from "path";
1526
+ var BUNDLER_ENTRY = "./src/index.ts";
1527
+ var ROOT_BINDING_INDEX_CONTENT = 'export * from "./src/index.js";\n';
1528
+ function resolveExportEntry(exportsField) {
1529
+ if (!exportsField) {
1530
+ return void 0;
1531
+ }
1532
+ const rootExport = exportsField["."];
1533
+ if (typeof rootExport === "string") {
1534
+ return rootExport;
1535
+ }
1536
+ if (rootExport && typeof rootExport === "object" && !Array.isArray(rootExport)) {
1537
+ const conditions = rootExport;
1538
+ for (const key of ["import", "default", "types"]) {
1539
+ const value = conditions[key];
1540
+ if (typeof value === "string") {
1541
+ return value;
1542
+ }
1543
+ }
1544
+ }
1545
+ return void 0;
1546
+ }
1547
+ function pointsToDist(main) {
1548
+ return typeof main === "string" && main.replace(/^\.\//, "").startsWith("dist/");
1549
+ }
1550
+ function pointsToBundlerSource(entry) {
1551
+ return entry === BUNDLER_ENTRY || entry === "./src/index.js";
1552
+ }
1553
+ function shouldPatchPackageJson(packageJson) {
1554
+ const exportEntry = resolveExportEntry(
1555
+ typeof packageJson.exports === "object" && packageJson.exports !== null && !Array.isArray(packageJson.exports) ? packageJson.exports : void 0
1556
+ );
1557
+ return pointsToDist(packageJson.main) || pointsToDist(packageJson.types) || !pointsToBundlerSource(exportEntry);
1558
+ }
1559
+ async function ensureRootBindingIndex(outputDir) {
1560
+ const rootIndexPath = path10.join(outputDir, "index.ts");
1561
+ try {
1562
+ const existing = await readFile4(rootIndexPath, "utf8");
1563
+ if (existing === ROOT_BINDING_INDEX_CONTENT) {
1564
+ return;
1565
+ }
1566
+ return;
1567
+ } catch {
1568
+ await writeFile3(rootIndexPath, ROOT_BINDING_INDEX_CONTENT, "utf8");
1569
+ }
1570
+ }
1571
+ async function patchGeneratedBindingPackage(outputDir) {
1572
+ const packageJsonPath = path10.join(outputDir, "package.json");
1573
+ const entryPath = path10.join(outputDir, "src", "index.ts");
1574
+ try {
1575
+ await access3(entryPath);
1576
+ } catch {
1577
+ throw new CaatingaError(
1578
+ "Generated binding package is missing src/index.ts.",
1579
+ CaatingaErrorCode.BINDINGS_FAILED,
1580
+ "Re-run caatinga generate or check @stellar/stellar-sdk generate output."
1581
+ );
1582
+ }
1583
+ let raw;
1584
+ try {
1585
+ raw = await readFile4(packageJsonPath, "utf8");
1586
+ } catch {
1587
+ throw new CaatingaError(
1588
+ "Generated binding package is missing package.json.",
1589
+ CaatingaErrorCode.BINDINGS_FAILED,
1590
+ "Re-run caatinga generate or check @stellar/stellar-sdk generate output."
1591
+ );
1592
+ }
1593
+ let packageJson;
1594
+ try {
1595
+ packageJson = JSON.parse(raw);
1596
+ } catch {
1597
+ throw new CaatingaError(
1598
+ "Generated binding package.json is not valid JSON.",
1599
+ CaatingaErrorCode.BINDINGS_FAILED,
1600
+ "Re-run caatinga generate or check @stellar/stellar-sdk generate output."
1601
+ );
1602
+ }
1603
+ if (shouldPatchPackageJson(packageJson)) {
1604
+ packageJson.main = BUNDLER_ENTRY;
1605
+ packageJson.types = BUNDLER_ENTRY;
1606
+ packageJson.exports = {
1607
+ ...typeof packageJson.exports === "object" && packageJson.exports !== null && !Array.isArray(packageJson.exports) ? packageJson.exports : {},
1608
+ ".": BUNDLER_ENTRY
1609
+ };
1610
+ await writeFile3(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
1611
+ `, "utf8");
1612
+ }
1613
+ await ensureRootBindingIndex(outputDir);
1614
+ }
1522
1615
 
1523
1616
  // src/contracts/build-generate-network-args.ts
1524
1617
  function buildGenerateNetworkArgs(network) {
@@ -1530,13 +1623,13 @@ function buildGenerateNetworkArgs(network) {
1530
1623
 
1531
1624
  // src/contracts/generate-bindings.ts
1532
1625
  function toBindingImportPath(bindingsOutput, contractName) {
1533
- const normalized = bindingsOutput.replace(/^\.\//, "").split(path10.sep).join("/");
1534
- return `./${path10.posix.join(normalized, contractName)}`;
1626
+ const normalized = bindingsOutput.replace(/^\.\//, "").split(path11.sep).join("/");
1627
+ return `./${path11.posix.join(normalized, contractName)}`;
1535
1628
  }
1536
1629
  async function removeLegacyBindingStub(cwd, bindingsOutput, contractName) {
1537
- const legacyPath = path10.resolve(cwd, bindingsOutput, `${contractName}.ts`);
1630
+ const legacyPath = path11.resolve(cwd, bindingsOutput, `${contractName}.ts`);
1538
1631
  try {
1539
- await access3(legacyPath);
1632
+ await access4(legacyPath);
1540
1633
  await unlink(legacyPath);
1541
1634
  return true;
1542
1635
  } catch {
@@ -1562,7 +1655,7 @@ async function generateBindings(options) {
1562
1655
  "Run caatinga deploy for this contract and network before generating bindings."
1563
1656
  );
1564
1657
  }
1565
- const outputDir = path10.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
1658
+ const outputDir = path11.resolve(cwd, options.config.frontend.bindingsOutput, options.contractName);
1566
1659
  await mkdir2(outputDir, { recursive: true });
1567
1660
  const result = await runCommand(
1568
1661
  "npx",
@@ -1589,6 +1682,7 @@ async function generateBindings(options) {
1589
1682
  options.config.frontend.bindingsOutput,
1590
1683
  options.contractName
1591
1684
  );
1685
+ await patchGeneratedBindingPackage(outputDir);
1592
1686
  const marker = {
1593
1687
  version: 1,
1594
1688
  contractId: contractArtifact.contractId,
@@ -1788,8 +1882,8 @@ async function readContract(options) {
1788
1882
  }
1789
1883
 
1790
1884
  // src/templates/create-project-from-template.ts
1791
- import { cp, mkdir as mkdir3, readFile as readFile4, readdir as readdir3, stat as stat2, writeFile as writeFile3 } from "fs/promises";
1792
- import path11 from "path";
1885
+ import { cp, mkdir as mkdir3, readFile as readFile5, readdir as readdir3, stat as stat2, writeFile as writeFile4 } from "fs/promises";
1886
+ import path12 from "path";
1793
1887
  import { z as z7 } from "zod";
1794
1888
 
1795
1889
  // src/templates/template-manifest.schema.ts
@@ -1860,8 +1954,8 @@ function formatTemplateCompatibilityHint(issue) {
1860
1954
  // src/templates/create-project-from-template.ts
1861
1955
  var TEMPLATE_COPY_EXCLUDED_DIRS = /* @__PURE__ */ new Set(["target", "test_snapshots", "node_modules", ".git"]);
1862
1956
  async function createProjectFromTemplate(options) {
1863
- const targetDir = path11.resolve(options.targetDir);
1864
- const templateDir = path11.resolve(options.templateDir);
1957
+ const targetDir = path12.resolve(options.targetDir);
1958
+ const templateDir = path12.resolve(options.templateDir);
1865
1959
  try {
1866
1960
  await stat2(templateDir);
1867
1961
  } catch {
@@ -1902,9 +1996,9 @@ async function ensureArtifacts(targetDir, projectName) {
1902
1996
  }
1903
1997
  }
1904
1998
  async function readTemplateManifest(templateDir) {
1905
- const manifestPath = path11.join(templateDir, "caatinga.template.json");
1999
+ const manifestPath = path12.join(templateDir, "caatinga.template.json");
1906
2000
  try {
1907
- const rawManifest = await readFile4(manifestPath, "utf8");
2001
+ const rawManifest = await readFile5(manifestPath, "utf8");
1908
2002
  const manifest = TemplateManifestSchema.parse(JSON.parse(rawManifest));
1909
2003
  const compatibilityIssue = getTemplateCompatibilityIssue(manifest);
1910
2004
  if (compatibilityIssue) {
@@ -1940,7 +2034,7 @@ async function replaceTemplateVariables(dir, projectName) {
1940
2034
  const entries = await readdir3(dir);
1941
2035
  await Promise.all(
1942
2036
  entries.map(async (entry) => {
1943
- const entryPath = path11.join(dir, entry);
2037
+ const entryPath = path12.join(dir, entry);
1944
2038
  const entryStat = await stat2(entryPath);
1945
2039
  if (entryStat.isDirectory()) {
1946
2040
  await replaceTemplateVariables(entryPath, projectName);
@@ -1949,38 +2043,38 @@ async function replaceTemplateVariables(dir, projectName) {
1949
2043
  if (!isTextTemplateFile(entryPath)) {
1950
2044
  return;
1951
2045
  }
1952
- const content = await readFile4(entryPath, "utf8");
1953
- await writeFile3(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
2046
+ const content = await readFile5(entryPath, "utf8");
2047
+ await writeFile4(entryPath, content.replaceAll("__PROJECT_NAME__", projectName), "utf8");
1954
2048
  })
1955
2049
  );
1956
2050
  }
1957
2051
  function shouldCopyTemplateEntry(templateDir, source, userFilter) {
1958
- const relativePath = path11.relative(templateDir, source);
2052
+ const relativePath = path12.relative(templateDir, source);
1959
2053
  if (!relativePath || relativePath === ".") {
1960
2054
  return true;
1961
2055
  }
1962
- const normalizedPath = relativePath.split(path11.sep).join("/");
2056
+ const normalizedPath = relativePath.split(path12.sep).join("/");
1963
2057
  if (userFilter && !userFilter(normalizedPath)) {
1964
2058
  return false;
1965
2059
  }
1966
- return !relativePath.split(path11.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
2060
+ return !relativePath.split(path12.sep).some((segment) => TEMPLATE_COPY_EXCLUDED_DIRS.has(segment));
1967
2061
  }
1968
2062
  function isTextTemplateFile(filePath) {
1969
2063
  return [".json", ".md", ".rs", ".toml", ".ts", ".tsx", ".css", ".html"].includes(
1970
- path11.extname(filePath)
2064
+ path12.extname(filePath)
1971
2065
  );
1972
2066
  }
1973
2067
 
1974
2068
  // src/scaffold/create-zk-project.ts
1975
- import { cp as cp2, mkdir as mkdir4, writeFile as writeFile4 } from "fs/promises";
2069
+ import { cp as cp2, mkdir as mkdir4, writeFile as writeFile5 } from "fs/promises";
1976
2070
  import { existsSync as existsSync2 } from "fs";
1977
- import path12 from "path";
2071
+ import path13 from "path";
1978
2072
  import { fileURLToPath } from "url";
1979
- var moduleDir = typeof __dirname === "string" ? __dirname : path12.dirname(fileURLToPath(import.meta.url));
2073
+ var moduleDir = typeof __dirname === "string" ? __dirname : path13.dirname(fileURLToPath(import.meta.url));
1980
2074
  function scaffoldRoot() {
1981
2075
  const candidates = [
1982
- path12.resolve(moduleDir, "../../scaffolds"),
1983
- path12.resolve(moduleDir, "../scaffolds")
2076
+ path13.resolve(moduleDir, "../../scaffolds"),
2077
+ path13.resolve(moduleDir, "../scaffolds")
1984
2078
  ];
1985
2079
  const found = candidates.find((candidate) => existsSync2(candidate));
1986
2080
  return found ?? candidates[0];
@@ -2071,39 +2165,39 @@ Replace \`circuits/main.circom\` with your circuit. Keep the entry point named \
2071
2165
  `;
2072
2166
  }
2073
2167
  async function createZkProject(options) {
2074
- const targetDir = path12.resolve(options.targetDir);
2168
+ const targetDir = path13.resolve(options.targetDir);
2075
2169
  const force = options.force ?? false;
2076
2170
  const projectFiles = options.projectFiles ?? true;
2077
2171
  await mkdir4(targetDir, { recursive: true });
2078
2172
  if (projectFiles) {
2079
2173
  await Promise.all([
2080
- writeFile4(path12.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
2174
+ writeFile5(path13.join(targetDir, "caatinga.config.ts"), configSource(options.projectName), {
2081
2175
  encoding: "utf8",
2082
2176
  flag: force ? "w" : "wx"
2083
2177
  }),
2084
- writeFile4(path12.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
2178
+ writeFile5(path13.join(targetDir, "package.json"), packageJsonSource(options.projectName), {
2085
2179
  encoding: "utf8",
2086
2180
  flag: force ? "w" : "wx"
2087
2181
  }),
2088
- writeFile4(path12.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2182
+ writeFile5(path13.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2089
2183
  encoding: "utf8",
2090
2184
  flag: force ? "w" : "wx"
2091
2185
  }),
2092
- writeFile4(path12.join(targetDir, "README.md"), readmeSource(options.projectName), {
2186
+ writeFile5(path13.join(targetDir, "README.md"), readmeSource(options.projectName), {
2093
2187
  encoding: "utf8",
2094
2188
  flag: force ? "w" : "wx"
2095
2189
  })
2096
2190
  ]);
2097
2191
  }
2098
- await mkdir4(path12.join(targetDir, "contracts"), { recursive: true });
2099
- await cp2(path12.join(scaffoldRoot(), "zk-circuit-stub"), path12.join(targetDir, "circuits"), {
2192
+ await mkdir4(path13.join(targetDir, "contracts"), { recursive: true });
2193
+ await cp2(path13.join(scaffoldRoot(), "zk-circuit-stub"), path13.join(targetDir, "circuits"), {
2100
2194
  recursive: true,
2101
2195
  force,
2102
2196
  errorOnExist: !force
2103
2197
  });
2104
2198
  await cp2(
2105
- path12.join(scaffoldRoot(), "zk-verifier"),
2106
- path12.join(targetDir, "contracts", "verifier"),
2199
+ path13.join(scaffoldRoot(), "zk-verifier"),
2200
+ path13.join(targetDir, "contracts", "verifier"),
2107
2201
  {
2108
2202
  recursive: true,
2109
2203
  force,
@@ -2120,15 +2214,15 @@ async function createZkProject(options) {
2120
2214
  }
2121
2215
 
2122
2216
  // src/scaffold/create-minimal-project.ts
2123
- import { cp as cp3, mkdir as mkdir5, writeFile as writeFile5 } from "fs/promises";
2217
+ import { cp as cp3, mkdir as mkdir5, writeFile as writeFile6 } from "fs/promises";
2124
2218
  import { existsSync as existsSync3 } from "fs";
2125
- import path13 from "path";
2219
+ import path14 from "path";
2126
2220
  import { fileURLToPath as fileURLToPath2 } from "url";
2127
- var moduleDir2 = typeof __dirname === "string" ? __dirname : path13.dirname(fileURLToPath2(import.meta.url));
2221
+ var moduleDir2 = typeof __dirname === "string" ? __dirname : path14.dirname(fileURLToPath2(import.meta.url));
2128
2222
  function scaffoldRoot2() {
2129
2223
  const candidates = [
2130
- path13.resolve(moduleDir2, "../../scaffolds"),
2131
- path13.resolve(moduleDir2, "../scaffolds")
2224
+ path14.resolve(moduleDir2, "../../scaffolds"),
2225
+ path14.resolve(moduleDir2, "../scaffolds")
2132
2226
  ];
2133
2227
  const found = candidates.find((candidate) => existsSync3(candidate));
2134
2228
  return found ?? candidates[0];
@@ -2219,31 +2313,31 @@ Edit \`contracts/app/src/lib.rs\` to customize the contract. Add a frontend late
2219
2313
  `;
2220
2314
  }
2221
2315
  async function createMinimalProject(options) {
2222
- const targetDir = path13.resolve(options.targetDir);
2316
+ const targetDir = path14.resolve(options.targetDir);
2223
2317
  const force = options.force ?? false;
2224
2318
  await mkdir5(targetDir, { recursive: true });
2225
2319
  await Promise.all([
2226
- writeFile5(path13.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
2320
+ writeFile6(path14.join(targetDir, "caatinga.config.ts"), configSource2(options.projectName), {
2227
2321
  encoding: "utf8",
2228
2322
  flag: force ? "w" : "wx"
2229
2323
  }),
2230
- writeFile5(path13.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
2324
+ writeFile6(path14.join(targetDir, "package.json"), packageJsonSource2(options.projectName), {
2231
2325
  encoding: "utf8",
2232
2326
  flag: force ? "w" : "wx"
2233
2327
  }),
2234
- writeFile5(path13.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2328
+ writeFile6(path14.join(targetDir, ".gitignore"), "node_modules\n.artifacts\ntarget\n", {
2235
2329
  encoding: "utf8",
2236
2330
  flag: force ? "w" : "wx"
2237
2331
  }),
2238
- writeFile5(path13.join(targetDir, "README.md"), readmeSource2(options.projectName), {
2332
+ writeFile6(path14.join(targetDir, "README.md"), readmeSource2(options.projectName), {
2239
2333
  encoding: "utf8",
2240
2334
  flag: force ? "w" : "wx"
2241
2335
  })
2242
2336
  ]);
2243
- await mkdir5(path13.join(targetDir, "contracts"), { recursive: true });
2337
+ await mkdir5(path14.join(targetDir, "contracts"), { recursive: true });
2244
2338
  await cp3(
2245
- path13.join(scaffoldRoot2(), "soroban-contract-stub"),
2246
- path13.join(targetDir, "contracts", "app"),
2339
+ path14.join(scaffoldRoot2(), "soroban-contract-stub"),
2340
+ path14.join(targetDir, "contracts", "app"),
2247
2341
  {
2248
2342
  recursive: true,
2249
2343
  force,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@caatinga/core",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "description": "Core config, artifacts, command orchestration, and error primitives for Caatinga/Soroban toolkit",
5
5
  "keywords": [
6
6
  "stellar",