{"_id":"@caterpillar-soft/viper","_rev":"2-48831f257d97897b3ebe3d947bdfdcf0","name":"@caterpillar-soft/viper","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@caterpillar-soft/viper","version":"0.1.0","author":{"name":"caterpi11ar","email":"daiqin1046@gmail.com"},"license":"MIT","_id":"@caterpillar-soft/viper@0.1.0","maintainers":[{"name":"daiqin1046","email":"1046572917@qq.com"}],"dist":{"shasum":"38a67395c1374407a431fbde3002adf65d1ba45f","tarball":"https://registry.npmjs.org/@caterpillar-soft/viper/-/viper-0.1.0.tgz","fileCount":4,"integrity":"sha512-51hx/vpDzaHqtbkfwLto8d4q/ibzmjpU9PbREJlqjbe9l2QwCmy+EukTp1mJNSZm3poiVGBDe2jsig9N51sRAA==","signatures":[{"sig":"MEUCIQD8iormBUticGhbPIHytdBpEQ8fx9908tpeCJZ8KYyaOQIgIWFRbAqfac/3i8MPhNzTMSQDvxotqh9IIqajKJJR+X4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19203},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=22.0.0","pnpm":">=9.6.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"ff368e12a532a24303767f7cf315e6f63af7c6a6","scripts":{"test":"vitest run","build":"tsup src/index.ts --format esm --dts","prepare":"husky","lint:fix":"eslint --ext .ts --fix  --cache .","typecheck":"tsc --noEmit","preinstall":"npx only-allow pnpm","test:watch":"vitest"},"_npmUser":{"name":"daiqin1046","email":"1046572917@qq.com"},"_npmVersion":"10.9.4","description":"Minimal Viper-inspired configuration library for TypeScript, powered by Zod and JSON5","directories":{},"_nodeVersion":"22.21.1","dependencies":{"zod":"^4.3.6","json5":"^2.2.3"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.27.0","devDependencies":{"tsup":"^8.5.0","husky":"^9.1.7","eslint":"^9.39.2","vitest":"^3.2.1","typescript":"^5.9.3","@types/node":"^25.0.10","lint-staged":"^16.2.7","@commitlint/cli":"^20.3.1","@antfu/eslint-config":"^7.2.0","@commitlint/config-conventional":"^20.3.1"},"_npmOperationalInternal":{"tmp":"tmp/viper_0.1.0_1770995714752_0.9858849382471975","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@caterpillar-soft/viper","type":"module","version":"0.1.1","packageManager":"pnpm@10.27.0","description":"Minimal Viper-inspired configuration library for TypeScript, powered by Zod and JSON5","author":{"name":"caterpi11ar","email":"daiqin1046@gmail.com"},"license":"MIT","publishConfig":{"access":"public"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"./dist/index.js","types":"./dist/index.d.ts","engines":{"node":">=22.0.0","pnpm":">=9.6.0"},"scripts":{"preinstall":"npx only-allow pnpm","prepare":"husky","build":"tsup src/index.ts --format esm --dts","test":"vitest run","test:watch":"vitest","lint:fix":"eslint --ext .ts --fix  --cache .","typecheck":"tsc --noEmit"},"dependencies":{"json5":"^2.2.3","zod":"^4.3.6"},"devDependencies":{"@antfu/eslint-config":"^7.2.0","@commitlint/cli":"^20.3.1","@commitlint/config-conventional":"^20.3.1","@types/node":"^25.0.10","eslint":"^9.39.2","husky":"^9.1.7","lint-staged":"^16.2.7","tsup":"^8.5.0","typescript":"^5.9.3","vitest":"^3.2.1"},"_id":"@caterpillar-soft/viper@0.1.1","gitHead":"b0d6720172cec804ad2d06f49b5df6db14f705b1","_nodeVersion":"22.21.1","_npmVersion":"10.9.4","dist":{"integrity":"sha512-A9hc/TszgOsI0eK8Sz1sPbnVxNZu9XlhbKsgVQrkIg2joyivdvMox4n+UGhlz0oLsW30tS9Wbk/vOpm0EiBlWw==","shasum":"8f5599d8af014f4e03fd2d9530c57a344160468f","tarball":"https://registry.npmjs.org/@caterpillar-soft/viper/-/viper-0.1.1.tgz","fileCount":4,"unpackedSize":19306,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIE6DVlQQnSCkVGmeZ0t0YrAa4ek3rH/t56E3O3KNWkOSAiBZOKeJQCq1Pho8YfbfqujmSZh4tVahDjyfcJ6v9PIBhg=="}]},"_npmUser":{"name":"daiqin1046","email":"1046572917@qq.com"},"directories":{},"maintainers":[{"name":"daiqin1046","email":"1046572917@qq.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/viper_0.1.1_1770996807675_0.5381147526189889"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-13T15:15:14.655Z","modified":"2026-02-13T15:33:27.928Z","0.1.0":"2026-02-13T15:15:14.894Z","0.1.1":"2026-02-13T15:33:27.825Z"},"author":{"name":"caterpi11ar","email":"daiqin1046@gmail.com"},"license":"MIT","description":"Minimal Viper-inspired configuration library for TypeScript, powered by Zod and JSON5","maintainers":[{"name":"daiqin1046","email":"1046572917@qq.com"}],"readme":"# viper\n\nMinimal Viper-inspired configuration library for TypeScript, powered by Zod and JSON5.\n\nConfiguration comes from multiple layered sources — defaults, config file, environment variables, and explicit overrides — unified into a single queryable registry with dot-notation key access.\n\n## Features\n\n- Layered config precedence: override > env > config file > defaults\n- Dot-notation key access (`database.host`)\n- Case-insensitive keys\n- JSON5 config files with atomic write\n- Environment variable binding (explicit + automatic with prefix)\n- Optional Zod schema validation\n- Key aliases and sub-tree extraction\n\n## Install\n\n```bash\npnpm add @caterpillar-soft/viper\n```\n\n## Quick Start\n\n```typescript\nimport { createViper } from '@caterpillar-soft/viper'\nimport { z } from 'zod'\n\nconst schema = z.object({\n  host: z.string(),\n  port: z.number(),\n  database: z.object({\n    url: z.string(),\n  }),\n})\n\nconst v = createViper({ schema })\n\n// Set defaults (lowest priority)\nv.setDefaults({ host: 'localhost', port: 3000 })\n\n// Read from config file\nv.setConfigName('config')     // file name without extension\nv.setConfigType('json5')      // file extension\nv.addConfigPath('./config')   // search directory\nv.addConfigPath('.')\nv.readInConfig()\n\n// Bind environment variables\nv.setEnvPrefix('APP')\nv.automaticEnv()              // APP_HOST, APP_PORT, APP_DATABASE_URL\nv.bindEnv('database.url', 'DATABASE_URL')  // explicit binding\n\n// Override (highest priority)\nv.set('port', 8080)\n\n// Read values\nv.get('host')                 // => 'localhost'\nv.getNumber('port')           // => 8080\nv.getString('database.url')   // from env or config\n\n// Introspection\nv.isSet('host')               // => true\nv.allKeys()                   // => ['database.url', 'host', 'port']\nv.allSettings()               // merged config object\n\n// Sub-tree\nconst db = v.sub('database')\ndb?.get('url')\n\n// Write config\nawait v.writeConfigAs('./config/config.json5')\n```\n\n## Config Precedence\n\nWhen reading a key, sources are checked in this order:\n\n1. **Override** — values set via `v.set(key, value)`\n2. **Environment** — bound env vars or automatic env lookup\n3. **Config file** — parsed from JSON5 file\n4. **Defaults** — values set via `v.setDefault()` / `v.setDefaults()`\n\n## API\n\n### Construction\n\n```typescript\nimport { Viper, createViper } from '@caterpillar-soft/viper'\n\nconst v = new Viper()\nconst v = new Viper({ schema, keyDelimiter: '.' })\nconst v = createViper({ schema })\n```\n\n### Defaults\n\n- `setDefault(key, value)` — set a single default\n- `setDefaults(obj)` — merge an object into defaults\n\n### Config File\n\n- `setConfigFile(path)` — set explicit config file path\n- `setConfigName(name)` — file name without extension (default: `\"config\"`)\n- `setConfigType(type)` — file extension (default: `\"json5\"`)\n- `addConfigPath(dir)` — add a directory to search\n- `readInConfig()` — find, read, parse, and validate config file\n- `mergeInConfig()` — like `readInConfig()` but merges into existing config\n- `mergeConfigMap(obj)` — merge a plain object into config layer\n- `configFileUsed()` — returns the discovered config file path\n\n### Write\n\n- `writeConfig()` — atomic write to discovered config path\n- `writeConfigAs(path)` — atomic write to specific path\n- `safeWriteConfig()` — write only if file doesn't exist\n- `safeWriteConfigAs(path)` — write to path only if it doesn't exist\n\n### Overrides\n\n- `set(key, value)` — set an override (highest priority)\n\n### Getters\n\n- `get<T>(key)` — returns `T | undefined`\n- `getString(key)` — returns `string` (empty string if missing)\n- `getNumber(key)` — returns `number` (0 if missing or NaN)\n- `getBoolean(key)` — returns `boolean` (false if missing)\n- `getArray(key)` — returns `unknown[]` (empty array if not an array)\n- `getObject(key)` — returns `Record<string, unknown>` (empty object if not an object)\n\n### Environment Variables\n\n- `setEnvPrefix(prefix)` — prefix for auto-derived env var names\n- `bindEnv(key, ...envVars)` — bind key to specific env vars\n- `automaticEnv()` — enable automatic env lookup (`{PREFIX}_{KEY}`, dots → underscores)\n\n### Introspection\n\n- `isSet(key)` — check if a key has a value in any layer\n- `allKeys()` — sorted list of all known keys\n- `allSettings()` — merged config from all layers\n\n### Alias & Sub-tree\n\n- `registerAlias(alias, key)` — alias resolves to real key on read\n- `sub(key)` — returns a new `Viper` instance scoped to a nested key\n\n## License\n\nMIT\n","readmeFilename":"README.md"}