@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.
- package/README.md +18 -1
- package/bin/cre-compile.ts +39 -17
- package/dist/generated/capabilities/blockchain/evm/v1alpha/client_pb.js +1 -1
- package/dist/generated/chain-selectors/mainnet/evm/ab-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/ab-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/adi-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/adi-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/edge-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/edge-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/everclear-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/everclear-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/gate-chain-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/gate-chain-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/gate-layer-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/gate-layer-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/jovay-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/jovay-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/megaeth-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/megaeth-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/pharos-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/pharos-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/stable-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/stable-mainnet.js +12 -0
- package/dist/generated/chain-selectors/mainnet/evm/tempo-mainnet.d.ts +3 -0
- package/dist/generated/chain-selectors/mainnet/evm/tempo-mainnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/0g-testnet-galileo-1.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/0g-testnet-galileo-1.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/ab-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/ab-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/adi-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/adi-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/arc-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/arc-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/celo-sepolia.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/celo-sepolia.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/dogeos-testnet-chikyu.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/dogeos-testnet-chikyu.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/edge-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/edge-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-morph.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-morph.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko-1.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko-1.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi-taiko.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-hoodi.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-sepolia-ronin-1.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/ethereum-testnet-sepolia-ronin-1.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/everclear-testnet-sepolia.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/everclear-testnet-sepolia.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/gate-chain-testnet-meteora.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/gate-chain-testnet-meteora.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/gate-layer-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/gate-layer-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/megaeth-testnet-2.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/megaeth-testnet-2.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/pharos-atlantic-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/pharos-atlantic-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/robinhood-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/robinhood-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/sonic-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/sonic-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/stable-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/stable-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/tempo-testnet-moderato.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/tempo-testnet-moderato.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/tempo-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/tempo-testnet.js +12 -0
- package/dist/generated/chain-selectors/testnet/evm/xlayer-testnet.d.ts +3 -0
- package/dist/generated/chain-selectors/testnet/evm/xlayer-testnet.js +12 -0
- package/dist/generated/networks.d.ts +2 -2
- package/dist/generated/networks.js +238 -0
- package/dist/generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen.d.ts +24 -0
- package/dist/generated-sdk/capabilities/blockchain/evm/v1alpha/client_sdk_gen.js +24 -0
- package/dist/index.d.ts +3 -0
- package/dist/sdk/types/global.d.ts +146 -2
- package/dist/sdk/types/restricted-apis.d.ts +18 -23
- package/dist/sdk/types/restricted-node-modules.d.ts +462 -0
- package/dist/sdk/utils/capabilities/blockchain/blockchain-helpers.d.ts +40 -3
- package/dist/sdk/utils/capabilities/blockchain/blockchain-helpers.js +80 -6
- package/dist/sdk/utils/prepare-runtime.d.ts +1 -1
- package/dist/sdk/utils/prepare-runtime.js +9 -2
- package/dist/sdk/wasm/host-bindings.d.ts +4 -4
- package/package.json +5 -5
- package/scripts/run.ts +11 -1
- package/scripts/src/build-types.ts +31 -1
- package/scripts/src/compile-cli-args.test.ts +32 -0
- package/scripts/src/compile-cli-args.ts +35 -0
- package/scripts/src/compile-to-js.test.ts +90 -0
- package/scripts/src/compile-to-js.ts +51 -13
- package/scripts/src/compile-to-wasm.ts +35 -34
- package/scripts/src/compile-workflow.ts +55 -27
- package/scripts/src/generate-chain-selectors.ts +9 -27
- package/scripts/src/typecheck-workflow.test.ts +77 -0
- package/scripts/src/typecheck-workflow.ts +96 -0
- package/scripts/src/validate-workflow-runtime-compat.test.ts +433 -0
- 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": "
|
|
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": "
|
|
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": "
|
|
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#
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
|
|
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 =
|
|
12
|
-
const outputPathArg =
|
|
50
|
+
const inputPath = parsedInputPath
|
|
51
|
+
const outputPathArg = parsedOutputPath
|
|
13
52
|
|
|
14
53
|
if (!inputPath) {
|
|
15
|
-
|
|
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
|
-
|
|
58
|
-
|
|
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 ${
|
|
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
|
-
|
|
5
|
-
|
|
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
|
-
|
|
19
|
-
const
|
|
20
|
-
const
|
|
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(
|
|
60
|
+
console.info(`๐จ Compiling to WASM`)
|
|
55
61
|
console.info(`๐ Input: ${resolvedInput}`)
|
|
56
62
|
console.info(`๐ฏ Output: ${resolvedOutput}`)
|
|
57
63
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
-
|
|
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 {
|
|
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
|
-
|
|
12
|
-
pluginPath?: string | null,
|
|
29
|
+
options?: CompileWorkflowOptions,
|
|
13
30
|
) => {
|
|
14
|
-
|
|
15
|
-
|
|
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 (
|
|
23
|
-
|
|
24
|
-
|
|
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
|
-
|
|
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(
|
|
48
|
-
console.info(`๐ Input: ${resolvedInput}`)
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
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
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
105
|
-
|
|
106
|
-
|
|
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[] => {
|