@apowerb/apowerb-sdk 0.1.3 → 0.1.4

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apowerb/apowerb-sdk",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "JavaScript SDK for the apowerb backend: agents, tools, RAG, BI, webhooks and billing. Dependency-free, runs in the browser and in Node.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -500,6 +500,30 @@ export const realAuthApi = {
500
500
  /**
501
501
  * Mock API for authentication (for development/testing)
502
502
  */
503
+ /**
504
+ * Shape check for an email address, without a backtracking regex.
505
+ *
506
+ * The previous `/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/` is polynomial: the two
507
+ * greedy classes around the dot make the engine retry every split of the
508
+ * domain when there is no dot to find. This only guards the mock backend,
509
+ * but the module ships in the published SDK bundle, so the pattern leaves
510
+ * with it.
511
+ *
512
+ * Same verdict as before: one `@`, non-empty on both sides, no whitespace,
513
+ * and a dot inside the domain with something on either side.
514
+ */
515
+ function looksLikeEmail(value) {
516
+ const parts = value.split("@");
517
+ if (parts.length !== 2) return false;
518
+
519
+ const [local, domain] = parts;
520
+ if (!local || !domain) return false;
521
+ if (/\s/.test(value)) return false;
522
+
523
+ const dot = domain.indexOf(".");
524
+ return dot > 0 && dot < domain.length - 1;
525
+ }
526
+
503
527
  export const mockAuthApi = {
504
528
  /**
505
529
  * Demo credentials for testing
@@ -604,7 +628,7 @@ export const mockAuthApi = {
604
628
  throw new Error("Password must be at least 6 characters");
605
629
  }
606
630
 
607
- if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
631
+ if (!looksLikeEmail(email)) {
608
632
  throw new Error("Invalid email format");
609
633
  }
610
634
 
package/src/config.js CHANGED
@@ -66,7 +66,22 @@ export function resetClientConfig() {
66
66
  */
67
67
  export function apiUrl(path) {
68
68
  const base = config.baseUrl || "";
69
- return base ? `${base.replace(/\/+$/, "")}${path}` : path;
69
+ return base ? `${stripTrailingSlashes(base)}${path}` : path;
70
+ }
71
+
72
+ /**
73
+ * Strip trailing slashes without a regular expression.
74
+ *
75
+ * `replace(/\/+$/, "")` did the same job, but `\/+$` is polynomial: on a
76
+ * string of N slashes that does not end with one, the engine retries from
77
+ * every position, so O(N squared). `baseUrl` normally comes from the
78
+ * application's own configuration, but nothing in this module guarantees
79
+ * that -- and this loop is linear by construction.
80
+ */
81
+ function stripTrailingSlashes(value) {
82
+ let end = value.length;
83
+ while (end > 0 && value[end - 1] === "/") end -= 1;
84
+ return value.slice(0, end);
70
85
  }
71
86
 
72
87
  export function getAuthToken() {