├── .gitignore
├── .npmignore
├── History.md
├── Readme.md
├── assets.json
├── bin
└── asset
├── index.js
├── lib
├── asset.js
└── installer.js
└── package.json
/.gitignore:
--------------------------------------------------------------------------------
1 | public
2 | node_modules
3 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | support
2 | test
3 | examples
4 | public
5 |
--------------------------------------------------------------------------------
/History.md:
--------------------------------------------------------------------------------
1 | 0.4.12 / 2012-09-25
2 | ==================
3 |
4 | * fix to match README syntax (compression option)
5 | * added jade-runtime
6 |
7 | 0.4.11 / 2012-06-13
8 | ==================
9 |
10 | * removed engines
11 |
12 | 0.4.10 / 2011-12-10
13 | ==================
14 |
15 | * Updated move
16 |
17 | 0.4.9 / 2011-11-16
18 | ==================
19 |
20 | * Updated move.js
21 |
22 | 0.4.8 / 2011-09-13
23 | ==================
24 |
25 | * Added Twitter's bootstrap CSS toolkit in assets.json
26 | * Added mkdirp dependency
27 |
28 | 0.4.7 / 2011-08-20
29 | ==================
30 |
31 | * Updated caustic Updated superagent
32 | * Added EE2
33 |
34 | 0.4.6 / 2011-08-09
35 | ==================
36 |
37 | * Added superagent
38 |
39 | 0.4.5 / 2011-07-20
40 | ==================
41 |
42 | * Added `caustic`
43 |
44 | 0.4.4 / 2011-07-15
45 | ==================
46 |
47 | * Added `mustache.js`
48 | * Updated `jQuery`
49 | * Updated `underscore`
50 | * Updated `backbone`
51 |
52 | 0.4.3 / 2011-07-08
53 | ==================
54 |
55 | * Updated three.js
56 |
57 | 0.4.2 / 2011-07-02
58 | ==================
59 |
60 | * Added `resistance`
61 | * Added `pagie`
62 | * Added `str.js`
63 | * Added `fidel`
64 |
65 | 0.4.1 / 2011-06-04
66 | ==================
67 |
68 | * Added `move.js`
69 |
70 | 0.4.0 / 2011-05-30
71 | ==================
72 |
73 | * Added `asset` command to install from ./assets.json. Closes #18
74 | * Added `live.js` support
75 | * Added `iscroll` and `iscroll-lite`
76 | * Added `zepto`
77 |
78 | 0.3.2 / 2011-04-27
79 | ==================
80 |
81 | * Added Modernizr and Yepnope assets [Mike Cantelon]
82 | * Added iscroll and iscroll-lite [Mike Cantelon]
83 | * Added ellipsis to long descriptions within search
84 |
85 | 0.3.0 / 2011-04-14
86 | ==================
87 |
88 | * Added date.js support [caged]
89 | * Added support for polymaps [caged]
90 | * Added support for protovis [caged]
91 | * Added support for d3 [caged]
92 |
93 | 0.2.0 / 2011-04-09
94 | ==================
95 |
96 | * Added `jquery-mobile`
97 | * Added `processing.js`
98 | * Added `blueprint`
99 | * Added; assume arg with "/" is `--out
`. closes #10
100 | * Added; search tags for search query
101 | * Added `tags` to all assets
102 | * Added basic "complex" support :) aka an array of files. Closes #4
103 | * Added `utils.mkdir()`
104 | * Fixed; create destination directory. Closes #8
105 | * Fixed several `{version}` substrings within the url
106 |
107 | 0.1.0 / 2011-04-05
108 | ==================
109 |
110 | * Added `underscore`
111 | * Added `mootools`
112 | * added mootools
113 | * Added `-c, --compress` to install compressed versions of the asset when possible
114 | * Added `:compress` modifier, ex `asset jquery@1.4.3:compress`
115 | * Added basic dependency mapping support. Closes #3
116 | * Added `info ` command
117 | * Added deps to `assets.json`
118 | * Changed; by default assets are not compressed
119 |
120 | 0.0.2 / 2011-04-04
121 | ==================
122 |
123 | * Added descriptions
124 |
125 | 0.0.1 / 2010-01-03
126 | ==================
127 |
128 | * Initial release
129 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Asset
2 |
3 | Asset manager for lazy people (think homebrew for assets). Somewhat defunct unless someone wants to maintain it, otherwise
4 | I recommend [component](http://github.com/component/component), a more robust successor.
5 |
6 | ## Installation
7 |
8 | $ npm install -g asset
9 |
10 | ## Usage
11 |
12 | Usage: asset [command] [options]
13 |
14 | Commands:
15 |
16 | install installs the given asset
17 | search [query] search available assets with optional [query]
18 | info display verbose information for the given asset
19 | none install dependencies from ./assets.json
20 |
21 | Options:
22 |
23 | -c, --compress compress assets
24 | -o, --out output directory defaulting to ./public
25 | -V, --version output program version
26 | -h, --help display help information
27 |
28 |
29 |
30 | ## Examples
31 |
32 | ### Installing Several Assets
33 |
34 | By default asset installs to `./public`.
35 |
36 | $ asset raphael jquery
37 |
38 | install : raphael@1.4.7
39 | install : jquery@1.5.2
40 | download : jquery@1.5.2
41 | complete : jquery@1.5.2 public/jquery.js
42 | download : raphael@1.4.7
43 | complete : raphael@1.4.7 public/raphael.js
44 |
45 | Asset names accept an optional version and modifiers, taking the form:
46 |
47 | ['@' version] [':' 'compress']
48 |
49 | To install all assets (that support compression) as compressed, we can use
50 | the `--compress` flag:
51 |
52 | $ asset jquery raphael --compress
53 |
54 | However this can be done at the asset-level as well using the `:compress` modifier:
55 |
56 | $ asset jquery@1.4.3:compress raphael
57 |
58 | install : jquery@1.4.3
59 | install : raphael@1.4.7
60 | download : jquery@1.4.3
61 | complete : jquery@1.4.3 public/jquery.min.js
62 | download : raphael@1.4.7
63 | complete : raphael@1.4.7 public/raphael.js
64 |
65 | ### Install Destination
66 |
67 | Tweak the output directory with `-o, --out `.
68 |
69 | $ asset raphael g.raphael g.pie -o public/javascripts
70 |
71 | install : raphael@1.4.7
72 | install : g.raphael@0.4.1
73 | install : g.pie@0.4.1
74 | download : raphael@1.4.7
75 | complete : raphael@1.4.7 public/javascripts/raphael.js
76 | download : g.raphael@0.4.1
77 | complete : g.raphael@0.4.1 public/javascripts/g.raphael.js
78 | download : g.pie@0.4.1
79 | complete : g.pie@0.4.1 public/javascripts/g.pie.js
80 |
81 | Alternatively passing a directory name containing "/" will work as well, since `asset` knows this is not an asset, and becomes equivalent to `--out `:
82 |
83 | $ asset raphael jquery public/javascripts
84 |
85 | ### Dependency Resolution
86 |
87 | Asset currently supports extremely basic dependency mapping, for example below is the output of installing `g.pie`, which depends on `g.raphael`, which in turn depends on `raphael` itself.
88 |
89 | $ asset g.pie
90 |
91 | install : g.pie@0.4.1
92 | dependency : g.raphael@0.4.1
93 | install : g.raphael@0.4.1
94 | dependency : raphael@1.4.7
95 | install : raphael@1.4.7
96 | download : raphael@1.4.7
97 | complete : raphael@1.4.7 public/raphael.js
98 | download : g.raphael@0.4.1
99 | complete : g.raphael@0.4.1 public/g.raphael.js
100 | download : g.pie@0.4.1
101 | complete : g.pie@0.4.1 public/g.pie.js
102 |
103 | ### Asset Information
104 |
105 | Inspect verbose asset information:
106 |
107 | $ asset info jquery g.raphael
108 |
109 | name : jquery
110 | description : jquery core framework
111 | url : http://code.jquery.com/jquery-{version}.min.js
112 | version : 1.5.2
113 | filename : jquery.js
114 |
115 | name : g.raphael
116 | description : charting for raphael
117 | url : https://github.com/DmitryBaranovskiy/g.raphael/raw/v{version}/g.raphael-min.js
118 | version : 0.4.1
119 | filename : g.raphael.js
120 | dependencies : raphael
121 |
122 |
123 | ### Installation Destination
124 |
125 | To install a specific version, we can use the `@` character:
126 |
127 | $ asset jquery@1.5.0
128 |
129 | ### Search Repository
130 |
131 | We can search the repository with an optional query, listing
132 | available assets and their default versions:
133 |
134 | $ asset raphael
135 |
136 | install : raphael@1.4.7
137 | download : raphael@1.4.7
138 | complete : raphael@1.4.7 public/raphael.js
139 |
140 | ### assets.json
141 |
142 | By adding `./assets.json` you can store application dependencies, and install them quickly and easily with a single command `asset`. For example this file may contain one or more deps:
143 |
144 | {
145 | "g.raphael": "0.4.1"
146 | , "jquery": "1.5.2"
147 | , "modernizr": "1.7"
148 | }
149 |
150 |
151 | Installed with the command:
152 |
153 | $ asset
154 |
155 | install : g.raphael@0.4.1
156 | dependency : raphael@1.4.7
157 | install : raphael@1.4.7
158 | install : jquery@1.5.2
159 | install : modernizr@1.7
160 | download : jquery@1.5.2
161 | complete : jquery@1.5.2 public/jquery.js
162 | download : raphael@1.4.7
163 | complete : raphael@1.4.7 public/raphael.js
164 | download : g.raphael@0.4.1
165 | complete : g.raphael@0.4.1 public/g.raphael.js
166 | download : modernizr@1.7
167 | complete : modernizr@1.7 public/modernizr.js
168 |
169 | ### Configuration
170 |
171 | By default options must be passed via the CLI, however `asset` will also check the `./.asset` and `~/.asset` JSON configuration files, so for example a project may set `{ "out": "public/javascripts" }` if we are mainly working with javascript, however the CLI options will always take precedence.
172 |
173 | ### The Repository
174 |
175 | By default the repo bundled with `asset` is used, however the `~/.assets` configuration file is checked first. Perhaps down the road if/when asset becomes more flexible a repo will be hosted, for now simply fork the project edit `./assets.json`, and send a pull request.
176 |
177 | ## License
178 |
179 | (The MIT License)
180 |
181 | Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca>
182 |
183 | Permission is hereby granted, free of charge, to any person obtaining
184 | a copy of this software and associated documentation files (the
185 | 'Software'), to deal in the Software without restriction, including
186 | without limitation the rights to use, copy, modify, merge, publish,
187 | distribute, sublicense, and/or sell copies of the Software, and to
188 | permit persons to whom the Software is furnished to do so, subject to
189 | the following conditions:
190 |
191 | The above copyright notice and this permission notice shall be
192 | included in all copies or substantial portions of the Software.
193 |
194 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
195 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
196 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
197 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
198 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
199 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
200 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "blueprint": {
3 | "base": "https://github.com/joshuaclayton/blueprint-css/raw/v{version}/blueprint",
4 | "description": "css framework",
5 | "tags": ["css"],
6 | "files": [
7 | "ie.css",
8 | "print.css",
9 | "screen.css",
10 | "src/forms.css",
11 | "src/grid.css",
12 | "src/grid.png",
13 | "src/ie.css",
14 | "src/print.css",
15 | "src/reset.css",
16 | "src/typography.css"
17 | ],
18 | "version": "1.0"
19 | },
20 | "bootstrap": {
21 | "url": "https://github.com/twitter/bootstrap/raw/v{version}/bootstrap-{version}.css",
22 | "compressed": "bootstrap-{version}.min.css",
23 | "description": "CSS toolkit from Twitter",
24 | "tags": ["css", "twitter"],
25 | "version": "1.1.1"
26 | },
27 | "bootstrap-less": {
28 | "base": "https://github.com/twitter/bootstrap/raw/v{version}",
29 | "description": "CSS toolkit from Twitter (LESS Source)",
30 | "tags": ["css", "twitter", "less"],
31 | "files": [
32 | "lib/bootstrap.less",
33 | "lib/forms.less",
34 | "lib/patterns.less",
35 | "lib/preboot.less",
36 | "lib/reset.less",
37 | "lib/scaffolding.less",
38 | "lib/tables.less",
39 | "lib/type.less"
40 | ],
41 | "version": "1.1.1"
42 | },
43 | "eventemitter2": {
44 | "url": "https://github.com/hij1nx/EventEmitter2/blob/v{version}/lib/eventemitter2.js",
45 | "description": "nodejs-style event emitter with namespaces, wildcards, TTL etc",
46 | "tags": ["events", "emitter", "node"],
47 | "version": "0.4.1"
48 | },
49 | "superagent": {
50 | "url": "https://raw.github.com/visionmedia/superagent/{version}/superagent.js",
51 | "description": "Ajax with less suck",
52 | "tags": ["request", "ajax"],
53 | "version": "0.1.1"
54 | },
55 | "caustic": {
56 | "url": "https://github.com/visionmedia/caustic/raw/{version}/build/caustic.js",
57 | "description": "Experimental view system for jQuery",
58 | "tags": ["templates", "view"],
59 | "version": "0.0.5"
60 | },
61 | "move.js": {
62 | "url": "https://github.com/visionmedia/move.js/raw/{version}/move.js",
63 | "description": "CSS3 JavaScript animation framework",
64 | "tags": ["css", "animation"],
65 | "version": "0.1.1"
66 | },
67 | "jade": {
68 | "url": "https://github.com/visionmedia/jade/raw/{version}/jade.js",
69 | "description": "jade template engine",
70 | "tags": ["template"],
71 | "version": "0.10.4"
72 | },
73 | "three.js": {
74 | "url": "https://github.com/mrdoob/three.js/raw/r{version}/build/Three.js",
75 | "description": "3d javascript engine",
76 | "tags": ["js", "3d"],
77 | "filename": "three.js",
78 | "version": "42"
79 | },
80 | "underscore": {
81 | "url": "https://github.com/documentcloud/underscore/raw/{version}/underscore.js",
82 | "description": "javascript's utility belt",
83 | "compressed": "underscore-min.js",
84 | "tags": ["js", "utilities"],
85 | "version": "1.1.7"
86 | },
87 | "mootools": {
88 | "url": "http://mootools.net/download/get/mootools-core-{version}-full-compat.js",
89 | "description": "mootools core javascript framework",
90 | "compressed": "mootools-core-{version}-full-compat-yc.js",
91 | "filename": "mootools.js",
92 | "tags": ["js"],
93 | "version": "1.3.1"
94 | },
95 | "raphael": {
96 | "url": "https://github.com/DmitryBaranovskiy/raphael/raw/v{version}/raphael.js",
97 | "description": "raphael vector library",
98 | "compressed": "raphael-min.js",
99 | "tags": ["js"],
100 | "version": "1.4.7"
101 | },
102 | "g.raphael": {
103 | "url": "https://github.com/DmitryBaranovskiy/g.raphael/raw/v{version}/g.raphael.js",
104 | "description": "charting for raphael",
105 | "compressed": "g.raphael-min.js",
106 | "tags": ["js", "raphael"],
107 | "version": "0.4.1",
108 | "dependencies": {
109 | "raphael": "1.4.7"
110 | }
111 | },
112 | "g.bar": {
113 | "url": "https://github.com/DmitryBaranovskiy/g.raphael/raw/v{version}/g.bar.js",
114 | "description": "bar charting for raphael",
115 | "compressed": "g.bar-min.js",
116 | "tags": ["js", "raphael"],
117 | "version": "0.4.1",
118 | "dependencies": {
119 | "g.raphael": "0.4.1"
120 | }
121 | },
122 | "g.dot": {
123 | "url": "https://github.com/DmitryBaranovskiy/g.raphael/raw/v{version}/g.dot.js",
124 | "description": "dot charting for raphael",
125 | "compressed": "g.dot-min.js",
126 | "tags": ["js", "raphael"],
127 | "version": "0.4.1",
128 | "dependencies": {
129 | "g.raphael": "0.4.1"
130 | }
131 | },
132 | "g.line": {
133 | "url": "https://github.com/DmitryBaranovskiy/g.raphael/raw/v{version}/g.line.js",
134 | "description": "line charting for raphael",
135 | "compressed": "g.line-min.js",
136 | "tags": ["js", "raphael"],
137 | "version": "0.4.1",
138 | "dependencies": {
139 | "g.raphael": "0.4.1"
140 | }
141 | },
142 | "g.pie": {
143 | "url": "https://github.com/DmitryBaranovskiy/g.raphael/raw/v{version}/g.pie.js",
144 | "description": "pie charting for raphael",
145 | "compressed": "g.pie-min.js",
146 | "tags": ["js", "raphael"],
147 | "version": "0.4.1",
148 | "dependencies": {
149 | "g.raphael": "0.4.1"
150 | }
151 | },
152 | "jquery": {
153 | "url": "http://code.jquery.com/jquery-{version}.js",
154 | "description": "jquery core framework",
155 | "compressed": "jquery-{version}.min.js",
156 | "tags": ["js", "jquery"],
157 | "filename": "jquery.js",
158 | "version": "1.6.2"
159 | },
160 | "jquery.validate": {
161 | "url":"http://ajax.aspnetcdn.com/ajax/jquery.validate/{version}/jquery.validate.js",
162 | "compressed": "jquery.validate.min.js",
163 | "description": "form validation for jquery",
164 | "tags": ["js", "jquery"],
165 | "version": "1.8",
166 | "dependencies": {
167 | "jquery": "1.5.1"
168 | }
169 | },
170 | "prototype": {
171 | "url": "http://prototypejs.org/assets/2008/9/29/prototype-{version}.js",
172 | "description": "prototype core framework",
173 | "filename": "prototype.js",
174 | "tags": ["js"],
175 | "version": "1.6.0.3"
176 | },
177 | "script.js": {
178 | "url": "https://github.com/ded/script.js/blob/master/dist/script.js",
179 | "description": "Asyncronous JavaScript loader and dependency manager",
180 | "tags": ["js"],
181 | "version": "1.3"
182 | },
183 | "jquery-mobile": {
184 | "url": "http://code.jquery.com/mobile/{version}/jquery.mobile-{version}.js",
185 | "description": "touch-optimized web framework for smartphones & tablets",
186 | "filename": "jquery.mobile.js",
187 | "tags": ["js", "jquery"],
188 | "version": "1.0a4",
189 | "dependencies": {
190 | "jquery": "1.5.1"
191 | }
192 | },
193 | "processing.js": {
194 | "url": "http://cloud.github.com/downloads/processing-js/processing-js/processing-{version}.js",
195 | "description": "a port of the Processing visualization language",
196 | "filename": "processing.js",
197 | "tags": ["js"],
198 | "version": "1.1.0"
199 | },
200 | "d3": {
201 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.js",
202 | "description": "A JavaScript visualization library for HTML and SVG.",
203 | "filename": "d3.js",
204 | "tags": ["js", "svg"],
205 | "version": "1.17.0"
206 | },
207 | "d3.behavior": {
208 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.behavior.js",
209 | "description": "Event module for d3. A JavaScript visualization library for HTML and SVG.",
210 | "tags": ["js", "svg"],
211 | "version": "1.11.0",
212 | "dependencies": {
213 | "d3": "1.17.0"
214 | }
215 | },
216 | "d3.chart": {
217 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.chart.js",
218 | "description": "Chart module for d3. A JavaScript visualization library for HTML and SVG.",
219 | "tags": ["js", "svg"],
220 | "version": "1.11.0",
221 | "dependencies": {
222 | "d3": "1.17.0"
223 | }
224 | },
225 | "d3.csv": {
226 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.csv.js",
227 | "description": "CSV parser module for d3. A JavaScript visualization library for HTML and SVG.",
228 | "tags": ["js", "svg"],
229 | "version": "1.11.0",
230 | "dependencies": {
231 | "d3": "1.17.0"
232 | }
233 | },
234 | "d3.geo": {
235 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.geo.js",
236 | "description": "Geo module for d3. A JavaScript visualization library for HTML and SVG.",
237 | "tags": ["js", "svg"],
238 | "version": "1.11.0",
239 | "dependencies": {
240 | "d3": "1.17.0"
241 | }
242 | },
243 | "d3.geom": {
244 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.geom.js",
245 | "description": "Geometry module for d3. A JavaScript visualization library for HTML and SVG.",
246 | "tags": ["js", "svg"],
247 | "version": "1.11.0",
248 | "dependencies": {
249 | "d3": "1.17.0"
250 | }
251 | },
252 | "d3.layout": {
253 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.layout.js",
254 | "description": "Layout module for d3. A JavaScript visualization library for HTML and SVG.",
255 | "tags": ["js", "svg"],
256 | "version": "1.11.0",
257 | "dependencies": {
258 | "d3": "1.17.0"
259 | }
260 | },
261 | "d3.time": {
262 | "url": "https://github.com/mbostock/d3/raw/v{version}/d3.time.js",
263 | "description": "Time module for d3. A JavaScript visualization library for HTML and SVG.",
264 | "tags": ["js", "svg"],
265 | "version": "1.11.0",
266 | "dependencies": {
267 | "d3": "1.17.0"
268 | }
269 | },
270 | "protovis": {
271 | "url": "https://github.com/mbostock/protovis/raw/v{version}/protovis.js",
272 | "description": "A visualization toolkit for JavaScript using SVG.",
273 | "tags": ["js", "svg"],
274 | "version": "3.3.1"
275 | },
276 | "polymaps": {
277 | "url": "https://github.com/simplegeo/polymaps/raw/v{version}/polymaps.js",
278 | "description": "Polymaps is a free JavaScript library for making dynamic, interactive maps in modern web browsers.",
279 | "tags": ["js", "maps", "mapping"],
280 | "version": "2.5.0"
281 | },
282 | "date.js": {
283 | "url": "http://datejs.googlecode.com/files/date.js",
284 | "description": "Datejs is an open source JavaScript Date library for parsing, formatting and processing.",
285 | "tags": ["js", "date", "time"],
286 | "version": "1.0 Alpha-1"
287 | },
288 | "backbone": {
289 | "url": "https://github.com/documentcloud/backbone/raw/{version}/backbone.js",
290 | "compressed": "backbone-min.js",
291 | "description": "Backbone supplies structure to Javascript Apps by providing models, views, collections, and events",
292 | "tags": ["js"],
293 | "version": "0.5.1"
294 | },
295 | "zepto": {
296 | "url": "https://github.com/madrobby/zepto/raw/v{version}/src/zepto.js",
297 | "description": "zepto.js is a minimalist inlinable framework for mobile WebKit browsers, with a jQuery-like chaining syntax",
298 | "tags": ["js"],
299 | "version": "0.5"
300 | },
301 | "iscroll": {
302 | "url": "https://github.com/cubiq/iscroll/raw/master/src/iscroll.js",
303 | "description": "Hardware accelerated scroll for mobile webkit",
304 | "tags": ["js"],
305 | "version": "4.0"
306 | },
307 | "iscroll-lite": {
308 | "url": "https://github.com/cubiq/iscroll/raw/master/src/iscroll-lite.js",
309 | "description": "Hardware accelerated scroll for mobile webkit",
310 | "tags": ["js"],
311 | "version": "4.0"
312 | },
313 | "modernizr": {
314 | "url": "https://github.com/Modernizr/Modernizr/raw/v{version}/modernizr.js",
315 | "description": "Feature detection to test browsers against upcoming features",
316 | "tags": ["js", "css", "detection"],
317 | "version": "1.7"
318 | },
319 | "yepnope": {
320 | "url": "https://github.com/SlexAxton/yepnope.js/raw/v{version}/yepnope.js",
321 | "description": "Conditional loader for polyfills",
322 | "tags": ["js", "detection"],
323 | "version": "1.0.1"
324 | },
325 | "live.js": {
326 | "url": "http://livejs.com/live.js",
327 | "description": "Live.js makes sure you're always looking at the latest version of the page you're working on, whether you're writing HTML, CSS or Javascript",
328 | "tags": ["js"],
329 | "version": "3.0"
330 | },
331 | "fidel": {
332 | "url": "https://raw.github.com/jgallen23/fidel/master/dist/fidel.js",
333 | "compressed": "fidel.min.js",
334 | "description": "Fidel is a simple, lightweight ui controller library",
335 | "tags": ["js"],
336 | "version": "1.1.2"
337 | },
338 | "str.js": {
339 | "url": "https://raw.github.com/jgallen23/str.js/master/str.js",
340 | "description": "A string utility library",
341 | "tags": ["js", "string", "template", "format"],
342 | "version": "1.0.3"
343 | },
344 | "resistance": {
345 | "url": "https://raw.github.com/jgallen23/resistance/master/dist/resistance.js",
346 | "compressed": "resistance.min.js",
347 | "description": "A simple async flow control library",
348 | "tags": ["js", "flow", "async"],
349 | "version": "1.0.1"
350 | },
351 | "pagie": {
352 | "url": "https://raw.github.com/jgallen23/pagie/master/pagie.js",
353 | "compressed": "pagie.min.js",
354 | "description": "A simple pagination class",
355 | "tags": ["js", "pagination"],
356 | "version": "0.0.1"
357 | },
358 | "mustache.js": {
359 | "url": "https://raw.github.com/janl/mustache.js/{version}/mustache.js",
360 | "description": "Minimal templating with {{mustaches}} in JavaScript",
361 | "version": "0.3.0",
362 | "tags": ["js", "templates", "templating"]
363 | },
364 | "jade-runtime": {
365 | "url": "https://github.com/visionmedia/jade/raw/{version}/runtime.js",
366 | "description": "jade template engine for client-side use",
367 | "compressed": "runtime.min.js",
368 | "tags": ["template"],
369 | "version": "0.27.4"
370 | }
371 | }
372 |
--------------------------------------------------------------------------------
/bin/asset:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * Module dependencies.
5 | */
6 |
7 | var asset = require('../')
8 | , exec = require('child_process').exec
9 | , tty = require('tty')
10 | , fs = require('fs');
11 |
12 | /**
13 | * Arguments.
14 | */
15 |
16 | var args = process.argv.slice(2);
17 |
18 | /**
19 | * Assets to install.
20 | */
21 |
22 | var assets = [];
23 |
24 | /**
25 | * Default options.
26 | */
27 |
28 | var options = {
29 | out: 'public'
30 | , compress: false
31 | };
32 |
33 | /**
34 | * Usage information.
35 | */
36 |
37 | var usage = [
38 | ''
39 | , ' Usage: asset [command] [options]'
40 | , ''
41 | , ' Commands:'
42 | , ''
43 | , ' install installs the given asset '
44 | , ' search [query] search available assets with optional [query]'
45 | , ' info display verbose information for the given asset '
46 | , ' none install dependencies from ./assets.json'
47 | , ''
48 | , ' Options:'
49 | , ''
50 | , ' -c, --compress compress assets'
51 | , ' -o, --out output directory defaulting to ./public'
52 | , ' -V, --version output program version'
53 | , ' -h, --help display help information'
54 | , ''
55 | ].join('\n');
56 |
57 | /**
58 | * Configuration.
59 | */
60 |
61 | var config = readJSON(process.cwd() + '/.asset')
62 | || readJSON(process.env.HOME + '/.asset')
63 | || {};
64 |
65 | /**
66 | * Repository.
67 | */
68 |
69 | var repo = readJSON(process.env.HOME + '/.assets')
70 | || readJSON(__dirname + '/../assets.json')
71 | || {};
72 |
73 | // merge config
74 |
75 | Object.keys(config).forEach(function(key){
76 | options[key] = config[key];
77 | });
78 |
79 | // parse arguments
80 |
81 | var arg;
82 | while (args.length) {
83 | arg = args.shift();
84 | switch (arg) {
85 | case '-h':
86 | case '--help':
87 | case 'help':
88 | console.log(usage);
89 | process.exit();
90 | break;
91 | case '-V':
92 | case '--version':
93 | console.log(asset.version);
94 | process.exit();
95 | break;
96 | case '-c':
97 | case '--compress':
98 | options.compress = true;
99 | break;
100 | case 'install':
101 | // ignore
102 | break;
103 | case 'search':
104 | console.log();
105 | search(args.shift());
106 | console.log();
107 | process.exit();
108 | break;
109 | case 'info':
110 | console.log();
111 | while (args.length) {
112 | info(args.shift());
113 | console.log();
114 | }
115 | process.exit();
116 | break;
117 | case '-o':
118 | case '--out':
119 | options.out = required(arg);
120 | break;
121 | default:
122 | if (~arg.indexOf('/')) {
123 | options.out = arg;
124 | } else {
125 | assets.push(arg);
126 | }
127 | }
128 | }
129 |
130 | // parse the asset strings or ./assets.json
131 |
132 | if (assets.length) {
133 | assets = assets.map(parse);
134 | } else {
135 | assets = assetsFromObject(readJSON('assets.json'));
136 | }
137 |
138 | // ensure we have assets
139 |
140 | if (!assets.length) abort('asset required');
141 |
142 | // install the assets
143 | console.log();
144 | mkdir(options.out, function(err){
145 | if (err) abort(err.message);
146 | install(assets);
147 | });
148 | process.on('exit', function(){ console.log(); });
149 |
150 | /**
151 | * Install assets from JSON `obj`.
152 | *
153 | * @param {Object} obj
154 | */
155 |
156 | function assetsFromObject(obj) {
157 | var arr = [];
158 | for (var asset in obj) {
159 | arr.push({ name: asset, version: obj[asset], compress: options.compress });
160 | }
161 | return arr;
162 | }
163 |
164 | /**
165 | * Install the given `assets`.
166 | *
167 | * @param {Array} assets
168 | */
169 |
170 | function install(assets) {
171 | var install = asset.install(assets, repo, options.out);
172 |
173 | install.on('unknown', function(asset){
174 | abort('unregistered asset ' + asset.name);
175 | });
176 |
177 | install.on('install', function(asset){
178 | log('install', name(asset));
179 | });
180 |
181 | install.on('download', function(asset, res){
182 | log('download', name(asset));
183 | });
184 |
185 | install.on('file download', function(asset, file, res){
186 | log('download', name(asset) + ' ' + file);
187 | });
188 |
189 | install.on('dependency', function(asset, dep){
190 | log('dependency', name(dep));
191 | });
192 |
193 | install.on('complete', function(asset, path){
194 | log('complete', name(asset) + ' ' + path);
195 | });
196 |
197 | install.on('complete files', function(asset, files){
198 | log('complete', name(asset) + ' ' + files.length + ' files');
199 | });
200 |
201 | install.on('error', function(err){
202 | abort(err.message);
203 | });
204 | }
205 |
206 | /**
207 | * Display info for asset `name`.
208 | *
209 | * @param {String} name
210 | */
211 |
212 | function info(name){
213 | var asset = repo[name];
214 | if (!asset) abort('failed to lookup asset "' + name + '"');
215 | log('name', name);
216 | log('description', asset.description);
217 | log('url', asset.url);
218 | if (asset.version) log('version', asset.version);
219 | if (asset.filename) log('filename', asset.filename);
220 | if (asset.dependencies) log('dependencies', Object.keys(asset.dependencies).join(', '));
221 | }
222 |
223 | /**
224 | * Search using the given `query` string.
225 | *
226 | * @param {String} query
227 | */
228 |
229 | function search(query) {
230 | var size = Array.isArray(tty.getWindowSize()) ? tty.getWindowSize().reverse() : process.stdout.getWindowSize()
231 | , padding = 30
232 | , width = size.shift() - padding
233 | , height = size.shift();
234 |
235 | asset.search(repo, query, function(name, entry){
236 | var desc = entry.description;
237 | if (desc.length > width) {
238 | desc = desc.substr(0, width - 3) + '...';
239 | }
240 |
241 | desc = desc
242 | ? '\033[90m: ' + desc + '\033[0m'
243 | : '';
244 |
245 | log(name, entry.version + ' ' + desc);
246 | });
247 | }
248 |
249 | /**
250 | * Log key / val.
251 | *
252 | * @param {String} key
253 | * @param {String} val
254 | */
255 |
256 | function log(key, val) {
257 | var width = 15
258 | , len = key.length;
259 | if (len < width) key = Array(width - len).join(' ') + key;
260 | console.log(' \033[90m%s :\033[0m \033[36m%s\033[0m', key, val);
261 | }
262 |
263 | /**
264 | * Normalize `asset` string, returning an object
265 | * representation of what is to be installed.
266 | *
267 | * Syntax:
268 | *
269 | * ['@' version] [':' 'compress']
270 | *
271 | * @param {String} asset
272 | * @return {Object}
273 | */
274 |
275 | function parse(asset) {
276 | var captures = asset.match(/([^:@]+)(?:@([^:]+))?((:\w+)*)/)
277 | , modifiers = captures[3].split(':').slice(1);
278 |
279 | return {
280 | name: captures[1]
281 | , version: captures[2]
282 | , compress: ~modifiers.indexOf('compress') || options.compress
283 | };
284 | }
285 |
286 | /**
287 | * Require argument for `flag`.
288 | *
289 | * @param {String} flag
290 | * @return {String}
291 | */
292 |
293 | function required(flag) {
294 | if (args.length) return args.shift();
295 | abort(flag + ' argument required');
296 | }
297 |
298 | /**
299 | * Abort with `msg`.
300 | *
301 | * @param {String} msg
302 | */
303 |
304 | function abort(msg) {
305 | console.error(' \033[31m%s\033[0m', msg);
306 | process.exit(1);
307 | }
308 |
309 | /**
310 | * Return asset name/
311 | *
312 | * @param {Object} asset
313 | * @return {String}
314 | */
315 |
316 | function name(asset) {
317 | return asset.name + '@' + asset.version;
318 | }
319 |
320 | /**
321 | * Attempt to read config json at `path`.
322 | *
323 | * @param {String} path
324 | * @return {Object}
325 | */
326 |
327 | function readJSON(path) {
328 | try {
329 | return JSON.parse(fs.readFileSync(path, 'utf8'));
330 | } catch (err) {
331 | // ignore
332 | }
333 | }
334 |
335 | /**
336 | * Mkdir -p.
337 | *
338 | * @param {String} path
339 | * @param {Function} fn
340 | */
341 |
342 | function mkdir(path, fn) {
343 | exec('mkdir -p ' + path, fn);
344 | }
345 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 |
2 | module.exports = require('./lib/asset');
--------------------------------------------------------------------------------
/lib/asset.js:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * asset
4 | * Copyright(c) 2011 TJ Holowaychuk
5 | * MIT Licensed
6 | */
7 |
8 | /**
9 | * Module dependencies.
10 | */
11 |
12 | var Installer = require('./installer');
13 |
14 | /**
15 | * Library version.
16 | */
17 |
18 | exports.version = '0.4.13';
19 |
20 | /**
21 | * Install `assets` with `repo` object, and `dest` directory.
22 | *
23 | * @param {Array} assets
24 | * @param {Object} repo
25 | * @param {String} dest
26 | * @return {Installer}
27 | * @api public
28 | */
29 |
30 | exports.install = function(assets, repo, dest){
31 | var installer = new Installer(repo, dest);
32 | assets.forEach(function(asset){
33 | process.nextTick(function(){
34 | installer.install(asset);
35 | });
36 | });
37 | return installer;
38 | };
39 |
40 | /**
41 | * Search `repo` for `query`, invoking `fn(name, entry)`
42 | * per matching entry.
43 | *
44 | * @param {Object} repo
45 | * @param {String} query
46 | * @param {Function} fn
47 | * @api public
48 | */
49 |
50 | exports.search = function(repo, query, fn){
51 | var names = Object.keys(repo);
52 | names.forEach(function(name){
53 | var entry = repo[name]
54 | , match = !query
55 | || ~name.indexOf(query)
56 | || ~entry.tags.indexOf(query);
57 | if (match) fn(name, entry);
58 | });
59 | };
--------------------------------------------------------------------------------
/lib/installer.js:
--------------------------------------------------------------------------------
1 |
2 | /*!
3 | * asset - Installer
4 | * Copyright(c) 2011 TJ Holowaychuk
5 | * MIT Licensed
6 | */
7 |
8 | /**
9 | * Module dependencies.
10 | */
11 |
12 | var EventEmitter = require('events').EventEmitter
13 | , dirname = require('path').dirname
14 | , basename = require('path').basename
15 | , extname = require('path').extname
16 | , mkdir = require('mkdirp').mkdirp
17 | , request = require('request')
18 | , fs = require('fs');
19 |
20 | /**
21 | * Expose installer.
22 | */
23 |
24 | module.exports = Installer;
25 |
26 | /**
27 | * Initialize a new `Installer`.
28 | *
29 | * @param {Object} repo
30 | * @api private
31 | */
32 |
33 | function Installer(repo, dest) {
34 | this.assets = [];
35 | this.repo = repo;
36 | this.dest = dest;
37 | if (!repo) throw new Error('repository required');
38 | this.queued = {};
39 | }
40 |
41 | /**
42 | * Inherit from `EventEmitter.prototype`.
43 | */
44 |
45 | Installer.prototype.__proto__ = EventEmitter.prototype;
46 |
47 | /**
48 | * Install the given `asset`.
49 | *
50 | * Asset:
51 | *
52 | * - `name` name of the asset
53 | * - `version` version of the asset
54 | *
55 | * @param {Object} asset
56 | * @api private
57 | */
58 |
59 | Installer.prototype.install = function(asset){
60 | var entry = this.lookup(asset);
61 | if (!entry) return this.emit('unknown', asset);
62 | asset.entry = entry;
63 | if (this.queued[asset.name]) return this.emit('queued', asset);
64 | this.emit('install', asset);
65 | this.queued[asset.name] = true;
66 | this.installDependencies(asset);
67 |
68 | // several files
69 | if (entry.files) {
70 | this.downloadFiles(asset, entry.files, this.dest);
71 | } else {
72 | this.download(asset, this.dest + '/' + entry.filename);
73 | }
74 | };
75 |
76 | /**
77 | * Lookup and normalize repo entry for `asset`.
78 | *
79 | * @param {Object} asset
80 | * @return {Object}
81 | * @api private
82 | */
83 |
84 | Installer.prototype.lookup = function(asset){
85 | // invalid or not found
86 | if (!asset.name) throw new Error('asset name required');
87 | var entry = this.repo[asset.name];
88 | if (!entry) return;
89 |
90 | // normalize filename
91 | entry.filename = entry.filename || basename(entry.url);
92 |
93 | // normalize compressed url
94 | if (entry.compressed && !~entry.compressed.indexOf('://')) {
95 | entry.compressed = entry.url.replace(basename(entry.url), entry.compressed);
96 | }
97 |
98 | // default version
99 | if (!asset.version) asset.version = entry.version;
100 |
101 | // extension
102 | entry.ext = extname(entry.url);
103 |
104 | return entry;
105 | };
106 |
107 | /**
108 | * Install the given `asset` dependencies when present.
109 | *
110 | * @param {Object} asset
111 | * @api private
112 | */
113 |
114 | Installer.prototype.installDependencies = function(asset){
115 | var version;
116 | for (var dep in asset.entry.dependencies) {
117 | version = asset.entry.dependencies[dep];
118 | dep = { name: dep, version: version };
119 | this.emit('dependency', asset, dep);
120 | this.install(dep);
121 | }
122 | };
123 |
124 | /**
125 | * Download the given `files` to `dest`.
126 | *
127 | * @param {Object} asset
128 | * @param {Array} files
129 | * @param {String} dest
130 | * @api private
131 | */
132 |
133 | Installer.prototype.downloadFiles = function(asset, files, dest){
134 | var pending = files.length
135 | , self = this;
136 |
137 | files.forEach(function(file){
138 | self.downloadFile(asset, file, dest, function(err){
139 | if (err) return self.emit('error', err);
140 | --pending || self.emit('complete files', asset, files);
141 | });
142 | });
143 | };
144 |
145 | /**
146 | * Download the given `asset`'s `file` to `dest`.
147 | *
148 | * @param {Object} asset
149 | * @param {String} file
150 | * @param {String} dest
151 | * @param {Function} fn
152 | * @api private
153 | */
154 |
155 | Installer.prototype.downloadFile = function(asset, file, dest, fn){
156 | var base = asset.entry.base.replace(/\{version\}/g, asset.version)
157 | , url = base + '/' + file
158 | , path = dest + '/' + file
159 | , dest = dest + '/' + dirname(file)
160 | , self = this;
161 |
162 | request({ url: url }, function(err, res, body){
163 | if (err) return fn(err);
164 | if (res.statusCode >= 300) {
165 | var err = new Error('failed to download ' + url);
166 | fn(err);
167 | } else {
168 | self.emit('file download', asset, path, res);
169 | mkdir(dest, 0755, function(err){
170 | if (err) return fn(err);
171 | fs.writeFile(path, body, function(err){
172 | if (err) return fn(err);
173 | self.emit('file write', asset, path);
174 | fn();
175 | });
176 | });
177 | }
178 | });
179 | };
180 |
181 | /**
182 | * Download the given `asset` to `path`.
183 | *
184 | * @param {Object} asset
185 | * @param {String} path
186 | * @api private
187 | */
188 |
189 | Installer.prototype.download = function(asset, path){
190 | var self = this
191 | , version = asset.version
192 | , url = asset.entry[asset.compress ? 'compressed' : 'url'] || asset.entry.url
193 | , url = url.replace(/\{version\}/g, version)
194 | , path = path.replace(/\{version\}/g, version);
195 |
196 | // compressed
197 | if (asset.compress && asset.entry.compressed) {
198 | switch (asset.entry.ext) {
199 | case '.js':
200 | path = path.replace(/\.js$/, '.min.js');
201 | break;
202 | }
203 | }
204 |
205 | // request the data
206 | request({ url: url }, function(err, res, body){
207 | if (err) return self.emit('error', err);
208 | if (res.statusCode >= 300) {
209 | var err = new Error('failed to download ' + url);
210 | self.emit('error', err);
211 | } else {
212 | self.emit('download', asset, res);
213 | fs.writeFile(path, body, function(err){
214 | if (err) return self.emit('error', err);
215 | self.emit('complete', asset, path);
216 | });
217 | }
218 | });
219 | };
220 |
221 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | { "name": "asset"
2 | , "version": "0.4.13"
3 | , "description": "Asset manager"
4 | , "keywords": ["assets", "javascript", "css", "package manager"]
5 | , "author": "TJ Holowaychuk "
6 | , "dependencies": { "request": "1.9.5", "mkdirp": "0.3.x" }
7 | , "bin": { "asset": "./bin/asset" }
8 | , "main": "index"
9 | }
10 |
--------------------------------------------------------------------------------