CloudWatch log group is not deleted on cdk destroy - amazon-cloudwatch

I have this CDK code:
const logGroup = new LogGroup(this, 'MyAppLogGroup', {
logGroupName: 'myapp',
retention: RetentionDays.ONE_DAY
});
When I run cdk deploy, log group is created in CloudWatch, but when I run cdk destroy, it's not deleted. Is there some way to enable this?

See https://docs.aws.amazon.com/cdk/api/latest/docs/#aws-cdk_aws-logs.LogGroup.html#removalpolicy. You need to set the removalPolicy of the LogGroup to DESTROY as the default one is RETAIN

Milan is 100% correct here, I'm just adding some example and more details about how to do it..
import * as cdk from "#aws-cdk/core";
const accessLogGroup = new LogGroup(this, 'MyAppLogGroup', {
logGroupName: 'myapp',
retention: RetentionDays.ONE_DAY,
// This does the work:
removalPolicy: core.RemovalPolicy.DESTROY
});

Related

Sveltekit,Supabase and Vercel (problem with Supabase when deploying to Vercel)

I'm trying to set up Sveltekit, Supabase and Vercel.
It works correctly on a local environment (SvelteKit and Supabase), but when I deploy it to Vercel there is a problem with Supabase - "Error: supabaseUrl is required" (I post a screenshot below).
If I don't use Supabase, there are no problems with deploying to Vercel.
Please someone if you have encountered a similar one or have a suggestion to share.
I finally got this to work after doing a couple of things I pieced together from a few sources.
First, I added the the environment variables in Vercel just as the were in the .env file. For example, VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY along with their values.
Next, I added some code in the svelte.config.js file. The result of the file looks like this:
import adapter from '#sveltejs/adapter-auto'
/** #type {import('#sveltejs/kit').Config} */
const config = {
kit: {
adapter: adapter(),
vite: {
define: {
'process.env': process.env,
},
},
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
},
}
export default config
I redeployed the project at Vercel, and it worked.
You should add your Supabase URL and Supabase ANON KEY to vercel and stick to the format given below VITE_SUPABASE_URL,VITE_SUPABASE_ANON_KEY if you have initialized according to the supabase guide.
More than adding the configuration to your svelte.config.js file, you should emphasize on adding environment variables to your Vercel environment if you have added this file
// utils/supabase.js
import { createClient } from '#supabase/supabase-js'
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY
export const supabase = createClient(supabaseUrl, supabaseAnonKey)

Strapi v4 Extending Server API for Plugins does not work

I am trying to follow the Strapi v4.0.0 guide on https://docs.strapi.io/developer-docs/latest/developer-resources/plugin-api-reference/server.html#entry-file for extending the users-permission plugin to add a custom route/controller, but so far have been unsuccessful. I add the custom files as stated in the docs, but there is no change in the UI.
I managed to get this to work for normal API highlighted in yellow, but was unable to do so for the users-permission plugin
In the previous version 3.6.8 this functionality was allowed through the extensions folder.
Am I missing something from the new guide, I even tried copying the files from node_modules > #strapi > plugin-users-permission and adding a new route and method to the exiting controller file but it still does not reflect the change in the section where we assign different route permission to roles. The user-permission plugin still shows the original routes, with no change.
Thanks,
I ran into this thread while researching pretty much the same issue, and I wanted to share my solution.
First of all, I found this portion of the documentation more useful than the one you referenced: https://docs.strapi.io/developer-docs/latest/development/plugins-extension.html
My goal was the write a new route to validate JWT tokens based on the comment made here: https://github.com/strapi/strapi/issues/3601#issuecomment-510810027 but updated for Strapi v4.
The solution turned out to be simple:
Create a new folder structure: ./src/extensions/user-permissions if it does not exist.
Create a new file ./src/extensions/user-permissions/strapi-server.js if it does not exist.
Add the following to the file:
module.exports = (plugin) => {
plugin.controllers.<controller>['<new method>'] = async (ctx) => {
// custom logic here
}
plugin.routes['content-api'].routes.push({
method: '<method>',
path: '/your/path',
handler: '<controller>.<new method>',
config: {
policies: [],
prefix: '',
},
});
return plugin;
};
If you're unsure what controllers are available, you can always check the API documentation or console.log(plugin) or console.log(plugin.controllers).
After the admin server restarts, you should see your new route under the user-permissions section as you would expect, and you can assign rights to it as you see fit.
My full strapi-server.js file including the logic to validate JWT:
module.exports = (plugin) => {
plugin.controllers.auth['tokenDecrypt'] = async (ctx) => {
// get token from the POST request
const {token} = ctx.request.body;
// check token requirement
if (!token) {
return ctx.badRequest('`token` param is missing')
}
try {
// decrypt the jwt
const obj = await strapi.plugin('users-permissions').service('jwt').verify(token);
// send the decrypted object
return obj;
} catch (err) {
// if the token is not a valid token it will throw and error
return ctx.badRequest(err.toString());
}
}
plugin.routes['content-api'].routes.push({
method: 'POST',
path: '/token/validation',
handler: 'auth.tokenDecrypt',
config: {
policies: [],
prefix: '',
},
});
return plugin;
};
When exporting routes you need to export the type, either content-api or admin. Look at the Strapi email plugin in node_modules for example, change the folder and file structure in your routes folder to match that and then you will be able to set permissions in the admin panel.
If your Strapi server is using Typescript, make sure that you name your extension files accordingly. So instead of strapi-server.js, you would need to name your file strapi-server.ts.

Overiding the default GraphQL sandbox with GraphQL Playground

Everytime when I created a graphQL server with ApolloServer and express when I navigate to http//:localhost:4000/graphql it opens me a sandbox which looks like:
What i really want to do is to open a graphql playground which looks like this
The reason i want this playground it's because it allows me to works with cookies very eaisly. I was thinking installing this exextion on my chrome browser will help. Unfortunately it did not work. Here is the instance of my ApolloSever with express in code:
const apolloServer = new ApolloServer({
schema: await buildSchema({
resolvers: [HelloResolver, TodoResolver, AuthResolver],
validate: false,
}),
});
await apolloServer.start();
apolloServer.applyMiddleware({ app });
Please if you know where what i'm missing help. t has been hours sitting here nothing works
Wow! After some hours i realized that I was looking for answers at wrong places. I started reading the docs line by line only to found out that the feature i wanted if for Apollo Server 2 and I'm using Apollo Server 3. So to solve this I had to go to my ApolloServer instance and add the following under plugins option:
...
import { ApolloServerPluginLandingPageGraphQLPlayground } from "apollo-server-core";
...
const apolloServer = new ApolloServer({
....
plugins: [ApolloServerPluginLandingPageGraphQLPlayground({})],
});

Using AWS SDK (JS) for s3.selectObjectContent gives error on 'on' keyword

I'm using AWS SDK for Javascript version 2.730.0 (latest at time of writing) in a Typescript file in Node.JS.
I'm using the selectObjectContent operation to query a CSV file, and following the guide in the documentation I have this block:
import * as S3 from 'aws-sdk/clients/s3';
const s3 = new S3();
...
s3.selectObjectContent(params, (err, data) => {
if (!err){
data.Payload.on('data', (event) => {
// Do something with returned records
});
}
});
The line data.Payload.on('data', (event) => { is giving this error in the linter:
Property 'on' does not exist on type 'EventStream<{ Records?: RecordsEvent; Stats?: StatsEvent; Progress?: ProgressEvent; Cont?: ContinuationEvent; End?: EndEvent; }>'.
What do I need to change for on to work?
I ran into the same problem myself. Found this problem post on another forum:
https://www.gitmemory.com/issue/aws/aws-sdk-js/3525/725076849
It does not explicitly show code to solve the problem but based on the information, I solved it as follows:
import { ReadStream } from "fs";
const eventStream = data.Payload as ReadStream;
eventStream.on("data", ({ Records, Stats, Progress, Cont, End }: ...
TypeScript no longer complains.

GraphQL schema won't import

I'm trying setup an express GraphQL server. Following a tutorial when I put the following in the server startup like this:
// ENTIRE SCHEMA IN MAIN FILE THIS WORKS!!!
...
var graphql = require('graphql');
const RootQuery = new graphql.GraphQLObjectType({
name: 'RootQuery',
description: 'The root query',
fields: {
viewer: {
type: graphql.GraphQLString,
resolve() {
return 'viewer!';
}
}
}
});
const Schema = new graphql.GraphQLSchema({
query: RootQuery
});
app.use('/graphql', graphqlHTTP({ schema: Schema }));
...
it works, returning the data 'viewer! But as I don't want everything in the main file, I tried to transfer this exact code to another file and import it like this:
//THIS DOES NOT WORK
...
var Schema = require('./build/models/graphql/schema');
app.use('/graphql', graphqlHTTP({ schema: Schema }));
...
I get the following error:
{
"errors": [
{
"message": "Schema must be an instance of GraphQLSchema. Also ensure that there are not multiple versions of GraphQL installed in your node_modules directory."
}
]
}
I'm not sure what I'm doing wrong. In case this has anything to do with it, I am writing in es6 then transpiling back to 5 in a build script. Here's the build of the schema file:
// TRANSPILED SCHEMA
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var graphql = require('graphql');
var RootQuery = new graphql.GraphQLObjectType({
name: 'RootQuery',
description: 'The root query',
fields: {
viewer: {
type: graphql.GraphQLString,
resolve: function resolve() {
return 'viewer!';
}
}
}
});
var Schema = new graphql.GraphQLSchema({
query: RootQuery
});
exports.default = Schema;
And here is my package.json:
"express": "^4.13.4",
"express-graphql": "^0.5.3",
"graphql": "^0.6.0",
I've checked that only one graphql is in the node_modules folder. Does graphql expect the same INSTANCE across all modules, like a shared global instance? Does express-graphql use it's own version? How do I check? I'm new to node, is there a way to check the instances?
I don't think this is a GraphQL problem, but a problem with how you're using require and exports in JS. The problem is probably:
var Schema = require('./build/models/graphql/schema')
along with
var Schema = new graphql.GraphQLSchema({
query: RootQuery
});
exports.default = Schema;
You're not importing the same value that you're exporting. Try either exporting Schema as module.exports = Schema or importing it as Schema = require("./...").default
Also ensure that there are not multiple versions of GraphQL installed in your node_modules directory.
As the error indicates, this most likely has to do with more than one copy of GraphQL in your node_modules directory. Have you checked that? If there is more than one copy, you might be able to solve it by running npm dedupe if you're using npm version 2. If you're using npm 3, then most likely you've installed two different versions of the graphql module.
Either way, you have to make sure that after the compile step, express-graphql and your schema both point to the same copy of the graphql module.
If you think implementing & maintaining Graphql services (mainly their schemas), please have a look at graphqly. Here's a sample code to define Graphql schemas:
import graphly from "graphqly";
const gBuilder = graphly.createBuilder();
// define types, inputs ... (in any order)
gBuilder.type("Products").implements("List").def(`
products: [Product]!
`);
gBuilder.type("Product").def(`
id: ID!
name: String!
link: String
price: Int
`);
// we're too lazy to define a separate input, so we can `extend` other structure
gBuilder.input("ProductInput").ext("Product");
gBuilder.enum("ProductOrder").def(`
PRICE_DESCENDING
PRICE_ASCENDING
NEWEST
`);