├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── bin └── firejs ├── examples ├── Examples.30Numbers.fjson ├── Examples.ClearingErrors.fjson ├── Examples.ContactsFromEmails.fjson ├── Examples.DotNotationPaths.fjson ├── Examples.Equals.fjson ├── Examples.EqualsStrict.fjson ├── Examples.ErrorCatching.fjson ├── Examples.IfBypass.fjson ├── Examples.IfLastResult.fjson ├── Examples.IfVariable.fjson ├── Examples.NoZeroNumbers.fjson ├── Examples.NotEquals.fjson ├── Examples.OuterVariables.fjson ├── Examples.ReturningErrors.fjson ├── Examples.ScopedVariables.fjson ├── Examples.SimpleNamesVariables.fjson ├── Examples.TheFruitsJoy.fjson ├── Examples.UnlessLastResult.fjson ├── helloModuleProgram │ ├── Examples.Hello.Main.fjson │ ├── ignition.manifest.json │ ├── node_modules │ │ └── examplesHello │ │ │ └── index.js │ └── package.json └── node_modules │ └── fire.js ├── index.js ├── package.json ├── src ├── Ast.js ├── AstNodeType.js ├── Comparable.js ├── CompilationError.js ├── Compiler.js ├── Error.js ├── Expressions.js ├── IgnoreOutput.js ├── InitializerError.js ├── Iterator.js ├── ModuleInitializer.js ├── ModuleInitializerError.js ├── NameGenerator.js ├── Paths.js ├── Runtime.js ├── RuntimeDictionary.js ├── RuntimeError.js ├── StringBuffer.js ├── SynTable.js ├── Utils.js ├── built-in │ ├── break.js │ ├── catch.js │ ├── clearError.js │ ├── concat.js │ ├── continue.js │ ├── decrement.js │ ├── each.js │ ├── equals.js │ ├── get.js │ ├── getModuleConfig.js │ ├── hint.js │ ├── if.js │ ├── increment.js │ ├── index.js │ ├── input.js │ ├── isEmpty.js │ ├── isNotEmpty.js │ ├── loop.js │ ├── notEquals.js │ ├── parentResult.js │ ├── push.js │ ├── raiseError.js │ ├── return.js │ ├── returnError.js │ ├── scopeSet.js │ ├── set.js │ ├── test.js │ ├── trigger.js │ ├── try.js │ ├── undefined.js │ ├── unless.js │ ├── xif.js │ └── xunless.js ├── cli.js ├── constants.js ├── core.js └── mergeWith.js └── test ├── commandLineDirs ├── appNameFromExpression │ ├── AppNameFromMainExpression.Main.fjson │ ├── AppNameFromOtherName.fjson │ └── ReturnAppName.fjs ├── appNameFromPackage │ ├── AppNameFromPackage.Main.fjs │ └── package.json ├── deferredSubModuleLoading │ ├── DeferredTest.Main.fjson │ ├── ignition.manifest.json │ ├── node_modules │ │ ├── fire.js │ │ └── sub │ │ │ ├── ignition.manifest.json │ │ │ ├── index.js │ │ │ └── node_modules │ │ │ ├── SubSub.fjson │ │ │ └── subsub.js │ └── package.json ├── expressionsList │ └── MyApp.Main.fjson ├── failingInitializer │ ├── failingInitializer.Main.fjson │ └── initializers │ │ └── development │ │ └── failingInitializer.Init.fjson ├── invalidMainPackageJson │ └── package.json ├── moduleInitExpInit │ ├── ReturnInitializedValues.fjs │ ├── ignition.manifest.json │ ├── initializers │ │ └── development │ │ │ └── appInitExpInit.App.init.fjs │ ├── moduleInitExpInit.Main.fjson │ ├── node_modules │ │ ├── fire.js │ │ └── mod1 │ │ │ ├── index.js │ │ │ └── initializers │ │ │ └── development │ │ │ └── moduleInitExpInit.App.init.fjs │ └── package.json ├── moduleInitializers │ ├── ignition.manifest.json │ ├── moduleInitializers.Main.fjson │ └── node_modules │ │ ├── fire.js │ │ └── someInitModule │ │ ├── index.js │ │ └── initializers │ │ └── development │ │ └── someInitModule.Init.fjson ├── moduleScriptDirs │ ├── ignition.manifest.json │ ├── moduleScriptDirs.Main.fjson │ └── node_modules │ │ ├── fire.js │ │ └── superModule1 │ │ ├── auxManifestDir │ │ ├── superExpression3.fjson │ │ └── superExpression4.fjs │ │ ├── auxModDir │ │ ├── superExpression2.fjson │ │ └── superExpression5.fjs │ │ ├── ignition.manifest.json │ │ ├── index.js │ │ ├── superExpression1.fjson │ │ └── superExpression1b.fjs ├── node_modules │ └── fire.js ├── packageJson │ ├── PackageExample.Main.fjson │ └── package.json ├── parsedArgv │ ├── Parsed.Argv.fjs │ └── Parsed.Main.fjson ├── printManifest │ ├── ignition.manifest.json │ └── package.json ├── simple │ └── mySimpleMain.fjson ├── withManifest2 │ ├── ignition.manifest.json │ ├── myMain.fjson │ └── node_modules │ │ ├── fire.js │ │ └── testFourModule │ │ ├── index.js │ │ └── package.json ├── withRootLevelFiles │ ├── myMain.fjson │ └── myOtherExpression.fjson └── withSubScripts │ ├── customExpression.fjs │ ├── ignition.manifest.json │ ├── myMain.fjson │ ├── myOtherExpression.fjson │ └── otherExpressions │ ├── customSubExpression.fjs │ └── subExpression.fjson ├── dependentModules ├── dependentModules.Main.fjson ├── ignition.manifest.json └── node_modules │ ├── fire.js │ ├── loadedModule1 │ ├── ignition.manifest.json │ └── index.js │ └── loadedModule2 │ └── index.js ├── expressions ├── testDoLoopControl.js ├── testExecAtFirstTime.js ├── testExecAtThirdTime.js ├── testExpThatRaisesError.js ├── testIncrementedName.js ├── testReturnParentResult.js └── tickedReturn.js ├── initializersTest ├── ignition.manifest.json ├── initializers │ ├── development │ │ └── initializersTest.Dev.Init.fjson │ └── test │ │ └── initializersTest.Test.Init.fjson ├── initializersTest.Main.fjson └── node_modules │ ├── fire.js │ └── initializersTestLog.js ├── loadedModules ├── ignition.manifest.json ├── node_modules │ ├── loadedModule1 │ │ └── index.js │ └── loadedModule2 │ │ └── index.js └── runtimeLoader.testjs ├── manifestTokens ├── testUnknownToken.json ├── testUnknownWithNoDefault.json ├── withDepth.json ├── withFireAppName.json ├── withFireAppPid.json ├── withFireBase.json ├── withFireEnvName.json └── withProcessEnv.json ├── manifests ├── testConfig │ ├── ignition.manifest.json │ ├── node_modules │ │ └── module1 │ │ │ ├── main.js │ │ │ └── package.json │ └── runtimeLoader.testjs ├── testConfigMissing │ ├── ignition.manifest.json │ ├── node_modules │ │ └── module1 │ │ │ ├── main.js │ │ │ └── package.json │ ├── runtimeLoader.testjs │ └── testConfigMissing.Main.fjson └── testModules │ ├── ignition.manifest.json │ ├── node_modules │ ├── expressionModule1 │ │ ├── main.js │ │ └── package.json │ └── expressionModule2 │ │ ├── main.js │ │ └── package.json │ └── runtimeLoader.testjs ├── node_modules └── fire.js ├── onLoadTest └── ignition.manifest.json ├── runtimeExtensions.js ├── sourceUri ├── Bye.fjson ├── Hello.js └── Hi.fjs ├── test.Ast.js ├── test.CommandLine.js ├── test.Comparable.js ├── test.Iterator.js ├── test.MergeWith.js ├── test.Paths.js ├── test.SourceUri.js ├── test.UnsupportedHints.js └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 0.4 4 | - 0.5 5 | - 0.6 6 | script: "make travis" 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Firebase.co - http://www.firebase.co 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | all: run-tests 2 | 3 | run-tests: 4 | node_modules/.bin/vows test/*.js 5 | 6 | run-tests-spec: 7 | node_modules/.bin/vows test/*.js --spec 8 | 9 | install-npm: 10 | npm install . -g 11 | 12 | travis: run-tests-spec 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fire.js 2 | [![Build Status](https://secure.travis-ci.org/firejs/fire.png)](http://travis-ci.org/firejs/fire) 3 | 4 | Fire.js is an experimental framework that aims to reduce the amount of javascript code and callbacks when developing in Node.js by the orchestration of tiny building blocks called Expressions defined in JSON documents. 5 | 6 | ### Example 7 | 8 | Example JSON app using a [MongoDB](http://www.mongodb.org/) database and the [MongoDB expressions](https://github.com/firebaseco/mongodb-expressions): 9 | 10 | `MongoApp.fjson` 11 | 12 | { 13 | "name": "MongoApp.Main", 14 | "json": { 15 | "enabledEmails": { 16 | "@Mongo.Find(users)": { 17 | "conditions": { 18 | "enabled": true 19 | } 20 | }, 21 | "@each": { 22 | "@get(CurrentItem.email)": null 23 | } 24 | }, 25 | "disabledEmails": { 26 | "@Mongo.Find(users)": { 27 | "conditions": { 28 | "enabled": false 29 | } 30 | }, 31 | "@each": { 32 | "@get(CurrentItem.email)": null 33 | } 34 | } 35 | } 36 | } 37 | 38 | The result will be: 39 | 40 | { 41 | "enabledEmails": ["email1@example.com", "email2@example.com", "email3@example.com"], 42 | "disabledEmails": ["email4@example.com", "email5@example.com", "email6@example.com"] 43 | } 44 | 45 | ## Installation 46 | 47 | The easiest way to install fire.js is using the awesome Node Package Manager. 48 | 49 | npm install -g fire 50 | 51 | The `firejs` command line utility should be ready to run your scripts. 52 | 53 | ## Learn more 54 | 55 | + [Tutorials](https://github.com/firejs/fire/wiki/Tutorials) 56 | 57 | + [Wiki](https://github.com/firejs/fire/wiki) 58 | 59 | + [Official Blog](http://firejs.firebase.co) 60 | 61 | + [Fire.js IDE](https://github.com/firejs/fire-ide) 62 | 63 | ## Supported Node Versions 64 | 65 | * 0.4.5 and above 66 | * 0.5 67 | * 0.6 68 | 69 | ## Cloning the Repository 70 | 71 | git clone https://github.com/firejs/fire.git 72 | 73 | 74 | ## Tests 75 | 76 | npm test 77 | 78 | ## Contributors 79 | 80 | * Johan (author). Email: *johan@firebase.co* 81 | 82 | ## MIT License 83 | 84 | Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 85 | 86 | Permission is hereby granted, free of charge, to any person obtaining a copy 87 | of this software and associated documentation files (the "Software"), to deal 88 | in the Software without restriction, including without limitation the rights 89 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 90 | copies of the Software, and to permit persons to whom the Software is 91 | furnished to do so, subject to the following conditions: 92 | 93 | The above copyright notice and this permission notice shall be included in 94 | all copies or substantial portions of the Software. 95 | 96 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 97 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 98 | FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 99 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 100 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 101 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 102 | THE SOFTWARE. -------------------------------------------------------------------------------- /bin/firejs: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | var path = require('path') 23 | var fire = require('../index.js') 24 | fire.executeApplication(process.argv.slice(2)) 25 | -------------------------------------------------------------------------------- /examples/Examples.30Numbers.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.30Numbers", 3 | "json": { 4 | "@loop": { 5 | "@equals": [ 6 | { 7 | "@get(CurrentIndex)": null 8 | }, 9 | 30 10 | ], 11 | "@if": { 12 | "@break":null 13 | }, 14 | "@get(CurrentIndex)": null 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /examples/Examples.ClearingErrors.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.ClearingErrors", 3 | "json": { 4 | "@return": "Boring... no errors happening around here", 5 | "@try": { 6 | "@raiseError": "This is an error, we are so screwed!" 7 | }, 8 | "@clearError": null, 9 | "@catch": "Whoa... This is an error!" 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /examples/Examples.ContactsFromEmails.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.ContactsFromEmails", 3 | "json": { 4 | "@return": ["chuck@example.com", "superman@example.com", "steveJobs@example.com"], 5 | "@each(superheroes)": { 6 | "email": { 7 | "@get(superheroesCurrentItem)": null 8 | } 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /examples/Examples.DotNotationPaths.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.DotNotationPaths", 3 | "json": { 4 | "@set(superhero)": { 5 | "name": "Chuck Norris", 6 | "age": 460 7 | }, 8 | "@get(superhero.name)": null 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /examples/Examples.Equals.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.Equals", 3 | "json": { 4 | "@equals": [10,"10"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/Examples.EqualsStrict.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.EqualsStrict", 3 | "json": { 4 | "@equals(strict)": [10,"10"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/Examples.ErrorCatching.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.ErrorCatching", 3 | "json": { 4 | "@try": { 5 | "@raiseError": "This is an error, we are so screwed!" 6 | }, 7 | "@catch": { 8 | "whatHappended": { 9 | "@get(CurrentError.error)": null 10 | }, 11 | "howAreWeDoing": "We had some trouble but we are ok now!" 12 | } 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /examples/Examples.IfBypass.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.IfBypass", 3 | "json": { 4 | "@return": "This is the First and Last Result of the Program", 5 | "@if(thisVariableDoesntEvenExists)": "This input is never used" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/Examples.IfLastResult.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.IfLastResult", 3 | "json": { 4 | "@return": true, 5 | "@if": "Totally true" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/Examples.IfVariable.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.IfVariable", 3 | "json": { 4 | "@set(chuckIsHere)": true, 5 | "@if(chuckIsHere)": "Chuck is here, we are in trouble!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/Examples.NoZeroNumbers.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.NoZeroNumbers", 3 | "json": { 4 | "@loop(mainLoop)": { 5 | "@equals": [ 6 | { 7 | "@get(mainLoopCurrentIndex)": null 8 | }, 9 | 30 10 | ], 11 | "@if": { 12 | "@break":null 13 | }, 14 | " @equals": [ 15 | { 16 | "@get(mainLoopCurrentIndex)": null 17 | }, 18 | 0 19 | ], 20 | " @if": { 21 | "@continue": null 22 | }, 23 | "@get(mainLoopCurrentIndex)": null 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /examples/Examples.NotEquals.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.NotEquals", 3 | "json": { 4 | "@notEquals": [10,13] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /examples/Examples.OuterVariables.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.OuterVariables", 3 | "json": { 4 | "@set(person)": null, 5 | "@return": { 6 | "@set(person)": { 7 | "firstName": "Chuch", 8 | "lastName": "Norris" 9 | }, 10 | "@get(person)": null 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /examples/Examples.ReturningErrors.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.ReturningErrors", 3 | "json": { 4 | "@try": { 5 | "@raiseError": "This is an error, we are so screwed!" 6 | }, 7 | "@returnError": null 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /examples/Examples.ScopedVariables.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.ScopedVariables", 3 | "json": { 4 | "@set(fName)": "Chuck", 5 | "@set(lName)": "Norris", 6 | "@return": { 7 | "firstName": { 8 | "@get(fName)": null 9 | }, 10 | "lastName": { 11 | "@get(lName)": null 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /examples/Examples.SimpleNamesVariables.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.SimpleNamesVariables", 3 | "json": { 4 | "@set(name)": "Chuck Norris", 5 | "@get(name)": null 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/Examples.TheFruitsJoy.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.TheFruitsJoy", 3 | "json": { 4 | "@set(fruits)": ["Orange", "Orange"], 5 | "@equals": { 6 | "@get(fruits)": null 7 | }, 8 | "@if": "Yay, We have different fruits!", 9 | "@unless": "Boring, Same fruits..." 10 | } 11 | } 12 | 13 | -------------------------------------------------------------------------------- /examples/Examples.UnlessLastResult.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.UnlessLastResult", 3 | "json": { 4 | "@set(chuckIsHere)": false, 5 | "@unless(chuckIsHere)": "Chuck Norris is not here, we are Safe!" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/helloModuleProgram/Examples.Hello.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.Hello.Main", 3 | "json": { 4 | "@Examples.HelloWorld": { 5 | "hello": "world" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /examples/helloModuleProgram/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["examplesHello"] 3 | } 4 | -------------------------------------------------------------------------------- /examples/helloModuleProgram/node_modules/examplesHello/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | function ExamplesHelloWorld() { 3 | 4 | } 5 | ExamplesHelloWorld.prototype = new fire.Expression() 6 | ExamplesHelloWorld.prototype.execute = function() { 7 | var self = this 8 | this.runInput(function(res) { 9 | self.end(res) 10 | }); 11 | } 12 | fire.igniteModule(module, require).exportExpression({ 13 | name: "Examples.HelloWorld", 14 | implementation: ExamplesHelloWorld 15 | }) 16 | -------------------------------------------------------------------------------- /examples/helloModuleProgram/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Examples.Hello", 3 | "version": "1.0.0", 4 | "dependencies": { 5 | "fire": ">= 0.1.0" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /examples/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../index.js') -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./src/core.js') -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fire", 3 | "description": "An experimental Framework that uses JSON structures to simplify the definition of complex behaviors from asynchronous sources in Node.js", 4 | "version": "0.1.1", 5 | "homepage": "http://firejs.firebase.co", 6 | "author": "Firebase.co (http://www.firebase.co)", 7 | "main": "./index.js", 8 | "preferGlobal" : true, 9 | "bin": { 10 | "firejs": "./bin/firejs" 11 | }, 12 | "repository": 13 | { 14 | "type": "git", 15 | "url": "https://github.com/firejs/fire" 16 | }, 17 | "bugs": { 18 | "email": "firejs@firebase.co", 19 | "url": "https://github.com/firejs/fire/issues" 20 | }, 21 | "keywords": ["JSON", "framework", "runtime"], 22 | "contributors" : [{ "name": "Johan Hernandez", "email": "johan@firebase.co" }], 23 | "dependencies": { 24 | "nopt": ">= 1.0.10" 25 | }, 26 | "devDependencies": { 27 | "vows": ">= 0.5.11" 28 | }, 29 | "engines": { 30 | "node": ">= 0.4.5" 31 | }, 32 | "scripts": { 33 | "test": "make" 34 | }, 35 | "licenses" : [ 36 | { 37 | "type" : "MIT", 38 | "url" : "https://github.com/firejs/fire/blob/master/LICENSE" 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /src/Ast.js: -------------------------------------------------------------------------------- 1 | var AstNodeType = require('./AstNodeType.js') 2 | var SPECIAL_KEY_SYMBOL = "@" 3 | var DELEGATE_KEY_SYMBOL = "#" 4 | var HINT_START_SYMBOL = "(" 5 | var HINT_END_SYMBOL = ")" 6 | 7 | function Tree(doc) { 8 | 9 | } 10 | 11 | Tree.prototype.parse = function(doc) { 12 | this.doc = doc 13 | this._rootNode = new Node().parse(doc) 14 | } 15 | 16 | Tree.prototype.getRootNode = function() { 17 | return this._rootNode 18 | } 19 | 20 | function Node() { 21 | this.children = [] 22 | this.parent = null 23 | } 24 | Node.prototype.type = null 25 | function trimString(str) { 26 | if(str == null || str == undefined) return str 27 | return str.replace(/^\s\s*/,'').replace(/\s\s*$/,'') 28 | } 29 | function isSpecialKey(propName) { 30 | var n = trimString(propName) 31 | return n.indexOf(SPECIAL_KEY_SYMBOL) == 0; 32 | } 33 | function isExpressionKey(propName) { 34 | var n = trimString(propName) 35 | return n.indexOf(SPECIAL_KEY_SYMBOL) == 0; 36 | } 37 | 38 | function isDelegateKey(propName) { 39 | var n = trimString(propName) 40 | return n.indexOf(DELEGATE_KEY_SYMBOL) == 0; 41 | } 42 | 43 | function isBlock(jsonObj) { 44 | var keys = Object.keys(jsonObj) 45 | if(keys.length == 0) return false 46 | for(var i = 0; i < keys.length; i++) { 47 | var propName = keys[i] 48 | if(!isSpecialKey(propName)) { 49 | return false 50 | } 51 | } 52 | return true 53 | } 54 | 55 | function isCompositeHash(jsonObj) { 56 | var keys = Object.keys(jsonObj) 57 | if(keys.length == 0) return false 58 | for(var i = 0; i < keys.length; i++) { 59 | var propName = keys[i] 60 | if(isDelegateKey(propName)) { 61 | return true 62 | } 63 | } 64 | return false 65 | } 66 | function keyHasHint(propName) { 67 | return propName.indexOf(HINT_START_SYMBOL) > -1 68 | } 69 | function getExpressionNameFromSpecialKey(propName) { 70 | if(!isSpecialKey(propName)){ 71 | throw "Asked to extract special from a key that is not a special key, the key was '" + propName + "'" 72 | } 73 | propName = trimString(propName) 74 | if(keyHasHint(propName)) { 75 | propName = propName.substring(0,propName.indexOf(HINT_START_SYMBOL)) 76 | } 77 | return propName.substring(1,propName.length) 78 | } 79 | Node.prototype.parse = function(value) { 80 | this.value = value 81 | if(this.type == null) 82 | { 83 | var valueType = typeof(value); 84 | if(value === null) { 85 | this.type = AstNodeType.null 86 | } 87 | else if(valueType === "number") { 88 | this.type = AstNodeType.number 89 | } 90 | else if(valueType === "string" && isExpressionKey(value)) { 91 | this.type = AstNodeType.expression 92 | } 93 | else if(valueType === "string" && isDelegateKey(value)) { 94 | this.type = AstNodeType.delegate; 95 | } 96 | else if(valueType === "string") { 97 | this.type = AstNodeType.string 98 | } 99 | else if(valueType === "object" && (value instanceof Array)) { 100 | this.type = AstNodeType.array 101 | } 102 | else if(valueType === "object" && isBlock(value)) { 103 | this.type = AstNodeType.block 104 | } 105 | else if(valueType === "object" && isCompositeHash(value)) { 106 | this.type = AstNodeType.composite_hash; 107 | } 108 | else if(valueType === "object") { 109 | this.type = AstNodeType.hash 110 | } 111 | else if(valueType === "boolean") { 112 | this.type = AstNodeType.boolean 113 | } 114 | else { 115 | throw "Failed to recognize JSON type for '" + value + "', typeof '" + valueType + "'" 116 | } 117 | } 118 | if(this.shouldParseChildren()) { 119 | this.parseChildren() 120 | } 121 | return this 122 | } 123 | 124 | Node.prototype.shouldParseChildren = function() { 125 | return AstNodeType.PARENT_TYPES.indexOf(this.type) != -1; 126 | } 127 | 128 | Node.prototype.parseChildren = function() { 129 | if(this.type == AstNodeType.block) { 130 | var keys = Object.keys(this.value) 131 | for(var i = 0; i < keys.length; i++) { 132 | var key = keys[i] 133 | var node = new Node() 134 | node.type = AstNodeType.expression 135 | node.parse(key) 136 | this.addChild(node) 137 | 138 | var subNode = new Node() 139 | subNode.parse(this.value[key]) 140 | node.addChild(subNode) 141 | } 142 | } 143 | else if(this.type == AstNodeType.hash) { 144 | var keys = Object.keys(this.value) 145 | for(var i = 0; i < keys.length; i++) { 146 | var key = keys[i] 147 | var node = new Node() 148 | node.type = AstNodeType.property 149 | node.parse(key) 150 | this.addChild(node) 151 | 152 | var subNode = new Node() 153 | subNode.parse(this.value[key]) 154 | node.addChild(subNode) 155 | } 156 | } 157 | else if(this.type == AstNodeType.composite_hash) { 158 | var keys = Object.keys(this.value) 159 | for(var i = 0; i < keys.length; i++) { 160 | var key = keys[i]; 161 | var node = new Node(); 162 | node.type = isDelegateKey(key) ? AstNodeType.delegate : AstNodeType.property; 163 | node.parse(key); 164 | this.addChild(node); 165 | 166 | var subNode = new Node(); 167 | subNode.parse(this.value[key]); 168 | node.addChild(subNode); 169 | } 170 | } 171 | else if(this.type == AstNodeType.array) { 172 | for(var i = 0; i < this.value.length; i++) { 173 | var node = new Node() 174 | node.type = AstNodeType.index 175 | node.parse(i) 176 | this.addChild(node) 177 | 178 | var subNode = new Node() 179 | subNode.parse(this.value[i]) 180 | node.addChild(subNode) 181 | } 182 | } 183 | } 184 | 185 | Node.prototype.getPathPart = function() { 186 | if(this.type == AstNodeType.block) { 187 | return "{@}" 188 | } else if(this.type == AstNodeType.hash) { 189 | return "{}" 190 | } else if(this.type == AstNodeType.array) { 191 | return "[]" 192 | } 193 | else if(this.type == AstNodeType.expression) { 194 | return this.value 195 | } 196 | else if(this.type == AstNodeType.property) { 197 | return this.value 198 | } 199 | return JSON.stringify(this.value) 200 | } 201 | Node.prototype.getPath = function() { 202 | var path = '' 203 | var currentNode = this 204 | while(currentNode) { 205 | if(path.length > 0){ 206 | path = "/" + path 207 | } 208 | path = currentNode.getPathPart() + path 209 | currentNode = currentNode.parent 210 | 211 | } 212 | return path 213 | } 214 | Node.prototype.addChild = function(node) { 215 | node.parent = this 216 | this.children.push(node) 217 | } 218 | 219 | Node.prototype.hasChildren = function() { 220 | return this.children.length > 0 221 | } 222 | Node.prototype.isPureValue = function() { 223 | if(AstNodeType.SPECIAL_TYPES.indexOf(this.type) != -1) { 224 | return false 225 | } 226 | return this.areChildrenPureValues(); 227 | } 228 | Node.prototype.areChildrenPureValues = function() { 229 | if(this.hasChildren()) { 230 | for(var i = 0; i < this.children.length; i++) { 231 | var child = this.children[i] 232 | if(!child.isPureValue()) { 233 | return false; 234 | } 235 | } 236 | } 237 | return true; 238 | } 239 | function keyHasHint(propName) { 240 | return propName.indexOf(HINT_START_SYMBOL) > -1 241 | } 242 | 243 | function getHint(propName) { 244 | if(!keyHasHint(propName)) return undefined; 245 | var hintEndIndex = propName.indexOf(HINT_END_SYMBOL) 246 | if(hintEndIndex > 1) { 247 | return propName.substring(propName.indexOf(HINT_START_SYMBOL) + 1,hintEndIndex) 248 | } 249 | return propName.substring(propName.indexOf(HINT_START_SYMBOL) + 1,propName.length) 250 | } 251 | module.exports.SPECIAL_KEY_SYMBOL = SPECIAL_KEY_SYMBOL 252 | module.exports.Tree = Tree 253 | module.exports.isSpecialKey = isSpecialKey 254 | module.exports.keyHasHint = keyHasHint 255 | module.exports.getExpressionNameFromSpecialKey = getExpressionNameFromSpecialKey 256 | module.exports.getHintFromSpecialKey = getHint 257 | -------------------------------------------------------------------------------- /src/AstNodeType.js: -------------------------------------------------------------------------------- 1 | exports.null = "null" 2 | exports.number = "number" 3 | exports.string = "string" 4 | exports.hash = "hash" 5 | exports.array = "array" 6 | exports.block = "block" 7 | exports.expression = "expression" 8 | exports.property = "property" 9 | exports.index = "index" 10 | exports.boolean = "boolean" 11 | exports.delegate = "delegate" 12 | exports.composite_hash = "composite_hash" 13 | exports.SPECIAL_TYPES = [exports.delegate, exports.composite_hash, exports.expression, exports.block]; 14 | exports.PARENT_TYPES = [exports.composite_hash, exports.block, exports.array, exports.hash]; 15 | -------------------------------------------------------------------------------- /src/Comparable.js: -------------------------------------------------------------------------------- 1 | /* 2 | Comparables are the comparable values of an object, used by comparison expressions like @equals. 3 | Check test.Comparable.js to know more about the behavior. 4 | */ 5 | 6 | module.exports.extractComparableValues = function(val) { 7 | if(val === undefined || val == null) return []; 8 | else if(typeof(val) === 'object') { 9 | if(val instanceof Array) return val 10 | var values = []; 11 | Object.keys(val).forEach(function(key){ 12 | values.push(val[key]) 13 | }) 14 | return values 15 | } else if(typeof(val) === 'string') { 16 | var values = []; 17 | for(var charIndex in val) { 18 | values.push(val.charAt(charIndex)) 19 | } 20 | return values 21 | } 22 | return [] 23 | } 24 | 25 | function areEqual(values, isStrict) { 26 | var res = undefined 27 | var abortComparison = false 28 | for(var i in values) { 29 | var currentVal = values[i] 30 | for(var ic = i - 1; ic >=0 ;ic--){ 31 | var iteratedVal = values[ic] 32 | if(isStrict ? currentVal !== iteratedVal : currentVal != iteratedVal){ 33 | abortComparison= true 34 | break; 35 | } 36 | } 37 | if(abortComparison) { 38 | res = false 39 | break 40 | } 41 | } 42 | if(res === undefined) res = true 43 | return res 44 | } 45 | module.exports.areEqual = areEqual 46 | 47 | 48 | function areNotEqual(values, isStrict) { 49 | var res = undefined 50 | var abortComparison = false 51 | for(var i in values) { 52 | var currentVal = values[i] 53 | for(var ic = i - 1; ic >=0 ;ic--){ 54 | var iteratedVal = values[ic] 55 | if(isStrict ? currentVal === iteratedVal : currentVal == iteratedVal){ 56 | abortComparison= true 57 | break; 58 | } 59 | } 60 | if(abortComparison) { 61 | res = false 62 | break 63 | } 64 | } 65 | if(res === undefined) res = true 66 | return res 67 | } 68 | module.exports.areNotEqual = areNotEqual -------------------------------------------------------------------------------- /src/CompilationError.js: -------------------------------------------------------------------------------- 1 | function CompilationError(sourceUri, path, message, code) { 2 | this.sourceUri = sourceUri || null 3 | this.path = path || null 4 | this.message = message || null 5 | this.code = code || null 6 | } 7 | CompilationError.prototype.toString = function() { 8 | return "#CompilationError" 9 | } 10 | 11 | module.exports = CompilationError -------------------------------------------------------------------------------- /src/Error.js: -------------------------------------------------------------------------------- 1 | var Error = function(code, message) { 2 | this.code = code; 3 | this.message = message; 4 | }; 5 | Error.prototype.toString = function() { 6 | return "fire.js error " + this.code + ": " + this.message 7 | } 8 | module.exports = Error; -------------------------------------------------------------------------------- /src/Expressions.js: -------------------------------------------------------------------------------- 1 | var RuntimeError = require('./RuntimeError') 2 | 3 | function Expression() { 4 | 5 | } 6 | Expression.prototype.reset = function() { 7 | this.createInputExpression = null 8 | this.parent = null 9 | this.resultCallback = null 10 | this.inputExpression = null 11 | this.errorCallback = null 12 | this.loopCallback = null 13 | 14 | // If we own the variables, then unlink the _parent 15 | if(!this.scopeBypass) { 16 | delete this.vars._parent 17 | } 18 | } 19 | Expression.prototype.execute = function() { 20 | console.trace() 21 | throw "Expression requires derived classes or instances to override the 'execute' function with a expression-compliant function" 22 | } 23 | Expression.prototype.getParentResult = function() { 24 | return this.parent !== undefined ? this.parent.getCurrentResult() : undefined 25 | } 26 | Expression.prototype.finish = function() { 27 | this.end(this.getCurrentResult()) 28 | } 29 | Expression.prototype.end = function(res) { 30 | var self = this 31 | if(!this.resultCallback) { 32 | throw "resultCallback not implemented" 33 | }else { 34 | var callback = this.resultCallback 35 | var parent = this.parent 36 | self.reset() 37 | callback(res, parent) 38 | } 39 | } 40 | Expression.prototype.setCurrentResult = function(res) { 41 | this.vars._result = res 42 | } 43 | Expression.prototype.getCurrentResult = function() { 44 | return this.vars._result 45 | } 46 | Expression.prototype.bypass = function(res) { 47 | this.end(this.getParentResult()) 48 | } 49 | Expression.prototype.getPath = function() { 50 | return null 51 | } 52 | Expression.prototype.hint = null 53 | Expression.prototype.input = undefined 54 | Expression.prototype.createInputExpression = null 55 | Expression.prototype.parent = null 56 | Expression.prototype.resultCallback = null 57 | Expression.prototype.errorCallback = null 58 | Expression.prototype.loopCallback = null 59 | Expression.prototype.inputExpression = null 60 | Expression.prototype.runtime = null 61 | Expression.prototype.isInput = false 62 | Expression.prototype.initialized = false 63 | Expression.prototype.isRoot = false 64 | Expression.prototype.scopeBypass = false 65 | 66 | Expression.prototype.onPrepareInput = null 67 | 68 | Expression.prototype.runInput = function(onResult) { 69 | this.runInputFromTarget(this, onResult) 70 | } 71 | 72 | Expression.prototype.runInputFromTarget = function(target, onResult) { 73 | var self = this 74 | if(typeof(onResult) !== 'function') { 75 | console.trace() 76 | throw "runInputFromTarget requires a function as callback" 77 | } 78 | if(target.createInputExpression) { 79 | target.inputExpression = target.createInputExpression() 80 | target.inputExpression.resultCallback = function(res, parent) { 81 | onResult(res, parent) 82 | } 83 | if(target.onPrepareInput) { 84 | target.onPrepareInput() 85 | } 86 | target.inputExpression.run(this) 87 | } else { 88 | onResult(target.input, this) 89 | } 90 | } 91 | 92 | Expression.prototype.ensureInitialized = function() { 93 | if(!this.initialized) { 94 | if(!this.scopeBypass){ 95 | this.vars = { 96 | _parent: null, 97 | _result: undefined, 98 | _error: null 99 | } 100 | } 101 | this.initialized = true 102 | } 103 | } 104 | Expression.prototype.run = function(callingParent) { 105 | this.ensureInitialized() 106 | this.parent = callingParent || null 107 | if(this.parent) { 108 | if(this.scopeBypass) { 109 | this.vars = this.parent.vars 110 | } else { 111 | this.vars._parent = this.parent.vars 112 | } 113 | this.runtime = this.parent.runtime 114 | } 115 | this.execute() 116 | } 117 | 118 | Expression.prototype.raiseError = function(err) { 119 | //console.warn("raiseError:", err) 120 | var errorInfo = new RuntimeError(this._blockContext, err) 121 | this.propagateError(errorInfo) 122 | } 123 | 124 | Expression.prototype.propagateError = function(errorInfo) { 125 | if(this.errorCallback) { 126 | this.errorCallback(errorInfo, this.parent, this); 127 | } else if(this.parent) { 128 | this.parent.propagateError(errorInfo); 129 | } else { 130 | throw "errorCallback not implemented" 131 | } 132 | } 133 | Expression.prototype.getError = function() { 134 | return this.vars._error 135 | } 136 | Expression.prototype.setError = function(errorInfo) { 137 | this.vars._error = errorInfo 138 | } 139 | 140 | Expression.prototype.clearError = function() { 141 | this.setError(null) 142 | } 143 | 144 | Expression.prototype.setParentError = function(errorInfo) { 145 | this.parent.setError(errorInfo) 146 | } 147 | 148 | Expression.prototype.getParentError = function() { 149 | return this.parent.getError() 150 | } 151 | 152 | Expression.prototype.clearParentError = function() { 153 | this.parent.clearError() 154 | } 155 | 156 | Expression.prototype.loopControl = function(payload) { 157 | this.propagateLoopControl(payload); 158 | } 159 | 160 | Expression.prototype.propagateLoopControl = function(payload) { 161 | if(this.loopCallback) { 162 | this.loopCallback(payload, this.parent, this); 163 | } else if(this.parent) { 164 | this.parent.propagateLoopControl(payload); 165 | } else { 166 | throw "loopCallback not implemented" 167 | } 168 | } 169 | 170 | Expression.prototype.bypass = function() { 171 | this.end(this.getParentResult()) 172 | } 173 | 174 | Expression.prototype.setVar = function(name, value) { 175 | setVarCore(this.runtime, this.vars, name, value) 176 | } 177 | 178 | Expression.prototype.setScopeVar = function(name, value) { 179 | setVarCore(this.runtime, this.vars, name, value, true) 180 | } 181 | 182 | Expression.prototype.setParentScopeVar = function(name, value) { 183 | this.parent.setScopeVar(name, value) 184 | } 185 | 186 | Expression.prototype.getVar = function(name) { 187 | return this.runtime.getPaths().run(this.vars, name) 188 | } 189 | 190 | Expression.prototype.setParentVar = function(path, value) { 191 | if(this.parent) { 192 | setVarCore(this.runtime, this.parent.vars, path, value) 193 | } else { 194 | 195 | console.trace() 196 | throw "setParentVar can't be used in root expressions" 197 | } 198 | } 199 | 200 | Expression.prototype.getParentVar = function(name) { 201 | return this.runtime.getPaths().run(this.parent.vars, name) 202 | } 203 | 204 | Expression.prototype.getParentResult = function() { 205 | return this.parent ? this.parent.getCurrentResult() : undefined 206 | } 207 | 208 | Expression.prototype.setParentResult = function(val) { 209 | if(this.parent) { 210 | this.parent.setCurrentResult(val) 211 | } else { 212 | throw "setParentResult can't be used in root expressions" 213 | } 214 | } 215 | 216 | Expression.prototype.hasHint = function() { 217 | return this.hint 218 | } 219 | 220 | Expression.prototype.getHintValue = function() { 221 | return this.hasHint() ? this.hint : undefined 222 | } 223 | 224 | Expression.prototype.getHintVariableValue = function() { 225 | return this.hasHint() ? this.getParentVar(this.hint) : undefined 226 | } 227 | 228 | Expression.prototype.getExpressionName = function() { 229 | return !this.expressionName ? "" : this.expressionName 230 | } 231 | 232 | Expression.prototype.getRootParent = function() { 233 | var _rootExpressionContext = null 234 | var currentParent = this 235 | while(currentParent) { 236 | if(currentParent.isRoot) { 237 | return currentParent 238 | } 239 | currentParent = currentParent.parent 240 | } 241 | return null 242 | } 243 | 244 | Expression.prototype.requireHint = function() { 245 | if(!this.hasHint()) { 246 | this.raiseError("Expression '" + this.getExpressionName() + "' requires a hint") 247 | return false 248 | } 249 | return true 250 | } 251 | 252 | function setVarCore(runtime, bag, path, value, forceCreate) { 253 | runtime.getPaths().runWrite(bag, path, value, forceCreate) 254 | } 255 | 256 | module.exports.Expression = Expression 257 | module.exports.setVarCore = setVarCore 258 | -------------------------------------------------------------------------------- /src/IgnoreOutput.js: -------------------------------------------------------------------------------- 1 | function IgnoreOutput() { 2 | 3 | } 4 | module.exports = IgnoreOutput -------------------------------------------------------------------------------- /src/InitializerError.js: -------------------------------------------------------------------------------- 1 | /* 2 | Object used when an error occurrs in the execution of an initializer expression 3 | */ 4 | function InitializerError(epDef, error) { 5 | this.expressionDefinition = epDef; 6 | this.error = error; 7 | }; 8 | InitializerError.prototype.toString = function() { 9 | return "fire.js runtime initializer '" + this.expressionDefinition.name + "' failed with error: '" + this.error + "'" 10 | } 11 | InitializerError.prototype.toJSONObject = function() { 12 | return { 13 | expression: { 14 | name: this.expressionDefinition.name, 15 | sourceUri: this.expressionDefinition.sourceUri 16 | }, 17 | error: (this.error.toJSONObject ? this.error.toJSONObject() : this.error.toString()) 18 | } 19 | } 20 | module.exports = InitializerError; -------------------------------------------------------------------------------- /src/Iterator.js: -------------------------------------------------------------------------------- 1 | var Iterator = function(collection) { 2 | if(!(collection instanceof Array)) { 3 | throw "Iterator requires the collection to be an array but '" + collection + "' was given instead" 4 | } 5 | this._lastIndex= collection.length - 1; 6 | this._index = -1; 7 | this._collection = collection; 8 | } 9 | 10 | Iterator.prototype.index = function() { 11 | return this._index 12 | } 13 | Iterator.prototype.isFirst = function() { 14 | return this._index === 0 15 | } 16 | Iterator.prototype.isLast = function() { 17 | return this._index === this._lastIndex 18 | } 19 | 20 | Iterator.prototype.current = function() { 21 | return this._collection[this._index] 22 | } 23 | 24 | Iterator.prototype.count = function() { 25 | return this._collection.length 26 | } 27 | 28 | Iterator.prototype.next = function() { 29 | if(this.isLast()) return false; 30 | this._index++; 31 | return true; 32 | } 33 | 34 | module.exports = Iterator -------------------------------------------------------------------------------- /src/ModuleInitializer.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var constants = require('./constants.js') 3 | function ModuleInitializer(thirdPartyModule, moduleRequire) { 4 | this.thirdPartyModule = thirdPartyModule 5 | this.thirdPartyModule.exports.ignition = thirdPartyModule.exports.ignition || {} 6 | this.thirdPartyModule.exports.ignition.expressions = thirdPartyModule.exports.ignition.expressions || [] 7 | //this.thirdPartyModule.exports.ignition.init = moduleInit 8 | this.thirdPartyModule.exports.ignition.moduleRequire = moduleRequire 9 | this.thirdPartyModule.exports.ignition.path = thirdPartyModule.filename 10 | 11 | var moduleDirName = this.moduleDirName = path.dirname(thirdPartyModule.filename) 12 | var moduleManifestFile = path.join(moduleDirName, constants.DEFAULT_MANIFEST_FILE_NAME) 13 | if(path.existsSync(moduleManifestFile)) { 14 | thirdPartyModule.exports.ignition.manifestFile = moduleManifestFile 15 | } 16 | var initializersDir = path.join(moduleDirName, constants.INITIALIZERS_DIR_NAME) 17 | if(path.existsSync(initializersDir)) { 18 | thirdPartyModule.exports.ignition.initializersDir = initializersDir 19 | } 20 | this.thirdPartyModule.exports.ignition.scriptDirs = [] 21 | 22 | // automatically add the root of the module as a scripts directory. 23 | this.exportScriptsDir('.') 24 | Object.defineProperty(this, "initializer", { 25 | get: function() { 26 | return this.thirdPartyModule.exports.ignition.init 27 | }, 28 | set: function(value) { 29 | this.thirdPartyModule.exports.ignition.init = value 30 | } 31 | }) 32 | } 33 | 34 | ModuleInitializer.prototype.exportExpressions = function(expDefArray) { 35 | var self = this 36 | if(!(expDefArray instanceof Array)) { 37 | throw "exportExpressions requires an Array with all the expression defintions" 38 | } 39 | expDefArray.forEach(function(expDef) { 40 | self.thirdPartyModule.exports.ignition.expressions.push(expDef) 41 | }) 42 | } 43 | 44 | ModuleInitializer.prototype.exportScriptsDir = function(dir, attributes) { 45 | var dirFullPath = path.join(this.moduleDirName, dir) 46 | if(!path.existsSync(dirFullPath)) { 47 | throw "ModuleInitializer could't find the scripts directory '" + dirFullPath + "'. Make sure the directory exists before using exportScriptsDir." 48 | } 49 | this.thirdPartyModule.exports.ignition.scriptDirs.push({ 50 | path: dirFullPath, 51 | attributes: attributes 52 | }) 53 | } 54 | 55 | ModuleInitializer.prototype.exportExpression = function(expDef) { 56 | this.thirdPartyModule.exports.ignition.expressions.push(expDef) 57 | } 58 | module.exports = ModuleInitializer -------------------------------------------------------------------------------- /src/ModuleInitializerError.js: -------------------------------------------------------------------------------- 1 | /* 2 | Object used when an error occurrs in the execution of a igniter initializer 3 | */ 4 | function ModuleInitializerError(module, error) { 5 | this.module = module; 6 | this.error = error; 7 | }; 8 | ModuleInitializerError.prototype.toString = function() { 9 | return "fire.js module initializer '" + this.module.ignition.path + "' failed with error: '" + this.error + "'" 10 | } 11 | ModuleInitializerError.prototype.toJSONObject = function() { 12 | return { 13 | modulePath:this.module.ignition.path, 14 | error: (this.error.toJSONObject ? this.error.toJSONObject() : this.error.toString()) 15 | } 16 | } 17 | module.exports = ModuleInitializerError; -------------------------------------------------------------------------------- /src/NameGenerator.js: -------------------------------------------------------------------------------- 1 | var NameGenerator = function(c) { 2 | this.count = c == undefined ? 0 : c 3 | } 4 | 5 | NameGenerator.prototype.name = function(base) { 6 | return "_v" + this.count + base 7 | } 8 | 9 | NameGenerator.prototype.createInner = function() { 10 | return new NameGenerator(this.count + 1) 11 | } 12 | 13 | module.exports = NameGenerator -------------------------------------------------------------------------------- /src/Paths.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var StringBuffer = require('./StringBuffer') 22 | var vm = require('vm') 23 | var Iterator = require('./Iterator') 24 | 25 | var AstEntryType = { 26 | "Unknown": 0, 27 | "Property": 1, 28 | } 29 | 30 | function PathCache() { 31 | this._compiledPaths = {} 32 | this._compiledWritePaths = {} 33 | } 34 | 35 | var Entry = function(type) { 36 | this.key = '' 37 | this.type = type 38 | } 39 | 40 | Entry.prototype.isEmpty = function() { 41 | return this.key === undefined || this.key === null || this.key === '' 42 | } 43 | 44 | var EXPECTING_ANYTHING = 0 45 | var EXPECTING_PROPERTY_NAME = 1 46 | var VALID_NUMBERS = "0123456789" 47 | 48 | function isDigit(c){ 49 | return VALID_NUMBERS.indexOf(c) !== -1 50 | } 51 | 52 | PathCache.prototype.parse = function(pathStr) { 53 | var list = [] 54 | var currentEntry = new Entry(AstEntryType.Property) 55 | var phase = undefined 56 | for(var i = 0; i < pathStr.length;i++) { 57 | var c = pathStr.charAt(i) 58 | if(c === '.') { 59 | //console.warn("period found at char " + i) 60 | if(currentEntry.isEmpty() && currentEntry.type !== AstEntryType.Unknown) { 61 | throw "Error at char index " + i + ": Can not get the property without an object" 62 | } 63 | if(currentEntry.type != AstEntryType.Unknown) { 64 | list.push(currentEntry) 65 | } 66 | currentEntry = new Entry(AstEntryType.Property)// new property entry 67 | phase = EXPECTING_PROPERTY_NAME 68 | } else if(c === ' ') { 69 | throw "Error at char index " + i + ": White spaces are not supported in names" 70 | } 71 | else { 72 | //console.warn("Literal char "+ c + " found at char " + i) 73 | if(currentEntry.type == AstEntryType.Unknown) { 74 | currentEntry.type = AstEntryType.Property 75 | } 76 | currentEntry.key += c 77 | phase = EXPECTING_ANYTHING 78 | } 79 | } 80 | //console.warn("end of parse") 81 | if(phase === EXPECTING_PROPERTY_NAME) { 82 | throw "Unexpected end path, expecting property name" 83 | } 84 | if(!currentEntry.isEmpty()) { 85 | list.push(currentEntry) 86 | } 87 | return list 88 | } 89 | 90 | PathCache.prototype.compile = function(pathStr) { 91 | var pathFileName = pathStr + ".path.js" 92 | var ast = this.parse(pathStr) 93 | var buffer = new StringBuffer() 94 | buffer.writeLine("//get: " + pathStr) 95 | buffer.writeLine("_compiledFunction = function(variablesSeed, path){") 96 | buffer.indent() 97 | buffer.writeLine("var res = undefined;") 98 | buffer.writeLine("var variables = undefined;") 99 | var iterator = new Iterator(ast); 100 | while(iterator.next()) { 101 | var entry = iterator.current(); 102 | buffer.writeLine("//." + entry.key) 103 | if(iterator.isFirst()) { 104 | 105 | buffer.writeLine("var currentVariables = variablesSeed") 106 | buffer.writeLine("while(currentVariables)") 107 | buffer.writeLine("{") 108 | buffer.indent() 109 | buffer.writeLine("res = currentVariables['" + entry.key +"']") 110 | buffer.writeLine("if(res !== undefined)") 111 | buffer.writeLine("{") 112 | buffer.indent() 113 | buffer.writeLine("variables = currentVariables") 114 | buffer.writeLine("break") 115 | buffer.unindent() 116 | buffer.writeLine("}") 117 | 118 | buffer.writeLine("currentVariables = currentVariables._parent") 119 | buffer.unindent() 120 | buffer.writeLine("} // while") 121 | buffer.writeLine("if(!variables)") 122 | buffer.writeLine("{") 123 | buffer.indent() 124 | buffer.writeLine("variables = variablesSeed") 125 | buffer.writeLine("res = variables['" + entry.key +"'];") 126 | buffer.unindent() 127 | buffer.writeLine("}") 128 | 129 | } else if(entry.type == AstEntryType.Property) { 130 | buffer.writeLine("res = res['" + entry.key +"'];") 131 | } 132 | buffer.writeLine("if(res === undefined || res === null) return res;") 133 | } 134 | buffer.writeLine("return res;") 135 | buffer.unindent() 136 | buffer.writeLine("}") 137 | var compilationResults = { 138 | "_compiledFunction": null 139 | } 140 | var sourceCode = buffer.toString() 141 | vm.runInNewContext(sourceCode, compilationResults, pathFileName); 142 | 143 | return this._compiledPaths[pathStr] = compilationResults._compiledFunction 144 | } 145 | 146 | PathCache.prototype.isCompiled = function(pathStr) { 147 | return this._compiledPaths[pathStr] !== undefined 148 | } 149 | PathCache.prototype.writeIsCompiled = function(pathStr) { 150 | return this._compiledWritePaths[pathStr] !== undefined 151 | } 152 | PathCache.prototype._runCore = function(variables, path) { 153 | return path(variables) 154 | } 155 | PathCache.prototype._runWriteCore = function(variables, path, value, forceCreate) { 156 | return path(variables, path, value, forceCreate) 157 | } 158 | PathCache.prototype.run = function(variables, pathStr) { 159 | var path = this._compiledPaths[pathStr] 160 | if(path === undefined) { 161 | path = this.compile(pathStr) 162 | } 163 | return this._runCore(variables, path) 164 | } 165 | 166 | PathCache.prototype.compileWrite = function(pathStr) { 167 | var pathFileName = pathStr + ".writePath.js" 168 | var ast = this.parse(pathStr) 169 | var buffer = new StringBuffer() 170 | buffer.writeLine("//set: " + pathStr) 171 | buffer.writeLine("_compiledFunction = function(variablesSeed, path, value, forceCreate){") 172 | buffer.indent() 173 | buffer.writeLine("var variables = undefined;") 174 | var iterator = new Iterator(ast); 175 | while(iterator.next()) { 176 | 177 | var entry = iterator.current(); 178 | buffer.writeLine("//." + entry.key) 179 | if(iterator.isFirst()) { 180 | 181 | buffer.writeLine("if(forceCreate) {") 182 | buffer.indent() 183 | buffer.writeLine("variables = variablesSeed") 184 | buffer.unindent() 185 | buffer.writeLine("}") 186 | buffer.writeLine("else {") 187 | buffer.indent() 188 | buffer.writeLine("var currentVariables = variablesSeed") 189 | buffer.writeLine("while(currentVariables)") 190 | buffer.writeLine("{") 191 | //buffer.writeLine("console.warn(currentVariables)") 192 | buffer.indent() 193 | 194 | buffer.writeLine("if(currentVariables['" + entry.key +"'] !== undefined)") 195 | buffer.writeLine("{") 196 | buffer.indent() 197 | buffer.writeLine("variables = currentVariables") 198 | buffer.writeLine("break") 199 | buffer.unindent() 200 | buffer.writeLine("}") 201 | 202 | buffer.writeLine("currentVariables = currentVariables._parent") 203 | buffer.unindent() 204 | buffer.writeLine("} // while") 205 | 206 | buffer.writeLine("if(!variables)") 207 | buffer.writeLine("{") 208 | buffer.indent() 209 | buffer.writeLine("variables = variablesSeed") 210 | buffer.unindent() 211 | buffer.writeLine("}") 212 | 213 | buffer.unindent() 214 | buffer.writeLine("} // else") 215 | buffer.writeLine("var currentVal = variables['" + entry.key +"'];") 216 | if(iterator.isLast()) { 217 | buffer.writeLine("variables['" + entry.key +"'] = value"); 218 | } else { 219 | buffer.writeLine("if(!currentVal) {"); 220 | buffer.indent() 221 | buffer.writeLine("currentVal = variables['" + entry.key +"'] = {}"); 222 | buffer.unindent() 223 | buffer.writeLine("}"); 224 | } 225 | } else if(entry.type == AstEntryType.Property) { 226 | if(iterator.isLast()) { 227 | buffer.writeLine("currentVal['" + entry.key +"'] = value;") 228 | } else { 229 | buffer.writeLine("var varVal = currentVal['" + entry.key +"']"); 230 | buffer.writeLine("if(!varVal){") 231 | buffer.indent() 232 | buffer.writeLine("varVal = currentVal['" + entry.key +"'] = {};") 233 | buffer.unindent() 234 | buffer.writeLine("}") 235 | buffer.writeLine("currentVal = varVal;"); 236 | } 237 | } 238 | } 239 | buffer.unindent() 240 | buffer.writeLine("}") 241 | var compilationResults = { 242 | "_compiledFunction": null, 243 | console: console 244 | } 245 | var sourceCode = buffer.toString() 246 | //console.log(sourceCode) 247 | vm.runInNewContext(sourceCode, compilationResults, pathFileName); 248 | 249 | return this._compiledWritePaths[pathStr] = compilationResults._compiledFunction 250 | } 251 | 252 | PathCache.prototype.runWrite = function(variables, pathStr, value, forceCreate) { 253 | var path = this._compiledWritePaths[pathStr] 254 | if(path === undefined) { 255 | path = this.compileWrite(pathStr) 256 | } 257 | return this._runWriteCore(variables, path, value, forceCreate) 258 | } 259 | 260 | module.exports.PathCache = PathCache 261 | module.exports.AstEntryType = AstEntryType -------------------------------------------------------------------------------- /src/RuntimeDictionary.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | function RuntimeDictionary() { 22 | 23 | } 24 | 25 | /* 26 | * Returns the name of all members. 27 | */ 28 | RuntimeDictionary.prototype.names = function() { 29 | return Object.keys(this) 30 | } 31 | 32 | RuntimeDictionary.prototype.toArray = function() { 33 | var array = [] 34 | var names = this.names(); 35 | for(var i = 0; i < names.length; i++) { 36 | array[i] = this[names[i]] 37 | } 38 | return array 39 | } 40 | module.exports = RuntimeDictionary -------------------------------------------------------------------------------- /src/RuntimeError.js: -------------------------------------------------------------------------------- 1 | /* 2 | Object used when some expression uses raiseError(error) 3 | */ 4 | function RuntimeError(blockContext, error) { 5 | this.blockContext = blockContext; 6 | this.error = error; 7 | }; 8 | RuntimeError.prototype.toString = function() { 9 | return "fire.js runtime error: " + this.error 10 | } 11 | module.exports = RuntimeError; -------------------------------------------------------------------------------- /src/StringBuffer.js: -------------------------------------------------------------------------------- 1 | 2 | var StringBuffer = function() { 3 | this.str = "" 4 | this.indentLevel = 0; 5 | this.indentStep = 2 6 | } 7 | StringBuffer.prototype.indent = function() { 8 | this.indentLevel++ 9 | } 10 | 11 | StringBuffer.prototype.unindent = function() { 12 | if(this.unindentLevel == 0) return; 13 | this.indentLevel-- 14 | } 15 | 16 | StringBuffer.prototype.createIndent = function() { 17 | var s = "" 18 | var max = this.indentLevel * this.indentStep; 19 | for(var i = 0;i < max; i++) { 20 | s+=" " 21 | } 22 | return s 23 | } 24 | 25 | StringBuffer.prototype.toString = function() { 26 | return this.str 27 | } 28 | 29 | StringBuffer.prototype.write = function(str, finishedCallback) { 30 | this.str+=str 31 | } 32 | 33 | StringBuffer.prototype.writeLine = function(str) { 34 | this.write(this.createIndent()) 35 | this.write(str) 36 | this.write("\n") 37 | } 38 | 39 | module.exports = StringBuffer; 40 | -------------------------------------------------------------------------------- /src/SynTable.js: -------------------------------------------------------------------------------- 1 | function SynTable() { 2 | this.count = 0 3 | this.prefix = "_" 4 | this.names= {} 5 | } 6 | 7 | SynTable.prototype.syn = function(name) { 8 | var syn = this.names[name] 9 | if(!syn) { 10 | syn = this.names[name] = this.prefix + (++this.count) 11 | } 12 | return syn 13 | } 14 | module.exports = SynTable -------------------------------------------------------------------------------- /src/Utils.js: -------------------------------------------------------------------------------- 1 | var path = require('path') 2 | var fs = require('fs') 3 | var assert = require('assert') 4 | 5 | 6 | function endsWith(str, suffix) { 7 | return str.indexOf(suffix, str.length - suffix.length) !== -1; 8 | } 9 | module.exports.endsWith = endsWith 10 | 11 | 12 | /* 13 | Returns the files with a specific extension. Returns the file name and not the path. 14 | */ 15 | module.exports.getFilesWithExtension = function(absoluteDirPath, extension) { 16 | var fileNames = fs.readdirSync(absoluteDirPath) 17 | var list = [] 18 | fileNames.forEach(function(fileName) { 19 | if(endsWith(fileName,extension)) 20 | { 21 | list.push(fileName) 22 | } 23 | }) 24 | return list 25 | } -------------------------------------------------------------------------------- /src/built-in/break.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Break() { 24 | 25 | } 26 | Break.prototype = new Expression(); 27 | Break.prototype.execute = function() { 28 | this.loopControl('break') 29 | } 30 | 31 | module.exports = { 32 | name:"break", 33 | implementation:Break 34 | } -------------------------------------------------------------------------------- /src/built-in/catch.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Catch() { 24 | 25 | } 26 | Catch.prototype = new Expression() 27 | Catch.prototype.execute = function() { 28 | var self = this 29 | var errInfo = this.getParentError() 30 | var CurrentErrorVarName = this.hasHint() ? this.getHintValue() + 'CurrentError' : 'CurrentError' 31 | 32 | this.clearParentError() 33 | 34 | if(errInfo) { 35 | // there is an error, run the input... 36 | this.setScopeVar(CurrentErrorVarName, errInfo) // let the input know about the error 37 | this.runInput(function(res) { 38 | // and return the values. any errors are bubbled up 39 | self.end(res) 40 | }); 41 | } else { 42 | // No errors found, return the parent result inmediately 43 | self.bypass() 44 | } 45 | } 46 | 47 | module.exports = { 48 | name:"catch", 49 | flags: ["hint"], 50 | implementation:Catch 51 | } -------------------------------------------------------------------------------- /src/built-in/clearError.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function ClearError() { 24 | 25 | } 26 | ClearError.prototype = new Expression() 27 | ClearError.prototype.execute = function() { 28 | var self = this 29 | self.clearParentError() 30 | self.bypass(); 31 | } 32 | 33 | module.exports = { 34 | name:"clearError", 35 | implementation:ClearError 36 | } -------------------------------------------------------------------------------- /src/built-in/concat.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | var extractComparableValues = require('../Comparable').extractComparableValues 24 | 25 | function ConcatExpression() { 26 | 27 | } 28 | ConcatExpression.prototype = new Expression() 29 | ConcatExpression.prototype.execute = function() { 30 | var self = this 31 | this.runInput(function(res) { 32 | var values = extractComparableValues(res) 33 | var len = values.length 34 | var result = null 35 | for(var i = 0;i < len; i++) { 36 | var val = values[i] 37 | if(result === null) { 38 | if(val !== undefined && val !== null) { 39 | // use the first not-null value as seed to concatenate the next values 40 | result = val 41 | } else { 42 | break 43 | } 44 | } else { 45 | if(result.concat) { 46 | result = result.concat(val) 47 | } else { 48 | // can't no longer concate values. 49 | break 50 | } 51 | } 52 | } 53 | self.end(result) 54 | }); 55 | } 56 | 57 | module.exports = { 58 | name: "concat", 59 | implementation: ConcatExpression 60 | } -------------------------------------------------------------------------------- /src/built-in/continue.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../Expressions").Expression 2 | function Continue() { 3 | 4 | } 5 | Continue.prototype = new Expression() 6 | Continue.prototype.execute = function() { 7 | this.loopControl('continue') 8 | } 9 | 10 | module.exports = { 11 | name:"continue", 12 | implementation:Continue 13 | } -------------------------------------------------------------------------------- /src/built-in/decrement.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Decrement() { 24 | 25 | } 26 | Decrement.prototype = new Expression() 27 | Decrement.prototype.execute = function() { 28 | var self = this 29 | if(!this.requireHint()) return; 30 | 31 | var value = this.getHintVariableValue() 32 | 33 | if(isNaN(value) || value === undefined || value === null) { 34 | this.setParentVar(this.getHintValue(), NaN) 35 | this.bypass() 36 | } else { 37 | // run the input... 38 | this.runInput(function(res) { 39 | if(isNaN(res) || res === undefined || res === null) { 40 | self.setParentVar(self.getHintValue(), NaN) 41 | self.bypass() 42 | } else { 43 | var res = value - res 44 | self.setParentVar(self.getHintValue(), res) 45 | self.bypass() 46 | } 47 | }); 48 | } 49 | } 50 | 51 | module.exports = { 52 | name: "decrement", 53 | flags: ["hint"], 54 | implementation: Decrement 55 | } -------------------------------------------------------------------------------- /src/built-in/each.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | var Iterator = require('../Iterator') 24 | function Each() { 25 | 26 | } 27 | Each.prototype = new Expression() 28 | Each.prototype.onPrepareInput = function() { 29 | var self = this 30 | this.inputExpression.scopeBypass = true 31 | this.inputExpression.loopCallback = function(cmd) { 32 | if(cmd == "break") { 33 | self.end(self._result) // return the array 34 | } else if(cmd == "continue") { 35 | process.nextTick(function() { 36 | self._iterate() // call the next iteration 37 | }) 38 | } else { 39 | throw "Invalid loop command " + cmd 40 | } 41 | } 42 | } 43 | Each.prototype._iterate = function() { 44 | var self = this 45 | if(!this._iterator.next()) { 46 | self.end(this._result) 47 | return 48 | } 49 | this._count++ 50 | this.setVar(this._CurrentIndexVarName, this._count) 51 | this.setVar(this._itemVarName, this._iterator.current()) 52 | this.runInput(function(res) { 53 | self._result.push(res) 54 | process.nextTick(function() { 55 | self._iterate() // call the next iteration 56 | }) 57 | }); 58 | } 59 | Each.prototype.execute = function() { 60 | this._result = [] 61 | this._varVal = this.getParentResult() 62 | if(!(this._varVal instanceof Array)) { 63 | this.end(this._result) 64 | return 65 | } 66 | this._itemVarName = this.hasHint() ? this.getHintValue() + 'CurrentItem' : 'CurrentItem' 67 | this._CurrentIndexVarName = this.hasHint() ? this.getHintValue() + 'CurrentIndex' : 'CurrentIndex' 68 | this._iterator = new Iterator(this._varVal) 69 | this._count = -1 70 | this._iterate(); // call the first iteration 71 | } 72 | 73 | module.exports = { 74 | name: "each", 75 | flags: ["hint"], 76 | implementation: Each 77 | } -------------------------------------------------------------------------------- /src/built-in/equals.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | var extractComparableValues = require('../Comparable').extractComparableValues 23 | var comparableAreEqual = require('../Comparable').areEqual 24 | var STRICT = 'strict' 25 | function Equals() { 26 | 27 | } 28 | Equals.prototype = new Expression() 29 | Equals.prototype.execute = function() { 30 | var self = this 31 | var strict = false 32 | if(this.hasHint() && this.getHintValue().indexOf(STRICT) != -1) { 33 | strict = true 34 | } 35 | this.runInput(function(res) { 36 | var values = extractComparableValues(res) 37 | if(values.length < 2) { 38 | self.end(undefined) 39 | return 40 | } 41 | var res = comparableAreEqual(values, strict) 42 | self.end(res) 43 | }); 44 | } 45 | 46 | module.exports = { 47 | name:"equals", 48 | flags: ["hint"], 49 | implementation:Equals 50 | } -------------------------------------------------------------------------------- /src/built-in/get.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Get() { 24 | 25 | } 26 | 27 | Get.prototype = new Expression() 28 | Get.prototype.execute = function() { 29 | var self = this 30 | var val = undefined; 31 | var hint = this.hint 32 | if(hint) 33 | { 34 | this.end(this.getParentVar(hint)) 35 | } else { 36 | this.bypass() 37 | } 38 | } 39 | 40 | module.exports = { 41 | name:"get", 42 | flags: ["hint"], 43 | implementation:Get 44 | } -------------------------------------------------------------------------------- /src/built-in/getModuleConfig.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function GetModuleConfigExpression() { 25 | 26 | } 27 | GetModuleConfigExpression.prototype = new Expression() 28 | GetModuleConfigExpression.prototype.execute = function() { 29 | var moduleName = this.getHintValue() 30 | var moduleConfig = this.runtime.getModuleConfiguration(moduleName) 31 | this.end(moduleConfig) 32 | } 33 | 34 | module.exports = { 35 | name: "getModuleConfig", 36 | flags: ["hint"], 37 | implementation: GetModuleConfigExpression 38 | } -------------------------------------------------------------------------------- /src/built-in/hint.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | 23 | var Expression = require("../Expressions").Expression 24 | 25 | function HintExpression() { 26 | 27 | } 28 | HintExpression.prototype = new Expression() 29 | HintExpression.prototype.execute = function() { 30 | var self = this 31 | var rootParent = this.getRootParent() 32 | if(!rootParent) { 33 | // Crap! They are trying to call @hint from a custom implementation... shouldn't they be using getRootParent().getHintValue() function function? 34 | throw "@hint can not be directly used by custom implementations. Only fire.js compiler is allowed to use it. You should be using the getRootParent().getHintValue() function instead." 35 | } 36 | //get the hint 37 | this.end(rootParent.getHintValue()) 38 | } 39 | 40 | module.exports = { 41 | name:"hint", 42 | implementation:HintExpression 43 | } -------------------------------------------------------------------------------- /src/built-in/if.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function If() { 24 | 25 | } 26 | If.prototype = new Expression() 27 | If.prototype.execute = function() { 28 | var self = this 29 | 30 | var met = this.hasHint() ? this.getHintVariableValue() : this.getParentResult(); 31 | 32 | if(met) { 33 | // run the input... 34 | this.runInput(function(res) { 35 | // and return the values. any errors are bubbled up 36 | self.end(res) 37 | }); 38 | } else { 39 | // Condition not met, return the parent result inmediately 40 | self.bypass() 41 | } 42 | } 43 | 44 | module.exports = { 45 | name:"if", 46 | flags: ["hint"], 47 | implementation:If 48 | } -------------------------------------------------------------------------------- /src/built-in/increment.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function Increment() { 25 | 26 | } 27 | Increment.prototype = new Expression() 28 | Increment.prototype.execute = function() { 29 | var self = this 30 | if(!this.requireHint()) return; 31 | 32 | var value = this.getHintVariableValue() 33 | 34 | if(isNaN(value) || value === undefined || value === null) { 35 | this.setParentVar(this.getHintValue(), NaN) 36 | this.bypass() 37 | } else { 38 | // run the input... 39 | this.runInput(function(res) { 40 | if(isNaN(res) || res === undefined || res === null) { 41 | self.setParentVar(self.getHintValue(), NaN) 42 | self.bypass() 43 | } else { 44 | var res = value + res 45 | self.setParentVar(self.getHintValue(), res) 46 | self.bypass() 47 | } 48 | }); 49 | } 50 | } 51 | 52 | module.exports = { 53 | name:"increment", 54 | flags: ["hint"], 55 | implementation:Increment 56 | } -------------------------------------------------------------------------------- /src/built-in/index.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function IndexExpression() { 25 | 26 | } 27 | 28 | IndexExpression.prototype = new Expression() 29 | IndexExpression.prototype.execute = function() { 30 | var self = this 31 | var result = this.hasHint() ? this.getHintVariableValue() : this.getParentResult() 32 | if(result) 33 | { 34 | if(typeof(result) === 'object') { 35 | this.runInput( function(res) { 36 | self.end(result[res]) 37 | }) 38 | } else { 39 | this.bypass() 40 | } 41 | } else { 42 | this.bypass() 43 | } 44 | } 45 | 46 | module.exports = { 47 | name:"index", 48 | flags: ["hint"], 49 | implementation:IndexExpression 50 | } -------------------------------------------------------------------------------- /src/built-in/input.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Input() { 24 | 25 | } 26 | Input.prototype = new Expression() 27 | Input.prototype.execute = function() { 28 | var self = this 29 | var rootParent = this.getRootParent() 30 | if(!rootParent) { 31 | // Crap! They are trying to call @input from a custom implementation... shouldn't they be using runInput function? 32 | throw "@input can not be directly used by custom implementations. Only fire.js compiler is allowed to use it. You should be using the getRootParent().runInput function instead." 33 | } 34 | // run the input... 35 | this.runInputFromTarget(rootParent, function(res) { 36 | // and return the values. any errors are bubbled up 37 | self.end(res) 38 | }); 39 | } 40 | 41 | module.exports = { 42 | name:"input", 43 | implementation:Input 44 | } -------------------------------------------------------------------------------- /src/built-in/isEmpty.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function IsEmpty() { 25 | 26 | } 27 | IsEmpty.prototype = new Expression() 28 | IsEmpty.prototype.isEmptyCore = function(val) { 29 | var isEmpty = (val == undefined || val == null || val == '') 30 | this.end(isEmpty) 31 | } 32 | IsEmpty.prototype.execute = function() { 33 | var self = this 34 | 35 | if(this.hasHint()) { 36 | this.isEmptyCore(this.getHintVariableValue()) 37 | } else { 38 | this.runInput(function(res) { 39 | self.isEmptyCore(res) 40 | }) 41 | } 42 | } 43 | 44 | module.exports = { 45 | name:"isEmpty", 46 | flags: ["hint"], 47 | implementation:IsEmpty 48 | } -------------------------------------------------------------------------------- /src/built-in/isNotEmpty.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function IsNotEmpty() { 25 | 26 | } 27 | IsNotEmpty.prototype = new Expression() 28 | IsNotEmpty.prototype.isNotEmptyCore = function(val) { 29 | var isEmpty = (val != undefined && val != null && val != '') 30 | this.end(isEmpty) 31 | } 32 | IsNotEmpty.prototype.execute = function() { 33 | var self = this 34 | 35 | if(this.hasHint()) { 36 | this.isNotEmptyCore(this.getHintVariableValue()) 37 | } else { 38 | this.runInput(function(res) { 39 | self.isNotEmptyCore(res) 40 | }) 41 | } 42 | } 43 | module.exports = { 44 | name:"isNotEmpty", 45 | flags: ["hint"], 46 | implementation:IsNotEmpty 47 | } 48 | -------------------------------------------------------------------------------- /src/built-in/loop.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | function Loop() { 24 | 25 | } 26 | Loop.prototype = new Expression() 27 | 28 | Loop.prototype.onPrepareInput = function() { 29 | var self = this 30 | this.inputExpression.scopeBypass = true 31 | this.inputExpression.loopCallback = function(cmd) { 32 | if(cmd == "break") { 33 | self.end(self._result) // return the array 34 | } else if(cmd == "continue") { 35 | process.nextTick(function() { 36 | self._iterate() // call the next iteration 37 | }) 38 | } else { 39 | throw "Invalid loop command " + cmd 40 | } 41 | } 42 | } 43 | Loop.prototype._iterate = function() { 44 | var self = this 45 | this._count++ 46 | this.setVar(this._CurrentIndexVarName,this._count) 47 | this.runInput(function(res) { 48 | self._result.push(res) 49 | process.nextTick(function() { 50 | self._iterate() // call the next iteration 51 | }) 52 | }); 53 | } 54 | Loop.prototype.execute = function() { 55 | var self = this 56 | this._result = [] 57 | this._count = -1 58 | this._CurrentIndexVarName = this.hasHint() ? this.getHintValue() + 'CurrentIndex' : 'CurrentIndex' 59 | this._iterate() // trigger the first iteration 60 | } 61 | 62 | module.exports = { 63 | name: "loop", 64 | flags: ["hint"], 65 | implementation: Loop 66 | } -------------------------------------------------------------------------------- /src/built-in/notEquals.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | var extractComparableValues = require('../Comparable').extractComparableValues 24 | var comparableAreNotEqual = require('../Comparable').areNotEqual 25 | var STRICT = 'strict' 26 | function NotEquals() { 27 | 28 | } 29 | NotEquals.prototype = new Expression() 30 | NotEquals.prototype.execute = function() { 31 | var self = this 32 | var strict = false 33 | if(this.hasHint() && this.getHintValue().indexOf(STRICT) != -1) { 34 | strict = true 35 | } 36 | this.runInput(function(res) { 37 | var values = extractComparableValues(res) 38 | if(values.length < 2) { 39 | self.end(undefined) 40 | return 41 | } 42 | var res = comparableAreNotEqual(values, strict) 43 | self.end(res) 44 | }); 45 | } 46 | 47 | module.exports = { 48 | name:"notEquals", 49 | flags: ["hint"], 50 | implementation:NotEquals 51 | } -------------------------------------------------------------------------------- /src/built-in/parentResult.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../Expressions").Expression 2 | 3 | function ParentResult() { 4 | 5 | } 6 | ParentResult.prototype = new Expression() 7 | ParentResult.prototype.execute = function() { 8 | var self = this 9 | var rootParent = this.getRootParent() 10 | if(!rootParent) { 11 | // Crap! They are trying to call @parentResult from a custom implementation... shouldn't they be using getParentResult function? 12 | throw "@parentResult can not be directly used by custom implementations. Only fire.js compiler is allowed to use it. You should be using the getRootParent().getCurrentResult() function instead." 13 | } 14 | this.end(rootParent.getParentResult()) 15 | } 16 | 17 | module.exports = { 18 | name: "parentResult", 19 | implementation: ParentResult 20 | } -------------------------------------------------------------------------------- /src/built-in/push.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Push() { 24 | 25 | } 26 | Push.prototype = new Expression() 27 | Push.prototype.execute = function() { 28 | this.runInput(function(item, self) { 29 | var target = self.hasHint() ? self.getHintVariableValue() : self.getParentResult() 30 | if(target instanceof Array) { 31 | self.end(target.push(item) -1) // Returns the index of the inserted item 32 | } else { 33 | self.end(undefined) // Returns undefined 34 | } 35 | }) 36 | } 37 | 38 | module.exports = { 39 | name: "push", 40 | flags: ["hint"], 41 | implementation: Push 42 | } -------------------------------------------------------------------------------- /src/built-in/raiseError.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | function RaiseError() { 24 | 25 | } 26 | RaiseError.prototype = new Expression() 27 | RaiseError.prototype.execute = function() { 28 | var self = this 29 | this.runInput(function(res) { 30 | self.raiseError(res) 31 | }); 32 | } 33 | 34 | module.exports = { 35 | name: "raiseError", 36 | implementation: RaiseError 37 | } -------------------------------------------------------------------------------- /src/built-in/return.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../Expressions").Expression 2 | function Return() { 3 | 4 | } 5 | Return.prototype = new Expression() 6 | Return.prototype.execute = function() { 7 | var self = this 8 | this.runInput(function(res) { 9 | self.end(res) 10 | }); 11 | } 12 | 13 | module.exports = { 14 | name: "return", 15 | implementation: Return 16 | } -------------------------------------------------------------------------------- /src/built-in/returnError.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | function ReturnError() { 24 | 25 | } 26 | ReturnError.prototype = new Expression() 27 | ReturnError.prototype.execute = function() { 28 | var error = this.getParentError() 29 | if(error) { 30 | this.end(error.error) 31 | } else { 32 | this.end(undefined) 33 | } 34 | } 35 | 36 | 37 | module.exports = { 38 | name: "returnError", 39 | implementation: ReturnError 40 | } -------------------------------------------------------------------------------- /src/built-in/scopeSet.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function ScopeSet() { 25 | 26 | } 27 | ScopeSet.prototype = new Expression() 28 | ScopeSet.prototype.execute = function(){ 29 | var self = this 30 | if(this.hasHint()) { 31 | this.runInput(function(res) { 32 | self.setParentScopeVar(self.getHintValue(), res) 33 | self.bypass() 34 | }); 35 | } else { 36 | self.bypass() 37 | } 38 | 39 | } 40 | 41 | module.exports = { 42 | name:"scopeSet", 43 | flags: ["hint"], 44 | implementation:ScopeSet 45 | } -------------------------------------------------------------------------------- /src/built-in/set.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function Set() { 25 | 26 | } 27 | Set.prototype = new Expression() 28 | Set.prototype.execute = function(){ 29 | var self = this 30 | var hint = this.hint 31 | var validHint = hint != undefined && hint != undefined && hint != null 32 | if(validHint) { 33 | this.runInput(function(res) { 34 | self.setParentVar(hint, res) 35 | self.bypass() 36 | }); 37 | } else { 38 | this.bypass() 39 | } 40 | } 41 | 42 | module.exports = { 43 | name:"set", 44 | flags: ["hint"], 45 | implementation:Set 46 | } -------------------------------------------------------------------------------- /src/built-in/test.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function Test() { 25 | 26 | } 27 | Test.prototype = new Expression() 28 | Test.prototype.execute = function() { 29 | var self = this 30 | var operand = this.hasHint() ? this.getHintVariableValue() : this.getParentResult(); 31 | this.runInput(function(res) { 32 | if(typeof(res) == 'string') { 33 | self.end(new RegExp(res).test(operand)) 34 | } else if(typeof(res) == 'object') { 35 | self.end(new RegExp(res.expression, res.modifiers).test(operand)) 36 | } else { 37 | self.end(false) 38 | } 39 | }) 40 | } 41 | module.exports = { 42 | name:"test", 43 | flags: ["hint"], 44 | implementation:Test 45 | } 46 | -------------------------------------------------------------------------------- /src/built-in/trigger.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require('../Expressions').Expression 22 | 23 | // 24 | // Invokes the delegate in the hint path and returns the result. The input is ignored, null is suggested. 25 | // 26 | function Trigger() { 27 | 28 | } 29 | Trigger.prototype = new Expression(); 30 | Trigger.prototype.execute = function() { 31 | var hintValue = this.getHintVariableValue(); 32 | if(typeof(hintValue) !== 'function') { 33 | // Is not a function, the delegate block was inlined by the compiler and it's the literal is already there. 34 | return this.end(hintValue); 35 | } else { 36 | // It's a function, we need to call it so we get an instance of the expression block. 37 | var delegateExpression = hintValue(); 38 | delegateExpression.resultCallback = function(res, parent) { 39 | parent.end(res); // Return the result of the delegate. 40 | }; 41 | // Execute the delegate 42 | delegateExpression.run(this); 43 | } 44 | }; 45 | 46 | exports.name = 'trigger'; 47 | exports.implementation = Trigger; 48 | exports.flags = ['hint']; 49 | -------------------------------------------------------------------------------- /src/built-in/try.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | function Try() { 24 | 25 | } 26 | Try.prototype = new Expression() 27 | Try.prototype.onPrepareInput = function() { 28 | var self = this 29 | this.inputExpression.errorCallback = function(err) { 30 | self.setParentError(err) 31 | self.bypass() 32 | } 33 | } 34 | Try.prototype.execute = function() { 35 | var self = this 36 | this.runInput(function(res) { 37 | self.end(res) 38 | }); 39 | } 40 | 41 | module.exports = { 42 | name:"try", 43 | implementation:Try 44 | } -------------------------------------------------------------------------------- /src/built-in/undefined.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function Undefined() { 25 | 26 | } 27 | 28 | Undefined.prototype = new Expression() 29 | Undefined.prototype.execute = function() { 30 | this.end(undefined) 31 | } 32 | 33 | module.exports = { 34 | name:"undefined", 35 | implementation:Undefined 36 | } -------------------------------------------------------------------------------- /src/built-in/unless.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | 22 | var Expression = require("../Expressions").Expression 23 | 24 | function Unless() { 25 | 26 | } 27 | Unless.prototype = new Expression() 28 | Unless.prototype.execute = function() { 29 | var self = this 30 | 31 | var met = this.hasHint() ? this.getHintVariableValue() : this.getParentResult(); 32 | 33 | if(!met) { 34 | // run the input... 35 | this.runInput(function(res) { 36 | // and return the values. any errors are bubbled up 37 | self.end(res) 38 | }); 39 | } else { 40 | // Condition not met, return the parent result inmediately 41 | self.bypass() 42 | } 43 | } 44 | 45 | module.exports = { 46 | name: "unless", 47 | flags: ["hint"], 48 | implementation: Unless 49 | } -------------------------------------------------------------------------------- /src/built-in/xif.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Xif() { 24 | 25 | } 26 | Xif.prototype = new Expression(); 27 | Xif.prototype.execute = function() { 28 | // run the input... 29 | this.runInput(function(res, parent) { 30 | if(!res) { 31 | return parent.end(undefined); 32 | } 33 | var met = parent.hasHint() ? parent.getHintVariableValue() : parent.getParentResult(); 34 | if(met) { 35 | // Return '#then' delegate result 36 | var thenDelegate = res['#then']; 37 | if(typeof(thenDelegate) === 'function') { 38 | var exp = thenDelegate(); 39 | exp.resultCallback = function(dres, dparent) { 40 | dparent.end(dres); 41 | }; 42 | exp.run(parent); 43 | } else { 44 | parent.end(thenDelegate); 45 | } 46 | } else { 47 | // Return '#else' delegate result 48 | var elseDelegate = res['#else']; 49 | if(typeof(elseDelegate) === 'function') { 50 | var exp = elseDelegate(); 51 | exp.resultCallback = function(dres, dparent) { 52 | dparent.end(dres); 53 | }; 54 | exp.run(parent); 55 | } else { 56 | parent.end(elseDelegate); 57 | } 58 | } 59 | }); 60 | }; 61 | 62 | exports.name = 'xif'; 63 | exports.flags = ['hint']; 64 | exports.implementation = Xif; 65 | -------------------------------------------------------------------------------- /src/built-in/xunless.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var Expression = require("../Expressions").Expression 22 | 23 | function Xunless() { 24 | 25 | } 26 | Xunless.prototype = new Expression(); 27 | Xunless.prototype.execute = function() { 28 | // run the input... 29 | this.runInput(function(res, parent) { 30 | if(!res) { 31 | return parent.end(undefined); 32 | } 33 | var met = parent.hasHint() ? parent.getHintVariableValue() : parent.getParentResult(); 34 | if(!met) { 35 | // Return '#then' delegate result 36 | var thenDelegate = res['#then']; 37 | if(typeof(thenDelegate) === 'function') { 38 | var exp = thenDelegate(); 39 | exp.resultCallback = function(dres, dparent) { 40 | dparent.end(dres); 41 | }; 42 | exp.run(parent); 43 | } else { 44 | parent.end(thenDelegate); 45 | } 46 | } else { 47 | // Return '#else' delegate result 48 | var elseDelegate = res['#else']; 49 | if(typeof(elseDelegate) === 'function') { 50 | var exp = elseDelegate(); 51 | exp.resultCallback = function(dres, dparent) { 52 | dparent.end(dres); 53 | }; 54 | exp.run(parent); 55 | } else { 56 | parent.end(elseDelegate); 57 | } 58 | } 59 | }); 60 | }; 61 | 62 | exports.name = 'xunless'; 63 | exports.flags = ['hint']; 64 | exports.implementation = Xunless; 65 | -------------------------------------------------------------------------------- /src/cli.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | /* 22 | * This file bootstraps the Runtime for the Command Line. It's compiled in place of the initial script of the app. Check the file bin/firejs 23 | */ 24 | 25 | var fire = require('fire') 26 | var path = require('path') 27 | var sys = require('util') 28 | var fs = require('fs') 29 | var util = require('util') 30 | 31 | module.exports = function() { 32 | var pureArgs = process.argv.slice(2) 33 | var parsedArgv = process.parsedArgv 34 | var noArgs = pureArgs.length == 0 35 | var mainScriptPath = module.filename 36 | var mainScriptDirName = path.dirname(mainScriptPath) 37 | var expressionName = null 38 | var applicationName = '' 39 | if(path.basename(mainScriptPath) == "package.json") { 40 | // Read package.json 41 | var packageJson = JSON.parse(fs.readFileSync(mainScriptPath, 'utf8')) 42 | expressionName = packageJson.name + ".Main" 43 | applicationName = packageJson.name 44 | } else { 45 | // Exec the app. 46 | var expressionName = fire.inferExpressionNameByFileName(path.basename(mainScriptPath)) 47 | if(!expressionName) { 48 | throw "The file '" + mainScriptPath+ "' was not recognized as a fire script due file name extension incompatibility" 49 | return 50 | } 51 | var appNameSeparator = expressionName.indexOf('.') 52 | applicationName = appNameSeparator == -1 ? expressionName : expressionName.substring(0,appNameSeparator) 53 | } 54 | 55 | 56 | //require.paths.unshift(path.join(mainScriptDirName,'node_modules')) 57 | 58 | var runtime = new fire.Runtime() 59 | runtime.applicationName = applicationName 60 | runtime.moduleRequire = function(moduleName) { 61 | return require(moduleName) 62 | } 63 | var manifestPath = path.join(mainScriptDirName, fire.DEFAULT_MANIFEST_FILE_NAME) 64 | path.exists(manifestPath, function(manifestFound) { 65 | var self = this 66 | var initializationFinished = function(err) { 67 | if(err) { 68 | var UnknownConstructor = "" 69 | var errorType = ((typeof(err) === 'object' && err.constructor) ? (err.constructor.name || UnknownConstructor) : "UnknownConstructor") 70 | if(!process.parsedArgv['porcelain-errors']) { 71 | console.error("Fire.JS Runtime Initialization Error") 72 | console.error({ 73 | type: errorType, 74 | error: err 75 | }) 76 | } else { 77 | console.error(JSON.stringify({ 78 | type: errorType, 79 | error: (err.toJSONObject ? err.toJSONObject() : err.toString()) 80 | })) 81 | } 82 | process.exit(fire.INITIALIZATION_ERROR_EXIT_CODE) 83 | } 84 | if(parsedArgv['print-expressions'] == true) { 85 | var expressions = [] 86 | var expNames = Object.keys(runtime.loadedExpressionsMeta) 87 | for(var i = 0; i < expNames.length; i++) { 88 | var meta = runtime.loadedExpressionsMeta[expNames[i]] 89 | expressions.push({ 90 | name: meta.name, 91 | flags: meta.flags 92 | }) 93 | } 94 | sys.print(JSON.stringify(expressions)) 95 | process.exit(0) 96 | } 97 | else if(parsedArgv['print-manifest'] == true) { 98 | sys.print(JSON.stringify(runtime.mergedManifest)) 99 | process.exit(0) 100 | } 101 | else 102 | { 103 | var expDef = runtime.getExpressionDefinition(expressionName) 104 | if(!expDef) { 105 | var msg = "Main Expression '" + expressionName + "' can not be found" 106 | if(!process.parsedArgv['porcelain-errors']) { 107 | console.error("Fire.JS CLI Error") 108 | console.error(msg) 109 | } else { 110 | console.error(JSON.stringify({ 111 | type: "MainExpressionNotFound", 112 | error: { 113 | message: msg, 114 | expressionName: expressionName 115 | } 116 | })) 117 | } 118 | process.exit(fire.MAIN_EXPRESSION_NOT_FOUND_ERROR_EXIT_CODE) 119 | } 120 | var exp = new(expDef.implementation) 121 | exp.runtime = runtime 122 | exp.resultCallback = function(res) { 123 | if(!(res instanceof fire.IgnoreOutput)) { 124 | sys.print(JSON.stringify(res)) 125 | } 126 | process.exit(0) 127 | } 128 | exp.errorCallback = function(err) { 129 | console.error(util.inspect(err)) 130 | process.exit(1) 131 | } 132 | exp.run() 133 | } 134 | } 135 | 136 | if(manifestFound) { 137 | runtime.loadFromManifestFile(manifestPath, initializationFinished) 138 | } else { 139 | runtime.setBaseDir(mainScriptDirName) 140 | // Manually load the scripts 141 | runtime.load(initializationFinished) 142 | } 143 | }) 144 | 145 | } -------------------------------------------------------------------------------- /src/constants.js: -------------------------------------------------------------------------------- 1 | module.exports.DEFAULT_SCRIPT_EXTENSION = ".fjson" 2 | module.exports.DEFAULT_CUSTOM_SCRIPT_EXTENSION = ".fjs" 3 | module.exports.DEFAULT_EXPRESSION_EXTENSIONS = [module.exports.DEFAULT_SCRIPT_EXTENSION, module.exports.DEFAULT_CUSTOM_SCRIPT_EXTENSION] 4 | module.exports.DEFAULT_MANIFEST_FILE_NAME = "ignition.manifest.json" 5 | module.exports.DEFAULT_ENVIRONMENT = "development" 6 | module.exports.INITIALIZERS_DIR_NAME = "initializers" 7 | module.exports.VIRTUAL_EXPRESSION_URI_PROTOCOL = "virtual" 8 | module.exports.FILE_EXPRESSION_URI_PROTOCOL = "fs" 9 | module.exports.INITIALIZATION_ERROR_EXIT_CODE = 1 10 | module.exports.MAIN_EXPRESSION_NOT_FOUND_ERROR_EXIT_CODE = 2 -------------------------------------------------------------------------------- /src/core.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 Firebase.co and Contributors - http://www.firebase.co 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a copy 4 | // of this software and associated documentation files (the "Software"), to deal 5 | // in the Software without restriction, including without limitation the rights 6 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | // copies of the Software, and to permit persons to whom the Software is 8 | // furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in 11 | // all copies or substantial portions of the Software. 12 | // 13 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | // FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE 16 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | // THE SOFTWARE. 20 | 21 | var vm = require('vm') 22 | var util = require('util') 23 | var path = require('path') 24 | var RuntimeError = require('./RuntimeError') 25 | var Iterator = require('./Iterator') 26 | var Expressions = require('./Expressions') 27 | var mergeWith = require('./mergeWith.js') 28 | var ModuleInitializer = require('./ModuleInitializer.js') 29 | var fs = require('fs') 30 | 31 | /* 32 | * Export Shared Types 33 | */ 34 | module.exports.Error = require('./Error') 35 | module.exports.Expression = Expressions.Expression 36 | module.exports.Iterator = require('./Iterator') 37 | module.exports.CompilationError = require('./CompilationError.js') 38 | module.exports.InitializerError = require('./InitializerError.js') 39 | module.exports.IgnoreOutput = require('./IgnoreOutput') 40 | module.exports.Runtime = require('./Runtime.js') 41 | module.exports.RuntimeError = require('./RuntimeError.js') 42 | module.exports.ModuleInitializerError = require('./ModuleInitializerError.js') 43 | 44 | /* 45 | * Export Constants 46 | */ 47 | var constants = require('./constants.js') 48 | mergeWith(module.exports, constants) 49 | 50 | /* 51 | * Register Custom Extensions in Node.JS 52 | */ 53 | require.extensions[constants.DEFAULT_CUSTOM_SCRIPT_EXTENSION] = function (module, filename) { 54 | var content = fs.readFileSync(filename, 'utf8'); 55 | module._compile(content, filename); 56 | } 57 | var loaderFunction = function (module, filename) { 58 | return module._compile(fs.readFileSync(path.join(__dirname,"cli.js"), 'utf8'), filename); 59 | }; 60 | require.extensions[".json"] = loaderFunction // loader for package.json 61 | require.extensions[constants.DEFAULT_SCRIPT_EXTENSION] = loaderFunction 62 | 63 | /* 64 | * Fire.js Ignitable Modules are absolutely in love with this function. 65 | */ 66 | module.exports.igniteModule = function(thirdPartyModule, thirdPartyRequire) { 67 | if(!thirdPartyModule || (typeof(thirdPartyModule) !== 'object')) { 68 | throw "thirdPartyModule object is required" 69 | } 70 | if(!thirdPartyRequire || (typeof(thirdPartyRequire) !== 'function')) { 71 | throw "thirdPartyRequire function is required" 72 | } 73 | return new ModuleInitializer(thirdPartyModule, thirdPartyRequire) 74 | } 75 | 76 | module.exports.inferExpressionNameByFileName = function(fileName) { 77 | if(!fileName) return null 78 | for(var i = 0; i < constants.DEFAULT_EXPRESSION_EXTENSIONS.length; i++) { 79 | var extension = constants.DEFAULT_EXPRESSION_EXTENSIONS[i] 80 | if(fileName.indexOf(extension) != -1) { 81 | return fileName.substring(0, fileName.indexOf(extension)) 82 | } 83 | } 84 | return null 85 | } 86 | 87 | /* 88 | * Boostrap a Fire.js Runtime into the current process using the given arguments. 89 | */ 90 | var nopt = require('nopt') 91 | module.exports.executeApplication = function(argv) { 92 | process.parsedArgv = nopt({ 93 | "print-expressions" : Boolean, 94 | "porcelain-errors" : Boolean, 95 | "print-manifest": Boolean 96 | }, 97 | { 98 | "pe": ["--print-expressions", true], 99 | "pm": ["--print-manifest", true] 100 | },argv, 0) 101 | var noArgs = process.parsedArgv.argv.remain.length == 0 102 | if(noArgs) { 103 | printHelp() 104 | process.exit(0); 105 | } else { 106 | var initialFileName = process.parsedArgv.argv.remain.shift() 107 | process.parsedArgv.argv.cooked.splice(process.parsedArgv.argv.cooked.indexOf(initialFileName), 1) 108 | var initialFileName = path.resolve(initialFileName) 109 | require(initialFileName)() // run the cli... check cli.js for more info. 110 | } 111 | 112 | function printHelp() { 113 | console.log("Fire.JS Runtime version " + module.exports.PackageInfo.version) 114 | console.log("usage: firejs TheProject.Main.fjson") 115 | console.log("usage: firejs package.json") 116 | console.log("options:") 117 | console.log(" --print-expressions: prints all the expression names and flags loaded by the runtime as a JSON document to stdout") 118 | console.log(" --porcelain-errors: prints errors to stderr in JSON format") 119 | console.log(" --print-manifest: prints the merged manifest as a JSON document to stdout") 120 | console.log("") 121 | console.log("Copyright (C) 2011 Firebase.co and Contributors. http://firejs.firebase.co") 122 | } 123 | } 124 | 125 | /* 126 | * Export the package information right from the package.json file. 127 | */ 128 | module.exports.PackageInfo = JSON.parse(fs.readFileSync(path.join(__dirname,"../package.json"), 'utf8')) 129 | -------------------------------------------------------------------------------- /src/mergeWith.js: -------------------------------------------------------------------------------- 1 | function mergeWith(original, override) { 2 | if(typeof(original) == 'object' && (original instanceof Array)) { 3 | // Array 4 | for(var i in override) { 5 | var overrideVal = override[i] 6 | if(original.indexOf(overrideVal) == -1) { 7 | original.push(overrideVal) 8 | } 9 | } 10 | return original 11 | } else if(typeof(original) == 'object' && !(original instanceof Array)) { 12 | // Object 13 | if(override && original) { 14 | Object.keys(override).forEach(function(overrideKey) { 15 | if(!original[overrideKey]) { 16 | original[overrideKey] = override[overrideKey] 17 | } else { 18 | original[overrideKey] = mergeWith(original[overrideKey], override[overrideKey]) 19 | } 20 | }) 21 | } else if(!original) { 22 | return override 23 | } 24 | return original 25 | } 26 | return override 27 | } 28 | module.exports = mergeWith 29 | -------------------------------------------------------------------------------- /test/commandLineDirs/appNameFromExpression/AppNameFromMainExpression.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AppNameFromMainExpression.Main", 3 | "json": { 4 | "@ReturnAppName": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/appNameFromExpression/AppNameFromOtherName.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AppNameFromOtherName", 3 | "json": { 4 | "@ReturnAppName": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/appNameFromExpression/ReturnAppName.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | function ReturnAppName(){}; 3 | ReturnAppName.prototype = new fire.Expression(); 4 | ReturnAppName.prototype.execute = function() { 5 | this.end(this.runtime.applicationName) 6 | } 7 | 8 | module.exports.name = "ReturnAppName" 9 | module.exports.implementation = ReturnAppName -------------------------------------------------------------------------------- /test/commandLineDirs/appNameFromPackage/AppNameFromPackage.Main.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | function AppNameFromPackage(){}; 3 | AppNameFromPackage.prototype = new fire.Expression(); 4 | AppNameFromPackage.prototype.execute = function() { 5 | this.end(this.runtime.applicationName) 6 | } 7 | 8 | module.exports.name = "AppNameFromPackage.Main" 9 | module.exports.implementation = AppNameFromPackage -------------------------------------------------------------------------------- /test/commandLineDirs/appNameFromPackage/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "AppNameFromPackage" 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/DeferredTest.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DeferredTest.Main", 3 | "json": { 4 | "@SubSub": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["sub"] 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../../index.js') -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/node_modules/sub/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["subsub"] 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/node_modules/sub/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | fire.igniteModule(module, require) -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/node_modules/sub/node_modules/SubSub.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SubSub", 3 | "json": "From Sub Sub" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/node_modules/sub/node_modules/subsub.js: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | fire.igniteModule(module, require) -------------------------------------------------------------------------------- /test/commandLineDirs/deferredSubModuleLoading/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DeferredTest" 3 | } 4 | -------------------------------------------------------------------------------- /test/commandLineDirs/expressionsList/MyApp.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MyApp.Main", 3 | "json": null 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/failingInitializer/failingInitializer.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "failingInitializer.Main", 3 | "json": { 4 | 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/failingInitializer/initializers/development/failingInitializer.Init.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "failingInitializer.Init", 3 | "json": { 4 | "@raiseError": "Can not find the right configuration" 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/invalidMainPackageJson/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "SuperApp", 3 | "verison": "1.0.0" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/ReturnInitializedValues.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function ReturnInitializedValues(){} 4 | ReturnInitializedValues.prototype = new fire.Expression() 5 | ReturnInitializedValues.prototype.execute = function() { 6 | this.end({ 7 | moduleInitValue: this.runtime._moduleInitValue, 8 | moduleInitExpValue: this.runtime._moduleInitExpValue, 9 | appInitValue: this.runtime._appInitValue 10 | }) 11 | } 12 | module.exports = { 13 | "name": "ReturnInitializedValues", 14 | "implementation": ReturnInitializedValues 15 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["mod1"] 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/initializers/development/appInitExpInit.App.init.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function appInitExpInitAppInit(){} 4 | appInitExpInitAppInit.prototype = new fire.Expression() 5 | appInitExpInitAppInit.prototype.execute = function() { 6 | this.runtime._appInitValue = "App Initializer Expression" 7 | this.finish() 8 | } 9 | module.exports = { 10 | "name": "appInitExpInitAppInit", 11 | "implementation": appInitExpInitAppInit 12 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/moduleInitExpInit.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moduleInitExpInit.Main", 3 | "json": { 4 | "@ReturnInitializedValues": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../../index.js') -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/node_modules/mod1/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | var igniter = fire.igniteModule(module, require) 3 | igniter.initializer = function(runtime, next) { 4 | runtime._moduleInitValue = "Module Initializer" 5 | next() 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/node_modules/mod1/initializers/development/moduleInitExpInit.App.init.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function moduleInitExpInitAppInit(){} 4 | moduleInitExpInitAppInit.prototype = new fire.Expression() 5 | moduleInitExpInitAppInit.prototype.execute = function() { 6 | this.runtime._moduleInitExpValue = "Module Expression Initializer" 7 | this.finish() 8 | } 9 | module.exports = { 10 | "name": "moduleInitExpInitAppInit", 11 | "implementation": moduleInitExpInitAppInit 12 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitExpInit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moduleInitExpInit" 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitializers/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["someInitModule"] 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitializers/moduleInitializers.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moduleInitializers.Main", 3 | "json": { 4 | 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitializers/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../../index.js') -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitializers/node_modules/someInitModule/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function moduleInitializersLog() { 4 | 5 | } 6 | moduleInitializersLog.prototype = new fire.Expression() 7 | moduleInitializersLog.prototype.execute = function() { 8 | var self = this 9 | this.runInput(function(res) { 10 | console.log(res) 11 | }) 12 | } 13 | 14 | fire.igniteModule(module, require).exportExpression({ 15 | "name": "moduleInitializers.Log", 16 | "implementation": moduleInitializersLog 17 | }) -------------------------------------------------------------------------------- /test/commandLineDirs/moduleInitializers/node_modules/someInitModule/initializers/development/someInitModule.Init.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "someInitModule", 3 | "json": { 4 | "@moduleInitializers.Log": "Initialized from Module in Dev Mode" 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["superModule1"] 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/moduleScriptDirs.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "moduleScriptDirs.Main", 3 | "json": { 4 | "superExpression1": { 5 | "@superExpression1": null 6 | }, 7 | "superExpression2": { 8 | "@superExpression2": null 9 | }, 10 | "superExpression3": { 11 | "@superExpression3": null 12 | }, 13 | "superExpression4": { 14 | "@superExpression4": null 15 | }, 16 | "superExpression5": { 17 | "@superExpression5": null 18 | }, 19 | "superExpression1b": { 20 | "@superExpression1b": null 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../../index.js') -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/auxManifestDir/superExpression3.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "superExpression3", 3 | "json": "This expression was loaded from an aux directori exported using the module manifest" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/auxManifestDir/superExpression4.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function superExpression4() { 4 | 5 | } 6 | superExpression4.prototype = new fire.Expression() 7 | superExpression4.prototype.execute = function() { 8 | this.end("This expression was loaded from a custom javascrip file in a manifest script dir") 9 | } 10 | 11 | module.exports = { 12 | name: "superExpression4", 13 | implementation: superExpression4 14 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/auxModDir/superExpression2.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "superExpression2", 3 | "json": "This expression was loaded from an aux directori exported using exportScriptsDir" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/auxModDir/superExpression5.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function superExpression5() { 4 | 5 | } 6 | superExpression5.prototype = new fire.Expression() 7 | superExpression5.prototype.execute = function() { 8 | this.end("This custom expression was loaded from a module explicit subdir") 9 | } 10 | 11 | module.exports = { 12 | name: "superExpression5", 13 | implementation: superExpression5 14 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "scriptDirectories": [ 3 | "auxManifestDir" 4 | ] 5 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | fire.igniteModule(module, require).exportScriptsDir("auxModDir") -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/superExpression1.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "superExpression1", 3 | "json": "Something from Super Expression One" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/moduleScriptDirs/node_modules/superModule1/superExpression1b.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function superExpression1b() { 4 | 5 | } 6 | superExpression1b.prototype = new fire.Expression() 7 | superExpression1b.prototype.execute = function() { 8 | this.end("This custom expression was loaded from the root of the app") 9 | } 10 | 11 | module.exports = { 12 | name: "superExpression1b", 13 | implementation: superExpression1b 14 | } -------------------------------------------------------------------------------- /test/commandLineDirs/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../index.js') -------------------------------------------------------------------------------- /test/commandLineDirs/packageJson/PackageExample.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PackageExample.Main", 3 | "json": "Hello from a package.json launched app" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/packageJson/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PackageExample", 3 | "version": "1.0.0" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/parsedArgv/Parsed.Argv.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function ParsedMain() { 4 | 5 | } 6 | ParsedMain.prototype = new fire.Expression() 7 | ParsedMain.prototype.execute = function() { 8 | this.end(process.parsedArgv.argv.cooked) 9 | } 10 | module.exports = { 11 | name: "Parsed.Argv", 12 | implementation: ParsedMain 13 | } -------------------------------------------------------------------------------- /test/commandLineDirs/parsedArgv/Parsed.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Parsed.Main", 3 | "json": { 4 | "@Parsed.Argv": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/printManifest/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifestProperty": "Manifest Value" 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/printManifest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name":"printManifest" 3 | } -------------------------------------------------------------------------------- /test/commandLineDirs/simple/mySimpleMain.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "mySimpleMain", 3 | "json" : { 4 | "@return": "Hello World from the Simplest JSON Expression" 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withManifest2/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": [ 3 | "testFourModule" 4 | ], 5 | "environments": { 6 | "development": { 7 | "testFourModule": { 8 | "fourIs": "The Chuck Norris Four" 9 | } 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withManifest2/myMain.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "myMain", 3 | "json" : { 4 | "@testFourModule.doSomething": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withManifest2/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../../index.js') -------------------------------------------------------------------------------- /test/commandLineDirs/withManifest2/node_modules/testFourModule/index.js: -------------------------------------------------------------------------------- 1 | var fire = require("fire") 2 | var Expression = fire.Expression 3 | function doSomethingExpression() { 4 | 5 | } 6 | doSomethingExpression.prototype = new Expression() 7 | doSomethingExpression.prototype.execute = function() { 8 | var config = this.runtime.getModuleConfiguration("testFourModule") 9 | this.end(config.fourIs) 10 | } 11 | var fireModule = fire.igniteModule(module, require) 12 | fireModule.exportExpression({ 13 | name: "testFourModule.doSomething", 14 | implementation: doSomethingExpression 15 | }) -------------------------------------------------------------------------------- /test/commandLineDirs/withManifest2/node_modules/testFourModule/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "testFourModule", 3 | "main" : "./index.js" 4 | } 5 | -------------------------------------------------------------------------------- /test/commandLineDirs/withRootLevelFiles/myMain.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "myMain", 3 | "json" : { 4 | "@myOtherExpression": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withRootLevelFiles/myOtherExpression.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myOtherExpression", 3 | "json": "Value from the Other Expression" 4 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withSubScripts/customExpression.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function customExpression() { 4 | 5 | } 6 | customExpression.prototype = new fire.Expression() 7 | customExpression.prototype.execute = function() { 8 | this.end("customExpression") 9 | } 10 | 11 | module.exports = { 12 | name: "customExpression", 13 | implementation: customExpression 14 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withSubScripts/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "scriptDirectories": [ 3 | "otherExpressions" 4 | ] 5 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withSubScripts/myMain.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "myMain", 3 | "json" : { 4 | "subExp": { 5 | "@myOtherExpression": null 6 | }, 7 | "customSubExp": { 8 | "@customSubExpression": null 9 | }, 10 | "customExp": { 11 | "@customExpression": null 12 | } 13 | } 14 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withSubScripts/myOtherExpression.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "myOtherExpression", 3 | "json": { 4 | "@subExpression": null 5 | } 6 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withSubScripts/otherExpressions/customSubExpression.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function customSubExpression() { 4 | 5 | } 6 | customSubExpression.prototype = new fire.Expression() 7 | customSubExpression.prototype.execute = function() { 8 | this.end("customSubExpression") 9 | } 10 | 11 | module.exports = { 12 | name: "customSubExpression", 13 | implementation: customSubExpression 14 | } -------------------------------------------------------------------------------- /test/commandLineDirs/withSubScripts/otherExpressions/subExpression.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subExpression", 3 | "json": "Value from a Sub expression" 4 | } -------------------------------------------------------------------------------- /test/dependentModules/dependentModules.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dependentModules.Main", 3 | "json": { 4 | "@loadedExpression1": null, 5 | "@loadedExpression2": null 6 | } 7 | } -------------------------------------------------------------------------------- /test/dependentModules/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["loadedModule1"] 3 | } -------------------------------------------------------------------------------- /test/dependentModules/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../index.js') -------------------------------------------------------------------------------- /test/dependentModules/node_modules/loadedModule1/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["loadedModule2"], 3 | "environments": { 4 | "development": { 5 | "loadedModule2": "Expression Two Result" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /test/dependentModules/node_modules/loadedModule1/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('../../../../index.js') 2 | var Expression = fire.Expression 3 | 4 | 5 | 6 | function loadedExpression1() { 7 | 8 | } 9 | loadedExpression1.prototype = new Expression() 10 | loadedExpression1.prototype.execute = function() { 11 | this.end("Expression One Result") 12 | } 13 | 14 | var fireModule = fire.igniteModule(module, require) 15 | 16 | fireModule.exportExpression({ 17 | name: "loadedExpression1", 18 | implementation: loadedExpression1 19 | }) -------------------------------------------------------------------------------- /test/dependentModules/node_modules/loadedModule2/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('../../../../index.js') 2 | var Expression = fire.Expression 3 | 4 | function loadedExpression2() { 5 | 6 | } 7 | loadedExpression2.prototype = new Expression() 8 | loadedExpression2.prototype.execute = function() { 9 | var res = this.runtime.getModuleConfiguration("loadedModule2") 10 | this.end(res) 11 | } 12 | var fireModule = fire.igniteModule(module, require) 13 | fireModule.exportExpression({ 14 | name: "loadedExpression2", 15 | implementation: loadedExpression2 16 | }) -------------------------------------------------------------------------------- /test/expressions/testDoLoopControl.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../../src/Expressions").Expression 2 | function testDoLoopControl() { 3 | 4 | } 5 | testDoLoopControl.prototype = new Expression() 6 | testDoLoopControl.prototype.execute = function() { 7 | this.loopControl() 8 | } 9 | 10 | module.exports = { 11 | name: "testDoLoopControl", 12 | implementation: testDoLoopControl 13 | } -------------------------------------------------------------------------------- /test/expressions/testExecAtFirstTime.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../../src/Expressions").Expression 2 | function testExecAtFirstTime() { 3 | 4 | } 5 | testExecAtFirstTime.prototype = new Expression() 6 | testExecAtFirstTime.prototype.execute = function() { 7 | if(this.getParentVar("testExecAtSecondTimeCount") == undefined) { 8 | this.setParentVar("testExecAtSecondTimeCount", 0) 9 | this.bypass() 10 | } else if(this.getParentVar("testExecAtSecondTimeCount") == 1) { 11 | this.setParentVar("testExecAtSecondTimeCount", this.getParentVar("testExecAtSecondTimeCount") +1) 12 | var self = this 13 | this.runInput( function(res) { 14 | self.bypass() 15 | }) 16 | }else { 17 | this.setParentVar("testExecAtSecondTimeCount", this.getParentVar("testExecAtSecondTimeCount") +1) 18 | this.bypass() 19 | } 20 | } 21 | 22 | module.exports = { 23 | name: "testExecAtFirstTime", 24 | implementation: testExecAtFirstTime 25 | } -------------------------------------------------------------------------------- /test/expressions/testExecAtThirdTime.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../../src/Expressions").Expression 2 | function testExecAtThirdTime() { 3 | 4 | } 5 | testExecAtThirdTime.prototype = new Expression() 6 | testExecAtThirdTime.prototype.execute = function() { 7 | //console.warn("testExecAtThirdTime", this.getVar("testExecAtThirdTimeCount"), typeof(this.getVar("testExecAtThirdTimeCount"))) 8 | 9 | if(this.getParentVar("testExecAtThirdTimeCount") === undefined) { 10 | 11 | //console.warn("initializing testExecAtThirdTimeCount") 12 | this.setParentVar("testExecAtThirdTimeCount", 0) 13 | //console.warn("testExecAtThirdTimeCount:", this.getParentVar("testExecAtThirdTimeCount"), this.parent.vars) 14 | this.bypass() 15 | //return 16 | } else { 17 | if(this.getParentVar("testExecAtThirdTimeCount") < 2) { 18 | //console.warn("incrementing testExecAtThirdTimeCount", this.getParentVar("testExecAtThirdTimeCount")) 19 | this.setParentVar("testExecAtThirdTimeCount", this.getParentVar("testExecAtThirdTimeCount") +1) 20 | this.bypass() 21 | //return 22 | } else { 23 | //console.warn("executing testExecAtThirdTimeCount") 24 | var self = this 25 | this.runInput(function(res) { 26 | self.bypass() 27 | }) 28 | } 29 | } 30 | } 31 | 32 | module.exports = { 33 | name:"testExecAtThirdTime", 34 | implementation:testExecAtThirdTime 35 | } -------------------------------------------------------------------------------- /test/expressions/testExpThatRaisesError.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../../src/Expressions").Expression 2 | function testExpThatRaisesError() { 3 | 4 | } 5 | testExpThatRaisesError.prototype = new Expression() 6 | testExpThatRaisesError.prototype.execute = function() { 7 | this.raiseError("Help!!!... Chuck Norris is in da house!") 8 | } 9 | 10 | module.exports = { 11 | name:"testExpThatRaisesError", 12 | implementation:testExpThatRaisesError 13 | } -------------------------------------------------------------------------------- /test/expressions/testIncrementedName.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../../src/Expressions").Expression 2 | function testIncrementedName() { 3 | 4 | } 5 | testIncrementedName.prototype = new Expression() 6 | testIncrementedName.prototype.execute = function() { 7 | var varName = this.getHintValue()+ "var"; 8 | if(this.getParentVar(varName) == undefined) { 9 | this.setParentVar(varName, -1) 10 | } 11 | this.setParentVar(varName, this.getParentVar(varName) + 1) 12 | this.end(this.getHintValue() + this.getParentVar(varName)) 13 | } 14 | module.exports = { 15 | name:"testIncrementedName", 16 | flags: ["hint"], 17 | implementation:testIncrementedName 18 | } -------------------------------------------------------------------------------- /test/expressions/testReturnParentResult.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../../src/Expressions").Expression 2 | function testReturnParentResult() { 3 | 4 | } 5 | testReturnParentResult.prototype = new Expression() 6 | testReturnParentResult.prototype.execute = function() { 7 | this.bypass() 8 | } 9 | 10 | module.exports = { 11 | name:"testReturnParentResult", 12 | implementation:testReturnParentResult 13 | } -------------------------------------------------------------------------------- /test/expressions/tickedReturn.js: -------------------------------------------------------------------------------- 1 | var Expression = require("../../src/Expressions").Expression 2 | var objCount = 0 3 | function testTickedReturn() { 4 | objCount++ 5 | this.returnName = "return " + objCount 6 | } 7 | testTickedReturn.prototype = new Expression() 8 | testTickedReturn.prototype.execute = function() { 9 | //console.warn("executing testTickedReturn ", this.returnName) 10 | var self = this 11 | 12 | process.nextTick(function() { 13 | self.runInput( function(res) { 14 | process.nextTick(function() { 15 | var interval = 0 16 | //console.warn("testTickedReturn ", self.returnName, " will wait ", self.getHintValue()) 17 | interval = setInterval(function() { 18 | //console.warn("setting result for testTickedReturn ", self.returnName) 19 | self.end(res) 20 | clearInterval(interval) 21 | },parseInt(self.getHintValue())); 22 | }); 23 | }) 24 | }) 25 | } 26 | 27 | module.exports = { 28 | name:"testTickedReturn", 29 | flags: "hint", 30 | implementation:testTickedReturn 31 | } -------------------------------------------------------------------------------- /test/initializersTest/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["initializersTestLog"] 3 | } -------------------------------------------------------------------------------- /test/initializersTest/initializers/development/initializersTest.Dev.Init.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "initializersTest.Dev.Init", 3 | "json": { 4 | "@initializersTest.Log": "Init in Development Mode" 5 | } 6 | } -------------------------------------------------------------------------------- /test/initializersTest/initializers/test/initializersTest.Test.Init.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "initializersTest.Test.Init", 3 | "json": { 4 | "@initializersTest.Log": "Init in Testing Mode" 5 | } 6 | } -------------------------------------------------------------------------------- /test/initializersTest/initializersTest.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "initializersTest.Main", 3 | "json": { 4 | 5 | } 6 | } -------------------------------------------------------------------------------- /test/initializersTest/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../../index.js') -------------------------------------------------------------------------------- /test/initializersTest/node_modules/initializersTestLog.js: -------------------------------------------------------------------------------- 1 | var fire = require('fire') 2 | 3 | function initializersTestLog() { 4 | 5 | } 6 | initializersTestLog.prototype = new fire.Expression() 7 | initializersTestLog.prototype.execute = function() { 8 | var self = this 9 | this.runInput(function(res) { 10 | console.log(res) 11 | }) 12 | } 13 | 14 | fire.igniteModule(module, require).exportExpression({ 15 | "name": "initializersTest.Log", 16 | "implementation": initializersTestLog 17 | }) -------------------------------------------------------------------------------- /test/loadedModules/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": ["loadedModule1", "loadedModule2"] 3 | } -------------------------------------------------------------------------------- /test/loadedModules/node_modules/loadedModule1/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('../../../../index.js') 2 | var Expression = fire.Expression 3 | 4 | function loadedExpression1() { 5 | 6 | } 7 | loadedExpression1.prototype = new Expression() 8 | loadedExpression1.prototype.execute = function() { 9 | this.end("Loaded Expression One Result") 10 | } 11 | module.exports.superName = "Super Module One" 12 | 13 | var fireModule = fire.igniteModule(module, require) 14 | 15 | fireModule.exportExpression({ 16 | name: "loadedExpression1", 17 | implementation: loadedExpression1 18 | }) -------------------------------------------------------------------------------- /test/loadedModules/node_modules/loadedModule2/index.js: -------------------------------------------------------------------------------- 1 | var fire = require('../../../../index.js') 2 | var Expression = fire.Expression 3 | 4 | function loadedExpression2() { 5 | 6 | } 7 | loadedExpression2.prototype = new Expression() 8 | loadedExpression2.prototype.execute = function() { 9 | this.end("Loaded Expression Two Result") 10 | } 11 | module.exports.superName = "Super Module Two" 12 | var fireModule = fire.igniteModule(module, require) 13 | 14 | fireModule.exportExpression({ 15 | name: "loadedExpression2", 16 | implementation: loadedExpression2 17 | }) -------------------------------------------------------------------------------- /test/loadedModules/runtimeLoader.testjs: -------------------------------------------------------------------------------- 1 | //Since Node.js 0.5 doesn't support require.paths, this file can be be used to load the runtime in tests where the the module or ignition files loading precision is sensitive to current directory. 2 | module.exports = function(Runtime, baseDir) { 3 | var runtime = new Runtime() 4 | runtime.setBaseDir(baseDir) 5 | runtime.moduleRequire = require 6 | return runtime 7 | } -------------------------------------------------------------------------------- /test/manifestTokens/testUnknownToken.json: -------------------------------------------------------------------------------- 1 | { 2 | "testUnknownToken": "{{UNKNOWN_STUFF|Too bad it can't be magic xD}}" 3 | } -------------------------------------------------------------------------------- /test/manifestTokens/testUnknownWithNoDefault.json: -------------------------------------------------------------------------------- 1 | { 2 | "testUnknownWithNoDefault": "This {{Thing}} can not be found" 3 | } -------------------------------------------------------------------------------- /test/manifestTokens/withDepth.json: -------------------------------------------------------------------------------- 1 | { 2 | "firstLevel": "{{SimpleUnknownKey|SimpleUnknownDefaultValue}}", 3 | "secondLevel": { 4 | "anotherKey": "{{AnotherUnknownKey|AnotherUnknownDefaultValue}}", 5 | "thirdLevel": [ 6 | "{{ArrayUnknownKey|ArrayUnknownDefaultValue}}" 7 | ] 8 | } 9 | } -------------------------------------------------------------------------------- /test/manifestTokens/withFireAppName.json: -------------------------------------------------------------------------------- 1 | { 2 | "testFireAppName": "{{FIRE_APP_NAME|YOU_KIDDING_ME}} is the current Application" 3 | } -------------------------------------------------------------------------------- /test/manifestTokens/withFireAppPid.json: -------------------------------------------------------------------------------- 1 | { 2 | "withFireAppPid": "Running on {{FIRE_APP_PID|0}}" 3 | } -------------------------------------------------------------------------------- /test/manifestTokens/withFireBase.json: -------------------------------------------------------------------------------- 1 | { 2 | "withFireBase": "Running on {{FIRE_BASE}}" 3 | } 4 | -------------------------------------------------------------------------------- /test/manifestTokens/withFireEnvName.json: -------------------------------------------------------------------------------- 1 | { 2 | "testFireEnvName": "{{FIRE_ENV_NAME|}} is the current environment name" 3 | } -------------------------------------------------------------------------------- /test/manifestTokens/withProcessEnv.json: -------------------------------------------------------------------------------- 1 | { 2 | "withProcessEnv": "{{SOME_TEST_KEY|}}" 3 | } -------------------------------------------------------------------------------- /test/manifests/testConfig/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": [ 3 | "module1" 4 | ], 5 | "environments": { 6 | "all": { 7 | "module1": { 8 | "server": "soome default value", 9 | "configFromAll": 10 10 | } 11 | }, 12 | "customEnv1": { 13 | "module1": { 14 | "server": "127.0.0.1", 15 | "fromCustom": 100 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/manifests/testConfig/node_modules/module1/main.js: -------------------------------------------------------------------------------- 1 | var fire = require("../../../../../index.js") 2 | var Expression = fire.Expression 3 | function module1() { 4 | 5 | } 6 | module1.prototype = new Expression() 7 | module1.prototype.execute = function() { 8 | var config = this._blockContext._runtime.getModuleConfiguration("module1") 9 | this._blockContext._resultCallback({ 10 | "config": config, 11 | "environmentName": this._blockContext._runtime.environmentName 12 | }); 13 | } 14 | 15 | var fireModule = fire.igniteModule(module, require) 16 | fireModule.exportExpression({ 17 | name: "module1", 18 | implementation: module1 19 | }) 20 | -------------------------------------------------------------------------------- /test/manifests/testConfig/node_modules/module1/package.json: -------------------------------------------------------------------------------- 1 | { "name" : "module1", 2 | "main" : "./main.js" } -------------------------------------------------------------------------------- /test/manifests/testConfig/runtimeLoader.testjs: -------------------------------------------------------------------------------- 1 | //Since Node.js 0.5 doesn't support require.paths, this file can be be used to load the runtime in tests where the the module or ignition files loading precision is sensitive to current directory. 2 | module.exports = function(Runtime, baseDir) { 3 | var runtime = new Runtime() 4 | runtime.setBaseDir(baseDir) 5 | runtime.moduleRequire = require 6 | return runtime 7 | } -------------------------------------------------------------------------------- /test/manifests/testConfigMissing/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": [ 3 | "module1" 4 | ], 5 | "environments": { 6 | "customEnv1": { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /test/manifests/testConfigMissing/node_modules/module1/main.js: -------------------------------------------------------------------------------- 1 | var fire = require("../../../../../index.js") 2 | var Expression = fire.Expression 3 | function module1() { 4 | 5 | } 6 | module1.prototype = new Expression() 7 | module1.prototype.execute = function() { 8 | var config = this._blockContext._runtime.getModuleConfiguration("module1") 9 | this._blockContext._resultCallback("Hello World with configurations, server configuration host is " + config.server + " is and the environment is " + this._blockContext._runtime.environmentName) 10 | } 11 | 12 | var fireModule = fire.igniteModule(module, require) 13 | fireModule.initializer = function(runtime, next) { 14 | if(!runtime.getModuleConfiguration('module1')){ 15 | next("database connection info is missing") 16 | } 17 | } 18 | 19 | fireModule.exportExpressions([ 20 | { 21 | name: "module1", 22 | implementation: module1 23 | }]) -------------------------------------------------------------------------------- /test/manifests/testConfigMissing/node_modules/module1/package.json: -------------------------------------------------------------------------------- 1 | { "name" : "module1", 2 | "main" : "./main.js" } -------------------------------------------------------------------------------- /test/manifests/testConfigMissing/runtimeLoader.testjs: -------------------------------------------------------------------------------- 1 | //Since Node.js 0.5 doesn't support require.paths, this file can be be used to load the runtime in tests where the the module or ignition files loading precision is sensitive to current directory. 2 | module.exports = function(Runtime, baseDir) { 3 | var runtime = new Runtime() 4 | runtime.setBaseDir(baseDir) 5 | runtime.moduleRequire = require 6 | return runtime 7 | } -------------------------------------------------------------------------------- /test/manifests/testConfigMissing/testConfigMissing.Main.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "testConfigMissing.Main", 3 | "json": null 4 | } -------------------------------------------------------------------------------- /test/manifests/testModules/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "modules": [ 3 | "expressionModule1", 4 | "expressionModule2" 5 | ] 6 | } -------------------------------------------------------------------------------- /test/manifests/testModules/node_modules/expressionModule1/main.js: -------------------------------------------------------------------------------- 1 | var fire = require("../../../../../index.js") 2 | var Expression = fire.Expression 3 | function expressionModule1() { 4 | 5 | } 6 | expressionModule1.prototype = new Expression() 7 | expressionModule1.prototype.execute = function() { 8 | this._blockContext._resultCallback("Hello World expressionModule1") 9 | } 10 | var fireModule = fire.igniteModule(module, require) 11 | fireModule.exportExpression({ 12 | name: "expressionModule1", 13 | implementation: expressionModule1 14 | }) -------------------------------------------------------------------------------- /test/manifests/testModules/node_modules/expressionModule1/package.json: -------------------------------------------------------------------------------- 1 | { "name" : "expressionModule1", 2 | "main" : "./main.js" } -------------------------------------------------------------------------------- /test/manifests/testModules/node_modules/expressionModule2/main.js: -------------------------------------------------------------------------------- 1 | var fire = require("../../../../../index.js") 2 | var Expression = fire.Expression 3 | function expressionModule2() { 4 | 5 | } 6 | expressionModule2.prototype = new Expression() 7 | expressionModule2.prototype.execute = function() { 8 | this._blockContext._resultCallback("Hello World expressionModule2") 9 | } 10 | 11 | var fireModule = fire.igniteModule(module, require) 12 | fireModule.exportExpression({ 13 | name: "expressionModule2", 14 | implementation: expressionModule2 15 | }) -------------------------------------------------------------------------------- /test/manifests/testModules/node_modules/expressionModule2/package.json: -------------------------------------------------------------------------------- 1 | { "name" : "expressionModule2", 2 | "main" : "./main.js" } -------------------------------------------------------------------------------- /test/manifests/testModules/runtimeLoader.testjs: -------------------------------------------------------------------------------- 1 | //Since Node.js 0.5 doesn't support require.paths, this file can be be used to load the runtime in tests where the the module or ignition files loading precision is sensitive to current directory. 2 | module.exports = function(Runtime, baseDir) { 3 | var runtime = new Runtime() 4 | runtime.setBaseDir(baseDir) 5 | runtime.moduleRequire = require 6 | return runtime 7 | } -------------------------------------------------------------------------------- /test/node_modules/fire.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../index.js') -------------------------------------------------------------------------------- /test/onLoadTest/ignition.manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /test/runtimeExtensions.js: -------------------------------------------------------------------------------- 1 | var fire = require('../src/core.js') 2 | var Runtime = fire.Runtime 3 | var Expression = fire.Expression 4 | var Ast = require('../src/Ast.js') 5 | function blockContextHasHint(blockContext) { 6 | return blockContext && blockContext._hint 7 | } 8 | function _testOnly_runJSONObjectFromJSON(jsonBlock, variables, inputCallback, loopCallback, resultCallback, outputFileName, hint, errorCallback, additionalExpressionsFiles) { 9 | if(errorCallback === undefined) { 10 | errorCallback = function(errInfo) { 11 | console.warn("_testOnly_runJSONObjectFromJSON default errorCallback just catched an error:", errInfo) 12 | } 13 | } 14 | if(hint === undefined) { 15 | hint = undefined 16 | } 17 | //var baseFunc = compileExpressionFuncFromJSON(jsonBlock, outputFileName === undefined? "test-in-memory.js" : outputFileName, outputFileName, hint) 18 | var runtime = new Runtime() 19 | runtime.registerWellKnownExpressionDefinition({ 20 | name: "_testOnly_runJSONObjectFromJSON", 21 | json: jsonBlock 22 | }) 23 | if(additionalExpressionsFiles !== undefined && additionalExpressionsFiles !== null) { 24 | additionalExpressionsFiles.forEach(function(fileName) { 25 | runtime.registerWellKnownExpressionFile(fileName) 26 | }) 27 | } 28 | var variablesObjects = {} 29 | for(var k in variables) { 30 | setVarCore(runtime, variablesObjects, k, variables[k]) 31 | } 32 | var contextBase = {} 33 | contextBase._resultCallback = resultCallback 34 | contextBase._loopCallback = loopCallback 35 | contextBase._inputExpression = inputCallback 36 | contextBase._variables = variablesObjects 37 | contextBase._hint = hint 38 | contextBase._errorCallback = errorCallback 39 | /* 40 | var contextBase = { 41 | _resultCallback: resultCallback, 42 | _loopCallback: loopCallback, 43 | _inputExpression: inputCallback, 44 | //_parentVariables: variables, 45 | _variables:variablesObjects, 46 | _hint: hint, 47 | _errorCallback: errorCallback 48 | }; 49 | */ 50 | runtime.load(function(initErr) { 51 | if(initErr) { 52 | //console.trace() 53 | contextBase._errorCallback("_testOnly_runJSONObjectFromJSON runtime init error:" + initErr) 54 | } 55 | runtime._testOnly_runExpressionByName("_testOnly_runJSONObjectFromJSON", contextBase, null) 56 | }) 57 | } 58 | 59 | 60 | Runtime.prototype._testOnly_runExpressionInstance = function(expressionInstance, block_context_base, context_block_overrides) { 61 | //console.warn("block_context_base",block_context_base) 62 | //console.warn("context_block_overrides",context_block_overrides) 63 | /*if(expFunc === undefined || expFunc == null || typeof(expFunc) != 'function') { 64 | throwInternalError("expFunc is required and must be a function") 65 | }*/ 66 | if(expressionInstance === undefined || expressionInstance == null || !(expressionInstance instanceof Expression)) { 67 | throwInternalError("expressionInstance is required to be an instance or derived from Expression") 68 | } 69 | if(block_context_base === undefined || typeof(block_context_base) != 'object' || block_context_base == null) { 70 | throwInternalError("block_context_base is required and must be an non-null object") 71 | } 72 | if(context_block_overrides === undefined) { 73 | throwInternalError("context_block_overrides must be an object or null") 74 | } 75 | if(block_context_base._loopCallback === undefined || block_context_base._loopCallback === null || typeof(block_context_base._loopCallback) != 'function') { 76 | throwInternalError("block_context_base._loopCallback must be a function") 77 | } 78 | if(block_context_base._inputExpression === undefined || block_context_base._inputExpression === null || typeof(block_context_base._inputExpression) != 'function') { 79 | throwInternalError("block_context_base._inputExpression must be a function") 80 | } 81 | if(block_context_base._variables === undefined || block_context_base._variables === null || typeof(block_context_base._variables) != 'object') { 82 | throwInternalError("block_context_base._variables must be an object") 83 | } 84 | //console.warn("runExpressionFunc validation passed") 85 | /* 86 | // block_context_base members structure 87 | { 88 | _resultCallback: , 89 | _loopCallback: , 90 | _inputExpression: , // needs to be called with runExp 91 | _variables: , 92 | //_parentVariables: , 93 | _hint: (optional), 94 | _errorCallback: , 95 | _parentResult: , // Caller Expression Block last Result 96 | _result: 97 | _parentContext: 98 | } 99 | */ 100 | 101 | 102 | var _blockContext = {}; 103 | Object.keys(block_context_base).forEach(function(k) { 104 | _blockContext[k] = block_context_base[k] 105 | }) 106 | 107 | var localVariables = null; 108 | var useSameScopeVariables = context_block_overrides == null || context_block_overrides._sameScope !== true 109 | if(useSameScopeVariables) { 110 | // 111 | // If it's not running on the same scope, then copy all the variables. 112 | // 113 | localVariables = {}//Object.create(block_context_base._variables) //block_context_base._variables; 114 | //console.warn("Copying Variables") 115 | if(block_context_base._variables != undefined && block_context_base._variables != null) { 116 | Object.keys(block_context_base._variables).forEach(function(k) { 117 | //console.warn("Copying var ", k, " with value ", block_context_base._variables[k]) 118 | localVariables[k] = block_context_base._variables[k] 119 | }) 120 | } 121 | } else { 122 | // Use the same Scope Varaibles 123 | localVariables = block_context_base._variables 124 | } 125 | 126 | _blockContext._hint = undefined; //formality 127 | if(context_block_overrides != null) { 128 | for(var k in context_block_overrides) { 129 | if(k == "_runtime" || k == "_parentVariables" || k == "_variables" || k == "_result" || k == "_parentContext" || k == "_errorInfo") continue; // can't replace these 130 | _blockContext[k] = context_block_overrides[k] 131 | } 132 | } 133 | 134 | 135 | _blockContext._variables = localVariables; 136 | _blockContext._runtime = this; 137 | _blockContext._result = undefined; //formality 138 | _blockContext._parentResult = block_context_base._result 139 | _blockContext._parentContext = block_context_base 140 | _blockContext._rootExpression = undefined // _rootScope can not be inherited. 141 | 142 | // The override key '_initialResult' can set the initial value of the calling expression block. 143 | if(context_block_overrides && context_block_overrides._initialResult != null && context_block_overrides._initialResult != undefined) { 144 | _blockContext._result = context_block_overrides._initialResult 145 | } 146 | 147 | expressionInstance._blockContext = _blockContext 148 | expressionInstance.ensureInitialized() 149 | // new Expressions model 150 | var localVarsKeys = Object.keys(localVariables) 151 | for(var i = 0; i < localVarsKeys.length; i++) { 152 | expressionInstance.vars[localVarsKeys[i]] = localVariables[localVarsKeys[i]] 153 | } 154 | expressionInstance.resultCallback = _blockContext._resultCallback; 155 | expressionInstance.errorCallback = _blockContext._errorCallback; 156 | expressionInstance.loopCallback = _blockContext._loopCallback; 157 | expressionInstance.createInputExpression = function() { 158 | var exp = new Expression() 159 | exp.execute = function() { 160 | var self = this 161 | var pseudoExp = { 162 | setResult: function(res) { 163 | self.end(res) 164 | }, 165 | execute: _blockContext._inputExpression 166 | } 167 | pseudoExp.execute() 168 | } 169 | return exp 170 | } 171 | expressionInstance.runtime = this 172 | expressionInstance.hint = _blockContext._hint 173 | expressionInstance.run() // run it 174 | }; 175 | 176 | 177 | Runtime.prototype._testOnly_runExpressionByName = function(expressionName, base_context, context_overrides) { 178 | //console.warn("Calling expression with name ", expressionName, " context_overrides ", context_overrides) 179 | var expDefinition = this.loadedExpressionsMeta[expressionName] 180 | if(expDefinition == undefined) { 181 | throw "Expression '" + expressionName + "' is not registered or was not loaded."; 182 | } 183 | 184 | var supportHints = expDefinition.flags && expDefinition.flags.indexOf("hint") != -1 185 | if(!supportHints && blockContextHasHint(context_overrides)) { 186 | throw new Error('UnsupportedHint', "Expression '" + expressionName + "' does not support hints") 187 | } 188 | var expObject = expDefinition.implementation 189 | var expressionObject = new expObject() 190 | this._testOnly_runExpressionInstance(expressionObject, base_context, context_overrides) 191 | } 192 | 193 | 194 | TEST_PRINT_TRACE_ON_INTERNAL_ERROR = true 195 | fire._testOnly_getExpressionNameFromSpecialKey = Ast.getExpressionNameFromSpecialKey 196 | fire._testOnly_runJSONObject = _testOnly_runJSONObjectFromJSON 197 | fire._testOnly_getHint = Ast.getHintFromSpecialKey 198 | 199 | -------------------------------------------------------------------------------- /test/sourceUri/Bye.fjson: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Bye", 3 | "json": "Bye Bye" 4 | } -------------------------------------------------------------------------------- /test/sourceUri/Hello.js: -------------------------------------------------------------------------------- 1 | var fire = require('../../src/core.js') 2 | 3 | function Hello(){}; 4 | Hello.prototype = new fire.Expression() 5 | 6 | module.exports = { 7 | name:"Hello", 8 | implementation: Hello 9 | } -------------------------------------------------------------------------------- /test/sourceUri/Hi.fjs: -------------------------------------------------------------------------------- 1 | var fire = require('../../src/core.js') 2 | 3 | function Hi(){}; 4 | Hi.prototype = new fire.Expression() 5 | 6 | module.exports = { 7 | name:"Hi", 8 | implementation: Hi 9 | } -------------------------------------------------------------------------------- /test/test.Comparable.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | var assert = require('assert') 3 | var extractComparableValues = require('../src/Comparable').extractComparableValues 4 | 5 | vows.describe('firejs comparable values').addBatch({ 6 | "the comparable values of any array it's the array itself": function() { 7 | var comparables = extractComparableValues(['1','2']) 8 | assert.deepEqual(comparables, ['1','2']) 9 | }, 10 | "the comparables of null is an empty array": function() { 11 | var comparables = extractComparableValues(null) 12 | assert.deepEqual(comparables, []) 13 | } 14 | , 15 | "the comparable values of undefined is an empty arrayy": function() { 16 | var comparables = extractComparableValues() 17 | assert.deepEqual(comparables, []) 18 | }, 19 | "the comparable values of an empty object is an empty array": function() { 20 | var comparables = extractComparableValues({}) 21 | assert.deepEqual(comparables, []) 22 | }, 23 | "the comparables values of any object are all the values of the first-level keys": function() { 24 | var comparables = extractComparableValues({x:500,y:700}) 25 | assert.deepEqual(comparables, [500,700]) 26 | }, 27 | "the comparables of a non object value like a boolean is an empty array": function() { 28 | var comparables = extractComparableValues(true) 29 | assert.deepEqual(comparables, []) 30 | 31 | comparables = extractComparableValues(false) 32 | assert.deepEqual(comparables, []) 33 | }, 34 | "the comparables of a String are all the characters of the array": function() { 35 | var comparables = extractComparableValues("Word") 36 | assert.deepEqual(comparables, ['W','o','r','d']) 37 | } 38 | /* 39 | NOTE: If you add a new case, make sure you update the fire.js specification, section "Comparable Values" 40 | */ 41 | }).export(module); -------------------------------------------------------------------------------- /test/test.Iterator.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | var assert = require('assert') 3 | var Iterator = require('../src/Iterator') 4 | 5 | vows.describe('firejs Iterator').addBatch({ 6 | "When I have an Iterator created with an empty array": { 7 | topic: function() { 8 | return new Iterator([]) 9 | }, 10 | "the count should be zero": function(topic) { 11 | assert.equal(topic.count(), 0) 12 | }, 13 | "isLast should return true": function(topic) { 14 | assert.isTrue(topic.isLast()) 15 | } 16 | , 17 | "current should return undefined": function(topic) { 18 | assert.isUndefined(topic.current()) 19 | }, 20 | "the count should be -1": function(topic) { 21 | assert.equal(topic.index(), -1) 22 | }, 23 | }, 24 | "When I have an Iterator created with an array of one element": { 25 | topic: function() { 26 | return new Iterator(["First"]) 27 | }, 28 | "the count should be 1": function(topic) { 29 | assert.equal(topic.count(), 1) 30 | }, 31 | "the index should be -1": function(topic) { 32 | assert.equal(topic.index(), -1) 33 | }, 34 | "isLast should return false": function(topic) { 35 | assert.isFalse(topic.isLast()) 36 | }, 37 | "current should return undefined": function(topic) { 38 | assert.isUndefined(topic.current()) 39 | }, 40 | "and when I ask for the next item": { 41 | topic: function(topic) { 42 | return topic.next() 43 | }, 44 | "it should return true": function(result) { 45 | assert.isTrue(result) 46 | } 47 | }, 48 | "and when I ask for the next item": { 49 | topic: function(topic) { 50 | topic.next() 51 | return topic 52 | }, 53 | "the current element should be the first item": function(topic) { 54 | assert.equal(topic.current(), "First") 55 | } 56 | } 57 | }, 58 | "When I have an Iterator created with an array of two elements": { 59 | topic: function() { 60 | console.warn("Creatin Iterator instance with two elemtns") 61 | return new Iterator(["First","Second"]) 62 | }, 63 | "the count should be 2": function(topic) { 64 | assert.equal(topic.count(), 2) 65 | }, 66 | "isLast should return false": function(topic) { 67 | assert.isFalse(topic.isLast()) 68 | }, 69 | "current should return undefined": function(topic) { 70 | assert.isUndefined(topic.current()) 71 | }, 72 | "the index should be -1": function(topic) { 73 | assert.equal(topic.index(), -1) 74 | } 75 | } 76 | , 77 | "When I have an Iterator created with an array of two elements": { 78 | topic: function() { 79 | return new Iterator(["First","Second"]) 80 | }, 81 | "and when I ask for the next item one time": { 82 | topic: function(topic) { 83 | assert.isTrue(topic.next()) 84 | return topic 85 | }, 86 | "the index should be 0": function(topic) { 87 | assert.equal(topic.index(), 0) 88 | }, 89 | "the current element should be the first item": function(topic) { 90 | assert.equal(topic.current(), "First") 91 | } 92 | } 93 | }, 94 | "When I have an Iterator created with an array of two elements": { 95 | topic: function() { 96 | return new Iterator(["First","Second"]) 97 | }, 98 | "and when I ask for the next item two times": { 99 | topic: function(topic) { 100 | assert.isTrue(topic.next()) 101 | assert.isTrue(topic.next()) 102 | return topic 103 | }, 104 | "the current element should be the last item": function(topic) { 105 | assert.equal(topic.current(), "Second") 106 | } 107 | , 108 | "isLast should return true": function(topic) { 109 | assert.isTrue(topic.isLast()) 110 | } 111 | } 112 | } 113 | , 114 | "When I create an iterator with something is not an array": { 115 | "I should get an error": { 116 | "with no arguments": function() { 117 | assert.throws(function() { 118 | new Iterator() 119 | }) 120 | }, 121 | "with null": function() { 122 | assert.throws(function() { 123 | new Iterator(null) 124 | }) 125 | }, 126 | "with number": function() { 127 | assert.throws(function() { 128 | new Iterator(2) 129 | }) 130 | }, 131 | "with string": function() { 132 | assert.throws(function() { 133 | new Iterator("") 134 | }) 135 | } 136 | } 137 | } , 138 | "When I load the firejs.js module the Iterator type must be exported": function(){ 139 | var fireExports = require('../index') 140 | assert.isFunction(fireExports.Iterator) 141 | assert.equal(Iterator, fireExports.Iterator) 142 | } 143 | }).export(module); 144 | -------------------------------------------------------------------------------- /test/test.MergeWith.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | var assert = require('assert') 3 | 4 | var mergeWith = require('../src/mergeWith.js') 5 | 6 | vows.describe('firejs mergeWith').addBatch({ 7 | "When I merge an object with properties at first level": { 8 | "with another object no properties the original object should remain intact": function() { 9 | var expectedObject = { 10 | "x": 100, 11 | "y": 200 12 | }; 13 | var originalObject = { 14 | "x": 100, 15 | "y": 200 16 | }; 17 | var mergeObject = { 18 | 19 | }; 20 | mergeWith(originalObject, mergeObject); 21 | assert.deepEqual(originalObject, expectedObject); 22 | } 23 | ,"with another object with one additional properties the merged object should contain the additional property": function() { 24 | var expectedObject = { 25 | "x": 100, 26 | "y": 200, 27 | "z": 300 28 | }; 29 | var originalObject = { 30 | "x": 100, 31 | "y": 200 32 | }; 33 | var mergeObject = { 34 | "z": 300 35 | }; 36 | mergeWith(originalObject, mergeObject); 37 | assert.deepEqual(originalObject, expectedObject); 38 | } 39 | ,"with another object at second level the merged object should contain the new property with the nested object": function() { 40 | var expectedObject = { 41 | "x": 100, 42 | "y": 200, 43 | "info": { 44 | "id": "Favorite Point" 45 | } 46 | }; 47 | var originalObject = { 48 | "x": 100, 49 | "y": 200 50 | }; 51 | var mergeObject = { 52 | "info": { 53 | "id": "Favorite Point" 54 | } 55 | }; 56 | mergeWith(originalObject, mergeObject); 57 | assert.deepEqual(originalObject, expectedObject); 58 | } 59 | ,"with another object that at second level contains an array, the merged object should contain the array": function() { 60 | var expectedObject = { 61 | "x": 100, 62 | "y": 200, 63 | "info": { 64 | "id": "Favorite Point", 65 | "tags": ["starters", "mids"] 66 | } 67 | }; 68 | var originalObject = { 69 | "x": 100, 70 | "y": 200 71 | }; 72 | var mergeObject = { 73 | "info": { 74 | "id": "Favorite Point", 75 | "tags": ["starters", "mids"] 76 | } 77 | }; 78 | mergeWith(originalObject, mergeObject); 79 | assert.deepEqual(originalObject, expectedObject); 80 | } 81 | } 82 | ,"When I merge an object with array properties of simple values at first level": { 83 | "with another object with arrays of simple values for the same properties, the original object should have the merged arrays with no duplicated values": function() { 84 | var expectedObject = { 85 | "tags": ["tag1", "tag2", "tag3"] 86 | }; 87 | var originalObject = { 88 | "tags": ["tag1"] 89 | }; 90 | var mergeObject = { 91 | "tags": ["tag2", "tag3", "tag1"] 92 | }; 93 | mergeWith(originalObject, mergeObject); 94 | assert.deepEqual(originalObject, expectedObject); 95 | }, 96 | "with another object with arrays of complex values for the same properties, the original object should have the merged arrays with simple and complex values with no duplicated values": function() { 97 | var expectedObject = { 98 | "tags": ["tag1", { 99 | "name": "tech-news", 100 | "description": "all about news" 101 | }] 102 | }; 103 | var originalObject = { 104 | "tags": ["tag1"] 105 | }; 106 | var mergeObject = { 107 | "tags": [ 108 | "tag1", 109 | { 110 | "name": "tech-news", 111 | "description": "all about news" 112 | }] 113 | }; 114 | mergeWith(originalObject, mergeObject); 115 | assert.deepEqual(originalObject, expectedObject); 116 | } 117 | } 118 | ,"When I merge an object with array properties of complex objects and some missing properties at first level": { 119 | "with another object with arrays of complex objects for the same properties, the original object should have the merged properties and complemented properties": function() { 120 | var expectedObject = { 121 | "point1": { 122 | "x": 140 123 | }, 124 | "point2": { 125 | "x": 30, 126 | "y": 40 127 | } 128 | }; 129 | var originalObject = { 130 | "point1": { 131 | "x": 20 132 | }, 133 | "point2": null 134 | }; 135 | var mergeObject = { 136 | "point1": { 137 | "x": 140 138 | }, 139 | "point2": { 140 | "x": 30, 141 | "y": 40 142 | } 143 | }; 144 | mergeWith(originalObject, mergeObject); 145 | assert.deepEqual(originalObject, expectedObject); 146 | }, 147 | "with another object overriding non-object values": function() { 148 | var expectedObject = { 149 | "number": 3422, 150 | "string": "Some String", 151 | "boolean": false, 152 | "null": null 153 | }; 154 | var originalObject = { 155 | "number": null, 156 | "string": null, 157 | "boolean": null, 158 | "null": "Invalid null" 159 | }; 160 | var mergeObject = { 161 | "number": 3422, 162 | "string": "Some String", 163 | "boolean": false, 164 | "null": null 165 | }; 166 | mergeWith(originalObject, mergeObject); 167 | assert.deepEqual(originalObject, expectedObject); 168 | } 169 | 170 | } 171 | 172 | }).export(module); 173 | -------------------------------------------------------------------------------- /test/test.Paths.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | var assert = require('assert') 3 | var PathCache = require('../src/Paths').PathCache 4 | var AstEntryType = require('../src/Paths').AstEntryType 5 | 6 | vows.describe('firejs Paths').addBatch({ 7 | "When I have a brand new cache": { 8 | topic: function() { 9 | return new PathCache() 10 | }, 11 | "and I ask for a non-compiled path status it should return false": function(topic){ 12 | assert.isFalse(topic.isCompiled("var1")) 13 | } 14 | } 15 | }).export(module); 16 | 17 | vows.describe('firejs Paths Valid AST').addBatch({ 18 | "When I have the path 'var1'": { 19 | topic: function() { 20 | return new PathCache() 21 | }, 22 | "the AST should be a single Object variable": function(topic){ 23 | assert.deepEqual(topic.parse("var1"), [ 24 | { 25 | key:'var1', 26 | type:AstEntryType.Property 27 | } 28 | ]) 29 | } 30 | }, 31 | "When I have the path 'var1.var2'": { 32 | topic: function() { 33 | return new PathCache() 34 | }, 35 | "the AST should be two Object variables": function(topic){ 36 | assert.deepEqual(topic.parse("var1.var2"), [ 37 | { 38 | key: 'var1', 39 | type: AstEntryType.Property 40 | }, 41 | { 42 | key: 'var2', 43 | type: AstEntryType.Property 44 | } 45 | ]) 46 | } 47 | } 48 | }).export(module); 49 | 50 | vows.describe('firejs Paths Invalid AST').addBatch({ 51 | "When I am checking errors and I have the path 'var1..'": { 52 | topic: function() { 53 | return "var1.." 54 | }, 55 | "I should get an exception": function(topic){ 56 | assert.throws(function() { 57 | new PathCache().parse(topic) 58 | }) 59 | }, 60 | "I should get an exception message 'Error at char index 5: Can not get the property without an object'": function(topic){ 61 | try{ 62 | new PathCache().parse(topic) 63 | }catch(msg) { 64 | assert.equal(msg,"Error at char index 5: Can not get the property without an object") 65 | } 66 | } 67 | },"When I am checking errors and I have the path 'var1.'": { 68 | topic: function() { 69 | return "var1." 70 | }, 71 | "I should get an exception": function(topic){ 72 | assert.throws(function() { 73 | new PathCache().parse(topic) 74 | }) 75 | }, 76 | "I should get an exception message 'Unexpected end path, expecting property name'": function(topic){ 77 | try{ 78 | new PathCache().parse(topic) 79 | }catch(msg) { 80 | assert.equal(msg,"Unexpected end path, expecting property name") 81 | } 82 | } 83 | } 84 | }).export(module); 85 | 86 | vows.describe('firejs Paths Values').addBatch({ 87 | "When I have a path cache": { 88 | topic: function() { 89 | return new PathCache() 90 | }, 91 | "and I get a path": function(topic){ 92 | assert.equal(topic.run({ 93 | "x":200 94 | },"x"), 200) 95 | }, 96 | "it should stay compiled to be reused for further executions": function(topic) { 97 | assert.isTrue(topic.isCompiled("x")) 98 | assert.equal(topic.run({ 99 | "x":200 100 | },"x"), 200) 101 | } 102 | }, 103 | "When I run the path 'var1' and the variables are properly registered": { 104 | topic: function() { 105 | return "var1" 106 | }, 107 | "I should get the variable value": function(topic){ 108 | assert.deepEqual(new PathCache().run({ 109 | "var1": 'value of variable 1' 110 | },topic), 'value of variable 1'); 111 | } 112 | }, 113 | "When I run the path 'point.x' and the variables are properly registered": { 114 | topic: function() { 115 | return "point.x" 116 | }, 117 | "I should get the variable value": function(topic){ 118 | assert.deepEqual(new PathCache().run({ 119 | "point": { 120 | "x": 200 121 | } 122 | },topic), 200); 123 | } 124 | }, 125 | "When I run the path 'point.x.y' and the variables are properly registered": { 126 | topic: function() { 127 | return "point.x.y" 128 | }, 129 | "I should get undefined since x is a number and there is no member y": function(topic){ 130 | assert.isUndefined(new PathCache().run({ 131 | "point": { 132 | "x": 200 133 | } 134 | },topic)); 135 | } 136 | }, 137 | "When I run the path 'name' and the variables is registered in a parent scope": { 138 | topic: function() { 139 | return "name" 140 | }, 141 | "I should get the value already set in the parent scope": function(topic){ 142 | assert.deepEqual(new PathCache().run({ 143 | _parent: { 144 | "name": "Value for Name" 145 | } 146 | },topic), "Value for Name"); 147 | } 148 | }, 149 | "When I run the path 'name' and the variables is registered in a deep parent scope": { 150 | topic: function() { 151 | return "name" 152 | }, 153 | "I should get the value already set in the deep parent scope": function(topic){ 154 | assert.deepEqual(new PathCache().run({ 155 | _parent: { 156 | _parent: { 157 | "name": "Value for Name 2" 158 | } 159 | } 160 | },topic), "Value for Name 2"); 161 | } 162 | } 163 | }).export(module); 164 | 165 | vows.describe('firejs Write Paths').addBatch({ 166 | "When I write a variable using a single part path": { 167 | topic: function(){ 168 | var pathCache = new PathCache() 169 | var variables = {}; 170 | pathCache.runWrite(variables, "x" , "Root Val"); 171 | return { 172 | variables: variables, 173 | pathCache: pathCache 174 | } 175 | }, 176 | "the variables bag should contain the variable assigned": function(res) { 177 | assert.equal(res.variables.x, "Root Val") 178 | }, 179 | "the path should remain compiled": function(res) { 180 | assert.isTrue(res.pathCache.writeIsCompiled("x"), "writeIsCompiled should return true") 181 | } 182 | }, 183 | "When I write a variable using a two object parts variable path": { 184 | topic: function(){ 185 | var pathCache = new PathCache() 186 | var variables = {}; 187 | pathCache.runWrite(variables, "point.x" , 534); 188 | return { 189 | variables: variables, 190 | pathCache: pathCache 191 | } 192 | }, 193 | "the variable should contain the assigned member": function(res) { 194 | assert.deepEqual(res.variables.point, { 195 | x: 534 196 | }) 197 | } , 198 | "then when I assign another variable at the same level": { 199 | topic: function(res) { 200 | var pathCache = res.pathCache 201 | var variables = res.variables 202 | pathCache.runWrite(variables, "point.y" , 632); 203 | return { 204 | variables: variables, 205 | pathCache: pathCache 206 | } 207 | }, 208 | "the first and second assignment should remain in the object": function(res) { 209 | assert.deepEqual(res.variables.point, { 210 | x: 534, 211 | y: 632 212 | }) 213 | } 214 | } 215 | }, 216 | "When I write a variable using a three object parts variable path": { 217 | topic: function(){ 218 | var pathCache = new PathCache() 219 | var variables = {}; 220 | pathCache.runWrite(variables, "rect.point1.x" , 534); 221 | return { 222 | variables: variables, 223 | pathCache: pathCache 224 | } 225 | }, 226 | "the variable should contain the assigned third part variable": function(res) { 227 | assert.deepEqual(res.variables.rect, { 228 | point1: { 229 | x: 534 230 | } 231 | }) 232 | }, 233 | "then when I assign another variable at the same level": { 234 | topic: function(res) { 235 | var pathCache = res.pathCache 236 | var variables = res.variables 237 | pathCache.runWrite(variables, "rect.point1.y" , 632); 238 | return { 239 | variables: variables, 240 | pathCache: pathCache 241 | } 242 | }, 243 | "the first and second assignment should remain in the object": function(res) { 244 | assert.deepEqual(res.variables.rect, { 245 | point1: { 246 | x: 534, 247 | y: 632 248 | } 249 | }) 250 | } 251 | } 252 | }, 253 | "When I write a variable using forceCreate": { 254 | topic: function(){ 255 | var pathCache = new PathCache() 256 | var variables = { 257 | _parent: { 258 | rect: "Original Rect Value" 259 | } 260 | }; 261 | pathCache.runWrite(variables, "rect.point1.x" , 534, 262 | true // force create 263 | ); 264 | return { 265 | variables: variables, 266 | pathCache: pathCache 267 | } 268 | }, 269 | "the variable should contain the assigned third part variable": function(res) { 270 | assert.deepEqual(res.variables.rect, { 271 | point1: { 272 | x: 534 273 | } 274 | }) 275 | }, 276 | "the original variable value in the parent scope should not be modified": function(res) { 277 | assert.equal(res.variables._parent.rect, "Original Rect Value") 278 | } 279 | }, 280 | "When I write a variable without forceCreate with parent scope": { 281 | topic: function(){ 282 | var pathCache = new PathCache() 283 | var variables = { 284 | _parent: { 285 | rect: {} 286 | } 287 | }; 288 | pathCache.runWrite(variables, "rect.point1.x" , 534, 289 | false // don't force, use existing variable slot if available 290 | ); 291 | return { 292 | variables: variables, 293 | pathCache: pathCache 294 | } 295 | }, 296 | "the variable in the current scope should not be defined": function(res) { 297 | assert.isUndefined(res.variables.rect) 298 | }, 299 | "the original variable value in the parent scope should contain the value": function(res) { 300 | assert.deepEqual(res.variables._parent.rect, { 301 | point1: { 302 | x: 534 303 | } 304 | }) 305 | } 306 | } 307 | , 308 | "When I write a variable without forceCreate with two level parent scope": { 309 | topic: function(){ 310 | var pathCache = new PathCache() 311 | var variables = { 312 | _parent: { 313 | _parent: { 314 | rect: null 315 | } 316 | } 317 | }; 318 | pathCache.runWrite(variables, "rect.point1.x" , 534, 319 | false // don't force, use existing variable slot if available 320 | ); 321 | return { 322 | variables: variables, 323 | pathCache: pathCache 324 | } 325 | }, 326 | "the variable in the current scope should not be defined": function(res) { 327 | assert.isUndefined(res.variables.rect) 328 | }, 329 | "the original variable value in the parent scope should contain the value": function(res) { 330 | assert.isUndefined(res.variables._parent.rect) 331 | }, 332 | "the original variable value in the deep parent scope should contain the value": function(res) { 333 | assert.deepEqual(res.variables._parent._parent.rect, { 334 | point1: { 335 | x: 534 336 | } 337 | }) 338 | } 339 | } 340 | }).export(module); 341 | -------------------------------------------------------------------------------- /test/test.SourceUri.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | var assert = require('assert') 3 | var fire = require('../src/core.js') 4 | var path = require('path') 5 | var Runtime = fire.Runtime 6 | 7 | vows.describe('firejs - Source Paths JSON').addBatch({ 8 | "When I register a JSON expression without explicit sourceUri": { 9 | topic: function() { 10 | var self = this 11 | var runtime = new Runtime() 12 | runtime.registerWellKnownExpressionDefinition({ 13 | name: "MyTestExpression", 14 | json: null 15 | }); 16 | runtime.load(function(initError) { 17 | if(initError) { 18 | self.callback(initError, null) 19 | } else { 20 | self.callback(null, runtime.loadedExpressionsMeta["MyTestExpression"]) 21 | } 22 | }); 23 | }, 24 | "The sourceUri of the expression should be the name of the expression with protocol 'virtual' and extension .fjson": function(err, exp) { 25 | assert.equal(exp.sourceUri, "virtual:/MyTestExpression.fjson") 26 | } 27 | }, 28 | "When I register a JSON expression with explicit sourceUri": { 29 | topic: function() { 30 | var self = this 31 | var runtime = new Runtime() 32 | runtime.registerWellKnownExpressionDefinition({ 33 | name: "MyTestExpression", 34 | json: null, 35 | sourceUri: "fs:/someJson.fjson" 36 | }); 37 | runtime.load(function(initError) { 38 | if(initError) { 39 | self.callback(initError, null) 40 | } else { 41 | self.callback(null, runtime.loadedExpressionsMeta["MyTestExpression"]) 42 | } 43 | }); 44 | }, 45 | "The sourceUri of the expression should remain the same": function(err, exp) { 46 | assert.equal(exp.sourceUri, "fs:/someJson.fjson") 47 | } 48 | } 49 | }).export(module) 50 | 51 | vows.describe('firejs - Source Paths Custom').addBatch({ 52 | "When I register a custom expression without explicit sourceUri": { 53 | topic: function() { 54 | var self = this 55 | var runtime = new Runtime() 56 | runtime.registerWellKnownExpressionDefinition({ 57 | name: "MyTestExpression", 58 | implementation: function() { 59 | // faked =) 60 | } 61 | }); 62 | runtime.load(function(initError) { 63 | if(initError) { 64 | self.callback(initError, null) 65 | } else { 66 | self.callback(null, runtime.loadedExpressionsMeta["MyTestExpression"]) 67 | } 68 | }); 69 | }, 70 | "The sourceUri of the expression should be the name of the expression with protocol 'virtual' and extension .fjs": function(err, exp) { 71 | assert.equal(exp.sourceUri, "virtual:/MyTestExpression.fjs") 72 | } 73 | }, 74 | "When I register a Custom expression with explicit sourceUri": { 75 | topic: function() { 76 | var self = this 77 | var runtime = new Runtime() 78 | runtime.registerWellKnownExpressionDefinition({ 79 | name: "MyTestExpression", 80 | implementation: function() { 81 | // faked =) 82 | }, 83 | sourceUri: "fs:/someJson.fjs" 84 | }); 85 | runtime.load(function(initError) { 86 | if(initError) { 87 | self.callback(initError, null) 88 | } else { 89 | self.callback(null, runtime.loadedExpressionsMeta["MyTestExpression"]) 90 | } 91 | }); 92 | }, 93 | "The sourceUri of the expression should remain the same": function(err, exp) { 94 | assert.equal(exp.sourceUri, "fs:/someJson.fjs") 95 | } 96 | } 97 | }).export(module) 98 | 99 | vows.describe('firejs - Source Paths Directories').addBatch({ 100 | "When I load a runtime and register files with registerWellKnownExpressionFile": { 101 | topic: function() { 102 | var self = this 103 | var runtime = new Runtime() 104 | runtime.registerWellKnownExpressionFile(path.join(__dirname, "sourceUri/Hello.js")) 105 | runtime.load(function(initError) { 106 | if(initError) { 107 | self.callback(initError, null) 108 | } else { 109 | self.callback(null, runtime.loadedExpressionsMeta["Hello"]) 110 | } 111 | }); 112 | }, 113 | "The sourceUri of the expression should be the path to the source file with protocol 'fs' ": function(err, exp) { 114 | assert.equal(exp.sourceUri, "fs:/" + path.join(__dirname, "sourceUri/Hello.js")) 115 | } 116 | } 117 | ,"When I load a runtime and load custom directories": { 118 | topic: function() { 119 | var self = this 120 | var runtime = new Runtime() 121 | runtime.scriptDirectories.push({ 122 | path: path.join(__dirname, "sourceUri") 123 | }) 124 | runtime.load(function(initError) { 125 | if(initError) { 126 | self.callback(initError, null) 127 | } else { 128 | self.callback(null, { 129 | Hi: runtime.loadedExpressionsMeta["Hi"], 130 | Bye: runtime.loadedExpressionsMeta["Bye"] 131 | }) 132 | } 133 | }); 134 | }, 135 | "The sourceUri of the expressions should be the right uri with protocol 'fs' and the file name": function(err, res) { 136 | assert.equal(res.Hi.sourceUri, "fs:/" + path.join(__dirname, "sourceUri/Hi.fjs")) 137 | assert.equal(res.Bye.sourceUri, "fs:/" + path.join(__dirname, "sourceUri/Bye.fjson")) 138 | } 139 | } 140 | }).export(module) -------------------------------------------------------------------------------- /test/test.UnsupportedHints.js: -------------------------------------------------------------------------------- 1 | var vows = require('vows') 2 | var assert = require('assert') 3 | var jsonCode = require('../src/core.js') 4 | var FireError = require('../src/core.js').Error 5 | var Runtime = jsonCode.Runtime 6 | 7 | var globalContextBase = {}; 8 | globalContextBase._resultCallback = function(res) {} 9 | globalContextBase._loopCallback = function() {}; 10 | globalContextBase._inputExpression = function() {}; 11 | globalContextBase._variables = {}; 12 | globalContextBase._errorCallback = function() {}; 13 | 14 | vows.describe('firejs').addBatch({ 15 | 'Having a JSON code that uses @return with a hint': { 16 | "when we register it": { 17 | topic:function() { 18 | var self = this 19 | var runtime = new Runtime() 20 | runtime.registerWellKnownExpressionDefinition({ 21 | name:"testForbiddenHints", 22 | json: { 23 | "@return(something)": 2 24 | } 25 | }) 26 | runtime.load(function(initError) { 27 | if(initError) { 28 | self.callback(initError, null) 29 | } 30 | else { 31 | self.callback(null, runtime) 32 | } 33 | return runtime 34 | }) 35 | }, 36 | "the error should not be null": function(err, runtime) { 37 | assert.isNotNull(err) 38 | }, 39 | "the error should be instance of CompilationError": function(err, runtime) { 40 | assert.instanceOf(err, jsonCode.CompilationError) 41 | }, 42 | "the error code should be 'UnsupportedHint'": function(err, runtime) { 43 | assert.equal(err.code, "UnsupportedHint") 44 | }, 45 | "the error message should be \"Expression \'return\' does not support hints\"": function(err, runtime) { 46 | assert.equal(err.message, "Expression 'return' does not support hints") 47 | }, 48 | "the error path should be '{@}/@return(something)'": function(err, runtime) { 49 | assert.equal(err.path, "{@}/@return(something)") 50 | } 51 | } 52 | }, 53 | }).export(module); --------------------------------------------------------------------------------