@mevdragon/vidfarm-devcli 0.5.3 → 0.7.0
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.
- package/README.md +3 -3
- package/SKILL.director.md +28 -7
- package/SKILL.platform.md +9 -5
- package/demo/README.md +28 -0
- package/demo/dist/app.css +1 -0
- package/demo/dist/app.js +1184 -0
- package/demo/dist/chunks/chunk-DXB73IDG.js +1 -0
- package/demo/dist/chunks/chunk-S7OWAJDS.js +36 -0
- package/demo/dist/chunks/chunk-VTIBZ6AN.js +1 -0
- package/demo/dist/chunks/dist-ADSJKBVE.js +332 -0
- package/demo/dist/chunks/domEditingLayers-VZMLL4AP-SGHWPND4.js +1 -0
- package/demo/dist/chunks/hyperframes-player-XB65TCD6.js +425 -0
- package/demo/dist/chunks/lib-XAQ37YOE.js +1 -0
- package/demo/dist/chunks/src-TJ2QYA4U.js +207 -0
- package/demo/dist/favicon.ico +0 -0
- package/demo/dist/icons/timeline/audio.svg +7 -0
- package/demo/dist/icons/timeline/captions.svg +5 -0
- package/demo/dist/icons/timeline/composition.svg +12 -0
- package/demo/dist/icons/timeline/image.svg +18 -0
- package/demo/dist/icons/timeline/music.svg +10 -0
- package/demo/dist/icons/timeline/text.svg +3 -0
- package/demo/dist/index.html +15 -0
- package/dist/src/account-pages-legacy.js +9396 -0
- package/dist/src/account-pages.js +61 -0
- package/dist/src/app.js +14663 -0
- package/dist/src/cli.js +60 -97
- package/dist/src/composition-runtime.js +613 -0
- package/dist/src/config.js +173 -0
- package/dist/src/context.js +447 -0
- package/dist/src/dev-app-legacy.js +739 -0
- package/dist/src/dev-app.js +6 -0
- package/dist/src/domain.js +2 -0
- package/dist/src/editor-chat-history.js +82 -0
- package/dist/src/editor-chat.js +449 -0
- package/dist/src/editor-dark-theme.js +1128 -0
- package/dist/src/frontend/debug.js +71 -0
- package/dist/src/frontend/flockposter-cache-store.js +124 -0
- package/dist/src/frontend/homepage-client.js +182 -0
- package/dist/src/frontend/homepage-shared.js +4 -0
- package/dist/src/frontend/homepage-store.js +28 -0
- package/dist/src/frontend/homepage-view.js +547 -0
- package/dist/src/frontend/page-runtime-client.js +132 -0
- package/dist/src/frontend/page-runtime-store.js +9 -0
- package/dist/src/frontend/sentry.js +42 -0
- package/dist/src/frontend/template-editor-chat.js +3960 -0
- package/dist/src/help-page.js +346 -0
- package/dist/src/homepage.js +1235 -0
- package/dist/src/hyperframes/composition.js +180 -0
- package/dist/src/index.js +16 -0
- package/dist/src/instrument.js +30 -0
- package/dist/src/lib/crypto.js +45 -0
- package/dist/src/lib/dev-log.js +54 -0
- package/dist/src/lib/display-name.js +11 -0
- package/dist/src/lib/ids.js +24 -0
- package/dist/src/lib/images.js +19 -0
- package/dist/src/lib/json.js +15 -0
- package/dist/src/lib/package-root.js +47 -0
- package/dist/src/lib/template-paths.js +28 -0
- package/dist/src/lib/time.js +7 -0
- package/dist/src/lib/url-clean.js +85 -0
- package/dist/src/page-runtime.js +2 -0
- package/dist/src/page-shell.js +1381 -0
- package/dist/src/primitive-context.js +357 -0
- package/dist/src/primitive-registry.js +2561 -0
- package/dist/src/primitive-sdk.js +4 -0
- package/dist/src/primitives/hyperframes-media.js +108 -0
- package/dist/src/react-page-shell.js +35 -0
- package/dist/src/ready-post-schedule-component.js +1540 -0
- package/dist/src/registry.js +296 -0
- package/dist/src/runtime.js +35 -0
- package/dist/src/services/api-call-history.js +249 -0
- package/dist/src/services/auth.js +152 -0
- package/dist/src/services/billing-pricing.js +39 -0
- package/dist/src/services/billing.js +228 -0
- package/dist/src/services/cast.js +127 -0
- package/dist/src/services/chat-threads.js +92 -0
- package/dist/src/services/composition-sanitize.js +124 -0
- package/dist/src/services/composition-watch.js +79 -0
- package/dist/src/services/fork-access.js +93 -0
- package/dist/src/services/fork-manifest.js +42 -0
- package/dist/src/services/ghostcut.js +179 -0
- package/dist/src/services/hyperframes.js +2307 -0
- package/dist/src/services/job-capacity.js +14 -0
- package/dist/src/services/job-logs.js +197 -0
- package/dist/src/services/jobs.js +136 -0
- package/dist/src/services/local-dynamo.js +0 -0
- package/dist/src/services/media-processing.js +766 -0
- package/dist/src/services/primitive-media-lambda.js +280 -0
- package/dist/src/services/providers.js +2926 -0
- package/dist/src/services/rate-limits.js +262 -0
- package/dist/src/services/serverless-auth.js +382 -0
- package/dist/src/services/serverless-jobs.js +1082 -0
- package/dist/src/services/serverless-provider-keys.js +409 -0
- package/dist/src/services/serverless-records.js +1385 -0
- package/dist/src/services/serverless-template-configs.js +75 -0
- package/dist/src/services/storage.js +383 -0
- package/dist/src/services/template-certification.js +413 -0
- package/dist/src/services/template-loader.js +99 -0
- package/dist/src/services/template-runtime-bundles.js +217 -0
- package/dist/src/services/template-sources.js +1017 -0
- package/dist/src/services/upstream.js +248 -0
- package/dist/src/services/video-normalization.js +2 -0
- package/dist/src/services/webhooks.js +62 -0
- package/dist/src/template-editor-pages.js +2576 -0
- package/dist/src/template-editor-shell.js +2840 -0
- package/dist/src/template-sdk.js +4 -0
- package/dist/src/worker.js +17 -0
- package/package.json +6 -4
- package/public/assets/homepage-app.js +54 -0
- package/public/assets/homepage-client-app.js +80 -0
- package/public/assets/page-runtime-client-app.js +94 -0
- package/src/assets/SELLING_AWARENESS_STAGES.md +579 -0
- package/src/assets/SELLING_WITH_HOOKS.md +377 -0
- package/src/assets/SELLING_WITH_VSLS.md +606 -0
- package/src/assets/favicon.ico +0 -0
- package/src/assets/logo-vidfarm.png +0 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
|
|
2
|
+
import { DeleteCommand, DynamoDBDocumentClient, PutCommand, QueryCommand, UpdateCommand } from "@aws-sdk/lib-dynamodb";
|
|
3
|
+
import { config } from "../config.js";
|
|
4
|
+
import { devLog } from "../lib/dev-log.js";
|
|
5
|
+
import { nowIso } from "../lib/time.js";
|
|
6
|
+
import { createLocalDynamoClient } from "./local-dynamo.js";
|
|
7
|
+
// `vidfarm serve` (RECORDS_DRIVER=local) swaps in the disk-backed shim so
|
|
8
|
+
// provider keys live on disk; deployed environments keep the real client.
|
|
9
|
+
const dynamodb = config.RECORDS_DRIVER === "local"
|
|
10
|
+
? createLocalDynamoClient()
|
|
11
|
+
: DynamoDBDocumentClient.from(new DynamoDBClient({}), {
|
|
12
|
+
marshallOptions: {
|
|
13
|
+
removeUndefinedValues: true
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
export class ServerlessProviderKeyService {
|
|
17
|
+
async listProviderKeys(customerId) {
|
|
18
|
+
const items = await this.queryCustomerKeys(customerId);
|
|
19
|
+
devLog("provider_keys.list", {
|
|
20
|
+
customer_id: customerId,
|
|
21
|
+
count: items.length
|
|
22
|
+
});
|
|
23
|
+
return items.map(itemToPublicProviderKey);
|
|
24
|
+
}
|
|
25
|
+
async listProviderKeysWithSecrets(customerId) {
|
|
26
|
+
const items = await this.queryCustomerKeys(customerId);
|
|
27
|
+
return items.map(itemToSecretProviderKey);
|
|
28
|
+
}
|
|
29
|
+
async createProviderKey(record) {
|
|
30
|
+
const timestamp = nowIso();
|
|
31
|
+
await dynamodb.send(new PutCommand({
|
|
32
|
+
TableName: requireMainTableName(),
|
|
33
|
+
Item: {
|
|
34
|
+
pk: providerKeyPk(record.id),
|
|
35
|
+
sk: "META",
|
|
36
|
+
entity_type: "ProviderKey",
|
|
37
|
+
gsi1pk: customerProviderKeysPk(record.customerId),
|
|
38
|
+
gsi1sk: providerKeySortKey(record.provider, timestamp, record.id),
|
|
39
|
+
key_id: record.id,
|
|
40
|
+
customer_id: record.customerId,
|
|
41
|
+
provider: record.provider,
|
|
42
|
+
label: record.label,
|
|
43
|
+
encrypted_secret: record.encryptedSecret,
|
|
44
|
+
status: "active",
|
|
45
|
+
last_used_at: null,
|
|
46
|
+
cooldown_until: null,
|
|
47
|
+
disabled_reason: null,
|
|
48
|
+
created_at: timestamp,
|
|
49
|
+
updated_at: timestamp
|
|
50
|
+
},
|
|
51
|
+
ConditionExpression: "attribute_not_exists(pk)"
|
|
52
|
+
}));
|
|
53
|
+
devLog("provider_keys.created", {
|
|
54
|
+
key_id: record.id,
|
|
55
|
+
customer_id: record.customerId,
|
|
56
|
+
provider: record.provider,
|
|
57
|
+
label: record.label
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async deleteProviderKey(customerId, keyId) {
|
|
61
|
+
await dynamodb.send(new DeleteCommand({
|
|
62
|
+
TableName: requireMainTableName(),
|
|
63
|
+
Key: providerKeyKey(keyId),
|
|
64
|
+
ConditionExpression: "customer_id = :customerId",
|
|
65
|
+
ExpressionAttributeValues: {
|
|
66
|
+
":customerId": customerId
|
|
67
|
+
}
|
|
68
|
+
})).catch((error) => {
|
|
69
|
+
if (isConditionalCheckFailed(error)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
throw error;
|
|
73
|
+
});
|
|
74
|
+
devLog("provider_keys.deleted", {
|
|
75
|
+
key_id: keyId,
|
|
76
|
+
customer_id: customerId
|
|
77
|
+
}, "warn");
|
|
78
|
+
}
|
|
79
|
+
async listAvailableProviderKeyCounts(customerId) {
|
|
80
|
+
const now = nowIso();
|
|
81
|
+
const counts = new Map();
|
|
82
|
+
for (const key of await this.listProviderKeysWithSecrets(customerId)) {
|
|
83
|
+
if (key.status !== "active" || !key.secret.trim()) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (key.cooldown_until && key.cooldown_until > now) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const item = await this.getProviderKeyItem(customerId, key.id);
|
|
90
|
+
if (!item) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const leaseExpiresAt = typeof item.active_lease_expires_at === "string" ? item.active_lease_expires_at : null;
|
|
94
|
+
if (leaseExpiresAt && leaseExpiresAt > now) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
counts.set(key.provider, (counts.get(key.provider) ?? 0) + 1);
|
|
98
|
+
}
|
|
99
|
+
return [...counts.entries()].map(([provider, availableCount]) => ({
|
|
100
|
+
customerId,
|
|
101
|
+
provider,
|
|
102
|
+
availableCount
|
|
103
|
+
})).map((entry) => {
|
|
104
|
+
devLog("provider_keys.available_count", {
|
|
105
|
+
customer_id: entry.customerId,
|
|
106
|
+
provider: entry.provider,
|
|
107
|
+
available_count: entry.availableCount
|
|
108
|
+
});
|
|
109
|
+
return entry;
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
async acquireProviderKeyLease(input) {
|
|
113
|
+
const now = nowIso();
|
|
114
|
+
const keys = (await this.queryCustomerKeys(input.customerId))
|
|
115
|
+
.map(itemToSecretProviderKeyWithLease)
|
|
116
|
+
.filter((key) => key.provider === input.provider)
|
|
117
|
+
.filter((key) => key.status === "active")
|
|
118
|
+
.filter((key) => !key.cooldown_until || key.cooldown_until <= now)
|
|
119
|
+
.filter((key) => key.secret.trim().length > 0)
|
|
120
|
+
.sort((a, b) => {
|
|
121
|
+
const aLast = a.last_used_at ?? "";
|
|
122
|
+
const bLast = b.last_used_at ?? "";
|
|
123
|
+
if (!aLast && bLast)
|
|
124
|
+
return -1;
|
|
125
|
+
if (aLast && !bLast)
|
|
126
|
+
return 1;
|
|
127
|
+
return aLast.localeCompare(bLast) || a.created_at.localeCompare(b.created_at);
|
|
128
|
+
});
|
|
129
|
+
for (const key of keys) {
|
|
130
|
+
try {
|
|
131
|
+
await dynamodb.send(new UpdateCommand({
|
|
132
|
+
TableName: requireMainTableName(),
|
|
133
|
+
Key: providerKeyKey(key.id),
|
|
134
|
+
ConditionExpression: [
|
|
135
|
+
"customer_id = :customerId",
|
|
136
|
+
"#status = :active",
|
|
137
|
+
"(attribute_not_exists(cooldown_until) OR attribute_type(cooldown_until, :nullType) OR cooldown_until = :empty OR cooldown_until <= :now)",
|
|
138
|
+
"(attribute_not_exists(active_lease_expires_at) OR active_lease_expires_at <= :now OR active_lease_token = :leaseToken)"
|
|
139
|
+
].join(" AND "),
|
|
140
|
+
UpdateExpression: [
|
|
141
|
+
"set active_lease_token = :leaseToken",
|
|
142
|
+
"active_lease_worker_id = :workerId",
|
|
143
|
+
"active_lease_job_id = :jobId",
|
|
144
|
+
"active_lease_expires_at = :expiresAt",
|
|
145
|
+
"updated_at = :now"
|
|
146
|
+
].join(", "),
|
|
147
|
+
ExpressionAttributeNames: {
|
|
148
|
+
"#status": "status"
|
|
149
|
+
},
|
|
150
|
+
ExpressionAttributeValues: {
|
|
151
|
+
":customerId": input.customerId,
|
|
152
|
+
":active": "active",
|
|
153
|
+
":nullType": "NULL",
|
|
154
|
+
":empty": "",
|
|
155
|
+
":now": now,
|
|
156
|
+
":leaseToken": input.leaseToken,
|
|
157
|
+
":workerId": input.workerId,
|
|
158
|
+
":jobId": input.jobId,
|
|
159
|
+
":expiresAt": input.expiresAt
|
|
160
|
+
}
|
|
161
|
+
}));
|
|
162
|
+
await this.putLeaseEvent({
|
|
163
|
+
keyId: key.id,
|
|
164
|
+
leaseToken: input.leaseToken,
|
|
165
|
+
workerId: input.workerId,
|
|
166
|
+
jobId: input.jobId,
|
|
167
|
+
expiresAt: input.expiresAt
|
|
168
|
+
});
|
|
169
|
+
devLog("provider_keys.lease.acquired", {
|
|
170
|
+
key_id: key.id,
|
|
171
|
+
customer_id: input.customerId,
|
|
172
|
+
provider: input.provider,
|
|
173
|
+
job_id: input.jobId,
|
|
174
|
+
worker_id: input.workerId,
|
|
175
|
+
expires_at: input.expiresAt
|
|
176
|
+
});
|
|
177
|
+
return {
|
|
178
|
+
keyId: key.id,
|
|
179
|
+
encryptedSecret: key.secret
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
catch (error) {
|
|
183
|
+
if (isConditionalCheckFailed(error)) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
throw error;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
devLog("provider_keys.lease.unavailable", {
|
|
190
|
+
customer_id: input.customerId,
|
|
191
|
+
provider: input.provider,
|
|
192
|
+
job_id: input.jobId,
|
|
193
|
+
worker_id: input.workerId
|
|
194
|
+
}, "warn");
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
async releaseProviderKeyLease(input) {
|
|
198
|
+
const now = nowIso();
|
|
199
|
+
await dynamodb.send(new UpdateCommand({
|
|
200
|
+
TableName: requireMainTableName(),
|
|
201
|
+
Key: providerKeyKey(input.keyId),
|
|
202
|
+
ConditionExpression: "active_lease_token = :leaseToken",
|
|
203
|
+
UpdateExpression: "SET updated_at = :now REMOVE active_lease_token, active_lease_worker_id, active_lease_job_id, active_lease_expires_at",
|
|
204
|
+
ExpressionAttributeValues: {
|
|
205
|
+
":leaseToken": input.leaseToken,
|
|
206
|
+
":now": now
|
|
207
|
+
}
|
|
208
|
+
})).catch((error) => {
|
|
209
|
+
if (isConditionalCheckFailed(error)) {
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
throw error;
|
|
213
|
+
});
|
|
214
|
+
await dynamodb.send(new DeleteCommand({
|
|
215
|
+
TableName: requireMainTableName(),
|
|
216
|
+
Key: {
|
|
217
|
+
pk: providerKeyPk(input.keyId),
|
|
218
|
+
sk: `LEASE#${input.leaseToken}`
|
|
219
|
+
}
|
|
220
|
+
}));
|
|
221
|
+
devLog("provider_keys.lease.released", {
|
|
222
|
+
key_id: input.keyId
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
async extendProviderKeyLease(input) {
|
|
226
|
+
await dynamodb.send(new UpdateCommand({
|
|
227
|
+
TableName: requireMainTableName(),
|
|
228
|
+
Key: providerKeyKey(input.keyId),
|
|
229
|
+
ConditionExpression: "active_lease_token = :leaseToken",
|
|
230
|
+
UpdateExpression: "set active_lease_expires_at = :expiresAt, updated_at = :now",
|
|
231
|
+
ExpressionAttributeValues: {
|
|
232
|
+
":leaseToken": input.leaseToken,
|
|
233
|
+
":expiresAt": input.expiresAt,
|
|
234
|
+
":now": nowIso()
|
|
235
|
+
}
|
|
236
|
+
})).catch((error) => {
|
|
237
|
+
if (isConditionalCheckFailed(error)) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
throw error;
|
|
241
|
+
});
|
|
242
|
+
devLog("provider_keys.lease.extended", {
|
|
243
|
+
key_id: input.keyId,
|
|
244
|
+
expires_at: input.expiresAt
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async recordProviderKeyUsage(input) {
|
|
248
|
+
const timestamp = nowIso();
|
|
249
|
+
await dynamodb.send(new PutCommand({
|
|
250
|
+
TableName: requireMainTableName(),
|
|
251
|
+
Item: {
|
|
252
|
+
pk: providerKeyPk(input.keyId),
|
|
253
|
+
sk: `USAGE#${timestamp}#${input.id}`,
|
|
254
|
+
entity_type: "ProviderKeyUsage",
|
|
255
|
+
gsi1pk: `JOB#${input.jobId}#PROVIDER_USAGE`,
|
|
256
|
+
gsi1sk: `USAGE#${timestamp}#${input.id}`,
|
|
257
|
+
usage_id: input.id,
|
|
258
|
+
key_id: input.keyId,
|
|
259
|
+
job_id: input.jobId,
|
|
260
|
+
provider: input.provider,
|
|
261
|
+
model: input.model ?? null,
|
|
262
|
+
event_type: input.eventType,
|
|
263
|
+
input_tokens: input.inputTokens ?? null,
|
|
264
|
+
output_tokens: input.outputTokens ?? null,
|
|
265
|
+
cost_usd: input.costUsd ?? null,
|
|
266
|
+
metadata: input.metadata ?? {},
|
|
267
|
+
created_at: timestamp
|
|
268
|
+
}
|
|
269
|
+
}));
|
|
270
|
+
devLog("provider_keys.usage.recorded", {
|
|
271
|
+
usage_id: input.id,
|
|
272
|
+
key_id: input.keyId,
|
|
273
|
+
job_id: input.jobId,
|
|
274
|
+
provider: input.provider,
|
|
275
|
+
model: input.model ?? null,
|
|
276
|
+
event_type: input.eventType,
|
|
277
|
+
cost_usd: input.costUsd ?? null
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
async touchProviderKey(keyId) {
|
|
281
|
+
const timestamp = nowIso();
|
|
282
|
+
await dynamodb.send(new UpdateCommand({
|
|
283
|
+
TableName: requireMainTableName(),
|
|
284
|
+
Key: providerKeyKey(keyId),
|
|
285
|
+
UpdateExpression: "set last_used_at = :now, updated_at = :now",
|
|
286
|
+
ExpressionAttributeValues: {
|
|
287
|
+
":now": timestamp
|
|
288
|
+
}
|
|
289
|
+
}));
|
|
290
|
+
}
|
|
291
|
+
async setProviderKeyCooldown(keyId, cooldownUntil, status = "active", disabledReason = null) {
|
|
292
|
+
const timestamp = nowIso();
|
|
293
|
+
await dynamodb.send(new UpdateCommand({
|
|
294
|
+
TableName: requireMainTableName(),
|
|
295
|
+
Key: providerKeyKey(keyId),
|
|
296
|
+
UpdateExpression: "set cooldown_until = :cooldownUntil, #status = :status, disabled_reason = :disabledReason, updated_at = :now",
|
|
297
|
+
ExpressionAttributeNames: {
|
|
298
|
+
"#status": "status"
|
|
299
|
+
},
|
|
300
|
+
ExpressionAttributeValues: {
|
|
301
|
+
":cooldownUntil": cooldownUntil instanceof Date ? cooldownUntil.toISOString() : cooldownUntil,
|
|
302
|
+
":status": status,
|
|
303
|
+
":disabledReason": disabledReason,
|
|
304
|
+
":now": timestamp
|
|
305
|
+
}
|
|
306
|
+
}));
|
|
307
|
+
}
|
|
308
|
+
async queryCustomerKeys(customerId) {
|
|
309
|
+
const response = await dynamodb.send(new QueryCommand({
|
|
310
|
+
TableName: requireMainTableName(),
|
|
311
|
+
IndexName: "gsi1",
|
|
312
|
+
KeyConditionExpression: "gsi1pk = :pk",
|
|
313
|
+
ExpressionAttributeValues: {
|
|
314
|
+
":pk": customerProviderKeysPk(customerId)
|
|
315
|
+
}
|
|
316
|
+
}));
|
|
317
|
+
return response.Items ?? [];
|
|
318
|
+
}
|
|
319
|
+
async getProviderKeyItem(customerId, keyId) {
|
|
320
|
+
const response = await dynamodb.send(new QueryCommand({
|
|
321
|
+
TableName: requireMainTableName(),
|
|
322
|
+
KeyConditionExpression: "pk = :pk and sk = :sk",
|
|
323
|
+
FilterExpression: "customer_id = :customerId",
|
|
324
|
+
ExpressionAttributeValues: {
|
|
325
|
+
":pk": providerKeyPk(keyId),
|
|
326
|
+
":sk": "META",
|
|
327
|
+
":customerId": customerId
|
|
328
|
+
},
|
|
329
|
+
Limit: 1
|
|
330
|
+
}));
|
|
331
|
+
return response.Items?.[0] ?? null;
|
|
332
|
+
}
|
|
333
|
+
async putLeaseEvent(input) {
|
|
334
|
+
await dynamodb.send(new PutCommand({
|
|
335
|
+
TableName: requireMainTableName(),
|
|
336
|
+
Item: {
|
|
337
|
+
pk: providerKeyPk(input.keyId),
|
|
338
|
+
sk: `LEASE#${input.leaseToken}`,
|
|
339
|
+
entity_type: "ProviderKeyLease",
|
|
340
|
+
key_id: input.keyId,
|
|
341
|
+
lease_token: input.leaseToken,
|
|
342
|
+
worker_id: input.workerId,
|
|
343
|
+
job_id: input.jobId,
|
|
344
|
+
leased_at: nowIso(),
|
|
345
|
+
expires_at: input.expiresAt,
|
|
346
|
+
expires_at_epoch_seconds: Math.ceil(Date.parse(input.expiresAt) / 1000)
|
|
347
|
+
}
|
|
348
|
+
}));
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function requireMainTableName() {
|
|
352
|
+
if (config.RECORDS_DRIVER === "local") {
|
|
353
|
+
return config.VIDFARM_SERVERLESS_MAIN_TABLE_NAME || "vidfarm-local-main";
|
|
354
|
+
}
|
|
355
|
+
if (!config.VIDFARM_SERVERLESS_MAIN_TABLE_NAME) {
|
|
356
|
+
throw new Error("Serverless provider key store requires VIDFARM_SERVERLESS_MAIN_TABLE_NAME.");
|
|
357
|
+
}
|
|
358
|
+
return config.VIDFARM_SERVERLESS_MAIN_TABLE_NAME;
|
|
359
|
+
}
|
|
360
|
+
function providerKeyPk(keyId) {
|
|
361
|
+
return `PROVIDER_KEY#${keyId}`;
|
|
362
|
+
}
|
|
363
|
+
function providerKeyKey(keyId) {
|
|
364
|
+
return {
|
|
365
|
+
pk: providerKeyPk(keyId),
|
|
366
|
+
sk: "META"
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
function customerProviderKeysPk(customerId) {
|
|
370
|
+
return `CUSTOMER#${customerId}#PROVIDER_KEYS`;
|
|
371
|
+
}
|
|
372
|
+
function providerKeySortKey(provider, createdAt, keyId) {
|
|
373
|
+
return `PROVIDER#${provider}#${createdAt}#${keyId}`;
|
|
374
|
+
}
|
|
375
|
+
function itemToPublicProviderKey(item) {
|
|
376
|
+
return {
|
|
377
|
+
id: String(item.key_id),
|
|
378
|
+
provider: normalizeProvider(item.provider),
|
|
379
|
+
label: typeof item.label === "string" ? item.label : null,
|
|
380
|
+
status: typeof item.status === "string" ? item.status : "active",
|
|
381
|
+
last_used_at: typeof item.last_used_at === "string" ? item.last_used_at : null,
|
|
382
|
+
cooldown_until: typeof item.cooldown_until === "string" ? item.cooldown_until : null,
|
|
383
|
+
disabled_reason: typeof item.disabled_reason === "string" ? item.disabled_reason : null,
|
|
384
|
+
created_at: String(item.created_at),
|
|
385
|
+
updated_at: String(item.updated_at)
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function itemToSecretProviderKey(item) {
|
|
389
|
+
return {
|
|
390
|
+
...itemToPublicProviderKey(item),
|
|
391
|
+
secret: typeof item.encrypted_secret === "string" ? item.encrypted_secret : ""
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
function itemToSecretProviderKeyWithLease(item) {
|
|
395
|
+
return {
|
|
396
|
+
...itemToSecretProviderKey(item),
|
|
397
|
+
active_lease_expires_at: typeof item.active_lease_expires_at === "string" ? item.active_lease_expires_at : null
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
function normalizeProvider(value) {
|
|
401
|
+
if (value === "openai" || value === "gemini" || value === "openrouter" || value === "perplexity") {
|
|
402
|
+
return value;
|
|
403
|
+
}
|
|
404
|
+
return "openai";
|
|
405
|
+
}
|
|
406
|
+
function isConditionalCheckFailed(error) {
|
|
407
|
+
return Boolean(error && typeof error === "object" && "name" in error && error.name === "ConditionalCheckFailedException");
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=serverless-provider-keys.js.map
|