@carlonicora/nextjs-jsonapi 1.84.0 → 1.86.0

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 (45) hide show
  1. package/dist/{BlockNoteEditor-ZNACEXKX.mjs → BlockNoteEditor-7TZA4XEN.mjs} +3 -3
  2. package/dist/{BlockNoteEditor-PJWPR4IU.js → BlockNoteEditor-KRDP6OSE.js} +7 -7
  3. package/dist/{BlockNoteEditor-PJWPR4IU.js.map → BlockNoteEditor-KRDP6OSE.js.map} +1 -1
  4. package/dist/billing/index.js +303 -303
  5. package/dist/billing/index.mjs +2 -2
  6. package/dist/{chunk-ZEJSPTHS.js → chunk-2AK4GRIB.js} +19 -11
  7. package/dist/chunk-2AK4GRIB.js.map +1 -0
  8. package/dist/{chunk-B7ZH2R62.js → chunk-AMP2ZDAV.js} +93 -83
  9. package/dist/chunk-AMP2ZDAV.js.map +1 -0
  10. package/dist/{chunk-CPXN5OGI.mjs → chunk-CZ56O6JZ.mjs} +22 -12
  11. package/dist/chunk-CZ56O6JZ.mjs.map +1 -0
  12. package/dist/{chunk-PV5V6CVW.mjs → chunk-NEJ7CDM3.mjs} +9 -1
  13. package/dist/chunk-NEJ7CDM3.mjs.map +1 -0
  14. package/dist/client/index.d.mts +1 -1
  15. package/dist/client/index.d.ts +1 -1
  16. package/dist/client/index.js +5 -3
  17. package/dist/client/index.js.map +1 -1
  18. package/dist/client/index.mjs +4 -2
  19. package/dist/components/index.d.mts +4 -2
  20. package/dist/components/index.d.ts +4 -2
  21. package/dist/components/index.js +3 -3
  22. package/dist/components/index.mjs +2 -2
  23. package/dist/{config-B5oBQVEA.d.ts → config-CLQynoaa.d.ts} +15 -1
  24. package/dist/{config-Bx_uh22h.d.mts → config-k61pe_o2.d.mts} +15 -1
  25. package/dist/contexts/index.js +3 -3
  26. package/dist/contexts/index.mjs +2 -2
  27. package/dist/index.d.mts +1 -1
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +4 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/index.mjs +3 -1
  32. package/package.json +1 -1
  33. package/src/client/config.ts +20 -0
  34. package/src/components/forms/CommonEditorButtons.tsx +7 -4
  35. package/src/components/forms/EditorSheet.tsx +9 -1
  36. package/src/features/auth/components/buttons/GoogleSignInButton.tsx +2 -2
  37. package/src/features/auth/components/details/LandingComponent.tsx +2 -2
  38. package/src/features/auth/components/forms/Login.tsx +2 -2
  39. package/src/features/auth/components/forms/Register.tsx +3 -3
  40. package/src/index.ts +8 -1
  41. package/dist/chunk-B7ZH2R62.js.map +0 -1
  42. package/dist/chunk-CPXN5OGI.mjs.map +0 -1
  43. package/dist/chunk-PV5V6CVW.mjs.map +0 -1
  44. package/dist/chunk-ZEJSPTHS.js.map +0 -1
  45. /package/dist/{BlockNoteEditor-ZNACEXKX.mjs.map → BlockNoteEditor-7TZA4XEN.mjs.map} +0 -0
package/dist/index.mjs CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  configureWaitlist,
11
11
  getApiUrl,
12
12
  getAppUrl,
13
+ getPublicApiUrl,
13
14
  getReferralConfig,
14
15
  getRoleId,
15
16
  getStripePublishableKey,
@@ -17,7 +18,7 @@ import {
17
18
  getWaitlistConfig,
18
19
  isReferralEnabled,
19
20
  isRolesConfigured
20
- } from "./chunk-PV5V6CVW.mjs";
21
+ } from "./chunk-NEJ7CDM3.mjs";
21
22
  import {
22
23
  AVAILABLE_OAUTH_SCOPES,
23
24
  AbstractApiData,
@@ -392,6 +393,7 @@ export {
392
393
  getLucideIcon,
393
394
  getLucideIconByModule,
394
395
  getLucideIconByModuleName,
396
+ getPublicApiUrl,
395
397
  getReferralConfig,
396
398
  getRoleId,
397
399
  getStripePublishableKey,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@carlonicora/nextjs-jsonapi",
3
- "version": "1.84.0",
3
+ "version": "1.86.0",
4
4
  "description": "Next.js JSON:API client with server/client support and caching",
5
5
  "author": "Carlo Nicora",
6
6
  "license": "GPL-3.0-or-later",
@@ -47,6 +47,11 @@ export function configureClientConfig(config: {
47
47
 
48
48
  /**
49
49
  * Get the configured API URL.
50
+ *
51
+ * This may resolve to an internal/private host (e.g. a docker-network
52
+ * hostname) when configured to do so for SSR fetches. Do NOT use this for
53
+ * URLs that are rendered into HTML and followed by the browser — use
54
+ * `getPublicApiUrl()` instead.
50
55
  */
51
56
  export function getApiUrl(): string {
52
57
  if (_clientConfig?.apiUrl) {
@@ -58,6 +63,21 @@ export function getApiUrl(): string {
58
63
  return "";
59
64
  }
60
65
 
66
+ /**
67
+ * Get the public-facing API URL.
68
+ *
69
+ * Always sourced from `NEXT_PUBLIC_API_URL` so it is identical on server
70
+ * and client, and reachable from the user's browser. Use for any URL that
71
+ * gets rendered into HTML the browser will navigate to (links, redirects,
72
+ * OAuth hrefs).
73
+ */
74
+ export function getPublicApiUrl(): string {
75
+ if (typeof process !== "undefined" && process.env?.NEXT_PUBLIC_API_URL) {
76
+ return process.env.NEXT_PUBLIC_API_URL;
77
+ }
78
+ return "";
79
+ }
80
+
61
81
  /**
62
82
  * Get the configured app URL.
63
83
  */
@@ -6,8 +6,9 @@ type CommonEditorButtonsProps = {
6
6
  form: any;
7
7
  disabled?: boolean;
8
8
  setOpen: (open: boolean) => void;
9
+ hideSubmit?: boolean;
9
10
  };
10
- export function CommonEditorButtons({ isEdit, form, disabled, setOpen }: CommonEditorButtonsProps) {
11
+ export function CommonEditorButtons({ isEdit, form, disabled, setOpen, hideSubmit }: CommonEditorButtonsProps) {
11
12
  const t = useTranslations();
12
13
 
13
14
  return (
@@ -22,9 +23,11 @@ export function CommonEditorButtons({ isEdit, form, disabled, setOpen }: CommonE
22
23
  {t(`ui.buttons.cancel`)}
23
24
  </Button>
24
25
 
25
- <Button type="submit" disabled={form.formState.isSubmitting || disabled} data-testid={`modal-button-create`}>
26
- {isEdit ? t(`ui.buttons.confirm_update`) : t(`ui.buttons.confirm_create`)}
27
- </Button>
26
+ {!hideSubmit && (
27
+ <Button type="submit" disabled={form.formState.isSubmitting || disabled} data-testid={`modal-button-create`}>
28
+ {isEdit ? t(`ui.buttons.confirm_update`) : t(`ui.buttons.confirm_create`)}
29
+ </Button>
30
+ )}
28
31
  </div>
29
32
  );
30
33
  }
@@ -51,6 +51,7 @@ export type EditorSheetProps<T extends FieldValues> = {
51
51
 
52
52
  size?: EditorSheetSize;
53
53
  disabled?: boolean;
54
+ hideSubmit?: boolean;
54
55
 
55
56
  trigger?: ReactNode;
56
57
  forceShow?: boolean;
@@ -78,6 +79,7 @@ export function EditorSheet<T extends FieldValues>({
78
79
  onNavigate,
79
80
  size = "xl",
80
81
  disabled,
82
+ hideSubmit,
81
83
  trigger,
82
84
  forceShow,
83
85
  onClose,
@@ -177,7 +179,13 @@ export function EditorSheet<T extends FieldValues>({
177
179
  <form onSubmit={form.handleSubmit(wrappedOnSubmit)} className="flex min-h-0 flex-1 flex-col">
178
180
  <div className="flex-1 overflow-y-auto px-6 py-4">{children}</div>
179
181
  <SheetFooter className="shrink-0 border-t px-6 py-4">
180
- <CommonEditorButtons form={form} setOpen={handleOpenChange} isEdit={isEdit} disabled={disabled} />
182
+ <CommonEditorButtons
183
+ form={form}
184
+ setOpen={handleOpenChange}
185
+ isEdit={isEdit}
186
+ disabled={disabled}
187
+ hideSubmit={hideSubmit}
188
+ />
181
189
  </SheetFooter>
182
190
  </form>
183
191
  </Form>
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import { getApiUrl } from "../../../../client/config";
3
+ import { getPublicApiUrl } from "../../../../client/config";
4
4
  import { isGoogleAuthEnabled } from "../../../../login";
5
5
  import { Button, Link } from "../../../../shadcnui";
6
6
 
@@ -15,7 +15,7 @@ export function GoogleSignInButton({ referralCode }: GoogleSignInButtonProps) {
15
15
 
16
16
  // Build OAuth URL with referral parameter if available
17
17
  const buildGoogleOAuthUrl = (): string => {
18
- const baseUrl = `${getApiUrl()}auth/google`;
18
+ const baseUrl = `${getPublicApiUrl()}auth/google`;
19
19
  if (!referralCode) return baseUrl;
20
20
  return `${baseUrl}?referral=${encodeURIComponent(referralCode)}`;
21
21
  };
@@ -2,7 +2,7 @@
2
2
 
3
3
  import { useTranslations } from "next-intl";
4
4
  import Image from "next/image";
5
- import { getApiUrl } from "../../../../client/config";
5
+ import { getPublicApiUrl } from "../../../../client/config";
6
6
  import {
7
7
  isDiscordAuthEnabled,
8
8
  isGoogleAuthEnabled,
@@ -53,7 +53,7 @@ export function LandingComponent() {
53
53
  )}
54
54
  {isGoogleAuthEnabled() && <GoogleSignInButton />}
55
55
  {isDiscordAuthEnabled() && (
56
- <Link href={`${getApiUrl()}auth/discord`} className="flex w-full justify-end">
56
+ <Link href={`${getPublicApiUrl()}auth/discord`} className="flex w-full justify-end">
57
57
  <Button className="w-full" variant={`outline`} data-testid="page-login-button-initial-login">
58
58
  Login with Discord
59
59
  </Button>
@@ -7,7 +7,7 @@ import { useRouter, useSearchParams } from "next/navigation";
7
7
  import { useEffect, useState } from "react";
8
8
  import { SubmitHandler, useForm } from "react-hook-form";
9
9
  import { z } from "zod";
10
- import { getApiUrl } from "../../../../client/config";
10
+ import { getPublicApiUrl } from "../../../../client/config";
11
11
  import { errorToast, FormInput, FormPassword } from "../../../../components";
12
12
  import { useI18nRouter, usePageUrlGenerator } from "../../../../hooks";
13
13
  import { isDiscordAuthEnabled, isGoogleAuthEnabled, isInternalAuthEnabled } from "../../../../login";
@@ -55,7 +55,7 @@ export function Login() {
55
55
 
56
56
  // Helper function to build OAuth URL with referral
57
57
  const buildDiscordOAuthUrl = (): string => {
58
- const baseUrl = `${getApiUrl()}auth/discord`;
58
+ const baseUrl = `${getPublicApiUrl()}auth/discord`;
59
59
  if (!referralCode) return baseUrl;
60
60
  return `${baseUrl}?referral=${encodeURIComponent(referralCode)}`;
61
61
  };
@@ -9,7 +9,7 @@ import { useEffect, useState } from "react";
9
9
  import { SubmitHandler, useForm } from "react-hook-form";
10
10
  import { v4 } from "uuid";
11
11
  import { z } from "zod";
12
- import { getApiUrl } from "../../../../client/config";
12
+ import { getPublicApiUrl } from "../../../../client/config";
13
13
  import { errorToast, FormInput, FormPassword } from "../../../../components";
14
14
  import { getRegistrationMode, isDiscordAuthEnabled, isGoogleAuthEnabled } from "../../../../login/config";
15
15
  import {
@@ -296,7 +296,7 @@ export default function Register() {
296
296
  <div className="space-y-2">
297
297
  {isGoogleAuthEnabled() && (
298
298
  <Link
299
- href={`${getApiUrl()}auth/google${buildOAuthQueryParams(inviteCode, referralCode)}`}
299
+ href={`${getPublicApiUrl()}auth/google${buildOAuthQueryParams(inviteCode, referralCode)}`}
300
300
  className="flex w-full"
301
301
  >
302
302
  <Button
@@ -328,7 +328,7 @@ export default function Register() {
328
328
  )}
329
329
  {isDiscordAuthEnabled() && (
330
330
  <Link
331
- href={`${getApiUrl()}auth/discord${buildOAuthQueryParams(inviteCode, referralCode)}`}
331
+ href={`${getPublicApiUrl()}auth/discord${buildOAuthQueryParams(inviteCode, referralCode)}`}
332
332
  className="flex w-full"
333
333
  >
334
334
  <Button className="w-full" variant="outline" type="button">
package/src/index.ts CHANGED
@@ -9,7 +9,14 @@ export * from "./core";
9
9
  export * from "./permissions";
10
10
 
11
11
  // JSON:API configuration (client-safe)
12
- export { configureJsonApi, getApiUrl, getAppUrl, getTrackablePages, getStripePublishableKey } from "./client/config";
12
+ export {
13
+ configureJsonApi,
14
+ getApiUrl,
15
+ getPublicApiUrl,
16
+ getAppUrl,
17
+ getTrackablePages,
18
+ getStripePublishableKey,
19
+ } from "./client/config";
13
20
 
14
21
  // I18n configuration (NOT hooks - those are in /hooks with "use client")
15
22
  export { configureI18n } from "./i18n";