diff --git a/.gitignore b/.gitignore index 65c4732e01..f85addaf20 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ node_g # various stuff that VC++ produces/uses Debug/ Release/ +!doc/blog/** *.sln !nodemsi.sln *.suo @@ -39,6 +40,5 @@ ipch/ /npm.wxs /tools/msvs/npm.wixobj email.md -blog.html deps/v8-* ./node_modules diff --git a/Makefile b/Makefile index 3eada059b4..17ab607e14 100644 --- a/Makefile +++ b/Makefile @@ -130,7 +130,13 @@ website_files = \ out/doc/changelog.html \ $(doc_images) -doc: program $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs) tools/doc/ +doc: program $(apidoc_dirs) $(website_files) $(apiassets) $(apidocs) tools/doc/ blog + +blogclean: + rm -rf out/blog + +blog: doc/blog out/Release/node tools/blog + out/Release/node tools/blog/generate.js doc/blog/ out/blog/ doc/blog.html $(apidoc_dirs): mkdir -p $@ @@ -160,6 +166,9 @@ email.md: ChangeLog tools/email-footer.md blog.html: email.md cat $< | ./node tools/doc/node_modules/.bin/marked > $@ +blog-upload: blog + rsync -r out/blog/ node@nodejs.org:~/web/nodejs.org/blog/ + website-upload: doc rsync -r out/doc/ node@nodejs.org:~/web/nodejs.org/ ssh node@nodejs.org '\ @@ -260,4 +269,4 @@ cpplint: lint: jslint cpplint -.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean check uninstall install install-includes install-bin all program staticlib dynamiclib test test-all website-upload pkg +.PHONY: lint cpplint jslint bench clean docopen docclean doc dist distclean check uninstall install install-includes install-bin all program staticlib dynamiclib test test-all website-upload pkg blog blogclean diff --git a/doc/blog.html b/doc/blog.html new file mode 100644 index 0000000000..718e5549b9 --- /dev/null +++ b/doc/blog.html @@ -0,0 +1,209 @@ + + + + + + + + + + <%= title %> + + + +
+ +
+ +
+
+ + + +
+ +
+

<%- title %>

+ <% if (typeof post !== 'undefined') { + // just one post on this page + %> +

<%= + post.author + ' - ' + + post.date.toUTCString().replace(/ GMT$/, '') + %>

+ + <%- post.content %> + +

Please post feedback and comments on + the Node.JS + user mailing list.

+ + <% + if (post.next || post.prev) { + if (post.prev) { + %>

← <%= + post.prev.title + %>

+ <% + } + if (post.next) { + %>

<%= + post.next.title + %> →

+ <% + } + } + } else { // not single post page + if (paginated && total > 1 ) { + if (page > 0) { + // add 1 to all of the displayed numbers, because + // humans are not zero-indexed like they ought to be. + %> +

+ ← Page <%- page %> +

+ <% + } + if (page < total - 1) { %> +

+ Page <%- page + 2 %> → +

+ <% + } + } + + posts.forEach(function(post) { + %> +
+

+

<%= + post.author + ' - ' + + post.date.toUTCString().replace(/ GMT$/, '') + %>

+ <%- post.content %> +
+ <% + }); + + if (paginated && total > 1 ) { + if (page > 0) { + // add 1 to all of the displayed numbers, because + // humans are not zero-indexed like they ought to be. + %> +

+ ← Page <%- page %> +

+ <% + } + if (page < total - 1) { %> +

+ Page <%- page + 2 %> → +

+ <% + } + } // pagination + } // not a single post + %> +
+
+ + + + + + + + + + diff --git a/doc/blog/README.md b/doc/blog/README.md new file mode 100644 index 0000000000..7d37706470 --- /dev/null +++ b/doc/blog/README.md @@ -0,0 +1,28 @@ +title: README.md +status: private + +# How This Blog Works + +Each `.md` file in this folder structure is a blog post. It has a +few headers and a markdown body. (HTML is allowed in the body as well.) + +The relevant headers are: + +1. title +2. author +3. status: Only posts with a status of "publish" are published. +4. category: The "release" category is treated a bit specially. +5. version: Only relevant for "release" category. +6. date +7. slug: The bit that goes on the url. Must be unique, will be + generated from the title and date if missing. + +Posts in the "release" category are only shown in the main lists when +they are the most recent release for that version family. The stable +branch supercedes its unstable counterpart, so the presence of a `0.8.2` +release notice will cause `0.7.10` to be hidden, but `0.6.19` would +be unaffected. + +The folder structure in the blog source does not matter. Organize files +here however makes sense. The metadata will be sorted out in the build +later. diff --git a/doc/blog/Uncategorized/an-easy-way-to-build-scalable-network-programs.md b/doc/blog/Uncategorized/an-easy-way-to-build-scalable-network-programs.md new file mode 100644 index 0000000000..e1a509ecd7 --- /dev/null +++ b/doc/blog/Uncategorized/an-easy-way-to-build-scalable-network-programs.md @@ -0,0 +1,16 @@ +title: An Easy Way to Build Scalable Network Programs +author: ryandahl +date: Tue Oct 04 2011 15:39:56 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: an-easy-way-to-build-scalable-network-programs + +Suppose you're writing a web server which does video encoding on each file upload. Video encoding is very much compute bound. Some recent blog posts suggest that Node.js would fail miserably at this. + +Using Node does not mean that you have to write a video encoding algorithm in JavaScript (a language without even 64 bit integers) and crunch away in the main server event loop. The suggested approach is to separate the I/O bound task of receiving uploads and serving downloads from the compute bound task of video encoding. In the case of video encoding this is accomplished by forking out to ffmpeg. Node provides advanced means of asynchronously controlling subprocesses for work like this. + +It has also been suggested that Node does not take advantage of multicore machines. Node has long supported load-balancing connections over multiple processes in just a few lines of code - in this way a Node server will use the available cores. In coming releases we'll make it even easier: just pass --balance on the command line and Node will manage the cluster of processes. + +Node has a clear purpose: provide an easy way to build scalable network programs. It is not a tool for every problem. Do not write a ray tracer with Node. Do not write a web browser with Node. Do however reach for Node if tasked with writing a DNS server, DHCP server, or even a video encoding server. + +By relying on the kernel to schedule and preempt computationally expensive tasks and to load balance incoming connections, Node appears less magical than server platforms that employ userland scheduling. So far, our focus on simplicity and transparency has paid off: the number of success stories from developers and corporations who are adopting the technology continues to grow. diff --git a/doc/blog/Uncategorized/development-environment.md b/doc/blog/Uncategorized/development-environment.md new file mode 100644 index 0000000000..f714181589 --- /dev/null +++ b/doc/blog/Uncategorized/development-environment.md @@ -0,0 +1,25 @@ +title: Development Environment +author: ryandahl +date: Mon Apr 04 2011 20:16:27 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: development-environment + +If you're compiling a software package because you need a particular version (e.g. the latest), then it requires a little bit more maintenance than using a package manager like dpkg. Software that you compile yourself should *not* go into /usr, it should go into your home directory. This is part of being a software developer. + +One way of doing this is to install everything into $HOME/local/$PACKAGE. Here is how I install node on my machine:
./configure --prefix=$HOME/local/node-v0.4.5 && make install
+ +To have my paths automatically set I put this inside my $HOME/.zshrc:
PATH="$HOME/local/bin:/opt/local/bin:/usr/bin:/sbin:/bin"
+LD_LIBRARY_PATH="/opt/local/lib:/usr/local/lib:/usr/lib"
+for i in $HOME/local/*; do
+  [ -d $i/bin ] && PATH="${i}/bin:${PATH}"
+  [ -d $i/sbin ] && PATH="${i}/sbin:${PATH}"
+  [ -d $i/include ] && CPATH="${i}/include:${CPATH}"
+  [ -d $i/lib ] && LD_LIBRARY_PATH="${i}/lib:${LD_LIBRARY_PATH}"
+  [ -d $i/lib/pkgconfig ] && PKG_CONFIG_PATH="${i}/lib/pkgconfig:${PKG_CONFIG_PATH}"
+  [ -d $i/share/man ] && MANPATH="${i}/share/man:${MANPATH}"
+done
+ +Node is under sufficiently rapid development that everyone should be compiling it themselves. A corollary of this is that npm (which should be installed alongside Node) does not require root to install packages. + +CPAN and RubyGems have blurred the lines between development tools and system package managers. With npm we wish to draw a clear line: it is not a system package manager. It is not for installing firefox or ffmpeg or OpenSSL; it is for rapidly downloading, building, and setting up Node packages. npm is a development tool. When a program written in Node becomes sufficiently mature it should be distributed as a tarball, .deb, .rpm, or other package system. It should not be distributed to end users with npm. diff --git a/doc/blog/Uncategorized/evolving-the-node-js-brand.md b/doc/blog/Uncategorized/evolving-the-node-js-brand.md new file mode 100644 index 0000000000..dbb7f852f1 --- /dev/null +++ b/doc/blog/Uncategorized/evolving-the-node-js-brand.md @@ -0,0 +1,34 @@ +title: Evolving the Node.js Brand +author: Emily Tanaka-Delgado +date: Mon Jul 11 2011 12:02:45 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: evolving-the-node-js-brand + +To echo Node’s evolutionary nature, we have refreshed the identity to help mark an exciting time for developers, businesses and users who benefit from the pioneering technology. + +Building a brand + +We began exploring elements to express Node.js and jettisoned preconceived notions about what we thought Node should look like, and focused on what Node is: kinetic,connectedscalablemodularmechanical and organic. Working with designer Chris Glass, our explorations emphasized Node's dynamism and formed a visual language based on structure, relationships and interconnectedness. + + + +Inspired by process visualization, we discovered pattern, form, and by relief, the hex shape. The angled infrastructure encourages energy to move through the letterforms. + + + +This language can expand into the organic network topography of Node or distill down into a single hex connection point. + +This scaling represents the dynamic nature of Node in a simple, distinct manner. + + + +We look forward to exploring this visual language as the technology charges into a very promising future. + + + +We hope you'll have fun using it. + +To download the new logo, visit nodejs.org/logos. + + diff --git a/doc/blog/Uncategorized/growing-up.md b/doc/blog/Uncategorized/growing-up.md new file mode 100644 index 0000000000..6faff59cec --- /dev/null +++ b/doc/blog/Uncategorized/growing-up.md @@ -0,0 +1,12 @@ +title: Growing up +author: ryandahl +date: Thu Dec 15 2011 11:59:15 GMT-0800 (PST) +status: publish +category: Uncategorized +slug: growing-up + +This week Microsoft announced support for Node in Windows Azure, their cloud computing platform. For the Node core team and the community, this is an important milestone. We've worked hard over the past six months reworking Node's machinery to support IO completion ports and Visual Studio to provide a good native port to Windows. The overarching goal of the port was to expand our user base to the largest number of developers. Happily, this has paid off in the form of being a first class citizen on Azure. Many users who would have never used Node as a pure unix tool are now up and running on the Windows platform. More users translates into a deeper and better ecosystem of modules, which makes for a better experience for everyone. + +We also redesigned our website - something that we've put off for a long time because we felt that Node was too nascent to dedicate marketing to it. But now that we have binary distributions for Macintosh and Windows, have bundled npm, and are serving millions of users at various companies, we felt ready to indulge in a new website and share of a few of our success stories on the home page. + +Work is on-going. We continue to improve the software, making performance improvements and adding isolate support, but Node is growing up. diff --git a/doc/blog/Uncategorized/jobs-nodejs-org.md b/doc/blog/Uncategorized/jobs-nodejs-org.md new file mode 100644 index 0000000000..bf8278b816 --- /dev/null +++ b/doc/blog/Uncategorized/jobs-nodejs-org.md @@ -0,0 +1,14 @@ +title: jobs.nodejs.org +author: ryandahl +date: Thu Mar 24 2011 23:05:22 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: jobs-nodejs-org + +We are starting an official jobs board for Node. There are two goals for this + +1. Promote the small emerging economy around this platform by having a central space for employers to find Node programmers. + +2. Make some money. We work hard to build this platform and taking a small tax for job posts seems a like reasonable "tip jar". + +jobs.nodejs.org diff --git a/doc/blog/Uncategorized/ldapjs-a-reprise-of-ldap.md b/doc/blog/Uncategorized/ldapjs-a-reprise-of-ldap.md new file mode 100644 index 0000000000..57d4af7fe1 --- /dev/null +++ b/doc/blog/Uncategorized/ldapjs-a-reprise-of-ldap.md @@ -0,0 +1,84 @@ +title: ldapjs: A reprise of LDAP +author: mcavage +date: Thu Sep 08 2011 14:25:43 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: ldapjs-a-reprise-of-ldap + +This post has been about 10 years in the making. My first job out of college was at IBM working on the Tivoli Directory Server, and at the time I had a preconceived notion that working on anything related to Internet RFCs was about as hot as you could get. I spent a lot of time back then getting "down and dirty" with everything about LDAP: the protocol, performance, storage engines, indexing and querying, caching, customer use cases and patterns, general network server patterns, etc. Basically, I soaked up as much as I possibly could while I was there. On top of that, I listened to all the "gray beards" tell me about the history of LDAP, which was a bizarre marriage of telecommunications conglomerates and graduate students. The point of this blog post is to give you a crash course in LDAP, and explain what makes ldapjs different. Allow me to be the gray beard for a bit... +

What is LDAP and where did it come from?

+ +Directory services were largely pioneered by the telecommunications companies (e.g., AT&T) to allow fast information retrieval of all the crap you'd expect would be in a telephone book and directory. That is, given a name, or an address, or an area code, or a number, or a foo support looking up customer records, billing information, routing information, etc. The efforts of several telcos came to exist in the X.500 standard(s). An X.500 directory is one of the most complicated beasts you can possibly imagine, but on a high note, there's +probably not a thing you can imagine in a directory service that wasn't thought of in there. It is literally the kitchen sink. Oh, and it doesn't run over IP (it's actually on the OSI model). + +Several years after X.500 had been deployed (at telcos, academic institutions, etc.), it became clear that the Internet was "for real." LDAP, the "Lightweight Directory Access Protocol," was invented to act purely as an IP-accessible gateway to an X.500 directory. + +At some point in the early 90's, a graduate student at the University of Michigan (with some help) cooked up the "grandfather" implementation of the LDAP protocol, which wasn't actually a "gateway," but rather a stand-alone implementation of LDAP. Said implementation, like many things at the time, was a process-per-connection concurrency model, and had "backends" (aka storage engine) for the file system and the Unix DB API. At some point the Berkeley Database (BDB) was put in, and still remains the de facto storage engine for most LDAP directories. + +Ok, so some a graduate student at UM wrote an LDAP server that wasn't a gateway. So what? Well, that UM code base turns out to be the thing that pretty much every vendor did a source license for. Those graduate students went off to Netscape later in the 90's, and largely dominated the market of LDAP middleware until Active Directory came along many years later (as far as I know, Active Directory is "from scratch", since while it's "almost" LDAP, it's different in a lot of ways). That Netscape code base was further bought and sold over the years to iPlanet, Sun Microsystems, and Red Hat (I'm probably missing somebody in that chain). It now lives in the Fedora umbrella as '389 Directory Server.' Probably the most popular fork of that code base now is OpenLDAP. + +IBM did the same thing, and the Directory Server I worked on was a fork of the UM code too, but it heavily diverged from the Netscape branches. The divergence was primarily due to: (1) backing to DB2 as opposed to BDB, and (2) needing to run on IBM's big iron like OS/400 and Z series mainframes. + +Macro point is that there have actually been very few "fresh" implementations of LDAP, and it gets a pretty bad reputation because at the end of the day you've got 20 years of "bolt-ons" to grad student code. Oh, and it was born out of ginormous telcos, so of course the protocol is overly complex. + +That said, while there certainly is some wacky stuff in the LDAP protocol itself, it really suffered from poor and buggy implementations more than the fact that LDAP itself was fundamentally flawed. As engine yard pointed out a few years back, you can think of LDAP as the original NoSQL store. +

LDAP: The Good Parts

+ +So what's awesome about LDAP? Since it's a directory system it maintains a hierarchy of your data, which as an information management pattern aligns +with _a lot_ of use case (the quintessential example is white pages for people in your company, but subscriptions to SaaS applications, "host groups" +for tracking machines/instances, physical goods tracking, etc., all have use cases that fit that organization scheme). For example, presumably at your job +you have a "reporting chain." Let's say a given record in LDAP (I'll use myself as a guinea pig here) looks like: +
    firstName: Mark
+    lastName: Cavage
+    city: Seattle
+    uid: markc
+    state: Washington
+    mail: mcavagegmailcom
+    phone: (206) 555-1212
+    title: Software Engineer
+    department: 123456
+    objectclass: joyentPerson
+The record for me would live under the tree of engineers I report to (and as an example some other popular engineers under said vice president) would look like: +
                   uid=david
+                    /
+               uid=bryan
+            /      |      \
+      uid=markc  uid=ryah  uid=isaacs
+Ok, so we've got a tree. It's not tremendously different from your filesystem, but how do we find people? LDAP has a rich search filter syntax that makes a lot of sense for key/value data (far more than tacking Map Reduce jobs on does, imo), and all search queries take a "start point" in the tree. Here's an example: let's say I wanted to find all "Software Engineers" in the entire company, a filter would look like: +
     (title="Software Engineer")
+And I'd just start my search from 'uid=david' in the example above. Let's say I wanted to find all software engineers who worked in Seattle: +
     (&(title="Software Engineer")(city=Seattle))
+I could keep going, but the gist is that LDAP has "full" boolean predicate logic, wildcard filters, etc. It's really rich. + +Oh, and on top of the technical merits, better or worse, it's an established standard for both administrators and applications (i.e., most "shipped" intranet software has either a local user repository or the ability to leverage an LDAP server somewhere). So there's a lot of compelling reasons to look at leveraging LDAP. +

ldapjs: Why do I care?

+ +As I said earlier, I spent a lot of time at IBM observing how customers used LDAP, and the real items I took away from that experience were: + + +For all the good parts of LDAP, those are really damned big failing points, and even I eventually abandoned LDAP for the greener pastures of NoSQL somewhere +along the way. But it always nagged at me that LDAP didn't get it's due because of a lot of implementation problems (to be clear, if I could, I'd change some +aspects of the protocol itself too, but that's a lot harder). + +Well, in the last year, I went to work for Joyent, and like everyone else, we have several use problems that are classic directory service problems. If you break down the list I outlined above: + + +So that's the crux of ldapjs right there. Giving you the ability to put LDAP back into your application while nailing those 4 fundamental problems that plague most existing LDAP deployments. + +The obvious question is how it turned out, and the answer is, honestly, better than I thought it would. When I set out to do this, I actually assumed I'd be shipping a much smaller percentage of the RFC than is there. There's actually about 95% of the core RFC implemented. I wasn't sure if the marriage of this protocol to node/JavaScript would work out, but if you've used express ever, this should be _really_ familiar. And I tried to make it as natural as possible to use "pure" JavaScript objects, rather than requiring the developer to understand ASN.1 (the binary wire protocol) or the LDAP RFC in detail (this one mostly worked out; ldap_modify is still kind of a PITA). + +Within 24 hours of releasing ldapjs on Twitter, there was an implementation of an address book that works with Thunderbird/Evolution, by the end of that weekend there was some slick integration with CouchDB, and ldapjs even got used in one of the node knockout apps. Off to a pretty good start! + +

The Road Ahead

+ +Hopefully you've been motivated to learn a little bit more about LDAP and try out ldapjs. The best place to start is probably the guide. After that you'll probably need to pick up a book from back in the day. ldapjs itself is still in its infancy; there's quite a bit of room to add some slick client-side logic (e.g., connection pools, automatic reconnects), easy to use schema validation, backends, etc. By the time this post is live, there will be experimental dtrace support if you're running on Mac OS X or preferably Joyent's SmartOS (shameless plug). And that nagging percentage of the protocol I didn't do will get filled in over time I suspect. If you've got an interest in any of this, send me some pull requests, but most importantly, I just want to see LDAP not just be a skeleton in the closet and get used in places where you should be using it. So get out there and write you some LDAP. diff --git a/doc/blog/Uncategorized/libuv-status-report.md b/doc/blog/Uncategorized/libuv-status-report.md new file mode 100644 index 0000000000..68637a43b9 --- /dev/null +++ b/doc/blog/Uncategorized/libuv-status-report.md @@ -0,0 +1,45 @@ +title: libuv status report +author: ryandahl +date: Fri Sep 23 2011 12:45:50 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: libuv-status-report + +We announced back in July that with Microsoft's support Joyent would be porting Node to Windows. This effort is ongoing but I thought it would be nice to make a status report post about the new platform library libuv which has resulted from porting Node to Windows. + +libuv's purpose is to abstract platform-dependent code in Node into one place where it can be tested for correctness and performance before bindings to V8 are added. Since Node is totally non-blocking, libuv turns out to be a rather useful library itself: a BSD-licensed, minimal, high-performance, cross-platform networking library. + +We attempt to not reinvent the wheel where possible. The entire Unix backend sits heavily on Marc Lehmann's beautiful libraries libev and libeio. For DNS we integrated with Daniel Stenberg's C-Ares. For cross-platform build-system support we're relying on Chrome's GYP meta-build system. + +The current implmented features are: + +The features we are working on still are + +For complete documentation see the header file: include/uv.h. There are a number of tests in the test directory which demonstrate the API. + +libuv supports Microsoft Windows operating systems since Windows XP SP2. It can be built with either Visual Studio or MinGW. Solaris 121 and later using GCC toolchain. Linux 2.6 or better using the GCC toolchain. Macinotsh Darwin using the GCC or XCode toolchain. It is known to work on the BSDs but we do not check the build regularly. + +In addition to Node v0.5, a number of projects have begun to use libuv: + +We hope to see more people contributing and using libuv in the future! diff --git a/doc/blog/Uncategorized/node-meetup-this-thursday.md b/doc/blog/Uncategorized/node-meetup-this-thursday.md new file mode 100644 index 0000000000..0dfb98dae5 --- /dev/null +++ b/doc/blog/Uncategorized/node-meetup-this-thursday.md @@ -0,0 +1,11 @@ +title: Node Meetup this Thursday +author: ryandahl +date: Tue Aug 02 2011 21:37:02 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: node-meetup-this-thursday + +http://nodejs.org/meetup/ +http://nodemeetup.eventbrite.com/ + +Three companies will describe their distributed Node applications. Sign up soon, space is limited! diff --git a/doc/blog/Uncategorized/node-office-hours-cut-short.md b/doc/blog/Uncategorized/node-office-hours-cut-short.md new file mode 100644 index 0000000000..48d0344057 --- /dev/null +++ b/doc/blog/Uncategorized/node-office-hours-cut-short.md @@ -0,0 +1,12 @@ +title: Node Office Hours Cut Short +author: ryandahl +date: Thu Apr 28 2011 09:04:35 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: node-office-hours-cut-short + +This week office hours are only from 4pm to 6pm. Isaac will be in the Joyent office in SF - everyone else is out of town. Sign up at http://nodeworkup.eventbrite.com/ if you would like to come. + +The week after, Thursday May 5th, we will all be at NodeConf in Portland. + +Normal office hours resume Thursday May 12th. diff --git a/doc/blog/Uncategorized/office-hours.md b/doc/blog/Uncategorized/office-hours.md new file mode 100644 index 0000000000..e4c94992ce --- /dev/null +++ b/doc/blog/Uncategorized/office-hours.md @@ -0,0 +1,12 @@ +title: Office Hours +author: ryandahl +date: Wed Mar 23 2011 21:42:47 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: office-hours + +Starting next Thursday Isaac, Tom, and I will be holding weekly office hours at Joyent HQ in San Francisco. Office hours are meant to be subdued working time - there are no talks and no alcohol. Bring your bugs or just come and hack with us. + +Our building requires that everyone attending be on a list so you must sign up at Event Brite. + +We start at 4p and end promptly at 8p. diff --git a/doc/blog/Uncategorized/porting-node-to-windows-with-microsoft%e2%80%99s-help.md b/doc/blog/Uncategorized/porting-node-to-windows-with-microsoft%e2%80%99s-help.md new file mode 100644 index 0000000000..d2be3e3ba2 --- /dev/null +++ b/doc/blog/Uncategorized/porting-node-to-windows-with-microsoft%e2%80%99s-help.md @@ -0,0 +1,12 @@ +title: Porting Node to Windows With Microsoft’s Help +author: ryandahl +date: Thu Jun 23 2011 15:22:58 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: porting-node-to-windows-with-microsoft%e2%80%99s-help + +I'm pleased to announce that Microsoft is partnering with Joyent in formally contributing resources towards porting Node to Windows. As you may have heard in a talk we gave earlier this year, we have started the undertaking of a native port to Windows - targeting the high-performance IOCP API. + +This requires a rather large modification of the core structure, and we're very happy to have official guidance and engineering resources from Microsoft. Rackspace is also contributing Bert Belder's time to this undertaking. + +The result will be an official binary node.exe releases on nodejs.org, which will work on Windows Azure and other Windows versions as far back as Server 2003. diff --git a/doc/blog/Uncategorized/profiling-node-js.md b/doc/blog/Uncategorized/profiling-node-js.md new file mode 100644 index 0000000000..ff259c3c42 --- /dev/null +++ b/doc/blog/Uncategorized/profiling-node-js.md @@ -0,0 +1,60 @@ +title: Profiling Node.js +author: Dave Pacheco +date: Wed Apr 25 2012 13:48:58 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: profiling-node-js + +It's incredibly easy to visualize where your Node program spends its time using DTrace and node-stackvis (a Node port of Brendan Gregg's FlameGraph tool): + +
    +
  1. Run your Node.js program as usual.
  2. +
  3. In another terminal, run: +
    +$ dtrace -o stacks.out -n 'profile-97/execname == "node" && arg1/{
    +    @[jstack(100, 8000)] = count(); } tick-60s { exit(0); }'
    + This will sample about 100 times per second for 60 seconds and emit results to stacks.out. Note that this will sample all running programs called "node". If you want a specific process, replace execname == "node" with pid == 12345 (the process id). +
  4. +
  5. Use the "stackvis" tool to transform this directly into a flame graph. First, install it: +
    $ npm install -g stackvis
    + then use stackvis to convert the DTrace output to a flamegraph: +
    $ stackvis dtrace flamegraph-svg < stacks.out > stacks.svg
    +
  6. +
  7. Open stacks.svg in your favorite browser.
  8. +
+ +You'll be looking at something like this: + + + +This is a visualization of all of the profiled call stacks. This example is from the "hello world" HTTP server on the Node.js home page under load. Start at the bottom, where you have "main", which is present in most Node stacks because Node spends most on-CPU time in the main thread. Above each row, you have the functions called by the frame beneath it. As you move up, you'll see actual JavaScript function names. The boxes in each row are not in chronological order, but their width indicates how much time was spent there. When you hover over each box, you can see exactly what percentage of time is spent in each function. This lets you see at a glance where your program spends its time. + +That's the summary. There are a few prerequisites: + + + +There are a few other notes: + + + +For more on the underlying pieces, see my previous post on Node.js profiling and Brendan's post on Flame Graphs. + +
+ +Dave Pacheco blogs at dtrace.org diff --git a/doc/blog/Uncategorized/some-new-node-projects.md b/doc/blog/Uncategorized/some-new-node-projects.md new file mode 100644 index 0000000000..77515af736 --- /dev/null +++ b/doc/blog/Uncategorized/some-new-node-projects.md @@ -0,0 +1,13 @@ +title: Some New Node Projects +author: ryandahl +date: Mon Aug 29 2011 08:30:41 GMT-0700 (PDT) +status: publish +category: Uncategorized +slug: some-new-node-projects + + +Download: http://nodejs.org/dist/node-v0.5.0.tar.gz + +Website: http://nodejs.org/docs/v0.5.0/ + +Documentation: http://nodejs.org/docs/v0.5.0/api/ diff --git a/doc/blog/release/node-v0-5-1.md b/doc/blog/release/node-v0-5-1.md new file mode 100644 index 0000000000..f9799d40bc --- /dev/null +++ b/doc/blog/release/node-v0-5-1.md @@ -0,0 +1,30 @@ +version: 0.5.1 +title: Node v0.5.1 +author: ryandahl +date: Thu Jul 14 2011 23:48:08 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-1 + +2011.07.14, Version 0.5.1 (unstable) + + + + + +Download: http://nodejs.org/dist/v0.5.1/node-v0.5.1.tar.gz + +Windows Build: http://nodejs.org/dist/v0.5.1/node.exe + +Documentation: http://nodejs.org/dist/v0.5.1/docs/api/ + +Website: http://nodejs.org/dist/v0.5.1/docs diff --git a/doc/blog/release/node-v0-5-10.md b/doc/blog/release/node-v0-5-10.md new file mode 100644 index 0000000000..47fb926427 --- /dev/null +++ b/doc/blog/release/node-v0-5-10.md @@ -0,0 +1,41 @@ +version: 0.5.10 +title: Node v0.5.10 +author: ryandahl +date: Fri Oct 21 2011 19:12:31 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-10 + +2011.10.21, Version 0.5.10 (unstable) + + + + +Download: http://nodejs.org/dist/v0.5.10/node-v0.5.10.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.10/node.exe + +Website: http://nodejs.org/docs/v0.5.10/ + +Documentation: http://nodejs.org/docs/v0.5.10/api/ diff --git a/doc/blog/release/node-v0-5-2.md b/doc/blog/release/node-v0-5-2.md new file mode 100644 index 0000000000..c44690f346 --- /dev/null +++ b/doc/blog/release/node-v0-5-2.md @@ -0,0 +1,27 @@ +version: 0.5.2 +title: Node v0.5.2 +author: ryandahl +date: Fri Jul 22 2011 11:40:22 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-2 + +2011.07.22, Version 0.5.2 (unstable) + + +Download: http://nodejs.org/dist/v0.5.2/node-v0.5.2.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.2/node.exe + +Website: http://nodejs.org/dist/v0.5.2/docs/ + +Documentation: http://nodejs.org/dist/v0.5.2/docs/api diff --git a/doc/blog/release/node-v0-5-3.md b/doc/blog/release/node-v0-5-3.md new file mode 100644 index 0000000000..f84a955f55 --- /dev/null +++ b/doc/blog/release/node-v0-5-3.md @@ -0,0 +1,53 @@ +version: 0.5.3 +title: Node v0.5.3 +author: ryandahl +date: Tue Aug 02 2011 08:03:06 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-3 + +2011.08.01, Version 0.5.3 (unstable) + + + + + +Download: http://nodejs.org/dist/v0.5.3/node-v0.5.3.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.3/node.exe + +Website: http://nodejs.org/dist/v0.5.3/docs + +Documentation: http://nodejs.org/dist/v0.5.3/docs/api diff --git a/doc/blog/release/node-v0-5-4.md b/doc/blog/release/node-v0-5-4.md new file mode 100644 index 0000000000..2dd02e12ad --- /dev/null +++ b/doc/blog/release/node-v0-5-4.md @@ -0,0 +1,36 @@ +version: 0.5.4 +title: Node v0.5.4 +author: ryandahl +date: Fri Aug 12 2011 08:38:26 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-4 + +2011.08.12, Version 0.5.4 (unstable) + + + + +Download: http://nodejs.org/dist/v0.5.4/node-v0.5.4.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.4/node.exe + +Website: http://nodejs.org/dist/v0.5.4/docs + +Documentation: http://nodejs.org/dist/v0.5.4/docs/api diff --git a/doc/blog/release/node-v0-5-5.md b/doc/blog/release/node-v0-5-5.md new file mode 100644 index 0000000000..886fac90ef --- /dev/null +++ b/doc/blog/release/node-v0-5-5.md @@ -0,0 +1,40 @@ +version: 0.5.5 +title: Node v0.5.5 +author: bennoordhuis +date: Fri Aug 26 2011 23:20:10 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-5 + +

2011.08.26, Version 0.5.5 (unstable)

+ +

Download: http://nodejs.org/dist/node-v0.5.5.tar.gz

+

Windows Executable: http://nodejs.org/dist/v0.5.5/node.exe

+

Website: http://nodejs.org/docs/v0.5.5/

+

Documentation: http://nodejs.org/docs/v0.5.5/api/

+

+ +Update: The .exe has a bug that results in incompatibility with Windows XP and Server 2003. This has been reported in issue #1592 and fixed. A new binary was made that is compatibile with the older Windows: http://nodejs.org/dist/v0.5.5/node-186364e.exe. diff --git a/doc/blog/release/node-v0-5-6.md b/doc/blog/release/node-v0-5-6.md new file mode 100644 index 0000000000..ca1a392b01 --- /dev/null +++ b/doc/blog/release/node-v0-5-6.md @@ -0,0 +1,49 @@ +version: 0.5.6 +title: Node v0.5.6 (unstable) +author: piscisaureus +date: Fri Sep 09 2011 16:30:39 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-6 + +2011.09.08, Version 0.5.6 (unstable) + +Download: http://nodejs.org/dist/v0.5.6/node-v0.5.6.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.6/node.exe + +Website: http://nodejs.org/docs/v0.5.6/ + +Documentation: http://nodejs.org/docs/v0.5.6/api/ diff --git a/doc/blog/release/node-v0-5-7-unstable.md b/doc/blog/release/node-v0-5-7-unstable.md new file mode 100644 index 0000000000..1b640e7dbe --- /dev/null +++ b/doc/blog/release/node-v0-5-7-unstable.md @@ -0,0 +1,35 @@ +version: 0.5.7 +title: Node v0.5.7 (unstable) +author: ryandahl +date: Fri Sep 16 2011 18:57:03 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-7-unstable + +2011.09.16, Version 0.5.7 (unstable) + + + + +Download: http://nodejs.org/dist/v0.5.7/node-v0.5.7.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.7/node.exe + +Website: http://nodejs.org/docs/v0.5.7/ + +Documentation: http://nodejs.org/docs/v0.5.7/api/ diff --git a/doc/blog/release/node-v0-5-8.md b/doc/blog/release/node-v0-5-8.md new file mode 100644 index 0000000000..9f0fc146c3 --- /dev/null +++ b/doc/blog/release/node-v0-5-8.md @@ -0,0 +1,26 @@ +version: 0.5.8 +title: Node v0.5.8 +author: ryandahl +date: Fri Sep 30 2011 16:47:11 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-8 + +2011.09.30, Version 0.5.8 (unstable) + +Download: http://nodejs.org/dist/v0.5.8/node-v0.5.8.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.8/node.exe + +Website: http://nodejs.org/docs/v0.5.8/ + +Documentation: http://nodejs.org/docs/v0.5.8/api/ diff --git a/doc/blog/release/node-v0-5-9.md b/doc/blog/release/node-v0-5-9.md new file mode 100644 index 0000000000..6e361bcc4f --- /dev/null +++ b/doc/blog/release/node-v0-5-9.md @@ -0,0 +1,27 @@ +version: 0.5.9 +title: Node v0.5.9 +author: ryandahl +date: Mon Oct 10 2011 19:06:21 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-5-9 + +2011.10.10, Version 0.5.9 (unstable) + + + +Download: http://nodejs.org/dist/v0.5.9/node-v0.5.9.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.5.9/node.exe + +Website: http://nodejs.org/docs/v0.5.9/ + +Documentation: http://nodejs.org/docs/v0.5.9/api/ diff --git a/doc/blog/release/node-v0-6-0.md b/doc/blog/release/node-v0-6-0.md new file mode 100644 index 0000000000..ea0e71373b --- /dev/null +++ b/doc/blog/release/node-v0-6-0.md @@ -0,0 +1,80 @@ +version: 0.6.0 +title: Node v0.6.0 +author: ryandahl +date: Sat Nov 05 2011 02:07:10 GMT-0700 (PDT) +status: publish +category: release +slug: node-v0-6-0 + +We are happy to announce the third stable branch of Node v0.6. We will be freezing JavaScript, C++, and binary interfaces for all v0.6 releases. + +The major differences between v0.4 and v0.6 are + +In order to support Windows we reworked much of the core architecture. There was some fear that our work would degrade performance on UNIX systems but this was not the case. Here is a Linux system we benched for demonstration: + + + + + +
v0.4.12 (linux)v0.6.0 (linux)
http_simple.js /bytes/1024 5461 r/s 6263 r/s
io.js read 19.75 mB/s 26.63 mB/s
io.js write 21.60 mB/s 17.40 mB/s
startup.js 74.7 ms 49.6 ms
+ +Bigger is better in http and io benchmarks, smaller is better in startup. The http benchmark was done with 600 clients on a 10GE network served from three load generation machines. + +In the last version of Node, v0.4, we could only run Node on Windows with Cygwin. Therefore we've gotten massive improvements by targeting the native APIs. Benchmarks on the same machine: + + + + + +
v0.4.12 (windows)v0.6.0 (windows)
http_simple.js /bytes/1024 3858 r/s 5823 r/s
io.js read 12.41 mB/s 26.51 mB/s
io.js write 12.61 mB/s 33.58 mB/s
startup.js 152.81 ms 52.04 ms
+ +We consider this a good intermediate stage for the Windows port. There is still work to be done. For example, we are not yet providing users with a blessed path for building addon modules in MS Visual Studio. Work will continue in later releases. + +For users upgrading code bases from v0.4 to v0.6 we've documented most of the issues that you will run into. Most people find the change painless. Despite the long list of changes most core APIs remain untouched. + +Our release cycle will be tightened dramatically now. Expect to see a new stable branch in January. We wish to eventually have our releases in sync with Chrome and V8's 6 week cycle. + +Thank you to everyone who contributed code, tests, docs, or sent in bug reports. + +Here are the changes between v0.5.12 and v0.6.0: + +2011.11.04, Version 0.6.0 (stable) + + +Download: http://nodejs.org/dist/v0.6.0/node-v0.6.0.tar.gz + +Windows Executable: http://nodejs.org/dist/v0.6.0/node.exe + +Website: http://nodejs.org/docs/v0.6.0/ + +Documentation: http://nodejs.org/docs/v0.6.0/api/ diff --git a/doc/blog/release/node-v0-6-1.md b/doc/blog/release/node-v0-6-1.md new file mode 100644 index 0000000000..14a0db4952 --- /dev/null +++ b/doc/blog/release/node-v0-6-1.md @@ -0,0 +1,33 @@ +version: 0.6.1 +title: Node v0.6.1 +author: ryandahl +date: Fri Nov 11 2011 15:34:15 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-1 + +2011.11.11, Version 0.6.1 (stable) + + + +Source Code: http://nodejs.org/dist/v0.6.1/node-v0.6.1.tar.gz + +Windows Installer: http://nodejs.org/dist/v0.6.1/node-v0.6.1.msi + +Macintosh Installer: http://nodejs.org/dist/v0.6.1/node-v0.6.1.pkg + +Website: http://nodejs.org/docs/v0.6.1/ + +Documentation: http://nodejs.org/docs/v0.6.1/api/ diff --git a/doc/blog/release/node-v0-6-10.md b/doc/blog/release/node-v0-6-10.md new file mode 100644 index 0000000000..a0ca4e4a37 --- /dev/null +++ b/doc/blog/release/node-v0-6-10.md @@ -0,0 +1,30 @@ +version: 0.6.10 +title: Node v0.6.10 +author: Isaac Schlueter +date: Thu Feb 02 2012 17:22:03 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-10 + +

2012.02.02, Version 0.6.10 (stable)

+ +

Source Code: http://nodejs.org/dist/v0.6.10/node-v0.6.10.tar.gz

+ +

Windows Installer: http://nodejs.org/dist/v0.6.10/node-v0.6.10.msi

+ +

Macintosh Installer: http://nodejs.org/dist/v0.6.10/node-v0.6.10.pkg

+ +

Website: http://nodejs.org/docs/v0.6.10/

+ +

Documentation: http://nodejs.org/docs/v0.6.10/api/

diff --git a/doc/blog/release/node-v0-6-2.md b/doc/blog/release/node-v0-6-2.md new file mode 100644 index 0000000000..b405268bc7 --- /dev/null +++ b/doc/blog/release/node-v0-6-2.md @@ -0,0 +1,27 @@ +version: 0.6.2 +title: Node v0.6.2 +author: bennoordhuis +date: Fri Nov 18 2011 15:35:32 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-2 + +

2011.11.18, Version 0.6.2 (stable)

+ +

Source Code: http://nodejs.org/dist/v0.6.2/node-v0.6.2.tar.gz

+

Windows Installer: http://nodejs.org/dist/v0.6.2/node-v0.6.2.msi

+

Macintosh Installer: http://nodejs.org/dist/v0.6.2/node-v0.6.2.pkg

+

Website: http://nodejs.org/docs/v0.6.2/

+

Documentation: http://nodejs.org/docs/v0.6.2/api/

diff --git a/doc/blog/release/node-v0-6-3.md b/doc/blog/release/node-v0-6-3.md new file mode 100644 index 0000000000..559c3d352a --- /dev/null +++ b/doc/blog/release/node-v0-6-3.md @@ -0,0 +1,30 @@ +version: 0.6.3 +title: Node v0.6.3 +author: piscisaureus +date: Fri Nov 25 2011 02:54:08 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-3 + +2011.11.25, Version 0.6.3 (stable) + +Source Code: http://nodejs.org/dist/v0.6.3/node-v0.6.3.tar.gz + +Windows Installer: http://nodejs.org/dist/v0.6.3/node-v0.6.3.msi + +Macintosh Installer: http://nodejs.org/dist/v0.6.3/node-v0.6.3.pkg + +Website: http://nodejs.org/docs/v0.6.3/ + +Documentation: http://nodejs.org/docs/v0.6.3/api/ diff --git a/doc/blog/release/node-v0-6-4.md b/doc/blog/release/node-v0-6-4.md new file mode 100644 index 0000000000..f99f15fc59 --- /dev/null +++ b/doc/blog/release/node-v0-6-4.md @@ -0,0 +1,31 @@ +version: 0.6.4 +title: Node v0.6.4 +author: bennoordhuis +date: Thu Dec 01 2011 18:20:14 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-4 + +2011.12.02, Version 0.6.4 (stable) + +Source Code: http://nodejs.org/dist/v0.6.4/node-v0.6.4.tar.gz + +Windows Installer: http://nodejs.org/dist/v0.6.4/node-v0.6.4.msi + +Macintosh Installer: http://nodejs.org/dist/v0.6.4/node-v0.6.4.pkg + +Website: http://nodejs.org/docs/v0.6.4/ + +Documentation: http://nodejs.org/docs/v0.6.4/api/ diff --git a/doc/blog/release/node-v0-6-5.md b/doc/blog/release/node-v0-6-5.md new file mode 100644 index 0000000000..832da74148 --- /dev/null +++ b/doc/blog/release/node-v0-6-5.md @@ -0,0 +1,21 @@ +version: 0.6.5 +title: Node v0.6.5 +author: ryandahl +date: Sun Dec 04 2011 00:59:57 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-5 + +2011.12.04, Version 0.6.5 (stable) + + +Source Code: http://nodejs.org/dist/v0.6.5/node-v0.6.5.tar.gz + +Windows Installer: http://nodejs.org/dist/v0.6.5/node-v0.6.5.msi + +Macintosh Installer: http://nodejs.org/dist/v0.6.5/node-v0.6.5.pkg + +Website: http://nodejs.org/docs/v0.6.5/ + +Documentation: http://nodejs.org/docs/v0.6.5/api/ diff --git a/doc/blog/release/node-v0-6-6.md b/doc/blog/release/node-v0-6-6.md new file mode 100644 index 0000000000..c52169a15a --- /dev/null +++ b/doc/blog/release/node-v0-6-6.md @@ -0,0 +1,32 @@ +version: 0.6.6 +title: Node v0.6.6 +author: Isaac Schlueter +date: Thu Dec 15 2011 11:07:57 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-6 + +2011.12.14, Version 0.6.6 (stable) + + + +Source Code: http://nodejs.org/dist/v0.6.6/node-v0.6.6.tar.gz + +Windows Installer: http://nodejs.org/dist/v0.6.6/node-v0.6.6.msi + +Macintosh Installer: http://nodejs.org/dist/v0.6.6/node-v0.6.6.pkg + +Website: http://nodejs.org/docs/v0.6.6/ + +Documentation: http://nodejs.org/docs/v0.6.6/api/ diff --git a/doc/blog/release/node-v0-6-7.md b/doc/blog/release/node-v0-6-7.md new file mode 100644 index 0000000000..0346f51c0c --- /dev/null +++ b/doc/blog/release/node-v0-6-7.md @@ -0,0 +1,41 @@ +version: 0.6.7 +title: Node v0.6.7 +author: Isaac Schlueter +date: Fri Jan 06 2012 17:54:49 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-7 + +

2012.01.06, Version 0.6.7 (stable)

+ + + +

Source Code: http://nodejs.org/dist/v0.6.7/node-v0.6.7.tar.gz

+ +

Windows Installer: http://nodejs.org/dist/v0.6.7/node-v0.6.7.msi

+ +

Macintosh Installer: http://nodejs.org/dist/v0.6.7/node-v0.6.7.pkg

+ +

Website: http://nodejs.org/docs/v0.6.7/

+ +

Documentation: http://nodejs.org/docs/v0.6.7/api/

diff --git a/doc/blog/release/node-v0-6-8.md b/doc/blog/release/node-v0-6-8.md new file mode 100644 index 0000000000..55de31eb6b --- /dev/null +++ b/doc/blog/release/node-v0-6-8.md @@ -0,0 +1,31 @@ +version: 0.6.8 +title: Node v0.6.8 +author: Isaac Schlueter +date: Thu Jan 19 2012 19:59:53 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-8 + +

2012.01.19, Version 0.6.8 (stable)

+ +

Source Code: http://nodejs.org/dist/v0.6.8/node-v0.6.8.tar.gz

+ +

Windows Installer: http://nodejs.org/dist/v0.6.8/node-v0.6.8.msi

+ +

Macintosh Installer: http://nodejs.org/dist/v0.6.8/node-v0.6.8.pkg

+ +

Website: http://nodejs.org/docs/v0.6.8/

+ +

Documentation: http://nodejs.org/docs/v0.6.8/api/

diff --git a/doc/blog/release/node-v0-6-9.md b/doc/blog/release/node-v0-6-9.md new file mode 100644 index 0000000000..05d992febd --- /dev/null +++ b/doc/blog/release/node-v0-6-9.md @@ -0,0 +1,30 @@ +version: 0.6.9 +title: Node v0.6.9 +author: Isaac Schlueter +date: Fri Jan 27 2012 16:58:18 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-6-9 + +

2012.01.27, Version 0.6.9 (stable)

+ +

Source Code: http://nodejs.org/dist/v0.6.9/node-v0.6.9.tar.gz

+ +

Windows Installer: http://nodejs.org/dist/v0.6.9/node-v0.6.9.msi

+ +

Macintosh Installer: http://nodejs.org/dist/v0.6.9/node-v0.6.9.pkg

+ +

Website: http://nodejs.org/docs/v0.6.9/

+ +

Documentation: http://nodejs.org/docs/v0.6.9/api/

diff --git a/doc/blog/release/node-v0-7-0-unstable.md b/doc/blog/release/node-v0-7-0-unstable.md new file mode 100644 index 0000000000..3036b9228f --- /dev/null +++ b/doc/blog/release/node-v0-7-0-unstable.md @@ -0,0 +1,29 @@ +version: 0.7.0 +title: Node v0.7.0 (Unstable) +author: ryandahl +date: Mon Jan 16 2012 19:58:28 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-7-0-unstable + +This is the first release in the unstable v0.7 series. Almost all users will want to remain using the stable v0.6 releases. + +2012.01.16, Version 0.7.0 (unstable) + + + +Source Code: http://nodejs.org/dist/v0.7.0/node-v0.7.0.tar.gz + +Windows Installer: http://nodejs.org/dist/v0.7.0/node-v0.7.0.msi + +Macintosh Installer: http://nodejs.org/dist/v0.7.0/node-v0.7.0.pkg + +Website: http://nodejs.org/docs/v0.7.0/ + +Documentation: http://nodejs.org/docs/v0.7.0/api/ diff --git a/doc/blog/release/node-v0-7-1.md b/doc/blog/release/node-v0-7-1.md new file mode 100644 index 0000000000..efb89d045d --- /dev/null +++ b/doc/blog/release/node-v0-7-1.md @@ -0,0 +1,30 @@ +version: 0.7.1 +title: Node v0.7.1 +author: Isaac Schlueter +date: Mon Jan 23 2012 17:35:59 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-7-1 + +

2012.01.23, Version 0.7.1 (unstable)

+ + + +

Source: http://nodejs.org/dist/v0.7.1/node-v0.7.1.tar.gz

+ +

Windows Installer: http://nodejs.org/dist/v0.7.1/node-v0.7.1.msi

+ +

Macintosh Installer: http://nodejs.org/dist/v0.7.1/node-v0.7.1.pkg

+ +

Website: http://nodejs.org/docs/v0.7.1/

+ +

Documentation: http://nodejs.org/docs/v0.7.1/api/

diff --git a/doc/blog/release/node-v0-7-2-unstable.md b/doc/blog/release/node-v0-7-2-unstable.md new file mode 100644 index 0000000000..d5c1f8fb82 --- /dev/null +++ b/doc/blog/release/node-v0-7-2-unstable.md @@ -0,0 +1,32 @@ +version: 0.7.2 +title: Node v0.7.2 (unstable) +author: Isaac Schlueter +date: Wed Feb 01 2012 13:13:04 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-7-2-unstable + +

2012.02.01, Version 0.7.2 (unstable)

+ +

Source Code: http://nodejs.org/dist/v0.7.2/node-v0.7.2.tar.gz

+ +

Windows Installer: http://nodejs.org/dist/v0.7.2/node-v0.7.2.msi

+ +

Macintosh Installer: http://nodejs.org/dist/v0.7.2/node-v0.7.2.pkg

+ +

Website: http://nodejs.org/docs/v0.7.2/

+ +

Documentation: http://nodejs.org/docs/v0.7.2/api/

diff --git a/doc/blog/release/node-v0-7-3.md b/doc/blog/release/node-v0-7-3.md new file mode 100644 index 0000000000..a0d93df12d --- /dev/null +++ b/doc/blog/release/node-v0-7-3.md @@ -0,0 +1,39 @@ +version: 0.7.3 +title: Node v0.7.3 (unstable) +author: Isaac Schlueter +date: Tue Feb 07 2012 17:08:27 GMT-0800 (PST) +status: publish +category: release +slug: node-v0-7-3 + +

2012.02.07, Version 0.7.3 (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.3/node-v0.7.3.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.3/node-v0.7.3.msi + +

+

Macintosh Installer: http://nodejs.org/dist/v0.7.3/node-v0.7.3.pkg + +

+

Website: http://nodejs.org/docs/v0.7.3/ + +

+

Documentation: http://nodejs.org/docs/v0.7.3/api/ +

diff --git a/doc/blog/release/node-version-0-6-19-stable.md b/doc/blog/release/node-version-0-6-19-stable.md new file mode 100644 index 0000000000..3a29556c57 --- /dev/null +++ b/doc/blog/release/node-version-0-6-19-stable.md @@ -0,0 +1,61 @@ +version: 0.6.19 +title: Node Version 0.6.19 (stable) +author: Isaac Schlueter +date: Wed Jun 06 2012 09:55:37 GMT-0700 (PDT) +status: publish +category: release +slug: node-version-0-6-19-stable + +

2012.06.06 Version 0.6.19 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.19/node-v0.6.19.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.19/node-v0.6.19.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.6.19/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.6.19/node-v0.6.19.pkg + +

+

Other release files: http://nodejs.org/dist/v0.6.19/ + +

+

Website: http://nodejs.org/docs/v0.6.19/ + +

+

Documentation: http://nodejs.org/docs/v0.6.19/api/ +

+ +

Shasums:

+
ef4f5c1e5f12f6ef3478a794d6a81f59669332f9  node-v0.6.19.msi
+781616f33208f532f168633758a648c20e1ea68b  node-v0.6.19.pkg
+f6c5cfbadff4788ac3a95f8263a0c2f4e07444b6  node-v0.6.19.tar.gz
+10f729ca236825821d97556441fa64f994cb4ca8  node.exe
+5b8cd02e5f92ed6512aabdac11766ad8c1abc436  node.exp
+20037e4901de605e08e48d0c85531334912844e3  node.lib
+c44f62852918d449850014d9b29dd073cb6920a5  node.pdb
+04db25c93c5357394941dd2de12cb61959eb82d1  x64/node-v0.6.19.msi
+f77c77f2e470cfc9071853af2f277ba91d660b9c  x64/node.exe
+fcf26a3f984a3f19804e0567414604b77b1d3bac  x64/node.exp
+bfed2a24f253dbac99379d6f22fc8e9e85ade7ed  x64/node.lib
+95226c1cc5170ea05c2e54431040f06c3e95e99f  x64/node.pdb
diff --git a/doc/blog/release/node-version-0-7-9-unstable.md b/doc/blog/release/node-version-0-7-9-unstable.md new file mode 100644 index 0000000000..cb077d6258 --- /dev/null +++ b/doc/blog/release/node-version-0-7-9-unstable.md @@ -0,0 +1,73 @@ +version: 0.7.9 +title: Node Version 0.7.9 (unstable) +author: Isaac Schlueter +date: Tue May 29 2012 10:11:45 GMT-0700 (PDT) +status: publish +category: release +slug: node-version-0-7-9-unstable + +

2012.05.28, Version 0.7.9 (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.9/node-v0.7.9.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.9/node-v0.7.9.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.7.9/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.7.9/node-v0.7.9.pkg + +

+

Other release files: http://nodejs.org/dist/v0.7.9/ + +

+

Website: http://nodejs.org/docs/v0.7.9/ + +

+

Documentation: http://nodejs.org/docs/v0.7.9/api/ +

diff --git a/doc/blog/release/version-0-6-11-stable.md b/doc/blog/release/version-0-6-11-stable.md new file mode 100644 index 0000000000..d57068f275 --- /dev/null +++ b/doc/blog/release/version-0-6-11-stable.md @@ -0,0 +1,64 @@ +version: 0.6.11 +title: Version 0.6.11 (stable) +author: Isaac Schlueter +date: Fri Feb 17 2012 13:32:55 GMT-0800 (PST) +status: publish +category: release +slug: version-0-6-11-stable + +

2012.02.17 Version 0.6.11 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.11/node-v0.6.11.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.11/node-v0.6.11.msi + +

+

Macintosh Installer: http://nodejs.org/dist/v0.6.11/node-v0.6.11.pkg + +

+

Website: http://nodejs.org/docs/v0.6.11/ + +

+

Documentation: http://nodejs.org/docs/v0.6.11/api/ +

diff --git a/doc/blog/release/version-0-6-12-stable.md b/doc/blog/release/version-0-6-12-stable.md new file mode 100644 index 0000000000..bd20ef7da9 --- /dev/null +++ b/doc/blog/release/version-0-6-12-stable.md @@ -0,0 +1,66 @@ +version: 0.6.12 +title: Version 0.6.12 (stable) +author: Isaac Schlueter +date: Fri Mar 02 2012 13:22:49 GMT-0800 (PST) +status: publish +category: release +slug: version-0-6-12-stable + +

2012.03.02 Version 0.6.12 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.12/node-v0.6.12.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.12/node-v0.6.12.msi + +

+

Macintosh Installer: http://nodejs.org/dist/v0.6.12/node-v0.6.12.pkg + +

+

Website: http://nodejs.org/docs/v0.6.12/ + +

+

Documentation: http://nodejs.org/docs/v0.6.12/api/ +

diff --git a/doc/blog/release/version-0-6-13-stable.md b/doc/blog/release/version-0-6-13-stable.md new file mode 100644 index 0000000000..2561c1df46 --- /dev/null +++ b/doc/blog/release/version-0-6-13-stable.md @@ -0,0 +1,50 @@ +version: 0.6.13 +title: Version 0.6.13 (stable) +author: Isaac Schlueter +date: Thu Mar 15 2012 10:37:02 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-6-13-stable + +

2012.03.15 Version 0.6.13 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.13/node-v0.6.13.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.13/node-v0.6.13.msi + +

+

Macintosh Installer: http://nodejs.org/dist/v0.6.13/node-v0.6.13.pkg + +

+

Website: http://nodejs.org/docs/v0.6.13/ + +

+

Documentation: http://nodejs.org/docs/v0.6.13/api/ +

diff --git a/doc/blog/release/version-0-6-14-stable.md b/doc/blog/release/version-0-6-14-stable.md new file mode 100644 index 0000000000..ba5183414c --- /dev/null +++ b/doc/blog/release/version-0-6-14-stable.md @@ -0,0 +1,55 @@ +version: 0.6.14 +title: Version 0.6.14 (stable) +author: Isaac Schlueter +date: Fri Mar 23 2012 11:22:22 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-6-14-stable + +

2012.03.22 Version 0.6.14 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.14/node-v0.6.14.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.14/node-v0.6.14.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.6.14/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.6.14/node-v0.6.14.pkg + +

+

Other release files: http://nodejs.org/dist/v0.6.14/ + +

+

Website: http://nodejs.org/docs/v0.6.14/ + +

+

Documentation: http://nodejs.org/docs/v0.6.14/api/ +

diff --git a/doc/blog/release/version-0-6-15-stable.md b/doc/blog/release/version-0-6-15-stable.md new file mode 100644 index 0000000000..e6f0502f74 --- /dev/null +++ b/doc/blog/release/version-0-6-15-stable.md @@ -0,0 +1,53 @@ +version: 0.6.15 +title: Version 0.6.15 (stable) +author: Isaac Schlueter +date: Mon Apr 09 2012 10:39:18 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-6-15-stable + +

2012.04.09 Version 0.6.15 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.15/node-v0.6.15.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.15/node-v0.6.15.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.6.15/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.6.15/node-v0.6.15.pkg + +

+

Other release files: http://nodejs.org/dist/v0.6.15/ + +

+

Website: http://nodejs.org/docs/v0.6.15/ + +

+

Documentation: http://nodejs.org/docs/v0.6.15/api/ +

diff --git a/doc/blog/release/version-0-6-16-stable.md b/doc/blog/release/version-0-6-16-stable.md new file mode 100644 index 0000000000..69f8b31700 --- /dev/null +++ b/doc/blog/release/version-0-6-16-stable.md @@ -0,0 +1,59 @@ +version: 0.6.16 +title: Version 0.6.16 (stable) +author: Isaac Schlueter +date: Mon Apr 30 2012 11:13:50 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-6-16-stable + +

2012.04.30 Version 0.6.16 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.16/node-v0.6.16.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.16/node-v0.6.16.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.6.16/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.6.16/node-v0.6.16.pkg + +

+

Other release files: http://nodejs.org/dist/v0.6.16/ + +

+

Website: http://nodejs.org/docs/v0.6.16/ + +

+

Documentation: http://nodejs.org/docs/v0.6.16/api/ +

diff --git a/doc/blog/release/version-0-6-17-stable.md b/doc/blog/release/version-0-6-17-stable.md new file mode 100644 index 0000000000..3512e1df2f --- /dev/null +++ b/doc/blog/release/version-0-6-17-stable.md @@ -0,0 +1,47 @@ +version: 0.6.17 +title: Version 0.6.17 (stable) +author: Isaac Schlueter +date: Fri May 04 2012 13:33:12 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-6-17-stable + +

2012.05.04 Version 0.6.17 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.17/node-v0.6.17.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.17/node-v0.6.17.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.6.17/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.6.17/node-v0.6.17.pkg + +

+

Other release files: http://nodejs.org/dist/v0.6.17/ + +

+

Website: http://nodejs.org/docs/v0.6.17/ + +

+

Documentation: http://nodejs.org/docs/v0.6.17/api/ +

diff --git a/doc/blog/release/version-0-6-18-stable.md b/doc/blog/release/version-0-6-18-stable.md new file mode 100644 index 0000000000..0cf179bfce --- /dev/null +++ b/doc/blog/release/version-0-6-18-stable.md @@ -0,0 +1,59 @@ +version: 0.6.18 +title: Version 0.6.18 (stable) +author: Isaac Schlueter +date: Tue May 15 2012 10:06:13 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-6-18-stable + +

2012.05.15 Version 0.6.18 (stable) + +

+ +

Source Code: http://nodejs.org/dist/v0.6.18/node-v0.6.18.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.6.18/node-v0.6.18.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.6.18/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.6.18/node-v0.6.18.pkg + +

+

Other release files: http://nodejs.org/dist/v0.6.18/ + +

+

Website: http://nodejs.org/docs/v0.6.18/ + +

+

Documentation: http://nodejs.org/docs/v0.6.18/api/ +

diff --git a/doc/blog/release/version-0-7-10-unstable.md b/doc/blog/release/version-0-7-10-unstable.md new file mode 100644 index 0000000000..3e14911147 --- /dev/null +++ b/doc/blog/release/version-0-7-10-unstable.md @@ -0,0 +1,86 @@ +version: 0.7.10 +title: Version 0.7.10 (unstable) +author: Isaac Schlueter +date: Mon Jun 11 2012 09:00:25 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-7-10-unstable + +

2012.06.11, Version 0.7.10 (unstable) + +

+

This is the second-to-last release on the 0.7 branch. Version 0.8.0 +will be released some time next week. As other even-numbered Node +releases before it, the v0.8.x releases will maintain API and binary +compatibility. + +

+

The major changes are detailed in +https://github.com/joyent/node/wiki/API-changes-between-v0.6-and-v0.8 + +

+

Please try out this release. There will be very few changes between +this and the v0.8.x release family. This is the last chance to comment +on the API before it is locked down for stability. + + +

+ +

Source Code: http://nodejs.org/dist/v0.7.10/node-v0.7.10.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.10/node-v0.7.10.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.7.10/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.7.10/node-v0.7.10.pkg + +

+

Other release files: http://nodejs.org/dist/v0.7.10/ + +

+

Website: http://nodejs.org/docs/v0.7.10/ + +

+

Documentation: http://nodejs.org/docs/v0.7.10/api/ +

diff --git a/doc/blog/release/version-0-7-11-unstable.md b/doc/blog/release/version-0-7-11-unstable.md new file mode 100644 index 0000000000..e8fd71a4e1 --- /dev/null +++ b/doc/blog/release/version-0-7-11-unstable.md @@ -0,0 +1,80 @@ +version: 0.7.11 +title: Version 0.7.11 (unstable) +author: Isaac Schlueter +date: Fri Jun 15 2012 12:45:20 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-7-11-unstable + +

This is the most stable 0.7 release yet. Please try it out. + +

+

Version 0.8 will be out very soon. You can follow the remaining issues +on the github issue tracker. + +

+

https://github.com/joyent/node/issues?milestone=10&state=open + +

+

2012.06.15, Version 0.7.11 (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.11/node-v0.7.11.tar.gz + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.7.11/node-v0.7.11.pkg + +

+

Windows Installer: http://nodejs.org/dist/v0.7.11/node-v0.7.11-x86.msi + +

+

Windows x64 Installer: http://nodejs.org/dist/v0.7.11/node-v0.7.11-x64.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.7.11/x64/ + +

+

Other release files: http://nodejs.org/dist/v0.7.11/ + +

+

Website: http://nodejs.org/docs/v0.7.11/ + +

+

Documentation: http://nodejs.org/docs/v0.7.11/api/ +

diff --git a/doc/blog/release/version-0-7-12.md b/doc/blog/release/version-0-7-12.md new file mode 100644 index 0000000000..91e571d2e3 --- /dev/null +++ b/doc/blog/release/version-0-7-12.md @@ -0,0 +1,56 @@ +version: 0.7.12 +title: Version 0.7.12 +author: Isaac Schlueter +date: Tue Jun 19 2012 16:31:09 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-7-12 + +

2012.06.19, Version 0.7.12 (unstable)

+

This is the last release on the 0.7 branch. Version 0.8.0 will be released some time later this week, barring any major problems.

+

As with other even-numbered Node releases before it, the v0.8.x releases will maintain API and binary compatibility.

+

The major changes between v0.6 and v0.8 are detailed in https://github.com/joyent/node/wiki/API-changes-between-v0.6-and-v0.8

+

Please try out this release. There will be very virtually no changes between this and the v0.8.x release family. This is the last chance to comment before it is locked down for stability. The API is effectively frozen now.

+

This version adds backwards-compatible shims for binary addons that use libeio and libev directly. If you find that binary modules that could compile on v0.6 can not compile on this version, please let us know. Note that libev is officially deprecated in v0.8, and will be removed in v0.9. You should be porting your modules to use libuv as soon as possible.

+

V8 is on 3.11.10 currently, and will remain on the V8 3.11.x branch for the duration of Node v0.8.x.

+

Source Code: http://nodejs.org/dist/v0.7.12/node-v0.7.12.tar.gz

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.7.12/node-v0.7.12.pkg

+

Windows Installer: http://nodejs.org/dist/v0.7.12/node-v0.7.12-x86.msi

+

Windows x64 Installer: http://nodejs.org/dist/v0.7.12/x64/node-v0.7.12-x64.msi

+

Windows x64 Files: http://nodejs.org/dist/v0.7.12/x64/

+

Other release files: http://nodejs.org/dist/v0.7.12/

+

Website: http://nodejs.org/docs/v0.7.12/

+

Documentation: http://nodejs.org/docs/v0.7.12/api/

+ +

Shasums

+ +
ded6a2197b1149b594eb45fea921e8538ba442aa  blog.html
+dfabff0923d4b4f1d53bd9831514c1ac8c4b1876  email.md
+be313d35511e6d7e43cae5fa2b18f3e0d2275ba1  node-v0.7.12-x86.msi
+8f7ba0c8283e3863de32fd5c034f5b599c78f830  node-v0.7.12.pkg
+cb570abacbf4eb7e23c3d2620d00dd3080d9c19d  node-v0.7.12.tar.gz
+e13a6edfcba1c67ffe794982dd20a222ce8ce40f  node.exe
+20906ad76a43eca52795b2a089654a105e11c1e6  node.exp
+acbcbb87b6f7f2af34a3ed0abe6131d9e7a237af  node.lib
+4013d5b25fe36ae4245433b972818686cd9a2205  node.pdb
+6c0a7a2e8ee360e2800156293fb2f6a5c1a57382  npm-1.1.30.tgz
+9d23e42e8260fa20001d5618d2583a62792bf63f  npm-1.1.30.zip
+840157b2d6f7389ba70b07fc9ddc048b92c501cc  x64/node-v0.7.12-x64.msi
+862d42706c21ea83bf73cd827101f0fe598b0cf7  x64/node.exe
+de0af95fac083762f99c875f91bab830dc030f71  x64/node.exp
+3122bd886dfb96f3b41846cef0bdd7e97326044a  x64/node.lib
+e0fa4e42cd19cadf8179e492ca606b7232bbc018  x64/node.pdb
diff --git a/doc/blog/release/version-0-7-4-unstable.md b/doc/blog/release/version-0-7-4-unstable.md new file mode 100644 index 0000000000..01bc92ae55 --- /dev/null +++ b/doc/blog/release/version-0-7-4-unstable.md @@ -0,0 +1,50 @@ +version: 0.7.4 +title: Node v0.7.4 (unstable) +author: Isaac Schlueter +date: Wed Feb 15 2012 11:38:35 GMT-0800 (PST) +status: publish +category: release +slug: version-0-7-4-unstable + +

2012.02.14, Version 0.7.4 (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.4/node-v0.7.4.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.4/node-v0.7.4.msi + +

+

Macintosh Installer: http://nodejs.org/dist/v0.7.4/node-v0.7.4.pkg + +

+

Other release files: http://nodejs.org/dist/v0.7.4/ + +

+

Website: http://nodejs.org/docs/v0.7.4/ + +

+

Documentation: http://nodejs.org/docs/v0.7.4/api/ +

diff --git a/doc/blog/release/version-0-7-5-unstable.md b/doc/blog/release/version-0-7-5-unstable.md new file mode 100644 index 0000000000..bc1e6047dd --- /dev/null +++ b/doc/blog/release/version-0-7-5-unstable.md @@ -0,0 +1,62 @@ +version: 0.7.5 +title: Version 0.7.5 (unstable) +author: Isaac Schlueter +date: Thu Feb 23 2012 14:45:21 GMT-0800 (PST) +status: publish +category: release +slug: version-0-7-5-unstable + +

2012.02.23, Version 0.7.5 (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.5/node-v0.7.5.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.5/node-v0.7.5.msi + +

+

Macintosh Installer: http://nodejs.org/dist/v0.7.5/node-v0.7.5.pkg + +

+

Other release files: http://nodejs.org/dist/v0.7.5/ + +

+

Website: http://nodejs.org/docs/v0.7.5/ + +

+

Documentation: http://nodejs.org/docs/v0.7.5/api/ +

diff --git a/doc/blog/release/version-0-7-6-unstable.md b/doc/blog/release/version-0-7-6-unstable.md new file mode 100644 index 0000000000..ecf67f3ea0 --- /dev/null +++ b/doc/blog/release/version-0-7-6-unstable.md @@ -0,0 +1,72 @@ +version: 0.7.6 +title: Version 0.7.6 (unstable) +author: Isaac Schlueter +date: Tue Mar 13 2012 14:12:30 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-7-6-unstable + +

2012.03.13, Version 0.7.6 (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.6/node-v0.7.6.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.6/node-v0.7.6.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.7.6/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.7.6/node-v0.7.6.pkg + +

+

Other release files: http://nodejs.org/dist/v0.7.6/ + +

+

Website: http://nodejs.org/docs/v0.7.6/ + +

+

Documentation: http://nodejs.org/docs/v0.7.6/api/ +

diff --git a/doc/blog/release/version-0-7-7-unstable.md b/doc/blog/release/version-0-7-7-unstable.md new file mode 100644 index 0000000000..6cdcc23128 --- /dev/null +++ b/doc/blog/release/version-0-7-7-unstable.md @@ -0,0 +1,71 @@ +version: 0.7.7 +title: Version 0.7.7 (unstable) +author: Isaac Schlueter +date: Fri Mar 30 2012 11:56:19 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-7-7-unstable + +

2012.03.30, Version 0.7.7 (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.7/node-v0.7.7.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.7/node-v0.7.7.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.7.7/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.7.7/node-v0.7.7.pkg + +

+

Other release files: http://nodejs.org/dist/v0.7.7/ + +

+

Website: http://nodejs.org/docs/v0.7.7/ + +

+

Documentation: http://nodejs.org/docs/v0.7.7/api/ +

diff --git a/doc/blog/release/version-0-7-8-unstable.md b/doc/blog/release/version-0-7-8-unstable.md new file mode 100644 index 0000000000..8e87a9007d --- /dev/null +++ b/doc/blog/release/version-0-7-8-unstable.md @@ -0,0 +1,71 @@ +version: 0.7.8 +title: Version 0.7.8 (unstable) +author: Isaac Schlueter +date: Wed Apr 18 2012 10:39:02 GMT-0700 (PDT) +status: publish +category: release +slug: version-0-7-8-unstable + +

2012.04.18, Version 0.7.8, (unstable) + +

+ +

Source Code: http://nodejs.org/dist/v0.7.8/node-v0.7.8.tar.gz + +

+

Windows Installer: http://nodejs.org/dist/v0.7.8/node-v0.7.8.msi + +

+

Windows x64 Files: http://nodejs.org/dist/v0.7.8/x64/ + +

+

Macintosh Installer (Universal): http://nodejs.org/dist/v0.7.8/node-v0.7.8.pkg + +

+

Other release files: http://nodejs.org/dist/v0.7.8/ + +

+

Website: http://nodejs.org/docs/v0.7.8/ + +

+

Documentation: http://nodejs.org/docs/v0.7.8/api/ +

diff --git a/doc/blog/video/bryan-cantrill-instrumenting-the-real-time-web.md b/doc/blog/video/bryan-cantrill-instrumenting-the-real-time-web.md new file mode 100644 index 0000000000..0c26cb7a49 --- /dev/null +++ b/doc/blog/video/bryan-cantrill-instrumenting-the-real-time-web.md @@ -0,0 +1,42 @@ +title: Bryan Cantrill: Instrumenting the Real Time Web +author: Isaac Schlueter +date: Tue May 08 2012 10:00:34 GMT-0700 (PDT) +status: publish +category: video +slug: bryan-cantrill-instrumenting-the-real-time-web + +Bryan Cantrill, VP of Engineering at Joyent, describes the challenges of instrumenting a distributed, dynamic, highly virtualized system -- and what their experiences taught them about the problem, the technologies used to tackle it, and promising approaches. + +This talk was given at Velocity Conf in 2011. + +
+ + +
+ Instrumenting the real-time web + + + + + + + + +
+ View more presentations from bcantrill +
+
+
diff --git a/doc/blog/video/welcome-to-the-node-blog.md b/doc/blog/video/welcome-to-the-node-blog.md new file mode 100644 index 0000000000..3ac3985832 --- /dev/null +++ b/doc/blog/video/welcome-to-the-node-blog.md @@ -0,0 +1,13 @@ +title: Welcome to the Node blog +author: ryandahl +date: Thu Mar 17 2011 20:17:12 GMT-0700 (PDT) +status: publish +category: video +slug: welcome-to-the-node-blog + +Since Livejournal is disintegrating into Russian spam, I'm moving my technical blog to http://blog.nodejs.org/. I hope to do frequent small posts about what's going on in Node development and include posts from other core Node developers. Please subscribe to the RSS feed. + +To avoid making this post completely devoid of content, here is a new video from a talk I gave at the SF PHP group tastefully produced by Marakana: + diff --git a/doc/blog/vulnerability/http-server-security-vulnerability-please-upgrade-to-0-6-17.md b/doc/blog/vulnerability/http-server-security-vulnerability-please-upgrade-to-0-6-17.md new file mode 100644 index 0000000000..22a8c71922 --- /dev/null +++ b/doc/blog/vulnerability/http-server-security-vulnerability-please-upgrade-to-0-6-17.md @@ -0,0 +1,45 @@ +title: HTTP Server Security Vulnerability: Please upgrade to 0.6.17 +author: Isaac Schlueter +date: Mon May 07 2012 10:02:01 GMT-0700 (PDT) +status: publish +category: vulnerability +slug: http-server-security-vulnerability-please-upgrade-to-0-6-17 + +

tl;dr

+ + + +

Details

+ +

A few weeks ago, Matthew Daley found a security vulnerability in Node's HTTP implementation, and thankfully did the responsible thing and reported it to us via email. He explained it quite well, so I'll quote him here:

+
+

There is a vulnerability in node's `http_parser` binding which allows information disclosure to a remote attacker: + +

+

In node::StringPtr::Update, an attempt is made at an optimization on certain inputs (`node_http_parser.cc`, line 151). The intent is that if the current string pointer plus the current string size is equal to the incoming string pointer, the current string size is just increased to match, as the incoming string lies just beyond the current string pointer. However, the check to see whether or not this can be done is incorrect; "size" is used whereas "size_" should be used. Therefore, an attacker can call Update with a string of certain length and cause the current string to have other data appended to it. In the case of HTTP being parsed out of incoming socket data, this can be incoming data from other sockets. + +

+

Normally node::StringPtr::Save, which is called after each execution of `http_parser`, would stop this from being exploitable as it converts strings to non-optimizable heap-based strings. However, this is not done to 0-length strings. An attacker can therefore exploit the mistake by making Update set a 0-length string, and then Update past its boundary, so long as it is done in one `http_parser` execution. This can be done with an HTTP header with empty value, followed by a continuation with a value of certain length. + +

+

The attached files demonstrate the issue:

+
$ ./node ~/stringptr-update-poc-server.js &
+[1] 11801
+$ ~/stringptr-update-poc-client.py
+HTTP/1.1 200 OK
+Content-Type: text/plain
+Date: Wed, 18 Apr 2012 00:05:11 GMT
+Connection: close
+Transfer-Encoding: chunked
+
+64
+X header:
+ This is private data, perhaps an HTTP request with a Cookie in it.
+0
+
+

The fix landed on 7b3fb22 and c9a231d, for master and v0.6, respectively. The innocuous commit message does not give away the security implications, precisely because we wanted to get a fix out before making a big deal about it.

+

The first releases with the fix are v0.7.8 and 0.6.17. So now is a good time to make a big deal about it.

+

If you are using node version 0.6 in production, please upgrade to at least v0.6.17, or at least apply the fix in c9a231d to your system. (Version 0.6.17 also fixes some other important bugs, and is without doubt the most stable release of Node 0.6 to date, so it's a good idea to upgrade anyway.)

+

I'm extremely grateful that Matthew took the time to report the problem to us with such an elegant explanation, and in such a way that we had a reasonable amount of time to fix the issue before making it public.

diff --git a/tools/blog/README.md b/tools/blog/README.md new file mode 100644 index 0000000000..52a3be7fd2 --- /dev/null +++ b/tools/blog/README.md @@ -0,0 +1,5 @@ +# node-blog-gen + +Generates the node blog from the markdown files in doc/blog/. + + diff --git a/tools/blog/generate.js b/tools/blog/generate.js new file mode 100644 index 0000000000..952553baae --- /dev/null +++ b/tools/blog/generate.js @@ -0,0 +1,261 @@ +#!/usr/bin/env node +var fs = require('fs'); +var marked = require('marked'); +var mkdirp = require('mkdirp'); +var glob = require('glob'); +var ejs = require('ejs'); +var path = require('path'); +var semver = require('semver'); + +var input = path.resolve(process.argv[2]); +var output = path.resolve(process.argv[3]); +var template = path.resolve(process.argv[4]); + +var config = { + postsPerPage: 5 +}; + +console.error("argv=%j", process.argv) + +fs.readFile(template, 'utf8', function(er, contents) { + if (er) throw er; + template = ejs.compile(contents, template); + readInput(); +}); + +function readInput() { + glob(input + '/**/*.md', function(er, files) { + if (er) throw er; + readFiles(files); + }); +} + +function readFiles(files) { + var n = files.length; + var data = { files: {}, feeds: {}, posts: {}}; + + files.forEach(function(file) { + fs.readFile(file, 'utf8', next(file)); + }); + + function next(file) { return function(er, contents) { + if (er) throw er; + if (contents) { + contents = parseFile(file, contents); + if (contents) { + data.files[file] = contents + } + } + if (--n === 0) { + buildOutput(data); + } + }} +} + +function parseFile(file, contents) { + var c = contents.split('\n\n'); + var head = c.shift(); + c = c.join('\n\n'); + var post = head.split('\n').reduce(function(set, kv) { + kv = kv.split(':'); + var key = kv.shift().trim(); + var val = kv.join(':').trim(); + set[key] = val; + return set; + }, {}); + if (post.status && post.status !== 'publish') return null; + post.body = c; + return post; +} + +function buildPermalinks(data) { + Object.keys(data.files).forEach(function(k) { + data.posts[k] = buildPermalink(k, data.files[k]); + }); +} + +function buildPermalink(key, post) { + var data = {}; + data.pageid = post.slug; + data.title = post.title; + data.content = post.content = marked.parse(post.body); + + // Fix for chjj/marked#56 + data.content = post.content = data.content + .replace(/\1<\/a>/g, '$1'); + + data.post = post; + + var d = post.date = new Date(post.date); + + var y = d.getYear() + 1900; + var m = d.getMonth() + 1; + if (m < 10) m = '0' + m; + var d = d.getDate(); + if (d < 10) d = '0' + d; + var uri = '/' + y + '/' + m + '/' + d + '/' + post.slug + '/'; + post.data = data; + post.uri = uri; + + post.permalink = data.permalink = uri; + return data; +} + +function writeFile(uri, data) { + data.uri = path.join(data.uri); + uri = path.join(uri); + var contents = template(data); + var outdir = path.join(output, uri); + mkdirp(outdir, function(er) { + if (er) throw er; + var file = path.resolve(outdir, 'index.html'); + fs.writeFile(file, contents, 'utf8', function(er) { + if (er) throw er; + console.log('wrote: ', data.pageid, path.relative(process.cwd(), file)); + }); + }); +} + +// sort in reverse chronological order +// prune out any releases that are not the most recent on their branch. +function buildFeeds(data) { + // first, sort by date. + var posts = Object.keys(data.posts).map(function(k) { + return data.posts[k].post; + }).sort(function(a, b) { + a = a.date.getTime(); + b = b.date.getTime(); + return (a === b) ? 0 : a > b ? -1 : 1; + }) + + // separate release posts by release families. + var releases = posts.reduce(function(releases, post) { + if (post.category !== 'release') return releases; + var ver = semver.parse(post.version); + if (!ver) return; + var major = +ver[1]; + var minor = +ver[2]; + var patch = +ver[3]; + var family = [major, minor]; + ver = [major, minor, patch, post]; + if (family[1] % 2) family[1]++; + family = family.join('.'); + post.family = family; + releases[family] = releases[family] || []; + releases[family].push(post); + return releases; + }, {}); + + // separate by categories. + var categories = posts.reduce(function(categories, post) { + if (!post.category) return categories; + if (!categories[post.category]) { + categories[post.category] = []; + } + categories[post.category].push(post); + return categories; + }, {}); + + // paginate categories. + for (var cat in categories) { + categories[cat] = paginate(categories[cat], cat); + } + + // filter non-latest release notices out of main feeds. + var main = posts.filter(function(post) { + if (post.version && post.family && post !== releases[post.family][0]) { + return false; + } + return true; + }); + + // add previous/next based on main feed. + main.forEach(function (post, i, posts) { + post.next = posts[i - 1]; + post.prev = posts[i + 1]; + }) + + // paginate each feed. + main = paginate(main, ''); + + // put previous/next links on orphaned old releases so you can get back + for (var family in releases) { + releases[family].forEach(function(post, i, family) { + if (!post.next) post.next = family[i - 1]; + if (!post.next) post.next = family[0].next; + // if (!post.next) post.next = family[0]; + + if (!post.prev) post.prev = family[i + 1]; + if (!post.prev) post.prev = family[0].prev; + }); + // paginate + releases[family] = paginate(releases[family], 'release-' + family); + } + + // paginate + data.feeds = { + main: main, + categories: categories, + releases: releases + }; +} + +function paginate(set, title) { + var pp = config.postsPerPage || 5 + var pages = []; + for (var i = 0; i < set.length; i += pp) { + pages.push(set.slice(i, i + pp)); + } + var id = title.replace(/[^a-zA-Z0-9.]+/g, '-'); + return { id: id || 'index', pageid: id, posts: set, pages: pages, title: title }; +} + +function writePermalinks(data) { + Object.keys(data.posts).forEach(function(k) { + var post = data.posts[k]; + writeFile(post.permalink, post); + }); +} + +function writeFeeds(data) { + writeFeed(data.feeds.main); + + for (var feed in data.feeds.categories) { + writeFeed(data.feeds.categories[feed]); + } + for (var feed in data.feeds.releases) { + writeFeed(data.feeds.releases[feed]); + } +} + +function writeFeed(feed) { + var title = feed.title; + feed.pages.forEach(function(page, p, pages) { + writePaginated(feed.title, page, p, pages.length, feed.id); + }); +} + +function writePaginated(title, posts, p, total, id) { + var uri = '/' + encodeURIComponent(title) + '/'; + var d = { + title: title, + page: p, + posts: posts, + total: total, + paginated: true, + pageid: id + '-' + p, + uri: uri + }; + if (p === 0) { + writeFile(uri, d); + } + writeFile(uri + p, d); +} + +function buildOutput(data) { + buildPermalinks(data); + buildFeeds(data); + writePermalinks(data); + writeFeeds(data); +} + diff --git a/tools/blog/node_modules/.bin/marked b/tools/blog/node_modules/.bin/marked new file mode 120000 index 0000000000..3b8ef881cb --- /dev/null +++ b/tools/blog/node_modules/.bin/marked @@ -0,0 +1 @@ +/Users/isaacs/dev/js/node-master/tools/blog/node_modules/marked/bin/marked \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/.gitmodules b/tools/blog/node_modules/ejs/.gitmodules new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/blog/node_modules/ejs/.npmignore b/tools/blog/node_modules/ejs/.npmignore new file mode 100644 index 0000000000..020ddac2ce --- /dev/null +++ b/tools/blog/node_modules/ejs/.npmignore @@ -0,0 +1,4 @@ +# ignore any vim files: +*.sw[a-z] +vim/.netrwhist +node_modules diff --git a/tools/blog/node_modules/ejs/History.md b/tools/blog/node_modules/ejs/History.md new file mode 100644 index 0000000000..75dc16f51f --- /dev/null +++ b/tools/blog/node_modules/ejs/History.md @@ -0,0 +1,98 @@ + +0.7.1 / 2012-03-26 +================== + + * Fixed exception when using express in production caused by typo. [slaskis] + +0.7.0 / 2012-03-24 +================== + + * Added newline consumption support (`-%>`) [whoatemydomain] + +0.6.1 / 2011-12-09 +================== + + * Fixed `ejs.renderFile()` + +0.6.0 / 2011-12-09 +================== + + * Changed: you no longer need `{ locals: {} }` + +0.5.0 / 2011-11-20 +================== + + * Added express 3.x support + * Added ejs.renderFile() + * Added 'json' filter + * Fixed tests for 0.5.x + +0.4.3 / 2011-06-20 +================== + + * Fixed stacktraces line number when used multiline js expressions [Octave] + +0.4.2 / 2011-05-11 +================== + + * Added client side support + +0.4.1 / 2011-04-21 +================== + + * Fixed error context + +0.4.0 / 2011-04-21 +================== + + * Added; ported jade's error reporting to ejs. [slaskis] + +0.3.1 / 2011-02-23 +================== + + * Fixed optional `compile()` options + +0.3.0 / 2011-02-14 +================== + + * Added 'json' filter [Yuriy Bogdanov] + * Use exported version of parse function to allow monkey-patching [Anatoliy Chakkaev] + +0.2.1 / 2010-10-07 +================== + + * Added filter support + * Fixed _cache_ option. ~4x performance increase + +0.2.0 / 2010-08-05 +================== + + * Added support for global tag config + * Added custom tag support. Closes #5 + * Fixed whitespace bug. Closes #4 + +0.1.0 / 2010-08-04 +================== + + * Faster implementation [ashleydev] + +0.0.4 / 2010-08-02 +================== + + * Fixed single quotes for content outside of template tags. [aniero] + * Changed; `exports.compile()` now expects only "locals" + +0.0.3 / 2010-07-15 +================== + + * Fixed single quotes + +0.0.2 / 2010-07-09 +================== + + * Fixed newline preservation + +0.0.1 / 2010-07-09 +================== + + * Initial release diff --git a/tools/blog/node_modules/ejs/Makefile b/tools/blog/node_modules/ejs/Makefile new file mode 100644 index 0000000000..14b93049da --- /dev/null +++ b/tools/blog/node_modules/ejs/Makefile @@ -0,0 +1,23 @@ + +SRC = $(shell find lib -name "*.js" -type f) +UGLIFY_FLAGS = --no-mangle + +all: ejs.min.js + +test: + @./node_modules/.bin/mocha \ + --ui exports + +ejs.js: $(SRC) + @node support/compile.js $^ + +ejs.min.js: ejs.js + @uglifyjs $(UGLIFY_FLAGS) $< > $@ \ + && du ejs.min.js \ + && du ejs.js + +clean: + rm -f ejs.js + rm -f ejs.min.js + +.PHONY: test \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/Readme.md b/tools/blog/node_modules/ejs/Readme.md new file mode 100644 index 0000000000..8e398fd20c --- /dev/null +++ b/tools/blog/node_modules/ejs/Readme.md @@ -0,0 +1,151 @@ + +# EJS + +Embedded JavaScript templates. + +## Installation + + $ npm install ejs + +## Features + + * Complies with the [Express](http://expressjs.com) view system + * Static caching of intermediate JavaScript + * Unbuffered code for conditionals etc `<% code %>` + * Escapes html by default with `<%= code %>` + * Unescaped buffering with `<%- code %>` + * Supports tag customization + * Filter support for designer-friendly templates + * Client-side support + * Newline slurping with `<% code -%>` or `<% -%>` or `<%= code -%>` or `<%- code -%>` + +## Example + + <% if (user) { %> +

<%= user.name %>

+ <% } %> + +## Usage + + ejs.compile(str, options); + // => Function + + ejs.render(str, options); + // => str + +## Options + + - `cache` Compiled functions are cached, requires `filename` + - `filename` Used by `cache` to key caches + - `scope` Function execution context + - `debug` Output generated function body + - `open` Open tag, defaulting to "<%" + - `close` Closing tag, defaulting to "%>" + - * All others are template-local variables + +## Custom tags + +Custom tags can also be applied globally: + + var ejs = require('ejs'); + ejs.open = '{{'; + ejs.close = '}}'; + +Which would make the following a valid template: + +

{{= title }}

+ +## Filters + +EJS conditionally supports the concept of "filters". A "filter chain" +is a designer friendly api for manipulating data, without writing JavaScript. + +Filters can be applied by supplying the _:_ modifier, so for example if we wish to take the array `[{ name: 'tj' }, { name: 'mape' }, { name: 'guillermo' }]` and output a list of names we can do this simply with filters: + +Template: + +

<%=: users | map:'name' | join %>

+ +Output: + +

Tj, Mape, Guillermo

+ +Render call: + + ejs.render(str, { + users: [ + { name: 'tj' }, + { name: 'mape' }, + { name: 'guillermo' } + ] + }); + +Or perhaps capitalize the first user's name for display: + +

<%=: users | first | capitalize %>

+ +## Filter list + +Currently these filters are available: + + - first + - last + - capitalize + - downcase + - upcase + - sort + - sort_by:'prop' + - size + - length + - plus:n + - minus:n + - times:n + - divided_by:n + - join:'val' + - truncate:n + - truncate_words:n + - replace:pattern,substitution + - prepend:val + - append:val + - map:'prop' + - reverse + - get:'prop' + +## Adding filters + + To add a filter simply add a method to the `.filters` object: + +```js +ejs.filters.last = function(obj) { + return obj[obj.length - 1]; +}; +``` + +## client-side support + + include `./ejs.js` or `./ejs.min.js` and `require("ejs").compile(str)`. + +## License + +(The MIT License) + +Copyright (c) 2009-2010 TJ Holowaychuk <tj@vision-media.ca> + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/blog/node_modules/ejs/benchmark.js b/tools/blog/node_modules/ejs/benchmark.js new file mode 100644 index 0000000000..7b267e1603 --- /dev/null +++ b/tools/blog/node_modules/ejs/benchmark.js @@ -0,0 +1,14 @@ + + +var ejs = require('./lib/ejs'), + str = '<% if (foo) { %>

<%= foo %>

<% } %>', + times = 50000; + +console.log('rendering ' + times + ' times'); + +var start = new Date; +while (times--) { + ejs.render(str, { cache: true, filename: 'test', locals: { foo: 'bar' }}); +} + +console.log('took ' + (new Date - start) + 'ms'); \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/ejs.js b/tools/blog/node_modules/ejs/ejs.js new file mode 100644 index 0000000000..b0fa93b12b --- /dev/null +++ b/tools/blog/node_modules/ejs/ejs.js @@ -0,0 +1,567 @@ + +// CommonJS require() + +function require(p){ + if ('fs' == p) return {}; + var path = require.resolve(p) + , mod = require.modules[path]; + if (!mod) throw new Error('failed to require "' + p + '"'); + if (!mod.exports) { + mod.exports = {}; + mod.call(mod.exports, mod, mod.exports, require.relative(path)); + } + return mod.exports; + } + +require.modules = {}; + +require.resolve = function (path){ + var orig = path + , reg = path + '.js' + , index = path + '/index.js'; + return require.modules[reg] && reg + || require.modules[index] && index + || orig; + }; + +require.register = function (path, fn){ + require.modules[path] = fn; + }; + +require.relative = function (parent) { + return function(p){ + if ('.' != p.substr(0, 1)) return require(p); + + var path = parent.split('/') + , segs = p.split('/'); + path.pop(); + + for (var i = 0; i < segs.length; i++) { + var seg = segs[i]; + if ('..' == seg) path.pop(); + else if ('.' != seg) path.push(seg); + } + + return require(path.join('/')); + }; + }; + + +require.register("ejs.js", function(module, exports, require){ + +/*! + * EJS + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./utils') + , fs = require('fs'); + +/** + * Library version. + */ + +exports.version = '0.6.1'; + +/** + * Filters. + * + * @type Object + */ + +var filters = exports.filters = require('./filters'); + +/** + * Intermediate js cache. + * + * @type Object + */ + +var cache = {}; + +/** + * Clear intermediate js cache. + * + * @api public + */ + +exports.clearCache = function(){ + cache = {}; +}; + +/** + * Translate filtered code into function calls. + * + * @param {String} js + * @return {String} + * @api private + */ + +function filtered(js) { + return js.substr(1).split('|').reduce(function(js, filter){ + var parts = filter.split(':') + , name = parts.shift() + , args = parts.shift() || ''; + if (args) args = ', ' + args; + return 'filters.' + name + '(' + js + args + ')'; + }); +}; + +/** + * Re-throw the given `err` in context to the + * `str` of ejs, `filename`, and `lineno`. + * + * @param {Error} err + * @param {String} str + * @param {String} filename + * @param {String} lineno + * @api private + */ + +function rethrow(err, str, filename, lineno){ + var lines = str.split('\n') + , start = Math.max(lineno - 3, 0) + , end = Math.min(lines.length, lineno + 3); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' >> ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'ejs') + ':' + + lineno + '\n' + + context + '\n\n' + + err.message; + + throw err; +} + +/** + * Parse the given `str` of ejs, returning the function body. + * + * @param {String} str + * @return {String} + * @api public + */ + +var parse = exports.parse = function(str, options){ + var options = options || {} + , open = options.open || exports.open || '<%' + , close = options.close || exports.close || '%>'; + + var buf = [ + "var buf = [];" + , "\nwith (locals) {" + , "\n buf.push('" + ]; + + var lineno = 1; + + for (var i = 0, len = str.length; i < len; ++i) { + if (str.slice(i, open.length + i) == open) { + i += open.length + + var prefix, postfix, line = '__stack.lineno=' + lineno; + switch (str.substr(i, 1)) { + case '=': + prefix = "', escape((" + line + ', '; + postfix = ")), '"; + ++i; + break; + case '-': + prefix = "', (" + line + ', '; + postfix = "), '"; + ++i; + break; + default: + prefix = "');" + line + ';'; + postfix = "; buf.push('"; + } + + var end = str.indexOf(close, i) + , js = str.substring(i, end) + , start = i + , n = 0; + + while (~(n = js.indexOf("\n", n))) n++, lineno++; + if (js.substr(0, 1) == ':') js = filtered(js); + buf.push(prefix, js, postfix); + i += end - start + close.length - 1; + + } else if (str.substr(i, 1) == "\\") { + buf.push("\\\\"); + } else if (str.substr(i, 1) == "'") { + buf.push("\\'"); + } else if (str.substr(i, 1) == "\r") { + buf.push(" "); + } else if (str.substr(i, 1) == "\n") { + buf.push("\\n"); + lineno++; + } else { + buf.push(str.substr(i, 1)); + } + } + + buf.push("');\n}\nreturn buf.join('');"); + return buf.join(''); +}; + +/** + * Compile the given `str` of ejs into a `Function`. + * + * @param {String} str + * @param {Object} options + * @return {Function} + * @api public + */ + +var compile = exports.compile = function(str, options){ + options = options || {}; + + var input = JSON.stringify(str) + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined'; + + // Adds the fancy stack trace meta info + str = [ + 'var __stack = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };', + rethrow.toString(), + 'try {', + exports.parse(str, options), + '} catch (err) {', + ' rethrow(err, __stack.input, __stack.filename, __stack.lineno);', + '}' + ].join("\n"); + + if (options.debug) console.log(str); + var fn = new Function('locals, filters, escape', str); + return function(locals){ + return fn.call(this, locals, filters, utils.escape); + } +}; + +/** + * Render the given `str` of ejs. + * + * Options: + * + * - `locals` Local variables object + * - `cache` Compiled functions are cached, requires `filename` + * - `filename` Used by `cache` to key caches + * - `scope` Function execution context + * - `debug` Output generated function body + * - `open` Open tag, defaulting to "<%" + * - `close` Closing tag, defaulting to "%>" + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api public + */ + +exports.render = function(str, options){ + var fn + , options = options || {}; + + if (options.cache) { + if (options.filename) { + fn = cache[options.filename] || (cache[options.filename] = compile(str, options)); + } else { + throw new Error('"cache" option requires "filename".'); + } + } else { + fn = compile(str, options); + } + + options.__proto__ = options.locals; + return fn.call(options.scope, options); +}; + +/** + * Render an EJS file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + options.filename = path; + + try { + var str = options.cache + ? exports.cache[key] || (exports.cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + + fn(null, exports.render(str, options)); + } catch (err) { + fn(err); + } +}; + +// express support + +exports.__express = exports.renderFile; + +/** + * Expose to require(). + */ + +if (require.extensions) { + require.extensions['.ejs'] = function(module, filename) { + source = require('fs').readFileSync(filename, 'utf-8'); + module._compile(compile(source, {}), filename); + }; +} else if (require.registerExtension) { + require.registerExtension('.ejs', function(src) { + return compile(src, {}); + }); +} + +}); // module: ejs.js + +require.register("filters.js", function(module, exports, require){ + +/*! + * EJS - Filters + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * First element of the target `obj`. + */ + +exports.first = function(obj) { + return obj[0]; +}; + +/** + * Last element of the target `obj`. + */ + +exports.last = function(obj) { + return obj[obj.length - 1]; +}; + +/** + * Capitalize the first letter of the target `str`. + */ + +exports.capitalize = function(str){ + str = String(str); + return str[0].toUpperCase() + str.substr(1, str.length); +}; + +/** + * Downcase the target `str`. + */ + +exports.downcase = function(str){ + return String(str).toLowerCase(); +}; + +/** + * Uppercase the target `str`. + */ + +exports.upcase = function(str){ + return String(str).toUpperCase(); +}; + +/** + * Sort the target `obj`. + */ + +exports.sort = function(obj){ + return Object.create(obj).sort(); +}; + +/** + * Sort the target `obj` by the given `prop` ascending. + */ + +exports.sort_by = function(obj, prop){ + return Object.create(obj).sort(function(a, b){ + a = a[prop], b = b[prop]; + if (a > b) return 1; + if (a < b) return -1; + return 0; + }); +}; + +/** + * Size or length of the target `obj`. + */ + +exports.size = exports.length = function(obj) { + return obj.length; +}; + +/** + * Add `a` and `b`. + */ + +exports.plus = function(a, b){ + return Number(a) + Number(b); +}; + +/** + * Subtract `b` from `a`. + */ + +exports.minus = function(a, b){ + return Number(a) - Number(b); +}; + +/** + * Multiply `a` by `b`. + */ + +exports.times = function(a, b){ + return Number(a) * Number(b); +}; + +/** + * Divide `a` by `b`. + */ + +exports.divided_by = function(a, b){ + return Number(a) / Number(b); +}; + +/** + * Join `obj` with the given `str`. + */ + +exports.join = function(obj, str){ + return obj.join(str || ', '); +}; + +/** + * Truncate `str` to `len`. + */ + +exports.truncate = function(str, len){ + str = String(str); + return str.substr(0, len); +}; + +/** + * Truncate `str` to `n` words. + */ + +exports.truncate_words = function(str, n){ + var str = String(str) + , words = str.split(/ +/); + return words.slice(0, n).join(' '); +}; + +/** + * Replace `pattern` with `substitution` in `str`. + */ + +exports.replace = function(str, pattern, substitution){ + return String(str).replace(pattern, substitution || ''); +}; + +/** + * Prepend `val` to `obj`. + */ + +exports.prepend = function(obj, val){ + return Array.isArray(obj) + ? [val].concat(obj) + : val + obj; +}; + +/** + * Append `val` to `obj`. + */ + +exports.append = function(obj, val){ + return Array.isArray(obj) + ? obj.concat(val) + : obj + val; +}; + +/** + * Map the given `prop`. + */ + +exports.map = function(arr, prop){ + return arr.map(function(obj){ + return obj[prop]; + }); +}; + +/** + * Reverse the given `obj`. + */ + +exports.reverse = function(obj){ + return Array.isArray(obj) + ? obj.reverse() + : String(obj).split('').reverse().join(''); +}; + +/** + * Get `prop` of the given `obj`. + */ + +exports.get = function(obj, prop){ + return obj[prop]; +}; + +/** + * Packs the given `obj` into json string + */ +exports.json = function(obj){ + return JSON.stringify(obj); +}; +}); // module: filters.js + +require.register("utils.js", function(module, exports, require){ + +/*! + * EJS + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + +}); // module: utils.js diff --git a/tools/blog/node_modules/ejs/ejs.min.js b/tools/blog/node_modules/ejs/ejs.min.js new file mode 100644 index 0000000000..b87881320e --- /dev/null +++ b/tools/blog/node_modules/ejs/ejs.min.js @@ -0,0 +1,2 @@ +// CommonJS require() +function require(p){if("fs"==p)return{};var path=require.resolve(p),mod=require.modules[path];if(!mod)throw new Error('failed to require "'+p+'"');mod.exports||(mod.exports={},mod.call(mod.exports,mod,mod.exports,require.relative(path)));return mod.exports}require.modules={},require.resolve=function(path){var orig=path,reg=path+".js",index=path+"/index.js";return require.modules[reg]&®||require.modules[index]&&index||orig},require.register=function(path,fn){require.modules[path]=fn},require.relative=function(parent){return function(p){if("."!=p.substr(0,1))return require(p);var path=parent.split("/"),segs=p.split("/");path.pop();for(var i=0;i> ":" ")+curr+"| "+line}).join("\n");err.path=filename,err.message=(filename||"ejs")+":"+lineno+"\n"+context+"\n\n"+err.message;throw err}var parse=exports.parse=function(str,options){var options=options||{},open=options.open||exports.open||"<%",close=options.close||exports.close||"%>",buf=["var buf = [];","\nwith (locals) {","\n buf.push('"],lineno=1;for(var i=0,len=str.length;ib)return 1;if(a/g,">").replace(/"/g,""")}}) \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/examples/client.html b/tools/blog/node_modules/ejs/examples/client.html new file mode 100644 index 0000000000..51ce0b4ced --- /dev/null +++ b/tools/blog/node_modules/ejs/examples/client.html @@ -0,0 +1,24 @@ + + + + + + + + + \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/examples/list.ejs b/tools/blog/node_modules/ejs/examples/list.ejs new file mode 100644 index 0000000000..d571330aee --- /dev/null +++ b/tools/blog/node_modules/ejs/examples/list.ejs @@ -0,0 +1,7 @@ +<% if (names.length) { %> +
    + <% names.forEach(function(name){ %> +
  • <%= name %>
  • + <% }) %> +
+<% } %> \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/examples/list.js b/tools/blog/node_modules/ejs/examples/list.js new file mode 100644 index 0000000000..ec614ed624 --- /dev/null +++ b/tools/blog/node_modules/ejs/examples/list.js @@ -0,0 +1,14 @@ + +/** + * Module dependencies. + */ + +var ejs = require('../') + , fs = require('fs') + , str = fs.readFileSync(__dirname + '/list.ejs', 'utf8'); + +var ret = ejs.render(str, { + names: ['foo', 'bar', 'baz'] +}); + +console.log(ret); \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/index.js b/tools/blog/node_modules/ejs/index.js new file mode 100644 index 0000000000..20bf71a3fc --- /dev/null +++ b/tools/blog/node_modules/ejs/index.js @@ -0,0 +1,2 @@ + +module.exports = require('./lib/ejs'); \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/lib/ejs.js b/tools/blog/node_modules/ejs/lib/ejs.js new file mode 100644 index 0000000000..e87b98ea55 --- /dev/null +++ b/tools/blog/node_modules/ejs/lib/ejs.js @@ -0,0 +1,298 @@ + +/*! + * EJS + * Copyright(c) 2012 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Module dependencies. + */ + +var utils = require('./utils') + , fs = require('fs'); + +/** + * Library version. + */ + +exports.version = '0.7.1'; + +/** + * Filters. + * + * @type Object + */ + +var filters = exports.filters = require('./filters'); + +/** + * Intermediate js cache. + * + * @type Object + */ + +var cache = {}; + +/** + * Clear intermediate js cache. + * + * @api public + */ + +exports.clearCache = function(){ + cache = {}; +}; + +/** + * Translate filtered code into function calls. + * + * @param {String} js + * @return {String} + * @api private + */ + +function filtered(js) { + return js.substr(1).split('|').reduce(function(js, filter){ + var parts = filter.split(':') + , name = parts.shift() + , args = parts.shift() || ''; + if (args) args = ', ' + args; + return 'filters.' + name + '(' + js + args + ')'; + }); +}; + +/** + * Re-throw the given `err` in context to the + * `str` of ejs, `filename`, and `lineno`. + * + * @param {Error} err + * @param {String} str + * @param {String} filename + * @param {String} lineno + * @api private + */ + +function rethrow(err, str, filename, lineno){ + var lines = str.split('\n') + , start = Math.max(lineno - 3, 0) + , end = Math.min(lines.length, lineno + 3); + + // Error context + var context = lines.slice(start, end).map(function(line, i){ + var curr = i + start + 1; + return (curr == lineno ? ' >> ' : ' ') + + curr + + '| ' + + line; + }).join('\n'); + + // Alter exception message + err.path = filename; + err.message = (filename || 'ejs') + ':' + + lineno + '\n' + + context + '\n\n' + + err.message; + + throw err; +} + +/** + * Parse the given `str` of ejs, returning the function body. + * + * @param {String} str + * @return {String} + * @api public + */ + +var parse = exports.parse = function(str, options){ + var options = options || {} + , open = options.open || exports.open || '<%' + , close = options.close || exports.close || '%>'; + + var buf = [ + "var buf = [];" + , "\nwith (locals) {" + , "\n buf.push('" + ]; + + var lineno = 1; + + var consumeEOL = false; + for (var i = 0, len = str.length; i < len; ++i) { + if (str.slice(i, open.length + i) == open) { + i += open.length + + var prefix, postfix, line = '__stack.lineno=' + lineno; + switch (str.substr(i, 1)) { + case '=': + prefix = "', escape((" + line + ', '; + postfix = ")), '"; + ++i; + break; + case '-': + prefix = "', (" + line + ', '; + postfix = "), '"; + ++i; + break; + default: + prefix = "');" + line + ';'; + postfix = "; buf.push('"; + } + + var end = str.indexOf(close, i) + , js = str.substring(i, end) + , start = i + , n = 0; + + if ('-' == js[js.length-1]){ + js = js.substring(0, js.length - 2); + consumeEOL = true; + } + + while (~(n = js.indexOf("\n", n))) n++, lineno++; + if (js.substr(0, 1) == ':') js = filtered(js); + buf.push(prefix, js, postfix); + i += end - start + close.length - 1; + + } else if (str.substr(i, 1) == "\\") { + buf.push("\\\\"); + } else if (str.substr(i, 1) == "'") { + buf.push("\\'"); + } else if (str.substr(i, 1) == "\r") { + buf.push(" "); + } else if (str.substr(i, 1) == "\n") { + if (consumeEOL) { + consumeEOL = false; + } else { + buf.push("\\n"); + lineno++; + } + } else { + buf.push(str.substr(i, 1)); + } + } + + buf.push("');\n}\nreturn buf.join('');"); + return buf.join(''); +}; + +/** + * Compile the given `str` of ejs into a `Function`. + * + * @param {String} str + * @param {Object} options + * @return {Function} + * @api public + */ + +var compile = exports.compile = function(str, options){ + options = options || {}; + + var input = JSON.stringify(str) + , filename = options.filename + ? JSON.stringify(options.filename) + : 'undefined'; + + // Adds the fancy stack trace meta info + str = [ + 'var __stack = { lineno: 1, input: ' + input + ', filename: ' + filename + ' };', + rethrow.toString(), + 'try {', + exports.parse(str, options), + '} catch (err) {', + ' rethrow(err, __stack.input, __stack.filename, __stack.lineno);', + '}' + ].join("\n"); + + if (options.debug) console.log(str); + var fn = new Function('locals, filters, escape', str); + return function(locals){ + return fn.call(this, locals, filters, utils.escape); + } +}; + +/** + * Render the given `str` of ejs. + * + * Options: + * + * - `locals` Local variables object + * - `cache` Compiled functions are cached, requires `filename` + * - `filename` Used by `cache` to key caches + * - `scope` Function execution context + * - `debug` Output generated function body + * - `open` Open tag, defaulting to "<%" + * - `close` Closing tag, defaulting to "%>" + * + * @param {String} str + * @param {Object} options + * @return {String} + * @api public + */ + +exports.render = function(str, options){ + var fn + , options = options || {}; + + if (options.cache) { + if (options.filename) { + fn = cache[options.filename] || (cache[options.filename] = compile(str, options)); + } else { + throw new Error('"cache" option requires "filename".'); + } + } else { + fn = compile(str, options); + } + + options.__proto__ = options.locals; + return fn.call(options.scope, options); +}; + +/** + * Render an EJS file at the given `path` and callback `fn(err, str)`. + * + * @param {String} path + * @param {Object|Function} options or callback + * @param {Function} fn + * @api public + */ + +exports.renderFile = function(path, options, fn){ + var key = path + ':string'; + + if ('function' == typeof options) { + fn = options, options = {}; + } + + options.filename = path; + + try { + var str = options.cache + ? cache[key] || (cache[key] = fs.readFileSync(path, 'utf8')) + : fs.readFileSync(path, 'utf8'); + + fn(null, exports.render(str, options)); + } catch (err) { + fn(err); + } +}; + +// express support + +exports.__express = exports.renderFile; + +/** + * Expose to require(). + */ + +if (require.extensions) { + require.extensions['.ejs'] = function(module, filename) { + source = require('fs').readFileSync(filename, 'utf-8'); + module._compile(compile(source, {}), filename); + }; +} else if (require.registerExtension) { + require.registerExtension('.ejs', function(src) { + return compile(src, {}); + }); +} diff --git a/tools/blog/node_modules/ejs/lib/filters.js b/tools/blog/node_modules/ejs/lib/filters.js new file mode 100644 index 0000000000..d425c8d89e --- /dev/null +++ b/tools/blog/node_modules/ejs/lib/filters.js @@ -0,0 +1,198 @@ + +/*! + * EJS - Filters + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * First element of the target `obj`. + */ + +exports.first = function(obj) { + return obj[0]; +}; + +/** + * Last element of the target `obj`. + */ + +exports.last = function(obj) { + return obj[obj.length - 1]; +}; + +/** + * Capitalize the first letter of the target `str`. + */ + +exports.capitalize = function(str){ + str = String(str); + return str[0].toUpperCase() + str.substr(1, str.length); +}; + +/** + * Downcase the target `str`. + */ + +exports.downcase = function(str){ + return String(str).toLowerCase(); +}; + +/** + * Uppercase the target `str`. + */ + +exports.upcase = function(str){ + return String(str).toUpperCase(); +}; + +/** + * Sort the target `obj`. + */ + +exports.sort = function(obj){ + return Object.create(obj).sort(); +}; + +/** + * Sort the target `obj` by the given `prop` ascending. + */ + +exports.sort_by = function(obj, prop){ + return Object.create(obj).sort(function(a, b){ + a = a[prop], b = b[prop]; + if (a > b) return 1; + if (a < b) return -1; + return 0; + }); +}; + +/** + * Size or length of the target `obj`. + */ + +exports.size = exports.length = function(obj) { + return obj.length; +}; + +/** + * Add `a` and `b`. + */ + +exports.plus = function(a, b){ + return Number(a) + Number(b); +}; + +/** + * Subtract `b` from `a`. + */ + +exports.minus = function(a, b){ + return Number(a) - Number(b); +}; + +/** + * Multiply `a` by `b`. + */ + +exports.times = function(a, b){ + return Number(a) * Number(b); +}; + +/** + * Divide `a` by `b`. + */ + +exports.divided_by = function(a, b){ + return Number(a) / Number(b); +}; + +/** + * Join `obj` with the given `str`. + */ + +exports.join = function(obj, str){ + return obj.join(str || ', '); +}; + +/** + * Truncate `str` to `len`. + */ + +exports.truncate = function(str, len){ + str = String(str); + return str.substr(0, len); +}; + +/** + * Truncate `str` to `n` words. + */ + +exports.truncate_words = function(str, n){ + var str = String(str) + , words = str.split(/ +/); + return words.slice(0, n).join(' '); +}; + +/** + * Replace `pattern` with `substitution` in `str`. + */ + +exports.replace = function(str, pattern, substitution){ + return String(str).replace(pattern, substitution || ''); +}; + +/** + * Prepend `val` to `obj`. + */ + +exports.prepend = function(obj, val){ + return Array.isArray(obj) + ? [val].concat(obj) + : val + obj; +}; + +/** + * Append `val` to `obj`. + */ + +exports.append = function(obj, val){ + return Array.isArray(obj) + ? obj.concat(val) + : obj + val; +}; + +/** + * Map the given `prop`. + */ + +exports.map = function(arr, prop){ + return arr.map(function(obj){ + return obj[prop]; + }); +}; + +/** + * Reverse the given `obj`. + */ + +exports.reverse = function(obj){ + return Array.isArray(obj) + ? obj.reverse() + : String(obj).split('').reverse().join(''); +}; + +/** + * Get `prop` of the given `obj`. + */ + +exports.get = function(obj, prop){ + return obj[prop]; +}; + +/** + * Packs the given `obj` into json string + */ +exports.json = function(obj){ + return JSON.stringify(obj); +}; \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/lib/utils.js b/tools/blog/node_modules/ejs/lib/utils.js new file mode 100644 index 0000000000..8d569d6f23 --- /dev/null +++ b/tools/blog/node_modules/ejs/lib/utils.js @@ -0,0 +1,23 @@ + +/*! + * EJS + * Copyright(c) 2010 TJ Holowaychuk + * MIT Licensed + */ + +/** + * Escape the given string of `html`. + * + * @param {String} html + * @return {String} + * @api private + */ + +exports.escape = function(html){ + return String(html) + .replace(/&(?!\w+;)/g, '&') + .replace(//g, '>') + .replace(/"/g, '"'); +}; + \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/package.json b/tools/blog/node_modules/ejs/package.json new file mode 100644 index 0000000000..0458a44465 --- /dev/null +++ b/tools/blog/node_modules/ejs/package.json @@ -0,0 +1,23 @@ +{ + "name": "ejs", + "description": "Embedded JavaScript templates", + "version": "0.7.1", + "author": { + "name": "TJ Holowaychuk", + "email": "tj@vision-media.ca" + }, + "keywords": [ + "template", + "engine", + "ejs" + ], + "devDependencies": { + "mocha": "*" + }, + "main": "./lib/ejs.js", + "_id": "ejs@0.7.1", + "dist": { + "shasum": "9ed557b7e65f9f1adf5473060d079141ad7e680b" + }, + "_from": "ejs" +} diff --git a/tools/blog/node_modules/ejs/support/compile.js b/tools/blog/node_modules/ejs/support/compile.js new file mode 100644 index 0000000000..95cafc88d0 --- /dev/null +++ b/tools/blog/node_modules/ejs/support/compile.js @@ -0,0 +1,174 @@ + +/** + * Module dependencies. + */ + +var fs = require('fs'); + +/** + * Arguments. + */ + +var args = process.argv.slice(2) + , pending = args.length + , files = {}; + +console.log(''); + +// parse arguments + +args.forEach(function(file){ + var mod = file.replace('lib/', ''); + fs.readFile(file, 'utf8', function(err, js){ + if (err) throw err; + console.log(' \033[90mcompile : \033[0m\033[36m%s\033[0m', file); + files[file] = parse(js); + --pending || compile(); + }); +}); + +/** + * Parse the given `js`. + */ + +function parse(js) { + return parseInheritance(parseConditionals(js)); +} + +/** + * Parse __proto__. + */ + +function parseInheritance(js) { + return js + .replace(/^ *(\w+)\.prototype\.__proto__ * = *(\w+)\.prototype *;?/gm, function(_, child, parent){ + return child + '.prototype = new ' + parent + ';\n' + + child + '.prototype.constructor = '+ child + ';\n'; + }); +} + +/** + * Parse the given `js`, currently supporting: + * + * 'if' ['node' | 'browser'] + * 'end' + * + */ + +function parseConditionals(js) { + var lines = js.split('\n') + , len = lines.length + , buffer = true + , browser = false + , buf = [] + , line + , cond; + + for (var i = 0; i < len; ++i) { + line = lines[i]; + if (/^ *\/\/ *if *(node|browser)/gm.exec(line)) { + cond = RegExp.$1; + buffer = browser = 'browser' == cond; + } else if (/^ *\/\/ *end/.test(line)) { + buffer = true; + browser = false; + } else if (browser) { + buf.push(line.replace(/^( *)\/\//, '$1')); + } else if (buffer) { + buf.push(line); + } + } + + return buf.join('\n'); +} + +/** + * Compile the files. + */ + +function compile() { + var buf = ''; + buf += '\n// CommonJS require()\n\n'; + buf += browser.require + '\n\n'; + buf += 'require.modules = {};\n\n'; + buf += 'require.resolve = ' + browser.resolve + ';\n\n'; + buf += 'require.register = ' + browser.register + ';\n\n'; + buf += 'require.relative = ' + browser.relative + ';\n\n'; + args.forEach(function(file){ + var js = files[file]; + file = file.replace('lib/', ''); + buf += '\nrequire.register("' + file + '", function(module, exports, require){\n'; + buf += js; + buf += '\n}); // module: ' + file + '\n'; + }); + fs.writeFile('ejs.js', buf, function(err){ + if (err) throw err; + console.log(' \033[90m create : \033[0m\033[36m%s\033[0m', 'ejs.js'); + console.log(); + }); +} + +// refactored version of weepy's +// https://github.com/weepy/brequire/blob/master/browser/brequire.js + +var browser = { + + /** + * Require a module. + */ + + require: function require(p){ + if ('fs' == p) return {}; + var path = require.resolve(p) + , mod = require.modules[path]; + if (!mod) throw new Error('failed to require "' + p + '"'); + if (!mod.exports) { + mod.exports = {}; + mod.call(mod.exports, mod, mod.exports, require.relative(path)); + } + return mod.exports; + }, + + /** + * Resolve module path. + */ + + resolve: function(path){ + var orig = path + , reg = path + '.js' + , index = path + '/index.js'; + return require.modules[reg] && reg + || require.modules[index] && index + || orig; + }, + + /** + * Return relative require(). + */ + + relative: function(parent) { + return function(p){ + if ('.' != p.substr(0, 1)) return require(p); + + var path = parent.split('/') + , segs = p.split('/'); + path.pop(); + + for (var i = 0; i < segs.length; i++) { + var seg = segs[i]; + if ('..' == seg) path.pop(); + else if ('.' != seg) path.push(seg); + } + + return require(path.join('/')); + }; + }, + + /** + * Register a module. + */ + + register: function(path, fn){ + require.modules[path] = fn; + } +}; \ No newline at end of file diff --git a/tools/blog/node_modules/ejs/test/ejs.test.js b/tools/blog/node_modules/ejs/test/ejs.test.js new file mode 100644 index 0000000000..54b8d2dacc --- /dev/null +++ b/tools/blog/node_modules/ejs/test/ejs.test.js @@ -0,0 +1,329 @@ + +/** + * Module dependencies. + */ + +var ejs = require('../') + , assert = require('assert'); + +module.exports = { + 'test .version': function(){ + assert.ok(/^\d+\.\d+\.\d+$/.test(ejs.version), 'Test .version format'); + }, + + 'test html': function(){ + assert.equal('

yay

', ejs.render('

yay

')); + }, + + 'test renderFile': function(){ + var html = '

tj

', + str = '

<%= name %>

', + options = { name: 'tj', open: '{', close: '}' }; + + ejs.renderFile(__dirname + '/fixtures/user.ejs', options, function(err, res){ + assert.ok(!err); + assert.equal(res, html); + }) + }, + + 'test buffered code': function(){ + var html = '

tj

', + str = '

<%= name %>

', + locals = { name: 'tj' }; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test unbuffered code': function(){ + var html = '

tj

', + str = '<% if (name) { %>

<%= name %>

<% } %>', + locals = { name: 'tj' }; + assert.equal(html, ejs.render(str, { locals: locals })); + }, + + 'test `scope` option': function(){ + var html = '

tj

', + str = '

<%= this %>

'; + assert.equal(html, ejs.render(str, { scope: 'tj' })); + }, + + 'test escaping': function(){ + assert.equal('<script>', ejs.render('<%= "