@pantheon-systems/p1-next-sdk 0.7.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.
Files changed (56) hide show
  1. package/README.md +87 -0
  2. package/bin/lib/cli.js +171 -0
  3. package/bin/lib/detect.js +179 -0
  4. package/bin/lib/fs-ops.js +32 -0
  5. package/bin/lib/git.js +60 -0
  6. package/bin/lib/messages.js +65 -0
  7. package/bin/lib/transform.js +155 -0
  8. package/bin/p1-migrate.js +5 -0
  9. package/dist/P1NextRouterProvider.d.ts +1 -1
  10. package/dist/P1NextRouterProvider.d.ts.map +1 -1
  11. package/dist/auth-handler.d.ts.map +1 -1
  12. package/dist/auth-handler.js +7 -2
  13. package/dist/auth-handler.js.map +1 -1
  14. package/dist/auth-utils.d.ts +2 -0
  15. package/dist/auth-utils.d.ts.map +1 -0
  16. package/dist/auth-utils.js +7 -0
  17. package/dist/auth-utils.js.map +1 -0
  18. package/dist/css-query-fetchers.d.ts +8 -0
  19. package/dist/css-query-fetchers.d.ts.map +1 -0
  20. package/dist/css-query-fetchers.js +48 -0
  21. package/dist/css-query-fetchers.js.map +1 -0
  22. package/dist/editor-paths.d.ts +10 -0
  23. package/dist/editor-paths.d.ts.map +1 -0
  24. package/dist/editor-paths.js +38 -0
  25. package/dist/editor-paths.js.map +1 -0
  26. package/dist/handler.d.ts.map +1 -1
  27. package/dist/handler.js +1 -7
  28. package/dist/handler.js.map +1 -1
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +1 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/middleware.d.ts +8 -0
  34. package/dist/middleware.d.ts.map +1 -0
  35. package/dist/middleware.js +46 -0
  36. package/dist/middleware.js.map +1 -0
  37. package/dist/pages-handler.d.ts +44 -14
  38. package/dist/pages-handler.d.ts.map +1 -1
  39. package/dist/pages-handler.js +31 -23
  40. package/dist/pages-handler.js.map +1 -1
  41. package/dist/routes/broker.d.ts.map +1 -1
  42. package/dist/routes/broker.js +79 -9
  43. package/dist/routes/broker.js.map +1 -1
  44. package/dist/routes/datasource-context.d.ts.map +1 -1
  45. package/dist/routes/datasource-context.js +15 -3
  46. package/dist/routes/datasource-context.js.map +1 -1
  47. package/dist/routes/editor-context.d.ts.map +1 -1
  48. package/dist/routes/editor-context.js +39 -2
  49. package/dist/routes/editor-context.js.map +1 -1
  50. package/dist/routes/resolve-preview.js +1 -1
  51. package/dist/routes/resolve-preview.js.map +1 -1
  52. package/dist/server.d.ts +2 -0
  53. package/dist/server.d.ts.map +1 -1
  54. package/dist/server.js +2 -0
  55. package/dist/server.js.map +1 -1
  56. package/package.json +15 -10
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Pure string transforms for the p1-migrate codemod.
3
+ *
4
+ * No filesystem, no side effects — every function takes source in and returns
5
+ * source out (or throws BailError when the input isn't the shape we recognize).
6
+ * The moves and depth rule are mechanical; the two localized edits validate
7
+ * their target and bail rather than guess, so a diverged app is never left
8
+ * half-migrated.
9
+ */
10
+
11
+ export class BailError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "BailError";
15
+ }
16
+ }
17
+
18
+ /**
19
+ * Moving a file one directory deeper (into the `(editor)` group) adds a real
20
+ * on-disk segment the URL never sees, so every relative import that already
21
+ * points at a parent gains one more `../`. Sibling (`./`) and bare package
22
+ * specifiers are untouched.
23
+ */
24
+ export function deepenRelativeImports(source) {
25
+ return source.replace(
26
+ /(\bfrom\s+|\bimport\s+|\bimport\(\s*|\brequire\(\s*)(['"])(\.\.\/)/g,
27
+ (_match, prefix, quote, dots) => `${prefix}${quote}../${dots}`,
28
+ );
29
+ }
30
+
31
+ /**
32
+ * Add `name` to the named-import list for `moduleSpecifier`. Idempotent when
33
+ * the name is already imported; bails when the module isn't imported at all.
34
+ */
35
+ export function addNamedImport(source, moduleSpecifier, name, position = "append") {
36
+ const escaped = moduleSpecifier.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
37
+ const re = new RegExp(`(import\\s*\\{)([^}]*)(\\}\\s*from\\s*['"])${escaped}(['"])`);
38
+ const match = source.match(re);
39
+ if (!match) {
40
+ throw new BailError(
41
+ `Expected an import from "${moduleSpecifier}" to add "${name}" to; migrate this file by hand.`,
42
+ );
43
+ }
44
+ const names = match[2].split(",").map((s) => s.trim()).filter(Boolean);
45
+ if (names.includes(name)) return source;
46
+ const next = position === "prepend" ? [name, ...names] : [...names, name];
47
+ return source.replace(re, `$1 ${next.join(", ")} $3${moduleSpecifier}$4`);
48
+ }
49
+
50
+ const LEGACY_SIGNATURE =
51
+ /export function EditorClientWrapper\(\{\s*path\s*\}\s*:\s*\{\s*path\s*:\s*string\s*\}\s*\)\s*\{/;
52
+ const MIGRATED_SIGNATURE = /export function EditorClientWrapper\(\s*\)/;
53
+
54
+ /**
55
+ * Drop the `{ path }` prop from EditorClientWrapper and derive the path from
56
+ * the URL instead — matching how the persistent layout renders it with no props.
57
+ */
58
+ export function rewriteWrapperSignature(source) {
59
+ if (LEGACY_SIGNATURE.test(source)) {
60
+ return source.replace(
61
+ LEGACY_SIGNATURE,
62
+ "export function EditorClientWrapper() {\n" +
63
+ " // Rendered from the persistent (editor) layout, so this survives page\n" +
64
+ " // switches; the edited page is derived from the URL instead of route params.\n" +
65
+ " const pathname = usePathname();\n" +
66
+ " const path = editorPagePathFromUrlPath(pathname);",
67
+ );
68
+ }
69
+ if (MIGRATED_SIGNATURE.test(source)) return source;
70
+ throw new BailError(
71
+ "EditorClientWrapper has an unrecognized signature; migrate this file by hand.",
72
+ );
73
+ }
74
+
75
+ /** Full editor-client transform: deepen imports, add the two named imports, rewrite the signature. */
76
+ export function rewriteEditorClient(source) {
77
+ let out = deepenRelativeImports(source);
78
+ out = addNamedImport(out, "next/navigation", "usePathname", "prepend");
79
+ out = addNamedImport(out, "@pantheon-systems/p1-next-sdk", "editorPagePathFromUrlPath", "append");
80
+ out = rewriteWrapperSignature(out);
81
+ return out;
82
+ }
83
+
84
+ /** The thin page.tsx that re-exports from the shared p1-pages module. */
85
+ export function buildNewPageFile() {
86
+ return (
87
+ 'import { pages } from "./p1-pages";\n' +
88
+ "\n" +
89
+ "export default pages.Page;\n" +
90
+ "export const generateMetadata = pages.generateMetadata;\n" +
91
+ 'export const dynamic = "force-dynamic";\n'
92
+ );
93
+ }
94
+
95
+ /** The `(editor)/layout.tsx` that renders the persistent editor. */
96
+ export function buildLayoutFile() {
97
+ return (
98
+ 'import "@puckeditor/core/puck.css";\n' +
99
+ 'import { pages } from "./[[...p1]]/p1-pages";\n' +
100
+ "\n" +
101
+ "// The editor renders from this layout, NOT the page. The (editor) group is a\n" +
102
+ "// static segment, so this layout survives navigation between /p1/<pageA> and\n" +
103
+ "// /p1/<pageB> — a layout inside [[...p1]] would remount on every switch, since\n" +
104
+ "// Next keys segment cache nodes by param value.\n" +
105
+ "//\n" +
106
+ "// Scoping the layout to the (editor) group (instead of app/p1/layout.tsx) is\n" +
107
+ "// what keeps the editor off sibling routes: /p1/merge and future pages like\n" +
108
+ "// /p1/settings live outside the group and never render the editor. Add such\n" +
109
+ "// pages as siblings of (editor), not inside it.\n" +
110
+ "export default pages.Layout;\n"
111
+ );
112
+ }
113
+
114
+ /** The re-exports that belong to the route file, not the shared factory module. */
115
+ const PAGE_LEVEL_EXPORTS = [
116
+ /^export default pages\.Page;\n/m,
117
+ /^export const generateMetadata = pages\.generateMetadata;\n/m,
118
+ /^export const dynamic = ["']force-dynamic["'];\n/m,
119
+ ];
120
+
121
+ /**
122
+ * Split the old catch-all page.tsx into the shared factory module (p1-pages.tsx)
123
+ * and the thin re-export page.tsx. Bails when the file isn't the recognized
124
+ * createP1Pages editor page.
125
+ */
126
+ export function splitPageFile(source) {
127
+ if (!source.includes("createP1Pages(") || !source.includes("pages.Page")) {
128
+ throw new BailError(
129
+ "page.tsx is not the recognized createP1Pages editor page; migrate it by hand.",
130
+ );
131
+ }
132
+ let p1Pages = deepenRelativeImports(source);
133
+ // The puck.css side-effect moves to layout.tsx.
134
+ p1Pages = p1Pages.replace(/^import ["']@puckeditor\/core\/puck\.css["'];\n/m, "");
135
+
136
+ // Export the factory result so both layout.tsx and page.tsx can consume it.
137
+ p1Pages = p1Pages.replace(/\bconst pages = createP1Pages\(/, "export const pages = createP1Pages(");
138
+ if (!/\bexport const pages = createP1Pages\(/.test(p1Pages)) {
139
+ throw new BailError(
140
+ "Could not find `const pages = createP1Pages(` to export from page.tsx; migrate this file by hand.",
141
+ );
142
+ }
143
+
144
+ // The page-level re-exports move to the thin page.tsx. Stripped individually
145
+ // so a reordered file does not leave dead exports behind in p1-pages.tsx.
146
+ for (const re of PAGE_LEVEL_EXPORTS) p1Pages = p1Pages.replace(re, "");
147
+ p1Pages = p1Pages.replace(/\n+$/, "\n");
148
+ if (/^export default pages\.Page;$/m.test(p1Pages)) {
149
+ throw new BailError(
150
+ "Could not remove the page-level exports from page.tsx; migrate this file by hand.",
151
+ );
152
+ }
153
+
154
+ return { p1Pages, page: buildNewPageFile() };
155
+ }
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { runCLI } from "./lib/cli.js";
4
+
5
+ runCLI();
@@ -1,5 +1,5 @@
1
1
  import { type ReactNode } from "react";
2
2
  export declare function P1NextRouterProvider({ children }: {
3
3
  children: ReactNode;
4
- }): import("react/jsx-runtime").JSX.Element;
4
+ }): import("react").JSX.Element;
5
5
  //# sourceMappingURL=P1NextRouterProvider.d.ts.map
@@ -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,2CA4CzE"}
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;AAG3C,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;EAgBzD"}
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"}
@@ -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, opts.p1BaseUrl, opts.p1SiteUrl, opts.redirectUrl, opts.prompt);
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, opts.p1BaseUrl);
16
+ return postBrokerRedeem(request, opts.p1ApiKey, p1BaseUrl);
12
17
  }
13
18
  return NextResponse.json({ error: "not_found" }, { status: 404 });
14
19
  }
@@ -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;QAExB,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,OAAO,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAChH,CAAC;QACD,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;YACvB,OAAO,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QAClE,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"}
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,2 @@
1
+ export declare function extractBearerToken(request: Request): string | undefined;
2
+ //# sourceMappingURL=auth-utils.d.ts.map
@@ -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,7 @@
1
+ export function extractBearerToken(request) {
2
+ const header = request.headers.get("authorization");
3
+ if (!header)
4
+ return undefined;
5
+ return header.match(/^Bearer\s+(.+)$/i)?.[1];
6
+ }
7
+ //# sourceMappingURL=auth-utils.js.map
@@ -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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Editor URL → page path mapping, shared by the server page handler and the
3
+ * client-side editor. Pure and client-safe: the editor renders from a
4
+ * persistent layout (so it survives route-param changes) and derives its page
5
+ * path from usePathname() with these helpers, which must agree with the
6
+ * server's parsing in pages-handler.
7
+ */
8
+ export declare function parseEditorSegments(segments: string[]): string;
9
+ export declare function editorPagePathFromUrlPath(pathname: string, basePath?: string): string;
10
+ //# sourceMappingURL=editor-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-paths.d.ts","sourceRoot":"","sources":["../src/editor-paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,CAc9D;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,QAAQ,SAAQ,GACf,MAAM,CAgBR"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Editor URL → page path mapping, shared by the server page handler and the
3
+ * client-side editor. Pure and client-safe: the editor renders from a
4
+ * persistent layout (so it survives route-param changes) and derives its page
5
+ * path from usePathname() with these helpers, which must agree with the
6
+ * server's parsing in pages-handler.
7
+ */
8
+ import { pagePathFromCatchAllSegments } from "@pantheon-systems/puck-css/routes";
9
+ export function parseEditorSegments(segments) {
10
+ if (segments.length === 0)
11
+ return "/";
12
+ const command = segments[0];
13
+ // /p1/api/... is handled by the route handler, not the page
14
+ if (command === "api")
15
+ return "/";
16
+ // /p1/edit/... -> editor for the path
17
+ if (command === "edit") {
18
+ return pagePathFromCatchAllSegments(segments.slice(1));
19
+ }
20
+ // /p1/... (anything else) -> editor for that path
21
+ return pagePathFromCatchAllSegments(segments);
22
+ }
23
+ export function editorPagePathFromUrlPath(pathname, basePath = "/p1") {
24
+ if (pathname !== basePath && !pathname.startsWith(`${basePath}/`)) {
25
+ // Falling back silently would make the editor load and edit the root
26
+ // document while the URL points somewhere else entirely.
27
+ console.warn(`[p1-next-sdk] "${pathname}" is outside the editor base path "${basePath}"; ` +
28
+ `falling back to the root page. If the editor is not mounted at ${basePath}, ` +
29
+ `pass the correct basePath to editorPagePathFromUrlPath.`);
30
+ return "/";
31
+ }
32
+ const segments = pathname
33
+ .slice(basePath.length)
34
+ .split("/")
35
+ .filter(Boolean);
36
+ return parseEditorSegments(segments);
37
+ }
38
+ //# sourceMappingURL=editor-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"editor-paths.js","sourceRoot":"","sources":["../src/editor-paths.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,4BAA4B,EAAE,MAAM,mCAAmC,CAAC;AAEjF,MAAM,UAAU,mBAAmB,CAAC,QAAkB;IACpD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,GAAG,CAAC;IACtC,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAE5B,4DAA4D;IAC5D,IAAI,OAAO,KAAK,KAAK;QAAE,OAAO,GAAG,CAAC;IAElC,sCAAsC;IACtC,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;QACvB,OAAO,4BAA4B,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,kDAAkD;IAClD,OAAO,4BAA4B,CAAC,QAAQ,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,QAAgB,EAChB,QAAQ,GAAG,KAAK;IAEhB,IAAI,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC;QAClE,qEAAqE;QACrE,yDAAyD;QACzD,OAAO,CAAC,IAAI,CACV,kBAAkB,QAAQ,sCAAsC,QAAQ,KAAK;YAC3E,kEAAkE,QAAQ,IAAI;YAC9E,yDAAyD,CAC5D,CAAC;QACF,OAAO,GAAG,CAAC;IACb,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ;SACtB,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC;SACtB,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,OAAO,CAAC,CAAC;IACnB,OAAO,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AACvC,CAAC"}
@@ -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;AAuBzF,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;AAeF,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"}
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)
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../src/handler.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  export { P1NextRouterProvider } from "./P1NextRouterProvider";
2
+ export { parseEditorSegments, editorPagePathFromUrlPath, } from "./editor-paths";
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
1
  export { P1NextRouterProvider } from "./P1NextRouterProvider";
2
+ export { parseEditorSegments, editorPagePathFromUrlPath, } from "./editor-paths";
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EACL,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,gBAAgB,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"}
@@ -1,31 +1,61 @@
1
1
  /**
2
- * P1 Next SDK page handler — provides page components for `/p1/[...p1]`.
2
+ * P1 Next SDK page handler — provides page components for `/p1/[[...p1]]`.
3
+ *
4
+ * The editor renders from `Layout`, not `Page`: Next.js keys segment cache
5
+ * nodes by their param values, so everything inside `[[...p1]]` — page AND
6
+ * any layout placed there — remounts when the param changes, tearing down
7
+ * the whole editor (providers, auth, Puck and its canvas iframe) on every
8
+ * document switch. `Layout` must therefore be mounted at a static segment,
9
+ * which persists; the editor follows the URL client-side from there (see
10
+ * editor-paths.ts).
11
+ *
12
+ * Mount that layout in an `(editor)` route group rather than directly at
13
+ * `app/p1/layout.tsx`. A layout at `/p1` wraps EVERY route under it, so
14
+ * sibling routes with their own pages (e.g. /p1/merge, /p1/settings) would
15
+ * render the editor on top of themselves. Scoping the layout to the group
16
+ * means only the catch-all page gets the editor; siblings placed outside the
17
+ * group stay editor-free by construction. Route groups add no URL segment, so
18
+ * /p1 and its subpaths are unchanged.
3
19
  *
4
20
  * Usage:
5
- * // app/p1/[...p1]/page.tsx
6
- * import { createP1Pages } from "@pantheon-systems/p1-next-sdk";
7
- * import config from "../../../puck.config";
8
- * const pages = createP1Pages({ config });
21
+ * // app/p1/(editor)/[[...p1]]/p1-pages.tsx (shared module)
22
+ * import { createP1Pages } from "@pantheon-systems/p1-next-sdk/server";
23
+ * export const pages = createP1Pages({ config, EditorClient });
24
+ *
25
+ * // app/p1/(editor)/layout.tsx <- static segment scoped to the group
26
+ * export default pages.Layout;
27
+ *
28
+ * // app/p1/(editor)/[[...p1]]/page.tsx
9
29
  * export default pages.Page;
10
30
  * export const generateMetadata = pages.generateMetadata;
11
31
  * export const dynamic = "force-dynamic";
32
+ *
33
+ * // app/p1/merge/page.tsx <- sibling OUTSIDE the group, no editor
34
+ * // app/p1/settings/page.tsx <- future siblings: same, editor-free
35
+ *
36
+ * The editor must be mounted at `/p1`: the client derives the edited page
37
+ * from the URL via editorPagePathFromUrlPath, whose basePath defaults to
38
+ * "/p1". A different mount point needs that basePath passed through in the
39
+ * EditorClient implementation, or every URL falls back to the root page.
12
40
  */
13
41
  import type { Config } from "@puckeditor/core";
14
42
  import type { Metadata } from "next";
15
43
  import { type P1DataConfig } from "@pantheon-systems/puck-css/server";
16
44
  export type P1PagesConfig = P1DataConfig & {
17
45
  config: Config;
18
- /** React component to render the editor. Receives only the page path; handles its own data loading and auth via P1App. */
19
- EditorClient: React.ComponentType<{
20
- path: string;
21
- }>;
46
+ /**
47
+ * React component to render the editor. Rendered from the persistent
48
+ * layout with no props — it derives the page path from the URL (see
49
+ * editorPagePathFromUrlPath) and handles its own data loading and auth
50
+ * via P1App.
51
+ */
52
+ EditorClient: React.ComponentType;
22
53
  };
23
54
  export declare function createP1Pages(opts: P1PagesConfig): {
24
- Page: ({ params, }: {
25
- params: Promise<{
26
- p1?: string[];
27
- }>;
28
- }) => Promise<import("react/jsx-runtime").JSX.Element>;
55
+ Page: () => null;
56
+ Layout: ({ children }: {
57
+ children: React.ReactNode;
58
+ }) => Promise<import("react").JSX.Element>;
29
59
  generateMetadata: ({ params, }: {
30
60
  params: Promise<{
31
61
  p1?: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"pages-handler.d.ts","sourceRoot":"","sources":["../src/pages-handler.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,mCAAmC,CAAC;AAE3C,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,0HAA0H;IAC1H,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC;QAChC,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;CACJ,CAAC;AAmBF,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa;wBAiB5C;QACD,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;KACpC;oCAbE;QACD,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;KACpC,KAAG,OAAO,CAAC,QAAQ,CAAC;EAoBtB"}
1
+ {"version":3,"file":"pages-handler.d.ts","sourceRoot":"","sources":["../src/pages-handler.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAErC,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,mCAAmC,CAAC;AAI3C,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG;IACzC,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,YAAY,EAAE,KAAK,CAAC,aAAa,CAAC;CACnC,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,aAAa;;2BAyBX;QAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE;oCAX9D;QACD,MAAM,EAAE,OAAO,CAAC;YAAE,EAAE,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC,CAAC;KACpC,KAAG,OAAO,CAAC,QAAQ,CAAC;EAwCtB"}