@aamini/config 0.2.0 → 0.2.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.
@@ -2,6 +2,7 @@ import { a as canResolve, c as mergeOptions, n as serverProject, o as importPeer
2
2
  import { n as lint, r as fmt, t as mergeToolkitConfig } from "../merge-DThKwm_6.mjs";
3
3
  import { n as rootKey } from "../root-U5B4x0aj.mjs";
4
4
  import { resolve } from "node:path";
5
+ import { lazyPlugins } from "vite-plus";
5
6
  //#region src/tanstack/index.ts
6
7
  const entry = "@aamini/config/tanstack";
7
8
  const peers = {
@@ -120,10 +121,11 @@ async function tanstackPlugins(plugins) {
120
121
  result.push(babel({ presets: [reactCompilerPreset(compilerOptions)] }));
121
122
  }
122
123
  const varlockOptions = pluginOptions(pluginDefaults.varlock, plugins.varlock);
123
- if (varlockOptions) {
124
+ const varlock = varlockOptions && lazyPlugins(async () => {
124
125
  const { varlockVitePlugin } = await importPeer(entry, peers.varlock, () => import("@varlock/vite-integration"));
125
- result.push(varlockVitePlugin(varlockOptions));
126
- }
126
+ return [varlockVitePlugin(varlockOptions)];
127
+ });
128
+ if (varlock) result.push(varlock);
127
129
  return result;
128
130
  }
129
131
  async function testProjects(tests) {
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/tanstack/index.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport type tailwindcss from '@tailwindcss/vite'\nimport type { devtools } from '@tanstack/devtools-vite'\nimport type { tanstackStart } from '@tanstack/react-start/plugin/vite'\nimport type { varlockVitePlugin } from '@varlock/vite-integration'\nimport type { reactCompilerPreset } from '@vitejs/plugin-react'\nimport type viteReact from '@vitejs/plugin-react'\nimport type { nitro } from 'nitro/vite'\nimport type { PluginOption, UserConfig } from 'vite-plus'\n\nimport { mergeOptions } from '../options.ts'\nimport { canResolve, importPeer, requirePeer, type Peer } from '../peers.ts'\nimport { fmt } from '../vite-plus/fmt.ts'\nimport { lint } from '../vite-plus/lint.ts'\nimport { mergeToolkitConfig, type ToolkitConfig } from '../vite-plus/merge.ts'\nimport {\n\tbrowserProject,\n\tserverProject,\n\tunitProject,\n\ttype ProjectOptions,\n} from '../vitest/index.ts'\nimport { rootKey } from '../vitest/root.ts'\n\n// Any function type is assignable to this signature, whatever it returns.\ntype Options<T extends (...args: never[]) => void> = NonNullable<\n\tParameters<T>[0]\n>\n\n/** `false` removes the plugin. An object merges over the toolkit options. */\ntype PluginSetting<T> = false | T\n\nexport interface TanstackPlugins {\n\ttanstackStart?: PluginSetting<Options<typeof tanstackStart>>\n\t/** Dev only. Vitest runs without it. */\n\tdevtools?: PluginSetting<Options<typeof devtools>>\n\t/** Dev and build only. Vitest runs without it. */\n\tnitro?: PluginSetting<Options<typeof nitro>>\n\ttailwindcss?: PluginSetting<Options<typeof tailwindcss>>\n\treact?: PluginSetting<Options<typeof viteReact>>\n\treactCompiler?: PluginSetting<Options<typeof reactCompilerPreset>>\n\tvarlock?: PluginSetting<Options<typeof varlockVitePlugin>>\n}\n\n/** `false` removes the project. An object merges over the toolkit options. */\nexport interface TanstackTests {\n\tunit?: false | ProjectOptions\n\tserver?: false | ProjectOptions\n\t/** Vitest browser mode, `desktop` and `mobile` instances. */\n\tbrowser?: false | ProjectOptions\n}\n\nexport interface TanstackToolkitOptions {\n\t/** The app root. Pass `import.meta.dirname` from `vite.config.ts`. */\n\troot?: string\n\tplugins?: TanstackPlugins\n\t/** Adds the `@shadcn/lint` rules. */\n\tshadcn?: boolean\n\ttests?: TanstackTests\n\t/** Vite+ config merged last. App plugins in `config.plugins` run after the toolkit plugins. */\n\tconfig?: ToolkitConfig\n}\n\nconst entry = '@aamini/config/tanstack'\n\nconst peers = {\n\ttanstackStart: {\n\t\tname: '@tanstack/react-start',\n\t\tspecifier: '@tanstack/react-start/plugin/vite',\n\t},\n\tdevtools: {\n\t\tname: '@tanstack/devtools-vite',\n\t\tspecifier: '@tanstack/devtools-vite',\n\t},\n\tnitro: { name: 'nitro', specifier: 'nitro/vite' },\n\ttailwindcss: { name: '@tailwindcss/vite', specifier: '@tailwindcss/vite' },\n\treact: { name: '@vitejs/plugin-react', specifier: '@vitejs/plugin-react' },\n\tbabel: {\n\t\tname: '@rolldown/plugin-babel',\n\t\tspecifier: '@rolldown/plugin-babel',\n\t},\n\treactCompiler: {\n\t\tname: 'babel-plugin-react-compiler',\n\t\tspecifier: 'babel-plugin-react-compiler',\n\t},\n\tvarlock: {\n\t\tname: '@varlock/vite-integration',\n\t\tspecifier: '@varlock/vite-integration',\n\t},\n\tshadcn: { name: '@shadcn/lint', specifier: '@shadcn/lint' },\n} satisfies Record<string, Peer>\n\ntype PluginDefaults = Required<{\n\t[K in keyof TanstackPlugins]: Exclude<TanstackPlugins[K], false | undefined>\n}>\n\nconst pluginDefaults: PluginDefaults = {\n\ttanstackStart: {\n\t\trouter: { routeFileIgnorePattern: '(\\\\.test\\\\.tsx$|__screenshots__)' },\n\t\tserver: { build: { inlineCss: true } },\n\t},\n\tdevtools: { injectSource: { enabled: false } },\n\tnitro: { sourcemap: true, experimental: { sourcemapMinify: false } },\n\ttailwindcss: {},\n\treact: {},\n\treactCompiler: {},\n\tvarlock: { ssrInjectMode: 'resolved-env' },\n}\n\nconst shadcnLint = {\n\tjsPlugins: ['@shadcn/lint'],\n\trules: {\n\t\t'shadcn/require-static-classes': 'error',\n\t\t'shadcn/no-raw-colors': 'error',\n\t\t'shadcn/no-unknown-classes': 'error',\n\t\t'shadcn/no-arbitrary-values': ['error', { allow: ['layout'] }],\n\t\t'shadcn/no-inline-styles': 'error',\n\t\t'shadcn/no-restyle': ['error', { allow: ['layout'] }],\n\t},\n\toverrides: [\n\t\t{\n\t\t\tfiles: ['src/components/ui/**'],\n\t\t\trules: {\n\t\t\t\t'shadcn/require-static-classes': 'off',\n\t\t\t\t'shadcn/no-restyle': 'off',\n\t\t\t\t'shadcn/no-arbitrary-values': 'off',\n\t\t\t},\n\t\t},\n\t],\n} satisfies UserConfig['lint']\n\nfunction pluginOptions<T extends object>(\n\tdefaults: T,\n\tsetting: PluginSetting<T> | undefined,\n) {\n\tif (setting === false) return undefined\n\n\treturn mergeOptions(defaults, setting)\n}\n\n/**\n * Builds the TanStack plugins in the toolkit order. Each import runs only\n * when its plugin is on, so an app never loads a plugin that it removes.\n */\nasync function tanstackPlugins(plugins: TanstackPlugins) {\n\tconst underVitest = process.env.VITEST === 'true'\n\tconst result: PluginOption[] = []\n\n\tconst startOptions = pluginOptions(\n\t\tpluginDefaults.tanstackStart,\n\t\tplugins.tanstackStart,\n\t)\n\n\tif (startOptions) {\n\t\tconst { tanstackStart } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.tanstackStart,\n\t\t\t() => import('@tanstack/react-start/plugin/vite'),\n\t\t)\n\n\t\tresult.push(tanstackStart(startOptions))\n\t}\n\n\tconst devtoolsOptions = pluginOptions(\n\t\tpluginDefaults.devtools,\n\t\tplugins.devtools,\n\t)\n\n\tif (devtoolsOptions && !underVitest) {\n\t\tconst { devtools } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.devtools,\n\t\t\t() => import('@tanstack/devtools-vite'),\n\t\t)\n\n\t\tresult.push(devtools(devtoolsOptions))\n\t}\n\n\tconst nitroOptions = pluginOptions(pluginDefaults.nitro, plugins.nitro)\n\n\tif (nitroOptions && !underVitest) {\n\t\tconst { nitro } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.nitro,\n\t\t\t() => import('nitro/vite'),\n\t\t)\n\n\t\tresult.push(nitro(nitroOptions))\n\t}\n\n\tconst tailwindOptions = pluginOptions(\n\t\tpluginDefaults.tailwindcss,\n\t\tplugins.tailwindcss,\n\t)\n\n\tif (tailwindOptions) {\n\t\tconst { default: tailwindcss } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.tailwindcss,\n\t\t\t() => import('@tailwindcss/vite'),\n\t\t)\n\n\t\tresult.push(tailwindcss(tailwindOptions))\n\t}\n\n\tconst reactOptions = pluginOptions(pluginDefaults.react, plugins.react)\n\n\tif (reactOptions) {\n\t\tconst { default: viteReact } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.react,\n\t\t\t() => import('@vitejs/plugin-react'),\n\t\t)\n\n\t\tresult.push(viteReact(reactOptions))\n\t}\n\n\tconst compilerOptions = pluginOptions(\n\t\tpluginDefaults.reactCompiler,\n\t\tplugins.reactCompiler,\n\t)\n\n\tif (compilerOptions) {\n\t\t// Babel loads the compiler plugin by name, after this config resolves.\n\t\trequirePeer(entry, peers.reactCompiler)\n\n\t\tconst { reactCompilerPreset } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.react,\n\t\t\t() => import('@vitejs/plugin-react'),\n\t\t)\n\n\t\tconst { default: babel } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.babel,\n\t\t\t() => import('@rolldown/plugin-babel'),\n\t\t)\n\n\t\tresult.push(babel({ presets: [reactCompilerPreset(compilerOptions)] }))\n\t}\n\n\tconst varlockOptions = pluginOptions(pluginDefaults.varlock, plugins.varlock)\n\n\tif (varlockOptions) {\n\t\tconst { varlockVitePlugin } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.varlock,\n\t\t\t() => import('@varlock/vite-integration'),\n\t\t)\n\n\t\tresult.push(varlockVitePlugin(varlockOptions))\n\t}\n\n\treturn result\n}\n\nasync function testProjects(tests: TanstackTests) {\n\tconst projects = []\n\n\tif (tests.unit !== false) projects.push(unitProject(tests.unit))\n\n\tif (tests.server !== false) projects.push(serverProject(tests.server))\n\n\tif (tests.browser !== false) {\n\t\tprojects.push(\n\t\t\tawait browserProject(\n\t\t\t\tmergeOptions<ProjectOptions>(\n\t\t\t\t\t{ setupFiles: ['./src/styles.css'] },\n\t\t\t\t\ttests.browser,\n\t\t\t\t),\n\t\t\t),\n\t\t)\n\t}\n\n\treturn projects\n}\n\n// Pre-bundles the browser test stack at startup. Without it, Vite discovers\n// each dependency mid-run, and the re-optimization reload aborts the test\n// file that is loading.\nfunction browserTestDeps() {\n\tconst deps = ['vite-plus/test', 'vite-plus/test/browser']\n\n\tfor (const optional of ['vitest-browser-react', 'msw', 'msw/browser']) {\n\t\tif (canResolve(optional)) deps.push(optional)\n\t}\n\n\treturn deps\n}\n\n/** The complete Vite+ config for a TanStack Start app. */\nexport async function defineToolkit(\n\toptions: TanstackToolkitOptions = {},\n): Promise<UserConfig> {\n\tconst root = options.root ?? process.cwd()\n\tconst shadcn = options.shadcn !== false\n\tconst tests = options.tests ?? {}\n\n\t// Oxlint loads the shadcn rules by name when it lints.\n\tif (shadcn) requirePeer(entry, peers.shadcn)\n\n\tconst preset: UserConfig = {\n\t\troot,\n\t\tstaged: { '*': 'vp check --fix' },\n\t\tserver: { host: '127.0.0.1', port: Number(process.env.APP_PORT ?? 3000) },\n\t\t// TanStack Router ships RSC \"use client\" directives in its dist for RSC\n\t\t// compat. These apps build no RSC graph, so the bundling warnings are\n\t\t// noise.\n\t\tbuild: { rollupOptions: { checks: { moduleLevelDirective: false } } },\n\t\tresolve: {\n\t\t\ttsconfigPaths: true,\n\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\talias: [\n\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t\t{ find: '@tests', replacement: resolve(root, 'tests') },\n\t\t\t],\n\t\t},\n\t\tplugins: await tanstackPlugins(options.plugins ?? {}),\n\t\tfmt,\n\t\tlint: lint('react'),\n\t\ttest: {\n\t\t\t// Headless runs and screenshot baselines work with writes disabled.\n\t\t\t// allowWrite serves UI clients on the tailnet, which update snapshots\n\t\t\t// and baselines from the browser UI. Execution stays disabled.\n\t\t\tapi: { allowWrite: true, allowExec: false },\n\t\t\t// Test fixtures resolve app paths against this root, not the cwd.\n\t\t\tprovide: { [rootKey]: root },\n\t\t\tprojects: await testProjects(tests),\n\t\t},\n\t}\n\n\tif (tests.browser !== false) {\n\t\tpreset.optimizeDeps = { include: browserTestDeps() }\n\t}\n\n\tconst withShadcn = shadcn\n\t\t? mergeToolkitConfig(preset, { lint: shadcnLint })\n\t\t: preset\n\n\treturn mergeToolkitConfig(withShadcn, options.config)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/tanstack/index.ts"],"sourcesContent":["import { resolve } from 'node:path'\n\nimport type tailwindcss from '@tailwindcss/vite'\nimport type { devtools } from '@tanstack/devtools-vite'\nimport type { tanstackStart } from '@tanstack/react-start/plugin/vite'\nimport type { varlockVitePlugin } from '@varlock/vite-integration'\nimport type { reactCompilerPreset } from '@vitejs/plugin-react'\nimport type viteReact from '@vitejs/plugin-react'\nimport type { nitro } from 'nitro/vite'\nimport { lazyPlugins, type PluginOption, type UserConfig } from 'vite-plus'\n\nimport { mergeOptions } from '../options.ts'\nimport { canResolve, importPeer, requirePeer, type Peer } from '../peers.ts'\nimport { fmt } from '../vite-plus/fmt.ts'\nimport { lint } from '../vite-plus/lint.ts'\nimport { mergeToolkitConfig, type ToolkitConfig } from '../vite-plus/merge.ts'\nimport {\n\tbrowserProject,\n\tserverProject,\n\tunitProject,\n\ttype ProjectOptions,\n} from '../vitest/index.ts'\nimport { rootKey } from '../vitest/root.ts'\n\n// Any function type is assignable to this signature, whatever it returns.\ntype Options<T extends (...args: never[]) => void> = NonNullable<\n\tParameters<T>[0]\n>\n\n/** `false` removes the plugin. An object merges over the toolkit options. */\ntype PluginSetting<T> = false | T\n\nexport interface TanstackPlugins {\n\ttanstackStart?: PluginSetting<Options<typeof tanstackStart>>\n\t/** Dev only. Vitest runs without it. */\n\tdevtools?: PluginSetting<Options<typeof devtools>>\n\t/** Dev and build only. Vitest runs without it. */\n\tnitro?: PluginSetting<Options<typeof nitro>>\n\ttailwindcss?: PluginSetting<Options<typeof tailwindcss>>\n\treact?: PluginSetting<Options<typeof viteReact>>\n\treactCompiler?: PluginSetting<Options<typeof reactCompilerPreset>>\n\tvarlock?: PluginSetting<Options<typeof varlockVitePlugin>>\n}\n\n/** `false` removes the project. An object merges over the toolkit options. */\nexport interface TanstackTests {\n\tunit?: false | ProjectOptions\n\tserver?: false | ProjectOptions\n\t/** Vitest browser mode, `desktop` and `mobile` instances. */\n\tbrowser?: false | ProjectOptions\n}\n\nexport interface TanstackToolkitOptions {\n\t/** The app root. Pass `import.meta.dirname` from `vite.config.ts`. */\n\troot?: string\n\tplugins?: TanstackPlugins\n\t/** Adds the `@shadcn/lint` rules. */\n\tshadcn?: boolean\n\ttests?: TanstackTests\n\t/** Vite+ config merged last. App plugins in `config.plugins` run after the toolkit plugins. */\n\tconfig?: ToolkitConfig\n}\n\nconst entry = '@aamini/config/tanstack'\n\nconst peers = {\n\ttanstackStart: {\n\t\tname: '@tanstack/react-start',\n\t\tspecifier: '@tanstack/react-start/plugin/vite',\n\t},\n\tdevtools: {\n\t\tname: '@tanstack/devtools-vite',\n\t\tspecifier: '@tanstack/devtools-vite',\n\t},\n\tnitro: { name: 'nitro', specifier: 'nitro/vite' },\n\ttailwindcss: { name: '@tailwindcss/vite', specifier: '@tailwindcss/vite' },\n\treact: { name: '@vitejs/plugin-react', specifier: '@vitejs/plugin-react' },\n\tbabel: {\n\t\tname: '@rolldown/plugin-babel',\n\t\tspecifier: '@rolldown/plugin-babel',\n\t},\n\treactCompiler: {\n\t\tname: 'babel-plugin-react-compiler',\n\t\tspecifier: 'babel-plugin-react-compiler',\n\t},\n\tvarlock: {\n\t\tname: '@varlock/vite-integration',\n\t\tspecifier: '@varlock/vite-integration',\n\t},\n\tshadcn: { name: '@shadcn/lint', specifier: '@shadcn/lint' },\n} satisfies Record<string, Peer>\n\ntype PluginDefaults = Required<{\n\t[K in keyof TanstackPlugins]: Exclude<TanstackPlugins[K], false | undefined>\n}>\n\nconst pluginDefaults: PluginDefaults = {\n\ttanstackStart: {\n\t\trouter: { routeFileIgnorePattern: '(\\\\.test\\\\.tsx$|__screenshots__)' },\n\t\tserver: { build: { inlineCss: true } },\n\t},\n\tdevtools: { injectSource: { enabled: false } },\n\tnitro: { sourcemap: true, experimental: { sourcemapMinify: false } },\n\ttailwindcss: {},\n\treact: {},\n\treactCompiler: {},\n\tvarlock: { ssrInjectMode: 'resolved-env' },\n}\n\nconst shadcnLint = {\n\tjsPlugins: ['@shadcn/lint'],\n\trules: {\n\t\t'shadcn/require-static-classes': 'error',\n\t\t'shadcn/no-raw-colors': 'error',\n\t\t'shadcn/no-unknown-classes': 'error',\n\t\t'shadcn/no-arbitrary-values': ['error', { allow: ['layout'] }],\n\t\t'shadcn/no-inline-styles': 'error',\n\t\t'shadcn/no-restyle': ['error', { allow: ['layout'] }],\n\t},\n\toverrides: [\n\t\t{\n\t\t\tfiles: ['src/components/ui/**'],\n\t\t\trules: {\n\t\t\t\t'shadcn/require-static-classes': 'off',\n\t\t\t\t'shadcn/no-restyle': 'off',\n\t\t\t\t'shadcn/no-arbitrary-values': 'off',\n\t\t\t},\n\t\t},\n\t],\n} satisfies UserConfig['lint']\n\nfunction pluginOptions<T extends object>(\n\tdefaults: T,\n\tsetting: PluginSetting<T> | undefined,\n) {\n\tif (setting === false) return undefined\n\n\treturn mergeOptions(defaults, setting)\n}\n\n/**\n * Builds the TanStack plugins in the toolkit order. Each import runs only\n * when its plugin is on, so an app never loads a plugin that it removes.\n */\nasync function tanstackPlugins(plugins: TanstackPlugins) {\n\tconst underVitest = process.env.VITEST === 'true'\n\tconst result: PluginOption[] = []\n\n\tconst startOptions = pluginOptions(\n\t\tpluginDefaults.tanstackStart,\n\t\tplugins.tanstackStart,\n\t)\n\n\tif (startOptions) {\n\t\tconst { tanstackStart } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.tanstackStart,\n\t\t\t() => import('@tanstack/react-start/plugin/vite'),\n\t\t)\n\n\t\tresult.push(tanstackStart(startOptions))\n\t}\n\n\tconst devtoolsOptions = pluginOptions(\n\t\tpluginDefaults.devtools,\n\t\tplugins.devtools,\n\t)\n\n\tif (devtoolsOptions && !underVitest) {\n\t\tconst { devtools } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.devtools,\n\t\t\t() => import('@tanstack/devtools-vite'),\n\t\t)\n\n\t\tresult.push(devtools(devtoolsOptions))\n\t}\n\n\tconst nitroOptions = pluginOptions(pluginDefaults.nitro, plugins.nitro)\n\n\tif (nitroOptions && !underVitest) {\n\t\tconst { nitro } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.nitro,\n\t\t\t() => import('nitro/vite'),\n\t\t)\n\n\t\tresult.push(nitro(nitroOptions))\n\t}\n\n\tconst tailwindOptions = pluginOptions(\n\t\tpluginDefaults.tailwindcss,\n\t\tplugins.tailwindcss,\n\t)\n\n\tif (tailwindOptions) {\n\t\tconst { default: tailwindcss } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.tailwindcss,\n\t\t\t() => import('@tailwindcss/vite'),\n\t\t)\n\n\t\tresult.push(tailwindcss(tailwindOptions))\n\t}\n\n\tconst reactOptions = pluginOptions(pluginDefaults.react, plugins.react)\n\n\tif (reactOptions) {\n\t\tconst { default: viteReact } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.react,\n\t\t\t() => import('@vitejs/plugin-react'),\n\t\t)\n\n\t\tresult.push(viteReact(reactOptions))\n\t}\n\n\tconst compilerOptions = pluginOptions(\n\t\tpluginDefaults.reactCompiler,\n\t\tplugins.reactCompiler,\n\t)\n\n\tif (compilerOptions) {\n\t\t// Babel loads the compiler plugin by name, after this config resolves.\n\t\trequirePeer(entry, peers.reactCompiler)\n\n\t\tconst { reactCompilerPreset } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.react,\n\t\t\t() => import('@vitejs/plugin-react'),\n\t\t)\n\n\t\tconst { default: babel } = await importPeer(\n\t\t\tentry,\n\t\t\tpeers.babel,\n\t\t\t() => import('@rolldown/plugin-babel'),\n\t\t)\n\n\t\tresult.push(babel({ presets: [reactCompilerPreset(compilerOptions)] }))\n\t}\n\n\tconst varlockOptions = pluginOptions(pluginDefaults.varlock, plugins.varlock)\n\n\t// Varlock resolves the env on import, so load it only when Vite runs, not\n\t// when Vite+ just reads lint, fmt, or run settings. tanstackStart stays\n\t// eager: it generates the route tree that type-checking reads.\n\tconst varlock =\n\t\tvarlockOptions &&\n\t\tlazyPlugins(async () => {\n\t\t\tconst { varlockVitePlugin } = await importPeer(\n\t\t\t\tentry,\n\t\t\t\tpeers.varlock,\n\t\t\t\t() => import('@varlock/vite-integration'),\n\t\t\t)\n\n\t\t\treturn [varlockVitePlugin(varlockOptions)]\n\t\t})\n\n\tif (varlock) result.push(varlock)\n\n\treturn result\n}\n\nasync function testProjects(tests: TanstackTests) {\n\tconst projects = []\n\n\tif (tests.unit !== false) projects.push(unitProject(tests.unit))\n\n\tif (tests.server !== false) projects.push(serverProject(tests.server))\n\n\tif (tests.browser !== false) {\n\t\tprojects.push(\n\t\t\tawait browserProject(\n\t\t\t\tmergeOptions<ProjectOptions>(\n\t\t\t\t\t{ setupFiles: ['./src/styles.css'] },\n\t\t\t\t\ttests.browser,\n\t\t\t\t),\n\t\t\t),\n\t\t)\n\t}\n\n\treturn projects\n}\n\n// Pre-bundles the browser test stack at startup. Without it, Vite discovers\n// each dependency mid-run, and the re-optimization reload aborts the test\n// file that is loading.\nfunction browserTestDeps() {\n\tconst deps = ['vite-plus/test', 'vite-plus/test/browser']\n\n\tfor (const optional of ['vitest-browser-react', 'msw', 'msw/browser']) {\n\t\tif (canResolve(optional)) deps.push(optional)\n\t}\n\n\treturn deps\n}\n\n/** The complete Vite+ config for a TanStack Start app. */\nexport async function defineToolkit(\n\toptions: TanstackToolkitOptions = {},\n): Promise<UserConfig> {\n\tconst root = options.root ?? process.cwd()\n\tconst shadcn = options.shadcn !== false\n\tconst tests = options.tests ?? {}\n\n\t// Oxlint loads the shadcn rules by name when it lints.\n\tif (shadcn) requirePeer(entry, peers.shadcn)\n\n\tconst preset: UserConfig = {\n\t\troot,\n\t\tstaged: { '*': 'vp check --fix' },\n\t\tserver: { host: '127.0.0.1', port: Number(process.env.APP_PORT ?? 3000) },\n\t\t// TanStack Router ships RSC \"use client\" directives in its dist for RSC\n\t\t// compat. These apps build no RSC graph, so the bundling warnings are\n\t\t// noise.\n\t\tbuild: { rollupOptions: { checks: { moduleLevelDirective: false } } },\n\t\tresolve: {\n\t\t\ttsconfigPaths: true,\n\t\t\tdedupe: ['react', 'react-dom'],\n\t\t\talias: [\n\t\t\t\t{ find: '@', replacement: resolve(root, 'src') },\n\t\t\t\t{ find: '@tests', replacement: resolve(root, 'tests') },\n\t\t\t],\n\t\t},\n\t\tplugins: await tanstackPlugins(options.plugins ?? {}),\n\t\tfmt,\n\t\tlint: lint('react'),\n\t\ttest: {\n\t\t\t// Headless runs and screenshot baselines work with writes disabled.\n\t\t\t// allowWrite serves UI clients on the tailnet, which update snapshots\n\t\t\t// and baselines from the browser UI. Execution stays disabled.\n\t\t\tapi: { allowWrite: true, allowExec: false },\n\t\t\t// Test fixtures resolve app paths against this root, not the cwd.\n\t\t\tprovide: { [rootKey]: root },\n\t\t\tprojects: await testProjects(tests),\n\t\t},\n\t}\n\n\tif (tests.browser !== false) {\n\t\tpreset.optimizeDeps = { include: browserTestDeps() }\n\t}\n\n\tconst withShadcn = shadcn\n\t\t? mergeToolkitConfig(preset, { lint: shadcnLint })\n\t\t: preset\n\n\treturn mergeToolkitConfig(withShadcn, options.config)\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aamini/config",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Shared Vite+, lint, format, type, and test config for aria-amini apps",
5
5
  "license": "MIT",
6
6
  "type": "module",