diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f41a14a --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.js +node_modules/ diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..b0a155e --- /dev/null +++ b/.npmignore @@ -0,0 +1 @@ +*.ts \ No newline at end of file diff --git a/EV3Base.ts b/EV3Base.ts new file mode 100644 index 0000000..ae1c46e --- /dev/null +++ b/EV3Base.ts @@ -0,0 +1,218 @@ +/// +/// +var fs = require("fs"); +var path = require('path'); +var Enumerable: linqjs.EnumerableStatic = require('linq'); + +//Debug settings +var DEBUG = false; + +/** + * A module to handle path creation from known properties + */ +module FilePathConstructor { + var motorDeviceDir: string = '/sys/class/tacho-motor/'; + var motorDirName: string = 'tacho-motor{0}'; + + var sensorDeviceDir: string = '/sys/class/msensor'; + var sensorDirName: string = 'sensor{0}'; + + var ledDeviceDir: string = '/sys/class/leds/'; + var ledDirName: string = 'ev3:{0}:{1}'; + + export function motorIndex(port: MotorPort) { + if (!fs.existsSync(motorDeviceDir)) + throw new Error('The motor class directory does not exist.'); + + + var motorFile = Enumerable.from(fs.readdirSync(motorDeviceDir)) + .firstOrDefault(file => fs.readFileSync( + path.join(motorDeviceDir, file, '/port_name') + ).toString() + .indexOf('out' + MotorPort[port]) == 0); + + return motorFile.match(/[0-9]+/)[0]; + } + + + export function motor(index: number) { + return path.join(motorDeviceDir, motorDirName.format(index), '/'); + } + + export function motorProperty(index: number, property: MotorProperty) { + return path.join(motor(index), MotorProperty[property]); + } + + export function sensorNumber(port: number) { + if (!fs.existsSync(sensorDeviceDir)) + throw new Error('The sensor class directory does not exist.'); + + var sensorFile = Enumerable.from(fs.readdirSync(sensorDeviceDir)) + .firstOrDefault(file => fs.readFileSync( + path.join(sensorDeviceDir, '/', file, '/port_name') + ).toString() + .indexOf('in' + port) == 0); + + return sensorFile.match(/[0-9]+/)[0]; + } + + export function sensor(sensorNumber: number) { + return path.join(sensorDeviceDir, sensorDirName.format(sensorNumber), '/'); + } + + export function sensorProperty(sensorNumber: number, property: string) { + return path.join(sensor(sensorNumber), property); + } + + + export function ledBrightness(position: ledPosition, color: ledUnitColor) { + return path.join(ledDeviceDir, ledDirName.format(ledUnitColor[color], ledPosition[position]), '/brightness'); + } +} + +//Extend the string prototype +interface String { + format(...args: any[]): string +} + +String.prototype.format = function () { + var args: IArguments = arguments; + return this.replace(/{(\d+)}/g, function (match, number) { + return typeof args[number] != 'undefined' + ? args[number] + : match + ; + }); +}; + +/** + * Takes any of the logical ways to express a boolean and normalizes them. + */ +function softBoolean(value: any, falseValue?: any, trueValue?: any): boolean { + switch (value) { + case 0: + case '0': + case 'off': + case false: + case 'false': + return falseValue == undefined ? false : falseValue; + + case 1: + case '1': + case 'on': + case true: + case 'true': + return trueValue == undefined ? true : trueValue; + + default: + return undefined; + } +} + +module.exports.debugLog = function (text: string, ...args: any[]) { + if (DEBUG) { + console.log("DEBUG: " + text.replace(/{(\d+)}/g, function (match, i) { + return typeof args[i] != 'undefined' + ? (typeof args[i] == 'object' ? JSON.stringify(args[i]) : args[i]) + : match + ; + })); + } +} + +enum MotorPort { + A, B, C, D +} + +enum MotorRunMode { + forever, + time, + position +} + +enum MotorProperty { + uevent, + subsystem, + device, + port_name, + type, + position, + state, + duty_cycle, + pulses_per_second, + duty_cycle_sp, + pulses_per_second_sp, + time_sp, + position_sp, + run_mode, + regulation_mode, + stop_modes, + stop_mode, + position_mode, + polarity_mode, + ramp_up_sp, + ramp_down_sp, + speed_regulation_P, + speed_regulation_I, + speed_regulation_D, + speed_regulation_K, + run, + estop, + reset, +} + +var MotorPropertyValidation: any = { + 4: { type: 'string', values: ['tacho', 'minitacho'] }, //type + 5: { type: 'number', min: -2147483648, max: 2147483648 }, //position + 9: { type: 'number', min: -100, max: 100 }, //duty_cycle_sp + 10: { type: 'number', min: -2000, max: 2000 }, //pulses_per_second_sp + 11: { type: 'number', min: 0 }, //time_sp + 12: { type: 'number', min: -2147483648, max: 2147483648 }, //position_sp + 13: { type: 'string', values: ['forever', 'time', 'position'] }, //run_mode + 14: { type: 'string', values: ['on', 'off'] }, //regulation_mode + 16: { type: 'string', values: ['coast', 'brake', 'hold'] }, //stop_mode + 17: { type: 'string', values: ['absolute', 'relative'] }, //position_mode + 18: { type: 'string', values: ['positive', 'negative'] },//polarity_mode + 25: { type: 'number', values: [0, 1] }, //run + 19: { type: 'number' }, //ramp_up_sp + 20: { type: 'number' }, //ramp_down_sp + 21: { type: 'number' }, //speed_regulation_P + 22: { type: 'number' }, //speed_regulation_I + 23: { type: 'number' }, //speed_regulation_D + 24: { type: 'number' }, //speed_regulation_K + + +} + +enum MotorType { + tacho, + minitacho +} + +enum ledPosition { + left, + right +} + +enum ledUnitColor { + green, + red +} + +enum ledColorSetting { + green, + amber, + red, + off +} + +module.exports.FilePathConstructor = FilePathConstructor; +module.exports.MotorPort = MotorPort; +module.exports.MotorProperty = MotorProperty; +module.exports.MotorType = MotorType; +module.exports.MotorPropertyValidation = MotorPropertyValidation; +module.exports.softBoolean = softBoolean; +module.exports.ledUnitColor = ledUnitColor; +module.exports.ledColorSetting = ledColorSetting; +module.exports.ledPosition = ledPosition; +module.exports.MotorRunMode = MotorRunMode; \ No newline at end of file diff --git a/Index.ts b/Index.ts new file mode 100644 index 0000000..9ef3d6a --- /dev/null +++ b/Index.ts @@ -0,0 +1,18 @@ +/// +var base = require("./EV3Base.js"); +var LED = require("./LED.js"); +var Motor = require("./Motor.js"); +var Sensor = require("./Sensors/Sensor.js"); +var SimpleSensors = require("./Sensors/SimpleSensors.js"); + +module.exports.Motor = Motor; +module.exports.LED = LED; + +module.exports.GenericSensor = Sensor; +module.exports.TouchSensor = SimpleSensors.TouchSensor; +module.exports.UltrasonicSensor = SimpleSensors.UltrasonicSensor; + +module.exports.MotorPort = base.MotorPort; +module.exports.ledColorSetting = base.ledColorSetting; +module.exports.ledPosition = base.ledPosition; +module.exports.MotorRunMode = base.MotorRunMode; \ No newline at end of file diff --git a/LED.ts b/LED.ts new file mode 100644 index 0000000..e5190d9 --- /dev/null +++ b/LED.ts @@ -0,0 +1,95 @@ +/// +/// + +// Require modules and globalize some stuff +var fs = require("fs"); +var base = require("./EV3Base.js"); + +var FilePathConstructor = base.FilePathConstructor; +var softBoolean = base.softBoolean; +var ledPosition = base.ledPosition; +var ledUnitColor = base.ledUnitColor; +var ledColorSetting = base.ledColorSetting; + +class LED { + private position: ledPosition; + + constructor(position: ledPosition) { + this.position = position; + } + + get color(): ledColorSetting { + var ledStatus = this.readLedStatus(); + + if (!ledStatus.greenLED && !ledStatus.redLED) + return ledColorSetting.off; + else if (ledStatus.greenLED && ledStatus.redLED) + return ledColorSetting.amber; + else if (ledStatus.greenLED) + return ledColorSetting.green; + else if (ledStatus.redLED) + return ledColorSetting.red; + } + + set color(value: ledColorSetting) { + var ledState = new LedState(false, false); + + switch (value) { + case ledColorSetting.amber: + ledState.greenLED = true; + ledState.redLED = true; + break; + case ledColorSetting.green: + ledState.greenLED = true; + break; + case ledColorSetting.red: + ledState.redLED = true; + break; + } + + this.writeLedStatus(ledState); + } + + /** + * Reads the status of the LED unit from the file; includes error handling if the file doesn't exist + */ + private readLedStatus(): LedState { + var redPropertyPath: string = FilePathConstructor.ledBrightness(this.position, ledUnitColor.red); + var greenPropertyPath: string = FilePathConstructor.ledBrightness(this.position, ledUnitColor.green); + + if (fs.existsSync(redPropertyPath) && fs.existsSync(greenPropertyPath)) + return new LedState( + !!String.fromCharCode(fs.readFileSync(redPropertyPath)[0]), + !!String.fromCharCode(fs.readFileSync(greenPropertyPath)[0]) + ); + else + throw new Error('The file could not be found.'); + } + + /** + * Sets the status of the LED unit. + */ + private writeLedStatus(value: LedState) { + var redPropertyPath: string = FilePathConstructor.ledBrightness(this.position, ledUnitColor.red); + var greenPropertyPath: string = FilePathConstructor.ledBrightness(this.position, ledUnitColor.green); + + if (fs.existsSync(redPropertyPath) && fs.existsSync(greenPropertyPath)) { + fs.writeFileSync(redPropertyPath, softBoolean(value.redLED, 0, 1)); + fs.writeFileSync(greenPropertyPath, softBoolean(value.greenLED, 0, 1)); + } + else + throw new Error('The file could not be found.'); + } +} + +class LedState { + redLED: boolean; + greenLED: boolean; + + constructor(redLED: boolean, greenLED: boolean) { + this.redLED = redLED; + this.greenLED = greenLED; + } +} + +module.exports = LED; \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..22fbe5d --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. \ No newline at end of file diff --git a/Motor.ts b/Motor.ts new file mode 100644 index 0000000..1e49479 --- /dev/null +++ b/Motor.ts @@ -0,0 +1,265 @@ +/// +/// + +//Require modules and globalize some stuff +var fs = require("fs"); +var base = require("./EV3Base.js"); + +var FilePathConstructor = base.FilePathConstructor; +var MotorPort = base.MotorPort; +var MotorProperty = base.MotorProperty; +var MotorPropertyValidation: any = base.MotorPropertyValidation; +var MotorType = base.MotorType; +var softBoolean = base.softBoolean; +var motorRunOptions = base.motorRunOptions; +var MotorRunMode = base.MotorRunMode; + +//Class to hold the basic function of the motor +class Motor { + private port: MotorPort; + private index: number; + + //Read-only properties + get position(): number { //Number of tacho ticks + return parseInt(this.readProperty(MotorProperty.position)); + } + + get type(): string { //The type of motor + return this.readProperty(MotorProperty.type); + } + + private scale(value: number, oldMin: number, oldMax: number, newMin: number, newMax: number): number { + return ((value - oldMin) / (oldMax - oldMin)) * (newMax - newMin) + newMin; + } + + /** + * Reads the value of a property from the file; includes error handling if the file doesn't exist + * @param {MotorProperty} property The property to read + */ + private readProperty(property: MotorProperty): string { + var propertyPath: string = FilePathConstructor.motorProperty(this.index, property); + + base.debugLog('READING PROPERTY {0}', propertyPath); + + if (fs.existsSync(propertyPath)) + return fs.readFileSync(propertyPath).toString().match(/[0-9A-Za-z._]+/)[0]; + else + throw new Error('The property file could not be found. Either the specified motor is not available or the property does not exist.'); + } + + //Writable properties + + //targetSpeed: The speed setpoint + get targetSpeed(): number { + if (this.regulationMode == 1) { + switch (this.type) { + case MotorType[MotorType.tacho]: + return this.scale(this.readProperty(MotorProperty.pulses_per_second), -900, 900, -100, 100); + case MotorType[MotorType.minitacho]: + return this.scale(this.readProperty(MotorProperty.pulses_per_second), -1200, 1200, -100, 100); + } + } + } + + set targetSpeed(value: number) { + if (this.regulationMode == 1) { + switch (this.type) { + case MotorType[MotorType.tacho]: + this.writeProperty(MotorProperty.pulses_per_second_sp, this.scale(value, -100, 100, -900, 900)); + break; + case MotorType[MotorType.minitacho]: + this.writeProperty(MotorProperty.pulses_per_second_sp, this.scale(value, -100, 100, -1200, 1200)); + break; + } + } + } + + //run: enables the motors. any type. + get run(): any { + return !!parseInt(this.readProperty(MotorProperty.run)); + } + + set run(value: any) { + this.writeProperty(MotorProperty.run, softBoolean(value, 0, 1)); + } + + //regulationMode + get regulationMode(): number { + return parseInt(this.readProperty(MotorProperty.regulation_mode)); + } + + set regulationMode(value: number) { + if (this.run) + this.writeProperty(MotorProperty.regulation_mode, softBoolean(value, 'off', 'on')); + else + throw new Error('You must stop the motor before changing the regulation mode.'); + } + + //stopMode: Choses how to stop the motor + get stopMode(): string { + return this.readProperty(MotorProperty.stop_mode); + } + + set stopMode(value: string) { + this.writeProperty(MotorProperty.stop_mode, value); + } + + /** + * Writes a value for a property. + * Checks the input against the validation params specified for each property; will throw if the input isn't valid. + */ + private writeProperty(property: MotorProperty, value: any) { + var propertySpec = MotorPropertyValidation[property]; + switch (propertySpec.type) { + case 'number': + //console.log(typeof value + ', ' + value); + if (isNaN(value)) + throw new Error('The specified value is not a number.'); + + if (typeof propertySpec.min != 'undefined') + if (value < propertySpec.min) + throw new Error('The specified value must be greater than or equal to ' + propertySpec.min + '. Property: ' + MotorProperty[property]); + + if (typeof propertySpec.max != 'undefined') + if (value > propertySpec.max) + throw new Error('The specified value must be less than or equal to ' + propertySpec.max + '. Property: ' + MotorProperty[property]); + + if (typeof propertySpec.values != 'undefined') + if (propertySpec.values.indexOf(value) == -1) + throw new Error('"' + value + '" is not an acceptable value.'); + + break; + + case 'string': + if (typeof propertySpec.values != 'undefined') + if (propertySpec.values.indexOf(value) == -1) + throw new Error('"' + value + '" is not an acceptable value.'); + break; + } + + var propertyPath: string = FilePathConstructor.motorProperty(this.index, property); + + base.debugLog('WRITING PROPERTY {0}', propertyPath); + + if (fs.existsSync(propertyPath)) + return fs.writeFileSync(propertyPath, value); + else + throw new Error('The property file could not be found. Either the specified motor is not available or the property does not exist.'); + } + + /** + * Starts the motor. + */ + public startMotor(options: any) { + base.debugLog('STARTING MOTOR {0},{1} with options {2}', MotorPort[this.port], this.index, options); + + for (var i in defaultMotorRunOptions) + if (options[i] == undefined) + options[i] = defaultMotorRunOptions[i]; + + if (options.time != undefined) { + this.writeProperty(MotorProperty.run_mode, MotorRunMode[MotorRunMode.time]); + this.writeProperty(MotorProperty.time_sp, options.time); + } + else + this.writeProperty(MotorProperty.run_mode, MotorRunMode[MotorRunMode.forever]) + + this.writeProperty(MotorProperty.regulation_mode, softBoolean(options.regulationMode, 'off', 'on')); + + if (softBoolean(options.regulationMode)) { + switch (this.type) { + case MotorType[MotorType.tacho]: + this.writeProperty(MotorProperty.pulses_per_second_sp, this.scale(options.targetSpeed, -100, 100, -900, 900)); + break; + case MotorType[MotorType.minitacho]: + this.writeProperty(MotorProperty.pulses_per_second_sp, this.scale(options.targetSpeed, -100, 100, -1200, 1200)); + break; + } + } + else + this.writeProperty(MotorProperty.duty_cycle_sp, options.targetSpeed); + + this.writeProperty(MotorProperty.stop_mode, options.stopMode); + this.writeProperty(MotorProperty.run, softBoolean(options.run, 0, 1)); + } + + /** + * Runs the motor to a specified position. Works well with holdMode and brakeMode. + */ + public runServo(options: any) { + base.debugLog('RUNNING SERVO {0},{1} with options {2}', MotorPort[this.port], this.index, options); + for (var i in defaultServoRunOptions) + if (options[i] == undefined) + options[i] = defaultServoRunOptions[i]; + + this.writeProperty(MotorProperty.run, 0); + + switch (this.type) { + case MotorType[MotorType.tacho]: + this.writeProperty(MotorProperty.pulses_per_second_sp, this.scale(options.targetSpeed, -100, 100, -900, 900)); + break; + case MotorType[MotorType.minitacho]: + this.writeProperty(MotorProperty.pulses_per_second_sp, this.scale(options.targetSpeed, -100, 100, -1200, 1200)); + break; + } + + this.writeProperty(MotorProperty.regulation_mode, 'on'); + + this.writeProperty(MotorProperty.position_mode, options.positionMode); + + this.writeProperty(MotorProperty.position_sp, options.position); + this.writeProperty(MotorProperty.stop_mode, options.stopMode); + this.writeProperty(MotorProperty.run, 1); + } + + /** + * Stops the motor by reversing the direction + */ + public brake() { + this.stopMode = 'brake'; + + this.startMotor({ run: false }); + } + + /** + * Stops the motor and actively holds it in place + */ + public hold() { + this.stopMode = 'hold'; + + this.startMotor({ run: false }); + } + + /** + * Turns off the motor but allows it to coast + */ + public coast() { + this.stopMode = 'coast'; + + this.startMotor({ run: false }); + } + + constructor(port: MotorPort) { + this.port = port; + this.index = FilePathConstructor.motorIndex(port); + + base.debugLog('MOTOR CREATED at index {0} on port {1}', this.index, MotorPort[this.port]); + } +} + +var defaultMotorRunOptions = { + targetSpeed: 0, + run: 1, + regulationMode: false, + time: undefined, + stopMode: 'coast' +} + +var defaultServoRunOptions = { + targetSpeed: 30, + positionMode: 'relative', + position: 0, + stopMode: 'coast' +} + +module.exports = Motor; \ No newline at end of file diff --git a/README.md b/README.md index 5201758..52d1e46 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,56 @@ -Relocation notice -================= +
+**IMPORTANT NOTE: AS OF 9/6/2014, ALL WORK HAS STOPPED IN THIS REPO. Development will continue here: http://github.com/ev3dev/ev3dev-lang in the `language-binding-unification` branch.** +
-AS OF 9/6/2014, ALL WORK HAS STOPPED IN THIS REPO. Development will -continue here: http://github.com/ev3dev/ev3dev-lang. +ev3dev-NodeJS +============= + +ev3dev-NodeJS is a NodeJS module that exposes the features of the ev3dev API. Your brick must be running [ev3dev](http://github.com/mindboards/ev3dev) and must have NodeJS installed. + +We currently support: + +- Motors + - Run forever + - Run time + - Run servo/position +- Sensors + - Generic read support +- LEDs + +**NOTE**: This library should be treated like an alpha release. The APIs are still changing rapidly, and the functionality cannot be fully tested until the codebase is more stable. + +Motors +------ +``` +//Require the module +var ev3 = require('ev3dev'); + +//Create the motor on port A +var motorA = new ev3.Motor(ev3.MotorPort.A); + +//Run the motor at 60% power for five seconds, and then hold it in place +motorA.startMotor({ + targetSpeed: 60, + time: 5000, + stopMode: 'hold' +}); +``` + +LEDs +---- +``` +//Require the module +var ev3 = require('ev3dev'); + +//Initialize both LEDs +var leftLED = new ev3.LED(ev3.ledPosition.left); +var rightLED = new ev3.LED(ev3.ledPosition.right); + +//Set their color +leftLED.color = ev3.ledColorSetting.green; +rightLED.color = ev3.ledColorSetting.red; +``` + + + +Simple, right? Learn more about the [Motor](https://github.com/WasabiFan/ev3dev-NodeJS/wiki/Motors) and [LED](https://github.com/WasabiFan/ev3dev-NodeJS/wiki/LEDs) APIs on the Wiki. diff --git a/Sensors/Sensor.ts b/Sensors/Sensor.ts new file mode 100644 index 0000000..18c0d97 --- /dev/null +++ b/Sensors/Sensor.ts @@ -0,0 +1,82 @@ +/// + +//Require modules and globalize some stuff +var fs = require("fs"); +var base = require("../EV3Base.js"); + +var FilePathConstructor = base.FilePathConstructor; +var softBoolean = base.softBoolean; + +class GenericSensor { + sensorPort: number; + sensorIndex: number; + numValues: number; + + constructor(sensorPort: number) { + this.sensorPort = sensorPort; + this.sensorIndex = FilePathConstructor.sensorNumber(sensorPort); + + var numValuesProperty: string = FilePathConstructor.sensorProperty(this.sensorIndex, 'num_values'); + + if (fs.existsSync(numValuesProperty)) + this.numValues = fs.readFileSync(numValuesProperty).toString().match(/[0-9A-Za-z._]+/)[0]; + } + + public getValue(valueN: number): string { + var val; + + if (valueN < this.numValues) + val = this.readProperty('value' + valueN); + else + throw new Error('The value index must be less than ' + this.numValues); + + val = val.match(/[0-9A-Za-z._]+/)[0] + + var dpVal = val / Math.pow(10, parseInt(this.readProperty('dp'))); + + if (!isNaN(dpVal)) + return dpVal; + + return val; + } + + //Get the possible sensor modes + get modes(): string[] { + return this.readProperty('modes').split(' '); + } + + //Get the current sensor mode + get mode(): string { + return this.readProperty('mode'); + } + + //Get the sensor type_id + get typeId(): string { + return this.readProperty('type_id'); + } + + private readProperty(property: string): string { + var propertyPath: string = FilePathConstructor.sensorProperty(this.sensorIndex, property); + + if (fs.existsSync(propertyPath)) + return fs.readFileSync(propertyPath).toString().replace('\n', ''); + else + throw new Error('The property file could not be found. Either the specified sensor is not available or the property does not exist.'); + } + + //Set the sensor mode + set mode(value: string) { + this.writeProperty('mode', value); + } + + private writeProperty(property: string, value: any) { + var propertyPath: string = FilePathConstructor.sensorProperty(this.sensorIndex, property); + + if (fs.existsSync(propertyPath)) + fs.writeFileSync(propertyPath, value); + else + throw new Error('The property file could not be found. Either the specified sensor is not available or the property does not exist.'); + } +} + +module.exports = GenericSensor; \ No newline at end of file diff --git a/Sensors/SimpleSensors.ts b/Sensors/SimpleSensors.ts new file mode 100644 index 0000000..f792173 --- /dev/null +++ b/Sensors/SimpleSensors.ts @@ -0,0 +1,48 @@ +/// + +var GenericSensor = require('./Sensor.js'); +var base = require("../EV3Base.js"); + +var softBoolean = base.softBoolean; + +class TouchSensor extends GenericSensor { + get touchState(): boolean { + return softBoolean(this.getValue(0)); + } +} + +class UltrasonicSensor extends GenericSensor { + constructor(sensorPort: number) { + super(sensorPort); + this.unitMode = 'in'; + } + + get unitMode(): string { + switch (this.mode) { + case 'US-DIST-CM': + case 'US-SI-CM': + case 'NXT-US-CM': + case 'NXT-US-SI-CM': + return 'CM'; + case 'US-DIST-IN': + case 'US-SI-IN': + case 'NXT-US-IN': + case 'NXT-US-SI-IN': + return 'IN'; + } + } + + set unitMode(unit: string) { + if (parseInt(this.typeId) == 5) + this.mode = 'NXT-US-' + unit.toUpperCase(); + else + this.mode = 'US-DIST-' + unit.toUpperCase(); + } + + get distanceValue(): number { + return parseFloat(this.getValue(0)); + } +} + +module.exports.TouchSensor = TouchSensor; +module.exports.UltrasonicSensor = UltrasonicSensor; \ No newline at end of file diff --git a/linq.d.ts b/linq.d.ts new file mode 100644 index 0000000..6699a8a --- /dev/null +++ b/linq.d.ts @@ -0,0 +1,192 @@ +// Typing for linq.js, ver 3.0.3-Beta4 + +declare module linqjs { + interface IEnumerator { + current(): any; + moveNext(): boolean; + dispose(): void; + } + + interface EnumerableStatic { + Utils: { + createLambda(expression: any): (...params: any[]) => any; + createEnumerable(getEnumerator: () => IEnumerator): Enumerable; + createEnumerator(initialize: () => void, tryGetNext: () => boolean, dispose: () => void): IEnumerator; + extendTo(type: any): void; + }; + choice(...params: any[]): Enumerable; + cycle(...params: any[]): Enumerable; + empty(): Enumerable; + from(): Enumerable; + from(obj: Enumerable): Enumerable; + from(obj: string): Enumerable; + from(obj: number): Enumerable; + from(obj: { length: number;[x: number]: any; }): Enumerable; + from(obj: any): Enumerable; + make(element: any): Enumerable; + matches(input: string, pattern: RegExp): Enumerable; + matches(input: string, pattern: string, flags?: string): Enumerable; + range(start: number, count: number, step?: number): Enumerable; + rangeDown(start: number, count: number, step?: number): Enumerable; + rangeTo(start: number, to: number, step?: number): Enumerable; + repeat(element: any, count?: number): Enumerable; + repeatWithFinalize(initializer: () => any, finalizer: (element) => void): Enumerable; + generate(func: () => any, count?: number): Enumerable; + toInfinity(start?: number, step?: number): Enumerable; + toNegativeInfinity(start?: number, step?: number): Enumerable; + unfold(seed: any, func: (value: any) => any): Enumerable; + defer(enumerableFactory: () => Enumerable): Enumerable; + } + + interface Enumerable { + constructor(getEnumerator: () => IEnumerator); + getEnumerator(): IEnumerator; + + // Extension Methods + traverseBreadthFirst(func: (element: any) => Enumerable, resultSelector?: (element: any, nestLevel: number) => any): Enumerable; + traverseDepthFirst(func: (element: any) => Enumerable, resultSelector?: (element: any, nestLevel: number) => any): Enumerable; + flatten(): Enumerable; + pairwise(selector: (prev: any, current: any) => any): Enumerable; + scan(func: (prev: any, current: any) => any): Enumerable; + scan(seed: any, func: (prev: any, current: any) => any): Enumerable; + select(selector: (element: any, index: number) => any): Enumerable; + selectMany(collectionSelector: (element: any, index: number) => any[], resultSelector?: (outer: any, inner: any) => any): Enumerable; + selectMany(collectionSelector: (element: any, index: number) => Enumerable, resultSelector?: (outer: any, inner: any) => any): Enumerable; + selectMany(collectionSelector: (element: any, index: number) => { length: number;[x: number]: any; }, resultSelector?: (outer: any, inner: any) => any): Enumerable; + where(predicate: (element: any, index: number) => boolean): Enumerable; + choose(selector: (element: any, index: number) => any): Enumerable; + ofType(type: any): Enumerable; + zip(second: any[], resultSelector: (first: any, second: any, index: number) => any): Enumerable; + zip(second: Enumerable, resultSelector: (first: any, second: any, index: number) => any): Enumerable; + zip(second: { length: number;[x: number]: any; }, resultSelector: (first: any, second: any, index: number) => any): Enumerable; + zip(...params: any[]): Enumerable; // last one is selector + merge(second: any[], resultSelector: (first: any, second: any, index: number) => any): Enumerable; + merge(second: Enumerable, resultSelector: (first: any, second: any, index: number) => any): Enumerable; + merge(second: { length: number;[x: number]: any; }, resultSelector: (first: any, second: any, index: number) => any): Enumerable; + merge(...params: any[]): Enumerable; // last one is selector + join(inner: Enumerable, outerKeySelector: (outer: any) => any, innerKeySelector: (inner: any) => any, resultSelector: (outer: any, inner: any) => any, compareSelector?: (obj: any) => any): Enumerable; + groupJoin(inner: Enumerable, outerKeySelector: (outer: any) => any, innerKeySelector: (inner: any) => any, resultSelector: (outer: any, inner: any) => any, compareSelector?: (obj: any) => any): Enumerable; + all(predicate: (element: any) => boolean): boolean; + any(predicate?: (element: any) => boolean): boolean; + isEmpty(): boolean; + concat(...sequences: any[]): Enumerable; + insert(index: number, second: any[]): Enumerable; + insert(index: number, second: Enumerable): Enumerable; + insert(index: number, second: { length: number;[x: number]: any; }): Enumerable; + alternate(alternateValue: any): Enumerable; + alternate(alternateSequence: any[]): Enumerable; + alternate(alternateSequence: Enumerable): Enumerable; + contains(value: any, compareSelector: (element: any) => any): Enumerable; + defaultIfEmpty(defaultValue?: any): Enumerable; + distinct(compareSelector?: (element: any) => any): Enumerable; + distinctUntilChanged(compareSelector: (element: any) => any): Enumerable; + except(second: any[], compareSelector?: (element: any) => any): Enumerable; + except(second: { length: number;[x: number]: any; }, compareSelector?: (element: any) => any): Enumerable; + except(second: Enumerable, compareSelector?: (element: any) => any): Enumerable; + intersect(second: any[], compareSelector?: (element: any) => any): Enumerable; + intersect(second: { length: number;[x: number]: any; }, compareSelector?: (element: any) => any): Enumerable; + intersect(second: Enumerable, compareSelector?: (element: any) => any): Enumerable; + sequenceEqual(second: any[], compareSelector?: (element: any) => any): Enumerable; + sequenceEqual(second: { length: number;[x: number]: any; }, compareSelector?: (element: any) => any): Enumerable; + sequenceEqual(second: Enumerable, compareSelector?: (element: any) => any): Enumerable; + union(second: any[], compareSelector?: (element: any) => any): Enumerable; + union(second: { length: number;[x: number]: any; }, compareSelector?: (element: any) => any): Enumerable; + union(second: Enumerable, compareSelector?: (element: any) => any): Enumerable; + orderBy(keySelector: (element: any) => any): OrderedEnumerable; + orderByDescending(keySelector: (element: any) => any): OrderedEnumerable; + reverse(): Enumerable; + shuffle(): Enumerable; + weightedSample(weightSelector: (element: any) => any): Enumerable; + groupBy(keySelector: (element: any) => any, elementSelector?: (element: any) => any, resultSelector?: (key: any, element: any) => any, compareSelector?: (element: any) => any): Enumerable; + partitionBy(keySelector: (element: any) => any, elementSelector?: (element: any) => any, resultSelector?: (key: any, element: any) => any, compareSelector?: (element: any) => any): Enumerable; + buffer(count: number): Enumerable; + aggregate(func: (prev: any, current: any) => any): any; + aggregate(seed: any, func: (prev: any, current: any) => any, resultSelector?: (last: any) => any): any; + average(selector?: (element: any) => any): number; + count(predicate?: (element: any, index: number) => boolean): number; + max(selector?: (element: any) => any): number; + min(selector?: (element: any) => any): number; + maxBy(keySelector: (element: any) => any): any; + minBy(keySelector: (element: any) => any): any; + sum(selector?: (element: any) => any): number; + elementAt(index: number): any; + elementAtOrDefault(index: number, defaultValue?: any): any; + first(predicate?: (element: any, index: number) => boolean): any; + firstOrDefault(predicate?: (element: any, index: number) => boolean, defaultValue?: any): any; + last(predicate?: (element: any, index: number) => boolean): any; + lastOrDefault(predicate?: (element: any, index: number) => boolean, defaultValue?: any): any; + single(predicate?: (element: any, index: number) => boolean): any; + singleOrDefault(predicate?: (element: any, index: number) => boolean, defaultValue?: any): any; + skip(count: number): Enumerable; + skipWhile(predicate: (element: any, index: number) => boolean): Enumerable; + take(count: number): Enumerable; + takeWhile(predicate: (element: any, index: number) => boolean): Enumerable; + takeExceptLast(count?: number): Enumerable; + takeFromLast(count: number): Enumerable; + indexOf(item: any): number; + indexOf(predicate: (element: any, index: number) => boolean): number; + lastIndexOf(item: any): number; + lastIndexOf(predicate: (element: any, index: number) => boolean): number; + asEnumerable(): Enumerable; + toArray(): any[]; + toLookup(keySelector: (element: any) => any, elementSelector?: (element: any) => any, compareSelector?: (element: any) => any): Lookup; + toObject(keySelector: (element: any) => any, elementSelector?: (element: any) => any): Object; + toDictionary(keySelector: (element: any) => any, elementSelector?: (element: any) => any, compareSelector?: (element: any) => any): Dictionary; + toJSONString(replacer: (key: string, value: any) => any): string; + toJSONString(replacer: any[]): string; + toJSONString(replacer: (key: string, value: any) => any, space: any): string; + toJSONString(replacer: any[], space: any): string; + toJoinedString(separator?: string, selector?: (element: any, index: number) => any): string; + doAction(action: (element: any, index: number) => void): Enumerable; + doAction(action: (element: any, index: number) => boolean): Enumerable; + forEach(action: (element: any, index: number) => void): void; + forEach(action: (element: any, index: number) => boolean): void; + write(separator?: string, selector?: (element: any) => any): void; + writeLine(selector?: (element: any) => any): void; + force(): void; + letBind(func: (source: Enumerable) => any[]): Enumerable; + letBind(func: (source: Enumerable) => { length: number;[x: number]: any; }): Enumerable; + letBind(func: (source: Enumerable) => Enumerable): Enumerable; + share(): DisposableEnumerable; + memoize(): DisposableEnumerable; + catchError(handler: (exception: any) => void): Enumerable; + finallyAction(finallyAction: () => void): Enumerable; + log(selector?: (element: any) => void): Enumerable; + trace(message?: string, selector?: (element: any) => void): Enumerable; + } + + interface OrderedEnumerable extends Enumerable { + createOrderedEnumerable(keySelector: (element: any) => any, descending: boolean): OrderedEnumerable; + thenBy(keySelector: (element: any) => any): OrderedEnumerable; + thenByDescending(keySelector: (element: any) => any): OrderedEnumerable; + } + + interface DisposableEnumerable extends Enumerable { + dispose(): void; + } + + interface Dictionary { + add(key: any, value: any): void; + get(key: any): any; + set(key: any, value: any): boolean; + contains(key: any): boolean; + clear(): void; + remove(key: any): void; + count(): number; + toEnumerable(): Enumerable; // Enumerable + } + + interface Lookup { + count(): number; + get(key: any): Enumerable; + contains(key: any): boolean; + toEnumerable(): Enumerable; // Enumerable + } + + interface Grouping extends Enumerable { + key(): any; + } +} + +// export definition +declare var Enumerable: linqjs.EnumerableStatic; diff --git a/node.d.ts b/node.d.ts new file mode 100644 index 0000000..a508ef5 --- /dev/null +++ b/node.d.ts @@ -0,0 +1,1296 @@ +// Type definitions for Node.js v0.10.1 +// Project: http://nodejs.org/ +// Definitions by: Microsoft TypeScript , DefinitelyTyped +// Definitions: https://github.com/borisyankov/DefinitelyTyped + +/************************************************ +* * +* Node.js v0.10.1 API * +* * +************************************************/ + +/************************************************ +* * +* GLOBAL * +* * +************************************************/ +declare var process: NodeJS.Process; +declare var global: any; + +declare var __filename: string; +declare var __dirname: string; + +declare function setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearTimeout(timeoutId: NodeJS.Timer): void; +declare function setInterval(callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timer; +declare function clearInterval(intervalId: NodeJS.Timer): void; +declare function setImmediate(callback: (...args: any[]) => void, ...args: any[]): any; +declare function clearImmediate(immediateId: any): void; + +declare var require: { + (id: string): any; + resolve(id:string): string; + cache: any; + extensions: any; + main: any; +}; + +declare var module: { + exports: any; + require(id: string): any; + id: string; + filename: string; + loaded: boolean; + parent: any; + children: any[]; +}; + +// Same as module.exports +declare var exports: any; +declare var SlowBuffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + + +// Buffer class +interface Buffer extends NodeBuffer {} +declare var Buffer: { + new (str: string, encoding?: string): Buffer; + new (size: number): Buffer; + new (array: any[]): Buffer; + prototype: Buffer; + isBuffer(obj: any): boolean; + byteLength(string: string, encoding?: string): number; + concat(list: Buffer[], totalLength?: number): Buffer; +}; + +/************************************************ +* * +* GLOBAL INTERFACES * +* * +************************************************/ +declare module NodeJS { + export interface ErrnoException extends Error { + errno?: any; + code?: string; + path?: string; + syscall?: string; + } + + export interface EventEmitter { + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } + + export interface ReadableStream extends EventEmitter { + readable: boolean; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: ReadableStream): ReadableStream; + } + + export interface WritableStream extends EventEmitter { + writable: boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface ReadWriteStream extends ReadableStream, WritableStream {} + + export interface Process extends EventEmitter { + stdout: WritableStream; + stderr: WritableStream; + stdin: ReadableStream; + argv: string[]; + execPath: string; + abort(): void; + chdir(directory: string): void; + cwd(): string; + env: any; + exit(code?: number): void; + getgid(): number; + setgid(id: number): void; + setgid(id: string): void; + getuid(): number; + setuid(id: number): void; + setuid(id: string): void; + version: string; + versions: { + http_parser: string; + node: string; + v8: string; + ares: string; + uv: string; + zlib: string; + openssl: string; + }; + config: { + target_defaults: { + cflags: any[]; + default_configuration: string; + defines: string[]; + include_dirs: string[]; + libraries: string[]; + }; + variables: { + clang: number; + host_arch: string; + node_install_npm: boolean; + node_install_waf: boolean; + node_prefix: string; + node_shared_openssl: boolean; + node_shared_v8: boolean; + node_shared_zlib: boolean; + node_use_dtrace: boolean; + node_use_etw: boolean; + node_use_openssl: boolean; + target_arch: string; + v8_no_strict_aliasing: number; + v8_use_snapshot: boolean; + visibility: string; + }; + }; + kill(pid: number, signal?: string): void; + pid: number; + title: string; + arch: string; + platform: string; + memoryUsage(): { rss: number; heapTotal: number; heapUsed: number; }; + nextTick(callback: Function): void; + umask(mask?: number): number; + uptime(): number; + hrtime(time?:number[]): number[]; + + // Worker + send?(message: any, sendHandle?: any): void; + } + + export interface Timer { + ref() : void; + unref() : void; + } +} + +/** + * @deprecated + */ +interface NodeBuffer { + [index: number]: number; + write(string: string, offset?: number, length?: number, encoding?: string): number; + toString(encoding?: string, start?: number, end?: number): string; + toJSON(): any; + length: number; + copy(targetBuffer: Buffer, targetStart?: number, sourceStart?: number, sourceEnd?: number): number; + slice(start?: number, end?: number): Buffer; + readUInt8(offset: number, noAsset?: boolean): number; + readUInt16LE(offset: number, noAssert?: boolean): number; + readUInt16BE(offset: number, noAssert?: boolean): number; + readUInt32LE(offset: number, noAssert?: boolean): number; + readUInt32BE(offset: number, noAssert?: boolean): number; + readInt8(offset: number, noAssert?: boolean): number; + readInt16LE(offset: number, noAssert?: boolean): number; + readInt16BE(offset: number, noAssert?: boolean): number; + readInt32LE(offset: number, noAssert?: boolean): number; + readInt32BE(offset: number, noAssert?: boolean): number; + readFloatLE(offset: number, noAssert?: boolean): number; + readFloatBE(offset: number, noAssert?: boolean): number; + readDoubleLE(offset: number, noAssert?: boolean): number; + readDoubleBE(offset: number, noAssert?: boolean): number; + writeUInt8(value: number, offset: number, noAssert?: boolean): void; + writeUInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeUInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeInt8(value: number, offset: number, noAssert?: boolean): void; + writeInt16LE(value: number, offset: number, noAssert?: boolean): void; + writeInt16BE(value: number, offset: number, noAssert?: boolean): void; + writeInt32LE(value: number, offset: number, noAssert?: boolean): void; + writeInt32BE(value: number, offset: number, noAssert?: boolean): void; + writeFloatLE(value: number, offset: number, noAssert?: boolean): void; + writeFloatBE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleLE(value: number, offset: number, noAssert?: boolean): void; + writeDoubleBE(value: number, offset: number, noAssert?: boolean): void; + fill(value: any, offset?: number, end?: number): void; +} + +/************************************************ +* * +* MODULES * +* * +************************************************/ +declare module "buffer" { + export var INSPECT_MAX_BYTES: number; +} + +declare module "querystring" { + export function stringify(obj: any, sep?: string, eq?: string): string; + export function parse(str: string, sep?: string, eq?: string, options?: { maxKeys?: number; }): any; + export function escape(): any; + export function unescape(): any; +} + +declare module "events" { + export class EventEmitter implements NodeJS.EventEmitter { + static listenerCount(emitter: EventEmitter, event: string): number; + + addListener(event: string, listener: Function): EventEmitter; + on(event: string, listener: Function): EventEmitter; + once(event: string, listener: Function): EventEmitter; + removeListener(event: string, listener: Function): EventEmitter; + removeAllListeners(event?: string): EventEmitter; + setMaxListeners(n: number): void; + listeners(event: string): Function[]; + emit(event: string, ...args: any[]): boolean; + } +} + +declare module "http" { + import events = require("events"); + import net = require("net"); + import stream = require("stream"); + + export interface Server extends events.EventEmitter { + listen(port: number, hostname?: string, backlog?: number, callback?: Function): Server; + listen(path: string, callback?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(cb?: any): Server; + address(): { port: number; family: string; address: string; }; + maxHeadersCount: number; + } + export interface ServerRequest extends events.EventEmitter, stream.Readable { + method: string; + url: string; + headers: any; + trailers: string; + httpVersion: string; + setEncoding(encoding?: string): void; + pause(): void; + resume(): void; + connection: net.Socket; + } + export interface ServerResponse extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + writeContinue(): void; + writeHead(statusCode: number, reasonPhrase?: string, headers?: any): void; + writeHead(statusCode: number, headers?: any): void; + statusCode: number; + setHeader(name: string, value: string): void; + sendDate: boolean; + getHeader(name: string): string; + removeHeader(name: string): void; + write(chunk: any, encoding?: string): any; + addTrailers(headers: any): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientRequest extends events.EventEmitter, stream.Writable { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + write(chunk: any, encoding?: string): void; + abort(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setSocketKeepAlive(enable?: boolean, initialDelay?: number): void; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + export interface ClientResponse extends events.EventEmitter, stream.Readable { + statusCode: number; + httpVersion: string; + headers: any; + trailers: any; + setEncoding(encoding?: string): void; + pause(): void; + resume(): void; + } + export interface Agent { maxSockets: number; sockets: any; requests: any; } + + export var STATUS_CODES: { + [errorCode: number]: string; + [errorCode: string]: string; + }; + export function createServer(requestListener?: (request: ServerRequest, response: ServerResponse) =>void ): Server; + export function createClient(port?: number, host?: string): any; + export function request(options: any, callback?: Function): ClientRequest; + export function get(options: any, callback?: Function): ClientRequest; + export var globalAgent: Agent; +} + +declare module "cluster" { + import child = require("child_process"); + import events = require("events"); + + export interface ClusterSettings { + exec?: string; + args?: string[]; + silent?: boolean; + } + + export class Worker extends events.EventEmitter { + id: string; + process: child.ChildProcess; + suicide: boolean; + send(message: any, sendHandle?: any): void; + kill(signal?: string): void; + destroy(signal?: string): void; + disconnect(): void; + } + + export var settings: ClusterSettings; + export var isMaster: boolean; + export var isWorker: boolean; + export function setupMaster(settings?: ClusterSettings): void; + export function fork(env?: any): Worker; + export function disconnect(callback?: Function): void; + export var worker: Worker; + export var workers: Worker[]; + + // Event emitter + export function addListener(event: string, listener: Function): void; + export function on(event: string, listener: Function): any; + export function once(event: string, listener: Function): void; + export function removeListener(event: string, listener: Function): void; + export function removeAllListeners(event?: string): void; + export function setMaxListeners(n: number): void; + export function listeners(event: string): Function[]; + export function emit(event: string, ...args: any[]): boolean; +} + +declare module "zlib" { + import stream = require("stream"); + export interface ZlibOptions { chunkSize?: number; windowBits?: number; level?: number; memLevel?: number; strategy?: number; dictionary?: any; } + + export interface Gzip extends stream.Transform { } + export interface Gunzip extends stream.Transform { } + export interface Deflate extends stream.Transform { } + export interface Inflate extends stream.Transform { } + export interface DeflateRaw extends stream.Transform { } + export interface InflateRaw extends stream.Transform { } + export interface Unzip extends stream.Transform { } + + export function createGzip(options?: ZlibOptions): Gzip; + export function createGunzip(options?: ZlibOptions): Gunzip; + export function createDeflate(options?: ZlibOptions): Deflate; + export function createInflate(options?: ZlibOptions): Inflate; + export function createDeflateRaw(options?: ZlibOptions): DeflateRaw; + export function createInflateRaw(options?: ZlibOptions): InflateRaw; + export function createUnzip(options?: ZlibOptions): Unzip; + + export function deflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function deflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function gunzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflate(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function inflateRaw(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + export function unzip(buf: Buffer, callback: (error: Error, result: any) =>void ): void; + + // Constants + export var Z_NO_FLUSH: number; + export var Z_PARTIAL_FLUSH: number; + export var Z_SYNC_FLUSH: number; + export var Z_FULL_FLUSH: number; + export var Z_FINISH: number; + export var Z_BLOCK: number; + export var Z_TREES: number; + export var Z_OK: number; + export var Z_STREAM_END: number; + export var Z_NEED_DICT: number; + export var Z_ERRNO: number; + export var Z_STREAM_ERROR: number; + export var Z_DATA_ERROR: number; + export var Z_MEM_ERROR: number; + export var Z_BUF_ERROR: number; + export var Z_VERSION_ERROR: number; + export var Z_NO_COMPRESSION: number; + export var Z_BEST_SPEED: number; + export var Z_BEST_COMPRESSION: number; + export var Z_DEFAULT_COMPRESSION: number; + export var Z_FILTERED: number; + export var Z_HUFFMAN_ONLY: number; + export var Z_RLE: number; + export var Z_FIXED: number; + export var Z_DEFAULT_STRATEGY: number; + export var Z_BINARY: number; + export var Z_TEXT: number; + export var Z_ASCII: number; + export var Z_UNKNOWN: number; + export var Z_DEFLATED: number; + export var Z_NULL: number; +} + +declare module "os" { + export function tmpDir(): string; + export function hostname(): string; + export function type(): string; + export function platform(): string; + export function arch(): string; + export function release(): string; + export function uptime(): number; + export function loadavg(): number[]; + export function totalmem(): number; + export function freemem(): number; + export function cpus(): { model: string; speed: number; times: { user: number; nice: number; sys: number; idle: number; irq: number; }; }[]; + export function networkInterfaces(): any; + export var EOL: string; +} + +declare module "https" { + import tls = require("tls"); + import events = require("events"); + import http = require("http"); + + export interface ServerOptions { + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + crl?: any; + ciphers?: string; + honorCipherOrder?: boolean; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; + SNICallback?: (servername: string) => any; + } + + export interface RequestOptions { + host?: string; + hostname?: string; + port?: number; + path?: string; + method?: string; + headers?: any; + auth?: string; + agent?: any; + pfx?: any; + key?: any; + passphrase?: string; + cert?: any; + ca?: any; + ciphers?: string; + rejectUnauthorized?: boolean; + } + + export interface Agent { + maxSockets: number; + sockets: any; + requests: any; + } + export var Agent: { + new (options?: RequestOptions): Agent; + }; + export interface Server extends tls.Server { } + export function createServer(options: ServerOptions, requestListener?: Function): Server; + export function request(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest; + export function get(options: RequestOptions, callback?: (res: events.EventEmitter) =>void ): http.ClientRequest; + export var globalAgent: Agent; +} + +declare module "punycode" { + export function decode(string: string): string; + export function encode(string: string): string; + export function toUnicode(domain: string): string; + export function toASCII(domain: string): string; + export var ucs2: ucs2; + interface ucs2 { + decode(string: string): string; + encode(codePoints: number[]): string; + } + export var version: any; +} + +declare module "repl" { + import stream = require("stream"); + import events = require("events"); + + export interface ReplOptions { + prompt?: string; + input?: NodeJS.ReadableStream; + output?: NodeJS.WritableStream; + terminal?: boolean; + eval?: Function; + useColors?: boolean; + useGlobal?: boolean; + ignoreUndefined?: boolean; + writer?: Function; + } + export function start(options: ReplOptions): events.EventEmitter; +} + +declare module "readline" { + import events = require("events"); + import stream = require("stream"); + + export interface ReadLine extends events.EventEmitter { + setPrompt(prompt: string, length: number): void; + prompt(preserveCursor?: boolean): void; + question(query: string, callback: Function): void; + pause(): void; + resume(): void; + close(): void; + write(data: any, key?: any): void; + } + export interface ReadLineOptions { + input: NodeJS.ReadableStream; + output: NodeJS.WritableStream; + completer?: Function; + terminal?: boolean; + } + export function createInterface(options: ReadLineOptions): ReadLine; +} + +declare module "vm" { + export interface Context { } + export interface Script { + runInThisContext(): void; + runInNewContext(sandbox?: Context): void; + } + export function runInThisContext(code: string, filename?: string): void; + export function runInNewContext(code: string, sandbox?: Context, filename?: string): void; + export function runInContext(code: string, context: Context, filename?: string): void; + export function createContext(initSandbox?: Context): Context; + export function createScript(code: string, filename?: string): Script; +} + +declare module "child_process" { + import events = require("events"); + import stream = require("stream"); + + export interface ChildProcess extends events.EventEmitter { + stdin: stream.Writable; + stdout: stream.Readable; + stderr: stream.Readable; + pid: number; + kill(signal?: string): void; + send(message: any, sendHandle: any): void; + disconnect(): void; + } + + export function spawn(command: string, args?: string[], options?: { + cwd?: string; + stdio?: any; + custom?: any; + env?: any; + detached?: boolean; + }): ChildProcess; + export function exec(command: string, options: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function exec(command: string, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function execFile(file: string, args: string[], options: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: string; + killSignal?: string; + }, callback: (error: Error, stdout: Buffer, stderr: Buffer) =>void ): ChildProcess; + export function fork(modulePath: string, args?: string[], options?: { + cwd?: string; + env?: any; + encoding?: string; + }): ChildProcess; +} + +declare module "url" { + export interface Url { + href: string; + protocol: string; + auth: string; + hostname: string; + port: string; + host: string; + pathname: string; + search: string; + query: string; + slashes: boolean; + hash?: string; + path?: string; + } + + export interface UrlOptions { + protocol?: string; + auth?: string; + hostname?: string; + port?: string; + host?: string; + pathname?: string; + search?: string; + query?: any; + hash?: string; + path?: string; + } + + export function parse(urlStr: string, parseQueryString?: boolean , slashesDenoteHost?: boolean ): Url; + export function format(url: UrlOptions): string; + export function resolve(from: string, to: string): string; +} + +declare module "dns" { + export function lookup(domain: string, family: number, callback: (err: Error, address: string, family: number) =>void ): string; + export function lookup(domain: string, callback: (err: Error, address: string, family: number) =>void ): string; + export function resolve(domain: string, rrtype: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve4(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolve6(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveMx(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveTxt(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveSrv(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveNs(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function resolveCname(domain: string, callback: (err: Error, addresses: string[]) =>void ): string[]; + export function reverse(ip: string, callback: (err: Error, domains: string[]) =>void ): string[]; +} + +declare module "net" { + import stream = require("stream"); + + export interface Socket extends stream.Duplex { + // Extended base methods + write(buffer: Buffer): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + write(str: string, encoding?: string, fd?: string): boolean; + + connect(port: number, host?: string, connectionListener?: Function): void; + connect(path: string, connectionListener?: Function): void; + bufferSize: number; + setEncoding(encoding?: string): void; + write(data: any, encoding?: string, callback?: Function): void; + destroy(): void; + pause(): void; + resume(): void; + setTimeout(timeout: number, callback?: Function): void; + setNoDelay(noDelay?: boolean): void; + setKeepAlive(enable?: boolean, initialDelay?: number): void; + address(): { port: number; family: string; address: string; }; + remoteAddress: string; + remotePort: number; + bytesRead: number; + bytesWritten: number; + + // Extended base methods + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + end(data?: any, encoding?: string): void; + } + + export var Socket: { + new (options?: { fd?: string; type?: string; allowHalfOpen?: boolean; }): Socket; + }; + + export interface Server extends Socket { + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + close(callback?: Function): Server; + address(): { port: number; family: string; address: string; }; + maxConnections: number; + connections: number; + } + export function createServer(connectionListener?: (socket: Socket) =>void ): Server; + export function createServer(options?: { allowHalfOpen?: boolean; }, connectionListener?: (socket: Socket) =>void ): Server; + export function connect(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function connect(port: number, host?: string, connectionListener?: Function): Socket; + export function connect(path: string, connectionListener?: Function): Socket; + export function createConnection(options: { allowHalfOpen?: boolean; }, connectionListener?: Function): Socket; + export function createConnection(port: number, host?: string, connectionListener?: Function): Socket; + export function createConnection(path: string, connectionListener?: Function): Socket; + export function isIP(input: string): number; + export function isIPv4(input: string): boolean; + export function isIPv6(input: string): boolean; +} + +declare module "dgram" { + import events = require("events"); + + export function createSocket(type: string, callback?: Function): Socket; + + interface Socket extends events.EventEmitter { + send(buf: Buffer, offset: number, length: number, port: number, address: string, callback?: (error: Error, bytes: number) => void): void; + bind(port: number, address?: string, callback?: () => void): void; + close(): void; + address: { address: string; family: string; port: number; }; + setBroadcast(flag: boolean): void; + setMulticastTTL(ttl: number): void; + setMulticastLoopback(flag: boolean): void; + addMembership(multicastAddress: string, multicastInterface?: string): void; + dropMembership(multicastAddress: string, multicastInterface?: string): void; + } +} + +declare module "fs" { + import stream = require("stream"); + import events = require("events"); + + interface Stats { + isFile(): boolean; + isDirectory(): boolean; + isBlockDevice(): boolean; + isCharacterDevice(): boolean; + isSymbolicLink(): boolean; + isFIFO(): boolean; + isSocket(): boolean; + dev: number; + ino: number; + mode: number; + nlink: number; + uid: number; + gid: number; + rdev: number; + size: number; + blksize: number; + blocks: number; + atime: Date; + mtime: Date; + ctime: Date; + } + + interface FSWatcher extends events.EventEmitter { + close(): void; + } + + export interface ReadStream extends stream.Readable {} + export interface WriteStream extends stream.Writable {} + + export function rename(oldPath: string, newPath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function renameSync(oldPath: string, newPath: string): void; + export function truncate(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncate(path: string, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function truncateSync(path: string, len?: number): void; + export function ftruncate(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncate(fd: number, len: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function ftruncateSync(fd: number, len?: number): void; + export function chown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chownSync(path: string, uid: number, gid: number): void; + export function fchown(fd: number, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchownSync(fd: number, uid: number, gid: number): void; + export function lchown(path: string, uid: number, gid: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchownSync(path: string, uid: number, gid: number): void; + export function chmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function chmodSync(path: string, mode: number): void; + export function chmodSync(path: string, mode: string): void; + export function fchmod(fd: number, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmod(fd: number, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fchmodSync(fd: number, mode: number): void; + export function fchmodSync(fd: number, mode: string): void; + export function lchmod(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmod(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function lchmodSync(path: string, mode: number): void; + export function lchmodSync(path: string, mode: string): void; + export function stat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function lstat(path: string, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function fstat(fd: number, callback?: (err: NodeJS.ErrnoException, stats: Stats) => any): void; + export function statSync(path: string): Stats; + export function lstatSync(path: string): Stats; + export function fstatSync(fd: number): Stats; + export function link(srcpath: string, dstpath: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function linkSync(srcpath: string, dstpath: string): void; + export function symlink(srcpath: string, dstpath: string, type?: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function symlinkSync(srcpath: string, dstpath: string, type?: string): void; + export function readlink(path: string, callback?: (err: NodeJS.ErrnoException, linkString: string) => any): void; + export function readlinkSync(path: string): string; + export function realpath(path: string, callback?: (err: NodeJS.ErrnoException, resolvedPath: string) => any): void; + export function realpath(path: string, cache: {[path: string]: string}, callback: (err: NodeJS.ErrnoException, resolvedPath: string) =>any): void; + export function realpathSync(path: string, cache?: {[path: string]: string}): string; + export function unlink(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function unlinkSync(path: string): void; + export function rmdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function rmdirSync(path: string): void; + export function mkdir(path: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdir(path: string, mode: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdir(path: string, mode: string, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function mkdirSync(path: string, mode?: number): void; + export function mkdirSync(path: string, mode?: string): void; + export function readdir(path: string, callback?: (err: NodeJS.ErrnoException, files: string[]) => void): void; + export function readdirSync(path: string): string[]; + export function close(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function closeSync(fd: number): void; + export function open(path: string, flags: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: number, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function open(path: string, flags: string, mode: string, callback?: (err: NodeJS.ErrnoException, fd: number) => any): void; + export function openSync(path: string, flags: string, mode?: number): number; + export function openSync(path: string, flags: string, mode?: string): number; + export function utimes(path: string, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimes(path: string, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function utimesSync(path: string, atime: number, mtime: number): void; + export function utimesSync(path: string, atime: Date, mtime: Date): void; + export function futimes(fd: number, atime: number, mtime: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimes(fd: number, atime: Date, mtime: Date, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function futimesSync(fd: number, atime: number, mtime: number): void; + export function futimesSync(fd: number, atime: Date, mtime: Date): void; + export function fsync(fd: number, callback?: (err?: NodeJS.ErrnoException) => void): void; + export function fsyncSync(fd: number): void; + export function write(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, written: number, buffer: Buffer) => void): void; + export function writeSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + export function read(fd: number, buffer: Buffer, offset: number, length: number, position: number, callback?: (err: NodeJS.ErrnoException, bytesRead: number, buffer: Buffer) => void): void; + export function readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number; + export function readFile(filename: string, encoding: string, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, options: { encoding: string; flag?: string; }, callback: (err: NodeJS.ErrnoException, data: string) => void): void; + export function readFile(filename: string, options: { flag?: string; }, callback: (err: NodeJS.ErrnoException, data: Buffer) => void): void; + export function readFile(filename: string, callback: (err: NodeJS.ErrnoException, data: Buffer) => void ): void; + export function readFileSync(filename: string, encoding: string): string; + export function readFileSync(filename: string, options: { encoding: string; flag?: string; }): string; + export function readFileSync(filename: string, options?: { flag?: string; }): Buffer; + export function writeFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function writeFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: number; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, options: { encoding?: string; mode?: string; flag?: string; }, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFile(filename: string, data: any, callback?: (err: NodeJS.ErrnoException) => void): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: number; flag?: string; }): void; + export function appendFileSync(filename: string, data: any, options?: { encoding?: string; mode?: string; flag?: string; }): void; + export function watchFile(filename: string, listener: (curr: Stats, prev: Stats) => void): void; + export function watchFile(filename: string, options: { persistent?: boolean; interval?: number; }, listener: (curr: Stats, prev: Stats) => void): void; + export function unwatchFile(filename: string, listener?: (curr: Stats, prev: Stats) => void): void; + export function watch(filename: string, listener?: (event: string, filename: string) => any): FSWatcher; + export function watch(filename: string, options: { persistent?: boolean; }, listener?: (event: string, filename: string) => any): FSWatcher; + export function exists(path: string, callback?: (exists: boolean) => void): void; + export function existsSync(path: string): boolean; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: number; + bufferSize?: number; + }): ReadStream; + export function createReadStream(path: string, options?: { + flags?: string; + encoding?: string; + fd?: string; + mode?: string; + bufferSize?: number; + }): ReadStream; + export function createWriteStream(path: string, options?: { + flags?: string; + encoding?: string; + string?: string; + }): WriteStream; +} + +declare module "path" { + export function normalize(p: string): string; + export function join(...paths: any[]): string; + export function resolve(...pathSegments: any[]): string; + export function relative(from: string, to: string): string; + export function dirname(p: string): string; + export function basename(p: string, ext?: string): string; + export function extname(p: string): string; + export var sep: string; +} + +declare module "string_decoder" { + export interface NodeStringDecoder { + write(buffer: Buffer): string; + detectIncompleteChar(buffer: Buffer): number; + } + export var StringDecoder: { + new (encoding: string): NodeStringDecoder; + }; +} + +declare module "tls" { + import crypto = require("crypto"); + import net = require("net"); + import stream = require("stream"); + + var CLIENT_RENEG_LIMIT: number; + var CLIENT_RENEG_WINDOW: number; + + export interface TlsOptions { + pfx?: any; //string or buffer + key?: any; //string or buffer + passphrase?: string; + cert?: any; + ca?: any; //string or buffer + crl?: any; //string or string array + ciphers?: string; + honorCipherOrder?: any; + requestCert?: boolean; + rejectUnauthorized?: boolean; + NPNProtocols?: any; //array or Buffer; + SNICallback?: (servername: string) => any; + } + + export interface ConnectionOptions { + host?: string; + port?: number; + socket?: net.Socket; + pfx?: any; //string | Buffer + key?: any; //string | Buffer + passphrase?: string; + cert?: any; //string | Buffer + ca?: any; //Array of string | Buffer + rejectUnauthorized?: boolean; + NPNProtocols?: any; //Array of string | Buffer + servername?: string; + } + + export interface Server extends net.Server { + // Extended base methods + listen(port: number, host?: string, backlog?: number, listeningListener?: Function): Server; + listen(path: string, listeningListener?: Function): Server; + listen(handle: any, listeningListener?: Function): Server; + + listen(port: number, host?: string, callback?: Function): Server; + close(): Server; + address(): { port: number; family: string; address: string; }; + addContext(hostName: string, credentials: { + key: string; + cert: string; + ca: string; + }): void; + maxConnections: number; + connections: number; + } + + export interface ClearTextStream extends stream.Duplex { + authorized: boolean; + authorizationError: Error; + getPeerCertificate(): any; + getCipher: { + name: string; + version: string; + }; + address: { + port: number; + family: string; + address: string; + }; + remoteAddress: string; + remotePort: number; + } + + export interface SecurePair { + encrypted: any; + cleartext: any; + } + + export function createServer(options: TlsOptions, secureConnectionListener?: (cleartextStream: ClearTextStream) =>void ): Server; + export function connect(options: TlsOptions, secureConnectionListener?: () =>void ): ClearTextStream; + export function connect(port: number, host?: string, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function connect(port: number, options?: ConnectionOptions, secureConnectListener?: () =>void ): ClearTextStream; + export function createSecurePair(credentials?: crypto.Credentials, isServer?: boolean, requestCert?: boolean, rejectUnauthorized?: boolean): SecurePair; +} + +declare module "crypto" { + export interface CredentialDetails { + pfx: string; + key: string; + passphrase: string; + cert: string; + ca: any; //string | string array + crl: any; //string | string array + ciphers: string; + } + export interface Credentials { context?: any; } + export function createCredentials(details: CredentialDetails): Credentials; + export function createHash(algorithm: string): Hash; + export function createHmac(algorithm: string, key: string): Hmac; + interface Hash { + update(data: any, input_encoding?: string): Hash; + digest(encoding?: string): string; + } + interface Hmac { + update(data: any, input_encoding?: string): Hmac; + digest(encoding?: string): string; + } + export function createCipher(algorithm: string, password: any): Cipher; + export function createCipheriv(algorithm: string, key: any, iv: any): Cipher; + interface Cipher { + update(data: any, input_encoding?: string, output_encoding?: string): string; + final(output_encoding?: string): string; + setAutoPadding(auto_padding: boolean): void; + createDecipher(algorithm: string, password: any): Decipher; + createDecipheriv(algorithm: string, key: any, iv: any): Decipher; + } + interface Decipher { + update(data: any, input_encoding?: string, output_encoding?: string): void; + final(output_encoding?: string): string; + setAutoPadding(auto_padding: boolean): void; + } + export function createSign(algorithm: string): Signer; + interface Signer { + update(data: any): void; + sign(private_key: string, output_format: string): string; + } + export function createVerify(algorith: string): Verify; + interface Verify { + update(data: any): void; + verify(object: string, signature: string, signature_format?: string): boolean; + } + export function createDiffieHellman(prime_length: number): DiffieHellman; + export function createDiffieHellman(prime: number, encoding?: string): DiffieHellman; + interface DiffieHellman { + generateKeys(encoding?: string): string; + computeSecret(other_public_key: string, input_encoding?: string, output_encoding?: string): string; + getPrime(encoding?: string): string; + getGenerator(encoding: string): string; + getPublicKey(encoding?: string): string; + getPrivateKey(encoding?: string): string; + setPublicKey(public_key: string, encoding?: string): void; + setPrivateKey(public_key: string, encoding?: string): void; + } + export function getDiffieHellman(group_name: string): DiffieHellman; + export function pbkdf2(password: string, salt: string, iterations: number, keylen: number, callback: (err: Error, derivedKey: string) => any): void; + export function pbkdf2Sync(password: string, salt: string, iterations: number, keylen: number) : Buffer; + export function randomBytes(size: number): Buffer; + export function randomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; + export function pseudoRandomBytes(size: number): Buffer; + export function pseudoRandomBytes(size: number, callback: (err: Error, buf: Buffer) =>void ): void; +} + +declare module "stream" { + import events = require("events"); + + export interface ReadableOptions { + highWaterMark?: number; + encoding?: string; + objectMode?: boolean; + } + + export class Readable extends events.EventEmitter implements NodeJS.ReadableStream { + readable: boolean; + constructor(opts?: ReadableOptions); + _read(size: number): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + } + + export interface WritableOptions { + highWaterMark?: number; + decodeStrings?: boolean; + } + + export class Writable extends events.EventEmitter implements NodeJS.WritableStream { + writable: boolean; + constructor(opts?: WritableOptions); + _write(data: Buffer, encoding: string, callback: Function): void; + _write(data: string, encoding: string, callback: Function): void; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface DuplexOptions extends ReadableOptions, WritableOptions { + allowHalfOpen?: boolean; + } + + // Note: Duplex extends both Readable and Writable. + export class Duplex extends Readable implements NodeJS.ReadWriteStream { + writable: boolean; + constructor(opts?: DuplexOptions); + _write(data: Buffer, encoding: string, callback: Function): void; + _write(data: string, encoding: string, callback: Function): void; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export interface TransformOptions extends ReadableOptions, WritableOptions {} + + // Note: Transform lacks the _read and _write methods of Readable/Writable. + export class Transform extends events.EventEmitter implements NodeJS.ReadWriteStream { + readable: boolean; + writable: boolean; + constructor(opts?: TransformOptions); + _transform(chunk: Buffer, encoding: string, callback: Function): void; + _transform(chunk: string, encoding: string, callback: Function): void; + _flush(callback: Function): void; + read(size?: number): any; + setEncoding(encoding: string): void; + pause(): void; + resume(): void; + pipe(destination: T, options?: { end?: boolean; }): T; + unpipe(destination?: T): void; + unshift(chunk: string): void; + unshift(chunk: Buffer): void; + wrap(oldStream: NodeJS.ReadableStream): NodeJS.ReadableStream; + push(chunk: any, encoding?: string): boolean; + write(buffer: Buffer, cb?: Function): boolean; + write(str: string, cb?: Function): boolean; + write(str: string, encoding?: string, cb?: Function): boolean; + end(): void; + end(buffer: Buffer, cb?: Function): void; + end(str: string, cb?: Function): void; + end(str: string, encoding?: string, cb?: Function): void; + } + + export class PassThrough extends Transform {} +} + +declare module "util" { + export interface InspectOptions { + showHidden?: boolean; + depth?: number; + colors?: boolean; + customInspect?: boolean; + } + + export function format(format: any, ...param: any[]): string; + export function debug(string: string): void; + export function error(...param: any[]): void; + export function puts(...param: any[]): void; + export function print(...param: any[]): void; + export function log(string: string): void; + export function inspect(object: any, showHidden?: boolean, depth?: number, color?: boolean): string; + export function inspect(object: any, options: InspectOptions): string; + export function isArray(object: any): boolean; + export function isRegExp(object: any): boolean; + export function isDate(object: any): boolean; + export function isError(object: any): boolean; + export function inherits(constructor: any, superConstructor: any): void; +} + +declare module "assert" { + function internal (value: any, message?: string): void; + module internal { + export class AssertionError implements Error { + name: string; + message: string; + actual: any; + expected: any; + operator: string; + generatedMessage: boolean; + + constructor(options?: {message?: string; actual?: any; expected?: any; + operator?: string; stackStartFunction?: Function}); + } + + export function fail(actual?: any, expected?: any, message?: string, operator?: string): void; + export function ok(value: any, message?: string): void; + export function equal(actual: any, expected: any, message?: string): void; + export function notEqual(actual: any, expected: any, message?: string): void; + export function deepEqual(actual: any, expected: any, message?: string): void; + export function notDeepEqual(acutal: any, expected: any, message?: string): void; + export function strictEqual(actual: any, expected: any, message?: string): void; + export function notStrictEqual(actual: any, expected: any, message?: string): void; + export var throws: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export var doesNotThrow: { + (block: Function, message?: string): void; + (block: Function, error: Function, message?: string): void; + (block: Function, error: RegExp, message?: string): void; + (block: Function, error: (err: any) => boolean, message?: string): void; + }; + + export function ifError(value: any): void; + } + + export = internal; +} + +declare module "tty" { + import net = require("net"); + + export function isatty(fd: number): boolean; + export interface ReadStream extends net.Socket { + isRaw: boolean; + setRawMode(mode: boolean): void; + } + export interface WriteStream extends net.Socket { + columns: number; + rows: number; + } +} + +declare module "domain" { + import events = require("events"); + + export class Domain extends events.EventEmitter { + run(fn: Function): void; + add(emitter: events.EventEmitter): void; + remove(emitter: events.EventEmitter): void; + bind(cb: (err: Error, data: any) => any): any; + intercept(cb: (data: any) => any): any; + dispose(): void; + + addListener(event: string, listener: Function): Domain; + on(event: string, listener: Function): Domain; + once(event: string, listener: Function): Domain; + removeListener(event: string, listener: Function): Domain; + removeAllListeners(event?: string): Domain; + } + + export function create(): Domain; +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..abe7d37 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "ev3dev", + "version": "0.3.1", + "description": "An interface to control an EV3 running ev3dev from JavaScript.", + "keywords": ["ev3dev"], + "homepage": "http://wasabifan.github.io/ev3dev-NodeJS/", + "bugs": {"url": "http://github.com/WasabiFan/ev3dev-NodeJS/issues"}, + "author": {"name": "WasabiFan", "email": "WasabiFan@outlook.com"}, + + "dependencies": {"linq": "3.x"}, + "files": ["EV3Base.js", "LED.js", "Motor.js", "Index.js", "README.md", "Sensors/Sensor.js", "Sensors/SimpleSensors.js"], + "main": "Index.js", + "repository" : + { "type" : "git", + "url" : "http://github.com/WasabiFan/ev3dev-NodeJS.git" + } +}