nextjs-hasura-auth 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.
- package/APOLLO.md +148 -0
- package/GENERATOR.md +671 -0
- package/README.md +154 -0
- package/dist/lib/apollo.d.ts +45 -0
- package/dist/lib/apollo.js +206 -0
- package/dist/lib/debug.d.ts +12 -0
- package/dist/lib/debug.js +24 -0
- package/dist/lib/generator.d.ts +33 -0
- package/dist/lib/generator.js +548 -0
- package/dist/lib/index.d.ts +3 -0
- package/dist/lib/index.js +20 -0
- package/dist/lib/jwt.d.ts +67 -0
- package/dist/lib/jwt.js +195 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +8 -0
- package/dist/package.json +113 -0
- package/dist/tsconfig.lib.tsbuildinfo +1 -0
- package/package.json +116 -0
package/README.md
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
# Next.js Hasura Authentication Boilerplate
|
2
|
+
|
3
|
+
This project provides a robust starting point for building applications using Next.js (App Router), Hasura, and strong authentication patterns. It features JWT-based authentication with NextAuth.js, a secure GraphQL proxy to Hasura, direct WebSocket support for subscriptions, and a powerful dynamic query generator.
|
4
|
+
|
5
|
+
[](GENERATOR.md) [](APOLLO.md)
|
6
|
+
|
7
|
+
See [`GENERATOR.md`](GENERATOR.md) for detailed documentation on the dynamic GraphQL query generator, which simplifies creating queries, mutations, and subscriptions based on your Hasura schema.
|
8
|
+
|
9
|
+
See [`APOLLO.md`](APOLLO.md) for details on the configured Apollo Client instance and how it handles authenticated requests and subscriptions.
|
10
|
+
|
11
|
+
## ✨ Features Checklist
|
12
|
+
|
13
|
+
**Implemented:**
|
14
|
+
|
15
|
+
* [x] **Secure Hasura Proxy:** An integrated API route acts as a proxy to Hasura, securely handling requests using the user's session JWT while hiding the Hasura Admin Secret from the client.
|
16
|
+
* [x] **Credentials Authentication:** User authentication implemented using NextAuth.js with a login/password (Credentials) provider.
|
17
|
+
* [x] **Unified Apollo Client:** A configured Apollo Client instance handles both authenticated HTTP requests (via the proxy) and direct, authenticated WebSocket connections for subscriptions.
|
18
|
+
* [x] **Dynamic Query Generator:** A versatile query generator (`lib/generator.ts`) allows dynamic creation of GraphQL operations based on options and schema, suitable for client/server use.
|
19
|
+
* [x] **WebSocket Authentication:** Real-time subscriptions connect directly to Hasura via WebSockets, authenticated using the user's session JWT.
|
20
|
+
|
21
|
+
**Planned / Future Ideas:**
|
22
|
+
|
23
|
+
* [ ] **Convenience Hooks:** Create easy-to-use React hooks (`useQuery`, `useSubscription`, potentially a `useCRUD` hook/class) that integrate the `Generator` with Apollo Client for streamlined data fetching in components.
|
24
|
+
* [ ] **Multi-Platform Builds:** Native builders for Android, iOS, MacOS, Windows, Linux, Oculus (e.g., using Tauri, Capacitor, or Electron).
|
25
|
+
* [ ] **Unique Environment Builders:** Specific builds for Chrome Extensions, Firefox Extensions, and VSCode Extensions (including custom UI elements).
|
26
|
+
* [ ] Additional Authentication Providers (OAuth: Google, GitHub, etc.).
|
27
|
+
* [ ] Role-based access control examples.
|
28
|
+
* [ ] Advanced caching strategies.
|
29
|
+
* [ ] Comprehensive end-to-end testing setup.
|
30
|
+
|
31
|
+
## 🚀 Core Concepts
|
32
|
+
|
33
|
+
### 1. Authentication (NextAuth.js)
|
34
|
+
|
35
|
+
* Uses `NextAuth.js` for handling authentication flow.
|
36
|
+
* Configured with the **Credentials provider** for email/password login (see `pages/api/auth/[...nextauth].ts` or `app/api/auth/[...nextauth]/route.ts`).
|
37
|
+
* Manages sessions using **JWT**. The JWT contains essential user information and Hasura claims.
|
38
|
+
* Provides standard pages/routes for login, logout, and potentially signup.
|
39
|
+
|
40
|
+
### 2. Hasura Integration
|
41
|
+
|
42
|
+
Interaction with the Hasura GraphQL Engine is handled in two primary ways:
|
43
|
+
|
44
|
+
* **HTTP Requests (Queries/Mutations via Proxy):**
|
45
|
+
* Client-side GraphQL queries and mutations are sent to a Next.js API route (`/api/graphql-proxy` or similar).
|
46
|
+
* This proxy route retrieves the user's JWT from their session.
|
47
|
+
* It then forwards the GraphQL request to the actual Hasura endpoint (`HASURA_GRAPHQL_URL`).
|
48
|
+
* Crucially, the proxy uses the **`HASURA_ADMIN_SECRET`** to communicate with Hasura but includes the user's details (like `x-hasura-user-id`, `x-hasura-default-role` derived from the JWT) as session variables in the request headers.
|
49
|
+
* This ensures Hasura applies the correct permissions for the logged-in user while keeping the powerful `admin_secret` completely hidden from the browser.
|
50
|
+
* **WebSocket Connections (Subscriptions):**
|
51
|
+
* For real-time data via GraphQL Subscriptions, the client establishes a direct WebSocket connection to the Hasura endpoint (`wss://...`).
|
52
|
+
* Authentication for the WebSocket connection is handled by passing the user's session JWT within the `connectionParams`. Hasura verifies this token to authorize the subscription.
|
53
|
+
* The `components/auth/SocketAuthStatus.tsx` component likely demonstrates checking the status of this authenticated connection.
|
54
|
+
|
55
|
+
### 3. Apollo Client
|
56
|
+
|
57
|
+
* A pre-configured Apollo Client instance (`lib/apolloClient.ts` or similar) is set up to manage GraphQL data fetching.
|
58
|
+
* It intelligently handles both:
|
59
|
+
* **HTTP Link:** Points to the Next.js GraphQL proxy (`/api/graphql-proxy`) for queries and mutations.
|
60
|
+
* **WebSocket Link:** Connects directly to Hasura's WebSocket endpoint for subscriptions, including logic to pass the authentication token.
|
61
|
+
* The client can be used both client-side (with React hooks) and server-side (for SSR/SSG data fetching).
|
62
|
+
|
63
|
+
### 4. Dynamic Query Generation (`GENERATOR.md`)
|
64
|
+
|
65
|
+
* The core `Generator` function in `lib/generator.ts` allows you to build complex GraphQL operations dynamically based on a simple options object and your `schema.json`.
|
66
|
+
* This avoids writing lengthy GraphQL query strings manually.
|
67
|
+
* See [`GENERATOR.md`](GENERATOR.md) for full usage details and examples.
|
68
|
+
* *Convenience hooks (like `useQuery`, `useSubscription`, `useCRUD`) are planned to further simplify using the generator within React components.*
|
69
|
+
|
70
|
+
## 📁 Project Structure (Key Directories)
|
71
|
+
|
72
|
+
```
|
73
|
+
.
|
74
|
+
├── app/ # Next.js App Router (Pages, Layouts, API Routes)
|
75
|
+
│ ├── api/ # API routes (e.g., auth, graphql-proxy)
|
76
|
+
│ └── (main)/ # Main application pages/routes
|
77
|
+
├── components/ # Shared React components
|
78
|
+
│ ├── auth/ # Authentication-related components
|
79
|
+
│ └── ui/ # UI primitives (likely shadcn/ui)
|
80
|
+
├── lib/ # Core logic, utilities, client configurations
|
81
|
+
│ ├── apolloClient.ts # Apollo Client setup
|
82
|
+
│ ├── auth.ts # Authentication utilities/configs
|
83
|
+
│ ├── generator.ts # GraphQL Query Generator
|
84
|
+
│ ├── debug.ts # Debug utility
|
85
|
+
│ └── ...
|
86
|
+
├── public/ # Static assets
|
87
|
+
├── styles/ # Global styles
|
88
|
+
├── .env.local # Environment variables (Gitignored)
|
89
|
+
├── GENERATOR.md # Query Generator Documentation
|
90
|
+
├── schema.json # Hasura GraphQL schema (for Generator)
|
91
|
+
├── next.config.js # Next.js configuration
|
92
|
+
├── package.json # Project dependencies and scripts
|
93
|
+
└── tsconfig.json # TypeScript configuration
|
94
|
+
```
|
95
|
+
|
96
|
+
## 🛠️ Getting Started
|
97
|
+
|
98
|
+
1. **Clone the repository:**
|
99
|
+
```bash
|
100
|
+
git clone <repository-url>
|
101
|
+
cd <repository-directory>
|
102
|
+
```
|
103
|
+
|
104
|
+
2. **Install dependencies:**
|
105
|
+
```bash
|
106
|
+
npm install
|
107
|
+
# or
|
108
|
+
yarn install
|
109
|
+
# or
|
110
|
+
pnpm install
|
111
|
+
```
|
112
|
+
|
113
|
+
3. **Set up Environment Variables:**
|
114
|
+
Create a `.env.local` file in the root directory and add the following variables:
|
115
|
+
|
116
|
+
```env
|
117
|
+
# Hasura Configuration
|
118
|
+
NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT="<your-hasura-graphql-url>" # e.g., https://your-project.hasura.app/v1/graphql
|
119
|
+
NEXT_PUBLIC_HASURA_WS_ENDPOINT="<your-hasura-websocket-url>" # e.g., wss://your-project.hasura.app/v1/graphql
|
120
|
+
HASURA_ADMIN_SECRET="<your-hasura-admin-secret>"
|
121
|
+
|
122
|
+
# NextAuth.js Configuration
|
123
|
+
NEXTAUTH_URL="<your-deployment-url>" # e.g., http://localhost:3000 for local dev
|
124
|
+
NEXTAUTH_SECRET="<generate-a-strong-secret>" # Generate with: openssl rand -base64 32
|
125
|
+
|
126
|
+
# Other (if needed by your setup)
|
127
|
+
# DATABASE_URL="..."
|
128
|
+
```
|
129
|
+
* Replace `<...>` with your actual Hasura credentials and secrets.
|
130
|
+
* Ensure `NEXTAUTH_URL` points to your application's base URL.
|
131
|
+
|
132
|
+
4. **Update Hasura Schema:**
|
133
|
+
Make sure the `schema.json` file in the root is up-to-date with your Hasura instance's schema. You might need to fetch this from Hasura if you've made changes.
|
134
|
+
|
135
|
+
5. **Run the development server:**
|
136
|
+
```bash
|
137
|
+
npm run dev
|
138
|
+
# or
|
139
|
+
yarn dev
|
140
|
+
# or
|
141
|
+
pnpm dev
|
142
|
+
```
|
143
|
+
|
144
|
+
6. Open [http://localhost:3000](http://localhost:3000) (or your `NEXTAUTH_URL`) in your browser.
|
145
|
+
|
146
|
+
## Environment Variables Summary
|
147
|
+
|
148
|
+
* `NEXT_PUBLIC_HASURA_GRAPHQL_ENDPOINT`: Public URL for Hasura GraphQL HTTP endpoint.
|
149
|
+
* `NEXT_PUBLIC_HASURA_WS_ENDPOINT`: Public URL for Hasura GraphQL WebSocket endpoint.
|
150
|
+
* `HASURA_ADMIN_SECRET`: Your Hasura admin secret (kept server-side).
|
151
|
+
* `NEXTAUTH_URL`: The canonical URL of your Next.js application.
|
152
|
+
* `NEXTAUTH_SECRET`: A secret key used by NextAuth.js to sign JWTs, etc.
|
153
|
+
|
154
|
+
Let me know what you think!
|
@@ -0,0 +1,45 @@
|
|
1
|
+
import { ApolloClient } from '@apollo/client';
|
2
|
+
/**
|
3
|
+
* Get JWT secret from environment variables
|
4
|
+
* @returns {Uint8Array} Secret key for JWT signing
|
5
|
+
*/
|
6
|
+
export declare const getJwtSecret: () => Uint8Array;
|
7
|
+
interface ApolloOptions {
|
8
|
+
url?: string;
|
9
|
+
ws?: boolean;
|
10
|
+
token?: string;
|
11
|
+
secret?: string;
|
12
|
+
}
|
13
|
+
/**
|
14
|
+
* Create Apollo Client
|
15
|
+
*
|
16
|
+
* @param {Object} options - Options for creating the client
|
17
|
+
* @param {boolean} options.ws - Use WebSocket connection
|
18
|
+
* @param {string} options.token - JWT token for authorization
|
19
|
+
* @param {string} options.secret - Admin secret for Hasura
|
20
|
+
* @returns {ApolloClient} Apollo Client
|
21
|
+
*/
|
22
|
+
export declare function createClient(options?: ApolloOptions): ApolloClient<import("@apollo/client").NormalizedCacheObject>;
|
23
|
+
/**
|
24
|
+
* Get or create Apollo client instance
|
25
|
+
* @param options Client options
|
26
|
+
* @returns Apollo client instance
|
27
|
+
*/
|
28
|
+
export declare function getClient(options?: {}): ApolloClient<any>;
|
29
|
+
/**
|
30
|
+
* React hook to get Apollo client instance
|
31
|
+
* @returns Apollo client instance
|
32
|
+
*/
|
33
|
+
export declare function useClient(options: ApolloOptions): ApolloClient<import("@apollo/client").NormalizedCacheObject>;
|
34
|
+
/**
|
35
|
+
* Check connection to Hasura GraphQL endpoint
|
36
|
+
* @returns {Promise<boolean>} True if connection is successful
|
37
|
+
*/
|
38
|
+
export declare function checkConnection(client?: ApolloClient<any>): Promise<boolean>;
|
39
|
+
declare const _default: {
|
40
|
+
createClient: typeof createClient;
|
41
|
+
getClient: typeof getClient;
|
42
|
+
getJwtSecret: () => Uint8Array;
|
43
|
+
checkConnection: typeof checkConnection;
|
44
|
+
};
|
45
|
+
export default _default;
|
@@ -0,0 +1,206 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
+
};
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
15
|
+
exports.getJwtSecret = void 0;
|
16
|
+
exports.createClient = createClient;
|
17
|
+
exports.getClient = getClient;
|
18
|
+
exports.useClient = useClient;
|
19
|
+
exports.checkConnection = checkConnection;
|
20
|
+
const client_1 = require("@apollo/client");
|
21
|
+
const context_1 = require("@apollo/client/link/context");
|
22
|
+
const utilities_1 = require("@apollo/client/utilities");
|
23
|
+
const subscriptions_1 = require("@apollo/client/link/subscriptions");
|
24
|
+
const graphql_ws_1 = require("graphql-ws");
|
25
|
+
const cross_fetch_1 = __importDefault(require("cross-fetch"));
|
26
|
+
const debug_1 = __importDefault(require("./debug"));
|
27
|
+
const react_1 = require("react");
|
28
|
+
// Create a debug logger for this module
|
29
|
+
const debug = (0, debug_1.default)('apollo');
|
30
|
+
// Determine if running on client
|
31
|
+
const isClient = typeof window !== 'undefined';
|
32
|
+
/**
|
33
|
+
* Get JWT secret from environment variables
|
34
|
+
* @returns {Uint8Array} Secret key for JWT signing
|
35
|
+
*/
|
36
|
+
const getJwtSecret = () => {
|
37
|
+
try {
|
38
|
+
const jwtSecret = process.env.HASURA_JWT_SECRET || '{"type":"HS256","key":"your-secret-key"}';
|
39
|
+
// Parse JWT configuration (may be in JSON format)
|
40
|
+
let secretKey;
|
41
|
+
try {
|
42
|
+
const jwtConfig = typeof jwtSecret === 'string' ? JSON.parse(jwtSecret) : jwtSecret;
|
43
|
+
secretKey = jwtConfig.key;
|
44
|
+
if (!secretKey) {
|
45
|
+
throw new Error('JWT key not found in configuration');
|
46
|
+
}
|
47
|
+
}
|
48
|
+
catch (e) {
|
49
|
+
// If failed to parse as JSON, use as string
|
50
|
+
secretKey = jwtSecret;
|
51
|
+
}
|
52
|
+
// Convert key to Uint8Array (required for jose)
|
53
|
+
return new TextEncoder().encode(secretKey);
|
54
|
+
}
|
55
|
+
catch (error) {
|
56
|
+
debug('apollo', '❌ Error getting JWT secret:', error);
|
57
|
+
throw error;
|
58
|
+
}
|
59
|
+
};
|
60
|
+
exports.getJwtSecret = getJwtSecret;
|
61
|
+
/**
|
62
|
+
* Create Apollo Client
|
63
|
+
*
|
64
|
+
* @param {Object} options - Options for creating the client
|
65
|
+
* @param {boolean} options.ws - Use WebSocket connection
|
66
|
+
* @param {string} options.token - JWT token for authorization
|
67
|
+
* @param {string} options.secret - Admin secret for Hasura
|
68
|
+
* @returns {ApolloClient} Apollo Client
|
69
|
+
*/
|
70
|
+
function createClient(options = {}) {
|
71
|
+
// Default values
|
72
|
+
const { url = process.env.NEXT_PUBLIC_HASURA_GRAPHQL_URL, ws = false, token = undefined, secret = process.env.HASURA_ADMIN_SECRET } = options;
|
73
|
+
if (!url) {
|
74
|
+
throw new Error('❌ options.url or NEXT_PUBLIC_HASURA_GRAPHQL_URL not defined');
|
75
|
+
}
|
76
|
+
debug('apollo', '🔌 Creating Apollo client with endpoint:', url);
|
77
|
+
// HTTP connection without authorization
|
78
|
+
const publicHttpLink = new client_1.HttpLink({
|
79
|
+
uri: url,
|
80
|
+
fetch: cross_fetch_1.default,
|
81
|
+
});
|
82
|
+
// Create auth link with JWT token
|
83
|
+
const authLink = token
|
84
|
+
? (0, context_1.setContext)((_, { headers }) => {
|
85
|
+
return {
|
86
|
+
headers: Object.assign(Object.assign({}, headers), { Authorization: `Bearer ${token}` })
|
87
|
+
};
|
88
|
+
})
|
89
|
+
: client_1.ApolloLink.from([]);
|
90
|
+
// Choose link based on token or secret availability
|
91
|
+
let httpLink;
|
92
|
+
if (token) {
|
93
|
+
// If token provided, use it for authorization
|
94
|
+
httpLink = client_1.ApolloLink.from([authLink, publicHttpLink]);
|
95
|
+
}
|
96
|
+
else if (secret) {
|
97
|
+
// If no token but admin secret exists, use it
|
98
|
+
httpLink = new client_1.HttpLink({
|
99
|
+
uri: url,
|
100
|
+
fetch: cross_fetch_1.default,
|
101
|
+
headers: {
|
102
|
+
'x-hasura-admin-secret': secret || ''
|
103
|
+
}
|
104
|
+
});
|
105
|
+
;
|
106
|
+
}
|
107
|
+
else {
|
108
|
+
// If neither token nor secret, use public access
|
109
|
+
httpLink = publicHttpLink;
|
110
|
+
}
|
111
|
+
// Create link splitter for queries
|
112
|
+
let splitLink = httpLink;
|
113
|
+
// If WebSocket connection needed and we're in browser
|
114
|
+
if (ws && isClient) {
|
115
|
+
const wsEndpoint = url.replace('http', 'ws').replace('https', 'wss');
|
116
|
+
// Configure connection parameters
|
117
|
+
const connectionParams = {};
|
118
|
+
if (token) {
|
119
|
+
// If token provided, use it for WebSocket authorization
|
120
|
+
connectionParams.headers = {
|
121
|
+
Authorization: `Bearer ${token}`,
|
122
|
+
};
|
123
|
+
}
|
124
|
+
else if (secret) {
|
125
|
+
// If no token but admin secret exists, use it
|
126
|
+
connectionParams.headers = {
|
127
|
+
'x-hasura-admin-secret': secret,
|
128
|
+
};
|
129
|
+
}
|
130
|
+
// Create WebSocket client
|
131
|
+
const wsLink = new subscriptions_1.GraphQLWsLink((0, graphql_ws_1.createClient)({
|
132
|
+
url: wsEndpoint,
|
133
|
+
connectionParams: () => connectionParams
|
134
|
+
}));
|
135
|
+
// Split requests: WebSocket for subscriptions, HTTP for others
|
136
|
+
splitLink = (0, client_1.split)(({ query }) => {
|
137
|
+
const definition = (0, utilities_1.getMainDefinition)(query);
|
138
|
+
return (definition.kind === 'OperationDefinition' &&
|
139
|
+
definition.operation === 'subscription');
|
140
|
+
}, wsLink, httpLink);
|
141
|
+
}
|
142
|
+
// Create Apollo Client
|
143
|
+
return new client_1.ApolloClient({
|
144
|
+
link: splitLink,
|
145
|
+
cache: new client_1.InMemoryCache(),
|
146
|
+
defaultOptions: {
|
147
|
+
watchQuery: {
|
148
|
+
fetchPolicy: 'network-only',
|
149
|
+
errorPolicy: 'all',
|
150
|
+
},
|
151
|
+
query: {
|
152
|
+
fetchPolicy: 'network-only',
|
153
|
+
errorPolicy: 'all',
|
154
|
+
},
|
155
|
+
mutate: {
|
156
|
+
errorPolicy: 'all',
|
157
|
+
},
|
158
|
+
}
|
159
|
+
});
|
160
|
+
}
|
161
|
+
// Default client instance
|
162
|
+
let clientInstance = null;
|
163
|
+
/**
|
164
|
+
* Get or create Apollo client instance
|
165
|
+
* @param options Client options
|
166
|
+
* @returns Apollo client instance
|
167
|
+
*/
|
168
|
+
function getClient(options = {}) {
|
169
|
+
if (!clientInstance) {
|
170
|
+
clientInstance = createClient(options);
|
171
|
+
}
|
172
|
+
return clientInstance;
|
173
|
+
}
|
174
|
+
/**
|
175
|
+
* React hook to get Apollo client instance
|
176
|
+
* @returns Apollo client instance
|
177
|
+
*/
|
178
|
+
function useClient(options) {
|
179
|
+
return (0, react_1.useMemo)(() => createClient(options), [options]);
|
180
|
+
}
|
181
|
+
const CHECK_CONNECTION = (0, client_1.gql) `
|
182
|
+
query CheckConnection {
|
183
|
+
__schema {
|
184
|
+
queryType {
|
185
|
+
name
|
186
|
+
}
|
187
|
+
}
|
188
|
+
}
|
189
|
+
`;
|
190
|
+
/**
|
191
|
+
* Check connection to Hasura GraphQL endpoint
|
192
|
+
* @returns {Promise<boolean>} True if connection is successful
|
193
|
+
*/
|
194
|
+
function checkConnection() {
|
195
|
+
return __awaiter(this, arguments, void 0, function* (client = getClient()) {
|
196
|
+
var _a, _b, _c;
|
197
|
+
const result = yield client.query({ query: CHECK_CONNECTION });
|
198
|
+
return !!((_c = (_b = (_a = result.data) === null || _a === void 0 ? void 0 : _a.__schema) === null || _b === void 0 ? void 0 : _b.queryType) === null || _c === void 0 ? void 0 : _c.name);
|
199
|
+
});
|
200
|
+
}
|
201
|
+
exports.default = {
|
202
|
+
createClient,
|
203
|
+
getClient,
|
204
|
+
getJwtSecret: exports.getJwtSecret,
|
205
|
+
checkConnection
|
206
|
+
};
|
@@ -0,0 +1,12 @@
|
|
1
|
+
export type DebuggerFunction = (...args: any[]) => void;
|
2
|
+
/**
|
3
|
+
* Debug utility factory.
|
4
|
+
*
|
5
|
+
* Always returns a debugger function for the specified namespace.
|
6
|
+
* If no namespace is provided, uses 'app' as the default.
|
7
|
+
*
|
8
|
+
* @param namespace - Namespace for the debugger.
|
9
|
+
* @returns A debugger function for the specified namespace.
|
10
|
+
*/
|
11
|
+
declare function Debug(namespace?: string): DebuggerFunction;
|
12
|
+
export default Debug;
|
@@ -0,0 +1,24 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
+
};
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
+
const debug_1 = __importDefault(require("debug"));
|
7
|
+
// @ts-ignore
|
8
|
+
const package_json_1 = __importDefault(require("../package.json")); // Using relative path
|
9
|
+
// Initialize root debugger using package name
|
10
|
+
const rootDebug = (0, debug_1.default)(package_json_1.default.shortName || package_json_1.default.name);
|
11
|
+
/**
|
12
|
+
* Debug utility factory.
|
13
|
+
*
|
14
|
+
* Always returns a debugger function for the specified namespace.
|
15
|
+
* If no namespace is provided, uses 'app' as the default.
|
16
|
+
*
|
17
|
+
* @param namespace - Namespace for the debugger.
|
18
|
+
* @returns A debugger function for the specified namespace.
|
19
|
+
*/
|
20
|
+
function Debug(namespace) {
|
21
|
+
// Return the debugger function for that namespace, defaulting to 'app'
|
22
|
+
return rootDebug.extend(namespace || 'app');
|
23
|
+
}
|
24
|
+
exports.default = Debug;
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import { DocumentNode } from '@apollo/client/core';
|
2
|
+
export type GenerateOperation = 'query' | 'subscription' | 'insert' | 'update' | 'delete';
|
3
|
+
export interface GenerateOptions {
|
4
|
+
operation: GenerateOperation;
|
5
|
+
table: string;
|
6
|
+
where?: Record<string, any>;
|
7
|
+
returning?: (string | Record<string, any>)[] | Record<string, any> | string;
|
8
|
+
aggregate?: Record<string, any>;
|
9
|
+
object?: Record<string, any>;
|
10
|
+
objects?: Record<string, any>[];
|
11
|
+
pk_columns?: Record<string, any>;
|
12
|
+
_set?: Record<string, any>;
|
13
|
+
limit?: number;
|
14
|
+
offset?: number;
|
15
|
+
order_by?: Record<string, any>[] | Record<string, any>;
|
16
|
+
fragments?: string[];
|
17
|
+
variables?: Record<string, any>;
|
18
|
+
varCounter?: number;
|
19
|
+
}
|
20
|
+
export interface GenerateResult {
|
21
|
+
queryString: string;
|
22
|
+
query: DocumentNode;
|
23
|
+
variables: Record<string, any>;
|
24
|
+
varCounter: number;
|
25
|
+
}
|
26
|
+
/**
|
27
|
+
* Creates a GraphQL query generator based on the provided schema.
|
28
|
+
*
|
29
|
+
* @param schema - The GraphQL schema in schema.json format.
|
30
|
+
* @returns A function to generate queries.
|
31
|
+
*/
|
32
|
+
export declare function Generator(schema: any): (opts: GenerateOptions) => GenerateResult;
|
33
|
+
export default Generator;
|