HEX
Server: Apache
System: Linux webd004.cluster130.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64
User: frenchy (106757)
PHP: 7.4.33
Disabled: _dyuweyrj4,_dyuweyrj4r,dl
Upload Files
File: /home/frenchy/www/french-american.org/current/node_modules/promised-handlebars/lib/markers.js
/*!
 * promised-handlebars <https://github.com/nknapp/promised-handlebars>
 *
 * Copyright (c) 2015 Nils Knappmeier.
 * Released under the MIT license.
 */

'use strict'

var isPromiseAlike = require('./utils').isPromiseAlike
var createReplaceP = require('./replaceP')

/**
 * Returns a `Markers` constructor that uses a specific Promise constructor
 * @param Promise a Promise constructor
 * @return {Markers} the Markers class
 */
module.exports = function createMarkersClass (Promise) {
  var replaceP = createReplaceP(Promise)

  /**
   * A class the handles the creation and resolution of markers in the Handlebars output.
   * Markes are used as placeholders in the output string for promises returned by helpers.
   * They are replaced as soon as the promises are resolved.
   * @param {Handlebars} engine a Handlebars instance (needed for the `escapeExpression` function)
   * @param {string} prefix the prefix to identify placeholders (this prefix should never occur in the template).
   * @constructor
   */
  function Markers (engine, prefix) {
    /**
     * This array stores the promises created in the current event-loop cycle
     * @type {Promise[]}
     */
    this.promiseStore = []
    this.engine = engine
    this.prefix = prefix
    // one line from substack's quotemeta-package
    var placeHolderRegexEscaped = String(this.prefix).replace(/(\W)/g, '\\$1')
    this.regex = new RegExp(placeHolderRegexEscaped + '(\\d+)(>|&gt;)', 'g')
  }

  /**
   * Add a promise the the store and return a placeholder.
   * A placeholder consists of
   * * The configured prefix (or \u0001), followed by
   * * the index in the array
   * * ">"

   * @param {Promise} promise the promise
   * @return {Promise} a new promise with a toString-method returning the placeholder
   */
  Markers.prototype.asMarker = function asMarker (promise) {
    // The placeholder: "prefix" for identification, index of promise in the store for retrieval, '>' for escaping
    var placeholder = this.prefix + this.promiseStore.length + '>'
    // Create a new promise, don't modify the input
    var result = Promise.resolve(promise)
    result.toString = function () {
      return placeholder
    }
    this.promiseStore.push(promise)
    return result
  }

  /**
   * Replace the placeholder found in a string by the resolved promise values.
   * The input may be Promise, in which case it will be resolved first.
   * Non-string values are returned directly since they cannot contain placeholders.
   * String values are search for placeholders, which are then replaced by their resolved values.
   * If the '>' part of the placeholder has been escaped (i.e. as '&gt;') the resolved value
   * will be escaped as well.
   *
   * @param {Promise<any>} input the string with placeholders
   * @return {Promise<string>} a promise for the string with resolved placeholders
   */
  Markers.prototype.resolve = function resolve (input) {
    var self = this
    return Promise.resolve(input).then(function (output) {
      if (typeof output !== 'string') {
        // Make sure that non-string values (e.g. numbers) are not converted to a string.
        return output
      }
      return Promise.all(self.promiseStore)
        .then(function (promiseResults) {
          /**
           * Replace placeholders in a string. Looks for placeholders
           * in the replacement string recursively.
           * @param {string|Promise|Handlebars.SafeString} string
           * @returns {Promise<string>}
           */
          function replacePlaceholdersRecursivelyIn (string) {
            if (isPromiseAlike(string)) {
              return string.then(function (string) {
                return replacePlaceholdersRecursivelyIn(string)
              })
            }
            if (typeof string.toHTML === 'function' && string.string) {
              // This is a Handlebars.SafeString or something like it
              return replacePlaceholdersRecursivelyIn(string.string)
            }

            // Must be a string, or something that can be converted to a string
            return replaceP(String(string), self.regex, function (match, index, gt) {
              // Check whether promise result must be escaped
              var resolvedValue = promiseResults[ index ]
              var result = gt === '>' ? resolvedValue : self.engine.escapeExpression(resolvedValue)
              return replacePlaceholdersRecursivelyIn(result)
            })
          }

          // Promises are fulfilled. Insert real values into the result.
          return replacePlaceholdersRecursivelyIn(output)
        })
    })
  }

  return Markers
}