@pantheon-systems/p1-next-sdk 0.8.0 → 0.10.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/README.md +87 -0
- package/dist/P1NextRouterProvider.d.ts +1 -1
- package/dist/P1NextRouterProvider.d.ts.map +1 -1
- package/dist/auth-handler.d.ts.map +1 -1
- package/dist/auth-handler.js +7 -2
- package/dist/auth-handler.js.map +1 -1
- package/dist/auth-utils.d.ts +2 -0
- package/dist/auth-utils.d.ts.map +1 -0
- package/dist/auth-utils.js +7 -0
- package/dist/auth-utils.js.map +1 -0
- package/dist/css-query-fetchers.d.ts +8 -0
- package/dist/css-query-fetchers.d.ts.map +1 -0
- package/dist/css-query-fetchers.js +48 -0
- package/dist/css-query-fetchers.js.map +1 -0
- package/dist/handler.d.ts.map +1 -1
- package/dist/handler.js +1 -7
- package/dist/handler.js.map +1 -1
- package/dist/middleware.d.ts +8 -0
- package/dist/middleware.d.ts.map +1 -0
- package/dist/middleware.js +46 -0
- package/dist/middleware.js.map +1 -0
- package/dist/pages-handler.d.ts +1 -1
- package/dist/routes/broker.d.ts.map +1 -1
- package/dist/routes/broker.js +79 -9
- package/dist/routes/broker.js.map +1 -1
- package/dist/routes/datasource-context.d.ts.map +1 -1
- package/dist/routes/datasource-context.js +15 -3
- package/dist/routes/datasource-context.js.map +1 -1
- package/dist/routes/editor-context.d.ts.map +1 -1
- package/dist/routes/editor-context.js +39 -2
- package/dist/routes/editor-context.js.map +1 -1
- package/dist/routes/resolve-preview.js +1 -1
- package/dist/routes/resolve-preview.js.map +1 -1
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -1
- package/package.json +9 -6
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# @pantheon-systems/p1-next-sdk
|
|
2
|
+
|
|
3
|
+
Next.js SDK for the P1 editor. Mounts the editor, its API routes, auth, and published-page
|
|
4
|
+
rendering into a Next.js App Router application with a handful of factories.
|
|
5
|
+
|
|
6
|
+
> Part of Pantheon's **P1** platform. It is published publicly so P1 applications can install
|
|
7
|
+
> it, but it talks to Pantheon-hosted services and is not a general-purpose Next.js library.
|
|
8
|
+
> Pre-1.0: minor versions may carry breaking changes.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @pantheon-systems/p1-next-sdk
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Peer dependencies:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install @puckeditor/core next react react-dom
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The fastest way to get a working application is to scaffold one:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm create @pantheon-systems/p1-starter-kit my-app
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Usage
|
|
29
|
+
|
|
30
|
+
Mount the API routes in `app/p1/api/[...p1]/route.ts`:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { createP1Handler } from "@pantheon-systems/p1-next-sdk/server";
|
|
34
|
+
import config from "../../../../puck.config";
|
|
35
|
+
|
|
36
|
+
const handler = createP1Handler({
|
|
37
|
+
config,
|
|
38
|
+
p1BaseUrl: process.env.NEXT_PUBLIC_CSS_BASE_URL,
|
|
39
|
+
p1ApiKey: process.env.CSS_API_KEY,
|
|
40
|
+
p1SiteId: process.env.NEXT_PUBLIC_CSS_SITE_ID,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const { GET, POST } = handler;
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
And the editor and dashboard pages:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { createP1Pages } from "@pantheon-systems/p1-next-sdk/server";
|
|
50
|
+
import config from "../../../../puck.config";
|
|
51
|
+
|
|
52
|
+
export const pages = createP1Pages({
|
|
53
|
+
config,
|
|
54
|
+
p1BaseUrl: process.env.NEXT_PUBLIC_CSS_BASE_URL,
|
|
55
|
+
p1ApiKey: process.env.CSS_API_KEY,
|
|
56
|
+
p1SiteId: process.env.NEXT_PUBLIC_CSS_SITE_ID,
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Client components render inside `P1NextRouterProvider`, which bridges P1 navigation to the
|
|
61
|
+
Next.js router.
|
|
62
|
+
|
|
63
|
+
## Entry points
|
|
64
|
+
|
|
65
|
+
| Import | Contents |
|
|
66
|
+
| --- | --- |
|
|
67
|
+
| `@pantheon-systems/p1-next-sdk` | `P1NextRouterProvider` and client-side helpers |
|
|
68
|
+
| `.../server` | `createP1Handler`, `createP1AuthHandler`, `createP1Pages`, `createP1Middleware`, `createCssQueryFetchers` |
|
|
69
|
+
|
|
70
|
+
Transpilation is required, since the P1 packages ship untranspiled ESM:
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
// next.config.mjs
|
|
74
|
+
transpilePackages: [
|
|
75
|
+
"@pantheon-systems/css-client",
|
|
76
|
+
"@pantheon-systems/puck-css",
|
|
77
|
+
"@pantheon-systems/p1-next-sdk",
|
|
78
|
+
],
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## CLI
|
|
82
|
+
|
|
83
|
+
The package ships a `p1-migrate` binary for applying P1 migrations:
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
npx p1-migrate
|
|
87
|
+
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"P1NextRouterProvider.d.ts","sourceRoot":"","sources":["../src/P1NextRouterProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGnE,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE
|
|
1
|
+
{"version":3,"file":"P1NextRouterProvider.d.ts","sourceRoot":"","sources":["../src/P1NextRouterProvider.tsx"],"names":[],"mappings":"AAGA,OAAO,EAA8B,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGnE,wBAAgB,oBAAoB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,+BA4CzE"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../src/auth-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-handler.d.ts","sourceRoot":"","sources":["../src/auth-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,mBAAmB;oBAEhD,OAAO,cACJ;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAA;KAAE;EAoBzD"}
|
package/dist/auth-handler.js
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
+
import { PRODUCTION_BASE_URL } from "@pantheon-systems/puck-css/server";
|
|
2
3
|
import { postBrokerLogin, postBrokerRedeem } from "./routes/broker";
|
|
3
4
|
export function createP1AuthHandler(opts) {
|
|
4
5
|
async function POST(request, { params }) {
|
|
5
6
|
const { action = [] } = await params;
|
|
6
7
|
const route = action[0];
|
|
8
|
+
// Same fallback as createNextConfig/createNextContentClient (PCC-3282):
|
|
9
|
+
// an unset p1BaseUrl (no CSS_BASE_URL / NEXT_PUBLIC_CSS_BASE_URL) should
|
|
10
|
+
// resolve to the production backend rather than failing broker login.
|
|
11
|
+
const p1BaseUrl = opts.p1BaseUrl ?? PRODUCTION_BASE_URL;
|
|
7
12
|
if (route === "login") {
|
|
8
|
-
return postBrokerLogin(request, opts.p1ApiKey,
|
|
13
|
+
return postBrokerLogin(request, opts.p1ApiKey, p1BaseUrl, opts.p1SiteUrl, opts.redirectUrl, opts.prompt);
|
|
9
14
|
}
|
|
10
15
|
if (route === "redeem") {
|
|
11
|
-
return postBrokerRedeem(request, opts.p1ApiKey,
|
|
16
|
+
return postBrokerRedeem(request, opts.p1ApiKey, p1BaseUrl);
|
|
12
17
|
}
|
|
13
18
|
return NextResponse.json({ error: "not_found" }, { status: 404 });
|
|
14
19
|
}
|
package/dist/auth-handler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-handler.js","sourceRoot":"","sources":["../src/auth-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAUpE,MAAM,UAAU,mBAAmB,CAAC,IAAyB;IAC3D,KAAK,UAAU,IAAI,CACjB,OAAgB,EAChB,EAAE,MAAM,EAA8C;QAEtD,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"auth-handler.js","sourceRoot":"","sources":["../src/auth-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAUpE,MAAM,UAAU,mBAAmB,CAAC,IAAyB;IAC3D,KAAK,UAAU,IAAI,CACjB,OAAgB,EAChB,EAAE,MAAM,EAA8C;QAEtD,MAAM,EAAE,MAAM,GAAG,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC;QACrC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,wEAAwE;QACxE,yEAAyE;QACzE,sEAAsE;QACtE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,mBAAmB,CAAC;QAExD,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3G,CAAC;QACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7D,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-utils.d.ts","sourceRoot":"","sources":["../src/auth-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAIvE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth-utils.js","sourceRoot":"","sources":["../src/auth-utils.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACpD,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RemoteDatasourceFetcher, P1StoreClient } from "@pantheon-systems/puck-css/server";
|
|
2
|
+
export interface CreateCssQueryFetchersOptions {
|
|
3
|
+
client?: P1StoreClient | null;
|
|
4
|
+
branchId?: string | null;
|
|
5
|
+
filterIds?: Set<string>;
|
|
6
|
+
}
|
|
7
|
+
export declare function createCssQueryFetchers(opts?: CreateCssQueryFetchersOptions): Promise<RemoteDatasourceFetcher[]>;
|
|
8
|
+
//# sourceMappingURL=css-query-fetchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-query-fetchers.d.ts","sourceRoot":"","sources":["../src/css-query-fetchers.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,uBAAuB,EACvB,aAAa,EACd,MAAM,mCAAmC,CAAC;AAE3C,MAAM,WAAW,6BAA6B;IAC5C,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACzB;AAsBD,wBAAsB,sBAAsB,CAC1C,IAAI,CAAC,EAAE,6BAA6B,GACnC,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAoCpC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getSharedP1Client, getSharedSiteId, getSharedBranchId, CSS_QUERY_ID_PREFIX, } from "@pantheon-systems/puck-css/server";
|
|
2
|
+
const inflightQueries = new Map();
|
|
3
|
+
function listQueriesDeduped(endpoint, siteId, branchId) {
|
|
4
|
+
const key = `${siteId}:${branchId}`;
|
|
5
|
+
const existing = inflightQueries.get(key);
|
|
6
|
+
if (existing)
|
|
7
|
+
return existing;
|
|
8
|
+
const promise = endpoint.list(siteId, branchId).finally(() => {
|
|
9
|
+
inflightQueries.delete(key);
|
|
10
|
+
});
|
|
11
|
+
inflightQueries.set(key, promise);
|
|
12
|
+
return promise;
|
|
13
|
+
}
|
|
14
|
+
export async function createCssQueryFetchers(opts) {
|
|
15
|
+
const client = opts?.client ?? getSharedP1Client();
|
|
16
|
+
const siteId = getSharedSiteId();
|
|
17
|
+
const branchId = opts?.branchId || getSharedBranchId();
|
|
18
|
+
if (!client?.queries || !siteId || !branchId) {
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const queries = client.queries;
|
|
22
|
+
let allQueries;
|
|
23
|
+
try {
|
|
24
|
+
allQueries = await listQueriesDeduped(queries, siteId, branchId);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
const filterIds = opts?.filterIds;
|
|
30
|
+
const filtered = filterIds
|
|
31
|
+
? allQueries.filter((q) => filterIds.has(`${CSS_QUERY_ID_PREFIX}${q.name}`))
|
|
32
|
+
: allQueries;
|
|
33
|
+
return filtered.map((query) => ({
|
|
34
|
+
id: `${CSS_QUERY_ID_PREFIX}${query.name}`,
|
|
35
|
+
fetch: async () => {
|
|
36
|
+
try {
|
|
37
|
+
const results = await queries.getResults(siteId, branchId, query.name, {
|
|
38
|
+
includeMetadata: true,
|
|
39
|
+
});
|
|
40
|
+
return results;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=css-query-fetchers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"css-query-fetchers.js","sourceRoot":"","sources":["../src/css-query-fetchers.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAe3C,MAAM,eAAe,GAAG,IAAI,GAAG,EAA8B,CAAC;AAE9D,SAAS,kBAAkB,CACzB,QAAyB,EACzB,MAAc,EACd,QAAgB;IAEhB,MAAM,GAAG,GAAG,GAAG,MAAM,IAAI,QAAQ,EAAE,CAAC;IACpC,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1C,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;QAC3D,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IACH,eAAe,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,IAAoC;IAEpC,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI,iBAAiB,EAAE,CAAC;IACnD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,IAAI,iBAAiB,EAAE,CAAC;IAEvD,IAAI,CAAC,MAAM,EAAE,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;QAC7C,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAE/B,IAAI,UAAU,CAAC;IACf,IAAI,CAAC;QACH,UAAU,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,EAAE,SAAS,CAAC;IAClC,MAAM,QAAQ,GAAG,SAAS;QACxB,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,mBAAmB,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC5E,CAAC,CAAC,UAAU,CAAC;IAEf,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC9B,EAAE,EAAE,GAAG,mBAAmB,GAAG,KAAK,CAAC,IAAI,EAAE;QACzC,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE;oBACrE,eAAe,EAAE,IAAI;iBACtB,CAAC,CAAC;gBACH,OAAO,OAA6C,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;KACF,CAAC,CAAC,CAAC;AACN,CAAC"}
|
package/dist/handler.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC7G,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"handler.d.ts","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAC7G,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAwBzF,MAAM,MAAM,eAAe,GAAG,YAAY,GAAG;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAC5C,yBAAyB,CAAC,EAAE,0BAA0B,EAAE,CAAC;CAC1D,CAAC;AAQF,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe;mBAIxC,OAAO,cACJ;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAA;KAAE;oBAuBzC,OAAO,cACJ;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAA;KAAE;sBAezC,OAAO,cACJ;QAAE,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAA;KAAE;EAYrD"}
|
package/dist/handler.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
import { NextResponse } from "next/server";
|
|
13
13
|
import { ensureInitialized } from "@pantheon-systems/puck-css/server";
|
|
14
14
|
import { runWithAuthToken } from "@pantheon-systems/puck-css/server";
|
|
15
|
+
import { extractBearerToken } from "./auth-utils";
|
|
15
16
|
import { getPageData, getRemoteDatasources, getEditorContext, getDatasourceContext, getRoutes, postPublish, postResolvePreview, postPreviewMeta, postRemoteDatasources, deleteRemoteDatasources, } from "./handler-actions";
|
|
16
17
|
/** Extract the sub-path segments from the catch-all `p1` param under `/p1/api/`. */
|
|
17
18
|
function parseP1Segments(p1) {
|
|
@@ -20,13 +21,6 @@ function parseP1Segments(p1) {
|
|
|
20
21
|
const [first, ...rest] = p1;
|
|
21
22
|
return { action: first, rest };
|
|
22
23
|
}
|
|
23
|
-
function extractBearerToken(request) {
|
|
24
|
-
const header = request.headers.get("authorization");
|
|
25
|
-
if (!header)
|
|
26
|
-
return undefined;
|
|
27
|
-
const match = header.match(/^Bearer\s+(.+)$/i);
|
|
28
|
-
return match?.[1];
|
|
29
|
-
}
|
|
30
24
|
function withAuth(request, fn) {
|
|
31
25
|
const token = extractBearerToken(request);
|
|
32
26
|
if (token)
|
package/dist/handler.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,iBAAiB,EAAqB,MAAM,mCAAmC,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,iBAAiB,EAAqB,MAAM,mCAAmC,CAAC;AACzF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EACL,WAAW,EACX,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,SAAS,EACT,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAE3B,oFAAoF;AACpF,SAAS,eAAe,CAAC,EAAY;IACnC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACrD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACjC,CAAC;AAQD,SAAS,QAAQ,CAAI,OAAgB,EAAE,EAAW;IAChD,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,KAAK;QAAE,OAAO,gBAAgB,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9C,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAqB;IACnD,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE5C,KAAK,UAAU,GAAG,CAChB,OAAgB,EAChB,EAAE,MAAM,EAA0C;QAElD,MAAM,WAAW,CAAC;QAClB,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC;QACjC,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QAEvC,IAAI,MAAM,KAAK,WAAW;YAAE,OAAO,WAAW,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,MAAM,KAAK,aAAa;YAAE,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACnE,IAAI,MAAM,KAAK,gBAAgB;YAC7B,OAAO,gBAAgB,CAAC,OAAO,EAAE;gBAC/B,eAAe,EAAE,IAAI,CAAC,eAAe;gBACrC,yBAAyB,EAAE,IAAI,CAAC,yBAAyB;aAC1D,CAAC,CAAC;QACL,IAAI,MAAM,KAAK,oBAAoB;YACjC,OAAO,oBAAoB,CAAC,OAAO,EAAE;gBACnC,eAAe,EAAE,IAAI,CAAC,eAAe;aACtC,CAAC,CAAC;QACL,IAAI,MAAM,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC;QAEnD,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,UAAU,IAAI,CACjB,OAAgB,EAChB,EAAE,MAAM,EAA0C;QAElD,MAAM,WAAW,CAAC;QAClB,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC;QACjC,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QAEvC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/E,IAAI,MAAM,KAAK,iBAAiB;YAAE,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;QACrE,IAAI,MAAM,KAAK,cAAc;YAAE,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC;QAC/D,IAAI,MAAM,KAAK,aAAa;YAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC;QAE7F,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,UAAU,MAAM,CACnB,OAAgB,EAChB,EAAE,MAAM,EAA0C;QAElD,MAAM,WAAW,CAAC;QAClB,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC;QACjC,MAAM,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC,CAAC;QAEvC,IAAI,MAAM,KAAK,aAAa;YAAE,OAAO,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAC;QAE/F,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
export interface P1MiddlewareConfig {
|
|
3
|
+
cssBaseUrl: string;
|
|
4
|
+
apiToken: string;
|
|
5
|
+
siteId: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function createP1Middleware(config: P1MiddlewareConfig): (request: Request) => Promise<NextResponse<unknown>>;
|
|
8
|
+
//# sourceMappingURL=middleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB,IAOxB,SAAS,OAAO,oCAqCpD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { P1ContentClient } from "@pantheon-systems/css-client/content";
|
|
2
|
+
import { NextResponse } from "next/server";
|
|
3
|
+
const SKIP_PREFIXES = ["/p1/", "/_next/", "/api/"];
|
|
4
|
+
export function createP1Middleware(config) {
|
|
5
|
+
const client = new P1ContentClient({
|
|
6
|
+
baseUrl: config.cssBaseUrl,
|
|
7
|
+
apiToken: config.apiToken,
|
|
8
|
+
siteId: config.siteId,
|
|
9
|
+
});
|
|
10
|
+
return async function p1Middleware(request) {
|
|
11
|
+
const url = new URL(request.url);
|
|
12
|
+
const pathname = url.pathname;
|
|
13
|
+
for (const prefix of SKIP_PREFIXES) {
|
|
14
|
+
if (pathname.startsWith(prefix)) {
|
|
15
|
+
return NextResponse.next();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const redirect = await client.getRedirect(pathname);
|
|
20
|
+
if (redirect !== null) {
|
|
21
|
+
const isAbsolute = redirect.destination.startsWith("http://") || redirect.destination.startsWith("https://") || redirect.destination.startsWith("//");
|
|
22
|
+
const destination = isAbsolute
|
|
23
|
+
? redirect.destination
|
|
24
|
+
: new URL(redirect.destination, url.origin).toString();
|
|
25
|
+
const validStatusCodes = [301, 302, 303, 307, 308];
|
|
26
|
+
const statusCode = validStatusCodes.includes(redirect.statusCode) ? redirect.statusCode : 301;
|
|
27
|
+
const destinationUrl = new URL(destination);
|
|
28
|
+
// Preserve original query parameters
|
|
29
|
+
if (url.search) {
|
|
30
|
+
url.searchParams.forEach((value, key) => {
|
|
31
|
+
if (!destinationUrl.searchParams.has(key)) {
|
|
32
|
+
destinationUrl.searchParams.set(key, value);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return NextResponse.redirect(destinationUrl.toString(), statusCode);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
41
|
+
console.warn('[P1 Middleware] Redirect lookup skipped:', message);
|
|
42
|
+
}
|
|
43
|
+
return NextResponse.next();
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AACvE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAQ3C,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;AAEnD,MAAM,UAAU,kBAAkB,CAAC,MAA0B;IAC3D,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;QACjC,OAAO,EAAE,MAAM,CAAC,UAAU;QAC1B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAC;IAEH,OAAO,KAAK,UAAU,YAAY,CAAC,OAAgB;QACjD,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC;QAE9B,KAAK,MAAM,MAAM,IAAI,aAAa,EAAE,CAAC;YACnC,IAAI,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAChC,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;YACpD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;gBACtJ,MAAM,WAAW,GAAG,UAAU;oBAC5B,CAAC,CAAC,QAAQ,CAAC,WAAW;oBACtB,CAAC,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;gBACzD,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBACnD,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC;gBAC9F,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;gBAC5C,qCAAqC;gBACrC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;oBACf,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;wBACtC,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;4BAC1C,cAAc,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;wBAC9C,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO,YAAY,CAAC,QAAQ,CAAC,cAAc,CAAC,QAAQ,EAAE,EAAE,UAAU,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,IAAI,CAAC,0CAA0C,EAAE,OAAO,CAAC,CAAC;QACpE,CAAC;QAED,OAAO,YAAY,CAAC,IAAI,EAAE,CAAC;IAC7B,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/pages-handler.d.ts
CHANGED
|
@@ -55,7 +55,7 @@ export declare function createP1Pages(opts: P1PagesConfig): {
|
|
|
55
55
|
Page: () => null;
|
|
56
56
|
Layout: ({ children }: {
|
|
57
57
|
children: React.ReactNode;
|
|
58
|
-
}) => Promise<import("react
|
|
58
|
+
}) => Promise<import("react").JSX.Element>;
|
|
59
59
|
generateMetadata: ({ params, }: {
|
|
60
60
|
params: Promise<{
|
|
61
61
|
p1?: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../src/routes/broker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"broker.d.ts","sourceRoot":"","sources":["../../src/routes/broker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAsB3C,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,OAAO,CAAC,EAAE,MAAM,EAChB,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,MAAM,8BA+EhB;AA6BD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,MAAM,GAAG,SAAS,8BA0C5B"}
|
package/dist/routes/broker.js
CHANGED
|
@@ -1,4 +1,23 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
+
// Route Handler `request.url` reflects the Node server's own bind address
|
|
3
|
+
// (e.g. localhost:3000), not the Host the browser actually requested, once a
|
|
4
|
+
// reverse proxy is involved -- but its scheme is unaffected by that, so only
|
|
5
|
+
// the host needs replacing.
|
|
6
|
+
//
|
|
7
|
+
// Deliberately reads `host`, NOT `x-forwarded-host`: on Pantheon, `Host` is
|
|
8
|
+
// what the edge routes on, so a request only reaches this container with a
|
|
9
|
+
// Host that resolves to this site -- an arbitrary Host 404s upstream.
|
|
10
|
+
// `X-Forwarded-Host` is not similarly validated; it passes through from the
|
|
11
|
+
// client unchanged, so trusting it here would let anyone redirect a login
|
|
12
|
+
// to an attacker-controlled origin (confirmed empirically, not theoretical).
|
|
13
|
+
function deriveOriginFromRequest(request) {
|
|
14
|
+
const host = request.headers.get("host");
|
|
15
|
+
const requestUrl = new URL(request.url);
|
|
16
|
+
if (host === null) {
|
|
17
|
+
return requestUrl.origin;
|
|
18
|
+
}
|
|
19
|
+
return `${requestUrl.protocol}//${host}`;
|
|
20
|
+
}
|
|
2
21
|
export async function postBrokerLogin(request, apiKey, baseUrl, siteUrl, redirectUrl, prompt) {
|
|
3
22
|
if (!apiKey || !baseUrl) {
|
|
4
23
|
return NextResponse.json({ error: "Server configuration error" }, { status: 500 });
|
|
@@ -13,18 +32,37 @@ export async function postBrokerLogin(request, apiKey, baseUrl, siteUrl, redirec
|
|
|
13
32
|
const requestUrl = new URL(request.url);
|
|
14
33
|
const basePath = requestUrl.pathname.replace(/\/auth\/.*$/, '') || '/';
|
|
15
34
|
const siteUrlValue = siteUrl ?? process.env.P1_SITE_URL;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
35
|
+
const derivedOrigin = deriveOriginFromRequest(request);
|
|
36
|
+
if (!siteUrlValue && derivedOrigin === requestUrl.origin && process.env.NODE_ENV === 'production') {
|
|
37
|
+
console.warn("[P1AuthHandler] p1SiteUrl is not set and no Host header was present. " +
|
|
38
|
+
"Redirect URLs may be incorrect behind a reverse proxy. " +
|
|
39
|
+
"Set the P1_SITE_URL environment variable or pass p1SiteUrl in your P1AuthHandlerConfig.");
|
|
40
|
+
}
|
|
41
|
+
let actualOrigin = derivedOrigin;
|
|
42
|
+
if (siteUrlValue) {
|
|
43
|
+
try {
|
|
44
|
+
actualOrigin = new URL(siteUrlValue).origin;
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
console.warn(`[P1AuthHandler] P1_SITE_URL/p1SiteUrl ("${siteUrlValue}") is not a valid URL; ` +
|
|
48
|
+
"falling back to the request's own origin.");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
24
51
|
const effectiveRedirectUrl = redirectUrl ?? actualOrigin + basePath;
|
|
52
|
+
// PCC-3531: the fallback above yields localhost on a deployed site because this
|
|
53
|
+
// server cannot see its own public origin. The browser can, so pass its origin
|
|
54
|
+
// upstream as a proposal for CCR to validate. Skipped when a target is
|
|
55
|
+
// configured, keeping those requests byte-identical to before.
|
|
56
|
+
const hasExplicitTarget = redirectUrl !== undefined || siteUrlValue !== undefined;
|
|
57
|
+
const proposedOrigin = hasExplicitTarget
|
|
58
|
+
? undefined
|
|
59
|
+
: await readProposedOrigin(request);
|
|
25
60
|
headers["Content-Type"] = "application/json";
|
|
26
61
|
fetchInit.body = JSON.stringify({
|
|
27
62
|
redirectUrl: effectiveRedirectUrl,
|
|
63
|
+
...(proposedOrigin !== undefined
|
|
64
|
+
? { proposedRedirectUrl: proposedOrigin + basePath }
|
|
65
|
+
: {}),
|
|
28
66
|
...(prompt !== undefined ? { prompt } : {}),
|
|
29
67
|
});
|
|
30
68
|
const response = await fetch(`${baseUrl}/broker/login`, fetchInit);
|
|
@@ -32,7 +70,39 @@ export async function postBrokerLogin(request, apiKey, baseUrl, siteUrl, redirec
|
|
|
32
70
|
if (!response.ok) {
|
|
33
71
|
return NextResponse.json(body, { status: response.status });
|
|
34
72
|
}
|
|
35
|
-
|
|
73
|
+
// Log then strip: this route is public, so echoing the warning would let anyone
|
|
74
|
+
// probe whether an origin is registered for a site. The browser never reads it.
|
|
75
|
+
const { warning, ...clientBody } = body;
|
|
76
|
+
if (typeof warning === "string" && warning !== "") {
|
|
77
|
+
console.warn(`[P1AuthHandler] ${warning}`);
|
|
78
|
+
}
|
|
79
|
+
return NextResponse.json(clientBody);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Still untrusted after this — CCR validates against the site's registered
|
|
83
|
+
* origins. Malformed values are dropped rather than forwarded upstream.
|
|
84
|
+
*/
|
|
85
|
+
async function readProposedOrigin(request) {
|
|
86
|
+
let parsed;
|
|
87
|
+
try {
|
|
88
|
+
parsed = await request.clone().json();
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
const candidate = parsed.origin;
|
|
94
|
+
if (typeof candidate !== "string" || candidate === "") {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
// Re-deriving the origin and requiring an exact match rejects anything
|
|
99
|
+
// carrying a path or credentials.
|
|
100
|
+
const url = new URL(candidate);
|
|
101
|
+
return url.origin === candidate ? candidate : undefined;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
36
106
|
}
|
|
37
107
|
export async function postBrokerRedeem(request, apiKey, baseUrl) {
|
|
38
108
|
if (!apiKey || !baseUrl) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../src/routes/broker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAgB,EAChB,MAA0B,EAC1B,OAA2B,EAC3B,OAAgB,EAChB,WAAoB,EACpB,MAAe;IAEf,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACxB,OAAO,YAAY,CAAC,IAAI,CACtB,EAAE,KAAK,EAAE,4BAA4B,EAAE,EACvC,EAAE,MAAM,EAAE,GAAG,EAAE,CAChB,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAA2B;QACtC,eAAe,EAAE,UAAU,MAAM,EAAE;KACpC,CAAC;IACF,MAAM,SAAS,GAAgB;QAC7B,MAAM,EAAE,MAAM;QACd,OAAO;KACR,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;IAEvE,MAAM,YAAY,GAAG,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../src/routes/broker.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datasource-context.d.ts","sourceRoot":"","sources":["../../src/routes/datasource-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"datasource-context.d.ts","sourceRoot":"","sources":["../../src/routes/datasource-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,OAAO,KAAK,EACV,uBAAuB,EACxB,MAAM,mCAAmC,CAAC;AAI3C,MAAM,WAAW,wBAAwB;IACvC,eAAe,CAAC,EAAE,uBAAuB,EAAE,CAAC;CAC7C;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,wBAAwB;;;;;IA6ClC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import { normalizePath, listRouteTemplateKeysFromDatabase, getPageEditorPreviewParams, loadRemoteDatasourceContext, } from "@pantheon-systems/puck-css/server";
|
|
2
|
+
import { normalizePath, listRouteTemplateKeysFromDatabase, getPageEditorPreviewParams, loadRemoteDatasourceContext, createAuthenticatedClient, } from "@pantheon-systems/puck-css/server";
|
|
3
|
+
import { extractBearerToken } from "../auth-utils";
|
|
4
|
+
import { createCssQueryFetchers } from "../css-query-fetchers";
|
|
3
5
|
export async function getDatasourceContext(request, options) {
|
|
4
6
|
const url = new URL(request.url);
|
|
5
7
|
const rawPath = url.searchParams.get("path") ?? "/";
|
|
@@ -15,15 +17,25 @@ export async function getDatasourceContext(request, options) {
|
|
|
15
17
|
listRouteTemplateKeysFromDatabase(),
|
|
16
18
|
Promise.resolve(getPageEditorPreviewParams(path)),
|
|
17
19
|
]);
|
|
20
|
+
const branchId = url.searchParams.get("branchId");
|
|
18
21
|
const referencedDatasourceIds = new Set([id]);
|
|
22
|
+
const token = extractBearerToken(request);
|
|
23
|
+
const client = token ? createAuthenticatedClient(token) : null;
|
|
24
|
+
const cssQueryFetchers = await createCssQueryFetchers({
|
|
25
|
+
client,
|
|
26
|
+
branchId,
|
|
27
|
+
filterIds: referencedDatasourceIds,
|
|
28
|
+
});
|
|
29
|
+
const allFetchers = [...(options.builtinFetchers ?? []), ...cssQueryFetchers];
|
|
19
30
|
const context = await loadRemoteDatasourceContext({
|
|
20
31
|
searchParams: Object.fromEntries(url.searchParams.entries()),
|
|
21
32
|
pagePath: path,
|
|
22
33
|
routeTemplateKeys,
|
|
23
34
|
savedPreviewParams,
|
|
24
|
-
builtinFetchers:
|
|
35
|
+
builtinFetchers: allFetchers,
|
|
25
36
|
referencedDatasourceIds,
|
|
26
37
|
});
|
|
27
|
-
|
|
38
|
+
const data = context[id] ?? {};
|
|
39
|
+
return NextResponse.json({ id, data });
|
|
28
40
|
}
|
|
29
41
|
//# sourceMappingURL=datasource-context.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"datasource-context.js","sourceRoot":"","sources":["../../src/routes/datasource-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,aAAa,EACb,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,
|
|
1
|
+
{"version":3,"file":"datasource-context.js","sourceRoot":"","sources":["../../src/routes/datasource-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,aAAa,EACb,iCAAiC,EACjC,0BAA0B,EAC1B,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,mCAAmC,CAAC;AAI3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAM/D,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAgB,EAChB,OAAiC;IAEjC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IACpD,MAAM,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEtC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC5D,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;QAClB,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChE,iCAAiC,EAAE;QACnC,OAAO,CAAC,OAAO,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAC;KAClD,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAClD,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAE9C,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE/D,MAAM,gBAAgB,GAAG,MAAM,sBAAsB,CAAC;QACpD,MAAM;QACN,QAAQ;QACR,SAAS,EAAE,uBAAuB;KACnC,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,EAAE,CAAC,EAAE,GAAG,gBAAgB,CAAC,CAAC;IAE9E,MAAM,OAAO,GAAG,MAAM,2BAA2B,CAAC;QAChD,YAAY,EAAE,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;QAC5D,QAAQ,EAAE,IAAI;QACd,iBAAiB;QACjB,kBAAkB;QAClB,eAAe,EAAE,WAAW;QAC5B,uBAAuB;KACxB,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IAC/B,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-context.d.ts","sourceRoot":"","sources":["../../src/routes/editor-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"editor-context.d.ts","sourceRoot":"","sources":["../../src/routes/editor-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAe3C,OAAO,KAAK,EACV,uBAAuB,EACvB,0BAA0B,EAC3B,MAAM,mCAAmC,CAAC;AAG3C,MAAM,WAAW,oBAAoB;IACnC,eAAe,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAC5C,yBAAyB,CAAC,EAAE,0BAA0B,EAAE,CAAC;CAC1D;AAsBD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,oBAAoB;;;;;;;;IAkB9B"}
|
|
@@ -1,19 +1,56 @@
|
|
|
1
1
|
import { NextResponse } from "next/server";
|
|
2
|
-
import { normalizePath, listRoutes, listRouteTemplateKeysFromDatabase, getPageEditorPreviewParams, buildRemoteDatasourceRegistry, listRemoteDatasourcesForPage, } from "@pantheon-systems/puck-css/server";
|
|
2
|
+
import { normalizePath, listRoutes, listRouteTemplateKeysFromDatabase, getPageEditorPreviewParams, buildRemoteDatasourceRegistry, listRemoteDatasourcesForPage, cssQueriesToDatasourceDefinitions, getSharedSiteId, getSharedBranchId, createAuthenticatedClient, runWithAuthToken, } from "@pantheon-systems/puck-css/server";
|
|
3
|
+
import { extractBearerToken } from "../auth-utils";
|
|
4
|
+
async function fetchCssQueryDefinitions(request, branchOverride) {
|
|
5
|
+
const siteId = getSharedSiteId();
|
|
6
|
+
const branchId = branchOverride || getSharedBranchId();
|
|
7
|
+
const token = extractBearerToken(request);
|
|
8
|
+
if (!siteId || !branchId)
|
|
9
|
+
return [];
|
|
10
|
+
if (!token)
|
|
11
|
+
return [];
|
|
12
|
+
const client = createAuthenticatedClient(token);
|
|
13
|
+
if (!client?.queries)
|
|
14
|
+
return [];
|
|
15
|
+
try {
|
|
16
|
+
const queries = await client.queries.list(siteId, branchId);
|
|
17
|
+
return cssQueriesToDatasourceDefinitions(queries);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
21
|
+
console.warn("[P1] Editor context: CSS query lookup failed:", message);
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
3
25
|
export async function getEditorContext(request, options) {
|
|
4
26
|
const url = new URL(request.url);
|
|
5
27
|
const rawPath = url.searchParams.get("path") ?? "/";
|
|
28
|
+
const branchId = url.searchParams.get("branchId");
|
|
6
29
|
const path = rawPath === "/" ? "/" : normalizePath(rawPath);
|
|
7
30
|
if (path === null) {
|
|
8
31
|
return NextResponse.json({ error: "invalid_path" }, { status: 400 });
|
|
9
32
|
}
|
|
33
|
+
// Unlike getRoutes, a missing token degrades rather than 401s: the editor
|
|
34
|
+
// falls back to an unauthenticated fetch and treats any error response as
|
|
35
|
+
// fatal, so rejecting here would break auth-optional deployments.
|
|
36
|
+
const token = extractBearerToken(request);
|
|
37
|
+
const run = (fn) => token ? runWithAuthToken(token, fn) : fn();
|
|
38
|
+
return run(() => buildEditorContext(request, options, path, branchId));
|
|
39
|
+
}
|
|
40
|
+
async function buildEditorContext(request, options, path, branchId) {
|
|
10
41
|
const [routes, routeTemplateKeys, savedPreviewParams, userDefs] = await Promise.all([
|
|
11
42
|
listRoutes(),
|
|
12
43
|
listRouteTemplateKeysFromDatabase(),
|
|
13
44
|
Promise.resolve(getPageEditorPreviewParams(path)),
|
|
14
45
|
Promise.resolve(listRemoteDatasourcesForPage(path)),
|
|
15
46
|
]);
|
|
16
|
-
|
|
47
|
+
// Must run after listRoutes() — branch ID is lazily resolved during
|
|
48
|
+
// that call, and getSharedBranchId() returns null until it completes.
|
|
49
|
+
const cssQueryDefinitions = await fetchCssQueryDefinitions(request, branchId);
|
|
50
|
+
const remoteDatasourceRegistry = [
|
|
51
|
+
...buildRemoteDatasourceRegistry(options.builtinDatasourceRegistry ?? [], userDefs.global, userDefs.page),
|
|
52
|
+
...cssQueryDefinitions,
|
|
53
|
+
];
|
|
17
54
|
return NextResponse.json({
|
|
18
55
|
remoteDatasourceContext: {},
|
|
19
56
|
routes,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-context.js","sourceRoot":"","sources":["../../src/routes/editor-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EACL,aAAa,EACb,UAAU,EACV,iCAAiC,EACjC,0BAA0B,EAC1B,6BAA6B,EAC7B,4BAA4B,
|
|
1
|
+
{"version":3,"file":"editor-context.js","sourceRoot":"","sources":["../../src/routes/editor-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ export async function postResolvePreview(request) {
|
|
|
10
10
|
return NextResponse.json({ error: "invalid_json" }, { status: 400 });
|
|
11
11
|
}
|
|
12
12
|
const data = body.data ?? {};
|
|
13
|
-
const datasourceContext = body.datasourceContext ?? {};
|
|
13
|
+
const datasourceContext = body.remoteDatasourceContext ?? body.datasourceContext ?? {};
|
|
14
14
|
const resolved = await resolveDataTemplates(data, datasourceContext);
|
|
15
15
|
return NextResponse.json({ data: resolved });
|
|
16
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve-preview.js","sourceRoot":"","sources":["../../src/routes/resolve-preview.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,OAAO,EAAE,kBAAkB,IAAI,IAAI,EAAE,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAgB;IACvD,IAAI,
|
|
1
|
+
{"version":3,"file":"resolve-preview.js","sourceRoot":"","sources":["../../src/routes/resolve-preview.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAEzE,OAAO,EAAE,kBAAkB,IAAI,IAAI,EAAE,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAgB;IACvD,IAAI,IAA8H,CAAC;IACnI,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAAgB,CAAC;IAC/C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;IAC7B,MAAM,iBAAiB,GAAG,IAAI,CAAC,uBAAuB,IAAI,IAAI,CAAC,iBAAiB,IAAI,EAAE,CAAC;IAEvF,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,IAAqB,EAAE,iBAAiB,CAAC,CAAC;IACtF,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC/C,CAAC"}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { createP1Handler, type P1HandlerConfig } from "./handler";
|
|
2
2
|
export { createP1AuthHandler, type P1AuthHandlerConfig } from "./auth-handler";
|
|
3
3
|
export { createP1Pages, type P1PagesConfig } from "./pages-handler";
|
|
4
|
+
export { createCssQueryFetchers, type CreateCssQueryFetchersOptions } from "./css-query-fetchers";
|
|
5
|
+
export { createP1Middleware, type P1MiddlewareConfig } from "./middleware";
|
|
4
6
|
//# sourceMappingURL=server.d.ts.map
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,KAAK,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/server.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { createP1Handler } from "./handler";
|
|
2
2
|
export { createP1AuthHandler } from "./auth-handler";
|
|
3
3
|
export { createP1Pages } from "./pages-handler";
|
|
4
|
+
export { createCssQueryFetchers } from "./css-query-fetchers";
|
|
5
|
+
export { createP1Middleware } from "./middleware";
|
|
4
6
|
//# sourceMappingURL=server.js.map
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwB,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAA4B,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAsB,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAwB,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAA4B,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAsB,MAAM,iBAAiB,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAsC,MAAM,sBAAsB,CAAC;AAClG,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pantheon-systems/p1-next-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Next.js SDK for P1 editor integration",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/pantheon-systems/
|
|
12
|
+
"url": "git+https://github.com/pantheon-systems/p1-platform.git",
|
|
13
13
|
"directory": "packages/p1-next-sdk"
|
|
14
14
|
},
|
|
15
15
|
"type": "module",
|
|
@@ -34,8 +34,8 @@
|
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"server-only": "^0.0.1",
|
|
37
|
-
"@pantheon-systems/css-client": "0.
|
|
38
|
-
"@pantheon-systems/puck-css": "0.
|
|
37
|
+
"@pantheon-systems/css-client": "0.10.0",
|
|
38
|
+
"@pantheon-systems/puck-css": "0.10.0"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@puckeditor/core": ">=0.21.0",
|
|
@@ -53,10 +53,13 @@
|
|
|
53
53
|
"vitest": "^4.1.5",
|
|
54
54
|
"@pantheon-systems/eslint-config": "0.1.0"
|
|
55
55
|
},
|
|
56
|
+
"homepage": "https://github.com/pantheon-systems/p1-platform/tree/main/packages/p1-next-sdk",
|
|
56
57
|
"scripts": {
|
|
57
|
-
"build": "tsc",
|
|
58
|
+
"build": "pnpm run clean && tsc",
|
|
58
59
|
"clean": "rm -rf dist *.tsbuildinfo",
|
|
60
|
+
"lint": "eslint src",
|
|
61
|
+
"lint:fix": "eslint src --fix",
|
|
59
62
|
"test": "vitest run",
|
|
60
|
-
"
|
|
63
|
+
"typecheck": "tsc --noEmit"
|
|
61
64
|
}
|
|
62
65
|
}
|