Template.body.addContent((function() {
  var view = this;
  return [ HTML.Raw("
Welcome to Meteor (again)!
\n  "), Spacebars.include(view.lookupTemplate("hello")) ];
}));
Meteor.startup(Template.body.renderToDocument);

Template.__checkName("hello");
Template["hello"] = new Template("Template.hello", (function() {
  var view = this;
  return [ HTML.Raw("<button>Click Me</button>\n  "), HTML.P("You've pressed the button ", Blaze.View("lookup:counter", function() {
    return Spacebars.mustache(view.lookup("counter"));
  }), " times.") ];
}));


This npm package is not Meteor itself, this npm package is just an installer. You should not include it as a dependency in your project. If you do your deploy is going to be broken.

By default, the Meteor installer adds its install path (by default, `~/.meteor/`) to your PATH by updating either your `.bashrc`, `.bash_profile`, or `.zshrc` as appropriate. To disable this behavior, install Meteor by running:

keep keep keep keep replace keep keep keep keep

This npm package is not Meteor itself, it is just an installer. You should not include it as a dependency in your project. If you do, your deployment is going to be broken.

// This file exists because it is the file in the tool that is not automatically
// transpiled by Babel

"use strict";

function babelRegister() {
  const meteorBabel = require("@meteorjs/babel");
  const path = require("path");
  const toolsPath = path.dirname(__dirname);
  const meteorPath = path.dirname(toolsPath);
  const cacheDir = path.join(meteorPath, ".babel-cache");
  const babelOptions = meteorBabel.getDefaultOptions({
    nodeMajorVersion: parseInt(process.versions.node),
    typescript: true
  });

  // Make sure that source maps are included in the generated code for
  // meteor/tools modules.
  babelOptions.sourceMaps = "inline";

  require('@meteorjs/babel/register')
    .setCacheDirectory(cacheDir)
    .setSourceMapRootPath(meteorPath)
    .allowDirectory(toolsPath)
    .setBabelOptions(babelOptions)
    // Exclude files that are imported before we configure
    // meteor-babel/register (including this very file).
    .excludeFile(path.join(toolsPath, "index.js"))
    .excludeFile(path.join(__dirname, "install-promise.js"))
    .excludeFile(path.join(__dirname, "wrap-fibers.js"))
    .excludeFile(path.join(__dirname, "install-reify.js"))
    .excludeFile(path.join(toolsPath, "cli", "dev-bundle-bin-commands.js"))
    .excludeFile(path.join(toolsPath, "cli", "dev-bundle-bin-helpers.js"))
    .excludeFile(path.join(toolsPath, "cli", "flush-buffers-on-exit-in-windows.js"))
    .excludeFile(path.join(toolsPath, "cli", "convert-to-os-path.js"))
    .excludeFile(__filename);
}

// Install reify first so babel falls back to it
require('./install-reify.js');

babelRegister(); // #RemoveInProd this line is removed in isopack.js

require("./install-runtime.js");


// We use cryptographically strong PRNGs (crypto.getRandomBytes() on the server,
// window.crypto.getRandomValues() in the browser) when available. If these
// PRNGs fail, we fall back to the Alea PRNG, which is not cryptographically
// strong, and we seed it with various sources such as the date, Math.random,
// and window size on the client.  When using crypto.getRandomValues(), our
// primitive is hexString(), from which we construct fraction(). When using
// window.crypto.getRandomValues() or alea, the primitive is fraction and we use
// that to construct hex string.

import { Meteor } from 'meteor/meteor';

const UNMISTAKABLE_CHARS = '23456789ABCDEFGHJKLMNPQRSTWXYZabcdefghijkmnopqrstuvwxyz';
const BASE64_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +
  '0123456789-_';

// `type` is one of `RandomGenerator.Type` as defined below.
//
// options:
// - seeds: (required, only for RandomGenerator.Type.ALEA) an array
//   whose items will be `toString`ed and used as the seed to the Alea
//   algorithm
export default class RandomGenerator {

  /**
   * @name Random.fraction
   * @summary Return a number between 0 and 1, like `Math.random`.
   * @locus Anywhere
   */
  fraction () {
    throw new Error(`Unknown random generator type`);
  }

  /**
   * @name Random.hexString
   * @summary Return a random string of `n` hexadecimal digits.
   * @locus Anywhere
   * @param {Number} n Length of the string
   */
  hexString (digits) {
    return this._randomString(digits, '0123456789abcdef');
  }

  _randomString (charsCount, alphabet) {
    let result = '';
    for (let i = 0; i < charsCount; i++) {
      result += this.choice(alphabet);
    }
    return result;
  }

  /**
   * @name Random.id
   * @summary Return a unique identifier, such as `"Jjwjg6gouWLXhMGKW"`, that is
   * likely to be unique in the whole world.
   * @locus Anywhere
   * @param {Number} [n] Optional length of the identifier in characters
   *   (defaults to 17)
   */
  id (charsCount) {
    // 17 characters is around 96 bits of entropy, which is the amount of
    // state in the Alea PRNG.
    if (charsCount === undefined) {
      charsCount = 17;
    }

    return this._randomString(charsCount, UNMISTAKABLE_CHARS);
  }

  /**
   * @name Random.secret
   * @summary Return a random string of printable characters with 6 bits of
   * entropy per character. Use `Random.secret` for security-critical secrets
   * that are intended for machine, rather than human, consumption.
   * @locus Anywhere
   * @param {Number} [n] Optional length of the secret string (defaults to 43
   *   characters, or 256 bits of entropy)
   */
  secret (charsCount) {
    // Default to 256 bits of entropy, or 43 characters at 6 bits per
    // character.
    if (charsCount === undefined) {
      charsCount = 43;
    }

    return this._randomString(charsCount, BASE64_CHARS);
  }

  /**
   * @name Random.choice
   * @summary Return a random element of the given array or string.
   * @locus Anywhere
   * @param {Array|String} arrayOrString Array or string to choose from
   */
  choice (arrayOrString) {
    const index = Math.floor(this.fraction() * arrayOrString.length);
    if (typeof arrayOrString === 'string') {
      return arrayOrString.substr(index, 1);
    }
    return arrayOrString[index];
  }
}


const isInstalledGlobally = process.env.npm_config_global === 'true';

'You are not using a global npm context to install, you should never add meteor to your package.json.'

const { engines } = require('./package');

// Compare installed NodeJs version with required NodeJs version

if (!semver.satisfies(process.version, nodeVersion)) {

console.error(`Required Node.js version ${nodeVersion} not satisfied with current version ${process.version}.`);

console.error('If you need to use other Node.js versions, we recommend you using Volta or NVM.');

meteor

Install Meteor


exports.plugins = [
  require("@babel/plugin-syntax-nullish-coalescing-operator"),
  require("@babel/plugin-proposal-nullish-coalescing-operator"),

  require("@babel/plugin-syntax-optional-chaining"),
  require("@babel/plugin-proposal-optional-chaining"),

  require("@babel/plugin-syntax-optional-catch-binding"),
  require("@babel/plugin-proposal-optional-catch-binding"),

  require("@babel/plugin-syntax-class-properties"),
  require("@babel/plugin-proposal-class-properties"),

  require("@babel/plugin-syntax-async-generators"),
  require("@babel/plugin-proposal-async-generator-functions"),

  require("@babel/plugin-syntax-object-rest-spread"),
  require("@babel/plugin-proposal-object-rest-spread"),

  require("@babel/plugin-proposal-logical-assignment-operators"),
];


import {
  AccountsClient,
  AccountsTest,
} from "./accounts_client.js";

/**
 * @namespace Accounts
 * @summary The namespace for all client-side accounts-related methods.
 */
Accounts = new AccountsClient();

/**
 * @summary A [Mongo.Collection](#collections) containing user documents.
 * @locus Anywhere
 * @type {Mongo.Collection}
 * @importFromPackage meteor
 */
Meteor.users = Accounts.users;

export {
  Accounts,
  AccountsClient,
  AccountsTest,
  // For backwards compatibility. Note that exporting an object as the
  // default export is *not* the same as exporting its properties as named
  // exports, as was previously assumed.
  exports as default,
};


console.error('Make sure you pass -g to npm install.');

process.on('unhandledRejection', err => {

keep keep keep keep replace keep keep keep keep keep

Install Meteor


var common = require("./url_common.js");

exports._constructUrl = function (url, query, params) {
  var query_match = /^(.*?)(\?.*)?$/.exec(url);
  return common.buildUrl(
    query_match[1],
    query_match[2],
    query,
    params
  );
};

exports._encodeParams = common._encodeParams;


"use strict";

import _ from "underscore";
import files from "../fs/files";
import { WatchSet, sha1 } from "../fs/watch";
import { NodeModulesDirectory } from "./bundler.js";
import * as archinfo from "../utils/archinfo";
import { SourceResource } from './compiler';

function rejectBadPath(p) {
  if (p.indexOf("..") >= 0) {
    throw new Error("bad path: " + p);
  }
}

let nextBuildId = 1;

export class Unibuild {
  constructor(isopack, {
    kind, // required (main/plugin/app)
    arch, // required
    uses,
    implies,
    watchSet,
    nodeModulesDirectories,
    declaredExports,
    resources,
  }) {
    this.pkg = isopack;
    this.kind = kind;
    this.arch = arch;
    this.uses = uses;
    this.implies = implies || [];

    // This WatchSet will end up having the watch items from the
    // SourceArch (such as package.js or .meteor/packages), plus all of
    // the actual source files for the unibuild (including items that we
    // looked at to find the source files, such as directories we
    // scanned).
    this.watchSet = watchSet || new WatchSet();

    // Each Unibuild is given a unique id when it's loaded (it is not
    // saved to disk). This is just a convenience to make it easier to
    // keep track of Unibuilds in a map; it's used by bundler and
    // compiler. We put some human readable info in here too to make
    // debugging easier.
    this.id = this.pkg.name + "." + this.kind + "@" + this.arch + "#" +
      (nextBuildId ++);

    // 'declaredExports' are the variables which are exported from this
    // package.  A list of objects with keys 'name' (required) and
    // 'testOnly' (boolean, defaults to false).
    this.declaredExports = declaredExports;

    // All of the data provided for eventual inclusion in the bundle,
    // other than JavaScript that still needs to be fed through the final
    // link stage. A list of objects with these keys:
    //
    // type: "source", "head", "body", "asset". (resources produced by
    // legacy source handlers can also be "js" or "css".
    //
    // data: The contents of this resource, as a Buffer. For example, for
    // "head", the data to insert in <head>; for "js", the JavaScript
    // source code (which may be subject to further processing such as
    // minification); for "asset", the contents of a static resource such
    // as an image.
    //
    // servePath: The (absolute) path at which the resource would prefer
    // to be served. Interpretation varies by type. For example, always
    // honored for "asset", ignored for "head" and "body", sometimes
    // honored for CSS but ignored if we are concatenating.
    //
    // sourceMap: Allowed only for "js". If present, a string.
    //
    // fileOptions: for "source", the options passed to `api.addFiles`.
    // plugin-specific.
    //
    // extension: for "source", the file extension that this matched
    // against at build time. null if matched against a specific filename.
    this.resources = resources;

    // Map from absolute paths of node_modules directories to
    // NodeModulesDirectory objects.
    this.nodeModulesDirectories = nodeModulesDirectories;

    // Provided for backwards compatibility; please use
    // unibuild.nodeModulesDirectories instead!
    _.some(this.nodeModulesDirectories, (nmd, nodeModulesPath) => {
      if (! nmd.local) {
        this.nodeModulesPath = nodeModulesPath;
        return true;
      }
    });
  }

  static fromJSON(unibuildJson, {
    isopack,
    // At some point we stopped writing 'kind's to the metadata file, so
    // default to main.
    kind = "main",
    arch,
    unibuildBasePath,
    watchSet,
  }) {
    if (unibuildJson.format !== "unipackage-unibuild-pre1" &&
        unibuildJson.format !== "isopack-2-unibuild") {
      throw new Error("Unsupported isopack unibuild format: " +
                      JSON.stringify(unibuildJson.format));
    }

    // Is this unibuild the legacy pre-"compiler plugin" format which contains
    // "prelink" resources of pre-processed JS files (as well as the
    // "packageVariables" field) instead of individual "source" resources (and
    // a "declaredExports" field)?
    const unibuildHasPrelink =
      unibuildJson.format === "unipackage-unibuild-pre1";

    const resources = [];

    _.each(unibuildJson.resources, function (resource) {
      rejectBadPath(resource.file);

      const data = files.readBufferWithLengthAndOffset(
        files.pathJoin(unibuildBasePath, resource.file),
        resource.length,
        resource.offset,
      );

      if (resource.type === "prelink") {
        if (! unibuildHasPrelink) {
          throw Error("Unexpected prelink resource in " +
                      unibuildJson.format + " at " + unibuildBasePath);
        }

        // We found a "prelink" resource, because we're processing a package
        // published with an older version of Meteor which did not create
        // isopack-2 isopacks and which always preprocessed and linked all JS
        // files instead of leaving that until bundle time.  Let's pretend it
        // was just a single js source file, but leave a "legacyPrelink" field
        // on it so we can not re-link that part (and not re-analyze for
        // assigned variables).
        const prelinkResource = {
          type: "source",
          extension: "js",
          data: data,
          path: resource.servePath,
          // It's a shame to have to calculate the hash here instead of having
          // it on disk, but this only runs for legacy packages anyway.
          hash: sha1(data),
          // Legacy prelink files definitely don't have a source processor!
          // They were created by an Isobuild that didn't even know about
          // source processors!
          usesDefaultSourceProcessor: true,
          legacyPrelink: {
            packageVariables: unibuildJson.packageVariables || []
          },
          // Only published packages still use prelink resources,
          // so there is no need to mark this file to be watched
          _dataUsed: false
        };

        if (resource.sourceMap) {
          rejectBadPath(resource.sourceMap);
          prelinkResource.legacyPrelink.sourceMap = files.readFile(
            files.pathJoin(unibuildBasePath, resource.sourceMap), 'utf8');
        }

        resources.push(prelinkResource);

      } else if (resource.type === "source") {
        resources.push(new SourceResource({
          extension: resource.extension,
          usesDefaultSourceProcessor:
          !! resource.usesDefaultSourceProcessor,
          data: data,
          path: resource.path,
          hash: resource.hash,
          fileOptions: resource.fileOptions
        }));
      } else if (["head", "body", "css", "js", "asset"].includes(resource.type)) {
        resources.push({
          type: resource.type,
          data: data,
          servePath: resource.servePath || undefined,
          path: resource.path || undefined
        });

      } else {
        throw new Error("bad resource type in isopack: " +
                        JSON.stringify(resource.type));
      }
    });

    let declaredExports = unibuildJson.declaredExports || [];

    if (unibuildHasPrelink) {
      // Legacy unibuild; it stores packageVariables and says some of them
      // are exports.
      declaredExports = [];

      _.each(unibuildJson.packageVariables, function (pv) {
        if (pv.export) {
          declaredExports.push({
            name: pv.name,
            testOnly: pv.export === "tests",
          });
        }
      });
    }

    const nodeModulesDirectories =
      NodeModulesDirectory.readDirsFromJSON(unibuildJson.node_modules, {
        packageName: isopack.name,
        sourceRoot: unibuildBasePath,
        // Rebuild binary npm packages if unibuild arch matches host arch.
        rebuildBinaries: archinfo.matches(archinfo.host(), arch)
      });

    return new this(isopack, {
      kind,
      arch,
      uses: unibuildJson.uses,
      implies: unibuildJson.implies,
      watchSet,
      nodeModulesDirectories,
      declaredExports: declaredExports,
      resources: resources,
    });
  }

  toJSON({
    builder,
    unibuildDir,
    usesModules,
    npmDirsToCopy,
  }) {
    const unibuild = this;
    const unibuildJson = {
      format: "isopack-2-unibuild",
      declaredExports: unibuild.declaredExports,
      uses: _.map(unibuild.uses, u => ({
        'package': u.package,
        // For cosmetic value, leave false values for these options out of
        // the JSON file.
        constraint: u.constraint || undefined,
        unordered: u.unordered || undefined,
        weak: u.weak || undefined,
      })),
      implies: (_.isEmpty(unibuild.implies) ? undefined : unibuild.implies),
      resources: [],
    };

    // Figure out where the npm dependencies go.
    let node_modules = {};
    _.each(unibuild.nodeModulesDirectories, nmd => {
      const bundlePath = _.has(npmDirsToCopy, nmd.sourcePath)
      // We already have this npm directory from another unibuild.
        ? npmDirsToCopy[nmd.sourcePath]
        : npmDirsToCopy[nmd.sourcePath] =
            nmd.getPreferredBundlePath("isopack");
      node_modules[bundlePath] = nmd.toJSON();
    });

    const preferredPaths = Object.keys(node_modules);
    if (preferredPaths.length === 1) {
      // For backwards compatibility, if there's only one node_modules
      // directory, store it as a single string.
      node_modules = preferredPaths[0];
    }

    if (preferredPaths.length > 0) {
      // If there are no node_modules directories, don't confuse older
      // versions of Meteor by storing an empty object.
      unibuildJson.node_modules = node_modules;
    }

    // Output 'head', 'body' resources nicely
    const concat = { head: [], body: [] };
    const offset = { head: 0, body: 0 };

    _.each(unibuild.resources, function (resource) {
      if (["head", "body"].includes(resource.type)) {
        if (concat[resource.type].length) {
          concat[resource.type].push(Buffer.from("\n", "utf8"));
          offset[resource.type]++;
        }
        if (! (resource.data instanceof Buffer)) {
          throw new Error("Resource data must be a Buffer");
        }

        if (! usesModules &&
            resource.fileOptions &&
            resource.fileOptions.lazy) {
          // Omit lazy resources from the unibuild JSON file.
          return;
        }

        unibuildJson.resources.push({
          type: resource.type,
          file: files.pathJoin(unibuildDir, resource.type),
          length: resource.data.length,
          offset: offset[resource.type]
        });

        concat[resource.type].push(resource.data);
        offset[resource.type] += resource.data.length;
      }
    });

    _.each(concat, function (parts, type) {
      if (parts.length) {
        builder.write(files.pathJoin(unibuildDir, type), {
          data: Buffer.concat(concat[type], offset[type])
        });
      }
    });

    // Output other resources each to their own file
    _.each(unibuild.resources, function (resource) {
      if (["head", "body"].includes(resource.type)) {
        // already did this one
        return;
      }

      let data;
      if (resource.type === 'source') {
        data = resource.legacyPrelink ? resource.data : resource._data;
      } else {
        data = resource.data;
      }

      const generatedFilename =
        builder.writeToGeneratedFilename(
          files.pathJoin(
            unibuildDir,
            resource.servePath || resource.path,
          ),
          { data }
        );

      if (! usesModules &&
          resource.fileOptions &&
          resource.fileOptions.lazy) {
        // Omit lazy resources from the unibuild JSON file, but only after
        // they are copied into the bundle (immediately above).
        return;
      }

      unibuildJson.resources.push({
        type: resource.type,
        extension: resource.extension,
        file: generatedFilename,
        length: data.length,
        offset: 0,
        usesDefaultSourceProcessor:
          resource.usesDefaultSourceProcessor || undefined,
        servePath: resource.servePath || undefined,
        path: resource.path || undefined,
        hash: resource._hash || resource.hash || undefined,
        fileOptions: resource.fileOptions || undefined
      });
    });

    return unibuildJson;
  }

  getLegacyJsResources() {
    const legacyJsResources = [];

    this.resources.forEach(resource => {
      if (resource.type === "source" &&
          resource.extension === "js") {
        legacyJsResources.push({
          data: resource.data,
          hash: resource.hash,
          servePath: this.pkg._getServePath(resource.path),
          bare: resource.fileOptions && resource.fileOptions.bare,
          sourceMap: resource.sourceMap,
          // If this file was actually read from a legacy isopack and is
          // itself prelinked, this will be an object with some metadata
          // about it, and we can skip re-running prelink later.
          legacyPrelink: resource.legacyPrelink
        });
      }
    });

    return legacyJsResources;
  }
}


# modules-runtime-hot

Patches modules-runtime to support HMR.


{
"name": "meteor",
"version": "2.7.4",
"description": "Install Meteor",
"main": "install.js",
"scripts": {

const { DownloaderHelper } = require('node-downloader-helper');
const cliProgress = require('cli-progress');
const Seven = require('node-7z');
const path = require('path');
const sevenBin = require('7zip-bin');
const fs = require('fs');
const child_process = require('child_process');
const fsPromises = fs.promises;
const tmp = require('tmp');
const os = require('os');
const {
  meteorPath,
  release,
  startedPath,
  extractPath,
  isWindows,
  rootPath,
  sudoUser,
  isSudo,
  isMac,
  METEOR_LATEST_VERSION,
  shouldSetupExecPath,
} = require('./config.js');
const { uninstall } = require('./uninstall');
const {
  extractWithTar,
  extractWith7Zip,
  extractWithNativeTar,
} = require('./extract.js');
const semver = require('semver');
const isInstalledGlobally = process.env.npm_config_global === 'true';

if (!isInstalledGlobally) {
  console.error('******************************************');
  console.error(
    'You are not using a global npm context to install, you should never add meteor to your package.json.'
  );
  console.error('Make sure you pass -g to npm install.');
  console.error('Aborting');
  console.error('******************************************');
  process.exit(1);
}
process.on('unhandledRejection', err => {
  throw err;
});
if (os.arch() !== 'x64') {
  const isValidM1Version = semver.gte(semver.coerce(METEOR_LATEST_VERSION), '2.5.1-beta.3');
  if (os.arch() !== 'arm64' || !isMac() || !isValidM1Version) {
    console.error(
      'The current architecture is not supported in this version: ',
      os.arch(),
      '. Try Meteor 2.5.1-beta.3 or above.'
    );
    process.exit(1);
  }
}

const downloadPlatform = {
  win32: 'windows',
  darwin: 'osx',
  linux: 'linux',
};

const url = `https://packages.meteor.com/bootstrap-link?arch=os.${
  downloadPlatform[os.platform()]
}.${os.arch() === 'arm64' ? 'arm64' : 'x86_64'}&release=${release}`;

let tempDirObject;
try {
  tempDirObject = tmp.dirSync();
} catch (e) {
  console.error('');
  console.error('');
  console.error('****************************');
  console.error("Couldn't create tmp dir for extracting meteor.");
  console.error('There are 2 possible causes:');
  console.error(
    '\t1. You are running npm install -g meteor as root without passing the --unsafe-perm option. Please rerun with this option enabled.'
  );
  console.error(
    '\t2. You might not have enough space in disk or permission to create folders'
  );
  console.error('****************************');
  console.error('');
  console.error('');
  process.exit(1);
}
const tempPath = tempDirObject.name;
const tarGzName = 'meteor.tar.gz';
const tarName = 'meteor.tar';

// This file only exists while files are being extracted, and is removed after
// the extraction succeeds. If it still exists, there is either another instance of
// the installer running, or it failed the last time it extracted files.
if (fs.existsSync(startedPath)) {
  console.log('It seems the previous installation of Meteor did not succeed.');
  uninstall();
  console.log('');
} else if (fs.existsSync(meteorPath)) {
  console.log('Meteor is already installed at', meteorPath);
  console.log(
    `If you want to reinstall it, run:

  $ meteor-installer uninstall
  $ meteor-installer install
`
  );
  process.exit();
}

// Creating symlinks requires running as an administrator or
// for developer mode to be enabled
let canCreateSymlinks = false;
try {
  const target = path.resolve(tempPath, 'test-target.txt');
  const symlinkPath = path.resolve(tempPath, 'symlink.txt');

  fs.writeFileSync(target, '');
  fs.symlinkSync(target, symlinkPath, 'file');

  fs.unlinkSync(symlinkPath);
  fs.unlinkSync(target);
  canCreateSymlinks = true;
} catch (e) {
  if (e.code === 'EPERM') {
    // Leave canCreateSymlinks as false
  } else {
    console.error('Unable to check if able to create symlinks');
    console.error(e);
    console.log('Assuming unable to create symlinks');
  }
}

download();

function download() {
  const start = Date.now();
  const downloadProgress = new cliProgress.SingleBar(
    {
      format: 'Downloading |{bar}| {percentage}%',
      clearOnComplete: true,
    },
    cliProgress.Presets.shades_classic
  );
  downloadProgress.start(100, 0);

  const dl = new DownloaderHelper(url, tempPath, {
    retry: { maxRetries: 5, delay: 5000 },
    override: true,
    fileName: tarGzName,
  });

  dl.on('progress', ({ progress }) => {
    downloadProgress.update(progress);
  });
  dl.on('end', async () => {
    downloadProgress.update(100);
    downloadProgress.stop();
    const end = Date.now();
    console.log(`=> Meteor Downloaded in ${(end - start) / 1000}s`);

    const exists = fs.existsSync(path.resolve(tempPath, tarGzName));
    if (!exists) {
      throw new Error('meteor.tar.gz does not exist');
    }

    if (isWindows()) {
      decompress();
      return;
    }

    fs.writeFileSync(startedPath, 'Meteor install started');
    console.log('=> Extracting the tarball, this may take some time');
    const extractStart = Date.now();
    await extractWithNativeTar(path.resolve(tempPath, tarGzName), extractPath);
    const extractEnd = Date.now();
    console.log(
      `=> Meteor extracted in ${(extractEnd - extractStart) / 1000}s`
    );
    await setup();
  });

  dl.start();
}

function decompress() {
  const start = Date.now();
  const decompressProgress = new cliProgress.SingleBar(
    {
      format: 'Decompressing |{bar}| {percentage}%',
      clearOnComplete: true,
    },
    cliProgress.Presets.shades_classic
  );
  decompressProgress.start(100, 0);

  const myStream = Seven.extract(path.resolve(tempPath, tarGzName), tempPath, {
    $progress: true,
    $bin: sevenBin.path7za,
  });
  myStream.on('progress', function(progress) {
    decompressProgress.update(progress.percent);
  });

  myStream.on('end', function() {
    decompressProgress.update(100);
    decompressProgress.stop();
    const end = Date.now();
    console.log(`=> Meteor Decompressed in ${(end - start) / 1000}s`);
    extract();
  });
}

async function extract() {
  const start = Date.now();
  fs.writeFileSync(startedPath, 'Meteor install started');

  const decompressProgress = new cliProgress.SingleBar(
    {
      format: 'Extracting |{bar}| {percentage}% - {fileCount} files completed',
      clearOnComplete: true,
    },
    cliProgress.Presets.shades_classic
  );
  decompressProgress.start(100, 0, {
    fileCount: 0,
  });

  let tarPath = path.resolve(tempPath, tarName);
  // 7Zip is ~15% faster, but doesn't work when the user doesn't have permission to create symlinks
  // TODO: we could always use 7zip if we have it ignore the symlinks, and then manually create them as
  // is done in extractWithTar
  if (canCreateSymlinks) {
    await extractWith7Zip(tarPath, extractPath, ({ percent, fileCount }) => {
      decompressProgress.update(percent, { fileCount });
    });
  } else {
    await extractWithTar(tarPath, extractPath, ({ percent, fileCount }) => {
      decompressProgress.update(percent, { fileCount });
    });
  }

  decompressProgress.stop();
  const end = Date.now();
  console.log(`=> Meteor Extracted ${(end - start) / 1000}s`);
  await setup();
}
async function setup() {
  fs.unlinkSync(startedPath);
  if (shouldSetupExecPath()) {
    await setupExecPath();
  }
  await fixOwnership();
  showGettingStarted();
}
async function setupExecPath() {
  if (isWindows()) {
    //set for the current session and beyond
    child_process.execSync(`setx path "${meteorPath}/;%path%`);
    return;
  }
  const exportCommand = `export PATH=${meteorPath}:$PATH`;

  const appendPathToFile = async file => {
    return fsPromises.appendFile(`${rootPath}/${file}`, `${exportCommand}\n`);
  };

  if (process.env.SHELL && process.env.SHELL.includes('zsh')) {
    await appendPathToFile('.zshrc');
  } else {
    await appendPathToFile('.bashrc');
    await appendPathToFile('.bash_profile');
  }
}
async function fixOwnership() {
  if (!isWindows() && isSudo()) {
    // if we identified sudo is being used, we need to change the ownership of the meteorpath folder
    child_process.execSync(`chown -R ${sudoUser} "${meteorPath}"`);
  }
}

function showGettingStarted() {
  const exportCommand = `export PATH=${meteorPath}:$PATH`;

  const runCommand = isWindows()
    ? `set path "${meteorPath}/;%path%`
    : exportCommand;
  const message = `
***************************************

Meteor has been installed!

To get started fast:

  $ meteor create ~/my_cool_app
  $ cd ~/my_cool_app
  $ meteor

Or see the docs at:

  docs.meteor.com

Deploy and host your app with Cloud:

  www.meteor.com/cloud

***************************************
You might need to open a new terminal window to have access to the meteor command, or run this in your terminal:

${runCommand}

For adding it immediately to your path.
***************************************
  `;

  console.log(message);
}


====================================================================
For the license for Meteor itself, see LICENSE.txt in the root of
the repository.  This file contains the licenses for externally
maintained libraries.
====================================================================

----------
commonmark: https://github.com/jgm/commonmark.js
----------

Copyright (c) 2014, John MacFarlane

All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

---

lib/encode.js and lib/decode.js come from
https://github.com/markdown-it/mdurl

Copyright (c) 2015 Vitaly Puzrin, Alex Kocharin.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

---

lib/normalize-reference.js is a slightly modified version of
https://github.com/dmoscrop/fold-case:

Copyright Mathias Bynens <https://mathiasbynens.be/>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

---

lib/from-code-point.js is derived from a polyfill
Copyright Mathias Bynens <http://mathiasbynens.be/>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

---

bench/samples/*.md:

With the exception of `bench/samples/README.md`, the samples in
`bench/samples` are taken from https://github.com/markdown-it/markdown-it.

Copyright (c) 2014 Vitaly Puzrin, Alex Kocharin.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

---

The CommonMark spec (spec.txt) in test/ is

Copyright (C) 2014-15 John MacFarlane

Released under the Creative Commons CC-BY-SA 4.0 license:
<http://creativecommons.org/licenses/by-sa/4.0/>.


// Constructor of Heap
// - comparator - Function - given two items returns a number
// - options:
//   - initData - Array - Optional - the initial data in a format:
//        Object:
//          - id - String - unique id of the item
//          - value - Any - the data value
//      each value is retained
//   - IdMap - Constructor - Optional - custom IdMap class to store id->index
//       mappings internally. Standard IdMap is used by default.
export class MaxHeap {
  constructor(comparator, options = {}) {
    if (typeof comparator !== 'function') {
      throw new Error('Passed comparator is invalid, should be a comparison function');
    }

    // a C-style comparator that is given two values and returns a number,
    // negative if the first value is less than the second, positive if the second
    // value is greater than the first and zero if they are equal.
    this._comparator = comparator;

    if (! options.IdMap) {
      options.IdMap = IdMap;
    }

    // _heapIdx maps an id to an index in the Heap array the corresponding value
    // is located on.
    this._heapIdx = new options.IdMap;

    // The Heap data-structure implemented as a 0-based contiguous array where
    // every item on index idx is a node in a complete binary tree. Every node can
    // have children on indexes idx*2+1 and idx*2+2, except for the leaves. Every
    // node has a parent on index (idx-1)/2;
    this._heap = [];

    // If the initial array is passed, we can build the heap in linear time
    // complexity (O(N)) compared to linearithmic time complexity (O(nlogn)) if
    // we push elements one by one.
    if (Array.isArray(options.initData)) {
      this._initFromData(options.initData);
    }
  }

  // Builds a new heap in-place in linear time based on passed data
  _initFromData(data) {
    this._heap = data.map(({ id, value }) => ({ id, value }));

    data.forEach(({ id }, i) => this._heapIdx.set(id, i));

    if (! data.length) {
      return;
    }

    // start from the first non-leaf - the parent of the last leaf
    for (let i = parentIdx(data.length - 1); i >= 0; i--) {
      this._downHeap(i);
    }
  }

  _downHeap(idx) {
    while (leftChildIdx(idx) < this.size()) {
      const left = leftChildIdx(idx);
      const right = rightChildIdx(idx);
      let largest = idx;

      if (left < this.size()) {
        largest = this._maxIndex(largest, left);
      }

      if (right < this.size()) {
        largest = this._maxIndex(largest, right);
      }

      if (largest === idx) {
        break;
      }

      this._swap(largest, idx);
      idx = largest;
    }
  }

  _upHeap(idx) {
    while (idx > 0) {
      const parent = parentIdx(idx);
      if (this._maxIndex(parent, idx) === idx) {
        this._swap(parent, idx)
        idx = parent;
      } else {
        break;
      }
    }
  }

  _maxIndex(idxA, idxB) {
    const valueA = this._get(idxA);
    const valueB = this._get(idxB);
    return this._comparator(valueA, valueB) >= 0 ? idxA : idxB;
  }

  // Internal: gets raw data object placed on idxth place in heap
  _get(idx) {
    return this._heap[idx].value;
  }

  _swap(idxA, idxB) {
    const recA = this._heap[idxA];
    const recB = this._heap[idxB];

    this._heapIdx.set(recA.id, idxB);
    this._heapIdx.set(recB.id, idxA);

    this._heap[idxA] = recB;
    this._heap[idxB] = recA;
  }

  get(id) {
    return this.has(id) ?
      this._get(this._heapIdx.get(id)) :
      null;
  }

  set(id, value) {
    if (this.has(id)) {
      if (this.get(id) === value) {
        return;
      }

      const idx = this._heapIdx.get(id);
      this._heap[idx].value = value;

      // Fix the new value's position
      // Either bubble new value up if it is greater than its parent
      this._upHeap(idx);
      // or bubble it down if it is smaller than one of its children
      this._downHeap(idx);
    } else {
      this._heapIdx.set(id, this._heap.length);
      this._heap.push({ id, value });
      this._upHeap(this._heap.length - 1);
    }
  }

  remove(id) {
    if (this.has(id)) {
      const last = this._heap.length - 1;
      const idx = this._heapIdx.get(id);

      if (idx !== last) {
        this._swap(idx, last);
        this._heap.pop();
        this._heapIdx.remove(id);

        // Fix the swapped value's position
        this._upHeap(idx);
        this._downHeap(idx);
      } else {
        this._heap.pop();
        this._heapIdx.remove(id);
      }
    }
  }

  has(id) {
    return this._heapIdx.has(id);
  }

  empty() {
    return !this.size();
  }

  clear() {
    this._heap = [];
    this._heapIdx.clear();
  }

  // iterate over values in no particular order
  forEach(iterator) {
    this._heap.forEach(obj => iterator(obj.value, obj.id));
  }

  size() {
    return this._heap.length;
  }

  setDefault(id, def) {
    if (this.has(id)) {
      return this.get(id);
    }

    this.set(id, def);
    return def;
  }

  clone() {
    const clone = new MaxHeap(this._comparator, this._heap);
    return clone;
  }

  maxElementId() {
    return this.size() ? this._heap[0].id : null;
  }

  _selfCheck() {
    for (let i = 1; i < this._heap.length; i++) {
      if (this._maxIndex(parentIdx(i), i) !== parentIdx(i)) {
          throw new Error(`An item with id ${this._heap[i].id}` +
                          " has a parent younger than it: " +
                          this._heap[parentIdx(i)].id);
      }
    }
  }
}

const leftChildIdx = i => i * 2 + 1;
const rightChildIdx = i => i * 2 + 2;
const parentIdx = i => (i - 1) >> 1;


# This workflow will triage pull requests and apply a label based on the
# paths that are modified in the pull request.
#
# To use this workflow, you will need to set up a .github/labeler.yml
# file with configuration.  For more information, see:
# https://github.com/actions/labeler

name: Labeler
on:
  - pull_request_target

jobs:
  label:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/labeler@v3
      with:
        repo-token: "${{ secrets.GITHUB_TOKEN }}"


keep keep keep keep keep replace replace replace replace keep

Install Meteor


// XXX COMPAT WITH 0.8.3
// This package is replaced by the use of bcrypt in accounts-password,
// but we are leaving in some of the code to allow existing user
// databases to be upgraded from SRP to bcrypt.

Package.describe({
  summary: "Library for Secure Remote Password (SRP) exchanges",
  version: "1.1.0",
  deprecated: true,
  documentation: 'README.md'
});

Package.onUse(function (api) {
  api.use([
    'ecmascript',
    'random',
    'check',
    'sha'
  ], ['client', 'server']);
  api.export('SRP');
  api.mainModule('srp.js');
});

Package.onTest(function (api) {
  api.use(['ecmascript', 'tinytest']);
  api.use('srp', ['client', 'server']);
  api.addFiles(['srp_tests.js'], ['client', 'server']);
});


// Based on json2.js from https://github.com/douglascrockford/JSON-js
//
//    json2.js
//    2012-10-08
//
//    Public Domain.
//
//    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

function quote(string) {
  return JSON.stringify(string);
}

const str = (key, holder, singleIndent, outerIndent, canonical) => {
  const value = holder[key];

  // What happens next depends on the value's type.
  switch (typeof value) {
  case 'string':
    return quote(value);
  case 'number':
    // JSON numbers must be finite. Encode non-finite numbers as null.
    return isFinite(value) ? String(value) : 'null';
  case 'boolean':
    return String(value);
  // If the type is 'object', we might be dealing with an object or an array or
  // null.
  case 'object': {
    // Due to a specification blunder in ECMAScript, typeof null is 'object',
    // so watch out for that case.
    if (!value) {
      return 'null';
    }
    // Make an array to hold the partial results of stringifying this object
    // value.
    const innerIndent = outerIndent + singleIndent;
    const partial = [];
    let v;

    // Is the value an array?
    if (Array.isArray(value) || ({}).hasOwnProperty.call(value, 'callee')) {
      // The value is an array. Stringify every element. Use null as a
      // placeholder for non-JSON values.
      const length = value.length;
      for (let i = 0; i < length; i += 1) {
        partial[i] =
          str(i, value, singleIndent, innerIndent, canonical) || 'null';
      }

      // Join all of the elements together, separated with commas, and wrap
      // them in brackets.
      if (partial.length === 0) {
        v = '[]';
      } else if (innerIndent) {
        v = '[\n' +
          innerIndent +
          partial.join(',\n' +
          innerIndent) +
          '\n' +
          outerIndent +
          ']';
      } else {
        v = '[' + partial.join(',') + ']';
      }
      return v;
    }

    // Iterate through all of the keys in the object.
    let keys = Object.keys(value);
    if (canonical) {
      keys = keys.sort();
    }
    keys.forEach(k => {
      v = str(k, value, singleIndent, innerIndent, canonical);
      if (v) {
        partial.push(quote(k) + (innerIndent ? ': ' : ':') + v);
      }
    });

    // Join all of the member texts together, separated with commas,
    // and wrap them in braces.
    if (partial.length === 0) {
      v = '{}';
    } else if (innerIndent) {
      v = '{\n' +
        innerIndent +
        partial.join(',\n' +
        innerIndent) +
        '\n' +
        outerIndent +
        '}';
    } else {
      v = '{' + partial.join(',') + '}';
    }
    return v;
  }

  default: // Do nothing
  }
};

// If the JSON object does not yet have a stringify method, give it one.
const canonicalStringify = (value, options) => {
  // Make a fake root object containing our value under the key of ''.
  // Return the result of stringifying the value.
  const allOptions = Object.assign({
    indent: '',
    canonical: false,
  }, options);
  if (allOptions.indent === true) {
    allOptions.indent = '  ';
  } else if (typeof allOptions.indent === 'number') {
    let newIndent = '';
    for (let i = 0; i < allOptions.indent; i++) {
      newIndent += ' ';
    }
    allOptions.indent = newIndent;
  }
  return str('', {'': value}, allOptions.indent, '', allOptions.canonical);
};

export default canonicalStringify;


keep replace replace replace keep keep keep

Install Meteor


struct AssetManifest {
  struct Entry {
    let filePath: String
    let URLPath: String
    let fileType: String
    let cacheable: Bool
    let hash: String?
    let sourceMapPath: String?
    let sourceMapURLPath: String?
  }

  let version: String
  let cordovaCompatibilityVersion: String
  var entries: [Entry]

  init(fileURL: URL) throws {
    try self.init(data: try Data(contentsOf: fileURL, options: []))
  }

  init(data: Data) throws {
    let JSON: JSONObject
    do {
      JSON = try JSONSerialization.jsonObject(with: data, options: []) as! JSONObject
    } catch {
      throw WebAppError.invalidAssetManifest(reason: "Error parsing asset manifest", underlyingError: error)
    }

    if let format = JSON["format"] as? String, format != "web-program-pre1" {
      throw WebAppError.invalidAssetManifest(reason: "The asset manifest format is incompatible: \(format)", underlyingError: nil)
    }

    guard let version = JSON["version"] as? String else {
      throw WebAppError.invalidAssetManifest(reason: "Asset manifest does not have a version", underlyingError: nil)
    }

    self.version = version

    guard let cordovaCompatibilityVersions = JSON["cordovaCompatibilityVersions"] as? JSONObject,
      let cordovaCompatibilityVersion = cordovaCompatibilityVersions["ios"] as? String else {
      throw WebAppError.invalidAssetManifest(reason: "Asset manifest does not have a cordovaCompatibilityVersion", underlyingError: nil)
    }

    self.cordovaCompatibilityVersion = cordovaCompatibilityVersion

    let entriesJSON = JSON["manifest"] as? [JSONObject] ?? []
    entries = []
    for entryJSON in entriesJSON {
      if entryJSON["where"] as? String != "client" { continue }

      if let URLPath = entryJSON["url"] as? String,
        let filePath = entryJSON["path"] as? String,
        let fileType = entryJSON["type"] as? String,
        let hash = entryJSON["hash"] as? String,
        let cacheable = entryJSON["cacheable"] as? Bool {
          let sourceMapPath = entryJSON["sourceMap"] as? String
          let sourceMapURLPath = entryJSON["sourceMapUrl"] as? String

          let entry = Entry(filePath: filePath, URLPath: URLPath,
            fileType: fileType, cacheable: cacheable, hash: hash,
            sourceMapPath: sourceMapPath, sourceMapURLPath: sourceMapURLPath)
          entries.append(entry)
      }
    }
  }
}


},
"bin": {
"meteor-installer": "cli.js"
}
}

Install Meteor


import { EJSON } from './ejson';

class Address {
  constructor(city, state) {
    this.city = city;
    this.state = state;
  }

  typeName() {
    return 'Address';
  }

  toJSONValue() {
    return {
      city: this.city,
      state: this.state,
    };
  }
}

EJSON.addType('Address', value => new Address(value.city, value.state));

class Person {
  constructor(name, dob, address) {
    this.name = name;
    this.dob = dob;
    this.address = address;
  }

  typeName() {
    return 'Person';
  }

  toJSONValue() {
    return {
      name: this.name,
      dob: EJSON.toJSONValue(this.dob),
      address: EJSON.toJSONValue(this.address),
    };
  }
}

EJSON.addType(
  'Person',
  value => new Person(
    value.name,
    EJSON.fromJSONValue(value.dob),
    EJSON.fromJSONValue(value.address)
  )
);

class Holder {
  constructor(content) {
    this.content = content;
  }

  typeName() {
    return 'Holder';
  }

  toJSONValue() {
    return this.content;
  }
}

EJSON.addType('Holder', value => new Holder(value));

const EJSONTest = {
  Address,
  Person,
  Holder,
};

export default EJSONTest;


import { ClientVersions } from "./client_versions.js";

var autoupdateVersionsCordova =
  __meteor_runtime_config__.autoupdate.versions["web.cordova"] || {
    version: "unknown"
  };

export const Autoupdate = {};

// Stores acceptable client versions.
const clientVersions = new ClientVersions();

// Used by hot-module-replacement
Autoupdate._clientVersions = clientVersions;

Meteor.connection.registerStore(
  "meteor_autoupdate_clientVersions",
  clientVersions.createStore()
);

Autoupdate.newClientAvailable = function () {
  return clientVersions.newClientAvailable(
    "web.cordova",
    ["version"],
    autoupdateVersionsCordova
  );
};

var retry = new Retry({
  // Unlike the stream reconnect use of Retry, which we want to be instant
  // in normal operation, this is a wacky failure. We don't want to retry
  // right away, we can start slowly.
  //
  // A better way than timeconstants here might be to use the knowledge
  // of when we reconnect to help trigger these retries. Typically, the
  // server fixing code will result in a restart and reconnect, but
  // potentially the subscription could have a transient error.
  minCount: 0, // don't do any immediate retries
  baseTimeout: 30*1000 // start with 30s
});

let failures = 0;

Autoupdate._retrySubscription = () => {
  const { appId } = __meteor_runtime_config__;

  Meteor.subscribe("meteor_autoupdate_clientVersions", appId, {
    onError(error) {
      console.log("autoupdate subscription failed:", error);
      failures++;
      retry.retryLater(failures, function() {
        // Just retry making the subscription, don't reload the whole
        // page. While reloading would catch more cases (for example,
        // the server went back a version and is now doing old-style hot
        // code push), it would also be more prone to reload loops,
        // which look really bad to the user. Just retrying the
        // subscription over DDP means it is at least possible to fix by
        // updating the server.
        Autoupdate._retrySubscription();
      });
    },

    onReady() {
      if (Package.reload) {
        function checkNewVersionDocument(doc) {
          if (doc.version !== autoupdateVersionsCordova.version) {
            newVersionAvailable();
          }
        }

        clientVersions.watch(checkNewVersionDocument, {
          filter: "web.cordova"
        });
      }
    }
  });
};

Meteor.startup(() => {
  WebAppLocalServer.onNewVersionReady(() => {
    if (Package.reload) {
      Package.reload.Reload._reload();
    }
  });

  Autoupdate._retrySubscription();
});

function newVersionAvailable() {
  WebAppLocalServer.checkForUpdates();
}


if (process.env.MONGO_URL === 'no-mongo-server') {
  Meteor._debug('Note: Restart Meteor to start the MongoDB server.');
}