diff --git a/components/apify/actions/run-actor/run-actor.mjs b/components/apify/actions/run-actor/run-actor.mjs index 84febb9e9b6a8..d34da2d29eb82 100644 --- a/components/apify/actions/run-actor/run-actor.mjs +++ b/components/apify/actions/run-actor/run-actor.mjs @@ -7,31 +7,53 @@ export default { key: "apify-run-actor", name: "Run Actor", description: "Performs an execution of a selected Actor in Apify. [See the documentation](https://docs.apify.com/api/v2#/reference/actors/run-collection/run-actor)", - version: "0.0.4", + version: "0.0.33", type: "action", props: { apify, + actorSource: { + type: "string", + label: "Search Actors from", + description: "Where to search for Actors. Valid options are Store and Recently used Actors.", + options: [ + { + label: "Apify Store Actors", + value: "store", + }, + { + label: "Recently used Actors", + value: "recently-used", + }, + ], + reloadProps: true, + default: "recently-used", + }, actorId: { propDefinition: [ apify, "actorId", + (c) => ({ + actorSource: c.actorSource, + }), ], }, - buildId: { + buildTag: { propDefinition: [ apify, - "buildId", + "buildTag", (c) => ({ actorId: c.actorId, }), ], reloadProps: true, + optional: true, }, runAsynchronously: { type: "boolean", label: "Run Asynchronously", description: "Set to `true` to run the Actor asynchronously", reloadProps: true, + default: true, }, timeout: { type: "string", @@ -76,19 +98,27 @@ export default { ? type : "string[]"; }, - async getSchema(buildId) { - const { data: { inputSchema } } = await this.apify.getBuild(buildId); + async getSchema(actorId, buildId) { + const { data: { inputSchema } } = await this.apify.getBuild(actorId, buildId); return JSON.parse(inputSchema); }, async prepareData(data) { const newData = {}; - const { properties } = await this.getSchema(this.buildId); + const { properties } = await this.getSchema(this.actorId, this.buildId); for (const [ key, value, ] of Object.entries(data)) { - const editor = properties[key].editor; + let editor; + + if (properties[key]) { + editor = properties[key].editor; + } else { + console.warn(`Property "${key}" is not defined in the schema`); + editor = "hidden"; // This will prevent it from showing up + } + newData[key] = (Array.isArray(value)) ? value.map((item) => this.setValue(editor, item)) : value; @@ -131,55 +161,47 @@ export default { }, async additionalProps() { const props = {}; - if (this.buildId) { - try { - const { - properties, required: requiredProps = [], - } = await this.getSchema(this.buildId); - for (const [ - key, - value, - ] of Object.entries(properties)) { - if (value.editor === "hidden") continue; + try { + const { + properties, required: requiredProps = [], + } = await this.getSchema(this.actorId, this.buildId); - props[key] = { - type: this.getType(value.type), - label: value.title, - description: value.description, - optional: !requiredProps.includes(key), - }; - const options = this.prepareOptions(value); - if (options) props[key].options = options; - if (value.default) { - props[key].description += ` Default: \`${JSON.stringify(value.default)}\``; - if (props[key].type !== "object") { // default values don't work properly for object props - props[key].default = value.default; - } + for (const [ + key, + value, + ] of Object.entries(properties)) { + if (value.editor === "hidden") continue; + + props[key] = { + type: this.getType(value.type), + label: value.title, + description: value.description, + optional: !requiredProps.includes(key), + }; + const options = this.prepareOptions(value); + if (options) props[key].options = options; + if (value.default) { + props[key].description += ` Default: \`${JSON.stringify(value.default)}\``; + if (props[key].type !== "object") { // default values don't work properly for object props + props[key].default = value.default; } } - } catch { - props.properties = { - type: "object", - label: "Properties", - description: "Properties to set for this Actor", - }; - } - if (this.runAsynchronously) { - props.outputRecordKey = { - type: "string", - label: "Output Record Key", - description: "Key of the record from run's default key-value store to be returned in the response. By default, it is OUTPUT.", - optional: true, - }; - } else { - props.waitForFinish = { - type: "string", - label: "Wait For Finish", - description: "The maximum number of seconds the server waits for the run to finish. By default, it is 0, the maximum value is 60. If the build finishes in time then the returned run object will have a terminal status (e.g. SUCCEEDED), otherwise it will have a transitional status (e.g. RUNNING).", - optional: true, - }; } + } catch { + props.properties = { + type: "object", + label: "Properties", + description: "Properties to set for this actor", + }; + } + if (this.runAsynchronously) { + props.outputRecordKey = { + type: "string", + label: "Output Record Key", + description: "Key of the record from run's default key-value store to be returned in the response. By default, it is OUTPUT.", + optional: true, + }; } if (this.webhook) { props.eventTypes = { @@ -200,7 +222,7 @@ export default { prepareData, apify, actorId, - buildId, + buildTag, properties, runAsynchronously, outputRecordKey, @@ -208,7 +230,6 @@ export default { memory, maxItems, maxTotalChargeUsd, - waitForFinish, webhook, eventTypes, ...data @@ -229,7 +250,7 @@ export default { memory, maxItems, maxTotalChargeUsd, - waitForFinish, + build: buildTag, webhooks: webhook ? btoa(JSON.stringify([ { diff --git a/components/apify/apify.app.mjs b/components/apify/apify.app.mjs index ad0fb25c9773d..f4639504ed200 100644 --- a/components/apify/apify.app.mjs +++ b/components/apify/apify.app.mjs @@ -30,39 +30,23 @@ export default { type: "string", label: "Actor ID", description: "Actor ID or a tilde-separated owner's username and Actor name", - async options({ page }) { - const { data: { items } } = await this.listActors({ + async options({ + page, actorSource, + }) { + actorSource ??= "recently-used"; + const listFn = actorSource === "store" + ? this.listActors + : this.listUserActors; + const { data: { items } } = await listFn({ params: { offset: LIMIT * page, limit: LIMIT, }, }); - return items.map(({ - id: value, name: label, - }) => ({ - label, - value, - })); - }, - }, - userActorId: { - type: "string", - label: "Actor ID", - description: "The ID of the Actor to monitor.", - async options({ page }) { - const { data: { items } } = await this.listUserActors({ - params: { - offset: LIMIT * page, - limit: LIMIT, - }, - }); - - return items.map(({ - id: value, name: label, - }) => ({ - label, - value, + return items.map((actor) => ({ + label: this.formatActorOrTaskLabel(actor), + value: actor.id, })); }, }, @@ -78,11 +62,9 @@ export default { }, }); - return items.map(({ - id: value, name: label, - }) => ({ - label, - value, + return items.map((task) => ({ + label: this.formatActorOrTaskLabel(task), + value: task.id, })); }, }, @@ -105,21 +87,17 @@ export default { })) || []; }, }, - buildId: { + buildTag: { type: "string", label: "Build", description: "Specifies the Actor build to run. It can be either a build tag or build number.", - async options({ - page, actorId, - }) { - const { data: { items } } = await this.listBuilds({ + async options({ actorId }) { + const { data: { taggedBuilds } } = await this.getActor({ actorId, - params: { - offset: LIMIT * page, - limit: LIMIT, - }, }); - return items?.map(({ id }) => id) || []; + return Object.entries(taggedBuilds).map(([ + name, + ]) => name); }, }, clean: { @@ -211,9 +189,20 @@ export default { path: `/actor-tasks/${taskId}/runs`, }); }, - getBuild(build) { + getActor({ actorId }) { + return this._makeRequest({ + path: `/acts/${actorId}`, + }); + }, + getBuild(actorId, buildId) { + if (buildId) { + return this._makeRequest({ + path: `/actor-builds/${buildId}`, + }); + } + return this._makeRequest({ - path: `/actor-builds/${build}`, + path: `/acts/${actorId}/builds/default`, }); }, listActors(opts = {}) { @@ -224,7 +213,7 @@ export default { }, listUserActors(opts = {}) { return this._makeRequest({ - path: "/acts", + path: "/acts?desc=1&sortBy=stats.lastRunStartedAt", ...opts, }); }, @@ -276,5 +265,13 @@ export default { ...opts, }); }, + formatActorOrTaskLabel({ + title, username, name, + }) { + if (title) { + return `${title} (${username}/${name})`; + } + return `${username}/${name}`; + }, }, }; diff --git a/components/apify/package.json b/components/apify/package.json index 6fa6e927daca3..6ee7c4ad5e8d3 100644 --- a/components/apify/package.json +++ b/components/apify/package.json @@ -1,6 +1,6 @@ { "name": "@pipedream/apify", - "version": "0.2.2", + "version": "0.2.3", "description": "Pipedream Apify Components", "main": "apify.app.mjs", "keywords": [ @@ -14,6 +14,6 @@ }, "dependencies": { "@apify/consts": "^2.41.0", - "@pipedream/platform": "^3.0.3" + "@pipedream/platform": "^3.1.0" } } diff --git a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs index 0dbf18cabe02e..14611eda57639 100644 --- a/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs +++ b/components/apify/sources/new-finished-actor-run-instant/new-finished-actor-run-instant.mjs @@ -6,7 +6,7 @@ export default { key: "apify-new-finished-actor-run-instant", name: "New Finished Actor Run (Instant)", description: "Emit new event when a selected Actor is run and finishes.", - version: "0.0.4", + version: "0.0.5", type: "source", dedupe: "unique", props: { @@ -15,7 +15,7 @@ export default { actorId: { propDefinition: [ common.props.apify, - "userActorId", + "actorId", ], }, }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d95be2f71e5a4..ea66ec975f858 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1078,10 +1078,7 @@ importers: version: 1.6.6 components/asters: - dependencies: - '@pipedream/platform': - specifier: ^3.1.0 - version: 3.1.0 + specifiers: {} components/astica_ai: dependencies: