@layerzerolabs/build-utils-rust 1.2.68 → 1.2.69

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 (83) hide show
  1. package/bin/build-utils-rust.js +3 -0
  2. package/dist/2T2WFWNM.js +57 -0
  3. package/dist/2T2WFWNM.js.map +1 -0
  4. package/dist/N2QRCDCB.js +115 -0
  5. package/dist/N2QRCDCB.js.map +1 -0
  6. package/dist/N4NI6N3K.js +83 -0
  7. package/dist/N4NI6N3K.js.map +1 -0
  8. package/dist/UDDAJZY4.js +26 -0
  9. package/dist/UDDAJZY4.js.map +1 -0
  10. package/dist/VUOMXK5T.js +6 -0
  11. package/dist/VUOMXK5T.js.map +1 -0
  12. package/dist/ZQ7KHDAO.js +52 -0
  13. package/dist/ZQ7KHDAO.js.map +1 -0
  14. package/dist/ZS7IDLZZ.js +59 -0
  15. package/dist/ZS7IDLZZ.js.map +1 -0
  16. package/dist/cli.d.ts +2 -0
  17. package/dist/cli.d.ts.map +1 -0
  18. package/dist/cli.js +27 -0
  19. package/dist/cli.js.map +1 -0
  20. package/{src/index.ts → dist/index.d.ts} +1 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/logger.d.ts +8 -0
  24. package/dist/logger.d.ts.map +1 -0
  25. package/dist/logger.js +4 -0
  26. package/dist/logger.js.map +1 -0
  27. package/dist/resolve/discover.d.ts +23 -0
  28. package/dist/resolve/discover.d.ts.map +1 -0
  29. package/dist/resolve/discover.js +7 -0
  30. package/dist/resolve/discover.js.map +1 -0
  31. package/dist/resolve/exclude.d.ts +10 -0
  32. package/dist/resolve/exclude.d.ts.map +1 -0
  33. package/dist/resolve/exclude.js +4 -0
  34. package/dist/resolve/exclude.js.map +1 -0
  35. package/dist/resolve/index.d.ts +20 -0
  36. package/dist/resolve/index.d.ts.map +1 -0
  37. package/dist/resolve/index.js +9 -0
  38. package/dist/resolve/index.js.map +1 -0
  39. package/dist/resolve/io.d.ts +17 -0
  40. package/dist/resolve/io.d.ts.map +1 -0
  41. package/dist/resolve/io.js +6 -0
  42. package/dist/resolve/io.js.map +1 -0
  43. package/dist/resolve/rewrite.d.ts +41 -0
  44. package/dist/resolve/rewrite.d.ts.map +1 -0
  45. package/dist/resolve/rewrite.js +8 -0
  46. package/dist/resolve/rewrite.js.map +1 -0
  47. package/package.json +9 -6
  48. package/src/cli.ts +0 -33
  49. package/src/logger.ts +0 -26
  50. package/src/resolve/discover.ts +0 -93
  51. package/src/resolve/exclude.ts +0 -58
  52. package/src/resolve/index.ts +0 -122
  53. package/src/resolve/io.ts +0 -69
  54. package/src/resolve/rewrite.ts +0 -231
  55. package/tests/resolve/discover.test.ts +0 -208
  56. package/tests/resolve/fixtures/index.ts +0 -6
  57. package/tests/resolve/fixtures/minimal.toml +0 -2
  58. package/tests/resolve/fixtures/mixed-deps.toml +0 -4
  59. package/tests/resolve/fixtures/multi-path-deps.toml +0 -9
  60. package/tests/resolve/fixtures/multi-section-path-deps.toml +0 -13
  61. package/tests/resolve/fixtures/no-path-deps.toml +0 -3
  62. package/tests/resolve/fixtures/oapp-with-stale-deps.toml +0 -5
  63. package/tests/resolve/fixtures/oft-core-with-stale-deep-deps.toml +0 -11
  64. package/tests/resolve/fixtures/patch-multi-registry.toml +0 -22
  65. package/tests/resolve/fixtures/program-with-deps.toml +0 -5
  66. package/tests/resolve/fixtures/program-with-macros.toml +0 -6
  67. package/tests/resolve/fixtures/program-workspace-member.toml +0 -5
  68. package/tests/resolve/fixtures/root-only-sections.toml +0 -13
  69. package/tests/resolve/fixtures/stellar-consumer.toml +0 -8
  70. package/tests/resolve/fixtures/stellar-member-inheriting.toml +0 -10
  71. package/tests/resolve/fixtures/stellar-workspace-root.toml +0 -17
  72. package/tests/resolve/fixtures/stellar-workspace-with-tests.toml +0 -15
  73. package/tests/resolve/fixtures/target-cfg-path-dep.toml +0 -10
  74. package/tests/resolve/fixtures/with-features.toml +0 -2
  75. package/tests/resolve/fixtures/workspace-at-end.toml +0 -6
  76. package/tests/resolve/fixtures/workspace-at-top.toml +0 -10
  77. package/tests/resolve/fixtures/workspace-middle.toml +0 -10
  78. package/tests/resolve/fixtures/workspace-with-default-members.toml +0 -8
  79. package/tests/resolve/fixtures/workspace-with-path-deps.toml +0 -8
  80. package/tests/resolve/index.test.ts +0 -468
  81. package/tests/resolve/rewrite.test.ts +0 -507
  82. package/tsconfig.json +0 -21
  83. package/tsup.config.ts +0 -8
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"discover.js"}
@@ -0,0 +1,10 @@
1
+ /** Files vendored into dependencies/ — everything else is skipped by type. */
2
+ export declare const COPY_EXTENSIONS: Set<string>;
3
+ /** Filter excluded names from a directory listing. */
4
+ export declare const removeExcludedFiles: (entries: string[]) => string[];
5
+ /**
6
+ * True if a resolved crate path contains an excluded segment.
7
+ * Do not use on raw `path` dep values — those legitimately pass through node_modules.
8
+ */
9
+ export declare const hasExcludedSegment: (relPath: string) => boolean;
10
+ //# sourceMappingURL=exclude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclude.d.ts","sourceRoot":"","sources":["../../src/resolve/exclude.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,eAAe,aAAqC,CAAC;AA+ClE,sDAAsD;AACtD,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,EAAE,KAAG,MAAM,EACN,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,KAAG,OACkB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { COPY_EXTENSIONS, hasExcludedSegment, removeExcludedFiles } from '../2T2WFWNM.js';
2
+ import '../VUOMXK5T.js';
3
+ //# sourceMappingURL=exclude.js.map
4
+ //# sourceMappingURL=exclude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"exclude.js"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Vendor @layerzerolabs Cargo dependencies from node_modules into a flat
3
+ * dependencies/ directory with rewritten path deps, so a Rust package builds
4
+ * without the rest of the monorepo.
5
+ */
6
+ import { type VendorTarget } from './discover';
7
+ /** Maps each crate's npm package source path to its vendored dependencies/ location. */
8
+ export declare const buildDependenciesPathMap: (targets: VendorTarget[]) => Map<string, string>;
9
+ /**
10
+ * Entry point: vendor every @layerzerolabs Cargo crate reachable through node_modules
11
+ * into dependencies/, with path deps rewritten to resolve locally.
12
+ *
13
+ * @param cwd pnpm package root (where node_modules/ lives). Default: process.cwd()
14
+ * @param cargoDir Cargo crate directory to vendor into. Default: packageRoot
15
+ */
16
+ export declare const resolveDependencies: ({ cwd, cargoDir, }?: {
17
+ cwd?: string;
18
+ cargoDir?: string;
19
+ }) => Promise<void>;
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resolve/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,OAAO,EAA6B,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ1E,wFAAwF;AACxF,eAAO,MAAM,wBAAwB,GAAI,SAAS,YAAY,EAAE,KAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAWpF,CAAC;AAoCF;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,GAAU,qBAGvC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,KAAG,OAAO,CAAC,IAAI,CA6CzD,CAAC"}
@@ -0,0 +1,9 @@
1
+ export { buildDependenciesPathMap, resolveDependencies } from '../N4NI6N3K.js';
2
+ import '../N2QRCDCB.js';
3
+ import '../ZQ7KHDAO.js';
4
+ import '../ZS7IDLZZ.js';
5
+ import '../UDDAJZY4.js';
6
+ import '../2T2WFWNM.js';
7
+ import '../VUOMXK5T.js';
8
+ //# sourceMappingURL=index.js.map
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,17 @@
1
+ export declare const tryRealpath: (path: string) => Promise<string | undefined>;
2
+ export declare const tryIsDirectory: (path: string) => Promise<boolean>;
3
+ export declare const tryReaddir: (dir: string) => Promise<string[]>;
4
+ export interface CollectedTree {
5
+ /** directories containing copyable content, relative to root (no empties) */
6
+ dirs: string[];
7
+ /** copyable files (COPY_EXTENSIONS), relative to root (excluded subtrees pruned) */
8
+ files: string[];
9
+ /** dirs that directly contain a Cargo.toml (crate roots), relative to root; '.' is the root */
10
+ manifestDirs: string[];
11
+ }
12
+ /**
13
+ * Walk `root` once, applying exclusion per level and keeping only COPY_EXTENSIONS files.
14
+ * Also records `manifestDirs` (dirs holding a Cargo.toml) so consumers don't re-scan.
15
+ */
16
+ export declare const collectFiles: (root: string, relativePath?: string) => Promise<CollectedTree>;
17
+ //# sourceMappingURL=io.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/resolve/io.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,WAAW,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAM1E,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,MAAM,MAAM,KAAG,OAAO,CAAC,OAAO,CAMlE,CAAC;AAEF,eAAO,MAAM,UAAU,GAAU,KAAK,MAAM,KAAG,OAAO,CAAC,MAAM,EAAE,CAM9D,CAAC;AAEF,MAAM,WAAW,aAAa;IAC1B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,oFAAoF;IACpF,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,+FAA+F;IAC/F,YAAY,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAU,MAAM,MAAM,EAAE,qBAAiB,KAAG,OAAO,CAAC,aAAa,CAyBzF,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { collectFiles, tryIsDirectory, tryReaddir, tryRealpath } from '../ZS7IDLZZ.js';
2
+ import '../UDDAJZY4.js';
3
+ import '../2T2WFWNM.js';
4
+ import '../VUOMXK5T.js';
5
+ //# sourceMappingURL=io.js.map
6
+ //# sourceMappingURL=io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"io.js"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Rewrite a vendored Cargo.toml's path deps into the flat dependencies/ layout,
3
+ * operating on the parsed TOML (via smol-toml) rather than text.
4
+ */
5
+ import { type CollectedTree } from './io';
6
+ /** Bundled resolution state passed through the rewrite pipeline. */
7
+ export interface RewriteContext {
8
+ pathMap: Map<string, string>;
9
+ discovered: Map<string, string>;
10
+ }
11
+ type Table = Record<string, unknown>;
12
+ /**
13
+ * Drop literal `members` / `default-members` entries whose path contains an excluded
14
+ * directory segment (e.g. `tests/mock_vault`) — those dirs are never vendored, so the
15
+ * member would dangle and fail Cargo's workspace load. Globs (`tests/*`) are kept; Cargo
16
+ * re-expands them to a harmless empty match. Returns true if any member was removed.
17
+ */
18
+ export declare const pruneExcludedLiteralMembers: (manifest: Table) => boolean;
19
+ /** Rebase every path dep in `manifest` into the flat dependencies/ layout. Returns true if any changed. */
20
+ export declare const rewritePathDeps: (manifest: Table, originalDir: string, manifestDir: string, ctx: RewriteContext, includeWorkspaceDeps: boolean) => Promise<boolean>;
21
+ /**
22
+ * Delete the `[workspace]` / `[patch.*]` / `[profile.*]` tables — invalid or ignored in a
23
+ * vendored dependency (only honored at the real workspace root). Returns true if any was removed.
24
+ */
25
+ export declare const stripRootOnlyTables: (manifest: Table) => boolean;
26
+ /**
27
+ * Rewrite one vendored Cargo.toml in place: rebase its path deps, then strip the root-only
28
+ * tables — or, for a preserved workspace root (`stripRootTables = false`), prune excluded
29
+ * members instead. Re-serialized only if something changed.
30
+ *
31
+ * @param originalDir source crate dir the manifest was copied from
32
+ * @param cargoTomlPath the vendored Cargo.toml to rewrite
33
+ */
34
+ export declare const rewriteCargoToml: (originalDir: string, cargoTomlPath: string, ctx: RewriteContext, stripRootTables?: boolean) => Promise<void>;
35
+ /**
36
+ * Rewrite every Cargo.toml in a copied dependency tree. The root manifest keeps its
37
+ * root-only tables when it's a workspace (members inherit from them); all others strip them.
38
+ */
39
+ export declare const rewriteCargoTomls: (srcRoot: string, destRoot: string, tree: CollectedTree, ctx: RewriteContext) => Promise<void>;
40
+ export {};
41
+ //# sourceMappingURL=rewrite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rewrite.d.ts","sourceRoot":"","sources":["../../src/resolve/rewrite.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,OAAO,EAAE,KAAK,aAAa,EAAe,MAAM,MAAM,CAAC;AAEvD,oEAAoE;AACpE,MAAM,WAAW,cAAc;IAC3B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAmCrC;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,GAAI,UAAU,KAAK,KAAG,OAoB7D,CAAC;AAEF,2GAA2G;AAC3G,eAAO,MAAM,eAAe,GACxB,UAAU,KAAK,EACf,aAAa,MAAM,EACnB,aAAa,MAAM,EACnB,KAAK,cAAc,EACnB,sBAAsB,OAAO,KAC9B,OAAO,CAAC,OAAO,CAiBjB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,UAAU,KAAK,KAAG,OASrD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,GACzB,aAAa,MAAM,EACnB,eAAe,MAAM,EACrB,KAAK,cAAc,EACnB,yBAAsB,KACvB,OAAO,CAAC,IAAI,CAmBd,CAAC;AAsDF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,GAC1B,SAAS,MAAM,EACf,UAAU,MAAM,EAChB,MAAM,aAAa,EACnB,KAAK,cAAc,KACpB,OAAO,CAAC,IAAI,CAWd,CAAC"}
@@ -0,0 +1,8 @@
1
+ export { pruneExcludedLiteralMembers, rewriteCargoToml, rewriteCargoTomls, rewritePathDeps, stripRootOnlyTables } from '../N2QRCDCB.js';
2
+ import '../ZQ7KHDAO.js';
3
+ import '../ZS7IDLZZ.js';
4
+ import '../UDDAJZY4.js';
5
+ import '../2T2WFWNM.js';
6
+ import '../VUOMXK5T.js';
7
+ //# sourceMappingURL=rewrite.js.map
8
+ //# sourceMappingURL=rewrite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"rewrite.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@layerzerolabs/build-utils-rust",
3
- "version": "1.2.68",
3
+ "version": "1.2.69",
4
4
  "private": false,
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -13,19 +13,22 @@
13
13
  "module": "./dist/index.js",
14
14
  "types": "./dist/index.d.ts",
15
15
  "bin": {
16
- "build-utils-rust": "./src/cli.ts"
16
+ "build-utils-rust": "./bin/build-utils-rust.js"
17
17
  },
18
+ "files": [
19
+ "dist/**/*",
20
+ "bin/**/*"
21
+ ],
18
22
  "dependencies": {
19
- "@layerzerolabs/logger-node": "1.2.68",
23
+ "@layerzerolabs/logger-node": "1.2.69",
20
24
  "commander": "13.1.0",
21
25
  "smol-toml": "^1.7.0"
22
26
  },
23
27
  "devDependencies": {
24
- "@layerzerolabs/tsup-configuration": "1.2.68",
25
- "@layerzerolabs/typescript-configuration": "1.2.68",
28
+ "@layerzerolabs/tsup-configuration": "1.2.69",
29
+ "@layerzerolabs/typescript-configuration": "1.2.69",
26
30
  "@types/node": "^24.13.3",
27
31
  "tsup": "^8.4.0",
28
- "tsx": "^4.21.0",
29
32
  "vitest": "^4.1.10"
30
33
  },
31
34
  "publishConfig": {
package/src/cli.ts DELETED
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env tsx
2
- import { Command } from 'commander';
3
-
4
- import { logger, parseLogLevel, setLogLevel } from './logger';
5
- import { resolveDependencies } from './resolve';
6
-
7
- const main = async (): Promise<void> => {
8
- const program = new Command();
9
- program
10
- .name('build-utils-rust')
11
- .description('Build utilities for Rust/Cargo packages in LayerZero.');
12
-
13
- program
14
- .command('resolve')
15
- .description(
16
- 'Resolve @layerzerolabs Cargo dependencies from node_modules into a flat ' +
17
- 'dependencies/ directory with rewritten path deps.',
18
- )
19
- .option('--cwd <path>', 'pnpm package root (where node_modules/ lives). Default: cwd.')
20
- .option('--cargo-dir <path>', 'Cargo crate directory to resolve. Defaults to package root.')
21
- .option('--log-level <level>', 'trace | debug | info | warn | error. Default: info.')
22
- .action(async (opts: { cwd?: string; cargoDir?: string; logLevel?: string }) => {
23
- setLogLevel(parseLogLevel(opts.logLevel));
24
- await resolveDependencies({ cwd: opts.cwd, cargoDir: opts.cargoDir });
25
- });
26
-
27
- await program.parseAsync(process.argv);
28
- };
29
-
30
- void main().catch((err: unknown) => {
31
- logger.error('build-utils-rust failed', err);
32
- process.exit(1);
33
- });
package/src/logger.ts DELETED
@@ -1,26 +0,0 @@
1
- import { createConsoleLogger, LogLevel } from '@layerzerolabs/logger-node';
2
-
3
- export type { Logger } from '@layerzerolabs/logger-node';
4
- export { LogLevel } from '@layerzerolabs/logger-node';
5
-
6
- export let logger = createConsoleLogger(LogLevel.INFO);
7
-
8
- export const setLogLevel = (level: LogLevel): void => {
9
- logger = createConsoleLogger(level);
10
- };
11
-
12
- /** Parse a log-level string (CLI flag). Unknown values fall back to INFO. */
13
- export const parseLogLevel = (value?: string): LogLevel => {
14
- switch (value?.toLowerCase()) {
15
- case 'trace':
16
- return LogLevel.TRACE;
17
- case 'debug':
18
- return LogLevel.DEBUG;
19
- case 'warn':
20
- return LogLevel.WARN;
21
- case 'error':
22
- return LogLevel.ERROR;
23
- default:
24
- return LogLevel.INFO;
25
- }
26
- };
@@ -1,93 +0,0 @@
1
- /** Discovery — walk node_modules/@layerzerolabs/ to find all @layerzerolabs Cargo crates. */
2
-
3
- import { access, readFile, stat } from 'fs/promises';
4
- import { join } from 'path';
5
- import { parse } from 'smol-toml';
6
-
7
- import { logger } from '../logger';
8
- import type { CollectedTree } from './io';
9
- import { tryReaddir, tryRealpath } from './io';
10
-
11
- // ─── Constants ───
12
-
13
- /** Only packages under this npm scope are treated as Cargo dependencies. */
14
- const LZ_SCOPE = '@layerzerolabs';
15
-
16
- // ─── Types ───
17
-
18
- /** A discovered package paired with its collected source tree, ready to vendor. */
19
- export interface VendorTarget {
20
- /** npm package name (without scope) — the dependencies/ subdir. */
21
- pkgName: string;
22
- /** canonical source path (realpath through pnpm symlinks). */
23
- npmPkgDir: string;
24
- /** vendored location: dependencies/<pkgName>. */
25
- depsPkgDir: string;
26
- /** included file/dir tree (excluded subtrees already pruned). */
27
- tree: CollectedTree;
28
- }
29
-
30
- // ─── Crate Helpers ───
31
-
32
- /** Checks if the directory contains a Cargo.toml. */
33
- export const isCrate = async (dir: string): Promise<boolean> => {
34
- try {
35
- const stats = await stat(dir);
36
- if (!stats.isDirectory()) return false;
37
- await access(join(dir, 'Cargo.toml'));
38
- return true;
39
- } catch {
40
- return false;
41
- }
42
- };
43
-
44
- /** True if the directory's Cargo.toml declares a `[workspace]` table. */
45
- export const isWorkspaceRoot = async (crateRoot: string): Promise<boolean> => {
46
- const manifestPath = join(crateRoot, 'Cargo.toml');
47
- let raw: string;
48
- try {
49
- raw = await readFile(manifestPath, 'utf-8');
50
- } catch {
51
- return false; // no readable Cargo.toml here — not a workspace root
52
- }
53
- try {
54
- return parse(raw).workspace != null;
55
- } catch (err) {
56
- // Warn rather than silently treat a malformed manifest as a non-workspace
57
- // (which would strip its [workspace] table); the parser is stricter than Cargo.
58
- logger.warn(`failed to parse ${manifestPath}; treating as non-workspace`, err);
59
- return false;
60
- }
61
- };
62
-
63
- // ─── Main Functions ───
64
-
65
- /**
66
- * Recursively discover all @layerzerolabs Cargo packages reachable from `dir`'s node_modules.
67
- * Resolves pnpm symlinks to canonical paths; `visited` prevents re-walking shared deps.
68
- */
69
- export const discoverPackages = async (
70
- dir: string,
71
- discovered: Map<string, string>,
72
- visited: Set<string>,
73
- ): Promise<void> => {
74
- const realDir = await tryRealpath(dir);
75
- if (!realDir || visited.has(realDir)) return;
76
- visited.add(realDir);
77
-
78
- const nodeModulesDir = join(dir, 'node_modules', LZ_SCOPE);
79
-
80
- for (const pkgName of await tryReaddir(nodeModulesDir)) {
81
- // Resolve pnpm symlink to canonical path (deduplicates across dep chains)
82
- const realPath = await tryRealpath(join(nodeModulesDir, pkgName));
83
- const isValidCratePath = realPath && (await isCrate(realPath));
84
- if (!isValidCratePath) continue;
85
-
86
- if (!discovered.has(pkgName)) {
87
- discovered.set(pkgName, realPath);
88
- }
89
-
90
- // Walk this package's own node_modules for transitive Cargo deps
91
- await discoverPackages(realPath, discovered, visited);
92
- }
93
- };
@@ -1,58 +0,0 @@
1
- /** Files vendored into dependencies/ — everything else is skipped by type. */
2
- export const COPY_EXTENSIONS = new Set(['.rs', '.toml', '.json']);
3
-
4
- /** Directories never descended into when copying or scanning. */
5
- const EXCLUDE_DIR = new Set([
6
- // npm directories
7
- 'dependencies',
8
- 'node_modules',
9
- 'target',
10
- '.turbo',
11
- // cargo directories
12
- 'examples',
13
- 'benches',
14
- 'fuzz',
15
- '.cargo',
16
- // vcs / ci
17
- '.git',
18
- '.github',
19
- // shared directories
20
- 'tests',
21
- 'integration-tests',
22
- 'integration_tests',
23
- // stellar test snapshots
24
- 'test_snapshots',
25
- ]);
26
-
27
- /** Files matching COPY_EXTENSIONS that must still be skipped — lockfiles, toolchain config, etc. */
28
- const EXCLUDE_FILE = new Set([
29
- // npm
30
- 'package.json',
31
- 'pnpm-lock.yaml',
32
- // Host-side TS config only; not needed for Rust crate vendoring.
33
- 'tsconfig.json',
34
- // turbo
35
- 'turbo-snapshot.lock.json',
36
- 'turbo.json',
37
- // cargo/rust
38
- 'Cargo.lock',
39
- 'clippy.toml',
40
- 'deny.toml',
41
- 'rust-toolchain.toml',
42
- 'rustfmt.toml',
43
- // solana
44
- 'Anchor.toml',
45
- ]);
46
-
47
- const COPY_EXCLUDES = new Set([...EXCLUDE_DIR, ...EXCLUDE_FILE]);
48
-
49
- /** Filter excluded names from a directory listing. */
50
- export const removeExcludedFiles = (entries: string[]): string[] =>
51
- entries.filter((entry) => !COPY_EXCLUDES.has(entry));
52
-
53
- /**
54
- * True if a resolved crate path contains an excluded segment.
55
- * Do not use on raw `path` dep values — those legitimately pass through node_modules.
56
- */
57
- export const hasExcludedSegment = (relPath: string): boolean =>
58
- relPath.split(/[\\/]+/).some((segment) => EXCLUDE_DIR.has(segment));
@@ -1,122 +0,0 @@
1
- /**
2
- * Vendor @layerzerolabs Cargo dependencies from node_modules into a flat
3
- * dependencies/ directory with rewritten path deps, so a Rust package builds
4
- * without the rest of the monorepo.
5
- */
6
-
7
- import { copyFile, mkdir, rm } from 'fs/promises';
8
- import { join, relative, resolve } from 'path';
9
-
10
- import { logger } from '../logger';
11
- import { discoverPackages, isCrate, type VendorTarget } from './discover';
12
- import type { CollectedTree } from './io';
13
- import { collectFiles } from './io';
14
- import type { RewriteContext } from './rewrite';
15
- import { rewriteCargoTomls } from './rewrite';
16
-
17
- // ─── Path Map ───
18
-
19
- /** Maps each crate's npm package source path to its vendored dependencies/ location. */
20
- export const buildDependenciesPathMap = (targets: VendorTarget[]): Map<string, string> => {
21
- const pathMap = new Map<string, string>();
22
-
23
- for (const { npmPkgDir, depsPkgDir, tree } of targets) {
24
- for (const dir of tree.manifestDirs) {
25
- pathMap.set(join(npmPkgDir, dir), join(depsPkgDir, dir));
26
- logger.trace(`map ${join(npmPkgDir, dir)} -> ${join(depsPkgDir, dir)}`);
27
- }
28
- }
29
- logger.debug(`built dependency path map: ${pathMap.size} entries`);
30
- return pathMap;
31
- };
32
-
33
- // ─── File Operations ───
34
-
35
- /** Copy a collected tree into destRoot. */
36
- const copyCollected = async (
37
- srcRoot: string,
38
- destRoot: string,
39
- tree: CollectedTree,
40
- ): Promise<void> => {
41
- await mkdir(destRoot, { recursive: true });
42
- await Promise.all(tree.dirs.map((dir) => mkdir(join(destRoot, dir), { recursive: true })));
43
- await Promise.all(
44
- tree.files.map((file) => copyFile(join(srcRoot, file), join(destRoot, file))),
45
- );
46
- };
47
-
48
- /** Resolves the Cargo root: `cargoDir` if provided, else `packageRoot`. Throws if no Cargo.toml. */
49
- const resolveCargoRoot = async (packageRoot: string, cargoDir?: string): Promise<string> => {
50
- if (cargoDir) {
51
- const resolved = resolve(packageRoot, cargoDir);
52
- if (!(await isCrate(resolved))) {
53
- throw new Error(`--cargo-dir ${cargoDir} does not contain a Cargo.toml`);
54
- }
55
- return resolved;
56
- }
57
-
58
- if (!(await isCrate(packageRoot))) {
59
- throw new Error(`${packageRoot} does not contain a Cargo.toml`);
60
- }
61
-
62
- return packageRoot;
63
- };
64
-
65
- // ─── Public API ───
66
-
67
- /**
68
- * Entry point: vendor every @layerzerolabs Cargo crate reachable through node_modules
69
- * into dependencies/, with path deps rewritten to resolve locally.
70
- *
71
- * @param cwd pnpm package root (where node_modules/ lives). Default: process.cwd()
72
- * @param cargoDir Cargo crate directory to vendor into. Default: packageRoot
73
- */
74
- export const resolveDependencies = async ({
75
- cwd,
76
- cargoDir,
77
- }: { cwd?: string; cargoDir?: string } = {}): Promise<void> => {
78
- const packageRoot = resolve(cwd ?? process.cwd());
79
-
80
- const depsRoot = join(await resolveCargoRoot(packageRoot, cargoDir), 'dependencies');
81
-
82
- const discovered = new Map<string, string>();
83
- await discoverPackages(packageRoot, discovered, new Set());
84
-
85
- if (discovered.size === 0) {
86
- logger.info('No @layerzerolabs namespaced Cargo dependencies found in node_modules');
87
- return;
88
- }
89
-
90
- // Rebuild dependencies/ from scratch each run.
91
- await rm(depsRoot, { recursive: true, force: true });
92
- await mkdir(depsRoot, { recursive: true });
93
-
94
- // Collect each package's tree once — copy, path map, and rewrite all reuse it.
95
- const targets: VendorTarget[] = await Promise.all(
96
- Array.from(discovered, async ([pkgName, npmPkgDir]) => {
97
- const tree = await collectFiles(npmPkgDir);
98
- logger.debug(
99
- `${pkgName}: collected ${tree.files.length} files, ${tree.dirs.length} dirs`,
100
- );
101
- return { pkgName, npmPkgDir, depsPkgDir: join(depsRoot, pkgName), tree };
102
- }),
103
- );
104
-
105
- const ctx: RewriteContext = {
106
- pathMap: buildDependenciesPathMap(targets),
107
- discovered,
108
- };
109
- logger.debug(`path map: ${ctx.pathMap.size} entries`);
110
-
111
- await Promise.all(
112
- targets.map(async ({ pkgName, npmPkgDir, depsPkgDir, tree }) => {
113
- await copyCollected(npmPkgDir, depsPkgDir, tree);
114
- await rewriteCargoTomls(npmPkgDir, depsPkgDir, tree, ctx);
115
- logger.debug(` ${pkgName} -> ${npmPkgDir}`);
116
- }),
117
- );
118
-
119
- logger.info(
120
- `Resolved ${discovered.size} Cargo dependencies into ${relative(packageRoot, depsRoot) || './dependencies/'}`,
121
- );
122
- };
package/src/resolve/io.ts DELETED
@@ -1,69 +0,0 @@
1
- import { readdir, realpath, stat } from 'fs/promises';
2
- import { basename, dirname, extname, join } from 'path';
3
-
4
- import { logger } from '../logger';
5
- import { COPY_EXTENSIONS, removeExcludedFiles } from './exclude';
6
-
7
- export const tryRealpath = async (path: string): Promise<string | undefined> => {
8
- try {
9
- return await realpath(path);
10
- } catch {
11
- return undefined;
12
- }
13
- };
14
-
15
- export const tryIsDirectory = async (path: string): Promise<boolean> => {
16
- try {
17
- return (await stat(path)).isDirectory();
18
- } catch {
19
- return false;
20
- }
21
- };
22
-
23
- export const tryReaddir = async (dir: string): Promise<string[]> => {
24
- try {
25
- return await readdir(dir);
26
- } catch {
27
- return [];
28
- }
29
- };
30
-
31
- export interface CollectedTree {
32
- /** directories containing copyable content, relative to root (no empties) */
33
- dirs: string[];
34
- /** copyable files (COPY_EXTENSIONS), relative to root (excluded subtrees pruned) */
35
- files: string[];
36
- /** dirs that directly contain a Cargo.toml (crate roots), relative to root; '.' is the root */
37
- manifestDirs: string[];
38
- }
39
-
40
- /**
41
- * Walk `root` once, applying exclusion per level and keeping only COPY_EXTENSIONS files.
42
- * Also records `manifestDirs` (dirs holding a Cargo.toml) so consumers don't re-scan.
43
- */
44
- export const collectFiles = async (root: string, relativePath = ''): Promise<CollectedTree> => {
45
- const dirs: string[] = [];
46
- const files: string[] = [];
47
- const manifestDirs: string[] = [];
48
-
49
- const rawFileNames = await tryReaddir(join(root, relativePath));
50
- const fileNames = removeExcludedFiles(rawFileNames).map((e) => join(relativePath, e));
51
-
52
- for (const file of fileNames) {
53
- if (await tryIsDirectory(join(root, file))) {
54
- const subDir = await collectFiles(root, file);
55
- if (subDir.files.length > 0) {
56
- dirs.push(file, ...subDir.dirs);
57
- files.push(...subDir.files);
58
- manifestDirs.push(...subDir.manifestDirs);
59
- } else {
60
- logger.trace(`skip empty dir ${file}`);
61
- }
62
- } else if (COPY_EXTENSIONS.has(extname(file))) {
63
- files.push(file);
64
- if (basename(file) === 'Cargo.toml') manifestDirs.push(dirname(file));
65
- logger.trace(`collect ${file}`);
66
- }
67
- }
68
- return { dirs, files, manifestDirs };
69
- };