@tanstack/start-server-core 1.168.0 → 1.168.1

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.
@@ -1,16 +1,42 @@
1
1
  import { resolveManifestAssetLink, rootRouteId } from "@tanstack/router-core";
2
2
  //#region src/transformAssetUrls.ts
3
- var hasWarnedAboutDeprecatedTransformAssetUrls = false;
4
- function warnDeprecatedTransformAssetUrls() {
5
- if ((process.env.NODE_ENV === "development" || process.env.TSS_DEV_SERVER === "true") && !hasWarnedAboutDeprecatedTransformAssetUrls) {
6
- hasWarnedAboutDeprecatedTransformAssetUrls = true;
7
- console.warn("[TanStack Start] `transformAssetUrls` is deprecated. Use `transformAssets` instead.");
8
- }
9
- }
10
3
  function normalizeTransformAssetResult(result) {
11
4
  if (typeof result === "string") return { href: result };
12
5
  return result;
13
6
  }
7
+ function escapeCssString(value) {
8
+ return value.replace(/\\/g, "\\\\").replace(/"/g, "\\\"").replace(/\n/g, "\\a ").replace(/\r/g, "\\d ").replace(/\f/g, "\\c ");
9
+ }
10
+ async function transformInlineCssTemplate(options) {
11
+ const { strings, urls } = options.template;
12
+ if (strings.length !== urls.length + 1) throw new Error(`TanStack Start inlineCss template for ${options.stylesheetHref} is invalid`);
13
+ let css = strings[0];
14
+ for (let index = 0; index < urls.length; index++) {
15
+ const transformed = normalizeTransformAssetResult(await options.transformFn({
16
+ kind: "css-url",
17
+ url: urls[index],
18
+ stylesheetHref: options.stylesheetHref
19
+ }));
20
+ css += escapeCssString(transformed.href) + strings[index + 1];
21
+ }
22
+ return css;
23
+ }
24
+ async function transformInlineCssStyles(inlineCss, transformFn) {
25
+ const transformedStyles = {};
26
+ const transformedEntries = await Promise.all(Object.entries(inlineCss.styles).map(async ([stylesheetHref, css]) => {
27
+ const template = inlineCss.templates?.[stylesheetHref];
28
+ return [stylesheetHref, template ? await transformInlineCssTemplate({
29
+ stylesheetHref,
30
+ template,
31
+ transformFn
32
+ }) : css];
33
+ }));
34
+ for (const [stylesheetHref, css] of transformedEntries) transformedStyles[stylesheetHref] = css;
35
+ return {
36
+ styles: transformedStyles,
37
+ ...inlineCss.templates ? { templates: inlineCss.templates } : {}
38
+ };
39
+ }
14
40
  function resolveTransformAssetsCrossOrigin(config, kind) {
15
41
  if (!config) return void 0;
16
42
  if (typeof config === "string") return config;
@@ -39,7 +65,7 @@ function resolveTransformAssetsConfig(transform) {
39
65
  type: "transform",
40
66
  transformFn: ({ url, kind }) => {
41
67
  const href = `${prefix}${url}`;
42
- if (kind === "clientEntry") return { href };
68
+ if (kind === "clientEntry" || kind === "css-url") return { href };
43
69
  const co = resolveTransformAssetsCrossOrigin(crossOrigin, kind);
44
70
  return co ? {
45
71
  href,
@@ -60,27 +86,6 @@ function resolveTransformAssetsConfig(transform) {
60
86
  cache: transform.cache !== false
61
87
  };
62
88
  }
63
- function adaptTransformAssetUrlsToTransformAssets(transformFn) {
64
- return async ({ url, kind }) => ({ href: await transformFn({
65
- url,
66
- type: kind
67
- }) });
68
- }
69
- function adaptTransformAssetUrlsConfigToTransformAssets(transform) {
70
- warnDeprecatedTransformAssetUrls();
71
- if (typeof transform === "string") return transform;
72
- if (typeof transform === "function") return adaptTransformAssetUrlsToTransformAssets(transform);
73
- if ("createTransform" in transform && transform.createTransform) return {
74
- createTransform: async (ctx) => adaptTransformAssetUrlsToTransformAssets(await transform.createTransform(ctx)),
75
- cache: transform.cache,
76
- warmup: transform.warmup
77
- };
78
- return {
79
- transform: typeof transform.transform === "string" ? transform.transform : adaptTransformAssetUrlsToTransformAssets(transform.transform),
80
- cache: transform.cache,
81
- warmup: transform.warmup
82
- };
83
- }
84
89
  /**
85
90
  * Builds the client entry `<script>` tag from a (possibly transformed) client
86
91
  * entry URL and optional injected head scripts.
@@ -103,6 +108,8 @@ function assignManifestAssetLink(link, next) {
103
108
  }
104
109
  async function transformManifestAssets(source, transformFn, _opts) {
105
110
  const manifest = structuredClone(source.manifest);
111
+ if (!(_opts?.inlineCss !== false)) delete manifest.inlineCss;
112
+ else if (manifest.inlineCss) manifest.inlineCss = await transformInlineCssStyles(manifest.inlineCss, transformFn);
106
113
  for (const route of Object.values(manifest.routes)) {
107
114
  if (route.preloads) route.preloads = await Promise.all(route.preloads.map(async (link) => {
108
115
  const result = normalizeTransformAssetResult(await transformFn({
@@ -114,7 +121,7 @@ async function transformManifestAssets(source, transformFn, _opts) {
114
121
  crossOrigin: result.crossOrigin
115
122
  });
116
123
  }));
117
- if (route.assets && !source.manifest.inlineCss) {
124
+ if (route.assets && !manifest.inlineCss) {
118
125
  for (const asset of route.assets) if (asset.tag === "link" && asset.attrs?.href) {
119
126
  const rel = asset.attrs.rel;
120
127
  if (!(typeof rel === "string" ? rel.split(/\s+/) : []).includes("stylesheet")) continue;
@@ -139,11 +146,11 @@ async function transformManifestAssets(source, transformFn, _opts) {
139
146
  }
140
147
  /**
141
148
  * Builds a final Manifest from a StartManifestWithClientEntry without any
142
- * URL transforms. Used when no transformAssetUrls option is provided.
149
+ * URL transforms. Used when no transformAssets option is provided.
143
150
  *
144
151
  * Returns a new manifest object so the cached base manifest is never mutated.
145
152
  */
146
- function buildManifestWithClientEntry(source) {
153
+ function buildManifestWithClientEntry(source, opts) {
147
154
  const scriptTag = buildClientEntryScriptTag(source.clientEntry, source.injectedHeadScripts);
148
155
  const baseRootRoute = source.manifest.routes[rootRouteId];
149
156
  const routes = {
@@ -154,11 +161,11 @@ function buildManifestWithClientEntry(source) {
154
161
  }
155
162
  };
156
163
  return {
157
- inlineCss: source.manifest.inlineCss,
164
+ ...opts?.inlineCss === false ? {} : { inlineCss: structuredClone(source.manifest.inlineCss) },
158
165
  routes
159
166
  };
160
167
  }
161
168
  //#endregion
162
- export { adaptTransformAssetUrlsConfigToTransformAssets, buildManifestWithClientEntry, resolveTransformAssetsConfig, transformManifestAssets };
169
+ export { buildManifestWithClientEntry, resolveTransformAssetsConfig, transformManifestAssets };
163
170
 
164
171
  //# sourceMappingURL=transformAssetUrls.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transformAssetUrls.js","names":[],"sources":["../../src/transformAssetUrls.ts"],"sourcesContent":["import { resolveManifestAssetLink, rootRouteId } from '@tanstack/router-core'\n\nimport type {\n AssetCrossOrigin,\n Awaitable,\n Manifest,\n ManifestAssetLink,\n RouterManagedTag,\n} from '@tanstack/router-core'\n\nexport type { AssetCrossOrigin }\n\nexport type TransformAssetKind = 'modulepreload' | 'stylesheet' | 'clientEntry'\n\ntype TransformAssetsShorthandCrossOriginKind = Exclude<\n TransformAssetKind,\n 'clientEntry'\n>\n\nexport type AssetUrlType = TransformAssetKind\n\nexport interface TransformAssetsContext {\n url: string\n kind: TransformAssetKind\n}\n\nexport type TransformAssetResult =\n | string\n | {\n href: string\n crossOrigin?: AssetCrossOrigin\n }\n\nexport type TransformAssetsFn = (\n context: TransformAssetsContext,\n) => Awaitable<TransformAssetResult>\n\nexport interface TransformAssetUrlsContext {\n url: string\n type: AssetUrlType\n}\n\nexport type TransformAssetUrlsFn = (\n context: TransformAssetUrlsContext,\n) => Awaitable<string>\n\nexport type CreateTransformAssetUrlsContext =\n | {\n /** True when the server is computing the cached manifest during startup warmup. */\n warmup: true\n }\n | {\n /**\n * The current Request.\n *\n * Only available during request handling (i.e. when `warmup: false`).\n */\n request: Request\n /** False when transforming URLs as part of request handling. */\n warmup: false\n }\n\n/**\n * Async factory that runs once per manifest computation and returns the\n * per-asset transform.\n */\nexport type CreateTransformAssetUrlsFn = (\n ctx: CreateTransformAssetUrlsContext,\n) => Awaitable<TransformAssetUrlsFn>\n\nexport type CreateTransformAssetsFn = (\n ctx: CreateTransformAssetUrlsContext,\n) => Awaitable<TransformAssetsFn>\n\ntype TransformAssetUrlsOptionsBase = {\n /**\n * Whether to cache the transformed manifest after the first request.\n *\n * When `true` (default), the transform runs once on the first request and\n * the resulting manifest is reused for all subsequent requests in production.\n *\n * Set to `false` for per-request transforms (e.g. geo-routing to different\n * CDNs based on request headers).\n *\n * @default true\n */\n cache?: boolean\n\n /**\n * When `true`, warms up the cached transformed manifest in the background when\n * the server starts (production only).\n *\n * This can reduce latency for the first request when `cache` is `true`.\n * Has no effect when `cache: false` (per-request transforms) or in dev mode.\n *\n * @default false\n */\n warmup?: boolean\n}\n\nexport type TransformAssetUrlsOptions =\n | (TransformAssetUrlsOptionsBase & {\n /**\n * The transform to apply to asset URLs. Can be a string prefix or a callback.\n *\n * **String** — prepended to every asset URL.\n * **Callback** — receives `{ url, type }` and returns a new URL.\n */\n transform: string | TransformAssetUrlsFn\n createTransform?: never\n })\n | (TransformAssetUrlsOptionsBase & {\n /**\n * Create a per-asset transform function.\n *\n * This factory runs once per manifest computation (per request when\n * `cache: false`, or once per server when `cache: true`). It can do async\n * setup work (fetch config, read from a KV, etc.) and return a fast\n * per-asset transformer.\n */\n createTransform: CreateTransformAssetUrlsFn\n transform?: never\n })\n\nexport type TransformAssetsOptions =\n | (TransformAssetUrlsOptionsBase & {\n transform: string | TransformAssetsFn\n createTransform?: never\n })\n | (TransformAssetUrlsOptionsBase & {\n createTransform: CreateTransformAssetsFn\n transform?: never\n })\n\nexport type TransformAssetUrls =\n | string\n | TransformAssetUrlsFn\n | TransformAssetUrlsOptions\n\n/**\n * Per-kind crossOrigin configuration for the object shorthand.\n *\n * Accepts either a single value applied to all asset kinds, or a per-kind\n * record (matching `HeadContent`'s `assetCrossOrigin` shape):\n *\n * ```ts\n * // All assets get the same value\n * crossOrigin: 'anonymous'\n *\n * // Different values per kind\n * crossOrigin: { modulepreload: 'anonymous', stylesheet: 'use-credentials' }\n * ```\n */\nexport type TransformAssetsCrossOriginConfig =\n | AssetCrossOrigin\n | Partial<Record<TransformAssetsShorthandCrossOriginKind, AssetCrossOrigin>>\n\n/**\n * Object shorthand for `transformAssets`. Combines a URL prefix with optional\n * per-asset `crossOrigin` without needing a callback:\n *\n * ```ts\n * transformAssets: {\n * prefix: 'https://cdn.example.com',\n * crossOrigin: 'anonymous',\n * }\n * ```\n */\nexport interface TransformAssetsObjectShorthand {\n /** URL prefix prepended to every asset URL. */\n prefix: string\n /**\n * Optional crossOrigin attribute applied to manifest-managed `<link>` assets.\n *\n * Accepts a single value or a per-kind record.\n */\n crossOrigin?: TransformAssetsCrossOriginConfig\n}\n\nexport type TransformAssets =\n | string\n | TransformAssetsFn\n | TransformAssetsObjectShorthand\n | TransformAssetsOptions\n\nexport type ResolvedTransformAssetsConfig =\n | {\n type: 'transform'\n transformFn: TransformAssetsFn\n cache: boolean\n }\n | {\n type: 'createTransform'\n createTransform: CreateTransformAssetsFn\n cache: boolean\n }\n\nlet hasWarnedAboutDeprecatedTransformAssetUrls = false\n\nexport function warnDeprecatedTransformAssetUrls() {\n if (\n (process.env.NODE_ENV === 'development' ||\n process.env.TSS_DEV_SERVER === 'true') &&\n !hasWarnedAboutDeprecatedTransformAssetUrls\n ) {\n hasWarnedAboutDeprecatedTransformAssetUrls = true\n console.warn(\n '[TanStack Start] `transformAssetUrls` is deprecated. Use `transformAssets` instead.',\n )\n }\n}\n\nfunction normalizeTransformAssetResult(\n result: TransformAssetResult,\n): Exclude<TransformAssetResult, string> {\n if (typeof result === 'string') {\n return { href: result }\n }\n\n return result\n}\n\nfunction resolveTransformAssetsCrossOrigin(\n config: TransformAssetsCrossOriginConfig | undefined,\n kind: TransformAssetsShorthandCrossOriginKind,\n): AssetCrossOrigin | undefined {\n if (!config) return undefined\n if (typeof config === 'string') return config\n\n return config[kind]\n}\n\nfunction isObjectShorthand(\n transform: TransformAssetsObjectShorthand | TransformAssetsOptions,\n): transform is TransformAssetsObjectShorthand {\n return 'prefix' in transform\n}\n\nexport function resolveTransformAssetsConfig(\n transform: TransformAssets,\n): ResolvedTransformAssetsConfig {\n if (typeof transform === 'string') {\n const prefix = transform\n return {\n type: 'transform',\n transformFn: ({ url }) => ({ href: `${prefix}${url}` }),\n cache: true,\n }\n }\n\n if (typeof transform === 'function') {\n return {\n type: 'transform',\n transformFn: transform,\n cache: true,\n }\n }\n\n // Object shorthand: { prefix, crossOrigin? }\n if (isObjectShorthand(transform)) {\n const { prefix, crossOrigin } = transform\n\n return {\n type: 'transform',\n transformFn: ({ url, kind }) => {\n const href = `${prefix}${url}`\n\n if (kind === 'clientEntry') {\n return { href }\n }\n\n const co = resolveTransformAssetsCrossOrigin(crossOrigin, kind)\n return co ? { href, crossOrigin: co } : { href }\n },\n cache: true,\n }\n }\n\n if ('createTransform' in transform && transform.createTransform) {\n return {\n type: 'createTransform',\n createTransform: transform.createTransform,\n cache: transform.cache !== false,\n }\n }\n\n const transformFn =\n typeof transform.transform === 'string'\n ? ((({ url }: TransformAssetsContext) => ({\n href: `${transform.transform}${url}`,\n })) as TransformAssetsFn)\n : transform.transform\n\n return {\n type: 'transform',\n transformFn,\n cache: transform.cache !== false,\n }\n}\n\nexport function adaptTransformAssetUrlsToTransformAssets(\n transformFn: TransformAssetUrlsFn,\n): TransformAssetsFn {\n return async ({ url, kind }) => ({\n href: await transformFn({ url, type: kind }),\n })\n}\n\nexport function adaptTransformAssetUrlsConfigToTransformAssets(\n transform: TransformAssetUrls,\n): TransformAssets {\n warnDeprecatedTransformAssetUrls()\n\n if (typeof transform === 'string') {\n return transform\n }\n\n if (typeof transform === 'function') {\n return adaptTransformAssetUrlsToTransformAssets(transform)\n }\n\n if ('createTransform' in transform && transform.createTransform) {\n return {\n createTransform: async (ctx: CreateTransformAssetUrlsContext) =>\n adaptTransformAssetUrlsToTransformAssets(\n await transform.createTransform(ctx),\n ),\n cache: transform.cache,\n warmup: transform.warmup,\n }\n }\n\n return {\n transform:\n typeof transform.transform === 'string'\n ? transform.transform\n : adaptTransformAssetUrlsToTransformAssets(transform.transform),\n cache: transform.cache,\n warmup: transform.warmup,\n }\n}\n\nexport interface StartManifestWithClientEntry {\n manifest: Manifest\n clientEntry: string\n /** Script content prepended before the client entry import (dev only) */\n injectedHeadScripts?: string\n}\n\n/**\n * Builds the client entry `<script>` tag from a (possibly transformed) client\n * entry URL and optional injected head scripts.\n */\nexport function buildClientEntryScriptTag(\n clientEntry: string,\n injectedHeadScripts?: string,\n): RouterManagedTag {\n const clientEntryLiteral = JSON.stringify(clientEntry)\n let script = `import(${clientEntryLiteral})`\n if (injectedHeadScripts) {\n script = `${injectedHeadScripts};${script}`\n }\n return {\n tag: 'script',\n attrs: {\n type: 'module',\n async: true,\n },\n children: script,\n }\n}\n\nfunction assignManifestAssetLink(\n link: ManifestAssetLink,\n next: { href: string; crossOrigin?: AssetCrossOrigin },\n): ManifestAssetLink {\n if (typeof link === 'string') {\n return next.crossOrigin ? next : next.href\n }\n\n return next.crossOrigin ? next : { href: next.href }\n}\n\nexport async function transformManifestAssets(\n source: StartManifestWithClientEntry,\n transformFn: TransformAssetsFn,\n _opts?: {\n clone?: boolean\n },\n): Promise<Manifest> {\n const manifest = structuredClone(source.manifest)\n\n for (const route of Object.values(manifest.routes)) {\n if (route.preloads) {\n route.preloads = await Promise.all(\n route.preloads.map(async (link) => {\n const resolved = resolveManifestAssetLink(link)\n const result = normalizeTransformAssetResult(\n await transformFn({\n url: resolved.href,\n kind: 'modulepreload',\n }),\n )\n\n return assignManifestAssetLink(link, {\n href: result.href,\n crossOrigin: result.crossOrigin,\n })\n }),\n )\n }\n\n if (route.assets && !source.manifest.inlineCss) {\n for (const asset of route.assets) {\n if (asset.tag === 'link' && asset.attrs?.href) {\n const rel = asset.attrs.rel\n const relTokens = typeof rel === 'string' ? rel.split(/\\s+/) : []\n\n if (!relTokens.includes('stylesheet')) {\n continue\n }\n\n const result = normalizeTransformAssetResult(\n await transformFn({\n url: asset.attrs.href,\n kind: 'stylesheet',\n }),\n )\n\n asset.attrs.href = result.href\n if (result.crossOrigin) {\n asset.attrs.crossOrigin = result.crossOrigin\n } else {\n delete asset.attrs.crossOrigin\n }\n }\n }\n }\n }\n\n const transformedClientEntry = normalizeTransformAssetResult(\n await transformFn({\n url: source.clientEntry,\n kind: 'clientEntry',\n }),\n )\n\n const rootRoute = (manifest.routes[rootRouteId] =\n manifest.routes[rootRouteId] || {})\n rootRoute.assets = rootRoute.assets || []\n rootRoute.assets.push(\n buildClientEntryScriptTag(\n transformedClientEntry.href,\n source.injectedHeadScripts,\n ),\n )\n\n return manifest\n}\n\n/**\n * Builds a final Manifest from a StartManifestWithClientEntry without any\n * URL transforms. Used when no transformAssetUrls option is provided.\n *\n * Returns a new manifest object so the cached base manifest is never mutated.\n */\nexport function buildManifestWithClientEntry(\n source: StartManifestWithClientEntry,\n): Manifest {\n const scriptTag = buildClientEntryScriptTag(\n source.clientEntry,\n source.injectedHeadScripts,\n )\n\n const baseRootRoute = source.manifest.routes[rootRouteId]\n const routes = {\n ...source.manifest.routes,\n [rootRouteId]: {\n ...baseRootRoute,\n assets: [...(baseRootRoute?.assets || []), scriptTag],\n },\n }\n\n return { inlineCss: source.manifest.inlineCss, routes }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"transformAssetUrls.js","names":[],"sources":["../../src/transformAssetUrls.ts"],"sourcesContent":["import { resolveManifestAssetLink, rootRouteId } from '@tanstack/router-core'\n\nimport type {\n AssetCrossOrigin,\n Awaitable,\n Manifest,\n ManifestAssetLink,\n RouterManagedTag,\n} from '@tanstack/router-core'\n\nexport type { AssetCrossOrigin }\n\nexport type TransformAssetsContext =\n | {\n url: string\n kind: 'modulepreload'\n }\n | {\n url: string\n kind: 'stylesheet'\n }\n | {\n url: string\n kind: 'clientEntry'\n }\n | {\n url: string\n kind: 'css-url'\n stylesheetHref: string\n }\n\nexport type TransformAssetKind = TransformAssetsContext['kind']\n\ntype TransformAssetsShorthandCrossOriginKind = Exclude<\n TransformAssetKind,\n 'clientEntry' | 'css-url'\n>\n\nexport type TransformAssetResult =\n | string\n | {\n href: string\n crossOrigin?: AssetCrossOrigin\n }\n\nexport type TransformAssetsFn = (\n context: TransformAssetsContext,\n) => Awaitable<TransformAssetResult>\n\nexport type CreateTransformAssetsContext =\n | {\n /** True when the server is computing the cached manifest during startup warmup. */\n warmup: true\n }\n | {\n /**\n * The current Request.\n *\n * Only available during request handling (i.e. when `warmup: false`).\n */\n request: Request\n /** False when transforming URLs as part of request handling. */\n warmup: false\n }\n\nexport type CreateTransformAssetsFn = (\n ctx: CreateTransformAssetsContext,\n) => Awaitable<TransformAssetsFn>\n\ntype TransformAssetsOptionsBase = {\n /**\n * Whether to cache the transformed manifest after the first request.\n *\n * When `true` (default), the transform runs once on the first request and\n * the resulting manifest is reused for all subsequent requests in production.\n *\n * Set to `false` for per-request transforms (e.g. geo-routing to different\n * CDNs based on request headers).\n *\n * @default true\n */\n cache?: boolean\n\n /**\n * When `true`, warms up the cached transformed manifest in the background when\n * the server starts (production only).\n *\n * This can reduce latency for the first request when `cache` is `true`.\n * Has no effect when `cache: false` (per-request transforms) or in dev mode.\n *\n * @default false\n */\n warmup?: boolean\n}\n\nexport type TransformAssetsOptions =\n | (TransformAssetsOptionsBase & {\n transform: string | TransformAssetsFn\n createTransform?: never\n })\n | (TransformAssetsOptionsBase & {\n createTransform: CreateTransformAssetsFn\n transform?: never\n })\n\n/**\n * Per-kind crossOrigin configuration for the object shorthand.\n *\n * Accepts either a single value applied to all asset kinds, or a per-kind\n * record (matching `HeadContent`'s `assetCrossOrigin` shape):\n *\n * ```ts\n * // All assets get the same value\n * crossOrigin: 'anonymous'\n *\n * // Different values per kind\n * crossOrigin: { modulepreload: 'anonymous', stylesheet: 'use-credentials' }\n * ```\n */\nexport type TransformAssetsCrossOriginConfig =\n | AssetCrossOrigin\n | Partial<Record<TransformAssetsShorthandCrossOriginKind, AssetCrossOrigin>>\n\n/**\n * Object shorthand for `transformAssets`. Combines a URL prefix with optional\n * per-asset `crossOrigin` without needing a callback:\n *\n * ```ts\n * transformAssets: {\n * prefix: 'https://cdn.example.com',\n * crossOrigin: 'anonymous',\n * }\n * ```\n */\nexport interface TransformAssetsObjectShorthand {\n /** URL prefix prepended to every asset URL. */\n prefix: string\n /**\n * Optional crossOrigin attribute applied to manifest-managed `<link>` assets.\n *\n * Accepts a single value or a per-kind record.\n */\n crossOrigin?: TransformAssetsCrossOriginConfig\n}\n\nexport type TransformAssets =\n | string\n | TransformAssetsFn\n | TransformAssetsObjectShorthand\n | TransformAssetsOptions\n\nexport type ResolvedTransformAssetsConfig =\n | {\n type: 'transform'\n transformFn: TransformAssetsFn\n cache: boolean\n }\n | {\n type: 'createTransform'\n createTransform: CreateTransformAssetsFn\n cache: boolean\n }\n\nfunction normalizeTransformAssetResult(\n result: TransformAssetResult,\n): Exclude<TransformAssetResult, string> {\n if (typeof result === 'string') {\n return { href: result }\n }\n\n return result\n}\n\nfunction escapeCssString(value: string) {\n return value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\a ')\n .replace(/\\r/g, '\\\\d ')\n .replace(/\\f/g, '\\\\c ')\n}\n\nasync function transformInlineCssTemplate(options: {\n stylesheetHref: string\n template: { strings: Array<string>; urls: Array<string> }\n transformFn: TransformAssetsFn\n}) {\n const { strings, urls } = options.template\n\n if (strings.length !== urls.length + 1) {\n throw new Error(\n `TanStack Start inlineCss template for ${options.stylesheetHref} is invalid`,\n )\n }\n\n let css = strings[0]!\n\n for (let index = 0; index < urls.length; index++) {\n const transformed = normalizeTransformAssetResult(\n await options.transformFn({\n kind: 'css-url',\n url: urls[index]!,\n stylesheetHref: options.stylesheetHref,\n }),\n )\n\n css += escapeCssString(transformed.href) + strings[index + 1]!\n }\n\n return css\n}\n\nasync function transformInlineCssStyles(\n inlineCss: NonNullable<Manifest['inlineCss']>,\n transformFn: TransformAssetsFn,\n) {\n const transformedStyles: Record<string, string> = {}\n\n const transformedEntries = await Promise.all(\n Object.entries(inlineCss.styles).map(async ([stylesheetHref, css]) => {\n const template = inlineCss.templates?.[stylesheetHref]\n return [\n stylesheetHref,\n template\n ? await transformInlineCssTemplate({\n stylesheetHref,\n template,\n transformFn,\n })\n : css,\n ] as const\n }),\n )\n\n for (const [stylesheetHref, css] of transformedEntries) {\n transformedStyles[stylesheetHref] = css\n }\n\n return {\n styles: transformedStyles,\n ...(inlineCss.templates ? { templates: inlineCss.templates } : {}),\n }\n}\n\nfunction resolveTransformAssetsCrossOrigin(\n config: TransformAssetsCrossOriginConfig | undefined,\n kind: TransformAssetsShorthandCrossOriginKind,\n): AssetCrossOrigin | undefined {\n if (!config) return undefined\n if (typeof config === 'string') return config\n\n return config[kind]\n}\n\nfunction isObjectShorthand(\n transform: TransformAssetsObjectShorthand | TransformAssetsOptions,\n): transform is TransformAssetsObjectShorthand {\n return 'prefix' in transform\n}\n\nexport function resolveTransformAssetsConfig(\n transform: TransformAssets,\n): ResolvedTransformAssetsConfig {\n if (typeof transform === 'string') {\n const prefix = transform\n return {\n type: 'transform',\n transformFn: ({ url }) => ({ href: `${prefix}${url}` }),\n cache: true,\n }\n }\n\n if (typeof transform === 'function') {\n return {\n type: 'transform',\n transformFn: transform,\n cache: true,\n }\n }\n\n // Object shorthand: { prefix, crossOrigin? }\n if (isObjectShorthand(transform)) {\n const { prefix, crossOrigin } = transform\n\n return {\n type: 'transform',\n transformFn: ({ url, kind }) => {\n const href = `${prefix}${url}`\n\n if (kind === 'clientEntry' || kind === 'css-url') {\n return { href }\n }\n\n const co = resolveTransformAssetsCrossOrigin(crossOrigin, kind)\n return co ? { href, crossOrigin: co } : { href }\n },\n cache: true,\n }\n }\n\n if ('createTransform' in transform && transform.createTransform) {\n return {\n type: 'createTransform',\n createTransform: transform.createTransform,\n cache: transform.cache !== false,\n }\n }\n\n const transformFn =\n typeof transform.transform === 'string'\n ? ((({ url }: TransformAssetsContext) => ({\n href: `${transform.transform}${url}`,\n })) as TransformAssetsFn)\n : transform.transform\n\n return {\n type: 'transform',\n transformFn,\n cache: transform.cache !== false,\n }\n}\n\nexport interface StartManifestWithClientEntry {\n manifest: Manifest\n clientEntry: string\n /** Script content prepended before the client entry import (dev only) */\n injectedHeadScripts?: string\n}\n\n/**\n * Builds the client entry `<script>` tag from a (possibly transformed) client\n * entry URL and optional injected head scripts.\n */\nexport function buildClientEntryScriptTag(\n clientEntry: string,\n injectedHeadScripts?: string,\n): RouterManagedTag {\n const clientEntryLiteral = JSON.stringify(clientEntry)\n let script = `import(${clientEntryLiteral})`\n if (injectedHeadScripts) {\n script = `${injectedHeadScripts};${script}`\n }\n return {\n tag: 'script',\n attrs: {\n type: 'module',\n async: true,\n },\n children: script,\n }\n}\n\nfunction assignManifestAssetLink(\n link: ManifestAssetLink,\n next: { href: string; crossOrigin?: AssetCrossOrigin },\n): ManifestAssetLink {\n if (typeof link === 'string') {\n return next.crossOrigin ? next : next.href\n }\n\n return next.crossOrigin ? next : { href: next.href }\n}\n\nexport async function transformManifestAssets(\n source: StartManifestWithClientEntry,\n transformFn: TransformAssetsFn,\n _opts?: {\n clone?: boolean\n inlineCss?: boolean\n },\n): Promise<Manifest> {\n const manifest = structuredClone(source.manifest)\n const inlineCssEnabled = _opts?.inlineCss !== false\n\n if (!inlineCssEnabled) {\n delete manifest.inlineCss\n } else if (manifest.inlineCss) {\n manifest.inlineCss = await transformInlineCssStyles(\n manifest.inlineCss,\n transformFn,\n )\n }\n\n for (const route of Object.values(manifest.routes)) {\n if (route.preloads) {\n route.preloads = await Promise.all(\n route.preloads.map(async (link) => {\n const resolved = resolveManifestAssetLink(link)\n const result = normalizeTransformAssetResult(\n await transformFn({\n url: resolved.href,\n kind: 'modulepreload',\n }),\n )\n\n return assignManifestAssetLink(link, {\n href: result.href,\n crossOrigin: result.crossOrigin,\n })\n }),\n )\n }\n\n if (route.assets && !manifest.inlineCss) {\n for (const asset of route.assets) {\n if (asset.tag === 'link' && asset.attrs?.href) {\n const rel = asset.attrs.rel\n const relTokens = typeof rel === 'string' ? rel.split(/\\s+/) : []\n\n if (!relTokens.includes('stylesheet')) {\n continue\n }\n\n const result = normalizeTransformAssetResult(\n await transformFn({\n url: asset.attrs.href,\n kind: 'stylesheet',\n }),\n )\n\n asset.attrs.href = result.href\n if (result.crossOrigin) {\n asset.attrs.crossOrigin = result.crossOrigin\n } else {\n delete asset.attrs.crossOrigin\n }\n }\n }\n }\n }\n\n const transformedClientEntry = normalizeTransformAssetResult(\n await transformFn({\n url: source.clientEntry,\n kind: 'clientEntry',\n }),\n )\n\n const rootRoute = (manifest.routes[rootRouteId] =\n manifest.routes[rootRouteId] || {})\n rootRoute.assets = rootRoute.assets || []\n rootRoute.assets.push(\n buildClientEntryScriptTag(\n transformedClientEntry.href,\n source.injectedHeadScripts,\n ),\n )\n\n return manifest\n}\n\n/**\n * Builds a final Manifest from a StartManifestWithClientEntry without any\n * URL transforms. Used when no transformAssets option is provided.\n *\n * Returns a new manifest object so the cached base manifest is never mutated.\n */\nexport function buildManifestWithClientEntry(\n source: StartManifestWithClientEntry,\n opts?: { inlineCss?: boolean },\n): Manifest {\n const scriptTag = buildClientEntryScriptTag(\n source.clientEntry,\n source.injectedHeadScripts,\n )\n\n const baseRootRoute = source.manifest.routes[rootRouteId]\n const routes = {\n ...source.manifest.routes,\n [rootRouteId]: {\n ...baseRootRoute,\n assets: [...(baseRootRoute?.assets || []), scriptTag],\n },\n }\n\n return {\n ...(opts?.inlineCss === false\n ? {}\n : { inlineCss: structuredClone(source.manifest.inlineCss) }),\n routes,\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/start-server-core",
3
- "version": "1.168.0",
3
+ "version": "1.168.1",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -66,10 +66,10 @@
66
66
  "fetchdts": "^0.1.6",
67
67
  "h3-v2": "npm:h3@2.0.1-rc.20",
68
68
  "seroval": "^1.5.4",
69
- "@tanstack/router-core": "1.170.0",
70
69
  "@tanstack/history": "1.162.0",
71
- "@tanstack/start-client-core": "1.169.0",
72
- "@tanstack/start-storage-context": "1.167.0"
70
+ "@tanstack/router-core": "1.170.1",
71
+ "@tanstack/start-storage-context": "1.167.1",
72
+ "@tanstack/start-client-core": "1.169.1"
73
73
  },
74
74
  "devDependencies": {
75
75
  "@standard-schema/spec": "^1.0.0",
@@ -41,7 +41,7 @@ With asset URL transforms (CDN):
41
41
  ```ts
42
42
  export default createStartHandler({
43
43
  handler: defaultStreamHandler,
44
- transformAssetUrls: 'https://cdn.example.com',
44
+ transformAssets: 'https://cdn.example.com',
45
45
  })
46
46
  ```
47
47