Inserting specific file at index of a stream - gulp

Basicly this gulp script finds the 'file1,file2,file3' in a folder, builds its dependencies (which are in the same folder) and add it all to 1 file.
Now, my problem is, i have a custom file which i have to put in after file2. How can i achieve this?
function gatherAMD(stream, file) {
var moduleId = file.path.match(/file\.(.+)\.js/)[1];
return stream.pipe(amdOptimize(`file.${moduleId}`, {
baseUrl: "fileslocation/location",
exclude: [ 'jquery' ]
}));
}
gulp.task("js", function() {
var included = [];
var files = "file1,file2,file3"
var stream = null;
if (files.indexOf(",") == -1) {
stream = gulp.src('fileslocation/location/file.'+ files+ '.js', { base: "fileslocation/location"});
} else {
stream = gulp.src(`fileslocation/location/file.{${files}}.js`, { base: "fileslocation/location"});
}
return stream.pipe(debug())
.pipe(foreach(gatherAMD))
.pipe(filter(function(file) {
if (included.indexOf(file.path) === -1) {
included.push(file.path);
return true;
} else {
return false;
}
}))
.pipe(concat({path: 'fileslocation/custom.js', base: 'fileslocation'}))
.pipe(gulp.dest("fileslocation"));
});

You can probably use map for checking the current file in the stream, and then adding it from some logic and then using gulp-inject to add a file to the stream.
Something like,
return stream.pipe(debug())
.pipe(foreach(gatherAMD))
.pipe(filter(function(file) {
if (included.indexOf(file.path) === -1) {
included.push(file.path);
return true;
} else {
return false;
}
}))
.pipe(map(function(file, callback) {
if (file.relative === 'file2.js') {
// inject file to the stream here
}
callback(null, file);
}))
.pipe(concat({path: 'fileslocation/custom.js', base: 'fileslocation'}))
.pipe(gulp.dest("fileslocation"));

Related

How to add multiple files from server response to zip file in Angular

exportIcsReportInJSONFormat() {
this.icsService.getICSReport()
.pipe(takeUntil(this.notifier))
.subscribe(response =>{
const icsReport =new Blob([response], { type: 'text/json;charset=utf-8' });
saveAs(icsReport, 'ics-report_' + new Date().toISOString() + '.json')}
);
}
exportIcsReportInCSVFormat() {
this.icsService.getICSReport()
.subscribe(
response => {
const csv = this.convertJSONToCSV(response);
const csvBlob = new Blob([csv], { type: 'text/json;charset=utf-8' });
saveAs(csvBlob, 'ics-report_' + new Date().toISOString() + '.csv');
});
}
exportIcsReportInTSEFormat() {
this.icsService.getTse()
.pipe(takeUntil(this.notifier))
.subscribe(tse => saveAs(tse, 'ics-report_' + new Date().toISOString() + '.tse'));
}
Calling the functions here to generate the files and adding them to zip:
getReports() {
const zip: JSZip = new JSZip();
this.selectedReportFormats.forEach(element => {
if (element == 'JSON') {
const JSONFile = this.exportIcsReportInJSONFormat();
zip.file("JSONFile");
}
if (element == 'CSV') {
const CSVFile = this.exportIcsReportInCSVFormat();
zip.file("CSVFile");
}
if (element == 'TSE') {
const TESFile = this.exportIcsReportInTSEFormat();
zip.file("TESFile");
}
zip.generateAsync({type:"blob"})
.then(function(content) {
// see FileSaver.js
saveAs(content, "example.zip");
});
});
}
I am doing it wrong because I can't find proper syntax to add files to zip kind of using a loop. This scenario is basically I want to download a report and I have 3 options JSON, CSV and TSE. So I have a checkbox and the options I check and click on Download I get files in all those formats added to zip and downloaded in a ZIP file.

Merge mixin in vue

I'm working in vue/quasar application.
I've my mixin like this in my view.cshtml
var mixin1 = {
data: function () {
return { data1:0,data2:'' }
}
,
beforeCreate: async function () {
...}
},
methods: {
addformulaire(url) {
},
Kilometrique() { }
}
}
And I want merge with my content in js file (it's to centralize same action an severals cshtml)
const nomeMixins = {
data: function () {
return { loadingcdt: false, lstclt: [], filterclient: [], loadingdoc: false, lstdoc: [], filterdoc: [] }
},
computed: {
libmntpiece(v) { return "toto"; }
},
methods: {
findinfcomplemtX3(cdecltx3, cdedocx3) {
},
preremplissagex3: async function (cdecltx3, cdedocx3) {
}
}
}
};
I want merge this 2 miwin in one. But when I try assign or var mixin = { ...mixin1, ...nomeMixins };
I've only mixin1 nothing about methods,data from my js file nomeMixins but merging failed cause I've same key in my json object. I'm trying to make a foreach but failed too
Someone try to merge to mixin / json object with same key in the case you've no double child property ?
You cant merge mixins in that way. the spread syntax will overwrite keys e.g data, computed, methods etc and final result will not be suitable for your purpose.
refer documentation for adding mixins in your component. Also note that You can easily add multiple mixins in any component, so I don't think combination of two mixins will be any useful.
UPDATE
reply to YannickIngenierie answer and pointing out mistakes in this article
Global Mixins are not declared like this
// not global mixin; on contrary MyMixin is local
// and only available in one component.
new Vue({
el: '#demo',
mixins: [MyMixin]
});
Local Mixins are not declared like this
// NOT local mixin; on contrary its global Mixin
// and available to all components
const DataLoader = Vue.mixin({....}}
Vue.component("article-card", {
mixins: [DataLoader], // no need of this
template: "#article-card-template",
created() {
this.load("https://jsonplaceholder.typicode.com/posts/1")
}
});
Point is refer documentation first before reading any article written by some random guy, including me. Do slight comparison what he is saying whats in documentation.
After working and searching... I find this one And understand that I can add directly mixin in my compoment (don't laught I'm begging with vue few months ago)
my custommiwin.js
const DataLoader = Vue.mixin({
data: function () {
return { loadingcdt: false, lstclt: [], filterclient: [], loadingdoc: false, lstdoc: [], filterdoc: [] }
},
methods: {
filterClt: async function (val, update, abort) {
if (val.length < 3) { abort(); return; }
else {//recherche
this.loadingcdt = true;
let res = await axios...
this.loadingcdt = false;
}
update(() => {
const needle = val.toLowerCase();
this.filterclient = this.lstclt.filter(v => v.libelle.toLowerCase().indexOf(needle) > -1 || v.id.toLowerCase().indexOf(needle) > -1);
})
},
filterDocument: async function (val, update, abort, cdecltx3) {
if (!cdecltx3 || val.length < 3) { abort(); return; }
else {//recherche
this.loadingdoc = true;
let res = await axios({ ...) }
this.loadingdoc = false;
}
update(() => {
const needle = val.toLowerCase();
this.filterdoc = this.lstdoc.filter(v => v.id.toLowerCase().indexOf(needle) > -1);
})
},
}
});
and in my compoment.js I add this
mixins: [DataLoader],
I include all my js file in my cshtml file

webpack : is there a good hook / custom function to dump out resolved configuration?

I'm somewhat of a newbie with webpack and have been experimenting with easier ways to adjust/merge webpack configurations.
The following code, added to webpack/lib/webpack.js has been pretty helpful:
this is the standard webpack.js:
function webpack(options, callback) {
var compiler;
if(Array.isArray(options)) {
compiler = new MultiCompiler(options.map(function(options) {
return webpack(options);
}));
} else if(typeof options === "object") {
new WebpackOptionsDefaulter().process(options);
compiler = new Compiler();
compiler.options = options;
compiler.options = new WebpackOptionsApply().process(options, compiler);
new NodeEnvironmentPlugin().apply(compiler);
compiler.applyPlugins("environment");
compiler.applyPlugins("after-environment");
} else {
throw new Error("Invalid argument: options");
}
if(callback) {
if(typeof callback !== "function") throw new Error("Invalid argument: callback");
if(options.watch === true || (Array.isArray(options) &&
options.some(function(o) {
return o.watch;
}))) {
var watchOptions = (!Array.isArray(options) ? options : options[0]).watchOptions || {};
// TODO remove this in next major version
var watchDelay = (!Array.isArray(options) ? options : options[0]).watchDelay;
if(watchDelay) {
console.warn("options.watchDelay is deprecated: Use 'options.watchOptions.aggregateTimeout' instead");
watchOptions.aggregateTimeout = watchDelay;
}
return compiler.watch(watchOptions, callback);
}
compiler.run(callback);
}
this is my code:
//customization start
fs = require('fs');
var fnp_dump = 'webpack.dump.json';
fs.writeFile(fnp_dump, JSON.stringify(options, null, 2), function(err) {
if(err) {
return console.log(err);
}
console.log("dumping dump.webpack.js.final.json from webpack.js to: " + fnp_dump);
});
//customization end
return compiler;
}
The basic idea is that it dumps out the final json/js options object after webpack has finished sorting out the usual webpack.base.js + webpack.development.js. Since it's, at that point, just a fully-resolved javascript object, it doesn't really matter how the config.js files were written by individual developers.
Now you can diff options sent to webpack (this is an example of tranforming webpack 1 to webpack 2 configurations:
diff 003/webpack.dump.json 004/webpack.dump.json
< "loader": "style!css!postcss-loader!sass"
---
> "use": [
> {
> "loader": "style-loader"
> },
> {
> "loader": "postcss-loader"
> },
> {
> "loader": "sass-loader"
> }
> ]
However, I am customizing webpack.js directly and need to re-apply my patch after each npm update webpack. Is there a better way?
If your webpack.config.js is a function, you can call it on your own to resolve to an object.
If you have several configs (you mentioned webpack.base.js and webpack.development.js) you can use Webpack Merge to just combine your options to a single object, and then write it to the file system.
I would recommend you to have an own script in package.json to do this job, which you can then always call after your webpack job:
...,
"scripts": {
"dump-options": "scriptThatMergesConfigsAndWritesToFS.js",
"webpack-job": "webpack ... && npm run dump-options",
...
},
...
UPDATE
After some more research I realized, that the resolved options object is stored in the compiler object. The compiler object is passed to Plugins, and therefore you can easily write a Plugin that writes the config to a file, as I did here (not tested).
I also realized, that the Plugins cannot be stringified, as they are functions, so be aware of losing the Plugin configuration information.
I ended up writing my own plugin (and now notice that wtho wrote one too). It worked for me - note you need to have the bit of code that handles circular references:
// WebPackCompilationObserver.js
function WebPackCompilationObserver(options) {
WebPackCompilationObserver.options = options || {};
}
WebPackCompilationObserver.prototype.apply = function(compiler) {
compiler.plugin("emit", function(compilation, callback) {
var fs = require('fs');
var fnp_dump = WebPackCompilationObserver.options.dump_filename;
if (! fnp_dump) {
fnp_dump = "./dump.webpack.options.json";
console.log("please specify dump_filename path in the WebPackCompilationObserver.options, otherwise using default:" % fnp_dump);
}
if (fnp_dump){
console.log("dumping compilation.options to: " + fnp_dump);
var cache = [];
fs.writeFile(fnp_dump, JSON.stringify(compilation.options, function(key, value) {
if (typeof value === 'object' && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
// Store value in our collection
cache.push(value);
}
return value;
}, 2),
function(err) {
if (err) {
return console.log(err);
}
});
cache = null;
}
callback();
});
};
module.exports = WebPackCompilationObserver;
To use it:
webpack.config.development.js:
....
var WebPackCompilationObserver = require("./WebPackCompilationObserver");
....
config.plugins = config.plugins.concat([
....
,new WebPackCompilationObserver({dump_filename: '../dumpithere.json'})
])

Setting data in viewModel knockoutjs from html5 websocket

I am trying to create knockout.js component that is getting data from HTML5 Websocket. Websocket code is in separate script e.g. util.js. I am able to connect and get data from socket, but dont know how correctly to set corresponding property in component`s ViewModel.
Websocket - util.js:
var options = {
server: '127.0.0.1',
port: '12345'
};
var socket, loadedFlag;
var timeout = 2000;
var clearTimer = -1;
var data = {};
function handleErrors(sError, sURL, iLine)
{
return true;
};
function getSocketState()
{
return (socket != null) ? socket.readyState : 0;
}
function onMessage(e)
{
data=$.parseJSON(e.data);
// ???? Is it possible to have here something like
// ???? viewModel.getDataWS1(data);
}
function onError()
{
clearInterval(clearTimer);
socket.onclose = function () {
loadedFlag = false;
};
clearTimer = setInterval("connectWebSocket()", timeout);
}
function onClose()
{
loadedFlag = false;
clearInterval(clearTimer);
clearTimer = setInterval("connectWebSocket()", timeout);
}
function onOpen()
{
clearInterval(clearTimer);
console.log("open" + getSocketState());
}
function connectWebSocket()
{
if ("WebSocket" in window)
{
if (getSocketState() === 1)
{
socket.onopen = onOpen;
clearInterval(clearTimer);
console.log(getSocketState());
}
else
{
try
{
host = "ws://" + options.server + ":" + options.port;
socket = new WebSocket(host);
socket.onopen = onOpen;
socket.onmessage = function (e) {
onMessage(e);
};
socket.onerror = onError;
socket.onclose = onClose;
}
catch (exeption)
{
console.log(exeption);
}
}
}
}
Component (productDisplay.js) - creating so that is can be used on multiple pages:
define([
'jquery',
'app/models/productDisplayModel',
'knockout',
'mapping',
'socket'
],
function ($, model, ko, mapping) {
ko.components.register('product', {
viewModel: {require: 'app/models/productModel'},
template: {require: 'text!app/views/product.html'}
});
});
Product ViewModel (productModel.js) - where I struggle to set viewModel property to data from websocket:
var viewModel = {};
define(['knockout', 'mapping', 'jquery'], function (ko, mapping, $) {
function Product(name, rating) {
this.name = name;
this.userRating = ko.observable(rating || null);
}
function MyViewModel() {
this.products = ko.observableArray(); // Start empty
}
MyViewModel.prototype.getDataWS1 = function () {
//Websocket has not connected and returned data yet, so data object is empty
// ???? Is there anyway I can add something like promise so that the value is set once socket is connected?
this.products(data);
};
// apply binding on page load
$(document).ready(function () {
connectToServer1();
viewModel = new MyViewModel();
ko.applyBindings(viewModel);
viewModel.getDataWS1();
});
});
Thank you for any ideas.
You can update an observable when you get a message in the following manner:
util.js
function onMessage(e) {
var productData = $.parseJSON(e.data);
viewModel.addNewProduct(productData);
}
productModel.js
function Product(name, rating) {
this.name = name;
this.userRating = ko.observable(rating || null);
}
function MyViewModel() {
this.products = ko.observableArray(); // Start empty
}
MyViewModel.prototype.addNewProduct(product) {
var newProduct = new Product(product.name, product.rating);
this.products.push(newProduct);
}
Basically the idea is that when you get a message (in onMessage function), you will parse the data and call a function in your viewmodel to add the message data to the viewmodel properties (observables, observableArrays, etc.)

Unable to dynamically load Json Arrays from JSP to a Jstree

I was trying to make a simple LDAP client to just retrieve the data from an LDAP server. I am returning array of JSON objects from the JSP. On click of any value I will get some data from online server. I am able to load the first set of array into a tree. The arrays got in the next step dont get attached to the JSTree. My codes:
function getGroupsStructure(id) {
console.log("in getGroupsStructure-->");
var paramId = "";
if(id == '') {
console.log("in if-->");
paramId = "c=de";
} else {
console.log("in else-->");
paramId = id;
}
var params = {
"DN" : paramId,
};
console.log("params-->",params);
var getGroupsStructureForUserService = service(webURL + "sendingValues/getGroupsStructureForUser",params,"POST");
getGroupsStructureForUserService.success(function(data) {
console.log("in success-->dta-->",data);
if(data.errorCode == '0') {
console.log("in error code 0-->dta-->",data.treeData);
$('.treeNode').jstree({
'core': {
'data': function (obj, cb) {
cb.call(this,
data.treeData);
}
}
});
console.log("Tree Created...");
} else {
console.log("error code not 0--data-->",data);
}
$(document).off('click').on('click', '.treeNode a', function() {
console.log("on click of a-->");
var id = $(this).parent().attr('id');
console.log("id-->",id);
getGroupsStructure(id);
console.log("after getGroupsStructure");
});
});
getGroupsStructureForUserService.error(function(data) {
console.log(" empty error");
// console.log(err);
});
}
The JSP Code is
def NextLevelLDAP(String DN) {
// println "Next Level===>"
assert ldap!=null
def responseArray=[]
def results=ldap.search('objectClass=*',DN,SearchScope.ONE) //Will be triggered when + is pressed in GUI to get next level of tree
// assert results==null
if(DN.startsWith("c="))
{
JSONObject responseJson1=new JSONObject()
responseJson1.put("id", initialDN )
responseJson1.put("parent", "#")
responseJson1.put("text","Parent")
responseArray.add(responseJson1)
for(entry in results) {
// println entry
// println "In NextLevel Using InitialDN"
JSONObject responseJson=new JSONObject()
responseJson.put("id", entry.dn)
responseJson.put("parent", DN)
String tempResDN=entry.dn.toString()
def tempLength=tempResDN.length() - DN.length()
// println tempResDN
String tempName=tempResDN.substring(2,tempLength-1)
// println tempName
responseJson.put("text",tempName)
responseArray.add(responseJson)
// println entry
println responseJson.toString()
}
return responseArray
}
if(results.size!=0)
{
for(entry in results) {
println entry
JSONObject responseJson=new JSONObject()
responseJson.put("id", entry.dn)
responseJson.put("parent", DN)
String tempResDN=entry.dn.toString()
def tempLength=tempResDN.length() - DN.length()
// println tempResDN
String tempName=tempResDN.substring(2,tempLength-1)
println tempName
responseJson.put("text",tempName)
responseArray.add(responseJson)
// println entry
}
return responseArray
}
}
Please Ignore the way of getting the Parent ID. Its Something COmplicated.
Please help me out how do I get The tree nodes created dynamically. I am just getting the fist level of the tree. The data on click for other levels is being shown in the console but not getting attached to the tree.
Thank you.
You have it the other way around - you need to create the tree and have it make the request for you, so instead of this:
'data': function (obj, cb) {
cb.call(this, data.treeData);
}
Use something like this:
'data': function (obj, cb) {
// you probably need to pass the obj.id as a parameter to the service
// keep in mind if obj.id is "#" you need to return the root nodes
service(...).success(function (data) {
cb.call(this, data.treeData);
});
}
This way you do not need to detach and reattach click handlers every time and it will work out of the box for opening nodes. If you want to open a node on click, you can use this:
$('#tree').on('select_node.jstree', function (e, data) {
data.instance.open_node(data.node);
});
So your whole code should look something like this:
function load(id) {
var params = {
"DN" : id && id !== '#' ? id : "c=de"
};
return service(webURL + "sendingValues/getGroupsStructureForUser", params, "POST");
}
$('#tree')
.jstree({
'core' : {
'data': function (obj, cb) {
load(obj.id).success(function (data) {
cb.(data.treeData);
});
}
}
})
.on('select_node.jstree', function (e, data) {
data.instance.open_node(data.node);
});
Just make sure you mark the nodes your return as having children (set their children property to boolean true).