@chainlink/cre-sdk 1.5.0-alpha.2 โ†’ 1.5.0-alpha.4

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 (98) hide show
  1. package/README.md +18 -1
  2. package/bin/cre-compile.ts +39 -17
  3. package/dist/generated/capabilities/blockchain/evm/v1alpha/client_pb.js +1 -1
  4. package/dist/generated/chain-selectors/mainnet/evm/ab-mainnet.d.ts +3 -0
  5. package/dist/generated/chain-selectors/mainnet/evm/ab-mainnet.js +12 -0
  6. package/dist/generated/chain-selectors/mainnet/evm/adi-mainnet.d.ts +3 -0
  7. package/dist/generated/chain-selectors/mainnet/evm/adi-mainnet.js +12 -0
  8. package/dist/generated/chain-selectors/mainnet/evm/edge-mainnet.d.ts +3 -0
  9. package/dist/generated/chain-selectors/mainnet/evm/edge-mainnet.js +12 -0
  10. package/dist/generated/chain-selectors/mainnet/evm/everclear-mainnet.d.ts +3 -0
  11. package/dist/generated/chain-selectors/mainnet/evm/everclear-mainnet.js +12 -0
  12. package/dist/generated/chain-selectors/mainnet/evm/gate-chain-mainnet.d.ts +3 -0
  13. package/dist/generated/chain-selectors/mainnet/evm/gate-chain-mainnet.js +12 -0
  14. package/dist/generated/chain-selectors/mainnet/evm/gate-layer-mainnet.d.ts +3 -0
  15. package/dist/generated/chain-selectors/mainnet/evm/gate-layer-mainnet.js +12 -0
  16. package/dist/generated/chain-selectors/mainnet/evm/jovay-mainnet.d.ts +3 -0
  17. package/dist/generated/chain-selectors/mainnet/evm/jovay-mainnet.js +12 -0
  18. package/dist/generated/chain-selectors/mainnet/evm/megaeth-mainnet.d.ts +3 -0
  19. package/dist/generated/chain-selectors/mainnet/evm/megaeth-mainnet.js +12 -0
  20. package/dist/generated/chain-selectors/mainnet/evm/pharos-mainnet.d.ts +3 -0
  21. package/dist/generated/chain-selectors/mainnet/evm/pharos-mainnet.js +12 -0
  22. package/dist/generated/chain-selectors/mainnet/evm/stable-mainnet.d.ts +3 -0
  23. package/dist/generated/chain-selectors/mainnet/evm/stable-mainnet.js +12 -0
  24. package/dist/generated/chain-selectors/mainnet/evm/tempo-mainnet.d.ts +3 -0
  25. package/dist/generated/chain-selectors/mainnet/evm/tempo-mainnet.js +12 -0
  26. package/dist/generated/chain-selectors/testnet/evm/0g-testnet-galileo-1.d.ts +3 -0
  27. package/dist/generated/chain-selectors/testnet/evm/0g-testnet-galileo-1.js +12 -0
  28. package/dist/generated/chain-selectors/testnet/evm/ab-testnet.d.ts +3 -0
  29. package/dist/generated/chain-selectors/testnet/evm/ab-testnet.js +12 -0
  30. package/dist/generated/chain-selectors/testnet/evm/adi-testnet.d.ts +3 -0
  31. package/dist/generated/chain-selectors/testnet/evm/adi-testnet.js +12 -0
  32. package/dist/generated/chain-selectors/testnet/evm/arc-testnet.d.ts +3 -0
  33. package/dist/generated/chain-selectors/testnet/evm/arc-testnet.js +12 -0
  34. package/dist/generated/chain-selectors/testnet/evm/celo-sepolia.d.ts +3 -0
  35. package/dist/generated/chain-selectors/testnet/evm/celo-sepolia.js +12 -0
  36. package/dist/generated/chain-selectors/testnet/evm/dogeos-testnet-chikyu.d.ts +3 -0
  37. package/dist/generated/chain-selectors/testnet/evm/dogeos-testnet-chikyu.js +12 -0
  38. package/dist/generated/chain-selectors/testnet/evm/edge-testnet.d.ts +3 -0
  39. package/dist/generated/chain-selectors/testnet/evm/edge-testnet.js +12 -0
  40. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-morph.d.ts +3 -0
  41. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-morph.js +12 -0
  42. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko-1.d.ts +3 -0
  43. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko-1.js +12 -0
  44. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko.d.ts +3 -0
  45. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko.js +12 -0
  46. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi.d.ts +3 -0
  47. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi.js +12 -0
  48. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-sepolia-ronin-1.d.ts +3 -0
  49. package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-sepolia-ronin-1.js +12 -0
  50. package/dist/generated/chain-selectors/testnet/evm/everclear-testnet-sepolia.d.ts +3 -0
  51. package/dist/generated/chain-selectors/testnet/evm/everclear-testnet-sepolia.js +12 -0
  52. package/dist/generated/chain-selectors/testnet/evm/gate-chain-testnet-meteora.d.ts +3 -0
  53. package/dist/generated/chain-selectors/testnet/evm/gate-chain-testnet-meteora.js +12 -0
  54. package/dist/generated/chain-selectors/testnet/evm/gate-layer-testnet.d.ts +3 -0
  55. package/dist/generated/chain-selectors/testnet/evm/gate-layer-testnet.js +12 -0
  56. package/dist/generated/chain-selectors/testnet/evm/megaeth-testnet-2.d.ts +3 -0
  57. package/dist/generated/chain-selectors/testnet/evm/megaeth-testnet-2.js +12 -0
  58. package/dist/generated/chain-selectors/testnet/evm/pharos-atlantic-testnet.d.ts +3 -0
  59. package/dist/generated/chain-selectors/testnet/evm/pharos-atlantic-testnet.js +12 -0
  60. package/dist/generated/chain-selectors/testnet/evm/robinhood-testnet.d.ts +3 -0
  61. package/dist/generated/chain-selectors/testnet/evm/robinhood-testnet.js +12 -0
  62. package/dist/generated/chain-selectors/testnet/evm/sonic-testnet.d.ts +3 -0
  63. package/dist/generated/chain-selectors/testnet/evm/sonic-testnet.js +12 -0
  64. package/dist/generated/chain-selectors/testnet/evm/stable-testnet.d.ts +3 -0
  65. package/dist/generated/chain-selectors/testnet/evm/stable-testnet.js +12 -0
  66. package/dist/generated/chain-selectors/testnet/evm/tempo-testnet-moderato.d.ts +3 -0
  67. package/dist/generated/chain-selectors/testnet/evm/tempo-testnet-moderato.js +12 -0
  68. package/dist/generated/chain-selectors/testnet/evm/tempo-testnet.d.ts +3 -0
  69. package/dist/generated/chain-selectors/testnet/evm/tempo-testnet.js +12 -0
  70. package/dist/generated/chain-selectors/testnet/evm/xlayer-testnet.d.ts +3 -0
  71. package/dist/generated/chain-selectors/testnet/evm/xlayer-testnet.js +12 -0
  72. package/dist/generated/networks.d.ts +2 -2
  73. package/dist/generated/networks.js +238 -0
  74. package/dist/generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen.d.ts +24 -0
  75. package/dist/generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen.js +24 -0
  76. package/dist/index.d.ts +3 -0
  77. package/dist/sdk/types/global.d.ts +146 -2
  78. package/dist/sdk/types/restricted-apis.d.ts +18 -23
  79. package/dist/sdk/types/restricted-node-modules.d.ts +462 -0
  80. package/dist/sdk/utils/capabilities/blockchain/blockchain-helpers.d.ts +40 -3
  81. package/dist/sdk/utils/capabilities/blockchain/blockchain-helpers.js +80 -6
  82. package/dist/sdk/utils/prepare-runtime.d.ts +1 -1
  83. package/dist/sdk/utils/prepare-runtime.js +9 -2
  84. package/dist/sdk/wasm/host-bindings.d.ts +4 -4
  85. package/package.json +5 -5
  86. package/scripts/run.ts +11 -1
  87. package/scripts/src/build-types.ts +31 -1
  88. package/scripts/src/compile-cli-args.test.ts +32 -0
  89. package/scripts/src/compile-cli-args.ts +35 -0
  90. package/scripts/src/compile-to-js.test.ts +90 -0
  91. package/scripts/src/compile-to-js.ts +51 -13
  92. package/scripts/src/compile-to-wasm.ts +35 -34
  93. package/scripts/src/compile-workflow.ts +55 -27
  94. package/scripts/src/generate-chain-selectors.ts +9 -27
  95. package/scripts/src/typecheck-workflow.test.ts +77 -0
  96. package/scripts/src/typecheck-workflow.ts +96 -0
  97. package/scripts/src/validate-workflow-runtime-compat.test.ts +433 -0
  98. package/scripts/src/validate-workflow-runtime-compat.ts +631 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chainlink/cre-sdk",
3
- "version": "v1.5.0-alpha.2",
3
+ "version": "1.5.0-alpha.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -47,9 +47,9 @@
47
47
  "compile:workflow": "bun scripts/run.ts compile-workflow",
48
48
  "fix-imports": "bun scripts/run.ts fix-imports",
49
49
  "format": "biome format --write ${BIOME_PATHS:-.}",
50
- "full-checks": "bun generate:sdk && bun build && bun typecheck && bun check && bun test && bun test:standard",
50
+ "full-checks": "bun generate:sdk && bun run build && bun typecheck && bun check && bun test && bun test:standard",
51
51
  "generate:chain-selectors": "bun scripts/run.ts generate-chain-selectors && BIOME_PATHS=\"src/generated\" bun check",
52
- "generate:proto": "bunx @bufbuild/buf generate && BIOME_PATHS=\"src/generated\" bun check",
52
+ "generate:proto": "bun x @bufbuild/buf generate && BIOME_PATHS=\"src/generated\" bun check",
53
53
  "generate:sdk": "bun generate:proto && bun generate:chain-selectors && bun scripts/run generate-sdks && BIOME_PATHS=\"src/generated src/generated-sdk src/sdk/test/generated\" bun check",
54
54
  "lint": "biome lint --write",
55
55
  "prepublishOnly": "bun typecheck && bun check && bun test && bun test:standard",
@@ -60,7 +60,7 @@
60
60
  "dependencies": {
61
61
  "@bufbuild/protobuf": "2.6.3",
62
62
  "@bufbuild/protoc-gen-es": "2.6.3",
63
- "@chainlink/cre-sdk-javy-plugin": "v1.5.0-alpha.2",
63
+ "@chainlink/cre-sdk-javy-plugin": "1.5.0-alpha.4",
64
64
  "@standard-schema/spec": "1.0.0",
65
65
  "viem": "2.34.0",
66
66
  "zod": "3.25.76"
@@ -69,7 +69,7 @@
69
69
  "@biomejs/biome": "2.3.14",
70
70
  "@bufbuild/buf": "1.56.0",
71
71
  "@types/bun": "1.3.8",
72
- "chain-selectors": "https://github.com/smartcontractkit/chain-selectors.git#8b963095ae797a3024c8e55822cced7bf618176f",
72
+ "chain-selectors": "https://github.com/smartcontractkit/chain-selectors.git#a86ae261a09f805ea37165f58b017b4538e2e3bb",
73
73
  "fast-glob": "3.3.3",
74
74
  "ts-proto": "2.7.5",
75
75
  "typescript": "5.9.3",
package/scripts/run.ts CHANGED
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
+ import { WorkflowTypecheckError } from './src/typecheck-workflow'
4
+ import { WorkflowRuntimeCompatibilityError } from './src/validate-workflow-runtime-compat'
5
+
3
6
  const availableScripts = [
4
7
  'build-types',
5
8
  'compile-to-js',
@@ -37,7 +40,14 @@ const main = async () => {
37
40
  process.exit(1)
38
41
  }
39
42
  } catch (error) {
40
- console.error(`Failed to load script ${scriptName}:`, error)
43
+ if (
44
+ error instanceof WorkflowRuntimeCompatibilityError ||
45
+ error instanceof WorkflowTypecheckError
46
+ ) {
47
+ console.error(`\nโŒ ${error.message}`)
48
+ } else {
49
+ console.error(`Failed to run script ${scriptName}:`, error)
50
+ }
41
51
  process.exit(1)
42
52
  }
43
53
  }
@@ -1,5 +1,5 @@
1
1
  import { glob } from 'fast-glob'
2
- import { copyFile, mkdir } from 'fs/promises'
2
+ import { copyFile, mkdir, readFile, writeFile } from 'fs/promises'
3
3
  import { join } from 'path'
4
4
 
5
5
  const buildTypes = async () => {
@@ -28,6 +28,36 @@ const buildTypes = async () => {
28
28
  }
29
29
 
30
30
  console.log(`โœ… Copied ${typeFiles.length} type definition file(s) to dist/sdk/types`)
31
+
32
+ // Prepend triple-slash references to dist/index.d.ts so consumers pick up
33
+ // global type augmentations (e.g. restricted-apis.d.ts) automatically.
34
+ // tsc strips these from the emitted .d.ts, so we add them back here.
35
+ const indexDts = join(packageRoot, 'dist/index.d.ts')
36
+ const sourceIndex = join(packageRoot, 'src/index.ts')
37
+ const sourceContent = await readFile(sourceIndex, 'utf-8')
38
+
39
+ const refsFromSource = sourceContent
40
+ .split('\n')
41
+ .filter((line) => line.startsWith('/// <reference types='))
42
+
43
+ // Add references for consumer-only type declarations that cannot be in src/index.ts
44
+ // because they would break the SDK's own scripts/tests (which legitimately use Node.js APIs).
45
+ const consumerOnlyRefs = ['/// <reference types="./sdk/types/restricted-node-modules" />']
46
+
47
+ const tripleSlashRefs = [...refsFromSource, ...consumerOnlyRefs].join('\n')
48
+
49
+ if (tripleSlashRefs) {
50
+ const indexContent = await readFile(indexDts, 'utf-8')
51
+ // Strip any existing triple-slash references from the top of the file
52
+ // so that re-running build-types is idempotent.
53
+ const withoutExistingRefs = indexContent
54
+ .split('\n')
55
+ .filter((line) => !line.trim().startsWith('/// <reference types='))
56
+ .join('\n')
57
+ .replace(/^\n+/, '') // trim leading blank lines left after stripping
58
+ await writeFile(indexDts, `${tripleSlashRefs}\n${withoutExistingRefs}`)
59
+ console.log('โœ… Added triple-slash references to dist/index.d.ts')
60
+ }
31
61
  }
32
62
 
33
63
  export const main = buildTypes
@@ -0,0 +1,32 @@
1
+ import { describe, expect, test } from 'bun:test'
2
+ import { parseCompileCliArgs } from './compile-cli-args'
3
+
4
+ describe('parseCompileCliArgs', () => {
5
+ test('parses positional input and output', () => {
6
+ const parsed = parseCompileCliArgs(['src/workflow.ts', 'dist/workflow.wasm'])
7
+ expect(parsed).toEqual({
8
+ inputPath: 'src/workflow.ts',
9
+ outputPath: 'dist/workflow.wasm',
10
+ skipTypeChecks: false,
11
+ })
12
+ })
13
+
14
+ test('parses --skip-type-checks flag', () => {
15
+ const parsed = parseCompileCliArgs(['src/workflow.ts', '--skip-type-checks'])
16
+ expect(parsed).toEqual({
17
+ inputPath: 'src/workflow.ts',
18
+ outputPath: undefined,
19
+ skipTypeChecks: true,
20
+ })
21
+ })
22
+
23
+ test('throws on unknown flags', () => {
24
+ expect(() => parseCompileCliArgs(['src/workflow.ts', '--foo'])).toThrow('Unknown option: --foo')
25
+ })
26
+
27
+ test('throws on too many positional args', () => {
28
+ expect(() => parseCompileCliArgs(['src/workflow.ts', 'dist/workflow.wasm', 'extra'])).toThrow(
29
+ 'Too many positional arguments.',
30
+ )
31
+ })
32
+ })
@@ -0,0 +1,35 @@
1
+ export const skipTypeChecksFlag = '--skip-type-checks'
2
+
3
+ export type ParsedCompileArgs = {
4
+ inputPath?: string
5
+ outputPath?: string
6
+ skipTypeChecks: boolean
7
+ }
8
+
9
+ export const parseCompileCliArgs = (args: string[]): ParsedCompileArgs => {
10
+ const positionalArgs: string[] = []
11
+ let skipTypeChecks = false
12
+
13
+ for (const arg of args) {
14
+ if (arg === skipTypeChecksFlag) {
15
+ skipTypeChecks = true
16
+ continue
17
+ }
18
+
19
+ if (arg.startsWith('-')) {
20
+ throw new Error(`Unknown option: ${arg}`)
21
+ }
22
+
23
+ positionalArgs.push(arg)
24
+ }
25
+
26
+ if (positionalArgs.length > 2) {
27
+ throw new Error('Too many positional arguments.')
28
+ }
29
+
30
+ return {
31
+ inputPath: positionalArgs[0],
32
+ outputPath: positionalArgs[1],
33
+ skipTypeChecks,
34
+ }
35
+ }
@@ -0,0 +1,90 @@
1
+ import { afterEach, beforeEach, describe, expect, test } from 'bun:test'
2
+ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'
3
+ import path from 'node:path'
4
+ import { main as compileToJs } from './compile-to-js'
5
+ import { WorkflowTypecheckError } from './typecheck-workflow'
6
+
7
+ let tempDir: string
8
+
9
+ beforeEach(() => {
10
+ tempDir = mkdtempSync(path.join(process.cwd(), '.tmp-cre-compile-to-js-test-'))
11
+ })
12
+
13
+ afterEach(() => {
14
+ rmSync(tempDir, { recursive: true, force: true })
15
+ })
16
+
17
+ const writeTemp = (filename: string, content: string): string => {
18
+ const filePath = path.join(tempDir, filename)
19
+ mkdirSync(path.dirname(filePath), { recursive: true })
20
+ writeFileSync(filePath, content, 'utf-8')
21
+ return filePath
22
+ }
23
+
24
+ describe('compile-to-js typecheck behavior', () => {
25
+ test('fails on type errors by default', async () => {
26
+ writeTemp(
27
+ 'tsconfig.json',
28
+ JSON.stringify(
29
+ {
30
+ compilerOptions: {
31
+ target: 'ES2022',
32
+ module: 'ESNext',
33
+ moduleResolution: 'Bundler',
34
+ skipLibCheck: true,
35
+ strict: true,
36
+ types: [],
37
+ lib: ['ESNext'],
38
+ },
39
+ include: ['src/**/*.ts'],
40
+ },
41
+ null,
42
+ 2,
43
+ ),
44
+ )
45
+ const entry = writeTemp('src/workflow.ts', "export const shouldBeNumber: number = 'oops'\n")
46
+ const output = path.join(tempDir, 'dist/workflow.js')
47
+
48
+ await expect(compileToJs(entry, output)).rejects.toBeInstanceOf(WorkflowTypecheckError)
49
+ })
50
+
51
+ test('continues when --skip-type-checks is enabled', async () => {
52
+ writeTemp(
53
+ 'tsconfig.json',
54
+ JSON.stringify(
55
+ {
56
+ compilerOptions: {
57
+ target: 'ES2022',
58
+ module: 'ESNext',
59
+ moduleResolution: 'Bundler',
60
+ skipLibCheck: true,
61
+ strict: true,
62
+ types: [],
63
+ lib: ['ESNext'],
64
+ },
65
+ include: ['src/**/*.ts'],
66
+ },
67
+ null,
68
+ 2,
69
+ ),
70
+ )
71
+ const entry = writeTemp('src/workflow.ts', "export const shouldBeNumber: number = 'oops'\n")
72
+ const output = path.join(tempDir, 'dist/workflow.js')
73
+
74
+ let thrownError: unknown
75
+ let result: string | undefined
76
+ try {
77
+ result = await compileToJs(entry, output, {
78
+ skipTypeChecks: true,
79
+ })
80
+ } catch (error) {
81
+ thrownError = error
82
+ }
83
+
84
+ expect(thrownError).not.toBeInstanceOf(WorkflowTypecheckError)
85
+ if (typeof result === 'string') {
86
+ expect(result).toEqual(output)
87
+ expect(existsSync(output)).toBeTrue()
88
+ }
89
+ })
90
+ })
@@ -2,23 +2,64 @@ import { existsSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
2
2
  import { mkdir } from 'node:fs/promises'
3
3
  import path from 'node:path'
4
4
  import { $ } from 'bun'
5
+ import { parseCompileCliArgs, skipTypeChecksFlag } from './compile-cli-args'
6
+ import { assertWorkflowTypecheck } from './typecheck-workflow'
7
+ import { assertWorkflowRuntimeCompatibility } from './validate-workflow-runtime-compat'
5
8
  import { wrapWorkflowCode } from './workflow-wrapper'
6
9
 
7
- export const main = async (tsFilePath?: string, outputFilePath?: string) => {
8
- const cliArgs = process.argv.slice(3)
10
+ type CompileToJsOptions = {
11
+ skipTypeChecks?: boolean
12
+ }
13
+
14
+ const printUsage = () => {
15
+ console.error(`Usage: bun compile:ts-to-js <path-to-file> [output-file] [${skipTypeChecksFlag}]`)
16
+ console.error('Example:')
17
+ console.error(' bun compile:ts-to-js src/tests/foo.ts dist/tests/foo.bundle.js')
18
+ console.error(
19
+ ` bun compile:ts-to-js src/tests/foo.ts dist/tests/foo.bundle.js ${skipTypeChecksFlag}`,
20
+ )
21
+ }
22
+
23
+ export const main = async (
24
+ tsFilePath?: string,
25
+ outputFilePath?: string,
26
+ options?: CompileToJsOptions,
27
+ ) => {
28
+ let parsedInputPath: string | undefined
29
+ let parsedOutputPath: string | undefined
30
+ let parsedSkipTypeChecks = false
31
+
32
+ if (tsFilePath != null || outputFilePath != null || options?.skipTypeChecks != null) {
33
+ parsedInputPath = tsFilePath
34
+ parsedOutputPath = outputFilePath
35
+ parsedSkipTypeChecks = options?.skipTypeChecks ?? false
36
+ } else {
37
+ try {
38
+ const parsed = parseCompileCliArgs(process.argv.slice(3))
39
+ parsedInputPath = parsed.inputPath
40
+ parsedOutputPath = parsed.outputPath
41
+ parsedSkipTypeChecks = parsed.skipTypeChecks
42
+ } catch (error) {
43
+ console.error(error instanceof Error ? error.message : error)
44
+ printUsage()
45
+ process.exit(1)
46
+ }
47
+ }
9
48
 
10
49
  // Prefer function params, fallback to CLI args
11
- const inputPath = tsFilePath ?? cliArgs[0]
12
- const outputPathArg = outputFilePath ?? cliArgs[1]
50
+ const inputPath = parsedInputPath
51
+ const outputPathArg = parsedOutputPath
13
52
 
14
53
  if (!inputPath) {
15
- console.error('Usage: bun test:standard:compile:js <path-to-file> [output-file]')
16
- console.error('Example:')
17
- console.error(' bun test:standard:compile:js src/tests/foo.ts dist/tests/foo.bundle.js')
54
+ printUsage()
18
55
  process.exit(1)
19
56
  }
20
57
 
21
58
  const resolvedInput = path.resolve(inputPath)
59
+ if (!parsedSkipTypeChecks) {
60
+ assertWorkflowTypecheck(resolvedInput)
61
+ }
62
+ assertWorkflowRuntimeCompatibility(resolvedInput)
22
63
  console.info(`๐Ÿ“ Using input file: ${resolvedInput}`)
23
64
 
24
65
  // If no explicit output path โ†’ same dir, swap extension to .js
@@ -54,16 +95,13 @@ export const main = async (tsFilePath?: string, outputFilePath?: string) => {
54
95
  naming: path.basename(resolvedOutput),
55
96
  })
56
97
 
57
- // The file Bun will emit before bundling
58
- const builtFile = path.join(path.dirname(resolvedOutput), path.basename(resolvedOutput))
59
-
60
- if (!existsSync(builtFile)) {
61
- console.error(`โŒ Expected file not found: ${builtFile}`)
98
+ if (!existsSync(resolvedOutput)) {
99
+ console.error(`โŒ Expected file not found: ${resolvedOutput}`)
62
100
  process.exit(1)
63
101
  }
64
102
 
65
103
  // Bundle into the final file (overwrite)
66
- await $`bun build ${builtFile} --bundle --outfile=${resolvedOutput}`
104
+ await $`bun build ${resolvedOutput} --bundle --outfile=${resolvedOutput}`
67
105
 
68
106
  console.info(`โœ… Built: ${resolvedOutput}`)
69
107
  return resolvedOutput
@@ -1,34 +1,38 @@
1
+ import { spawn } from 'node:child_process'
1
2
  import { existsSync } from 'node:fs'
2
3
  import { mkdir } from 'node:fs/promises'
3
4
  import path from 'node:path'
4
- import { $ } from 'bun'
5
- import { parseCompileFlags } from '../../../cre-sdk-javy-plugin/scripts/parse-compile-flags'
5
+
6
+ function runBun(args: string[]): Promise<void> {
7
+ return new Promise((resolve, reject) => {
8
+ const child = spawn('bun', args, {
9
+ stdio: 'inherit',
10
+ env: process.env,
11
+ })
12
+ child.on('error', reject)
13
+ child.on('exit', (code) => {
14
+ if (code === 0) resolve()
15
+ else reject(new Error(`bun exited with code ${code ?? 'unknown'}`))
16
+ })
17
+ })
18
+ }
6
19
 
7
20
  const isJsFile = (p: string) => ['.js', '.mjs', '.cjs'].includes(path.extname(p).toLowerCase())
8
21
 
9
- export const main = async (
10
- inputFile?: string,
11
- outputFile?: string,
12
- creExportsPaths?: string[],
13
- pluginPath?: string | null,
14
- ) => {
22
+ export const main = async (inputFile?: string, outputFile?: string) => {
15
23
  const cliArgs = process.argv.slice(3)
16
- const { creExports: cliCreExports, plugin: cliPlugin, rest: cliRest } = parseCompileFlags(cliArgs)
17
24
 
18
- const inputPath = inputFile ?? cliRest[0]
19
- const outputPathArg = outputFile ?? cliRest[1]
20
- const creExports = creExportsPaths ?? cliCreExports
21
- const plugin = pluginPath !== undefined ? pluginPath : cliPlugin
22
-
23
- if (plugin !== null && plugin !== undefined && creExports.length > 0) {
24
- console.error('โŒ Error: --plugin and --cre-exports are mutually exclusive.')
25
- process.exit(1)
26
- }
25
+ // Resolve input/output from params or CLI
26
+ const inputPath = inputFile ?? cliArgs[0]
27
+ const outputPathArg = outputFile ?? cliArgs[1]
27
28
 
28
29
  if (!inputPath) {
29
30
  console.error(
30
31
  'Usage: bun compile:js-to-wasm <path/to/input.(js|mjs|cjs)> [path/to/output.wasm]',
31
32
  )
33
+ console.error('Examples:')
34
+ console.error(' bun compile:js-to-wasm ./build/workflows/test.js')
35
+ console.error(' bun compile:js-to-wasm ./build/workflows/test.mjs ./artifacts/test.wasm')
32
36
  process.exit(1)
33
37
  }
34
38
 
@@ -43,34 +47,31 @@ export const main = async (
43
47
  process.exit(1)
44
48
  }
45
49
 
50
+ // Default output = same dir, same basename, .wasm extension
46
51
  const defaultOut = path.join(
47
52
  path.dirname(resolvedInput),
48
53
  path.basename(resolvedInput).replace(/\.(m|c)?js$/i, '.wasm'),
49
54
  )
50
55
  const resolvedOutput = outputPathArg ? path.resolve(outputPathArg) : defaultOut
51
56
 
57
+ // Ensure output directory exists
52
58
  await mkdir(path.dirname(resolvedOutput), { recursive: true })
53
59
 
54
- console.info('๐Ÿ”จ Compiling to WASM')
60
+ console.info(`๐Ÿ”จ Compiling to WASM`)
55
61
  console.info(`๐Ÿ“ Input: ${resolvedInput}`)
56
62
  console.info(`๐ŸŽฏ Output: ${resolvedOutput}`)
57
63
 
58
- const compileArgs: string[] = []
59
- if (plugin != null && plugin !== '') {
60
- compileArgs.push('--plugin', path.resolve(plugin))
64
+ // Prefer the sibling @chainlink/cre-sdk-javy-plugin install (same as monorepo layout).
65
+ // Bun's shell `$` template can throw EINVAL on some Linux/arm64 Docker setups; use spawn.
66
+ const scriptDir = import.meta.dir
67
+ const compilerPath = path.resolve(
68
+ scriptDir,
69
+ '../../../cre-sdk-javy-plugin/bin/compile-workflow.ts',
70
+ )
71
+ if (existsSync(compilerPath)) {
72
+ await runBun(['--bun', compilerPath, resolvedInput, resolvedOutput])
61
73
  } else {
62
- compileArgs.push(...creExports.flatMap((p) => ['--cre-exports', path.resolve(p)]))
63
- }
64
- compileArgs.push(resolvedInput, resolvedOutput)
65
- try {
66
- await $`bun cre-compile-workflow ${compileArgs}`
67
- } catch {
68
- const scriptDir = import.meta.dir
69
- const compilerPath = path.resolve(
70
- scriptDir,
71
- '../../../cre-sdk-javy-plugin/bin/compile-workflow.ts',
72
- )
73
- await $`bun --bun ${compilerPath} ${compileArgs}`
74
+ await runBun(['x', 'cre-compile-workflow', resolvedInput, resolvedOutput])
74
75
  }
75
76
 
76
77
  console.info(`โœ… Compiled: ${resolvedOutput}`)
@@ -1,31 +1,59 @@
1
1
  import { existsSync } from 'node:fs'
2
2
  import { mkdir } from 'node:fs/promises'
3
3
  import path from 'node:path'
4
- import { parseCompileFlags } from '../../../cre-sdk-javy-plugin/scripts/parse-compile-flags'
4
+ import { parseCompileCliArgs, skipTypeChecksFlag } from './compile-cli-args'
5
5
  import { main as compileToJs } from './compile-to-js'
6
6
  import { main as compileToWasm } from './compile-to-wasm'
7
7
 
8
+ type CompileWorkflowOptions = {
9
+ skipTypeChecks?: boolean
10
+ }
11
+
12
+ const printUsage = () => {
13
+ console.error(
14
+ `Usage: bun compile:workflow <path/to/workflow.ts> [path/to/output.wasm] [${skipTypeChecksFlag}]`,
15
+ )
16
+ console.error('Examples:')
17
+ console.error(' bun compile:workflow src/standard_tests/secrets/test.ts')
18
+ console.error(
19
+ ' bun compile:workflow src/standard_tests/secrets/test.ts .temp/standard_tests/secrets/test.wasm',
20
+ )
21
+ console.error(
22
+ ` bun compile:workflow src/standard_tests/secrets/test.ts .temp/standard_tests/secrets/test.wasm ${skipTypeChecksFlag}`,
23
+ )
24
+ }
25
+
8
26
  export const main = async (
9
27
  inputFile?: string,
10
28
  outputWasmFile?: string,
11
- creExportsPaths?: string[],
12
- pluginPath?: string | null,
29
+ options?: CompileWorkflowOptions,
13
30
  ) => {
14
- const cliArgs = process.argv.slice(3)
15
- const { creExports: cliCreExports, plugin: cliPlugin, rest: cliRest } = parseCompileFlags(cliArgs)
16
-
17
- const inputPath = inputFile ?? cliRest[0]
18
- const outputPathArg = outputWasmFile ?? cliRest[1]
19
- const creExports = creExportsPaths ?? cliCreExports
20
- const plugin = pluginPath !== undefined ? pluginPath : cliPlugin
31
+ let parsedInputPath: string | undefined
32
+ let parsedOutputPath: string | undefined
33
+ let parsedSkipTypeChecks = false
21
34
 
22
- if (plugin != null && plugin !== '' && creExports.length > 0) {
23
- console.error('โŒ Error: --plugin and --cre-exports are mutually exclusive.')
24
- process.exit(1)
35
+ if (inputFile != null || outputWasmFile != null || options?.skipTypeChecks != null) {
36
+ parsedInputPath = inputFile
37
+ parsedOutputPath = outputWasmFile
38
+ parsedSkipTypeChecks = options?.skipTypeChecks ?? false
39
+ } else {
40
+ try {
41
+ const parsed = parseCompileCliArgs(process.argv.slice(3))
42
+ parsedInputPath = parsed.inputPath
43
+ parsedOutputPath = parsed.outputPath
44
+ parsedSkipTypeChecks = parsed.skipTypeChecks
45
+ } catch (error) {
46
+ console.error(error instanceof Error ? error.message : error)
47
+ printUsage()
48
+ process.exit(1)
49
+ }
25
50
  }
26
51
 
52
+ const inputPath = parsedInputPath
53
+ const outputPathArg = parsedOutputPath
54
+
27
55
  if (!inputPath) {
28
- console.error('Usage: bun compile:workflow <path/to/workflow.ts> [path/to/output.wasm]')
56
+ printUsage()
29
57
  process.exit(1)
30
58
  }
31
59
 
@@ -35,33 +63,33 @@ export const main = async (
35
63
  process.exit(1)
36
64
  }
37
65
 
66
+ // Default final output = same dir, same basename, .wasm
38
67
  const defaultWasmOut = path.join(
39
68
  path.dirname(resolvedInput),
40
69
  path.basename(resolvedInput).replace(/\.[^.]+$/, '.wasm'),
41
70
  )
42
71
  const resolvedWasmOutput = outputPathArg ? path.resolve(outputPathArg) : defaultWasmOut
72
+
73
+ // Put the intermediate JS next to the final wasm (so custom outputs stay together)
43
74
  const resolvedJsOutput = resolvedWasmOutput.replace(/\.wasm$/i, '.js')
44
75
 
76
+ // Ensure directories exist (handles both intermediate JS dir and wasm dir)
45
77
  await mkdir(path.dirname(resolvedJsOutput), { recursive: true })
46
78
 
47
- console.info('๐Ÿš€ Compiling workflow')
48
- console.info(`๐Ÿ“ Input: ${resolvedInput}`)
49
- console.info(`๐Ÿงช JS out: ${resolvedJsOutput}`)
50
- console.info(`๐ŸŽฏ WASM out:${resolvedWasmOutput}\n`)
79
+ console.info(`๐Ÿš€ Compiling workflow`)
80
+ console.info(`๐Ÿ“ Input: ${resolvedInput}\n`)
81
+ if (parsedSkipTypeChecks) {
82
+ console.info(`โš ๏ธ Skipping TypeScript checks (${skipTypeChecksFlag})`)
83
+ }
51
84
 
85
+ // Step 1: TS/JS โ†’ JS (bundled)
52
86
  console.info('๐Ÿ“ฆ Step 1: Compiling JS...')
53
- await compileToJs(resolvedInput, resolvedJsOutput)
87
+ await compileToJs(resolvedInput, resolvedJsOutput, { skipTypeChecks: parsedSkipTypeChecks })
54
88
 
89
+ // Step 2: JS โ†’ WASM
55
90
  console.info('\n๐Ÿ”จ Step 2: Compiling to WASM...')
56
- await compileToWasm(resolvedJsOutput, resolvedWasmOutput, creExports, plugin)
91
+ await compileToWasm(resolvedJsOutput, resolvedWasmOutput)
57
92
 
58
93
  console.info(`\nโœ… Workflow built: ${resolvedWasmOutput}`)
59
94
  return resolvedWasmOutput
60
95
  }
61
-
62
- if (import.meta.main) {
63
- main().catch((e) => {
64
- console.error(e)
65
- process.exit(1)
66
- })
67
- }
@@ -78,34 +78,16 @@ const CHAIN_CONFIGS: ChainSelectorConfig[] = [
78
78
  },
79
79
  ]
80
80
 
81
- const readYamlFile = (filename: string): string => {
82
- // Look for chain-selectors in node_modules by trying multiple possible locations
83
- // This handles different execution contexts (local dev, CI, etc.)
84
- const possiblePaths = [
85
- // Try workspace root (3 levels up from scripts/)
86
- join(process.cwd(), '..', '..', '..', 'node_modules', 'chain-selectors', filename),
87
- // Try 2 levels up (in case cwd is already in scripts/src/)
88
- join(process.cwd(), '..', '..', 'node_modules', 'chain-selectors', filename),
89
- // Try current directory's node_modules
90
- join(process.cwd(), 'node_modules', 'chain-selectors', filename),
91
- // Try parent directory's node_modules
92
- join(process.cwd(), '..', 'node_modules', 'chain-selectors', filename),
93
- ]
94
-
95
- for (const path of possiblePaths) {
96
- try {
97
- return readFileSync(path, 'utf-8')
98
- } catch {
99
- // Try next path
100
- continue
101
- }
102
- }
81
+ const resolveChainSelectorsDir = (): string => {
82
+ // Use require.resolve to find the package through bun/Node module resolution,
83
+ // which correctly handles workspace hoisting, .bun cache, etc.
84
+ const packageDir = require.resolve('chain-selectors/selectors.yml')
85
+ return join(packageDir, '..')
86
+ }
103
87
 
104
- throw new Error(
105
- `Failed to find ${filename} in any of the expected locations. Tried:\n${possiblePaths.join(
106
- '\n',
107
- )}`,
108
- )
88
+ const readYamlFile = (filename: string): string => {
89
+ const filePath = join(resolveChainSelectorsDir(), filename)
90
+ return readFileSync(filePath, 'utf-8')
109
91
  }
110
92
 
111
93
  const parseChainSelectors = (): NetworkInfo[] => {