@spotpatch/next 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -0
- package/dist/cli.js +579 -48
- package/dist/cli.js.map +1 -1
- package/dist/client.cjs +29 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.js +9 -0
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +20 -5
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +20 -5
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config/with-spotpatch.ts","../src/internal/constants.ts","../src/config/handshake.ts","../src/internal/ipc.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { realpath } from \"node:fs/promises\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport {\n resolveCredentialEnvironment,\n resolveEnvironmentAiConfiguration,\n resolveProjectOptions,\n type SpotPatchOptions,\n} from \"@spotpatch/dev-server\";\nimport { SPOTPATCH_API_BASE } from \"@spotpatch/shared\";\nimport type { NextConfig } from \"next\";\nimport { PHASE_DEVELOPMENT_SERVER } from \"next/constants\";\n\nimport {\n NEXT_CLIENT_MODULE_ID,\n NEXT_DEFAULT_INCLUDE,\n NEXT_SOURCE_RULE_KEYS,\n} from \"../internal/constants.js\";\nimport { configureNextRuntime } from \"./handshake.js\";\n\nexport type NextSpotPatchOptions = Omit<SpotPatchOptions, \"allowLan\" | \"dataFlow\"> &\n Readonly<{\n allowLan?: false;\n dataFlow?: false;\n }>;\n\nexport interface NextConfigContext<\n Config extends object = Readonly<Record<string, unknown>>,\n> {\n readonly defaultConfig: Config;\n}\n\nexport type NextConfigFactory<\n Config extends object = Readonly<Record<string, unknown>>,\n> = (phase: string, context: NextConfigContext<Config>) => Config | Promise<Config>;\n\nexport type NextConfigInput<Config extends object = Readonly<Record<string, unknown>>> =\n Config | NextConfigFactory<Config>;\n\nexport type NextConfigEnhancer = <\n Config extends object = Readonly<Record<string, unknown>>,\n>(\n input?: NextConfigInput<Config>,\n) => NextConfigFactory<Config>;\n\ninterface AdapterModulePaths {\n readonly loader: string;\n readonly noop: string;\n readonly turbopackLoader: string;\n readonly turbopackNoop: string;\n}\n\ntype WebpackConfig = Record<string, unknown>;\ntype WebpackHandler = (config: unknown, context: unknown) => unknown;\n\ninterface WebpackContext extends Readonly<Record<string, unknown>> {\n readonly dev: boolean;\n}\n\ntype TurbopackRules = NonNullable<NonNullable<NextConfig[\"turbopack\"]>[\"rules\"]>;\n\nconst configuredWebpackConfigs = new WeakSet();\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readWebpackHandler(config: NextConfig): WebpackHandler | undefined {\n const value = (config as unknown as Readonly<Record<string, unknown>>).webpack;\n\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value !== \"function\") {\n throw new TypeError(\"SpotPatch requires nextConfig.webpack to be a function.\");\n }\n\n return value as WebpackHandler;\n}\n\nfunction requireWebpackConfig(value: unknown): WebpackConfig {\n if (!isRecord(value)) {\n throw new TypeError(\"SpotPatch received an invalid webpack configuration.\");\n }\n\n return value;\n}\n\nfunction requireWebpackContext(value: unknown): WebpackContext {\n if (!isRecord(value) || typeof value.dev !== \"boolean\") {\n throw new TypeError(\"SpotPatch received an invalid webpack context.\");\n }\n\n return value as WebpackContext;\n}\n\nfunction isWithinRoot(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return (\n relative === \"\" ||\n (!relative.startsWith(`..${path.sep}`) &&\n relative !== \"..\" &&\n !path.isAbsolute(relative))\n );\n}\n\nfunction findCommonFilesystemRoot(paths: readonly string[]): string {\n const normalized = paths.map((value) => path.resolve(value));\n const firstPath = normalized[0];\n\n if (firstPath === undefined) {\n throw new Error(\"SpotPatch requires at least one filesystem path.\");\n }\n\n let candidate = firstPath;\n\n while (!normalized.every((value) => isWithinRoot(candidate, value))) {\n const parent = path.dirname(candidate);\n\n if (parent === candidate) {\n throw new Error(\"SpotPatch paths do not share a safe filesystem root.\");\n }\n\n candidate = parent;\n }\n\n if (candidate === path.parse(candidate).root) {\n throw new Error(\"SpotPatch refuses to configure the filesystem root.\");\n }\n\n return candidate;\n}\n\nfunction findLogicalAdapterRoot(\n appRoot: string,\n resolvedAdapterRoot: string,\n): string | undefined {\n let directory = appRoot;\n\n while (directory !== path.dirname(directory)) {\n const candidate = path.join(directory, \"node_modules\", \"@spotpatch\", \"next\");\n\n if (existsSync(candidate) && realpathSync(candidate) === resolvedAdapterRoot) {\n return candidate;\n }\n\n directory = path.dirname(directory);\n }\n\n return undefined;\n}\n\nfunction resolveAdapterModulePaths(appRoot: string): AdapterModulePaths {\n const resolveFromApplication = createRequire(path.join(appRoot, \"package.json\"));\n const loader = resolveFromApplication.resolve(\"@spotpatch/next/loader\");\n const resolvedAdapterRoot = path.dirname(loader);\n const noop = path.join(resolvedAdapterRoot, \"dist\", \"noop.cjs\");\n const logicalAdapterRoot = findLogicalAdapterRoot(appRoot, resolvedAdapterRoot);\n const logicalNoop =\n logicalAdapterRoot === undefined\n ? undefined\n : path.join(logicalAdapterRoot, \"dist\", \"noop.js\");\n const relativeNoop =\n logicalNoop === undefined\n ? undefined\n : path.relative(appRoot, logicalNoop).split(path.sep).join(\"/\");\n\n return Object.freeze({\n loader,\n noop,\n turbopackLoader:\n logicalAdapterRoot === undefined\n ? loader\n : path.join(logicalAdapterRoot, \"loader.cjs\"),\n turbopackNoop:\n relativeNoop === undefined\n ? noop\n : relativeNoop.startsWith(\".\")\n ? relativeNoop\n : `./${relativeNoop}`,\n });\n}\n\nfunction mergeTurbopackRoot(\n config: NextConfig,\n requiredPaths: readonly string[],\n): string {\n const commonRoot = findCommonFilesystemRoot(requiredPaths);\n const existingRoot = config.turbopack?.root;\n\n if (\n existingRoot !== undefined &&\n !requiredPaths.every((value) => isWithinRoot(existingRoot, value))\n ) {\n throw new Error(\n \"SpotPatch cannot use the existing turbopack.root because it excludes an adapter module.\",\n );\n }\n\n return existingRoot ?? commonRoot;\n}\n\nfunction mergeTurbopackAlias(\n config: NextConfig,\n noopPath: string,\n): NonNullable<NextConfig[\"turbopack\"]> {\n const aliases = config.turbopack?.resolveAlias ?? {};\n const existing = aliases[NEXT_CLIENT_MODULE_ID];\n\n if (existing !== undefined && existing !== noopPath) {\n throw new Error(\n `SpotPatch cannot replace turbopack.resolveAlias[${NEXT_CLIENT_MODULE_ID}].`,\n );\n }\n\n return {\n ...config.turbopack,\n resolveAlias: {\n ...aliases,\n [NEXT_CLIENT_MODULE_ID]: noopPath,\n },\n };\n}\n\nfunction mergeWebpackAlias(config: WebpackConfig, noopPath: string): void {\n const resolveValue = config.resolve;\n\n if (resolveValue !== undefined && !isRecord(resolveValue)) {\n throw new Error(\"SpotPatch requires webpack resolve to be an object.\");\n }\n\n const resolve = resolveValue ?? {};\n const alias = resolve.alias ?? {};\n\n if (!isRecord(alias)) {\n throw new Error(\"SpotPatch requires webpack resolve.alias to be an object.\");\n }\n\n const existing = alias[NEXT_CLIENT_MODULE_ID];\n\n if (existing !== undefined && existing !== noopPath) {\n throw new Error(\n `SpotPatch cannot replace webpack resolve.alias[${NEXT_CLIENT_MODULE_ID}].`,\n );\n }\n\n resolve.alias = { ...alias, [NEXT_CLIENT_MODULE_ID]: noopPath };\n config.resolve = resolve;\n}\n\nfunction scopeWebpackFilesystemCache(\n config: WebpackConfig,\n registryEpoch: string,\n): void {\n const cache = config.cache;\n\n if (isRecord(cache) && cache.type === \"filesystem\") {\n const currentVersion = typeof cache.version === \"string\" ? cache.version : \"\";\n cache.version = [currentVersion, `spotpatch:${registryEpoch}`]\n .filter(Boolean)\n .join(\"|\");\n }\n}\n\nfunction appendWebpackLoader(\n config: WebpackConfig,\n context: WebpackContext,\n loaderPath: string,\n registryEpoch: string,\n appRoot: string,\n): void {\n if (!context.dev) {\n return;\n }\n\n const module = config.module;\n\n if (!isRecord(module) || !Array.isArray(module.rules)) {\n throw new Error(\"SpotPatch requires webpack module.rules to be an array.\");\n }\n\n if (configuredWebpackConfigs.has(config)) {\n return;\n }\n\n scopeWebpackFilesystemCache(config, registryEpoch);\n const rule = {\n enforce: \"pre\" as const,\n include: appRoot,\n test: /\\.(?:jsx|tsx)$/u,\n use: [\n {\n loader: loaderPath,\n options: { registryEpoch },\n },\n ],\n };\n module.rules.push(rule);\n configuredWebpackConfigs.add(config);\n}\n\nfunction rewriteCanClaimPrivateApi(source: string): boolean {\n return (\n source === SPOTPATCH_API_BASE ||\n source.startsWith(`${SPOTPATCH_API_BASE}/`) ||\n source.startsWith(\"/:path\") ||\n source.startsWith(\"/:slug\") ||\n source.includes(\"(.*)\")\n );\n}\n\nfunction assertRewriteCompatibility(\n rewrites: readonly Readonly<{ source: string }>[] | undefined,\n): void {\n const conflict = rewrites?.find(({ source }) => rewriteCanClaimPrivateApi(source));\n\n if (conflict !== undefined) {\n throw new Error(\n `SpotPatch API prefix conflicts with the host rewrite ${conflict.source}.`,\n );\n }\n}\n\nfunction createRewrites(\n config: NextConfig,\n sidecarOrigin: string,\n): NonNullable<NextConfig[\"rewrites\"]> {\n return async () => {\n const spotPatchRewrite = {\n basePath: false as const,\n destination: `${sidecarOrigin}${SPOTPATCH_API_BASE}/:path*`,\n source: `${SPOTPATCH_API_BASE}/:path*`,\n };\n const original = await config.rewrites?.();\n\n if (original === undefined) {\n return {\n beforeFiles: [spotPatchRewrite],\n afterFiles: [],\n fallback: [],\n };\n }\n\n if (Array.isArray(original)) {\n assertRewriteCompatibility(original);\n return {\n beforeFiles: [spotPatchRewrite],\n afterFiles: original,\n fallback: [],\n };\n }\n\n const beforeFiles = original.beforeFiles ?? [];\n const afterFiles = original.afterFiles ?? [];\n const fallback = original.fallback ?? [];\n assertRewriteCompatibility([...beforeFiles, ...afterFiles, ...fallback]);\n return {\n beforeFiles: [spotPatchRewrite, ...beforeFiles],\n afterFiles,\n fallback,\n };\n };\n}\n\nfunction createWebpackWrapper(input: {\n readonly appRoot: string;\n readonly development: boolean;\n readonly loaderPath: string;\n readonly noopPath: string;\n readonly original: WebpackHandler | undefined;\n readonly registryEpoch?: string;\n}): WebpackHandler {\n return (configValue, contextValue) => {\n const config = requireWebpackConfig(configValue);\n const context = requireWebpackContext(contextValue);\n const configuredValue = input.original?.(configValue, contextValue);\n const configured =\n configuredValue === undefined ? config : requireWebpackConfig(configuredValue);\n\n if (input.development) {\n if (input.registryEpoch === undefined) {\n throw new Error(\"SpotPatch is missing the development registry epoch.\");\n }\n\n appendWebpackLoader(\n configured,\n context,\n input.loaderPath,\n input.registryEpoch,\n input.appRoot,\n );\n } else {\n mergeWebpackAlias(configured, input.noopPath);\n }\n\n return configured;\n };\n}\n\nfunction mergeProductionConfig(\n config: NextConfig,\n appRoot: string,\n paths: AdapterModulePaths,\n): NextConfig {\n return {\n ...config,\n turbopack: mergeTurbopackAlias(config, paths.turbopackNoop),\n webpack: createWebpackWrapper({\n appRoot,\n development: false,\n loaderPath: paths.loader,\n noopPath: paths.noop,\n original: readWebpackHandler(config),\n }),\n };\n}\n\nfunction mergeDevelopmentConfig(\n config: NextConfig,\n appRoot: string,\n paths: AdapterModulePaths,\n registryEpoch: string,\n sidecarOrigin: string,\n): NextConfig {\n const turbopackRoot = mergeTurbopackRoot(config, [appRoot, paths.turbopackLoader]);\n const existingRules = config.turbopack?.rules ?? {};\n const spotPatchRules: TurbopackRules = {};\n\n for (const key of NEXT_SOURCE_RULE_KEYS) {\n if (existingRules[key] !== undefined) {\n throw new Error(\n `SpotPatch cannot replace turbopack.rules[${JSON.stringify(key)}].`,\n );\n }\n\n spotPatchRules[key] = {\n condition: { all: [\"development\", { not: \"foreign\" }] },\n loaders: [\n {\n loader: paths.turbopackLoader,\n options: { registryEpoch },\n },\n ],\n };\n }\n\n return {\n ...config,\n rewrites: createRewrites(config, sidecarOrigin),\n turbopack: {\n ...config.turbopack,\n root: turbopackRoot,\n rules: { ...existingRules, ...spotPatchRules },\n },\n webpack: createWebpackWrapper({\n appRoot,\n development: true,\n loaderPath: paths.loader,\n noopPath: paths.noop,\n original: readWebpackHandler(config),\n registryEpoch,\n }),\n };\n}\n\nasync function resolveInputConfig<Config extends object>(\n input: NextConfigInput<Config> | undefined,\n phase: string,\n context: NextConfigContext<Config>,\n): Promise<Config> {\n if (typeof input === \"function\") {\n return await input(phase, context);\n }\n\n return input ?? ({} as Config);\n}\n\nexport function withSpotPatch(\n userOptions: NextSpotPatchOptions = {},\n): NextConfigEnhancer {\n const requestedDataFlow = (userOptions as Readonly<Record<string, unknown>>).dataFlow;\n\n if (requestedDataFlow !== undefined && requestedDataFlow !== false) {\n throw new RangeError(\n \"SpotPatch Next does not support component dataFlow yet; use dataFlow only with @spotpatch/vite.\",\n );\n }\n\n return <Config extends object = Readonly<Record<string, unknown>>>(\n input?: NextConfigInput<Config>,\n ): NextConfigFactory<Config> =>\n async (phase, context): Promise<Config> => {\n const inputConfig = await resolveInputConfig(input, phase, context);\n const config = inputConfig as unknown as NextConfig;\n const appRoot = await realpath(process.cwd());\n const paths = resolveAdapterModulePaths(appRoot);\n\n if (phase !== PHASE_DEVELOPMENT_SERVER) {\n return mergeProductionConfig(config, appRoot, paths) as unknown as Config;\n }\n\n const environmentAi =\n userOptions.ai === undefined\n ? resolveEnvironmentAiConfiguration(process.env).ai\n : false;\n const options = await resolveProjectOptions({\n appRoot,\n environmentAi,\n options: {\n ...userOptions,\n include: userOptions.include ?? NEXT_DEFAULT_INCLUDE,\n },\n });\n\n if (options.allowLan) {\n throw new RangeError(\n \"SpotPatch Next does not support allowLan; use a loopback development host.\",\n );\n }\n\n const carrier = await configureNextRuntime({\n appRoot,\n credentials: resolveCredentialEnvironment(options, process.env),\n options,\n });\n\n if (!options.enabled) {\n return mergeProductionConfig(config, appRoot, paths) as unknown as Config;\n }\n\n return mergeDevelopmentConfig(\n config,\n appRoot,\n paths,\n carrier.registryEpoch,\n carrier.sidecarOrigin,\n ) as unknown as Config;\n };\n}\n","export const NEXT_IPC_PROTOCOL_VERSION = 1 as const;\nexport const NEXT_IPC_MESSAGE_LIMIT_BYTES = 256 * 1024;\nexport const NEXT_IPC_TIMEOUT_MS = 15_000;\nexport const NEXT_INTERNAL_REGISTRATION_PATH =\n \"/__spotpatch-internal/register\" as const;\nexport const NEXT_INTERNAL_CONFIGURATION_PATH =\n \"/__spotpatch-internal/configure\" as const;\n\nexport const NEXT_ENVIRONMENT_KEYS = Object.freeze({\n appRoot: \"SPOTPATCH_NEXT_APP_ROOT\",\n bundler: \"SPOTPATCH_NEXT_BUNDLER\",\n configurationSecret: \"SPOTPATCH_NEXT_CONFIGURATION_SECRET\",\n internalOrigin: \"SPOTPATCH_NEXT_INTERNAL_ORIGIN\",\n internalSecret: \"SPOTPATCH_NEXT_INTERNAL_SECRET\",\n launchNonce: \"SPOTPATCH_NEXT_LAUNCH_NONCE\",\n registryEpoch: \"SPOTPATCH_NEXT_REGISTRY_EPOCH\",\n sidecarOrigin: \"SPOTPATCH_NEXT_SIDECAR_ORIGIN\",\n} as const);\n\nexport const NEXT_SOURCE_RULE_KEYS = Object.freeze([\"*.jsx\", \"*.tsx\"] as const);\nexport const NEXT_CLIENT_MODULE_ID = \"@spotpatch/next/client\" as const;\n\nexport const NEXT_DEFAULT_INCLUDE = Object.freeze([/\\.(?:jsx|tsx)$/u]);\n","import { randomBytes } from \"node:crypto\";\n\nimport {\n serializeResolvedSpotPatchOptions,\n type ResolvedSpotPatchOptions,\n} from \"@spotpatch/dev-server\";\n\nimport {\n NEXT_ENVIRONMENT_KEYS,\n NEXT_INTERNAL_CONFIGURATION_PATH,\n NEXT_IPC_PROTOCOL_VERSION,\n NEXT_IPC_TIMEOUT_MS,\n} from \"../internal/constants.js\";\nimport {\n assertIpcMessageSize,\n parseNextConfigureAck,\n type NextConfigureMessage,\n} from \"../internal/ipc.js\";\n\nconst ID_PATTERN = /^[A-Za-z0-9_-]{16,128}$/u;\nconst CONFIGURATION_SECRET_PATTERN = /^[A-Za-z0-9_-]{32,128}$/u;\nconst ACKNOWLEDGEMENT_LIMIT_BYTES = 4_096;\n\nexport interface NextRuntimeCarrier {\n readonly registryEpoch: string;\n readonly sidecarOrigin: string;\n}\n\ninterface ConfigureInput {\n readonly appRoot: string;\n readonly credentials: Readonly<Record<string, string>>;\n readonly options: ResolvedSpotPatchOptions;\n}\n\nlet activeSignature: string | undefined;\nlet activeConfiguration: Promise<NextRuntimeCarrier> | undefined;\n\nfunction readRequiredEnvironment(name: string): string {\n const value = process.env[name];\n\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(\n \"SpotPatch Next development must be started with `spotpatch-next dev`.\",\n );\n }\n\n return value;\n}\n\nfunction readLoopbackOrigin(name: string): string {\n const value = readRequiredEnvironment(name);\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"SpotPatch received an invalid CLI transport origin.\");\n }\n\n if (\n url.origin !== value ||\n url.protocol !== \"http:\" ||\n url.hostname !== \"127.0.0.1\"\n ) {\n throw new Error(\"SpotPatch received an invalid CLI transport origin.\");\n }\n\n return url.origin;\n}\n\nfunction configurationSignature(input: ConfigureInput): string {\n return JSON.stringify({\n appRoot: input.appRoot,\n credentials: input.credentials,\n options: serializeResolvedSpotPatchOptions(input.options),\n });\n}\n\nasync function sendConfiguration(input: ConfigureInput): Promise<NextRuntimeCarrier> {\n const nonce = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.launchNonce);\n const expectedAppRoot = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.appRoot);\n const registryEpoch = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.registryEpoch);\n const sidecarOrigin = readLoopbackOrigin(NEXT_ENVIRONMENT_KEYS.sidecarOrigin);\n const internalOrigin = readLoopbackOrigin(NEXT_ENVIRONMENT_KEYS.internalOrigin);\n readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.internalSecret);\n const configurationSecret = readRequiredEnvironment(\n NEXT_ENVIRONMENT_KEYS.configurationSecret,\n );\n const bundler = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.bundler);\n\n if (\n input.appRoot !== expectedAppRoot ||\n internalOrigin !== sidecarOrigin ||\n (bundler !== \"turbopack\" && bundler !== \"webpack\") ||\n !CONFIGURATION_SECRET_PATTERN.test(configurationSecret) ||\n !ID_PATTERN.test(nonce) ||\n !ID_PATTERN.test(registryEpoch)\n ) {\n throw new Error(\"SpotPatch received an invalid CLI launch identity.\");\n }\n\n const requestId = randomBytes(18).toString(\"base64url\");\n const message = Object.freeze({\n appRoot: input.appRoot,\n credentials: input.credentials,\n nonce,\n options: serializeResolvedSpotPatchOptions(input.options),\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId,\n type: \"spotpatch:next:configure\",\n }) satisfies NextConfigureMessage;\n assertIpcMessageSize(message);\n let response: Response;\n\n try {\n response = await fetch(new URL(NEXT_INTERNAL_CONFIGURATION_PATH, internalOrigin), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-SpotPatch-Configuration\": configurationSecret,\n },\n body: JSON.stringify(message),\n signal: AbortSignal.timeout(NEXT_IPC_TIMEOUT_MS),\n });\n } catch {\n throw new Error(\"SpotPatch Next configuration transport failed.\");\n }\n\n const declaredLength = Number(response.headers.get(\"content-length\"));\n\n if (Number.isFinite(declaredLength) && declaredLength > ACKNOWLEDGEMENT_LIMIT_BYTES) {\n await response.body?.cancel();\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n const text = await response.text();\n\n if (Buffer.byteLength(text, \"utf8\") > ACKNOWLEDGEMENT_LIMIT_BYTES) {\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n let acknowledgementValue: unknown;\n\n try {\n acknowledgementValue = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n const acknowledgement = parseNextConfigureAck(acknowledgementValue);\n\n if (\n !response.ok ||\n acknowledgement.nonce !== nonce ||\n acknowledgement.requestId !== requestId\n ) {\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n if (!acknowledgement.ok) {\n throw new Error(`SpotPatch Next configuration failed (${acknowledgement.code}).`);\n }\n\n return Object.freeze({ registryEpoch, sidecarOrigin });\n}\n\nexport function configureNextRuntime(\n input: ConfigureInput,\n): Promise<NextRuntimeCarrier> {\n const signature = configurationSignature(input);\n\n if (activeConfiguration !== undefined) {\n if (activeSignature !== signature) {\n return Promise.reject(\n new Error(\"SpotPatch Next received inconsistent repeated configuration.\"),\n );\n }\n\n return activeConfiguration;\n }\n\n activeSignature = signature;\n activeConfiguration = sendConfiguration(input).catch((error: unknown) => {\n activeConfiguration = undefined;\n activeSignature = undefined;\n throw error;\n });\n return activeConfiguration;\n}\n","import path from \"node:path\";\n\nimport {\n parseSerializedSpotPatchOptions,\n type ResolvedSpotPatchOptions,\n type SerializedSpotPatchOptions,\n} from \"@spotpatch/dev-server\";\n\nimport {\n NEXT_IPC_MESSAGE_LIMIT_BYTES,\n NEXT_IPC_PROTOCOL_VERSION,\n} from \"./constants.js\";\n\nconst ID_PATTERN = /^[A-Za-z0-9_-]{16,128}$/u;\nconst ENVIRONMENT_NAME_PATTERN = /^[A-Z][A-Z0-9_]{1,127}$/u;\n\nexport interface NextConfigureMessage {\n readonly appRoot: string;\n readonly credentials: Readonly<Record<string, string>>;\n readonly nonce: string;\n readonly options: SerializedSpotPatchOptions;\n readonly protocolVersion: typeof NEXT_IPC_PROTOCOL_VERSION;\n readonly requestId: string;\n readonly type: \"spotpatch:next:configure\";\n}\n\nexport type NextConfigureAck =\n | Readonly<{\n nonce: string;\n ok: true;\n protocolVersion: typeof NEXT_IPC_PROTOCOL_VERSION;\n requestId: string;\n type: \"spotpatch:next:configure-ack\";\n }>\n | Readonly<{\n code: \"CONFIGURATION_CONFLICT\" | \"CONFIGURATION_FAILED\" | \"INVALID_IPC\";\n nonce: string;\n ok: false;\n protocolVersion: typeof NEXT_IPC_PROTOCOL_VERSION;\n requestId: string;\n type: \"spotpatch:next:configure-ack\";\n }>;\n\nexport interface ParsedNextConfigureMessage extends Omit<\n NextConfigureMessage,\n \"options\"\n> {\n readonly options: ResolvedSpotPatchOptions;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(\n value: Readonly<Record<string, unknown>>,\n expectedKeys: readonly string[],\n): boolean {\n const actual = Object.keys(value).sort();\n const expected = [...expectedKeys].sort();\n return (\n actual.length === expected.length &&\n actual.every((key, index) => key === expected[index])\n );\n}\n\nexport function assertIpcMessageSize(value: unknown): void {\n let serialized: string;\n\n try {\n serialized = JSON.stringify(value);\n } catch (error: unknown) {\n throw new TypeError(\"The SpotPatch IPC message is not serializable.\", {\n cause: error,\n });\n }\n\n if (Buffer.byteLength(serialized, \"utf8\") > NEXT_IPC_MESSAGE_LIMIT_BYTES) {\n throw new RangeError(\"The SpotPatch IPC message exceeds the size limit.\");\n }\n}\n\nfunction parseCredentials(value: unknown): Readonly<Record<string, string>> {\n if (!isRecord(value) || Object.keys(value).length > 32) {\n throw new TypeError(\"The SpotPatch IPC credentials are invalid.\");\n }\n\n const entries = Object.entries(value);\n const credentials: Record<string, string> = {};\n\n for (const [name, credential] of entries) {\n if (\n !ENVIRONMENT_NAME_PATTERN.test(name) ||\n typeof credential !== \"string\" ||\n credential.length === 0 ||\n credential.length > 16_384 ||\n credential.includes(\"\\0\")\n ) {\n throw new TypeError(\"The SpotPatch IPC credentials are invalid.\");\n }\n\n credentials[name] = credential;\n }\n\n return Object.freeze(credentials);\n}\n\nexport function parseNextConfigureMessage(value: unknown): ParsedNextConfigureMessage {\n assertIpcMessageSize(value);\n\n if (\n !isRecord(value) ||\n !hasExactKeys(value, [\n \"appRoot\",\n \"credentials\",\n \"nonce\",\n \"options\",\n \"protocolVersion\",\n \"requestId\",\n \"type\",\n ]) ||\n value.type !== \"spotpatch:next:configure\" ||\n value.protocolVersion !== NEXT_IPC_PROTOCOL_VERSION ||\n typeof value.nonce !== \"string\" ||\n !ID_PATTERN.test(value.nonce) ||\n typeof value.requestId !== \"string\" ||\n !ID_PATTERN.test(value.requestId) ||\n typeof value.appRoot !== \"string\" ||\n !path.isAbsolute(value.appRoot) ||\n value.appRoot.length > 4_096 ||\n value.appRoot.includes(\"\\0\")\n ) {\n throw new TypeError(\"The SpotPatch configure IPC message is invalid.\");\n }\n\n return Object.freeze({\n appRoot: value.appRoot,\n credentials: parseCredentials(value.credentials),\n nonce: value.nonce,\n options: parseSerializedSpotPatchOptions(value.options),\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId: value.requestId,\n type: \"spotpatch:next:configure\",\n });\n}\n\nexport function parseNextConfigureAck(value: unknown): NextConfigureAck {\n assertIpcMessageSize(value);\n\n if (\n !isRecord(value) ||\n value.type !== \"spotpatch:next:configure-ack\" ||\n value.protocolVersion !== NEXT_IPC_PROTOCOL_VERSION ||\n typeof value.ok !== \"boolean\" ||\n typeof value.nonce !== \"string\" ||\n !ID_PATTERN.test(value.nonce) ||\n typeof value.requestId !== \"string\" ||\n !ID_PATTERN.test(value.requestId)\n ) {\n throw new TypeError(\"The SpotPatch configure IPC acknowledgement is invalid.\");\n }\n\n if (value.ok) {\n if (!hasExactKeys(value, [\"nonce\", \"ok\", \"protocolVersion\", \"requestId\", \"type\"])) {\n throw new TypeError(\"The SpotPatch configure IPC acknowledgement is invalid.\");\n }\n\n return Object.freeze({\n nonce: value.nonce,\n ok: true,\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId: value.requestId,\n type: \"spotpatch:next:configure-ack\",\n });\n }\n\n if (\n !hasExactKeys(value, [\n \"code\",\n \"nonce\",\n \"ok\",\n \"protocolVersion\",\n \"requestId\",\n \"type\",\n ]) ||\n (value.code !== \"CONFIGURATION_CONFLICT\" &&\n value.code !== \"CONFIGURATION_FAILED\" &&\n value.code !== \"INVALID_IPC\")\n ) {\n throw new TypeError(\"The SpotPatch configure IPC acknowledgement is invalid.\");\n }\n\n return Object.freeze({\n code: value.code,\n nonce: value.nonce,\n ok: false,\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId: value.requestId,\n type: \"spotpatch:next:configure-ack\",\n });\n}\n"],"mappings":"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","names":["path","ID_PATTERN","isRecord","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/config/with-spotpatch.ts","../src/internal/constants.ts","../src/config/handshake.ts","../src/internal/ipc.ts"],"sourcesContent":["import { createRequire } from \"node:module\";\nimport { realpath } from \"node:fs/promises\";\nimport { existsSync, realpathSync } from \"node:fs\";\nimport path from \"node:path\";\n\nimport {\n resolveCredentialEnvironment,\n resolveEnvironmentAiConfiguration,\n resolveProjectOptions,\n type SpotPatchOptions,\n} from \"@spotpatch/dev-server\";\nimport { SPOTPATCH_API_BASE } from \"@spotpatch/shared\";\nimport type { NextConfig } from \"next\";\nimport { PHASE_DEVELOPMENT_SERVER } from \"next/constants\";\n\nimport {\n NEXT_CLIENT_MODULE_ID,\n NEXT_DEFAULT_INCLUDE,\n NEXT_SOURCE_RULE_KEYS,\n} from \"../internal/constants.js\";\nimport { configureNextRuntime } from \"./handshake.js\";\n\nexport type NextSpotPatchOptions = Omit<SpotPatchOptions, \"allowLan\" | \"dataFlow\"> &\n Readonly<{\n allowLan?: false;\n dataFlow?: false;\n }>;\n\nexport interface NextConfigContext<\n Config extends object = Readonly<Record<string, unknown>>,\n> {\n readonly defaultConfig: Config;\n}\n\nexport type NextConfigFactory<\n Config extends object = Readonly<Record<string, unknown>>,\n> = (phase: string, context: NextConfigContext<Config>) => Config | Promise<Config>;\n\nexport type NextConfigInput<Config extends object = Readonly<Record<string, unknown>>> =\n Config | NextConfigFactory<Config>;\n\nexport type NextConfigEnhancer = <\n Config extends object = Readonly<Record<string, unknown>>,\n>(\n input?: NextConfigInput<Config>,\n) => NextConfigFactory<Config>;\n\ninterface AdapterModulePaths {\n readonly client: string;\n readonly loader: string;\n readonly noop: string;\n readonly turbopackClient: string;\n readonly turbopackLoader: string;\n readonly turbopackNoop: string;\n}\n\ntype WebpackConfig = Record<string, unknown>;\ntype WebpackHandler = (config: unknown, context: unknown) => unknown;\n\ninterface WebpackContext extends Readonly<Record<string, unknown>> {\n readonly dev: boolean;\n}\n\ntype TurbopackRules = NonNullable<NonNullable<NextConfig[\"turbopack\"]>[\"rules\"]>;\n\nconst configuredWebpackConfigs = new WeakSet();\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readWebpackHandler(config: NextConfig): WebpackHandler | undefined {\n const value = (config as unknown as Readonly<Record<string, unknown>>).webpack;\n\n if (value === undefined) {\n return undefined;\n }\n\n if (typeof value !== \"function\") {\n throw new TypeError(\"SpotPatch requires nextConfig.webpack to be a function.\");\n }\n\n return value as WebpackHandler;\n}\n\nfunction requireWebpackConfig(value: unknown): WebpackConfig {\n if (!isRecord(value)) {\n throw new TypeError(\"SpotPatch received an invalid webpack configuration.\");\n }\n\n return value;\n}\n\nfunction requireWebpackContext(value: unknown): WebpackContext {\n if (!isRecord(value) || typeof value.dev !== \"boolean\") {\n throw new TypeError(\"SpotPatch received an invalid webpack context.\");\n }\n\n return value as WebpackContext;\n}\n\nfunction isWithinRoot(root: string, candidate: string): boolean {\n const relative = path.relative(root, candidate);\n return (\n relative === \"\" ||\n (!relative.startsWith(`..${path.sep}`) &&\n relative !== \"..\" &&\n !path.isAbsolute(relative))\n );\n}\n\nfunction findCommonFilesystemRoot(paths: readonly string[]): string {\n const normalized = paths.map((value) => path.resolve(value));\n const firstPath = normalized[0];\n\n if (firstPath === undefined) {\n throw new Error(\"SpotPatch requires at least one filesystem path.\");\n }\n\n let candidate = firstPath;\n\n while (!normalized.every((value) => isWithinRoot(candidate, value))) {\n const parent = path.dirname(candidate);\n\n if (parent === candidate) {\n throw new Error(\"SpotPatch paths do not share a safe filesystem root.\");\n }\n\n candidate = parent;\n }\n\n if (candidate === path.parse(candidate).root) {\n throw new Error(\"SpotPatch refuses to configure the filesystem root.\");\n }\n\n return candidate;\n}\n\nfunction findLogicalAdapterRoot(\n appRoot: string,\n resolvedAdapterRoot: string,\n): string | undefined {\n let directory = appRoot;\n\n while (directory !== path.dirname(directory)) {\n const candidate = path.join(directory, \"node_modules\", \"@spotpatch\", \"next\");\n\n if (existsSync(candidate) && realpathSync(candidate) === resolvedAdapterRoot) {\n return candidate;\n }\n\n directory = path.dirname(directory);\n }\n\n return undefined;\n}\n\nfunction relativeModulePath(appRoot: string, target: string): string {\n const relative = path.relative(appRoot, target).split(path.sep).join(\"/\");\n return relative.startsWith(\".\") ? relative : `./${relative}`;\n}\n\nfunction resolveAdapterModulePaths(appRoot: string): AdapterModulePaths {\n const resolveFromApplication = createRequire(path.join(appRoot, \"package.json\"));\n const client = resolveFromApplication.resolve(\"@spotpatch/next/client\");\n const loader = resolveFromApplication.resolve(\"@spotpatch/next/loader\");\n const resolvedAdapterRoot = path.dirname(loader);\n const noop = path.join(resolvedAdapterRoot, \"dist\", \"noop.cjs\");\n const logicalAdapterRoot = findLogicalAdapterRoot(appRoot, resolvedAdapterRoot);\n const logicalClient =\n logicalAdapterRoot === undefined\n ? undefined\n : path.join(logicalAdapterRoot, \"dist\", \"client.js\");\n const logicalNoop =\n logicalAdapterRoot === undefined\n ? undefined\n : path.join(logicalAdapterRoot, \"dist\", \"noop.js\");\n\n return Object.freeze({\n client,\n loader,\n noop,\n turbopackClient:\n logicalClient === undefined ? client : relativeModulePath(appRoot, logicalClient),\n turbopackLoader:\n logicalAdapterRoot === undefined\n ? loader\n : path.join(logicalAdapterRoot, \"loader.cjs\"),\n turbopackNoop:\n logicalNoop === undefined ? noop : relativeModulePath(appRoot, logicalNoop),\n });\n}\n\nfunction mergeTurbopackRoot(\n config: NextConfig,\n requiredPaths: readonly string[],\n): string {\n const commonRoot = findCommonFilesystemRoot(requiredPaths);\n const existingRoot = config.turbopack?.root;\n\n if (\n existingRoot !== undefined &&\n !requiredPaths.every((value) => isWithinRoot(existingRoot, value))\n ) {\n throw new Error(\n \"SpotPatch cannot use the existing turbopack.root because it excludes an adapter module.\",\n );\n }\n\n return existingRoot ?? commonRoot;\n}\n\nfunction mergeTurbopackAlias(\n config: NextConfig,\n noopPath: string,\n): NonNullable<NextConfig[\"turbopack\"]> {\n const aliases = config.turbopack?.resolveAlias ?? {};\n const existing = aliases[NEXT_CLIENT_MODULE_ID];\n\n if (existing !== undefined && existing !== noopPath) {\n throw new Error(\n `SpotPatch cannot replace turbopack.resolveAlias[${NEXT_CLIENT_MODULE_ID}].`,\n );\n }\n\n return {\n ...config.turbopack,\n resolveAlias: {\n ...aliases,\n [NEXT_CLIENT_MODULE_ID]: noopPath,\n },\n };\n}\n\nfunction mergeWebpackAlias(config: WebpackConfig, noopPath: string): void {\n const resolveValue = config.resolve;\n\n if (resolveValue !== undefined && !isRecord(resolveValue)) {\n throw new Error(\"SpotPatch requires webpack resolve to be an object.\");\n }\n\n const resolve = resolveValue ?? {};\n const alias = resolve.alias ?? {};\n\n if (!isRecord(alias)) {\n throw new Error(\"SpotPatch requires webpack resolve.alias to be an object.\");\n }\n\n const existing = alias[NEXT_CLIENT_MODULE_ID];\n\n if (existing !== undefined && existing !== noopPath) {\n throw new Error(\n `SpotPatch cannot replace webpack resolve.alias[${NEXT_CLIENT_MODULE_ID}].`,\n );\n }\n\n resolve.alias = { ...alias, [NEXT_CLIENT_MODULE_ID]: noopPath };\n config.resolve = resolve;\n}\n\nfunction scopeWebpackFilesystemCache(\n config: WebpackConfig,\n registryEpoch: string,\n): void {\n const cache = config.cache;\n\n if (isRecord(cache) && cache.type === \"filesystem\") {\n const currentVersion = typeof cache.version === \"string\" ? cache.version : \"\";\n cache.version = [currentVersion, `spotpatch:${registryEpoch}`]\n .filter(Boolean)\n .join(\"|\");\n }\n}\n\nfunction appendWebpackLoader(\n config: WebpackConfig,\n context: WebpackContext,\n loaderPath: string,\n registryEpoch: string,\n appRoot: string,\n): void {\n if (!context.dev) {\n return;\n }\n\n const module = config.module;\n\n if (!isRecord(module) || !Array.isArray(module.rules)) {\n throw new Error(\"SpotPatch requires webpack module.rules to be an array.\");\n }\n\n if (configuredWebpackConfigs.has(config)) {\n return;\n }\n\n scopeWebpackFilesystemCache(config, registryEpoch);\n const rule = {\n enforce: \"pre\" as const,\n include: appRoot,\n test: /\\.(?:jsx|tsx)$/u,\n use: [\n {\n loader: loaderPath,\n options: { registryEpoch },\n },\n ],\n };\n module.rules.push(rule);\n configuredWebpackConfigs.add(config);\n}\n\nfunction rewriteCanClaimPrivateApi(source: string): boolean {\n return (\n source === SPOTPATCH_API_BASE ||\n source.startsWith(`${SPOTPATCH_API_BASE}/`) ||\n source.startsWith(\"/:path\") ||\n source.startsWith(\"/:slug\") ||\n source.includes(\"(.*)\")\n );\n}\n\nfunction assertRewriteCompatibility(\n rewrites: readonly Readonly<{ source: string }>[] | undefined,\n): void {\n const conflict = rewrites?.find(({ source }) => rewriteCanClaimPrivateApi(source));\n\n if (conflict !== undefined) {\n throw new Error(\n `SpotPatch API prefix conflicts with the host rewrite ${conflict.source}.`,\n );\n }\n}\n\nfunction createRewrites(\n config: NextConfig,\n sidecarOrigin: string,\n): NonNullable<NextConfig[\"rewrites\"]> {\n return async () => {\n const spotPatchRewrite = {\n basePath: false as const,\n destination: `${sidecarOrigin}${SPOTPATCH_API_BASE}/:path*`,\n source: `${SPOTPATCH_API_BASE}/:path*`,\n };\n const original = await config.rewrites?.();\n\n if (original === undefined) {\n return {\n beforeFiles: [spotPatchRewrite],\n afterFiles: [],\n fallback: [],\n };\n }\n\n if (Array.isArray(original)) {\n assertRewriteCompatibility(original);\n return {\n beforeFiles: [spotPatchRewrite],\n afterFiles: original,\n fallback: [],\n };\n }\n\n const beforeFiles = original.beforeFiles ?? [];\n const afterFiles = original.afterFiles ?? [];\n const fallback = original.fallback ?? [];\n assertRewriteCompatibility([...beforeFiles, ...afterFiles, ...fallback]);\n return {\n beforeFiles: [spotPatchRewrite, ...beforeFiles],\n afterFiles,\n fallback,\n };\n };\n}\n\nfunction createWebpackWrapper(input: {\n readonly appRoot: string;\n readonly development: boolean;\n readonly loaderPath: string;\n readonly noopPath: string;\n readonly original: WebpackHandler | undefined;\n readonly registryEpoch?: string;\n}): WebpackHandler {\n return (configValue, contextValue) => {\n const config = requireWebpackConfig(configValue);\n const context = requireWebpackContext(contextValue);\n const configuredValue = input.original?.(configValue, contextValue);\n const configured =\n configuredValue === undefined ? config : requireWebpackConfig(configuredValue);\n\n if (input.development) {\n if (input.registryEpoch === undefined) {\n throw new Error(\"SpotPatch is missing the development registry epoch.\");\n }\n\n appendWebpackLoader(\n configured,\n context,\n input.loaderPath,\n input.registryEpoch,\n input.appRoot,\n );\n } else {\n mergeWebpackAlias(configured, input.noopPath);\n }\n\n return configured;\n };\n}\n\nfunction mergeProductionConfig(\n config: NextConfig,\n appRoot: string,\n paths: AdapterModulePaths,\n): NextConfig {\n const turbopackRoot = mergeTurbopackRoot(config, [appRoot, paths.noop]);\n\n return {\n ...config,\n turbopack: {\n ...mergeTurbopackAlias(config, paths.turbopackNoop),\n root: turbopackRoot,\n },\n webpack: createWebpackWrapper({\n appRoot,\n development: false,\n loaderPath: paths.loader,\n noopPath: paths.noop,\n original: readWebpackHandler(config),\n }),\n };\n}\n\nfunction mergeDevelopmentConfig(\n config: NextConfig,\n appRoot: string,\n paths: AdapterModulePaths,\n registryEpoch: string,\n sidecarOrigin: string,\n): NextConfig {\n const turbopackRoot = mergeTurbopackRoot(config, [\n appRoot,\n paths.client,\n paths.loader,\n ]);\n const existingRules = config.turbopack?.rules ?? {};\n const spotPatchRules: TurbopackRules = {};\n\n for (const key of NEXT_SOURCE_RULE_KEYS) {\n if (existingRules[key] !== undefined) {\n throw new Error(\n `SpotPatch cannot replace turbopack.rules[${JSON.stringify(key)}].`,\n );\n }\n\n spotPatchRules[key] = {\n condition: { all: [\"development\", { not: \"foreign\" }] },\n loaders: [\n {\n loader: paths.turbopackLoader,\n options: { registryEpoch },\n },\n ],\n };\n }\n\n return {\n ...config,\n rewrites: createRewrites(config, sidecarOrigin),\n turbopack: {\n ...mergeTurbopackAlias(config, paths.turbopackClient),\n root: turbopackRoot,\n rules: { ...existingRules, ...spotPatchRules },\n },\n webpack: createWebpackWrapper({\n appRoot,\n development: true,\n loaderPath: paths.loader,\n noopPath: paths.noop,\n original: readWebpackHandler(config),\n registryEpoch,\n }),\n };\n}\n\nasync function resolveInputConfig<Config extends object>(\n input: NextConfigInput<Config> | undefined,\n phase: string,\n context: NextConfigContext<Config>,\n): Promise<Config> {\n if (typeof input === \"function\") {\n return await input(phase, context);\n }\n\n return input ?? ({} as Config);\n}\n\nexport function withSpotPatch(\n userOptions: NextSpotPatchOptions = {},\n): NextConfigEnhancer {\n const requestedDataFlow = (userOptions as Readonly<Record<string, unknown>>).dataFlow;\n\n if (requestedDataFlow !== undefined && requestedDataFlow !== false) {\n throw new RangeError(\n \"SpotPatch Next does not support component dataFlow yet; use dataFlow only with @spotpatch/vite.\",\n );\n }\n\n return <Config extends object = Readonly<Record<string, unknown>>>(\n input?: NextConfigInput<Config>,\n ): NextConfigFactory<Config> =>\n async (phase, context): Promise<Config> => {\n const inputConfig = await resolveInputConfig(input, phase, context);\n const config = inputConfig as unknown as NextConfig;\n const appRoot = await realpath(process.cwd());\n const paths = resolveAdapterModulePaths(appRoot);\n\n if (phase !== PHASE_DEVELOPMENT_SERVER) {\n return mergeProductionConfig(config, appRoot, paths) as unknown as Config;\n }\n\n const environmentAi =\n userOptions.ai === undefined\n ? resolveEnvironmentAiConfiguration(process.env).ai\n : false;\n const options = await resolveProjectOptions({\n appRoot,\n environmentAi,\n options: {\n ...userOptions,\n include: userOptions.include ?? NEXT_DEFAULT_INCLUDE,\n },\n });\n\n if (options.allowLan) {\n throw new RangeError(\n \"SpotPatch Next does not support allowLan; use a loopback development host.\",\n );\n }\n\n const carrier = await configureNextRuntime({\n appRoot,\n credentials: resolveCredentialEnvironment(options, process.env),\n options,\n });\n\n if (!options.enabled) {\n return mergeProductionConfig(config, appRoot, paths) as unknown as Config;\n }\n\n return mergeDevelopmentConfig(\n config,\n appRoot,\n paths,\n carrier.registryEpoch,\n carrier.sidecarOrigin,\n ) as unknown as Config;\n };\n}\n","export const NEXT_IPC_PROTOCOL_VERSION = 1 as const;\nexport const NEXT_IPC_MESSAGE_LIMIT_BYTES = 256 * 1024;\nexport const NEXT_IPC_TIMEOUT_MS = 15_000;\nexport const NEXT_INTERNAL_REGISTRATION_PATH =\n \"/__spotpatch-internal/register\" as const;\nexport const NEXT_INTERNAL_CONFIGURATION_PATH =\n \"/__spotpatch-internal/configure\" as const;\n\nexport const NEXT_ENVIRONMENT_KEYS = Object.freeze({\n appRoot: \"SPOTPATCH_NEXT_APP_ROOT\",\n bundler: \"SPOTPATCH_NEXT_BUNDLER\",\n configurationSecret: \"SPOTPATCH_NEXT_CONFIGURATION_SECRET\",\n internalOrigin: \"SPOTPATCH_NEXT_INTERNAL_ORIGIN\",\n internalSecret: \"SPOTPATCH_NEXT_INTERNAL_SECRET\",\n launchNonce: \"SPOTPATCH_NEXT_LAUNCH_NONCE\",\n registryEpoch: \"SPOTPATCH_NEXT_REGISTRY_EPOCH\",\n sidecarOrigin: \"SPOTPATCH_NEXT_SIDECAR_ORIGIN\",\n} as const);\n\nexport const NEXT_SOURCE_RULE_KEYS = Object.freeze([\"*.jsx\", \"*.tsx\"] as const);\nexport const NEXT_CLIENT_MODULE_ID = \"@spotpatch/next/client\" as const;\n\nexport const NEXT_DEFAULT_INCLUDE = Object.freeze([/\\.(?:jsx|tsx)$/u]);\n","import { randomBytes } from \"node:crypto\";\n\nimport {\n serializeResolvedSpotPatchOptions,\n type ResolvedSpotPatchOptions,\n} from \"@spotpatch/dev-server\";\n\nimport {\n NEXT_ENVIRONMENT_KEYS,\n NEXT_INTERNAL_CONFIGURATION_PATH,\n NEXT_IPC_PROTOCOL_VERSION,\n NEXT_IPC_TIMEOUT_MS,\n} from \"../internal/constants.js\";\nimport {\n assertIpcMessageSize,\n parseNextConfigureAck,\n type NextConfigureMessage,\n} from \"../internal/ipc.js\";\n\nconst ID_PATTERN = /^[A-Za-z0-9_-]{16,128}$/u;\nconst CONFIGURATION_SECRET_PATTERN = /^[A-Za-z0-9_-]{32,128}$/u;\nconst ACKNOWLEDGEMENT_LIMIT_BYTES = 4_096;\n\nexport interface NextRuntimeCarrier {\n readonly registryEpoch: string;\n readonly sidecarOrigin: string;\n}\n\ninterface ConfigureInput {\n readonly appRoot: string;\n readonly credentials: Readonly<Record<string, string>>;\n readonly options: ResolvedSpotPatchOptions;\n}\n\nlet activeSignature: string | undefined;\nlet activeConfiguration: Promise<NextRuntimeCarrier> | undefined;\n\nfunction readRequiredEnvironment(name: string): string {\n const value = process.env[name];\n\n if (typeof value !== \"string\" || value.length === 0) {\n throw new Error(\n \"SpotPatch Next development must be started with `spotpatch-next dev`.\",\n );\n }\n\n return value;\n}\n\nfunction readLoopbackOrigin(name: string): string {\n const value = readRequiredEnvironment(name);\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n throw new Error(\"SpotPatch received an invalid CLI transport origin.\");\n }\n\n if (\n url.origin !== value ||\n url.protocol !== \"http:\" ||\n url.hostname !== \"127.0.0.1\"\n ) {\n throw new Error(\"SpotPatch received an invalid CLI transport origin.\");\n }\n\n return url.origin;\n}\n\nfunction configurationSignature(input: ConfigureInput): string {\n return JSON.stringify({\n appRoot: input.appRoot,\n credentials: input.credentials,\n options: serializeResolvedSpotPatchOptions(input.options),\n });\n}\n\nasync function sendConfiguration(input: ConfigureInput): Promise<NextRuntimeCarrier> {\n const nonce = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.launchNonce);\n const expectedAppRoot = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.appRoot);\n const registryEpoch = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.registryEpoch);\n const sidecarOrigin = readLoopbackOrigin(NEXT_ENVIRONMENT_KEYS.sidecarOrigin);\n const internalOrigin = readLoopbackOrigin(NEXT_ENVIRONMENT_KEYS.internalOrigin);\n readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.internalSecret);\n const configurationSecret = readRequiredEnvironment(\n NEXT_ENVIRONMENT_KEYS.configurationSecret,\n );\n const bundler = readRequiredEnvironment(NEXT_ENVIRONMENT_KEYS.bundler);\n\n if (\n input.appRoot !== expectedAppRoot ||\n internalOrigin !== sidecarOrigin ||\n (bundler !== \"turbopack\" && bundler !== \"webpack\") ||\n !CONFIGURATION_SECRET_PATTERN.test(configurationSecret) ||\n !ID_PATTERN.test(nonce) ||\n !ID_PATTERN.test(registryEpoch)\n ) {\n throw new Error(\"SpotPatch received an invalid CLI launch identity.\");\n }\n\n const requestId = randomBytes(18).toString(\"base64url\");\n const message = Object.freeze({\n appRoot: input.appRoot,\n credentials: input.credentials,\n nonce,\n options: serializeResolvedSpotPatchOptions(input.options),\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId,\n type: \"spotpatch:next:configure\",\n }) satisfies NextConfigureMessage;\n assertIpcMessageSize(message);\n let response: Response;\n\n try {\n response = await fetch(new URL(NEXT_INTERNAL_CONFIGURATION_PATH, internalOrigin), {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"X-SpotPatch-Configuration\": configurationSecret,\n },\n body: JSON.stringify(message),\n signal: AbortSignal.timeout(NEXT_IPC_TIMEOUT_MS),\n });\n } catch {\n throw new Error(\"SpotPatch Next configuration transport failed.\");\n }\n\n const declaredLength = Number(response.headers.get(\"content-length\"));\n\n if (Number.isFinite(declaredLength) && declaredLength > ACKNOWLEDGEMENT_LIMIT_BYTES) {\n await response.body?.cancel();\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n const text = await response.text();\n\n if (Buffer.byteLength(text, \"utf8\") > ACKNOWLEDGEMENT_LIMIT_BYTES) {\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n let acknowledgementValue: unknown;\n\n try {\n acknowledgementValue = JSON.parse(text) as unknown;\n } catch {\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n const acknowledgement = parseNextConfigureAck(acknowledgementValue);\n\n if (\n !response.ok ||\n acknowledgement.nonce !== nonce ||\n acknowledgement.requestId !== requestId\n ) {\n throw new Error(\"SpotPatch Next configuration response is invalid.\");\n }\n\n if (!acknowledgement.ok) {\n throw new Error(`SpotPatch Next configuration failed (${acknowledgement.code}).`);\n }\n\n return Object.freeze({ registryEpoch, sidecarOrigin });\n}\n\nexport function configureNextRuntime(\n input: ConfigureInput,\n): Promise<NextRuntimeCarrier> {\n const signature = configurationSignature(input);\n\n if (activeConfiguration !== undefined) {\n if (activeSignature !== signature) {\n return Promise.reject(\n new Error(\"SpotPatch Next received inconsistent repeated configuration.\"),\n );\n }\n\n return activeConfiguration;\n }\n\n activeSignature = signature;\n activeConfiguration = sendConfiguration(input).catch((error: unknown) => {\n activeConfiguration = undefined;\n activeSignature = undefined;\n throw error;\n });\n return activeConfiguration;\n}\n","import path from \"node:path\";\n\nimport {\n parseSerializedSpotPatchOptions,\n type ResolvedSpotPatchOptions,\n type SerializedSpotPatchOptions,\n} from \"@spotpatch/dev-server\";\n\nimport {\n NEXT_IPC_MESSAGE_LIMIT_BYTES,\n NEXT_IPC_PROTOCOL_VERSION,\n} from \"./constants.js\";\n\nconst ID_PATTERN = /^[A-Za-z0-9_-]{16,128}$/u;\nconst ENVIRONMENT_NAME_PATTERN = /^[A-Z][A-Z0-9_]{1,127}$/u;\n\nexport interface NextConfigureMessage {\n readonly appRoot: string;\n readonly credentials: Readonly<Record<string, string>>;\n readonly nonce: string;\n readonly options: SerializedSpotPatchOptions;\n readonly protocolVersion: typeof NEXT_IPC_PROTOCOL_VERSION;\n readonly requestId: string;\n readonly type: \"spotpatch:next:configure\";\n}\n\nexport type NextConfigureAck =\n | Readonly<{\n nonce: string;\n ok: true;\n protocolVersion: typeof NEXT_IPC_PROTOCOL_VERSION;\n requestId: string;\n type: \"spotpatch:next:configure-ack\";\n }>\n | Readonly<{\n code: \"CONFIGURATION_CONFLICT\" | \"CONFIGURATION_FAILED\" | \"INVALID_IPC\";\n nonce: string;\n ok: false;\n protocolVersion: typeof NEXT_IPC_PROTOCOL_VERSION;\n requestId: string;\n type: \"spotpatch:next:configure-ack\";\n }>;\n\nexport interface ParsedNextConfigureMessage extends Omit<\n NextConfigureMessage,\n \"options\"\n> {\n readonly options: ResolvedSpotPatchOptions;\n}\n\nfunction isRecord(value: unknown): value is Readonly<Record<string, unknown>> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction hasExactKeys(\n value: Readonly<Record<string, unknown>>,\n expectedKeys: readonly string[],\n): boolean {\n const actual = Object.keys(value).sort();\n const expected = [...expectedKeys].sort();\n return (\n actual.length === expected.length &&\n actual.every((key, index) => key === expected[index])\n );\n}\n\nexport function assertIpcMessageSize(value: unknown): void {\n let serialized: string;\n\n try {\n serialized = JSON.stringify(value);\n } catch (error: unknown) {\n throw new TypeError(\"The SpotPatch IPC message is not serializable.\", {\n cause: error,\n });\n }\n\n if (Buffer.byteLength(serialized, \"utf8\") > NEXT_IPC_MESSAGE_LIMIT_BYTES) {\n throw new RangeError(\"The SpotPatch IPC message exceeds the size limit.\");\n }\n}\n\nfunction parseCredentials(value: unknown): Readonly<Record<string, string>> {\n if (!isRecord(value) || Object.keys(value).length > 32) {\n throw new TypeError(\"The SpotPatch IPC credentials are invalid.\");\n }\n\n const entries = Object.entries(value);\n const credentials: Record<string, string> = {};\n\n for (const [name, credential] of entries) {\n if (\n !ENVIRONMENT_NAME_PATTERN.test(name) ||\n typeof credential !== \"string\" ||\n credential.length === 0 ||\n credential.length > 16_384 ||\n credential.includes(\"\\0\")\n ) {\n throw new TypeError(\"The SpotPatch IPC credentials are invalid.\");\n }\n\n credentials[name] = credential;\n }\n\n return Object.freeze(credentials);\n}\n\nexport function parseNextConfigureMessage(value: unknown): ParsedNextConfigureMessage {\n assertIpcMessageSize(value);\n\n if (\n !isRecord(value) ||\n !hasExactKeys(value, [\n \"appRoot\",\n \"credentials\",\n \"nonce\",\n \"options\",\n \"protocolVersion\",\n \"requestId\",\n \"type\",\n ]) ||\n value.type !== \"spotpatch:next:configure\" ||\n value.protocolVersion !== NEXT_IPC_PROTOCOL_VERSION ||\n typeof value.nonce !== \"string\" ||\n !ID_PATTERN.test(value.nonce) ||\n typeof value.requestId !== \"string\" ||\n !ID_PATTERN.test(value.requestId) ||\n typeof value.appRoot !== \"string\" ||\n !path.isAbsolute(value.appRoot) ||\n value.appRoot.length > 4_096 ||\n value.appRoot.includes(\"\\0\")\n ) {\n throw new TypeError(\"The SpotPatch configure IPC message is invalid.\");\n }\n\n return Object.freeze({\n appRoot: value.appRoot,\n credentials: parseCredentials(value.credentials),\n nonce: value.nonce,\n options: parseSerializedSpotPatchOptions(value.options),\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId: value.requestId,\n type: \"spotpatch:next:configure\",\n });\n}\n\nexport function parseNextConfigureAck(value: unknown): NextConfigureAck {\n assertIpcMessageSize(value);\n\n if (\n !isRecord(value) ||\n value.type !== \"spotpatch:next:configure-ack\" ||\n value.protocolVersion !== NEXT_IPC_PROTOCOL_VERSION ||\n typeof value.ok !== \"boolean\" ||\n typeof value.nonce !== \"string\" ||\n !ID_PATTERN.test(value.nonce) ||\n typeof value.requestId !== \"string\" ||\n !ID_PATTERN.test(value.requestId)\n ) {\n throw new TypeError(\"The SpotPatch configure IPC acknowledgement is invalid.\");\n }\n\n if (value.ok) {\n if (!hasExactKeys(value, [\"nonce\", \"ok\", \"protocolVersion\", \"requestId\", \"type\"])) {\n throw new TypeError(\"The SpotPatch configure IPC acknowledgement is invalid.\");\n }\n\n return Object.freeze({\n nonce: value.nonce,\n ok: true,\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId: value.requestId,\n type: \"spotpatch:next:configure-ack\",\n });\n }\n\n if (\n !hasExactKeys(value, [\n \"code\",\n \"nonce\",\n \"ok\",\n \"protocolVersion\",\n \"requestId\",\n \"type\",\n ]) ||\n (value.code !== \"CONFIGURATION_CONFLICT\" &&\n value.code !== \"CONFIGURATION_FAILED\" &&\n value.code !== \"INVALID_IPC\")\n ) {\n throw new TypeError(\"The SpotPatch configure IPC acknowledgement is invalid.\");\n }\n\n return Object.freeze({\n code: value.code,\n nonce: value.nonce,\n ok: false,\n protocolVersion: NEXT_IPC_PROTOCOL_VERSION,\n requestId: value.requestId,\n type: \"spotpatch:next:configure-ack\",\n });\n}\n"],"mappings":"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","names":["path","ID_PATTERN","isRecord","path"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spotpatch/next",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Development-only Next.js adapter and CLI for SpotPatch.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -90,10 +90,11 @@
|
|
|
90
90
|
"bippy": "0.6.1",
|
|
91
91
|
"magic-string": "1.1.0",
|
|
92
92
|
"oxc-parser": "0.143.0",
|
|
93
|
+
"@spotpatch/bridge": "^0.2.0",
|
|
93
94
|
"@spotpatch/compiler": "^0.2.0",
|
|
94
|
-
"@spotpatch/dev-server": "^0.
|
|
95
|
-
"@spotpatch/runtime": "^1.
|
|
96
|
-
"@spotpatch/shared": "^1.
|
|
95
|
+
"@spotpatch/dev-server": "^0.7.0",
|
|
96
|
+
"@spotpatch/runtime": "^1.11.0",
|
|
97
|
+
"@spotpatch/shared": "^1.11.0"
|
|
97
98
|
},
|
|
98
99
|
"peerDependencies": {
|
|
99
100
|
"next": ">=15.3.0 <17.0.0",
|