{
  "version": 3,
  "sources": ["../../../src/plugins/fully-specified/plugin.ts"],
  "sourceRoot": "file://",
  "sourcesContent": ["/**\n * @file Plugins - fully-specified\n * @module mkbuild/plugins/fully-specified\n */\n\nimport type { OutputMetadata } from '#src/types'\nimport type { NodeError } from '@flex-development/errnode'\nimport * as mlly from '@flex-development/mlly'\nimport * as pathe from '@flex-development/pathe'\nimport { at, cast, constant, define, get, keys } from '@flex-development/tutils'\nimport type {\n  BuildOptions,\n  BuildResult,\n  OnEndResult,\n  OutputFile,\n  Plugin,\n  PluginBuild\n} from 'esbuild'\nimport util from 'node:util'\n\n/**\n * Plugin-specific build options.\n *\n * @internal\n */\ntype SpecificOptions = { metafile: true; write: false }\n\n/**\n * Plugin name.\n *\n * @const {string} PLUGIN_NAME\n */\nconst PLUGIN_NAME: string = 'fully-specified'\n\n/**\n * Returns a specifier resolver plugin. There are three types of specifiers:\n *\n * > - *Relative specifiers* like `'./startup.js'` or `'../config.mjs'`. They\n * >   refer to a path relative to the location of the importing file. *The file\n * >   extension is always necessary for these.*\n * > - *Bare specifiers* like `'some-package'` or `'some-package/shuffle'`. They\n * >   can refer to the main entry point of a package by the package name, or a\n * >   specific feature module within a package prefixed by the package name as\n * >   per the examples respectively. *Including the file extension is only\n * >   necessary for packages without an [`\"exports\"`][1] field.*\n * > - *Absolute specifiers* like `'file:///opt/nodejs/config.js'`. They refer\n * >   directly and explicitly to a full path.\n *\n * The resolver adds file extensions to **absolute** and **relative** specifiers\n * in output content.\n *\n * **Note**: [`--experimental-specifier-resolution=node`][2] can be used to\n * customize the ESM specifier resolution algorithm so that file extensions are\n * not required.\n *\n * [1]: https://nodejs.org/api/packages.html#exports\n * [2]: https://nodejs.org/api/esm.html#customizing-esm-specifier-resolution-algorithm\n *\n * @see https://nodejs.org/api/esm.html#terminology\n *\n * @return {Plugin} Specifier resolver plugin\n */\nconst plugin = (): Plugin => {\n  /**\n   * Adds file extensions to relative specifiers in output file content.\n   *\n   * [1]: https://esbuild.github.io/plugins\n   * [2]: https://esbuild.github.io/api/#build-api\n   *\n   * @param {PluginBuild} build - [esbuild plugin api][1]\n   * @param {BuildOptions} build.initialOptions - [esbuild build api][2] options\n   * @param {PluginBuild['onEnd']} build.onEnd - Build end callback\n   * @return {void} Nothing when complete\n   * @throws {Error}\n   */\n  const setup = ({ initialOptions, onEnd }: PluginBuild): void => {\n    const {\n      absWorkingDir = process.cwd(),\n      bundle,\n      conditions,\n      metafile,\n      outExtension: { '.js': ext = '.js' } = {},\n      resolveExtensions,\n      preserveSymlinks,\n      write\n    } = initialOptions\n\n    // bundle output shouldn't contain relative specifiers\n    if (bundle) return void bundle\n\n    // esbuild write must be disabled to access result.outputFiles\n    if (write) throw new Error('write must be disabled')\n\n    // metafile required to get output metadata\n    if (!metafile) throw new Error('metafile required')\n\n    return void onEnd(\n      async (result: BuildResult<SpecificOptions>): Promise<OnEndResult> => {\n        /**\n         * Output file objects.\n         *\n         * @const {OutputFile[]} outputFiles\n         */\n        const outputFiles: OutputFile[] = []\n\n        for (const output of result.outputFiles) {\n          /**\n           * {@linkcode output} metadata.\n           *\n           * @const {OutputMetadata} metadata\n           */\n          const metadata: OutputMetadata = get(\n            result.metafile.outputs,\n            output.path.replace(absWorkingDir, '').replace(/^\\//, '')\n          )\n\n          /**\n           * Relative path to source file.\n           *\n           * @const {string} entryPoint\n           */\n          const entryPoint: string = get(\n            metadata,\n            'entryPoint',\n            // because this plugin doesn't handle bundles, the entry point can\n            // fallback to the first (and only!) key in metadata.inputs\n            at(keys(metadata.inputs), 0, '')\n          )\n\n          // skip output files without entry points\n          if (!entryPoint) {\n            outputFiles.push(output)\n            continue\n          }\n\n          // reset entry point\n          metadata.entryPoint = entryPoint\n\n          try {\n            // redefine output text\n            define(output, 'text', {\n              get: constant(\n                await mlly.fillModules(output.text, {\n                  conditions: new Set(conditions),\n                  ext,\n                  extensions: new Set(resolveExtensions),\n                  parent: mlly.toURL(pathe.join(absWorkingDir, entryPoint)),\n                  preserveSymlinks\n                })\n              )\n            })\n\n            // reset output contents\n            output.contents = new util.TextEncoder().encode(output.text)\n\n            // add output file with fully specified modules\n            outputFiles.push(output)\n          } catch (e: unknown) {\n            const { code, message, stack = '' } = cast<NodeError>(e)\n\n            return {\n              errors: [\n                {\n                  id: code,\n                  location: null,\n                  notes: [{ location: null, text: stack }],\n                  pluginName: PLUGIN_NAME,\n                  text: message\n                }\n              ]\n            }\n          }\n        }\n\n        // reset output files\n        result.outputFiles = outputFiles\n\n        return {}\n      }\n    )\n  }\n\n  return { name: PLUGIN_NAME, setup }\n}\n\nexport default plugin\n"],
  "mappings": ";;AAOA,YAAY,UAAU;AACtB,YAAY,WAAW;AACvB,SAAS,IAAI,MAAM,UAAU,QAAQ,KAAK,YAAY;AAStD,OAAO,UAAU;AAcjB,MAAM,cAAsB,mBA8BtB,SAAS,8BAwHN,EAAE,MAAM,aAAa,OA3Gd,wBAAC,EAAE,gBAAgB,MAAM,MAAyB;AAC9D,QAAM;AAAA,IACJ,gBAAgB,QAAQ,IAAI;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAGJ,MAAI,SAGJ;AAAA,QAAI;AAAO,YAAM,IAAI,MAAM,wBAAwB;AAGnD,QAAI,CAAC;AAAU,YAAM,IAAI,MAAM,mBAAmB;AAElD,WAAO,KAAK;AAAA,MACV,OAAO,WAA+D;AAMpE,cAAM,cAA4B,CAAC;AAEnC,mBAAW,UAAU,OAAO,aAAa;AAMvC,gBAAM,WAA2B;AAAA,YAC/B,OAAO,SAAS;AAAA,YAChB,OAAO,KAAK,QAAQ,eAAe,EAAE,EAAE,QAAQ,OAAO,EAAE;AAAA,UAC1D,GAOM,aAAqB;AAAA,YACzB;AAAA,YACA;AAAA;AAAA;AAAA,YAGA,GAAG,KAAK,SAAS,MAAM,GAAG,GAAG,EAAE;AAAA,UACjC;AAGA,cAAI,CAAC,YAAY;AACf,wBAAY,KAAK,MAAM;AACvB;AAAA,UACF;AAGA,mBAAS,aAAa;AAEtB,cAAI;AAEF,mBAAO,QAAQ,QAAQ;AAAA,cACrB,KAAK;AAAA,gBACH,MAAM,KAAK,YAAY,OAAO,MAAM;AAAA,kBAClC,YAAY,IAAI,IAAI,UAAU;AAAA,kBAC9B;AAAA,kBACA,YAAY,IAAI,IAAI,iBAAiB;AAAA,kBACrC,QAAQ,KAAK,MAAM,MAAM,KAAK,eAAe,UAAU,CAAC;AAAA,kBACxD;AAAA,gBACF,CAAC;AAAA,cACH;AAAA,YACF,CAAC,GAGD,OAAO,WAAW,IAAI,KAAK,YAAY,EAAE,OAAO,OAAO,IAAI,GAG3D,YAAY,KAAK,MAAM;AAAA,UACzB,SAAS,GAAY;AACnB,kBAAM,EAAE,MAAM,SAAS,QAAQ,GAAG,IAAI,KAAgB,CAAC;AAEvD,mBAAO;AAAA,cACL,QAAQ;AAAA,gBACN;AAAA,kBACE,IAAI;AAAA,kBACJ,UAAU;AAAA,kBACV,OAAO,CAAC,EAAE,UAAU,MAAM,MAAM,MAAM,CAAC;AAAA,kBACvC,YAAY;AAAA,kBACZ,MAAM;AAAA,gBACR;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAGA,sBAAO,cAAc,aAEd,CAAC;AAAA,MACV;AAAA,IACF;AAAA;AACF,GAzGc,SA2GoB,IAxHrB;AA2Hf,IAAO,iBAAQ;",
  "names": []
}
