@xcript-dev/next 0.1.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.
@@ -0,0 +1,10 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ export {
9
+ __require
10
+ };
@@ -0,0 +1,37 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface LicenseState {
5
+ /** Whether the license is valid. */
6
+ isValid: boolean;
7
+ /** Whether validation is in progress. */
8
+ isLoading: boolean;
9
+ /** Dynamic config from the Xcript dashboard. */
10
+ config: Record<string, string>;
11
+ /** Error message if validation failed. */
12
+ error: string | null;
13
+ }
14
+ interface XcriptProviderProps {
15
+ children: ReactNode;
16
+ }
17
+ /**
18
+ * Context provider that reads the license validation state from
19
+ * the middleware cookie. No client-side API calls needed.
20
+ *
21
+ * Wrap your app layout with this provider, then use `useLicense()`
22
+ * in any client component.
23
+ */
24
+ declare function XcriptProvider({ children }: XcriptProviderProps): react_jsx_runtime.JSX.Element;
25
+ /**
26
+ * React hook to access the current license state.
27
+ *
28
+ * Must be used within a `<XcriptProvider>`.
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * const { isValid, config, isLoading } = useLicense()
33
+ * ```
34
+ */
35
+ declare function useLicense(): LicenseState;
36
+
37
+ export { XcriptProvider, useLicense };
@@ -0,0 +1,37 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+
4
+ interface LicenseState {
5
+ /** Whether the license is valid. */
6
+ isValid: boolean;
7
+ /** Whether validation is in progress. */
8
+ isLoading: boolean;
9
+ /** Dynamic config from the Xcript dashboard. */
10
+ config: Record<string, string>;
11
+ /** Error message if validation failed. */
12
+ error: string | null;
13
+ }
14
+ interface XcriptProviderProps {
15
+ children: ReactNode;
16
+ }
17
+ /**
18
+ * Context provider that reads the license validation state from
19
+ * the middleware cookie. No client-side API calls needed.
20
+ *
21
+ * Wrap your app layout with this provider, then use `useLicense()`
22
+ * in any client component.
23
+ */
24
+ declare function XcriptProvider({ children }: XcriptProviderProps): react_jsx_runtime.JSX.Element;
25
+ /**
26
+ * React hook to access the current license state.
27
+ *
28
+ * Must be used within a `<XcriptProvider>`.
29
+ *
30
+ * @example
31
+ * ```tsx
32
+ * const { isValid, config, isLoading } = useLicense()
33
+ * ```
34
+ */
35
+ declare function useLicense(): LicenseState;
36
+
37
+ export { XcriptProvider, useLicense };
package/dist/client.js ADDED
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ "use client";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/client.tsx
22
+ var client_exports = {};
23
+ __export(client_exports, {
24
+ XcriptProvider: () => XcriptProvider,
25
+ useLicense: () => useLicense
26
+ });
27
+ module.exports = __toCommonJS(client_exports);
28
+ var import_react = require("react");
29
+ var import_jsx_runtime = require("react/jsx-runtime");
30
+ var XcriptContext = (0, import_react.createContext)({
31
+ isValid: false,
32
+ isLoading: true,
33
+ config: {},
34
+ error: null
35
+ });
36
+ var COOKIE_NAME = "__xcript_status";
37
+ function XcriptProvider({ children }) {
38
+ const [state, setState] = (0, import_react.useState)({
39
+ isValid: false,
40
+ isLoading: true,
41
+ config: {},
42
+ error: null
43
+ });
44
+ (0, import_react.useEffect)(() => {
45
+ try {
46
+ const cookies = document.cookie.split(";").reduce((acc, c) => {
47
+ const [key, ...rest] = c.trim().split("=");
48
+ acc[key] = decodeURIComponent(rest.join("="));
49
+ return acc;
50
+ }, {});
51
+ const raw = cookies[COOKIE_NAME];
52
+ if (raw) {
53
+ const parsed = JSON.parse(raw);
54
+ setState({
55
+ isValid: !!parsed.valid,
56
+ isLoading: false,
57
+ config: parsed.config || {},
58
+ error: null
59
+ });
60
+ } else {
61
+ setState((prev) => ({ ...prev, isLoading: false }));
62
+ }
63
+ } catch {
64
+ setState({
65
+ isValid: false,
66
+ isLoading: false,
67
+ config: {},
68
+ error: "Failed to read license state"
69
+ });
70
+ }
71
+ }, []);
72
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(XcriptContext.Provider, { value: state, children });
73
+ }
74
+ function useLicense() {
75
+ return (0, import_react.useContext)(XcriptContext);
76
+ }
77
+ // Annotate the CommonJS export names for ESM import in node:
78
+ 0 && (module.exports = {
79
+ XcriptProvider,
80
+ useLicense
81
+ });
@@ -0,0 +1,62 @@
1
+ "use client";
2
+ import "./chunk-Y6FXYEAI.mjs";
3
+
4
+ // src/client.tsx
5
+ import {
6
+ createContext,
7
+ useContext,
8
+ useEffect,
9
+ useState
10
+ } from "react";
11
+ import { jsx } from "react/jsx-runtime";
12
+ var XcriptContext = createContext({
13
+ isValid: false,
14
+ isLoading: true,
15
+ config: {},
16
+ error: null
17
+ });
18
+ var COOKIE_NAME = "__xcript_status";
19
+ function XcriptProvider({ children }) {
20
+ const [state, setState] = useState({
21
+ isValid: false,
22
+ isLoading: true,
23
+ config: {},
24
+ error: null
25
+ });
26
+ useEffect(() => {
27
+ try {
28
+ const cookies = document.cookie.split(";").reduce((acc, c) => {
29
+ const [key, ...rest] = c.trim().split("=");
30
+ acc[key] = decodeURIComponent(rest.join("="));
31
+ return acc;
32
+ }, {});
33
+ const raw = cookies[COOKIE_NAME];
34
+ if (raw) {
35
+ const parsed = JSON.parse(raw);
36
+ setState({
37
+ isValid: !!parsed.valid,
38
+ isLoading: false,
39
+ config: parsed.config || {},
40
+ error: null
41
+ });
42
+ } else {
43
+ setState((prev) => ({ ...prev, isLoading: false }));
44
+ }
45
+ } catch {
46
+ setState({
47
+ isValid: false,
48
+ isLoading: false,
49
+ config: {},
50
+ error: "Failed to read license state"
51
+ });
52
+ }
53
+ }, []);
54
+ return /* @__PURE__ */ jsx(XcriptContext.Provider, { value: state, children });
55
+ }
56
+ function useLicense() {
57
+ return useContext(XcriptContext);
58
+ }
59
+ export {
60
+ XcriptProvider,
61
+ useLicense
62
+ };
@@ -0,0 +1,56 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ export { ValidationResponse, XcriptConfig } from '@xcript-dev/sdk';
3
+
4
+ /**
5
+ * @xcript/next — Next.js middleware for license validation.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // middleware.ts
10
+ * import { withXcript } from '@xcript/next'
11
+ *
12
+ * export default withXcript({
13
+ * apiKey: process.env.XCRIPT_API_KEY!,
14
+ * licenseKey: process.env.XCRIPT_LICENSE_KEY!,
15
+ * protectedRoutes: ['/dashboard/*', '/api/*'],
16
+ * onInvalid: '/license-expired',
17
+ * })
18
+ *
19
+ * export const config = {
20
+ * matcher: ['/dashboard/:path*', '/api/:path*'],
21
+ * }
22
+ * ```
23
+ */
24
+
25
+ interface XcriptMiddlewareConfig {
26
+ /** Your Xcript API key (starts with "xk_"). */
27
+ apiKey: string;
28
+ /** The license key to validate. */
29
+ licenseKey: string;
30
+ /** Ed25519 public key for signature verification (hex). Optional. */
31
+ publicKey?: string;
32
+ /** API base URL. Defaults to "https://api.xcript.dev". */
33
+ baseUrl?: string;
34
+ /**
35
+ * Glob patterns for routes that require a valid license.
36
+ * Use '*' as wildcard. Example: ['/dashboard/*', '/api/*']
37
+ */
38
+ protectedRoutes?: string[];
39
+ /** Route to redirect to when the license is invalid. Default: returns 403. */
40
+ onInvalid?: string;
41
+ /**
42
+ * How often to re-validate (in seconds).
43
+ * During this window, the cached result is trusted.
44
+ * Default: 300 (5 minutes).
45
+ */
46
+ revalidateInterval?: number;
47
+ }
48
+ /**
49
+ * Create a Next.js middleware that validates the Xcript license.
50
+ *
51
+ * The middleware validates once, stores the result in a cookie,
52
+ * and re-validates after `revalidateInterval` seconds.
53
+ */
54
+ declare function withXcript(config: XcriptMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
55
+
56
+ export { withXcript };
@@ -0,0 +1,56 @@
1
+ import { NextRequest, NextResponse } from 'next/server';
2
+ export { ValidationResponse, XcriptConfig } from '@xcript-dev/sdk';
3
+
4
+ /**
5
+ * @xcript/next — Next.js middleware for license validation.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * // middleware.ts
10
+ * import { withXcript } from '@xcript/next'
11
+ *
12
+ * export default withXcript({
13
+ * apiKey: process.env.XCRIPT_API_KEY!,
14
+ * licenseKey: process.env.XCRIPT_LICENSE_KEY!,
15
+ * protectedRoutes: ['/dashboard/*', '/api/*'],
16
+ * onInvalid: '/license-expired',
17
+ * })
18
+ *
19
+ * export const config = {
20
+ * matcher: ['/dashboard/:path*', '/api/:path*'],
21
+ * }
22
+ * ```
23
+ */
24
+
25
+ interface XcriptMiddlewareConfig {
26
+ /** Your Xcript API key (starts with "xk_"). */
27
+ apiKey: string;
28
+ /** The license key to validate. */
29
+ licenseKey: string;
30
+ /** Ed25519 public key for signature verification (hex). Optional. */
31
+ publicKey?: string;
32
+ /** API base URL. Defaults to "https://api.xcript.dev". */
33
+ baseUrl?: string;
34
+ /**
35
+ * Glob patterns for routes that require a valid license.
36
+ * Use '*' as wildcard. Example: ['/dashboard/*', '/api/*']
37
+ */
38
+ protectedRoutes?: string[];
39
+ /** Route to redirect to when the license is invalid. Default: returns 403. */
40
+ onInvalid?: string;
41
+ /**
42
+ * How often to re-validate (in seconds).
43
+ * During this window, the cached result is trusted.
44
+ * Default: 300 (5 minutes).
45
+ */
46
+ revalidateInterval?: number;
47
+ }
48
+ /**
49
+ * Create a Next.js middleware that validates the Xcript license.
50
+ *
51
+ * The middleware validates once, stores the result in a cookie,
52
+ * and re-validates after `revalidateInterval` seconds.
53
+ */
54
+ declare function withXcript(config: XcriptMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
55
+
56
+ export { withXcript };
package/dist/index.js ADDED
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ withXcript: () => withXcript
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+ var import_server = require("next/server");
27
+ var COOKIE_NAME = "__xcript_status";
28
+ var DEFAULT_REVALIDATE = 300;
29
+ function withXcript(config) {
30
+ const baseUrl = (config.baseUrl || "https://api.xcript.dev").replace(/\/+$/, "");
31
+ const revalidate = config.revalidateInterval ?? DEFAULT_REVALIDATE;
32
+ return async function middleware(request) {
33
+ const { pathname } = request.nextUrl;
34
+ if (config.protectedRoutes && !isProtected(pathname, config.protectedRoutes)) {
35
+ return import_server.NextResponse.next();
36
+ }
37
+ const cached = request.cookies.get(COOKIE_NAME)?.value;
38
+ if (cached) {
39
+ try {
40
+ const parsed = JSON.parse(cached);
41
+ const age = (Date.now() - parsed.timestamp) / 1e3;
42
+ if (age < revalidate && parsed.valid) {
43
+ return import_server.NextResponse.next();
44
+ }
45
+ } catch {
46
+ }
47
+ }
48
+ try {
49
+ const res = await fetch(`${baseUrl}/api/v1/validate`, {
50
+ method: "POST",
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ "X-Api-Key": config.apiKey
54
+ },
55
+ body: JSON.stringify({
56
+ license_key: config.licenseKey,
57
+ machine_id: `nextjs-${hostname()}`
58
+ })
59
+ });
60
+ if (!res.ok) {
61
+ return handleInvalid(request, config);
62
+ }
63
+ const data = await res.json();
64
+ if (!data.valid) {
65
+ return handleInvalid(request, config);
66
+ }
67
+ const response = import_server.NextResponse.next();
68
+ response.cookies.set(COOKIE_NAME, JSON.stringify({
69
+ valid: true,
70
+ timestamp: Date.now(),
71
+ config: data.config || {}
72
+ }), {
73
+ httpOnly: true,
74
+ secure: process.env.NODE_ENV === "production",
75
+ sameSite: "lax",
76
+ maxAge: revalidate,
77
+ path: "/"
78
+ });
79
+ return response;
80
+ } catch {
81
+ if (cached) {
82
+ try {
83
+ const parsed = JSON.parse(cached);
84
+ if (parsed.valid) {
85
+ return import_server.NextResponse.next();
86
+ }
87
+ } catch {
88
+ }
89
+ }
90
+ return handleInvalid(request, config);
91
+ }
92
+ };
93
+ }
94
+ function handleInvalid(request, config) {
95
+ if (config.onInvalid) {
96
+ const url = request.nextUrl.clone();
97
+ url.pathname = config.onInvalid;
98
+ const response = import_server.NextResponse.redirect(url);
99
+ response.cookies.delete(COOKIE_NAME);
100
+ return response;
101
+ }
102
+ return new import_server.NextResponse(
103
+ JSON.stringify({ error: "License validation failed" }),
104
+ {
105
+ status: 403,
106
+ headers: { "Content-Type": "application/json" }
107
+ }
108
+ );
109
+ }
110
+ function isProtected(pathname, patterns) {
111
+ return patterns.some((pattern) => {
112
+ const regex = new RegExp(
113
+ "^" + pattern.replace(/\*/g, ".*").replace(/\//g, "\\/") + "$"
114
+ );
115
+ return regex.test(pathname);
116
+ });
117
+ }
118
+ function hostname() {
119
+ try {
120
+ return require("os").hostname();
121
+ } catch {
122
+ return "unknown";
123
+ }
124
+ }
125
+ // Annotate the CommonJS export names for ESM import in node:
126
+ 0 && (module.exports = {
127
+ withXcript
128
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,107 @@
1
+ import {
2
+ __require
3
+ } from "./chunk-Y6FXYEAI.mjs";
4
+
5
+ // src/index.ts
6
+ import { NextResponse } from "next/server";
7
+ var COOKIE_NAME = "__xcript_status";
8
+ var DEFAULT_REVALIDATE = 300;
9
+ function withXcript(config) {
10
+ const baseUrl = (config.baseUrl || "https://api.xcript.dev").replace(/\/+$/, "");
11
+ const revalidate = config.revalidateInterval ?? DEFAULT_REVALIDATE;
12
+ return async function middleware(request) {
13
+ const { pathname } = request.nextUrl;
14
+ if (config.protectedRoutes && !isProtected(pathname, config.protectedRoutes)) {
15
+ return NextResponse.next();
16
+ }
17
+ const cached = request.cookies.get(COOKIE_NAME)?.value;
18
+ if (cached) {
19
+ try {
20
+ const parsed = JSON.parse(cached);
21
+ const age = (Date.now() - parsed.timestamp) / 1e3;
22
+ if (age < revalidate && parsed.valid) {
23
+ return NextResponse.next();
24
+ }
25
+ } catch {
26
+ }
27
+ }
28
+ try {
29
+ const res = await fetch(`${baseUrl}/api/v1/validate`, {
30
+ method: "POST",
31
+ headers: {
32
+ "Content-Type": "application/json",
33
+ "X-Api-Key": config.apiKey
34
+ },
35
+ body: JSON.stringify({
36
+ license_key: config.licenseKey,
37
+ machine_id: `nextjs-${hostname()}`
38
+ })
39
+ });
40
+ if (!res.ok) {
41
+ return handleInvalid(request, config);
42
+ }
43
+ const data = await res.json();
44
+ if (!data.valid) {
45
+ return handleInvalid(request, config);
46
+ }
47
+ const response = NextResponse.next();
48
+ response.cookies.set(COOKIE_NAME, JSON.stringify({
49
+ valid: true,
50
+ timestamp: Date.now(),
51
+ config: data.config || {}
52
+ }), {
53
+ httpOnly: true,
54
+ secure: process.env.NODE_ENV === "production",
55
+ sameSite: "lax",
56
+ maxAge: revalidate,
57
+ path: "/"
58
+ });
59
+ return response;
60
+ } catch {
61
+ if (cached) {
62
+ try {
63
+ const parsed = JSON.parse(cached);
64
+ if (parsed.valid) {
65
+ return NextResponse.next();
66
+ }
67
+ } catch {
68
+ }
69
+ }
70
+ return handleInvalid(request, config);
71
+ }
72
+ };
73
+ }
74
+ function handleInvalid(request, config) {
75
+ if (config.onInvalid) {
76
+ const url = request.nextUrl.clone();
77
+ url.pathname = config.onInvalid;
78
+ const response = NextResponse.redirect(url);
79
+ response.cookies.delete(COOKIE_NAME);
80
+ return response;
81
+ }
82
+ return new NextResponse(
83
+ JSON.stringify({ error: "License validation failed" }),
84
+ {
85
+ status: 403,
86
+ headers: { "Content-Type": "application/json" }
87
+ }
88
+ );
89
+ }
90
+ function isProtected(pathname, patterns) {
91
+ return patterns.some((pattern) => {
92
+ const regex = new RegExp(
93
+ "^" + pattern.replace(/\*/g, ".*").replace(/\//g, "\\/") + "$"
94
+ );
95
+ return regex.test(pathname);
96
+ });
97
+ }
98
+ function hostname() {
99
+ try {
100
+ return __require("os").hostname();
101
+ } catch {
102
+ return "unknown";
103
+ }
104
+ }
105
+ export {
106
+ withXcript
107
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @xcript/next/server — Server-side utilities for license validation.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * // Server Action or Route Handler
7
+ * import { requireLicense, getLicense } from '@xcript/next/server'
8
+ *
9
+ * // Throws if license is invalid
10
+ * export async function POST() {
11
+ * const license = await requireLicense()
12
+ * // license.config.max_users → "50"
13
+ * }
14
+ *
15
+ * // Returns null if invalid (no throw)
16
+ * export async function GET() {
17
+ * const license = await getLicense()
18
+ * if (!license) return Response.json({ error: 'No license' }, { status: 403 })
19
+ * }
20
+ * ```
21
+ */
22
+ interface LicenseData {
23
+ /** Whether the license is valid. */
24
+ valid: boolean;
25
+ /** Dynamic config from the Xcript dashboard. */
26
+ config: Record<string, string>;
27
+ /** When the validation was performed (epoch ms). */
28
+ timestamp: number;
29
+ }
30
+ /**
31
+ * Get the current license state from the middleware cookie.
32
+ * Returns null if no valid license is found.
33
+ *
34
+ * Use this in Server Components, Server Actions, or Route Handlers.
35
+ */
36
+ declare function getLicense(): Promise<LicenseData | null>;
37
+ /**
38
+ * Require a valid license. Throws an error if the license is invalid.
39
+ *
40
+ * Use this at the top of protected Server Actions or Route Handlers.
41
+ *
42
+ * @throws Error if the license is not valid
43
+ */
44
+ declare function requireLicense(): Promise<LicenseData>;
45
+ /**
46
+ * Get a specific config value from the license.
47
+ * Returns undefined if the license is invalid or the key doesn't exist.
48
+ */
49
+ declare function getLicenseConfig(key: string): Promise<string | undefined>;
50
+
51
+ export { getLicense, getLicenseConfig, requireLicense };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @xcript/next/server — Server-side utilities for license validation.
3
+ *
4
+ * @example
5
+ * ```ts
6
+ * // Server Action or Route Handler
7
+ * import { requireLicense, getLicense } from '@xcript/next/server'
8
+ *
9
+ * // Throws if license is invalid
10
+ * export async function POST() {
11
+ * const license = await requireLicense()
12
+ * // license.config.max_users → "50"
13
+ * }
14
+ *
15
+ * // Returns null if invalid (no throw)
16
+ * export async function GET() {
17
+ * const license = await getLicense()
18
+ * if (!license) return Response.json({ error: 'No license' }, { status: 403 })
19
+ * }
20
+ * ```
21
+ */
22
+ interface LicenseData {
23
+ /** Whether the license is valid. */
24
+ valid: boolean;
25
+ /** Dynamic config from the Xcript dashboard. */
26
+ config: Record<string, string>;
27
+ /** When the validation was performed (epoch ms). */
28
+ timestamp: number;
29
+ }
30
+ /**
31
+ * Get the current license state from the middleware cookie.
32
+ * Returns null if no valid license is found.
33
+ *
34
+ * Use this in Server Components, Server Actions, or Route Handlers.
35
+ */
36
+ declare function getLicense(): Promise<LicenseData | null>;
37
+ /**
38
+ * Require a valid license. Throws an error if the license is invalid.
39
+ *
40
+ * Use this at the top of protected Server Actions or Route Handlers.
41
+ *
42
+ * @throws Error if the license is not valid
43
+ */
44
+ declare function requireLicense(): Promise<LicenseData>;
45
+ /**
46
+ * Get a specific config value from the license.
47
+ * Returns undefined if the license is invalid or the key doesn't exist.
48
+ */
49
+ declare function getLicenseConfig(key: string): Promise<string | undefined>;
50
+
51
+ export { getLicense, getLicenseConfig, requireLicense };
package/dist/server.js ADDED
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/server.ts
21
+ var server_exports = {};
22
+ __export(server_exports, {
23
+ getLicense: () => getLicense,
24
+ getLicenseConfig: () => getLicenseConfig,
25
+ requireLicense: () => requireLicense
26
+ });
27
+ module.exports = __toCommonJS(server_exports);
28
+ var import_headers = require("next/headers");
29
+ var COOKIE_NAME = "__xcript_status";
30
+ async function getLicense() {
31
+ try {
32
+ const cookieStore = await (0, import_headers.cookies)();
33
+ const raw = cookieStore.get(COOKIE_NAME)?.value;
34
+ if (!raw) return null;
35
+ const parsed = JSON.parse(raw);
36
+ if (!parsed.valid) return null;
37
+ return parsed;
38
+ } catch {
39
+ return null;
40
+ }
41
+ }
42
+ async function requireLicense() {
43
+ const license = await getLicense();
44
+ if (!license) {
45
+ throw new Error(
46
+ "Xcript: License validation required. Ensure withXcript() middleware is configured."
47
+ );
48
+ }
49
+ return license;
50
+ }
51
+ async function getLicenseConfig(key) {
52
+ const license = await getLicense();
53
+ return license?.config[key];
54
+ }
55
+ // Annotate the CommonJS export names for ESM import in node:
56
+ 0 && (module.exports = {
57
+ getLicense,
58
+ getLicenseConfig,
59
+ requireLicense
60
+ });
@@ -0,0 +1,35 @@
1
+ import "./chunk-Y6FXYEAI.mjs";
2
+
3
+ // src/server.ts
4
+ import { cookies } from "next/headers";
5
+ var COOKIE_NAME = "__xcript_status";
6
+ async function getLicense() {
7
+ try {
8
+ const cookieStore = await cookies();
9
+ const raw = cookieStore.get(COOKIE_NAME)?.value;
10
+ if (!raw) return null;
11
+ const parsed = JSON.parse(raw);
12
+ if (!parsed.valid) return null;
13
+ return parsed;
14
+ } catch {
15
+ return null;
16
+ }
17
+ }
18
+ async function requireLicense() {
19
+ const license = await getLicense();
20
+ if (!license) {
21
+ throw new Error(
22
+ "Xcript: License validation required. Ensure withXcript() middleware is configured."
23
+ );
24
+ }
25
+ return license;
26
+ }
27
+ async function getLicenseConfig(key) {
28
+ const license = await getLicense();
29
+ return license?.config[key];
30
+ }
31
+ export {
32
+ getLicense,
33
+ getLicenseConfig,
34
+ requireLicense
35
+ };
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "@xcript-dev/next",
3
+ "version": "0.1.0",
4
+ "description": "Next.js integration for Xcript — middleware, hooks, and server utilities for license validation",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.mjs",
11
+ "require": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./client": {
15
+ "import": "./dist/client.mjs",
16
+ "require": "./dist/client.js",
17
+ "types": "./dist/client.d.ts"
18
+ },
19
+ "./server": {
20
+ "import": "./dist/server.mjs",
21
+ "require": "./dist/server.js",
22
+ "types": "./dist/server.d.ts"
23
+ }
24
+ },
25
+ "files": [
26
+ "dist"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsup src/index.ts src/client.tsx src/server.ts --format cjs,esm --dts --clean --external react --external next --external @xcript-dev/sdk",
30
+ "dev": "tsup src/index.ts src/client.tsx src/server.ts --format cjs,esm --dts --watch --external react --external next --external @xcript-dev/sdk"
31
+ },
32
+ "keywords": [
33
+ "nextjs",
34
+ "licensing",
35
+ "xcript",
36
+ "middleware",
37
+ "react-hook"
38
+ ],
39
+ "license": "MIT",
40
+ "engines": {
41
+ "node": ">=18.0.0"
42
+ },
43
+ "sideEffects": false,
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "https://github.com/xcript/xcript-js",
47
+ "directory": "packages/next"
48
+ },
49
+ "dependencies": {
50
+ "@xcript-dev/sdk": "*"
51
+ },
52
+ "peerDependencies": {
53
+ "next": ">=14.0.0",
54
+ "react": ">=18.0.0"
55
+ },
56
+ "devDependencies": {
57
+ "typescript": "^5.4.0",
58
+ "tsup": "^8.0.0",
59
+ "@types/react": "^18.0.0",
60
+ "next": "^15.0.0",
61
+ "react": "^18.0.0"
62
+ }
63
+ }