learn-secrets-sdk 1.10.0 → 1.11.1

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.
Files changed (2) hide show
  1. package/dist/cli/index.mjs +11 -327
  2. package/package.json +2 -2
@@ -362,7 +362,7 @@ Log in on ${this.baseUrl}`);
362
362
  /**
363
363
  * Make authenticated request
364
364
  */
365
- async request(method, path3, body) {
365
+ async request(method, path2, body) {
366
366
  const token = this.getAccessToken();
367
367
  const options = {
368
368
  method,
@@ -374,7 +374,7 @@ Log in on ${this.baseUrl}`);
374
374
  if (body) {
375
375
  options.body = JSON.stringify(body);
376
376
  }
377
- const response = await fetch(`${this.baseUrl}${path3}`, options);
377
+ const response = await fetch(`${this.baseUrl}${path2}`, options);
378
378
  if (!response.ok) {
379
379
  const errorData = await response.json().catch(() => ({}));
380
380
  throw new SecretsSDKError(
@@ -675,107 +675,6 @@ function summarizeDetectedSecrets(secrets) {
675
675
  return lines.join("\n");
676
676
  }
677
677
 
678
- // src/cli/commands/connect-cloudflare.ts
679
- function getApiUrl(baseUrl) {
680
- return baseUrl || "https://cloudprototype.org";
681
- }
682
- async function connectCloudflare(apiToken, baseUrl) {
683
- if (!apiToken.match(/^[A-Za-z0-9_-]{40,}$/)) {
684
- return {
685
- success: false,
686
- error: "Invalid API token format. Token should be 40+ alphanumeric characters"
687
- };
688
- }
689
- const validation = await validateCloudflareToken(apiToken);
690
- if (!validation.valid) {
691
- return {
692
- success: false,
693
- error: validation.error || "Token validation failed"
694
- };
695
- }
696
- try {
697
- const apiUrl = getApiUrl(baseUrl);
698
- const response = await fetch(`${apiUrl}/api/cloudflare/connect`, {
699
- method: "POST",
700
- headers: {
701
- "Content-Type": "application/json"
702
- },
703
- credentials: "include",
704
- body: JSON.stringify({
705
- apiToken,
706
- accountId: validation.accountId,
707
- accountName: validation.accountName
708
- })
709
- });
710
- if (!response.ok) {
711
- const error = await response.json();
712
- return {
713
- success: false,
714
- error: error.message || "Failed to store token"
715
- };
716
- }
717
- return {
718
- success: true,
719
- accountId: validation.accountId,
720
- accountName: validation.accountName
721
- };
722
- } catch (error) {
723
- return {
724
- success: false,
725
- error: error.message || "Failed to connect Cloudflare account"
726
- };
727
- }
728
- }
729
- async function validateCloudflareToken(token) {
730
- try {
731
- const response = await fetch("https://api.cloudflare.com/client/v4/user", {
732
- headers: {
733
- Authorization: `Bearer ${token}`,
734
- "Content-Type": "application/json"
735
- }
736
- });
737
- if (!response.ok) {
738
- const error = await response.json();
739
- return {
740
- valid: false,
741
- error: error.errors?.[0]?.message || "Invalid token"
742
- };
743
- }
744
- const data = await response.json();
745
- const accountsResponse = await fetch("https://api.cloudflare.com/client/v4/accounts", {
746
- headers: {
747
- Authorization: `Bearer ${token}`,
748
- "Content-Type": "application/json"
749
- }
750
- });
751
- if (!accountsResponse.ok) {
752
- return {
753
- valid: false,
754
- error: "Token does not have access to accounts"
755
- };
756
- }
757
- const accountsData = await accountsResponse.json();
758
- const accounts = accountsData.result || [];
759
- if (accounts.length === 0) {
760
- return {
761
- valid: false,
762
- error: "No accounts found for this token"
763
- };
764
- }
765
- const account = accounts[0];
766
- return {
767
- valid: true,
768
- accountId: account.id,
769
- accountName: account.name
770
- };
771
- } catch (error) {
772
- return {
773
- valid: false,
774
- error: error.message || "Failed to validate token"
775
- };
776
- }
777
- }
778
-
779
678
  // src/cli/commands/init.ts
780
679
  async function initCommand(options) {
781
680
  if (!hasValidCredentials()) {
@@ -865,67 +764,16 @@ Onboarding site for project: ${projectId}`);
865
764
  console.log(` - ${failure.name}: ${failure.error}`);
866
765
  }
867
766
  }
767
+ const dashboardUrl = options.baseUrl || "https://cloudprototype.org";
868
768
  console.log("\nYour site is ready!");
869
769
  console.log("\nAdd to your static site code:");
870
770
  console.log(" const sdk = new SecretsSDK();");
871
771
  console.log(" // Uses origin-based auth - no token needed!");
872
- console.log("\n--- Cloudflare Worker Setup ---");
873
- const dashboardUrl = options.baseUrl || "https://cloudprototype.org";
874
- let cloudflareConnected = false;
875
- try {
876
- const statusResponse = await fetch(`${dashboardUrl}/api/cloudflare/status`, {
877
- credentials: "include"
878
- });
879
- cloudflareConnected = statusResponse.ok;
880
- } catch {
881
- cloudflareConnected = false;
882
- }
883
- if (cloudflareConnected) {
884
- console.log("Cloudflare account is already connected.");
885
- } else {
886
- console.log("To deploy secrets via Cloudflare Worker, we need your Cloudflare API token.");
887
- console.log("\nRequired permissions:");
888
- console.log(" - Workers Scripts: Edit");
889
- console.log(" - Workers Routes: Edit");
890
- console.log(" - Account Settings: Read");
891
- console.log("\nCreate token at: https://dash.cloudflare.com/profile/api-tokens");
892
- const readline = await import("readline");
893
- const rl = readline.createInterface({
894
- input: process.stdin,
895
- output: process.stdout
896
- });
897
- const apiToken = await new Promise((resolve2) => {
898
- rl.question("\nCloudflare API Token (or press Enter to skip): ", (answer) => {
899
- rl.close();
900
- resolve2(answer.trim());
901
- });
902
- });
903
- if (apiToken) {
904
- console.log("\nValidating token...");
905
- const result2 = await connectCloudflare(apiToken, options.baseUrl);
906
- if (result2.success) {
907
- console.log("Cloudflare account connected");
908
- console.log(` Account: ${result2.accountName}`);
909
- cloudflareConnected = true;
910
- } else {
911
- console.log(`
912
- Warning: Failed to connect Cloudflare: ${result2.error}`);
913
- console.log("You can connect later by running: learn-secrets deploy");
914
- }
915
- } else {
916
- console.log("\nSkipped Cloudflare connection.");
917
- console.log("You can connect later when you run: learn-secrets deploy");
918
- }
919
- }
920
772
  console.log(`
921
773
  Next steps:`);
922
- console.log(` 1. Run: learn-secrets deploy`);
923
- if (cloudflareConnected) {
924
- console.log(` (Deploy Worker to Cloudflare with your secrets)`);
925
- } else {
926
- console.log(` (Connect Cloudflare and deploy Worker with your secrets)`);
927
- }
928
- console.log(` 2. Visit: ${dashboardUrl}/dashboard to manage secrets`);
774
+ console.log(` 1. Run: learn-secrets deploy (to update secrets)`);
775
+ console.log(` 2. Visit: ${dashboardUrl}/dashboard/secrets to manage secrets`);
776
+ console.log(` 3. View usage at: ${dashboardUrl}/dashboard/settings/usage`);
929
777
  const config = {
930
778
  project: projectId,
931
779
  origins,
@@ -994,87 +842,6 @@ Configuration saved to: ${configFile}`);
994
842
 
995
843
  // src/cli/commands/deploy.ts
996
844
  import fs5 from "fs";
997
-
998
- // src/cli/commands/provision-worker.ts
999
- import path2 from "path";
1000
- import { fileURLToPath } from "url";
1001
- var __filename = fileURLToPath(import.meta.url);
1002
- var __dirname = path2.dirname(__filename);
1003
- function getApiUrl2(baseUrl) {
1004
- return baseUrl || "https://cloudprototype.org";
1005
- }
1006
- async function provisionWorker(workerName, origins, envVars, baseUrl) {
1007
- const publicVars = [];
1008
- const secretVars = [];
1009
- for (const { key, value } of envVars) {
1010
- if (isPublicConfig(key)) {
1011
- publicVars.push({ key, value });
1012
- } else {
1013
- secretVars.push({ key, value });
1014
- }
1015
- }
1016
- try {
1017
- const apiUrl = getApiUrl2(baseUrl);
1018
- const deployResponse = await fetch(`${apiUrl}/api/cloudflare/provision-worker`, {
1019
- method: "POST",
1020
- headers: {
1021
- "Content-Type": "application/json"
1022
- },
1023
- credentials: "include",
1024
- body: JSON.stringify({
1025
- workerName,
1026
- allowedOrigins: origins,
1027
- publicVars: publicVars.map((v) => ({
1028
- key: `PUBLIC_${v.key}`,
1029
- value: v.value
1030
- })),
1031
- secrets: secretVars.map((v) => ({
1032
- key: `SECRET_${v.key}`,
1033
- value: v.value
1034
- }))
1035
- })
1036
- });
1037
- if (!deployResponse.ok) {
1038
- const error = await deployResponse.json();
1039
- return {
1040
- success: false,
1041
- error: error.message || "Failed to deploy Worker"
1042
- };
1043
- }
1044
- const result = await deployResponse.json();
1045
- return {
1046
- success: true,
1047
- workerUrl: result.workerUrl,
1048
- workerName: result.workerName
1049
- };
1050
- } catch (error) {
1051
- return {
1052
- success: false,
1053
- error: error.message || "Failed to provision Worker"
1054
- };
1055
- }
1056
- }
1057
- function isPublicConfig(key) {
1058
- const publicPatterns = [
1059
- /_DOMAIN$/,
1060
- /_CLIENT_ID$/,
1061
- /_AUDIENCE$/,
1062
- /_CALLBACK_URL$/,
1063
- /_ISSUER$/,
1064
- /_TEAM_ID$/,
1065
- /_KEY_ID$/,
1066
- /^API_BASE_URL$/,
1067
- /^PUBLIC_/
1068
- ];
1069
- for (const pattern of publicPatterns) {
1070
- if (pattern.test(key)) {
1071
- return true;
1072
- }
1073
- }
1074
- return false;
1075
- }
1076
-
1077
- // src/cli/commands/deploy.ts
1078
845
  async function deployCommand(options = {}) {
1079
846
  if (!hasValidCredentials()) {
1080
847
  console.error('Error: Not authenticated. Run "learn-secrets login" first.');
@@ -1156,93 +923,10 @@ Deploying secrets to project: ${config.project}`);
1156
923
  }
1157
924
  const dashboardUrl = options.baseUrl || "https://cloudprototype.org";
1158
925
  console.log(`
1159
- Secrets deployed! View them at: ${dashboardUrl}/dashboard/collections/secrets`);
1160
- console.log("\n--- Cloudflare Worker Deployment ---");
1161
- let cloudflareConnected = false;
1162
- try {
1163
- const statusResponse = await fetch(`${dashboardUrl}/api/cloudflare/status`, {
1164
- credentials: "include"
1165
- });
1166
- cloudflareConnected = statusResponse.ok;
1167
- } catch {
1168
- cloudflareConnected = false;
1169
- }
1170
- if (!cloudflareConnected) {
1171
- console.log("Cloudflare account not connected.");
1172
- console.log("\nTo deploy Worker, we need your Cloudflare API token.");
1173
- console.log("Required permissions:");
1174
- console.log(" - Workers Scripts: Edit");
1175
- console.log(" - Workers Routes: Edit");
1176
- console.log(" - Account Settings: Read");
1177
- console.log("\nCreate token at: https://dash.cloudflare.com/profile/api-tokens");
1178
- const readline = await import("readline");
1179
- const rl = readline.createInterface({
1180
- input: process.stdin,
1181
- output: process.stdout
1182
- });
1183
- const apiToken = await new Promise((resolve2) => {
1184
- rl.question("\nCloudflare API Token (or press Enter to skip): ", (answer) => {
1185
- rl.close();
1186
- resolve2(answer.trim());
1187
- });
1188
- });
1189
- if (apiToken) {
1190
- console.log("\nValidating token...");
1191
- const result2 = await connectCloudflare(apiToken, options.baseUrl);
1192
- if (result2.success) {
1193
- console.log("Cloudflare account connected");
1194
- console.log(` Account: ${result2.accountName}`);
1195
- cloudflareConnected = true;
1196
- } else {
1197
- console.log(`
1198
- Error: Failed to connect Cloudflare: ${result2.error}`);
1199
- console.log("Worker deployment skipped.");
1200
- }
1201
- } else {
1202
- console.log("\nSkipped Cloudflare connection. Worker deployment skipped.");
1203
- }
1204
- } else {
1205
- console.log("Cloudflare account is connected.");
1206
- }
1207
- if (cloudflareConnected) {
1208
- const readline = await import("readline");
1209
- const rl = readline.createInterface({
1210
- input: process.stdin,
1211
- output: process.stdout
1212
- });
1213
- const shouldProvision = await new Promise((resolve2) => {
1214
- rl.question("\nDeploy/update Worker to Cloudflare? (y/N): ", (answer) => {
1215
- rl.close();
1216
- resolve2(answer.trim());
1217
- });
1218
- });
1219
- if (shouldProvision.toLowerCase() === "y" || shouldProvision.toLowerCase() === "yes") {
1220
- console.log("\nDeploying Worker to Cloudflare...");
1221
- const workerName = `learn-secrets-${config.project.toLowerCase()}`;
1222
- const provisionResult = await provisionWorker(
1223
- workerName,
1224
- config.origins,
1225
- envVars,
1226
- options.baseUrl
1227
- );
1228
- if (provisionResult.success) {
1229
- console.log("\nWorker deployed successfully");
1230
- console.log(` Name: ${provisionResult.workerName}`);
1231
- console.log(` URL: ${provisionResult.workerUrl}`);
1232
- config.workerUrl = provisionResult.workerUrl;
1233
- fs5.writeFileSync(configFile, JSON.stringify(config, null, 2));
1234
- console.log("\nNext steps:");
1235
- console.log(` 1. Test Worker: curl ${provisionResult.workerUrl}/health`);
1236
- console.log(` 2. Update your frontend to use Worker URL`);
1237
- console.log(` 3. Test origin validation from your site`);
1238
- } else {
1239
- console.log(`
1240
- Error: Worker deployment failed: ${provisionResult.error}`);
1241
- }
1242
- } else {
1243
- console.log("\nSkipped Worker deployment.");
1244
- }
1245
- }
926
+ Secrets deployed to Learn dashboard!`);
927
+ console.log(`View at: ${dashboardUrl}/dashboard/collections/secrets`);
928
+ console.log(`
929
+ Your secrets are now accessible via the Learn Secrets API.`);
1246
930
  } catch (error) {
1247
931
  console.error("\nDeploy failed:", error.message);
1248
932
  if (error.status === 401) {
@@ -1257,7 +941,7 @@ Error: Worker deployment failed: ${provisionResult.error}`);
1257
941
 
1258
942
  // src/cli/index.ts
1259
943
  var program = new Command();
1260
- program.name("learn-secrets").description("CLI tool for managing API secrets with Cloudflare Worker deployment").version("1.10.0");
944
+ program.name("learn-secrets").description("CLI tool for managing secrets with the Learn platform").version("1.11.1");
1261
945
  program.command("login").description("Authenticate with Learn Secrets via browser").option("--base-url <url>", "Custom base URL for API").action(async (options) => {
1262
946
  await loginCommand(options);
1263
947
  });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "learn-secrets-sdk",
3
- "version": "1.10.0",
4
- "description": "Secure API proxy SDK with Cloudflare Worker deployment for static sites",
3
+ "version": "1.11.1",
4
+ "description": "Secrets management SDK for static sites with Learn platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.esm.js",
7
7
  "types": "dist/index.d.ts",