From 875a56662395648c6af1bdfa4a0b6caaba697b0a Mon Sep 17 00:00:00 2001 From: Benjamin Pannell Date: Thu, 21 Nov 2013 04:06:44 +0200 Subject: [PATCH] Initial code commit --- .gitattributes | 22 ++ .gitignore | 7 + Iridium.csproj | 155 ++++++++++ Iridium.sln | 22 ++ README.md | 81 +++++ example/User.js | 171 +++++++++++ index.js | 5 + lib/Database.js | 131 ++++++++ lib/Instance.js | 284 +++++++++++++++++ lib/Model.js | 289 ++++++++++++++++++ lib/utils/String.js | 147 +++++++++ lib/utils/transforms.js | 43 +++ lib/utils/validation.js | 121 ++++++++ nodelib/assert.js | 93 ++++++ nodelib/buffer.js | 440 ++++++++++++++++++++++++++ nodelib/child_process.js | 91 ++++++ nodelib/cluster.js | 243 +++++++++++++++ nodelib/console.js | 69 +++++ nodelib/core.js | 17 ++ nodelib/crypto.js | 389 +++++++++++++++++++++++ nodelib/dgram.js | 179 +++++++++++ nodelib/dns.js | 126 ++++++++ nodelib/domain.js | 91 ++++++ nodelib/events.js | 70 +++++ nodelib/fs.js | 611 +++++++++++++++++++++++++++++++++++++ nodelib/http.js | 338 ++++++++++++++++++++ nodelib/https.js | 49 +++ nodelib/lodash.js | 4 + nodelib/mocha.js | 43 +++ nodelib/module.js | 14 + nodelib/net.js | 266 ++++++++++++++++ nodelib/node.js | 94 ++++++ nodelib/os.js | 76 +++++ nodelib/path.js | 101 ++++++ nodelib/process.js | 186 +++++++++++ nodelib/punycode.js | 62 ++++ nodelib/querystring.js | 40 +++ nodelib/readline.js | 82 +++++ nodelib/repl.js | 77 +++++ nodelib/should.js | 4 + nodelib/stream.js | 123 ++++++++ nodelib/stringdecoder.js | 17 ++ nodelib/superagent.js | 4 + nodelib/supertest.js | 5 + nodelib/tls.js | 172 +++++++++++ nodelib/tty.js | 59 ++++ nodelib/url.js | 32 ++ nodelib/util.js | 110 +++++++ nodelib/vm.js | 84 +++++ nodelib/zlib.js | 135 ++++++++ package.json | 28 ++ tests/.gitignore | 1 + tests/common.js | 42 +++ tests/config.example.js | 8 + tests/integration/orm.js | 143 +++++++++ tests/integration/utils.js | 130 ++++++++ tests/logging.js | 29 ++ tests/run.js | 30 ++ tests/run.sh | 18 ++ 59 files changed, 6503 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 Iridium.csproj create mode 100644 Iridium.sln create mode 100644 README.md create mode 100644 example/User.js create mode 100644 index.js create mode 100644 lib/Database.js create mode 100644 lib/Instance.js create mode 100644 lib/Model.js create mode 100644 lib/utils/String.js create mode 100644 lib/utils/transforms.js create mode 100644 lib/utils/validation.js create mode 100644 nodelib/assert.js create mode 100644 nodelib/buffer.js create mode 100644 nodelib/child_process.js create mode 100644 nodelib/cluster.js create mode 100644 nodelib/console.js create mode 100644 nodelib/core.js create mode 100644 nodelib/crypto.js create mode 100644 nodelib/dgram.js create mode 100644 nodelib/dns.js create mode 100644 nodelib/domain.js create mode 100644 nodelib/events.js create mode 100644 nodelib/fs.js create mode 100644 nodelib/http.js create mode 100644 nodelib/https.js create mode 100644 nodelib/lodash.js create mode 100644 nodelib/mocha.js create mode 100644 nodelib/module.js create mode 100644 nodelib/net.js create mode 100644 nodelib/node.js create mode 100644 nodelib/os.js create mode 100644 nodelib/path.js create mode 100644 nodelib/process.js create mode 100644 nodelib/punycode.js create mode 100644 nodelib/querystring.js create mode 100644 nodelib/readline.js create mode 100644 nodelib/repl.js create mode 100644 nodelib/should.js create mode 100644 nodelib/stream.js create mode 100644 nodelib/stringdecoder.js create mode 100644 nodelib/superagent.js create mode 100644 nodelib/supertest.js create mode 100644 nodelib/tls.js create mode 100644 nodelib/tty.js create mode 100644 nodelib/url.js create mode 100644 nodelib/util.js create mode 100644 nodelib/vm.js create mode 100644 nodelib/zlib.js create mode 100644 package.json create mode 100644 tests/.gitignore create mode 100644 tests/common.js create mode 100644 tests/config.example.js create mode 100644 tests/integration/orm.js create mode 100644 tests/integration/utils.js create mode 100644 tests/logging.js create mode 100644 tests/run.js create mode 100644 tests/run.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..412eeda --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp +*.sln merge=union +*.csproj merge=union +*.vbproj merge=union +*.fsproj merge=union +*.dbproj merge=union + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b3fa805 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +Properties +bin +obj +*.suo +*.user +*.sublime* +node_modules \ No newline at end of file diff --git a/Iridium.csproj b/Iridium.csproj new file mode 100644 index 0000000..f2cf381 --- /dev/null +++ b/Iridium.csproj @@ -0,0 +1,155 @@ + + + + + Debug + AnyCPU + + + 2.0 + {A937B8F5-CB90-46AD-AB3C-1EBD8E827378} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + Iridium + Iridium + v4.5 + true + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + True + 64607 + / + http://localhost:64607/ + False + False + + + False + + + + + + \ No newline at end of file diff --git a/Iridium.sln b/Iridium.sln new file mode 100644 index 0000000..35d73e4 --- /dev/null +++ b/Iridium.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Iridium", "Iridium.csproj", "{A937B8F5-CB90-46AD-AB3C-1EBD8E827378}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {A937B8F5-CB90-46AD-AB3C-1EBD8E827378}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A937B8F5-CB90-46AD-AB3C-1EBD8E827378}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A937B8F5-CB90-46AD-AB3C-1EBD8E827378}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A937B8F5-CB90-46AD-AB3C-1EBD8E827378}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md new file mode 100644 index 0000000..107d0dc --- /dev/null +++ b/README.md @@ -0,0 +1,81 @@ +# Iridium - A bare metal ORM for MongoDB +Iridium was designed to alleviate many of the issues often present in modern ORMs, especially those designed for NoSQL datastores like MongoDB. Namely, these include a high level of bloat and an excessive amount of documentation - vastly raising the barrier to entry. On the flip side of the coin, they also tend to abstract core database functionality away from the developer to the extent that they end up jumping through unnecessary hoops just to get the results they're looking for. + +Iridium hopes to solve these issues by providing a bare bones ORM targeted at power users, and those looking for an exceptionally low overhead. It provides much of the indispensable functionality found in ORMs without the fluff. + +## Features + - **Flexible Schema Validation** + MongoDB's greatest strength is its ability to support dynamic schemas, we think that's a great idea but sometimes it's necessary to be able to validate aspects of your models. That's where Iridium's validation framework comes in - with an intuitive schema design framework with support for optional and dynamic fields, you'll never find yourself stuck again. + - **Powerful Transforms** + Anyone familiar with MongoDB knows the headaches that ObjectID causes due to its custom datatype. We also know that sometimes custom datatypes are unavoidable, or preferable for storage - though not necessarily ideal for processing. Iridium allows you to define a set of up-down transforms which are applied to parts of your model so that your code doesn't need to worry about these inconsistencies, and you can get down to writing the code you want to. + - **IntelliSense Support** + We understand the value of an easy to use library, and having to go *documentation diving* every time you want to find out how to use a function is a pain we're all to familiar with. Iridium was designed from the ground up to include support for Visual Studio's IntelliSense engine - reducing the number of round trips between documentation and your code. + - **Express Support** + Everyone who has written code using Node.js knows about Express, to help make your life easier we've included support right out of the box for Express. + - **Powerful Models** + Iridium's models are designed to exist as individual files or modules within your application, this helps simplify management of your models and separates database design code from your application code. In addition to this, Iridium supports virtual properties, extension methods, transforms, client side property renaming and validations in an easy to understand and implement package. + +## Example +```js +var iridium = require('iridium'); + +var database = new iridium({ + database: 'demo' +}); + +database.register('User', new iridium.Model('user', { + firstname: String, + lastname: String, + since: Date, + clown: Boolean, + houses: [{ + address: String, + colour: /Red|White|Blue|Green|Pink/ + }] +})); + +database.connect(function(err, db) { + if(err) throw err; + + // at this point database == db + + db.User.create({ + firstname: 'Billy', + lastname: 'Bob', + since: new Date(), + clown: true, + houses: [ + { address: 'The middle of nowhere', colour: 'Red' } + ] + }, function(err, user) { + if(err) throw err; + + console.log(JSON.stringify(user)); + }); +}); + +``` + +## Core +The Iridium core (that sounds WAY cooler than I intended when I came up with the name) is where you create a database connection and register any models to be used by the database. Registration of models is optional, however it makes accessing them easier. + +When using Iridium, you are required to instantiate a core with a settings object which describes the database server you want to connect to. This is done by calling the core's constructor and passing an object similar to the following. + +```js +{ + host: 'localhost', // Optional + port: 27018, // Optional + username: '', // Optional + password: '', // Optional + database: 'iridium' +} +``` + +Once you've got a core, you need to connect it to the database. This is done by calling the core's *connect* method and giving it a callback function. +TODO + +## Models +TODO + +## Instances +TODO \ No newline at end of file diff --git a/example/User.js b/example/User.js new file mode 100644 index 0000000..ff163eb --- /dev/null +++ b/example/User.js @@ -0,0 +1,171 @@ +/// +/// +/// +/// + +var _ = require('lodash'); +var Database = require('iridium'); +var Model = Database.Model; + +(require.modules || {}).User = module.exports = function (db) { + /// Configure the User model to use the given database + /// The database connection to use + /// + + "use strict"; + var database = db; + + var options = { + rename: { + '_id': 'username' + }, + virtuals: { + API: function () { + var $ = this; + + return { + username: $.username, + fullname: $.fullname, + email: $.email, + banned: $.banned, + statistics: $.statistics, + skill: { + level: $.skill.level, + xp: $.skill.xp + }, + friends: $.friends, + pending_messages: $.pending_messages, + last_seen: $.last_seen + }; + } + }, + methods: { + setPassword: function (newPassword, callback) { + /// Updates the user's stored password hash + /// The new password to use for the user + /// A function to be called once the user's password has been updated + + var passwordTest = /(?=^.{8,}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*/; + if (!passwordTest.test(newPassword || '')) return callback(new Error('Password didn\'t meet the minimum safe password requirements. Passwords should be at least 8 characters long, and contain at least 3 of the following categories: lowercase letters, uppercase letters, numbers, characters')); + + var hashed = require('crypto').createHash('sha512').update(database.settings.security.salt).update(newPassword).digest('hex'); + this.password = hashed; + this.save(callback); + }, + checkPassword: function (password) { + /// Checks whether a given password is correct for a user's account + /// The password to validate against the user's password hash. + /// + + var hashed = require('crypto').createHash('sha512').update(database.settings.security.salt).update(password).digest('hex'); + return hashed == this.password; + }, + addFriend: function (friend, callback) { + this.save({ $push: { friends: friend } }, callback); + }, + updateLevel: function () { + /// Update's the user's current level based on the amount of XP they have. Doesn't save the user instance. + + // Amount of XP required per level starts at 1200, doubles for each consecutive level + // tf. XP_n = XP_nm1 + 1200 * 2^n + + var remainingXP = this.skill.xp; + + var previousLevelXP = 0; + var levelXP = 1200; + var level = 0; + + for(; remainingXP >= levelXP; level++, previousLevelXP = levelXP, remainingXP -= levelXP, levelXP += 1200 * Math.pow(2, level)); + + this.skill.level = level; + this.skill.current_level = previousLevelXP; + this.skill.next_level = levelXP; + } + }, + hooks: { + beforeCreate: function (done) { + var item = this; + + item._id = item.username; + if (item.username) delete item.username; + + var passwordTest = /(?=^.{8,}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*/; + + if (!passwordTest.test(item.password || '')) return done('Password didn\'t meet the minimum safe password requirements. Passwords should be at least 8 characters long, and contain at least 3 of the following categories: lowercase letters, uppercase letters, numbers, characters'); + + item.password = require('crypto').createHash('sha512').update(database.settings.security.salt).update(item.password).digest('hex'); + + _.defaults(item, { + type: "Player", + banned: false, + statistics: { + won: 0, + drawn: 0, + lost: 0, + incomplete: 0 + }, + skill: { + matchmaking: 0, + trend: 0, + level: 0, + xp: 0, + current_level: 0, + next_level: 1200 + }, + friends: [], + friend_requests: [], + pending_messages: [], + sessions: [], + last_seen: new Date() + }); + + done(); + } + }, + transforms: { + _id: false + }, + indexes: [ + [{ email: 1 }, { unique: true, background: true }], + [{ type: 1 }, { background: true }], + [{ sessions: 1 }, { sparse: true, background: true }], + [{ 'skill.xp': -1 }, { background: true }] + ] + }; + + var schema = { + _id: /[a-z0-9]+(_[a-z0-9]+)*/, + fullname: String, + email: String, + password: String, + type: /Player|Moderator|Admin/, + banned: Boolean, + statistics: { + won: Number, + drawn: Number, + lost: Number, + incomplete: Number + }, + skill: { + matchmaking: Number, + trend: Number, + level: Number, + xp: Number, + current_level: Number, + next_level: Number + }, + friends: [String], + pending_messages: [{ + from: String, + time: Date, + message: String, + group: { $type: String, $required: false }, + game: { $type: String, $required: false } + }], + sessions: [String], + friend_requests: [String], + last_seen: Date + }; + + return new Model(db, 'user', schema, options); +}; diff --git a/index.js b/index.js new file mode 100644 index 0000000..09957e5 --- /dev/null +++ b/index.js @@ -0,0 +1,5 @@ +/// +/// +var Database = require('./lib/Database'); + +(require.modules || {}).iridium = (require.modules || {}).index = module.exports = Database; \ No newline at end of file diff --git a/lib/Database.js b/lib/Database.js new file mode 100644 index 0000000..e8ce161 --- /dev/null +++ b/lib/Database.js @@ -0,0 +1,131 @@ +/// +/// +/// + +var MongoClient = require('mongodb').MongoClient; +var Model = require('./Model'); +var Instance = require('./Instance'); + +(require.modules || {}).Database = module.exports = Database; + +function Database(config) { + /// Creates a new Iridium instance + /// A configuration object describing the details of the database to connect to + + this.connection = null; + this.models = {}; + + Object.defineProperty(this, 'settings', { + get: function () { + "use strict"; + return config; + }, + enumerable: false + }); +} + +Database.Model = Model; +Database.Instance = Instance; + +Database.prototype.connect = function (cb) { + /// Connects to the database server specified in the provided configuration + /// A function to be called when the connection is completed, called immediately if one is already open + + if (this.connection) return cb(null, this.connection); + + var $ = this; + + MongoClient.connect(this.connect_url, function (err, db) { + /// + /// + + if (err) { + err.message = 'Failed to establish connection to database server. Please ensure that the server is accessible.'; + return cb(err); + } + + $.connection = db; + + cb(null, $); + }); +}; + +Database.prototype.express = function (config) { + /// Creates an Express Middleware which will make this database wrapper avaiable through the req.db property + /// A configuration object, generally loaded from settings.js + + "use strict"; + + var $ = this; + + return function (req, res, next) { + /// Express Middleware which will make this database wrapper available through the req.db property + /// Node Request object + /// Node Response object + /// Callback used to continue to the next step in the Express request pipeline + + $.connect(config, function (err, _db) { + if (err) return next(err); + req.db = _db; + return next(); + }); + }; +}; + +Database.prototype.register = function (name, model) { + /// + /// Registers a model with the ORM (not entirely necessary) + /// The name of the model to register with the current connection + /// The model to register with the database connection + /// + /// + /// Registers a model with the ORM (not entirely necessary) + /// The name of the model to register with the ORM + /// A function which creates a model for a given database connection + /// + "use strict"; + + var $ = this; + + if (model.isModel) + this.models[name] = model; + else this.models[name] = model(this); + + Object.defineProperty($, name, { + get: function () { + /// + return $.models[name]; + }, + enumerable: true + }); +}; + +Object.defineProperty(Database.prototype, 'connect_url', { + get: function () { + /// Gets a URL which can be used to connec to a MongoDB instance based on the configuration + /// + + "use strict"; + var uri = 'mongodb://'; + if (this.settings.username && this.settings.password) + uri += this.settings.username + ':' + this.settings.password + '@'; + uri += this.settings.host || 'localhost'; + if (this.settings.port) + uri += ':' + this.settings.port; + uri += '/' + this.settings.database; + + return uri; + }, + enumerable: false +}); + +Object.defineProperty(Database.prototype, 'db', { + get: function () { + /// Gets the MongoDB database connection + + "use strict"; + if (!this.connection) throw new Error('Database connection not yet established'); + return this.connection; + }, + enumerable: false +}); diff --git a/lib/Instance.js b/lib/Instance.js new file mode 100644 index 0000000..c7b4748 --- /dev/null +++ b/lib/Instance.js @@ -0,0 +1,284 @@ +/// +/// +/// + +var ObjectID = require('mongodb').ObjectID; +var _ = require('lodash'); +var validate = require('./utils/validation'); +var transform = require('./utils/transforms'); + + +(require.modules || {}).Instance = module.exports = Instance; + +function Instance(collection, doc, options, isNew) { + /// + /// Creates a new wrapper around a database document + /// The database collection from which the document originated + /// The document from the database which is to be wrapped + /// Additional options used to determine how the instance is handled + /// + /// + /// Creates a new wrapper around a database document + /// The database collection from which the document originated + /// The document from the database which is to be wrapped + /// Additional options used to determine how the instance is handled + /// The document's unique database identifier field + + return oldDoc._id; + }, + enumerable: true + }); + + var schema = {}; + for (k in doc) { + schema[k] = false; + } + for (k in options.schema) { + schema[k] = options.schema[k]; + } + + for (k in schema) { + + var targetProperty = k; + if (options.rename && options.rename[k]) + targetProperty = options.rename[k]; + + if (targetProperty === '_id' || targetProperty === "id") continue; + + (function (sourceProperty) { + if (k === '_id') + Object.defineProperty($, targetProperty, { + get: function () { + return newDoc[sourceProperty]; + }, + enumerable: true + }); + + else + Object.defineProperty($, targetProperty, { + get: function () { + /// Get the most recent value for this field + + return newDoc[sourceProperty] === undefined ? null : newDoc[sourceProperty]; + }, + set: function (value) { + /// Set the value of this field. Changes may be committed by calling save() on this instance. + + var validation = validate(options.schema[sourceProperty], value, sourceProperty); + + if (!validation.passed) throw validation.toError(); + + newDoc[sourceProperty] = value; + }, + enumerable: true + }); + })(k); + } + + for (k in options.methods) { + (function (sourceProperty) { + Object.defineProperty($, k, { + value: function () { + return options.methods[sourceProperty].apply($, arguments); + } + }); + })(k); + } + + for (k in options.virtuals) { + (function (sourceProperty) { + Object.defineProperty($, k, { + get: function () { + return options.virtuals[sourceProperty].call($); + } + }); + })(k); + } + + Object.defineProperty($, 'save', { + value: function (changes, cb) { + /// + /// Saves changes made to the current instance to the database without waiting for a response + /// + /// + /// Saves changes made to the current instance to the database without waiting for a response + /// MongoDB changes query to be used instead of differential patching + /// + /// + /// Saves changes made to the current instance to the database + /// A function which is called when the save has been completed + /// + /// + /// Saves changes made to the current instance to the database + /// MongoDB changes query to be used instead of differential patching + /// A function which is called when the save has been completed + /// + + if (!cb && typeof changes === 'function') { + cb = changes; + changes = null; + } + + if (!cb) cb = function () { }; + + var createObject = function (callback) { + + var createDoc = _.cloneDeep(newDoc); + transform.up(options.transforms, createDoc); + + collection.insert(createDoc, { w: 1 }, function (err, inserted) { + if (err) return callback(err); + + inserted = inserted[0]; + transform.down(options.transforms, inserted); + + oldDoc = newDoc = inserted; + + isNew = false; + + return callback(null, $); + }); + }; + + if (!changes) { + var transformedOld = _.cloneDeep(oldDoc); + var transformedNew = _.cloneDeep(newDoc); + + transform.up(options.transforms, transformedOld); + transform.up(options.transforms, transformedNew); + + changes = diffPatch(transformedOld, transformedNew); + } + + if (!!isNew || Object.keys(changes).length > 0) { + var runOptions = function () { + + var conditions = { _id: $.id }; + + transform.up(options.transforms, conditions); + + collection.update(conditions, changes, { w: 1 }, function (err, updateCount) { + if (err) return cb(err); + + if (updateCount > 0) { + collection.findOne(conditions, function (err, updated) { + if (err) return cb(err); + + transform.down(options.transforms, updated); + + oldDoc = newDoc = updated; + return cb(null, $); + }); + } else return cb(null, $); + }); + }; + + if (oldDoc._id && !isNew) return runOptions(); + else createObject(function (err) { + if (err) return cb(err); + if (Object.keys(changes).length > 0) runOptions(cb); + else return cb(null, $); + }); + } + else return cb(null, $); + }, + enumerable: false + }); + + Object.defineProperty($, 'update', { + value: function (callback) { + /// Updates this object from the database, bringing it up to date + /// A function to be called once the update is complete + + var conditions = { _id: $.id }; + + transform.up(options.transforms, conditions); + + collection.findOne(conditions, function (err, updated) { + if (err) return cb(err); + + transform.down(options.transforms, updated); + + oldDoc = newDoc = updated; + return callback(null, $); + }); + } + }); + + Object.defineProperty($, 'remove', { + value: function (callback) { + /// Removes this object from the database collection + /// A function to be called when the object has been removed + + if (oldDoc._id) { + var conditions = { _id: $.id }; + + transform.up(options.transforms, conditions); + + collection.remove(conditions, callback); + } else { + callback(null, 0); // No objects removed from the database + } + }, + enumerable: false + }); +} + +var diffPatch = Instance.diff = function (oldDoc, newDoc, path) { + /// + /// Creates a differential update query for use by MongoDB + /// The original document prior to any changes + /// The document containing the changes made to the original document + /// + + "use strict"; + + var changes = {}; + + for (var k in newDoc) { + if (Array.isArray(newDoc[k]) && Array.isArray(oldDoc[k])) { + var different = newDoc.length !== oldDoc.length; + for (var i = 0; i < newDoc[k].length && !different; i++) { + if (oldDoc[k][i] !== newDoc[k][i]) different = true; + } + if (!different) continue; + changes.$set = changes.$set || {}; + changes.$set[(path ? (path + '.') : '') + k] = newDoc[k]; + } + else if (_.isPlainObject(newDoc[k]) && _.isPlainObject(oldDoc[k])) { + // Make recursive diff update + _.merge(changes, diffPatch(oldDoc[k], newDoc[k], (path ? (path + '.') : '') + k)); + } + else { + if (oldDoc[k] === newDoc[k]) continue; + changes.$set = changes.$set || {}; + changes.$set[(path ? (path + '.') : '') + k] = newDoc[k]; + } + } + + return changes; +}; \ No newline at end of file diff --git a/lib/Model.js b/lib/Model.js new file mode 100644 index 0000000..56d3f51 --- /dev/null +++ b/lib/Model.js @@ -0,0 +1,289 @@ +/// +/// +/// +/// + +var _ = require('lodash'); +var Instance = require('./Instance'); +var validate = require('./utils/validation'); +var transform = require('./utils/transforms'); +var ObjectID = require('mongodb').ObjectID; + + +(require.modules || {}).Model = module.exports = Model; + +function Model(database, collection, schema, options) { + /// Creates a new model around the specified database + /// The database wrapper on which this model will operate + /// The name of the database collection in which objects of this type are stored + /// A JSON representation of the database schema + /// Additional options configuring the behaviour of this model's instances + + if (!options) options = {}; + if (!options.hooks) options.hooks = {}; + + options.transforms = options.transforms || {}; + + _.defaults(options.transforms, { + _id: { + $down: function (value) { return new ObjectID(value.id).toHexString(); }, + $up: function (value) { return value ? ObjectID.createFromHexString(value) : undefined; } + } + }); + + options.schema = schema; + + + Object.defineProperty(this, 'collection', { + get: function () { return database.db.collection(collection); }, + enumerable: false + }); + + Object.defineProperty(this, 'options', { + get: function () { return options; }, + enumerable: false + }); + + Object.defineProperty(this, 'isModel', { + value: true, + enumerable: false + }); +} + +Model.prototype.wrap = function (document, isNew) { + /// + /// Wraps the given database object in this model's Instance wrapper + /// The database object to be wrapped by this model + /// + /// + /// + /// Wraps the given database object in this model's Instance wrapper + /// The database object to be wrapped by this model + /// Whether or not this instance is new (not in the database) + /// + /// + + return new Instance(this.collection, document, this.options, isNew); +}; + +Model.prototype.find = function (conditions, callback) { + /// + /// Gets all objects in the collection. + /// A function to be called with the results once they have been retrieved. + /// + /// + /// Finds all occurences in the collection with an _id field matching the given conditions. + /// The _id field of the object to locate + /// A function to be called with the results once they have been retrieved. + /// + /// + /// Finds all occurences in the collection which match the given conditions. + /// The conditions which will be used to select matches + /// A function to be called with the results once they have been retrieved. + /// + + if (!callback) { + callback = conditions; + conditions = {}; + } + + var $ = this; + if (!_.isPlainObject(conditions)) conditions = { _id: conditions }; + + transform.up(this.options.transforms, conditions); + + this.collection.find(conditions).toArray(function (err, results) { + if (err) return callback(err); + if (!results) return callback(null, null); + return callback(null, _.map(results, function (result) { return $.wrap(result, false); }, $)); + }); +}; + +Model.prototype.findOne = Model.prototype.get = function (conditions, callback) { + /// + /// Gets a single object from the collection. + /// A function to be called with the results once they have been retrieved. + /// + /// + /// Finds the first occurence in the collection with an _id field matching the given conditions. + /// The _id field of the object to locate + /// A function to be called with the results once they have been retrieved. + /// + /// + /// Finds the first occurence in the collection which matches the given conditions. + /// The conditions which will be used to select matches + /// A function to be called with the results once they have been retrieved. + /// + + if (!callback) { + callback = conditions; + conditions = {}; + } + + var $ = this; + if (!_.isPlainObject(conditions)) conditions = { _id: conditions }; + + transform.up(this.options.transforms, conditions); + + this.collection.findOne(conditions, function (err, results) { + if (err) return callback(err); + if (!results) return callback(null, null); + + return callback(null, $.wrap.call($, results)); + }); +}; + +Model.prototype.insert = Model.prototype.create = function (object, callback) { + /// Inserts the given object into the database + /// The properties to set on the newly created object + /// + + var $ = this; + + var doInsert = function(err) { + if(err) return callback(err); + + var validation = validate($.options.schema, object); + + if (!validation.passed) return callback(validation.toError()); + + var instance = $.wrap.call($, object, true); + instance.save(callback); + + $.setupIndexes(); + }; + + if (this.options.hooks.beforeCreate) { + if (this.options.hooks.beforeCreate.length === 0) this.options.hooks.beforeCreate.call(object); + else return this.options.hooks.beforeCreate.call(object, doInsert); + } + + doInsert(); +}; + +Model.prototype.update = function (conditions, changes, callback) { + /// + /// Updates all documents in the collection which match the specified conditions - making the requested changes + /// The conditions used to select objects to be updated + /// The changes to be made to objects in the collection + /// + /// + /// Updates all documents in the collection which match the specified conditions - making the requested changes + /// The conditions used to select objects to be updated + /// The changes to be made to objects in the collection + /// A function to be called once the update has completed + /// + + transform.up(this.options.transforms, conditions); + this.collection.update(conditions, changes, { w: callback ? 1 : 0, multi: true }, callback); +}; + +Model.prototype.count = function (conditions, callback) { + /// + /// Counts the number of documents in the collection + /// A function to be called once the documents have been counted. + /// + /// + /// Counts the number of documents in the collection which match the given conditions + /// The conditions on which to match documents for counting + /// A function to be called once the documents have been counted. + /// + + if (!callback) { + callback = conditions; + conditions = {}; + } + + transform.up(this.options.transforms, conditions); + + this.collection.count(conditions, callback); +}; + +Model.prototype.remove = function (conditions, callback) { + /// + /// Removes all objects in the collection. + /// A function to be called once all objects have been removed. + /// + /// + /// Removes all occurences in the collection with an _id field matching the given condition value. + /// The _id field of the object to locate + /// A function to be called once all objects have been removed. + /// + /// + /// Removes all occurences in the collection which match the given conditions. + /// The conditions which will be used to select matches + /// A function to be called once all objects have been removed. + /// + + if (!callback) { + callback = conditions; + conditions = {}; + } + + if (!_.isPlainObject(conditions)) conditions = { _id: conditions }; + + transform.up(this.options.transforms, conditions); + + this.collection.remove(conditions, { w: callback ? 1 : 0 }, callback); +}; + +Model.prototype.aggregate = function (chain, callback) { + /// Allows you to execute aggregation queries using MongoDB's aggregation framework + /// The aggregation toolchain to run + /// A function to be called once aggregation has been completed + + this.collection.aggregate(chain, callback); +}; + +Model.prototype.ensureIndex = function (spec, options, callback) { + /// + /// Ensures that an index is present on the database collection + /// The description of the index to be created + /// A function to be called once the operation has completed + /// + /// + /// Ensures that an index is present on the database collection + /// The description of the index to be created + /// Options to be applied to the index (unique, sparse, background etc.) + /// A function to be called once the operation has completed + /// + + if (!callback) { + callback = options; + options = {}; + } + + this.collection.ensureIndex(spec, options, callback); +}; + +Model.prototype.setupIndexes = function (callback) { + /// + /// Configures indexes defined for this model + /// + /// + /// Configures indexes defined for this model + /// A function to be called once all index creations have been requested + /// + + var $ = this; + + callback = callback || function (err) { + if (err) throw err; + }; + + if (!this.options.indexes || this.options.indexes.length === 0) return callback(null, []); + + var i = 0; + var errors = []; + var results = []; + + var next = function (err, result) { + errors.push(err); + results.push(result); + + if (++i === $.options.indexes.length) return callback(errors.length > 0 ? errors.pop() : null, results); + $.ensureIndex($.options.indexes[i][0], $.options.indexes[i][1], next); + }; + + $.ensureIndex($.options.indexes[i][0], $.options.indexes[i][1], next); +}; diff --git a/lib/utils/String.js b/lib/utils/String.js new file mode 100644 index 0000000..a3d011b --- /dev/null +++ b/lib/utils/String.js @@ -0,0 +1,147 @@ +/* + Copyright (c) 2009, CodePlex Foundation + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are permitted + provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions + and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions + and the following disclaimer in the documentation and/or other materials provided with the distribution. + + * Neither the name of CodePlex Foundation nor the names of its contributors may be used to endorse or + promote products derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +(function () { + + $type = String; + $type.__typeName = 'String'; + $type.__class = true; + + $prototype = $type.prototype; + $prototype.endsWith = function String$endsWith(suffix) { + /// Determines whether the end of this instance matches the specified string. + /// A string to compare to. + /// true if suffix matches the end of this instance; otherwise, false. + return (this.substr(this.length - suffix.length) === suffix); + } + + $prototype.startsWith = function String$startsWith(prefix) { + /// Determines whether the beginning of this instance matches the specified string. + /// The String to compare. + /// true if prefix matches the beginning of this string; otherwise, false. + return (this.substr(0, prefix.length) === prefix); + } + + $prototype.trim = function String$trim() { + /// Removes all leading and trailing white-space characters from the current String object. + /// The string that remains after all white-space characters are removed from the start and end of the current String object. + return this.replace(/^\s+|\s+$/g, ''); + } + + $prototype.trimEnd = function String$trimEnd() { + /// Removes all trailing white spaces from the current String object. + /// The string that remains after all white-space characters are removed from the end of the current String object. + return this.replace(/\s+$/, ''); + } + + $prototype.trimStart = function String$trimStart() { + /// Removes all leading white spaces from the current String object. + /// The string that remains after all white-space characters are removed from the start of the current String object. + return this.replace(/^\s+/, ''); + } + + $type.format = function String$format(format, args) { + /// Replaces the format items in a specified String with the text equivalents of the values of corresponding object instances. The invariant culture will be used to format dates and numbers. + /// A format string. + /// The objects to format. + /// A copy of format in which the format items have been replaced by the string equivalent of the corresponding instances of object arguments. + return String._toFormattedString(false, arguments); + } + + $type._toFormattedString = function String$_toFormattedString(useLocale, args) { + var result = ''; + var format = args[0]; + + for (var i = 0; ;) { + // Find the next opening or closing brace + var open = format.indexOf('{', i); + var close = format.indexOf('}', i); + if ((open < 0) && (close < 0)) { + // Not found: copy the end of the string and break + result += format.slice(i); + break; + } + if ((close > 0) && ((close < open) || (open < 0))) { + + if (format.charAt(close + 1) !== '}') { + throw new Error('format stringFormatBraceMismatch'); + } + + result += format.slice(i, close + 1); + i = close + 2; + continue; + } + + // Copy the string before the brace + result += format.slice(i, open); + i = open + 1; + + // Check for double braces (which display as one and are not arguments) + if (format.charAt(i) === '{') { + result += '{'; + i++; + continue; + } + + if (close < 0) throw new Error('format stringFormatBraceMismatch'); + + + // Find the closing brace + + // Get the string between the braces, and split it around the ':' (if any) + var brace = format.substring(i, close); + var colonIndex = brace.indexOf(':'); + var argNumber = parseInt((colonIndex < 0) ? brace : brace.substring(0, colonIndex), 10) + 1; + + if (isNaN(argNumber)) throw new Error('format stringFormatInvalid'); + + var argFormat = (colonIndex < 0) ? '' : brace.substring(colonIndex + 1); + + var arg = args[argNumber]; + if (typeof (arg) === "undefined" || arg === null) { + arg = ''; + } + + // If it has a toFormattedString method, call it. Otherwise, call toString() + if (arg.toFormattedString) { + result += arg.toFormattedString(argFormat); + } + else if (useLocale && arg.localeFormat) { + result += arg.localeFormat(argFormat); + } + else if (arg.format) { + result += arg.format(argFormat); + } + else + result += arg.toString(); + + i = close + 1; + } + + return result; + } + +})(); \ No newline at end of file diff --git a/lib/utils/transforms.js b/lib/utils/transforms.js new file mode 100644 index 0000000..6f4b74e --- /dev/null +++ b/lib/utils/transforms.js @@ -0,0 +1,43 @@ +var _ = require('lodash'); + + +(require.modules || {}).transforms = module.exports = transform; + +function transform(transforms, method, properties) { + /// Transforms properties according to a number of transformation functions + /// Mapped transformation functions to apply + /// The transformation method to apply to the properties + /// The object on which to apply the transformations + + if (!_.isPlainObject(properties)) return; // Cannot transform strange objects + + for (var k in transforms) { + if(k[0] === '$') break; // Transform methods, not properties to transform + + if (transforms[k] && transforms[k][method]) { + // Have a direct transform to apply + var newValue = transforms[k][method](properties[k]); + if(newValue === undefined && properties[k] !== undefined) delete properties[k]; + else if(newValue !== undefined) properties[k] = newValue; + } else if (transforms[k]) { + // Have a nested transformation to apply + transform(transforms[k], method, properties[k]); + } + } +} + +transform.up = function (transforms, properties) { + /// Transforms properties according to a number of transformation functions + /// Mapped transformation functions to apply + /// The object on which to apply the transformations + + transform(transforms, '$up', properties); +}; + +transform.down = function (transforms, properties) { + /// Transforms properties according to a number of transformation functions + /// Mapped transformation functions to apply + /// The object on which to apply the transformations + + transform(transforms, '$down', properties); +}; \ No newline at end of file diff --git a/lib/utils/validation.js b/lib/utils/validation.js new file mode 100644 index 0000000..575420b --- /dev/null +++ b/lib/utils/validation.js @@ -0,0 +1,121 @@ +/// + +var _ = require('lodash'); +require('./String'); + + +var validateType = (require.modules || {}).validation = module.exports = function (schemaType, value, property) { + /// + /// Validates the given value against a specified schema type field + /// The type of data specified to be contained within the Schema + /// The data to validate + /// + + "use strict"; + + var fail = function (expected, got) { + /// + /// Logs a failure reason to the application error log + /// A description of what was expected by the validator + /// + /// + /// Logs a failure reason to the application error log + /// A description of what was expected by the validator + /// The acctual value + /// + + if (!got) got = value; + + return { + passed: false, + reason: { + property: property, + expected: expected, + got: got + }, + toError: function () { + if (this.reason.property) return new Error(String.format('Failed to validate, expected value of {0} to be a {1} but got {2}', this.reason.property, this.reason.expected, this.reason.got)); + return new Error(String.format('Failed to validate, expected {0} but got {1}', this.reason.expected, this.reason.got)); + } + }; + }; + + var pass = { + passed: true + }; + + var assert = function (condition, expected, got) { + /// + /// Checks if a condition is met and returns a failure object if it is not + /// The condition to check + /// A description of what was expected by the validator + /// + /// + /// Logs a failure reason to the application error log + /// The condition to check + /// A description of what was expected by the validator + /// The acctual value + /// + + if (condition) return { + passed: true + }; + + return fail(expected, got); + }; + + var propertyPrefix = property ? (property + '.') : 'object.'; + + if (!schemaType) return pass; + + if (schemaType === true) return assert(value, 'value'); + + if (schemaType === Object) return pass; + if (_.isPlainObject(schemaType)) { + if (schemaType.$type) { + if (schemaType.$required === false && !value) return pass; + return validateType(schemaType.$type, value, property); + } + else if (schemaType.$propertyType) { + if (schemaType.$required === false && !value) return pass; + + // Check sub properties + for (var k in value) { + var result = validateType(schemaType.$propertyType, value[k], propertyPrefix + k); + if (!result.passed) return result; + } + return pass; + } + else { + if (!value) return fail('value'); + + // Check sub properties + for (var k in schemaType) { + var result = validateType(schemaType[k], value[k], propertyPrefix + k); + if (!result.passed) return result; + } + return pass; + } + } + if (Array.isArray(schemaType)) { + if (!Array.isArray(value)) return fail('array'); + + // Validate array values + for (var i = 0; i < value.length; i++) { + var result = validateType(schemaType[0], value[i], property + '[' + i + ']'); + if (!result.passed) return result; + } + + if (schemaType.length > 1 && value.length < schemaType[1]) return fail('array with a min length of ' + schemaType[1], value.length); // Minimum element count + if (schemaType.length > 2 && value.length > schemaType[2]) return fail('array with a max length of ' + schemaType[2], value.length); // Maximum element count + + return pass; + } + + if (schemaType === String) return assert(_.isString(value), 'string'); + if (schemaType === Number) return assert(_.isNumber(value), 'number'); + if (schemaType === Boolean) return assert(_.isBoolean(value), 'boolean'); + if (schemaType === Date) return assert(_.isDate(value), 'date'); + if (schemaType instanceof RegExp) return assert(schemaType.test(value), 'regex ' + schemaType.toString() + ' to match', value.toString()); + return assert(value instanceof schemaType, 'instanceof ' + schemaType.toString()); +}; \ No newline at end of file diff --git a/nodelib/assert.js b/nodelib/assert.js new file mode 100644 index 0000000..9403e0a --- /dev/null +++ b/nodelib/assert.js @@ -0,0 +1,93 @@ +/// +(function () { + var assert = require.modules.assert = function (value, message) { + /// + /// This module is used for writing unit tests for your applications, you can access it with require('assert'). + /// + /// truthy + /// + }; + assert.fail = function (actual, expected, message, operator) { + /// + /// Throws an exception that displays the values for `actual` and `expected` separated by the provided operator. + /// + /// + /// + /// + /// + }; + assert.ok = function (value, message) { + /// + /// Tests if value is a `true` value, it is equivalent to assert.equal(true, value, message); + /// + /// truthy + /// + }; + assert.equal = function (actual, expected, message) { + /// + /// Tests shallow, coercive equality with the equal comparison operator ( == ). + /// + /// + /// + /// + }; + assert.notEqual = function (actual, expected, message) { + /// + /// Tests shallow, coercive non-equality with the not equal comparison operator ( != ). + /// + /// + /// + /// + }; + assert.deepEqual = function (actual, expected, message) { + /// Tests for deep equality. + /// + /// + /// + }; + assert.notDeepEqual = function (actual, expected, message) { + /// Tests for any deep inequality. + /// + /// + /// + }; + assert.strictEqual = function (actual, expected, message) { + /// + /// Tests strict equality, as determined by the strict equality operator ( === ) + /// + /// + /// + /// + }; + assert.notStrictEqual = function (actual, expected, message) { + /// + /// Tests strict non-equality, as determined by the strict not equal operator ( !== ) + /// + /// + /// + /// + }; + assert.throws = function (block, error, message) { + /// + /// Expects `block` to throw an error. error can be constructor, regexp or validation function. + /// + /// + /// + /// + }; + assert.doesNotThrow = function (block, error, message) { + /// + /// Expects `block` not to throw an error, see assert.throws for details. + /// + /// + /// + /// + }; + assert.ifError = function (value) { + /// + /// Tests if value is not a false value, throws + /// if it is a true value. Useful when testing the first argument, `error` in callbacks. + /// + /// + }; +})(); diff --git a/nodelib/buffer.js b/nodelib/buffer.js new file mode 100644 index 0000000..3667904 --- /dev/null +++ b/nodelib/buffer.js @@ -0,0 +1,440 @@ +var Buffer = function (args) { + /// + /// Allocates a new buffer, using subject as a size of octets or using it as an array of octets. + /// + /// Number, array, or string. + /// + /// + /// + /// The size of the buffer in bytes. + /// Note that this is not necessarily the size of the contents. + /// length refers to the amount of memory allocated for the buffer object. + /// It does not change when the contents of the buffer are changed. + /// + /// + /// How many bytes will be returned when buffer.inspect() is called. This can be overriden by user modules. + /// + + var buf = new Array(); + buf.write = function (string, offset, length, encoding) { + /// + /// Writes string to the buffer at offset using the given encoding. + /// length is the number of bytes to write. Returns number of octets written. + /// If buffer did not contain enough space to fit the entire string, it will write a partial amount of the string. + /// The method will not write partial characters. + /// + /// String data. + /// Offset number. + /// Length of data to writing buffers. + /// Encoding option + }; + buf.copy = function (targetBuffer, targetStart, sourceStart, sourceEnd) { + /// + /// Does copy between buffers. The source and target regions can be overlapped. + /// + /// + /// + /// + /// + }; + + buf.toString = function(encoding, start, end) { + /// + /// Decodes and returns a string from buffer data encoded with encoding beginning at start and ending at end. + /// + /// + /// + /// + }; + buf.slice = function(start, end) { + /// + /// Returns a new buffer which references the same memory as the old, but offset and cropped by the start and end indexes. + /// Modifying the new buffer slice will modify memory in the original buffer! + /// + /// + /// + }; + + buf.readUInt8 = function (offset, noAssert) { + /// + /// Reads an unsigned 8 bit integer from the buffer at the specified offset. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that offset may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readUInt16LE = function (offset, noAssert) { + /// + /// Reads an unsigned 16 bit integer from the buffer at the specified offset with little endian format. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that offset may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readUInt16BE = function (offset, noAssert) { + /// + /// Reads an unsigned 16 bit integer from the buffer at the specified offset with big endian format. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that offset may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readUInt32LE = function (offset, noAssert) { + /// + /// Reads an unsigned 32 bit integer from the buffer at the specified offset with little endian format. + /// + /// + /// + /// + return new Number(); + }; + buf.readUInt32BE = function (offset, noAssert) { + /// + /// Reads an unsigned 32 bit integer from the buffer at the specified offset with big endian format. + /// + /// + /// Set `noAssert` to true to skip validation of `offset`. This means that `offset` may be beyond the end of the buffer. + return new Number(); + }; + buf.readInt8 = function (offset, noAssert) { + /// + /// Reads a signed 8 bit integer from the buffer at the specified offset. + /// Works as buffer.readUInt8, except buffer contents are treated as two's complement signed values. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that `offset` may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readInt16LE = function (offset, noAssert) { + /// + /// Reads a signed 16 bit integer from the buffer at the specified offset with little endian format. + /// Works as buffer.readUInt16*, except buffer contents are treated as two's complement signed values. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that `offset` may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readInt16BE = function (offset, noAssert) { + /// + /// Reads a signed 16 bit integer from the buffer at the specified offset with big endian format. + /// Works as `buffer.readUInt16*`, except buffer contents are treated as two's complement signed values. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that offset may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readInt32LE = function (offset, noAssert) { + /// + /// Reads a signed 32 bit integer from the buffer at the specified offset with little endian format. + /// Works as buffer.readUInt32*, except buffer contents are treated as two's complement signed values. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that offset may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readInt32BE = function (offset, noAssert) { + /// + /// Reads a signed 32 bit integer from the buffer at the specified offset with big endian format. + /// Works as buffer.readUInt32*, except buffer contents are treated as two's complement signed values. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that offset may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readFloatLE = function (offset, noAssert) { + /// + /// Reads a 32 bit float from the buffer at the specified offset with little endian format. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that `offset` may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readFloatBE = function (offset, noAssert) { + /// + /// Reads a 64 bit double from the buffer at the specified offset with little endian format. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that `offset` may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readDoubleLE = function (offset, noAssert) { + /// + /// Reads a 64 bit double from the buffer at the specified offset with little endian format. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that `offset` may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.readDoubleBE = function (offset, noAssert) { + /// + /// Reads a 64 bit double from the buffer at the specified offset with big endian format. + /// + /// + /// + /// Set noAssert to true to skip validation of offset. + /// This means that `offset` may be beyond the end of the buffer. + /// + return new Number(); + }; + buf.writeUInt8 = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset. + /// Note, value must be a valid unsigned 8 bit integer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function + /// and offset may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeUInt16LE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with little endian format. + /// Note, value must be a valid unsigned 16 bit integer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function + /// and offset may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeUInt16BE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with big endian format. + /// Note, value must be a valid unsigned 16 bit integer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function and offset may be beyond + /// the end of the buffer leading to the values being silently dropped. This should not be used + /// unless you are certain of correctness. + /// + }; + buf.writeUInt32LE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with little endian format. + /// Note, value must be a valid unsigned 32 bit integer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that `value` may be too large for the specific function and offset + /// may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeUInt32BE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with big endian format. + /// Note, value must be a valid unsigned 32 bit integer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function and offset + /// may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeInt8 = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset. + /// Note, value must be a valid signed 8 bit integer. + /// Works as buffer.writeUInt8, except value is written out as a two's complement signed integer into buffer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that `value` may be too large for the specific function and offset + /// may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeInt16LE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with little endian format. + /// Note, value must be a valid signed 16 bit integer. + /// Works as buffer.writeUInt16*, except value is written out as a two's complement signed integer into buffer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function + /// and offset may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeInt16BE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with big endian format. + /// Note, value must be a valid signed 16 bit integer. + /// Works as buffer.writeUInt16*, except value is written out as a two's complement signed integer into buffe. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function and offset + /// may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeInt32LE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with little endian format. + /// Note, value must be a valid signed 32 bit integer. Works as buffer.writeUInt32*, + /// except value is written out as a two's complement signed integer into buffer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function and offset + /// may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeInt32BE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with big endian format. + /// Note, value must be a valid signed 32 bit integer. + /// Works as buffer.writeUInt32*, except value is written out as a two's complement signed integer into buffer. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function + /// and offset may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeFloatLE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with little endian format. + /// Note, value must be a valid 32 bit float. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function + /// and offset may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeFloatBE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with big endian format. + /// Note, value must be a valid 32 bit float. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function and offset may be beyond + /// the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeDoubleLE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with little endian format. + /// Note, value must be a valid 64 bit double. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function + /// and offset may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.writeDoubleBE = function (value, offset, noAssert) { + /// + /// Writes value to the buffer at the specified offset with big endian format. + /// Note, value must be a valid 64 bit double. + /// + /// + /// + /// + /// Set noAssert to true to skip validation of value and offset. + /// This means that value may be too large for the specific function + /// and offset may be beyond the end of the buffer leading to the values being silently dropped. + /// This should not be used unless you are certain of correctness. + /// + }; + buf.fill = function (value, offset, end) { + /// + /// Fills the buffer with the specified value. + /// If the offset and length are not given it will fill the entire buffer. + /// + /// + /// + /// + }; + return buf; +}; +Buffer.isBuffer = function (obj) { + /// Tests if `obj` is a `Buffer`. + /// + /// + return new Boolean(); +}; +Buffer.byteLength = function (string, encoding) { + /// + /// Gives the actual byte length of a string. + /// This is not the same as String.prototype.length since that returns the number of *characters* in a string. + /// + /// + /// + /// + return new Number(); +}; +var INSPECT_MAX_BYTES = new Number(50); diff --git a/nodelib/child_process.js b/nodelib/child_process.js new file mode 100644 index 0000000..f0fd13c --- /dev/null +++ b/nodelib/child_process.js @@ -0,0 +1,91 @@ +/// +/// +/// +/// + +(function () { + require.modules.child_process = { + spawn: function (command, args, options) { + /// + /// Launches a new process with the given `command`, with command line arguments in `args`.
+ /// If omitted, `args` defaults to an empty Array.
+ ///
+ /// The command to run. + /// Array List of string arguments. + /// + return new ChildProcess(); + }, + exec: function (command, options, callback) { + /// + /// Runs a command in a shell and buffers the output. + /// + /// The command to run, with space-separated arguments. + /// + /// Function called with the output when process terminates. + return new ChildProcess(); + }, + execFile: function (file, args, options, callback) { + /// + /// This is similar to `child_process.exec()` except it does not execute a subshell but rather the specified file directly.
+ /// This makes it slightly leaner than `child_process.exec`. It has the same options. + ///
+ /// The filename of the program to run. + /// Array List of string arguments. + /// + /// Function called with the output when process terminates. + /// + return new ChildProcess(); + }, + fork: function (modulePath, args, options) { + /// + /// This is a special case of the `spawn()` functionality for spawning Node processes.
+ /// In addition to having all the methods in a normal ChildProcess instance,
+ /// the returned object has a communication channel built-in.
+ /// The channel is written to with `child.send(message)` and messages are recieved by a `'message'` event on the child. + ///
+ /// + /// Array List of string arguments. + /// + /// + return new ChildProcess(); + } + }; + + var ChildProcess = function () { + /// An instance of a child process created by the child_process library. + /// + /// A Writable Stream that represents the child process's stdin.
+ /// Closing this stream via end() often causes the child process to terminate. + ///
+ /// A Readable Stream that represents the child process's stdout. + /// A Readable Stream that represents the child process's stderr. + /// The PID of the child process. + + + ////Event: 'exit' + ////Event: 'close' + ////Event: 'disconnect' + ////Event: 'message' + this.stdin = new Stream(); + this.stdout = new Stream(); + this.stderr = new Stream(); + this.pid = new Number(); + this.kill = function (signal) { + /// + /// Send a signal to the child process.
+ /// If no argument is given, the process will be sent 'SIGTERM'.
+ /// See signal for a list of available signals. + ///
+ /// + }; + this.send = function (message, sendHandle) { + /// Send a message (and, optionally, a handle object) to a child process. + /// + /// + }; + this.disconnect = function () { }; + }; + + var EventEmitter = require("events").EventEmitter; + ChildProcess.prototype = new EventEmitter(); +})(); \ No newline at end of file diff --git a/nodelib/cluster.js b/nodelib/cluster.js new file mode 100644 index 0000000..feaad46 --- /dev/null +++ b/nodelib/cluster.js @@ -0,0 +1,243 @@ +/// +/// + +require.modules.cluster = new function () { + /// + /// A single instance of Node runs in a single thread.
+ /// To take advantage of multi-core systems the user will sometimes
+ /// want to launch a cluster of Node processes to handle the load. + ///
+ /// + /// All settings set by the .setupMaster is stored in this settings object.
+ /// This object is not supposed to be change or set manually, by you. + ///
+ /// + /// True if the process is a master. This is determined by the process.env.NODE_UNIQUE_ID.
+ /// If process.env.NODE_UNIQUE_ID is undefined, then isMaster is true. + ///
+ /// + /// This boolean flag is true if the process is a worker forked from a master.
+ /// If the process.env.NODE_UNIQUE_ID is set to a value, then isWorker is true. + ///
+ /// + /// A hash that stores the active worker objects, keyed by id field.
+ /// Makes it easy to loop through all the workers. It is only available in the master process. + ///
+ + + this.settings = new Object(); + this.isMaster = new Boolean(); + this.isWorker = new Boolean(); + this.setupMaster = function (settings) { + /// + /// setupMaster is used to change the default 'fork' behavior.
+ /// The new settings are effective immediately and permanently, they cannot be changed later on. + ///
+ /// + }; + this.fork = function (env) { + /// + /// Spawn a new worker process. This can only be called from the master process. + /// + /// + /// + new require.modules.cluster.Worker(); + }; + this.disconnect = function (callback) { + /// + /// When calling this method, all workers will commit a graceful suicide.
+ /// When they are disconnected all internal handlers will be closed,
+ /// allowing the master process to die graceful if no other event is waiting. + ///
+ /// + }; + this.workers = new Object(); + ////Event: 'fork' + ////Event: 'online' + ////Event: 'listening' + ////Event: 'disconnect' + ////Event: 'exit' + ////Event: 'setup' + + this.on = function (event, listener) { + /// + /// event method. + /// + /// + /// event name.
+ /// 'fork', 'online', 'listening', 'disconnect', 'exit', 'setup' + /// + /// listenr function. + }; + this.addListener = function (event, listener) { + /// Adds a listener to the end of the listeners array for the specified event. + /// event name. + /// listener function. + }; + this.once = function (event, listener) { + /// + /// Adds a **one time** listener for the event.
+ /// This listener is invoked only the next time the event is fired, after which it is removed. + ///
+ /// event name. + /// listener function. + }; + this.removeListener = function (event, listener) { + /// + /// Remove a listener from the listener array for the specified event.
+ /// **Caution**: changes array indices in the listener array behind the listener. + ///
+ /// event name. + /// listener function. + }; + this.removeAllListeners = function (event) { + /// + /// Removes all listeners, or those of the specified event. + /// + /// event name. + }; + this.setMaxListeners = function (n) { + /// + /// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
+ /// This is a useful default which helps finding memory leaks.
+ /// Obviously not all Emitters should be limited to 10.
+ /// This function allows that to be increased. Set to zero for unlimited. + ///
+ /// + }; + this.listeners = function (event) { + /// + /// Returns an array of listeners for the specified event.
+ /// This array can be manipulated, e.g. to remove listeners.
+ /// event name. + }; + this.emit = function (event, arg1, arg2) { + /// + /// Execute each of the listeners in order with the supplied arguments. + /// + /// event name. + /// + /// + }; + +}; + +require.modules.cluster.Worker = function () { + /// + /// A Worker object contains all public information and method about a worker.
+ /// In the master it can be obtained using cluster.workers.
+ /// In a worker it can be obtained using cluster.worker. + ///
+ /// + /// Each new worker is given its own unique id, this id is stored in the id. + /// + /// + /// All workers are created using child_process.fork(), the returned object from this function is stored in process. + /// + /// + /// This property is a boolean.
+ /// It is set when a worker dies after calling .destroy() or immediately after calling the .disconnect() method.
+ /// Until then it is undefined. + ///
+ + this.id = new String(); + this.process = new ChildProcess(); + this.suicide = new Boolean(); + this.send = function (message, sendHandle) { + /// + /// This function is equal to the send methods provided by child_process.fork().
+ /// In the master you should use this function to send a message to a specific worker.
+ /// However in a worker you can also use process.send(message), since this is the same function. + ///
+ /// + /// + }; + this.destroy = function() { + /// + /// This function will kill the worker, and inform the master to not spawn a new worker.
+ /// The boolean suicide lets you distinguish between voluntary and accidental exit. + ///
+ }; + this.disconnect = function() { + /// + /// When calling this function the worker will no longer accept new connections,
+ /// but they will be handled by any other listening worker. Existing connection
+ /// will be allowed to exit as usual. When no more connections exist, the IPC channel
+ /// to the worker will close allowing it to die graceful. When the IPC channel is closed
+ /// the disconnect event will emit, this is then followed by the exit event, there is
+ /// emitted when the worker finally die. + /// Because there might be long living connections, it is useful to implement a timeout.
+ /// This example ask the worker to disconnect and after 2 seconds it will destroy the server.
+ /// An alternative would be to execute worker.destroy() after 2 seconds, but that would
+ /// normally not allow the worker to do any cleanup if needed. + ///
+ + }; + ////Event: 'message' + ////Event: 'online' + ////Event: 'listening' + ////Event: 'disconnect' + ////Event: 'exit' + + this.on = function (event, listener) { + /// + /// event method. + /// + /// + /// event name.
+ /// 'message', 'online', 'listening', 'disconnect', 'exit' + /// + /// listenr function. + }; + this.addListener = function (event, listener) { + /// Adds a listener to the end of the listeners array for the specified event. + /// event name. + /// listener function. + }; + this.once = function (event, listener) { + /// + /// Adds a **one time** listener for the event.
+ /// This listener is invoked only the next time the event is fired, after which it is removed. + ///
+ /// event name. + /// listener function. + }; + this.removeListener = function (event, listener) { + /// + /// Remove a listener from the listener array for the specified event.
+ /// **Caution**: changes array indices in the listener array behind the listener. + ///
+ /// event name. + /// listener function. + }; + this.removeAllListeners = function (event) { + /// + /// Removes all listeners, or those of the specified event. + /// + /// event name. + }; + this.setMaxListeners = function (n) { + /// + /// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
+ /// This is a useful default which helps finding memory leaks.
+ /// Obviously not all Emitters should be limited to 10.
+ /// This function allows that to be increased. Set to zero for unlimited. + ///
+ /// + }; + this.listeners = function (event) { + /// + /// Returns an array of listeners for the specified event.
+ /// This array can be manipulated, e.g. to remove listeners.
+ /// event name. + }; + this.emit = function (event, arg1, arg2) { + /// + /// Execute each of the listeners in order with the supplied arguments. + /// + /// event name. + /// + /// + }; + +}; diff --git a/nodelib/console.js b/nodelib/console.js new file mode 100644 index 0000000..6e62026 --- /dev/null +++ b/nodelib/console.js @@ -0,0 +1,69 @@ +/// +/// +/// + +var Console = function () { + /// + /// For printing to stdout and stderr.
+ /// Similar to the console object functions provided by most web browsers, here the output is sent to stdout or stderr. + ///
+ this.log = function (data) { + /// + /// Prints to stdout with newline. This function can take multiple arguments in a printf()-like way.
+ /// Example: console.log('count: %d', count);
+ ///
+ /// + }; + this.info = function (data) { + /// + /// Prints to stdout with newline. This function can take multiple arguments in a printf()-like way.
+ /// Example: console.log('count: %d', count);
+ ///
+ /// + }; + this.error = function (data) { + /// + /// Prints to stderr with newline. This function can take multiple arguments in a printf()-like way.
+ /// Example: console.log('count: %d', count);
+ ///
+ /// + }; + this.warn = function (data) { + /// + /// Prints to stderr with newline. This function can take multiple arguments in a printf()-like way.
+ /// Example: console.log('count: %d', count);
+ ///
+ /// + }; + this.dir = function (obj) { + /// + /// Uses util.inspect on obj and prints resulting string to stdout. + /// + /// + }; + this.time = function (label) { + /// + /// Mark a time. + /// + /// + }; + this.timeEnd = function (label) { + /// + /// Finish timer, record output. + /// + /// + }; + this.trace = function (label) { + /// + /// Print a stack trace to stderr of the current position. + /// + /// + }; + this.assert = function (expression, message) { + /// + /// Same as assert.ok() where if the expression evaluates as false throw an AssertionError with message. + /// + /// truthy + /// + }; +}; diff --git a/nodelib/core.js b/nodelib/core.js new file mode 100644 index 0000000..8afaca1 --- /dev/null +++ b/nodelib/core.js @@ -0,0 +1,17 @@ +/// node.js 0.8.18 + +function require(name) { + /// Loads the specified module or file for use + /// The name of the module, or relative path to the file to load + + return require.modules[name.substr(name.lastIndexOf('/') + 1)]; +}; + +// Contains modules recognized by require() +// Add a property to this object to support +// other modules. +require.modules = {}; + +require.resolve = new Function(); +require.cache = new Object(); +require.extensions = new Array(); \ No newline at end of file diff --git a/nodelib/crypto.js b/nodelib/crypto.js new file mode 100644 index 0000000..7cf66e0 --- /dev/null +++ b/nodelib/crypto.js @@ -0,0 +1,389 @@ +/// + +require.modules.crypto =new function () { + /// + /// The crypto module requires OpenSSL to be available on the underlying platform.
+ /// It offers a way of encapsulating secure credentials to be used as part of a secure HTTPS net or http connection.
+ /// It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sign and verify methods.
+ ///
+ this.createCredentials = function (details) { + /// + /// Creates a credentials object, with the optional details being a dictionary with keys. + /// + /// + /// key (a string holding the PEM encoded private key), `cert` (a string holding the PEM encoded certificate),
+ /// and `ca` (either a string or list of strings of PEM encoded CA certificates to trust) + /// + /// + return new require.modules.crypto.Credentials(); + }; + this.createHash = function (algorithm) { + /// + /// Creates and returns a hash object, a cryptographic hash with the given algorithm which can be used to generate hash digests. + /// + /// + /// `algorithm` is dependent on the available algorithms supported by the version of OpenSSL on the platform.
+ /// Examples are 'sha1', 'md5', 'sha256', 'sha512', etc. On recent releases,
+ /// `openssl list-message-digest-algorithms` will display the available digest algorithms. + /// + /// + return new require.modules.crypto.Hash(); + }; + this.createHmac = function (algorithm, key) { + /// + /// Creates and returns a hmac object, a cryptographic hmac with the given algorithm and key. + /// + ///`algorithm` is dependent on the available algorithms supported by OpenSSL. + ///`key` is the hmac key to be used. + /// + return new require.modules.crypto.Hmac(); + }; + this.createCipher = function (algorithm, password) { + /// Creates and returns a cipher object, with the given algorithm and password. + /// + /// `algorithm` is dependent on OpenSSL, examples are 'aes192', etc. On recent releases,
+ /// `openssl list-cipher-algorithms` will display the available cipher algorithms. + /// + /// `password` is used to derive key and IV, which must be 'binary' encoded string + /// + return new require.modules.crypto.Cipher(); + }; + this.createCipheriv = function (algorithm, key, iv) { + /// Creates and returns a cipher object, with the given algorithm, key and iv. + /// + /// `algorithm` is dependent on OpenSSL, examples are 'aes192', etc. On recent releases,
+ /// `openssl list-cipher-algorithms` will display the available cipher algorithms. + /// + /// `key` is a raw key used in algorithm. Must be `binary' encoded string. + /// `iv` is an initialization vector. Must be `binary' encoded string. + /// + return new require.modules.crypto.Cipher(); + }; + this.createDecipher = function (algorithm, password) { + /// Creates and returns a decipher object, with the given algorithm and password. + /// + /// `algorithm` is dependent on OpenSSL, examples are 'aes192', etc. On recent releases,
+ /// `openssl list-cipher-algorithms` will display the available cipher algorithms. + /// + /// `password` is used to derive key and IV, which must be 'binary' encoded string + /// + return new require.modules.crypto.Decipher(); + }; + this.createDecipheriv = function (algorithm, key, iv) { + /// Creates and returns a decipher object, with the given algorithm, key and iv. + /// + /// `algorithm` is dependent on OpenSSL, examples are 'aes192', etc.
+ /// On recent releases, `openssl list-cipher-algorithms` will display the available cipher algorithms. + /// + ///`key` is a raw key used in algorithm. Must be `binary' encoded string. + ///`iv` is an initialization vector. Must be `binary' encoded string. + /// + return new require.modules.crypto.Decipher(); + }; + this.createSign = function (algorithm) { + /// + /// Creates and returns a signing object, with the given algorithm.
+ /// On recent OpenSSL releases, `openssl list-public-key-algorithms` will display the available signing algorithms.
+ /// Examples are `'RSA-SHA256'`. + ///
+ /// + /// + return new require.modules.crypto.Signer(); + }; + this.createVerify = function(algorithm) { + /// + /// Creates and returns a verification object, with the given algorithm. This is the mirror of the signing object. + /// + /// + /// + return new require.modules.crypto.Verify(); + }; + this.createDiffieHellman = function (prime, encoding) { + /// + /// Creates a Diffie-Hellman key exchange object and generates a prime of the given bit length. The generator used is `2`. + /// + /// + /// + /// + return new require.modules.crypto.DiffieHellman(); + }; + this.getDiffieHellman = function (group_name) { + + /// + /// + return new require.modules.crypto.DiffieHellman(); + }; + this.pbkdf2 = function (password, salt, iterations, keylen, callback) { + /// + /// Asynchronous PBKDF2 applies pseudorandom function HMAC-SHA1 to derive a key of given length from the given password, + /// salt and iterations. The callback gets two arguments `(err, derivedKey)`. + /// + /// + /// + /// + /// + /// + /// + }; + this.randomBytes = function (size, callback) { + /// Generates cryptographically strong pseudo-random data. + /// + /// + /// + return new Buffer(); + }; +}; + +require.modules.crypto.Credentials = function () { } + +require.modules.crypto.Hash = function () { + /// + /// A hash object, a cryptographic hash with the given algorithm which can be used to generate hash digests. + /// + this.update = function (data, input_encoding) { + /// + /// Updates the hash content with the given data. This can be called many times with new data as it is streamed. + /// + /// + /// + }; + this.digest = function (encoding) { + /// + /// Calculates the digest of all of the passed data to be hashed. + /// The encoding can be 'hex', 'binary' or 'base64'. + /// + /// + /// The encoding can be 'hex', 'binary' or 'base64'.\ + /// + /// + return new String(); + }; +}; + +require.modules.crypto.Hmac = function () { + /// + /// An hmac object, a cryptographic hmac with the given algorithm and key. + /// + this.update = function (data) { + /// + /// Update the hmac content with the given data.
+ /// This can be called many times with new data as it is streamed. + ///
+ /// + }; + this.digest = function (encoding) { + /// + /// Calculates the digest of all of the passed data to the hmac. + /// The encoding can be 'hex', 'binary' or 'base64'. + /// + /// + /// The encoding can be 'hex', 'binary' or 'base64'. + /// + /// + return new String(); + }; +}; + +require.modules.crypto.Cipher = function () { + /// A cipher object + this.update = function (data, input_encoding, output_encoding) { + /// + /// Updates the cipher with data, the encoding of
+ /// which is given in input_encoding and can be 'utf8', 'ascii' or 'binary'.
+ /// The output_encoding specifies the output format of the enciphered data,
+ /// and can be 'binary', 'base64' or 'hex'.
+ /// Returns the enciphered contents, and can be called many times with new data as it is streamed.
+ ///
+ /// + /// + /// 'utf8', 'ascii' or 'binary' + /// + /// + /// 'binary', 'base64' or 'hex' + /// + }; + this.final = function (output_encoding) { + /// + /// Returns any remaining enciphered contents, with output_encoding being one of: 'binary', 'base64' or 'hex'. + /// + /// 'binary', 'base64' or 'hex' + return new String(); + }; + this.setAutoPadding = function (auto_padding) { + /// + }; +}; + +require.modules.crypto.Decipher = function () { + /// A decipher object + this.update = function (data, input_encoding, output_encoding) { + /// + /// Updates the decipher with data, which is encoded in 'binary', 'base64' or 'hex'.
+ /// The `output_decoding` specifies in what format to return the deciphered plaintext: 'binary', 'ascii' or 'utf8'. + ///
+ /// + /// + /// 'utf8', 'ascii' or 'binary' + /// + /// + /// 'binary', 'base64' or 'hex' + /// + }; + this.final = function (output_encoding) { + /// + /// Returns any remaining plaintext which is deciphered, with output_encoding
+ /// being one of: 'binary', 'ascii' or 'utf8'. + ///
+ /// + /// 'binary', 'ascii' or 'utf8' + /// + return new String(); + }; + this.setAutoPadding = function (auto_padding) { + /// + }; +}; + +require.modules.crypto.Signer = function () { + /// A signing object. + this.update = function (data) { + /// + /// Updates the signer object with data.
+ /// This can be called many times with new data as it is streamed.
+ ///
+ /// + }; + this.sign = function (private_key, output_format) { + /// + /// Calculates the signature on all the updated data passed through the signer.
+ /// private_key is a string containing the PEM encoded private key for signing.
+ ///
+ /// + /// + return new String(); + }; +}; + +require.modules.crypto.Verify = function () { + this.update = function (data) { + /// + /// Updates the verifier object with data.
+ /// This can be called many times with new data as it is streamed. + ///
+ /// + }; + this.verify = function (object, signature, signature_format) { + /// + /// Verifies the signed data by using the object and signature.
+ /// object is a string containing a PEM encoded object, which can be one of RSA public key,
+ /// DSA public key, or X.509 certificate. + /// signature is the previously calculated signature for the data,
+ /// in the signature_format which can be 'binary', 'hex' or 'base64'. + ///
+ /// + /// + /// + /// 'binary', 'hex' or 'base64' + /// + /// + /// Returns true or false depending on the validity of the signature for the data and public key. + /// + return new Boolean(); + }; +}; + +require.modules.crypto.DiffieHellman = function () { + /// A Diffie-Hellman key exchange object. + this.generateKeys = function (encoding) { + /// + /// Generates private and public Diffie-Hellman key values,
+ /// and returns the public key in the specified encoding.
+ /// This key should be transferred to the other party.
+ /// Encoding can be 'binary', 'hex', or 'base64'. + ///
+ /// + /// 'binary', 'hex', or 'base64' + /// + }; + this.computeSecret = function (other_public_key, input_encoding, output_encoding) { + /// + /// Computes the shared secret using other_public_key as the other party's public key
+ /// and returns the computed shared secret.
+ /// Supplied key is interpreted using specified input_encoding,
+ /// and secret is encoded using specified output_encoding.
+ /// Encodings can be 'binary', 'hex', or 'base64'.
+ /// If no output encoding is given, the input encoding is used as output encoding.
+ ///
+ /// + /// 'binary', 'hex', or 'base64' + /// 'binary', 'hex', or 'base64' + /// + return new String(); + }; + this.getPrime = function (encoding) { + /// + /// Returns the Diffie-Hellman prime in the specified encoding,
+ /// which can be 'binary', 'hex', or 'base64'.
+ /// + /// 'binary', 'hex', or 'base64' + /// + /// + return new String(); + }; + this.getGenerator = function (encoding) { + /// + /// Returns the Diffie-Hellman prime in the specified encoding,
+ /// which can be 'binary', 'hex', or 'base64'. + ///
+ /// + /// 'binary', 'hex', or 'base64' + /// + /// + return new String(); + }; + this.getPublicKey = function (encoding) { + /// + /// Returns the Diffie-Hellman public key in the specified encoding,
+ /// which can be 'binary', 'hex', or 'base64'. + ///
+ /// + /// 'binary', 'hex', or 'base64' + /// + /// + return new String(); + }; + this.getPrivateKey = function (encoding) { + /// + /// Returns the Diffie-Hellman private key in the specified encoding,
+ /// which can be 'binary', 'hex', or 'base64'. + ///
+ /// + /// 'binary', 'hex', or 'base64' + /// + return new String(); + }; + this.setPublicKey = function (public_key, encoding) { + /// + /// Sets the Diffie-Hellman public key.
+ /// Key encoding can be 'binary', 'hex', or 'base64'.
+ ///
+ /// + /// + /// 'binary', 'hex', or 'base64' + /// + /// + return new String(); + }; + this.setPrivateKey = function (public_key, encoding) { + /// + /// Sets the Diffie-Hellman private key.
+ /// Key encoding can be 'binary', 'hex', or 'base64'. + ///
+ /// + /// + /// 'binary', 'hex', or 'base64' + /// + /// + return new String(); + }; +}; diff --git a/nodelib/dgram.js b/nodelib/dgram.js new file mode 100644 index 0000000..d50452a --- /dev/null +++ b/nodelib/dgram.js @@ -0,0 +1,179 @@ +/// + +require.modules.crypto.dgram = { + createSocket: function (type, callback) { + /// + /// Creates a datagram Socket of the specified types. Valid types are udp4 and udp6. + /// Takes an optional callback which is added as a listener for message events. + /// + /// + /// Either 'udp4' or 'udp6'. + /// + /// + /// Attached as a listener to message events. Optional. + /// + /// Socket object + return new require.modules.crypto.dgram.Socket(); + } +}; + +require.modules.crypto.dgram.Socket = function (type, callback) { + /// + /// The dgram Socket class encapsulates the datagram functionality.
+ /// It should be created via dgram.createSocket(type, [callback]). + ///
+ + this.send = function (buf, offset, length, port, address, callback) { + /// + /// For UDP sockets, the destination port and IP address must be specified.
+ /// A string may be supplied for the address parameter, and it will be resolved
+ /// with DNS. An optional callback may be specified to detect any DNS errors and
+ /// when buf may be re-used. Note that DNS lookups will delay the time that a
+ /// send takes place, at least until the next tick. The only way to know for sure
+ /// that a send has taken place is to use the callback. + ///
+ /// Message to be sent + /// Offset in the buffer where the message starts. + /// Number of bytes in the message. + /// destination port. + /// destination IP + /// + /// Callback when message is done being delivered. Optional. + /// + }; + this.bind = function(port, address) { + /// + /// For UDP sockets, listen for datagrams on a named port and optional address.
+ /// If address is not specified, the OS will try to listen on all addresses. + ///
+ /// + /// + }; + this.close = function() { + /// + /// Close the underlying socket and stop listening for data on it. + /// + }; + this.address = function() { + /// + /// Returns an object containing the address information for a socket. For UDP sockets,
+ /// this object will contain address , family and port. + ///
+ /// + return new Object(); + }; + this.setBroadcast = function(flag) { + /// + /// Sets or clears the SO_BROADCAST socket option. When this option is set, UDP packets may
+ /// be sent to a local interface's broadcast address. + ///
+ /// + }; + this.setTTL = function (ttl) { + /// + /// Sets the IP_TTL socket option. TTL stands for "Time to Live," but in this context it
+ /// specifies the number of IP hops that a packet is allowed to go through. Each router or
+ /// gateway that forwards a packet decrements the TTL. If the TTL is decremented to 0 by a
+ /// router, it will not be forwarded. Changing TTL values is typically done for network
+ /// probes or when multicasting. + ///
+ /// + }; + this.setMulticastTTL = function (ttl) { + /// + /// Sets or clears the IP_MULTICAST_LOOP socket option. When this option is set, multicast
+ /// packets will also be received on the local interface. + ///
+ /// + }; + this.setMulticastLoopback = function (flag) { + /// + /// Sets or clears the IP_MULTICAST_LOOP socket option. When this option is set, multicast
+ /// packets will also be received on the local interface. + ///
+ /// + }; + this.addMembership = function (multicastAddress, multicastInterface) { + /// + /// Tells the kernel to join a multicast group with IP_ADD_MEMBERSHIP socket option. + /// If multicastInterface is not specified, the OS will try to add membership to all valid interfaces. + /// + /// + /// + }; + this.dropMembership = function (multicastAddress, multicastInterface) { + /// + /// Opposite of addMembership - tells the kernel to leave a multicast group with IP_DROP_MEMBERSHIP
+ /// socket option. This is automatically called by the kernel when the socket is closed or
+ /// process terminates, so most apps will never need to call this. + ///
+ /// + /// + }; + + ////Event: 'message' + ////Event: 'listening' + ////Event: 'close' + ////Event: 'error' + this.on = function (event, listener) { + /// + /// event method. + /// + /// + /// event name.
+ /// 'message', 'listening', 'close', 'error' + /// + /// listenr function. + }; + this.addListener = function (event, listener) { + /// Adds a listener to the end of the listeners array for the specified event. + /// event name. + /// listener function. + }; + this.once = function (event, listener) { + /// + /// Adds a **one time** listener for the event.
+ /// This listener is invoked only the next time the event is fired, after which it is removed. + ///
+ /// event name. + /// listener function. + }; + this.removeListener = function (event, listener) { + /// + /// Remove a listener from the listener array for the specified event.
+ /// **Caution**: changes array indices in the listener array behind the listener. + ///
+ /// event name. + /// listener function. + }; + this.removeAllListeners = function (event) { + /// + /// Removes all listeners, or those of the specified event. + /// + /// event name. + }; + this.setMaxListeners = function (n) { + /// + /// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
+ /// This is a useful default which helps finding memory leaks.
+ /// Obviously not all Emitters should be limited to 10.
+ /// This function allows that to be increased. Set to zero for unlimited. + ///
+ /// + }; + this.listeners = function (event) { + /// + /// Returns an array of listeners for the specified event.
+ /// This array can be manipulated, e.g. to remove listeners.
+ /// event name. + }; + this.emit = function (event, arg1, arg2) { + /// + /// Execute each of the listeners in order with the supplied arguments. + /// + /// event name. + /// + /// + }; + +}; diff --git a/nodelib/dns.js b/nodelib/dns.js new file mode 100644 index 0000000..5813d45 --- /dev/null +++ b/nodelib/dns.js @@ -0,0 +1,126 @@ +require.modules.crypto.dns = new function () { + /// + /// Use require('dns') to access this module. All methods in the dns module
+ /// use C-Ares except for dns.lookup which uses getaddrinfo in a thread pool.
+ /// C-Ares is much faster than getaddrinfo but the system resolver is more
+ /// constant with how other programs operate. When a user does
+ /// net.connect(80, 'google.com') or http.get({ host: 'google.com' }) the
+ /// dns.lookup method is used. Users who need to do a large number of look
+ /// ups quickly should use the methods that go through C-Ares. + ///
+ + + this.lookup = function (domain, family, callback) { + /// + /// Resolves a domain (e.g. 'google.com') into the first found A (IPv4)
+ /// or AAAA (IPv6) record. The family can be the integer 4 or 6.
+ /// Defaults to null that indicates both Ip v4 and v6 address family. + ///
+ /// + /// + /// + }; + this.resolve = function (domain, rrtype, callback) { + /// + /// Resolves a domain (e.g. 'google.com') into an array of the record
+ /// types specified by rrtype. Valid rrtypes are 'A' (IPV4 addresses,
+ /// default), 'AAAA' (IPV6 addresses), 'MX' (mail exchange records),
+ /// 'TXT' (text records), 'SRV' (SRV records), 'PTR' (used for reverse
+ /// IP lookups), 'NS' (name server records) and 'CNAME' (canonical name records). + ///
+ /// + /// + /// + }; + this.resolve4 = function (domain, callback) { + /// + /// The same as dns.resolve(), but only for IPv4 queries (A records).
+ /// addresses is an array of IPv4 addresses (e.g. ['74.125.79.104',
+ /// '74.125.79.105', '74.125.79.106']). + ///
+ /// + /// + }; + this.resolve6 = function (domain, callback) { + /// + /// The same as dns.resolve4() except for IPv6 queries (an AAAA query). + /// + /// + /// + }; + this.resolveMx = function (domain, callback) { + /// + /// The same as dns.resolve(), but only for mail exchange queries (MX records). + /// + /// + /// + }; + this.resolveTxt = function (domain, callback) { + /// + /// The same as dns.resolve(), but only for service records (SRV
+ /// records). addresses is an array of the SRV records available for
+ /// domain. Properties of SRV records are priority, weight, port, and name + ///
+ /// + /// + }; + this.resolveSrv = function (domain, callback) { + /// + /// The same as dns.resolve(), but only for service records (SRV
+ /// records). addresses is an array of the SRV records available for
+ /// domain. Properties of SRV records are priority, weight, port, and name + ///
+ /// + /// + }; + this.resolveNs = function (domain, callback) { + /// + /// The same as dns.resolve(), but only for name server records (NS
+ /// records). addresses is an array of the name server records available
+ /// for domain + ///
+ /// + /// + }; + this.resolveCname = function (domain, callback) { + /// + /// The same as dns.resolve(), but only for name server records (NS
+ /// records). addresses is an array of the name server records available
+ /// for domain + ///
+ /// + /// + }; + this.reverse = function (ip, callback) { + /// + /// Reverse resolves an ip address to an array of domain names. + /// + /// + /// + }; + // Error Codes + ////dns.NODATA; + ////dns.FORMERR; + ////dns.SERVFAIL; + ////dns.NOTFOUND; + ////dns.NOTIMP; + ////dns.REFUSED; + ////dns.BADQUERY; + ////dns.BADNAME; + ////dns.BADFAMILY; + ////dns.BADRESP; + ////dns.CONNREFUSED; + ////dns.TIMEOUT; + ////dns.EOF; + ////dns.FILE; + ////dns.NOMEM; + ////dns.DESTRUCTION; + ////dns.BADSTR; + ////dns.BADFLAGS; + ////dns.NONAME; + ////dns.BADHINTS; + ////dns.NOTINITIALIZED; + ////dns.LOADIPHLPAPI; + ////dns.ADDRGETNETWORKPARAMS; + ////dns.CANCELLED; +}; diff --git a/nodelib/domain.js b/nodelib/domain.js new file mode 100644 index 0000000..df4b215 --- /dev/null +++ b/nodelib/domain.js @@ -0,0 +1,91 @@ +/// +/// + +require.modules.domain = function () { + /// + /// Domains provide a way to handle multiple different IO operations as a
+ /// single group. If any of the event emitters or callbacks registered to a
+ /// domain emit an error event, or throw an error, then the domain object
+ /// will be notified, rather than losing the context of the error in the
+ /// process.on('uncaughtException') handler, or causing the program to exit
+ /// with an error code. + ///
+ /// + /// An array of timers and event emitters that have been explicitly added to the domain. + /// + + this.create = function () { + /// Returns a new Domain object. + /// + return new Domain(); + }; + this.run = function (fn) { + /// + /// Run the supplied function in the context of the domain, implicitly
+ /// binding all event emitters, timers, and lowlevel requests that are
+ /// created in that context. + ///
+ /// + }; + this.members = new Array(); + this.add = function (emitter) { + /// + /// Explicitly adds an emitter to the domain. If any event handlers
+ /// called by the emitter throw an error, or if the emitter emits an
+ /// error event, it will be routed to the domain's error event, just
+ /// like with implicit binding. + ///
+ /// + /// Timer emitter or timer to be added to the domain + /// + }; + this.remove = function (emitter) { + /// + /// The opposite of domain.add(emitter). Removes domain handling from the specified emitter + /// + /// + /// Timer emitter or timer to be added to the domain + /// + }; + this.bind = function (cb) { + /// + /// The returned function will be a wrapper around the supplied callback
+ /// function. When the returned function is called, any errors that are
+ /// thrown will be routed to the domain's error event. + ///
+ /// + /// The callback function + /// + /// + /// The bound function + /// + return new Function(); + }; + this.intercept = function (cb) { + /// + /// This method is almost identical to domain.bind(callback). However,
+ /// in addition to catching thrown errors, it will also intercept Error
+ /// objects sent as the first argument to the function. + ///
+ /// + /// The callback function + /// + /// + /// The intercepted function + /// + return new Function(); + }; + this.dispose = function() { + /// + /// The dispose method destroys a domain, and makes a best effort
+ /// attempt to clean up any and all IO that is associated with the domain.
+ /// Streams are aborted, ended, closed, and/or destroyed. Timers are cleared.
+ /// Explicitly bound callbacks are no longer called. Any error events that
+ /// are raised as a result of this are ignored. + ///
+ + }; +}; +require.modules.domain.prototype = new require.modules.events.EventEmitter(); + +require.modules.domain = new require.modules.domain(); \ No newline at end of file diff --git a/nodelib/events.js b/nodelib/events.js new file mode 100644 index 0000000..fd7db72 --- /dev/null +++ b/nodelib/events.js @@ -0,0 +1,70 @@ +/// +require.modules.events = { + EventEmitter: function () { + /// + /// When an EventEmitter instance experiences an error, + /// the typical action is to emit an 'error' event. Error events are treated as a special case in node. + /// If there is no listener for it, then the default action is to print a stack trace and exit the program. + /// + /// EventEmitter class + this.addListener = function (event, listener) { + /// + /// Adds a listener to the end of the listeners array for the specified event. + /// + /// + /// + }; + this.on = function (event, listener) { + /// + /// Adds a listener to the end of the listeners array for the specified event. + /// + /// + /// + }; + this.once = function (event, listener) { + /// + /// Adds a one time listener for the event. This listener is invoked only the next time the event is fired, + /// after which it is removed. + /// + /// + /// + }; + this.removeListener = function (event, listener) { + /// + /// Remove a listener from the listener array for the specified event. + /// + /// + /// + }; + this.removeAllListeners = function (event) { + /// + /// Removes all listeners, or those of the specified event. + /// + /// + }; + this.setMaxListeners = function (n) { + /// + /// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. + /// This is a useful default which helps finding memory leaks. + /// Obviously not all Emitters should be limited to 10. + /// This function allows that to be increased. Set to zero for unlimited. + /// + /// + }; + this.listeners = function (event) { + /// + /// Returns an array of listeners for the specified event. + /// + /// + /// + return new Array(); + }; + this.emit = function (event, arg1) { + /// + /// Execute each of the listeners in order with the supplied arguments. + /// + /// event handler. + /// event message. + }; + } +}; diff --git a/nodelib/fs.js b/nodelib/fs.js new file mode 100644 index 0000000..be8b263 --- /dev/null +++ b/nodelib/fs.js @@ -0,0 +1,611 @@ +/// +/// + +require.modules.fs = new function () { + ///File I/O is provided by simple wrappers around standard POSIX functions. All the methods have asynchronous and synchronous forms. + ///Objects returned from `fs.stat()` and `fs.lstat()` are of this type. + ///`ReadStream` is a `Readable Stream`. + ///`WriteStream` is a `Writable Stream`. + + this.rename = function (oldPath, newPath, callback) { + /// Asynchronous rename. No arguments other than a possible exception are given to the completion callback. + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.renameSync = function (oldPath, newPath) { + /// Synchronous rename. + /// + /// + }; + this.truncate = function (fd, len, callback) { + /// Asynchronous ftruncate. No arguments other than a possible exception are given to the completion callback. + /// file descriptor + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + + }; + this.truncateSync = function (fd, len) { + /// Synchronous ftruncate. + /// file descriptor + /// + }; + this.chown = function (path, uid, gid, callback) { + /// Asynchronous chown. No arguments other than a possible exception are given to the completion callback. + /// File path. + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.chownSync = function (path, uid, gid) { + /// Synchronous chown(2). No arguments other than a possible exception are given to the completion callback. + /// File path. + /// + /// + }; + this.fchown = function (fd, uid, gid, callback) { + /// Asynchronous fchown. No arguments other than a possible exception are given to the completion callback. + /// file descriptor + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.fchownSync = function (fd, uid, gid) { + /// Synchronous fchown. + /// file descriptor + /// + /// + }; + this.lchown = function (path, uid, gid, callback) { + /// Asynchronous lchown. No arguments other than a possible exception are given to the completion callback. + /// + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.lchownSync = function (path, uid, gid) { + /// Synchronous lchown. + /// + /// + /// + }; + this.chmod = function (path, mode, callback) { + /// Asynchronous chmod. No arguments other than a possible exception are given to the completion callback. + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.chmodSync = function (path, mode) { + /// Synchronous chmod. No arguments other than a possible exception are given to the completion callback. + /// + /// + }; + this.fchmod = function (fd, mode, callback) { + /// Asynchronous fchmod. No arguments other than a possible exception are given to the completion callback. + /// file descriptor + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.fchmodSync = function (fd, mode) { + /// Synchronous fchmod. + /// file descriptor + /// + }; + this.lchmod = function (path, mode, callback) { + /// Asynchronous lchmod. No arguments other than a possible exception are given to the completion callback.
+ /// Only available on Mac OS X.
+ /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.lchmodSync = function (path, mode) { + /// Asynchronous lchmod. + /// + /// + }; + this.stat = function (path, callback) { + /// Asynchronous stat. The callback gets two arguments (err, stats) where stats is a fs.Stats object. + /// + /// + /// Callback function.
+ /// The callback gets two arguments (err, stats) where stats is a fs.Stats object. + /// + /// + return new require.modules.fs.Stats(); + }; + this.lstat = function (path, callback) { + /// Asynchronous lstat. The callback gets two arguments (err, stats) where stats is a fs.Stats object.
+ /// lstat() is identical to stat(), except that if path is a symbolic link, then the link itself is stat-ed, not the file that it refers to. + ///
+ /// + /// + /// Callback function.
+ /// The callback gets two arguments (err, stats) where stats is a fs.Stats object. + /// + /// + return new require.modules.fs.Stats(); + }; + this.fstat = function (fd, callback) { + /// Synchronous lstat. + /// file descriptor + /// + /// Callback function.
+ /// The callback gets two arguments (err, stats) where stats is a fs.Stats object. + /// + /// + return new require.modules.fs.Stats(); + }; + this.statSync = function (path) { + /// Synchronous stat. Returns an instance of fs.Stats. + /// + /// + return new require.modules.fs.Stats(); + }; + this.lstatSync = function (path) { + /// Synchronous lstat. Returns an instance of fs.Stats. + /// + /// + return new require.modules.fs.Stats(); + }; + this.fstatSync = function (fd) { + /// Synchronous fstat. Returns an instance of fs.Stats. + /// file descriptor + /// + return new require.modules.fs.Stats(); + }; + this.link = function (srcpath, dstpath, callback) { + /// Asynchronous link. No arguments other than a possible exception are given to the completion callback. + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.linkSync = function (srcpath, dstpath) { + /// Synchronous link. + /// + /// + }; + this.symlink = function (destination, path, type, callback) { + /// Asynchronous symlink. No arguments other than a possible exception are given to the completion callback.
+ /// type argument can be either 'dir', 'file', or 'junction' (default is 'file').
+ /// It is only used on Windows (ignored on other platforms).
+ /// Note that Windows junction points require the destination path to be absolute.
+ /// When using 'junction', the destination argument will automatically be normalized to absolute path. + ///
+ /// + /// + /// + /// type argument can be either 'dir', 'file', or 'junction' (default is 'file').
+ /// It is only used on Windows (ignored on other platforms). + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.symlinkSync = function (destination, path, type) { + /// Synchronous symlink.
+ /// type argument can be either 'dir', 'file', or 'junction' (default is 'file').
+ /// It is only used on Windows (ignored on other platforms).
+ /// Note that Windows junction points require the destination path to be absolute.
+ /// When using 'junction', the destination argument will automatically be normalized to absolute path. + ///
+ /// + /// + /// + /// type argument can be either 'dir', 'file', or 'junction' (default is 'file').
+ /// It is only used on Windows (ignored on other platforms). + /// + }; + this.readlink = function (path, callback) { + /// Asynchronous readlink. The callback gets two arguments (err, linkString). + /// + /// + /// The callback gets two arguments (err, linkString). + /// + }; + this.readlinkSync = function (path) { + /// Synchronous readlink. + /// + /// + return new String(); + }; + this.realpath = function (path, cache, callback) { + /// + /// Asynchronous realpath. The callback gets two arguments (err, resolvedPath).
+ /// May use process.cwd to resolve relative paths.
+ ///
+ /// + /// + /// cache is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional fs.stat calls for known real paths. + /// + /// + /// The callback gets two arguments (err, resolvedPath). + /// + }; + this.realpathSync = function (path, cache) { + /// Synchronous readlink. Returns the symbolic link's string value. + /// + /// + /// cache is an object literal of mapped paths that can be used to force a specific path resolution or avoid additional fs.stat calls for known real paths. + /// + /// + /// Returns the symbolic link's string value. + /// + return new String(); + }; + this.unlink = function (path, callback) { + /// Asynchronous unlink. No arguments other than a possible exception are given to the completion callback. + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.unlinkSync = function (path) { + /// Synchronous unlink. + /// + }; + this.rmdir = function (path, callback) { + /// Asynchronous rmdir. No arguments other than a possible exception are given to the completion callback. + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.rmdirSync = function (path) { + /// Synchronous rmdir. + /// + }; + this.mkdir = function (path, mode, callback) { + /// Asynchronous mkdir. No arguments other than a possible exception are given to the completion callback. + /// + /// + /// mode defaults to 0777. + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.mkdirSync = function (path, mode) { + /// Synchronous mkdir. + /// + /// + }; + this.readdir = function (path, callback) { + /// Asynchronous readdir. Reads the contents of a directory. + /// + /// + /// + /// The callback gets two arguments (err, files) where files is an array of the names of the files in the directory excluding '.' and '..'. + /// + }; + this.readdirSync = function (path) { + /// Synchronous readdir. Returns an array of filenames excluding '.' and '..'. + /// + /// + return new Array(); + }; + this.close = function (fd, callback) { + /// Asynchronous close. No arguments other than a possible exception are given to the completion callback. + /// file descriptor + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.closeSync = function (fd) { + /// Synchronous close. No arguments other than a possible exception are given to the completion callback. + /// file descriptor + }; + this.open = function (path, flags, mode, callback) { + /// Asynchronous file open. + /// file path. + /// file open mode.drfault flag is 'r'. + /// file premission. default permission is 0666. + /// + /// callback function.
+ /// The callback is passed two arguments (err, fd), where fd is the file descriptor. + /// + }; + this.openSync = function (path, flags, mode) { + /// Synchronous open. Retuen value is file descriptor. + /// file path. + /// file open mode.drfault flag is 'r'. + /// file premission. default permission is 0666. + /// file descriptor + return new Number(); + }; + this.utimes = function (path, atime, mtime, callback) { + /// Change the file timestamps of a file referenced by the supplied file descriptor. + /// + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.utimesSync = function (path, atime, mtime) { + /// Change the file timestamps of a file referenced by the supplied file descriptor. + /// + /// + /// + }; + this.futimes = function (fd, atime, mtime, callback) { + /// Change the file timestamps of a file referenced by the supplied file descriptor. + /// file descriptor + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.futimesSync = function (fd, atime, mtime) { + /// Change the file timestamps of a file referenced by the supplied file descriptor. + /// file descriptor + /// + /// + }; + this.fsync = function (fd, callback) { + /// Asynchronous fsync. No arguments other than a possible exception are given to the completion callback. + /// file descriptor + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.fsyncSync = function (fd) { + /// Synchronous fsync. + /// file descriptor + }; + this.write = function (fd, buffer, offset, length, position, callback) { + /// Write buffer to the file specified by fd. + /// file descriptor + /// + /// offset and length determine the part of the buffer to be written. + /// >offset and length determine the part of the buffer to be written. + /// + /// position refers to the offset from the beginning of the file where this data should be written.
+ /// If position is null, the data will be written at the current position. + /// + /// + /// The callback will be given three arguments (err, written, buffer) where written specifies how many bytes were written from buffer. + /// + }; + this.writeSync = function (fd, buffer, ofthiset, length, position) { + /// Synchronous version of fs.write(). Returns the number of bytes written. + /// file descriptor + /// + /// offset and length determine the part of the buffer to be written. + /// >offset and length determine the part of the buffer to be written. + /// + /// position refers to the offset from the beginning of the file where this data should be written.
+ /// If position is null, the data will be written at the current position. + /// + /// Returns the number of bytes written. + return new Number(); + }; + this.read = function (fd, buffer, ofthiset, length, position, callback) { + /// Read data from the file specified by fd. + /// file descriptor + /// buffer is the buffer that the data will be written to. + /// offset is offset within the buffer where reading will start. + /// length is an integer specifying the number of bytes to read. + /// + /// position is an integer specifying where to begin reading from in the file.
+ /// If position is null, data will be read from the current file position. + /// + /// + /// The callback is given the three arguments, (err, bytesRead, buffer). + /// + }; + this.readSync = function (fd, buffer, ofthiset, length, position) { + /// Synchronous version of fs.read. Returns the number of bytesRead. + /// file descriptor + /// buffer is the buffer that the data will be written to. + /// offset is offset within the buffer where reading will start. + /// length is an integer specifying the number of bytes to read. + /// + /// position is an integer specifying where to begin reading from in the file.
+ /// If position is null, data will be read from the current file position. + /// + /// number of bytesRead. + return new Number(); + }; + this.readFile = function (filename, encoding, callback) { + /// Asynchronously reads the entire contents of a file. + /// file path. + /// encoding argument. It defaults to 'utf8'.Description + /// + /// Callback function.
+ /// The callback is passed two arguments (err, data), where data is the contents of the file. + /// + }; + this.readFileSync = function (filename, encoding) { + /// Synchronous version of fs.readFile. + /// file path. + /// encoding argument. It defaults to 'utf8'.Description + /// the contents of the file. + return new Object(); + }; + this.writeFile = function (filename, data, encoding, callback) { + /// + /// Asynchronously writes data to a file, replacing the file if it already exists. data can be a string or a buffer. + /// + /// file path. + /// buffer or string. + /// encoding argument. It defaults to 'utf8'.Description + /// callback function. + }; + this.writeFileSync = function (filename, data, encoding) { + /// The synchronous version of fs.writeFile. + /// file path. + /// buffer or string. + /// encoding argument. It defaults to 'utf8'.Description + }; + this.appendFile = function (filename, data, encoding, callback) { + /// Asynchronously append data to a file, creating the file if it not yet exists.
+ /// data can be a string or a buffer.
+ /// The encoding argument is ignored if data is a buffer.
+ /// + /// + /// + /// + /// Callback function.
+ /// The callback will be given a arguments(err). + /// + }; + this.appendFileSync = function (filename, data, encoding) { + /// Synchronously append data to a file, creating the file if it not yet exists. + /// + /// + /// + }; + this.watchFile = function (filename, options, listener) { + /// Asynchronously writes data to a file, replacing the file if it already exists. data can be a string or a buffer.
+ /// The encoding argument is ignored if data is a buffer. It defaults to 'utf8'.
+ /// + /// + /// + }; + this.unwatchFile = function (filename) { + /// + /// top watching for changes on filename.
+ /// If listener is specified, only that particular listener is removed.
+ /// Otherwise, all listeners are removed and you have effectively stopped watching filename. + ///
+ /// + }; + this.watch = function (filename, options, listener) { + /// + /// Watch for changes on filename, where filename is either a file or a directory. The returned object is a fs.FSWatcher. + /// + /// + /// The options if provided should be an object containing a boolean member persistent,
+ /// which indicates whether the process should continue to run as long as files are being watched.
+ /// The default is { persistent: true }. + /// + /// + /// + /// The listener callback gets two arguments (event, filename). event is either 'rename' or 'change', and filename is the name of the file which triggered the event. + /// + /// + return new require.modules.fs.FSWatcher(); + }; + this.exists = function (path, callback) { + /// Test whether or not the given path exists by checking with the file system. + /// + /// + /// Then call the callback argument with either true or false. + /// + }; + this.existsSync = function (path) { + /// Test whether or not the given path exists by checking with the file system. + /// + /// + return new Boolean(); + }; + this.createReadStream = function (path, options) { + /// Returns a new ReadStream object. + /// File path. + /// + /// Options can include start and end values to read a range of bytes from the file instead of the entire file.
+ /// Both start and end are inclusive and start at 0. The encoding can be 'utf8', 'ascii', or 'base64'.
+ /// bufferSize sets up the number of bytes read at a time. Default buffer size is 64KB. + /// + /// New ReadStream object + return new require.modules.fs.ReadStream(); + }; + this.createWriteStream = function (path, options) { + /// Returns a new WriteStream object. + /// File path. + /// + /// Options may also include a start option to allow writing data at some position past the beginning of the file.
+ /// Modifying a file rather than replacing it may require a flags mode of r+ rather than the default mode w.
+ /// The encoding can be 'utf8', 'ascii', or 'base64'. + /// The mode can set file permission mode. + /// + /// New WriteStream object + return new require.modules.fs.WriteStream(); + }; +} + +require.modules.fs.Stats = function () { + /// Objects returned from fs.stat(), fs.lstat() and fs.fstat() and their synchronous counterparts are of this type. + this.isFile = function () { + /// + return new Boolean(); + }; + this.isDirectory = function () { + /// + return new Boolean(); + }; + this.isBlockDevice = function () { + /// + return new Boolean(); + }; + this.isCharacterDevice = function () { + /// + return new Boolean(); + }; + this.isSymbolicLink = function () { + /// + return new Boolean(); + }; + this.isFIFO = function () { + /// + return new Boolean(); + }; + this.isSocket = function () { + /// + return new Boolean(); + }; +} + +require.modules.fs.ReadStream = function () { + /// ReadStream is a Readable Stream. + /// + return new Stream(); +} + +require.modules.fs.WriteStream = function () { + /// WriteStream is a Writable Stream. + /// + return new Stream(); +} + +require.modules.fs.FSWatcher = function () { + this.close = function () { + /// Stop watching for changes on the given fs.FSWatcher. + }; +} diff --git a/nodelib/http.js b/nodelib/http.js new file mode 100644 index 0000000..915d990 --- /dev/null +++ b/nodelib/http.js @@ -0,0 +1,338 @@ +/// +/// +/// + +require.modules.http = new function () { + /// + /// To use the HTTP server and client one must require('http'). + /// + /// + /// A collection of all the standard HTTP response status codes, and the
+ /// short description of each. + ///
+ + + this.STATUS_CODES; + this.createServer = function (requestListener) { + /// + /// The requestListener is a function which is automatically added to the 'request' event. + /// + /// + /// + return new require.modules.http.Server(); + }; + // this.createClient = function (port, host) {}; //deprecated + this.request = function (options, callback) { + /// + /// Node maintains several connections per server to make HTTP requests. + /// This function allows one to transparently issue requests. + /// + /// Option Object or String + /// + }; + this.get = function (options, callback) { + /// + /// Since most requests are GET requests without bodies, Node provides this convenience method. + /// The only difference between this method and http.request() is that it sets the method + /// to GET and calls req.end() automatically. + /// + /// + /// + }; + + this.globalAgent = new require.modules.http.Agent(); +}; + +require.modules.http.Server = function () { + /// HTTP Server. + /// Limits maximum incoming headers count, equal to 1000 by default. + this.listen = function (port, hostname, backlog, callback) { + /// Begin accepting connections on the specified port and hostname. + /// + /// + /// If the hostname is omitted, the server will accept connections directed to any IPv4 address (INADDR_ANY). + /// + /// + /// Backlog is the maximum length of the queue of pending connections. + /// + /// + }; + //this.listen = function (path, callback) { + // /// + // /// + //}; + this.close = function (cb) { + /// Stops the server from accepting new connections. + /// + }; + this.maxHeadersCount = new Number(); + +}; +require.modules.http.Server.prototype = new Events.EventEmitter(); + +require.modules.http.ServerRequest = function () { + /// + /// This object is created internally by a HTTP server -- not by the user --
+ /// and passed as the first argument to a 'request' listener. + ///
+ /// + /// The request method as a string. Read only. Example: 'GET', 'DELETE'. + /// + /// + /// The request method as a string. Read only. Example: 'GET', 'DELETE'. + /// + /// + /// Request URL string. This contains only the URL that is present in the actual HTTP request. + /// + /// + /// Read only map of header names and values. Header names are lower-cased. + /// + /// + /// Read only; HTTP trailers (if present). Only populated after the 'end' event. + /// + /// + /// The HTTP protocol version as a string. Read only. Examples: '1.1', '1.0'. Also request.
+ /// httpVersionMajor is the first integer and request.httpVersionMinor is the second. + ///
+ /// + /// With HTTPS support, use request.connection.verifyPeer() and + /// request.connection.getPeerCertificate() to obtain the client's authentication details. + /// + + //Event: 'data' + //Event: 'end' + //Event: 'close' + this.method = new String(); + this.url = new String(); + this.headers = new Object(); + this.trailers = new Object(); + this.httpVersion = new Number(); + this.httpVersionMajor = new Number(); + this.httpVersionMinor = new Number(); + this.setEncoding = function (encoding) { + /// Set the encoding for the request body. See stream.setEncoding() for more information. + /// + }; + this.pause = function() { + /// Pauses request from emitting events. Useful to throttle back an upload. + }; + this.resume = function() { + /// + /// Resumes a paused request. + /// + }; + this.connection = new Net.Socket(); +}; +require.modules.http.ServerRequest.prototype = new Stream(); + +require.modules.http.ServerResponse = function () { + /// + /// This object is created internally by a HTTP server--not by the user. + /// It is passed as the second parameter to the 'request' event. + /// + /// + /// When using implicit headers (not calling response.writeHead() explicitly), + /// this property controls the status code that will be sent to the client when the headers get flushed. + /// + /// + /// When true, the Date header will be automatically generated and sent + /// in the response if it is not already present in the headers. Defaults to true. + /// + + + //Event: 'close' + this.writeContinue = function() { + /// + /// Sends a HTTP/1.1 100 Continue message to the client, + /// indicating that the request body should be sent. + /// See the 'checkContinue' event on Server. + /// + }; + this.writeHead = function(statusCode, reasonPhrase, headers) { + /// + /// Sends a response header to the request. + /// The status code is a 3-digit HTTP status code, like 404. The last argument, headers, + /// are the response headers. Optionally one can give a human-readable reasonPhrase as + /// the second argument. + /// + /// + /// + /// + }; + this.statusCode = new Number(); + this.setHeader = function (name, value) { + /// + /// Sets a single header value for implicit headers. + /// If this header already exists in the to-be-sent headers, its value will be replaced. + /// Use an array of strings here if you need to send multiple headers with the same name. + /// + /// + /// + }; + this.sendDate = new Boolean(); + this.getHeader = function (name) { + /// + /// Reads out a header that's already been queued but not sent to the client. + /// Note that the name is case insensitive. This can only be called before headers get implicitly flushed. + /// + /// + /// + return new String(); + }; + this.removeHeader = function (name) { + /// Removes a header that's queued for implicit sending. + /// + }; + this.write = function (chunk, encoding) { + /// + /// If this method is called and response.writeHead() has not been called, + /// it will switch to implicit header mode and flush the implicit headers. + /// + /// + /// + }; + this.addTrailers = function (headers) { + /// + /// This method adds HTTP trailing headers (a header but at the end of the message) to the response. + /// + /// + }; + this.end = function (data, encoding) { + /// + /// Node maintains several connections per server to make HTTP requests. + /// This function allows one to transparently issue requests. + /// + /// + /// + }; +}; +require.modules.http.ServerResponse.prototype = new Stream(); + +require.modules.http.Agent = function () { + /// + /// Previously, a single agent instance helped pool for a single host+port. + /// The current implementation now holds sockets for any number of hosts.
+ /// The current HTTP Agent also defaults client requests to using Connection:keep-alive. + /// If no pending HTTP requests are waiting on a socket to become free the socket is closed. This means that node's pool has the benefit of keep-alive when under load but still does not require developers to manually close the HTTP clients using keep-alive. + ///
+ /// + /// By default set to 5. Determines how many concurrent sockets the agent can have open per host. + /// + /// + /// An object which contains arrays of sockets currently in use by the Agent. Do not modify. + /// + /// + /// An object which contains queues of requests that have not yet been assigned to sockets. Do not modify. + /// + + this.maxSockets = new Number(); + this.sockets = new Array(); + this.requests = new Object(); +}; + +require.modules.http.ClientRequest = function () { + /// + /// This object is created internally and returned from http.request(). + /// It represents an in-progress request whose header has already been queued. + /// The header is still mutable using the setHeader(name, value), + /// getHeader(name), removeHeader(name) API. + /// The actual header will be sent along with the first data chunk or when closing the connection. + /// + + //Event 'response' + //Event: 'socket' + //Event: 'connect' + //Event: 'upgrade' + //Event: 'continue' + this.write = function (chunk, encoding) { + /// + /// Sends a chunk of the body. + /// By calling this method many times, the user can stream a request body + /// to a server--in that case it is suggested to use + /// the ['Transfer-Encoding', 'chunked'] header line when creating the request. + /// + /// + /// + }; + this.end = function (data, encoding) { + /// + /// Finishes sending the request. + /// If any parts of the body are unsent, + /// it will flush them to the stream. If the request is chunked, + /// this will send the terminating '0\r\n\r\n'. + /// + /// + /// + }; + this.abort = function() { + /// + /// Aborts a request. (New since v0.3.8.) + /// + }; + this.setTimeout = function (timeout, callback) { + /// + /// Once a socket is assigned to this request and is connected socket.setTimeout() will be called. + /// + /// + /// + }; + this.setNoDelay = function (noDelay) { + /// + /// Once a socket is assigned to this request and is connected socket.setNoDelay() will be called. + /// + /// + }; + this.setSocketKeepAlive = function (enable, initialDelay) { + /// + /// Once a socket is assigned to this request and is connected socket.setKeepAlive() will be called. + /// + /// + /// + }; +}; +require.modules.http.ClientRequest.prototype = new Stream(); + +require.modules.http.ClientResponse = function () { + /// + /// This object is created when making a request with http.request(). + /// It is passed to the 'response' event of the request object. + /// + /// + /// The 3-digit HTTP response status code. E.G. 404. + /// + /// + /// The HTTP version of the connected-to server. + /// Probably either '1.1' or '1.0'. Also response.httpVersionMajor is + /// the first integer and response.httpVersionMinor is the second. + /// + /// + /// The response headers object. + /// + /// + /// The response trailers object. Only populated after the 'end' event. + /// + + //Event: 'data' + //Event: 'end' + //Event: 'close' + this.statusCode = new Number(); + this.httpVersion = new Number(); + this.headers = new Object(); + this.trailers = new Object(); + this.setEncoding = function (encoding) { + /// Set the encoding for the response body. + /// + }; + + this.pause = function() { + /// + /// Pauses response from emitting events. Useful to throttle back a download. + /// + }; + this.resume = function() { + /// + /// Resumes a paused response. + /// + }; +}; +require.modules.http.ClientResponse.prototype = new Stream(); diff --git a/nodelib/https.js b/nodelib/https.js new file mode 100644 index 0000000..3829a86 --- /dev/null +++ b/nodelib/https.js @@ -0,0 +1,49 @@ +/// +/// + +require.modules.https = new function () { + /// HTTPS is the HTTP protocol over TLS/SSL. In Node this is implemented as a separate module. + this.createServer = function (options, requestListener) { + /// + /// Returns a new HTTPS web server object. + /// The options is similar to tls.createServer(). + /// The requestListener is a function which is automatically added to the 'request' event. + /// + /// + /// + /// + return new require.modules.https.Server(); + }; + this.request = function (options, callback) { + /// + /// Makes a request to a secure web server. + /// + /// + /// + /// + return new require.modules.http.ClientRequest(); + }; + this.get = function (options, callback) { + /// Like http.get() but for HTTPS. + /// + /// + /// + return new require.modules.http.ClientRequest(); + }; + this.globalAgent = new require.modules.https.Agent(); +}; + +require.modules.https.Server = function() { + /// This class is a subclass of tls.Server and emits events same as http.Server. +}; +require.modules.https.Server.prototype = new TLS.Server(); + +require.modules.https.Agent = function() { + /// + /// An Agent object for HTTPS similar to http.Agent. See https.request() for more information. + /// + +}; + +require.modules.https.Agent.prototype = new require.modules.http.Agent(); + diff --git a/nodelib/lodash.js b/nodelib/lodash.js new file mode 100644 index 0000000..f60cf23 --- /dev/null +++ b/nodelib/lodash.js @@ -0,0 +1,4 @@ +/// +/// + +require.modules.lodash = module.exports; \ No newline at end of file diff --git a/nodelib/mocha.js b/nodelib/mocha.js new file mode 100644 index 0000000..5690cf4 --- /dev/null +++ b/nodelib/mocha.js @@ -0,0 +1,43 @@ +function describe(name, tests) { + /// Describes a suit of tests to run + /// The name of the test suit + /// A function to be called to execute the tests + +} + +describe.skip = describe; +describe.only = describe; + +function it(should, test) { + /// Describes a test that should pass + /// A description of what the code should do to pass the test + /// A function to be called to execute the test + +} + +it.skip = it; +it.only = it; + +function before(something) { + /// Execute a function before the first test in this suit begins + /// The function to execute + +} + +function after(something) { + /// Execute a function after the last test in this suit ends + /// The function to execute + +} + +function beforeEach(something) { + /// Execute a function before each test in this suit begins + /// The function to execute + +} + +function afterEach(something) { + /// Execute a function after each test in this suit ends + /// The function to execute + +} \ No newline at end of file diff --git a/nodelib/module.js b/nodelib/module.js new file mode 100644 index 0000000..4c23d96 --- /dev/null +++ b/nodelib/module.js @@ -0,0 +1,14 @@ + +var Module = function () { + this.exports = new Object(); + this.require = function (id) { + /// + /// + return new Object(); + }; + this.id = new String(); + this.filename = new String(); + this.loaded = new Boolean(); + this.parent = new Object(); + this.children = new Object(); +} \ No newline at end of file diff --git a/nodelib/net.js b/nodelib/net.js new file mode 100644 index 0000000..6e374e0 --- /dev/null +++ b/nodelib/net.js @@ -0,0 +1,266 @@ +/// + +require.modules.net = new function () { + this.createServer = function (options, connectionListener) { + /// Creates a new TCP server. + /// + /// + /// The connectionListener argument is automatically set as a listener for the 'connection' event. + /// + /// + return new require.modules.net.Server(); + }; + this.connect = function (options, connectionListener) { + /// Constructs a new socket object and opens the socket to the given location. When the socket is established, the 'connect' event will be emitted. + /// + /// For TCP sockets, options argument should be an object which specifies:
+ /// port: Port the client should connect to (Required). exp. {port: 8124}
+ /// host: Host the client should connect to. Defaults to 'localhost'.
+ /// localAddress: Local interface to bind to for network connections. + /// + /// + /// The connectListener parameter will be added as an listener for the 'connect' event. + /// + /// + return new require.modules.net.Socket(); + }; + this.createConnection = function (options, connectionListener) { + /// Constructs a new socket object and opens the socket to the given location. When the socket is established, the 'connect' event will be emitted. + /// + /// For TCP sockets, options argument should be an object which specifies:
+ /// port: Port the client should connect to (Required). exp. {port: 8124}
+ /// host: Host the client should connect to. Defaults to 'localhost'.
+ /// localAddress: Local interface to bind to for network connections. + /// + /// + /// The connectListener parameter will be added as an listener for the 'connect' event. + /// + /// + return new require.modules.net.Socket(); + }; + this.isIP = function (input) { + /// Tests if input is an IP address. Returns 0 for invalid strings, returns 4 for IP version 4 addresses, and returns 6 for IP version 6 addresses. + /// + /// + return new Boolean(); + }; + this.isIPv4 = function (input) { + /// Returns true if input is a version 4 IP address, otherwise returns false. + /// + /// + return new Boolean(); + }; + this.isIPv6 = function (input) { + /// Returns true if input is a version 6 IP address, otherwise returns false. + /// + /// + return new Boolean(); + }; +}; + + + + +require.modules.net.Socket = function (options) { + /// + /// Construct a new socket object. + /// + /// + /// 'fd' allows you to specify the existing file descriptor of socket.
+ /// 'type' specified underlying protocol. It can be 'tcp4', 'tcp6', or 'unix'.
+ /// 'allowHalfOpen' If allowHalfOpen is true, then the socket won't automatically send a FIN packet when the other end of the socket sends a FIN packet. The socket becomes non-readable, but still writable. You should call the end() method explicitly. See 'end' event for more information. + /// + /// `net.Socket` has the property that `socket.write()` always works. This is to help users get up and running quickly. The computer cannot always keep up with the amount of data that is written to a socket - the network connection simply might be too slow. Node will internally queue up the data written to a socket and send it out over the wire when it is possible. (Internally it is polling on the socket's file descriptor for being writable). The consequence of this internal buffering is that memory may grow. This property shows the number of characters currently buffered to be written. (Number of characters is approximately equal to the number of bytes to be written, but the buffer may contain strings, and the strings are lazily encoded, so the exact number of bytes is not known.) + /// The string representation of the remote IP address. For example, `'74.125.127.100'` or `'2001:4860:a005::68'`. + /// The numeric representation of the remote port. For example, `80` or `21`. + /// The amount of received bytes. + /// The amount of bytes sent. + /// + /// + + + this.connect = function (port, host, connectListener) { + /// + /// Opens the connection for a given socket.
+ /// If port and host are given, then the socket will be opened as a TCP socket, if host is omitted, localhost will be assumed.
+ /// If a path is given, the socket will be opened as a unix socket to that path.
+ /// Normally this method is not needed, as net.createConnection opens the socket.
+ /// Use this only if you are implementing a custom Socket or if a Socket is closed and you want to reuse it to connect to another server.
+ /// This function is asynchronous. When the 'connect' event is emitted the socket is established. If there is a problem connecting, the 'connect' event will not be emitted, the 'error' event will be emitted with the exception. + ///
+ /// port number. + /// path + /// + /// The connectListener parameter will be added as an listener for the 'connect' event. + /// + }; + this.setEncoding = function (encoding) { + /// Set the encoding for the socket as a Readable Stream. See stream.setEncoding() for more information. + /// + }; + this.write = function (data, encoding, callback) { + /// + /// Sends data on the socket. The second parameter specifies the encoding in the case of a string--it defaults to UTF8 encoding.
+ /// Returns true if the entire data was flushed successfully to the kernel buffer.
+ /// Returns false if all or part of the data was queued in user memory.
+ /// 'drain' will be emitted when the buffer is again free. + ///
+ /// data.(buffer) + /// exp. 'utf8', 'base64', null(raw buffer).. + /// + /// The optional callback parameter will be executed when the data is finally written out - this may not be immediately. + /// + }; + this.end = function (data, encoding) { + /// + /// Half-closes the socket. i.e., it sends a FIN packet. It is possible the server will still send some data.
+ /// If data is specified, it is equivalent to calling socket.write(data, encoding) followed by socket.end(). + ///
+ /// data.(buffer) + /// exp. 'utf8', 'base64', null(raw buffer).. + }; + this.destroy = function () { + /// Ensures that no more I/O activity happens on this socket. Only necessary in case of errors (parse error or so). + }; + this.pause = function () { + /// Pauses the reading of data. That is, 'data' events will not be emitted. Useful to throttle back an upload. + }; + this.resume = function () { + /// Resumes reading after a call to pause(). + }; + this.setTimeout = function (timeout, callback) { + /// Sets the socket to timeout after timeout milliseconds of inactivity on the socket. By default net.Socket do not have a timeout. + /// milli second.
If timeout is 0, then the existing idle timeout is disabled. + /// + /// The optional callback parameter will be added as a one time listener for the 'timeout' event. + /// + }; + this.setNoDelay = function (noDelay) { + /// Disables the Nagle algorithm. + /// + /// By default TCP connections use the Nagle algorithm, they buffer data before sending it off.
+ /// Setting true for noDelay will immediately fire off data each time socket.write() is called. noDelay defaults to true. + /// + }; + this.setKeepAlive = function (enable, initialDelay) { + /// Enable/disable keep-alive functionality, and optionally set the initial delay before the first keepalive probe is sent on an idle socket. + /// default : false + /// + /// Set initialDelay (in milliseconds) to set the delay between the last data packet received and the first keepalive probe.
+ /// Setting 0 for initialDelay will leave the value unchanged from the default (or previous) setting. Defaults to 0. + /// + }; + this.address = function () { + /// Returns the bound address, the address family name and port of the socket as reported by the operating system.
+ /// Returns an object with three properties, e.g. { port: 12346, family: 'IPv4', address: '127.0.0.1' }
+ /// + return new Object(); + }; + //net.Socket has the property that socket.write() always works. + this.bufferSize = new Number(); + //The string representation of the remote IP address. For example, '74.125.127.100' or '2001:4860:a005::68'. + this.remoteAddress = new String(); + //The numeric representation of the remote port. For example, 80 or 21. + this.remotePort = new Number(); + //The amount of received bytes. + this.bytesRead = new Number(); + //The amount of bytes sent. + this.bytesWritten = new Number(); + + // -- eventEmitter -- + this.on = function (event, listener) { + /// + /// event method. + /// + /// + /// event name.
+ /// 'connect', 'data', 'end', 'timeout', 'drain', 'error', 'close' + /// + /// listenr function. + }; + this.addListener = function (event, listener) { + ///Adds a listener to the end of the listeners array for the specified event. + ///event name. + ///listener function. + }; + this.once = function(event, listener) { + /// + /// Adds a **one time** listener for the event. + /// This listener is invoked only the next time the event is fired, after which it is removed. + /// + ///event name. + ///listener function. + }; + this.removeListener = function(event, listener) { + ///Remove a listener from the listener array for the specified event. **Caution**: changes array indices in the listener array behind the listener. + ///event name. + ///listener function. + }; + this.removeAllListeners = function(event) { + ///Removes all listeners, or those of the specified event. + ///event name. + }; + this.setMaxListeners = function(n) { + ///By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default which helps finding memory leaks. Obviously not all Emitters should be limited to 10. This function allows that to be increased. Set to zero for unlimited. + /// + }; + this.listeners = function(event) { + ///Returns an array of listeners for the specified event. This array can be manipulated, e.g. to remove listeners. + ///event name. + }; + this.emit = function(event, arg1, arg2) { + ///Execute each of the listeners in order with the supplied arguments. + ///event name. + /// + /// + }; + + + if (this instanceof Net.Socket) + return new Net.Socket(); + else + return this; +}; + + +require.modules.net.Server = function () { + this.listen = function (port, host, backlog, listeningListener) { + /// + /// Begin accepting connections on the specified port and host. + /// + /// Port Number. A port value of zero will assign a random port. + /// If the host is omitted, the server will accept connections directed to any IPv4 address (INADDR_ANY). + /// + /// Backlog is the maximum length of the queue of pending connections. + /// The actual length will be determined by your OS through sysctl settings such as tcp_max_syn_backlog and somaxconn on linux. + /// The default value of this parameter is 511 (not 512). + /// + /// + /// This function is asynchronous. When the server has been bound, 'listening' event will be emitted. + /// The last parameter callback will be added as an listener for the 'listening' event. + /// + /// Set this property to reject connections when the server's connection count gets high. + /// The number of concurrent connections on the server. + }; + this.close = function (cb) { + /// + }; + this.address = function () { + /// + return { port: 0, family: '', address: '' }; + }; + this.maxConnections = new Number(); + this.connections = new Number(); + this.on = function (event, listener) { + /// + /// event method. + /// + /// + /// event name.
+ /// 'listening', 'connection', 'close', 'error' + /// + /// listenr function. + }; +}; + +require.modules.net.Server.prototype = new Net.Socket(); diff --git a/nodelib/node.js b/nodelib/node.js new file mode 100644 index 0000000..43d0dd0 --- /dev/null +++ b/nodelib/node.js @@ -0,0 +1,94 @@ +/// node.js 0.8.18 + +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// + +var global = new Object(); +var process = new Process(); +var console = new Console(); +var module = new Module(); +var exports = module.exports; + +// Allows req to autocomplete to require(). +delete requestAnimationFrame; + +var __filename = new String(); +var __dirname = new String(); +var setTimeout = function (cb, ms) { + /// + /// To schedule execution of a one-time callback after delay milliseconds.
+ /// Returns a timeoutId for possible use with clearTimeout(). Optionally
+ /// you can also pass arguments to the callback. + ///
+ /// + /// Callback function. + /// + /// + /// Dlay Time(ms) + /// + /// timeoutId + + return new Number(); +}; +var clearTimeout = function (t) { + /// + /// Prevents a timeout from triggering. + /// + /// + /// timeoutId + /// +}; +var setInterval = function (cb, ms) { + /// + /// To schedule the repeated execution of callback every delay milliseconds.
+ /// Returns a intervalId for possible use with clearInterval(). Optionally
+ /// you can also pass arguments to the callback. + ///
+ /// + /// Callback function. + /// + /// + /// Dlay Time(ms) + /// + /// timeoutId + + return new Number(); +}; +var clearInterval = function (t) { + /// + /// Prevents a timeout from triggering. + /// + /// + /// timeoutId + /// +}; diff --git a/nodelib/os.js b/nodelib/os.js new file mode 100644 index 0000000..5b5a761 --- /dev/null +++ b/nodelib/os.js @@ -0,0 +1,76 @@ +require.modules.os = new function () { + /// + /// Provides a few basic operating-system related utility functions. + /// Use require('os') to access this module. + /// + this.tmpdir = function() { + /// + /// Returns the operating system's default directory for temp files. + /// + /// + return new String; + }; + this.hostname = function () { + /// Returns the hostname of the operating system. + /// + return new String(); + }; + this.type = function () { + /// Returns the operating system name. + /// + return new String(); + }; + this.platform = function () { + /// Returns the operating system platform. + /// + return new String(); + }; + this.arch = function () { + /// Returns the operating system CPU architecture. + /// + return new String(); + }; + this.release = function () { + /// Returns the operating system release. + /// + return new String(); + }; + this.uptime = function () { + /// Returns the system uptime in seconds. + /// + return new Number(); + }; + this.loadavg = function () { + /// Returns an array containing the 1, 5, and 15 minute load averages. + /// + return new Array(); + }; + this.totalmem = function () { + /// Returns the total amount of system memory in bytes. + /// + return new Number(); + }; + this.freemem = function () { + /// Returns the amount of free system memory in bytes. + /// + return new Number(); + }; + this.cpus = function () { + /// + /// Returns an array of objects containing information about each
+ /// CPU/core installed: model, speed (in MHz), and times (an object
+ /// containing the number of CPU ticks spent in: user, nice, sys, idle,
+ /// and irq). + ///
+ /// + return new Object(); + }; + this.networkInterfaces = function () { + /// + /// Get a list of network interfaces + /// + /// + return new Object(); + }; + this.EOL = new String(); +}; diff --git a/nodelib/path.js b/nodelib/path.js new file mode 100644 index 0000000..9b8f617 --- /dev/null +++ b/nodelib/path.js @@ -0,0 +1,101 @@ +require.modules.path = new function () { + /// + /// This module contains utilities for handling and transforming file
+ /// paths. Almost all these methods perform only string transformations.
+ /// The file system is not consulted to check whether paths are valid. + ///
+ /// + /// The platform-specific file separator. '\\' or '/'. + /// + + this.normalize = function (p) { + /// + /// Normalize a string path, taking care of '..' and '.' parts.
+ /// When multiple slashes are found, they're replaced by a single one;
+ /// when the path contains a trailing slash, it is preserved. On
+ /// windows backslashes are used. + ///
+ /// + /// + return new String(); + }; + this.join = function (path1, path2, pathX) { + /// + /// Join all arguments together and normalize the resulting path.
+ /// Non-string arguments are ignored. + ///
+ /// + /// + /// + /// + return new String(); + }; + this.resolve = function (from, to) { + /// + /// Resolves to to an absolute path. + /// + /// + /// + /// + return new String(); + }; + this.relative = function (from, to) { + /// + /// Solve the relative path from from to to. + /// + /// + /// + /// + return new String(); + }; + this.dirname = function (p) { + /// + /// Return the directory name of a path. Similar to the Unix dirname command. + /// + /// + /// + return new String(); + }; + this.basename = function (p, ext) { + /// + /// Return the last portion of a path. Similar to the Unix basename command. + /// + /// + /// + /// + return new String(); + }; + this.extname = function (p) { + /// + /// Return the extension of the path, from the last '.' to end of
+ /// string in the last portion of the path. If there is no '.' in the
+ /// last portion of the path or the first character of it is '.', then
+ /// it returns an empty string. + ///
+ /// + /// + return new String(); + }; + + /// + /// The platform-specific file separator. '\\' or '/'. + /// + /// + this.sep = new String(); + + this.basename = function (p, ext) { + /// + /// Return the last portion of a path. Similar to the Unix basename command. + /// + /// + /// + /// + return new String(); + }; + + /// + /// The platform-specific path delimiter, ; or ':'. + /// + /// + this.delimiter = new String(); +}; diff --git a/nodelib/process.js b/nodelib/process.js new file mode 100644 index 0000000..86f37db --- /dev/null +++ b/nodelib/process.js @@ -0,0 +1,186 @@ +/// +/// +/// + +require.modules.process = function () { + /// + /// The process object is a global object and can be accessed from anywhere. It is an instance of EventEmitter. + /// + /// + /// A Writable Stream to stdout. + /// + /// + /// A writable stream to stderr. + /// + /// + /// A Readable Stream for stdin. The stdin stream is paused by default, so
+ /// one must call process.stdin.resume() to read from it. + ///
+ /// + /// An array containing the command line arguments. The first element will
+ /// be 'node', the second element will be the name of the JavaScript file.
+ /// The next elements will be any additional command line arguments. + ///
+ /// + /// This is the absolute pathname of the executable that started the process. + /// + /// + /// An object containing the user environment. + /// + /// + /// A compiled-in property that exposes NODE_VERSION. + /// + /// + /// A property exposing version strings of node and its dependencies. + /// + /// + /// An Object containing the JavaScript representation of the configure
+ /// options that were used to compile the current node executable. This is
+ /// the same as the "config.gypi" file that was produced when running
+ /// the ./configure script. + ///
+ /// + /// AThe PID of the process. + /// + /// + /// Getter/setter to set what is displayed in 'ps'. + /// + /// + /// What processor architecture you're running on: 'arm', 'ia32', or 'x64'. + /// + /// + /// What platform you're running on: 'darwin', 'freebsd', 'linux', 'sunos' or 'win32' + /// + + this.stdout = new Stream(); + this.stderr = new Stream(); + this.stdin = new Stream(); + this.argv = new Array(); + this.execPath = new String(); + this.abort = function() { + /// + /// This causes node to emit an abort. This will cause node to exit and generate a core file. + /// + }; + this.chdir = function (directory) { + /// + /// Changes the current working directory of the process or throws an exception if that fails. + /// + /// + }; + this.cwd = function () { + /// + /// Returns the current working directory of the process. + /// + /// + return new String(); + }; + this.env = new String(); + this.exit = function (code) { + /// + /// Ends the process with the specified code. If omitted, exit uses the 'success' code 0. + /// + /// + }; + this.getgid = function () { + /// + /// Gets the group identity of the process. (See getgid.) This is the
+ /// numerical group id, not the group name. + /// Note: this function is only available on POSIX platforms (i.e. not Windows) + ///
+ /// + return new Number(); + }; + this.setgid = function (id) { + /// + /// Sets the group identity of the process. (See setgid.) This
+ /// accepts either a numerical ID or a groupname string. If a groupname
+ /// is specified, this method blocks while resolving it to a numerical ID. + /// Note: this function is only available on POSIX platforms (i.e. not Windows) + ///
+ /// + }; + this.getuid = function () { + /// + /// Gets the user identity of the process. (See getuid.) This is the
+ /// numerical userid, not the username.
+ /// Note: this function is only available on POSIX platforms (i.e. not Windows) + ///
+ /// + return new Number(); + }; + this.setuid = function (id) { + /// + ///Sets the user identity of the process. (See setuid(2).) This accepts
+ /// either a numerical ID or a username string. If a username is
+ /// specified, this method blocks while resolving it to a numerical ID.
+ /// Note: this function is only available on POSIX platforms (i.e. not Windows) + ///
+ /// + }; + this.version = new Number(); + this.versions = new Object(); + this.config = new Object(); + //this.installPrefix = new String(); + this.kill = function (pid, signal) { + /// + /// Send a signal to a process. pid is the process id and signal is the
+ /// string describing the signal to send. Signal names are strings like
+ /// 'SIGINT' or 'SIGUSR1'. If omitted, the signal will be 'SIGTERM'. See
+ /// kill for more information. + ///
+ /// + /// + }; + this.pid = new Number(); + this.title = new String(); + this.arch = new String(); + this.platform = new String(); + this.memoryUsage = function () { + /// + /// Returns an object describing the memory usage of the Node process measured in bytes. + /// + /// + return new Number(); + }; + this.nextTick = function (callback) { + /// + /// On the next loop around the event loop call this callback. This is
+ /// not a simple alias to setTimeout(fn, 0), it's much more efficient. + ///
+ /// + }; + this.umask = function (mask) { + /// + /// Sets or reads the process's file mode creation mask. Child
+ /// processes inherit the mask from the parent process. Returns the
+ /// old mask if mask argument is given, otherwise returns the current
+ /// mask. + ///
+ /// + /// + return new Number(); + }; + this.uptime = function () { + /// + /// Number of seconds Node has been running. + /// + /// + return new Number(); + }; + this.hrtime = function () { + /// + /// Returns the current high-resolution real time in
+ /// a [seconds, nanoseconds] tuple Array. It is relative to an
+ /// arbitrary time in the past. It is not related to the time of day
+ /// and therefore not subject to clock drift. The primary use is for
+ /// measuring performance between intervals. + ///
+ /// + return new Array(); + }; +}; + +require.modules.process.prototype = new require.modules.events.EventEmitter(); + +require.modules.process = new require.modules.process(); \ No newline at end of file diff --git a/nodelib/punycode.js b/nodelib/punycode.js new file mode 100644 index 0000000..37c2d5e --- /dev/null +++ b/nodelib/punycode.js @@ -0,0 +1,62 @@ +require.modules.punycode = new function () { + /// + /// Punycode.js is bundled with Node.js v0.6.2+. Use require('punycode')
+ /// to access it. (To use it with other Node.js versions, use npm to install
+ /// the punycode module first.) + ///
+ /// Ucs2 conversion object. + /// A string representing the current Punycode.js version number. + + this.decode = function(string) { + /// + /// Converts a Punycode string of ASCII code points to a string of Unicode code points. + /// + /// + }; + + this.encode = function(string) { + /// + /// Converts a string of Unicode code points to a Punycode string of ASCII code points. + /// + /// + }; + + this.toUnicode = function (domain) { + /// + /// Converts a Unicode string representing a domain name to Punycode.
+ /// Only the non-ASCII parts of the domain name will be converted, i.e.
+ /// it doesn't matter if you call it with a domain that's already in ASCII. + ///
+ /// Domain name + }; + + this.toASCII = function(dimain) { + /// + /// Converts a Unicode string representing a domain name to Punycode.
+ /// Only the non-ASCII parts of the domain name will be converted, i.e.
+ /// it doesn't matter if you call it with a domain that's already in ASCII. + ///
+ /// + }; + + this.ucs2 = { + decode: function(string) { + /// + /// Creates an array containing the decimal code points of each Unicode
+ /// character in the string. While JavaScript uses UCS-2 internally,
+ /// this function will convert a pair of surrogate halves (each of
+ /// which UCS-2 exposes as separate characters) into a single code point,
+ /// matching UTF-16. + ///
+ /// + }, + encode : function(codePoint) { + /// + /// Creates a string based on an array of decimal code points. + /// + /// + } + }; + + this.version = new Number(); +}; diff --git a/nodelib/querystring.js b/nodelib/querystring.js new file mode 100644 index 0000000..7a273fd --- /dev/null +++ b/nodelib/querystring.js @@ -0,0 +1,40 @@ +require.modules.querystring = new function () { + /// + /// This module provides utilities for dealing with query strings. + /// + + this.stringify = function (obj, sep, eq) { + /// + /// Serialize an object to a query string. Optionally override the
+ /// default separator ('&') and assignment ('=') characters. + ///
+ /// + /// separator. + /// assignment. + /// + return new String(); + }; + this.parse = function (str, sep, eq, options) { + /// + /// Deserialize a query string to an object. Optionally override the
+ /// default separator ('&') and assignment ('=') characters. + ///
+ /// + /// separator. + /// assignment. + /// + return new Object(); + }; + this.escape = new function () { + /// + /// The escape function used by querystring.stringify, provided so that
+ /// it could be overridden if necessary. + ///
+ }; + this.unescape = new function () { + /// + /// The unescape function used by querystring.parse, provided so that
+ /// it could be overridden if necessary. + ///
+ }; +}; diff --git a/nodelib/readline.js b/nodelib/readline.js new file mode 100644 index 0000000..b4232b3 --- /dev/null +++ b/nodelib/readline.js @@ -0,0 +1,82 @@ +require.modules.readline = new function () { + this.createInterface = function (options) { + ///Interface to streams used for readline. + return new require.modules.readline.Interface(); + }; + this.on = function (event, listener) { + /// + /// event method. + /// + /// + /// event name.
+ ///'line', 'pause', 'resume', 'close', 'SIGINT', 'SIGTSTP', 'SIGCONT' + /// + /// listenr function. + }; + this.addListener = function (event, listener) { + ///Adds a listener to the end of the listeners array for the specified event. + /// + /// + }; + this.once = function (event, listener) { + ///Adds a **one time** listener for the event. This listener is invoked only the next time the event is fired, after which it is removed. + /// + /// + }; + this.removeListener = function (event, listener) { + ///Remove a listener from the listener array for the specified event. **Caution**: changes array indices in the listener array behind the listener. + /// + /// + }; + this.removeAllListeners = function (event) { + ///Removes all listeners, or those of the specified event. + /// + }; + this.setMaxListeners = function (n) { + ///By default EventEmitters will print a warning if more than 10 listeners are added for a particular event. This is a useful default which helps finding memory leaks. Obviously not all Emitters should be limited to 10. This function allows that to be increased. Set to zero for unlimited. + /// + }; + this.listeners = function (event) { + ///Returns an array of listeners for the specified event. This array can be manipulated, e.g. to remove listeners. + /// + }; + this.emit = function (event, arg1, arg2) { + ///Execute each of the listeners in order with the supplied arguments. + /// + /// + /// + }; + +}; + + +require.modules.readline.Interface = function () { + this.setPrompt = function (prompt, length) { + ///Sets the prompt, for example when you run `node` on the command line, you see `> `, which is node's prompt. + /// + /// + }; + this.prompt = function (preserveCursor) { + ///Readies readline for input from the user, putting the current `setPrompt` options on a new line, giving the user a new spot to write. + /// + }; + this.question = function (query, callback) { + ///Prepends the prompt with `query` and invokes `callback` with the user's response. Displays the query to the user, and then invokes `callback` with the user's response after it has been typed. + /// + /// + }; + this.pause = function() { + ///Prepends the prompt with `query` and invokes `callback` with the user's response. Displays the query to the user, and then invokes `callback` with the user's response after it has been typed. + }; + this.resume = function() { + ///Resumes tty. + }; + this.close = function() { + ///Closes tty. + }; + this.write = function (data, key) { + ///Writes to tty. + /// + /// + }; +}; diff --git a/nodelib/repl.js b/nodelib/repl.js new file mode 100644 index 0000000..a783431 --- /dev/null +++ b/nodelib/repl.js @@ -0,0 +1,77 @@ +require.modules.repl = new function () { + /// + /// A Read-Eval-Print-Loop (REPL) is available both as a standalone program
+ /// and easily includable in other programs. The REPL provides a way to
+ /// interactively run JavaScript and see the results. It can be used for
+ /// debugging, testing, or just trying things out. + ///
+ this.start = function (options) { + /// + /// Returns and starts a REPLServer instance. + /// + /// + }; + + ////Event: 'exit' + this.on = function (event, listener) { + /// + /// event method. + /// + /// + /// event name.
+ /// 'exit' + /// + /// listenr function. + }; + this.addListener = function (event, listener) { + /// Adds a listener to the end of the listeners array for the specified event. + /// event name. + /// listener function. + }; + this.once = function (event, listener) { + /// + /// Adds a **one time** listener for the event.
+ /// This listener is invoked only the next time the event is fired, after which it is removed. + ///
+ /// event name. + /// listener function. + }; + this.removeListener = function (event, listener) { + /// + /// Remove a listener from the listener array for the specified event.
+ /// **Caution**: changes array indices in the listener array behind the listener. + ///
+ /// event name. + /// listener function. + }; + this.removeAllListeners = function (event) { + /// + /// Removes all listeners, or those of the specified event. + /// + /// event name. + }; + this.setMaxListeners = function (n) { + /// + /// By default EventEmitters will print a warning if more than 10 listeners are added for a particular event.
+ /// This is a useful default which helps finding memory leaks.
+ /// Obviously not all Emitters should be limited to 10.
+ /// This function allows that to be increased. Set to zero for unlimited. + ///
+ /// + }; + this.listeners = function (event) { + /// + /// Returns an array of listeners for the specified event.
+ /// This array can be manipulated, e.g. to remove listeners.
+ /// event name. + }; + this.emit = function (event, arg1, arg2) { + /// + /// Execute each of the listeners in order with the supplied arguments. + /// + /// event name. + /// + /// + }; + +}; diff --git a/nodelib/should.js b/nodelib/should.js new file mode 100644 index 0000000..0352213 --- /dev/null +++ b/nodelib/should.js @@ -0,0 +1,4 @@ +/// +/// + +require.modules.should = module.exports = assert; diff --git a/nodelib/stream.js b/nodelib/stream.js new file mode 100644 index 0000000..499803d --- /dev/null +++ b/nodelib/stream.js @@ -0,0 +1,123 @@ +/// + +require.modules.stream = function () { + /// + /// A stream is an abstract interface implemented by various objects in Node.
+ /// For example a request to an HTTP server is a stream, as is stdout.
+ /// Streams are readable, writable, or both. All streams are instances of EventEmitter + ///
+ /// + /// A boolean that is true by default, but turns false after an 'error' occurred or end() / destroy() was called. + /// + /// + /// A boolean that is true by default, but turns false after an 'error' occurred, the stream came to an 'end', or destroy() was called. + /// + + + this.writable = new Boolean(); + this.readable = new Boolean(); + + + + + this.setEncoding = function (encoding) { + /// + /// Makes the 'data' event emit a string instead of a Buffer. + /// encoding can be 'utf8', 'utf16le' ('ucs2'), 'ascii', or 'hex'. + /// Defaults to 'utf8'. + /// + /// + }; + this.pause = function () { + /// + /// Issues an advisory signal to the underlying communication layer, + /// requesting that no further data be sent until resume() is called. + /// + }; + this.resume = function () { + /// + /// Resumes the incoming 'data' events after a pause(). + /// + }; + this.destroy = function () { + /// + /// Closes the underlying file descriptor. Stream is no longer writable nor readable. + /// The stream will not emit any more 'data', or 'end' events. Any queued write data will not be sent. + /// The stream should emit 'close' event once its resources have been disposed of. + /// + }; + this.pipe = function (destination, options) { + /// + /// This is a Stream.prototype method available on all Streams.
+ /// Connects this read stream to destination WriteStream. Incoming data on this stream gets written to destination. + /// The destination and source streams are kept in sync by pausing and resuming as necessary. + ///
+ /// + /// + /// This function returns the destination stream. + return new Stream(); + }; + + + this.write = function (buffer, string, encoding) { + /// + /// + /// Same as the above except with a raw buffer. + /// + /// raw buffer. + /// + /// + /// + /// Writes string with the given encoding to the stream.
+ /// Returns true if the string has been flushed to the kernel buffer.
+ /// Returns false to indicate that the kernel buffer is full, and the data will be sent out in the future.
+ /// The 'drain' event will indicate when the kernel buffer is empty again. The encoding defaults to 'utf8'. + ///
+ /// text. + /// text encoding description. + /// + /// Returns true if the string has been flushed to the kernel buffer.
+ /// Returns false to indicate that the kernel buffer is full, and the data will be sent out in the future. + ///
+ ///
+ return new Boolean(); + + }; + this.end = function (buffer) { + /// + /// Terminates the stream with EOF or FIN.
+ /// This call will allow queued write data to be sent before closing the stream. + ///
+ ///
+ /// + /// + /// Same as above but with a buffer. + /// + /// + /// + /// + /// + /// Sends string with the given encoding and terminates the stream with EOF or FIN.
+ /// This is useful to reduce the number of packets sent. + ///
+ /// text. + /// text encoding description. + ///
+ + }; + this.destroy = function () { + /// + /// Closes the underlying file descriptor. Stream is no longer writable nor readable. The stream will not emit any more 'data', or 'end' events. Any queued write data will not be sent.
+ /// The stream should emit 'close' event once its resources have been disposed of. + ///
+ }; + + this.destroySoon = function () { + /// + /// After the write queue is drained, close the file descriptor.
+ /// destroySoon() can still destroy straight away, as long as there is no data left in the queue for writes. + ///
+ }; +}; + +require.modules.stream.prototype = new require.modules.events.EventEmitter(); diff --git a/nodelib/stringdecoder.js b/nodelib/stringdecoder.js new file mode 100644 index 0000000..e96e606 --- /dev/null +++ b/nodelib/stringdecoder.js @@ -0,0 +1,17 @@ +require.modules.string_decoder = { + StringDecoder: function (encoding) { + /// + /// To use this module, do require('string_decoder'). StringDecoder decodes
+ /// a buffer to a string. It is a simple interface to buffer.toString() but
+ /// provides additional support for utf8. + ///
+ /// + } +}; + +require.modules.string_decoder.StringDecoder.prototype.write = function (buffer) { + /// + /// Returns a decoded string. + /// + /// +}; \ No newline at end of file diff --git a/nodelib/superagent.js b/nodelib/superagent.js new file mode 100644 index 0000000..e17e723 --- /dev/null +++ b/nodelib/superagent.js @@ -0,0 +1,4 @@ +/// +/// + +require.modules.superagent = module.exports; diff --git a/nodelib/supertest.js b/nodelib/supertest.js new file mode 100644 index 0000000..5abfe5a --- /dev/null +++ b/nodelib/supertest.js @@ -0,0 +1,5 @@ +/// +/// +/// + +require.modules.supertest = module.exports = Test; diff --git a/nodelib/tls.js b/nodelib/tls.js new file mode 100644 index 0000000..ae73772 --- /dev/null +++ b/nodelib/tls.js @@ -0,0 +1,172 @@ +/// +/// +/// + +require.modules.tls = new function () { + /// + /// The tls module uses OpenSSL to provide Transport Layer Security and/or
+ /// Secure Socket Layer: encrypted stream communication.
+ ///
+ + var SecurePair = function() { + /// + /// Returned by tls.createSecurePair. + /// + }; + this.createServer = function (options, secureConnectionListener) { + /// + /// Creates a new tls.Server. The connectionListener argument is
+ /// automatically set as a listener for the secureConnection event. + ///
+ /// + /// + /// + return new require.modules.tls.Server(); + }; + this.Connect = function (options, callback) { + /// + /// Creates a new client connection to the given port and host (old API) or options.port and options.host. + /// + /// option object. + /// + /// + return new require.modules.tls.CleartextStream(); + }; + this.connect = function (port, host, options, secureConnectionListener) { + /// + /// Creates a new client connection to the given port and host (old API) or options.port and options.host. + /// + /// + /// + /// + /// + /// + return new require.modules.tls.CleartextStream(); + }; + this.createSecurePair = function (credentials, isServer, requestCert, rejectUnauthorized) { + /// + /// Creates a new secure pair object with two streams, one of which
+ /// reads/writes encrypted data, and one reads/writes cleartext data.
+ /// Generally the encrypted one is piped to/from an incoming encrypted
+ /// data stream, and the cleartext one is used as a replacement for the
+ /// initial encrypted stream. + ///
+ /// + /// + /// + /// + /// + return new SecurePair(); + }; +}; + + +require.modules.tls.Server = function () { + /// + /// This class is a subclass of net.Server and has the same methods on it.
+ /// Instead of accepting just raw TCP connections, this accepts encrypted
+ /// connections using TLS or SSL. + ///
+ /// + /// Set this property to reject connections when the server's connection count gets high. + /// + /// + /// Set this property to reject connections when the server's connection count gets high. + /// + this.listen = function (port, host, callback) { + /// + /// Begin accepting connections on the specified port and host. If the
+ /// host is omitted, the server will accept connections directed to any
+ /// IPv4 address (INADDR_ANY). + ///
+ /// + /// + /// + }; + this.close = function() { + /// + /// Stops the server from accepting new connections. This function is
+ /// asynchronous, the server is finally closed when the server emits a
+ /// 'close' event. + ///
+ }; + this.address = function () { + /// + /// Returns the bound address, the address family name and port of the
+ /// server as reported by the operating system. See net.Server.address()
+ /// for more information. + ///
+ /// + return { port: 0, family: '', address: '' }; + }; + this.addContext = function (hostname, credentials) { + /// + /// Add secure context that will be used if client request's SNI
+ /// hostname is matching passed hostname (wildcards can be used).
+ /// credentials can contain key, cert and ca. + ///
+ /// + /// + }; + this.maxConnections = new Number(); + this.connections = new Number(); + + + +}; + +require.modules.tls.Server.prototype = new Net.Server(); + +require.modules.tls.CleartextStream = function () { + /// + /// This is a stream on top of the Encrypted stream that makes it possible
+ /// to read/write an encrypted data as a cleartext data. + ///
+ /// + /// A boolean that is true if the peer certificate was signed by one of the specified CAs, otherwise false. + /// + /// + /// The reason why the peer's certificate has not been verified. This property becomes available only when cleartextStream.authorized === false. + /// + /// + /// The string representation of the remote IP address. For example, '74.125.127.100' or '2001:4860:a005::68'. + /// + /// + /// + /// The numeric representation of the remote port. For example, 443. + /// + + + this.authorized = new Boolean(); + this.authorizationError = new String(); + this.getPeerCertificate = function () { + /// + /// Returns an object representing the peer's certificate. The returned
+ /// object has some properties corresponding to the field of the certificate. + ///
+ /// + return new Object(); + }; + this.getCipher = function () { + /// + /// Returns an object representing the cipher name and the SSL/TLS
+ /// protocol version of the current connection. + ///
+ /// + return { name: '', version: '' }; + }; + this.address = function () { + /// + /// Returns the bound address, the address family name and port of the
+ /// underlying socket as reported by the operating system. Returns an
+ /// object with three properties, e.g. { port: 12346, family: 'IPv4',
+ /// address: '127.0.0.1' } + ///
+ /// + return { port: 0, family: '', address: '' }; + }; + this.remoteAddress = new String(); + this.remotePort = new Number(); +}; + +require.modules.tls.CleartextStream.prototype = new Stream(); diff --git a/nodelib/tty.js b/nodelib/tty.js new file mode 100644 index 0000000..6affc15 --- /dev/null +++ b/nodelib/tty.js @@ -0,0 +1,59 @@ +/// + +require.modules.tty = new function () { + /// + /// The tty module houses the tty.ReadStream and tty.WriteStream classes. In
+ /// most cases, you will not need to use this module directly. + ///
+ this.isatty = function (fd) { + /// + /// Returns true or false depending on if the fd is associated with a terminal. + /// + /// file descriptor + /// + return new Boolean(); + }; + //this.setRawMode = function(mode){}; + this.ReadStream = function () { + /// + /// A net.Socket subclass that represents the readable portion of a
+ /// tty. In normal circumstances, process.stdin will be the only
+ /// tty.ReadStream instance in any node program (only when isatty(0) is
+ /// true). + ///
+ /// + /// A Boolean that is initialized to false. It represents the current "raw" state of the tty.ReadStream instance. + /// + + this.isRaw = new Boolean(); + this.setRawMode = function (mode) { + /// + /// mode should be true or false. This sets the properties of the
+ /// tty.ReadStream to act either as a raw device or default. isRaw
+ /// will be set to the resulting mode. + ///
+ /// + }; + }; + this.ReadStream.prototype = new require.modules.net.Socket(); + + this.WriteStream = function () { + /// + /// A net.Socket subclass that represents the writable portion of a tty.
+ /// In normal circumstances, process.stdout will be the only
+ /// tty.WriteStream instance ever created (and only when isatty(1) is
+ /// true). + ///
+ /// + /// A Number that gives the number of columns the TTY currently has. This property gets updated on "resize" events. + /// + /// + /// A Number that gives the number of rows the TTY currently has. This property gets updated on "resize" events. + /// + + this.columns = new Number(); + this.rows = new Number(); + ////Event: 'resize' + }; + this.WriteStream.prototype = new require.modules.net.Socket(); +}; diff --git a/nodelib/url.js b/nodelib/url.js new file mode 100644 index 0000000..ffc4646 --- /dev/null +++ b/nodelib/url.js @@ -0,0 +1,32 @@ +/// + +require.modules.url = new function () { + /// + /// This module has utilities for URL resolution and parsing. Call require('url') to use it. + /// + this.parse = function (urlStr, parseQueryString, slashesDenoteHost) { + /// Take a URL string, and return an object. + /// + /// + /// + /// URL Object. + return new Object(); + }; + this.format = function(urlObj) { + /// + /// Take a parsed URL object, and return a formatted URL string. + /// + /// URL Object + /// + return new String(); + }; + this.resolve = function(from, to) { + /// + /// Take a base URL, and a href URL, and resolve them as a browser would for an anchor tag. + /// + /// + /// + /// + return new String(); + }; +}; diff --git a/nodelib/util.js b/nodelib/util.js new file mode 100644 index 0000000..02d62b7 --- /dev/null +++ b/nodelib/util.js @@ -0,0 +1,110 @@ +/// + +require.modules.util = new function () { + /// These functions are in the module 'util'. Use require('util') to access them. + this.format = function (format, args) { + /// Returns a formatted string using the first argument as a printf-like format. + /// + /// %s String, %d Number, %j JSON + /// + /// + /// + return new String(); + }; + this.debug = function (string) { + /// + /// A synchronous output function. + /// Will block the process and output string immediately to stderr. + /// + /// + }; + this.error = function (args) { + /// + /// Same as util.debug() except this will output all arguments immediately to stderr. + /// + /// + }; + this.puts = function (args) { + /// + /// A synchronous output function. + /// Will block the process and output all arguments to stdout with newlines after each argument. + /// + /// + }; + this.print = function (args) { + /// + /// A synchronous output function. + /// Will block the process, cast each argument to a string then output to stdout. + /// Does not place newlines after each argument. + /// + /// + }; + this.log = function (string) { + /// Output with timestamp on stdout. + /// + }; + this.inspect = function (object, showHidden, depth, colors) { + /// + /// Return a string representation of object, which is useful for debugging. + /// + /// + /// + /// + /// + /// + return new String(); + }; + this.isArray = function (object) { + /// + /// Returns true if the given "object" is an Array. false otherwise. + /// + /// + /// + return new Boolean(); + }; + this.isRegExp = function (object) { + /// + /// Returns true if the given "object" is a RegExp. false otherwise. + /// + /// + /// + return new Boolean(); + }; + this.isDate = function (object) { + /// + /// Returns true if the given "object" is a Date. false otherwise. + /// + /// + /// + return new Boolean(); + }; + this.isError = function (object) { + /// + /// Returns true if the given "object" is an Error. false otherwise. + /// + /// + /// + return new Boolean(); + }; + this.pump = function (readableStream, writableStream, callback) { + /// + /// Read the data from readableStream and send it to the writableStream. + /// When writableStream.write(data) returns false readableStream + /// will be paused until the drain event occurs on the writableStream. + /// callback gets an error as its only argument and is called + /// when writableStream is closed or when an error occurs. + /// + /// + /// + /// + }; + this.inherits = function (constructor, superConstructor) { + /// + /// Inherit the prototype methods from one constructor into another. + /// The prototype of constructor will be set to a new object created from superConstructor. + /// + /// + /// + }; +}; + diff --git a/nodelib/vm.js b/nodelib/vm.js new file mode 100644 index 0000000..3becb32 --- /dev/null +++ b/nodelib/vm.js @@ -0,0 +1,84 @@ +require.modules.vm = new function () { + /// + /// JavaScript code can be compiled and run immediately or compiled, saved, and run later. + /// + this.runInThisContext = function (code, filename) { + /// + /// vm.runInThisContext() compiles code, runs it and returns the result. + /// Running code does not have access to local scope. + /// filename is optional, it"s used only in stack traces. + /// + /// + /// + /// + return new Object(); + }; + this.runInNewContext = function (code, sandbox, filename) { + /// + /// vm.runInNewContext compiles code, then runs it in sandbox and returns the result. + /// Running code does not have access to local scope. + /// The object sandbox will be used as the global object for code. + /// sandbox and filename are optional, filename is only used in stack traces. + /// + /// + /// + /// + /// + return new Object(); + }; + this.runInContext = function (code, context, filename) { + /// + /// vm.runInContext compiles code, then runs it in context and returns the result. + /// A (V8) context comprises a global object, together with a set of built-in objects and functions. + /// Running code does not have access to local scope and the global object held within context + /// will be used as the global object for code. filename is optional, it"s used only in stack traces. + /// + /// + /// + /// + /// + return new Object(); + }; + this.createContext = function (initSandbox) { + /// + /// vm.createContext creates a new context which is suitable for use as the 2nd argument of a subsequent call to vm.runInContext. + /// A (V8) context comprises a global object together with a set of build-in objects and functions. + /// The optional argument initSandbox will be shallow-copied to seed the initial contents of the global object used by the context. + /// + /// + /// + return new Object(); + }; + this.createScript = function (code, filename) { + /// + /// createScript compiles code but does not run it. Instead, + /// it returns a vm.Script object representing this compiled code. + /// This script can be run later many times using methods below. + /// The returned script is not bound to any global object. + /// It is bound before each run, just for that run. filename is optional, it"s only used in stack traces + /// + /// + /// + /// + return new require.modules.vm.Script(); + }; +}; + +require.modules.vm.Script = function () { + /// A class for running scripts. Returned by vm.createScript. + this.runInThisContext = function() { + /// + /// Similar to vm.runInThisContext but a method of a precompiled Script object. script.runInThisContext runs + /// the code of script and returns the result. + /// Running code does not have access to local scope, + /// but does have access to the global object (v8: in actual context). + /// + }; + this.runInNewContext = function (sandbox) { + /// + /// Similar to vm.runInNewContext a method of a precompiled Script object. + /// script.runInNewContext runs the code of script with sandbox as the global object and returns the result. + /// Running code does not have access to local scope. sandbox is optional. + /// + }; +}; diff --git a/nodelib/zlib.js b/nodelib/zlib.js new file mode 100644 index 0000000..7a1bfea --- /dev/null +++ b/nodelib/zlib.js @@ -0,0 +1,135 @@ +/// + +require.modules.zlib = new function () { + /// + /// This provides bindings to Gzip/Gunzip, Deflate/Inflate, and DeflateRaw/InflateRaw classes. + /// Each class takes the same options, and is a readable/writable Stream. + /// + this.createGzip = function (options) { + /// Returns a new Gzip object with an options. + /// + /// + return new require.modules.zlib.Gzip(); + }; + this.createGunzip = function (options) { + /// Returns a new Gunzip object with an options. + /// + /// + return new require.modules.zlib.Gunzip(); + }; + this.createDeflate = function (options) { + /// Returns a new Deflate object with an options. + /// + /// + return new require.modules.zlib.Deflate(); + }; + this.createInflate = function (options) { + /// Returns a new Inflate object with an options. + /// + /// + return new require.modules.zlib.Inflate(); + }; + this.createDeflateRaw = function (options) { + /// Returns a new DeflateRaw object with an options. + /// + /// + return new require.modules.zlib.DeflateRaw(); + }; + this.createInflateRaw = function (options) { + /// Returns a new InflateRaw object with an options. + /// + /// + return new require.modules.zlib.InflateRaw(); + }; + this.createUnzip = function (options) { + /// Returns a new Unzip object with an options. + /// + /// + return new require.modules.zlib.Unzip(); + }; + this.deflate = function (buf, callback) { + /// Compress a string with Deflate. + /// + /// + }; + this.deflateRaw = function (buf, callback) { + /// Compress a string with DeflateRaw. + /// + /// + }; + this.gzip = function (buf, callback) { + /// Compress a string with Gzip. + /// + /// + }; + this.gunzip = function (buf, callback) { + /// Decompress a raw Buffer with Gunzip. + /// + /// + }; + this.inflate = function (buf, callback) { + /// Decompress a raw Buffer with Inflate. + /// + /// + }; + this.inflateRaw = function (buf, callback) { + /// Decompress a raw Buffer with InflateRaw. + /// + /// + }; + this.unzip = function (buf, callback) { + /// Decompress a raw Buffer with Unzip. + /// + /// + }; +}; + +require.modules.zlib.Gzip = function () { + /// + /// Compress data using gzip. + /// +}; +require.modules.zlib.Gzip.prototype = new require.modules.stream(); +require.modules.zlib.Gunzip = function () { + /// + /// Decompress a gzip stream. + /// +}; +require.modules.zlib.Gunzip.prototype = new require.modules.stream(); +require.modules.zlib.Deflate = function () { + /// + /// Compress data using deflate. + /// +}; +require.modules.zlib.Deflate.prototype = new require.modules.stream(); +require.modules.zlib.Inflate = function () { + /// + /// Decompress a deflate stream. + /// +}; +require.modules.zlib.Inflate.prototype = new require.modules.stream(); +require.modules.zlib.DeflateRaw = function () { + /// + /// Compress data using deflate, and do not append a zlib header. + /// +}; +require.modules.zlib.DeflateRaw.prototype = new require.modules.stream(); +require.modules.zlib.InflateRaw = function () { + /// + /// Decompress a raw deflate stream. + /// +}; +require.modules.zlib.InflateRaw.prototype = new require.modules.stream(); +require.modules.zlib.InflateRaw = function () { + /// + /// Decompress a raw deflate stream. + /// +}; +require.modules.zlib.InflateRaw.prototype = new require.modules.stream(); +require.modules.zlib.Unzip = function () { + /// + /// Decompress either a Gzip- or Deflate-compressed stream by auto-detecting the header. + /// +}; +require.modules.zlib.Unzip.prototype = new require.modules.stream(); + diff --git a/package.json b/package.json new file mode 100644 index 0000000..2ecc494 --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "iridium", + "version": "1.0.0", + "author": "Benjamin Pannell ", + "description": "A custom lightweight ORM for MongoDB designed for power-users", + "homepage": "https://sierrasoftworks.com/iridium", + "repository": "https://github.com/sierrasoftworks/iridium", + "contributors": [ + { "name": "Benjamin Pannell", "email": "admin@sierrasoftworks.com" } + ], + "main": "./index", + "scripts": { + "test": "node test/run" + }, + "engines": { + "node": ">= 0.8" + }, + "dependencies": { + "mongodb": "*", + "lodash": "*" + }, + "devDependencies": { + "async": "*", + "mocha": "*", + "should": "*", + "gitlablist-mocha": "*" + } +} \ No newline at end of file diff --git a/tests/.gitignore b/tests/.gitignore new file mode 100644 index 0000000..a2d72a2 --- /dev/null +++ b/tests/.gitignore @@ -0,0 +1 @@ +config.js \ No newline at end of file diff --git a/tests/common.js b/tests/common.js new file mode 100644 index 0000000..d366482 --- /dev/null +++ b/tests/common.js @@ -0,0 +1,42 @@ +/// + +var path = require('path'); +var async = require('async'); + +module.exports.isCI = function() { + return !!process.env.CI_SERVER; +}; + +module.exports.extend = function (original, merge) { + var merged = {}; + for(var k in original) { + merged[k] = merge.hasOwnProperty(k) ? merge[k] : original[k]; + } + return merged; +}; + +module.exports.hasConfig = function () { + var config; + + try { + config = module.exports.getConfig(); + } catch (ex) { + return 'not-found'; + } + + return 'found'; +}; + +var config = null; + +module.exports.getConfig = function () { + if (module.exports.isCI()) { + return config || (config = module.exports.extend(require('../settings'), { + user: "iridium", + password: "", + database: "iridium" + })); + } else { + return config || (config = require("./config")); + } +}; \ No newline at end of file diff --git a/tests/config.example.js b/tests/config.example.js new file mode 100644 index 0000000..1456902 --- /dev/null +++ b/tests/config.example.js @@ -0,0 +1,8 @@ +var settings = { + host: "localhost", + user: "iridium", + password: "", + database: "iridium" +}; + +module.exports = settings; diff --git a/tests/integration/orm.js b/tests/integration/orm.js new file mode 100644 index 0000000..f22f6fc --- /dev/null +++ b/tests/integration/orm.js @@ -0,0 +1,143 @@ +/// +/// +/// +/// + +var common = require('../common'); +var Database = require('../../index'); +var Model = Database.Model; +var Instance = Database.Instance; +var should = require('should'); + +describe('orm', function () { + "use strict"; + + describe('Instance', function () { + describe('diff', function () { + it('should generate $set for basic changes', function () { + Instance.diff({ x: 1 }, { x: 2 }).should.eql({ $set: { x: 2 } }); + }); + + it('should not generate $set for unnecessary changes', function () { + Instance.diff({ x: 1, y: 1 }, { x: 1, y: 2 }).should.eql({ $set: { y: 2 } }); + Instance.diff({ a: [1], b: 1 }, { a: [1], b: 2 }).should.eql({ $set: { b: 2 } }); + }); + + it('should generate $set for new properties', function () { + Instance.diff({ a: 1 }, { a: 1, b: 1 }).should.eql({ $set: { b: 1 } }); + }); + + it('should generate $set for array changes', function () { + Instance.diff({ a: [1] }, { a: [1, 2] }).should.eql({ $set: { a: [1, 2] } }); + }); + + it('should generate recursive $set for child properties', function () { + Instance.diff({ a: { b: 1, c: 1 } }, { a: { b: 1, c: 2 } }).should.eql({ $set: { 'a.c': 2 } }); + }); + }); + + describe('constructor', function () { + it('should present all properties of the document', function () { + var i = new Instance({}, { + _id: 'custom_id', + name: 'name' + }, {}); + + i.should.have.property('id', 'custom_id'); + i.should.have.property('name', 'name'); + }); + + it('should allow renaming of properties', function () { + var i = new Instance({}, { + _id: 'custom_id', + uglyName: 'value' + }, { + rename: { + uglyName: 'pretty' + } + }); + + i.should.have.property('pretty', 'value'); + }); + + it('should allow the creation of methods', function () { + var i = new Instance({}, { + _id: 'custom_id' + }, { + methods: { + test: function () { return true; } + } + }); + + i.test().should.equal(true); + }); + + it('should correctly pass all arguments to a method', function () { + var i = new Instance({}, { + _id: 'custom_id' + }, { + methods: { + test: function (a, b, c) { + should.equal(a, 'a'); + should.equal(b, 'b'); + should.equal(c, 'c'); + } + } + }); + + i.test('a', 'b', 'c'); + }); + + it('should allow the creation of virtual properties', function () { + var i = new Instance({}, { + _id: 'custom_id', + firstname: 'Billy', + lastname: 'Bob' + }, { + virtuals: { + fullname: function () { return this.firstname + ' ' + this.lastname; } + } + }); + + i.fullname.should.equal('Billy Bob'); + }); + + it('should allow a custom schema', function () { + var i = new Instance({}, { + _id: 'custom_id', + name: 'name' + }, { + schema: { + name: String, + age: { type: Number, required: false } + } + }); + + (function () { + i.age = 'hello'; + }).should.throwError(); + + i.should.have.property('id', 'custom_id'); + i.should.have.property('name', 'name'); + i.should.have.property('age', null); + }); + }); + }); + + describe('Model', function () { + var db = null; + before(function (done) { + db = new Database(common.getConfig(), done); + }); + + describe('constructor', function () { + it('should allow a new model to be created', function () { + var model = new Model(db, 'model', { + + }, { + + }); + }); + }); + }); +}); diff --git a/tests/integration/utils.js b/tests/integration/utils.js new file mode 100644 index 0000000..34cfd32 --- /dev/null +++ b/tests/integration/utils.js @@ -0,0 +1,130 @@ +/// +/// +/// +/// +/// +/// + +var _ = require('lodash'); +var should = require('should'); + +describe('utils', function () { + + describe('validation', function () { + var validation = require('../../lib/utils/validation'); + function validate(schema, value, pass, message) { + validation(schema, value).should.have.ownProperty('passed', pass, message); + } + + it('should allow validation of basic types', function () { + validate(true, undefined, false, 'Expected true:undefined to fail'); + validate(true, null, false, 'Expected true:null to fail'); + validate(true, '', false, 'Expected true:"" to fail'); + validate(true, 'hello', true, 'Expected true:"hello" to pass'); + + validate(false, undefined, true, 'Expected false:undefined to pass'); + validate(false, '', true, 'Expected false:"" to pass'); + + validate(Object, { test: 1 }, true, 'Expected Object:{test:1} to pass'); + + validate(String, 1, false, 'Expected String:1 to fail'); + validate(String, 'hello', true, 'Expected String:"hello" to pass'); + + validate(Number, 'hello', false, 'Expected Number:"hello" to fail'); + validate(Number, 1, true, 'Expected Number:1 to pass'); + }); + + it('should allow validation of array elements', function () { + validate([String], ['hello'], true, 'Expected [String]:["hello"] to pass'); + validate([Number], ['hello'], false, 'Expected [Number]:["hello"] to fail'); + }); + + it('should allow validation of an array\'s minimum and maximum length', function () { + validate([String, 1], [], false, 'Expected [String,1]:[] to fail'); + validate([String, 1, 2], ['a', 'b', 'c'], false, 'Expected [String,1,2]:["a","b","c"] to fail'); + }); + + it('should allow validation of object properties', function () { + validate({ name: String, age: Number }, { name: 'Benjamin Pannell', age: 20 }, true); + validate({ name: String, age: Number }, { name: 'Benjamin Pannell', age: '20' }, false); + }); + + it('should allow validation of objects within arrays', function () { + validate([{ name: String, age: Number }], [{ name: 'Benjamin Pannell', age: 20 }, { name: 'Billy Jean', age: 27 }], true); + validate([{ name: String, age: Number }], [{ name: 'Benjamin Pannell', age: 20 }, { name: 'Billy Jean', age: '27' }], false); + }); + + it('shouldn\'t fail to correctly validate objects with a type field', function () { + validate({ type: String, name: String }, { type: 'test', name: 'runner' }, true); + }); + + it('should allow validation of non-required typed properties', function () { + validate({ $type: Number, $required: false }, null, true); + validate({ $type: Number, $required: false }, 1, true); + validate({ $type: Number, $required: false }, 'hello', false); + }); + + it('should allow validation using a regular expression', function () { + validate(/test/, 'test', true); + validate(/test/, 'fail', false); + }); + + it('should allow validation of an object map', function () { + validate({ $propertyType: Number, $required: false }, null, true); + validate({ $propertyType: Number }, null, false); + validate({ $propertyType: Number }, { + a: 1, + b: 2 + }, true); + validate({ $propertyType: Number }, { + a: 1, + b: 'b' + }, false); + }); + }); + + describe('transforms', function () { + var transform = require('../../lib/utils/transforms'); + + it('should allow the transformation of an object\'s properties', function () { + var original = { + a: 'a', + b: 1, + c: 'c', + d: 'd' + }; + + var expected = { + a: 'aa', + b: 1, + c: 'c', + d: 'd' + }; + + var trans = { + a: { $t: function (value) { return value + value; } }, + b: false, + c: { $t: false } + }; + + transform(trans, '$t', original); + + original.should.eql(expected); + }); + + it('should remove properties where the transform returns undefined', function () { + var original = { + a: 1 + }; + + var expected = { + b: '1' + }; + + var trans = { + a: { $t: function (value) { return undefined; } }, + b: { $t: function (value) { return '1'; } } + }; + }); + }); +}); \ No newline at end of file diff --git a/tests/logging.js b/tests/logging.js new file mode 100644 index 0000000..906f51a --- /dev/null +++ b/tests/logging.js @@ -0,0 +1,29 @@ +var util = require("util"); + +exports.info = buildMethod(process.stdout, "[i]", 34); +exports.error = buildMethod(process.stderr, "[!]", 31); + +function buildMethod(stream, prefix, color) { + return function () { + var params = Array.prototype.slice.apply(arguments); + var text = params.shift(); + + return printTo(stream, prefix + " ", color, text, params); + }; +} + +function printTo(stream, prefix, color, text, params) { + params.unshift(text); + text = util.format.apply(util, params); + + stream.write(printColor(color, true) + prefix + printColor(color) + text.replace(/\*\*(.+?)\*\*/, function (m, t) { + return printColor(color, true) + t + printColor(color); + }) + printColor(null) + "\n"); +} + +function printColor(color, bold) { + if (color === null) { + return "\033[0m"; + } + return "\033[" + (bold ? "1" : "0") + ";" + color + "m"; +} diff --git a/tests/run.js b/tests/run.js new file mode 100644 index 0000000..4854d05 --- /dev/null +++ b/tests/run.js @@ -0,0 +1,30 @@ +var Mocha = require("mocha"); +var fs = require("fs"); +var path = require("path"); +var common = require("./common"); +var logging = require("./logging"); +var location = path.normalize(path.join(__dirname, "integration")); +var mocha = new Mocha({ + reporter: 'gitlablist-mocha' +}); + +if (common.hasConfig() === 'not-found') { + logging.error("**test/config.js** missing. Take a look at **test/config.example.js**"); + process.exit(1); +} + +runTests(); + +function runTests() { + fs.readdirSync(location).filter(function (file) { + return file.substr(-3) === '.js'; + }).forEach(function (file) { + mocha.addFile( + path.join(location, file) + ); + }); + + mocha.run(function (failures) { + process.exit(failures); + }); +} diff --git a/tests/run.sh b/tests/run.sh new file mode 100644 index 0000000..54f5387 --- /dev/null +++ b/tests/run.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Paths to different commands +NODE=$(which node) + +success() { + echo -e '\e[1;32mOK\e[0m' +} + +fail() { + echo -e '\e[1;31mFAILED\e[0m' + exit 1 +} + +echo -ne "Installing NPM Modules..." +npm install > /dev/null && success || fail + +echo -ne "Running Test Suite..." +$NODE test/run && success || fail \ No newline at end of file