@djangocfg/ext-newsletter 1.0.9 → 1.0.10

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/config.cjs CHANGED
@@ -27,7 +27,7 @@ var import_ext_base = require("@djangocfg/ext-base");
27
27
  // package.json
28
28
  var package_default = {
29
29
  name: "@djangocfg/ext-newsletter",
30
- version: "1.0.9",
30
+ version: "1.0.10",
31
31
  description: "Newsletter and subscription management extension for DjangoCFG",
32
32
  keywords: [
33
33
  "django",
package/dist/config.js CHANGED
@@ -4,7 +4,7 @@ import { createExtensionConfig } from "@djangocfg/ext-base";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "@djangocfg/ext-newsletter",
7
- version: "1.0.9",
7
+ version: "1.0.10",
8
8
  description: "Newsletter and subscription management extension for DjangoCFG",
9
9
  keywords: [
10
10
  "django",
package/dist/hooks.cjs CHANGED
@@ -278,7 +278,7 @@ var models_exports7 = {};
278
278
  // src/api/generated/ext_newsletter/http.ts
279
279
  var FetchAdapter = class {
280
280
  async request(request) {
281
- const { method, url, headers, body, params, formData } = request;
281
+ const { method, url, headers, body, params, formData, binaryBody } = request;
282
282
  let finalUrl = url;
283
283
  if (params) {
284
284
  const searchParams = new URLSearchParams();
@@ -296,6 +296,9 @@ var FetchAdapter = class {
296
296
  let requestBody;
297
297
  if (formData) {
298
298
  requestBody = formData;
299
+ } else if (binaryBody) {
300
+ finalHeaders["Content-Type"] = "application/octet-stream";
301
+ requestBody = binaryBody;
299
302
  } else if (body) {
300
303
  finalHeaders["Content-Type"] = "application/json";
301
304
  requestBody = JSON.stringify(body);
@@ -620,6 +623,7 @@ var APIClient = class {
620
623
  httpClient;
621
624
  logger = null;
622
625
  retryConfig = null;
626
+ tokenGetter = null;
623
627
  // Sub-clients
624
628
  ext_newsletter_bulk_email;
625
629
  ext_newsletter_campaigns;
@@ -631,6 +635,7 @@ var APIClient = class {
631
635
  constructor(baseUrl, options) {
632
636
  this.baseUrl = baseUrl.replace(/\/$/, "");
633
637
  this.httpClient = options?.httpClient || new FetchAdapter();
638
+ this.tokenGetter = options?.tokenGetter || null;
634
639
  if (options?.loggerConfig !== void 0) {
635
640
  this.logger = new APILogger(options.loggerConfig);
636
641
  }
@@ -659,6 +664,19 @@ var APIClient = class {
659
664
  }
660
665
  return null;
661
666
  }
667
+ /**
668
+ * Get the base URL for building streaming/download URLs.
669
+ */
670
+ getBaseUrl() {
671
+ return this.baseUrl;
672
+ }
673
+ /**
674
+ * Get JWT token for URL authentication (used in streaming endpoints).
675
+ * Returns null if no token getter is configured or no token is available.
676
+ */
677
+ getToken() {
678
+ return this.tokenGetter ? this.tokenGetter() : null;
679
+ }
662
680
  /**
663
681
  * Make HTTP request with Django CSRF and session handling.
664
682
  * Automatically retries on network errors and 5xx server errors.
@@ -689,7 +707,7 @@ var APIClient = class {
689
707
  const headers = {
690
708
  ...options?.headers || {}
691
709
  };
692
- if (!options?.formData && !headers["Content-Type"]) {
710
+ if (!options?.formData && !options?.binaryBody && !headers["Content-Type"]) {
693
711
  headers["Content-Type"] = "application/json";
694
712
  }
695
713
  if (this.logger) {
@@ -708,7 +726,8 @@ var APIClient = class {
708
726
  headers,
709
727
  params: options?.params,
710
728
  body: options?.body,
711
- formData: options?.formData
729
+ formData: options?.formData,
730
+ binaryBody: options?.binaryBody
712
731
  });
713
732
  const duration = Date.now() - startTime;
714
733
  if (response.status >= 400) {
@@ -989,7 +1008,7 @@ var BulkEmailRequestSchema = zod.z.object({
989
1008
  main_text: zod.z.string().min(1),
990
1009
  main_html_content: zod.z.string().optional(),
991
1010
  button_text: zod.z.string().max(100).optional(),
992
- button_url: zod.z.url().optional(),
1011
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
993
1012
  secondary_text: zod.z.string().optional()
994
1013
  });
995
1014
  var BulkEmailResponseSchema = zod.z.object({
@@ -1036,7 +1055,7 @@ var NewsletterCampaignSchema = zod.z.object({
1036
1055
  main_text: zod.z.string(),
1037
1056
  main_html_content: zod.z.string().optional(),
1038
1057
  button_text: zod.z.string().max(100).optional(),
1039
- button_url: zod.z.url().optional(),
1058
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
1040
1059
  secondary_text: zod.z.string().optional(),
1041
1060
  status: zod.z.nativeEnum(NewsletterCampaignStatus),
1042
1061
  created_at: zod.z.iso.datetime(),
@@ -1050,7 +1069,7 @@ var NewsletterCampaignRequestSchema = zod.z.object({
1050
1069
  main_text: zod.z.string().min(1),
1051
1070
  main_html_content: zod.z.string().optional(),
1052
1071
  button_text: zod.z.string().max(100).optional(),
1053
- button_url: zod.z.url().optional(),
1072
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
1054
1073
  secondary_text: zod.z.string().optional()
1055
1074
  });
1056
1075
  var NewsletterSubscriptionSchema = zod.z.object({
@@ -1115,7 +1134,7 @@ var PatchedNewsletterCampaignRequestSchema = zod.z.object({
1115
1134
  main_text: zod.z.string().min(1).optional(),
1116
1135
  main_html_content: zod.z.string().optional(),
1117
1136
  button_text: zod.z.string().max(100).optional(),
1118
- button_url: zod.z.url().optional(),
1137
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
1119
1138
  secondary_text: zod.z.string().optional()
1120
1139
  });
1121
1140
  var PatchedUnsubscribeRequestSchema = zod.z.object({
@@ -1225,15 +1244,28 @@ __export(fetchers_exports, {
1225
1244
 
1226
1245
  // src/api/generated/ext_newsletter/api-instance.ts
1227
1246
  var globalAPI = null;
1247
+ var autoConfigAttempted = false;
1248
+ function tryAutoConfigureFromEnv() {
1249
+ if (autoConfigAttempted) return;
1250
+ autoConfigAttempted = true;
1251
+ if (globalAPI) return;
1252
+ if (typeof process === "undefined" || !process.env) return;
1253
+ const baseUrl = process.env.NEXT_PUBLIC_API_URL || process.env.VITE_API_URL || process.env.REACT_APP_API_URL || process.env.API_URL;
1254
+ if (baseUrl) {
1255
+ globalAPI = new API(baseUrl);
1256
+ }
1257
+ }
1228
1258
  function getAPIInstance() {
1259
+ tryAutoConfigureFromEnv();
1229
1260
  if (!globalAPI) {
1230
1261
  throw new Error(
1231
- 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })'
1262
+ 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })\n\nOr set environment variable: NEXT_PUBLIC_API_URL, VITE_API_URL, or REACT_APP_API_URL'
1232
1263
  );
1233
1264
  }
1234
1265
  return globalAPI;
1235
1266
  }
1236
1267
  function isAPIConfigured() {
1268
+ tryAutoConfigureFromEnv();
1237
1269
  return globalAPI !== null;
1238
1270
  }
1239
1271
  function configureAPI(config) {
@@ -1969,7 +2001,8 @@ var API = class {
1969
2001
  this._loadTokensFromStorage();
1970
2002
  this._client = new APIClient(this.baseUrl, {
1971
2003
  retryConfig: this.options?.retryConfig,
1972
- loggerConfig: this.options?.loggerConfig
2004
+ loggerConfig: this.options?.loggerConfig,
2005
+ tokenGetter: () => this.getToken()
1973
2006
  });
1974
2007
  this._injectAuthHeader();
1975
2008
  this.ext_newsletter_bulk_email = this._client.ext_newsletter_bulk_email;
@@ -1987,7 +2020,8 @@ var API = class {
1987
2020
  _reinitClients() {
1988
2021
  this._client = new APIClient(this.baseUrl, {
1989
2022
  retryConfig: this.options?.retryConfig,
1990
- loggerConfig: this.options?.loggerConfig
2023
+ loggerConfig: this.options?.loggerConfig,
2024
+ tokenGetter: () => this.getToken()
1991
2025
  });
1992
2026
  this._injectAuthHeader();
1993
2027
  this.ext_newsletter_bulk_email = this._client.ext_newsletter_bulk_email;
@@ -2084,12 +2118,13 @@ var API = class {
2084
2118
  return "./schema.json";
2085
2119
  }
2086
2120
  };
2121
+ api.initializeExtensionAPI(configureAPI);
2087
2122
  var apiNewsletter = api.createExtensionAPI(API);
2088
2123
 
2089
2124
  // package.json
2090
2125
  var package_default = {
2091
2126
  name: "@djangocfg/ext-newsletter",
2092
- version: "1.0.9",
2127
+ version: "1.0.10",
2093
2128
  description: "Newsletter and subscription management extension for DjangoCFG",
2094
2129
  keywords: [
2095
2130
  "django",
package/dist/hooks.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createConsola, consola } from 'consola';
2
2
  import pRetry, { AbortError } from 'p-retry';
3
3
  import { z } from 'zod';
4
- import { createExtensionAPI } from '@djangocfg/ext-base/api';
4
+ import { initializeExtensionAPI, createExtensionAPI } from '@djangocfg/ext-base/api';
5
5
  import { createExtensionConfig } from '@djangocfg/ext-base';
6
6
  import useSWR, { useSWRConfig } from 'swr';
7
7
  import { createContext, useContext, useState } from 'react';
@@ -271,7 +271,7 @@ var models_exports7 = {};
271
271
  // src/api/generated/ext_newsletter/http.ts
272
272
  var FetchAdapter = class {
273
273
  async request(request) {
274
- const { method, url, headers, body, params, formData } = request;
274
+ const { method, url, headers, body, params, formData, binaryBody } = request;
275
275
  let finalUrl = url;
276
276
  if (params) {
277
277
  const searchParams = new URLSearchParams();
@@ -289,6 +289,9 @@ var FetchAdapter = class {
289
289
  let requestBody;
290
290
  if (formData) {
291
291
  requestBody = formData;
292
+ } else if (binaryBody) {
293
+ finalHeaders["Content-Type"] = "application/octet-stream";
294
+ requestBody = binaryBody;
292
295
  } else if (body) {
293
296
  finalHeaders["Content-Type"] = "application/json";
294
297
  requestBody = JSON.stringify(body);
@@ -613,6 +616,7 @@ var APIClient = class {
613
616
  httpClient;
614
617
  logger = null;
615
618
  retryConfig = null;
619
+ tokenGetter = null;
616
620
  // Sub-clients
617
621
  ext_newsletter_bulk_email;
618
622
  ext_newsletter_campaigns;
@@ -624,6 +628,7 @@ var APIClient = class {
624
628
  constructor(baseUrl, options) {
625
629
  this.baseUrl = baseUrl.replace(/\/$/, "");
626
630
  this.httpClient = options?.httpClient || new FetchAdapter();
631
+ this.tokenGetter = options?.tokenGetter || null;
627
632
  if (options?.loggerConfig !== void 0) {
628
633
  this.logger = new APILogger(options.loggerConfig);
629
634
  }
@@ -652,6 +657,19 @@ var APIClient = class {
652
657
  }
653
658
  return null;
654
659
  }
660
+ /**
661
+ * Get the base URL for building streaming/download URLs.
662
+ */
663
+ getBaseUrl() {
664
+ return this.baseUrl;
665
+ }
666
+ /**
667
+ * Get JWT token for URL authentication (used in streaming endpoints).
668
+ * Returns null if no token getter is configured or no token is available.
669
+ */
670
+ getToken() {
671
+ return this.tokenGetter ? this.tokenGetter() : null;
672
+ }
655
673
  /**
656
674
  * Make HTTP request with Django CSRF and session handling.
657
675
  * Automatically retries on network errors and 5xx server errors.
@@ -682,7 +700,7 @@ var APIClient = class {
682
700
  const headers = {
683
701
  ...options?.headers || {}
684
702
  };
685
- if (!options?.formData && !headers["Content-Type"]) {
703
+ if (!options?.formData && !options?.binaryBody && !headers["Content-Type"]) {
686
704
  headers["Content-Type"] = "application/json";
687
705
  }
688
706
  if (this.logger) {
@@ -701,7 +719,8 @@ var APIClient = class {
701
719
  headers,
702
720
  params: options?.params,
703
721
  body: options?.body,
704
- formData: options?.formData
722
+ formData: options?.formData,
723
+ binaryBody: options?.binaryBody
705
724
  });
706
725
  const duration = Date.now() - startTime;
707
726
  if (response.status >= 400) {
@@ -982,7 +1001,7 @@ var BulkEmailRequestSchema = z.object({
982
1001
  main_text: z.string().min(1),
983
1002
  main_html_content: z.string().optional(),
984
1003
  button_text: z.string().max(100).optional(),
985
- button_url: z.url().optional(),
1004
+ button_url: z.union([z.url(), z.literal("")]).optional(),
986
1005
  secondary_text: z.string().optional()
987
1006
  });
988
1007
  var BulkEmailResponseSchema = z.object({
@@ -1029,7 +1048,7 @@ var NewsletterCampaignSchema = z.object({
1029
1048
  main_text: z.string(),
1030
1049
  main_html_content: z.string().optional(),
1031
1050
  button_text: z.string().max(100).optional(),
1032
- button_url: z.url().optional(),
1051
+ button_url: z.union([z.url(), z.literal("")]).optional(),
1033
1052
  secondary_text: z.string().optional(),
1034
1053
  status: z.nativeEnum(NewsletterCampaignStatus),
1035
1054
  created_at: z.iso.datetime(),
@@ -1043,7 +1062,7 @@ var NewsletterCampaignRequestSchema = z.object({
1043
1062
  main_text: z.string().min(1),
1044
1063
  main_html_content: z.string().optional(),
1045
1064
  button_text: z.string().max(100).optional(),
1046
- button_url: z.url().optional(),
1065
+ button_url: z.union([z.url(), z.literal("")]).optional(),
1047
1066
  secondary_text: z.string().optional()
1048
1067
  });
1049
1068
  var NewsletterSubscriptionSchema = z.object({
@@ -1108,7 +1127,7 @@ var PatchedNewsletterCampaignRequestSchema = z.object({
1108
1127
  main_text: z.string().min(1).optional(),
1109
1128
  main_html_content: z.string().optional(),
1110
1129
  button_text: z.string().max(100).optional(),
1111
- button_url: z.url().optional(),
1130
+ button_url: z.union([z.url(), z.literal("")]).optional(),
1112
1131
  secondary_text: z.string().optional()
1113
1132
  });
1114
1133
  var PatchedUnsubscribeRequestSchema = z.object({
@@ -1218,15 +1237,28 @@ __export(fetchers_exports, {
1218
1237
 
1219
1238
  // src/api/generated/ext_newsletter/api-instance.ts
1220
1239
  var globalAPI = null;
1240
+ var autoConfigAttempted = false;
1241
+ function tryAutoConfigureFromEnv() {
1242
+ if (autoConfigAttempted) return;
1243
+ autoConfigAttempted = true;
1244
+ if (globalAPI) return;
1245
+ if (typeof process === "undefined" || !process.env) return;
1246
+ const baseUrl = process.env.NEXT_PUBLIC_API_URL || process.env.VITE_API_URL || process.env.REACT_APP_API_URL || process.env.API_URL;
1247
+ if (baseUrl) {
1248
+ globalAPI = new API(baseUrl);
1249
+ }
1250
+ }
1221
1251
  function getAPIInstance() {
1252
+ tryAutoConfigureFromEnv();
1222
1253
  if (!globalAPI) {
1223
1254
  throw new Error(
1224
- 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })'
1255
+ 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })\n\nOr set environment variable: NEXT_PUBLIC_API_URL, VITE_API_URL, or REACT_APP_API_URL'
1225
1256
  );
1226
1257
  }
1227
1258
  return globalAPI;
1228
1259
  }
1229
1260
  function isAPIConfigured() {
1261
+ tryAutoConfigureFromEnv();
1230
1262
  return globalAPI !== null;
1231
1263
  }
1232
1264
  function configureAPI(config) {
@@ -1962,7 +1994,8 @@ var API = class {
1962
1994
  this._loadTokensFromStorage();
1963
1995
  this._client = new APIClient(this.baseUrl, {
1964
1996
  retryConfig: this.options?.retryConfig,
1965
- loggerConfig: this.options?.loggerConfig
1997
+ loggerConfig: this.options?.loggerConfig,
1998
+ tokenGetter: () => this.getToken()
1966
1999
  });
1967
2000
  this._injectAuthHeader();
1968
2001
  this.ext_newsletter_bulk_email = this._client.ext_newsletter_bulk_email;
@@ -1980,7 +2013,8 @@ var API = class {
1980
2013
  _reinitClients() {
1981
2014
  this._client = new APIClient(this.baseUrl, {
1982
2015
  retryConfig: this.options?.retryConfig,
1983
- loggerConfig: this.options?.loggerConfig
2016
+ loggerConfig: this.options?.loggerConfig,
2017
+ tokenGetter: () => this.getToken()
1984
2018
  });
1985
2019
  this._injectAuthHeader();
1986
2020
  this.ext_newsletter_bulk_email = this._client.ext_newsletter_bulk_email;
@@ -2077,12 +2111,13 @@ var API = class {
2077
2111
  return "./schema.json";
2078
2112
  }
2079
2113
  };
2114
+ initializeExtensionAPI(configureAPI);
2080
2115
  var apiNewsletter = createExtensionAPI(API);
2081
2116
 
2082
2117
  // package.json
2083
2118
  var package_default = {
2084
2119
  name: "@djangocfg/ext-newsletter",
2085
- version: "1.0.9",
2120
+ version: "1.0.10",
2086
2121
  description: "Newsletter and subscription management extension for DjangoCFG",
2087
2122
  keywords: [
2088
2123
  "django",
package/dist/index.cjs CHANGED
@@ -271,7 +271,7 @@ var models_exports7 = {};
271
271
  // src/api/generated/ext_newsletter/http.ts
272
272
  var FetchAdapter = class {
273
273
  async request(request) {
274
- const { method, url, headers, body, params, formData } = request;
274
+ const { method, url, headers, body, params, formData, binaryBody } = request;
275
275
  let finalUrl = url;
276
276
  if (params) {
277
277
  const searchParams = new URLSearchParams();
@@ -289,6 +289,9 @@ var FetchAdapter = class {
289
289
  let requestBody;
290
290
  if (formData) {
291
291
  requestBody = formData;
292
+ } else if (binaryBody) {
293
+ finalHeaders["Content-Type"] = "application/octet-stream";
294
+ requestBody = binaryBody;
292
295
  } else if (body) {
293
296
  finalHeaders["Content-Type"] = "application/json";
294
297
  requestBody = JSON.stringify(body);
@@ -613,6 +616,7 @@ var APIClient = class {
613
616
  httpClient;
614
617
  logger = null;
615
618
  retryConfig = null;
619
+ tokenGetter = null;
616
620
  // Sub-clients
617
621
  ext_newsletter_bulk_email;
618
622
  ext_newsletter_campaigns;
@@ -624,6 +628,7 @@ var APIClient = class {
624
628
  constructor(baseUrl, options) {
625
629
  this.baseUrl = baseUrl.replace(/\/$/, "");
626
630
  this.httpClient = options?.httpClient || new FetchAdapter();
631
+ this.tokenGetter = options?.tokenGetter || null;
627
632
  if (options?.loggerConfig !== void 0) {
628
633
  this.logger = new APILogger(options.loggerConfig);
629
634
  }
@@ -652,6 +657,19 @@ var APIClient = class {
652
657
  }
653
658
  return null;
654
659
  }
660
+ /**
661
+ * Get the base URL for building streaming/download URLs.
662
+ */
663
+ getBaseUrl() {
664
+ return this.baseUrl;
665
+ }
666
+ /**
667
+ * Get JWT token for URL authentication (used in streaming endpoints).
668
+ * Returns null if no token getter is configured or no token is available.
669
+ */
670
+ getToken() {
671
+ return this.tokenGetter ? this.tokenGetter() : null;
672
+ }
655
673
  /**
656
674
  * Make HTTP request with Django CSRF and session handling.
657
675
  * Automatically retries on network errors and 5xx server errors.
@@ -682,7 +700,7 @@ var APIClient = class {
682
700
  const headers = {
683
701
  ...options?.headers || {}
684
702
  };
685
- if (!options?.formData && !headers["Content-Type"]) {
703
+ if (!options?.formData && !options?.binaryBody && !headers["Content-Type"]) {
686
704
  headers["Content-Type"] = "application/json";
687
705
  }
688
706
  if (this.logger) {
@@ -701,7 +719,8 @@ var APIClient = class {
701
719
  headers,
702
720
  params: options?.params,
703
721
  body: options?.body,
704
- formData: options?.formData
722
+ formData: options?.formData,
723
+ binaryBody: options?.binaryBody
705
724
  });
706
725
  const duration = Date.now() - startTime;
707
726
  if (response.status >= 400) {
@@ -982,7 +1001,7 @@ var BulkEmailRequestSchema = zod.z.object({
982
1001
  main_text: zod.z.string().min(1),
983
1002
  main_html_content: zod.z.string().optional(),
984
1003
  button_text: zod.z.string().max(100).optional(),
985
- button_url: zod.z.url().optional(),
1004
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
986
1005
  secondary_text: zod.z.string().optional()
987
1006
  });
988
1007
  var BulkEmailResponseSchema = zod.z.object({
@@ -1029,7 +1048,7 @@ var NewsletterCampaignSchema = zod.z.object({
1029
1048
  main_text: zod.z.string(),
1030
1049
  main_html_content: zod.z.string().optional(),
1031
1050
  button_text: zod.z.string().max(100).optional(),
1032
- button_url: zod.z.url().optional(),
1051
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
1033
1052
  secondary_text: zod.z.string().optional(),
1034
1053
  status: zod.z.nativeEnum(NewsletterCampaignStatus),
1035
1054
  created_at: zod.z.iso.datetime(),
@@ -1043,7 +1062,7 @@ var NewsletterCampaignRequestSchema = zod.z.object({
1043
1062
  main_text: zod.z.string().min(1),
1044
1063
  main_html_content: zod.z.string().optional(),
1045
1064
  button_text: zod.z.string().max(100).optional(),
1046
- button_url: zod.z.url().optional(),
1065
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
1047
1066
  secondary_text: zod.z.string().optional()
1048
1067
  });
1049
1068
  var NewsletterSubscriptionSchema = zod.z.object({
@@ -1108,7 +1127,7 @@ var PatchedNewsletterCampaignRequestSchema = zod.z.object({
1108
1127
  main_text: zod.z.string().min(1).optional(),
1109
1128
  main_html_content: zod.z.string().optional(),
1110
1129
  button_text: zod.z.string().max(100).optional(),
1111
- button_url: zod.z.url().optional(),
1130
+ button_url: zod.z.union([zod.z.url(), zod.z.literal("")]).optional(),
1112
1131
  secondary_text: zod.z.string().optional()
1113
1132
  });
1114
1133
  var PatchedUnsubscribeRequestSchema = zod.z.object({
@@ -1218,15 +1237,28 @@ __export(fetchers_exports, {
1218
1237
 
1219
1238
  // src/api/generated/ext_newsletter/api-instance.ts
1220
1239
  var globalAPI = null;
1240
+ var autoConfigAttempted = false;
1241
+ function tryAutoConfigureFromEnv() {
1242
+ if (autoConfigAttempted) return;
1243
+ autoConfigAttempted = true;
1244
+ if (globalAPI) return;
1245
+ if (typeof process === "undefined" || !process.env) return;
1246
+ const baseUrl = process.env.NEXT_PUBLIC_API_URL || process.env.VITE_API_URL || process.env.REACT_APP_API_URL || process.env.API_URL;
1247
+ if (baseUrl) {
1248
+ globalAPI = new API(baseUrl);
1249
+ }
1250
+ }
1221
1251
  function getAPIInstance() {
1252
+ tryAutoConfigureFromEnv();
1222
1253
  if (!globalAPI) {
1223
1254
  throw new Error(
1224
- 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })'
1255
+ 'API not configured. Call configureAPI() with your base URL before using fetchers or hooks.\n\nExample:\n import { configureAPI } from "./api-instance"\n configureAPI({ baseUrl: "https://api.example.com" })\n\nOr set environment variable: NEXT_PUBLIC_API_URL, VITE_API_URL, or REACT_APP_API_URL'
1225
1256
  );
1226
1257
  }
1227
1258
  return globalAPI;
1228
1259
  }
1229
1260
  function isAPIConfigured() {
1261
+ tryAutoConfigureFromEnv();
1230
1262
  return globalAPI !== null;
1231
1263
  }
1232
1264
  function configureAPI(config) {
@@ -1962,7 +1994,8 @@ var API = class {
1962
1994
  this._loadTokensFromStorage();
1963
1995
  this._client = new APIClient(this.baseUrl, {
1964
1996
  retryConfig: this.options?.retryConfig,
1965
- loggerConfig: this.options?.loggerConfig
1997
+ loggerConfig: this.options?.loggerConfig,
1998
+ tokenGetter: () => this.getToken()
1966
1999
  });
1967
2000
  this._injectAuthHeader();
1968
2001
  this.ext_newsletter_bulk_email = this._client.ext_newsletter_bulk_email;
@@ -1980,7 +2013,8 @@ var API = class {
1980
2013
  _reinitClients() {
1981
2014
  this._client = new APIClient(this.baseUrl, {
1982
2015
  retryConfig: this.options?.retryConfig,
1983
- loggerConfig: this.options?.loggerConfig
2016
+ loggerConfig: this.options?.loggerConfig,
2017
+ tokenGetter: () => this.getToken()
1984
2018
  });
1985
2019
  this._injectAuthHeader();
1986
2020
  this.ext_newsletter_bulk_email = this._client.ext_newsletter_bulk_email;
@@ -2077,12 +2111,13 @@ var API = class {
2077
2111
  return "./schema.json";
2078
2112
  }
2079
2113
  };
2114
+ api.initializeExtensionAPI(configureAPI);
2080
2115
  var apiNewsletter = api.createExtensionAPI(API);
2081
2116
 
2082
2117
  // package.json
2083
2118
  var package_default = {
2084
2119
  name: "@djangocfg/ext-newsletter",
2085
- version: "1.0.9",
2120
+ version: "1.0.10",
2086
2121
  description: "Newsletter and subscription management extension for DjangoCFG",
2087
2122
  keywords: [
2088
2123
  "django",