@interfere/vite 11.0.0-canary.3 → 11.0.0-canary.4
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/dist/internal/build/pipeline.d.mts +1 -0
- package/dist/internal/build/pipeline.mjs +1 -1
- package/dist/internal/server/request-trace.d.mts +9 -0
- package/dist/internal/server/request-trace.mjs +1 -0
- package/dist/package.mjs +1 -1
- package/dist/plugin.mjs +2 -2
- package/dist/tanstack-start.d.mts +6 -0
- package/dist/tanstack-start.mjs +1 -0
- package/package.json +17 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
import{cleanupSourceMaps,uploadSourceMaps}from"./source-maps.mjs";import{parseEnvValue}from"@interfere/types/sdk/env";import{releaseSlugSchema}from"@interfere/types/releases/slug";import{execSync}from"node:child_process";import{HTTPClient,Interfere}from"@interfere/sdk";import{releaseDestinationProviderSchema}from"@interfere/types/integrations";import{resolveCliReleaseDestination}from"@interfere/types/sdk/cli-destination";const sources={github:resolveGithubSource},destinations={vercel:resolveVercelDestination,cloudflare:resolveCloudflareDestination,cli:resolveCliDestination};async function timed(fn){let start=performance.now();return[await fn(),Math.round(performance.now()-start)]}function createSdkClient(opts){let httpClient=new HTTPClient;return httpClient.addHook(`beforeRequest`,request=>{let next=new Request(request);return next.headers.set(`Authorization`,`Bearer ${opts.apiKey}`),next}),{httpClient,sdk:new Interfere({serverURL:opts.apiUrl,httpClient}),security:{apiKey:opts.apiKey}}}function resolveReleaseRequest(buildId,releaseSlug,producerVersion,config){if(!config.surface.sourceProvider)return{ok:!1,reason:`missing_source_provider`};let destinationProvider=releaseDestinationProviderSchema.safeParse(config.surface.destinationProvider);return destinationProvider.success?{ok:!0,request:{source:sources[config.surface.sourceProvider](),destination:destinations[destinationProvider.data](releaseSlug),buildId,slug:releaseSlug,producerVersion}}:{ok:!1,reason:`missing_destination_provider`}}async function runReleasePipeline(input){let{apiKey,apiUrl,bundler,discovery,releasesConfig}=input,releaseRequest=resolveReleaseRequest(input.buildId,input.releaseSlug,input.producerVersion,releasesConfig);if(!releaseRequest.ok)return{ok:!1,failure:{kind:releaseRequest.reason,config:releasesConfig}};let start=performance.now(),{httpClient,sdk,security}=createSdkClient({apiKey,apiUrl}),[release,createReleaseMs]=await timed(()=>sdk.releases.create(security,releaseRequest.request)),releaseSlug=releaseSlugSchema.parse(release.destination.slug),buildId=release.build.hash??input.buildId,[{totalBytes},uploadMs]=await timed(()=>uploadSourceMaps({apiUrl,bundler,discovered:discovery,httpClient,releaseSlug})),[,preflightMs]=await timed(()=>sdk.releases.preflight(security,{releaseSlug})),[{failures},cleanupMs]=await timed(()=>cleanupSourceMaps(discovery.files));return{ok:!0,data:{buildId,cleanupFailures:failures,config:releasesConfig,fileCount:discovery.files.length,release:{...release,destination:{...release.destination,slug:releaseSlug}},releaseSlug,timing:{createRelease:createReleaseMs,upload:uploadMs,preflight:preflightMs,cleanup:cleanupMs,total:Math.round(performance.now()-start),fileCount:discovery.files.length,totalBytes}}}}function runGitCommand(command){try{let output=execSync(command,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim();return output.length>0?output:null}catch{return null}}function resolveGithubSource(){return{provider:`github`,branch:parseEnvValue(process.env.VERCEL_GIT_COMMIT_REF)??parseEnvValue(process.env.GITHUB_REF_NAME)??parseEnvValue(process.env.GITHUB_HEAD_REF)??runGitCommand(`git rev-parse --abbrev-ref HEAD`)??`unknown`,commitMessage:parseEnvValue(process.env.VERCEL_GIT_COMMIT_MESSAGE)??runGitCommand(`git log -1 --pretty=%B`)??``,commitSha:parseEnvValue(process.env.VERCEL_GIT_COMMIT_SHA)??parseEnvValue(process.env.GITHUB_SHA)??runGitCommand(`git rev-parse HEAD`)}}function resolveVercelDestination(){let environment=parseEnvValue(process.env.VERCEL_ENV??process.env.VERCEL_TARGET_ENV),deploymentId=parseEnvValue(process.env.VERCEL_DEPLOYMENT_ID);return{provider:`vercel`,destinationReleaseId:deploymentId,environment,deploymentId,deploymentUrl:resolveDeploymentUrl(),environmentName:environment,environmentTarget:environment}}function resolveDeploymentUrl(){let deploymentUrl=parseEnvValue(process.env.VERCEL_URL);return deploymentUrl===null?null:deploymentUrl.startsWith(`https://`)||deploymentUrl.startsWith(`http://`)?deploymentUrl:`https://${deploymentUrl}`}function resolveCloudflareDestination(){let raw=parseEnvValue(process.env.CF_VERSION_METADATA),versionMetadata=null;if(raw)try{versionMetadata=JSON.parse(raw)}catch{versionMetadata=null}let versionId=parseEnvValue(process.env.CF_VERSION_ID)??versionMetadata?.id??parseEnvValue(process.env.WORKERS_CI_BUILD_UUID)??null,scriptName=parseEnvValue(process.env.CF_WORKER_NAME)??parseEnvValue(process.env.WORKERS_CI_SCRIPT_NAME)??null,accountId=parseEnvValue(process.env.CF_ACCOUNT_ID)??parseEnvValue(process.env.CLOUDFLARE_ACCOUNT_ID)??null,environment=parseEnvValue(process.env.WORKERS_CI_BRANCH)??versionMetadata?.tag??null;return{provider:`cloudflare`,destinationReleaseId:versionId,environment,versionId,scriptName,accountId,deploymentUrl:resolveCloudflareDeploymentUrl(),environmentName:environment,environmentTarget:environment}}function resolveCloudflareDeploymentUrl(){let candidate=parseEnvValue(process.env.CF_PAGES_URL)??parseEnvValue(process.env.WORKERS_CI_DEPLOY_URL);return candidate===null?null:candidate.startsWith(`https://`)||candidate.startsWith(`http://`)?candidate:`https://${candidate}`}function resolveCliDestination(releaseSlug){return resolveCliReleaseDestination(process.env,releaseSlug)}export{createSdkClient,runReleasePipeline};
|
|
1
|
+
import{cleanupSourceMaps,uploadSourceMaps}from"./source-maps.mjs";import{parseEnvValue}from"@interfere/types/sdk/env";import{releaseSlugSchema}from"@interfere/types/releases/slug";import{applyDeployEnvironment}from"@interfere/types/sdk/deploy-environment";import{execSync}from"node:child_process";import{HTTPClient,Interfere}from"@interfere/sdk";import{releaseDestinationProviderSchema}from"@interfere/types/integrations";import{resolveCliReleaseDestination}from"@interfere/types/sdk/cli-destination";const sources={github:resolveGithubSource},destinations={vercel:resolveVercelDestination,cloudflare:resolveCloudflareDestination,cli:resolveCliDestination};async function timed(fn){let start=performance.now();return[await fn(),Math.round(performance.now()-start)]}function createSdkClient(opts){let httpClient=new HTTPClient;return httpClient.addHook(`beforeRequest`,request=>{let next=new Request(request);return next.headers.set(`Authorization`,`Bearer ${opts.apiKey}`),next}),{httpClient,sdk:new Interfere({serverURL:opts.apiUrl,httpClient}),security:{apiKey:opts.apiKey}}}function resolveReleaseRequest(buildId,environment,releaseSlug,producerVersion,config){if(!config.surface.sourceProvider)return{ok:!1,reason:`missing_source_provider`};let destinationProvider=releaseDestinationProviderSchema.safeParse(config.surface.destinationProvider);return destinationProvider.success?{ok:!0,request:{source:sources[config.surface.sourceProvider](),destination:applyDeployEnvironment(destinations[destinationProvider.data](releaseSlug),environment),buildId,slug:releaseSlug,producerVersion}}:{ok:!1,reason:`missing_destination_provider`}}async function runReleasePipeline(input){let{apiKey,apiUrl,bundler,discovery,releasesConfig}=input,releaseRequest=resolveReleaseRequest(input.buildId,input.environment,input.releaseSlug,input.producerVersion,releasesConfig);if(!releaseRequest.ok)return{ok:!1,failure:{kind:releaseRequest.reason,config:releasesConfig}};let start=performance.now(),{httpClient,sdk,security}=createSdkClient({apiKey,apiUrl}),[release,createReleaseMs]=await timed(()=>sdk.releases.create(security,releaseRequest.request)),releaseSlug=releaseSlugSchema.parse(release.destination.slug),buildId=release.build.hash??input.buildId,[{totalBytes},uploadMs]=await timed(()=>uploadSourceMaps({apiUrl,bundler,discovered:discovery,httpClient,releaseSlug})),[,preflightMs]=await timed(()=>sdk.releases.preflight(security,{releaseSlug})),[{failures},cleanupMs]=await timed(()=>cleanupSourceMaps(discovery.files));return{ok:!0,data:{buildId,cleanupFailures:failures,config:releasesConfig,fileCount:discovery.files.length,release:{...release,destination:{...release.destination,slug:releaseSlug}},releaseSlug,timing:{createRelease:createReleaseMs,upload:uploadMs,preflight:preflightMs,cleanup:cleanupMs,total:Math.round(performance.now()-start),fileCount:discovery.files.length,totalBytes}}}}function runGitCommand(command){try{let output=execSync(command,{encoding:`utf8`,stdio:[`ignore`,`pipe`,`ignore`]}).trim();return output.length>0?output:null}catch{return null}}function resolveGithubSource(){return{provider:`github`,branch:parseEnvValue(process.env.VERCEL_GIT_COMMIT_REF)??parseEnvValue(process.env.GITHUB_REF_NAME)??parseEnvValue(process.env.GITHUB_HEAD_REF)??runGitCommand(`git rev-parse --abbrev-ref HEAD`)??`unknown`,commitMessage:parseEnvValue(process.env.VERCEL_GIT_COMMIT_MESSAGE)??runGitCommand(`git log -1 --pretty=%B`)??``,commitSha:parseEnvValue(process.env.VERCEL_GIT_COMMIT_SHA)??parseEnvValue(process.env.GITHUB_SHA)??runGitCommand(`git rev-parse HEAD`)}}function resolveVercelDestination(){let environment=parseEnvValue(process.env.VERCEL_ENV??process.env.VERCEL_TARGET_ENV),deploymentId=parseEnvValue(process.env.VERCEL_DEPLOYMENT_ID);return{provider:`vercel`,destinationReleaseId:deploymentId,environment,deploymentId,deploymentUrl:resolveDeploymentUrl(),environmentName:environment,environmentTarget:environment}}function resolveDeploymentUrl(){let deploymentUrl=parseEnvValue(process.env.VERCEL_URL);return deploymentUrl===null?null:deploymentUrl.startsWith(`https://`)||deploymentUrl.startsWith(`http://`)?deploymentUrl:`https://${deploymentUrl}`}function resolveCloudflareDestination(){let raw=parseEnvValue(process.env.CF_VERSION_METADATA),versionMetadata=null;if(raw)try{versionMetadata=JSON.parse(raw)}catch{versionMetadata=null}let versionId=parseEnvValue(process.env.CF_VERSION_ID)??versionMetadata?.id??parseEnvValue(process.env.WORKERS_CI_BUILD_UUID)??null,scriptName=parseEnvValue(process.env.CF_WORKER_NAME)??parseEnvValue(process.env.WORKERS_CI_SCRIPT_NAME)??null,accountId=parseEnvValue(process.env.CF_ACCOUNT_ID)??parseEnvValue(process.env.CLOUDFLARE_ACCOUNT_ID)??null,environment=parseEnvValue(process.env.WORKERS_CI_BRANCH)??versionMetadata?.tag??null;return{provider:`cloudflare`,destinationReleaseId:versionId,environment,versionId,scriptName,accountId,deploymentUrl:resolveCloudflareDeploymentUrl(),environmentName:environment,environmentTarget:environment}}function resolveCloudflareDeploymentUrl(){let candidate=parseEnvValue(process.env.CF_PAGES_URL)??parseEnvValue(process.env.WORKERS_CI_DEPLOY_URL);return candidate===null?null:candidate.startsWith(`https://`)||candidate.startsWith(`http://`)?candidate:`https://${candidate}`}function resolveCliDestination(releaseSlug){return resolveCliReleaseDestination(process.env,releaseSlug)}export{createSdkClient,runReleasePipeline};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
//#region src/internal/server/request-trace.d.ts
|
|
2
|
+
interface TraceMetaDescriptor {
|
|
3
|
+
content: string;
|
|
4
|
+
name: string;
|
|
5
|
+
}
|
|
6
|
+
declare function traceMeta(): TraceMetaDescriptor[];
|
|
7
|
+
declare function withRequestSpan<T>(request: Request, next: () => Promise<T>): Promise<T>;
|
|
8
|
+
//#endregion
|
|
9
|
+
export { TraceMetaDescriptor, traceMeta, withRequestSpan };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{isEnabledOnServer}from"./env.mjs";import{SpanKind,SpanStatusCode,TraceFlags,context,propagation,trace}from"@opentelemetry/api";const SAMPLED_BIT=TraceFlags.SAMPLED,PROPAGATED_FIELDS=[`traceparent`,`tracestate`,`baggage`];function traceMeta(){let span=trace.getActiveSpan();if(!span||(span.spanContext().traceFlags&SAMPLED_BIT)!==SAMPLED_BIT)return[];let carrier={};propagation.inject(context.active(),carrier);let meta=[];for(let name of PROPAGATED_FIELDS){let content=carrier[name];content&&meta.push({content,name})}return meta}function withRequestSpan(request,next){if(!isEnabledOnServer())return next();let parent=propagation.extract(context.active(),headersToCarrier(request.headers));return context.with(parent,()=>trace.getTracer(`@interfere/vite/tanstack-start`).startActiveSpan(spanName(request),{attributes:requestAttributes(request),kind:SpanKind.SERVER},async span=>{try{return await next()}catch(error){throw span.recordException(error),span.setStatus({code:SpanStatusCode.ERROR}),error}finally{span.end()}}))}function headersToCarrier(headers){let carrier={};for(let[key,value]of headers)carrier[key]=value;return carrier}function spanName(request){return`${request.method} ${new URL(request.url).pathname}`}function requestAttributes(request){let url=new URL(request.url);return{"http.request.method":request.method,"server.address":url.host,"url.full":url.href,"url.path":url.pathname}}export{traceMeta,withRequestSpan};
|
package/dist/package.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var name=`@interfere/vite`,version=`11.0.0-canary.
|
|
1
|
+
var name=`@interfere/vite`,version=`11.0.0-canary.4`;export{name,version};
|
package/dist/plugin.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{PRODUCER_VERSION}from"./version.mjs";import{discoverByPairing}from"./internal/build/source-maps.mjs";import{createSdkClient,runReleasePipeline}from"./internal/build/pipeline.mjs";import{resolveCommitSha}from"./internal/release-slug.mjs";import{API_URL}from"@interfere/constants/api";import{deriveReleaseSlug}from"@interfere/types/releases/slug";import{resolveDeployEnvironment}from"@interfere/types/sdk/deploy-environment";import{existsSync,readdirSync,statSync}from"node:fs";import{join,resolve}from"node:path";import{loadEnv}from"vite";const SERVER_RUNTIME_PLUGIN_HINTS=[`tanstack-start`,`nitro`,`@tanstack/react-start`];function isTruthyEnvFlag(value){if(!value)return!1;let normalized=value.trim().toLowerCase();return normalized===`1`||normalized===`true`}function isTestEnv(){return!!(process.env.VITEST||process.env.VITEST_WORKER_ID)}function pickEnvValue(env,key){let value=env[key];return value&&value.length>0?value:void 0}function failMissingPublicKey(){let lines=[`interfere() requires VITE_INTERFERE_PUBLIC_KEY to identify your project at runtime.`,`Set the VITE_INTERFERE_PUBLIC_KEY environment variable, or remove interfere() from your Vite config.`,`See: https://support.interfere.com/docs/guides/vite`];if(isTestEnv())throw Error(`Interfere: Public key not set\n${lines.join(`
|
|
1
|
+
import{PRODUCER_VERSION}from"./version.mjs";import{discoverByPairing}from"./internal/build/source-maps.mjs";import{createSdkClient,runReleasePipeline}from"./internal/build/pipeline.mjs";import{resolveCommitSha}from"./internal/release-slug.mjs";import{API_URL}from"@interfere/constants/api";import{deriveReleaseSlug}from"@interfere/types/releases/slug";import{API_KEY_PREFIX,classifyReleasePipelineError,diagnoseRelease}from"@interfere/types/sdk/build-diagnostics";import{resolveDeployEnvironment}from"@interfere/types/sdk/deploy-environment";import{existsSync,readdirSync,statSync}from"node:fs";import{join,resolve}from"node:path";import{loadEnv}from"vite";const SERVER_RUNTIME_PLUGIN_HINTS=[`tanstack-start`,`nitro`,`@tanstack/react-start`],DIAGNOSTIC_CONTEXT={publicKeyEnvVar:`VITE_INTERFERE_PUBLIC_KEY`};function reportReleaseDiagnostic(logger,code,input){let diagnostic=diagnoseRelease(code,DIAGNOSTIC_CONTEXT,input);logger.warn(`[interfere] ${diagnostic.title}`);for(let line of diagnostic.details)logger.warn(`[interfere] ${line}`)}function isTruthyEnvFlag(value){if(!value)return!1;let normalized=value.trim().toLowerCase();return normalized===`1`||normalized===`true`}function isTestEnv(){return!!(process.env.VITEST||process.env.VITEST_WORKER_ID)}function pickEnvValue(env,key){let value=env[key];return value&&value.length>0?value:void 0}function failMissingPublicKey(){let lines=[`interfere() requires VITE_INTERFERE_PUBLIC_KEY to identify your project at runtime.`,`Set the VITE_INTERFERE_PUBLIC_KEY environment variable, or remove interfere() from your Vite config.`,`See: https://support.interfere.com/docs/guides/vite`];if(isTestEnv())throw Error(`Interfere: Public key not set\n${lines.join(`
|
|
2
2
|
`)}`);console.error(`
|
|
3
|
-
⨯ Interfere → Public key not set`);for(let i=0;i<lines.length;i+=1){let line=lines[i];if(!line)continue;let connector=i===lines.length-1?`└`:`├`;console.error(` ${connector} ${line}`)}process.exit(1)}function detectServerRuntime(config){return config.plugins.some(p=>SERVER_RUNTIME_PLUGIN_HINTS.some(hint=>p.name?.includes(hint)))}function resolveMode(optsMode,config,logger){let requested=optsMode??`auto`;if(requested!==`auto`)return logger.info(`[interfere] mode=${requested} (explicit)`),requested;let detected=detectServerRuntime(config)?`proxy`:`direct`;return logger.info(`[interfere] mode=${detected} (auto-detected). Override with \`interfere({ mode: "..." })\`.`),detected}function hasFreshServerSourceMaps(root,sinceMs){if(!existsSync(root))return!1;let entries=readdirSync(root,{withFileTypes:!0});for(let entry of entries){let absolute=join(root,entry.name);if(entry.isDirectory()){if(hasFreshServerSourceMaps(absolute,sinceMs))return!0;continue}if(entry.name.endsWith(`.map`)&&statSync(absolute).mtimeMs>=sinceMs)return!0}return!1}function isUploadReady(state){return!!(state.enableUpload&&state.apiKey&&state.releaseSlug&&state.commitSha&&!state.uploadStarted)}function shouldWaitForServerOutput(state){return state.mode===`proxy`&&!hasFreshServerSourceMaps(join(state.uploadOutDir,`server`),state.buildStartedAt)}function logSkippedRelease(logger,failure){if(failure.kind===`missing_source_provider`){logger.warn(`[interfere] release skipped: this surface has no version control provider configured. Configure one at https://interfere.com/~/${failure.config.org.slug}/surfaces/${failure.config.surface.slug}.`);return}logger.warn(`[interfere] release skipped: this surface has no deployment target configured. Configure one at https://interfere.com/~/${failure.config.org.slug}/surfaces/${failure.config.surface.slug}.`)}function logCleanupFailures(logger,failures){for(let failure of failures)logger.warn(`[interfere] cleanup left ${failure.absolute} on disk: ${failure.code??failure.message}`)}async function uploadSourceMaps(state){let{apiKey,apiUrl,releaseSlug,commitSha,logger,projectDir,uploadOutDir}=state;logger.info(`[interfere] uploading source maps for release ${releaseSlug}…`);try{let{sdk,security}=createSdkClient({apiKey,apiUrl}),[discovered,releasesConfig]=await Promise.all([discoverByPairing({projectDir,distDir:uploadOutDir,subtrees:[`.`],publicPathRewrites:[{from:`public`,to:``}]}),sdk.releases.getConfig(security)]);if(discovered.files.length===0){logger.info(`[interfere] no source maps found, skipping upload.`);return}let result=await runReleasePipeline({apiKey,apiUrl,bundler:`rollup`,buildId:commitSha,discovery:discovered,producerVersion:PRODUCER_VERSION,releasesConfig,releaseSlug});if(!result.ok){logSkippedRelease(logger,result.failure);return}logCleanupFailures(logger,result.data.cleanupFailures),logger.info(`[interfere] release ${result.data.releaseSlug} confirmed — ${result.data.fileCount} maps, ${result.data.timing.total}ms.`)}catch(err){let message=err instanceof Error?err.message:String(err);logger
|
|
3
|
+
⨯ Interfere → Public key not set`);for(let i=0;i<lines.length;i+=1){let line=lines[i];if(!line)continue;let connector=i===lines.length-1?`└`:`├`;console.error(` ${connector} ${line}`)}process.exit(1)}function detectServerRuntime(config){return config.plugins.some(p=>SERVER_RUNTIME_PLUGIN_HINTS.some(hint=>p.name?.includes(hint)))}function resolveMode(optsMode,config,logger,announce){let requested=optsMode??`auto`;if(requested!==`auto`)return announce&&logger.info(`[interfere] mode=${requested} (explicit)`),requested;let detected=detectServerRuntime(config)?`proxy`:`direct`;return announce&&logger.info(`[interfere] mode=${detected} (auto-detected). Override with \`interfere({ mode: "..." })\`.`),detected}function hasFreshServerSourceMaps(root,sinceMs){if(!existsSync(root))return!1;let entries=readdirSync(root,{withFileTypes:!0});for(let entry of entries){let absolute=join(root,entry.name);if(entry.isDirectory()){if(hasFreshServerSourceMaps(absolute,sinceMs))return!0;continue}if(entry.name.endsWith(`.map`)&&statSync(absolute).mtimeMs>=sinceMs)return!0}return!1}function isUploadReady(state){return!!(state.isProductionBuild&&state.enableUpload&&state.apiKey&&state.releaseSlug&&state.commitSha&&!state.uploadStarted)}function shouldWaitForServerOutput(state){return state.mode===`proxy`&&!hasFreshServerSourceMaps(join(state.uploadOutDir,`server`),state.buildStartedAt)}function logSkippedRelease(logger,failure){if(failure.kind===`missing_source_provider`){logger.warn(`[interfere] release skipped: this surface has no version control provider configured. Configure one at https://interfere.com/~/${failure.config.org.slug}/surfaces/${failure.config.surface.slug}.`);return}logger.warn(`[interfere] release skipped: this surface has no deployment target configured. Configure one at https://interfere.com/~/${failure.config.org.slug}/surfaces/${failure.config.surface.slug}.`)}function logCleanupFailures(logger,failures){for(let failure of failures)logger.warn(`[interfere] cleanup left ${failure.absolute} on disk: ${failure.code??failure.message}`)}async function uploadSourceMaps(state){let{apiKey,apiUrl,releaseSlug,commitSha,logger,projectDir,uploadOutDir}=state;if(!apiKey.startsWith(API_KEY_PREFIX)){reportReleaseDiagnostic(logger,`API_KEY_WRONG_PREFIX`,{apiKey});return}logger.info(`[interfere] uploading source maps for release ${releaseSlug}…`);try{let{sdk,security}=createSdkClient({apiKey,apiUrl}),[discovered,releasesConfig]=await Promise.all([discoverByPairing({projectDir,distDir:uploadOutDir,subtrees:[`.`],publicPathRewrites:[{from:`public`,to:``}]}),sdk.releases.getConfig(security)]);if(discovered.files.length===0){logger.info(`[interfere] no source maps found, skipping upload.`);return}let result=await runReleasePipeline({apiKey,apiUrl,bundler:`rollup`,buildId:commitSha,discovery:discovered,environment:state.environment,producerVersion:PRODUCER_VERSION,releasesConfig,releaseSlug});if(!result.ok){logSkippedRelease(logger,result.failure);return}logCleanupFailures(logger,result.data.cleanupFailures),logger.info(`[interfere] release ${result.data.releaseSlug} confirmed — ${result.data.fileCount} maps, ${result.data.timing.total}ms.`)}catch(err){let message=err instanceof Error?err.message:String(err);reportReleaseDiagnostic(logger,classifyReleasePipelineError(err),{errorMessage:message})}}async function uploadSourceMapsWhenReady(state){if(isUploadReady(state)){if(shouldWaitForServerOutput(state)){state.logger.info(`[interfere] waiting for Nitro server output before uploading source maps.`);return}state.uploadStarted=!0,await uploadSourceMaps(state)}}function emitSetupWarnings(state){let{logger,mode,publicKeyPresent,apiKey,releaseSlug,sourceMapsExplicit,isProductionBuild}=state;mode===`proxy`&&publicKeyPresent&&logger.info(`[interfere] mode=proxy: using VITE_INTERFERE_PUBLIC_KEY with the first-party proxy route.`),sourceMapsExplicit!==!1&&apiKey&&!releaseSlug&&logger.warn(`[interfere] No commit SHA available. Release metadata publishing is disabled. Set INTERFERE_SOURCE_ID, expose VERCEL_GIT_COMMIT_SHA / GITHUB_SHA, or run inside a git checkout.`),isProductionBuild&&sourceMapsExplicit!==!1&&!apiKey&&logger.warn("[interfere] INTERFERE_API_KEY is not set. Release metadata will not be published. Create an Interfere API key in the dashboard and set it in your build environment, or pass `interfere({ sourceMaps: false })` to suppress this warning if release metadata is intentionally handled out-of-band.")}function resolveReleaseEnv(config){return{...loadEnv(config.mode,config.envDir,``),...process.env}}function resolveReleaseIdentity(options,config){let commitSha=options.commitSha??config.env.VITE_INTERFERE_COMMIT_SHA??resolveCommitSha();return{commitSha,releaseSlug:commitSha?deriveReleaseSlug(commitSha):null}}function shouldEnableUpload({apiKey,isProductionBuild,releaseSlug,sourceMaps}){return isProductionBuild?sourceMaps??!!(apiKey&&releaseSlug):!1}function buildPluginState(options,config,announce){let logger=config.logger,mode=resolveMode(options.mode,config,logger,announce),publicKey=config.env.VITE_INTERFERE_PUBLIC_KEY,isProductionBuild=config.command===`build`;isProductionBuild&&!publicKey&&failMissingPublicKey();let releaseEnv=resolveReleaseEnv(config),pickEnv=key=>pickEnvValue(releaseEnv,key),apiKey=pickEnv(`INTERFERE_API_KEY`),apiUrl=pickEnv(`INTERFERE_API_URL`)??API_URL,{commitSha,releaseSlug}=resolveReleaseIdentity(options,config),environment=isProductionBuild?resolveDeployEnvironment(releaseEnv):null,rawBrowserApiUrl=config.env.VITE_INTERFERE_API_URL,browserApiUrl=rawBrowserApiUrl&&rawBrowserApiUrl.length>0?rawBrowserApiUrl:void 0;return announce&&emitSetupWarnings({apiKey,isProductionBuild,logger,mode,publicKeyPresent:!!publicKey,releaseSlug,sourceMapsExplicit:options.sourceMaps}),{apiKey,apiUrl,browserApiUrl:mode===`direct`?browserApiUrl:void 0,commitSha,enableUpload:shouldEnableUpload({apiKey,isProductionBuild,releaseSlug,sourceMaps:options.sourceMaps}),environment,forceEnable:isTruthyEnvFlag(config.env.VITE_INTERFERE_FORCE_ENABLE),isProductionBuild,logger,mode,projectDir:config.root,publicKey,releaseSlug,uploadOutDir:resolve(config.root,config.build.outDir),uploadStarted:!1,buildStartedAt:Date.now()}}function interfere(options={}){let state=null,forcedSourcemapOriginal,announced=!1;return{name:`interfere`,enforce:`pre`,config(userConfig,{command,mode}){if(command!==`build`||options.sourceMaps===!1)return;let root=userConfig.root?resolve(process.cwd(),userConfig.root):process.cwd();if(!pickEnvValue(loadEnv(mode,userConfig.envDir?resolve(root,userConfig.envDir):root,``),`INTERFERE_API_KEY`))return;let current=userConfig.build?.sourcemap;current!==void 0&¤t!==!0&&(forcedSourcemapOriginal=current),userConfig.build={...userConfig.build,sourcemap:!0}},configResolved(config){let next=buildPluginState(options,config,!announced);announced=!0,state?.mode===`proxy`&&next.mode===`proxy`&&(next.uploadOutDir=state.uploadOutDir,next.uploadStarted=state.uploadStarted,next.buildStartedAt=state.buildStartedAt),state=next,forcedSourcemapOriginal!==void 0&&(next.logger.warn(`[interfere] Forced build.sourcemap to true (was ${JSON.stringify(forcedSourcemapOriginal)}). Source maps are required to symbolicate errors; they are uploaded then deleted from the build output, so they are never served. Pass interfere({ sourceMaps: false }) to opt out.`),forcedSourcemapOriginal=void 0)},transformIndexHtml(){let assignments=[];return state?.releaseSlug&&assignments.push(`globalThis["__INTERFERE_RELEASE_SLUG__"]=${JSON.stringify(state.releaseSlug)};`),state?.publicKey&&assignments.push(`globalThis["__INTERFERE_PUBLIC_KEY__"]=${JSON.stringify(state.publicKey)};`),state?.environment&&assignments.push(`globalThis["__INTERFERE_ENVIRONMENT__"]=${JSON.stringify(state.environment)};`),state?.forceEnable&&assignments.push(`globalThis["__INTERFERE_FORCE_ENABLE__"]=true;`),state?.mode===`proxy`&&state.publicKey&&assignments.push(`globalThis["__INTERFERE_PROXY_MODE__"]=true;`),state?.mode===`direct`&&state.browserApiUrl&&assignments.push(`globalThis["__INTERFERE_API_URL__"]=${JSON.stringify(state.browserApiUrl)};`),assignments.length===0?[]:[{tag:`script`,children:assignments.join(``),injectTo:`head-prepend`}]},async closeBundle(){state&&await uploadSourceMapsWhenReady(state)}}}export{interfere};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { TraceMetaDescriptor, traceMeta } from "./internal/server/request-trace.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/tanstack-start.d.ts
|
|
4
|
+
declare const interfereRequestMiddleware: import("@tanstack/react-start").RequestMiddlewareAfterServer<{}, undefined, undefined>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { type TraceMetaDescriptor, interfereRequestMiddleware, traceMeta };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{traceMeta,withRequestSpan}from"./internal/server/request-trace.mjs";import{createMiddleware}from"@tanstack/react-start";const interfereRequestMiddleware=createMiddleware().server(({next,request})=>withRequestSpan(request,()=>Promise.resolve(next())));export{interfereRequestMiddleware,traceMeta};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interfere/vite",
|
|
3
|
-
"version": "11.0.0-canary.
|
|
3
|
+
"version": "11.0.0-canary.4",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Vite build plugin and client + server initialization for Interfere.",
|
|
6
6
|
"keywords": [
|
|
@@ -47,6 +47,11 @@
|
|
|
47
47
|
"types": "./dist/server.d.mts",
|
|
48
48
|
"default": "./dist/server.mjs"
|
|
49
49
|
},
|
|
50
|
+
"./tanstack-start": {
|
|
51
|
+
"monorepo": "./src/tanstack-start.ts",
|
|
52
|
+
"types": "./dist/tanstack-start.d.mts",
|
|
53
|
+
"default": "./dist/tanstack-start.mjs"
|
|
54
|
+
},
|
|
50
55
|
"./handler": {
|
|
51
56
|
"monorepo": "./src/handler.ts",
|
|
52
57
|
"types": "./dist/handler.d.mts",
|
|
@@ -64,8 +69,8 @@
|
|
|
64
69
|
"dependencies": {
|
|
65
70
|
"@interfere/constants": "^9.0.2-canary.0",
|
|
66
71
|
"@interfere/helpers": "^9.0.0",
|
|
67
|
-
"@interfere/react": "^11.0.0-canary.
|
|
68
|
-
"@interfere/sdk": "^11.0.0-canary.
|
|
72
|
+
"@interfere/react": "^11.0.0-canary.4",
|
|
73
|
+
"@interfere/sdk": "^11.0.0-canary.4",
|
|
69
74
|
"@interfere/types": "^9.0.3-canary.2",
|
|
70
75
|
"@opentelemetry/api": "^1.9.1",
|
|
71
76
|
"@opentelemetry/api-logs": "^0.219.0",
|
|
@@ -84,11 +89,15 @@
|
|
|
84
89
|
"@opentelemetry/sdk-trace-node": "^2.7.1"
|
|
85
90
|
},
|
|
86
91
|
"peerDependencies": {
|
|
92
|
+
"@tanstack/react-start": "1.168.26",
|
|
87
93
|
"react": "^19.2.6",
|
|
88
94
|
"react-dom": "^19.2.6",
|
|
89
|
-
"vite": "^8.0
|
|
95
|
+
"vite": "^8.1.0"
|
|
90
96
|
},
|
|
91
97
|
"peerDependenciesMeta": {
|
|
98
|
+
"@tanstack/react-start": {
|
|
99
|
+
"optional": true
|
|
100
|
+
},
|
|
92
101
|
"react": {
|
|
93
102
|
"optional": true
|
|
94
103
|
},
|
|
@@ -102,15 +111,16 @@
|
|
|
102
111
|
"devDependencies": {
|
|
103
112
|
"@interfere/test-utils": "^9.0.0",
|
|
104
113
|
"@interfere/typescript-config": "^9.0.0",
|
|
105
|
-
"@
|
|
114
|
+
"@tanstack/react-start": "1.168.26",
|
|
115
|
+
"@types/node": "^26.0.0",
|
|
106
116
|
"@types/react": "19.2.17",
|
|
107
117
|
"@types/react-dom": "19.2.3",
|
|
108
|
-
"@typescript/native-preview": "7.0.0-dev.
|
|
118
|
+
"@typescript/native-preview": "7.0.0-dev.20260623.1",
|
|
109
119
|
"@vitest/coverage-v8": "4.1.9",
|
|
110
120
|
"react": "^19.2.6",
|
|
111
121
|
"react-dom": "^19.2.6",
|
|
112
122
|
"tsdown": "^0.22.2",
|
|
113
|
-
"vite": "^8.0
|
|
123
|
+
"vite": "^8.1.0",
|
|
114
124
|
"vitest": "4.1.9"
|
|
115
125
|
}
|
|
116
126
|
}
|