{
	"id": "arkenv",
	"name": "ArkEnv",
	"version": "1.0.0-rc.2",
	"description": "Typesafe environment variable validation with build-time validation and runtime leak protection.",
	"type": "add-on",
	"phase": "add-on",
	"category": "tooling",
	"color": "#06B6D4",
	"priority": 28,
	"link": "https://arkenv.js.org",
	"modes": ["file-router", "code-router"],
	"options": {
		"validator": {
			"type": "select",
			"label": "Validator Engine",
			"default": "arktype",
			"options": [
				{
					"value": "arktype",
					"label": "ArkType (@arkenv/core) - Recommended"
				},
				{
					"value": "zod",
					"label": "Zod (@arkenv/standard)"
				},
				{
					"value": "valibot",
					"label": "Valibot (@arkenv/standard)"
				}
			]
		},
		"demo": {
			"type": "select",
			"label": "Interactive Demo Route",
			"default": "true",
			"options": [
				{
					"value": "true",
					"label": "Include /demo/arkenv (recommended)"
				},
				{
					"value": "false",
					"label": "Skip demo route"
				}
			]
		}
	},
	"routes": [
		{
			"url": "/demo/arkenv",
			"name": "ArkEnv Demo",
			"path": "src/routes/demo/arkenv.tsx",
			"jsName": "ArkEnvDemo"
		}
	],
	"integrations": [
		{
			"type": "vite-plugin",
			"import": "import arkenvPlugin from '@arkenv/vite-plugin'",
			"code": "arkenvPlugin()"
		}
	],
	"packageTemplate": "<%\n  const arkenvOption = (typeof addOnOption !== 'undefined' && (\n    addOnOption['arkenv'] ||\n    Object.entries(addOnOption).find(([k]) => k.includes('arkenv') || k.includes('info.json'))?.[1]\n  )) || {};\n  const validator = arkenvOption.validator || 'arktype';\n-%>\n{\n  \"dependencies\": {\n<% if (validator === 'zod') { -%>\n    \"@arkenv/standard\": \"^1.0.0-rc.2\",\n    \"zod\": \"^3.24.2\"\n<% } else if (validator === 'valibot') { -%>\n    \"@arkenv/standard\": \"^1.0.0-rc.2\",\n    \"valibot\": \"^1.0.0\"\n<% } else { -%>\n    \"@arkenv/core\": \"^1.0.0-rc.2\",\n    \"arktype\": \"^2.2.0\"\n<% } -%>\n  },\n  \"devDependencies\": {\n    \"@arkenv/vite-plugin\": \"^1.0.0-rc.2\"\n  }\n}\n",
	"files": {
		"_dot_env.example": "# Port for the dev/preview server\nPORT=3000\n\n# Public API URL (inlined into client bundle)\nVITE_API_URL=https://api.example.com\n\n# Server-only database connection URL (protected from client access)\nDATABASE_URL=postgresql://postgres:postgres@localhost:5432/db\n\n# Environment mode\nNODE_ENV=development\n",
		"src/env.ts.ejs": "<%\n  const arkenvOption = (typeof addOnOption !== 'undefined' && (\n    addOnOption['arkenv'] ||\n    Object.entries(addOnOption).find(([k]) => k.includes('arkenv') || k.includes('info.json'))?.[1]\n  )) || {};\n  const validator = arkenvOption.validator || 'arktype';\n-%>\n<% if (validator === 'zod') { -%>\nimport arkenv from \"@arkenv/standard\";\nimport { z } from \"zod\";\n\nexport const env = arkenv({\n  PORT: z.coerce.number().int().min(1).max(65535).default(3000),\n  VITE_API_URL: z.string().url().default(\"https://api.example.com\"),\n  DATABASE_URL: z.string().url().default(\"postgresql://postgres:postgres@localhost:5432/db\"),\n  NODE_ENV: z.enum([\"development\", \"production\", \"test\"]).default(\"development\"),\n});\n<% } else if (validator === 'valibot') { -%>\nimport arkenv from \"@arkenv/standard\";\nimport * as v from \"valibot\";\n\nexport const env = arkenv({\n  PORT: v.optional(v.pipe(v.unknown(), v.transform(Number), v.integer()), 3000),\n  VITE_API_URL: v.optional(v.pipe(v.string(), v.url()), \"https://api.example.com\"),\n  DATABASE_URL: v.optional(v.pipe(v.string(), v.url()), \"postgresql://postgres:postgres@localhost:5432/db\"),\n  NODE_ENV: v.optional(v.picklist([\"development\", \"production\", \"test\"]), \"development\"),\n});\n<% } else { -%>\nimport arkenv from \"@arkenv/core\";\n\nexport const env = arkenv({\n  PORT: \"number.port = 3000\",\n  VITE_API_URL: \"string = 'https://api.example.com'\",\n  DATABASE_URL: \"string = 'postgresql://postgres:postgres@localhost:5432/db'\",\n  NODE_ENV: \"'development' | 'production' | 'test' = 'development'\",\n});\n<% } -%>\n",
		"src/routes/demo/arkenv.tsx.ejs": "<%\n  const arkenvOption = (typeof addOnOption !== 'undefined' && (\n    addOnOption['arkenv'] ||\n    Object.entries(addOnOption).find(([k]) => k.includes('arkenv') || k.includes('info.json'))?.[1]\n  )) || {};\n  const includeDemo = typeof includeExamples !== 'undefined' ? includeExamples : true;\n  if (arkenvOption.demo === 'false' || !includeDemo) {\n    if (typeof ignoreFile === 'function') {\n      ignoreFile();\n      return;\n    }\n  }\n-%>\nimport { createFileRoute } from \"@tanstack/react-router\";\nimport { createServerFn } from \"@tanstack/react-start\";\nimport { useState } from \"react\";\nimport { env } from \"../../env\";\n\nconst getDatabaseConfig = createServerFn({ method: \"GET\" }).handler(() => {\n\t// Server-only key: safely read on the server during SSR / RPC\n\ttry {\n\t\tconst url = new URL(env.DATABASE_URL);\n\t\treturn { host: url.host, protocol: url.protocol };\n\t} catch {\n\t\treturn { host: \"localhost:5432\", protocol: \"postgresql:\" };\n\t}\n});\n\nexport const Route = createFileRoute(\"/demo/arkenv\")({\n\tcomponent: ArkEnvDemo,\n\tloader: () => getDatabaseConfig(),\n});\n\nfunction LeakedSecret() {\n\t// Accessing server-only DATABASE_URL directly on the client throws at runtime\n\treturn <p>Server key leaked: {env.DATABASE_URL}</p>;\n}\n\nfunction ArkEnvDemo() {\n\tconst dbConfig = Route.useLoaderData();\n\tconst [attemptLeak, setAttemptLeak] = useState(false);\n\n\treturn (\n\t\t<div className=\"p-6 max-w-xl mx-auto space-y-4 font-sans\">\n\t\t\t<h1 className=\"text-2xl font-bold\">ArkEnv Demo</h1>\n\t\t\t<p className=\"text-sm text-gray-600\">\n\t\t\t\tTypesafe environment variables with build-time validation and runtime\n\t\t\t\tleak protection.\n\t\t\t</p>\n\n\t\t\t<div className=\"p-4 bg-gray-100 dark:bg-gray-800 rounded-md space-y-2\">\n\t\t\t\t<h2 className=\"font-semibold text-lg\">Public Client Variables</h2>\n\t\t\t\t<p className=\"text-sm text-gray-600 dark:text-gray-300\">\n\t\t\t\t\tInlined safely into client bundles:\n\t\t\t\t</p>\n\t\t\t\t<code className=\"block p-2 bg-white dark:bg-black rounded border text-xs font-mono\">\n\t\t\t\t\tenv.VITE_API_URL: {env.VITE_API_URL}\n\t\t\t\t</code>\n\t\t\t</div>\n\n\t\t\t<div className=\"p-4 bg-gray-100 dark:bg-gray-800 rounded-md space-y-2\">\n\t\t\t\t<h2 className=\"font-semibold text-lg\">Server-Only Variables</h2>\n\t\t\t\t<p className=\"text-sm text-gray-600 dark:text-gray-300\">\n\t\t\t\t\tAccessible inside createServerFn handlers:\n\t\t\t\t</p>\n\t\t\t\t<code className=\"block p-2 bg-white dark:bg-black rounded border text-xs font-mono\">\n\t\t\t\t\tDatabase Host: {dbConfig.host} ({dbConfig.protocol})\n\t\t\t\t</code>\n\t\t\t</div>\n\n\t\t\t<div className=\"p-4 bg-red-50 dark:bg-red-950/30 border border-red-200 dark:border-red-900 rounded-md space-y-2\">\n\t\t\t\t<h2 className=\"font-semibold text-red-800 dark:text-red-300 text-lg\">\n\t\t\t\t\tSecret Leak Protection\n\t\t\t\t</h2>\n\t\t\t\t<p className=\"text-sm text-red-700 dark:text-red-400\">\n\t\t\t\t\tClicking the button below attempts to access the server secret{\" \"}\n\t\t\t\t\t<code>env.DATABASE_URL</code> on the client, which ArkEnv blocks:\n\t\t\t\t</p>\n\t\t\t\t{attemptLeak ? (\n\t\t\t\t\t<LeakedSecret />\n\t\t\t\t) : (\n\t\t\t\t\t<button\n\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\tclassName=\"px-3 py-1.5 bg-red-600 text-white rounded text-sm hover:bg-red-700 cursor-pointer\"\n\t\t\t\t\t\tonClick={() => setAttemptLeak(true)}\n\t\t\t\t\t>\n\t\t\t\t\t\tAttempt client access to DATABASE_URL\n\t\t\t\t\t</button>\n\t\t\t\t)}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"
	},
	"deletedFiles": []
}
