n8n-nodes-base 1.93.1 → 1.94.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/credentials/AirtopApi.credentials.js +2 -1
  2. package/dist/credentials/AirtopApi.credentials.js.map +1 -1
  3. package/dist/credentials/JinaAiApi.credentials.js +1 -1
  4. package/dist/credentials/JinaAiApi.credentials.js.map +1 -1
  5. package/dist/credentials/MicrosoftSharePointOAuth2Api.credentials.js +9 -0
  6. package/dist/credentials/MicrosoftSharePointOAuth2Api.credentials.js.map +1 -1
  7. package/dist/credentials/icons/microsoftSharePoint.svg +59 -0
  8. package/dist/known/nodes.json +0 -4
  9. package/dist/nodes/Airtop/Airtop.node.js +14 -8
  10. package/dist/nodes/Airtop/Airtop.node.js.map +1 -1
  11. package/dist/nodes/Airtop/GenericFunctions.js +87 -15
  12. package/dist/nodes/Airtop/GenericFunctions.js.map +1 -1
  13. package/dist/nodes/Airtop/actions/common/fields.js +9 -0
  14. package/dist/nodes/Airtop/actions/common/fields.js.map +1 -1
  15. package/dist/nodes/Airtop/actions/common/output.utils.js +79 -0
  16. package/dist/nodes/Airtop/actions/common/output.utils.js.map +1 -0
  17. package/dist/nodes/Airtop/actions/common/session.utils.js +2 -2
  18. package/dist/nodes/Airtop/actions/common/session.utils.js.map +1 -1
  19. package/dist/nodes/Airtop/actions/extraction/getPaginated.operation.js +13 -4
  20. package/dist/nodes/Airtop/actions/extraction/getPaginated.operation.js.map +1 -1
  21. package/dist/nodes/Airtop/actions/extraction/query.operation.js +21 -3
  22. package/dist/nodes/Airtop/actions/extraction/query.operation.js.map +1 -1
  23. package/dist/nodes/Airtop/actions/extraction/scrape.operation.js +2 -1
  24. package/dist/nodes/Airtop/actions/extraction/scrape.operation.js.map +1 -1
  25. package/dist/nodes/Airtop/actions/file/File.resource.js +104 -0
  26. package/dist/nodes/Airtop/actions/file/File.resource.js.map +1 -0
  27. package/dist/nodes/Airtop/actions/file/delete.operation.js +60 -0
  28. package/dist/nodes/Airtop/actions/file/delete.operation.js.map +1 -0
  29. package/dist/nodes/Airtop/actions/file/get.operation.js +91 -0
  30. package/dist/nodes/Airtop/actions/file/get.operation.js.map +1 -0
  31. package/dist/nodes/Airtop/actions/file/getMany.operation.js +100 -0
  32. package/dist/nodes/Airtop/actions/file/getMany.operation.js.map +1 -0
  33. package/dist/nodes/Airtop/actions/file/helpers.js +199 -0
  34. package/dist/nodes/Airtop/actions/file/helpers.js.map +1 -0
  35. package/dist/nodes/Airtop/actions/file/load.operation.js +85 -0
  36. package/dist/nodes/Airtop/actions/file/load.operation.js.map +1 -0
  37. package/dist/nodes/Airtop/actions/file/upload.operation.js +186 -0
  38. package/dist/nodes/Airtop/actions/file/upload.operation.js.map +1 -0
  39. package/dist/nodes/Airtop/actions/interaction/Interaction.resource.js +22 -1
  40. package/dist/nodes/Airtop/actions/interaction/Interaction.resource.js.map +1 -1
  41. package/dist/nodes/Airtop/actions/interaction/fill.operation.js +89 -0
  42. package/dist/nodes/Airtop/actions/interaction/fill.operation.js.map +1 -0
  43. package/dist/nodes/Airtop/actions/interaction/scroll.operation.js +219 -0
  44. package/dist/nodes/Airtop/actions/interaction/scroll.operation.js.map +1 -0
  45. package/dist/nodes/Airtop/actions/node.type.js.map +1 -1
  46. package/dist/nodes/Airtop/actions/router.js +13 -4
  47. package/dist/nodes/Airtop/actions/router.js.map +1 -1
  48. package/dist/nodes/Airtop/actions/session/create.operation.js +85 -32
  49. package/dist/nodes/Airtop/actions/session/create.operation.js.map +1 -1
  50. package/dist/nodes/Airtop/actions/window/Window.resource.js +2 -1
  51. package/dist/nodes/Airtop/actions/window/Window.resource.js.map +1 -1
  52. package/dist/nodes/Airtop/actions/window/create.operation.js +1 -1
  53. package/dist/nodes/Airtop/actions/window/create.operation.js.map +1 -1
  54. package/dist/nodes/Airtop/actions/window/takeScreenshot.operation.js +26 -3
  55. package/dist/nodes/Airtop/actions/window/takeScreenshot.operation.js.map +1 -1
  56. package/dist/nodes/Airtop/constants.js +38 -5
  57. package/dist/nodes/Airtop/constants.js.map +1 -1
  58. package/dist/nodes/Airtop/countries.js +1026 -0
  59. package/dist/nodes/Airtop/countries.js.map +1 -0
  60. package/dist/nodes/Airtop/transport/index.js +6 -3
  61. package/dist/nodes/Airtop/transport/index.js.map +1 -1
  62. package/dist/nodes/Airtop/transport/types.js.map +1 -1
  63. package/dist/nodes/Google/Drive/v2/actions/file/upload.operation.js +4 -1
  64. package/dist/nodes/Google/Drive/v2/actions/file/upload.operation.js.map +1 -1
  65. package/dist/nodes/Google/Firebase/CloudFirestore/GenericFunctions.js +1 -2
  66. package/dist/nodes/Google/Firebase/CloudFirestore/GenericFunctions.js.map +1 -1
  67. package/dist/nodes/HttpRequest/GenericFunctions.js +1 -1
  68. package/dist/nodes/HttpRequest/GenericFunctions.js.map +1 -1
  69. package/dist/nodes/Merge/Merge.node.js +3 -2
  70. package/dist/nodes/Merge/Merge.node.js.map +1 -1
  71. package/dist/nodes/Merge/v3/actions/mode/combineBySql.js +42 -4
  72. package/dist/nodes/Merge/v3/actions/mode/combineBySql.js.map +1 -1
  73. package/dist/nodes/Merge/v3/actions/versionDescription.js +1 -1
  74. package/dist/nodes/Merge/v3/actions/versionDescription.js.map +1 -1
  75. package/dist/nodes/Microsoft/SharePoint/descriptions/file/update.operation.js +2 -2
  76. package/dist/nodes/Microsoft/SharePoint/descriptions/file/update.operation.js.map +1 -1
  77. package/dist/nodes/Microsoft/SharePoint/descriptions/file/upload.operation.js +2 -2
  78. package/dist/nodes/Microsoft/SharePoint/descriptions/file/upload.operation.js.map +1 -1
  79. package/dist/nodes/Microsoft/SharePoint/descriptions/item/Item.resource.js +1 -1
  80. package/dist/nodes/Microsoft/SharePoint/descriptions/item/Item.resource.js.map +1 -1
  81. package/dist/nodes/Microsoft/SharePoint/descriptions/list/List.resource.js +1 -1
  82. package/dist/nodes/Microsoft/SharePoint/descriptions/list/List.resource.js.map +1 -1
  83. package/dist/nodes/MongoDb/GenericFunctions.js +9 -2
  84. package/dist/nodes/MongoDb/GenericFunctions.js.map +1 -1
  85. package/dist/nodes/MongoDb/MongoDb.node.js +25 -5
  86. package/dist/nodes/MongoDb/MongoDb.node.js.map +1 -1
  87. package/dist/nodes/Telegram/Telegram.node.js +5 -1
  88. package/dist/nodes/Telegram/Telegram.node.js.map +1 -1
  89. package/dist/nodes/Transform/Summarize/utils.js +2 -1
  90. package/dist/nodes/Transform/Summarize/utils.js.map +1 -1
  91. package/dist/test/setup.js +1 -0
  92. package/dist/test/setup.js.map +1 -1
  93. package/dist/types/credentials.json +2 -2
  94. package/dist/types/nodes.json +8 -9
  95. package/package.json +4 -5
  96. package/dist/nodes/EvaluationMetrics/EvaluationMetrics.node.js +0 -119
  97. package/dist/nodes/EvaluationMetrics/EvaluationMetrics.node.js.map +0 -1
  98. package/dist/nodes/EvaluationMetrics/EvaluationMetrics.node.json +0 -14
@@ -21,6 +21,7 @@ __export(AirtopApi_credentials_exports, {
21
21
  AirtopApi: () => AirtopApi
22
22
  });
23
23
  module.exports = __toCommonJS(AirtopApi_credentials_exports);
24
+ var import_constants = require("../nodes/Airtop/constants");
24
25
  class AirtopApi {
25
26
  constructor() {
26
27
  this.name = "airtopApi";
@@ -52,7 +53,7 @@ class AirtopApi {
52
53
  this.test = {
53
54
  request: {
54
55
  method: "GET",
55
- baseURL: "https://api.airtop.ai/api/v1",
56
+ baseURL: import_constants.BASE_URL,
56
57
  url: "/sessions",
57
58
  qs: {
58
59
  limit: 10
@@ -1 +1 @@
1
- {"version":3,"sources":["../../credentials/AirtopApi.credentials.ts"],"sourcesContent":["import type {\n\tIAuthenticateGeneric,\n\tICredentialType,\n\tICredentialTestRequest,\n\tINodeProperties,\n} from 'n8n-workflow';\n\nexport class AirtopApi implements ICredentialType {\n\tname = 'airtopApi';\n\n\tdisplayName = 'Airtop API';\n\n\tdocumentationUrl = 'airtop';\n\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'apiKey',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\tdescription:\n\t\t\t\t'The Airtop API key. You can create one at <a href=\"https://portal.airtop.ai/api-keys\" target=\"_blank\">Airtop</a> for free.',\n\t\t\trequired: true,\n\t\t\ttypeOptions: {\n\t\t\t\tpassword: true,\n\t\t\t},\n\t\t\tnoDataExpression: true,\n\t\t},\n\t];\n\n\tauthenticate: IAuthenticateGeneric = {\n\t\ttype: 'generic',\n\t\tproperties: {\n\t\t\theaders: {\n\t\t\t\tAuthorization: '=Bearer {{$credentials.apiKey}}',\n\t\t\t\t'api-key': '={{$credentials.apiKey}}',\n\t\t\t},\n\t\t},\n\t};\n\n\ttest: ICredentialTestRequest = {\n\t\trequest: {\n\t\t\tmethod: 'GET',\n\t\t\tbaseURL: 'https://api.airtop.ai/api/v1',\n\t\t\turl: '/sessions',\n\t\t\tqs: {\n\t\t\t\tlimit: 10,\n\t\t\t},\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,MAAM,UAAqC;AAAA,EAA3C;AACN,gBAAO;AAEP,uBAAc;AAEd,4BAAmB;AAEnB,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACC;AAAA,QACD,UAAU;AAAA,QACV,aAAa;AAAA,UACZ,UAAU;AAAA,QACX;AAAA,QACA,kBAAkB;AAAA,MACnB;AAAA,IACD;AAEA,wBAAqC;AAAA,MACpC,MAAM;AAAA,MACN,YAAY;AAAA,QACX,SAAS;AAAA,UACR,eAAe;AAAA,UACf,WAAW;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AAEA,gBAA+B;AAAA,MAC9B,SAAS;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,KAAK;AAAA,QACL,IAAI;AAAA,UACH,OAAO;AAAA,QACR;AAAA,MACD;AAAA,IACD;AAAA;AACD;","names":[]}
1
+ {"version":3,"sources":["../../credentials/AirtopApi.credentials.ts"],"sourcesContent":["import type {\n\tIAuthenticateGeneric,\n\tICredentialType,\n\tICredentialTestRequest,\n\tINodeProperties,\n} from 'n8n-workflow';\n\nimport { BASE_URL } from '../nodes/Airtop/constants';\n\nexport class AirtopApi implements ICredentialType {\n\tname = 'airtopApi';\n\n\tdisplayName = 'Airtop API';\n\n\tdocumentationUrl = 'airtop';\n\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'apiKey',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\tdescription:\n\t\t\t\t'The Airtop API key. You can create one at <a href=\"https://portal.airtop.ai/api-keys\" target=\"_blank\">Airtop</a> for free.',\n\t\t\trequired: true,\n\t\t\ttypeOptions: {\n\t\t\t\tpassword: true,\n\t\t\t},\n\t\t\tnoDataExpression: true,\n\t\t},\n\t];\n\n\tauthenticate: IAuthenticateGeneric = {\n\t\ttype: 'generic',\n\t\tproperties: {\n\t\t\theaders: {\n\t\t\t\tAuthorization: '=Bearer {{$credentials.apiKey}}',\n\t\t\t\t'api-key': '={{$credentials.apiKey}}',\n\t\t\t},\n\t\t},\n\t};\n\n\ttest: ICredentialTestRequest = {\n\t\trequest: {\n\t\t\tmethod: 'GET',\n\t\t\tbaseURL: BASE_URL,\n\t\t\turl: '/sessions',\n\t\t\tqs: {\n\t\t\t\tlimit: 10,\n\t\t\t},\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOA,uBAAyB;AAElB,MAAM,UAAqC;AAAA,EAA3C;AACN,gBAAO;AAEP,uBAAc;AAEd,4BAAmB;AAEnB,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,aACC;AAAA,QACD,UAAU;AAAA,QACV,aAAa;AAAA,UACZ,UAAU;AAAA,QACX;AAAA,QACA,kBAAkB;AAAA,MACnB;AAAA,IACD;AAEA,wBAAqC;AAAA,MACpC,MAAM;AAAA,MACN,YAAY;AAAA,QACX,SAAS;AAAA,UACR,eAAe;AAAA,UACf,WAAW;AAAA,QACZ;AAAA,MACD;AAAA,IACD;AAEA,gBAA+B;AAAA,MAC9B,SAAS;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,KAAK;AAAA,QACL,IAAI;AAAA,UACH,OAAO;AAAA,QACR;AAAA,MACD;AAAA,IACD;AAAA;AACD;","names":[]}
@@ -25,7 +25,7 @@ class JinaAiApi {
25
25
  constructor() {
26
26
  this.name = "jinaAiApi";
27
27
  this.displayName = "Jina AI API";
28
- this.documentationUrl = "jinaAi";
28
+ this.documentationUrl = "jinaai";
29
29
  this.properties = [
30
30
  {
31
31
  displayName: "API Key",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../credentials/JinaAiApi.credentials.ts"],"sourcesContent":["import type {\n\tIAuthenticateGeneric,\n\tICredentialTestRequest,\n\tICredentialType,\n\tINodeProperties,\n} from 'n8n-workflow';\n\nexport class JinaAiApi implements ICredentialType {\n\tname = 'jinaAiApi';\n\n\tdisplayName = 'Jina AI API';\n\n\tdocumentationUrl = 'jinaAi';\n\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'apiKey',\n\t\t\ttype: 'string',\n\t\t\ttypeOptions: { password: true },\n\t\t\tdefault: '',\n\t\t},\n\t];\n\n\tauthenticate: IAuthenticateGeneric = {\n\t\ttype: 'generic',\n\t\tproperties: {\n\t\t\theaders: {\n\t\t\t\tAuthorization: '=Bearer {{ $credentials?.apiKey }}',\n\t\t\t},\n\t\t},\n\t};\n\n\ttest: ICredentialTestRequest = {\n\t\trequest: {\n\t\t\tmethod: 'GET',\n\t\t\turl: 'https://embeddings-dashboard-api.jina.ai/api/v1/api_key/fe_user',\n\t\t\tqs: {\n\t\t\t\tapi_key: '={{$credentials.apiKey}}',\n\t\t\t},\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,MAAM,UAAqC;AAAA,EAA3C;AACN,gBAAO;AAEP,uBAAc;AAEd,4BAAmB;AAEnB,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa,EAAE,UAAU,KAAK;AAAA,QAC9B,SAAS;AAAA,MACV;AAAA,IACD;AAEA,wBAAqC;AAAA,MACpC,MAAM;AAAA,MACN,YAAY;AAAA,QACX,SAAS;AAAA,UACR,eAAe;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AAEA,gBAA+B;AAAA,MAC9B,SAAS;AAAA,QACR,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,IAAI;AAAA,UACH,SAAS;AAAA,QACV;AAAA,MACD;AAAA,IACD;AAAA;AACD;","names":[]}
1
+ {"version":3,"sources":["../../credentials/JinaAiApi.credentials.ts"],"sourcesContent":["import type {\n\tIAuthenticateGeneric,\n\tICredentialTestRequest,\n\tICredentialType,\n\tINodeProperties,\n} from 'n8n-workflow';\n\nexport class JinaAiApi implements ICredentialType {\n\tname = 'jinaAiApi';\n\n\tdisplayName = 'Jina AI API';\n\n\tdocumentationUrl = 'jinaai';\n\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'API Key',\n\t\t\tname: 'apiKey',\n\t\t\ttype: 'string',\n\t\t\ttypeOptions: { password: true },\n\t\t\tdefault: '',\n\t\t},\n\t];\n\n\tauthenticate: IAuthenticateGeneric = {\n\t\ttype: 'generic',\n\t\tproperties: {\n\t\t\theaders: {\n\t\t\t\tAuthorization: '=Bearer {{ $credentials?.apiKey }}',\n\t\t\t},\n\t\t},\n\t};\n\n\ttest: ICredentialTestRequest = {\n\t\trequest: {\n\t\t\tmethod: 'GET',\n\t\t\turl: 'https://embeddings-dashboard-api.jina.ai/api/v1/api_key/fe_user',\n\t\t\tqs: {\n\t\t\t\tapi_key: '={{$credentials.apiKey}}',\n\t\t\t},\n\t\t},\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAOO,MAAM,UAAqC;AAAA,EAA3C;AACN,gBAAO;AAEP,uBAAc;AAEd,4BAAmB;AAEnB,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,aAAa,EAAE,UAAU,KAAK;AAAA,QAC9B,SAAS;AAAA,MACV;AAAA,IACD;AAEA,wBAAqC;AAAA,MACpC,MAAM;AAAA,MACN,YAAY;AAAA,QACX,SAAS;AAAA,UACR,eAAe;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AAEA,gBAA+B;AAAA,MAC9B,SAAS;AAAA,QACR,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,IAAI;AAAA,UACH,SAAS;AAAA,QACV;AAAA,MACD;AAAA,IACD;AAAA;AACD;","names":[]}
@@ -25,8 +25,17 @@ class MicrosoftSharePointOAuth2Api {
25
25
  constructor() {
26
26
  this.name = "microsoftSharePointOAuth2Api";
27
27
  this.extends = ["microsoftOAuth2Api"];
28
+ this.icon = {
29
+ light: "file:icons/microsoftSharePoint.svg",
30
+ dark: "file:icons/microsoftSharePoint.svg"
31
+ };
28
32
  this.displayName = "Microsoft SharePoint OAuth2 API";
29
33
  this.documentationUrl = "microsoft";
34
+ this.httpRequestNode = {
35
+ name: "Microsoft SharePoint",
36
+ docsUrl: "https://learn.microsoft.com/en-us/sharepoint/dev/apis/sharepoint-rest-graph",
37
+ apiBaseUrlPlaceholder: "https://{subdomain}.sharepoint.com/_api/v2.0/"
38
+ };
30
39
  this.properties = [
31
40
  {
32
41
  displayName: "Scope",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../credentials/MicrosoftSharePointOAuth2Api.credentials.ts"],"sourcesContent":["import type { ICredentialType, INodeProperties } from 'n8n-workflow';\n\nexport class MicrosoftSharePointOAuth2Api implements ICredentialType {\n\tname = 'microsoftSharePointOAuth2Api';\n\n\textends = ['microsoftOAuth2Api'];\n\n\tdisplayName = 'Microsoft SharePoint OAuth2 API';\n\n\tdocumentationUrl = 'microsoft';\n\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'Scope',\n\t\t\tname: 'scope',\n\t\t\ttype: 'hidden',\n\t\t\tdefault: '=openid offline_access https://{{$self.subdomain}}.sharepoint.com/.default',\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Subdomain',\n\t\t\tname: 'subdomain',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\thint: 'You can extract the subdomain from the URL. For example, in the URL \"https://tenant123.sharepoint.com\", the subdomain is \"tenant123\".',\n\t\t},\n\t];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,MAAM,6BAAwD;AAAA,EAA9D;AACN,gBAAO;AAEP,mBAAU,CAAC,oBAAoB;AAE/B,uBAAc;AAEd,4BAAmB;AAEnB,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,MACV;AAAA,MACA;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MACP;AAAA,IACD;AAAA;AACD;","names":[]}
1
+ {"version":3,"sources":["../../credentials/MicrosoftSharePointOAuth2Api.credentials.ts"],"sourcesContent":["import type { Icon, ICredentialType, INodeProperties } from 'n8n-workflow';\n\nexport class MicrosoftSharePointOAuth2Api implements ICredentialType {\n\tname = 'microsoftSharePointOAuth2Api';\n\n\textends = ['microsoftOAuth2Api'];\n\n\ticon: Icon = {\n\t\tlight: 'file:icons/microsoftSharePoint.svg',\n\t\tdark: 'file:icons/microsoftSharePoint.svg',\n\t};\n\n\tdisplayName = 'Microsoft SharePoint OAuth2 API';\n\n\tdocumentationUrl = 'microsoft';\n\n\thttpRequestNode = {\n\t\tname: 'Microsoft SharePoint',\n\t\tdocsUrl: 'https://learn.microsoft.com/en-us/sharepoint/dev/apis/sharepoint-rest-graph',\n\t\tapiBaseUrlPlaceholder: 'https://{subdomain}.sharepoint.com/_api/v2.0/',\n\t};\n\n\tproperties: INodeProperties[] = [\n\t\t{\n\t\t\tdisplayName: 'Scope',\n\t\t\tname: 'scope',\n\t\t\ttype: 'hidden',\n\t\t\tdefault: '=openid offline_access https://{{$self.subdomain}}.sharepoint.com/.default',\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Subdomain',\n\t\t\tname: 'subdomain',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\thint: 'You can extract the subdomain from the URL. For example, in the URL \"https://tenant123.sharepoint.com\", the subdomain is \"tenant123\".',\n\t\t},\n\t];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEO,MAAM,6BAAwD;AAAA,EAA9D;AACN,gBAAO;AAEP,mBAAU,CAAC,oBAAoB;AAE/B,gBAAa;AAAA,MACZ,OAAO;AAAA,MACP,MAAM;AAAA,IACP;AAEA,uBAAc;AAEd,4BAAmB;AAEnB,2BAAkB;AAAA,MACjB,MAAM;AAAA,MACN,SAAS;AAAA,MACT,uBAAuB;AAAA,IACxB;AAEA,sBAAgC;AAAA,MAC/B;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,MACV;AAAA,MACA;AAAA,QACC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM;AAAA,MACP;AAAA,IACD;AAAA;AACD;","names":[]}
@@ -0,0 +1,59 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
4
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
5
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
6
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
7
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
8
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
9
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
10
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
11
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
12
+ ]>
13
+ <svg version="1.1" id="Livello_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
14
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1992.333 1946"
15
+ enable-background="new 0 0 1992.333 1946" xml:space="preserve">
16
+ <metadata>
17
+ <sfw xmlns="&ns_sfw;">
18
+ <slices></slices>
19
+ <sliceSourceBounds bottomLeftOrigin="true" height="1946" width="1992.333" x="-995.333" y="-949"></sliceSourceBounds>
20
+ </sfw>
21
+ </metadata>
22
+ <circle fill="#036C70" cx="1019.333" cy="556" r="556"/>
23
+ <circle fill="#1A9BA1" cx="1482.667" cy="1065.667" r="509.667"/>
24
+ <circle fill="#37C6D0" cx="1088.833" cy="1552.167" r="393.833"/>
25
+ <path opacity="0.1" enable-background="new " d="M1112,501.79v988.753c-0.23,34.357-21.05,65.222-52.82,78.303
26
+ c-10.116,4.279-20.987,6.484-31.97,6.487H695.463c-0.463-7.877-0.463-15.29-0.463-23.167c-0.154-7.734,0.155-15.47,0.927-23.167
27
+ c8.48-148.106,99.721-278.782,235.837-337.77v-86.18c-302.932-48.005-509.592-332.495-461.587-635.427
28
+ c0.333-2.098,0.677-4.195,1.034-6.289c2.306-15.626,5.556-31.099,9.73-46.333h546.27C1073.964,417.178,1111.822,455.036,1112,501.79
29
+ z"/>
30
+ <path opacity="0.2" enable-background="new " d="M980.877,463.333H471.21c-51.486,302.386,151.908,589.256,454.293,640.742
31
+ c9.156,1.559,18.35,2.888,27.573,3.986c-143.633,68.11-248.3,261.552-257.196,420.938c-0.771,7.697-1.081,15.433-0.927,23.167
32
+ c0,7.877,0,15.29,0.463,23.167c0.836,15.574,2.85,31.063,6.023,46.333h279.39c34.357-0.23,65.222-21.05,78.303-52.82
33
+ c4.279-10.115,6.485-20.987,6.487-31.97V548.123C1065.443,501.387,1027.613,463.537,980.877,463.333z"/>
34
+ <path opacity="0.2" enable-background="new " d="M980.877,463.333H471.21c-51.475,302.414,151.95,589.297,454.364,640.773
35
+ c6.186,1.053,12.389,2.001,18.607,2.844c-139,73.021-239.543,266-248.254,422.05h284.95c46.681-0.353,84.437-38.109,84.79-84.79
36
+ V548.123C1065.489,501.369,1027.631,463.511,980.877,463.333z"/>
37
+ <path opacity="0.2" enable-background="new " d="M934.543,463.333H471.21c-48.606,285.482,130.279,560.404,410.977,631.616
38
+ C775.901,1216.384,710.711,1368.301,695.927,1529h238.617c46.754-0.178,84.612-38.036,84.79-84.79V548.123
39
+ C1019.308,501.306,981.361,463.359,934.543,463.333z"/>
40
+ <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="177.0788" y1="1551.0284" x2="842.2545" y2="398.9716" gradientTransform="matrix(1 0 0 -1 0 1948)">
41
+ <stop offset="0" style="stop-color:#058F92"/>
42
+ <stop offset="0.5" style="stop-color:#038489"/>
43
+ <stop offset="1" style="stop-color:#026D71"/>
44
+ </linearGradient>
45
+ <path fill="url(#SVGID_1_)" d="M84.929,463.333h849.475c46.905,0,84.929,38.024,84.929,84.929v849.475
46
+ c0,46.905-38.024,84.929-84.929,84.929H84.929c-46.905,0-84.929-38.024-84.929-84.929V548.262
47
+ C0,501.357,38.024,463.333,84.929,463.333z"/>
48
+ <path fill="#FFFFFF" d="M379.331,962.621c-19.903-13.202-36.528-30.777-48.604-51.384c-11.701-21.542-17.533-45.781-16.912-70.288
49
+ c-1.042-33.181,10.155-65.586,31.46-91.045c22.388-25.49,51.326-44.366,83.678-54.581c36.871-12.136,75.49-18.116,114.304-17.699
50
+ c51.043-1.865,102.015,5.272,150.583,21.082v106.567c-21.103-12.784-44.088-22.166-68.11-27.8
51
+ c-26.065-6.392-52.81-9.597-79.647-9.545c-28.3-1.039-56.419,4.913-81.871,17.329c-19.65,8.475-32.392,27.807-32.433,49.206
52
+ c-0.08,12.981,4.907,25.481,13.9,34.843c10.622,11.037,23.187,20.021,37.067,26.503c15.444,7.691,38.611,17.916,69.5,30.673
53
+ c3.401,1.075,6.716,2.407,9.915,3.985c30.401,11.881,59.729,26.344,87.663,43.229c21.154,13.043,38.908,30.924,51.801,52.171
54
+ c13.218,24.085,19.625,51.315,18.533,78.767c1.509,34.066-8.913,67.591-29.468,94.798c-20.488,25.012-47.88,43.446-78.767,53.005
55
+ c-36.329,11.387-74.245,16.892-112.312,16.309c-34.154,0.155-68.258-2.635-101.933-8.34c-28.434-4.653-56.182-12.807-82.612-24.279
56
+ v-112.358c25.264,18.043,53.489,31.529,83.4,39.847c29.81,9.289,60.798,14.251,92.018,14.734c28.895,1.83,57.739-4.291,83.4-17.699
57
+ c17.976-10.144,28.909-29.358,28.449-49.994c0.12-14.359-5.56-28.158-15.753-38.271c-12.676-12.444-27.352-22.671-43.414-30.256
58
+ c-18.533-9.267-45.824-21.483-81.871-36.65C432.618,993.951,405.161,979.594,379.331,962.621z"/>
59
+ </svg>
@@ -427,10 +427,6 @@
427
427
  "className": "ExecutionData",
428
428
  "sourcePath": "dist/nodes/ExecutionData/ExecutionData.node.js"
429
429
  },
430
- "evaluationMetrics": {
431
- "className": "EvaluationMetrics",
432
- "sourcePath": "dist/nodes/EvaluationMetrics/EvaluationMetrics.node.js"
433
- },
434
430
  "facebookGraphApi": {
435
431
  "className": "FacebookGraphApi",
436
432
  "sourcePath": "dist/nodes/Facebook/FacebookGraphApi.node.js"
@@ -33,6 +33,7 @@ __export(Airtop_node_exports, {
33
33
  module.exports = __toCommonJS(Airtop_node_exports);
34
34
  var import_n8n_workflow = require("n8n-workflow");
35
35
  var extraction = __toESM(require("./actions/extraction/Extraction.resource"));
36
+ var file = __toESM(require("./actions/file/File.resource"));
36
37
  var interaction = __toESM(require("./actions/interaction/Interaction.resource"));
37
38
  var import_router = require("./actions/router");
38
39
  var session = __toESM(require("./actions/session/Session.resource"));
@@ -67,27 +68,32 @@ class Airtop {
67
68
  type: "options",
68
69
  noDataExpression: true,
69
70
  options: [
70
- {
71
- name: "Session",
72
- value: "session"
73
- },
74
- {
75
- name: "Window",
76
- value: "window"
77
- },
78
71
  {
79
72
  name: "Extraction",
80
73
  value: "extraction"
81
74
  },
75
+ {
76
+ name: "File",
77
+ value: "file"
78
+ },
82
79
  {
83
80
  name: "Interaction",
84
81
  value: "interaction"
82
+ },
83
+ {
84
+ name: "Session",
85
+ value: "session"
86
+ },
87
+ {
88
+ name: "Window",
89
+ value: "window"
85
90
  }
86
91
  ],
87
92
  default: "session"
88
93
  },
89
94
  ...session.description,
90
95
  ...window.description,
96
+ ...file.description,
91
97
  ...extraction.description,
92
98
  ...interaction.description
93
99
  ]
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../nodes/Airtop/Airtop.node.ts"],"sourcesContent":["import { NodeConnectionTypes } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeType, INodeTypeDescription } from 'n8n-workflow';\n\nimport * as extraction from './actions/extraction/Extraction.resource';\nimport * as interaction from './actions/interaction/Interaction.resource';\nimport { router } from './actions/router';\nimport * as session from './actions/session/Session.resource';\nimport * as window from './actions/window/Window.resource';\nexport class Airtop implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Airtop',\n\t\tname: 'airtop',\n\t\ticon: 'file:airtop.svg',\n\t\tgroup: ['transform'],\n\t\tdefaultVersion: 1,\n\t\tversion: [1],\n\t\tsubtitle: '={{ $parameter[\"operation\"] + \": \" + $parameter[\"resource\"] }}',\n\t\tdescription: 'Scrape and control any site with Airtop',\n\t\tusableAsTool: true,\n\t\tdefaults: {\n\t\t\tname: 'Airtop',\n\t\t},\n\t\tinputs: [NodeConnectionTypes.Main],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'airtopApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Resource',\n\t\t\t\tname: 'resource',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Session',\n\t\t\t\t\t\tvalue: 'session',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Window',\n\t\t\t\t\t\tvalue: 'window',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Extraction',\n\t\t\t\t\t\tvalue: 'extraction',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Interaction',\n\t\t\t\t\t\tvalue: 'interaction',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'session',\n\t\t\t},\n\t\t\t...session.description,\n\t\t\t...window.description,\n\t\t\t...extraction.description,\n\t\t\t...interaction.description,\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions) {\n\t\treturn await router.call(this);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAoC;AAGpC,iBAA4B;AAC5B,kBAA6B;AAC7B,oBAAuB;AACvB,cAAyB;AACzB,aAAwB;AACjB,MAAM,OAA4B;AAAA,EAAlC;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,WAAW;AAAA,MACnB,gBAAgB;AAAA,MAChB,SAAS,CAAC,CAAC;AAAA,MACX,UAAU;AAAA,MACV,aAAa;AAAA,MACb,cAAc;AAAA,MACd,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,QAAQ,CAAC,wCAAoB,IAAI;AAAA,MACjC,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,YAAY;AAAA,QACX;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,SAAS;AAAA,QACV;AAAA,QACA,GAAG,QAAQ;AAAA,QACX,GAAG,OAAO;AAAA,QACV,GAAG,WAAW;AAAA,QACd,GAAG,YAAY;AAAA,MAChB;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,UAAiC;AACtC,WAAO,MAAM,qBAAO,KAAK,IAAI;AAAA,EAC9B;AACD;","names":[]}
1
+ {"version":3,"sources":["../../../nodes/Airtop/Airtop.node.ts"],"sourcesContent":["import { NodeConnectionTypes } from 'n8n-workflow';\nimport type { IExecuteFunctions, INodeType, INodeTypeDescription } from 'n8n-workflow';\n\nimport * as extraction from './actions/extraction/Extraction.resource';\nimport * as file from './actions/file/File.resource';\nimport * as interaction from './actions/interaction/Interaction.resource';\nimport { router } from './actions/router';\nimport * as session from './actions/session/Session.resource';\nimport * as window from './actions/window/Window.resource';\n\nexport class Airtop implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Airtop',\n\t\tname: 'airtop',\n\t\ticon: 'file:airtop.svg',\n\t\tgroup: ['transform'],\n\t\tdefaultVersion: 1,\n\t\tversion: [1],\n\t\tsubtitle: '={{ $parameter[\"operation\"] + \": \" + $parameter[\"resource\"] }}',\n\t\tdescription: 'Scrape and control any site with Airtop',\n\t\tusableAsTool: true,\n\t\tdefaults: {\n\t\t\tname: 'Airtop',\n\t\t},\n\t\tinputs: [NodeConnectionTypes.Main],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'airtopApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Resource',\n\t\t\t\tname: 'resource',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Extraction',\n\t\t\t\t\t\tvalue: 'extraction',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'File',\n\t\t\t\t\t\tvalue: 'file',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Interaction',\n\t\t\t\t\t\tvalue: 'interaction',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Session',\n\t\t\t\t\t\tvalue: 'session',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Window',\n\t\t\t\t\t\tvalue: 'window',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'session',\n\t\t\t},\n\t\t\t...session.description,\n\t\t\t...window.description,\n\t\t\t...file.description,\n\t\t\t...extraction.description,\n\t\t\t...interaction.description,\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions) {\n\t\treturn await router.call(this);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAoC;AAGpC,iBAA4B;AAC5B,WAAsB;AACtB,kBAA6B;AAC7B,oBAAuB;AACvB,cAAyB;AACzB,aAAwB;AAEjB,MAAM,OAA4B;AAAA,EAAlC;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,WAAW;AAAA,MACnB,gBAAgB;AAAA,MAChB,SAAS,CAAC,CAAC;AAAA,MACX,UAAU;AAAA,MACV,aAAa;AAAA,MACb,cAAc;AAAA,MACd,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,QAAQ,CAAC,wCAAoB,IAAI;AAAA,MACjC,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,YAAY;AAAA,QACX;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,SAAS;AAAA,QACV;AAAA,QACA,GAAG,QAAQ;AAAA,QACX,GAAG,OAAO;AAAA,QACV,GAAG,KAAK;AAAA,QACR,GAAG,WAAW;AAAA,QACd,GAAG,YAAY;AAAA,MAChB;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,UAAiC;AACtC,WAAO,MAAM,qBAAO,KAAK,IAAI;AAAA,EAC9B;AACD;","names":[]}
@@ -19,14 +19,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
19
  var GenericFunctions_exports = {};
20
20
  __export(GenericFunctions_exports, {
21
21
  convertScreenshotToBinary: () => convertScreenshotToBinary,
22
+ createSession: () => createSession,
22
23
  createSessionAndWindow: () => createSessionAndWindow,
23
24
  shouldCreateNewSession: () => shouldCreateNewSession,
24
25
  validateAirtopApiResponse: () => validateAirtopApiResponse,
25
26
  validateProfileName: () => validateProfileName,
26
- validateProxyUrl: () => validateProxyUrl,
27
+ validateProxy: () => validateProxy,
27
28
  validateRequiredStringField: () => validateRequiredStringField,
28
29
  validateSaveProfileOnTermination: () => validateSaveProfileOnTermination,
29
30
  validateScreenResolution: () => validateScreenResolution,
31
+ validateScrollByAmount: () => validateScrollByAmount,
32
+ validateScrollingMode: () => validateScrollingMode,
30
33
  validateSessionAndWindowId: () => validateSessionAndWindowId,
31
34
  validateSessionId: () => validateSessionId,
32
35
  validateTimeoutMinutes: () => validateTimeoutMinutes,
@@ -39,7 +42,7 @@ var import_fields = require("./actions/common/fields");
39
42
  var import_constants = require("./constants");
40
43
  var import_transport = require("./transport");
41
44
  function validateRequiredStringField(index, field, fieldName) {
42
- let value = this.getNodeParameter(field, index);
45
+ let value = this.getNodeParameter(field, index, "");
43
46
  value = (value || "").trim();
44
47
  const errorMessage = import_constants.ERROR_MESSAGES.REQUIRED_PARAMETER.replace("{{field}}", fieldName);
45
48
  if (!value) {
@@ -118,23 +121,57 @@ function validateUrl(index) {
118
121
  }
119
122
  return url;
120
123
  }
121
- function validateProxyUrl(index, proxy) {
122
- let proxyUrl = this.getNodeParameter("proxyUrl", index, "");
123
- proxyUrl = (proxyUrl || "").trim();
124
- if (proxy !== "custom") {
125
- return "";
124
+ function validateProxy(index) {
125
+ const proxyParam = this.getNodeParameter("proxy", index, "");
126
+ const proxyConfig = this.getNodeParameter("proxyConfig", index, "");
127
+ const isConfigEmpty = Object.keys(proxyConfig).length === 0;
128
+ if (proxyParam === "integrated") {
129
+ return {
130
+ proxy: isConfigEmpty ? true : { ...proxyConfig }
131
+ };
132
+ }
133
+ if (proxyParam === "proxyUrl") {
134
+ return {
135
+ proxy: validateRequiredStringField.call(this, index, "proxyUrl", "Proxy URL")
136
+ };
137
+ }
138
+ return {
139
+ proxy: false
140
+ };
141
+ }
142
+ function validateScrollByAmount(index, parameterName) {
143
+ const regex = /^(?:-?\d{1,3}(?:%|px))$/;
144
+ const scrollBy = this.getNodeParameter(parameterName, index, {});
145
+ if (!scrollBy?.xAxis && !scrollBy?.yAxis) {
146
+ return {};
126
147
  }
127
- if (!proxyUrl) {
128
- throw new import_n8n_workflow2.NodeOperationError(this.getNode(), import_constants.ERROR_MESSAGES.PROXY_URL_REQUIRED, {
148
+ const allAxisValid = [scrollBy.xAxis, scrollBy.yAxis].filter(Boolean).every((axis) => regex.test(axis ?? ""));
149
+ if (!allAxisValid) {
150
+ throw new import_n8n_workflow2.NodeOperationError(this.getNode(), import_constants.ERROR_MESSAGES.SCROLL_BY_AMOUNT_INVALID, {
129
151
  itemIndex: index
130
152
  });
131
153
  }
132
- if (!proxyUrl.startsWith("http")) {
133
- throw new import_n8n_workflow2.NodeOperationError(this.getNode(), import_constants.ERROR_MESSAGES.PROXY_URL_INVALID, {
154
+ return scrollBy;
155
+ }
156
+ function validateScrollingMode(index) {
157
+ const scrollingMode = this.getNodeParameter(
158
+ "scrollingMode",
159
+ index,
160
+ "automatic"
161
+ );
162
+ const scrollToEdge = this.getNodeParameter("scrollToEdge.edgeValues", index, {});
163
+ const scrollBy = this.getNodeParameter("scrollBy.scrollValues", index, {});
164
+ if (scrollingMode !== "manual") {
165
+ return scrollingMode;
166
+ }
167
+ const emptyScrollBy = !scrollBy.xAxis && !scrollBy.yAxis;
168
+ const emptyScrollToEdge = !scrollToEdge.xAxis && !scrollToEdge.yAxis;
169
+ if (emptyScrollBy && emptyScrollToEdge) {
170
+ throw new import_n8n_workflow2.NodeOperationError(this.getNode(), import_constants.ERROR_MESSAGES.SCROLL_MODE_INVALID, {
134
171
  itemIndex: index
135
172
  });
136
173
  }
137
- return proxyUrl;
174
+ return scrollingMode;
138
175
  }
139
176
  function validateScreenResolution(index) {
140
177
  let screenResolution = this.getNodeParameter("screenResolution", index, "");
@@ -180,12 +217,44 @@ function shouldCreateNewSession(index) {
180
217
  const sessionMode = this.getNodeParameter("sessionMode", index);
181
218
  return Boolean(sessionMode && sessionMode === import_fields.SESSION_MODE.NEW);
182
219
  }
220
+ async function createSession(parameters, timeout = import_constants.OPERATION_TIMEOUT) {
221
+ const response = await import_transport.apiRequest.call(
222
+ this,
223
+ "POST",
224
+ "/sessions",
225
+ parameters
226
+ );
227
+ const sessionId = response?.data?.id;
228
+ if (!sessionId) {
229
+ throw new import_n8n_workflow.NodeApiError(this.getNode(), {
230
+ message: "Failed to create session",
231
+ code: 500
232
+ });
233
+ }
234
+ let sessionStatus = response?.data?.status;
235
+ const startTime = Date.now();
236
+ while (sessionStatus !== import_constants.SESSION_STATUS.RUNNING) {
237
+ if (Date.now() - startTime > timeout) {
238
+ throw new import_n8n_workflow.NodeApiError(this.getNode(), {
239
+ message: import_constants.ERROR_MESSAGES.TIMEOUT_REACHED,
240
+ code: 500
241
+ });
242
+ }
243
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
244
+ const sessionStatusResponse = await import_transport.apiRequest.call(
245
+ this,
246
+ "GET",
247
+ `/sessions/${sessionId}`
248
+ );
249
+ sessionStatus = sessionStatusResponse.data.status;
250
+ }
251
+ return { sessionId };
252
+ }
183
253
  async function createSessionAndWindow(index) {
184
254
  const node = this.getNode();
185
- const noCodeEndpoint = `${import_constants.INTEGRATION_URL}/create-session`;
186
255
  const profileName = validateProfileName.call(this, index);
187
256
  const url = validateRequiredStringField.call(this, index, "url", "URL");
188
- const { sessionId } = await import_transport.apiRequest.call(this, "POST", noCodeEndpoint, {
257
+ const { sessionId } = await createSession.call(this, {
189
258
  configuration: {
190
259
  profileName
191
260
  }
@@ -213,14 +282,17 @@ async function createSessionAndWindow(index) {
213
282
  // Annotate the CommonJS export names for ESM import in node:
214
283
  0 && (module.exports = {
215
284
  convertScreenshotToBinary,
285
+ createSession,
216
286
  createSessionAndWindow,
217
287
  shouldCreateNewSession,
218
288
  validateAirtopApiResponse,
219
289
  validateProfileName,
220
- validateProxyUrl,
290
+ validateProxy,
221
291
  validateRequiredStringField,
222
292
  validateSaveProfileOnTermination,
223
293
  validateScreenResolution,
294
+ validateScrollByAmount,
295
+ validateScrollingMode,
224
296
  validateSessionAndWindowId,
225
297
  validateSessionId,
226
298
  validateTimeoutMinutes,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../nodes/Airtop/GenericFunctions.ts"],"sourcesContent":["import { NodeApiError, type IExecuteFunctions, type INode } from 'n8n-workflow';\nimport { NodeOperationError } from 'n8n-workflow';\n\nimport { SESSION_MODE } from './actions/common/fields';\nimport {\n\tERROR_MESSAGES,\n\tDEFAULT_TIMEOUT_MINUTES,\n\tMIN_TIMEOUT_MINUTES,\n\tMAX_TIMEOUT_MINUTES,\n\tINTEGRATION_URL,\n} from './constants';\nimport { apiRequest } from './transport';\nimport type { IAirtopResponse } from './transport/types';\n\n/**\n * Validate a required string field\n * @param this - The execution context\n * @param index - The index of the node\n * @param field - The field to validate\n * @param fieldName - The name of the field\n */\nexport function validateRequiredStringField(\n\tthis: IExecuteFunctions,\n\tindex: number,\n\tfield: string,\n\tfieldName: string,\n) {\n\tlet value = this.getNodeParameter(field, index) as string;\n\tvalue = (value || '').trim();\n\tconst errorMessage = ERROR_MESSAGES.REQUIRED_PARAMETER.replace('{{field}}', fieldName);\n\n\tif (!value) {\n\t\tthrow new NodeOperationError(this.getNode(), errorMessage, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn value;\n}\n\n/**\n * Validate the session ID parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated session ID\n */\nexport function validateSessionId(this: IExecuteFunctions, index: number) {\n\tlet sessionId = this.getNodeParameter('sessionId', index, '') as string;\n\tsessionId = (sessionId || '').trim();\n\n\tif (!sessionId) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SESSION_ID_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn sessionId;\n}\n\n/**\n * Validate the session ID and window ID parameters\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated session ID and window ID parameters\n */\nexport function validateSessionAndWindowId(this: IExecuteFunctions, index: number) {\n\tlet sessionId = this.getNodeParameter('sessionId', index, '') as string;\n\tlet windowId = this.getNodeParameter('windowId', index, '') as string;\n\tsessionId = (sessionId || '').trim();\n\twindowId = (windowId || '').trim();\n\n\tif (!sessionId) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SESSION_ID_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\tif (!windowId) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.WINDOW_ID_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn {\n\t\tsessionId,\n\t\twindowId,\n\t};\n}\n\n/**\n * Validate the profile name parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated profile name\n */\nexport function validateProfileName(this: IExecuteFunctions, index: number) {\n\tlet profileName = this.getNodeParameter('profileName', index) as string;\n\tprofileName = (profileName || '').trim();\n\n\tif (!profileName) {\n\t\treturn profileName;\n\t}\n\n\tif (!/^[a-zA-Z0-9-]+$/.test(profileName)) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.PROFILE_NAME_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn profileName;\n}\n\n/**\n * Validate the timeout minutes parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated timeout minutes\n */\nexport function validateTimeoutMinutes(this: IExecuteFunctions, index: number) {\n\tconst timeoutMinutes = this.getNodeParameter(\n\t\t'timeoutMinutes',\n\t\tindex,\n\t\tDEFAULT_TIMEOUT_MINUTES,\n\t) as number;\n\n\tif (timeoutMinutes < MIN_TIMEOUT_MINUTES || timeoutMinutes > MAX_TIMEOUT_MINUTES) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.TIMEOUT_MINUTES_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn timeoutMinutes;\n}\n\n/**\n * Validate the URL parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated URL\n */\nexport function validateUrl(this: IExecuteFunctions, index: number) {\n\tlet url = this.getNodeParameter('url', index) as string;\n\turl = (url || '').trim();\n\n\tif (!url) {\n\t\treturn '';\n\t}\n\n\tif (!url.startsWith('http')) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.URL_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn url;\n}\n\n/**\n * Validate the Proxy URL parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @param proxy - The value of the Proxy parameter\n * @returns The validated proxy URL\n */\nexport function validateProxyUrl(this: IExecuteFunctions, index: number, proxy: string) {\n\tlet proxyUrl = this.getNodeParameter('proxyUrl', index, '') as string;\n\tproxyUrl = (proxyUrl || '').trim();\n\n\t// only validate proxyUrl if proxy is custom\n\tif (proxy !== 'custom') {\n\t\treturn '';\n\t}\n\n\tif (!proxyUrl) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.PROXY_URL_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\tif (!proxyUrl.startsWith('http')) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.PROXY_URL_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn proxyUrl;\n}\n\n/**\n * Validate the screen resolution parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated screen resolution\n */\nexport function validateScreenResolution(this: IExecuteFunctions, index: number) {\n\tlet screenResolution = this.getNodeParameter('screenResolution', index, '') as string;\n\tscreenResolution = (screenResolution || '').trim().toLowerCase();\n\tconst regex = /^\\d{3,4}x\\d{3,4}$/; // Expected format: 1280x720\n\n\tif (!screenResolution) {\n\t\treturn '';\n\t}\n\n\tif (!regex.test(screenResolution)) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SCREEN_RESOLUTION_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn screenResolution;\n}\n\n/**\n * Validate the save profile on termination parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @param profileName - The profile name\n * @returns The validated save profile on termination\n */\nexport function validateSaveProfileOnTermination(\n\tthis: IExecuteFunctions,\n\tindex: number,\n\tprofileName: string,\n) {\n\tconst saveProfileOnTermination = this.getNodeParameter(\n\t\t'saveProfileOnTermination',\n\t\tindex,\n\t\tfalse,\n\t) as boolean;\n\n\tif (saveProfileOnTermination && !profileName) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.PROFILE_NAME_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn saveProfileOnTermination;\n}\n\n/**\n * Check if there is an error in the API response and throw NodeApiError\n * @param node - The node instance\n * @param response - The response from the API\n */\nexport function validateAirtopApiResponse(node: INode, response: IAirtopResponse) {\n\tif (response?.errors?.length) {\n\t\tconst errorMessage = response.errors.map((error) => error.message).join('\\n');\n\t\tthrow new NodeApiError(node, {\n\t\t\tmessage: errorMessage,\n\t\t});\n\t}\n}\n\n/**\n * Convert a screenshot from the API response to a binary buffer\n * @param screenshot - The screenshot from the API response\n * @returns The processed screenshot\n */\nexport function convertScreenshotToBinary(screenshot: { dataUrl: string }): Buffer {\n\tconst base64Data = screenshot.dataUrl.replace('data:image/jpeg;base64,', '');\n\tconst buffer = Buffer.from(base64Data, 'base64');\n\treturn buffer;\n}\n\n/**\n * Check if a new session should be created\n * @param this - The execution context\n * @param index - The index of the node\n * @returns True if a new session should be created, false otherwise\n */\nexport function shouldCreateNewSession(this: IExecuteFunctions, index: number) {\n\tconst sessionMode = this.getNodeParameter('sessionMode', index) as string;\n\treturn Boolean(sessionMode && sessionMode === SESSION_MODE.NEW);\n}\n\n/**\n * Create a new session and window\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The session ID and window ID\n */\nexport async function createSessionAndWindow(\n\tthis: IExecuteFunctions,\n\tindex: number,\n): Promise<{ sessionId: string; windowId: string }> {\n\tconst node = this.getNode();\n\tconst noCodeEndpoint = `${INTEGRATION_URL}/create-session`;\n\tconst profileName = validateProfileName.call(this, index);\n\tconst url = validateRequiredStringField.call(this, index, 'url', 'URL');\n\n\tconst { sessionId } = await apiRequest.call(this, 'POST', noCodeEndpoint, {\n\t\tconfiguration: {\n\t\t\tprofileName,\n\t\t},\n\t});\n\n\tif (!sessionId) {\n\t\tthrow new NodeApiError(node, {\n\t\t\tmessage: 'Failed to create session',\n\t\t\tcode: 500,\n\t\t});\n\t}\n\tthis.logger.info(`[${node.name}] Session successfully created.`);\n\n\tconst windowResponse = await apiRequest.call(this, 'POST', `/sessions/${sessionId}/windows`, {\n\t\turl,\n\t});\n\tconst windowId = windowResponse?.data?.windowId as string;\n\n\tif (!windowId) {\n\t\tthrow new NodeApiError(node, {\n\t\t\tmessage: 'Failed to create window',\n\t\t\tcode: 500,\n\t\t});\n\t}\n\tthis.logger.info(`[${node.name}] Window successfully created.`);\n\treturn { sessionId, windowId };\n}\n"],"mappings":"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","names":["import_n8n_workflow"]}
1
+ {"version":3,"sources":["../../../nodes/Airtop/GenericFunctions.ts"],"sourcesContent":["import { NodeApiError, type IExecuteFunctions, type INode, type IDataObject } from 'n8n-workflow';\nimport { NodeOperationError } from 'n8n-workflow';\n\nimport { SESSION_MODE } from './actions/common/fields';\nimport type { TScrollingMode } from './constants';\nimport {\n\tERROR_MESSAGES,\n\tDEFAULT_TIMEOUT_MINUTES,\n\tMIN_TIMEOUT_MINUTES,\n\tMAX_TIMEOUT_MINUTES,\n\tSESSION_STATUS,\n\tOPERATION_TIMEOUT,\n} from './constants';\nimport { apiRequest } from './transport';\nimport type { IAirtopResponse, IAirtopSessionResponse } from './transport/types';\n\n/**\n * Validate a required string field\n * @param this - The execution context\n * @param index - The index of the node\n * @param field - The field to validate\n * @param fieldName - The name of the field\n */\nexport function validateRequiredStringField(\n\tthis: IExecuteFunctions,\n\tindex: number,\n\tfield: string,\n\tfieldName: string,\n) {\n\tlet value = this.getNodeParameter(field, index, '') as string;\n\tvalue = (value || '').trim();\n\tconst errorMessage = ERROR_MESSAGES.REQUIRED_PARAMETER.replace('{{field}}', fieldName);\n\n\tif (!value) {\n\t\tthrow new NodeOperationError(this.getNode(), errorMessage, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn value;\n}\n\n/**\n * Validate the session ID parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated session ID\n */\nexport function validateSessionId(this: IExecuteFunctions, index: number) {\n\tlet sessionId = this.getNodeParameter('sessionId', index, '') as string;\n\tsessionId = (sessionId || '').trim();\n\n\tif (!sessionId) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SESSION_ID_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn sessionId;\n}\n\n/**\n * Validate the session ID and window ID parameters\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated session ID and window ID parameters\n */\nexport function validateSessionAndWindowId(this: IExecuteFunctions, index: number) {\n\tlet sessionId = this.getNodeParameter('sessionId', index, '') as string;\n\tlet windowId = this.getNodeParameter('windowId', index, '') as string;\n\tsessionId = (sessionId || '').trim();\n\twindowId = (windowId || '').trim();\n\n\tif (!sessionId) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SESSION_ID_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\tif (!windowId) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.WINDOW_ID_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn {\n\t\tsessionId,\n\t\twindowId,\n\t};\n}\n\n/**\n * Validate the profile name parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated profile name\n */\nexport function validateProfileName(this: IExecuteFunctions, index: number) {\n\tlet profileName = this.getNodeParameter('profileName', index) as string;\n\tprofileName = (profileName || '').trim();\n\n\tif (!profileName) {\n\t\treturn profileName;\n\t}\n\n\tif (!/^[a-zA-Z0-9-]+$/.test(profileName)) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.PROFILE_NAME_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn profileName;\n}\n\n/**\n * Validate the timeout minutes parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated timeout minutes\n */\nexport function validateTimeoutMinutes(this: IExecuteFunctions, index: number) {\n\tconst timeoutMinutes = this.getNodeParameter(\n\t\t'timeoutMinutes',\n\t\tindex,\n\t\tDEFAULT_TIMEOUT_MINUTES,\n\t) as number;\n\n\tif (timeoutMinutes < MIN_TIMEOUT_MINUTES || timeoutMinutes > MAX_TIMEOUT_MINUTES) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.TIMEOUT_MINUTES_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn timeoutMinutes;\n}\n\n/**\n * Validate the URL parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated URL\n */\nexport function validateUrl(this: IExecuteFunctions, index: number) {\n\tlet url = this.getNodeParameter('url', index) as string;\n\turl = (url || '').trim();\n\n\tif (!url) {\n\t\treturn '';\n\t}\n\n\tif (!url.startsWith('http')) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.URL_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn url;\n}\n\n/**\n * Validate the Proxy configuration\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated proxy configuration\n */\nexport function validateProxy(this: IExecuteFunctions, index: number) {\n\tconst proxyParam = this.getNodeParameter('proxy', index, '') as\n\t\t| 'none'\n\t\t| 'integrated'\n\t\t| 'proxyUrl';\n\tconst proxyConfig = this.getNodeParameter('proxyConfig', index, '') as {\n\t\tcountry: string;\n\t\tsticky: boolean;\n\t};\n\tconst isConfigEmpty = Object.keys(proxyConfig).length === 0;\n\n\tif (proxyParam === 'integrated') {\n\t\treturn {\n\t\t\tproxy: isConfigEmpty ? true : { ...proxyConfig },\n\t\t};\n\t}\n\n\t// handle custom proxy configuration\n\tif (proxyParam === 'proxyUrl') {\n\t\treturn {\n\t\t\tproxy: validateRequiredStringField.call(this, index, 'proxyUrl', 'Proxy URL'),\n\t\t};\n\t}\n\n\treturn {\n\t\tproxy: false,\n\t};\n}\n\n/**\n * Validate the scrollBy amount parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @param parameterName - The name of the parameter\n * @returns The validated scrollBy amount\n */\nexport function validateScrollByAmount(\n\tthis: IExecuteFunctions,\n\tindex: number,\n\tparameterName: string,\n) {\n\tconst regex = /^(?:-?\\d{1,3}(?:%|px))$/;\n\tconst scrollBy = this.getNodeParameter(parameterName, index, {}) as {\n\t\txAxis?: string;\n\t\tyAxis?: string;\n\t};\n\n\tif (!scrollBy?.xAxis && !scrollBy?.yAxis) {\n\t\treturn {};\n\t}\n\n\tconst allAxisValid = [scrollBy.xAxis, scrollBy.yAxis]\n\t\t.filter(Boolean)\n\t\t.every((axis) => regex.test(axis ?? ''));\n\n\tif (!allAxisValid) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SCROLL_BY_AMOUNT_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn scrollBy;\n}\n\n/**\n * Validate the scroll mode parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns Scroll mode\n * @throws Error if the scroll mode or scroll parameters are invalid\n */\nexport function validateScrollingMode(this: IExecuteFunctions, index: number): TScrollingMode {\n\tconst scrollingMode = this.getNodeParameter(\n\t\t'scrollingMode',\n\t\tindex,\n\t\t'automatic',\n\t) as TScrollingMode;\n\n\tconst scrollToEdge = this.getNodeParameter('scrollToEdge.edgeValues', index, {}) as {\n\t\txAxis?: string;\n\t\tyAxis?: string;\n\t};\n\tconst scrollBy = this.getNodeParameter('scrollBy.scrollValues', index, {}) as {\n\t\txAxis?: string;\n\t\tyAxis?: string;\n\t};\n\n\tif (scrollingMode !== 'manual') {\n\t\treturn scrollingMode;\n\t}\n\n\t// validate manual scroll parameters\n\tconst emptyScrollBy = !scrollBy.xAxis && !scrollBy.yAxis;\n\tconst emptyScrollToEdge = !scrollToEdge.xAxis && !scrollToEdge.yAxis;\n\n\tif (emptyScrollBy && emptyScrollToEdge) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SCROLL_MODE_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn scrollingMode;\n}\n\n/**\n * Validate the screen resolution parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The validated screen resolution\n */\nexport function validateScreenResolution(this: IExecuteFunctions, index: number) {\n\tlet screenResolution = this.getNodeParameter('screenResolution', index, '') as string;\n\tscreenResolution = (screenResolution || '').trim().toLowerCase();\n\tconst regex = /^\\d{3,4}x\\d{3,4}$/; // Expected format: 1280x720\n\n\tif (!screenResolution) {\n\t\treturn '';\n\t}\n\n\tif (!regex.test(screenResolution)) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.SCREEN_RESOLUTION_INVALID, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn screenResolution;\n}\n\n/**\n * Validate the save profile on termination parameter\n * @param this - The execution context\n * @param index - The index of the node\n * @param profileName - The profile name\n * @returns The validated save profile on termination\n */\nexport function validateSaveProfileOnTermination(\n\tthis: IExecuteFunctions,\n\tindex: number,\n\tprofileName: string,\n) {\n\tconst saveProfileOnTermination = this.getNodeParameter(\n\t\t'saveProfileOnTermination',\n\t\tindex,\n\t\tfalse,\n\t) as boolean;\n\n\tif (saveProfileOnTermination && !profileName) {\n\t\tthrow new NodeOperationError(this.getNode(), ERROR_MESSAGES.PROFILE_NAME_REQUIRED, {\n\t\t\titemIndex: index,\n\t\t});\n\t}\n\n\treturn saveProfileOnTermination;\n}\n\n/**\n * Check if there is an error in the API response and throw NodeApiError\n * @param node - The node instance\n * @param response - The response from the API\n */\nexport function validateAirtopApiResponse(node: INode, response: IAirtopResponse) {\n\tif (response?.errors?.length) {\n\t\tconst errorMessage = response.errors.map((error) => error.message).join('\\n');\n\t\tthrow new NodeApiError(node, {\n\t\t\tmessage: errorMessage,\n\t\t});\n\t}\n}\n\n/**\n * Convert a screenshot from the API response to a binary buffer\n * @param screenshot - The screenshot from the API response\n * @returns The processed screenshot\n */\nexport function convertScreenshotToBinary(screenshot: { dataUrl: string }): Buffer {\n\tconst base64Data = screenshot.dataUrl.replace('data:image/jpeg;base64,', '');\n\tconst buffer = Buffer.from(base64Data, 'base64');\n\treturn buffer;\n}\n\n/**\n * Check if a new session should be created\n * @param this - The execution context\n * @param index - The index of the node\n * @returns True if a new session should be created, false otherwise\n */\nexport function shouldCreateNewSession(this: IExecuteFunctions, index: number) {\n\tconst sessionMode = this.getNodeParameter('sessionMode', index) as string;\n\treturn Boolean(sessionMode && sessionMode === SESSION_MODE.NEW);\n}\n\n/**\n * Create a new session and wait until the session is ready\n * @param this - The execution context\n * @param parameters - The parameters for the session\n * @returns The session ID\n */\nexport async function createSession(\n\tthis: IExecuteFunctions,\n\tparameters: IDataObject,\n\ttimeout = OPERATION_TIMEOUT,\n): Promise<{ sessionId: string }> {\n\t// Request session creation\n\tconst response = (await apiRequest.call(\n\t\tthis,\n\t\t'POST',\n\t\t'/sessions',\n\t\tparameters,\n\t)) as IAirtopSessionResponse;\n\tconst sessionId = response?.data?.id;\n\n\tif (!sessionId) {\n\t\tthrow new NodeApiError(this.getNode(), {\n\t\t\tmessage: 'Failed to create session',\n\t\t\tcode: 500,\n\t\t});\n\t}\n\n\t// Poll until the session is ready or timeout is reached\n\tlet sessionStatus = response?.data?.status;\n\tconst startTime = Date.now();\n\n\twhile (sessionStatus !== SESSION_STATUS.RUNNING) {\n\t\tif (Date.now() - startTime > timeout) {\n\t\t\tthrow new NodeApiError(this.getNode(), {\n\t\t\t\tmessage: ERROR_MESSAGES.TIMEOUT_REACHED,\n\t\t\t\tcode: 500,\n\t\t\t});\n\t\t}\n\t\tawait new Promise((resolve) => setTimeout(resolve, 1000));\n\t\tconst sessionStatusResponse = (await apiRequest.call(\n\t\t\tthis,\n\t\t\t'GET',\n\t\t\t`/sessions/${sessionId}`,\n\t\t)) as IAirtopSessionResponse;\n\t\tsessionStatus = sessionStatusResponse.data.status;\n\t}\n\n\treturn { sessionId };\n}\n\n/**\n * Create a new session and window\n * @param this - The execution context\n * @param index - The index of the node\n * @returns The session ID and window ID\n */\nexport async function createSessionAndWindow(\n\tthis: IExecuteFunctions,\n\tindex: number,\n): Promise<{ sessionId: string; windowId: string }> {\n\tconst node = this.getNode();\n\tconst profileName = validateProfileName.call(this, index);\n\tconst url = validateRequiredStringField.call(this, index, 'url', 'URL');\n\n\tconst { sessionId } = await createSession.call(this, {\n\t\tconfiguration: {\n\t\t\tprofileName,\n\t\t},\n\t});\n\n\tif (!sessionId) {\n\t\tthrow new NodeApiError(node, {\n\t\t\tmessage: 'Failed to create session',\n\t\t\tcode: 500,\n\t\t});\n\t}\n\tthis.logger.info(`[${node.name}] Session successfully created.`);\n\n\tconst windowResponse = await apiRequest.call(this, 'POST', `/sessions/${sessionId}/windows`, {\n\t\turl,\n\t});\n\tconst windowId = windowResponse?.data?.windowId as string;\n\n\tif (!windowId) {\n\t\tthrow new NodeApiError(node, {\n\t\t\tmessage: 'Failed to create window',\n\t\t\tcode: 500,\n\t\t});\n\t}\n\tthis.logger.info(`[${node.name}] Window successfully created.`);\n\treturn { sessionId, windowId };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAmF;AACnF,IAAAA,uBAAmC;AAEnC,oBAA6B;AAE7B,uBAOO;AACP,uBAA2B;AAUpB,SAAS,4BAEf,OACA,OACA,WACC;AACD,MAAI,QAAQ,KAAK,iBAAiB,OAAO,OAAO,EAAE;AAClD,WAAS,SAAS,IAAI,KAAK;AAC3B,QAAM,eAAe,gCAAe,mBAAmB,QAAQ,aAAa,SAAS;AAErF,MAAI,CAAC,OAAO;AACX,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,cAAc;AAAA,MAC1D,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAQO,SAAS,kBAA2C,OAAe;AACzE,MAAI,YAAY,KAAK,iBAAiB,aAAa,OAAO,EAAE;AAC5D,eAAa,aAAa,IAAI,KAAK;AAEnC,MAAI,CAAC,WAAW;AACf,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,qBAAqB;AAAA,MAChF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAQO,SAAS,2BAAoD,OAAe;AAClF,MAAI,YAAY,KAAK,iBAAiB,aAAa,OAAO,EAAE;AAC5D,MAAI,WAAW,KAAK,iBAAiB,YAAY,OAAO,EAAE;AAC1D,eAAa,aAAa,IAAI,KAAK;AACnC,cAAY,YAAY,IAAI,KAAK;AAEjC,MAAI,CAAC,WAAW;AACf,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,qBAAqB;AAAA,MAChF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,MAAI,CAAC,UAAU;AACd,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,oBAAoB;AAAA,MAC/E,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AAAA,IACN;AAAA,IACA;AAAA,EACD;AACD;AAQO,SAAS,oBAA6C,OAAe;AAC3E,MAAI,cAAc,KAAK,iBAAiB,eAAe,KAAK;AAC5D,iBAAe,eAAe,IAAI,KAAK;AAEvC,MAAI,CAAC,aAAa;AACjB,WAAO;AAAA,EACR;AAEA,MAAI,CAAC,kBAAkB,KAAK,WAAW,GAAG;AACzC,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,sBAAsB;AAAA,MACjF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAQO,SAAS,uBAAgD,OAAe;AAC9E,QAAM,iBAAiB,KAAK;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAEA,MAAI,iBAAiB,wCAAuB,iBAAiB,sCAAqB;AACjF,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,yBAAyB;AAAA,MACpF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAQO,SAAS,YAAqC,OAAe;AACnE,MAAI,MAAM,KAAK,iBAAiB,OAAO,KAAK;AAC5C,SAAO,OAAO,IAAI,KAAK;AAEvB,MAAI,CAAC,KAAK;AACT,WAAO;AAAA,EACR;AAEA,MAAI,CAAC,IAAI,WAAW,MAAM,GAAG;AAC5B,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,aAAa;AAAA,MACxE,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAQO,SAAS,cAAuC,OAAe;AACrE,QAAM,aAAa,KAAK,iBAAiB,SAAS,OAAO,EAAE;AAI3D,QAAM,cAAc,KAAK,iBAAiB,eAAe,OAAO,EAAE;AAIlE,QAAM,gBAAgB,OAAO,KAAK,WAAW,EAAE,WAAW;AAE1D,MAAI,eAAe,cAAc;AAChC,WAAO;AAAA,MACN,OAAO,gBAAgB,OAAO,EAAE,GAAG,YAAY;AAAA,IAChD;AAAA,EACD;AAGA,MAAI,eAAe,YAAY;AAC9B,WAAO;AAAA,MACN,OAAO,4BAA4B,KAAK,MAAM,OAAO,YAAY,WAAW;AAAA,IAC7E;AAAA,EACD;AAEA,SAAO;AAAA,IACN,OAAO;AAAA,EACR;AACD;AASO,SAAS,uBAEf,OACA,eACC;AACD,QAAM,QAAQ;AACd,QAAM,WAAW,KAAK,iBAAiB,eAAe,OAAO,CAAC,CAAC;AAK/D,MAAI,CAAC,UAAU,SAAS,CAAC,UAAU,OAAO;AACzC,WAAO,CAAC;AAAA,EACT;AAEA,QAAM,eAAe,CAAC,SAAS,OAAO,SAAS,KAAK,EAClD,OAAO,OAAO,EACd,MAAM,CAAC,SAAS,MAAM,KAAK,QAAQ,EAAE,CAAC;AAExC,MAAI,CAAC,cAAc;AAClB,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,0BAA0B;AAAA,MACrF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AASO,SAAS,sBAA+C,OAA+B;AAC7F,QAAM,gBAAgB,KAAK;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAEA,QAAM,eAAe,KAAK,iBAAiB,2BAA2B,OAAO,CAAC,CAAC;AAI/E,QAAM,WAAW,KAAK,iBAAiB,yBAAyB,OAAO,CAAC,CAAC;AAKzE,MAAI,kBAAkB,UAAU;AAC/B,WAAO;AAAA,EACR;AAGA,QAAM,gBAAgB,CAAC,SAAS,SAAS,CAAC,SAAS;AACnD,QAAM,oBAAoB,CAAC,aAAa,SAAS,CAAC,aAAa;AAE/D,MAAI,iBAAiB,mBAAmB;AACvC,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,qBAAqB;AAAA,MAChF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAQO,SAAS,yBAAkD,OAAe;AAChF,MAAI,mBAAmB,KAAK,iBAAiB,oBAAoB,OAAO,EAAE;AAC1E,sBAAoB,oBAAoB,IAAI,KAAK,EAAE,YAAY;AAC/D,QAAM,QAAQ;AAEd,MAAI,CAAC,kBAAkB;AACtB,WAAO;AAAA,EACR;AAEA,MAAI,CAAC,MAAM,KAAK,gBAAgB,GAAG;AAClC,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,2BAA2B;AAAA,MACtF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AASO,SAAS,iCAEf,OACA,aACC;AACD,QAAM,2BAA2B,KAAK;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAEA,MAAI,4BAA4B,CAAC,aAAa;AAC7C,UAAM,IAAI,wCAAmB,KAAK,QAAQ,GAAG,gCAAe,uBAAuB;AAAA,MAClF,WAAW;AAAA,IACZ,CAAC;AAAA,EACF;AAEA,SAAO;AACR;AAOO,SAAS,0BAA0B,MAAa,UAA2B;AACjF,MAAI,UAAU,QAAQ,QAAQ;AAC7B,UAAM,eAAe,SAAS,OAAO,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE,KAAK,IAAI;AAC5E,UAAM,IAAI,iCAAa,MAAM;AAAA,MAC5B,SAAS;AAAA,IACV,CAAC;AAAA,EACF;AACD;AAOO,SAAS,0BAA0B,YAAyC;AAClF,QAAM,aAAa,WAAW,QAAQ,QAAQ,2BAA2B,EAAE;AAC3E,QAAM,SAAS,OAAO,KAAK,YAAY,QAAQ;AAC/C,SAAO;AACR;AAQO,SAAS,uBAAgD,OAAe;AAC9E,QAAM,cAAc,KAAK,iBAAiB,eAAe,KAAK;AAC9D,SAAO,QAAQ,eAAe,gBAAgB,2BAAa,GAAG;AAC/D;AAQA,eAAsB,cAErB,YACA,UAAU,oCACuB;AAEjC,QAAM,WAAY,MAAM,4BAAW;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACD;AACA,QAAM,YAAY,UAAU,MAAM;AAElC,MAAI,CAAC,WAAW;AACf,UAAM,IAAI,iCAAa,KAAK,QAAQ,GAAG;AAAA,MACtC,SAAS;AAAA,MACT,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AAGA,MAAI,gBAAgB,UAAU,MAAM;AACpC,QAAM,YAAY,KAAK,IAAI;AAE3B,SAAO,kBAAkB,gCAAe,SAAS;AAChD,QAAI,KAAK,IAAI,IAAI,YAAY,SAAS;AACrC,YAAM,IAAI,iCAAa,KAAK,QAAQ,GAAG;AAAA,QACtC,SAAS,gCAAe;AAAA,QACxB,MAAM;AAAA,MACP,CAAC;AAAA,IACF;AACA,UAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAI,CAAC;AACxD,UAAM,wBAAyB,MAAM,4BAAW;AAAA,MAC/C;AAAA,MACA;AAAA,MACA,aAAa,SAAS;AAAA,IACvB;AACA,oBAAgB,sBAAsB,KAAK;AAAA,EAC5C;AAEA,SAAO,EAAE,UAAU;AACpB;AAQA,eAAsB,uBAErB,OACmD;AACnD,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAM,cAAc,oBAAoB,KAAK,MAAM,KAAK;AACxD,QAAM,MAAM,4BAA4B,KAAK,MAAM,OAAO,OAAO,KAAK;AAEtE,QAAM,EAAE,UAAU,IAAI,MAAM,cAAc,KAAK,MAAM;AAAA,IACpD,eAAe;AAAA,MACd;AAAA,IACD;AAAA,EACD,CAAC;AAED,MAAI,CAAC,WAAW;AACf,UAAM,IAAI,iCAAa,MAAM;AAAA,MAC5B,SAAS;AAAA,MACT,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AACA,OAAK,OAAO,KAAK,IAAI,KAAK,IAAI,iCAAiC;AAE/D,QAAM,iBAAiB,MAAM,4BAAW,KAAK,MAAM,QAAQ,aAAa,SAAS,YAAY;AAAA,IAC5F;AAAA,EACD,CAAC;AACD,QAAM,WAAW,gBAAgB,MAAM;AAEvC,MAAI,CAAC,UAAU;AACd,UAAM,IAAI,iCAAa,MAAM;AAAA,MAC5B,SAAS;AAAA,MACT,MAAM;AAAA,IACP,CAAC;AAAA,EACF;AACA,OAAK,OAAO,KAAK,IAAI,KAAK,IAAI,gCAAgC;AAC9D,SAAO,EAAE,WAAW,SAAS;AAC9B;","names":["import_n8n_workflow"]}
@@ -22,6 +22,7 @@ __export(fields_exports, {
22
22
  elementDescriptionField: () => elementDescriptionField,
23
23
  getSessionModeFields: () => getSessionModeFields,
24
24
  outputSchemaField: () => outputSchemaField,
25
+ parseJsonOutputField: () => parseJsonOutputField,
25
26
  profileNameField: () => profileNameField,
26
27
  sessionIdField: () => sessionIdField,
27
28
  urlField: () => urlField,
@@ -73,6 +74,13 @@ const outputSchemaField = {
73
74
  type: "json",
74
75
  default: ""
75
76
  };
77
+ const parseJsonOutputField = {
78
+ displayName: "Parse JSON Output",
79
+ name: "parseJsonOutput",
80
+ type: "boolean",
81
+ default: true,
82
+ description: "Whether to parse the model's response to JSON in the output. Requires the 'JSON Output Schema' parameter to be set."
83
+ };
76
84
  const elementDescriptionField = {
77
85
  displayName: "Element Description",
78
86
  name: "elementDescription",
@@ -166,6 +174,7 @@ function getSessionModeFields(resource, operations) {
166
174
  elementDescriptionField,
167
175
  getSessionModeFields,
168
176
  outputSchemaField,
177
+ parseJsonOutputField,
169
178
  profileNameField,
170
179
  sessionIdField,
171
180
  urlField,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../nodes/Airtop/actions/common/fields.ts"],"sourcesContent":["import type { INodeProperties } from 'n8n-workflow';\n\nexport const SESSION_MODE = {\n\tNEW: 'new',\n\tEXISTING: 'existing',\n} as const;\n\n/**\n * Session related fields\n */\n\nexport const sessionIdField: INodeProperties = {\n\tdisplayName: 'Session ID',\n\tname: 'sessionId',\n\ttype: 'string',\n\trequired: true,\n\tdefault: '={{ $json[\"sessionId\"] }}',\n\tdescription:\n\t\t'The ID of the <a href=\"https://docs.airtop.ai/guides/how-to/creating-a-session\" target=\"_blank\">Session</a> to use',\n};\n\nexport const windowIdField: INodeProperties = {\n\tdisplayName: 'Window ID',\n\tname: 'windowId',\n\ttype: 'string',\n\trequired: true,\n\tdefault: '={{ $json[\"windowId\"] }}',\n\tdescription:\n\t\t'The ID of the <a href=\"https://docs.airtop.ai/guides/how-to/creating-a-session#windows\" target=\"_blank\">Window</a> to use',\n};\n\nexport const profileNameField: INodeProperties = {\n\tdisplayName: 'Profile Name',\n\tname: 'profileName',\n\ttype: 'string',\n\tdefault: '',\n\tdescription: 'The name of the Airtop profile to load or create',\n\thint: '<a href=\"https://docs.airtop.ai/guides/how-to/saving-a-profile\" target=\"_blank\">Learn more</a> about Airtop profiles',\n\tplaceholder: 'e.g. my-x-profile',\n};\n\nexport const urlField: INodeProperties = {\n\tdisplayName: 'URL',\n\tname: 'url',\n\ttype: 'string',\n\tdefault: '',\n\tplaceholder: 'e.g. https://google.com',\n\tdescription: 'URL to load in the window',\n};\n\n/**\n * Extraction related fields\n */\n\nexport const outputSchemaField: INodeProperties = {\n\tdisplayName: 'JSON Output Schema',\n\tname: 'outputSchema',\n\tdescription: 'JSON schema defining the structure of the output',\n\thint: 'If you want to force your output to be JSON, provide a valid JSON schema describing the output. You can generate one automatically in the <a href=\"https://portal.airtop.ai/\" target=\"_blank\">Airtop API Playground</a>.',\n\ttype: 'json',\n\tdefault: '',\n};\n\n/**\n * Interaction related fields\n */\n\nexport const elementDescriptionField: INodeProperties = {\n\tdisplayName: 'Element Description',\n\tname: 'elementDescription',\n\ttype: 'string',\n\tdefault: '',\n\tdescription: 'A specific description of the element to execute the interaction on',\n\tplaceholder: 'e.g. the search box at the top of the page',\n};\n\nexport function getSessionModeFields(resource: string, operations: string[]): INodeProperties[] {\n\treturn [\n\t\t{\n\t\t\tdisplayName: 'Session Mode',\n\t\t\tname: 'sessionMode',\n\t\t\ttype: 'options',\n\t\t\tdefault: 'existing',\n\t\t\tdescription: 'Choose between creating a new session or using an existing one',\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Automatically Create Session',\n\t\t\t\t\tdescription: 'Automatically create a new session and window for this operation',\n\t\t\t\t\tvalue: SESSION_MODE.NEW,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Use Existing Session',\n\t\t\t\t\tdescription: 'Use an existing session and window for this operation',\n\t\t\t\t\tvalue: SESSION_MODE.EXISTING,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\toperation: operations,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...sessionIdField,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.EXISTING],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...windowIdField,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.EXISTING],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...urlField,\n\t\t\trequired: true,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.NEW],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...profileNameField,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.NEW],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Auto-Terminate Session',\n\t\t\tname: 'autoTerminateSession',\n\t\t\ttype: 'boolean',\n\t\t\tdefault: true,\n\t\t\tdescription:\n\t\t\t\t'Whether to terminate the session after the operation is complete. When disabled, you must manually terminate the session. By default, idle sessions timeout after 10 minutes',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.NEW],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t];\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../../nodes/Airtop/actions/common/fields.ts"],"sourcesContent":["import type { INodeProperties } from 'n8n-workflow';\n\nexport const SESSION_MODE = {\n\tNEW: 'new',\n\tEXISTING: 'existing',\n} as const;\n\n/**\n * Session related fields\n */\n\nexport const sessionIdField: INodeProperties = {\n\tdisplayName: 'Session ID',\n\tname: 'sessionId',\n\ttype: 'string',\n\trequired: true,\n\tdefault: '={{ $json[\"sessionId\"] }}',\n\tdescription:\n\t\t'The ID of the <a href=\"https://docs.airtop.ai/guides/how-to/creating-a-session\" target=\"_blank\">Session</a> to use',\n};\n\nexport const windowIdField: INodeProperties = {\n\tdisplayName: 'Window ID',\n\tname: 'windowId',\n\ttype: 'string',\n\trequired: true,\n\tdefault: '={{ $json[\"windowId\"] }}',\n\tdescription:\n\t\t'The ID of the <a href=\"https://docs.airtop.ai/guides/how-to/creating-a-session#windows\" target=\"_blank\">Window</a> to use',\n};\n\nexport const profileNameField: INodeProperties = {\n\tdisplayName: 'Profile Name',\n\tname: 'profileName',\n\ttype: 'string',\n\tdefault: '',\n\tdescription: 'The name of the Airtop profile to load or create',\n\thint: '<a href=\"https://docs.airtop.ai/guides/how-to/saving-a-profile\" target=\"_blank\">Learn more</a> about Airtop profiles',\n\tplaceholder: 'e.g. my-x-profile',\n};\n\nexport const urlField: INodeProperties = {\n\tdisplayName: 'URL',\n\tname: 'url',\n\ttype: 'string',\n\tdefault: '',\n\tplaceholder: 'e.g. https://google.com',\n\tdescription: 'URL to load in the window',\n};\n\n/**\n * Extraction related fields\n */\n\nexport const outputSchemaField: INodeProperties = {\n\tdisplayName: 'JSON Output Schema',\n\tname: 'outputSchema',\n\tdescription: 'JSON schema defining the structure of the output',\n\thint: 'If you want to force your output to be JSON, provide a valid JSON schema describing the output. You can generate one automatically in the <a href=\"https://portal.airtop.ai/\" target=\"_blank\">Airtop API Playground</a>.',\n\ttype: 'json',\n\tdefault: '',\n};\n\nexport const parseJsonOutputField: INodeProperties = {\n\tdisplayName: 'Parse JSON Output',\n\tname: 'parseJsonOutput',\n\ttype: 'boolean',\n\tdefault: true,\n\tdescription:\n\t\t\"Whether to parse the model's response to JSON in the output. Requires the 'JSON Output Schema' parameter to be set.\",\n};\n\n/**\n * Interaction related fields\n */\n\nexport const elementDescriptionField: INodeProperties = {\n\tdisplayName: 'Element Description',\n\tname: 'elementDescription',\n\ttype: 'string',\n\tdefault: '',\n\tdescription: 'A specific description of the element to execute the interaction on',\n\tplaceholder: 'e.g. the search box at the top of the page',\n};\n\nexport function getSessionModeFields(resource: string, operations: string[]): INodeProperties[] {\n\treturn [\n\t\t{\n\t\t\tdisplayName: 'Session Mode',\n\t\t\tname: 'sessionMode',\n\t\t\ttype: 'options',\n\t\t\tdefault: 'existing',\n\t\t\tdescription: 'Choose between creating a new session or using an existing one',\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Automatically Create Session',\n\t\t\t\t\tdescription: 'Automatically create a new session and window for this operation',\n\t\t\t\t\tvalue: SESSION_MODE.NEW,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Use Existing Session',\n\t\t\t\t\tdescription: 'Use an existing session and window for this operation',\n\t\t\t\t\tvalue: SESSION_MODE.EXISTING,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\toperation: operations,\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...sessionIdField,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.EXISTING],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...windowIdField,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.EXISTING],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...urlField,\n\t\t\trequired: true,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.NEW],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\t...profileNameField,\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.NEW],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Auto-Terminate Session',\n\t\t\tname: 'autoTerminateSession',\n\t\t\ttype: 'boolean',\n\t\t\tdefault: true,\n\t\t\tdescription:\n\t\t\t\t'Whether to terminate the session after the operation is complete. When disabled, you must manually terminate the session. By default, idle sessions timeout after 10 minutes',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresource: [resource],\n\t\t\t\t\tsessionMode: [SESSION_MODE.NEW],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t];\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var output_utils_exports = {};
20
+ __export(output_utils_exports, {
21
+ cleanOutputForToolUse: () => cleanOutputForToolUse,
22
+ parseJsonIfPresent: () => parseJsonIfPresent
23
+ });
24
+ module.exports = __toCommonJS(output_utils_exports);
25
+ var import_n8n_workflow = require("n8n-workflow");
26
+ function parseJsonIfPresent(index, response) {
27
+ const parseJsonOutput = this.getNodeParameter("additionalFields.parseJsonOutput", index, false);
28
+ const outputJsonSchema = this.getNodeParameter(
29
+ "additionalFields.outputSchema",
30
+ index,
31
+ ""
32
+ );
33
+ if (!parseJsonOutput || !outputJsonSchema.startsWith("{")) {
34
+ return response;
35
+ }
36
+ try {
37
+ const output = JSON.parse(response.data?.modelResponse ?? "");
38
+ return {
39
+ sessionId: response.sessionId,
40
+ windowId: response.windowId,
41
+ output
42
+ };
43
+ } catch (error) {
44
+ throw new import_n8n_workflow.NodeOperationError(this.getNode(), "Output is not a valid JSON");
45
+ }
46
+ }
47
+ function cleanOutputForToolUse(output) {
48
+ const getOutput = (executionData) => {
49
+ if (executionData.json?.errors?.length) {
50
+ const errorMessage = executionData.json?.errors[0].message;
51
+ return {
52
+ output: `Error: ${errorMessage}`
53
+ };
54
+ }
55
+ if (executionData.json?.output) {
56
+ return executionData.json?.output;
57
+ }
58
+ if (executionData.json?.data?.modelResponse) {
59
+ return {
60
+ output: executionData.json?.data?.modelResponse
61
+ };
62
+ }
63
+ return {
64
+ output: { ...executionData.json?.data ?? {} }
65
+ };
66
+ };
67
+ return output.map((executionData) => ({
68
+ ...executionData,
69
+ json: {
70
+ ...getOutput(executionData)
71
+ }
72
+ }));
73
+ }
74
+ // Annotate the CommonJS export names for ESM import in node:
75
+ 0 && (module.exports = {
76
+ cleanOutputForToolUse,
77
+ parseJsonIfPresent
78
+ });
79
+ //# sourceMappingURL=output.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../nodes/Airtop/actions/common/output.utils.ts"],"sourcesContent":["import { NodeOperationError } from 'n8n-workflow';\nimport type { IExecuteFunctions, IDataObject } from 'n8n-workflow';\n\nimport type { IAirtopNodeExecutionData, IAirtopResponse } from '../../transport/types';\n\n/**\n * Parse JSON when the 'Parse JSON Output' parameter is enabled\n * @param this - The execution context\n * @param index - The index of the node\n * @param response - The Airtop API response to parse\n * @returns The parsed output\n */\nexport function parseJsonIfPresent(\n\tthis: IExecuteFunctions,\n\tindex: number,\n\tresponse: IAirtopResponse,\n): IAirtopResponse {\n\tconst parseJsonOutput = this.getNodeParameter('additionalFields.parseJsonOutput', index, false);\n\tconst outputJsonSchema = this.getNodeParameter(\n\t\t'additionalFields.outputSchema',\n\t\tindex,\n\t\t'',\n\t) as string;\n\n\tif (!parseJsonOutput || !outputJsonSchema.startsWith('{')) {\n\t\treturn response;\n\t}\n\n\ttry {\n\t\tconst output = JSON.parse(response.data?.modelResponse ?? '') as IDataObject;\n\t\treturn {\n\t\t\tsessionId: response.sessionId,\n\t\t\twindowId: response.windowId,\n\t\t\toutput,\n\t\t};\n\t} catch (error) {\n\t\tthrow new NodeOperationError(this.getNode(), 'Output is not a valid JSON');\n\t}\n}\n\n/**\n * Clean up the output when used as a tool\n * @param output - The output to clean up\n * @returns The cleaned up output\n */\nexport function cleanOutputForToolUse(output: IAirtopNodeExecutionData[]) {\n\tconst getOutput = (executionData: IAirtopNodeExecutionData) => {\n\t\t// Return error message\n\t\tif (executionData.json?.errors?.length) {\n\t\t\tconst errorMessage = executionData.json?.errors[0].message as string;\n\t\t\treturn {\n\t\t\t\toutput: `Error: ${errorMessage}`,\n\t\t\t};\n\t\t}\n\n\t\t// Return output parsed from JSON\n\t\tif (executionData.json?.output) {\n\t\t\treturn executionData.json?.output;\n\t\t}\n\n\t\t// Return model response\n\t\tif (executionData.json?.data?.modelResponse) {\n\t\t\treturn {\n\t\t\t\toutput: executionData.json?.data?.modelResponse,\n\t\t\t};\n\t\t}\n\n\t\t// Return everything else\n\t\treturn {\n\t\t\toutput: { ...(executionData.json?.data ?? {}) },\n\t\t};\n\t};\n\n\treturn output.map((executionData) => ({\n\t\t...executionData,\n\t\tjson: {\n\t\t\t...getOutput(executionData),\n\t\t},\n\t}));\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAmC;AAY5B,SAAS,mBAEf,OACA,UACkB;AAClB,QAAM,kBAAkB,KAAK,iBAAiB,oCAAoC,OAAO,KAAK;AAC9F,QAAM,mBAAmB,KAAK;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,EACD;AAEA,MAAI,CAAC,mBAAmB,CAAC,iBAAiB,WAAW,GAAG,GAAG;AAC1D,WAAO;AAAA,EACR;AAEA,MAAI;AACH,UAAM,SAAS,KAAK,MAAM,SAAS,MAAM,iBAAiB,EAAE;AAC5D,WAAO;AAAA,MACN,WAAW,SAAS;AAAA,MACpB,UAAU,SAAS;AAAA,MACnB;AAAA,IACD;AAAA,EACD,SAAS,OAAO;AACf,UAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,4BAA4B;AAAA,EAC1E;AACD;AAOO,SAAS,sBAAsB,QAAoC;AACzE,QAAM,YAAY,CAAC,kBAA4C;AAE9D,QAAI,cAAc,MAAM,QAAQ,QAAQ;AACvC,YAAM,eAAe,cAAc,MAAM,OAAO,CAAC,EAAE;AACnD,aAAO;AAAA,QACN,QAAQ,UAAU,YAAY;AAAA,MAC/B;AAAA,IACD;AAGA,QAAI,cAAc,MAAM,QAAQ;AAC/B,aAAO,cAAc,MAAM;AAAA,IAC5B;AAGA,QAAI,cAAc,MAAM,MAAM,eAAe;AAC5C,aAAO;AAAA,QACN,QAAQ,cAAc,MAAM,MAAM;AAAA,MACnC;AAAA,IACD;AAGA,WAAO;AAAA,MACN,QAAQ,EAAE,GAAI,cAAc,MAAM,QAAQ,CAAC,EAAG;AAAA,IAC/C;AAAA,EACD;AAEA,SAAO,OAAO,IAAI,CAAC,mBAAmB;AAAA,IACrC,GAAG;AAAA,IACH,MAAM;AAAA,MACL,GAAG,UAAU,aAAa;AAAA,IAC3B;AAAA,EACD,EAAE;AACH;","names":[]}