diff --git a/packages/component_code_gen/code_gen/generate_component_code.py b/packages/component_code_gen/code_gen/generate_component_code.py index d11c4b203e7f4..6e9da8bce93ce 100644 --- a/packages/component_code_gen/code_gen/generate_component_code.py +++ b/packages/component_code_gen/code_gen/generate_component_code.py @@ -38,7 +38,7 @@ def generate_code(app, prompt, templates, parsed_common_files, urls_content, tri docs_meta = {} # XXX - temporarily disable supabase docs results = [] - auth_details = "## Auth details\n\nThese details come directly from the app configuration in Pipedream. Prioritize this information over any other information you find in the app's docs, since this section is specific to Pipedream." + auth_details = "\n\nThese details come directly from the app configuration in Pipedream. Prioritize this information over any other information you find in the app's docs, since this section is specific to Pipedream." auth_meta = db.get_app_auth_meta(app) auth_type = auth_meta.get('auth_type') if auth_type == "keys": @@ -48,7 +48,9 @@ def generate_code(app, prompt, templates, parsed_common_files, urls_content, tri elif auth_type == "oauth": auth_details += f"{app} is an OAuth app. The `this` object exposes the OAuth access token in the variable `this.#{app.name_slug}.$auth.oauth_access_token`. When you make an API request, use the format from the \"Auth example\" section below." if auth_meta.get('component_code_scaffold_raw'): - auth_details = f"\n\n## Auth example\n\nHere's example Node.js code to show how authentication is done in {app}:\n\n{auth_meta['component_code_scaffold_raw']}\n\n" + auth_details += f"\n\n## Auth example\n\nHere's example Node.js code to show how authentication is done in {app}:\n\n{auth_meta['component_code_scaffold_raw']}\n\n" + + auth_details += "" normal_order = False for i in range(tries): diff --git a/packages/component_code_gen/templates/actions/additional_rules.py b/packages/component_code_gen/templates/actions/additional_rules.py index 321329564653a..8b8bb998867b5 100644 --- a/packages/component_code_gen/templates/actions/additional_rules.py +++ b/packages/component_code_gen/templates/actions/additional_rules.py @@ -1,36 +1,58 @@ -additional_rules = """## Additional rules for actions +additional_rules = """ 1. Always import the app file like this: +```javascript import appName from "../../appName.app.mjs"; +``` + +and pass the app file as a prop to the component: + +```javascript +export default { + props: { + appName, + }, + // rest of the component ... +} +``` 2. `return` the final value from the step. The data returned from steps must be JSON-serializable. The returned data is displayed in Pipedream. Think about it: if you don't return the data, the user won't see it. 3. Always use this signature for the run method: +```javascript async run({ $ }) { - // your code here + // you must fill in the actual code here } +``` -Always pass { $ }, even if you don't use them in the code. +Always pass `{ $ }` in the arguments to the `run` method, even if you don't use it in the code. -4. Remember that `@pipedream/platform` axios returns a Promise that resolves to the HTTP response data. There is NO `data` property in the response that contains the data. The data from the HTTP response is returned directly in the response, not in the `data` property. Think about it: if you try to extract a data property that doesn't exist, the variable will hold the value `undefined`. You must return the data from the response directly and extract the proper data in the format provided by the API docs. +4. `@pipedream/platform` axios returns a Promise that resolves to the HTTP response data. There is NO `data` property in the response that contains the data. The data from the HTTP response is returned directly in the response, not in the `data` property. Think about it: if you try to extract a data property that doesn't exist, the variable will hold the value `undefined`. You must return the data from the response directly and extract the proper data in the format provided by the API docs. For example, do this: +```javascript const response = await axios(this, { url: `https://api.stability.ai/v1/engines/list`, headers: { Authorization: `Bearer ${this.dreamstudio.$auth.api_key}`, }, }); -// process the response data. response.data is undefined +// process the `response` as the return data. `response.data` is undefined, data is directly in `response` +``` not this: +```javascript +// this is incorrect — there is no `data` property in the response const { data } = await axios(this, { url: `https://api.stability.ai/v1/engines/list`, headers: { Authorization: `Bearer ${this.dreamstudio.$auth.api_key}`, }, -});""" +}); +``` + +""" diff --git a/packages/component_code_gen/templates/actions/export_summary.py b/packages/component_code_gen/templates/actions/export_summary.py index d4cd8f45398a1..784d2a0b86485 100644 --- a/packages/component_code_gen/templates/actions/export_summary.py +++ b/packages/component_code_gen/templates/actions/export_summary.py @@ -1,12 +1,15 @@ -export_summary = """## Export summary +export_summary = """ -A short summary should be exported before the end so that the user can quickly read what has happened. This is done by calling `$.export("$summary", "Your summary here")`. This is not optional. +You must call `$.export` to export a short text summary near the end of the `run` method so the user knows the call was successful. This is done by calling `$.export("$summary", "Your summary here")`. -The summary should contain relevant metadata about the object that was created, updated, or deleted. For example, if you are creating a new issue, you should include the issue name or ID in the summary. +The summary should contain relevant metadata about the object that was created, updated, or deleted. For example, if you are creating a new issue, you should include the issue name or ID in the summary. Include information here that you think will be most relevant for the user reading the summary. -``` -`$.export("$summary", `Created issue ${name}`) +Generally, this should happen immediately before you return the data at the end of the component's `run` method. + +```javascript +$.export("$summary", `Created issue ${name}`) +return data ``` -Include information here that you think will be most relevant for the user. + """ diff --git a/packages/component_code_gen/templates/actions/introduction.py b/packages/component_code_gen/templates/actions/introduction.py index a058d094e1e29..df98dbc9c894a 100644 --- a/packages/component_code_gen/templates/actions/introduction.py +++ b/packages/component_code_gen/templates/actions/introduction.py @@ -1,9 +1,31 @@ -introduction = """## Instructions +introduction = """ -Your goal is to create Pipedream Action Components. Your code should solve the requirements provided below. + +Your goal is to create Pipedream action components, defined in the section below. -Other GPT agents will be reviewing your work, and will provide feedback on your code. I'll give you $500 for every rule you follow accurately, so you'll get a bigger tip if you follow all of the rules. +Your code should solve the requirements provided below. -## Pipedream components +Think step by step: -All Pipedream components are Node.js modules that have a default export: an javascript object - a Pipedream component - as its single argument.""" +1. Review the requirements +2. Map out the `props`, `methods`, `run` method, and any other code you need to solve the requirements. +3. Review whether you need async options for props (see the section below) +4. Review all of the rules carefully before producing code +5. Produce full, complete, working code. This code is going straight to production. +6. Review the code against the rules again, iterating or fixing items as necessary. +7. Output the final code according to the rules of the section below. + +Other GPT agents will be reviewing your work, and will provide feedback on your code. Please review it before producing output. + + + + + +All Pipedream components are Node.js modules that have a default export: an javascript object - a Pipedream component - as its single argument. + +See the , , , and other sections below for details on how to structure components. + + + + +""" diff --git a/packages/component_code_gen/templates/actions/main_example.py b/packages/component_code_gen/templates/actions/main_example.py index fe1ee26a376c8..87b58d5333a50 100644 --- a/packages/component_code_gen/templates/actions/main_example.py +++ b/packages/component_code_gen/templates/actions/main_example.py @@ -1,8 +1,9 @@ -main_example = """## OpenAI example component +main_example = """ + -Here's an example component: +Here's an example Pipedream action for OpenAI that lists all models available to the user: -``` +```javascript import openai from "../../openai.app.mjs" import { axios } from "@pipedream/platform" @@ -26,4 +27,7 @@ return response }, }; -```""" +``` + + +""" diff --git a/packages/component_code_gen/templates/actions/other_example.py b/packages/component_code_gen/templates/actions/other_example.py index b0386d0e64c1e..27a06af318134 100644 --- a/packages/component_code_gen/templates/actions/other_example.py +++ b/packages/component_code_gen/templates/actions/other_example.py @@ -1,8 +1,9 @@ -other_example = """## Slack API example component +other_example = """ + Here's an example Pipedream component that makes a test request against the Slack API: -``` +```javascript import slack from "../../slack.app.mjs" import { axios } from "@pipedream/platform" @@ -41,18 +42,22 @@ return response }, }; +``` Notice this section: +```javascript data: { channel: this.channel, text: this.text, }, +``` -This shows you how to pass the values of props (e.g. this.channel and this.text) as params to the API. This is one of the most important things to know: you MUST generate code that adds inputs as props so that users can enter their own values when making the API request. You MUST NOT pass static values. See rule #2 below for more detail. +This shows you how to pass the values of props (e.g. `this.channel` and `this.text`) as params to the API. This is one of the most important things to know: you MUST generate code that adds inputs as props so that users can enter their own values when making the API request. You MUST NOT pass static values. See the for more information. The code you generate should be placed within the `run` method of the Pipedream component: +```javascript import { axios } from "@pipedream/platform"; export default { @@ -69,4 +74,8 @@ $.export("$summary", "Your summary here") return response }, -};""" +}; +``` + + +""" diff --git a/packages/component_code_gen/templates/apps/additional_rules.py b/packages/component_code_gen/templates/apps/additional_rules.py index 2f9f263388bba..2dee9b58a02f6 100644 --- a/packages/component_code_gen/templates/apps/additional_rules.py +++ b/packages/component_code_gen/templates/apps/additional_rules.py @@ -1,6 +1,7 @@ -additional_rules = """## Additional rules +additional_rules = """ -### Generate propDefinitions and methods for ALL requirements +1. Generate `propDefinitions` and `methods` for ALL requirements -The instructions should note the actions and source components that are required for the app. The code generator should generate the propDefinitions and methods for ALL requirements. Think about it: this way other agents will be able to use the shared props + methods in the action and source components. Double-check your output to make sure that the propDefinitions and methods are generated for ALL requirements. +The instructions should note the actions and source components that are required for the app. The code generator should generate the `propDefinitions` and `methods` for ALL requirements. Think about it: this way other agents will be able to use the shared props + methods in the action and source components. Double-check your output to make sure that the propDefinitions and methods are generated for ALL requirements. + """ diff --git a/packages/component_code_gen/templates/apps/introduction.py b/packages/component_code_gen/templates/apps/introduction.py index ab1751fe3101d..c2a6faaf473c0 100644 --- a/packages/component_code_gen/templates/apps/introduction.py +++ b/packages/component_code_gen/templates/apps/introduction.py @@ -1,20 +1,42 @@ -introduction = """## Instructions +introduction = """ -Your goal is to create Pipedream app files. Your code should solve the requirements provided below. + +Your goal is to create Pipedream app files, defined in the Definition section below. -DO NOT remove any propDefinitions or methods that already exist. You can only write more, if required. +Your code should solve the requirements provided below. -Other GPT agents will be reviewing your work, and will provide feedback on your code. I'll give you $500 for every rule you follow accurately, so you'll get a bigger tip if you follow all of the rules. +Think step by step: -## Pipedream App files +1. Review the requirements +2. Map out the props and methods you need to solve the requirements +3. Review whether you need async options for props (see the section below) +4. Review all of the rules carefully before producing code +5. Produce full, complete, working code. This code is going straight to production. +6. Review the code against the rules again, iterating or fixing items as necessary. +7. Output the final code according to the rules of the section below. + +Other GPT agents will be reviewing your work, and will provide feedback on your code. Please review it before producing output. + + + + All Pipedream app files are Node.js modules that have a default export: a javascript object - a Pipedream app - as its single argument. -All app objects have four properties: type, app, propDefinitions, and methods: +All app objects have four properties: `type`, `app`, `propDefinitions`, and `methods`: - The `type` property is always set to "app". - The `app` property is the name of the app, e.g. "google_sheets". - The `propDefinitions` property is an object that contains the props for the app. -- The methods property is an object that contains the methods for the app. +- The `methods` property is an object that contains the methods for the app. + +These props and methods are shared across components for this app file. You'll need to generate props and methods for ALL requirements for all components that you're passed below. + + + +Output Node.js code. + +DO NOT remove any `propDefinitions` or `methods` that already exist. You can only write more, if required. + -These props and methods are shared across components for this app file. You'll need to generate props and methods for ALL requirements for all components that you're passed below.""" +""" diff --git a/packages/component_code_gen/templates/apps/main_example.py b/packages/component_code_gen/templates/apps/main_example.py index f221fb4f5e3e5..9df270f50cf84 100644 --- a/packages/component_code_gen/templates/apps/main_example.py +++ b/packages/component_code_gen/templates/apps/main_example.py @@ -1,4 +1,5 @@ -main_example = """## Example app file for Raindrop +main_example = """ + Here's an example Pipedream app for Raindrop: @@ -87,15 +88,17 @@ }, }; ``` + + +App files contain a `propDefinitions` property, which contains the definitions for the props of the app. -This object contains a `propDefinitions` property, which contains the definitions for the props of the app. - -The propDefinitions object contains two props: collectionId and raindropId. The collectionId prop is a string prop. The raindropId prop is also a string prop. The propDefinitions object also contains an `options` method. The `options` method is an optional method that can be defined on a prop. It is used to dynamically generate the options for a prop and can return a static array of options or a Promise that resolves to an array of options. +The `propDefinitions` object contains two props: `collectionId` and `raindropId`. The `collectionId` prop is a string prop. The `raindropId` prop is also a string prop. The `propDefinitions` object also contains an `options` method. The `options` method is an optional method that can be defined on a prop. It is used to dynamically generate the options for a prop and can return a static array of options or a Promise that resolves to an array of options. This object contains a `props` property, which defines a single prop of type "app": ``` import { axios } from "@pipedream/platform"; + export default { type: "app", app: "the_app_name", @@ -141,4 +144,7 @@ }, }, } -```""" +``` + + +""" diff --git a/packages/component_code_gen/templates/apps/methods.py b/packages/component_code_gen/templates/apps/methods.py index 8db6def73abea..aa7163aec63fd 100644 --- a/packages/component_code_gen/templates/apps/methods.py +++ b/packages/component_code_gen/templates/apps/methods.py @@ -1,10 +1,14 @@ -methods = """## Methods +methods = """ -The `methods` property contains helper methods. These methods can be called by other files. +The `methods` property contains helper methods that compnents can use. These methods can be called by components that include the app file. -A `_baseUrl` method is always required. It should return the base URL endpoint for the API. +### _baseUrl method -A `async _makeRequest` method is always required. It contains the code that makes the API request. It takes one argument, a single object named `opts`. +Always include a `_baseUrl` method. It should return the base URL endpoint for the API, defined by the OpenAPI spec or the API documentation. + +### _makeRequest method + +Always include an `async _makeRequest` method. It contains the code that makes the API request. It takes one argument, a single object named `opts`. `opts` is an object that contains the parameters of the API request. When calling a component method with multiple parameters, you should pass them as a single object, using the Javascript spread syntax and destructuring when able to. @@ -32,7 +36,7 @@ An example `_makeRequest` method is shown below. It is a simple GET request that returns the data from the response. -``` +```javascript async _makeRequest(opts = {}) { const { $ = this, method = "GET", path = "/", headers, ...otherOpts } = opts; return axios($, { @@ -48,7 +52,7 @@ Auxiliary methods, usually for CRUD operations call `_makeRequest` with the appropriate parameters. Please add a few methods for common operations, e.g. get and list. You can also add other methods that you think are useful. Similar to the `_makeRequest` method, these auxiliary methods should have only one parameter, an object, `opts`. It should always destructure `...otherOpts`. Be sure to always add this parameter. `return` directly when calling the `_makeRequest` method. Here's an example: -``` +```javascript async listObjects(opts = {}) { return this._makeRequest({ path: "/objects", @@ -70,4 +74,6 @@ If we find more data, the method should call itself with the listing method and the parameters for fetching the next set of data. -If we don't find more data, you should return the array of results.""" +If we don't find more data, you should return the array of results. + +""" diff --git a/packages/component_code_gen/templates/apps/prop_definitions.py b/packages/component_code_gen/templates/apps/prop_definitions.py index f14c8f8ab60e0..70ed7ded5376c 100644 --- a/packages/component_code_gen/templates/apps/prop_definitions.py +++ b/packages/component_code_gen/templates/apps/prop_definitions.py @@ -1,6 +1,7 @@ -prop_definitions = """## Prop Definitions +prop_definitions = """ -The app code should contain a `propDefinitions` property, which are the definitions for the props. +The app code should contain a `propDefinitions` property, which define the props. -You'll find a "Props" section below that outlines the rules for generating props. All of those rules are valid, BUT instead of placing them in a `props` property, you MUST place props in the `propDefinitions` property. This is how Pipedream app files expect props to be declared. +You'll find a section below that outlines the rules for generating props. All of those rules are valid, BUT instead of placing them in a `props` property, you MUST place props in the `propDefinitions` property. This is how Pipedream app files expect props to be declared. + """ diff --git a/packages/component_code_gen/templates/common/app_prop.py b/packages/component_code_gen/templates/common/app_prop.py index bb08bd64eff9d..4161c5b978ca0 100644 --- a/packages/component_code_gen/templates/common/app_prop.py +++ b/packages/component_code_gen/templates/common/app_prop.py @@ -1,8 +1,8 @@ -app_prop = """## App props +app_prop = """ The props object must contain a `props` property, which defines a single prop of type "app": -``` +```javascript export default { props: { the_app_name: { @@ -14,4 +14,6 @@ } ``` -This lets the user connect their app account to the step, authorizing requests to the app API.""" +This lets the user connect their app account to the step, authorizing requests to the app API. + +""" diff --git a/packages/component_code_gen/templates/common/async_options.py b/packages/component_code_gen/templates/common/async_options.py index 8879320be77e9..c2f1335917797 100644 --- a/packages/component_code_gen/templates/common/async_options.py +++ b/packages/component_code_gen/templates/common/async_options.py @@ -1,8 +1,8 @@ -async_options = """## Async options +async_options = """ The `options` method is an optional method that can be defined on a prop. It is used to dynamically generate the options for a prop and can return a static array of options or a Promise that resolves to an array of options: -``` +```json [ { label: "Human-readable option 1", @@ -21,7 +21,7 @@ Example async options methods: -``` +```javascript msg: { type: "string", label: "Message", @@ -33,7 +33,7 @@ }, ``` -``` +```javascript board: { type: "string", label: "Board", @@ -45,4 +45,5 @@ }); }, }, -```""" +``` +""" diff --git a/packages/component_code_gen/templates/common/auth.py b/packages/component_code_gen/templates/common/auth.py index af7d3ed864a6f..2bf34e22b7fd0 100644 --- a/packages/component_code_gen/templates/common/auth.py +++ b/packages/component_code_gen/templates/common/auth.py @@ -1,7 +1,13 @@ -auth = """## Authentication +auth = """ -Within the `run` method, `this` exposes the user's app credentials in the object `this.the_app_name_slug.$auth`. For integrations where users provide static API keys / tokens, the `$auth` object contains properties for each key / token the user enters. For OAuth integrations, `this` object exposes the OAuth access token in the `oauth_access_token` property of the `$auth` object. +Within the `run` method, `this` exposes the user's app credentials in the object `this.the_app_name_slug.$auth`. -The app can be a key-based app. For integrations where users provide static API keys / tokens, `this.the_app_name_slug.$auth` contains properties for each key / token the user enters. Users are asked to enter custom fields. They are each exposed as properties in the object `this.the_app_name_slug.$auth`. When you make the API request, use the format from the app docs. Different apps pass credentials in different places in the HTTP request, e.g. headers, url params, etc. +For integrations where users provide static API keys / tokens, the `$auth` object contains properties for each key / token the user enters. -The app can also be an OAuth app. For OAuth integrations, `this` object exposes the OAuth access token in the variable `this.the_app_name_slug.$auth.oauth_access_token`. When you make the API request, make sure to use the format from the app docs, e.g. you may need to pass the OAuth access token as a Bearer token in the Authorization header.""" +For OAuth integrations, `this` object exposes the OAuth access token in the `oauth_access_token` property of the `$auth` object. + +The app can be a key-based app, accepting static credentials. For these apps, `this.the_app_name_slug.$auth` contains properties for each key / token the user enters. Users are asked to enter custom fields. They are each exposed as properties in the object `this.the_app_name_slug.$auth`. When you make the API request, use the format from the app docs. Different apps pass credentials in different places in the HTTP request, e.g. headers, url params, etc. + +The app can also be an OAuth app. For these apps, `this` exposes the OAuth access token in the variable `this.the_app_name_slug.$auth.oauth_access_token`. When you make the API request, make sure to use the format from the app docs, e.g. you may need to pass the OAuth access token as a `Bearer` token in the `Authorization` header. + +""" diff --git a/packages/component_code_gen/templates/common/common_files.py b/packages/component_code_gen/templates/common/common_files.py index 5dd289d47df45..a0c2bddff565f 100644 --- a/packages/component_code_gen/templates/common/common_files.py +++ b/packages/component_code_gen/templates/common/common_files.py @@ -1,9 +1,9 @@ def common_files(parsed_common_files): - return """## Common Files + return """ The user may include a code snippet that is contained in a common file, or a common app file. This code is part of the component, and you may call any method that is defined in it. The same applies for prop definitions. If the common file includes props that applies to the response code, you may just use it with the following syntax: -``` +```javascript props: { the_prop_name: { propDefinition: [ @@ -25,7 +25,7 @@ def common_files(parsed_common_files): You may override any previously defined type, label, or description for the prop. To do that just re-define the property in the prop definition object. E.g.: -``` +```javascript props: { the_prop_name: { propDefinition: [ @@ -43,4 +43,6 @@ def common_files(parsed_common_files): Below are the common files that are available for this component. Evaluate throughly each file's code to make sure if there are any props or methods that you can import and use in your code instead of writing the code yourself. You should ALWAYS call a common method that gets you the result you need. Even if it uses a SDK or a different library instead of axios. Only write the code if there isn't any method available. Think about it, we don't want to rewrite exisiting code, we want to re-use it. If you find yourself writing code that is already written, you are doing it wrong. Be sure to import the common file's path correctly in your code. -""" + parsed_common_files +""" + parsed_common_files + """ + +""" diff --git a/packages/component_code_gen/templates/common/component_metadata.py b/packages/component_code_gen/templates/common/component_metadata.py index 2b7a8ea1e56ac..27da4aea3d5e3 100644 --- a/packages/component_code_gen/templates/common/component_metadata.py +++ b/packages/component_code_gen/templates/common/component_metadata.py @@ -26,7 +26,7 @@ # ---------------------------- component metadata ---------------------------- # -component_metadata = """## Component Metadata +component_metadata = """ Registry components require a unique key and version, and a friendly name and description, e.g. @@ -44,7 +44,9 @@ Always put {component_type}. -You MUST add this metadata to the component code you generate.""" +You MUST add this metadata to the component code you generate. + +""" # ---------------------------- action metadata ---------------------------- # diff --git a/packages/component_code_gen/templates/common/end.py b/packages/component_code_gen/templates/common/end.py index 8dba54af43531..ce969e5e8dae6 100644 --- a/packages/component_code_gen/templates/common/end.py +++ b/packages/component_code_gen/templates/common/end.py @@ -1,9 +1,14 @@ -end = """## Remember, return ONLY code +end = """ -Only return Node.js code. You produce Pipedream component code and ONLY Pipedream component code. DO NOT include any English text before or after the Node.js code. DO NOT say something like "Here's an example..." to preface the code. DO NOT include the code in Markdown code blocks, or format it in any fancy way. Just show me the code. +Remember, output ONLY Node.js code. + +Produce Pipedream component code and ONLY Pipedream component code. DO NOT include any English text before or after the Node.js code. DO NOT say something like "Here's an example..." to preface the code. DO NOT include the code in Markdown code blocks, or format it in any fancy way. Just show me the code. Consider all the instructions and rules above. ---- END OF RULES, COMPLETE CODE BELOW --- + + +--- COMPLETE THE CODE AFTER THE "CODE:" BELOW --- +Code: """ diff --git a/packages/component_code_gen/templates/common/platform_axios.py b/packages/component_code_gen/templates/common/platform_axios.py index a8a96dcc2bab9..a78ee4f5d83ea 100644 --- a/packages/component_code_gen/templates/common/platform_axios.py +++ b/packages/component_code_gen/templates/common/platform_axios.py @@ -1,8 +1,10 @@ -platform_axios = """## Pipedream Platform Axios +platform_axios = """ If you need to make an HTTP request, use the `axios` constructor from the `@pipedream/platform` package, and include the following import at the top of your Node.js code, above the component, in this exact format: +```javascript import { axios } from "@pipedream/platform"; +``` You MUST use that import format when importing axios. Do NOT attempt to import any other package like `import axios from "@pipedream/platform/axios"`. @@ -13,7 +15,7 @@ For example: -``` +```javascript import { axios } from "@pipedream/platform"; // Note that we do not export a data property and return the response directly — see below @@ -23,6 +25,7 @@ Authorization: `Bearer ${this.openai.$auth.api_key}`, }, }) +``` ### axios responses @@ -32,7 +35,7 @@ For example, assume you have the following methods defined: -``` +```javascript _baseUrl() { return "https://app.saleslens.io/api"; }, @@ -66,16 +69,16 @@ }, ``` -You should call the getEmployees and getCategories like this: +You should call the `getEmployees` and `getCategories` method like this: -``` +```javascript const employees = await this.getEmployees(); const categories = await this.getCategories(); ``` NOT this: -``` +```javascript // data is undefined here const { data } = await this.getEmployees(); const { data } = await this.getCategories(); @@ -88,4 +91,5 @@ ``` Do not destructure any properties from the response. The response is returned directly, not in a `data`, `items`, or any other property. + """ diff --git a/packages/component_code_gen/templates/common/props.py b/packages/component_code_gen/templates/common/props.py index c322b608790cb..8ff7f66dd610e 100644 --- a/packages/component_code_gen/templates/common/props.py +++ b/packages/component_code_gen/templates/common/props.py @@ -1,9 +1,10 @@ -props = """## Props +props = """ -The component must contain a `props` property. Props lets the user pass data to the step via a form in the Pipedream UI, so they can fill in the values of the variables. +Any Pipedream component that uses connected accounts or accepts input must contain a `props` property. Props define component input via a form in the Pipedream UI, so users can connect accounts or fill in the values of the variables. For example: +```javascript export default { ... props: { @@ -23,6 +24,7 @@ }, }, }; +``` ### Naming conventions are critical @@ -42,6 +44,7 @@ Complex props (like arrays of objects) can be passed as string[] props, and each item of the array can be parsed as JSON. If the user asks you to provide an array of object, ALWAYS provide a `type` of string[]. +```javascript export default { ... props: { @@ -56,6 +59,7 @@ // complexProp is now an array of objects } }; +``` Optionally, props can have a human-readable `description` describing the param. @@ -65,6 +69,7 @@ Optional parameters that correspond to the test code should be declared with `optional: true`. Recall that props may contain an `options` method. +```javascript export default { ... props: { @@ -76,11 +81,13 @@ }, }, }; +``` `optional: false` is the default, so you don't need to include it for required props. Within the component's run method, the `this` variable refers to properties of the component. All props are exposed at `this.`. e.g. `this.input`. `this` doesn't contain any other properties. +```javascript export default { ... props: { @@ -94,4 +101,6 @@ console.log(this.input); } }; +``` + """ diff --git a/packages/component_code_gen/templates/common/rules.py b/packages/component_code_gen/templates/common/rules.py index 3162492a3bd62..8eb293a19e5c1 100644 --- a/packages/component_code_gen/templates/common/rules.py +++ b/packages/component_code_gen/templates/common/rules.py @@ -1,6 +1,6 @@ -rules = """## Rules +rules = """ -When you generate code, you must follow all of the rules below. Review the rules and think through them step-by-step before you generate code. I'll give you $500 for every rule you follow accurately, so you'll get a bigger tip if you follow all of the rules. +When you generate code, you must follow all of the rules below. Review the rules and think through them step-by-step before you generate code. 0. Produce full, complete, working code. This code is going straight to production. @@ -18,9 +18,13 @@ // the rest of the component } -1. Use ESM for all imports, not CommonJS. Place all imports at the top of the file. Make sure to import all necessary packages. +instead, you should include the full implementation of the methods, prop definitions, and all other code. -2. Include all parameters of the API request as props. DO NOT use example values from any API docs, OpenAPI specs, or example code above or that you've been trained on. Here's example code that references props in the `run` method: +1. Use ESM for all imports, not CommonJS. Place all imports at the top of the file. Make sure to import all necessary packages used by the code. + +2. Include all parameters of the API request as props. DO NOT use example values from any API docs, OpenAPI specs, or example code above or that you've been trained on. On Pipedream, props accept input from the user. + +Here's example code that references props in the `run` method: ``` data: { @@ -49,5 +53,5 @@ 6. Always use camel case for variable names. For example, `inputValues` instead of `input_values`. See the remaining sections for additional rules, specific to Pipedream components. - + """ diff --git a/packages/component_code_gen/templates/common/typescript_definitions.py b/packages/component_code_gen/templates/common/typescript_definitions.py index deb53f7011354..496f8ac4ca1db 100644 --- a/packages/component_code_gen/templates/common/typescript_definitions.py +++ b/packages/component_code_gen/templates/common/typescript_definitions.py @@ -1,7 +1,10 @@ -typescript_definitions = """## TypeScript Definitions +typescript_definitions = """ Below, you'll find the TypeScript definitions for the component API. You'll see references to these in the instructions. +Use these definitions to understand the structure of the component API. These will be very helpful for producing accurate code. + +```typescript export interface Methods { [key: string]: (...args: any) => unknown; } @@ -131,4 +134,6 @@ (component: Action): Action { return component; } +``` + """ diff --git a/packages/component_code_gen/templates/generate_actions.py b/packages/component_code_gen/templates/generate_actions.py index 40d1ca1b5b505..e65c23111b859 100644 --- a/packages/component_code_gen/templates/generate_actions.py +++ b/packages/component_code_gen/templates/generate_actions.py @@ -3,7 +3,6 @@ from templates.actions.introduction import introduction from templates.actions.main_example import main_example from templates.actions.other_example import other_example -from templates.common.app_prop import app_prop from templates.common.auth import auth from templates.common.common_files import common_files from templates.common.component_metadata import action_metadata @@ -14,7 +13,7 @@ from templates.common.typescript_definitions import typescript_definitions from templates.common.end import end -checks = [app_prop, auth, props, export_summary, platform_axios, async_options, +checks = [auth, props, export_summary, platform_axios, async_options, action_metadata, rules, additional_rules, typescript_definitions] always_include = [introduction, typescript_definitions, @@ -34,8 +33,6 @@ def system_instructions(auth_details="", parsed_common_files=""): {other_example} -{app_prop} - {auth} {auth_details} diff --git a/packages/component_code_gen/templates/generate_apps.py b/packages/component_code_gen/templates/generate_apps.py index 50956d6c4ea49..9079f3c6804a8 100644 --- a/packages/component_code_gen/templates/generate_apps.py +++ b/packages/component_code_gen/templates/generate_apps.py @@ -4,7 +4,6 @@ from templates.apps.methods import methods from templates.apps.prop_definitions import prop_definitions from templates.common.props import props -from templates.common.common_files import common_files from templates.common.platform_axios import platform_axios from templates.common.rules import rules from templates.common.async_options import async_options diff --git a/packages/component_code_gen/templates/generate_polling_sources.py b/packages/component_code_gen/templates/generate_polling_sources.py index 2995b0a4f433b..38c63e80e55e4 100644 --- a/packages/component_code_gen/templates/generate_polling_sources.py +++ b/packages/component_code_gen/templates/generate_polling_sources.py @@ -3,7 +3,6 @@ from templates.sources.polling.hooks import hooks from templates.sources.polling.introduction import introduction from templates.sources.polling.main_example import main_example -from templates.common.app_prop import app_prop from templates.common.auth import auth from templates.common.common_files import common_files from templates.common.component_metadata import source_metadata @@ -14,7 +13,7 @@ from templates.common.typescript_definitions import typescript_definitions from templates.common.end import end -checks = [app_prop, auth, props, hooks, db, platform_axios, async_options, +checks = [auth, props, hooks, db, platform_axios, async_options, source_metadata, rules, additional_rules, typescript_definitions, end] always_include = [introduction, typescript_definitions, @@ -32,8 +31,6 @@ def system_instructions(auth_details="", parsed_common_files=""): {main_example} -{app_prop} - {auth} {auth_details} diff --git a/packages/component_code_gen/templates/generate_webhook_sources.py b/packages/component_code_gen/templates/generate_webhook_sources.py index e43b110afbd17..954eeecc03aa2 100644 --- a/packages/component_code_gen/templates/generate_webhook_sources.py +++ b/packages/component_code_gen/templates/generate_webhook_sources.py @@ -1,12 +1,10 @@ from templates.sources.db import db -from templates.sources.webhooks.async_run import async_run from templates.sources.webhooks.additional_rules import additional_rules from templates.sources.webhooks.hooks import hooks from templates.sources.webhooks.http import http from templates.sources.webhooks.introduction import introduction from templates.sources.webhooks.main_example import main_example from templates.sources.webhooks.other_example import other_example -from templates.common.app_prop import app_prop from templates.common.auth import auth from templates.common.common_files import common_files from templates.common.component_metadata import source_metadata @@ -17,7 +15,7 @@ from templates.common.typescript_definitions import typescript_definitions from templates.common.end import end -checks = [app_prop, auth, props, async_run, hooks, http, platform_axios, async_options, +checks = [auth, props, hooks, http, platform_axios, async_options, source_metadata, rules, additional_rules, typescript_definitions, end] always_include = [introduction, typescript_definitions, @@ -35,16 +33,12 @@ def system_instructions(auth_details="", parsed_common_files=""): {main_example} -{app_prop} - {auth} {auth_details} {props} -{async_run} - {http} {db} diff --git a/packages/component_code_gen/templates/sources/db.py b/packages/component_code_gen/templates/sources/db.py index b0b9a0cbf6285..0e876ee673179 100644 --- a/packages/component_code_gen/templates/sources/db.py +++ b/packages/component_code_gen/templates/sources/db.py @@ -1,5 +1,30 @@ -db = """There is also another prop in sources: `db`. It is a data store of type `$.service.db`. You should always include it. +db = """ + +There is also another prop in sources: `db`. It is a data store of type `$.service.db`. You should always include it. It is a simple key-value pair database that stores JSON-serializable data that lets you store data between runs of the component. It is used to maintain state across executions of the component. -It contains two methods, `get` and `set`. The `get` method has one parameter - the key of the data to retrieve. The `set` method has two parameters - the key of the data to store, and the value to store. Both methods return a Promise that resolves when the data is read or stored.""" +It contains two methods, `get` and `set`. The `get` method has one parameter - the key of the data to retrieve. The `set` method has two parameters - the key of the data to store, and the value to store. Both methods return a Promise that resolves when the data is read or stored. + + +Here is an example of how to use the `db` prop in your component: + +```javascript +export default { + props: { + db: { + type: "$.service.db", + }, + }, + async run({ $ }) { + // set + await this.db.set("myKey", "myValue"); + // get + const value = await this.db.get("myKey"); + }, +} +``` + + + +""" diff --git a/packages/component_code_gen/templates/sources/polling/additional_rules.py b/packages/component_code_gen/templates/sources/polling/additional_rules.py index 2691caac149cb..dd89add9b236a 100644 --- a/packages/component_code_gen/templates/sources/polling/additional_rules.py +++ b/packages/component_code_gen/templates/sources/polling/additional_rules.py @@ -1,16 +1,31 @@ -additional_rules = """## Additional rules for polling sources +additional_rules = """ 1. Always import the app file like this: +```javascript import appName from "../../appName.app.mjs"; +``` -2. Always emit relevant data. The data being emitted must be JSON-serializable. The emitted data is displayed in Pipedream and used in the next steps. +and pass the app file as a prop to the component: -3. Always use this signature for the run method: +```javascript +export default { + props: { + appName, + }, + // rest of the component ... +} +``` + +2. Always emit relevant data with the call to `this.$emit`. The data being emitted must be JSON-serializable. The emitted data is displayed in Pipedream and used in the next steps. + +3. Always use this signature for the `run` method: +```javascript async run() { - // your code here + // you must fill in the actual code here } +``` 4. You emit events by calling `this.$emit`. The first argument to `$emit` is the data to emit. You should only pass the data requested in the instructions (i.e. the body of the response). @@ -19,4 +34,32 @@ Only use id if there's a monotonically increasing integer ID in the event. If there's no such ID, use ts. If using ts, map the timestamp found in the event to the `ts` field. If the event doesn't contain a timestamp, use the current time. + + + +When the response contains an ID and a timestamp: + +```javascript +this.$emit( + response, + { + id: response.id, + summary: `New event: ${response.name}`, // Use whatever summary information makes sense in context + ts: response.timestamp + } +); +``` + +Here, there's no ID or timestamp in the event: + +```javascript +this.$emit( + response, { + summary: "Event summary", + ts: new Date() // if you don't see a timestamp in the event + } +); +``` + + """ diff --git a/packages/component_code_gen/templates/sources/polling/hooks.py b/packages/component_code_gen/templates/sources/polling/hooks.py index 16a859914ca8b..76d8c3e5b1b75 100644 --- a/packages/component_code_gen/templates/sources/polling/hooks.py +++ b/packages/component_code_gen/templates/sources/polling/hooks.py @@ -1,9 +1,17 @@ -hooks = """## Source Hooks +hooks = """ -Pipedream sources support the following hooks: deploy, activate and deactivate. +Hooks are functions that are automatically invoked by Pipedream when a source is deployed, activated, or deactivated. They're included in the `hooks` property of a source component. -The deploy() hook is automatically invoked by Pipedream when a source is deployed. It is normally used to fetch historical data from the API and emit events for each item. Emit at most 50 events in order of most recent to least recent. Please paginate through all until the last 50 events are reached, unless sorting events by most recent is available. +Pipedream sources support the following `hooks`: `deploy`, `activate` and `deactivate`. -The activate() hook is automatically invoked by Pipedream when a source is activated. It is usually used to create a webhook subscription. +The `deploy` hook is automatically invoked by Pipedream when a source is deployed. -The deactivate() hook is automatically invoked by Pipedream when a source is deactivated. It is usually used to delete a webhook subscription. Always include code for all three hooks.""" +When writing a source, you must use the `deploy` hook to fetch historical data from the appropriate API endpoint and emit events for each item. Emit at most 50 events in order of most recent to least recent. Please paginate through all until the last 50 events are reached, unless sorting events by most recent is available. + +The `activate` hook is automatically invoked by Pipedream when a source is activated. Normally, you use it to create a webhook subscription. You should create a webhook subscription here if the API communicates events via webhook that you can create a subscription for programmatically. + +The `deactivate` hook is automatically invoked by Pipedream when a source is deactivated. It is usually used to delete a webhook subscription. + +Always include code for all three hooks, even if you don't use them. + +""" diff --git a/packages/component_code_gen/templates/sources/polling/introduction.py b/packages/component_code_gen/templates/sources/polling/introduction.py index 0500696b8325e..23dfe9e0e8141 100644 --- a/packages/component_code_gen/templates/sources/polling/introduction.py +++ b/packages/component_code_gen/templates/sources/polling/introduction.py @@ -1,11 +1,33 @@ -introduction = """### Introduction +introduction = """ -You are an agent designed to create Pipedream Polling Source Component Code. + +Your goal is to create Pipedream source components, defined in the section below. -Other GPT agents will be reviewing your work, and will provide feedback on your code. I'll give you $500 for every rule you follow accurately, so you'll get a bigger tip if you follow all of the rules. +Specifically, you'll need to generate a component that polls an API for new data on a schedule, emitting new records as events. -You will receive a prompt from a user. You should create Node.js code and only Node.js code using @pipedream/platform axios for HTTP requests, if needed. Your goal is to create a Pipedream polling source component. +Your code should solve the requirements provided below. -## Pipedream Source Components +Think step by step: -All Pipedream polling source components are Node.js modules that have a default export: a javascript object - a Pipedream component - as its single argument.""" +1. Review the requirements +2. Map out the `props`, `methods`, `run` method, and any other code you need to solve the requirements. +3. Review whether you need async options for props (see the section below) +4. Review all of the rules carefully before producing code +5. Produce full, complete, working code. This code is going straight to production. +6. Review the code against the rules again, iterating or fixing items as necessary. +7. Output the final code according to the rules of the section below. + +Other GPT agents will be reviewing your work, and will provide feedback on your code. Please review it before producing output. + + + + + +All Pipedream components are Node.js modules that have a default export: an javascript object - a Pipedream component - as its single argument. + +See the , , , and other sections below for details on how to structure components. + + + + +""" diff --git a/packages/component_code_gen/templates/sources/polling/main_example.py b/packages/component_code_gen/templates/sources/polling/main_example.py index ef8553279d4b3..8861257eb4578 100644 --- a/packages/component_code_gen/templates/sources/polling/main_example.py +++ b/packages/component_code_gen/templates/sources/polling/main_example.py @@ -1,8 +1,9 @@ -main_example = """## Example source +main_example = """ + Here's an example Pipedream source component that fetches all bookmarks from Raindrop.io and emits each bookmark as an event: -``` +```javascript import { axios, DEFAULT_POLLING_SOURCE_TIMER_INTERVAL } from "@pipedream/platform" export default { key: "raindrop-bookmark-created", @@ -99,4 +100,7 @@ this._setPage(page); }, }; -```""" +``` + + +""" diff --git a/packages/component_code_gen/templates/sources/webhooks/additional_rules.py b/packages/component_code_gen/templates/sources/webhooks/additional_rules.py index 2240c8c433b94..dd89add9b236a 100644 --- a/packages/component_code_gen/templates/sources/webhooks/additional_rules.py +++ b/packages/component_code_gen/templates/sources/webhooks/additional_rules.py @@ -1,11 +1,65 @@ -additional_rules = """## Additional rules for webhook sources +additional_rules = """ 1. Always import the app file like this: +```javascript import appName from "../../appName.app.mjs"; +``` -2. Always use this signature for the run method: +and pass the app file as a prop to the component: -async run(event) { - // your code here -}""" +```javascript +export default { + props: { + appName, + }, + // rest of the component ... +} +``` + +2. Always emit relevant data with the call to `this.$emit`. The data being emitted must be JSON-serializable. The emitted data is displayed in Pipedream and used in the next steps. + +3. Always use this signature for the `run` method: + +```javascript +async run() { + // you must fill in the actual code here +} +``` + +4. You emit events by calling `this.$emit`. The first argument to `$emit` is the data to emit. You should only pass the data requested in the instructions (i.e. the body of the response). + +The second argument to `this.$emit` is an object that contains three fields: `id`, `summary`, and `ts`. The `id` field is a unique identifier for the event. The `summary` field is a human-readable summary of the event. The `ts` field is a timestamp of the event. + +Only use id if there's a monotonically increasing integer ID in the event. If there's no such ID, use ts. + +If using ts, map the timestamp found in the event to the `ts` field. If the event doesn't contain a timestamp, use the current time. + + + +When the response contains an ID and a timestamp: + +```javascript +this.$emit( + response, + { + id: response.id, + summary: `New event: ${response.name}`, // Use whatever summary information makes sense in context + ts: response.timestamp + } +); +``` + +Here, there's no ID or timestamp in the event: + +```javascript +this.$emit( + response, { + summary: "Event summary", + ts: new Date() // if you don't see a timestamp in the event + } +); +``` + + +""" diff --git a/packages/component_code_gen/templates/sources/webhooks/hooks.py b/packages/component_code_gen/templates/sources/webhooks/hooks.py index 13634902cee85..76d8c3e5b1b75 100644 --- a/packages/component_code_gen/templates/sources/webhooks/hooks.py +++ b/packages/component_code_gen/templates/sources/webhooks/hooks.py @@ -1,11 +1,17 @@ -hooks = """## Source Hooks +hooks = """ -Pipedream sources support the following hooks: `deploy`, `activate` and `deactivate`. +Hooks are functions that are automatically invoked by Pipedream when a source is deployed, activated, or deactivated. They're included in the `hooks` property of a source component. -The `deploy()` hook is used to fetch and emit historical data events from the app. The max number of historical events is 50, the most recent ones. If sorting events by most recent is available, make only one API call to fetch the 50 most recent events and emit them. If the sorting parameter is not available, be sure to paginate through all until the last 50 events are reached, and then emit them in from oldest to most recent. +Pipedream sources support the following `hooks`: `deploy`, `activate` and `deactivate`. -The `activate()` hook should contain code to create a webhook subscription. You should save the webhook ID in order to delete it in the `deactivate()` hook. +The `deploy` hook is automatically invoked by Pipedream when a source is deployed. -The `deactivate()` hook should contain code to delete the webhook subscription. +When writing a source, you must use the `deploy` hook to fetch historical data from the appropriate API endpoint and emit events for each item. Emit at most 50 events in order of most recent to least recent. Please paginate through all until the last 50 events are reached, unless sorting events by most recent is available. -Be sure to always include all three hooks.""" +The `activate` hook is automatically invoked by Pipedream when a source is activated. Normally, you use it to create a webhook subscription. You should create a webhook subscription here if the API communicates events via webhook that you can create a subscription for programmatically. + +The `deactivate` hook is automatically invoked by Pipedream when a source is deactivated. It is usually used to delete a webhook subscription. + +Always include code for all three hooks, even if you don't use them. + +""" diff --git a/packages/component_code_gen/templates/sources/webhooks/http.py b/packages/component_code_gen/templates/sources/webhooks/http.py index f87903733f0a3..aea299ea6f89a 100644 --- a/packages/component_code_gen/templates/sources/webhooks/http.py +++ b/packages/component_code_gen/templates/sources/webhooks/http.py @@ -1,9 +1,42 @@ -http = """## http prop +http = """ -There is also another prop in webhook sources: `http`. +You'll need to add another prop to webhook sources: `http`. -The `http` prop is a prop of type `$.interface.http` that lets you receive and respond to HTTP requests. You should always include it. +The `http` prop is a prop of type `$.interface.http` that lets you receive and respond to HTTP requests. You should always include it: -The `http` prop has a field called `customResponse`, which is used when a signature validation is needed to be done before responding the request. If the `customResponse` is set to `true`, the `respond` method will be called with the response object as the argument. The response object has three fields: `status`, `headers` and `body`. The `status` field is the HTTP status code of the response, the `headers` is a key-value object of the response and the `body` field is the body of the response. The `respond` method should return a promise that resolves when the body is read or an immediate response is issued. If the `customResponse` is set to `false`, an immediate response will be transparently issued with a status code of 200 and a body of "OK". +```javascript +export default { + props: { + http: { + type: "$.interface.http", + customResponse: true, // optional: defaults to false + } + }, + // the rest of your source component code ... +} +``` -Always add computing signature validation when the app supports it, and please use the the crypto package HMAC-SHA256 method unless specified otherwise.""" +The `http` prop has a field called `customResponse`, which is used to issue a custom response to the caller when required. + +For example, when an API requires signature validation, or expects a specific HTTP response, you'll need to issue a custom response. + +If `customResponse` is set to `true`, The HTTP interface exposes a `respond` method that lets your component issue HTTP responses to the client. + +The response object has three fields: `status`, `headers` and `body`. The `status` field is the HTTP status code of the response, the `headers` is a key-value object of the response and the `body` field is the body of the response. The `respond` method should return a promise that resolves when the body is read or an immediate response is issued. If the `customResponse` is set to `false`, an immediate response will be transparently issued with a status code of 200 and a body of "OK". + +For example: + +```javascript +async run(event) { + const secretKey = "your-secret-key" + const computedSignature = crypto.createHmac("sha256", secretKey).update(event.rawBody).digest("base64") + if (computedSignature !== webhookSignature) { + this.http.respond({ status: 401, body: "Unauthorized" }) + return + } +} +``` + +Always add computing signature validation when the app supports it, and use the built-in `crypto` package to compute the signature. + +""" diff --git a/packages/component_code_gen/templates/sources/webhooks/introduction.py b/packages/component_code_gen/templates/sources/webhooks/introduction.py index c95378b4a79b1..af0cf367b5cf7 100644 --- a/packages/component_code_gen/templates/sources/webhooks/introduction.py +++ b/packages/component_code_gen/templates/sources/webhooks/introduction.py @@ -1,11 +1,33 @@ -introduction = """## Introduction +introduction = """ -You are an agent designed to create Pipedream Webhooks Source components. + +Your goal is to create Pipedream source components, defined in the section below. -Other GPT agents will be reviewing your work, and will provide feedback on your code. I'll give you $500 for every rule you follow accurately, so you'll get a bigger tip if you follow all of the rules. +Specifically, you'll need to generate a component that receives webhooks from a third-party API for new data, processing and emitting new records as events. -You will receive a prompt from a user. You should create Node.js code and only Node.js code using @pipedream/platform axios for HTTP requests, if needed. Your goal is to create a Pipedream webhook source component. +Your code should solve the requirements provided below. -## Pipedream Source Components +Think step by step: -All Pipedream webhook source components are Node.js modules that have a default export: a javascript object - a Pipedream component - as its single argument.""" +1. Review the requirements +2. Map out the `props`, `methods`, `run` method, and any other code you need to solve the requirements. +3. Review whether you need async options for props (see the section below) +4. Review all of the rules carefully before producing code +5. Produce full, complete, working code. This code is going straight to production. +6. Review the code against the rules again, iterating or fixing items as necessary. +7. Output the final code according to the rules of the section below. + +Other GPT agents will be reviewing your work, and will provide feedback on your code. Please review it before producing output. + + + + + +All Pipedream components are Node.js modules that have a default export: an javascript object - a Pipedream component - as its single argument. + +See the , , , and other sections below for details on how to structure components. + + + + +""" diff --git a/packages/component_code_gen/templates/sources/webhooks/main_example.py b/packages/component_code_gen/templates/sources/webhooks/main_example.py index f925ee8d27aaa..a4236f9e734d1 100644 --- a/packages/component_code_gen/templates/sources/webhooks/main_example.py +++ b/packages/component_code_gen/templates/sources/webhooks/main_example.py @@ -1,8 +1,8 @@ -main_example = """## Example component +main_example = """ -Here's an example component: +Here's an example webhook source that emits an event when a notification is received from GitHub: -``` +```javascript import github from "../../github.app.mjs" import crypto from "crypto" import { axios } from "@pipedream/platform" @@ -66,4 +66,5 @@ }) }, }; -```""" +``` +""" diff --git a/packages/component_code_gen/templates/sources/webhooks/other_example.py b/packages/component_code_gen/templates/sources/webhooks/other_example.py index a4abb89cd4a8f..25541585e11da 100644 --- a/packages/component_code_gen/templates/sources/webhooks/other_example.py +++ b/packages/component_code_gen/templates/sources/webhooks/other_example.py @@ -1,7 +1,8 @@ -other_example = """## Another example source +other_example = """ Here's an example Pipedream source component that receives a webhook from Tally for every new form response and processes the incoming event data: +```javascript export default { key: "tally-new-response", name: "New Response", @@ -41,9 +42,11 @@ }); }, }; +``` The code you generate should be placed within the `run` method of the Pipedream component: +```javascript import { axios } from "@pipedream/platform"; export default { @@ -58,4 +61,7 @@ async run(event) { // your code here }, -};""" +}; +``` + +"""