payload-live-preview 2.0.1 → 2.0.2

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 (76) hide show
  1. package/README.md +36 -31
  2. package/dist/adapters/astro/RichText.astro +1 -1
  3. package/dist/adapters/astro/index.js +1 -1
  4. package/dist/adapters/astro/index.js.map +1 -1
  5. package/dist/adapters/astro/middleware-entry.js +1 -1
  6. package/dist/adapters/astro/middleware-entry.js.map +1 -1
  7. package/dist/adapters/nextjs/index.js +1 -1
  8. package/dist/adapters/nextjs/index.js.map +1 -1
  9. package/dist/adapters/nuxt/index.js +1 -1
  10. package/dist/adapters/nuxt/index.js.map +1 -1
  11. package/dist/adapters/nuxt/module.d.ts +12 -4
  12. package/dist/adapters/nuxt/module.js.map +1 -1
  13. package/dist/adapters/react/index.d.ts +6 -5
  14. package/dist/adapters/react/index.js.map +1 -1
  15. package/dist/adapters/sveltekit/index.js +1 -1
  16. package/dist/adapters/sveltekit/index.js.map +1 -1
  17. package/dist/adapters/vue/index.d.ts +3 -3
  18. package/dist/adapters/vue/index.js.map +1 -1
  19. package/dist/annotate.js +1 -1
  20. package/dist/annotate.js.map +1 -1
  21. package/dist/client.cjs +1 -1
  22. package/dist/client.cjs.map +1 -1
  23. package/dist/client.js +1 -1
  24. package/dist/client.js.map +1 -1
  25. package/dist/codegen-astro.d.ts +4 -1
  26. package/dist/codegen-astro.js.map +1 -1
  27. package/dist/codegen-cli.js +1 -1
  28. package/dist/codegen-cli.js.map +1 -1
  29. package/dist/codegen.cjs +1 -1
  30. package/dist/codegen.cjs.map +1 -1
  31. package/dist/codegen.js +1 -1
  32. package/dist/codegen.js.map +1 -1
  33. package/dist/core.cjs +1 -1
  34. package/dist/core.cjs.map +1 -1
  35. package/dist/core.d.cts +1 -1
  36. package/dist/core.d.ts +1 -1
  37. package/dist/core.js +1 -1
  38. package/dist/core.js.map +1 -1
  39. package/dist/doctor-cli.d.ts +1 -1
  40. package/dist/doctor-cli.js +1 -1
  41. package/dist/doctor-cli.js.map +1 -1
  42. package/dist/doctor.d.ts +2 -2
  43. package/dist/doctor.js +1 -1
  44. package/dist/doctor.js.map +1 -1
  45. package/dist/fragment.cjs.map +1 -1
  46. package/dist/fragment.d.cts +6 -3
  47. package/dist/fragment.d.ts +6 -3
  48. package/dist/fragment.js.map +1 -1
  49. package/dist/index.cjs +1 -1
  50. package/dist/index.cjs.map +1 -1
  51. package/dist/index.d.cts +8 -8
  52. package/dist/index.d.ts +8 -8
  53. package/dist/index.js +1 -1
  54. package/dist/index.js.map +1 -1
  55. package/dist/lean.cjs +1 -1
  56. package/dist/lean.cjs.map +1 -1
  57. package/dist/lean.d.cts +3 -3
  58. package/dist/lean.d.ts +3 -3
  59. package/dist/lean.js +1 -1
  60. package/dist/lean.js.map +1 -1
  61. package/dist/lexical.cjs +1 -1
  62. package/dist/lexical.cjs.map +1 -1
  63. package/dist/lexical.d.cts +11 -1
  64. package/dist/lexical.d.ts +11 -1
  65. package/dist/lexical.js +1 -1
  66. package/dist/lexical.js.map +1 -1
  67. package/dist/plugins.cjs +1 -1
  68. package/dist/plugins.cjs.map +1 -1
  69. package/dist/plugins.js +1 -1
  70. package/dist/plugins.js.map +1 -1
  71. package/dist/{probe-wmvfVEsI.d.ts → probe-DqaItcwX.d.ts} +2 -1
  72. package/dist/structural.cjs +2 -2
  73. package/dist/structural.cjs.map +1 -1
  74. package/dist/structural.js +2 -2
  75. package/dist/structural.js.map +1 -1
  76. package/package.json +2 -3
@@ -1 +1 @@
1
- {"version":3,"file":"doctor-cli.js","names":["tsMorph","project","PACKAGE_NAME","loadTsMorph","createRequire","url","error","Error","cause","parseScript","text","kind","morph","Project","useInMemoryFileSystem","skipLoadingLibFiles","skipFileDependencyResolution","compilerOptions","allowJs","noLib","createSourceFile","overwrite","isPackageSpecifier","specifier","startsWith","packageBindings","script","Node","SyntaxKind","out","declaration","getImportDeclarations","getModuleSpecifierValue","spec","getNamedImports","alias","getAliasNode","localNode","getNameNode","push","imported","getName","local","getText","importedNode","aliased","symbol","getSymbol","getDescendantsOfKind","VariableDeclaration","requiredSpecifier","getInitializer","pattern","isObjectBindingPattern","element","getElements","nameNode","isIdentifier","propertyName","getPropertyNameNode","literalName","initializer","call","isAwaitExpression","getExpression","isCallExpression","callee","getKind","ImportKeyword","argument","getArguments","isStringLiteral","getLiteralText","node","isNoSubstitutionTemplateLiteral","propertyKey","property","isSpreadAssignment","isComputedPropertyName","referencesTo","binding","target","compilerSymbol","checker","getProject","getTypeChecker","Identifier","isInside","parent","getParent","isShorthandPropertyAssignment","getShorthandAssignmentValueSymbol","isExportSpecifier","getLocalTargetSymbol","ancestor","getFirstAncestor","candidate","declaresName","name","except","bindsIdentifier","some","skip","isVariableDeclaration","isBindingElement","isFunctionDeclaration","isClassDeclaration","isParameterDeclaration","isEnumDeclaration","isImportSpecifier","isImportClause","getDefaultImport","isNamespaceImport","replaceNode","start","getStart","end","getEnd","applyTextEdits","edits","ordered","sort","left","right","output","floor","Number","POSITIVE_INFINITY","edit","slice","ID","SERVER_SPECIFIER","METHOD","fetchPreviewDocument","fetchPreviewGlobal","SERVER_OPTIONS","Set","DROPPED_OPTIONS","SHARED_READ_OPTIONS","READ_OPTIONS","conflict","line","reason","codemod","rewriteCall","options","server","read","dropped","keys","getProperties","key","add","has","accepted","unplaceable","filter","includes","typeArguments","getTypeArguments","map","generic","length","join","method","droppedNote","getStartLineNumber","notes","importLine","quote","names","moveFetchPreviewHelpers","id","summary","ledgerEntry","apply","bindings","conflicts","blocking","reference","isObjectLiteralExpression","rewritten","serverDeclaration","foreign","declarations","isImportDeclaration","serverImport","find","isTypeOnly","hasDefinePreview","serverLine","getModuleSpecifier","getQuoteKind","defaultImport","clauses","remaining","clause","typeOnly","kept","trailingNewline","getFullText","rewriteImports","plan","CALLEE","OLD_KEY","NEW_KEY","BY_HAND","renameAdminOriginsOption","properties","isPropertyAssignment","BOOLEAN_REFUSED","renameBindingsAuthorizedOption","value","isFalseLiteral","OLD_NAME","NEW_NAME","renameBinding","getParentOrThrow","renameIsPreviewRequest","notice","existing","isPropertyAccessExpression","memberAccesses","WHOLE_FILE","COMPONENT_EXTENSIONS","FRONTMATTER","SCRIPT_TAG","PACKAGE_REFERENCE","IMPLEMENTATIONS","CODEMODS","lineNumberAt","source","offset","index","lineEdits","before","after","firstLine","oldLines","split","newLines","prefix","suffix","oldMiddle","newMiddle","changed","Math","max","migrateSource","chosen","only","test","importsThisPackage","byCodemod","Map","cursor","block","fileName","extension","extname","toLowerCase","blocks","frontmatter","exec","indexOf","match","matchAll","body","trim","lastIndexOf","scriptBlocks","item","next","lines","get","set","count","SOURCE_EXTENSIONS","DECLARATION_FILE","SKIP_DIRECTORIES","isSourceFile","async","collectFiles","root","found","stat","isDirectory","walk","directory","entry","readdir","withFileTypes","path","relativeTo","file","rel","relative","describe","String","LEVEL_LABEL","warning","info","DIAGNOSTIC_CODES","Object","freeze","NoTrustedOrigin","ReferrerOnlyTrust","PluginIncompatible","ProfileFeatureOmitted","OrphanField","UnattributableUpdate","VisibilityGateDeferred","UnsafeAttributeWrite","TextTargetHasChildren","MissingArrayTemplate","StructuralItemUnkeyed","StructuralDuplicateKey","StructuralUnstableKeys","UnsupportedStrategy","UnknownValueFormat","SanitizerDroppedAttribute","UnrenderedBlockKept","UnfaithfulPatch","ServerFormatReplaced","UnrenderedBlockLost","MessageRejected","TokenRejected","ProtocolShapeUnknown","HandlerThrew","TransformThrew","RendererThrew","StartupFailed","ReadyFailed","HydrationWaitTimedOut","AuditRuntimeMissing","AuditNoFrameAncestors","AuditFrameOptionsBlocks","AuditBindingsExposed","AuditGateThresholdExceeded","AuditUnownedBindings","AuditNoBindings","AuditNotAPage","FragmentRequestFailed","FragmentResponseInvalid","FragmentUnauthorized","FragmentSuperseded","RouteRefreshLoop","FragmentStrategyUnavailable","UnboundChangeRefresh","V2ReadinessGap","RuntimeOnPublicPage","DEFAULT_PORT","http","https","ws","wss","SCHEME_SOURCE","HOST_SOURCE","schemeOf","protocol","portOf","port","schemeMatches","expression","actual","isSelf","admin","page","hostname","adminScheme","pageScheme","sourceMatches","scheme","host","expressionScheme","expressionHost","expressionPort","wanted","replace","endsWith","hostMatches","INLINE_CONFIG_KEYS","V2_RUNTIME_DEFAULTS","disableReferrerDetection","eventSourcePolicy","skipUnchanged","sanitizerPolicy","V1_RUNTIME_DEFAULTS","DEFAULTS_SLOT","ROWS","title","effect","condition","ORIGIN_DETAIL","profile","explicit","unmarked","UNREADABLE","code","level","detail","remedy","UNMARKED","literal","JSON","stringify","remedyFor","origin","row","gap","unknownGeneration","marker","RUNTIME_MARKER","BINDING_ATTRIBUTE","OWNER_ATTRIBUTE","LEVEL_ORDER","NON_MARKUP","visibleMarkup","markup","stripped","haystack","tryUrl","URL","analyzeProbe","probe","context","publicResponse","pub","previewResponse","preview","notAPage","status","location","headers","contentType","describeNonPage","findings","errors","warnings","runtimeInPreview","credentials","adminOrigin","sameOrigin","frameAncestors","csp","directive","trimmed","frameAncestorsOf","admitted","sources","frameAncestorsAdmits","frameOptions","judged","framingFindings","previewMarkup","publicMarkup","runtime","previewBindings","publicBindings","owners","unowned","firstOwner","search","unownedBindingsBeforeFirstOwner","bindingFindings","v2","config","from","CONFIG_MARKER","depth","inString","previous","json","char","parse","Array","isArray","readInlineConfig","generation","fallback","flatMap","slot","analyzeV2Readiness","a","b","finding","DEFAULT_INTENT_PARAMS","splitUrl","hashAt","hash","beforeHash","queryAt","base","parts","decodePart","part","at","decode","decodeURIComponent","lowercaseHeaders","forEach","readBody","response","limit","reader","getReader","decoder","TextDecoder","received","done","byteLength","cancel","stream","previewReferer","href","PARAM_NAME","HEADER_LINE","addHeader","parsed","isAbsoluteUrl","given","usageError","addParam","params","HELP_TEXT","run","argv","fetchImpl","subcommand","rest","process","stdout","write","args","unknown","help","ids","token","parseArgs","stderr","result","io","readFile","content","writeFile","list","results","files","changedCount","conflictCount","runMigrate","message","conflicted","where","runMigrateCommand","showHelp","i","report","timeoutMs","maxBodyBytes","init","fetchFn","globalThis","fetch","redirect","signal","AbortSignal","timeout","createDefaultFetch","previewQueryParams","visitorUrl","Accept","probeHeaders","Referer","sent","own","taken","fromEntries","entries","callerHeaders","previewHeaders","isIntentValue","query","joiner","intent","encodeURIComponent","previewUrl","runDoctor","describeFailure","formatReport","isCliInvocation","pop","then","exit"],"sources":["../src/migrate/ast.ts","../src/migrate/codemods/move-fetch-preview-helpers.ts","../src/migrate/codemods/rename-admin-origins-option.ts","../src/migrate/codemods/rename-bindings-authorized-option.ts","../src/migrate/codemods/rename-is-preview-request.ts","../src/migrate/script-blocks.ts","../src/migrate/index.ts","../src/migrate/runner.ts","../src/migrate/cli.ts","../src/doctor/format.ts","../src/core/diagnostic-codes.ts","../src/doctor/csp.ts","../src/types/inline-config.ts","../src/types/defaults-profile.ts","../src/doctor/readiness.ts","../src/doctor/analyze.ts","../src/doctor/probe.ts","../src/doctor/cli.ts"],"sourcesContent":["/**\n * ts-morph access for the codemods: parsing, the package's bindings in a\n * script and the references those bindings have. ts-morph is loaded on first\n * use so the entry stays importable without the optional peer.\n */\nimport { createRequire } from 'node:module';\nimport type * as TsMorphModule from 'ts-morph';\nimport type {\n Identifier,\n Node,\n ObjectLiteralElementLike,\n Project,\n SourceFile,\n Symbol as TsSymbol,\n} from 'ts-morph';\nimport type { TextEdit } from './types';\n\ntype TsMorph = typeof TsMorphModule;\n\nexport type ScriptKind = 'ts' | 'tsx' | 'js' | 'jsx';\n\nexport const PACKAGE_NAME = 'payload-live-preview';\n\nlet tsMorph: TsMorph | undefined;\nlet project: Project | undefined;\n\nexport function loadTsMorph(): TsMorph {\n if (tsMorph === undefined) {\n try {\n tsMorph = createRequire(import.meta.url)('ts-morph') as TsMorph;\n } catch (error) {\n throw new Error('pll migrate needs ts-morph: npm install --save-dev ts-morph', {\n cause: error,\n });\n }\n }\n return tsMorph;\n}\n\n/** Parse one script into a throwaway in-memory project; the previous script is discarded. */\nexport function parseScript(text: string, kind: ScriptKind): SourceFile {\n const morph = loadTsMorph();\n project ??= new morph.Project({\n useInMemoryFileSystem: true,\n skipLoadingLibFiles: true,\n skipFileDependencyResolution: true,\n compilerOptions: { allowJs: true, noLib: true },\n });\n return project.createSourceFile(`/script.${kind}`, text, { overwrite: true });\n}\n\nexport function isPackageSpecifier(specifier: string): boolean {\n return specifier === PACKAGE_NAME || specifier.startsWith(`${PACKAGE_NAME}/`);\n}\n\n/** A name the script binds from the package, by `import` or by destructuring `require()`/`import()`. */\nexport interface PackageBinding {\n /** The exported name, as the package spells it. */\n readonly imported: string;\n /** The name the script uses; equals `imported` unless aliased. */\n readonly local: string;\n readonly specifier: string;\n readonly kind: 'import' | 'require';\n /** The node spelling the exported name; rewritten when the export is renamed. */\n readonly importedNode: Node;\n readonly aliased: boolean;\n readonly symbol: TsSymbol | undefined;\n /** The import declaration or variable declaration that binds it. */\n readonly declaration: Node;\n}\n\nexport function packageBindings(script: SourceFile): readonly PackageBinding[] {\n const { Node, SyntaxKind } = loadTsMorph();\n const out: PackageBinding[] = [];\n for (const declaration of script.getImportDeclarations()) {\n const specifier = declaration.getModuleSpecifierValue();\n if (!isPackageSpecifier(specifier)) continue;\n for (const spec of declaration.getNamedImports()) {\n const alias = spec.getAliasNode();\n const localNode = alias ?? spec.getNameNode();\n out.push({\n imported: spec.getName(),\n local: localNode.getText(),\n specifier,\n kind: 'import',\n importedNode: spec.getNameNode(),\n aliased: alias !== undefined,\n symbol: localNode.getSymbol(),\n declaration,\n });\n }\n }\n for (const declaration of script.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {\n const specifier = requiredSpecifier(declaration.getInitializer());\n const pattern = declaration.getNameNode();\n if (specifier === undefined || !isPackageSpecifier(specifier)) continue;\n if (!Node.isObjectBindingPattern(pattern)) continue;\n for (const element of pattern.getElements()) {\n const nameNode = element.getNameNode();\n if (!Node.isIdentifier(nameNode)) continue;\n const propertyName = element.getPropertyNameNode();\n out.push({\n imported: propertyName === undefined ? nameNode.getText() : literalName(propertyName),\n local: nameNode.getText(),\n specifier,\n kind: 'require',\n importedNode: propertyName ?? nameNode,\n aliased: propertyName !== undefined,\n symbol: nameNode.getSymbol(),\n declaration,\n });\n }\n }\n return out;\n}\n\nfunction requiredSpecifier(initializer: Node | undefined): string | undefined {\n const { Node, SyntaxKind } = loadTsMorph();\n const call =\n initializer !== undefined && Node.isAwaitExpression(initializer)\n ? initializer.getExpression()\n : initializer;\n if (call === undefined || !Node.isCallExpression(call)) return undefined;\n const callee = call.getExpression();\n const isRequire = Node.isIdentifier(callee) && callee.getText() === 'require';\n if (!isRequire && callee.getKind() !== SyntaxKind.ImportKeyword) return undefined;\n const [argument] = call.getArguments();\n return argument !== undefined && Node.isStringLiteral(argument)\n ? argument.getLiteralText()\n : undefined;\n}\n\nfunction literalName(node: Node): string {\n const { Node } = loadTsMorph();\n if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {\n return node.getLiteralText();\n }\n return node.getText();\n}\n\n/** The key of an object-literal member, or `undefined` when it is computed. */\nexport function propertyKey(property: ObjectLiteralElementLike): string | undefined {\n const { Node } = loadTsMorph();\n if (Node.isSpreadAssignment(property)) return undefined;\n const nameNode = property.getNameNode();\n if (Node.isComputedPropertyName(nameNode)) return undefined;\n return literalName(nameNode);\n}\n\nexport type ReferenceKind = 'reference' | 'shorthand' | 'export';\n\nexport interface BindingReference {\n readonly node: Identifier;\n /** `shorthand` is `{ name }`, `export` is `export { name }`; both keep the old key visible. */\n readonly kind: ReferenceKind;\n}\n\n/** Every use of the binding outside its own declaration, resolved by symbol so shadowing is respected. */\nexport function referencesTo(\n script: SourceFile,\n binding: PackageBinding,\n): readonly BindingReference[] {\n const { Node, SyntaxKind } = loadTsMorph();\n const target = binding.symbol?.compilerSymbol;\n if (target === undefined) return [];\n const checker = script.getProject().getTypeChecker();\n const out: BindingReference[] = [];\n for (const node of script.getDescendantsOfKind(SyntaxKind.Identifier)) {\n if (node.getText() !== binding.local || isInside(node, binding.declaration)) continue;\n const parent = node.getParent();\n if (Node.isShorthandPropertyAssignment(parent)) {\n if (checker.getShorthandAssignmentValueSymbol(parent)?.compilerSymbol === target) {\n out.push({ node, kind: 'shorthand' });\n }\n continue;\n }\n if (Node.isExportSpecifier(parent)) {\n if (\n parent.getNameNode() === node &&\n parent.getLocalTargetSymbol()?.compilerSymbol === target\n ) {\n out.push({ node, kind: 'export' });\n }\n continue;\n }\n if (node.getSymbol()?.compilerSymbol === target) out.push({ node, kind: 'reference' });\n }\n return out;\n}\n\nfunction isInside(node: Node, ancestor: Node): boolean {\n return node.getFirstAncestor((candidate) => candidate === ancestor) !== undefined;\n}\n\n/** The declaration that binds `name` anywhere in the script, ignoring those in `except`. */\nexport function declaresName(\n script: SourceFile,\n name: string,\n except: readonly Node[] = [],\n): Node | undefined {\n const { SyntaxKind } = loadTsMorph();\n for (const node of script.getDescendantsOfKind(SyntaxKind.Identifier)) {\n if (node.getText() !== name) continue;\n const parent = node.getParent();\n if (!bindsIdentifier(parent, node)) continue;\n if (except.some((skip) => skip === parent || isInside(parent, skip))) continue;\n return parent;\n }\n return undefined;\n}\n\nfunction bindsIdentifier(parent: Node, node: Identifier): boolean {\n const { Node } = loadTsMorph();\n if (\n Node.isVariableDeclaration(parent) ||\n Node.isBindingElement(parent) ||\n Node.isFunctionDeclaration(parent) ||\n Node.isClassDeclaration(parent) ||\n Node.isParameterDeclaration(parent) ||\n Node.isEnumDeclaration(parent)\n ) {\n return parent.getNameNode() === node;\n }\n if (Node.isImportSpecifier(parent)) {\n return (parent.getAliasNode() ?? parent.getNameNode()) === node;\n }\n if (Node.isImportClause(parent)) return parent.getDefaultImport() === node;\n if (Node.isNamespaceImport(parent)) return parent.getNameNode() === node;\n return false;\n}\n\n/** Identifiers spelled `name` that are member names (`x.name`), never the package's binding. */\nexport function memberAccesses(script: SourceFile, name: string): readonly Identifier[] {\n const { Node, SyntaxKind } = loadTsMorph();\n return script.getDescendantsOfKind(SyntaxKind.Identifier).filter((node) => {\n const parent = node.getParent();\n return (\n node.getText() === name &&\n Node.isPropertyAccessExpression(parent) &&\n parent.getNameNode() === node\n );\n });\n}\n\nexport function replaceNode(node: Node, text: string): TextEdit {\n return { start: node.getStart(), end: node.getEnd(), text };\n}\n\n/** Splice non-overlapping edits into `text`. */\nexport function applyTextEdits(text: string, edits: readonly TextEdit[]): string {\n const ordered = [...edits].sort((left, right) => right.start - left.start);\n let output = text;\n let floor = Number.POSITIVE_INFINITY;\n for (const edit of ordered) {\n if (edit.end > floor) throw new Error('overlapping codemod edits');\n output = `${output.slice(0, edit.start)}${edit.text}${output.slice(edit.end)}`;\n floor = edit.start;\n }\n return output;\n}\n","/**\n * Ledger entry 9: `fetchPreviewDocument()`/`fetchPreviewGlobal()` on the root\n * entry → `definePreview({ serverURL, depth }).fetchDocument()`/`.fetchGlobal()`\n * on `payload-live-preview/server`.\n */\nimport {\n PACKAGE_NAME,\n declaresName,\n loadTsMorph,\n packageBindings,\n propertyKey,\n referencesTo,\n type PackageBinding,\n} from '../ast';\nimport type { CodemodImplementation, CodemodConflict, CodemodPlan, TextEdit } from '../types';\nimport type {\n CallExpression,\n ImportDeclaration,\n ObjectLiteralExpression,\n SourceFile,\n} from 'ts-morph';\n\nconst ID = 'move-fetch-preview-helpers';\nconst SERVER_SPECIFIER = `${PACKAGE_NAME}/server`;\nconst METHOD: Readonly<Record<string, string>> = {\n fetchPreviewDocument: 'fetchDocument',\n fetchPreviewGlobal: 'fetchGlobal',\n};\nconst SERVER_OPTIONS = new Set(['serverURL', 'apiRoute', 'depth']);\nconst DROPPED_OPTIONS = new Set(['draft', 'fetchFn']);\n/**\n * What `ReadDocumentOptions`/`ReadGlobalOptions` accept (src/server/preview.ts).\n * 1.x spelled the target `collection` and `global` too, so there is no rename to\n * make here — a key that is in neither set is one this codemod cannot place, and\n * passing it through unannounced produces a file that does not compile.\n */\nconst SHARED_READ_OPTIONS = ['authorization', 'locale', 'headers', 'signal', 'errorMode'];\nconst READ_OPTIONS: Readonly<Record<string, readonly string[]>> = {\n fetchPreviewDocument: ['collection', 'where', ...SHARED_READ_OPTIONS],\n fetchPreviewGlobal: ['global', ...SHARED_READ_OPTIONS],\n};\nconst DEPTH_TODO =\n 'depth: 1 /* TODO(pll migrate): the 1.x default; match the runtime mergeDepth */';\nconst AUTHORIZATION_TODO =\n 'authorization: null /* TODO(pll migrate): pass the verdict from authorizePreviewRequest(); ' +\n 'null reads the published document */';\n\nfunction conflict(line: number, reason: string): CodemodConflict {\n return { codemod: ID, reason, line };\n}\n\ninterface RewrittenCall {\n readonly edit: TextEdit;\n readonly notes: readonly CodemodConflict[];\n}\n\nfunction rewriteCall(\n call: CallExpression,\n options: ObjectLiteralExpression,\n imported: string,\n): RewrittenCall {\n const server: string[] = [];\n const read: string[] = [];\n const dropped: string[] = [];\n const keys = new Set<string>();\n for (const property of options.getProperties()) {\n const key = propertyKey(property);\n if (key !== undefined) keys.add(key);\n if (key !== undefined && SERVER_OPTIONS.has(key)) server.push(property.getText());\n else if (key !== undefined && DROPPED_OPTIONS.has(key)) dropped.push(key);\n else read.push(property.getText());\n }\n if (!keys.has('depth')) server.push(DEPTH_TODO);\n if (!keys.has('authorization')) read.push(AUTHORIZATION_TODO);\n const accepted = READ_OPTIONS[imported] ?? [];\n const unplaceable = [...keys].filter(\n (key) => !SERVER_OPTIONS.has(key) && !DROPPED_OPTIONS.has(key) && !accepted.includes(key),\n );\n const typeArguments = call.getTypeArguments().map((argument) => argument.getText());\n const generic = typeArguments.length === 0 ? '' : `<${typeArguments.join(', ')}>`;\n const method = METHOD[imported] ?? imported;\n const text = `definePreview({ ${server.join(', ')} }).${method}${generic}({ ${read.join(', ')} })`;\n const droppedNote = dropped.length === 0 ? '' : `, and ${dropped.join('/')} was dropped`;\n const line = call.getStartLineNumber();\n const notes = [\n conflict(\n line,\n `${imported}() was rewritten onto definePreview().${method}(); it now returns a ` +\n `PreviewFetchResult (check ok/data) and needs a real authorization for drafts${droppedNote}`,\n ),\n ];\n if (unplaceable.length > 0) {\n notes.push(\n conflict(\n line,\n `${imported}() was passed ${unplaceable.map((key) => `\\`${key}\\``).join(', ')}, which ` +\n `.${method}() does not accept; it takes ${accepted.join(', ')}. The key was carried ` +\n 'over unchanged and will not compile — place it by hand',\n ),\n );\n }\n return { edit: { start: call.getStart(), end: call.getEnd(), text }, notes };\n}\n\nfunction importLine(quote: string, names: readonly string[], specifier: string): string {\n return `import { ${names.join(', ')} } from ${quote}${specifier}${quote};`;\n}\n\n/** Drop the moved names from their root imports and make sure `definePreview` is imported from the server entry. */\nfunction rewriteImports(script: SourceFile, bindings: readonly PackageBinding[]): TextEdit[] {\n const { Node } = loadTsMorph();\n const edits: TextEdit[] = [];\n const declarations = new Set<ImportDeclaration>();\n for (const binding of bindings) {\n if (Node.isImportDeclaration(binding.declaration)) declarations.add(binding.declaration);\n }\n const serverImport = script\n .getImportDeclarations()\n .find(\n (declaration) =>\n declaration.getModuleSpecifierValue() === SERVER_SPECIFIER && !declaration.isTypeOnly(),\n );\n const hasDefinePreview =\n serverImport?.getNamedImports().some((spec) => spec.getName() === 'definePreview') === true;\n let serverLine: string | undefined;\n if (serverImport !== undefined && !hasDefinePreview) {\n const quote = serverImport.getModuleSpecifier().getQuoteKind();\n const names = [\n ...serverImport.getNamedImports().map((spec) => spec.getText()),\n 'definePreview',\n ];\n const defaultImport = serverImport.getDefaultImport()?.getText();\n const clauses =\n defaultImport === undefined ? names.join(', ') : `${defaultImport}, { ${names.join(', ')} }`;\n const text =\n defaultImport === undefined\n ? importLine(quote, names, SERVER_SPECIFIER)\n : `import ${clauses} from ${quote}${SERVER_SPECIFIER}${quote};`;\n edits.push({ start: serverImport.getStart(), end: serverImport.getEnd(), text });\n }\n for (const declaration of declarations) {\n const quote = declaration.getModuleSpecifier().getQuoteKind();\n const remaining = declaration\n .getNamedImports()\n .filter((spec) => !(spec.getName() in METHOD))\n .map((spec) => spec.getText());\n const defaultImport = declaration.getDefaultImport()?.getText();\n const clauses = [\n defaultImport,\n remaining.length === 0 ? undefined : `{ ${remaining.join(', ')} }`,\n ].filter((clause): clause is string => clause !== undefined);\n const typeOnly = declaration.isTypeOnly() ? 'type ' : '';\n const kept =\n clauses.length === 0\n ? ''\n : `import ${typeOnly}${clauses.join(', ')} from ${quote}${PACKAGE_NAME}${quote};`;\n if (serverImport === undefined && serverLine === undefined) {\n serverLine = importLine(quote, ['definePreview'], SERVER_SPECIFIER);\n edits.push({\n start: declaration.getStart(),\n end: declaration.getEnd(),\n text: kept === '' ? serverLine : `${kept}\\n${serverLine}`,\n });\n } else {\n // A removed declaration takes its line break with it.\n const end = declaration.getEnd();\n const trailingNewline = kept === '' && script.getFullText()[end] === '\\n' ? 1 : 0;\n edits.push({ start: declaration.getStart(), end: end + trailingNewline, text: kept });\n }\n }\n return edits;\n}\n\nfunction plan(script: SourceFile, bindings: readonly PackageBinding[]): CodemodPlan {\n const { Node } = loadTsMorph();\n const blocking: CodemodConflict[] = [];\n const notes: CodemodConflict[] = [];\n const edits: TextEdit[] = [];\n for (const binding of bindings) {\n if (binding.kind === 'require') {\n blocking.push(\n conflict(\n binding.declaration.getStartLineNumber(),\n `${binding.imported} is bound with require(); rewrite it onto definePreview() from ` +\n `${SERVER_SPECIFIER} by hand`,\n ),\n );\n continue;\n }\n for (const reference of referencesTo(script, binding)) {\n const line = reference.node.getStartLineNumber();\n const call = reference.node.getParent();\n const isCall =\n reference.kind === 'reference' &&\n Node.isCallExpression(call) &&\n call.getExpression() === reference.node;\n if (!isCall) {\n blocking.push(\n conflict(\n line,\n `${binding.local} is used other than as a direct call; rewrite it onto definePreview() by hand`,\n ),\n );\n continue;\n }\n const [options] = call.getArguments();\n if (\n options === undefined ||\n !Node.isObjectLiteralExpression(options) ||\n options.getProperties().some((property) => Node.isSpreadAssignment(property))\n ) {\n blocking.push(\n conflict(\n line,\n `${binding.imported}() options are not a plain object literal, so serverURL/depth ` +\n 'cannot be split out; rewrite it onto definePreview() by hand',\n ),\n );\n continue;\n }\n const rewritten = rewriteCall(call, options, binding.imported);\n edits.push(rewritten.edit);\n notes.push(...rewritten.notes);\n }\n }\n const serverDeclaration = script\n .getImportDeclarations()\n .filter((declaration) => declaration.getModuleSpecifierValue() === SERVER_SPECIFIER);\n const foreign = declaresName(script, 'definePreview', serverDeclaration);\n if (foreign !== undefined) {\n blocking.push(\n conflict(\n foreign.getStartLineNumber(),\n `this module already binds a definePreview that is not ${SERVER_SPECIFIER}'s; rename it, ` +\n 'then move the fetch helpers by hand',\n ),\n );\n }\n if (blocking.length > 0) return { edits: [], conflicts: [...blocking, ...notes] };\n edits.push(...rewriteImports(script, bindings));\n return { edits, conflicts: notes };\n}\n\nexport const moveFetchPreviewHelpers: CodemodImplementation = {\n id: ID,\n summary:\n '`fetchPreviewDocument`/`fetchPreviewGlobal` from the root → `definePreview().fetchDocument`/`.fetchGlobal` (payload-live-preview/server)',\n ledgerEntry: 9,\n apply(script) {\n const bindings = packageBindings(script).filter(\n (binding) => binding.specifier === PACKAGE_NAME && binding.imported in METHOD,\n );\n if (bindings.length === 0) return { edits: [], conflicts: [] };\n return plan(script, bindings);\n },\n};\n","/** Ledger entry 13: `hasPreviewIntent(request, { adminOrigins })` → `{ allowedOrigins }`. */\nimport { loadTsMorph, packageBindings, propertyKey, referencesTo, replaceNode } from '../ast';\nimport type { CodemodImplementation, CodemodConflict, TextEdit } from '../types';\n\nconst ID = 'rename-admin-origins-option';\nconst CALLEE = 'hasPreviewIntent';\nconst OLD_KEY = 'adminOrigins';\nconst NEW_KEY = 'allowedOrigins';\nconst BY_HAND = `if they carry \\`${OLD_KEY}\\`, rename it to \\`${NEW_KEY}\\``;\n\nexport const renameAdminOriginsOption: CodemodImplementation = {\n id: ID,\n summary: '`hasPreviewIntent(request, { adminOrigins })` → `{ allowedOrigins }`',\n ledgerEntry: 13,\n apply(script) {\n const { Node } = loadTsMorph();\n const edits: TextEdit[] = [];\n const conflicts: CodemodConflict[] = [];\n const bindings = packageBindings(script).filter((binding) => binding.imported === CALLEE);\n for (const binding of bindings) {\n for (const reference of referencesTo(script, binding)) {\n const call = reference.node.getParent();\n if (reference.kind !== 'reference' || !Node.isCallExpression(call)) continue;\n if (call.getExpression() !== reference.node) continue;\n const options = call.getArguments()[1];\n if (options === undefined) continue;\n const line = options.getStartLineNumber();\n if (!Node.isObjectLiteralExpression(options)) {\n conflicts.push({\n codemod: ID,\n line,\n reason: `${CALLEE}() options are not a literal; ${BY_HAND}`,\n });\n continue;\n }\n const properties = options.getProperties();\n const keys = properties.map((property) => propertyKey(property));\n // With both names the package reads `allowedOrigins` and ignores the\n // alias; renamed, the later key would win instead.\n if (keys.includes(OLD_KEY) && keys.includes(NEW_KEY)) {\n conflicts.push({\n codemod: ID,\n line,\n reason: `${CALLEE}() is given both ${OLD_KEY} and ${NEW_KEY}; ${NEW_KEY} wins, drop ${OLD_KEY} by hand`,\n });\n continue;\n }\n for (const property of properties) {\n if (Node.isSpreadAssignment(property)) {\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: `${CALLEE}() spreads its options; ${BY_HAND}`,\n });\n } else if (propertyKey(property) !== OLD_KEY) {\n continue;\n } else if (Node.isShorthandPropertyAssignment(property)) {\n edits.push(replaceNode(property, `${NEW_KEY}: ${OLD_KEY}`));\n } else if (Node.isPropertyAssignment(property)) {\n edits.push(replaceNode(property.getNameNode(), NEW_KEY));\n }\n }\n }\n }\n return { edits, conflicts };\n },\n};\n","/** Ledger entry 7: `createPreviewBindings({ authorized })` → `{ authorization }`. */\nimport { loadTsMorph, packageBindings, propertyKey, referencesTo, replaceNode } from '../ast';\nimport type { CodemodImplementation, CodemodConflict, TextEdit } from '../types';\n\nconst ID = 'rename-bindings-authorized-option';\nconst OLD_KEY = 'authorized';\nconst NEW_KEY = 'authorization';\nconst BY_HAND =\n `if they carry \\`${OLD_KEY}\\`, rename it to \\`${NEW_KEY}\\` and pass the verdict from ` +\n 'authorizePreviewRequest()';\n/**\n * `false` has an exact equivalent — an unauthorized response suppresses every\n * binding, which is what `null` means — so it is rewritten. Nothing else does:\n * only a real context from `authorizePreviewRequest()` authorizes emission, and\n * a boolean left under the new name does not compile (TS2322).\n */\nconst BOOLEAN_REFUSED =\n `\\`${NEW_KEY}\\` takes the context from authorizePreviewRequest(); the boolean 1.x ` +\n 'accepted is not. The key was renamed and its value left as it stands — pass the ' +\n 'verdict, or `null` for a public response';\n\nexport const renameBindingsAuthorizedOption: CodemodImplementation = {\n id: ID,\n summary: '`createPreviewBindings({ authorized })` → `{ authorization }`',\n ledgerEntry: 7,\n apply(script) {\n const { Node } = loadTsMorph();\n const edits: TextEdit[] = [];\n const conflicts: CodemodConflict[] = [];\n const bindings = packageBindings(script).filter(\n (binding) => binding.imported === 'createPreviewBindings',\n );\n for (const binding of bindings) {\n for (const reference of referencesTo(script, binding)) {\n const call = reference.node.getParent();\n if (reference.kind !== 'reference' || !Node.isCallExpression(call)) continue;\n if (call.getExpression() !== reference.node) continue;\n const [options] = call.getArguments();\n if (options === undefined) continue;\n const line = options.getStartLineNumber();\n if (!Node.isObjectLiteralExpression(options)) {\n conflicts.push({\n codemod: ID,\n line,\n reason: `createPreviewBindings() options are not a literal; ${BY_HAND}`,\n });\n continue;\n }\n for (const property of options.getProperties()) {\n if (Node.isSpreadAssignment(property)) {\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: `createPreviewBindings() spreads its options; ${BY_HAND}`,\n });\n } else if (propertyKey(property) !== OLD_KEY) {\n continue;\n } else if (Node.isShorthandPropertyAssignment(property)) {\n edits.push(replaceNode(property, `${NEW_KEY}: ${OLD_KEY}`));\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: BOOLEAN_REFUSED,\n });\n } else if (Node.isPropertyAssignment(property)) {\n const value = property.getInitializer();\n if (value !== undefined && Node.isFalseLiteral(value)) {\n edits.push(replaceNode(property, `${NEW_KEY}: null`));\n continue;\n }\n edits.push(replaceNode(property.getNameNode(), NEW_KEY));\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: BOOLEAN_REFUSED,\n });\n }\n }\n }\n }\n return { edits, conflicts };\n },\n};\n","/** Ledger entry 1: `isPreviewRequest()` → `hasPreviewIntent()`, same signature. */\nimport {\n declaresName,\n memberAccesses,\n packageBindings,\n referencesTo,\n replaceNode,\n type PackageBinding,\n} from '../ast';\nimport type { CodemodImplementation, CodemodConflict, CodemodPlan, TextEdit } from '../types';\n\nconst ID = 'rename-is-preview-request';\nconst OLD_NAME = 'isPreviewRequest';\nconst NEW_NAME = 'hasPreviewIntent';\n\nfunction conflict(line: number, reason: string): CodemodConflict {\n return { codemod: ID, reason, line };\n}\n\nfunction renameBinding(binding: PackageBinding): TextEdit {\n // `import { isPreviewRequest as hasPreviewIntent }` collapses to the bare name.\n if (binding.aliased && binding.local === NEW_NAME) {\n return replaceNode(binding.importedNode.getParentOrThrow(), NEW_NAME);\n }\n return replaceNode(binding.importedNode, NEW_NAME);\n}\n\nfunction plan(\n bindings: readonly PackageBinding[],\n script: Parameters<CodemodImplementation['apply']>[0],\n): CodemodPlan {\n const blocking: CodemodConflict[] = [];\n const edits: TextEdit[] = [];\n const existing = declaresName(\n script,\n NEW_NAME,\n bindings.map((binding) => binding.declaration),\n );\n if (existing !== undefined) {\n blocking.push(\n conflict(\n existing.getStartLineNumber(),\n `this module already binds ${NEW_NAME}; rename it (or drop the wrapper and import the ` +\n `package's ${NEW_NAME} directly), then rename ${OLD_NAME} by hand`,\n ),\n );\n }\n for (const binding of bindings) {\n edits.push(renameBinding(binding));\n if (binding.aliased) continue;\n for (const reference of referencesTo(script, binding)) {\n if (reference.kind === 'reference') {\n edits.push(replaceNode(reference.node, NEW_NAME));\n } else if (reference.kind === 'shorthand') {\n blocking.push(\n conflict(\n reference.node.getStartLineNumber(),\n `{ ${OLD_NAME} } keeps the old key for whoever reads it; write ` +\n `{ ${OLD_NAME}: ${NEW_NAME} } or rename the key and its readers by hand`,\n ),\n );\n } else {\n blocking.push(\n conflict(\n reference.node.getStartLineNumber(),\n `${OLD_NAME} is re-exported under its old name; rename the export and its ` +\n `importers, or write export { ${NEW_NAME} as ${OLD_NAME} }`,\n ),\n );\n }\n }\n }\n const notes = memberAccesses(script, OLD_NAME).map((node) =>\n conflict(\n node.getStartLineNumber(),\n `.${OLD_NAME} is a member of this module's own object, not the package import, and was ` +\n 'left alone; check that it does not wrap the removed API',\n ),\n );\n if (blocking.length > 0) return { edits: [], conflicts: [...blocking, ...notes] };\n return { edits, conflicts: notes };\n}\n\nexport const renameIsPreviewRequest: CodemodImplementation = {\n id: ID,\n summary: '`isPreviewRequest()` → `hasPreviewIntent()` (same signature)',\n ledgerEntry: 1,\n // The rename keeps behaviour, and that is the part worth saying: the 2.0\n // adapters count only the query, and a renamed call silently does not.\n notice:\n 'hasPreviewIntent() takes the options isPreviewRequest() took and, without `signals`, counts ' +\n 'the same three: a preview query parameter, Sec-Fetch-Dest: iframe and an admin Referer. The ' +\n \"2.0 adapters count only the query; where a call should agree with them, pass { signals: ['query'] } \" +\n '(docs/migration.md).',\n apply(script) {\n const bindings = packageBindings(script).filter((binding) => binding.imported === OLD_NAME);\n if (bindings.length === 0) return { edits: [], conflicts: [] };\n return plan(bindings, script);\n },\n};\n","/** Where the script lives in a file: the whole file, or the script blocks of a component. */\nimport { extname } from 'node:path';\nimport type { ScriptKind } from './ast';\n\nexport interface ScriptBlock {\n readonly start: number;\n readonly end: number;\n readonly kind: ScriptKind;\n}\n\nconst WHOLE_FILE: Readonly<Record<string, ScriptKind>> = {\n '.ts': 'ts',\n '.mts': 'ts',\n '.cts': 'ts',\n '.tsx': 'tsx',\n '.js': 'js',\n '.mjs': 'js',\n '.cjs': 'js',\n '.jsx': 'jsx',\n};\nconst COMPONENT_EXTENSIONS = new Set(['.astro', '.vue', '.svelte']);\nconst FRONTMATTER = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/u;\n// Browsers close a script on `</script` followed by anything up to `>`, so the\n// end tag must accept that too, or a stray `</script foo>` would swallow the\n// rest of the file into one block.\nconst SCRIPT_TAG = /<script(?:\\s[^>]*)?>([\\s\\S]*?)<\\/script\\b[^>]*>/giu;\n\nexport function scriptBlocks(source: string, fileName: string): readonly ScriptBlock[] {\n const extension = extname(fileName).toLowerCase();\n if (!COMPONENT_EXTENSIONS.has(extension)) {\n return [{ start: 0, end: source.length, kind: WHOLE_FILE[extension] ?? 'ts' }];\n }\n const blocks: ScriptBlock[] = [];\n const frontmatter = extension === '.astro' ? FRONTMATTER.exec(source) : null;\n if (frontmatter?.[1] !== undefined) {\n const start = frontmatter.index + frontmatter[0].indexOf('\\n') + 1;\n blocks.push({ start, end: start + frontmatter[1].length, kind: 'ts' });\n }\n for (const match of source.matchAll(SCRIPT_TAG)) {\n const body = match[1] ?? '';\n if (body.trim() === '') continue;\n const start = match.index + match[0].lastIndexOf(body);\n blocks.push({ start, end: start + body.length, kind: 'ts' });\n }\n return blocks;\n}\n","/**\n * `pll migrate`: the 1.x → 2.0 codemods and the driver that applies them to one\n * source string. Rewrites are planned on the AST (ts-morph) so only names the\n * package binds are touched; see ADR 0007.\n */\nimport { applyTextEdits, parseScript } from './ast';\nimport { moveFetchPreviewHelpers } from './codemods/move-fetch-preview-helpers';\nimport { renameAdminOriginsOption } from './codemods/rename-admin-origins-option';\nimport { renameBindingsAuthorizedOption } from './codemods/rename-bindings-authorized-option';\nimport { renameIsPreviewRequest } from './codemods/rename-is-preview-request';\nimport { scriptBlocks } from './script-blocks';\nimport type {\n Codemod,\n CodemodConflict,\n CodemodEdit,\n CodemodImplementation,\n CodemodLineEdit,\n} from './types';\n\nexport type {\n Codemod,\n CodemodConflict,\n CodemodEdit,\n CodemodLineEdit,\n CodemodPlan,\n TextEdit,\n} from './types';\n\nconst PACKAGE_REFERENCE =\n /(?:\\bfrom\\s*|\\bimport\\s*\\(?\\s*|\\brequire\\s*\\(\\s*)['\"]payload-live-preview(?:\\/[^'\"]*)?['\"]/u;\n\n/** Whether the source names the package in an `import`, `import()` or `require()`. @internal */\nexport function importsThisPackage(source: string): boolean {\n return PACKAGE_REFERENCE.test(source);\n}\n\n// The option rename follows the function rename so it sees the new binding.\nconst IMPLEMENTATIONS: readonly CodemodImplementation[] = [\n renameIsPreviewRequest,\n renameAdminOriginsOption,\n renameBindingsAuthorizedOption,\n moveFetchPreviewHelpers,\n];\n\n/**\n * The codemods in the order they run. Each is idempotent. Metadata only: the\n * rewrite is internal, so importing this entry's types does not require\n * `ts-morph`, which is needed only to run `pll migrate`.\n * @internal\n */\nexport const CODEMODS: readonly Codemod[] = IMPLEMENTATIONS;\n\nexport interface MigrateSourceOptions {\n /** Restrict to these codemod ids. */\n readonly only?: readonly string[];\n /**\n * Decides how the source is parsed: `.astro`, `.vue` and `.svelte` by script\n * block, JSX by extension. Defaults to a `.ts` module.\n */\n readonly fileName?: string;\n}\n\nexport interface MigrateSourceResult {\n readonly output: string;\n readonly edits: readonly CodemodEdit[];\n readonly conflicts: readonly CodemodConflict[];\n}\n\nfunction lineNumberAt(source: string, offset: number): number {\n let line = 1;\n for (let index = 0; index < offset; index += 1) if (source[index] === '\\n') line += 1;\n return line;\n}\n\n/** The changed lines between two versions, trimmed to the differing middle. */\nfunction lineEdits(before: string, after: string, firstLine: number): CodemodLineEdit[] {\n const oldLines = before.split('\\n');\n const newLines = after.split('\\n');\n let prefix = 0;\n while (\n prefix < oldLines.length &&\n prefix < newLines.length &&\n oldLines[prefix] === newLines[prefix]\n ) {\n prefix += 1;\n }\n let suffix = 0;\n while (\n suffix < oldLines.length - prefix &&\n suffix < newLines.length - prefix &&\n oldLines[oldLines.length - 1 - suffix] === newLines[newLines.length - 1 - suffix]\n ) {\n suffix += 1;\n }\n const oldMiddle = oldLines.slice(prefix, oldLines.length - suffix);\n const newMiddle = newLines.slice(prefix, newLines.length - suffix);\n const changed: CodemodLineEdit[] = [];\n for (let index = 0; index < Math.max(oldMiddle.length, newMiddle.length); index += 1) {\n const before = oldMiddle[index] ?? '';\n const after = newMiddle[index] ?? '';\n if (before !== after) changed.push({ line: firstLine + prefix + index, before, after });\n }\n return changed;\n}\n\n/** Apply every codemod (or the chosen subset) to one source string. */\nexport function migrateSource(\n source: string,\n options: MigrateSourceOptions = {},\n): MigrateSourceResult {\n const chosen =\n options.only === undefined\n ? IMPLEMENTATIONS\n : IMPLEMENTATIONS.filter((codemod) => options.only?.includes(codemod.id));\n if (chosen.length === 0 || !importsThisPackage(source)) {\n return { output: source, edits: [], conflicts: [] };\n }\n const byCodemod = new Map<string, CodemodLineEdit[]>();\n const conflicts: CodemodConflict[] = [];\n let output = '';\n let cursor = 0;\n for (const block of scriptBlocks(source, options.fileName ?? 'source.ts')) {\n output += source.slice(cursor, block.start);\n const firstLine = lineNumberAt(source, block.start);\n let text = source.slice(block.start, block.end);\n for (const codemod of chosen) {\n const plan = codemod.apply(parseScript(text, block.kind));\n for (const item of plan.conflicts) {\n conflicts.push(\n item.line === undefined ? item : { ...item, line: item.line + firstLine - 1 },\n );\n }\n if (plan.edits.length === 0) continue;\n const next = applyTextEdits(text, plan.edits);\n const lines = byCodemod.get(codemod.id) ?? [];\n lines.push(...lineEdits(text, next, firstLine));\n byCodemod.set(codemod.id, lines);\n text = next;\n }\n output += text;\n cursor = block.end;\n }\n output += source.slice(cursor);\n const edits = [...byCodemod].map(([codemod, lines]) => ({ codemod, count: lines.length, lines }));\n return { output, edits, conflicts };\n}\n","/** The file walker behind `pll migrate`: find source files, apply the codemods, report or write. */\nimport { readFile, readdir, stat, writeFile } from 'node:fs/promises';\nimport { extname, join, relative } from 'node:path';\nimport { migrateSource } from './index';\nimport type { CodemodConflict, CodemodEdit } from './types';\n\nconst SOURCE_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.mts',\n '.cts',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.astro',\n '.svelte',\n '.vue',\n]);\nconst DECLARATION_FILE = /\\.d\\.[cm]?ts$/u;\nconst SKIP_DIRECTORIES = new Set([\n 'node_modules',\n 'dist',\n '.git',\n '.astro',\n '.svelte-kit',\n '.next',\n '.nuxt',\n 'coverage',\n]);\n\nexport interface MigrateFileResult {\n readonly file: string;\n readonly edits: readonly CodemodEdit[];\n readonly changed: boolean;\n /** What a codemod could not rewrite safely in this file. */\n readonly conflicts: readonly CodemodConflict[];\n}\n\nexport interface MigrateRunResult {\n readonly files: readonly MigrateFileResult[];\n /** Files the run changed (or would change, in dry-run). */\n readonly changedCount: number;\n /** Codemod id → number of files it touched. */\n readonly byCodemod: Readonly<Record<string, number>>;\n /** Files needing manual attention. */\n readonly conflictCount: number;\n}\n\nexport interface MigrateOptions {\n /** Apply and save; without it the run only reports. */\n readonly write?: boolean;\n /** Restrict to these codemod ids. */\n readonly only?: readonly string[];\n /** Reader/writer injection for tests. */\n readonly io?: {\n readonly read: (path: string) => Promise<string>;\n readonly write: (path: string, content: string) => Promise<void>;\n readonly list: (root: string) => Promise<readonly string[]>;\n };\n}\n\nfunction isSourceFile(name: string): boolean {\n return SOURCE_EXTENSIONS.has(extname(name)) && !DECLARATION_FILE.test(name);\n}\n\nasync function collectFiles(root: string): Promise<string[]> {\n const found: string[] = [];\n async function walk(directory: string): Promise<void> {\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n const path = join(directory, entry.name);\n if (entry.isDirectory()) {\n if (!SKIP_DIRECTORIES.has(entry.name)) await walk(path);\n } else if (isSourceFile(entry.name)) {\n found.push(path);\n }\n }\n }\n const info = await stat(root);\n if (info.isDirectory()) await walk(root);\n else if (isSourceFile(root)) found.push(root);\n return found.sort();\n}\n\nfunction relativeTo(root: string, file: string): string {\n const rel = relative(root, file);\n return rel.length === 0 ? file : rel;\n}\n\n/** Migrate every source file under `root`. */\nexport async function runMigrate(\n root: string,\n options: MigrateOptions = {},\n): Promise<MigrateRunResult> {\n const io = options.io ?? {\n read: (path) => readFile(path, 'utf8'),\n write: (path, content) => writeFile(path, content, 'utf8'),\n list: collectFiles,\n };\n const results: MigrateFileResult[] = [];\n const byCodemod: Record<string, number> = {};\n for (const file of await io.list(root)) {\n const source = await io.read(file);\n const { output, edits, conflicts } = migrateSource(source, {\n fileName: file,\n ...(options.only === undefined ? {} : { only: options.only }),\n });\n const changed = output !== source;\n if (changed && options.write === true) await io.write(file, output);\n if (changed) {\n for (const edit of edits) byCodemod[edit.codemod] = (byCodemod[edit.codemod] ?? 0) + 1;\n }\n results.push({ file: relativeTo(root, file), edits, changed, conflicts });\n }\n return {\n files: results,\n changedCount: results.filter((result) => result.changed).length,\n byCodemod,\n conflictCount: results.filter((result) => result.conflicts.length > 0).length,\n };\n}\n","/**\n * `pll migrate <path> [--write] [--only <id,id>]`, hosted by the `pll` binary.\n * Exit codes: 0 clean, 1 usage or I/O error, 3 when conflicts need a human.\n */\nimport { CODEMODS } from './index';\nimport { runMigrate, type MigrateFileResult } from './runner';\n\nexport const MIGRATE_HELP = `pll migrate — rewrite 1.x APIs to their 2.0 names and homes (ADR 0007)\n\nUsage:\n pll migrate <path> [--write] [--only <id,id>]\n\nWithout --write the run only reports what it would change. Codemods touch\nonly names bound from payload-live-preview; anything they cannot rewrite\nsafely is listed as needing manual attention. Requires ts-morph.\n\nOptions:\n --write Apply the changes (otherwise dry-run)\n --only <ids> Run only these codemods (comma-separated)\n -h, --help Show this help\n\nExit codes:\n 0 nothing needs a human (changes applied, or would be with --write)\n 1 usage error, unreadable path, or ts-morph is not installed\n 3 at least one file needs manual attention\n`;\n\ninterface MigrateArgs {\n readonly target: string | undefined;\n readonly write: boolean;\n readonly only: readonly string[] | undefined;\n readonly help: boolean;\n readonly unknown: string | undefined;\n}\n\nfunction parseArgs(argv: readonly string[]): MigrateArgs {\n let target: string | undefined;\n let write = false;\n let only: string[] | undefined;\n let help = false;\n let unknown: string | undefined;\n const ids = (value: string): string[] => value.split(',').filter((id) => id.length > 0);\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === undefined) continue;\n if (token === '-h' || token === '--help') help = true;\n else if (token === '--write') write = true;\n else if (token === '--only') {\n only = ids(argv[index + 1] ?? '');\n index += 1;\n } else if (token.startsWith('--only=')) only = ids(token.slice('--only='.length));\n else if (token.startsWith('-')) unknown ??= token;\n else target ??= token;\n }\n return { target, write, only, help, unknown };\n}\n\nfunction describe(file: MigrateFileResult): string {\n return file.edits.map((edit) => `${edit.codemod}: ${String(edit.count)} line(s)`).join(', ');\n}\n\nexport async function runMigrateCommand(argv: readonly string[]): Promise<number> {\n const args = parseArgs(argv);\n if (args.help) {\n process.stdout.write(MIGRATE_HELP);\n return 0;\n }\n if (args.unknown !== undefined) {\n process.stderr.write(`pll migrate: unknown option ${args.unknown}\\n`);\n return 1;\n }\n if (args.target === undefined) {\n process.stderr.write('pll migrate: a path is required. Try `pll migrate --help`.\\n');\n return 1;\n }\n let result;\n try {\n result = await runMigrate(args.target, {\n write: args.write,\n ...(args.only === undefined ? {} : { only: args.only }),\n });\n } catch (error) {\n process.stderr.write(\n `pll migrate: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n return 1;\n }\n for (const file of result.files) {\n if (!file.changed) continue;\n process.stdout.write(\n `${args.write ? 'migrated' : 'would migrate'} ${file.file} (${describe(file)})\\n`,\n );\n }\n process.stdout.write(\n `\\n${args.write ? 'Migrated' : 'Would migrate'} ${String(result.changedCount)} file(s).` +\n `${args.write ? '' : ' Re-run with --write to apply.'}\\n`,\n );\n for (const { id, notice } of CODEMODS) {\n if (notice !== undefined && (result.byCodemod[id] ?? 0) > 0) {\n process.stdout.write(`\\nNote (${id}): ${notice}\\n`);\n }\n }\n const conflicted = result.files.filter((file) => file.conflicts.length > 0);\n if (conflicted.length === 0) return 0;\n process.stdout.write(`\\n${String(conflicted.length)} file(s) need manual attention:\\n`);\n for (const file of conflicted) {\n for (const item of file.conflicts) {\n const where = item.line === undefined ? file.file : `${file.file}:${String(item.line)}`;\n process.stdout.write(` ${where}: ${item.reason}\\n`);\n }\n }\n return 3;\n}\n","/** Terminal rendering of a doctor report. */\nimport type { DoctorReport } from './types';\n\nconst LEVEL_LABEL = { error: 'ERROR', warning: 'WARN ', info: 'INFO ' } as const;\n\n/** @internal */\nexport function formatReport(report: DoctorReport): string {\n const lines: string[] = [`pll doctor — ${report.url}`, ''];\n if (report.findings.length === 0) {\n lines.push('No findings. The preview response carries the runtime, a frame-ancestors');\n lines.push('policy, and bindings; the public response carries none of them.', '');\n return lines.join('\\n');\n }\n for (const finding of report.findings) {\n lines.push(`${LEVEL_LABEL[finding.level]} ${finding.code} ${finding.title}`);\n lines.push(` ${finding.detail}`);\n if (finding.remedy !== '') lines.push(` → ${finding.remedy}`);\n lines.push('');\n }\n lines.push(`${String(report.errors)} error(s), ${String(report.warnings)} warning(s).`, '');\n return lines.join('\\n');\n}\n","/**\n * Every diagnostic code the runtime and tools emit, so a consumer can branch\n * on `e.code` instead of matching message text. A code is never reused for a\n * different meaning; a retired one stays reserved.\n *\n * Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than\n * reading it from this record: the frozen table would then ship in the inline\n * runtime for the sake of six characters — it did, 1 287 B in every page, for\n * the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`\n * now holds the artifact free of it. Server-side tools may import it.\n */\n\n/**\n * Every diagnostic code the runtime can report, by name.\n *\n * ```ts\n * client.events.on('error', (e) => {\n * if (e.code === DIAGNOSTIC_CODES.TransformThrew) reportToSentry(e.error);\n * });\n * ```\n */\nexport const DIAGNOSTIC_CODES = Object.freeze({\n /** No trusted origin configured in production; nothing will be accepted. */\n NoTrustedOrigin: 'LP0101',\n /** Origin trust rests on `document.referrer`, so any framing site is trusted. */\n ReferrerOnlyTrust: 'LP0102',\n /** A plugin declares a runtime range this runtime does not satisfy; it was refused. */\n PluginIncompatible: 'LP0103',\n /** The page carries the lean runtime and needs a feature that profile leaves out. */\n ProfileFeatureOmitted: 'LP0104',\n\n /** An update named a field with no binding anchor on the page. */\n OrphanField: 'LP0201',\n /** Owner scoping is on and the update names no document it could belong to. */\n UnattributableUpdate: 'LP0202',\n\n /** The visibility gate held offscreen writes back until they scroll into view. */\n VisibilityGateDeferred: 'LP0301',\n\n /** A value was refused because the attribute or the value itself is unsafe. */\n UnsafeAttributeWrite: 'LP0401',\n /** A text element has structured children, so replacing its text was skipped. */\n TextTargetHasChildren: 'LP0402',\n /** A structural container has no array template, so the update was skipped. */\n MissingArrayTemplate: 'LP0403',\n /** A structural item has no `id`; it pairs positionally, so an insert re-renders every row after it. */\n StructuralItemUnkeyed: 'LP0404',\n /** Two structural items share a key; later ones pair positionally. */\n StructuralDuplicateKey: 'LP0405',\n /** Every structural key changed while the length did not; the source generates keys per message. */\n StructuralUnstableKeys: 'LP0406',\n /** A binding asks for a delivery strategy this release does not have; it is left unchanged. */\n UnsupportedStrategy: 'LP0407',\n /** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */\n UnknownValueFormat: 'LP0408',\n /** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */\n SanitizerDroppedAttribute: 'LP0409',\n /** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */\n UnrenderedBlockKept: 'LP0410',\n /** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */\n UnfaithfulPatch: 'LP0411',\n /** The first write to a date, number or checkbox binding replaced a different reading of the same value. */\n ServerFormatReplaced: 'LP0412',\n /** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */\n UnrenderedBlockLost: 'LP0413',\n\n /** A message was rejected before it reached the update pipeline. */\n MessageRejected: 'LP0501',\n /** A preview token was rejected. */\n TokenRejected: 'LP0502',\n /** A trusted origin sent a message this protocol version does not recognise. */\n ProtocolShapeUnknown: 'LP0503',\n\n /** A consumer event handler threw. */\n HandlerThrew: 'LP0601',\n /** A consumer transform threw; the original value was kept. */\n TransformThrew: 'LP0602',\n /** A renderer threw while writing a value. */\n RendererThrew: 'LP0603',\n // LP0604 is reserved and unassigned; codes are never reused or renumbered.\n /** Runtime startup failed. */\n StartupFailed: 'LP0605',\n /** Sending the ready handshake failed. */\n ReadyFailed: 'LP0606',\n /** The page declared hydration, but no React commit or Vue mount came within the cap; the runtime started without waiting. */\n HydrationWaitTimedOut: 'LP0607',\n\n /** The audit found no runtime in a response that carried preview intent. */\n AuditRuntimeMissing: 'LP0701',\n /** The preview response declares no `frame-ancestors`. */\n AuditNoFrameAncestors: 'LP0702',\n /** `X-Frame-Options` forbids framing, which no CSP can undo; `SAMEORIGIN` forbids it from another origin only. */\n AuditFrameOptionsBlocks: 'LP0703',\n /** Binding attributes are served to anonymous visitors. */\n AuditBindingsExposed: 'LP0704',\n /** More bindings than the default visibility gate will write eagerly. */\n AuditGateThresholdExceeded: 'LP0705',\n /** Owner markers exist, but some bindings are outside all of them. */\n AuditUnownedBindings: 'LP0706',\n /** The preview response carries no bindings at all. */\n AuditNoBindings: 'LP0707',\n /** The URL did not return an HTML page, so nothing else can be judged. */\n AuditNotAPage: 'LP0708',\n /** A fragment request failed (network, timeout, server error); the boundary was patched instead. */\n FragmentRequestFailed: 'LP0801',\n /** The fragment response had the wrong content type or shape; the boundary was patched instead. */\n FragmentResponseInvalid: 'LP0802',\n /** The fragment endpoint refused the preview (not authorized); the boundary was patched instead. */\n FragmentUnauthorized: 'LP0803',\n /** A fragment response arrived for a revision that was already superseded and was discarded. */\n FragmentSuperseded: 'LP0804',\n /** A route refresh was refused: the loop guard, or the strategy's minimum interval. */\n RouteRefreshLoop: 'LP0805',\n /** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */\n FragmentStrategyUnavailable: 'LP0806',\n /** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */\n UnboundChangeRefresh: 'LP0807',\n /** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */\n V2ReadinessGap: 'LP0709',\n /** The preview runtime is served to anonymous visitors, not only inside the admin frame. */\n RuntimeOnPublicPage: 'LP0710',\n} as const);\n\n/** A diagnostic code, as it appears in log output and on the `error` event. */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n","/**\n * `frame-ancestors` matching by the CSP3 source-expression rules. The audit\n * judges origins, so path parts of a host-source are ignored.\n */\n\nconst DEFAULT_PORT: Readonly<Record<string, string>> = {\n http: '80',\n https: '443',\n ws: '80',\n wss: '443',\n};\nconst SCHEME_SOURCE = /^([a-z][a-z0-9+.-]*):$/u;\nconst HOST_SOURCE =\n /^(?:([a-z][a-z0-9+.-]*):\\/\\/)?(\\*|(?:\\*\\.)?[a-z0-9-]+(?:\\.[a-z0-9-]+)*\\.?)(?::(\\*|\\d+))?(?:\\/.*)?$/u;\n\n/** The `frame-ancestors` directive of a policy, verbatim, or `undefined` when it has none. */\nexport function frameAncestorsOf(csp: string | undefined): string | undefined {\n if (csp === undefined) return undefined;\n for (const directive of csp.split(';')) {\n const trimmed = directive.trim();\n if (/^frame-ancestors(?:\\s|$)/iu.test(trimmed)) return trimmed;\n }\n return undefined;\n}\n\nfunction schemeOf(url: URL): string {\n return url.protocol.slice(0, -1).toLowerCase();\n}\n\nfunction portOf(url: URL): string {\n return url.port === '' ? (DEFAULT_PORT[schemeOf(url)] ?? '') : url.port;\n}\n\nfunction schemeMatches(expression: string, actual: string): boolean {\n return (\n expression === actual ||\n (expression === 'http' && actual === 'https') ||\n (expression === 'ws' && actual === 'wss')\n );\n}\n\nfunction hostMatches(pattern: string, host: string): boolean {\n if (pattern === '*') return true;\n const wanted = pattern.replace(/\\.$/u, '');\n const actual = host.replace(/\\.$/u, '');\n if (wanted.startsWith('*.')) {\n return actual.endsWith(wanted.slice(1)) && actual.length > wanted.length - 1;\n }\n return wanted === actual;\n}\n\nfunction isSelf(admin: URL, page: URL): boolean {\n if (admin.hostname !== page.hostname) return false;\n const adminScheme = schemeOf(admin);\n const pageScheme = schemeOf(page);\n if (adminScheme !== pageScheme && !(pageScheme === 'http' && adminScheme === 'https')) {\n return false;\n }\n return portOf(admin) === portOf(page) || (admin.port === '' && page.port === '');\n}\n\nfunction sourceMatches(source: string, admin: URL, page: URL): boolean {\n const scheme = SCHEME_SOURCE.exec(source);\n if (scheme?.[1] !== undefined) return schemeMatches(scheme[1], schemeOf(admin));\n const host = HOST_SOURCE.exec(source);\n if (host === null) return false;\n const expressionScheme = host[1];\n const expressionHost = host[2] ?? '';\n const expressionPort = host[3];\n const requiredScheme = expressionScheme ?? schemeOf(page);\n if (!schemeMatches(requiredScheme, schemeOf(admin))) return false;\n if (!hostMatches(expressionHost, admin.hostname)) return false;\n if (expressionPort === undefined) return admin.port === '';\n return expressionPort === '*' || expressionPort === portOf(admin);\n}\n\n/** Whether the directive admits `admin` as an ancestor of `page`. */\nexport function frameAncestorsAdmits(directive: string, admin: URL, page: URL): boolean {\n const sources = directive\n .split(/\\s+/u)\n .slice(1)\n .filter((source) => source.length > 0)\n .map((source) => source.toLowerCase());\n if (sources.length === 0 || (sources.length === 1 && sources[0] === \"'none'\")) return false;\n for (const source of sources) {\n if (source === \"'self'\") {\n if (isSelf(admin, page)) return true;\n } else if (source === '*') {\n return true;\n } else if (!source.startsWith(\"'\") && sourceMatches(source, admin, page)) {\n return true;\n }\n }\n return false;\n}\n","/**\n * The inline script's configuration and its positional wire order: the\n * generator writes the tuple, `src/core/runtime.ts` destructures it, and\n * `INLINE_CONFIG_KEYS` is where they agree. Append only, never reorder.\n */\n\nimport type { DefaultsProfile } from '@/types/defaults-profile';\n\nexport interface InlineScriptConfig {\n /** Trusted admin origins, merged with the detected ones. */\n readonly allowedOrigins?: readonly string[];\n /** Payload origin; every update is then re-fetched through the REST API with credentials. Requires `mergeDepth`. */\n readonly serverURL?: string;\n /** REST route prefix used with `serverURL`. Default `/api`. */\n readonly apiRoute?: string;\n /** Population depth used with `serverURL`. Required with `serverURL` unless `defaults: 'v1'`. */\n readonly mergeDepth?: number;\n /** Verbose console logging. Default `false`. */\n readonly debug?: boolean;\n /** Debounce window for incoming updates in ms. Default `50`. */\n readonly debounceMs?: number;\n /** Mount the screen-reader live region. Default `true`. */\n readonly enableA11y?: boolean;\n /** Heartbeat timeout in ms; `0` disables it (default), because the admin posts only on edits. */\n readonly heartbeatMs?: number;\n /** Apply every update regardless of viewport position. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cache size above which off-screen updates wait for intersection. Default `50`. */\n readonly visibilityGateThreshold?: number;\n /** `rootMargin` of the IntersectionObserver. Default `'200px'`. */\n readonly intersectionRootMargin?: string;\n /** Ignore `document.referrer` as an origin source. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly disableReferrerDetection?: boolean;\n /** Disable the dev-mode localhost matcher (any port on `localhost`/`127.0.0.1`). Default `false`. */\n readonly disableLocalhostMatching?: boolean;\n /** Update only bindings under a matching `data-payload-owner`. Default `false`. */\n readonly scopeBindingsByOwner?: boolean;\n /** Skip bindings whose value did not change. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly skipUnchanged?: boolean;\n /** Scroll the preview to the field being edited. Default `false`. */\n readonly revealEditedField?: boolean;\n /** Which windows may post updates. Default `'parent-or-opener'`; `defaults: 'v1'` sets `'any'`. */\n readonly eventSourcePolicy?: 'any' | 'parent-or-opener';\n /** Sanitizer policy for rich text and HTML writes. Default `'strict'`; `defaults: 'v1'` sets `'compat'`. */\n readonly sanitizerPolicy?: 'compat' | 'strict';\n /** Same-origin path of a fragment endpoint; the script then carries the fragment client ahead of the runtime (ADR 0011). */\n readonly fragmentEndpoint?: string;\n /**\n * Carry the route strategy, so a binding in `<head>` or one marked\n * `data-payload-strategy=\"route\"` refreshes the route. `fragmentEndpoint`\n * implies it — the fragment prelude already contains it. Default `false`.\n */\n readonly routeStrategy?: boolean;\n /**\n * The 2.0 name for `onUnfaithfulPatch`, kept until 3.0. `'route'` means\n * `'escalate'`, `'ignore'` means `'ignore'`.\n *\n * @deprecated Renamed to `onUnfaithfulPatch`.\n */\n readonly onUnboundChange?: 'ignore' | 'route';\n /**\n * What to do when the runtime knows a patch cannot reach what the server\n * would have drawn. `'escalate'` (the default) hands the region to the\n * fragment strategy when a boundary covers it and to the route otherwise, so\n * it needs `fragmentEndpoint` or `routeStrategy` to do anything. `'warn'`\n * reports LP0411 and keeps the patch; `'ignore'` keeps it silently.\n */\n readonly onUnfaithfulPatch?: 'ignore' | 'warn' | 'escalate';\n /**\n * Find bindings by value on the connection's first message (ADR 0014): a\n * scalar whose value is the whole content of exactly one element is bound\n * to it as if `data-payload-field` stood there. Default `'off'`.\n */\n readonly autoBind?: 'off' | 'unique';\n /**\n * The framework that hydrates this page (ADR 0015). Under `'react'` the\n * runtime holds its first write until React has committed the tree that\n * holds the bindings — otherwise React finds markup it did not render,\n * throws `Hydration failed` and regenerates the tree, and the write is gone.\n * Under `'vue'` it holds the write until Vue has mounted the app around them\n * — otherwise Vue's hydration repairs the write back to the server's value,\n * quietly. The Next.js and Nuxt adapters set it on every script they emit; a\n * page built by hand with `generateInlineScript()` may. Omitted: the runtime\n * starts on `DOMContentLoaded`, as on a static page.\n */\n readonly hydration?: 'react' | 'vue';\n /**\n * Which defaults the omitted options fall back to, resolved by the generator\n * rather than the runtime, whose own fallbacks are the 2.0 rows: `'v1'`\n * writes its four runtime rows into their slots (an explicit option still\n * wins) and relaxes the `mergeDepth` check. The resolved value always\n * travels, in the last slot, so a reader of the served page knows what an\n * empty slot means instead of guessing it — `pll doctor --v2` reads it. The\n * runtime does not: every row the profile decides is already in its slot.\n */\n readonly defaults?: DefaultsProfile;\n /**\n * A runtime artifact to embed instead of the full one — today only\n * `LEAN_RUNTIME` from `payload-live-preview/lean`, which leaves out the\n * strategies, the keyed morph, the structural arrays, the item templates and\n * the announcer (about 5.5 KB gzip less on the page) and reports LP0104 when\n * a page needs one of them.\n *\n * It is an imported value rather than a `profile: 'lean'` string on purpose:\n * a second artifact behind a string option would sit in every build that can\n * reach the generator, which measured +24 KB gzip in each adapter entry. This\n * way the bytes follow the import.\n *\n * Not serialized: it decides which bytes are emitted, not how they behave.\n */\n readonly runtime?: RuntimeArtifact;\n}\n\n/**\n * A runtime build this package produces. `source` is the IIFE the page runs;\n * the two digests describe the same bytes as a servable asset, so asset\n * delivery can hash-name and SRI-verify whichever artifact was chosen without\n * hashing anything at request time.\n */\nexport interface RuntimeArtifact {\n readonly profile: 'lean';\n readonly source: string;\n /** Short content hash, for the asset's file name. */\n readonly contentHash: string;\n /** `sha384-…`, for the bootstrap's `integrity` attribute. */\n readonly integrity: string;\n}\n\n/** Keys that travel in the wire tuple, in slot order. */\nexport const INLINE_CONFIG_KEYS = [\n 'allowedOrigins',\n 'serverURL',\n 'apiRoute',\n 'mergeDepth',\n 'debug',\n 'debounceMs',\n 'enableA11y',\n 'heartbeatMs',\n 'disableVisibilityGate',\n 'visibilityGateThreshold',\n 'intersectionRootMargin',\n 'disableReferrerDetection',\n 'disableLocalhostMatching',\n 'scopeBindingsByOwner',\n 'skipUnchanged',\n 'eventSourcePolicy',\n 'sanitizerPolicy',\n 'fragmentEndpoint',\n 'revealEditedField',\n 'routeStrategy',\n 'onUnboundChange',\n 'onUnfaithfulPatch',\n 'autoBind',\n 'hydration',\n 'defaults',\n] as const satisfies readonly Exclude<keyof InlineScriptConfig, 'runtime'>[];\n","/**\n * The two defaults profiles, row by row. 2.0 ships `v2`; `defaults: 'v1'` opts\n * back into the 1.x table for a staged migration. Each row belongs to exactly\n * one side — the adapter's request decision or the browser runtime — and a\n * test asserts the profile assigns every readiness row that has an option, so\n * a row added later cannot be forgotten. See ADR 0007.\n *\n * It lives in the leaf `types` domain, like `merge-depth.ts`, because the\n * inline generator resolves the profile too, and the generator is server-side\n * code that may not reach the browser runtime in `core`.\n */\n\n/** `'v2'` is the 2.0 default; `'v1'` is the 1.x table. */\nexport type DefaultsProfile = 'v1' | 'v2';\n\n/** How the runtime decides which windows may post updates. */\nexport type EventSourcePolicy = 'any' | 'parent-or-opener';\n\n/** Readiness rows that are options, keyed by the option they set. */\nexport const READINESS_ROWS = Object.freeze({\n strict: 'production response changes require an authorized context',\n previewSignals: 'query-only intent signal',\n disableReferrerDetection: 'referrer trust off',\n eventSourcePolicy: 'messages must come from parent/opener',\n skipUnchanged: 'skip unchanged bindings by default',\n sanitizerPolicy: 'hardened sanitizer id/data-* policy',\n} as const);\n\n/** Options an adapter's request decision reads from the profile. */\nexport interface AdapterProfileDefaults {\n readonly strict: boolean;\n readonly previewSignals: readonly ('query' | 'fetch-dest' | 'referer')[];\n}\n\n/** Options the browser runtime reads from the profile (through the inline configuration). */\nexport interface RuntimeProfileDefaults {\n readonly disableReferrerDetection: boolean;\n readonly eventSourcePolicy: EventSourcePolicy;\n readonly skipUnchanged: boolean;\n readonly sanitizerPolicy: 'compat' | 'strict';\n}\n\nexport const V2_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: true,\n previewSignals: Object.freeze(['query'] as const),\n});\n\nexport const V2_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: true,\n eventSourcePolicy: 'parent-or-opener',\n skipUnchanged: true,\n sanitizerPolicy: 'strict',\n});\n\n/** The 1.x table, spelled out so the profiles compare row by row. */\nexport const V1_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: false,\n previewSignals: Object.freeze(['query', 'fetch-dest', 'referer'] as const),\n});\n\nexport const V1_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: false,\n eventSourcePolicy: 'any',\n skipUnchanged: false,\n sanitizerPolicy: 'compat',\n});\n\n/** Only an explicit `'v1'` opts out; everything else gets the hardened rows. */\nexport function adapterDefaultsFor(profile: DefaultsProfile | undefined): AdapterProfileDefaults {\n return profile === 'v1' ? V1_ADAPTER_DEFAULTS : V2_ADAPTER_DEFAULTS;\n}\n\nexport function runtimeDefaultsFor(profile: DefaultsProfile | undefined): RuntimeProfileDefaults {\n return profile === 'v1' ? V1_RUNTIME_DEFAULTS : V2_RUNTIME_DEFAULTS;\n}\n","/**\n * `pll doctor --v2`: read the served inline configuration and report each\n * runtime row still at its 1.x value (ADR 0007).\n *\n * An empty slot means whatever the generation that wrote the script meant by\n * it, and that is exactly what changed between 1.x and 2.0. So the script\n * names the defaults it was resolved against, in its last slot, and this reads\n * the answer instead of guessing it. A script without the marker predates it —\n * 1.x or 2.0.0-beta.0 — and is read as 1.x, with a line that says so.\n */\nimport { INLINE_CONFIG_KEYS } from '@/types/inline-config';\nimport {\n V1_RUNTIME_DEFAULTS,\n V2_RUNTIME_DEFAULTS,\n type RuntimeProfileDefaults,\n} from '@/types/defaults-profile';\nimport type { DoctorFinding, DoctorProbe } from './types';\n\nconst CONFIG_MARKER = 'var __LIVE_PREVIEW_CONFIG__=';\nconst DEFAULTS_SLOT = INLINE_CONFIG_KEYS.indexOf('defaults');\n\n/** A runtime row of the readiness table, as a finding words it. */\ninterface ReadinessRow {\n readonly key: keyof RuntimeProfileDefaults;\n readonly title: string;\n /** What the 1.x value does. */\n readonly effect: string;\n /** What has to hold before the row can take its 2.0 value. */\n readonly condition: string;\n}\n\nconst ROWS: readonly ReadinessRow[] = [\n {\n key: 'disableReferrerDetection',\n title: 'Referrer trust is still on',\n effect: 'the runtime accepts the admin referer as a preview signal.',\n condition: 'no preview flow relies on the admin referer alone',\n },\n {\n key: 'eventSourcePolicy',\n title: 'Messages are accepted from any window',\n effect: 'any window that passes the origin check may post updates.',\n condition: 'no window but the parent or opener posts updates',\n },\n {\n key: 'sanitizerPolicy',\n title: 'Sanitizer is in compat mode',\n effect: 'id and every data-* pass.',\n condition: 'rich text no longer relies on `id` or `data-*`',\n },\n {\n key: 'skipUnchanged',\n title: 'Unchanged bindings are re-applied every message',\n effect: 'every binding is written again on every message.',\n condition: 'no renderer relies on running again for a value that did not change',\n },\n];\n\n/** Where a row's value came from, which decides what the reader can change. */\ntype Origin = 'profile' | 'explicit' | 'unmarked';\n\nconst ORIGIN_DETAIL: Readonly<Record<Origin, string>> = {\n profile: \"The script was generated with `defaults: 'v1'`.\",\n explicit: 'The script sets it explicitly.',\n unmarked: 'The script names no defaults, so its empty slot is read as the 1.x value.',\n};\n\nconst UNREADABLE: DoctorFinding = {\n code: 'LP0709',\n level: 'info',\n title: 'Could not read the inline configuration for a v2 readiness check',\n detail: 'The preview response carried no readable `__LIVE_PREVIEW_CONFIG__` inline script.',\n remedy:\n 'Run this against a page with the inline runtime (not loader mode without a preview context). ' +\n 'A preview behind authorizePreview serves it only to a request with credentials: pass them with --header.',\n};\n\nconst UNMARKED: DoctorFinding = {\n code: 'LP0709',\n level: 'info',\n title: 'The inline configuration does not say which defaults it was generated against',\n detail:\n 'Scripts carry a `defaults` marker from 2.0.0-rc.1 on; this one has none, so a 1.x or 2.0.0-beta.0 generator wrote it. An empty slot is read as its 1.x value, which is what a 1.x runtime runs.',\n remedy:\n 'On 1.x the warnings stand as written. On 2.0.0-beta.0 an empty slot already runs its 2.0 value, so a warning about one does not apply there; upgrade and run `pll doctor --v2` again to read the marker.',\n};\n\n/**\n * The array literal after the marker, read as JSON. The generator writes `,,`\n * for unset slots, which JSON cannot express, so elisions outside strings\n * become `null`. Never evaluated: a page controls this text.\n */\nexport function readInlineConfig(body: string): readonly unknown[] | undefined {\n const start = body.indexOf(CONFIG_MARKER);\n if (start === -1) return undefined;\n const from = start + CONFIG_MARKER.length;\n if (body[from] !== '[') return undefined;\n let depth = 0;\n let inString = false;\n let previous = '';\n let json = '';\n for (let index = from; index < body.length; index += 1) {\n const char = body[index] ?? '';\n if (inString) {\n json += char;\n if (char === '\\\\') {\n json += body[index + 1] ?? '';\n index += 1;\n } else if (char === '\"') {\n inString = false;\n // A closed string is a value: without this, the next `,` reads as an elision.\n previous = '\"';\n }\n continue;\n }\n if (char === '\"') {\n inString = true;\n json += char;\n continue;\n }\n if (/\\s/u.test(char)) continue;\n const elision =\n (char === ',' && (previous === ',' || previous === '[')) ||\n (char === ']' && previous === ',');\n if (elision) json += 'null';\n json += char;\n previous = char;\n if (char === '[') depth += 1;\n if (char === ']') {\n depth -= 1;\n if (depth === 0) break;\n }\n }\n if (depth !== 0) return undefined;\n try {\n const value: unknown = JSON.parse(json);\n return Array.isArray(value) ? (value as readonly unknown[]) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** `'compat'` rather than `\"compat\"`: remedies are read as source code. */\nfunction literal(value: unknown): string {\n return typeof value === 'string' ? `'${value}'` : JSON.stringify(value);\n}\n\nfunction remedyFor(origin: Origin, row: ReadinessRow, value: unknown): string {\n const wanted = `\\`${row.key}: ${literal(V2_RUNTIME_DEFAULTS[row.key])}\\``;\n switch (origin) {\n case 'profile':\n return `Set ${wanted} or drop \\`defaults: 'v1'\\` once ${row.condition}.`;\n case 'explicit':\n return `Drop the explicit \\`${row.key}: ${literal(value)}\\` once ${row.condition}; 2.0 defaults to ${wanted}.`;\n case 'unmarked':\n // 1.8.1 has no `defaults` option and three of the four rows are not\n // inline options there, so the way out is the upgrade itself.\n return `Upgrading to 2.0 sets ${wanted}; check first that ${row.condition}.`;\n }\n}\n\nfunction gap(row: ReadinessRow, value: unknown, origin: Origin): DoctorFinding {\n return {\n code: 'LP0709',\n level: 'warning',\n title: row.title,\n detail: `${row.key} is ${literal(value)}: ${row.effect} ${ORIGIN_DETAIL[origin]}`,\n remedy: remedyFor(origin, row, value),\n };\n}\n\nfunction unknownGeneration(marker: unknown): DoctorFinding {\n return {\n code: 'LP0709',\n level: 'info',\n title: 'The inline configuration names defaults this doctor does not know',\n detail: `Its \\`defaults\\` marker is ${JSON.stringify(marker)}; this version reads 'v1' and 'v2', so no row was judged.`,\n remedy: 'Run the `pll doctor` of the package version that generated the page.',\n };\n}\n\n/**\n * One `LP0709` finding per runtime row not yet at its 2.0 value. An empty slot\n * has the value of the generation the script names, and the 1.x value when it\n * names none; a generation this version does not know is not judged at all.\n * @internal\n */\nexport function analyzeV2Readiness(probe: DoctorProbe): readonly DoctorFinding[] {\n const config = readInlineConfig(probe.previewResponse.body);\n if (config === undefined) return [UNREADABLE];\n const marker = config[DEFAULTS_SLOT] ?? undefined;\n if (marker !== undefined && marker !== 'v1' && marker !== 'v2') {\n return [unknownGeneration(marker)];\n }\n const generation = marker;\n const fallback = generation === 'v2' ? V2_RUNTIME_DEFAULTS : V1_RUNTIME_DEFAULTS;\n const findings = ROWS.flatMap((row) => {\n const slot = config[INLINE_CONFIG_KEYS.indexOf(row.key)] ?? undefined;\n const value = slot ?? fallback[row.key];\n if (value === V2_RUNTIME_DEFAULTS[row.key]) return [];\n const origin: Origin =\n generation === 'v1' ? 'profile' : slot === undefined ? 'unmarked' : 'explicit';\n return [gap(row, value, origin)];\n });\n return generation === undefined ? [...findings, UNMARKED] : findings;\n}\n","/**\n * The `pll doctor` audit: judge what a deployment serves from two fetches of\n * one URL, as a visitor and as the admin's iframe. Pure — the caller fetches.\n * Markup is read with regular expressions, which is enough to count\n * attributes and find the runtime marker; findings say what was observed.\n */\nimport { DIAGNOSTIC_CODES } from '../core/diagnostic-codes';\nimport { frameAncestorsAdmits, frameAncestorsOf } from './csp';\nimport { analyzeV2Readiness } from './readiness';\nimport type {\n DoctorContext,\n DoctorFinding,\n DoctorProbe,\n DoctorReport,\n DoctorResponse,\n} from './types';\n\n/** Survives minification; the banner comment does not. */\nconst RUNTIME_MARKER = '__LIVE_PREVIEW_CONFIG__';\nconst BINDING_ATTRIBUTE = /\\bdata-payload-field\\s*=/gu;\nconst OWNER_ATTRIBUTE = /\\bdata-payload-owner\\s*=/gu;\n/** Mirrors the scheduler default; the audit must not import the runtime. */\nconst DEFAULT_VISIBILITY_GATE_THRESHOLD = 50;\nconst LEVEL_ORDER = { error: 0, warning: 1, info: 2 } as const;\n// An end tag may carry junk before its `>`; browsers still close on it, so the\n// pattern must too, or a `</script foo>` would leave the script body counted.\nconst NON_MARKUP =\n /<script\\b[^>]*>[\\s\\S]*?<\\/script\\b[^>]*>|<style\\b[^>]*>[\\s\\S]*?<\\/style\\b[^>]*>|<!--[\\s\\S]*?-->/giu;\n\n/**\n * The runtime's own source spells `data-payload-field=` in a message, so\n * scripts must not be counted. This is a counter's view of the page, not a\n * sanitiser — nothing here is rendered — but it strips to a fixed point all\n * the same, so a block that only appears once its neighbour is gone is still\n * removed rather than counted.\n */\nfunction visibleMarkup(body: string): string {\n let markup = body;\n for (;;) {\n const stripped = markup.replace(NON_MARKUP, '');\n if (stripped === markup) return markup;\n markup = stripped;\n }\n}\n\nfunction count(haystack: string, pattern: RegExp): number {\n return haystack.match(pattern)?.length ?? 0;\n}\n\n/** Bindings before the first owner marker are certainly unowned; nesting is not modelled, so this under-reports. */\nfunction unownedBindingsBeforeFirstOwner(markup: string): number {\n const firstOwner = markup.search(/\\bdata-payload-owner\\s*=/u);\n return firstOwner === -1 ? 0 : count(markup.slice(0, firstOwner), BINDING_ATTRIBUTE);\n}\n\nfunction tryUrl(value: string | undefined): URL | undefined {\n if (value === undefined) return undefined;\n try {\n return new URL(value);\n } catch {\n return undefined;\n }\n}\n\n/** Why the preview response cannot be audited as a page; the public one may legitimately be gated. */\nfunction describeNonPage(preview: DoctorResponse): DoctorFinding | undefined {\n if (preview.status >= 300 && preview.status <= 399) {\n const location = preview.headers['location'];\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request was redirected (${String(preview.status)})${location === undefined ? '' : ` to ${location}`}`,\n detail:\n 'The audit does not follow redirects: the page at the end of one is a different ' +\n 'resource, usually a login or a canonical host, and judging it would say nothing ' +\n 'about this URL.',\n remedy:\n 'The request carried the intent parameter (?preview=true, or the --param name), the ' +\n \"way the admin's iframe loads the page, so a rule that redirects on that query redirects \" +\n 'the iframe too. A redirect to a login means the route needs authentication that a ' +\n \"plain probe cannot supply: pass an editor's credentials with --header. Probe the final \" +\n 'URL directly only when the redirect has nothing to do with either.',\n };\n }\n if (preview.status < 200 || preview.status > 299) {\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request returned ${String(preview.status)}, not a page`,\n detail:\n 'Nothing below this can be judged: a status outside 2xx means the body is an ' +\n 'error page or empty.',\n remedy: 'Check the URL.',\n };\n }\n if (preview.body.trim() === '') {\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request returned ${String(preview.status)} with an empty body`,\n detail:\n 'A 2xx status with nothing in it — 204 and 205 are defined that way — is not a page, ' +\n 'so its missing runtime and missing bindings say nothing.',\n remedy: 'Point the audit at a route that renders a document.',\n };\n }\n const contentType = preview.headers['content-type'];\n if (contentType !== undefined && !contentType.toLowerCase().includes('html')) {\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request returned ${contentType}, not HTML`,\n detail:\n 'The audit reads a rendered page. A non-HTML response has no runtime and no ' +\n 'bindings by definition, so reporting their absence would say nothing.',\n remedy: 'Point the audit at a page route rather than an API or an asset.',\n };\n }\n return undefined;\n}\n\nfunction framingFindings(\n preview: DoctorResponse,\n runtimeInPreview: boolean,\n context: DoctorContext,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n const page = tryUrl(context.url);\n const admin = tryUrl(context.adminOrigin);\n const sameOrigin = admin !== undefined && page?.origin === admin.origin;\n const frameAncestors = frameAncestorsOf(preview.headers['content-security-policy']);\n if (runtimeInPreview && frameAncestors === undefined) {\n findings.push({\n code: 'LP0702',\n level: 'warning',\n title: 'Preview response declares no frame-ancestors',\n detail:\n 'The runtime is injected but the response carries no frame-ancestors directive, ' +\n 'so nothing states which origins may embed this page.',\n remedy:\n 'Let the adapter manage CSP, or set frame-ancestors yourself to the admin origin. ' +\n 'Without it you are relying on the absence of a policy.',\n });\n } else if (frameAncestors !== undefined && context.adminOrigin !== undefined) {\n const admitted =\n admin !== undefined &&\n page !== undefined &&\n frameAncestorsAdmits(frameAncestors, admin, page);\n if (!admitted) {\n findings.push({\n code: 'LP0702',\n level: 'error',\n title: 'frame-ancestors does not admit the admin origin',\n detail:\n admin === undefined\n ? `\"${context.adminOrigin}\" is not an absolute URL, so no source expression can admit it.`\n : `Served: \"${frameAncestors}\". Expected it to allow ${admin.origin}.`,\n remedy:\n 'Add the admin origin to allowedOrigins so the adapter merges it into ' +\n 'frame-ancestors, or add it to your own policy.',\n });\n }\n }\n const frameOptions = preview.headers['x-frame-options'];\n const blocks =\n frameOptions !== undefined &&\n (/deny/iu.test(frameOptions) || (/sameorigin/iu.test(frameOptions) && !sameOrigin));\n if (blocks) {\n // `SAMEORIGIN` refuses a frame from *another* origin, so it is a verdict\n // about this preview only once the admin origin is known. Without --admin\n // the audit says what it saw and names the condition instead of asserting a\n // block it cannot have established: where the admin and the site share an\n // origin, the preview runs. `DENY` needs no origin to be a verdict.\n const judged = admin !== undefined || /deny/iu.test(frameOptions);\n findings.push(\n judged\n ? {\n code: 'LP0703',\n level: 'error',\n title: `X-Frame-Options: ${frameOptions} blocks the preview iframe`,\n detail:\n 'This header is older than CSP and browsers honour it independently. No ' +\n 'frame-ancestors directive can override it.',\n remedy:\n 'Remove X-Frame-Options for preview responses. It is usually set by a proxy ' +\n 'or a security middleware rather than by the app.',\n }\n : {\n code: 'LP0703',\n level: 'warning',\n title: `X-Frame-Options: ${frameOptions} blocks every frame from another origin`,\n detail:\n 'This header is older than CSP and browsers honour it independently, and no ' +\n 'frame-ancestors directive can override it. SAMEORIGIN refuses a frame from ' +\n 'another origin only, and no admin origin was given: whether it blocks this ' +\n 'preview depends on where the admin is served, which this probe cannot see.',\n remedy:\n 'Re-run with --admin <origin> to have it judged. If the admin is on another ' +\n 'origin, remove X-Frame-Options for preview responses; a proxy or a security ' +\n 'middleware usually sets it.',\n },\n );\n }\n return findings;\n}\n\nfunction bindingFindings(\n previewMarkup: string,\n publicMarkup: string,\n runtime: boolean,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n const previewBindings = count(previewMarkup, BINDING_ATTRIBUTE);\n const publicBindings = count(publicMarkup, BINDING_ATTRIBUTE);\n const owners = count(previewMarkup, OWNER_ATTRIBUTE);\n if (publicBindings > 0) {\n findings.push({\n code: 'LP0704',\n level: 'warning',\n title: `${String(publicBindings)} binding attribute(s) served to anonymous visitors`,\n detail:\n 'A request with no preview intent received data-payload-field attributes. These ' +\n 'disclose the CMS field taxonomy, and any CSS keyed on them changes public layout ' +\n 'the moment emission is gated.',\n remedy:\n 'Gate binding emission on an authorized preview context — see ' +\n 'createPreviewBindings(), whose suppressed form emits nothing at all.',\n });\n }\n if (previewBindings > DEFAULT_VISIBILITY_GATE_THRESHOLD) {\n findings.push({\n code: 'LP0705',\n level: 'warning',\n title: `${String(previewBindings)} bindings exceed the default visibility gate`,\n detail:\n `Above visibilityGateThreshold (${String(DEFAULT_VISIBILITY_GATE_THRESHOLD)}) the ` +\n 'scheduler stops writing offscreen elements and buffers them until they scroll into ' +\n 'view. On a page nobody scrolls, that is never.',\n remedy:\n 'Raise visibilityGateThreshold if the whole page must stay live, or confirm that ' +\n 'deferring below the fold is acceptable here.',\n });\n }\n if (runtime && previewBindings === 0) {\n findings.push({\n code: 'LP0707',\n level: 'error',\n title: 'Preview response carries no bindings',\n detail:\n 'The runtime is present but there is not one data-payload-field element for it to ' +\n 'write into, so no edit can ever be visible on this page.',\n remedy:\n 'Add binding attributes to the markup. pll-codegen --inventory lists every field ' +\n 'the schema makes addressable.',\n });\n }\n const unowned = unownedBindingsBeforeFirstOwner(previewMarkup);\n if (owners > 0 && unowned > 0) {\n findings.push({\n code: 'LP0706',\n level: 'warning',\n title: `${String(unowned)} binding(s) outside every owner marker`,\n detail:\n `The page declares ${String(owners)} owner marker(s), so owner scoping is in use. ` +\n 'Bindings that belong to no owner receive nothing once scopeBindingsByOwner is on — ' +\n 'they fail closed.',\n remedy:\n 'Give every binding an owning ancestor, or leave scopeBindingsByOwner off until they ' +\n 'all have one. Counted before the first owner marker only, so the real number may be ' +\n 'higher.',\n });\n }\n return findings;\n}\n\n/** Audit a probed deployment. */\nexport function analyzeProbe(\n probe: DoctorProbe,\n context: DoctorContext & {\n readonly v2?: boolean;\n /** Whether the preview probe carried caller-supplied headers (`--header`). */\n readonly credentials?: boolean;\n },\n): DoctorReport {\n const { publicResponse: pub, previewResponse: preview } = probe;\n const notAPage = describeNonPage(preview);\n if (notAPage !== undefined) {\n return { url: context.url, findings: [notAPage], errors: 1, warnings: 0 };\n }\n const runtimeInPreview = preview.body.includes(RUNTIME_MARKER);\n const findings: DoctorFinding[] = [];\n if (!runtimeInPreview) {\n findings.push(\n context.credentials === true\n ? {\n code: 'LP0701',\n level: 'warning',\n title: 'No inline runtime in the preview response',\n detail:\n `The preview request returned ${String(preview.status)} without the inline ` +\n 'runtime, although it carried the headers passed with --header. Three readings: ' +\n 'those credentials were not accepted — expired, issued for another page, or not ' +\n 'what authorizePreview reads — an adapter that did not recognise the request as a ' +\n 'preview, or a consumer that starts LivePreviewClient itself.',\n remedy:\n 'Check that the credentials are current and are the ones authorizePreview reads; ' +\n 'if you use an adapter, check its inject mode and previewSignals. If you start the ' +\n 'client yourself, this line is expected.',\n }\n : {\n code: 'LP0701',\n level: 'warning',\n title: 'No inline runtime in the preview response',\n detail:\n `The preview request returned ${String(preview.status)} without the inline ` +\n 'runtime. Three readings, and this audit cannot tell them apart from the response ' +\n 'alone: a preview behind authorizePreview — the strict 2.0 default — which answers ' +\n 'a request without credentials exactly like this, an adapter that did not recognise ' +\n 'the request as a preview, or a consumer that starts LivePreviewClient itself.',\n remedy:\n \"To audit a gated preview, send what an editor's browser sends: \" +\n \"--header 'Cookie: payload-token=…' for a Payload session, or \" +\n \"--header 'x-preview-token: …' for a signed token. Otherwise check the adapter's \" +\n 'inject mode and previewSignals; if you start the client yourself, this line is ' +\n 'expected.',\n },\n );\n }\n findings.push(...framingFindings(preview, runtimeInPreview, context));\n findings.push(\n ...bindingFindings(visibleMarkup(preview.body), visibleMarkup(pub.body), runtimeInPreview),\n );\n if (pub.body.includes(RUNTIME_MARKER)) {\n findings.push({\n code: DIAGNOSTIC_CODES.RuntimeOnPublicPage,\n level: 'info',\n title: 'Runtime is also served to anonymous visitors',\n detail:\n 'A request with no preview intent received the inline runtime. That is correct for ' +\n \"inject: 'always' and unintended for 'preview-only'.\",\n remedy: '',\n });\n }\n if (context.v2 === true) findings.push(...analyzeV2Readiness(probe));\n findings.sort((a, b) => LEVEL_ORDER[a.level] - LEVEL_ORDER[b.level]);\n return {\n url: context.url,\n findings,\n errors: findings.filter((finding) => finding.level === 'error').length,\n warnings: findings.filter((finding) => finding.level === 'warning').length,\n };\n}\n","/**\n * Fetching for `pll doctor`: the two probes, and the default fetch that talks\n * to a real server. Not in the barrel so it stays in the coverage report.\n */\nimport { analyzeProbe } from './analyze';\nimport type { DoctorReport, DoctorResponse } from './types';\n\n/** Injectable so tests can drive the audit without a server. */\nexport type DoctorFetch = (\n url: string,\n init: { readonly headers: Readonly<Record<string, string>> },\n) => Promise<DoctorResponse>;\n\nexport interface RunDoctorOptions {\n readonly url: string;\n /** Admin origin the preview is meant to be embedded from, when known. */\n readonly adminOrigin?: string | undefined;\n /** Defaults to a fetch built on `globalThis.fetch`. */\n readonly fetchImpl?: DoctorFetch | undefined;\n /** Also check the served page against the 2.0 readiness table. */\n readonly v2?: boolean;\n /**\n * Headers sent with the preview probe only, never with the visitor probe: the\n * credentials a preview behind `authorizePreview` needs, such as a Payload\n * session `Cookie` or an `x-preview-token`. Without them a gated page answers\n * the audit the way it answers any stranger. Their values never reach the report.\n */\n readonly previewHeaders?: Readonly<Record<string, string>> | undefined;\n /**\n * The query parameters the deployment reads as preview intent, when its\n * adapter sets `previewQueryParams`; the same list, since that option replaces\n * the default `preview`, `draft` and `livePreview`. The first one is what the\n * preview probe appends as `=true`; none of them reaches the visitor probe.\n */\n readonly previewQueryParams?: readonly string[] | undefined;\n}\n\n/**\n * The query parameters an adapter reads as preview intent by default; the same\n * list as `DEFAULT_QUERY_PARAMS` in adapters/shared/preview-request.ts, which\n * `previewQueryParams` replaces rather than extends.\n */\nconst DEFAULT_INTENT_PARAMS: readonly string[] = ['preview', 'draft', 'livePreview'];\n\nfunction isIntentValue(value: string): boolean {\n return value === 'true' || value === '1';\n}\n\n/** `key=value` and `#fragment` split off a URL, with the query kept as the caller spelled it. */\nfunction splitUrl(url: string): {\n readonly base: string;\n readonly parts: string[];\n readonly hash: string;\n} {\n const hashAt = url.indexOf('#');\n const hash = hashAt === -1 ? '' : url.slice(hashAt);\n const beforeHash = hashAt === -1 ? url : url.slice(0, hashAt);\n const queryAt = beforeHash.indexOf('?');\n if (queryAt === -1) return { base: beforeHash, parts: [], hash };\n return {\n base: beforeHash.slice(0, queryAt),\n parts: beforeHash.slice(queryAt + 1).split('&'),\n hash,\n };\n}\n\nfunction decodePart(part: string): readonly [string, string] {\n const at = part.indexOf('=');\n const decode = (text: string): string => {\n try {\n return decodeURIComponent(text.replace(/\\+/gu, ' '));\n } catch {\n return text;\n }\n };\n return at === -1 ? [decode(part), ''] : [decode(part.slice(0, at)), decode(part.slice(at + 1))];\n}\n\n/**\n * The page a visitor requests: the intent parameters removed, the rest of the\n * query byte for byte as given. A query is never re-serialised — `URLSearchParams`\n * would turn `%20` into `+` and add `=` to a bare key, and a page whose query is\n * signed by an edge token would answer a different request than a visitor makes.\n */\nfunction visitorUrl(url: string, params: readonly string[]): string {\n const { base, parts, hash } = splitUrl(url);\n const kept = parts.filter((part) => !params.includes(decodePart(part)[0]));\n if (kept.length === parts.length) return url;\n return `${base}${kept.length === 0 ? '' : `?${kept.join('&')}`}${hash}`;\n}\n\n/**\n * The page the admin's iframe loads. A 2.0 adapter counts only the query as\n * intent (`previewSignals: ['query']`), and `buildLivePreviewUrl` writes\n * `preview=true`, so the first intent parameter is appended as `=true` unless the\n * URL already names one with a value that counts.\n */\nfunction previewUrl(url: string, params: readonly string[]): string {\n const { base, parts, hash } = splitUrl(url);\n const carries = parts.some((part) => {\n const [key, value] = decodePart(part);\n return params.includes(key) && isIntentValue(value);\n });\n if (carries) return url;\n const query = parts.join('&');\n const joiner = query === '' ? '?' : query.endsWith('&') ? '' : '&';\n const intent = `${encodeURIComponent(params[0] ?? 'preview')}=true`;\n return `${base}${parts.length === 0 ? '?' : `?${query}${joiner}`}${intent}${hash}`;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 15_000;\nexport const MAX_BODY_BYTES = 10 * 1024 * 1024;\n\nexport interface DefaultFetchOptions {\n readonly fetchFn?: typeof fetch;\n readonly timeoutMs?: number;\n readonly maxBodyBytes?: number;\n}\n\n/** Header names lowercased; every check downstream reads a lowercase key. @internal */\nexport function lowercaseHeaders(headers: Headers): Record<string, string> {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n}\n\n/** The error's message plus its cause's, which is where undici puts `self-signed certificate` and friends. */\nexport function describeFailure(error: unknown): string {\n if (!(error instanceof Error)) return String(error);\n const cause = error.cause;\n if (cause instanceof Error && cause.message !== '' && !error.message.includes(cause.message)) {\n return `${error.message} (${cause.message})`;\n }\n return error.message;\n}\n\nasync function readBody(response: Response, limit: number): Promise<string> {\n const reader = response.body?.getReader();\n if (reader === undefined) return response.text();\n const decoder = new TextDecoder();\n let received = 0;\n let text = '';\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n received += value.byteLength;\n if (received > limit) {\n await reader.cancel();\n throw new Error(\n `the response body exceeds ${String(limit)} bytes, which is not a page the audit can judge`,\n );\n }\n text += decoder.decode(value, { stream: true });\n }\n return text + decoder.decode();\n}\n\n/** Redirects are reported, not followed; a hanging origin is abandoned; a runaway body is refused. */\nexport function createDefaultFetch(options: DefaultFetchOptions = {}): DoctorFetch {\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const limit = options.maxBodyBytes ?? MAX_BODY_BYTES;\n return async (url, init) => {\n const fetchFn = options.fetchFn ?? globalThis.fetch;\n let response: Response;\n try {\n response = await fetchFn(url, {\n headers: init.headers,\n redirect: 'manual',\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n throw new Error(`no response within ${String(timeoutMs / 1000)} s`, { cause: error });\n }\n throw error;\n }\n return {\n status: response.status,\n headers: lowercaseHeaders(response.headers),\n body: await readBody(response, limit),\n };\n };\n}\n\n/** The referer the admin's iframe would send: the origin (or the given admin path) with one slash. */\nexport function previewReferer(adminOrigin: string): string {\n try {\n return new URL(adminOrigin).href;\n } catch {\n return `${adminOrigin.replace(/\\/+$/u, '')}/`;\n }\n}\n\n/**\n * The caller's headers without the ones the probe sets itself. Header names are\n * case-insensitive, and `fetch` combines two spellings of one name into one\n * comma-joined value, so a caller's `sec-fetch-dest` would otherwise turn the\n * probe's `iframe` into `document, iframe`. The probe's own headers win.\n */\nfunction callerHeaders(\n headers: Readonly<Record<string, string>> | undefined,\n own: Readonly<Record<string, string>>,\n): Record<string, string> {\n const taken = new Set(Object.keys(own).map((name) => name.toLowerCase()));\n return Object.fromEntries(\n Object.entries(headers ?? {}).filter(([name]) => !taken.has(name.toLowerCase())),\n );\n}\n\n/** Fetch the URL twice — as a visitor and as the admin's iframe — and audit the difference. */\nexport async function runDoctor(options: RunDoctorOptions): Promise<DoctorReport> {\n const fetchImpl = options.fetchImpl ?? createDefaultFetch();\n const params =\n options.previewQueryParams === undefined || options.previewQueryParams.length === 0\n ? DEFAULT_INTENT_PARAMS\n : options.previewQueryParams;\n // No referer, no intent parameter and no credentials on the visitor probe:\n // each of them is a preview signal or a way past one.\n const publicResponse = await fetchImpl(visitorUrl(options.url, params), {\n headers: {\n Accept: 'text/html',\n 'Sec-Fetch-Dest': 'document',\n 'Sec-Fetch-Mode': 'navigate',\n },\n });\n const probeHeaders: Record<string, string> = {\n Accept: 'text/html',\n 'Sec-Fetch-Dest': 'iframe',\n 'Sec-Fetch-Mode': 'navigate',\n ...(options.adminOrigin === undefined ? {} : { Referer: previewReferer(options.adminOrigin) }),\n };\n const sent = callerHeaders(options.previewHeaders, probeHeaders);\n const previewResponse = await fetchImpl(previewUrl(options.url, params), {\n headers: { ...sent, ...probeHeaders },\n });\n return analyzeProbe(\n { publicResponse, previewResponse },\n {\n url: options.url,\n adminOrigin: options.adminOrigin,\n ...(options.v2 === true ? { v2: true } : {}),\n ...(Object.keys(sent).length > 0 ? { credentials: true } : {}),\n },\n );\n}\n","#!/usr/bin/env node\n/**\n * The `pll` binary: `pll doctor <url>` here, `pll migrate <path>` in\n * migrate/cli. Doctor exit codes: 0 no error-level findings, 1 usage error or\n * the URL could not be fetched, 2 at least one error-level finding.\n */\nimport { runMigrateCommand } from '../migrate/cli';\nimport { formatReport } from './format';\nimport { describeFailure, runDoctor, type DoctorFetch } from './probe';\n\ninterface ParsedArgs {\n url: string | undefined;\n adminOrigin: string | undefined;\n json: boolean;\n v2: boolean;\n showHelp: boolean;\n unknown: string[];\n /** Headers for the preview probe, from every `--header`/`-H`. */\n headers: Record<string, string>;\n /** The first `--header` or `--param` that could not be read, as the message to print. */\n usageError: string | undefined;\n /** Query parameter names from every `--param`. */\n params: string[];\n}\n\n/** A query parameter name: no separator, no space, and not the next option. */\nconst PARAM_NAME = /^[^\\s&=#?-][^\\s&=#]*$/u;\n\n/** An HTTP field name (RFC 9110 token), a colon, then the value. */\nconst HEADER_LINE = /^([!#$%&'*+.^_`|~0-9A-Za-z-]+):[ \\t]*(.*)$/u;\n\nfunction addHeader(parsed: ParsedArgs, line: string | undefined): void {\n // A missing value would otherwise read the next argument: `https://example.com/`\n // matches as name `https`, and `--v2` as no header at all.\n const match =\n line === undefined || line.startsWith('-') || isAbsoluteUrl(line)\n ? null\n : HEADER_LINE.exec(line);\n const name = match?.[1];\n const value = match?.[2];\n if (name === undefined || value === undefined) {\n // The value is not echoed: a mistyped header can still hold half a token.\n parsed.usageError ??=\n 'pll doctor: --header takes \"Name: value\", such as --header \"x-preview-token: …\"';\n return;\n }\n // Header names are case-insensitive; a second spelling would be joined onto\n // the first by fetch, and a repeat would silently replace it.\n if (Object.keys(parsed.headers).some((given) => given.toLowerCase() === name.toLowerCase())) {\n parsed.usageError ??= `pll doctor: --header \"${name}\" is given twice; join the values into one header`;\n return;\n }\n parsed.headers[name] = value;\n}\n\nfunction addParam(parsed: ParsedArgs, name: string | undefined): void {\n if (name === undefined || !PARAM_NAME.test(name)) {\n parsed.usageError ??= 'pll doctor: --param takes a query parameter name, such as --param draft';\n return;\n }\n parsed.params.push(name);\n}\n\nfunction parseArgs(argv: readonly string[]): ParsedArgs {\n const parsed: ParsedArgs = {\n url: undefined,\n adminOrigin: undefined,\n json: false,\n v2: false,\n showHelp: false,\n unknown: [],\n headers: {},\n usageError: undefined,\n params: [],\n };\n for (let i = 0; i < argv.length; i += 1) {\n const token = argv[i];\n if (token === undefined) continue;\n if (token === '-h' || token === '--help') parsed.showHelp = true;\n else if (token === '--json') parsed.json = true;\n else if (token === '--v2') parsed.v2 = true;\n else if (token === '--admin' || token === '-a') {\n parsed.adminOrigin = argv[i + 1];\n i += 1;\n } else if (token.startsWith('--admin=')) parsed.adminOrigin = token.slice('--admin='.length);\n else if (token === '--header' || token === '-H') {\n addHeader(parsed, argv[i + 1]);\n i += 1;\n } else if (token.startsWith('--header=')) addHeader(parsed, token.slice('--header='.length));\n else if (token === '--param') {\n addParam(parsed, argv[i + 1]);\n i += 1;\n } else if (token.startsWith('--param=')) addParam(parsed, token.slice('--param='.length));\n else if (token.startsWith('-')) parsed.unknown.push(token);\n else parsed.url ??= token;\n }\n return parsed;\n}\n\nconst HELP_TEXT = `pll doctor — audit what a live-preview deployment actually serves\n\nUsage:\n pll doctor <url> [--admin <origin>] [--header <name: value>]... [--param <name>]... [--json] [--v2]\n pll migrate <path> [--write] [--only <id,id>]\n\nThe URL is fetched twice: once as an ordinary visitor, without any intent\nparameter, and once the way the Payload admin's iframe loads it, with\n?preview=true and the iframe's headers.\nMost findings come from the difference between the two responses. Redirects\nare reported, not followed.\n\nOptions:\n -a, --admin <origin> Admin origin the preview is embedded from. Enables the\n frame-ancestors check to verify the origin is admitted,\n not merely that a policy exists.\n -H, --header <h> A header for the preview request only, as \"Name: value\";\n repeat it for more. A preview behind authorizePreview\n needs an editor's credentials: a Payload session Cookie\n or an x-preview-token. The visitor request stays\n anonymous and values are never printed, but a shell\n keeps them in its history, so prefer a short-lived token.\n --param <name> A query parameter the deployment reads as preview intent,\n for an adapter whose previewQueryParams replaces the\n default preview, draft and livePreview; repeat it for\n more. The first one is what the preview request carries\n as <name>=true; none of them reaches the visitor request.\n --json Emit the report as JSON instead of text\n --v2 Also check the page against the 2.0 readiness table\n -h, --help Show this help\n\nExit codes:\n 0 no error-level findings\n 1 usage error, or the URL could not be fetched\n 2 at least one error-level finding\n\nExamples:\n pll doctor https://example.com/\n pll doctor https://example.com/blog/hello --admin https://cms.example.com\n pll doctor https://example.com/ --header \"x-preview-token: $PREVIEW_TOKEN\" --v2\n`;\n\nfunction isAbsoluteUrl(value: string): boolean {\n try {\n return new URL(value).origin !== 'null';\n } catch {\n return false;\n }\n}\n\n/** @param fetchImpl Seam for tests; the bin shim never passes it. */\nexport async function run(argv: readonly string[], fetchImpl?: DoctorFetch): Promise<number> {\n const [subcommand, ...rest] = argv;\n if (subcommand === undefined || subcommand === '-h' || subcommand === '--help') {\n process.stdout.write(HELP_TEXT);\n return subcommand === undefined ? 1 : 0;\n }\n if (subcommand === 'migrate') return runMigrateCommand(rest);\n if (subcommand !== 'doctor') {\n process.stderr.write(`pll: unknown command \"${subcommand}\". Try \\`pll --help\\`.\\n`);\n return 1;\n }\n const args = parseArgs(rest);\n if (args.showHelp) {\n process.stdout.write(HELP_TEXT);\n return 0;\n }\n if (args.unknown.length > 0) {\n process.stderr.write(`pll doctor: unknown option ${args.unknown.join(', ')}\\n`);\n return 1;\n }\n if (args.url === undefined) {\n process.stderr.write('pll doctor: a URL is required. Try `pll doctor --help`.\\n');\n return 1;\n }\n if (args.usageError !== undefined) {\n process.stderr.write(`${args.usageError}\\n`);\n return 1;\n }\n if (args.adminOrigin !== undefined && !isAbsoluteUrl(args.adminOrigin)) {\n process.stderr.write(\n `pll doctor: --admin must be an absolute URL such as https://cms.example.com (got \"${args.adminOrigin}\")\\n`,\n );\n return 1;\n }\n let report;\n try {\n report = await runDoctor({\n url: args.url,\n ...(args.adminOrigin !== undefined ? { adminOrigin: args.adminOrigin } : {}),\n ...(args.v2 ? { v2: true } : {}),\n ...(Object.keys(args.headers).length > 0 ? { previewHeaders: args.headers } : {}),\n ...(args.params.length > 0 ? { previewQueryParams: args.params } : {}),\n ...(fetchImpl !== undefined ? { fetchImpl } : {}),\n });\n } catch (error) {\n const message = describeFailure(error);\n if (args.json) {\n process.stdout.write(`${JSON.stringify({ url: args.url, error: message }, undefined, 2)}\\n`);\n } else {\n process.stderr.write(`pll doctor: could not probe ${args.url}: ${message}\\n`);\n }\n return 1;\n }\n process.stdout.write(\n args.json ? `${JSON.stringify(report, undefined, 2)}\\n` : formatReport(report),\n );\n return report.errors > 0 ? 2 : 0;\n}\n\n/** Matches the entry's basename only, so importing this module from a path containing `pll` never runs it. */\nexport function isCliInvocation(argv: readonly (string | undefined)[] = process.argv): boolean {\n if (typeof process === 'undefined') return false;\n const entry = argv[1];\n if (entry === undefined || entry === '') return false;\n const name = entry.split(/[\\\\/]/u).pop() ?? '';\n return name === 'pll' || name === 'pll.cmd' || name.startsWith('doctor-cli');\n}\n\nif (isCliInvocation()) {\n void run(process.argv.slice(2)).then((code) => {\n process.exit(code);\n });\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"doctor-cli.js","names":["tsMorph","project","PACKAGE_NAME","loadTsMorph","createRequire","url","error","Error","cause","parseScript","text","kind","morph","Project","useInMemoryFileSystem","skipLoadingLibFiles","skipFileDependencyResolution","compilerOptions","allowJs","noLib","createSourceFile","overwrite","isPackageSpecifier","specifier","startsWith","packageBindings","script","Node","SyntaxKind","out","declaration","getImportDeclarations","getModuleSpecifierValue","spec","getNamedImports","alias","getAliasNode","localNode","getNameNode","push","imported","getName","local","getText","importedNode","aliased","symbol","getSymbol","getDescendantsOfKind","VariableDeclaration","requiredSpecifier","getInitializer","pattern","isObjectBindingPattern","element","getElements","nameNode","isIdentifier","propertyName","getPropertyNameNode","literalName","initializer","call","isAwaitExpression","getExpression","isCallExpression","callee","getKind","ImportKeyword","argument","getArguments","isStringLiteral","getLiteralText","node","isNoSubstitutionTemplateLiteral","propertyKey","property","isSpreadAssignment","isComputedPropertyName","referencesTo","binding","target","compilerSymbol","checker","getProject","getTypeChecker","Identifier","isInside","parent","getParent","isShorthandPropertyAssignment","getShorthandAssignmentValueSymbol","isExportSpecifier","getLocalTargetSymbol","ancestor","getFirstAncestor","candidate","declaresName","name","except","bindsIdentifier","some","skip","isVariableDeclaration","isBindingElement","isFunctionDeclaration","isClassDeclaration","isParameterDeclaration","isEnumDeclaration","isImportSpecifier","isImportClause","getDefaultImport","isNamespaceImport","replaceNode","start","getStart","end","getEnd","applyTextEdits","edits","ordered","sort","left","right","output","floor","Number","POSITIVE_INFINITY","edit","slice","ID","SERVER_SPECIFIER","METHOD","fetchPreviewDocument","fetchPreviewGlobal","SERVER_OPTIONS","Set","DROPPED_OPTIONS","SHARED_READ_OPTIONS","READ_OPTIONS","conflict","line","reason","codemod","rewriteCall","options","server","read","dropped","keys","getProperties","key","add","has","accepted","unplaceable","filter","includes","typeArguments","getTypeArguments","map","generic","length","join","method","droppedNote","getStartLineNumber","notes","importLine","quote","names","moveFetchPreviewHelpers","id","summary","ledgerEntry","apply","bindings","conflicts","blocking","reference","isObjectLiteralExpression","rewritten","serverDeclaration","foreign","declarations","isImportDeclaration","serverImport","find","isTypeOnly","hasDefinePreview","serverLine","getModuleSpecifier","getQuoteKind","defaultImport","clauses","remaining","clause","typeOnly","kept","trailingNewline","getFullText","rewriteImports","plan","CALLEE","OLD_KEY","NEW_KEY","BY_HAND","renameAdminOriginsOption","properties","isPropertyAssignment","BOOLEAN_REFUSED","renameBindingsAuthorizedOption","value","isFalseLiteral","OLD_NAME","NEW_NAME","renameBinding","getParentOrThrow","renameIsPreviewRequest","notice","existing","isPropertyAccessExpression","memberAccesses","WHOLE_FILE","COMPONENT_EXTENSIONS","FRONTMATTER","SCRIPT_TAG","PACKAGE_REFERENCE","IMPLEMENTATIONS","CODEMODS","lineNumberAt","source","offset","index","lineEdits","before","after","firstLine","oldLines","split","newLines","prefix","suffix","oldMiddle","newMiddle","changed","Math","max","migrateSource","chosen","only","test","importsThisPackage","byCodemod","Map","cursor","block","fileName","extension","extname","toLowerCase","blocks","frontmatter","exec","indexOf","match","matchAll","body","trim","lastIndexOf","scriptBlocks","item","next","lines","get","set","count","SOURCE_EXTENSIONS","DECLARATION_FILE","SKIP_DIRECTORIES","isSourceFile","async","collectFiles","root","found","stat","isDirectory","walk","directory","entry","readdir","withFileTypes","path","relativeTo","file","rel","relative","describe","String","LEVEL_LABEL","warning","info","DIAGNOSTIC_CODES","Object","freeze","NoTrustedOrigin","ReferrerOnlyTrust","PluginIncompatible","ProfileFeatureOmitted","OrphanField","UnattributableUpdate","VisibilityGateDeferred","UnsafeAttributeWrite","TextTargetHasChildren","MissingArrayTemplate","StructuralItemUnkeyed","StructuralDuplicateKey","StructuralUnstableKeys","UnsupportedStrategy","UnknownValueFormat","SanitizerDroppedAttribute","UnrenderedBlockKept","UnfaithfulPatch","ServerFormatReplaced","UnrenderedBlockLost","MessageRejected","TokenRejected","ProtocolShapeUnknown","HandlerThrew","TransformThrew","RendererThrew","StartupFailed","ReadyFailed","HydrationWaitTimedOut","AuditRuntimeMissing","AuditNoFrameAncestors","AuditFrameOptionsBlocks","AuditBindingsExposed","AuditGateThresholdExceeded","AuditUnownedBindings","AuditNoBindings","AuditNotAPage","FragmentRequestFailed","FragmentResponseInvalid","FragmentUnauthorized","FragmentSuperseded","RouteRefreshLoop","FragmentStrategyUnavailable","UnboundChangeRefresh","V2ReadinessGap","RuntimeOnPublicPage","DEFAULT_PORT","http","https","ws","wss","SCHEME_SOURCE","HOST_SOURCE","schemeOf","protocol","portOf","port","schemeMatches","expression","actual","isSelf","admin","page","hostname","adminScheme","pageScheme","sourceMatches","scheme","host","expressionScheme","expressionHost","expressionPort","wanted","replace","endsWith","hostMatches","INLINE_CONFIG_KEYS","V2_RUNTIME_DEFAULTS","disableReferrerDetection","eventSourcePolicy","skipUnchanged","sanitizerPolicy","V1_RUNTIME_DEFAULTS","DEFAULTS_SLOT","ROWS","title","effect","condition","ORIGIN_DETAIL","profile","explicit","unmarked","UNREADABLE","code","level","detail","remedy","UNMARKED","literal","JSON","stringify","remedyFor","origin","row","gap","unknownGeneration","marker","RUNTIME_MARKER","BINDING_ATTRIBUTE","OWNER_ATTRIBUTE","LEVEL_ORDER","NON_MARKUP","visibleMarkup","markup","stripped","haystack","tryUrl","URL","analyzeProbe","probe","context","publicResponse","pub","previewResponse","preview","notAPage","status","location","headers","contentType","describeNonPage","findings","errors","warnings","runtimeInPreview","credentials","adminOrigin","sameOrigin","frameAncestors","csp","directive","trimmed","frameAncestorsOf","admitted","sources","frameAncestorsAdmits","frameOptions","judged","framingFindings","previewMarkup","publicMarkup","runtime","previewBindings","publicBindings","owners","unowned","firstOwner","search","unownedBindingsBeforeFirstOwner","bindingFindings","v2","config","from","CONFIG_MARKER","depth","inString","previous","json","char","parse","Array","isArray","readInlineConfig","generation","fallback","flatMap","slot","analyzeV2Readiness","a","b","finding","DEFAULT_INTENT_PARAMS","splitUrl","hashAt","hash","beforeHash","queryAt","base","parts","decodePart","part","at","decode","decodeURIComponent","TOKEN_PARAM","redactToken","shown","lowercaseHeaders","forEach","readBody","response","limit","reader","getReader","decoder","TextDecoder","received","done","byteLength","cancel","stream","previewReferer","href","PARAM_NAME","HEADER_LINE","addHeader","parsed","isAbsoluteUrl","given","usageError","addParam","params","HELP_TEXT","run","argv","fetchImpl","subcommand","rest","process","stdout","write","args","unknown","help","ids","token","parseArgs","stderr","result","io","readFile","content","writeFile","list","results","files","changedCount","conflictCount","runMigrate","message","conflicted","where","runMigrateCommand","showHelp","i","report","timeoutMs","maxBodyBytes","init","fetchFn","globalThis","fetch","redirect","signal","AbortSignal","timeout","createDefaultFetch","previewQueryParams","visitorUrl","Accept","probeHeaders","Referer","sent","own","taken","fromEntries","entries","callerHeaders","previewHeaders","isIntentValue","query","joiner","intent","encodeURIComponent","previewUrl","runDoctor","describeFailure","formatReport","isCliInvocation","pop","then","exit"],"sources":["../src/migrate/ast.ts","../src/migrate/codemods/move-fetch-preview-helpers.ts","../src/migrate/codemods/rename-admin-origins-option.ts","../src/migrate/codemods/rename-bindings-authorized-option.ts","../src/migrate/codemods/rename-is-preview-request.ts","../src/migrate/script-blocks.ts","../src/migrate/index.ts","../src/migrate/runner.ts","../src/migrate/cli.ts","../src/doctor/format.ts","../src/core/diagnostic-codes.ts","../src/doctor/csp.ts","../src/types/inline-config.ts","../src/types/defaults-profile.ts","../src/doctor/readiness.ts","../src/doctor/analyze.ts","../src/doctor/probe.ts","../src/doctor/cli.ts"],"sourcesContent":["/**\n * ts-morph access for the codemods: parsing, the package's bindings in a\n * script and the references those bindings have. ts-morph is loaded on first\n * use so the entry stays importable without the optional peer.\n */\nimport { createRequire } from 'node:module';\nimport type * as TsMorphModule from 'ts-morph';\nimport type {\n Identifier,\n Node,\n ObjectLiteralElementLike,\n Project,\n SourceFile,\n Symbol as TsSymbol,\n} from 'ts-morph';\nimport type { TextEdit } from './types';\n\ntype TsMorph = typeof TsMorphModule;\n\nexport type ScriptKind = 'ts' | 'tsx' | 'js' | 'jsx';\n\nexport const PACKAGE_NAME = 'payload-live-preview';\n\nlet tsMorph: TsMorph | undefined;\nlet project: Project | undefined;\n\nexport function loadTsMorph(): TsMorph {\n if (tsMorph === undefined) {\n try {\n tsMorph = createRequire(import.meta.url)('ts-morph') as TsMorph;\n } catch (error) {\n throw new Error('pll migrate needs ts-morph: npm install --save-dev ts-morph', {\n cause: error,\n });\n }\n }\n return tsMorph;\n}\n\n/** Parse one script into a throwaway in-memory project; the previous script is discarded. */\nexport function parseScript(text: string, kind: ScriptKind): SourceFile {\n const morph = loadTsMorph();\n project ??= new morph.Project({\n useInMemoryFileSystem: true,\n skipLoadingLibFiles: true,\n skipFileDependencyResolution: true,\n compilerOptions: { allowJs: true, noLib: true },\n });\n return project.createSourceFile(`/script.${kind}`, text, { overwrite: true });\n}\n\nexport function isPackageSpecifier(specifier: string): boolean {\n return specifier === PACKAGE_NAME || specifier.startsWith(`${PACKAGE_NAME}/`);\n}\n\n/** A name the script binds from the package, by `import` or by destructuring `require()`/`import()`. */\nexport interface PackageBinding {\n /** The exported name, as the package spells it. */\n readonly imported: string;\n /** The name the script uses; equals `imported` unless aliased. */\n readonly local: string;\n readonly specifier: string;\n readonly kind: 'import' | 'require';\n /** The node spelling the exported name; rewritten when the export is renamed. */\n readonly importedNode: Node;\n readonly aliased: boolean;\n readonly symbol: TsSymbol | undefined;\n /** The import declaration or variable declaration that binds it. */\n readonly declaration: Node;\n}\n\nexport function packageBindings(script: SourceFile): readonly PackageBinding[] {\n const { Node, SyntaxKind } = loadTsMorph();\n const out: PackageBinding[] = [];\n for (const declaration of script.getImportDeclarations()) {\n const specifier = declaration.getModuleSpecifierValue();\n if (!isPackageSpecifier(specifier)) continue;\n for (const spec of declaration.getNamedImports()) {\n const alias = spec.getAliasNode();\n const localNode = alias ?? spec.getNameNode();\n out.push({\n imported: spec.getName(),\n local: localNode.getText(),\n specifier,\n kind: 'import',\n importedNode: spec.getNameNode(),\n aliased: alias !== undefined,\n symbol: localNode.getSymbol(),\n declaration,\n });\n }\n }\n for (const declaration of script.getDescendantsOfKind(SyntaxKind.VariableDeclaration)) {\n const specifier = requiredSpecifier(declaration.getInitializer());\n const pattern = declaration.getNameNode();\n if (specifier === undefined || !isPackageSpecifier(specifier)) continue;\n if (!Node.isObjectBindingPattern(pattern)) continue;\n for (const element of pattern.getElements()) {\n const nameNode = element.getNameNode();\n if (!Node.isIdentifier(nameNode)) continue;\n const propertyName = element.getPropertyNameNode();\n out.push({\n imported: propertyName === undefined ? nameNode.getText() : literalName(propertyName),\n local: nameNode.getText(),\n specifier,\n kind: 'require',\n importedNode: propertyName ?? nameNode,\n aliased: propertyName !== undefined,\n symbol: nameNode.getSymbol(),\n declaration,\n });\n }\n }\n return out;\n}\n\nfunction requiredSpecifier(initializer: Node | undefined): string | undefined {\n const { Node, SyntaxKind } = loadTsMorph();\n const call =\n initializer !== undefined && Node.isAwaitExpression(initializer)\n ? initializer.getExpression()\n : initializer;\n if (call === undefined || !Node.isCallExpression(call)) return undefined;\n const callee = call.getExpression();\n const isRequire = Node.isIdentifier(callee) && callee.getText() === 'require';\n if (!isRequire && callee.getKind() !== SyntaxKind.ImportKeyword) return undefined;\n const [argument] = call.getArguments();\n return argument !== undefined && Node.isStringLiteral(argument)\n ? argument.getLiteralText()\n : undefined;\n}\n\nfunction literalName(node: Node): string {\n const { Node } = loadTsMorph();\n if (Node.isStringLiteral(node) || Node.isNoSubstitutionTemplateLiteral(node)) {\n return node.getLiteralText();\n }\n return node.getText();\n}\n\n/** The key of an object-literal member, or `undefined` when it is computed. */\nexport function propertyKey(property: ObjectLiteralElementLike): string | undefined {\n const { Node } = loadTsMorph();\n if (Node.isSpreadAssignment(property)) return undefined;\n const nameNode = property.getNameNode();\n if (Node.isComputedPropertyName(nameNode)) return undefined;\n return literalName(nameNode);\n}\n\nexport type ReferenceKind = 'reference' | 'shorthand' | 'export';\n\nexport interface BindingReference {\n readonly node: Identifier;\n /** `shorthand` is `{ name }`, `export` is `export { name }`; both keep the old key visible. */\n readonly kind: ReferenceKind;\n}\n\n/** Every use of the binding outside its own declaration, resolved by symbol so shadowing is respected. */\nexport function referencesTo(\n script: SourceFile,\n binding: PackageBinding,\n): readonly BindingReference[] {\n const { Node, SyntaxKind } = loadTsMorph();\n const target = binding.symbol?.compilerSymbol;\n if (target === undefined) return [];\n const checker = script.getProject().getTypeChecker();\n const out: BindingReference[] = [];\n for (const node of script.getDescendantsOfKind(SyntaxKind.Identifier)) {\n if (node.getText() !== binding.local || isInside(node, binding.declaration)) continue;\n const parent = node.getParent();\n if (Node.isShorthandPropertyAssignment(parent)) {\n if (checker.getShorthandAssignmentValueSymbol(parent)?.compilerSymbol === target) {\n out.push({ node, kind: 'shorthand' });\n }\n continue;\n }\n if (Node.isExportSpecifier(parent)) {\n if (\n parent.getNameNode() === node &&\n parent.getLocalTargetSymbol()?.compilerSymbol === target\n ) {\n out.push({ node, kind: 'export' });\n }\n continue;\n }\n if (node.getSymbol()?.compilerSymbol === target) out.push({ node, kind: 'reference' });\n }\n return out;\n}\n\nfunction isInside(node: Node, ancestor: Node): boolean {\n return node.getFirstAncestor((candidate) => candidate === ancestor) !== undefined;\n}\n\n/** The declaration that binds `name` anywhere in the script, ignoring those in `except`. */\nexport function declaresName(\n script: SourceFile,\n name: string,\n except: readonly Node[] = [],\n): Node | undefined {\n const { SyntaxKind } = loadTsMorph();\n for (const node of script.getDescendantsOfKind(SyntaxKind.Identifier)) {\n if (node.getText() !== name) continue;\n const parent = node.getParent();\n if (!bindsIdentifier(parent, node)) continue;\n if (except.some((skip) => skip === parent || isInside(parent, skip))) continue;\n return parent;\n }\n return undefined;\n}\n\nfunction bindsIdentifier(parent: Node, node: Identifier): boolean {\n const { Node } = loadTsMorph();\n if (\n Node.isVariableDeclaration(parent) ||\n Node.isBindingElement(parent) ||\n Node.isFunctionDeclaration(parent) ||\n Node.isClassDeclaration(parent) ||\n Node.isParameterDeclaration(parent) ||\n Node.isEnumDeclaration(parent)\n ) {\n return parent.getNameNode() === node;\n }\n if (Node.isImportSpecifier(parent)) {\n return (parent.getAliasNode() ?? parent.getNameNode()) === node;\n }\n if (Node.isImportClause(parent)) return parent.getDefaultImport() === node;\n if (Node.isNamespaceImport(parent)) return parent.getNameNode() === node;\n return false;\n}\n\n/** Identifiers spelled `name` that are member names (`x.name`), never the package's binding. */\nexport function memberAccesses(script: SourceFile, name: string): readonly Identifier[] {\n const { Node, SyntaxKind } = loadTsMorph();\n return script.getDescendantsOfKind(SyntaxKind.Identifier).filter((node) => {\n const parent = node.getParent();\n return (\n node.getText() === name &&\n Node.isPropertyAccessExpression(parent) &&\n parent.getNameNode() === node\n );\n });\n}\n\nexport function replaceNode(node: Node, text: string): TextEdit {\n return { start: node.getStart(), end: node.getEnd(), text };\n}\n\n/** Splice non-overlapping edits into `text`. */\nexport function applyTextEdits(text: string, edits: readonly TextEdit[]): string {\n const ordered = [...edits].sort((left, right) => right.start - left.start);\n let output = text;\n let floor = Number.POSITIVE_INFINITY;\n for (const edit of ordered) {\n if (edit.end > floor) throw new Error('overlapping codemod edits');\n output = `${output.slice(0, edit.start)}${edit.text}${output.slice(edit.end)}`;\n floor = edit.start;\n }\n return output;\n}\n","/**\n * Ledger entry 9: `fetchPreviewDocument()`/`fetchPreviewGlobal()` on the root\n * entry → `definePreview({ serverURL, depth }).fetchDocument()`/`.fetchGlobal()`\n * on `payload-live-preview/server`.\n */\nimport {\n PACKAGE_NAME,\n declaresName,\n loadTsMorph,\n packageBindings,\n propertyKey,\n referencesTo,\n type PackageBinding,\n} from '../ast';\nimport type { CodemodImplementation, CodemodConflict, CodemodPlan, TextEdit } from '../types';\nimport type {\n CallExpression,\n ImportDeclaration,\n ObjectLiteralExpression,\n SourceFile,\n} from 'ts-morph';\n\nconst ID = 'move-fetch-preview-helpers';\nconst SERVER_SPECIFIER = `${PACKAGE_NAME}/server`;\nconst METHOD: Readonly<Record<string, string>> = {\n fetchPreviewDocument: 'fetchDocument',\n fetchPreviewGlobal: 'fetchGlobal',\n};\nconst SERVER_OPTIONS = new Set(['serverURL', 'apiRoute', 'depth']);\nconst DROPPED_OPTIONS = new Set(['draft', 'fetchFn']);\n/**\n * What `ReadDocumentOptions`/`ReadGlobalOptions` accept (src/server/preview.ts).\n * 1.x spelled the target `collection` and `global` too, so there is no rename to\n * make here — a key that is in neither set is one this codemod cannot place, and\n * passing it through unannounced produces a file that does not compile.\n */\nconst SHARED_READ_OPTIONS = ['authorization', 'locale', 'headers', 'signal', 'errorMode'];\nconst READ_OPTIONS: Readonly<Record<string, readonly string[]>> = {\n fetchPreviewDocument: ['collection', 'where', ...SHARED_READ_OPTIONS],\n fetchPreviewGlobal: ['global', ...SHARED_READ_OPTIONS],\n};\nconst DEPTH_TODO =\n 'depth: 1 /* TODO(pll migrate): the 1.x default; match the runtime mergeDepth */';\nconst AUTHORIZATION_TODO =\n 'authorization: null /* TODO(pll migrate): pass the verdict from authorizePreviewRequest(); ' +\n 'null reads the published document */';\n\nfunction conflict(line: number, reason: string): CodemodConflict {\n return { codemod: ID, reason, line };\n}\n\ninterface RewrittenCall {\n readonly edit: TextEdit;\n readonly notes: readonly CodemodConflict[];\n}\n\nfunction rewriteCall(\n call: CallExpression,\n options: ObjectLiteralExpression,\n imported: string,\n): RewrittenCall {\n const server: string[] = [];\n const read: string[] = [];\n const dropped: string[] = [];\n const keys = new Set<string>();\n for (const property of options.getProperties()) {\n const key = propertyKey(property);\n if (key !== undefined) keys.add(key);\n if (key !== undefined && SERVER_OPTIONS.has(key)) server.push(property.getText());\n else if (key !== undefined && DROPPED_OPTIONS.has(key)) dropped.push(key);\n else read.push(property.getText());\n }\n if (!keys.has('depth')) server.push(DEPTH_TODO);\n if (!keys.has('authorization')) read.push(AUTHORIZATION_TODO);\n const accepted = READ_OPTIONS[imported] ?? [];\n const unplaceable = [...keys].filter(\n (key) => !SERVER_OPTIONS.has(key) && !DROPPED_OPTIONS.has(key) && !accepted.includes(key),\n );\n const typeArguments = call.getTypeArguments().map((argument) => argument.getText());\n const generic = typeArguments.length === 0 ? '' : `<${typeArguments.join(', ')}>`;\n const method = METHOD[imported] ?? imported;\n const text = `definePreview({ ${server.join(', ')} }).${method}${generic}({ ${read.join(', ')} })`;\n const droppedNote = dropped.length === 0 ? '' : `, and ${dropped.join('/')} was dropped`;\n const line = call.getStartLineNumber();\n const notes = [\n conflict(\n line,\n `${imported}() was rewritten onto definePreview().${method}(); it now returns a ` +\n `PreviewFetchResult (check ok/data) and needs a real authorization for drafts${droppedNote}`,\n ),\n ];\n if (unplaceable.length > 0) {\n notes.push(\n conflict(\n line,\n `${imported}() was passed ${unplaceable.map((key) => `\\`${key}\\``).join(', ')}, which ` +\n `.${method}() does not accept; it takes ${accepted.join(', ')}. The key was carried ` +\n 'over unchanged and will not compile — place it by hand',\n ),\n );\n }\n return { edit: { start: call.getStart(), end: call.getEnd(), text }, notes };\n}\n\nfunction importLine(quote: string, names: readonly string[], specifier: string): string {\n return `import { ${names.join(', ')} } from ${quote}${specifier}${quote};`;\n}\n\n/** Drop the moved names from their root imports and make sure `definePreview` is imported from the server entry. */\nfunction rewriteImports(script: SourceFile, bindings: readonly PackageBinding[]): TextEdit[] {\n const { Node } = loadTsMorph();\n const edits: TextEdit[] = [];\n const declarations = new Set<ImportDeclaration>();\n for (const binding of bindings) {\n if (Node.isImportDeclaration(binding.declaration)) declarations.add(binding.declaration);\n }\n const serverImport = script\n .getImportDeclarations()\n .find(\n (declaration) =>\n declaration.getModuleSpecifierValue() === SERVER_SPECIFIER && !declaration.isTypeOnly(),\n );\n const hasDefinePreview =\n serverImport?.getNamedImports().some((spec) => spec.getName() === 'definePreview') === true;\n let serverLine: string | undefined;\n if (serverImport !== undefined && !hasDefinePreview) {\n const quote = serverImport.getModuleSpecifier().getQuoteKind();\n const names = [\n ...serverImport.getNamedImports().map((spec) => spec.getText()),\n 'definePreview',\n ];\n const defaultImport = serverImport.getDefaultImport()?.getText();\n const clauses =\n defaultImport === undefined ? names.join(', ') : `${defaultImport}, { ${names.join(', ')} }`;\n const text =\n defaultImport === undefined\n ? importLine(quote, names, SERVER_SPECIFIER)\n : `import ${clauses} from ${quote}${SERVER_SPECIFIER}${quote};`;\n edits.push({ start: serverImport.getStart(), end: serverImport.getEnd(), text });\n }\n for (const declaration of declarations) {\n const quote = declaration.getModuleSpecifier().getQuoteKind();\n const remaining = declaration\n .getNamedImports()\n .filter((spec) => !(spec.getName() in METHOD))\n .map((spec) => spec.getText());\n const defaultImport = declaration.getDefaultImport()?.getText();\n const clauses = [\n defaultImport,\n remaining.length === 0 ? undefined : `{ ${remaining.join(', ')} }`,\n ].filter((clause): clause is string => clause !== undefined);\n const typeOnly = declaration.isTypeOnly() ? 'type ' : '';\n const kept =\n clauses.length === 0\n ? ''\n : `import ${typeOnly}${clauses.join(', ')} from ${quote}${PACKAGE_NAME}${quote};`;\n if (serverImport === undefined && serverLine === undefined) {\n serverLine = importLine(quote, ['definePreview'], SERVER_SPECIFIER);\n edits.push({\n start: declaration.getStart(),\n end: declaration.getEnd(),\n text: kept === '' ? serverLine : `${kept}\\n${serverLine}`,\n });\n } else {\n // A removed declaration takes its line break with it.\n const end = declaration.getEnd();\n const trailingNewline = kept === '' && script.getFullText()[end] === '\\n' ? 1 : 0;\n edits.push({ start: declaration.getStart(), end: end + trailingNewline, text: kept });\n }\n }\n return edits;\n}\n\nfunction plan(script: SourceFile, bindings: readonly PackageBinding[]): CodemodPlan {\n const { Node } = loadTsMorph();\n const blocking: CodemodConflict[] = [];\n const notes: CodemodConflict[] = [];\n const edits: TextEdit[] = [];\n for (const binding of bindings) {\n if (binding.kind === 'require') {\n blocking.push(\n conflict(\n binding.declaration.getStartLineNumber(),\n `${binding.imported} is bound with require(); rewrite it onto definePreview() from ` +\n `${SERVER_SPECIFIER} by hand`,\n ),\n );\n continue;\n }\n for (const reference of referencesTo(script, binding)) {\n const line = reference.node.getStartLineNumber();\n const call = reference.node.getParent();\n const isCall =\n reference.kind === 'reference' &&\n Node.isCallExpression(call) &&\n call.getExpression() === reference.node;\n if (!isCall) {\n blocking.push(\n conflict(\n line,\n `${binding.local} is used other than as a direct call; rewrite it onto definePreview() by hand`,\n ),\n );\n continue;\n }\n const [options] = call.getArguments();\n if (\n options === undefined ||\n !Node.isObjectLiteralExpression(options) ||\n options.getProperties().some((property) => Node.isSpreadAssignment(property))\n ) {\n blocking.push(\n conflict(\n line,\n `${binding.imported}() options are not a plain object literal, so serverURL/depth ` +\n 'cannot be split out; rewrite it onto definePreview() by hand',\n ),\n );\n continue;\n }\n const rewritten = rewriteCall(call, options, binding.imported);\n edits.push(rewritten.edit);\n notes.push(...rewritten.notes);\n }\n }\n const serverDeclaration = script\n .getImportDeclarations()\n .filter((declaration) => declaration.getModuleSpecifierValue() === SERVER_SPECIFIER);\n const foreign = declaresName(script, 'definePreview', serverDeclaration);\n if (foreign !== undefined) {\n blocking.push(\n conflict(\n foreign.getStartLineNumber(),\n `this module already binds a definePreview that is not ${SERVER_SPECIFIER}'s; rename it, ` +\n 'then move the fetch helpers by hand',\n ),\n );\n }\n if (blocking.length > 0) return { edits: [], conflicts: [...blocking, ...notes] };\n edits.push(...rewriteImports(script, bindings));\n return { edits, conflicts: notes };\n}\n\nexport const moveFetchPreviewHelpers: CodemodImplementation = {\n id: ID,\n summary:\n '`fetchPreviewDocument`/`fetchPreviewGlobal` from the root → `definePreview().fetchDocument`/`.fetchGlobal` (payload-live-preview/server)',\n ledgerEntry: 9,\n apply(script) {\n const bindings = packageBindings(script).filter(\n (binding) => binding.specifier === PACKAGE_NAME && binding.imported in METHOD,\n );\n if (bindings.length === 0) return { edits: [], conflicts: [] };\n return plan(script, bindings);\n },\n};\n","/** Ledger entry 13: `hasPreviewIntent(request, { adminOrigins })` → `{ allowedOrigins }`. */\nimport { loadTsMorph, packageBindings, propertyKey, referencesTo, replaceNode } from '../ast';\nimport type { CodemodImplementation, CodemodConflict, TextEdit } from '../types';\n\nconst ID = 'rename-admin-origins-option';\nconst CALLEE = 'hasPreviewIntent';\nconst OLD_KEY = 'adminOrigins';\nconst NEW_KEY = 'allowedOrigins';\nconst BY_HAND = `if they carry \\`${OLD_KEY}\\`, rename it to \\`${NEW_KEY}\\``;\n\nexport const renameAdminOriginsOption: CodemodImplementation = {\n id: ID,\n summary: '`hasPreviewIntent(request, { adminOrigins })` → `{ allowedOrigins }`',\n ledgerEntry: 13,\n apply(script) {\n const { Node } = loadTsMorph();\n const edits: TextEdit[] = [];\n const conflicts: CodemodConflict[] = [];\n const bindings = packageBindings(script).filter((binding) => binding.imported === CALLEE);\n for (const binding of bindings) {\n for (const reference of referencesTo(script, binding)) {\n const call = reference.node.getParent();\n if (reference.kind !== 'reference' || !Node.isCallExpression(call)) continue;\n if (call.getExpression() !== reference.node) continue;\n const options = call.getArguments()[1];\n if (options === undefined) continue;\n const line = options.getStartLineNumber();\n if (!Node.isObjectLiteralExpression(options)) {\n conflicts.push({\n codemod: ID,\n line,\n reason: `${CALLEE}() options are not a literal; ${BY_HAND}`,\n });\n continue;\n }\n const properties = options.getProperties();\n const keys = properties.map((property) => propertyKey(property));\n // With both names the package reads `allowedOrigins` and ignores the\n // alias; renamed, the later key would win instead.\n if (keys.includes(OLD_KEY) && keys.includes(NEW_KEY)) {\n conflicts.push({\n codemod: ID,\n line,\n reason: `${CALLEE}() is given both ${OLD_KEY} and ${NEW_KEY}; ${NEW_KEY} wins, drop ${OLD_KEY} by hand`,\n });\n continue;\n }\n for (const property of properties) {\n if (Node.isSpreadAssignment(property)) {\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: `${CALLEE}() spreads its options; ${BY_HAND}`,\n });\n } else if (propertyKey(property) !== OLD_KEY) {\n continue;\n } else if (Node.isShorthandPropertyAssignment(property)) {\n edits.push(replaceNode(property, `${NEW_KEY}: ${OLD_KEY}`));\n } else if (Node.isPropertyAssignment(property)) {\n edits.push(replaceNode(property.getNameNode(), NEW_KEY));\n }\n }\n }\n }\n return { edits, conflicts };\n },\n};\n","/** Ledger entry 7: `createPreviewBindings({ authorized })` → `{ authorization }`. */\nimport { loadTsMorph, packageBindings, propertyKey, referencesTo, replaceNode } from '../ast';\nimport type { CodemodImplementation, CodemodConflict, TextEdit } from '../types';\n\nconst ID = 'rename-bindings-authorized-option';\nconst OLD_KEY = 'authorized';\nconst NEW_KEY = 'authorization';\nconst BY_HAND =\n `if they carry \\`${OLD_KEY}\\`, rename it to \\`${NEW_KEY}\\` and pass the verdict from ` +\n 'authorizePreviewRequest()';\n/**\n * `false` has an exact equivalent — an unauthorized response suppresses every\n * binding, which is what `null` means — so it is rewritten. Nothing else does:\n * only a real context from `authorizePreviewRequest()` authorizes emission, and\n * a boolean left under the new name does not compile (TS2322).\n */\nconst BOOLEAN_REFUSED =\n `\\`${NEW_KEY}\\` takes the context from authorizePreviewRequest(); the boolean 1.x ` +\n 'accepted is not. The key was renamed and its value left as it stands — pass the ' +\n 'verdict, or `null` for a public response';\n\nexport const renameBindingsAuthorizedOption: CodemodImplementation = {\n id: ID,\n summary: '`createPreviewBindings({ authorized })` → `{ authorization }`',\n ledgerEntry: 7,\n apply(script) {\n const { Node } = loadTsMorph();\n const edits: TextEdit[] = [];\n const conflicts: CodemodConflict[] = [];\n const bindings = packageBindings(script).filter(\n (binding) => binding.imported === 'createPreviewBindings',\n );\n for (const binding of bindings) {\n for (const reference of referencesTo(script, binding)) {\n const call = reference.node.getParent();\n if (reference.kind !== 'reference' || !Node.isCallExpression(call)) continue;\n if (call.getExpression() !== reference.node) continue;\n const [options] = call.getArguments();\n if (options === undefined) continue;\n const line = options.getStartLineNumber();\n if (!Node.isObjectLiteralExpression(options)) {\n conflicts.push({\n codemod: ID,\n line,\n reason: `createPreviewBindings() options are not a literal; ${BY_HAND}`,\n });\n continue;\n }\n for (const property of options.getProperties()) {\n if (Node.isSpreadAssignment(property)) {\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: `createPreviewBindings() spreads its options; ${BY_HAND}`,\n });\n } else if (propertyKey(property) !== OLD_KEY) {\n continue;\n } else if (Node.isShorthandPropertyAssignment(property)) {\n edits.push(replaceNode(property, `${NEW_KEY}: ${OLD_KEY}`));\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: BOOLEAN_REFUSED,\n });\n } else if (Node.isPropertyAssignment(property)) {\n const value = property.getInitializer();\n if (value !== undefined && Node.isFalseLiteral(value)) {\n edits.push(replaceNode(property, `${NEW_KEY}: null`));\n continue;\n }\n edits.push(replaceNode(property.getNameNode(), NEW_KEY));\n conflicts.push({\n codemod: ID,\n line: property.getStartLineNumber(),\n reason: BOOLEAN_REFUSED,\n });\n }\n }\n }\n }\n return { edits, conflicts };\n },\n};\n","/** Ledger entry 1: `isPreviewRequest()` → `hasPreviewIntent()`, same signature. */\nimport {\n declaresName,\n memberAccesses,\n packageBindings,\n referencesTo,\n replaceNode,\n type PackageBinding,\n} from '../ast';\nimport type { CodemodImplementation, CodemodConflict, CodemodPlan, TextEdit } from '../types';\n\nconst ID = 'rename-is-preview-request';\nconst OLD_NAME = 'isPreviewRequest';\nconst NEW_NAME = 'hasPreviewIntent';\n\nfunction conflict(line: number, reason: string): CodemodConflict {\n return { codemod: ID, reason, line };\n}\n\nfunction renameBinding(binding: PackageBinding): TextEdit {\n // `import { isPreviewRequest as hasPreviewIntent }` collapses to the bare name.\n if (binding.aliased && binding.local === NEW_NAME) {\n return replaceNode(binding.importedNode.getParentOrThrow(), NEW_NAME);\n }\n return replaceNode(binding.importedNode, NEW_NAME);\n}\n\nfunction plan(\n bindings: readonly PackageBinding[],\n script: Parameters<CodemodImplementation['apply']>[0],\n): CodemodPlan {\n const blocking: CodemodConflict[] = [];\n const edits: TextEdit[] = [];\n const existing = declaresName(\n script,\n NEW_NAME,\n bindings.map((binding) => binding.declaration),\n );\n if (existing !== undefined) {\n blocking.push(\n conflict(\n existing.getStartLineNumber(),\n `this module already binds ${NEW_NAME}; rename it (or drop the wrapper and import the ` +\n `package's ${NEW_NAME} directly), then rename ${OLD_NAME} by hand`,\n ),\n );\n }\n for (const binding of bindings) {\n edits.push(renameBinding(binding));\n if (binding.aliased) continue;\n for (const reference of referencesTo(script, binding)) {\n if (reference.kind === 'reference') {\n edits.push(replaceNode(reference.node, NEW_NAME));\n } else if (reference.kind === 'shorthand') {\n blocking.push(\n conflict(\n reference.node.getStartLineNumber(),\n `{ ${OLD_NAME} } keeps the old key for whoever reads it; write ` +\n `{ ${OLD_NAME}: ${NEW_NAME} } or rename the key and its readers by hand`,\n ),\n );\n } else {\n blocking.push(\n conflict(\n reference.node.getStartLineNumber(),\n `${OLD_NAME} is re-exported under its old name; rename the export and its ` +\n `importers, or write export { ${NEW_NAME} as ${OLD_NAME} }`,\n ),\n );\n }\n }\n }\n const notes = memberAccesses(script, OLD_NAME).map((node) =>\n conflict(\n node.getStartLineNumber(),\n `.${OLD_NAME} is a member of this module's own object, not the package import, and was ` +\n 'left alone; check that it does not wrap the removed API',\n ),\n );\n if (blocking.length > 0) return { edits: [], conflicts: [...blocking, ...notes] };\n return { edits, conflicts: notes };\n}\n\nexport const renameIsPreviewRequest: CodemodImplementation = {\n id: ID,\n summary: '`isPreviewRequest()` → `hasPreviewIntent()` (same signature)',\n ledgerEntry: 1,\n // The rename keeps behaviour, and that is the part worth saying: the 2.0\n // adapters count only the query, and a renamed call silently does not.\n notice:\n 'hasPreviewIntent() takes the options isPreviewRequest() took and, without `signals`, counts ' +\n 'the same three: a preview query parameter, Sec-Fetch-Dest: iframe and an admin Referer. The ' +\n \"2.0 adapters count only the query; where a call should agree with them, pass { signals: ['query'] } \" +\n '(docs/migration.md).',\n apply(script) {\n const bindings = packageBindings(script).filter((binding) => binding.imported === OLD_NAME);\n if (bindings.length === 0) return { edits: [], conflicts: [] };\n return plan(bindings, script);\n },\n};\n","/** Where the script lives in a file: the whole file, or the script blocks of a component. */\nimport { extname } from 'node:path';\nimport type { ScriptKind } from './ast';\n\nexport interface ScriptBlock {\n readonly start: number;\n readonly end: number;\n readonly kind: ScriptKind;\n}\n\nconst WHOLE_FILE: Readonly<Record<string, ScriptKind>> = {\n '.ts': 'ts',\n '.mts': 'ts',\n '.cts': 'ts',\n '.tsx': 'tsx',\n '.js': 'js',\n '.mjs': 'js',\n '.cjs': 'js',\n '.jsx': 'jsx',\n};\nconst COMPONENT_EXTENSIONS = new Set(['.astro', '.vue', '.svelte']);\nconst FRONTMATTER = /^---\\r?\\n([\\s\\S]*?)\\r?\\n---/u;\n// Browsers close a script on `</script` followed by anything up to `>`, so the\n// end tag must accept that too, or a stray `</script foo>` would swallow the\n// rest of the file into one block.\nconst SCRIPT_TAG = /<script(?:\\s[^>]*)?>([\\s\\S]*?)<\\/script\\b[^>]*>/giu;\n\nexport function scriptBlocks(source: string, fileName: string): readonly ScriptBlock[] {\n const extension = extname(fileName).toLowerCase();\n if (!COMPONENT_EXTENSIONS.has(extension)) {\n return [{ start: 0, end: source.length, kind: WHOLE_FILE[extension] ?? 'ts' }];\n }\n const blocks: ScriptBlock[] = [];\n const frontmatter = extension === '.astro' ? FRONTMATTER.exec(source) : null;\n if (frontmatter?.[1] !== undefined) {\n const start = frontmatter.index + frontmatter[0].indexOf('\\n') + 1;\n blocks.push({ start, end: start + frontmatter[1].length, kind: 'ts' });\n }\n for (const match of source.matchAll(SCRIPT_TAG)) {\n const body = match[1] ?? '';\n if (body.trim() === '') continue;\n const start = match.index + match[0].lastIndexOf(body);\n blocks.push({ start, end: start + body.length, kind: 'ts' });\n }\n return blocks;\n}\n","/**\n * `pll migrate`: the 1.x → 2.0 codemods and the driver that applies them to one\n * source string. Rewrites are planned on the AST (ts-morph) so only names the\n * package binds are touched; see ADR 0007.\n */\nimport { applyTextEdits, parseScript } from './ast';\nimport { moveFetchPreviewHelpers } from './codemods/move-fetch-preview-helpers';\nimport { renameAdminOriginsOption } from './codemods/rename-admin-origins-option';\nimport { renameBindingsAuthorizedOption } from './codemods/rename-bindings-authorized-option';\nimport { renameIsPreviewRequest } from './codemods/rename-is-preview-request';\nimport { scriptBlocks } from './script-blocks';\nimport type {\n Codemod,\n CodemodConflict,\n CodemodEdit,\n CodemodImplementation,\n CodemodLineEdit,\n} from './types';\n\nexport type {\n Codemod,\n CodemodConflict,\n CodemodEdit,\n CodemodLineEdit,\n CodemodPlan,\n TextEdit,\n} from './types';\n\nconst PACKAGE_REFERENCE =\n /(?:\\bfrom\\s*|\\bimport\\s*\\(?\\s*|\\brequire\\s*\\(\\s*)['\"]payload-live-preview(?:\\/[^'\"]*)?['\"]/u;\n\n/** Whether the source names the package in an `import`, `import()` or `require()`. @internal */\nexport function importsThisPackage(source: string): boolean {\n return PACKAGE_REFERENCE.test(source);\n}\n\n// The option rename follows the function rename so it sees the new binding.\nconst IMPLEMENTATIONS: readonly CodemodImplementation[] = [\n renameIsPreviewRequest,\n renameAdminOriginsOption,\n renameBindingsAuthorizedOption,\n moveFetchPreviewHelpers,\n];\n\n/**\n * The codemods in the order they run. Each is idempotent. Metadata only: the\n * rewrite is internal, so importing this entry's types does not require\n * `ts-morph`, which is needed only to run `pll migrate`.\n * @internal\n */\nexport const CODEMODS: readonly Codemod[] = IMPLEMENTATIONS;\n\nexport interface MigrateSourceOptions {\n /** Restrict to these codemod ids. */\n readonly only?: readonly string[];\n /**\n * Decides how the source is parsed: `.astro`, `.vue` and `.svelte` by script\n * block, JSX by extension. Defaults to a `.ts` module.\n */\n readonly fileName?: string;\n}\n\nexport interface MigrateSourceResult {\n readonly output: string;\n readonly edits: readonly CodemodEdit[];\n readonly conflicts: readonly CodemodConflict[];\n}\n\nfunction lineNumberAt(source: string, offset: number): number {\n let line = 1;\n for (let index = 0; index < offset; index += 1) if (source[index] === '\\n') line += 1;\n return line;\n}\n\n/** The changed lines between two versions, trimmed to the differing middle. */\nfunction lineEdits(before: string, after: string, firstLine: number): CodemodLineEdit[] {\n const oldLines = before.split('\\n');\n const newLines = after.split('\\n');\n let prefix = 0;\n while (\n prefix < oldLines.length &&\n prefix < newLines.length &&\n oldLines[prefix] === newLines[prefix]\n ) {\n prefix += 1;\n }\n let suffix = 0;\n while (\n suffix < oldLines.length - prefix &&\n suffix < newLines.length - prefix &&\n oldLines[oldLines.length - 1 - suffix] === newLines[newLines.length - 1 - suffix]\n ) {\n suffix += 1;\n }\n const oldMiddle = oldLines.slice(prefix, oldLines.length - suffix);\n const newMiddle = newLines.slice(prefix, newLines.length - suffix);\n const changed: CodemodLineEdit[] = [];\n for (let index = 0; index < Math.max(oldMiddle.length, newMiddle.length); index += 1) {\n const before = oldMiddle[index] ?? '';\n const after = newMiddle[index] ?? '';\n if (before !== after) changed.push({ line: firstLine + prefix + index, before, after });\n }\n return changed;\n}\n\n/** Apply every codemod (or the chosen subset) to one source string. */\nexport function migrateSource(\n source: string,\n options: MigrateSourceOptions = {},\n): MigrateSourceResult {\n const chosen =\n options.only === undefined\n ? IMPLEMENTATIONS\n : IMPLEMENTATIONS.filter((codemod) => options.only?.includes(codemod.id));\n if (chosen.length === 0 || !importsThisPackage(source)) {\n return { output: source, edits: [], conflicts: [] };\n }\n const byCodemod = new Map<string, CodemodLineEdit[]>();\n const conflicts: CodemodConflict[] = [];\n let output = '';\n let cursor = 0;\n for (const block of scriptBlocks(source, options.fileName ?? 'source.ts')) {\n output += source.slice(cursor, block.start);\n const firstLine = lineNumberAt(source, block.start);\n let text = source.slice(block.start, block.end);\n for (const codemod of chosen) {\n const plan = codemod.apply(parseScript(text, block.kind));\n for (const item of plan.conflicts) {\n conflicts.push(\n item.line === undefined ? item : { ...item, line: item.line + firstLine - 1 },\n );\n }\n if (plan.edits.length === 0) continue;\n const next = applyTextEdits(text, plan.edits);\n const lines = byCodemod.get(codemod.id) ?? [];\n lines.push(...lineEdits(text, next, firstLine));\n byCodemod.set(codemod.id, lines);\n text = next;\n }\n output += text;\n cursor = block.end;\n }\n output += source.slice(cursor);\n const edits = [...byCodemod].map(([codemod, lines]) => ({ codemod, count: lines.length, lines }));\n return { output, edits, conflicts };\n}\n","/** The file walker behind `pll migrate`: find source files, apply the codemods, report or write. */\nimport { readFile, readdir, stat, writeFile } from 'node:fs/promises';\nimport { extname, join, relative } from 'node:path';\nimport { migrateSource } from './index';\nimport type { CodemodConflict, CodemodEdit } from './types';\n\nconst SOURCE_EXTENSIONS = new Set([\n '.ts',\n '.tsx',\n '.mts',\n '.cts',\n '.js',\n '.jsx',\n '.mjs',\n '.cjs',\n '.astro',\n '.svelte',\n '.vue',\n]);\nconst DECLARATION_FILE = /\\.d\\.[cm]?ts$/u;\nconst SKIP_DIRECTORIES = new Set([\n 'node_modules',\n 'dist',\n '.git',\n '.astro',\n '.svelte-kit',\n '.next',\n '.nuxt',\n 'coverage',\n]);\n\nexport interface MigrateFileResult {\n readonly file: string;\n readonly edits: readonly CodemodEdit[];\n readonly changed: boolean;\n /** What a codemod could not rewrite safely in this file. */\n readonly conflicts: readonly CodemodConflict[];\n}\n\nexport interface MigrateRunResult {\n readonly files: readonly MigrateFileResult[];\n /** Files the run changed (or would change, in dry-run). */\n readonly changedCount: number;\n /** Codemod id → number of files it touched. */\n readonly byCodemod: Readonly<Record<string, number>>;\n /** Files needing manual attention. */\n readonly conflictCount: number;\n}\n\nexport interface MigrateOptions {\n /** Apply and save; without it the run only reports. */\n readonly write?: boolean;\n /** Restrict to these codemod ids. */\n readonly only?: readonly string[];\n /** Reader/writer injection for tests. */\n readonly io?: {\n readonly read: (path: string) => Promise<string>;\n readonly write: (path: string, content: string) => Promise<void>;\n readonly list: (root: string) => Promise<readonly string[]>;\n };\n}\n\nfunction isSourceFile(name: string): boolean {\n return SOURCE_EXTENSIONS.has(extname(name)) && !DECLARATION_FILE.test(name);\n}\n\nasync function collectFiles(root: string): Promise<string[]> {\n const found: string[] = [];\n async function walk(directory: string): Promise<void> {\n for (const entry of await readdir(directory, { withFileTypes: true })) {\n const path = join(directory, entry.name);\n if (entry.isDirectory()) {\n if (!SKIP_DIRECTORIES.has(entry.name)) await walk(path);\n } else if (isSourceFile(entry.name)) {\n found.push(path);\n }\n }\n }\n const info = await stat(root);\n if (info.isDirectory()) await walk(root);\n else if (isSourceFile(root)) found.push(root);\n return found.sort();\n}\n\nfunction relativeTo(root: string, file: string): string {\n const rel = relative(root, file);\n return rel.length === 0 ? file : rel;\n}\n\n/** Migrate every source file under `root`. */\nexport async function runMigrate(\n root: string,\n options: MigrateOptions = {},\n): Promise<MigrateRunResult> {\n const io = options.io ?? {\n read: (path) => readFile(path, 'utf8'),\n write: (path, content) => writeFile(path, content, 'utf8'),\n list: collectFiles,\n };\n const results: MigrateFileResult[] = [];\n const byCodemod: Record<string, number> = {};\n for (const file of await io.list(root)) {\n const source = await io.read(file);\n const { output, edits, conflicts } = migrateSource(source, {\n fileName: file,\n ...(options.only === undefined ? {} : { only: options.only }),\n });\n const changed = output !== source;\n if (changed && options.write === true) await io.write(file, output);\n if (changed) {\n for (const edit of edits) byCodemod[edit.codemod] = (byCodemod[edit.codemod] ?? 0) + 1;\n }\n results.push({ file: relativeTo(root, file), edits, changed, conflicts });\n }\n return {\n files: results,\n changedCount: results.filter((result) => result.changed).length,\n byCodemod,\n conflictCount: results.filter((result) => result.conflicts.length > 0).length,\n };\n}\n","/**\n * `pll migrate <path> [--write] [--only <id,id>]`, hosted by the `pll` binary.\n * Exit codes: 0 clean, 1 usage or I/O error, 3 when conflicts need a human.\n */\nimport { CODEMODS } from './index';\nimport { runMigrate, type MigrateFileResult } from './runner';\n\nexport const MIGRATE_HELP = `pll migrate — rewrite 1.x APIs to their 2.0 names and homes (ADR 0007)\n\nUsage:\n pll migrate <path> [--write] [--only <id,id>]\n\nWithout --write the run only reports what it would change. Codemods touch\nonly names bound from payload-live-preview; anything they cannot rewrite\nsafely is listed as needing manual attention. Requires ts-morph.\n\nOptions:\n --write Apply the changes (otherwise dry-run)\n --only <ids> Run only these codemods (comma-separated); an id not\n listed below runs nothing\n -h, --help Show this help\n\nCodemods, in the order they run:\n rename-is-preview-request\n rename-admin-origins-option\n rename-bindings-authorized-option\n move-fetch-preview-helpers\n\nExit codes:\n 0 nothing needs a human (changes applied, or would be with --write)\n 1 usage error, unreadable path, or ts-morph is not installed\n 3 at least one file needs manual attention\n`;\n\ninterface MigrateArgs {\n readonly target: string | undefined;\n readonly write: boolean;\n readonly only: readonly string[] | undefined;\n readonly help: boolean;\n readonly unknown: string | undefined;\n}\n\nfunction parseArgs(argv: readonly string[]): MigrateArgs {\n let target: string | undefined;\n let write = false;\n let only: string[] | undefined;\n let help = false;\n let unknown: string | undefined;\n const ids = (value: string): string[] => value.split(',').filter((id) => id.length > 0);\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === undefined) continue;\n if (token === '-h' || token === '--help') help = true;\n else if (token === '--write') write = true;\n else if (token === '--only') {\n only = ids(argv[index + 1] ?? '');\n index += 1;\n } else if (token.startsWith('--only=')) only = ids(token.slice('--only='.length));\n else if (token.startsWith('-')) unknown ??= token;\n else target ??= token;\n }\n return { target, write, only, help, unknown };\n}\n\nfunction describe(file: MigrateFileResult): string {\n return file.edits.map((edit) => `${edit.codemod}: ${String(edit.count)} line(s)`).join(', ');\n}\n\nexport async function runMigrateCommand(argv: readonly string[]): Promise<number> {\n const args = parseArgs(argv);\n if (args.help) {\n process.stdout.write(MIGRATE_HELP);\n return 0;\n }\n if (args.unknown !== undefined) {\n process.stderr.write(`pll migrate: unknown option ${args.unknown}\\n`);\n return 1;\n }\n if (args.target === undefined) {\n process.stderr.write('pll migrate: a path is required. Try `pll migrate --help`.\\n');\n return 1;\n }\n let result;\n try {\n result = await runMigrate(args.target, {\n write: args.write,\n ...(args.only === undefined ? {} : { only: args.only }),\n });\n } catch (error) {\n process.stderr.write(\n `pll migrate: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n return 1;\n }\n for (const file of result.files) {\n if (!file.changed) continue;\n process.stdout.write(\n `${args.write ? 'migrated' : 'would migrate'} ${file.file} (${describe(file)})\\n`,\n );\n }\n process.stdout.write(\n `\\n${args.write ? 'Migrated' : 'Would migrate'} ${String(result.changedCount)} file(s).` +\n `${args.write ? '' : ' Re-run with --write to apply.'}\\n`,\n );\n for (const { id, notice } of CODEMODS) {\n if (notice !== undefined && (result.byCodemod[id] ?? 0) > 0) {\n process.stdout.write(`\\nNote (${id}): ${notice}\\n`);\n }\n }\n const conflicted = result.files.filter((file) => file.conflicts.length > 0);\n if (conflicted.length === 0) return 0;\n process.stdout.write(`\\n${String(conflicted.length)} file(s) need manual attention:\\n`);\n for (const file of conflicted) {\n for (const item of file.conflicts) {\n const where = item.line === undefined ? file.file : `${file.file}:${String(item.line)}`;\n process.stdout.write(` ${where}: ${item.reason}\\n`);\n }\n }\n return 3;\n}\n","/** Terminal rendering of a doctor report. */\nimport type { DoctorReport } from './types';\n\nconst LEVEL_LABEL = { error: 'ERROR', warning: 'WARN ', info: 'INFO ' } as const;\n\n/** @internal */\nexport function formatReport(report: DoctorReport): string {\n const lines: string[] = [`pll doctor — ${report.url}`, ''];\n if (report.findings.length === 0) {\n lines.push('No findings. The preview response carries the runtime, a frame-ancestors');\n lines.push('policy, and bindings; the public response carries none of them.', '');\n return lines.join('\\n');\n }\n for (const finding of report.findings) {\n lines.push(`${LEVEL_LABEL[finding.level]} ${finding.code} ${finding.title}`);\n lines.push(` ${finding.detail}`);\n if (finding.remedy !== '') lines.push(` → ${finding.remedy}`);\n lines.push('');\n }\n lines.push(`${String(report.errors)} error(s), ${String(report.warnings)} warning(s).`, '');\n return lines.join('\\n');\n}\n","/**\n * Every diagnostic code the runtime and tools emit, so a consumer can branch\n * on `e.code` instead of matching message text. A code is never reused for a\n * different meaning; a retired one stays reserved.\n *\n * Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than\n * reading it from this record: the frozen table would then ship in the inline\n * runtime for the sake of six characters — it did, 1 287 B in every page, for\n * the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`\n * now holds the artifact free of it. Server-side tools may import it.\n */\n\n/**\n * Every diagnostic code the runtime can report, by name.\n *\n * ```ts\n * client.events.on('error', (e) => {\n * if (e.code === DIAGNOSTIC_CODES.TransformThrew) reportToSentry(e.error);\n * });\n * ```\n */\nexport const DIAGNOSTIC_CODES = Object.freeze({\n /** No trusted origin configured in production; nothing will be accepted. */\n NoTrustedOrigin: 'LP0101',\n /** Origin trust rests on `document.referrer`, so any framing site is trusted. */\n ReferrerOnlyTrust: 'LP0102',\n /** A plugin declares a runtime range this runtime does not satisfy; it was refused. */\n PluginIncompatible: 'LP0103',\n /** The page carries the lean runtime and needs a feature that profile leaves out. */\n ProfileFeatureOmitted: 'LP0104',\n\n /** An update named a field with no binding anchor on the page. */\n OrphanField: 'LP0201',\n /** Owner scoping is on and the update names no document it could belong to. */\n UnattributableUpdate: 'LP0202',\n\n /** The visibility gate held offscreen writes back until they scroll into view. */\n VisibilityGateDeferred: 'LP0301',\n\n /** A value was refused because the attribute or the value itself is unsafe. */\n UnsafeAttributeWrite: 'LP0401',\n /** A text element has structured children, so replacing its text was skipped. */\n TextTargetHasChildren: 'LP0402',\n /** A structural container has no array template, so the update was skipped. */\n MissingArrayTemplate: 'LP0403',\n /** A structural item has no `id`; it pairs positionally, so an insert re-renders every row after it. */\n StructuralItemUnkeyed: 'LP0404',\n /** Two structural items share a key; later ones pair positionally. */\n StructuralDuplicateKey: 'LP0405',\n /** Every structural key changed while the length did not; the source generates keys per message. */\n StructuralUnstableKeys: 'LP0406',\n /** A binding asks for a delivery strategy this release does not have; it is left unchanged. */\n UnsupportedStrategy: 'LP0407',\n /** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */\n UnknownValueFormat: 'LP0408',\n /** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */\n SanitizerDroppedAttribute: 'LP0409',\n /** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */\n UnrenderedBlockKept: 'LP0410',\n /** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */\n UnfaithfulPatch: 'LP0411',\n /** The first write to a date, number or checkbox binding replaced a different reading of the same value. */\n ServerFormatReplaced: 'LP0412',\n /** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */\n UnrenderedBlockLost: 'LP0413',\n\n /** A message was rejected before it reached the update pipeline. */\n MessageRejected: 'LP0501',\n /** A preview token was rejected. */\n TokenRejected: 'LP0502',\n /** A trusted origin sent a message this protocol version does not recognise. */\n ProtocolShapeUnknown: 'LP0503',\n\n /** A consumer event handler threw. */\n HandlerThrew: 'LP0601',\n /** A consumer transform threw; the original value was kept. */\n TransformThrew: 'LP0602',\n /** A renderer threw while writing a value. */\n RendererThrew: 'LP0603',\n // LP0604 is reserved and unassigned; codes are never reused or renumbered.\n /** Runtime startup failed. */\n StartupFailed: 'LP0605',\n /** Sending the ready handshake failed. */\n ReadyFailed: 'LP0606',\n /** The page declared hydration, but no React commit or Vue mount came within the cap; the runtime started without waiting. */\n HydrationWaitTimedOut: 'LP0607',\n\n /** The audit found no runtime in a response that carried preview intent. */\n AuditRuntimeMissing: 'LP0701',\n /** The preview response declares no `frame-ancestors`. */\n AuditNoFrameAncestors: 'LP0702',\n /** `X-Frame-Options` forbids framing, which no CSP can undo; `SAMEORIGIN` forbids it from another origin only. */\n AuditFrameOptionsBlocks: 'LP0703',\n /** Binding attributes are served to anonymous visitors. */\n AuditBindingsExposed: 'LP0704',\n /** More bindings than the default visibility gate will write eagerly. */\n AuditGateThresholdExceeded: 'LP0705',\n /** Owner markers exist, but some bindings are outside all of them. */\n AuditUnownedBindings: 'LP0706',\n /** The preview response carries no bindings at all. */\n AuditNoBindings: 'LP0707',\n /** The URL did not return an HTML page, so nothing else can be judged. */\n AuditNotAPage: 'LP0708',\n /** A fragment request failed (network, timeout, server error); the boundary was patched instead. */\n FragmentRequestFailed: 'LP0801',\n /** The fragment response had the wrong content type or shape; the boundary was patched instead. */\n FragmentResponseInvalid: 'LP0802',\n /** The fragment endpoint refused the preview (not authorized); the boundary was patched instead. */\n FragmentUnauthorized: 'LP0803',\n /** A fragment response arrived for a revision that was already superseded and was discarded. */\n FragmentSuperseded: 'LP0804',\n /** A route refresh was refused: the loop guard, or the strategy's minimum interval. */\n RouteRefreshLoop: 'LP0805',\n /** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */\n FragmentStrategyUnavailable: 'LP0806',\n /** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */\n UnboundChangeRefresh: 'LP0807',\n /** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */\n V2ReadinessGap: 'LP0709',\n /** The preview runtime is served to anonymous visitors, not only inside the admin frame. */\n RuntimeOnPublicPage: 'LP0710',\n} as const);\n\n/** A diagnostic code, as it appears in log output and on the `error` event. */\nexport type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];\n","/**\n * `frame-ancestors` matching by the CSP3 source-expression rules. The audit\n * judges origins, so path parts of a host-source are ignored.\n */\n\nconst DEFAULT_PORT: Readonly<Record<string, string>> = {\n http: '80',\n https: '443',\n ws: '80',\n wss: '443',\n};\nconst SCHEME_SOURCE = /^([a-z][a-z0-9+.-]*):$/u;\nconst HOST_SOURCE =\n /^(?:([a-z][a-z0-9+.-]*):\\/\\/)?(\\*|(?:\\*\\.)?[a-z0-9-]+(?:\\.[a-z0-9-]+)*\\.?)(?::(\\*|\\d+))?(?:\\/.*)?$/u;\n\n/** The `frame-ancestors` directive of a policy, verbatim, or `undefined` when it has none. */\nexport function frameAncestorsOf(csp: string | undefined): string | undefined {\n if (csp === undefined) return undefined;\n for (const directive of csp.split(';')) {\n const trimmed = directive.trim();\n if (/^frame-ancestors(?:\\s|$)/iu.test(trimmed)) return trimmed;\n }\n return undefined;\n}\n\nfunction schemeOf(url: URL): string {\n return url.protocol.slice(0, -1).toLowerCase();\n}\n\nfunction portOf(url: URL): string {\n return url.port === '' ? (DEFAULT_PORT[schemeOf(url)] ?? '') : url.port;\n}\n\nfunction schemeMatches(expression: string, actual: string): boolean {\n return (\n expression === actual ||\n (expression === 'http' && actual === 'https') ||\n (expression === 'ws' && actual === 'wss')\n );\n}\n\nfunction hostMatches(pattern: string, host: string): boolean {\n if (pattern === '*') return true;\n const wanted = pattern.replace(/\\.$/u, '');\n const actual = host.replace(/\\.$/u, '');\n if (wanted.startsWith('*.')) {\n return actual.endsWith(wanted.slice(1)) && actual.length > wanted.length - 1;\n }\n return wanted === actual;\n}\n\nfunction isSelf(admin: URL, page: URL): boolean {\n if (admin.hostname !== page.hostname) return false;\n const adminScheme = schemeOf(admin);\n const pageScheme = schemeOf(page);\n if (adminScheme !== pageScheme && !(pageScheme === 'http' && adminScheme === 'https')) {\n return false;\n }\n return portOf(admin) === portOf(page) || (admin.port === '' && page.port === '');\n}\n\nfunction sourceMatches(source: string, admin: URL, page: URL): boolean {\n const scheme = SCHEME_SOURCE.exec(source);\n if (scheme?.[1] !== undefined) return schemeMatches(scheme[1], schemeOf(admin));\n const host = HOST_SOURCE.exec(source);\n if (host === null) return false;\n const expressionScheme = host[1];\n const expressionHost = host[2] ?? '';\n const expressionPort = host[3];\n const requiredScheme = expressionScheme ?? schemeOf(page);\n if (!schemeMatches(requiredScheme, schemeOf(admin))) return false;\n if (!hostMatches(expressionHost, admin.hostname)) return false;\n if (expressionPort === undefined) return admin.port === '';\n return expressionPort === '*' || expressionPort === portOf(admin);\n}\n\n/** Whether the directive admits `admin` as an ancestor of `page`. */\nexport function frameAncestorsAdmits(directive: string, admin: URL, page: URL): boolean {\n const sources = directive\n .split(/\\s+/u)\n .slice(1)\n .filter((source) => source.length > 0)\n .map((source) => source.toLowerCase());\n if (sources.length === 0 || (sources.length === 1 && sources[0] === \"'none'\")) return false;\n for (const source of sources) {\n if (source === \"'self'\") {\n if (isSelf(admin, page)) return true;\n } else if (source === '*') {\n return true;\n } else if (!source.startsWith(\"'\") && sourceMatches(source, admin, page)) {\n return true;\n }\n }\n return false;\n}\n","/**\n * The inline script's configuration and its positional wire order: the\n * generator writes the tuple, `src/core/runtime.ts` destructures it, and\n * `INLINE_CONFIG_KEYS` is where they agree. Append only, never reorder.\n */\n\nimport type { DefaultsProfile } from '@/types/defaults-profile';\n\nexport interface InlineScriptConfig {\n /** Trusted admin origins, merged with the detected ones. */\n readonly allowedOrigins?: readonly string[];\n /** Payload origin; every update is then re-fetched through the REST API with credentials. Requires `mergeDepth`. */\n readonly serverURL?: string;\n /** REST route prefix used with `serverURL`. Default `/api`. */\n readonly apiRoute?: string;\n /** Population depth used with `serverURL`. Required with `serverURL` unless `defaults: 'v1'`. */\n readonly mergeDepth?: number;\n /** Verbose console logging. Default `false`. */\n readonly debug?: boolean;\n /** Debounce window for incoming updates in ms. Default `50`. */\n readonly debounceMs?: number;\n /** Mount the screen-reader live region. Default `true`. */\n readonly enableA11y?: boolean;\n /** Heartbeat timeout in ms; `0` disables it (default), because the admin posts only on edits. */\n readonly heartbeatMs?: number;\n /** Apply every update regardless of viewport position. Default `false`. */\n readonly disableVisibilityGate?: boolean;\n /** Cache size above which off-screen updates wait for intersection. Default `50`. */\n readonly visibilityGateThreshold?: number;\n /** `rootMargin` of the IntersectionObserver. Default `'200px'`. */\n readonly intersectionRootMargin?: string;\n /** Ignore `document.referrer` as an origin source. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly disableReferrerDetection?: boolean;\n /** Disable the dev-mode localhost matcher (any port on `localhost`/`127.0.0.1`). Default `false`. */\n readonly disableLocalhostMatching?: boolean;\n /** Update only bindings under a matching `data-payload-owner`. Default `false`. */\n readonly scopeBindingsByOwner?: boolean;\n /** Skip bindings whose value did not change. Default `true`; `defaults: 'v1'` sets `false`. */\n readonly skipUnchanged?: boolean;\n /** Scroll the preview to the field being edited. Default `false`. */\n readonly revealEditedField?: boolean;\n /** Which windows may post updates. Default `'parent-or-opener'`; `defaults: 'v1'` sets `'any'`. */\n readonly eventSourcePolicy?: 'any' | 'parent-or-opener';\n /** Sanitizer policy for rich text and HTML writes. Default `'strict'`; `defaults: 'v1'` sets `'compat'`. */\n readonly sanitizerPolicy?: 'compat' | 'strict';\n /** Same-origin path of a fragment endpoint; the script then carries the fragment client ahead of the runtime (ADR 0011). */\n readonly fragmentEndpoint?: string;\n /**\n * Carry the route strategy, so a binding in `<head>` or one marked\n * `data-payload-strategy=\"route\"` refreshes the route. `fragmentEndpoint`\n * implies it — the fragment prelude already contains it. Default `false`.\n */\n readonly routeStrategy?: boolean;\n /**\n * The 2.0 name for `onUnfaithfulPatch`, kept until 3.0. `'route'` means\n * `'escalate'`, `'ignore'` means `'ignore'`.\n *\n * @deprecated Renamed to `onUnfaithfulPatch`.\n */\n readonly onUnboundChange?: 'ignore' | 'route';\n /**\n * What to do when the runtime knows a patch cannot reach what the server\n * would have drawn. `'escalate'` (the default) hands the region to the\n * fragment strategy when a boundary covers it and to the route otherwise, so\n * it needs `fragmentEndpoint` or `routeStrategy` to do anything. `'warn'`\n * reports LP0411 and keeps the patch; `'ignore'` keeps it silently.\n */\n readonly onUnfaithfulPatch?: 'ignore' | 'warn' | 'escalate';\n /**\n * Find bindings by value on the connection's first message (ADR 0014): a\n * scalar whose value is the whole content of exactly one element is bound\n * to it as if `data-payload-field` stood there. Default `'off'`.\n */\n readonly autoBind?: 'off' | 'unique';\n /**\n * The framework that hydrates this page (ADR 0015). Under `'react'` the\n * runtime holds its first write until React has committed the tree that\n * holds the bindings — otherwise React finds markup it did not render,\n * throws `Hydration failed` and regenerates the tree, and the write is gone.\n * Under `'vue'` it holds the write until Vue has mounted the app around them\n * — otherwise Vue's hydration repairs the write back to the server's value,\n * quietly. The Next.js and Nuxt adapters set it on every script they emit; a\n * page built by hand with `generateInlineScript()` may. Omitted: the runtime\n * starts on `DOMContentLoaded`, as on a static page.\n */\n readonly hydration?: 'react' | 'vue';\n /**\n * Which defaults the omitted options fall back to, resolved by the generator\n * rather than the runtime, whose own fallbacks are the 2.0 rows: `'v1'`\n * writes its four runtime rows into their slots (an explicit option still\n * wins) and relaxes the `mergeDepth` check. The resolved value always\n * travels, in the last slot, so a reader of the served page knows what an\n * empty slot means instead of guessing it — `pll doctor --v2` reads it. The\n * runtime does not: every row the profile decides is already in its slot.\n */\n readonly defaults?: DefaultsProfile;\n /**\n * A runtime artifact to embed instead of the full one — today only\n * `LEAN_RUNTIME` from `payload-live-preview/lean`, which leaves out the\n * strategies, the keyed morph, the structural arrays, the item templates, the\n * announcer and auto-binding (about 7 KB gzip less on the page) and reports\n * LP0104 when a page needs one of them.\n *\n * It is an imported value rather than a `profile: 'lean'` string on purpose:\n * a second artifact behind a string option would sit in every build that can\n * reach the generator; measured, it grew each adapter entry by the artifact's\n * whole size. This way the bytes follow the import.\n *\n * Not serialized: it decides which bytes are emitted, not how they behave.\n */\n readonly runtime?: RuntimeArtifact;\n}\n\n/**\n * A runtime build this package produces. `source` is the IIFE the page runs;\n * the two digests describe the same bytes as a servable asset, so asset\n * delivery can hash-name and SRI-verify whichever artifact was chosen without\n * hashing anything at request time.\n */\nexport interface RuntimeArtifact {\n readonly profile: 'lean';\n readonly source: string;\n /** Short content hash, for the asset's file name. */\n readonly contentHash: string;\n /** `sha384-…`, for the bootstrap's `integrity` attribute. */\n readonly integrity: string;\n}\n\n/** Keys that travel in the wire tuple, in slot order. */\nexport const INLINE_CONFIG_KEYS = [\n 'allowedOrigins',\n 'serverURL',\n 'apiRoute',\n 'mergeDepth',\n 'debug',\n 'debounceMs',\n 'enableA11y',\n 'heartbeatMs',\n 'disableVisibilityGate',\n 'visibilityGateThreshold',\n 'intersectionRootMargin',\n 'disableReferrerDetection',\n 'disableLocalhostMatching',\n 'scopeBindingsByOwner',\n 'skipUnchanged',\n 'eventSourcePolicy',\n 'sanitizerPolicy',\n 'fragmentEndpoint',\n 'revealEditedField',\n 'routeStrategy',\n 'onUnboundChange',\n 'onUnfaithfulPatch',\n 'autoBind',\n 'hydration',\n 'defaults',\n] as const satisfies readonly Exclude<keyof InlineScriptConfig, 'runtime'>[];\n","/**\n * The two defaults profiles, row by row. 2.0 ships `v2`; `defaults: 'v1'` opts\n * back into the 1.x table for a staged migration. Each row belongs to exactly\n * one side — the adapter's request decision or the browser runtime — and a\n * test asserts the profile assigns every readiness row that has an option, so\n * a row added later cannot be forgotten. See ADR 0007.\n *\n * It lives in the leaf `types` domain, like `merge-depth.ts`, because the\n * inline generator resolves the profile too, and the generator is server-side\n * code that may not reach the browser runtime in `core`.\n */\n\n/** `'v2'` is the 2.0 default; `'v1'` is the 1.x table. */\nexport type DefaultsProfile = 'v1' | 'v2';\n\n/** How the runtime decides which windows may post updates. */\nexport type EventSourcePolicy = 'any' | 'parent-or-opener';\n\n/** Readiness rows that are options, keyed by the option they set. */\nexport const READINESS_ROWS = Object.freeze({\n strict: 'production response changes require an authorized context',\n previewSignals: 'query-only intent signal',\n disableReferrerDetection: 'referrer trust off',\n eventSourcePolicy: 'messages must come from parent/opener',\n skipUnchanged: 'skip unchanged bindings by default',\n sanitizerPolicy: 'hardened sanitizer id/data-* policy',\n} as const);\n\n/** Options an adapter's request decision reads from the profile. */\nexport interface AdapterProfileDefaults {\n readonly strict: boolean;\n readonly previewSignals: readonly ('query' | 'fetch-dest' | 'referer')[];\n}\n\n/** Options the browser runtime reads from the profile (through the inline configuration). */\nexport interface RuntimeProfileDefaults {\n readonly disableReferrerDetection: boolean;\n readonly eventSourcePolicy: EventSourcePolicy;\n readonly skipUnchanged: boolean;\n readonly sanitizerPolicy: 'compat' | 'strict';\n}\n\nexport const V2_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: true,\n previewSignals: Object.freeze(['query'] as const),\n});\n\nexport const V2_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: true,\n eventSourcePolicy: 'parent-or-opener',\n skipUnchanged: true,\n sanitizerPolicy: 'strict',\n});\n\n/** The 1.x table, spelled out so the profiles compare row by row. */\nexport const V1_ADAPTER_DEFAULTS: AdapterProfileDefaults = Object.freeze({\n strict: false,\n previewSignals: Object.freeze(['query', 'fetch-dest', 'referer'] as const),\n});\n\nexport const V1_RUNTIME_DEFAULTS: RuntimeProfileDefaults = Object.freeze({\n disableReferrerDetection: false,\n eventSourcePolicy: 'any',\n skipUnchanged: false,\n sanitizerPolicy: 'compat',\n});\n\n/** Only an explicit `'v1'` opts out; everything else gets the hardened rows. */\nexport function adapterDefaultsFor(profile: DefaultsProfile | undefined): AdapterProfileDefaults {\n return profile === 'v1' ? V1_ADAPTER_DEFAULTS : V2_ADAPTER_DEFAULTS;\n}\n\nexport function runtimeDefaultsFor(profile: DefaultsProfile | undefined): RuntimeProfileDefaults {\n return profile === 'v1' ? V1_RUNTIME_DEFAULTS : V2_RUNTIME_DEFAULTS;\n}\n","/**\n * `pll doctor --v2`: read the served inline configuration and report each\n * runtime row still at its 1.x value (ADR 0007).\n *\n * An empty slot means whatever the generation that wrote the script meant by\n * it, and that is exactly what changed between 1.x and 2.0. So the script\n * names the defaults it was resolved against, in its last slot, and this reads\n * the answer instead of guessing it. A script without the marker predates it —\n * 1.x or 2.0.0-beta.0 — and is read as 1.x, with a line that says so.\n */\nimport { INLINE_CONFIG_KEYS } from '@/types/inline-config';\nimport {\n V1_RUNTIME_DEFAULTS,\n V2_RUNTIME_DEFAULTS,\n type RuntimeProfileDefaults,\n} from '@/types/defaults-profile';\nimport type { DoctorFinding, DoctorProbe } from './types';\n\nconst CONFIG_MARKER = 'var __LIVE_PREVIEW_CONFIG__=';\nconst DEFAULTS_SLOT = INLINE_CONFIG_KEYS.indexOf('defaults');\n\n/** A runtime row of the readiness table, as a finding words it. */\ninterface ReadinessRow {\n readonly key: keyof RuntimeProfileDefaults;\n readonly title: string;\n /** What the 1.x value does. */\n readonly effect: string;\n /** What has to hold before the row can take its 2.0 value. */\n readonly condition: string;\n}\n\nconst ROWS: readonly ReadinessRow[] = [\n {\n key: 'disableReferrerDetection',\n title: 'Referrer trust is still on',\n effect: 'the runtime accepts the admin referer as a preview signal.',\n condition: 'no preview flow relies on the admin referer alone',\n },\n {\n key: 'eventSourcePolicy',\n title: 'Messages are accepted from any window',\n effect: 'any window that passes the origin check may post updates.',\n condition: 'no window but the parent or opener posts updates',\n },\n {\n key: 'sanitizerPolicy',\n title: 'Sanitizer is in compat mode',\n effect: 'id and every data-* pass.',\n condition: 'rich text no longer relies on `id` or `data-*`',\n },\n {\n key: 'skipUnchanged',\n title: 'Unchanged bindings are re-applied every message',\n effect: 'every binding is written again on every message.',\n condition: 'no renderer relies on running again for a value that did not change',\n },\n];\n\n/** Where a row's value came from, which decides what the reader can change. */\ntype Origin = 'profile' | 'explicit' | 'unmarked';\n\nconst ORIGIN_DETAIL: Readonly<Record<Origin, string>> = {\n profile: \"The script was generated with `defaults: 'v1'`.\",\n explicit: 'The script sets it explicitly.',\n unmarked: 'The script names no defaults, so its empty slot is read as the 1.x value.',\n};\n\nconst UNREADABLE: DoctorFinding = {\n code: 'LP0709',\n level: 'info',\n title: 'Could not read the inline configuration for a v2 readiness check',\n detail: 'The preview response carried no readable `__LIVE_PREVIEW_CONFIG__` inline script.',\n remedy:\n 'Run this against a page with the inline runtime (not loader mode without a preview context). ' +\n 'A preview behind authorizePreview serves it only to a request with credentials: pass them with --header, or a signed token as ?previewToken=… in the URL.',\n};\n\nconst UNMARKED: DoctorFinding = {\n code: 'LP0709',\n level: 'info',\n title: 'The inline configuration does not say which defaults it was generated against',\n detail:\n 'Scripts carry a `defaults` marker from 2.0.0-rc.1 on; this one has none, so a 1.x or 2.0.0-beta.0 generator wrote it. An empty slot is read as its 1.x value, which is what a 1.x runtime runs.',\n remedy:\n 'On 1.x the warnings stand as written. On 2.0.0-beta.0 an empty slot already runs its 2.0 value, so a warning about one does not apply there; upgrade and run `pll doctor --v2` again to read the marker.',\n};\n\n/**\n * The array literal after the marker, read as JSON. The generator writes `,,`\n * for unset slots, which JSON cannot express, so elisions outside strings\n * become `null`. Never evaluated: a page controls this text.\n */\nexport function readInlineConfig(body: string): readonly unknown[] | undefined {\n const start = body.indexOf(CONFIG_MARKER);\n if (start === -1) return undefined;\n const from = start + CONFIG_MARKER.length;\n if (body[from] !== '[') return undefined;\n let depth = 0;\n let inString = false;\n let previous = '';\n let json = '';\n for (let index = from; index < body.length; index += 1) {\n const char = body[index] ?? '';\n if (inString) {\n json += char;\n if (char === '\\\\') {\n json += body[index + 1] ?? '';\n index += 1;\n } else if (char === '\"') {\n inString = false;\n // A closed string is a value: without this, the next `,` reads as an elision.\n previous = '\"';\n }\n continue;\n }\n if (char === '\"') {\n inString = true;\n json += char;\n continue;\n }\n if (/\\s/u.test(char)) continue;\n const elision =\n (char === ',' && (previous === ',' || previous === '[')) ||\n (char === ']' && previous === ',');\n if (elision) json += 'null';\n json += char;\n previous = char;\n if (char === '[') depth += 1;\n if (char === ']') {\n depth -= 1;\n if (depth === 0) break;\n }\n }\n if (depth !== 0) return undefined;\n try {\n const value: unknown = JSON.parse(json);\n return Array.isArray(value) ? (value as readonly unknown[]) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** `'compat'` rather than `\"compat\"`: remedies are read as source code. */\nfunction literal(value: unknown): string {\n return typeof value === 'string' ? `'${value}'` : JSON.stringify(value);\n}\n\nfunction remedyFor(origin: Origin, row: ReadinessRow, value: unknown): string {\n const wanted = `\\`${row.key}: ${literal(V2_RUNTIME_DEFAULTS[row.key])}\\``;\n switch (origin) {\n case 'profile':\n return `Set ${wanted} or drop \\`defaults: 'v1'\\` once ${row.condition}.`;\n case 'explicit':\n return `Drop the explicit \\`${row.key}: ${literal(value)}\\` once ${row.condition}; 2.0 defaults to ${wanted}.`;\n case 'unmarked':\n // 1.8.1 has no `defaults` option and three of the four rows are not\n // inline options there, so the way out is the upgrade itself.\n return `Upgrading to 2.0 sets ${wanted}; check first that ${row.condition}.`;\n }\n}\n\nfunction gap(row: ReadinessRow, value: unknown, origin: Origin): DoctorFinding {\n return {\n code: 'LP0709',\n level: 'warning',\n title: row.title,\n detail: `${row.key} is ${literal(value)}: ${row.effect} ${ORIGIN_DETAIL[origin]}`,\n remedy: remedyFor(origin, row, value),\n };\n}\n\nfunction unknownGeneration(marker: unknown): DoctorFinding {\n return {\n code: 'LP0709',\n level: 'info',\n title: 'The inline configuration names defaults this doctor does not know',\n detail: `Its \\`defaults\\` marker is ${JSON.stringify(marker)}; this version reads 'v1' and 'v2', so no row was judged.`,\n remedy: 'Run the `pll doctor` of the package version that generated the page.',\n };\n}\n\n/**\n * One `LP0709` finding per runtime row not yet at its 2.0 value. An empty slot\n * has the value of the generation the script names, and the 1.x value when it\n * names none; a generation this version does not know is not judged at all.\n * @internal\n */\nexport function analyzeV2Readiness(probe: DoctorProbe): readonly DoctorFinding[] {\n const config = readInlineConfig(probe.previewResponse.body);\n if (config === undefined) return [UNREADABLE];\n const marker = config[DEFAULTS_SLOT] ?? undefined;\n if (marker !== undefined && marker !== 'v1' && marker !== 'v2') {\n return [unknownGeneration(marker)];\n }\n const generation = marker;\n const fallback = generation === 'v2' ? V2_RUNTIME_DEFAULTS : V1_RUNTIME_DEFAULTS;\n const findings = ROWS.flatMap((row) => {\n const slot = config[INLINE_CONFIG_KEYS.indexOf(row.key)] ?? undefined;\n const value = slot ?? fallback[row.key];\n if (value === V2_RUNTIME_DEFAULTS[row.key]) return [];\n const origin: Origin =\n generation === 'v1' ? 'profile' : slot === undefined ? 'unmarked' : 'explicit';\n return [gap(row, value, origin)];\n });\n return generation === undefined ? [...findings, UNMARKED] : findings;\n}\n","/**\n * The `pll doctor` audit: judge what a deployment serves from two fetches of\n * one URL, as a visitor and as the admin's iframe. Pure — the caller fetches.\n * Markup is read with regular expressions, which is enough to count\n * attributes and find the runtime marker; findings say what was observed.\n */\nimport { DIAGNOSTIC_CODES } from '../core/diagnostic-codes';\nimport { frameAncestorsAdmits, frameAncestorsOf } from './csp';\nimport { analyzeV2Readiness } from './readiness';\nimport type {\n DoctorContext,\n DoctorFinding,\n DoctorProbe,\n DoctorReport,\n DoctorResponse,\n} from './types';\n\n/** Survives minification; the banner comment does not. */\nconst RUNTIME_MARKER = '__LIVE_PREVIEW_CONFIG__';\nconst BINDING_ATTRIBUTE = /\\bdata-payload-field\\s*=/gu;\nconst OWNER_ATTRIBUTE = /\\bdata-payload-owner\\s*=/gu;\n/** Mirrors the scheduler default; the audit must not import the runtime. */\nconst DEFAULT_VISIBILITY_GATE_THRESHOLD = 50;\nconst LEVEL_ORDER = { error: 0, warning: 1, info: 2 } as const;\n// An end tag may carry junk before its `>`; browsers still close on it, so the\n// pattern must too, or a `</script foo>` would leave the script body counted.\nconst NON_MARKUP =\n /<script\\b[^>]*>[\\s\\S]*?<\\/script\\b[^>]*>|<style\\b[^>]*>[\\s\\S]*?<\\/style\\b[^>]*>|<!--[\\s\\S]*?-->/giu;\n\n/**\n * The runtime's own source spells `data-payload-field=` in a message, so\n * scripts must not be counted. This is a counter's view of the page, not a\n * sanitiser — nothing here is rendered — but it strips to a fixed point all\n * the same, so a block that only appears once its neighbour is gone is still\n * removed rather than counted.\n */\nfunction visibleMarkup(body: string): string {\n let markup = body;\n for (;;) {\n const stripped = markup.replace(NON_MARKUP, '');\n if (stripped === markup) return markup;\n markup = stripped;\n }\n}\n\nfunction count(haystack: string, pattern: RegExp): number {\n return haystack.match(pattern)?.length ?? 0;\n}\n\n/** Bindings before the first owner marker are certainly unowned; nesting is not modelled, so this under-reports. */\nfunction unownedBindingsBeforeFirstOwner(markup: string): number {\n const firstOwner = markup.search(/\\bdata-payload-owner\\s*=/u);\n return firstOwner === -1 ? 0 : count(markup.slice(0, firstOwner), BINDING_ATTRIBUTE);\n}\n\nfunction tryUrl(value: string | undefined): URL | undefined {\n if (value === undefined) return undefined;\n try {\n return new URL(value);\n } catch {\n return undefined;\n }\n}\n\n/** Why the preview response cannot be audited as a page; the public one may legitimately be gated. */\nfunction describeNonPage(preview: DoctorResponse): DoctorFinding | undefined {\n if (preview.status >= 300 && preview.status <= 399) {\n const location = preview.headers['location'];\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request was redirected (${String(preview.status)})${location === undefined ? '' : ` to ${location}`}`,\n detail:\n 'The audit does not follow redirects: the page at the end of one is a different ' +\n 'resource, usually a login or a canonical host, and judging it would say nothing ' +\n 'about this URL.',\n remedy:\n 'The request carried the intent parameter (?preview=true, or the --param name), the ' +\n \"way the admin's iframe loads the page, so a rule that redirects on that query redirects \" +\n 'the iframe too. A redirect to a login means the route needs authentication that a ' +\n \"plain probe cannot supply: pass an editor's credentials with --header, or a signed token as ?previewToken=… in the URL. Probe the final \" +\n 'URL directly only when the redirect has nothing to do with either.',\n };\n }\n if (preview.status < 200 || preview.status > 299) {\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request returned ${String(preview.status)}, not a page`,\n detail:\n 'Nothing below this can be judged: a status outside 2xx means the body is an ' +\n 'error page or empty.',\n remedy: 'Check the URL.',\n };\n }\n if (preview.body.trim() === '') {\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request returned ${String(preview.status)} with an empty body`,\n detail:\n 'A 2xx status with nothing in it — 204 and 205 are defined that way — is not a page, ' +\n 'so its missing runtime and missing bindings say nothing.',\n remedy: 'Point the audit at a route that renders a document.',\n };\n }\n const contentType = preview.headers['content-type'];\n if (contentType !== undefined && !contentType.toLowerCase().includes('html')) {\n return {\n code: 'LP0708',\n level: 'error',\n title: `The preview request returned ${contentType}, not HTML`,\n detail:\n 'The audit reads a rendered page. A non-HTML response has no runtime and no ' +\n 'bindings by definition, so reporting their absence would say nothing.',\n remedy: 'Point the audit at a page route rather than an API or an asset.',\n };\n }\n return undefined;\n}\n\nfunction framingFindings(\n preview: DoctorResponse,\n runtimeInPreview: boolean,\n context: DoctorContext,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n const page = tryUrl(context.url);\n const admin = tryUrl(context.adminOrigin);\n const sameOrigin = admin !== undefined && page?.origin === admin.origin;\n const frameAncestors = frameAncestorsOf(preview.headers['content-security-policy']);\n if (runtimeInPreview && frameAncestors === undefined) {\n findings.push({\n code: 'LP0702',\n level: 'warning',\n title: 'Preview response declares no frame-ancestors',\n detail:\n 'The runtime is injected but the response carries no frame-ancestors directive, ' +\n 'so nothing states which origins may embed this page.',\n remedy:\n 'Let the adapter manage CSP, or set frame-ancestors yourself to the admin origin. ' +\n 'Without it you are relying on the absence of a policy.',\n });\n } else if (frameAncestors !== undefined && context.adminOrigin !== undefined) {\n const admitted =\n admin !== undefined &&\n page !== undefined &&\n frameAncestorsAdmits(frameAncestors, admin, page);\n if (!admitted) {\n findings.push({\n code: 'LP0702',\n level: 'error',\n title: 'frame-ancestors does not admit the admin origin',\n detail:\n admin === undefined\n ? `\"${context.adminOrigin}\" is not an absolute URL, so no source expression can admit it.`\n : `Served: \"${frameAncestors}\". Expected it to allow ${admin.origin}.`,\n remedy:\n 'Add the admin origin to allowedOrigins so the adapter merges it into ' +\n 'frame-ancestors, or add it to your own policy.',\n });\n }\n }\n const frameOptions = preview.headers['x-frame-options'];\n const blocks =\n frameOptions !== undefined &&\n (/deny/iu.test(frameOptions) || (/sameorigin/iu.test(frameOptions) && !sameOrigin));\n if (blocks) {\n // `SAMEORIGIN` refuses a frame from *another* origin, so it is a verdict\n // about this preview only once the admin origin is known. Without --admin\n // the audit says what it saw and names the condition instead of asserting a\n // block it cannot have established: where the admin and the site share an\n // origin, the preview runs. `DENY` needs no origin to be a verdict.\n const judged = admin !== undefined || /deny/iu.test(frameOptions);\n findings.push(\n judged\n ? {\n code: 'LP0703',\n level: 'error',\n title: `X-Frame-Options: ${frameOptions} blocks the preview iframe`,\n detail:\n 'This header is older than CSP and browsers honour it independently. No ' +\n 'frame-ancestors directive can override it.',\n remedy:\n 'Remove X-Frame-Options for preview responses. It is usually set by a proxy ' +\n 'or a security middleware rather than by the app.',\n }\n : {\n code: 'LP0703',\n level: 'warning',\n title: `X-Frame-Options: ${frameOptions} blocks every frame from another origin`,\n detail:\n 'This header is older than CSP and browsers honour it independently, and no ' +\n 'frame-ancestors directive can override it. SAMEORIGIN refuses a frame from ' +\n 'another origin only, and no admin origin was given: whether it blocks this ' +\n 'preview depends on where the admin is served, which this probe cannot see.',\n remedy:\n 'Re-run with --admin <origin> to have it judged. If the admin is on another ' +\n 'origin, remove X-Frame-Options for preview responses; a proxy or a security ' +\n 'middleware usually sets it.',\n },\n );\n }\n return findings;\n}\n\nfunction bindingFindings(\n previewMarkup: string,\n publicMarkup: string,\n runtime: boolean,\n): DoctorFinding[] {\n const findings: DoctorFinding[] = [];\n const previewBindings = count(previewMarkup, BINDING_ATTRIBUTE);\n const publicBindings = count(publicMarkup, BINDING_ATTRIBUTE);\n const owners = count(previewMarkup, OWNER_ATTRIBUTE);\n if (publicBindings > 0) {\n findings.push({\n code: 'LP0704',\n level: 'warning',\n title: `${String(publicBindings)} binding attribute(s) served to anonymous visitors`,\n detail:\n 'A request with no preview intent received data-payload-field attributes. These ' +\n 'disclose the CMS field taxonomy, and any CSS keyed on them changes public layout ' +\n 'the moment emission is gated.',\n remedy:\n 'Gate binding emission on an authorized preview context — see ' +\n 'createPreviewBindings(), whose suppressed form emits nothing at all.',\n });\n }\n if (previewBindings > DEFAULT_VISIBILITY_GATE_THRESHOLD) {\n findings.push({\n code: 'LP0705',\n level: 'warning',\n title: `${String(previewBindings)} bindings exceed the default visibility gate`,\n detail:\n `Above visibilityGateThreshold (${String(DEFAULT_VISIBILITY_GATE_THRESHOLD)}) the ` +\n 'scheduler stops writing offscreen elements and buffers them until they scroll into ' +\n 'view. On a page nobody scrolls, that is never.',\n remedy:\n 'Raise visibilityGateThreshold if the whole page must stay live, or confirm that ' +\n 'deferring below the fold is acceptable here.',\n });\n }\n if (runtime && previewBindings === 0) {\n findings.push({\n code: 'LP0707',\n level: 'error',\n title: 'Preview response carries no bindings',\n detail:\n 'The runtime is present but there is not one data-payload-field element for it to ' +\n 'write into, so no edit can ever be visible on this page.',\n remedy:\n 'Add binding attributes to the markup. pll-codegen --inventory lists every field ' +\n 'the schema makes addressable.',\n });\n }\n const unowned = unownedBindingsBeforeFirstOwner(previewMarkup);\n if (owners > 0 && unowned > 0) {\n findings.push({\n code: 'LP0706',\n level: 'warning',\n title: `${String(unowned)} binding(s) outside every owner marker`,\n detail:\n `The page declares ${String(owners)} owner marker(s), so owner scoping is in use. ` +\n 'Bindings that belong to no owner receive nothing once scopeBindingsByOwner is on — ' +\n 'they fail closed.',\n remedy:\n 'Give every binding an owning ancestor, or leave scopeBindingsByOwner off until they ' +\n 'all have one. Counted before the first owner marker only, so the real number may be ' +\n 'higher.',\n });\n }\n return findings;\n}\n\n/** Audit a probed deployment. */\nexport function analyzeProbe(\n probe: DoctorProbe,\n context: DoctorContext & {\n readonly v2?: boolean;\n /** Whether the preview probe carried caller-supplied headers (`--header`). */\n readonly credentials?: boolean;\n },\n): DoctorReport {\n const { publicResponse: pub, previewResponse: preview } = probe;\n const notAPage = describeNonPage(preview);\n if (notAPage !== undefined) {\n return { url: context.url, findings: [notAPage], errors: 1, warnings: 0 };\n }\n const runtimeInPreview = preview.body.includes(RUNTIME_MARKER);\n const findings: DoctorFinding[] = [];\n if (!runtimeInPreview) {\n findings.push(\n context.credentials === true\n ? {\n code: 'LP0701',\n level: 'warning',\n title: 'No inline runtime in the preview response',\n detail:\n `The preview request returned ${String(preview.status)} without the inline ` +\n 'runtime, although it carried credentials (--header, or ?previewToken= in the URL). Three readings: ' +\n 'those credentials were not accepted — expired, issued for another page, or not ' +\n 'what authorizePreview reads — an adapter that did not recognise the request as a ' +\n 'preview, or a consumer that starts LivePreviewClient itself.',\n remedy:\n 'Check that the credentials are current and are the ones authorizePreview reads; ' +\n 'if you use an adapter, check its inject mode and previewSignals. If you start the ' +\n 'client yourself, this line is expected.',\n }\n : {\n code: 'LP0701',\n level: 'warning',\n title: 'No inline runtime in the preview response',\n detail:\n `The preview request returned ${String(preview.status)} without the inline ` +\n 'runtime. Three readings, and this audit cannot tell them apart from the response ' +\n 'alone: a preview behind authorizePreview — the strict 2.0 default — which answers ' +\n 'a request without credentials exactly like this, an adapter that did not recognise ' +\n 'the request as a preview, or a consumer that starts LivePreviewClient itself.',\n remedy:\n \"To audit a gated preview, send what an editor's browser sends: \" +\n \"--header 'Cookie: payload-token=…' for a Payload session; for a signed token, \" +\n 'the URL with ?previewToken=… (the default transport, dropped from the visitor ' +\n \"request), or --header 'x-preview-token: …' where the strategy sets transport: \" +\n \"{ kind: 'header' }. Otherwise check the adapter's \" +\n 'inject mode and previewSignals; if you start the client yourself, this line is ' +\n 'expected.',\n },\n );\n }\n findings.push(...framingFindings(preview, runtimeInPreview, context));\n findings.push(\n ...bindingFindings(visibleMarkup(preview.body), visibleMarkup(pub.body), runtimeInPreview),\n );\n if (pub.body.includes(RUNTIME_MARKER)) {\n findings.push({\n code: DIAGNOSTIC_CODES.RuntimeOnPublicPage,\n level: 'info',\n title: 'Runtime is also served to anonymous visitors',\n detail:\n 'A request with no preview intent received the inline runtime. That is correct for ' +\n \"inject: 'always' and unintended for 'preview-only'.\",\n remedy: '',\n });\n }\n if (context.v2 === true) findings.push(...analyzeV2Readiness(probe));\n findings.sort((a, b) => LEVEL_ORDER[a.level] - LEVEL_ORDER[b.level]);\n return {\n url: context.url,\n findings,\n errors: findings.filter((finding) => finding.level === 'error').length,\n warnings: findings.filter((finding) => finding.level === 'warning').length,\n };\n}\n","/**\n * Fetching for `pll doctor`: the two probes, and the default fetch that talks\n * to a real server. Not in the barrel so it stays in the coverage report.\n */\nimport { analyzeProbe } from './analyze';\nimport type { DoctorReport, DoctorResponse } from './types';\n\n/** Injectable so tests can drive the audit without a server. */\nexport type DoctorFetch = (\n url: string,\n init: { readonly headers: Readonly<Record<string, string>> },\n) => Promise<DoctorResponse>;\n\nexport interface RunDoctorOptions {\n readonly url: string;\n /** Admin origin the preview is meant to be embedded from, when known. */\n readonly adminOrigin?: string | undefined;\n /** Defaults to a fetch built on `globalThis.fetch`. */\n readonly fetchImpl?: DoctorFetch | undefined;\n /** Also check the served page against the 2.0 readiness table. */\n readonly v2?: boolean;\n /**\n * Headers sent with the preview probe only, never with the visitor probe: the\n * credentials a preview behind `authorizePreview` needs, such as a Payload\n * session `Cookie`, or an `x-preview-token` where the token strategy reads a\n * header (a token in the URL is passed in `url` instead). Without them a gated page answers\n * the audit the way it answers any stranger. Their values never reach the report.\n */\n readonly previewHeaders?: Readonly<Record<string, string>> | undefined;\n /**\n * The query parameters the deployment reads as preview intent, when its\n * adapter sets `previewQueryParams`; the same list, since that option replaces\n * the default `preview`, `draft` and `livePreview`. The first one is what the\n * preview probe appends as `=true`; none of them reaches the visitor probe.\n */\n readonly previewQueryParams?: readonly string[] | undefined;\n}\n\n/**\n * The query parameters an adapter reads as preview intent by default; the same\n * list as `DEFAULT_QUERY_PARAMS` in adapters/shared/preview-request.ts, which\n * `previewQueryParams` replaces rather than extends.\n */\nconst DEFAULT_INTENT_PARAMS: readonly string[] = ['preview', 'draft', 'livePreview'];\n\nfunction isIntentValue(value: string): boolean {\n return value === 'true' || value === '1';\n}\n\n/** `key=value` and `#fragment` split off a URL, with the query kept as the caller spelled it. */\nfunction splitUrl(url: string): {\n readonly base: string;\n readonly parts: string[];\n readonly hash: string;\n} {\n const hashAt = url.indexOf('#');\n const hash = hashAt === -1 ? '' : url.slice(hashAt);\n const beforeHash = hashAt === -1 ? url : url.slice(0, hashAt);\n const queryAt = beforeHash.indexOf('?');\n if (queryAt === -1) return { base: beforeHash, parts: [], hash };\n return {\n base: beforeHash.slice(0, queryAt),\n parts: beforeHash.slice(queryAt + 1).split('&'),\n hash,\n };\n}\n\nfunction decodePart(part: string): readonly [string, string] {\n const at = part.indexOf('=');\n const decode = (text: string): string => {\n try {\n return decodeURIComponent(text.replace(/\\+/gu, ' '));\n } catch {\n return text;\n }\n };\n return at === -1 ? [decode(part), ''] : [decode(part.slice(0, at)), decode(part.slice(at + 1))];\n}\n\n/**\n * The query parameter the `signed-token` strategy reads by default. A token\n * audit puts the token in the URL, and it belongs to the preview request only:\n * in the visitor request it would authorize the \"anonymous\" probe and, behind a\n * replay store, spend the token before the preview request arrives.\n */\nconst TOKEN_PARAM = 'previewToken';\n\n/**\n * The URL as the audit prints it: the token's value replaced by `…`. Header\n * values never reach the report, and a token passed in the URL is the same\n * credential, so the report, `--json` and the failure line all show this form.\n * @internal\n */\nexport function redactToken(url: string): string {\n const { base, parts, hash } = splitUrl(url);\n const shown = parts.map((part) => {\n const at = part.indexOf('=');\n return at === -1 || decodePart(part)[0] !== TOKEN_PARAM ? part : `${part.slice(0, at)}=…`;\n });\n return shown.some((part, index) => part !== parts[index])\n ? `${base}?${shown.join('&')}${hash}`\n : url;\n}\n\n/** Whether the URL carries a non-empty token for the preview request. */\nfunction carriesToken(url: string): boolean {\n return splitUrl(url).parts.some((part) => {\n const [key, value] = decodePart(part);\n return key === TOKEN_PARAM && value !== '';\n });\n}\n\n/**\n * The page a visitor requests: the intent parameters removed, the rest of the\n * query byte for byte as given. A query is never re-serialised — `URLSearchParams`\n * would turn `%20` into `+` and add `=` to a bare key, and a page whose query is\n * signed by an edge token would answer a different request than a visitor makes.\n */\nfunction visitorUrl(url: string, params: readonly string[]): string {\n const { base, parts, hash } = splitUrl(url);\n const dropped = new Set([...params, TOKEN_PARAM]);\n const kept = parts.filter((part) => !dropped.has(decodePart(part)[0]));\n if (kept.length === parts.length) return url;\n return `${base}${kept.length === 0 ? '' : `?${kept.join('&')}`}${hash}`;\n}\n\n/**\n * The page the admin's iframe loads. A 2.0 adapter counts only the query as\n * intent (`previewSignals: ['query']`), and `buildLivePreviewUrl` writes\n * `preview=true`, so the first intent parameter is appended as `=true` unless the\n * URL already names one with a value that counts.\n */\nfunction previewUrl(url: string, params: readonly string[]): string {\n const { base, parts, hash } = splitUrl(url);\n const carries = parts.some((part) => {\n const [key, value] = decodePart(part);\n return params.includes(key) && isIntentValue(value);\n });\n if (carries) return url;\n const query = parts.join('&');\n const joiner = query === '' ? '?' : query.endsWith('&') ? '' : '&';\n const intent = `${encodeURIComponent(params[0] ?? 'preview')}=true`;\n return `${base}${parts.length === 0 ? '?' : `?${query}${joiner}`}${intent}${hash}`;\n}\n\nexport const DEFAULT_TIMEOUT_MS = 15_000;\nexport const MAX_BODY_BYTES = 10 * 1024 * 1024;\n\nexport interface DefaultFetchOptions {\n readonly fetchFn?: typeof fetch;\n readonly timeoutMs?: number;\n readonly maxBodyBytes?: number;\n}\n\n/** Header names lowercased; every check downstream reads a lowercase key. @internal */\nexport function lowercaseHeaders(headers: Headers): Record<string, string> {\n const out: Record<string, string> = {};\n headers.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n}\n\n/** The error's message plus its cause's, which is where undici puts `self-signed certificate` and friends. */\nexport function describeFailure(error: unknown): string {\n if (!(error instanceof Error)) return String(error);\n const cause = error.cause;\n if (cause instanceof Error && cause.message !== '' && !error.message.includes(cause.message)) {\n return `${error.message} (${cause.message})`;\n }\n return error.message;\n}\n\nasync function readBody(response: Response, limit: number): Promise<string> {\n const reader = response.body?.getReader();\n if (reader === undefined) return response.text();\n const decoder = new TextDecoder();\n let received = 0;\n let text = '';\n for (;;) {\n const { done, value } = await reader.read();\n if (done) break;\n received += value.byteLength;\n if (received > limit) {\n await reader.cancel();\n throw new Error(\n `the response body exceeds ${String(limit)} bytes, which is not a page the audit can judge`,\n );\n }\n text += decoder.decode(value, { stream: true });\n }\n return text + decoder.decode();\n}\n\n/** Redirects are reported, not followed; a hanging origin is abandoned; a runaway body is refused. */\nexport function createDefaultFetch(options: DefaultFetchOptions = {}): DoctorFetch {\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const limit = options.maxBodyBytes ?? MAX_BODY_BYTES;\n return async (url, init) => {\n const fetchFn = options.fetchFn ?? globalThis.fetch;\n let response: Response;\n try {\n response = await fetchFn(url, {\n headers: init.headers,\n redirect: 'manual',\n signal: AbortSignal.timeout(timeoutMs),\n });\n } catch (error) {\n if (error instanceof Error && error.name === 'TimeoutError') {\n throw new Error(`no response within ${String(timeoutMs / 1000)} s`, { cause: error });\n }\n throw error;\n }\n return {\n status: response.status,\n headers: lowercaseHeaders(response.headers),\n body: await readBody(response, limit),\n };\n };\n}\n\n/** The referer the admin's iframe would send: the origin (or the given admin path) with one slash. */\nexport function previewReferer(adminOrigin: string): string {\n try {\n return new URL(adminOrigin).href;\n } catch {\n return `${adminOrigin.replace(/\\/+$/u, '')}/`;\n }\n}\n\n/**\n * The caller's headers without the ones the probe sets itself. Header names are\n * case-insensitive, and `fetch` combines two spellings of one name into one\n * comma-joined value, so a caller's `sec-fetch-dest` would otherwise turn the\n * probe's `iframe` into `document, iframe`. The probe's own headers win.\n */\nfunction callerHeaders(\n headers: Readonly<Record<string, string>> | undefined,\n own: Readonly<Record<string, string>>,\n): Record<string, string> {\n const taken = new Set(Object.keys(own).map((name) => name.toLowerCase()));\n return Object.fromEntries(\n Object.entries(headers ?? {}).filter(([name]) => !taken.has(name.toLowerCase())),\n );\n}\n\n/** Fetch the URL twice — as a visitor and as the admin's iframe — and audit the difference. */\nexport async function runDoctor(options: RunDoctorOptions): Promise<DoctorReport> {\n const fetchImpl = options.fetchImpl ?? createDefaultFetch();\n const params =\n options.previewQueryParams === undefined || options.previewQueryParams.length === 0\n ? DEFAULT_INTENT_PARAMS\n : options.previewQueryParams;\n // No referer, no intent parameter and no credentials on the visitor probe:\n // each of them is a preview signal or a way past one.\n const publicResponse = await fetchImpl(visitorUrl(options.url, params), {\n headers: {\n Accept: 'text/html',\n 'Sec-Fetch-Dest': 'document',\n 'Sec-Fetch-Mode': 'navigate',\n },\n });\n const probeHeaders: Record<string, string> = {\n Accept: 'text/html',\n 'Sec-Fetch-Dest': 'iframe',\n 'Sec-Fetch-Mode': 'navigate',\n ...(options.adminOrigin === undefined ? {} : { Referer: previewReferer(options.adminOrigin) }),\n };\n const sent = callerHeaders(options.previewHeaders, probeHeaders);\n const previewResponse = await fetchImpl(previewUrl(options.url, params), {\n headers: { ...sent, ...probeHeaders },\n });\n return analyzeProbe(\n { publicResponse, previewResponse },\n {\n url: redactToken(options.url),\n adminOrigin: options.adminOrigin,\n ...(options.v2 === true ? { v2: true } : {}),\n ...(Object.keys(sent).length > 0 || carriesToken(options.url) ? { credentials: true } : {}),\n },\n );\n}\n","#!/usr/bin/env node\n/**\n * The `pll` binary: `pll doctor <url>` here, `pll migrate <path>` in\n * migrate/cli. Doctor exit codes: 0 no error-level findings, 1 usage error or\n * the URL could not be fetched, 2 at least one error-level finding.\n */\nimport { runMigrateCommand } from '../migrate/cli';\nimport { formatReport } from './format';\nimport { describeFailure, redactToken, runDoctor, type DoctorFetch } from './probe';\n\ninterface ParsedArgs {\n url: string | undefined;\n adminOrigin: string | undefined;\n json: boolean;\n v2: boolean;\n showHelp: boolean;\n unknown: string[];\n /** Headers for the preview probe, from every `--header`/`-H`. */\n headers: Record<string, string>;\n /** The first `--header` or `--param` that could not be read, as the message to print. */\n usageError: string | undefined;\n /** Query parameter names from every `--param`. */\n params: string[];\n}\n\n/** A query parameter name: no separator, no space, and not the next option. */\nconst PARAM_NAME = /^[^\\s&=#?-][^\\s&=#]*$/u;\n\n/** An HTTP field name (RFC 9110 token), a colon, then the value. */\nconst HEADER_LINE = /^([!#$%&'*+.^_`|~0-9A-Za-z-]+):[ \\t]*(.*)$/u;\n\nfunction addHeader(parsed: ParsedArgs, line: string | undefined): void {\n // A missing value would otherwise read the next argument: `https://example.com/`\n // matches as name `https`, and `--v2` as no header at all.\n const match =\n line === undefined || line.startsWith('-') || isAbsoluteUrl(line)\n ? null\n : HEADER_LINE.exec(line);\n const name = match?.[1];\n const value = match?.[2];\n if (name === undefined || value === undefined) {\n // The value is not echoed: a mistyped header can still hold half a token.\n parsed.usageError ??=\n 'pll doctor: --header takes \"Name: value\", such as --header \"Cookie: payload-token=…\"';\n return;\n }\n // Header names are case-insensitive; a second spelling would be joined onto\n // the first by fetch, and a repeat would silently replace it.\n if (Object.keys(parsed.headers).some((given) => given.toLowerCase() === name.toLowerCase())) {\n parsed.usageError ??= `pll doctor: --header \"${name}\" is given twice; join the values into one header`;\n return;\n }\n parsed.headers[name] = value;\n}\n\nfunction addParam(parsed: ParsedArgs, name: string | undefined): void {\n if (name === undefined || !PARAM_NAME.test(name)) {\n parsed.usageError ??= 'pll doctor: --param takes a query parameter name, such as --param draft';\n return;\n }\n parsed.params.push(name);\n}\n\nfunction parseArgs(argv: readonly string[]): ParsedArgs {\n const parsed: ParsedArgs = {\n url: undefined,\n adminOrigin: undefined,\n json: false,\n v2: false,\n showHelp: false,\n unknown: [],\n headers: {},\n usageError: undefined,\n params: [],\n };\n for (let i = 0; i < argv.length; i += 1) {\n const token = argv[i];\n if (token === undefined) continue;\n if (token === '-h' || token === '--help') parsed.showHelp = true;\n else if (token === '--json') parsed.json = true;\n else if (token === '--v2') parsed.v2 = true;\n else if (token === '--admin' || token === '-a') {\n parsed.adminOrigin = argv[i + 1];\n i += 1;\n } else if (token.startsWith('--admin=')) parsed.adminOrigin = token.slice('--admin='.length);\n else if (token === '--header' || token === '-H') {\n addHeader(parsed, argv[i + 1]);\n i += 1;\n } else if (token.startsWith('--header=')) addHeader(parsed, token.slice('--header='.length));\n else if (token === '--param') {\n addParam(parsed, argv[i + 1]);\n i += 1;\n } else if (token.startsWith('--param=')) addParam(parsed, token.slice('--param='.length));\n else if (token.startsWith('-')) parsed.unknown.push(token);\n else parsed.url ??= token;\n }\n return parsed;\n}\n\nconst HELP_TEXT = `pll doctor — audit what a live-preview deployment actually serves\npll migrate — rewrite 1.x APIs to their 2.0 names and homes\n\nUsage:\n pll doctor <url> [--admin <origin>] [--header <name: value>]... [--param <name>]... [--json] [--v2]\n pll migrate <path> [--write] [--only <id,id>]\n\nThe URL is fetched twice: once as an ordinary visitor, without any intent\nparameter, and once the way the Payload admin's iframe loads it, with\n?preview=true and the iframe's headers.\nMost findings come from the difference between the two responses. Redirects\nare reported, not followed.\n\nOptions of pll doctor:\n -a, --admin <origin> Admin origin the preview is embedded from. Enables the\n frame-ancestors check to verify the origin is admitted,\n not merely that a policy exists.\n -H, --header <h> A header for the preview request only, as \"Name: value\";\n repeat it for more. A preview behind authorizePreview\n needs an editor's credentials: a Payload session Cookie,\n or an x-preview-token where the token strategy sets\n transport: { kind: 'header' }. A signed token travels in\n the URL by default, as ?previewToken=…, which the visitor\n request drops. The visitor request stays anonymous and\n values are never printed, but a shell keeps them in its\n history, so prefer a short-lived token.\n --param <name> A query parameter the deployment reads as preview intent,\n for an adapter whose previewQueryParams replaces the\n default preview, draft and livePreview; repeat it for\n more. The first one is what the preview request carries\n as <name>=true; none of them reaches the visitor request.\n --json Emit the report as JSON instead of text\n --v2 Also check the page against the 2.0 readiness table\n -h, --help Show this help\n\nExit codes of pll doctor:\n 0 no error-level findings\n 1 usage error, or the URL could not be fetched\n 2 at least one error-level finding\n\npll migrate has its own options and exit codes: pll migrate --help\n\nExamples:\n pll doctor https://example.com/\n pll doctor https://example.com/blog/hello --admin https://cms.example.com\n pll doctor \"https://example.com/?previewToken=$PREVIEW_TOKEN\" --v2\n pll doctor https://example.com/ --header \"Cookie: payload-token=$PAYLOAD_TOKEN\"\n`;\n\nfunction isAbsoluteUrl(value: string): boolean {\n try {\n return new URL(value).origin !== 'null';\n } catch {\n return false;\n }\n}\n\n/** @param fetchImpl Seam for tests; the bin shim never passes it. */\nexport async function run(argv: readonly string[], fetchImpl?: DoctorFetch): Promise<number> {\n const [subcommand, ...rest] = argv;\n if (subcommand === undefined || subcommand === '-h' || subcommand === '--help') {\n process.stdout.write(HELP_TEXT);\n return subcommand === undefined ? 1 : 0;\n }\n if (subcommand === 'migrate') return runMigrateCommand(rest);\n if (subcommand !== 'doctor') {\n process.stderr.write(`pll: unknown command \"${subcommand}\". Try \\`pll --help\\`.\\n`);\n return 1;\n }\n const args = parseArgs(rest);\n if (args.showHelp) {\n process.stdout.write(HELP_TEXT);\n return 0;\n }\n if (args.unknown.length > 0) {\n process.stderr.write(`pll doctor: unknown option ${args.unknown.join(', ')}\\n`);\n return 1;\n }\n if (args.url === undefined) {\n process.stderr.write('pll doctor: a URL is required. Try `pll doctor --help`.\\n');\n return 1;\n }\n if (args.usageError !== undefined) {\n process.stderr.write(`${args.usageError}\\n`);\n return 1;\n }\n if (args.adminOrigin !== undefined && !isAbsoluteUrl(args.adminOrigin)) {\n process.stderr.write(\n `pll doctor: --admin must be an absolute URL such as https://cms.example.com (got \"${args.adminOrigin}\")\\n`,\n );\n return 1;\n }\n let report;\n try {\n report = await runDoctor({\n url: args.url,\n ...(args.adminOrigin !== undefined ? { adminOrigin: args.adminOrigin } : {}),\n ...(args.v2 ? { v2: true } : {}),\n ...(Object.keys(args.headers).length > 0 ? { previewHeaders: args.headers } : {}),\n ...(args.params.length > 0 ? { previewQueryParams: args.params } : {}),\n ...(fetchImpl !== undefined ? { fetchImpl } : {}),\n });\n } catch (error) {\n const message = describeFailure(error);\n const shown = redactToken(args.url);\n if (args.json) {\n process.stdout.write(`${JSON.stringify({ url: shown, error: message }, undefined, 2)}\\n`);\n } else {\n process.stderr.write(`pll doctor: could not probe ${shown}: ${message}\\n`);\n }\n return 1;\n }\n process.stdout.write(\n args.json ? `${JSON.stringify(report, undefined, 2)}\\n` : formatReport(report),\n );\n return report.errors > 0 ? 2 : 0;\n}\n\n/** Matches the entry's basename only, so importing this module from a path containing `pll` never runs it. */\nexport function isCliInvocation(argv: readonly (string | undefined)[] = process.argv): boolean {\n if (typeof process === 'undefined') return false;\n const entry = argv[1];\n if (entry === undefined || entry === '') return false;\n const name = entry.split(/[\\\\/]/u).pop() ?? '';\n return name === 'pll' || name === 'pll.cmd' || name.startsWith('doctor-cli');\n}\n\nif (isCliInvocation()) {\n void run(process.argv.slice(2)).then((code) => {\n process.exit(code);\n });\n}\n"],"mappings":"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","ignoreList":[]}