From 317381114a642594ef6b4107c90cda065d96f0f5 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 12 Nov 2024 20:17:40 +0300 Subject: [PATCH 1/5] allow unkown tags eg @state --- tools/parse-jsdoc/jsdoc/jsdoc.conf.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/parse-jsdoc/jsdoc/jsdoc.conf.json b/tools/parse-jsdoc/jsdoc/jsdoc.conf.json index 27679f88f..9c1925354 100644 --- a/tools/parse-jsdoc/jsdoc/jsdoc.conf.json +++ b/tools/parse-jsdoc/jsdoc/jsdoc.conf.json @@ -1,6 +1,6 @@ { "tags": { - "allowUnknownTags": false + "allowUnknownTags": true }, "plugins": ["./lookup-tags.cjs"] } From 535379439327f7626bd2e75cefcbe8c2a93d19e3 Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 12 Nov 2024 20:30:59 +0300 Subject: [PATCH 2/5] update examples --- packages/salesforce/ast.json | 80 ++++++++++++++++++++++++++---- packages/salesforce/src/Adaptor.js | 67 ++++++++++++++++++------- 2 files changed, 120 insertions(+), 27 deletions(-) diff --git a/packages/salesforce/ast.json b/packages/salesforce/ast.json index 152355eca..f6726e464 100644 --- a/packages/salesforce/ast.json +++ b/packages/salesforce/ast.json @@ -26,6 +26,11 @@ "description": "bulk(\n \"vera__Beneficiary__c\",\n \"upsert\",\n [\n {\n vera__Reporting_Period__c: 2023,\n vera__Geographic_Area__c: \"Uganda\",\n \"vera__Indicator__r.vera__ExtId__c\": 1001,\n vera__Result_UID__c: \"1001_2023_Uganda\",\n },\n ],\n { extIdField: \"vera__Result_UID__c\" }\n);", "caption": "Bulk upsert" }, + { + "title": "example", + "description": "fn((state) => {\n state.accounts = state.data.map((a) => ({ Id: a.id, Name: a.name }));\n return state;\n});\nbulk(\"Account\", \"update\", { failOnError: true }, $.accounts);", + "caption": "Bulk update Account records using a lazy state reference" + }, { "title": "function", "description": null, @@ -131,6 +136,10 @@ "name": "options.pollTimeout", "default": "240000" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -159,12 +168,18 @@ }, { "title": "example", - "description": "bulkQuery(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`);", - "caption": "The results will be available on `state.data`" + "description": "bulkQuery(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`);", + "caption": "Bulk query patient records where `Health_ID__c` is equal to the value in `state.data.healthId`" + }, + { + "title": "example", + "description": "bulkQuery(`SELECT Id FROM Patient__c WHERE Health_ID__c = '${$.data.healthId}'`);", + "caption": "Bulk query patient records using a lazy state reference" }, { "title": "example", - "description": "bulkQuery(\n (state) =>\n `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`,\n { pollTimeout: 10000, pollInterval: 6000 }\n);" + "description": "bulkQuery(\n (state) =>\n `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`,\n { pollTimeout: 10000, pollInterval: 6000 }\n);", + "caption": "Bulk query with custom polling options" }, { "title": "function", @@ -215,6 +230,10 @@ "name": "options.pollInterval", "default": "3000" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -274,6 +293,10 @@ }, "name": "records" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -326,6 +349,10 @@ }, "name": "sObjectName" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -355,7 +382,8 @@ }, { "title": "example", - "description": "destroy('obj_name', [\n '0060n00000JQWHYAA5',\n '0090n00000JQEWHYAA5'\n], { failOnError: true })" + "description": "destroy(\"Account\", [\"001XXXXXXXXXXXXXXX\", \"001YYYYYYYYYYYYYYY\"], {\n failOnError: true,\n});", + "caption": "Delete multiple Account records" }, { "title": "function", @@ -389,6 +417,10 @@ }, "name": "options" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -448,6 +480,10 @@ }, "name": "records" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -477,12 +513,18 @@ }, { "title": "example", - "description": "query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`);" + "description": "query('SELECT Id FROM Patient__c', { autoFetch: true });", + "caption": "Query more records if next records are available" }, { "title": "example", - "description": "query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`, { autoFetch: true });", - "caption": "Query more records if next records are available" + "description": "query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`);", + "caption": "Query patients by Health ID" + }, + { + "title": "example", + "description": "query(`SELECT Id FROM Patient__c WHERE Health_ID__c = '${$.data.healthId}'`);", + "caption": "Query patients by Health ID using a lazy state reference" }, { "title": "function", @@ -522,13 +564,17 @@ }, { "title": "param", - "description": "A callback to execute once the record is retrieved", + "description": "A callback to execute once the record is retrieved\n<<<<<<< HEAD\n=======", "type": { "type": "NameExpression", "name": "function" }, "name": "callback" }, + { + "title": "state", + "description": "{SalesforceState}\n>>>>>>> 1ece1ff1 (update examples)" + }, { "title": "returns", "description": null, @@ -628,6 +674,10 @@ "title": "magic", "description": "records - $.children[?(@.name==\"{{args.sObject}}\")].children[?(!@.meta.externalId)]" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -705,6 +755,10 @@ }, "name": "records" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, @@ -732,7 +786,8 @@ }, { "title": "example", - "description": "fn((state) => {\n const s = toUTF8(\"άνθρωποι\");\n console.log(s); // anthropoi\n return state;\n});" + "description": "fn((state) => {\n const s = toUTF8(\"άνθρωποι\");\n console.log(s); // anthropoi\n return state;\n});", + "caption": "Transliterate `άνθρωποι` to `anthropoi`" }, { "title": "param", @@ -771,7 +826,8 @@ }, { "title": "example", - "description": "retrieve('ContentVersion', '0684K0000020Au7QAE/VersionData');" + "description": "retrieve('ContentVersion', '0684K0000020Au7QAE/VersionData');", + "caption": "Retrieve a specific ContentVersion record" }, { "title": "function", @@ -796,6 +852,10 @@ }, "name": "id" }, + { + "title": "state", + "description": "{SalesforceState}" + }, { "title": "returns", "description": null, diff --git a/packages/salesforce/src/Adaptor.js b/packages/salesforce/src/Adaptor.js index 9d96cbf63..1e69d2962 100644 --- a/packages/salesforce/src/Adaptor.js +++ b/packages/salesforce/src/Adaptor.js @@ -11,6 +11,13 @@ * @ignore */ +/** + * State object + * @typedef {Object} SalesforceState + * @property data - Operation results + * @property references - History of all previous operations results + **/ + import { execute as commonExecute, composeNextState, @@ -80,6 +87,12 @@ export function execute(...operations) { * ], * { extIdField: "vera__Result_UID__c" } * ); + * @example Bulk update Account records using a lazy state reference + * fn((state) => { + * state.accounts = state.data.map((a) => ({ Id: a.id, Name: a.name })); + * return state; + * }); + * bulk("Account", "update", { failOnError: true }, $.accounts); * @function * @param {string} sObjectName - API name of the sObject. * @param {string} operation - The bulk operation to be performed.Eg "insert" | "update" | "upsert" @@ -90,6 +103,7 @@ export function execute(...operations) { * @param {boolean} [options.failOnError=false] - Fail the operation on error. * @param {integer} [options.pollInterval=6000] - Polling interval in milliseconds. * @param {integer} [options.pollTimeout=240000] - Polling timeout in milliseconds. + * @state {SalesforceState} * @returns {Operation} */ export function bulk(sObjectName, operation, records, options = {}) { @@ -192,10 +206,11 @@ export function bulk(sObjectName, operation, records, options = {}) { * `bulkQuery()` uses {@link https://sforce.co/4azgczz Bulk API v.2.0 Query} which is available in API version 47.0 and later. * This API is subject to {@link https://sforce.co/4b6kn6z rate limits}. * @public - * @example - * The results will be available on `state.data` - * bulkQuery(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`); - * @example + * @example Bulk query patient records where `Health_ID__c` is equal to the value in `state.data.healthId` + * bulkQuery(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`); + * @example Bulk query patient records using a lazy state reference + * bulkQuery(`SELECT Id FROM Patient__c WHERE Health_ID__c = '${$.data.healthId}'`); + * @example Bulk query with custom polling options * bulkQuery( * (state) => * `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`, @@ -206,6 +221,7 @@ export function bulk(sObjectName, operation, records, options = {}) { * @param {object} options - Options passed to the bulk api. * @param {integer} [options.pollTimeout=90000] - Polling timeout in milliseconds. * @param {integer} [options.pollInterval=3000] - Polling interval in milliseconds. + * @state {SalesforceState} * @returns {Operation} */ export function bulkQuery(qs, options = {}) { @@ -253,6 +269,7 @@ export function bulkQuery(qs, options = {}) { * @function * @param {string} sObjectName - API name of the sObject. * @param {object} records - Field attributes for the new record. + * @state {SalesforceState} * @returns {Operation} */ export function create(sObjectName, records) { @@ -284,6 +301,7 @@ export function create(sObjectName, records) { * describe('Account') * @function * @param {string} [sObjectName] - The API name of the sObject. If omitted, fetches metadata for all sObjects. + * @state {SalesforceState} * @returns {Operation} */ export function describe(sObjectName) { @@ -313,15 +331,15 @@ export function describe(sObjectName) { /** * Delete records of an object. * @public - * @example - * destroy('obj_name', [ - * '0060n00000JQWHYAA5', - * '0090n00000JQEWHYAA5' - * ], { failOnError: true }) + * @example Delete multiple Account records + * destroy("Account", ["001XXXXXXXXXXXXXXX", "001YYYYYYYYYYYYYYY"], { + * failOnError: true, + * }); * @function * @param {string} sObjectName - API name of the sObject. * @param {object} ids - Array of IDs of records to delete. * @param {object} options - Options for the destroy delete operation. + * @state {SalesforceState} * @returns {Operation} */ export function destroy(sObjectName, ids, options = {}) { @@ -360,10 +378,13 @@ export function destroy(sObjectName, ids, options = {}) { /** * Send a GET HTTP request using connected session information. - * @example + * @example Make a GET request to a custom Salesforce flow * get('/actions/custom/flow/POC_OpenFN_Test_Flow'); * @param {string} path - The Salesforce API endpoint, Relative to request from - * @param {object} options - Request query parameters and headers + * @param {object} options - Request options + * @param {object} [options.headers] - Object of request headers + * @param {object} [options.query] - A JSON Object request body + * @state {SalesforceState} * @returns {Operation} */ export function get(path, options = {}) { @@ -398,6 +419,7 @@ export function get(path, options = {}) { * @function * @param {string} sObjectName - API name of the sObject. * @param {object} records - Field attributes for the new record. + * @state {SalesforceState} * @returns {Operation} */ export function insert(sObjectName, records) { @@ -407,13 +429,14 @@ export function insert(sObjectName, records) { /** * Send a POST HTTP request using connected session information. * - * @example + * @example Make a POST request to a custom Salesforce flow * post('/actions/custom/flow/POC_OpenFN_Test_Flow', { inputs: [{}] }); * @param {string} path - The Salesforce API endpoint, Relative to request from * @param {object} data - A JSON Object request body * @param {object} options - Request options * @param {object} [options.headers] - Object of request headers * @param {object} [options.query] - A JSON Object request body + * @state {SalesforceState} * @returns {Operation} */ export function post(path, data, options = {}) { @@ -450,15 +473,21 @@ export function post(path, data, options = {}) { * * The Salesforce query API is subject to rate limits, {@link https://sforce.co/3W9zyaQ See for more details}. * @public - * @example - * query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`); * @example Query more records if next records are available - * query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.field1}'`, { autoFetch: true }); + * query('SELECT Id FROM Patient__c', { autoFetch: true }); + * @example Query patients by Health ID + * query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`); + * @example Query patients by Health ID using a lazy state reference + * query(`SELECT Id FROM Patient__c WHERE Health_ID__c = '${$.data.healthId}'`); * @function * @param {string} qs - A query string. Must be less than `4000` characters in WHERE clause * @param {object} options - Options passed to the bulk api. * @param {boolean} [options.autoFetch=false] - Fetch next records if available. * @param {function} callback - A callback to execute once the record is retrieved +<<<<<<< HEAD +======= + * @state {SalesforceState} +>>>>>>> 1ece1ff1 (update examples) * @returns {Operation} */ export function query(qs, options = {}, callback = s => s) { @@ -548,6 +577,7 @@ export function query(qs, options = {}, callback = s => s) { * @magic externalId - $.children[?(@.name=="{{args.sObject}}")].children[?(@.meta.externalId)].name * @param {(object|object[])} records - Field attributes for the new object. * @magic records - $.children[?(@.name=="{{args.sObject}}")].children[?(!@.meta.externalId)] + * @state {SalesforceState} * @returns {Operation} */ export function upsert(sObjectName, externalId, records) { @@ -588,6 +618,7 @@ export function upsert(sObjectName, externalId, records) { * @function * @param {string} sObjectName - API name of the sObject. * @param {(object|object[])} records - Field attributes for the new object. + * @state {SalesforceState} * @returns {Operation} */ export function update(sObjectName, records) { @@ -612,7 +643,7 @@ export function update(sObjectName, records) { /** * Transliterates unicode characters to their best ASCII representation * @public - * @example + * @example Transliterate `άνθρωποι` to `anthropoi` * fn((state) => { * const s = toUTF8("άνθρωποι"); * console.log(s); // anthropoi @@ -639,6 +670,7 @@ export function toUTF8(input) { * @param {object} [options.headers] - Object of request headers * @param {object} [options.json] - A JSON object to send as the request body. * @param {string} [options.body] - HTTP body (in POST/PUT/PATCH methods) + * @state {SalesforceState} * @returns {Operation} */ export function request(path, options = {}) { @@ -669,11 +701,12 @@ export function request(path, options = {}) { /** * Retrieves a Salesforce sObject(s). * @public - * @example + * @example Retrieve a specific ContentVersion record * retrieve('ContentVersion', '0684K0000020Au7QAE/VersionData'); * @function * @param {string} sObjectName - The sObject to retrieve * @param {string} id - The id of the record + * @state {SalesforceState} * @returns {Operation} */ export function retrieve(sObjectName, id) { From 3a86bd769906c8e0fccb3c1486f5ce81d8e83a1e Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 12 Nov 2024 20:38:07 +0300 Subject: [PATCH 3/5] fix merge conflicts --- packages/salesforce/ast.json | 43 ++++++++++++++++++++---------- packages/salesforce/src/Adaptor.js | 24 ++++++++--------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/packages/salesforce/ast.json b/packages/salesforce/ast.json index f6726e464..bfc597ce2 100644 --- a/packages/salesforce/ast.json +++ b/packages/salesforce/ast.json @@ -504,7 +504,7 @@ "callback" ], "docs": { - "description": "Execute an SOQL query.\nNote that in an event of a query error,\nerror logs will be printed but the operation will not throw the error.\n\nThe Salesforce query API is subject to rate limits, {@link https://sforce.co/3W9zyaQ See for more details}.", + "description": "Executes an SOQL (Salesforce Object Query Language) query to retrieve records from Salesforce.\nThis operation allows querying Salesforce objects using SOQL syntax and handles pagination.\nNote that in an event of a query error, error logs will be printed but the operation will not throw the error.\n\nThe Salesforce query API is subject to rate limits, {@link https://sforce.co/3W9zyaQ See for more details}.", "tags": [ { "title": "public", @@ -518,7 +518,7 @@ }, { "title": "example", - "description": "query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`);", + "description": "query(state => `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`);", "caption": "Query patients by Health ID" }, { @@ -533,25 +533,37 @@ }, { "title": "param", - "description": "A query string. Must be less than `4000` characters in WHERE clause", + "description": "A SOQL query string or a function that returns a query string. Must be less than 4000 characters in WHERE clause", "type": { - "type": "NameExpression", - "name": "string" + "type": "UnionType", + "elements": [ + { + "type": "NameExpression", + "name": "string" + }, + { + "type": "NameExpression", + "name": "function" + } + ] }, "name": "qs" }, { "title": "param", - "description": "Options passed to the bulk api.", + "description": "Optional configuration for the query operation", "type": { - "type": "NameExpression", - "name": "object" + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "object" + } }, "name": "options" }, { "title": "param", - "description": "Fetch next records if available.", + "description": "When true, automatically fetches next batch of records if available", "type": { "type": "OptionalType", "expression": { @@ -564,20 +576,23 @@ }, { "title": "param", - "description": "A callback to execute once the record is retrieved\n<<<<<<< HEAD\n=======", + "description": "Optional callback function to execute for each retrieved record", "type": { - "type": "NameExpression", - "name": "function" + "type": "OptionalType", + "expression": { + "type": "NameExpression", + "name": "function" + } }, "name": "callback" }, { "title": "state", - "description": "{SalesforceState}\n>>>>>>> 1ece1ff1 (update examples)" + "description": "{SalesforceState} - The Salesforce connection state" }, { "title": "returns", - "description": null, + "description": "Returns an Operation object containing the query results and metadata", "type": { "type": "NameExpression", "name": "Operation" diff --git a/packages/salesforce/src/Adaptor.js b/packages/salesforce/src/Adaptor.js index 1e69d2962..586d74327 100644 --- a/packages/salesforce/src/Adaptor.js +++ b/packages/salesforce/src/Adaptor.js @@ -467,28 +467,26 @@ export function post(path, data, options = {}) { } /** - * Execute an SOQL query. - * Note that in an event of a query error, - * error logs will be printed but the operation will not throw the error. + * Executes an SOQL (Salesforce Object Query Language) query to retrieve records from Salesforce. + * This operation allows querying Salesforce objects using SOQL syntax and handles pagination. + * Note that in an event of a query error, error logs will be printed but the operation will not throw the error. * * The Salesforce query API is subject to rate limits, {@link https://sforce.co/3W9zyaQ See for more details}. + * * @public * @example Query more records if next records are available * query('SELECT Id FROM Patient__c', { autoFetch: true }); * @example Query patients by Health ID - * query(state=> `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`); + * query(state => `SELECT Id FROM Patient__c WHERE Health_ID__c = '${state.data.healthId}'`); * @example Query patients by Health ID using a lazy state reference * query(`SELECT Id FROM Patient__c WHERE Health_ID__c = '${$.data.healthId}'`); * @function - * @param {string} qs - A query string. Must be less than `4000` characters in WHERE clause - * @param {object} options - Options passed to the bulk api. - * @param {boolean} [options.autoFetch=false] - Fetch next records if available. - * @param {function} callback - A callback to execute once the record is retrieved -<<<<<<< HEAD -======= - * @state {SalesforceState} ->>>>>>> 1ece1ff1 (update examples) - * @returns {Operation} + * @param {string|function} qs - A SOQL query string or a function that returns a query string. Must be less than 4000 characters in WHERE clause + * @param {object} [options] - Optional configuration for the query operation + * @param {boolean} [options.autoFetch=false] - When true, automatically fetches next batch of records if available + * @param {function} [callback] - Optional callback function to execute for each retrieved record + * @state {SalesforceState} - The Salesforce connection state + * @returns {Operation} Returns an Operation object containing the query results and metadata */ export function query(qs, options = {}, callback = s => s) { return async state => { From d1cac65413cf91e5f5cb3489a84201bfe3babc7f Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 12 Nov 2024 21:31:27 +0300 Subject: [PATCH 4/5] add typedef for function options --- packages/salesforce/ast.json | 303 ++++++++++++++++++----------- packages/salesforce/src/Adaptor.js | 95 ++++++--- 2 files changed, 255 insertions(+), 143 deletions(-) diff --git a/packages/salesforce/ast.json b/packages/salesforce/ast.json index bfc597ce2..72a92a5af 100644 --- a/packages/salesforce/ast.json +++ b/packages/salesforce/ast.json @@ -68,74 +68,10 @@ "description": "Options passed to the bulk api.", "type": { "type": "NameExpression", - "name": "object" + "name": "BulkOptions" }, "name": "options" }, - { - "title": "param", - "description": "External id field.", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "string" - } - }, - "name": "options.extIdField" - }, - { - "title": "param", - "description": "Skipping bulk operation if no records.", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "boolean" - } - }, - "name": "options.allowNoOp", - "default": "false" - }, - { - "title": "param", - "description": "Fail the operation on error.", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "boolean" - } - }, - "name": "options.failOnError", - "default": "false" - }, - { - "title": "param", - "description": "Polling interval in milliseconds.", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "integer" - } - }, - "name": "options.pollInterval", - "default": "6000" - }, - { - "title": "param", - "description": "Polling timeout in milliseconds.", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "integer" - } - }, - "name": "options.pollTimeout", - "default": "240000" - }, { "title": "state", "description": "{SalesforceState}" @@ -150,7 +86,7 @@ } ] }, - "valid": false + "valid": true }, { "name": "bulkQuery", @@ -200,36 +136,10 @@ "description": "Options passed to the bulk api.", "type": { "type": "NameExpression", - "name": "object" + "name": "BulkQueryOptions" }, "name": "options" }, - { - "title": "param", - "description": "Polling timeout in milliseconds.", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "integer" - } - }, - "name": "options.pollTimeout", - "default": "90000" - }, - { - "title": "param", - "description": "Polling interval in milliseconds.", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "integer" - } - }, - "name": "options.pollInterval", - "default": "3000" - }, { "title": "state", "description": "{SalesforceState}" @@ -244,7 +154,7 @@ } ] }, - "valid": false + "valid": true }, { "name": "create", @@ -433,6 +343,64 @@ }, "valid": true }, + { + "name": "get", + "params": [ + "path", + "options" + ], + "docs": { + "description": "Send a GET HTTP request using connected session information.", + "tags": [ + { + "title": "public", + "description": null, + "type": null + }, + { + "title": "example", + "description": "get('/actions/custom/flow/POC_OpenFN_Test_Flow');", + "caption": "Make a GET request to a custom Salesforce flow" + }, + { + "title": "function", + "description": null, + "name": null + }, + { + "title": "param", + "description": "The Salesforce API endpoint, Relative to request from", + "type": { + "type": "NameExpression", + "name": "string" + }, + "name": "path" + }, + { + "title": "param", + "description": "Request options", + "type": { + "type": "NameExpression", + "name": "RequestOptions" + }, + "name": "options" + }, + { + "title": "state", + "description": "{SalesforceState}" + }, + { + "title": "returns", + "description": null, + "type": { + "type": "NameExpression", + "name": "Operation" + } + } + ] + }, + "valid": true + }, { "name": "insert", "params": [ @@ -496,6 +464,74 @@ }, "valid": true }, + { + "name": "post", + "params": [ + "path", + "data", + "options" + ], + "docs": { + "description": "Send a POST HTTP request using connected session information.", + "tags": [ + { + "title": "public", + "description": null, + "type": null + }, + { + "title": "example", + "description": "post('/actions/custom/flow/POC_OpenFN_Test_Flow', { inputs: [{}] });", + "caption": "Make a POST request to a custom Salesforce flow" + }, + { + "title": "function", + "description": null, + "name": null + }, + { + "title": "param", + "description": "The Salesforce API endpoint, Relative to request from", + "type": { + "type": "NameExpression", + "name": "string" + }, + "name": "path" + }, + { + "title": "param", + "description": "A JSON Object request body", + "type": { + "type": "NameExpression", + "name": "object" + }, + "name": "data" + }, + { + "title": "param", + "description": "Request options", + "type": { + "type": "NameExpression", + "name": "RequestOptions" + }, + "name": "options" + }, + { + "title": "state", + "description": "{SalesforceState}" + }, + { + "title": "returns", + "description": null, + "type": { + "type": "NameExpression", + "name": "Operation" + } + } + ] + }, + "valid": true + }, { "name": "query", "params": [ @@ -556,24 +592,11 @@ "type": "OptionalType", "expression": { "type": "NameExpression", - "name": "object" + "name": "QueryOptions" } }, "name": "options" }, - { - "title": "param", - "description": "When true, automatically fetches next batch of records if available", - "type": { - "type": "OptionalType", - "expression": { - "type": "NameExpression", - "name": "boolean" - } - }, - "name": "options.autoFetch", - "default": "false" - }, { "title": "param", "description": "Optional callback function to execute for each retrieved record", @@ -588,11 +611,11 @@ }, { "title": "state", - "description": "{SalesforceState} - The Salesforce connection state" + "description": "{SalesforceState}" }, { "title": "returns", - "description": "Returns an Operation object containing the query results and metadata", + "description": null, "type": { "type": "NameExpression", "name": "Operation" @@ -600,7 +623,7 @@ } ] }, - "valid": false + "valid": true }, { "name": "upsert", @@ -825,6 +848,64 @@ }, "valid": true }, + { + "name": "request", + "params": [ + "path", + "options" + ], + "docs": { + "description": "Send a HTTP request using connected session information.", + "tags": [ + { + "title": "public", + "description": null, + "type": null + }, + { + "title": "example", + "description": "request(\"/actions/custom/flow/POC_OpenFN_Test_Flow\", {\n method: \"POST\",\n json: { inputs: [{}] },\n});", + "caption": "Make a POST request to a custom Salesforce flow" + }, + { + "title": "function", + "description": null, + "name": null + }, + { + "title": "param", + "description": "The Salesforce API endpoint, Relative to request from", + "type": { + "type": "NameExpression", + "name": "string" + }, + "name": "path" + }, + { + "title": "param", + "description": "Request options", + "type": { + "type": "NameExpression", + "name": "SalesforceRequestOptions" + }, + "name": "options" + }, + { + "title": "state", + "description": "{SalesforceState}" + }, + { + "title": "returns", + "description": null, + "type": { + "type": "NameExpression", + "name": "Operation" + } + } + ] + }, + "valid": true + }, { "name": "retrieve", "params": [ diff --git a/packages/salesforce/src/Adaptor.js b/packages/salesforce/src/Adaptor.js index 586d74327..0098d8d82 100644 --- a/packages/salesforce/src/Adaptor.js +++ b/packages/salesforce/src/Adaptor.js @@ -18,6 +18,48 @@ * @property references - History of all previous operations results **/ +/** + * Options provided to the Salesforce HTTP request + * @typedef {Object} SalesforceRequestOptions + * @public + * @property {string} [method=GET] - HTTP method to use. Defaults to GET + * @property {object} headers - Object of request headers + * @property {object} query - Object request query + * @property {object} json - Object request body + * @property {string} body - A string request body + */ + +/** + * @typedef {Object} RequestOptions + * @public + * @property {object} headers - Object of request headers + * @property {object} query - Object of request query + * */ + +/** + * Options provided to the Salesforce bulk API request + * @typedef {Object} BulkOptions + * @public + * @property {string} extIdField - External id field. + * @property {boolean} [allowNoOp=false] - Skipping bulk operation if no records. Default: false + * @property {boolean} [failOnError=false] - Fail the operation on error. Default: false + * @property {integer} [pollTimeout=240000] - Polling timeout in milliseconds. + * @property {integer} [pollInterval=6000] - Polling interval in milliseconds. + */ + +/** + * Options provided to the Salesforce bulk query API request + * @typedef {Object} BulkQueryOptions + * @property {integer} [pollTimeout=90000] - Polling timeout in milliseconds. + * @property {integer} [pollInterval=3000] - Polling interval in milliseconds. + * */ + +/** + * @typedef {Object} QueryOptions + * @public + * @property {boolean} [autoFetch=false] - When true, automatically fetches next batch of records if available + * */ + import { execute as commonExecute, composeNextState, @@ -97,12 +139,7 @@ export function execute(...operations) { * @param {string} sObjectName - API name of the sObject. * @param {string} operation - The bulk operation to be performed.Eg "insert" | "update" | "upsert" * @param {array} records - an array of records, or a function which returns an array. - * @param {object} options - Options passed to the bulk api. - * @param {string} [options.extIdField] - External id field. - * @param {boolean} [options.allowNoOp=false] - Skipping bulk operation if no records. - * @param {boolean} [options.failOnError=false] - Fail the operation on error. - * @param {integer} [options.pollInterval=6000] - Polling interval in milliseconds. - * @param {integer} [options.pollTimeout=240000] - Polling timeout in milliseconds. + * @param {BulkOptions} options - Options passed to the bulk api. * @state {SalesforceState} * @returns {Operation} */ @@ -218,9 +255,7 @@ export function bulk(sObjectName, operation, records, options = {}) { * ); * @function * @param {string} qs - A query string. - * @param {object} options - Options passed to the bulk api. - * @param {integer} [options.pollTimeout=90000] - Polling timeout in milliseconds. - * @param {integer} [options.pollInterval=3000] - Polling interval in milliseconds. + * @param {BulkQueryOptions} options - Options passed to the bulk api. * @state {SalesforceState} * @returns {Operation} */ @@ -378,12 +413,12 @@ export function destroy(sObjectName, ids, options = {}) { /** * Send a GET HTTP request using connected session information. + * @public * @example Make a GET request to a custom Salesforce flow * get('/actions/custom/flow/POC_OpenFN_Test_Flow'); + * @function * @param {string} path - The Salesforce API endpoint, Relative to request from - * @param {object} options - Request options - * @param {object} [options.headers] - Object of request headers - * @param {object} [options.query] - A JSON Object request body + * @param {RequestOptions} options - Request options * @state {SalesforceState} * @returns {Operation} */ @@ -428,14 +463,13 @@ export function insert(sObjectName, records) { /** * Send a POST HTTP request using connected session information. - * + * @public * @example Make a POST request to a custom Salesforce flow * post('/actions/custom/flow/POC_OpenFN_Test_Flow', { inputs: [{}] }); + * @function * @param {string} path - The Salesforce API endpoint, Relative to request from * @param {object} data - A JSON Object request body - * @param {object} options - Request options - * @param {object} [options.headers] - Object of request headers - * @param {object} [options.query] - A JSON Object request body + * @param {RequestOptions} options - Request options * @state {SalesforceState} * @returns {Operation} */ @@ -481,12 +515,11 @@ export function post(path, data, options = {}) { * @example Query patients by Health ID using a lazy state reference * query(`SELECT Id FROM Patient__c WHERE Health_ID__c = '${$.data.healthId}'`); * @function - * @param {string|function} qs - A SOQL query string or a function that returns a query string. Must be less than 4000 characters in WHERE clause - * @param {object} [options] - Optional configuration for the query operation - * @param {boolean} [options.autoFetch=false] - When true, automatically fetches next batch of records if available + * @param {(string|function)} qs - A SOQL query string or a function that returns a query string. Must be less than 4000 characters in WHERE clause + * @param {QueryOptions} [options] - Optional configuration for the query operation * @param {function} [callback] - Optional callback function to execute for each retrieved record - * @state {SalesforceState} - The Salesforce connection state - * @returns {Operation} Returns an Operation object containing the query results and metadata + * @state {SalesforceState} + * @returns {Operation} */ export function query(qs, options = {}, callback = s => s) { return async state => { @@ -656,18 +689,15 @@ export function toUTF8(input) { /** * Send a HTTP request using connected session information. - * - * @example - * request('/actions/custom/flow/POC_OpenFN_Test_Flow', { - * method: 'POST', + * @public + * @example Make a POST request to a custom Salesforce flow + * request("/actions/custom/flow/POC_OpenFN_Test_Flow", { + * method: "POST", * json: { inputs: [{}] }, * }); - * @param {string} url - Relative to request from - * @param {object} options - The options for the request. - * @param {string} [options.method=GET] - HTTP method to use. Defaults to GET - * @param {object} [options.headers] - Object of request headers - * @param {object} [options.json] - A JSON object to send as the request body. - * @param {string} [options.body] - HTTP body (in POST/PUT/PATCH methods) + * @function + * @param {string} path - The Salesforce API endpoint, Relative to request from + * @param {SalesforceRequestOptions} options - Request options * @state {SalesforceState} * @returns {Operation} */ @@ -679,11 +709,12 @@ export function request(path, options = {}) { path, options ); - const { method = 'GET', json, body, headers } = resolvedOptions; + const { method = 'GET', json, body, headers, query } = resolvedOptions; const requestOptions = { url: resolvedPath, method, + query, headers: json ? { 'content-type': 'application/json', ...headers } : headers, From b1227a266539ebe020760b672ba52edc75a6840e Mon Sep 17 00:00:00 2001 From: Emmanuel Evance Date: Tue, 12 Nov 2024 21:37:20 +0300 Subject: [PATCH 5/5] add changeset --- .changeset/ten-mayflies-nail.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/ten-mayflies-nail.md diff --git a/.changeset/ten-mayflies-nail.md b/.changeset/ten-mayflies-nail.md new file mode 100644 index 000000000..c8bcda42c --- /dev/null +++ b/.changeset/ten-mayflies-nail.md @@ -0,0 +1,6 @@ +--- +'@openfn/language-salesforce': minor +--- + +- add `query` option in `request` function +- update function examples and improve options documentation