@botonic/nx-plugin 2.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +420 -0
- package/README.md +279 -0
- package/executors.json +55 -0
- package/generators.json +61 -0
- package/migrations.json +40 -0
- package/package.json +54 -0
- package/src/cursor-commands/update-bot.md +114 -0
- package/src/cursor-commands/update-botonic.md +63 -0
- package/src/executors/build-node-app/executor.d.ts +5 -0
- package/src/executors/build-node-app/executor.js +65 -0
- package/src/executors/build-node-app/schema.d.js +16 -0
- package/src/executors/build-node-app/schema.json +25 -0
- package/src/executors/delete-bot/executor.d.ts +5 -0
- package/src/executors/delete-bot/executor.js +112 -0
- package/src/executors/delete-bot/schema.d.js +16 -0
- package/src/executors/delete-bot/schema.json +35 -0
- package/src/executors/deploy-local-runtime/executor.d.ts +5 -0
- package/src/executors/deploy-local-runtime/executor.js +144 -0
- package/src/executors/deploy-local-runtime/schema.d.js +16 -0
- package/src/executors/deploy-local-runtime/schema.json +34 -0
- package/src/executors/deploy-netlify-snapshot/executor.d.ts +8 -0
- package/src/executors/deploy-netlify-snapshot/executor.js +79 -0
- package/src/executors/deploy-netlify-snapshot/schema.d.js +16 -0
- package/src/executors/deploy-netlify-snapshot/schema.json +31 -0
- package/src/executors/deploy-to-hubtype/executor.d.ts +5 -0
- package/src/executors/deploy-to-hubtype/executor.js +308 -0
- package/src/executors/deploy-to-hubtype/schema.d.js +16 -0
- package/src/executors/deploy-to-hubtype/schema.json +31 -0
- package/src/executors/e2e-webchat/botonic-package-publish.spec.ts +84 -0
- package/src/executors/e2e-webchat/executor.d.ts +5 -0
- package/src/executors/e2e-webchat/executor.js +134 -0
- package/src/executors/e2e-webchat/schema.d.js +16 -0
- package/src/executors/e2e-webchat/schema.json +35 -0
- package/src/executors/integrate-provider/executor.d.ts +5 -0
- package/src/executors/integrate-provider/executor.js +155 -0
- package/src/executors/integrate-provider/schema.d.js +16 -0
- package/src/executors/integrate-provider/schema.json +30 -0
- package/src/executors/login-to-hubtype/executor.d.ts +5 -0
- package/src/executors/login-to-hubtype/executor.js +79 -0
- package/src/executors/login-to-hubtype/schema.d.js +16 -0
- package/src/executors/login-to-hubtype/schema.json +25 -0
- package/src/executors/logout-from-hubtype/executor.d.ts +3 -0
- package/src/executors/logout-from-hubtype/executor.js +54 -0
- package/src/executors/logout-from-hubtype/schema.d.js +16 -0
- package/src/executors/logout-from-hubtype/schema.json +9 -0
- package/src/executors/run-lambda/executor.d.ts +5 -0
- package/src/executors/run-lambda/executor.js +65 -0
- package/src/executors/run-lambda/schema.d.js +16 -0
- package/src/executors/run-lambda/schema.json +20 -0
- package/src/executors/serve-bot/executor.d.ts +5 -0
- package/src/executors/serve-bot/executor.js +330 -0
- package/src/executors/serve-bot/schema.d.js +16 -0
- package/src/executors/serve-bot/schema.json +40 -0
- package/src/generators/action/files/__name__.spec.ts.template +15 -0
- package/src/generators/action/files/__name__.ts.template +15 -0
- package/src/generators/action/generator.d.ts +4 -0
- package/src/generators/action/generator.js +112 -0
- package/src/generators/action/schema.d.ts +7 -0
- package/src/generators/action/schema.js +16 -0
- package/src/generators/action/schema.json +43 -0
- package/src/generators/bot-app/files/.eslintrc.json.template +18 -0
- package/src/generators/bot-app/files/README.md.template +148 -0
- package/src/generators/bot-app/files/src/client/custom-messages/index.ts.template +2 -0
- package/src/generators/bot-app/files/src/client/webchat/index.html.template +35 -0
- package/src/generators/bot-app/files/src/client/webchat/index.tsx.template +107 -0
- package/src/generators/bot-app/files/src/client/webchat/styles.css.template +17 -0
- package/src/generators/bot-app/files/src/client/webchat/webchat-tokens-overrides.css.template +2 -0
- package/src/generators/bot-app/files/src/client/webviews/app.tsx.template +8 -0
- package/src/generators/bot-app/files/src/client/webviews/index.html.template +32 -0
- package/src/generators/bot-app/files/src/client/webviews/index.tsx.template +18 -0
- package/src/generators/bot-app/files/src/server/bot/actions/index.ts.template +2 -0
- package/src/generators/bot-app/files/src/server/bot/actions/not-found.ts.template +13 -0
- package/src/generators/bot-app/files/src/server/bot/actions/welcome.ts.template +13 -0
- package/src/generators/bot-app/files/src/server/bot/index.ts.template +43 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/ai-agents/index.ts.template +30 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/flow-builder/index.ts.template +28 -0
- package/src/generators/bot-app/files/src/server/bot/plugins/index.ts.template +11 -0
- package/src/generators/bot-app/files/src/server/bot/routes.ts.template +23 -0
- package/src/generators/bot-app/files/src/server/bot/tools/index.ts.template +5 -0
- package/src/generators/bot-app/files/src/server/bot/tracking.ts.template +35 -0
- package/src/generators/bot-app/files/src/server/bot/types.ts.template +4 -0
- package/src/generators/bot-app/files/src/server/bot/utils.ts.template +9 -0
- package/src/generators/bot-app/files/src/server/lambda/handler.js.template +24 -0
- package/src/generators/bot-app/files/src/server/lambda/package.json +20 -0
- package/src/generators/bot-app/files/src/server/lambda/template.yaml.template +20 -0
- package/src/generators/bot-app/files/src/shared/constants.ts.template +12 -0
- package/src/generators/bot-app/files/vite/base-client.config.ts.template +14 -0
- package/src/generators/bot-app/files/vite/base.config.ts.template +20 -0
- package/src/generators/bot-app/files/vite/build.config.ts.template +65 -0
- package/src/generators/bot-app/files/vite/node.config.ts.template +41 -0
- package/src/generators/bot-app/files/vite/plugins/move-html.plugin.ts.template +36 -0
- package/src/generators/bot-app/files/vite/webchat.config.ts.template +58 -0
- package/src/generators/bot-app/files/vite/webviews.config.ts.template +57 -0
- package/src/generators/bot-app/files/vite.config.ts.template +36 -0
- package/src/generators/bot-app/generator.d.ts +4 -0
- package/src/generators/bot-app/generator.js +294 -0
- package/src/generators/bot-app/schema.d.ts +6 -0
- package/src/generators/bot-app/schema.js +16 -0
- package/src/generators/bot-app/schema.json +36 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/generator.js +92 -0
- package/src/generators/bot-app-migrations/migrate-fix-css-code-split/schema.json +15 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/generator.js +97 -0
- package/src/generators/bot-app-migrations/migrate-pnpm-compat/schema.json +15 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.d.ts +5 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/generator.js +165 -0
- package/src/generators/bot-app-migrations/migrate-webchat-trigger/schema.json +15 -0
- package/src/generators/custom-message/files/__name__-output.ts.template +21 -0
- package/src/generators/custom-message/files/__name__.spec.tsx.template +27 -0
- package/src/generators/custom-message/files/__name__.tsx.template +18 -0
- package/src/generators/custom-message/generator.d.ts +4 -0
- package/src/generators/custom-message/generator.js +235 -0
- package/src/generators/custom-message/schema.d.ts +7 -0
- package/src/generators/custom-message/schema.js +16 -0
- package/src/generators/custom-message/schema.json +44 -0
- package/src/generators/preset/files/.cursor/commands/update-bot.md +5 -0
- package/src/generators/preset/files/.cursor/commands/update-botonic.md +5 -0
- package/src/generators/preset/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
- package/src/generators/preset/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
- package/src/generators/preset/files/.cursor/skills/botonic-action/SKILL.md +167 -0
- package/src/generators/preset/files/.cursor/skills/botonic-custom-message/SKILL.md +231 -0
- package/src/generators/preset/files/.cursor/skills/botonic-webview/SKILL.md +179 -0
- package/src/generators/preset/files/.env.prod.template +2 -0
- package/src/generators/preset/files/.env.template +2 -0
- package/src/generators/preset/files/.npmrc.template +1 -0
- package/src/generators/preset/files/README.md.template +174 -0
- package/src/generators/preset/files/nx.json +66 -0
- package/src/generators/preset/files/package.json +26 -0
- package/src/generators/preset/files/tsconfig.base.json +27 -0
- package/src/generators/preset/files/tsconfig.base.json.template +27 -0
- package/src/generators/preset/files/tsconfig.json +9 -0
- package/src/generators/preset/generator.d.ts +4 -0
- package/src/generators/preset/generator.js +127 -0
- package/src/generators/preset/schema.d.ts +6 -0
- package/src/generators/preset/schema.js +16 -0
- package/src/generators/preset/schema.json +50 -0
- package/src/generators/remove-custom-message/generator.d.ts +4 -0
- package/src/generators/remove-custom-message/generator.js +259 -0
- package/src/generators/remove-custom-message/schema.d.ts +6 -0
- package/src/generators/remove-custom-message/schema.js +16 -0
- package/src/generators/remove-custom-message/schema.json +39 -0
- package/src/generators/shared/bot-app-utils.d.ts +25 -0
- package/src/generators/shared/bot-app-utils.js +209 -0
- package/src/generators/webview/files/__name__.spec.tsx.template +20 -0
- package/src/generators/webview/files/__name__.tsx.template +19 -0
- package/src/generators/webview/generator.d.ts +4 -0
- package/src/generators/webview/generator.js +179 -0
- package/src/generators/webview/schema.d.ts +5 -0
- package/src/generators/webview/schema.js +16 -0
- package/src/generators/webview/schema.json +34 -0
- package/src/index.d.ts +7 -0
- package/src/index.js +56 -0
- package/src/lib/api-service.d.ts +110 -0
- package/src/lib/api-service.js +591 -0
- package/src/lib/bot-config.d.ts +30 -0
- package/src/lib/bot-config.js +203 -0
- package/src/lib/cloudflared-tunnel.d.ts +29 -0
- package/src/lib/cloudflared-tunnel.js +95 -0
- package/src/lib/constants.d.ts +13 -0
- package/src/lib/constants.js +60 -0
- package/src/lib/credentials-handler.d.ts +40 -0
- package/src/lib/credentials-handler.js +115 -0
- package/src/lib/index.d.ts +10 -0
- package/src/lib/index.js +47 -0
- package/src/lib/interfaces.d.ts +49 -0
- package/src/lib/interfaces.js +16 -0
- package/src/lib/util/executor-helpers.d.ts +97 -0
- package/src/lib/util/executor-helpers.js +574 -0
- package/src/lib/util/file-system.d.ts +8 -0
- package/src/lib/util/file-system.js +65 -0
- package/src/lib/util/sam-container-cleanup.d.ts +11 -0
- package/src/lib/util/sam-container-cleanup.js +55 -0
- package/src/lib/util/sam-template.d.ts +9 -0
- package/src/lib/util/sam-template.js +71 -0
- package/src/lib/util/system.d.ts +1 -0
- package/src/lib/util/system.js +30 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.d.ts +2 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.js +52 -0
- package/src/migrations/add-botonic-update-bots-skill/add-botonic-update-bots-skill.migration.md +23 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-bot.md +5 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/commands/update-botonic.md +5 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/discover-bots.sh +67 -0
- package/src/migrations/add-botonic-update-bots-skill/files/.cursor/scripts/update-bot/find-migration-guides.sh +70 -0
- package/src/migrations/add-botonic-update-bots-skill/schema.json +5 -0
- package/src/migrations/add-lilara-registry/add-lilara-registry.migration.d.ts +2 -0
- package/src/migrations/add-lilara-registry/add-lilara-registry.migration.js +49 -0
- package/src/migrations/add-lilara-registry/schema.json +5 -0
- package/src/migrations/fix-css-code-split/fix-css-code-split.migration.md +45 -0
- package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.d.ts +2 -0
- package/src/migrations/remove-codeartifact-registry/remove-codeartifact-registry.migration.js +59 -0
- package/src/migrations/remove-codeartifact-registry/schema.json +5 -0
- package/src/migrations/sync-pending-bot-migrations/schema.json +5 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.d.ts +2 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.js +137 -0
- package/src/migrations/sync-pending-bot-migrations/sync-pending-bot-migrations.migration.md +19 -0
- package/src/migrations/update-cursor-commands-to-stubs/schema.json +5 -0
- package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.d.ts +2 -0
- package/src/migrations/update-cursor-commands-to-stubs/update-cursor-commands-to-stubs.migration.js +61 -0
- package/src/migrations/update-pnpm-workspace-scripts/schema.json +4 -0
- package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.d.ts +2 -0
- package/src/migrations/update-pnpm-workspace-scripts/update-pnpm-workspace-scripts.migration.js +47 -0
- package/src/migrations/utils/migration-utils.d.ts +109 -0
- package/src/migrations/utils/migration-utils.js +448 -0
- package/src/plugin.d.ts +15 -0
- package/src/plugin.js +246 -0
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var generator_exports = {};
|
|
20
|
+
__export(generator_exports, {
|
|
21
|
+
default: () => generator_default
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(generator_exports);
|
|
24
|
+
var import_devkit = require("@nx/devkit");
|
|
25
|
+
var import_bot_app_utils = require("../shared/bot-app-utils");
|
|
26
|
+
const MODULE_DIR = __dirname;
|
|
27
|
+
function normalizeOptions(tree, options) {
|
|
28
|
+
const { projectRoot, sourceRoot } = (0, import_bot_app_utils.validateBotAppProject)(
|
|
29
|
+
tree,
|
|
30
|
+
options.project
|
|
31
|
+
);
|
|
32
|
+
const paths = (0, import_bot_app_utils.resolveStandardPaths)(sourceRoot);
|
|
33
|
+
const name = (0, import_devkit.names)(options.name);
|
|
34
|
+
const fileName = name.fileName;
|
|
35
|
+
const className = name.className;
|
|
36
|
+
const propertyName = name.propertyName;
|
|
37
|
+
const constantName = name.constantName.toUpperCase();
|
|
38
|
+
const customMessagesPath = options.directory ? `${sourceRoot}/client/custom-messages/${options.directory}` : `${sourceRoot}/client/custom-messages`;
|
|
39
|
+
return {
|
|
40
|
+
...options,
|
|
41
|
+
projectName: options.project,
|
|
42
|
+
projectRoot,
|
|
43
|
+
fileName,
|
|
44
|
+
className,
|
|
45
|
+
propertyName,
|
|
46
|
+
constantName,
|
|
47
|
+
customMessagesPath,
|
|
48
|
+
constantsPath: paths.constantsPath,
|
|
49
|
+
actionsPath: paths.actionsPath,
|
|
50
|
+
routesPath: paths.routesPath
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function addFilesToProject(tree, options) {
|
|
54
|
+
const name = (0, import_devkit.names)(options.name);
|
|
55
|
+
const templateOptions = {
|
|
56
|
+
...options,
|
|
57
|
+
...name,
|
|
58
|
+
name: name.fileName
|
|
59
|
+
// __name__ in filenames must be kebab-case
|
|
60
|
+
};
|
|
61
|
+
(0, import_devkit.generateFiles)(
|
|
62
|
+
tree,
|
|
63
|
+
(0, import_devkit.joinPathFragments)(MODULE_DIR, "files"),
|
|
64
|
+
options.customMessagesPath,
|
|
65
|
+
templateOptions
|
|
66
|
+
);
|
|
67
|
+
if (options.skipTests) {
|
|
68
|
+
const testFilePath = `${options.customMessagesPath}/${options.fileName}.spec.tsx`;
|
|
69
|
+
if (tree.exists(testFilePath)) {
|
|
70
|
+
tree.delete(testFilePath);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (options.skipAction) {
|
|
74
|
+
const actionPath = `${options.customMessagesPath}/${options.fileName}-output.ts`;
|
|
75
|
+
if (tree.exists(actionPath)) {
|
|
76
|
+
tree.delete(actionPath);
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
const sourceActionPath = `${options.customMessagesPath}/${options.fileName}-output.ts`;
|
|
80
|
+
const targetActionPath = `${options.actionsPath}/${options.fileName}.ts`;
|
|
81
|
+
if (tree.exists(sourceActionPath)) {
|
|
82
|
+
const content = tree.read(sourceActionPath, "utf-8");
|
|
83
|
+
tree.write(targetActionPath, content);
|
|
84
|
+
tree.delete(sourceActionPath);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function updateCustomMessagesIndex(tree, options) {
|
|
89
|
+
const indexPath = `${options.customMessagesPath}/index.ts`;
|
|
90
|
+
if (!tree.exists(indexPath)) {
|
|
91
|
+
tree.write(
|
|
92
|
+
indexPath,
|
|
93
|
+
`import { CUSTOM_MESSAGE_TYPES } from '../../shared/constants'
|
|
94
|
+
|
|
95
|
+
export const customMessages = {
|
|
96
|
+
[CUSTOM_MESSAGE_TYPES.${options.constantName}]: ${options.className},
|
|
97
|
+
}
|
|
98
|
+
`
|
|
99
|
+
);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const content = tree.read(indexPath, "utf-8");
|
|
103
|
+
const lines = content.split("\n");
|
|
104
|
+
const importStatement = `import { ${options.className} } from './${options.directory ? options.directory + "/" : ""}${options.fileName}'`;
|
|
105
|
+
let importInsertIndex = 0;
|
|
106
|
+
for (let i = 0; i < lines.length; i++) {
|
|
107
|
+
if (lines[i].startsWith("import")) {
|
|
108
|
+
importInsertIndex = i + 1;
|
|
109
|
+
} else if (lines[i].trim() === "" && importInsertIndex > 0) {
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
lines.splice(importInsertIndex, 0, importStatement);
|
|
114
|
+
const exportLineIndex = lines.findIndex(
|
|
115
|
+
(line) => line.includes("export const customMessages")
|
|
116
|
+
);
|
|
117
|
+
if (exportLineIndex !== -1) {
|
|
118
|
+
let braceIndex = exportLineIndex;
|
|
119
|
+
while (braceIndex < lines.length && !lines[braceIndex].includes("{")) {
|
|
120
|
+
braceIndex++;
|
|
121
|
+
}
|
|
122
|
+
if (braceIndex < lines.length) {
|
|
123
|
+
const braceLine = lines[braceIndex];
|
|
124
|
+
if (braceLine.trim() === "{" || braceLine.includes("{}")) {
|
|
125
|
+
const newEntry = ` [CUSTOM_MESSAGE_TYPES.${options.constantName}]: ${options.className},`;
|
|
126
|
+
if (braceLine.includes("{}")) {
|
|
127
|
+
lines[braceIndex] = braceLine.replace("{}", `{
|
|
128
|
+
${newEntry}
|
|
129
|
+
}`);
|
|
130
|
+
} else {
|
|
131
|
+
lines.splice(braceIndex + 1, 0, newEntry);
|
|
132
|
+
}
|
|
133
|
+
} else {
|
|
134
|
+
let closingBraceIndex = braceIndex;
|
|
135
|
+
let braceCount = 0;
|
|
136
|
+
for (let i = braceIndex; i < lines.length; i++) {
|
|
137
|
+
for (const char of lines[i]) {
|
|
138
|
+
if (char === "{") braceCount++;
|
|
139
|
+
if (char === "}") braceCount--;
|
|
140
|
+
}
|
|
141
|
+
if (braceCount === 0) {
|
|
142
|
+
closingBraceIndex = i;
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
const newEntry = ` [CUSTOM_MESSAGE_TYPES.${options.constantName}]: ${options.className},`;
|
|
147
|
+
lines.splice(closingBraceIndex, 0, newEntry);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
tree.write(indexPath, lines.join("\n"));
|
|
152
|
+
}
|
|
153
|
+
function updateConstantsFile(tree, options) {
|
|
154
|
+
if (!tree.exists(options.constantsPath)) {
|
|
155
|
+
tree.write(
|
|
156
|
+
options.constantsPath,
|
|
157
|
+
`export const CUSTOM_MESSAGE_TYPES = {
|
|
158
|
+
${options.constantName}: '${options.fileName}',
|
|
159
|
+
} as const
|
|
160
|
+
|
|
161
|
+
export const WEBVIEWS = {
|
|
162
|
+
// Add your webviews here
|
|
163
|
+
} as const
|
|
164
|
+
|
|
165
|
+
export const PAYLOADS = {
|
|
166
|
+
// Add your payloads here
|
|
167
|
+
} as const
|
|
168
|
+
`
|
|
169
|
+
);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
(0, import_bot_app_utils.addConstEntry)(
|
|
173
|
+
tree,
|
|
174
|
+
options.constantsPath,
|
|
175
|
+
"CUSTOM_MESSAGE_TYPES",
|
|
176
|
+
options.constantName,
|
|
177
|
+
options.fileName
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
function updateActionsIndex(tree, options) {
|
|
181
|
+
if (options.skipAction) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
(0, import_bot_app_utils.addExportToIndex)(
|
|
185
|
+
tree,
|
|
186
|
+
`${options.actionsPath}/index.ts`,
|
|
187
|
+
`export * from './${options.fileName}'`
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
function updateRoutes(tree, options) {
|
|
191
|
+
if (options.skipAction) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const actionImport = `${options.propertyName}Output`;
|
|
195
|
+
(0, import_bot_app_utils.addActionImportToRoutes)(tree, options.routesPath, actionImport);
|
|
196
|
+
(0, import_bot_app_utils.insertRouteBeforeFlowBuilder)(tree, options.routesPath, [
|
|
197
|
+
` {`,
|
|
198
|
+
` text: '${options.fileName}',`,
|
|
199
|
+
` action: async () => await ${actionImport}(botContext),`,
|
|
200
|
+
` },`
|
|
201
|
+
]);
|
|
202
|
+
}
|
|
203
|
+
async function generator_default(tree, options) {
|
|
204
|
+
console.log(`Creating custom message: ${options.name}`);
|
|
205
|
+
const normalizedOptions = normalizeOptions(tree, options);
|
|
206
|
+
console.log(`Project: ${normalizedOptions.projectName}`);
|
|
207
|
+
console.log(`Location: ${normalizedOptions.customMessagesPath}`);
|
|
208
|
+
addFilesToProject(tree, normalizedOptions);
|
|
209
|
+
updateConstantsFile(tree, normalizedOptions);
|
|
210
|
+
updateCustomMessagesIndex(tree, normalizedOptions);
|
|
211
|
+
updateActionsIndex(tree, normalizedOptions);
|
|
212
|
+
updateRoutes(tree, normalizedOptions);
|
|
213
|
+
await (0, import_devkit.formatFiles)(tree);
|
|
214
|
+
console.log(
|
|
215
|
+
`
|
|
216
|
+
Successfully created custom message: ${normalizedOptions.className}`
|
|
217
|
+
);
|
|
218
|
+
console.log(`Next steps:`);
|
|
219
|
+
console.log(
|
|
220
|
+
` 1. Customize the component in: ${normalizedOptions.customMessagesPath}/${normalizedOptions.fileName}.tsx`
|
|
221
|
+
);
|
|
222
|
+
if (!options.skipAction) {
|
|
223
|
+
console.log(
|
|
224
|
+
` 2. Update the action in: ${normalizedOptions.actionsPath}/${normalizedOptions.fileName}.ts`
|
|
225
|
+
);
|
|
226
|
+
console.log(
|
|
227
|
+
` 3. Test by typing '${normalizedOptions.fileName}' in the webchat`
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
if (!options.skipTests) {
|
|
231
|
+
console.log(
|
|
232
|
+
` 4. Update the tests in: ${normalizedOptions.customMessagesPath}/${normalizedOptions.fileName}.spec.tsx`
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
15
|
+
var schema_exports = {};
|
|
16
|
+
module.exports = __toCommonJS(schema_exports);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
|
+
"cli": "nx",
|
|
4
|
+
"$id": "CustomMessage",
|
|
5
|
+
"title": "Create a custom message component for Botonic",
|
|
6
|
+
"description": "Generate a custom message component with automatic registration in the bot application.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"properties": {
|
|
9
|
+
"name": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "The name of the custom message component.",
|
|
12
|
+
"$default": {
|
|
13
|
+
"$source": "argv",
|
|
14
|
+
"index": 0
|
|
15
|
+
},
|
|
16
|
+
"x-prompt": "What name would you like to use for the custom message?",
|
|
17
|
+
"pattern": "^[a-zA-Z].*$"
|
|
18
|
+
},
|
|
19
|
+
"project": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"description": "The name of the botonic project to add the custom message to.",
|
|
22
|
+
"x-prompt": "Which botonic project should this custom message be added to?",
|
|
23
|
+
"$default": {
|
|
24
|
+
"$source": "projectName"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"directory": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "The directory within custom-messages to create the component (optional).",
|
|
30
|
+
"alias": "dir"
|
|
31
|
+
},
|
|
32
|
+
"skipTests": {
|
|
33
|
+
"type": "boolean",
|
|
34
|
+
"description": "Skip generating test files.",
|
|
35
|
+
"default": false
|
|
36
|
+
},
|
|
37
|
+
"skipAction": {
|
|
38
|
+
"type": "boolean",
|
|
39
|
+
"description": "Skip generating an example action that uses this custom message.",
|
|
40
|
+
"default": false
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"required": ["name", "project"]
|
|
44
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Discovers botonic bot apps and their current versions.
|
|
3
|
+
# Uses nx show projects with tag:botonic:bot-app filter.
|
|
4
|
+
# Run from workspace root. Output: JSON array of { name, path, version }.
|
|
5
|
+
# Usage: bash .cursor/scripts/update-bot/discover-bots.sh
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
# Ensure we're in workspace root (contains apps/ or nx.json)
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
11
|
+
GIT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
|
|
12
|
+
REL_ROOT="$(cd "$SCRIPT_DIR/../../../" && pwd)"
|
|
13
|
+
if [[ -n "$GIT_ROOT" ]] && [[ -f "$GIT_ROOT/nx.json" ]]; then
|
|
14
|
+
ROOT="$GIT_ROOT"
|
|
15
|
+
elif [[ -d "$REL_ROOT/apps" ]] || [[ -f "$REL_ROOT/nx.json" ]]; then
|
|
16
|
+
ROOT="$REL_ROOT"
|
|
17
|
+
else
|
|
18
|
+
ROOT="${GIT_ROOT:-.}"
|
|
19
|
+
fi
|
|
20
|
+
cd "$ROOT"
|
|
21
|
+
|
|
22
|
+
# List bot apps via nx (tag:botonic:bot-app)
|
|
23
|
+
# Nx may print plugin messages to stdout; use tail -1 to get JSON only
|
|
24
|
+
names=$(npx nx show projects --projects "tag:botonic:bot-app" --json 2>/dev/null | tail -1 || echo "[]")
|
|
25
|
+
if [[ "$names" == "[]" ]] || [[ -z "$names" ]]; then
|
|
26
|
+
echo "[]"
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
bots='[]'
|
|
31
|
+
for name in $(echo "$names" | node -e "
|
|
32
|
+
try {
|
|
33
|
+
const arr = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
|
|
34
|
+
(Array.isArray(arr) ? arr : []).forEach(n => console.log(n));
|
|
35
|
+
} catch {}
|
|
36
|
+
"); do
|
|
37
|
+
[[ -z "$name" ]] && continue
|
|
38
|
+
|
|
39
|
+
path="$name"
|
|
40
|
+
if root=$(npx nx show project "$name" --json 2>/dev/null | tail -1 | node -e "try { const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); process.stdout.write(d.root||''); } catch {}"); then
|
|
41
|
+
[[ -n "$root" ]] && path="$root"
|
|
42
|
+
else
|
|
43
|
+
path="apps/$name"
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
version="unknown"
|
|
47
|
+
pkg="$ROOT/$path/package.json"
|
|
48
|
+
if [[ -f "$pkg" ]]; then
|
|
49
|
+
version=$(node -e "
|
|
50
|
+
try {
|
|
51
|
+
const p = require('$pkg');
|
|
52
|
+
const v = p.dependencies?.['@botonic/core']
|
|
53
|
+
|| p.dependencies?.['@botonic/webchat-react']
|
|
54
|
+
|| 'unknown';
|
|
55
|
+
console.log(String(v).replace(/^[\^~]/, ''));
|
|
56
|
+
} catch { console.log('unknown'); }
|
|
57
|
+
" 2>/dev/null || echo "unknown")
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
bots=$(echo "$bots" | node -e "
|
|
61
|
+
const b = JSON.parse(require('fs').readFileSync('/dev/stdin', 'utf8'));
|
|
62
|
+
b.push({ name: process.argv[1], path: process.argv[2], version: process.argv[3] });
|
|
63
|
+
console.log(JSON.stringify(b, null, 2));
|
|
64
|
+
" "$name" "$path" "$version")
|
|
65
|
+
done
|
|
66
|
+
|
|
67
|
+
echo "$bots"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Finds <name>.migration.md files for migrations between two versions.
|
|
3
|
+
# Reads node_modules/@botonic/nx-plugin/migrations.json (published, real semver).
|
|
4
|
+
# Usage: find-migration-guides.sh <from-version> <to-version>
|
|
5
|
+
# Output: JSON array of { version, migrations: [{ name, migrationGuide }] } grouped by unique version
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
FROM_VERSION="${1:?Usage: find-migration-guides.sh <from> <to>}"
|
|
10
|
+
TO_VERSION="${2:?Usage: find-migration-guides.sh <from> <to>}"
|
|
11
|
+
|
|
12
|
+
# Run from workspace root
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
GIT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
|
|
15
|
+
REL_ROOT="$(cd "$SCRIPT_DIR/../../../" && pwd)"
|
|
16
|
+
if [[ -n "$GIT_ROOT" ]] && [[ -f "$GIT_ROOT/nx.json" ]]; then
|
|
17
|
+
ROOT="$GIT_ROOT"
|
|
18
|
+
elif [[ -f "$REL_ROOT/nx.json" ]] || [[ -f "$REL_ROOT/node_modules/@botonic/nx-plugin/migrations.json" ]]; then
|
|
19
|
+
ROOT="$REL_ROOT"
|
|
20
|
+
else
|
|
21
|
+
ROOT="${GIT_ROOT:-$REL_ROOT}"
|
|
22
|
+
fi
|
|
23
|
+
cd "$ROOT"
|
|
24
|
+
|
|
25
|
+
MIGRATIONS_JSON="node_modules/@botonic/nx-plugin/migrations.json"
|
|
26
|
+
MIGRATIONS_DIR="node_modules/@botonic/nx-plugin/src/migrations"
|
|
27
|
+
|
|
28
|
+
if [ ! -f "$MIGRATIONS_JSON" ]; then
|
|
29
|
+
echo '{"error": "migrations.json not found. Run pnpm install first."}' >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
node -e "
|
|
34
|
+
const fs = require('fs');
|
|
35
|
+
const path = require('path');
|
|
36
|
+
let semver;
|
|
37
|
+
try { semver = require('semver'); } catch { semver = null; }
|
|
38
|
+
|
|
39
|
+
const mj = JSON.parse(fs.readFileSync('$MIGRATIONS_JSON', 'utf8'));
|
|
40
|
+
const generators = mj.generators || {};
|
|
41
|
+
const from = '$FROM_VERSION';
|
|
42
|
+
const to = '$TO_VERSION';
|
|
43
|
+
const migrationsDir = path.resolve('$MIGRATIONS_DIR');
|
|
44
|
+
|
|
45
|
+
const valid = (v) => semver ? semver.valid(v) : /^\\d+\\.\\d+\\.\\d+$/.test(v);
|
|
46
|
+
const gt = (a, b) => semver ? semver.gt(a, b) : a !== b;
|
|
47
|
+
const lte = (a, b) => semver ? semver.lte(a, b) : true;
|
|
48
|
+
const compare = (a, b) => semver ? semver.compare(a, b) : 0;
|
|
49
|
+
|
|
50
|
+
const entries = Object.entries(generators)
|
|
51
|
+
.filter(([, cfg]) => valid(cfg.version) && gt(cfg.version, from) && lte(cfg.version, to))
|
|
52
|
+
.sort(([, a], [, b]) => compare(a.version, b.version));
|
|
53
|
+
|
|
54
|
+
const byVersion = new Map();
|
|
55
|
+
for (const [name, cfg] of entries) {
|
|
56
|
+
const guideFile = path.join(migrationsDir, name, \`\${name}.migration.md\`);
|
|
57
|
+
const migrationGuide = fs.existsSync(guideFile) ? guideFile : null;
|
|
58
|
+
if (!byVersion.has(cfg.version)) {
|
|
59
|
+
byVersion.set(cfg.version, []);
|
|
60
|
+
}
|
|
61
|
+
byVersion.get(cfg.version).push({ name, migrationGuide });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const results = Array.from(byVersion.entries()).map(([version, migrations]) => ({
|
|
65
|
+
version,
|
|
66
|
+
migrations
|
|
67
|
+
}));
|
|
68
|
+
|
|
69
|
+
console.log(JSON.stringify(results, null, 2));
|
|
70
|
+
"
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: botonic-action
|
|
3
|
+
description: Scaffold and implement a Botonic bot action using the Nx generator, then guide implementation. Use when the user says "create action", "add action", "new action", "generate action", or wants to handle a specific message, intent, or conversation route in a Botonic bot project.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Botonic Action
|
|
7
|
+
|
|
8
|
+
Scaffold a server-side action, wire its route, and help implement its logic.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
### Step 1 — Gather inputs
|
|
13
|
+
|
|
14
|
+
Collect from context or ask:
|
|
15
|
+
|
|
16
|
+
- **`name`** (required): kebab-case name, e.g. `order-status`, `greet-user`
|
|
17
|
+
- **`project`** (required): Nx project name of the bot app, e.g. `my-bot`
|
|
18
|
+
- **`routeMatcher`** (required unless skipping route): the text pattern that triggers this action. Ask the user explicitly — e.g. _"What message or phrase should trigger this action?"_. Defaults to the kebab-case name if omitted.
|
|
19
|
+
- **`skipRoute`** (optional): `true` only if the action should not be wired into `routes.ts` (e.g. internal helper, called by another action)
|
|
20
|
+
- **`skipTests`** (optional): `true` to skip spec file generation
|
|
21
|
+
|
|
22
|
+
### Step 2 — Run the generator
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pnpm nx g @botonic/nx-plugin:action --name=<name> --project=<project>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
With route matcher:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pnpm nx g @botonic/nx-plugin:action order-status --project my-bot --routeMatcher "order status"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Without route wiring (internal helpers):
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm nx g @botonic/nx-plugin:action send-confirmation --project my-bot --skipRoute
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Step 3 — Review the generated route
|
|
41
|
+
|
|
42
|
+
Open `src/server/bot/routes.ts` and show the user the entry that was inserted:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
{
|
|
46
|
+
text: 'order-status',
|
|
47
|
+
action: async () => await OrderStatus(botContext),
|
|
48
|
+
},
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Confirm with the user:
|
|
52
|
+
|
|
53
|
+
- Is the `text` matcher correct? Does it match what the bot will receive?
|
|
54
|
+
- Should it be a regex? e.g. `/^order.*/i`
|
|
55
|
+
- Should it match on `payload` or `type` instead of `text`?
|
|
56
|
+
|
|
57
|
+
If the matcher needs changing, edit `routes.ts` directly:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Regex matcher
|
|
61
|
+
{ text: /^order.*/i, action: async () => await OrderStatus(botContext) },
|
|
62
|
+
|
|
63
|
+
// Payload matcher
|
|
64
|
+
{ payload: 'ORDER_STATUS', action: async () => await OrderStatus(botContext) },
|
|
65
|
+
|
|
66
|
+
// Message type matcher
|
|
67
|
+
{ type: 'postback', payload: 'ORDER_STATUS', action: async () => await OrderStatus(botContext) },
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Step 4 — Ask what to implement
|
|
71
|
+
|
|
72
|
+
If not already clear from context, ask: "What should this action do?"
|
|
73
|
+
|
|
74
|
+
### Step 5 — Implement the action
|
|
75
|
+
|
|
76
|
+
#### Building blocks: `sendMessage` and `BotServerMessageFactory`
|
|
77
|
+
|
|
78
|
+
Every action receives `BotContext` as its argument. The two key pieces for sending responses are:
|
|
79
|
+
|
|
80
|
+
- **`sendMessage`** — async function from `BotContext`. Call it once per message you want to send. You can call it multiple times to send a sequence of messages.
|
|
81
|
+
- **`BotServerMessageFactory`** — imported from `@botonic/shared`. Use its factory methods to build every message; never construct raw message objects by hand.
|
|
82
|
+
|
|
83
|
+
```typescript
|
|
84
|
+
import { BotContext, BotServerMessageFactory } from '@botonic/shared'
|
|
85
|
+
|
|
86
|
+
export async function MyAction({ sendMessage }: BotContext) {
|
|
87
|
+
await sendMessage(BotServerMessageFactory.createText({ text: 'Hello!' }))
|
|
88
|
+
return { status: 200, response: 'OK' }
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Expected return value
|
|
93
|
+
|
|
94
|
+
Every action **must** return `{ status: number, response: string }`. Use `200 / 'OK'` for success and a meaningful status code + message for errors.
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
return { status: 200, response: 'OK' } // success
|
|
98
|
+
return { status: 400, response: 'Bad Request' } // validation error
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### Factory methods
|
|
102
|
+
|
|
103
|
+
**Text message**
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
await sendMessage(BotServerMessageFactory.createText({ text: 'Your order is on the way!' }))
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Button message** — build each button with the appropriate factory method; never pass raw button objects
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
await sendMessage(
|
|
113
|
+
BotServerMessageFactory.createButtonMessage({
|
|
114
|
+
text: 'Need help with your order?',
|
|
115
|
+
buttons: [BotServerMessageFactory.createPostbackButton({ title: 'Order status', payload: 'ORDER_STATUS' }), BotServerMessageFactory.createUrlButton({ title: 'Visit website', url: 'https://example.com' }), BotServerMessageFactory.createWebviewButton({ title: 'Open form', webview: WEBVIEWS.ORDER_FORM }, session)],
|
|
116
|
+
})
|
|
117
|
+
)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
**Custom message**
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
await sendMessage(
|
|
124
|
+
BotServerMessageFactory.createCustom({
|
|
125
|
+
name: CUSTOM_MESSAGE_TYPES.ORDER_CARD,
|
|
126
|
+
props: { orderId, status },
|
|
127
|
+
})
|
|
128
|
+
)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Conditional logic with early return**
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
export async function OrderStatus({ sendMessage, request }: BotContext) {
|
|
135
|
+
const { payload } = request
|
|
136
|
+
if (!payload?.orderId) {
|
|
137
|
+
await sendMessage(BotServerMessageFactory.createText({ text: 'Please provide an order ID.' }))
|
|
138
|
+
return { status: 400, response: 'Bad Request' }
|
|
139
|
+
}
|
|
140
|
+
// fetch order and respond...
|
|
141
|
+
return { status: 200, response: 'OK' }
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
**Calling an external API**
|
|
146
|
+
|
|
147
|
+
Keep HTTP calls in a dedicated service file; import and call it from the action:
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
import { orderService } from '../../services/order-service'
|
|
151
|
+
|
|
152
|
+
export async function OrderStatus({ sendMessage, request }: BotContext) {
|
|
153
|
+
const order = await orderService.getOrder(request.payload?.orderId)
|
|
154
|
+
await sendMessage(BotServerMessageFactory.createText({ text: order.statusMessage }))
|
|
155
|
+
return { status: 200, response: 'OK' }
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Options reference
|
|
160
|
+
|
|
161
|
+
| Option | Default | Notes |
|
|
162
|
+
| -------------- | --------------- | -------------------------------- |
|
|
163
|
+
| `name` | — | Required. kebab-case recommended |
|
|
164
|
+
| `project` | — | Required. Nx project name |
|
|
165
|
+
| `routeMatcher` | kebab-case name | The `text` field in `routes.ts` |
|
|
166
|
+
| `skipRoute` | `false` | Omit route entry in `routes.ts` |
|
|
167
|
+
| `skipTests` | `false` | Omit `<name>.spec.ts` |
|