Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/ts.corals.io/frontend/node_modules/@nuxt/vue-renderer/dist/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //home/corals/ts.corals.io/frontend/node_modules/@nuxt/vue-renderer/dist/vue-renderer.js
/*!
 * @nuxt/vue-renderer v2.15.8 (c) 2016-2021
 * Released under the MIT License
 * Repository: https://github.com/nuxt/nuxt.js
 * Website: https://nuxtjs.org
*/
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

const path = require('path');
const fs = require('fs-extra');
const consola = require('consola');
const lodash = require('lodash');
const utils = require('@nuxt/utils');
const ufo = require('ufo');
const defu = require('defu');
const VueMeta = require('vue-meta');
const vueServerRenderer = require('vue-server-renderer');
const LRU = require('lru-cache');
const devalue = require('@nuxt/devalue');
const crypto = require('crypto');
const util = require('util');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

const path__default = /*#__PURE__*/_interopDefaultLegacy(path);
const fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
const consola__default = /*#__PURE__*/_interopDefaultLegacy(consola);
const defu__default = /*#__PURE__*/_interopDefaultLegacy(defu);
const VueMeta__default = /*#__PURE__*/_interopDefaultLegacy(VueMeta);
const LRU__default = /*#__PURE__*/_interopDefaultLegacy(LRU);
const devalue__default = /*#__PURE__*/_interopDefaultLegacy(devalue);
const crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);

class BaseRenderer {
  constructor (serverContext) {
    this.serverContext = serverContext;
    this.options = serverContext.options;

    this.vueRenderer = this.createRenderer();
  }

  createRenderer () {
    throw new Error('`createRenderer()` needs to be implemented')
  }

  renderTemplate (templateFn, opts) {
    // Fix problem with HTMLPlugin's minify option (#3392)
    opts.html_attrs = opts.HTML_ATTRS;
    opts.head_attrs = opts.HEAD_ATTRS;
    opts.body_attrs = opts.BODY_ATTRS;

    return templateFn(opts)
  }

  render () {
    throw new Error('`render()` needs to be implemented')
  }
}

class SPARenderer extends BaseRenderer {
  constructor (serverContext) {
    super(serverContext);

    this.cache = new LRU__default['default']();

    this.vueMetaConfig = {
      ssrAppId: '1',
      ...this.options.vueMeta,
      keyName: 'head',
      attribute: 'data-n-head',
      ssrAttribute: 'data-n-head-ssr',
      tagIDKeyName: 'hid'
    };
  }

  createRenderer () {
    return vueServerRenderer.createRenderer()
  }

  async render (renderContext) {
    const { url = '/', req = {} } = renderContext;
    const modernMode = this.options.modern;
    const modern = (modernMode && this.options.target === utils.TARGETS.static) || utils.isModernRequest(req, modernMode);
    const cacheKey = `${modern ? 'modern:' : 'legacy:'}${url}`;
    let meta = this.cache.get(cacheKey);

    if (meta) {
      // Return a copy of the content, so that future
      // modifications do not effect the data in cache
      return lodash.cloneDeep(meta)
    }

    meta = {
      HTML_ATTRS: '',
      HEAD_ATTRS: '',
      BODY_ATTRS: '',
      HEAD: '',
      BODY_SCRIPTS_PREPEND: '',
      BODY_SCRIPTS: ''
    };

    if (this.options.features.meta) {
      // Get vue-meta context
      renderContext.head = typeof this.options.head === 'function'
        ? this.options.head()
        : lodash.cloneDeep(this.options.head);
    }

    // Allow overriding renderContext
    await this.serverContext.nuxt.callHook('vue-renderer:spa:prepareContext', renderContext);

    if (this.options.features.meta) {
      const m = VueMeta__default['default'].generate(renderContext.head || {}, this.vueMetaConfig);

      // HTML_ATTRS
      meta.HTML_ATTRS = m.htmlAttrs.text();

      // HEAD_ATTRS
      meta.HEAD_ATTRS = m.headAttrs.text();

      // BODY_ATTRS
      meta.BODY_ATTRS = m.bodyAttrs.text();

      // HEAD tags
      meta.HEAD =
        m.title.text() +
        m.meta.text() +
        m.link.text() +
        m.style.text() +
        m.script.text() +
        m.noscript.text();

      // Add <base href=""> meta if router base specified
      if (this.options._routerBaseSpecified) {
        meta.HEAD += `<base href="${this.options.router.base}">`;
      }

      // BODY_SCRIPTS (PREPEND)
      meta.BODY_SCRIPTS_PREPEND =
        m.meta.text({ pbody: true }) +
        m.link.text({ pbody: true }) +
        m.style.text({ pbody: true }) +
        m.script.text({ pbody: true }) +
        m.noscript.text({ pbody: true });

      // BODY_SCRIPTS (APPEND)
      meta.BODY_SCRIPTS =
        m.meta.text({ body: true }) +
        m.link.text({ body: true }) +
        m.style.text({ body: true }) +
        m.script.text({ body: true }) +
        m.noscript.text({ body: true });
    }

    // Resources Hints
    meta.resourceHints = '';

    const { resources: { modernManifest, clientManifest } } = this.serverContext;
    const manifest = modern ? modernManifest : clientManifest;

    const { shouldPreload, shouldPrefetch } = this.options.render.bundleRenderer;

    if (this.options.render.resourceHints && manifest) {
      const publicPath = manifest.publicPath || '/_nuxt/';

      // Preload initial resources
      if (Array.isArray(manifest.initial)) {
        const { crossorigin } = this.options.render;
        const cors = `${crossorigin ? ` crossorigin="${crossorigin}"` : ''}`;

        meta.preloadFiles = manifest.initial
          .map(SPARenderer.normalizeFile)
          .filter(({ fileWithoutQuery, asType }) => shouldPreload(fileWithoutQuery, asType))
          .map(file => ({ ...file, modern }));

        meta.resourceHints += meta.preloadFiles
          .map(({ file, extension, fileWithoutQuery, asType, modern }) => {
            let extra = '';
            if (asType === 'font') {
              extra = ` type="font/${extension}"${cors ? '' : ' crossorigin'}`;
            }
            const rel = modern && asType === 'script' ? 'modulepreload' : 'preload';
            return `<link rel="${rel}"${cors} href="${publicPath}${file}"${
              asType !== '' ? ` as="${asType}"` : ''}${extra}>`
          })
          .join('');
      }

      // Prefetch async resources
      if (Array.isArray(manifest.async)) {
        meta.resourceHints += manifest.async
          .map(SPARenderer.normalizeFile)
          .filter(({ fileWithoutQuery, asType }) => shouldPrefetch(fileWithoutQuery, asType))
          .map(({ file }) => `<link rel="prefetch" href="${publicPath}${file}">`)
          .join('');
      }

      // Add them to HEAD
      if (meta.resourceHints) {
        meta.HEAD += meta.resourceHints;
      }
    }

    // Serialize state (runtime config)
    let APP = `${meta.BODY_SCRIPTS_PREPEND}<div id="${this.serverContext.globals.id}">${this.serverContext.resources.loadingHTML}</div>${meta.BODY_SCRIPTS}`;

    const payload = {
      config: renderContext.runtimeConfig.public
    };
    if (renderContext.staticAssetsBase) {
      payload.staticAssetsBase = renderContext.staticAssetsBase;
    }
    APP += `<script>window.${this.serverContext.globals.context}=${devalue__default['default'](payload)}</script>`;

    // Prepare template params
    const templateParams = {
      ...meta,
      APP,
      ENV: this.options.env
    };

    // Call spa:templateParams hook
    await this.serverContext.nuxt.callHook('vue-renderer:spa:templateParams', templateParams);

    // Render with SPA template
    const html = this.renderTemplate(this.serverContext.resources.spaTemplate, templateParams);
    const content = {
      html,
      preloadFiles: meta.preloadFiles || []
    };

    // Set meta tags inside cache
    this.cache.set(cacheKey, content);

    // Return a copy of the content, so that future
    // modifications do not effect the data in cache
    return lodash.cloneDeep(content)
  }

  static normalizeFile (file) {
    const withoutQuery = file.replace(/\?.*/, '');
    const extension = path.extname(withoutQuery).slice(1);
    return {
      file,
      extension,
      fileWithoutQuery: withoutQuery,
      asType: SPARenderer.getPreloadType(extension)
    }
  }

  static getPreloadType (ext) {
    if (ext === 'js') {
      return 'script'
    } else if (ext === 'css') {
      return 'style'
    } else if (/jpe?g|png|svg|gif|webp|ico|avif/.test(ext)) {
      return 'image'
    } else if (/woff2?|ttf|otf|eot/.test(ext)) {
      return 'font'
    } else {
      return ''
    }
  }
}

class SSRRenderer extends BaseRenderer {
  get rendererOptions () {
    const hasModules = fs__default['default'].existsSync(path__default['default'].resolve(this.options.rootDir, 'node_modules'));

    return {
      clientManifest: this.serverContext.resources.clientManifest,
      // for globally installed nuxt command, search dependencies in global dir
      basedir: hasModules ? this.options.rootDir : __dirname,
      ...this.options.render.bundleRenderer
    }
  }

  addAttrs (tags, referenceTag, referenceAttr) {
    const reference = referenceTag ? `<${referenceTag}` : referenceAttr;
    if (!reference) {
      return tags
    }

    const { render: { crossorigin } } = this.options;
    if (crossorigin) {
      tags = tags.replace(
        new RegExp(reference, 'g'),
        `${reference} crossorigin="${crossorigin}"`
      );
    }

    return tags
  }

  renderResourceHints (renderContext) {
    return this.addAttrs(renderContext.renderResourceHints(), null, 'rel="preload"')
  }

  renderScripts (renderContext) {
    let renderedScripts = this.addAttrs(renderContext.renderScripts(), 'script');
    if (this.options.render.asyncScripts) {
      renderedScripts = renderedScripts.replace(/defer>/g, 'defer async>');
    }
    return renderedScripts
  }

  renderStyles (renderContext) {
    return this.addAttrs(renderContext.renderStyles(), 'link')
  }

  getPreloadFiles (renderContext) {
    return renderContext.getPreloadFiles()
  }

  createRenderer () {
    // Create bundle renderer for SSR
    return vueServerRenderer.createBundleRenderer(
      this.serverContext.resources.serverManifest,
      this.rendererOptions
    )
  }

  useSSRLog () {
    if (!this.options.render.ssrLog) {
      return
    }
    const logs = [];
    const devReporter = {
      log (logObj) {
        logs.push({
          ...logObj,
          args: logObj.args.map(arg => util.format(arg))
        });
      }
    };
    consola__default['default'].addReporter(devReporter);

    return () => {
      consola__default['default'].removeReporter(devReporter);
      return logs
    }
  }

  async render (renderContext) {
    // Call ssr:context hook to extend context from modules
    await this.serverContext.nuxt.callHook('vue-renderer:ssr:prepareContext', renderContext);

    const getSSRLog = this.useSSRLog();

    // Call Vue renderer renderToString
    let APP = await this.vueRenderer.renderToString(renderContext);

    if (typeof getSSRLog === 'function') {
      renderContext.nuxt.logs = getSSRLog();
    }

    // Call ssr:context hook
    await this.serverContext.nuxt.callHook('vue-renderer:ssr:context', renderContext);

    // TODO: Remove in next major release (#4722)
    await this.serverContext.nuxt.callHook('_render:context', renderContext.nuxt);

    // Fallback to empty response
    if (!renderContext.nuxt.serverRendered) {
      APP = `<div id="${this.serverContext.globals.id}"></div>`;
    }

    // Perf: early returns if server target and redirected
    if (renderContext.redirected && renderContext.target === utils.TARGETS.server) {
      return {
        html: APP,
        error: renderContext.nuxt.error,
        redirected: renderContext.redirected
      }
    }

    let HEAD = '';

    // Inject head meta
    // (this is unset when features.meta is false in server template)
    const meta = renderContext.meta && renderContext.meta.inject({
      isSSR: renderContext.nuxt.serverRendered,
      ln: this.options.dev
    });

    if (meta) {
      HEAD += meta.title.text() + meta.meta.text();
    }

    // Add <base href=""> meta if router base specified
    if (this.options._routerBaseSpecified) {
      HEAD += `<base href="${this.options.router.base}">`;
    }

    if (meta) {
      HEAD += meta.link.text() +
        meta.style.text() +
        meta.script.text() +
        meta.noscript.text();
    }

    // Check if we need to inject scripts and state
    const shouldInjectScripts = this.options.render.injectScripts !== false;

    // Inject resource hints
    if (this.options.render.resourceHints && shouldInjectScripts) {
      HEAD += this.renderResourceHints(renderContext);
    }

    // Inject styles
    HEAD += this.renderStyles(renderContext);

    if (meta) {
      const prependInjectorOptions = { pbody: true };

      const BODY_PREPEND =
        meta.meta.text(prependInjectorOptions) +
        meta.link.text(prependInjectorOptions) +
        meta.style.text(prependInjectorOptions) +
        meta.script.text(prependInjectorOptions) +
        meta.noscript.text(prependInjectorOptions);

      if (BODY_PREPEND) {
        APP = `${BODY_PREPEND}${APP}`;
      }
    }

    const { csp } = this.options.render;
    // Only add the hash if 'unsafe-inline' rule isn't present to avoid conflicts (#5387)
    const containsUnsafeInlineScriptSrc = csp.policies && csp.policies['script-src'] && csp.policies['script-src'].includes('\'unsafe-inline\'');
    const shouldHashCspScriptSrc = csp && (csp.unsafeInlineCompatibility || !containsUnsafeInlineScriptSrc);
    const inlineScripts = [];

    if (shouldInjectScripts && renderContext.staticAssetsBase) {
      const preloadScripts = [];
      renderContext.staticAssets = [];
      const { staticAssetsBase, url, nuxt, staticAssets } = renderContext;
      const { data, fetch, mutations, ...state } = nuxt;

      // Initial state
      const stateScript = `window.${this.serverContext.globals.context}=${devalue__default['default']({
        staticAssetsBase,
        ...state
      })};`;

      // Make chunk for initial state > 10 KB
      const stateScriptKb = (stateScript.length * 4 /* utf8 */) / 100;
      if (stateScriptKb > 10) {
        const statePath = utils.urlJoin(url, 'state.js');
        const stateUrl = utils.urlJoin(staticAssetsBase, statePath);
        staticAssets.push({ path: statePath, src: stateScript });
        if (this.options.render.asyncScripts) {
          APP += `<script defer async src="${stateUrl}"></script>`;
        } else {
          APP += `<script defer src="${stateUrl}"></script>`;
        }
        preloadScripts.push(stateUrl);
      } else {
        APP += `<script>${stateScript}</script>`;
      }

      // Save payload only if no error or redirection were made
      if (!renderContext.nuxt.error && !renderContext.redirected) {
        // Page level payload.js (async loaded for CSR)
        const payloadPath = utils.urlJoin(url, 'payload.js');
        const payloadUrl = utils.urlJoin(staticAssetsBase, payloadPath);
        const routePath = ufo.withoutTrailingSlash(ufo.parsePath(url).pathname);
        const payloadScript = `__NUXT_JSONP__("${routePath}", ${devalue__default['default']({ data, fetch, mutations })});`;
        staticAssets.push({ path: payloadPath, src: payloadScript });
        preloadScripts.push(payloadUrl);
        // Add manifest preload
        if (this.options.generate.manifest) {
          const manifestUrl = utils.urlJoin(staticAssetsBase, 'manifest.js');
          preloadScripts.push(manifestUrl);
        }
      }

      // Preload links
      for (const href of preloadScripts) {
        HEAD += `<link rel="preload" href="${href}" as="script">`;
      }
    } else {
      // Serialize state
      let serializedSession;
      if (shouldInjectScripts || shouldHashCspScriptSrc) {
        // Only serialized session if need inject scripts or csp hash
        serializedSession = `window.${this.serverContext.globals.context}=${devalue__default['default'](renderContext.nuxt)};`;
        inlineScripts.push(serializedSession);
      }

      if (shouldInjectScripts) {
        APP += `<script>${serializedSession}</script>`;
      }
    }

    // Calculate CSP hashes
    const cspScriptSrcHashes = [];
    if (csp) {
      if (shouldHashCspScriptSrc) {
        for (const script of inlineScripts) {
          const hash = crypto__default['default'].createHash(csp.hashAlgorithm);
          hash.update(script);
          cspScriptSrcHashes.push(`'${csp.hashAlgorithm}-${hash.digest('base64')}'`);
        }
      }

      // Call ssr:csp hook
      await this.serverContext.nuxt.callHook('vue-renderer:ssr:csp', cspScriptSrcHashes);

      // Add csp meta tags
      if (csp.addMeta) {
        HEAD += `<meta http-equiv="Content-Security-Policy" content="script-src ${cspScriptSrcHashes.join()}">`;
      }
    }

    // Prepend scripts
    if (shouldInjectScripts) {
      APP += this.renderScripts(renderContext);
    }

    if (meta) {
      const appendInjectorOptions = { body: true };

      // Append body scripts
      APP += meta.meta.text(appendInjectorOptions);
      APP += meta.link.text(appendInjectorOptions);
      APP += meta.style.text(appendInjectorOptions);
      APP += meta.script.text(appendInjectorOptions);
      APP += meta.noscript.text(appendInjectorOptions);
    }

    // Template params
    const templateParams = {
      HTML_ATTRS: meta ? meta.htmlAttrs.text(renderContext.nuxt.serverRendered /* addSrrAttribute */) : '',
      HEAD_ATTRS: meta ? meta.headAttrs.text() : '',
      BODY_ATTRS: meta ? meta.bodyAttrs.text() : '',
      HEAD,
      APP,
      ENV: this.options.env
    };

    // Call ssr:templateParams hook
    await this.serverContext.nuxt.callHook('vue-renderer:ssr:templateParams', templateParams, renderContext);

    // Render with SSR template
    const html = this.renderTemplate(this.serverContext.resources.ssrTemplate, templateParams);

    let preloadFiles;
    if (this.options.render.http2.push) {
      preloadFiles = this.getPreloadFiles(renderContext);
    }

    return {
      html,
      cspScriptSrcHashes,
      preloadFiles,
      error: renderContext.nuxt.error,
      redirected: renderContext.redirected
    }
  }
}

class ModernRenderer extends SSRRenderer {
  constructor (serverContext) {
    super(serverContext);

    const { build: { publicPath }, router: { base } } = this.options;
    this.publicPath = utils.isUrl(publicPath) || ufo.isRelative(publicPath) ? publicPath : utils.urlJoin(base, publicPath);
  }

  get assetsMapping () {
    if (this._assetsMapping) {
      return this._assetsMapping
    }

    const { clientManifest, modernManifest } = this.serverContext.resources;
    const legacyAssets = clientManifest.assetsMapping;
    const modernAssets = modernManifest.assetsMapping;
    const mapping = {};

    Object.keys(legacyAssets).forEach((componentHash) => {
      const modernComponentAssets = modernAssets[componentHash] || [];
      legacyAssets[componentHash].forEach((legacyAssetName, index) => {
        mapping[legacyAssetName] = modernComponentAssets[index];
      });
    });
    delete clientManifest.assetsMapping;
    delete modernManifest.assetsMapping;
    this._assetsMapping = mapping;

    return mapping
  }

  get isServerMode () {
    return this.options.modern === 'server'
  }

  get rendererOptions () {
    const rendererOptions = super.rendererOptions;
    if (this.isServerMode) {
      rendererOptions.clientManifest = this.serverContext.resources.modernManifest;
    }
    return rendererOptions
  }

  renderScripts (renderContext) {
    const scripts = super.renderScripts(renderContext);

    if (this.isServerMode) {
      return scripts
    }

    const scriptPattern = /<script[^>]*?src="([^"]*?)" defer( async)?><\/script>/g;

    const modernScripts = scripts.replace(scriptPattern, (scriptTag, jsFile) => {
      const legacyJsFile = jsFile.replace(this.publicPath, '');
      const modernJsFile = this.assetsMapping[legacyJsFile];
      if (!modernJsFile) {
        return scriptTag.replace('<script', `<script nomodule`)
      }
      const moduleTag = scriptTag
        .replace('<script', `<script type="module"`)
        .replace(legacyJsFile, modernJsFile);
      const noModuleTag = scriptTag.replace('<script', `<script nomodule`);

      return noModuleTag + moduleTag
    });

    const safariNoModuleFixScript = `<script>${utils.safariNoModuleFix}</script>`;

    return safariNoModuleFixScript + modernScripts
  }

  getModernFiles (legacyFiles = []) {
    const modernFiles = [];

    for (const legacyJsFile of legacyFiles) {
      const modernFile = { ...legacyJsFile, modern: true };
      if (modernFile.asType === 'script') {
        const file = this.assetsMapping[legacyJsFile.file];
        modernFile.file = file;
        modernFile.fileWithoutQuery = file.replace(/\?.*/, '');
      }
      modernFiles.push(modernFile);
    }

    return modernFiles
  }

  getPreloadFiles (renderContext) {
    const preloadFiles = super.getPreloadFiles(renderContext);
    // In eligible server modern mode, preloadFiles are modern bundles from modern renderer
    return this.isServerMode ? preloadFiles : this.getModernFiles(preloadFiles)
  }

  renderResourceHints (renderContext) {
    const resourceHints = super.renderResourceHints(renderContext);
    if (this.isServerMode) {
      return resourceHints
    }

    const linkPattern = /<link[^>]*?href="([^"]*?)"[^>]*?as="script"[^>]*?>/g;

    return resourceHints.replace(linkPattern, (linkTag, jsFile) => {
      const legacyJsFile = jsFile.replace(this.publicPath, '');
      const modernJsFile = this.assetsMapping[legacyJsFile];
      if (!modernJsFile) {
        return ''
      }
      return linkTag
        .replace('rel="preload"', `rel="modulepreload"`)
        .replace(legacyJsFile, modernJsFile)
    })
  }

  render (renderContext) {
    if (this.isServerMode) {
      renderContext.res.setHeader('Vary', 'User-Agent');
    }
    return super.render(renderContext)
  }
}

class VueRenderer {
  constructor (context) {
    this.serverContext = context;
    this.options = this.serverContext.options;

    // Will be set by createRenderer
    this.renderer = {
      ssr: undefined,
      modern: undefined,
      spa: undefined
    };

    // Renderer runtime resources
    Object.assign(this.serverContext.resources, {
      clientManifest: undefined,
      modernManifest: undefined,
      serverManifest: undefined,
      ssrTemplate: undefined,
      spaTemplate: undefined,
      errorTemplate: this.parseTemplate('Nuxt Internal Server Error')
    });

    // Default status
    this._state = 'created';
    this._error = null;
  }

  ready () {
    if (!this._readyPromise) {
      this._state = 'loading';
      this._readyPromise = this._ready()
        .then(() => {
          this._state = 'ready';
          return this
        })
        .catch((error) => {
          this._state = 'error';
          this._error = error;
          throw error
        });
    }

    return this._readyPromise
  }

  async _ready () {
    // Resolve dist path
    this.distPath = path__default['default'].resolve(this.options.buildDir, 'dist', 'server');

    // -- Development mode --
    if (this.options.dev) {
      this.serverContext.nuxt.hook('build:resources', mfs => this.loadResources(mfs));
      return
    }

    // -- Production mode --

    // Try once to load SSR resources from fs
    await this.loadResources(fs__default['default']);

    // Without using `nuxt start` (programmatic, tests and generate)
    if (!this.options._start) {
      this.serverContext.nuxt.hook('build:resources', () => this.loadResources(fs__default['default']));
      return
    }

    // Verify resources
    if (this.options.modern && !this.isModernReady) {
      throw new Error(
        `No modern build files found in ${this.distPath}.\nUse either \`nuxt build --modern\` or \`modern\` option to build modern files.`
      )
    } else if (!this.isReady) {
      throw new Error(
        `No build files found in ${this.distPath}.\nUse either \`nuxt build\` or \`builder.build()\` or start nuxt in development mode.`
      )
    }
  }

  async loadResources (_fs) {
    const updated = [];

    const readResource = async (fileName, encoding) => {
      try {
        const fullPath = path__default['default'].resolve(this.distPath, fileName);

        if (!await _fs.exists(fullPath)) {
          return
        }
        const contents = await _fs.readFile(fullPath, encoding);

        return contents
      } catch (err) {
        consola__default['default'].error('Unable to load resource:', fileName, err);
      }
    };

    for (const resourceName in this.resourceMap) {
      const { fileName, transform, encoding } = this.resourceMap[resourceName];

      // Load resource
      let resource = await readResource(fileName, encoding);

      // Skip unavailable resources
      if (!resource) {
        continue
      }

      // Apply transforms
      if (typeof transform === 'function') {
        resource = await transform(resource, { readResource });
      }

      // Update resource
      this.serverContext.resources[resourceName] = resource;
      updated.push(resourceName);
    }

    // Load templates
    await this.loadTemplates();

    await this.serverContext.nuxt.callHook('render:resourcesLoaded', this.serverContext.resources);

    // Detect if any resource updated
    if (updated.length > 0) {
      // Create new renderer
      this.createRenderer();
    }
  }

  async loadTemplates () {
    // Reload error template
    const errorTemplatePath = path__default['default'].resolve(this.options.buildDir, 'views/error.html');

    if (await fs__default['default'].exists(errorTemplatePath)) {
      const errorTemplate = await fs__default['default'].readFile(errorTemplatePath, 'utf8');
      this.serverContext.resources.errorTemplate = this.parseTemplate(errorTemplate);
    }

    // Reload loading template
    const loadingHTMLPath = path__default['default'].resolve(this.options.buildDir, 'loading.html');

    if (await fs__default['default'].exists(loadingHTMLPath)) {
      this.serverContext.resources.loadingHTML = await fs__default['default'].readFile(loadingHTMLPath, 'utf8');
      this.serverContext.resources.loadingHTML = this.serverContext.resources.loadingHTML.replace(/\r|\n|[\t\s]{3,}/g, '');
    } else {
      this.serverContext.resources.loadingHTML = '';
    }
  }

  // TODO: Remove in Nuxt 3
  get noSSR () { /* Backward compatibility */
    return this.options.render.ssr === false
  }

  get SSR () {
    return this.options.render.ssr === true
  }

  get isReady () {
    // SPA
    if (!this.serverContext.resources.spaTemplate || !this.renderer.spa) {
      return false
    }

    // SSR
    if (this.SSR && (!this.serverContext.resources.ssrTemplate || !this.renderer.ssr)) {
      return false
    }

    return true
  }

  get isModernReady () {
    return this.isReady && this.serverContext.resources.modernManifest
  }

  // TODO: Remove in Nuxt 3
  get isResourcesAvailable () { /* Backward compatibility */
    return this.isReady
  }

  detectModernBuild () {
    const { options, resources } = this.serverContext;
    if ([false, 'client', 'server'].includes(options.modern)) {
      return
    }

    const isExplicitStaticModern = options.target === utils.TARGETS.static && options.modern;
    if (!resources.modernManifest && !isExplicitStaticModern) {
      options.modern = false;
      return
    }

    options.modern = options.render.ssr ? 'server' : 'client';
    consola__default['default'].info(`Modern bundles are detected. Modern mode (\`${options.modern}\`) is enabled now.`);
  }

  createRenderer () {
    // Resource clientManifest is always required
    if (!this.serverContext.resources.clientManifest) {
      return
    }

    this.detectModernBuild();

    // Create SPA renderer
    if (this.serverContext.resources.spaTemplate) {
      this.renderer.spa = new SPARenderer(this.serverContext);
    }

    // Skip the rest if SSR resources are not available
    if (this.serverContext.resources.ssrTemplate && this.serverContext.resources.serverManifest) {
      // Create bundle renderer for SSR
      this.renderer.ssr = new SSRRenderer(this.serverContext);

      if (this.options.modern !== false) {
        this.renderer.modern = new ModernRenderer(this.serverContext);
      }
    }
  }

  renderSPA (renderContext) {
    return this.renderer.spa.render(renderContext)
  }

  renderSSR (renderContext) {
    // Call renderToString from the bundleRenderer and generate the HTML (will update the renderContext as well)
    const renderer = renderContext.modern ? this.renderer.modern : this.renderer.ssr;
    return renderer.render(renderContext)
  }

  async renderRoute (url, renderContext = {}, _retried = 0) {
    /* istanbul ignore if */
    if (!this.isReady) {
      // Fall-back to loading-screen if enabled
      if (this.options.build.loadingScreen) {
        // Tell nuxt middleware to use `server:nuxt:renderLoading hook
        return false
      }

      // Retry
      const retryLimit = this.options.dev ? 60 : 3;
      if (_retried < retryLimit && this._state !== 'error') {
        await this.ready().then(() => utils.waitFor(1000));
        return this.renderRoute(url, renderContext, _retried + 1)
      }

      // Throw Error
      switch (this._state) {
        case 'created':
          throw new Error('Renderer ready() is not called! Please ensure `nuxt.ready()` is called and awaited.')
        case 'loading':
          throw new Error('Renderer is loading.')
        case 'error':
          throw this._error
        case 'ready':
          throw new Error(`Renderer resources are not loaded! Please check possible console errors and ensure dist (${this.distPath}) exists.`)
        default:
          throw new Error('Renderer is in unknown state!')
      }
    }

    // Log rendered url
    consola__default['default'].debug(`Rendering url ${url}`);

    // Add url to the renderContext
    renderContext.url = ufo.normalizeURL(url);

    // Add target to the renderContext
    renderContext.target = this.options.target;

    const { req = {}, res = {} } = renderContext;

    // renderContext.spa
    if (renderContext.spa === undefined) {
      // TODO: Remove reading from renderContext.res in Nuxt3
      renderContext.spa = !this.SSR || req.spa || res.spa;
    }

    // renderContext.modern
    if (renderContext.modern === undefined) {
      const modernMode = this.options.modern;
      renderContext.modern = modernMode === 'client' || utils.isModernRequest(req, modernMode);
    }

    // Set runtime config on renderContext
    renderContext.runtimeConfig = {
      private: renderContext.spa ? {} : defu__default['default'](this.options.privateRuntimeConfig, this.options.publicRuntimeConfig),
      public: { ...this.options.publicRuntimeConfig }
    };

    // Call renderContext hook
    await this.serverContext.nuxt.callHook('vue-renderer:context', renderContext);

    // Render SPA or SSR
    return renderContext.spa
      ? this.renderSPA(renderContext)
      : this.renderSSR(renderContext)
  }

  get resourceMap () {
    const publicPath = utils.urlJoin(this.options.app.cdnURL, this.options.app.assetsPath);
    return {
      clientManifest: {
        fileName: 'client.manifest.json',
        transform: src => Object.assign(JSON.parse(src), { publicPath })
      },
      modernManifest: {
        fileName: 'modern.manifest.json',
        transform: src => Object.assign(JSON.parse(src), { publicPath })
      },
      serverManifest: {
        fileName: 'server.manifest.json',
        // BundleRenderer needs resolved contents
        transform: async (src, { readResource }) => {
          const serverManifest = JSON.parse(src);

          const readResources = async (obj) => {
            const _obj = {};
            await Promise.all(Object.keys(obj).map(async (key) => {
              _obj[key] = await readResource(obj[key]);
            }));
            return _obj
          };

          const [files, maps] = await Promise.all([
            readResources(serverManifest.files),
            readResources(serverManifest.maps)
          ]);

          // Try to parse sourcemaps
          for (const map in maps) {
            if (maps[map] && maps[map].version) {
              continue
            }
            try {
              maps[map] = JSON.parse(maps[map]);
            } catch (e) {
              maps[map] = { version: 3, sources: [], mappings: '' };
            }
          }

          return {
            ...serverManifest,
            files,
            maps
          }
        }
      },
      ssrTemplate: {
        fileName: 'index.ssr.html',
        transform: src => this.parseTemplate(src)
      },
      spaTemplate: {
        fileName: 'index.spa.html',
        transform: src => this.parseTemplate(src)
      }
    }
  }

  parseTemplate (templateStr) {
    return lodash.template(templateStr, {
      interpolate: /{{([\s\S]+?)}}/g,
      evaluate: /{%([\s\S]+?)%}/g
    })
  }

  close () {
    if (this.__closed) {
      return
    }
    this.__closed = true;

    for (const key in this.renderer) {
      delete this.renderer[key];
    }
  }
}

exports.VueRenderer = VueRenderer;

Spamworldpro Mini