1 | 'use strict';
|
2 | const _ = require('lodash');
|
3 | const bases = require('bases');
|
4 | const builtInSlotsMap = require('./built-in-slots-map');
|
5 | const builtInIntentsMap = require('./built-in-intents-map');
|
6 | const validator = require('./validator');
|
7 | const parseError = require('./error-handler').parseError;
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 | module.exports = (intents, name, richUtterances, handler) => {
|
17 |
|
18 | richUtterances = _.isArray(richUtterances) ? richUtterances : [richUtterances];
|
19 |
|
20 |
|
21 | if (!name) {
|
22 | name = generateIntentName(intents);
|
23 |
|
24 | } else if (!validator.isNameValid(name)) {
|
25 | const e = parseError(new Error(`Intent name ${name} is invalid. Only lowercase and uppercase letters are allowed`));
|
26 | throw e;
|
27 | } else if (builtInIntentsMap[name]) {
|
28 |
|
29 | name = builtInIntentsMap[name];
|
30 | }
|
31 |
|
32 |
|
33 | let slots = [];
|
34 | let utterances = [];
|
35 |
|
36 | parseRichUtterances(richUtterances, slots, utterances);
|
37 |
|
38 | return {
|
39 | name: name,
|
40 | slots: slots,
|
41 | utterances: utterances,
|
42 | handler: handler
|
43 | };
|
44 | };
|
45 |
|
46 | const generateIntentName = (intents) => {
|
47 | let position = 0;
|
48 | let generatedName;
|
49 |
|
50 |
|
51 | while (intents[(generatedName = bases.toBase52(position++))] && !builtInIntentsMap[generatedName]);
|
52 |
|
53 | return generatedName;
|
54 | };
|
55 |
|
56 | const parseRichUtterances = (richUtterances, slots, utterances) => {
|
57 |
|
58 | _.each(richUtterances, function (utterance) {
|
59 | var matches = findUtteranceMatches(utterance);
|
60 |
|
61 | _.each(matches, function (match) {
|
62 | const slotName = match[1];
|
63 | const slotType = match[2];
|
64 |
|
65 |
|
66 | if (!_.find(slots, {name: slotName})) {
|
67 |
|
68 |
|
69 | slots.push({
|
70 | name: slotName,
|
71 | type: transformSlotType(slotType)
|
72 | });
|
73 | }
|
74 |
|
75 |
|
76 | utterance = utterance.replace(match[0], '{' + slotName + '}');
|
77 | });
|
78 |
|
79 | if (validator.isUtteranceValid(utterance)) {
|
80 |
|
81 | utterances.push(utterance);
|
82 | } else {
|
83 | const e = parseError(new Error(`Sample utterance: '${utterance}' is not valid. Each sample utterance must consist only of alphabet characters, spaces, dots, hyphens, brackets and single quotes`));
|
84 | throw e;
|
85 | }
|
86 |
|
87 | });
|
88 | };
|
89 |
|
90 | const transformSlotType = (type) => {
|
91 | const transformedType = builtInSlotsMap[type];
|
92 | return transformedType || type;
|
93 | };
|
94 |
|
95 | const findUtteranceMatches = (utterance) => {
|
96 |
|
97 |
|
98 | const myregex = /{(.*?):(.*?)\}/gmi;
|
99 | let result;
|
100 | let allMatches = [];
|
101 |
|
102 | while ((result = myregex.exec(utterance)) != null) {
|
103 | allMatches.push(result);
|
104 | }
|
105 |
|
106 | return allMatches;
|
107 | };
|