@qelos/integrator-next 4.0.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/LICENSE +20 -0
- package/README.md +256 -0
- package/dist/context.d.ts +55 -0
- package/dist/context.js +131 -0
- package/dist/context.js.map +1 -0
- package/dist/env-config.d.ts +28 -0
- package/dist/env-config.js +59 -0
- package/dist/env-config.js.map +1 -0
- package/dist/forward-headers.d.ts +7 -0
- package/dist/forward-headers.js +16 -0
- package/dist/forward-headers.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware.d.ts +68 -0
- package/dist/middleware.js +140 -0
- package/dist/middleware.js.map +1 -0
- package/dist/pages.d.ts +54 -0
- package/dist/pages.js +190 -0
- package/dist/pages.js.map +1 -0
- package/dist/route.d.ts +15 -0
- package/dist/route.js +21 -0
- package/dist/route.js.map +1 -0
- package/dist/sdk-factory.d.ts +20 -0
- package/dist/sdk-factory.js +90 -0
- package/dist/sdk-factory.js.map +1 -0
- package/dist/social-auth.d.ts +12 -0
- package/dist/social-auth.js +14 -0
- package/dist/social-auth.js.map +1 -0
- package/dist/types.d.ts +39 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/package.json +91 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Polyform Shield License 1.0.0
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Velocitech LTD
|
|
4
|
+
|
|
5
|
+
Your use of this software is governed by the Polyform Shield License 1.0.0.
|
|
6
|
+
|
|
7
|
+
You may obtain a copy of the License at:
|
|
8
|
+
https://polyformproject.org/licenses/shield/1.0.0
|
|
9
|
+
|
|
10
|
+
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
|
|
12
|
+
Additional Terms – Exception Notice:
|
|
13
|
+
|
|
14
|
+
The author of this software grants additional permissions beyond the Polyform Shield License 1.0.0:
|
|
15
|
+
|
|
16
|
+
✅ All uses of the software are permitted — including modification, distribution, commercial use, and sublicensing — as long as the software is not used to create, offer, or operate any product or service that competes directly with Qelos (https://qelos.io), a no-code platform for building AI-assisted SaaS applications.
|
|
17
|
+
|
|
18
|
+
❌ "Direct competition" includes platforms, tools, or services that enable users to visually or programmatically create SaaS applications with the assistance of artificial intelligence.
|
|
19
|
+
|
|
20
|
+
This exception does not modify the terms of the original Polyform Shield License for other users and applies only by explicit permission of the licensor.
|
package/README.md
ADDED
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
# @qelos/integrator-next
|
|
2
|
+
|
|
3
|
+
Qelos integrator middleware for **Next.js** — supports both the **App Router**
|
|
4
|
+
and the **Pages Router**, on Next.js **14** and **15**. Drop it into your
|
|
5
|
+
Next.js app to identify the user and active workspace via the Qelos SDK
|
|
6
|
+
*before* your own handlers run, and to keep refresh-token cookies fresh on
|
|
7
|
+
every request.
|
|
8
|
+
|
|
9
|
+
The package is a sibling of `@qelos/integrator-express` and
|
|
10
|
+
`@qelos/integrator-nuxt` — they all expose the same `QelosRequestContext`
|
|
11
|
+
shape (`{ user, workspace, workspaces, sdk, tokens }`).
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @qelos/integrator-next @qelos/sdk
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`next` (>=13.4) and `react` are peer dependencies. Tested with Next.js 14.2
|
|
20
|
+
and 15.x on both the App Router and the Pages Router.
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
Set `QELOS_APP_URL` (and any optional vars below) in your environment, then
|
|
25
|
+
re-export the pre-built middleware and use the no-arg context loader:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// middleware.ts
|
|
29
|
+
export { qelosMiddleware as middleware } from '@qelos/integrator-next/middleware';
|
|
30
|
+
|
|
31
|
+
export const config = {
|
|
32
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
33
|
+
};
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```tsx
|
|
37
|
+
// app/dashboard/page.tsx
|
|
38
|
+
import { getQelosContext } from '@qelos/integrator-next/context';
|
|
39
|
+
|
|
40
|
+
export default async function Dashboard() {
|
|
41
|
+
const { user, sdk } = await getQelosContext();
|
|
42
|
+
if (!user) return <p>Please sign in.</p>;
|
|
43
|
+
const products = await sdk.entities('products').getList();
|
|
44
|
+
return <div>Welcome {user.fullName}, you have {products.length} products</div>;
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Environment variables
|
|
49
|
+
|
|
50
|
+
| Variable | Default | Description |
|
|
51
|
+
|---|---|---|
|
|
52
|
+
| `QELOS_APP_URL` | — (required) | Qelos backend base URL |
|
|
53
|
+
| `QELOS_API_TOKEN` | — | Service-to-service token (skips refresh logic) |
|
|
54
|
+
| `QELOS_ACCESS_TOKEN_COOKIE` | `q_access_token` | Cookie name for the access token |
|
|
55
|
+
| `QELOS_REFRESH_TOKEN_COOKIE` | `q_refresh_token` | Cookie name for the refresh token |
|
|
56
|
+
| `QELOS_REQUIRE_AUTH` | `false` | Set `true` to reject anonymous requests with 401 |
|
|
57
|
+
| `QELOS_SKIP_PATHS` | — | Comma-separated path prefixes to bypass entirely |
|
|
58
|
+
|
|
59
|
+
## Explicit configuration (App Router)
|
|
60
|
+
|
|
61
|
+
When you need control over `resolveWorkspace`, `onTokenRefresh`, or any other
|
|
62
|
+
option, call the factory yourself.
|
|
63
|
+
|
|
64
|
+
### 1. Edge middleware
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
// middleware.ts
|
|
68
|
+
import { createQelosMiddleware } from '@qelos/integrator-next/middleware';
|
|
69
|
+
|
|
70
|
+
export default createQelosMiddleware({
|
|
71
|
+
config: {
|
|
72
|
+
appUrl: process.env.QELOS_APP_URL!,
|
|
73
|
+
skipPaths: ['/_next', '/favicon.ico'],
|
|
74
|
+
requireAuth: false,
|
|
75
|
+
},
|
|
76
|
+
resolveWorkspace: ({ req, workspaces }) => {
|
|
77
|
+
const slug = req.nextUrl.searchParams.get('workspace');
|
|
78
|
+
return workspaces.find((w) => (w as any).slug === slug) ?? workspaces[0] ?? null;
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const config = {
|
|
83
|
+
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
84
|
+
};
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
The middleware:
|
|
88
|
+
|
|
89
|
+
- Reads tokens from cookies (`q_access_token`, `q_refresh_token`) or the
|
|
90
|
+
`Authorization` header.
|
|
91
|
+
- Calls the Qelos SDK to resolve the user and the active workspace.
|
|
92
|
+
- Forwards the resolved ids to downstream handlers via the
|
|
93
|
+
`x-qelos-user-id` and `x-qelos-workspace-id` request headers.
|
|
94
|
+
- Refreshes the access/refresh token pair when needed and writes the new
|
|
95
|
+
cookies onto the outbound response.
|
|
96
|
+
- Returns `401` early when `config.requireAuth: true` and the user cannot be
|
|
97
|
+
resolved.
|
|
98
|
+
|
|
99
|
+
### 2. Server components (RSC)
|
|
100
|
+
|
|
101
|
+
`getQelosContext()` is safe to call inside React Server Components on both
|
|
102
|
+
Next.js 14 (sync `cookies()` / `headers()`) and Next.js 15 (async). Wrap it
|
|
103
|
+
with React's `cache()` so re-renders within the same request reuse the result:
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
// lib/qelos.ts
|
|
107
|
+
import { cache } from 'react';
|
|
108
|
+
import { getQelosContext } from '@qelos/integrator-next/context';
|
|
109
|
+
|
|
110
|
+
export const loadQelos = cache(() => getQelosContext());
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
// app/page.tsx
|
|
115
|
+
import { loadQelos } from '../lib/qelos';
|
|
116
|
+
|
|
117
|
+
export default async function Page() {
|
|
118
|
+
const { user, workspace } = await loadQelos();
|
|
119
|
+
return <p>Hello {user?.fullName ?? 'guest'} — {workspace?.name}</p>;
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### 3. Route handlers (`app/api/**/route.ts`)
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
// app/api/me/route.ts
|
|
127
|
+
import { NextResponse } from 'next/server';
|
|
128
|
+
import { withQelosRoute } from '@qelos/integrator-next/route';
|
|
129
|
+
|
|
130
|
+
export const GET = withQelosRoute((_req, _ctx, qelos) => {
|
|
131
|
+
if (!qelos.user) return NextResponse.json({ user: null });
|
|
132
|
+
return NextResponse.json({ user: qelos.user, workspace: qelos.workspace });
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Anywhere downstream — including modules outside the React tree — can read the
|
|
137
|
+
active context from AsyncLocalStorage via `getStoredQelosContext()`, provided
|
|
138
|
+
execution went through `withQelosRoute`, `withQelosContext`, or one of the
|
|
139
|
+
Pages Router wrappers.
|
|
140
|
+
|
|
141
|
+
```ts
|
|
142
|
+
// services/products.ts
|
|
143
|
+
import { getStoredQelosContext } from '@qelos/integrator-next/context';
|
|
144
|
+
|
|
145
|
+
export async function listProducts() {
|
|
146
|
+
const qelos = getStoredQelosContext();
|
|
147
|
+
if (!qelos?.sdk) throw new Error('no qelos context');
|
|
148
|
+
return qelos.sdk.entities('products').getList();
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Pages Router
|
|
153
|
+
|
|
154
|
+
### API routes
|
|
155
|
+
|
|
156
|
+
```ts
|
|
157
|
+
// pages/api/me.ts
|
|
158
|
+
import { withQelosApi } from '@qelos/integrator-next/pages';
|
|
159
|
+
|
|
160
|
+
export default withQelosApi(
|
|
161
|
+
(req, res) => {
|
|
162
|
+
res.json({ user: req.qelos!.user, workspace: req.qelos!.workspace });
|
|
163
|
+
},
|
|
164
|
+
{ config: { appUrl: process.env.QELOS_APP_URL! } },
|
|
165
|
+
);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### `getServerSideProps`
|
|
169
|
+
|
|
170
|
+
```ts
|
|
171
|
+
// pages/dashboard.tsx
|
|
172
|
+
import { withQelosSSR } from '@qelos/integrator-next/pages';
|
|
173
|
+
|
|
174
|
+
export const getServerSideProps = withQelosSSR(
|
|
175
|
+
async (_ctx, qelos) => ({ props: { user: qelos.user, workspace: qelos.workspace } }),
|
|
176
|
+
{ config: { appUrl: process.env.QELOS_APP_URL!, requireAuth: true } },
|
|
177
|
+
);
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
## Token refresh
|
|
181
|
+
|
|
182
|
+
When a request arrives with an expired access token, the SDK's failed-auth
|
|
183
|
+
path triggers a refresh, in order:
|
|
184
|
+
|
|
185
|
+
1. If a refresh token is present, calls
|
|
186
|
+
`sdk.authentication.refreshToken()` (`POST /api/token/refresh`) — issues a
|
|
187
|
+
new access + refresh pair.
|
|
188
|
+
2. Otherwise, calls `sdk.authentication.refreshCookieToken()`
|
|
189
|
+
(`POST /api/cookie/refresh`) — used for cookie-only sessions that do not
|
|
190
|
+
carry a separate refresh token (e.g. social-auth flows).
|
|
191
|
+
|
|
192
|
+
The new pair is then written back to cookies using the configured
|
|
193
|
+
`accessTokenCookie` / `refreshTokenCookie` names — automatically in App
|
|
194
|
+
Router middleware (`response.cookies.set`), Pages Router API routes
|
|
195
|
+
(`Set-Cookie` header), and `getServerSideProps` responses.
|
|
196
|
+
|
|
197
|
+
App Router server components and route handlers cannot mutate cookies after
|
|
198
|
+
rendering starts, so the default refresh hook there is a no-op — the new
|
|
199
|
+
tokens are still applied to the in-memory pair so subsequent SDK calls in the
|
|
200
|
+
same request use the fresh access token. To persist the refreshed pair, hand
|
|
201
|
+
the request off to a route handler that calls `cookies().set(...)`.
|
|
202
|
+
|
|
203
|
+
Override the behaviour by passing `onTokenRefresh` to any of the wrappers.
|
|
204
|
+
The hook receives:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
interface TokenRefreshContext<T> {
|
|
208
|
+
target: T; // NextResponse | NextApiResponse | ServerResponse | null
|
|
209
|
+
oldTokens: { accessToken?: string; refreshToken?: string };
|
|
210
|
+
newTokens: { accessToken: string; refreshToken?: string };
|
|
211
|
+
sdk: QelosSDK;
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Manual cookie refresh
|
|
216
|
+
|
|
217
|
+
Long-lived integrator-hosted sessions can also call the SDK directly to
|
|
218
|
+
proactively refresh the cookie token. From a route handler that owns the
|
|
219
|
+
response (so it can mutate cookies):
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
// app/api/session/refresh/route.ts
|
|
223
|
+
import { NextResponse } from 'next/server';
|
|
224
|
+
import { withQelosRoute } from '@qelos/integrator-next/route';
|
|
225
|
+
|
|
226
|
+
export const POST = withQelosRoute(async (_req, _ctx, qelos) => {
|
|
227
|
+
const result = await qelos.sdk.authentication.refreshCookieToken();
|
|
228
|
+
// result.headers['set-cookie'] — fresh cookie value to forward
|
|
229
|
+
return NextResponse.json({ user: result.payload.user });
|
|
230
|
+
});
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
## Configuration
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
interface QelosNextConfig {
|
|
237
|
+
appUrl: string; // Qelos backend base URL
|
|
238
|
+
apiToken?: string; // service-to-service token (skips refresh logic)
|
|
239
|
+
accessTokenCookie?: string; // default 'q_access_token'
|
|
240
|
+
refreshTokenCookie?: string; // default 'q_refresh_token'
|
|
241
|
+
requireAuth?: boolean; // 401/redirect on anonymous (default false)
|
|
242
|
+
skipPaths?: string[]; // path prefixes to bypass entirely
|
|
243
|
+
sdkOptions?: Partial<QelosSDKOptions>;
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Subpath exports
|
|
248
|
+
|
|
249
|
+
| Import | Purpose |
|
|
250
|
+
|---|---|
|
|
251
|
+
| `@qelos/integrator-next` | Everything (re-exports of all subpaths) |
|
|
252
|
+
| `@qelos/integrator-next/middleware` | Edge middleware (`qelosMiddleware`, `createQelosMiddleware`) |
|
|
253
|
+
| `@qelos/integrator-next/context` | Server-component / route-handler context (`getQelosContext`, `getStoredQelosContext`) |
|
|
254
|
+
| `@qelos/integrator-next/route` | App Router route wrapper (`withQelosRoute`) |
|
|
255
|
+
| `@qelos/integrator-next/pages` | Pages Router wrappers (`withQelosApi`, `withQelosSSR`) |
|
|
256
|
+
| `@qelos/integrator-next/types` | Shared types |
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { IUser } from '@qelos/sdk/dist/authentication';
|
|
2
|
+
import type { IWorkspace } from '@qelos/sdk/workspaces';
|
|
3
|
+
import type { QelosNextConfig, QelosRequestContext, TokenRefreshHook } from './types';
|
|
4
|
+
/**
|
|
5
|
+
* Run `fn` with `ctx` as the active Qelos request context. Code anywhere in
|
|
6
|
+
* the resulting async stack can call `getStoredQelosContext()` to retrieve it
|
|
7
|
+
* without prop-drilling.
|
|
8
|
+
*/
|
|
9
|
+
export declare function runWithQelosContext<T>(ctx: QelosRequestContext, fn: () => T | Promise<T>): T | Promise<T>;
|
|
10
|
+
/**
|
|
11
|
+
* Return the Qelos request context stored on the current async stack, or
|
|
12
|
+
* `null` when no context has been entered.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getStoredQelosContext(): QelosRequestContext | null;
|
|
15
|
+
export interface GetQelosContextOptions {
|
|
16
|
+
config: QelosNextConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Hook invoked after a successful token refresh. App Router server
|
|
19
|
+
* components and route handlers cannot mutate cookies after rendering
|
|
20
|
+
* starts, so the default is a no-op. Callers handling refresh through a
|
|
21
|
+
* route handler can override this to call `cookies().set(...)`.
|
|
22
|
+
*/
|
|
23
|
+
onTokenRefresh?: TokenRefreshHook<null>;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve the active workspace for a request. Defaults to picking the first
|
|
26
|
+
* workspace returned from `sdk.workspaces.getList()`.
|
|
27
|
+
*/
|
|
28
|
+
resolveWorkspace?: (params: {
|
|
29
|
+
user: IUser;
|
|
30
|
+
workspaces: IWorkspace[];
|
|
31
|
+
}) => IWorkspace | null | Promise<IWorkspace | null>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Identify the user / workspace for the current App Router request and
|
|
35
|
+
* return the Qelos context. Safe to call multiple times within the same
|
|
36
|
+
* request — each call performs its own SDK round-trip, so wrap it with
|
|
37
|
+
* React's `cache()` if you want a single resolution per render.
|
|
38
|
+
*
|
|
39
|
+
* Calling without arguments uses the env-derived config (see
|
|
40
|
+
* {@link loadQelosConfigFromEnv}); pass `{ config }` explicitly when you
|
|
41
|
+
* need full control or want to override resolution behavior.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getQelosContext(options?: GetQelosContextOptions): Promise<QelosRequestContext>;
|
|
44
|
+
/**
|
|
45
|
+
* Convenience wrapper: resolve the Qelos context, store it in
|
|
46
|
+
* AsyncLocalStorage, and run `fn` inside that scope. Useful as the top of an
|
|
47
|
+
* App Router route handler when you want downstream code (utility modules,
|
|
48
|
+
* etc.) to read the context via `getStoredQelosContext()`.
|
|
49
|
+
*/
|
|
50
|
+
export declare function withQelosContext<T>(options: GetQelosContextOptions, fn: (ctx: QelosRequestContext) => T | Promise<T>): Promise<T>;
|
|
51
|
+
/**
|
|
52
|
+
* Throw a 401-like error if the current stored context has no user.
|
|
53
|
+
* Returns the context for chaining.
|
|
54
|
+
*/
|
|
55
|
+
export declare function requireQelosUser(): QelosRequestContext;
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { getDefaultQelosConfig } from './env-config';
|
|
3
|
+
import { createRequestSdk } from './sdk-factory';
|
|
4
|
+
const DEFAULT_ACCESS_COOKIE = 'q_access_token';
|
|
5
|
+
const DEFAULT_REFRESH_COOKIE = 'q_refresh_token';
|
|
6
|
+
const storage = new AsyncLocalStorage();
|
|
7
|
+
/**
|
|
8
|
+
* Run `fn` with `ctx` as the active Qelos request context. Code anywhere in
|
|
9
|
+
* the resulting async stack can call `getStoredQelosContext()` to retrieve it
|
|
10
|
+
* without prop-drilling.
|
|
11
|
+
*/
|
|
12
|
+
export function runWithQelosContext(ctx, fn) {
|
|
13
|
+
return storage.run(ctx, fn);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Return the Qelos request context stored on the current async stack, or
|
|
17
|
+
* `null` when no context has been entered.
|
|
18
|
+
*/
|
|
19
|
+
export function getStoredQelosContext() {
|
|
20
|
+
return storage.getStore() || null;
|
|
21
|
+
}
|
|
22
|
+
let nextHeadersModulePromise = null;
|
|
23
|
+
function loadNextHeaders() {
|
|
24
|
+
if (!nextHeadersModulePromise) {
|
|
25
|
+
nextHeadersModulePromise = (async () => {
|
|
26
|
+
const mod = (await import('next/headers'));
|
|
27
|
+
return mod;
|
|
28
|
+
})();
|
|
29
|
+
}
|
|
30
|
+
return nextHeadersModulePromise;
|
|
31
|
+
}
|
|
32
|
+
async function readTokensFromHeaders(config) {
|
|
33
|
+
const { cookies, headers } = await loadNextHeaders();
|
|
34
|
+
const accessCookie = config.accessTokenCookie || DEFAULT_ACCESS_COOKIE;
|
|
35
|
+
const refreshCookie = config.refreshTokenCookie || DEFAULT_REFRESH_COOKIE;
|
|
36
|
+
const jar = await cookies();
|
|
37
|
+
const hdr = await headers();
|
|
38
|
+
const cookieAccess = jar.get(accessCookie)?.value;
|
|
39
|
+
const cookieRefresh = jar.get(refreshCookie)?.value;
|
|
40
|
+
const authHeader = hdr.get('authorization');
|
|
41
|
+
const headerAccess = authHeader && authHeader.toLowerCase().startsWith('bearer ')
|
|
42
|
+
? authHeader.slice(7).trim()
|
|
43
|
+
: undefined;
|
|
44
|
+
return {
|
|
45
|
+
accessToken: headerAccess || cookieAccess || undefined,
|
|
46
|
+
refreshToken: cookieRefresh || undefined,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Identify the user / workspace for the current App Router request and
|
|
51
|
+
* return the Qelos context. Safe to call multiple times within the same
|
|
52
|
+
* request — each call performs its own SDK round-trip, so wrap it with
|
|
53
|
+
* React's `cache()` if you want a single resolution per render.
|
|
54
|
+
*
|
|
55
|
+
* Calling without arguments uses the env-derived config (see
|
|
56
|
+
* {@link loadQelosConfigFromEnv}); pass `{ config }` explicitly when you
|
|
57
|
+
* need full control or want to override resolution behavior.
|
|
58
|
+
*/
|
|
59
|
+
export async function getQelosContext(options) {
|
|
60
|
+
const resolved = options ?? { config: getDefaultQelosConfig() };
|
|
61
|
+
const { config, resolveWorkspace } = resolved;
|
|
62
|
+
const tokens = await readTokensFromHeaders(config);
|
|
63
|
+
const sdk = createRequestSdk({
|
|
64
|
+
config,
|
|
65
|
+
tokens,
|
|
66
|
+
refreshTarget: null,
|
|
67
|
+
onTokenRefresh: resolved.onTokenRefresh,
|
|
68
|
+
});
|
|
69
|
+
const ctx = {
|
|
70
|
+
user: null,
|
|
71
|
+
workspace: null,
|
|
72
|
+
workspaces: [],
|
|
73
|
+
sdk,
|
|
74
|
+
tokens,
|
|
75
|
+
};
|
|
76
|
+
const hasAuthMaterial = Boolean(config.apiToken || tokens.accessToken || tokens.refreshToken);
|
|
77
|
+
if (!hasAuthMaterial) {
|
|
78
|
+
return ctx;
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
ctx.user = await sdk.authentication.getLoggedInUser();
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return ctx;
|
|
85
|
+
}
|
|
86
|
+
if (!ctx.user)
|
|
87
|
+
return ctx;
|
|
88
|
+
try {
|
|
89
|
+
ctx.workspaces = await sdk.workspaces.getList();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
ctx.workspaces = [];
|
|
93
|
+
}
|
|
94
|
+
if (ctx.workspaces.length) {
|
|
95
|
+
if (resolveWorkspace) {
|
|
96
|
+
ctx.workspace =
|
|
97
|
+
(await resolveWorkspace({
|
|
98
|
+
user: ctx.user,
|
|
99
|
+
workspaces: ctx.workspaces,
|
|
100
|
+
})) || null;
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
ctx.workspace = ctx.workspaces[0] || null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return ctx;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Convenience wrapper: resolve the Qelos context, store it in
|
|
110
|
+
* AsyncLocalStorage, and run `fn` inside that scope. Useful as the top of an
|
|
111
|
+
* App Router route handler when you want downstream code (utility modules,
|
|
112
|
+
* etc.) to read the context via `getStoredQelosContext()`.
|
|
113
|
+
*/
|
|
114
|
+
export async function withQelosContext(options, fn) {
|
|
115
|
+
const ctx = await getQelosContext(options);
|
|
116
|
+
return await storage.run(ctx, () => Promise.resolve(fn(ctx)));
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Throw a 401-like error if the current stored context has no user.
|
|
120
|
+
* Returns the context for chaining.
|
|
121
|
+
*/
|
|
122
|
+
export function requireQelosUser() {
|
|
123
|
+
const ctx = getStoredQelosContext();
|
|
124
|
+
if (!ctx || !ctx.user) {
|
|
125
|
+
const err = new Error('UNAUTHORIZED');
|
|
126
|
+
err.status = 401;
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
return ctx;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { QelosNextConfig } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Build a {@link QelosNextConfig} from `process.env`. Used by the
|
|
4
|
+
* convention-over-configuration entry points (`qelosMiddleware`, the
|
|
5
|
+
* no-arg `getQelosContext()`) so consumers can re-export the integrator
|
|
6
|
+
* without writing a factory call.
|
|
7
|
+
*
|
|
8
|
+
* Recognized variables:
|
|
9
|
+
*
|
|
10
|
+
* - `QELOS_APP_URL` (required) — Qelos backend base URL.
|
|
11
|
+
* - `QELOS_API_TOKEN` — service-to-service token (skips refresh logic).
|
|
12
|
+
* - `QELOS_ACCESS_TOKEN_COOKIE` — defaults to `q_access_token`.
|
|
13
|
+
* - `QELOS_REFRESH_TOKEN_COOKIE` — defaults to `q_refresh_token`.
|
|
14
|
+
* - `QELOS_REQUIRE_AUTH` — `"true"` to reject anonymous requests.
|
|
15
|
+
* - `QELOS_SKIP_PATHS` — comma-separated path prefixes to bypass.
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadQelosConfigFromEnv(env?: NodeJS.ProcessEnv): QelosNextConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Return the env-derived config, memoized after the first call. The cache is
|
|
20
|
+
* scoped to the current Node process — Next.js dev-mode reloads create a new
|
|
21
|
+
* module instance, so changes to env vars are picked up on restart.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getDefaultQelosConfig(): QelosNextConfig;
|
|
24
|
+
/**
|
|
25
|
+
* Reset the memoized env-derived config. Exported for tests; not part of the
|
|
26
|
+
* stable surface.
|
|
27
|
+
*/
|
|
28
|
+
export declare function __resetDefaultQelosConfig(): void;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a {@link QelosNextConfig} from `process.env`. Used by the
|
|
3
|
+
* convention-over-configuration entry points (`qelosMiddleware`, the
|
|
4
|
+
* no-arg `getQelosContext()`) so consumers can re-export the integrator
|
|
5
|
+
* without writing a factory call.
|
|
6
|
+
*
|
|
7
|
+
* Recognized variables:
|
|
8
|
+
*
|
|
9
|
+
* - `QELOS_APP_URL` (required) — Qelos backend base URL.
|
|
10
|
+
* - `QELOS_API_TOKEN` — service-to-service token (skips refresh logic).
|
|
11
|
+
* - `QELOS_ACCESS_TOKEN_COOKIE` — defaults to `q_access_token`.
|
|
12
|
+
* - `QELOS_REFRESH_TOKEN_COOKIE` — defaults to `q_refresh_token`.
|
|
13
|
+
* - `QELOS_REQUIRE_AUTH` — `"true"` to reject anonymous requests.
|
|
14
|
+
* - `QELOS_SKIP_PATHS` — comma-separated path prefixes to bypass.
|
|
15
|
+
*/
|
|
16
|
+
export function loadQelosConfigFromEnv(env = process.env) {
|
|
17
|
+
const appUrl = env.QELOS_APP_URL;
|
|
18
|
+
if (!appUrl) {
|
|
19
|
+
throw new Error('@qelos/integrator-next: QELOS_APP_URL is required when using the default ' +
|
|
20
|
+
'qelosMiddleware / getQelosContext() exports. Set it in your environment ' +
|
|
21
|
+
'or call createQelosMiddleware({ config: ... }) explicitly.');
|
|
22
|
+
}
|
|
23
|
+
const config = { appUrl };
|
|
24
|
+
if (env.QELOS_API_TOKEN)
|
|
25
|
+
config.apiToken = env.QELOS_API_TOKEN;
|
|
26
|
+
if (env.QELOS_ACCESS_TOKEN_COOKIE)
|
|
27
|
+
config.accessTokenCookie = env.QELOS_ACCESS_TOKEN_COOKIE;
|
|
28
|
+
if (env.QELOS_REFRESH_TOKEN_COOKIE)
|
|
29
|
+
config.refreshTokenCookie = env.QELOS_REFRESH_TOKEN_COOKIE;
|
|
30
|
+
if (env.QELOS_REQUIRE_AUTH === 'true' || env.QELOS_REQUIRE_AUTH === '1') {
|
|
31
|
+
config.requireAuth = true;
|
|
32
|
+
}
|
|
33
|
+
if (env.QELOS_SKIP_PATHS) {
|
|
34
|
+
config.skipPaths = env.QELOS_SKIP_PATHS.split(',')
|
|
35
|
+
.map((p) => p.trim())
|
|
36
|
+
.filter(Boolean);
|
|
37
|
+
}
|
|
38
|
+
return config;
|
|
39
|
+
}
|
|
40
|
+
let cachedConfig = null;
|
|
41
|
+
/**
|
|
42
|
+
* Return the env-derived config, memoized after the first call. The cache is
|
|
43
|
+
* scoped to the current Node process — Next.js dev-mode reloads create a new
|
|
44
|
+
* module instance, so changes to env vars are picked up on restart.
|
|
45
|
+
*/
|
|
46
|
+
export function getDefaultQelosConfig() {
|
|
47
|
+
if (!cachedConfig) {
|
|
48
|
+
cachedConfig = loadQelosConfigFromEnv();
|
|
49
|
+
}
|
|
50
|
+
return cachedConfig;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Reset the memoized env-derived config. Exported for tests; not part of the
|
|
54
|
+
* stable surface.
|
|
55
|
+
*/
|
|
56
|
+
export function __resetDefaultQelosConfig() {
|
|
57
|
+
cachedConfig = null;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=env-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-config.js","sourceRoot":"","sources":["../src/env-config.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACzE,MAAM,MAAM,GAAG,GAAG,CAAC,aAAa,CAAC;IACjC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,2EAA2E;YACzE,0EAA0E;YAC1E,4DAA4D,CAC/D,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAoB,EAAE,MAAM,EAAE,CAAC;IAC3C,IAAI,GAAG,CAAC,eAAe;QAAE,MAAM,CAAC,QAAQ,GAAG,GAAG,CAAC,eAAe,CAAC;IAC/D,IAAI,GAAG,CAAC,yBAAyB;QAAE,MAAM,CAAC,iBAAiB,GAAG,GAAG,CAAC,yBAAyB,CAAC;IAC5F,IAAI,GAAG,CAAC,0BAA0B;QAAE,MAAM,CAAC,kBAAkB,GAAG,GAAG,CAAC,0BAA0B,CAAC;IAC/F,IAAI,GAAG,CAAC,kBAAkB,KAAK,MAAM,IAAI,GAAG,CAAC,kBAAkB,KAAK,GAAG,EAAE,CAAC;QACxE,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC;IAC5B,CAAC;IACD,IAAI,GAAG,CAAC,gBAAgB,EAAE,CAAC;QACzB,MAAM,CAAC,SAAS,GAAG,GAAG,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,CAAC;aAC/C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aACpB,MAAM,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,IAAI,YAAY,GAA2B,IAAI,CAAC;AAEhD;;;;GAIG;AACH,MAAM,UAAU,qBAAqB;IACnC,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,YAAY,GAAG,sBAAsB,EAAE,CAAC;IAC1C,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB;IACvC,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { IUser } from '@qelos/sdk/dist/authentication';
|
|
2
|
+
import type { IWorkspace } from '@qelos/sdk/workspaces';
|
|
3
|
+
/**
|
|
4
|
+
* Replace forwarded identity headers on the outbound request: strip any
|
|
5
|
+
* client-supplied values first, then attach ids resolved by the integrator.
|
|
6
|
+
*/
|
|
7
|
+
export declare function applyQelosForwardHeaders(forwardedHeaders: Headers, user: IUser | null, workspace: IWorkspace | null): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { QELOS_USER_HEADER, QELOS_WORKSPACE_HEADER } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Replace forwarded identity headers on the outbound request: strip any
|
|
4
|
+
* client-supplied values first, then attach ids resolved by the integrator.
|
|
5
|
+
*/
|
|
6
|
+
export function applyQelosForwardHeaders(forwardedHeaders, user, workspace) {
|
|
7
|
+
forwardedHeaders.delete(QELOS_USER_HEADER);
|
|
8
|
+
forwardedHeaders.delete(QELOS_WORKSPACE_HEADER);
|
|
9
|
+
if (user) {
|
|
10
|
+
forwardedHeaders.set(QELOS_USER_HEADER, String(user._id ?? ''));
|
|
11
|
+
}
|
|
12
|
+
if (workspace) {
|
|
13
|
+
forwardedHeaders.set(QELOS_WORKSPACE_HEADER, String(workspace._id ?? ''));
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=forward-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"forward-headers.js","sourceRoot":"","sources":["../src/forward-headers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEpE;;;GAGG;AACH,MAAM,UAAU,wBAAwB,CACtC,gBAAyB,EACzB,IAAkB,EAClB,SAA4B;IAE5B,gBAAgB,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAC3C,gBAAgB,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;IAChD,IAAI,IAAI,EAAE,CAAC;QACT,gBAAgB,CAAC,GAAG,CAClB,iBAAiB,EACjB,MAAM,CAAE,IAA0B,CAAC,GAAG,IAAI,EAAE,CAAC,CAC9C,CAAC;IACJ,CAAC;IACD,IAAI,SAAS,EAAE,CAAC;QACd,gBAAgB,CAAC,GAAG,CAClB,sBAAsB,EACtB,MAAM,CAAE,SAA+B,CAAC,GAAG,IAAI,EAAE,CAAC,CACnD,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createQelosMiddleware, qelosMiddleware, type CreateMiddlewareOptions, type MiddlewareRefreshTarget, type PendingCookie, type QelosMiddleware, } from './middleware';
|
|
2
|
+
export { loadQelosConfigFromEnv, getDefaultQelosConfig, } from './env-config';
|
|
3
|
+
export { createRequestSdk, type CreateSdkParams, } from './sdk-factory';
|
|
4
|
+
export { getQelosContext, withQelosContext, runWithQelosContext, getStoredQelosContext, requireQelosUser, type GetQelosContextOptions, } from './context';
|
|
5
|
+
export { withQelosApi, withQelosSSR, requireQelosApiUser, type PagesIntegratorOptions, } from './pages';
|
|
6
|
+
export { withQelosRoute, type AppRouteHandler, type QelosAppRouteHandler, } from './route';
|
|
7
|
+
export { QELOS_USER_HEADER, QELOS_WORKSPACE_HEADER, type QelosNextConfig, type QelosRequestContext, type QelosTokenPair, type ResolvedTokens, type TokenRefreshContext, type TokenRefreshHook, } from './types';
|
|
8
|
+
export { completeSocialAuthCallback, applySocialAuthCookiesToServerResponse, getSocialAuthSetCookieParts, parseSocialCallbackRefreshToken, type SocialAuthCallbackPayload, type SocialCallbackInput, } from './social-auth';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { createQelosMiddleware, qelosMiddleware, } from './middleware';
|
|
2
|
+
export { loadQelosConfigFromEnv, getDefaultQelosConfig, } from './env-config';
|
|
3
|
+
export { createRequestSdk, } from './sdk-factory';
|
|
4
|
+
export { getQelosContext, withQelosContext, runWithQelosContext, getStoredQelosContext, requireQelosUser, } from './context';
|
|
5
|
+
export { withQelosApi, withQelosSSR, requireQelosApiUser, } from './pages';
|
|
6
|
+
export { withQelosRoute, } from './route';
|
|
7
|
+
export { QELOS_USER_HEADER, QELOS_WORKSPACE_HEADER, } from './types';
|
|
8
|
+
export { completeSocialAuthCallback, applySocialAuthCookiesToServerResponse, getSocialAuthSetCookieParts, parseSocialCallbackRefreshToken, } from './social-auth';
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,eAAe,GAKhB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,gBAAgB,GAEjB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,gBAAgB,GAEjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,mBAAmB,GAEpB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,cAAc,GAGf,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,iBAAiB,EACjB,sBAAsB,GAOvB,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,0BAA0B,EAC1B,sCAAsC,EACtC,2BAA2B,EAC3B,+BAA+B,GAGhC,MAAM,eAAe,CAAC"}
|