Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 75 additions & 54 deletions components/apify/actions/run-actor/run-actor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 = {
Expand All @@ -200,15 +222,14 @@ export default {
prepareData,
apify,
actorId,
buildId,
buildTag,
properties,
runAsynchronously,
outputRecordKey,
timeout,
memory,
maxItems,
maxTotalChargeUsd,
waitForFinish,
webhook,
eventTypes,
...data
Expand All @@ -229,7 +250,7 @@ export default {
memory,
maxItems,
maxTotalChargeUsd,
waitForFinish,
build: buildTag,
webhooks: webhook
? btoa(JSON.stringify([
{
Expand Down
87 changes: 42 additions & 45 deletions components/apify/apify.app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}));
},
},
Expand All @@ -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,
}));
},
},
Expand All @@ -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: {
Expand Down Expand Up @@ -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 = {}) {
Expand All @@ -224,7 +213,7 @@ export default {
},
listUserActors(opts = {}) {
return this._makeRequest({
path: "/acts",
path: "/acts?desc=1&sortBy=stats.lastRunStartedAt",
...opts,
});
},
Expand Down Expand Up @@ -276,5 +265,13 @@ export default {
...opts,
});
},
formatActorOrTaskLabel({
title, username, name,
}) {
if (title) {
return `${title} (${username}/${name})`;
}
return `${username}/${name}`;
},
},
};
4 changes: 2 additions & 2 deletions components/apify/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@pipedream/apify",
"version": "0.2.2",
"version": "0.2.3",
"description": "Pipedream Apify Components",
"main": "apify.app.mjs",
"keywords": [
Expand All @@ -14,6 +14,6 @@
},
"dependencies": {
"@apify/consts": "^2.41.0",
"@pipedream/platform": "^3.0.3"
"@pipedream/platform": "^3.1.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -15,7 +15,7 @@ export default {
actorId: {
propDefinition: [
common.props.apify,
"userActorId",
"actorId",
],
},
},
Expand Down
5 changes: 1 addition & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading