@basictech/nextjs 0.6.0-beta.5 → 0.6.0-beta.7

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/index.mjs CHANGED
@@ -1,85 +1,69 @@
1
- "use client";
2
-
3
- // src/index.ts
4
- import dynamic from "next/dynamic";
5
- import { useBasic, useQuery } from "@basictech/react";
6
-
7
- // src/componets.tsx
8
- import * as Avatar from "@radix-ui/react-avatar";
9
- import * as Popover from "@radix-ui/react-popover";
10
- import { jsx, jsxs } from "react/jsx-runtime";
11
- var LoginButton = () => {
12
- return /* @__PURE__ */ jsxs(Popover.Root, { children: [
13
- /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(Avatar.Root, { style: avatarContainerStyle, children: [
14
- /* @__PURE__ */ jsx(
15
- Avatar.Image,
16
- {
17
- src: "https://via.placeholder.com/150",
18
- alt: "User Avatar",
19
- style: avatarImageStyle
20
- }
21
- ),
22
- /* @__PURE__ */ jsx(Avatar.Fallback, { delayMs: 600, style: avatarFallbackStyle, children: "U" })
23
- ] }) }),
24
- /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(Popover.Content, { style: popoverContentStyle, sideOffset: 10, children: [
25
- /* @__PURE__ */ jsx("p", { style: { marginBottom: "10px" }, children: "Hello, User!" }),
26
- /* @__PURE__ */ jsx("button", { style: buttonStyle, children: "Logout" }),
27
- /* @__PURE__ */ jsx(Popover.Arrow, { style: popoverArrowStyle })
28
- ] }) })
29
- ] });
1
+ // src/middleware.ts
2
+ import { NextResponse } from "next/server";
3
+ var DEFAULT_CONFIG = {
4
+ protectedRoutes: [],
5
+ publicRoutes: ["/login", "/signup", "/auth/*"],
6
+ signInUrl: "/login",
7
+ afterSignInUrl: "/",
8
+ tokenCookieName: "basic_access_token",
9
+ fullTokenCookieName: "basic_token"
30
10
  };
31
- var avatarContainerStyle = {
32
- display: "inline-flex",
33
- alignItems: "center",
34
- justifyContent: "center",
35
- width: "40px",
36
- height: "40px",
37
- borderRadius: "100%",
38
- backgroundColor: "#ccc",
39
- cursor: "pointer"
40
- };
41
- var avatarImageStyle = {
42
- width: "100%",
43
- height: "100%",
44
- borderRadius: "100%"
45
- // objectFit: 'cover',
46
- };
47
- var avatarFallbackStyle = {
48
- width: "100%",
49
- height: "100%",
50
- borderRadius: "100%",
51
- backgroundColor: "#007bff",
52
- color: "white",
53
- display: "flex",
54
- alignItems: "center",
55
- justifyContent: "center",
56
- fontSize: "20px"
57
- };
58
- var popoverContentStyle = {
59
- padding: "20px",
60
- borderRadius: "8px",
61
- // backgroundColor: 'white',
62
- boxShadow: "0 2px 10px rgba(0, 0, 0, 0.2)"
63
- };
64
- var buttonStyle = {
65
- padding: "8px 16px",
66
- backgroundColor: "#007bff",
67
- color: "#fff",
68
- border: "none",
69
- borderRadius: "4px",
70
- cursor: "pointer"
71
- };
72
- var popoverArrowStyle = {
73
- fill: "white"
74
- };
75
- var componets_default = LoginButton;
76
-
77
- // src/index.ts
78
- var BasicProvider = dynamic(() => import("@basictech/react").then((mod) => mod.BasicProvider), { ssr: false });
11
+ function matchesPattern(path, patterns) {
12
+ return patterns.some((pattern) => {
13
+ const regexPattern = pattern.replace(/\*/g, ".*").replace(/\//g, "\\/");
14
+ const regex = new RegExp(`^${regexPattern}$`);
15
+ return regex.test(path);
16
+ });
17
+ }
18
+ function hasValidToken(request, config) {
19
+ const token = request.cookies.get(config.tokenCookieName)?.value;
20
+ if (!token) {
21
+ return false;
22
+ }
23
+ return token.length > 0;
24
+ }
25
+ function getAuthFromRequest(request, config) {
26
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
27
+ const token = request.cookies.get(mergedConfig.tokenCookieName)?.value || null;
28
+ return {
29
+ isAuthenticated: !!token && token.length > 0,
30
+ token
31
+ };
32
+ }
33
+ function createBasicMiddleware(config) {
34
+ const mergedConfig = { ...DEFAULT_CONFIG, ...config };
35
+ return function middleware(request) {
36
+ const { pathname } = request.nextUrl;
37
+ if (pathname.startsWith("/_next") || pathname.startsWith("/api/_next") || pathname.includes(".")) {
38
+ return NextResponse.next();
39
+ }
40
+ if (matchesPattern(pathname, mergedConfig.publicRoutes)) {
41
+ return NextResponse.next();
42
+ }
43
+ const isProtectedRoute = mergedConfig.protectedRoutes.length === 0 ? true : matchesPattern(pathname, mergedConfig.protectedRoutes);
44
+ if (!isProtectedRoute) {
45
+ return NextResponse.next();
46
+ }
47
+ const isAuthenticated = hasValidToken(request, mergedConfig);
48
+ if (!isAuthenticated) {
49
+ const signInUrl = new URL(mergedConfig.signInUrl, request.url);
50
+ signInUrl.searchParams.set("returnUrl", pathname);
51
+ return NextResponse.redirect(signInUrl);
52
+ }
53
+ return NextResponse.next();
54
+ };
55
+ }
56
+ function withBasicAuth(request) {
57
+ return createBasicMiddleware()(request);
58
+ }
59
+ function getReturnUrl(request, defaultUrl = "/") {
60
+ const returnUrl = request.nextUrl.searchParams.get("returnUrl");
61
+ return returnUrl || defaultUrl;
62
+ }
79
63
  export {
80
- BasicProvider,
81
- componets_default as LoginButton,
82
- useBasic,
83
- useQuery
64
+ createBasicMiddleware,
65
+ getAuthFromRequest,
66
+ getReturnUrl,
67
+ withBasicAuth
84
68
  };
85
69
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/componets.tsx"],"sourcesContent":["'use client'\n\nimport dynamic from 'next/dynamic'\n\nimport { useBasic, useQuery } from \"@basictech/react\"\nimport LoginButton from \"./componets\";\n\n\nconst BasicProvider = dynamic(() => import('@basictech/react').then(mod => mod.BasicProvider), { ssr: false });\n\n\nexport {\n useBasic, BasicProvider, useQuery, LoginButton\n}","import React from 'react';\nimport * as Avatar from '@radix-ui/react-avatar';\nimport * as Popover from '@radix-ui/react-popover';\n\nconst LoginButton = () => {\n return (\n <Popover.Root>\n {/* Trigger: Avatar that will be clicked */}\n <Popover.Trigger asChild>\n <Avatar.Root style={avatarContainerStyle}>\n <Avatar.Image\n src=\"https://via.placeholder.com/150\"\n alt=\"User Avatar\"\n style={avatarImageStyle}\n />\n <Avatar.Fallback delayMs={600} style={avatarFallbackStyle}>\n U\n </Avatar.Fallback>\n </Avatar.Root>\n </Popover.Trigger>\n\n {/* Popover content */}\n <Popover.Portal>\n <Popover.Content style={popoverContentStyle} sideOffset={10}>\n <p style={{ marginBottom: '10px' }}>Hello, User!</p>\n <button style={buttonStyle}>Logout</button>\n <Popover.Arrow style={popoverArrowStyle} />\n </Popover.Content>\n </Popover.Portal>\n </Popover.Root>\n );\n};\n\n// Basic styles\nconst avatarContainerStyle = {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '40px',\n height: '40px',\n borderRadius: '100%',\n backgroundColor: '#ccc',\n cursor: 'pointer',\n};\n\nconst avatarImageStyle = {\n width: '100%',\n height: '100%',\n borderRadius: '100%',\n// objectFit: 'cover',\n};\n\nconst avatarFallbackStyle = {\n width: '100%',\n height: '100%',\n borderRadius: '100%',\n backgroundColor: '#007bff',\n color: 'white',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n fontSize: '20px',\n};\n\nconst popoverContentStyle = {\n padding: '20px',\n borderRadius: '8px',\n// backgroundColor: 'white',\n boxShadow: '0 2px 10px rgba(0, 0, 0, 0.2)',\n};\n\nconst buttonStyle = {\n padding: '8px 16px',\n backgroundColor: '#007bff',\n color: '#fff',\n border: 'none',\n borderRadius: '4px',\n cursor: 'pointer',\n};\n\nconst popoverArrowStyle = {\n fill: 'white',\n};\n\nexport default LoginButton;\n"],"mappings":";;;AAEA,OAAO,aAAa;AAEpB,SAAS,UAAU,gBAAgB;;;ACHnC,YAAY,YAAY;AACxB,YAAY,aAAa;AAOjB,SACE,KADF;AALR,IAAM,cAAc,MAAM;AACxB,SACE,qBAAS,cAAR,EAEC;AAAA,wBAAS,iBAAR,EAAgB,SAAO,MACtB,+BAAQ,aAAP,EAAY,OAAO,sBAClB;AAAA;AAAA,QAAQ;AAAA,QAAP;AAAA,UACC,KAAI;AAAA,UACJ,KAAI;AAAA,UACJ,OAAO;AAAA;AAAA,MACT;AAAA,MACA,oBAAQ,iBAAP,EAAgB,SAAS,KAAK,OAAO,qBAAqB,eAE3D;AAAA,OACF,GACF;AAAA,IAGA,oBAAS,gBAAR,EACC,+BAAS,iBAAR,EAAgB,OAAO,qBAAqB,YAAY,IACvD;AAAA,0BAAC,OAAE,OAAO,EAAE,cAAc,OAAO,GAAG,0BAAY;AAAA,MAChD,oBAAC,YAAO,OAAO,aAAa,oBAAM;AAAA,MAClC,oBAAS,eAAR,EAAc,OAAO,mBAAmB;AAAA,OAC3C,GACF;AAAA,KACF;AAEJ;AAGA,IAAM,uBAAuB;AAAA,EAC3B,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,QAAQ;AACV;AAEA,IAAM,mBAAmB;AAAA,EACvB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA;AAEhB;AAEA,IAAM,sBAAsB;AAAA,EAC1B,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB,UAAU;AACZ;AAEA,IAAM,sBAAsB;AAAA,EAC1B,SAAS;AAAA,EACT,cAAc;AAAA;AAAA,EAEd,WAAW;AACb;AAEA,IAAM,cAAc;AAAA,EAClB,SAAS;AAAA,EACT,iBAAiB;AAAA,EACjB,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,cAAc;AAAA,EACd,QAAQ;AACV;AAEA,IAAM,oBAAoB;AAAA,EACxB,MAAM;AACR;AAEA,IAAO,oBAAQ;;;AD5Ef,IAAM,gBAAgB,QAAQ,MAAM,OAAO,kBAAkB,EAAE,KAAK,SAAO,IAAI,aAAa,GAAG,EAAE,KAAK,MAAM,CAAC;","names":[]}
1
+ {"version":3,"sources":["../src/middleware.ts"],"sourcesContent":["import { NextRequest, NextResponse } from 'next/server'\n\n/**\n * Configuration options for the Basic auth middleware\n */\nexport interface BasicMiddlewareConfig {\n /**\n * Routes that require authentication\n * Supports glob patterns like '/dashboard/*', '/api/protected/*'\n */\n protectedRoutes?: string[]\n \n /**\n * Routes that are always public (bypass auth check)\n * Useful for login pages, public APIs, etc.\n */\n publicRoutes?: string[]\n \n /**\n * Where to redirect unauthenticated users\n * @default '/login'\n */\n signInUrl?: string\n \n /**\n * Where to redirect after successful sign-in\n * @default '/'\n */\n afterSignInUrl?: string\n \n /**\n * Cookie name for the access token\n * @default 'basic_access_token'\n */\n tokenCookieName?: string\n \n /**\n * Cookie name for the full token object\n * @default 'basic_token'\n */\n fullTokenCookieName?: string\n}\n\nconst DEFAULT_CONFIG: Required<BasicMiddlewareConfig> = {\n protectedRoutes: [],\n publicRoutes: ['/login', '/signup', '/auth/*'],\n signInUrl: '/login',\n afterSignInUrl: '/',\n tokenCookieName: 'basic_access_token',\n fullTokenCookieName: 'basic_token'\n}\n\n/**\n * Check if a path matches any of the patterns\n * Supports simple glob patterns with * wildcard\n */\nfunction matchesPattern(path: string, patterns: string[]): boolean {\n return patterns.some(pattern => {\n // Convert glob pattern to regex\n const regexPattern = pattern\n .replace(/\\*/g, '.*') // Replace * with .*\n .replace(/\\//g, '\\\\/') // Escape slashes\n const regex = new RegExp(`^${regexPattern}$`)\n return regex.test(path)\n })\n}\n\n/**\n * Check if the user has a valid token\n */\nfunction hasValidToken(request: NextRequest, config: Required<BasicMiddlewareConfig>): boolean {\n const token = request.cookies.get(config.tokenCookieName)?.value\n \n if (!token) {\n return false\n }\n \n // Basic validation - token exists and is not empty\n // For more thorough validation, you'd decode the JWT and check expiry\n // But that adds latency to every request\n return token.length > 0\n}\n\n/**\n * Get auth info from cookies\n */\nexport function getAuthFromRequest(request: NextRequest, config?: Partial<BasicMiddlewareConfig>): {\n isAuthenticated: boolean\n token: string | null\n} {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config }\n const token = request.cookies.get(mergedConfig.tokenCookieName)?.value || null\n \n return {\n isAuthenticated: !!token && token.length > 0,\n token\n }\n}\n\n/**\n * Create a Basic auth middleware for NextJS\n * \n * @example\n * // In middleware.ts at the root of your NextJS app:\n * import { createBasicMiddleware } from '@basictech/nextjs'\n * \n * export const middleware = createBasicMiddleware({\n * protectedRoutes: ['/dashboard/*', '/settings/*'],\n * publicRoutes: ['/login', '/signup', '/'],\n * signInUrl: '/login'\n * })\n * \n * export const config = {\n * matcher: ['/((?!_next/static|_next/image|favicon.ico).*)']\n * }\n */\nexport function createBasicMiddleware(config?: BasicMiddlewareConfig) {\n const mergedConfig = { ...DEFAULT_CONFIG, ...config }\n \n return function middleware(request: NextRequest): NextResponse {\n const { pathname } = request.nextUrl\n \n // Skip middleware for static files and Next.js internals\n if (\n pathname.startsWith('/_next') ||\n pathname.startsWith('/api/_next') ||\n pathname.includes('.') // Static files like .css, .js, .ico\n ) {\n return NextResponse.next()\n }\n \n // Check if route is explicitly public\n if (matchesPattern(pathname, mergedConfig.publicRoutes)) {\n return NextResponse.next()\n }\n \n // Check if route is protected\n const isProtectedRoute = mergedConfig.protectedRoutes.length === 0 \n ? true // If no protected routes specified, protect everything except public\n : matchesPattern(pathname, mergedConfig.protectedRoutes)\n \n if (!isProtectedRoute) {\n return NextResponse.next()\n }\n \n // Check authentication\n const isAuthenticated = hasValidToken(request, mergedConfig)\n \n if (!isAuthenticated) {\n // Redirect to sign-in page with return URL\n const signInUrl = new URL(mergedConfig.signInUrl, request.url)\n signInUrl.searchParams.set('returnUrl', pathname)\n \n return NextResponse.redirect(signInUrl)\n }\n \n // User is authenticated, allow the request\n return NextResponse.next()\n }\n}\n\n/**\n * Simple auth check middleware - redirects unauthenticated users\n * \n * @example\n * // In middleware.ts\n * import { withBasicAuth } from '@basictech/nextjs'\n * \n * export const middleware = withBasicAuth\n * \n * export const config = {\n * matcher: ['/dashboard/:path*', '/settings/:path*']\n * }\n */\nexport function withBasicAuth(request: NextRequest): NextResponse {\n return createBasicMiddleware()(request)\n}\n\n/**\n * Helper to get the return URL from search params\n */\nexport function getReturnUrl(request: NextRequest, defaultUrl: string = '/'): string {\n const returnUrl = request.nextUrl.searchParams.get('returnUrl')\n return returnUrl || defaultUrl\n}\n\n"],"mappings":";AAAA,SAAsB,oBAAoB;AA2C1C,IAAM,iBAAkD;AAAA,EACtD,iBAAiB,CAAC;AAAA,EAClB,cAAc,CAAC,UAAU,WAAW,SAAS;AAAA,EAC7C,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,iBAAiB;AAAA,EACjB,qBAAqB;AACvB;AAMA,SAAS,eAAe,MAAc,UAA6B;AACjE,SAAO,SAAS,KAAK,aAAW;AAE9B,UAAM,eAAe,QAClB,QAAQ,OAAO,IAAI,EACnB,QAAQ,OAAO,KAAK;AACvB,UAAM,QAAQ,IAAI,OAAO,IAAI,YAAY,GAAG;AAC5C,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB,CAAC;AACH;AAKA,SAAS,cAAc,SAAsB,QAAkD;AAC7F,QAAM,QAAQ,QAAQ,QAAQ,IAAI,OAAO,eAAe,GAAG;AAE3D,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,EACT;AAKA,SAAO,MAAM,SAAS;AACxB;AAKO,SAAS,mBAAmB,SAAsB,QAGvD;AACA,QAAM,eAAe,EAAE,GAAG,gBAAgB,GAAG,OAAO;AACpD,QAAM,QAAQ,QAAQ,QAAQ,IAAI,aAAa,eAAe,GAAG,SAAS;AAE1E,SAAO;AAAA,IACL,iBAAiB,CAAC,CAAC,SAAS,MAAM,SAAS;AAAA,IAC3C;AAAA,EACF;AACF;AAmBO,SAAS,sBAAsB,QAAgC;AACpE,QAAM,eAAe,EAAE,GAAG,gBAAgB,GAAG,OAAO;AAEpD,SAAO,SAAS,WAAW,SAAoC;AAC7D,UAAM,EAAE,SAAS,IAAI,QAAQ;AAG7B,QACE,SAAS,WAAW,QAAQ,KAC5B,SAAS,WAAW,YAAY,KAChC,SAAS,SAAS,GAAG,GACrB;AACA,aAAO,aAAa,KAAK;AAAA,IAC3B;AAGA,QAAI,eAAe,UAAU,aAAa,YAAY,GAAG;AACvD,aAAO,aAAa,KAAK;AAAA,IAC3B;AAGA,UAAM,mBAAmB,aAAa,gBAAgB,WAAW,IAC7D,OACA,eAAe,UAAU,aAAa,eAAe;AAEzD,QAAI,CAAC,kBAAkB;AACrB,aAAO,aAAa,KAAK;AAAA,IAC3B;AAGA,UAAM,kBAAkB,cAAc,SAAS,YAAY;AAE3D,QAAI,CAAC,iBAAiB;AAEpB,YAAM,YAAY,IAAI,IAAI,aAAa,WAAW,QAAQ,GAAG;AAC7D,gBAAU,aAAa,IAAI,aAAa,QAAQ;AAEhD,aAAO,aAAa,SAAS,SAAS;AAAA,IACxC;AAGA,WAAO,aAAa,KAAK;AAAA,EAC3B;AACF;AAeO,SAAS,cAAc,SAAoC;AAChE,SAAO,sBAAsB,EAAE,OAAO;AACxC;AAKO,SAAS,aAAa,SAAsB,aAAqB,KAAa;AACnF,QAAM,YAAY,QAAQ,QAAQ,aAAa,IAAI,WAAW;AAC9D,SAAO,aAAa;AACtB;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basictech/nextjs",
3
- "version": "0.6.0-beta.5",
3
+ "version": "0.6.0-beta.7",
4
4
  "description": "",
5
5
  "private": false,
6
6
  "publishConfig": {
@@ -9,6 +9,27 @@
9
9
  "main": "dist/index.js",
10
10
  "module": "dist/index.mjs",
11
11
  "types": "dist/index.d.ts",
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.mjs",
16
+ "require": "./dist/index.js",
17
+ "default": "./src/index.ts"
18
+ },
19
+ "./client": {
20
+ "types": "./dist/client.d.ts",
21
+ "import": "./dist/client.mjs",
22
+ "require": "./dist/client.js",
23
+ "default": "./src/client.ts"
24
+ }
25
+ },
26
+ "typesVersions": {
27
+ "*": {
28
+ "client": [
29
+ "./dist/client.d.ts"
30
+ ]
31
+ }
32
+ },
12
33
  "scripts": {
13
34
  "build": "tsup",
14
35
  "dev": "tsup --watch",
@@ -17,7 +38,7 @@
17
38
  "author": "",
18
39
  "license": "ISC",
19
40
  "dependencies": {
20
- "@basictech/react": "0.7.0-beta.5",
41
+ "@basictech/react": "0.7.0-beta.7",
21
42
  "@radix-ui/react-avatar": "^1.1.1",
22
43
  "@radix-ui/react-popover": "^1.1.2"
23
44
  },
@@ -29,6 +50,6 @@
29
50
  },
30
51
  "peerDependencies": {
31
52
  "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
32
- "next": "^14.0.0"
53
+ "next": "^14.0.0 || ^15.0.0 || ^16.0.0"
33
54
  }
34
55
  }