');
154 | });
155 | }
156 |
157 | function fetchLanguages(callBack) {
158 | //fetch supported languages
159 | io.socket.get('/chat/languages', {}, function(data) {
160 | languageMapping = data.languageMapping;
161 |
162 | var rendered = Mustache.render($('#language-select').html(),
163 | { languages: data.languages }
164 | );
165 |
166 | $('.languages-select').html(rendered);
167 |
168 | callBack();
169 | });
170 | }
171 |
172 | function autoDetectLanguage() {
173 | var code = window.navigator.userLanguage || window.navigator.language;
174 |
175 | var option = $(".languages-select option[data-code='" + code +"']");
176 |
177 | if(option.length === 0) {
178 | console.log('Language code '+ code +' was not found. Defaulting to English');
179 | $('.languages-select').val('en').change();
180 | } else {
181 | $('.languages-select').val(code).change();
182 | }
183 | }
184 |
185 | function getCookie(name) {
186 | var value = "; " + document.cookie;
187 | var parts = value.split("; " + name + "=");
188 | if (parts.length == 2) return parts.pop().split(";").shift();
189 | }
190 |
--------------------------------------------------------------------------------
/assets/js/chat.js:
--------------------------------------------------------------------------------
1 | function renderMessage(message) {
2 | var lang = $('#current-language').val();
3 |
4 | if(message.user.id === currentUser.id) {
5 | var rendered = Mustache.render($('#chat-message-yourself').html(), message);
6 |
7 | $('.chat-messages').append(rendered);
8 |
9 | updateScroll();
10 |
11 | $('.chat-messages').linkify({
12 | target: "_blank"
13 | });
14 | } else {
15 | translateText(message.body, lang).done(function(res) {
16 | var rendered = Mustache.render($('#chat-message').html(), {
17 | shortName: message.user.name.substr(0, 1),
18 | body: res,
19 | originalLanguage: languageMapping[res.detectedSourceLanguage],
20 | translate: (lang != res.detectedSourceLanguage)
21 | });
22 |
23 | $('.chat-messages').append(rendered);
24 |
25 | $('.chat-messages').linkify({
26 | target: "_blank"
27 | });
28 | });
29 | }
30 | }
31 |
32 | function renderMessages(messages) {
33 | var lang = $('#current-language').val();
34 |
35 | messages.forEach(function(message) {
36 | if(message.user.id === currentUser.id) {
37 | var params = { body: message.originalBody }
38 |
39 | var rendered = Mustache.render($('#chat-message-yourself').html(), params);
40 |
41 | $('.chat-messages').append(rendered);
42 | } else {
43 | var rendered = Mustache.render($('#chat-message').html(), {
44 | shortName: message.user.name.substr(0, 1),
45 | body: {translatedText: message.body, originalText: message.originalBody},
46 | originalLanguage: languageMapping[message.sourceLanguage],
47 | translate: (lang != message.sourceLanguage)
48 | });
49 |
50 | $('.chat-messages').append(rendered);
51 | }
52 |
53 | $('.chat-messages').linkify({
54 | target: "_blank"
55 | });
56 | });
57 |
58 | $('.messages.loading-indicator').addClass('hide');
59 |
60 | updateScroll();
61 | }
62 |
63 | // Render User has joined message
64 | function renderUserJoinedMessage(message) {
65 | var template = Mustache.render($('#joined-message').html(), {
66 | shortName: message.data.name.substr(0, 1),
67 | name: message.data.name
68 | });
69 |
70 | $('.chat-messages').append(template);
71 | }
72 |
73 | function renderLeftRoomMessage(message){
74 | var template = Mustache.render($('#left-message').html(), message.previous);
75 |
76 | $('.chat-messages').append(template);
77 | }
78 |
79 | function renderWelcomeMessage(username, force) {
80 | var lang = $('#current-language').val();
81 |
82 | if($('#received-welcome').val() === 'false' || force) {
83 | return $.ajax({
84 | url: "chat/welcome",
85 | data: { username: $('#username').val()}
86 | }).done(function(res) {
87 | translateText(res.welcome_message, $('#current-language').val()).done(function(res) {
88 | var template = Mustache.render($('#welcome-message').html(), {
89 | username: username,
90 | translatedText: res.translatedText,
91 | originalText: res.originalText,
92 | translate: (lang != res.detectedSourceLanguage)
93 | });
94 |
95 | $('.chat-messages').append(template);
96 | $('#received-welcome').val('true');
97 | });
98 | });
99 |
100 | }
101 | }
102 |
103 | function updateUserCount(data) {
104 | $('#random-active').text(data.count);
105 | }
106 |
107 | function submitMessage(message) {
108 | io.socket.post('/message', { body: message, sourceLanguage: $('#current-language').val() }, function(err, data) {
109 | if(err) { return console.log(err); }
110 | });
111 | }
112 |
113 | //used to update chat window scroll when new messages are added
114 | function updateScroll(){
115 | var element = document.getElementById("messages-scrollable");
116 | element.scrollTop = element.scrollHeight;
117 | }
118 |
119 | function promptUsername(callBack) {
120 | var username = prompt("Please enter your name", "");
121 |
122 | if (username == null) {
123 | promptUsername(callBack);
124 | } else {
125 | $('#username').val(username);
126 |
127 | callBack(username);
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/assets/js/dependencies/linkify-jquery.min.js:
--------------------------------------------------------------------------------
1 | "use strict";!function(e,t,n){var i=function(t,n){function i(e,t,n){var i=n[n.length-1];e.replaceChild(i,t);for(var r=n.length-2;r>=0;r--)e.insertBefore(n[r],i),i=n[r]}function r(e,t,n){for(var i=[],r=e,a=Array.isArray(r),o=0,r=a?r:r[Symbol.iterator]();;){var l;if(a){if(o>=r.length)break;l=r[o++]}else{if(o=r.next(),o.done)break;l=o.value}var f=l;if("nl"===f.type&&t.nl2br)i.push(n.createElement("br"));else if(f.isLink&&t.check(f)){var s=t.resolve(f),c=s.formatted,u=s.formattedHref,d=s.tagName,m=s.className,y=s.target,h=s.events,k=s.attributes,v=n.createElement(d);if(v.setAttribute("href",u),m&&v.setAttribute("class",m),y&&v.setAttribute("target",y),k)for(var g in k)v.setAttribute(g,k[g]);if(h)for(var b in h)v.addEventListener?v.addEventListener(b,h[b]):v.attachEvent&&v.attachEvent("on"+b,h[b]);v.appendChild(n.createTextNode(c)),i.push(v)}else i.push(n.createTextNode(f.toString()))}return i}function a(e,t,n){if(!e||e.nodeType!==d)throw new Error("Cannot linkify "+e+" - Invalid DOM Node type");var o=t.ignoreTags;if("A"===e.tagName||s.contains(o,e.tagName))return e;for(var l=e.firstChild;l;){switch(l.nodeType){case d:a(l,t,n);break;case m:var c=l.nodeValue,y=f(c);if(0===y.length||1===y.length&&y[0]instanceof u)break;var h=r(y,t,n);i(e,l,h),l=h[h.length-1]}l=l.nextSibling}return e}function o(t,n){var i=arguments.length>2&&void 0!==arguments[2]&&arguments[2];try{i=i||document||e&&e.document||global&&global.document}catch(r){}if(!i)throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the third argument to linkifyElement.");return n=new c(n),a(t,n,i)}function l(t){function n(e){return e=o.normalize(e),this.each(function(){o.helper(this,e,i)})}var i=arguments.length>1&&void 0!==arguments[1]&&arguments[1];t.fn=t.fn||{};try{i=i||document||e&&e.document||global&&global.document}catch(r){}if(!i)throw new Error("Cannot find document implementation. If you are in a non-browser environment like Node.js, pass the document implementation as the second argument to linkify/jquery");"function"!=typeof t.fn.linkify&&(t.fn.linkify=n,t(i).ready(function(){t("[data-linkify]").each(function(){var e=t(this),n=e.data(),i=n.linkify,r=n.linkifyNlbr,a={attributes:n.linkifyAttributes,defaultProtocol:n.linkifyDefaultProtocol,events:n.linkifyEvents,format:n.linkifyFormat,formatHref:n.linkifyFormatHref,nl2br:!!r&&0!==r&&"false"!==r,tagName:n.linkifyTagname,target:n.linkifyTarget,className:n.linkifyClassName||n.linkifyLinkclass,validate:n.linkifyValidate,ignoreTags:n.linkifyIgnoreTags},o="this"===i?e:e.find(i);o.linkify(a)})}))}t="default"in t?t["default"]:t;var f=n.tokenize,s=n.options,c=s.Options,u=n.parser.TOKENS.TEXT,d=1,m=3;o.helper=a,o.normalize=function(e){return new c(e)};try{!define&&(e.linkifyElement=o)}catch(y){}return l}(n,t);"function"!=typeof n.fn.linkify&&i(n)}(window,linkify,jQuery);
--------------------------------------------------------------------------------
/assets/js/dependencies/linkify.min.js:
--------------------------------------------------------------------------------
1 | !function(){"use strict";var t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};!function(e){function n(t,e){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=Object.create(t.prototype);for(var a in n)o[a]=n[a];return o.constructor=e,e.prototype=o,e}function o(t){t=t||{},this.defaultProtocol=t.defaultProtocol||h.defaultProtocol,this.events=t.events||h.events,this.format=t.format||h.format,this.formatHref=t.formatHref||h.formatHref,this.nl2br=t.nl2br||h.nl2br,this.tagName=t.tagName||h.tagName,this.target=t.target||h.target,this.validate=t.validate||h.validate,this.ignoreTags=[],this.attributes=t.attributes||t.linkAttributes||h.attributes,this.className=t.className||t.linkClass||h.className;for(var e=t.ignoreTags||h.ignoreTags,n=0;n=r)return[];for(;a1&&void 0!==arguments[1]?arguments[1]:null,n=this.next(new t(""));return n===this.defaultTransition?(n=new this.constructor(e),this.on(t,n)):e&&(n.T=e),n},test:function(t,e){return t instanceof e}}),b=l();b.prototype={toString:function(){return this.v+""}};var v=u(),y=u("@"),k=u(":"),w=u("."),j=u(),x=u(),z=u("\n"),O=u(),S=u("+"),N=u("#"),T=u(),A=u("mailto:"),L=u("?"),E=u("/"),C=u("_"),P=u(),R=u(),q=u(),H=u("{"),B=u("["),U=u("<"),M=u("("),D=u("}"),I=u("]"),K=u(">"),_=u(")"),G=u("&"),Y=Object.freeze({Base:b,DOMAIN:v,AT:y,COLON:k,DOT:w,PUNCTUATION:j,LOCALHOST:x,NL:z,NUM:O,PLUS:S,POUND:N,QUERY:L,PROTOCOL:T,MAILTO:A,SLASH:E,UNDERSCORE:C,SYM:P,TLD:R,WS:q,OPENBRACE:H,OPENBRACKET:B,OPENANGLEBRACKET:U,OPENPAREN:M,CLOSEBRACE:D,CLOSEBRACKET:I,CLOSEANGLEBRACKET:K,CLOSEPAREN:_,AMPERSAND:G}),Q="aaa|aarp|abb|abbott|abogado|ac|academy|accenture|accountant|accountants|aco|active|actor|ad|adac|ads|adult|ae|aeg|aero|af|afl|ag|agency|ai|aig|airforce|airtel|al|alibaba|alipay|allfinanz|alsace|am|amica|amsterdam|an|analytics|android|ao|apartments|app|apple|aq|aquarelle|ar|aramco|archi|army|arpa|arte|as|asia|associates|at|attorney|au|auction|audi|audio|author|auto|autos|avianca|aw|ax|axa|az|azure|ba|baidu|band|bank|bar|barcelona|barclaycard|barclays|bargains|bauhaus|bayern|bb|bbc|bbva|bcg|bcn|bd|be|beats|beer|bentley|berlin|best|bet|bf|bg|bh|bharti|bi|bible|bid|bike|bing|bingo|bio|biz|bj|black|blackfriday|bloomberg|blue|bm|bms|bmw|bn|bnl|bnpparibas|bo|boats|boehringer|bom|bond|boo|book|boots|bosch|bostik|bot|boutique|br|bradesco|bridgestone|broadway|broker|brother|brussels|bs|bt|budapest|bugatti|build|builders|business|buy|buzz|bv|bw|by|bz|bzh|ca|cab|cafe|cal|call|camera|camp|cancerresearch|canon|capetown|capital|car|caravan|cards|care|career|careers|cars|cartier|casa|cash|casino|cat|catering|cba|cbn|cc|cd|ceb|center|ceo|cern|cf|cfa|cfd|cg|ch|chanel|channel|chase|chat|cheap|chloe|christmas|chrome|church|ci|cipriani|circle|cisco|citic|city|cityeats|ck|cl|claims|cleaning|click|clinic|clinique|clothing|cloud|club|clubmed|cm|cn|co|coach|codes|coffee|college|cologne|com|commbank|community|company|compare|computer|comsec|condos|construction|consulting|contact|contractors|cooking|cool|coop|corsica|country|coupon|coupons|courses|cr|credit|creditcard|creditunion|cricket|crown|crs|cruises|csc|cu|cuisinella|cv|cw|cx|cy|cymru|cyou|cz|dabur|dad|dance|date|dating|datsun|day|dclk|de|dealer|deals|degree|delivery|dell|deloitte|delta|democrat|dental|dentist|desi|design|dev|diamonds|diet|digital|direct|directory|discount|dj|dk|dm|dnp|do|docs|dog|doha|domains|download|drive|dubai|durban|dvag|dz|earth|eat|ec|edeka|edu|education|ee|eg|email|emerck|energy|engineer|engineering|enterprises|epson|equipment|er|erni|es|esq|estate|et|eu|eurovision|eus|events|everbank|exchange|expert|exposed|express|fage|fail|fairwinds|faith|family|fan|fans|farm|fashion|fast|feedback|ferrero|fi|film|final|finance|financial|firestone|firmdale|fish|fishing|fit|fitness|fj|fk|flickr|flights|florist|flowers|flsmidth|fly|fm|fo|foo|football|ford|forex|forsale|forum|foundation|fox|fr|fresenius|frl|frogans|frontier|fund|furniture|futbol|fyi|ga|gal|gallery|gallup|game|garden|gb|gbiz|gd|gdn|ge|gea|gent|genting|gf|gg|ggee|gh|gi|gift|gifts|gives|giving|gl|glass|gle|global|globo|gm|gmail|gmbh|gmo|gmx|gn|gold|goldpoint|golf|goo|goog|google|gop|got|gov|gp|gq|gr|grainger|graphics|gratis|green|gripe|group|gs|gt|gu|gucci|guge|guide|guitars|guru|gw|gy|hamburg|hangout|haus|hdfcbank|health|healthcare|help|helsinki|here|hermes|hiphop|hitachi|hiv|hk|hm|hn|hockey|holdings|holiday|homedepot|homes|honda|horse|host|hosting|hoteles|hotmail|house|how|hr|hsbc|ht|hu|hyundai|ibm|icbc|ice|icu|id|ie|ifm|iinet|il|im|immo|immobilien|in|industries|infiniti|info|ing|ink|institute|insurance|insure|int|international|investments|io|ipiranga|iq|ir|irish|is|iselect|ist|istanbul|it|itau|iwc|jaguar|java|jcb|je|jetzt|jewelry|jlc|jll|jm|jmp|jo|jobs|joburg|jot|joy|jp|jpmorgan|jprs|juegos|kaufen|kddi|ke|kerryhotels|kerrylogistics|kerryproperties|kfh|kg|kh|ki|kia|kim|kinder|kitchen|kiwi|km|kn|koeln|komatsu|kp|kpn|kr|krd|kred|kuokgroup|kw|ky|kyoto|kz|la|lacaixa|lamborghini|lamer|lancaster|land|landrover|lanxess|lasalle|lat|latrobe|law|lawyer|lb|lc|lds|lease|leclerc|legal|lexus|lgbt|li|liaison|lidl|life|lifeinsurance|lifestyle|lighting|like|limited|limo|lincoln|linde|link|live|living|lixil|lk|loan|loans|local|locus|lol|london|lotte|lotto|love|lr|ls|lt|ltd|ltda|lu|lupin|luxe|luxury|lv|ly|ma|madrid|maif|maison|makeup|man|management|mango|market|marketing|markets|marriott|mba|mc|md|me|med|media|meet|melbourne|meme|memorial|men|menu|meo|mg|mh|miami|microsoft|mil|mini|mk|ml|mm|mma|mn|mo|mobi|mobily|moda|moe|moi|mom|monash|money|montblanc|mormon|mortgage|moscow|motorcycles|mov|movie|movistar|mp|mq|mr|ms|mt|mtn|mtpc|mtr|mu|museum|mutuelle|mv|mw|mx|my|mz|na|nadex|nagoya|name|natura|navy|nc|ne|nec|net|netbank|network|neustar|new|news|nexus|nf|ng|ngo|nhk|ni|nico|nikon|ninja|nissan|nl|no|nokia|norton|nowruz|np|nr|nra|nrw|ntt|nu|nyc|nz|obi|office|okinawa|om|omega|one|ong|onl|online|ooo|oracle|orange|org|organic|origins|osaka|otsuka|ovh|pa|page|pamperedchef|panerai|paris|pars|partners|parts|party|passagens|pe|pet|pf|pg|ph|pharmacy|philips|photo|photography|photos|physio|piaget|pics|pictet|pictures|pid|pin|ping|pink|pizza|pk|pl|place|play|playstation|plumbing|plus|pm|pn|pohl|poker|porn|post|pr|praxi|press|pro|prod|productions|prof|promo|properties|property|protection|ps|pt|pub|pw|pwc|py|qa|qpon|quebec|quest|racing|re|read|realtor|realty|recipes|red|redstone|redumbrella|rehab|reise|reisen|reit|ren|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rexroth|rich|ricoh|rio|rip|ro|rocher|rocks|rodeo|room|rs|rsvp|ru|ruhr|run|rw|rwe|ryukyu|sa|saarland|safe|safety|sakura|sale|salon|samsung|sandvik|sandvikcoromant|sanofi|sap|sapo|sarl|sas|saxo|sb|sbs|sc|sca|scb|schaeffler|schmidt|scholarships|school|schule|schwarz|science|scor|scot|sd|se|seat|security|seek|select|sener|services|seven|sew|sex|sexy|sfr|sg|sh|sharp|shell|shia|shiksha|shoes|show|shriram|si|singles|site|sj|sk|ski|skin|sky|skype|sl|sm|smile|sn|sncf|so|soccer|social|softbank|software|sohu|solar|solutions|song|sony|soy|space|spiegel|spot|spreadbetting|sr|srl|st|stada|star|starhub|statefarm|statoil|stc|stcgroup|stockholm|storage|store|studio|study|style|su|sucks|supplies|supply|support|surf|surgery|suzuki|sv|swatch|swiss|sx|sy|sydney|symantec|systems|sz|tab|taipei|taobao|tatamotors|tatar|tattoo|tax|taxi|tc|tci|td|team|tech|technology|tel|telecity|telefonica|temasek|tennis|tf|tg|th|thd|theater|theatre|tickets|tienda|tiffany|tips|tires|tirol|tj|tk|tl|tm|tmall|tn|to|today|tokyo|tools|top|toray|toshiba|total|tours|town|toyota|toys|tp|tr|trade|trading|training|travel|travelers|travelersinsurance|trust|trv|tt|tube|tui|tunes|tushu|tv|tvs|tw|tz|ua|ubs|ug|uk|unicom|university|uno|uol|us|uy|uz|va|vacations|vana|vc|ve|vegas|ventures|verisign|versicherung|vet|vg|vi|viajes|video|viking|villas|vin|vip|virgin|vision|vista|vistaprint|viva|vlaanderen|vn|vodka|volkswagen|vote|voting|voto|voyage|vu|vuelos|wales|walter|wang|wanggou|watch|watches|weather|weatherchannel|webcam|weber|website|wed|wedding|weir|wf|whoswho|wien|wiki|williamhill|win|windows|wine|wme|wolterskluwer|work|works|world|ws|wtc|wtf|xbox|xerox|xin|xperia|xxx|xyz|yachts|yahoo|yamaxun|yandex|ye|yodobashi|yoga|yokohama|youtube|yt|za|zara|zero|zip|zm|zone|zuerich|zw".split("|"),W="0123456789".split(""),X="0123456789abcdefghijklmnopqrstuvwxyz".split(""),Z=[" ","\f","\r","\t","\x0B"," "," ",""],F=[],J=function(t){return new m(t)},V=J(),$=J(O),tt=J(v),et=J(),nt=J(q);V.on("@",J(y)).on(".",J(w)).on("+",J(S)).on("#",J(N)).on("?",J(L)).on("/",J(E)).on("_",J(C)).on(":",J(k)).on("{",J(H)).on("[",J(B)).on("<",J(U)).on("(",J(M)).on("}",J(D)).on("]",J(I)).on(">",J(K)).on(")",J(_)).on("&",J(G)).on([",",";","!",'"',"'"],J(j)),V.on("\n",J(z)).on(Z,nt),nt.on(Z,nt);for(var ot=0;ot=0&&u++,c++,a++;if(!(u<0)){a-=u,c-=u;var p=l.emit();o.push(new p(t.substr(a-c,c)))}}return o},yt=V,kt=Object.freeze({State:m,TOKENS:Y,run:vt,start:yt}),wt=l();wt.prototype={type:"token",isLink:!1,toString:function(){for(var t=[],e=0;e0&&void 0!==arguments[0]?arguments[0]:"http";return{type:this.type,value:this.toString(),href:this.toHref(t)}}};var jt=n(wt,l(),{type:"email",isLink:!0}),xt=n(wt,l(),{type:"email",isLink:!0,toHref:function(){this.v;return"mailto:"+this.toString()}}),zt=n(wt,l(),{type:"text"}),Ot=n(wt,l(),{type:"nl"}),St=n(wt,l(),{type:"url",isLink:!0,toHref:function(){for(var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"http",e=!1,n=!1,o=this.v,a=[],r=0;o[r]instanceof T;)e=!0,a.push(o[r].toString().toLowerCase()),r++;for(;o[r]instanceof E;)n=!0,a.push(o[r].toString()),r++;for(;p(o[r]);)a.push(o[r].toString().toLowerCase()),r++;for(;r=0&&u++,n++,c++;if(u<0)for(var p=n-c;p0&&(o.push(new zt(a)),a=[]),n-=u,c-=u;var h=l.emit();o.push(new h(t.slice(n-c,n)))}}return a.length>0&&o.push(new zt(a)),o},fe=Object.freeze({State:d,TOKENS:Nt,run:ge,start:At});Array.isArray||(Array.isArray=function(t){return"[object Array]"===Object.prototype.toString.call(t)});var me=function(t){return ge(vt(t))},de=function(t){for(var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:null,n=me(t),o=[],a=0;a1&&void 0!==arguments[1]?arguments[1]:null,n=me(t);return 1===n.length&&n[0].isLink&&(!e||n[0].type===e)};e.find=de,e.inherits=n,e.options=g,e.parser=fe,e.scanner=kt,e.test=be,e.tokenize=me}(self.linkify=self.linkify||{})}();
--------------------------------------------------------------------------------
/assets/js/translate.js:
--------------------------------------------------------------------------------
1 | function translateText(string, targetLang) {
2 | return $.ajax({
3 | url: "/translate",
4 | data: { msg: string, lang: targetLang }
5 | });
6 | }
7 |
--------------------------------------------------------------------------------
/assets/js/user.js:
--------------------------------------------------------------------------------
1 | function postMessage() {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/assets/robots.txt:
--------------------------------------------------------------------------------
1 | # The robots.txt file is used to control how search engines index your live URLs.
2 | # See http://sailsjs.org/documentation/anatomy/my-app/assets/robots-txt for more information.
3 |
4 |
5 |
6 | # To prevent search engines from seeing the site altogether, uncomment the next two lines:
7 | # User-Agent: *
8 | # Disallow: /
9 |
--------------------------------------------------------------------------------
/assets/styles/icons.less:
--------------------------------------------------------------------------------
1 | .active-icon {
2 | background-image: url('../images/active-icon.svg');
3 | height: 9px;
4 | width: 9px;
5 | display: inline-block;
6 | margin-right: 2px;
7 | }
8 |
9 | .inactive-icon {
10 | background-image: url('../images/inactive-icon.svg');
11 | height: 9px;
12 | width: 9px;
13 | display: inline-block;
14 | margin-right: 2px;
15 | }
16 |
--------------------------------------------------------------------------------
/assets/styles/importer.less:
--------------------------------------------------------------------------------
1 | @import 'bootstrap.min.css';
2 | @import 'pages/chat-room.less';
3 | @import 'icons.less';
4 |
--------------------------------------------------------------------------------
/assets/styles/pages/chat-room.less:
--------------------------------------------------------------------------------
1 | body {
2 | width: 100vw;
3 | }
4 | .master-container {
5 | overflow-x: hidden;
6 | }
7 | .chat-window {
8 | overflow: hidden;
9 | }
10 | .chat-sidebar {
11 | .card-header {
12 | text-align: center;
13 | }
14 | }
15 | .chat-window, .chat-sidebar {
16 | height: 100vh;
17 | border: 0;
18 | border-radius: 0;
19 |
20 | .card-header {
21 | border-radius: 0;
22 | }
23 | }
24 | .loading-indicator {
25 | position: absolute;
26 | left: 50%;
27 | top: 50%;
28 |
29 | margin-left: -25px;
30 | margin-top: -25px;
31 | }
32 | .sidebar-list {
33 | margin: 0;
34 | padding: 0;
35 | padding-left: 14px;
36 | list-style: none;
37 |
38 | li {
39 | padding: 10px 15px;
40 | border-top: 1px solid rgba(201,200,238,0.15);
41 | border-bottom: 1px solid rgba(201,200,238,0.15);
42 | }
43 | }
44 | .live-stats {
45 | li {
46 | padding-left: 50px;
47 | }
48 | }
49 | .channel-list {
50 | .channel-active {
51 | float: right;
52 | font-size: 11px;
53 | line-height: 25px;
54 | }
55 | }
56 | .chat-messages {
57 | width: 100%;
58 | }
59 |
60 | //helpers
61 | .scrollable {
62 | overflow: scroll;
63 | height: inherit;
64 | }
65 |
66 | .hide {
67 | display: none;
68 | }
69 | .no-padding {
70 | padding: 0;
71 | }
72 | //end helpers
73 |
74 | .chat-message {
75 | margin-bottom: 5px;
76 | min-height: 40px;
77 |
78 | .message-body {
79 | width: auto;
80 | max-width: 85%;
81 | font-size: 12px;
82 | line-height: 14px;
83 | padding: 10px 15px;
84 | background: #FFFFFF;
85 | border-radius: 6px;
86 | min-width: 250px;
87 | cursor: pointer;
88 | display: inline-block;
89 | position: relative;
90 | .info {
91 | font-size: 10px;
92 | }
93 | }
94 | .rate-btn {
95 | position: absolute;
96 | right: 10px;
97 | }
98 | .rate-btn:hover {
99 | text-decoration: underline;
100 | }
101 | .action-buttons {
102 | margin-top: 5px;
103 | }
104 | .original-language {
105 | text-align: left;
106 | }
107 | .see-original {
108 | float: right;
109 | text-align: right;
110 | font-style: italic;
111 | margin-left: 15px;
112 | }
113 | }
114 | .profile-picture {
115 | display: inline-block;
116 | text-transform: uppercase;
117 | border-radius: 50%;
118 | width: 30px;
119 | height: 30px;
120 | text-align: center;
121 | padding-top: 3px;
122 |
123 | .short-name {
124 | // visibility: hidden;
125 | text-transform: uppercase;
126 | display: inline-block;
127 | width: 15px;
128 | }
129 | .short-name:first-letter {
130 | // visibility:visible;
131 | }
132 | }
133 | .compose-message {
134 | padding: 15px 20px 0;
135 | background-color: #fff;
136 |
137 | position: relative;
138 | bottom: 10px;
139 | .form-control {
140 | border: none;
141 | }
142 | }
143 |
144 | .chat-message.yourself {
145 | .message-body {
146 | float: right;
147 | min-width: inherit;
148 | }
149 | text-align: right;
150 | }
151 | .purple.chat-sidebar {
152 | background-color: #3F3F5F;
153 | color: #CAC8EE;
154 |
155 | .card-header {
156 | background-color: #2D2D4E;
157 | }
158 | }
159 | .purple.chat-window {
160 | background-color: #DCDDF5;
161 |
162 | .card-header {
163 | background-color: #585886;
164 | color: #CAC8EE;
165 | }
166 | .profile-picture {
167 | background-color: #5B5B89;
168 | color: #fff;
169 | }
170 | .message-body {
171 | color: #8785AB;
172 |
173 | .info {
174 | color: rgba(135,133,171,0.50);
175 | }
176 | }
177 | .chat-message.yourself {
178 | .message-body {
179 | background-color: #89A1FC;
180 | color: #fff;
181 | }
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/assets/templates/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawilster/poly/eb9051d49e406751e0bad3418b1e5eb5e7de201b/assets/templates/.gitkeep
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "ignore": [
3 | "**/.*",
4 | "node_modules",
5 | "bower_components",
6 | "test",
7 | "tests"
8 | ],
9 | "dependencies": {
10 | "bootstrap": "v4.0.0-alpha.6",
11 | "mustache.js": "mustache#^2.3.0"
12 | },
13 | "name": "chat-app",
14 | "version": "0.0.0",
15 | "author": "william",
16 | "private": true
17 | }
18 |
--------------------------------------------------------------------------------
/config/blueprints.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Blueprint API Configuration
3 | * (sails.config.blueprints)
4 | *
5 | * These settings are for the global configuration of blueprint routes and
6 | * request options (which impact the behavior of blueprint actions).
7 | *
8 | * You may also override any of these settings on a per-controller basis
9 | * by defining a '_config' key in your controller definition, and assigning it
10 | * a configuration object with overrides for the settings in this file.
11 | * A lot of the configuration options below affect so-called "CRUD methods",
12 | * or your controllers' `find`, `create`, `update`, and `destroy` actions.
13 | *
14 | * It's important to realize that, even if you haven't defined these yourself, as long as
15 | * a model exists with the same name as the controller, Sails will respond with built-in CRUD
16 | * logic in the form of a JSON API, including support for sort, pagination, and filtering.
17 | *
18 | * For more information on the blueprint API, check out:
19 | * http://sailsjs.org/#!/documentation/reference/blueprint-api
20 | *
21 | * For more information on the settings in this file, see:
22 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.blueprints.html
23 | *
24 | */
25 |
26 | module.exports.blueprints = {
27 |
28 | /***************************************************************************
29 | * *
30 | * Action routes speed up the backend development workflow by *
31 | * eliminating the need to manually bind routes. When enabled, GET, POST, *
32 | * PUT, and DELETE routes will be generated for every one of a controller's *
33 | * actions. *
34 | * *
35 | * If an `index` action exists, additional naked routes will be created for *
36 | * it. Finally, all `actions` blueprints support an optional path *
37 | * parameter, `id`, for convenience. *
38 | * *
39 | * `actions` are enabled by default, and can be OK for production-- *
40 | * however, if you'd like to continue to use controller/action autorouting *
41 | * in a production deployment, you must take great care not to *
42 | * inadvertently expose unsafe/unintentional controller logic to GET *
43 | * requests. *
44 | * *
45 | ***************************************************************************/
46 |
47 | actions: true,
48 |
49 | /***************************************************************************
50 | * *
51 | * RESTful routes (`sails.config.blueprints.rest`) *
52 | * *
53 | * REST blueprints are the automatically generated routes Sails uses to *
54 | * expose a conventional REST API on top of a controller's `find`, *
55 | * `create`, `update`, and `destroy` actions. *
56 | * *
57 | * For example, a BoatController with `rest` enabled generates the *
58 | * following routes: *
59 | * ::::::::::::::::::::::::::::::::::::::::::::::::::::::: *
60 | * GET /boat -> BoatController.find *
61 | * GET /boat/:id -> BoatController.findOne *
62 | * POST /boat -> BoatController.create *
63 | * PUT /boat/:id -> BoatController.update *
64 | * DELETE /boat/:id -> BoatController.destroy *
65 | * *
66 | * `rest` blueprint routes are enabled by default, and are suitable for use *
67 | * in a production scenario, as long you take standard security precautions *
68 | * (combine w/ policies, etc.) *
69 | * *
70 | ***************************************************************************/
71 |
72 | rest: true,
73 |
74 | /***************************************************************************
75 | * *
76 | * Shortcut routes are simple helpers to provide access to a *
77 | * controller's CRUD methods from your browser's URL bar. When enabled, *
78 | * GET, POST, PUT, and DELETE routes will be generated for the *
79 | * controller's`find`, `create`, `update`, and `destroy` actions. *
80 | * *
81 | * `shortcuts` are enabled by default, but should be disabled in *
82 | * production. *
83 | * *
84 | ***************************************************************************/
85 |
86 | shortcuts: true,
87 |
88 | /***************************************************************************
89 | * *
90 | * An optional mount path for all blueprint routes on a controller, *
91 | * including `rest`, `actions`, and `shortcuts`. This allows you to take *
92 | * advantage of blueprint routing, even if you need to namespace your API *
93 | * methods. *
94 | * *
95 | * (NOTE: This only applies to blueprint autoroutes, not manual routes from *
96 | * `sails.config.routes`) *
97 | * *
98 | ***************************************************************************/
99 |
100 | prefix: '',
101 |
102 | /***************************************************************************
103 | * *
104 | * An optional mount path for all REST blueprint routes on a controller. *
105 | * And it do not include `actions` and `shortcuts` routes. *
106 | * This allows you to take advantage of REST blueprint routing, *
107 | * even if you need to namespace your RESTful API methods *
108 | * *
109 | ***************************************************************************/
110 |
111 | // restPrefix: '',
112 |
113 | /***************************************************************************
114 | * *
115 | * Whether to pluralize controller names in blueprint routes. *
116 | * *
117 | * (NOTE: This only applies to blueprint autoroutes, not manual routes from *
118 | * `sails.config.routes`) *
119 | * *
120 | * For example, REST blueprints for `FooController` with `pluralize` *
121 | * enabled: *
122 | * GET /foos/:id? *
123 | * POST /foos *
124 | * PUT /foos/:id? *
125 | * DELETE /foos/:id? *
126 | * *
127 | ***************************************************************************/
128 |
129 | pluralize: false,
130 |
131 | /***************************************************************************
132 | * *
133 | * Whether the blueprint controllers should populate model fetches with *
134 | * data from other models which are linked by associations *
135 | * *
136 | * If you have a lot of data in one-to-many associations, leaving this on *
137 | * may result in very heavy api calls *
138 | * *
139 | ***************************************************************************/
140 |
141 | // populate: true,
142 |
143 | /****************************************************************************
144 | * *
145 | * Whether to run Model.watch() in the find and findOne blueprint actions. *
146 | * Can be overridden on a per-model basis. *
147 | * *
148 | ****************************************************************************/
149 |
150 | // autoWatch: true,
151 |
152 | /****************************************************************************
153 | * *
154 | * The default number of records to show in the response from a "find" *
155 | * action. Doubles as the default size of populated arrays if populate is *
156 | * true. *
157 | * *
158 | ****************************************************************************/
159 |
160 | // defaultLimit: 30
161 |
162 | };
163 |
--------------------------------------------------------------------------------
/config/bootstrap.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstrap
3 | * (sails.config.bootstrap)
4 | *
5 | * An asynchronous bootstrap function that runs before your Sails app gets lifted.
6 | * This gives you an opportunity to set up your data model, run jobs, or perform some special logic.
7 | *
8 | * For more information on bootstrapping your app, check out:
9 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.bootstrap.html
10 | */
11 |
12 | module.exports.bootstrap = function(cb) {
13 |
14 | // It's very important to trigger this callback method when you are finished
15 | // with the bootstrap! (otherwise your server will never lift, since it's waiting on the bootstrap)
16 | cb();
17 | };
18 |
--------------------------------------------------------------------------------
/config/connections.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Connections
3 | * (sails.config.connections)
4 | *
5 | * `Connections` are like "saved settings" for your adapters. What's the difference between
6 | * a connection and an adapter, you might ask? An adapter (e.g. `sails-mysql`) is generic--
7 | * it needs some additional information to work (e.g. your database host, password, user, etc.)
8 | * A `connection` is that additional information.
9 | *
10 | * Each model must have a `connection` property (a string) which is references the name of one
11 | * of these connections. If it doesn't, the default `connection` configured in `config/models.js`
12 | * will be applied. Of course, a connection can (and usually is) shared by multiple models.
13 | * .
14 | * Note: If you're using version control, you should put your passwords/api keys
15 | * in `config/local.js`, environment variables, or use another strategy.
16 | * (this is to prevent you inadvertently sensitive credentials up to your repository.)
17 | *
18 | * For more information on configuration, check out:
19 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.connections.html
20 | */
21 |
22 | module.exports.connections = {
23 |
24 | /***************************************************************************
25 | * *
26 | * Local disk storage for DEVELOPMENT ONLY *
27 | * *
28 | * Installed by default. *
29 | * *
30 | ***************************************************************************/
31 | localDiskDb: {
32 | adapter: 'sails-disk'
33 | },
34 |
35 |
36 | /***************************************************************************
37 | * *
38 | * MySQL is the world's most popular relational database. *
39 | * http://en.wikipedia.org/wiki/MySQL *
40 | * *
41 | * Run: npm install sails-mysql *
42 | * *
43 | ***************************************************************************/
44 | // someMysqlServer: {
45 | // adapter: 'sails-mysql',
46 | // host: 'YOUR_MYSQL_SERVER_HOSTNAME_OR_IP_ADDRESS',
47 | // user: 'YOUR_MYSQL_USER', //optional
48 | // password: 'YOUR_MYSQL_PASSWORD', //optional
49 | // database: 'YOUR_MYSQL_DB' //optional
50 | // },
51 |
52 | /***************************************************************************
53 | * *
54 | * MongoDB is the leading NoSQL database. *
55 | * http://en.wikipedia.org/wiki/MongoDB *
56 | * *
57 | * Run: npm install sails-mongo *
58 | * *
59 | ***************************************************************************/
60 | // mongodb: {
61 | // adapter: 'sails-mongo',
62 | // host: 'ds157439.mlab.com',
63 | // port: 57439,
64 | // user: 'poly', //optional
65 | // password: 'qTZbxAt8eJfCgkKKYhbJGevJLQRNewHQ', //optional
66 | // database: 'heroku_vxmclkvk' //optional
67 | // },
68 | // mongodb: {
69 | // adapter: 'sails-mongo',
70 | // host: 'localhost',
71 | // port: 27017,
72 | // user: '', //optional
73 | // password: '', //optional
74 | // database: 'poly_db_dev' //optional
75 | // },
76 | /***************************************************************************
77 | * *
78 | * PostgreSQL is another officially supported relational database. *
79 | * http://en.wikipedia.org/wiki/PostgreSQL *
80 | * *
81 | * Run: npm install sails-postgresql *
82 | * *
83 | * *
84 | ***************************************************************************/
85 | // somePostgresqlServer: {
86 | // adapter: 'sails-postgresql',
87 | // host: 'YOUR_POSTGRES_SERVER_HOSTNAME_OR_IP_ADDRESS',
88 | // user: 'YOUR_POSTGRES_USER', // optional
89 | // password: 'YOUR_POSTGRES_PASSWORD', // optional
90 | // database: 'YOUR_POSTGRES_DB' //optional
91 | // }
92 |
93 |
94 | /***************************************************************************
95 | * *
96 | * More adapters: https://github.com/balderdashy/sails *
97 | * *
98 | ***************************************************************************/
99 |
100 | };
101 |
--------------------------------------------------------------------------------
/config/cors.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cross-Origin Resource Sharing (CORS) Settings
3 | * (sails.config.cors)
4 | *
5 | * CORS is like a more modern version of JSONP-- it allows your server/API
6 | * to successfully respond to requests from client-side JavaScript code
7 | * running on some other domain (e.g. google.com)
8 | * Unlike JSONP, it works with POST, PUT, and DELETE requests
9 | *
10 | * For more information on CORS, check out:
11 | * http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
12 | *
13 | * Note that any of these settings (besides 'allRoutes') can be changed on a per-route basis
14 | * by adding a "cors" object to the route configuration:
15 | *
16 | * '/get foo': {
17 | * controller: 'foo',
18 | * action: 'bar',
19 | * cors: {
20 | * origin: 'http://foobar.com,https://owlhoot.com'
21 | * }
22 | * }
23 | *
24 | * For more information on this configuration file, see:
25 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.cors.html
26 | *
27 | */
28 |
29 | module.exports.cors = {
30 |
31 | /***************************************************************************
32 | * *
33 | * Allow CORS on all routes by default? If not, you must enable CORS on a *
34 | * per-route basis by either adding a "cors" configuration object to the *
35 | * route config, or setting "cors:true" in the route config to use the *
36 | * default settings below. *
37 | * *
38 | ***************************************************************************/
39 |
40 | // allRoutes: false,
41 |
42 | /***************************************************************************
43 | * *
44 | * Which domains which are allowed CORS access? This can be a *
45 | * comma-delimited list of hosts (beginning with http:// or https://) or *
46 | * "*" to allow all domains CORS access. *
47 | * *
48 | ***************************************************************************/
49 |
50 | // origin: '*',
51 |
52 | /***************************************************************************
53 | * *
54 | * Allow cookies to be shared for CORS requests? *
55 | * *
56 | ***************************************************************************/
57 |
58 | // credentials: true,
59 |
60 | /***************************************************************************
61 | * *
62 | * Which methods should be allowed for CORS requests? This is only used in *
63 | * response to preflight requests (see article linked above for more info) *
64 | * *
65 | ***************************************************************************/
66 |
67 | // methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
68 |
69 | /***************************************************************************
70 | * *
71 | * Which headers should be allowed for CORS requests? This is only used in *
72 | * response to preflight requests. *
73 | * *
74 | ***************************************************************************/
75 |
76 | // headers: 'content-type'
77 |
78 | };
79 |
--------------------------------------------------------------------------------
/config/csrf.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Cross-Site Request Forgery Protection Settings
3 | * (sails.config.csrf)
4 | *
5 | * CSRF tokens are like a tracking chip. While a session tells the server that a user
6 | * "is who they say they are", a csrf token tells the server "you are where you say you are".
7 | *
8 | * When enabled, all non-GET requests to the Sails server must be accompanied by
9 | * a special token, identified as the '_csrf' parameter.
10 | *
11 | * This option protects your Sails app against cross-site request forgery (or CSRF) attacks.
12 | * A would-be attacker needs not only a user's session cookie, but also this timestamped,
13 | * secret CSRF token, which is refreshed/granted when the user visits a URL on your app's domain.
14 | *
15 | * This allows us to have certainty that our users' requests haven't been hijacked,
16 | * and that the requests they're making are intentional and legitimate.
17 | *
18 | * This token has a short-lived expiration timeline, and must be acquired by either:
19 | *
20 | * (a) For traditional view-driven web apps:
21 | * Fetching it from one of your views, where it may be accessed as
22 | * a local variable, e.g.:
23 | *
26 | *
27 | * or (b) For AJAX/Socket-heavy and/or single-page apps:
28 | * Sending a GET request to the `/csrfToken` route, where it will be returned
29 | * as JSON, e.g.:
30 | * { _csrf: 'ajg4JD(JGdajhLJALHDa' }
31 | *
32 | *
33 | * Enabling this option requires managing the token in your front-end app.
34 | * For traditional web apps, it's as easy as passing the data from a view into a form action.
35 | * In AJAX/Socket-heavy apps, just send a GET request to the /csrfToken route to get a valid token.
36 | *
37 | * For more information on CSRF, check out:
38 | * http://en.wikipedia.org/wiki/Cross-site_request_forgery
39 | *
40 | * For more information on this configuration file, including info on CSRF + CORS, see:
41 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.csrf.html
42 | *
43 | */
44 |
45 | /****************************************************************************
46 | * *
47 | * Enabled CSRF protection for your site? *
48 | * *
49 | ****************************************************************************/
50 |
51 | // module.exports.csrf = false;
52 |
53 | /****************************************************************************
54 | * *
55 | * You may also specify more fine-grained settings for CSRF, including the *
56 | * domains which are allowed to request the CSRF token via AJAX. These *
57 | * settings override the general CORS settings in your config/cors.js file. *
58 | * *
59 | ****************************************************************************/
60 |
61 | // module.exports.csrf = {
62 | // grantTokenViaAjax: true,
63 | // origin: ''
64 | // }
65 |
--------------------------------------------------------------------------------
/config/env/development.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Development environment settings
3 | *
4 | * This file can include shared settings for a development team,
5 | * such as API keys or remote database passwords. If you're using
6 | * a version control solution for your Sails app, this file will
7 | * be committed to your repository unless you add it to your .gitignore
8 | * file. If your repository will be publicly viewable, don't add
9 | * any private information to this file!
10 | *
11 | */
12 |
13 | module.exports = {
14 |
15 | /***************************************************************************
16 | * Set the default database connection for models in the development *
17 | * environment (see config/connections.js and config/models.js ) *
18 | ***************************************************************************/
19 |
20 | };
21 |
--------------------------------------------------------------------------------
/config/env/development/connections.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Connections
3 | * (sails.config.connections)
4 | *
5 | * `Connections` are like "saved settings" for your adapters. What's the difference between
6 | * a connection and an adapter, you might ask? An adapter (e.g. `sails-mysql`) is generic--
7 | * it needs some additional information to work (e.g. your database host, password, user, etc.)
8 | * A `connection` is that additional information.
9 | *
10 | * Each model must have a `connection` property (a string) which is references the name of one
11 | * of these connections. If it doesn't, the default `connection` configured in `config/models.js`
12 | * will be applied. Of course, a connection can (and usually is) shared by multiple models.
13 | * .
14 | * Note: If you're using version control, you should put your passwords/api keys
15 | * in `config/local.js`, environment variables, or use another strategy.
16 | * (this is to prevent you inadvertently sensitive credentials up to your repository.)
17 | *
18 | * For more information on configuration, check out:
19 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.connections.html
20 | */
21 |
22 | module.exports.connections = {
23 | mongodb: {
24 | adapter: 'sails-mongo',
25 | host: 'localhost',
26 | port: 27017,
27 | user: '', //optional
28 | password: '', //optional
29 | database: 'poly_db_dev' //optional
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/config/env/production.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Production environment settings
3 | *
4 | * This file can include shared settings for a production environment,
5 | * such as API keys or remote database passwords. If you're using
6 | * a version control solution for your Sails app, this file will
7 | * be committed to your repository unless you add it to your .gitignore
8 | * file. If your repository will be publicly viewable, don't add
9 | * any private information to this file!
10 | *
11 | */
12 |
13 | module.exports = {
14 |
15 | /***************************************************************************
16 | * Set the default database connection for models in the production *
17 | * environment (see config/connections.js and config/models.js ) *
18 | ***************************************************************************/
19 |
20 | // models: {
21 | // connection: 'mongodb',
22 | // },
23 |
24 | session: {
25 | url: process.env.REDIS_URL
26 | },
27 |
28 | /***************************************************************************
29 | * Set the port in the production environment to 80 *
30 | ***************************************************************************/
31 |
32 | port: 80,
33 |
34 | /***************************************************************************
35 | * Set the log level in production environment to "silent" *
36 | ***************************************************************************/
37 |
38 | log: {
39 | level: "silent"
40 | }
41 |
42 | };
43 |
--------------------------------------------------------------------------------
/config/env/production/connections.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Connections
3 | * (sails.config.connections)
4 | *
5 | * `Connections` are like "saved settings" for your adapters. What's the difference between
6 | * a connection and an adapter, you might ask? An adapter (e.g. `sails-mysql`) is generic--
7 | * it needs some additional information to work (e.g. your database host, password, user, etc.)
8 | * A `connection` is that additional information.
9 | *
10 | * Each model must have a `connection` property (a string) which is references the name of one
11 | * of these connections. If it doesn't, the default `connection` configured in `config/models.js`
12 | * will be applied. Of course, a connection can (and usually is) shared by multiple models.
13 | * .
14 | * Note: If you're using version control, you should put your passwords/api keys
15 | * in `config/local.js`, environment variables, or use another strategy.
16 | * (this is to prevent you inadvertently sensitive credentials up to your repository.)
17 | *
18 | * For more information on configuration, check out:
19 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.connections.html
20 | */
21 |
22 | module.exports.connections = {
23 | mongodb: {
24 | adapter: 'sails-mongo',
25 | host: process.env.MONGO_HOST,
26 | port: 57439,
27 | user: process.env.MONGO_USER,
28 | password: process.env.MONGO_PASSWORD,
29 | database: process.env.MONGO_DB
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/config/globals.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Global Variable Configuration
3 | * (sails.config.globals)
4 | *
5 | * Configure which global variables which will be exposed
6 | * automatically by Sails.
7 | *
8 | * For more information on configuration, check out:
9 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.globals.html
10 | */
11 | module.exports.globals = {
12 |
13 | /****************************************************************************
14 | * *
15 | * Expose the lodash installed in Sails core as a global variable. If this *
16 | * is disabled, like any other node module you can always run npm install *
17 | * lodash --save, then var _ = require('lodash') at the top of any file. *
18 | * *
19 | ****************************************************************************/
20 |
21 | // _: true,
22 |
23 | /****************************************************************************
24 | * *
25 | * Expose the async installed in Sails core as a global variable. If this is *
26 | * disabled, like any other node module you can always run npm install async *
27 | * --save, then var async = require('async') at the top of any file. *
28 | * *
29 | ****************************************************************************/
30 |
31 | // async: true,
32 |
33 | /****************************************************************************
34 | * *
35 | * Expose the sails instance representing your app. If this is disabled, you *
36 | * can still get access via req._sails. *
37 | * *
38 | ****************************************************************************/
39 |
40 | // sails: true,
41 |
42 | /****************************************************************************
43 | * *
44 | * Expose each of your app's services as global variables (using their *
45 | * "globalId"). E.g. a service defined in api/models/NaturalLanguage.js *
46 | * would have a globalId of NaturalLanguage by default. If this is disabled, *
47 | * you can still access your services via sails.services.* *
48 | * *
49 | ****************************************************************************/
50 |
51 | // services: true,
52 |
53 | /****************************************************************************
54 | * *
55 | * Expose each of your app's models as global variables (using their *
56 | * "globalId"). E.g. a model defined in api/models/User.js would have a *
57 | * globalId of User by default. If this is disabled, you can still access *
58 | * your models via sails.models.*. *
59 | * *
60 | ****************************************************************************/
61 |
62 | // models: true
63 | };
64 |
--------------------------------------------------------------------------------
/config/http.js:
--------------------------------------------------------------------------------
1 | /**
2 | * HTTP Server Settings
3 | * (sails.config.http)
4 | *
5 | * Configuration for the underlying HTTP server in Sails.
6 | * Only applies to HTTP requests (not WebSockets)
7 | *
8 | * For more information on configuration, check out:
9 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.http.html
10 | */
11 |
12 | module.exports.http = {
13 |
14 | /****************************************************************************
15 | * *
16 | * Express middleware to use for every Sails request. To add custom *
17 | * middleware to the mix, add a function to the middleware config object and *
18 | * add its key to the "order" array. The $custom key is reserved for *
19 | * backwards-compatibility with Sails v0.9.x apps that use the *
20 | * `customMiddleware` config option. *
21 | * *
22 | ****************************************************************************/
23 |
24 | middleware: {
25 |
26 | /***************************************************************************
27 | * *
28 | * The order in which middleware should be run for HTTP request. (the Sails *
29 | * router is invoked by the "router" middleware below.) *
30 | * *
31 | ***************************************************************************/
32 |
33 | // order: [
34 | // 'startRequestTimer',
35 | // 'cookieParser',
36 | // 'session',
37 | // 'myRequestLogger',
38 | // 'bodyParser',
39 | // 'handleBodyParserError',
40 | // 'compress',
41 | // 'methodOverride',
42 | // 'poweredBy',
43 | // '$custom',
44 | // 'router',
45 | // 'www',
46 | // 'favicon',
47 | // '404',
48 | // '500'
49 | // ],
50 |
51 | /****************************************************************************
52 | * *
53 | * Example custom middleware; logs each request to the console. *
54 | * *
55 | ****************************************************************************/
56 |
57 | // myRequestLogger: function (req, res, next) {
58 | // console.log("Requested :: ", req.method, req.url);
59 | // return next();
60 | // }
61 |
62 |
63 | /***************************************************************************
64 | * *
65 | * The body parser that will handle incoming multipart HTTP requests. By *
66 | * default as of v0.10, Sails uses *
67 | * [skipper](http://github.com/balderdashy/skipper). See *
68 | * http://www.senchalabs.org/connect/multipart.html for other options. *
69 | * *
70 | * Note that Sails uses an internal instance of Skipper by default; to *
71 | * override it and specify more options, make sure to "npm install skipper" *
72 | * in your project first. You can also specify a different body parser or *
73 | * a custom function with req, res and next parameters (just like any other *
74 | * middleware function). *
75 | * *
76 | ***************************************************************************/
77 |
78 | // bodyParser: require('skipper')({strict: true})
79 |
80 | },
81 |
82 | /***************************************************************************
83 | * *
84 | * The number of seconds to cache flat files on disk being served by *
85 | * Express static middleware (by default, these files are in `.tmp/public`) *
86 | * *
87 | * The HTTP static cache is only active in a 'production' environment, *
88 | * since that's the only time Express will cache flat-files. *
89 | * *
90 | ***************************************************************************/
91 |
92 | // cache: 31557600000
93 | };
94 |
--------------------------------------------------------------------------------
/config/i18n.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Internationalization / Localization Settings
3 | * (sails.config.i18n)
4 | *
5 | * If your app will touch people from all over the world, i18n (or internationalization)
6 | * may be an important part of your international strategy.
7 | *
8 | *
9 | * For more informationom i18n in Sails, check out:
10 | * http://sailsjs.org/#!/documentation/concepts/Internationalization
11 | *
12 | * For a complete list of i18n options, see:
13 | * https://github.com/mashpie/i18n-node#list-of-configuration-options
14 | *
15 | *
16 | */
17 |
18 | module.exports.i18n = {
19 |
20 | /***************************************************************************
21 | * *
22 | * Which locales are supported? *
23 | * *
24 | ***************************************************************************/
25 |
26 | // locales: ['en', 'es', 'fr', 'de'],
27 |
28 | /****************************************************************************
29 | * *
30 | * What is the default locale for the site? Note that this setting will be *
31 | * overridden for any request that sends an "Accept-Language" header (i.e. *
32 | * most browsers), but it's still useful if you need to localize the *
33 | * response for requests made by non-browser clients (e.g. cURL). *
34 | * *
35 | ****************************************************************************/
36 |
37 | // defaultLocale: 'en',
38 |
39 | /****************************************************************************
40 | * *
41 | * Automatically add new keys to locale (translation) files when they are *
42 | * encountered during a request? *
43 | * *
44 | ****************************************************************************/
45 |
46 | // updateFiles: false,
47 |
48 | /****************************************************************************
49 | * *
50 | * Path (relative to app root) of directory to store locale (translation) *
51 | * files in. *
52 | * *
53 | ****************************************************************************/
54 |
55 | // localesDirectory: '/config/locales'
56 |
57 | };
58 |
--------------------------------------------------------------------------------
/config/locales/_README.md:
--------------------------------------------------------------------------------
1 | # Internationalization / Localization Settings
2 |
3 | > Also see the official docs on internationalization/localization:
4 | > http://links.sailsjs.org/docs/config/locales
5 |
6 | ## Locales
7 | All locale files live under `config/locales`. Here is where you can add translations
8 | as JSON key-value pairs. The name of the file should match the language that you are supporting, which allows for automatic language detection based on request headers.
9 |
10 | Here is an example locale stringfile for the Spanish language (`config/locales/es.json`):
11 | ```json
12 | {
13 | "Hello!": "Hola!",
14 | "Hello %s, how are you today?": "¿Hola %s, como estas?",
15 | }
16 | ```
17 | ## Usage
18 | Locales can be accessed in controllers/policies through `res.i18n()`, or in views through the `__(key)` or `i18n(key)` functions.
19 | Remember that the keys are case sensitive and require exact key matches, e.g.
20 |
21 | ```ejs
22 |
<%= __('Welcome to PencilPals!') %>
23 |
<%= i18n('Hello %s, how are you today?', 'Pencil Maven') %>
24 |
<%= i18n('That\'s right-- you can use either i18n() or __()') %>
25 | ```
26 |
27 | ## Configuration
28 | Localization/internationalization config can be found in `config/i18n.js`, from where you can set your supported locales.
29 |
--------------------------------------------------------------------------------
/config/locales/de.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Willkommen",
3 | "A brand new app.": "Eine neue App."
4 | }
5 |
--------------------------------------------------------------------------------
/config/locales/en.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Welcome",
3 | "A brand new app.": "A brand new app."
4 | }
5 |
--------------------------------------------------------------------------------
/config/locales/es.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Bienvenido",
3 | "A brand new app.": "Una nueva aplicación."
4 | }
5 |
--------------------------------------------------------------------------------
/config/locales/fr.json:
--------------------------------------------------------------------------------
1 | {
2 | "Welcome": "Bienvenue",
3 | "A brand new app.": "Une toute nouvelle application."
4 | }
5 |
--------------------------------------------------------------------------------
/config/log.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Built-in Log Configuration
3 | * (sails.config.log)
4 | *
5 | * Configure the log level for your app, as well as the transport
6 | * (Underneath the covers, Sails uses Winston for logging, which
7 | * allows for some pretty neat custom transports/adapters for log messages)
8 | *
9 | * For more information on the Sails logger, check out:
10 | * http://sailsjs.org/#!/documentation/concepts/Logging
11 | */
12 |
13 | module.exports.log = {
14 |
15 | /***************************************************************************
16 | * *
17 | * Valid `level` configs: i.e. the minimum log level to capture with *
18 | * sails.log.*() *
19 | * *
20 | * The order of precedence for log levels from lowest to highest is: *
21 | * silly, verbose, info, debug, warn, error *
22 | * *
23 | * You may also set the level to "silent" to suppress all logs. *
24 | * *
25 | ***************************************************************************/
26 |
27 | // level: 'info'
28 |
29 | };
30 |
--------------------------------------------------------------------------------
/config/models.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Default model configuration
3 | * (sails.config.models)
4 | *
5 | * Unless you override them, the following properties will be included
6 | * in each of your models.
7 | *
8 | * For more info on Sails models, see:
9 | * http://sailsjs.org/#!/documentation/concepts/ORM
10 | */
11 |
12 | module.exports.models = {
13 |
14 | /***************************************************************************
15 | * *
16 | * Your app's default connection. i.e. the name of one of your app's *
17 | * connections (see `config/connections.js`) *
18 | * *
19 | ***************************************************************************/
20 | connection: 'mongodb',
21 |
22 | /***************************************************************************
23 | * *
24 | * How and whether Sails will attempt to automatically rebuild the *
25 | * tables/collections/etc. in your schema. *
26 | * *
27 | * See http://sailsjs.org/#!/documentation/concepts/ORM/model-settings.html *
28 | * *
29 | ***************************************************************************/
30 | migrate: 'alter'
31 |
32 | };
33 |
--------------------------------------------------------------------------------
/config/policies.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Policy Mappings
3 | * (sails.config.policies)
4 | *
5 | * Policies are simple functions which run **before** your controllers.
6 | * You can apply one or more policies to a given controller, or protect
7 | * its actions individually.
8 | *
9 | * Any policy file (e.g. `api/policies/authenticated.js`) can be accessed
10 | * below by its filename, minus the extension, (e.g. "authenticated")
11 | *
12 | * For more information on how policies work, see:
13 | * http://sailsjs.org/#!/documentation/concepts/Policies
14 | *
15 | * For more information on configuring policies, check out:
16 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.policies.html
17 | */
18 |
19 |
20 | module.exports.policies = {
21 |
22 | /***************************************************************************
23 | * *
24 | * Default policy for all controllers and actions (`true` allows public *
25 | * access) *
26 | * *
27 | ***************************************************************************/
28 |
29 | // '*': true,
30 |
31 | /***************************************************************************
32 | * *
33 | * Here's an example of mapping some policies to run before a controller *
34 | * and its actions *
35 | * *
36 | ***************************************************************************/
37 | // RabbitController: {
38 |
39 | // Apply the `false` policy as the default for all of RabbitController's actions
40 | // (`false` prevents all access, which ensures that nothing bad happens to our rabbits)
41 | // '*': false,
42 |
43 | // For the action `nurture`, apply the 'isRabbitMother' policy
44 | // (this overrides `false` above)
45 | // nurture : 'isRabbitMother',
46 |
47 | // Apply the `isNiceToAnimals` AND `hasRabbitFood` policies
48 | // before letting any users feed our rabbits
49 | // feed : ['isNiceToAnimals', 'hasRabbitFood']
50 | // }
51 | };
52 |
--------------------------------------------------------------------------------
/config/routes.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Route Mappings
3 | * (sails.config.routes)
4 | *
5 | * Your routes map URLs to views and controllers.
6 | *
7 | * If Sails receives a URL that doesn't match any of the routes below,
8 | * it will check for matching files (images, scripts, stylesheets, etc.)
9 | * in your assets directory. e.g. `http://localhost:1337/images/foo.jpg`
10 | * might match an image file: `/assets/images/foo.jpg`
11 | *
12 | * Finally, if those don't match either, the default 404 handler is triggered.
13 | * See `api/responses/notFound.js` to adjust your app's 404 logic.
14 | *
15 | * Note: Sails doesn't ACTUALLY serve stuff from `assets`-- the default Gruntfile in Sails copies
16 | * flat files from `assets` to `.tmp/public`. This allows you to do things like compile LESS or
17 | * CoffeeScript for the front-end.
18 | *
19 | * For more information on configuring custom routes, check out:
20 | * http://sailsjs.org/#!/documentation/concepts/Routes/RouteTargetSyntax.html
21 | */
22 |
23 | module.exports.routes = {
24 |
25 | /***************************************************************************
26 | * *
27 | * Make the view located at `views/homepage.ejs` (or `views/homepage.jade`, *
28 | * etc. depending on your default view engine) your home page. *
29 | * *
30 | * (Alternatively, remove this and add an `index.html` file in your *
31 | * `assets` directory) *
32 | * *
33 | ***************************************************************************/
34 |
35 | '/': {
36 | view: 'index'
37 | },
38 |
39 | 'get /translate': 'ChatController.translate',
40 | 'get /welcome': 'ChatController.welcome',
41 | 'get /reset' : 'ChatController.reset'
42 |
43 |
44 | /***************************************************************************
45 | * *
46 | * Custom routes here... *
47 | * *
48 | * If a request to a URL doesn't match any of the custom routes above, it *
49 | * is matched against Sails route blueprints. See `config/blueprints.js` *
50 | * for configuration options and examples. *
51 | * *
52 | ***************************************************************************/
53 |
54 | };
55 |
--------------------------------------------------------------------------------
/config/session.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Session Configuration
3 | * (sails.config.session)
4 | *
5 | * Sails session integration leans heavily on the great work already done by
6 | * Express, but also unifies Socket.io with the Connect session store. It uses
7 | * Connect's cookie parser to normalize configuration differences between Express
8 | * and Socket.io and hooks into Sails' middleware interpreter to allow you to access
9 | * and auto-save to `req.session` with Socket.io the same way you would with Express.
10 | *
11 | * For more information on configuring the session, check out:
12 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.session.html
13 | */
14 |
15 | module.exports.session = {
16 |
17 | /***************************************************************************
18 | * *
19 | * Session secret is automatically generated when your new app is created *
20 | * Replace at your own risk in production-- you will invalidate the cookies *
21 | * of your users, forcing them to log in again. *
22 | * *
23 | ***************************************************************************/
24 | secret: 'd0c55bdc5312a787dec0c9f730c11660',
25 |
26 |
27 | /***************************************************************************
28 | * *
29 | * Set the session cookie expire time The maxAge is set by milliseconds, *
30 | * the example below is for 24 hours *
31 | * *
32 | ***************************************************************************/
33 |
34 | // cookie: {
35 | // maxAge: 24 * 60 * 60 * 1000
36 | // },
37 |
38 | /***************************************************************************
39 | * *
40 | * Uncomment the following lines to set up a Redis session store that can *
41 | * be shared across multiple Sails.js servers. *
42 | * *
43 | * Requires connect-redis (https://www.npmjs.com/package/connect-redis) *
44 | * *
45 | ***************************************************************************/
46 |
47 | adapter: 'redis',
48 |
49 | /***************************************************************************
50 | * *
51 | * The following values are optional, if no options are set a redis *
52 | * instance running on localhost is expected. Read more about options at: *
53 | * *
54 | * https://github.com/visionmedia/connect-redis *
55 | * *
56 | ***************************************************************************/
57 |
58 | // host: 'localhost',
59 | // port: 6379,
60 | // ttl: ,
61 | // db: 0,
62 | // pass: ,
63 | // prefix: 'sess:',
64 |
65 |
66 | /***************************************************************************
67 | * *
68 | * Uncomment the following lines to set up a MongoDB session store that can *
69 | * be shared across multiple Sails.js servers. *
70 | * *
71 | * Requires connect-mongo (https://www.npmjs.com/package/connect-mongo) *
72 | * Use version 0.8.2 with Node version <= 0.12 *
73 | * Use the latest version with Node >= 4.0 *
74 | * *
75 | ***************************************************************************/
76 |
77 | // adapter: 'mongo',
78 | // url: 'mongodb://user:password@localhost:27017/dbname', // user, password and port optional
79 |
80 | /***************************************************************************
81 | * *
82 | * Optional Values: *
83 | * *
84 | * See https://github.com/kcbanner/connect-mongo for more *
85 | * information about connect-mongo options. *
86 | * *
87 | * See http://bit.ly/mongooptions for more information about options *
88 | * available in `mongoOptions` *
89 | * *
90 | ***************************************************************************/
91 |
92 | // collection: 'sessions',
93 | // stringify: true,
94 | // mongoOptions: {
95 | // server: {
96 | // ssl: true
97 | // }
98 | // }
99 |
100 | };
101 |
--------------------------------------------------------------------------------
/config/sockets.js:
--------------------------------------------------------------------------------
1 | /**
2 | * WebSocket Server Settings
3 | * (sails.config.sockets)
4 | *
5 | * These settings provide transparent access to the options for Sails'
6 | * encapsulated WebSocket server, as well as some additional Sails-specific
7 | * configuration layered on top.
8 | *
9 | * For more information on sockets configuration, including advanced config options, see:
10 | * http://sailsjs.org/#!/documentation/reference/sails.config/sails.config.sockets.html
11 | */
12 |
13 | module.exports.sockets = {
14 | // This custom onDisconnect function will be run each time a socket disconnects
15 | afterDisconnect: function(session, socket, cb) {
16 | console.log("DISCONNECT SESSION", session);
17 | try {
18 | // Look up the user ID using the connected socket
19 | var userId = session.userId;
20 |
21 | // Get the user instance
22 | User.findOne(userId).exec(function(err, user) {
23 |
24 | if (err) { return cb(); }
25 |
26 | //deactivate the user
27 | User.update(userId, {active: false}).exec(function(err) {
28 | if (err) { return cb(); }
29 | User.stats(function(err, stats) {
30 | if (err) { return res.serverError(err); }
31 |
32 | User.broadcaseCount();
33 | });
34 | });
35 | });
36 | } catch (e) {
37 | console.log("Error in onDisconnect: ", e);
38 | return cb();
39 | }
40 |
41 | }
42 |
43 |
44 |
45 | /***************************************************************************
46 | * *
47 | * Node.js (and consequently Sails.js) apps scale horizontally. It's a *
48 | * powerful, efficient approach, but it involves a tiny bit of planning. At *
49 | * scale, you'll want to be able to copy your app onto multiple Sails.js *
50 | * servers and throw them behind a load balancer. *
51 | * *
52 | * One of the big challenges of scaling an application is that these sorts *
53 | * of clustered deployments cannot share memory, since they are on *
54 | * physically different machines. On top of that, there is no guarantee *
55 | * that a user will "stick" with the same server between requests (whether *
56 | * HTTP or sockets), since the load balancer will route each request to the *
57 | * Sails server with the most available resources. However that means that *
58 | * all room/pubsub/socket processing and shared memory has to be offloaded *
59 | * to a shared, remote messaging queue (usually Redis) *
60 | * *
61 | * Luckily, Socket.io (and consequently Sails.js) apps support Redis for *
62 | * sockets by default. To enable a remote redis pubsub server, uncomment *
63 | * the config below. *
64 | * *
65 | * Worth mentioning is that, if `adapter` config is `redis`, but host/port *
66 | * is left unset, Sails will try to connect to redis running on localhost *
67 | * via port 6379 *
68 | * *
69 | ***************************************************************************/
70 | // adapter: 'memory',
71 |
72 | //
73 | // -OR-
74 | //
75 |
76 | // adapter: 'socket.io-redis',
77 | // host: '127.0.0.1',
78 | // port: 6379,
79 | // db: 0,
80 | // pass: '',
81 |
82 |
83 |
84 | /***************************************************************************
85 | * *
86 | * Whether to expose a 'get /__getcookie' route with CORS support that sets *
87 | * a cookie (this is used by the sails.io.js socket client to get access to *
88 | * a 3rd party cookie and to enable sessions). *
89 | * *
90 | * Warning: Currently in this scenario, CORS settings apply to interpreted *
91 | * requests sent via a socket.io connection that used this cookie to *
92 | * connect, even for non-browser clients! (e.g. iOS apps, toasters, node.js *
93 | * unit tests) *
94 | * *
95 | ***************************************************************************/
96 |
97 | // grant3rdPartyCookie: true,
98 |
99 |
100 |
101 | /***************************************************************************
102 | * *
103 | * `beforeConnect` *
104 | * *
105 | * This custom beforeConnect function will be run each time BEFORE a new *
106 | * socket is allowed to connect, when the initial socket.io handshake is *
107 | * performed with the server. *
108 | * *
109 | * By default, when a socket tries to connect, Sails allows it, every time. *
110 | * (much in the same way any HTTP request is allowed to reach your routes. *
111 | * If no valid cookie was sent, a temporary session will be created for the *
112 | * connecting socket. *
113 | * *
114 | * If the cookie sent as part of the connection request doesn't match any *
115 | * known user session, a new user session is created for it. *
116 | * *
117 | * In most cases, the user would already have a cookie since they loaded *
118 | * the socket.io client and the initial HTML page you're building. *
119 | * *
120 | * However, in the case of cross-domain requests, it is possible to receive *
121 | * a connection upgrade request WITHOUT A COOKIE (for certain transports) *
122 | * In this case, there is no way to keep track of the requesting user *
123 | * between requests, since there is no identifying information to link *
124 | * him/her with a session. The sails.io.js client solves this by connecting *
125 | * to a CORS/jsonp endpoint first to get a 3rd party cookie(fortunately this*
126 | * works, even in Safari), then opening the connection. *
127 | * *
128 | * You can also pass along a ?cookie query parameter to the upgrade url, *
129 | * which Sails will use in the absence of a proper cookie e.g. (when *
130 | * connecting from the client): *
131 | * io.sails.connect('http://localhost:1337?cookie=smokeybear') *
132 | * *
133 | * Finally note that the user's cookie is NOT (and will never be) accessible*
134 | * from client-side javascript. Using HTTP-only cookies is crucial for your *
135 | * app's security. *
136 | * *
137 | ***************************************************************************/
138 | // beforeConnect: function(handshake, cb) {
139 | // // `true` allows the connection
140 | // return cb(null, true);
141 | //
142 | // // (`false` would reject the connection)
143 | // },
144 |
145 |
146 | /***************************************************************************
147 | * *
148 | * `afterDisconnect` *
149 | * *
150 | * This custom afterDisconnect function will be run each time a socket *
151 | * disconnects *
152 | * *
153 | ***************************************************************************/
154 | // afterDisconnect: function(session, socket, cb) {
155 | // // By default: do nothing.
156 | // return cb();
157 | // },
158 |
159 | /***************************************************************************
160 | * *
161 | * `transports` *
162 | * *
163 | * A array of allowed transport methods which the clients will try to use. *
164 | * On server environments that don't support sticky sessions, the "polling" *
165 | * transport should be disabled. *
166 | * *
167 | ***************************************************************************/
168 | // transports: ["polling", "websocket"]
169 |
170 | };
171 |
--------------------------------------------------------------------------------
/config/views.js:
--------------------------------------------------------------------------------
1 | /**
2 | * View Engine Configuration
3 | * (sails.config.views)
4 | *
5 | * Server-sent views are a classic and effective way to get your app up
6 | * and running. Views are normally served from controllers. Below, you can
7 | * configure your templating language/framework of choice and configure
8 | * Sails' layout support.
9 | *
10 | * For more information on views and layouts, check out:
11 | * http://sailsjs.org/#!/documentation/concepts/Views
12 | */
13 |
14 | module.exports.views = {
15 |
16 | /****************************************************************************
17 | * *
18 | * View engine (aka template language) to use for your app's *server-side* *
19 | * views *
20 | * *
21 | * Sails+Express supports all view engines which implement TJ Holowaychuk's *
22 | * `consolidate.js`, including, but not limited to: *
23 | * *
24 | * ejs, jade, handlebars, mustache underscore, hogan, haml, haml-coffee, *
25 | * dust atpl, eco, ect, jazz, jqtpl, JUST, liquor, QEJS, swig, templayed, *
26 | * toffee, walrus, & whiskers *
27 | * *
28 | * For more options, check out the docs: *
29 | * https://github.com/balderdashy/sails-wiki/blob/0.9/config.views.md#engine *
30 | * *
31 | ****************************************************************************/
32 |
33 | engine: 'ejs',
34 |
35 |
36 | /****************************************************************************
37 | * *
38 | * Layouts are simply top-level HTML templates you can use as wrappers for *
39 | * your server-side views. If you're using ejs or jade, you can take *
40 | * advantage of Sails' built-in `layout` support. *
41 | * *
42 | * When using a layout, when one of your views is served, it is injected *
43 | * into the `body` partial defined in the layout. This lets you reuse header *
44 | * and footer logic between views. *
45 | * *
46 | * NOTE: Layout support is only implemented for the `ejs` view engine! *
47 | * For most other engines, it is not necessary, since they implement *
48 | * partials/layouts themselves. In those cases, this config will be *
49 | * silently ignored. *
50 | * *
51 | * The `layout` setting may be set to one of the following: *
52 | * *
53 | * If `false`, layouts will be disabled. Otherwise, if a string is *
54 | * specified, it will be interpreted as the relative path to your layout *
55 | * file from `views/` folder. (the file extension, ".ejs", should be *
56 | * omitted) *
57 | * *
58 | ****************************************************************************/
59 |
60 | /****************************************************************************
61 | * *
62 | * Using Multiple Layouts *
63 | * *
64 | * If you're using the default `ejs` or `handlebars` Sails supports the use *
65 | * of multiple `layout` files. To take advantage of this, before rendering a *
66 | * view, override the `layout` local in your controller by setting *
67 | * `res.locals.layout`. (this is handy if you parts of your app's UI look *
68 | * completely different from each other) *
69 | * *
70 | * e.g. your default might be *
71 | * layout: 'layouts/public' *
72 | * *
73 | * But you might override that in some of your controllers with: *
74 | * layout: 'layouts/internal' *
75 | * *
76 | ****************************************************************************/
77 |
78 | layout: 'layout',
79 |
80 | /****************************************************************************
81 | * *
82 | * Partials are simply top-level snippets you can leverage to reuse template *
83 | * for your server-side views. If you're using handlebars, you can take *
84 | * advantage of Sails' built-in `partials` support. *
85 | * *
86 | * If `false` or empty partials will be located in the same folder as views. *
87 | * Otherwise, if a string is specified, it will be interpreted as the *
88 | * relative path to your partial files from `views/` folder. *
89 | * *
90 | ****************************************************************************/
91 |
92 | partials: false
93 |
94 |
95 | };
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "connect-redis": "^3.2.0",
4 | "ejs": "2.3.4",
5 | "foreman": "2.0.0",
6 | "google-translate": "^1.0.9",
7 | "grunt": "1.0.1",
8 | "grunt-bower-task": "^0.3.4",
9 | "grunt-contrib-clean": "1.0.0",
10 | "grunt-contrib-coffee": "1.0.0",
11 | "grunt-contrib-concat": "1.0.1",
12 | "grunt-contrib-copy": "1.0.0",
13 | "grunt-contrib-cssmin": "1.0.1",
14 | "grunt-contrib-jst": "1.0.0",
15 | "grunt-contrib-less": "1.3.0",
16 | "grunt-contrib-uglify": "2.1.0",
17 | "grunt-contrib-watch": "1.0.0",
18 | "grunt-sails-linker": "~0.10.1",
19 | "grunt-sync": "0.5.2",
20 | "include-all": "^1.0.0",
21 | "jquery": "^3.1.1",
22 | "mongodb": "^2.2.24",
23 | "mstranslator": "^2.1.1",
24 | "rc": "1.0.1",
25 | "redis": "^2.6.5",
26 | "sails": "~0.12.11",
27 | "sails-disk": "~0.10.9",
28 | "sails-generate-bower": "0.0.2",
29 | "sails-hook-babel": "^6.0.3",
30 | "sails-mongo": "^0.12.2",
31 | "socket.io-client": "^1.7.2",
32 | "socket.io-redis": "^4.0.0"
33 | },
34 | "name": "chat-app",
35 | "private": true,
36 | "version": "0.0.0",
37 | "description": "a Sails application",
38 | "keywords": [],
39 | "scripts": {
40 | "start": "sails lift",
41 | "debug": "node debug app.js"
42 | },
43 | "main": "app.js",
44 | "repository": {
45 | "type": "git",
46 | "url": "git://github.com/william/chat-app.git"
47 | },
48 | "author": "william",
49 | "license": ""
50 | }
51 |
--------------------------------------------------------------------------------
/tasks/README.md:
--------------------------------------------------------------------------------
1 | # About the `tasks` folder
2 |
3 | The `tasks` directory is a suite of Grunt tasks and their configurations, bundled for your convenience. The Grunt integration is mainly useful for bundling front-end assets, (like stylesheets, scripts, & markup templates) but it can also be used to run all kinds of development tasks, from browserify compilation to database migrations.
4 |
5 | If you haven't used [Grunt](http://gruntjs.com/) before, be sure to check out the [Getting Started](http://gruntjs.com/getting-started) guide, as it explains how to create a [Gruntfile](http://gruntjs.com/sample-gruntfile) as well as install and use Grunt plugins. Once you're familiar with that process, read on!
6 |
7 |
8 | ### How does this work?
9 |
10 | The asset pipeline bundled in Sails is a set of Grunt tasks configured with conventional defaults designed to make your project more consistent and productive.
11 |
12 | The entire front-end asset workflow in Sails is completely customizable-- while it provides some suggestions out of the box, Sails makes no pretense that it can anticipate all of the needs you'll encounter building the browser-based/front-end portion of your application. Who's to say you're even building an app for a browser?
13 |
14 |
15 |
16 | ### What tasks does Sails run automatically?
17 |
18 | Sails runs some of these tasks (the ones in the `tasks/register` folder) automatically when you run certain commands.
19 |
20 | ###### `sails lift`
21 |
22 | Runs the `default` task (`tasks/register/default.js`).
23 |
24 | ###### `sails lift --prod`
25 |
26 | Runs the `prod` task (`tasks/register/prod.js`).
27 |
28 | ###### `sails www`
29 |
30 | Runs the `build` task (`tasks/register/build.js`).
31 |
32 | ###### `sails www --prod` (production)
33 |
34 | Runs the `buildProd` task (`tasks/register/buildProd.js`).
35 |
36 |
37 | ### Can I customize this for SASS, Angular, client-side Jade templates, etc?
38 |
39 | You can modify, omit, or replace any of these Grunt tasks to fit your requirements. You can also add your own Grunt tasks- just add a `someTask.js` file in the `grunt/config` directory to configure the new task, then register it with the appropriate parent task(s) (see files in `grunt/register/*.js`).
40 |
41 |
42 | ### Do I have to use Grunt?
43 |
44 | Nope! To disable Grunt integration in Sails, just delete your Gruntfile or disable the Grunt hook.
45 |
46 |
47 | ### What if I'm not building a web frontend?
48 |
49 | That's ok! A core tenant of Sails is client-agnosticism-- it's especially designed for building APIs used by all sorts of clients; native Android/iOS/Cordova, serverside SDKs, etc.
50 |
51 | You can completely disable Grunt by following the instructions above.
52 |
53 | If you still want to use Grunt for other purposes, but don't want any of the default web front-end stuff, just delete your project's `assets` folder and remove the front-end oriented tasks from the `grunt/register` and `grunt/config` folders. You can also run `sails new myCoolApi --no-frontend` to omit the `assets` folder and front-end-oriented Grunt tasks for future projects. You can also replace your `sails-generate-frontend` module with alternative community generators, or create your own. This allows `sails new` to create the boilerplate for native iOS apps, Android apps, Cordova apps, SteroidsJS apps, etc.
54 |
55 |
--------------------------------------------------------------------------------
/tasks/config/bower.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Install bower components.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Installs bower components and copies the required files into the assets folder structure.
7 | *
8 | */
9 |
10 | module.exports = function(grunt) {
11 |
12 | grunt.config.set('bower', {
13 | install: {
14 | options: {
15 | targetDir: './assets/vendor',
16 | layout: 'byType',
17 | install: true,
18 | verbose: false,
19 | cleanTargetDir: true,
20 | cleanBowerDir: true,
21 | bowerOptions: {}
22 | }
23 | }
24 | });
25 |
26 | grunt.loadNpmTasks('grunt-bower-task');
27 | };
28 |
--------------------------------------------------------------------------------
/tasks/config/clean.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `clean`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Remove the files and folders in your Sails app's web root
7 | * (conventionally a hidden directory called `.tmp/public`).
8 | *
9 | * For usage docs see:
10 | * https://github.com/gruntjs/grunt-contrib-clean
11 | *
12 | */
13 | module.exports = function(grunt) {
14 |
15 | grunt.config.set('clean', {
16 | dev: ['.tmp/public/**'],
17 | build: ['www']
18 | });
19 |
20 | grunt.loadNpmTasks('grunt-contrib-clean');
21 | };
22 |
--------------------------------------------------------------------------------
/tasks/config/coffee.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `coffee`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Compile CoffeeScript files located in `assets/js` into Javascript
7 | * and generate new `.js` files in `.tmp/public/js`.
8 | *
9 | * For usage docs see:
10 | * https://github.com/gruntjs/grunt-contrib-coffee
11 | *
12 | */
13 | module.exports = function(grunt) {
14 |
15 | grunt.config.set('coffee', {
16 | dev: {
17 | options: {
18 | bare: true,
19 | sourceMap: true,
20 | sourceRoot: './'
21 | },
22 | files: [{
23 | expand: true,
24 | cwd: 'assets/js/',
25 | src: ['**/*.coffee'],
26 | dest: '.tmp/public/js/',
27 | ext: '.js'
28 | }]
29 | }
30 | });
31 |
32 | grunt.loadNpmTasks('grunt-contrib-coffee');
33 | };
34 |
--------------------------------------------------------------------------------
/tasks/config/concat.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `concat`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Concatenates the contents of multiple JavaScript and/or CSS files
7 | * into two new files, each located at `concat/production.js` and
8 | * `concat/production.css` respectively in `.tmp/public/concat`.
9 | *
10 | * This is used as an intermediate step to generate monolithic files
11 | * that can then be passed in to `uglify` and/or `cssmin` for minification.
12 | *
13 | * For usage docs see:
14 | * https://github.com/gruntjs/grunt-contrib-concat
15 | *
16 | */
17 | module.exports = function(grunt) {
18 |
19 | grunt.config.set('concat', {
20 | js: {
21 | src: require('../pipeline').jsFilesToInject,
22 | dest: '.tmp/public/concat/production.js'
23 | },
24 | css: {
25 | src: require('../pipeline').cssFilesToInject,
26 | dest: '.tmp/public/concat/production.css'
27 | }
28 | });
29 |
30 | grunt.loadNpmTasks('grunt-contrib-concat');
31 | };
32 |
--------------------------------------------------------------------------------
/tasks/config/copy.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `copy`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Copy files and/or folders from your `assets/` directory into
7 | * the web root (`.tmp/public`) so they can be served via HTTP,
8 | * and also for further pre-processing by other Grunt tasks.
9 | *
10 | * #### Normal usage (`sails lift`)
11 | * Copies all directories and files (except CoffeeScript and LESS)
12 | * from the `assets/` folder into the web root -- conventionally a
13 | * hidden directory located `.tmp/public`.
14 | *
15 | * #### Via the `build` tasklist (`sails www`)
16 | * Copies all directories and files from the .tmp/public directory into a www directory.
17 | *
18 | * For usage docs see:
19 | * https://github.com/gruntjs/grunt-contrib-copy
20 | *
21 | */
22 | module.exports = function(grunt) {
23 |
24 | grunt.config.set('copy', {
25 | dev: {
26 | files: [{
27 | expand: true,
28 | cwd: './assets',
29 | src: ['**/*.!(coffee|less)'],
30 | dest: '.tmp/public'
31 | }]
32 | },
33 | build: {
34 | files: [{
35 | expand: true,
36 | cwd: '.tmp/public',
37 | src: ['**/*'],
38 | dest: 'www'
39 | }]
40 | }
41 | });
42 |
43 | grunt.loadNpmTasks('grunt-contrib-copy');
44 | };
45 |
--------------------------------------------------------------------------------
/tasks/config/cssmin.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Compress CSS files.
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Minify the intermediate concatenated CSS stylesheet which was
7 | * prepared by the `concat` task at `.tmp/public/concat/production.css`.
8 | *
9 | * Together with the `concat` task, this is the final step that minifies
10 | * all CSS files from `assets/styles/` (and potentially your LESS importer
11 | * file from `assets/styles/importer.less`)
12 | *
13 | * For usage docs see:
14 | * https://github.com/gruntjs/grunt-contrib-cssmin
15 | *
16 | */
17 | module.exports = function(grunt) {
18 |
19 | grunt.config.set('cssmin', {
20 | dist: {
21 | src: ['.tmp/public/concat/production.css'],
22 | dest: '.tmp/public/min/production.min.css'
23 | }
24 | });
25 |
26 | grunt.loadNpmTasks('grunt-contrib-cssmin');
27 | };
28 |
--------------------------------------------------------------------------------
/tasks/config/jst.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `jst`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Precompile HTML templates using Underscore/Lodash notation into
7 | * functions, creating a `.jst` file. This can be brought into your HTML
8 | * via a ',
38 | appRoot: '.tmp/public'
39 | },
40 | files: {
41 | '.tmp/public/**/*.html': require('../pipeline').jsFilesToInject,
42 | 'views/**/*.html': require('../pipeline').jsFilesToInject,
43 | 'views/**/*.ejs': require('../pipeline').jsFilesToInject
44 | }
45 | },
46 |
47 | devJsRelative: {
48 | options: {
49 | startTag: '',
50 | endTag: '',
51 | fileTmpl: '',
52 | appRoot: '.tmp/public',
53 | relative: true
54 | },
55 | files: {
56 | '.tmp/public/**/*.html': require('../pipeline').jsFilesToInject,
57 | 'views/**/*.html': require('../pipeline').jsFilesToInject,
58 | 'views/**/*.ejs': require('../pipeline').jsFilesToInject
59 | }
60 | },
61 |
62 | prodJs: {
63 | options: {
64 | startTag: '',
65 | endTag: '',
66 | fileTmpl: '',
67 | appRoot: '.tmp/public'
68 | },
69 | files: {
70 | '.tmp/public/**/*.html': ['.tmp/public/min/production.min.js'],
71 | 'views/**/*.html': ['.tmp/public/min/production.min.js'],
72 | 'views/**/*.ejs': ['.tmp/public/min/production.min.js']
73 | }
74 | },
75 |
76 | prodJsRelative: {
77 | options: {
78 | startTag: '',
79 | endTag: '',
80 | fileTmpl: '',
81 | appRoot: '.tmp/public',
82 | relative: true
83 | },
84 | files: {
85 | '.tmp/public/**/*.html': ['.tmp/public/min/production.min.js'],
86 | 'views/**/*.html': ['.tmp/public/min/production.min.js'],
87 | 'views/**/*.ejs': ['.tmp/public/min/production.min.js']
88 | }
89 | },
90 |
91 | devStyles: {
92 | options: {
93 | startTag: '',
94 | endTag: '',
95 | fileTmpl: '',
96 | appRoot: '.tmp/public'
97 | },
98 |
99 | files: {
100 | '.tmp/public/**/*.html': require('../pipeline').cssFilesToInject,
101 | 'views/**/*.html': require('../pipeline').cssFilesToInject,
102 | 'views/**/*.ejs': require('../pipeline').cssFilesToInject
103 | }
104 | },
105 |
106 | devStylesRelative: {
107 | options: {
108 | startTag: '',
109 | endTag: '',
110 | fileTmpl: '',
111 | appRoot: '.tmp/public',
112 | relative: true
113 | },
114 |
115 | files: {
116 | '.tmp/public/**/*.html': require('../pipeline').cssFilesToInject,
117 | 'views/**/*.html': require('../pipeline').cssFilesToInject,
118 | 'views/**/*.ejs': require('../pipeline').cssFilesToInject
119 | }
120 | },
121 |
122 | prodStyles: {
123 | options: {
124 | startTag: '',
125 | endTag: '',
126 | fileTmpl: '',
127 | appRoot: '.tmp/public'
128 | },
129 | files: {
130 | '.tmp/public/index.html': ['.tmp/public/min/production.min.css'],
131 | 'views/**/*.html': ['.tmp/public/min/production.min.css'],
132 | 'views/**/*.ejs': ['.tmp/public/min/production.min.css']
133 | }
134 | },
135 |
136 | prodStylesRelative: {
137 | options: {
138 | startTag: '',
139 | endTag: '',
140 | fileTmpl: '',
141 | appRoot: '.tmp/public',
142 | relative: true
143 | },
144 | files: {
145 | '.tmp/public/index.html': ['.tmp/public/min/production.min.css'],
146 | 'views/**/*.html': ['.tmp/public/min/production.min.css'],
147 | 'views/**/*.ejs': ['.tmp/public/min/production.min.css']
148 | }
149 | },
150 |
151 | // Bring in JST template object
152 | devTpl: {
153 | options: {
154 | startTag: '',
155 | endTag: '',
156 | fileTmpl: '',
157 | appRoot: '.tmp/public'
158 | },
159 | files: {
160 | '.tmp/public/index.html': ['.tmp/public/jst.js'],
161 | 'views/**/*.html': ['.tmp/public/jst.js'],
162 | 'views/**/*.ejs': ['.tmp/public/jst.js']
163 | }
164 | },
165 |
166 | devJsJade: {
167 | options: {
168 | startTag: '// SCRIPTS',
169 | endTag: '// SCRIPTS END',
170 | fileTmpl: 'script(src="%s")',
171 | appRoot: '.tmp/public'
172 | },
173 | files: {
174 | 'views/**/*.jade': require('../pipeline').jsFilesToInject
175 | }
176 | },
177 |
178 | devJsRelativeJade: {
179 | options: {
180 | startTag: '// SCRIPTS',
181 | endTag: '// SCRIPTS END',
182 | fileTmpl: 'script(src="%s")',
183 | appRoot: '.tmp/public',
184 | relative: true
185 | },
186 | files: {
187 | 'views/**/*.jade': require('../pipeline').jsFilesToInject
188 | }
189 | },
190 |
191 | prodJsJade: {
192 | options: {
193 | startTag: '// SCRIPTS',
194 | endTag: '// SCRIPTS END',
195 | fileTmpl: 'script(src="%s")',
196 | appRoot: '.tmp/public'
197 | },
198 | files: {
199 | 'views/**/*.jade': ['.tmp/public/min/production.min.js']
200 | }
201 | },
202 |
203 | prodJsRelativeJade: {
204 | options: {
205 | startTag: '// SCRIPTS',
206 | endTag: '// SCRIPTS END',
207 | fileTmpl: 'script(src="%s")',
208 | appRoot: '.tmp/public',
209 | relative: true
210 | },
211 | files: {
212 | 'views/**/*.jade': ['.tmp/public/min/production.min.js']
213 | }
214 | },
215 |
216 | devStylesJade: {
217 | options: {
218 | startTag: '// STYLES',
219 | endTag: '// STYLES END',
220 | fileTmpl: 'link(rel="stylesheet", href="%s")',
221 | appRoot: '.tmp/public'
222 | },
223 |
224 | files: {
225 | 'views/**/*.jade': require('../pipeline').cssFilesToInject
226 | }
227 | },
228 |
229 | devStylesRelativeJade: {
230 | options: {
231 | startTag: '// STYLES',
232 | endTag: '// STYLES END',
233 | fileTmpl: 'link(rel="stylesheet", href="%s")',
234 | appRoot: '.tmp/public',
235 | relative: true
236 | },
237 |
238 | files: {
239 | 'views/**/*.jade': require('../pipeline').cssFilesToInject
240 | }
241 | },
242 |
243 | prodStylesJade: {
244 | options: {
245 | startTag: '// STYLES',
246 | endTag: '// STYLES END',
247 | fileTmpl: 'link(rel="stylesheet", href="%s")',
248 | appRoot: '.tmp/public'
249 | },
250 | files: {
251 | 'views/**/*.jade': ['.tmp/public/min/production.min.css']
252 | }
253 | },
254 |
255 | prodStylesRelativeJade: {
256 | options: {
257 | startTag: '// STYLES',
258 | endTag: '// STYLES END',
259 | fileTmpl: 'link(rel="stylesheet", href="%s")',
260 | appRoot: '.tmp/public',
261 | relative: true
262 | },
263 | files: {
264 | 'views/**/*.jade': ['.tmp/public/min/production.min.css']
265 | }
266 | },
267 |
268 | // Bring in JST template object
269 | devTplJade: {
270 | options: {
271 | startTag: '// TEMPLATES',
272 | endTag: '// TEMPLATES END',
273 | fileTmpl: 'script(type="text/javascript", src="%s")',
274 | appRoot: '.tmp/public'
275 | },
276 | files: {
277 | 'views/**/*.jade': ['.tmp/public/jst.js']
278 | }
279 | }
280 | });
281 |
282 | grunt.loadNpmTasks('grunt-sails-linker');
283 | };
284 |
--------------------------------------------------------------------------------
/tasks/config/sync.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `sync`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Synchronize files from the `assets` folder to `.tmp/public`,
7 | * smashing anything that's already there.
8 | *
9 | * This task synchronizes one directory with another (like rsync).
10 | * In the default Sails asset pipeline, it plays very similar role
11 | * to `grunt-contrib-copy`, but copies only those files that have
12 | * actually changed since the last time the task was run.
13 | *
14 | * For usage docs see:
15 | * https://github.com/tomusdrw/grunt-sync
16 | *
17 | */
18 | module.exports = function(grunt) {
19 |
20 | grunt.config.set('sync', {
21 | dev: {
22 | files: [{
23 | cwd: './assets',
24 | src: ['**/*.!(coffee|less)'],
25 | dest: '.tmp/public'
26 | }]
27 | }
28 | });
29 |
30 | grunt.loadNpmTasks('grunt-sync');
31 | };
32 |
--------------------------------------------------------------------------------
/tasks/config/uglify.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `uglify`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Minify client-side JavaScript files using UglifyJS.
7 | *
8 | * For usage docs see:
9 | * https://github.com/gruntjs/grunt-contrib-uglify
10 | *
11 | */
12 | module.exports = function(grunt) {
13 |
14 | grunt.config.set('uglify', {
15 | dist: {
16 | src: ['.tmp/public/concat/production.js'],
17 | dest: '.tmp/public/min/production.min.js'
18 | }
19 | });
20 |
21 | grunt.loadNpmTasks('grunt-contrib-uglify');
22 | };
23 |
--------------------------------------------------------------------------------
/tasks/config/watch.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `watch`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * Run predefined tasks whenever watched file patterns are added, changed or deleted.
7 | *
8 | * Watch for changes on:
9 | * - files in the `assets` folder
10 | * - the `tasks/pipeline.js` file
11 | * and re-run the appropriate tasks.
12 | *
13 | * For usage docs see:
14 | * https://github.com/gruntjs/grunt-contrib-watch
15 | *
16 | */
17 | module.exports = function(grunt) {
18 |
19 | grunt.config.set('watch', {
20 | assets: {
21 |
22 | // Assets to watch:
23 | files: ['assets/**/*', 'tasks/pipeline.js', '!**/node_modules/**'],
24 |
25 | // When assets are changed:
26 | tasks: ['syncAssets' , 'linkAssets' ]
27 | }
28 | });
29 |
30 | grunt.loadNpmTasks('grunt-contrib-watch');
31 | };
32 |
--------------------------------------------------------------------------------
/tasks/pipeline.js:
--------------------------------------------------------------------------------
1 | /**
2 | * grunt/pipeline.js
3 | *
4 | * The order in which your css, javascript, and template files should be
5 | * compiled and linked from your views and static HTML files.
6 | *
7 | * (Note that you can take advantage of Grunt-style wildcard/glob/splat expressions
8 | * for matching multiple files, and ! in front of an expression to ignore files.)
9 | *
10 | * For more information see:
11 | * https://github.com/balderdashy/sails-docs/blob/master/anatomy/myApp/tasks/pipeline.js.md
12 | */
13 |
14 |
15 | // CSS files to inject in order
16 | //
17 | // (if you're using LESS with the built-in default config, you'll want
18 | // to change `assets/styles/importer.less` instead.)
19 | var cssFilesToInject = [
20 | 'styles/**/*.css'
21 | ];
22 |
23 |
24 | // Client-side javascript files to inject in order
25 | // (uses Grunt-style wildcard/glob/splat expressions)
26 | var jsFilesToInject = [
27 |
28 | // Load sails.io before everything else
29 | 'js/dependencies/sails.io.js',
30 |
31 | // Dependencies like jQuery, or Angular are brought in here
32 | 'js/dependencies/linkify.min.js',
33 | 'js/dependencies/**/*.js',
34 |
35 | // All of the rest of your client-side js files
36 | // will be injected here in no particular order.
37 | 'js/**/*.js'
38 | ];
39 |
40 |
41 | // Client-side HTML templates are injected using the sources below
42 | // The ordering of these templates shouldn't matter.
43 | // (uses Grunt-style wildcard/glob/splat expressions)
44 | //
45 | // By default, Sails uses JST templates and precompiles them into
46 | // functions for you. If you want to use jade, handlebars, dust, etc.,
47 | // with the linker, no problem-- you'll just want to make sure the precompiled
48 | // templates get spit out to the same file. Be sure and check out `tasks/README.md`
49 | // for information on customizing and installing new tasks.
50 | var templateFilesToInject = [
51 | 'templates/**/*.html'
52 | ];
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | // Default path for public folder (see documentation for more information)
61 | var tmpPath = '.tmp/public/';
62 |
63 | // Prefix relative paths to source files so they point to the proper locations
64 | // (i.e. where the other Grunt tasks spit them out, or in some cases, where
65 | // they reside in the first place)
66 | module.exports.cssFilesToInject = cssFilesToInject.map(function(cssPath) {
67 | // If we're ignoring the file, make sure the ! is at the beginning of the path
68 | if (cssPath[0] === '!') {
69 | return require('path').join('!.tmp/public/', cssPath.substr(1));
70 | }
71 | return require('path').join('.tmp/public/', cssPath);
72 | });
73 | module.exports.jsFilesToInject = jsFilesToInject.map(function(jsPath) {
74 | // If we're ignoring the file, make sure the ! is at the beginning of the path
75 | if (jsPath[0] === '!') {
76 | return require('path').join('!.tmp/public/', jsPath.substr(1));
77 | }
78 | return require('path').join('.tmp/public/', jsPath);
79 | });
80 | module.exports.templateFilesToInject = templateFilesToInject.map(function(tplPath) {
81 | // If we're ignoring the file, make sure the ! is at the beginning of the path
82 | if (tplPath[0] === '!') {
83 | return require('path').join('!assets/', tplPath.substr(1));
84 | }
85 | return require('path').join('assets/',tplPath);
86 | });
87 |
88 |
89 |
--------------------------------------------------------------------------------
/tasks/register/build.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `build`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist will be executed if you run `sails www` or
7 | * `grunt build` in a development environment. It generates a
8 | * folder containing your compiled assets, e.g. for troubleshooting
9 | * issues with other Grunt plugins, bundling assets for an Electron
10 | * or PhoneGap app, or deploying your app's flat files to a CDN.
11 | *
12 | * Note that when running `sails www` in a production environment (with the
13 | * `NODE_ENV` environment variable set to 'production') the `buildProd` task
14 | * will be run instead of this one.
15 | *
16 | * For more information see:
17 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/build-js
18 | *
19 | */
20 | module.exports = function(grunt) {
21 | grunt.registerTask('build', [
22 | 'compileAssets',
23 | 'linkAssetsBuild',
24 | 'clean:build',
25 | 'copy:build'
26 | ]);
27 | };
28 |
--------------------------------------------------------------------------------
/tasks/register/buildProd.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `buildProd`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist will be executed instead of `build` if you
7 | * run `sails www` in a production environment, e.g.:
8 | * `NODE_ENV=production sails www`
9 | *
10 | * This generates a folder containing your compiled (and usually minified)
11 | * assets. The most common use case for this is bundling up files to
12 | * deploy to a CDN.
13 | *
14 | * For more information see:
15 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/build-prod-js
16 | *
17 | */
18 | module.exports = function(grunt) {
19 | grunt.registerTask('buildProd', [
20 | 'compileAssets',
21 | 'concat',
22 | 'uglify',
23 | 'cssmin',
24 | 'linkAssetsBuildProd',
25 | 'clean:build',
26 | 'copy:build'
27 | ]);
28 | };
29 |
30 |
--------------------------------------------------------------------------------
/tasks/register/compileAssets.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `compileAssets`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist is not designed to be used directly-- rather
7 | * it is a helper called by the `default`, `prod`, `build`, and
8 | * `buildProd` tasklists.
9 | *
10 | * For more information see:
11 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/compile-assets-js
12 | *
13 | */
14 | module.exports = function(grunt) {
15 | grunt.registerTask('compileAssets', [
16 | 'clean:dev',
17 | 'jst:dev',
18 | 'less:dev',
19 | 'copy:dev',
20 | 'coffee:dev'
21 | ]);
22 | };
23 |
--------------------------------------------------------------------------------
/tasks/register/default.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `default`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This is the default Grunt tasklist that will be executed if you
7 | * run `grunt` in the top level directory of your app. It is also
8 | * called automatically when you start Sails in development mode using
9 | * `sails lift` or `node app`.
10 | *
11 | * Note that when lifting your app with a custom environment setting
12 | * (i.e. `sails.config.environment`), Sails will look for a tasklist file
13 | * with the same name and run that instead of this one.
14 | *
15 | * > Note that as a special case for compatibility/historial reasons, if
16 | * > your environment is "production", and Sails cannot find a tasklist named
17 | * > `production.js`, it will attempt to run the `prod.js` tasklist as well
18 | * > before defaulting to `default.js`.
19 | *
20 | * For more information see:
21 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/default-js
22 | *
23 | */
24 | module.exports = function (grunt) {
25 | grunt.registerTask('default', ['compileAssets', 'linkAssets', 'watch']);
26 | };
27 |
--------------------------------------------------------------------------------
/tasks/register/linkAssets.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `linkAssets`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist is not designed to be used directly-- rather
7 | * it is a helper called by the `default` tasklist and the `watch` task
8 | * (but only if the `grunt-sails-linker` package is in use).
9 | *
10 | * For more information see:
11 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/link-assets-js
12 | *
13 | */
14 | module.exports = function(grunt) {
15 | grunt.registerTask('linkAssets', [
16 | 'sails-linker:devJs',
17 | 'sails-linker:devStyles',
18 | 'sails-linker:devTpl',
19 | 'sails-linker:devJsJade',
20 | 'sails-linker:devStylesJade',
21 | 'sails-linker:devTplJade'
22 | ]);
23 | };
24 |
--------------------------------------------------------------------------------
/tasks/register/linkAssetsBuild.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `linkAssetsBuild`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist is not designed to be used directly-- rather
7 | * it is a helper called by the `build` tasklist.
8 | *
9 | * For more information see:
10 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/link-assets-build-js
11 | *
12 | */
13 | module.exports = function(grunt) {
14 | grunt.registerTask('linkAssetsBuild', [
15 | 'sails-linker:devJsRelative',
16 | 'sails-linker:devStylesRelative',
17 | 'sails-linker:devTpl',
18 | 'sails-linker:devJsRelativeJade',
19 | 'sails-linker:devStylesRelativeJade',
20 | 'sails-linker:devTplJade'
21 | ]);
22 | };
23 |
--------------------------------------------------------------------------------
/tasks/register/linkAssetsBuildProd.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `linkAssetsBuildProd`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist is not designed to be used directly-- rather
7 | * it is a helper called by the `buildProd` tasklist.
8 | *
9 | * For more information see:
10 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/link-assets-build-prod-js
11 | *
12 | */
13 | module.exports = function(grunt) {
14 | grunt.registerTask('linkAssetsBuildProd', [
15 | 'sails-linker:prodJsRelative',
16 | 'sails-linker:prodStylesRelative',
17 | 'sails-linker:devTpl',
18 | 'sails-linker:prodJsRelativeJade',
19 | 'sails-linker:prodStylesRelativeJade',
20 | 'sails-linker:devTplJade'
21 | ]);
22 | };
23 |
--------------------------------------------------------------------------------
/tasks/register/prod.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `prod`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist will be executed instead of `default` when
7 | * your Sails app is lifted in a production environment (e.g. using
8 | * `NODE_ENV=production node app`).
9 | *
10 | * For more information see:
11 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/prod-js
12 | *
13 | */
14 | module.exports = function(grunt) {
15 | grunt.registerTask('prod', [
16 | 'compileAssets',
17 | 'concat',
18 | 'uglify',
19 | 'cssmin',
20 | 'sails-linker:prodJs',
21 | 'sails-linker:prodStyles',
22 | 'sails-linker:devTpl',
23 | 'sails-linker:prodJsJade',
24 | 'sails-linker:prodStylesJade',
25 | 'sails-linker:devTplJade'
26 | ]);
27 | };
28 |
--------------------------------------------------------------------------------
/tasks/register/syncAssets.js:
--------------------------------------------------------------------------------
1 | /**
2 | * `syncAssets`
3 | *
4 | * ---------------------------------------------------------------
5 | *
6 | * This Grunt tasklist is not designed to be used directly-- rather
7 | * it is a helper called by the `watch` task (`tasks/config/watch.js`).
8 | *
9 | * For more information see:
10 | * http://sailsjs.org/documentation/anatomy/my-app/tasks/register/sync-assets-js
11 | *
12 | */
13 | module.exports = function(grunt) {
14 | grunt.registerTask('syncAssets', [
15 | 'jst:dev',
16 | 'less:dev',
17 | 'sync:dev',
18 | 'coffee:dev'
19 | ]);
20 | };
21 |
--------------------------------------------------------------------------------
/views/403.ejs:
--------------------------------------------------------------------------------
1 |
35 |
36 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Forbidden
49 |
50 |
51 | <% if (typeof data !== 'undefined') { %>
52 | <%= data %>
53 | <% } else { %>
54 | You don't have permission to see the page you're trying to reach.
55 | <% } %>
56 |