# Επιχειρηματικοί κανόνες ως κείμενο με το NEWMACRO()

> Μεταγλωττίστε μικρούς κανόνες γραμμένους σε μια απλή γλώσσα (IF, ELSE, AND, OR, RETURN, κλήσεις helpers) σε μια συνάρτηση που εκτελείτε με ένα μοντέλο, ώστε οι κανόνες να ζουν σε ένα αρχείο ή σε μια βάση δεδομένων.

Framework: total5
Product: Total.js 5 (total5@0.0.19)
Language: el
Content-SHA256: 3197298ded7bba38dcdcbca449e26347b06882417406316a2654c2d84c794315
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: total5-installed@total5@0.0.19
Review: not-recorded

Το `NEWMACRO(text, [nocompile], [isasync])` μετατρέπει μερικές γραμμές μιας μικρής γλώσσας σε μια συνάρτηση `function(model, helpers)`. Προορίζεται για κανόνες που αλλάζουν συχνότερα από τον κώδικα: μια έκπτωση, μια τιμή, έναν έλεγχο δικαιωμάτων, μια επικύρωση που κάποιος που δεν γράφει JavaScript συντηρεί σε ένα αρχείο ή σε μια βάση δεδομένων.

Η γλώσσα, όπως ελέγχθηκε:

- Τα `IF condition`, `ELSE IF condition`, `ELSE` και `FI` (το τέλος της συνθήκης) λειτουργούν όπως σε έναν κανόνα βασισμένο σε κείμενο. Οι συνθήκες χρησιμοποιούν `>`, `<`, `>=`, `<=`, `=` και `AND` / `OR`.
- Το `RETURN value` τελειώνει το macro με μια τιμή. Τα `YES` και `NO` (επίσης `TRUE`, `FALSE`, `OK`) είναι λογικές τιμές, το κείμενο ανάμεσα σε εισαγωγικά είναι κείμενο και οι αριθμοί είναι αριθμοί.
- Μια λέξη είναι **ιδιότητα του μοντέλου**, γραμμένη με πεζά: το `age` διαβάζει το `model.age` και το `total = price * qty` γράφει το `model.total`.
- Το `NAME(arguments)` καλεί έναν **helper**, τη συνάρτηση με αυτό το όνομα (με πεζά) στο αντικείμενο `helpers` που περνάτε· μέσα της το `this` είναι το μοντέλο. Με το `isasync` ίσο με `true` το macro είναι async συνάρτηση και περιμένει τους helpers.
- Το `#name` είναι μια προσωρινή μεταβλητή της εκτέλεσης: `#temp = num + 1` και `RETURN #temp`.
- Χρησιμοποιήστε ονόματα με **περισσότερα γράμματα**: μια ιδιότητα ή μεταβλητή ενός γράμματος δεν αναγνωρίστηκε στους ελέγχους.

Το `NEWMACRO()` μεταγλωττίζει το κείμενο με `new Function`, άρα ένα macro είναι κώδικας: μεταγλωττίστε μόνο κείμενο που γράψατε εσείς ή που συντηρεί ένα αξιόπιστο πρόσωπο, ποτέ κείμενο που έστειλε ένας επισκέπτης. Με το `nocompile` ίσο με `true` επιστρέφει το JavaScript που παράγει αντί για τη συνάρτηση, κάτι χρήσιμο για να δείτε τι κάνει ένας κανόνας.

```js controllers/rules.js
const helpers = {
	percent: function(value, rate) {
		return value * rate / 100;
	}
};

const age = NEWMACRO("IF age >= 18\n\tRETURN 'adult'\nELSE\n\tRETURN 'minor'\nFI");

const level = NEWMACRO("IF points > 100\n\tRETURN 'gold'\nELSE IF points > 50\n\tRETURN 'silver'\nELSE\n\tRETURN 'bronze'\nFI");

const access = NEWMACRO("IF active AND score >= 5\n\tRETURN yes\nFI\nRETURN no");

const total = NEWMACRO("total = price * qty\nIF qty >= 10\n\ttotal = total - PERCENT(total, 10)\nFI\nRETURN total");

const temporary = NEWMACRO("#next = count + 1\nRETURN #next");

const slow = NEWMACRO("RETURN LOOKUP(code)", false, true);

exports.install = function() {
	ROUTE('POST /rules/', rules);
	ROUTE('GET /source/', source);
};

async function rules($) {
	const model = $.body;
	$.json({
		age: age(model, helpers),
		level: level(model, helpers),
		access: access(model, helpers),
		total: total(model, helpers),
		model_total: model.total,
		temporary: temporary(model, helpers),
		slow: await slow(model, { lookup: async code => 'found ' + code })
	});
}

function source($) {
	$.plain(NEWMACRO("IF points > 100\n\tRETURN 'gold'\nFI", true));
}
```
