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
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import app from "../../data_stores.app.mjs";
import xss from "xss";

export default {
key: "data_stores-add-update-multiple-records",
name: "Add or update multiple records",
description: "Add or update multiple records to your [Pipedream Data Store](https://pipedream.com/data-stores/).",
version: "0.0.4",
version: "0.0.5",
type: "action",
props: {
app,
Expand Down Expand Up @@ -53,13 +52,7 @@ export default {
}
}

// Try to evaluate string as javascript, using xss as extra security
// If some problem occurs, return the original string
try {
return eval(`(${xss(value)})`);
} catch {
return value;
}
return this.app.evaluate(value);
},
/**
* Add all the key-value pairs in the map object to be used in the data store
Expand All @@ -68,8 +61,7 @@ export default {
*/
populateHashMapOfData(data, map) {
if (!Array.isArray(data) && typeof(data) === "object") {
Object.keys(data)
.forEach((key) => map[key] = this.convertString(data[key]));
Object.keys(data).forEach((key) => map[key] = this.convertString(data[key]));
return;
}

Expand All @@ -87,7 +79,7 @@ export default {
},
async run({ $ }) {
if (typeof this.data === "string") {
this.data = eval(`(${this.data})`);
this.data = this.app.evaluate(this.data);
}
const map = this.getHashMapOfData(this.data);
const keys = Object.keys(map);
Expand All @@ -96,7 +88,9 @@ export default {
if (keys.length === 0) {
$.export("$summary", "No data was added to the data store.");
} else {
$.export("$summary", `Successfully added or updated ${keys.length} record(s)`);
// eslint-disable-next-line multiline-ternary
$.export("$summary", `Successfully added or updated ${keys.length} record${keys.length === 1 ? "" : "s"}`);
}
return map;
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
key: "data_stores-add-update-record",
name: "Add or update a single record",
description: "Add or update a single record in your [Pipedream Data Store](https://pipedream.com/data-stores/).",
version: "0.0.7",
version: "0.0.8",
type: "action",
props: {
app,
Expand All @@ -25,24 +25,25 @@ export default {
description: "Enter a key for the record you'd like to create or select an existing key to update.",
},
value: {
label: "Value",
type: "any",
description: "Enter a string, object, or array.",
propDefinition: [
app,
"value",
],
},
},
async run({ $ }) {
const {
key,
value,
} = this;
const record = await this.dataStore.get(key);
const exists = await this.dataStore.has(key);
const parsedValue = this.app.parseValue(value);
await this.dataStore.set(key, parsedValue);
// eslint-disable-next-line multiline-ternary
$.export("$summary", `Successfully ${record ? "updated the record for" : "added a new record with the"} key, \`${key}\`.`);
$.export("$summary", `Successfully ${exists ? "updated the record for" : "added a new record with the"} key, \`${key}\`.`);
return {
key,
value,
value: parsedValue,
};
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
key: "data_stores-delete-single-record",
name: "Delete a single record",
description: "Delete a single record in your [Pipedream Data Store](https://pipedream.com/data-stores/).",
version: "0.0.6",
version: "0.0.7",
type: "action",
props: {
app,
Expand All @@ -30,9 +30,10 @@ export default {

if (record) {
await this.dataStore.delete(this.key);
$.export("$summary", "Successfully deleted the record for key, `" + this.key + "`.");
} else {
$.export("$summary", "No record found for key, `" + this.key + "`. No data was deleted.");
$.export("$summary", `Successfully deleted the record for key, \`${this.key}\`.`);
return record;
}

$.export("$summary", `No record found for key, \`${this.key}\`. No data was deleted.`);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
key: "data_stores-get-record-or-create",
name: "Get record (or create one if not found)",
description: "Get a single record in your [Pipedream Data Store](https://pipedream.com/data-stores/) or create one if it doesn't exist.",
version: "0.0.7",
version: "0.0.8",
type: "action",
props: {
app,
Expand Down Expand Up @@ -32,27 +32,28 @@ export default {
},
},
async additionalProps() {
const props = {};
if (this.app.shouldAddRecord(this.addRecordIfNotFound)) {
return this.app.valueProp();
props.value = app.propDefinitions.value;
}
return {};
return props;
},
async run({ $ }) {
const record = await this.dataStore.get(this.key);

if (record) {
$.export("$summary", "Found data for the key, `" + this.key + "`.");
} else {
if (this.app.shouldAddRecord(this.addRecordIfNotFound)) {
const parsedValue = this.app.parseValue(this.value);
await this.dataStore.set(this.key, parsedValue);
$.export("$summary", "Successfully added a new record with the key, `" + this.key + "`.");
return this.dataStore.get(this.key);
} else {
$.export("$summary", "No data found for key, `" + this.key + "`.");
}
$.export("$summary", `Found data for the key, \`${this.key}\`.`);
return record;
}

return record;
if (!this.app.shouldAddRecord(this.addRecordIfNotFound)) {
$.export("$summary", `No data found for key, \`${this.key}\`.`);
return;
}

const parsedValue = this.app.parseValue(this.value);
await this.dataStore.set(this.key, parsedValue);
$.export("$summary", `Successfully added a new record with the key, \`${this.key}\`.`);
return parsedValue;
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
key: "data_stores-has-key-or-create",
name: "Check for existence of key",
description: "Check if a key exists in your [Pipedream Data Store](https://pipedream.com/data-stores/) or create one if it doesn't exist.",
version: "0.0.3",
version: "0.0.4",
type: "action",
props: {
app,
Expand Down Expand Up @@ -32,25 +32,26 @@ export default {
},
},
async additionalProps() {
const props = {};
if (this.app.shouldAddRecord(this.addRecordIfNotFound)) {
return this.app.valueProp();
props.value = app.propDefinitions.value;
}
return {};
return props;
},
async run ({ $ }) {
if (await this.dataStore.has(this.key)) {
$.export("$summary", `Key "${this.key}" exists.`);
$.export("$summary", `Key \`${this.key}\` exists.`);
return true;
}

if (this.app.shouldAddRecord(this.addRecordIfNotFound)) {
const parsedValue = this.app.parseValue(this.value);
await this.dataStore.set(this.key, parsedValue);
$.export("$summary", `Key "${this.key}" was not found. Successfully added a new record.`);
return this.dataStore.get(this.key);
if (!this.app.shouldAddRecord(this.addRecordIfNotFound)) {
$.export("$summary", `Key \`${this.key}\` does not exist.`);
return false;
}

$.export("$summary", `Key "${this.key}" does not exist.`);
return false;
const parsedValue = this.app.parseValue(this.value);
await this.dataStore.set(this.key, parsedValue);
$.export("$summary", `Key \`${this.key}\` was not found. Successfully added a new record.`);
return parsedValue;
},
};
43 changes: 25 additions & 18 deletions components/data_stores/data_stores.app.mjs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
import xss from "xss";

/**
* Should support the following data types:
* https://pipedream.com/docs/data-stores/#supported-data-types
*/

export default {
type: "app",
app: "data_stores",
Expand All @@ -15,6 +22,11 @@ export default {
return dataStore.keys();
},
},
value: {
label: "Value",
type: "any",
description: "Enter a string, object, or array.",
},
addRecordIfNotFound: {
label: "Create a new record if the key is not found?",
description: "Create a new record if no records are found for the specified key.",
Expand All @@ -28,36 +40,31 @@ export default {
},
},
methods: {
// using Function approach instead of eval:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#never_use_eval!
evaluate(value) {
try {
return Function(`"use strict"; return (${xss(value)})`)();
} catch (err) {
return value;
}
},
parseJSON(value) {
return JSON.parse(JSON.stringify(this.evaluate(value)));
},
shouldAddRecord(option) {
return option === "Yes";
},
valueProp() {
return {
value: {
label: "Value",
type: "any",
description: "Enter a string, object, or array.",
},
};
},
parseValue(value) {
if (typeof value !== "string") {
return value;
}

try {
return JSON.parse(this.sanitizeJson(value));
return this.parseJSON(value);
} catch (err) {
return value;
}
},
//Because user might enter a JSON as JS object;
//This method converts a JS object string to a JSON string before parsing it
//e.g. {a:"b", 'c':1} => {"a":"b", "c":1}
//We don't use eval here because of security reasons.
//Using eval may cause something undesired run in the script.
sanitizeJson(str) {
return str.replace(/(['"])?([a-z0-9A-Z_]+)(['"])?:/g, "\"$2\": ");
},
},
};