-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
cli: hook up a basic generate command
- Loading branch information
1 parent
d5a740b
commit b353c8c
Showing
5 changed files
with
419 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/** | ||
* Handler to generate adaptor code | ||
*/ | ||
|
||
import { Opts } from '../options'; | ||
import { Logger } from '../util'; | ||
import mailchimp from './mailchimp-spec.json' assert { type: 'json' }; | ||
|
||
// TODO: really I just want one domain here | ||
const endpoints = { | ||
signature: 'http://localhost:8001/generate_signature', | ||
code: 'http://localhost:8002/generate_code/', | ||
}; | ||
|
||
type AdaptorGenOptions = Pick< | ||
Opts, | ||
| 'command' | ||
| 'path' // path to spec - we proably want to override the description | ||
| 'log' // same log rules | ||
| 'logJson' | ||
| 'monorepoPath' // maybe use the monorepo (or use env var) | ||
| 'outputPath' // where to output to. Defaults to monorepo or as sibling of the spec | ||
> & { | ||
adaptor: string; | ||
|
||
// TODO spec overrides | ||
}; | ||
|
||
// spec.spec is silly, so what is this object? | ||
type Spec = { | ||
spec: any; // OpenAPI spec | ||
|
||
instruction: string; // for now... but we'll use endpoints later | ||
|
||
endpoints?: string[]; // TODO not supported yet | ||
|
||
model?: string; // TODO not supported yet | ||
}; | ||
|
||
const generateAdaptor = async (opts: any, logger: Logger) => { | ||
logger.success('** GENERATE ADAPTOR**'); | ||
// if we're using the monorepo, and no adaptor with this name exists | ||
// prompt to generate it | ||
// humm is that worth it? it'll create a git diff anyway | ||
|
||
// TODO load spec from path | ||
// gonna hard code it right now | ||
const spec = { | ||
spec: mailchimp, // post as open_api_spec | ||
instruction: 'Create an OpenFn function that accesses the /goals endpoint', | ||
}; | ||
|
||
const sig = await generateSignature(spec, logger); | ||
const code = await generateCode(spec, sig, logger); | ||
|
||
// Now we need to output to disk | ||
|
||
return { sig, code }; | ||
}; | ||
|
||
export default generateAdaptor; | ||
|
||
// throw if the spec is missing anything | ||
const validateSpec = () => {}; | ||
|
||
// this will generate a basic package for the adaptor | ||
// what is a good way to do this? | ||
const generatePackageTemplate = () => { | ||
// package json | ||
// src | ||
// Adaptor.js | ||
// index.js | ||
// readme.md | ||
}; | ||
|
||
const convertSpec = (spec: Spec) => | ||
JSON.stringify({ | ||
open_api_spec: spec.spec, | ||
instruction: spec.instruction, | ||
model: 'gpt3_turbo', | ||
}); | ||
|
||
const generateSignature = async (spec: Spec, logger: Logger) => { | ||
// generate signature | ||
const result = await fetch(endpoints.signature, { | ||
method: 'POST', | ||
body: convertSpec(spec), | ||
headers: { | ||
['Content-Type']: 'application/json', | ||
}, | ||
}); | ||
const json = await result.json(); | ||
logger.success('Generated signature:\n', json.signature); | ||
|
||
// TODO write output | ||
|
||
return json.signature; | ||
}; | ||
|
||
const generateCode = async (spec: Spec, signature: string, logger: Logger) => { | ||
const result = await fetch(endpoints.code, { | ||
method: 'POST', | ||
body: JSON.stringify({ | ||
// TODO why doesn't code gen use the spec?? | ||
signature, | ||
model: 'gpt3_turbo', | ||
}), | ||
headers: { | ||
['Content-Type']: 'application/json', | ||
}, | ||
}); | ||
const json = await result.json(); | ||
logger.success('Generated code:\n', json.implementation); | ||
return json.implementation; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import yargs from 'yargs'; | ||
import * as o from '../options'; | ||
import type { Opts } from '../options'; | ||
import { build, ensure } from '../util/command-builders'; | ||
|
||
export type TestOptions = Pick<Opts, 'stateStdin' | 'log' | 'logJson'>; | ||
|
||
const options = [o.log, o.logJson, o.useAdaptorsMonorepo, o.outputPath]; | ||
|
||
options.push({ | ||
name: 'adaptor', | ||
yargs: { | ||
description: 'The name of the adaptor to generate', | ||
}, | ||
} as o.CLIOption); | ||
|
||
// Adaptor generation subcommand | ||
const adaptor = { | ||
command: 'adaptor', | ||
desc: 'Generate adaptor code', | ||
handler: ensure('generate-adaptor', options), | ||
builder: (yargs) => | ||
build(options, yargs) | ||
.example( | ||
'generate adaptor ./spec.json', | ||
'Generate adaptor code based on spec.json' | ||
) | ||
.positional('path', { | ||
describe: 'The path spec.json', | ||
demandOption: true, | ||
}), | ||
} as yargs.CommandModule<{}>; | ||
|
||
export default { | ||
command: 'generate [subcommand]', | ||
desc: 'Generate code (only adaptors supported now)', | ||
handler: () => { | ||
// TODO: better error handling | ||
console.error('ERROR: invalid command'); | ||
console.error('Try:\n\n openfn generate adaptor\n'); | ||
}, | ||
builder: (yargs: yargs.Argv) => | ||
yargs | ||
.command(adaptor) | ||
.example( | ||
'generate adaptor ./spec.json', | ||
'Generate adaptor code based on spec.json' | ||
), | ||
} as yargs.CommandModule<{}>; |
Oops, something went wrong.