diff --git a/packages/cli/src/compile/compile.ts b/packages/cli/src/compile/compile.ts index 30c9959f1..01c98837b 100644 --- a/packages/cli/src/compile/compile.ts +++ b/packages/cli/src/compile/compile.ts @@ -5,6 +5,7 @@ import compile, { preloadAdaptorExports, Options, getExports, + transformers as t, } from '@openfn/compiler'; import { getModulePath, type ExecutionPlan, type Job } from '@openfn/runtime'; import type { SourceMapWithOperations } from '@openfn/lexicon'; @@ -56,11 +57,15 @@ const compileJob = async ( jobName?: string ): Promise => { try { + let transformers: any = undefined; const compilerOptions: Options = await loadTransformOptions(opts, log); + if (opts.exportsOnly) { + transformers = [t.exportsOnly, t.lazyState, t.promises, t.addImports]; + } if (jobName) { compilerOptions.name = jobName; } - return compile(job, compilerOptions); + return compile(job, compilerOptions, transformers); } catch (e: any) { abort( log, @@ -141,12 +146,6 @@ export const loadTransformOptions = async ( trace: opts.trace, }; - if (opts.exportsOnly) { - options['exports-only'] = true; - // ensure-exports and top-level-operations produce output incompatible with exports-only mode - options['ensure-exports'] = false; - options['top-level-operations'] = false; - } if (opts.adaptors?.length && opts.ignoreImports != true) { const adaptorsConfig = []; for (const adaptorInput of opts.adaptors) { diff --git a/packages/cli/test/compile/compile.test.ts b/packages/cli/test/compile/compile.test.ts index da1c7c9c9..cab8e333b 100644 --- a/packages/cli/test/compile/compile.test.ts +++ b/packages/cli/test/compile/compile.test.ts @@ -495,17 +495,6 @@ test.serial('loadTransformOptions: ignore some imports', async (t) => { // TODO test exception if the module can't be found -test.serial( - 'loadTransformOptions: --exports-only enables exports-only transformer', - async (t) => { - const opts = { exportsOnly: true } as CompileOptions; - const result = await loadTransformOptions(opts, mockLog); - t.is(result['exports-only'], true); - t.is(result['ensure-exports'], false); - t.is(result['top-level-operations'], false); - } -); - test.serial( 'loadTransformOptions: --exports-only does not affect other options', async (t) => { diff --git a/packages/compiler/src/compile.ts b/packages/compiler/src/compile.ts index 297682cbe..9899c08c3 100644 --- a/packages/compiler/src/compile.ts +++ b/packages/compiler/src/compile.ts @@ -2,7 +2,7 @@ import { print } from 'recast'; import createLogger, { Logger } from '@openfn/logger'; import parse from './parse'; -import transform, { TransformOptions } from './transform'; +import transform, { TransformOptions, Transformer } from './transform'; import { isPath, loadFile } from './util'; import type { SourceMapWithOperations } from '@openfn/lexicon'; @@ -23,7 +23,8 @@ export type Options = TransformOptions & { export default function compile( pathOrSource: string, - options: Options = {} + options: Options = {}, + transformers?: Transformer[] ): { code: string; map?: SourceMapWithOperations; @@ -42,7 +43,7 @@ export default function compile( const name = options.name ?? 'src'; const trace = options.trace; const ast = parse(source, { logger, name, trace }); - const transformedAst = transform(ast, undefined, options); + const transformedAst = transform(ast, transformers, options); const { code, map } = print(transformedAst, { sourceMapName: `${name}.map.js`, diff --git a/packages/compiler/src/index.ts b/packages/compiler/src/index.ts index 401388960..00b94ed5a 100644 --- a/packages/compiler/src/index.ts +++ b/packages/compiler/src/index.ts @@ -2,6 +2,7 @@ import compile from './compile'; export { default as getExports } from './get-exports'; export * from './util'; +export * as transformers from './transforms/index'; export type { TransformOptions } from './transform'; export type { Options } from './compile'; export default compile; diff --git a/packages/compiler/src/transform.ts b/packages/compiler/src/transform.ts index bac5e4f69..367b9fa53 100644 --- a/packages/compiler/src/transform.ts +++ b/packages/compiler/src/transform.ts @@ -5,7 +5,6 @@ import createLogger, { Logger } from '@openfn/logger'; import addImports, { AddImportsOptions } from './transforms/add-imports'; import ensureExports from './transforms/ensure-exports'; -import exportsOnly from './transforms/exports-only'; import lazyState from './transforms/lazy-state'; import promises from './transforms/promises'; import topLevelOps, { @@ -63,7 +62,6 @@ export default function transform( if (!transformers) { transformers = [ - exportsOnly, lazyState, promises, ensureExports, diff --git a/packages/compiler/src/transforms/exports-only.ts b/packages/compiler/src/transforms/exports-only.ts index 6a51df5b6..c07e81024 100644 --- a/packages/compiler/src/transforms/exports-only.ts +++ b/packages/compiler/src/transforms/exports-only.ts @@ -40,13 +40,7 @@ const declaresName = (node: any, names: Set) => { return false; }; -function visitor( - programPath: NodePath, - _logger: any, - options: boolean | {} = {} -) { - if (options !== true) return; - +function visitor(programPath: NodePath) { const { body } = programPath.node; const exportListNames = findExportListNames(body); diff --git a/packages/compiler/src/transforms/index.ts b/packages/compiler/src/transforms/index.ts new file mode 100644 index 000000000..765e80e99 --- /dev/null +++ b/packages/compiler/src/transforms/index.ts @@ -0,0 +1,9 @@ +export { default as addImports } from './add-imports'; +export { default as ensureExports } from './ensure-exports'; +export { default as exportsOnly } from './exports-only'; +export { default as lazyState } from './lazy-state'; +export { default as promises } from './promises'; +export { default as topLevelOps } from './top-level-operations'; + +export type { AddImportsOptions } from './add-imports'; +export type { TopLevelOpsOptions } from './top-level-operations'; diff --git a/packages/compiler/test/compile.test.ts b/packages/compiler/test/compile.test.ts index 0f44148f5..529f3889f 100644 --- a/packages/compiler/test/compile.test.ts +++ b/packages/compiler/test/compile.test.ts @@ -2,6 +2,7 @@ import test from 'ava'; import fs from 'node:fs/promises'; import path from 'node:path'; import compile from '../src/compile'; +import exportsOnly from '../src/transforms/exports-only'; // Not doing deep testing on this because recast does the heavy lifting // This is just to ensure the map is actually generated @@ -285,46 +286,17 @@ const exportsOnlyOpts = { 'top-level-operations': false, } as const; -test('exports-only: removes top-level operations, keeps exported JS', (t) => { +test('only run transformers that are passed in', (t) => { const source = [ 'export const formatDate = (d) => d.toISOString();', 'get("/api");', 'fn(state => ({ ...state, date: formatDate(state.data.date) }));', ].join('\n'); - const { code: result } = compile(source, exportsOnlyOpts); + const { code: result } = compile(source, exportsOnlyOpts, [exportsOnly]); t.true(result.includes('export const formatDate')); t.false(result.includes('get(')); t.false(result.includes('fn(state')); t.false(result.includes('export default []')); }); - -test('exports-only: removes non-exported declarations', (t) => { - const source = [ - 'const formatDate = (d) => d.toISOString();', - 'get("/api");', - ].join('\n'); - - const { code: result } = compile(source, exportsOnlyOpts); - - // non-exported const is dropped; no export default [] - t.false(result.includes('const formatDate')); - t.false(result.includes('get(')); - t.false(result.includes('export default []')); -}); - -test('exports-only: keeps import statements', (t) => { - const source = [ - 'import { dateFns } from "@openfn/language-common";', - 'export const formatDate = (d) => dateFns.format(d);', - 'get("/api");', - 'export default [];', - ].join('\n'); - - const { code: result } = compile(source, exportsOnlyOpts); - - t.true(result.includes('import { dateFns }')); - t.true(result.includes('export const formatDate')); - t.false(result.includes('get(')); -}); diff --git a/packages/compiler/test/transforms/exports-only.test.ts b/packages/compiler/test/transforms/exports-only.test.ts index cc9b1c64a..49302cddb 100644 --- a/packages/compiler/test/transforms/exports-only.test.ts +++ b/packages/compiler/test/transforms/exports-only.test.ts @@ -27,16 +27,6 @@ fn();`; t.is(after, before); }); -test('is a no-op if no options are passed', (t) => { - const before = `const x = 42; -fn();`; - const ast = parse(before); - const transformed = transform(ast, [visitors]); - const after = print(transformed).code; - - t.is(after, before); -}); - test('strips operation calls', (t) => { const before = `get(); fn();`;