-
Notifications
You must be signed in to change notification settings - Fork 0
/
package.json
60 lines (59 loc) · 10.9 KB
/
package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
{
"name": "annoteJS",
"version": "0.1.5",
"description": "An annotation support framework for Javascript",
"main": "index.js",
"scripts": {
"test": "make test",
"preinstall": "cd ../../ ; npm install promised-io"
},
"repository": {
"type": "git",
"url": "https://github.com/atrifan/annoteJS.git"
},
"keywords": [
"javascript",
"JS",
"annotations",
"NodeJS",
"framework",
"express",
"integration",
"easy",
"REST",
"logging",
"controllers"
],
"author": {
"name": "Trifan Alex",
"email": "[email protected]",
"url": "https://ro.linkedin.com/in/trifanalexandru"
},
"licenses": [
{
"type": "MIT",
"url": "https://raw.githubusercontent.com/atrifan/annoteJS/master/LICENSE"
}
],
"bugs": {
"url": "https://github.com/atrifan/annoteJS/issues"
},
"devDependencies": {
"mocha": "",
"expect.js": "",
"sinon": "",
"mocha-phantomjs": ""
},
"dependencies": {
"esprima": "2.7.3",
"lex": "1.7.9",
"escodegen": "1.8.1"
},
"readme": "# AnnoteJS Framework - annotations support framework \n**Git - [github](https://github.com/atrifan/annoteJS)**\n## Table of Contents\n* [Installation](#installation)\n* [Writing your own annotations](#writing-your-own-annotations)\n * [Example of annotations](#example-of-annotations)\n* [Using the annotations](#using-the-annotations)\n * [Naming](#naming)\n * [Registering](#registering)\n * [Writing an annotated module](#writing-an-annotated-module)\n * [Using the annotated module](#using-the-annotated-module)\n * [Annotation variables](#annotation-variables)\n## Installation\n`npm install annoteJS`\n**This installs in your projects location the _promised-io_ module**\n## Writing your own annotations\nThere are two types of annotation types supported:\n1. **Decorator** means that this type of annotation proxies the request through the annotation function and afterwards based on the annotation's implementation \nit calls or not the original function.\n2. **NonDecorator** means that the annotation is called first before instantiating the annotated class so it can decide what it should do with the specified \nclass. In general we use this type of annotations if we don't intend to later use the annotated modules as standalone. For example a routing annotation does this.\nAfter you have written down your annotation always keep in mind to do the following and this is very **strict**:\n```\n module.exports = {\n isDecorator: false,\n implementation: Standalone\n }\n```\nThe above module.exports is standard for your written annotations and should contain the following info:\n* **isDecorator** - having true/false value - specifies if it should be a proxy and injected around the code or is a standalone that runs before the annotated module itself.\n* **implementation** - the value of this is the actual implementation of the annotation - it should not be a class for that it is called as a function\n### Example of annotations\nIn this section the two types of annotations supported are presented with some particularities and an implementation example. You can also find this implementations\nin the packages default annotations.\n#### NonDecorator annotation\nThe following code shows how to write your own annotation of type **NonDecorator**. The **NonDecorator** annotation supports figuring out if your annotation is above a **class**\nor above a **method** so you are able to know if you have to instantiate the class or just use the method.\n**For NonDecorator annotations _this_ object is the annotation's implementation _this_**\nIn the implementation method you will receive an object with the following properties:\n* **what** - the annotation implementation in string format\n* **type** - _method_|_class_ depending on the case. Keep in mind that class applies also for standalone functions - as stated in the below code\n* **name** - the name of the class/method/function\n* **file** - the file of the annotated module's implementation\n* **originalFile** - the original file on this of the annotated module's implementation\n* **parentClass** - _[optional]_ - this field is received only on class methods in order to be able to instantiate the main class before running the method name\n```\n function Standalone(clazz) {\n if(this.type == 'class') {\n try {\n _treatClass.call(this, clazz);\n } catch (ex) {\n throw ex;\n }\n } else {\n try {\n _treatMethod.call(this, clazz);\n } catch (ex) {\n throw ex;\n }\n }\n }\n \n function _treatClass(clazz) {\n var isClass = false;\n for(var element in clazz[this.name].prototype) {\n if(element != 'constructor' && element != '__proto__') {\n isClass = true;\n break;\n }\n }\n \n //if it is class instantiate it and put info on it\n if(isClass) {\n return;\n }\n \n clazz[this.name](1,2);\n }\n \n function _treatMethod(clazz) {\n var instance;\n \n console.log(\"Trying\");\n if(clazz[this.parentClass]) {\n instance = new clazz[this.parentClass]();\n } else {\n return;\n }\n \n instance[this.name]();\n }\n \n module.exports = {\n isDecorator: false,\n implementation: Standalone\n }\n```\n#### Decorator Annotations\nThe following code shows how to write your own annotation of type **Decorator**. The **Decorator** annotation can be used over a class or over a method. What happens is\nthat your annotation implementation will get injected inside the function and get executed first so you can then trigger the actual implementation's call before your operations or after\nor anyway around, being also able to change the return of the function. I don't recommend changing the return of the function for that can get very misleading.\n**For Decorator annotations _this_ object is the classe's/function's/method's _this_**\nIn the implementation method you will receive the same arguments as the original function. Also you will have a **fn** variable available in your annotation's implementation so you\ncan later call the original function. Another important part is that you have a **Promise** variable also declared inside your original function and available in your annotation's\nimplementation.\n**The original function will change it's return type to a promise** see the [Usage Example](#using-the-annotated-module) section for more info\n```\n function implementation(x, y) {\n var Promise = require('promised-io/promise');\n var self = this;\n return Promise.seq([\n function() {\n console.log(\"doing something before\");\n },\n fn.bind(self, x, y),\n function(result) {\n console.log(\"doing something after\");\n return result;\n }\n ]);\n }\n \n \n module.exports = {\n isDecorator: true,\n implementation: implementation\n }\n```\n## Using the annotations\n### Naming\nAfter you have written your possible annotations you must give the js files containing the implementation a suitable name for that the name of the file will be the\nannotation's name. Avoid naming annotations the same for that the last implementation will be the correct one.\nExample: `/x/y/myAnnotations/My.js` will be used inside modules like `@My()`\n### Registering\nTo register an annotation before you use the module you must run the following code:\n```\n var annoteModule = require('annoteJS');\n annoteModule.registerAnnotations('/x/y/z/myAnnotations');\n```\nThe registerAnnotations method receives **absolute path of the folder location where you have your annotations declared**.\n### Writing an annotated module\nAn annotated module module is a standard module that contains annotations and has 2 restrictions:\n1. module.exports must have the **key name** the **same with** the **annotated function's name** (in case of functions) or must have the **key name** \nthe **same with** the **class name**\n2. You can have either a module with multiple functions or a module with just one class (for the moment this can't be combined)\n#### Writing an annotated class module\n```\n function AnnotatedClass() {}\n \n @My()\n AnnotatedClass.prototype.doSomething = function() {...}\n \n module.exports = {\n AnnotatedClass: AnnotatedClass\n }\n```\n#### Writing an annotated module with multiple functions but !!NO CLASS!!.\n```\n @My()\n function annotatedF1() {}\n \n @My()\n function annotatedF2() {}\n \n module.exports = {\n annotatedF1: annotatedF1,\n annotatedF2: annotatedF2\n }\n```\n### Using the annotated module\nIn order for the module to work you must require the annotatedModule as described in the bellow code.\n**Annotation - My** - path /x/y/annotations\n```\n function My(x, y) {\n return Promise.seq([\n fn.bind(this, x, y),\n function(result) {\n console.log(\"the result is \", result);\n return result;\n }\n ]);\n }\n \n module.exports = {\n isDecorator: true,\n implementation: My\n }\n```\n**Annotated Module - Calculator**\n```\n @My()\n function calculate(x, y) {\n return x + y;\n }\n \n module.exports = {\n calculate: calculate\n }\n```\n**Usage of the annotated Module**\n```\n var annoteModule = require('annoteJS');\n annoteModule.registerAnnotations('/x/y/z/myAnnotations');\n \n var annoteJS = annoteModule.get(),\n annotatedCalculator = annoteJS.requireWithAnnotations('./path/to/my/Calculator.js');\n \n annotatedCalculator.calculate(2,3).then(function(result) {\n console.log(\"the official result of all in all module is \", result);\n }, function(err) {\n //something bad happened\n });\n```\n### Annotation variables\nYou are also permitted to pass some variables to your annotations for example:\n \n```\n function My() {\n console.log(My.path);\n console.log(My.stuff);\n console.log(My.defaultArgument);\n }\n```\n```\n @My(path=left,stuff=1)\n function annotatedFunction(){...}\n \n @My(critter)\n function defaultArgumentAnnotatedFunction() {...}\n \n module.exports = {\n annotatedFunction: annotatedFunction,\n defaultArgumentAnnotatedFunction: defaultArgumentAnnotatedFunction\n }\n```\nWhen no name for variable is passed the value inside the brackets is found on the defaultArgument field of the annotation's implementation.\n",
"_id": "[email protected]",
"dist": {
"shasum": "35b85ddf52a0a9a1152b55b228629d7060f4e8a2"
},
"_from": "https://github.com/atrifan/annoteJS/tarball/master",
"_resolved": "https://github.com/atrifan/annoteJS/tarball/master"
}