<commit_before>(function ($) {

module("Dataset");

test('new Dataset', function () {
  var datasetId = 'test-dataset';
  var metadata = {
    title: 'My Test Dataset'
    , name: '1-my-test-dataset'
    , id: datasetId
  };
  var indata = {
      headers: ['x', 'y', 'z']
    , rows: [
        {id: 0, x: 1, y: 2, z: 3}
      , {id: 1, x: 2, y: 4, z: 6}
      , {id: 2, x: 3, y: 6, z: 9}
      , {id: 3, x: 4, y: 8, z: 12}
      , {id: 4, x: 5, y: 10, z: 15}
      , {id: 5, x: 6, y: 12, z: 18}
    ]
  };
  // this is all rather artificial here but would make more sense with more complex backend
  backend = new recline.Model.BackendMemory({
    metadata: metadata,
    data: indata
    });
  recline.Model.setBackend(backend);
  var dataset = backend.getDataset(datasetId);
  expect(6);
  dataset.fetch().then(function(dataset) {
    equal(dataset.get('name'), metadata.name);
    equal(dataset.get('headers'), indata.headers);
    equal(dataset.getLength(), 6);
    dataset.getRows(4, 2).then(function(documentList) {
      deepEqual(indata.rows[2], documentList.models[0].toJSON());
    });
    dataset.getRows().then(function(docList) {
      equal(docList.length, Math.min(10, indata.rows.length));
      deepEqual(docList.models[0].toJSON(), indata.rows[0]);
      });
  });
});

// TODO: move to fixtures
var webstoreSchema = {
  "count": 3,
  "data": [
    {
      "name": "__id__",
      "type": "integer",
      "values_url": "/rufuspollock/demo/data/distinct/__id__"
    },
    {
      "name": "date",
      "type": "text",
      "values_url": "/rufuspollock/demo/data/distinct/date"
    },
    {
      "name": "geometry",
      "type": "text",
      "values_url": "/rufuspollock/demo/data/distinct/geometry"
    },
    {
      "name": "amount",
      "type": "text",
      "values_url": "/rufuspollock/demo/data/distinct/amount"
    }
  ],
  "fields": [
    {
      "name": "type"
    },
    {
      "name": "name"
    },
    {
      "name": "values_url"
    }
  ]
};

webstoreData = {
  "count": null,
  "data": [
    {
      "__id__": 1,
      "amount": "100",
      "date": "2009-01-01",
      "geometry": null
    },
    {
      "__id__": 2,
      "amount": "200",
      "date": "2010-01-01",
      "geometry": null
    },
    {
      "__id__": 3,
      "amount": "300",
      "date": "2011-01-01",
      "geometry": null
    }
  ],
  "fields": [
    {
      "name": "__id__"
    },
    {
      "name": "date"
    },
    {
      "name": "geometry"
    },
    {
      "name": "amount"
    }
  ]
};

test('Webstore Backend', function() {
  stop();
  var backend = new recline.Model.BackendWebstore({
    url: 'http://webstore.test.ckan.org/rufuspollock/demo/data'
  });
  recline.Model.setBackend(backend);
  dataset = backend.getDataset();

  var stub = sinon.stub($, 'ajax', function(options) {
    return {
      then: function(callback) {
        callback(webstoreSchema);
      }
    }
  });

  dataset.fetch().then(function(dataset) {
    deepEqual(['__id__', 'date', 'geometry', 'amount'], dataset.get('headers'));
    equal(3, dataset.rowCount)
    // restore mocked method
    $.ajax.restore();
    dataset.getRows().then(function(docList) {
      start();
      equal(3, docList.length)
      equal("2009-01-01", docList.models[0].get('date'));
    });
  });
});

})(this.jQuery);
<commit_msg>[test/model][s]: update webstore backend test to have ajax fully mocked so tests work fully when offline.<commit_after>(function ($) {

module("Dataset");

test('new Dataset', function () {
  var datasetId = 'test-dataset';
  var metadata = {
    title: 'My Test Dataset'
    , name: '1-my-test-dataset'
    , id: datasetId
  };
  var indata = {
      headers: ['x', 'y', 'z']
    , rows: [
        {id: 0, x: 1, y: 2, z: 3}
      , {id: 1, x: 2, y: 4, z: 6}
      , {id: 2, x: 3, y: 6, z: 9}
      , {id: 3, x: 4, y: 8, z: 12}
      , {id: 4, x: 5, y: 10, z: 15}
      , {id: 5, x: 6, y: 12, z: 18}
    ]
  };
  // this is all rather artificial here but would make more sense with more complex backend
  backend = new recline.Model.BackendMemory({
    metadata: metadata,
    data: indata
    });
  recline.Model.setBackend(backend);
  var dataset = backend.getDataset(datasetId);
  expect(6);
  dataset.fetch().then(function(dataset) {
    equal(dataset.get('name'), metadata.name);
    equal(dataset.get('headers'), indata.headers);
    equal(dataset.getLength(), 6);
    dataset.getRows(4, 2).then(function(documentList) {
      deepEqual(indata.rows[2], documentList.models[0].toJSON());
    });
    dataset.getRows().then(function(docList) {
      equal(docList.length, Math.min(10, indata.rows.length));
      deepEqual(docList.models[0].toJSON(), indata.rows[0]);
      });
  });
});

// TODO: move to fixtures
var webstoreSchema = {
  "count": 3,
  "data": [
    {
      "name": "__id__",
      "type": "integer",
      "values_url": "/rufuspollock/demo/data/distinct/__id__"
    },
    {
      "name": "date",
      "type": "text",
      "values_url": "/rufuspollock/demo/data/distinct/date"
    },
    {
      "name": "geometry",
      "type": "text",
      "values_url": "/rufuspollock/demo/data/distinct/geometry"
    },
    {
      "name": "amount",
      "type": "text",
      "values_url": "/rufuspollock/demo/data/distinct/amount"
    }
  ],
  "fields": [
    {
      "name": "type"
    },
    {
      "name": "name"
    },
    {
      "name": "values_url"
    }
  ]
};

webstoreData = {
  "count": null,
  "data": [
    {
      "__id__": 1,
      "amount": "100",
      "date": "2009-01-01",
      "geometry": null
    },
    {
      "__id__": 2,
      "amount": "200",
      "date": "2010-01-01",
      "geometry": null
    },
    {
      "__id__": 3,
      "amount": "300",
      "date": "2011-01-01",
      "geometry": null
    }
  ],
  "fields": [
    {
      "name": "__id__"
    },
    {
      "name": "date"
    },
    {
      "name": "geometry"
    },
    {
      "name": "amount"
    }
  ]
};

test('Webstore Backend', function() {
  var backend = new recline.Model.BackendWebstore({
    url: 'http://webstore.test.ckan.org/rufuspollock/demo/data'
  });
  recline.Model.setBackend(backend);
  dataset = backend.getDataset();

  var stub = sinon.stub($, 'ajax', function(options) {
    if (options.url.indexOf('schema.json') != -1) {
      return {
        then: function(callback) {
          callback(webstoreSchema);
        }
      }
    } else {
      console.log('here');
      return {
        then: function(callback) {
          callback(webstoreData);
        }
      }
    }
  });

  dataset.fetch().then(function(dataset) {
    deepEqual(['__id__', 'date', 'geometry', 'amount'], dataset.get('headers'));
    equal(3, dataset.rowCount)
    dataset.getRows().then(function(docList) {
      equal(3, docList.length)
      equal("2009-01-01", docList.models[0].get('date'));
    });
  });
});

})(this.jQuery);
<|endoftext|>


<commit_before>define(function(require) {

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');
  var AppView = require('views/app');
  var docs = require('collections/docs');
  var cache = require('utils/cache');
  var settings = require('models/settings');
  var router = require('utils/router');
  var remoteStorageDocuments = require('remotestorage-documents');

  function litewrite() {

    initRemotestorage();

    settings
      .on('change:openDocId', saveDocAndChange)
      .on('change:openDocId', setWindowTitle)
      .on('change:openDocId', router.setUrl, router)
      .on('change:openDocId', docs.deleteEmpty, docs);

    docs
      .on('change:title', router.setUrl, router)
      .on('change:title', setWindowTitle)
      .on('add', updateOpenDocId);

    fetch();

    $.when(settings.loading, docs.loading)
      .done(loadCache);

    cache.loading.done(setWindowTitle, startHistory);

    //Load on DOM-ready
    $(function() {
      new AppView();
      new FastClick(document.body);
    });

  }

  function initRemotestorage() {
    var origHash = document.location.hash;

    remoteStorage.on('ready', fetch);

    remoteStorage.on('disconnect', function() {
      docs.reset().addNew();
    });

    remoteStorage.claimAccess('documents', 'rw').then(function() {
      remoteStorage.documents.init();
      remoteStorage.displayWidget('remotestorage-connect');

      remoteStorageDocuments.onChange('notes', function(event) {
        if(event.origin !== 'window') {
          fetch();
        }
      });

      setTimeout(function() {
        var md = origHash.match(/access_token=([^&]+)/);
        if(md && (! remoteStorage.getBearerToken())) {
          // backbone stole our access token
          remoteStorage.setBearerToken(md[1]);
        }
      }, 0);

    });
  }

  function loadCache() {
    ensureOpenDocId();
    setOpenDoc();
    cache.loading.resolve();
  }

  function ensureOpenDocId() {
    if ( _.isUndefined(settings.get('openDocId')) ) {
      settings.save('openDocId', docs.first().id);
    }
  }

  function saveDocAndChange() {
    if (cache.openDoc) cache.openDoc.save();
    setOpenDoc();
  }

  function setOpenDoc() {
    cache.openDoc = docs.get( settings.get('openDocId') );
  }

  function setWindowTitle() {
    document.title = (
      cache.openDoc ? cache.openDoc.get('title') : null
    ) || 'Litewrite';
  }

  function updateOpenDocId(doc) {
    settings.save('openDocId', doc.id);
  }

  function startHistory() {
    Backbone.history.start();
  }

  fetch = _.debounce(function() {
    docs.fetch({
      success: function() {
        docs.trigger('fetch');
        setOpenDoc();
        if (docs.isEmpty()) docs.addNew();
        docs.loading.resolve();
      }
    });
  }, 300);

  return litewrite;
});
<commit_msg>not necessary to wait for dom ready sience we include js on bottom of body tag<commit_after>define(function(require) {

  var $ = require('jquery');
  var _ = require('underscore');
  var Backbone = require('backbone');
  var AppView = require('views/app');
  var docs = require('collections/docs');
  var cache = require('utils/cache');
  var settings = require('models/settings');
  var router = require('utils/router');
  var remoteStorageDocuments = require('remotestorage-documents');

  function litewrite() {

    initRemotestorage();

    settings
      .on('change:openDocId', saveDocAndChange)
      .on('change:openDocId', setWindowTitle)
      .on('change:openDocId', router.setUrl, router)
      .on('change:openDocId', docs.deleteEmpty, docs);

    docs
      .on('change:title', router.setUrl, router)
      .on('change:title', setWindowTitle)
      .on('add', updateOpenDocId);

    fetch();

    $.when(settings.loading, docs.loading)
      .done(loadCache);

    cache.loading.done(setWindowTitle, startHistory);

    new AppView();
    new FastClick(document.body);

  }

  function initRemotestorage() {
    var origHash = document.location.hash;

    remoteStorage.on('ready', fetch);

    remoteStorage.on('disconnect', function() {
      docs.reset().addNew();
    });

    remoteStorage.claimAccess('documents', 'rw').then(function() {
      remoteStorage.documents.init();
      remoteStorage.displayWidget('remotestorage-connect');

      remoteStorageDocuments.onChange('notes', function(event) {
        if(event.origin !== 'window') {
          fetch();
        }
      });

      setTimeout(function() {
        var md = origHash.match(/access_token=([^&]+)/);
        if(md && (! remoteStorage.getBearerToken())) {
          // backbone stole our access token
          remoteStorage.setBearerToken(md[1]);
        }
      }, 0);

    });
  }

  function loadCache() {
    ensureOpenDocId();
    setOpenDoc();
    cache.loading.resolve();
  }

  function ensureOpenDocId() {
    if ( _.isUndefined(settings.get('openDocId')) ) {
      settings.save('openDocId', docs.first().id);
    }
  }

  function saveDocAndChange() {
    if (cache.openDoc) cache.openDoc.save();
    setOpenDoc();
  }

  function setOpenDoc() {
    cache.openDoc = docs.get( settings.get('openDocId') );
  }

  function setWindowTitle() {
    document.title = (
      cache.openDoc ? cache.openDoc.get('title') : null
    ) || 'Litewrite';
  }

  function updateOpenDocId(doc) {
    settings.save('openDocId', doc.id);
  }

  function startHistory() {
    Backbone.history.start();
  }

  fetch = _.debounce(function() {
    docs.fetch({
      success: function() {
        docs.trigger('fetch');
        setOpenDoc();
        if (docs.isEmpty()) docs.addNew();
        docs.loading.resolve();
      }
    });
  }, 300);

  return litewrite;
});
<|endoftext|>


<commit_before>var fs = require('fs');
var assert = require('assert');
var util = require('util');
var Carmen = require('..');
var S3 = require('tilelive-s3');
var index = require('../lib/index');
var feature = require('../lib/util/feature');
var memFixture = require('./fixtures/mem.json');
var mem = require('../lib/api-mem');
var UPDATE = process.env.UPDATE;

describe('index', function() {
    var east = new S3(__dirname + '/fixtures/01-ne.country.east.s3');
    var west = new S3(__dirname + '/fixtures/01-ne.country.west.s3');
//    var eastSource = new mem(null, function() {});
//    var westSource = new mem(null, function() {});
//    eastSource.getIndexableDocs = function(pointer, callback) {
//        mem.prototype.getIndexableDocs.call(this, pointer, function(err, docs, pointer) {
//            if (err) return callback(err);
//            docs = docs.filter(function(d) { return d._center[0] >= 0 });
//            return callback(null, docs, pointer);
//        });
//    };
//    westSource.getIndexableDocs = function(pointer, callback) {
//        mem.prototype.getIndexableDocs.call(this, pointer, function(err, docs, pointer) {
//            if (err) return callback(err);
//            docs = docs.filter(function(d) { return d._center[0] < 0 });
//            return callback(null, docs, pointer);
//        });
//    };
//    it.skip('indexes east', function(done) {
//        this.timeout(60e3);
//        var c = new Carmen({ east:east, eastSource:eastSource });
//        c.index(eastSource, east, {}, function(err) {
//            assert.ifError(err);
//            feature.getAllFeatures(east, function(err, features) {
//                assert.ifError(err);
//                assert.equal(features.length, 164);
//                done();
//            });
//        });
//    });
//    it.skip('indexes west', function(done) {
//        this.timeout(60e3);
//        var c = new Carmen({ west:west, westSource:westSource });
//        c.index(westSource, west, {}, function(err) {
//            assert.ifError(err);
//            feature.getAllFeatures(west, function(err, features) {
//                assert.ifError(err);
//                assert.equal(features.length, 89);
//                done();
//            });
//        });
//    });
    it('queries east as country', function(done) {
        var c = new Carmen({
            east: east,
            west: west
        });
        c.geocode('china', {}, function(err, res) {
            assert.ifError(err);
            assert.equal(res.features.length, 1);
            assert.equal(res.features[0].id, 'country.3');
            done();
        });
    });
    it('queries west as country', function(done) {
        var c = new Carmen({
            east: east,
            west: west
        });
        c.geocode('brazil', {}, function(err, res) {
            assert.ifError(err);
            assert.equal(res.features.length, 1);
            assert.equal(res.features[0].id, 'country.7');
            done();
        });
    });
});

<commit_msg>Tapify named.test<commit_after>var fs = require('fs');
var util = require('util');
var Carmen = require('..');
var S3 = require('tilelive-s3');
var index = require('../lib/index');
var feature = require('../lib/util/feature');
var memFixture = require('./fixtures/mem.json');
var mem = require('../lib/api-mem');
var UPDATE = process.env.UPDATE;
var test = require('tape');

test('index', function(t) {
    var east = new S3(__dirname + '/fixtures/01-ne.country.east.s3', function(err, source) {
        if (err) t.fail();
    });
    var west = new S3(__dirname + '/fixtures/01-ne.country.west.s3', function(err, source) {
        if (err) t.fail();
    });
    var eastSource = new mem(null, function() {});
    var westSource = new mem(null, function() {});
    eastSource.getIndexableDocs = function(pointer, callback) {
        mem.prototype.getIndexableDocs.call(this, pointer, function(err, docs, pointer) {
            if (err) return callback(err);
            docs = docs.filter(function(d) { return d._center[0] >= 0 });
            return callback(null, docs, pointer);
        });
    };
    westSource.getIndexableDocs = function(pointer, callback) {
        mem.prototype.getIndexableDocs.call(this, pointer, function(err, docs, pointer) {
            if (err) return callback(err);
            docs = docs.filter(function(d) { return d._center[0] < 0 });
            return callback(null, docs, pointer);
        });
    };
    t.skip('indexes east', function(q) {
        this.timeout(60e3);
        var c = new Carmen({ east:east, eastSource:eastSource });
        c.index(eastSource, east, {}, function(err) {
            q.ifError(err);
            feature.getAllFeatures(east, function(err, features) {
                q.ifError(err);
                q.equal(features.length, 164);
                q.end();
            });
        });
    });
    t.skip('indexes west', function(q) {
        this.timeout(60e3);
        var c = new Carmen({ west:west, westSource:westSource });
        c.index(westSource, west, {}, function(err) {
            q.ifError(err);
            feature.getAllFeatures(west, function(err, features) {
                q.ifError(err);
                q.equal(features.length, 89);
                q.end();
            });
        });
    });
    t.test('queries east as country', function(q) {
        var c = new Carmen({
            east: east,
            west: west
        });
        c.geocode('china', {}, function(err, res) {
            q.ifError(err);
            q.equal(res.features.length, 1);
            q.equal(res.features[0].id, 'country.3');
            q.end();
        });
    });
    t.test('queries west as country', function(q) {
        var c = new Carmen({
            east: east,
            west: west
        });
        c.geocode('brazil', {}, function(err, res) {
            q.ifError(err);
            q.equal(res.features.length, 1);
            q.equal(res.features[0].id, 'country.7');
            q.end();
        });
    });
    t.end();
});

<|endoftext|>


<commit_before>import { createOption, linkSelects } from '../util.js';
import { controllers } from './Controller.js';
import { simVars } from '../simVars.js';

/**      Contents
 *  1. Initialization block
 *  2. Getters block
 *  3. Setters block
 *
 */
export class TimeSeriesButton extends HTMLElement {
    /** ===== Initialization block ===== */
    constructor(dataType = 'continuous') {
        super();
        this.innerHTML = `

                    start time:
                    <select class='timeseries-select' id='startDate'></select>

                    end time:
                    <select class='timeseries-select' id='endDate'></select>

                    data type:
                    <select class='timeseries-select' id='dataType'>
                        <option value='continuous'>continuous</option>
                        <option value='discrete'>discrete</option>
                    </select>

                    for layers:
                    <select class='timeseries-select' id='layer-specification'>
                        <option value='all-added-layers'>all added layers</option>
                        <option value='top-layer'>top layer</option>
                    </select>

                <button class='timeSeriesButton' id='timeSeriesButton'>
                    generate timeseries
                    cancel timeseries

                </button>

        `;
        this.querySelector('#dataType').value = dataType;
        this.loading = false;
    }

    connectedCallback() {
        this.querySelector('#timeseries-button').onpointerdown = (e) => e.stopPropagation();

        this.initializeTimeSeriesButton();
        this.initializeStartDateSelector();
        this.initializeEndDateSelector();

        this.subscribeToTimeSeriesProgress();

        const dataTypeSelector = this.querySelector('#dataType');
        dataTypeSelector.addEventListener('change', () => {
            let dataType = dataTypeSelector.value;
            controllers.timeSeriesDataType.setValue(dataType);
        });
        this.updateTimestamps();
    }

    initializeTimeSeriesButton() {
        const timeSeriesButton = this.querySelector('#timeSeriesButton');
        timeSeriesButton.onpointerdown = () => {
            if (this.loading) {
                simVars.cancelTimeSeriesCallback();
                this.setProgress(1);
                this.loading = false;
            } else {
                this.loading = true;
                this.setProgress(0);
                this.querySelector('#generate-button-label').classList.add('hidden');
                this.querySelector('#cancel-button-label').classList.remove('hidden');
                simVars.generateTimeSeriesCallback();
            }
        }
    }

    initializeStartDateSelector() {
        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');
        startDate.addEventListener('change', () => {
            let simulationStartDate = controllers.startDate.getValue();
            if (startDate.value < simulationStartDate) {
                controllers.startDate.setValue(startDate.value);
            }
            linkSelects(startDate, endDate);
        });
    }

    initializeEndDateSelector() {
        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');
        endDate.addEventListener('change', () => {
            let simulationEndDate = controllers.endDate.getValue();
            if (endDate.value > simulationEndDate) {
                controllers.endDate.setValue(endDate.value);
            }
            linkSelects(startDate, endDate);
        });
    }

    subscribeToTimeSeriesProgress() {
        controllers.timeSeriesProgress.subscribe(() => {
            let progress = controllers.timeSeriesProgress.getValue();
            this.setProgress(progress);
        });
    }

    /** ===== Getters block ===== */
    getButton() {
        return this.querySelector('#timeSeriesButton');
    }

    getStartDate() {
        return this.querySelector('#startDate').value;
    }

    getEndDate() {
        return this.querySelector('#endDate').value;
    }

    getDataType() {
        return this.querySelector('#dataType').value;
    }

    getLayerSpecification() {
        return this.querySelector('#layer-specification').value;
    }

    /** ===== Setters block ===== */
    updateTimestamps() {
        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');
        startDate.innerHTML = '';
        endDate.innerHTML = '';
        for (let timestamp of simVars.sortedTimestamps) {
            startDate.appendChild(createOption(timestamp, true));
            endDate.appendChild(createOption(timestamp, true));
        }
        startDate.value = controllers.startDate.getValue();
        endDate.value = controllers.endDate.getValue();
    }

    setProgress(progress) {
        if (!this.loading) {
            return;
        }
        const progressBar = this.querySelector('#progressBar');
        if (progress < 1) {
            progressBar.classList.remove('hidden');
            progressBar.style.width = Math.floor(progress*100) + '%';
        } else {
            this.loading = false;
            this.querySelector('#generate-button-label').classList.remove('hidden');
            this.querySelector('#cancel-button-label').classList.add('hidden');
            progressBar.classList.add('hidden');
        }
    }

    setStartDate(newStartDate) {
        let newStartIndex = simVars.sortedTimestamps.indexOf(newStartDate);
        if (newStartIndex == simVars.sortedTimestamps.length - 1) {
            return;
        }

        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');

        let oldEndDate = endDate.value;
        if (newStartDate >= oldEndDate) {
           endDate.value =  simVars.sortedTimestamps[newStartIndex + 1];
        }
        startDate.value = newStartDate;

        linkSelects(startDate, endDate);
    }

    setEndDate(newEndDate) {
        let newEndIndex = simVars.sortedTimestamps.indexOf(newEndDate);
        if (newEndIndex == 0) {
            return;
        }

        const endDate = this.querySelector('#endDate');
        const startDate = this.querySelector('#startDate');

        let oldStartDate = startDate.value;
        if (newEndDate <= oldStartDate) {
            startDate.value = simVars.sortedTimestamps[newEndIndex - 1];
        }
        endDate.value = newEndDate;

        linkSelects(startDate, endDate);
    }
}

window.customElements.define('timeseries-button', TimeSeriesButton);<commit_msg>Links start and end dates of timeSeriesMenu<commit_after>import { createOption, linkSelects } from '../util.js';
import { controllers, controllerEvents } from './Controller.js';
import { simVars } from '../simVars.js';

/**      Contents
 *  1. Initialization block
 *  2. Getters block
 *  3. Setters block
 *
 */
export class TimeSeriesButton extends HTMLElement {
    /** ===== Initialization block ===== */
    constructor(dataType = 'continuous') {
        super();
        this.innerHTML = `

                    start time:
                    <select class='timeseries-select' id='startDate'></select>

                    end time:
                    <select class='timeseries-select' id='endDate'></select>

                    data type:
                    <select class='timeseries-select' id='dataType'>
                        <option value='continuous'>continuous</option>
                        <option value='discrete'>discrete</option>
                    </select>

                    for layers:
                    <select class='timeseries-select' id='layer-specification'>
                        <option value='all-added-layers'>all added layers</option>
                        <option value='top-layer'>top layer</option>
                    </select>

                <button class='timeSeriesButton' id='timeSeriesButton'>
                    generate timeseries
                    cancel timeseries

                </button>

        `;
        this.querySelector('#dataType').value = dataType;
        this.loading = false;
    }

    connectedCallback() {
        this.querySelector('#timeseries-button').onpointerdown = (e) => e.stopPropagation();

        this.initializeTimeSeriesButton();
        this.initializeStartDateSelector();
        this.initializeEndDateSelector();

        this.subscribeToTimeSeriesProgress();

        const dataTypeSelector = this.querySelector('#dataType');
        dataTypeSelector.addEventListener('change', () => {
            let dataType = dataTypeSelector.value;
            controllers.timeSeriesDataType.setValue(dataType);
        });
        this.updateTimestamps();
    }

    initializeTimeSeriesButton() {
        const timeSeriesButton = this.querySelector('#timeSeriesButton');
        timeSeriesButton.onpointerdown = () => {
            if (this.loading) {
                simVars.cancelTimeSeriesCallback();
                this.setProgress(1);
                this.loading = false;
            } else {
                this.loading = true;
                this.setProgress(0);
                this.querySelector('#generate-button-label').classList.add('hidden');
                this.querySelector('#cancel-button-label').classList.remove('hidden');
                simVars.generateTimeSeriesCallback();
            }
        }
    }

    initializeStartDateSelector() {
        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');
        startDate.addEventListener('change', () => {
            let simulationStartDate = controllers.startDate.getValue();
            if (startDate.value < simulationStartDate) {
                controllers.startDate.setValue(startDate.value);
                controllers.startDate.broadcastEvent(controllerEvents.VALUE_SET)
            }
            linkSelects(startDate, endDate);
        });
    }

    initializeEndDateSelector() {
        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');
        endDate.addEventListener('change', () => {
            let simulationEndDate = controllers.endDate.getValue();
            if (endDate.value > simulationEndDate) {
                controllers.endDate.setValue(endDate.value);
                controllers.endDate.broadcastEvent(controllerEvents.VALUE_SET)
            }
            linkSelects(startDate, endDate);
        });
    }

    subscribeToTimeSeriesProgress() {
        controllers.timeSeriesProgress.subscribe(() => {
            let progress = controllers.timeSeriesProgress.getValue();
            this.setProgress(progress);
        });
    }

    /** ===== Getters block ===== */
    getButton() {
        return this.querySelector('#timeSeriesButton');
    }

    getStartDate() {
        return this.querySelector('#startDate').value;
    }

    getEndDate() {
        return this.querySelector('#endDate').value;
    }

    getDataType() {
        return this.querySelector('#dataType').value;
    }

    getLayerSpecification() {
        return this.querySelector('#layer-specification').value;
    }

    /** ===== Setters block ===== */
    updateTimestamps() {
        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');
        startDate.innerHTML = '';
        endDate.innerHTML = '';
        for (let timestamp of simVars.sortedTimestamps) {
            startDate.appendChild(createOption(timestamp, true));
            endDate.appendChild(createOption(timestamp, true));
        }
        startDate.value = controllers.startDate.getValue();
        endDate.value = controllers.endDate.getValue();
    }

    setProgress(progress) {
        if (!this.loading) {
            return;
        }
        const progressBar = this.querySelector('#progressBar');
        if (progress < 1) {
            progressBar.classList.remove('hidden');
            progressBar.style.width = Math.floor(progress*100) + '%';
        } else {
            this.loading = false;
            this.querySelector('#generate-button-label').classList.remove('hidden');
            this.querySelector('#cancel-button-label').classList.add('hidden');
            progressBar.classList.add('hidden');
        }
    }

    setStartDate(newStartDate) {
        let newStartIndex = simVars.sortedTimestamps.indexOf(newStartDate);
        if (newStartIndex == simVars.sortedTimestamps.length - 1) {
            return;
        }

        const startDate = this.querySelector('#startDate');
        const endDate = this.querySelector('#endDate');

        let oldEndDate = endDate.value;
        if (newStartDate >= oldEndDate) {
           endDate.value =  simVars.sortedTimestamps[newStartIndex + 1];
        }
        startDate.value = newStartDate;

        linkSelects(startDate, endDate);
    }

    setEndDate(newEndDate) {
        let newEndIndex = simVars.sortedTimestamps.indexOf(newEndDate);
        if (newEndIndex == 0) {
            return;
        }

        const endDate = this.querySelector('#endDate');
        const startDate = this.querySelector('#startDate');

        let oldStartDate = startDate.value;
        if (newEndDate <= oldStartDate) {
            startDate.value = simVars.sortedTimestamps[newEndIndex - 1];
        }
        endDate.value = newEndDate;

        linkSelects(startDate, endDate);
    }
}

window.customElements.define('timeseries-button', TimeSeriesButton);<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular
    .module('app.meerp.sales')
    .controller('NewSaleCtrl', NewSaleCtrl);

  function NewSaleCtrl($scope,
                       $location,
                       $ionicPopup,
                       $stateParams,
                       currentSaleService,
                       productsService,
                       dataMiningService) {

    // Controller as vm pattern
    var vm = this;
    vm.captureProduct = captureProduct;

    init(); // Initialize controller

    /**
     * Captures new product
     */
    function captureProduct(productCode) {
      // Check if provided code is SKU or EAN:

      if (productCode > 6) { // If code is EAN
        productsService.getProductByEAN(productCode)
          .then(function (product) {
            addItem(product);
          })
          .catch(function (err) {
            // Catch error
          });
      } else { // If code is SKU
        productsService.getProductBySKU(productCode)
          .then(function (product) {
            addItem(product);
          })
          .catch(function (err) {
            // Catch error
          });
      }
    }

    function addItem(product) {
      showProductQuantityPopUp()
        .then(function (qty) {
          product.quantity = qty;

          if (product.quantity > 0) {
            // Persist products in current sale
            currentSaleService.setItem(product);
            // Also update controller's sale object
            vm.sale.items = currentSaleService.getItems();
            // Clear input value to be ready for next capture
            vm.productCode = '';
          }
        });
    }

    /**
     * Displays initial instructions alert.
     */
    function showAlertOnSiteInstructions() {
      $ionicPopup.alert({
        title: 'Nueva Venta in situ',
        template: 'Seleccione el cliente al cual visita.'
      });
    }

    function showProductQuantityPopUp() {
      $scope.data = {qty: 0};

      var qtyPopup = $ionicPopup.show({
        template: '<input type="text" ng-model="data.qty">',
        title: 'Cantidad',
        //subTitle: 'Please use normal things',
        scope: $scope,
        buttons: [
          {
            text: 'Cancel',
            onTap: function() {
              return 0;
            }
          },
          {
            text: 'Aceptar',
            type: 'button-positive',
            onTap: function(e) {
              if ($scope.data.qty > 0) {
                return $scope.data.qty;
              }
              //don't allow the user to close unless he enters wifi password
              e.preventDefault();
            }
          }
        ]
      });

      return qtyPopup;

    }

    /**
     * Initializes controller setups.
     */
    function init() {
      vm.sale = {}; // Current controller's sale object
      // Retrieve client from current sale service.
      vm.sale.client = currentSaleService.getClient();

      // Check if current sale has not a client selected yet
      if (!vm.sale.client && $stateParams.onsite) {
        // Redirect to locate a client using map
        //$location.path('app/clients/locate');
        // Display instructions
        //showAlertOnSiteInstructions();

      } else if (vm.sale.client) { // If a client has already been selected
        // Get client required stock suggests from data mining service
        dataMiningService.getClientReStock(vm.sale.client)
          .then(function (products) {
            // If suggested re-stock found, add them to current new sale
            if (products.length > 0) {
              products.forEach(function (item) {
                captureProduct.setItem(item);
              });
            }
          })
          .then(function (err) {
            // Catch error
          })

      }

    }

  }

})();
<commit_msg>Uncommented lines.<commit_after>(function () {
  'use strict';

  angular
    .module('app.meerp.sales')
    .controller('NewSaleCtrl', NewSaleCtrl);

  function NewSaleCtrl($scope,
                       $location,
                       $ionicPopup,
                       $stateParams,
                       currentSaleService,
                       productsService,
                       dataMiningService) {

    // Controller as vm pattern
    var vm = this;
    vm.captureProduct = captureProduct;

    init(); // Initialize controller

    /**
     * Captures new product
     */
    function captureProduct(productCode) {
      // Check if provided code is SKU or EAN:

      if (productCode > 6) { // If code is EAN
        productsService.getProductByEAN(productCode)
          .then(function (product) {
            addItem(product);
          })
          .catch(function (err) {
            // Catch error
          });
      } else { // If code is SKU
        productsService.getProductBySKU(productCode)
          .then(function (product) {
            addItem(product);
          })
          .catch(function (err) {
            // Catch error
          });
      }
    }

    function addItem(product) {
      showProductQuantityPopUp()
        .then(function (qty) {
          product.quantity = qty;

          if (product.quantity > 0) {
            // Persist products in current sale
            currentSaleService.setItem(product);
            // Also update controller's sale object
            vm.sale.items = currentSaleService.getItems();
            // Clear input value to be ready for next capture
            vm.productCode = '';
          }
        });
    }

    /**
     * Displays initial instructions alert.
     */
    function showAlertOnSiteInstructions() {
      $ionicPopup.alert({
        title: 'Nueva Venta in situ',
        template: 'Seleccione el cliente al cual visita.'
      });
    }

    function showProductQuantityPopUp() {
      $scope.data = {qty: 0};

      var qtyPopup = $ionicPopup.show({
        template: '<input type="text" ng-model="data.qty">',
        title: 'Cantidad',
        //subTitle: 'Please use normal things',
        scope: $scope,
        buttons: [
          {
            text: 'Cancel',
            onTap: function() {
              return 0;
            }
          },
          {
            text: 'Aceptar',
            type: 'button-positive',
            onTap: function(e) {
              if ($scope.data.qty > 0) {
                return $scope.data.qty;
              }
              //don't allow the user to close unless he enters wifi password
              e.preventDefault();
            }
          }
        ]
      });

      return qtyPopup;

    }

    /**
     * Initializes controller setups.
     */
    function init() {
      vm.sale = {}; // Current controller's sale object
      // Retrieve client from current sale service.
      vm.sale.client = currentSaleService.getClient();

      // Check if current sale has not a client selected yet
      if (!vm.sale.client && $stateParams.onsite) {
        // Redirect to locate a client using map
        $location.path('app/clients/locate');
        // Display instructions
        showAlertOnSiteInstructions();

      } else if (vm.sale.client) { // If a client has already been selected
        // Get client required stock suggests from data mining service
        dataMiningService.getClientReStock(vm.sale.client)
          .then(function (products) {
            // If suggested re-stock found, add them to current new sale
            if (products.length > 0) {
              products.forEach(function (item) {
                captureProduct.setItem(item);
              });
            }
          })
          .then(function (err) {
            // Catch error
          })

      }

    }

  }

})();
<|endoftext|>


<commit_before>const nodeType = process.env.NODE_TYPE
const domainType = nodeType?.toLowerCase() === 'network' ? 'network' : 'domain'

module.exports = {
  typescript: {
    ignoreDevErrors: true,
    ignoreBuildErrors: true
  },
  webpackDevMiddleware: config => {
    config.watchOptions = {
      poll: 1000,
      aggregateTimeout: 300
    }
    return config
  },
  env: {
    NEXT_PUBLIC_VERSION: process.env.VERSION,
    NEXT_PUBLIC_VERSION_HASH: process.env.VERSION_HASH,
    NEXT_PUBLIC_NODE_TYPE: process.env.NODE_TYPE
  },
  async redirects() {
    return [
      {
        source: '/_network/:path*',
        destination: '/:path*',
        permanent: false
      },
      {
        source: '/_domain/:path*',
        destination: '/:path*',
        permanent: false
      }
    ]
  },
  async rewrites() {
    return [
      {
        source: '/:path*',
        destination: `/_${domainType}/:path*`
      }
    ]
  }
}
<commit_msg>next config<commit_after>const Module = require('module')
const path = require('path')
const resolveFrom = require('resolve-from')
const node_modules = path.resolve(__dirname, 'node_modules')
const originalRequire = Module.prototype.require

const nodeType = process.env.NODE_TYPE
const domainType = nodeType?.toLowerCase() === 'network' ? 'network' : 'domain'

Module.prototype.require = function (modulePath) {
  // Only redirect resolutions to non-relative and non-absolute modules
  if (
    ['/react/', '/react-dom/', '/react-query/'].some(d => {
      try {
        return require.resolve(modulePath).includes(d)
      } catch (err) {
        return false
      }
    })
  ) {
    try {
      modulePath = resolveFrom(node_modules, modulePath)
    } catch (err) {
      //
    }
  }

  return originalRequire.call(this, modulePath)
}

module.exports = {
  typescript: {
    ignoreDevErrors: true,
    ignoreBuildErrors: true
  },
  webpackDevMiddleware: config => {
    config.watchOptions = {
      poll: 1000,
      aggregateTimeout: 300
    }
    return config
  },
  webpack: config => {
    config.resolve = {
      ...config.resolve,
      alias: {
        ...config.resolve.alias,
        react$: resolveFrom(path.resolve('node_modules'), 'react'),
        'react-query$': resolveFrom(path.resolve('node_modules'), 'react-query'),
        'react-dom$': resolveFrom(path.resolve('node_modules'), 'react-dom')
      }
    }
    return config
  },
  env: {
    NEXT_PUBLIC_VERSION: process.env.VERSION,
    NEXT_PUBLIC_VERSION_HASH: process.env.VERSION_HASH,
    NEXT_PUBLIC_NODE_TYPE: process.env.NODE_TYPE
  },
  async redirects() {
    return [
      {
        source: '/_network/:path*',
        destination: '/:path*',
        permanent: false
      },
      {
        source: '/_domain/:path*',
        destination: '/:path*',
        permanent: false
      }
    ]
  },
  async rewrites() {
    return [
      {
        source: '/:path*',
        destination: `/_${domainType}/:path*`
      }
    ]
  }
}
<|endoftext|>


<commit_before>/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

import assert from '../../../../lib/assert';
import {defaultMethod, validMethods} from './constants';

/**
 * A `Route` allows you to tell a service worker that it should handle
 * certain network requests using a specific response strategy.
 *
 * Two configuration options are required:
 *
 * - A `match` function, which examines
 * an incoming [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
 * to determine whether this `Route` should apply. The function should return
 * a [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) value
 * if the `Route` matches, in which case that return value is passed along to
 * the `handle` function.
 * - A `handler` object, which should in turn have a function defined on it
 * named `handle`. This `handle` function is given the incoming request along
 * with any additional parameters generated during the `match`, and returns a
 * Promise for a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
 *
 * Instead of implementing your own `handler`, you can use one of the
 * pre-defined runtime caching strategies from the
 * {@link module:sw-runtime-caching|sw-runtime-caching} module.
 *
 * While you can use `Route` directly, the [`RegExpRoute`]{@link RegExpRoute}
 * and [`ExpressRoute`]{@link ExpressRoute} subclasses provide a convenient
 * wrapper with a nicer interface for using regular expressions or Express-style
 * routes as the `match` criteria.
 *
 * @example
 * // Any navigation requests for URLs that start with /path/to/ will match.
 * const route = new goog.routing.Route({
 *   match: ({url, event}) => {
 *     return event.request.mode === 'navigation' &&
 *            url.pathname.startsWith('/path/to/');
 *   },
 *   handler: ({event}) => {
 *     // Do something that returns a Promise.<Response>, like:
 *     return caches.match(event.request);
 *   },
 * });
 *
 * const router = new goog.routing.Router();
 * router.registerRoute({route});
 *
 * @memberof module:sw-routing
 */
class Route {
  /**
   * Constructor for Route class.
   * @param {Object} input
   * @param {function} input.match The function that determines whether the
   *        route matches. The function is passed an object with two properties:
   *        `url`, which is a [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL),
   *        and `event`, which is a [FetchEvent](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent).
   *        `match` should return a truthy value when the route applies, and
   *        that value is passed on to the handle function.
   * @param {function|Object} input.handler A function, or an Object with a
   *        `handle` method. As parameters, the handler is passed object with
   *        the same `url` and `event` properties as `match` received, along
   *        with an additional property, `params`, set to the truthy value
   *        `match` returned.
   * @param {string} [input.method] Only match requests that use this
   *        HTTP method. Defaults to `'GET'` if not specified.
   */
  constructor({match, handler, method} = {}) {
    assert.isType({match}, 'function');
    if (typeof handler === 'object') {
      assert.hasMethod({handler}, 'handle');
    } else {
      assert.isType({handler}, 'function');
    }

    this.match = match;
    // Normalize things so that even if the handler is a function, this.handler
    // gets set to an object with a handle method.
    this.handler = typeof handler === 'function' ? {handle: handler} : handler;
    if (method) {
      assert.isOneOf({method}, validMethods);
      this.method = method;
    } else {
      this.method = defaultMethod;
    }
  }
}

export default Route;
<commit_msg>Fix a typo. (#292)<commit_after>/*
 Copyright 2016 Google Inc. All Rights Reserved.
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
*/

import assert from '../../../../lib/assert';
import {defaultMethod, validMethods} from './constants';

/**
 * A `Route` allows you to tell a service worker that it should handle
 * certain network requests using a specific response strategy.
 *
 * Two configuration options are required:
 *
 * - A `match` function, which examines
 * an incoming [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request)
 * to determine whether this `Route` should apply. The function should return
 * a [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) value
 * if the `Route` matches, in which case that return value is passed along to
 * the `handle` function.
 * - A `handler` object, which should in turn have a function defined on it
 * named `handle`. This `handle` function is given the incoming request along
 * with any additional parameters generated during the `match`, and returns a
 * Promise for a [`Response`](https://developer.mozilla.org/en-US/docs/Web/API/Response).
 *
 * Instead of implementing your own `handler`, you can use one of the
 * pre-defined runtime caching strategies from the
 * {@link module:sw-runtime-caching|sw-runtime-caching} module.
 *
 * While you can use `Route` directly, the [`RegExpRoute`]{@link RegExpRoute}
 * and [`ExpressRoute`]{@link ExpressRoute} subclasses provide a convenient
 * wrapper with a nicer interface for using regular expressions or Express-style
 * routes as the `match` criteria.
 *
 * @example
 * // Any navigation requests for URLs that start with /path/to/ will match.
 * const route = new goog.routing.Route({
 *   match: ({url, event}) => {
 *     return event.request.mode === 'navigation' &&
 *            url.pathname.startsWith('/path/to/');
 *   },
 *   handler: ({event}) => {
 *     // Do something that returns a Promise.<Response>, like:
 *     return caches.match(event.request);
 *   },
 * });
 *
 * const router = new goog.routing.Router();
 * router.registerRoute({route});
 *
 * @memberof module:sw-routing
 */
class Route {
  /**
   * Constructor for Route class.
   * @param {Object} input
   * @param {function} input.match The function that determines whether the
   *        route matches. The function is passed an object with two properties:
   *        `url`, which is a [URL](https://developer.mozilla.org/en-US/docs/Web/API/URL),
   *        and `event`, which is a [FetchEvent](https://developer.mozilla.org/en-US/docs/Web/API/FetchEvent).
   *        `match` should return a truthy value when the route applies, and
   *        that value is passed on to the handle function.
   * @param {function|Object} input.handler A function, or an Object with a
   *        `handle` method. As parameters, the handler is passed an object with
   *        the same `url` and `event` properties as `match` received, along
   *        with an additional property, `params`, set to the truthy value
   *        `match` returned.
   * @param {string} [input.method] Only match requests that use this
   *        HTTP method. Defaults to `'GET'` if not specified.
   */
  constructor({match, handler, method} = {}) {
    assert.isType({match}, 'function');
    if (typeof handler === 'object') {
      assert.hasMethod({handler}, 'handle');
    } else {
      assert.isType({handler}, 'function');
    }

    this.match = match;
    // Normalize things so that even if the handler is a function, this.handler
    // gets set to an object with a handle method.
    this.handler = typeof handler === 'function' ? {handle: handler} : handler;
    if (method) {
      assert.isOneOf({method}, validMethods);
      this.method = method;
    } else {
      this.method = defaultMethod;
    }
  }
}

export default Route;
<|endoftext|>


<commit_before>import * as React from "react";
import PropTypes from "prop-types";
import values from "object.values";
import { fontSizes, fontTypes } from "@crave/farmblocks-theme";

import Container from "../styledComponents/Text";

export default class Text extends React.Component {
  render() {
    const { children, title, ...props } = this.props;
    return (
      <Container isTitle={title} {...props}>
        {children}
      </Container>
    );
  }

  static propTypes = {
    children: PropTypes.node,
    size: PropTypes.number,
    type: PropTypes.oneOf(values(fontTypes)),
    align: PropTypes.oneOf(["left", "center", "right", "justify"]),
    lineHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
    paragraph: PropTypes.bool,
    title: PropTypes.bool,
    letterSpacing: PropTypes.string,
    fontWeight: PropTypes.number
  };

  static defaultProps = {
    size: fontSizes.LARGE,
    type: fontTypes.NORMAL,
    align: "left",
    paragraph: false,
    title: false
  };
}
<commit_msg>Update packages/text/src/components/Text.js<commit_after>import * as React from "react";
import PropTypes from "prop-types";
import values from "object.values";
import { fontSizes, fontTypes } from "@crave/farmblocks-theme";

import Container from "../styledComponents/Text";

export default class Text extends React.Component {
  render() {
    const { children, title, ...props } = this.props;
    return (
      <Container isTitle={title} {...props}>
        {children}
      </Container>
    );
  }

  static propTypes = {
    children: PropTypes.node,
    size: PropTypes.number,
    type: PropTypes.oneOf(values(fontTypes)),
    align: PropTypes.oneOf(["left", "center", "right", "justify"]),
    lineHeight: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
    paragraph: PropTypes.bool,
    title: PropTypes.bool,
    letterSpacing: PropTypes.string,
    light: PropTypes.bool
  };

  static defaultProps = {
    size: fontSizes.LARGE,
    type: fontTypes.NORMAL,
    align: "left",
    paragraph: false,
    title: false
  };
}
<|endoftext|>


<commit_before>// Node test suite

sinon = require('sinon');
require('../suite/suite');
require('../suite/log');
require('../suite/helpers/common');
require('../suite/helpers/core');
require('../suite/helpers/date');
require('../suite/helpers/array');
require('../suite/helpers/object');

// TODO: Move this to sugar-core when its ready
var Sugar = require('../../lib/core');
testSetGlobal(Sugar);

var exitOnFail = true;

function notice(message, logFn) {
  var cols = 36;
  var pad = new Array(Math.floor((cols - message.length) / 2)).join(' ');
  var sep = new Array(cols).join('-');
  console.info();
  console.info();
  logFn(sep);
  logFn(pad + message + pad);
  logFn(sep);
  console.info();
}

function load(path) {
  if (path.match(/es[567]$/)) {
    // Need to manually expire this as it's being
    // linked to from inside the polyfill package.
    resetPolyfillCache();
  }
  delete require.cache[require.resolve(path)]
  return require(path);
}

function loadLocaleTests() {
  var path = require('path'), fs = require('fs');
  fs.readdirSync(path.join(__dirname, '../tests/locales')).forEach(function(file) {
    load(path.relative(__dirname, path.join('./test/tests/locales', file)));
  });
}

function resetPolyfillCache() {
  for (var path in require.cache) {
    if(!require.cache.hasOwnProperty(path)) continue;
    var path = require.resolve(path);
    if (path.match(/polyfills\/\w+\/\w+\.js$/)) {
      delete require.cache[path]
    }
  };
}

function getTestNameFromModule(mod) {
  var match = mod.filename.match(/(\w+)\/([\w-]+)\.js$/);
  var type = match[1];
  var name = match[2];
  if (name === 'regexp') {
    name = 'RegExp';
  } else if (name.match(/^es\d/)) {
    name = name.toUpperCase();
  } else {
    name = name.slice(0, 1).toUpperCase() + name.slice(1);
  }
  return type === 'extended' ? name + ' - Extended' : name;
}

module.exports = {

  load: function(path) {
    return load(path);
  },

  loadTest: function(name) {
    return load('../tests/' + name);
  },

  loadLocaleTests: function() {
    loadLocaleTests();
  },

  run: function(mod, extended) {

    var testName = getTestNameFromModule(mod);
    if (extended) {
      storeNativeState();
      Sugar.extendAll();
    }
    function finished(runtime, results) {
      logResults(runtime, results, testName, exitOnFail);
    }
    runTests(finished, !!extended, 'node');

    if (extended) {
      // Tests may be in a watcher, so restore native state
      // after finished to prepare for next run.
      restoreNativeState();
    }
  },

  runExtended: function(mod) {
    this.run(mod, true);
  },

  resetPolyfills: function(name) {
    load('../suite/helpers/' + name + '-reset.js');
  },

  reset: function() {
    globalFailures = 0;
  },

  exitOnFail: function(set) {
    exitOnFail = set;
  },

  logTotals: function() {
    if (globalFailures) {
      notice('Fail! ' + globalFailures + ' failures', logRed);
    } else {
      notice('Success! 0 failures', logBlue);
    }
    globalFailures = 0;
  },

  notice: function(message) {
    notice(message, logYellow);
  }

};
<commit_msg>complain when npm package does not exist<commit_after>// Node test suite

sinon = require('sinon');
require('../suite/suite');
require('../suite/log');
require('../suite/helpers/common');
require('../suite/helpers/core');
require('../suite/helpers/date');
require('../suite/helpers/array');
require('../suite/helpers/object');

// TODO: Move this to sugar-core when its ready
var Sugar = require('../../lib/core');
testSetGlobal(Sugar);

var exitOnFail = true;

function notice(message, logFn) {
  var cols = Math.max(36, message.length + 1);
  var pad = new Array(Math.floor((cols - message.length) / 2)).join(' ');
  var sep = new Array(cols).join('-');
  console.info();
  console.info();
  logFn(sep);
  logFn(pad + message + pad);
  logFn(sep);
  console.info();
}

function load(path) {
  if (path.match(/es[567]$/)) {
    // Need to manually expire this as it's being
    // linked to from inside the polyfill package.
    resetPolyfillCache();
  }
  if (path.match(/foobar/)) {
    fs.lstatSync(COMPIER_JAR_PATH);
  }
  try {
    return require(path);
  } catch (e) {
    var match = path.match(/(sugar(-\w+)?)$/);
    if (match) {
      var message = [
        '',
        '     Package "' + match[1] + '" does not exist!',
        (match[2] ?
        '     Run "gulp build:npm:all" to build all packages.' :
        '     Run "gulp build:npm" to build it.'
        ),
        '',
      ].join('\n');
      logYellow(message);
      process.exit();
    } else {
      throw e;
    }
  }
}

function loadLocaleTests() {
  var path = require('path'), fs = require('fs');
  fs.readdirSync(path.join(__dirname, '../tests/locales')).forEach(function(file) {
    load(path.relative(__dirname, path.join('./test/tests/locales', file)));
  });
}

function resetPolyfillCache() {
  for (var path in require.cache) {
    if(!require.cache.hasOwnProperty(path)) continue;
    var path = require.resolve(path);
    if (path.match(/polyfills\/\w+\/\w+\.js$/)) {
      delete require.cache[path]
    }
  };
}

function getTestNameFromModule(mod) {
  var match = mod.filename.match(/(\w+)\/([\w-]+)\.js$/);
  var type = match[1];
  var name = match[2];
  if (name === 'regexp') {
    name = 'RegExp';
  } else if (name.match(/^es\d/)) {
    name = name.toUpperCase();
  } else {
    name = name.slice(0, 1).toUpperCase() + name.slice(1);
  }
  return type === 'extended' ? name + ' - Extended' : name;
}

module.exports = {

  load: function(path) {
    return load(path);
  },

  loadTest: function(name) {
    return load('../tests/' + name);
  },

  loadLocaleTests: function() {
    loadLocaleTests();
  },

  run: function(mod, extended) {

    var testName = getTestNameFromModule(mod);
    if (extended) {
      storeNativeState();
      Sugar.extendAll();
    }
    function finished(runtime, results) {
      logResults(runtime, results, testName, exitOnFail);
    }
    runTests(finished, !!extended, 'node');

    if (extended) {
      // Tests may be in a watcher, so restore native state
      // after finished to prepare for next run.
      restoreNativeState();
    }
  },

  runExtended: function(mod) {
    this.run(mod, true);
  },

  resetPolyfills: function(name) {
    load('../suite/helpers/' + name + '-reset.js');
  },

  reset: function() {
    globalFailures = 0;
  },

  exitOnFail: function(set) {
    exitOnFail = set;
  },

  logTotals: function() {
    if (globalFailures) {
      notice('Fail! ' + globalFailures + ' failures', logRed);
    } else {
      notice('Success! 0 failures', logBlue);
    }
    globalFailures = 0;
  },

  notice: function(message) {
    notice(message, logYellow);
  }

};
<|endoftext|>


<commit_before>var assert = require('assert'),
    pubsub = require('node-internal-pubsub'),
    non_global = require('../examples/non_global');

describe('examples/non_global', function(){
  it('runs', function(){
    assert(typeof non_global != "undefined");
  });

});<commit_msg>leave test commented out.<commit_after>// var assert = require('assert'),
//     pubsub = require('node-internal-pubsub'),
//     non_global = require('../examples/non_global');

// describe('examples/non_global', function(){
//   it('runs', function(){
//     assert(typeof non_global != "undefined");
//   });

// });<|endoftext|>


<commit_before>var ipc = require('node-ipc');
var path = require('path');
var spawn = require('child_process').spawn;

var Develop = {
  start: function(testrpcOptions, callback) {
    var chainPath;

    // The path to the dev env process depends on whether or not
    // we're running in the bundled version. If not, use chain.js
    // directly, otherwise let the bundle point at the bundled version.
    if (typeof BUNDLE_CHAIN_FILENAME != "undefined") {
      // Remember: In the bundled version, __dirname refers to the
      // build directory where cli.bundled.js and cli.chain.js live.
      chainPath = path.join(__dirname, BUNDLE_CHAIN_FILENAME);
    } else {
      chainPath = path.join(__dirname, "../", "chain.js");
    }

    var cmd = spawn("node", [chainPath, JSON.stringify(testrpcOptions)], {
      detached: true
    });

    var callbackCalled = false;

    cmd.stdout.on('data', function(data) {
      // // Print anything our chain process outputs (not much).
      // // Trim or else we'll have double new lines.
      // config.logger.log(data.toString().trim());

      // Here, we use on('data') to tell us if the application
      // has started correctly. We'll call the callback and setup
      // the configuration once get our first output on stdout.
      // Note: Chain errors go to stderr (see below).
      if (callbackCalled) return;

      callbackCalled = true;

      ipc.connectTo('truffleDevelop', function() {
        ipc.of.truffleDevelop.on('connect', function() {
          callback();
        });
      });
    });

    cmd.stderr.on('data', function(data) {
      // Log any chain errors.
      // config.logger.log(data.toString().trim());
    });

    cmd.on('error', function(err) {
      // If ther'es a bigger error, throw it.
      throw err;
    });
  },

  connect: function(callback) {
    ipc.config.maxRetries = 0;
    ipc.config.silent = true;

    ipc.connectTo('truffleDevelop', function() {
      ipc.of.truffleDevelop.on('error', function(error) {
        callback(error);
      });

      ipc.of.truffleDevelop.on('connect', function() {
        callback();
      });
    });
  },

  connectOrStart: function(testrpcOptions, callback) {
    var self = this;

    this.connect(function(error) {
      if (error) {
        self.start(testrpcOptions, function() { callback(true); });
      } else {
        callback(false);
      }
    });
  }
};

module.exports = Develop;
<commit_msg>Remove code for capturing server output<commit_after>var ipc = require('node-ipc');
var path = require('path');
var spawn = require('child_process').spawn;

var Develop = {
  start: function(testrpcOptions, callback) {
    var chainPath;

    // The path to the dev env process depends on whether or not
    // we're running in the bundled version. If not, use chain.js
    // directly, otherwise let the bundle point at the bundled version.
    if (typeof BUNDLE_CHAIN_FILENAME != "undefined") {
      // Remember: In the bundled version, __dirname refers to the
      // build directory where cli.bundled.js and cli.chain.js live.
      chainPath = path.join(__dirname, BUNDLE_CHAIN_FILENAME);
    } else {
      chainPath = path.join(__dirname, "../", "chain.js");
    }

    var cmd = spawn("node", [chainPath, JSON.stringify(testrpcOptions)], {
      detached: true
    });

    var callbackCalled = false;

    cmd.stdout.on('data', function(data) {
      // Here, we use on('data') to tell us if the application
      // has started correctly. We'll call the callback and setup
      // the configuration once get our first output on stdout.
      // Note: Chain errors go to stderr (see below).
      if (callbackCalled) return;

      callbackCalled = true;

      ipc.connectTo('truffleDevelop', function() {
        ipc.of.truffleDevelop.on('connect', function() {
          callback();
        });
      });
    });

    cmd.on('error', function(err) {
      // If ther'es a bigger error, throw it.
      throw err;
    });
  },

  connect: function(callback) {
    ipc.config.maxRetries = 0;
    ipc.config.silent = true;

    ipc.connectTo('truffleDevelop', function() {
      ipc.of.truffleDevelop.on('error', function(error) {
        callback(error);
      });

      ipc.of.truffleDevelop.on('connect', function() {
        callback();
      });
    });
  },

  connectOrStart: function(testrpcOptions, callback) {
    var self = this;

    this.connect(function(error) {
      if (error) {
        self.start(testrpcOptions, function() { callback(true); });
      } else {
        callback(false);
      }
    });
  }
};

module.exports = Develop;
<|endoftext|>


<commit_before>const fs = require('fs')
const path = require('path')

const {
  removeExt,
  normalizePath,
  camelize,
  capitalize
} = require('./util')

const {
  getJson,
  parseJson
} = require('./json')

let mainEntry = ''
let nvueMainEntry = ''

function getMainEntry () {
  if (!mainEntry) {
    mainEntry = fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'main.ts')) ? 'main.ts' : 'main.js'
  }
  return mainEntry
}

function getNVueMainEntry () {
  if (!nvueMainEntry) {
    nvueMainEntry = fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'main.js')) ? 'main.js' : '.main.js'
    if (nvueMainEntry === '.main.js') {
      fs.writeFileSync(path.resolve(process.env.UNI_INPUT_DIR, '.main.js'), '')
    }
  }
  return nvueMainEntry
}

function getPagesJson () {
  return processPagesJson(getJson('pages.json', true))
}

function parsePagesJson (content, loader) {
  return processPagesJson(parseJson(content, true), loader)
}

function filterPages (pages = [], root) {
  for (let i = pages.length - 1; i >= 0; i--) {
    const page = pages[i]
    if (!isValidPage(page, root)) {
      pages.splice(i, 1)
    }
  }
}

const pagesJsonJsFileName = 'pages.js'

function processPagesJson (pagesJson, loader = {
  addDependency: function () {}
}) {
  const pagesJsonJsPath = path.resolve(process.env.UNI_INPUT_DIR, pagesJsonJsFileName)
  if (fs.existsSync(pagesJsonJsPath)) {
    delete require.cache[pagesJsonJsPath]
    const pagesJsonJsFn = require(pagesJsonJsPath)
    if (typeof pagesJsonJsFn === 'function') {
      pagesJson = pagesJsonJsFn(pagesJson, loader)
      if (!pagesJson) {
        console.error(`${pagesJsonJsFileName}  必须返回一个 json 对象`)
      }
    } else {
      console.error(`${pagesJsonJsFileName} 必须导出 function`)
    }
  }

  let uniNVueEntryPagePath
  if (pagesJson.pages && pagesJson.pages.length) { // 如果首页是 nvue
    if (isNVuePage(pagesJson.pages[0])) {
      uniNVueEntryPagePath = pagesJson.pages[0].path
    }
  }
  // pages
  filterPages(pagesJson.pages)
  // subPackages
  if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) {
    pagesJson.subPackages.forEach(subPackage => {
      filterPages(subPackage.pages, subPackage.root)
    })
  }

  if (uniNVuePages.length) { // 直接挂在 pagesJson 上
    pagesJson.nvue = {
      pages: uniNVuePages.reverse()
    }
    if (uniNVueEntryPagePath) {
      pagesJson.nvue.entryPagePath = uniNVueEntryPagePath
    }
  }
  return pagesJson
}

function isNVuePage (page, root = '') {
  if (process.env.UNI_PLATFORM === 'app-plus') {
    const pagePath = path.join(root, page.path)
    if (fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, pagePath + '.nvue'))) { // cache一下结果？如果文件被删除，cache 就会出现错误
      return true
    }
  }
  return false
}

function isValidPage (page, root = '') {
  if (typeof page === 'string') { // 不合法的配置
    console.warn(`${page} 配置错误, 已被忽略, 查看文档: https://uniapp.dcloud.io/collocation/pages?id=pages`)
    return false
  }
  let pagePath = page.path

  if (pagePath.indexOf('platforms') === 0) { // 平台相关
    if (pagePath.indexOf('platforms/' + process.env.UNI_PLATFORM) === -1) { // 非本平台
      return false
    }
  }

  if (
    process.env.UNI_PLATFORM === 'app-plus' &&
    page.style
  ) {
    const subNVues = page.style.subNVues || (page.style['app-plus'] && page.style['app-plus'].subNVues)
    if (Array.isArray(subNVues)) {
      subNVues.forEach(subNVue => {
        let subNVuePath = subNVue.path
        if (subNVuePath) {
          subNVuePath = subNVue.path.split('?')[0]
          const subNVuePagePath = removeExt(path.join(root, subNVuePath))
          process.UNI_NVUE_ENTRY[subNVuePagePath] = getNVueMainJsPath(subNVuePagePath)
        }
      })
    }
  } else {
    page.style && (delete page.style.subNVues)
  }

  if (isNVuePage(page, root)) {
    // 存储 nvue 相关信息
    pagePath = normalizePath(path.join(root, pagePath))

    process.UNI_NVUE_ENTRY[pagePath] = getNVueMainJsPath(pagePath)

    if (process.env.UNI_USING_V3 || process.env.UNI_USING_V3_NATIVE) { // 不移除
      page.nvue = true
      return true
    } else {
      uniNVuePages.push({
        path: pagePath + '.html',
        style: page.style || {}
      })
      return false
    }
  }

  return true
}

function getMainJsPath (page) {
  return path.resolve(process.env.UNI_INPUT_DIR, getMainEntry() + '?' + JSON.stringify({
    page: encodeURIComponent(page)
  }))
}

function getNVueMainJsPath (page) {
  return path.resolve(process.env.UNI_INPUT_DIR, getNVueMainEntry() + '?' + JSON.stringify({
    page: encodeURIComponent(page)
  }))
}

process.UNI_ENTRY = {}
process.UNI_NVUE_ENTRY = {}

const uniNVuePages = []

function parsePages (pagesJson, pageCallback, subPageCallback) {
  if (!pagesJson) {
    pagesJson = getPagesJson()
  }

  // pages
  pagesJson.pages.forEach(page => {
    pageCallback && pageCallback(page)
  })
  // subPackages
  if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) {
    pagesJson.subPackages.forEach((subPackage) => {
      const {
        root,
        pages
      } = subPackage
      pages.forEach(page => {
        root && subPageCallback && subPageCallback(root, page, subPackage)
      })
    })
  }
}

function parseEntry (pagesJson) {
  process.UNI_ENTRY = {
    'common/main': path.resolve(process.env.UNI_INPUT_DIR, getMainEntry())
  }

  process.UNI_SUB_PACKAGES_ROOT = {}

  process.UNI_NVUE_ENTRY = {}

  if (process.env.UNI_USING_NATIVE || process.env.UNI_USING_V3_NATIVE) {
    process.UNI_NVUE_ENTRY['app-config'] = path.resolve(process.env.UNI_INPUT_DIR, 'pages.json')
    process.UNI_NVUE_ENTRY['app-service'] = path.resolve(process.env.UNI_INPUT_DIR, getMainEntry())
  }

  uniNVuePages.length = 0

  if (!pagesJson) {
    pagesJson = getPagesJson() // 会检测修改 nvue entry
  }

  // pages
  pagesJson.pages.forEach(page => {
    process.UNI_ENTRY[page.path] = getMainJsPath(page.path)
  })
  // subPackages
  if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) {
    pagesJson.subPackages.forEach(({
      root,
      pages
    }) => {
      Array.isArray(pages) && pages.forEach(page => {
        if (root) {
          const pagePath = normalizePath(path.join(root, page.path))
          process.UNI_ENTRY[pagePath] = getMainJsPath(pagePath)
          process.UNI_SUB_PACKAGES_ROOT[pagePath] = root
        }
      })
    })
  }
}

function parseUsingComponents (usingComponents = {}) {
  const components = []
  Object.keys(usingComponents).forEach(name => {
    const identifier = capitalize(camelize(name))
    let source = usingComponents[name]
    if (source.indexOf('/') === 0) { // 绝对路径
      source = '@' + source
    } else if (source.indexOf('.') !== 0) { // 相对路径
      source = './' + source
    }
    components.push({
      name,
      identifier,
      source
    })
  })
  return components
}

function generateUsingComponentsCode (usingComponents) {
  const components = parseUsingComponents(usingComponents)
  const importCode = []
  const componentsCode = []
  components.forEach(({
    name,
    identifier,
    source
  }) => {
    importCode.push(`import ${identifier} from '${source}.vue'`)
    componentsCode.push(`'${name}':${identifier}`)
  })
  if (!importCode.length) {
    return ''
  }
  return `;${importCode.join(';')};exports.default.components=Object.assign({${componentsCode.join(',')}},exports.default.components||{});`
}

function generateGlobalUsingComponentsCode (usingComponents) {
  const components = parseUsingComponents(usingComponents)
  const importCode = []
  const componentsCode = []
  components.forEach(({
    name,
    identifier,
    source
  }) => {
    importCode.push(`import ${identifier} from '${source}.vue'`)
    componentsCode.push(`Vue.component('${name}',${identifier})`)
  })
  if (!importCode.length) {
    return ''
  }
  return `${importCode.join(';')};${componentsCode.join(';')};`
}

function getGlobalUsingComponentsCode () {
  const pagesJson = getPagesJson()
  const usingComponents = pagesJson.globalStyle && pagesJson.globalStyle.usingComponents
  if (!usingComponents) {
    return ''
  }
  return generateGlobalUsingComponentsCode(usingComponents)
}

function getUsingComponentsCode (pagePath) {
  const usingComponents = usingComponentsPages[pagePath]
  if (!usingComponents) {
    return ''
  }
  return generateUsingComponentsCode(usingComponents)
}

const usingComponentsPages = Object.create(null)

function addPageUsingComponents (pagePath, usingComponents) {
  if (usingComponents && Object.keys(usingComponents).length) {
    usingComponentsPages[pagePath] = usingComponents
  }
}
// 存储自动组件
const autoComponentMap = {}

let lastUsingAutoImportComponentsJson = ''

let uniAutoImportComponents = []

let uniAutoImportScanComponents = []

let uniQuickAppAutoImportScanComponents = false

const isDirectory = source => fs.lstatSync(source).isDirectory()

function getAutoComponentsByDir (componentsPath, absolute = false) {
  const components = {}
  try {
    fs.existsSync(componentsPath) && fs.readdirSync(componentsPath).forEach(name => {
      const folder = path.resolve(componentsPath, name)
      if (!isDirectory(folder)) {
        return
      }
      const importDir = absolute ? normalizePath(folder) : `@/components/${name}`
      // 读取文件夹文件列表，比对文件名（fs.existsSync在大小写不敏感的系统会匹配不准确）
      const files = fs.readdirSync(folder)
      if (files.includes(name + '.vue')) {
        components[`^${name}$`] = `${importDir}/${name}.vue`
      } else if (files.includes(name + '.nvue')) {
        components[`^${name}$`] = `${importDir}/${name}.nvue`
      }
    })
  } catch (e) {
    console.log(e)
  }
  return components
}

function initAutoImportScanComponents () {
  const componentsPath = path.resolve(process.env.UNI_INPUT_DIR, 'components')

  const components = getAutoComponentsByDir(componentsPath)

  if (process.env.UNI_PLATFORM === 'quickapp-native') {
    if (!uniQuickAppAutoImportScanComponents) {
      uniQuickAppAutoImportScanComponents = getAutoComponentsByDir(
        path.resolve(require.resolve('@dcloudio/uni-quickapp-native'), '../../components'),
        true
      )
    }
    // 平台内置组件优先级高
    Object.assign(components, uniQuickAppAutoImportScanComponents)
  }

  uniAutoImportScanComponents = parseUsingAutoImportComponents(components)
  refreshAutoComponentMap()
}

const _toString = Object.prototype.toString

function isPlainObject (obj) {
  return _toString.call(obj) === '[object Object]'
}

function initAutoImportComponents (easycom = {}) {
  let usingAutoImportComponents = easycom.custom || easycom || {}
  if (!isPlainObject(usingAutoImportComponents)) {
    usingAutoImportComponents = {}
  }
  // 目前仅 mp-weixin 内置支持 page-meta 等组件
  if (process.env.UNI_PLATFORM !== 'mp-weixin') {
    if (!usingAutoImportComponents['^page-meta$']) {
      usingAutoImportComponents['^page-meta$'] =
        '@dcloudio/uni-cli-shared/components/page-meta.vue'
    }
    if (!usingAutoImportComponents['^navigation-bar$']) {
      usingAutoImportComponents['^navigation-bar$'] =
        '@dcloudio/uni-cli-shared/components/navigation-bar.vue'
    }
  }

  const newUsingAutoImportComponentsJson = JSON.stringify(usingAutoImportComponents)
  if (newUsingAutoImportComponentsJson !== lastUsingAutoImportComponentsJson) {
    lastUsingAutoImportComponentsJson = newUsingAutoImportComponentsJson
    uniAutoImportComponents = parseUsingAutoImportComponents(usingAutoImportComponents)
    refreshAutoComponentMap()
  }
}

/**
 * UNI_AUTO_COMPONENTS 被更新,重新刷新 map
 */
function refreshAutoComponentMap () {
  Object.keys(autoComponentMap).forEach(name => {
    addAutoComponent(name)
  })
}

function addAutoComponent (name) {
  let opt = uniAutoImportComponents.find(opt => opt.pattern.test(name))
  if (!opt) {
    opt = uniAutoImportScanComponents.find(opt => opt.pattern.test(name))
  }
  if (!opt) { // 不匹配
    return (autoComponentMap[name] = true) // cache
  }
  return (autoComponentMap[name] = {
    name,
    identifier: capitalize(camelize(name + '-auto-import')),
    source: name.replace(opt.pattern, opt.replacement)
  })
}

function getAutoComponents (autoComponents) {
  const components = []
  autoComponents.forEach(name => {
    let autoComponent = autoComponentMap[name]
    if (!autoComponent) {
      autoComponent = addAutoComponent(name)
    }
    if (autoComponent !== true) {
      components.push(autoComponent)
    }
  })
  return components
}

function parseUsingAutoImportComponents (usingAutoImportComponents) {
  const autoImportComponents = []
  if (usingAutoImportComponents) {
    Object.keys(usingAutoImportComponents).forEach(pattern => {
      const replacement = usingAutoImportComponents[pattern]
      if (replacement && typeof replacement === 'string') {
        autoImportComponents.push({
          pattern: new RegExp(pattern),
          replacement: replacement
        })
      }
    })
  }
  return autoImportComponents
}
module.exports = {
  getMainEntry,
  getNVueMainEntry,
  parsePages,
  parseEntry,
  getPagesJson,
  parsePagesJson,
  pagesJsonJsFileName,
  getAutoComponents,
  initAutoImportComponents,
  initAutoImportScanComponents,
  addPageUsingComponents,
  getUsingComponentsCode,
  generateUsingComponentsCode,
  getGlobalUsingComponentsCode,
  parseUsingAutoImportComponents,
  generateGlobalUsingComponentsCode
}
<commit_msg>feat(cli): Compatible with subpackages<commit_after>const fs = require('fs')
const path = require('path')

const {
  removeExt,
  normalizePath,
  camelize,
  capitalize
} = require('./util')

const {
  getJson,
  parseJson
} = require('./json')

let mainEntry = ''
let nvueMainEntry = ''

function getMainEntry () {
  if (!mainEntry) {
    mainEntry = fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'main.ts')) ? 'main.ts' : 'main.js'
  }
  return mainEntry
}

function getNVueMainEntry () {
  if (!nvueMainEntry) {
    nvueMainEntry = fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, 'main.js')) ? 'main.js' : '.main.js'
    if (nvueMainEntry === '.main.js') {
      fs.writeFileSync(path.resolve(process.env.UNI_INPUT_DIR, '.main.js'), '')
    }
  }
  return nvueMainEntry
}

function getPagesJson () {
  return processPagesJson(getJson('pages.json', true))
}

function parsePagesJson (content, loader) {
  return processPagesJson(parseJson(content, true), loader)
}

function filterPages (pages = [], root) {
  for (let i = pages.length - 1; i >= 0; i--) {
    const page = pages[i]
    if (!isValidPage(page, root)) {
      pages.splice(i, 1)
    }
  }
}

const pagesJsonJsFileName = 'pages.js'

function processPagesJson (pagesJson, loader = {
  addDependency: function () {}
}) {
  const pagesJsonJsPath = path.resolve(process.env.UNI_INPUT_DIR, pagesJsonJsFileName)
  if (fs.existsSync(pagesJsonJsPath)) {
    delete require.cache[pagesJsonJsPath]
    const pagesJsonJsFn = require(pagesJsonJsPath)
    if (typeof pagesJsonJsFn === 'function') {
      pagesJson = pagesJsonJsFn(pagesJson, loader)
      if (!pagesJson) {
        console.error(`${pagesJsonJsFileName}  必须返回一个 json 对象`)
      }
    } else {
      console.error(`${pagesJsonJsFileName} 必须导出 function`)
    }
  }
  // 将 subpackages 转换成 subPackages
  if (pagesJson.subpackages && !pagesJson.subPackages) {
    pagesJson.subPackages = pagesJson.subpackages
    delete pagesJson.subpackages
  }

  let uniNVueEntryPagePath
  if (pagesJson.pages && pagesJson.pages.length) { // 如果首页是 nvue
    if (isNVuePage(pagesJson.pages[0])) {
      uniNVueEntryPagePath = pagesJson.pages[0].path
    }
  }
  // pages
  filterPages(pagesJson.pages)
  // subPackages
  if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) {
    pagesJson.subPackages.forEach(subPackage => {
      filterPages(subPackage.pages, subPackage.root)
    })
  }

  if (uniNVuePages.length) { // 直接挂在 pagesJson 上
    pagesJson.nvue = {
      pages: uniNVuePages.reverse()
    }
    if (uniNVueEntryPagePath) {
      pagesJson.nvue.entryPagePath = uniNVueEntryPagePath
    }
  }
  return pagesJson
}

function isNVuePage (page, root = '') {
  if (process.env.UNI_PLATFORM === 'app-plus') {
    const pagePath = path.join(root, page.path)
    if (fs.existsSync(path.resolve(process.env.UNI_INPUT_DIR, pagePath + '.nvue'))) { // cache一下结果？如果文件被删除，cache 就会出现错误
      return true
    }
  }
  return false
}

function isValidPage (page, root = '') {
  if (typeof page === 'string') { // 不合法的配置
    console.warn(`${page} 配置错误, 已被忽略, 查看文档: https://uniapp.dcloud.io/collocation/pages?id=pages`)
    return false
  }
  let pagePath = page.path

  if (pagePath.indexOf('platforms') === 0) { // 平台相关
    if (pagePath.indexOf('platforms/' + process.env.UNI_PLATFORM) === -1) { // 非本平台
      return false
    }
  }

  if (
    process.env.UNI_PLATFORM === 'app-plus' &&
    page.style
  ) {
    const subNVues = page.style.subNVues || (page.style['app-plus'] && page.style['app-plus'].subNVues)
    if (Array.isArray(subNVues)) {
      subNVues.forEach(subNVue => {
        let subNVuePath = subNVue.path
        if (subNVuePath) {
          subNVuePath = subNVue.path.split('?')[0]
          const subNVuePagePath = removeExt(path.join(root, subNVuePath))
          process.UNI_NVUE_ENTRY[subNVuePagePath] = getNVueMainJsPath(subNVuePagePath)
        }
      })
    }
  } else {
    page.style && (delete page.style.subNVues)
  }

  if (isNVuePage(page, root)) {
    // 存储 nvue 相关信息
    pagePath = normalizePath(path.join(root, pagePath))

    process.UNI_NVUE_ENTRY[pagePath] = getNVueMainJsPath(pagePath)

    if (process.env.UNI_USING_V3 || process.env.UNI_USING_V3_NATIVE) { // 不移除
      page.nvue = true
      return true
    } else {
      uniNVuePages.push({
        path: pagePath + '.html',
        style: page.style || {}
      })
      return false
    }
  }

  return true
}

function getMainJsPath (page) {
  return path.resolve(process.env.UNI_INPUT_DIR, getMainEntry() + '?' + JSON.stringify({
    page: encodeURIComponent(page)
  }))
}

function getNVueMainJsPath (page) {
  return path.resolve(process.env.UNI_INPUT_DIR, getNVueMainEntry() + '?' + JSON.stringify({
    page: encodeURIComponent(page)
  }))
}

process.UNI_ENTRY = {}
process.UNI_NVUE_ENTRY = {}

const uniNVuePages = []

function parsePages (pagesJson, pageCallback, subPageCallback) {
  if (!pagesJson) {
    pagesJson = getPagesJson()
  }

  // pages
  pagesJson.pages.forEach(page => {
    pageCallback && pageCallback(page)
  })
  // subPackages
  if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) {
    pagesJson.subPackages.forEach((subPackage) => {
      const {
        root,
        pages
      } = subPackage
      pages.forEach(page => {
        root && subPageCallback && subPageCallback(root, page, subPackage)
      })
    })
  }
}

function parseEntry (pagesJson) {
  process.UNI_ENTRY = {
    'common/main': path.resolve(process.env.UNI_INPUT_DIR, getMainEntry())
  }

  process.UNI_SUB_PACKAGES_ROOT = {}

  process.UNI_NVUE_ENTRY = {}

  if (process.env.UNI_USING_NATIVE || process.env.UNI_USING_V3_NATIVE) {
    process.UNI_NVUE_ENTRY['app-config'] = path.resolve(process.env.UNI_INPUT_DIR, 'pages.json')
    process.UNI_NVUE_ENTRY['app-service'] = path.resolve(process.env.UNI_INPUT_DIR, getMainEntry())
  }

  uniNVuePages.length = 0

  if (!pagesJson) {
    pagesJson = getPagesJson() // 会检测修改 nvue entry
  }

  // pages
  pagesJson.pages.forEach(page => {
    process.UNI_ENTRY[page.path] = getMainJsPath(page.path)
  })
  // subPackages
  if (Array.isArray(pagesJson.subPackages) && pagesJson.subPackages.length) {
    pagesJson.subPackages.forEach(({
      root,
      pages
    }) => {
      Array.isArray(pages) && pages.forEach(page => {
        if (root) {
          const pagePath = normalizePath(path.join(root, page.path))
          process.UNI_ENTRY[pagePath] = getMainJsPath(pagePath)
          process.UNI_SUB_PACKAGES_ROOT[pagePath] = root
        }
      })
    })
  }
}

function parseUsingComponents (usingComponents = {}) {
  const components = []
  Object.keys(usingComponents).forEach(name => {
    const identifier = capitalize(camelize(name))
    let source = usingComponents[name]
    if (source.indexOf('/') === 0) { // 绝对路径
      source = '@' + source
    } else if (source.indexOf('.') !== 0) { // 相对路径
      source = './' + source
    }
    components.push({
      name,
      identifier,
      source
    })
  })
  return components
}

function generateUsingComponentsCode (usingComponents) {
  const components = parseUsingComponents(usingComponents)
  const importCode = []
  const componentsCode = []
  components.forEach(({
    name,
    identifier,
    source
  }) => {
    importCode.push(`import ${identifier} from '${source}.vue'`)
    componentsCode.push(`'${name}':${identifier}`)
  })
  if (!importCode.length) {
    return ''
  }
  return `;${importCode.join(';')};exports.default.components=Object.assign({${componentsCode.join(',')}},exports.default.components||{});`
}

function generateGlobalUsingComponentsCode (usingComponents) {
  const components = parseUsingComponents(usingComponents)
  const importCode = []
  const componentsCode = []
  components.forEach(({
    name,
    identifier,
    source
  }) => {
    importCode.push(`import ${identifier} from '${source}.vue'`)
    componentsCode.push(`Vue.component('${name}',${identifier})`)
  })
  if (!importCode.length) {
    return ''
  }
  return `${importCode.join(';')};${componentsCode.join(';')};`
}

function getGlobalUsingComponentsCode () {
  const pagesJson = getPagesJson()
  const usingComponents = pagesJson.globalStyle && pagesJson.globalStyle.usingComponents
  if (!usingComponents) {
    return ''
  }
  return generateGlobalUsingComponentsCode(usingComponents)
}

function getUsingComponentsCode (pagePath) {
  const usingComponents = usingComponentsPages[pagePath]
  if (!usingComponents) {
    return ''
  }
  return generateUsingComponentsCode(usingComponents)
}

const usingComponentsPages = Object.create(null)

function addPageUsingComponents (pagePath, usingComponents) {
  if (usingComponents && Object.keys(usingComponents).length) {
    usingComponentsPages[pagePath] = usingComponents
  }
}
// 存储自动组件
const autoComponentMap = {}

let lastUsingAutoImportComponentsJson = ''

let uniAutoImportComponents = []

let uniAutoImportScanComponents = []

let uniQuickAppAutoImportScanComponents = false

const isDirectory = source => fs.lstatSync(source).isDirectory()

function getAutoComponentsByDir (componentsPath, absolute = false) {
  const components = {}
  try {
    fs.existsSync(componentsPath) && fs.readdirSync(componentsPath).forEach(name => {
      const folder = path.resolve(componentsPath, name)
      if (!isDirectory(folder)) {
        return
      }
      const importDir = absolute ? normalizePath(folder) : `@/components/${name}`
      // 读取文件夹文件列表，比对文件名（fs.existsSync在大小写不敏感的系统会匹配不准确）
      const files = fs.readdirSync(folder)
      if (files.includes(name + '.vue')) {
        components[`^${name}$`] = `${importDir}/${name}.vue`
      } else if (files.includes(name + '.nvue')) {
        components[`^${name}$`] = `${importDir}/${name}.nvue`
      }
    })
  } catch (e) {
    console.log(e)
  }
  return components
}

function initAutoImportScanComponents () {
  const componentsPath = path.resolve(process.env.UNI_INPUT_DIR, 'components')

  const components = getAutoComponentsByDir(componentsPath)

  if (process.env.UNI_PLATFORM === 'quickapp-native') {
    if (!uniQuickAppAutoImportScanComponents) {
      uniQuickAppAutoImportScanComponents = getAutoComponentsByDir(
        path.resolve(require.resolve('@dcloudio/uni-quickapp-native'), '../../components'),
        true
      )
    }
    // 平台内置组件优先级高
    Object.assign(components, uniQuickAppAutoImportScanComponents)
  }

  uniAutoImportScanComponents = parseUsingAutoImportComponents(components)
  refreshAutoComponentMap()
}

const _toString = Object.prototype.toString

function isPlainObject (obj) {
  return _toString.call(obj) === '[object Object]'
}

function initAutoImportComponents (easycom = {}) {
  let usingAutoImportComponents = easycom.custom || easycom || {}
  if (!isPlainObject(usingAutoImportComponents)) {
    usingAutoImportComponents = {}
  }
  // 目前仅 mp-weixin 内置支持 page-meta 等组件
  if (process.env.UNI_PLATFORM !== 'mp-weixin') {
    if (!usingAutoImportComponents['^page-meta$']) {
      usingAutoImportComponents['^page-meta$'] =
        '@dcloudio/uni-cli-shared/components/page-meta.vue'
    }
    if (!usingAutoImportComponents['^navigation-bar$']) {
      usingAutoImportComponents['^navigation-bar$'] =
        '@dcloudio/uni-cli-shared/components/navigation-bar.vue'
    }
  }

  const newUsingAutoImportComponentsJson = JSON.stringify(usingAutoImportComponents)
  if (newUsingAutoImportComponentsJson !== lastUsingAutoImportComponentsJson) {
    lastUsingAutoImportComponentsJson = newUsingAutoImportComponentsJson
    uniAutoImportComponents = parseUsingAutoImportComponents(usingAutoImportComponents)
    refreshAutoComponentMap()
  }
}

/**
 * UNI_AUTO_COMPONENTS 被更新,重新刷新 map
 */
function refreshAutoComponentMap () {
  Object.keys(autoComponentMap).forEach(name => {
    addAutoComponent(name)
  })
}

function addAutoComponent (name) {
  let opt = uniAutoImportComponents.find(opt => opt.pattern.test(name))
  if (!opt) {
    opt = uniAutoImportScanComponents.find(opt => opt.pattern.test(name))
  }
  if (!opt) { // 不匹配
    return (autoComponentMap[name] = true) // cache
  }
  return (autoComponentMap[name] = {
    name,
    identifier: capitalize(camelize(name + '-auto-import')),
    source: name.replace(opt.pattern, opt.replacement)
  })
}

function getAutoComponents (autoComponents) {
  const components = []
  autoComponents.forEach(name => {
    let autoComponent = autoComponentMap[name]
    if (!autoComponent) {
      autoComponent = addAutoComponent(name)
    }
    if (autoComponent !== true) {
      components.push(autoComponent)
    }
  })
  return components
}

function parseUsingAutoImportComponents (usingAutoImportComponents) {
  const autoImportComponents = []
  if (usingAutoImportComponents) {
    Object.keys(usingAutoImportComponents).forEach(pattern => {
      const replacement = usingAutoImportComponents[pattern]
      if (replacement && typeof replacement === 'string') {
        autoImportComponents.push({
          pattern: new RegExp(pattern),
          replacement: replacement
        })
      }
    })
  }
  return autoImportComponents
}
module.exports = {
  getMainEntry,
  getNVueMainEntry,
  parsePages,
  parseEntry,
  getPagesJson,
  parsePagesJson,
  pagesJsonJsFileName,
  getAutoComponents,
  initAutoImportComponents,
  initAutoImportScanComponents,
  addPageUsingComponents,
  getUsingComponentsCode,
  generateUsingComponentsCode,
  getGlobalUsingComponentsCode,
  parseUsingAutoImportComponents,
  generateGlobalUsingComponentsCode
}
<|endoftext|>