compile typescript in chatbot - node.js

I'm trying to create a chatbot I'm following a tutorial on youtube
https://www.youtube.com/watch?v=cYuWse7GB9E
However at the end of the tutorial you build the typescript using the command Ctrl + Shift + b
my tsconfig.json file looks like this
{
"conpileOnSave":true,
"compileOptions":{
"module":"commonjs",
"target":"es6",
"sourceMap":true,
"declaration":false,
"removeComments":true,
"outDir":"./dist",
"allowJs":true
},
"files":[
"./lib/types.ts",
"./lib/app.ts"
]
}
and my app.ts file looks like this
import { BotFrameworkAdapter, MemoryStorage,ConversationState } from "botbuilder";
import * as restify from "restify";
//import { ConfState } from "./types";
let server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(`${server.name} listening on ${server.url}`);
})
const adaptor = new BotFrameworkAdapter({
appId: process.env.MICROSOFT_APP_ID,
appPassword: process.env.MICROSOFT_APP_PASSWORD
});
let conversationState;
const memoryStorage = new MemoryStorage();
conversationState = new ConversationState(memoryStorage);
//const conversationState = new ConversationState(new MemoryStorage());
adaptor.use(conversationState);
server.post("/api/messages",(req,res) => {
adaptor.processActivity(req,res,async(context) =>{
if(context.activity.type === "message") {
const state = conversationState.get(context);
await context.sendActivity(`you said ${context.activity.text}`);
} else {
await context.sendActivity(`${context.activity.type} event detected`);
}
})
});
my problem is that it builds, well doesn't have any errors but nothing is ever built into the "dist" folder so when I then run "node server.js" which contains this code
module.exports = require("./dist/app");
It throws an error
internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module './dist/app'
Has anyone any idea what is wrong. I have changed the permissions on the dist folder to full but still nothing.
thanks
my complete source code can be found here
https://github.com/andrewslaughter/chatbot/tree/master/video2

Related

Shopify App Node.js template: Testing Errors

Overview
I have been having A LOT of problems running basic unit tests with shopify's node app setup: https://github.com/Shopify/shopify-app-template-node
When trying to use the #shopify/react-testing library, with Jest as the runner, I keep getting this TypeError of testUtils.act is not a function.
TextFieldComponent.test.tsx
import { mount } from '#shopify/react-testing';
import TextFieldComponent from "../../components/atoms/TextFieldComponent";
describe("TextFieldComponent", () => {
it("renders TextFieldComponent", () => {
const testId = "text-field";
const value = "test";
const label = "test";
const type = "text";
const autoComplete = "off";
const wrapper = mount( <TextFieldComponent
value={value}
type={type}
autoComplete={autoComplete}
label={label}
/>);
});
});
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom'
}
The Error:
testUtils.act is not a function

get all routes from nest.js app from a script

Currently i save all my routes in a file after the projects starts
async function bootstrap() {
const adapter = new FastifyAdapter(fastifyInstance);
adapter.register(fastifyMultipart, fastifyAdapterConfig);
const app = await NestFactory.create<NestFastifyApplication>(AppModule, adapter);
// Collecting all the routes from the project
const routesList: Array<{ method: string; url: string }> = [];
app
.getHttpAdapter()
.getInstance()
.addHook('onRoute', (route: Record<string, string>) => {
if (!JSON.stringify(route).includes('"hide":true')) {
routesList.push({ method: <string>route.method, url: <string>route.url });
}
});
// Saving all routes into a file in a root of a project
const routesFileName = 'mock_index.js';
fs.writeFile(path.join(process.cwd(), routesFileName), JSON.stringify(routesList), (err) => {
if (err) {
logger.error(`File ${routesFileName} saving errors: ${JSON.stringify(err)}`);
throw err;
}
logger.log(`Routes list is saved in a root folder in a file: ${routesFileName}`);
});
}
But how can I save all my routes without starting a project, outside bootstrap()
for example from yarn:generate-routes.
"generate-routes": "node ./ci-cd/generate-routes.js",
The main problem is to get the list of routes in runtime.

Apollo subscriptions - Nextjs - Error: Observable cancelled prematurely at Concast.removeObserver

I am trying to use apollo/graphql subscription in my nextjs project, my graphql server is placed in external nextjs service,I can work with queries and mutation without any problem but when I use an implementation of useSubscription I get the following error:
"Error: Observable cancelled prematurely
at Concast.removeObserver (webpack-internal:///../../node_modules/#apollo/client/utilities/observables/Concast.js:118:33)
at eval (webpack-internal:///../../node_modules/#apollo/client/utilities/observables/Concast.js:21:47)
at cleanupSubscription (webpack-internal:///../../node_modules/zen-observable-ts/module.js:92:7)
at Subscription.unsubscribe (webpack-internal:///../../node_modules/zen-observable-ts/module.js:207:7)
at cleanupSubscription (webpack-internal:///../../node_modules/zen-observable-ts/module.js:97:21)
at Subscription.unsubscribe (webpack-internal:///../../node_modules/zen-observable-ts/module.js:207:7)
at eval (webpack-internal:///../../node_modules/#apollo/client/react/hooks/useSubscription.js:106:26)
at safelyCallDestroy (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:22763:5)
at commitHookEffectListUnmount (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:22927:11)
at invokePassiveEffectUnmountInDEV (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:24998:13)
at invokeEffectsInDev (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:27137:11)
at commitDoubleInvokeEffectsInDEV (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:27110:7)
at flushPassiveEffectsImpl (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:26860:5)
at flushPassiveEffects (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:26796:14)
at eval (webpack-internal:///../../node_modules/react-dom/cjs/react-dom.development.js:26592:9)
at workLoop (webpack-internal:///../../node_modules/scheduler/cjs/scheduler.development.js:266:34)
at flushWork (webpack-internal:///../../node_modules/scheduler/cjs/scheduler.development.js:239:14)
at MessagePort.performWorkUntilDeadline (webpack-internal:///../../node_modules/scheduler/cjs/scheduler.development.js:533:21)"
I know that the subscriptions server is working right because I can to listening from apollo studio and I have created a spa with create-react-app and it works fine
I have used:
Server:
"apollo-server-express": "^3.6.7"
"graphql-ws": "^5.7.0"
Client
"next": "^12.1.5"
"#apollo/client": "^3.5.10"
"graphql-ws": "^5.7.0"
Hook implementation
const room = useSubscription(
gql`
subscription onRoomAdded($roomAddedId: ID!) {
roomAdded(id: $roomAddedId) {
id
name
}
}
`
);
Client implementation
import { ApolloClient, HttpLink, InMemoryCache, split } from '#apollo/client';
import { GraphQLWsLink } from '#apollo/client/link/subscriptions';
import { getMainDefinition } from '#apollo/client/utilities';
import { createClient } from 'graphql-ws';
import fetch from 'isomorphic-fetch';
const HOST = 'http://localhost:3001/graphql';
const HOST_WS = 'ws://localhost:3001/graphql';
const isServer = typeof window === 'undefined';
if (isServer) {
global.fetch = fetch;
}
const httpLink = new HttpLink({
uri: HOST,
});
const link = isServer
? httpLink
: split(
({ query }) => {
const definition = getMainDefinition(query);
return (
definition.kind === 'OperationDefinition' &&
definition.operation === 'subscription'
);
},
new GraphQLWsLink(
createClient({
url: HOST_WS,
})
),
httpLink
);
const client = new ApolloClient({
ssrMode: isServer,
link,
cache: new InMemoryCache(),
});
export default client;
any idea about the problem? I think the problem could be that NextJS only works with subscriptions-transport-ws but in the official apollo documentation indicates that the new official way is to use graphql-ws the other library is unmaintained already
UPDATE!
I have checked that the subscriptions are working right in production build, I'm investigating how to implement in development process. any suggestions are welcome.
If it is working in production, but in not in dev, you may have the same issue I had with my React SPA: StrictMode and double rendering as described in this github issue.
So far I have found 2 ways to make it work:
remove StrictMode
subscribe with vanilla JS instead ofuseSubscription
const ON_USER_ADDED = gql`
subscription OnUserAdded {
userAdded {
name
id
}
}
`;
const subscribe = () => {
client.subscribe({
query: ON_USER_ADDED,
}).subscribe({
next(data) {
console.log('data', data);
},
complete(){
console.log('complete');
},
error(err) {
console.log('error', err);
}
})
};

TypeError: Slackbot is not a constructor

I need your help because it's the first time that I develop a Slack bot and I don't understand why this message appear:
const botSlack = new Slackbot ({
^
TypeError: Slackbot is not a constructor
Here my code : slack.js
const {Slackbot} = require('#slack/bolt');
const botSlack = new Slackbot({
token : process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET,
});
(async () => {
await botSlack.start(process.env.PORT || 3000);
})();
Part of my package.json:
"scripts": {
"dev": "nodemon slack.js",
},
"dependencies": {
"#slack/bolt": "^3.11.0",
},
In the bolt documentation (https://api.slack.com/tutorials/hello-world-bolt) and others, it's the same and it's run.
Please someone can explain to me why ?
The documentation has this code - App instead of Slackbot. You can rename the local variable if you want, but the import statement requires the exact name:
const { App } = require('#slack/bolt');
const botSlack = new App({
token: process.env.SLACK_BOT_TOKEN,
signingSecret: process.env.SLACK_SIGNING_SECRET
});
(async () => {
await botSlack.start(process.env.PORT || 3000);
})();
if you do want to rename the value, you can use
const { App: Slackbot } = require('#slack/bolt');
It is more common to use import statements for this, you can still alias it using import { App as Stackbot} from '#slack/bolt', see MDN - import

Typescript: classes and Interfaces in definition file getting required in compiled .js

I have a Typescript project with two important files:
app.ts
models.d.ts
The first few lines of app.ts look like this:
///<reference path="models.d.ts"/>
'use strict';
import * as fs from 'async-file';
import { MyClass } from './models';
The first few lines of the compiled app.js are:
///<reference path="models.d.ts"/>
'use strict';
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("async-file");
const models_1 = require("./models"); //// ERROR THROWN HERE!!!!!!!!
However, no models.js is generated because it's just a .d.ts declaration file. So when I run this, and require is called to get ./models, I get the following exception:
Cannot find module './models'
This is Visual Studio Professional 2017 and I don't have a tsconfig.json file. However, my project compilation settings look like this:
What am I doing wrong? This is killing me.
models.d.ts implies that there is a models.js that already exists in its place in your output directory.
You should probably use a .ts file if that isn't the case. In other words, rename it from models.d.ts to models.ts.

Resources