{"bugs":{"url":"https://github.com/natemoo-re/proload/issues"},"dist":{"shasum":"4ab33e557429c4894c8abe1dc166eddf311f2df6","tarball":"https://registry.npmjs.org/@proload/core/-/core-0.3.2-next.1.tgz","fileCount":10,"integrity":"sha512-qPcArX0cfrtiKdX//2ab02FIGlQlj39PMdp2icJDEdf9pNkecasANYZVwMrfdLu1o/+8aEba7dBVpQ1er08dZg==","signatures":[{"sig":"MEQCIAjfth8AzoJGtp4hkdqXbxDsJAw6gIQ6t0ac9jy47QuIAiAR9G/prNpMqAU5tnoGBkG/OlmM1A7YoDuOnl6TLogIjw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":28749,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiaA7FACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo8rQ//a8Ni8iKoGM1H1nmcPlJeA3fM6U0U6EgAlF733J5d8fbSGEhX\r\nClB6ZlQs3b0lpclK18XMGr9mSEhhZpA8mB5sQda1iUwgW7t6KliLZmwZL+rR\r\nAExV5LYqFrZZ82DW2ZEBm62pyJ1EG6Op4ytM/3FJkborlwYDkro8r/95bb72\r\nIL33tOQtgJpPfXo6Qm3CcwGUmT5soF9/Uk+4GZRV+G30wL9kqmC9RkBU4igz\r\nv31xb1MOTbNLoB++P68AB6yO5s9vA4IfzZ9Pp5Vt7PseWV/otEJD2iempxOr\r\n4Ta2Db2Oj3raScsqu5YXdN8NWAYiwHOLz+LBPFSmcwjQLULf6MjK8vN8NYUX\r\nEOyNBur5zHPEtmrMSnnY1klxCYmmTNG33lkJDb2EtiCKtO/SLa2CWBPz5ko4\r\nh4wFEEGOgxDPCXQ6JTEvFbza/2udKbPthE6HhhfJGHDhS9ymifyYZXnBMzPe\r\npn/82V8Z54YjNEKmq6f9TrfDThqpWS/C3+9lhuXrhRpqZsjjD/QyM6TuT46O\r\npLMBstXR/apaYHbI0Z0OP+q8lh8sT+w8xw32WWNcGm9KvSVKVeyEowYA5rIl\r\nKU455hMiBUCWOBOHcypw0NJ0sIpAz3CpIedqMS9zLMUTd1oUrR0qDv1Or0Uv\r\nJeuev+3thKWgJWp1Wi0wvXMgQIjZJ/6afkk=\r\n=CqaT\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./lib/cjs/index.cjs","name":"@proload/core","types":"./lib/index.d.ts","author":{"name":"Nate Moore","email":"nate@natemoo.re"},"module":"./lib/esm/index.mjs","readme":"# `@proload/core`\n\nProload searches for and loads your tool's JavaScript configuration files. Users have complex expectations when it comes to configuration files—the goal of Proload is to offer a single, straightforward and extensible API for loading them.\n\n```js\nimport load from '@proload/core';\n\nawait load('namespace');\n```\n\n> `@proload/core` can be used in `node@12.20.1` and up. It relies on Node's native ESM semantics.\n\n## Motivation\n\nConfiguration files are really difficult to get right. Tool authors tend to think, \"Easy solve! I'll just have everyone use one `namespace.config.js`!\" In most cases that should work, but since `node@12.17.0`, plain `.js` files can be written in either ESM or CJS—both formats are officially supported and can be configured on a per-project basis. Additionally, `node` is able to load any file using a `.cjs` or `.mjs` extension, not just `.js`.\n\nMany popular libraries get these semantics wrong, but maintaining and testing this resolution logic in library code can be a huge maintanence burden. As a library author, you don't need to know (or care) which module format your users choose—you just need to load the contents of the config file. `@proload/core` is a well-tested solution that gets these semantics right, so you can focus on more important things.\n\n> You probably have TypeScript users, too! They would definitely appreciate being able to write a `.ts` config file. `@proload/core` uses a plugin system to load non-JavaScript files. See [Plugins](https://github.com/natemoo-re/proload/tree/main/packages/core#plugins) or [`@proload/plugin-typescript`](https://github.com/natemoo-re/proload/tree/main/packages/core#typescript) specifically.\n\n## Resolution\n\nOut of the box, `@proload/core` searches up the directory tree for the following files:\n\n- a `[namespace].config.js`, `[namespace].config.cjs`, or `[namespace].config.mjs` file\n- any of the `js/cjs/mjs` files inside of `config/` directory\n- a `package.json` file with a top-level `[namespace]` key\n\n\nHere's an overview of all the files supported by default for a tool named `donut`.\n\n```\nawait load('donut');\n\n.\n├── donut.config.js        // Either ESM or CJS supported\n├── donut.config.cjs\n├── donut.config.mjs\n├── config/                // Great for organizing many configs\n│   ├── donut.config.js\n│   ├── donut.config.cjs\n│   └── donut.config.mjs\n└── package.json           // with top-level \"donut\" property\n```\n\n## `resolve`\n\n`resolve` is an additional named export of `@proload/core`. It is an `async` function that resolves **but does not load** a configuration file.\n\n- `namespace` is the name of your tool. As an example, `donut` would search for `donut.config.[ext]`.\n- `opts` configure the behavior of `load`. See [Options](https://github.com/natemoo-re/proload/tree/main/packages/core#options).\n\n```ts\nresolve(namespace: string, opts?: ResolveOptions);\n```\n\n## `load`\n\nThe `default` export of `@proload/core` is an `async` function to load a configuration file.\n\n- `namespace` is the name of your tool. As an example, `donut` would search for `donut.config.[ext]`.\n- `opts` configure the behavior of `load`. See [Options](https://github.com/natemoo-re/proload/tree/main/packages/core#options).\n\n```ts\nload(namespace: string, opts?: LoadOptions);\n```\n\n\n## Options\n\n### cwd\n`load` searches up the directory tree, beginning from this loaction. Defaults to `process.cwd()`.\n\n```js\nimport load from '@proload/core';\nawait load('namespace', { cwd: '/path/to/user/project' });\n```\n\n### filePath\nIf you already have the exact (absolute or relative) `filePath` of your user's config file, set the `filePath` option to disable Proload's search algorithm.\n\n```js\nimport load from '@proload/core';\nawait load('namespace', { cwd: '/path/to/user/project', filePath: './custom-user-config.js' });\n```\n\n### mustExist\n`mustExist` controls whether a configuration _must_ be found. Defaults to `true`—Proload will throw an error when a configuration is not found. To customize error handling, you may check the shape of the thrown error. \n\nSetting this option to `false` allows a return value of `undefined` when a configuration is not found.\n\n```js\nimport load, { ProloadError } from '@proload/core';\n\ntry {\n    await load('namespace', { mustExist: true });\n} catch (err) {\n    // Proload couldn't resolve a configuration, log a custom contextual error\n    if (err instanceof ProloadError && err.code === 'ERR_PROLOAD_NOT_FOUND') {\n        console.error(`See the \"namespace\" docs for configuration info`);\n    }\n    throw err;\n}\n```\n\n### context\n\nUsers may want to dynamically generate a different configuration based on some contextual information passed from your tool. Any `{ context }` passed to the `load` function will be forwarded to configuration \"factory\" functions.\n\n```js\n// Library code\nimport load from '@proload/core';\nawait load('namespace', { context: { isDev: true }});\n\n// namespace.config.js\nexport default ({ isDev }) => {\n    return { featureFlag: isDev }\n}\n```\n\n### accept\nIf you need complete control over which file to load, the `accept` handler can customize resolution behavior. A return value of `true` marks a file to be loaded, any other return values (even truthy ones) is ignored.\n\nSee the [`accept`](https://github.com/natemoo-re/proload/blob/34413acf87d98d3ef310ce2873103455cb2eb379/packages/core/lib/index.d.ts#L11) interface.\n\n> Note that [Plugins](https://github.com/natemoo-re/proload/tree/main/packages/core#plugins) are able to modify similar behavior. To load non-JavaScript files, you should use a plugin instead of `accept`.\n\n```js\nimport load from '@proload/core';\n\nawait load('donut', {\n    accept(fileName) {\n        // Support alternative spelling for any European friends\n        return fileName.startsWith('doughnut.config');\n    }\n})\n```\n\nThe following example uses `@proload/plugin-typescript` to add support for loading `.ts` files and an `accept` handler to require all config files to use the `.ts` extension.\n```js\nimport load from '@proload/core';\nimport typescript from '@proload/plugin-typescript';\n\nload.use([typescript]);\nawait load('namespace', {\n    accept(fileName) {\n        // Only accept `.ts` config files\n        return fileName.endsWith('.ts');\n    }\n})\n```\n\n### merge\n\nTo customize `extends` behavior, you may pass a custom `merge` function to the `load` function. By default, [`deepmerge`](https://github.com/TehShrike/deepmerge) is used.\n\n```js\n// Library code\nimport load from '@proload/core';\n\nconst shallowMerge = (a, b) => ({ ...a, ...b })\nawait load('namespace', { merge: shallowMerge });\n\n// namespace.config.js\nexport default {\n    extends: ['./a.js', './b.js']\n}\n\n// a.js\nexport default {\n    a: true\n}\n\n// b.js\nexport default {\n    b: true\n}\n\n// result\n{\n    a: true,\n    b: true\n}\n```\n\n\n## Automatic `extends`\n\nTools like `typescript` and `babel` have popularized the ability to share configuration presets through a top-level `extends` clause. `extends` also allows you to share a local base configuration with other packages, which is extremely useful for monorepo users.\n\nCustom implementation of this behavior can be difficult, so `@proload/core` automatically recognizes top-level `extends` clauses (`string[]`) for you. It recursively resolves and merges all dependent configurations.\n\n```js\n// namespace.config.js\nexport default {\n    extends: ['@namespace/preset', '../namespace.base.config.js']\n}\n```\n\n### Extending local configuration files\nIn many cases, particularly in monorepos, it's useful to have a base configuration file and use `extends` in any sub-packages to inherit the base configuration. `@proload/core` resolves paths in `extends` relative to the configuration file itself.\n\n```\n.\n├── namespace.base.config.js\n└── packages/\n    ├── package-a/\n    │   └── namespace.config.js\n    └── package-b/\n        └── namespace.config.js\n```\n\n### Extending configuration presets\n`@proload/core` uses the same strategy to resolve a configuration file from project `dependencies` as it does for user configurations. When publishing a configuration preset, use the same file naming strategy as you would for local configuration.\n\n```\n.\n├── node_modules/\n│   └── @namespace/\n│       └── preset-env/\n│           ├── package.json\n│           └── namespace.config.js\n├── package.json\n└── namespace.config.js\n```\n\nAssuming `@namespace/preset-env` is a project dependency, the top-level `namespace.config.js` file can use `extends` to reference the dependency.\n\n```js\nexport default {\n    extends: ['@namespace/preset-env']\n}\n```\n\n## Plugins\n\nIn order to support as many use cases as possible, `@proload/core` uses a plugin system. Plugins build on each other and are designed to be combined. For example, to support a `namespacerc.json` file, you could use both `@proload/plugin-json` and `@proload/plugin-rc`.\n\n```js\nimport load from '@proload/core';\nimport rc from '@proload/plugin-rc';\nimport json from '@proload/plugin-json';\n\nload.use([rc, json]);\nawait load('namespace');\n```\n\n### TypeScript\nIn order to load a `[namespace].config.ts` file, use `@proload/plugin-typescript`.\n\n```js\nimport load from '@proload/core';\nimport typescript from '@proload/plugin-typescript';\n\nload.use([typescript]);\nawait load('namespace');\n```\n\n### JSON\nIn order to load a `[namespace].config.json` file, use `@proload/plugin-json`.\n\n```js\nimport load from '@proload/core';\nimport json from '@proload/plugin-json';\n\nload.use([json]);\nawait load('namespace');\n```\n\n### YAML\nIn order to load a `[namespace].config.yaml` or `[namespace].config.yml` file, use `@proload/plugin-yaml`.\n\n```js\nimport load from '@proload/core';\nimport yaml from '@proload/plugin-yaml';\n\nload.use([yaml]);\nawait load('namespace');\n```\n\n### RC files\nIn order to load a `[namespace]rc` file with any extension, use `@proload/plugin-rc`.\n\n```js\nimport load from '@proload/core';\nimport rc from '@proload/plugin-rc';\n\nload.use([rc]);\nawait load('namespace');\n```\n\n### All Plugins\nFor illustrative purposes (please don't do this), combining all of these plugins would support the following resolution logic:\n\n```\n.\n├── namespace.config.js\n├── namespace.config.cjs\n├── namespace.config.mjs\n├── namespace.config.ts\n├── namespace.config.json\n├── namespace.config.yaml\n├── namespace.config.yml\n├── namespacerc.js\n├── namespacerc.cjs\n├── namespacerc.mjs\n├── namespacerc.ts\n├── namespacerc.json\n├── namespacerc.yaml\n├── namespacerc.yml\n├── config/\n│   ├── namespace.config.js\n│   ├── namespace.config.cjs\n│   ├── namespace.config.mjs\n│   ├── namespace.config.ts\n│   ├── namespace.config.json\n│   ├── namespace.config.yaml\n│   ├── namespace.config.yml\n│   ├── namespacerc.js\n│   ├── namespacerc.cjs\n│   ├── namespacerc.mjs\n│   ├── namespacerc.ts\n│   ├── namespacerc.json\n│   ├── namespacerc.yaml\n│   └── namespacerc.yml\n└── package.json\n```\n\n## Credits\n\nProload is heavily inspired by tools like [`cosmiconfig`](https://github.com/davidtheclark/cosmiconfig#readme) and [`rc`](https://github.com/dominictarr/rc). \n\nProload would not be possible without [@lukeed](https://github.com/lukeed)'s amazing work on [`escalade`](https://github.com/lukeed/escalade) and [`uvu`](https://github.com/lukeed/uvu).\n","exports":{".":{"import":"./lib/esm/index.mjs","require":"./lib/cjs/index.cjs"},"./cjs":"./lib/cjs/index.cjs","./esm":"./lib/esm/index.mjs","./package.json":"./package.json","./lib/index.d.ts":"./lib/index.d.ts"},"license":"MIT","_npmUser":{"name":"natemoo-re","email":"nate@natemoo.re"},"homepage":"https://github.com/natemoo-re/proload#readme","keywords":["load","configuration","config","esm","cjs","typescript"],"repository":{"url":"git+https://github.com/natemoo-re/proload.git","type":"git","directory":"packages/core"},"_npmVersion":"6.14.16","description":"Searches for and loads your tool's JavaScript configuration files with full support for CJS, ESM, TypeScript and more.","directories":{},"maintainers":[{"name":"natemoo-re","email":"nate@natemoo.re"}],"_nodeVersion":"14.19.1","dependencies":{"escalade":"^3.1.1","deepmerge":"^4.2.2","resolve-pkg":"^2.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","_npmOperationalInternal":{"tmp":"tmp/core_0.3.2-next.1_1650986693217_0.4524984735903923","host":"s3://npm-registry-packages"},"_id":"@proload/core@0.3.2-next.1","version":"0.3.2-next.1"}