How to import GraphQL query as a string instead of an object - vue.js

I created a .gql file for my query and I'm importing it like this:
const query = require("#/hello.gql");
However, if I log the query variable to the console, it shows an object, not a string. What can I do so that my imported query is just a string?

When querying your server using apollo-client, the provided query parameter has to be an object of the type DocumentNode, which is an AST representation of the query. In other words, if you use apollo-client, you can't just pass it a query as a string, you have to parse it first. This is commonly done using the graphql-tag library. It can also be done automatically through webpack by utilizing a loader like graphql-tag's loader or graphql-loader. If you utilize a loader like that, then any .gql files you import will automatically be parsed into DocumentNode objects for you.
If you're not using apollo-client, there's no need to utilize those loaders. If you still want to store you queries in separate files and import them as strings, you should utilize a different loader, for example, raw-loader.

Because, you are only importing the query, not using it.
You can use apollo to use that query like this
const yourQuery= require("#/hello.gql");
data(){
return {
queryResponse: []
}
}
apollo: {
queryResponse: {
prefetch: true,
query: yourQuery
}
}
Whit this, you are fetch the query and save the response in queryResponse

Now raw-loader is deprecated, you can load them like this.
In the webpack config
module: {
rules: [
{
test: /\.gql/,
type: "asset/source",
},
],
},
Then import
import myGraphQlQuery from "myGraphQlQuery.gql"

Related

Can I use TypeOrm's FindOperators inside a base class without getting bad SQL Unknown column '_type' in 'where clause'

I am trying to write a base class for CRUD operations for "typeorm": "~0.2.45" under "#nestjs/typeorm": "~8.0.3" using node v14.19.3.
The base class looks like this:
export class CrudService<T> {
protected repository: Repository<T>;
constructor(repository: Repository<T>) {
this.repository = repository;
}
...
// Minimized code example
async find() {
return this.repository.find({
where: {
created: Between("2022-06-21T14:18:00.000Z", "2022-06-21T14:19:00.000Z")
}
});
}
}
This generates the following SQL query (which is wrong), it seems to use the Between() object as a literal equality comparison.
query failed: SELECT ... FROM `carts` `CartEntity` WHERE `CartEntity`.`created` = ?
-- PARAMETERS: {
"_type":"between",
"_value":[
"2022-06-21T14:18:00.000Z",
"2022-06-21T14:19:00.000Z"
],
"_useParameter":true,
"_multipleParameters":true
}
If I implement the same code inside the CartsEntity service like this:
#Injectable()
export class CartsService extends CrudService<CartEntity> {
constructor(
#InjectRepository(CartsRepository) repository: CartsRepository
) {
super(repository);
}
...
async find() {
return this.repository.find({
where: {
created: Between("2022-06-21T14:18:00.000Z", "2022-06-21T14:19:00.000Z")
}
});
}
It works fine and retrieves the data with valid SQL using BETWEEN on MySql.
I am wondering what is wrong here since I am using the same instance of repository in both code examples. I tried looking at the TypeOrm FindOperator logic but could not pinpoint it.
It turns out that the problem is a difference in the typeorm npm versions I was using.
The CrudEntity described above is inside a private npm using typeorm 0.2.45 as are my microservices extending CrudEntity like the CartEntity above.
Since #nestjs/typeorm is tagged to typeorm 0.2.34 the type was not the same for FindOperator and thus returned as an object condition instead of a FindOperator generating the proper BETWEEN SQL statement.
Basically, make sure all typeorm versions are the same across all your projects sharing code.

Using refs with Vue 3 + TypeScript + Options API

I am trying to understand the best way to use refs together with TypeScript and the Options API. In the docs they reference it like below, but that is without using TS. When it comes to TS, they only explain how to use it with Composition API.
When I use this.$refs.myRef it throws this error Object is of type 'unknown'.
I know that I can cast it and use it like this: (this.$refs.myRef as HTMLElement) but that I feel shouldn't be necessary to do for every ref every single time.
What is the correct way to use a reference with Options API + TS?
I created a shim like this:
shims-runtime-core.d.ts
import * as runtimeCore from '#vue/runtime-core'
declare module '#vue/runtime-core' {
interface ComponentCustomProperties {
$refs: {
[key: string]: HTMLElement|any,
},
// ... more stuff
}
}
And then I can access the refs like normal.

Cant access helper methods inside mongoose schema

My directory looks like bellow
--controllers
-helper.js
--models
-userModel.js
--server.js
My helper module is like
module.exports = {
check: function() {
return 'check';
}
}
I want to access helper module inside userModel.js. So I put like
var helper = require('.././controllers/helper');
Then I do console.log(helper.check()); but it shows error helper.check is not a function Or if I do console.log(helper); only it returns {}. How to access the helper module inside models? Thank you.
Since you said it returns {}, can you please check in your helper module that you have imported userModel.js. Because it forms circular dependencies and sometimes result empty json.

rollup equivalent of "browserify -r"

I need to force some modules into my bundle, as they are required dynamically through some code like below:
var moduleName = "someModule";
var myModule = require(moduleName);
I was using browserify to bundle this (through browserify -r or the API equivalent).
I am trying to switch to rollup and I don't figure out how to do this with rollup. Basically, I just want to force some modules into the bundle, and make them available globally through the require statement.
I think the key here is to use the new ES6 module syntax as described in the Rollup documentation. This will also give Rollup the possibility to apply features like chunking and tree-shaking.
Another important thing is to make it explicit what might get imported. By that I mean to use statements like 'import('./module1.js')' instead of 'import(some_variable)'. It is hard for Rollup to figure out all possible contents of the variable which gets used in the import. Therefore I would use explicit file names here but wrap everything in some kind of if/else condition.
Consider the following example:
File ./src/main.js:
let num = Math.random() * 10;
let condition = Math.round(num % 3);
let mod;
if (condition === 1) {
import('./module1.js').then((module)=> {
log(module);
});
} else if (condition === 2) {
import('./module2.js').then((module)=> {
log(module);
});
} else {
import('./module3.js').then((module)=> {
log(module);
});
}
function log(module) {
mod = module;
console.log(mod.test());
console.log('Done');
}
File ./src/module1.js:
function test() {
return 'This is 1!';
}
export { test };
The files module2.js and module3.js are the same like module1. The only difference is that they log 'This is 2!' and 'This is 3!'.
The Rollup config looks like this:
const production = !process.env.ROLLUP_WATCH;
export default {
inlineDynamicImports: true,
input: 'src/main.js',
output: {
dir: 'public/',
format: 'esm',
sourcemap: true
}
};
If you run 'rollup -c' then there will be one file './public/main.js'. This bundle will include all three modules. Usually Rollup would create main.js and three chunks. By using the setting 'inlineDynamicImports=true', Rollup puts everything in one file.
You can also change the format in the Rollup config to 'iife' (or amd, cjs, umd) if you want to.

How can i encode a string in base64 using meteor

I am trying to use a form to upload files to a s3 bucket using Meteor. I am following this amazon article. At "Sign Your S3 POST Form", near the end, I need to encode a string to base64 but I've been unable to find a way to do this. Can anyone tell me how to do this? Notice that the string first needs to be encoded and then signed. This is how it's done in python:
import base64
import hmac, hashlib
policy = base64.b64encode(policy_document)
signature = base64.b64encode(hmac.new(AWS_SECRET_ACCESS_KEY, policy, hashlib.sha1).digest())
You can do this without the NodeJS crypto module, creating a package looked a bit like breaking a fly on the wheel to me so I figured out this:
if (Meteor.isServer) {
Meteor.methods({
'base64Encode':function(unencoded) {
return new Buffer(unencoded || '').toString('base64');
},
'base64Decode':function(encoded) {
return new Buffer(encoded || '', 'base64').toString('utf8');
},
'base64UrlEncode':function(unencoded) {
var encoded = Meteor.call('base64Encode',unencoded);
return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
},
'base64UrlDecode':function(encoded) {
encoded = encoded.replace(/-/g, '+').replace(/_/g, '/');
while (encoded.length % 4)
encoded += '=';
return Meteor.call('base64Decode',encoded);
}
console.log(Meteor.call('base64Encode','abc'));
});
This is based on the base64.js by John Hurliman found at https://gist.github.com/jhurliman/1250118 Note that this will work like a charm on the server but for porting it to the client you have call the methods with a callback function that stores the result as a session variable.
You need NodeJS crypto module to perform these tasks.
First create a "packages" directory at the root of your meteor project, then create a "my-package" directory.
Inside it, you need two files : a "package.js" and "my-package.js".
package.js should look like :
Package.describe({
summary:"MyPackage doing amazing stuff with AWS."
});
Package.on_use(function(api){
// add your package file to the server app
api.add_files("my-package.js","server");
// what we export outside of the package
// (this is important : packages have their own scope !)
api.export("MyPackage","server");
});
my-package.js should look like :
var crypto=Npm.require("crypto");
MyPackage={
myFunction:function(arguments){
// here you can use crypto functions !
}
};
The function you will probably need is crypto.createHmac.
Here is an example code of how I encode a JSON security policy in base64 then use it to generate a security signature in my own app :
encodePolicy:function(jsonPolicy){
// stringify the policy, store it in a NodeJS Buffer object
var buffer=new Buffer(JSON.stringify(jsonPolicy));
// convert it to base64
var policy=buffer.toString("base64");
// replace "/" and "+" so that it is URL-safe.
return policy.replace(/\//g,"_").replace(/\+/g,"-");
},
encodeSignature:function(policy){
var hmac=crypto.createHmac("sha256",APP_SECRET);
hmac.update(policy);
return hmac.digest("hex");
}
This will allow you to call MyPackage.myFunction in the server-side of your Meteor app.
Last but not last, don't forget to "meteor add my-package" in order to use it !
You can use meteor-crypto-base64 package.
CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse('Hello, World!'));
//"SGVsbG8sIFdvcmxkIQ=="