@sylphx/sdk 0.10.0 → 0.10.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.
@@ -1041,7 +1041,7 @@ var PlatformContext = createContext3(null);
1041
1041
  // src/connection-url.ts
1042
1042
  var SYLPHX_PROTOCOL = "sylphx:";
1043
1043
  var DEFAULT_VERSION = "v1";
1044
- var CREDENTIAL_REGEX = /^(pk|sk)_(dev|stg|prod|prev)_[a-f0-9]{32,64}$/;
1044
+ var CREDENTIAL_REGEX = /^(pk|sk)_(dev|stg|prod|prev)(?:_[a-z0-9]{12})?_[a-f0-9]{32,64}$/;
1045
1045
  var VERSION_REGEX = /^v[0-9]+$/;
1046
1046
  var SLUG_REGEX = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
1047
1047
  var InvalidConnectionUrlError = class _InvalidConnectionUrlError extends Error {
@@ -1058,7 +1058,7 @@ function fail(reason) {
1058
1058
  function parseCredential(raw) {
1059
1059
  const match = CREDENTIAL_REGEX.exec(raw);
1060
1060
  if (!match) {
1061
- fail(`credential must match (pk|sk)_(dev|stg|prod|prev)_[a-f0-9]{32,64}, got "${raw}"`);
1061
+ fail(`credential must match (pk|sk)_(dev|stg|prod|prev)(_{ref})?_{hex}, got "${raw}"`);
1062
1062
  }
1063
1063
  return {
1064
1064
  credentialType: match[1],
@@ -1136,7 +1136,7 @@ function parseConnectionUrl(url) {
1136
1136
  init_constants();
1137
1137
  var LEGACY_EMBEDDED_REF_PATTERN = /^(pk|sk)_(dev|stg|prod|prev)_[a-z0-9]{12}_[a-f0-9]+$/;
1138
1138
  var LEGACY_APP_KEY_PATTERN = /^app_(dev|stg|prod|prev)_/;
1139
- var MIGRATION_MESSAGE = "API key format has changed. Use a sylphx:// connection URL instead.\n\nNew format: sylphx://pk_prod_{hex}@your-slug.api.sylphx.com\n\nGenerate new credentials from the Sylphx Console \u2192 Your App \u2192 Environments.\nSee https://docs.sylphx.com/migration for details.";
1139
+ var MIGRATION_MESSAGE = "API key format has changed. Use a sylphx:// connection URL instead.\n\nNew format: sylphx://pk_prod_{ref?}_{hex}@your-slug.api.sylphx.com\n\nGenerate new credentials from the Sylphx Console \u2192 Your App \u2192 Environments.\nSee https://docs.sylphx.com/migration for details.";
1140
1140
  function rejectLegacyKeyFormat(input) {
1141
1141
  const trimmed = input.trim().toLowerCase();
1142
1142
  if (LEGACY_APP_KEY_PATTERN.test(trimmed)) {
@@ -1259,7 +1259,7 @@ function createConfigFromComponents(input) {
1259
1259
  });
1260
1260
  }
1261
1261
  throw new SylphxError(
1262
- `[Sylphx] Invalid credential format. Expected (pk|sk)_(dev|stg|prod|prev)_[a-f0-9]{32,64}. Got: "${trimmedCred.slice(0, 30)}..."`,
1262
+ `[Sylphx] Invalid credential format. Expected (pk|sk)_(dev|stg|prod|prev)(_{ref})?_{hex}. Got: "${trimmedCred.slice(0, 30)}..."`,
1263
1263
  { code: "BAD_REQUEST" }
1264
1264
  );
1265
1265
  }
@@ -2748,6 +2748,7 @@ var ORG_STORAGE_KEY = "sylphx_active_org";
2748
2748
  var ORG_BROADCAST_CHANNEL = "sylphx_org_sync";
2749
2749
  function useOrganization() {
2750
2750
  const platform = useContext4(PlatformContext);
2751
+ const auth = useAuthContextSafe();
2751
2752
  const [organizations, setOrganizations] = useState4([]);
2752
2753
  const [organization, setOrganization] = useState4(null);
2753
2754
  const [members, setMembers] = useState4([]);
@@ -2824,6 +2825,9 @@ function useOrganization() {
2824
2825
  }
2825
2826
  try {
2826
2827
  const result = await getOrganization(config2, orgIdOrSlug);
2828
+ if (auth?.isSignedIn) {
2829
+ await auth.switchOrganizationToken(result.organization.id);
2830
+ }
2827
2831
  setOrganization(result.organization);
2828
2832
  setRole(result.membership?.role ?? null);
2829
2833
  storeOrgSlug(result.organization.slug);
@@ -2844,7 +2848,7 @@ function useOrganization() {
2844
2848
  setError(err instanceof Error ? err : new Error("Failed to load organization"));
2845
2849
  }
2846
2850
  },
2847
- [config2, storeOrgSlug, broadcastOrgChange]
2851
+ [auth, config2, storeOrgSlug, broadcastOrgChange]
2848
2852
  );
2849
2853
  useEffect3(() => {
2850
2854
  if (!config2) {
@@ -3006,6 +3010,7 @@ function useOrganization() {
3006
3010
  role,
3007
3011
  hasPermission: hasPermission2,
3008
3012
  setOrganization: selectOrganization,
3013
+ switchOrg: selectOrganization,
3009
3014
  createOrganization: createOrg,
3010
3015
  updateOrganization: updateOrg,
3011
3016
  deleteOrganization: deleteOrg,
@@ -11543,13 +11548,14 @@ async function linkAnonymousConsents(config2, input) {
11543
11548
  init_constants();
11544
11549
 
11545
11550
  // src/key-validation.ts
11546
- var PUBLIC_KEY_PATTERN = /^pk_(dev|stg|prod)_[a-z0-9]{12}_[a-f0-9]{32}$/;
11551
+ var PUBLIC_KEY_PATTERN = /^pk_(dev|stg|prod|prev)(?:_[a-z0-9]{12})?_[a-f0-9]{32}$/;
11547
11552
  var APP_ID_PATTERN = /^(app|pk)_(dev|stg|prod|prev)_[a-z0-9_-]+$/;
11548
- var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod)_[a-z0-9_-]+$/;
11553
+ var SECRET_KEY_PATTERN = /^sk_(dev|stg|prod|prev)_[a-z0-9_-]+$/;
11549
11554
  var ENV_PREFIX_MAP = {
11550
11555
  dev: "development",
11551
11556
  stg: "staging",
11552
- prod: "production"
11557
+ prod: "production",
11558
+ prev: "preview"
11553
11559
  };
11554
11560
  function detectKeyIssues(key) {
11555
11561
  const issues = [];
@@ -11574,7 +11580,7 @@ The SDK will automatically sanitize the key, but fixing the source is recommende
11574
11580
  }
11575
11581
  function createInvalidKeyError(keyType, key, envVarName) {
11576
11582
  const maskedKey = key.length > 20 ? `${key.slice(0, 20)}...` : key;
11577
- const formatHint = keyType === "appId" ? "pk_(dev|stg|prod)_{ref}_{hex} or app_(dev|stg|prod)_[id]" : "sk_(dev|stg|prod)_{ref}_{hex}";
11583
+ const formatHint = keyType === "appId" ? "pk_(dev|stg|prod|prev)_{ref}_{hex} or app_(dev|stg|prod|prev)_[id]" : "sk_(dev|stg|prod|prev)_{ref}_{hex}";
11578
11584
  const keyTypeName = keyType === "appId" ? "App ID" : "Secret Key";
11579
11585
  return `[Sylphx] Invalid ${keyTypeName} format.
11580
11586
 
@@ -11587,7 +11593,7 @@ You can find your keys in the Sylphx Console \u2192 API Keys.
11587
11593
  Common issues:
11588
11594
  \u2022 Key has uppercase characters (must be lowercase)
11589
11595
  \u2022 Key has wrong prefix (App ID: pk_ or app_, Secret Key: sk_)
11590
- \u2022 Key has invalid environment (must be dev, stg, or prod)
11596
+ \u2022 Key has invalid environment (must be dev, stg, prod, or prev)
11591
11597
  \u2022 Key was copied with extra whitespace`;
11592
11598
  }
11593
11599
  function extractEnvironment(key) {
@@ -11634,7 +11640,7 @@ function validateKeyForType(key, keyType, pattern, envVarName) {
11634
11640
  };
11635
11641
  }
11636
11642
  function validatePublicKey(key) {
11637
- return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "NEXT_PUBLIC_SYLPHX_KEY");
11643
+ return validateKeyForType(key, "publicKey", PUBLIC_KEY_PATTERN, "publishable credential");
11638
11644
  }
11639
11645
  function validateAppId(key) {
11640
11646
  return validateKeyForType(key, "appId", APP_ID_PATTERN, "NEXT_PUBLIC_SYLPHX_APP_ID");
@@ -11650,7 +11656,7 @@ function validateAndSanitizeAppId(key) {
11650
11656
  return result.sanitizedKey;
11651
11657
  }
11652
11658
  function validateSecretKey(key) {
11653
- return validateKeyForType(key, "secret", SECRET_KEY_PATTERN, "SYLPHX_SECRET_KEY");
11659
+ return validateKeyForType(key, "secret", SECRET_KEY_PATTERN, "secret credential");
11654
11660
  }
11655
11661
  function validateAndSanitizeSecretKey(key) {
11656
11662
  const result = validateSecretKey(key);
@@ -11691,7 +11697,7 @@ function isProductionKey(key) {
11691
11697
  }
11692
11698
  function getCookieNamespace(secretKey) {
11693
11699
  const env = detectEnvironment(secretKey);
11694
- const shortEnv = env === "development" ? "dev" : env === "staging" ? "stg" : "prod";
11700
+ const shortEnv = env === "development" ? "dev" : env === "staging" ? "stg" : env === "preview" ? "prev" : "prod";
11695
11701
  return `sylphx_${shortEnv}`;
11696
11702
  }
11697
11703
  function detectKeyType(key) {
@@ -11721,7 +11727,7 @@ function validateKey(key) {
11721
11727
  return {
11722
11728
  valid: false,
11723
11729
  sanitizedKey: "",
11724
- error: key ? `Invalid key format. Keys must start with 'pk_' (publishable), 'app_' (legacy), or 'sk_' (secret), followed by environment (dev/stg/prod). Got: ${key.slice(0, 20)}...` : "API key is required but was not provided.",
11730
+ error: key ? `Invalid key format. Keys must start with 'pk_' (publishable), 'app_' (legacy), or 'sk_' (secret), followed by environment (dev/stg/prod/prev). Got: ${key.slice(0, 20)}...` : "API key is required but was not provided.",
11725
11731
  issues: key ? ["invalid_format"] : ["missing"]
11726
11732
  };
11727
11733
  }
@@ -13034,6 +13040,8 @@ function SylphxProviderInner({
13034
13040
  user: event.data.user,
13035
13041
  error: null
13036
13042
  }));
13043
+ } else if (event.data?.type === "org-token-change") {
13044
+ tokenManager.invalidate();
13037
13045
  }
13038
13046
  };
13039
13047
  channel.addEventListener("message", handleMessage);
@@ -13041,7 +13049,7 @@ function SylphxProviderInner({
13041
13049
  channel.removeEventListener("message", handleMessage);
13042
13050
  channel.close();
13043
13051
  };
13044
- }, [appId]);
13052
+ }, [appId, tokenManager]);
13045
13053
  useEffect23(() => {
13046
13054
  const handleVisibilityChange = () => {
13047
13055
  if (document.visibilityState === "visible") {
@@ -13166,6 +13174,39 @@ function SylphxProviderInner({
13166
13174
  return null;
13167
13175
  }
13168
13176
  }, [authState.isSignedIn, authPrefix]);
13177
+ const switchOrganizationToken = useCallback27(
13178
+ async (orgId) => {
13179
+ if (!authState.isSignedIn) {
13180
+ throw new Error("Not authenticated");
13181
+ }
13182
+ const response = await fetch(`${authPrefix}/switch-org`, {
13183
+ method: "POST",
13184
+ headers: { "Content-Type": "application/json" },
13185
+ credentials: "include",
13186
+ body: JSON.stringify({ orgId })
13187
+ });
13188
+ if (!response.ok) {
13189
+ const data = await response.json().catch(() => ({}));
13190
+ throw new Error(data.error || data.message || "Failed to switch organization");
13191
+ }
13192
+ tokenManager.invalidate();
13193
+ setAuthState((prev) => ({
13194
+ ...prev,
13195
+ isLoaded: true,
13196
+ isSignedIn: true,
13197
+ error: null
13198
+ }));
13199
+ if (typeof window !== "undefined" && typeof BroadcastChannel !== "undefined") {
13200
+ try {
13201
+ const channel = new BroadcastChannel(`sylphx-auth-${appId}`);
13202
+ channel.postMessage({ type: "org-token-change" });
13203
+ channel.close();
13204
+ } catch {
13205
+ }
13206
+ }
13207
+ },
13208
+ [appId, authPrefix, authState.isSignedIn, tokenManager]
13209
+ );
13169
13210
  const resetPassword = useCallback27(
13170
13211
  async (options) => {
13171
13212
  await api.post("/auth/reset-password", {
@@ -14326,6 +14367,7 @@ function SylphxProviderInner({
14326
14367
  signUp,
14327
14368
  signOut,
14328
14369
  getToken,
14370
+ switchOrganizationToken,
14329
14371
  resetPassword,
14330
14372
  verifyEmail,
14331
14373
  resendVerificationEmail,
@@ -14349,6 +14391,7 @@ function SylphxProviderInner({
14349
14391
  signUp,
14350
14392
  signOut,
14351
14393
  getToken,
14394
+ switchOrganizationToken,
14352
14395
  resetPassword,
14353
14396
  verifyEmail,
14354
14397
  resendVerificationEmail,
@@ -14368,6 +14411,7 @@ function SylphxProviderInner({
14368
14411
  () => ({
14369
14412
  appId,
14370
14413
  platformUrl,
14414
+ authPrefix,
14371
14415
  slug: resolvedRef,
14372
14416
  ref: resolvedRef,
14373
14417
  anonymousId,
@@ -14443,6 +14487,7 @@ function SylphxProviderInner({
14443
14487
  api,
14444
14488
  appId,
14445
14489
  platformUrl,
14490
+ authPrefix,
14446
14491
  anonymousId,
14447
14492
  queryClient,
14448
14493
  clickIds,
@@ -14774,7 +14819,6 @@ var PATHS = {
14774
14819
  versions: (id) => `/storage/files/${encodeURIComponent(String(id))}/versions`,
14775
14820
  versionRestore: (id, vid) => `/storage/files/${encodeURIComponent(String(id))}/versions/${encodeURIComponent(String(vid))}:restore`
14776
14821
  };
14777
- var isBrowser = () => typeof globalThis !== "undefined" && typeof globalThis.window !== "undefined";
14778
14822
  var hasXhr = () => typeof globalThis.XMLHttpRequest !== "undefined";
14779
14823
  var hasLocalStorage = () => {
14780
14824
  try {
@@ -14786,16 +14830,14 @@ var hasLocalStorage = () => {
14786
14830
  };
14787
14831
  async function computeSha256Hex(blob) {
14788
14832
  const subtle = globalThis.crypto?.subtle;
14789
- if (subtle?.digest) {
14790
- const buf2 = await blob.arrayBuffer();
14791
- const digest = await subtle.digest("SHA-256", buf2);
14792
- return bytesToHex(new Uint8Array(digest));
14833
+ if (!subtle?.digest) {
14834
+ throw new SylphxError("Web Crypto SHA-256 support is required for storage uploads", {
14835
+ code: "NOT_IMPLEMENTED"
14836
+ });
14793
14837
  }
14794
- const nodeCrypto = await import("crypto");
14795
- const hash = nodeCrypto.createHash("sha256");
14796
- const buf = Buffer.from(await blob.arrayBuffer());
14797
- hash.update(buf);
14798
- return hash.digest("hex");
14838
+ const buf = await blob.arrayBuffer();
14839
+ const digest = await subtle.digest("SHA-256", buf);
14840
+ return bytesToHex(new Uint8Array(digest));
14799
14841
  }
14800
14842
  function bytesToHex(b2) {
14801
14843
  let s2 = "";
@@ -14812,10 +14854,6 @@ function persistResume(rec) {
14812
14854
  localStorage.setItem(resumeKey(rec.uploadId), JSON.stringify(rec));
14813
14855
  } catch {
14814
14856
  }
14815
- return;
14816
- }
14817
- if (!isBrowser()) {
14818
- void persistResumeNode(rec);
14819
14857
  }
14820
14858
  }
14821
14859
  function clearResume(uploadId) {
@@ -14824,41 +14862,6 @@ function clearResume(uploadId) {
14824
14862
  localStorage.removeItem(resumeKey(uploadId));
14825
14863
  } catch {
14826
14864
  }
14827
- return;
14828
- }
14829
- if (!isBrowser()) void clearResumeNode(uploadId);
14830
- }
14831
- async function persistResumeNode(rec) {
14832
- try {
14833
- const fs = await import("fs/promises");
14834
- const path = await import("path");
14835
- const os = await import("os");
14836
- const dir = path.join(os.homedir(), ".sylphx");
14837
- await fs.mkdir(dir, { recursive: true });
14838
- const file = path.join(dir, "uploads.json");
14839
- let store = {};
14840
- try {
14841
- const text = await fs.readFile(file, "utf8");
14842
- store = JSON.parse(text);
14843
- } catch {
14844
- store = {};
14845
- }
14846
- store[rec.uploadId] = rec;
14847
- await fs.writeFile(file, JSON.stringify(store), "utf8");
14848
- } catch {
14849
- }
14850
- }
14851
- async function clearResumeNode(uploadId) {
14852
- try {
14853
- const fs = await import("fs/promises");
14854
- const path = await import("path");
14855
- const os = await import("os");
14856
- const file = path.join(os.homedir(), ".sylphx", "uploads.json");
14857
- const text = await fs.readFile(file, "utf8");
14858
- const store = JSON.parse(text);
14859
- delete store[uploadId];
14860
- await fs.writeFile(file, JSON.stringify(store), "utf8");
14861
- } catch {
14862
14865
  }
14863
14866
  }
14864
14867
  function putBlob(url, body, headers, signal, onProgress) {
@@ -15212,6 +15215,7 @@ var storageKeys = {
15212
15215
  function useStorage() {
15213
15216
  const config2 = useSdkConfig2();
15214
15217
  const queryClient = useQueryClient6();
15218
+ const [progress, setProgress] = useState31(0);
15215
15219
  const listQuery = useQuery7({
15216
15220
  queryKey: storageKeys.list({}),
15217
15221
  queryFn: async () => {
@@ -15224,26 +15228,46 @@ function useStorage() {
15224
15228
  const uploadMutation = useMutation2({
15225
15229
  mutationFn: async (input) => {
15226
15230
  if (!config2) throw new Error("SDK not configured \u2014 wrap your app in SylphxProvider");
15227
- return storage.uploads.create(config2, input.blob, input.options ?? {});
15231
+ setProgress(0);
15232
+ return storage.uploads.create(config2, input.blob, {
15233
+ ...input.options ?? {},
15234
+ onProgress: (event) => {
15235
+ const nextProgress = event.total > 0 ? Math.min(100, Math.round(event.loaded / event.total * 100)) : 0;
15236
+ setProgress(nextProgress);
15237
+ input.options?.onProgress?.(event);
15238
+ }
15239
+ });
15228
15240
  },
15229
15241
  onSuccess: () => {
15242
+ setProgress(100);
15230
15243
  void queryClient.invalidateQueries({ queryKey: storageKeys.lists() });
15244
+ },
15245
+ onError: () => {
15246
+ setProgress(0);
15231
15247
  }
15232
15248
  });
15233
15249
  const upload = useCallback29(
15234
15250
  (blob, options) => uploadMutation.mutateAsync({ blob, options }),
15235
15251
  [uploadMutation]
15236
15252
  );
15253
+ const uploadAvatar = useCallback29(
15254
+ (blob, options) => upload(blob, { visibility: "public", folder: "avatars", ...options }),
15255
+ [upload]
15256
+ );
15237
15257
  const refetch = useCallback29(async () => {
15238
15258
  await listQuery.refetch();
15239
15259
  }, [listQuery]);
15240
15260
  const error = uploadMutation.error ?? listQuery.error;
15261
+ const uploadError = uploadMutation.error;
15241
15262
  return {
15242
15263
  upload,
15264
+ uploadAvatar,
15243
15265
  files: listQuery.data?.files,
15244
15266
  isUploading: uploadMutation.isPending,
15245
15267
  isLoadingFiles: listQuery.isLoading,
15268
+ progress,
15246
15269
  error,
15270
+ uploadError,
15247
15271
  refetch
15248
15272
  };
15249
15273
  }
@@ -36155,23 +36179,24 @@ var mixpanelHandler = {
36155
36179
  const { token, debug } = config2;
36156
36180
  ((f2, b2) => {
36157
36181
  if (!b2) return;
36158
- const c2 = {};
36159
- c2._i = [];
36160
- c2.init = (e2, f3) => {
36161
- c2._i.push([e2, f3]);
36162
- };
36163
- c2.track = (...args) => {
36164
- c2._i[0]?.[2]?.track?.(...args);
36165
- };
36166
- c2.identify = (...args) => {
36167
- c2._i[0]?.[2]?.identify?.(...args);
36168
- };
36169
- c2.people = {
36170
- // biome-ignore lint/suspicious/noExplicitAny: Mixpanel SDK vendor snippet — matches Mixpanel's own typings
36171
- set: (...args) => {
36172
- c2._i[0]?.[2]?.people?.set?.(...args);
36182
+ const c2 = {
36183
+ _i: [],
36184
+ init: (token2, options = {}) => {
36185
+ c2._i.push([token2, options]);
36186
+ },
36187
+ track: (...args) => {
36188
+ c2._i[0]?.[2]?.track?.(String(args[0] ?? ""), args[1]);
36189
+ },
36190
+ identify: (...args) => {
36191
+ c2._i[0]?.[2]?.identify?.(String(args[0] ?? ""));
36192
+ },
36193
+ people: {
36194
+ set: (...args) => {
36195
+ c2._i[0]?.[2]?.people?.set?.(args[0]);
36196
+ }
36173
36197
  }
36174
36198
  };
36199
+ c2._i = [];
36175
36200
  const a2 = b2.createElement("script");
36176
36201
  a2.type = "text/javascript";
36177
36202
  a2.async = true;
@@ -36231,14 +36256,16 @@ var segmentHandler = {
36231
36256
  "setAnonymousId",
36232
36257
  "addDestinationMiddleware"
36233
36258
  ];
36234
- analytics.factory = // biome-ignore lint/suspicious/noExplicitAny: Segment SDK vendor snippet — returns a stub function that matches any Segment analytics method signature
36235
- (e2) => (...args) => {
36236
- args.unshift(e2);
36237
- analytics.push(args);
36238
- return analytics;
36259
+ analytics.factory = (method) => {
36260
+ return (...args) => {
36261
+ args.unshift(method);
36262
+ analytics.push(args);
36263
+ return analytics;
36264
+ };
36239
36265
  };
36240
36266
  for (let e2 = 0; e2 < analytics.methods.length; e2++) {
36241
36267
  const key = analytics.methods[e2];
36268
+ if (!key) continue;
36242
36269
  analytics[key] = analytics.factory(key);
36243
36270
  }
36244
36271
  analytics.load = (key, e2) => {
@@ -36270,7 +36297,24 @@ var posthogHandler = {
36270
36297
  const { apiKey, apiHost = "https://us.i.posthog.com" } = config2;
36271
36298
  ((t2, e2) => {
36272
36299
  if (!e2) return;
36273
- const o2 = {};
36300
+ const o2 = {
36301
+ __load_queue: [],
36302
+ _i: [],
36303
+ people: {
36304
+ set: (...args) => {
36305
+ o2.__load_queue.push(["people.set", args]);
36306
+ }
36307
+ },
36308
+ init: (apiKey2, config3) => {
36309
+ o2._i.push([apiKey2, config3]);
36310
+ const r2 = e2.createElement("script");
36311
+ r2.type = "text/javascript";
36312
+ r2.async = true;
36313
+ r2.src = "https://us-assets.i.posthog.com/static/array.js";
36314
+ const s2 = e2.getElementsByTagName("script")[0];
36315
+ s2.parentNode?.insertBefore(r2, s2);
36316
+ }
36317
+ };
36274
36318
  let n2;
36275
36319
  const p2 = [
36276
36320
  "snapshot",
@@ -36296,27 +36340,10 @@ var posthogHandler = {
36296
36340
  for (n2 of p2) {
36297
36341
  o2[n2] = /* @__PURE__ */ ((n3) => (...args) => {
36298
36342
  if (!o2.__loaded) {
36299
- o2.__load_queue = o2.__load_queue || [];
36300
36343
  o2.__load_queue.push([n3, args]);
36301
36344
  }
36302
36345
  })(n2);
36303
36346
  }
36304
- o2.people = {
36305
- // biome-ignore lint/suspicious/noExplicitAny: PostHog SDK vendor snippet — matches PostHog's own typings
36306
- set: (...args) => {
36307
- o2.__load_queue.push(["people.set", args]);
36308
- }
36309
- };
36310
- o2._i = [];
36311
- o2.init = (apiKey2, config3) => {
36312
- o2._i.push([apiKey2, config3]);
36313
- const r2 = e2.createElement("script");
36314
- r2.type = "text/javascript";
36315
- r2.async = true;
36316
- r2.src = "https://us-assets.i.posthog.com/static/array.js";
36317
- const s2 = e2.getElementsByTagName("script")[0];
36318
- s2.parentNode?.insertBefore(r2, s2);
36319
- };
36320
36347
  t2.posthog = o2;
36321
36348
  })(window, document);
36322
36349
  window.posthog?.init(apiKey, { api_host: apiHost });
@@ -36336,25 +36363,26 @@ var amplitudeHandler = {
36336
36363
  const { apiKey, serverUrl } = config2;
36337
36364
  ((e2, t2) => {
36338
36365
  if (!t2) return;
36339
- const r2 = {};
36340
- r2._q = [];
36341
- r2.track = (...args) => {
36342
- r2._q.push(["track", args]);
36343
- };
36344
- r2.identify = (...args) => {
36345
- r2._q.push(["identify", args]);
36346
- };
36347
- r2.setUserId = (...args) => {
36348
- r2._q.push(["setUserId", args]);
36349
- };
36350
- r2.init = (apiKey2, options) => {
36351
- r2._q.push(["init", [apiKey2, options]]);
36352
- const n2 = t2.createElement("script");
36353
- n2.type = "text/javascript";
36354
- n2.async = true;
36355
- n2.src = "https://cdn.amplitude.com/libs/analytics-browser-2.0.0-min.js.gz";
36356
- const o2 = t2.getElementsByTagName("script")[0];
36357
- o2.parentNode?.insertBefore(n2, o2);
36366
+ const r2 = {
36367
+ _q: [],
36368
+ track: (...args) => {
36369
+ r2._q.push(["track", [...args]]);
36370
+ },
36371
+ identify: (...args) => {
36372
+ r2._q.push(["identify", [...args]]);
36373
+ },
36374
+ setUserId: (...args) => {
36375
+ r2._q.push(["setUserId", [...args]]);
36376
+ },
36377
+ init: (apiKey2, options) => {
36378
+ r2._q.push(["init", [apiKey2, options]]);
36379
+ const n2 = t2.createElement("script");
36380
+ n2.type = "text/javascript";
36381
+ n2.async = true;
36382
+ n2.src = "https://cdn.amplitude.com/libs/analytics-browser-2.0.0-min.js.gz";
36383
+ const o2 = t2.getElementsByTagName("script")[0];
36384
+ o2.parentNode?.insertBefore(n2, o2);
36385
+ }
36358
36386
  };
36359
36387
  e2.amplitude = r2;
36360
36388
  })(window, document);
@@ -38018,7 +38046,7 @@ function createTasksHandler(taskDefs, options = {}) {
38018
38046
  { status: 400 }
38019
38047
  );
38020
38048
  }
38021
- const signingSecret = options.signingSecret ?? process.env.SYLPHX_SIGNING_SECRET ?? process.env.SYLPHX_SECRET_KEY ?? "";
38049
+ const signingSecret = options.signingSecret ?? process.env.SYLPHX_SIGNING_SECRET ?? "";
38022
38050
  if (signingSecret) {
38023
38051
  const signature = req.headers.get("x-sylphx-signature") ?? "";
38024
38052
  if (!signature) {
@@ -38249,7 +38277,9 @@ var TasksClient = class {
38249
38277
  const params = new URLSearchParams();
38250
38278
  if (options?.limit) params.set("limit", String(options.limit));
38251
38279
  if (options?.offset) params.set("offset", String(options.offset));
38252
- const response = await this.fetch(`/jobs/dlq?${params.toString()}`);
38280
+ const response = await this.fetch(
38281
+ `/jobs/dlq?${params.toString()}`
38282
+ );
38253
38283
  return { entries: response.entries, total: response.total };
38254
38284
  }
38255
38285
  /**
@@ -38294,7 +38324,9 @@ var TasksClient = class {
38294
38324
  * Get a workflow by ID
38295
38325
  */
38296
38326
  async getWorkflow(workflowId) {
38297
- const response = await this.fetch(`/workflows/${workflowId}`);
38327
+ const response = await this.fetch(
38328
+ `/workflows/${workflowId}`
38329
+ );
38298
38330
  return response.workflow;
38299
38331
  }
38300
38332
  /**
@@ -38315,7 +38347,9 @@ var TasksClient = class {
38315
38347
  if (options?.status) params.set("status", options.status);
38316
38348
  if (options?.limit) params.set("limit", String(options.limit));
38317
38349
  if (options?.offset) params.set("offset", String(options.offset));
38318
- const response = await this.fetch(`/workflows?${params.toString()}`);
38350
+ const response = await this.fetch(
38351
+ `/workflows?${params.toString()}`
38352
+ );
38319
38353
  return { workflows: response.workflows, total: response.total };
38320
38354
  }
38321
38355
  // =========================================================================
@@ -38329,25 +38363,33 @@ var TasksClient = class {
38329
38363
  if (options?.status) params.set("status", options.status);
38330
38364
  if (options?.limit) params.set("limit", String(options.limit));
38331
38365
  if (options?.offset) params.set("offset", String(options.offset));
38332
- const response = await this.fetch(`/jobs/scheduled?${params.toString()}`);
38366
+ const response = await this.fetch(
38367
+ `/jobs/scheduled?${params.toString()}`
38368
+ );
38333
38369
  return { scheduled: response.scheduled, total: response.total };
38334
38370
  }
38335
38371
  /**
38336
38372
  * Pause a scheduled job
38337
38373
  */
38338
38374
  async pauseScheduledJob(scheduleId) {
38339
- const response = await this.fetch(`/jobs/scheduled/${scheduleId}/pause`, {
38340
- method: "POST"
38341
- });
38375
+ const response = await this.fetch(
38376
+ `/jobs/scheduled/${scheduleId}/pause`,
38377
+ {
38378
+ method: "POST"
38379
+ }
38380
+ );
38342
38381
  return response.scheduled;
38343
38382
  }
38344
38383
  /**
38345
38384
  * Resume a scheduled job
38346
38385
  */
38347
38386
  async resumeScheduledJob(scheduleId) {
38348
- const response = await this.fetch(`/jobs/scheduled/${scheduleId}/resume`, {
38349
- method: "POST"
38350
- });
38387
+ const response = await this.fetch(
38388
+ `/jobs/scheduled/${scheduleId}/resume`,
38389
+ {
38390
+ method: "POST"
38391
+ }
38392
+ );
38351
38393
  return response.scheduled;
38352
38394
  }
38353
38395
  /**
@@ -38389,7 +38431,6 @@ var TasksClient = class {
38389
38431
  // =========================================================================
38390
38432
  // Internal
38391
38433
  // =========================================================================
38392
- // biome-ignore lint/suspicious/noExplicitAny: Internal method, type safety enforced at public API level -- Internal method, type safety enforced at public API level
38393
38434
  async fetch(path, options) {
38394
38435
  const url = `${this.config.apiEndpoint}${path}`;
38395
38436
  const response = await fetch(url, {
@@ -38403,10 +38444,12 @@ var TasksClient = class {
38403
38444
  }
38404
38445
  });
38405
38446
  if (!response.ok) {
38406
- const error = await response.json().catch(() => ({ message: response.statusText }));
38407
- throw new Error(error.message || `HTTP ${response.status}`);
38447
+ const errorPayload = await response.json().catch(() => ({ message: response.statusText }));
38448
+ const message = typeof errorPayload === "object" && errorPayload !== null && "message" in errorPayload && typeof errorPayload.message === "string" ? errorPayload.message : response.statusText;
38449
+ throw new Error(message || `HTTP ${response.status}`);
38408
38450
  }
38409
- return response.json();
38451
+ const payload = await response.json();
38452
+ return payload;
38410
38453
  }
38411
38454
  // =========================================================================
38412
38455
  // Native Task Engine — Handler API
@@ -38449,31 +38492,35 @@ var TasksClient = class {
38449
38492
  * Returns the taskRunId which can be used to poll status.
38450
38493
  */
38451
38494
  async trigger(taskName, payload, options) {
38452
- const response = await this.fetch("/tasks/trigger", {
38453
- method: "POST",
38454
- body: JSON.stringify({
38455
- taskName,
38456
- payload,
38457
- delay: options?.delay,
38458
- scheduledFor: options?.scheduledFor?.toISOString(),
38459
- idempotencyKey: options?.idempotencyKey,
38460
- maxAttempts: options?.maxAttempts
38461
- })
38462
- });
38495
+ const response = await this.fetch(
38496
+ "/tasks/trigger",
38497
+ {
38498
+ method: "POST",
38499
+ body: JSON.stringify({
38500
+ taskName,
38501
+ payload,
38502
+ delay: options?.delay,
38503
+ scheduledFor: options?.scheduledFor?.toISOString(),
38504
+ idempotencyKey: options?.idempotencyKey,
38505
+ maxAttempts: options?.maxAttempts
38506
+ })
38507
+ }
38508
+ );
38463
38509
  return response;
38464
38510
  }
38465
38511
  /**
38466
38512
  * Fetch the current status of a task run.
38467
38513
  */
38468
38514
  async getTaskRun(taskRunId) {
38469
- const response = await this.fetch(`/tasks/${taskRunId}`);
38470
- return response;
38515
+ return this.fetch(`/tasks/${taskRunId}`);
38471
38516
  }
38472
38517
  /**
38473
38518
  * Cancel a pending or waiting task run.
38474
38519
  */
38475
38520
  async cancelTaskRun(taskRunId) {
38476
- const response = await this.fetch(`/tasks/${taskRunId}/cancel`, { method: "POST" });
38521
+ const response = await this.fetch(`/tasks/${taskRunId}/cancel`, {
38522
+ method: "POST"
38523
+ });
38477
38524
  return response.success;
38478
38525
  }
38479
38526
  /**
@@ -38485,8 +38532,7 @@ var TasksClient = class {
38485
38532
  if (options?.status) params.set("status", options.status);
38486
38533
  if (options?.limit) params.set("limit", String(options.limit));
38487
38534
  if (options?.offset) params.set("offset", String(options.offset));
38488
- const response = await this.fetch(`/tasks?${params.toString()}`);
38489
- return response;
38535
+ return this.fetch(`/tasks?${params.toString()}`);
38490
38536
  }
38491
38537
  };
38492
38538
  function createTasksClient(config2) {