@positronic/cloudflare 0.0.28 → 0.0.30
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/dist/src/api.js +525 -0
- package/dist/src/dev-server.js +203 -9
- package/dist/types/api.d.ts +3 -0
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/dev-server.d.ts +9 -0
- package/dist/types/dev-server.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/src/api.js
CHANGED
|
@@ -2215,4 +2215,529 @@ app.delete('/pages/:slug', function(context) {
|
|
|
2215
2215
|
});
|
|
2216
2216
|
})();
|
|
2217
2217
|
});
|
|
2218
|
+
/**
|
|
2219
|
+
* Helper to check if Cloudflare API credentials are configured
|
|
2220
|
+
*/ function getSecretsApiConfig(env) {
|
|
2221
|
+
var CLOUDFLARE_API_TOKEN = env.CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID = env.CLOUDFLARE_ACCOUNT_ID, CF_SCRIPT_NAME = env.CF_SCRIPT_NAME;
|
|
2222
|
+
if (!CLOUDFLARE_API_TOKEN || !CLOUDFLARE_ACCOUNT_ID || !CF_SCRIPT_NAME) {
|
|
2223
|
+
return null;
|
|
2224
|
+
}
|
|
2225
|
+
return {
|
|
2226
|
+
accountId: CLOUDFLARE_ACCOUNT_ID,
|
|
2227
|
+
scriptName: CF_SCRIPT_NAME,
|
|
2228
|
+
apiToken: CLOUDFLARE_API_TOKEN
|
|
2229
|
+
};
|
|
2230
|
+
}
|
|
2231
|
+
/**
|
|
2232
|
+
* Helper to make Cloudflare API requests for secrets
|
|
2233
|
+
*/ function cloudflareSecretsApi(_0, _1) {
|
|
2234
|
+
return _async_to_generator(function(config, path) {
|
|
2235
|
+
var options, baseUrl, url;
|
|
2236
|
+
var _arguments = arguments;
|
|
2237
|
+
return _ts_generator(this, function(_state) {
|
|
2238
|
+
options = _arguments.length > 2 && _arguments[2] !== void 0 ? _arguments[2] : {};
|
|
2239
|
+
baseUrl = "https://api.cloudflare.com/client/v4/accounts/".concat(config.accountId, "/workers/scripts/").concat(config.scriptName, "/secrets");
|
|
2240
|
+
url = path ? "".concat(baseUrl, "/").concat(path) : baseUrl;
|
|
2241
|
+
return [
|
|
2242
|
+
2,
|
|
2243
|
+
fetch(url, _object_spread_props(_object_spread({}, options), {
|
|
2244
|
+
headers: _object_spread({
|
|
2245
|
+
'Authorization': "Bearer ".concat(config.apiToken),
|
|
2246
|
+
'Content-Type': 'application/json'
|
|
2247
|
+
}, options.headers)
|
|
2248
|
+
}))
|
|
2249
|
+
];
|
|
2250
|
+
});
|
|
2251
|
+
}).apply(this, arguments);
|
|
2252
|
+
}
|
|
2253
|
+
// List all secrets (names only, not values)
|
|
2254
|
+
app.get('/secrets', function(context) {
|
|
2255
|
+
return _async_to_generator(function() {
|
|
2256
|
+
var config, response, data, _data_errors_, _data_errors, errorMessage, now, secrets, error;
|
|
2257
|
+
return _ts_generator(this, function(_state) {
|
|
2258
|
+
switch(_state.label){
|
|
2259
|
+
case 0:
|
|
2260
|
+
config = getSecretsApiConfig(context.env);
|
|
2261
|
+
if (!config) {
|
|
2262
|
+
return [
|
|
2263
|
+
2,
|
|
2264
|
+
context.json({
|
|
2265
|
+
error: 'Secrets management not configured. Please set CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, and CF_SCRIPT_NAME.'
|
|
2266
|
+
}, 400)
|
|
2267
|
+
];
|
|
2268
|
+
}
|
|
2269
|
+
_state.label = 1;
|
|
2270
|
+
case 1:
|
|
2271
|
+
_state.trys.push([
|
|
2272
|
+
1,
|
|
2273
|
+
4,
|
|
2274
|
+
,
|
|
2275
|
+
5
|
|
2276
|
+
]);
|
|
2277
|
+
return [
|
|
2278
|
+
4,
|
|
2279
|
+
cloudflareSecretsApi(config, '')
|
|
2280
|
+
];
|
|
2281
|
+
case 2:
|
|
2282
|
+
response = _state.sent();
|
|
2283
|
+
return [
|
|
2284
|
+
4,
|
|
2285
|
+
response.json()
|
|
2286
|
+
];
|
|
2287
|
+
case 3:
|
|
2288
|
+
data = _state.sent();
|
|
2289
|
+
if (!data.success) {
|
|
2290
|
+
;
|
|
2291
|
+
errorMessage = ((_data_errors = data.errors) === null || _data_errors === void 0 ? void 0 : (_data_errors_ = _data_errors[0]) === null || _data_errors_ === void 0 ? void 0 : _data_errors_.message) || 'Failed to list secrets';
|
|
2292
|
+
return [
|
|
2293
|
+
2,
|
|
2294
|
+
context.json({
|
|
2295
|
+
error: errorMessage
|
|
2296
|
+
}, 500)
|
|
2297
|
+
];
|
|
2298
|
+
}
|
|
2299
|
+
// Transform to match spec format - Cloudflare API doesn't return timestamps
|
|
2300
|
+
// so we use placeholder values
|
|
2301
|
+
now = new Date().toISOString();
|
|
2302
|
+
secrets = data.result.map(function(secret) {
|
|
2303
|
+
return {
|
|
2304
|
+
name: secret.name,
|
|
2305
|
+
createdAt: now,
|
|
2306
|
+
updatedAt: now
|
|
2307
|
+
};
|
|
2308
|
+
});
|
|
2309
|
+
return [
|
|
2310
|
+
2,
|
|
2311
|
+
context.json({
|
|
2312
|
+
secrets: secrets,
|
|
2313
|
+
count: secrets.length
|
|
2314
|
+
})
|
|
2315
|
+
];
|
|
2316
|
+
case 4:
|
|
2317
|
+
error = _state.sent();
|
|
2318
|
+
console.error('Error listing secrets:', error);
|
|
2319
|
+
return [
|
|
2320
|
+
2,
|
|
2321
|
+
context.json({
|
|
2322
|
+
error: "Failed to list secrets: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
|
|
2323
|
+
}, 500)
|
|
2324
|
+
];
|
|
2325
|
+
case 5:
|
|
2326
|
+
return [
|
|
2327
|
+
2
|
|
2328
|
+
];
|
|
2329
|
+
}
|
|
2330
|
+
});
|
|
2331
|
+
})();
|
|
2332
|
+
});
|
|
2333
|
+
// Create or update a secret
|
|
2334
|
+
app.post('/secrets', function(context) {
|
|
2335
|
+
return _async_to_generator(function() {
|
|
2336
|
+
var config, body, name, value, response, data, _data_errors_, _data_errors, errorMessage, now, error;
|
|
2337
|
+
return _ts_generator(this, function(_state) {
|
|
2338
|
+
switch(_state.label){
|
|
2339
|
+
case 0:
|
|
2340
|
+
config = getSecretsApiConfig(context.env);
|
|
2341
|
+
if (!config) {
|
|
2342
|
+
return [
|
|
2343
|
+
2,
|
|
2344
|
+
context.json({
|
|
2345
|
+
error: 'Secrets management not configured. Please set CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, and CF_SCRIPT_NAME.'
|
|
2346
|
+
}, 400)
|
|
2347
|
+
];
|
|
2348
|
+
}
|
|
2349
|
+
_state.label = 1;
|
|
2350
|
+
case 1:
|
|
2351
|
+
_state.trys.push([
|
|
2352
|
+
1,
|
|
2353
|
+
5,
|
|
2354
|
+
,
|
|
2355
|
+
6
|
|
2356
|
+
]);
|
|
2357
|
+
return [
|
|
2358
|
+
4,
|
|
2359
|
+
context.req.json()
|
|
2360
|
+
];
|
|
2361
|
+
case 2:
|
|
2362
|
+
body = _state.sent();
|
|
2363
|
+
name = body.name, value = body.value;
|
|
2364
|
+
if (!name) {
|
|
2365
|
+
return [
|
|
2366
|
+
2,
|
|
2367
|
+
context.json({
|
|
2368
|
+
error: 'Missing required field "name"'
|
|
2369
|
+
}, 400)
|
|
2370
|
+
];
|
|
2371
|
+
}
|
|
2372
|
+
if (value === undefined) {
|
|
2373
|
+
return [
|
|
2374
|
+
2,
|
|
2375
|
+
context.json({
|
|
2376
|
+
error: 'Missing required field "value"'
|
|
2377
|
+
}, 400)
|
|
2378
|
+
];
|
|
2379
|
+
}
|
|
2380
|
+
return [
|
|
2381
|
+
4,
|
|
2382
|
+
cloudflareSecretsApi(config, encodeURIComponent(name), {
|
|
2383
|
+
method: 'PUT',
|
|
2384
|
+
body: JSON.stringify({
|
|
2385
|
+
name: name,
|
|
2386
|
+
text: value,
|
|
2387
|
+
type: 'secret_text'
|
|
2388
|
+
})
|
|
2389
|
+
})
|
|
2390
|
+
];
|
|
2391
|
+
case 3:
|
|
2392
|
+
response = _state.sent();
|
|
2393
|
+
return [
|
|
2394
|
+
4,
|
|
2395
|
+
response.json()
|
|
2396
|
+
];
|
|
2397
|
+
case 4:
|
|
2398
|
+
data = _state.sent();
|
|
2399
|
+
if (!data.success) {
|
|
2400
|
+
;
|
|
2401
|
+
errorMessage = ((_data_errors = data.errors) === null || _data_errors === void 0 ? void 0 : (_data_errors_ = _data_errors[0]) === null || _data_errors_ === void 0 ? void 0 : _data_errors_.message) || 'Failed to create secret';
|
|
2402
|
+
return [
|
|
2403
|
+
2,
|
|
2404
|
+
context.json({
|
|
2405
|
+
error: errorMessage
|
|
2406
|
+
}, 500)
|
|
2407
|
+
];
|
|
2408
|
+
}
|
|
2409
|
+
now = new Date().toISOString();
|
|
2410
|
+
return [
|
|
2411
|
+
2,
|
|
2412
|
+
context.json({
|
|
2413
|
+
name: name,
|
|
2414
|
+
createdAt: now,
|
|
2415
|
+
updatedAt: now
|
|
2416
|
+
}, 201)
|
|
2417
|
+
];
|
|
2418
|
+
case 5:
|
|
2419
|
+
error = _state.sent();
|
|
2420
|
+
console.error('Error creating secret:', error);
|
|
2421
|
+
return [
|
|
2422
|
+
2,
|
|
2423
|
+
context.json({
|
|
2424
|
+
error: "Failed to create secret: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
|
|
2425
|
+
}, 500)
|
|
2426
|
+
];
|
|
2427
|
+
case 6:
|
|
2428
|
+
return [
|
|
2429
|
+
2
|
|
2430
|
+
];
|
|
2431
|
+
}
|
|
2432
|
+
});
|
|
2433
|
+
})();
|
|
2434
|
+
});
|
|
2435
|
+
// Delete a secret
|
|
2436
|
+
app.delete('/secrets/:name', function(context) {
|
|
2437
|
+
return _async_to_generator(function() {
|
|
2438
|
+
var config, name, response, data, _data_errors_, _data_errors, errorMessage, error;
|
|
2439
|
+
return _ts_generator(this, function(_state) {
|
|
2440
|
+
switch(_state.label){
|
|
2441
|
+
case 0:
|
|
2442
|
+
config = getSecretsApiConfig(context.env);
|
|
2443
|
+
if (!config) {
|
|
2444
|
+
return [
|
|
2445
|
+
2,
|
|
2446
|
+
context.json({
|
|
2447
|
+
error: 'Secrets management not configured. Please set CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, and CF_SCRIPT_NAME.'
|
|
2448
|
+
}, 400)
|
|
2449
|
+
];
|
|
2450
|
+
}
|
|
2451
|
+
name = decodeURIComponent(context.req.param('name'));
|
|
2452
|
+
_state.label = 1;
|
|
2453
|
+
case 1:
|
|
2454
|
+
_state.trys.push([
|
|
2455
|
+
1,
|
|
2456
|
+
4,
|
|
2457
|
+
,
|
|
2458
|
+
5
|
|
2459
|
+
]);
|
|
2460
|
+
return [
|
|
2461
|
+
4,
|
|
2462
|
+
cloudflareSecretsApi(config, encodeURIComponent(name), {
|
|
2463
|
+
method: 'DELETE'
|
|
2464
|
+
})
|
|
2465
|
+
];
|
|
2466
|
+
case 2:
|
|
2467
|
+
response = _state.sent();
|
|
2468
|
+
return [
|
|
2469
|
+
4,
|
|
2470
|
+
response.json()
|
|
2471
|
+
];
|
|
2472
|
+
case 3:
|
|
2473
|
+
data = _state.sent();
|
|
2474
|
+
if (!data.success) {
|
|
2475
|
+
;
|
|
2476
|
+
errorMessage = ((_data_errors = data.errors) === null || _data_errors === void 0 ? void 0 : (_data_errors_ = _data_errors[0]) === null || _data_errors_ === void 0 ? void 0 : _data_errors_.message) || 'Failed to delete secret';
|
|
2477
|
+
return [
|
|
2478
|
+
2,
|
|
2479
|
+
context.json({
|
|
2480
|
+
error: errorMessage
|
|
2481
|
+
}, 500)
|
|
2482
|
+
];
|
|
2483
|
+
}
|
|
2484
|
+
return [
|
|
2485
|
+
2,
|
|
2486
|
+
new Response(null, {
|
|
2487
|
+
status: 204
|
|
2488
|
+
})
|
|
2489
|
+
];
|
|
2490
|
+
case 4:
|
|
2491
|
+
error = _state.sent();
|
|
2492
|
+
console.error("Error deleting secret ".concat(name, ":"), error);
|
|
2493
|
+
return [
|
|
2494
|
+
2,
|
|
2495
|
+
context.json({
|
|
2496
|
+
error: "Failed to delete secret: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
|
|
2497
|
+
}, 500)
|
|
2498
|
+
];
|
|
2499
|
+
case 5:
|
|
2500
|
+
return [
|
|
2501
|
+
2
|
|
2502
|
+
];
|
|
2503
|
+
}
|
|
2504
|
+
});
|
|
2505
|
+
})();
|
|
2506
|
+
});
|
|
2507
|
+
// Check if a secret exists
|
|
2508
|
+
app.get('/secrets/:name/exists', function(context) {
|
|
2509
|
+
return _async_to_generator(function() {
|
|
2510
|
+
var config, name, response, data, _data_errors_, _data_errors, errorMessage, exists, error;
|
|
2511
|
+
return _ts_generator(this, function(_state) {
|
|
2512
|
+
switch(_state.label){
|
|
2513
|
+
case 0:
|
|
2514
|
+
config = getSecretsApiConfig(context.env);
|
|
2515
|
+
if (!config) {
|
|
2516
|
+
return [
|
|
2517
|
+
2,
|
|
2518
|
+
context.json({
|
|
2519
|
+
error: 'Secrets management not configured. Please set CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, and CF_SCRIPT_NAME.'
|
|
2520
|
+
}, 400)
|
|
2521
|
+
];
|
|
2522
|
+
}
|
|
2523
|
+
name = decodeURIComponent(context.req.param('name'));
|
|
2524
|
+
_state.label = 1;
|
|
2525
|
+
case 1:
|
|
2526
|
+
_state.trys.push([
|
|
2527
|
+
1,
|
|
2528
|
+
4,
|
|
2529
|
+
,
|
|
2530
|
+
5
|
|
2531
|
+
]);
|
|
2532
|
+
return [
|
|
2533
|
+
4,
|
|
2534
|
+
cloudflareSecretsApi(config, '')
|
|
2535
|
+
];
|
|
2536
|
+
case 2:
|
|
2537
|
+
response = _state.sent();
|
|
2538
|
+
return [
|
|
2539
|
+
4,
|
|
2540
|
+
response.json()
|
|
2541
|
+
];
|
|
2542
|
+
case 3:
|
|
2543
|
+
data = _state.sent();
|
|
2544
|
+
if (!data.success) {
|
|
2545
|
+
;
|
|
2546
|
+
errorMessage = ((_data_errors = data.errors) === null || _data_errors === void 0 ? void 0 : (_data_errors_ = _data_errors[0]) === null || _data_errors_ === void 0 ? void 0 : _data_errors_.message) || 'Failed to check secret';
|
|
2547
|
+
return [
|
|
2548
|
+
2,
|
|
2549
|
+
context.json({
|
|
2550
|
+
error: errorMessage
|
|
2551
|
+
}, 500)
|
|
2552
|
+
];
|
|
2553
|
+
}
|
|
2554
|
+
exists = data.result.some(function(secret) {
|
|
2555
|
+
return secret.name === name;
|
|
2556
|
+
});
|
|
2557
|
+
return [
|
|
2558
|
+
2,
|
|
2559
|
+
context.json({
|
|
2560
|
+
exists: exists
|
|
2561
|
+
})
|
|
2562
|
+
];
|
|
2563
|
+
case 4:
|
|
2564
|
+
error = _state.sent();
|
|
2565
|
+
console.error("Error checking secret ".concat(name, ":"), error);
|
|
2566
|
+
return [
|
|
2567
|
+
2,
|
|
2568
|
+
context.json({
|
|
2569
|
+
error: "Failed to check secret: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
|
|
2570
|
+
}, 500)
|
|
2571
|
+
];
|
|
2572
|
+
case 5:
|
|
2573
|
+
return [
|
|
2574
|
+
2
|
|
2575
|
+
];
|
|
2576
|
+
}
|
|
2577
|
+
});
|
|
2578
|
+
})();
|
|
2579
|
+
});
|
|
2580
|
+
// Bulk create secrets
|
|
2581
|
+
app.post('/secrets/bulk', function(context) {
|
|
2582
|
+
return _async_to_generator(function() {
|
|
2583
|
+
var config, body, secrets, listResponse, listData, existingNames, created, updated, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, secret, response, data, err, error;
|
|
2584
|
+
return _ts_generator(this, function(_state) {
|
|
2585
|
+
switch(_state.label){
|
|
2586
|
+
case 0:
|
|
2587
|
+
config = getSecretsApiConfig(context.env);
|
|
2588
|
+
if (!config) {
|
|
2589
|
+
return [
|
|
2590
|
+
2,
|
|
2591
|
+
context.json({
|
|
2592
|
+
error: 'Secrets management not configured. Please set CLOUDFLARE_API_TOKEN, CLOUDFLARE_ACCOUNT_ID, and CF_SCRIPT_NAME.'
|
|
2593
|
+
}, 400)
|
|
2594
|
+
];
|
|
2595
|
+
}
|
|
2596
|
+
_state.label = 1;
|
|
2597
|
+
case 1:
|
|
2598
|
+
_state.trys.push([
|
|
2599
|
+
1,
|
|
2600
|
+
14,
|
|
2601
|
+
,
|
|
2602
|
+
15
|
|
2603
|
+
]);
|
|
2604
|
+
return [
|
|
2605
|
+
4,
|
|
2606
|
+
context.req.json()
|
|
2607
|
+
];
|
|
2608
|
+
case 2:
|
|
2609
|
+
body = _state.sent();
|
|
2610
|
+
secrets = body.secrets;
|
|
2611
|
+
if (!secrets || !Array.isArray(secrets)) {
|
|
2612
|
+
return [
|
|
2613
|
+
2,
|
|
2614
|
+
context.json({
|
|
2615
|
+
error: 'Missing required field "secrets" (array)'
|
|
2616
|
+
}, 400)
|
|
2617
|
+
];
|
|
2618
|
+
}
|
|
2619
|
+
return [
|
|
2620
|
+
4,
|
|
2621
|
+
cloudflareSecretsApi(config, '')
|
|
2622
|
+
];
|
|
2623
|
+
case 3:
|
|
2624
|
+
listResponse = _state.sent();
|
|
2625
|
+
return [
|
|
2626
|
+
4,
|
|
2627
|
+
listResponse.json()
|
|
2628
|
+
];
|
|
2629
|
+
case 4:
|
|
2630
|
+
listData = _state.sent();
|
|
2631
|
+
existingNames = new Set(listData.success ? listData.result.map(function(s) {
|
|
2632
|
+
return s.name;
|
|
2633
|
+
}) : []);
|
|
2634
|
+
created = 0;
|
|
2635
|
+
updated = 0;
|
|
2636
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
2637
|
+
_state.label = 5;
|
|
2638
|
+
case 5:
|
|
2639
|
+
_state.trys.push([
|
|
2640
|
+
5,
|
|
2641
|
+
11,
|
|
2642
|
+
12,
|
|
2643
|
+
13
|
|
2644
|
+
]);
|
|
2645
|
+
_iterator = secrets[Symbol.iterator]();
|
|
2646
|
+
_state.label = 6;
|
|
2647
|
+
case 6:
|
|
2648
|
+
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
2649
|
+
3,
|
|
2650
|
+
10
|
|
2651
|
+
];
|
|
2652
|
+
secret = _step.value;
|
|
2653
|
+
if (!secret.name || secret.value === undefined) {
|
|
2654
|
+
return [
|
|
2655
|
+
3,
|
|
2656
|
+
9
|
|
2657
|
+
]; // Skip invalid entries
|
|
2658
|
+
}
|
|
2659
|
+
return [
|
|
2660
|
+
4,
|
|
2661
|
+
cloudflareSecretsApi(config, encodeURIComponent(secret.name), {
|
|
2662
|
+
method: 'PUT',
|
|
2663
|
+
body: JSON.stringify({
|
|
2664
|
+
name: secret.name,
|
|
2665
|
+
text: secret.value,
|
|
2666
|
+
type: 'secret_text'
|
|
2667
|
+
})
|
|
2668
|
+
})
|
|
2669
|
+
];
|
|
2670
|
+
case 7:
|
|
2671
|
+
response = _state.sent();
|
|
2672
|
+
return [
|
|
2673
|
+
4,
|
|
2674
|
+
response.json()
|
|
2675
|
+
];
|
|
2676
|
+
case 8:
|
|
2677
|
+
data = _state.sent();
|
|
2678
|
+
if (data.success) {
|
|
2679
|
+
if (existingNames.has(secret.name)) {
|
|
2680
|
+
updated++;
|
|
2681
|
+
} else {
|
|
2682
|
+
created++;
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
_state.label = 9;
|
|
2686
|
+
case 9:
|
|
2687
|
+
_iteratorNormalCompletion = true;
|
|
2688
|
+
return [
|
|
2689
|
+
3,
|
|
2690
|
+
6
|
|
2691
|
+
];
|
|
2692
|
+
case 10:
|
|
2693
|
+
return [
|
|
2694
|
+
3,
|
|
2695
|
+
13
|
|
2696
|
+
];
|
|
2697
|
+
case 11:
|
|
2698
|
+
err = _state.sent();
|
|
2699
|
+
_didIteratorError = true;
|
|
2700
|
+
_iteratorError = err;
|
|
2701
|
+
return [
|
|
2702
|
+
3,
|
|
2703
|
+
13
|
|
2704
|
+
];
|
|
2705
|
+
case 12:
|
|
2706
|
+
try {
|
|
2707
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
2708
|
+
_iterator.return();
|
|
2709
|
+
}
|
|
2710
|
+
} finally{
|
|
2711
|
+
if (_didIteratorError) {
|
|
2712
|
+
throw _iteratorError;
|
|
2713
|
+
}
|
|
2714
|
+
}
|
|
2715
|
+
return [
|
|
2716
|
+
7
|
|
2717
|
+
];
|
|
2718
|
+
case 13:
|
|
2719
|
+
return [
|
|
2720
|
+
2,
|
|
2721
|
+
context.json({
|
|
2722
|
+
created: created,
|
|
2723
|
+
updated: updated
|
|
2724
|
+
}, 201)
|
|
2725
|
+
];
|
|
2726
|
+
case 14:
|
|
2727
|
+
error = _state.sent();
|
|
2728
|
+
console.error('Error bulk creating secrets:', error);
|
|
2729
|
+
return [
|
|
2730
|
+
2,
|
|
2731
|
+
context.json({
|
|
2732
|
+
error: "Failed to bulk create secrets: ".concat(_instanceof(error, Error) ? error.message : 'Unknown error')
|
|
2733
|
+
}, 500)
|
|
2734
|
+
];
|
|
2735
|
+
case 15:
|
|
2736
|
+
return [
|
|
2737
|
+
2
|
|
2738
|
+
];
|
|
2739
|
+
}
|
|
2740
|
+
});
|
|
2741
|
+
})();
|
|
2742
|
+
});
|
|
2218
2743
|
export default app;
|
package/dist/src/dev-server.js
CHANGED
|
@@ -1289,16 +1289,70 @@ export var CloudflareDevServer = /*#__PURE__*/ function() {
|
|
|
1289
1289
|
reject(err);
|
|
1290
1290
|
});
|
|
1291
1291
|
wranglerProcess.on('exit', function(code) {
|
|
1292
|
-
|
|
1293
|
-
var successMessage
|
|
1294
|
-
|
|
1295
|
-
|
|
1292
|
+
return _async_to_generator(function() {
|
|
1293
|
+
var successMessage, secretsError;
|
|
1294
|
+
return _ts_generator(this, function(_state) {
|
|
1295
|
+
switch(_state.label){
|
|
1296
|
+
case 0:
|
|
1297
|
+
if (!(code === 0)) return [
|
|
1298
|
+
3,
|
|
1299
|
+
5
|
|
1300
|
+
];
|
|
1301
|
+
console.log('✅ Deployment complete!');
|
|
1302
|
+
// Set up secrets for the secrets management API
|
|
1303
|
+
console.log('🔐 Configuring secrets management...');
|
|
1304
|
+
_state.label = 1;
|
|
1305
|
+
case 1:
|
|
1306
|
+
_state.trys.push([
|
|
1307
|
+
1,
|
|
1308
|
+
3,
|
|
1309
|
+
,
|
|
1310
|
+
4
|
|
1311
|
+
]);
|
|
1312
|
+
return [
|
|
1313
|
+
4,
|
|
1314
|
+
this.setupSecretsManagement(bucketName)
|
|
1315
|
+
];
|
|
1316
|
+
case 2:
|
|
1317
|
+
_state.sent();
|
|
1318
|
+
successMessage = '✅ Deployment and secrets configuration complete!\n';
|
|
1319
|
+
this.logCallbacks.forEach(function(cb) {
|
|
1320
|
+
return cb(successMessage);
|
|
1321
|
+
});
|
|
1322
|
+
console.log('✅ Secrets management configured!');
|
|
1323
|
+
resolve();
|
|
1324
|
+
return [
|
|
1325
|
+
3,
|
|
1326
|
+
4
|
|
1327
|
+
];
|
|
1328
|
+
case 3:
|
|
1329
|
+
secretsError = _state.sent();
|
|
1330
|
+
// Warn but don't fail deployment if secrets setup fails
|
|
1331
|
+
console.warn('⚠️ Warning: Could not configure secrets management:', secretsError);
|
|
1332
|
+
console.warn(' You can manually set these secrets later with:');
|
|
1333
|
+
console.warn(' wrangler secret put CLOUDFLARE_API_TOKEN --env production');
|
|
1334
|
+
console.warn(' wrangler secret put CLOUDFLARE_ACCOUNT_ID --env production');
|
|
1335
|
+
console.warn(' wrangler secret put CF_SCRIPT_NAME --env production');
|
|
1336
|
+
resolve();
|
|
1337
|
+
return [
|
|
1338
|
+
3,
|
|
1339
|
+
4
|
|
1340
|
+
];
|
|
1341
|
+
case 4:
|
|
1342
|
+
return [
|
|
1343
|
+
3,
|
|
1344
|
+
6
|
|
1345
|
+
];
|
|
1346
|
+
case 5:
|
|
1347
|
+
reject(new Error("Wrangler deploy exited with code ".concat(code)));
|
|
1348
|
+
_state.label = 6;
|
|
1349
|
+
case 6:
|
|
1350
|
+
return [
|
|
1351
|
+
2
|
|
1352
|
+
];
|
|
1353
|
+
}
|
|
1296
1354
|
});
|
|
1297
|
-
|
|
1298
|
-
resolve();
|
|
1299
|
-
} else {
|
|
1300
|
-
reject(new Error("Wrangler deploy exited with code ".concat(code)));
|
|
1301
|
-
}
|
|
1355
|
+
}).call(_this);
|
|
1302
1356
|
});
|
|
1303
1357
|
})
|
|
1304
1358
|
];
|
|
@@ -1307,6 +1361,146 @@ export var CloudflareDevServer = /*#__PURE__*/ function() {
|
|
|
1307
1361
|
}).call(this);
|
|
1308
1362
|
}
|
|
1309
1363
|
},
|
|
1364
|
+
{
|
|
1365
|
+
key: "setupSecretsManagement",
|
|
1366
|
+
value: /**
|
|
1367
|
+
* Set up secrets required for the secrets management API.
|
|
1368
|
+
* This allows the deployed worker to manage its own secrets via HTTP API.
|
|
1369
|
+
*/ function setupSecretsManagement(projectName) {
|
|
1370
|
+
return _async_to_generator(function() {
|
|
1371
|
+
var apiToken, accountId, secrets, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, secret, err;
|
|
1372
|
+
return _ts_generator(this, function(_state) {
|
|
1373
|
+
switch(_state.label){
|
|
1374
|
+
case 0:
|
|
1375
|
+
apiToken = process.env.CLOUDFLARE_API_TOKEN;
|
|
1376
|
+
accountId = process.env.CLOUDFLARE_ACCOUNT_ID;
|
|
1377
|
+
secrets = [
|
|
1378
|
+
{
|
|
1379
|
+
name: 'CLOUDFLARE_API_TOKEN',
|
|
1380
|
+
value: apiToken
|
|
1381
|
+
},
|
|
1382
|
+
{
|
|
1383
|
+
name: 'CLOUDFLARE_ACCOUNT_ID',
|
|
1384
|
+
value: accountId
|
|
1385
|
+
},
|
|
1386
|
+
{
|
|
1387
|
+
name: 'CF_SCRIPT_NAME',
|
|
1388
|
+
value: projectName
|
|
1389
|
+
}
|
|
1390
|
+
];
|
|
1391
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
1392
|
+
_state.label = 1;
|
|
1393
|
+
case 1:
|
|
1394
|
+
_state.trys.push([
|
|
1395
|
+
1,
|
|
1396
|
+
6,
|
|
1397
|
+
7,
|
|
1398
|
+
8
|
|
1399
|
+
]);
|
|
1400
|
+
_iterator = secrets[Symbol.iterator]();
|
|
1401
|
+
_state.label = 2;
|
|
1402
|
+
case 2:
|
|
1403
|
+
if (!!(_iteratorNormalCompletion = (_step = _iterator.next()).done)) return [
|
|
1404
|
+
3,
|
|
1405
|
+
5
|
|
1406
|
+
];
|
|
1407
|
+
secret = _step.value;
|
|
1408
|
+
return [
|
|
1409
|
+
4,
|
|
1410
|
+
this.setWorkerSecret(accountId, projectName, secret.name, secret.value, apiToken)
|
|
1411
|
+
];
|
|
1412
|
+
case 3:
|
|
1413
|
+
_state.sent();
|
|
1414
|
+
_state.label = 4;
|
|
1415
|
+
case 4:
|
|
1416
|
+
_iteratorNormalCompletion = true;
|
|
1417
|
+
return [
|
|
1418
|
+
3,
|
|
1419
|
+
2
|
|
1420
|
+
];
|
|
1421
|
+
case 5:
|
|
1422
|
+
return [
|
|
1423
|
+
3,
|
|
1424
|
+
8
|
|
1425
|
+
];
|
|
1426
|
+
case 6:
|
|
1427
|
+
err = _state.sent();
|
|
1428
|
+
_didIteratorError = true;
|
|
1429
|
+
_iteratorError = err;
|
|
1430
|
+
return [
|
|
1431
|
+
3,
|
|
1432
|
+
8
|
|
1433
|
+
];
|
|
1434
|
+
case 7:
|
|
1435
|
+
try {
|
|
1436
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
1437
|
+
_iterator.return();
|
|
1438
|
+
}
|
|
1439
|
+
} finally{
|
|
1440
|
+
if (_didIteratorError) {
|
|
1441
|
+
throw _iteratorError;
|
|
1442
|
+
}
|
|
1443
|
+
}
|
|
1444
|
+
return [
|
|
1445
|
+
7
|
|
1446
|
+
];
|
|
1447
|
+
case 8:
|
|
1448
|
+
return [
|
|
1449
|
+
2
|
|
1450
|
+
];
|
|
1451
|
+
}
|
|
1452
|
+
});
|
|
1453
|
+
}).call(this);
|
|
1454
|
+
}
|
|
1455
|
+
},
|
|
1456
|
+
{
|
|
1457
|
+
key: "setWorkerSecret",
|
|
1458
|
+
value: /**
|
|
1459
|
+
* Set a secret on a Cloudflare Worker using the Cloudflare API.
|
|
1460
|
+
*/ function setWorkerSecret(accountId, scriptName, secretName, secretValue, apiToken) {
|
|
1461
|
+
return _async_to_generator(function() {
|
|
1462
|
+
var url, response, error;
|
|
1463
|
+
return _ts_generator(this, function(_state) {
|
|
1464
|
+
switch(_state.label){
|
|
1465
|
+
case 0:
|
|
1466
|
+
url = "https://api.cloudflare.com/client/v4/accounts/".concat(accountId, "/workers/scripts/").concat(scriptName, "/secrets/").concat(secretName);
|
|
1467
|
+
return [
|
|
1468
|
+
4,
|
|
1469
|
+
fetch(url, {
|
|
1470
|
+
method: 'PUT',
|
|
1471
|
+
headers: {
|
|
1472
|
+
'Authorization': "Bearer ".concat(apiToken),
|
|
1473
|
+
'Content-Type': 'application/json'
|
|
1474
|
+
},
|
|
1475
|
+
body: JSON.stringify({
|
|
1476
|
+
name: secretName,
|
|
1477
|
+
text: secretValue,
|
|
1478
|
+
type: 'secret_text'
|
|
1479
|
+
})
|
|
1480
|
+
})
|
|
1481
|
+
];
|
|
1482
|
+
case 1:
|
|
1483
|
+
response = _state.sent();
|
|
1484
|
+
if (!!response.ok) return [
|
|
1485
|
+
3,
|
|
1486
|
+
3
|
|
1487
|
+
];
|
|
1488
|
+
return [
|
|
1489
|
+
4,
|
|
1490
|
+
response.text()
|
|
1491
|
+
];
|
|
1492
|
+
case 2:
|
|
1493
|
+
error = _state.sent();
|
|
1494
|
+
throw new Error("Failed to set secret ".concat(secretName, ": ").concat(error));
|
|
1495
|
+
case 3:
|
|
1496
|
+
return [
|
|
1497
|
+
2
|
|
1498
|
+
];
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
})();
|
|
1502
|
+
}
|
|
1503
|
+
},
|
|
1310
1504
|
{
|
|
1311
1505
|
key: "onLog",
|
|
1312
1506
|
value: function onLog(callback) {
|
package/dist/types/api.d.ts
CHANGED
|
@@ -13,6 +13,9 @@ type Bindings = {
|
|
|
13
13
|
R2_SECRET_ACCESS_KEY?: string;
|
|
14
14
|
R2_ACCOUNT_ID?: string;
|
|
15
15
|
R2_BUCKET_NAME?: string;
|
|
16
|
+
CLOUDFLARE_API_TOKEN?: string;
|
|
17
|
+
CLOUDFLARE_ACCOUNT_ID?: string;
|
|
18
|
+
CF_SCRIPT_NAME?: string;
|
|
16
19
|
};
|
|
17
20
|
declare const app: Hono<{
|
|
18
21
|
Bindings: Bindings;
|
package/dist/types/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAI1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,2BAA2B,CAAC;AAGpE,KAAK,QAAQ,GAAG;IACd,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmBF,QAAA,MAAM,GAAG;cAAwB,QAAQ;yCAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAgB,MAAM,MAAM,CAAC;AAI1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,2BAA2B,CAAC;AAGpE,KAAK,QAAQ,GAAG;IACd,eAAe,EAAE,sBAAsB,CAAC,aAAa,CAAC,CAAC;IACvD,UAAU,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IAC9C,WAAW,EAAE,sBAAsB,CAAC,UAAU,CAAC,CAAC;IAChD,gBAAgB,EAAE,QAAQ,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAmBF,QAAA,MAAM,GAAG;cAAwB,QAAQ;yCAAK,CAAC;AA03C/C,eAAe,GAAG,CAAC"}
|
|
@@ -35,6 +35,15 @@ export declare class CloudflareDevServer implements PositronicDevServer {
|
|
|
35
35
|
watch(filePath: string, event: 'add' | 'change' | 'unlink'): Promise<void>;
|
|
36
36
|
private ensureR2BucketExists;
|
|
37
37
|
deploy(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Set up secrets required for the secrets management API.
|
|
40
|
+
* This allows the deployed worker to manage its own secrets via HTTP API.
|
|
41
|
+
*/
|
|
42
|
+
private setupSecretsManagement;
|
|
43
|
+
/**
|
|
44
|
+
* Set a secret on a Cloudflare Worker using the Cloudflare API.
|
|
45
|
+
*/
|
|
46
|
+
private setWorkerSecret;
|
|
38
47
|
onLog(callback: (message: string) => void): void;
|
|
39
48
|
onError(callback: (message: string) => void): void;
|
|
40
49
|
onWarning(callback: (message: string) => void): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/dev-server.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAqJ1E,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAmBnD;AA8CD,qBAAa,mBAAoB,YAAW,mBAAmB;IAyB1C,cAAc,EAAE,MAAM;IAjBzC;;;;;;;;;;;OAWG;IAEH,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,gBAAgB,CAAwC;gBAE7C,cAAc,EAAE,MAAM;IAEnC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAiB7B,qBAAqB;YA4DrB,wBAAwB;YAqBxB,yBAAyB;YAQzB,2BAA2B;IAuBzC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,wBAAwB;YASlB,0BAA0B;IA4BxC,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,gBAAgB;IA4BlB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAkD3C,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GACjC,OAAO,CAAC,IAAI,CAAC;YAUF,oBAAoB;IA0D5B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../../src/dev-server.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAqJ1E,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAmBnD;AA8CD,qBAAa,mBAAoB,YAAW,mBAAmB;IAyB1C,cAAc,EAAE,MAAM;IAjBzC;;;;;;;;;;;OAWG;IAEH,OAAO,CAAC,YAAY,CAAwC;IAC5D,OAAO,CAAC,cAAc,CAAwC;IAC9D,OAAO,CAAC,gBAAgB,CAAwC;gBAE7C,cAAc,EAAE,MAAM;IAEnC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;YAiB7B,qBAAqB;YA4DrB,wBAAwB;YAqBxB,yBAAyB;YAQzB,2BAA2B;IAuBzC,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,wBAAwB;YASlB,0BAA0B;IA4BxC,OAAO,CAAC,iBAAiB;IAuBzB,OAAO,CAAC,gBAAgB;IA4BlB,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAkD3C,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GACjC,OAAO,CAAC,IAAI,CAAC;YAUF,oBAAoB;IA0D5B,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAyG7B;;;OAGG;YACW,sBAAsB;IAepC;;OAEG;YACW,eAAe;IA4B7B,KAAK,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIhD,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAIlD,SAAS,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI9C,WAAW,IAAI,OAAO,CAC1B,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,IAAI,CAAC;QAAC,SAAS,CAAC,EAAE,IAAI,CAAA;KAAE,CAAC,CAC5D;IAwCK,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CrD,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAuC5C,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA0DnD"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@positronic/cloudflare",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.30",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"clean": "rm -rf tsconfig.tsbuildinfo dist"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@positronic/core": "^0.0.
|
|
35
|
-
"@positronic/spec": "^0.0.
|
|
36
|
-
"@positronic/template-new-project": "^0.0.
|
|
34
|
+
"@positronic/core": "^0.0.30",
|
|
35
|
+
"@positronic/spec": "^0.0.30",
|
|
36
|
+
"@positronic/template-new-project": "^0.0.30",
|
|
37
37
|
"aws4fetch": "^1.0.18",
|
|
38
38
|
"caz": "^2.0.0",
|
|
39
39
|
"cron-schedule": "^5.0.4",
|