import { parse } from 'yaml'; import { paddingList } from '../helpers/paddingList'; import inquirer from 'inquirer'; export const stepYaml = () => `connectorId: "||VARIABLE_KEY_connectorId||" key: "||VARIABLE_KEY_key||" name: "||VARIABLE_KEY_name||" description: displayType: next: arguments: {} data:`; export function restAPISample(entityType: string) { return parse(`next: arguments: data: url: type: REST method: GET anonymous: false headers: "Content-Type": ["application/json"] queries: {} body: |- {} acceptHttpStatuses: success: parser: regex expression: 2\\d{2} responseFilters: jsonata: items: acceptedStatuses: - success expression: |- $.{ "field_1": field_1, "field_2": field_2 }[] scriban: # there will be a loop for pulling all data from API until hasNextPage return FALSE hasNextPage: acceptedStatuses: - success expression: |- {{(puller.current.PULL_DATA?.items | array.size) > 0}} `); } export function graphQLAPISample(entityType: string) { return parse(`next: arguments: after: |- {{ if puller.lastToken && puller.lastToken.PULL_DATA && puller.lastToken.PULL_DATA.after puller.lastToken.PULL_DATA.after end }} updated_at: |- {{ if puller.history.GET_LAST_UPDATED && puller.history.GET_LAST_UPDATED.updated_at puller.history.GET_LAST_UPDATED.updated_at | hexasync.date.parse 'yyyy-MM-ddTHH:mm:ss.fffZ' | hexasync.date.add_days (-7) | hexasync.date.format_date 'yyyy-MM-dd' else "1970-01-01" end }} data: url: admin/api/{{connector.options.API_VERSION}}/graphql.json type: GRAPHQL method: POST anonymous: false headers: {} queries: {} body: query: |- query products ({{if (__this.arguments.after | string.size) > 0}}$after: String!, {{end}}$query: String!) { products( first:200, sortKey: UPDATED_AT, query: $query {{if (__this.arguments.after | string.size) > 0}}after: $after{{end}} ) { pageInfo { hasNextPage, hasPreviousPage }, edges { cursor, node { legacyResourceId, createdAt, updatedAt, productCode: metafield( namespace: "hexasync" key: "product_code" ) { value, createdAt, updatedAt } } } } } variables: |- { {{if (__this.arguments.after | string.size) > 0}}"after": "{{__this.arguments.after}}",{{end}} "query": "created_at:>={{__this.arguments.updated_at}} OR updated_at:>={{__this.arguments.updated_at}}" } acceptHttpStatuses: success: parser: regex expression: 2\\d{2} responseFilters: jsonata: items: acceptedStatuses: - success expression: |- $.data.products.edges[$exists(node.productCode.value)].node.{ "id": legacyResourceId, "created_at": createdAt, "updated_at": updatedAt, "product_code_value": productCode.value, "product_code_created_at": productCode.createdAt, "product_code_updated_at": productCode.updatedAt }[] jsonpath: cursor: acceptedStatuses: - success expression: |- type: eval expression: >- $.data.products.edges[-1:].cursor hasJsonNextPage: acceptedStatuses: - success expression: |- type: eval expression: >- $.data.products.pageInfo.hasNextPage throttled: acceptedStatuses: - success expression: |- type: eval expression: >- $.errors[:1].extensions.code scriban: after: acceptedStatuses: - success expression: |- {{ if (filters.jsonpath.throttled | string.upcase) == 'THROTTLED' __this.arguments.after else filters.jsonpath.cursor end }} hasNextPage: acceptedStatuses: - success expression: |- {{(filters.jsonpath.throttled | string.upcase) == 'THROTTLED' || (filters.jsonpath.hasJsonNextPage | string.upcase) == 'TRUE' }}`); } export const stepTypeTemplates = () => [ { type: 'FORWARD', getSample: (entityType: string): any => { return { data: {}, arguments: {}, next: `{{ if item | hexasync.item.should_remove "" else if (item.__destination_id | string.size) > 0 "UPDATE" else "CHECK_EXISTS" end }}`, }; }, usage: (entityType: string, stepKey: string) => `n/a`, }, { type: 'SQL', getSample: (entityType: string): any => { return entityType == 'puller' ? { data: { sql: `select p.id, p.name, p.description from p where p.id > @lastId order by p.id limit @limit;`, responseFilters: [ { key: 'items', type: 'List', }, ], // resultSets: { items: "list" }, // keySets: { items: { lastId: "id" } }, hasNextPage: 'items', }, arguments: { lastId: `{{puller.lastToken?.PULL_DATA?.__lastKeys?.lastId}}`, limit: 1000, }, next: ``, } : { data: { sql: `select p.name from p where p.id > @lastId order by p.id limit 1;`, // resultSets: { name: "single" }, responseFilters: [ { key: 'name', type: 'Field', }, ], }, arguments: { lastId: `{{puller.lastToken?.PULL_DATA?.__lastKeys?.lastId}}`, limit: 1000, }, next: ``, }; }, usage: (entityType: string, stepKey: string) => `- ${entityType}.current.${stepKey}. - ${entityType}.current.${stepKey}.[0].`, }, { type: 'API', getSample: async (entityType: string): Promise => { const apiTypes = ['REST', 'GRAPHQL']; const apiTypeNames = apiTypes.map((t, i) => `${i + 1}. ${t}`); console.log(`Please choose one of the API Type below. ${paddingList(apiTypeNames)}`); const answer = await inquirer.prompt<{ value: string }>([ { type: 'input', name: 'value', message: `Answer (default 1):`, }, ]); const index = parseInt(answer.value, 10) || 1; const apiType = apiTypes[index - 1]; switch (apiType) { case 'REST': return restAPISample(entityType); case 'GRAPHQL': return graphQLAPISample(entityType); default: break; } }, usage: (entityType: string, stepKey: string) => `- ${entityType}.current.${stepKey}. - ${entityType}.current.${stepKey}.[0].`, }, { type: 'DIRECT_INDEX', getSample: (entityType: string): any => { return parse(`next: arguments: __is_removed: false data: objectIds: - "****" dataPath: $.${entityType}.current..[*]`); }, usage: (entityType: string, stepKey: string) => `n/a`, }, { type: 'CACHE', getSample: (entityType: string): any => { return parse(`arguments: object_id: "** `n/a`, }, { type: 'VERIFY_CACHED', getSample: (entityType: string): any => { return parse(`arguments: object_id: "** `${entityType}.current.${stepKey}.__destination_id`, }, { type: 'PUSHER', getSample: (entityType: string): any => { return parse(`arguments: item_id: |- {{ pusher.current.GET_SHOPIFY_SALES_ORDER_ITEM_ID.id }} __idx: |- {{ if (pusher.current.PUSH_LINE_ITEMS?.__idx | string.size) > 0 (pusher.current.PUSH_LINE_ITEMS.__idx | string.to_int) + 1 # The Index of the Line Items array else 0 end }} next: {{ if ((pusher.current.PUSH_LINE_ITEMS?.__idx | string.to_int) + 1) < (item.line_items | array.size) "PUSH_LINE_ITEMS" # recursive else "COMMIT_ORDER" end }} data: pusherId: "****" objectId: "****" noError: false responseFilters: scriban: __idx: expression: '{{__this.arguments.__idx}}'`); }, usage: (entityType: string, stepKey: string) => `n/a`, }, { type: 'UPDATE_ITEM_STATUS', getSample: (entityType: string): any => { return parse(` data: objectId: "****" itemIds: (pusher.current.RECONCILE_TOTAL_POINT_BETWEEN_AX_AND_JOY.ax_total_point[0].__id)[] includes: - 1 excludes: - 0`); }, usage: (entityType: string, stepKey: string) => `n/a`, }, { type: 'BASE64_TO_MIME_TYPE', getSample: (entityType: string): any => { return parse(`next: arguments: data: "{{pusher.current.GET_IMAGE_BASE64.image}}"`); }, usage: (entityType: string, stepKey: string) => `${entityType}.current.${stepKey}.mime_type`, }, // { // type: "CHECK_FORMAT", // getSample: (entityType: string): any => {}, // usage: (entityType: string, stepKey: string) => // `${entityType}.current.${stepKey}.mime_type`, // }, // { // type: "DOWNLOAD_CSV", // getSample: (entityType: string): any => {}, // usage: (entityType: string, stepKey: string) => // `${entityType}.current.${stepKey}.mime_type`, // }, { type: 'ENQUEUER', getSample: (entityType: string): any => { return parse(`data: objectId: 'c033791c-b7fb-492f-a3d4-52eb3df00834' itemIds: ($.pusher.current.TRIGGER_AX_STOCK.id_list.__id)[]`); }, usage: (entityType: string, stepKey: string) => `n/a`, }, // { // type: "EXCEPTION", // getSample: (entityType: string): any => {}, // usage: (entityType: string, stepKey: string) => // `${entityType}.current.${stepKey}.mime_type`, // }, // { // type: "GET_KEY_VALUE", // getSample: (entityType: string): any => {}, // usage: (entityType: string, stepKey: string) => // `${entityType}.current.${stepKey}.mime_type`, // }, // { // type: "INVALIDATE_CACHE", // getSample: (entityType: string): any => {}, // usage: (entityType: string, stepKey: string) => // `${entityType}.current.${stepKey}.mime_type`, // }, // { // type: "SET_KEY_VALUE", // getSample: (entityType: string): any => {}, // usage: (entityType: string, stepKey: string) => // `${entityType}.current.${stepKey}.mime_type`, // }, // { // type: "SLEEP", // getSample: (entityType: string): any => {}, // usage: (entityType: string, stepKey: string) => // `${entityType}.current.${stepKey}.mime_type`, // }, ];