Skip to content

Commit 1316268

Browse files
dannyrooseveltClaude
and
Claude
committed
Add TTL functionality to Data Store actions
- Added TTL prop to all Data Store actions to support record expiration - Created helper methods for human-readable TTL formatting - Added a new "Update record expiration" action for modifying TTL on existing records - Added preset TTL options for common time periods - Improved summaries and return values with TTL information 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent bfccd6c commit 1316268

File tree

7 files changed

+281
-17
lines changed

7 files changed

+281
-17
lines changed

components/data_stores/actions/add-update-multiple-records/add-update-multiple-records.mjs

+26-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default {
44
key: "data_stores-add-update-multiple-records",
55
name: "Add or update multiple records",
66
description: "Add or update multiple records to your [Pipedream Data Store](https://pipedream.com/data-stores/).",
7-
version: "0.0.6",
7+
version: "0.0.7",
88
type: "action",
99
props: {
1010
app,
@@ -19,6 +19,12 @@ export default {
1919
type: "object",
2020
description: "Enter data you'd like to add as key-value pairs, or reference an object from a previous step using a custom expression (e.g., `{{steps.data.$return_value}}`). Note that any keys that are duplicated will get overwritten with the last value entered (so `[{jerry: \"constanza\", jerry: \"seinfeld\"}]` will get stored as `[{jerry: \"seinfeld\"}]`).",
2121
},
22+
ttl: {
23+
propDefinition: [
24+
app,
25+
"ttl",
26+
],
27+
},
2228
},
2329
methods: {
2430
/**
@@ -83,14 +89,30 @@ export default {
8389
}
8490
const map = this.getHashMapOfData(this.data);
8591
const keys = Object.keys(map);
86-
const promises = Object.keys(map).map((key) => this.dataStore.set(key, map[key]));
92+
93+
const promises = Object.keys(map).map((key) => {
94+
if (this.ttl) {
95+
return this.dataStore.set(key, map[key], {
96+
ttl: this.ttl,
97+
});
98+
} else {
99+
return this.dataStore.set(key, map[key]);
100+
}
101+
});
102+
87103
await Promise.all(promises);
104+
88105
if (keys.length === 0) {
89106
$.export("$summary", "No data was added to the data store.");
90107
} else {
91108
// eslint-disable-next-line multiline-ternary
92-
$.export("$summary", `Successfully added or updated ${keys.length} record${keys.length === 1 ? "" : "s"}`);
109+
$.export("$summary", `Successfully added or updated ${keys.length} record${keys.length === 1 ? "" : "s"}${this.ttl ? ` (expires in ${this.app.formatTtl(this.ttl)})` : ""}`);
93110
}
94-
return map;
111+
112+
// Include TTL in the returned map
113+
return {
114+
...map,
115+
_ttl: this.ttl || null,
116+
};
95117
},
96118
};

components/data_stores/actions/add-update-record/add-update-record.mjs

+19-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default {
44
key: "data_stores-add-update-record",
55
name: "Add or update a single record",
66
description: "Add or update a single record in your [Pipedream Data Store](https://pipedream.com/data-stores/).",
7-
version: "0.0.9",
7+
version: "0.0.10",
88
type: "action",
99
props: {
1010
app,
@@ -30,20 +30,36 @@ export default {
3030
"value",
3131
],
3232
},
33+
ttl: {
34+
propDefinition: [
35+
app,
36+
"ttl",
37+
],
38+
},
3339
},
3440
async run({ $ }) {
3541
const {
3642
key,
3743
value,
44+
ttl,
3845
} = this;
3946
const exists = await this.dataStore.has(key);
4047
const parsedValue = this.app.parseValue(value);
41-
await this.dataStore.set(key, parsedValue);
48+
49+
if (ttl) {
50+
await this.dataStore.set(key, parsedValue, {
51+
ttl,
52+
});
53+
} else {
54+
await this.dataStore.set(key, parsedValue);
55+
}
56+
4257
// eslint-disable-next-line multiline-ternary
43-
$.export("$summary", `Successfully ${exists ? "updated the record for" : "added a new record with the"} key, \`${key}\`.`);
58+
$.export("$summary", `Successfully ${exists ? "updated the record for" : "added a new record with the"} key, \`${key}\`${ttl ? ` (expires in ${this.app.formatTtl(ttl)})` : ""}.`);
4459
return {
4560
key,
4661
value: parsedValue,
62+
ttl: ttl || null,
4763
};
4864
},
4965
};

components/data_stores/actions/append-to-record/append-to-record.mjs

+22-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export default {
55
key: "data_stores-append-to-record",
66
name: "Append to record",
77
description: "Append to a record in your data store [Pipedream Data Store](https://pipedream.com/data-stores/). If the record does not exist, a new record will be created in an array format.",
8-
version: "0.0.2",
8+
version: "0.0.3",
99
type: "action",
1010
props: {
1111
app,
@@ -31,11 +31,18 @@ export default {
3131
"value",
3232
],
3333
},
34+
ttl: {
35+
propDefinition: [
36+
app,
37+
"ttl",
38+
],
39+
},
3440
},
3541
async run({ $ }) {
3642
const {
3743
key,
3844
value,
45+
ttl,
3946
} = this;
4047
const currentValue = await this.dataStore.get(key);
4148
if (currentValue && !Array.isArray(currentValue)) {
@@ -44,12 +51,23 @@ export default {
4451
const recordSet = currentValue ?? [];
4552
const parsedValue = this.app.parseValue(value);
4653
recordSet.push(parsedValue);
47-
await this.dataStore.set(key, recordSet);
48-
// eslint-disable-next-line multiline-ternary
49-
$.export("$summary", `Successfully ${currentValue ? "appended to the record for" : "created new record with the"} key: \`${key}\`.`);
54+
55+
if (ttl) {
56+
await this.dataStore.set(key, recordSet, {
57+
ttl,
58+
});
59+
// eslint-disable-next-line multiline-ternary
60+
$.export("$summary", `Successfully ${currentValue ? "appended to the record for" : "created new record with the"} key: \`${key}\` (expires in ${this.app.formatTtl(ttl)}).`);
61+
} else {
62+
await this.dataStore.set(key, recordSet);
63+
// eslint-disable-next-line multiline-ternary
64+
$.export("$summary", `Successfully ${currentValue ? "appended to the record for" : "created new record with the"} key: \`${key}\`.`);
65+
}
66+
5067
return {
5168
key,
5269
value: parsedValue,
70+
ttl: ttl || null,
5371
};
5472
},
5573
};

components/data_stores/actions/get-record-or-create/get-record-or-create.mjs

+26-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default {
44
key: "data_stores-get-record-or-create",
55
name: "Get record (or create one if not found)",
66
description: "Get a single record in your [Pipedream Data Store](https://pipedream.com/data-stores/) or create one if it doesn't exist.",
7-
version: "0.0.10",
7+
version: "0.0.11",
88
type: "action",
99
props: {
1010
app,
@@ -30,6 +30,12 @@ export default {
3030
"addRecordIfNotFound",
3131
],
3232
},
33+
ttl: {
34+
propDefinition: [
35+
app,
36+
"ttl",
37+
],
38+
},
3339
},
3440
async additionalProps() {
3541
const props = {};
@@ -52,8 +58,25 @@ export default {
5258
}
5359

5460
const parsedValue = this.app.parseValue(this.value);
55-
await this.dataStore.set(this.key, parsedValue);
56-
$.export("$summary", `Successfully added a new record with the key, \`${this.key}\`.`);
61+
62+
if (this.ttl) {
63+
await this.dataStore.set(this.key, parsedValue, {
64+
ttl: this.ttl,
65+
});
66+
$.export("$summary", `Successfully added a new record with the key, \`${this.key}\` (expires in ${this.app.formatTtl(this.ttl)}).`);
67+
} else {
68+
await this.dataStore.set(this.key, parsedValue);
69+
$.export("$summary", `Successfully added a new record with the key, \`${this.key}\`.`);
70+
}
71+
72+
// Include TTL information in the return value if it was set
73+
if (this.ttl) {
74+
return {
75+
value: parsedValue,
76+
ttl: this.ttl,
77+
};
78+
}
79+
5780
return parsedValue;
5881
},
5982
};

components/data_stores/actions/has-key-or-create/has-key-or-create.mjs

+18-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ export default {
44
key: "data_stores-has-key-or-create",
55
name: "Check for existence of key",
66
description: "Check if a key exists in your [Pipedream Data Store](https://pipedream.com/data-stores/) or create one if it doesn't exist.",
7-
version: "0.1.2",
7+
version: "0.1.3",
88
type: "action",
99
props: {
1010
app,
@@ -30,6 +30,12 @@ export default {
3030
"addRecordIfNotFound",
3131
],
3232
},
33+
ttl: {
34+
propDefinition: [
35+
app,
36+
"ttl",
37+
],
38+
},
3339
},
3440
async additionalProps() {
3541
const props = {};
@@ -58,13 +64,22 @@ export default {
5864
}
5965

6066
const parsedValue = this.app.parseValue(this.value);
61-
await this.dataStore.set(this.key, parsedValue);
62-
$.export("$summary", `Key \`${this.key}\` was not found. Successfully added a new record.`);
67+
68+
if (this.ttl) {
69+
await this.dataStore.set(this.key, parsedValue, {
70+
ttl: this.ttl,
71+
});
72+
$.export("$summary", `Key \`${this.key}\` was not found. Successfully added a new record (expires in ${this.app.formatTtl(this.ttl)}).`);
73+
} else {
74+
await this.dataStore.set(this.key, parsedValue);
75+
$.export("$summary", `Key \`${this.key}\` was not found. Successfully added a new record.`);
76+
}
6377

6478
return {
6579
existingKeyFound: false,
6680
newKeyCreated: true,
6781
value: parsedValue,
82+
ttl: this.ttl || null,
6883
};
6984
},
7085
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import app from "../../data_stores.app.mjs";
2+
3+
export default {
4+
key: "data_stores-update-ttl",
5+
name: "Update record expiration",
6+
description: "Update the expiration time for a record in your [Pipedream Data Store](https://pipedream.com/data-stores/).",
7+
version: "0.0.1",
8+
type: "action",
9+
props: {
10+
app,
11+
dataStore: {
12+
propDefinition: [
13+
app,
14+
"dataStore",
15+
],
16+
},
17+
key: {
18+
propDefinition: [
19+
app,
20+
"key",
21+
({ dataStore }) => ({
22+
dataStore,
23+
}),
24+
],
25+
description: "Select the key for the record you'd like to update the expiration time.",
26+
},
27+
ttlOption: {
28+
type: "string",
29+
label: "Expiration Type",
30+
description: "Choose a common expiration time or specify a custom value",
31+
options: [
32+
{
33+
label: "Custom value",
34+
value: "custom",
35+
},
36+
{
37+
label: "No expiration (remove expiry)",
38+
value: "0",
39+
},
40+
{
41+
label: "1 hour",
42+
value: "3600",
43+
},
44+
{
45+
label: "1 day",
46+
value: "86400",
47+
},
48+
{
49+
label: "1 week",
50+
value: "604800",
51+
},
52+
{
53+
label: "30 days",
54+
value: "2592000",
55+
},
56+
{
57+
label: "90 days",
58+
value: "7776000",
59+
},
60+
{
61+
label: "1 year",
62+
value: "31536000",
63+
},
64+
],
65+
reloadProps: true,
66+
},
67+
},
68+
async additionalProps() {
69+
const props = {};
70+
if (this.ttlOption === "custom") {
71+
props.ttl = {
72+
type: "integer",
73+
label: "Custom TTL (seconds)",
74+
description: "The number of seconds until this record expires and is automatically deleted. Use 0 to remove expiration.",
75+
min: 0,
76+
max: 63072000, // 2 years (safe upper limit)
77+
};
78+
}
79+
return props;
80+
},
81+
async run({ $ }) {
82+
const {
83+
key, ttlOption, ttl,
84+
} = this;
85+
86+
// Determine TTL value to use
87+
const ttlValue = ttlOption === "custom"
88+
? ttl
89+
: parseInt(ttlOption, 10);
90+
91+
if (!await this.dataStore.has(key)) {
92+
$.export("$summary", `No record found with key \`${key}\`.`);
93+
return {
94+
success: false,
95+
message: `No record found with key ${key}`,
96+
};
97+
}
98+
99+
if (ttlValue === 0) {
100+
// Remove expiration
101+
await this.dataStore.setTtl(key, null);
102+
$.export("$summary", `Successfully removed expiration for key \`${key}\`.`);
103+
return {
104+
success: true,
105+
key,
106+
ttl: null,
107+
message: "Expiration removed",
108+
};
109+
} else {
110+
// Update TTL
111+
await this.dataStore.setTtl(key, ttlValue);
112+
$.export("$summary", `Successfully updated expiration for key \`${key}\` (expires in ${this.app.formatTtl(ttlValue)}).`);
113+
return {
114+
success: true,
115+
key,
116+
ttl: ttlValue,
117+
ttlFormatted: this.app.formatTtl(ttlValue),
118+
};
119+
}
120+
},
121+
};

0 commit comments

Comments
 (0)