@positronic/cloudflare 0.0.29 → 0.0.31

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 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;
@@ -1289,16 +1289,70 @@ export var CloudflareDevServer = /*#__PURE__*/ function() {
1289
1289
  reject(err);
1290
1290
  });
1291
1291
  wranglerProcess.on('exit', function(code) {
1292
- if (code === 0) {
1293
- var successMessage = '✅ Deployment complete!\n';
1294
- _this.logCallbacks.forEach(function(cb) {
1295
- return cb(successMessage);
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
- console.log('✅ Deployment complete!');
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,147 @@ 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
+ // Cloudflare API endpoint - secret name goes in the body, not the URL
1467
+ url = "https://api.cloudflare.com/client/v4/accounts/".concat(accountId, "/workers/scripts/").concat(scriptName, "/secrets");
1468
+ return [
1469
+ 4,
1470
+ fetch(url, {
1471
+ method: 'PUT',
1472
+ headers: {
1473
+ 'Authorization': "Bearer ".concat(apiToken),
1474
+ 'Content-Type': 'application/json'
1475
+ },
1476
+ body: JSON.stringify({
1477
+ name: secretName,
1478
+ text: secretValue,
1479
+ type: 'secret_text'
1480
+ })
1481
+ })
1482
+ ];
1483
+ case 1:
1484
+ response = _state.sent();
1485
+ if (!!response.ok) return [
1486
+ 3,
1487
+ 3
1488
+ ];
1489
+ return [
1490
+ 4,
1491
+ response.text()
1492
+ ];
1493
+ case 2:
1494
+ error = _state.sent();
1495
+ throw new Error("Failed to set secret ".concat(secretName, ": ").concat(error));
1496
+ case 3:
1497
+ return [
1498
+ 2
1499
+ ];
1500
+ }
1501
+ });
1502
+ })();
1503
+ }
1504
+ },
1310
1505
  {
1311
1506
  key: "onLog",
1312
1507
  value: function onLog(callback) {
@@ -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;
@@ -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;AA+jC/C,eAAe,GAAG,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;IA0F7B,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"}
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;IA6B7B,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.29",
3
+ "version": "0.0.31",
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.29",
35
- "@positronic/spec": "^0.0.29",
36
- "@positronic/template-new-project": "^0.0.29",
34
+ "@positronic/core": "^0.0.31",
35
+ "@positronic/spec": "^0.0.31",
36
+ "@positronic/template-new-project": "^0.0.31",
37
37
  "aws4fetch": "^1.0.18",
38
38
  "caz": "^2.0.0",
39
39
  "cron-schedule": "^5.0.4",