Last active
August 29, 2015 14:02
-
-
Save ForbesLindesay/74b01d2fedf06b8f325e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
// run this in the packages directory of the metor repository to generate "meteor-packages.html" | |
var fs = require('fs'); | |
var uglify = require('uglify-js'); | |
function getDependenciesFromSource(str) { | |
var dependencies = { | |
summary: '', | |
use: [], | |
require: [] | |
}; | |
function visitor(node) { | |
if (node.TYPE === 'Call' && node.expression.TYPE === 'Dot') { | |
var method = node.expression.property; | |
if (method === 'use' || method === 'require') { | |
dependencies[method] = dependencies[method].concat( | |
node.args.reduce(function (acc, next) { | |
return acc.concat(next.TYPE === 'Array' ? next.elements : [next]) | |
}, []).filter(function (arg) { | |
return arg.TYPE === 'String' && arg.value !== 'client' && arg.value !== 'server'; | |
}).map(function (arg) { | |
return arg.value; | |
})); | |
} | |
if (method === 'describe') { | |
node.args.filter(function (arg) { | |
return arg.TYPE === 'Object'; | |
}).reduce(function (acc, obj) { | |
return acc.concat(obj.properties); | |
}, []).filter(function (prop) { | |
return prop.TYPE === 'ObjectKeyVal' && prop.key === 'summary' && prop.value.TYPE === 'String'; | |
}).forEach(function (prop) { | |
dependencies.summary = prop.value.value | |
}); | |
} | |
} | |
} | |
var ast = uglify.parse(str); | |
ast.walk(new uglify.TreeWalker(visitor)); | |
function unique(item, i, arr) { | |
return arr.indexOf(item) === i; | |
} | |
return { | |
summary: dependencies.summary, | |
use: dependencies.use.sort().filter(unique), | |
require: dependencies.require.sort().filter(unique) | |
}; | |
} | |
var nodesByName = {}; | |
var nodes = []; | |
function parse(name) { | |
if (nodesByName['key:' + name]) return nodesByName['key:' + name]; | |
var node = nodesByName['key:' + name] = { | |
name: name, | |
summary: '', | |
require: [], | |
use: [] | |
}; | |
nodes.push(node); | |
var str = fs.readFileSync(__dirname + '/' + name + '/package.js', 'utf8'); | |
var deps = getDependenciesFromSource(str); | |
node.summary = deps.summary; | |
node.require = deps.require; | |
node.use = deps.use.filter(function (name) { | |
return name !== node.name; | |
}); | |
return node; | |
} | |
fs.readdirSync(__dirname).filter(function (name) { | |
return fs.existsSync(__dirname + '/' + name + '/package.js'); | |
}).forEach(parse); | |
fs.writeFileSync(__dirname + '/data.json', JSON.stringify(nodes, null, ' ')); | |
fs.writeFileSync(__dirname + '/meteor-packages.html', fs.readFileSync(__dirname + '/index.html', 'utf8').replace(/{{data}}/g, JSON.stringify(nodes, null, ' '))); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/> | |
<style> | |
.btn-clear { | |
display: block; | |
background: none; | |
border: none; | |
width: 100%; | |
text-align: left; | |
outline: none; | |
padding: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Meteor JS Packages</h1> | |
<form role="form"> | |
<div class="form-group"> | |
<label class="sr-only" for="search">Search</label> | |
<input type="search" class="form-control" id="search" placeholder="Search..."> | |
<p class="help-block">Enter spaces to search for multiple different modules.</p> | |
<p class="help-block">Click on modules to expand and see their dependencies.</p> | |
</div> | |
</form> | |
<div id="display"> | |
</div> | |
</div> | |
<script id="data" type="application/json">{{data}}</script> | |
<script> | |
var expanded = []; | |
var display = document.getElementById('display'); | |
var search = document.getElementById('search'); | |
var raw = JSON.parse(document.getElementById('data').textContent); | |
var byName = {}; | |
raw.forEach(function (node) { | |
byName[node.name] = node; | |
}); | |
search.value = decodeURIComponent(location.hash).substring(1); | |
function filter(raw) { | |
return raw.filter(function (node) { | |
if (search.value.trim() === '') return true; | |
return search.value.split(' ').filter(function (name) { | |
return name.trim() !== ''; | |
}).some(function (searchTerm) { | |
return node.name.indexOf(searchTerm) !== -1; | |
}) | |
}); | |
} | |
function render() { | |
location.hash = encodeURIComponent(search.value); | |
display.innerHTML = renderCollection(filter(raw), ''); | |
} | |
function renderCollection(data, path) { | |
return '<ul class="list-group">' + data.map(function (node) { | |
var p = path + node.name; | |
var isCircular = path.indexOf(node.name + '.') === 0 || path.indexOf('.' + node.name + '.') !== -1; | |
var isExpandable = node.use.length > 0 && !isCircular; | |
var isExpanded = expanded.indexOf(p) !== -1; | |
var open = '<li class="list-group-item">'; | |
var badge = !isExpanded && isExpandable ? | |
'<span class="badge pull-right">' + node.use.length + '</span>' : | |
isCircular ? '<span class="label label-danger pull-right">circular</span>' : ''; | |
var name = '<p class="lead">' + node.name + '</p>'; | |
var summary = '<p>' + node.summary + '</p>'; | |
var button = '<button data-name="' + p + '"type="button" class="btn-clear">' + badge + name + summary + '</button>'; | |
var children = isExpanded && isExpandable ? renderCollection(node.use.map(function (name) { | |
return byName[name]; | |
}), p + '.') : ''; | |
var close = '</li>'; | |
if (!isExpandable) return open + badge + name + summary + close; | |
return open + button + children + close; | |
}).join('') + '</ul>'; | |
} | |
render(); | |
search.addEventListener('keyup', render, false); | |
search.addEventListener('change', render, false); | |
display.addEventListener('click', function (e) { | |
var target = e.target; | |
while (target && target.hasAttribute && !target.hasAttribute('data-name')) { | |
target = target.parentNode; | |
} | |
if (!(target && target.hasAttribute)) return; | |
var name = target.getAttribute('data-name'); | |
var i = expanded.indexOf(name); | |
if (i === -1) { | |
expanded.push(name); | |
} else { | |
expanded.splice(i, 1); | |
} | |
render(); | |
}) | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet"/> | |
<style> | |
.btn-clear { | |
display: block; | |
background: none; | |
border: none; | |
width: 100%; | |
text-align: left; | |
outline: none; | |
padding: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Meteor JS Packages</h1> | |
<form role="form"> | |
<div class="form-group"> | |
<label class="sr-only" for="search">Search</label> | |
<input type="search" class="form-control" id="search" placeholder="Search..."> | |
<p class="help-block">Enter spaces to search for multiple different modules.</p> | |
<p class="help-block">Click on modules to expand and see their dependencies.</p> | |
</div> | |
</form> | |
<div id="display"> | |
</div> | |
</div> | |
<script id="data" type="application/json">[ | |
{ | |
"name": "accounts-base", | |
"summary": "A user account system", | |
"require": [], | |
"use": [ | |
"autopublish", | |
"callback-hook", | |
"check", | |
"deps", | |
"ejson", | |
"livedata", | |
"localstorage", | |
"mongo-livedata", | |
"oauth-encryption", | |
"random", | |
"service-configuration", | |
"test-helpers", | |
"tinytest", | |
"ui", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "accounts-facebook", | |
"summary": "Login service for Facebook accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"facebook" | |
] | |
}, | |
{ | |
"name": "accounts-github", | |
"summary": "Login service for Github accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"github" | |
] | |
}, | |
{ | |
"name": "accounts-google", | |
"summary": "Login service for Google accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"google", | |
"random", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "accounts-meetup", | |
"summary": "Login service for Meetup accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"meetup" | |
] | |
}, | |
{ | |
"name": "accounts-meteor-developer", | |
"summary": "Login service for Meteor developer accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"meteor-developer", | |
"random", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "accounts-oauth", | |
"summary": "Common code for OAuth-based login services", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"check", | |
"oauth", | |
"random", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "accounts-password", | |
"summary": "Password support for accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"check", | |
"deps", | |
"email", | |
"livedata", | |
"random", | |
"srp", | |
"test-helpers", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "accounts-twitter", | |
"summary": "Login service for Twitter accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"http", | |
"twitter", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "accounts-ui", | |
"summary": "Simple templates to add login widgets to an app", | |
"require": [], | |
"use": [ | |
"accounts-ui-unstyled", | |
"less" | |
] | |
}, | |
{ | |
"name": "accounts-ui-unstyled", | |
"summary": "Unstyled version of login widgets", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"accounts-password", | |
"deps", | |
"service-configuration", | |
"session", | |
"templating", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "accounts-weibo", | |
"summary": "Login service for Sina Weibo accounts", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"accounts-oauth", | |
"weibo" | |
] | |
}, | |
{ | |
"name": "amplify", | |
"summary": "API for Persistent Storage, PubSub and Request", | |
"require": [], | |
"use": [ | |
"jquery" | |
] | |
}, | |
{ | |
"name": "appcache", | |
"summary": "Enable the application cache in the browser", | |
"require": [], | |
"use": [ | |
"autoupdate", | |
"reload", | |
"routepolicy", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "application-configuration", | |
"summary": "Interaction with the configuration sources for your apps", | |
"require": [], | |
"use": [ | |
"ejson", | |
"follower-livedata", | |
"livedata", | |
"logging", | |
"mongo-livedata", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "audit-argument-checks", | |
"summary": "Try to detect inadequate input sanitization", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "autopublish", | |
"summary": "Publish the entire database to all clients", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "autoupdate", | |
"summary": "Update the client when new client code is available", | |
"require": [], | |
"use": [ | |
"deps", | |
"livedata", | |
"mongo-livedata", | |
"reload", | |
"retry", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "backbone", | |
"summary": "A minimalist client-side MVC framework", | |
"require": [], | |
"use": [ | |
"jquery", | |
"json", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "binary-heap", | |
"summary": "Binary Heap datastructure implementation", | |
"require": [], | |
"use": [ | |
"id-map", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "bootstrap", | |
"summary": "Front-end framework from Twitter", | |
"require": [ | |
"path" | |
], | |
"use": [ | |
"jquery" | |
] | |
}, | |
{ | |
"name": "browser-policy", | |
"summary": "Configure security policies enforced by the browser", | |
"require": [], | |
"use": [ | |
"browser-policy-content", | |
"browser-policy-framing", | |
"ejson", | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "browser-policy-common", | |
"summary": "Common code for browser-policy packages", | |
"require": [], | |
"use": [ | |
"webapp" | |
] | |
}, | |
{ | |
"name": "browser-policy-content", | |
"summary": "Configure content security policies", | |
"require": [], | |
"use": [ | |
"browser-policy-common", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "browser-policy-framing", | |
"summary": "Restrict which websites can frame your app", | |
"require": [], | |
"use": [ | |
"browser-policy-common", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "callback-hook", | |
"summary": "Register callbacks on a hook", | |
"require": [], | |
"use": [ | |
"underscore" | |
] | |
}, | |
{ | |
"name": "check", | |
"summary": "Check whether a value matches a pattern", | |
"require": [], | |
"use": [ | |
"ejson", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "code-prettify", | |
"summary": "Syntax highlighting of code, from Google", | |
"require": [ | |
"path" | |
], | |
"use": [] | |
}, | |
{ | |
"name": "coffeescript", | |
"summary": "Javascript dialect with fewer braces and semicolons", | |
"require": [], | |
"use": [ | |
"coffeescript-test-helper", | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "coffeescript-test-helper", | |
"summary": "Used by the coffeescript package's tests", | |
"require": [], | |
"use": [ | |
"coffeescript" | |
] | |
}, | |
{ | |
"name": "ctl", | |
"summary": "Default control program for an application", | |
"require": [], | |
"use": [ | |
"application-configuration", | |
"ctl-helper", | |
"follower-livedata", | |
"livedata", | |
"mongo-livedata", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "ctl-helper", | |
"summary": "Helpers for control programs", | |
"require": [], | |
"use": [ | |
"application-configuration", | |
"follower-livedata", | |
"livedata", | |
"logging", | |
"mongo-livedata", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "d3", | |
"summary": "Library for manipulating documents based on data", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "deps", | |
"summary": "Dependency mananger to allow reactive callbacks", | |
"require": [], | |
"use": [ | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "dev-bundle-fetcher", | |
"summary": "A shell script for downloading the Meteor dev bundle", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "disable-oplog", | |
"summary": "Disables oplog tailing", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "ejson", | |
"summary": "Extended and Extensible JSON library", | |
"require": [], | |
"use": [ | |
"json", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "email", | |
"summary": "Send email messages", | |
"require": [], | |
"use": [ | |
"application-configuration", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "facebook", | |
"summary": "Facebook OAuth flow", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth2", | |
"random", | |
"service-configuration", | |
"templating", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "facts", | |
"summary": "Publish internal app statistics", | |
"require": [], | |
"use": [ | |
"autopublish", | |
"livedata", | |
"mongo-livedata", | |
"templating", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "follower-livedata", | |
"summary": "Maintain a connection to the leader of an election set", | |
"require": [], | |
"use": [ | |
"ejson", | |
"livedata", | |
"logging", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "force-ssl", | |
"summary": "Require this application to use HTTPS", | |
"require": [], | |
"use": [ | |
"livedata", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "geojson-utils", | |
"summary": "GeoJSON utility functions (from https://github.com/maxogden/geojson-js-utils)", | |
"require": [], | |
"use": [ | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "github", | |
"summary": "Github OAuth flow", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth2", | |
"random", | |
"service-configuration", | |
"templating", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "google", | |
"summary": "Google OAuth flow", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth2", | |
"random", | |
"service-configuration", | |
"templating", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "handlebars", | |
"summary": "Deprecated", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "html-tools", | |
"summary": "Standards-compliant HTML tools", | |
"require": [], | |
"use": [ | |
"htmljs", | |
"spacebars-compiler", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "htmljs", | |
"summary": "Small library for expressing HTML trees", | |
"require": [], | |
"use": [ | |
"html-tools", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "http", | |
"summary": "Make HTTP calls to remote servers", | |
"require": [], | |
"use": [ | |
"jquery", | |
"random", | |
"test-helpers", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "id-map", | |
"summary": "Dictionary data structure allowing non-string keys", | |
"require": [], | |
"use": [ | |
"ejson", | |
"json", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "insecure", | |
"summary": "Allow all database writes by default", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "jquery", | |
"summary": "Manipulate the DOM using CSS selectors", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "jquery-history", | |
"summary": "pushState module from the jQuery project", | |
"require": [], | |
"use": [ | |
"jquery", | |
"json" | |
] | |
}, | |
{ | |
"name": "jquery-layout", | |
"summary": "Easily create arbitrary multicolumn layouts", | |
"require": [], | |
"use": [ | |
"jquery" | |
] | |
}, | |
{ | |
"name": "jquery-waypoints", | |
"summary": "Run a function when the user scrolls past an element", | |
"require": [], | |
"use": [ | |
"coffeescript", | |
"jquery" | |
] | |
}, | |
{ | |
"name": "js-analyze", | |
"summary": "JavaScript code analysis for Meteor", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "js-analyze-tests", | |
"summary": "Tests for JavaScript code analysis for Meteor", | |
"require": [], | |
"use": [ | |
"js-analyze", | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "json", | |
"summary": "Provides JSON.stringify and JSON.parse for older browsers", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "jsparse", | |
"summary": "Full-featured JavaScript parser", | |
"require": [], | |
"use": [ | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "less", | |
"summary": "The dynamic stylesheet language", | |
"require": [], | |
"use": [ | |
"templating", | |
"test-helpers", | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "livedata", | |
"summary": "Meteor's latency-compensated distributed data framework", | |
"require": [], | |
"use": [ | |
"audit-argument-checks", | |
"autopublish", | |
"callback-hook", | |
"check", | |
"deps", | |
"ejson", | |
"facts", | |
"http", | |
"json", | |
"logging", | |
"minimongo", | |
"mongo-livedata", | |
"random", | |
"reload", | |
"retry", | |
"routepolicy", | |
"test-helpers", | |
"tinytest", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "localstorage", | |
"summary": "Simulates local storage on IE 6,7 using userData", | |
"require": [], | |
"use": [ | |
"random", | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "logging", | |
"summary": "Logging facility.", | |
"require": [], | |
"use": [ | |
"ejson", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "meetup", | |
"summary": "Meetup OAuth flow", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth2", | |
"random", | |
"service-configuration", | |
"templating", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "meteor", | |
"summary": "Core Meteor environment", | |
"require": [], | |
"use": [ | |
"test-helpers", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "meteor-developer", | |
"summary": "Meteor developer accounts OAuth flow", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth2", | |
"random", | |
"service-configuration", | |
"templating", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "meyerweb-reset", | |
"summary": "reset.css v2.0 from http://meyerweb.com/eric/tools/css/reset/", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "minifiers", | |
"summary": "JavaScript and CSS minifiers", | |
"require": [], | |
"use": [ | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "minimongo", | |
"summary": "Meteor's client-side datastore: a port of MongoDB to Javascript", | |
"require": [], | |
"use": [ | |
"deps", | |
"ejson", | |
"geojson-utils", | |
"id-map", | |
"json", | |
"ordered-dict", | |
"random", | |
"test-helpers", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "mongo-livedata", | |
"summary": "Adaptor for using MongoDB and Minimongo over DDP", | |
"require": [], | |
"use": [ | |
"application-configuration", | |
"autopublish", | |
"binary-heap", | |
"callback-hook", | |
"check", | |
"deps", | |
"disable-oplog", | |
"ejson", | |
"facts", | |
"insecure", | |
"json", | |
"livedata", | |
"logging", | |
"minimongo", | |
"random", | |
"test-helpers", | |
"tinytest", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "oauth", | |
"summary": "Common code for OAuth-based services", | |
"require": [], | |
"use": [ | |
"logging", | |
"mongo-livedata", | |
"oauth-encryption", | |
"random", | |
"routepolicy", | |
"service-configuration", | |
"tinytest", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "oauth-encryption", | |
"summary": "Encrypt account secrets stored in the database", | |
"require": [], | |
"use": [ | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "oauth1", | |
"summary": "Common code for OAuth1-based login services", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth-encryption", | |
"random", | |
"service-configuration", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "oauth2", | |
"summary": "Common code for OAuth2-based login services", | |
"require": [], | |
"use": [ | |
"oauth", | |
"oauth-encryption", | |
"random", | |
"service-configuration", | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "observe-sequence", | |
"summary": "Observe changes to various sequence types such as arrays, cursors and objects", | |
"require": [], | |
"use": [ | |
"deps", | |
"ejson", | |
"minimongo", | |
"random", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "ordered-dict", | |
"summary": "Ordered traversable dictionary with a mutable ordering", | |
"require": [], | |
"use": [ | |
"underscore" | |
] | |
}, | |
{ | |
"name": "preserve-inputs", | |
"summary": "Deprecated package (now empty)", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "random", | |
"summary": "Random number generator and utilities", | |
"require": [], | |
"use": [ | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "reactive-dict", | |
"summary": "Reactive dictionary", | |
"require": [], | |
"use": [ | |
"deps", | |
"ejson", | |
"mongo-livedata", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "reload", | |
"summary": "Reload the page while preserving application state.", | |
"require": [], | |
"use": [ | |
"json", | |
"logging", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "retry", | |
"summary": "Retry logic with exponential backoff", | |
"require": [], | |
"use": [ | |
"random", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "routepolicy", | |
"summary": "route policy declarations", | |
"require": [], | |
"use": [ | |
"tinytest", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "service-configuration", | |
"summary": "Manage the configuration for third-party services", | |
"require": [], | |
"use": [ | |
"accounts-base", | |
"mongo-livedata" | |
] | |
}, | |
{ | |
"name": "session", | |
"summary": "Session variable", | |
"require": [], | |
"use": [ | |
"deps", | |
"ejson", | |
"mongo-livedata", | |
"reactive-dict", | |
"reload", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "showdown", | |
"summary": "Markdown-to-HTML processor", | |
"require": [], | |
"use": [ | |
"ui" | |
] | |
}, | |
{ | |
"name": "spacebars", | |
"summary": "Handlebars-like template language for Meteor", | |
"require": [], | |
"use": [ | |
"htmljs", | |
"spacebars-common", | |
"templating", | |
"test-helpers", | |
"tinytest", | |
"ui" | |
] | |
}, | |
{ | |
"name": "spacebars-common", | |
"summary": "Common code for spacebars and spacebars-compiler", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "spacebars-compiler", | |
"summary": "Compiler for Spacebars template language", | |
"require": [], | |
"use": [ | |
"html-tools", | |
"minifiers", | |
"spacebars-common", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "spacebars-tests", | |
"summary": "Additional tests for Spacebars", | |
"require": [], | |
"use": [ | |
"jquery", | |
"showdown", | |
"spacebars", | |
"templating", | |
"test-helpers", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "spiderable", | |
"summary": "Makes the application crawlable to web spiders", | |
"require": [], | |
"use": [ | |
"templating", | |
"tinytest", | |
"underscore", | |
"webapp" | |
] | |
}, | |
{ | |
"name": "srp", | |
"summary": "Library for Secure Remote Password (SRP) exchanges", | |
"require": [], | |
"use": [ | |
"check", | |
"random", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "standard-app-packages", | |
"summary": "Include a standard set of Meteor packages in your app", | |
"require": [], | |
"use": [ | |
"autoupdate", | |
"reload" | |
] | |
}, | |
{ | |
"name": "star-translate", | |
"summary": "A package for translating old bundles into stars", | |
"require": [], | |
"use": [ | |
"dev-bundle-fetcher" | |
] | |
}, | |
{ | |
"name": "startup", | |
"summary": "Deprecated package (now empty)", | |
"require": [], | |
"use": [] | |
}, | |
{ | |
"name": "stylus", | |
"summary": "Expressive, dynamic, robust CSS", | |
"require": [], | |
"use": [ | |
"templating", | |
"test-helpers", | |
"tinytest" | |
] | |
}, | |
{ | |
"name": "templating", | |
"summary": "Allows templates to be defined in .html files", | |
"require": [], | |
"use": [ | |
"deps", | |
"htmljs", | |
"minimongo", | |
"session", | |
"spacebars-compiler", | |
"test-helpers", | |
"tinytest", | |
"ui", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "test-helpers", | |
"summary": "Utility functions for tests", | |
"require": [], | |
"use": [ | |
"deps", | |
"ejson", | |
"jquery", | |
"livedata", | |
"random", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "test-in-browser", | |
"summary": "Run tests interactively in the browser", | |
"require": [], | |
"use": [ | |
"autoupdate", | |
"bootstrap", | |
"deps", | |
"livedata", | |
"random", | |
"reload", | |
"session", | |
"spacebars", | |
"templating", | |
"tinytest", | |
"ui", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "test-in-console", | |
"summary": "Run tests noninteractively, with results going to the console.", | |
"require": [], | |
"use": [ | |
"check", | |
"ejson", | |
"http", | |
"random", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "tinytest", | |
"summary": "Tiny testing framework", | |
"require": [], | |
"use": [ | |
"check", | |
"livedata", | |
"mongo-livedata", | |
"random", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "twitter", | |
"summary": "Twitter OAuth flow", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth1", | |
"random", | |
"service-configuration", | |
"templating", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "ui", | |
"summary": "Meteor UI Components framework", | |
"require": [], | |
"use": [ | |
"deps", | |
"ejson", | |
"html-tools", | |
"htmljs", | |
"jquery", | |
"minimongo", | |
"observe-sequence", | |
"ordered-dict", | |
"random", | |
"spacebars-compiler", | |
"test-helpers", | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "underscore", | |
"summary": "Collection of small helpers: _.map, _.each, ...", | |
"require": [], | |
"use": [ | |
"meteor" | |
] | |
}, | |
{ | |
"name": "underscore-tests", | |
"summary": "Tests for the underscore package", | |
"require": [], | |
"use": [ | |
"tinytest", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "webapp", | |
"summary": "Serves a Meteor app over HTTP", | |
"require": [], | |
"use": [ | |
"application-configuration", | |
"follower-livedata", | |
"htmljs", | |
"http", | |
"logging", | |
"routepolicy", | |
"spacebars", | |
"spacebars-compiler", | |
"tinytest", | |
"ui", | |
"underscore" | |
] | |
}, | |
{ | |
"name": "weibo", | |
"summary": "Weibo OAuth flow", | |
"require": [], | |
"use": [ | |
"http", | |
"oauth", | |
"oauth2", | |
"random", | |
"service-configuration", | |
"templating" | |
] | |
} | |
]</script> | |
<script> | |
var expanded = []; | |
var display = document.getElementById('display'); | |
var search = document.getElementById('search'); | |
var raw = JSON.parse(document.getElementById('data').textContent); | |
var byName = {}; | |
raw.forEach(function (node) { | |
byName[node.name] = node; | |
}); | |
search.value = decodeURIComponent(location.hash).substring(1); | |
function filter(raw) { | |
return raw.filter(function (node) { | |
if (search.value.trim() === '') return true; | |
return search.value.split(' ').filter(function (name) { | |
return name.trim() !== ''; | |
}).some(function (searchTerm) { | |
return node.name.indexOf(searchTerm) !== -1; | |
}) | |
}); | |
} | |
function render() { | |
location.hash = encodeURIComponent(search.value); | |
display.innerHTML = renderCollection(filter(raw), ''); | |
} | |
function renderCollection(data, path) { | |
return '<ul class="list-group">' + data.map(function (node) { | |
var p = path + node.name; | |
var isCircular = path.indexOf(node.name + '.') === 0 || path.indexOf('.' + node.name + '.') !== -1; | |
var isExpandable = node.use.length > 0 && !isCircular; | |
var isExpanded = expanded.indexOf(p) !== -1; | |
var open = '<li class="list-group-item">'; | |
var badge = !isExpanded && isExpandable ? | |
'<span class="badge pull-right">' + node.use.length + '</span>' : | |
isCircular ? '<span class="label label-danger pull-right">circular</span>' : ''; | |
var name = '<p class="lead">' + node.name + '</p>'; | |
var summary = '<p>' + node.summary + '</p>'; | |
var button = '<button data-name="' + p + '"type="button" class="btn-clear">' + badge + name + summary + '</button>'; | |
var children = isExpanded && isExpandable ? renderCollection(node.use.map(function (name) { | |
return byName[name]; | |
}), p + '.') : ''; | |
var close = '</li>'; | |
if (!isExpandable) return open + badge + name + summary + close; | |
return open + button + children + close; | |
}).join('') + '</ul>'; | |
} | |
render(); | |
search.addEventListener('keyup', render, false); | |
search.addEventListener('change', render, false); | |
display.addEventListener('click', function (e) { | |
var target = e.target; | |
while (target && target.hasAttribute && !target.hasAttribute('data-name')) { | |
target = target.parentNode; | |
} | |
if (!(target && target.hasAttribute)) return; | |
var name = target.getAttribute('data-name'); | |
var i = expanded.indexOf(name); | |
if (i === -1) { | |
expanded.push(name); | |
} else { | |
expanded.splice(i, 1); | |
} | |
render(); | |
}) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment