@tanstack/start-plugin-core 1.121.0-alpha.4 → 1.121.0-alpha.6
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/cjs/build-sitemap.cjs +136 -0
- package/dist/cjs/build-sitemap.cjs.map +1 -0
- package/dist/cjs/build-sitemap.d.cts +31 -0
- package/dist/cjs/nitro/nitro-plugin.cjs +9 -0
- package/dist/cjs/nitro/nitro-plugin.cjs.map +1 -1
- package/dist/cjs/plugin.d.cts +88 -481
- package/dist/cjs/prerender.cjs +1 -7
- package/dist/cjs/prerender.cjs.map +1 -1
- package/dist/cjs/schema.cjs +5 -3
- package/dist/cjs/schema.cjs.map +1 -1
- package/dist/cjs/schema.d.cts +490 -1601
- package/dist/esm/build-sitemap.d.ts +31 -0
- package/dist/esm/build-sitemap.js +136 -0
- package/dist/esm/build-sitemap.js.map +1 -0
- package/dist/esm/nitro/nitro-plugin.js +9 -0
- package/dist/esm/nitro/nitro-plugin.js.map +1 -1
- package/dist/esm/plugin.d.ts +88 -481
- package/dist/esm/prerender.js +1 -7
- package/dist/esm/prerender.js.map +1 -1
- package/dist/esm/schema.d.ts +490 -1601
- package/dist/esm/schema.js +5 -3
- package/dist/esm/schema.js.map +1 -1
- package/package.json +4 -4
- package/src/build-sitemap.ts +210 -0
- package/src/nitro/nitro-plugin.ts +9 -13
- package/src/prerender.ts +1 -9
- package/src/schema.ts +5 -6
- package/dist/cjs/nitro/build-sitemap.d.cts +0 -9
- package/dist/esm/nitro/build-sitemap.d.ts +0 -9
- package/src/nitro/build-sitemap.ts +0 -79
package/dist/esm/schema.js
CHANGED
|
@@ -74,9 +74,11 @@ function createTanStackStartOptionsSchema(frameworkPlugin = {}) {
|
|
|
74
74
|
dir: z.string().optional().default("public"),
|
|
75
75
|
base: z.string().optional().default("/")
|
|
76
76
|
}).optional().default({}),
|
|
77
|
-
pages: z.array(
|
|
78
|
-
sitemap:
|
|
79
|
-
|
|
77
|
+
pages: z.array(pageSchema).optional().default([]),
|
|
78
|
+
sitemap: z.object({
|
|
79
|
+
enabled: z.boolean().optional().default(true),
|
|
80
|
+
host: z.string().optional(),
|
|
81
|
+
outputPath: z.string().optional().default("sitemap.xml")
|
|
80
82
|
}).optional(),
|
|
81
83
|
prerender: z.object({
|
|
82
84
|
enabled: z.boolean().optional(),
|
package/dist/esm/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-generator'\nimport type { NitroConfig } from 'nitropack'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true })\n .partial()\n .extend({\n srcDirectory: z.string().optional().default('src'),\n })\n\nexport function createTanStackConfig<\n TFrameworkPlugin extends Record<string, unknown>,\n>(frameworkPlugin?: TFrameworkPlugin) {\n const schema = createTanStackStartOptionsSchema(frameworkPlugin)\n\n return {\n schema,\n parse: (opts?: z.input<typeof schema>) => {\n const options = schema.parse(opts)\n\n const srcDirectory = options.tsr.srcDirectory\n\n const routesDirectory =\n options.tsr.routesDirectory ?? path.join(srcDirectory, 'routes')\n\n const generatedRouteTree =\n options.tsr.generatedRouteTree ??\n path.join(srcDirectory, 'routeTree.gen.ts')\n\n const clientEntryPath = (() => {\n if (options.client.entry) {\n return path.join(srcDirectory, options.client.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'client.tsx'))) {\n return path.join(srcDirectory, 'client.tsx')\n }\n\n return '/~start/default-client-entry'\n })()\n\n const serverEntryPath = (() => {\n if (options.server.entry) {\n return path.join(srcDirectory, options.server.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'server.tsx'))) {\n return path.join(srcDirectory, 'server.tsx')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.ts'))) {\n return path.join(srcDirectory, 'server.ts')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.js'))) {\n return path.join(srcDirectory, 'server.js')\n }\n\n return '/~start/default-server-entry'\n })()\n\n return {\n ...options,\n tsr: {\n ...options.tsr,\n ...getConfig({\n ...options.tsr,\n routesDirectory,\n generatedRouteTree,\n }),\n },\n clientEntryPath,\n serverEntryPath,\n }\n },\n }\n}\n\nexport function createTanStackStartOptionsSchema(\n frameworkPlugin: Record<string, unknown> = {},\n) {\n return z\n .object({\n root: z.string().optional().default(process.cwd()),\n target: z.custom<NitroConfig['preset']>().optional(),\n ...frameworkPlugin,\n tsr: tsrConfig.optional().default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n })\n .optional()\n .default({}),\n public: z\n .object({\n dir: z.string().optional().default('public'),\n base: z.string().optional().default('/'),\n })\n .optional()\n .default({}),\n pages: z\n .array(z.union([z.string(), pageSchema]))\n .optional()\n .default([]),\n sitemap: pagePrerenderOptionsSchema\n .extend({\n host: z.string().optional(),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n })\n .optional()\n .default({})\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nexport const pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nexport type Page = z.infer<typeof pageSchema>\n"],"names":[],"mappings":";;;;AAMA,MAAM,YAAY,aACf,KAAK,EAAE,mBAAmB,MAAM,EAChC,QAAQ,EACR,OAAO;AAAA,EACN,cAAc,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,KAAK;AACnD,CAAC;AAEI,SAAS,qBAEd,iBAAoC;AAC9B,QAAA,SAAS,iCAAiC,eAAe;AAExD,SAAA;AAAA,IACL;AAAA,IACA,OAAO,CAAC,SAAkC;AAClC,YAAA,UAAU,OAAO,MAAM,IAAI;AAE3B,YAAA,eAAe,QAAQ,IAAI;AAEjC,YAAM,kBACJ,QAAQ,IAAI,mBAAmB,KAAK,KAAK,cAAc,QAAQ;AAEjE,YAAM,qBACJ,QAAQ,IAAI,sBACZ,KAAK,KAAK,cAAc,kBAAkB;AAE5C,YAAM,mBAAmB,MAAM;AACzB,YAAA,QAAQ,OAAO,OAAO;AACxB,iBAAO,KAAK,KAAK,cAAc,QAAQ,OAAO,KAAK;AAAA,QAAA;AAGrD,YAAI,WAAW,KAAK,KAAK,cAAc,YAAY,CAAC,GAAG;AAC9C,iBAAA,KAAK,KAAK,cAAc,YAAY;AAAA,QAAA;AAGtC,eAAA;AAAA,MAAA,GACN;AAEH,YAAM,mBAAmB,MAAM;AACzB,YAAA,QAAQ,OAAO,OAAO;AACxB,iBAAO,KAAK,KAAK,cAAc,QAAQ,OAAO,KAAK;AAAA,QAAA;AAGrD,YAAI,WAAW,KAAK,KAAK,cAAc,YAAY,CAAC,GAAG;AAC9C,iBAAA,KAAK,KAAK,cAAc,YAAY;AAAA,QAAA;AAG7C,YAAI,WAAW,KAAK,KAAK,cAAc,WAAW,CAAC,GAAG;AAC7C,iBAAA,KAAK,KAAK,cAAc,WAAW;AAAA,QAAA;AAG5C,YAAI,WAAW,KAAK,KAAK,cAAc,WAAW,CAAC,GAAG;AAC7C,iBAAA,KAAK,KAAK,cAAc,WAAW;AAAA,QAAA;AAGrC,eAAA;AAAA,MAAA,GACN;AAEI,aAAA;AAAA,QACL,GAAG;AAAA,QACH,KAAK;AAAA,UACH,GAAG,QAAQ;AAAA,UACX,GAAG,UAAU;AAAA,YACX,GAAG,QAAQ;AAAA,YACX;AAAA,YACA;AAAA,UACD,CAAA;AAAA,QACH;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAAA,EAEJ;AACF;AAEgB,SAAA,iCACd,kBAA2C,IAC3C;AACA,SAAO,EACJ,OAAO;AAAA,IACN,MAAM,EAAE,SAAS,SAAW,EAAA,QAAQ,QAAQ,KAAK;AAAA,IACjD,QAAQ,EAAE,OAA8B,EAAE,SAAS;AAAA,IACnD,GAAG;AAAA,IACH,KAAK,UAAU,WAAW,QAAQ,CAAA,CAAE;AAAA,IACpC,QAAQ,EACL,OAAO;AAAA,MACN,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,MAC3B,MAAM,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,SAAS;AAAA,IAC9C,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,QAAQ,EACL,OAAO;AAAA,MACN,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,WAAW,EACR,OAAO;AAAA,MACN,MAAM,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,YAAY;AAAA,IACjD,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,QAAQ,EACL,OAAO;AAAA,MACN,KAAK,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,QAAQ;AAAA,MAC3C,MAAM,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,GAAG;AAAA,IACxC,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AAAA,IACb,OAAO,EACJ,MAAM,EAAE,MAAM,CAAC,EAAE,OAAA,GAAU,UAAU,CAAC,CAAC,EACvC,WACA,QAAQ,CAAA,CAAE;AAAA,IACb,SAAS,2BACN,OAAO;AAAA,MACN,MAAM,EAAE,OAAO,EAAE,SAAS;AAAA,IAC3B,CAAA,EACA,SAAS;AAAA,IACZ,WAAW,EACR,OAAO;AAAA,MACN,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,MAC9B,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,MACjC,QAAQ,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,QAAQ,EAAE,IAAK,CAAA,EAAE,SAAS;AAAA,MAChE,aAAa,EAAE,QAAQ,EAAE,SAAS;AAAA,IACnC,CAAA,EACA,IAAI,2BAA2B,SAAU,CAAA,EACzC,SAAS;AAAA,IACZ,KAAK,UAAU,SAAS;AAAA,EACzB,CAAA,EACA,SAAA,EACA,QAAQ,EAAE;AACf;AAEA,MAAM,2BAA2B,EAAE,OAAO;AAAA,EACxC,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,UAAU,EAAE,OAAA,EAAS,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;AAAA,EAC5C,YAAY,EACT,KAAK,CAAC,UAAU,UAAU,SAAS,UAAU,WAAW,UAAU,OAAO,CAAC,EAC1E,SAAS;AAAA,EACZ,SAAS,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC,EAAE,SAAS;AAAA,EAClD,eAAe,EACZ;AAAA,IACC,EAAE,OAAO;AAAA,MACP,MAAM,EAAE,OAAO;AAAA,MACf,UAAU,EAAE,OAAO;AAAA,IACpB,CAAA;AAAA,IAEF,SAAS;AAAA,EACZ,QAAQ,EACL;AAAA,IACC,EAAE,OAAO;AAAA,MACP,KAAK,EAAE,OAAO;AAAA,MACd,SAAS,EAAE,OAAO,EAAE,SAAS;AAAA,MAC7B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,IAC5B,CAAA;AAAA,IAEF,SAAS;AAAA,EACZ,MAAM,EACH,OAAO;AAAA,IACN,aAAa,EAAE,OAAO;AAAA,MACpB,MAAM,EAAE,OAAO;AAAA,MACf,UAAU,EAAE,OAAO;AAAA,IAAA,CACpB;AAAA,IACD,iBAAiB,EAAE,MAAM,CAAC,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;AAAA,IAC/C,OAAO,EAAE,OAAO;AAAA,EACjB,CAAA,EACA,SAAS;AACd,CAAC;AAED,MAAM,iBAAiB,EAAE,OAAO;AAAA,EAC9B,MAAM,EAAE,OAAO;AAAA,EACf,SAAS,yBAAyB,SAAS;AAAA,EAC3C,WAAW,EAAE,QAAQ,EAAE,SAAS;AAClC,CAAC;AAED,MAAM,6BAA6B,EAAE,OAAO;AAAA,EAC1C,SAAS,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC9B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,oBAAoB,EAAE,QAAQ,EAAE,SAAS;AAAA,EACzC,YAAY,EAAE,QAAQ,EAAE,SAAS;AAAA,EACjC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,EAChC,WAAW,EACR,SAAA,EACA;AAAA,IACC,EAAE,OAAO;AAAA,MACP,MAAM;AAAA,MACN,MAAM,EAAE,OAAO;AAAA,IAChB,CAAA;AAAA,IAEF,QAAQ,EAAE,IAAI,CAAC,EACf,SAAS;AACd,CAAC;AAED,MAAM,YAAY,EAAE,OAAO;AAAA,EACzB,SAAS,EAAE,QAAA,EAAU,SAAS,EAAE,QAAQ,IAAI;AAAA,EAC5C,UAAU,EAAE,OAAA,EAAS,SAAS,EAAE,QAAQ,GAAG;AAAA,EAC3C,WAAW,2BACR,WACA,QAAQ,CAAA,CAAE,EACV,UAAU,CAAC,UAAU;AAAA,IACpB,YAAY,KAAK,cAAc;AAAA,IAC/B,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,GAAG;AAAA,IACH,SAAS;AAAA,EAAA,EACT;AACN,CAAC;AAEY,MAAA,aAAa,eAAe,OAAO;AAAA,EAC9C,WAAW,2BAA2B,SAAS;AACjD,CAAC;"}
|
|
1
|
+
{"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { existsSync } from 'node:fs'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-generator'\nimport type { NitroConfig } from 'nitropack'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true })\n .partial()\n .extend({\n srcDirectory: z.string().optional().default('src'),\n })\n\nexport function createTanStackConfig<\n TFrameworkPlugin extends Record<string, unknown>,\n>(frameworkPlugin?: TFrameworkPlugin) {\n const schema = createTanStackStartOptionsSchema(frameworkPlugin)\n\n return {\n schema,\n parse: (opts?: z.input<typeof schema>) => {\n const options = schema.parse(opts)\n\n const srcDirectory = options.tsr.srcDirectory\n\n const routesDirectory =\n options.tsr.routesDirectory ?? path.join(srcDirectory, 'routes')\n\n const generatedRouteTree =\n options.tsr.generatedRouteTree ??\n path.join(srcDirectory, 'routeTree.gen.ts')\n\n const clientEntryPath = (() => {\n if (options.client.entry) {\n return path.join(srcDirectory, options.client.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'client.tsx'))) {\n return path.join(srcDirectory, 'client.tsx')\n }\n\n return '/~start/default-client-entry'\n })()\n\n const serverEntryPath = (() => {\n if (options.server.entry) {\n return path.join(srcDirectory, options.server.entry)\n }\n\n if (existsSync(path.join(srcDirectory, 'server.tsx'))) {\n return path.join(srcDirectory, 'server.tsx')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.ts'))) {\n return path.join(srcDirectory, 'server.ts')\n }\n\n if (existsSync(path.join(srcDirectory, 'server.js'))) {\n return path.join(srcDirectory, 'server.js')\n }\n\n return '/~start/default-server-entry'\n })()\n\n return {\n ...options,\n tsr: {\n ...options.tsr,\n ...getConfig({\n ...options.tsr,\n routesDirectory,\n generatedRouteTree,\n }),\n },\n clientEntryPath,\n serverEntryPath,\n }\n },\n }\n}\n\nexport function createTanStackStartOptionsSchema(\n frameworkPlugin: Record<string, unknown> = {},\n) {\n return z\n .object({\n root: z.string().optional().default(process.cwd()),\n target: z.custom<NitroConfig['preset']>().optional(),\n ...frameworkPlugin,\n tsr: tsrConfig.optional().default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n })\n .optional()\n .default({}),\n public: z\n .object({\n dir: z.string().optional().default('public'),\n base: z.string().optional().default('/'),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n })\n .optional()\n .default({})\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nexport const pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nexport type Page = z.infer<typeof pageSchema>\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.121.0-alpha.
|
|
3
|
+
"version": "1.121.0-alpha.6",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,11 +63,11 @@
|
|
|
63
63
|
"ufo": "^1.5.4",
|
|
64
64
|
"xmlbuilder2": "^3.1.1",
|
|
65
65
|
"zod": "^3.24.2",
|
|
66
|
-
"@tanstack/router-generator": "^1.121.0-alpha.
|
|
66
|
+
"@tanstack/router-generator": "^1.121.0-alpha.5",
|
|
67
|
+
"@tanstack/router-plugin": "^1.121.0-alpha.5",
|
|
67
68
|
"@tanstack/router-utils": "^1.121.0-alpha.2",
|
|
68
|
-
"@tanstack/router-plugin": "^1.121.0-alpha.4",
|
|
69
69
|
"@tanstack/server-functions-plugin": "^1.121.0-alpha.2",
|
|
70
|
-
"@tanstack/router-core": "^1.121.0-alpha.
|
|
70
|
+
"@tanstack/router-core": "^1.121.0-alpha.5"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"vite": "^6.0.0"
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import { writeFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { create } from 'xmlbuilder2'
|
|
4
|
+
import type { TanStackStartOutputConfig } from './plugin'
|
|
5
|
+
import type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'
|
|
6
|
+
|
|
7
|
+
export type SitemapUrl = {
|
|
8
|
+
loc: string
|
|
9
|
+
lastmod: string
|
|
10
|
+
priority?: number
|
|
11
|
+
changefreq?:
|
|
12
|
+
| 'always'
|
|
13
|
+
| 'hourly'
|
|
14
|
+
| 'daily'
|
|
15
|
+
| 'weekly'
|
|
16
|
+
| 'monthly'
|
|
17
|
+
| 'yearly'
|
|
18
|
+
| 'never'
|
|
19
|
+
alternateRefs?: Array<{
|
|
20
|
+
href: string
|
|
21
|
+
hreflang?: string
|
|
22
|
+
}>
|
|
23
|
+
images?: Array<{
|
|
24
|
+
loc: string
|
|
25
|
+
title?: string
|
|
26
|
+
caption?: string
|
|
27
|
+
}>
|
|
28
|
+
news?: {
|
|
29
|
+
publication: {
|
|
30
|
+
name: string
|
|
31
|
+
language: string
|
|
32
|
+
}
|
|
33
|
+
publicationDate: string | Date
|
|
34
|
+
title: string
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export type SitemapData = {
|
|
39
|
+
urls: Array<SitemapUrl>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function buildSitemapJson(
|
|
43
|
+
pages: TanStackStartOutputConfig['pages'],
|
|
44
|
+
host: string,
|
|
45
|
+
): SitemapData {
|
|
46
|
+
const slash = checkSlash(host)
|
|
47
|
+
|
|
48
|
+
const urls: Array<SitemapUrl> = pages
|
|
49
|
+
.filter((page) => {
|
|
50
|
+
return page.sitemap?.exclude !== true
|
|
51
|
+
})
|
|
52
|
+
.map((page) => ({
|
|
53
|
+
loc: `${host}${slash}${page.path.replace(/^\/+/g, '')}`,
|
|
54
|
+
lastmod: page.sitemap?.lastmod
|
|
55
|
+
? new Date(page.sitemap.lastmod).toISOString().split('T')[0]!
|
|
56
|
+
: new Date().toISOString().split('T')[0]!,
|
|
57
|
+
priority: page.sitemap?.priority,
|
|
58
|
+
changefreq: page.sitemap?.changefreq,
|
|
59
|
+
alternateRefs: page.sitemap?.alternateRefs,
|
|
60
|
+
images: page.sitemap?.images,
|
|
61
|
+
news: page.sitemap?.news,
|
|
62
|
+
}))
|
|
63
|
+
|
|
64
|
+
return { urls }
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function jsonToXml(sitemapData: SitemapData): string {
|
|
68
|
+
const sitemap = createXml('urlset')
|
|
69
|
+
|
|
70
|
+
for (const item of sitemapData.urls) {
|
|
71
|
+
const page = sitemap.ele('url')
|
|
72
|
+
page.ele('loc').txt(item.loc)
|
|
73
|
+
page.ele('lastmod').txt(item.lastmod)
|
|
74
|
+
|
|
75
|
+
if (item.priority !== undefined) {
|
|
76
|
+
page.ele('priority').txt(item.priority.toString())
|
|
77
|
+
}
|
|
78
|
+
if (item.changefreq) {
|
|
79
|
+
page.ele('changefreq').txt(item.changefreq)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Add alternate references
|
|
83
|
+
if (item.alternateRefs?.length) {
|
|
84
|
+
for (const ref of item.alternateRefs) {
|
|
85
|
+
const alternateRef = page.ele('xhtml:link')
|
|
86
|
+
alternateRef.att('rel', 'alternate')
|
|
87
|
+
alternateRef.att('href', ref.href)
|
|
88
|
+
if (ref.hreflang) {
|
|
89
|
+
alternateRef.att('hreflang', ref.hreflang)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Add images
|
|
95
|
+
if (item.images?.length) {
|
|
96
|
+
for (const image of item.images) {
|
|
97
|
+
const imageElement = page.ele('image:image')
|
|
98
|
+
imageElement.ele('image:loc').txt(image.loc)
|
|
99
|
+
if (image.title) {
|
|
100
|
+
imageElement.ele('image:title').txt(image.title)
|
|
101
|
+
}
|
|
102
|
+
if (image.caption) {
|
|
103
|
+
imageElement.ele('image:caption').txt(image.caption)
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Add news
|
|
109
|
+
if (item.news) {
|
|
110
|
+
const newsElement = page.ele('news:news')
|
|
111
|
+
const publication = newsElement.ele('news:publication')
|
|
112
|
+
publication.ele('news:name').txt(item.news.publication.name)
|
|
113
|
+
publication.ele('news:language').txt(item.news.publication.language)
|
|
114
|
+
newsElement
|
|
115
|
+
.ele('news:publication_date')
|
|
116
|
+
.txt(new Date(item.news.publicationDate).toISOString().split('T')[0]!)
|
|
117
|
+
newsElement.ele('news:title').txt(item.news.title)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return sitemap.end({ prettyPrint: true })
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function buildSitemap({
|
|
125
|
+
options,
|
|
126
|
+
publicDir,
|
|
127
|
+
}: {
|
|
128
|
+
options: TanStackStartOutputConfig
|
|
129
|
+
publicDir: string
|
|
130
|
+
}) {
|
|
131
|
+
let sitemapOptions = options.sitemap
|
|
132
|
+
|
|
133
|
+
if (!sitemapOptions && options.pages.length) {
|
|
134
|
+
sitemapOptions = { enabled: true, outputPath: 'sitemap.xml' }
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (!sitemapOptions?.enabled) {
|
|
138
|
+
throw new Error('Sitemap is not enabled')
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const { host, outputPath } = sitemapOptions
|
|
142
|
+
|
|
143
|
+
if (!host) {
|
|
144
|
+
if (!options.sitemap) {
|
|
145
|
+
console.info(
|
|
146
|
+
'Hint: Pages found, but no sitemap host has been set. To enable sitemap generation, set the `sitemap.host` option.',
|
|
147
|
+
)
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
throw new Error(
|
|
151
|
+
'Sitemap host is not set and required to build the sitemap.',
|
|
152
|
+
)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (!outputPath) {
|
|
156
|
+
throw new Error('Sitemap output path is not set')
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const { pages } = options
|
|
160
|
+
|
|
161
|
+
if (!pages.length) {
|
|
162
|
+
console.log('No pages were found to build the sitemap. Skipping...')
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
console.log('Building Sitemap...')
|
|
167
|
+
|
|
168
|
+
// Build the sitemap data
|
|
169
|
+
const sitemapData = buildSitemapJson(pages, host)
|
|
170
|
+
|
|
171
|
+
// Generate output paths
|
|
172
|
+
const xmlOutputPath = path.join(publicDir, outputPath)
|
|
173
|
+
const pagesOutputPath = path.join(publicDir, 'pages.json')
|
|
174
|
+
|
|
175
|
+
try {
|
|
176
|
+
// Write XML sitemap
|
|
177
|
+
console.log(`Writing sitemap XML at ${xmlOutputPath}`)
|
|
178
|
+
writeFileSync(xmlOutputPath, jsonToXml(sitemapData))
|
|
179
|
+
|
|
180
|
+
// Write pages data for runtime use
|
|
181
|
+
console.log(`Writing pages data at ${pagesOutputPath}`)
|
|
182
|
+
writeFileSync(
|
|
183
|
+
pagesOutputPath,
|
|
184
|
+
JSON.stringify(
|
|
185
|
+
{
|
|
186
|
+
pages,
|
|
187
|
+
host,
|
|
188
|
+
lastBuilt: new Date().toISOString(),
|
|
189
|
+
},
|
|
190
|
+
null,
|
|
191
|
+
2,
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
} catch (e) {
|
|
195
|
+
console.error(`Unable to write sitemap files`, e)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {
|
|
200
|
+
return create({ version: '1.0', encoding: 'UTF-8' })
|
|
201
|
+
.ele(elementName, {
|
|
202
|
+
xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',
|
|
203
|
+
})
|
|
204
|
+
.com(`This file was automatically generated by TanStack Start.`)
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function checkSlash(host: string): string {
|
|
208
|
+
const finalChar = host.slice(-1)
|
|
209
|
+
return finalChar === '/' ? '' : '/'
|
|
210
|
+
}
|
|
@@ -5,6 +5,7 @@ import { dirname, resolve } from 'pathe'
|
|
|
5
5
|
import { clientDistDir, ssrEntryFile } from '../plugin'
|
|
6
6
|
import { prerender } from '../prerender'
|
|
7
7
|
import { VITE_ENVIRONMENT_NAMES } from '../constants'
|
|
8
|
+
import { buildSitemap } from '../build-sitemap'
|
|
8
9
|
import { devServerPlugin } from './dev-server-plugin'
|
|
9
10
|
import { buildNitroEnvironment } from './build-nitro'
|
|
10
11
|
import type { EnvironmentOptions, PluginOption, Rollup } from 'vite'
|
|
@@ -132,19 +133,14 @@ export function nitroPlugin(
|
|
|
132
133
|
})
|
|
133
134
|
}
|
|
134
135
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
// }
|
|
144
|
-
|
|
145
|
-
// console.log(
|
|
146
|
-
// `\n\n✅ Client and server bundles successfully built.`,
|
|
147
|
-
// )
|
|
136
|
+
if (options.pages.length) {
|
|
137
|
+
await buildSitemap({
|
|
138
|
+
options,
|
|
139
|
+
publicDir: nitro.options.output.publicDir,
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
console.log(`\n✅ Client and server bundles successfully built.`)
|
|
148
144
|
},
|
|
149
145
|
},
|
|
150
146
|
}
|
package/src/prerender.ts
CHANGED
|
@@ -129,15 +129,7 @@ export async function prerender({
|
|
|
129
129
|
console.info(`Concurrency: ${concurrency}`)
|
|
130
130
|
const queue = new Queue({ concurrency })
|
|
131
131
|
|
|
132
|
-
options.pages.forEach((
|
|
133
|
-
let page = _page as Page
|
|
134
|
-
|
|
135
|
-
if (typeof _page === 'string') {
|
|
136
|
-
page = { path: _page }
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
addCrawlPageTask(page)
|
|
140
|
-
})
|
|
132
|
+
options.pages.forEach((page) => addCrawlPageTask(page))
|
|
141
133
|
|
|
142
134
|
await queue.start()
|
|
143
135
|
|
package/src/schema.ts
CHANGED
|
@@ -114,13 +114,12 @@ export function createTanStackStartOptionsSchema(
|
|
|
114
114
|
})
|
|
115
115
|
.optional()
|
|
116
116
|
.default({}),
|
|
117
|
-
pages: z
|
|
118
|
-
|
|
119
|
-
.
|
|
120
|
-
|
|
121
|
-
sitemap: pagePrerenderOptionsSchema
|
|
122
|
-
.extend({
|
|
117
|
+
pages: z.array(pageSchema).optional().default([]),
|
|
118
|
+
sitemap: z
|
|
119
|
+
.object({
|
|
120
|
+
enabled: z.boolean().optional().default(true),
|
|
123
121
|
host: z.string().optional(),
|
|
122
|
+
outputPath: z.string().optional().default('sitemap.xml'),
|
|
124
123
|
})
|
|
125
124
|
.optional(),
|
|
126
125
|
prerender: z
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type PagesJson = {
|
|
2
|
-
page: string;
|
|
3
|
-
lastMod: string;
|
|
4
|
-
};
|
|
5
|
-
export declare function buildSitemap({ host, routes, outputDir, }: {
|
|
6
|
-
host: string;
|
|
7
|
-
routes: Array<string | undefined> | (() => Promise<Array<string | undefined>>);
|
|
8
|
-
outputDir: string;
|
|
9
|
-
}): Promise<void>;
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export type PagesJson = {
|
|
2
|
-
page: string;
|
|
3
|
-
lastMod: string;
|
|
4
|
-
};
|
|
5
|
-
export declare function buildSitemap({ host, routes, outputDir, }: {
|
|
6
|
-
host: string;
|
|
7
|
-
routes: Array<string | undefined> | (() => Promise<Array<string | undefined>>);
|
|
8
|
-
outputDir: string;
|
|
9
|
-
}): Promise<void>;
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { writeFileSync } from 'node:fs'
|
|
2
|
-
import { resolve } from 'node:path'
|
|
3
|
-
import { create } from 'xmlbuilder2'
|
|
4
|
-
import type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'
|
|
5
|
-
|
|
6
|
-
export type PagesJson = {
|
|
7
|
-
page: string
|
|
8
|
-
lastMod: string
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function buildSitemap({
|
|
12
|
-
host,
|
|
13
|
-
routes,
|
|
14
|
-
outputDir,
|
|
15
|
-
}: {
|
|
16
|
-
host: string
|
|
17
|
-
routes: Array<string | undefined> | (() => Promise<Array<string | undefined>>)
|
|
18
|
-
outputDir: string
|
|
19
|
-
}) {
|
|
20
|
-
const routeList: Array<string> = await optionHasRoutes(routes)
|
|
21
|
-
|
|
22
|
-
if (routeList.length) {
|
|
23
|
-
const slash = checkSlash(host)
|
|
24
|
-
const sitemapData: Array<PagesJson> = routeList.map((page: string) => ({
|
|
25
|
-
page: `${host}${slash}${page.replace(/^\/+/g, '')}`,
|
|
26
|
-
lastMod: new Date().toISOString().split('T')[0]!,
|
|
27
|
-
}))
|
|
28
|
-
|
|
29
|
-
const sitemap = createXml('urlset')
|
|
30
|
-
|
|
31
|
-
for (const item of sitemapData) {
|
|
32
|
-
const page = sitemap.ele('url')
|
|
33
|
-
page.ele('loc').txt(item.page)
|
|
34
|
-
page.ele('lastmod').txt(item.lastMod)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const mapPath = `${resolve(outputDir)}/sitemap.xml`
|
|
38
|
-
try {
|
|
39
|
-
console.log(`Writing sitemap at ${mapPath}`)
|
|
40
|
-
writeFileSync(mapPath, sitemap.end({ prettyPrint: true }))
|
|
41
|
-
} catch (e) {
|
|
42
|
-
console.error(`Unable to write file at ${mapPath}`, e)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {
|
|
48
|
-
return create({ version: '1.0', encoding: 'UTF-8' })
|
|
49
|
-
.ele(elementName, {
|
|
50
|
-
xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',
|
|
51
|
-
})
|
|
52
|
-
.com(`This file was automatically generated by Analog.`)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function checkSlash(host: string): string {
|
|
56
|
-
const finalChar = host.slice(-1)
|
|
57
|
-
return finalChar === '/' ? '' : '/'
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function optionHasRoutes(
|
|
61
|
-
routes:
|
|
62
|
-
| Array<string | undefined>
|
|
63
|
-
| (() => Promise<Array<string | undefined>>),
|
|
64
|
-
): Promise<Array<string>> {
|
|
65
|
-
let routeList: Array<string | undefined>
|
|
66
|
-
|
|
67
|
-
if (typeof routes === 'function') {
|
|
68
|
-
// returns an array or undefined
|
|
69
|
-
routeList = await routes()
|
|
70
|
-
} else if (Array.isArray(routes)) {
|
|
71
|
-
// returns an array of strings
|
|
72
|
-
routeList = routes
|
|
73
|
-
} else {
|
|
74
|
-
// default it to an empty of array
|
|
75
|
-
routeList = []
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
return routeList.filter(Boolean) as Array<string>
|
|
79
|
-
}
|