next-formatter 2.0.0 → 2.0.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.
package/README.md CHANGED
@@ -1,24 +1,21 @@
1
- ### next-formatter
1
+ # next-formatter
2
2
 
3
3
  Universal number, currency, date, and relative time formatter for Next.js App Router — works in both **Server Components** and **Client Components** with zero hydration mismatches.
4
4
 
5
- [→ View Full Documentation (Interactive)](https://gauravgorade.github.io/next-formatter/)
6
-
7
- ### Installation
5
+ [→ View Full Documentation](https://gauravgorade.github.io/next-formatter/)
8
6
 
7
+ ## Installation
9
8
  ```bash
10
9
  npm install next-formatter
11
10
  ```
12
11
 
13
- ### Recommended Setup
12
+ ## Recommended Setup
14
13
 
15
- Define your configuration once in a shared library file to ensure consistency across the server and client.
14
+ Define your configuration once in a shared file to keep locale and currency consistent across server and client.
16
15
 
17
16
  **lib/formatter.ts**
18
-
19
17
  ```typescript
20
18
  import { getFormatter as _getFormatter } from "next-formatter/server";
21
- import { useFormatter } from "next-formatter/client";
22
19
  import type { NextFormatterConfig } from "next-formatter";
23
20
 
24
21
  const config: NextFormatterConfig = {
@@ -31,46 +28,45 @@ const config: NextFormatterConfig = {
31
28
 
32
29
  export const formatterConfig = config;
33
30
  export const getFormatter = () => _getFormatter(config);
34
- export { useFormatter };
35
31
  ```
36
32
 
37
- ### 1. Initialize Provider
33
+ ## 1. Add the Provider
38
34
 
39
- Add the `NextFormatterProvider` to your root layout.
35
+ Add `NextFormatterProvider` to your root layout.
40
36
 
41
37
  **app/layout.tsx**
42
-
43
38
  ```tsx
44
- import { NextFormatterProvider } from "next-formatter";
39
+ import { NextFormatterProvider } from "next-formatter/server";
45
40
  import { formatterConfig } from "@/lib/formatter";
46
41
 
47
42
  export default async function RootLayout({ children }) {
48
43
  return (
49
44
  <html lang="en">
50
45
  <body>
51
- <NextFormatterProvider config={formatterConfig}>{children}</NextFormatterProvider>
46
+ <NextFormatterProvider config={formatterConfig}>
47
+ {children}
48
+ </NextFormatterProvider>
52
49
  </body>
53
50
  </html>
54
51
  );
55
52
  }
56
53
  ```
57
54
 
58
- ### 2. Usage in Server Components
59
-
55
+ ## 2. Server Components
60
56
  ```tsx
61
57
  import { getFormatter } from "@/lib/formatter";
62
58
 
63
59
  export default async function Page() {
64
60
  const fmt = await getFormatter();
61
+
65
62
  return <h1>{fmt.currency(49.99)}</h1>;
66
63
  }
67
64
  ```
68
65
 
69
- ### 3. Usage in Client Components
70
-
66
+ ## 3. Client Components
71
67
  ```tsx
72
68
  "use client";
73
- import { useFormatter } from "@/lib/formatter";
69
+ import { useFormatter } from "next-formatter/client";
74
70
 
75
71
  export function Price({ value }) {
76
72
  const { currency } = useFormatter();
@@ -78,14 +74,31 @@ export function Price({ value }) {
78
74
  }
79
75
  ```
80
76
 
81
- ### Why next-formatter?
77
+ ## Dynamic Locale & Currency
78
+
79
+ Resolve locale and currency per request from session, cookies, or headers.
80
+ ```typescript
81
+ import type { NextFormatterConfig } from "next-formatter";
82
+
83
+ export const formatterConfig: NextFormatterConfig = {
84
+ getLocale: async () => {
85
+ const session = await auth();
86
+ return session?.user?.locale;
87
+ },
88
+ getCurrency: async () => {
89
+ const session = await auth();
90
+ return session?.user?.currency;
91
+ },
92
+ };
93
+ ```
82
94
 
83
- - **Safe ICU Hydration**: Zero spacing or fraction-digit mismatches between server and client.
84
- - **Dynamic Resolvers**: Detect locale from cookies, headers, or your database.
85
- - **Micro-Bundle**: Optimized for the App Router with negligible client-side impact.
95
+ ## Why next-formatter?
86
96
 
87
- [→ Full Documentation](https://gauravgorade.github.io/next-formatter/)
97
+ - **Zero hydration mismatches** — ICU spacing and fraction digits are normalized between server and client.
98
+ - **Dynamic resolvers** — detect locale and currency from cookies, headers, or your database per request.
99
+ - **Tiny client bundle** — server resolution means minimal JavaScript shipped to the browser.
100
+ - **Drop-in** — no global state, no providers required for server-only usage.
88
101
 
89
- ### License
102
+ ## License
90
103
 
91
- MIT © [gauravgorade](https://github.com/gauravgorade)
104
+ MIT © [gauravgorade](https://github.com/gauravgorade)
package/dist/cjs/index.js CHANGED
@@ -1,14 +1,2 @@
1
1
  'use strict';
2
2
 
3
- var client = require('./client');
4
- var create = require('./create');
5
- var jsxRuntime = require('react/jsx-runtime');
6
-
7
- // src/index.tsx
8
- async function NextFormatterProvider({ config = {}, children }) {
9
- const locale = await create.resolveLocale(config.getLocale, config.locale);
10
- const currency = await create.resolveCurrency(config.getCurrency, config.currency);
11
- return /* @__PURE__ */ jsxRuntime.jsx(client.FormattersProvider, { config: { locale, currency, fallback: config.fallback, rules: config.rules }, children });
12
- }
13
-
14
- exports.NextFormatterProvider = NextFormatterProvider;
@@ -1,9 +1,16 @@
1
1
  'use strict';
2
2
 
3
+ var client = require('./client');
3
4
  var core = require('./core');
4
5
  var create = require('./create');
6
+ var jsxRuntime = require('react/jsx-runtime');
5
7
 
6
- // src/server.ts
8
+ // src/server.tsx
9
+ async function NextFormatterProvider({ config = {}, children }) {
10
+ const locale = await create.resolveLocale(config.getLocale, config.locale);
11
+ const currency = await create.resolveCurrency(config.getCurrency, config.currency);
12
+ return /* @__PURE__ */ jsxRuntime.jsx(client.FormattersProvider, { config: { locale, currency, fallback: config.fallback, rules: config.rules }, children });
13
+ }
7
14
  async function getFormatter(config = {}) {
8
15
  const locale = await create.resolveLocale(config.getLocale, config.locale);
9
16
  const currency = await create.resolveCurrency(config.getCurrency, config.currency);
@@ -15,4 +22,5 @@ async function getFormatter(config = {}) {
15
22
  });
16
23
  }
17
24
 
25
+ exports.NextFormatterProvider = NextFormatterProvider;
18
26
  exports.getFormatter = getFormatter;
@@ -1,12 +1 @@
1
- import { FormattersProvider } from './client';
2
- import { resolveLocale, resolveCurrency } from './create';
3
- import { jsx } from 'react/jsx-runtime';
4
1
 
5
- // src/index.tsx
6
- async function NextFormatterProvider({ config = {}, children }) {
7
- const locale = await resolveLocale(config.getLocale, config.locale);
8
- const currency = await resolveCurrency(config.getCurrency, config.currency);
9
- return /* @__PURE__ */ jsx(FormattersProvider, { config: { locale, currency, fallback: config.fallback, rules: config.rules }, children });
10
- }
11
-
12
- export { NextFormatterProvider };
@@ -1,7 +1,14 @@
1
+ import { FormattersProvider } from './client';
1
2
  import { createFormatters } from './core';
2
3
  import { resolveLocale, resolveCurrency } from './create';
4
+ import { jsx } from 'react/jsx-runtime';
3
5
 
4
- // src/server.ts
6
+ // src/server.tsx
7
+ async function NextFormatterProvider({ config = {}, children }) {
8
+ const locale = await resolveLocale(config.getLocale, config.locale);
9
+ const currency = await resolveCurrency(config.getCurrency, config.currency);
10
+ return /* @__PURE__ */ jsx(FormattersProvider, { config: { locale, currency, fallback: config.fallback, rules: config.rules }, children });
11
+ }
5
12
  async function getFormatter(config = {}) {
6
13
  const locale = await resolveLocale(config.getLocale, config.locale);
7
14
  const currency = await resolveCurrency(config.getCurrency, config.currency);
@@ -13,4 +20,4 @@ async function getFormatter(config = {}) {
13
20
  });
14
21
  }
15
22
 
16
- export { getFormatter };
23
+ export { NextFormatterProvider, getFormatter };
@@ -1,60 +1,3 @@
1
- import { type PropsWithChildren } from "react";
2
- import { type NextFormatterConfig } from "./create";
3
- /**
4
- * Root provider for Next.js App Router. Place in `app/layout.tsx`.
5
- *
6
- * Async Server Component — resolves locale and currency server-side per request,
7
- * then passes the resolved config to the client-side context. Zero client bundle cost.
8
- *
9
- * Resolution order for locale:
10
- * 1. `getLocale()` resolver (session, db, cookie)
11
- * 2. `locale` static value
12
- * 3. `accept-language` request header
13
- * 4. `"en-US"` default
14
- *
15
- * Resolution order for currency:
16
- * 1. `getCurrency()` resolver (session, db, cookie)
17
- * 2. `currency` static value
18
- * 3. `"USD"` default
19
- *
20
- * @example
21
- * // Zero config — locale auto-detected from accept-language header
22
- * <NextFormatterProvider>{children}</NextFormatterProvider>
23
- *
24
- * @example
25
- * // Static locale and currency
26
- * <NextFormatterProvider config={{ locale: "de-DE", currency: "EUR" }}>
27
- * {children}
28
- * </NextFormatterProvider>
29
- *
30
- * @example
31
- * // Dynamic locale and currency from session
32
- * <NextFormatterProvider
33
- * config={{
34
- * getLocale: async () => (await auth())?.user?.locale,
35
- * getCurrency: async () => (await auth())?.user?.currency,
36
- * fallback: "N/A",
37
- * rules: {
38
- * compactThreshold: 50_000,
39
- * currencyDisplay: "symbol",
40
- * dateFormat: { year: "numeric", month: "long", day: "2-digit" },
41
- * },
42
- * }}
43
- * >
44
- * {children}
45
- * </NextFormatterProvider>
46
- *
47
- * @example
48
- * // Recommended — define config once in lib/formatter.ts, import everywhere
49
- * import { formatterConfig } from "@/lib/formatter";
50
- *
51
- * <NextFormatterProvider config={formatterConfig}>
52
- * {children}
53
- * </NextFormatterProvider>
54
- */
55
- export declare function NextFormatterProvider({ config, children }: PropsWithChildren<{
56
- config?: NextFormatterConfig;
57
- }>): Promise<import("react/jsx-runtime").JSX.Element>;
58
- export type { FormatterConfig, Formatter, FormatterRules, NumericInput, DateInput } from "./core";
1
+ export type { FormatterConfig, Formatter, FormatterRules, NumericInput, DateInput, NumberOptions, CurrencyOptions, PercentageOptions, DateOptions, DateTimeOptions } from "./core";
59
2
  export type { NextFormatterConfig } from "./create";
60
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,OAAO,EAAkC,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAsB,qBAAqB,CAAC,EAAE,MAAW,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC;IAAE,MAAM,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC,oDAKzH;AAED,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAClG,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,eAAe,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,iBAAiB,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACnL,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC"}
@@ -1,22 +1,94 @@
1
+ import { type PropsWithChildren } from "react";
1
2
  import { type Formatter } from "./core";
2
3
  import { type NextFormatterConfig } from "./create";
4
+ /**
5
+ * Root provider for Next.js App Router. Place in `app/layout.tsx`.
6
+ *
7
+ * Async Server Component — resolves locale and currency server-side per request,
8
+ * then passes the resolved config to the client-side context. Zero client bundle cost.
9
+ *
10
+ * Resolution order for locale:
11
+ * 1. `getLocale()` resolver (session, db, cookie)
12
+ * 2. `locale` static value
13
+ * 3. `accept-language` request header
14
+ * 4. `"en-US"` default
15
+ *
16
+ * Resolution order for currency:
17
+ * 1. `getCurrency()` resolver (session, db, cookie)
18
+ * 2. `currency` static value
19
+ * 3. `"USD"` default
20
+ *
21
+ * @example
22
+ * // Zero config — locale auto-detected from accept-language header
23
+ * <NextFormatterProvider>{children}</NextFormatterProvider>
24
+ *
25
+ * @example
26
+ * // Static locale and currency
27
+ * <NextFormatterProvider config={{ locale: "de-DE", currency: "EUR" }}>
28
+ * {children}
29
+ * </NextFormatterProvider>
30
+ *
31
+ * @example
32
+ * // Dynamic locale and currency from session
33
+ * <NextFormatterProvider
34
+ * config={{
35
+ * getLocale: async () => (await auth())?.user?.locale,
36
+ * getCurrency: async () => (await auth())?.user?.currency,
37
+ * fallback: "N/A",
38
+ * rules: {
39
+ * compactThreshold: 50_000,
40
+ * currencyDisplay: "symbol",
41
+ * dateFormat: { year: "numeric", month: "long", day: "2-digit" },
42
+ * },
43
+ * }}
44
+ * >
45
+ * {children}
46
+ * </NextFormatterProvider>
47
+ *
48
+ * @example
49
+ * // Recommended — define config once in lib/formatter.ts, import everywhere
50
+ * import { formatterConfig } from "@/lib/formatter";
51
+ *
52
+ * <NextFormatterProvider config={formatterConfig}>
53
+ * {children}
54
+ * </NextFormatterProvider>
55
+ */
56
+ export declare function NextFormatterProvider({ config, children }: PropsWithChildren<{
57
+ config?: NextFormatterConfig;
58
+ }>): Promise<import("react/jsx-runtime").JSX.Element>;
3
59
  /**
4
60
  * Use in Server Components or Server Actions.
5
61
  * Locale is auto-detected from request headers — pass config only to override.
6
62
  *
7
63
  * @example
8
- * // Zero config
64
+ * // Zero config — locale and currency auto-detected
9
65
  * const fmt = await getFormatter();
66
+ * fmt.currency(1234); // "$1,234"
10
67
  *
11
68
  * @example
12
- * // With overrides
13
- * const fmt = await getFormatter({ currency: "EUR" });
69
+ * // Static overrides
70
+ * const fmt = await getFormatter({ locale: "de-DE", currency: "EUR" });
71
+ * fmt.currency(1234); // "1.234 €"
14
72
  *
15
73
  * @example
16
74
  * // Dynamic currency from session
17
75
  * const fmt = await getFormatter({
18
76
  * getCurrency: async () => (await auth())?.user?.currency,
19
77
  * });
78
+ *
79
+ * @example
80
+ * // With custom rules
81
+ * const fmt = await getFormatter({
82
+ * rules: {
83
+ * compactThreshold: 50_000,
84
+ * currencyDisplay: "symbol",
85
+ * },
86
+ * });
87
+ *
88
+ * @example
89
+ * // Recommended — define config once in lib/formatter.ts, import everywhere
90
+ * import { formatterConfig } from "@/lib/formatter";
91
+ * const fmt = await getFormatter(formatterConfig);
20
92
  */
21
93
  export declare function getFormatter(config?: NextFormatterConfig): Promise<Formatter>;
22
94
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAkC,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,YAAY,CAAC,MAAM,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,CAUvF"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/server.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAE/C,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC1D,OAAO,EAAkC,KAAK,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AACH,wBAAsB,qBAAqB,CAAC,EAAE,MAAW,EAAE,QAAQ,EAAE,EAAE,iBAAiB,CAAC;IAAE,MAAM,CAAC,EAAE,mBAAmB,CAAA;CAAE,CAAC,oDAKzH;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,YAAY,CAAC,MAAM,GAAE,mBAAwB,GAAG,OAAO,CAAC,SAAS,CAAC,CAUvF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-formatter",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "A universal formatter for numbers, currency, dates, and relative time — built for Next.js App Router, supporting server components, client components, and Node.js backends.",
5
5
  "author": "gauravgorade",
6
6
  "license": "MIT",